Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

melody-idom

Package Overview
Dependencies
Maintainers
3
Versions
84
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

melody-idom - npm Package Compare versions

Comparing version 1.2.0-commit.f9b4ed0d to 1.2.0-f61c830.4

LICENSE

8

built/assertions.d.ts

@@ -48,6 +48,6 @@ /**

/**
* Makes sure that tags are correctly nested.
* @param {string} nodeName
* @param {string} tag
*/
* Makes sure that tags are correctly nested.
* @param {string} nodeName
* @param {string} tag
*/
declare var assertCloseMatchesOpenTag: (nodeName: any, tag: any) => void;

@@ -54,0 +54,0 @@ /**

@@ -18,12 +18,12 @@ /**

/**
* Keeps track whether or not we are in an attributes declaration (after
* elementOpenStart, but before elementOpenEnd).
* @type {boolean}
*/
* 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}
*/
* Keeps track whether or not we are in an element that should not have its
* children cleared.
* @type {boolean}
*/
var inSkip = false;

@@ -99,6 +99,6 @@ /**

/**
* Makes sure that tags are correctly nested.
* @param {string} nodeName
* @param {string} tag
*/
* Makes sure that tags are correctly nested.
* @param {string} nodeName
* @param {string} tag
*/
var assertCloseMatchesOpenTag = function (nodeName, tag) {

@@ -105,0 +105,0 @@ if (nodeName !== tag) {

@@ -14,2 +14,3 @@ import { enqueueComponent } from './renderQueue';

notify(): void;
type: String;
}

@@ -16,0 +17,0 @@ declare const patchInner: (node: any, fn: any, data: any) => any;

@@ -26,64 +26,64 @@ /**

/**
* The attributes and their values.
* @const {!Object<string, *>}
*/
* 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<*>}
*/
* 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, *>}
*/
* 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
*/
* 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>}
*/
* 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}
*/
* 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}
*/
* 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}
*/
* 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}
*/
* The node name for this node.
* @const {string}
*/
this.nodeName = nodeName;
/**
* @type {?string}
*/
* @type {?string}
*/
this.text = null;
/**
* The component instance associated with this element.
* @type {Object}
*/
* 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}
*/
* The length of the children in this element.
* This value is only calculated for raw elements.
* @type {number}
*/
this.childLength = 0;

@@ -90,0 +90,0 @@ }

@@ -23,4 +23,3 @@ /**

/* istanbul ignore next */
document.createElement('div')
.addEventListener('test', function () { }, {
document.createElement('div').addEventListener('test', function () { }, {
get passive() {

@@ -59,13 +58,15 @@ supportsPassiveListeners = true;

}
// 2: Is the parent of this component already scheduled for an update?
if (getParent(component) === head.component) {
// if so: we don't need to do anything
return;
if (component.type !== 'streaming') {
// 2: Is the parent of this component already scheduled for an update?
if (getParent(component) === 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) {
// if so: replace the child with its parent
head.component = component;
return;
}
}
// 3: Is the component a parent of a node within the queue?
if (getParent(head.component) === component) {
// if so: replace the child with its parent
head.component = component;
return;
}
if (head.next === NIL) {

@@ -72,0 +73,0 @@ // insert the new node at the end of the list

@@ -53,7 +53,7 @@ /**

/*
* 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.
*/
* 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;

@@ -100,4 +100,4 @@ var newAttrs = data.newAttrs;

/**
* Actually perform the attribute update.
*/
* Actually perform the attribute update.
*/
for (i = 0; i < attrsArr.length; i += 2) {

@@ -281,5 +281,5 @@ newAttrs[attrsArr[i]] = attrsArr[i + 1];

/*
* Call the formatter function directly to prevent leaking arguments.
* https://github.com/google/incremental-dom/pull/204#issuecomment-178223574
*/
* Call the formatter function directly to prevent leaking arguments.
* https://github.com/google/incremental-dom/pull/204#issuecomment-178223574
*/
var fn = arguments[i];

@@ -286,0 +286,0 @@ formatted = fn(formatted);

@@ -124,64 +124,64 @@ import _debounce from 'lodash/debounce';

/**
* The attributes and their values.
* @const {!Object<string, *>}
*/
* 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<*>}
*/
* 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, *>}
*/
* 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
*/
* 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>}
*/
* 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}
*/
* 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}
*/
* 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}
*/
* 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}
*/
* The node name for this node.
* @const {string}
*/
this.nodeName = nodeName;
/**
* @type {?string}
*/
* @type {?string}
*/
this.text = null;
/**
* The component instance associated with this element.
* @type {Object}
*/
* 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}
*/
* The length of the children in this element.
* This value is only calculated for raw elements.
* @type {number}
*/
this.childLength = 0;

@@ -349,12 +349,12 @@ }

/**
* Keeps track whether or not we are in an attributes declaration (after
* elementOpenStart, but before elementOpenEnd).
* @type {boolean}
*/
* 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}
*/
* Keeps track whether or not we are in an element that should not have its
* children cleared.
* @type {boolean}
*/
var inSkip = false;

@@ -423,6 +423,6 @@ /**

/**
* Makes sure that tags are correctly nested.
* @param {string} nodeName
* @param {string} tag
*/
* Makes sure that tags are correctly nested.
* @param {string} nodeName
* @param {string} tag
*/
var assertCloseMatchesOpenTag = function assertCloseMatchesOpenTag(nodeName, tag) {

@@ -1105,13 +1105,15 @@ if (nodeName !== tag) {

}
// 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;
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;
}
}
// 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) {

@@ -1574,7 +1576,7 @@ // insert the new node at the end of the list

/*
* 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.
*/
* 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;

@@ -1620,4 +1622,4 @@ var newAttrs = data.newAttrs;

/**
* Actually perform the attribute update.
*/
* Actually perform the attribute update.
*/
for (i = 0; i < attrsArr.length; i += 2) {

@@ -1802,5 +1804,5 @@ newAttrs[attrsArr[i]] = attrsArr[i + 1];

/*
* Call the formatter function directly to prevent leaking arguments.
* https://github.com/google/incremental-dom/pull/204#issuecomment-178223574
*/
* Call the formatter function directly to prevent leaking arguments.
* https://github.com/google/incremental-dom/pull/204#issuecomment-178223574
*/
var fn = arguments[i];

@@ -1807,0 +1809,0 @@ formatted = fn(formatted);

@@ -1,1862 +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;
}
// 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-commit.f9b4ed0d",
"version": "1.2.0-f61c830.4+f61c830",
"description": "",

@@ -17,5 +17,3 @@ "main": "./lib/index.js",

},
"devDependencies": {
"rollup-plugin-babel": "^2.6.1"
}
"gitHead": "f61c8303bc847d41f4005c1c969510332ece7d1d"
}

@@ -19,13 +19,13 @@ /**

/**
* Keeps track whether or not we are in an attributes declaration (after
* elementOpenStart, but before elementOpenEnd).
* @type {boolean}
*/
* 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}
*/
* Keeps track whether or not we are in an element that should not have its
* children cleared.
* @type {boolean}
*/
var inSkip = false;

@@ -120,6 +120,6 @@

/**
* Makes sure that tags are correctly nested.
* @param {string} nodeName
* @param {string} tag
*/
* Makes sure that tags are correctly nested.
* @param {string} nodeName
* @param {string} tag
*/
var assertCloseMatchesOpenTag = function(nodeName, tag) {

@@ -126,0 +126,0 @@ if (nodeName !== tag) {

@@ -46,2 +46,3 @@ /**

notify(): void;
type: String;
}

@@ -48,0 +49,0 @@

@@ -28,75 +28,75 @@ /**

/**
* The attributes and their values.
* @const {!Object<string, *>}
*/
* 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<*>}
*/
* 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, *>}
*/
* 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
*/
* 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>}
*/
* 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}
*/
* 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}
*/
* 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}
*/
* 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}
*/
* The node name for this node.
* @const {string}
*/
this.nodeName = nodeName;
/**
* @type {?string}
*/
* @type {?string}
*/
this.text = null;
/**
* The component instance associated with this element.
* @type {Object}
*/
* 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}
*/
* The length of the children in this element.
* This value is only calculated for raw elements.
* @type {number}
*/
this.childLength = 0;

@@ -103,0 +103,0 @@ }

@@ -48,9 +48,12 @@ /**

/* istanbul ignore next */
(document.createElement('div')
.addEventListener as WhatWGAddEventListener)('test', function() {}, {
get passive() {
supportsPassiveListeners = true;
return false;
},
});
(document.createElement('div').addEventListener as WhatWGAddEventListener)(
'test',
function() {},
{
get passive() {
supportsPassiveListeners = true;
return false;
},
}
);

@@ -91,13 +94,15 @@ const BUSY_FRAME_LENGTH = 3;

// 2: Is the parent of this component already scheduled for an update?
if (getParent(component) === head.component) {
// if so: we don't need to do anything
return;
}
if (component.type !== 'streaming') {
// 2: Is the parent of this component already scheduled for an update?
if (getParent(component) === 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) {
// if so: replace the child with its parent
head.component = component;
return;
// 3: Is the component a parent of a node within the queue?
if (getParent(head.component) === component) {
// if so: replace the child with its parent
head.component = component;
return;
}
}

@@ -104,0 +109,0 @@

@@ -72,7 +72,7 @@ /**

/*
* 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.
*/
* 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.
*/
const attrsArr = data.attrsArr;

@@ -124,4 +124,4 @@ const newAttrs = data.newAttrs;

/**
* Actually perform the attribute update.
*/
* Actually perform the attribute update.
*/
for (i = 0; i < attrsArr.length; i += 2) {

@@ -330,5 +330,5 @@ newAttrs[attrsArr[i]] = attrsArr[i + 1];

/*
* Call the formatter function directly to prevent leaking arguments.
* https://github.com/google/incremental-dom/pull/204#issuecomment-178223574
*/
* Call the formatter function directly to prevent leaking arguments.
* https://github.com/google/incremental-dom/pull/204#issuecomment-178223574
*/
var fn = arguments[i];

@@ -335,0 +335,0 @@ formatted = fn(formatted);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc