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

Feat/sustain hooks #29

Merged
merged 5 commits into from
Mar 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions addon/components/flexi-sustain.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const component = Component.extend({
copy: false,
expires: null,

didInsertElement() {
willInsertElement() {
let element = this.element || this._renderNode;
let properties = this.getProperties('label', 'component', 'model', 'copy', 'expires');

Expand All @@ -27,7 +27,7 @@ const component = Component.extend({
},

willDestroyElement() {
this.get('sustains').uninstall(this.element || this._renderNode, this.get('sustain'));
this.get('sustains').uninstall(this.element || this._renderNode, this.get('label'));
this._super();
},

Expand Down
43 changes: 36 additions & 7 deletions addon/lib/sustain.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const {
Object: Obj
} = Ember;

const DEFAULT_EXPIRES = 1000 * 5; // 5s

export default Obj.extend({
_isSustainFactory: true,

Expand All @@ -17,7 +19,7 @@ export default Obj.extend({
label: null,
model: null,
copy: false,
expires: 1000 * 5, // 5s
expires: DEFAULT_EXPIRES,

// the element where the content should currently be rendered
parent: null,
Expand All @@ -31,6 +33,7 @@ export default Obj.extend({

// caches the teardown handler
removeTimeout: null,
storeTimeout: null,

// caches clone info
_previousParent: null,
Expand All @@ -53,16 +56,26 @@ export default Obj.extend({
this._previousClone = this.cloneNodeRange();
}

this.scheduleStorage();
this.scheduleRemove();

this.triggerHook('willMove');
},

triggerHook(name) {
if (this._component[name]) {
this._component[name]();
}
this._component.trigger(name);
},

// called each time the location of parent has changed
insert(to) {
run.cancel(this.removeTimeout);
run.cancel(this.storeTimeout);

// initial insert
if (!this._isReady) {

this.parent = to.parent;
return;
}
Expand All @@ -72,8 +85,10 @@ export default Obj.extend({
appendCachedRange(to.parent, this._cachedRange);
this._cachedRange = null;
} else {
this.triggerHook('willMove');
appendRange(to.parent, this.range.firstNode, this.range.lastNode);
}
this.triggerHook('didMove');

// leave copy in old location
if (this._previousClone) {
Expand Down Expand Up @@ -106,11 +121,11 @@ export default Obj.extend({
let node = this.range.firstNode;
let list = [];

list.push(node);
while (node !== this.range.lastNode) {
list.push(node);
node = node.nextSibling;
}
list.push(node);

return list;
},
Expand All @@ -125,6 +140,14 @@ export default Obj.extend({
return list;
},

scheduleStorage() {
this.storeTimeout = run.next(this, this.store);
},

store() {
appendRange(this._fragment, this.range.firstNode, this.range.lastNode);
},

scheduleRemove() {
let expires = this.get('expires');

Expand All @@ -139,6 +162,7 @@ export default Obj.extend({
if (this.parent && this.parent === this._component.element) {
return;
}

this.destroy();
},

Expand Down Expand Up @@ -173,6 +197,7 @@ export default Obj.extend({

if (this.parent) {
appendRange(this.parent, this.range.firstNode, this.range.lastNode);
this.triggerHook('didMove');
}
},

Expand All @@ -189,20 +214,24 @@ export default Obj.extend({

this._component.set('model', model);

let _super = this._component.get('didInsertElement');
let _super = this._component.willInsertElement;

this._component.set('didInsertElement', () => {
this._component.willInsertElement = () => {
this.isReady();
if (_super) {
_super();
_super.call(this._component);
}
});
};
this._fragment = this._component.renderToElement();
},

init() {
this._super();
this.setupComponent();

if (!this.expires && this.expires !== 0) {
this.expires = DEFAULT_EXPIRES;
}
}

});
39 changes: 39 additions & 0 deletions tests/acceptance/sustain-hooks-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { test } from 'qunit';
import Ember from 'ember';
import moduleForAcceptance from '../../tests/helpers/module-for-acceptance';

const {
run
} = Ember;

moduleForAcceptance('Acceptance | sustain hooks');

test('Testing sustain-hooks', function(assert) {
visit('/tests/sustain-hooks');

andThen(() => {
assert.equal(currentURL(), '/tests/sustain-hooks');

let registry = this.application.__container__.lookup('-view-registry:main') || Ember.View.views;
let component = registry['sustain-hooks-test'];

assert.ok(component.get('didMoveTriggered'), 'didMove triggers on initial insert');
assert.ok(component.get('didMoveEvent'), 'didMove event triggers on initial insert');

assert.notOk(component.get('willMoveTriggered'), 'willMove does not trigger on initial insert');
assert.notOk(component.get('willMoveEvent'), 'willMove event does not trigger on initial insert');

assert.ok(component.get('insertTriggered'), 'didInsertElement properly triggers its super');

let controller = this.application.__container__.lookup('controller:tests/sustain-hooks');

run(() => {
controller.set('showSustain', false);
});

andThen(() => {
assert.ok(component.get('willMoveTriggered'), 'willMove triggers when leaving a location');
assert.ok(component.get('willMoveEvent'), 'willMove event triggers when leaving a location');
});
});
});
19 changes: 15 additions & 4 deletions tests/acceptance/sustain-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,29 @@ test('visiting /tests/sustain', function(assert) {
andThen(() => {
assert.equal(currentURL(), '/tests/sustain', 'We transitioned to the initial route');

assert.equal(find('h2.sustain-test').text(), 'I ought to be sustained', 'We rendered the sustain');
assert.equal(find('h2.sustain-test').eq(0).text(), 'I ought to be sustained', 'We rendered the sustain');
let id1 = find('layout.sustain-test').get(0).id;
let id2 = find('layout.sustain-test').get(1).id;
let children = find('.tagless-stuff');

assert.ok(id2, 'we found two IDs');
assert.equal(children.length, 2, 'we have two tagless children');

click('#next-sustain-test-page');

andThen(() => {
assert.equal(currentURL(), '/tests/sustain-b', 'We transitioned to the next route');

assert.equal(find('h2.sustain-test').text(), 'I ought to be sustained', 'We rendered the sustain on the next page');
let id2 = find('layout.sustain-test').get(0).id;
assert.equal(find('h2.sustain-test').eq(0).text(), 'I ought to be sustained', 'We rendered the sustain on the next page');
let id3 = find('layout.sustain-test').get(0).id;
let id4 = find('layout.sustain-test').get(1).id;
let children = find('.tagless-stuff');

assert.ok(id4, 'we found two IDs');
assert.equal(children.length, 2, 'we still have two tagless children');

assert.equal(id1, id2, 'We rendered the identical sustain');
assert.equal(id1, id3, 'We rendered the identical sustain');
assert.equal(id2, id4, 'We rendered the identical tagless sustain');
});

});
Expand Down
1 change: 1 addition & 0 deletions tests/dummy/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Router.map(function() {
this.route('sustain-no-layout');
this.route('sustain-labels');
this.route('sustain-labels-2');
this.route('sustain-hooks');
});

this.route('docs', function() {
Expand Down
13 changes: 13 additions & 0 deletions tests/dummy/app/routes/docs/sustain/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@
</p>
{{code-snippet name='sustain-6.hbs'}}

<h4>Lifecycle Hooks</h4>
<p>
The component being sustained has access to two new hooks: `willMove` and `didMove`.
For both, a method by that name on your component will trigger before the event fires.
</p>
<ul>
<li>willMove: fires before a component instance leaves a location</li>
<li>didMove: fires when a component instance has entered a location</li>
</ul>
<p>
On the initial render and insertion of a sustained component, only `didMove` triggers.
</p>

</box>
</box>

Expand Down
3 changes: 2 additions & 1 deletion tests/dummy/app/routes/tests/sustain-b/template.hbs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
{{sustain 'tests/sustain/components/test-title'}}
{{sustain 'tests/sustain/components/test-title'}}
{{sustain 'tests/sustain/components/tagless-title'}}
5 changes: 5 additions & 0 deletions tests/dummy/app/routes/tests/sustain-hooks/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Ember from 'ember';

export default Ember.Controller.extend({
showSustain: true
});
39 changes: 39 additions & 0 deletions tests/dummy/app/routes/tests/sustain-hooks/has-hooks/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Ember from 'ember';

const {
Component,
on
} = Ember;

export default Component.extend({
elementId: 'sustain-hooks-test',

insertTriggered: false,
willMoveTriggered: false,
didMoveTriggered: false,

willMoveEvent: false,
didMoveEvent: false,

didMove() {
this.set('didMoveTriggered', true);
},

willMove() {
this.set('willMoveTriggered', true);
},

_onDidMove: on('didMove', function() {
this.set('didMoveEvent', true);
}),

_onWillMove: on('willMove', function() {
this.set('willMoveEvent', true);
}),

willInsertElement() {
this._super();
this.set('insertTriggered', true);
}

});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Rendered!</h1>
4 changes: 4 additions & 0 deletions tests/dummy/app/routes/tests/sustain-hooks/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Ember from 'ember';

export default Ember.Route.extend({
});
3 changes: 3 additions & 0 deletions tests/dummy/app/routes/tests/sustain-hooks/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{#if showSustain}}
{{sustain "tests/sustain-hooks/has-hooks"}}
{{/if}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Ember from 'ember';
import layout from './template';

export default Ember.Component.extend({
layout,
tagName: ''
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{#flexi-layout tagName="layout" class="sustain-test tagless-stuff flexi-layout"}}
<h2 class="sustain-test">I ought to be sustained</h2>
<p>If I was, the component above's ID will be identical.</p>
{{/flexi-layout}}
<div class="tagless-stuff">
<h3>More Tagless Stuff</h3>
</div>
3 changes: 2 additions & 1 deletion tests/dummy/app/routes/tests/sustain/template.hbs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
{{#link-to 'tests.sustain-b' id="next-sustain-test-page"}}Go to B{{/link-to}}
{{sustain 'tests/sustain/components/test-title'}}
{{sustain 'tests/sustain/components/test-title'}}
{{sustain 'tests/sustain/components/tagless-title'}}