skatejs-named-slots
Advanced tools
Comparing version
2293
dist/index.js
@@ -5,1428 +5,1431 @@ (function (global, factory) { | ||
(factory((global.skatejsNamedSlots = global.skatejsNamedSlots || {}),global.debounce,global.customEventPolyfill)); | ||
}(this, function (exports,debounce,customEventPolyfill) { | ||
}(this, (function (exports,debounce,customEventPolyfill) { | ||
debounce = 'default' in debounce ? debounce['default'] : debounce; | ||
debounce = 'default' in debounce ? debounce['default'] : debounce; | ||
/** | ||
* @license | ||
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt | ||
*/ | ||
/** | ||
* @license | ||
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt | ||
*/ | ||
if (typeof WeakMap === 'undefined') { | ||
(function () { | ||
var defineProperty = Object.defineProperty; | ||
var counter = Date.now() % 1e9; | ||
if (typeof WeakMap === 'undefined') { | ||
(function () { | ||
var defineProperty = Object.defineProperty; | ||
var counter = Date.now() % 1e9; | ||
var WeakMap = function WeakMap() { | ||
this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); | ||
}; | ||
var WeakMap = function WeakMap() { | ||
this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); | ||
}; | ||
WeakMap.prototype = { | ||
set: function set(key, value) { | ||
var entry = key[this.name]; | ||
if (entry && entry[0] === key) entry[1] = value;else defineProperty(key, this.name, { value: [key, value], writable: true }); | ||
return this; | ||
}, | ||
get: function get(key) { | ||
var entry; | ||
return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined; | ||
}, | ||
delete: function _delete(key) { | ||
var entry = key[this.name]; | ||
if (!entry || entry[0] !== key) return false; | ||
entry[0] = entry[1] = undefined; | ||
return true; | ||
}, | ||
has: function has(key) { | ||
var entry = key[this.name]; | ||
if (!entry) return false; | ||
return entry[0] === key; | ||
} | ||
}; | ||
WeakMap.prototype = { | ||
set: function set(key, value) { | ||
var entry = key[this.name]; | ||
if (entry && entry[0] === key) entry[1] = value;else defineProperty(key, this.name, { value: [key, value], writable: true }); | ||
return this; | ||
}, | ||
get: function get(key) { | ||
var entry; | ||
return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined; | ||
}, | ||
delete: function _delete(key) { | ||
var entry = key[this.name]; | ||
if (!entry || entry[0] !== key) return false; | ||
entry[0] = entry[1] = undefined; | ||
return true; | ||
}, | ||
has: function has(key) { | ||
var entry = key[this.name]; | ||
if (!entry) return false; | ||
return entry[0] === key; | ||
} | ||
}; | ||
window.WeakMap = WeakMap; | ||
})(); | ||
window.WeakMap = WeakMap; | ||
})(); | ||
} | ||
function eachChildNode(node, func) { | ||
if (!node) { | ||
return; | ||
} | ||
function eachChildNode(node, func) { | ||
if (!node) { | ||
return; | ||
var chs = node.childNodes; | ||
var chsLen = chs.length; | ||
for (var a = 0; a < chsLen; a++) { | ||
var ret = func(chs[a], a, chs); | ||
if (typeof ret !== 'undefined') { | ||
return ret; // eslint-disable-line consistent-return | ||
} | ||
} | ||
} | ||
// Re-implemented to avoid Array.prototype.slice.call for performance reasons | ||
function reverse(arr) { | ||
var reversedArray = []; | ||
for (var i = arr.length - 1; i >= 0; i--) { | ||
reversedArray.push(arr[i]); | ||
} | ||
return reversedArray; | ||
} | ||
/** | ||
* Execute func over all child nodes or a document fragment, or a single node | ||
* @param node the node or document fragment | ||
* @param func a function to execute on node or the children of node, if node is a document fragment. | ||
* func may optionally append the node elsewhere, in the case of a document fragment | ||
*/ | ||
function eachNodeOrFragmentNodes(node, func) { | ||
if (node instanceof DocumentFragment) { | ||
var chs = node.childNodes; | ||
var chsLen = chs.length; | ||
for (var a = 0; a < chsLen; a++) { | ||
var ret = func(chs[a], a, chs); | ||
if (typeof ret !== 'undefined') { | ||
return ret; // eslint-disable-line consistent-return | ||
} | ||
} | ||
} | ||
// Re-implemented to avoid Array.prototype.slice.call for performance reasons | ||
function reverse(arr) { | ||
var reversedArray = []; | ||
for (var i = arr.length - 1; i >= 0; i--) { | ||
reversedArray.push(arr[i]); | ||
// We must iterate in reverse to handle the case where child nodes are moved elsewhere during execution | ||
for (var a = chsLen - 1; a >= 0; a--) { | ||
var thisNode = reverse(node.childNodes)[a]; | ||
func(thisNode, a); | ||
} | ||
return reversedArray; | ||
} else { | ||
func(node, 0); | ||
} | ||
} | ||
/** | ||
* Execute func over all child nodes or a document fragment, or a single node | ||
* @param node the node or document fragment | ||
* @param func a function to execute on node or the children of node, if node is a document fragment. | ||
* func may optionally append the node elsewhere, in the case of a document fragment | ||
*/ | ||
function eachNodeOrFragmentNodes(node, func) { | ||
if (node instanceof DocumentFragment) { | ||
var chs = node.childNodes; | ||
var chsLen = chs.length; | ||
var div = document.createElement('div'); | ||
var shadowDomV0 = !!div.createShadowRoot; | ||
var shadowDomV1 = !!div.attachShadow; | ||
// We must iterate in reverse to handle the case where child nodes are moved elsewhere during execution | ||
for (var a = chsLen - 1; a >= 0; a--) { | ||
var thisNode = reverse(node.childNodes)[a]; | ||
func(thisNode, a); | ||
} | ||
} else { | ||
func(node, 0); | ||
} | ||
} | ||
var div$1 = document.createElement('div'); | ||
var div = document.createElement('div'); | ||
var shadowDomV0 = !!div.createShadowRoot; | ||
var shadowDomV1 = !!div.attachShadow; | ||
function getPrototype(obj, key) { | ||
var descriptor = void 0; | ||
var div$1 = document.createElement('div'); | ||
while (obj && !(descriptor = Object.getOwnPropertyDescriptor(obj, key))) { | ||
// eslint-disable-line no-cond-assign | ||
obj = Object.getPrototypeOf(obj); | ||
} | ||
return descriptor; | ||
} | ||
function getPropertyDescriptor (obj, key) { | ||
if (obj instanceof Node) { | ||
obj = div$1; | ||
} | ||
var proto = getPrototype(obj, key); | ||
function getPrototype(obj, key) { | ||
var descriptor = void 0; | ||
if (proto) { | ||
var getter = proto.get; | ||
var setter = proto.set; | ||
var _descriptor = { | ||
configurable: true, | ||
enumerable: true | ||
}; | ||
while (obj && !(descriptor = Object.getOwnPropertyDescriptor(obj, key))) { | ||
// eslint-disable-line no-cond-assign | ||
obj = Object.getPrototypeOf(obj); | ||
if (getter) { | ||
_descriptor.get = getter; | ||
_descriptor.set = setter; | ||
return _descriptor; | ||
} else if (typeof obj[key] === 'function') { | ||
_descriptor.value = obj[key]; | ||
return _descriptor; | ||
} | ||
} | ||
var descriptor = Object.getOwnPropertyDescriptor(obj, key); | ||
if (descriptor && descriptor.get) { | ||
return descriptor; | ||
} | ||
function getPropertyDescriptor (obj, key) { | ||
if (obj instanceof Node) { | ||
obj = div$1; | ||
} | ||
var proto = getPrototype(obj, key); | ||
} | ||
if (proto) { | ||
var getter = proto.get; | ||
var setter = proto.set; | ||
var _descriptor = { | ||
configurable: true, | ||
enumerable: true | ||
}; | ||
// Any code referring to this is because it has to work around this bug in | ||
// WebKit: https://bugs.webkit.org/show_bug.cgi?id=49739 | ||
if (getter) { | ||
_descriptor.get = getter; | ||
_descriptor.set = setter; | ||
return _descriptor; | ||
} else if (typeof obj[key] === 'function') { | ||
_descriptor.value = obj[key]; | ||
return _descriptor; | ||
} | ||
} | ||
var nativeParentNode = getPropertyDescriptor(Element.prototype, 'innerHTML'); | ||
var descriptor = Object.getOwnPropertyDescriptor(obj, key); | ||
if (descriptor && descriptor.get) { | ||
return descriptor; | ||
} | ||
} | ||
var canPatchNativeAccessors = !!nativeParentNode; | ||
var nativeParentNode = getPropertyDescriptor(Element.prototype, 'innerHTML'); | ||
/** | ||
* See https://w3c.github.io/DOM-Parsing/#serializing | ||
* @param {TextNode} | ||
* @returns {string} | ||
*/ | ||
function getEscapedTextContent(textNode) { | ||
return textNode.textContent.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); | ||
} | ||
var canPatchNativeAccessors = !!nativeParentNode; | ||
/** | ||
* @returns {string} | ||
* @param {commentNode} | ||
*/ | ||
function getCommentNodeOuterHtml(commentNode) { | ||
return commentNode.text || "<!--" + commentNode.textContent + "-->"; | ||
} | ||
/** | ||
* See https://w3c.github.io/DOM-Parsing/#serializing | ||
* @param {TextNode} | ||
* @returns {string} | ||
*/ | ||
function getEscapedTextContent(textNode) { | ||
return textNode.textContent.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); | ||
} | ||
function isSlotNode (node) { | ||
return node.tagName === 'SLOT'; | ||
} | ||
/** | ||
* @returns {string} | ||
* @param {commentNode} | ||
*/ | ||
function getCommentNodeOuterHtml(commentNode) { | ||
return commentNode.text || "<!--" + commentNode.textContent + "-->"; | ||
} | ||
var toConsumableArray = function (arr) { | ||
if (Array.isArray(arr)) { | ||
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; | ||
function isSlotNode (node) { | ||
return node.tagName === 'SLOT'; | ||
return arr2; | ||
} else { | ||
return Array.from(arr); | ||
} | ||
}; | ||
var toConsumableArray = function (arr) { | ||
if (Array.isArray(arr)) { | ||
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; | ||
function findSlots(root) { | ||
var slots = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; | ||
var childNodes = root.childNodes; | ||
return arr2; | ||
} else { | ||
return Array.from(arr); | ||
} | ||
}; | ||
function findSlots(root) { | ||
var slots = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; | ||
var childNodes = root.childNodes; | ||
if (shadowDomV0) { | ||
return [].concat(toConsumableArray(root.querySelectorAll('content'))); | ||
} | ||
if (!childNodes || root.nodeType !== Node.ELEMENT_NODE) { | ||
return slots; | ||
} | ||
if (shadowDomV0) { | ||
return [].concat(toConsumableArray(root.querySelectorAll('content'))); | ||
} | ||
var length = childNodes.length; | ||
if (!childNodes || root.nodeType !== Node.ELEMENT_NODE) { | ||
return slots; | ||
} | ||
var length = childNodes.length; | ||
for (var a = 0; a < length; a++) { | ||
var childNode = childNodes[a]; | ||
for (var a = 0; a < length; a++) { | ||
var childNode = childNodes[a]; | ||
if (isSlotNode(childNode)) { | ||
slots.push(childNode); | ||
} | ||
findSlots(childNode, slots); | ||
if (isSlotNode(childNode)) { | ||
slots.push(childNode); | ||
} | ||
return slots; | ||
findSlots(childNode, slots); | ||
} | ||
function isRootNode (node) { | ||
return node.tagName === '_SHADOW_ROOT_'; | ||
} | ||
return slots; | ||
} | ||
var pseudoArrayToArray = (function (pseudoArray) { | ||
return Array.prototype.slice.call(pseudoArray); | ||
}) | ||
function isRootNode (node) { | ||
return node.tagName === '_SHADOW_ROOT_'; | ||
} | ||
var $shadowRoot = '__shadowRoot'; | ||
var pseudoArrayToArray = (function (pseudoArray) { | ||
return Array.prototype.slice.call(pseudoArray); | ||
}) | ||
var v0 = (function () { | ||
// Returns the assigned nodes (unflattened) for a <content> node. | ||
var getAssignedNodes = function getAssignedNodes(node) { | ||
var slot = node.getAttribute('name'); | ||
var $shadowRoot = '__shadowRoot'; | ||
var host = node; | ||
while (host) { | ||
var sr = host[$shadowRoot]; | ||
if (sr && sr.contains(node)) { | ||
break; | ||
} | ||
host = host.parentNode; | ||
} | ||
var v0 = (function () { | ||
// Returns the assigned nodes (unflattened) for a <content> node. | ||
var getAssignedNodes = function getAssignedNodes(node) { | ||
var slot = node.getAttribute('name'); | ||
if (!host) { | ||
return []; | ||
var host = node; | ||
while (host) { | ||
var sr = host[$shadowRoot]; | ||
if (sr && sr.contains(node)) { | ||
break; | ||
} | ||
host = host.parentNode; | ||
} | ||
var chs = host.childNodes; | ||
var chsLen = chs.length; | ||
var filtered = []; | ||
if (!host) { | ||
return []; | ||
} | ||
for (var a = 0; a < chsLen; a++) { | ||
var ch = chs[a]; | ||
var chSlot = ch.getAttribute ? ch.getAttribute('slot') : null; | ||
if (slot === chSlot) { | ||
filtered.push(ch); | ||
} | ||
var chs = host.childNodes; | ||
var chsLen = chs.length; | ||
var filtered = []; | ||
for (var a = 0; a < chsLen; a++) { | ||
var ch = chs[a]; | ||
var chSlot = ch.getAttribute ? ch.getAttribute('slot') : null; | ||
if (slot === chSlot) { | ||
filtered.push(ch); | ||
} | ||
} | ||
return filtered; | ||
}; | ||
return filtered; | ||
}; | ||
var _HTMLElement$prototyp = HTMLElement.prototype; | ||
var getAttribute = _HTMLElement$prototyp.getAttribute; | ||
var setAttribute = _HTMLElement$prototyp.setAttribute; | ||
var _HTMLElement$prototyp = HTMLElement.prototype; | ||
var getAttribute = _HTMLElement$prototyp.getAttribute; | ||
var setAttribute = _HTMLElement$prototyp.setAttribute; | ||
var elementInnerHTML = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML'); | ||
var shadowRootInnerHTML = Object.getOwnPropertyDescriptor(ShadowRoot.prototype, 'innerHTML'); | ||
var elementInnerHTML = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML'); | ||
var shadowRootInnerHTML = Object.getOwnPropertyDescriptor(ShadowRoot.prototype, 'innerHTML'); | ||
// We do this so creating a <slot> actually creates a <content>. | ||
var filterTagName = function filterTagName(name) { | ||
return name === 'slot' ? 'content' : name; | ||
}; | ||
var createElement = document.createElement.bind(document); | ||
var createElementNS = document.createElementNS.bind(document); | ||
document.createElement = function (name) { | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
// We do this so creating a <slot> actually creates a <content>. | ||
var filterTagName = function filterTagName(name) { | ||
return name === 'slot' ? 'content' : name; | ||
}; | ||
var createElement = document.createElement.bind(document); | ||
var createElementNS = document.createElementNS.bind(document); | ||
document.createElement = function (name) { | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
return createElement.apply(undefined, [filterTagName(name)].concat(args)); | ||
}; | ||
document.createElementNS = function (name) { | ||
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { | ||
args[_key2 - 1] = arguments[_key2]; | ||
} | ||
return createElement.apply(undefined, [filterTagName(name)].concat(args)); | ||
}; | ||
document.createElementNS = function (name) { | ||
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { | ||
args[_key2 - 1] = arguments[_key2]; | ||
} | ||
return createElementNS.apply(undefined, [filterTagName(name)].concat(args)); | ||
}; | ||
return createElementNS.apply(undefined, [filterTagName(name)].concat(args)); | ||
}; | ||
// Override innerHTML to turn slot nodes into content nodes. | ||
function replaceSlotsWithContents(node) { | ||
var tree = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT); | ||
var repl = []; | ||
// Override innerHTML to turn slot nodes into content nodes. | ||
function replaceSlotsWithContents(node) { | ||
var tree = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT); | ||
var repl = []; | ||
// Walk the tree and record nodes that need replacing. | ||
while (tree.nextNode()) { | ||
var currentNode = tree.currentNode; | ||
// Walk the tree and record nodes that need replacing. | ||
while (tree.nextNode()) { | ||
var currentNode = tree.currentNode; | ||
if (currentNode.tagName === 'SLOT') { | ||
repl.push(currentNode); | ||
} | ||
if (currentNode.tagName === 'SLOT') { | ||
repl.push(currentNode); | ||
} | ||
} | ||
repl.forEach(function (fake) { | ||
var name = fake.getAttribute('name'); | ||
var real = document.createElement('slot'); | ||
if (name) { | ||
real.setAttribute('name', name); | ||
} | ||
repl.forEach(function (fake) { | ||
var name = fake.getAttribute('name'); | ||
var real = document.createElement('slot'); | ||
if (name) { | ||
real.setAttribute('name', name); | ||
} | ||
fake.parentNode.replaceChild(real, fake); | ||
while (fake.hasChildNodes()) { | ||
real.appendChild(fake.firstChild); | ||
} | ||
}); | ||
} | ||
Object.defineProperty(Element.prototype, 'innerHTML', { | ||
configurable: true, | ||
get: elementInnerHTML.get, | ||
set: function set(html) { | ||
elementInnerHTML.set.call(this, html); | ||
replaceSlotsWithContents(this); | ||
fake.parentNode.replaceChild(real, fake); | ||
while (fake.hasChildNodes()) { | ||
real.appendChild(fake.firstChild); | ||
} | ||
}); | ||
Object.defineProperty(ShadowRoot.prototype, 'innerHTML', { | ||
configurable: true, | ||
get: shadowRootInnerHTML.get, | ||
set: function set(html) { | ||
shadowRootInnerHTML.set.call(this, html); | ||
replaceSlotsWithContents(this); | ||
} | ||
}); | ||
} | ||
Object.defineProperty(Element.prototype, 'innerHTML', { | ||
configurable: true, | ||
get: elementInnerHTML.get, | ||
set: function set(html) { | ||
elementInnerHTML.set.call(this, html); | ||
replaceSlotsWithContents(this); | ||
} | ||
}); | ||
Object.defineProperty(ShadowRoot.prototype, 'innerHTML', { | ||
configurable: true, | ||
get: shadowRootInnerHTML.get, | ||
set: function set(html) { | ||
shadowRootInnerHTML.set.call(this, html); | ||
replaceSlotsWithContents(this); | ||
} | ||
}); | ||
// Node | ||
// ---- | ||
// Node | ||
// ---- | ||
Object.defineProperty(Node.prototype, 'assignedSlot', { | ||
get: function get() { | ||
var parentNode = this.parentNode; | ||
Object.defineProperty(Node.prototype, 'assignedSlot', { | ||
get: function get() { | ||
var parentNode = this.parentNode; | ||
if (parentNode) { | ||
var shadowRoot = parentNode.shadowRoot; | ||
if (parentNode) { | ||
var shadowRoot = parentNode.shadowRoot; | ||
// If { mode } is "closed", always return `null`. | ||
// If { mode } is "closed", always return `null`. | ||
if (!shadowRoot) { | ||
return null; | ||
} | ||
if (!shadowRoot) { | ||
return null; | ||
} | ||
var contents = shadowRoot.querySelectorAll('content'); | ||
for (var a = 0; a < contents.length; a++) { | ||
var content = contents[a]; | ||
if (content.assignedNodes().indexOf(this) > -1) { | ||
return content; | ||
} | ||
var contents = shadowRoot.querySelectorAll('content'); | ||
for (var a = 0; a < contents.length; a++) { | ||
var content = contents[a]; | ||
if (content.assignedNodes().indexOf(this) > -1) { | ||
return content; | ||
} | ||
} | ||
return null; | ||
} | ||
}); | ||
return null; | ||
} | ||
}); | ||
// Just proxy createShadowRoot() because there's no such thing as closed | ||
// shadow trees in v0. | ||
HTMLElement.prototype.attachShadow = function attachShadow() { | ||
var _this = this; | ||
// Just proxy createShadowRoot() because there's no such thing as closed | ||
// shadow trees in v0. | ||
HTMLElement.prototype.attachShadow = function attachShadow() { | ||
var _this = this; | ||
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var mode = _ref.mode; | ||
var mode = _ref.mode; | ||
// In v1 you must specify a mode. | ||
if (mode !== 'closed' && mode !== 'open') { | ||
throw new Error('You must specify { mode } as "open" or "closed" to attachShadow().'); | ||
} | ||
// In v1 you must specify a mode. | ||
if (mode !== 'closed' && mode !== 'open') { | ||
throw new Error('You must specify { mode } as "open" or "closed" to attachShadow().'); | ||
} | ||
// Proxy native v0. | ||
var sr = this.createShadowRoot(); | ||
// Proxy native v0. | ||
var sr = this.createShadowRoot(); | ||
// In v0 it always defines the shadowRoot property so we must undefine it. | ||
if (mode === 'closed') { | ||
Object.defineProperty(this, 'shadowRoot', { | ||
configurable: true, | ||
get: function get() { | ||
return null; | ||
} | ||
}); | ||
} | ||
// For some reason this wasn't being reported as set, but it seems to work | ||
// in dev tools. | ||
Object.defineProperty(sr, 'parentNode', { | ||
// In v0 it always defines the shadowRoot property so we must undefine it. | ||
if (mode === 'closed') { | ||
Object.defineProperty(this, 'shadowRoot', { | ||
configurable: true, | ||
get: function get() { | ||
return _this; | ||
return null; | ||
} | ||
}); | ||
} | ||
// Add a MutationObserver to trigger slot change events when the element | ||
// is mutated. We only need to listen to the childList because we only care | ||
// about light DOM. | ||
var mo = new MutationObserver(function (muts) { | ||
var root = _this[$shadowRoot]; | ||
muts.forEach(function (mut) { | ||
var addedNodes = mut.addedNodes; | ||
var removedNodes = mut.removedNodes; | ||
// For some reason this wasn't being reported as set, but it seems to work | ||
// in dev tools. | ||
Object.defineProperty(sr, 'parentNode', { | ||
get: function get() { | ||
return _this; | ||
} | ||
}); | ||
var slots = {}; | ||
var recordSlots = function recordSlots(node) { | ||
return slots[node.getAttribute && node.getAttribute('slot') || '__default'] = true; | ||
}; | ||
// Add a MutationObserver to trigger slot change events when the element | ||
// is mutated. We only need to listen to the childList because we only care | ||
// about light DOM. | ||
var mo = new MutationObserver(function (muts) { | ||
var root = _this[$shadowRoot]; | ||
muts.forEach(function (mut) { | ||
var addedNodes = mut.addedNodes; | ||
var removedNodes = mut.removedNodes; | ||
if (addedNodes) { | ||
var addedNodesLen = addedNodes.length; | ||
for (var a = 0; a < addedNodesLen; a++) { | ||
recordSlots(addedNodes[a]); | ||
} | ||
var slots = {}; | ||
var recordSlots = function recordSlots(node) { | ||
return slots[node.getAttribute && node.getAttribute('slot') || '__default'] = true; | ||
}; | ||
if (addedNodes) { | ||
var addedNodesLen = addedNodes.length; | ||
for (var a = 0; a < addedNodesLen; a++) { | ||
recordSlots(addedNodes[a]); | ||
} | ||
} | ||
if (removedNodes) { | ||
var removedNodesLen = removedNodes.length; | ||
for (var _a = 0; _a < removedNodesLen; _a++) { | ||
recordSlots(removedNodes[_a]); | ||
} | ||
if (removedNodes) { | ||
var removedNodesLen = removedNodes.length; | ||
for (var _a = 0; _a < removedNodesLen; _a++) { | ||
recordSlots(removedNodes[_a]); | ||
} | ||
} | ||
Object.keys(slots).forEach(function (slot) { | ||
var node = slot === '__default' ? root.querySelector('content:not([name])') || root.querySelector('content[name=""]') : root.querySelector('content[name="' + slot + '"]'); | ||
Object.keys(slots).forEach(function (slot) { | ||
var node = slot === '__default' ? root.querySelector('content:not([name])') || root.querySelector('content[name=""]') : root.querySelector('content[name="' + slot + '"]'); | ||
if (node) { | ||
node.dispatchEvent(new CustomEvent('slotchange', { | ||
bubbles: false, | ||
cancelable: false | ||
})); | ||
} | ||
}); | ||
if (node) { | ||
node.dispatchEvent(new CustomEvent('slotchange', { | ||
bubbles: false, | ||
cancelable: false | ||
})); | ||
} | ||
}); | ||
}); | ||
mo.observe(this, { childList: true }); | ||
}); | ||
mo.observe(this, { childList: true }); | ||
return this[$shadowRoot] = sr; | ||
}; | ||
return this[$shadowRoot] = sr; | ||
}; | ||
// Make like the <slot> name property. | ||
Object.defineProperty(HTMLContentElement.prototype, 'name', { | ||
get: function get() { | ||
return this.getAttribute('name'); | ||
}, | ||
set: function set(name) { | ||
return this.setAttribute('name', name); | ||
} | ||
}); | ||
// Make like the <slot> name property. | ||
Object.defineProperty(HTMLContentElement.prototype, 'name', { | ||
get: function get() { | ||
return this.getAttribute('name'); | ||
}, | ||
set: function set(name) { | ||
return this.setAttribute('name', name); | ||
} | ||
}); | ||
// Make like the element slot property. | ||
Object.defineProperty(HTMLElement.prototype, 'slot', { | ||
get: function get() { | ||
return this.getAttribute('slot'); | ||
}, | ||
set: function set(name) { | ||
return this.setAttribute('slot', name); | ||
} | ||
}); | ||
// Make like the element slot property. | ||
Object.defineProperty(HTMLElement.prototype, 'slot', { | ||
get: function get() { | ||
return this.getAttribute('slot'); | ||
}, | ||
set: function set(name) { | ||
return this.setAttribute('slot', name); | ||
} | ||
}); | ||
// By default, getDistributedNodes() returns a flattened tree (no <slot> | ||
// nodes). That means we get native { deep } but we have to manually do the | ||
// opposite. | ||
HTMLContentElement.prototype.assignedNodes = function assignedNodes() { | ||
var _ref2 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
// By default, getDistributedNodes() returns a flattened tree (no <slot> | ||
// nodes). That means we get native { deep } but we have to manually do the | ||
// opposite. | ||
HTMLContentElement.prototype.assignedNodes = function assignedNodes() { | ||
var _ref2 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var deep = _ref2.deep; | ||
var deep = _ref2.deep; | ||
var cnodes = []; | ||
var dnodes = deep ? this.getDistributedNodes() : getAssignedNodes(this); | ||
var cnodes = []; | ||
var dnodes = deep ? this.getDistributedNodes() : getAssignedNodes(this); | ||
// Regardless of how we get the nodes, we must ensure we're only given text | ||
// nodes or element nodes. | ||
for (var a = 0; a < dnodes.length; a++) { | ||
var dnode = dnodes[a]; | ||
var dtype = dnode.nodeType; | ||
if (dtype === Node.ELEMENT_NODE || dtype === Node.TEXT_NODE) { | ||
cnodes.push(dnode); | ||
} | ||
// Regardless of how we get the nodes, we must ensure we're only given text | ||
// nodes or element nodes. | ||
for (var a = 0; a < dnodes.length; a++) { | ||
var dnode = dnodes[a]; | ||
var dtype = dnode.nodeType; | ||
if (dtype === Node.ELEMENT_NODE || dtype === Node.TEXT_NODE) { | ||
cnodes.push(dnode); | ||
} | ||
return cnodes; | ||
}; | ||
} | ||
return cnodes; | ||
}; | ||
HTMLContentElement.prototype.getAttribute = function overriddenGetAttribute(name) { | ||
if (name === 'name') { | ||
var select = getAttribute.call(this, 'select'); | ||
return select ? select.match(/\[slot=['"]?(.*?)['"]?\]/)[1] : null; | ||
} | ||
return getAttribute.call(this, name); | ||
}; | ||
HTMLContentElement.prototype.getAttribute = function overriddenGetAttribute(name) { | ||
if (name === 'name') { | ||
var select = getAttribute.call(this, 'select'); | ||
return select ? select.match(/\[slot=['"]?(.*?)['"]?\]/)[1] : null; | ||
} | ||
return getAttribute.call(this, name); | ||
}; | ||
HTMLContentElement.prototype.setAttribute = function overriddenSetAttribute(name, value) { | ||
if (name === 'name') { | ||
name = 'select'; | ||
value = '[slot=\'' + value + '\']'; | ||
} | ||
return setAttribute.call(this, name, value); | ||
}; | ||
}) | ||
HTMLContentElement.prototype.setAttribute = function overriddenSetAttribute(name, value) { | ||
if (name === 'name') { | ||
name = 'select'; | ||
value = '[slot=\'' + value + '\']'; | ||
} | ||
return setAttribute.call(this, name, value); | ||
}; | ||
}) | ||
var version = '0.0.1'; | ||
var version = '0.0.1'; | ||
var arrProto = Array.prototype; | ||
var forEach = arrProto.forEach; | ||
var arrProto = Array.prototype; | ||
var forEach = arrProto.forEach; | ||
// We use a real DOM node for a shadow root. This is because the host node | ||
// basically becomes a virtual entry point for your element leaving the shadow | ||
// root the only thing that can receive instructions on how the host should | ||
// render to the browser. | ||
// We use a real DOM node for a shadow root. This is because the host node | ||
// basically becomes a virtual entry point for your element leaving the shadow | ||
// root the only thing that can receive instructions on how the host should | ||
// render to the browser. | ||
var defaultShadowRootTagName = '_shadow_root_'; | ||
var defaultShadowRootTagName = '_shadow_root_'; | ||
// * WebKit only * | ||
// | ||
// These members we need cannot override as we require native access to their | ||
// original values at some point. | ||
var polyfillAtRuntime = ['childNodes', 'parentNode']; | ||
// * WebKit only * | ||
// | ||
// These members we need cannot override as we require native access to their | ||
// original values at some point. | ||
var polyfillAtRuntime = ['childNodes', 'parentNode']; | ||
// Some properties that should not be overridden in the Text prototype. | ||
var doNotOverridePropertiesInTextNodes = ['textContent']; | ||
// Some properties that should not be overridden in the Text prototype. | ||
var doNotOverridePropertiesInTextNodes = ['textContent']; | ||
// Some new properties that should be defined in the Text prototype. | ||
var defineInTextNodes = ['assignedSlot']; | ||
// Some new properties that should be defined in the Text prototype. | ||
var defineInTextNodes = ['assignedSlot']; | ||
// Some properties that should not be overridden in the Comment prototype. | ||
var doNotOverridePropertiesInCommNodes = ['textContent']; | ||
// Some properties that should not be overridden in the Comment prototype. | ||
var doNotOverridePropertiesInCommNodes = ['textContent']; | ||
// Some new properties that should be defined in the Comment prototype. | ||
var defineInCommNodes = []; | ||
// Some new properties that should be defined in the Comment prototype. | ||
var defineInCommNodes = []; | ||
// Nodes that should be slotted | ||
var slottedNodeTypes = [Node.ELEMENT_NODE, Node.TEXT_NODE]; | ||
// Nodes that should be slotted | ||
var slottedNodeTypes = [Node.ELEMENT_NODE, Node.TEXT_NODE]; | ||
// Private data stores. | ||
var assignedToSlotMap = new WeakMap(); | ||
var hostToModeMap = new WeakMap(); | ||
var hostToRootMap = new WeakMap(); | ||
var nodeToChildNodesMap = new WeakMap(); | ||
var nodeToParentNodeMap = new WeakMap(); | ||
var nodeToSlotMap = new WeakMap(); | ||
var rootToHostMap = new WeakMap(); | ||
var rootToSlotMap = new WeakMap(); | ||
var slotToRootMap = new WeakMap(); | ||
// Private data stores. | ||
var assignedToSlotMap = new WeakMap(); | ||
var hostToModeMap = new WeakMap(); | ||
var hostToRootMap = new WeakMap(); | ||
var nodeToChildNodesMap = new WeakMap(); | ||
var nodeToParentNodeMap = new WeakMap(); | ||
var nodeToSlotMap = new WeakMap(); | ||
var rootToHostMap = new WeakMap(); | ||
var rootToSlotMap = new WeakMap(); | ||
var slotToRootMap = new WeakMap(); | ||
// Unfortunately manual DOM parsing is because of WebKit. | ||
var parser = new DOMParser(); | ||
function parse(html) { | ||
var tree = document.createElement('div'); | ||
// Unfortunately manual DOM parsing is because of WebKit. | ||
var parser = new DOMParser(); | ||
function parse(html) { | ||
var tree = document.createElement('div'); | ||
// Everything not WebKit can do this easily. | ||
if (canPatchNativeAccessors) { | ||
tree.__innerHTML = html; | ||
return tree; | ||
} | ||
// Everything not WebKit can do this easily. | ||
if (canPatchNativeAccessors) { | ||
tree.__innerHTML = html; | ||
return tree; | ||
} | ||
var parsed = parser.parseFromString('<div>' + html + '</div>', 'text/html').body.firstChild; | ||
var parsed = parser.parseFromString('<div>' + html + '</div>', 'text/html').body.firstChild; | ||
while (parsed.hasChildNodes()) { | ||
var firstChild = parsed.firstChild; | ||
parsed.removeChild(firstChild); | ||
tree.appendChild(firstChild); | ||
while (parsed.hasChildNodes()) { | ||
var firstChild = parsed.firstChild; | ||
parsed.removeChild(firstChild); | ||
tree.appendChild(firstChild); | ||
} | ||
// Need to import the node to initialise the custom elements from the parser. | ||
return document.importNode(tree, true); | ||
} | ||
function staticProp(obj, name, value) { | ||
Object.defineProperty(obj, name, { | ||
configurable: true, | ||
get: function get() { | ||
return value; | ||
} | ||
}); | ||
} | ||
// Need to import the node to initialise the custom elements from the parser. | ||
return document.importNode(tree, true); | ||
} | ||
// Slotting helpers. | ||
function staticProp(obj, name, value) { | ||
Object.defineProperty(obj, name, { | ||
configurable: true, | ||
get: function get() { | ||
return value; | ||
} | ||
}); | ||
} | ||
function arrayItem(idx) { | ||
return this[idx]; | ||
} | ||
// Slotting helpers. | ||
function makeLikeNodeList(arr) { | ||
arr.item = arrayItem; | ||
return arr; | ||
} | ||
function arrayItem(idx) { | ||
return this[idx]; | ||
function isHostNode(node) { | ||
return !!hostToRootMap.get(node); | ||
} | ||
function getNodeType(node) { | ||
if (isHostNode(node)) { | ||
return 'host'; | ||
} | ||
function makeLikeNodeList(arr) { | ||
arr.item = arrayItem; | ||
return arr; | ||
if (isSlotNode(node)) { | ||
return 'slot'; | ||
} | ||
function isHostNode(node) { | ||
return !!hostToRootMap.get(node); | ||
if (isRootNode(node)) { | ||
return 'root'; | ||
} | ||
function getNodeType(node) { | ||
if (isHostNode(node)) { | ||
return 'host'; | ||
} | ||
return 'node'; | ||
} | ||
if (isSlotNode(node)) { | ||
return 'slot'; | ||
function findClosest(node, func) { | ||
while (node) { | ||
if (node === document) { | ||
break; | ||
} | ||
if (isRootNode(node)) { | ||
return 'root'; | ||
if (func(node)) { | ||
return node; | ||
} | ||
return 'node'; | ||
node = node.parentNode; | ||
} | ||
} | ||
function findClosest(node, func) { | ||
while (node) { | ||
if (node === document) { | ||
break; | ||
} | ||
if (func(node)) { | ||
return node; | ||
} | ||
node = node.parentNode; | ||
} | ||
} | ||
function getSlotNameFromSlot(node) { | ||
return node.getAttribute && node.getAttribute('name') || 'default'; | ||
} | ||
function getSlotNameFromSlot(node) { | ||
return node.getAttribute && node.getAttribute('name') || 'default'; | ||
} | ||
function getSlotNameFromNode(node) { | ||
return node.getAttribute && node.getAttribute('slot') || 'default'; | ||
} | ||
function getSlotNameFromNode(node) { | ||
return node.getAttribute && node.getAttribute('slot') || 'default'; | ||
function slotNodeIntoSlot(slot, node, insertBefore) { | ||
// Only Text and Element nodes should be slotted. | ||
if (slottedNodeTypes.indexOf(node.nodeType) === -1) { | ||
return; | ||
} | ||
function slotNodeIntoSlot(slot, node, insertBefore) { | ||
// Only Text and Element nodes should be slotted. | ||
if (slottedNodeTypes.indexOf(node.nodeType) === -1) { | ||
return; | ||
} | ||
var assignedNodes = slot.assignedNodes(); | ||
var shouldGoIntoContentMode = assignedNodes.length === 0; | ||
var slotInsertBeforeIndex = assignedNodes.indexOf(insertBefore); | ||
var assignedNodes = slot.assignedNodes(); | ||
var shouldGoIntoContentMode = assignedNodes.length === 0; | ||
var slotInsertBeforeIndex = assignedNodes.indexOf(insertBefore); | ||
// Assign the slot to the node internally. | ||
nodeToSlotMap.set(node, slot); | ||
// Assign the slot to the node internally. | ||
nodeToSlotMap.set(node, slot); | ||
// Remove the fallback content and state if we're going into content mode. | ||
if (shouldGoIntoContentMode) { | ||
forEach.call(slot.childNodes, function (child) { | ||
return slot.__removeChild(child); | ||
}); | ||
} | ||
// Remove the fallback content and state if we're going into content mode. | ||
if (shouldGoIntoContentMode) { | ||
forEach.call(slot.childNodes, function (child) { | ||
return slot.__removeChild(child); | ||
}); | ||
} | ||
if (slotInsertBeforeIndex > -1) { | ||
slot.__insertBefore(node, insertBefore !== undefined ? insertBefore : null); | ||
assignedNodes.splice(slotInsertBeforeIndex, 0, node); | ||
} else { | ||
slot.__appendChild(node); | ||
assignedNodes.push(node); | ||
} | ||
slot.____triggerSlotChangeEvent(); | ||
if (slotInsertBeforeIndex > -1) { | ||
slot.__insertBefore(node, insertBefore !== undefined ? insertBefore : null); | ||
assignedNodes.splice(slotInsertBeforeIndex, 0, node); | ||
} else { | ||
slot.__appendChild(node); | ||
assignedNodes.push(node); | ||
} | ||
function slotNodeFromSlot(node) { | ||
var slot = nodeToSlotMap.get(node); | ||
slot.____triggerSlotChangeEvent(); | ||
} | ||
if (slot) { | ||
var assignedNodes = slot.assignedNodes(); | ||
var index = assignedNodes.indexOf(node); | ||
function slotNodeFromSlot(node) { | ||
var slot = nodeToSlotMap.get(node); | ||
if (index > -1) { | ||
var shouldGoIntoDefaultMode = assignedNodes.length === 1; | ||
if (slot) { | ||
var assignedNodes = slot.assignedNodes(); | ||
var index = assignedNodes.indexOf(node); | ||
assignedNodes.splice(index, 1); | ||
nodeToSlotMap.set(node, null); | ||
if (index > -1) { | ||
var shouldGoIntoDefaultMode = assignedNodes.length === 1; | ||
// Actually remove the child. | ||
slot.__removeChild(node); | ||
assignedNodes.splice(index, 1); | ||
nodeToSlotMap.set(node, null); | ||
// If this was the last slotted node, then insert fallback content. | ||
if (shouldGoIntoDefaultMode) { | ||
forEach.call(slot.childNodes, function (child) { | ||
return slot.__appendChild(child); | ||
}); | ||
} | ||
// Actually remove the child. | ||
slot.__removeChild(node); | ||
slot.____triggerSlotChangeEvent(); | ||
// If this was the last slotted node, then insert fallback content. | ||
if (shouldGoIntoDefaultMode) { | ||
forEach.call(slot.childNodes, function (child) { | ||
return slot.__appendChild(child); | ||
}); | ||
} | ||
slot.____triggerSlotChangeEvent(); | ||
} | ||
} | ||
} | ||
// Returns the index of the node in the host's childNodes. | ||
function indexOfNode(host, node) { | ||
var chs = host.childNodes; | ||
var chsLen = chs.length; | ||
for (var a = 0; a < chsLen; a++) { | ||
if (chs[a] === node) { | ||
return a; | ||
} | ||
// Returns the index of the node in the host's childNodes. | ||
function indexOfNode(host, node) { | ||
var chs = host.childNodes; | ||
var chsLen = chs.length; | ||
for (var a = 0; a < chsLen; a++) { | ||
if (chs[a] === node) { | ||
return a; | ||
} | ||
return -1; | ||
} | ||
return -1; | ||
} | ||
// Adds the node to the list of childNodes on the host and fakes any necessary | ||
// information such as parentNode. | ||
function registerNode(host, node, insertBefore, func) { | ||
var index = indexOfNode(host, insertBefore); | ||
eachNodeOrFragmentNodes(node, function (eachNode, eachIndex) { | ||
func(eachNode, eachIndex); | ||
// Adds the node to the list of childNodes on the host and fakes any necessary | ||
// information such as parentNode. | ||
function registerNode(host, node, insertBefore, func) { | ||
var index = indexOfNode(host, insertBefore); | ||
eachNodeOrFragmentNodes(node, function (eachNode, eachIndex) { | ||
func(eachNode, eachIndex); | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(eachNode, host); | ||
} else { | ||
staticProp(eachNode, 'parentNode', host); | ||
} | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(eachNode, host); | ||
} else { | ||
staticProp(eachNode, 'parentNode', host); | ||
} | ||
if (index > -1) { | ||
arrProto.splice.call(host.childNodes, index + eachIndex, 0, eachNode); | ||
} else { | ||
arrProto.push.call(host.childNodes, eachNode); | ||
} | ||
}); | ||
} | ||
if (index > -1) { | ||
arrProto.splice.call(host.childNodes, index + eachIndex, 0, eachNode); | ||
} else { | ||
arrProto.push.call(host.childNodes, eachNode); | ||
} | ||
}); | ||
} | ||
// Cleans up registerNode(). | ||
function unregisterNode(host, node, func) { | ||
var index = indexOfNode(host, node); | ||
// Cleans up registerNode(). | ||
function unregisterNode(host, node, func) { | ||
var index = indexOfNode(host, node); | ||
if (index > -1) { | ||
func(node, 0); | ||
if (index > -1) { | ||
func(node, 0); | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(node, null); | ||
} else { | ||
staticProp(node, 'parentNode', null); | ||
} | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(node, null); | ||
} else { | ||
staticProp(node, 'parentNode', null); | ||
} | ||
arrProto.splice.call(host.childNodes, index, 1); | ||
} | ||
arrProto.splice.call(host.childNodes, index, 1); | ||
} | ||
} | ||
function addNodeToNode(host, node, insertBefore) { | ||
registerNode(host, node, insertBefore, function (eachNode) { | ||
host.__insertBefore(eachNode, insertBefore !== undefined ? insertBefore : null); | ||
}); | ||
function addNodeToNode(host, node, insertBefore) { | ||
registerNode(host, node, insertBefore, function (eachNode) { | ||
host.__insertBefore(eachNode, insertBefore !== undefined ? insertBefore : null); | ||
}); | ||
} | ||
function addNodeToHost(host, node, insertBefore) { | ||
registerNode(host, node, insertBefore, function (eachNode) { | ||
var rootNode = hostToRootMap.get(host); | ||
var slotNodes = rootToSlotMap.get(rootNode); | ||
var slotNode = slotNodes[getSlotNameFromNode(eachNode)]; | ||
if (slotNode) { | ||
slotNodeIntoSlot(slotNode, eachNode, insertBefore); | ||
} | ||
}); | ||
} | ||
function addSlotToRoot(root, slot) { | ||
var slotName = getSlotNameFromSlot(slot); | ||
// Ensure a slot node's childNodes are overridden at the earliest point | ||
// possible for WebKit. | ||
if (!canPatchNativeAccessors && !Array.isArray(slot.childNodes)) { | ||
staticProp(slot, 'childNodes', pseudoArrayToArray(slot.childNodes)); | ||
} | ||
function addNodeToHost(host, node, insertBefore) { | ||
registerNode(host, node, insertBefore, function (eachNode) { | ||
var rootNode = hostToRootMap.get(host); | ||
var slotNodes = rootToSlotMap.get(rootNode); | ||
var slotNode = slotNodes[getSlotNameFromNode(eachNode)]; | ||
if (slotNode) { | ||
slotNodeIntoSlot(slotNode, eachNode, insertBefore); | ||
} | ||
}); | ||
rootToSlotMap.get(root)[slotName] = slot; | ||
if (!slotToRootMap.has(slot)) { | ||
slotToRootMap.set(slot, root); | ||
} | ||
function addSlotToRoot(root, slot) { | ||
var slotName = getSlotNameFromSlot(slot); | ||
eachChildNode(rootToHostMap.get(root), function (eachNode) { | ||
if (!eachNode.assignedSlot && slotName === getSlotNameFromNode(eachNode)) { | ||
slotNodeIntoSlot(slot, eachNode); | ||
} | ||
}); | ||
} | ||
// Ensure a slot node's childNodes are overridden at the earliest point | ||
// possible for WebKit. | ||
if (!canPatchNativeAccessors && !Array.isArray(slot.childNodes)) { | ||
staticProp(slot, 'childNodes', pseudoArrayToArray(slot.childNodes)); | ||
function addNodeToRoot(root, node, insertBefore) { | ||
eachNodeOrFragmentNodes(node, function (child) { | ||
if (isSlotNode(child)) { | ||
addSlotToRoot(root, child); | ||
} else { | ||
var slotNodes = findSlots(child); | ||
if (slotNodes) { | ||
var slotNodesLen = slotNodes.length; | ||
for (var a = 0; a < slotNodesLen; a++) { | ||
addSlotToRoot(root, slotNodes[a]); | ||
} | ||
} | ||
} | ||
}); | ||
addNodeToNode(root, node, insertBefore); | ||
} | ||
rootToSlotMap.get(root)[slotName] = slot; | ||
// Adds a node to a slot. In other words, adds default content to a slot. It | ||
// ensures that if the slot doesn't have any assigned nodes yet, that the node | ||
// is actually displayed, otherwise it's just registered as child content. | ||
function addNodeToSlot(slot, node, insertBefore) { | ||
var isInDefaultMode = slot.assignedNodes().length === 0; | ||
registerNode(slot, node, insertBefore, function (eachNode) { | ||
if (isInDefaultMode) { | ||
slot.__insertBefore(eachNode, insertBefore !== undefined ? insertBefore : null); | ||
} | ||
}); | ||
} | ||
if (!slotToRootMap.has(slot)) { | ||
slotToRootMap.set(slot, root); | ||
// Removes a node from a slot (default content). It ensures that if the slot | ||
// doesn't have any assigned nodes yet, that the node is actually removed, | ||
// otherwise it's just unregistered. | ||
function removeNodeFromSlot(slot, node) { | ||
var isInDefaultMode = slot.assignedNodes().length === 0; | ||
unregisterNode(slot, node, function () { | ||
if (isInDefaultMode) { | ||
slot.__removeChild(node); | ||
} | ||
}); | ||
} | ||
eachChildNode(rootToHostMap.get(root), function (eachNode) { | ||
if (!eachNode.assignedSlot && slotName === getSlotNameFromNode(eachNode)) { | ||
slotNodeIntoSlot(slot, eachNode); | ||
} | ||
}); | ||
} | ||
function removeNodeFromNode(host, node) { | ||
unregisterNode(host, node, function () { | ||
host.__removeChild(node); | ||
}); | ||
} | ||
function addNodeToRoot(root, node, insertBefore) { | ||
eachNodeOrFragmentNodes(node, function (child) { | ||
if (isSlotNode(child)) { | ||
addSlotToRoot(root, child); | ||
} else { | ||
var slotNodes = findSlots(child); | ||
if (slotNodes) { | ||
var slotNodesLen = slotNodes.length; | ||
for (var a = 0; a < slotNodesLen; a++) { | ||
addSlotToRoot(root, slotNodes[a]); | ||
} | ||
function removeNodeFromHost(host, node) { | ||
unregisterNode(host, node, function () { | ||
slotNodeFromSlot(node); | ||
}); | ||
} | ||
function removeSlotFromRoot(root, node) { | ||
var assignedNodes = Array.prototype.slice.call(node.assignedNodes()); | ||
assignedNodes.forEach(slotNodeFromSlot); | ||
delete rootToSlotMap.get(root)[getSlotNameFromSlot(node)]; | ||
slotToRootMap.delete(node); | ||
} | ||
function removeNodeFromRoot(root, node) { | ||
unregisterNode(root, node, function () { | ||
if (isSlotNode(node)) { | ||
removeSlotFromRoot(root, node); | ||
} else { | ||
var nodes = findSlots(node); | ||
if (nodes) { | ||
for (var a = 0; a < nodes.length; a++) { | ||
removeSlotFromRoot(root, nodes[a]); | ||
} | ||
} | ||
}); | ||
addNodeToNode(root, node, insertBefore); | ||
} | ||
} | ||
root.__removeChild(node); | ||
}); | ||
} | ||
// Adds a node to a slot. In other words, adds default content to a slot. It | ||
// ensures that if the slot doesn't have any assigned nodes yet, that the node | ||
// is actually displayed, otherwise it's just registered as child content. | ||
function addNodeToSlot(slot, node, insertBefore) { | ||
var isInDefaultMode = slot.assignedNodes().length === 0; | ||
registerNode(slot, node, insertBefore, function (eachNode) { | ||
if (isInDefaultMode) { | ||
slot.__insertBefore(eachNode, insertBefore !== undefined ? insertBefore : null); | ||
} | ||
}); | ||
// TODO terribly inefficient | ||
function getRootNode(host) { | ||
if (isRootNode(host)) { | ||
return host; | ||
} | ||
// Removes a node from a slot (default content). It ensures that if the slot | ||
// doesn't have any assigned nodes yet, that the node is actually removed, | ||
// otherwise it's just unregistered. | ||
function removeNodeFromSlot(slot, node) { | ||
var isInDefaultMode = slot.assignedNodes().length === 0; | ||
unregisterNode(slot, node, function () { | ||
if (isInDefaultMode) { | ||
slot.__removeChild(node); | ||
} | ||
}); | ||
if (!host.parentNode) { | ||
return; | ||
} | ||
function removeNodeFromNode(host, node) { | ||
unregisterNode(host, node, function () { | ||
host.__removeChild(node); | ||
}); | ||
} | ||
return getRootNode(host.parentNode); | ||
} | ||
function removeNodeFromHost(host, node) { | ||
unregisterNode(host, node, function () { | ||
slotNodeFromSlot(node); | ||
}); | ||
} | ||
function appendChildOrInsertBefore(host, newNode, refNode) { | ||
var nodeType = getNodeType(host); | ||
var parentNode = newNode.parentNode; | ||
var rootNode = getRootNode(host); | ||
function removeSlotFromRoot(root, node) { | ||
var assignedNodes = Array.prototype.slice.call(node.assignedNodes()); | ||
assignedNodes.forEach(slotNodeFromSlot); | ||
delete rootToSlotMap.get(root)[getSlotNameFromSlot(node)]; | ||
slotToRootMap.delete(node); | ||
// Ensure childNodes is patched so we can manually update it for WebKit. | ||
if (!canPatchNativeAccessors && !Array.isArray(host.childNodes)) { | ||
staticProp(host, 'childNodes', pseudoArrayToArray(host.childNodes)); | ||
} | ||
function removeNodeFromRoot(root, node) { | ||
unregisterNode(root, node, function () { | ||
if (isSlotNode(node)) { | ||
removeSlotFromRoot(root, node); | ||
} else { | ||
var nodes = findSlots(node); | ||
if (nodes) { | ||
for (var a = 0; a < nodes.length; a++) { | ||
removeSlotFromRoot(root, nodes[a]); | ||
} | ||
} | ||
} | ||
root.__removeChild(node); | ||
}); | ||
if (rootNode && getNodeType(newNode) === 'slot') { | ||
addSlotToRoot(rootNode, newNode); | ||
} | ||
// TODO terribly inefficient | ||
function getRootNode(host) { | ||
if (isRootNode(host)) { | ||
return host; | ||
// If we append a child to a host, the host tells the shadow root to distribute | ||
// it. If the root decides it doesn't need to be distributed, it is never | ||
// removed from the old parent because in polyfill land we store a reference | ||
// to the node but we don't move it. Due to that, we must explicitly remove the | ||
// node from its old parent. | ||
if (parentNode && getNodeType(parentNode) === 'host') { | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(newNode, null); | ||
} else { | ||
staticProp(newNode, 'parentNode', null); | ||
} | ||
} | ||
if (!host.parentNode) { | ||
return; | ||
if (nodeType === 'node') { | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(newNode, host); | ||
return host.__insertBefore(newNode, refNode !== undefined ? refNode : null); | ||
} | ||
return getRootNode(host.parentNode); | ||
return addNodeToNode(host, newNode, refNode); | ||
} | ||
function appendChildOrInsertBefore(host, newNode, refNode) { | ||
var nodeType = getNodeType(host); | ||
var parentNode = newNode.parentNode; | ||
var rootNode = getRootNode(host); | ||
if (nodeType === 'slot') { | ||
return addNodeToSlot(host, newNode, refNode); | ||
} | ||
// Ensure childNodes is patched so we can manually update it for WebKit. | ||
if (!canPatchNativeAccessors && !Array.isArray(host.childNodes)) { | ||
staticProp(host, 'childNodes', pseudoArrayToArray(host.childNodes)); | ||
} | ||
if (nodeType === 'host') { | ||
return addNodeToHost(host, newNode, refNode); | ||
} | ||
if (rootNode && getNodeType(newNode) === 'slot') { | ||
addSlotToRoot(rootNode, newNode); | ||
} | ||
if (nodeType === 'root') { | ||
return addNodeToRoot(host, newNode, refNode); | ||
} | ||
} | ||
// If we append a child to a host, the host tells the shadow root to distribute | ||
// it. If the root decides it doesn't need to be distributed, it is never | ||
// removed from the old parent because in polyfill land we store a reference | ||
// to the node but we don't move it. Due to that, we must explicitly remove the | ||
// node from its old parent. | ||
if (parentNode && getNodeType(parentNode) === 'host') { | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(newNode, null); | ||
} else { | ||
staticProp(newNode, 'parentNode', null); | ||
} | ||
function syncSlotChildNodes(node) { | ||
if (canPatchNativeAccessors && getNodeType(node) === 'slot' && node.__childNodes.length !== node.childNodes.length) { | ||
while (node.hasChildNodes()) { | ||
node.removeChild(node.firstChild); | ||
} | ||
if (nodeType === 'node') { | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(newNode, host); | ||
return host.__insertBefore(newNode, refNode !== undefined ? refNode : null); | ||
} | ||
forEach.call(node.__childNodes, function (child) { | ||
return node.appendChild(child); | ||
}); | ||
} | ||
} | ||
return addNodeToNode(host, newNode, refNode); | ||
var members = { | ||
// For testing purposes. | ||
____assignedNodes: { | ||
get: function get() { | ||
return this.______assignedNodes || (this.______assignedNodes = []); | ||
} | ||
}, | ||
if (nodeType === 'slot') { | ||
return addNodeToSlot(host, newNode, refNode); | ||
// For testing purposes. | ||
____isInFallbackMode: { | ||
get: function get() { | ||
return this.assignedNodes().length === 0; | ||
} | ||
}, | ||
if (nodeType === 'host') { | ||
return addNodeToHost(host, newNode, refNode); | ||
____slotChangeListeners: { | ||
get: function get() { | ||
if (typeof this.______slotChangeListeners === 'undefined') { | ||
this.______slotChangeListeners = 0; | ||
} | ||
return this.______slotChangeListeners; | ||
}, | ||
set: function set(value) { | ||
this.______slotChangeListeners = value; | ||
} | ||
if (nodeType === 'root') { | ||
return addNodeToRoot(host, newNode, refNode); | ||
}, | ||
____triggerSlotChangeEvent: { | ||
value: debounce(function callback() { | ||
if (this.____slotChangeListeners) { | ||
this.dispatchEvent(new CustomEvent('slotchange', { | ||
bubbles: false, | ||
cancelable: false | ||
})); | ||
} | ||
}) | ||
}, | ||
addEventListener: { | ||
value: function value(name, func, opts) { | ||
if (name === 'slotchange' && isSlotNode(this)) { | ||
this.____slotChangeListeners++; | ||
} | ||
return this.__addEventListener(name, func, opts); | ||
} | ||
} | ||
}, | ||
appendChild: { | ||
value: function value(newNode) { | ||
appendChildOrInsertBefore(this, newNode); | ||
return newNode; | ||
} | ||
}, | ||
assignedSlot: { | ||
get: function get() { | ||
var slot = nodeToSlotMap.get(this); | ||
function syncSlotChildNodes(node) { | ||
if (canPatchNativeAccessors && getNodeType(node) === 'slot' && node.__childNodes.length !== node.childNodes.length) { | ||
while (node.hasChildNodes()) { | ||
node.removeChild(node.firstChild); | ||
if (!slot) { | ||
return null; | ||
} | ||
forEach.call(node.__childNodes, function (child) { | ||
return node.appendChild(child); | ||
}); | ||
var root = slotToRootMap.get(slot); | ||
var host = rootToHostMap.get(root); | ||
var mode = hostToModeMap.get(host); | ||
return mode === 'open' ? slot : null; | ||
} | ||
} | ||
}, | ||
attachShadow: { | ||
value: function value(opts) { | ||
var _this = this; | ||
var members = { | ||
// For testing purposes. | ||
____assignedNodes: { | ||
get: function get() { | ||
return this.______assignedNodes || (this.______assignedNodes = []); | ||
var mode = opts && opts.mode; | ||
if (mode !== 'closed' && mode !== 'open') { | ||
throw new Error('You must specify { mode } as "open" or "closed" to attachShadow().'); | ||
} | ||
}, | ||
// For testing purposes. | ||
____isInFallbackMode: { | ||
get: function get() { | ||
return this.assignedNodes().length === 0; | ||
// Return the existing shadow root if it exists. | ||
var existingShadowRoot = hostToRootMap.get(this); | ||
if (existingShadowRoot) { | ||
return existingShadowRoot; | ||
} | ||
}, | ||
____slotChangeListeners: { | ||
get: function get() { | ||
if (typeof this.______slotChangeListeners === 'undefined') { | ||
this.______slotChangeListeners = 0; | ||
} | ||
return this.______slotChangeListeners; | ||
}, | ||
set: function set(value) { | ||
this.______slotChangeListeners = value; | ||
} | ||
}, | ||
____triggerSlotChangeEvent: { | ||
value: debounce(function callback() { | ||
if (this.____slotChangeListeners) { | ||
this.dispatchEvent(new CustomEvent('slotchange', { | ||
bubbles: false, | ||
cancelable: false | ||
})); | ||
} | ||
}) | ||
}, | ||
addEventListener: { | ||
value: function value(name, func, opts) { | ||
if (name === 'slotchange' && isSlotNode(this)) { | ||
this.____slotChangeListeners++; | ||
} | ||
return this.__addEventListener(name, func, opts); | ||
} | ||
}, | ||
appendChild: { | ||
value: function value(newNode) { | ||
appendChildOrInsertBefore(this, newNode); | ||
return newNode; | ||
} | ||
}, | ||
assignedSlot: { | ||
get: function get() { | ||
var slot = nodeToSlotMap.get(this); | ||
var lightNodes = makeLikeNodeList([].slice.call(this.childNodes)); | ||
var shadowRoot = document.createElement(opts.polyfillShadowRootTagName || defaultShadowRootTagName); | ||
if (!slot) { | ||
return null; | ||
} | ||
// Host and shadow root data. | ||
hostToModeMap.set(this, mode); | ||
hostToRootMap.set(this, shadowRoot); | ||
rootToHostMap.set(shadowRoot, this); | ||
rootToSlotMap.set(shadowRoot, {}); | ||
var root = slotToRootMap.get(slot); | ||
var host = rootToHostMap.get(root); | ||
var mode = hostToModeMap.get(host); | ||
return mode === 'open' ? slot : null; | ||
if (canPatchNativeAccessors) { | ||
nodeToChildNodesMap.set(this, lightNodes); | ||
} else { | ||
staticProp(this, 'childNodes', lightNodes); | ||
} | ||
}, | ||
attachShadow: { | ||
value: function value(opts) { | ||
var _this = this; | ||
var mode = opts && opts.mode; | ||
if (mode !== 'closed' && mode !== 'open') { | ||
throw new Error('You must specify { mode } as "open" or "closed" to attachShadow().'); | ||
} | ||
// Process light DOM. | ||
lightNodes.forEach(function (node) { | ||
// Existing children should be removed from being displayed, but still | ||
// appear to be child nodes. This is how light DOM works; they're still | ||
// child nodes but not in the composed DOM yet as there won't be any | ||
// slots for them to go into. | ||
_this.__removeChild(node); | ||
// Return the existing shadow root if it exists. | ||
var existingShadowRoot = hostToRootMap.get(this); | ||
if (existingShadowRoot) { | ||
return existingShadowRoot; | ||
} | ||
var lightNodes = makeLikeNodeList([].slice.call(this.childNodes)); | ||
var shadowRoot = document.createElement(opts.polyfillShadowRootTagName || defaultShadowRootTagName); | ||
// Host and shadow root data. | ||
hostToModeMap.set(this, mode); | ||
hostToRootMap.set(this, shadowRoot); | ||
rootToHostMap.set(shadowRoot, this); | ||
rootToSlotMap.set(shadowRoot, {}); | ||
// We must register the parentNode here as this has the potential to | ||
// become out of sync if the node is moved before being slotted. | ||
if (canPatchNativeAccessors) { | ||
nodeToChildNodesMap.set(this, lightNodes); | ||
nodeToParentNodeMap.set(node, _this); | ||
} else { | ||
staticProp(this, 'childNodes', lightNodes); | ||
staticProp(node, 'parentNode', _this); | ||
} | ||
}); | ||
// Process light DOM. | ||
lightNodes.forEach(function (node) { | ||
// Existing children should be removed from being displayed, but still | ||
// appear to be child nodes. This is how light DOM works; they're still | ||
// child nodes but not in the composed DOM yet as there won't be any | ||
// slots for them to go into. | ||
_this.__removeChild(node); | ||
// The shadow root is actually the only child of the host. | ||
return this.__appendChild(shadowRoot); | ||
} | ||
}, | ||
childElementCount: { | ||
get: function get() { | ||
return this.children.length; | ||
} | ||
}, | ||
childNodes: { | ||
get: function get() { | ||
if (canPatchNativeAccessors && getNodeType(this) === 'node') { | ||
return this.__childNodes; | ||
} | ||
var childNodes = nodeToChildNodesMap.get(this); | ||
// We must register the parentNode here as this has the potential to | ||
// become out of sync if the node is moved before being slotted. | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(node, _this); | ||
} else { | ||
staticProp(node, 'parentNode', _this); | ||
} | ||
}); | ||
if (!childNodes) { | ||
nodeToChildNodesMap.set(this, childNodes = makeLikeNodeList([])); | ||
} | ||
// The shadow root is actually the only child of the host. | ||
return this.__appendChild(shadowRoot); | ||
} | ||
}, | ||
childElementCount: { | ||
get: function get() { | ||
return this.children.length; | ||
} | ||
}, | ||
childNodes: { | ||
get: function get() { | ||
if (canPatchNativeAccessors && getNodeType(this) === 'node') { | ||
return this.__childNodes; | ||
return childNodes; | ||
} | ||
}, | ||
children: { | ||
get: function get() { | ||
var chs = []; | ||
eachChildNode(this, function (node) { | ||
if (node.nodeType === 1) { | ||
chs.push(node); | ||
} | ||
var childNodes = nodeToChildNodesMap.get(this); | ||
}); | ||
return makeLikeNodeList(chs); | ||
} | ||
}, | ||
firstChild: { | ||
get: function get() { | ||
return this.childNodes[0] || null; | ||
} | ||
}, | ||
firstElementChild: { | ||
get: function get() { | ||
return this.children[0] || null; | ||
} | ||
}, | ||
assignedNodes: { | ||
value: function value() { | ||
if (isSlotNode(this)) { | ||
var assigned = assignedToSlotMap.get(this); | ||
if (!childNodes) { | ||
nodeToChildNodesMap.set(this, childNodes = makeLikeNodeList([])); | ||
if (!assigned) { | ||
assignedToSlotMap.set(this, assigned = []); | ||
} | ||
return childNodes; | ||
return assigned; | ||
} | ||
}, | ||
children: { | ||
get: function get() { | ||
var chs = []; | ||
eachChildNode(this, function (node) { | ||
if (node.nodeType === 1) { | ||
chs.push(node); | ||
} | ||
}); | ||
return makeLikeNodeList(chs); | ||
} | ||
}, | ||
firstChild: { | ||
get: function get() { | ||
return this.childNodes[0] || null; | ||
} | ||
}, | ||
firstElementChild: { | ||
get: function get() { | ||
return this.children[0] || null; | ||
} | ||
}, | ||
assignedNodes: { | ||
value: function value() { | ||
if (isSlotNode(this)) { | ||
var assigned = assignedToSlotMap.get(this); | ||
} | ||
}, | ||
hasChildNodes: { | ||
value: function value() { | ||
return this.childNodes.length > 0; | ||
} | ||
}, | ||
innerHTML: { | ||
get: function get() { | ||
var innerHTML = ''; | ||
if (!assigned) { | ||
assignedToSlotMap.set(this, assigned = []); | ||
} | ||
var getHtmlNodeOuterHtml = function getHtmlNodeOuterHtml(node) { | ||
return node.outerHTML; | ||
}; | ||
var getOuterHtmlByNodeType = { | ||
1: getHtmlNodeOuterHtml, | ||
3: getEscapedTextContent, | ||
8: getCommentNodeOuterHtml | ||
}; | ||
return assigned; | ||
} | ||
} | ||
eachChildNode(this, function (node) { | ||
var getOuterHtml = getOuterHtmlByNodeType[node.nodeType] || getHtmlNodeOuterHtml; | ||
innerHTML += getOuterHtml(node); | ||
}); | ||
return innerHTML; | ||
}, | ||
hasChildNodes: { | ||
value: function value() { | ||
return this.childNodes.length > 0; | ||
set: function set(innerHTML) { | ||
var parsed = parse(innerHTML); | ||
while (this.hasChildNodes()) { | ||
this.removeChild(this.firstChild); | ||
} | ||
}, | ||
innerHTML: { | ||
get: function get() { | ||
var innerHTML = ''; | ||
var getHtmlNodeOuterHtml = function getHtmlNodeOuterHtml(node) { | ||
return node.outerHTML; | ||
}; | ||
var getOuterHtmlByNodeType = { | ||
1: getHtmlNodeOuterHtml, | ||
3: getEscapedTextContent, | ||
8: getCommentNodeOuterHtml | ||
}; | ||
// when we are doing this: root.innerHTML = "<slot><div></div></slot>"; | ||
// slot.__childNodes is out of sync with slot.childNodes. | ||
// to fix it we have to manually remove and insert them | ||
var slots = findSlots(parsed); | ||
forEach.call(slots, function (slot) { | ||
return syncSlotChildNodes(slot); | ||
}); | ||
eachChildNode(this, function (node) { | ||
var getOuterHtml = getOuterHtmlByNodeType[node.nodeType] || getHtmlNodeOuterHtml; | ||
innerHTML += getOuterHtml(node); | ||
}); | ||
return innerHTML; | ||
}, | ||
set: function set(innerHTML) { | ||
var parsed = parse(innerHTML); | ||
while (parsed.hasChildNodes()) { | ||
var firstChild = parsed.firstChild; | ||
while (this.hasChildNodes()) { | ||
this.removeChild(this.firstChild); | ||
} | ||
// When we polyfill everything on HTMLElement.prototype, we overwrite | ||
// properties. This makes it so that parentNode reports null even though | ||
// it's actually a parent of the HTML parser. For this reason, | ||
// cleanNode() won't work and we must manually remove it from the | ||
// parser before it is moved to the host just in case it's added as a | ||
// light node but not assigned to a slot. | ||
parsed.removeChild(firstChild); | ||
// when we are doing this: root.innerHTML = "<slot><div></div></slot>"; | ||
// slot.__childNodes is out of sync with slot.childNodes. | ||
// to fix it we have to manually remove and insert them | ||
var slots = findSlots(parsed); | ||
forEach.call(slots, function (slot) { | ||
return syncSlotChildNodes(slot); | ||
}); | ||
this.appendChild(firstChild); | ||
} | ||
} | ||
}, | ||
insertBefore: { | ||
value: function value(newNode, refNode) { | ||
appendChildOrInsertBefore(this, newNode, refNode); | ||
while (parsed.hasChildNodes()) { | ||
var firstChild = parsed.firstChild; | ||
return newNode; | ||
} | ||
}, | ||
lastChild: { | ||
get: function get() { | ||
var ch = this.childNodes; | ||
return ch[ch.length - 1] || null; | ||
} | ||
}, | ||
lastElementChild: { | ||
get: function get() { | ||
var ch = this.children; | ||
return ch[ch.length - 1] || null; | ||
} | ||
}, | ||
name: { | ||
get: function get() { | ||
return this.getAttribute('name'); | ||
}, | ||
set: function set(name) { | ||
var oldName = this.name; | ||
var ret = this.__setAttribute('name', name); | ||
// When we polyfill everything on HTMLElement.prototype, we overwrite | ||
// properties. This makes it so that parentNode reports null even though | ||
// it's actually a parent of the HTML parser. For this reason, | ||
// cleanNode() won't work and we must manually remove it from the | ||
// parser before it is moved to the host just in case it's added as a | ||
// light node but not assigned to a slot. | ||
parsed.removeChild(firstChild); | ||
this.appendChild(firstChild); | ||
} | ||
if (name === oldName) { | ||
return ret; | ||
} | ||
}, | ||
insertBefore: { | ||
value: function value(newNode, refNode) { | ||
appendChildOrInsertBefore(this, newNode, refNode); | ||
return newNode; | ||
if (!isSlotNode(this)) { | ||
return ret; | ||
} | ||
}, | ||
lastChild: { | ||
get: function get() { | ||
var ch = this.childNodes; | ||
return ch[ch.length - 1] || null; | ||
var root = slotToRootMap.get(this); | ||
if (root) { | ||
removeSlotFromRoot(root, this); | ||
addSlotToRoot(root, this); | ||
} | ||
return ret; | ||
} | ||
}, | ||
nextSibling: { | ||
get: function get() { | ||
var host = this; | ||
return eachChildNode(this.parentNode, function (child, index, nodes) { | ||
if (host === child) { | ||
return nodes[index + 1] || null; | ||
} | ||
}); | ||
} | ||
}, | ||
nextElementSibling: { | ||
get: function get() { | ||
var host = this; | ||
var found = void 0; | ||
return eachChildNode(this.parentNode, function (child) { | ||
if (found && child.nodeType === 1) { | ||
return child; | ||
} | ||
if (host === child) { | ||
found = true; | ||
} | ||
}); | ||
} | ||
}, | ||
outerHTML: { | ||
get: function get() { | ||
var name = this.tagName.toLowerCase(); | ||
var attributes = Array.prototype.slice.call(this.attributes).map(function (attr) { | ||
return ' ' + attr.name + (attr.value ? '="' + attr.value + '"' : ''); | ||
}).join(''); | ||
return '<' + name + attributes + '>' + this.innerHTML + '</' + name + '>'; | ||
}, | ||
lastElementChild: { | ||
get: function get() { | ||
var ch = this.children; | ||
return ch[ch.length - 1] || null; | ||
} | ||
}, | ||
name: { | ||
get: function get() { | ||
return this.getAttribute('name'); | ||
}, | ||
set: function set(name) { | ||
var oldName = this.name; | ||
var ret = this.__setAttribute('name', name); | ||
if (name === oldName) { | ||
return ret; | ||
set: function set(outerHTML) { | ||
if (this.parentNode) { | ||
var parsed = parse(outerHTML); | ||
this.parentNode.replaceChild(parsed.firstChild, this); | ||
} else if (canPatchNativeAccessors) { | ||
this.__outerHTML = outerHTML; // this will throw a native error; | ||
} else { | ||
throw new Error('Failed to set the \'outerHTML\' property on \'Element\': This element has no parent node.'); | ||
} | ||
if (!isSlotNode(this)) { | ||
return ret; | ||
} | ||
}, | ||
parentElement: { | ||
get: function get() { | ||
return findClosest(this.parentNode, function (node) { | ||
return node.nodeType === 1; | ||
}); | ||
} | ||
}, | ||
parentNode: { | ||
get: function get() { | ||
return nodeToParentNodeMap.get(this) || this.__parentNode || null; | ||
} | ||
}, | ||
previousSibling: { | ||
get: function get() { | ||
var host = this; | ||
return eachChildNode(this.parentNode, function (child, index, nodes) { | ||
if (host === child) { | ||
return nodes[index - 1] || null; | ||
} | ||
var root = slotToRootMap.get(this); | ||
if (root) { | ||
removeSlotFromRoot(root, this); | ||
addSlotToRoot(root, this); | ||
}); | ||
} | ||
}, | ||
previousElementSibling: { | ||
get: function get() { | ||
var host = this; | ||
var found = void 0; | ||
return eachChildNode(this.parentNode, function (child) { | ||
if (found && host === child) { | ||
return found; | ||
} | ||
return ret; | ||
} | ||
}, | ||
nextSibling: { | ||
get: function get() { | ||
var host = this; | ||
return eachChildNode(this.parentNode, function (child, index, nodes) { | ||
if (host === child) { | ||
return nodes[index + 1] || null; | ||
if (child.nodeType === 1) { | ||
found = child; | ||
} | ||
}); | ||
} | ||
}, | ||
removeChild: { | ||
value: function value(refNode) { | ||
var nodeType = getNodeType(this); | ||
switch (nodeType) { | ||
case 'node': | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(refNode, null); | ||
return this.__removeChild(refNode); | ||
} | ||
}); | ||
removeNodeFromNode(this, refNode); | ||
break; | ||
case 'slot': | ||
removeNodeFromSlot(this, refNode); | ||
break; | ||
case 'host': | ||
removeNodeFromHost(this, refNode); | ||
break; | ||
case 'root': | ||
removeNodeFromRoot(this, refNode); | ||
break; | ||
default: | ||
break; | ||
} | ||
}, | ||
nextElementSibling: { | ||
get: function get() { | ||
var host = this; | ||
var found = void 0; | ||
return eachChildNode(this.parentNode, function (child) { | ||
if (found && child.nodeType === 1) { | ||
return child; | ||
} | ||
if (host === child) { | ||
found = true; | ||
} | ||
}); | ||
return refNode; | ||
} | ||
}, | ||
removeEventListener: { | ||
value: function value(name, func, opts) { | ||
if (name === 'slotchange' && this.____slotChangeListeners && isSlotNode(this)) { | ||
this.____slotChangeListeners--; | ||
} | ||
}, | ||
outerHTML: { | ||
get: function get() { | ||
var name = this.tagName.toLowerCase(); | ||
var attributes = Array.prototype.slice.call(this.attributes).map(function (attr) { | ||
return ' ' + attr.name + (attr.value ? '="' + attr.value + '"' : ''); | ||
}).join(''); | ||
return '<' + name + attributes + '>' + this.innerHTML + '</' + name + '>'; | ||
}, | ||
set: function set(outerHTML) { | ||
if (this.parentNode) { | ||
var parsed = parse(outerHTML); | ||
this.parentNode.replaceChild(parsed.firstChild, this); | ||
} else if (canPatchNativeAccessors) { | ||
this.__outerHTML = outerHTML; // this will throw a native error; | ||
} else { | ||
throw new Error('Failed to set the \'outerHTML\' property on \'Element\': This element has no parent node.'); | ||
} | ||
return this.__removeEventListener(name, func, opts); | ||
} | ||
}, | ||
replaceChild: { | ||
value: function value(newNode, refNode) { | ||
this.insertBefore(newNode, refNode); | ||
return this.removeChild(refNode); | ||
} | ||
}, | ||
setAttribute: { | ||
value: function value(attrName, attrValue) { | ||
if (attrName === 'slot') { | ||
this[attrName] = attrValue; | ||
} | ||
}, | ||
parentElement: { | ||
get: function get() { | ||
return findClosest(this.parentNode, function (node) { | ||
return node.nodeType === 1; | ||
}); | ||
} | ||
}, | ||
parentNode: { | ||
get: function get() { | ||
return nodeToParentNodeMap.get(this) || this.__parentNode || null; | ||
} | ||
}, | ||
previousSibling: { | ||
get: function get() { | ||
var host = this; | ||
return eachChildNode(this.parentNode, function (child, index, nodes) { | ||
if (host === child) { | ||
return nodes[index - 1] || null; | ||
} | ||
}); | ||
} | ||
}, | ||
previousElementSibling: { | ||
get: function get() { | ||
var host = this; | ||
var found = void 0; | ||
return eachChildNode(this.parentNode, function (child) { | ||
if (found && host === child) { | ||
return found; | ||
} | ||
if (child.nodeType === 1) { | ||
found = child; | ||
} | ||
}); | ||
} | ||
}, | ||
removeChild: { | ||
value: function value(refNode) { | ||
var nodeType = getNodeType(this); | ||
switch (nodeType) { | ||
case 'node': | ||
if (canPatchNativeAccessors) { | ||
nodeToParentNodeMap.set(refNode, null); | ||
return this.__removeChild(refNode); | ||
} | ||
removeNodeFromNode(this, refNode); | ||
break; | ||
case 'slot': | ||
removeNodeFromSlot(this, refNode); | ||
break; | ||
case 'host': | ||
removeNodeFromHost(this, refNode); | ||
break; | ||
case 'root': | ||
removeNodeFromRoot(this, refNode); | ||
break; | ||
default: | ||
break; | ||
} | ||
return refNode; | ||
} | ||
}, | ||
removeEventListener: { | ||
value: function value(name, func, opts) { | ||
if (name === 'slotchange' && this.____slotChangeListeners && isSlotNode(this)) { | ||
this.____slotChangeListeners--; | ||
} | ||
return this.__removeEventListener(name, func, opts); | ||
} | ||
}, | ||
replaceChild: { | ||
value: function value(newNode, refNode) { | ||
this.insertBefore(newNode, refNode); | ||
return this.removeChild(refNode); | ||
} | ||
}, | ||
setAttribute: { | ||
value: function value(attrName, attrValue) { | ||
if (attrName === 'slot') { | ||
if (isSlotNode(this)) { | ||
if (attrName === 'name') { | ||
this[attrName] = attrValue; | ||
} | ||
if (isSlotNode(this)) { | ||
if (attrName === 'name') { | ||
this[attrName] = attrValue; | ||
} | ||
} | ||
return this.__setAttribute(attrName, attrValue); | ||
} | ||
return this.__setAttribute(attrName, attrValue); | ||
} | ||
}, | ||
shadowRoot: { | ||
get: function get() { | ||
return hostToModeMap.get(this) === 'open' ? hostToRootMap.get(this) : null; | ||
} | ||
}, | ||
slot: { | ||
get: function get() { | ||
return this.getAttribute('slot'); | ||
}, | ||
shadowRoot: { | ||
get: function get() { | ||
return hostToModeMap.get(this) === 'open' ? hostToRootMap.get(this) : null; | ||
set: function set(name) { | ||
var oldName = this.name; | ||
var ret = this.__setAttribute('slot', name); | ||
if (oldName === name) { | ||
return ret; | ||
} | ||
}, | ||
slot: { | ||
get: function get() { | ||
return this.getAttribute('slot'); | ||
}, | ||
set: function set(name) { | ||
var oldName = this.name; | ||
var ret = this.__setAttribute('slot', name); | ||
if (oldName === name) { | ||
return ret; | ||
} | ||
var slot = nodeToSlotMap.get(this); | ||
var root = slot && slotToRootMap.get(slot); | ||
var host = root && rootToHostMap.get(root); | ||
var slot = nodeToSlotMap.get(this); | ||
var root = slot && slotToRootMap.get(slot); | ||
var host = root && rootToHostMap.get(root); | ||
if (host) { | ||
removeNodeFromHost(host, this); | ||
addNodeToHost(host, this); | ||
if (host) { | ||
removeNodeFromHost(host, this); | ||
addNodeToHost(host, this); | ||
} | ||
return ret; | ||
} | ||
}, | ||
textContent: { | ||
get: function get() { | ||
var textContent = ''; | ||
eachChildNode(this, function (node) { | ||
if (node.nodeType !== Node.COMMENT_NODE) { | ||
textContent += node.textContent; | ||
} | ||
return ret; | ||
} | ||
}); | ||
return textContent; | ||
}, | ||
textContent: { | ||
get: function get() { | ||
var textContent = ''; | ||
eachChildNode(this, function (node) { | ||
if (node.nodeType !== Node.COMMENT_NODE) { | ||
textContent += node.textContent; | ||
} | ||
}); | ||
return textContent; | ||
}, | ||
set: function set(textContent) { | ||
while (this.hasChildNodes()) { | ||
this.removeChild(this.firstChild); | ||
} | ||
if (!textContent) { | ||
return; | ||
} | ||
this.appendChild(document.createTextNode(textContent)); | ||
set: function set(textContent) { | ||
while (this.hasChildNodes()) { | ||
this.removeChild(this.firstChild); | ||
} | ||
if (!textContent) { | ||
return; | ||
} | ||
this.appendChild(document.createTextNode(textContent)); | ||
} | ||
}; | ||
} | ||
}; | ||
if (shadowDomV1) { | ||
// then we should probably not be loading this | ||
} else if (shadowDomV0) { | ||
v0(); | ||
} else { | ||
(function () { | ||
var commProto = Comment.prototype; | ||
var elementProto = HTMLElement.prototype; | ||
var svgProto = SVGElement.prototype; | ||
var textProto = Text.prototype; | ||
var textNode = document.createTextNode(''); | ||
var commNode = document.createComment(''); | ||
if (shadowDomV1) { | ||
// then we should probably not be loading this | ||
} else if (shadowDomV0) { | ||
v0(); | ||
} else { | ||
(function () { | ||
var commProto = Comment.prototype; | ||
var elementProto = HTMLElement.prototype; | ||
var svgProto = SVGElement.prototype; | ||
var textProto = Text.prototype; | ||
var textNode = document.createTextNode(''); | ||
var commNode = document.createComment(''); | ||
Object.keys(members).forEach(function (memberName) { | ||
var memberProperty = members[memberName]; | ||
Object.keys(members).forEach(function (memberName) { | ||
var memberProperty = members[memberName]; | ||
// All properties should be configurable. | ||
memberProperty.configurable = true; | ||
// All properties should be configurable. | ||
memberProperty.configurable = true; | ||
// Applying to the data properties only since we can't have writable accessor properties. | ||
if (memberProperty.hasOwnProperty('value')) { | ||
// eslint-disable-line no-prototype-builtins | ||
memberProperty.writable = true; | ||
} | ||
// Applying to the data properties only since we can't have writable accessor properties. | ||
if (memberProperty.hasOwnProperty('value')) { | ||
// eslint-disable-line no-prototype-builtins | ||
memberProperty.writable = true; | ||
} | ||
// Polyfill as much as we can and work around WebKit in other areas. | ||
if (canPatchNativeAccessors || polyfillAtRuntime.indexOf(memberName) === -1) { | ||
var nativeDescriptor = getPropertyDescriptor(elementProto, memberName); | ||
var nativeTextDescriptor = getPropertyDescriptor(textProto, memberName); | ||
var nativeCommDescriptor = getPropertyDescriptor(commProto, memberName); | ||
var shouldOverrideInTextNode = memberName in textNode && doNotOverridePropertiesInTextNodes.indexOf(memberName) === -1 || ~defineInTextNodes.indexOf(memberName); | ||
var shouldOverrideInCommentNode = memberName in commNode && doNotOverridePropertiesInCommNodes.indexOf(memberName) === -1 || ~defineInCommNodes.indexOf(memberName); | ||
var nativeMemberName = '__' + memberName; | ||
// Polyfill as much as we can and work around WebKit in other areas. | ||
if (canPatchNativeAccessors || polyfillAtRuntime.indexOf(memberName) === -1) { | ||
var nativeDescriptor = getPropertyDescriptor(elementProto, memberName); | ||
var nativeTextDescriptor = getPropertyDescriptor(textProto, memberName); | ||
var nativeCommDescriptor = getPropertyDescriptor(commProto, memberName); | ||
var shouldOverrideInTextNode = memberName in textNode && doNotOverridePropertiesInTextNodes.indexOf(memberName) === -1 || ~defineInTextNodes.indexOf(memberName); | ||
var shouldOverrideInCommentNode = memberName in commNode && doNotOverridePropertiesInCommNodes.indexOf(memberName) === -1 || ~defineInCommNodes.indexOf(memberName); | ||
var nativeMemberName = '__' + memberName; | ||
Object.defineProperty(elementProto, memberName, memberProperty); | ||
Object.defineProperty(svgProto, memberName, memberProperty); | ||
Object.defineProperty(elementProto, memberName, memberProperty); | ||
Object.defineProperty(svgProto, memberName, memberProperty); | ||
if (nativeDescriptor) { | ||
Object.defineProperty(elementProto, nativeMemberName, nativeDescriptor); | ||
Object.defineProperty(svgProto, nativeMemberName, nativeDescriptor); | ||
} | ||
if (nativeDescriptor) { | ||
Object.defineProperty(elementProto, nativeMemberName, nativeDescriptor); | ||
Object.defineProperty(svgProto, nativeMemberName, nativeDescriptor); | ||
} | ||
if (shouldOverrideInTextNode) { | ||
Object.defineProperty(textProto, memberName, memberProperty); | ||
} | ||
if (shouldOverrideInTextNode) { | ||
Object.defineProperty(textProto, memberName, memberProperty); | ||
} | ||
if (shouldOverrideInTextNode && nativeTextDescriptor) { | ||
Object.defineProperty(textProto, nativeMemberName, nativeTextDescriptor); | ||
} | ||
if (shouldOverrideInTextNode && nativeTextDescriptor) { | ||
Object.defineProperty(textProto, nativeMemberName, nativeTextDescriptor); | ||
} | ||
if (shouldOverrideInCommentNode) { | ||
Object.defineProperty(commProto, memberName, memberProperty); | ||
} | ||
if (shouldOverrideInCommentNode) { | ||
Object.defineProperty(commProto, memberName, memberProperty); | ||
} | ||
if (shouldOverrideInCommentNode && nativeCommDescriptor) { | ||
Object.defineProperty(commProto, nativeMemberName, nativeCommDescriptor); | ||
} | ||
if (shouldOverrideInCommentNode && nativeCommDescriptor) { | ||
Object.defineProperty(commProto, nativeMemberName, nativeCommDescriptor); | ||
} | ||
}); | ||
})(); | ||
} | ||
} | ||
}); | ||
})(); | ||
} | ||
exports['default'] = version; | ||
exports['default'] = version; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
})); | ||
}))); | ||
//# sourceMappingURL=index.js.map |
@@ -10,6 +10,6 @@ { | ||
"test/watch": "sk-tests-watch", | ||
"test/perf": "karma start --single-run --perf", | ||
"lint": "eslint . --ext .js,.jsx --format 'node_modules/eslint-friendly-formatter'", | ||
"test/perf": "sk-tests -- --perf", | ||
"lint": "sk-lint", | ||
"prepublish": "sk-bundle", | ||
"commit": "npm run lint && git cz" | ||
"commit": "sk-commit" | ||
}, | ||
@@ -40,6 +40,5 @@ "repository": { | ||
"eslint": "^3.2.2", | ||
"eslint-friendly-formatter": "^2.0.6", | ||
"eslint-plugin-react": "^6.0.0", | ||
"precommit-hook": "^3.0.0", | ||
"skatejs-build": "^7.1.0" | ||
"skatejs-build": "^7.3.0" | ||
}, | ||
@@ -59,3 +58,3 @@ "dependencies": { | ||
], | ||
"version": "1.1.1" | ||
"version": "1.2.0" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
5
-16.67%4028
0.05%504284
-2.48%