summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/behaviors/markdown/render_kroki.js
blob: abe71694d735faf9ba6f4da20c3a4811d2f2d341 (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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import Vue from 'vue';
import DiagramPerformanceWarning from '../components/diagram_performance_warning.vue';
import { unrestrictedPages } from './constants';

/**
 * Create alert element.
 *
 * @param {Element} krokiImage Kroki `img` element
 * @return {Element} Alert element
 */
function createAlert(krokiImage) {
  const app = new Vue({
    el: document.createElement('div'),
    name: 'DiagramPerformanceWarningRoot',
    render(createElement) {
      return createElement(DiagramPerformanceWarning, {
        on: {
          closeAlert() {
            app.$destroy();
            app.$el.remove();
          },
          showImage() {
            krokiImage.removeAttribute('hidden');
            app.$destroy();
            app.$el.remove();
          },
        },
      });
    },
  });

  return app.$el;
}

/**
 * Add warning alert to hidden Kroki images,
 * or show Kroki image if on an unrestricted page.
 *
 * Kroki images are given a hidden attribute by the
 * backend when the original markdown source is large.
 *
 * @param {Array<Element>} krokiImages Array of hidden Kroki `img` elements
 */
export function renderKroki(krokiImages) {
  const pageName = document.querySelector('body').dataset.page;
  const isUnrestrictedPage = unrestrictedPages.includes(pageName);

  krokiImages.forEach((krokiImage) => {
    if (isUnrestrictedPage) {
      krokiImage.removeAttribute('hidden');
      return;
    }

    const parent = krokiImage.parentElement;

    // A single Kroki image is processed multiple times for some reason,
    // so this condition ensures we only create one alert per Kroki image
    if (!parent.hasAttribute('data-kroki-processed')) {
      parent.setAttribute('data-kroki-processed', 'true');
      parent.after(createAlert(krokiImage));
    }
  });
}