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

paste_markdown.js « extensions « content_editor « javascripts « assets « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c349aa42a62f7fa887fc5802bb0f692c42922adc (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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { Extension } from '@tiptap/core';
import { Plugin, PluginKey } from 'prosemirror-state';
import { __ } from '~/locale';
import { VARIANT_DANGER } from '~/flash';
import createMarkdownDeserializer from '../services/markdown_deserializer';
import {
  ALERT_EVENT,
  LOADING_CONTENT_EVENT,
  LOADING_SUCCESS_EVENT,
  LOADING_ERROR_EVENT,
  EXTENSION_PRIORITY_HIGHEST,
} from '../constants';

const TEXT_FORMAT = 'text/plain';
const HTML_FORMAT = 'text/html';
const VS_CODE_FORMAT = 'vscode-editor-data';

export default Extension.create({
  name: 'pasteMarkdown',
  priority: EXTENSION_PRIORITY_HIGHEST,
  addOptions() {
    return {
      renderMarkdown: null,
    };
  },
  addCommands() {
    return {
      pasteMarkdown: (markdown) => () => {
        const { editor, options } = this;
        const { renderMarkdown, eventHub } = options;
        const deserializer = createMarkdownDeserializer({ render: renderMarkdown });

        eventHub.$emit(LOADING_CONTENT_EVENT);

        deserializer
          .deserialize({ schema: editor.schema, content: markdown })
          .then(({ document }) => {
            if (!document) {
              return;
            }

            const { state, view } = editor;
            const { tr, selection } = state;

            tr.replaceWith(selection.from - 1, selection.to, document.content);
            view.dispatch(tr);
            eventHub.$emit(LOADING_SUCCESS_EVENT);
          })
          .catch(() => {
            eventHub.$emit(ALERT_EVENT, {
              message: __('An error occurred while pasting text in the editor. Please try again.'),
              variant: VARIANT_DANGER,
            });
            eventHub.$emit(LOADING_ERROR_EVENT);
          });

        return true;
      },
    };
  },
  addProseMirrorPlugins() {
    return [
      new Plugin({
        key: new PluginKey('pasteMarkdown'),
        props: {
          handlePaste: (_, event) => {
            const { clipboardData } = event;
            const content = clipboardData.getData(TEXT_FORMAT);
            const hasHTML = clipboardData.types.some((type) => type === HTML_FORMAT);
            const hasVsCode = clipboardData.types.some((type) => type === VS_CODE_FORMAT);
            const vsCodeMeta = hasVsCode ? JSON.parse(clipboardData.getData(VS_CODE_FORMAT)) : {};
            const language = vsCodeMeta.mode;

            if (!content || (hasHTML && !hasVsCode) || (hasVsCode && language !== 'markdown')) {
              return false;
            }

            this.editor.commands.pasteMarkdown(content);

            return true;
          },
        },
      }),
    ];
  },
});