summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_comments.js
blob: 8b52df83fdf0d092df2a80c02ee616ea7362303c (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
import { HLJS_COMMENT_SELECTOR } from '../constants';

const createWrapper = (content) => {
  const span = document.createElement('span');
  span.className = HLJS_COMMENT_SELECTOR;

  // eslint-disable-next-line no-unsanitized/property
  span.innerHTML = content;
  return span.outerHTML;
};

/**
 * Highlight.js plugin for wrapping multi-line comments in the `hljs-comment` class.
 * This ensures that multi-line comments are rendered correctly in the GitLab UI.
 *
 * Plugin API: https://github.com/highlightjs/highlight.js/blob/main/docs/plugin-api.rst
 *
 * @param {Object} Result - an object that represents the highlighted result from Highlight.js
 */
export default (result) => {
  if (!result.value.includes(HLJS_COMMENT_SELECTOR)) return;

  let wrapComment = false;

  // eslint-disable-next-line no-param-reassign
  result.value = result.value // Highlight.js expects the result param to be mutated for plugins to work
    .split('\n')
    .map((lineContent) => {
      const includesClosingTag = lineContent.includes('</span>');
      if (lineContent.includes(HLJS_COMMENT_SELECTOR) && !includesClosingTag) {
        wrapComment = true;
        return lineContent;
      }
      const line = wrapComment ? createWrapper(lineContent) : lineContent;
      if (includesClosingTag) {
        wrapComment = false;
      }
      return line;
    })
    .join('\n');
};