Index: polymer_1.2.3/bower_components/polymer/polymer-mini.html |
diff --git a/polymer_1.0.4/bower_components/polymer/polymer-mini.html b/polymer_1.2.3/bower_components/polymer/polymer-mini.html |
similarity index 65% |
copy from polymer_1.0.4/bower_components/polymer/polymer-mini.html |
copy to polymer_1.2.3/bower_components/polymer/polymer-mini.html |
index 25393126c79768a1d254562e5b5c5d15c38747ad..4cea2d512df2bb9bb49e27ffe2ea93e3101942eb 100644 |
--- a/polymer_1.0.4/bower_components/polymer/polymer-mini.html |
+++ b/polymer_1.2.3/bower_components/polymer/polymer-mini.html |
@@ -10,10 +10,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN |
<script>Polymer.Base._addFeature({ |
_prepTemplate: function () { |
-this._template = this._template || Polymer.DomModule.import(this.is, 'template'); |
+if (this._template === undefined) { |
+this._template = Polymer.DomModule.import(this.is, 'template'); |
+} |
if (this._template && this._template.hasAttribute('is')) { |
this._warn(this._logf('_prepTemplate', 'top-level Polymer template ' + 'must not be a type-extension, found', this._template, 'Move inside simple <template>.')); |
} |
+if (this._template && !this._template.content && window.HTMLTemplateElement && HTMLTemplateElement.decorate) { |
+HTMLTemplateElement.decorate(this._template); |
+} |
}, |
_stampTemplate: function () { |
if (this._template) { |
@@ -31,20 +36,19 @@ Polymer.Base._addFeature({ |
_hostStack: [], |
ready: function () { |
}, |
-_pushHost: function (host) { |
+_registerHost: function (host) { |
this.dataHost = host = host || Polymer.Base._hostStack[Polymer.Base._hostStack.length - 1]; |
if (host && host._clients) { |
host._clients.push(this); |
} |
-this._beginHost(); |
}, |
-_beginHost: function () { |
+_beginHosting: function () { |
Polymer.Base._hostStack.push(this); |
if (!this._clients) { |
this._clients = []; |
} |
}, |
-_popHost: function () { |
+_endHosting: function () { |
Polymer.Base._hostStack.pop(); |
}, |
_tryReady: function () { |
@@ -57,20 +61,24 @@ return !this.dataHost || this.dataHost._clientsReadied; |
}, |
_ready: function () { |
this._beforeClientsReady(); |
+if (this._template) { |
this._setupRoot(); |
this._readyClients(); |
+} |
+this._clientsReadied = true; |
+this._clients = null; |
this._afterClientsReady(); |
this._readySelf(); |
}, |
_readyClients: function () { |
this._beginDistribute(); |
var c$ = this._clients; |
+if (c$) { |
for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { |
c._ready(); |
} |
+} |
this._finishDistribute(); |
-this._clientsReadied = true; |
-this._clients = null; |
}, |
_readySelf: function () { |
this._doBehavior('ready'); |
@@ -266,61 +274,6 @@ return currentValue === previousValue; |
}; |
return new ArraySplice(); |
}(); |
-Polymer.EventApi = function () { |
-var Settings = Polymer.Settings; |
-var EventApi = function (event) { |
-this.event = event; |
-}; |
-if (Settings.useShadow) { |
-EventApi.prototype = { |
-get rootTarget() { |
-return this.event.path[0]; |
-}, |
-get localTarget() { |
-return this.event.target; |
-}, |
-get path() { |
-return this.event.path; |
-} |
-}; |
-} else { |
-EventApi.prototype = { |
-get rootTarget() { |
-return this.event.target; |
-}, |
-get localTarget() { |
-var current = this.event.currentTarget; |
-var currentRoot = current && Polymer.dom(current).getOwnerRoot(); |
-var p$ = this.path; |
-for (var i = 0; i < p$.length; i++) { |
-if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) { |
-return p$[i]; |
-} |
-} |
-}, |
-get path() { |
-if (!this.event._path) { |
-var path = []; |
-var o = this.rootTarget; |
-while (o) { |
-path.push(o); |
-o = Polymer.dom(o).parentNode || o.host; |
-} |
-path.push(window); |
-this.event._path = path; |
-} |
-return this.event._path; |
-} |
-}; |
-} |
-var factory = function (event) { |
-if (!event.__eventApi) { |
-event.__eventApi = new EventApi(event); |
-} |
-return event.__eventApi; |
-}; |
-return { factory: factory }; |
-}(); |
Polymer.domInnerHTML = function () { |
var escapeAttrRegExp = /[&\u00A0"]/g; |
var escapeDataRegExp = /[&\u00A0<>]/g; |
@@ -426,84 +379,94 @@ var getInnerHTML = Polymer.domInnerHTML.getInnerHTML; |
var nativeInsertBefore = Element.prototype.insertBefore; |
var nativeRemoveChild = Element.prototype.removeChild; |
var nativeAppendChild = Element.prototype.appendChild; |
-var dirtyRoots = []; |
+var nativeCloneNode = Element.prototype.cloneNode; |
+var nativeImportNode = Document.prototype.importNode; |
+var needsToWrap = Settings.hasShadow && !Settings.nativeShadow; |
+var wrap = window.wrap ? window.wrap : function (node) { |
+return node; |
+}; |
var DomApi = function (node) { |
-this.node = node; |
+this.node = needsToWrap ? wrap(node) : node; |
if (this.patch) { |
this.patch(); |
} |
}; |
DomApi.prototype = { |
flush: function () { |
-for (var i = 0, host; i < dirtyRoots.length; i++) { |
-host = dirtyRoots[i]; |
-host.flushDebouncer('_distribute'); |
+Polymer.dom.flush(); |
+}, |
+deepContains: function (node) { |
+if (this.node.contains(node)) { |
+return true; |
+} |
+var n = node; |
+var wrappedDocument = wrap(document); |
+while (n && n !== wrappedDocument && n !== this.node) { |
+n = Polymer.dom(n).parentNode || n.host; |
} |
-dirtyRoots = []; |
+return n === this.node; |
}, |
_lazyDistribute: function (host) { |
if (host.shadyRoot && host.shadyRoot._distributionClean) { |
host.shadyRoot._distributionClean = false; |
-host.debounce('_distribute', host._distributeContent); |
-dirtyRoots.push(host); |
+Polymer.dom.addDebouncer(host.debounce('_distribute', host._distributeContent)); |
} |
}, |
appendChild: function (node) { |
-var handled; |
-this._removeNodeFromHost(node, true); |
-if (this._nodeIsInLogicalTree(this.node)) { |
-this._addLogicalInfo(node, this.node); |
-this._addNodeToHost(node); |
-handled = this._maybeDistribute(node, this.node); |
-} |
-if (!handled && !this._tryRemoveUndistributedNode(node)) { |
-var container = this.node._isShadyRoot ? this.node.host : this.node; |
-addToComposedParent(container, node); |
-nativeAppendChild.call(container, node); |
-} |
-return node; |
+return this._addNode(node); |
}, |
insertBefore: function (node, ref_node) { |
-if (!ref_node) { |
-return this.appendChild(node); |
+return this._addNode(node, ref_node); |
+}, |
+_addNode: function (node, ref_node) { |
+this._removeNodeFromParent(node); |
+var addedInsertionPoint; |
+var root = this.getOwnerRoot(); |
+if (root) { |
+addedInsertionPoint = this._maybeAddInsertionPoint(node, this.node); |
} |
-var handled; |
-this._removeNodeFromHost(node, true); |
-if (this._nodeIsInLogicalTree(this.node)) { |
-saveLightChildrenIfNeeded(this.node); |
+if (this._nodeHasLogicalChildren(this.node)) { |
+if (ref_node) { |
var children = this.childNodes; |
var index = children.indexOf(ref_node); |
if (index < 0) { |
throw Error('The ref_node to be inserted before is not a child ' + 'of this node'); |
} |
+} |
this._addLogicalInfo(node, this.node, index); |
-this._addNodeToHost(node); |
-handled = this._maybeDistribute(node, this.node); |
} |
-if (!handled && !this._tryRemoveUndistributedNode(node)) { |
+this._addNodeToHost(node); |
+if (!this._maybeDistribute(node, this.node) && !this._tryRemoveUndistributedNode(node)) { |
+if (ref_node) { |
ref_node = ref_node.localName === CONTENT ? this._firstComposedNode(ref_node) : ref_node; |
+} |
var container = this.node._isShadyRoot ? this.node.host : this.node; |
addToComposedParent(container, node, ref_node); |
+if (ref_node) { |
nativeInsertBefore.call(container, node, ref_node); |
+} else { |
+nativeAppendChild.call(container, node); |
+} |
} |
+if (addedInsertionPoint) { |
+this._updateInsertionPoints(root.host); |
+} |
+this.notifyObserver(); |
return node; |
}, |
removeChild: function (node) { |
if (factory(node).parentNode !== this.node) { |
console.warn('The node to be removed is not a child of this node', node); |
} |
-var handled; |
-if (this._nodeIsInLogicalTree(this.node)) { |
this._removeNodeFromHost(node); |
-handled = this._maybeDistribute(node, this.node); |
-} |
-if (!handled) { |
+if (!this._maybeDistribute(node, this.node)) { |
var container = this.node._isShadyRoot ? this.node.host : this.node; |
if (container === node.parentNode) { |
removeFromComposedParent(container, node); |
nativeRemoveChild.call(container, node); |
} |
} |
+this.notifyObserver(); |
return node; |
}, |
replaceChild: function (node, ref_node) { |
@@ -511,6 +474,9 @@ this.insertBefore(node, ref_node); |
this.removeChild(ref_node); |
return node; |
}, |
+_hasCachedOwnerRoot: function (node) { |
+return Boolean(node._ownerShadyRoot !== undefined); |
+}, |
getOwnerRoot: function () { |
return this._ownerShadyRootForNode(this.node); |
}, |
@@ -535,14 +501,13 @@ node._ownerShadyRoot = root; |
return node._ownerShadyRoot; |
}, |
_maybeDistribute: function (node, parent) { |
-var fragContent = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && node.querySelector(CONTENT); |
-var wrappedContent = fragContent && fragContent.parentNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE; |
+var fragContent = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent && Polymer.dom(node).querySelector(CONTENT); |
+var wrappedContent = fragContent && Polymer.dom(fragContent).parentNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE; |
var hasContent = fragContent || node.localName === CONTENT; |
if (hasContent) { |
var root = this._ownerShadyRootForNode(parent); |
if (root) { |
var host = root.host; |
-this._updateInsertionPoints(host); |
this._lazyDistribute(host); |
} |
} |
@@ -552,41 +517,74 @@ this._lazyDistribute(parent); |
} |
return parentNeedsDist || hasContent && !wrappedContent; |
}, |
+_maybeAddInsertionPoint: function (node, parent) { |
+var added; |
+if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent) { |
+var c$ = factory(node).querySelectorAll(CONTENT); |
+for (var i = 0, n, np, na; i < c$.length && (n = c$[i]); i++) { |
+np = factory(n).parentNode; |
+if (np === node) { |
+np = parent; |
+} |
+na = this._maybeAddInsertionPoint(n, np); |
+added = added || na; |
+} |
+} else if (node.localName === CONTENT) { |
+saveLightChildrenIfNeeded(parent); |
+saveLightChildrenIfNeeded(node); |
+added = true; |
+} |
+return added; |
+}, |
_tryRemoveUndistributedNode: function (node) { |
if (this.node.shadyRoot) { |
-if (node.parentNode) { |
-nativeRemoveChild.call(node.parentNode, node); |
+var parent = getComposedParent(node); |
+if (parent) { |
+nativeRemoveChild.call(parent, node); |
} |
return true; |
} |
}, |
_updateInsertionPoints: function (host) { |
-host.shadyRoot._insertionPoints = factory(host.shadyRoot).querySelectorAll(CONTENT); |
+var i$ = host.shadyRoot._insertionPoints = factory(host.shadyRoot).querySelectorAll(CONTENT); |
+for (var i = 0, c; i < i$.length; i++) { |
+c = i$[i]; |
+saveLightChildrenIfNeeded(c); |
+saveLightChildrenIfNeeded(factory(c).parentNode); |
+} |
}, |
-_nodeIsInLogicalTree: function (node) { |
-return Boolean(node._lightParent || node._isShadyRoot || this._ownerShadyRootForNode(node) || node.shadyRoot); |
+_nodeHasLogicalChildren: function (node) { |
+return Boolean(node._lightChildren !== undefined); |
}, |
_parentNeedsDistribution: function (parent) { |
return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot); |
}, |
+_removeNodeFromParent: function (node) { |
+var parent = node._lightParent || node.parentNode; |
+if (parent && hasDomApi(parent)) { |
+factory(parent).notifyObserver(); |
+} |
+this._removeNodeFromHost(node, true); |
+}, |
_removeNodeFromHost: function (node, ensureComposedRemoval) { |
var hostNeedsDist; |
var root; |
var parent = node._lightParent; |
if (parent) { |
+factory(node)._distributeParent(); |
root = this._ownerShadyRootForNode(node); |
if (root) { |
root.host._elementRemove(node); |
hostNeedsDist = this._removeDistributedChildren(root, node); |
} |
-this._removeLogicalInfo(node, node._lightParent); |
+this._removeLogicalInfo(node, parent); |
} |
this._removeOwnerShadyRoot(node); |
if (root && hostNeedsDist) { |
this._updateInsertionPoints(root.host); |
this._lazyDistribute(root.host); |
} else if (ensureComposedRemoval) { |
-removeFromComposedParent(parent || node.parentNode, node); |
+removeFromComposedParent(getComposedParent(node), node); |
} |
}, |
_removeDistributedChildren: function (root, container) { |
@@ -598,7 +596,7 @@ if (this._contains(container, content)) { |
var dc$ = factory(content).getDistributedNodes(); |
for (var j = 0; j < dc$.length; j++) { |
hostNeedsDist = true; |
-var node = dc$[i]; |
+var node = dc$[j]; |
var parent = node.parentNode; |
if (parent) { |
removeFromComposedParent(parent, node); |
@@ -618,18 +616,16 @@ node = factory(node).parentNode; |
} |
}, |
_addNodeToHost: function (node) { |
-var checkNode = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ? node.firstChild : node; |
-var root = this._ownerShadyRootForNode(checkNode); |
+var root = this.getOwnerRoot(); |
if (root) { |
root.host._elementAdd(node); |
} |
}, |
_addLogicalInfo: function (node, container, index) { |
-saveLightChildrenIfNeeded(container); |
var children = factory(container).childNodes; |
index = index === undefined ? children.length : index; |
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { |
-var c$ = Array.prototype.slice.call(node.childNodes); |
+var c$ = arrayCopyChildNodes(node); |
for (var i = 0, n; i < c$.length && (n = c$[i]); i++) { |
children.splice(index++, 0, n); |
n._lightParent = container; |
@@ -649,8 +645,7 @@ children.splice(index, 1); |
node._lightParent = null; |
}, |
_removeOwnerShadyRoot: function (node) { |
-var hasCachedRoot = factory(node).getOwnerRoot() !== undefined; |
-if (hasCachedRoot) { |
+if (this._hasCachedOwnerRoot(node)) { |
var c$ = factory(node).childNodes; |
for (var i = 0, l = c$.length, n; i < l && (n = c$[i]); i++) { |
this._removeOwnerShadyRoot(n); |
@@ -701,24 +696,29 @@ getDistributedNodes: function () { |
return this.node._distributedNodes || []; |
}, |
queryDistributedElements: function (selector) { |
-var c$ = this.childNodes; |
+var c$ = this.getEffectiveChildNodes(); |
var list = []; |
-this._distributedFilter(selector, c$, list); |
for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { |
-if (c.localName === CONTENT) { |
-this._distributedFilter(selector, factory(c).getDistributedNodes(), list); |
+if (c.nodeType === Node.ELEMENT_NODE && matchesSelector.call(c, selector)) { |
+list.push(c); |
} |
} |
return list; |
}, |
-_distributedFilter: function (selector, list, results) { |
-results = results || []; |
-for (var i = 0, l = list.length, d; i < l && (d = list[i]); i++) { |
-if (d.nodeType === Node.ELEMENT_NODE && d.localName !== CONTENT && matchesSelector.call(d, selector)) { |
-results.push(d); |
+getEffectiveChildNodes: function () { |
+var list = []; |
+var c$ = this.childNodes; |
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { |
+if (c.localName === CONTENT) { |
+var d$ = factory(c).getDistributedNodes(); |
+for (var j = 0; j < d$.length; j++) { |
+list.push(d$[j]); |
+} |
+} else { |
+list.push(c); |
} |
} |
-return results; |
+return list; |
}, |
_clear: function () { |
while (this.childNodes.length) { |
@@ -737,33 +737,49 @@ _distributeParent: function () { |
if (this._parentNeedsDistribution(this.parentNode)) { |
this._lazyDistribute(this.parentNode); |
} |
+}, |
+cloneNode: function (deep) { |
+var n = nativeCloneNode.call(this.node, false); |
+if (deep) { |
+var c$ = this.childNodes; |
+var d = factory(n); |
+for (var i = 0, nc; i < c$.length; i++) { |
+nc = factory(c$[i]).cloneNode(true); |
+d.appendChild(nc); |
} |
-}; |
-Object.defineProperty(DomApi.prototype, 'classList', { |
-get: function () { |
-if (!this._classList) { |
-this._classList = new DomApi.ClassList(this); |
} |
-return this._classList; |
+return n; |
}, |
-configurable: true |
-}); |
-DomApi.ClassList = function (host) { |
-this.domApi = host; |
-this.node = host.node; |
-}; |
-DomApi.ClassList.prototype = { |
-add: function () { |
-this.node.classList.add.apply(this.node.classList, arguments); |
-this.domApi._distributeParent(); |
+importNode: function (externalNode, deep) { |
+var doc = this.node instanceof Document ? this.node : this.node.ownerDocument; |
+var n = nativeImportNode.call(doc, externalNode, false); |
+if (deep) { |
+var c$ = factory(externalNode).childNodes; |
+var d = factory(n); |
+for (var i = 0, nc; i < c$.length; i++) { |
+nc = factory(doc).importNode(c$[i], true); |
+d.appendChild(nc); |
+} |
+} |
+return n; |
}, |
-remove: function () { |
-this.node.classList.remove.apply(this.node.classList, arguments); |
-this.domApi._distributeParent(); |
+observeNodes: function (callback) { |
+if (callback) { |
+if (!this.observer) { |
+this.observer = this.node.localName === CONTENT ? new DomApi.DistributedNodesObserver(this) : new DomApi.EffectiveNodesObserver(this); |
+} |
+return this.observer.addListener(callback); |
+} |
}, |
-toggle: function () { |
-this.node.classList.toggle.apply(this.node.classList, arguments); |
-this.domApi._distributeParent(); |
+unobserveNodes: function (handle) { |
+if (this.observer) { |
+this.observer.removeListener(handle); |
+} |
+}, |
+notifyObserver: function () { |
+if (this.observer) { |
+this.observer.notify(); |
+} |
} |
}; |
if (!Settings.useShadow) { |
@@ -771,7 +787,7 @@ Object.defineProperties(DomApi.prototype, { |
childNodes: { |
get: function () { |
var c$ = getLightChildren(this.node); |
-return Array.isArray(c$) ? c$ : Array.prototype.slice.call(c$); |
+return Array.isArray(c$) ? c$ : arrayCopyChildNodes(this.node); |
}, |
configurable: true |
}, |
@@ -785,7 +801,7 @@ configurable: true |
}, |
parentNode: { |
get: function () { |
-return this.node._lightParent || (this.node.__patched ? this.node._composedParent : this.node.parentNode); |
+return this.node._lightParent || getComposedParent(this.node); |
}, |
configurable: true |
}, |
@@ -853,37 +869,50 @@ configurable: true |
}, |
textContent: { |
get: function () { |
-if (this.node.nodeType === Node.TEXT_NODE) { |
+var nt = this.node.nodeType; |
+if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) { |
return this.node.textContent; |
} else { |
-return Array.prototype.map.call(this.childNodes, function (c) { |
-return c.textContent; |
-}).join(''); |
+var tc = []; |
+for (var i = 0, cn = this.childNodes, c; c = cn[i]; i++) { |
+if (c.nodeType !== Node.COMMENT_NODE) { |
+tc.push(c.textContent); |
+} |
+} |
+return tc.join(''); |
} |
}, |
set: function (text) { |
+var nt = this.node.nodeType; |
+if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) { |
+this.node.textContent = text; |
+} else { |
this._clear(); |
if (text) { |
this.appendChild(document.createTextNode(text)); |
} |
+} |
}, |
configurable: true |
}, |
innerHTML: { |
get: function () { |
-if (this.node.nodeType === Node.TEXT_NODE) { |
+var nt = this.node.nodeType; |
+if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) { |
return null; |
} else { |
return getInnerHTML(this.node); |
} |
}, |
set: function (text) { |
-if (this.node.nodeType !== Node.TEXT_NODE) { |
+var nt = this.node.nodeType; |
+if (nt !== Node.TEXT_NODE || nt !== Node.COMMENT_NODE) { |
this._clear(); |
var d = document.createElement('div'); |
d.innerHTML = text; |
-for (var e = d.firstChild; e; e = e.nextSibling) { |
-this.appendChild(e); |
+var c$ = arrayCopyChildNodes(d); |
+for (var i = 0; i < c$.length; i++) { |
+this.appendChild(c$[i]); |
} |
} |
}, |
@@ -894,8 +923,25 @@ DomApi.prototype._getComposedInnerHTML = function () { |
return getInnerHTML(this.node, true); |
}; |
} else { |
+var forwardMethods = function (m$) { |
+for (var i = 0; i < m$.length; i++) { |
+forwardMethod(m$[i]); |
+} |
+}; |
+var forwardMethod = function (method) { |
+DomApi.prototype[method] = function () { |
+return this.node[method].apply(this.node, arguments); |
+}; |
+}; |
+forwardMethods([ |
+'cloneNode', |
+'appendChild', |
+'insertBefore', |
+'removeChild', |
+'replaceChild' |
+]); |
DomApi.prototype.querySelectorAll = function (selector) { |
-return Array.prototype.slice.call(this.node.querySelectorAll(selector)); |
+return arrayCopy(this.node.querySelectorAll(selector)); |
}; |
DomApi.prototype.getOwnerRoot = function () { |
var n = this.node; |
@@ -906,26 +952,30 @@ return n; |
n = n.parentNode; |
} |
}; |
+DomApi.prototype.importNode = function (externalNode, deep) { |
+var doc = this.node instanceof Document ? this.node : this.node.ownerDocument; |
+return doc.importNode(externalNode, deep); |
+}; |
DomApi.prototype.getDestinationInsertionPoints = function () { |
-var n$ = this.node.getDestinationInsertionPoints(); |
-return n$ ? Array.prototype.slice.call(n$) : []; |
+var n$ = this.node.getDestinationInsertionPoints && this.node.getDestinationInsertionPoints(); |
+return n$ ? arrayCopy(n$) : []; |
}; |
DomApi.prototype.getDistributedNodes = function () { |
-var n$ = this.node.getDistributedNodes(); |
-return n$ ? Array.prototype.slice.call(n$) : []; |
+var n$ = this.node.getDistributedNodes && this.node.getDistributedNodes(); |
+return n$ ? arrayCopy(n$) : []; |
}; |
DomApi.prototype._distributeParent = function () { |
}; |
Object.defineProperties(DomApi.prototype, { |
childNodes: { |
get: function () { |
-return Array.prototype.slice.call(this.node.childNodes); |
+return arrayCopyChildNodes(this.node); |
}, |
configurable: true |
}, |
children: { |
get: function () { |
-return Array.prototype.slice.call(this.node.children); |
+return arrayCopyChildren(this.node); |
}, |
configurable: true |
}, |
@@ -948,7 +998,20 @@ return this.node.innerHTML = value; |
configurable: true |
} |
}); |
-var forwards = [ |
+var forwardProperties = function (f$) { |
+for (var i = 0; i < f$.length; i++) { |
+forwardProperty(f$[i]); |
+} |
+}; |
+var forwardProperty = function (name) { |
+Object.defineProperty(DomApi.prototype, name, { |
+get: function () { |
+return this.node[name]; |
+}, |
+configurable: true |
+}); |
+}; |
+forwardProperties([ |
'parentNode', |
'firstChild', |
'lastChild', |
@@ -958,24 +1021,21 @@ var forwards = [ |
'lastElementChild', |
'nextElementSibling', |
'previousElementSibling' |
-]; |
-forwards.forEach(function (name) { |
-Object.defineProperty(DomApi.prototype, name, { |
-get: function () { |
-return this.node[name]; |
-}, |
-configurable: true |
-}); |
-}); |
+]); |
} |
var CONTENT = 'content'; |
-var factory = function (node, patch) { |
+function factory(node, patch) { |
node = node || document; |
if (!node.__domApi) { |
node.__domApi = new DomApi(node, patch); |
} |
return node.__domApi; |
-}; |
+} |
+; |
+function hasDomApi(node) { |
+return Boolean(node.__domApi); |
+} |
+; |
Polymer.dom = function (obj, patch) { |
if (obj instanceof Event) { |
return Polymer.EventApi.factory(obj); |
@@ -983,14 +1043,13 @@ return Polymer.EventApi.factory(obj); |
return factory(obj, patch); |
} |
}; |
-Polymer.dom.flush = DomApi.prototype.flush; |
function getLightChildren(node) { |
var children = node._lightChildren; |
return children ? children : node.childNodes; |
} |
function getComposedChildren(node) { |
if (!node._composedChildren) { |
-node._composedChildren = Array.prototype.slice.call(node.childNodes); |
+node._composedChildren = arrayCopyChildNodes(node); |
} |
return node._composedChildren; |
} |
@@ -1007,6 +1066,9 @@ node._composedChildren = null; |
addNodeToComposedChildren(node, parent, children, i); |
} |
} |
+function getComposedParent(node) { |
+return node.__patched ? node._composedParent : node.parentNode; |
+} |
function addNodeToComposedChildren(node, parent, children, i) { |
node._composedParent = parent; |
children.splice(i >= 0 ? i : children.length, 0, node); |
@@ -1023,36 +1085,457 @@ children.splice(i, 1); |
} |
function saveLightChildrenIfNeeded(node) { |
if (!node._lightChildren) { |
-var c$ = Array.prototype.slice.call(node.childNodes); |
+var c$ = arrayCopyChildNodes(node); |
for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) { |
child._lightParent = child._lightParent || node; |
} |
node._lightChildren = c$; |
} |
} |
+function arrayCopyChildNodes(parent) { |
+var copy = [], i = 0; |
+for (var n = parent.firstChild; n; n = n.nextSibling) { |
+copy[i++] = n; |
+} |
+return copy; |
+} |
+function arrayCopyChildren(parent) { |
+var copy = [], i = 0; |
+for (var n = parent.firstElementChild; n; n = n.nextElementSibling) { |
+copy[i++] = n; |
+} |
+return copy; |
+} |
+function arrayCopy(a$) { |
+var l = a$.length; |
+var copy = new Array(l); |
+for (var i = 0; i < l; i++) { |
+copy[i] = a$[i]; |
+} |
+return copy; |
+} |
function hasInsertionPoint(root) { |
-return Boolean(root._insertionPoints.length); |
+return Boolean(root && root._insertionPoints.length); |
} |
var p = Element.prototype; |
var matchesSelector = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector; |
return { |
getLightChildren: getLightChildren, |
+getComposedParent: getComposedParent, |
getComposedChildren: getComposedChildren, |
removeFromComposedParent: removeFromComposedParent, |
saveLightChildrenIfNeeded: saveLightChildrenIfNeeded, |
matchesSelector: matchesSelector, |
hasInsertionPoint: hasInsertionPoint, |
ctor: DomApi, |
-factory: factory |
+factory: factory, |
+hasDomApi: hasDomApi, |
+arrayCopy: arrayCopy, |
+arrayCopyChildNodes: arrayCopyChildNodes, |
+arrayCopyChildren: arrayCopyChildren, |
+wrap: wrap |
+}; |
+}(); |
+Polymer.Base.extend(Polymer.dom, { |
+_flushGuard: 0, |
+_FLUSH_MAX: 100, |
+_needsTakeRecords: !Polymer.Settings.useNativeCustomElements, |
+_debouncers: [], |
+_staticFlushList: [], |
+_finishDebouncer: null, |
+flush: function () { |
+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(); |
+} |
+if (this._finishDebouncer) { |
+this._finishDebouncer.complete(); |
+} |
+this._prepareFlush(); |
+this._flushGuard++; |
+} |
+if (this._flushGuard >= this._FLUSH_MAX) { |
+console.warn('Polymer.dom.flush aborted. Flush may not be complete.'); |
+} |
+}, |
+_prepareFlush: function () { |
+if (this._needsTakeRecords) { |
+CustomElements.takeRecords(); |
+} |
+for (var i = 0; i < this._staticFlushList.length; i++) { |
+this._staticFlushList[i](); |
+} |
+}, |
+addStaticFlush: function (fn) { |
+this._staticFlushList.push(fn); |
+}, |
+removeStaticFlush: function (fn) { |
+var i = this._staticFlushList.indexOf(fn); |
+if (i >= 0) { |
+this._staticFlushList.splice(i, 1); |
+} |
+}, |
+addDebouncer: function (debouncer) { |
+this._debouncers.push(debouncer); |
+this._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlush); |
+}, |
+_finishFlush: function () { |
+Polymer.dom._debouncers = []; |
+} |
+}); |
+Polymer.EventApi = function () { |
+'use strict'; |
+var DomApi = Polymer.DomApi.ctor; |
+var Settings = Polymer.Settings; |
+DomApi.Event = function (event) { |
+this.event = event; |
}; |
+if (Settings.useShadow) { |
+DomApi.Event.prototype = { |
+get rootTarget() { |
+return this.event.path[0]; |
+}, |
+get localTarget() { |
+return this.event.target; |
+}, |
+get path() { |
+return this.event.path; |
+} |
+}; |
+} else { |
+DomApi.Event.prototype = { |
+get rootTarget() { |
+return this.event.target; |
+}, |
+get localTarget() { |
+var current = this.event.currentTarget; |
+var currentRoot = current && Polymer.dom(current).getOwnerRoot(); |
+var p$ = this.path; |
+for (var i = 0; i < p$.length; i++) { |
+if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) { |
+return p$[i]; |
+} |
+} |
+}, |
+get path() { |
+if (!this.event._path) { |
+var path = []; |
+var o = this.rootTarget; |
+while (o) { |
+path.push(o); |
+o = Polymer.dom(o).parentNode || o.host; |
+} |
+path.push(window); |
+this.event._path = path; |
+} |
+return this.event._path; |
+} |
+}; |
+} |
+var factory = function (event) { |
+if (!event.__eventApi) { |
+event.__eventApi = new DomApi.Event(event); |
+} |
+return event.__eventApi; |
+}; |
+return { factory: factory }; |
}(); |
(function () { |
+'use strict'; |
+var DomApi = Polymer.DomApi.ctor; |
+Object.defineProperty(DomApi.prototype, 'classList', { |
+get: function () { |
+if (!this._classList) { |
+this._classList = new DomApi.ClassList(this); |
+} |
+return this._classList; |
+}, |
+configurable: true |
+}); |
+DomApi.ClassList = function (host) { |
+this.domApi = host; |
+this.node = host.node; |
+}; |
+DomApi.ClassList.prototype = { |
+add: function () { |
+this.node.classList.add.apply(this.node.classList, arguments); |
+this.domApi._distributeParent(); |
+}, |
+remove: function () { |
+this.node.classList.remove.apply(this.node.classList, arguments); |
+this.domApi._distributeParent(); |
+}, |
+toggle: function () { |
+this.node.classList.toggle.apply(this.node.classList, arguments); |
+this.domApi._distributeParent(); |
+}, |
+contains: function () { |
+return this.node.classList.contains.apply(this.node.classList, arguments); |
+} |
+}; |
+}()); |
+(function () { |
+'use strict'; |
+var DomApi = Polymer.DomApi.ctor; |
+var Settings = Polymer.Settings; |
+var hasDomApi = Polymer.DomApi.hasDomApi; |
+DomApi.EffectiveNodesObserver = function (domApi) { |
+this.domApi = domApi; |
+this.node = this.domApi.node; |
+this._listeners = []; |
+}; |
+DomApi.EffectiveNodesObserver.prototype = { |
+addListener: function (callback) { |
+if (!this._isSetup) { |
+this._setup(); |
+this._isSetup = true; |
+} |
+var listener = { |
+fn: callback, |
+_nodes: [] |
+}; |
+this._listeners.push(listener); |
+this._scheduleNotify(); |
+return listener; |
+}, |
+removeListener: function (handle) { |
+var i = this._listeners.indexOf(handle); |
+if (i >= 0) { |
+this._listeners.splice(i, 1); |
+handle._nodes = []; |
+} |
+if (!this._hasListeners()) { |
+this._cleanup(); |
+this._isSetup = false; |
+} |
+}, |
+_setup: function () { |
+this._observeContentElements(this.domApi.childNodes); |
+}, |
+_cleanup: function () { |
+this._unobserveContentElements(this.domApi.childNodes); |
+}, |
+_hasListeners: function () { |
+return Boolean(this._listeners.length); |
+}, |
+_scheduleNotify: function () { |
+if (this._debouncer) { |
+this._debouncer.stop(); |
+} |
+this._debouncer = Polymer.Debounce(this._debouncer, this._notify); |
+this._debouncer.context = this; |
+Polymer.dom.addDebouncer(this._debouncer); |
+}, |
+notify: function () { |
+if (this._hasListeners()) { |
+this._scheduleNotify(); |
+} |
+}, |
+_notify: function (mxns) { |
+this._beforeCallListeners(); |
+this._callListeners(); |
+}, |
+_beforeCallListeners: function () { |
+this._updateContentElements(); |
+}, |
+_updateContentElements: function () { |
+this._observeContentElements(this.domApi.childNodes); |
+}, |
+_observeContentElements: function (elements) { |
+for (var i = 0, n; i < elements.length && (n = elements[i]); i++) { |
+if (this._isContent(n)) { |
+n.__observeNodesMap = n.__observeNodesMap || new WeakMap(); |
+if (!n.__observeNodesMap.has(this)) { |
+n.__observeNodesMap.set(this, this._observeContent(n)); |
+} |
+} |
+} |
+}, |
+_observeContent: function (content) { |
+var self = this; |
+var h = Polymer.dom(content).observeNodes(function () { |
+self._scheduleNotify(); |
+}); |
+h._avoidChangeCalculation = true; |
+return h; |
+}, |
+_unobserveContentElements: function (elements) { |
+for (var i = 0, n, h; i < elements.length && (n = elements[i]); i++) { |
+if (this._isContent(n)) { |
+h = n.__observeNodesMap.get(this); |
+if (h) { |
+Polymer.dom(n).unobserveNodes(h); |
+n.__observeNodesMap.delete(this); |
+} |
+} |
+} |
+}, |
+_isContent: function (node) { |
+return node.localName === 'content'; |
+}, |
+_callListeners: function () { |
+var o$ = this._listeners; |
+var nodes = this._getEffectiveNodes(); |
+for (var i = 0, o; i < o$.length && (o = o$[i]); i++) { |
+var info = this._generateListenerInfo(o, nodes); |
+if (info || o._alwaysNotify) { |
+this._callListener(o, info); |
+} |
+} |
+}, |
+_getEffectiveNodes: function () { |
+return this.domApi.getEffectiveChildNodes(); |
+}, |
+_generateListenerInfo: function (listener, newNodes) { |
+if (listener._avoidChangeCalculation) { |
+return true; |
+} |
+var oldNodes = listener._nodes; |
+var info = { |
+target: this.node, |
+addedNodes: [], |
+removedNodes: [] |
+}; |
+var splices = Polymer.ArraySplice.calculateSplices(newNodes, oldNodes); |
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { |
+for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) { |
+info.removedNodes.push(n); |
+} |
+} |
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { |
+for (var j = s.index; j < s.index + s.addedCount; j++) { |
+info.addedNodes.push(newNodes[j]); |
+} |
+} |
+listener._nodes = newNodes; |
+if (info.addedNodes.length || info.removedNodes.length) { |
+return info; |
+} |
+}, |
+_callListener: function (listener, info) { |
+return listener.fn.call(this.node, info); |
+}, |
+enableShadowAttributeTracking: function () { |
+} |
+}; |
+if (Settings.useShadow) { |
+var baseSetup = DomApi.EffectiveNodesObserver.prototype._setup; |
+var baseCleanup = DomApi.EffectiveNodesObserver.prototype._cleanup; |
+var beforeCallListeners = DomApi.EffectiveNodesObserver.prototype._beforeCallListeners; |
+Polymer.Base.extend(DomApi.EffectiveNodesObserver.prototype, { |
+_setup: function () { |
+if (!this._observer) { |
+var self = this; |
+this._mutationHandler = function (mxns) { |
+if (mxns && mxns.length) { |
+self._scheduleNotify(); |
+} |
+}; |
+this._observer = new MutationObserver(this._mutationHandler); |
+this._boundFlush = function () { |
+self._flush(); |
+}; |
+Polymer.dom.addStaticFlush(this._boundFlush); |
+this._observer.observe(this.node, { childList: true }); |
+} |
+baseSetup.call(this); |
+}, |
+_cleanup: function () { |
+this._observer.disconnect(); |
+this._observer = null; |
+this._mutationHandler = null; |
+Polymer.dom.removeStaticFlush(this._boundFlush); |
+baseCleanup.call(this); |
+}, |
+_flush: function () { |
+if (this._observer) { |
+this._mutationHandler(this._observer.takeRecords()); |
+} |
+}, |
+enableShadowAttributeTracking: function () { |
+if (this._observer) { |
+this._makeContentListenersAlwaysNotify(); |
+this._observer.disconnect(); |
+this._observer.observe(this.node, { |
+childList: true, |
+attributes: true, |
+subtree: true |
+}); |
+var root = this.domApi.getOwnerRoot(); |
+var host = root && root.host; |
+if (host && Polymer.dom(host).observer) { |
+Polymer.dom(host).observer.enableShadowAttributeTracking(); |
+} |
+} |
+}, |
+_makeContentListenersAlwaysNotify: function () { |
+for (var i = 0, h; i < this._listeners.length; i++) { |
+h = this._listeners[i]; |
+h._alwaysNotify = h._isContentListener; |
+} |
+} |
+}); |
+} |
+}()); |
+(function () { |
+'use strict'; |
+var DomApi = Polymer.DomApi.ctor; |
+var Settings = Polymer.Settings; |
+DomApi.DistributedNodesObserver = function (domApi) { |
+DomApi.EffectiveNodesObserver.call(this, domApi); |
+}; |
+DomApi.DistributedNodesObserver.prototype = Object.create(DomApi.EffectiveNodesObserver.prototype); |
+Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, { |
+_setup: function () { |
+}, |
+_cleanup: function () { |
+}, |
+_beforeCallListeners: function () { |
+}, |
+_getEffectiveNodes: function () { |
+return this.domApi.getDistributedNodes(); |
+} |
+}); |
+if (Settings.useShadow) { |
+Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, { |
+_setup: function () { |
+if (!this._observer) { |
+var root = this.domApi.getOwnerRoot(); |
+var host = root && root.host; |
+if (host) { |
+var self = this; |
+this._observer = Polymer.dom(host).observeNodes(function () { |
+self._scheduleNotify(); |
+}); |
+this._observer._isContentListener = true; |
+if (this._hasAttrSelect()) { |
+Polymer.dom(host).observer.enableShadowAttributeTracking(); |
+} |
+} |
+} |
+}, |
+_hasAttrSelect: function () { |
+var select = this.node.getAttribute('select'); |
+return select && select.match(/[[.]+/); |
+}, |
+_cleanup: function () { |
+var root = this.domApi.getOwnerRoot(); |
+var host = root && root.host; |
+if (host) { |
+Polymer.dom(host).unobserveNodes(this._observer); |
+} |
+this._observer = null; |
+} |
+}); |
+} |
+}()); |
+(function () { |
+var hasDomApi = Polymer.DomApi.hasDomApi; |
Polymer.Base._addFeature({ |
_prepShady: function () { |
this._useContent = this._useContent || Boolean(this._template); |
-if (this._useContent) { |
-this._template._hasInsertionPoint = this._template.content.querySelector('content'); |
-} |
}, |
_poolContent: function () { |
if (this._useContent) { |
@@ -1070,10 +1553,16 @@ upgradeLightChildren(this._lightChildren); |
_createLocalRoot: function () { |
this.shadyRoot = this.root; |
this.shadyRoot._distributionClean = false; |
+this.shadyRoot._hasDistributed = false; |
this.shadyRoot._isShadyRoot = true; |
this.shadyRoot._dirtyRoots = []; |
-this.shadyRoot._insertionPoints = this._template._hasInsertionPoint ? this.shadyRoot.querySelectorAll('content') : []; |
+var i$ = this.shadyRoot._insertionPoints = !this._notes || this._notes._hasContent ? this.shadyRoot.querySelectorAll('content') : []; |
saveLightChildrenIfNeeded(this.shadyRoot); |
+for (var i = 0, c; i < i$.length; i++) { |
+c = i$[i]; |
+saveLightChildrenIfNeeded(c); |
+saveLightChildrenIfNeeded(c.parentNode); |
+} |
this.shadyRoot.host = this; |
}, |
get domHost() { |
@@ -1112,8 +1601,10 @@ this.shadyRoot._dirtyRoots = []; |
}, |
_finishDistribute: function () { |
if (this._useContent) { |
+this.shadyRoot._distributionClean = true; |
if (hasInsertionPoint(this.shadyRoot)) { |
this._composeTree(); |
+notifyContentObservers(this.shadyRoot); |
} else { |
if (!this.shadyRoot._hasDistributed) { |
this.textContent = ''; |
@@ -1124,8 +1615,10 @@ var children = this._composeNode(this); |
this._updateChildNodes(this, children); |
} |
} |
+if (!this.shadyRoot._hasDistributed) { |
+notifyInitialDistribution(this); |
+} |
this.shadyRoot._hasDistributed = true; |
-this.shadyRoot._distributionClean = true; |
} |
}, |
elementMatches: function (selector, node) { |
@@ -1223,7 +1716,9 @@ var composed = getComposedChildren(container); |
var splices = Polymer.ArraySplice.calculateSplices(children, composed); |
for (var i = 0, d = 0, s; i < splices.length && (s = splices[i]); i++) { |
for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) { |
+if (getComposedParent(n) === container) { |
remove(n); |
+} |
composed.splice(s.index + d, 1); |
} |
d -= s.addedCount; |
@@ -1236,6 +1731,7 @@ insertBefore(container, n, next); |
composed.splice(j, 0, n); |
} |
} |
+ensureComposedParent(container, children); |
}, |
_matchesContentSelect: function (node, contentElement) { |
var select = contentElement.getAttribute('select'); |
@@ -1265,6 +1761,7 @@ var getLightChildren = Polymer.DomApi.getLightChildren; |
var matchesSelector = Polymer.DomApi.matchesSelector; |
var hasInsertionPoint = Polymer.DomApi.hasInsertionPoint; |
var getComposedChildren = Polymer.DomApi.getComposedChildren; |
+var getComposedParent = Polymer.DomApi.getComposedParent; |
var removeFromComposedParent = Polymer.DomApi.removeFromComposedParent; |
function distributeNodeInto(child, insertionPoint) { |
insertionPoint._distributedNodes.push(child); |
@@ -1308,20 +1805,20 @@ if (newChildParent !== parentNode) { |
removeFromComposedParent(newChildParent, newChild); |
} |
remove(newChild); |
-saveLightChildrenIfNeeded(parentNode); |
nativeInsertBefore.call(parentNode, newChild, refChild || null); |
newChild._composedParent = parentNode; |
} |
function remove(node) { |
var parentNode = getComposedParent(node); |
if (parentNode) { |
-saveLightChildrenIfNeeded(parentNode); |
node._composedParent = null; |
nativeRemoveChild.call(parentNode, node); |
} |
} |
-function getComposedParent(node) { |
-return node.__patched ? node._composedParent : node.parentNode; |
+function ensureComposedParent(parent, children) { |
+for (var i = 0, n; i < children.length; i++) { |
+children[i]._composedParent = parent; |
+} |
} |
function getTopDistributingHost(host) { |
while (host && hostNeedsRedistribution(host)) { |
@@ -1338,6 +1835,19 @@ return host.domHost; |
} |
} |
} |
+function notifyContentObservers(root) { |
+for (var i = 0, c; i < root._insertionPoints.length; i++) { |
+c = root._insertionPoints[i]; |
+if (hasDomApi(c)) { |
+Polymer.dom(c).notifyObserver(); |
+} |
+} |
+} |
+function notifyInitialDistribution(host) { |
+if (hasDomApi(host)) { |
+Polymer.dom(host).notifyObserver(); |
+} |
+} |
var needsUpgrade = window.CustomElements && !CustomElements.useNative; |
function upgradeLightChildren(children) { |
if (needsUpgrade && children) { |
@@ -1370,21 +1880,23 @@ Polymer.DomModule = document.createElement('dom-module'); |
Polymer.Base._addFeature({ |
_registerFeatures: function () { |
this._prepIs(); |
-this._prepAttributes(); |
this._prepBehaviors(); |
-this._prepExtends(); |
this._prepConstructor(); |
this._prepTemplate(); |
this._prepShady(); |
+this._prepPropertyInfo(); |
}, |
_prepBehavior: function (b) { |
this._addHostAttributes(b.hostAttributes); |
}, |
_initFeatures: function () { |
+this._registerHost(); |
+if (this._template) { |
this._poolContent(); |
-this._pushHost(); |
+this._beginHosting(); |
this._stampTemplate(); |
-this._popHost(); |
+this._endHosting(); |
+} |
this._marshalHostAttributes(); |
this._setupDebouncers(); |
this._marshalBehaviors(); |