From 6ebe027d75eabe25640632ced96f81431fea3182 Mon Sep 17 00:00:00 2001
From: rhenck <richard.henck@iqb.hu-berlin.de>
Date: Mon, 17 Jan 2022 17:05:20 +0100
Subject: [PATCH] [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.

---
 .../app/text-editor/extensions/bullet-list.ts | 37 ++---------
 .../text-editor/extensions/ordered-list.ts    | 43 +++++++++++++
 .../extensions/orderedList-extension.ts       | 64 -------------------
 .../text-editor/rich-text-editor.component.ts |  8 ++-
 4 files changed, 55 insertions(+), 97 deletions(-)
 create mode 100644 projects/editor/src/app/text-editor/extensions/ordered-list.ts
 delete mode 100644 projects/editor/src/app/text-editor/extensions/orderedList-extension.ts

diff --git a/projects/editor/src/app/text-editor/extensions/bullet-list.ts b/projects/editor/src/app/text-editor/extensions/bullet-list.ts
index 54cd0538c..9f817b81d 100644
--- a/projects/editor/src/app/text-editor/extensions/bullet-list.ts
+++ b/projects/editor/src/app/text-editor/extensions/bullet-list.ts
@@ -1,5 +1,3 @@
-import { Command } from '@tiptap/core';
-import { Transaction } from 'prosemirror-state';
 import { BulletList } from '@tiptap/extension-bullet-list';
 
 declare module '@tiptap/core' {
@@ -11,45 +9,24 @@ declare module '@tiptap/core' {
 }
 
 export const BulletListExtension = BulletList.extend({
-  name: 'BulletListExtension',
-
   addAttributes() {
     return {
       listStyle: {
         default: 'disc',
         parseHTML: element => element.style.listStyleType,
-        renderHTML: attributes => ({
-          style: `list-style: ${attributes.listStyle};`
-        })
+        renderHTML: attributes => {
+          return { 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 };
-        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 {
-      setBulletListStyle: (newStyle: string) => applyListStyle(newStyle)()
+      ...this.parent?.(),
+      setBulletListStyle: (newStyle: string) => ({ commands }) => {
+        return commands.updateAttributes(this.name, { listStyle: newStyle });
+      }
     };
   }
 });
diff --git a/projects/editor/src/app/text-editor/extensions/ordered-list.ts b/projects/editor/src/app/text-editor/extensions/ordered-list.ts
new file mode 100644
index 000000000..5a1d5e121
--- /dev/null
+++ b/projects/editor/src/app/text-editor/extensions/ordered-list.ts
@@ -0,0 +1,43 @@
+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 })
+      )
+    };
+  }
+});
diff --git a/projects/editor/src/app/text-editor/extensions/orderedList-extension.ts b/projects/editor/src/app/text-editor/extensions/orderedList-extension.ts
deleted file mode 100644
index a410c265d..000000000
--- a/projects/editor/src/app/text-editor/extensions/orderedList-extension.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-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)()
-    };
-  }
-});
diff --git a/projects/editor/src/app/text-editor/rich-text-editor.component.ts b/projects/editor/src/app/text-editor/rich-text-editor.component.ts
index d73e6a999..55bfbee73 100644
--- a/projects/editor/src/app/text-editor/rich-text-editor.component.ts
+++ b/projects/editor/src/app/text-editor/rich-text-editor.component.ts
@@ -19,7 +19,7 @@ import { HangingIndent } from './extensions/hanging-indent';
 import { ParagraphExtension } from './extensions/paragraph-extension';
 import { FontSize } from './extensions/font-size';
 import { BulletListExtension } from './extensions/bullet-list';
-import { OrderedListExtension } from './extensions/orderedList-extension';
+import { OrderedListExtension } from './extensions/ordered-list';
 
 import { FileService } from '../services/file.service';
 
@@ -144,7 +144,8 @@ export class RichTextEditorComponent implements AfterViewInit {
 
   toggleOrderedList(): void {
     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 {
@@ -156,7 +157,8 @@ export class RichTextEditorComponent implements AfterViewInit {
       }
     } else {
       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')) {
         this.toggleOrderedList();
       }
-- 
GitLab