melody-idom
Advanced tools
Comparing version 1.2.0-21.2 to 1.2.0-alpha.3
1865
lib/index.js
@@ -1,1864 +0,1 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var _debounce = _interopDefault(require('lodash/debounce')); | ||
var options = {}; | ||
/** | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
var parentToChildren = new WeakMap(); | ||
var childToParent = new WeakMap(); | ||
function link(parent, child) { | ||
childToParent.set(child, parent); | ||
var children = getChildren(parent); | ||
children.push(child); | ||
} | ||
function unlink(node) { | ||
parentToChildren.delete(node); | ||
childToParent.delete(node); | ||
} | ||
function getChildren(parent) { | ||
var children = parentToChildren.get(parent); | ||
if (!children) { | ||
children = []; | ||
parentToChildren.set(parent, children); | ||
} | ||
return children; | ||
} | ||
function getParent(child) { | ||
return childToParent.get(child); | ||
} | ||
function reset(node) { | ||
parentToChildren.set(node, []); | ||
} | ||
/** | ||
* Copyright 2015 The Incremental DOM Authors. | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** | ||
* A cached reference to the create function. | ||
*/ | ||
function Blank() {} | ||
Blank.prototype = Object.create(null); | ||
/** | ||
* Creates an map object without a prototype. | ||
* @return {!Object} | ||
*/ | ||
var createMap = function createMap() { | ||
return new Blank(); | ||
}; | ||
var unmountComponent = function unmountComponent(comp) { | ||
getChildren(comp).forEach(unmountComponent); | ||
unlink(comp); | ||
drop(comp); | ||
var data = comp.el ? comp.el['__incrementalDOMData'] : null; | ||
if (options.beforeUnmount) { | ||
options.beforeUnmount(comp); | ||
} | ||
if (mountedComponents.has(comp)) { | ||
comp.componentWillUnmount(); | ||
mountedComponents.delete(comp); | ||
} | ||
if (data && data.componentInstance) { | ||
data.componentInstance = null; | ||
} | ||
comp.el = null; | ||
}; | ||
var documentRange = null; | ||
function parseHTML(htmlString) { | ||
if (!documentRange) { | ||
documentRange = document.createRange(); | ||
documentRange.selectNode(document.body); | ||
} | ||
return documentRange.createContextualFragment(htmlString.trim()).childNodes; | ||
} | ||
/** | ||
* Copyright 2015 The Incremental DOM Authors. | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** | ||
* Keeps track of information needed to perform diffs for a given DOM node. | ||
* @param {!string} nodeName | ||
* @param {?string=} key | ||
* @constructor | ||
*/ | ||
function NodeData(nodeName, key) { | ||
/** | ||
* The attributes and their values. | ||
* @const {!Object<string, *>} | ||
*/ | ||
this.attrs = createMap(); | ||
/** | ||
* An array of attribute name/value pairs, used for quickly diffing the | ||
* incomming attributes to see if the DOM node's attributes need to be | ||
* updated. | ||
* @const {Array<*>} | ||
*/ | ||
this.attrsArr = []; | ||
/** | ||
* The incoming attributes for this Node, before they are updated. | ||
* @const {!Object<string, *>} | ||
*/ | ||
this.newAttrs = createMap(); | ||
/** | ||
* The key used to identify this node, used to preserve DOM nodes when they | ||
* move within their parent. | ||
* @const | ||
*/ | ||
this.key = key; | ||
/** | ||
* Keeps track of children within this node by their key. | ||
* {?Object<string, !Element>} | ||
*/ | ||
this.keyMap = createMap(); | ||
/** | ||
* Whether or not the keyMap is currently valid. | ||
* {boolean} | ||
*/ | ||
this.keyMapValid = true; | ||
/** | ||
* Whether or not the statics for the given node have already been applied. | ||
* | ||
* @type {boolean} | ||
*/ | ||
this.staticsApplied = false; | ||
/** | ||
* Whether or not the associated node is or contains a focused Element. | ||
* @type {boolean} | ||
*/ | ||
this.focused = false; | ||
/** | ||
* The node name for this node. | ||
* @const {string} | ||
*/ | ||
this.nodeName = nodeName; | ||
/** | ||
* @type {?string} | ||
*/ | ||
this.text = null; | ||
/** | ||
* The component instance associated with this element. | ||
* @type {Object} | ||
*/ | ||
this.componentInstance = null; | ||
/** | ||
* The length of the children in this element. | ||
* This value is only calculated for raw elements. | ||
* @type {number} | ||
*/ | ||
this.childLength = 0; | ||
} | ||
/** | ||
* Initializes a NodeData object for a Node. | ||
* | ||
* @param {Node} node The node to initialize data for. | ||
* @param {string} nodeName The node name of node. | ||
* @param {?string=} key The key that identifies the node. | ||
* @return {!NodeData} The newly initialized data object | ||
*/ | ||
var initData = function initData(node, nodeName, key) { | ||
var data = new NodeData(nodeName, key); | ||
node['__incrementalDOMData'] = data; | ||
return data; | ||
}; | ||
/** | ||
* Retrieves the NodeData object for a Node, creating it if necessary. | ||
* | ||
* @param {Node} node The node to retrieve the data for. | ||
* @return {!NodeData} The NodeData for this Node. | ||
*/ | ||
var getData = function getData(node) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (!node) { | ||
throw new Error("Can't getData for non-existing node."); | ||
} | ||
} | ||
importNode(node); | ||
return node['__incrementalDOMData']; | ||
}; | ||
var importNode = function importNode(node) { | ||
var stack = [node]; | ||
while (stack.length) { | ||
var node_1 = stack.pop(); | ||
if (node_1['__incrementalDOMData']) { | ||
continue; | ||
} | ||
var isElement = node_1 instanceof Element; | ||
var nodeName = isElement ? node_1.localName : node_1.nodeName; | ||
var key = isElement ? node_1.getAttribute('key') : null; | ||
var data = initData(node_1, nodeName, key); | ||
if (key) { | ||
var parentData = node_1.parentNode && node_1.parentNode['__incrementalDOMData']; | ||
if (parentData) { | ||
parentData.keyMap[key] = node_1; | ||
} | ||
} | ||
if (isElement) { | ||
var attributes = node_1.attributes; | ||
var attrs = data.attrs; | ||
var newAttrs = data.newAttrs; | ||
var attrsArr = data.attrsArr; | ||
for (var i = 0; i < attributes.length; i += 1) { | ||
var attr = attributes[i]; | ||
var name_1 = attr.name; | ||
var value = attr.value; | ||
attrs[name_1] = value; | ||
newAttrs[name_1] = undefined; | ||
attrsArr.push(name_1); | ||
attrsArr.push(value); | ||
} | ||
for (var child = node_1.firstChild; child; child = child.nextSibling) { | ||
stack.push(child); | ||
} | ||
} else if (node_1.nodeType === 3) { | ||
data.text = node_1.data; | ||
} | ||
} | ||
}; | ||
/** | ||
* Copyright 2015 The Incremental DOM Authors. | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** | ||
* Gets the namespace to create an element (of a given tag) in. | ||
* @param {string} tag The tag to get the namespace for. | ||
* @param {?Node} parent | ||
* @return {?string} The namespace to create the tag in. | ||
*/ | ||
var getNamespaceForTag = function getNamespaceForTag(tag, parent) { | ||
if (tag === 'svg') { | ||
return 'http://www.w3.org/2000/svg'; | ||
} | ||
if (getData(parent).nodeName === 'foreignObject') { | ||
return null; | ||
} | ||
return parent.namespaceURI; | ||
}; | ||
/** | ||
* Creates an Element. | ||
* @param {Document} doc The document with which to create the Element. | ||
* @param {?Node} parent | ||
* @param {string} tag The tag for the Element. | ||
* @param {?string=} key A key to identify the Element. | ||
* @param {?Array<*>=} statics An array of attribute name/value pairs of the | ||
* static attributes for the Element. | ||
* @return {!Element} | ||
*/ | ||
var createElement = function createElement(doc, parent, tag, key) { | ||
var namespace = getNamespaceForTag(tag, parent); | ||
var el; | ||
if (namespace) { | ||
el = doc.createElementNS(namespace, tag); | ||
} else { | ||
el = doc.createElement(tag); | ||
} | ||
initData(el, tag, key); | ||
return el; | ||
}; | ||
/** | ||
* Creates a Text Node. | ||
* @param {Document} doc The document with which to create the Element. | ||
* @return {!Text} | ||
*/ | ||
var createText = function createText(doc) { | ||
var node = doc.createTextNode(''); | ||
initData(node, '#text', null); | ||
return node; | ||
}; | ||
var createRaw = function createRaw(doc, html) { | ||
var children = parseHTML(html); | ||
if (!children.length) { | ||
var frag = document.createElement('div'); | ||
frag.appendChild(doc.createTextNode('')); | ||
children = frag.childNodes; | ||
} | ||
var data = initData(children[0], '#raw', null); | ||
data.text = html; | ||
data.childLength = children.length; | ||
return children; | ||
}; | ||
/** | ||
* Copyright 2015 The Incremental DOM Authors. | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** | ||
* Keeps track whether or not we are in an attributes declaration (after | ||
* elementOpenStart, but before elementOpenEnd). | ||
* @type {boolean} | ||
*/ | ||
var inAttributes = false; | ||
/** | ||
* Keeps track whether or not we are in an element that should not have its | ||
* children cleared. | ||
* @type {boolean} | ||
*/ | ||
var inSkip = false; | ||
/** | ||
* Makes sure that there is a current patch context. | ||
* @param {*} context | ||
*/ | ||
var assertInPatch = function assertInPatch(functionName, context) { | ||
if (!context) { | ||
throw new Error('Cannot call ' + functionName + '() unless in patch'); | ||
} | ||
}; | ||
/** | ||
* Makes sure that a patch closes every node that it opened. | ||
* @param {?Node} openElement | ||
* @param {!Node|!DocumentFragment} root | ||
*/ | ||
var assertNoUnclosedTags = function assertNoUnclosedTags(openElement, root) { | ||
if (openElement === root) { | ||
return; | ||
} | ||
var currentElement = openElement; | ||
var openTags = []; | ||
while (currentElement && currentElement !== root) { | ||
openTags.push(currentElement.nodeName.toLowerCase()); | ||
currentElement = currentElement.parentNode; | ||
} | ||
throw new Error('One or more tags were not closed:\n' + openTags.join('\n')); | ||
}; | ||
/** | ||
* Makes sure that the caller is not where attributes are expected. | ||
* @param {string} functionName | ||
*/ | ||
var assertNotInAttributes = function assertNotInAttributes(functionName) { | ||
if (inAttributes) { | ||
throw new Error(functionName + '() can not be called between ' + 'elementOpenStart() and elementOpenEnd().'); | ||
} | ||
}; | ||
/** | ||
* Makes sure that the caller is not inside an element that has declared skip. | ||
* @param {string} functionName | ||
*/ | ||
var assertNotInSkip = function assertNotInSkip(functionName) { | ||
if (inSkip) { | ||
throw new Error(functionName + '() may not be called inside an element ' + 'that has called skip().'); | ||
} | ||
}; | ||
/** | ||
* Makes sure that the caller is where attributes are expected. | ||
* @param {string} functionName | ||
*/ | ||
var assertInAttributes = function assertInAttributes(functionName) { | ||
if (!inAttributes) { | ||
throw new Error(functionName + '() can only be called after calling ' + 'elementOpenStart().'); | ||
} | ||
}; | ||
/** | ||
* Makes sure the patch closes virtual attributes call | ||
*/ | ||
var assertVirtualAttributesClosed = function assertVirtualAttributesClosed() { | ||
if (inAttributes) { | ||
throw new Error('elementOpenEnd() must be called after calling ' + 'elementOpenStart().'); | ||
} | ||
}; | ||
/** | ||
* Makes sure that tags are correctly nested. | ||
* @param {string} nodeName | ||
* @param {string} tag | ||
*/ | ||
var assertCloseMatchesOpenTag = function assertCloseMatchesOpenTag(nodeName, tag) { | ||
if (nodeName !== tag) { | ||
throw new Error('Received a call to close "' + tag + '" but "' + nodeName + '" was open.'); | ||
} | ||
}; | ||
/** | ||
* Makes sure that no children elements have been declared yet in the current | ||
* element. | ||
* @param {string} functionName | ||
* @param {?Node} previousNode | ||
*/ | ||
var assertNoChildrenDeclaredYet = function assertNoChildrenDeclaredYet(functionName, previousNode) { | ||
if (previousNode !== null) { | ||
throw new Error(functionName + '() must come before any child ' + 'declarations inside the current element.'); | ||
} | ||
}; | ||
/** | ||
* Checks that a call to patchOuter actually patched the element. | ||
* @param {?Node} node The node requested to be patched. | ||
* @param {?Node} previousNode The previousNode after the patch. | ||
*/ | ||
var assertPatchElementNoExtras = function assertPatchElementNoExtras(startNode, currentNode, expectedNextNode, expectedPrevNode) { | ||
var wasUpdated = currentNode.nextSibling === expectedNextNode && currentNode.previousSibling === expectedPrevNode; | ||
var wasChanged = currentNode.nextSibling === startNode.nextSibling && currentNode.previousSibling === expectedPrevNode; | ||
var wasRemoved = currentNode === startNode; | ||
if (!wasUpdated && !wasChanged && !wasRemoved) { | ||
throw new Error('There must be exactly one top level call corresponding ' + 'to the patched element.'); | ||
} | ||
}; | ||
/** | ||
* Updates the state of being in an attribute declaration. | ||
* @param {boolean} value | ||
* @return {boolean} the previous value. | ||
*/ | ||
var setInAttributes = function setInAttributes(value) { | ||
var previous = inAttributes; | ||
inAttributes = value; | ||
return previous; | ||
}; | ||
/** | ||
* Updates the state of being in a skip element. | ||
* @param {boolean} value | ||
* @return {boolean} the previous value. | ||
*/ | ||
var setInSkip = function setInSkip(value) { | ||
var previous = inSkip; | ||
inSkip = value; | ||
return previous; | ||
}; | ||
/** | ||
* Copyright 2015 The Incremental DOM Authors. | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** | ||
* @param {!Node} node | ||
* @return {boolean} True if the node the root of a document, false otherwise. | ||
*/ | ||
var isDocumentRoot = function isDocumentRoot(node) { | ||
// For ShadowRoots, check if they are a DocumentFragment instead of if they | ||
// are a ShadowRoot so that this can work in 'use strict' if ShadowRoots are | ||
// not supported. | ||
return node instanceof Document || node instanceof DocumentFragment; | ||
}; | ||
/** | ||
* @param {!Node} node The node to start at, inclusive. | ||
* @param {?Node} root The root ancestor to get until, exclusive. | ||
* @return {!Array<!Node>} The ancestry of DOM nodes. | ||
*/ | ||
var getAncestry = function getAncestry(node, root) { | ||
var ancestry = []; | ||
var cur = node; | ||
while (cur !== root) { | ||
ancestry.push(cur); | ||
cur = cur.parentNode; | ||
} | ||
return ancestry; | ||
}; | ||
/** | ||
* @param {!Node} node | ||
* @return {!Node} The root node of the DOM tree that contains node. | ||
*/ | ||
var getRoot = function getRoot(node) { | ||
var cur = node; | ||
var prev = cur; | ||
while (cur) { | ||
prev = cur; | ||
cur = cur.parentNode; | ||
} | ||
return prev; | ||
}; | ||
/** | ||
* @param {!Node} node The node to get the activeElement for. | ||
* @return {?Element} The activeElement in the Document or ShadowRoot | ||
* corresponding to node, if present. | ||
*/ | ||
var getActiveElement = function getActiveElement(node) { | ||
var root = getRoot(node); | ||
return isDocumentRoot(root) ? root.activeElement : null; | ||
}; | ||
/** | ||
* Function that checks whether some element is contained inside a node. This function | ||
* has a fallback implementation for cases where Node.prototype.contains is | ||
* not implemented (e.g. IE11 for SVGElements). | ||
* @param {!Node} node The node that should be parent of elm. | ||
* @param {?Element} elm The element that should be child of elm. | ||
* @return {Boolean} whether or not elm is contained within node. | ||
*/ | ||
var nodeContainsElement = function nodeContainsElement(node, elm) { | ||
if (node.contains) { | ||
return node.contains(elm); | ||
} | ||
while (elm && elm !== node) { | ||
elm = elm.parentNode; | ||
} | ||
return elm === node; | ||
}; | ||
/** | ||
* Gets the path of nodes that contain the focused node in the same document as | ||
* a reference node, up until the root. | ||
* @param {!Node} node The reference node to get the activeElement for. | ||
* @param {?Node} root The root to get the focused path until. | ||
* @return {!Array<Node>} | ||
*/ | ||
var getFocusedPath = function getFocusedPath(node, root) { | ||
var activeElement = getActiveElement(node); | ||
if (!activeElement || !nodeContainsElement(node, activeElement)) { | ||
return []; | ||
} | ||
return getAncestry(activeElement, root); | ||
}; | ||
/** | ||
* Like insertBefore, but instead instead of moving the desired node, instead | ||
* moves all the other nodes after. | ||
* @param {?Node} parentNode | ||
* @param {!Node} node | ||
* @param {?Node} referenceNode | ||
*/ | ||
var moveBefore = function moveBefore(parentNode, node, referenceNode) { | ||
var insertReferenceNode = node.nextSibling; | ||
var cur = referenceNode; | ||
while (cur && cur !== node) { | ||
var next = cur.nextSibling; | ||
parentNode.insertBefore(cur, insertReferenceNode); | ||
cur = next; | ||
} | ||
}; | ||
/** | ||
* Copyright 2015 The Incremental DOM Authors. | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** @type {?Node} */ | ||
var currentNode; | ||
/** @type {?Node} */ | ||
var currentParent; | ||
/** @type {?Document} */ | ||
var doc; | ||
var componentKey = null; | ||
var currentComponent = null; | ||
var deletedNodes = null; | ||
var markFocused = function markFocused(focusPath, focused) { | ||
for (var i = 0; i < focusPath.length; i += 1) { | ||
getData(focusPath[i]).focused = focused; | ||
} | ||
}; | ||
var patchFactory = function patchFactory(run) { | ||
return function (node, fn, data) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (!node) { | ||
throw new Error('Patch invoked without an element.'); | ||
} | ||
} | ||
var prevDeletedNodes = deletedNodes; | ||
var prevDoc = doc; | ||
var prevCurrentNode = currentNode; | ||
var prevCurrentParent = currentParent; | ||
var prevCurrentComponent = currentComponent; | ||
var previousInAttribute = false; | ||
var previousInSkip = false; | ||
deletedNodes = []; | ||
doc = node.ownerDocument; | ||
currentParent = node.parentNode; | ||
if (process.env.NODE_ENV !== 'production') { | ||
previousInAttribute = setInAttributes(false); | ||
previousInSkip = setInSkip(false); | ||
} | ||
var focusPath = getFocusedPath(node, currentParent); | ||
markFocused(focusPath, true); | ||
var retVal; | ||
if (process.env.NODE_ENV !== 'production') { | ||
try { | ||
retVal = run(node, fn, data); | ||
} catch (e) { | ||
// reset context | ||
deletedNodes = prevDeletedNodes; | ||
doc = prevDoc; | ||
currentNode = prevCurrentNode; | ||
currentParent = prevCurrentParent; | ||
currentComponent = prevCurrentComponent; | ||
// rethrow the error | ||
throw e; | ||
} | ||
} else { | ||
retVal = run(node, fn, data); | ||
} | ||
markFocused(focusPath, false); | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertVirtualAttributesClosed(); | ||
setInAttributes(previousInAttribute); | ||
setInSkip(previousInSkip); | ||
} | ||
var i, len; | ||
for (i = 0, len = deletedNodes.length; i < len; i++) { | ||
nodeDeleted(deletedNodes[i]); | ||
} | ||
// reset context | ||
deletedNodes = prevDeletedNodes; | ||
doc = prevDoc; | ||
currentNode = prevCurrentNode; | ||
currentParent = prevCurrentParent; | ||
currentComponent = prevCurrentComponent; | ||
return retVal; | ||
}; | ||
}; | ||
function nodeDeleted(node) { | ||
var data = getData(node); | ||
if (data.attrs.ref && data.attrs.ref.disposer) { | ||
data.attrs.ref.disposer.unsubscribe(); | ||
data.attrs.ref = null; | ||
} | ||
if (data.componentInstance) { | ||
unmountComponent(data.componentInstance); | ||
} | ||
// not an ideal solution but we can eventually move it | ||
// towards a scheduler (perhaps `requestIdleCallback` if we notice | ||
// that there are actual issues with this) | ||
// Chose a recursive solution here to avoid unnecessary memory usage | ||
var child = node.firstChild; | ||
while (child) { | ||
nodeDeleted(child); | ||
child = child.nextSibling; | ||
} | ||
} | ||
var patchInner = patchFactory(function (node, fn, data) { | ||
currentNode = node; | ||
enterNode(); | ||
fn(data); | ||
exitNode(); | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertNoUnclosedTags(currentNode, node); | ||
} | ||
return node; | ||
}); | ||
var patchOuter = patchFactory(function (node, fn, data) { | ||
var startNode = { nextSibling: node }; | ||
var expectedNextNode = null; | ||
var expectedPrevNode = null; | ||
if (process.env.NODE_ENV !== 'production') { | ||
expectedNextNode = node.nextSibling; | ||
expectedPrevNode = node.previousSibling; | ||
} | ||
currentNode = startNode; | ||
fn(data); | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertPatchElementNoExtras(startNode, currentNode, expectedNextNode, expectedPrevNode); | ||
} | ||
if (node !== currentNode && node.parentNode) { | ||
removeChild(currentParent, node, getData(currentParent).keyMap); | ||
} | ||
return startNode === currentNode ? null : currentNode; | ||
}); | ||
/** | ||
* Checks whether or not the current node matches the specified nodeName and | ||
* key. | ||
* | ||
* @param {?string} nodeName The nodeName for this node. | ||
* @param {?string=} key An optional key that identifies a node. | ||
* @return {boolean} True if the node matches, false otherwise. | ||
*/ | ||
var matches = function matches(matchNode, nodeName, key) { | ||
var data = getData(matchNode); | ||
// Key check is done using double equals as we want to treat a null key the | ||
// same as undefined. This should be okay as the only values allowed are | ||
// strings, null and undefined so the == semantics are not too weird. | ||
// templates rendered on the server side may not have keys at all while melody templates | ||
// always will have them so we reconcile the dom in those cases. | ||
if (nodeName === data.nodeName) { | ||
if (key == data.key) { | ||
return true; | ||
} | ||
// exisiting DOM element does not have a key | ||
// which means we can hook onto it freely | ||
if (!data.key) { | ||
data.key = key; | ||
// but we'll need to update the parent element | ||
var parentKeys = currentParent && getData(currentParent).keyMap; | ||
if (parentKeys) { | ||
parentKeys[key] = matchNode; | ||
} | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
/** | ||
* Aligns the virtual Element definition with the actual DOM, moving the | ||
* corresponding DOM node to the correct location or creating it if necessary. | ||
* @param {string} nodeName For an Element, this should be a valid tag string. | ||
* For a Text, this should be #text. | ||
* @param {?string=} key The key used to identify this element. | ||
* @param {?Array<*>=} statics For an Element, this should be an array of | ||
* name-value pairs. | ||
*/ | ||
var alignWithDOM = function alignWithDOM(nodeName, key) { | ||
if (currentNode && matches(currentNode, nodeName, key)) { | ||
return; | ||
} | ||
var parentData = getData(currentParent); | ||
var currentNodeData = currentNode && getData(currentNode); | ||
var keyMap = parentData.keyMap; | ||
var fromKeyMap = false; | ||
var node; | ||
var componentInstance = null; | ||
// Check to see if the node has moved within the parent. | ||
if (key) { | ||
var keyNode = keyMap[key]; | ||
if (keyNode) { | ||
if (matches(keyNode, nodeName, key)) { | ||
fromKeyMap = true; | ||
node = keyNode; | ||
} else if (keyNode === currentNode) { | ||
var keyNodeData = getData(keyNode); | ||
// if (keyNodeData.componentInstance === currentComponent) { | ||
if (keyNodeData.componentInstance) { | ||
componentInstance = keyNodeData.componentInstance; | ||
keyNodeData.componentInstance = null; | ||
} else { | ||
deletedNodes.push(keyNode); | ||
} | ||
} else { | ||
removeChild(currentParent, keyNode, keyMap); | ||
} | ||
} else if (currentNode && currentNode.nodeType === 3 && currentNode.data.trim() === '') { | ||
// special handling here to ignore empty text nodes if the one after it is what we're actually looking for | ||
// this reduces a lot of special handling for server side rendered content. | ||
if (currentNode.nextSibling && matches(currentNode.nextSibling, nodeName, key)) { | ||
node = currentNode.nextSibling; | ||
} | ||
} | ||
} | ||
// Create the node if it doesn't exist. | ||
if (!node) { | ||
if (nodeName === '#text') { | ||
node = createText(doc); | ||
} else { | ||
node = createElement(doc, currentParent, nodeName, key); | ||
} | ||
if (key) { | ||
keyMap[key] = node; | ||
} | ||
} | ||
if (componentInstance) { | ||
getData(node).componentInstance = componentInstance; | ||
componentInstance.el = node; | ||
} | ||
// Re-order the node into the right position, preserving focus if either | ||
// node or currentNode are focused by making sure that they are not detached | ||
// from the DOM. | ||
if (getData(node).focused) { | ||
// move everything else before the node. | ||
moveBefore(currentParent, node, currentNode); | ||
} else if (!(fromKeyMap && !node.parentNode) && currentNodeData && currentNodeData.key && !currentNodeData.focused) { | ||
// Remove the currentNode, which can always be added back since we hold a | ||
// reference through the keyMap. This prevents a large number of moves when | ||
// a keyed item is removed or moved backwards in the DOM. | ||
currentParent.replaceChild(node, currentNode); | ||
parentData.keyMapValid = false; | ||
} else if (currentNode && currentNode.nextSibling === node && currentNode.nodeType === 3 && currentNode.data.trim() === '') { | ||
// if the empty text node handling above was successful, we simply remove the skipped text node | ||
currentParent.removeChild(currentNode); | ||
} else { | ||
currentParent.insertBefore(node, currentNode); | ||
} | ||
currentNode = node; | ||
}; | ||
var removeChild = function removeChild(node, child, keyMap) { | ||
node.removeChild(child); | ||
deletedNodes.push(child); | ||
var key = getData(child).key; | ||
if (key) { | ||
delete keyMap[key]; | ||
} | ||
}; | ||
/** | ||
* Clears out any unvisited Nodes, as the corresponding virtual element | ||
* functions were never called for them. | ||
*/ | ||
var clearUnvisitedDOM = function clearUnvisitedDOM() { | ||
var node = currentParent; | ||
var data = getData(node); | ||
var keyMap = data.keyMap; | ||
var keyMapValid = data.keyMapValid; | ||
var child = node.lastChild; | ||
var key; | ||
if (child === currentNode && keyMapValid) { | ||
return; | ||
} | ||
while (child && child !== currentNode) { | ||
removeChild(node, child, keyMap); | ||
child = node.lastChild; | ||
} | ||
// Clean the keyMap, removing any unusued keys. | ||
if (!keyMapValid) { | ||
for (key in keyMap) { | ||
child = keyMap[key]; | ||
if (child.parentNode !== node) { | ||
deletedNodes.push(child); | ||
delete keyMap[key]; | ||
} | ||
} | ||
data.keyMapValid = true; | ||
} | ||
}; | ||
/** | ||
* Changes to the first child of the current node. | ||
*/ | ||
var enterNode = function enterNode() { | ||
currentParent = currentNode; | ||
currentNode = null; | ||
}; | ||
/** | ||
* Changes to the next sibling of the current node. | ||
*/ | ||
var nextNode = function nextNode() { | ||
currentNode = getNextNode(); | ||
}; | ||
var getNextNode = function getNextNode() { | ||
if (currentNode) { | ||
return currentNode.nextSibling; | ||
} else { | ||
return currentParent.firstChild; | ||
} | ||
}; | ||
/** | ||
* Changes to the parent of the current node, removing any unvisited children. | ||
*/ | ||
var exitNode = function exitNode() { | ||
clearUnvisitedDOM(); | ||
currentNode = currentParent; | ||
currentParent = currentParent.parentNode; | ||
}; | ||
var updateComponent = function updateComponent(comp) { | ||
var data = getData(comp.el); | ||
var parentComponent = currentComponent; | ||
componentKey = data.key; | ||
reset(comp); | ||
currentComponent = comp; | ||
comp.render(); | ||
currentComponent = parentComponent; | ||
}; | ||
var scheduleComponent = function scheduleComponent(Component, key, props, el) { | ||
var comp; | ||
if (el) { | ||
// we've already seen this component | ||
var data = getData(el); | ||
comp = data.componentInstance; | ||
if (!comp) { | ||
// but apparently we didn't have a component instance so far | ||
// most likely we're mounting a server side rendered DOM | ||
comp = typeof Component === 'function' ? new Component() : Component; | ||
comp.el = el; | ||
data.componentInstance = comp; | ||
} | ||
// Q: Do we even want to support this in the future? | ||
// if (typeof Component === 'function' && !(comp instanceof Component)) { | ||
// unmountComponent(comp); | ||
// comp = null; | ||
// } | ||
elementOpen(data.nodeName, key); | ||
skip(); | ||
elementClose(); | ||
} else { | ||
// unknown component | ||
if (typeof Component === 'function') { | ||
comp = new Component(); | ||
} else { | ||
comp = Component; | ||
} | ||
elementOpen('m-placeholder', key); | ||
skip(); | ||
comp.el = elementClose(); | ||
getData(comp.el).componentInstance = comp; | ||
} | ||
if (currentComponent) { | ||
link(currentComponent, comp); | ||
} | ||
return comp.apply(props); | ||
}; | ||
var component = function component(Component, key, props) { | ||
var el = getData(currentParent).keyMap[key]; | ||
return scheduleComponent(Component, key, props, el); | ||
}; | ||
var getCurrentComponent = function getCurrentComponent() { | ||
return currentComponent; | ||
}; | ||
var mount = function mount(element, Component, props) { | ||
var data = getData(element); | ||
var key = data && data.key; | ||
var comp = data.componentInstance; | ||
var isComponentInstance = typeof Component !== 'function'; | ||
// if the existing component is not an instance of the specified component type | ||
// then we just unmount the existing one and proceed as if none ever existed | ||
if (comp && !isComponentInstance && !(comp instanceof Component)) { | ||
unmountComponent(comp); | ||
} | ||
return scheduleComponent(Component, key, props, element); | ||
}; | ||
/** | ||
* Makes sure that the current node is an Element with a matching tagName and | ||
* key. | ||
* | ||
* @param {string} tag The element's tag. | ||
* @param {?string=} key The key used to identify this element. This can be an | ||
* empty string, but performance may be better if a unique value is used | ||
* when iterating over an array of items. | ||
* @return {!Element} The corresponding Element. | ||
*/ | ||
var elementOpen = function elementOpen(tag, key) { | ||
nextNode(); | ||
alignWithDOM(tag, componentKey || key); | ||
componentKey = null; | ||
enterNode(); | ||
return currentParent; | ||
}; | ||
/** | ||
* Closes the currently open Element, removing any unvisited children if | ||
* necessary. | ||
* | ||
* @return {!Element} The corresponding Element. | ||
*/ | ||
var elementClose = function elementClose() { | ||
if (process.env.NODE_ENV !== 'production') { | ||
setInSkip(false); | ||
} | ||
exitNode(); | ||
return currentNode; | ||
}; | ||
/** | ||
* Makes sure the current node is a Text node and creates a Text node if it is | ||
* not. | ||
* | ||
* @return {!Text} The corresponding Text Node. | ||
*/ | ||
var text = function text() { | ||
nextNode(); | ||
alignWithDOM('#text', null); | ||
return currentNode; | ||
}; | ||
/** | ||
* Gets the current Element being patched. | ||
* @return {!Element} | ||
*/ | ||
var currentElement = function currentElement() { | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertInPatch('currentElement', deletedNodes); | ||
assertNotInAttributes('currentElement'); | ||
} | ||
return currentParent; | ||
}; | ||
/** | ||
* Skips the children in a subtree, allowing an Element to be closed without | ||
* clearing out the children. | ||
*/ | ||
var skip = function skip() { | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertNoChildrenDeclaredYet('skip', currentNode); | ||
setInSkip(true); | ||
} | ||
currentNode = currentParent.lastChild; | ||
}; | ||
var skipNode = nextNode; | ||
var insertRawHtml = function insertRawHtml(html) { | ||
var children = createRaw(doc, html); | ||
var node = doc.createDocumentFragment(), | ||
lastChild = children[children.length - 1]; | ||
while (children.length) { | ||
node.appendChild(children[0]); | ||
} | ||
currentParent.insertBefore(node, currentNode); | ||
currentNode = lastChild; | ||
}; | ||
var raw = function raw(html) { | ||
nextNode(); | ||
if (currentNode && matches(currentNode, '#raw', null)) { | ||
// patch node | ||
var data = getData(currentNode), | ||
remainingSiblingCount = data.childLength - 1; | ||
if (data.text !== html) { | ||
// if the text is not the same as before, we'll have some work to do | ||
insertRawHtml(html); | ||
// remove the remaining siblings of the old child | ||
if (data.childLength > 1) { | ||
while (remainingSiblingCount--) { | ||
currentParent.removeChild(currentNode.nextSibling); | ||
} | ||
} | ||
} else if (remainingSiblingCount) { | ||
// still the same text so just jump over the remaining siblings | ||
while (remainingSiblingCount--) { | ||
currentNode = currentNode.nextSibling; | ||
} | ||
} | ||
} else { | ||
// insert raw html | ||
insertRawHtml(html); | ||
} | ||
return currentNode; | ||
}; | ||
var supportsPassiveListeners = false; | ||
/* istanbul ignore next */ | ||
document.createElement('div').addEventListener('test', function () {}, { | ||
get passive() { | ||
supportsPassiveListeners = true; | ||
return false; | ||
} | ||
}); | ||
var BUSY_FRAME_LENGTH = 3; | ||
var IDLE_FRAME_LENGTH = 30; | ||
var MESSAGE_KEY = '__melodyPrioritize_' + Math.random().toString(36).slice(2); | ||
var mountedComponents = new WeakSet(); | ||
// by default we assume that we have to deal with a busy frame | ||
// we can afford a little more time if we can detect that the | ||
// browser is currently idle (=not scrolling) | ||
var idealFrameLength = IDLE_FRAME_LENGTH; | ||
var scrollListenerAttached = false; | ||
var prioritizationRequested = false; | ||
var prioritizationDisabled = !!options.experimentalSyncDeepRendering; | ||
var NIL = { component: null, next: null }; | ||
var queue = NIL; | ||
function isEmpty() { | ||
return queue === NIL; | ||
} | ||
function addToQueue(component$$1) { | ||
if (queue !== NIL) { | ||
// before we schedule this update, we should check a few things first | ||
for (var head = queue; head !== NIL; head = head.next) { | ||
// 1: Has this component already been scheduled for an update? | ||
if (head.component === component$$1) { | ||
// if so: we don't need | ||
return; | ||
} | ||
if (component$$1.type !== 'streaming') { | ||
// 2: Is the parent of this component already scheduled for an update? | ||
if (getParent(component$$1) === head.component) { | ||
// if so: we don't need to do anything | ||
return; | ||
} | ||
// 3: Is the component a parent of a node within the queue? | ||
if (getParent(head.component) === component$$1) { | ||
// if so: replace the child with its parent | ||
head.component = component$$1; | ||
return; | ||
} | ||
} | ||
if (head.next === NIL) { | ||
// insert the new node at the end of the list | ||
// we probably want to adjust that once we know how | ||
// to prioritize an update | ||
head.next = { | ||
component: component$$1, | ||
next: NIL | ||
}; | ||
break; | ||
} | ||
} | ||
} else { | ||
queue = { | ||
component: component$$1, | ||
next: NIL | ||
}; | ||
} | ||
} | ||
function drop(component$$1) { | ||
if (queue === NIL) { | ||
return; | ||
} | ||
if (queue.component === component$$1) { | ||
queue = queue.next; | ||
} | ||
var prev = queue; | ||
for (var head = queue.next; head && head !== NIL; head = head.next) { | ||
// is the component (or one of its parents) in the queue the removed component? | ||
var comp = head.component; | ||
do { | ||
if (comp === component$$1) { | ||
// if so: drop it | ||
prev.next = head.next; | ||
head = prev; | ||
break; | ||
} | ||
comp = getParent(comp); | ||
} while (comp); | ||
prev = head; | ||
} | ||
} | ||
function getPriority(node) { | ||
if (!node.component.el) { | ||
return -1; | ||
} | ||
var windowHeight = window.innerHeight || document.documentElement.clientHeight; | ||
var _a = node.component.el.getBoundingClientRect(), | ||
top = _a.top, | ||
bottom = _a.bottom; | ||
// is fully visible | ||
if (0 < top && bottom < windowHeight || top < 0 && windowHeight < bottom) { | ||
return 0; | ||
} | ||
// bottom of component is visible | ||
if (top < 0 && 0 < bottom && bottom < windowHeight) { | ||
return 1; | ||
} | ||
// top of component is visible | ||
if (0 < top && top < windowHeight) { | ||
return 2; | ||
} | ||
// not visible, not new | ||
return 3; | ||
} | ||
function prioritizeQueue(queue) { | ||
var buckets = new Array(4); | ||
for (var head = queue; head !== NIL; head = head.next) { | ||
var bucketIndex = getPriority(head); | ||
if (bucketIndex < 0) { | ||
continue; | ||
} | ||
var clone = { component: head.component, next: NIL }; | ||
if (!buckets[bucketIndex]) { | ||
buckets[bucketIndex] = { first: clone, last: clone }; | ||
} else { | ||
buckets[bucketIndex].last.next = clone; | ||
buckets[bucketIndex].last = clone; | ||
} | ||
} | ||
return buckets.reduceRight(concatWithKnownLast, NIL); | ||
} | ||
function concatWithKnownLast(queue, _a) { | ||
var first = _a.first, | ||
last = _a.last; | ||
var newList = concat(last, queue); | ||
return newList === last ? first : newList; | ||
} | ||
function concat(queue, nextQueue) { | ||
if (queue === NIL) { | ||
return nextQueue; | ||
} | ||
var p = queue; | ||
while (p.next !== NIL) { | ||
if (nextQueue === NIL) { | ||
return queue; | ||
} | ||
if (nextQueue.component === p.component) { | ||
nextQueue = nextQueue.next; | ||
} else { | ||
var prev = nextQueue; | ||
for (var head = nextQueue.next; head && head !== NIL; head = head.next) { | ||
if (head.component === p.component) { | ||
prev.next = head.next; | ||
break; | ||
} | ||
prev = head; | ||
} | ||
} | ||
p = p.next; | ||
} | ||
p.next = nextQueue; | ||
return queue; | ||
} | ||
function pop() { | ||
if (isEmpty()) { | ||
return null; | ||
} | ||
var head = queue; | ||
queue = queue.next; | ||
return head; | ||
} | ||
var isTicking = false; | ||
function tick(callback) { | ||
if (isTicking) { | ||
return; | ||
} | ||
isTicking = true; | ||
requestAnimationFrame(function () { | ||
var startTime = Date.now(); | ||
callback({ | ||
didTimeout: false, | ||
timeRemaining: function timeRemaining() { | ||
return Math.max(0, idealFrameLength - (Date.now() - startTime)); | ||
} | ||
}); | ||
}); | ||
} | ||
function drain() { | ||
var next = pop(); | ||
var mounted = []; | ||
while (next) { | ||
if (next.component.el) { | ||
patchOuter(next.component.el, function (_) { | ||
return updateComponent(next.component); | ||
}, {}); | ||
mounted.push(next.component); | ||
} | ||
next = pop(); | ||
} | ||
return mounted; | ||
} | ||
function flush(deadline) { | ||
var prevQueue; | ||
var next = pop(); | ||
var hasNew = false; | ||
var mounted = new Set(); | ||
while (next) { | ||
prevQueue = queue; | ||
queue = NIL; | ||
if (next.component.el) { | ||
var isNew = next.component.el.localName === 'm-placeholder'; | ||
patchOuter(next.component.el, function (_) { | ||
return updateComponent(next.component); | ||
}, {}); | ||
mounted.add(next.component); | ||
if (isNew && queue !== NIL) { | ||
var drained = drain(); | ||
for (var i = 0; i < drained.length; i++) { | ||
mounted.add(drained[i]); | ||
} | ||
queue = NIL; | ||
} | ||
} | ||
if (queue !== NIL) { | ||
hasNew = true; | ||
} | ||
queue = concat(queue, prevQueue); | ||
if (options.experimentalSyncDeepRendering) { | ||
next = pop(); | ||
} else { | ||
next = 0 < deadline.timeRemaining() ? pop() : null; | ||
} | ||
} | ||
// notify the freshly mounted components | ||
var notified = mounted.values(); | ||
for (var current = notified.next(); !current.done; current = notified.next()) { | ||
var comp = current.value; | ||
if (comp.el) { | ||
mountedComponents.add(comp); | ||
comp.notify(); | ||
} | ||
} | ||
isTicking = false; | ||
if (!isEmpty()) { | ||
if (!prioritizationDisabled && !prioritizationRequested && hasNew) { | ||
prioritizationRequested = true; | ||
window.postMessage(MESSAGE_KEY, '*'); | ||
} | ||
tick(flush); | ||
} | ||
} | ||
function clear() { | ||
if (process.env.NODE_ENV !== 'test') { | ||
throw new Error('Clearing the queue is only allowed within a test environment.'); | ||
} | ||
queue = NIL; | ||
} | ||
function performReordering(event) { | ||
if (event.source !== this || event.data !== MESSAGE_KEY) { | ||
return; | ||
} | ||
prioritizationRequested = false; | ||
var timeSpent = Date.now(); | ||
queue = prioritizeQueue(queue); | ||
timeSpent = Date.now() - timeSpent; | ||
// Usually prioritization takes 0 - 4 ms on fast browsers. If browser is not | ||
// able to do that (like Edge/IE) in this period skip the process. | ||
if (timeSpent > 10) { | ||
prioritizationDisabled = true; | ||
} | ||
} | ||
window.addEventListener('message', performReordering, false); | ||
function enqueueComponent$$1(component$$1) { | ||
/* istanbul ignore if */ | ||
if (supportsPassiveListeners && !scrollListenerAttached) { | ||
attachScrollListener(); | ||
} | ||
addToQueue(component$$1); | ||
/* istanbul ignore else */ | ||
if (process.env.NODE_ENV === 'test') { | ||
return; | ||
} | ||
tick(flush); | ||
} | ||
/* istanbul ignore next */ | ||
var detectIdleCallback = _debounce(function detectIdleCallback() { | ||
idealFrameLength = IDLE_FRAME_LENGTH; | ||
}, 300); | ||
/* istanbul ignore next */ | ||
function attachScrollListener() { | ||
scrollListenerAttached = true; | ||
// if we can detect when the browser is busy | ||
// then we can assume its idle by default | ||
idealFrameLength = IDLE_FRAME_LENGTH; | ||
document.addEventListener('scroll', function () { | ||
idealFrameLength = BUSY_FRAME_LENGTH; | ||
detectIdleCallback(); | ||
}, { passive: true }); | ||
} | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { | ||
return typeof obj; | ||
} : function (obj) { | ||
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; | ||
}; | ||
/** | ||
* Copyright 2015 The Incremental DOM Authors. | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
var getNamespace = function getNamespace(name) { | ||
if (name.lastIndexOf('xml:', 0) === 0) { | ||
return 'http://www.w3.org/XML/1998/namespace'; | ||
} | ||
if (name.lastIndexOf('xlink:', 0) === 0) { | ||
return 'http://www.w3.org/1999/xlink'; | ||
} | ||
}; | ||
/** | ||
* Applies an attribute or property to a given Element. If the value is null | ||
* or undefined, it is removed from the Element. Otherwise, the value is set | ||
* as an attribute. | ||
* @param {!Element} el | ||
* @param {string} name The attribute's name. | ||
* @param {?(boolean|number|string)=} value The attribute's value. | ||
*/ | ||
var applyAttr = function applyAttr(el, name, value) { | ||
if (value == null) { | ||
el.removeAttribute(name); | ||
} else { | ||
var attrNS = getNamespace(name); | ||
if (attrNS) { | ||
el.setAttributeNS(attrNS, name, value); | ||
} else { | ||
el.setAttribute(name, value); | ||
} | ||
} | ||
}; | ||
/** | ||
* Updates a single attribute on an Element. | ||
* @param {!Element} el | ||
* @param {string} name The attribute's name. | ||
* @param {*} value The attribute's value. If the value is an object or | ||
* function it is set on the Element, otherwise, it is set as an HTML | ||
* attribute. | ||
*/ | ||
function applyAttributeTyped(el, name, value) { | ||
var type = typeof value === 'undefined' ? 'undefined' : _typeof(value); | ||
if (type === 'object' || type === 'function') { | ||
setProperty(el, name, value); | ||
} else { | ||
applyAttr(el, name /** @type {?(boolean|number|string)} */, value); | ||
} | ||
} | ||
function setProperty(el, name, value) { | ||
try { | ||
el[name] = value; | ||
} catch (e) {} | ||
} | ||
function eventProxy(e) { | ||
return this._listeners[e.type](e); | ||
} | ||
/** | ||
* Calls the appropriate attribute mutator for this attribute. | ||
* @param {!Element} el | ||
* @param {string} name The attribute's name. | ||
* @param {*} value The attribute's value. | ||
*/ | ||
var updateAttribute = function updateAttribute(el, name, value) { | ||
var data = getData(el); | ||
var attrs = data.attrs; | ||
if (attrs[name] === value) { | ||
return; | ||
} | ||
if (name === 'style') { | ||
var old = attrs.style; | ||
if (!value || typeof value === 'string') { | ||
el.style.cssText = value || ''; | ||
} else { | ||
if (typeof old === 'string') { | ||
el.style.cssText = ''; | ||
} else { | ||
for (var i in old) { | ||
if (!(i in value)) { | ||
el.style[i] = ''; | ||
} | ||
} | ||
} | ||
for (var i in value) { | ||
if (i.indexOf('-') >= 0) { | ||
el.style.setProperty(i, value[i]); | ||
} else { | ||
el.style[i] = value[i]; | ||
} | ||
} | ||
} | ||
} else if (name === 'ref') { | ||
var old = attrs.ref; | ||
if (old && old.disposer) { | ||
if (old.creator === value) { | ||
return; | ||
} | ||
old.disposer.unsubscribe(); | ||
} | ||
if (!value) { | ||
attrs.ref = null; | ||
return; | ||
} | ||
attrs.ref = { | ||
creator: value, | ||
disposer: value(el) | ||
}; | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (!attrs.ref.disposer || typeof attrs.ref.disposer.unsubscribe !== 'function') { | ||
throw new Error("A ref handler is supposed to return a Subscription object which must have a \"unsubscribe\" method."); | ||
} | ||
} | ||
return; | ||
} else if (name[0] === 'o' && name[1] === 'n') { | ||
if (typeof value === 'string') { | ||
applyAttributeTyped(el, name, value); | ||
} else { | ||
var eventName = name.replace(/Capture$/, ''); | ||
var useCapture = name !== eventName; | ||
eventName = eventName.toLowerCase().substring(2); | ||
if (value) { | ||
if (!attrs[name]) { | ||
el.addEventListener(eventName, eventProxy, useCapture); | ||
} | ||
} else if (typeof attrs[name] === 'string') { | ||
el.removeAttribute(name); | ||
} else { | ||
el.removeEventListener(eventName, eventProxy, useCapture); | ||
} | ||
(el._listeners || (el._listeners = {}))[eventName] = value; | ||
} | ||
} else if (name !== 'list' && name !== 'type' && name !== 'draggable' && !(el.ownerSVGElement || el.localName === 'svg') && name in el) { | ||
setProperty(el, name, value == null ? '' : value); | ||
if (value == null || value === false) { | ||
el.removeAttribute(name); | ||
} | ||
} else { | ||
applyAttributeTyped(el, name, value); | ||
} | ||
attrs[name] = value; | ||
}; | ||
/** | ||
* Copyright 2015 The Incremental DOM Authors. | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** | ||
* The offset in the virtual element declaration where the attributes are | ||
* specified. | ||
* @const | ||
*/ | ||
var ATTRIBUTES_OFFSET = 3; | ||
/** | ||
* Builds an array of arguments for use with elementOpenStart, attr and | ||
* elementOpenEnd. | ||
* @const {Array<*>} | ||
*/ | ||
var argsBuilder = []; | ||
/** | ||
* @param {string} tag The element's tag. | ||
* @param {?string=} key The key used to identify this element. This can be an | ||
* empty string, but performance may be better if a unique value is used | ||
* when iterating over an array of items. | ||
* @param {?Array<*>=} statics An array of attribute name/value pairs of the | ||
* static attributes for the Element. These will only be set once when the | ||
* Element is created. | ||
* @param {...*} var_args Attribute name/value pairs of the dynamic attributes | ||
* for the Element. | ||
* @return {!Element} The corresponding Element. | ||
*/ | ||
var elementOpen$1 = function elementOpen$$1(tag, key, statics, var_args) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertNotInAttributes('elementOpen'); | ||
assertNotInSkip('elementOpen'); | ||
} | ||
var node = elementOpen(tag, key); | ||
var data = getData(node); | ||
/* | ||
* Checks to see if one or more attributes have changed for a given Element. | ||
* When no attributes have changed, this is much faster than checking each | ||
* individual argument. When attributes have changed, the overhead of this is | ||
* minimal. | ||
*/ | ||
var attrsArr = data.attrsArr; | ||
var newAttrs = data.newAttrs; | ||
var isNew = !attrsArr.length; | ||
var i = ATTRIBUTES_OFFSET; | ||
var j = 0; | ||
if (!data.staticsApplied) { | ||
if (statics) { | ||
for (var i_1 = 0; i_1 < statics.length; i_1 += 2) { | ||
var name_1 = statics[i_1]; | ||
var value = statics[i_1 + 1]; | ||
if (newAttrs[name_1] === undefined) { | ||
delete newAttrs[name_1]; | ||
} | ||
updateAttribute(node, name_1, value); | ||
} | ||
} | ||
data.staticsApplied = true; | ||
} | ||
for (; i < arguments.length; i += 2, j += 2) { | ||
var attr_1 = arguments[i]; | ||
if (isNew) { | ||
attrsArr[j] = attr_1; | ||
newAttrs[attr_1] = undefined; | ||
} else if (attrsArr[j] !== attr_1) { | ||
break; | ||
} | ||
var value = arguments[i + 1]; | ||
if (isNew || attrsArr[j + 1] !== value) { | ||
attrsArr[j + 1] = value; | ||
updateAttribute(node, attr_1, value); | ||
} | ||
} | ||
if (i < arguments.length || j < attrsArr.length) { | ||
for (; i < arguments.length; i += 1, j += 1) { | ||
attrsArr[j] = arguments[i]; | ||
} | ||
if (j < attrsArr.length) { | ||
attrsArr.length = j; | ||
} | ||
/** | ||
* Actually perform the attribute update. | ||
*/ | ||
for (i = 0; i < attrsArr.length; i += 2) { | ||
newAttrs[attrsArr[i]] = attrsArr[i + 1]; | ||
} | ||
for (var attr_2 in newAttrs) { | ||
updateAttribute(node, attr_2, newAttrs[attr_2]); | ||
newAttrs[attr_2] = undefined; | ||
} | ||
} | ||
return node; | ||
}; | ||
/** | ||
* Declares a virtual Element at the current location in the document. This | ||
* corresponds to an opening tag and a elementClose tag is required. This is | ||
* like elementOpen, but the attributes are defined using the attr function | ||
* rather than being passed as arguments. Must be folllowed by 0 or more calls | ||
* to attr, then a call to elementOpenEnd. | ||
* @param {string} tag The element's tag. | ||
* @param {?string=} key The key used to identify this element. This can be an | ||
* empty string, but performance may be better if a unique value is used | ||
* when iterating over an array of items. | ||
* @param {?Array<*>=} statics An array of attribute name/value pairs of the | ||
* static attributes for the Element. These will only be set once when the | ||
* Element is created. | ||
*/ | ||
var elementOpenStart = function elementOpenStart(tag, key, statics, var_args) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertNotInAttributes('elementOpenStart'); | ||
setInAttributes(true); | ||
} | ||
argsBuilder[0] = tag; | ||
argsBuilder[1] = key; | ||
argsBuilder[2] = statics; | ||
var i = ATTRIBUTES_OFFSET; | ||
for (; i < arguments.length; i++) { | ||
argsBuilder[i] = arguments[i]; | ||
} | ||
}; | ||
/*** | ||
* Defines a virtual attribute at this point of the DOM. This is only valid | ||
* when called between elementOpenStart and elementOpenEnd. | ||
* | ||
* @param {string} name | ||
* @param {*} value | ||
*/ | ||
var attr = function attr(name, value) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertInAttributes('attr'); | ||
} | ||
argsBuilder.push(name, value); | ||
}; | ||
/** | ||
* Closes an open tag started with elementOpenStart. | ||
* @return {!Element} The corresponding Element. | ||
*/ | ||
var elementOpenEnd = function elementOpenEnd() { | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertInAttributes('elementOpenEnd'); | ||
setInAttributes(false); | ||
} | ||
var node = elementOpen$1.apply(null, argsBuilder); | ||
argsBuilder.length = 0; | ||
return node; | ||
}; | ||
/** | ||
* Closes an open virtual Element. | ||
* | ||
* @param {string} tag The element's tag. | ||
* @return {!Element} The corresponding Element. | ||
*/ | ||
var elementClose$1 = function elementClose$$1(tag) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertNotInAttributes('elementClose'); | ||
} | ||
var node = elementClose(); | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertCloseMatchesOpenTag(getData(node).nodeName, tag); | ||
} | ||
return node; | ||
}; | ||
/** | ||
* Declares a virtual Element at the current location in the document that has | ||
* no children. | ||
* @param {string} tag The element's tag. | ||
* @param {?string=} key The key used to identify this element. This can be an | ||
* empty string, but performance may be better if a unique value is used | ||
* when iterating over an array of items. | ||
* @param {?Array<*>=} statics An array of attribute name/value pairs of the | ||
* static attributes for the Element. These will only be set once when the | ||
* Element is created. | ||
* @param {...*} var_args Attribute name/value pairs of the dynamic attributes | ||
* for the Element. | ||
* @return {!Element} The corresponding Element. | ||
*/ | ||
var elementVoid = function elementVoid(tag, key, statics, var_args) { | ||
elementOpen$1.apply(null, arguments); | ||
skip(); | ||
return elementClose$1(tag); | ||
}; | ||
var ref = function ref(id) { | ||
return function (element) { | ||
var comp = getCurrentComponent(); | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (!comp || !comp.refs) { | ||
throw new Error('ref() must be used within a component'); | ||
} | ||
} | ||
comp.refs[id] = element; | ||
return { | ||
unsubscribe: function unsubscribe() { | ||
if (!comp) { | ||
return; | ||
} | ||
comp = null; | ||
} | ||
}; | ||
}; | ||
}; | ||
/** | ||
* Creates a new RawString that may contain HTML that should be rendered | ||
* as is and should not be escaped. | ||
* | ||
* @param {string} value The wrapped String. | ||
* @class | ||
*/ | ||
var RawString = function RawString(value) { | ||
this.value = value; | ||
}; | ||
/** | ||
* Return the wrapped value of the raw string. | ||
*/ | ||
RawString.prototype.toString = function () { | ||
return this.value; | ||
}; | ||
/** | ||
* Creates a new RawString that may contain HTML that should be rendered | ||
* as is and should not be escaped. | ||
* | ||
* @param {string} value The wrapped String. | ||
*/ | ||
var rawString = function rawString(value) { | ||
if (value instanceof RawString) { | ||
return value; | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (typeof value !== 'string') { | ||
throw new Error('Tried to create a RawString from non-string value: ' + JSON.stringify(value)); | ||
} | ||
} | ||
return new RawString(value); | ||
}; | ||
/** | ||
* Declares a virtual Text at this point in the document. | ||
* | ||
* @param {string|number|boolean|RawString} value The value of the Text. | ||
* @param {...(function((string|number|boolean)):string)} var_args | ||
* Functions to format the value which are called only when the value has | ||
* changed. | ||
* @return {!Text} The corresponding text node. | ||
*/ | ||
var text$1 = function text$$1(value, var_args) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertNotInAttributes('text'); | ||
assertNotInSkip('text'); | ||
} | ||
if (value instanceof RawString) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (arguments.length > 1) { | ||
throw new Error("Can't call filters on a raw string."); | ||
} | ||
} | ||
return raw$1(value.value); | ||
} | ||
var node = text(); | ||
var data = getData(node); | ||
if (data.text !== value) { | ||
data.text /** @type {string} */ = value; | ||
var formatted = value; | ||
for (var i = 1; i < arguments.length; i += 1) { | ||
/* | ||
* Call the formatter function directly to prevent leaking arguments. | ||
* https://github.com/google/incremental-dom/pull/204#issuecomment-178223574 | ||
*/ | ||
var fn = arguments[i]; | ||
formatted = fn(formatted); | ||
} | ||
node.data = formatted; | ||
} | ||
return node; | ||
}; | ||
var raw$1 = function raw$$1(value) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
assertNotInAttributes('text'); | ||
assertNotInSkip('text'); | ||
} | ||
return raw(value); | ||
}; | ||
/** | ||
* Copyright 2015 The Incremental DOM Authors. | ||
* Copyright 2017 trivago N.V. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
exports.options = options; | ||
exports.flush = flush; | ||
exports.clearQueue = clear; | ||
exports.getParent = getParent; | ||
exports.link = link; | ||
exports.patch = patchInner; | ||
exports.patchInner = patchInner; | ||
exports.patchOuter = patchOuter; | ||
exports.currentElement = currentElement; | ||
exports.skip = skip; | ||
exports.skipNode = skipNode; | ||
exports.mount = mount; | ||
exports.component = component; | ||
exports.enqueueComponent = enqueueComponent$$1; | ||
exports.elementVoid = elementVoid; | ||
exports.elementOpenStart = elementOpenStart; | ||
exports.elementOpenEnd = elementOpenEnd; | ||
exports.elementOpen = elementOpen$1; | ||
exports.elementClose = elementClose$1; | ||
exports.text = text$1; | ||
exports.attr = attr; | ||
exports.raw = raw$1; | ||
exports.rawString = rawString; | ||
exports.ref = ref; | ||
exports.getNodeData = getData; | ||
exports.unmountComponent = unmountComponent; | ||
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var n=e(require("lodash/debounce")),s={},t=new WeakMap,r=new WeakMap;function a(e,n){r.set(n,e),i(e).push(n)}function o(e){t.delete(e),r.delete(e)}function i(e){var n=t.get(e);return n||(n=[],t.set(e,n)),n}function u(e){return r.get(e)}function l(e){t.set(e,[])}function c(){}c.prototype=Object.create(null);var f=function(){return new c},p=function e(n){i(n).forEach(e),o(n),we(n);var t=n.el?n.el.__incrementalDOMData:null;s.beforeUnmount&&s.beforeUnmount(n),pe.has(n)&&(n.componentWillUnmount(),pe.delete(n)),t&&t.componentInstance&&(t.componentInstance=null),n.el=null},d=null;function m(e){return d||(d=document.createRange()).selectNode(document.body),d.createContextualFragment(e.trim()).childNodes}function v(e,n){this.attrs=f(),this.attrsArr=[],this.newAttrs=f(),this.key=n,this.keyMap=f(),this.keyMapValid=!0,this.staticsApplied=!1,this.focused=!1,this.nodeName=e,this.text=null,this.componentInstance=null,this.childLength=0}var h,x,g,y=function(e,n,t){var r=new v(n,t);return e.__incrementalDOMData=r},b=function(e){return w(e),e.__incrementalDOMData},w=function(e){for(var n=[e];n.length;){var t=n.pop();if(!t.__incrementalDOMData){var r=t instanceof Element,o=r?t.localName:t.nodeName,i=r?t.getAttribute("key"):null,a=y(t,o,i);if(i){var u=t.parentNode&&t.parentNode.__incrementalDOMData;u&&(u.keyMap[i]=t)}if(r){for(var l=t.attributes,c=a.attrs,f=a.newAttrs,s=a.attrsArr,p=0;p<l.length;p+=1){var d=l[p],m=d.name,v=d.value;c[m]=v,f[m]=void 0,s.push(m),s.push(v)}for(var h=t.firstChild;h;h=h.nextSibling)n.push(h)}else 3===t.nodeType&&(a.text=t.data)}}},k=function(e,n){return"svg"===e?"http://www.w3.org/2000/svg":"foreignObject"===b(n).nodeName?null:n.namespaceURI},S=function(e,n,t,r){var o,i=k(t,n);return o=i?e.createElementNS(i,t):e.createElement(t),y(o,t,r),o},N=function(e){var n=e.createTextNode("");return y(n,"#text",null),n},M=function(e,n){var t=m(n);if(!t.length){var r=document.createElement("div");r.appendChild(e.createTextNode("")),t=r.childNodes}var o=y(t[0],"#raw",null);return o.text=n,o.childLength=t.length,t},D=function(e){return e instanceof Document||e instanceof DocumentFragment},C=function(e,n){for(var t=[],r=e;r!==n;)t.push(r),r=r.parentNode;return t},_=function(e){for(var n=e,t=n;n;)n=(t=n).parentNode;return t},A=function(e){var n=_(e);return D(n)?n.activeElement:null},E=function(e,n){if(e.contains)return e.contains(n);for(;n&&n!==e;)n=n.parentNode;return n===e},I=function(e,n){var t=A(e);return t&&E(e,t)?C(t,n):[]},O=function(e,n,t){for(var r=n.nextSibling,o=t;o&&o!==n;){var i=o.nextSibling;e.insertBefore(o,r),o=i}},L=null,R=null,T=null,V=function(e,n){for(var t=0;t<e.length;t+=1)b(e[t]).focused=n},j=function(p){return function(e,n,t){var r=T,o=g,i=h,a=x,u=R;T=[],g=e.ownerDocument,x=e.parentNode;var l,c,f,s=I(e,x);for(V(s,!0),l=p(e,n,t),V(s,!1),c=0,f=T.length;c<f;c++)q(T[c]);return T=r,g=o,h=i,x=a,R=u,l}};function q(e){var n=b(e);n.attrs.ref&&n.attrs.ref.disposer&&(n.attrs.ref.disposer.unsubscribe(),n.attrs.ref=null),n.componentInstance&&p(n.componentInstance);for(var t=e.firstChild;t;)q(t),t=t.nextSibling}var B=j(function(e,n,t){return h=e,z(),n(t),X(),e}),F=j(function(e,n,t){var r={nextSibling:e};return h=r,n(t),e!==h&&e.parentNode&&W(x,e,b(x).keyMap),r===h?null:h}),P=function(e,n,t){var r=b(e);if(n===r.nodeName){if(t==r.key)return!0;if(!r.key){r.key=t;var o=x&&b(x).keyMap;return o&&(o[t]=e),!0}}return!1},U=function(e,n){if(!h||!P(h,e,n)){var t,r=b(x),o=h&&b(h),i=r.keyMap,a=!1,u=null;if(n){var l=i[n];if(l)if(P(l,e,n))a=!0,t=l;else if(l===h){var c=b(l);c.componentInstance?(u=c.componentInstance,c.componentInstance=null):T.push(l)}else W(x,l,i);else h&&3===h.nodeType&&""===h.data.trim()&&h.nextSibling&&P(h.nextSibling,e,n)&&(t=h.nextSibling)}t||(t="#text"===e?N(g):S(g,x,e,n),n&&(i[n]=t)),u&&((b(t).componentInstance=u).el=t),b(t).focused?O(x,t,h):a&&!t.parentNode||!o||!o.key||o.focused?h&&h.nextSibling===t&&3===h.nodeType&&""===h.data.trim()?x.removeChild(h):x.insertBefore(t,h):(x.replaceChild(t,h),r.keyMapValid=!1),h=t}},W=function(e,n,t){e.removeChild(n),T.push(n);var r=b(n).key;r&&delete t[r]},H=function(){var e,n=x,t=b(n),r=t.keyMap,o=t.keyMapValid,i=n.lastChild;if(i!==h||!o){for(;i&&i!==h;)W(n,i,r),i=n.lastChild;if(!o){for(e in r)(i=r[e]).parentNode!==n&&(T.push(i),delete r[e]);t.keyMapValid=!0}}},z=function(){x=h,h=null},G=function(){h=Q()},Q=function(){return h?h.nextSibling:x.firstChild},X=function(){H(),x=(h=x).parentNode},$=function(e){var n=b(e.el),t=R;L=n.key,l(e),(R=e).render(),R=t},J=function(e,n,t,r){var o;if(r){var i=b(r);(o=i.componentInstance)||((o="function"==typeof e?new e:e).el=r,i.componentInstance=o),ee(i.nodeName,n),oe(),ne()}else o="function"==typeof e?new e:e,ee("m-placeholder",n),oe(),o.el=ne(),b(o.el).componentInstance=o;return R&&a(R,o),o.apply(t)},K=function(e,n,t){var r=b(x).keyMap[n];return J(e,n,t,r)},Y=function(){return R},Z=function(e,n,t){var r=b(e),o=r&&r.key,i=r.componentInstance;return!i||"function"!=typeof n||i instanceof n||p(i),J(n,o,t,e)},ee=function(e,n){return G(),U(e,L||n),L=null,z(),x},ne=function(){return X(),h},te=function(){return G(),U("#text",null),h},re=function(){return x},oe=function(){h=x.lastChild},ie=G,ae=function(e){for(var n=M(g,e),t=g.createDocumentFragment(),r=n[n.length-1];n.length;)t.appendChild(n[0]);x.insertBefore(t,h),h=r},ue=function(e){if(G(),h&&P(h,"#raw",null)){var n=b(h),t=n.childLength-1;if(n.text!==e){if(ae(e),1<n.childLength)for(;t--;)x.removeChild(h.nextSibling)}else if(t)for(;t--;)h=h.nextSibling}else ae(e);return h},le=!1;document.createElement("div").addEventListener("test",function(){},{get passive(){return!(le=!0)}});var ce=3,fe=30,se="__melodyPrioritize_"+Math.random().toString(36).slice(2),pe=new WeakSet,de=fe,me=!1,ve=!1,he=!!s.experimentalSyncDeepRendering,xe={component:null,next:null},ge=xe;function ye(){return ge===xe}function be(e){if(ge!==xe)for(var n=ge;n!==xe;n=n.next){if(n.component===e)return;if("streaming"!==e.type){if(u(e)===n.component)return;if(u(n.component)===e)return void(n.component=e)}if(n.next===xe){n.next={component:e,next:xe};break}}else ge={component:e,next:xe}}function we(e){if(ge!==xe){ge.component===e&&(ge=ge.next);for(var n=ge,t=ge.next;t&&t!==xe;t=t.next){var r=t.component;do{if(r===e){n.next=t.next,t=n;break}r=u(r)}while(r);n=t}}}function ke(e){if(!e.component.el)return-1;var n=window.innerHeight||document.documentElement.clientHeight,t=e.component.el.getBoundingClientRect(),r=t.top,o=t.bottom;return 0<r&&o<n||r<0&&n<o?0:r<0&&0<o&&o<n?1:0<r&&r<n?2:3}function Se(e){for(var n=new Array(4),t=e;t!==xe;t=t.next){var r=ke(t);if(!(r<0)){var o={component:t.component,next:xe};n[r]?(n[r].last.next=o,n[r].last=o):n[r]={first:o,last:o}}}return n.reduceRight(Ne,xe)}function Ne(e,n){var t=n.first,r=n.last,o=Me(r,e);return o===r?t:o}function Me(e,n){if(e===xe)return n;for(var t=e;t.next!==xe;){if(n===xe)return e;if(n.component===t.component)n=n.next;else for(var r=n,o=n.next;o&&o!==xe;o=o.next){if(o.component===t.component){r.next=o.next;break}r=o}t=t.next}return t.next=n,e}function De(){if(ye())return null;var e=ge;return ge=ge.next,e}var Ce=!1;function _e(n){Ce||(Ce=!0,requestAnimationFrame(function(){var e=Date.now();n({didTimeout:!1,timeRemaining:function(){return Math.max(0,de-(Date.now()-e))}})}))}function Ae(){for(var n=De(),e=[];n;)n.component.el&&(F(n.component.el,function(e){return $(n.component)},{}),e.push(n.component)),n=De();return e}function Ee(e){for(var n,t=De(),r=!1,o=new Set;t;){if(n=ge,ge=xe,t.component.el){var i="m-placeholder"===t.component.el.localName;if(F(t.component.el,function(e){return $(t.component)},{}),o.add(t.component),i&&ge!==xe){for(var a=Ae(),u=0;u<a.length;u++)o.add(a[u]);ge=xe}}ge!==xe&&(r=!0),ge=Me(ge,n),t=s.experimentalSyncDeepRendering?De():0<e.timeRemaining()?De():null}for(var l=o.values(),c=l.next();!c.done;c=l.next()){var f=c.value;f.el&&(pe.add(f),f.notify())}Ce=!1,ye()||(he||ve||!r||(ve=!0,window.postMessage(se,"*")),_e(Ee))}function Ie(){throw new Error("Clearing the queue is only allowed within a test environment.")}function Oe(e){if(e.source===this&&e.data===se){ve=!1;var n=Date.now();ge=Se(ge),10<(n=Date.now()-n)&&(he=!0)}}function Le(e){le&&!me&&Te(),be(e),_e(Ee)}window.addEventListener("message",Oe,!1);var Re=n(function(){de=fe},300);function Te(){me=!0,de=fe,document.addEventListener("scroll",function(){de=ce,Re()},{passive:!0})}var Ve="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},je=function(e){return 0===e.lastIndexOf("xml:",0)?"http://www.w3.org/XML/1998/namespace":0===e.lastIndexOf("xlink:",0)?"http://www.w3.org/1999/xlink":void 0},qe=function(e,n,t){if(null==t)e.removeAttribute(n);else{var r=je(n);r?e.setAttributeNS(r,n,t):e.setAttribute(n,t)}};function Be(e,n,t){var r=void 0===t?"undefined":Ve(t);"object"===r||"function"===r?Fe(e,n,t):qe(e,n,t)}function Fe(e,n,t){try{e[n]=t}catch(e){}}function Pe(e){return this._listeners[e.type](e)}var Ue=function(e,n,t){var r=b(e).attrs;if(r[n]!==t){if("style"===n){var o=r.style;if(t&&"string"!=typeof t){if("string"==typeof o)e.style.cssText="";else for(var i in o)i in t||(e.style[i]="");for(var i in t)0<=i.indexOf("-")?e.style.setProperty(i,t[i]):e.style[i]=t[i]}else e.style.cssText=t||""}else{if("ref"===n){if((o=r.ref)&&o.disposer){if(o.creator===t)return;o.disposer.unsubscribe()}return t?void(r.ref={creator:t,disposer:t(e)}):void(r.ref=null)}if("o"===n[0]&&"n"===n[1])if("string"==typeof t)Be(e,n,t);else{var a=n.replace(/Capture$/,""),u=n!==a;a=a.toLowerCase().substring(2),t?r[n]||e.addEventListener(a,Pe,u):"string"==typeof r[n]?e.removeAttribute(n):e.removeEventListener(a,Pe,u),(e._listeners||(e._listeners={}))[a]=t}else"list"!==n&&"type"!==n&&"draggable"!==n&&!e.ownerSVGElement&&"svg"!==e.localName&&n in e?(Fe(e,n,null==t?"":t),null!=t&&!1!==t||e.removeAttribute(n)):Be(e,n,t)}r[n]=t}},We=3,He=[],ze=function(e,n,t,r){var o=ee(e,n),i=b(o),a=i.attrsArr,u=i.newAttrs,l=!a.length,c=We,f=0;if(!i.staticsApplied){if(t)for(var s=0;s<t.length;s+=2){var p=t[s],d=t[s+1];void 0===u[p]&&delete u[p],Ue(o,p,d)}i.staticsApplied=!0}for(;c<arguments.length;c+=2,f+=2){var m=arguments[c];if(l)u[a[f]=m]=void 0;else if(a[f]!==m)break;d=arguments[c+1];(l||a[f+1]!==d)&&(a[f+1]=d,Ue(o,m,d))}if(c<arguments.length||f<a.length){for(;c<arguments.length;c+=1,f+=1)a[f]=arguments[c];for(f<a.length&&(a.length=f),c=0;c<a.length;c+=2)u[a[c]]=a[c+1];for(var v in u)Ue(o,v,u[v]),u[v]=void 0}return o},Ge=function(e,n,t,r){He[0]=e,He[1]=n,He[2]=t;for(var o=We;o<arguments.length;o++)He[o]=arguments[o]},Qe=function(e,n){He.push(e,n)},Xe=function(){var e=ze.apply(null,He);return He.length=0,e},$e=function(e){return ne()},Je=function(e,n,t,r){return ze.apply(null,arguments),oe(),$e(e)},Ke=function(t){return function(e){var n=Y();return n.refs[t]=e,{unsubscribe:function(){n&&(n=null)}}}},Ye=function(e){this.value=e};Ye.prototype.toString=function(){return this.value};var Ze=function(e){return e instanceof Ye?e:new Ye(e)},en=function(e,n){if(e instanceof Ye)return nn(e.value);var t=te(),r=b(t);if(r.text!==e){for(var o=r.text=e,i=1;i<arguments.length;i+=1){o=(0,arguments[i])(o)}t.data=o}return t},nn=function(e){return ue(e)};exports.options=s,exports.flush=Ee,exports.clearQueue=Ie,exports.getParent=u,exports.link=a,exports.patch=B,exports.patchInner=B,exports.patchOuter=F,exports.currentElement=re,exports.skip=oe,exports.skipNode=ie,exports.mount=Z,exports.component=K,exports.enqueueComponent=Le,exports.elementVoid=Je,exports.elementOpenStart=Ge,exports.elementOpenEnd=Xe,exports.elementOpen=ze,exports.elementClose=$e,exports.text=en,exports.attr=Qe,exports.raw=nn,exports.rawString=Ze,exports.ref=Ke,exports.getNodeData=b,exports.unmountComponent=p; |
{ | ||
"name": "melody-idom", | ||
"version": "1.2.0-21.2", | ||
"version": "1.2.0-alpha.3+617386e", | ||
"description": "", | ||
@@ -17,5 +17,3 @@ "main": "./lib/index.js", | ||
}, | ||
"devDependencies": { | ||
"rollup-plugin-babel": "^2.6.1" | ||
} | ||
"gitHead": "617386e7af1af3c08f469e1c2348fa5e5fdfea05" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
0
41
51
235042
6433
3
1