Add supporting themes required for Lotusdocs
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
import morph from '../src/index.js'
|
||||
|
||||
document.addEventListener('alpine:init', () => {
|
||||
window.Alpine.plugin(morph)
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
import morph from '../src/index.js'
|
||||
|
||||
export default morph
|
||||
|
||||
export { morph }
|
||||
343
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/dist/cdn.js
vendored
Normal file
343
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/dist/cdn.js
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
(() => {
|
||||
// packages/morph/src/morph.js
|
||||
function morph(from, toHtml, options) {
|
||||
monkeyPatchDomSetAttributeToAllowAtSymbols();
|
||||
let fromEl;
|
||||
let toEl;
|
||||
let key, lookahead, updating, updated, removing, removed, adding, added;
|
||||
function assignOptions(options2 = {}) {
|
||||
let defaultGetKey = (el) => el.getAttribute("key");
|
||||
let noop = () => {
|
||||
};
|
||||
updating = options2.updating || noop;
|
||||
updated = options2.updated || noop;
|
||||
removing = options2.removing || noop;
|
||||
removed = options2.removed || noop;
|
||||
adding = options2.adding || noop;
|
||||
added = options2.added || noop;
|
||||
key = options2.key || defaultGetKey;
|
||||
lookahead = options2.lookahead || false;
|
||||
}
|
||||
function patch(from2, to) {
|
||||
if (differentElementNamesTypesOrKeys(from2, to)) {
|
||||
return swapElements(from2, to);
|
||||
}
|
||||
let updateChildrenOnly = false;
|
||||
if (shouldSkip(updating, from2, to, () => updateChildrenOnly = true))
|
||||
return;
|
||||
if (from2.nodeType === 1 && window.Alpine) {
|
||||
window.Alpine.cloneNode(from2, to);
|
||||
}
|
||||
if (textOrComment(to)) {
|
||||
patchNodeValue(from2, to);
|
||||
updated(from2, to);
|
||||
return;
|
||||
}
|
||||
if (!updateChildrenOnly) {
|
||||
patchAttributes(from2, to);
|
||||
}
|
||||
updated(from2, to);
|
||||
patchChildren(from2, to);
|
||||
}
|
||||
function differentElementNamesTypesOrKeys(from2, to) {
|
||||
return from2.nodeType != to.nodeType || from2.nodeName != to.nodeName || getKey(from2) != getKey(to);
|
||||
}
|
||||
function swapElements(from2, to) {
|
||||
if (shouldSkip(removing, from2))
|
||||
return;
|
||||
let toCloned = to.cloneNode(true);
|
||||
if (shouldSkip(adding, toCloned))
|
||||
return;
|
||||
from2.replaceWith(toCloned);
|
||||
removed(from2);
|
||||
added(toCloned);
|
||||
}
|
||||
function patchNodeValue(from2, to) {
|
||||
let value = to.nodeValue;
|
||||
if (from2.nodeValue !== value) {
|
||||
from2.nodeValue = value;
|
||||
}
|
||||
}
|
||||
function patchAttributes(from2, to) {
|
||||
if (from2._x_transitioning)
|
||||
return;
|
||||
if (from2._x_isShown && !to._x_isShown) {
|
||||
return;
|
||||
}
|
||||
if (!from2._x_isShown && to._x_isShown) {
|
||||
return;
|
||||
}
|
||||
let domAttributes = Array.from(from2.attributes);
|
||||
let toAttributes = Array.from(to.attributes);
|
||||
for (let i = domAttributes.length - 1; i >= 0; i--) {
|
||||
let name = domAttributes[i].name;
|
||||
if (!to.hasAttribute(name)) {
|
||||
from2.removeAttribute(name);
|
||||
}
|
||||
}
|
||||
for (let i = toAttributes.length - 1; i >= 0; i--) {
|
||||
let name = toAttributes[i].name;
|
||||
let value = toAttributes[i].value;
|
||||
if (from2.getAttribute(name) !== value) {
|
||||
from2.setAttribute(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
function patchChildren(from2, to) {
|
||||
if (from2._x_teleport)
|
||||
from2 = from2._x_teleport;
|
||||
if (to._x_teleport)
|
||||
to = to._x_teleport;
|
||||
let fromKeys = keyToMap(from2.children);
|
||||
let fromKeyHoldovers = {};
|
||||
let currentTo = getFirstNode(to);
|
||||
let currentFrom = getFirstNode(from2);
|
||||
while (currentTo) {
|
||||
seedingMatchingId(currentTo, currentFrom);
|
||||
let toKey = getKey(currentTo);
|
||||
let fromKey = getKey(currentFrom);
|
||||
if (!currentFrom) {
|
||||
if (toKey && fromKeyHoldovers[toKey]) {
|
||||
let holdover = fromKeyHoldovers[toKey];
|
||||
from2.appendChild(holdover);
|
||||
currentFrom = holdover;
|
||||
} else {
|
||||
if (!shouldSkip(adding, currentTo)) {
|
||||
let clone = currentTo.cloneNode(true);
|
||||
from2.appendChild(clone);
|
||||
added(clone);
|
||||
}
|
||||
currentTo = getNextSibling(to, currentTo);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let isIf = (node) => node && node.nodeType === 8 && node.textContent === "[if BLOCK]><![endif]";
|
||||
let isEnd = (node) => node && node.nodeType === 8 && node.textContent === "[if ENDBLOCK]><![endif]";
|
||||
if (isIf(currentTo) && isIf(currentFrom)) {
|
||||
let nestedIfCount = 0;
|
||||
let fromBlockStart = currentFrom;
|
||||
while (currentFrom) {
|
||||
let next = getNextSibling(from2, currentFrom);
|
||||
if (isIf(next)) {
|
||||
nestedIfCount++;
|
||||
} else if (isEnd(next) && nestedIfCount > 0) {
|
||||
nestedIfCount--;
|
||||
} else if (isEnd(next) && nestedIfCount === 0) {
|
||||
currentFrom = next;
|
||||
break;
|
||||
}
|
||||
currentFrom = next;
|
||||
}
|
||||
let fromBlockEnd = currentFrom;
|
||||
nestedIfCount = 0;
|
||||
let toBlockStart = currentTo;
|
||||
while (currentTo) {
|
||||
let next = getNextSibling(to, currentTo);
|
||||
if (isIf(next)) {
|
||||
nestedIfCount++;
|
||||
} else if (isEnd(next) && nestedIfCount > 0) {
|
||||
nestedIfCount--;
|
||||
} else if (isEnd(next) && nestedIfCount === 0) {
|
||||
currentTo = next;
|
||||
break;
|
||||
}
|
||||
currentTo = next;
|
||||
}
|
||||
let toBlockEnd = currentTo;
|
||||
let fromBlock = new Block(fromBlockStart, fromBlockEnd);
|
||||
let toBlock = new Block(toBlockStart, toBlockEnd);
|
||||
patchChildren(fromBlock, toBlock);
|
||||
continue;
|
||||
}
|
||||
if (currentFrom.nodeType === 1 && lookahead && !currentFrom.isEqualNode(currentTo)) {
|
||||
let nextToElementSibling = getNextSibling(to, currentTo);
|
||||
let found = false;
|
||||
while (!found && nextToElementSibling) {
|
||||
if (nextToElementSibling.nodeType === 1 && currentFrom.isEqualNode(nextToElementSibling)) {
|
||||
found = true;
|
||||
currentFrom = addNodeBefore(from2, currentTo, currentFrom);
|
||||
fromKey = getKey(currentFrom);
|
||||
}
|
||||
nextToElementSibling = getNextSibling(to, nextToElementSibling);
|
||||
}
|
||||
}
|
||||
if (toKey !== fromKey) {
|
||||
if (!toKey && fromKey) {
|
||||
fromKeyHoldovers[fromKey] = currentFrom;
|
||||
currentFrom = addNodeBefore(from2, currentTo, currentFrom);
|
||||
fromKeyHoldovers[fromKey].remove();
|
||||
currentFrom = getNextSibling(from2, currentFrom);
|
||||
currentTo = getNextSibling(to, currentTo);
|
||||
continue;
|
||||
}
|
||||
if (toKey && !fromKey) {
|
||||
if (fromKeys[toKey]) {
|
||||
currentFrom.replaceWith(fromKeys[toKey]);
|
||||
currentFrom = fromKeys[toKey];
|
||||
}
|
||||
}
|
||||
if (toKey && fromKey) {
|
||||
let fromKeyNode = fromKeys[toKey];
|
||||
if (fromKeyNode) {
|
||||
fromKeyHoldovers[fromKey] = currentFrom;
|
||||
currentFrom.replaceWith(fromKeyNode);
|
||||
currentFrom = fromKeyNode;
|
||||
} else {
|
||||
fromKeyHoldovers[fromKey] = currentFrom;
|
||||
currentFrom = addNodeBefore(from2, currentTo, currentFrom);
|
||||
fromKeyHoldovers[fromKey].remove();
|
||||
currentFrom = getNextSibling(from2, currentFrom);
|
||||
currentTo = getNextSibling(to, currentTo);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
let currentFromNext = currentFrom && getNextSibling(from2, currentFrom);
|
||||
patch(currentFrom, currentTo);
|
||||
currentTo = currentTo && getNextSibling(to, currentTo);
|
||||
currentFrom = currentFromNext;
|
||||
}
|
||||
let removals = [];
|
||||
while (currentFrom) {
|
||||
if (!shouldSkip(removing, currentFrom))
|
||||
removals.push(currentFrom);
|
||||
currentFrom = getNextSibling(from2, currentFrom);
|
||||
}
|
||||
while (removals.length) {
|
||||
let domForRemoval = removals.shift();
|
||||
domForRemoval.remove();
|
||||
removed(domForRemoval);
|
||||
}
|
||||
}
|
||||
function getKey(el) {
|
||||
return el && el.nodeType === 1 && key(el);
|
||||
}
|
||||
function keyToMap(els) {
|
||||
let map = {};
|
||||
for (let el of els) {
|
||||
let theKey = getKey(el);
|
||||
if (theKey) {
|
||||
map[theKey] = el;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
function addNodeBefore(parent, node, beforeMe) {
|
||||
if (!shouldSkip(adding, node)) {
|
||||
let clone = node.cloneNode(true);
|
||||
parent.insertBefore(clone, beforeMe);
|
||||
added(clone);
|
||||
return clone;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
assignOptions(options);
|
||||
fromEl = from;
|
||||
toEl = typeof toHtml === "string" ? createElement(toHtml) : toHtml;
|
||||
if (window.Alpine && window.Alpine.closestDataStack && !from._x_dataStack) {
|
||||
toEl._x_dataStack = window.Alpine.closestDataStack(from);
|
||||
toEl._x_dataStack && window.Alpine.cloneNode(from, toEl);
|
||||
}
|
||||
patch(from, toEl);
|
||||
fromEl = void 0;
|
||||
toEl = void 0;
|
||||
return from;
|
||||
}
|
||||
morph.step = () => {
|
||||
};
|
||||
morph.log = () => {
|
||||
};
|
||||
function shouldSkip(hook, ...args) {
|
||||
let skip = false;
|
||||
hook(...args, () => skip = true);
|
||||
return skip;
|
||||
}
|
||||
var patched = false;
|
||||
function createElement(html) {
|
||||
const template = document.createElement("template");
|
||||
template.innerHTML = html;
|
||||
return template.content.firstElementChild;
|
||||
}
|
||||
function textOrComment(el) {
|
||||
return el.nodeType === 3 || el.nodeType === 8;
|
||||
}
|
||||
var Block = class {
|
||||
constructor(start, end) {
|
||||
this.startComment = start;
|
||||
this.endComment = end;
|
||||
}
|
||||
get children() {
|
||||
let children = [];
|
||||
let currentNode = this.startComment.nextSibling;
|
||||
while (currentNode && currentNode !== this.endComment) {
|
||||
children.push(currentNode);
|
||||
currentNode = currentNode.nextSibling;
|
||||
}
|
||||
return children;
|
||||
}
|
||||
appendChild(child) {
|
||||
this.endComment.before(child);
|
||||
}
|
||||
get firstChild() {
|
||||
let first = this.startComment.nextSibling;
|
||||
if (first === this.endComment)
|
||||
return;
|
||||
return first;
|
||||
}
|
||||
nextNode(reference) {
|
||||
let next = reference.nextSibling;
|
||||
if (next === this.endComment)
|
||||
return;
|
||||
return next;
|
||||
}
|
||||
insertBefore(newNode, reference) {
|
||||
reference.before(newNode);
|
||||
return newNode;
|
||||
}
|
||||
};
|
||||
function getFirstNode(parent) {
|
||||
return parent.firstChild;
|
||||
}
|
||||
function getNextSibling(parent, reference) {
|
||||
let next;
|
||||
if (parent instanceof Block) {
|
||||
next = parent.nextNode(reference);
|
||||
} else {
|
||||
next = reference.nextSibling;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
function monkeyPatchDomSetAttributeToAllowAtSymbols() {
|
||||
if (patched)
|
||||
return;
|
||||
patched = true;
|
||||
let original = Element.prototype.setAttribute;
|
||||
let hostDiv = document.createElement("div");
|
||||
Element.prototype.setAttribute = function newSetAttribute(name, value) {
|
||||
if (!name.includes("@")) {
|
||||
return original.call(this, name, value);
|
||||
}
|
||||
hostDiv.innerHTML = `<span ${name}="${value}"></span>`;
|
||||
let attr = hostDiv.firstElementChild.getAttributeNode(name);
|
||||
hostDiv.firstElementChild.removeAttributeNode(attr);
|
||||
this.setAttributeNode(attr);
|
||||
};
|
||||
}
|
||||
function seedingMatchingId(to, from) {
|
||||
let fromId = from && from._x_bindings && from._x_bindings.id;
|
||||
if (!fromId)
|
||||
return;
|
||||
to.setAttribute("id", fromId);
|
||||
to.id = fromId;
|
||||
}
|
||||
|
||||
// packages/morph/src/index.js
|
||||
function src_default(Alpine) {
|
||||
Alpine.morph = morph;
|
||||
}
|
||||
|
||||
// packages/morph/builds/cdn.js
|
||||
document.addEventListener("alpine:init", () => {
|
||||
window.Alpine.plugin(src_default);
|
||||
});
|
||||
})();
|
||||
1
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/dist/cdn.min.js
vendored
Normal file
1
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/dist/cdn.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
(()=>{function k(u,l,o){Y();let g,h,y,B,O,E,v,T,_,A;function V(e={}){let n=a=>a.getAttribute("key"),d=()=>{};O=e.updating||d,E=e.updated||d,v=e.removing||d,T=e.removed||d,_=e.adding||d,A=e.added||d,y=e.key||n,B=e.lookahead||!1}function D(e,n){if(W(e,n))return q(e,n);let d=!1;if(!b(O,e,n,()=>d=!0)){if(e.nodeType===1&&window.Alpine&&window.Alpine.cloneNode(e,n),X(n)){$(e,n),E(e,n);return}d||G(e,n),E(e,n),L(e,n)}}function W(e,n){return e.nodeType!=n.nodeType||e.nodeName!=n.nodeName||x(e)!=x(n)}function q(e,n){if(b(v,e))return;let d=n.cloneNode(!0);b(_,d)||(e.replaceWith(d),T(e),A(d))}function $(e,n){let d=n.nodeValue;e.nodeValue!==d&&(e.nodeValue=d)}function G(e,n){if(e._x_transitioning||e._x_isShown&&!n._x_isShown||!e._x_isShown&&n._x_isShown)return;let d=Array.from(e.attributes),a=Array.from(n.attributes);for(let i=d.length-1;i>=0;i--){let t=d[i].name;n.hasAttribute(t)||e.removeAttribute(t)}for(let i=a.length-1;i>=0;i--){let t=a[i].name,m=a[i].value;e.getAttribute(t)!==m&&e.setAttribute(t,m)}}function L(e,n){e._x_teleport&&(e=e._x_teleport),n._x_teleport&&(n=n._x_teleport);let d=H(e.children),a={},i=I(n),t=I(e);for(;i;){Z(i,t);let s=x(i),p=x(t);if(!t)if(s&&a[s]){let r=a[s];e.appendChild(r),t=r}else{if(!b(_,i)){let r=i.cloneNode(!0);e.appendChild(r),A(r)}i=c(n,i);continue}let C=r=>r&&r.nodeType===8&&r.textContent==="[if BLOCK]><![endif]",S=r=>r&&r.nodeType===8&&r.textContent==="[if ENDBLOCK]><![endif]";if(C(i)&&C(t)){let r=0,N=t;for(;t;){let f=c(e,t);if(C(f))r++;else if(S(f)&&r>0)r--;else if(S(f)&&r===0){t=f;break}t=f}let R=t;r=0;let j=i;for(;i;){let f=c(n,i);if(C(f))r++;else if(S(f)&&r>0)r--;else if(S(f)&&r===0){i=f;break}i=f}let z=i,J=new w(N,R),Q=new w(j,z);L(J,Q);continue}if(t.nodeType===1&&B&&!t.isEqualNode(i)){let r=c(n,i),N=!1;for(;!N&&r;)r.nodeType===1&&t.isEqualNode(r)&&(N=!0,t=K(e,i,t),p=x(t)),r=c(n,r)}if(s!==p){if(!s&&p){a[p]=t,t=K(e,i,t),a[p].remove(),t=c(e,t),i=c(n,i);continue}if(s&&!p&&d[s]&&(t.replaceWith(d[s]),t=d[s]),s&&p){let r=d[s];if(r)a[p]=t,t.replaceWith(r),t=r;else{a[p]=t,t=K(e,i,t),a[p].remove(),t=c(e,t),i=c(n,i);continue}}}let P=t&&c(e,t);D(t,i),i=i&&c(n,i),t=P}let m=[];for(;t;)b(v,t)||m.push(t),t=c(e,t);for(;m.length;){let s=m.shift();s.remove(),T(s)}}function x(e){return e&&e.nodeType===1&&y(e)}function H(e){let n={};for(let d of e){let a=x(d);a&&(n[a]=d)}return n}function K(e,n,d){if(!b(_,n)){let a=n.cloneNode(!0);return e.insertBefore(a,d),A(a),a}return n}return V(o),g=u,h=typeof l=="string"?U(l):l,window.Alpine&&window.Alpine.closestDataStack&&!u._x_dataStack&&(h._x_dataStack=window.Alpine.closestDataStack(u),h._x_dataStack&&window.Alpine.cloneNode(u,h)),D(u,h),g=void 0,h=void 0,u}k.step=()=>{};k.log=()=>{};function b(u,...l){let o=!1;return u(...l,()=>o=!0),o}var F=!1;function U(u){let l=document.createElement("template");return l.innerHTML=u,l.content.firstElementChild}function X(u){return u.nodeType===3||u.nodeType===8}var w=class{constructor(l,o){this.startComment=l,this.endComment=o}get children(){let l=[],o=this.startComment.nextSibling;for(;o&&o!==this.endComment;)l.push(o),o=o.nextSibling;return l}appendChild(l){this.endComment.before(l)}get firstChild(){let l=this.startComment.nextSibling;if(l!==this.endComment)return l}nextNode(l){let o=l.nextSibling;if(o!==this.endComment)return o}insertBefore(l,o){return o.before(l),l}};function I(u){return u.firstChild}function c(u,l){let o;return u instanceof w?o=u.nextNode(l):o=l.nextSibling,o}function Y(){if(F)return;F=!0;let u=Element.prototype.setAttribute,l=document.createElement("div");Element.prototype.setAttribute=function(g,h){if(!g.includes("@"))return u.call(this,g,h);l.innerHTML=`<span ${g}="${h}"></span>`;let y=l.firstElementChild.getAttributeNode(g);l.firstElementChild.removeAttributeNode(y),this.setAttributeNode(y)}}function Z(u,l){let o=l&&l._x_bindings&&l._x_bindings.id;o&&(u.setAttribute("id",o),u.id=o)}function M(u){u.morph=k}document.addEventListener("alpine:init",()=>{window.Alpine.plugin(M)});})();
|
||||
369
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/dist/module.cjs.js
vendored
Normal file
369
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/dist/module.cjs.js
vendored
Normal file
@@ -0,0 +1,369 @@
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// packages/morph/builds/module.js
|
||||
var module_exports = {};
|
||||
__export(module_exports, {
|
||||
default: () => module_default,
|
||||
morph: () => src_default
|
||||
});
|
||||
module.exports = __toCommonJS(module_exports);
|
||||
|
||||
// packages/morph/src/morph.js
|
||||
function morph(from, toHtml, options) {
|
||||
monkeyPatchDomSetAttributeToAllowAtSymbols();
|
||||
let fromEl;
|
||||
let toEl;
|
||||
let key, lookahead, updating, updated, removing, removed, adding, added;
|
||||
function assignOptions(options2 = {}) {
|
||||
let defaultGetKey = (el) => el.getAttribute("key");
|
||||
let noop = () => {
|
||||
};
|
||||
updating = options2.updating || noop;
|
||||
updated = options2.updated || noop;
|
||||
removing = options2.removing || noop;
|
||||
removed = options2.removed || noop;
|
||||
adding = options2.adding || noop;
|
||||
added = options2.added || noop;
|
||||
key = options2.key || defaultGetKey;
|
||||
lookahead = options2.lookahead || false;
|
||||
}
|
||||
function patch(from2, to) {
|
||||
if (differentElementNamesTypesOrKeys(from2, to)) {
|
||||
return swapElements(from2, to);
|
||||
}
|
||||
let updateChildrenOnly = false;
|
||||
if (shouldSkip(updating, from2, to, () => updateChildrenOnly = true))
|
||||
return;
|
||||
if (from2.nodeType === 1 && window.Alpine) {
|
||||
window.Alpine.cloneNode(from2, to);
|
||||
}
|
||||
if (textOrComment(to)) {
|
||||
patchNodeValue(from2, to);
|
||||
updated(from2, to);
|
||||
return;
|
||||
}
|
||||
if (!updateChildrenOnly) {
|
||||
patchAttributes(from2, to);
|
||||
}
|
||||
updated(from2, to);
|
||||
patchChildren(from2, to);
|
||||
}
|
||||
function differentElementNamesTypesOrKeys(from2, to) {
|
||||
return from2.nodeType != to.nodeType || from2.nodeName != to.nodeName || getKey(from2) != getKey(to);
|
||||
}
|
||||
function swapElements(from2, to) {
|
||||
if (shouldSkip(removing, from2))
|
||||
return;
|
||||
let toCloned = to.cloneNode(true);
|
||||
if (shouldSkip(adding, toCloned))
|
||||
return;
|
||||
from2.replaceWith(toCloned);
|
||||
removed(from2);
|
||||
added(toCloned);
|
||||
}
|
||||
function patchNodeValue(from2, to) {
|
||||
let value = to.nodeValue;
|
||||
if (from2.nodeValue !== value) {
|
||||
from2.nodeValue = value;
|
||||
}
|
||||
}
|
||||
function patchAttributes(from2, to) {
|
||||
if (from2._x_transitioning)
|
||||
return;
|
||||
if (from2._x_isShown && !to._x_isShown) {
|
||||
return;
|
||||
}
|
||||
if (!from2._x_isShown && to._x_isShown) {
|
||||
return;
|
||||
}
|
||||
let domAttributes = Array.from(from2.attributes);
|
||||
let toAttributes = Array.from(to.attributes);
|
||||
for (let i = domAttributes.length - 1; i >= 0; i--) {
|
||||
let name = domAttributes[i].name;
|
||||
if (!to.hasAttribute(name)) {
|
||||
from2.removeAttribute(name);
|
||||
}
|
||||
}
|
||||
for (let i = toAttributes.length - 1; i >= 0; i--) {
|
||||
let name = toAttributes[i].name;
|
||||
let value = toAttributes[i].value;
|
||||
if (from2.getAttribute(name) !== value) {
|
||||
from2.setAttribute(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
function patchChildren(from2, to) {
|
||||
if (from2._x_teleport)
|
||||
from2 = from2._x_teleport;
|
||||
if (to._x_teleport)
|
||||
to = to._x_teleport;
|
||||
let fromKeys = keyToMap(from2.children);
|
||||
let fromKeyHoldovers = {};
|
||||
let currentTo = getFirstNode(to);
|
||||
let currentFrom = getFirstNode(from2);
|
||||
while (currentTo) {
|
||||
seedingMatchingId(currentTo, currentFrom);
|
||||
let toKey = getKey(currentTo);
|
||||
let fromKey = getKey(currentFrom);
|
||||
if (!currentFrom) {
|
||||
if (toKey && fromKeyHoldovers[toKey]) {
|
||||
let holdover = fromKeyHoldovers[toKey];
|
||||
from2.appendChild(holdover);
|
||||
currentFrom = holdover;
|
||||
} else {
|
||||
if (!shouldSkip(adding, currentTo)) {
|
||||
let clone = currentTo.cloneNode(true);
|
||||
from2.appendChild(clone);
|
||||
added(clone);
|
||||
}
|
||||
currentTo = getNextSibling(to, currentTo);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let isIf = (node) => node && node.nodeType === 8 && node.textContent === "[if BLOCK]><![endif]";
|
||||
let isEnd = (node) => node && node.nodeType === 8 && node.textContent === "[if ENDBLOCK]><![endif]";
|
||||
if (isIf(currentTo) && isIf(currentFrom)) {
|
||||
let nestedIfCount = 0;
|
||||
let fromBlockStart = currentFrom;
|
||||
while (currentFrom) {
|
||||
let next = getNextSibling(from2, currentFrom);
|
||||
if (isIf(next)) {
|
||||
nestedIfCount++;
|
||||
} else if (isEnd(next) && nestedIfCount > 0) {
|
||||
nestedIfCount--;
|
||||
} else if (isEnd(next) && nestedIfCount === 0) {
|
||||
currentFrom = next;
|
||||
break;
|
||||
}
|
||||
currentFrom = next;
|
||||
}
|
||||
let fromBlockEnd = currentFrom;
|
||||
nestedIfCount = 0;
|
||||
let toBlockStart = currentTo;
|
||||
while (currentTo) {
|
||||
let next = getNextSibling(to, currentTo);
|
||||
if (isIf(next)) {
|
||||
nestedIfCount++;
|
||||
} else if (isEnd(next) && nestedIfCount > 0) {
|
||||
nestedIfCount--;
|
||||
} else if (isEnd(next) && nestedIfCount === 0) {
|
||||
currentTo = next;
|
||||
break;
|
||||
}
|
||||
currentTo = next;
|
||||
}
|
||||
let toBlockEnd = currentTo;
|
||||
let fromBlock = new Block(fromBlockStart, fromBlockEnd);
|
||||
let toBlock = new Block(toBlockStart, toBlockEnd);
|
||||
patchChildren(fromBlock, toBlock);
|
||||
continue;
|
||||
}
|
||||
if (currentFrom.nodeType === 1 && lookahead && !currentFrom.isEqualNode(currentTo)) {
|
||||
let nextToElementSibling = getNextSibling(to, currentTo);
|
||||
let found = false;
|
||||
while (!found && nextToElementSibling) {
|
||||
if (nextToElementSibling.nodeType === 1 && currentFrom.isEqualNode(nextToElementSibling)) {
|
||||
found = true;
|
||||
currentFrom = addNodeBefore(from2, currentTo, currentFrom);
|
||||
fromKey = getKey(currentFrom);
|
||||
}
|
||||
nextToElementSibling = getNextSibling(to, nextToElementSibling);
|
||||
}
|
||||
}
|
||||
if (toKey !== fromKey) {
|
||||
if (!toKey && fromKey) {
|
||||
fromKeyHoldovers[fromKey] = currentFrom;
|
||||
currentFrom = addNodeBefore(from2, currentTo, currentFrom);
|
||||
fromKeyHoldovers[fromKey].remove();
|
||||
currentFrom = getNextSibling(from2, currentFrom);
|
||||
currentTo = getNextSibling(to, currentTo);
|
||||
continue;
|
||||
}
|
||||
if (toKey && !fromKey) {
|
||||
if (fromKeys[toKey]) {
|
||||
currentFrom.replaceWith(fromKeys[toKey]);
|
||||
currentFrom = fromKeys[toKey];
|
||||
}
|
||||
}
|
||||
if (toKey && fromKey) {
|
||||
let fromKeyNode = fromKeys[toKey];
|
||||
if (fromKeyNode) {
|
||||
fromKeyHoldovers[fromKey] = currentFrom;
|
||||
currentFrom.replaceWith(fromKeyNode);
|
||||
currentFrom = fromKeyNode;
|
||||
} else {
|
||||
fromKeyHoldovers[fromKey] = currentFrom;
|
||||
currentFrom = addNodeBefore(from2, currentTo, currentFrom);
|
||||
fromKeyHoldovers[fromKey].remove();
|
||||
currentFrom = getNextSibling(from2, currentFrom);
|
||||
currentTo = getNextSibling(to, currentTo);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
let currentFromNext = currentFrom && getNextSibling(from2, currentFrom);
|
||||
patch(currentFrom, currentTo);
|
||||
currentTo = currentTo && getNextSibling(to, currentTo);
|
||||
currentFrom = currentFromNext;
|
||||
}
|
||||
let removals = [];
|
||||
while (currentFrom) {
|
||||
if (!shouldSkip(removing, currentFrom))
|
||||
removals.push(currentFrom);
|
||||
currentFrom = getNextSibling(from2, currentFrom);
|
||||
}
|
||||
while (removals.length) {
|
||||
let domForRemoval = removals.shift();
|
||||
domForRemoval.remove();
|
||||
removed(domForRemoval);
|
||||
}
|
||||
}
|
||||
function getKey(el) {
|
||||
return el && el.nodeType === 1 && key(el);
|
||||
}
|
||||
function keyToMap(els) {
|
||||
let map = {};
|
||||
for (let el of els) {
|
||||
let theKey = getKey(el);
|
||||
if (theKey) {
|
||||
map[theKey] = el;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
function addNodeBefore(parent, node, beforeMe) {
|
||||
if (!shouldSkip(adding, node)) {
|
||||
let clone = node.cloneNode(true);
|
||||
parent.insertBefore(clone, beforeMe);
|
||||
added(clone);
|
||||
return clone;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
assignOptions(options);
|
||||
fromEl = from;
|
||||
toEl = typeof toHtml === "string" ? createElement(toHtml) : toHtml;
|
||||
if (window.Alpine && window.Alpine.closestDataStack && !from._x_dataStack) {
|
||||
toEl._x_dataStack = window.Alpine.closestDataStack(from);
|
||||
toEl._x_dataStack && window.Alpine.cloneNode(from, toEl);
|
||||
}
|
||||
patch(from, toEl);
|
||||
fromEl = void 0;
|
||||
toEl = void 0;
|
||||
return from;
|
||||
}
|
||||
morph.step = () => {
|
||||
};
|
||||
morph.log = () => {
|
||||
};
|
||||
function shouldSkip(hook, ...args) {
|
||||
let skip = false;
|
||||
hook(...args, () => skip = true);
|
||||
return skip;
|
||||
}
|
||||
var patched = false;
|
||||
function createElement(html) {
|
||||
const template = document.createElement("template");
|
||||
template.innerHTML = html;
|
||||
return template.content.firstElementChild;
|
||||
}
|
||||
function textOrComment(el) {
|
||||
return el.nodeType === 3 || el.nodeType === 8;
|
||||
}
|
||||
var Block = class {
|
||||
constructor(start, end) {
|
||||
this.startComment = start;
|
||||
this.endComment = end;
|
||||
}
|
||||
get children() {
|
||||
let children = [];
|
||||
let currentNode = this.startComment.nextSibling;
|
||||
while (currentNode && currentNode !== this.endComment) {
|
||||
children.push(currentNode);
|
||||
currentNode = currentNode.nextSibling;
|
||||
}
|
||||
return children;
|
||||
}
|
||||
appendChild(child) {
|
||||
this.endComment.before(child);
|
||||
}
|
||||
get firstChild() {
|
||||
let first = this.startComment.nextSibling;
|
||||
if (first === this.endComment)
|
||||
return;
|
||||
return first;
|
||||
}
|
||||
nextNode(reference) {
|
||||
let next = reference.nextSibling;
|
||||
if (next === this.endComment)
|
||||
return;
|
||||
return next;
|
||||
}
|
||||
insertBefore(newNode, reference) {
|
||||
reference.before(newNode);
|
||||
return newNode;
|
||||
}
|
||||
};
|
||||
function getFirstNode(parent) {
|
||||
return parent.firstChild;
|
||||
}
|
||||
function getNextSibling(parent, reference) {
|
||||
let next;
|
||||
if (parent instanceof Block) {
|
||||
next = parent.nextNode(reference);
|
||||
} else {
|
||||
next = reference.nextSibling;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
function monkeyPatchDomSetAttributeToAllowAtSymbols() {
|
||||
if (patched)
|
||||
return;
|
||||
patched = true;
|
||||
let original = Element.prototype.setAttribute;
|
||||
let hostDiv = document.createElement("div");
|
||||
Element.prototype.setAttribute = function newSetAttribute(name, value) {
|
||||
if (!name.includes("@")) {
|
||||
return original.call(this, name, value);
|
||||
}
|
||||
hostDiv.innerHTML = `<span ${name}="${value}"></span>`;
|
||||
let attr = hostDiv.firstElementChild.getAttributeNode(name);
|
||||
hostDiv.firstElementChild.removeAttributeNode(attr);
|
||||
this.setAttributeNode(attr);
|
||||
};
|
||||
}
|
||||
function seedingMatchingId(to, from) {
|
||||
let fromId = from && from._x_bindings && from._x_bindings.id;
|
||||
if (!fromId)
|
||||
return;
|
||||
to.setAttribute("id", fromId);
|
||||
to.id = fromId;
|
||||
}
|
||||
|
||||
// packages/morph/src/index.js
|
||||
function src_default(Alpine) {
|
||||
Alpine.morph = morph;
|
||||
}
|
||||
|
||||
// packages/morph/builds/module.js
|
||||
var module_default = src_default;
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
morph
|
||||
});
|
||||
343
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/dist/module.esm.js
vendored
Normal file
343
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/dist/module.esm.js
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
// packages/morph/src/morph.js
|
||||
function morph(from, toHtml, options) {
|
||||
monkeyPatchDomSetAttributeToAllowAtSymbols();
|
||||
let fromEl;
|
||||
let toEl;
|
||||
let key, lookahead, updating, updated, removing, removed, adding, added;
|
||||
function assignOptions(options2 = {}) {
|
||||
let defaultGetKey = (el) => el.getAttribute("key");
|
||||
let noop = () => {
|
||||
};
|
||||
updating = options2.updating || noop;
|
||||
updated = options2.updated || noop;
|
||||
removing = options2.removing || noop;
|
||||
removed = options2.removed || noop;
|
||||
adding = options2.adding || noop;
|
||||
added = options2.added || noop;
|
||||
key = options2.key || defaultGetKey;
|
||||
lookahead = options2.lookahead || false;
|
||||
}
|
||||
function patch(from2, to) {
|
||||
if (differentElementNamesTypesOrKeys(from2, to)) {
|
||||
return swapElements(from2, to);
|
||||
}
|
||||
let updateChildrenOnly = false;
|
||||
if (shouldSkip(updating, from2, to, () => updateChildrenOnly = true))
|
||||
return;
|
||||
if (from2.nodeType === 1 && window.Alpine) {
|
||||
window.Alpine.cloneNode(from2, to);
|
||||
}
|
||||
if (textOrComment(to)) {
|
||||
patchNodeValue(from2, to);
|
||||
updated(from2, to);
|
||||
return;
|
||||
}
|
||||
if (!updateChildrenOnly) {
|
||||
patchAttributes(from2, to);
|
||||
}
|
||||
updated(from2, to);
|
||||
patchChildren(from2, to);
|
||||
}
|
||||
function differentElementNamesTypesOrKeys(from2, to) {
|
||||
return from2.nodeType != to.nodeType || from2.nodeName != to.nodeName || getKey(from2) != getKey(to);
|
||||
}
|
||||
function swapElements(from2, to) {
|
||||
if (shouldSkip(removing, from2))
|
||||
return;
|
||||
let toCloned = to.cloneNode(true);
|
||||
if (shouldSkip(adding, toCloned))
|
||||
return;
|
||||
from2.replaceWith(toCloned);
|
||||
removed(from2);
|
||||
added(toCloned);
|
||||
}
|
||||
function patchNodeValue(from2, to) {
|
||||
let value = to.nodeValue;
|
||||
if (from2.nodeValue !== value) {
|
||||
from2.nodeValue = value;
|
||||
}
|
||||
}
|
||||
function patchAttributes(from2, to) {
|
||||
if (from2._x_transitioning)
|
||||
return;
|
||||
if (from2._x_isShown && !to._x_isShown) {
|
||||
return;
|
||||
}
|
||||
if (!from2._x_isShown && to._x_isShown) {
|
||||
return;
|
||||
}
|
||||
let domAttributes = Array.from(from2.attributes);
|
||||
let toAttributes = Array.from(to.attributes);
|
||||
for (let i = domAttributes.length - 1; i >= 0; i--) {
|
||||
let name = domAttributes[i].name;
|
||||
if (!to.hasAttribute(name)) {
|
||||
from2.removeAttribute(name);
|
||||
}
|
||||
}
|
||||
for (let i = toAttributes.length - 1; i >= 0; i--) {
|
||||
let name = toAttributes[i].name;
|
||||
let value = toAttributes[i].value;
|
||||
if (from2.getAttribute(name) !== value) {
|
||||
from2.setAttribute(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
function patchChildren(from2, to) {
|
||||
if (from2._x_teleport)
|
||||
from2 = from2._x_teleport;
|
||||
if (to._x_teleport)
|
||||
to = to._x_teleport;
|
||||
let fromKeys = keyToMap(from2.children);
|
||||
let fromKeyHoldovers = {};
|
||||
let currentTo = getFirstNode(to);
|
||||
let currentFrom = getFirstNode(from2);
|
||||
while (currentTo) {
|
||||
seedingMatchingId(currentTo, currentFrom);
|
||||
let toKey = getKey(currentTo);
|
||||
let fromKey = getKey(currentFrom);
|
||||
if (!currentFrom) {
|
||||
if (toKey && fromKeyHoldovers[toKey]) {
|
||||
let holdover = fromKeyHoldovers[toKey];
|
||||
from2.appendChild(holdover);
|
||||
currentFrom = holdover;
|
||||
} else {
|
||||
if (!shouldSkip(adding, currentTo)) {
|
||||
let clone = currentTo.cloneNode(true);
|
||||
from2.appendChild(clone);
|
||||
added(clone);
|
||||
}
|
||||
currentTo = getNextSibling(to, currentTo);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let isIf = (node) => node && node.nodeType === 8 && node.textContent === "[if BLOCK]><![endif]";
|
||||
let isEnd = (node) => node && node.nodeType === 8 && node.textContent === "[if ENDBLOCK]><![endif]";
|
||||
if (isIf(currentTo) && isIf(currentFrom)) {
|
||||
let nestedIfCount = 0;
|
||||
let fromBlockStart = currentFrom;
|
||||
while (currentFrom) {
|
||||
let next = getNextSibling(from2, currentFrom);
|
||||
if (isIf(next)) {
|
||||
nestedIfCount++;
|
||||
} else if (isEnd(next) && nestedIfCount > 0) {
|
||||
nestedIfCount--;
|
||||
} else if (isEnd(next) && nestedIfCount === 0) {
|
||||
currentFrom = next;
|
||||
break;
|
||||
}
|
||||
currentFrom = next;
|
||||
}
|
||||
let fromBlockEnd = currentFrom;
|
||||
nestedIfCount = 0;
|
||||
let toBlockStart = currentTo;
|
||||
while (currentTo) {
|
||||
let next = getNextSibling(to, currentTo);
|
||||
if (isIf(next)) {
|
||||
nestedIfCount++;
|
||||
} else if (isEnd(next) && nestedIfCount > 0) {
|
||||
nestedIfCount--;
|
||||
} else if (isEnd(next) && nestedIfCount === 0) {
|
||||
currentTo = next;
|
||||
break;
|
||||
}
|
||||
currentTo = next;
|
||||
}
|
||||
let toBlockEnd = currentTo;
|
||||
let fromBlock = new Block(fromBlockStart, fromBlockEnd);
|
||||
let toBlock = new Block(toBlockStart, toBlockEnd);
|
||||
patchChildren(fromBlock, toBlock);
|
||||
continue;
|
||||
}
|
||||
if (currentFrom.nodeType === 1 && lookahead && !currentFrom.isEqualNode(currentTo)) {
|
||||
let nextToElementSibling = getNextSibling(to, currentTo);
|
||||
let found = false;
|
||||
while (!found && nextToElementSibling) {
|
||||
if (nextToElementSibling.nodeType === 1 && currentFrom.isEqualNode(nextToElementSibling)) {
|
||||
found = true;
|
||||
currentFrom = addNodeBefore(from2, currentTo, currentFrom);
|
||||
fromKey = getKey(currentFrom);
|
||||
}
|
||||
nextToElementSibling = getNextSibling(to, nextToElementSibling);
|
||||
}
|
||||
}
|
||||
if (toKey !== fromKey) {
|
||||
if (!toKey && fromKey) {
|
||||
fromKeyHoldovers[fromKey] = currentFrom;
|
||||
currentFrom = addNodeBefore(from2, currentTo, currentFrom);
|
||||
fromKeyHoldovers[fromKey].remove();
|
||||
currentFrom = getNextSibling(from2, currentFrom);
|
||||
currentTo = getNextSibling(to, currentTo);
|
||||
continue;
|
||||
}
|
||||
if (toKey && !fromKey) {
|
||||
if (fromKeys[toKey]) {
|
||||
currentFrom.replaceWith(fromKeys[toKey]);
|
||||
currentFrom = fromKeys[toKey];
|
||||
}
|
||||
}
|
||||
if (toKey && fromKey) {
|
||||
let fromKeyNode = fromKeys[toKey];
|
||||
if (fromKeyNode) {
|
||||
fromKeyHoldovers[fromKey] = currentFrom;
|
||||
currentFrom.replaceWith(fromKeyNode);
|
||||
currentFrom = fromKeyNode;
|
||||
} else {
|
||||
fromKeyHoldovers[fromKey] = currentFrom;
|
||||
currentFrom = addNodeBefore(from2, currentTo, currentFrom);
|
||||
fromKeyHoldovers[fromKey].remove();
|
||||
currentFrom = getNextSibling(from2, currentFrom);
|
||||
currentTo = getNextSibling(to, currentTo);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
let currentFromNext = currentFrom && getNextSibling(from2, currentFrom);
|
||||
patch(currentFrom, currentTo);
|
||||
currentTo = currentTo && getNextSibling(to, currentTo);
|
||||
currentFrom = currentFromNext;
|
||||
}
|
||||
let removals = [];
|
||||
while (currentFrom) {
|
||||
if (!shouldSkip(removing, currentFrom))
|
||||
removals.push(currentFrom);
|
||||
currentFrom = getNextSibling(from2, currentFrom);
|
||||
}
|
||||
while (removals.length) {
|
||||
let domForRemoval = removals.shift();
|
||||
domForRemoval.remove();
|
||||
removed(domForRemoval);
|
||||
}
|
||||
}
|
||||
function getKey(el) {
|
||||
return el && el.nodeType === 1 && key(el);
|
||||
}
|
||||
function keyToMap(els) {
|
||||
let map = {};
|
||||
for (let el of els) {
|
||||
let theKey = getKey(el);
|
||||
if (theKey) {
|
||||
map[theKey] = el;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
function addNodeBefore(parent, node, beforeMe) {
|
||||
if (!shouldSkip(adding, node)) {
|
||||
let clone = node.cloneNode(true);
|
||||
parent.insertBefore(clone, beforeMe);
|
||||
added(clone);
|
||||
return clone;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
assignOptions(options);
|
||||
fromEl = from;
|
||||
toEl = typeof toHtml === "string" ? createElement(toHtml) : toHtml;
|
||||
if (window.Alpine && window.Alpine.closestDataStack && !from._x_dataStack) {
|
||||
toEl._x_dataStack = window.Alpine.closestDataStack(from);
|
||||
toEl._x_dataStack && window.Alpine.cloneNode(from, toEl);
|
||||
}
|
||||
patch(from, toEl);
|
||||
fromEl = void 0;
|
||||
toEl = void 0;
|
||||
return from;
|
||||
}
|
||||
morph.step = () => {
|
||||
};
|
||||
morph.log = () => {
|
||||
};
|
||||
function shouldSkip(hook, ...args) {
|
||||
let skip = false;
|
||||
hook(...args, () => skip = true);
|
||||
return skip;
|
||||
}
|
||||
var patched = false;
|
||||
function createElement(html) {
|
||||
const template = document.createElement("template");
|
||||
template.innerHTML = html;
|
||||
return template.content.firstElementChild;
|
||||
}
|
||||
function textOrComment(el) {
|
||||
return el.nodeType === 3 || el.nodeType === 8;
|
||||
}
|
||||
var Block = class {
|
||||
constructor(start, end) {
|
||||
this.startComment = start;
|
||||
this.endComment = end;
|
||||
}
|
||||
get children() {
|
||||
let children = [];
|
||||
let currentNode = this.startComment.nextSibling;
|
||||
while (currentNode && currentNode !== this.endComment) {
|
||||
children.push(currentNode);
|
||||
currentNode = currentNode.nextSibling;
|
||||
}
|
||||
return children;
|
||||
}
|
||||
appendChild(child) {
|
||||
this.endComment.before(child);
|
||||
}
|
||||
get firstChild() {
|
||||
let first = this.startComment.nextSibling;
|
||||
if (first === this.endComment)
|
||||
return;
|
||||
return first;
|
||||
}
|
||||
nextNode(reference) {
|
||||
let next = reference.nextSibling;
|
||||
if (next === this.endComment)
|
||||
return;
|
||||
return next;
|
||||
}
|
||||
insertBefore(newNode, reference) {
|
||||
reference.before(newNode);
|
||||
return newNode;
|
||||
}
|
||||
};
|
||||
function getFirstNode(parent) {
|
||||
return parent.firstChild;
|
||||
}
|
||||
function getNextSibling(parent, reference) {
|
||||
let next;
|
||||
if (parent instanceof Block) {
|
||||
next = parent.nextNode(reference);
|
||||
} else {
|
||||
next = reference.nextSibling;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
function monkeyPatchDomSetAttributeToAllowAtSymbols() {
|
||||
if (patched)
|
||||
return;
|
||||
patched = true;
|
||||
let original = Element.prototype.setAttribute;
|
||||
let hostDiv = document.createElement("div");
|
||||
Element.prototype.setAttribute = function newSetAttribute(name, value) {
|
||||
if (!name.includes("@")) {
|
||||
return original.call(this, name, value);
|
||||
}
|
||||
hostDiv.innerHTML = `<span ${name}="${value}"></span>`;
|
||||
let attr = hostDiv.firstElementChild.getAttributeNode(name);
|
||||
hostDiv.firstElementChild.removeAttributeNode(attr);
|
||||
this.setAttributeNode(attr);
|
||||
};
|
||||
}
|
||||
function seedingMatchingId(to, from) {
|
||||
let fromId = from && from._x_bindings && from._x_bindings.id;
|
||||
if (!fromId)
|
||||
return;
|
||||
to.setAttribute("id", fromId);
|
||||
to.id = fromId;
|
||||
}
|
||||
|
||||
// packages/morph/src/index.js
|
||||
function src_default(Alpine) {
|
||||
Alpine.morph = morph;
|
||||
}
|
||||
|
||||
// packages/morph/builds/module.js
|
||||
var module_default = src_default;
|
||||
export {
|
||||
module_default as default,
|
||||
src_default as morph
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "@alpinejs/morph",
|
||||
"version": "3.13.8",
|
||||
"description": "Diff and patch a block of HTML on a page with an HTML template",
|
||||
"homepage": "https://alpinejs.dev/plugins/morph",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/alpinejs/alpine.git",
|
||||
"directory": "packages/morph"
|
||||
},
|
||||
"author": "Caleb Porzio",
|
||||
"license": "MIT",
|
||||
"main": "dist/module.cjs.js",
|
||||
"module": "dist/module.esm.js"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { morph } from './morph'
|
||||
|
||||
export default function (Alpine) {
|
||||
Alpine.morph = morph
|
||||
}
|
||||
|
||||
export { morph }
|
||||
501
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/src/morph.js
Normal file
501
themes/hugo-mod-jslibs-dist/alpinejs/packages/morph/src/morph.js
Normal file
@@ -0,0 +1,501 @@
|
||||
|
||||
let resolveStep = () => {}
|
||||
|
||||
let logger = () => {}
|
||||
|
||||
export function morph(from, toHtml, options) {
|
||||
monkeyPatchDomSetAttributeToAllowAtSymbols()
|
||||
|
||||
// We're defining these globals and methods inside this function (instead of outside)
|
||||
// because it's an async function and if run twice, they would overwrite
|
||||
// each other.
|
||||
|
||||
let fromEl
|
||||
let toEl
|
||||
let key, lookahead, updating, updated, removing, removed, adding, added
|
||||
|
||||
function assignOptions(options = {}) {
|
||||
let defaultGetKey = el => el.getAttribute('key')
|
||||
let noop = () => {}
|
||||
|
||||
updating = options.updating || noop
|
||||
updated = options.updated || noop
|
||||
removing = options.removing || noop
|
||||
removed = options.removed || noop
|
||||
adding = options.adding || noop
|
||||
added = options.added || noop
|
||||
key = options.key || defaultGetKey
|
||||
lookahead = options.lookahead || false
|
||||
}
|
||||
|
||||
function patch(from, to) {
|
||||
if (differentElementNamesTypesOrKeys(from, to)) {
|
||||
return swapElements(from, to)
|
||||
}
|
||||
|
||||
let updateChildrenOnly = false
|
||||
|
||||
if (shouldSkip(updating, from, to, () => updateChildrenOnly = true)) return
|
||||
|
||||
// Initialize the server-side HTML element with Alpine...
|
||||
if (from.nodeType === 1 && window.Alpine) {
|
||||
window.Alpine.cloneNode(from, to)
|
||||
}
|
||||
|
||||
if (textOrComment(to)) {
|
||||
patchNodeValue(from, to)
|
||||
|
||||
updated(from, to)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (! updateChildrenOnly) {
|
||||
patchAttributes(from, to)
|
||||
}
|
||||
|
||||
updated(from, to)
|
||||
|
||||
patchChildren(from, to)
|
||||
}
|
||||
|
||||
function differentElementNamesTypesOrKeys(from, to) {
|
||||
return from.nodeType != to.nodeType
|
||||
|| from.nodeName != to.nodeName
|
||||
|| getKey(from) != getKey(to)
|
||||
}
|
||||
|
||||
function swapElements(from, to) {
|
||||
if (shouldSkip(removing, from)) return
|
||||
|
||||
let toCloned = to.cloneNode(true)
|
||||
|
||||
if (shouldSkip(adding, toCloned)) return
|
||||
|
||||
from.replaceWith(toCloned)
|
||||
|
||||
removed(from)
|
||||
added(toCloned)
|
||||
}
|
||||
|
||||
function patchNodeValue(from, to) {
|
||||
let value = to.nodeValue
|
||||
|
||||
if (from.nodeValue !== value) {
|
||||
// Change text node...
|
||||
from.nodeValue = value
|
||||
}
|
||||
}
|
||||
|
||||
function patchAttributes(from, to) {
|
||||
if (from._x_transitioning) return
|
||||
|
||||
if (from._x_isShown && ! to._x_isShown) {
|
||||
return
|
||||
}
|
||||
if (! from._x_isShown && to._x_isShown) {
|
||||
return
|
||||
}
|
||||
|
||||
let domAttributes = Array.from(from.attributes)
|
||||
let toAttributes = Array.from(to.attributes)
|
||||
|
||||
for (let i = domAttributes.length - 1; i >= 0; i--) {
|
||||
let name = domAttributes[i].name;
|
||||
|
||||
if (! to.hasAttribute(name)) {
|
||||
// Remove attribute...
|
||||
from.removeAttribute(name)
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = toAttributes.length - 1; i >= 0; i--) {
|
||||
let name = toAttributes[i].name
|
||||
let value = toAttributes[i].value
|
||||
|
||||
if (from.getAttribute(name) !== value) {
|
||||
from.setAttribute(name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function patchChildren(from, to) {
|
||||
// If we hit a <template x-teleport="body">,
|
||||
// let's use the teleported nodes for this patch...
|
||||
if (from._x_teleport) from = from._x_teleport
|
||||
if (to._x_teleport) to = to._x_teleport
|
||||
|
||||
let fromKeys = keyToMap(from.children)
|
||||
let fromKeyHoldovers = {}
|
||||
|
||||
let currentTo = getFirstNode(to)
|
||||
let currentFrom = getFirstNode(from)
|
||||
|
||||
while (currentTo) {
|
||||
// If the "from" element has a dynamically bound "id" (x-bind:id="..."),
|
||||
// Let's transfer it to the "to" element so that there isn't a key mismatch...
|
||||
seedingMatchingId(currentTo, currentFrom)
|
||||
|
||||
let toKey = getKey(currentTo)
|
||||
let fromKey = getKey(currentFrom)
|
||||
|
||||
// Add new elements...
|
||||
if (! currentFrom) {
|
||||
if (toKey && fromKeyHoldovers[toKey]) {
|
||||
// Add element (from key)...
|
||||
let holdover = fromKeyHoldovers[toKey]
|
||||
|
||||
from.appendChild(holdover)
|
||||
|
||||
currentFrom = holdover
|
||||
} else {
|
||||
if(! shouldSkip(adding, currentTo)) {
|
||||
// Add element...
|
||||
let clone = currentTo.cloneNode(true)
|
||||
|
||||
from.appendChild(clone)
|
||||
|
||||
added(clone)
|
||||
}
|
||||
|
||||
currentTo = getNextSibling(to, currentTo)
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Handle conditional markers (presumably added by backends like Livewire)...
|
||||
let isIf = node => node && node.nodeType === 8 && node.textContent === '[if BLOCK]><![endif]'
|
||||
let isEnd = node => node && node.nodeType === 8 && node.textContent === '[if ENDBLOCK]><![endif]'
|
||||
|
||||
if (isIf(currentTo) && isIf(currentFrom)) {
|
||||
let nestedIfCount = 0
|
||||
|
||||
let fromBlockStart = currentFrom
|
||||
|
||||
while (currentFrom) {
|
||||
let next = getNextSibling(from, currentFrom)
|
||||
|
||||
if (isIf(next)) {
|
||||
nestedIfCount++
|
||||
} else if (isEnd(next) && nestedIfCount > 0) {
|
||||
nestedIfCount--
|
||||
} else if (isEnd(next) && nestedIfCount === 0) {
|
||||
currentFrom = next
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
currentFrom = next
|
||||
}
|
||||
|
||||
let fromBlockEnd = currentFrom
|
||||
|
||||
nestedIfCount = 0
|
||||
|
||||
let toBlockStart = currentTo
|
||||
|
||||
while (currentTo) {
|
||||
let next = getNextSibling(to, currentTo)
|
||||
|
||||
if (isIf(next)) {
|
||||
nestedIfCount++
|
||||
} else if (isEnd(next) && nestedIfCount > 0) {
|
||||
nestedIfCount--
|
||||
} else if (isEnd(next) && nestedIfCount === 0) {
|
||||
currentTo = next
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
currentTo = next
|
||||
}
|
||||
|
||||
let toBlockEnd = currentTo
|
||||
|
||||
let fromBlock = new Block(fromBlockStart, fromBlockEnd)
|
||||
let toBlock = new Block(toBlockStart, toBlockEnd)
|
||||
|
||||
patchChildren(fromBlock, toBlock)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// Lookaheads should only apply to non-text-or-comment elements...
|
||||
if (currentFrom.nodeType === 1 && lookahead && ! currentFrom.isEqualNode(currentTo)) {
|
||||
let nextToElementSibling = getNextSibling(to, currentTo)
|
||||
|
||||
let found = false
|
||||
|
||||
while (! found && nextToElementSibling) {
|
||||
if (nextToElementSibling.nodeType === 1 && currentFrom.isEqualNode(nextToElementSibling)) {
|
||||
found = true; // This ";" needs to be here...
|
||||
|
||||
currentFrom = addNodeBefore(from, currentTo, currentFrom)
|
||||
|
||||
fromKey = getKey(currentFrom)
|
||||
}
|
||||
|
||||
nextToElementSibling = getNextSibling(to, nextToElementSibling)
|
||||
}
|
||||
}
|
||||
|
||||
if (toKey !== fromKey) {
|
||||
if (! toKey && fromKey) {
|
||||
// No "to" key...
|
||||
fromKeyHoldovers[fromKey] = currentFrom; // This ";" needs to be here...
|
||||
currentFrom = addNodeBefore(from, currentTo, currentFrom)
|
||||
fromKeyHoldovers[fromKey].remove()
|
||||
currentFrom = getNextSibling(from, currentFrom)
|
||||
currentTo = getNextSibling(to, currentTo)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if (toKey && ! fromKey) {
|
||||
if (fromKeys[toKey]) {
|
||||
// No "from" key...
|
||||
currentFrom.replaceWith(fromKeys[toKey])
|
||||
currentFrom = fromKeys[toKey]
|
||||
}
|
||||
}
|
||||
|
||||
if (toKey && fromKey) {
|
||||
let fromKeyNode = fromKeys[toKey]
|
||||
|
||||
if (fromKeyNode) {
|
||||
// Move "from" key...
|
||||
fromKeyHoldovers[fromKey] = currentFrom
|
||||
currentFrom.replaceWith(fromKeyNode)
|
||||
currentFrom = fromKeyNode
|
||||
} else {
|
||||
// Swap elements with keys...
|
||||
fromKeyHoldovers[fromKey] = currentFrom; // This ";" needs to be here...
|
||||
currentFrom = addNodeBefore(from, currentTo, currentFrom)
|
||||
fromKeyHoldovers[fromKey].remove()
|
||||
currentFrom = getNextSibling(from, currentFrom)
|
||||
currentTo = getNextSibling(to, currentTo)
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get next from sibling before patching in case the node is replaced
|
||||
let currentFromNext = currentFrom && getNextSibling(from, currentFrom) //dom.next(from, fromChildren, currentFrom))
|
||||
|
||||
// Patch elements
|
||||
patch(currentFrom, currentTo)
|
||||
|
||||
currentTo = currentTo && getNextSibling(to, currentTo) // dom.next(from, toChildren, currentTo))
|
||||
|
||||
currentFrom = currentFromNext
|
||||
}
|
||||
|
||||
// Cleanup extra forms.
|
||||
let removals = []
|
||||
|
||||
// We need to collect the "removals" first before actually
|
||||
// removing them so we don't mess with the order of things.
|
||||
while (currentFrom) {
|
||||
if (! shouldSkip(removing, currentFrom)) removals.push(currentFrom)
|
||||
|
||||
// currentFrom = dom.next(fromChildren, currentFrom)
|
||||
currentFrom = getNextSibling(from, currentFrom)
|
||||
}
|
||||
|
||||
// Now we can do the actual removals.
|
||||
while (removals.length) {
|
||||
let domForRemoval = removals.shift()
|
||||
|
||||
domForRemoval.remove()
|
||||
|
||||
removed(domForRemoval)
|
||||
}
|
||||
}
|
||||
|
||||
function getKey(el) {
|
||||
return el && el.nodeType === 1 && key(el)
|
||||
}
|
||||
|
||||
function keyToMap(els) {
|
||||
let map = {}
|
||||
|
||||
for (let el of els) {
|
||||
let theKey = getKey(el)
|
||||
|
||||
if (theKey) {
|
||||
map[theKey] = el
|
||||
}
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
function addNodeBefore(parent, node, beforeMe) {
|
||||
if(! shouldSkip(adding, node)) {
|
||||
let clone = node.cloneNode(true)
|
||||
|
||||
parent.insertBefore(clone, beforeMe)
|
||||
|
||||
added(clone)
|
||||
|
||||
return clone
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
// Finally we morph the element
|
||||
|
||||
assignOptions(options)
|
||||
|
||||
fromEl = from
|
||||
toEl = typeof toHtml === 'string' ? createElement(toHtml) : toHtml
|
||||
|
||||
if (window.Alpine && window.Alpine.closestDataStack && ! from._x_dataStack) {
|
||||
// Just in case a part of this template uses Alpine scope from somewhere
|
||||
// higher in the DOM tree, we'll find that state and replace it on the root
|
||||
// element so everything is synced up accurately.
|
||||
toEl._x_dataStack = window.Alpine.closestDataStack(from)
|
||||
|
||||
// We will kick off a clone on the root element.
|
||||
toEl._x_dataStack && window.Alpine.cloneNode(from, toEl)
|
||||
}
|
||||
|
||||
patch(from, toEl)
|
||||
|
||||
// Release these for the garbage collector.
|
||||
fromEl = undefined
|
||||
toEl = undefined
|
||||
|
||||
return from
|
||||
}
|
||||
|
||||
// These are legacy holdovers that don't do anything anymore...
|
||||
morph.step = () => {}
|
||||
morph.log = () => {}
|
||||
|
||||
function shouldSkip(hook, ...args) {
|
||||
let skip = false
|
||||
|
||||
hook(...args, () => skip = true)
|
||||
|
||||
return skip
|
||||
}
|
||||
|
||||
let patched = false
|
||||
|
||||
export function createElement(html) {
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = html
|
||||
return template.content.firstElementChild
|
||||
}
|
||||
|
||||
export function textOrComment(el) {
|
||||
return el.nodeType === 3
|
||||
|| el.nodeType === 8
|
||||
}
|
||||
|
||||
// "Block"s are used when morphing with conditional markers.
|
||||
// They allow us to patch isolated portions of a list of
|
||||
// siblings in a DOM tree...
|
||||
class Block {
|
||||
constructor(start, end) {
|
||||
// We're assuming here that the start and end caps are comment blocks...
|
||||
this.startComment = start
|
||||
this.endComment = end
|
||||
}
|
||||
|
||||
get children() {
|
||||
let children = [];
|
||||
|
||||
let currentNode = this.startComment.nextSibling
|
||||
|
||||
while (currentNode && currentNode !== this.endComment) {
|
||||
children.push(currentNode)
|
||||
|
||||
currentNode = currentNode.nextSibling
|
||||
}
|
||||
|
||||
return children
|
||||
}
|
||||
|
||||
appendChild(child) {
|
||||
this.endComment.before(child)
|
||||
}
|
||||
|
||||
get firstChild() {
|
||||
let first = this.startComment.nextSibling
|
||||
|
||||
if (first === this.endComment) return
|
||||
|
||||
return first
|
||||
}
|
||||
|
||||
nextNode(reference) {
|
||||
let next = reference.nextSibling
|
||||
|
||||
if (next === this.endComment) return
|
||||
|
||||
return next
|
||||
}
|
||||
|
||||
insertBefore(newNode, reference) {
|
||||
reference.before(newNode)
|
||||
|
||||
return newNode
|
||||
}
|
||||
}
|
||||
|
||||
function getFirstNode(parent) {
|
||||
return parent.firstChild
|
||||
}
|
||||
|
||||
function getNextSibling(parent, reference) {
|
||||
let next
|
||||
|
||||
if (parent instanceof Block) {
|
||||
next = parent.nextNode(reference)
|
||||
} else {
|
||||
next = reference.nextSibling
|
||||
}
|
||||
|
||||
return next
|
||||
}
|
||||
|
||||
function monkeyPatchDomSetAttributeToAllowAtSymbols() {
|
||||
if (patched) return
|
||||
|
||||
patched = true
|
||||
|
||||
// Because morphdom may add attributes to elements containing "@" symbols
|
||||
// like in the case of an Alpine `@click` directive, we have to patch
|
||||
// the standard Element.setAttribute method to allow this to work.
|
||||
let original = Element.prototype.setAttribute
|
||||
|
||||
let hostDiv = document.createElement('div')
|
||||
|
||||
Element.prototype.setAttribute = function newSetAttribute(name, value) {
|
||||
if (! name.includes('@')) {
|
||||
return original.call(this, name, value)
|
||||
}
|
||||
|
||||
hostDiv.innerHTML = `<span ${name}="${value}"></span>`
|
||||
|
||||
let attr = hostDiv.firstElementChild.getAttributeNode(name)
|
||||
|
||||
hostDiv.firstElementChild.removeAttributeNode(attr)
|
||||
|
||||
this.setAttributeNode(attr)
|
||||
}
|
||||
}
|
||||
|
||||
function seedingMatchingId(to, from) {
|
||||
let fromId = from && from._x_bindings && from._x_bindings.id
|
||||
|
||||
if (! fromId) return
|
||||
|
||||
to.setAttribute('id', fromId)
|
||||
to.id = fromId
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
import { dom, createElement, textOrComment} from './dom.js'
|
||||
|
||||
let resolveStep = () => {}
|
||||
|
||||
let logger = () => {}
|
||||
|
||||
export async function morph(from, toHtml, options) {
|
||||
// We're defining these globals and methods inside this function (instead of outside)
|
||||
// because it's an async function and if run twice, they would overwrite
|
||||
// each other.
|
||||
|
||||
let fromEl
|
||||
let toEl
|
||||
let key
|
||||
,lookahead
|
||||
,updating
|
||||
,updated
|
||||
,removing
|
||||
,removed
|
||||
,adding
|
||||
,added
|
||||
,debug
|
||||
|
||||
|
||||
function breakpoint(message) {
|
||||
if (! debug) return
|
||||
|
||||
logger((message || '').replace('\n', '\\n'), fromEl, toEl)
|
||||
|
||||
return new Promise(resolve => resolveStep = () => resolve())
|
||||
}
|
||||
|
||||
function assignOptions(options = {}) {
|
||||
let defaultGetKey = el => el.getAttribute('key')
|
||||
let noop = () => {}
|
||||
|
||||
updating = options.updating || noop
|
||||
updated = options.updated || noop
|
||||
removing = options.removing || noop
|
||||
removed = options.removed || noop
|
||||
adding = options.adding || noop
|
||||
added = options.added || noop
|
||||
key = options.key || defaultGetKey
|
||||
lookahead = options.lookahead || false
|
||||
debug = options.debug || false
|
||||
}
|
||||
|
||||
async function patch(from, to) {
|
||||
// This is a time saver, however, it won't catch differences in nested <template> tags.
|
||||
// I'm leaving this here as I believe it's an important speed improvement, I just
|
||||
// don't see a way to enable it currently:
|
||||
//
|
||||
// if (from.isEqualNode(to)) return
|
||||
|
||||
if (differentElementNamesTypesOrKeys(from, to)) {
|
||||
let result = patchElement(from, to)
|
||||
|
||||
await breakpoint('Swap elements')
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
let updateChildrenOnly = false
|
||||
|
||||
if (shouldSkip(updating, from, to, () => updateChildrenOnly = true)) return
|
||||
|
||||
window.Alpine && initializeAlpineOnTo(from, to, () => updateChildrenOnly = true)
|
||||
|
||||
if (textOrComment(to)) {
|
||||
await patchNodeValue(from, to)
|
||||
updated(from, to)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (! updateChildrenOnly) {
|
||||
await patchAttributes(from, to)
|
||||
}
|
||||
|
||||
updated(from, to)
|
||||
|
||||
await patchChildren(from, to)
|
||||
}
|
||||
|
||||
function differentElementNamesTypesOrKeys(from, to) {
|
||||
return from.nodeType != to.nodeType
|
||||
|| from.nodeName != to.nodeName
|
||||
|| getKey(from) != getKey(to)
|
||||
}
|
||||
|
||||
function patchElement(from, to) {
|
||||
if (shouldSkip(removing, from)) return
|
||||
|
||||
let toCloned = to.cloneNode(true)
|
||||
|
||||
if (shouldSkip(adding, toCloned)) return
|
||||
|
||||
dom(from).replace(toCloned)
|
||||
|
||||
removed(from)
|
||||
added(toCloned)
|
||||
}
|
||||
|
||||
async function patchNodeValue(from, to) {
|
||||
let value = to.nodeValue
|
||||
|
||||
if (from.nodeValue !== value) {
|
||||
from.nodeValue = value
|
||||
|
||||
await breakpoint('Change text node to: ' + value)
|
||||
}
|
||||
}
|
||||
|
||||
async function patchAttributes(from, to) {
|
||||
if (from._x_isShown && ! to._x_isShown) {
|
||||
return
|
||||
}
|
||||
if (! from._x_isShown && to._x_isShown) {
|
||||
return
|
||||
}
|
||||
|
||||
let domAttributes = Array.from(from.attributes)
|
||||
let toAttributes = Array.from(to.attributes)
|
||||
|
||||
for (let i = domAttributes.length - 1; i >= 0; i--) {
|
||||
let name = domAttributes[i].name;
|
||||
|
||||
if (! to.hasAttribute(name)) {
|
||||
from.removeAttribute(name)
|
||||
|
||||
await breakpoint('Remove attribute')
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = toAttributes.length - 1; i >= 0; i--) {
|
||||
let name = toAttributes[i].name
|
||||
let value = toAttributes[i].value
|
||||
|
||||
if (from.getAttribute(name) !== value) {
|
||||
from.setAttribute(name, value)
|
||||
|
||||
await breakpoint(`Set [${name}] attribute to: "${value}"`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function patchChildren(from, to) {
|
||||
let domChildren = from.childNodes
|
||||
let toChildren = to.childNodes
|
||||
|
||||
let toKeyToNodeMap = keyToMap(toChildren)
|
||||
let domKeyDomNodeMap = keyToMap(domChildren)
|
||||
|
||||
let currentTo = dom(to).nodes().first()
|
||||
let currentFrom = dom(from).nodes().first()
|
||||
|
||||
let domKeyHoldovers = {}
|
||||
|
||||
let isInsideWall = false
|
||||
|
||||
while (currentTo) {
|
||||
// If "<!-- end -->"
|
||||
if (
|
||||
currentTo.nodeType === 8
|
||||
&& currentTo.textContent === ' end '
|
||||
) {
|
||||
isInsideWall = false
|
||||
currentTo = dom(currentTo).nodes().next()
|
||||
currentFrom = dom(currentFrom).nodes().next()
|
||||
continue
|
||||
}
|
||||
|
||||
if (insideWall)
|
||||
|
||||
if (isInsideWall) {
|
||||
console.log(currentFrom, currentTo)
|
||||
}
|
||||
|
||||
let toKey = getKey(currentTo)
|
||||
let domKey = getKey(currentFrom)
|
||||
|
||||
// Add new elements
|
||||
if (! currentFrom) {
|
||||
if (toKey && domKeyHoldovers[toKey]) {
|
||||
let holdover = domKeyHoldovers[toKey]
|
||||
|
||||
dom(from).append(holdover)
|
||||
currentFrom = holdover
|
||||
|
||||
await breakpoint('Add element (from key)')
|
||||
} else {
|
||||
let added = addNodeTo(currentTo, from) || {}
|
||||
|
||||
await breakpoint('Add element: ' + (added.outerHTML || added.nodeValue))
|
||||
|
||||
currentTo = dom(currentTo).nodes().next()
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// If "<!-- if -->"
|
||||
if (
|
||||
currentTo.nodeType === 8
|
||||
&& currentTo.textContent === ' if '
|
||||
&& currentFrom.nodeType === 8
|
||||
&& currentFrom.textContent === ' if '
|
||||
) {
|
||||
isInsideWall = true
|
||||
currentTo = dom(currentTo).nodes().next()
|
||||
currentFrom = dom(currentFrom).nodes().next()
|
||||
continue
|
||||
}
|
||||
|
||||
if (lookahead) {
|
||||
let nextToElementSibling = dom(currentTo).next()
|
||||
|
||||
let found = false
|
||||
|
||||
while (!found && nextToElementSibling) {
|
||||
if (currentFrom.isEqualNode(nextToElementSibling)) {
|
||||
found = true
|
||||
|
||||
currentFrom = addNodeBefore(currentTo, currentFrom)
|
||||
|
||||
domKey = getKey(currentFrom)
|
||||
|
||||
await breakpoint('Move element (lookahead)')
|
||||
}
|
||||
|
||||
nextToElementSibling = dom(nextToElementSibling).next()
|
||||
}
|
||||
}
|
||||
|
||||
if (toKey !== domKey) {
|
||||
if (! toKey && domKey) {
|
||||
domKeyHoldovers[domKey] = currentFrom
|
||||
currentFrom = addNodeBefore(currentTo, currentFrom)
|
||||
domKeyHoldovers[domKey].remove()
|
||||
currentFrom = dom(currentFrom).nodes().next()
|
||||
currentTo = dom(currentTo).nodes().next()
|
||||
|
||||
await breakpoint('No "to" key')
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if (toKey && ! domKey) {
|
||||
if (domKeyDomNodeMap[toKey]) {
|
||||
currentFrom = dom(currentFrom).replace(domKeyDomNodeMap[toKey])
|
||||
|
||||
await breakpoint('No "from" key')
|
||||
}
|
||||
}
|
||||
|
||||
if (toKey && domKey) {
|
||||
domKeyHoldovers[domKey] = currentFrom
|
||||
let domKeyNode = domKeyDomNodeMap[toKey]
|
||||
|
||||
if (domKeyNode) {
|
||||
currentFrom = dom(currentFrom).replace(domKeyNode)
|
||||
|
||||
await breakpoint('Move "from" key')
|
||||
} else {
|
||||
domKeyHoldovers[domKey] = currentFrom
|
||||
currentFrom = addNodeBefore(currentTo, currentFrom)
|
||||
domKeyHoldovers[domKey].remove()
|
||||
currentFrom = dom(currentFrom).next()
|
||||
currentTo = dom(currentTo).next()
|
||||
|
||||
await breakpoint('Swap elements with keys')
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get next from sibling before patching in case the node is replaced
|
||||
let currentFromNext = currentFrom && dom(currentFrom).nodes().next()
|
||||
|
||||
// Patch elements
|
||||
await patch(currentFrom, currentTo)
|
||||
|
||||
currentTo = currentTo && dom(currentTo).nodes().next()
|
||||
currentFrom = currentFromNext
|
||||
}
|
||||
|
||||
// Cleanup extra forms.
|
||||
let removals = []
|
||||
|
||||
// We need to collect the "removals" first before actually
|
||||
// removing them so we don't mess with the order of things.
|
||||
while (currentFrom) {
|
||||
if(! shouldSkip(removing, currentFrom)) removals.push(currentFrom)
|
||||
|
||||
currentFrom = dom(currentFrom).nodes().next()
|
||||
}
|
||||
|
||||
// Now we can do the actual removals.
|
||||
while (removals.length) {
|
||||
let domForRemoval = removals.shift()
|
||||
|
||||
domForRemoval.remove()
|
||||
|
||||
await breakpoint('remove el')
|
||||
|
||||
removed(domForRemoval)
|
||||
}
|
||||
}
|
||||
|
||||
function getKey(el) {
|
||||
return el && el.nodeType === 1 && key(el)
|
||||
}
|
||||
|
||||
function keyToMap(els) {
|
||||
let map = {}
|
||||
|
||||
els.forEach(el => {
|
||||
let theKey = getKey(el)
|
||||
|
||||
if (theKey) {
|
||||
map[theKey] = el
|
||||
}
|
||||
})
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
function addNodeTo(node, parent) {
|
||||
if(! shouldSkip(adding, node)) {
|
||||
let clone = node.cloneNode(true)
|
||||
|
||||
dom(parent).append(clone)
|
||||
|
||||
added(clone)
|
||||
|
||||
return clone
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function addNodeBefore(node, beforeMe) {
|
||||
if(! shouldSkip(adding, node)) {
|
||||
let clone = node.cloneNode(true)
|
||||
|
||||
dom(beforeMe).before(clone)
|
||||
|
||||
added(clone)
|
||||
|
||||
return clone
|
||||
}
|
||||
|
||||
return beforeMe
|
||||
}
|
||||
|
||||
// Finally we morph the element
|
||||
|
||||
assignOptions(options)
|
||||
|
||||
fromEl = from
|
||||
toEl = typeof toHtml === 'string' ? createElement(toHtml) : toHtml
|
||||
|
||||
// If there is no x-data on the element we're morphing,
|
||||
// let's seed it with the outer Alpine scope on the page.
|
||||
if (window.Alpine && window.Alpine.closestDataStack && ! from._x_dataStack) {
|
||||
toEl._x_dataStack = window.Alpine.closestDataStack(from)
|
||||
|
||||
toEl._x_dataStack && window.Alpine.clone(from, toEl)
|
||||
}
|
||||
|
||||
await breakpoint()
|
||||
|
||||
await patch(from, toEl)
|
||||
|
||||
// Release these for the garbage collector.
|
||||
fromEl = undefined
|
||||
toEl = undefined
|
||||
|
||||
return from
|
||||
}
|
||||
|
||||
morph.step = () => resolveStep()
|
||||
morph.log = (theLogger) => {
|
||||
logger = theLogger
|
||||
}
|
||||
|
||||
function shouldSkip(hook, ...args) {
|
||||
let skip = false
|
||||
|
||||
hook(...args, () => skip = true)
|
||||
|
||||
return skip
|
||||
}
|
||||
|
||||
function initializeAlpineOnTo(from, to, childrenOnly) {
|
||||
if (from.nodeType !== 1) return
|
||||
|
||||
// If the element we are updating is an Alpine component...
|
||||
if (from._x_dataStack) {
|
||||
// Then temporarily clone it (with it's data) to the "to" element.
|
||||
// This should simulate backend Livewire being aware of Alpine changes.
|
||||
window.Alpine.clone(from, to)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user