PageSourceSearch

https://www.albankaldawli.org/ext/scripts/delayed.js

js albankaldawli.org collected 2026-09-24 09:45:48 UTC 7,091 bytes, 237 lines download raw bytes

1// add delayed functionality here
2import { getMetadata, sampleRUM, loadCSS } from "./aem.js";
3import { getLanguage, isHomePage, loadAdobeAnalytics } from './utils-core.js';
4import {
5  a, span, i,
6  section,
7} from './dom-helpers.js';
8import { loadConsentManager, hasTargetingConsent } from './consent.js';
9
10
11/**
12 * Swoosh on page
13 */
14
15// Adobe Target
16window.targetGlobalSettings = {
17  bodyHidingEnabled: false,
18};
19
20function pageSwoosh() {
21  const pSwoosh = getMetadata('page-swoosh');
22  if (!pSwoosh || pSwoosh.length < 1) return;
23  if (pSwoosh !== 'page-swoosh-no') {
24    document.body.classList.add(pSwoosh);
25  } else {
26    document.body.classList.remove(pSwoosh);
27  }
28}
29
30// refactor tweetable links function
31/**
32 * Opens a popup for the Twitter links autoblock.
33 */
34function openPopUp(popUrl) {
35  const popupParams = `height=450, width=550, top=${(window.innerHeight / 2 - 275)}`
36   + `, left=${(window.innerWidth / 2 - 225)}`
37   + ', toolbar=0, location=0, menubar=0, directories=0, scrollbars=0';
38  window.open(popUrl, 'fbShareWindow', popupParams);
39}
40
41/**
42 * Finds and decorates anchor elements with Twitter hrefs
43 */
44function buildTwitterLinks() {
45  const main = document.querySelector('main');
46  if (!main) return;
47
48  // get all paragraph elements
49  const paras = main.querySelectorAll('p');
50  const url = window.location.href;
51  const encodedUrl = encodeURIComponent(url);
52
53  [...paras].forEach((paragraph) => {
54    const tweetables = paragraph.innerHTML.match(/&lt;tweetable[^>]*&gt;([\s\S]*?)&lt;\/tweetable&gt;/g);
55    if (tweetables) {
56      tweetables.forEach((tweetableTag) => {
57        const matchedContent = tweetableTag.match(
58          /&lt;tweetable(?:[^>]*data-channel=['"]([^'"]*)['"])?(?:[^>]*data-hashtag=['"]([^'"]*)['"])?[^>]*&gt;([\s\S]*?)&lt;\/tweetable&gt;/,
59        );
60        const channel = matchedContent[1] || '';
61        const hashtag = matchedContent[2] || '';
62        const tweetContent = matchedContent[3];
63
64        let modalURL = `https://twitter.com/intent/tweet?text=${encodeURIComponent(tweetContent)}`
65          + `&original_referrer=${encodedUrl}&source=tweetbutton`;
66        if (channel) modalURL += `&via=${encodeURIComponent(channel.charAt(0) === '@' ? channel.substring(1) : channel)}`;
67        if (hashtag) modalURL += `&hashtags=${encodeURIComponent(hashtag)}`;
68
69        const tweetableEl = span(
70          { class: 'tweetable' },
71          a({ href: modalURL, target: '_blank', tabindex: 0 }, tweetContent, i({ class: 'lp lp-twit' })),
72        );
73        paragraph.innerHTML = paragraph.innerHTML.replace(tweetableTag, tweetableEl.outerHTML);
74      });
75    }
76    [...paragraph.querySelectorAll('.tweetable > a')].forEach((twitterAnchor) => {
77      twitterAnchor.addEventListener('click', (event) => {
78        event.preventDefault();
79        const apiURL = twitterAnchor.href;
80        openPopUp(apiURL);
81      });
82    });
83  });
84}
85
86async function removeTitleAttrFromButtons() {
87  const buttons = document.querySelectorAll('.button-container .button');
88  buttons.forEach((button) => {
89    if (button.hasAttribute('title')) {
90      button.removeAttribute('title');
91    }
92    const dataTitle = button.getAttribute('data-title');
93    if (dataTitle) {
94      button.setAttribute('title', dataTitle);
95      button.removeAttribute('data-title');
96    }
97  });
98}
99
100function loadFlourishScript() {
101  return new Promise((resolve, reject) => {
102    // If it's already defined, resolve immediately
103    if (window.Flourish) {
104      resolve();
105      return;
106    }
107
108    // Set configuration to prevent auto-loading if you want full manual control
109    window.Flourish = { disable_autoload: true };
110
111    const script = document.createElement('script');
112    script.src = 'https://public.flourish.studio/resources/embed.js';
113    script.async = true;
114
115    script.onload = () => resolve();
116    script.onerror = (err) => reject(err);
117
118    document.head.appendChild(script);
119  });
120}
121
122async function handleFlourishEmbedScripts() {
123  const embeds = document.querySelectorAll('.flourish-embed:not(:has(iframe))');
124  
125  if (!embeds.length) return;
126
127  // Ensure the Flourish library is loaded
128  if (!window.Flourish) {
129    await loadFlourishScript();
130  }
131
132  // Re-initialize logic
133  if (window.Flourish && typeof window.Flourish.loadEmbed === 'function') {
134    embeds.forEach(embed => {
135      window.Flourish.loadEmbed(embed);
136    });
137  } 
138  
139  // Fallback to init() if loadEmbed isn't supported for some reason
140  else if (window.Flourish && typeof window.Flourish.init === 'function') {
141    window.Flourish.init();
142  }
143}
144
145function getClosestShowNotes(iframe) {
146  let ancestor = iframe.parentElement;
147  while (ancestor) {
148    const notesEl = ancestor.querySelector('.cp-show-notes');
149    if (notesEl) return notesEl;
150    ancestor = ancestor.parentElement;
151  }
152  return null;
153}
154
155async function handleCaptivateEmbedScripts() {
156  const iframe = document.querySelector('iframe[src*="player.captivate.fm"]');
157  if (!iframe) return;
158
159  const allow = iframe.getAttribute('allow') || '';
160  if (!allow.includes('autoplay')) {
161    iframe.setAttribute('allow', allow ? `${allow};
161 autoplay` : 'autoplay');
162  }
163
164  let didSetup = false;
165  const setup = () => {
166    if (didSetup) return;
167    didSetup = true;
168
169    // eslint-disable-next-line no-undef
170    const player = new CP(iframe);
171
172    const notesEl = getClosestShowNotes(iframe);
173    if (!notesEl) return;
174
175    const TIMESTAMP_REGEX = /(?:[0-5]\d|2[0-3]):(?:[0-5]\d):?(?:[0-5]\d)?/g;
176
177    notesEl.innerHTML = notesEl.innerHTML.replace(TIMESTAMP_REGEX, (match) => (
178      `<a href="javascript: void(0);" data-ts="${match}" class="cp-timestamp">${match}</a>`
179    ));
180
181    notesEl.addEventListener('click', (evt) => {
182      const target = evt.target.closest('.cp-timestamp');
183      if (!target) return;
184
185      const parts = target.dataset.ts.split(':');
186      let seconds = 0;
187      let multiplier = 1;
188      while (parts.length > 0) {
189        seconds += multiplier * parseInt(parts.pop(), 10);
190        multiplier *= 60;
191      }
192
193      player.seekTo(seconds);
194    });
195  };
196
197  iframe.addEventListener('load', setup);
198  setup();
199}
200
201async function loadDelayed() {
202  pageSwoosh();
203  sampleRUM('cwv');
204  await removeTitleAttrFromButtons();
205  // Defer the OneTrust CMP to an idle gap so its ~1s of main-thread work runs
206  // after the page has settled, instead of competing with other delayed scripts.
207  if ('requestIdleCallback' in window) {
208    requestIdleCallback(() => loadConsentManager(), { timeout: 5000 });
209  } else {
210    setTimeout(() => loadConsentManager(), 3000);
211  }
212  if (hasTargetingConsent()) {
213    //todo: add any scripts that require targeting consent here
214  }
215
216  if (!isHomePage()) {
217    await loadAdobeAnalytics();
218  }
219  await handleFlourishEmbedScripts();
220  await handleCaptivateEmbedScripts();
221  // insertSchemaScript();
222}
223loadDelayed();
224
225
226function isInUniversalEditor() {
227  return window.self !== window.top;
228}
229
230async function loadDelayedScripts() {
231  if (isInUniversalEditor()) {
232    const { default: registerUEExtensions } = await import('./ue-extensions.js');
233    registerUEExtensions();
234  }
235}
236
237loadDelayedScripts();

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.