diff options
Diffstat (limited to 'app/assets/javascripts/behaviors/markdown')
4 files changed, 91 insertions, 38 deletions
diff --git a/app/assets/javascripts/behaviors/markdown/init_gfm.js b/app/assets/javascripts/behaviors/markdown/init_gfm.js new file mode 100644 index 00000000000..d9c7cee50da --- /dev/null +++ b/app/assets/javascripts/behaviors/markdown/init_gfm.js @@ -0,0 +1,13 @@ +import $ from 'jquery'; +import { renderGFM } from '~/behaviors/markdown/render_gfm'; + +$.fn.renderGFM = function plugin() { + this.get().forEach(renderGFM); + return this; +}; +requestIdleCallback( + () => { + renderGFM(document.body); + }, + { timeout: 500 }, +); diff --git a/app/assets/javascripts/behaviors/markdown/render_gfm.js b/app/assets/javascripts/behaviors/markdown/render_gfm.js index a08cf48c327..2eab5b84e3e 100644 --- a/app/assets/javascripts/behaviors/markdown/render_gfm.js +++ b/app/assets/javascripts/behaviors/markdown/render_gfm.js @@ -1,45 +1,52 @@ -import $ from 'jquery'; import syntaxHighlight from '~/syntax_highlight'; import highlightCurrentUser from './highlight_current_user'; import { renderKroki } from './render_kroki'; import renderMath from './render_math'; import renderSandboxedMermaid from './render_sandboxed_mermaid'; import renderMetrics from './render_metrics'; +import renderObservability from './render_observability'; import { renderJSONTable } from './render_json_table'; -// Render GitLab flavoured Markdown -// -// Delegates to syntax highlight and render math & mermaid diagrams. -// -$.fn.renderGFM = function renderGFM() { - syntaxHighlight(this.find('.js-syntax-highlight').get()); - renderKroki(this.find('.js-render-kroki[hidden]').get()); - renderMath(this.find('.js-render-math')); - renderSandboxedMermaid(this.find('.js-render-mermaid').get()); - renderJSONTable( - Array.from(this.find('[lang="json"][data-lang-params="table"]').get()).map((e) => e.parentNode), - ); - - highlightCurrentUser(this.find('.gfm-project_member').get()); +function initPopovers(elements) { + if (!elements.length) return; + import(/* webpackChunkName: 'IssuablePopoverBundle' */ '~/issuable/popover') + .then(({ default: initIssuablePopovers }) => { + initIssuablePopovers(elements); + }) + .catch(() => {}); +} - const issuablePopoverElements = this.find('.gfm-issue, .gfm-merge_request').get(); - if (issuablePopoverElements.length) { - import(/* webpackChunkName: 'IssuablePopoverBundle' */ '~/issuable/popover') - .then(({ default: initIssuablePopovers }) => { - initIssuablePopovers(issuablePopoverElements); - }) - .catch(() => {}); - } - - renderMetrics(this.find('.js-render-metrics').get()); - return this; -}; +// Render GitLab flavoured Markdown +export function renderGFM(element) { + const [ + highlightEls, + krokiEls, + mathEls, + mermaidEls, + tableEls, + userEls, + popoverEls, + metricsEls, + observabilityEls, + ] = [ + '.js-syntax-highlight', + '.js-render-kroki[hidden]', + '.js-render-math', + '.js-render-mermaid', + '[lang="json"][data-lang-params="table"]', + '.gfm-project_member', + '.gfm-issue, .gfm-merge_request', + '.js-render-metrics', + '.js-render-observability', + ].map((selector) => Array.from(element.querySelectorAll(selector))); -$(() => { - window.requestIdleCallback( - () => { - $('body').renderGFM(); - }, - { timeout: 500 }, - ); -}); + syntaxHighlight(highlightEls); + renderKroki(krokiEls); + renderMath(mathEls); + renderSandboxedMermaid(mermaidEls); + renderJSONTable(tableEls.map((e) => e.parentNode)); + highlightCurrentUser(userEls); + renderMetrics(metricsEls); + renderObservability(observabilityEls); + initPopovers(popoverEls); +} diff --git a/app/assets/javascripts/behaviors/markdown/render_math.js b/app/assets/javascripts/behaviors/markdown/render_math.js index ac41af4df7a..7852a909160 100644 --- a/app/assets/javascripts/behaviors/markdown/render_math.js +++ b/app/assets/javascripts/behaviors/markdown/render_math.js @@ -175,14 +175,14 @@ class SafeMathRenderer { } } -export default function renderMath($els) { - if (!$els.length) return; +export default function renderMath(elements) { + if (!elements.length) return; Promise.all([ import(/* webpackChunkName: 'katex' */ 'katex'), import(/* webpackChunkName: 'katex' */ 'katex/dist/katex.min.css'), ]) .then(([katex]) => { - const renderer = new SafeMathRenderer($els.get(), katex); + const renderer = new SafeMathRenderer(elements, katex); renderer.render(); renderer.attachEvents(); }) diff --git a/app/assets/javascripts/behaviors/markdown/render_observability.js b/app/assets/javascripts/behaviors/markdown/render_observability.js new file mode 100644 index 00000000000..704d85cf22e --- /dev/null +++ b/app/assets/javascripts/behaviors/markdown/render_observability.js @@ -0,0 +1,33 @@ +import Vue from 'vue'; +import { darkModeEnabled } from '~/lib/utils/color_utils'; +import { setUrlParams } from '~/lib/utils/url_utility'; + +export function getFrameSrc(url) { + return `${setUrlParams({ theme: darkModeEnabled() ? 'dark' : 'light' }, url)}&kiosk`; +} + +const mountVueComponent = (element) => { + const url = [element.dataset.frameUrl]; + + return new Vue({ + el: element, + render(h) { + return h('iframe', { + style: { + height: '366px', + width: '768px', + }, + attrs: { + src: getFrameSrc(url), + frameBorder: '0', + }, + }); + }, + }); +}; + +export default function renderObservability(elements) { + elements.forEach((element) => { + mountVueComponent(element); + }); +} |