-
Notifications
You must be signed in to change notification settings - Fork 0
/
text-class.js
86 lines (76 loc) · 2.25 KB
/
text-class.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/**
* This extension is originally from the community
* https://github.com/ueberdosis/tiptap/issues/1151#issuecomment-1046030306
*/
import {
Mark,
getMarkAttributes,
mergeAttributes
} from '@tiptap/core';
export const TextClass = Mark.create({
name: 'textClass',
addAttributes() {
return {
class: {
default: null,
parseHTML: (element) => element.getAttribute('class'),
renderHTML: (attributes) => {
if (!attributes.class) {
return {};
}
return {
class: attributes.class,
};
},
},
};
},
parseHTML() {
return [
{
tag: 'span',
},
];
},
renderHTML({ HTMLAttributes }) {
/**
* Temporary solution to automatically adding dir="rtl"
* for tags which contains text-arabic class
*
* Ref: https://github.com/amirhhashemi/tiptap-text-direction/issues/12
*/
const textArabicExists = HTMLAttributes?.class?.includes('text-arabic')
return ['span', mergeAttributes(HTMLAttributes, { ...(textArabicExists && {dir: 'rtl'}) }), 0];
},
addCommands() {
return {
removeEmptyTextClass: () => ({ state, commands }) => {
const attributes = getMarkAttributes(state, this.type)
const hasClasses = Object.entries(attributes).some(([, value]) => !!value)
if (hasClasses) {
return true
}
return commands.unsetMark(this.name)
},
setTextClass: (className) => ({ commands }) => {
return commands.setMark(this.name, { class: className })
},
toggleTextClass: (className) => ({ editor, chain }) => {
let textClasses = editor.getAttributes('textClass').class?.split(' ') ?? []
if ((textClasses).includes(className)) {
textClasses = textClasses.filter(cls => cls !== className)
} else {
textClasses.push(className)
}
if (textClasses.length) {
return chain().setMark(this.name, { class: textClasses.join(' ') }).run()
} else {
return chain().setMark(this.name, { class: '' })
.removeEmptyTextClass()
.run()
}
},
unsetTextClass: () => ({ commands }) => commands.unsetMark(this.name),
};
},
});