@hortonstudio/main 1.6.0 → 1.6.2
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/autoInit/accessibility.js +93 -0
- package/autoInit/transition.js +0 -16
- package/index.js +1 -1
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@ export function init() {
|
|
|
10
10
|
setupPreventDefault();
|
|
11
11
|
setupRichTextAccessibility();
|
|
12
12
|
setupSummaryAccessibility();
|
|
13
|
+
setupCustomValuesReplacement();
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
function setupListAccessibility() {
|
|
@@ -339,6 +340,98 @@ export function init() {
|
|
|
339
340
|
});
|
|
340
341
|
}
|
|
341
342
|
|
|
343
|
+
function setupCustomValuesReplacement() {
|
|
344
|
+
const customValuesList = document.querySelector('[data-hs-a11y="custom-values-list"]');
|
|
345
|
+
|
|
346
|
+
if (!customValuesList) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Collect all custom values data
|
|
351
|
+
const customValues = {};
|
|
352
|
+
const descendants = customValuesList.getElementsByTagName('*');
|
|
353
|
+
|
|
354
|
+
Array.from(descendants).forEach(descendant => {
|
|
355
|
+
const nameElement = descendant.querySelector('[data-hs-a11y="custom-values-name"]');
|
|
356
|
+
const valueElement = descendant.querySelector('[data-hs-a11y="custom-values-value"]');
|
|
357
|
+
|
|
358
|
+
if (nameElement && valueElement) {
|
|
359
|
+
const name = nameElement.textContent.trim();
|
|
360
|
+
const value = valueElement.textContent.trim();
|
|
361
|
+
|
|
362
|
+
if (name && value) {
|
|
363
|
+
customValues[name] = value;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// If no custom values found, exit early
|
|
369
|
+
if (Object.keys(customValues).length === 0) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Replace text content efficiently using TreeWalker
|
|
374
|
+
const walker = document.createTreeWalker(
|
|
375
|
+
document.body,
|
|
376
|
+
NodeFilter.SHOW_TEXT,
|
|
377
|
+
{
|
|
378
|
+
acceptNode: (node) => {
|
|
379
|
+
// Check if any custom value names exist in the text content
|
|
380
|
+
const text = node.textContent;
|
|
381
|
+
for (const name in customValues) {
|
|
382
|
+
if (text.includes(`{{${name}}}`)) {
|
|
383
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return NodeFilter.FILTER_SKIP;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
const textNodes = [];
|
|
392
|
+
let node;
|
|
393
|
+
while (node = walker.nextNode()) {
|
|
394
|
+
textNodes.push(node);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Replace text in collected nodes
|
|
398
|
+
textNodes.forEach(textNode => {
|
|
399
|
+
let newText = textNode.textContent;
|
|
400
|
+
let hasChanges = false;
|
|
401
|
+
|
|
402
|
+
for (const name in customValues) {
|
|
403
|
+
const placeholder = `{{${name}}}`;
|
|
404
|
+
if (newText.includes(placeholder)) {
|
|
405
|
+
newText = newText.replace(new RegExp(placeholder, 'g'), customValues[name]);
|
|
406
|
+
hasChanges = true;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (hasChanges) {
|
|
411
|
+
textNode.textContent = newText;
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
// Replace link hrefs
|
|
416
|
+
const links = document.querySelectorAll('a[href]');
|
|
417
|
+
links.forEach(link => {
|
|
418
|
+
let href = link.getAttribute('href');
|
|
419
|
+
let hasChanges = false;
|
|
420
|
+
|
|
421
|
+
for (const name in customValues) {
|
|
422
|
+
const placeholder = `{{${name}}}`;
|
|
423
|
+
if (href.includes(placeholder)) {
|
|
424
|
+
href = href.replace(new RegExp(placeholder, 'g'), customValues[name]);
|
|
425
|
+
hasChanges = true;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (hasChanges) {
|
|
430
|
+
link.setAttribute('href', href);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
|
|
342
435
|
function setupRichTextAccessibility() {
|
|
343
436
|
const contentAreas = document.querySelectorAll('[data-hs-a11y="rich-content"]');
|
|
344
437
|
const tocLists = document.querySelectorAll('[data-hs-a11y="rich-toc"]');
|
package/autoInit/transition.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
// Page Transition Module
|
|
2
2
|
const API_NAME = "hsmain";
|
|
3
|
-
let initialized = false;
|
|
4
3
|
|
|
5
4
|
export async function init() {
|
|
6
|
-
console.log('[Transition] Module init called');
|
|
7
5
|
|
|
8
6
|
// Wait for Webflow to be ready before initializing transitions
|
|
9
7
|
window[API_NAME].afterWebflowReady(() => {
|
|
10
|
-
console.log('[Transition] afterWebflowReady callback fired');
|
|
11
8
|
setTimeout(() => {
|
|
12
|
-
console.log('[Transition] Attempting to initialize transitions');
|
|
13
9
|
initTransitions();
|
|
14
10
|
initialized = true;
|
|
15
11
|
}, 50);
|
|
@@ -19,11 +15,8 @@ export async function init() {
|
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
function initTransitions() {
|
|
22
|
-
console.log('[Transition] initTransitions called');
|
|
23
18
|
const transitionTrigger = document.querySelector(".transition-trigger");
|
|
24
19
|
const transitionElement = document.querySelector(".transition");
|
|
25
|
-
console.log('[Transition] transitionTrigger found:', transitionTrigger);
|
|
26
|
-
console.log('[Transition] transitionElement found:', transitionElement);
|
|
27
20
|
|
|
28
21
|
let excludedClass = "no-transition";
|
|
29
22
|
|
|
@@ -34,19 +27,14 @@ function initTransitions() {
|
|
|
34
27
|
const delayAttr = transitionElement?.getAttribute('data-hs-delay');
|
|
35
28
|
const delaySeconds = delayAttr ? parseFloat(delayAttr) : 0;
|
|
36
29
|
|
|
37
|
-
console.log('[Transition] First load:', isFirstLoad);
|
|
38
|
-
console.log('[Transition] Delay attribute:', delayAttr);
|
|
39
|
-
console.log('[Transition] Delay seconds:', delaySeconds);
|
|
40
30
|
|
|
41
31
|
const triggerAnimation = () => {
|
|
42
|
-
console.log('[Transition] Triggering page load transition');
|
|
43
32
|
Webflow.push(function () {
|
|
44
33
|
transitionTrigger.click();
|
|
45
34
|
});
|
|
46
35
|
};
|
|
47
36
|
|
|
48
37
|
if (isFirstLoad && delaySeconds > 0) {
|
|
49
|
-
console.log(`[Transition] Delaying first load by ${delaySeconds} seconds`);
|
|
50
38
|
setTimeout(triggerAnimation, delaySeconds * 1000);
|
|
51
39
|
sessionStorage.setItem('transition-loaded', 'true');
|
|
52
40
|
} else {
|
|
@@ -63,7 +51,6 @@ function initTransitions() {
|
|
|
63
51
|
|
|
64
52
|
const checkComplete = () => {
|
|
65
53
|
if (transitionElement.classList.contains('transition-done')) {
|
|
66
|
-
console.log('[Transition] Animation complete detected');
|
|
67
54
|
callback();
|
|
68
55
|
} else {
|
|
69
56
|
setTimeout(checkComplete, 50);
|
|
@@ -73,7 +60,6 @@ function initTransitions() {
|
|
|
73
60
|
}
|
|
74
61
|
|
|
75
62
|
// On Link Click
|
|
76
|
-
console.log('[Transition] Setting up click handler');
|
|
77
63
|
document.addEventListener("click", function (e) {
|
|
78
64
|
const link = e.target.closest("a");
|
|
79
65
|
|
|
@@ -86,7 +72,6 @@ function initTransitions() {
|
|
|
86
72
|
link.getAttribute("target") !== "_blank" &&
|
|
87
73
|
transitionTrigger
|
|
88
74
|
) {
|
|
89
|
-
console.log('[Transition] Triggering exit transition to:', link.getAttribute("href"));
|
|
90
75
|
e.preventDefault();
|
|
91
76
|
|
|
92
77
|
let transitionURL = link.getAttribute("href");
|
|
@@ -96,7 +81,6 @@ function initTransitions() {
|
|
|
96
81
|
|
|
97
82
|
// Wait for animation to complete before navigating
|
|
98
83
|
waitForTransitionComplete(() => {
|
|
99
|
-
console.log('[Transition] Navigating to:', transitionURL);
|
|
100
84
|
window.location = transitionURL;
|
|
101
85
|
});
|
|
102
86
|
}
|
package/index.js
CHANGED