Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Commit

Permalink
added prepareInstancePositionChanged delegate method
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelw committed Oct 16, 2013
1 parent 8242f08 commit 786825e
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 8 deletions.
70 changes: 66 additions & 4 deletions src/TemplateBinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,14 @@
return instanceNodes;
},

getDelegateFunction: function(delegate, name, template) {
if (!delegate || typeof delegate[name] !== 'function')
return null;

var fn = delegate[name](template);
return typeof fn === 'function' ? fn : null;
},

handleSplices: function(splices) {
if (this.closed)
return;
Expand All @@ -1014,10 +1022,15 @@
}

if (this.instanceModelFn_ === undefined) {
if (delegate && typeof delegate.prepareInstanceModel === 'function')
this.instanceModelFn_ = delegate.prepareInstanceModel(template);
if (typeof this.instanceModelFn_ !== 'function')
this.instanceModelFn_ = false;
this.instanceModelFn_ = this.getDelegateFunction(delegate,
'prepareInstanceModel',
template);
}

if (this.instancePositionChangedFn_ === undefined) {
this.instancePositionChangedFn_ =
this.getDelegateFunction(delegate, 'prepareInstancePositionChanged',
template);
}

var instanceCache = new Map;
Expand Down Expand Up @@ -1061,6 +1074,55 @@
instanceCache.forEach(function(instanceNodes) {
this.closeInstanceBindings(instanceNodes.bound);
}, this);

if (this.instancePositionChangedFn_)
this.reportInstancesMoved(splices);
},

reportInstanceMoved: function(index) {
var previousTerminator = this.getTerminatorAt(index - 1);
var terminator = this.getTerminatorAt(index);
if (previousTerminator === terminator)
return; // instance has zero nodes.

// We must use the first node of the instance, because any subsequent
// nodes may have been generated by sub-templates.
// TODO(rafaelw): This is brittle WRT instance mutation -- e.g. if the
// first node was removed by script.
var templateInstance = previousTerminator.nextSibling.templateInstance;
this.instancePositionChangedFn_(templateInstance, index);
},

reportInstancesMoved: function(splices) {
var index = 0;
var offset = 0;
for (var i = 0; i < splices.length; i++) {
var splice = splices[i];
if (offset != 0) {
while (index < splice.index) {
this.reportInstanceMoved(index);
index++;
}
} else {
index = splice.index;
}

while (index < splice.index + splice.addedCount) {
this.reportInstanceMoved(index);
index++;
}

offset += splice.addedCount - splice.removed.length;
}

if (offset == 0)
return;

var length = this.terminators.length / 2;
while (index < length) {
this.reportInstanceMoved(index);
index++;
}
},

closeInstanceBindings: function(bound) {
Expand Down
66 changes: 62 additions & 4 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1859,7 +1859,7 @@ suite('Template Instantiation', function() {

var template = div.firstChild;

var model = {
var model = {
show: true,
items: [1]
};
Expand Down Expand Up @@ -1890,7 +1890,7 @@ suite('Binding Delegate API', function() {

teardown(doTeardown);

test('Registration', function() {
test('prepareBinding', function() {
var model = { foo: 'bar'};
var prepareBindData = {
type: 'prepare',
Expand Down Expand Up @@ -1967,7 +1967,7 @@ suite('Binding Delegate API', function() {
assert.strictEqual(0, testData.length);
});

test('getInstanceModel', function() {
test('prepareInstanceModel', function() {
var model = [{ foo: 1 }, { foo: 2 }, { foo: 3 }];

var div = createTestHtml(
Expand Down Expand Up @@ -2017,7 +2017,7 @@ suite('Binding Delegate API', function() {
assert.strictEqual(0, testData.length);
});

test('getInstanceModel - reorder instances', function() {
test('prepareInstanceModel - reorder instances', function() {
var model = [0, 1, 2];

var div = createTestHtml(
Expand Down Expand Up @@ -2048,6 +2048,64 @@ suite('Binding Delegate API', function() {
assert.strictEqual(3, callCount);
});

test('prepareInstancePositionChanged', function() {
var model = ['a', 'b', 'c'];

var div = createTestHtml(
'<template repeat>' +
'{{}}</template>');
var template = div.firstChild;

var testData = [
{
template: template,
},
{
model: model[0],
index: 0
},
{
model: model[1],
index: 1
},
{
model: model[2],
index: 2
},
// After splice
{
model: model[2],
index: 1
}
];

var delegate = {
prepareInstancePositionChanged: function(template) {
var data = testData.shift();
assert.strictEqual(data.template, template);

return function(templateInstance, index) {
data = testData.shift();
assert.strictEqual(data.model, templateInstance.model);
assert.strictEqual(data.index, index);
}
}
};

recursivelySetTemplateModel(div, model, delegate);
Platform.performMicrotaskCheckpoint();
assert.strictEqual(4, div.childNodes.length);
assert.strictEqual('TEMPLATE', div.childNodes[0].tagName);
assert.strictEqual('a', div.childNodes[1].textContent);
assert.strictEqual('b', div.childNodes[2].textContent);
assert.strictEqual('c', div.childNodes[3].textContent);

model.splice(1, 1);
Platform.performMicrotaskCheckpoint();

assert.strictEqual(0, testData.length);
});

test('Basic', function() {
var model = { foo: 2, bar: 4 };

Expand Down

0 comments on commit 786825e

Please sign in to comment.