Skip to content
Snippets Groups Projects
Commit 6ebe027d authored by rhenck's avatar rhenck
Browse files

[editor] Fix and rework TextEditor list extensions

Was not working at all before. Now the logic is much simpler with the 
use of tiptap attributes.
parent 5f69cce6
No related branches found
No related tags found
No related merge requests found
import { Command } from '@tiptap/core';
import { Transaction } from 'prosemirror-state';
import { BulletList } from '@tiptap/extension-bullet-list'; import { BulletList } from '@tiptap/extension-bullet-list';
declare module '@tiptap/core' { declare module '@tiptap/core' {
...@@ -11,45 +9,24 @@ declare module '@tiptap/core' { ...@@ -11,45 +9,24 @@ declare module '@tiptap/core' {
} }
export const BulletListExtension = BulletList.extend({ export const BulletListExtension = BulletList.extend({
name: 'BulletListExtension',
addAttributes() { addAttributes() {
return { return {
listStyle: { listStyle: {
default: 'disc', default: 'disc',
parseHTML: element => element.style.listStyleType, parseHTML: element => element.style.listStyleType,
renderHTML: attributes => ({ renderHTML: attributes => {
style: `list-style: ${attributes.listStyle};` return { style: `list-style: ${attributes.listStyle};` };
}) }
} }
}; };
}, },
addCommands() { addCommands() {
const setNodeIndentMarkup = (tr: Transaction, pos: number, newStyle: string): Transaction => {
const node = tr?.doc?.nodeAt(pos);
if (node) {
const nodeAttrs = { ...node.attrs, listStyle: newStyle };
if (node.type.name !== 'text') {
return tr.setNodeMarkup(pos, node.type, nodeAttrs, node.marks);
}
}
return tr;
};
const applyListStyle: (newStyle: string) => () => Command =
newStyle => () => ({ tr, state, dispatch }) => {
const { selection } = state;
let transaction;
tr.doc.nodesBetween(selection.from, selection.to, (node, pos) => {
transaction = setNodeIndentMarkup(tr, pos, newStyle);
});
dispatch?.(transaction);
return true;
};
return { return {
setBulletListStyle: (newStyle: string) => applyListStyle(newStyle)() ...this.parent?.(),
setBulletListStyle: (newStyle: string) => ({ commands }) => {
return commands.updateAttributes(this.name, { listStyle: newStyle });
}
}; };
} }
}); });
import { OrderedList } from '@tiptap/extension-ordered-list';
declare module '@tiptap/core' {
interface Commands<ReturnType> {
orderedListExtension: {
setOrderedListStyle: (newStyle: string) => ReturnType,
setOrderedListFontSize: (fontSize: string) => ReturnType
};
}
}
export const OrderedListExtension = OrderedList.extend({
addAttributes() {
return {
listStyle: {
default: 'upper-roman',
parseHTML: element => element.style.listStyleType,
renderHTML: attributes => {
return { style: `list-style: ${attributes.listStyle}` };
}
},
fontSize: {
default: '20px',
parseHTML: element => element.style.fontSize,
renderHTML: attributes => {
return { style: `font-size: ${attributes.fontSize}` };
}
}
};
},
addCommands() {
return {
...this.parent?.(),
setOrderedListStyle: (newStyle: string) => ({ commands }) => (
commands.updateAttributes(this.name, { listStyle: newStyle })
),
setOrderedListFontSize: (fontSize: string) => ({ commands }) => (
commands.updateAttributes(this.name, { fontSize: fontSize })
)
};
}
});
import { Command } from '@tiptap/core';
import { Transaction } from 'prosemirror-state';
import { OrderedList } from '@tiptap/extension-ordered-list';
declare module '@tiptap/core' {
interface Commands<ReturnType> {
orderedListExtension: {
setOrderedListStyle: (newStyle: string, fontSize: string) => ReturnType
};
}
}
export const OrderedListExtension = OrderedList.extend({
name: 'OrderedListExtension',
addAttributes() {
return {
listStyle: {
default: 'decimal',
parseHTML: element => element.style.listStyleType,
renderHTML: attributes => ({
style: `list-style: ${attributes.listStyle}`
})
},
fontSize: {
default: '20px',
parseHTML: element => element.style.fontSize,
renderHTML: attributes => ({
style: `font-size: ${attributes.fontSize}`
})
}
};
},
addCommands() {
const setNodeIndentMarkup = (tr: Transaction, pos: number, newStyle: string, fontSize: string): Transaction => {
const node = tr?.doc?.nodeAt(pos);
if (node) {
const nodeAttrs = { ...node.attrs, listStyle: newStyle, fontSize: fontSize };
if (node.type.name !== 'text') {
return tr.setNodeMarkup(pos, node.type, nodeAttrs, node.marks);
}
}
return tr;
};
const applyListStyle: (newStyle: string, fontSize: string) => () => Command =
(newStyle, fontSize) => () => (
{ tr, state, dispatch }
) => {
const { selection } = state;
let transaction;
tr.doc.nodesBetween(selection.from, selection.to, (node, pos) => {
transaction = setNodeIndentMarkup(tr, pos, newStyle, fontSize);
});
dispatch?.(transaction);
return true;
};
return {
setOrderedListStyle: (newStyle: string, fontSize: string) => applyListStyle(newStyle, fontSize)()
};
}
});
...@@ -19,7 +19,7 @@ import { HangingIndent } from './extensions/hanging-indent'; ...@@ -19,7 +19,7 @@ import { HangingIndent } from './extensions/hanging-indent';
import { ParagraphExtension } from './extensions/paragraph-extension'; import { ParagraphExtension } from './extensions/paragraph-extension';
import { FontSize } from './extensions/font-size'; import { FontSize } from './extensions/font-size';
import { BulletListExtension } from './extensions/bullet-list'; import { BulletListExtension } from './extensions/bullet-list';
import { OrderedListExtension } from './extensions/orderedList-extension'; import { OrderedListExtension } from './extensions/ordered-list';
import { FileService } from '../services/file.service'; import { FileService } from '../services/file.service';
...@@ -144,7 +144,8 @@ export class RichTextEditorComponent implements AfterViewInit { ...@@ -144,7 +144,8 @@ export class RichTextEditorComponent implements AfterViewInit {
toggleOrderedList(): void { toggleOrderedList(): void {
this.editor.chain().toggleOrderedList().focus().run(); this.editor.chain().toggleOrderedList().focus().run();
this.editor.commands.setOrderedListStyle(this.orderedListStyle, this.selectedFontSize); this.editor.commands.setOrderedListStyle(this.orderedListStyle);
this.editor.commands.setOrderedListFontSize(this.selectedFontSize);
} }
applyListStyle(listType: string, style: string): void { applyListStyle(listType: string, style: string): void {
...@@ -156,7 +157,8 @@ export class RichTextEditorComponent implements AfterViewInit { ...@@ -156,7 +157,8 @@ export class RichTextEditorComponent implements AfterViewInit {
} }
} else { } else {
this.orderedListStyle = style; this.orderedListStyle = style;
this.editor.commands.setOrderedListStyle(style, this.selectedFontSize); this.editor.commands.setOrderedListStyle(style);
this.editor.commands.setOrderedListFontSize(this.selectedFontSize);
if (!this.editor.isActive('orderedList')) { if (!this.editor.isActive('orderedList')) {
this.toggleOrderedList(); this.toggleOrderedList();
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment