mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-08-26 20:22:18 +00:00
Changed to a psuedo-style approach for tasklist in wysiwyg
This commit is contained in:
parent
f991948c49
commit
65dd7ad1e9
@ -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: [
|
||||||
|
@ -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}
|
||||||
|
@ -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%;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user