Improved tasklist wysiwyg behaviour

- Updated buttons/actions to better handle nesting.
- Added hack for better usage with normal bullets
This commit is contained in:
Dan Brown 2022-03-22 14:03:20 +00:00
parent 5ae9ed1e22
commit ea62fe6004
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
2 changed files with 28 additions and 6 deletions

View File

@ -24,7 +24,8 @@ function register(editor, url) {
}, },
onSetup(api) { onSetup(api) {
editor.on('NodeChange', event => { editor.on('NodeChange', event => {
const inList = event.parents.find(el => el.nodeName === 'LI' && el.classList.contains('task-list-item')) !== undefined; const parentListEl = event.parents.find(el => el.nodeName === 'LI');
const inList = parentListEl && parentListEl.classList.contains('task-list-item');
api.setActive(inList); api.setActive(inList);
}); });
} }
@ -35,12 +36,22 @@ function register(editor, url) {
const existingBullListButton = editor.ui.registry.getAll().buttons.bullist; const existingBullListButton = editor.ui.registry.getAll().buttons.bullist;
existingBullListButton.onSetup = function(api) { existingBullListButton.onSetup = function(api) {
editor.on('NodeChange', event => { editor.on('NodeChange', event => {
const notInTaskList = event.parents.find(el => el.nodeName === 'LI' && el.classList.contains('task-list-item')) === undefined; const parentList = event.parents.find(el => el.nodeName === 'LI');
const inList = event.parents.find(el => el.nodeName === 'UL') !== undefined; const inTaskList = parentList && parentList.classList.contains('task-list-item');
api.setActive(inList && notInTaskList); const inUlList = parentList && parentList.parentNode.nodeName === 'UL';
api.setActive(inUlList && !inTaskList);
}); });
}; };
existingBullListButton.onAction = function() { existingBullListButton.onAction = function() {
// Cheeky hack to prevent list toggle action treating tasklists as normal
// unordered lists which would unwrap the list on toggle from tasklist to bullet list.
// Instead we quickly jump through an ordered list first if we're within a tasklist.
if (elementWithinTaskList(editor.selection.getNode())) {
editor.execCommand('InsertOrderedList', null, {
'list-item-attributes': {class: null}
});
}
editor.execCommand('InsertUnorderedList', null, { editor.execCommand('InsertUnorderedList', null, {
'list-item-attributes': {class: null} 'list-item-attributes': {class: null}
}); });
@ -80,6 +91,15 @@ function register(editor, url) {
}); });
} }
/**
* @param {Element} element
* @return {boolean}
*/
function elementWithinTaskList(element) {
const listEl = element.closest('li');
return listEl && listEl.parentNode.nodeName === 'UL' && listEl.classList.contains('task-list-item');
}
/** /**
* @param {MouseEvent} event * @param {MouseEvent} event
* @param {Element} clickedEl * @param {Element} clickedEl
@ -126,6 +146,7 @@ function parseTaskListNode(node) {
* @param {AstNode} node * @param {AstNode} node
*/ */
function serializeTaskListNode(node) { function serializeTaskListNode(node) {
// Get checked status and clean it from list node
const isChecked = node.attr('checked') === 'checked'; const isChecked = node.attr('checked') === 'checked';
node.attr('checked', null); node.attr('checked', null);
@ -134,6 +155,7 @@ function serializeTaskListNode(node) {
inputAttrs.checked = 'checked'; inputAttrs.checked = 'checked';
} }
// Create & insert checkbox input element
const checkbox = new tinymce.html.Node.create('input', inputAttrs); const checkbox = new tinymce.html.Node.create('input', inputAttrs);
checkbox.shortEnded = true; checkbox.shortEnded = true;
node.firstChild ? node.insert(checkbox, node.firstChild, true) : node.append(checkbox); node.firstChild ? node.insert(checkbox, node.firstChild, true) : node.append(checkbox);

View File

@ -10,7 +10,7 @@ export function getPrimaryToolbar(options) {
'styleselect', 'styleselect',
'bold italic underline forecolor backcolor formatoverflow', 'bold italic underline forecolor backcolor formatoverflow',
'alignleft aligncenter alignright alignjustify', 'alignleft aligncenter alignright alignjustify',
'bullist numlist tasklist listoverflow', 'bullist numlist listoverflow',
textDirPlugins, textDirPlugins,
'link table imagemanager-insert insertoverflow', 'link table imagemanager-insert insertoverflow',
'code about fullscreen' 'code about fullscreen'
@ -31,7 +31,7 @@ function registerPrimaryToolbarGroups(editor) {
editor.ui.registry.addGroupToolbarButton('listoverflow', { editor.ui.registry.addGroupToolbarButton('listoverflow', {
icon: 'more-drawer', icon: 'more-drawer',
tooltip: 'More', tooltip: 'More',
items: 'outdent indent' items: 'tasklist outdent indent'
}); });
editor.ui.registry.addGroupToolbarButton('insertoverflow', { editor.ui.registry.addGroupToolbarButton('insertoverflow', {
icon: 'more-drawer', icon: 'more-drawer',