@hortonstudio/main 1.2.1 → 1.2.3

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.
Files changed (2) hide show
  1. package/index.js +168 -23
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,13 +1,19 @@
1
- // ver 1.2.1
1
+ // ver 1.2.3
2
2
 
3
3
  const API_NAME = 'hsmain';
4
4
 
5
+ console.log(`🟢 ${API_NAME} v1.2.3 initializing...`);
6
+ console.log('🔍 DOM state:', document.readyState);
7
+ console.log('🔍 Script URL:', import.meta.url);
8
+
5
9
  window[API_NAME] = window[API_NAME] || {};
6
10
  window[API_NAME].loaded = false
7
11
 
8
12
  // Dynamic module loader function (like Finsweet's approach)
9
13
  const loadModule = async (moduleName) => {
14
+ console.log(`📦 Loading module: ${moduleName}`);
10
15
  const baseURL = new URL('./', import.meta.url).href;
16
+ console.log(`📂 Base URL: ${baseURL}`);
11
17
 
12
18
  switch (moduleName) {
13
19
  case "data-hs-anim-text":
@@ -25,8 +31,28 @@ const loadModule = async (moduleName) => {
25
31
  case "smooth-scroll":
26
32
  return import(new URL('./autoInit/smooth-scroll.js', import.meta.url).href);
27
33
  default:
34
+ console.error(`❌ Unsupported module: ${moduleName}`);
28
35
  throw new Error(`HortonStudio module "${moduleName}" is not supported.`);
29
36
  }
37
+
38
+ // Refresh Webflow after processing
39
+ setTimeout(() => {
40
+ if (window.Webflow && window.Webflow.ready) {
41
+ window.Webflow.ready();
42
+ }
43
+
44
+ // Run all registered post-Webflow callbacks (even without Webflow)
45
+ setTimeout(() => {
46
+ postWebflowCallbacks.forEach(callback => {
47
+ try {
48
+ callback();
49
+ } catch (error) {
50
+ console.error('Callback error:', error);
51
+ }
52
+ });
53
+ window[API_NAME].loaded = true;
54
+ }, 100);
55
+ }, 100);
30
56
  };
31
57
 
32
58
  const animationModules = {
@@ -52,21 +78,32 @@ const postWebflowCallbacks = [];
52
78
  const findCurrentScriptTag = () => {
53
79
  // Use import.meta.url like Finsweet does
54
80
  const scripts = [...document.querySelectorAll(`script[data-hs-main][src="${import.meta.url}"]`)];
55
- return scripts[0] || document.querySelector('script[data-hs-main]');
81
+ const fallbackScript = document.querySelector('script[data-hs-main]');
82
+ const found = scripts[0] || fallbackScript;
83
+ console.log(`🏷️ Script tag found:`, found);
84
+ console.log(`🏷️ Script attributes:`, found ? [...found.attributes].map(a => `${a.name}="${a.value}"`).join(' ') : 'none');
85
+ return found;
56
86
  };
57
87
 
58
88
  const processModules = async (scriptTag) => {
89
+ console.log(`⚙️ Processing modules with script tag:`, scriptTag);
59
90
  const modulePromises = [];
60
91
 
61
92
  // Load manual modules based on attributes
62
- for (const moduleName of Object.keys({ ...animationModules, ...utilityModules })) {
93
+ const manualModules = Object.keys({ ...animationModules, ...utilityModules });
94
+ console.log(`🔍 Checking for manual modules:`, manualModules);
95
+
96
+ for (const moduleName of manualModules) {
63
97
  if (scriptTag && scriptTag.hasAttribute(moduleName)) {
98
+ console.log(`✅ Found attribute for: ${moduleName}`);
64
99
  modulePromises.push(loadHsModule(moduleName));
65
100
  }
66
101
  }
67
102
 
68
103
  // Load auto-init modules
69
- for (const moduleName of Object.keys(autoInitModules)) {
104
+ const autoModules = Object.keys(autoInitModules);
105
+ console.log(`🔄 Auto-loading modules:`, autoModules);
106
+ for (const moduleName of autoModules) {
70
107
  modulePromises.push(loadHsModule(moduleName));
71
108
  }
72
109
 
@@ -79,38 +116,51 @@ const processModules = async (scriptTag) => {
79
116
  }
80
117
 
81
118
  // Wait for ALL modules to finish loading
119
+ console.log(`⏳ Waiting for ${modulePromises.length} modules to load...`);
82
120
  await Promise.all(modulePromises);
121
+ console.log(`✅ All modules loaded successfully`);
83
122
 
84
123
  // Always refresh Webflow after all modules are loaded
85
124
  refreshWebflow();
86
125
  };
87
126
 
88
127
  const refreshWebflow = () => {
128
+ console.log(`🔄 Refreshing Webflow...`);
89
129
  setTimeout(() => {
90
130
  if (window.Webflow && window.Webflow.ready) {
131
+ console.log(`🌐 Calling Webflow.ready()`);
91
132
  window.Webflow.ready();
133
+ } else {
134
+ console.log(`⚠️ Webflow not detected`);
92
135
  }
93
136
 
94
137
  // Run all registered post-Webflow callbacks (even without Webflow)
95
138
  setTimeout(() => {
96
- postWebflowCallbacks.forEach(callback => {
139
+ console.log(`🔄 Running ${postWebflowCallbacks.length} post-Webflow callbacks`);
140
+ postWebflowCallbacks.forEach((callback, index) => {
97
141
  try {
142
+ console.log(`📞 Executing callback ${index + 1}/${postWebflowCallbacks.length}`);
98
143
  callback();
99
144
  } catch (error) {
145
+ console.error(`❌ Callback ${index + 1} failed:`, error);
100
146
  }
101
147
  });
102
148
  window[API_NAME].loaded = true;
103
- },);
104
- },);
149
+ console.log(`🎉 ${API_NAME} fully loaded and ready!`);
150
+ }, 100);
151
+ }, 100);
105
152
  };
106
153
 
107
154
  const loadHsModule = async (moduleName) => {
155
+ console.log(`🔄 loadHsModule called for: ${moduleName}`);
108
156
  const apiInstance = window[API_NAME];
109
157
 
110
158
  if (apiInstance.process.has(moduleName)) {
159
+ console.log(`⚠️ Module ${moduleName} already processing, returning existing promise`);
111
160
  return apiInstance.modules[moduleName]?.loading;
112
161
  }
113
162
 
163
+ console.log(`➕ Adding ${moduleName} to process set`);
114
164
  apiInstance.process.add(moduleName);
115
165
 
116
166
  const moduleObj = apiInstance.modules[moduleName] || {};
@@ -122,14 +172,26 @@ const loadHsModule = async (moduleName) => {
122
172
  });
123
173
 
124
174
  try {
175
+ console.log(`📦 Importing ${moduleName}...`);
125
176
  const { init, version } = await loadModule(moduleName);
177
+ console.log(`✅ ${moduleName} imported, version: ${version}`);
178
+
179
+ console.log(`🔧 Initializing ${moduleName}...`);
126
180
  const initResult = await init();
127
- const { result } = initResult || {};
181
+ const { result, destroy } = initResult || {};
182
+ console.log(`✅ ${moduleName} initialized:`, result);
128
183
 
129
184
  moduleObj.version = version;
130
- moduleObj.restart = () => {
185
+
186
+ // Finsweet-style destroy and restart methods
187
+ moduleObj.destroy = () => {
188
+ destroy?.();
131
189
  apiInstance.process.delete(moduleName);
132
- return loadHsModule(moduleName);
190
+ };
191
+
192
+ moduleObj.restart = () => {
193
+ moduleObj.destroy?.();
194
+ return apiInstance.load(moduleName);
133
195
  };
134
196
 
135
197
  moduleObj.resolve?.(result);
@@ -139,6 +201,7 @@ const loadHsModule = async (moduleName) => {
139
201
  return result;
140
202
 
141
203
  } catch (error) {
204
+ console.error(`❌ Failed to load ${moduleName}:`, error);
142
205
  moduleObj.reject?.(error);
143
206
  apiInstance.process.delete(moduleName);
144
207
  throw error;
@@ -146,10 +209,27 @@ const loadHsModule = async (moduleName) => {
146
209
  };
147
210
 
148
211
  const initializeAPI = () => {
149
- const apiInstance = window[API_NAME];
150
-
151
- const existingRequests = Array.isArray(apiInstance) ? apiInstance : [];
152
- const scriptTag = findCurrentScriptTag();
212
+ console.log(`🚀 Initializing ${API_NAME} API...`);
213
+
214
+ // Handle early API calls (like Finsweet)
215
+ const existingAPI = window[API_NAME];
216
+ console.log(`🔍 Existing API:`, existingAPI);
217
+
218
+ if (existingAPI && !Array.isArray(existingAPI)) {
219
+ console.log(`⚡ API already initialized, processing...`);
220
+ processAPI();
221
+ return;
222
+ }
223
+
224
+ const existingRequests = Array.isArray(existingAPI) ? existingAPI : [];
225
+ console.log(`📝 Existing queued requests:`, existingRequests);
226
+
227
+ const scripts = [...document.querySelectorAll(`script[data-hs-main][src="${import.meta.url}"]`)];
228
+ const scriptTag = scripts[0] || document.querySelector('script[data-hs-main]');
229
+ console.log(`📄 Found ${scripts.length} script tags with exact src match`);
230
+ console.log(`🏷️ Using script tag:`, scriptTag);
231
+
232
+ // Handle rich text blocks
153
233
  const richTextBlocks = document.querySelectorAll('.w-richtext');
154
234
  richTextBlocks.forEach(block => {
155
235
  const images = block.querySelectorAll('img');
@@ -159,17 +239,33 @@ const initializeAPI = () => {
159
239
  });
160
240
 
161
241
  window[API_NAME] = {
162
- scriptTag,
242
+ scripts,
163
243
  modules: {},
164
244
  process: new Set(),
165
-
166
245
  load: loadHsModule,
246
+
247
+ // Push method for queuing (like Finsweet)
248
+ push(...requests) {
249
+ for (let [moduleName, callback] of requests) {
250
+ if (typeof callback === 'function') {
251
+ this.modules[moduleName]?.loading?.then(callback);
252
+ } else {
253
+ this.load(moduleName);
254
+ }
255
+ }
256
+ },
257
+
258
+ // Destroy all modules
259
+ destroy() {
260
+ for (let moduleName in this.modules) {
261
+ this.modules[moduleName]?.destroy?.();
262
+ }
263
+ },
167
264
 
168
265
  // API function for scripts to register post-initialization callbacks
169
266
  afterReady: (callback) => {
170
267
  if (typeof callback === 'function') {
171
268
  postWebflowCallbacks.push(callback);
172
- } else {
173
269
  }
174
270
  },
175
271
 
@@ -177,7 +273,6 @@ const initializeAPI = () => {
177
273
  afterWebflowReady: (callback) => {
178
274
  if (typeof callback === 'function') {
179
275
  postWebflowCallbacks.push(callback);
180
- } else {
181
276
  }
182
277
  },
183
278
 
@@ -198,19 +293,69 @@ const initializeAPI = () => {
198
293
  }
199
294
  };
200
295
 
201
- processModules(scriptTag);
296
+ processAPI();
297
+
298
+ // Process any queued requests
299
+ window[API_NAME].push(...existingRequests);
300
+ };
202
301
 
203
- if (existingRequests.length > 0) {
204
- existingRequests.forEach(request => {
205
- if (typeof request === 'string') {
206
- window[API_NAME].load(request);
302
+ const processAPI = () => {
303
+ // Check for auto mode
304
+ let autoMode = false;
305
+ for (let script of window[API_NAME].scripts || []) {
306
+ autoMode ||= script.getAttribute('data-hs-auto') === 'true';
307
+
308
+ // Load modules based on script attributes
309
+ for (const moduleName of Object.keys({ ...animationModules, ...utilityModules })) {
310
+ if (script.hasAttribute(moduleName)) {
311
+ loadHsModule(moduleName);
312
+ }
313
+ }
314
+ }
315
+
316
+ // Auto-discovery mode (scan DOM for attributes)
317
+ if (autoMode) {
318
+ document.fonts.ready.then(() => {
319
+ const foundModules = new Set();
320
+ const allElements = document.querySelectorAll('*');
321
+
322
+ for (let element of allElements) {
323
+ for (let attrName of element.getAttributeNames()) {
324
+ // Look for data-hs-[something] attributes
325
+ const match = attrName.match(/^data-hs-([^-=]+)/)?.[1];
326
+ if (match && attributeToModule[match]) {
327
+ foundModules.add(attributeToModule[match]);
328
+ }
329
+ }
207
330
  }
331
+
332
+ for (let moduleName of foundModules) {
333
+ loadHsModule(moduleName);
334
+ }
335
+ });
336
+ }
337
+
338
+ // Always load auto-init modules
339
+ for (const moduleName of Object.keys(autoInitModules)) {
340
+ loadHsModule(moduleName);
341
+ }
342
+
343
+ // Hide .transition elements if transition module is not loaded
344
+ const hasTransition = window[API_NAME].scripts?.some(script =>
345
+ script.hasAttribute('data-hs-anim-transition')
346
+ );
347
+ if (!hasTransition) {
348
+ const transitionElements = document.querySelectorAll('.transition');
349
+ transitionElements.forEach(element => {
350
+ element.style.display = 'none';
208
351
  });
209
352
  }
210
353
  };
211
354
 
212
355
  if (document.readyState === 'loading') {
356
+ console.log(`⏳ DOM still loading, waiting for DOMContentLoaded...`);
213
357
  document.addEventListener('DOMContentLoaded', initializeAPI);
214
358
  } else {
359
+ console.log(`✅ DOM ready, initializing immediately`);
215
360
  initializeAPI();
216
361
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hortonstudio/main",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "scripts": {