hyperclayjs 1.15.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +3 -3
- package/README.md +18 -18
- package/package.json +1 -1
- package/src/communication/live-sync.js +72 -139
- package/src/core/autosave.js +14 -0
- package/src/core/savePage.js +76 -19
- package/src/core/savePageCore.js +25 -3
- package/src/core/snapshot.js +91 -2
- package/src/core/tailwindInject.js +43 -2
- package/src/core/unsavedWarning.js +15 -3
- package/src/custom-attributes/autosize.esm.js +1 -0
- package/src/custom-attributes/autosize.js +15 -12
- package/src/custom-attributes/sortable.js +1 -1
- package/src/dom-utilities/insertStyleTag.js +14 -4
- package/src/hyperclay.js +40 -5
- package/src/ui/theModal.js +1 -1
- package/src/ui/toast-hyperclay.js +14 -6
- package/src/ui/toast.js +20 -7
- package/src/utilities/autosaveDebug.js +223 -0
- package/src/utilities/loadVendorScript.js +4 -4
- package/src/utilities/mutation.js +33 -8
- package/src/vendor/hyper-morph.vendor.js +22 -0
- package/src/vendor/idiomorph.min.js +0 -20
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autosave Debug Utility
|
|
3
|
+
*
|
|
4
|
+
* Provides conditional logging for the autosave system.
|
|
5
|
+
* Enable by setting localStorage.setItem('hyperclay:debug:autosave', 'true')
|
|
6
|
+
*
|
|
7
|
+
* When enabled, dynamically imports a diff library to show exactly
|
|
8
|
+
* what changed between DOM states.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const DEBUG_KEY = 'hyperclay:debug:autosave';
|
|
12
|
+
|
|
13
|
+
let diffModule = null;
|
|
14
|
+
let diffLoadPromise = null;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Check if autosave debug mode is enabled
|
|
18
|
+
*/
|
|
19
|
+
export function isDebugEnabled() {
|
|
20
|
+
try {
|
|
21
|
+
return localStorage.getItem(DEBUG_KEY) === 'true';
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Lazily load the diff library only when needed
|
|
29
|
+
* Uses esm.sh for zero-install dynamic import
|
|
30
|
+
*/
|
|
31
|
+
async function loadDiff() {
|
|
32
|
+
if (diffModule) return diffModule;
|
|
33
|
+
if (diffLoadPromise) return diffLoadPromise;
|
|
34
|
+
|
|
35
|
+
diffLoadPromise = import('https://esm.sh/diff@5.2.0')
|
|
36
|
+
.then(mod => {
|
|
37
|
+
diffModule = mod;
|
|
38
|
+
return mod;
|
|
39
|
+
})
|
|
40
|
+
.catch(err => {
|
|
41
|
+
console.warn('[autosave-debug] Failed to load diff library:', err);
|
|
42
|
+
return null;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return diffLoadPromise;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Log a brief one-liner for save operations
|
|
50
|
+
*/
|
|
51
|
+
export function logSaveCheck(label, matches) {
|
|
52
|
+
if (!isDebugEnabled()) return;
|
|
53
|
+
|
|
54
|
+
const status = matches ? '✓ matches' : '✗ differs';
|
|
55
|
+
console.log(`[autosave] ${label}: ${status}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Log when baseline is captured/updated
|
|
60
|
+
*/
|
|
61
|
+
export function logBaseline(event, details = '') {
|
|
62
|
+
if (!isDebugEnabled()) return;
|
|
63
|
+
|
|
64
|
+
console.log(`[autosave] baseline ${event}${details ? `: ${details}` : ''}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Log and diff two HTML strings (async, for unload warning)
|
|
69
|
+
* Returns a promise that resolves when logging is complete
|
|
70
|
+
*/
|
|
71
|
+
export async function logUnloadDiff(currentContents, lastSaved) {
|
|
72
|
+
if (!isDebugEnabled()) return;
|
|
73
|
+
|
|
74
|
+
console.group('[autosave] Unload warning triggered - content differs from last save');
|
|
75
|
+
console.log('Current length:', currentContents.length);
|
|
76
|
+
console.log('Last saved length:', lastSaved.length);
|
|
77
|
+
console.log('Difference:', currentContents.length - lastSaved.length, 'characters');
|
|
78
|
+
|
|
79
|
+
const diff = await loadDiff();
|
|
80
|
+
|
|
81
|
+
if (diff) {
|
|
82
|
+
const changes = diff.diffLines(lastSaved, currentContents);
|
|
83
|
+
|
|
84
|
+
console.log('\n--- DIFF (last saved → current) ---');
|
|
85
|
+
|
|
86
|
+
let hasChanges = false;
|
|
87
|
+
changes.forEach(part => {
|
|
88
|
+
if (part.added || part.removed) {
|
|
89
|
+
hasChanges = true;
|
|
90
|
+
const prefix = part.added ? '+++ ' : '--- ';
|
|
91
|
+
const lines = part.value.split('\n').filter(l => l.length > 0);
|
|
92
|
+
|
|
93
|
+
// Truncate very long diffs
|
|
94
|
+
const maxLines = 20;
|
|
95
|
+
const displayLines = lines.slice(0, maxLines);
|
|
96
|
+
|
|
97
|
+
displayLines.forEach(line => {
|
|
98
|
+
// Truncate very long lines
|
|
99
|
+
const displayLine = line.length > 200
|
|
100
|
+
? line.substring(0, 200) + '...[truncated]'
|
|
101
|
+
: line;
|
|
102
|
+
console.log(prefix + displayLine);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
if (lines.length > maxLines) {
|
|
106
|
+
console.log(`... and ${lines.length - maxLines} more lines`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (!hasChanges) {
|
|
112
|
+
console.log('(No line-level differences found - may be whitespace or inline changes)');
|
|
113
|
+
// Fall back to character diff for small differences
|
|
114
|
+
if (Math.abs(currentContents.length - lastSaved.length) < 500) {
|
|
115
|
+
const charChanges = diff.diffChars(lastSaved, currentContents);
|
|
116
|
+
console.log('\n--- CHARACTER DIFF ---');
|
|
117
|
+
charChanges.forEach(part => {
|
|
118
|
+
if (part.added || part.removed) {
|
|
119
|
+
const prefix = part.added ? '+++ ' : '--- ';
|
|
120
|
+
const value = part.value.length > 100
|
|
121
|
+
? part.value.substring(0, 100) + '...[truncated]'
|
|
122
|
+
: part.value;
|
|
123
|
+
console.log(prefix + JSON.stringify(value));
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
console.log('(diff library not available - showing raw comparison)');
|
|
130
|
+
console.log('First 500 chars of current:', currentContents.substring(0, 500));
|
|
131
|
+
console.log('First 500 chars of last saved:', lastSaved.substring(0, 500));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
console.groupEnd();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Synchronous version for beforeunload (can't await in event handler)
|
|
139
|
+
* Logs what it can immediately, diff loads async but may not complete before unload
|
|
140
|
+
*/
|
|
141
|
+
export function logUnloadDiffSync(currentContents, lastSaved) {
|
|
142
|
+
if (!isDebugEnabled()) return;
|
|
143
|
+
|
|
144
|
+
console.group('[autosave] Unload warning triggered - content differs from last save');
|
|
145
|
+
console.log('Current length:', currentContents.length);
|
|
146
|
+
console.log('Last saved length:', lastSaved.length);
|
|
147
|
+
console.log('Difference:', currentContents.length - lastSaved.length, 'characters');
|
|
148
|
+
|
|
149
|
+
// If diff is already loaded, use it synchronously
|
|
150
|
+
if (diffModule) {
|
|
151
|
+
const changes = diffModule.diffLines(lastSaved, currentContents);
|
|
152
|
+
|
|
153
|
+
console.log('\n--- DIFF (last saved → current) ---');
|
|
154
|
+
|
|
155
|
+
let hasChanges = false;
|
|
156
|
+
changes.forEach(part => {
|
|
157
|
+
if (part.added || part.removed) {
|
|
158
|
+
hasChanges = true;
|
|
159
|
+
const prefix = part.added ? '+++ ' : '--- ';
|
|
160
|
+
const lines = part.value.split('\n').filter(l => l.length > 0);
|
|
161
|
+
|
|
162
|
+
const maxLines = 20;
|
|
163
|
+
const displayLines = lines.slice(0, maxLines);
|
|
164
|
+
|
|
165
|
+
displayLines.forEach(line => {
|
|
166
|
+
const displayLine = line.length > 200
|
|
167
|
+
? line.substring(0, 200) + '...[truncated]'
|
|
168
|
+
: line;
|
|
169
|
+
console.log(prefix + displayLine);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
if (lines.length > maxLines) {
|
|
173
|
+
console.log(`... and ${lines.length - maxLines} more lines`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (!hasChanges) {
|
|
179
|
+
console.log('(No line-level differences - checking character diff)');
|
|
180
|
+
if (Math.abs(currentContents.length - lastSaved.length) < 500) {
|
|
181
|
+
const charChanges = diffModule.diffChars(lastSaved, currentContents);
|
|
182
|
+
charChanges.forEach(part => {
|
|
183
|
+
if (part.added || part.removed) {
|
|
184
|
+
const prefix = part.added ? '+++ ' : '--- ';
|
|
185
|
+
const value = part.value.length > 100
|
|
186
|
+
? part.value.substring(0, 100) + '...[truncated]'
|
|
187
|
+
: part.value;
|
|
188
|
+
console.log(prefix + JSON.stringify(value));
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
// Kick off async load for next time, show basic info now
|
|
195
|
+
loadDiff();
|
|
196
|
+
console.log('(diff library loading - run localStorage.setItem("hyperclay:debug:autosave", "true") and reload for full diff)');
|
|
197
|
+
|
|
198
|
+
// Find first difference position
|
|
199
|
+
let diffPos = 0;
|
|
200
|
+
const minLen = Math.min(currentContents.length, lastSaved.length);
|
|
201
|
+
while (diffPos < minLen && currentContents[diffPos] === lastSaved[diffPos]) {
|
|
202
|
+
diffPos++;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
console.log('First difference at position:', diffPos);
|
|
206
|
+
console.log('Context around difference:');
|
|
207
|
+
console.log(' Last saved:', JSON.stringify(lastSaved.substring(Math.max(0, diffPos - 50), diffPos + 100)));
|
|
208
|
+
console.log(' Current:', JSON.stringify(currentContents.substring(Math.max(0, diffPos - 50), diffPos + 100)));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
console.groupEnd();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Pre-load the diff library if debug is enabled
|
|
216
|
+
* Call this early to ensure diff is ready for unload events
|
|
217
|
+
*/
|
|
218
|
+
export function preloadIfEnabled() {
|
|
219
|
+
if (isDebugEnabled()) {
|
|
220
|
+
loadDiff();
|
|
221
|
+
console.log('[autosave-debug] Debug mode enabled - diff library loading');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
Lazy-load vendor scripts in edit mode only
|
|
3
3
|
|
|
4
|
-
Injects a <script save-
|
|
5
|
-
The save-
|
|
4
|
+
Injects a <script save-remove> tag that loads the vendor script.
|
|
5
|
+
The save-remove attribute ensures it's stripped when the page is saved.
|
|
6
6
|
|
|
7
7
|
Usage:
|
|
8
8
|
import { loadVendorScript } from '../utilities/loadVendorScript.js';
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Load a vendor script via script tag with save-
|
|
18
|
+
* Load a vendor script via script tag with save-remove
|
|
19
19
|
* @param {string} url - URL to the vendor script
|
|
20
20
|
* @param {Object} [options] - Options
|
|
21
21
|
* @param {string} [options.globalName] - Window property to return when loaded (for classic scripts)
|
|
@@ -33,7 +33,7 @@ export function loadVendorScript(url, options = {}) {
|
|
|
33
33
|
return new Promise((resolve, reject) => {
|
|
34
34
|
const script = document.createElement('script');
|
|
35
35
|
script.src = url;
|
|
36
|
-
script.setAttribute('save-
|
|
36
|
+
script.setAttribute('save-remove', '');
|
|
37
37
|
if (isModule) {
|
|
38
38
|
script.type = 'module';
|
|
39
39
|
}
|
|
@@ -67,8 +67,27 @@ const Mutation = {
|
|
|
67
67
|
},
|
|
68
68
|
|
|
69
69
|
_observing: false,
|
|
70
|
+
_paused: false,
|
|
70
71
|
debug: false,
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Pause mutation observation.
|
|
75
|
+
* Use this when making programmatic DOM changes that shouldn't trigger callbacks.
|
|
76
|
+
* Always pair with resume() in a try/finally block.
|
|
77
|
+
*/
|
|
78
|
+
pause() {
|
|
79
|
+
this._paused = true;
|
|
80
|
+
this._log('Paused');
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Resume mutation observation after a pause.
|
|
85
|
+
*/
|
|
86
|
+
resume() {
|
|
87
|
+
this._paused = false;
|
|
88
|
+
this._log('Resumed');
|
|
89
|
+
},
|
|
90
|
+
|
|
72
91
|
_log(message, data = null, type = 'log') {
|
|
73
92
|
if (!this.debug) return;
|
|
74
93
|
|
|
@@ -173,9 +192,14 @@ const Mutation = {
|
|
|
173
192
|
}
|
|
174
193
|
},
|
|
175
194
|
|
|
176
|
-
_shouldIgnore(
|
|
195
|
+
_shouldIgnore(node) {
|
|
196
|
+
// For non-element nodes (like text nodes), start from parent
|
|
197
|
+
let element = (node && node.nodeType !== 1) ? node.parentElement : node;
|
|
198
|
+
|
|
177
199
|
while (element && element.nodeType === 1) {
|
|
178
|
-
if (element.hasAttribute?.('mutations-ignore') ||
|
|
200
|
+
if (element.hasAttribute?.('mutations-ignore') ||
|
|
201
|
+
element.hasAttribute?.('save-remove') ||
|
|
202
|
+
element.hasAttribute?.('save-ignore')) {
|
|
179
203
|
return true;
|
|
180
204
|
}
|
|
181
205
|
element = element.parentElement;
|
|
@@ -184,8 +208,12 @@ const Mutation = {
|
|
|
184
208
|
},
|
|
185
209
|
|
|
186
210
|
_handleMutations(mutations) {
|
|
187
|
-
|
|
188
|
-
|
|
211
|
+
// Skip all mutations while paused (e.g., during live-sync morph)
|
|
212
|
+
if (this._paused) {
|
|
213
|
+
this._log(`Skipping ${mutations.length} mutations (paused)`);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
189
217
|
const changes = [];
|
|
190
218
|
const changesByType = {
|
|
191
219
|
add: [],
|
|
@@ -197,7 +225,6 @@ const Mutation = {
|
|
|
197
225
|
for (const mutation of mutations) {
|
|
198
226
|
// Check if the target or any parent has mutations-ignore attribute
|
|
199
227
|
if (this._shouldIgnore(mutation.target)) {
|
|
200
|
-
this._log('Ignoring mutation due to mutations-ignore attribute', { mutation });
|
|
201
228
|
continue;
|
|
202
229
|
}
|
|
203
230
|
|
|
@@ -244,7 +271,7 @@ const Mutation = {
|
|
|
244
271
|
}
|
|
245
272
|
|
|
246
273
|
for (const node of mutation.removedNodes) {
|
|
247
|
-
if (node.nodeType === 1 && !
|
|
274
|
+
if (node.nodeType === 1 && !this._shouldIgnore(node)) {
|
|
248
275
|
const removedNodes = [node, ...node.querySelectorAll('*')];
|
|
249
276
|
this._log(`Processing ${removedNodes.length} removed nodes`, { removedNodes });
|
|
250
277
|
|
|
@@ -309,8 +336,6 @@ const Mutation = {
|
|
|
309
336
|
if (changesByType.attribute.length) {
|
|
310
337
|
this._notify('attribute', changesByType.attribute);
|
|
311
338
|
}
|
|
312
|
-
} else {
|
|
313
|
-
this._log('No changes to process after filtering');
|
|
314
339
|
}
|
|
315
340
|
},
|
|
316
341
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
var HyperMorph=(()=>{var V=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var Y=Object.prototype.hasOwnProperty;var J=(s,o)=>{for(var u in o)V(s,u,{get:o[u],enumerable:!0})},Q=(s,o,u,d)=>{if(o&&typeof o=="object"||typeof o=="function")for(let h of G(o))!Y.call(s,h)&&h!==u&&V(s,h,{get:()=>o[h],enumerable:!(d=K(o,h))||d.enumerable});return s};var X=s=>Q(V({},"__esModule",{value:!0}),s);var pe={};J(pe,{HyperMorph:()=>$,default:()=>he,defaults:()=>fe,morph:()=>de});var F={includeClasses:!0,includeAttributes:["href","src","name","type","role","aria-label","alt","title"],excludeAttributePrefixes:["data-morph-","data-hyper-","data-im-"],textHintLength:64,excludeIds:!0,maxPathDepth:4,landmarks:["HEADER","NAV","MAIN","ASIDE","FOOTER","SECTION","ARTICLE"],weights:{signature:100,pathSegment:10,textMatch:20,textMismatch:25,uniqueCandidate:50,positionPenalty:1},minConfidence:101};function Z(s){let o=5381;for(let u=0;u<s.length;u++)o=(o<<5)+o^s.charCodeAt(u);return Math.abs(o).toString(36)}function ee(s){if(s.classList&&s.classList.length>0)return Array.from(s.classList).sort().join(" ");let o=s.getAttribute?.("class");return o?o.split(/\s+/).filter(Boolean).sort().join(" "):""}function te(s,o){let u=[];for(let d of s.attributes||[]){let h=d.name;h==="id"||h==="class"||o.excludeAttributePrefixes.some(y=>h.startsWith(y))||o.includeAttributes.includes(h)&&u.push(`${h}=${d.value}`)}return u.sort().join("|")}function ne(s,o){return(s.textContent||"").replace(/\s+/g," ").trim().slice(0,o.textHintLength)}function re(s,o){let u=[s.tagName];return o.includeClasses&&u.push(ee(s)),u.push(te(s,o)),Z(u.join("|"))}function se(s){let o=s.tagName,u=1,d=s.previousElementSibling;for(;d;)d.tagName===o&&u++,d=d.previousElementSibling;return u}function ie(s,o){return s.id||s.getAttribute?.("role")?!0:o.landmarks.includes(s.tagName)}function ae(s){if(s.id)return`#${s.id}`;let o=s.getAttribute?.("role");return o?`@${o}`:s.tagName}function oe(s,o){let u=[],d=s;for(;d&&d.tagName&&u.length<o.maxPathDepth;){let h=`${d.tagName}:${se(d)}`;if(u.unshift(h),d!==s&&ie(d,o)){u.unshift(ae(d));break}d=d.parentElement}return u}function ue(s,o){let u=0,d=s.length-1,h=o.length-1;for(;d>=0&&h>=0&&s[d]===o[h];)u++,d--,h--;return u}function C(s,o,u){if(u.has(s))return u.get(s);let d={signature:re(s,o),path:oe(s,o),textHint:ne(s,o)};return u.set(s,d),d}function z(s,o,u,d){if(d.has(s))return d.get(s);let h=new Map,y=s.querySelectorAll("*"),H=0;for(let S of y){let I=C(S,o,u);I.domIndex=H++,h.has(I.signature)||h.set(I.signature,[]),h.get(I.signature).push(S)}return d.set(s,h),h}function ce(s,o,u){u.delete(s),o.delete(s);let d=s.querySelectorAll("*");for(let h of d)o.delete(h)}function q(s,o,u,d,h){let y=C(s,u,d),H=C(o,u,d),S=u.weights,I={},E=0;if(y.signature!==H.signature)return{score:0,breakdown:{rejected:"signature mismatch"}};E+=S.signature,I.signature=S.signature;let T=ue(y.path,H.path)*S.pathSegment;E+=T,I.path=T;let k=!0;if(y.textHint&&H.textHint?y.textHint===H.textHint?(E+=S.textMatch,I.text=S.textMatch):(E-=S.textMismatch,I.text=-S.textMismatch,k=!1):y.textHint!==H.textHint&&(E-=S.textMismatch,I.text=-S.textMismatch,k=!1),h.candidateCount===1&&k&&(E+=S.uniqueCandidate,I.unique=S.uniqueCandidate),typeof y.domIndex=="number"&&typeof H.domIndex=="number"){let N=Math.abs(y.domIndex-H.domIndex),R=Math.min(N*S.positionPenalty,20);E-=R,I.drift=-R}return{score:E,breakdown:I}}function D(s,o,u,d,h){if(u.excludeIds&&s.id)return null;let y=z(o,u,d,h),H=C(s,u,d);if(typeof H.domIndex!="number"){let k=0,N=s.previousElementSibling;for(;N;)k++,N=N.previousElementSibling;H.domIndex=k}let S=y.get(H.signature)||[],I=u.excludeIds?S.filter(k=>!k.id):S;if(I.length===0)return null;let E=null,x=0,T=null;for(let k of I){let{score:N,breakdown:R}=q(s,k,u,d,{candidateCount:I.length});N>x&&(x=N,E=k,T=R)}return x<u.minConfidence?null:{element:E,confidence:x,breakdown:T}}function W(s,o,u,d,h){let y=o.querySelectorAll("*"),H=z(s,u,d,h),S=0;for(let T of y){let k=C(T,u,d);k.domIndex=S++}let I=[];for(let T of y){if(u.excludeIds&&T.id)continue;let k=C(T,u,d),N=H.get(k.signature)||[],R=u.excludeIds?N.filter(B=>!B.id):N;for(let B of R){let{score:l,breakdown:A}=q(T,B,u,d,{candidateCount:R.length});l>=u.minConfidence&&I.push({newEl:T,oldEl:B,score:l,breakdown:A})}}I.sort((T,k)=>k.score-T.score);let E=new Map,x=new Set;for(let{newEl:T,oldEl:k}of I)E.has(T)||x.has(k)||(E.set(T,k),x.add(k));return E}function P(s,o,u,d){let h=C(s,u,d),y=C(o,u,d),{score:H,breakdown:S}=q(s,o,u,d,{candidateCount:1});return{matches:H>=u.minConfidence,score:H,breakdown:S,newMeta:{signature:h.signature,path:h.path,textHint:h.textHint},oldMeta:{signature:y.signature,path:y.path,textHint:y.textHint}}}function U(s={}){let o={...F,...s,weights:{...F.weights,...s.weights}},u=new WeakMap,d=new WeakMap;return{findMatch:(h,y)=>D(h,y,o,u,d),computeMatches:(h,y)=>W(h,y,o,u,d),explain:(h,y)=>P(h,y,o,u),invalidate:h=>ce(h,u,d),session:()=>{let h=new WeakMap,y=new WeakMap;return{findMatch:(H,S)=>D(H,S,o,h,y),computeMatches:(H,S)=>W(H,S,o,h,y),explain:(H,S)=>P(H,S,o,h)}},getConfig:()=>({...o})}}var le=U(),$=(function(){"use strict";let s=()=>{};function o(l){if(!(l instanceof Element))return!1;if(l.hasAttribute("save-ignore"))return!0;if(l.tagName==="LINK"||l.tagName==="SCRIPT"){let A=l.getAttribute("src")||l.getAttribute("href")||"";if(A.startsWith("chrome-extension://")||A.startsWith("moz-extension://")||A.startsWith("safari-web-extension://"))return!0}return!1}function u(l,A){if(A!=="smart")return l.outerHTML;let p=l.getAttribute("src"),v=l.getAttribute("type")||"text/javascript";if(p)try{let b=new URL(p,window.location.href);return`ext:${v}:${b.origin}${b.pathname}`}catch{return`ext:${v}:${p}`}else{let b=l.textContent.trim(),g=5381;for(let r=0;r<b.length;r++)g=(g<<5)+g^b.charCodeAt(r);return`inline:${v}:${Math.abs(g).toString(36)}`}}let d={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:s,afterNodeAdded:s,beforeNodeMorphed:s,afterNodeMorphed:s,beforeNodeRemoved:s,afterNodeRemoved:s,beforeAttributeUpdated:s},head:{style:"merge",shouldPreserve:l=>l.getAttribute("im-preserve")==="true",shouldReAppend:l=>l.getAttribute("im-re-append")==="true",shouldRemove:s,afterHeadMorphed:s},scripts:{handle:!1,matchMode:"outerHTML",shouldPreserve:l=>l.getAttribute("im-preserve")==="true",shouldReAppend:l=>l.getAttribute("im-re-append")==="true",shouldRemove:s,afterScriptsHandled:s},restoreFocus:!0},h={computeMatches(l,A){let{computeMatches:p}=le.session();return p(l,A)}};function y(l,A,p={}){l=R(l);let v=B(A),b=N(l,v,p),g=b.scripts.matchMode,r=new Set(Array.from(l.querySelectorAll("script")).map(n=>u(n,g))),c=S(b,()=>x(b,l,v,n=>n.morphStyle==="innerHTML"?(I(n,l,v),Array.from(l.childNodes)):H(n,l,v)));b.pantry.remove();let e=k(l,r,b);return e.length>0?c instanceof Promise?c.then(n=>Promise.all(e).then(()=>n)):Promise.all(e).then(()=>c):c}function H(l,A,p){let v=B(A);return I(l,v,p,A,A.nextSibling),Array.from(v.childNodes)}function S(l,A){if(!l.config.restoreFocus)return A();let p=document.activeElement;if(!(p instanceof HTMLInputElement||p instanceof HTMLTextAreaElement))return A();let{id:v,selectionStart:b,selectionEnd:g}=p,r=A();return v&&v!==document.activeElement?.getAttribute("id")&&(p=l.target.querySelector(`[id="${v}"]`),p?.focus()),p&&!p.selectionEnd&&g!=null&&p.setSelectionRange(b,g),r}let I=(function(){function l(e,n,i,t=null,a=null){n instanceof HTMLTemplateElement&&i instanceof HTMLTemplateElement&&(n=n.content,i=i.content),t||=n.firstChild;for(let f of i.childNodes){if(o(f))continue;if(t&&t!=a){let M=p(e,f,t,a);if(M){M!==t&&b(e,t,M),E(M,f,e),t=M.nextSibling;continue}}if(f instanceof Element){let M=f.getAttribute("id");if(e.persistentIds.has(M)){let w=g(n,M,t,e);E(w,f,e),t=w.nextSibling;continue}if(!e.idMap.has(f)){let w=e.hyperMatches.get(f);if(w&&!e.idMap.has(w)){c(n,w,t),E(w,f,e),t=w.nextSibling;continue}}}let m=A(n,f,t,e);m&&(t=m.nextSibling)}for(;t&&t!=a;){let f=t;t=t.nextSibling,o(f)||v(e,f)}}function A(e,n,i,t){if(t.callbacks.beforeNodeAdded(n)===!1)return null;if(t.idMap.has(n)){let a=document.createElement(n.tagName);return e.insertBefore(a,i),E(a,n,t),t.callbacks.afterNodeAdded(a),a}else{let a=document.importNode(n,!0);return e.insertBefore(a,i),t.callbacks.afterNodeAdded(a),a}}let p=(function(){function e(t,a,f,m){let M=a instanceof Element&&!t.idMap.has(a)?t.hyperMatches.get(a):null,w=null,O=a.nextSibling,j=0,L=f;for(;L&&L!=m;){if(i(L,a)){if(n(t,L,a)||L===M&&!t.idMap.has(L))return L;if(w===null){let _=L instanceof Element&&t.hyperMatchedOldElements.has(L);!t.idMap.has(L)&&!_&&(w=L)}}if(w===null&&O&&i(L,O)&&(j++,O=O.nextSibling,j>=2&&(w=void 0)),t.activeElementAndParents.includes(L))break;L=L.nextSibling}return w||null}function n(t,a,f){let m=t.idMap.get(a),M=t.idMap.get(f);if(!M||!m)return!1;for(let w of m)if(M.has(w))return!0;return!1}function i(t,a){let f=t,m=a;return f.nodeType===m.nodeType&&f.tagName===m.tagName&&(!f.getAttribute?.("id")||f.getAttribute?.("id")===m.getAttribute?.("id"))}return e})();function v(e,n){let i=n instanceof Element&&e.hyperMatchedOldElements.has(n)&&!e.idMap.has(n);if(e.idMap.has(n)||i)c(e.pantry,n,null);else{if(e.callbacks.beforeNodeRemoved(n)===!1)return;n.parentNode?.removeChild(n),e.callbacks.afterNodeRemoved(n)}}function b(e,n,i){let t=n;for(;t&&t!==i;){let a=t;t=t.nextSibling,o(a)||v(e,a)}return t}function g(e,n,i,t){let a=t.target.getAttribute?.("id")===n&&t.target||t.target.querySelector(`[id="${n}"]`)||t.pantry.querySelector(`[id="${n}"]`);return r(a,t),c(e,a,i),a}function r(e,n){let i=e.getAttribute("id");for(;e=e.parentNode;){let t=n.idMap.get(e);t&&(t.delete(i),t.size||n.idMap.delete(e))}}function c(e,n,i){if(e.moveBefore)try{e.moveBefore(n,i)}catch{e.insertBefore(n,i)}else e.insertBefore(n,i)}return l})(),E=(function(){function l(r,c,e){return e.ignoreActive&&r===document.activeElement?null:(e.callbacks.beforeNodeMorphed(r,c)===!1||(r instanceof HTMLHeadElement&&e.head.ignore||(r instanceof HTMLHeadElement&&e.head.style!=="morph"?T(r,c,e):(A(r,c,e),g(r,e)||I(e,r,c))),e.callbacks.afterNodeMorphed(r,c)),r)}function A(r,c,e){let n=c.nodeType;if(n===1){let i=r,t=c,a=i.attributes,f=t.attributes;for(let m of f)b(m.name,i,"update",e)||i.getAttribute(m.name)!==m.value&&i.setAttribute(m.name,m.value);for(let m=a.length-1;0<=m;m--){let M=a[m];if(M&&!t.hasAttribute(M.name)){if(b(M.name,i,"remove",e))continue;i.removeAttribute(M.name)}}g(i,e)||p(i,t,e)}(n===8||n===3)&&r.nodeValue!==c.nodeValue&&(r.nodeValue=c.nodeValue)}function p(r,c,e){if(r instanceof HTMLInputElement&&c instanceof HTMLInputElement&&c.type!=="file"){let n=c.value,i=r.value;v(r,c,"checked",e),v(r,c,"disabled",e),c.hasAttribute("value")?i!==n&&(b("value",r,"update",e)||(r.setAttribute("value",n),r.value=n)):b("value",r,"remove",e)||(r.value="",r.removeAttribute("value"))}else if(r instanceof HTMLOptionElement&&c instanceof HTMLOptionElement)v(r,c,"selected",e);else if(r instanceof HTMLTextAreaElement&&c instanceof HTMLTextAreaElement){let n=c.value,i=r.value;if(b("value",r,"update",e))return;n!==i&&(r.value=n),r.firstChild&&r.firstChild.nodeValue!==n&&(r.firstChild.nodeValue=n)}}function v(r,c,e,n){let i=c[e],t=r[e];if(i!==t){let a=b(e,r,"update",n);a||(r[e]=c[e]),i?a||r.setAttribute(e,""):b(e,r,"remove",n)||r.removeAttribute(e)}}function b(r,c,e,n){return r==="value"&&n.ignoreActiveValue&&c===document.activeElement?!0:n.callbacks.beforeAttributeUpdated(r,c,e)===!1}function g(r,c){return!!c.ignoreActiveValue&&r===document.activeElement&&r!==document.body}return l})();function x(l,A,p,v){if(l.head.block){let b=A.querySelector("head"),g=p.querySelector("head");if(b&&g){let r=T(b,g,l);return Promise.all(r).then(()=>{let c=Object.assign(l,{head:{block:!1,ignore:!0}});return v(c)})}}return v(l)}function T(l,A,p){let v=[],b=[],g=[],r=[],c=p.scripts.matchMode,e=t=>{if(t.tagName==="SCRIPT")return u(t,c);if(t.tagName==="LINK"&&c==="smart"){let a=t.getAttribute("href");if(a)try{let f=new URL(a,window.location.href);return`link:${t.getAttribute("rel")||""}:${f.origin}${f.pathname}`}catch{}}return t.outerHTML},n=new Map;for(let t of A.children)o(t)||n.set(e(t),t);for(let t of l.children){let a=e(t),f=n.has(a),m=p.head.shouldReAppend(t),M=p.head.shouldPreserve(t);f||M?m?b.push(t):(n.delete(a),g.push(t)):p.head.style==="append"?m&&(b.push(t),r.push(t)):p.head.shouldRemove(t)!==!1&&!o(t)&&b.push(t)}r.push(...n.values());let i=[];for(let t of r){let a=document.createRange().createContextualFragment(t.outerHTML).firstChild;if(p.callbacks.beforeNodeAdded(a)!==!1){if("href"in a&&a.href||"src"in a&&a.src){let f,m=new Promise(function(M){f=M});a.addEventListener("load",function(){f()}),i.push(m)}l.appendChild(a),p.callbacks.afterNodeAdded(a),v.push(a)}}for(let t of b)p.callbacks.beforeNodeRemoved(t)!==!1&&(l.removeChild(t),p.callbacks.afterNodeRemoved(t));return p.head.afterHeadMorphed(l,{added:v,kept:g,removed:b}),i}function k(l,A,p){if(!p.scripts.handle)return[];let v=[],b=[],g=[],r=[],c=p.scripts.matchMode,e=Array.from(l.querySelectorAll("script"));for(let i of e){let t=u(i,c),a=A.has(t),f=p.scripts.shouldPreserve(i),m=p.scripts.shouldReAppend(i);a||f?m?(b.push(i),r.push(i)):g.push(i):r.push(i)}for(let i of A){let t=e.some(a=>a.outerHTML===i)}let n=[];for(let i of r){if(p.callbacks.beforeNodeAdded(i)===!1)continue;let t=document.createRange().createContextualFragment(i.outerHTML).firstChild;if(t.src){let a,f=new Promise(function(m){a=m});t.addEventListener("load",function(){a()}),t.addEventListener("error",function(){a()}),n.push(f)}i.replaceWith(t),p.callbacks.afterNodeAdded(t),v.push(t)}return p.scripts.afterScriptsHandled(l,{added:v,kept:g,removed:b}),n}let N=(function(){function l(e,n,i){let{persistentIds:t,idMap:a}=r(e,n),f=h.computeMatches(e,n),m=new Set;for(let O of f.values())m.add(O);let M=A(i),w=M.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(w))throw`Do not understand how to morph style ${w}`;return{target:e,newContent:n,config:M,morphStyle:w,ignoreActive:M.ignoreActive,ignoreActiveValue:M.ignoreActiveValue,restoreFocus:M.restoreFocus,idMap:a,persistentIds:t,hyperMatches:f,hyperMatchedOldElements:m,pantry:p(),activeElementAndParents:v(e),callbacks:M.callbacks,head:M.head,scripts:M.scripts}}function A(e){let n=Object.assign({},d);return Object.assign(n,e),n.callbacks=Object.assign({},d.callbacks,e.callbacks),n.head=Object.assign({},d.head,e.head),n.scripts=Object.assign({},d.scripts,e.scripts),n}function p(){let e=document.createElement("div");return e.hidden=!0,document.body.insertAdjacentElement("afterend",e),e}function v(e){let n=[],i=document.activeElement;if(i?.tagName!=="BODY"&&e.contains(i))for(;i&&(n.push(i),i!==e);)i=i.parentElement;return n}function b(e){let n=Array.from(e.querySelectorAll("[id]"));return e.getAttribute?.("id")&&n.push(e),n}function g(e,n,i,t){for(let a of t){let f=a.getAttribute("id");if(n.has(f)){let m=a;for(;m;){let M=e.get(m);if(M==null&&(M=new Set,e.set(m,M)),M.add(f),m===i)break;m=m.parentElement}}}}function r(e,n){let i=b(e),t=b(n),a=c(i,t),f=new Map;g(f,a,e,i);let m=n.__hyperMorphRoot||n;return g(f,a,m,t),{persistentIds:a,idMap:f}}function c(e,n){let i=new Set,t=new Map;for(let{id:f,tagName:m}of e)t.has(f)?i.add(f):t.set(f,m);let a=new Set;for(let{id:f,tagName:m}of n)a.has(f)?i.add(f):t.get(f)===m&&a.add(f);for(let f of i)a.delete(f);return a}return l})(),{normalizeElement:R,normalizeParent:B}=(function(){let l=new WeakSet;function A(g){return g instanceof Document?g.documentElement:g}function p(g){if(g==null)return document.createElement("div");if(typeof g=="string")return p(b(g));if(l.has(g))return g;if(g instanceof Node){if(g.parentNode)return new v(g);{let r=document.createElement("div");return r.append(g),r}}else{let r=document.createElement("div");for(let c of[...g])r.append(c);return r}}class v{constructor(r){this.originalNode=r,this.realParentNode=r.parentNode,this.previousSibling=r.previousSibling,this.nextSibling=r.nextSibling}get childNodes(){let r=[],c=this.previousSibling?this.previousSibling.nextSibling:this.realParentNode.firstChild;for(;c&&c!=this.nextSibling;)r.push(c),c=c.nextSibling;return r}querySelectorAll(r){return this.childNodes.reduce((c,e)=>{if(e instanceof Element){e.matches(r)&&c.push(e);let n=e.querySelectorAll(r);for(let i=0;i<n.length;i++)c.push(n[i])}return c},[])}insertBefore(r,c){return this.realParentNode.insertBefore(r,c)}moveBefore(r,c){return this.realParentNode.moveBefore(r,c)}get __hyperMorphRoot(){return this.originalNode}}function b(g){let r=new DOMParser,c=g.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(c.match(/<\/html>/)||c.match(/<\/head>/)||c.match(/<\/body>/)){let e=r.parseFromString(g,"text/html");if(c.match(/<\/html>/))return l.add(e),e;{let n=e.firstChild;return n&&l.add(n),n}}else{let n=r.parseFromString("<body><template>"+g+"</template></body>","text/html").body.querySelector("template").content;return l.add(n),n}}return{normalizeElement:A,normalizeParent:p}})();return{morph:y,defaults:d}})();var de=$.morph,fe=$.defaults,he=$;return X(pe);})();
|
|
2
|
+
|
|
3
|
+
// Convenience morph wrapper with data-id support
|
|
4
|
+
var morph = function(oldEl, newEl, options = {}) {
|
|
5
|
+
return HyperMorph.morph(oldEl, newEl, {
|
|
6
|
+
key: (el) => el.getAttribute('data-id') || el.id,
|
|
7
|
+
...options
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// Auto-export to window unless suppressed by loader
|
|
12
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
13
|
+
window.hyperclay = window.hyperclay || {};
|
|
14
|
+
window.hyperclay.HyperMorph = HyperMorph;
|
|
15
|
+
window.hyperclay.morph = morph;
|
|
16
|
+
window.HyperMorph = HyperMorph;
|
|
17
|
+
window.morph = morph;
|
|
18
|
+
window.h = window.hyperclay;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { HyperMorph, morph };
|
|
22
|
+
export default HyperMorph;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
var Idiomorph=function(){"use strict";let o=new Set;let n={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:t,afterNodeAdded:t,beforeNodeMorphed:t,afterNodeMorphed:t,beforeNodeRemoved:t,afterNodeRemoved:t,beforeAttributeUpdated:t},head:{style:"merge",shouldPreserve:function(e){return e.getAttribute("im-preserve")==="true"},shouldReAppend:function(e){return e.getAttribute("im-re-append")==="true"},shouldRemove:t,afterHeadMorphed:t}};function e(e,t,n={}){if(e instanceof Document){e=e.documentElement}if(typeof t==="string"){t=k(t)}let l=y(t);let r=p(e,l,n);return a(e,l,r)}function a(r,i,o){if(o.head.block){let t=r.querySelector("head");let n=i.querySelector("head");if(t&&n){let e=c(n,t,o);Promise.all(e).then(function(){a(r,i,Object.assign(o,{head:{block:false,ignore:true}}))});return}}if(o.morphStyle==="innerHTML"){l(i,r,o);return r.children}else if(o.morphStyle==="outerHTML"||o.morphStyle==null){let e=M(i,r,o);let t=e?.previousSibling;let n=e?.nextSibling;let l=d(r,e,o);if(e){return N(t,l,n)}else{return[]}}else{throw"Do not understand how to morph style "+o.morphStyle}}function u(e,t){return t.ignoreActiveValue&&e===document.activeElement}function d(e,t,n){if(n.ignoreActive&&e===document.activeElement){}else if(t==null){if(n.callbacks.beforeNodeRemoved(e)===false)return e;e.remove();n.callbacks.afterNodeRemoved(e);return null}else if(!g(e,t)){if(n.callbacks.beforeNodeRemoved(e)===false)return e;if(n.callbacks.beforeNodeAdded(t)===false)return e;e.parentElement.replaceChild(t,e);n.callbacks.afterNodeAdded(t);n.callbacks.afterNodeRemoved(e);return t}else{if(n.callbacks.beforeNodeMorphed(e,t)===false)return e;if(e instanceof HTMLHeadElement&&n.head.ignore){}else if(e instanceof HTMLHeadElement&&n.head.style!=="morph"){c(t,e,n)}else{r(t,e,n);if(!u(e,n)){l(t,e,n)}}n.callbacks.afterNodeMorphed(e,t);return e}}function l(n,l,r){let i=n.firstChild;let o=l.firstChild;let a;while(i){a=i;i=a.nextSibling;if(o==null){if(r.callbacks.beforeNodeAdded(a)===false)return;l.appendChild(a);r.callbacks.afterNodeAdded(a);H(r,a);continue}if(b(a,o,r)){d(o,a,r);o=o.nextSibling;H(r,a);continue}let e=A(n,l,a,o,r);if(e){o=v(o,e,r);d(e,a,r);H(r,a);continue}let t=S(n,l,a,o,r);if(t){o=v(o,t,r);d(t,a,r);H(r,a);continue}if(r.callbacks.beforeNodeAdded(a)===false)return;l.insertBefore(a,o);r.callbacks.afterNodeAdded(a);H(r,a)}while(o!==null){let e=o;o=o.nextSibling;T(e,r)}}function f(e,t,n,l){if(e==="value"&&l.ignoreActiveValue&&t===document.activeElement){return true}return l.callbacks.beforeAttributeUpdated(e,t,n)===false}function r(t,n,l){let e=t.nodeType;if(e===1){const r=t.attributes;const i=n.attributes;for(const o of r){if(f(o.name,n,"update",l)){continue}if(n.getAttribute(o.name)!==o.value){n.setAttribute(o.name,o.value)}}for(let e=i.length-1;0<=e;e--){const a=i[e];if(f(a.name,n,"remove",l)){continue}if(!t.hasAttribute(a.name)){n.removeAttribute(a.name)}}}if(e===8||e===3){if(n.nodeValue!==t.nodeValue){n.nodeValue=t.nodeValue}}if(!u(n,l)){s(t,n,l)}}function i(t,n,l,r){if(t[l]!==n[l]){let e=f(l,n,"update",r);if(!e){n[l]=t[l]}if(t[l]){if(!e){n.setAttribute(l,t[l])}}else{if(!f(l,n,"remove",r)){n.removeAttribute(l)}}}}function s(n,l,r){if(n instanceof HTMLInputElement&&l instanceof HTMLInputElement&&n.type!=="file"){let e=n.value;let t=l.value;i(n,l,"checked",r);i(n,l,"disabled",r);if(!n.hasAttribute("value")){if(!f("value",l,"remove",r)){l.value="";l.removeAttribute("value")}}else if(e!==t){if(!f("value",l,"update",r)){l.setAttribute("value",e);l.value=e}}}else if(n instanceof HTMLOptionElement){i(n,l,"selected",r)}else if(n instanceof HTMLTextAreaElement&&l instanceof HTMLTextAreaElement){let e=n.value;let t=l.value;if(f("value",l,"update",r)){return}if(e!==t){l.value=e}if(l.firstChild&&l.firstChild.nodeValue!==e){l.firstChild.nodeValue=e}}}function c(e,t,l){let r=[];let i=[];let o=[];let a=[];let u=l.head.style;let d=new Map;for(const n of e.children){d.set(n.outerHTML,n)}for(const s of t.children){let e=d.has(s.outerHTML);let t=l.head.shouldReAppend(s);let n=l.head.shouldPreserve(s);if(e||n){if(t){i.push(s)}else{d.delete(s.outerHTML);o.push(s)}}else{if(u==="append"){if(t){i.push(s);a.push(s)}}else{if(l.head.shouldRemove(s)!==false){i.push(s)}}}}a.push(...d.values());m("to append: ",a);let f=[];for(const c of a){m("adding: ",c);let n=document.createRange().createContextualFragment(c.outerHTML).firstChild;m(n);if(l.callbacks.beforeNodeAdded(n)!==false){if(n.href||n.src){let t=null;let e=new Promise(function(e){t=e});n.addEventListener("load",function(){t()});f.push(e)}t.appendChild(n);l.callbacks.afterNodeAdded(n);r.push(n)}}for(const h of i){if(l.callbacks.beforeNodeRemoved(h)!==false){t.removeChild(h);l.callbacks.afterNodeRemoved(h)}}l.head.afterHeadMorphed(t,{added:r,kept:o,removed:i});return f}function m(){}function t(){}function h(e){let t={};Object.assign(t,n);Object.assign(t,e);t.callbacks={};Object.assign(t.callbacks,n.callbacks);Object.assign(t.callbacks,e.callbacks);t.head={};Object.assign(t.head,n.head);Object.assign(t.head,e.head);return t}function p(e,t,n){n=h(n);return{target:e,newContent:t,config:n,morphStyle:n.morphStyle,ignoreActive:n.ignoreActive,ignoreActiveValue:n.ignoreActiveValue,idMap:C(e,t),deadIds:new Set,callbacks:n.callbacks,head:n.head}}function b(e,t,n){if(e==null||t==null){return false}if(e.nodeType===t.nodeType&&e.tagName===t.tagName){if(e.id!==""&&e.id===t.id){return true}else{return L(n,e,t)>0}}return false}function g(e,t){if(e==null||t==null){return false}return e.nodeType===t.nodeType&&e.tagName===t.tagName}function v(t,e,n){while(t!==e){let e=t;t=t.nextSibling;T(e,n)}H(n,e);return e.nextSibling}function A(n,e,l,r,i){let o=L(i,l,e);let t=null;if(o>0){let e=r;let t=0;while(e!=null){if(b(l,e,i)){return e}t+=L(i,e,n);if(t>o){return null}e=e.nextSibling}}return t}function S(e,t,n,l,r){let i=l;let o=n.nextSibling;let a=0;while(i!=null){if(L(r,i,e)>0){return null}if(g(n,i)){return i}if(g(o,i)){a++;o=o.nextSibling;if(a>=2){return null}}i=i.nextSibling}return i}function k(n){let l=new DOMParser;let e=n.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(e.match(/<\/html>/)||e.match(/<\/head>/)||e.match(/<\/body>/)){let t=l.parseFromString(n,"text/html");if(e.match(/<\/html>/)){t.generatedByIdiomorph=true;return t}else{let e=t.firstChild;if(e){e.generatedByIdiomorph=true;return e}else{return null}}}else{let e=l.parseFromString("<body><template>"+n+"</template></body>","text/html");let t=e.body.querySelector("template").content;t.generatedByIdiomorph=true;return t}}function y(e){if(e==null){const t=document.createElement("div");return t}else if(e.generatedByIdiomorph){return e}else if(e instanceof Node){const t=document.createElement("div");t.append(e);return t}else{const t=document.createElement("div");for(const n of[...e]){t.append(n)}return t}}function N(e,t,n){let l=[];let r=[];while(e!=null){l.push(e);e=e.previousSibling}while(l.length>0){let e=l.pop();r.push(e);t.parentElement.insertBefore(e,t)}r.push(t);while(n!=null){l.push(n);r.push(n);n=n.nextSibling}while(l.length>0){t.parentElement.insertBefore(l.pop(),t.nextSibling)}return r}function M(e,t,n){let l;l=e.firstChild;let r=l;let i=0;while(l){let e=w(l,t,n);if(e>i){r=l;i=e}l=l.nextSibling}return r}function w(e,t,n){if(g(e,t)){return.5+L(n,e,t)}return 0}function T(e,t){H(t,e);if(t.callbacks.beforeNodeRemoved(e)===false)return;e.remove();t.callbacks.afterNodeRemoved(e)}function E(e,t){return!e.deadIds.has(t)}function x(e,t,n){let l=e.idMap.get(n)||o;return l.has(t)}function H(e,t){let n=e.idMap.get(t)||o;for(const l of n){e.deadIds.add(l)}}function L(e,t,n){let l=e.idMap.get(t)||o;let r=0;for(const i of l){if(E(e,i)&&x(e,i,n)){++r}}return r}function R(e,n){let l=e.parentElement;let t=e.querySelectorAll("[id]");for(const r of t){let t=r;while(t!==l&&t!=null){let e=n.get(t);if(e==null){e=new Set;n.set(t,e)}e.add(r.id);t=t.parentElement}}}function C(e,t){let n=new Map;R(e,n);R(t,n);return n}return{morph:e,defaults:n}}();
|
|
2
|
-
// MODIFIED, added `morph`
|
|
3
|
-
var morph = function(oldEl, newEl, options = {}) {
|
|
4
|
-
return Idiomorph.morph(oldEl, newEl, {
|
|
5
|
-
key: (el) => el.getAttribute('data-id') || el.id,
|
|
6
|
-
...options
|
|
7
|
-
});
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
// Auto-export to window unless suppressed by loader
|
|
11
|
-
if (!window.__hyperclayNoAutoExport) {
|
|
12
|
-
window.hyperclay = window.hyperclay || {};
|
|
13
|
-
window.hyperclay.Idiomorph = Idiomorph;
|
|
14
|
-
window.hyperclay.morph = morph;
|
|
15
|
-
window.morph = morph;
|
|
16
|
-
window.h = window.hyperclay;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export { Idiomorph, morph };
|
|
20
|
-
export default Idiomorph;
|