Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #142 #143

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ env:
matrix:
# we recommend new addons test the current and previous LTS
# as well as latest stable release (bonus points to beta/canary)
- EMBER_TRY_SCENARIO=ember-lts-2.12
- EMBER_TRY_SCENARIO=ember-lts-2.16
- EMBER_TRY_SCENARIO=ember-lts-2.18
- EMBER_TRY_SCENARIO=ember-lts-3.8
- EMBER_TRY_SCENARIO=ember-lts-3.12
- EMBER_TRY_SCENARIO=ember-lts-3.16
- EMBER_TRY_SCENARIO=ember-lts-3.20
- EMBER_TRY_SCENARIO=ember-release
- EMBER_TRY_SCENARIO=ember-beta
- EMBER_TRY_SCENARIO=ember-canary
Expand Down
4 changes: 2 additions & 2 deletions addon/event_dispatcher.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getOwner } from '@ember/application';
import { merge, assign as _assign } from '@ember/polyfills';
import { merge } from '@ember/polyfills';
import { get, set } from '@ember/object';
import Ember from 'ember';
import defaultHammerEvents from './hammer-events';
Expand All @@ -21,7 +21,7 @@ const eventEndings = {
tap: []
};

const assign = _assign || merge;
const assign = Object.assign || merge;

const notFocusableTypes = ['submit', 'file', 'button', 'hidden', 'reset', 'range', 'radio', 'image', 'checkbox'];

Expand Down
99 changes: 51 additions & 48 deletions addon/modifiers/recognize-gesture.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,58 @@

import Modifier from 'ember-class-based-modifier';
import { getOwner } from '@ember/application';
import Modifier from "ember-modifier";
import { registerDestructor } from "@ember/destroyable";

function cleanup(instance) {
if (instance.manager !== null) {
instance.manager.destroy();
instance.manager = null;
}
}

export default class RecognizeGestureModifier extends Modifier {

constructor() {
super(...arguments);
this.recognizers = null;
this.manager = null;
this.gestures = getOwner(this).lookup('service:-gestures');

if (this.args.positional) {
this.recognizers = this.gestures.retrieve(this.args.positional);
}
this.managerOptions = (this.args.named && (Object.keys(this.args.named).length > 0)) ? Object.assign({}, this.args.named) : { domEvents: true };
this.managerOptions.useCapture = this.gestures.useCapture;

}

didInstall() {
if (!this.recognizers) return;
this.element.style['touch-action'] = 'manipulation';
this.element.style['-ms-touch-action'] = 'manipulation';
this.recognizers.then ( (recognizers) => {
if (this.isDestroyed) return;
this.sortRecognizers(recognizers);
this.manager = new Hammer.Manager(this.element, this.managerOptions);
recognizers.forEach((recognizer) => { this.manager.add(recognizer); });
constructor(owner) {
super(...arguments);
this.gestures = owner.lookup("service:-gestures");

registerDestructor(this, cleanup);
}

modify(element, positional, named) {
const gestureNames = [...positional];
this.recognizers = this.gestures.retrieve(gestureNames);
const managerOptions =
named && Object.keys(named).length > 0
? Object.assign({}, named)
: { domEvents: true };
managerOptions.useCapture = this.gestures.useCapture;
if (this.recognizers) {
element.style["touch-action"] = "manipulation";
element.style["-ms-touch-action"] = "manipulation";
this.recognizers.then((recognizers) => {
if (this.isDestroyed) return;
this.sortRecognizers(recognizers);
this.manager = new Hammer.Manager(element, managerOptions);
recognizers.forEach((recognizer) => {
this.manager.add(recognizer);
});
});
}

willRemove() {
this.manager.destroy();
this.manager = null;
}

// Move each recognizer after all recognizers it excludes in the list - why?
sortRecognizers(recognizers) {
for (let i = 0; i < recognizers.length; i++) {
const r = recognizers[i];
let currentIndex = i;
if (r.exclude.length) {
for (let j = 0; j < r.exclude.length; j++) {
const newIndex = recognizers.indexOf(r.exclude[j]);
if (newIndex > 0 && currentIndex < newIndex) {
recognizers.splice(currentIndex, 1);
recognizers.splice(newIndex, 0, r);
currentIndex = newIndex;
}
}
}
}

// Move each recognizer after all recognizers it excludes in the list - why?
sortRecognizers(recognizers) {
for (let i = 0; i < recognizers.length; i++) {
const r = recognizers[i];
let currentIndex = i;
if (r.exclude.length) {
for (let j = 0; j < r.exclude.length; j++) {
const newIndex = recognizers.indexOf(r.exclude[j]);
if (newIndex > 0 && currentIndex < newIndex) {
recognizers.splice(currentIndex, 1);
recognizers.splice(newIndex, 0, r);
currentIndex = newIndex;
}
}
}
}
}
}
142 changes: 76 additions & 66 deletions addon/services/-gestures.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
import { computed } from '@ember/object';
import { getOwner } from '@ember/application';
import Service from '@ember/service';
import RSVP from 'rsvp';
import camelize from '../utils/string/dasherized-to-camel';
import capitalize from '../utils/string/capitalize-word';
import { getOwner } from "@ember/application";
import Service from "@ember/service";
import RSVP from "rsvp";
import camelize from "../utils/string/dasherized-to-camel";
import capitalize from "../utils/string/capitalize-word";

const {
Promise, // jshint ignore:line
defer // jshint ignore:line
Promise, // jshint ignore:line
defer, // jshint ignore:line
} = RSVP;

export default Service.extend({
export default class Gestures extends Service {
_recognizers = {};

_recognizers: null,
_fastboot: computed(function() {
get _fastboot() {
let owner = getOwner(this);

return owner.lookup('service:fastboot');
}),
return owner.lookup("service:fastboot");
}

get isFastBoot() {
return this._fastboot && this._fastboot.isFastBoot;
}

retrieve(names) {
let promises = names.map((name) => { return this.lookupRecognizer(name); });
let promises = names.map((name) => {
return this.lookupRecognizer(name);
});
return RSVP.all(promises);
},
}

createRecognizer(name, details) {
const eventName = camelize(details.eventName || name).toLowerCase();
Expand All @@ -35,51 +40,55 @@ export default Service.extend({
const Recognizer = new Hammer[gesture](options);
Recognizer.initialize = defer();

this.set(`_recognizers.${name}`, Recognizer);
this._recognizers[name] = Recognizer;
return Recognizer;
},
}

setupRecognizer(name, details) {
if (this.get('_fastboot.isFastBoot')) { return; }
return Promise.resolve(this.createRecognizer(name, details))

// includes
.then((Recognizer) => {
if (details.include) {
const included = details.include.map((name) => {
return this.__speedyLookupRecognizer(name);
});
return RSVP.all(included).then((recognizers) => {
Recognizer.recognizeWith(recognizers);
return Recognizer;
});
}
return Recognizer;
})

// excludes
.then((Recognizer) => {
if (details.exclude) {
const excluded = details.exclude.map((name) => {
return this.__speedyLookupRecognizer(name);
});

return RSVP.all(excluded).then((recognizers) => {
Recognizer.requireFailure(recognizers);
Recognizer.exclude = recognizers;
if (this.isFastBoot) {
return;
}
return (
Promise.resolve(this.createRecognizer(name, details))

// includes
.then((Recognizer) => {
if (details.include) {
const included = details.include.map((name) => {
return this.__speedyLookupRecognizer(name);
});
return RSVP.all(included).then((recognizers) => {
Recognizer.recognizeWith(recognizers);
return Recognizer;
});
}
return Recognizer;
})

// excludes
.then((Recognizer) => {
if (details.exclude) {
const excluded = details.exclude.map((name) => {
return this.__speedyLookupRecognizer(name);
});

return RSVP.all(excluded).then((recognizers) => {
Recognizer.requireFailure(recognizers);
Recognizer.exclude = recognizers;
Recognizer.initialize.resolve(Recognizer);
return Recognizer;
});
} else {
Recognizer.exclude = [];
Recognizer.initialize.resolve(Recognizer);
return Recognizer;
});
} else {
Recognizer.exclude = [];
Recognizer.initialize.resolve(Recognizer);
return Recognizer;
}
});
},
}
})
);
}

__speedyLookupRecognizer(name) {
let recognizer = this.get(`_recognizers.${name}`);
let recognizer = this._recognizers[name];
if (recognizer) {
return recognizer;
}
Expand All @@ -91,14 +100,17 @@ export default Service.extend({
return this.setupRecognizer(name, details.class);
}

return Promise.reject(new Error(`ember-gestures/recognizers/${name} was not found. You can scaffold this recognizer with 'ember g recognizer ${name}'`));

},
return Promise.reject(
new Error(
`ember-gestures/recognizers/${name} was not found. You can scaffold this recognizer with 'ember g recognizer ${name}'`
)
);
}

lookupRecognizer(name) {
let recognizer = this.get(`_recognizers.${name}`);
let recognizer = this._recognizers[name];
if (recognizer) {
return recognizer.initialize.promise.then(function(recognizer) {
return recognizer.initialize.promise.then(function (recognizer) {
return recognizer;
});
}
Expand All @@ -110,12 +122,10 @@ export default Service.extend({
return this.setupRecognizer(name, details.class);
}

return Promise.reject(new Error(`ember-gestures/recognizers/${name} was not found. You can scaffold this recognizer with 'ember g recognizer ${name}'`));
},

init() {
this._super();
this._recognizers = {};
return Promise.reject(
new Error(
`ember-gestures/recognizers/${name} was not found. You can scaffold this recognizer with 'ember g recognizer ${name}'`
)
);
}

});
}
5 changes: 2 additions & 3 deletions app/event_dispatcher.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { merge, assign as _assign } from '@ember/polyfills';

import { merge } from '@ember/polyfills';

import EventDispatcher from 'ember-gestures/event_dispatcher';
import config from './config/environment';

const assign = _assign || merge;
const assign = Object.assign || merge;

let gestures = assign({}, {
emberUseCapture: false,
Expand Down
4 changes: 2 additions & 2 deletions app/services/-gestures.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { merge, assign as _assign } from '@ember/polyfills';
import { merge } from '@ember/polyfills';
import config from '../config/environment';
import Service from 'ember-gestures/services/-gestures';

const assign = _assign || merge;
const assign = Object.assign || merge;

let gestures = assign({}, {
useCapture: false
Expand Down
16 changes: 16 additions & 0 deletions config/ember-try.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,22 @@ module.exports = function() {
}
}
},
{
name: 'ember-lts-3.16',
npm: {
devDependencies: {
'ember-source': '~3.16.0'
}
}
},
{
name: 'ember-lts-3.20',
npm: {
devDependencies: {
'ember-source': '~3.20.0'
}
}
},
{
name: 'ember-release',
npm: {
Expand Down
1 change: 1 addition & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"compilerOptions":{"target":"es6","experimentalDecorators":true},"exclude":["node_modules","bower_components","tmp","vendor",".git","dist"]}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@
"animation-frame": "~0.2.4",
"broccoli-funnel": "^2.0.2",
"broccoli-merge-trees": "^3.0.2",
"ember-class-based-modifier": "^0.10.0",
"ember-cli-babel": "^7.7.0",
"ember-cli-htmlbars": "^2.0.1",
"ember-cli-version-checker": "^2.1.0",
"ember-copy": "^2.0.0",
"ember-modifier": "^2.1.1",
"fastboot-transform": "^0.1.3",
"hammerjs": "^2.0.8",
"resolve": "^1.10.0"
Expand All @@ -73,7 +73,7 @@
"ember-on-modifier": "1.0.0",
"ember-qunit": "^4.5.1",
"ember-resolver": "^4.0.0",
"ember-source": "~3.1.0",
"ember-source": "~3.3.0",
"ember-source-channel-url": "^1.0.1",
"ember-try": "^0.2.23",
"eslint-plugin-ember": "^5.0.0",
Expand Down