mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Make Polymer.dom.flush reentrant-safe. Fixes #3115.
This commit is contained in:
parent
203e862976
commit
644105a469
@ -9,16 +9,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
-->
|
||||
<script>
|
||||
|
||||
/**
|
||||
* `Polymer.dom.flush()` causes any asynchronously queued actions to be
|
||||
/**
|
||||
* `Polymer.dom.flush()` causes any asynchronously queued actions to be
|
||||
* flushed synchronously. It should be used sparingly as calling it frequently
|
||||
* can negatively impact performance since work is often deferred for
|
||||
* efficiency. Calling `Polymer.dom.flush()` is useful, for example, when
|
||||
* an element has to measure itself and is unsure about the state of its
|
||||
* can negatively impact performance since work is often deferred for
|
||||
* efficiency. Calling `Polymer.dom.flush()` is useful, for example, when
|
||||
* an element has to measure itself and is unsure about the state of its
|
||||
* internal or compoased DOM.
|
||||
*/
|
||||
Polymer.Base.extend(Polymer.dom, {
|
||||
|
||||
|
||||
_flushGuard: 0,
|
||||
_FLUSH_MAX: 100,
|
||||
_needsTakeRecords: !Polymer.Settings.useNativeCustomElements,
|
||||
@ -31,8 +31,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
this._flushGuard = 0;
|
||||
this._prepareFlush();
|
||||
while (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) {
|
||||
for (var i=0; i < this._debouncers.length; i++) {
|
||||
this._debouncers[i].complete();
|
||||
while (this._debouncers.length) {
|
||||
this._debouncers.shift().complete();
|
||||
}
|
||||
// clear the list of debouncers
|
||||
if (this._finishDebouncer) {
|
||||
@ -47,9 +47,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
},
|
||||
|
||||
_prepareFlush: function() {
|
||||
// TODO(sorvell): There is currently not a good way
|
||||
// TODO(sorvell): There is currently not a good way
|
||||
// to process all custom elements mutations under SD polyfill because
|
||||
// these mutations may be inside shadowRoots.
|
||||
// these mutations may be inside shadowRoots.
|
||||
// again make any pending CE mutations that might trigger debouncer
|
||||
// additions go...
|
||||
if (this._needsTakeRecords) {
|
||||
@ -76,7 +76,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
addDebouncer: function(debouncer) {
|
||||
this._debouncers.push(debouncer);
|
||||
// ensure the list of active debouncers is cleared when done.
|
||||
this._finishDebouncer = Polymer.Debounce(this._finishDebouncer,
|
||||
this._finishDebouncer = Polymer.Debounce(this._finishDebouncer,
|
||||
this._finishFlush);
|
||||
},
|
||||
|
||||
|
@ -635,6 +635,34 @@ suite('Polymer.dom', function() {
|
||||
|
||||
});
|
||||
|
||||
test('Polymer.dom.flush reentrancy', function() {
|
||||
// Setup callbacks
|
||||
var order = [];
|
||||
var cb1 = sinon.spy(function() { order.push(cb1); });
|
||||
var cb2 = sinon.spy(function() { order.push(cb2); });
|
||||
var cb3 = sinon.spy(function() { order.push(cb3); });
|
||||
var cb4 = sinon.spy(function() { order.push(cb4); });
|
||||
var cbReentrant = sinon.spy(function() {
|
||||
order.push(cbReentrant);
|
||||
Polymer.dom.addDebouncer(Polymer.Debounce(null, cb3));
|
||||
Polymer.dom.flush();
|
||||
Polymer.dom.addDebouncer(Polymer.Debounce(null, cb4));
|
||||
});
|
||||
// Enqueue debouncers
|
||||
Polymer.dom.addDebouncer(Polymer.Debounce(null, cb1));
|
||||
Polymer.dom.addDebouncer(Polymer.Debounce(null, cbReentrant));
|
||||
Polymer.dom.addDebouncer(Polymer.Debounce(null, cb2));
|
||||
// Flush
|
||||
Polymer.dom.flush();
|
||||
// Check callbacks called and in correct order
|
||||
assert.isTrue(cb1.calledOnce);
|
||||
assert.isTrue(cb2.calledOnce);
|
||||
assert.isTrue(cb3.calledOnce);
|
||||
assert.isTrue(cb4.calledOnce);
|
||||
assert.isTrue(cbReentrant.calledOnce);
|
||||
assert.sameMembers(order, [cb1, cbReentrant, cb2, cb3, cb4]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('Polymer.dom accessors', function() {
|
||||
|
Loading…
Reference in New Issue
Block a user