PageSourceSearch

https://www.westpac.com.au/scripts/utility/site-alert-loader.js

js westpac.com.au collected 2026-09-24 08:27:22 UTC 3,123 bytes, 96 lines download raw bytes

1const SITE_ALERT_FRAGMENT_PATH = '/site-configuration/site-alert';
2
3/**
4 * Creates an isolated site-alert loader.
5 * @param {Object} dependencies Loader dependencies
6 * @returns {Object} Site-alert loading and reveal operations
7 */
8export function createSiteAlertLoader({
9  loadFragment: configuredLoadFragment,
10  createResizeObserver = (callback) => new ResizeObserver(callback),
11  logger = console,
12} = {}) {
13  let readinessPromise;
14  let resizeObserver;
15
16  function synchronizeHeight(doc) {
17    const alert = doc.querySelector('header > .site-alert');
18    const alertHeight = alert?.offsetHeight || 0;
19    doc.body.style.setProperty('--site-alert-height', `${alertHeight}px`);
20
21    if (!alert && resizeObserver) {
22      resizeObserver.disconnect();
23      resizeObserver = undefined;
24    }
25
26    if (alert && !resizeObserver) {
27      resizeObserver = createResizeObserver(() => synchronizeHeight(doc));
28      resizeObserver.observe(alert);
29      alert.addEventListener('click', (event) => {
30        if (event.target.closest('.site-alert__dismiss')) {
31          synchronizeHeight(doc);
32        }
33      });
34    }
35
36    return alertHeight;
37  }
38
39  function load(header, fragmentLoader = configuredLoadFragment) {
40    if (!readinessPromise) {
41      const mountedAlert = header?.querySelector(':scope > .site-alert');
42      readinessPromise = mountedAlert
43        ? Promise.resolve(mountedAlert)
44        : fragmentLoader(SITE_ALERT_FRAGMENT_PATH)
45          .then((fragment) => {
46            const alert = fragment?.querySelector('.site-alert') || null;
47            if (alert && header && !header.querySelector(':scope > .site-alert')) {
48              header.prepend(alert);
49            }
50            return header?.querySelector(':scope > .site-alert') || alert;
51          })
52          .catch((error) => {
53            logger.error('loadSiteAlert: failed to load site alert fragment', error);
54            return null;
55          });
56    }
57    return readinessPromise;
58  }
59
60  async function loadPageChrome(header, fragmentLoader, loadHeaderStyles) {
61    const headerStylesReadiness = loadHeaderStyles().catch((error) => {
62      logger.error('loadSiteAlert: failed to load header styles', error);
63    });
64    const [alert] = await Promise.all([
65      load(header, fragmentLoader),
66      headerStylesReadiness,
67    ]);
68    return alert;
69  }
70
71  async function revealBody(siteAlertReadiness, doc) {
72    await siteAlertReadiness;
73    doc.body.classList.add('appear');
74    synchronizeHeight(doc);
75  }
76
77  return {
78    load,
79    loadPageChrome,
80    revealBody,
81    synchronizeHeight,
82  };
83}
84
85const siteAlertLoader = createSiteAlertLoader();
86
87export const loadSiteAlert = (header, fragmentLoader) => (
88  siteAlertLoader.load(header, fragmentLoader)
89);
90export const loadSiteAlertAndHeaderStyles = (header, fragmentLoader, loadHeaderStyles) => (
91  siteAlertLoader.loadPageChrome(header, fragmentLoader, loadHeaderStyles)
92);
93export const revealBodyAfterSiteAlert = (siteAlertReadiness, doc) => (
94  siteAlertLoader.revealBody(siteAlertReadiness, doc)
95);
96export const synchronizeSiteAlertHeight = (doc) => siteAlertLoader.synchronizeHeight(doc);

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.