Skip to content

Commit

Permalink
Merge pull request #1 from rwjblue/initial-implementation
Browse files Browse the repository at this point in the history
Initial implementation of emberjs/rfcs#415
  • Loading branch information
rwjblue authored Jan 28, 2019
2 parents 082cfc5 + e6e04ed commit d27456c
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 0 deletions.
Empty file removed addon/.gitkeep
Empty file.
17 changes: 17 additions & 0 deletions addon/modifiers/did-insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Ember from 'ember';

export default Ember._setModifierManager(
() => ({
createModifier() {},

installModifier(_state, element, args) {
let [fn, ...positional] = args.positional;

fn(element, positional, args.named);
},

updateModifier() {},
destroyModifier() {},
}),
class DidInsertModifier {}
);
22 changes: 22 additions & 0 deletions addon/modifiers/did-update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Ember from 'ember';

export default Ember._setModifierManager(
() => ({
createModifier() {
return { element: null };
},
installModifier(state, element) {
// save element into state bucket
state.element = element;
},

updateModifier({ element }, args) {
let [fn, ...positional] = args.positional;

fn(element, positional, args.named);
},

destroyModifier() {},
}),
class DidUpdateModifier {}
);
22 changes: 22 additions & 0 deletions addon/modifiers/will-destroy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Ember from 'ember';

export default Ember._setModifierManager(
() => ({
createModifier() {
return { element: null };
},

installModifier(state, element) {
state.element = element;
},

updateModifier() {},

destroyModifier({ element }, args) {
let [fn, ...positional] = args.positional;

fn(element, positional, args.named);
},
}),
class WillDestroyModifier {}
);
Empty file removed app/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions app/modifiers/did-insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@ember/render-modifiers/modifiers/did-insert';
1 change: 1 addition & 0 deletions app/modifiers/did-update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@ember/render-modifiers/modifiers/did-update';
1 change: 1 addition & 0 deletions app/modifiers/will-destroy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@ember/render-modifiers/modifiers/will-destroy';
79 changes: 79 additions & 0 deletions tests/integration/modifiers/did-insert-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import Component from '@ember/component';

module('Integration | Modifier | did-insert', function(hooks) {
setupRenderingTest(hooks);

test('it basically works', async function(assert) {
assert.expect(2);

this.someMethod = element => {
assert.equal(element.tagName, 'DIV', 'correct element tagName');
assert.dom(element).hasAttribute('data-foo', 'some-thing');
};
await render(hbs`<div data-foo="some-thing" {{did-insert this.someMethod}}></div>`);
});

test('it can accept arguments', async function(assert) {
assert.expect(4);

this.someMethod = (element, positional, named) => {
assert.equal(element.tagName, 'DIV', 'correct element tagName');
assert.dom(element).hasAttribute('data-foo', 'some-thing');

assert.namedArgsEqual(named, { some: 'hash-value' }, 'named args match');
assert.deepEqual(positional, ['some-positional-value'], 'positional args match');
};

await render(
hbs`<div data-foo="some-thing" {{did-insert this.someMethod "some-positional-value" some="hash-value"}}></div>`
);
});

test('it is not invoked again when arguments change', async function(assert) {
assert.expect(4);

this.someMethod = (element, positional, named) => {
assert.equal(element.tagName, 'DIV', 'correct element tagName');
assert.dom(element).hasAttribute('data-foo', 'some-thing');

assert.namedArgsEqual(named, {}, 'named args match');
assert.deepEqual(positional, ['initial'], 'positional args match');
};

this.set('firstArg', 'initial');
await render(
hbs`<div data-foo="some-thing" {{did-insert this.someMethod this.firstArg}}></div>`
);
this.set('firstArg', 'updated');
});

test('adding class on insert (RFC example)', async function(assert) {
this.owner.register(
'component:sometimes-fades-in',
Component.extend({
fadeIn(element) {
element.classList.add('fade-in');
},
})
);

this.owner.register(
'template:components/sometimes-fades-in',
hbs`
{{#if shouldShow}}
<div {{did-insert this.fadeIn}} class="alert">
{{yield}}
</div>
{{/if}}
`
);

await render(hbs`{{sometimes-fades-in shouldShow=true}}`);

assert.dom('.alert').hasClass('fade-in');
});
});
27 changes: 27 additions & 0 deletions tests/integration/modifiers/did-update-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Modifier | did-update', function(hooks) {
setupRenderingTest(hooks);

test('it basically works', async function(assert) {
assert.expect(4);

this.someMethod = (element, positional, named) => {
assert.equal(element.tagName, 'DIV', 'correct element tagName');
assert.dom(element).hasAttribute('data-foo', 'some-thing');

assert.namedArgsEqual(named, {}, 'named args match');
assert.deepEqual(positional, ['update'], 'positional args match');
};

this.set('boundValue', 'initial');
await render(
hbs`<div data-foo="some-thing" {{did-update this.someMethod this.boundValue}}></div>`
);

this.set('boundValue', 'update');
});
});
46 changes: 46 additions & 0 deletions tests/integration/modifiers/will-destroy-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Modifier | will-destroy', function(hooks) {
setupRenderingTest(hooks);

test('it basically works', async function(assert) {
assert.expect(2);

this.someMethod = element => {
assert.equal(element.tagName, 'DIV', 'correct element tagName');
assert.dom(element).hasAttribute('data-foo', 'some-thing');
};
this.set('show', true);

await render(
hbs`{{#if show}}<div data-foo="some-thing" {{will-destroy this.someMethod}}></div>{{/if}}`
);

// trigger destroy
this.set('show', false);
});

test('it can accept arguments', async function(assert) {
assert.expect(4);

this.someMethod = (element, positional, named) => {
assert.equal(element.tagName, 'DIV', 'correct element tagName');
assert.dom(element).hasAttribute('data-foo', 'some-thing');

assert.namedArgsEqual(named, { some: 'hash-value' }, 'named args match');
assert.deepEqual(positional, ['some-positional-value'], 'positional args match');
};

this.set('show', true);

await render(
hbs`{{#if show}}<div data-foo="some-thing" {{will-destroy this.someMethod "some-positional-value" some="hash-value"}}></div>{{/if}}`
);

// trigger destroy
this.set('show', false);
});
});
10 changes: 10 additions & 0 deletions tests/test-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@ import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';
import { start } from 'ember-qunit';
import { assign } from '@ember/polyfills';
import QUnit from 'qunit';

setApplication(Application.create(config.APP));

start();

QUnit.assert.namedArgsEqual = function(actual, expected, message) {
// this is needed because older versions of Ember pass an `EmptyObject`
// based object and QUnit fails due to the prototypes not matching
let sanitizedActual = assign({}, actual);

this.deepEqual(sanitizedActual, expected, message);
};

0 comments on commit d27456c

Please sign in to comment.