1const behaviorNames = []; 2let listenersBound = false; 3let resizeTimer = null; 4 5export function attachBehaviorWhenReady(Drupal, names) { 6 toArray(names).forEach((name) => { 7 if (behaviorNames.indexOf(name) === -1) { 8 behaviorNames.push(name); 9 } 10 }); 11 12 if (!listenersBound) { 13 bindAttachListeners(Drupal); 14 } 15 16 queueAttach(Drupal); 17} 18 19function bindAttachListeners(Drupal) { 20 listenersBound = true; 21 22 if (document.readyState === 'loading') { 23 document.addEventListener('DOMContentLoaded', () => queueAttach(Drupal)); 24 } else { 25 queueAttach(Drupal); 26 } 27 28 window.addEventListener('load', () => queueAttach(Drupal)); 29 window.addEventListener('pageshow', () => queueAttach(Drupal)); 30 window.addEventListener('orientationchange', () => queueDelayedAttach(Drupal)); 31 window.addEventListener('resize', () => queueDelayedAttach(Drupal)); 32 33 if (window.visualViewport && window.visualViewport.addEventListener) { 34 window.visualViewport.addEventListener('resize', () => queueDelayedAttach(Drupal)); 35 } 36 37 document.addEventListener('visibilitychange', () => { 38 if (!document.hidden) { 39 queueDelayedAttach(Drupal); 40 } 41 }); 42} 43 44function queueAttach(Drupal) { 45 window.setTimeout(() => runAttach(Drupal), 0); 46 47 if (window.requestAnimationFrame) { 48 window.requestAnimationFrame(() => runAttach(Drupal)); 49 } 50 51 window.setTimeout(() => runAttach(Drupal), 250); 52 window.setTimeout(() => runAttach(Drupal), 1000); 53} 54 55function queueDelayedAttach(Drupal) { 56 window.clearTimeout(resizeTimer); 57 resizeTimer = window.setTimeout(() => queueAttach(Drupal), 120); 58} 59 60function runAttach(Drupal) { 61 if (!Drupal || !Drupal.behaviors || !document.body) { 62 return; 63 } 64 65 behaviorNames.forEach((name) => { 66 const behavior = Drupal.behaviors[name]; 67 68 if (!behavior || typeof behavior.attach !== 'function') { 69 return; 70 } 71 72 try { 73 behavior.attach(document); 74 } catch (error) { 75 debugError(`behavior attach failed: ${name}`, error); 76 } 77 }); 78} 79 80function toArray(items) { 81 if (!items) { 82 return []; 83 } 84 85 return Array.isArray(items) ? items : [items]; 86} 87 88function debugError(message, error) { 89 if (isDebugEnabled() && window.console && window.console.error) { 90 window.console.error(`[loyalty] ${message}`, error); 91 } 92} 93 94function isDebugEnabled() { 95 try { 96 return window.loyaltyDebug === true || window.localStorage.getItem('loyaltyDebug') === 'true'; 97 } catch (error) { 98 return window.loyaltyDebug === true; 99 } 100}
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.