]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/plugins-tasklist.js
Started initial tasklist attempt, failed implementation
[bookstack] / resources / js / wysiwyg / plugins-tasklist.js
1 /**
2  * @param {Editor} editor
3  */
4 function defineTaskListCustomElement(editor) {
5     const doc = editor.getDoc();
6     const win = doc.defaultView;
7
8     class TaskListElement extends win.HTMLElement {
9         constructor() {
10             super();
11             // this.attachShadow({mode: 'open'});
12             //
13             // const input = doc.createElement('input');
14             // input.setAttribute('type', 'checkbox');
15             // input.setAttribute('disabled', 'disabled');
16             //
17             // if (this.hasAttribute('selected')) {
18             //     input.setAttribute('selected', 'selected');
19             // }
20             //
21             // this.shadowRoot.append(input);
22             // this.shadowRoot.close();
23         }
24     }
25
26     win.customElements.define('task-list-item', TaskListElement);
27 }
28
29 /**
30  * @param {Editor} editor
31  * @param {String} url
32  */
33 function register(editor, url) {
34
35     // editor.on('NewBlock', ({ newBlock}) => {
36     //     ensureElementHasCheckbox(newBlock);
37     // });
38
39     editor.on('PreInit', () => {
40
41         defineTaskListCustomElement(editor);
42
43         editor.parser.addNodeFilter('li', function(elms) {
44             for (const elem of elms) {
45                 if (elem.attributes.map.class === 'task-list-item') {
46                     replaceTaskListNode(elem);
47                 }
48             }
49         });
50
51         // editor.serializer.addNodeFilter('li', function(elms) {
52         //     for (const elem of elms) {
53         //         if (elem.attributes.map.class === 'task-list-item') {
54         //             ensureNodeHasCheckbox(elem);
55         //         }
56         //     }
57         // });
58
59     });
60
61 }
62
63 /**
64  * @param {AstNode} node
65  */
66 function replaceTaskListNode(node) {
67
68     const taskListItem = new tinymce.html.Node.create('task-list-item', {
69     });
70
71     for (const child of node.children()) {
72         if (node.name !== 'input') {
73             taskListItem.append(child);
74         }
75     }
76
77     node.replace(taskListItem);
78 }
79
80 // /**
81 //  * @param {Element} elem
82 //  */
83 // function ensureElementHasCheckbox(elem) {
84 //     const hasCheckbox = elem.querySelector(':scope > input[type="checkbox"]') !== null;
85 //     if (hasCheckbox) {
86 //         return;
87 //     }
88 //
89 //     const input = elem.ownerDocument.createElement('input');
90 //     input.setAttribute('type', 'checkbox');
91 //     input.setAttribute('disabled', 'disabled');
92 //     elem.prepend(input);
93 // }
94
95 /**
96  * @param {AstNode} elem
97  */
98 function ensureNodeHasCheckbox(elem) {
99     // Stop if there's already an input
100     if (elem.firstChild && elem.firstChild.name === 'input') {
101         return;
102     }
103
104     const input = new tinymce.html.Node.create('input', {
105         type: 'checkbox',
106         disabled: 'disabled',
107     });
108
109     if (elem.firstChild) {
110         elem.insert(input, elem.firstChild, true);
111     } else {
112         elem.append(input);
113     }
114 }
115
116
117 /**
118  * @param {WysiwygConfigOptions} options
119  * @return {register}
120  */
121 export function getPlugin(options) {
122     return register;
123 }