Merge branch 'master' into shady-linked

This commit is contained in:
Steven Orvell 2015-11-30 16:02:24 -08:00
commit b03a30e74b
8 changed files with 129 additions and 55 deletions

View File

@ -14,7 +14,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<link rel="import" href="src/micro/constructor.html">
<link rel="import" href="src/micro/properties.html">
<link rel="import" href="src/micro/attributes.html">
<link rel="import" href="src/micro/debouncer.html">
<script>
Polymer.version = 'master';
@ -45,8 +44,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
_initFeatures: function() {
// install host attributes
this._marshalHostAttributes();
// setup debouncers
this._setupDebouncers();
// acquire behaviors
this._marshalBehaviors();
}

View File

@ -14,6 +14,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<link rel="import" href="src/mini/ready.html">
<link rel="import" href="src/mini/shady.html">
<link rel="import" href="src/mini/shadow.html">
<link rel="import" href="src/mini/debouncer.html">
<script>

View File

@ -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,10 @@ 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();
// Avoid using an index in this loop to ensure flush is safe to be
// called reentrantly from a debouncer callback being flushed
while (this._debouncers.length) {
this._debouncers.shift().complete();
}
// clear the list of debouncers
if (this._finishDebouncer) {
@ -47,9 +49,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 +78,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);
},

View File

@ -7,6 +7,9 @@ The complete set of contributors may be found at http://polymer.github.io/CONTRI
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../lib/async.html">
<link rel="import" href="../lib/debounce.html">
<script>
Polymer.Base._addFeature({

View File

@ -37,6 +37,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
'unit/polymer-dom-content.html?dom=shadow',
'unit/polymer-dom-observeNodes.html',
'unit/polymer-dom-observeNodes.html?dom=shadow',
'unit/debounce.html',
'unit/bind.html',
'unit/bind.html?dom=shadow',
'unit/notify-path.html',

83
test/unit/debounce.html Normal file
View File

@ -0,0 +1,83 @@
<!doctype html>
<!--
@license
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
<meta charset="utf-8">
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
<script src="../../../web-component-tester/browser.js"></script>
<link rel="import" href="../../polymer-mini.html">
</head>
<body>
<script>
HTMLImports.whenReady(function() {
Polymer({is: 'my-element'});
});
setup(function() {
window.el1 = document.createElement('my-element');
document.body.appendChild(window.el1);
window.el2 = document.createElement('my-element');
window.el1.appendChild(window.el2);
});
teardown(function() {
document.body.removeChild(window.el1);
delete window.el1;
delete window.el2;
});
suite('debounce', function() {
test('debounce (no-wait)', function(done) {
var called = 0;
var cb = function() {
called++;
};
window.el1.debounce('foo', cb);
window.el1.debounce('foo', cb);
window.el1.debounce('foo', cb);
setTimeout(function() {
assert.equal(called, 1, 'debounce should be called exactly once');
done();
}, 50);
});
test('debounce (wait)', function(done) {
var called = 0;
var now = Date.now();
var cb = function() {
called++;
};
window.el1.debounce('foo', cb);
window.el1.debounce('foo', cb, 100);
window.el1.debounce('foo', cb, 100);
setTimeout(function() {
assert.equal(called, 1, 'debounce should be called exactly once');
assert(Date.now() - now > 100, 'debounce should be called after at least 100ms');
done();
}, 200);
});
});
</script>
</body>
</html>

View File

@ -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() {

View File

@ -57,47 +57,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
});
suite('debounce', function() {
test('debounce (no-wait)', function(done) {
var called = 0;
var cb = function() {
called++;
};
window.el1.debounce('foo', cb);
window.el1.debounce('foo', cb);
window.el1.debounce('foo', cb);
setTimeout(function() {
assert.equal(called, 1, 'debounce should be called exactly once');
done();
}, 50);
});
test('debounce (wait)', function(done) {
var called = 0;
var now = Date.now();
var cb = function() {
called++;
};
window.el1.debounce('foo', cb);
window.el1.debounce('foo', cb, 100);
window.el1.debounce('foo', cb, 100);
setTimeout(function() {
assert.equal(called, 1, 'debounce should be called exactly once');
assert(Date.now() - now > 100, 'debounce should be called after at least 100ms');
done();
}, 200);
});
});
</script>
</body>