Remove limit & chunkCount API. Refactor insert/remove.

This commit is contained in:
Kevin Schaaf 2015-11-04 17:39:42 -08:00
parent 59c27fa4c3
commit f447c0eb70
3 changed files with 243 additions and 275 deletions

View File

@ -190,19 +190,6 @@ Then the `observe` property should be configured as follows:
*/
delay: Number,
/**
* When `limit` is defined, the number of actually rendered template
* instances will be limited to this count.
*
* Note that if `initialCount` is used, the `limit` property will be
* automatically controlled and should not be set by the user.
*/
limit: {
value: Infinity,
type: Number,
observer: '_limitChanged'
},
/**
* Defines an initial count of template instances to render after setting
* the `items` array, before the next paint, and puts the `dom-repeat`
@ -213,28 +200,16 @@ Then the `observe` property should be configured as follows:
*/
initialCount: {
type: Number,
value: 0
observer: '_initializeChunking'
},
/**
* When `initialCount` is used, defines the number of instances to be
* created at each animation frame after rendering the `initialCount`.
* When left to the default `'auto'` value, the chunk count will be
* throttled automatically using a best effort scheme to maintain the
* value of the `targetFramerate` property.
*/
chunkCount: {
type: Number,
value: 'auto'
},
/**
* When `initialCount` is used and `chunkCount` is set to `'auto'`, this
* property defines a frame rate to target by throttling the number of
* instances rendered each frame to not exceed the budget for the target
* frame rate. Setting this to a higher number will allow lower latency
* and higher throughput for things like event handlers, but will result
* in a longer time for the remaining items to complete rendering.
* When `initialCount` is used, this property defines a frame rate to
* target by throttling the number of instances rendered each frame to
* not exceed the budget for the target frame rate. Setting this to a
* higher number will allow lower latency and higher throughput for
* things like event handlers, but will result in a longer time for the
* remaining items to complete rendering.
*/
targetFramerate: {
type: Number,
@ -252,32 +227,29 @@ Then the `observe` property should be configured as follows:
],
observers: [
'_itemsChanged(items.*)',
'_initializeChunkCount(initialCount, chunkCount)'
'_itemsChanged(items.*)'
],
created: function() {
this._instances = [];
this._pool = [];
this._boundRenderChunk = this._renderChunk.bind(this);
this._limit = Infinity;
var self = this;
this._boundRenderChunk = function() {
self._renderChunk();
};
},
detached: function() {
for (var i=0; i<this._instances.length; i++) {
var inst = this._instances[i];
if (!inst.isPlaceholder) {
this._detachRow(i, true);
}
this._detachInstance(i);
}
},
attached: function() {
var parentNode = Polymer.dom(this).parentNode;
var parent = Polymer.dom(Polymer.dom(this).parentNode);
for (var i=0; i<this._instances.length; i++) {
var inst = this._instances[i];
if (!inst.isPlaceholder) {
Polymer.dom(parentNode).insertBefore(inst.root, this);
}
this._attachInstance(i, parent);
}
},
@ -316,26 +288,22 @@ Then the `observe` property should be configured as follows:
}
},
_limitChanged: function(limit) {
if (this.items) {
this._debounceTemplate(this._render);
}
},
_computeFrameTime: function(rate) {
return Math.ceil(1000/rate);
},
_initializeChunkCount: function() {
_initializeChunking: function() {
if (this.initialCount) {
this.limit = this.initialCount;
this._chunkCount = parseInt(this.chunkCount, 10) || this.initialCount;
this._limit = this.initialCount;
this._chunkCount = this.initialCount;
this._lastChunkTime = performance.now();
}
},
_tryRenderChunk: function() {
if (this._chunkCount &&
Math.min(this.limit, this._instances.length) < this.items.length) {
// Debounced so that multiple calls through `_render` between animation
// frames only queue one new rAF (e.g. array mutation & chunked render)
if (this.items && this._limit < this.items.length) {
this.debounce('renderChunk', this._requestRenderChunk);
}
},
@ -345,19 +313,16 @@ Then the `observe` property should be configured as follows:
},
_renderChunk: function() {
if (this.chunkCount == 'auto') {
// Simple auto chunkSize throttling algorithm based on feedback loop:
// measure actual time between frames and scale chunk count by ratio
// of target/actual frame time
var prevChunkTime = this._currChunkTime;
this._currChunkTime = performance.now();
var chunkTime = this._currChunkTime - prevChunkTime;
if (chunkTime) {
var ratio = this._targetFrameTime / chunkTime;
this._chunkCount = Math.round(this._chunkCount * ratio) || 1;
}
}
this.limit += this._chunkCount;
// Simple auto chunkSize throttling algorithm based on feedback loop:
// measure actual time between frames and scale chunk count by ratio
// of target/actual frame time
var lastChunkTime = this._lastChunkTime;
var currChunkTime = performance.now();
var ratio = this._targetFrameTime / (currChunkTime - lastChunkTime);
this._chunkCount = Math.round(this._chunkCount * ratio) || 1;
this._limit += this._chunkCount;
this._lastChunkTime = currChunkTime;
this._debounceTemplate(this._render);
},
_observeChanged: function() {
@ -375,12 +340,10 @@ Then the `observe` property should be configured as follows:
this._error(this._logf('dom-repeat', 'expected array for `items`,' +
' found', this.items));
}
if (this._instances.length && this.initialCount) {
this._initializeChunkCount();
}
this._keySplices = [];
this._indexSplices = [];
this._needFullRefresh = true;
this._initializeChunking();
this._debounceTemplate(this._render);
} else if (change.path == 'items.splices') {
this._keySplices = this._keySplices.concat(change.value.keySplices);
@ -432,9 +395,11 @@ Then the `observe` property should be configured as follows:
var c = this.collection;
// Choose rendering path: full vs. incremental using splices
if (this._needFullRefresh) {
// Full refresh when items, sort, filter change or render() called
this._applyFullRefresh();
this._needFullRefresh = false;
} else if (this._keySplices.length) {
// Incremental refresh when splices were queued
if (this._sortFn) {
this._applySplicesUserSort(this._keySplices);
} else {
@ -445,6 +410,9 @@ Then the `observe` property should be configured as follows:
this._applySplicesArrayOrder(this._indexSplices);
}
}
} else {
// Otherwise only limit changed; no change to instances, just need to
// upgrade more placeholders to instances
}
this._keySplices = [];
this._indexSplices = [];
@ -452,10 +420,10 @@ Then the `observe` property should be configured as follows:
var keyToIdx = this._keyToInstIdx = {};
for (var i=this._instances.length-1; i>=0; i--) {
var inst = this._instances[i];
if (inst.isPlaceholder && i<this.limit) {
inst = this._insertRow(i, inst.__key__, true);
} else if (!inst.isPlaceholder && i>=this.limit) {
inst = this._insertRow(i, inst.__key__, true, true);
if (inst.isPlaceholder && i<this._limit) {
inst = this._upgradePlaceholder(i, inst.__key__);
} else if (!inst.isPlaceholder && i>=this._limit) {
inst = this._downgradeInstance(i, inst.__key__);
}
keyToIdx[inst.__key__] = i;
if (!inst.isPlaceholder) {
@ -514,16 +482,16 @@ Then the `observe` property should be configured as follows:
var inst = this._instances[i];
if (inst) {
inst.__key__ = key;
if (!inst.isPlaceholder && i < this.limit) {
if (!inst.isPlaceholder && i < this._limit) {
inst.__setProperty(this.as, c.getItem(key), true);
}
} else {
this._insertRow(i, key);
this._insertPlaceholder(i, key);
}
}
// Remove any extra instances from previous state
for (var j=this._instances.length-1; j>=i; j--) {
this._detachRow(j);
this._removeInstance(j);
}
},
@ -576,7 +544,7 @@ Then the `observe` property should be configured as follows:
var idx = removedIdxs[i];
// Removed idx may be undefined if item was previously filtered out
if (idx !== undefined) {
this._detachRow(idx);
this._removeInstance(idx);
}
}
}
@ -624,7 +592,7 @@ Then the `observe` property should be configured as follows:
idx = end + 1;
}
// Insert instance at insertion point
this._insertRow(idx, key);
this._insertPlaceholder(idx, key);
return idx;
},
@ -638,65 +606,48 @@ Then the `observe` property should be configured as follows:
splices.forEach(function(s) {
// Detach & pool removed instances
for (var i=0; i<s.removed.length; i++) {
this._detachRow(s.index);
this._removeInstance(s.index);
}
for (var i=0; i<s.addedKeys.length; i++) {
this._insertRow(s.index+i, s.addedKeys[i], false, true);
this._insertPlaceholder(s.index+i, s.addedKeys[i]);
}
}, this);
},
_detachRow: function(idx, keepInstance) {
_detachInstance: function(idx) {
var inst = this._instances[idx];
if (!inst.isPlaceholder) {
var parentNode = Polymer.dom(this).parentNode;
for (var i=0; i<inst._children.length; i++) {
var el = inst._children[i];
Polymer.dom(inst.root).appendChild(el);
}
if (!keepInstance) {
this._pool.push(inst);
}
return inst;
}
if (!keepInstance) {
this._instances.splice(idx, 1);
}
return inst;
},
_insertRow: function(idx, key, replace, makePlaceholder) {
var inst;
if (makePlaceholder || idx >= this.limit) {
inst = {
isPlaceholder: true,
__key__: key
};
} else {
if (inst = this._pool.pop()) {
// TODO(kschaaf): If the pool is shared across turns, parentProps
// need to be re-set to reused instances in addition to item/key
inst.__setProperty(this.as, this.collection.getItem(key), true);
inst.__setProperty('__key__', key, true);
} else {
inst = this._generateRow(idx, key);
}
var beforeRow = this._instances[replace ? idx + 1 : idx];
var beforeNode = beforeRow && !beforeRow.isPlaceholder ? beforeRow._children[0] : this;
var parentNode = Polymer.dom(this).parentNode;
Polymer.dom(parentNode).insertBefore(inst.root, beforeNode);
_attachInstance: function(idx, parent) {
var inst = this._instances[idx];
if (!inst.isPlaceholder) {
parent.insertBefore(inst.root, this);
}
if (replace) {
if (makePlaceholder) {
this._detachRow(idx, true);
}
this._instances[idx] = inst;
} else {
this._instances.splice(idx, 0, inst);
}
return inst;
},
_generateRow: function(idx, key) {
_removeInstance: function(idx) {
var inst = this._detachInstance(idx);
if (inst) {
this._pool.push(inst);
}
this._instances.splice(idx, 1);
},
_insertPlaceholder: function(idx, key) {
this._instances.splice(idx, 0, {
isPlaceholder: true,
__key__: key
});
},
_generateInstance: function(idx, key) {
var model = {
__key__: key
};
@ -706,6 +657,37 @@ Then the `observe` property should be configured as follows:
return inst;
},
_upgradePlaceholder: function(idx, key) {
var inst = this._pool.pop();
if (inst) {
// TODO(kschaaf): If the pool is shared across turns, parentProps
// need to be re-set to reused instances in addition to item/key
inst.__setProperty(this.as, this.collection.getItem(key), true);
inst.__setProperty('__key__', key, true);
} else {
inst = this._generateInstance(idx, key);
}
var beforeRow = this._instances[idx + 1 ];
var beforeNode = beforeRow && !beforeRow.isPlaceholder ? beforeRow._children[0] : this;
var parentNode = Polymer.dom(this).parentNode;
Polymer.dom(parentNode).insertBefore(inst.root, beforeNode);
this._instances[idx] = inst;
return inst;
},
_downgradeInstance: function(idx, key) {
var inst = this._detachInstance(idx);
if (inst) {
this._pool.push(inst);
}
inst = {
isPlaceholder: true,
__key__: key
};
this._instances[idx] = inst;
return inst;
},
// Implements extension point from Templatizer mixin
_showHideChildren: function(hidden) {
for (var i=0; i<this._instances.length; i++) {

View File

@ -414,7 +414,7 @@ window.data = [
<dom-module id="x-repeat-limit">
<template>
<template id="repeater" is="dom-repeat" items="{{items}}" limit="2">
<template id="repeater" is="dom-repeat" items="{{items}}">
<div prop="{{outerProp.prop}}">{{item.prop}}</div>
</template>
</template>
@ -422,7 +422,7 @@ window.data = [
Polymer({
is: 'x-repeat-limit',
properties: {
items: {
preppedItems: {
value: function() {
var ar = [];
for (var i = 0; i < 20; i++) {

View File

@ -3365,6 +3365,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
};
test('initial limit', function() {
limited.items = limited.preppedItems;
limited.$.repeater._limit = 2;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 2);
checkItemOrder(stamped);
@ -3381,54 +3384,50 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
assert.equal(stamped[0].prop, 'changed again');
});
test('increase limit', function(done) {
// Increase limit and test async rendering
limited.$.repeater.limit = 10;
setTimeout(function() {
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
assert.equal(stamped[3].prop, 'changed again');
assert.equal(stamped[3].textContent, '3-changed');
limited.set('items.0.prop', 0);
limited.set('items.3.prop', 3);
// Increase limit and test sync rendering
limited.$.repeater.limit = 20;
Polymer.dom.flush();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 20);
checkItemOrder(stamped);
done();
});
test('increase limit', function() {
// Increase limit
limited.$.repeater._limit = 10;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
assert.equal(stamped[3].prop, 'changed again');
assert.equal(stamped[3].textContent, '3-changed');
limited.set('items.0.prop', 0);
limited.set('items.3.prop', 3);
// Increase limit
limited.$.repeater._limit = 20;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 20);
checkItemOrder(stamped);
});
test('increase limit above items.length', function() {
limited.$.repeater.limit = 30;
Polymer.dom.flush();
limited.$.repeater._limit = 30;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 20);
checkItemOrder(stamped);
checkItemOrder(stamped);
});
test('decrease limit', function(done) {
// Decrease limit and test async rendering
limited.$.repeater.limit = 15;
setTimeout(function() {
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 15);
checkItemOrder(stamped);
// Decrease limit and test sync rendering
limited.$.repeater.limit = 0;
Polymer.dom.flush();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
done();
});
test('decrease limit', function() {
// Decrease limit
limited.$.repeater._limit = 15;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 15);
checkItemOrder(stamped);
// Decrease limit
limited.$.repeater._limit = 0;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
});
test('negative limit', function() {
limited.$.repeater.limit = -10;
Polymer.dom.flush();
limited.$.repeater._limit = -10;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
});
@ -3444,64 +3443,59 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
};
test('initial limit', function() {
var items = limited.items;
limited.$.repeater.limit = 2;
limited.$.repeater._limit = 2;
limited.$.repeater.sort = function(a, b) {
return b.prop - a.prop;
};
limited.items = null;
Polymer.dom.flush();
limited.items = items;
Polymer.dom.flush();
limited.$.repeater.render();
limited.items = limited.preppedItems;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 2);
checkItemOrder(stamped);
});
test('increase limit', function(done) {
// Increase limit and test async rendering
limited.$.repeater.limit = 10;
setTimeout(function() {
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
// Increase limit and test sync rendering
limited.$.repeater.limit = 20;
Polymer.dom.flush();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 20);
checkItemOrder(stamped);
done();
});
test('increase limit', function() {
// Increase limit
limited.$.repeater._limit = 10;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
// Increase limit
limited.$.repeater._limit = 20;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 20);
checkItemOrder(stamped);
});
test('increase limit above items.length', function() {
limited.$.repeater.limit = 30;
Polymer.dom.flush();
limited.$.repeater._limit = 30;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 20);
checkItemOrder(stamped);
checkItemOrder(stamped);
});
test('decrease limit', function(done) {
// Decrease limit and test async rendering
limited.$.repeater.limit = 15;
setTimeout(function() {
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 15);
checkItemOrder(stamped);
// Decrease limit and test sync rendering
limited.$.repeater.limit = 0;
Polymer.dom.flush();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
done();
});
test('decrease limit', function() {
// Decrease limit
limited.$.repeater._limit = 15;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 15);
checkItemOrder(stamped);
// Decrease limit
limited.$.repeater._limit = 0;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
});
test('negative limit', function() {
limited.$.repeater.limit = -10;
Polymer.dom.flush();
limited.$.repeater._limit = -10;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
});
@ -3518,64 +3512,60 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
test('initial limit', function() {
var items = limited.items;
limited.$.repeater.limit = 2;
limited.$.repeater._limit = 2;
limited.$.repeater.sort = null;
limited.$.repeater.filter = function(a) {
return (a.prop % 2) === 0;
};
limited.items = null;
Polymer.dom.flush();
limited.$.repeater.render();
limited.items = items;
Polymer.dom.flush();
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 2);
checkItemOrder(stamped);
});
test('increase limit', function(done) {
// Increase limit and test async rendering
limited.$.repeater.limit = 5;
setTimeout(function() {
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 5);
checkItemOrder(stamped);
// Increase limit and test sync rendering
limited.$.repeater.limit = 10;
Polymer.dom.flush();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
done();
});
test('increase limit', function() {
// Increase limit
limited.$.repeater._limit = 5;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 5);
checkItemOrder(stamped);
// Increase limit
limited.$.repeater._limit = 10;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
});
test('increase limit above items.length', function() {
limited.$.repeater.limit = 30;
Polymer.dom.flush();
limited.$.repeater._limit = 30;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
});
test('decrease limit', function(done) {
// Decrease limit and test async rendering
limited.$.repeater.limit = 5;
setTimeout(function() {
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 5);
checkItemOrder(stamped);
// Decrease limit and test sync rendering
limited.$.repeater.limit = 0;
Polymer.dom.flush();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
done();
});
test('decrease limit', function() {
// Decrease limit
limited.$.repeater._limit = 5;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 5);
checkItemOrder(stamped);
// Decrease limit
limited.$.repeater._limit = 0;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
});
test('negative limit', function() {
limited.$.repeater.limit = -10;
Polymer.dom.flush();
limited.$.repeater._limit = -10;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
});
@ -3592,7 +3582,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
test('initial limit', function() {
var items = limited.items;
limited.$.repeater.limit = 2;
limited.$.repeater._limit = 2;
limited.$.repeater.sort = function(a, b) {
return b.prop - a.prop;
};
@ -3600,58 +3590,54 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
return (a.prop % 2) === 0;
};
limited.items = null;
Polymer.dom.flush();
limited.$.repeater.render();
limited.items = items;
Polymer.dom.flush();
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 2);
checkItemOrder(stamped);
});
test('increase limit', function(done) {
// Increase limit and test async rendering
limited.$.repeater.limit = 5;
setTimeout(function() {
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 5);
checkItemOrder(stamped);
// Increase limit and test sync rendering
limited.$.repeater.limit = 10;
Polymer.dom.flush();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
done();
});
});
test('increase limit above items.length', function() {
limited.$.repeater.limit = 30;
Polymer.dom.flush();
test('increase limit', function() {
// Increase limit
limited.$.repeater._limit = 5;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 5);
checkItemOrder(stamped);
// Increase limit
limited.$.repeater._limit = 10;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
});
test('decrease limit', function(done) {
// Decrease limit and test async rendering
limited.$.repeater.limit = 5;
setTimeout(function() {
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 5);
checkItemOrder(stamped);
// Decrease limit and test sync rendering
limited.$.repeater.limit = 0;
Polymer.dom.flush();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
done();
});
test('increase limit above items.length', function() {
limited.$.repeater._limit = 30;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 10);
checkItemOrder(stamped);
});
test('decrease limit', function() {
// Decrease limit
limited.$.repeater._limit = 5;
limited.$.repeater.render();
var stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 5);
checkItemOrder(stamped);
// Decrease limit
limited.$.repeater._limit = 0;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
});
test('negative limit', function() {
limited.$.repeater.limit = -10;
Polymer.dom.flush();
limited.$.repeater._limit = -10;
limited.$.repeater.render();
stamped = Polymer.dom(limited.root).querySelectorAll('*:not(template)');
assert.equal(stamped.length, 0);
});