PageSourceSearch

https://woodsholefilmfestival.org/wp-content/plugins/Elevent-WordP…/widget-initializer.js?ver=1780400965

js woodsholefilmfestival.org collected 2026-10-02 04:36:48 UTC 12,842 bytes, 448 lines download raw bytes

1/**
2 * Elevent Widget Initializer
3 *
4 * Vanilla JavaScript widget initializer for maximum performance.
5 * Runs immediately without waiting for jQuery or DOM ready.
6 * Also exposes a public API (window.EleventWidgetInitializer) for
7 * re-initialization by the widget observer when DOM content changes.
8 *
9 * This script is enqueued with a dependency on the Elevent widget library,
10 * so window.elevent is guaranteed to be available when this executes.
11 * Retry logic is kept as a safety net for edge cases (e.g., deferred loading).
12 *
13 * @package Elevent
14 */
15
16(function () {
17  "use strict";
18
19  /**
20   * Safe performance timing function
21   * Falls back to Date.now() if Performance API is unavailable
22   * @returns {number} Milliseconds since epoch or load start
23   */
24  function getTimestamp() {
25    if (
26      typeof window.performance === "object" &&
27      typeof window.performance.now === "function"
28    ) {
29      return window.performance.now();
30    }
31    return Date.now();
32  }
33
34  function isDebugEnabled() {
35    return (
36      typeof eleventWidgetConfig !== "undefined" && eleventWidgetConfig.debug
37    );
38  }
39
40  function pushBenchmarkLog(source, stage, data) {
41    if (!isDebugEnabled()) {
42      return;
43    }
44
45    window.EleventBenchmarkLog = window.EleventBenchmarkLog || [];
46    window.EleventBenchmarkLog.push({
47      source: source,
48      stage: stage,
49      at: getTimestamp(),
50      isoTime: new Date().toISOString(),
51      data: data || null,
52    });
53  }
54
55  // Performance tracking
56  var perfData = {
57    scriptStart: getTimestamp(),
58    initStart: null,
59    initEnd: null,
60  };
61
62  /**
63   * Log performance metrics to console
64   * @param {string} message
65   * @param {object} data
66   */
67  function logPerformance(message, data) {
68    if (isDebugEnabled()) {
69      data
70        ? console.log("[Elevent Perf] " + message, data)
71        : console.log("[Elevent Perf] " + message);
72    }
73  }
74
75  /**
76   * Log warning to console (if debug enabled)
77   * @param {string} message
78   * @param {object} data
79   */
80  function warnPerformance(message, data) {
81    if (isDebugEnabled()) {
82      data
83        ? console.warn("[Elevent Perf] " + message, data)
84        : console.warn("[Elevent Perf] " + message);
85    }
86  }
87
88  /**
89   * Log error to console (if debug enabled)
90   * @param {string} message
91   * @param {object} data
92   */
93  function errorPerformance(message, data) {
94    if (isDebugEnabled()) {
95      data
96        ? console.error("[Elevent Perf] " + message, data)
97        : console.error("[Elevent Perf] " + message);
98    }
99  }
100
101  /**
102   * Report performance metrics (can be extended to send to analytics)
103   */
104  function reportMetrics() {
105    var metrics = {
106      scriptToInit: perfData.initStart - perfData.scriptStart,
107      initDuration: perfData.initEnd - perfData.initStart,
108      totalTime: perfData.initEnd - perfData.scriptStart,
109      timestamp: new Date().toISOString(),
110    };
111
112    logPerformance("Widget initialization metrics:", metrics);
113    pushBenchmarkLog("initializer", "metrics", metrics);
114
115    // Store metrics for external access
116    window.EleventPerfMetrics = metrics;
117
118    // Fire custom event for external monitoring
119    if (typeof CustomEvent !== "undefined") {
120      document.dispatchEvent(
121        new CustomEvent("elevent:initialized", { detail: metrics }),
122      );
123    }
124  }
125
126  /**
127   * Initialize Elevent widgets immediately
128   * @param {string} key Widget key
129   * @returns {boolean} Success status
130   */
131  function initializeWidget(key) {
132    perfData.initStart = getTimestamp();
133    pushBenchmarkLog("initializer", "initialize-start", {
134      hasKey: !!key,
135      keyLength: typeof key === "string" ? key.trim().length : 0,
136      eleventAvailable: typeof window.elevent !== "undefined",
137    });
138
139    // Validate key
140    if (!key || typeof key !== "string" || key.trim().length === 0) {
141      pushBenchmarkLog("initializer", "initialize-skipped-invalid-key");
142      warnPerformance("No valid widget key provided");
143      return false;
144    }
145
146    // Check if Elevent library is loaded
147    if (typeof window.elevent === "undefined") {
148      pushBenchmarkLog("initializer", "initialize-deferred-library-missing");
149      logPerformance("Elevent library not yet loaded, deferring...");
150      return false;
151    }
152
153    // Check if Initialize method exists
154    if (typeof window.elevent.Initialize !== "function") {
155      pushBenchmarkLog("initializer", "initialize-error-missing-method");
156      errorPerformance("Elevent.Initialize is not a function");
157      return false;
158    }
159
160    try {
161      var trimmedKey = key.trim();
162      logPerformance("Initializing with key length: " + trimmedKey.length);
163
164      window.elevent.Initialize(trimmedKey);
165
166      perfData.initEnd = getTimestamp();
167      pushBenchmarkLog("initializer", "initialize-success", {
168        duration: perfData.initEnd - perfData.initStart,
169      });
170      logPerformance("Initialization successful");
171      reportMetrics();
172
173      // Mark as initialized for other scripts
174      window.EleventEarlyInitialized = true;
175      window.EleventWidgetKey = trimmedKey;
176
177      return true;
178    } catch (error) {
179      perfData.initEnd = getTimestamp();
180      pushBenchmarkLog("initializer", "initialize-exception", {
181        duration: perfData.initEnd - perfData.initStart,
182        message: error && error.message ? error.message : String(error),
183      });
184      errorPerformance("Initialization error:", error);
185      return false;
186    }
187  }
188
189  /**
190   * Attempt initialization with retry logic
191   *
192   * The Elevent widget library is declared as a script dependency, so
193   * window.elevent should always be available on the first attempt.
194   * The widget key is always inlined in the page config.
195   * Retries are a safety net for edge cases (deferred loading, caching
196   * plugins reordering scripts, etc.) and use exponential backoff.
197   */
198  function attemptInitialization() {
199    var config =
200      typeof eleventWidgetConfig !== "undefined" ? eleventWidgetConfig : null;
201    var inlineKey = config && config.widgetKey ? config.widgetKey : null;
202
203    if (!inlineKey) {
204      pushBenchmarkLog("initializer", "attempt-missing-inline-key");
205      errorPerformance("Widget key not localized in page config");
206      return;
207    }
208
209    // Cache the trimmed key for use by public API and retries
210    var trimmedKey = inlineKey.trim();
211    if (trimmedKey.length === 0) {
212      pushBenchmarkLog("initializer", "attempt-empty-inline-key");
213      errorPerformance("Widget key not localized in page config");
214      return;
215    }
216
217    pushBenchmarkLog("initializer", "attempt-start", {
218      keyLength: trimmedKey.length,
219    });
220
221    window.EleventWidgetKey = trimmedKey;
222
223    // Attempt immediate initialization
224    if (initializeWidget(trimmedKey)) {
225      return; // Success — initialized immediately
226    }
227
228    // Library not yet loaded — retry with the cached key
229    retryWithKey(trimmedKey);
230  }
231
232  /**
233   * Retry initialization with exponential backoff
234   * Reuses a known key — no additional network requests.
235   *
236   * @param {string} key Widget key to retry with
237   */
238  function retryWithKey(key) {
239    var retryCount = 0;
240    var maxRetries = 10;
241    var baseInterval = 50; // ms
242
243    var retryInit = function () {
244      retryCount++;
245      pushBenchmarkLog("initializer", "retry-attempt", {
246        retryCount: retryCount,
247        eleventAvailable: typeof window.elevent !== "undefined",
248      });
249
250      if (typeof window.elevent !== "undefined") {
251        if (initializeWidget(key)) {
252          warnPerformance(
253            "Initialized after " +
254              retryCount +
255              " retries — check script load order",
256          );
257          return;
258        }
259      }
260
261      if (retryCount < maxRetries) {
262        // Exponential backoff: 50, 100, 200, 400, 800, 1600, 3200, 6400, 12800ms
263        var delay = baseInterval * Math.pow(2, retryCount - 1);
264        pushBenchmarkLog("initializer", "retry-scheduled", {
265          retryCount: retryCount,
266          delay: delay,
267        });
268        setTimeout(retryInit, delay);
269      } else {
270        pushBenchmarkLog("initializer", "retry-exhausted", {
271          maxRetries: maxRetries,
272        });
273        errorPerformance(
274          "Max retries reached, widget initialization failed — Elevent widget script may not have loaded",
275        );
276      }
277    };
278
279    setTimeout(retryInit, baseInterval);
280  }
281
282  /**
283   * Public API for widget initialization
284   *
285   * Exposes methods for re-initialization (used by widget-observer.js
286   * when DOM content changes via FacetWP, AJAX, etc.)
287   */
288  var WidgetInitializer = {
289    /**
290     * Debounce timeout for initialization calls
291     * @type {number|null}
292     */
293    _initTimeout: null,
294
295    /**
296     * Initialize or re-initialize widgets
297     *
298     * @param {boolean} forceReinit Force re-initialization even if already initialized
299     */
300    initialize: function (forceReinit) {
301      pushBenchmarkLog("initializer", "public-initialize", {
302        forceReinit: !!forceReinit,
303        alreadyInitialized: !!window.EleventEarlyInitialized,
304      });
305
306      if (
307        window.EleventEarlyInitialized &&
308        window.EleventWidgetKey &&
309        !forceReinit
310      ) {
311        logPerformance("Widgets already initialized, skipping redundant call");
312        return;
313      }
314
315      // Clear any pending initialization
316      if (this._initTimeout) {
317        clearTimeout(this._initTimeout);
318      }
319
320      // Debounce initialization
321      var self = this;
322      this._initTimeout = setTimeout(function () {
323        self._doInitialize(forceReinit);
324      }, 50);
325    },
326
327    /**
328     * Perform the actual initialization
329     *
330     * @param {boolean} forceReinit Force re-initialization
331     * @private
332     */
333    _doInitialize: function (forceReinit) {
334      pushBenchmarkLog("initializer", "do-initialize", {
335        forceReinit: !!forceReinit,
336        eleventAvailable: typeof window.elevent !== "undefined",
337      });
338
339      if (typeof window.elevent === "undefined") {
340        warnPerformance("Elevent widget script not loaded");
341        return;
342      }
343
344      var key = window.EleventWidgetKey;
345
346      // Fallback to eleventWidgetConfig if key not yet cached
347      // (can happen during retry window before initializeWidget succeeds)
348      if (!key) {
349        var config =
350          typeof eleventWidgetConfig !== "undefined"
351            ? eleventWidgetConfig
352            : null;
353        key = config && config.widgetKey ? config.widgetKey : null;
354      }
355
356      if (key) {
357        this._initializeWithKey(key, forceReinit);
358        return;
359      }
360
361      // No key available
362      warnPerformance("No widget key available for initialization");
363    },
364
365    /**
366     * Initialize with a specific key
367     *
368     * @param {string} key Widget key
369     * @param {boolean} forceReinit Force re-initialization
370     * @private
371     */
372    _initializeWithKey: function (key, forceReinit) {
373      if (!key) {
374        warnPerformance("No widget key provided");
375        return;
376      }
377
378      if (typeof key !== "string" || key.trim().length === 0) {
379        errorPerformance("Invalid widget key format:", typeof key);
380        return;
381      }
382
383      if (typeof window.elevent === "undefined") {
384        warnPerformance("Elevent library not available for initialization");
385        return;
386      }
387
388      if (typeof window.elevent.Initialize !== "function") {
389        errorPerformance("Elevent.Initialize is not a function");
390        return;
391      }
392
393      if (
394        window.EleventEarlyInitialized &&
395        window.EleventWidgetKey === key &&
396        !forceReinit
397      ) {
398        logPerformance("Elevent widgets already initialized with this key");
399        return;
400      }
401
402      try {
403        var trimmedKey = key.trim();
404
405        logPerformance(
406          forceReinit
407            ? "Re-initializing Elevent widgets (DOM updated)"
408            : "Initializing Elevent widgets",
409        );
410
411        window.elevent.Initialize(trimmedKey);
412        window.EleventEarlyInitialized = true;
413        window.EleventWidgetKey = trimmedKey;
414
415        logPerformance("Initialization complete", {
416          reinit: !!forceReinit,
417        });
418      } catch (error) {
419        window.EleventEarlyInitialized = false;
420        errorPerformance("Error initializing Elevent widgets:", error);
421      }
422    },
423
424    /**
425     * Get the current widget key
426     *
427     * @return {string|null} Widget key or null
428     */
429    getWidgetKey: function () {
430      return window.EleventWidgetKey || null;
431    },
432
433    /**
434     * Check if widgets have been initialized
435     *
436     * @return {boolean} True if initialized
437     */
438    isInitialized: function () {
439      return !!window.EleventEarlyInitialized;
440    },
441  };
442
443  // Export public API
444  window.EleventWidgetInitializer = WidgetInitializer;
445
446  // Execute immediately
447  attemptInitialization();
448})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.