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:
Diffstat (limited to 'app/assets/javascripts/content_editor/extensions/code_suggestion.js')
-rw-r--r--app/assets/javascripts/content_editor/extensions/code_suggestion.js81
1 files changed, 81 insertions, 0 deletions
diff --git a/app/assets/javascripts/content_editor/extensions/code_suggestion.js b/app/assets/javascripts/content_editor/extensions/code_suggestion.js
new file mode 100644
index 00000000000..c70a96769fb
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/code_suggestion.js
@@ -0,0 +1,81 @@
+import { lowlight } from 'lowlight/lib/core';
+import { textblockTypeInputRule } from '@tiptap/core';
+import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants';
+import { memoizedGet } from '../services/utils';
+import CodeBlockHighlight from './code_block_highlight';
+
+const backtickInputRegex = /^```suggestion[\s\n]$/;
+
+export default CodeBlockHighlight.extend({
+ name: 'codeSuggestion',
+
+ isolating: true,
+
+ addOptions() {
+ return {
+ lowlight,
+ config: {},
+ };
+ },
+
+ addAttributes() {
+ return {
+ ...this.parent?.(),
+ language: {
+ default: 'suggestion',
+ },
+ isCodeSuggestion: {
+ default: true,
+ },
+ };
+ },
+
+ addCommands() {
+ const ext = this;
+
+ return {
+ insertCodeSuggestion: (attributes) => async ({ editor }) => {
+ // do not insert a new suggestion if already inside a suggestion
+ if (editor.isActive('codeSuggestion')) return false;
+
+ const rawPath = ext.options.config.diffFile.view_path.replace('/blob/', '/raw/');
+ const allLines = (await memoizedGet(rawPath)).split('\n');
+ const { line } = ext.options.config;
+ let { lines } = ext.options.config;
+
+ if (!lines.length) lines = [line];
+
+ const content = lines.map((l) => allLines[l.new_line - 1]).join('\n');
+ const lineNumbers = `-${lines.length - 1}+0`;
+
+ editor.commands.insertContent({
+ type: 'codeSuggestion',
+ attrs: { langParams: lineNumbers, ...attributes },
+ // empty strings are not allowed in text nodes
+ content: [{ type: 'text', text: content || ' ' }],
+ });
+
+ return true;
+ },
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ priority: PARSE_HTML_PRIORITY_HIGHEST,
+ tag: 'pre[lang="suggestion"]',
+ },
+ ];
+ },
+
+ addInputRules() {
+ return [
+ textblockTypeInputRule({
+ find: backtickInputRegex,
+ type: this.type,
+ getAttributes: () => ({ language: 'suggestion', langParams: '-0+0' }),
+ }),
+ ];
+ },
+});