Skip to content
Snippets Groups Projects
Commit 040ca536 authored by rhenck's avatar rhenck
Browse files

[editor] TextEditor: Add extensions for list styles

Before it was done with a dysfunctional hack. Now with proper extensions 
to existing (tiptap-node-)extensions.
Also reads existing style and sets select-element accordingly.
parent df2d8bb1
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';
declare module '@tiptap/core' {
interface Commands<ReturnType> {
bulletListExtension: {
setBulletListStyle: (newStyle: string) => ReturnType;
};
}
}
export const bulletListExtension = BulletList.extend({
addAttributes() {
return {
listStyle: {
default: 'disc',
parseHTML: element => element.style.listStyleType,
renderHTML: attributes => ({
style: `list-style: ${attributes.listStyle};`
})
}
};
},
addCommands() {
const setNodeIndentMarkup = (tr: Transaction, pos: number, newStyle: string): Transaction => {
const node = tr?.doc?.nodeAt(pos);
if (node) {
const nodeAttrs = { ...node.attrs, listStyle: newStyle };
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 {
setBulletListStyle: (newStyle: string) => applyListStyle(newStyle)()
};
}
});
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) => ReturnType;
};
}
}
export const orderedListExtension = OrderedList.extend({
addAttributes() {
return {
listStyle: {
default: 'decimal',
parseHTML: element => {
return element.style.listStyleType;
},
renderHTML: attributes => ({
style: `list-style: ${attributes.listStyle};`
})
}
};
},
addCommands() {
const setNodeIndentMarkup = (tr: Transaction, pos: number, newStyle: string): Transaction => {
const node = tr?.doc?.nodeAt(pos);
if (node) {
const nodeAttrs = { ...node.attrs, listStyle: newStyle };
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 {
setOrderedListStyle: (newStyle: string) => applyListStyle(newStyle)()
};
}
});
......@@ -160,7 +160,8 @@
<mat-menu #optionsMenu="matMenu">
<mat-form-field>
<mat-label>Aufzählungszeichen</mat-label>
<mat-select [value]="'disc'" (click)="$any($event).stopPropagation()"
<mat-select [value]="editor.getAttributes('bulletList').listStyle"
(click)="$any($event).stopPropagation()"
(valueChange)="applyListStyle('bulletList', $event)">
<mat-option value="disc">disc</mat-option>
<mat-option value="circle">circle</mat-option>
......@@ -169,7 +170,8 @@
</mat-form-field>
<mat-form-field>
<mat-label>Aufzählungsnummerierung</mat-label>
<mat-select [value]="'decimal'" (click)="$any($event).stopPropagation()"
<mat-select [value]="editor.getAttributes('orderedList').listStyle"
(click)="$any($event).stopPropagation()"
(valueChange)="applyListStyle('orderedList', $event)">
<mat-option value="decimal">decimal</mat-option>
<mat-option value="lower-latin">lower-latin</mat-option>
......
......@@ -2,7 +2,7 @@ import {
Component, EventEmitter, Input, Output, ViewEncapsulation,
AfterViewInit
} from '@angular/core';
import { Editor, Extension } from '@tiptap/core';
import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';
import { Underline } from '@tiptap/extension-underline';
import { Superscript } from '@tiptap/extension-superscript';
......@@ -15,6 +15,8 @@ import { Heading } from '@tiptap/extension-heading';
import { Indent } from './indent';
import { customParagraph } from './paragraph-extension';
import { fontSizeExtension } from './font-size-extension';
import { bulletListExtension } from './bulletList-extension';
import { orderedListExtension } from './orderedList-extension';
@Component({
selector: 'app-rich-text-editor',
......@@ -45,7 +47,9 @@ export class RichTextEditorComponent implements AfterViewInit {
levels: [1, 2, 3, 4]
}),
customParagraph,
fontSizeExtension
fontSizeExtension,
bulletListExtension,
orderedListExtension
]
});
......@@ -110,11 +114,11 @@ export class RichTextEditorComponent implements AfterViewInit {
}
applyListStyle(listType: string, style: string): void {
(this.editor.extensionManager.extensions
.filter(ext => ext.name === listType)[0] as Extension).options.HTMLAttributes =
{
style: `list-style-type:${style}`
};
if (listType === 'bulletList') {
this.editor.commands.setBulletListStyle(style);
} else {
this.editor.commands.setOrderedListStyle(style);
}
}
toggleHeading(level?: string): void {
......
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