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-06-08 18:08:15 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-08 18:08:15 +0300
commite18e22ce4c7a4ee0680adda25e4cfa9cf4bb1be4 (patch)
treead5cdd2a994e9ae4627330769eb5004f49d6f435 /app/assets/javascripts/content_editor
parentcdda3d117c99cadf295f26abc92cb2456033b762 (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/components/wrappers/footnote_definition.vue28
-rw-r--r--app/assets/javascripts/content_editor/extensions/footnote_definition.js28
-rw-r--r--app/assets/javascripts/content_editor/extensions/footnote_reference.js15
-rw-r--r--app/assets/javascripts/content_editor/extensions/footnotes_section.js5
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_serializer.js16
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 = {