Skip to content

Commit f5ae31a

Browse files
author
Robert Jackson
committed
Initial implementation of emberjs/rfcs#415
This is the initial implementation of [emberjs/rfcs#415](https://emberjs.github.io/rfcs/0415-render-element-modifiers.html). It currently depends on [ember-modifier-manager-polyfill](https://github.com/rwjblue/ember-modifier-manager-polyfill) in order to support Ember versions prior to 3.8 (should work back to at least 2.12).
1 parent 082cfc5 commit f5ae31a

11 files changed

Lines changed: 189 additions & 0 deletions

File tree

addon/.gitkeep

Whitespace-only changes.

addon/modifiers/did-insert.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Ember from 'ember';
2+
3+
export default Ember._setModifierManager(
4+
() => ({
5+
createModifier() {},
6+
7+
installModifier(_state, element, args) {
8+
let [fn, ...positional] = args.positional;
9+
10+
fn(element, positional, args.named);
11+
},
12+
13+
updateModifier() {},
14+
destroyModifier() {},
15+
}),
16+
class DidInsertModifier {}
17+
);

addon/modifiers/did-update.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Ember from 'ember';
2+
3+
export default Ember._setModifierManager(
4+
() => ({
5+
createModifier() {
6+
return { element: null };
7+
},
8+
installModifier(state, element) {
9+
// save element into state bucket
10+
state.element = element;
11+
},
12+
13+
updateModifier({ element }, args) {
14+
let [fn, ...positional] = args.positional;
15+
16+
fn(element, positional, args.named);
17+
},
18+
19+
destroyModifier() {},
20+
}),
21+
class DidUpdateModifier {}
22+
);

addon/modifiers/will-destroy.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Ember from 'ember';
2+
3+
export default Ember._setModifierManager(
4+
() => ({
5+
createModifier() {
6+
return { element: null };
7+
},
8+
9+
installModifier(state, element) {
10+
state.element = element;
11+
},
12+
13+
updateModifier() {},
14+
15+
destroyModifier({ element }, args) {
16+
let [fn, ...positional] = args.positional;
17+
18+
fn(element, positional, args.named);
19+
},
20+
}),
21+
class WillDestroyModifier {}
22+
);

app/.gitkeep

Whitespace-only changes.

app/modifiers/did-insert.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from '@ember/render-modifiers/modifiers/did-insert';

app/modifiers/did-update.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from '@ember/render-modifiers/modifiers/did-update';

app/modifiers/will-destroy.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from '@ember/render-modifiers/modifiers/will-destroy';
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { module, test } from 'qunit';
2+
import { setupRenderingTest } from 'ember-qunit';
3+
import { render } from '@ember/test-helpers';
4+
import hbs from 'htmlbars-inline-precompile';
5+
6+
module('Integration | Modifier | did-insert', function(hooks) {
7+
setupRenderingTest(hooks);
8+
9+
test('it basically works', async function(assert) {
10+
assert.expect(2);
11+
12+
this.someMethod = element => {
13+
assert.equal(element.tagName, 'DIV', 'correct element tagName');
14+
assert.dom(element).hasAttribute('data-foo', 'some-thing');
15+
};
16+
await render(hbs`<div data-foo="some-thing" {{did-insert this.someMethod}}></div>`);
17+
});
18+
19+
test('it can accept arguments', async function(assert) {
20+
assert.expect(4);
21+
22+
this.someMethod = (element, positional, named) => {
23+
assert.equal(element.tagName, 'DIV', 'correct element tagName');
24+
assert.dom(element).hasAttribute('data-foo', 'some-thing');
25+
26+
assert.deepEqual(named, { some: 'hash-value' }, 'named args match');
27+
assert.deepEqual(positional, ['some-positional-value'], 'positional args match');
28+
};
29+
30+
await render(
31+
hbs`<div data-foo="some-thing" {{did-insert this.someMethod "some-positional-value" some="hash-value"}}></div>`
32+
);
33+
});
34+
35+
test('it is not invoked again when arguments change', async function(assert) {
36+
assert.expect(4);
37+
38+
this.someMethod = (element, positional, named) => {
39+
assert.equal(element.tagName, 'DIV', 'correct element tagName');
40+
assert.dom(element).hasAttribute('data-foo', 'some-thing');
41+
42+
assert.deepEqual(named, {}, 'named args match');
43+
assert.deepEqual(positional, ['initial'], 'positional args match');
44+
};
45+
46+
this.set('firstArg', 'initial');
47+
await render(
48+
hbs`<div data-foo="some-thing" {{did-insert this.someMethod this.firstArg}}></div>`
49+
);
50+
this.set('firstArg', 'updated');
51+
});
52+
});
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { module, test } from 'qunit';
2+
import { setupRenderingTest } from 'ember-qunit';
3+
import { render } from '@ember/test-helpers';
4+
import hbs from 'htmlbars-inline-precompile';
5+
6+
module('Integration | Modifier | did-update', function(hooks) {
7+
setupRenderingTest(hooks);
8+
9+
test('it basically works', async function(assert) {
10+
assert.expect(4);
11+
12+
this.someMethod = (element, positional, named) => {
13+
assert.equal(element.tagName, 'DIV', 'correct element tagName');
14+
assert.dom(element).hasAttribute('data-foo', 'some-thing');
15+
16+
assert.deepEqual(named, {}, 'named args match');
17+
assert.deepEqual(positional, ['update'], 'positional args match');
18+
};
19+
20+
this.set('boundValue', 'initial');
21+
await render(
22+
hbs`<div data-foo="some-thing" {{did-update this.someMethod this.boundValue}}></div>`
23+
);
24+
25+
this.set('boundValue', 'update');
26+
});
27+
});

0 commit comments

Comments
 (0)