mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #5452 from Polymer/shady-nopatch
Changes to make compatible with `noPatch` version of ShadyDOM [3.x]
This commit is contained in:
@@ -13,6 +13,7 @@ import { PropertyEffects } from '../mixins/property-effects.js';
|
||||
import { OptionalMutableData } from '../mixins/mutable-data.js';
|
||||
import { GestureEventListeners } from '../mixins/gesture-event-listeners.js';
|
||||
import { strictTemplatePolicy } from '../utils/settings.js';
|
||||
import { wrap } from '../utils/wrap.js';
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -87,7 +88,7 @@ export class DomBind extends domBindBase {
|
||||
}
|
||||
|
||||
__insertChildren() {
|
||||
this.parentNode.insertBefore(this.root, this);
|
||||
wrap(wrap(this).parentNode).insertBefore(this.root, this);
|
||||
}
|
||||
|
||||
__removeChildren() {
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Debouncer } from '../utils/debounce.js';
|
||||
import { enqueueDebouncer, flush } from '../utils/flush.js';
|
||||
import { microTask } from '../utils/async.js';
|
||||
import { root } from '../utils/path.js';
|
||||
import { wrap } from '../utils/wrap.js';
|
||||
|
||||
/**
|
||||
* The `<dom-if>` element will stamp a light-dom `<template>` child when
|
||||
@@ -120,9 +121,9 @@ export class DomIf extends PolymerElement {
|
||||
*/
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
if (!this.parentNode ||
|
||||
(this.parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE &&
|
||||
!this.parentNode.host)) {
|
||||
const parent = wrap(this).parentNode;
|
||||
if (!parent || (parent.nodeType == Node.DOCUMENT_FRAGMENT_NODE &&
|
||||
!wrap(parent).host)) {
|
||||
this.__teardownInstance();
|
||||
}
|
||||
}
|
||||
@@ -174,15 +175,15 @@ export class DomIf extends PolymerElement {
|
||||
}
|
||||
|
||||
__ensureInstance() {
|
||||
let parentNode = this.parentNode;
|
||||
let parentNode = wrap(this).parentNode;
|
||||
// Guard against element being detached while render was queued
|
||||
if (parentNode) {
|
||||
if (!this.__ctor) {
|
||||
let template = /** @type {HTMLTemplateElement} */(this.querySelector('template'));
|
||||
let template = /** @type {HTMLTemplateElement} */(wrap(this).querySelector('template'));
|
||||
if (!template) {
|
||||
// Wait until childList changes and template should be there by then
|
||||
let observer = new MutationObserver(() => {
|
||||
if (this.querySelector('template')) {
|
||||
if (wrap(this).querySelector('template')) {
|
||||
observer.disconnect();
|
||||
this.__render();
|
||||
} else {
|
||||
@@ -219,16 +220,16 @@ export class DomIf extends PolymerElement {
|
||||
}
|
||||
if (!this.__instance) {
|
||||
this.__instance = new this.__ctor();
|
||||
parentNode.insertBefore(this.__instance.root, this);
|
||||
wrap(parentNode).insertBefore(this.__instance.root, this);
|
||||
} else {
|
||||
this.__syncHostProperties();
|
||||
let c$ = this.__instance.children;
|
||||
if (c$ && c$.length) {
|
||||
// Detect case where dom-if was re-attached in new position
|
||||
let lastChild = this.previousSibling;
|
||||
let lastChild = wrap(this).previousSibling;
|
||||
if (lastChild !== c$[c$.length-1]) {
|
||||
for (let i=0, n; (i<c$.length) && (n=c$[i]); i++) {
|
||||
parentNode.insertBefore(n, this);
|
||||
wrap(parentNode).insertBefore(n, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,10 +254,11 @@ export class DomIf extends PolymerElement {
|
||||
let c$ = this.__instance.children;
|
||||
if (c$ && c$.length) {
|
||||
// use first child parent, for case when dom-if may have been detached
|
||||
let parent = c$[0].parentNode;
|
||||
// Instance children may be disconnected from parents when dom-if
|
||||
// detaches if a tree was innerHTML'ed
|
||||
if (parent) {
|
||||
let parent = wrap(c$[0]).parentNode;
|
||||
// Instance children may be disconnected from parents when dom-if
|
||||
// detaches if a tree was innerHTML'ed
|
||||
if (parent) {
|
||||
parent = wrap(parent);
|
||||
for (let i=0, n; (i<c$.length) && (n=c$[i]); i++) {
|
||||
parent.removeChild(n);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { enqueueDebouncer, flush } from '../utils/flush.js';
|
||||
import { OptionalMutableData } from '../mixins/mutable-data.js';
|
||||
import { matches, translate } from '../utils/path.js';
|
||||
import { timeOut, microTask } from '../utils/async.js';
|
||||
import { wrap } from '../utils/wrap.js';
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -323,9 +324,9 @@ export class DomRepeat extends domRepeatBase {
|
||||
// only perform attachment if the element was previously detached.
|
||||
if (this.__isDetached) {
|
||||
this.__isDetached = false;
|
||||
let parent = this.parentNode;
|
||||
let wrappedParent = wrap(wrap(this).parentNode);
|
||||
for (let i=0; i<this.__instances.length; i++) {
|
||||
this.__attachInstance(i, parent);
|
||||
this.__attachInstance(i, wrappedParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -583,15 +584,17 @@ export class DomRepeat extends domRepeatBase {
|
||||
|
||||
__detachInstance(idx) {
|
||||
let inst = this.__instances[idx];
|
||||
const wrappedRoot = wrap(inst.root);
|
||||
for (let i=0; i<inst.children.length; i++) {
|
||||
let el = inst.children[i];
|
||||
inst.root.appendChild(el);
|
||||
wrappedRoot.appendChild(el);
|
||||
}
|
||||
return inst;
|
||||
}
|
||||
|
||||
__attachInstance(idx, parent) {
|
||||
let inst = this.__instances[idx];
|
||||
// Note, this is pre-wrapped as an optimization
|
||||
parent.insertBefore(inst.root, this);
|
||||
}
|
||||
|
||||
@@ -625,7 +628,7 @@ export class DomRepeat extends domRepeatBase {
|
||||
}
|
||||
let beforeRow = this.__instances[instIdx + 1];
|
||||
let beforeNode = beforeRow ? beforeRow.children[0] : this;
|
||||
this.parentNode.insertBefore(inst.root, beforeNode);
|
||||
wrap(wrap(this).parentNode).insertBefore(inst.root, beforeNode);
|
||||
this.__instances[instIdx] = inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ function flattenBehaviors(behaviors, list, exclude) {
|
||||
/**
|
||||
* @param {!PolymerInit} info Polymer info object
|
||||
* @param {function(new:HTMLElement)} Base base class to extend with info object
|
||||
* @param {Object} behaviors behaviors to copy into the element
|
||||
* @param {Object=} behaviors behaviors to copy into the element
|
||||
* @return {function(new:HTMLElement)} Generated class
|
||||
* @suppress {checkTypes}
|
||||
* @private
|
||||
@@ -197,7 +197,7 @@ function GenerateClassFromInfo(info, Base, behaviors) {
|
||||
// explicitly not calling super._finalizeClass
|
||||
static _finalizeClass() {
|
||||
// if calling via a subclass that hasn't been generated, pass through to super
|
||||
if (!this.hasOwnProperty(window.JSCompiler_renameProperty('generatedFrom', this))) {
|
||||
if (!this.hasOwnProperty(JSCompiler_renameProperty('generatedFrom', this))) {
|
||||
super._finalizeClass();
|
||||
} else {
|
||||
// interleave properties and observers per behavior and `info`
|
||||
|
||||
@@ -151,12 +151,31 @@ Polymer.Class = (info, mixin) => Class(info,
|
||||
|
||||
// Apply LegacyDataMixin to Templatizer instances as well, and defer
|
||||
// runtime switch to the root's host (_methodHost)
|
||||
templatize.mixin =
|
||||
dedupingMixin(superClass => class extends LegacyDataMixin(superClass) {
|
||||
get _legacyUndefinedCheck() {
|
||||
return this._methodHost && this._methodHost._legacyUndefinedCheck;
|
||||
/**
|
||||
* @mixinFunction
|
||||
* @polymer
|
||||
*/
|
||||
const TemplatizeMixin =
|
||||
dedupingMixin(superClass => {
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {HTMLElement}
|
||||
*/
|
||||
const legacyBase = LegacyDataMixin(superClass);
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
class TemplateLegacy extends legacyBase {
|
||||
get _legacyUndefinedCheck() {
|
||||
return this._methodHost && this._methodHost._legacyUndefinedCheck;
|
||||
}
|
||||
}
|
||||
/** @type {!Polymer_PropertyEffects} */
|
||||
TemplateLegacy.prototype._methodHost;
|
||||
return TemplateLegacy;
|
||||
});
|
||||
|
||||
templatize.mixin = TemplatizeMixin;
|
||||
|
||||
console.info('LegacyDataMixin will be applied to all legacy elements.\n' +
|
||||
'Set `_legacyUndefinedCheck: true` on element class to enable.');
|
||||
|
||||
@@ -8,7 +8,6 @@ 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
|
||||
*/
|
||||
import '@webcomponents/shadycss/entrypoints/apply-shim.js';
|
||||
|
||||
import { ElementMixin } from '../mixins/element-mixin.js';
|
||||
import { GestureEventListeners } from '../mixins/gesture-event-listeners.js';
|
||||
import { DirMixin } from '../mixins/dir-mixin.js';
|
||||
@@ -20,6 +19,7 @@ import { setTouchAction } from '../utils/gestures.js';
|
||||
import { Debouncer } from '../utils/debounce.js';
|
||||
import { timeOut, microTask } from '../utils/async.js';
|
||||
import { get } from '../utils/path.js';
|
||||
import { wrap } from '../utils/wrap.js';
|
||||
|
||||
let styleInterface = window.ShadyCSS;
|
||||
|
||||
@@ -419,7 +419,7 @@ export const LegacyElementMixin = dedupingMixin((base) => {
|
||||
});
|
||||
event.detail = detail;
|
||||
let node = options.node || this;
|
||||
node.dispatchEvent(event);
|
||||
wrap(node).dispatchEvent(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
@@ -506,6 +506,7 @@ export const LegacyElementMixin = dedupingMixin((base) => {
|
||||
* @override
|
||||
*/
|
||||
$$(slctr) {
|
||||
// Note, no need to `wrap` this because root is always patched
|
||||
return this.root.querySelector(slctr);
|
||||
}
|
||||
|
||||
@@ -516,7 +517,7 @@ export const LegacyElementMixin = dedupingMixin((base) => {
|
||||
* @this {Element}
|
||||
*/
|
||||
get domHost() {
|
||||
let root = this.getRootNode();
|
||||
let root = wrap(this).getRootNode();
|
||||
return (root instanceof DocumentFragment) ? /** @type {ShadowRoot} */ (root).host : root;
|
||||
}
|
||||
|
||||
@@ -528,7 +529,9 @@ export const LegacyElementMixin = dedupingMixin((base) => {
|
||||
* @override
|
||||
*/
|
||||
distributeContent() {
|
||||
if (window.ShadyDOM && this.shadowRoot) {
|
||||
const thisEl = /** @type {Element} */ (this);
|
||||
const domApi = /** @type {PolymerDomApi} */(dom(thisEl));
|
||||
if (window.ShadyDOM && domApi.shadowRoot) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
}
|
||||
@@ -638,6 +641,7 @@ export const LegacyElementMixin = dedupingMixin((base) => {
|
||||
* @override
|
||||
*/
|
||||
getContentChildNodes(slctr) {
|
||||
// Note, no need to `wrap` this because root is always
|
||||
let content = this.root.querySelector(slctr || 'slot');
|
||||
return content ?
|
||||
/** @type {PolymerDomApi} */ (dom(content)).getDistributedNodes() :
|
||||
@@ -678,8 +682,8 @@ export const LegacyElementMixin = dedupingMixin((base) => {
|
||||
*/
|
||||
isLightDescendant(node) {
|
||||
const thisNode = /** @type {Node} */ (this);
|
||||
return thisNode !== node && thisNode.contains(node) &&
|
||||
thisNode.getRootNode() === node.getRootNode();
|
||||
return thisNode !== node && wrap(thisNode).contains(node) &&
|
||||
wrap(thisNode).getRootNode() === wrap(node).getRootNode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -690,7 +694,7 @@ export const LegacyElementMixin = dedupingMixin((base) => {
|
||||
* @override
|
||||
*/
|
||||
isLocalDescendant(node) {
|
||||
return this.root === node.getRootNode();
|
||||
return this.root === wrap(node).getRootNode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -875,18 +879,18 @@ export const LegacyElementMixin = dedupingMixin((base) => {
|
||||
* @override
|
||||
*/
|
||||
toggleAttribute(name, bool) {
|
||||
let node = /** @type {Element} */ this;
|
||||
let node = /** @type {Element} */(this);
|
||||
if (arguments.length === 3) {
|
||||
node = /** @type {Element} */ arguments[2];
|
||||
node = /** @type {Element} */(arguments[2]);
|
||||
}
|
||||
if (arguments.length == 1) {
|
||||
bool = !node.hasAttribute(name);
|
||||
}
|
||||
if (bool) {
|
||||
node.setAttribute(name, '');
|
||||
wrap(node).setAttribute(name, '');
|
||||
return true;
|
||||
} else {
|
||||
node.removeAttribute(name);
|
||||
wrap(node).removeAttribute(name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ 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
|
||||
*/
|
||||
import '../utils/boot.js';
|
||||
|
||||
import { wrap } from '../utils/wrap.js';
|
||||
import '../utils/settings.js';
|
||||
import { FlattenedNodesObserver } from '../utils/flattened-nodes-observer.js';
|
||||
export { flush, enqueueDebouncer as addDebouncer } from '../utils/flush.js';
|
||||
@@ -40,8 +40,9 @@ export const matchesSelector = function(node, selector) {
|
||||
* Node API wrapper class returned from `Polymer.dom.(target)` when
|
||||
* `target` is a `Node`.
|
||||
* @implements {PolymerDomApi}
|
||||
* @unrestricted
|
||||
*/
|
||||
export class DomApi {
|
||||
class DomApiNative {
|
||||
|
||||
/**
|
||||
* @param {Node} node Node for which to create a Polymer.dom helper object.
|
||||
@@ -93,7 +94,7 @@ export class DomApi {
|
||||
* @override
|
||||
*/
|
||||
deepContains(node) {
|
||||
if (this.node.contains(node)) {
|
||||
if (wrap(this.node).contains(node)) {
|
||||
return true;
|
||||
}
|
||||
let n = node;
|
||||
@@ -101,7 +102,7 @@ export class DomApi {
|
||||
// walk from node to `this` or `document`
|
||||
while (n && n !== doc && n !== this.node) {
|
||||
// use logical parentnode, or native ShadowRoot host
|
||||
n = n.parentNode || n.host;
|
||||
n = wrap(n).parentNode || wrap(n).host;
|
||||
}
|
||||
return n === this.node;
|
||||
}
|
||||
@@ -116,7 +117,7 @@ export class DomApi {
|
||||
* @override
|
||||
*/
|
||||
getOwnerRoot() {
|
||||
return this.node.getRootNode();
|
||||
return wrap(this.node).getRootNode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +129,7 @@ export class DomApi {
|
||||
*/
|
||||
getDistributedNodes() {
|
||||
return (this.node.localName === 'slot') ?
|
||||
this.node.assignedNodes({flatten: true}) :
|
||||
wrap(this.node).assignedNodes({flatten: true}) :
|
||||
[];
|
||||
}
|
||||
|
||||
@@ -140,10 +141,10 @@ export class DomApi {
|
||||
*/
|
||||
getDestinationInsertionPoints() {
|
||||
let ip$ = [];
|
||||
let n = this.node.assignedSlot;
|
||||
let n = wrap(this.node).assignedSlot;
|
||||
while (n) {
|
||||
ip$.push(n);
|
||||
n = n.assignedSlot;
|
||||
n = wrap(n).assignedSlot;
|
||||
}
|
||||
return ip$;
|
||||
}
|
||||
@@ -159,7 +160,7 @@ export class DomApi {
|
||||
importNode(node, deep) {
|
||||
let doc = this.node instanceof Document ? this.node :
|
||||
this.node.ownerDocument;
|
||||
return doc.importNode(node, deep);
|
||||
return wrap(doc).importNode(node, deep);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,7 +197,7 @@ export class DomApi {
|
||||
* For shadow roots, returns the currently focused element within this
|
||||
* shadow root.
|
||||
*
|
||||
* @return {Node|undefined} Currently focused element
|
||||
* return {Node|undefined} Currently focused element
|
||||
* @override
|
||||
*/
|
||||
get activeElement() {
|
||||
@@ -209,7 +210,7 @@ function forwardMethods(proto, methods) {
|
||||
for (let i=0; i < methods.length; i++) {
|
||||
let method = methods[i];
|
||||
/* eslint-disable valid-jsdoc */
|
||||
proto[method] = /** @this {DomApi} */ function() {
|
||||
proto[method] = /** @this {DomApiNative} */ function() {
|
||||
return this.node[method].apply(this.node, arguments);
|
||||
};
|
||||
/* eslint-enable */
|
||||
@@ -221,7 +222,7 @@ function forwardReadOnlyProperties(proto, properties) {
|
||||
let name = properties[i];
|
||||
Object.defineProperty(proto, name, {
|
||||
get: function() {
|
||||
const domApi = /** @type {DomApi} */(this);
|
||||
const domApi = /** @type {DomApiNative} */(this);
|
||||
return domApi.node[name];
|
||||
},
|
||||
configurable: true
|
||||
@@ -234,14 +235,14 @@ function forwardProperties(proto, properties) {
|
||||
let name = properties[i];
|
||||
Object.defineProperty(proto, name, {
|
||||
/**
|
||||
* @this {DomApi}
|
||||
* @this {DomApiNative}
|
||||
* @return {*} .
|
||||
*/
|
||||
get: function() {
|
||||
return this.node[name];
|
||||
},
|
||||
/**
|
||||
* @this {DomApi}
|
||||
* @this {DomApiNative}
|
||||
* @param {*} value .
|
||||
*/
|
||||
set: function(value) {
|
||||
@@ -268,7 +269,7 @@ export class EventApi {
|
||||
* @return {!EventTarget} The node this event was dispatched to
|
||||
*/
|
||||
get rootTarget() {
|
||||
return this.event.composedPath()[0];
|
||||
return this.path[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,105 +295,146 @@ export class EventApi {
|
||||
* @param {boolean=} deep
|
||||
* @return {!Node}
|
||||
*/
|
||||
DomApi.prototype.cloneNode;
|
||||
DomApiNative.prototype.cloneNode;
|
||||
/**
|
||||
* @function
|
||||
* @param {!Node} node
|
||||
* @return {!Node}
|
||||
*/
|
||||
DomApi.prototype.appendChild;
|
||||
DomApiNative.prototype.appendChild;
|
||||
/**
|
||||
* @function
|
||||
* @param {!Node} newChild
|
||||
* @param {Node} refChild
|
||||
* @return {!Node}
|
||||
*/
|
||||
DomApi.prototype.insertBefore;
|
||||
DomApiNative.prototype.insertBefore;
|
||||
/**
|
||||
* @function
|
||||
* @param {!Node} node
|
||||
* @return {!Node}
|
||||
*/
|
||||
DomApi.prototype.removeChild;
|
||||
DomApiNative.prototype.removeChild;
|
||||
/**
|
||||
* @function
|
||||
* @param {!Node} oldChild
|
||||
* @param {!Node} newChild
|
||||
* @return {!Node}
|
||||
*/
|
||||
DomApi.prototype.replaceChild;
|
||||
DomApiNative.prototype.replaceChild;
|
||||
/**
|
||||
* @function
|
||||
* @param {string} name
|
||||
* @param {string} value
|
||||
* @return {void}
|
||||
*/
|
||||
DomApi.prototype.setAttribute;
|
||||
DomApiNative.prototype.setAttribute;
|
||||
/**
|
||||
* @function
|
||||
* @param {string} name
|
||||
* @return {void}
|
||||
*/
|
||||
DomApi.prototype.removeAttribute;
|
||||
DomApiNative.prototype.removeAttribute;
|
||||
/**
|
||||
* @function
|
||||
* @param {string} selector
|
||||
* @return {?Element}
|
||||
*/
|
||||
DomApi.prototype.querySelector;
|
||||
DomApiNative.prototype.querySelector;
|
||||
/**
|
||||
* @function
|
||||
* @param {string} selector
|
||||
* @return {!NodeList<!Element>}
|
||||
*/
|
||||
DomApi.prototype.querySelectorAll;
|
||||
DomApiNative.prototype.querySelectorAll;
|
||||
|
||||
/** @type {?Node} */
|
||||
DomApi.prototype.parentNode;
|
||||
DomApiNative.prototype.parentNode;
|
||||
/** @type {?Node} */
|
||||
DomApi.prototype.firstChild;
|
||||
DomApiNative.prototype.firstChild;
|
||||
/** @type {?Node} */
|
||||
DomApi.prototype.lastChild;
|
||||
DomApiNative.prototype.lastChild;
|
||||
/** @type {?Node} */
|
||||
DomApi.prototype.nextSibling;
|
||||
DomApiNative.prototype.nextSibling;
|
||||
/** @type {?Node} */
|
||||
DomApi.prototype.previousSibling;
|
||||
DomApiNative.prototype.previousSibling;
|
||||
/** @type {?HTMLElement} */
|
||||
DomApi.prototype.firstElementChild;
|
||||
DomApiNative.prototype.firstElementChild;
|
||||
/** @type {?HTMLElement} */
|
||||
DomApi.prototype.lastElementChild;
|
||||
DomApiNative.prototype.lastElementChild;
|
||||
/** @type {?HTMLElement} */
|
||||
DomApi.prototype.nextElementSibling;
|
||||
DomApiNative.prototype.nextElementSibling;
|
||||
/** @type {?HTMLElement} */
|
||||
DomApi.prototype.previousElementSibling;
|
||||
DomApiNative.prototype.previousElementSibling;
|
||||
/** @type {!Array<!Node>} */
|
||||
DomApi.prototype.childNodes;
|
||||
DomApiNative.prototype.childNodes;
|
||||
/** @type {!Array<!HTMLElement>} */
|
||||
DomApi.prototype.children;
|
||||
DomApiNative.prototype.children;
|
||||
/** @type {?DOMTokenList} */
|
||||
DomApi.prototype.classList;
|
||||
DomApiNative.prototype.classList;
|
||||
|
||||
/** @type {string} */
|
||||
DomApi.prototype.textContent;
|
||||
DomApiNative.prototype.textContent;
|
||||
/** @type {string} */
|
||||
DomApi.prototype.innerHTML;
|
||||
DomApiNative.prototype.innerHTML;
|
||||
|
||||
forwardMethods(DomApi.prototype, [
|
||||
'cloneNode', 'appendChild', 'insertBefore', 'removeChild',
|
||||
'replaceChild', 'setAttribute', 'removeAttribute',
|
||||
'querySelector', 'querySelectorAll'
|
||||
]);
|
||||
let DomApiImpl = DomApiNative;
|
||||
|
||||
forwardReadOnlyProperties(DomApi.prototype, [
|
||||
'parentNode', 'firstChild', 'lastChild',
|
||||
'nextSibling', 'previousSibling', 'firstElementChild',
|
||||
'lastElementChild', 'nextElementSibling', 'previousElementSibling',
|
||||
'childNodes', 'children', 'classList'
|
||||
]);
|
||||
if (window['ShadyDOM'] && window['ShadyDOM']['inUse'] && window['ShadyDOM']['noPatch'] && window['ShadyDOM']['Wrapper']) {
|
||||
|
||||
forwardProperties(DomApi.prototype, [
|
||||
'textContent', 'innerHTML'
|
||||
]);
|
||||
/**
|
||||
* @private
|
||||
* @extends {HTMLElement}
|
||||
*/
|
||||
class Wrapper extends window['ShadyDOM']['Wrapper'] {}
|
||||
|
||||
// copy bespoke API onto wrapper
|
||||
Object.getOwnPropertyNames(DomApiNative.prototype).forEach((prop) => {
|
||||
if (prop != 'activeElement') {
|
||||
Wrapper.prototype[prop] = DomApiNative.prototype[prop];
|
||||
}
|
||||
});
|
||||
|
||||
DomApiImpl = Wrapper;
|
||||
|
||||
Object.defineProperties(EventApi.prototype, {
|
||||
|
||||
localTarget: {
|
||||
get() {
|
||||
return this.event.currentTarget;
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
|
||||
path: {
|
||||
get() {
|
||||
return window['ShadyDOM']['composedPath'](this.event);
|
||||
},
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
forwardMethods(DomApiNative.prototype, [
|
||||
'cloneNode', 'appendChild', 'insertBefore', 'removeChild',
|
||||
'replaceChild', 'setAttribute', 'removeAttribute',
|
||||
'querySelector', 'querySelectorAll'
|
||||
]);
|
||||
|
||||
forwardReadOnlyProperties(DomApiNative.prototype, [
|
||||
'parentNode', 'firstChild', 'lastChild',
|
||||
'nextSibling', 'previousSibling', 'firstElementChild',
|
||||
'lastElementChild', 'nextElementSibling', 'previousElementSibling',
|
||||
'childNodes', 'children', 'classList'
|
||||
]);
|
||||
|
||||
forwardProperties(DomApiNative.prototype, [
|
||||
'textContent', 'innerHTML'
|
||||
]);
|
||||
}
|
||||
|
||||
export const DomApi = DomApiImpl;
|
||||
|
||||
/**
|
||||
* Legacy DOM and Event manipulation API wrapper factory used to abstract
|
||||
@@ -405,19 +447,25 @@ forwardProperties(DomApi.prototype, [
|
||||
*
|
||||
* @summary Legacy DOM and Event manipulation API wrapper factory used to
|
||||
* abstract differences between native Shadow DOM and "Shady DOM."
|
||||
* @param {(Node|Event)=} obj Node or event to operate on
|
||||
* @return {!DomApi|!EventApi} Wrapper providing either node API or event API
|
||||
* @param {(Node|Event|DomApiNative|EventApi)=} obj Node or event to operate on
|
||||
* @return {!DomApiNative|!EventApi} Wrapper providing either node API or event API
|
||||
*/
|
||||
export const dom = function(obj) {
|
||||
obj = obj || document;
|
||||
if (!obj['__domApi']) {
|
||||
let helper;
|
||||
if (obj instanceof DomApiImpl) {
|
||||
return /** @type {!DomApi} */(obj);
|
||||
}
|
||||
if (obj instanceof EventApi) {
|
||||
return /** @type {!EventApi} */(obj);
|
||||
}
|
||||
let helper = obj['__domApi'];
|
||||
if (!helper) {
|
||||
if (obj instanceof Event) {
|
||||
helper = new EventApi(obj);
|
||||
} else {
|
||||
helper = new DomApi(obj);
|
||||
helper = new DomApiImpl(/** @type {Node} */(obj));
|
||||
}
|
||||
obj['__domApi'] = helper;
|
||||
}
|
||||
return obj['__domApi'];
|
||||
return helper;
|
||||
};
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
* @suppress {checkPrototypalTypes}
|
||||
@license
|
||||
Copyright (c) 2017 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
|
||||
*/
|
||||
* @license Copyright (c) 2017 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
|
||||
*/
|
||||
import { PropertyAccessors } from './property-accessors.js';
|
||||
|
||||
import { dedupingMixin } from '../utils/mixin.js';
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
* @suppress {checkPrototypalTypes}
|
||||
@license
|
||||
Copyright (c) 2017 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
|
||||
*/
|
||||
* @license Copyright (c) 2017 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
|
||||
*/
|
||||
import { ElementMixin } from './element-mixin.js';
|
||||
|
||||
import { dedupingMixin } from '../utils/mixin.js';
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
* @suppress {checkPrototypalTypes}
|
||||
@license
|
||||
Copyright (c) 2017 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
|
||||
*/
|
||||
* @license Copyright (c) 2017 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
|
||||
*/
|
||||
import '../utils/boot.js';
|
||||
|
||||
import { rootPath, strictTemplatePolicy, allowTemplateFromDomModule, legacyOptimizations } from '../utils/settings.js';
|
||||
import { rootPath, strictTemplatePolicy, allowTemplateFromDomModule, legacyOptimizations, syncInitialRender } from '../utils/settings.js';
|
||||
import { dedupingMixin } from '../utils/mixin.js';
|
||||
import { stylesFromTemplate, stylesFromModuleImports } from '../utils/style-gather.js';
|
||||
import { pathFromUrl, resolveCss, resolveUrl } from '../utils/resolve-url.js';
|
||||
import { DomModule } from '../elements/dom-module.js';
|
||||
import { PropertyEffects } from './property-effects.js';
|
||||
import { PropertiesMixin } from './properties-mixin.js';
|
||||
import { wrap } from '../utils/wrap.js';
|
||||
|
||||
/**
|
||||
* Current Polymer version in Semver notation.
|
||||
@@ -324,7 +326,7 @@ export const ElementMixin = dedupingMixin(base => {
|
||||
*/
|
||||
class PolymerElement extends polymerElementBase {
|
||||
|
||||
/**
|
||||
/**
|
||||
* Current Polymer version in Semver notation.
|
||||
* @type {string} Semver notation of the current version of Polymer.
|
||||
*/
|
||||
@@ -666,13 +668,17 @@ export const ElementMixin = dedupingMixin(base => {
|
||||
* @return {ShadowRoot} node to which the dom has been attached.
|
||||
*/
|
||||
_attachDom(dom) {
|
||||
if (this.attachShadow) {
|
||||
const n = wrap(this);
|
||||
if (n.attachShadow) {
|
||||
if (dom) {
|
||||
if (!this.shadowRoot) {
|
||||
this.attachShadow({mode: 'open'});
|
||||
if (!n.shadowRoot) {
|
||||
n.attachShadow({mode: 'open'});
|
||||
}
|
||||
this.shadowRoot.appendChild(dom);
|
||||
return this.shadowRoot;
|
||||
n.shadowRoot.appendChild(dom);
|
||||
if (syncInitialRender && window.ShadyDOM) {
|
||||
ShadyDOM.flushInitial(n.shadowRoot);
|
||||
}
|
||||
return n.shadowRoot;
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
@@ -760,6 +766,7 @@ export const ElementMixin = dedupingMixin(base => {
|
||||
* @param {Object=} effect Effect metadata object
|
||||
* @return {void}
|
||||
* @protected
|
||||
* @suppress {missingProperties} Interfaces in closure do not inherit statics, but classes do
|
||||
*/
|
||||
static _addTemplatePropertyEffect(templateInfo, prop, effect) {
|
||||
// Warn if properties are used in template without being declared.
|
||||
|
||||
@@ -11,6 +11,7 @@ import '../utils/boot.js';
|
||||
|
||||
import { dedupingMixin } from '../utils/mixin.js';
|
||||
import { microTask } from '../utils/async.js';
|
||||
import { wrap } from '../utils/wrap.js';
|
||||
|
||||
/** @const {!AsyncInterface} */
|
||||
const microtask = microTask;
|
||||
@@ -496,6 +497,9 @@ export const PropertiesChanged = dedupingMixin(
|
||||
if (str === undefined) {
|
||||
node.removeAttribute(attribute);
|
||||
} else {
|
||||
if (attribute === 'class' || attribute === 'name' || attribute === 'slot') {
|
||||
node = /** @type {?Element} */(wrap(node));
|
||||
}
|
||||
node.setAttribute(attribute, str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ export const PropertyAccessors = dedupingMixin(superClass => {
|
||||
* setter at instance time. This method is provided as an override
|
||||
* point for customizing or providing more efficient initialization.
|
||||
*
|
||||
* @param {!Object} props Bag of property values that were overwritten
|
||||
* @param {Object} props Bag of property values that were overwritten
|
||||
* when creating property accessors.
|
||||
* @return {void}
|
||||
* @protected
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
* @suppress {checkPrototypalTypes}
|
||||
@license
|
||||
Copyright (c) 2017 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
|
||||
*/
|
||||
* @license Copyright (c) 2017 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
|
||||
*/
|
||||
|
||||
import '../utils/boot.js';
|
||||
|
||||
import { wrap } from '../utils/wrap.js';
|
||||
import { dedupingMixin } from '../utils/mixin.js';
|
||||
import { root, isAncestor, isDescendant, get, translate, isPath, set, normalize } from '../utils/path.js';
|
||||
/* for notify, reflect */
|
||||
@@ -300,7 +301,7 @@ function dispatchNotifyEvent(inst, eventName, value, path) {
|
||||
if (path) {
|
||||
detail.path = path;
|
||||
}
|
||||
/** @type {!HTMLElement} */(inst).dispatchEvent(new CustomEvent(eventName, { detail }));
|
||||
wrap(/** @type {!HTMLElement} */(inst)).dispatchEvent(new CustomEvent(eventName, { detail }));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1172,7 +1173,7 @@ export const PropertyEffects = dedupingMixin(superClass => {
|
||||
* the prototype on the instance.
|
||||
*
|
||||
* @override
|
||||
* @param {!Object} props Properties to initialize on the prototype
|
||||
* @param {Object} props Properties to initialize on the prototype
|
||||
* @return {void}
|
||||
*/
|
||||
_initializeProtoProperties(props) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import './boot.js';
|
||||
|
||||
import { calculateSplices } from './array-splice.js';
|
||||
import { microTask } from './async.js';
|
||||
import { wrap } from './wrap.js';
|
||||
|
||||
/**
|
||||
* Returns true if `node` is a slot element
|
||||
@@ -64,7 +65,7 @@ function isSlot(node) {
|
||||
* "flattened nodes" on a given `node`.
|
||||
* @implements {PolymerDomApi.ObserveHandle}
|
||||
*/
|
||||
export class FlattenedNodesObserver {
|
||||
export let FlattenedNodesObserver = class {
|
||||
|
||||
/**
|
||||
* Returns the list of flattened nodes for the given `node`.
|
||||
@@ -80,15 +81,17 @@ export class FlattenedNodesObserver {
|
||||
* @return {!Array<!Node>} The list of flattened nodes for the given `node`.
|
||||
* @nocollapse See https://github.com/google/closure-compiler/issues/2763
|
||||
*/
|
||||
// eslint-disable-next-line
|
||||
static getFlattenedNodes(node) {
|
||||
const wrapped = wrap(node);
|
||||
if (isSlot(node)) {
|
||||
node = /** @type {!HTMLSlotElement} */(node); // eslint-disable-line no-self-assign
|
||||
return node.assignedNodes({flatten: true});
|
||||
return wrapped.assignedNodes({flatten: true});
|
||||
} else {
|
||||
return Array.from(node.childNodes).map((node) => {
|
||||
return Array.from(wrapped.childNodes).map((node) => {
|
||||
if (isSlot(node)) {
|
||||
node = /** @type {!HTMLSlotElement} */(node); // eslint-disable-line no-self-assign
|
||||
return node.assignedNodes({flatten: true});
|
||||
return wrap(node).assignedNodes({flatten: true});
|
||||
} else {
|
||||
return [node];
|
||||
}
|
||||
@@ -101,6 +104,7 @@ export class FlattenedNodesObserver {
|
||||
* @param {?function(this: Element, { target: !HTMLElement, addedNodes: !Array<!Element>, removedNodes: !Array<!Element> }):void} callback Function called when there are additions
|
||||
* or removals from the target's list of flattened nodes.
|
||||
*/
|
||||
// eslint-disable-next-line
|
||||
constructor(target, callback) {
|
||||
/**
|
||||
* @type {MutationObserver}
|
||||
@@ -143,9 +147,9 @@ export class FlattenedNodesObserver {
|
||||
connect() {
|
||||
if (isSlot(this._target)) {
|
||||
this._listenSlots([this._target]);
|
||||
} else if (this._target.children) {
|
||||
} else if (wrap(this._target).children) {
|
||||
this._listenSlots(
|
||||
/** @type {!NodeList<!Node>} */ (this._target.children));
|
||||
/** @type {!NodeList<!Node>} */ (wrap(this._target).children));
|
||||
if (window.ShadyDOM) {
|
||||
this._shadyChildrenObserver =
|
||||
ShadyDOM.observeChildren(this._target, (mutations) => {
|
||||
@@ -174,9 +178,9 @@ export class FlattenedNodesObserver {
|
||||
disconnect() {
|
||||
if (isSlot(this._target)) {
|
||||
this._unlistenSlots([this._target]);
|
||||
} else if (this._target.children) {
|
||||
} else if (wrap(this._target).children) {
|
||||
this._unlistenSlots(
|
||||
/** @type {!NodeList<!Node>} */ (this._target.children));
|
||||
/** @type {!NodeList<!Node>} */ (wrap(this._target).children));
|
||||
if (window.ShadyDOM && this._shadyChildrenObserver) {
|
||||
ShadyDOM.unobserveChildren(this._shadyChildrenObserver);
|
||||
this._shadyChildrenObserver = null;
|
||||
@@ -307,4 +311,4 @@ export class FlattenedNodesObserver {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
@@ -26,6 +26,7 @@ import './boot.js';
|
||||
import { timeOut, microTask } from './async.js';
|
||||
import { Debouncer } from './debounce.js';
|
||||
import { passiveTouchGestures } from './settings.js';
|
||||
import { wrap } from './wrap.js';
|
||||
|
||||
// detect native touch action support
|
||||
let HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
|
||||
@@ -173,23 +174,21 @@ let mouseCanceller = function(mouseEvent) {
|
||||
// disable "ghost clicks"
|
||||
if (mouseEvent.type === 'click') {
|
||||
let clickFromLabel = false;
|
||||
let path = mouseEvent.composedPath && mouseEvent.composedPath();
|
||||
if (path) {
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
if (path[i].nodeType === Node.ELEMENT_NODE) {
|
||||
if (path[i].localName === 'label') {
|
||||
clickedLabels.push(path[i]);
|
||||
} else if (canBeLabelled(path[i])) {
|
||||
let ownerLabels = matchingLabels(path[i]);
|
||||
// check if one of the clicked labels is labelling this element
|
||||
for (let j = 0; j < ownerLabels.length; j++) {
|
||||
clickFromLabel = clickFromLabel || clickedLabels.indexOf(ownerLabels[j]) > -1;
|
||||
}
|
||||
let path = getComposedPath(mouseEvent);
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
if (path[i].nodeType === Node.ELEMENT_NODE) {
|
||||
if (path[i].localName === 'label') {
|
||||
clickedLabels.push(path[i]);
|
||||
} else if (canBeLabelled(path[i])) {
|
||||
let ownerLabels = matchingLabels(path[i]);
|
||||
// check if one of the clicked labels is labelling this element
|
||||
for (let j = 0; j < ownerLabels.length; j++) {
|
||||
clickFromLabel = clickFromLabel || clickedLabels.indexOf(ownerLabels[j]) > -1;
|
||||
}
|
||||
}
|
||||
if (path[i] === POINTERSTATE.mouse.target) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (path[i] === POINTERSTATE.mouse.target) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if one of the clicked labels was labelling the target element,
|
||||
@@ -229,7 +228,7 @@ function ignoreMouse(e) {
|
||||
POINTERSTATE.mouse.target = null;
|
||||
POINTERSTATE.mouse.mouseIgnoreJob = null;
|
||||
};
|
||||
POINTERSTATE.mouse.target = e.composedPath()[0];
|
||||
POINTERSTATE.mouse.target = getComposedPath(e)[0];
|
||||
POINTERSTATE.mouse.mouseIgnoreJob = Debouncer.debounce(
|
||||
POINTERSTATE.mouse.mouseIgnoreJob
|
||||
, timeOut.after(MOUSE_TIMEOUT)
|
||||
@@ -303,14 +302,12 @@ let POINTERSTATE = {
|
||||
|
||||
function firstTouchAction(ev) {
|
||||
let ta = 'auto';
|
||||
let path = ev.composedPath && ev.composedPath();
|
||||
if (path) {
|
||||
for (let i = 0, n; i < path.length; i++) {
|
||||
n = path[i];
|
||||
if (n[TOUCH_ACTION]) {
|
||||
ta = n[TOUCH_ACTION];
|
||||
break;
|
||||
}
|
||||
let path = getComposedPath(ev);
|
||||
for (let i = 0, n; i < path.length; i++) {
|
||||
n = path[i];
|
||||
if (n[TOUCH_ACTION]) {
|
||||
ta = n[TOUCH_ACTION];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ta;
|
||||
@@ -334,6 +331,15 @@ function untrackDocument(stateObj) {
|
||||
// Use passive event listeners, if supported, to not affect scrolling performance
|
||||
document.addEventListener('touchend', ignoreMouse, SUPPORTS_PASSIVE ? {passive: true} : false);
|
||||
|
||||
/**
|
||||
* Returns the composedPath for the given event.
|
||||
* @param {Event} event to process
|
||||
* @return {!Array<!EventTarget>} Path of the event
|
||||
*/
|
||||
const getComposedPath = window.ShadyDOM && window.ShadyDOM.noPatch ?
|
||||
window.ShadyDOM.composedPath :
|
||||
(event) => event.composedPath && event.composedPath() || [];
|
||||
|
||||
/** @type {!Object<string, !GestureRecognizer>} */
|
||||
export const gestures = {};
|
||||
|
||||
@@ -380,14 +386,9 @@ export function deepTargetFind(x, y) {
|
||||
* @return {EventTarget} Returns the event target.
|
||||
*/
|
||||
function _findOriginalTarget(ev) {
|
||||
// shadowdom
|
||||
if (ev.composedPath) {
|
||||
const targets = /** @type {!Array<!EventTarget>} */(ev.composedPath());
|
||||
// It shouldn't be, but sometimes targets is empty (window on Safari).
|
||||
return targets.length > 0 ? targets[0] : ev.target;
|
||||
}
|
||||
// shadydom
|
||||
return ev.target;
|
||||
const path = getComposedPath(ev);
|
||||
// It shouldn't be, but sometimes path is empty (window on Safari).
|
||||
return path.length > 0 ? path[0] : ev.target;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -659,7 +660,7 @@ export function setTouchAction(node, value) {
|
||||
function _fire(target, type, detail) {
|
||||
let ev = new Event(type, { bubbles: true, cancelable: true, composed: true });
|
||||
ev.detail = detail;
|
||||
target.dispatchEvent(ev);
|
||||
wrap(/** @type {!Node} */(target)).dispatchEvent(ev);
|
||||
// forward `preventDefault` in a clean way
|
||||
if (ev.defaultPrevented) {
|
||||
let preventer = detail.preventer || detail.sourceEvent;
|
||||
|
||||
@@ -140,3 +140,21 @@ export let legacyOptimizations = false;
|
||||
export const setLegacyOptimizations = function(useLegacyOptimizations) {
|
||||
legacyOptimizations = useLegacyOptimizations;
|
||||
};
|
||||
|
||||
/**
|
||||
* Setting to perform initial rendering synchronously when running under ShadyDOM.
|
||||
* This matches the behavior of Polymer 1.
|
||||
*/
|
||||
export let syncInitialRender = false;
|
||||
|
||||
/**
|
||||
* Sets `syncInitialRender` globally for all elements to enable synchronous
|
||||
* initial rendering.
|
||||
*
|
||||
* @param {boolean} useSyncInitialRender enable or disable synchronous initial
|
||||
* rendering globally.
|
||||
* @return {void}
|
||||
*/
|
||||
export const setSyncInitialRender = function(useSyncInitialRender) {
|
||||
syncInitialRender = useSyncInitialRender;
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ export const registrations = [];
|
||||
* @private
|
||||
*/
|
||||
function _regLog(prototype) {
|
||||
console.log('[' + prototype.is + ']: registered');
|
||||
console.log('[' + /** @type {?} */(prototype).is + ']: registered');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,7 +49,8 @@ import './boot.js';
|
||||
|
||||
import { PropertyEffects } from '../mixins/property-effects.js';
|
||||
import { MutableData } from '../mixins/mutable-data.js';
|
||||
import { strictTemplatePolicy } from '../utils/settings.js';
|
||||
import { strictTemplatePolicy } from './settings.js';
|
||||
import { wrap } from './wrap.js';
|
||||
|
||||
// Base class for HTMLTemplateElement extension that has property effects
|
||||
// machinery for propagating host properties to children. This is an ES5
|
||||
@@ -116,6 +117,7 @@ class TemplateInstanceBase extends templateInstanceBase {
|
||||
this.root = this._stampTemplate(this.__dataHost);
|
||||
// Save list of stamped children
|
||||
let children = this.children = [];
|
||||
// Polymer 1.x did not use `Polymer.dom` here so not bothering.
|
||||
for (let n = this.root.firstChild; n; n=n.nextSibling) {
|
||||
children.push(n);
|
||||
n.__templatizeInstance = this;
|
||||
@@ -220,11 +222,11 @@ class TemplateInstanceBase extends templateInstanceBase {
|
||||
} else if (n.localName === 'slot') {
|
||||
if (hide) {
|
||||
n.__polymerReplaced__ = document.createComment('hidden-slot');
|
||||
n.parentNode.replaceChild(n.__polymerReplaced__, n);
|
||||
wrap(wrap(n).parentNode).replaceChild(n.__polymerReplaced__, n);
|
||||
} else {
|
||||
const replace = n.__polymerReplaced__;
|
||||
if (replace) {
|
||||
replace.parentNode.replaceChild(n, replace);
|
||||
wrap(wrap(replace).parentNode).replaceChild(n, replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -338,7 +340,7 @@ function createTemplatizerClass(template, templateInfo, options) {
|
||||
*/
|
||||
let templatizerBase = options.mutableData ?
|
||||
MutableTemplateInstanceBase : TemplateInstanceBase;
|
||||
|
||||
|
||||
// Affordance for global mixins onto TemplatizeInstance
|
||||
if (templatize.mixin) {
|
||||
templatizerBase = templatize.mixin(templatizerBase);
|
||||
@@ -599,7 +601,7 @@ export function modelForElement(template, node) {
|
||||
} else {
|
||||
// Still in a template scope, keep going up until
|
||||
// a __templatizeInstance is found
|
||||
node = node.parentNode;
|
||||
node = wrap(node).parentNode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
23
lib/utils/wrap.js
Normal file
23
lib/utils/wrap.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
@license
|
||||
Copyright (c) 2017 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
|
||||
*/
|
||||
|
||||
/* eslint-disable valid-jsdoc */
|
||||
/**
|
||||
* Node wrapper to ensure ShadowDOM safe operation regardless of polyfill
|
||||
* presence or mode. Note that with the introduction of `ShadyDOM.noPatch`,
|
||||
* a node wrapper must be used to access ShadowDOM API.
|
||||
* This is similar to using `Polymer.dom` but relies exclusively
|
||||
* on the presence of the ShadyDOM polyfill rather than requiring the loading
|
||||
* of legacy (Polymer.dom) API.
|
||||
* @type {function(Node):Node}
|
||||
*/
|
||||
export const wrap = (window['ShadyDOM'] && window['ShadyDOM']['noPatch'] && window['ShadyDOM']['wrap']) ?
|
||||
window['ShadyDOM']['wrap'] : (n) => n;
|
||||
|
||||
1307
package-lock.json
generated
1307
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@
|
||||
"@polymer/gen-typescript-declarations": "^1.5.1",
|
||||
"@polymer/iron-component-page": "^3.0.0-pre.12",
|
||||
"@polymer/test-fixture": "^3.0.0-pre.12",
|
||||
"@webcomponents/webcomponentsjs": "^2.2.6",
|
||||
"@webcomponents/webcomponentsjs": "^2.2.7",
|
||||
"babel-eslint": "^7.2.3",
|
||||
"babel-preset-minify": "^0.2.0",
|
||||
"del": "^3.0.0",
|
||||
|
||||
@@ -37,6 +37,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
'unit/shady-events.html',
|
||||
'unit/shady-content.html',
|
||||
'unit/shady-dynamic.html',
|
||||
'unit/shady-dynamic.html?syncInitialRender=true',
|
||||
'unit/styling-scoped.html',
|
||||
'unit/styling-cross-scope-var.html',
|
||||
'unit/styling-cross-scope-apply.html',
|
||||
@@ -70,6 +71,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
'unit/dom-bind.html',
|
||||
'unit/array-selector.html',
|
||||
'unit/polymer-dom.html',
|
||||
'unit/polymer-dom-nopatch.html',
|
||||
'unit/polymer-dom-observeNodes.html',
|
||||
'unit/flattened-nodes-observer.html',
|
||||
// TODO: substitute for equivalent es6 import tests
|
||||
|
||||
362
test/unit/polymer-dom-nopatch.html
Normal file
362
test/unit/polymer-dom-nopatch.html
Normal file
@@ -0,0 +1,362 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
@license
|
||||
Copyright (c) 2017 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>
|
||||
ShadyDOM = {force: true, noPatch: true};
|
||||
</script>
|
||||
<script src="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
|
||||
<script src="wct-browser-config.js"></script>
|
||||
<script src="../../node_modules/wct-browser-legacy/browser.js"></script>
|
||||
<script type="module" src="../../polymer-legacy.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<dom-module id="x-slot">
|
||||
<template>
|
||||
<div id="container"><slot id="slot"></slot></div>
|
||||
</template>
|
||||
<script type="module">
|
||||
import { Polymer } from '../../polymer-legacy.js';
|
||||
Polymer({
|
||||
is: 'x-slot'
|
||||
});
|
||||
</script>
|
||||
</dom-module>
|
||||
|
||||
<dom-module id="x-container-slot">
|
||||
<template>
|
||||
<x-slot id="container"><div id="first">first</div><slot id="slot"></slot><div id="last">last</div></x-slot>
|
||||
</template>
|
||||
<script type="module">
|
||||
import { Polymer } from '../../polymer-legacy.js';
|
||||
Polymer({
|
||||
is: 'x-container-slot'
|
||||
});
|
||||
</script>
|
||||
</dom-module>
|
||||
|
||||
<dom-module id="x-event-scoped">
|
||||
<template>
|
||||
<div id="scoped"></div>
|
||||
</template>
|
||||
<script type="module">
|
||||
import { Polymer } from '../../polymer-legacy.js';
|
||||
Polymer({
|
||||
is: 'x-event-scoped',
|
||||
fireComposed: function() {
|
||||
return this.fire('composed', null, {node: this.$.scoped});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</dom-module>
|
||||
|
||||
<dom-module id="x-focusable-in-shadow">
|
||||
<template>
|
||||
<input id="focusable"></input>
|
||||
</template>
|
||||
<script type="module">
|
||||
import { Polymer } from '../../polymer-legacy.js';
|
||||
Polymer({
|
||||
is: 'x-focusable-in-shadow'
|
||||
});
|
||||
</script>
|
||||
</dom-module>
|
||||
|
||||
<test-fixture id="scoped">
|
||||
<template>
|
||||
<x-event-scoped></x-event-scoped>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<test-fixture id="slot">
|
||||
<template>
|
||||
<x-container-slot></x-container-slot>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<test-fixture id="focusableInShadow">
|
||||
<template>
|
||||
<x-focusable-in-shadow></x-focusable-in-shadow>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script type="module">
|
||||
import { dom } from '../../lib/legacy/polymer.dom.js';
|
||||
import { useShadow, useNativeCustomElements, useNativeCSSProperties } from '../../lib/utils/settings.js';
|
||||
|
||||
suite('extended dom api', function() {
|
||||
test('getEffectiveChildNodes', function() {
|
||||
var el = fixture('slot');
|
||||
var div = document.createElement('div');
|
||||
dom(el).appendChild(div);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(dom(el).getEffectiveChildNodes(),
|
||||
[div]);
|
||||
assert.deepEqual(dom(el.$.container).getEffectiveChildNodes(),
|
||||
[el.$.first, div, el.$.last]);
|
||||
assert.deepEqual(dom(el.$.container.$.container).getEffectiveChildNodes(),
|
||||
[el.$.first, div, el.$.last]);
|
||||
});
|
||||
|
||||
test('queryDistributedElements', function() {
|
||||
var el = fixture('slot');
|
||||
var div = document.createElement('div');
|
||||
dom(el).appendChild(div);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(dom(el).queryDistributedElements('foo'),
|
||||
[]);
|
||||
assert.deepEqual(dom(el).queryDistributedElements('div'),
|
||||
[div]);
|
||||
assert.deepEqual(dom(el.$.container).queryDistributedElements('#first'),
|
||||
[el.$.first]);
|
||||
assert.deepEqual(dom(el.$.container.$.container).queryDistributedElements('#last'),
|
||||
[el.$.last]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('distribution', function() {
|
||||
test('getDistributedNodes', function() {
|
||||
var el = fixture('slot');
|
||||
var div = document.createElement('div');
|
||||
dom(el).appendChild(div);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(dom(el.$.slot).getDistributedNodes(), [div]);
|
||||
assert.deepEqual(dom(el.$.container.$.slot).getDistributedNodes(),
|
||||
[el.$.first, div, el.$.last]);
|
||||
});
|
||||
|
||||
test('getDestinationInsertionPoints', function() {
|
||||
var el = fixture('slot');
|
||||
var div = document.createElement('div');
|
||||
dom(el).appendChild(div);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(dom(el.$.first).getDestinationInsertionPoints(),
|
||||
[el.$.container.$.slot]);
|
||||
assert.deepEqual(dom(div).getDestinationInsertionPoints(),
|
||||
[el.$.slot, el.$.container.$.slot]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('events', function() {
|
||||
|
||||
test('localTarget, rootTarget, path', function(done) {
|
||||
// skip if noPatch is not available
|
||||
if (!window.ShadyDOM.wrap) {
|
||||
this.skip();
|
||||
}
|
||||
var el = fixture('scoped');
|
||||
el.addEventListener('composed', function(e) {
|
||||
assert.equal(dom(e).rootTarget, el.$.scoped);
|
||||
assert.equal(dom(e).localTarget, el);
|
||||
let nodes = [];
|
||||
let p = el.$.scoped;
|
||||
while (p) {
|
||||
nodes.push(p);
|
||||
p = dom(p).parentNode || ShadyDOM.wrap(p).host;
|
||||
}
|
||||
nodes.push(window);
|
||||
const path = dom(e).path;
|
||||
assert.deepEqual(path, nodes);
|
||||
done();
|
||||
});
|
||||
ShadyDOM.flush();
|
||||
el.fireComposed();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('activeElement getter', function() {
|
||||
test('Retrieves `activeElement`', function() {
|
||||
// skip if noPatch is not available
|
||||
if (!window.ShadyDOM.wrap) {
|
||||
this.skip();
|
||||
}
|
||||
var focusableInShadow = fixture('focusableInShadow');
|
||||
ShadyDOM.wrap(focusableInShadow.$.focusable).focus();
|
||||
var rootNode = ShadyDOM.wrap(focusableInShadow).getRootNode();
|
||||
assert.equal(dom(rootNode).activeElement, focusableInShadow);
|
||||
assert.equal(dom(dom(focusableInShadow).shadowRoot).activeElement, focusableInShadow.$.focusable);
|
||||
});
|
||||
});
|
||||
|
||||
suite('legacy api', function() {
|
||||
test('getEffectiveChildNodes', function() {
|
||||
var el = fixture('slot');
|
||||
var div = document.createElement('div');
|
||||
var t = document.createTextNode('yo');
|
||||
dom(el).appendChild(div);
|
||||
dom(el).appendChild(t);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(el.getEffectiveChildNodes(),
|
||||
[div, t]);
|
||||
assert.deepEqual(el.$.container.getEffectiveChildNodes(),
|
||||
[el.$.first, div, t, el.$.last]);
|
||||
});
|
||||
|
||||
test('getEffectiveChildren', function() {
|
||||
var el = fixture('slot');
|
||||
var div = document.createElement('div');
|
||||
dom(el).appendChild(div);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(el.getEffectiveChildNodes(),
|
||||
[div]);
|
||||
assert.deepEqual(el.$.container.getEffectiveChildNodes(),
|
||||
[el.$.first, div, el.$.last]);
|
||||
});
|
||||
|
||||
test('getEffectiveTextContent', function() {
|
||||
var el = fixture('slot');
|
||||
var t1 = document.createTextNode('a');
|
||||
var t2 = document.createTextNode('b');
|
||||
dom(el).appendChild(t1);
|
||||
dom(el).appendChild(t2);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(el.getEffectiveTextContent(), 'ab');
|
||||
assert.deepEqual(el.$.container.getEffectiveTextContent(), 'firstablast');
|
||||
});
|
||||
|
||||
test('getContentChildNodes', function() {
|
||||
var el = fixture('slot');
|
||||
var div1 = document.createElement('div');
|
||||
var t = document.createTextNode('');
|
||||
var div2 = document.createElement('div');
|
||||
dom(el).appendChild(div1);
|
||||
dom(el).appendChild(t);
|
||||
dom(el).appendChild(div2);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(el.getContentChildNodes(),
|
||||
[div1, t, div2]);
|
||||
assert.deepEqual(el.getContentChildNodes('slot'),
|
||||
[div1, t, div2]);
|
||||
});
|
||||
|
||||
test('getContentChildren', function() {
|
||||
var el = fixture('slot');
|
||||
var div1 = document.createElement('div');
|
||||
var t = document.createTextNode('');
|
||||
var div2 = document.createElement('div');
|
||||
dom(el).appendChild(div1);
|
||||
dom(el).appendChild(t);
|
||||
dom(el).appendChild(div2);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(el.getContentChildren(),
|
||||
[div1, div2]);
|
||||
assert.deepEqual(el.getContentChildren('slot'),
|
||||
[div1, div2]);
|
||||
});
|
||||
|
||||
test('queryDistributedElements', function() {
|
||||
var el = fixture('slot');
|
||||
var div = document.createElement('div');
|
||||
dom(el).appendChild(div);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(el.queryDistributedElements('foo'),
|
||||
[]);
|
||||
assert.deepEqual(el.queryDistributedElements('div'),
|
||||
[div]);
|
||||
assert.deepEqual(el.$.container.queryDistributedElements('#first'),
|
||||
[el.$.first]);
|
||||
});
|
||||
|
||||
test('queryEffectiveChildren', function() {
|
||||
var el = fixture('slot');
|
||||
var div = document.createElement('div');
|
||||
dom(el).appendChild(div);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.equal(el.queryEffectiveChildren('foo'),
|
||||
null);
|
||||
assert.deepEqual(el.queryEffectiveChildren('div'),
|
||||
div);
|
||||
assert.deepEqual(el.$.container.queryEffectiveChildren('#first'),
|
||||
el.$.first);
|
||||
});
|
||||
|
||||
test('queryAllEffectiveChildren', function() {
|
||||
var el = fixture('slot');
|
||||
var div1 = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
dom(el).appendChild(div1);
|
||||
dom(el).appendChild(div2);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.deepEqual(el.queryAllEffectiveChildren('foo'),
|
||||
[]);
|
||||
assert.deepEqual(el.queryAllEffectiveChildren('div'),
|
||||
[div1, div2]);
|
||||
assert.deepEqual(el.$.container.queryAllEffectiveChildren('div'),
|
||||
[el.$.first, div1, div2, el.$.last]);
|
||||
});
|
||||
|
||||
test('isLightDescendant', function() {
|
||||
var el = fixture('slot');
|
||||
var div1 = document.createElement('div');
|
||||
dom(el).appendChild(div1);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.equal(el.isLightDescendant(div1), true);
|
||||
assert.equal(el.isLightDescendant(el.$.container), false);
|
||||
});
|
||||
|
||||
test('isLocalDescendant', function() {
|
||||
var el = fixture('slot');
|
||||
var div1 = document.createElement('div');
|
||||
dom(el).appendChild(div1);
|
||||
if (window.ShadyDOM) {
|
||||
ShadyDOM.flush();
|
||||
}
|
||||
assert.equal(el.isLocalDescendant(div1), false);
|
||||
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(useShadow, !(window.ShadyDOM));
|
||||
assert.equal(useNativeCustomElements, !(window.customElements.polyfillWrapFlushCallback));
|
||||
assert.equal(useNativeCSSProperties, Boolean(!window.ShadyCSS || window.ShadyCSS.nativeCss));
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -22,14 +22,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
<script src="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
|
||||
<script src="wct-browser-config.js"></script>
|
||||
<script src="../../node_modules/wct-browser-legacy/browser.js"></script>
|
||||
<script type="module">
|
||||
import {setSyncInitialRender} from '../../lib/utils/settings.js';
|
||||
window.syncInitialRender = Boolean(window.location.search.match('syncInitialRender'));
|
||||
setSyncInitialRender(window.syncInitialRender);
|
||||
</script>
|
||||
<script type="module" src="../../polymer-legacy.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<dom-module id="x-project">
|
||||
<template>
|
||||
x-project: [<slot></slot>]
|
||||
</template>
|
||||
<template strip-whitespace>x-project: [<slot></slot>]</template>
|
||||
</dom-module>
|
||||
<script type="module">
|
||||
import { Polymer } from '../../polymer-legacy.js';
|
||||
@@ -39,7 +42,7 @@ Polymer({
|
||||
</script>
|
||||
|
||||
<dom-module id="x-reproject">
|
||||
<template>
|
||||
<template strip-whitespace>
|
||||
<x-project>x-reproject: [<slot></slot>]</x-project>
|
||||
</template>
|
||||
</dom-module>
|
||||
@@ -51,7 +54,7 @@ Polymer({
|
||||
</script>
|
||||
|
||||
<dom-module id='x-rereproject'>
|
||||
<template>
|
||||
<template strip-whitespace>
|
||||
<x-reproject>x-rereproject: [<slot></slot>]</x-reproject>
|
||||
</template>
|
||||
</dom-module>
|
||||
@@ -67,7 +70,7 @@ Polymer({
|
||||
</script>
|
||||
|
||||
<dom-module id="x-test">
|
||||
<template>
|
||||
<template strip-whitespace>
|
||||
<x-rereproject><span id="projected">projected</span></x-rereproject>
|
||||
</template>
|
||||
</dom-module>
|
||||
@@ -1328,6 +1331,22 @@ test('event.composedPath correctly calculated for elements with destination inse
|
||||
document.body.removeChild(re);
|
||||
});
|
||||
|
||||
test('initial distribution is synchronous when `syncInitialRender` is true', function() {
|
||||
if (!window.syncInitialRender) {
|
||||
this.skip();
|
||||
}
|
||||
const el = document.createElement('x-test');
|
||||
document.body.appendChild(el);
|
||||
let child = ShadyDOM.nativeTree.firstElementChild(el);
|
||||
assert.equal(child.localName, 'x-rereproject');
|
||||
child = ShadyDOM.nativeTree.firstElementChild(child);
|
||||
assert.equal(child.localName, 'x-reproject');
|
||||
child = ShadyDOM.nativeTree.firstElementChild(child);
|
||||
assert.equal(child.localName, 'x-project');
|
||||
assert.equal(ShadyDOM.nativeTree.textContent(child), 'x-project: [x-reproject: [x-rereproject: [projected]]]');
|
||||
document.body.removeChild(el);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('Accessors', function() {
|
||||
|
||||
Reference in New Issue
Block a user