mirror of
				https://github.com/BookStackApp/BookStack.git
				synced 2025-11-03 02:13:16 +03:00 
			
		
		
		
	Started initial tasklist attempt, failed implementation
This commit is contained in:
		@@ -10,6 +10,7 @@ import {getPlugin as getCustomhrPlugin} from "./plugins-customhr";
 | 
				
			|||||||
import {getPlugin as getImagemanagerPlugin} from "./plugins-imagemanager";
 | 
					import {getPlugin as getImagemanagerPlugin} from "./plugins-imagemanager";
 | 
				
			||||||
import {getPlugin as getAboutPlugin} from "./plugins-about";
 | 
					import {getPlugin as getAboutPlugin} from "./plugins-about";
 | 
				
			||||||
import {getPlugin as getDetailsPlugin} from "./plugins-details";
 | 
					import {getPlugin as getDetailsPlugin} from "./plugins-details";
 | 
				
			||||||
 | 
					import {getPlugin as getTasklistPlugin} from "./plugins-tasklist";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const style_formats = [
 | 
					const style_formats = [
 | 
				
			||||||
    {title: "Large Header", format: "h2", preview: 'color: blue;'},
 | 
					    {title: "Large Header", format: "h2", preview: 'color: blue;'},
 | 
				
			||||||
@@ -81,6 +82,7 @@ function gatherPlugins(options) {
 | 
				
			|||||||
        "imagemanager",
 | 
					        "imagemanager",
 | 
				
			||||||
        "about",
 | 
					        "about",
 | 
				
			||||||
        "details",
 | 
					        "details",
 | 
				
			||||||
 | 
					        "tasklist",
 | 
				
			||||||
        options.textDirection === 'rtl' ? 'directionality' : '',
 | 
					        options.textDirection === 'rtl' ? 'directionality' : '',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -89,6 +91,7 @@ function gatherPlugins(options) {
 | 
				
			|||||||
    window.tinymce.PluginManager.add('imagemanager', getImagemanagerPlugin(options));
 | 
					    window.tinymce.PluginManager.add('imagemanager', getImagemanagerPlugin(options));
 | 
				
			||||||
    window.tinymce.PluginManager.add('about', getAboutPlugin(options));
 | 
					    window.tinymce.PluginManager.add('about', getAboutPlugin(options));
 | 
				
			||||||
    window.tinymce.PluginManager.add('details', getDetailsPlugin(options));
 | 
					    window.tinymce.PluginManager.add('details', getDetailsPlugin(options));
 | 
				
			||||||
 | 
					    window.tinymce.PluginManager.add('tasklist', getTasklistPlugin(options));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (options.drawioUrl) {
 | 
					    if (options.drawioUrl) {
 | 
				
			||||||
        window.tinymce.PluginManager.add('drawio', getDrawioPlugin(options));
 | 
					        window.tinymce.PluginManager.add('drawio', getDrawioPlugin(options));
 | 
				
			||||||
@@ -204,7 +207,7 @@ export function build(options) {
 | 
				
			|||||||
        statusbar: false,
 | 
					        statusbar: false,
 | 
				
			||||||
        menubar: false,
 | 
					        menubar: false,
 | 
				
			||||||
        paste_data_images: false,
 | 
					        paste_data_images: false,
 | 
				
			||||||
        extended_valid_elements: 'pre[*],svg[*],div[drawio-diagram],details[*],summary[*],div[*]',
 | 
					        extended_valid_elements: 'pre[*],svg[*],div[drawio-diagram],details[*],summary[*],div[*],li[class]',
 | 
				
			||||||
        automatic_uploads: false,
 | 
					        automatic_uploads: false,
 | 
				
			||||||
        custom_elements: 'doc-root,code-block',
 | 
					        custom_elements: 'doc-root,code-block',
 | 
				
			||||||
        valid_children: [
 | 
					        valid_children: [
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										123
									
								
								resources/js/wysiwyg/plugins-tasklist.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								resources/js/wysiwyg/plugins-tasklist.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {Editor} editor
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function defineTaskListCustomElement(editor) {
 | 
				
			||||||
 | 
					    const doc = editor.getDoc();
 | 
				
			||||||
 | 
					    const win = doc.defaultView;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class TaskListElement extends win.HTMLElement {
 | 
				
			||||||
 | 
					        constructor() {
 | 
				
			||||||
 | 
					            super();
 | 
				
			||||||
 | 
					            // this.attachShadow({mode: 'open'});
 | 
				
			||||||
 | 
					            //
 | 
				
			||||||
 | 
					            // const input = doc.createElement('input');
 | 
				
			||||||
 | 
					            // input.setAttribute('type', 'checkbox');
 | 
				
			||||||
 | 
					            // input.setAttribute('disabled', 'disabled');
 | 
				
			||||||
 | 
					            //
 | 
				
			||||||
 | 
					            // if (this.hasAttribute('selected')) {
 | 
				
			||||||
 | 
					            //     input.setAttribute('selected', 'selected');
 | 
				
			||||||
 | 
					            // }
 | 
				
			||||||
 | 
					            //
 | 
				
			||||||
 | 
					            // this.shadowRoot.append(input);
 | 
				
			||||||
 | 
					            // this.shadowRoot.close();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    win.customElements.define('task-list-item', TaskListElement);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {Editor} editor
 | 
				
			||||||
 | 
					 * @param {String} url
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function register(editor, url) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // editor.on('NewBlock', ({ newBlock}) => {
 | 
				
			||||||
 | 
					    //     ensureElementHasCheckbox(newBlock);
 | 
				
			||||||
 | 
					    // });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    editor.on('PreInit', () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        defineTaskListCustomElement(editor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        editor.parser.addNodeFilter('li', function(elms) {
 | 
				
			||||||
 | 
					            for (const elem of elms) {
 | 
				
			||||||
 | 
					                if (elem.attributes.map.class === 'task-list-item') {
 | 
				
			||||||
 | 
					                    replaceTaskListNode(elem);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // editor.serializer.addNodeFilter('li', function(elms) {
 | 
				
			||||||
 | 
					        //     for (const elem of elms) {
 | 
				
			||||||
 | 
					        //         if (elem.attributes.map.class === 'task-list-item') {
 | 
				
			||||||
 | 
					        //             ensureNodeHasCheckbox(elem);
 | 
				
			||||||
 | 
					        //         }
 | 
				
			||||||
 | 
					        //     }
 | 
				
			||||||
 | 
					        // });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {AstNode} node
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function replaceTaskListNode(node) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const taskListItem = new tinymce.html.Node.create('task-list-item', {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (const child of node.children()) {
 | 
				
			||||||
 | 
					        if (node.name !== 'input') {
 | 
				
			||||||
 | 
					            taskListItem.append(child);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    node.replace(taskListItem);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// /**
 | 
				
			||||||
 | 
					//  * @param {Element} elem
 | 
				
			||||||
 | 
					//  */
 | 
				
			||||||
 | 
					// function ensureElementHasCheckbox(elem) {
 | 
				
			||||||
 | 
					//     const hasCheckbox = elem.querySelector(':scope > input[type="checkbox"]') !== null;
 | 
				
			||||||
 | 
					//     if (hasCheckbox) {
 | 
				
			||||||
 | 
					//         return;
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     const input = elem.ownerDocument.createElement('input');
 | 
				
			||||||
 | 
					//     input.setAttribute('type', 'checkbox');
 | 
				
			||||||
 | 
					//     input.setAttribute('disabled', 'disabled');
 | 
				
			||||||
 | 
					//     elem.prepend(input);
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {AstNode} elem
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function ensureNodeHasCheckbox(elem) {
 | 
				
			||||||
 | 
					    // Stop if there's already an input
 | 
				
			||||||
 | 
					    if (elem.firstChild && elem.firstChild.name === 'input') {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const input = new tinymce.html.Node.create('input', {
 | 
				
			||||||
 | 
					        type: 'checkbox',
 | 
				
			||||||
 | 
					        disabled: 'disabled',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (elem.firstChild) {
 | 
				
			||||||
 | 
					        elem.insert(input, elem.firstChild, true);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        elem.append(input);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {WysiwygConfigOptions} options
 | 
				
			||||||
 | 
					 * @return {register}
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function getPlugin(options) {
 | 
				
			||||||
 | 
					    return register;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -310,6 +310,7 @@ li > ol, li > ul {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
li.checkbox-item, li.task-list-item {
 | 
					li.checkbox-item, li.task-list-item {
 | 
				
			||||||
 | 
					  display: list-item;
 | 
				
			||||||
  list-style: none;
 | 
					  list-style: none;
 | 
				
			||||||
  margin-left: -($-m * 1.2);
 | 
					  margin-left: -($-m * 1.2);
 | 
				
			||||||
  input[type="checkbox"] {
 | 
					  input[type="checkbox"] {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user