diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-10 18:08:17 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-10 18:08:17 +0300 |
commit | 69e6424b738ea9ac3c6eed0263fe5a6951df7195 (patch) | |
tree | 64f4c186ee1e5587d642eaaf1c6a064e841946ba /app/assets/javascripts/content_editor | |
parent | 215001eca7ababe4c617a04a37d307a97353d6e0 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/content_editor')
-rw-r--r-- | app/assets/javascripts/content_editor/extensions/copy_paste.js (renamed from app/assets/javascripts/content_editor/extensions/paste_markdown.js) | 54 | ||||
-rw-r--r-- | app/assets/javascripts/content_editor/extensions/loading.js | 23 | ||||
-rw-r--r-- | app/assets/javascripts/content_editor/services/create_content_editor.js | 6 | ||||
-rw-r--r-- | app/assets/javascripts/content_editor/services/markdown_serializer.js | 2 |
4 files changed, 71 insertions, 14 deletions
diff --git a/app/assets/javascripts/content_editor/extensions/paste_markdown.js b/app/assets/javascripts/content_editor/extensions/copy_paste.js index db13438de5e..45a89cc08cf 100644 --- a/app/assets/javascripts/content_editor/extensions/paste_markdown.js +++ b/app/assets/javascripts/content_editor/extensions/copy_paste.js @@ -2,6 +2,7 @@ import OrderedMap from 'orderedmap'; import { Extension } from '@tiptap/core'; import { Plugin, PluginKey } from '@tiptap/pm/state'; import { Schema, DOMParser as ProseMirrorDOMParser, DOMSerializer } from '@tiptap/pm/model'; +import { uniqueId } from 'lodash'; import { __ } from '~/locale'; import { VARIANT_DANGER } from '~/alert'; import createMarkdownDeserializer from '../services/gl_api_markdown_deserializer'; @@ -24,8 +25,23 @@ function parseHTML(schema, html) { return { document: ProseMirrorDOMParser.fromSchema(schema).parse(body) }; } +const findLoader = (editor, loaderId) => { + let position; + + editor.view.state.doc.descendants((descendant, pos) => { + if (descendant.type.name === 'loading' && descendant.attrs.id === loaderId) { + position = pos; + return false; + } + + return true; + }); + + return position; +}; + export default Extension.create({ - name: 'pasteMarkdown', + name: 'copyPaste', priority: EXTENSION_PRIORITY_HIGHEST, addOptions() { return { @@ -35,7 +51,7 @@ export default Extension.create({ }, addCommands() { return { - pasteContent: (content = '', processMarkdown = true) => async () => { + pasteContent: (content = '', processMarkdown = true) => () => { const { editor, options } = this; const { renderMarkdown, eventHub } = options; const deserializer = createMarkdownDeserializer({ render: renderMarkdown }); @@ -43,23 +59,37 @@ export default Extension.create({ const pasteSchemaSpec = { ...editor.schema.spec }; pasteSchemaSpec.marks = OrderedMap.from(pasteSchemaSpec.marks).remove('span'); pasteSchemaSpec.nodes = OrderedMap.from(pasteSchemaSpec.nodes).remove('div').remove('pre'); - const schema = new Schema(pasteSchemaSpec); + const pasteSchema = new Schema(pasteSchemaSpec); const promise = processMarkdown - ? deserializer.deserialize({ schema, markdown: content }) - : Promise.resolve(parseHTML(schema, content)); - - promise - .then(({ document }) => { + ? deserializer.deserialize({ schema: pasteSchema, markdown: content }) + : Promise.resolve(parseHTML(pasteSchema, content)); + const loaderId = uniqueId('loading'); + + Promise.resolve() + .then(() => { + editor.commands.insertContent({ type: 'loading', attrs: { id: loaderId } }); + return promise; + }) + .then(async ({ document }) => { if (!document) return; - const { firstChild } = document.content; + const pos = findLoader(editor, loaderId); + if (!pos) return; + + const { firstChild, childCount } = document.content; const toPaste = - document.content.childCount === 1 && firstChild.type.name === 'paragraph' + childCount === 1 && firstChild.type.name === 'paragraph' ? firstChild.content : document.content; - editor.commands.insertContent(toPaste.toJSON()); + editor + .chain() + .deleteRange({ from: pos, to: pos + 1 }) + .insertContentAt(pos, toPaste.toJSON(), { + updateSelection: false, + }) + .run(); }) .catch(() => { eventHub.$emit(ALERT_EVENT, { @@ -94,7 +124,7 @@ export default Extension.create({ return [ new Plugin({ - key: new PluginKey('pasteMarkdown'), + key: new PluginKey('copyPaste'), props: { handleDOMEvents: { copy: handleCutAndCopy, diff --git a/app/assets/javascripts/content_editor/extensions/loading.js b/app/assets/javascripts/content_editor/extensions/loading.js new file mode 100644 index 00000000000..0115fb10d5d --- /dev/null +++ b/app/assets/javascripts/content_editor/extensions/loading.js @@ -0,0 +1,23 @@ +import { Node } from '@tiptap/core'; + +export default Node.create({ + name: 'loading', + inline: true, + group: 'inline', + + addAttributes() { + return { + id: { + default: null, + }, + }; + }, + + renderHTML() { + return [ + 'span', + { class: 'gl-display-inline-flex gl-align-items-center' }, + ['span', { class: 'gl-dots-loader gl-mx-2' }, ['span']], + ]; + }, +}); diff --git a/app/assets/javascripts/content_editor/services/create_content_editor.js b/app/assets/javascripts/content_editor/services/create_content_editor.js index a0dc059b909..f7d189e443f 100644 --- a/app/assets/javascripts/content_editor/services/create_content_editor.js +++ b/app/assets/javascripts/content_editor/services/create_content_editor.js @@ -11,6 +11,7 @@ import Code from '../extensions/code'; import CodeBlockHighlight from '../extensions/code_block_highlight'; import CodeSuggestion from '../extensions/code_suggestion'; import ColorChip from '../extensions/color_chip'; +import CopyPaste from '../extensions/copy_paste'; import DescriptionItem from '../extensions/description_item'; import DescriptionList from '../extensions/description_list'; import Details from '../extensions/details'; @@ -40,10 +41,10 @@ import InlineDiff from '../extensions/inline_diff'; import Italic from '../extensions/italic'; import Link from '../extensions/link'; import ListItem from '../extensions/list_item'; +import Loading from '../extensions/loading'; import MathInline from '../extensions/math_inline'; import OrderedList from '../extensions/ordered_list'; import Paragraph from '../extensions/paragraph'; -import PasteMarkdown from '../extensions/paste_markdown'; import Reference from '../extensions/reference'; import ReferenceLabel from '../extensions/reference_label'; import ReferenceDefinition from '../extensions/reference_definition'; @@ -143,10 +144,11 @@ export const createContentEditor = ({ ExternalKeydownHandler.configure({ eventHub }), Link, ListItem, + Loading, MathInline, OrderedList, Paragraph, - PasteMarkdown.configure({ eventHub, renderMarkdown, serializer }), + CopyPaste.configure({ eventHub, renderMarkdown, serializer }), Reference.configure({ assetResolver }), ReferenceLabel, ReferenceDefinition, diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js index bc738073e15..972b4acf523 100644 --- a/app/assets/javascripts/content_editor/services/markdown_serializer.js +++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js @@ -32,6 +32,7 @@ import InlineDiff from '../extensions/inline_diff'; import Italic from '../extensions/italic'; import Link from '../extensions/link'; import ListItem from '../extensions/list_item'; +import Loading from '../extensions/loading'; import MathInline from '../extensions/math_inline'; import OrderedList from '../extensions/ordered_list'; import Paragraph from '../extensions/paragraph'; @@ -194,6 +195,7 @@ const defaultSerializerConfig = { inline: true, }), [ListItem.name]: preserveUnchanged(defaultMarkdownSerializer.nodes.list_item), + [Loading.name]: () => {}, [OrderedList.name]: preserveUnchanged(renderOrderedList), [Paragraph.name]: preserveUnchanged(defaultMarkdownSerializer.nodes.paragraph), [Reference.name]: renderReference, |