Commit 0578cc5c authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch 'remove-tiptapv1-from-builds' into 'master'

Remove tiptap v1 library

See merge request gitlab-org/gitlab!80013
parents fccbd744 3c485e1e
...@@ -48,54 +48,48 @@ import Video from './nodes/video'; ...@@ -48,54 +48,48 @@ import Video from './nodes/video';
// from GFM should have a node or mark here. // from GFM should have a node or mark here.
// The GFM-to-HTML-to-GFM cycle is tested in spec/features/markdown/copy_as_gfm_spec.rb. // The GFM-to-HTML-to-GFM cycle is tested in spec/features/markdown/copy_as_gfm_spec.rb.
export default [ export default {
new Doc(), nodes: [
new Paragraph(), Doc(),
new Text(), Paragraph(),
Text(),
new Blockquote(), Blockquote(),
new CodeBlock(), CodeBlock(),
new HardBreak(), HardBreak(),
new Heading({ maxLevel: 6 }), Heading(),
new HorizontalRule(), HorizontalRule(),
new Image(), Image(),
new Table(), Table(),
new TableHead(), TableHead(),
new TableBody(), TableBody(),
new TableHeaderRow(), TableHeaderRow(),
new TableRow(), TableRow(),
new TableCell(), TableCell(),
new Emoji(), Emoji(),
new Reference(), Reference(),
new TableOfContents(), TableOfContents(),
new Video(), Video(),
new Audio(), Audio(),
new BulletList(), BulletList(),
new OrderedList(), OrderedList(),
new ListItem(), ListItem(),
new DescriptionList(), DescriptionList(),
new DescriptionTerm(), DescriptionTerm(),
new DescriptionDetails(), DescriptionDetails(),
new TaskList(), TaskList(),
new OrderedTaskList(), OrderedTaskList(),
new TaskListItem(), TaskListItem(),
new Summary(), Summary(),
new Details(), Details(),
],
new Bold(), marks: [Bold(), Italic(), Strike(), InlineDiff(), Link(), Code(), MathMark(), InlineHTML()],
new Italic(), };
new Strike(),
new InlineDiff(),
new Link(),
new Code(),
new MathMark(),
new InlineHTML(),
];
/* eslint-disable class-methods-use-this */
import { Bold as BaseBold } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Bold extends BaseBold { export default () => {
get toMarkdown() { return {
return defaultMarkdownSerializer.marks.strong; name: 'bold',
} schema: {
} parseDOM: [
{
tag: 'strong',
},
],
toDOM: () => ['strong', 0],
},
toMarkdown: defaultMarkdownSerializer.marks.strong,
};
};
/* eslint-disable class-methods-use-this */
import { Code as BaseCode } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Code extends BaseCode { export default () => ({
get toMarkdown() { name: 'code',
return defaultMarkdownSerializer.marks.code; schema: {
} excludes: '_',
} parseDOM: [{ tag: 'code' }],
toDOM: () => ['code', 0],
},
toMarkdown: defaultMarkdownSerializer.marks.code,
});
/* eslint-disable class-methods-use-this */
import { Mark } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::InlineDiffFilter // Transforms generated HTML back to GFM for Banzai::Filter::InlineDiffFilter
export default class InlineDiff extends Mark { export default () => ({
get name() { name: 'inline_diff',
return 'inline_diff'; schema: {
} attrs: {
addition: {
get schema() { default: true,
return {
attrs: {
addition: {
default: true,
},
}, },
parseDOM: [ },
{ tag: 'span.idiff.addition', attrs: { addition: true } }, parseDOM: [
{ tag: 'span.idiff.deletion', attrs: { addition: false } }, { tag: 'span.idiff.addition', attrs: { addition: true } },
], { tag: 'span.idiff.deletion', attrs: { addition: false } },
toDOM: (node) => [ ],
'span', toDOM: (node) => [
{ class: `idiff left right ${node.attrs.addition ? 'addition' : 'deletion'}` }, 'span',
0, { class: `idiff left right ${node.attrs.addition ? 'addition' : 'deletion'}` },
], 0,
}; ],
} },
toMarkdown: {
get toMarkdown() { mixable: true,
return { open(_, mark) {
mixable: true, return mark.attrs.addition ? '{+' : '{-';
open(state, mark) { },
return mark.attrs.addition ? '{+' : '{-'; close(_, mark) {
}, return mark.attrs.addition ? '+}' : '-}';
close(state, mark) { },
return mark.attrs.addition ? '+}' : '-}'; },
}, });
};
}
}
/* eslint-disable class-methods-use-this */
import { escape } from 'lodash'; import { escape } from 'lodash';
import { Mark } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class InlineHTML extends Mark { export default () => ({
get name() { name: 'inline_html',
return 'inline_html'; schema: {
} excludes: '',
attrs: {
get schema() { tag: {},
return { title: { default: null },
excludes: '', },
attrs: { parseDOM: [
tag: {}, {
title: { default: null }, tag: 'sup, sub, kbd, q, samp, var',
}, getAttrs: (el) => ({ tag: el.nodeName.toLowerCase() }),
parseDOM: [
{
tag: 'sup, sub, kbd, q, samp, var',
getAttrs: (el) => ({ tag: el.nodeName.toLowerCase() }),
},
{
tag: 'abbr',
getAttrs: (el) => ({ tag: 'abbr', title: el.getAttribute('title') }),
},
],
toDOM: (node) => [node.attrs.tag, { title: node.attrs.title }, 0],
};
}
get toMarkdown() {
return {
mixable: true,
open(state, mark) {
return `<${mark.attrs.tag}${
mark.attrs.title ? ` title="${state.esc(escape(mark.attrs.title))}"` : ''
}>`;
}, },
close(state, mark) { {
return `</${mark.attrs.tag}>`; tag: 'abbr',
getAttrs: (el) => ({ tag: 'abbr', title: el.getAttribute('title') }),
}, },
}; ],
} toDOM: (node) => [node.attrs.tag, { title: node.attrs.title }, 0],
} },
toMarkdown: {
mixable: true,
open(state, mark) {
return `<${mark.attrs.tag}${
mark.attrs.title ? ` title="${state.esc(escape(mark.attrs.title))}"` : ''
}>`;
},
close(_, mark) {
return `</${mark.attrs.tag}>`;
},
},
});
/* eslint-disable class-methods-use-this */
import { Italic as BaseItalic } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Italic extends BaseItalic { export default () => ({
get toMarkdown() { name: 'italic',
return defaultMarkdownSerializer.marks.em; schema: {
} parseDOM: [{ tag: 'em' }],
} toDOM: () => ['em', 0],
},
toMarkdown: defaultMarkdownSerializer.marks.em,
});
/* eslint-disable class-methods-use-this */
import { Link as BaseLink } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Link extends BaseLink { export default () => ({
get toMarkdown() { name: 'link',
return { schema: {
mixable: true, attrs: {
open(state, mark, parent, index) { href: {
const open = defaultMarkdownSerializer.marks.link.open(state, mark, parent, index); default: null,
return open === '<' ? '' : open; },
target: {
default: null,
},
},
inclusive: false,
parseDOM: [
{
tag: 'a[href]',
getAttrs: (dom) => ({
href: dom.getAttribute('href'),
target: dom.getAttribute('target'),
}),
}, },
close(state, mark, parent, index) { ],
const close = defaultMarkdownSerializer.marks.link.close(state, mark, parent, index); toDOM: (node) => [
return close === '>' ? '' : close; 'a',
{
...node.attrs,
// eslint-disable-next-line @gitlab/require-i18n-strings
rel: 'noopener noreferrer nofollow',
target: node.attrs.target,
}, },
}; 0,
} ],
} },
toMarkdown: {
mixable: true,
open(state, mark, parent, index) {
const open = defaultMarkdownSerializer.marks.link.open(state, mark, parent, index);
return open === '<' ? '' : open;
},
close(state, mark, parent, index) {
const close = defaultMarkdownSerializer.marks.link.close(state, mark, parent, index);
return close === '>' ? '' : close;
},
},
});
/* eslint-disable class-methods-use-this */
import { Mark } from 'tiptap';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants'; import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::MathFilter // Transforms generated HTML back to GFM for Banzai::Filter::MathFilter
export default class MathMark extends Mark { export default () => ({
get name() { name: 'math',
return 'math'; schema: {
} parseDOM: [
// Matches HTML generated by Banzai::Filter::MathFilter
get schema() { {
return { tag: 'code.code.math[data-math-style=inline]',
parseDOM: [ priority: HIGHER_PARSE_RULE_PRIORITY,
// Matches HTML generated by Banzai::Filter::MathFilter
{
tag: 'code.code.math[data-math-style=inline]',
priority: HIGHER_PARSE_RULE_PRIORITY,
},
// Matches HTML after being transformed by app/assets/javascripts/behaviors/markdown/render_math.js
{
tag: 'span.katex',
contentElement: 'annotation[encoding="application/x-tex"]',
},
],
toDOM: () => ['code', { class: 'code math', 'data-math-style': 'inline' }, 0],
};
}
get toMarkdown() {
return {
escape: false,
open(state, mark, parent, index) {
return `$${defaultMarkdownSerializer.marks.code.open(state, mark, parent, index)}`;
}, },
close(state, mark, parent, index) { // Matches HTML after being transformed by app/assets/javascripts/behaviors/markdown/render_math.js
return `${defaultMarkdownSerializer.marks.code.close(state, mark, parent, index)}$`; {
tag: 'span.katex',
contentElement: 'annotation[encoding="application/x-tex"]',
}, },
}; ],
} toDOM: () => ['code', { class: 'code math', 'data-math-style': 'inline' }, 0],
} },
toMarkdown: {
escape: false,
open(state, mark, parent, index) {
return `$${defaultMarkdownSerializer.marks.code.open(state, mark, parent, index)}`;
},
close(state, mark, parent, index) {
return `${defaultMarkdownSerializer.marks.code.close(state, mark, parent, index)}$`;
},
},
});
/* eslint-disable class-methods-use-this */
import { Strike as BaseStrike } from 'tiptap-extensions';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Strike extends BaseStrike { export default () => ({
get toMarkdown() { name: 'strike',
return { schema: {
open: '~~', parseDOM: [
close: '~~', {
mixable: true, tag: 'del',
expelEnclosingWhitespace: true, },
}; ],
} toDOM: () => ['s', 0],
} },
toMarkdown: {
open: '~~',
close: '~~',
mixable: true,
expelEnclosingWhitespace: true,
},
});
import Playable from './playable'; import playable from './playable';
// Transforms generated HTML back to GFM for Banzai::Filter::AudioLinkFilter // Transforms generated HTML back to GFM for Banzai::Filter::AudioLinkFilter
export default class Audio extends Playable { export default () => playable({ mediaType: 'audio' });
constructor() {
super();
this.mediaType = 'audio';
}
}
/* eslint-disable class-methods-use-this */
import { Blockquote as BaseBlockquote } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Blockquote extends BaseBlockquote { export default () => ({
name: 'blockquote',
schema: {
content: 'block*',
group: 'block',
defining: true,
draggable: false,
parseDOM: [{ tag: 'blockquote' }],
toDOM: () => ['blockquote', 0],
},
toMarkdown(state, node) { toMarkdown(state, node) {
if (!node.childCount) return; if (!node.childCount) return;
defaultMarkdownSerializer.nodes.blockquote(state, node); defaultMarkdownSerializer.nodes.blockquote(state, node);
} },
} });
/* eslint-disable class-methods-use-this */
import { BulletList as BaseBulletList } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class BulletList extends BaseBulletList { export default () => ({
name: 'bullet_list',
schema: {
content: 'list_item+',
group: 'block',
parseDOM: [{ tag: 'ul' }],
toDOM: () => ['ul', 0],
},
toMarkdown(state, node) { toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.bullet_list(state, node); defaultMarkdownSerializer.nodes.bullet_list(state, node);
} },
} });
/* eslint-disable class-methods-use-this */
import { CodeBlock as BaseCodeBlock } from 'tiptap-extensions';
const PLAINTEXT_LANG = 'plaintext'; const PLAINTEXT_LANG = 'plaintext';
// Transforms generated HTML back to GFM for: // Transforms generated HTML back to GFM for:
...@@ -9,68 +5,67 @@ const PLAINTEXT_LANG = 'plaintext'; ...@@ -9,68 +5,67 @@ const PLAINTEXT_LANG = 'plaintext';
// - Banzai::Filter::MathFilter // - Banzai::Filter::MathFilter
// - Banzai::Filter::MermaidFilter // - Banzai::Filter::MermaidFilter
// - Banzai::Filter::SuggestionFilter // - Banzai::Filter::SuggestionFilter
export default class CodeBlock extends BaseCodeBlock { export default () => ({
get schema() { name: 'code_block',
return { schema: {
content: 'text*', content: 'text*',
marks: '', marks: '',
group: 'block', group: 'block',
code: true, code: true,
defining: true, defining: true,
attrs: { attrs: {
lang: { default: PLAINTEXT_LANG }, lang: { default: PLAINTEXT_LANG },
}, },
parseDOM: [ parseDOM: [
// Matches HTML generated by Banzai::Filter::SyntaxHighlightFilter, Banzai::Filter::MathFilter, Banzai::Filter::MermaidFilter, or Banzai::Filter::SuggestionFilter // Matches HTML generated by Banzai::Filter::SyntaxHighlightFilter, Banzai::Filter::MathFilter, Banzai::Filter::MermaidFilter, or Banzai::Filter::SuggestionFilter
{ {
tag: 'pre.code.highlight', tag: 'pre.code.highlight',
preserveWhitespace: 'full', preserveWhitespace: 'full',
getAttrs: (el) => { getAttrs: (el) => {
const lang = el.getAttribute('lang'); const lang = el.getAttribute('lang');
if (!lang || lang === '') return {}; if (!lang || lang === '') return {};
return { lang }; return { lang };
},
},
// Matches HTML generated by Banzai::Filter::MathFilter,
// after being transformed by app/assets/javascripts/behaviors/markdown/render_math.js
{
tag: 'span.katex-display',
preserveWhitespace: 'full',
contentElement: 'annotation[encoding="application/x-tex"]',
attrs: { lang: 'math' },
},
// Matches HTML generated by Banzai::Filter::MermaidFilter,
// after being transformed by app/assets/javascripts/behaviors/markdown/render_mermaid.js
{
tag: 'svg.mermaid',
preserveWhitespace: 'full',
contentElement: 'text.source',
attrs: { lang: 'mermaid' },
},
// Matches HTML generated by Banzai::Filter::SuggestionFilter,
// after being transformed by app/assets/javascripts/vue_shared/components/markdown/suggestions.vue
{
tag: '.md-suggestion',
skip: true,
},
{
tag: '.md-suggestion-header',
ignore: true,
}, },
{ },
tag: '.md-suggestion-diff', // Matches HTML generated by Banzai::Filter::MathFilter,
preserveWhitespace: 'full', // after being transformed by app/assets/javascripts/behaviors/markdown/render_math.js
getContent: (el, schema) => {
[...el.querySelectorAll('.line_content.new span')].map((span) => tag: 'span.katex-display',
schema.text(span.innerText), preserveWhitespace: 'full',
), contentElement: 'annotation[encoding="application/x-tex"]',
attrs: { lang: 'suggestion' }, attrs: { lang: 'math' },
}, },
], // Matches HTML generated by Banzai::Filter::MermaidFilter,
toDOM: (node) => ['pre', { class: 'code highlight', lang: node.attrs.lang }, ['code', 0]], // after being transformed by app/assets/javascripts/behaviors/markdown/render_mermaid.js
}; {
} tag: 'svg.mermaid',
preserveWhitespace: 'full',
contentElement: 'text.source',
attrs: { lang: 'mermaid' },
},
// Matches HTML generated by Banzai::Filter::SuggestionFilter,
// after being transformed by app/assets/javascripts/vue_shared/components/markdown/suggestions.vue
{
tag: '.md-suggestion',
skip: true,
},
{
tag: '.md-suggestion-header',
ignore: true,
},
{
tag: '.md-suggestion-diff',
preserveWhitespace: 'full',
getContent: (el, schema) =>
[...el.querySelectorAll('.line_content.new span')].map((span) =>
schema.text(span.innerText),
),
attrs: { lang: 'suggestion' },
},
],
toDOM: (node) => ['pre', { class: 'code highlight', lang: node.attrs.lang }, ['code', 0]],
},
toMarkdown(state, node) { toMarkdown(state, node) {
if (!node.childCount) return; if (!node.childCount) return;
...@@ -95,5 +90,5 @@ export default class CodeBlock extends BaseCodeBlock { ...@@ -95,5 +90,5 @@ export default class CodeBlock extends BaseCodeBlock {
state.write('```'); state.write('```');
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class DescriptionDetails extends Node { export default () => ({
get name() { name: 'description_details',
return 'description_details';
}
get schema() { schema: {
return { content: 'text*',
content: 'text*', marks: '',
marks: '', defining: true,
defining: true, parseDOM: [{ tag: 'dd' }],
parseDOM: [{ tag: 'dd' }], toDOM: () => ['dd', 0],
toDOM: () => ['dd', 0], },
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
state.flushClose(1); state.flushClose(1);
...@@ -24,5 +16,5 @@ export default class DescriptionDetails extends Node { ...@@ -24,5 +16,5 @@ export default class DescriptionDetails extends Node {
state.text(node.textContent, false); state.text(node.textContent, false);
state.write('</dd>'); state.write('</dd>');
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class DescriptionList extends Node { export default () => ({
get name() { name: 'description_list',
return 'description_list'; schema: {
} content: '(description_term+ description_details+)+',
group: 'block',
get schema() { parseDOM: [{ tag: 'dl' }],
return { toDOM: () => ['dl', 0],
content: '(description_term+ description_details+)+', },
group: 'block',
parseDOM: [{ tag: 'dl' }],
toDOM: () => ['dl', 0],
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
state.write('<dl>\n'); state.write('<dl>\n');
...@@ -24,5 +15,5 @@ export default class DescriptionList extends Node { ...@@ -24,5 +15,5 @@ export default class DescriptionList extends Node {
state.ensureNewLine(); state.ensureNewLine();
state.write('</dl>'); state.write('</dl>');
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class DescriptionTerm extends Node { export default () => ({
get name() { name: 'description_term',
return 'description_term'; schema: {
} content: 'text*',
marks: '',
get schema() { defining: true,
return { parseDOM: [{ tag: 'dt' }],
content: 'text*', toDOM: () => ['dt', 0],
marks: '', },
defining: true,
parseDOM: [{ tag: 'dt' }],
toDOM: () => ['dt', 0],
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
state.flushClose(state.closed && state.closed.type === node.type ? 1 : 2); state.flushClose(state.closed && state.closed.type === node.type ? 1 : 2);
state.write('<dt>'); state.write('<dt>');
state.text(node.textContent, false); state.text(node.textContent, false);
state.write('</dt>'); state.write('</dt>');
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Details extends Node { export default () => ({
get name() { name: 'details',
return 'details'; schema: {
} content: 'summary block*',
group: 'block',
get schema() { parseDOM: [{ tag: 'details' }],
return { toDOM: () => ['details', { open: true, onclick: 'return false', tabindex: '-1' }, 0],
content: 'summary block*', },
group: 'block',
parseDOM: [{ tag: 'details' }],
toDOM: () => ['details', { open: true, onclick: 'return false', tabindex: '-1' }, 0],
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
state.write('<details>\n'); state.write('<details>\n');
state.renderContent(node); state.renderContent(node);
...@@ -24,5 +14,5 @@ export default class Details extends Node { ...@@ -24,5 +14,5 @@ export default class Details extends Node {
state.ensureNewLine(); state.ensureNewLine();
state.write('</details>'); state.write('</details>');
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */ export default () => ({
name: 'doc',
import { Node } from 'tiptap'; schema: {
content: 'block+',
export default class Doc extends Node { },
get name() { });
return 'doc';
}
get schema() {
return {
content: 'block+',
};
}
}
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::EmojiFilter // Transforms generated HTML back to GFM for Banzai::Filter::EmojiFilter
export default class Emoji extends Node { export default () => ({
get name() { name: 'emoji',
return 'emoji'; schema: {
} inline: true,
group: 'inline',
get schema() { attrs: {
return { name: {},
inline: true, title: {},
group: 'inline', moji: {},
attrs: { },
name: {}, parseDOM: [
title: {}, {
moji: {}, tag: 'gl-emoji',
getAttrs: (el) => ({
name: el.dataset.name,
title: el.getAttribute('title'),
moji: el.textContent,
}),
}, },
parseDOM: [ {
{ tag: 'img.emoji',
tag: 'gl-emoji', getAttrs: (el) => {
getAttrs: (el) => ({ const name = el.getAttribute('title').replace(/^:|:$/g, '');
name: el.dataset.name,
title: el.getAttribute('title'),
moji: el.textContent,
}),
},
{
tag: 'img.emoji',
getAttrs: (el) => {
const name = el.getAttribute('title').replace(/^:|:$/g, '');
return { return {
name, name,
title: name, title: name,
moji: name, moji: name,
}; };
},
}, },
], },
toDOM: (node) => [ ],
'gl-emoji', toDOM: (node) => [
{ 'data-name': node.attrs.name, title: node.attrs.title }, 'gl-emoji',
node.attrs.moji, { 'data-name': node.attrs.name, title: node.attrs.title },
], node.attrs.moji,
}; ],
} },
toMarkdown(state, node) { toMarkdown(state, node) {
state.write(`:${node.attrs.name}:`); state.write(`:${node.attrs.name}:`);
} },
} });
/* eslint-disable class-methods-use-this */
import { HardBreak as BaseHardBreak } from 'tiptap-extensions';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class HardBreak extends BaseHardBreak { export default () => ({
name: 'hard_break',
schema: {
inline: true,
group: 'inline',
selectable: false,
parseDOM: [{ tag: 'br' }],
toDOM: () => ['br'],
},
toMarkdown(state) { toMarkdown(state) {
if (!state.atBlank()) state.write(' \n'); if (!state.atBlank()) state.write(' \n');
} },
} });
/* eslint-disable class-methods-use-this */
import { Heading as BaseHeading } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Heading extends BaseHeading { export default ({ levels = [1, 2, 3, 4, 5, 6] } = {}) => ({
name: 'heading',
schema: {
attrs: {
level: {
default: 1,
},
},
content: 'inline*',
group: 'block',
defining: true,
draggable: false,
parseDOM: levels.map((level) => ({
tag: `h${level}`,
attrs: { level },
})),
toDOM: (node) => [`h${node.attrs.level}`, 0],
},
toMarkdown(state, node) { toMarkdown(state, node) {
if (!node.childCount) return; if (!node.childCount) return;
defaultMarkdownSerializer.nodes.heading(state, node); defaultMarkdownSerializer.nodes.heading(state, node);
} },
} });
/* eslint-disable class-methods-use-this */
import { HorizontalRule as BaseHorizontalRule } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class HorizontalRule extends BaseHorizontalRule { export default () => ({
name: 'horizontal_rule',
schema: {
group: 'block',
parseDOM: [{ tag: 'hr' }],
toDOM: () => ['hr'],
},
toMarkdown(state, node) { toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.horizontal_rule(state, node); defaultMarkdownSerializer.nodes.horizontal_rule(state, node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Image as BaseImage } from 'tiptap-extensions';
import { placeholderImage } from '~/lazy_loader'; import { placeholderImage } from '~/lazy_loader';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants'; import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
export default class Image extends BaseImage { export default () => ({
get schema() { name: 'image',
return { schema: {
attrs: { attrs: {
src: {}, src: {},
alt: { alt: {
default: null, default: null,
},
title: {
default: null,
},
}, },
group: 'inline', title: {
inline: true, default: null,
draggable: true, },
parseDOM: [ },
// Matches HTML generated by Banzai::Filter::ImageLinkFilter group: 'inline',
{ inline: true,
tag: 'a.no-attachment-icon', draggable: true,
priority: HIGHER_PARSE_RULE_PRIORITY, parseDOM: [
skip: true, // Matches HTML generated by Banzai::Filter::ImageLinkFilter
}, {
// Matches HTML generated by Banzai::Filter::ImageLazyLoadFilter tag: 'a.no-attachment-icon',
{ priority: HIGHER_PARSE_RULE_PRIORITY,
tag: 'img[src]:not(.emoji)', skip: true,
getAttrs: (el) => { },
const imageSrc = el.src; // Matches HTML generated by Banzai::Filter::ImageLazyLoadFilter
const imageUrl = {
imageSrc && imageSrc !== placeholderImage ? imageSrc : el.dataset.src || ''; tag: 'img[src]:not(.emoji)',
getAttrs: (el) => {
const imageSrc = el.src;
const imageUrl =
imageSrc && imageSrc !== placeholderImage ? imageSrc : el.dataset.src || '';
return { return {
src: imageUrl, src: imageUrl,
title: el.getAttribute('title'), title: el.getAttribute('title'),
alt: el.getAttribute('alt'), alt: el.getAttribute('alt'),
}; };
},
}, },
], },
toDOM: (node) => ['img', node.attrs], ],
}; toDOM: (node) => ['img', node.attrs],
} },
toMarkdown(state, node) { toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.image(state, node); defaultMarkdownSerializer.nodes.image(state, node);
} },
} });
/* eslint-disable class-methods-use-this */
import { ListItem as BaseListItem } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class ListItem extends BaseListItem { export default () => ({
name: 'list_item',
schema: {
content: 'paragraph block*',
defining: true,
draggable: false,
parseDOM: [{ tag: 'li' }],
toDOM: () => ['li', 0],
},
toMarkdown(state, node) { toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.list_item(state, node); defaultMarkdownSerializer.nodes.list_item(state, node);
} },
} });
/* eslint-disable class-methods-use-this */
import { OrderedList as BaseOrderedList } from 'tiptap-extensions';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class OrderedList extends BaseOrderedList { export default () => ({
name: 'ordered_list',
schema: {
attrs: {
order: {
default: 1,
},
},
content: 'list_item+',
group: 'block',
parseDOM: [
{
tag: 'ol',
getAttrs: (dom) => ({
order: dom.hasAttribute('start') ? dom.getAttribute('start') + 1 : 1,
}),
},
],
toDOM: (node) => (node.attrs.order === 1 ? ['ol', 0] : ['ol', { start: node.attrs.order }, 0]),
},
toMarkdown(state, node) { toMarkdown(state, node) {
state.renderList(node, ' ', () => '1. '); state.renderList(node, ' ', () => '1. ');
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants'; import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::TaskListFilter // Transforms generated HTML back to GFM for Banzai::Filter::TaskListFilter
export default class OrderedTaskList extends Node { export default () => ({
get name() { name: 'ordered_task_list',
return 'ordered_task_list'; schema: {
} group: 'block',
content: '(task_list_item|list_item)+',
get schema() { parseDOM: [
return { {
group: 'block', priority: HIGHER_PARSE_RULE_PRIORITY,
content: '(task_list_item|list_item)+', tag: 'ol.task-list',
parseDOM: [ },
{ ],
priority: HIGHER_PARSE_RULE_PRIORITY, toDOM: () => ['ol', { class: 'task-list' }, 0],
tag: 'ol.task-list', },
},
],
toDOM: () => ['ol', { class: 'task-list' }, 0],
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
state.renderList(node, ' ', () => '1. '); state.renderList(node, ' ', () => '1. ');
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Paragraph extends Node { export default () => ({
get name() { name: 'paragraph',
return 'paragraph'; schema: {
} content: 'inline*',
group: 'block',
get schema() { parseDOM: [{ tag: 'p' }],
return { toDOM: () => ['p', 0],
content: 'inline*', },
group: 'block',
parseDOM: [{ tag: 'p' }],
toDOM: () => ['p', 0],
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.paragraph(state, node); defaultMarkdownSerializer.nodes.paragraph(state, node);
} },
} });
/* eslint-disable class-methods-use-this */
/* eslint-disable @gitlab/require-i18n-strings */
import { Node } from 'tiptap';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
/** /**
...@@ -10,62 +6,51 @@ import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer ...@@ -10,62 +6,51 @@ import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer
* the `mediaType` property in their constructors. * the `mediaType` property in their constructors.
* @abstract * @abstract
*/ */
export default class Playable extends Node { export default ({ mediaType, extraElementAttrs = {} }) => {
constructor() { const attrs = {
super(); src: {},
this.mediaType = ''; alt: {
this.extraElementAttrs = {}; default: null,
} },
};
get name() { const parseDOM = [
return this.mediaType; {
} // eslint-disable-next-line @gitlab/require-i18n-strings
tag: `.${mediaType}-container`,
get schema() { getAttrs: (el) => ({
const attrs = { src: el.querySelector(mediaType).src,
src: {}, alt: el.querySelector(mediaType).dataset.title,
alt: { }),
default: null, },
}, ];
}; const toDOM = (node) => [
'span',
const parseDOM = [ { class: `media-container ${mediaType}-container` },
[
mediaType,
{ {
tag: `.${this.mediaType}-container`, src: node.attrs.src,
getAttrs: (el) => ({ controls: true,
src: el.querySelector(this.mediaType).src, 'data-setup': '{}',
alt: el.querySelector(this.mediaType).dataset.title, 'data-title': node.attrs.alt,
}), ...extraElementAttrs,
}, },
]; ],
['a', { href: node.attrs.src }, node.attrs.alt],
const toDOM = (node) => [ ];
'span',
{ class: `media-container ${this.mediaType}-container` },
[
this.mediaType,
{
src: node.attrs.src,
controls: true,
'data-setup': '{}',
'data-title': node.attrs.alt,
...this.extraElementAttrs,
},
],
['a', { href: node.attrs.src }, node.attrs.alt],
];
return { return {
name: mediaType,
schema: {
attrs, attrs,
group: 'inline', group: 'inline',
inline: true, inline: true,
draggable: true, draggable: true,
parseDOM, parseDOM,
toDOM, toDOM,
}; },
} toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.image(state, node);
toMarkdown(state, node) { },
defaultMarkdownSerializer.nodes.image(state, node); };
} };
}
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants'; import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::ReferenceFilter and subclasses // Transforms generated HTML back to GFM for Banzai::Filter::ReferenceFilter and subclasses
export default class Reference extends Node { export default () => ({
get name() { name: 'reference',
return 'reference'; schema: {
} inline: true,
group: 'inline',
get schema() { atom: true,
return { attrs: {
inline: true, className: {},
group: 'inline', referenceType: {},
atom: true, originalText: { default: null },
attrs: { href: {},
className: {}, text: {},
referenceType: {}, },
originalText: { default: null }, parseDOM: [
href: {}, {
text: {}, tag: 'a.gfm:not([data-link=true])',
priority: HIGHER_PARSE_RULE_PRIORITY,
getAttrs: (el) => ({
className: el.className,
referenceType: el.dataset.referenceType,
originalText: el.dataset.original,
href: el.getAttribute('href'),
text: el.textContent,
}),
}, },
parseDOM: [ ],
{ toDOM: (node) => [
tag: 'a.gfm:not([data-link=true])', 'a',
priority: HIGHER_PARSE_RULE_PRIORITY, {
getAttrs: (el) => ({ class: node.attrs.className,
className: el.className, href: node.attrs.href,
referenceType: el.dataset.referenceType, 'data-reference-type': node.attrs.referenceType,
originalText: el.dataset.original, 'data-original': node.attrs.originalText,
href: el.getAttribute('href'), },
text: el.textContent, node.attrs.text,
}), ],
}, },
],
toDOM: (node) => [
'a',
{
class: node.attrs.className,
href: node.attrs.href,
'data-reference-type': node.attrs.referenceType,
'data-original': node.attrs.originalText,
},
node.attrs.text,
],
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
state.write(node.attrs.originalText || node.attrs.text); state.write(node.attrs.originalText || node.attrs.text);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Summary extends Node { export default () => ({
get name() { name: 'summary',
return 'summary'; schema: {
} content: 'text*',
marks: '',
get schema() { defining: true,
return { parseDOM: [{ tag: 'summary' }],
content: 'text*', toDOM: () => ['summary', 0],
marks: '', },
defining: true,
parseDOM: [{ tag: 'summary' }],
toDOM: () => ['summary', 0],
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
state.write('<summary>'); state.write('<summary>');
state.text(node.textContent, false); state.text(node.textContent, false);
state.write('</summary>'); state.write('</summary>');
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class Table extends Node { export default () => ({
get name() { name: 'table',
return 'table'; schema: {
} content: 'table_head table_body',
group: 'block',
get schema() { isolating: true,
return { parseDOM: [{ tag: 'table' }],
content: 'table_head table_body', toDOM: () => ['table', 0],
group: 'block', },
isolating: true,
parseDOM: [{ tag: 'table' }],
toDOM: () => ['table', 0],
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
state.renderContent(node); state.renderContent(node);
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class TableBody extends Node { export default () => ({
get name() { name: 'table_body',
return 'table_body'; schema: {
} content: 'table_row+',
parseDOM: [{ tag: 'tbody' }],
get schema() { toDOM: () => ['tbody', 0],
return { },
content: 'table_row+', toMarkdown: (state, node) => {
parseDOM: [{ tag: 'tbody' }],
toDOM: () => ['tbody', 0],
};
}
toMarkdown(state, node) {
state.flushClose(1); state.flushClose(1);
state.renderContent(node); state.renderContent(node);
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class TableCell extends Node { export default () => ({
get name() { name: 'table_cell',
return 'table_cell'; schema: {
} attrs: {
header: { default: false },
get schema() { align: { default: null },
return { },
attrs: { content: 'inline*',
header: { default: false }, isolating: true,
align: { default: null }, parseDOM: [
{
tag: 'td, th',
getAttrs: (el) => ({
header: el.tagName === 'TH',
align: el.getAttribute('align') || el.style.textAlign,
}),
}, },
content: 'inline*', ],
isolating: true, toDOM: (node) => [node.attrs.header ? 'th' : 'td', { align: node.attrs.align }, 0],
parseDOM: [ },
{ toMarkdown: (state, node) => {
tag: 'td, th',
getAttrs: (el) => ({
header: el.tagName === 'TH',
align: el.getAttribute('align') || el.style.textAlign,
}),
},
],
toDOM: (node) => [node.attrs.header ? 'th' : 'td', { align: node.attrs.align }, 0],
};
}
toMarkdown(state, node) {
state.renderInline(node); state.renderInline(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class TableHead extends Node { export default () => ({
get name() { name: 'table_head',
return 'table_head'; schema: {
} content: 'table_header_row',
parseDOM: [{ tag: 'thead' }],
get schema() { toDOM: () => ['thead', 0],
return { },
content: 'table_header_row', toMarkdown: (state, node) => {
parseDOM: [{ tag: 'thead' }],
toDOM: () => ['thead', 0],
};
}
toMarkdown(state, node) {
state.flushClose(1); state.flushClose(1);
state.renderContent(node); state.renderContent(node);
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants'; import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
import TableRow from './table_row'; import TableRow from './table_row';
const CENTER_ALIGN = 'center'; const CENTER_ALIGN = 'center';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class TableHeaderRow extends TableRow { export default () => ({
get name() { name: 'table_header_row',
return 'table_header_row'; schema: {
} content: 'table_cell+',
parseDOM: [
get schema() { {
return { tag: 'thead tr',
content: 'table_cell+', priority: HIGHER_PARSE_RULE_PRIORITY,
parseDOM: [ },
{ ],
tag: 'thead tr', toDOM: () => ['tr', 0],
priority: HIGHER_PARSE_RULE_PRIORITY, },
}, toMarkdown: (state, node) => {
], const cellWidths = TableRow().toMarkdown(state, node);
toDOM: () => ['tr', 0],
};
}
toMarkdown(state, node) {
const cellWidths = super.toMarkdown(state, node);
state.flushClose(1); state.flushClose(1);
...@@ -40,5 +32,5 @@ export default class TableHeaderRow extends TableRow { ...@@ -40,5 +32,5 @@ export default class TableHeaderRow extends TableRow {
state.write('|'); state.write('|');
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants'; import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::TableOfContentsFilter // Transforms generated HTML back to GFM for Banzai::Filter::TableOfContentsFilter
export default class TableOfContents extends Node { export default () => ({
get name() { name: 'table_of_contents',
return 'table_of_contents'; schema: {
} group: 'block',
atom: true,
get schema() { parseDOM: [
return { {
group: 'block', tag: 'ul.section-nav',
atom: true, priority: HIGHER_PARSE_RULE_PRIORITY,
parseDOM: [ },
{ {
tag: 'ul.section-nav', tag: 'p.table-of-contents',
priority: HIGHER_PARSE_RULE_PRIORITY, priority: HIGHER_PARSE_RULE_PRIORITY,
}, },
{ ],
tag: 'p.table-of-contents', toDOM: () => ['p', { class: 'table-of-contents' }, __('Table of Contents')],
priority: HIGHER_PARSE_RULE_PRIORITY, },
}, toMarkdown: (state, node) => {
],
toDOM: () => ['p', { class: 'table-of-contents' }, __('Table of Contents')],
};
}
toMarkdown(state, node) {
state.write('[[_TOC_]]'); state.write('[[_TOC_]]');
state.closeBlock(node); state.closeBlock(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter // Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
export default class TableRow extends Node { export default () => ({
get name() { name: 'table_row',
return 'table_row'; schema: {
} content: 'table_cell+',
parseDOM: [{ tag: 'tr' }],
get schema() { toDOM: () => ['tr', 0],
return { },
content: 'table_cell+', toMarkdown: (state, node) => {
parseDOM: [{ tag: 'tr' }],
toDOM: () => ['tr', 0],
};
}
toMarkdown(state, node) {
const cellWidths = []; const cellWidths = [];
state.flushClose(1); state.flushClose(1);
...@@ -34,5 +24,5 @@ export default class TableRow extends Node { ...@@ -34,5 +24,5 @@ export default class TableRow extends Node {
state.closeBlock(node); state.closeBlock(node);
return cellWidths; return cellWidths;
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants'; import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::TaskListFilter // Transforms generated HTML back to GFM for Banzai::Filter::TaskListFilter
export default class TaskList extends Node { export default () => ({
get name() { name: 'task_list',
return 'task_list'; schema: {
} group: 'block',
content: '(task_list_item|list_item)+',
get schema() { parseDOM: [
return { {
group: 'block', priority: HIGHER_PARSE_RULE_PRIORITY,
content: '(task_list_item|list_item)+', tag: 'ul.task-list',
parseDOM: [ },
{ ],
priority: HIGHER_PARSE_RULE_PRIORITY, toDOM: () => ['ul', { class: 'task-list' }, 0],
tag: 'ul.task-list', },
},
],
toDOM: () => ['ul', { class: 'task-list' }, 0],
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
state.renderList(node, ' ', () => '* '); state.renderList(node, ' ', () => '* ');
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants'; import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::TaskListFilter // Transforms generated HTML back to GFM for Banzai::Filter::TaskListFilter
export default class TaskListItem extends Node { export default () => ({
get name() { name: 'task_list_item',
return 'task_list_item'; schema: {
} attrs: {
done: {
get schema() { default: false,
return {
attrs: {
done: {
default: false,
},
}, },
defining: true, },
draggable: false, defining: true,
content: 'paragraph block*', draggable: false,
parseDOM: [ content: 'paragraph block*',
{ parseDOM: [
priority: HIGHER_PARSE_RULE_PRIORITY, {
tag: 'li.task-list-item', priority: HIGHER_PARSE_RULE_PRIORITY,
getAttrs: (el) => { tag: 'li.task-list-item',
const checkbox = el.querySelector('input[type=checkbox].task-list-item-checkbox'); getAttrs: (el) => {
return { done: checkbox && checkbox.checked }; const checkbox = el.querySelector('input[type=checkbox].task-list-item-checkbox');
}, return { done: checkbox && checkbox.checked };
}, },
],
toDOM(node) {
return [
'li',
{ class: 'task-list-item' },
[
'input',
{ type: 'checkbox', class: 'task-list-item-checkbox', checked: node.attrs.done },
],
['div', { class: 'todo-content' }, 0],
];
}, },
}; ],
} toDOM(node) {
return [
'li',
{ class: 'task-list-item' },
['input', { type: 'checkbox', class: 'task-list-item-checkbox', checked: node.attrs.done }],
['div', { class: 'todo-content' }, 0],
];
},
},
toMarkdown(state, node) { toMarkdown(state, node) {
state.write(`[${node.attrs.done ? 'x' : ' '}] `); state.write(`[${node.attrs.done ? 'x' : ' '}] `);
state.renderContent(node); state.renderContent(node);
} },
} });
/* eslint-disable class-methods-use-this */
import { Node } from 'tiptap';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
export default class Text extends Node { export default () => ({
get name() { name: 'text',
return 'text'; schema: {
} group: 'inline',
},
get schema() {
return {
group: 'inline',
};
}
toMarkdown(state, node) { toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.text(state, node); defaultMarkdownSerializer.nodes.text(state, node);
} },
} });
import Playable from './playable'; import playable from './playable';
// Transforms generated HTML back to GFM for Banzai::Filter::VideoLinkFilter // Transforms generated HTML back to GFM for Banzai::Filter::VideoLinkFilter
export default class Video extends Playable { export default () => playable({ mediaType: 'video', extraElementAttrs: { width: '400' } });
constructor() {
super();
this.mediaType = 'video';
this.extraElementAttrs = { width: '400' };
}
}
import { Schema } from 'prosemirror-model'; import { Schema } from 'prosemirror-model';
import editorExtensions from './editor_extensions'; import editorExtensions from './editor_extensions';
const nodes = editorExtensions const nodes = editorExtensions.nodes.reduce(
.filter((extension) => extension.type === 'node') (ns, { name, schema }) => ({
.reduce( ...ns,
(ns, { name, schema }) => ({ [name]: schema,
...ns, }),
[name]: schema, {},
}), );
{},
);
const marks = editorExtensions const marks = editorExtensions.marks.reduce(
.filter((extension) => extension.type === 'mark') (ms, { name, schema }) => ({
.reduce( ...ms,
(ms, { name, schema }) => ({ [name]: schema,
...ms, }),
[name]: schema, {},
}), );
{},
);
export default new Schema({ nodes, marks }); export default new Schema({ nodes, marks });
import { MarkdownSerializer } from '~/lib/prosemirror_markdown_serializer'; import { MarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
import editorExtensions from './editor_extensions'; import editorExtensions from './editor_extensions';
const nodes = editorExtensions const nodes = editorExtensions.nodes.reduce(
.filter((extension) => extension.type === 'node') (ns, { name, toMarkdown }) => ({
.reduce( ...ns,
(ns, { name, toMarkdown }) => ({ [name]: toMarkdown,
...ns, }),
[name]: toMarkdown, {},
}), );
{},
);
const marks = editorExtensions const marks = editorExtensions.marks.reduce(
.filter((extension) => extension.type === 'mark') (ms, { name, toMarkdown }) => ({
.reduce( ...ms,
(ms, { name, toMarkdown }) => ({ [name]: toMarkdown,
...ms, }),
[name]: toMarkdown, {},
}), );
{},
);
export default new MarkdownSerializer(nodes, marks); export default new MarkdownSerializer(nodes, marks);
...@@ -8096,7 +8096,7 @@ lowercase-keys@^2.0.0: ...@@ -8096,7 +8096,7 @@ lowercase-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
lowlight@^1.17.0, lowlight@^1.20.0: lowlight@^1.20.0:
version "1.20.0" version "1.20.0"
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888" resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888"
integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw== integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==
...@@ -9584,14 +9584,7 @@ prop-types@^15.7.2: ...@@ -9584,14 +9584,7 @@ prop-types@^15.7.2:
object-assign "^4.1.1" object-assign "^4.1.1"
react-is "^16.8.1" react-is "^16.8.1"
prosemirror-collab@^1.2.2: prosemirror-commands@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.2.2.tgz#8d2c0e82779cfef5d051154bd0836428bd6d9c4a"
integrity sha512-tBnHKMLgy5Qmx9MYVcLfs3pAyjtcqYYDd9kp3y+LSiQzkhMQDfZSV3NXWe4Gsly32adSef173BvObwfoSQL5MA==
dependencies:
prosemirror-state "^1.0.0"
prosemirror-commands@^1.1.4, prosemirror-commands@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.2.1.tgz#eae0cb714df695260659b78ff5d201d3a037e50d" resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.2.1.tgz#eae0cb714df695260659b78ff5d201d3a037e50d"
integrity sha512-S/IkpXfpuLFsRynC2HQ5iYROUPiZskKS1+ClcWycGJvj4HMb/mVfeEkQrixYxgTl96EAh+RZQNWPC06GZXk5tQ== integrity sha512-S/IkpXfpuLFsRynC2HQ5iYROUPiZskKS1+ClcWycGJvj4HMb/mVfeEkQrixYxgTl96EAh+RZQNWPC06GZXk5tQ==
...@@ -9600,7 +9593,7 @@ prosemirror-commands@^1.1.4, prosemirror-commands@^1.2.1: ...@@ -9600,7 +9593,7 @@ prosemirror-commands@^1.1.4, prosemirror-commands@^1.2.1:
prosemirror-state "^1.0.0" prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0" prosemirror-transform "^1.0.0"
prosemirror-dropcursor@^1.3.2, prosemirror-dropcursor@^1.4.0: prosemirror-dropcursor@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.4.0.tgz#91a859d4ee79c99b1c0ba6ee61c093b195c0d9f0" resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.4.0.tgz#91a859d4ee79c99b1c0ba6ee61c093b195c0d9f0"
integrity sha512-6+YwTjmqDwlA/Dm+5wK67ezgqgjA/MhSDgaNxKUzH97SmeuWFXyLeDRxxOPZeSo7yTxcDGUCWTEjmQZsVBuMrQ== integrity sha512-6+YwTjmqDwlA/Dm+5wK67ezgqgjA/MhSDgaNxKUzH97SmeuWFXyLeDRxxOPZeSo7yTxcDGUCWTEjmQZsVBuMrQ==
...@@ -9609,7 +9602,7 @@ prosemirror-dropcursor@^1.3.2, prosemirror-dropcursor@^1.4.0: ...@@ -9609,7 +9602,7 @@ prosemirror-dropcursor@^1.3.2, prosemirror-dropcursor@^1.4.0:
prosemirror-transform "^1.1.0" prosemirror-transform "^1.1.0"
prosemirror-view "^1.1.0" prosemirror-view "^1.1.0"
prosemirror-gapcursor@^1.1.5, prosemirror-gapcursor@^1.2.1: prosemirror-gapcursor@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.2.1.tgz#02365e1bcc1ad25d390b0fb7f0e94a7fc173ad75" resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.2.1.tgz#02365e1bcc1ad25d390b0fb7f0e94a7fc173ad75"
integrity sha512-PHa9lj27iM/g4C46gxVzsefuXVfy/LrGQH4QjMRht7VDBgw77iWYWn8ZHMWSFkwtr9jQEuxI5gccHHHwWG80nw== integrity sha512-PHa9lj27iM/g4C46gxVzsefuXVfy/LrGQH4QjMRht7VDBgw77iWYWn8ZHMWSFkwtr9jQEuxI5gccHHHwWG80nw==
...@@ -9619,7 +9612,7 @@ prosemirror-gapcursor@^1.1.5, prosemirror-gapcursor@^1.2.1: ...@@ -9619,7 +9612,7 @@ prosemirror-gapcursor@^1.1.5, prosemirror-gapcursor@^1.2.1:
prosemirror-state "^1.0.0" prosemirror-state "^1.0.0"
prosemirror-view "^1.0.0" prosemirror-view "^1.0.0"
prosemirror-history@^1.1.3, prosemirror-history@^1.2.0: prosemirror-history@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.2.0.tgz#04cc4df8d2f7b2a46651a2780de191ada6d465ea" resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.2.0.tgz#04cc4df8d2f7b2a46651a2780de191ada6d465ea"
integrity sha512-B9v9xtf4fYbKxQwIr+3wtTDNLDZcmMMmGiI3TAPShnUzvo+Rmv1GiUrsQChY1meetHl7rhML2cppF3FTs7f7UQ== integrity sha512-B9v9xtf4fYbKxQwIr+3wtTDNLDZcmMMmGiI3TAPShnUzvo+Rmv1GiUrsQChY1meetHl7rhML2cppF3FTs7f7UQ==
...@@ -9628,15 +9621,7 @@ prosemirror-history@^1.1.3, prosemirror-history@^1.2.0: ...@@ -9628,15 +9621,7 @@ prosemirror-history@^1.1.3, prosemirror-history@^1.2.0:
prosemirror-transform "^1.0.0" prosemirror-transform "^1.0.0"
rope-sequence "^1.3.0" rope-sequence "^1.3.0"
prosemirror-inputrules@^1.1.2, prosemirror-inputrules@^1.1.3: prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.5:
version "1.1.3"
resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz#93f9199ca02473259c30d7e352e4c14022d54638"
integrity sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw==
dependencies:
prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.4, prosemirror-keymap@^1.1.5:
version "1.1.5" version "1.1.5"
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.5.tgz#b5984c7d30f5c75956c853126c54e9e624c0327b" resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.5.tgz#b5984c7d30f5c75956c853126c54e9e624c0327b"
integrity sha512-8SZgPH3K+GLsHL2wKuwBD9rxhsbnVBTwpHCO4VUO5GmqUQlxd/2GtBVWTsyLq4Dp3N9nGgPd3+lZFKUDuVp+Vw== integrity sha512-8SZgPH3K+GLsHL2wKuwBD9rxhsbnVBTwpHCO4VUO5GmqUQlxd/2GtBVWTsyLq4Dp3N9nGgPd3+lZFKUDuVp+Vw==
...@@ -9652,7 +9637,7 @@ prosemirror-markdown@1.7.1: ...@@ -9652,7 +9637,7 @@ prosemirror-markdown@1.7.1:
markdown-it "^12.0.0" markdown-it "^12.0.0"
prosemirror-model "^1.0.0" prosemirror-model "^1.0.0"
prosemirror-model@^1.0.0, prosemirror-model@^1.13.1, prosemirror-model@^1.16.0, prosemirror-model@^1.16.1, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1: prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.16.1, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
version "1.16.1" version "1.16.1"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.16.1.tgz#fb388270bc9609b66298d6a7e15d0cc1d6c61253" resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.16.1.tgz#fb388270bc9609b66298d6a7e15d0cc1d6c61253"
integrity sha512-r1/w0HDU40TtkXp0DyKBnFPYwd8FSlUSJmGCGFv4DeynfeSlyQF2FD0RQbVEMOe6P3PpUSXM6LZBV7W/YNZ4mA== integrity sha512-r1/w0HDU40TtkXp0DyKBnFPYwd8FSlUSJmGCGFv4DeynfeSlyQF2FD0RQbVEMOe6P3PpUSXM6LZBV7W/YNZ4mA==
...@@ -9666,7 +9651,7 @@ prosemirror-schema-basic@^1.0.0, prosemirror-schema-basic@^1.1.2: ...@@ -9666,7 +9651,7 @@ prosemirror-schema-basic@^1.0.0, prosemirror-schema-basic@^1.1.2:
dependencies: dependencies:
prosemirror-model "^1.2.0" prosemirror-model "^1.2.0"
prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.1.4, prosemirror-schema-list@^1.1.6: prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.1.6:
version "1.1.6" version "1.1.6"
resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.1.6.tgz#c3e13fe2f74750e4a53ff88d798dc0c4ccca6707" resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.1.6.tgz#c3e13fe2f74750e4a53ff88d798dc0c4ccca6707"
integrity sha512-aFGEdaCWmJzouZ8DwedmvSsL50JpRkqhQ6tcpThwJONVVmCgI36LJHtoQ4VGZbusMavaBhXXr33zyD2IVsTlkw== integrity sha512-aFGEdaCWmJzouZ8DwedmvSsL50JpRkqhQ6tcpThwJONVVmCgI36LJHtoQ4VGZbusMavaBhXXr33zyD2IVsTlkw==
...@@ -9674,7 +9659,7 @@ prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.1.4, prosemirror-sche ...@@ -9674,7 +9659,7 @@ prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.1.4, prosemirror-sche
prosemirror-model "^1.0.0" prosemirror-model "^1.0.0"
prosemirror-transform "^1.0.0" prosemirror-transform "^1.0.0"
prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.3.3, prosemirror-state@^1.3.4: prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.3.4:
version "1.3.4" version "1.3.4"
resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.4.tgz#4c6b52628216e753fc901c6d2bfd84ce109e8952" resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.4.tgz#4c6b52628216e753fc901c6d2bfd84ce109e8952"
integrity sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA== integrity sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA==
...@@ -9702,14 +9687,14 @@ prosemirror-test-builder@^1.0.5: ...@@ -9702,14 +9687,14 @@ prosemirror-test-builder@^1.0.5:
prosemirror-schema-basic "^1.0.0" prosemirror-schema-basic "^1.0.0"
prosemirror-schema-list "^1.0.0" prosemirror-schema-list "^1.0.0"
prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.2.8, prosemirror-transform@^1.3.3: prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.3.3:
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.3.3.tgz#5f6712b0577a119cc418686fe7588b6dd9b7464d" resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.3.3.tgz#5f6712b0577a119cc418686fe7588b6dd9b7464d"
integrity sha512-9NLVXy1Sfa2G6qPqhWMkEvwQQMTw7OyTqOZbJaGQWsCeH3hH5Cw+c5eNaLM1Uu75EyKLsEZhJ93XpHJBa6RX8A== integrity sha512-9NLVXy1Sfa2G6qPqhWMkEvwQQMTw7OyTqOZbJaGQWsCeH3hH5Cw+c5eNaLM1Uu75EyKLsEZhJ93XpHJBa6RX8A==
dependencies: dependencies:
prosemirror-model "^1.0.0" prosemirror-model "^1.0.0"
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.23.6, prosemirror-view@^1.23.7: prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.23.6, prosemirror-view@^1.23.7:
version "1.23.7" version "1.23.7"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.7.tgz#f003af94445ef456e397c18cf4bb995e7072097f" resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.7.tgz#f003af94445ef456e397c18cf4bb995e7072097f"
integrity sha512-ugY+g/4UI2Ree1zzdvbyQWF2KpbFa7kxKMLHaEJcxiPaErnZiD5wZFqIgFinc7fY2v/QM3DLnJ++2I45ULRdrg== integrity sha512-ugY+g/4UI2Ree1zzdvbyQWF2KpbFa7kxKMLHaEJcxiPaErnZiD5wZFqIgFinc7fY2v/QM3DLnJ++2I45ULRdrg==
...@@ -11335,61 +11320,6 @@ tippy.js@^6.3.7: ...@@ -11335,61 +11320,6 @@ tippy.js@^6.3.7:
dependencies: dependencies:
"@popperjs/core" "^2.9.0" "@popperjs/core" "^2.9.0"
tiptap-commands@^1.17.1:
version "1.17.1"
resolved "https://registry.yarnpkg.com/tiptap-commands/-/tiptap-commands-1.17.1.tgz#a8974a26d87db57b2fd4fc56a552520c69e43a4a"
integrity sha512-CyGvMD/c6fNer5LThWGtrVMXHAqHn93ivGQpqJ58x3HNZFuoIiF9QTWXAiWbY/4QrG0ANYHKCSe9n5afickTqw==
dependencies:
prosemirror-commands "^1.1.4"
prosemirror-inputrules "^1.1.2"
prosemirror-model "^1.13.1"
prosemirror-schema-list "^1.1.4"
prosemirror-state "^1.3.3"
prosemirror-tables "^1.1.1"
tiptap-utils "^1.13.1"
tiptap-extensions@^1.35.2:
version "1.35.2"
resolved "https://registry.yarnpkg.com/tiptap-extensions/-/tiptap-extensions-1.35.2.tgz#83dd6ee703ae8c83b58c7608f97253fcc4f1a94c"
integrity sha512-TIMbHVJe0/3aVeTeCmqGbatDkfxduPYFOffNCmuKR+h6oQNzTu6rLVhRzoNqktfxIoi/b44SiDPorTjSN72dCw==
dependencies:
lowlight "^1.17.0"
prosemirror-collab "^1.2.2"
prosemirror-history "^1.1.3"
prosemirror-model "^1.13.1"
prosemirror-state "^1.3.3"
prosemirror-tables "^1.1.1"
prosemirror-transform "^1.2.8"
prosemirror-view "^1.16.5"
tiptap "^1.32.2"
tiptap-commands "^1.17.1"
tiptap-utils "^1.13.1"
tiptap-utils@^1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/tiptap-utils/-/tiptap-utils-1.13.1.tgz#f2150ded432465d66aa03a5ab333803415cddd20"
integrity sha512-RoCvMfkdu7fp9u7nsRr1OgsYU8RFjoHKHEKpx075rJ9X0t+j5Vxah9n6QzTTr4yjvcavq22WO2flFacm36zYtA==
dependencies:
prosemirror-model "^1.13.1"
prosemirror-state "^1.3.3"
prosemirror-tables "^1.1.1"
tiptap@^1.32.2:
version "1.32.2"
resolved "https://registry.yarnpkg.com/tiptap/-/tiptap-1.32.2.tgz#cd6259e853652bfc6860758ff44ebb695d5edd1c"
integrity sha512-5IwVj8nGo8y5V3jbdtoEd7xNUsi8Q0N6WV2Nfs70olqz3fldXkiImBrDhZJ4Anx8vhyP6PIBttrg0prFVmwIvw==
dependencies:
prosemirror-commands "^1.1.4"
prosemirror-dropcursor "^1.3.2"
prosemirror-gapcursor "^1.1.5"
prosemirror-inputrules "^1.1.3"
prosemirror-keymap "^1.1.4"
prosemirror-model "^1.13.1"
prosemirror-state "^1.3.3"
prosemirror-view "^1.16.5"
tiptap-commands "^1.17.1"
tiptap-utils "^1.13.1"
tmpl@1.0.x: tmpl@1.0.x:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment