summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/helpers/startup_css_helper.js
blob: 8e25e1421c02f51945e5b00d82577dabaf992575 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
const CSS_LOADED_EVENT = 'CSSLoaded';
const STARTUP_LINK_LOADED_EVENT = 'CSSStartupLinkLoaded';

const getAllStartupLinks = (() => {
  let links = null;
  return () => {
    if (!links) {
      links = Array.from(document.querySelectorAll('link[data-startupcss]'));
    }
    return links;
  };
})();
const isStartupLinkLoaded = ({ dataset }) => dataset.startupcss === 'loaded';
const allLinksLoaded = () => getAllStartupLinks().every(isStartupLinkLoaded);

const handleStartupEvents = () => {
  if (allLinksLoaded()) {
    document.dispatchEvent(new CustomEvent(CSS_LOADED_EVENT));
    document.removeEventListener(STARTUP_LINK_LOADED_EVENT, handleStartupEvents);
  }
};

/* Wait for.... The methods can be used:
  - with a callback (preferred),
    waitFor(action)

  - with then (discouraged),
    await waitFor().then(action);

  - with await,
    await waitFor;
    action();
-*/
export const waitForCSSLoaded = (action = () => {}) => {
  if (!gon.features.startupCss || allLinksLoaded()) {
    return new Promise(resolve => {
      action();
      resolve();
    });
  }

  return new Promise(resolve => {
    document.addEventListener(CSS_LOADED_EVENT, resolve, { once: true });
    document.addEventListener(STARTUP_LINK_LOADED_EVENT, handleStartupEvents);
  }).then(action);
};