@hortonstudio/main 1.2.6 → 1.2.7
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/index.js +253 -247
- package/package.json +1 -1
package/index.js
CHANGED
@@ -1,286 +1,292 @@
|
|
1
|
-
// ver 1.2.
|
1
|
+
// ver 1.2.6
|
2
2
|
|
3
3
|
const API_NAME = 'hsmain';
|
4
4
|
|
5
|
-
console.log(`🟢 ${API_NAME} v1.2.
|
5
|
+
console.log(`🟢 ${API_NAME} v1.2.6 initializing...`);
|
6
6
|
console.log('🔍 DOM state:', document.readyState);
|
7
7
|
console.log('🔍 Script URL:', import.meta.url);
|
8
8
|
|
9
|
-
//
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
// Main initialization function
|
10
|
+
const initializeHsMain = () => {
|
11
|
+
// Handle existing API
|
12
|
+
if (window[API_NAME] && !Array.isArray(window[API_NAME]) && window[API_NAME].loaded) {
|
13
|
+
console.log('⚠️ API already loaded, skipping initialization');
|
14
|
+
return;
|
15
|
+
}
|
14
16
|
|
15
|
-
// Store any early API calls
|
16
|
-
const existingRequests = Array.isArray(window[API_NAME]) ? window[API_NAME] : [];
|
17
|
+
// Store any early API calls
|
18
|
+
const existingRequests = Array.isArray(window[API_NAME]) ? window[API_NAME] : [];
|
17
19
|
|
18
|
-
// Module definitions
|
19
|
-
const animationModules = {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
};
|
20
|
+
// Module definitions
|
21
|
+
const animationModules = {
|
22
|
+
"data-hs-anim-text": true,
|
23
|
+
"data-hs-anim-hero": true,
|
24
|
+
"data-hs-anim-transition": true
|
25
|
+
};
|
24
26
|
|
25
|
-
const utilityModules = {
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
};
|
27
|
+
const utilityModules = {
|
28
|
+
"data-hs-util-toc": true,
|
29
|
+
"data-hs-util-progress": true,
|
30
|
+
"data-hs-util-navbar": true
|
31
|
+
};
|
30
32
|
|
31
|
-
const autoInitModules = {
|
32
|
-
|
33
|
-
};
|
33
|
+
const autoInitModules = {
|
34
|
+
"smooth-scroll": true
|
35
|
+
};
|
34
36
|
|
35
|
-
// All available modules
|
36
|
-
const allModules = { ...animationModules, ...utilityModules };
|
37
|
+
// All available modules
|
38
|
+
const allModules = { ...animationModules, ...utilityModules };
|
37
39
|
|
38
|
-
// Dynamic module loader (like Finsweet)
|
39
|
-
const loadModule = async (moduleName) => {
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
};
|
40
|
+
// Dynamic module loader (like Finsweet)
|
41
|
+
const loadModule = async (moduleName) => {
|
42
|
+
console.log(`📦 Loading module: ${moduleName}`);
|
43
|
+
|
44
|
+
switch (moduleName) {
|
45
|
+
case "data-hs-anim-text":
|
46
|
+
return import(new URL('./animations/text.js', import.meta.url).href);
|
47
|
+
case "data-hs-anim-hero":
|
48
|
+
return import(new URL('./animations/hero.js', import.meta.url).href);
|
49
|
+
case "data-hs-anim-transition":
|
50
|
+
return import(new URL('./animations/transition.js', import.meta.url).href);
|
51
|
+
case "data-hs-util-toc":
|
52
|
+
return import(new URL('./utils/toc.js', import.meta.url).href);
|
53
|
+
case "data-hs-util-progress":
|
54
|
+
return import(new URL('./utils/scroll-progress.js', import.meta.url).href);
|
55
|
+
case "data-hs-util-navbar":
|
56
|
+
return import(new URL('./utils/navbar.js', import.meta.url).href);
|
57
|
+
case "smooth-scroll":
|
58
|
+
return import(new URL('./autoInit/smooth-scroll.js', import.meta.url).href);
|
59
|
+
default:
|
60
|
+
console.error(`❌ Unsupported module: ${moduleName}`);
|
61
|
+
throw new Error(`${API_NAME} module "${moduleName}" is not supported.`);
|
62
|
+
}
|
63
|
+
};
|
62
64
|
|
63
|
-
// Webflow ready helper (like Finsweet)
|
64
|
-
const waitWebflowReady = async () => {
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
};
|
65
|
+
// Webflow ready helper (like Finsweet)
|
66
|
+
const waitWebflowReady = async () => {
|
67
|
+
return new Promise((resolve) => {
|
68
|
+
window.Webflow ||= [];
|
69
|
+
window.Webflow.push(resolve);
|
70
|
+
});
|
71
|
+
};
|
70
72
|
|
71
|
-
// DOM ready helper (like Finsweet)
|
72
|
-
const waitDOMReady = async () => {
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
};
|
73
|
+
// DOM ready helper (like Finsweet)
|
74
|
+
const waitDOMReady = async () => {
|
75
|
+
return new Promise((resolve) => {
|
76
|
+
if (document.readyState === 'loading') {
|
77
|
+
document.addEventListener('DOMContentLoaded', resolve);
|
78
|
+
} else {
|
79
|
+
resolve();
|
80
|
+
}
|
81
|
+
});
|
82
|
+
};
|
81
83
|
|
82
|
-
// Find script tags (Finsweet approach)
|
83
|
-
const scripts = [...document.querySelectorAll(`script[type="module"][src="${import.meta.url}"]`)];
|
84
|
-
console.log(`📄 Found ${scripts.length} matching script tags`);
|
84
|
+
// Find script tags (Finsweet approach)
|
85
|
+
const scripts = [...document.querySelectorAll(`script[type="module"][src="${import.meta.url}"]`)];
|
86
|
+
console.log(`📄 Found ${scripts.length} matching script tags`);
|
85
87
|
|
86
|
-
// Module loading function
|
87
|
-
const loadHsModule = async (moduleName) => {
|
88
|
-
|
89
|
-
|
90
|
-
const apiInstance = window[API_NAME];
|
91
|
-
|
92
|
-
// Check if already processing
|
93
|
-
if (apiInstance.process.has(moduleName)) {
|
94
|
-
console.log(`⚠️ Module ${moduleName} already processing`);
|
95
|
-
return apiInstance.modules[moduleName]?.loading;
|
96
|
-
}
|
97
|
-
|
98
|
-
// Add to processing set
|
99
|
-
console.log(`➕ Adding ${moduleName} to process set`);
|
100
|
-
apiInstance.process.add(moduleName);
|
101
|
-
|
102
|
-
// Create module object
|
103
|
-
const moduleObj = apiInstance.modules[moduleName] || {};
|
104
|
-
apiInstance.modules[moduleName] = moduleObj;
|
105
|
-
|
106
|
-
// Create loading promise
|
107
|
-
moduleObj.loading = new Promise((resolve, reject) => {
|
108
|
-
moduleObj.resolve = resolve;
|
109
|
-
moduleObj.reject = reject;
|
110
|
-
});
|
111
|
-
|
112
|
-
try {
|
113
|
-
console.log(`📦 Importing ${moduleName}...`);
|
114
|
-
const { init, version } = await loadModule(moduleName);
|
115
|
-
console.log(`✅ ${moduleName} imported, version: ${version}`);
|
116
|
-
|
117
|
-
console.log(`🔧 Initializing ${moduleName}...`);
|
118
|
-
const initResult = await init();
|
119
|
-
const { result, destroy } = initResult || {};
|
120
|
-
console.log(`✅ ${moduleName} initialized:`, result);
|
88
|
+
// Module loading function
|
89
|
+
const loadHsModule = async (moduleName) => {
|
90
|
+
console.log(`🔄 loadHsModule called for: ${moduleName}`);
|
121
91
|
|
122
|
-
|
92
|
+
const apiInstance = window[API_NAME];
|
123
93
|
|
124
|
-
//
|
125
|
-
|
126
|
-
|
127
|
-
apiInstance.
|
128
|
-
}
|
94
|
+
// Check if already processing
|
95
|
+
if (apiInstance.process.has(moduleName)) {
|
96
|
+
console.log(`⚠️ Module ${moduleName} already processing`);
|
97
|
+
return apiInstance.modules[moduleName]?.loading;
|
98
|
+
}
|
129
99
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
};
|
100
|
+
// Add to processing set
|
101
|
+
console.log(`➕ Adding ${moduleName} to process set`);
|
102
|
+
apiInstance.process.add(moduleName);
|
134
103
|
|
135
|
-
|
136
|
-
|
137
|
-
|
104
|
+
// Create module object
|
105
|
+
const moduleObj = apiInstance.modules[moduleName] || {};
|
106
|
+
apiInstance.modules[moduleName] = moduleObj;
|
138
107
|
|
139
|
-
|
108
|
+
// Create loading promise
|
109
|
+
moduleObj.loading = new Promise((resolve, reject) => {
|
110
|
+
moduleObj.resolve = resolve;
|
111
|
+
moduleObj.reject = reject;
|
112
|
+
});
|
140
113
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
} else {
|
163
|
-
this.load(moduleName);
|
164
|
-
}
|
165
|
-
}
|
166
|
-
},
|
167
|
-
|
168
|
-
// Destroy all modules
|
169
|
-
destroy() {
|
170
|
-
for (let moduleName in this.modules) {
|
171
|
-
this.modules[moduleName]?.destroy?.();
|
172
|
-
}
|
173
|
-
},
|
174
|
-
|
175
|
-
// Status method
|
176
|
-
status(moduleName) {
|
177
|
-
if (!moduleName) {
|
178
|
-
return {
|
179
|
-
loaded: Object.keys(this.modules),
|
180
|
-
loading: [...this.process],
|
181
|
-
animations: Object.keys(animationModules),
|
182
|
-
utilities: Object.keys(utilityModules),
|
183
|
-
autoInit: Object.keys(autoInitModules)
|
114
|
+
try {
|
115
|
+
console.log(`📦 Importing ${moduleName}...`);
|
116
|
+
const { init, version } = await loadModule(moduleName);
|
117
|
+
console.log(`✅ ${moduleName} imported, version: ${version}`);
|
118
|
+
|
119
|
+
console.log(`🔧 Initializing ${moduleName}...`);
|
120
|
+
const initResult = await init();
|
121
|
+
const { result, destroy } = initResult || {};
|
122
|
+
console.log(`✅ ${moduleName} initialized:`, result);
|
123
|
+
|
124
|
+
moduleObj.version = version;
|
125
|
+
|
126
|
+
// Add destroy and restart methods
|
127
|
+
moduleObj.destroy = () => {
|
128
|
+
destroy?.();
|
129
|
+
apiInstance.process.delete(moduleName);
|
130
|
+
};
|
131
|
+
|
132
|
+
moduleObj.restart = () => {
|
133
|
+
moduleObj.destroy?.();
|
134
|
+
return apiInstance.load(moduleName);
|
184
135
|
};
|
136
|
+
|
137
|
+
moduleObj.resolve?.(result);
|
138
|
+
delete moduleObj.resolve;
|
139
|
+
delete moduleObj.reject;
|
140
|
+
|
141
|
+
return result;
|
142
|
+
|
143
|
+
} catch (error) {
|
144
|
+
console.error(`❌ Failed to load ${moduleName}:`, error);
|
145
|
+
moduleObj.reject?.(error);
|
146
|
+
apiInstance.process.delete(moduleName);
|
147
|
+
throw error;
|
185
148
|
}
|
186
|
-
|
187
|
-
loaded: !!this.modules[moduleName],
|
188
|
-
loading: this.process.has(moduleName)
|
189
|
-
};
|
190
|
-
}
|
191
|
-
};
|
149
|
+
};
|
192
150
|
|
193
|
-
//
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
151
|
+
// Initialize API
|
152
|
+
window[API_NAME] = {
|
153
|
+
scripts,
|
154
|
+
modules: {},
|
155
|
+
process: new Set(),
|
156
|
+
load: loadHsModule,
|
157
|
+
loaded: false,
|
199
158
|
|
200
|
-
//
|
201
|
-
|
202
|
-
|
159
|
+
// Push method for queuing
|
160
|
+
push(...requests) {
|
161
|
+
for (let [moduleName, callback] of requests) {
|
162
|
+
if (typeof callback === 'function') {
|
163
|
+
this.modules[moduleName]?.loading?.then(callback);
|
164
|
+
} else {
|
165
|
+
this.load(moduleName);
|
166
|
+
}
|
167
|
+
}
|
168
|
+
},
|
169
|
+
|
170
|
+
// Destroy all modules
|
171
|
+
destroy() {
|
172
|
+
for (let moduleName in this.modules) {
|
173
|
+
this.modules[moduleName]?.destroy?.();
|
174
|
+
}
|
175
|
+
},
|
203
176
|
|
204
|
-
//
|
205
|
-
|
206
|
-
if (
|
207
|
-
|
208
|
-
|
177
|
+
// Status method
|
178
|
+
status(moduleName) {
|
179
|
+
if (!moduleName) {
|
180
|
+
return {
|
181
|
+
loaded: Object.keys(this.modules),
|
182
|
+
loading: [...this.process],
|
183
|
+
animations: Object.keys(animationModules),
|
184
|
+
utilities: Object.keys(utilityModules),
|
185
|
+
autoInit: Object.keys(autoInitModules)
|
186
|
+
};
|
209
187
|
}
|
188
|
+
return {
|
189
|
+
loaded: !!this.modules[moduleName],
|
190
|
+
loading: this.process.has(moduleName)
|
191
|
+
};
|
210
192
|
}
|
193
|
+
};
|
194
|
+
|
195
|
+
// Process modules from script tags
|
196
|
+
const processScriptModules = () => {
|
197
|
+
console.log(`⚙️ Processing ${scripts.length} script tags`);
|
211
198
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
if (match && allModules[match]) {
|
224
|
-
foundModules.add(match);
|
225
|
-
}
|
226
|
-
}
|
227
|
-
}
|
228
|
-
|
229
|
-
console.log(`🔍 Auto-discovered modules:`, [...foundModules]);
|
230
|
-
for (const moduleName of foundModules) {
|
199
|
+
for (const script of scripts) {
|
200
|
+
console.log(`🏷️ Processing script:`, script.src);
|
201
|
+
|
202
|
+
// Check for auto mode
|
203
|
+
const autoMode = script.getAttribute('data-hs-auto') === 'true';
|
204
|
+
console.log(`🔍 Auto mode: ${autoMode}`);
|
205
|
+
|
206
|
+
// Load modules based on script attributes
|
207
|
+
for (const moduleName of Object.keys(allModules)) {
|
208
|
+
if (script.hasAttribute(moduleName)) {
|
209
|
+
console.log(`✅ Found attribute for: ${moduleName}`);
|
231
210
|
loadHsModule(moduleName);
|
232
211
|
}
|
212
|
+
}
|
213
|
+
|
214
|
+
// Auto-discovery mode
|
215
|
+
if (autoMode) {
|
216
|
+
waitDOMReady().then(() => {
|
217
|
+
console.log(`🔍 Starting auto-discovery...`);
|
218
|
+
const foundModules = new Set();
|
219
|
+
const allElements = document.querySelectorAll('*');
|
220
|
+
|
221
|
+
for (const element of allElements) {
|
222
|
+
for (const attrName of element.getAttributeNames()) {
|
223
|
+
// Look for data-hs-* attributes
|
224
|
+
const match = attrName.match(/^(data-hs-(?:anim|util)-[^-=]+)/)?.[1];
|
225
|
+
if (match && allModules[match]) {
|
226
|
+
foundModules.add(match);
|
227
|
+
}
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
console.log(`🔍 Auto-discovered modules:`, [...foundModules]);
|
232
|
+
for (const moduleName of foundModules) {
|
233
|
+
loadHsModule(moduleName);
|
234
|
+
}
|
235
|
+
});
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
// Always load auto-init modules
|
240
|
+
console.log(`🔄 Loading auto-init modules:`, Object.keys(autoInitModules));
|
241
|
+
for (const moduleName of Object.keys(autoInitModules)) {
|
242
|
+
loadHsModule(moduleName);
|
243
|
+
}
|
244
|
+
|
245
|
+
// Hide .transition elements if transition module is not loaded
|
246
|
+
const hasTransition = scripts.some(script => script.hasAttribute('data-hs-anim-transition'));
|
247
|
+
if (!hasTransition) {
|
248
|
+
const transitionElements = document.querySelectorAll('.transition');
|
249
|
+
transitionElements.forEach(element => {
|
250
|
+
element.style.display = 'none';
|
233
251
|
});
|
234
252
|
}
|
235
|
-
}
|
236
|
-
|
237
|
-
// Always load auto-init modules
|
238
|
-
console.log(`🔄 Loading auto-init modules:`, Object.keys(autoInitModules));
|
239
|
-
for (const moduleName of Object.keys(autoInitModules)) {
|
240
|
-
loadHsModule(moduleName);
|
241
|
-
}
|
242
|
-
|
243
|
-
// Hide .transition elements if transition module is not loaded
|
244
|
-
const hasTransition = scripts.some(script => script.hasAttribute('data-hs-anim-transition'));
|
245
|
-
if (!hasTransition) {
|
246
|
-
const transitionElements = document.querySelectorAll('.transition');
|
247
|
-
transitionElements.forEach(element => {
|
248
|
-
element.style.display = 'none';
|
249
|
-
});
|
250
|
-
}
|
251
|
-
};
|
253
|
+
};
|
252
254
|
|
253
|
-
// Handle rich text blocks
|
254
|
-
const richTextBlocks = document.querySelectorAll('.w-richtext');
|
255
|
-
richTextBlocks.forEach(block => {
|
256
|
-
|
257
|
-
|
258
|
-
|
255
|
+
// Handle rich text blocks
|
256
|
+
const richTextBlocks = document.querySelectorAll('.w-richtext');
|
257
|
+
richTextBlocks.forEach(block => {
|
258
|
+
const images = block.querySelectorAll('img');
|
259
|
+
images.forEach(img => {
|
260
|
+
img.loading = 'eager';
|
261
|
+
});
|
259
262
|
});
|
260
|
-
});
|
261
263
|
|
262
|
-
// Main initialization
|
263
|
-
const initializeMain = async () => {
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
};
|
264
|
+
// Main initialization
|
265
|
+
const initializeMain = async () => {
|
266
|
+
console.log(`🚀 Starting main initialization...`);
|
267
|
+
|
268
|
+
// Process script modules
|
269
|
+
processScriptModules();
|
270
|
+
|
271
|
+
// Wait for Webflow
|
272
|
+
console.log(`⏳ Waiting for Webflow...`);
|
273
|
+
await waitWebflowReady();
|
274
|
+
console.log(`✅ Webflow ready`);
|
275
|
+
|
276
|
+
// Mark as loaded
|
277
|
+
window[API_NAME].loaded = true;
|
278
|
+
console.log(`🎉 ${API_NAME} fully loaded and ready!`);
|
279
|
+
};
|
280
|
+
|
281
|
+
// Process any early requests
|
282
|
+
console.log(`📝 Processing ${existingRequests.length} early requests`);
|
283
|
+
window[API_NAME].push(...existingRequests);
|
278
284
|
|
279
|
-
//
|
280
|
-
|
281
|
-
|
285
|
+
// Start initialization
|
286
|
+
initializeMain().catch(error => {
|
287
|
+
console.error(`❌ Failed to initialize ${API_NAME}:`, error);
|
288
|
+
});
|
289
|
+
};
|
282
290
|
|
283
|
-
//
|
284
|
-
|
285
|
-
console.error(`❌ Failed to initialize ${API_NAME}:`, error);
|
286
|
-
});
|
291
|
+
// Run initialization
|
292
|
+
initializeHsMain();
|