You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1052 lines
41 KiB
1052 lines
41 KiB
(function (global, factory) { |
|
factory(BI.Snabbdom = BI.Snabbdom || {}); |
|
})(this, function (exports) { |
|
'use strict'; |
|
|
|
function createElement(tagName) { |
|
return document.createElement(tagName); |
|
} |
|
function createElementNS(namespaceURI, qualifiedName) { |
|
return document.createElementNS(namespaceURI, qualifiedName); |
|
} |
|
function createTextNode(text) { |
|
return document.createTextNode(text); |
|
} |
|
function createComment(text) { |
|
return document.createComment(text); |
|
} |
|
function insertBefore(parentNode, newNode, referenceNode) { |
|
parentNode.insertBefore(newNode, referenceNode); |
|
} |
|
function removeChild(node, child) { |
|
node.removeChild(child); |
|
} |
|
function appendChild(node, child) { |
|
node.appendChild(child); |
|
} |
|
function parentNode(node) { |
|
return node.parentNode; |
|
} |
|
function nextSibling(node) { |
|
return node.nextSibling; |
|
} |
|
function tagName(elm) { |
|
return elm.tagName; |
|
} |
|
function setTextContent(node, text) { |
|
node.textContent = text; |
|
} |
|
function getTextContent(node) { |
|
return node.textContent; |
|
} |
|
function isElement(node) { |
|
return node.nodeType === 1; |
|
} |
|
function isText(node) { |
|
return node.nodeType === 3; |
|
} |
|
function isComment(node) { |
|
return node.nodeType === 8; |
|
} |
|
var htmlDomApi = { |
|
createElement: createElement, |
|
createElementNS: createElementNS, |
|
createTextNode: createTextNode, |
|
createComment: createComment, |
|
insertBefore: insertBefore, |
|
removeChild: removeChild, |
|
appendChild: appendChild, |
|
parentNode: parentNode, |
|
nextSibling: nextSibling, |
|
tagName: tagName, |
|
setTextContent: setTextContent, |
|
getTextContent: getTextContent, |
|
isElement: isElement, |
|
isText: isText, |
|
isComment: isComment |
|
}; |
|
|
|
function vnode(sel, data, children, text, elm) { |
|
var key = data === undefined ? undefined : data.key; |
|
return { sel: sel, data: data, children: children, text: text, elm: elm, key: key }; |
|
} |
|
|
|
var array = Array.isArray; |
|
function primitive(s) { |
|
return typeof s === "string" || typeof s === "number"; |
|
} |
|
|
|
function isUndef(s) { |
|
return s === undefined; |
|
} |
|
function isDef(s) { |
|
return s !== undefined; |
|
} |
|
var emptyNode = vnode("", {}, [], undefined, undefined); |
|
function sameVnode(vnode1, vnode2) { |
|
return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel; |
|
} |
|
function isVnode(vnode) { |
|
return vnode.sel !== undefined; |
|
} |
|
function createKeyToOldIdx(children, beginIdx, endIdx) { |
|
var _a; |
|
var map = {}; |
|
for (var i = beginIdx; i <= endIdx; ++i) { |
|
var key = (_a = children[i]) === null || _a === void 0 ? void 0 : _a.key; |
|
if (key !== undefined) { |
|
map[key] = i; |
|
} |
|
} |
|
return map; |
|
} |
|
var hooks = ["create", "update", "remove", "destroy", "pre", "post"]; |
|
function init(modules, domApi) { |
|
var i = void 0; |
|
var j = void 0; |
|
var cbs = { |
|
create: [], |
|
update: [], |
|
remove: [], |
|
destroy: [], |
|
pre: [], |
|
post: [] |
|
}; |
|
var api = domApi !== undefined ? domApi : htmlDomApi; |
|
for (i = 0; i < hooks.length; ++i) { |
|
cbs[hooks[i]] = []; |
|
for (j = 0; j < modules.length; ++j) { |
|
var hook = modules[j][hooks[i]]; |
|
if (hook !== undefined) { |
|
cbs[hooks[i]].push(hook); |
|
} |
|
} |
|
} |
|
function emptyNodeAt(elm) { |
|
var id = elm.id ? "#" + elm.id : ""; |
|
var c = elm.className ? "." + elm.className.split(" ").join(".") : ""; |
|
return vnode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm); |
|
} |
|
function createRmCb(childElm, listeners) { |
|
return function rmCb() { |
|
if (--listeners === 0) { |
|
var parent = api.parentNode(childElm); |
|
api.removeChild(parent, childElm); |
|
} |
|
}; |
|
} |
|
function createElm(vnode, insertedVnodeQueue) { |
|
var _a, _b; |
|
var i = void 0; |
|
var data = vnode.data; |
|
if (data !== undefined) { |
|
var _init = (_a = data.hook) === null || _a === void 0 ? void 0 : _a.init; |
|
if (isDef(_init)) { |
|
_init(vnode); |
|
data = vnode.data; |
|
} |
|
} |
|
var children = vnode.children; |
|
var sel = vnode.sel; |
|
if (sel === "!") { |
|
if (isUndef(vnode.text)) { |
|
vnode.text = ""; |
|
} |
|
vnode.elm = api.createComment(vnode.text); |
|
} else if (sel !== undefined) { |
|
// Parse selector |
|
var hashIdx = sel.indexOf("#"); |
|
var dotIdx = sel.indexOf(".", hashIdx); |
|
var hash = hashIdx > 0 ? hashIdx : sel.length; |
|
var dot = dotIdx > 0 ? dotIdx : sel.length; |
|
var tag = hashIdx !== -1 || dotIdx !== -1 ? sel.slice(0, Math.min(hash, dot)) : sel; |
|
var elm = vnode.elm = isDef(data) && isDef(i = data.ns) ? api.createElementNS(i, tag) : api.createElement(tag); |
|
if (hash < dot) elm.setAttribute("id", sel.slice(hash + 1, dot)); |
|
if (dotIdx > 0) elm.setAttribute("class", sel.slice(dot + 1).replace(/\./g, " ")); |
|
for (i = 0; i < cbs.create.length; ++i) { |
|
cbs.create[i](emptyNode, vnode); |
|
}if (array(children)) { |
|
for (i = 0; i < children.length; ++i) { |
|
var ch = children[i]; |
|
if (ch != null) { |
|
api.appendChild(elm, createElm(ch, insertedVnodeQueue)); |
|
} |
|
} |
|
} else if (primitive(vnode.text)) { |
|
api.appendChild(elm, api.createTextNode(vnode.text)); |
|
} |
|
var _hook = vnode.data.hook; |
|
if (isDef(_hook)) { |
|
(_b = _hook.create) === null || _b === void 0 ? void 0 : _b.call(_hook, emptyNode, vnode); |
|
if (_hook.insert) { |
|
insertedVnodeQueue.push(vnode); |
|
} |
|
} |
|
} else { |
|
vnode.elm = api.createTextNode(vnode.text); |
|
} |
|
return vnode.elm; |
|
} |
|
function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) { |
|
for (; startIdx <= endIdx; ++startIdx) { |
|
var ch = vnodes[startIdx]; |
|
if (ch != null) { |
|
api.insertBefore(parentElm, createElm(ch, insertedVnodeQueue), before); |
|
} |
|
} |
|
} |
|
function invokeDestroyHook(vnode) { |
|
var _a, _b; |
|
var data = vnode.data; |
|
if (data !== undefined) { |
|
(_b = (_a = data === null || data === void 0 ? void 0 : data.hook) === null || _a === void 0 ? void 0 : _a.destroy) === null || _b === void 0 ? void 0 : _b.call(_a, vnode); |
|
for (var _i = 0; _i < cbs.destroy.length; ++_i) { |
|
cbs.destroy[_i](vnode); |
|
}if (vnode.children !== undefined) { |
|
for (var _j = 0; _j < vnode.children.length; ++_j) { |
|
var child = vnode.children[_j]; |
|
if (child != null && typeof child !== "string") { |
|
invokeDestroyHook(child); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
function removeVnodes(parentElm, vnodes, startIdx, endIdx) { |
|
var _a, _b; |
|
for (; startIdx <= endIdx; ++startIdx) { |
|
var listeners = void 0; |
|
var rm = void 0; |
|
var ch = vnodes[startIdx]; |
|
if (ch != null) { |
|
if (isDef(ch.sel)) { |
|
invokeDestroyHook(ch); |
|
listeners = cbs.remove.length + 1; |
|
rm = createRmCb(ch.elm, listeners); |
|
for (var _i2 = 0; _i2 < cbs.remove.length; ++_i2) { |
|
cbs.remove[_i2](ch, rm); |
|
}var removeHook = (_b = (_a = ch === null || ch === void 0 ? void 0 : ch.data) === null || _a === void 0 ? void 0 : _a.hook) === null || _b === void 0 ? void 0 : _b.remove; |
|
if (isDef(removeHook)) { |
|
removeHook(ch, rm); |
|
} else { |
|
rm(); |
|
} |
|
} else { |
|
// Text node |
|
api.removeChild(parentElm, ch.elm); |
|
} |
|
} |
|
} |
|
} |
|
function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) { |
|
var oldStartIdx = 0; |
|
var newStartIdx = 0; |
|
var oldEndIdx = oldCh.length - 1; |
|
var oldStartVnode = oldCh[0]; |
|
var oldEndVnode = oldCh[oldEndIdx]; |
|
var newEndIdx = newCh.length - 1; |
|
var newStartVnode = newCh[0]; |
|
var newEndVnode = newCh[newEndIdx]; |
|
var oldKeyToIdx = void 0; |
|
var idxInOld = void 0; |
|
var elmToMove = void 0; |
|
var before = void 0; |
|
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { |
|
if (oldStartVnode == null) { |
|
oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left |
|
} else if (oldEndVnode == null) { |
|
oldEndVnode = oldCh[--oldEndIdx]; |
|
} else if (newStartVnode == null) { |
|
newStartVnode = newCh[++newStartIdx]; |
|
} else if (newEndVnode == null) { |
|
newEndVnode = newCh[--newEndIdx]; |
|
} else if (sameVnode(oldStartVnode, newStartVnode)) { |
|
patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue); |
|
oldStartVnode = oldCh[++oldStartIdx]; |
|
newStartVnode = newCh[++newStartIdx]; |
|
} else if (sameVnode(oldEndVnode, newEndVnode)) { |
|
patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue); |
|
oldEndVnode = oldCh[--oldEndIdx]; |
|
newEndVnode = newCh[--newEndIdx]; |
|
} else if (sameVnode(oldStartVnode, newEndVnode)) { |
|
// Vnode moved right |
|
patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue); |
|
api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm)); |
|
oldStartVnode = oldCh[++oldStartIdx]; |
|
newEndVnode = newCh[--newEndIdx]; |
|
} else if (sameVnode(oldEndVnode, newStartVnode)) { |
|
// Vnode moved left |
|
patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue); |
|
api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); |
|
oldEndVnode = oldCh[--oldEndIdx]; |
|
newStartVnode = newCh[++newStartIdx]; |
|
} else { |
|
if (oldKeyToIdx === undefined) { |
|
oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); |
|
} |
|
idxInOld = oldKeyToIdx[newStartVnode.key]; |
|
if (isUndef(idxInOld)) { |
|
// New element |
|
api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm); |
|
} else { |
|
elmToMove = oldCh[idxInOld]; |
|
if (elmToMove.sel !== newStartVnode.sel) { |
|
api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm); |
|
} else { |
|
patchVnode(elmToMove, newStartVnode, insertedVnodeQueue); |
|
oldCh[idxInOld] = undefined; |
|
api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm); |
|
} |
|
} |
|
newStartVnode = newCh[++newStartIdx]; |
|
} |
|
} |
|
if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) { |
|
if (oldStartIdx > oldEndIdx) { |
|
before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm; |
|
addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue); |
|
} else { |
|
removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx); |
|
} |
|
} |
|
} |
|
function patchVnode(oldVnode, vnode, insertedVnodeQueue) { |
|
var _a, _b, _c, _d, _e; |
|
var hook = (_a = vnode.data) === null || _a === void 0 ? void 0 : _a.hook; |
|
(_b = hook === null || hook === void 0 ? void 0 : hook.prepatch) === null || _b === void 0 ? void 0 : _b.call(hook, oldVnode, vnode); |
|
var elm = vnode.elm = oldVnode.elm; |
|
var oldCh = oldVnode.children; |
|
var ch = vnode.children; |
|
if (oldVnode === vnode) return; |
|
if (vnode.data !== undefined) { |
|
for (var _i3 = 0; _i3 < cbs.update.length; ++_i3) { |
|
cbs.update[_i3](oldVnode, vnode); |
|
}(_d = (_c = vnode.data.hook) === null || _c === void 0 ? void 0 : _c.update) === null || _d === void 0 ? void 0 : _d.call(_c, oldVnode, vnode); |
|
} |
|
if (isUndef(vnode.text)) { |
|
if (isDef(oldCh) && isDef(ch)) { |
|
if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue); |
|
} else if (isDef(ch)) { |
|
if (isDef(oldVnode.text)) api.setTextContent(elm, ""); |
|
addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue); |
|
} else if (isDef(oldCh)) { |
|
removeVnodes(elm, oldCh, 0, oldCh.length - 1); |
|
} else if (isDef(oldVnode.text)) { |
|
api.setTextContent(elm, ""); |
|
} |
|
} else if (oldVnode.text !== vnode.text) { |
|
if (isDef(oldCh)) { |
|
removeVnodes(elm, oldCh, 0, oldCh.length - 1); |
|
} |
|
api.setTextContent(elm, vnode.text); |
|
} |
|
(_e = hook === null || hook === void 0 ? void 0 : hook.postpatch) === null || _e === void 0 ? void 0 : _e.call(hook, oldVnode, vnode); |
|
} |
|
return function patch(oldVnode, vnode) { |
|
var i = void 0, |
|
elm = void 0, |
|
parent = void 0; |
|
var insertedVnodeQueue = []; |
|
for (i = 0; i < cbs.pre.length; ++i) { |
|
cbs.pre[i](); |
|
}if (!isVnode(oldVnode)) { |
|
oldVnode = emptyNodeAt(oldVnode); |
|
} |
|
if (sameVnode(oldVnode, vnode)) { |
|
patchVnode(oldVnode, vnode, insertedVnodeQueue); |
|
} else { |
|
elm = oldVnode.elm; |
|
parent = api.parentNode(elm); |
|
createElm(vnode, insertedVnodeQueue); |
|
if (parent !== null) { |
|
api.insertBefore(parent, vnode.elm, api.nextSibling(elm)); |
|
removeVnodes(parent, [oldVnode], 0, 0); |
|
} |
|
} |
|
for (i = 0; i < insertedVnodeQueue.length; ++i) { |
|
insertedVnodeQueue[i].data.hook.insert(insertedVnodeQueue[i]); |
|
} |
|
for (i = 0; i < cbs.post.length; ++i) { |
|
cbs.post[i](); |
|
}return vnode; |
|
}; |
|
} |
|
|
|
function addNS(data, children, sel) { |
|
data.ns = "http://www.w3.org/2000/svg"; |
|
if (sel !== "foreignObject" && children !== undefined) { |
|
for (var i = 0; i < children.length; ++i) { |
|
var childData = children[i].data; |
|
if (childData !== undefined) { |
|
addNS(childData, children[i].children, children[i].sel); |
|
} |
|
} |
|
} |
|
} |
|
function h(sel, b, c) { |
|
var data = {}; |
|
var children = void 0; |
|
var text = void 0; |
|
var i = void 0; |
|
if (c !== undefined) { |
|
if (b !== null) { |
|
data = b; |
|
} |
|
if (array(c)) { |
|
children = c; |
|
} else if (primitive(c)) { |
|
text = c; |
|
} else if (c && c.sel) { |
|
children = [c]; |
|
} |
|
} else if (b !== undefined && b !== null) { |
|
if (array(b)) { |
|
children = b; |
|
} else if (primitive(b)) { |
|
text = b; |
|
} else if (b && b.sel) { |
|
children = [b]; |
|
} else { |
|
data = b; |
|
} |
|
} |
|
if (children !== undefined) { |
|
for (i = 0; i < children.length; ++i) { |
|
if (primitive(children[i])) children[i] = vnode(undefined, undefined, undefined, children[i], undefined); |
|
} |
|
} |
|
if (sel[0] === "s" && sel[1] === "v" && sel[2] === "g" && (sel.length === 3 || sel[3] === "." || sel[3] === "#")) { |
|
addNS(data, children, sel); |
|
} |
|
return vnode(sel, data, children, text, undefined); |
|
} |
|
|
|
function copyToThunk(vnode, thunk) { |
|
vnode.data.fn = thunk.data.fn; |
|
vnode.data.args = thunk.data.args; |
|
thunk.data = vnode.data; |
|
thunk.children = vnode.children; |
|
thunk.text = vnode.text; |
|
thunk.elm = vnode.elm; |
|
} |
|
function init$1(thunk) { |
|
var cur = thunk.data; |
|
var vnode = cur.fn.apply(undefined, cur.args); |
|
copyToThunk(vnode, thunk); |
|
} |
|
function prepatch(oldVnode, thunk) { |
|
var i = void 0; |
|
var old = oldVnode.data; |
|
var cur = thunk.data; |
|
var oldArgs = old.args; |
|
var args = cur.args; |
|
if (old.fn !== cur.fn || oldArgs.length !== args.length) { |
|
copyToThunk(cur.fn.apply(undefined, args), thunk); |
|
return; |
|
} |
|
for (i = 0; i < args.length; ++i) { |
|
if (oldArgs[i] !== args[i]) { |
|
copyToThunk(cur.fn.apply(undefined, args), thunk); |
|
return; |
|
} |
|
} |
|
copyToThunk(oldVnode, thunk); |
|
} |
|
var thunk = function thunk(sel, key, fn, args) { |
|
if (args === undefined) { |
|
args = fn; |
|
fn = key; |
|
key = undefined; |
|
} |
|
return h(sel, { |
|
key: key, |
|
hook: { init: init$1, prepatch: prepatch }, |
|
fn: fn, |
|
args: args |
|
}); |
|
}; |
|
|
|
function pre(vnode, newVnode) { |
|
var attachData = vnode.data.attachData; |
|
// Copy created placeholder and real element from old vnode |
|
newVnode.data.attachData.placeholder = attachData.placeholder; |
|
newVnode.data.attachData.real = attachData.real; |
|
// Mount real element in vnode so the patch process operates on it |
|
vnode.elm = vnode.data.attachData.real; |
|
} |
|
function post(_, vnode) { |
|
// Mount dummy placeholder in vnode so potential reorders use it |
|
vnode.elm = vnode.data.attachData.placeholder; |
|
} |
|
function destroy(vnode) { |
|
// Remove placeholder |
|
if (vnode.elm !== undefined) { |
|
vnode.elm.parentNode.removeChild(vnode.elm); |
|
} |
|
// Remove real element from where it was inserted |
|
vnode.elm = vnode.data.attachData.real; |
|
} |
|
function create(_, vnode) { |
|
var real = vnode.elm; |
|
var attachData = vnode.data.attachData; |
|
var placeholder = document.createElement("span"); |
|
// Replace actual element with dummy placeholder |
|
// Snabbdom will then insert placeholder instead |
|
vnode.elm = placeholder; |
|
attachData.target.appendChild(real); |
|
attachData.real = real; |
|
attachData.placeholder = placeholder; |
|
} |
|
function attachTo(target, vnode) { |
|
if (vnode.data === undefined) vnode.data = {}; |
|
if (vnode.data.hook === undefined) vnode.data.hook = {}; |
|
var data = vnode.data; |
|
var hook = vnode.data.hook; |
|
data.attachData = { target: target, placeholder: undefined, real: undefined }; |
|
hook.create = create; |
|
hook.prepatch = pre; |
|
hook.postpatch = post; |
|
hook.destroy = destroy; |
|
return vnode; |
|
} |
|
|
|
function toVNode(node, domApi) { |
|
var api = domApi !== undefined ? domApi : htmlDomApi; |
|
var text = void 0; |
|
if (api.isElement(node)) { |
|
var id = node.id ? "#" + node.id : ""; |
|
var cn = node.getAttribute("class"); |
|
var c = cn ? "." + cn.split(" ").join(".") : ""; |
|
var sel = api.tagName(node).toLowerCase() + id + c; |
|
var attrs = {}; |
|
var children = []; |
|
var name = void 0; |
|
var i = void 0, |
|
n = void 0; |
|
var elmAttrs = node.attributes; |
|
var elmChildren = node.childNodes; |
|
for (i = 0, n = elmAttrs.length; i < n; i++) { |
|
name = elmAttrs[i].nodeName; |
|
if (name !== "id" && name !== "class") { |
|
attrs[name] = elmAttrs[i].nodeValue; |
|
} |
|
} |
|
for (i = 0, n = elmChildren.length; i < n; i++) { |
|
children.push(toVNode(elmChildren[i], domApi)); |
|
} |
|
return vnode(sel, { attrs: attrs }, children, undefined, node); |
|
} else if (api.isText(node)) { |
|
text = api.getTextContent(node); |
|
return vnode(undefined, undefined, undefined, text, node); |
|
} else if (api.isComment(node)) { |
|
text = api.getTextContent(node); |
|
return vnode("!", {}, [], text, node); |
|
} else { |
|
return vnode("", {}, [], undefined, node); |
|
} |
|
} |
|
|
|
var xlinkNS = "http://www.w3.org/1999/xlink"; |
|
var xmlNS = "http://www.w3.org/XML/1998/namespace"; |
|
var colonChar = 58; |
|
var xChar = 120; |
|
function updateAttrs(oldVnode, vnode) { |
|
var key = void 0; |
|
var elm = vnode.elm; |
|
var oldAttrs = oldVnode.data.attrs; |
|
var attrs = vnode.data.attrs; |
|
if (!oldAttrs && !attrs) return; |
|
if (oldAttrs === attrs) return; |
|
oldAttrs = oldAttrs || {}; |
|
attrs = attrs || {}; |
|
// update modified attributes, add new attributes |
|
for (key in attrs) { |
|
var cur = attrs[key]; |
|
var old = oldAttrs[key]; |
|
if (old !== cur) { |
|
if (cur === true) { |
|
elm.setAttribute(key, ""); |
|
} else if (cur === false) { |
|
elm.removeAttribute(key); |
|
} else { |
|
if (key.charCodeAt(0) !== xChar) { |
|
elm.setAttribute(key, cur); |
|
} else if (key.charCodeAt(3) === colonChar) { |
|
// Assume xml namespace |
|
elm.setAttributeNS(xmlNS, key, cur); |
|
} else if (key.charCodeAt(5) === colonChar) { |
|
// Assume xlink namespace |
|
elm.setAttributeNS(xlinkNS, key, cur); |
|
} else { |
|
elm.setAttribute(key, cur); |
|
} |
|
} |
|
} |
|
} |
|
// remove removed attributes |
|
// use `in` operator since the previous `for` iteration uses it (.i.e. add even attributes with undefined value) |
|
// the other option is to remove all attributes with value == undefined |
|
for (key in oldAttrs) { |
|
if (!(key in attrs)) { |
|
elm.removeAttribute(key); |
|
} |
|
} |
|
} |
|
var attributesModule = { create: updateAttrs, update: updateAttrs }; |
|
|
|
function updateClass(oldVnode, vnode) { |
|
var cur = void 0; |
|
var name = void 0; |
|
var elm = vnode.elm; |
|
var oldClass = oldVnode.data["class"]; |
|
var klass = vnode.data["class"]; |
|
if (!oldClass && !klass) return; |
|
if (oldClass === klass) return; |
|
oldClass = oldClass || {}; |
|
klass = klass || {}; |
|
for (name in oldClass) { |
|
if (oldClass[name] && !Object.prototype.hasOwnProperty.call(klass, name)) { |
|
// was `true` and now not provided |
|
elm.classList.remove(name); |
|
} |
|
} |
|
for (name in klass) { |
|
cur = klass[name]; |
|
if (cur !== oldClass[name]) { |
|
elm.classList[cur ? "add" : "remove"](name); |
|
} |
|
} |
|
} |
|
var classModule = { create: updateClass, update: updateClass }; |
|
|
|
var CAPS_REGEX = /[A-Z]/g; |
|
function updateDataset(oldVnode, vnode) { |
|
var elm = vnode.elm; |
|
var oldDataset = oldVnode.data.dataset; |
|
var dataset = vnode.data.dataset; |
|
var key = void 0; |
|
if (!oldDataset && !dataset) return; |
|
if (oldDataset === dataset) return; |
|
oldDataset = oldDataset || {}; |
|
dataset = dataset || {}; |
|
var d = elm.dataset; |
|
for (key in oldDataset) { |
|
if (!dataset[key]) { |
|
if (d) { |
|
if (key in d) { |
|
delete d[key]; |
|
} |
|
} else { |
|
elm.removeAttribute("data-" + key.replace(CAPS_REGEX, "-$&").toLowerCase()); |
|
} |
|
} |
|
} |
|
for (key in dataset) { |
|
if (oldDataset[key] !== dataset[key]) { |
|
if (d) { |
|
d[key] = dataset[key]; |
|
} else { |
|
elm.setAttribute("data-" + key.replace(CAPS_REGEX, "-$&").toLowerCase(), dataset[key]); |
|
} |
|
} |
|
} |
|
} |
|
var datasetModule = { create: updateDataset, update: updateDataset }; |
|
|
|
function invokeHandler(handler, vnode, event) { |
|
if (typeof handler === "function") { |
|
// call function handler |
|
handler.call(vnode, event, vnode); |
|
} else if (typeof handler === "object") { |
|
// call multiple handlers |
|
for (var i = 0; i < handler.length; i++) { |
|
invokeHandler(handler[i], vnode, event); |
|
} |
|
} |
|
} |
|
function handleEvent(event, vnode) { |
|
var name = event.type; |
|
var on = vnode.data.on; |
|
// call event handler(s) if exists |
|
if (on && on[name]) { |
|
invokeHandler(on[name], vnode, event); |
|
} |
|
} |
|
function createListener() { |
|
return function handler(event) { |
|
handleEvent(event, handler.vnode); |
|
}; |
|
} |
|
function updateEventListeners(oldVnode, vnode) { |
|
var oldOn = oldVnode.data.on; |
|
var oldListener = oldVnode.listener; |
|
var oldElm = oldVnode.elm; |
|
var on = vnode && vnode.data.on; |
|
var elm = vnode && vnode.elm; |
|
var name = void 0; |
|
// optimization for reused immutable handlers |
|
if (oldOn === on) { |
|
return; |
|
} |
|
// remove existing listeners which no longer used |
|
if (oldOn && oldListener) { |
|
// if element changed or deleted we remove all existing listeners unconditionally |
|
if (!on) { |
|
for (name in oldOn) { |
|
// remove listener if element was changed or existing listeners removed |
|
oldElm.removeEventListener(name, oldListener, false); |
|
} |
|
} else { |
|
for (name in oldOn) { |
|
// remove listener if existing listener removed |
|
if (!on[name]) { |
|
oldElm.removeEventListener(name, oldListener, false); |
|
} |
|
} |
|
} |
|
} |
|
// add new listeners which has not already attached |
|
if (on) { |
|
// reuse existing listener or create new |
|
var listener = vnode.listener = oldVnode.listener || createListener(); |
|
// update vnode for listener |
|
listener.vnode = vnode; |
|
// if element changed or added we add all needed listeners unconditionally |
|
if (!oldOn) { |
|
for (name in on) { |
|
// add listener if element was changed or new listeners added |
|
elm.addEventListener(name, listener, false); |
|
} |
|
} else { |
|
for (name in on) { |
|
// add listener if new listener added |
|
if (!oldOn[name]) { |
|
elm.addEventListener(name, listener, false); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
var eventListenersModule = { |
|
create: updateEventListeners, |
|
update: updateEventListeners, |
|
destroy: updateEventListeners |
|
}; |
|
|
|
var raf = typeof window !== "undefined" && window.requestAnimationFrame || setTimeout; |
|
var nextFrame = function nextFrame(fn) { |
|
raf(function () { |
|
raf(fn); |
|
}); |
|
}; |
|
function setNextFrame(obj, prop, val) { |
|
nextFrame(function () { |
|
obj[prop] = val; |
|
}); |
|
} |
|
function getTextNodeRect(textNode) { |
|
var rect = void 0; |
|
if (document.createRange) { |
|
var range = document.createRange(); |
|
range.selectNodeContents(textNode); |
|
if (range.getBoundingClientRect) { |
|
rect = range.getBoundingClientRect(); |
|
} |
|
} |
|
return rect; |
|
} |
|
function calcTransformOrigin(isTextNode, textRect, boundingRect) { |
|
if (isTextNode) { |
|
if (textRect) { |
|
// calculate pixels to center of text from left edge of bounding box |
|
var relativeCenterX = textRect.left + textRect.width / 2 - boundingRect.left; |
|
var relativeCenterY = textRect.top + textRect.height / 2 - boundingRect.top; |
|
return relativeCenterX + "px " + relativeCenterY + "px"; |
|
} |
|
} |
|
return "0 0"; // top left |
|
} |
|
function getTextDx(oldTextRect, newTextRect) { |
|
if (oldTextRect && newTextRect) { |
|
return oldTextRect.left + oldTextRect.width / 2 - (newTextRect.left + newTextRect.width / 2); |
|
} |
|
return 0; |
|
} |
|
function getTextDy(oldTextRect, newTextRect) { |
|
if (oldTextRect && newTextRect) { |
|
return oldTextRect.top + oldTextRect.height / 2 - (newTextRect.top + newTextRect.height / 2); |
|
} |
|
return 0; |
|
} |
|
function isTextElement(elm) { |
|
return elm.childNodes.length === 1 && elm.childNodes[0].nodeType === 3; |
|
} |
|
var removed = void 0; |
|
var created = void 0; |
|
function pre$1() { |
|
removed = {}; |
|
created = []; |
|
} |
|
function create$1(oldVnode, vnode) { |
|
var hero = vnode.data.hero; |
|
if (hero && hero.id) { |
|
created.push(hero.id); |
|
created.push(vnode); |
|
} |
|
} |
|
function destroy$1(vnode) { |
|
var hero = vnode.data.hero; |
|
if (hero && hero.id) { |
|
var elm = vnode.elm; |
|
vnode.isTextNode = isTextElement(elm); // is this a text node? |
|
vnode.boundingRect = elm.getBoundingClientRect(); // save the bounding rectangle to a new property on the vnode |
|
vnode.textRect = vnode.isTextNode ? getTextNodeRect(elm.childNodes[0]) : null; // save bounding rect of inner text node |
|
var computedStyle = window.getComputedStyle(elm, undefined); // get current styles (includes inherited properties) |
|
vnode.savedStyle = JSON.parse(JSON.stringify(computedStyle)); // save a copy of computed style values |
|
removed[hero.id] = vnode; |
|
} |
|
} |
|
function post$1() { |
|
var i = void 0, |
|
id = void 0, |
|
newElm = void 0, |
|
oldVnode = void 0, |
|
oldElm = void 0, |
|
hRatio = void 0, |
|
wRatio = void 0, |
|
oldRect = void 0, |
|
newRect = void 0, |
|
dx = void 0, |
|
dy = void 0, |
|
origTransform = void 0, |
|
origTransition = void 0, |
|
newStyle = void 0, |
|
oldStyle = void 0, |
|
newComputedStyle = void 0, |
|
isTextNode = void 0, |
|
newTextRect = void 0, |
|
oldTextRect = void 0; |
|
for (i = 0; i < created.length; i += 2) { |
|
id = created[i]; |
|
newElm = created[i + 1].elm; |
|
oldVnode = removed[id]; |
|
if (oldVnode) { |
|
isTextNode = oldVnode.isTextNode && isTextElement(newElm); // Are old & new both text? |
|
newStyle = newElm.style; |
|
newComputedStyle = window.getComputedStyle(newElm, undefined); // get full computed style for new element |
|
oldElm = oldVnode.elm; |
|
oldStyle = oldElm.style; |
|
// Overall element bounding boxes |
|
newRect = newElm.getBoundingClientRect(); |
|
oldRect = oldVnode.boundingRect; // previously saved bounding rect |
|
// Text node bounding boxes & distances |
|
if (isTextNode) { |
|
newTextRect = getTextNodeRect(newElm.childNodes[0]); |
|
oldTextRect = oldVnode.textRect; |
|
dx = getTextDx(oldTextRect, newTextRect); |
|
dy = getTextDy(oldTextRect, newTextRect); |
|
} else { |
|
// Calculate distances between old & new positions |
|
dx = oldRect.left - newRect.left; |
|
dy = oldRect.top - newRect.top; |
|
} |
|
hRatio = newRect.height / Math.max(oldRect.height, 1); |
|
wRatio = isTextNode ? hRatio : newRect.width / Math.max(oldRect.width, 1); // text scales based on hRatio |
|
// Animate new element |
|
origTransform = newStyle.transform; |
|
origTransition = newStyle.transition; |
|
if (newComputedStyle.display === "inline") { |
|
// inline elements cannot be transformed |
|
newStyle.display = "inline-block"; // this does not appear to have any negative side effects |
|
} |
|
newStyle.transition = origTransition + "transform 0s"; |
|
newStyle.transformOrigin = calcTransformOrigin(isTextNode, newTextRect, newRect); |
|
newStyle.opacity = "0"; |
|
newStyle.transform = origTransform + "translate(" + dx + "px, " + dy + "px) " + "scale(" + 1 / wRatio + ", " + 1 / hRatio + ")"; |
|
setNextFrame(newStyle, "transition", origTransition); |
|
setNextFrame(newStyle, "transform", origTransform); |
|
setNextFrame(newStyle, "opacity", "1"); |
|
// Animate old element |
|
for (var key in oldVnode.savedStyle) { |
|
// re-apply saved inherited properties |
|
if (String(parseInt(key)) !== key) { |
|
var ms = key.substring(0, 2) === "ms"; |
|
var moz = key.substring(0, 3) === "moz"; |
|
var webkit = key.substring(0, 6) === "webkit"; |
|
if (!ms && !moz && !webkit) { |
|
// ignore prefixed style properties |
|
oldStyle[key] = oldVnode.savedStyle[key]; |
|
} |
|
} |
|
} |
|
oldStyle.position = "absolute"; |
|
oldStyle.top = oldRect.top + "px"; // start at existing position |
|
oldStyle.left = oldRect.left + "px"; |
|
oldStyle.width = oldRect.width + "px"; // Needed for elements who were sized relative to their parents |
|
oldStyle.height = oldRect.height + "px"; // Needed for elements who were sized relative to their parents |
|
oldStyle.margin = "0"; // Margin on hero element leads to incorrect positioning |
|
oldStyle.transformOrigin = calcTransformOrigin(isTextNode, oldTextRect, oldRect); |
|
oldStyle.transform = ""; |
|
oldStyle.opacity = "1"; |
|
document.body.appendChild(oldElm); |
|
setNextFrame(oldStyle, "transform", "translate(" + -dx + "px, " + -dy + "px) scale(" + wRatio + ", " + hRatio + ")"); // scale must be on far right for translate to be correct |
|
setNextFrame(oldStyle, "opacity", "0"); |
|
oldElm.addEventListener("transitionend", function (ev) { |
|
if (ev.propertyName === "transform") { |
|
document.body.removeChild(ev.target); |
|
} |
|
}); |
|
} |
|
} |
|
removed = created = undefined; |
|
} |
|
var heroModule = { |
|
pre: pre$1, |
|
create: create$1, |
|
destroy: destroy$1, |
|
post: post$1 |
|
}; |
|
|
|
function updateProps(oldVnode, vnode) { |
|
var key = void 0; |
|
var cur = void 0; |
|
var old = void 0; |
|
var elm = vnode.elm; |
|
var oldProps = oldVnode.data.props; |
|
var props = vnode.data.props; |
|
if (!oldProps && !props) return; |
|
if (oldProps === props) return; |
|
oldProps = oldProps || {}; |
|
props = props || {}; |
|
for (key in props) { |
|
cur = props[key]; |
|
old = oldProps[key]; |
|
if (old !== cur && (key !== "value" || elm[key] !== cur)) { |
|
elm[key] = cur; |
|
} |
|
} |
|
} |
|
var propsModule = { create: updateProps, update: updateProps }; |
|
|
|
// Bindig `requestAnimationFrame` like this fixes a bug in IE/Edge. See #360 and #409. |
|
var raf$1 = typeof window !== "undefined" && (window.requestAnimationFrame && window.requestAnimationFrame.bind(window)) || setTimeout; |
|
var nextFrame$1 = function nextFrame$1(fn) { |
|
raf$1(function () { |
|
raf$1(fn); |
|
}); |
|
}; |
|
var reflowForced = false; |
|
function setNextFrame$1(obj, prop, val) { |
|
nextFrame$1(function () { |
|
obj[prop] = val; |
|
}); |
|
} |
|
function updateStyle(oldVnode, vnode) { |
|
var cur = void 0; |
|
var name = void 0; |
|
var elm = vnode.elm; |
|
var oldStyle = oldVnode.data.style; |
|
var style = vnode.data.style; |
|
if (!oldStyle && !style) return; |
|
if (oldStyle === style) return; |
|
oldStyle = oldStyle || {}; |
|
style = style || {}; |
|
var oldHasDel = "delayed" in oldStyle; |
|
for (name in oldStyle) { |
|
if (!style[name]) { |
|
if (name[0] === "-" && name[1] === "-") { |
|
elm.style.removeProperty(name); |
|
} else { |
|
elm.style[name] = ""; |
|
} |
|
} |
|
} |
|
for (name in style) { |
|
cur = style[name]; |
|
if (name === "delayed" && style.delayed) { |
|
for (var name2 in style.delayed) { |
|
cur = style.delayed[name2]; |
|
if (!oldHasDel || cur !== oldStyle.delayed[name2]) { |
|
setNextFrame$1(elm.style, name2, cur); |
|
} |
|
} |
|
} else if (name !== "remove" && cur !== oldStyle[name]) { |
|
if (name[0] === "-" && name[1] === "-") { |
|
elm.style.setProperty(name, cur); |
|
} else { |
|
elm.style[name] = cur; |
|
} |
|
} |
|
} |
|
} |
|
function applyDestroyStyle(vnode) { |
|
var style = void 0; |
|
var name = void 0; |
|
var elm = vnode.elm; |
|
var s = vnode.data.style; |
|
if (!s || !(style = s.destroy)) return; |
|
for (name in style) { |
|
elm.style[name] = style[name]; |
|
} |
|
} |
|
function applyRemoveStyle(vnode, rm) { |
|
var s = vnode.data.style; |
|
if (!s || !s.remove) { |
|
rm(); |
|
return; |
|
} |
|
if (!reflowForced) { |
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions |
|
vnode.elm.offsetLeft; |
|
reflowForced = true; |
|
} |
|
var name = void 0; |
|
var elm = vnode.elm; |
|
var i = 0; |
|
var style = s.remove; |
|
var amount = 0; |
|
var applied = []; |
|
for (name in style) { |
|
applied.push(name); |
|
elm.style[name] = style[name]; |
|
} |
|
var compStyle = getComputedStyle(elm); |
|
var props = compStyle["transition-property"].split(", "); |
|
for (; i < props.length; ++i) { |
|
if (applied.indexOf(props[i]) !== -1) amount++; |
|
} |
|
elm.addEventListener("transitionend", function (ev) { |
|
if (ev.target === elm) --amount; |
|
if (amount === 0) rm(); |
|
}); |
|
} |
|
function forceReflow() { |
|
reflowForced = false; |
|
} |
|
var styleModule = { |
|
pre: forceReflow, |
|
create: updateStyle, |
|
update: updateStyle, |
|
destroy: applyDestroyStyle, |
|
remove: applyRemoveStyle |
|
}; |
|
|
|
exports.array = array; |
|
exports.attachTo = attachTo; |
|
exports.attributesModule = attributesModule; |
|
exports.classModule = classModule; |
|
exports.datasetModule = datasetModule; |
|
exports.eventListenersModule = eventListenersModule; |
|
exports.h = h; |
|
exports.heroModule = heroModule; |
|
exports.htmlDomApi = htmlDomApi; |
|
exports.init = init; |
|
exports.primitive = primitive; |
|
exports.propsModule = propsModule; |
|
exports.styleModule = styleModule; |
|
exports.thunk = thunk; |
|
exports.toVNode = toVNode; |
|
exports.vnode = vnode; |
|
|
|
exports.__esModule = true; |
|
});
|
|
|