diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-08 18:08:15 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-08 18:08:15 +0300 |
commit | e18e22ce4c7a4ee0680adda25e4cfa9cf4bb1be4 (patch) | |
tree | ad5cdd2a994e9ae4627330769eb5004f49d6f435 /app/assets/javascripts/content_editor | |
parent | cdda3d117c99cadf295f26abc92cb2456033b762 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/content_editor')
5 files changed, 71 insertions, 21 deletions
diff --git a/app/assets/javascripts/content_editor/components/wrappers/footnote_definition.vue b/app/assets/javascripts/content_editor/components/wrappers/footnote_definition.vue new file mode 100644 index 00000000000..8b7b02605f7 --- /dev/null +++ b/app/assets/javascripts/content_editor/components/wrappers/footnote_definition.vue @@ -0,0 +1,28 @@ +<script> +import { NodeViewWrapper, NodeViewContent } from '@tiptap/vue-2'; + +export default { + name: 'FootnoteDefinitionWrapper', + components: { + NodeViewWrapper, + NodeViewContent, + }, + props: { + node: { + type: Object, + required: true, + }, + }, +}; +</script> +<template> + <node-view-wrapper class="gl-display-flex gl-font-sm" as="div"> + <span + data-testid="footnote-label" + contenteditable="false" + class="gl-display-inline-flex gl-mr-2" + >{{ node.attrs.label }}:</span + > + <node-view-content /> + </node-view-wrapper> +</template> diff --git a/app/assets/javascripts/content_editor/extensions/footnote_definition.js b/app/assets/javascripts/content_editor/extensions/footnote_definition.js index dbab0de3421..6b1c0c9fd7d 100644 --- a/app/assets/javascripts/content_editor/extensions/footnote_definition.js +++ b/app/assets/javascripts/content_editor/extensions/footnote_definition.js @@ -1,12 +1,26 @@ import { mergeAttributes, Node } from '@tiptap/core'; +import { VueNodeViewRenderer } from '@tiptap/vue-2'; +import FootnoteDefinitionWrapper from '../components/wrappers/footnote_definition.vue'; import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants'; +const extractFootnoteIdentifier = (idAttribute) => /^fn-(\w+)-\d+$/.exec(idAttribute)?.[1]; + export default Node.create({ name: 'footnoteDefinition', - - content: 'paragraph', - + content: 'inline*', group: 'block', + addAttributes() { + return { + identifier: { + default: null, + parseHTML: (element) => extractFootnoteIdentifier(element.getAttribute('id')), + }, + label: { + default: null, + parseHTML: (element) => extractFootnoteIdentifier(element.getAttribute('id')), + }, + }; + }, parseHTML() { return [ @@ -15,7 +29,11 @@ export default Node.create({ ]; }, - renderHTML({ HTMLAttributes }) { - return ['li', mergeAttributes(HTMLAttributes), 0]; + renderHTML({ label, ...HTMLAttributes }) { + return ['div', mergeAttributes(HTMLAttributes), 0]; + }, + + addNodeView() { + return new VueNodeViewRenderer(FootnoteDefinitionWrapper); }, }); diff --git a/app/assets/javascripts/content_editor/extensions/footnote_reference.js b/app/assets/javascripts/content_editor/extensions/footnote_reference.js index 1ac8016f774..ae5b8edc7af 100644 --- a/app/assets/javascripts/content_editor/extensions/footnote_reference.js +++ b/app/assets/javascripts/content_editor/extensions/footnote_reference.js @@ -1,6 +1,9 @@ import { Node, mergeAttributes } from '@tiptap/core'; import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants'; +const extractFootnoteIdentifier = (element) => + /^fnref-(\w+)-\d+$/.exec(element.querySelector('a')?.getAttribute('id'))?.[1]; + export default Node.create({ name: 'footnoteReference', @@ -16,13 +19,13 @@ export default Node.create({ addAttributes() { return { - footnoteId: { + identifier: { default: null, - parseHTML: (element) => element.querySelector('a').getAttribute('id'), + parseHTML: extractFootnoteIdentifier, }, - footnoteNumber: { + label: { default: null, - parseHTML: (element) => element.textContent, + parseHTML: extractFootnoteIdentifier, }, }; }, @@ -31,7 +34,7 @@ export default Node.create({ return [{ tag: 'sup.footnote-ref', priority: PARSE_HTML_PRIORITY_HIGHEST }]; }, - renderHTML({ HTMLAttributes: { footnoteNumber, footnoteId, ...HTMLAttributes } }) { - return ['sup', mergeAttributes(HTMLAttributes), footnoteNumber]; + renderHTML({ HTMLAttributes: { label, ...HTMLAttributes } }) { + return ['sup', mergeAttributes(HTMLAttributes), label]; }, }); diff --git a/app/assets/javascripts/content_editor/extensions/footnotes_section.js b/app/assets/javascripts/content_editor/extensions/footnotes_section.js index 914a8934734..2b2c4177e1d 100644 --- a/app/assets/javascripts/content_editor/extensions/footnotes_section.js +++ b/app/assets/javascripts/content_editor/extensions/footnotes_section.js @@ -10,7 +10,10 @@ export default Node.create({ isolating: true, parseHTML() { - return [{ tag: 'section.footnotes > ol' }]; + return [ + { tag: 'section.footnotes', skip: true }, + { tag: 'section.footnotes > ol', skip: true }, + ]; }, renderHTML({ HTMLAttributes }) { diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js index d5c4da8c76c..2d33a16f1a5 100644 --- a/app/assets/javascripts/content_editor/services/markdown_serializer.js +++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js @@ -17,7 +17,6 @@ import Diagram from '../extensions/diagram'; import Emoji from '../extensions/emoji'; import Figure from '../extensions/figure'; import FigureCaption from '../extensions/figure_caption'; -import FootnotesSection from '../extensions/footnotes_section'; import FootnoteDefinition from '../extensions/footnote_definition'; import FootnoteReference from '../extensions/footnote_reference'; import Frontmatter from '../extensions/frontmatter'; @@ -154,15 +153,14 @@ const defaultSerializerConfig = { state.write(`:${name}:`); }, - [FootnoteDefinition.name]: (state, node) => { + [FootnoteDefinition.name]: preserveUnchanged((state, node) => { + state.write(`[^${node.attrs.identifier}]: `); state.renderInline(node); - }, - [FootnoteReference.name]: (state, node) => { - state.write(`[^${node.attrs.footnoteNumber}]`); - }, - [FootnotesSection.name]: (state, node) => { - state.renderList(node, '', (index) => `[^${index + 1}]: `); - }, + state.ensureNewLine(); + }), + [FootnoteReference.name]: preserveUnchanged((state, node) => { + state.write(`[^${node.attrs.identifier}]`); + }), [Frontmatter.name]: (state, node) => { const { language } = node.attrs; const syntax = { |