Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-10-13 18:09:32 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-10-13 18:09:32 +0300
commitbd25f1d9c685039381df23e49bc52cdcf4ec1b4a (patch)
tree33b3b16ae2ef653f74828f69742154122ff0ac2d /app/assets/javascripts/vue_shared/components/source_viewer
parent70ce746bd011b101605e6d84f141d1f0c3175831 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/source_viewer')
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/constants.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js4
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_child_nodes.js45
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_comments.js41
5 files changed, 48 insertions, 46 deletions
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue b/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue
index 6395dbdac50..ffd0eea63a1 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue
@@ -48,7 +48,7 @@ export default {
</div>
<pre
- class="gl-p-0! gl-w-full gl-overflow-visible! gl-border-none! code highlight gl-line-height-normal"
+ class="gl-p-0! gl-w-full gl-overflow-visible! gl-border-none! code highlight gl-line-height-0"
><code><span :id="`LC${number}`" v-safe-html="content" :lang="language" class="line" data-testid="content"></span></code></pre>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/constants.js b/app/assets/javascripts/vue_shared/components/source_viewer/constants.js
index 10489a4eff3..a28460dd58e 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/constants.js
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/constants.js
@@ -139,6 +139,4 @@ export const BIDI_CHARS_CLASS_LIST = 'unicode-bidi has-tooltip';
export const BIDI_CHAR_TOOLTIP = 'Potentially unwanted character detected: Unicode BiDi Control';
-export const HLJS_COMMENT_SELECTOR = 'hljs-comment';
-
export const HLJS_ON_AFTER_HIGHLIGHT = 'after:highlight';
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js
index e38c9b8f66f..d694adf7147 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js
@@ -1,4 +1,4 @@
-import wrapComments from './wrap_comments';
+import wrapChildNodes from './wrap_child_nodes';
import linkDependencies from './link_dependencies';
import wrapBidiChars from './wrap_bidi_chars';
@@ -12,8 +12,8 @@ export const HLJS_ON_AFTER_HIGHLIGHT = 'after:highlight';
* @param {Object} hljs - the Highlight.js instance.
*/
export const registerPlugins = (hljs, fileType, rawContent) => {
+ hljs.addPlugin({ [HLJS_ON_AFTER_HIGHLIGHT]: wrapChildNodes });
hljs.addPlugin({ [HLJS_ON_AFTER_HIGHLIGHT]: wrapBidiChars });
- hljs.addPlugin({ [HLJS_ON_AFTER_HIGHLIGHT]: wrapComments });
hljs.addPlugin({
[HLJS_ON_AFTER_HIGHLIGHT]: (result) => linkDependencies(result, fileType, rawContent),
});
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_child_nodes.js b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_child_nodes.js
new file mode 100644
index 00000000000..e0ba4b730a7
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_child_nodes.js
@@ -0,0 +1,45 @@
+import { escape } from 'lodash';
+
+/**
+ * Highlight.js plugin for wrapping nodes with the correct selectors to ensure
+ * child-elements are highlighted correctly after we split up the result into chunks and lines.
+ *
+ * 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
+ */
+const newlineRegex = /\r?\n/;
+const generateClassName = (suffix) => (suffix ? `hljs-${escape(suffix)}` : '');
+const generateCloseTag = (includeClose) => (includeClose ? '</span>' : '');
+const generateHLJSTag = (kind, content = '', includeClose) =>
+ `<span class="${generateClassName(kind)}">${escape(content)}${generateCloseTag(includeClose)}`;
+
+const format = (node, kind = '') => {
+ let buffer = '';
+
+ if (typeof node === 'string') {
+ buffer += node
+ .split(newlineRegex)
+ .map((newline) => generateHLJSTag(kind, newline, true))
+ .join('\n');
+ } else if (node.kind) {
+ const { children } = node;
+ if (children.length && children.length === 1) {
+ buffer += format(children[0], node.kind);
+ } else {
+ buffer += generateHLJSTag(node.kind);
+ children.forEach((subChild) => {
+ buffer += format(subChild, node.kind);
+ });
+ buffer += `</span>`;
+ }
+ }
+
+ return buffer;
+};
+
+export default (result) => {
+ // NOTE: We're using the private Emitter API here as we expect the Emitter API to be publicly available soon (https://github.com/highlightjs/highlight.js/issues/3621)
+ // eslint-disable-next-line no-param-reassign, no-underscore-dangle
+ result.value = result._emitter.rootNode.children.reduce((val, node) => val + format(node), ''); // Highlight.js expects the result param to be mutated for plugins to work
+};
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_comments.js b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_comments.js
deleted file mode 100644
index 8b52df83fdf..00000000000
--- a/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_comments.js
+++ /dev/null
@@ -1,41 +0,0 @@
-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');
-};