Skip to content

Commit

Permalink
feat: restrict blockquote marks on transaction instead of schema
Browse files Browse the repository at this point in the history
  • Loading branch information
robertu7 committed Jun 8, 2024
1 parent 9d455d8 commit c21a021
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 191 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@matters/matters-editor",
"version": "0.2.5-alpha.2",
"version": "0.2.5-alpha.3",
"description": "Editor for matters.news",
"author": "https://github.com/thematters",
"homepage": "https://github.com/thematters/matters-editor",
Expand Down
113 changes: 113 additions & 0 deletions src/editors/extensions/blockquote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'
import { Plugin, PluginKey } from '@tiptap/pm/state'

export interface BlockquoteOptions {
/**
* HTML attributes to add to the blockquote element
* @default {}
* @example { class: 'foo' }
*/
HTMLAttributes: Record<string, any>
}

declare module '@tiptap/core' {
interface Commands<ReturnType> {
blockquote: {
setBlockquote: () => ReturnType
}
}
}

/**
* Matches a blockquote to a `>` as input.
*/
export const inputRegex = /^\s*>\s$/

/**
* This extension allows you to create blockquotes,
* contains only plain text paragraph and soft break (<br>).
*
* Forked from:
* @see https://tiptap.dev/api/nodes/blockquote
*/
export const Blockquote = Node.create<BlockquoteOptions>({
name: 'blockquote',

addOptions() {
return {
HTMLAttributes: {},
}
},

group: 'block',

content: 'paragraph+',

defining: true,

parseHTML() {
return [{ tag: 'blockquote' }]
},

renderHTML({ HTMLAttributes }) {
return [
'blockquote',
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
0,
]
},

addCommands() {
return {
setBlockquote:
() =>
({ chain }) => {
return chain().wrapIn(this.name).run()
},
}
},

addKeyboardShortcuts() {
return {
'Mod-Shift-b': () => this.editor.commands.setBlockquote(),
}
},

addInputRules() {
return [
wrappingInputRule({
find: inputRegex,
type: this.type,
}),
]
},

addProseMirrorPlugins() {
return [
new Plugin({
key: new PluginKey('restrictBlockquoteMarks'),
filterTransaction: (transaction, state) => {
// Nothing has changed, ignore it.
if (!transaction.docChanged) {
return true
}

// Skip if not in a blockquote
const $anchor = transaction.selection.$anchor
const $grandParent = $anchor.node($anchor.depth - 1)
const isInBlockquote = $grandParent.type.name === this.name
if (!isInBlockquote) {
return true
}

// Prevent adding marks (except <br>) to blockquote
const $start = $anchor.start($anchor.depth - 1)
const $end = $anchor.end($anchor.depth - 1)
transaction.removeMark($start, $end)

return true
},
}),
]
},
})
6 changes: 2 additions & 4 deletions src/editors/extensions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ import Placeholder from '@tiptap/extension-placeholder'
import Strike from '@tiptap/extension-strike'
import Text from '@tiptap/extension-text'

import { Blockquote } from './blockquote'
import { Bold } from './bold'
import { FigureAudio } from './figureAudio'
import { FigureEmbed } from './figureEmbed'
import { FigureImage } from './figureImage'
import { HorizontalRule } from './horizontalRule'
import { Link } from './link'
import { Mention, type MentionSuggestion } from './mention'
import { PlainBlockquote } from './plainBlockquote'
import { PlainParagraph } from './plainParagraph'

export * from './bold'
export * from './figureAudio'
Expand All @@ -47,8 +46,7 @@ const baseExtensions = (placeholder?: string) => [
}),
// Custom Formats
Link,
PlainParagraph,
PlainBlockquote,
Blockquote,
]

const baseArticleExtensions = (placeholder?: string) => [
Expand Down
83 changes: 0 additions & 83 deletions src/editors/extensions/plainBlockquote.ts

This file was deleted.

69 changes: 0 additions & 69 deletions src/editors/extensions/plainParagraph.ts

This file was deleted.

36 changes: 18 additions & 18 deletions src/transformers/normalize-sanitize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@ describe('Sanitize and normalize article', () => {
expectProcessArticleHTML(
stripIndent`
<blockquote>
<p class="plain">1</p>
<p class="plain">2</p>
<p class="plain"></p>
<p class="plain">3</p>
<p>1</p>
<p>2</p>
<p></p>
<p>3</p>
</blockquote>
`,
stripIndent`
<blockquote>
<p class="plain">1</p>
<p class="plain">2</p>
<p class="plain"><br class="smart"></p>
<p class="plain">3</p>
<p>1</p>
<p>2</p>
<p><br class="smart"></p>
<p>3</p>
</blockquote>
`,
{ maxHardBreaks: 1 },
Expand Down Expand Up @@ -252,20 +252,20 @@ describe('Sanitize and normalize comment', () => {
expectProcessCommentHTML(
stripIndent`
<blockquote>
<p class="plain">1</p>
<p class="plain">2</p>
<p class="plain">1<br>2</p>
<p class="plain">1<br><br>2</p>
<p class="plain">1<br><br></p>
<p>1</p>
<p>2</p>
<p>1<br>2</p>
<p>1<br><br>2</p>
<p>1<br><br></p>
</blockquote>
`,
stripIndent`
<blockquote>
<p class="plain">1</p>
<p class="plain">2</p>
<p class="plain">12</p>
<p class="plain">12</p>
<p class="plain">1</p>
<p>1</p>
<p>2</p>
<p>12</p>
<p>12</p>
<p>1</p>
</blockquote>
`,
{ maxHardBreaks: 0, maxSoftBreaks: 0 },
Expand Down
20 changes: 10 additions & 10 deletions src/transformers/normalize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,25 +291,25 @@ describe('Normalization: Comment', () => {
expectNormalizeCommentHTML(
stripIndent`
<blockquote>
<p class="plain">hello,<br>world</p>
<p class="plain">how are you today</p>
<p class="plain"><strong>strong</strong></p>
<p>normal paragraph</p>
<h2>heading</h2>hello,world
<p>1</p>
<p>2</p>
<p>3</p>
</blockquote>
`,
'<blockquote><p class="plain">hello,<br class="smart">world</p><p class="plain">how are you today</p><p class="plain">strong</p><p class="plain">normal paragraph</p><p class="plain">heading</p><p class="plain">hello,world</p></blockquote>',
'<blockquote><p>1</p><p>2</p><p>3</p></blockquote>',
)

expectNormalizeCommentHTML(
stripIndent`
<blockquote>
<p>1</p>
<p>2</p>
<p>3</p>
<p>hello,<br>world</p>
<p>how are you today</p>
<p><strong>strong</strong></p>
<p>normal paragraph</p>
<h2>heading</h2>hello,world
</blockquote>
`,
'<blockquote><p class="plain">1 2 3</p></blockquote>',
'<blockquote><p>hello,<br class="smart">world</p><p>how are you today</p><p>strong</p><p>normal paragraph</p><p>heading</p><p>hello,world</p></blockquote>',
)
})

Expand Down
Loading

0 comments on commit c21a021

Please sign in to comment.