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-05-11 18:07:26 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-11 18:07:26 +0300
commit6282dd78339f98cbc5624e7fdf744a342d3d8b73 (patch)
tree50952cb7a6f9ead4c805c20227871d3be845cc98 /app/assets/javascripts/content_editor
parentb9ab87c14ce9ebe8284aeffa32c1cee934156e58 (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/services/markdown_serializer.js28
-rw-r--r--app/assets/javascripts/content_editor/services/serialization_helpers.js117
2 files changed, 127 insertions, 18 deletions
diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js
index 6c8c562af8e..d665f24bba1 100644
--- a/app/assets/javascripts/content_editor/services/markdown_serializer.js
+++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js
@@ -48,7 +48,6 @@ import Text from '../extensions/text';
import Video from '../extensions/video';
import WordBreak from '../extensions/word_break';
import {
- isPlainURL,
renderCodeBlock,
renderHardBreak,
renderTable,
@@ -62,36 +61,29 @@ import {
renderHTMLNode,
renderContent,
preserveUnchanged,
+ bold,
+ italic,
+ link,
+ code,
} from './serialization_helpers';
const defaultSerializerConfig = {
marks: {
- [Bold.name]: defaultMarkdownSerializer.marks.strong,
- [Italic.name]: { open: '_', close: '_', mixable: true, expelEnclosingWhitespace: true },
- [Code.name]: defaultMarkdownSerializer.marks.code,
+ [Bold.name]: bold,
+ [Italic.name]: italic,
+ [Code.name]: code,
[Subscript.name]: { open: '<sub>', close: '</sub>', mixable: true },
[Superscript.name]: { open: '<sup>', close: '</sup>', mixable: true },
[InlineDiff.name]: {
mixable: true,
- open(state, mark) {
+ open(_, mark) {
return mark.attrs.type === 'addition' ? '{+' : '{-';
},
- close(state, mark) {
+ close(_, mark) {
return mark.attrs.type === 'addition' ? '+}' : '-}';
},
},
- [Link.name]: {
- open(state, mark, parent, index) {
- return isPlainURL(mark, parent, index, 1) ? '<' : '[';
- },
- close(state, mark, parent, index) {
- const href = mark.attrs.canonicalSrc || mark.attrs.href;
-
- return isPlainURL(mark, parent, index, -1)
- ? '>'
- : `](${state.esc(href)}${mark.attrs.title ? ` ${state.quote(mark.attrs.title)}` : ''})`;
- },
- },
+ [Link.name]: link,
[MathInline.name]: {
open: (...args) => `$${defaultMarkdownSerializer.marks.code.open(...args)}`,
close: (...args) => `${defaultMarkdownSerializer.marks.code.close(...args)}$`,
diff --git a/app/assets/javascripts/content_editor/services/serialization_helpers.js b/app/assets/javascripts/content_editor/services/serialization_helpers.js
index 99aaee8f312..089d30edec7 100644
--- a/app/assets/javascripts/content_editor/services/serialization_helpers.js
+++ b/app/assets/javascripts/content_editor/services/serialization_helpers.js
@@ -363,3 +363,120 @@ export function preserveUnchanged(render) {
}
};
}
+
+const generateBoldTags = (open = true) => {
+ return (_, mark) => {
+ const type = /^(\*\*|__|<strong|<b).*/.exec(mark.attrs.sourceMarkdown)?.[1];
+
+ switch (type) {
+ case '**':
+ case '__':
+ return type;
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ case '<strong':
+ case '<b':
+ return (open ? openTag : closeTag)(type.substring(1));
+ default:
+ return '**';
+ }
+ };
+};
+
+export const bold = {
+ open: generateBoldTags(),
+ close: generateBoldTags(false),
+ mixable: true,
+ expelEnclosingWhitespace: true,
+};
+
+const generateItalicTag = (open = true) => {
+ return (_, mark) => {
+ const type = /^(\*|_|<em|<i).*/.exec(mark.attrs.sourceMarkdown)?.[1];
+
+ switch (type) {
+ case '*':
+ case '_':
+ return type;
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ case '<em':
+ case '<i':
+ return (open ? openTag : closeTag)(type.substring(1));
+ default:
+ return '_';
+ }
+ };
+};
+
+export const italic = {
+ open: generateItalicTag(),
+ close: generateItalicTag(false),
+ mixable: true,
+ expelEnclosingWhitespace: true,
+};
+
+const generateCodeTag = (open = true) => {
+ return (_, mark) => {
+ const type = /^(`|<code).*/.exec(mark.attrs.sourceMarkdown)?.[1];
+
+ if (type === '<code') {
+ return (open ? openTag : closeTag)(type.substring(1));
+ }
+
+ return '`';
+ };
+};
+
+export const code = {
+ open: generateCodeTag(),
+ close: generateCodeTag(false),
+ mixable: true,
+ expelEnclosingWhitespace: true,
+};
+
+const LINK_HTML = 'linkHtml';
+const LINK_MARKDOWN = 'linkMarkdown';
+
+const linkType = (sourceMarkdown) => {
+ const expression = /^(\[|<a).*/.exec(sourceMarkdown)?.[1];
+
+ if (!expression || expression === '[') {
+ return LINK_MARKDOWN;
+ }
+
+ return LINK_HTML;
+};
+
+export const link = {
+ open(state, mark, parent, index) {
+ if (isPlainURL(mark, parent, index, 1)) {
+ return '<';
+ }
+
+ const { canonicalSrc, href, title, sourceMarkdown } = mark.attrs;
+
+ if (linkType(sourceMarkdown) === LINK_MARKDOWN) {
+ return '[';
+ }
+
+ const attrs = { href: state.esc(href || canonicalSrc) };
+
+ if (title) {
+ attrs.title = title;
+ }
+
+ return openTag('a', attrs);
+ },
+ close(state, mark, parent, index) {
+ if (isPlainURL(mark, parent, index, -1)) {
+ return '>';
+ }
+
+ const { canonicalSrc, href, title, sourceMarkdown } = mark.attrs;
+
+ if (linkType(sourceMarkdown) === LINK_HTML) {
+ return closeTag('a');
+ }
+
+ return `](${state.esc(canonicalSrc || href)}${title ? ` ${state.quote(title)}` : ''})`;
+ },
+};