@ckeditor/ckeditor5-list
Version:
Ordered and unordered lists feature to CKEditor 5.
118 lines (117 loc) • 4.11 kB
JavaScript
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* Checks if view element is a list type (ul or ol).
*
* @internal
*/
export function isListView(viewElement) {
return viewElement.is('element', 'ol') || viewElement.is('element', 'ul');
}
/**
* Checks if view element is a list item (li).
*
* @internal
*/
export function isListItemView(viewElement) {
return viewElement.is('element', 'li');
}
/**
* Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.
*
* Also, fixes non HTML compliant lists indents:
*
* ```
* before: fixed list:
* OL OL
* |-> LI (parent LIs: 0) |-> LI (indent: 0)
* |-> OL |-> OL
* |-> OL |
* | |-> OL |
* | |-> OL |
* | |-> LI (parent LIs: 1) |-> LI (indent: 1)
* |-> LI (parent LIs: 1) |-> LI (indent: 1)
*
* before: fixed list:
* OL OL
* |-> OL |
* |-> OL |
* |-> OL |
* |-> LI (parent LIs: 0) |-> LI (indent: 0)
*
* before: fixed list:
* OL OL
* |-> LI (parent LIs: 0) |-> LI (indent: 0)
* |-> OL |-> OL
* |-> LI (parent LIs: 0) |-> LI (indent: 1)
* ```
*
* @internal
*/
export function getIndent(listItem) {
let indent = 0;
let parent = listItem.parent;
while (parent) {
// Each LI in the tree will result in an increased indent for HTML compliant lists.
if (isListItemView(parent)) {
indent++;
}
else {
// If however the list is nested in other list we should check previous sibling of any of the list elements...
const previousSibling = parent.previousSibling;
// ...because the we might need increase its indent:
// before: fixed list:
// OL OL
// |-> LI (parent LIs: 0) |-> LI (indent: 0)
// |-> OL |-> OL
// |-> LI (parent LIs: 0) |-> LI (indent: 1)
if (previousSibling && isListItemView(previousSibling)) {
indent++;
}
}
parent = parent.parent;
}
return indent;
}
/**
* Creates a list attribute element (ol or ul).
*
* @internal
*/
export function createListElement(writer, indent, type, id = getViewElementIdForListType(type, indent)) {
// Negative priorities so that restricted editing attribute won't wrap lists.
return writer.createAttributeElement(getViewElementNameForListType(type), null, {
priority: 2 * indent / 100 - 100,
id
});
}
/**
* Creates a list item attribute element (li).
*
* @internal
*/
export function createListItemElement(writer, indent, id) {
// Negative priorities so that restricted editing attribute won't wrap list items.
return writer.createAttributeElement('li', null, {
priority: (2 * indent + 1) / 100 - 100,
id
});
}
/**
* Returns a view element name for the given list type.
*
* @internal
*/
export function getViewElementNameForListType(type) {
return type == 'numbered' || type == 'customNumbered' ? 'ol' : 'ul';
}
/**
* Returns a view element ID for the given list type and indent.
*
* @internal
*/
export function getViewElementIdForListType(type, indent) {
return `list-${type}-${indent}`;
}