mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #4337 from Polymer/2.0-issue-blitz
Fixes a number of issues
This commit is contained in:
commit
106b53cdd7
@ -161,6 +161,7 @@ Polymer 2.0 elements will stamp their templates into shadow roots created using
|
||||
* <a name="breaking-slot-slot"></a>Selection of distributed content into named slots must use `slot="..."` rather than tag/class/attributes selected by `<content>`
|
||||
* <a name="breaking-redistribution"></a>Re-distributing content by placing a `<slot>` into an element that itself has named slots requires placing a `name` attribute on the `<slot>` to indicate what content _it_ selects from its host children, and placing a `slot` attribute to indicate where its selected content should be slotted into its parent
|
||||
* <a name="breaking-async-distribution"></a>In the V1 "Shady DOM" shim, initial distribution of children into `<slot>` is asynchronous (microtask) to creating the `shadowRoot`, meaning distribution occurs after observers/`ready` (in Polymer 1.0's shim, initial distribution occurred before `ready`). In order to force distribution synchronously, call `ShadyDOM.flush()`.
|
||||
* <a name="breaking-observe-nodes-flush"></a>Calling `Polymer.dom.flush` no longer results in callbacks registered with `Polymer.dom.observeNodes` being called. Instead, the object returned from `Polymer.dom.observeNodes` now contains a `flush` method which can be used to immediately call the registered callback if any changes are pending.
|
||||
|
||||
#### Scoped styling
|
||||
|
||||
|
@ -8,30 +8,11 @@ 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="../utils/boot.html">
|
||||
<link rel="import" href="../utils/array-splice.html">
|
||||
<link rel="import" href="../utils/async.html">
|
||||
<link rel="import" href="../utils/flattened-nodes-observer.html">
|
||||
<link rel="import" href="../utils/flush.html">
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
function isSlot(node) {
|
||||
return (node.localName === 'slot');
|
||||
}
|
||||
|
||||
function getEffectiveNodes(node) {
|
||||
if (isSlot(node)) {
|
||||
return node.assignedNodes({flatten: true});
|
||||
} else {
|
||||
return Array.from(node.childNodes).map(node => {
|
||||
if (isSlot(node)) {
|
||||
return node.assignedNodes({flatten: true});
|
||||
} else {
|
||||
return [node];
|
||||
}
|
||||
}).reduce((a, b) => a.concat(b), []);
|
||||
}
|
||||
}
|
||||
|
||||
let matchesSelector = (function() {
|
||||
let p = Element.prototype;
|
||||
let normalizedMatchesSelector = p.matches || p.matchesSelector ||
|
||||
@ -43,149 +24,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
})();
|
||||
|
||||
class EffectiveNodesObserver {
|
||||
|
||||
constructor(target, callback) {
|
||||
/** @type {MutationObserver} */
|
||||
this._shadyChildrenObserver = null;
|
||||
/** @type {MutationObserver} */
|
||||
this._nativeChildrenObserver = null;
|
||||
this._connected = false;
|
||||
this._target = target;
|
||||
this.callback = callback;
|
||||
this._effectiveNodes = [];
|
||||
this._observer = null;
|
||||
this._scheduled = false;
|
||||
this._boundSchedule = () => {
|
||||
this._schedule();
|
||||
}
|
||||
this._connect();
|
||||
this._schedule();
|
||||
}
|
||||
|
||||
_connect() {
|
||||
if (isSlot(this._target)) {
|
||||
this._listenSlots([this._target]);
|
||||
} else {
|
||||
this._listenSlots(this._target.children);
|
||||
if (window.ShadyDOM) {
|
||||
this._shadyChildrenObserver =
|
||||
ShadyDOM.observeChildren(this._target, (mutations) => {
|
||||
this._processMutations(mutations);
|
||||
});
|
||||
} else {
|
||||
this._nativeChildrenObserver =
|
||||
new MutationObserver((mutations) => {
|
||||
this._processMutations(mutations);
|
||||
});
|
||||
this._nativeChildrenObserver.observe(this._target, {childList: true});
|
||||
}
|
||||
}
|
||||
this._connected = true;
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (isSlot(this._target)) {
|
||||
this._unlistenSlots([this._target]);
|
||||
} else {
|
||||
this._unlistenSlots(this._target.children);
|
||||
if (window.ShadyDOM && this._shadyChildrenObserver) {
|
||||
ShadyDOM.unobserveChildren(this._shadyChildrenObserver);
|
||||
this._shadyChildrenObserver = null;
|
||||
} else if (this._nativeChildrenObserver) {
|
||||
this._nativeChildrenObserver.disconnect();
|
||||
this._nativeChildrenObserver = null;
|
||||
}
|
||||
}
|
||||
this._connected = false;
|
||||
}
|
||||
|
||||
_schedule() {
|
||||
if (!this._scheduled) {
|
||||
this._scheduled = true;
|
||||
Polymer.Async.microTask.run(() => this.flush());
|
||||
}
|
||||
}
|
||||
|
||||
_processMutations(mutations) {
|
||||
this._processSlotMutations(mutations);
|
||||
this.flush();
|
||||
}
|
||||
|
||||
_processSlotMutations(mutations) {
|
||||
if (mutations) {
|
||||
for (let i=0; i < mutations.length; i++) {
|
||||
let mutation = mutations[i];
|
||||
if (mutation.addedNodes) {
|
||||
this._listenSlots(mutation.addedNodes);
|
||||
}
|
||||
if (mutation.removedNodes) {
|
||||
this._unlistenSlots(mutation.removedNodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flush() {
|
||||
if (!this._connected) {
|
||||
return;
|
||||
}
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
if (this._nativeChildrenObserver) {
|
||||
this._processSlotMutations(this._nativeChildrenObserver.takeRecords());
|
||||
} else if (this.shadyChildrenObserver) {
|
||||
this._processSlotMutations(this._shadyChildrenObserver.takeRecords());
|
||||
}
|
||||
this._scheduled = false;
|
||||
let info = {
|
||||
target: this._target,
|
||||
addedNodes: [],
|
||||
removedNodes: []
|
||||
};
|
||||
let newNodes = getEffectiveNodes(this._target);
|
||||
let splices = Polymer.ArraySplice.calculateSplices(newNodes,
|
||||
this._effectiveNodes);
|
||||
// process removals
|
||||
for (let i=0, s; (i<splices.length) && (s=splices[i]); i++) {
|
||||
for (let j=0, n; (j < s.removed.length) && (n=s.removed[j]); j++) {
|
||||
info.removedNodes.push(n);
|
||||
}
|
||||
}
|
||||
// process adds
|
||||
for (let i=0, s; (i<splices.length) && (s=splices[i]); i++) {
|
||||
for (let j=s.index; j < s.index + s.addedCount; j++) {
|
||||
info.addedNodes.push(newNodes[j]);
|
||||
}
|
||||
}
|
||||
// update cache
|
||||
this._effectiveNodes = newNodes;
|
||||
if (info.addedNodes.length || info.removedNodes.length) {
|
||||
this.callback.call(this._target, info);
|
||||
}
|
||||
}
|
||||
|
||||
_listenSlots(nodeList) {
|
||||
for (let i=0; i < nodeList.length; i++) {
|
||||
let n = nodeList[i];
|
||||
if (isSlot(n)) {
|
||||
n.addEventListener('slotchange', this._boundSchedule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_unlistenSlots(nodeList) {
|
||||
for (let i=0; i < nodeList.length; i++) {
|
||||
let n = nodeList[i];
|
||||
if (isSlot(n)) {
|
||||
n.removeEventListener('slotchange', this._boundSchedule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DomApi {
|
||||
|
||||
constructor(node) {
|
||||
@ -196,7 +34,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
|
||||
observeNodes(callback) {
|
||||
return new EffectiveNodesObserver(this.node, callback);
|
||||
return new Polymer.FlattenedNodesObserver(this.node, callback);
|
||||
}
|
||||
|
||||
unobserveNodes(observerHandle) {
|
||||
@ -246,7 +84,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
|
||||
getEffectiveChildNodes() {
|
||||
return getEffectiveNodes(this.node);
|
||||
return Polymer.FlattenedNodesObserver.getFlattenedNodes(this.node);
|
||||
}
|
||||
|
||||
queryDistributedElements(selector) {
|
||||
@ -354,9 +192,14 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
Polymer.dom.addDebouncer = Polymer.enqueueDebouncer;
|
||||
|
||||
Polymer.Settings = {
|
||||
useShadow: true
|
||||
};
|
||||
// expose BC settings.
|
||||
let settings = Polymer.Settings || {};
|
||||
settings.useShadow = !(window.ShadyDOM);
|
||||
settings.useNativeCSSProperties =
|
||||
Boolean(!window.ShadyCSS || window.ShadyCSS.nativeCss);
|
||||
settings.useNativeCustomElements =
|
||||
!(window.customElements.polyfillWrapFlushCallback);
|
||||
Polymer.Settings = settings;
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
180
src/utils/flattened-nodes-observer.html
Normal file
180
src/utils/flattened-nodes-observer.html
Normal file
@ -0,0 +1,180 @@
|
||||
<!--
|
||||
@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
|
||||
-->
|
||||
<link rel="import" href="../utils/boot.html">
|
||||
<link rel="import" href="../utils/array-splice.html">
|
||||
<link rel="import" href="../utils/async.html">
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
function isSlot(node) {
|
||||
return (node.localName === 'slot');
|
||||
}
|
||||
|
||||
class FlattenedNodesObserver {
|
||||
|
||||
static getFlattenedNodes(node) {
|
||||
if (isSlot(node)) {
|
||||
return node.assignedNodes({flatten: true});
|
||||
} else {
|
||||
return Array.from(node.childNodes).map(node => {
|
||||
if (isSlot(node)) {
|
||||
return node.assignedNodes({flatten: true});
|
||||
} else {
|
||||
return [node];
|
||||
}
|
||||
}).reduce((a, b) => a.concat(b), []);
|
||||
}
|
||||
}
|
||||
|
||||
constructor(target, callback) {
|
||||
/** @type {MutationObserver} */
|
||||
this._shadyChildrenObserver = null;
|
||||
/** @type {MutationObserver} */
|
||||
this._nativeChildrenObserver = null;
|
||||
this._connected = false;
|
||||
this._target = target;
|
||||
this.callback = callback;
|
||||
this._effectiveNodes = [];
|
||||
this._observer = null;
|
||||
this._scheduled = false;
|
||||
this._boundSchedule = () => {
|
||||
this._schedule();
|
||||
}
|
||||
this._connect();
|
||||
this._schedule();
|
||||
}
|
||||
|
||||
_connect() {
|
||||
if (isSlot(this._target)) {
|
||||
this._listenSlots([this._target]);
|
||||
} else {
|
||||
this._listenSlots(this._target.children);
|
||||
if (window.ShadyDOM) {
|
||||
this._shadyChildrenObserver =
|
||||
ShadyDOM.observeChildren(this._target, (mutations) => {
|
||||
this._processMutations(mutations);
|
||||
});
|
||||
} else {
|
||||
this._nativeChildrenObserver =
|
||||
new MutationObserver((mutations) => {
|
||||
this._processMutations(mutations);
|
||||
});
|
||||
this._nativeChildrenObserver.observe(this._target, {childList: true});
|
||||
}
|
||||
}
|
||||
this._connected = true;
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (isSlot(this._target)) {
|
||||
this._unlistenSlots([this._target]);
|
||||
} else {
|
||||
this._unlistenSlots(this._target.children);
|
||||
if (window.ShadyDOM && this._shadyChildrenObserver) {
|
||||
ShadyDOM.unobserveChildren(this._shadyChildrenObserver);
|
||||
this._shadyChildrenObserver = null;
|
||||
} else if (this._nativeChildrenObserver) {
|
||||
this._nativeChildrenObserver.disconnect();
|
||||
this._nativeChildrenObserver = null;
|
||||
}
|
||||
}
|
||||
this._connected = false;
|
||||
}
|
||||
|
||||
_schedule() {
|
||||
if (!this._scheduled) {
|
||||
this._scheduled = true;
|
||||
Polymer.Async.microTask.run(() => this.flush());
|
||||
}
|
||||
}
|
||||
|
||||
_processMutations(mutations) {
|
||||
this._processSlotMutations(mutations);
|
||||
this.flush();
|
||||
}
|
||||
|
||||
_processSlotMutations(mutations) {
|
||||
if (mutations) {
|
||||
for (let i=0; i < mutations.length; i++) {
|
||||
let mutation = mutations[i];
|
||||
if (mutation.addedNodes) {
|
||||
this._listenSlots(mutation.addedNodes);
|
||||
}
|
||||
if (mutation.removedNodes) {
|
||||
this._unlistenSlots(mutation.removedNodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flush() {
|
||||
if (!this._connected) {
|
||||
return;
|
||||
}
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
if (this._nativeChildrenObserver) {
|
||||
this._processSlotMutations(this._nativeChildrenObserver.takeRecords());
|
||||
} else if (this.shadyChildrenObserver) {
|
||||
this._processSlotMutations(this._shadyChildrenObserver.takeRecords());
|
||||
}
|
||||
this._scheduled = false;
|
||||
let info = {
|
||||
target: this._target,
|
||||
addedNodes: [],
|
||||
removedNodes: []
|
||||
};
|
||||
let newNodes = this.constructor.getFlattenedNodes(this._target);
|
||||
let splices = Polymer.ArraySplice.calculateSplices(newNodes,
|
||||
this._effectiveNodes);
|
||||
// process removals
|
||||
for (let i=0, s; (i<splices.length) && (s=splices[i]); i++) {
|
||||
for (let j=0, n; (j < s.removed.length) && (n=s.removed[j]); j++) {
|
||||
info.removedNodes.push(n);
|
||||
}
|
||||
}
|
||||
// process adds
|
||||
for (let i=0, s; (i<splices.length) && (s=splices[i]); i++) {
|
||||
for (let j=s.index; j < s.index + s.addedCount; j++) {
|
||||
info.addedNodes.push(newNodes[j]);
|
||||
}
|
||||
}
|
||||
// update cache
|
||||
this._effectiveNodes = newNodes;
|
||||
if (info.addedNodes.length || info.removedNodes.length) {
|
||||
this.callback.call(this._target, info);
|
||||
}
|
||||
}
|
||||
|
||||
_listenSlots(nodeList) {
|
||||
for (let i=0; i < nodeList.length; i++) {
|
||||
let n = nodeList[i];
|
||||
if (isSlot(n)) {
|
||||
n.addEventListener('slotchange', this._boundSchedule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_unlistenSlots(nodeList) {
|
||||
for (let i=0; i < nodeList.length; i++) {
|
||||
let n = nodeList[i];
|
||||
if (isSlot(n)) {
|
||||
n.removeEventListener('slotchange', this._boundSchedule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Polymer.FlattenedNodesObserver = FlattenedNodesObserver;
|
||||
|
||||
})();
|
||||
</script>
|
@ -32,12 +32,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
|
||||
function flushQueue(queue) {
|
||||
for (let i=0, q, context, callback, args; i<queue.length; i++) {
|
||||
while (queue.length) {
|
||||
const q = queue.shift();
|
||||
const context = q[0];
|
||||
const callback = q[1];
|
||||
const args = q[2];
|
||||
try {
|
||||
q = queue[i];
|
||||
context = q[0];
|
||||
callback = q[1];
|
||||
args = q[2];
|
||||
callback.apply(context, args);
|
||||
} catch(e) {
|
||||
setTimeout(() => {
|
||||
@ -45,7 +45,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
})
|
||||
}
|
||||
}
|
||||
queue.length = 0;
|
||||
}
|
||||
|
||||
function flush() {
|
||||
while (beforeRenderQueue.length || afterRenderQueue.length) {
|
||||
flushQueue(beforeRenderQueue);
|
||||
flushQueue(afterRenderQueue);
|
||||
}
|
||||
}
|
||||
|
||||
Polymer.RenderStatus = {
|
||||
@ -62,7 +68,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
schedule();
|
||||
}
|
||||
afterRenderQueue.push([context, callback, args]);
|
||||
}
|
||||
},
|
||||
|
||||
flush: flush
|
||||
|
||||
};
|
||||
|
||||
|
@ -60,6 +60,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
'unit/array-selector.html',
|
||||
'unit/polymer-dom.html',
|
||||
'unit/polymer-dom-observeNodes.html',
|
||||
'unit/flattened-nodes-observer.html',
|
||||
'unit/importHref.html',
|
||||
'unit/dynamic-import.html',
|
||||
'unit/gestures.html',
|
||||
|
@ -345,7 +345,7 @@ window.data = [
|
||||
|
||||
<dom-module id="x-simple-repeat">
|
||||
<template>
|
||||
<template is="dom-repeat" items="{{items}}">
|
||||
<template id="repeat" is="dom-repeat" items="{{items}}">
|
||||
<x-foo itema-prop="{{item.prop}}"></x-foo>
|
||||
</template>
|
||||
</template>
|
||||
|
@ -5653,39 +5653,36 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
});
|
||||
});
|
||||
|
||||
test('css scoping retained when re-ordering', function(done) {
|
||||
var removed;
|
||||
if (!Polymer.Settings.useShadow) {
|
||||
// Confirm initial scoping
|
||||
var stamped = simple.root.querySelectorAll('*:not(template):not(dom-repeat)');
|
||||
assert.equal(stamped[0].itemaProp, 'prop-1');
|
||||
assert(stamped[0].classList.contains('x-simple-repeat'), 'expected scoping');
|
||||
assert.equal(stamped.length, 3, 'total stamped count incorrect');
|
||||
var row = stamped[0];
|
||||
// Move
|
||||
removed = simple.splice('items', 0, 1);
|
||||
simple.splice('items', 1, 0, removed[0]);
|
||||
setTimeout(function() {
|
||||
stamped = simple.root.querySelectorAll('*:not(template):not(dom-repeat)');
|
||||
assert.equal(stamped.length, 3, 'total stamped count incorrect');
|
||||
assert.equal(row, stamped[1]);
|
||||
assert.equal(stamped[1].itemaProp, 'prop-1');
|
||||
assert(stamped[1].classList.contains('x-simple-repeat'), 'expected scoping');
|
||||
// Revert
|
||||
removed = simple.splice('items', 1, 1);
|
||||
simple.splice('items', 0, 0, removed[0]);
|
||||
setTimeout(function() {
|
||||
stamped = simple.root.querySelectorAll('*:not(template):not(dom-repeat)');
|
||||
assert.equal(stamped.length, 3, 'total stamped count incorrect');
|
||||
assert.equal(row, stamped[0]);
|
||||
assert.equal(stamped[0].itemaProp, 'prop-1');
|
||||
assert(stamped[0].classList.contains('x-simple-repeat'), 'expected scoping');
|
||||
done();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
test('css scoping retained when re-ordering', function() {
|
||||
if (!window.ShadyDOM) {
|
||||
this.skip();
|
||||
}
|
||||
var removed;
|
||||
// Confirm initial scoping
|
||||
var stamped = simple.root.querySelectorAll('*:not(template):not(dom-repeat)');
|
||||
assert.equal(stamped[0].itemaProp, 'prop-1');
|
||||
assert(stamped[0].classList.contains('x-simple-repeat'), 'expected scoping');
|
||||
assert.equal(stamped.length, 3, 'total stamped count incorrect');
|
||||
// Move
|
||||
removed = simple.splice('items', 0, 1);
|
||||
simple.splice('items', 1, 0, removed[0]);
|
||||
Polymer.flush();
|
||||
stamped = simple.root.querySelectorAll('*:not(template):not(dom-repeat)');
|
||||
assert.equal(stamped.length, 3, 'total stamped count incorrect');
|
||||
let movedItem = simple.$.repeat.modelForElement(stamped[1]).item;
|
||||
assert.equal(removed[0], movedItem);
|
||||
assert.equal(stamped[1].itemaProp, 'prop-1');
|
||||
assert(stamped[1].classList.contains('x-simple-repeat'), 'expected scoping');
|
||||
// Revert
|
||||
removed = simple.splice('items', 1, 1);
|
||||
simple.splice('items', 0, 0, removed[0]);
|
||||
Polymer.flush();
|
||||
stamped = simple.root.querySelectorAll('*:not(template):not(dom-repeat)');
|
||||
assert.equal(stamped.length, 3, 'total stamped count incorrect');
|
||||
movedItem = simple.$.repeat.modelForElement(stamped[0]).item;
|
||||
assert.equal(removed[0], movedItem);
|
||||
assert.equal(stamped[0].itemaProp, 'prop-1');
|
||||
assert(stamped[0].classList.contains('x-simple-repeat'), 'expected scoping');
|
||||
});
|
||||
|
||||
});
|
||||
|
1047
test/unit/flattened-nodes-observer.html
Normal file
1047
test/unit/flattened-nodes-observer.html
Normal file
File diff suppressed because it is too large
Load Diff
@ -331,6 +331,18 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
assert.equal(el.isLocalDescendant(el.$.container), true);
|
||||
});
|
||||
|
||||
test('domHost', function() {
|
||||
var el = fixture('slot');
|
||||
assert.equal(el.domHost, document);
|
||||
assert.equal(el.$.container.domHost, el);
|
||||
});
|
||||
|
||||
test('legacy settings', function() {
|
||||
assert.equal(Polymer.Settings.useShadow, !(window.ShadyDOM));
|
||||
assert.equal(Polymer.Settings.useNativeCustomElements, !(window.customElements.polyfillWrapFlushCallback));
|
||||
assert.equal(Polymer.Settings.useNativeCSSProperties, Boolean(!window.ShadyCSS || window.ShadyCSS.nativeCss));
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
@ -73,6 +73,22 @@ suite('render-status', function() {
|
||||
document.body.appendChild(el);
|
||||
});
|
||||
|
||||
test('flush', function() {
|
||||
let el = document.createElement('x-foo');
|
||||
let beforeCalled;
|
||||
el.beforeNextRender = function() {
|
||||
beforeCalled = true;
|
||||
}
|
||||
let afterCalled;
|
||||
el.afterNextRender = function() {
|
||||
afterCalled = true;
|
||||
}
|
||||
document.body.appendChild(el);
|
||||
Polymer.RenderStatus.flush();
|
||||
assert.isTrue(beforeCalled);
|
||||
assert.isTrue(afterCalled);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user