Changed to a psuedo-style approach for tasklist in wysiwyg

This commit is contained in:
Dan Brown 2022-03-19 17:12:56 +00:00
parent f991948c49
commit 65dd7ad1e9
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
3 changed files with 58 additions and 85 deletions

View File

@ -207,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[*],li[class]', extended_valid_elements: 'pre[*],svg[*],div[drawio-diagram],details[*],summary[*],div[*],li[class|checked]',
automatic_uploads: false, automatic_uploads: false,
custom_elements: 'doc-root,code-block', custom_elements: 'doc-root,code-block',
valid_children: [ valid_children: [

View File

@ -1,60 +1,27 @@
/**
* @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 {Editor} editor
* @param {String} url * @param {String} url
*/ */
function register(editor, url) {
// editor.on('NewBlock', ({ newBlock}) => { function register(editor, url) {
// ensureElementHasCheckbox(newBlock);
// });
editor.on('PreInit', () => { editor.on('PreInit', () => {
defineTaskListCustomElement(editor); editor.parser.addNodeFilter('li', function(nodes) {
for (const node of nodes) {
editor.parser.addNodeFilter('li', function(elms) { if (node.attributes.map.class === 'task-list-item') {
for (const elem of elms) { parseTaskListNode(node);
if (elem.attributes.map.class === 'task-list-item') {
replaceTaskListNode(elem);
} }
} }
}); });
// editor.serializer.addNodeFilter('li', function(elms) { editor.serializer.addNodeFilter('li', function(nodes) {
// for (const elem of elms) { for (const node of nodes) {
// if (elem.attributes.map.class === 'task-list-item') { if (node.attributes.map.class === 'task-list-item') {
// ensureNodeHasCheckbox(elem); serializeTaskListNode(node);
// } }
// } }
// }); });
}); });
@ -63,57 +30,38 @@ function register(editor, url) {
/** /**
* @param {AstNode} node * @param {AstNode} node
*/ */
function replaceTaskListNode(node) { function parseTaskListNode(node) {
// Force task list item class
const taskListItem = new tinymce.html.Node.create('task-list-item', { node.attr('class', 'task-list-item');
});
// Copy checkbox status and remove checkbox within editor
for (const child of node.children()) { for (const child of node.children()) {
if (node.name !== 'input') { if (child.name === 'input') {
taskListItem.append(child); if (child.attr('checked') === 'checked') {
node.attr('checked', 'checked');
}
child.remove();
} }
} }
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 * @param {AstNode} node
*/ */
function ensureNodeHasCheckbox(elem) { function serializeTaskListNode(node) {
// Stop if there's already an input const isChecked = node.attr('checked') === 'checked';
if (elem.firstChild && elem.firstChild.name === 'input') { node.attr('checked', null);
return;
const inputAttrs = {type: 'checkbox', disabled: 'disabled'};
if (isChecked) {
inputAttrs.checked = 'checked';
} }
const input = new tinymce.html.Node.create('input', { const checkbox = new tinymce.html.Node.create('input', inputAttrs);
type: 'checkbox', checkbox.shortEnded = true;
disabled: 'disabled', node.firstChild ? node.insert(checkbox, node.firstChild, true) : node.append(checkbox);
});
if (elem.firstChild) {
elem.insert(input, elem.firstChild, true);
} else {
elem.append(input);
}
} }
/** /**
* @param {WysiwygConfigOptions} options * @param {WysiwygConfigOptions} options
* @return {register} * @return {register}

View File

@ -113,3 +113,28 @@ body.page-content.mce-content-body {
.tox-menu .tox-collection__item-label { .tox-menu .tox-collection__item-label {
line-height: normal !important; line-height: normal !important;
} }
/**
* Fake task list checkboxes
*/
.page-content.mce-content-body .task-list-item > input[type="checkbox"] {
display: none;
}
.page-content.mce-content-body .task-list-item:before {
content: '';
display: inline-block;
border: 2px solid #CCC;
width: 12px;
height: 12px;
border-radius: 2px;
margin-right: 8px;
vertical-align: text-top;
cursor: pointer;
}
.page-content.mce-content-body .task-list-item[checked]:before {
background-color: #CCC;
background-image: url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m8.4856 20.274-6.736-6.736 2.9287-2.7823 3.8073 3.8073 10.836-10.836 2.9287 2.9287z" stroke-width="1.4644"/></svg>');
background-position: 50% 50%;
background-size: 100% 100%;
}