diff --git a/index.js b/index.js
index 74bc85f..ef7ae02 100644
--- a/index.js
+++ b/index.js
@@ -1,5 +1,6 @@
'use strict';
+const VersionChecker = require('ember-cli-version-checker');
const Funnel = require('broccoli-funnel');
module.exports = {
@@ -8,9 +9,26 @@ module.exports = {
included(...args) {
this._super.included.apply(this, args);
+ const checker = new VersionChecker(this.project);
+ const ember = checker.forEmber();
+
+ this.hasNativeOnModifier = ember.gte('3.11.0-beta.1');
+
this.hasEventHelpers = Boolean(
this.project.findAddonByName('ember-event-helpers')
);
+
+ if (this.hasNativeOnModifier && this.parent === this.project) {
+ let message =
+ 'The `{{on}}` modifier is available natively since Ember 3.11.0-beta.1. You can remove `ember-on-modifier` from your `package.json`.';
+
+ if (!this.hasEventHelpers) {
+ message +=
+ ' If you use the `(prevent-default)` helper, please install `ember-event-helpers`.';
+ }
+
+ this.ui.writeDeprecateLine(message);
+ }
},
treeForApp(...args) {
@@ -22,10 +40,15 @@ module.exports = {
},
filterTree(tree) {
+ const exclude = [];
+
+ if (this.hasNativeOnModifier) {
+ exclude.push(/modifiers/);
+ }
if (this.hasEventHelpers) {
- return new Funnel(tree, { exclude: [/helpers/] });
+ exclude.push(/helpers/);
}
- return tree;
+ return new Funnel(tree, { exclude });
}
};
diff --git a/package.json b/package.json
index e56ccd0..17b5d90 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"dependencies": {
"broccoli-funnel": "^2.0.2",
"ember-cli-babel": "^7.7.3",
+ "ember-cli-version-checker": "^3.1.3",
"ember-modifier-manager-polyfill": "^1.0.3"
},
"devDependencies": {
diff --git a/tests/helpers/ember-on-modifier-polyfill.js b/tests/helpers/ember-on-modifier-polyfill.js
new file mode 100644
index 0000000..287642e
--- /dev/null
+++ b/tests/helpers/ember-on-modifier-polyfill.js
@@ -0,0 +1,6 @@
+import { test, skip } from 'qunit';
+import { gte } from 'ember-compatibility-helpers';
+
+export const onModifierPolyfilled = !gte('3.11.0-beta.1');
+
+export const testIfOnModifierPolyfilled = onModifierPolyfilled ? test : skip;
diff --git a/tests/integration/modifiers/on-test.js b/tests/integration/modifiers/on-test.js
index 260dc5a..621dbd7 100644
--- a/tests/integration/modifiers/on-test.js
+++ b/tests/integration/modifiers/on-test.js
@@ -11,12 +11,16 @@ import hbs from 'htmlbars-inline-precompile';
import { set } from '@ember/object';
import { run } from '@ember/runloop';
import { gte } from 'ember-compatibility-helpers';
+import {
+ testIfOnModifierPolyfilled,
+ onModifierPolyfilled
+} from '../../helpers/ember-on-modifier-polyfill';
module('Integration | Modifier | on', function(hooks) {
setupRenderingTest(hooks);
hooks.afterEach(() => resetOnerror());
- test('it basically works', async function(assert) {
+ testIfOnModifierPolyfilled('it basically works', async function(assert) {
assert.expect(6);
this.someMethod = function(event) {
@@ -47,7 +51,9 @@ module('Integration | Modifier | on', function(hooks) {
assert.counts({ adds: 1, removes: 0 });
});
- test('it can accept the `once` option', async function(assert) {
+ testIfOnModifierPolyfilled('it can accept the `once` option', async function(
+ assert
+ ) {
assert.expect(3);
let n = 0;
@@ -67,121 +73,136 @@ module('Integration | Modifier | on', function(hooks) {
assert.strictEqual(n, 1, 'callback has only been called once');
});
- test('unrelated property changes do not break the `once` option', async function(assert) {
- assert.expect(5);
+ testIfOnModifierPolyfilled(
+ 'unrelated property changes do not break the `once` option',
+ async function(assert) {
+ assert.expect(5);
- let n = 0;
- this.someMethod = () => n++;
- this.someProp = 0;
+ let n = 0;
+ this.someMethod = () => n++;
+ this.someProp = 0;
- await render(
- hbs``
- );
+ await render(
+ hbs``
+ );
- assert.counts({ adds: 1, removes: 0 });
+ assert.counts({ adds: 1, removes: 0 });
- await click('button');
- await click('button');
+ await click('button');
+ await click('button');
- assert.counts({ adds: 1, removes: 0 });
+ assert.counts({ adds: 1, removes: 0 });
- assert.strictEqual(n, 1, 'callback has only been called once');
+ assert.strictEqual(n, 1, 'callback has only been called once');
- run(() => set(this, 'someProp', 1));
- await settled();
- assert.counts({ adds: 1, removes: 0 });
+ run(() => set(this, 'someProp', 1));
+ await settled();
+ assert.counts({ adds: 1, removes: 0 });
- await click('button');
- assert.strictEqual(n, 1, 'callback has only been called once');
- });
+ await click('button');
+ assert.strictEqual(n, 1, 'callback has only been called once');
+ }
+ );
- test('unrelated property changes do not cause the listener to re-register', async function(assert) {
- assert.expect(2);
+ testIfOnModifierPolyfilled(
+ 'unrelated property changes do not cause the listener to re-register',
+ async function(assert) {
+ assert.expect(2);
- this.someMethod = () => {};
- this.someProp = 0;
+ this.someMethod = () => {};
+ this.someProp = 0;
- await render(
- hbs``
- );
- assert.counts({ adds: 1, removes: 0 });
+ await render(
+ hbs``
+ );
+ assert.counts({ adds: 1, removes: 0 });
- run(() => set(this, 'someProp', 1));
- await settled();
- assert.counts({ adds: 1, removes: 0 });
- });
+ run(() => set(this, 'someProp', 1));
+ await settled();
+ assert.counts({ adds: 1, removes: 0 });
+ }
+ );
- test('it can accept the `capture` option', async function(assert) {
- assert.expect(5);
+ testIfOnModifierPolyfilled(
+ 'it can accept the `capture` option',
+ async function(assert) {
+ assert.expect(5);
- this.outerListener = () => assert.step('outer');
- this.innerListener = () => assert.step('inner');
+ this.outerListener = () => assert.step('outer');
+ this.innerListener = () => assert.step('inner');
- await render(hbs`
+ await render(hbs`
`);
- assert.counts({ adds: 2, removes: 0 });
+ assert.counts({ adds: 2, removes: 0 });
- await click('button');
+ await click('button');
- assert.counts({ adds: 2, removes: 0 });
+ assert.counts({ adds: 2, removes: 0 });
- assert.verifySteps(
- ['outer', 'inner'],
- 'outer capture listener was called first'
- );
- });
+ assert.verifySteps(
+ ['outer', 'inner'],
+ 'outer capture listener was called first'
+ );
+ }
+ );
- test('it can accept the `once` & `capture` option combined', async function(assert) {
- assert.expect(6);
+ testIfOnModifierPolyfilled(
+ 'it can accept the `once` & `capture` option combined',
+ async function(assert) {
+ assert.expect(6);
- this.outerListener = () => assert.step('outer');
- this.innerListener = () => assert.step('inner');
+ this.outerListener = () => assert.step('outer');
+ this.innerListener = () => assert.step('inner');
- await render(hbs`
+ await render(hbs`
`);
- assert.counts({ adds: 2, removes: 0 });
+ assert.counts({ adds: 2, removes: 0 });
- await click('button');
- await click('button');
+ await click('button');
+ await click('button');
- assert.counts({ adds: 2, removes: 0 });
+ assert.counts({ adds: 2, removes: 0 });
- assert.verifySteps(
- ['outer', 'inner', 'inner'],
- 'outer capture listener was called first and was then unregistered'
- );
- });
-
- test('it raises an assertion when calling `event.preventDefault()` on a `passive` event', async function(assert) {
- assert.expect(3);
-
- this.handler = event => {
- assert.expectAssertion(
- () => event.preventDefault(),
- `ember-on-modifier: You marked this listener as 'passive', meaning that you must not call 'event.preventDefault()'.`
+ assert.verifySteps(
+ ['outer', 'inner', 'inner'],
+ 'outer capture listener was called first and was then unregistered'
+ );
+ }
+ );
+
+ testIfOnModifierPolyfilled(
+ 'it raises an assertion when calling `event.preventDefault()` on a `passive` event',
+ async function(assert) {
+ assert.expect(3);
+
+ this.handler = event => {
+ assert.expectAssertion(
+ () => event.preventDefault(),
+ `ember-on-modifier: You marked this listener as 'passive', meaning that you must not call 'event.preventDefault()'.`
+ );
+ };
+
+ await render(
+ hbs``
);
- };
-
- await render(
- hbs``
- );
- assert.counts({ adds: 1, removes: 0 });
+ assert.counts({ adds: 1, removes: 0 });
- await click('button');
+ await click('button');
- assert.counts({ adds: 1, removes: 0 });
- });
+ assert.counts({ adds: 1, removes: 0 });
+ }
+ );
- (gte('3.0.0') // I have no clue how to catch the error in Ember 2.13
+ (gte('3.0.0') && onModifierPolyfilled // I have no clue how to catch the error in Ember 2.13
? test
: skip)('it raises an assertion if an invalid event option is passed in', async function(assert) {
assert.expect(2);
@@ -201,7 +222,7 @@ module('Integration | Modifier | on', function(hooks) {
assert.counts({ adds: 0, removes: 0 });
});
- (gte('3.0.0') // I have no clue how to catch the error in Ember 2.13
+ (gte('3.0.0') && onModifierPolyfilled // I have no clue how to catch the error in Ember 2.13
? test
: skip)('it raises an assertion if an invalid event name or callback is passed in', async function(assert) {
setupOnerror(error => assert.step(error.message));
@@ -223,7 +244,7 @@ module('Integration | Modifier | on', function(hooks) {
]);
});
- (gte('3.0.0') // I have no clue how to catch the error in Ember 2.13
+ (gte('3.0.0') && onModifierPolyfilled // I have no clue how to catch the error in Ember 2.13
? test
: skip)('it recovers after updating to incorrect parameters', async function(assert) {
assert.expect(9);
@@ -260,99 +281,108 @@ module('Integration | Modifier | on', function(hooks) {
assert.counts({ adds: 2, removes: 2 });
});
- test('it passes additional parameters through to the listener', async function(assert) {
- assert.expect(11);
-
- this.a = 1;
- this.b = 3;
- this.c = 5;
- this.someMethod = (a, b, c, event) => {
- assert.step([a, b, c].join('-'));
- assert.ok(event instanceof MouseEvent, 'last parameter is an event');
- };
-
- await render(
- hbs``
- );
- assert.counts({ adds: 1, removes: 0 });
-
- await click('button');
- await click('button');
- assert.counts({ adds: 1, removes: 0 });
-
- run(() => set(this, 'c', 7));
- await settled();
- assert.counts({ adds: 2, removes: 1 });
-
- await click('button');
- assert.counts({ adds: 2, removes: 1 });
-
- assert.verifySteps(
- [[1, 3, 5], [1, 3, 5], [1, 3, 7]].map(s => s.join('-')),
- 'parameters were passed through and updated on change'
- );
- });
-
- test('it is re-registered, when the callback changes', async function(assert) {
- assert.expect(6);
-
- let a = 0;
- this.someMethod = () => a++;
+ testIfOnModifierPolyfilled(
+ 'it passes additional parameters through to the listener',
+ async function(assert) {
+ assert.expect(11);
+
+ this.a = 1;
+ this.b = 3;
+ this.c = 5;
+ this.someMethod = (a, b, c, event) => {
+ assert.step([a, b, c].join('-'));
+ assert.ok(event instanceof MouseEvent, 'last parameter is an event');
+ };
+
+ await render(
+ hbs``
+ );
+ assert.counts({ adds: 1, removes: 0 });
- await render(hbs``);
- assert.counts({ adds: 1, removes: 0 });
+ await click('button');
+ await click('button');
+ assert.counts({ adds: 1, removes: 0 });
- await click('button');
- assert.counts({ adds: 1, removes: 0 });
+ run(() => set(this, 'c', 7));
+ await settled();
+ assert.counts({ adds: 2, removes: 1 });
- let b = 0;
- run(() => set(this, 'someMethod', () => b++));
- await settled();
- assert.counts({ adds: 2, removes: 1 });
+ await click('button');
+ assert.counts({ adds: 2, removes: 1 });
- await click('button');
- assert.counts({ adds: 2, removes: 1 });
+ assert.verifySteps(
+ [[1, 3, 5], [1, 3, 5], [1, 3, 7]].map(s => s.join('-')),
+ 'parameters were passed through and updated on change'
+ );
+ }
+ );
- assert.strictEqual(a, 1);
- assert.strictEqual(b, 1);
- });
+ testIfOnModifierPolyfilled(
+ 'it is re-registered, when the callback changes',
+ async function(assert) {
+ assert.expect(6);
- test('it is re-registered, when the callback changes and `capture` is used', async function(assert) {
- assert.expect(9);
+ let a = 0;
+ this.someMethod = () => a++;
- let a = 0;
- this.someMethod = () => a++;
- this.capture = true;
+ await render(hbs``);
+ assert.counts({ adds: 1, removes: 0 });
- await render(
- hbs``
- );
- assert.counts({ adds: 1, removes: 0 });
+ await click('button');
+ assert.counts({ adds: 1, removes: 0 });
- await click('button');
- assert.counts({ adds: 1, removes: 0 });
+ let b = 0;
+ run(() => set(this, 'someMethod', () => b++));
+ await settled();
+ assert.counts({ adds: 2, removes: 1 });
- let b = 0;
- run(() => set(this, 'someMethod', () => b++));
- await settled();
- assert.counts({ adds: 2, removes: 1 });
+ await click('button');
+ assert.counts({ adds: 2, removes: 1 });
- await click('button');
- assert.counts({ adds: 2, removes: 1 });
+ assert.strictEqual(a, 1);
+ assert.strictEqual(b, 1);
+ }
+ );
- let c = 0;
- run(() => {
- set(this, 'someMethod', () => c++);
- set(this, 'capture', false);
- });
- await settled();
- assert.counts({ adds: 3, removes: 2 });
+ testIfOnModifierPolyfilled(
+ 'it is re-registered, when the callback changes and `capture` is used',
+ async function(assert) {
+ assert.expect(9);
- await click('button');
- assert.counts({ adds: 3, removes: 2 });
+ let a = 0;
+ this.someMethod = () => a++;
+ this.capture = true;
- assert.strictEqual(a, 1);
- assert.strictEqual(b, 1);
- assert.strictEqual(c, 1);
- });
+ await render(
+ hbs``
+ );
+ assert.counts({ adds: 1, removes: 0 });
+
+ await click('button');
+ assert.counts({ adds: 1, removes: 0 });
+
+ let b = 0;
+ run(() => set(this, 'someMethod', () => b++));
+ await settled();
+ assert.counts({ adds: 2, removes: 1 });
+
+ await click('button');
+ assert.counts({ adds: 2, removes: 1 });
+
+ let c = 0;
+ run(() => {
+ set(this, 'someMethod', () => c++);
+ set(this, 'capture', false);
+ });
+ await settled();
+ assert.counts({ adds: 3, removes: 2 });
+
+ await click('button');
+ assert.counts({ adds: 3, removes: 2 });
+
+ assert.strictEqual(a, 1);
+ assert.strictEqual(b, 1);
+ assert.strictEqual(c, 1);
+ }
+ );
});
diff --git a/yarn.lock b/yarn.lock
index 18dc3ab..df68b46 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3152,7 +3152,7 @@ ember-cli-version-checker@^2.0.0, ember-cli-version-checker@^2.1.0, ember-cli-ve
resolve "^1.3.3"
semver "^5.3.0"
-ember-cli-version-checker@^3.0.0, ember-cli-version-checker@^3.0.1:
+ember-cli-version-checker@^3.0.0, ember-cli-version-checker@^3.0.1, ember-cli-version-checker@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-3.1.3.tgz#7c9b4f5ff30fdebcd480b1c06c4de43bb51c522c"
integrity sha512-PZNSvpzwWgv68hcXxyjREpj3WWb81A7rtYNQq1lLEgrWIchF8ApKJjWP3NBpHjaatwILkZAV8klair5WFlXAKg==