diff --git a/LexicalList.dev.js b/LexicalList.dev.js index 3b91ac0e93f7e6a9d784c7d8a19f11496369ecc0..de90d1b8de072015dc57a9174e1206c7371d0434 100644 --- a/LexicalList.dev.js +++ b/LexicalList.dev.js @@ -140,27 +140,6 @@ function wrapInListItem(node) { function $isSelectingEmptyListItem(anchorNode, nodes) { return $isListItemNode(anchorNode) && (nodes.length === 0 || nodes.length === 1 && anchorNode.is(nodes[0]) && anchorNode.getChildrenSize() === 0); } -function $getListItemValue(listItem) { - const list = listItem.getParent(); - let value = 1; - if (list != null) { - if (!$isListNode(list)) { - { - throw Error(`$getListItemValue: list node is not parent of list item node`); - } - } else { - value = list.getStart(); - } - } - const siblings = listItem.getPreviousSiblings(); - for (let i = 0; i < siblings.length; i++) { - const sibling = siblings[i]; - if ($isListItemNode(sibling) && !$isListNode(sibling.getFirstChild())) { - value++; - } - } - return value; -} /** * Inserts a new ListNode. If the selection's anchor node is an empty ListItemNode and is a child of @@ -217,7 +196,6 @@ function insertList(editor, listType) { const newListNode = $createListNode(listType); append(newListNode, parent.getChildren()); parent.replace(newListNode); - updateChildrenListItemValue(newListNode); handled.add(parentKey); } break; @@ -268,7 +246,6 @@ function createListOrMerge(node, listType) { const list = $createListNode(listType); list.append(listItem); node.replace(list); - updateChildrenListItemValue(list); return list; } } @@ -289,7 +266,6 @@ function mergeLists(list1, list2) { const toMerge = list2.getChildren(); if (toMerge.length > 0) { list1.append(...toMerge); - updateChildrenListItemValue(list1); } list2.remove(); } @@ -352,22 +328,23 @@ function removeList(editor) { /** * Takes the value of a child ListItemNode and makes it the value the ListItemNode - * should be if it isn't already. If only certain children should be updated, they - * can be passed optionally in an array. + * should be if it isn't already. Also ensures that checked is undefined if the + * parent does not have a list type of 'check'. * @param list - The list whose children are updated. - * @param children - An array of the children to be updated. */ -function updateChildrenListItemValue(list, children) { - const childrenOrExisting = children || list.getChildren(); - if (childrenOrExisting !== undefined) { - for (let i = 0; i < childrenOrExisting.length; i++) { - const child = childrenOrExisting[i]; - if ($isListItemNode(child)) { - const prevValue = child.getValue(); - const nextValue = $getListItemValue(child); - if (prevValue !== nextValue) { - child.setValue(nextValue); - } +function updateChildrenListItemValue(list) { + const isNotChecklist = list.getListType() !== 'check'; + let value = list.getStart(); + for (const child of list.getChildren()) { + if ($isListItemNode(child)) { + if (child.getValue() !== value) { + child.setValue(value); + } + if (isNotChecklist && child.getChecked() != null) { + child.setChecked(undefined); + } + if (!$isListNode(child.getFirstChild())) { + value++; } } } @@ -403,7 +380,6 @@ function $handleIndent(listItemNode) { nextSibling.remove(); removed.add(nextSibling.getKey()); } - updateChildrenListItemValue(innerList); } } else if (isNestedListNode(nextSibling)) { // if the ListItemNode is next to a nested ListNode, merge them @@ -413,13 +389,11 @@ function $handleIndent(listItemNode) { if (firstChild !== null) { firstChild.insertBefore(listItemNode); } - updateChildrenListItemValue(innerList); } } else if (isNestedListNode(previousSibling)) { const innerList = previousSibling.getFirstChild(); if ($isListNode(innerList)) { innerList.append(listItemNode); - updateChildrenListItemValue(innerList); } } else { // otherwise, we need to create a new nested ListNode @@ -436,12 +410,8 @@ function $handleIndent(listItemNode) { } else { parent.append(newListItem); } - updateChildrenListItemValue(newList); } } - if ($isListNode(parent)) { - updateChildrenListItemValue(parent); - } } /** @@ -495,8 +465,6 @@ function $handleOutdent(listItemNode) { // replace the grandparent list item (now between the siblings) with the outdented list item. grandparentListItem.replace(listItemNode); } - updateChildrenListItemValue(parentList); - updateChildrenListItemValue(greatGrandparentList); } } @@ -603,12 +571,14 @@ class ListItemNode extends lexical.ElementNode { } static transform() { return node => { + if (!$isListItemNode(node)) { + throw Error(`node is not a ListItemNode`); + } + if (node.__checked == null) { + return; + } const parent = node.getParent(); if ($isListNode(parent)) { - updateChildrenListItemValue(parent); - if (!$isListItemNode(node)) { - throw Error(`node is not a ListItemNode`); - } if (parent.getListType() !== 'check' && node.getChecked() != null) { node.setChecked(undefined); } @@ -704,15 +674,10 @@ class ListItemNode extends lexical.ElementNode { throw Error(`insertAfter: list node is not parent of list item node`); } } - const siblings = this.getNextSiblings(); if ($isListItemNode(node)) { - const after = super.insertAfter(node, restoreSelection); - const afterListNode = node.getParentOrThrow(); - if ($isListNode(afterListNode)) { - updateChildrenListItemValue(afterListNode); - } - return after; + return super.insertAfter(node, restoreSelection); } + const siblings = this.getNextSiblings(); // Attempt to merge if the list is of the same type. @@ -743,11 +708,6 @@ class ListItemNode extends lexical.ElementNode { if (prevSibling && nextSibling && isNestedListNode(prevSibling) && isNestedListNode(nextSibling)) { mergeLists(prevSibling.getFirstChild(), nextSibling.getFirstChild()); nextSibling.remove(); - } else if (nextSibling) { - const parent = nextSibling.getParent(); - if ($isListNode(parent)) { - updateChildrenListItemValue(parent); - } } } insertNewAfter(_, restoreSelection = true) { @@ -839,16 +799,6 @@ class ListItemNode extends lexical.ElementNode { } return this; } - insertBefore(nodeToInsert) { - if ($isListItemNode(nodeToInsert)) { - const parent = this.getParentOrThrow(); - if ($isListNode(parent)) { - const siblings = this.getNextSiblings(); - updateChildrenListItemValue(parent, siblings); - } - } - return super.insertBefore(nodeToInsert); - } canInsertAfter(node) { return $isListItemNode(node); } @@ -1018,6 +968,14 @@ class ListNode extends lexical.ElementNode { setListThemeClassNames(dom, config.theme, this); return false; } + static transform() { + return node => { + if (!$isListNode(node)) { + throw Error(`node is not a ListNode`); + } + updateChildrenListItemValue(node); + }; + } static importDOM() { return { ol: node => ({ @@ -1087,7 +1045,6 @@ class ListNode extends lexical.ElementNode { super.append(listItemNode); } } - updateChildrenListItemValue(this); return this; } extractWithChild(child) { diff --git a/LexicalList.prod.js b/LexicalList.prod.js index 4687f6a90633c254974aedd06538d334f84de249..54fac0766cf47224af5d0e4e05054861f1072872 100644 --- a/LexicalList.prod.js +++ b/LexicalList.prod.js @@ -4,32 +4,33 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -'use strict';var h=require("lexical"),k=require("@lexical/utils");function l(a){let b=new URLSearchParams;b.append("code",a);for(let c=1;cm.append(x));f=y();g=E(g);f.append(g);C(g,a.getNextSiblings());c.insertBefore(e);c.insertAfter(f);c.replace(a)}F(b);F(d)}}} -class I extends h.ElementNode{static getType(){return"listitem"}static clone(a){return new I(a.__value,a.__checked,a.__key)}constructor(a,b,c){super(c);this.__value=void 0===a?1:a;this.__checked=b}createDOM(a){let b=document.createElement("li"),c=this.getParent();q(c)&&"check"===c.getListType()&&J(b,this,null);b.value=this.__value;K(b,a.theme,this);return b}updateDOM(a,b,c){let d=this.getParent();q(d)&&"check"===d.getListType()&&J(b,this,a);b.value=this.__value;K(b,c.theme,this);return!1}static transform(){return a=> -{let b=a.getParent();q(b)&&(F(b),p(a)||l(144),"check"!==b.getListType()&&null!=a.getChecked()&&a.setChecked(void 0))}}static importDOM(){return{li:()=>({conversion:L,priority:0})}}static importJSON(a){let b=y();b.setChecked(a.checked);b.setValue(a.value);b.setFormat(a.format);b.setDirection(a.direction);return b}exportDOM(a){a=this.createDOM(a._config);a.style.textAlign=this.getFormatType();return{element:a}}exportJSON(){return{...super.exportJSON(),checked:this.getChecked(),type:"listitem",value:this.getValue(), -version:1}}append(...a){for(let b=0;b{a.append(d)}));this.remove();0===c.getChildrenSize()&&c.remove();return a}insertAfter(a,b=!0){var c=this.getParentOrThrow();q(c)||l(39);var d=this.getNextSiblings();if(p(a))return b=super.insertAfter(a,b),a=a.getParentOrThrow(),q(a)&&F(a),b;if(q(a)){c=a;a=a.getChildren();for(d=a.length-1;0<=d;d--)c=a[d],this.insertAfter(c,b);return c}c.insertAfter(a,b);if(0!==d.length){let e=E(c.getListType());d.forEach(f=>e.append(f)); -a.insertAfter(e,b)}return a}remove(a){let b=this.getPreviousSibling(),c=this.getNextSibling();super.remove(a);b&&c&&u(b)&&u(c)?(G(b.getFirstChild(),c.getFirstChild()),c.remove()):c&&(a=c.getParent(),q(a)&&F(a))}insertNewAfter(a,b=!0){a=y(null==this.__checked?void 0:!1);this.insertAfter(a,b);return a}collapseAtStart(a){let b=h.$createParagraphNode();this.getChildren().forEach(f=>b.append(f));var c=this.getParentOrThrow(),d=c.getParentOrThrow();let e=p(d);1===c.getChildrenSize()?e?(c.remove(),d.select()): -(c.insertBefore(b),c.remove(),c=a.anchor,a=a.focus,d=b.getKey(),"element"===c.type&&c.getNode().is(this)&&c.set(d,c.offset,"element"),"element"===a.type&&a.getNode().is(this)&&a.set(d,a.offset,"element")):(c.insertBefore(b),this.remove());return!0}getValue(){return this.getLatest().__value}setValue(a){this.getWritable().__value=a}getChecked(){return this.getLatest().__checked}setChecked(a){this.getWritable().__checked=a}toggleChecked(){this.setChecked(!this.__checked)}getIndent(){var a=this.getParent(); -if(null===a)return this.getLatest().__indent;a=a.getParentOrThrow();let b=0;for(;p(a);)a=a.getParentOrThrow().getParentOrThrow(),b++;return b}setIndent(a){"number"===typeof a&&-1q(m))?d.push(...g):e.push(...g));0({conversion:Q,priority:0}),ul:()=>({conversion:Q,priority:0})}}static importJSON(a){let b=E(a.listType,a.start);b.setFormat(a.format);b.setIndent(a.indent);b.setDirection(a.direction);return b}exportDOM(a){({element:a}=super.exportDOM(a));a&&k.isHTMLElement(a)&&(1!==this.__start&&a.setAttribute("start",String(this.__start)), -"check"===this.__listType&&a.setAttribute("__lexicalListType","check"));return{element:a}}exportJSON(){return{...super.exportJSON(),listType:this.getListType(),start:this.getStart(),tag:this.getTag(),type:"list",version:1}}canBeEmpty(){return!1}canIndent(){return!1}append(...a){for(let c=0;c{q(e)&&b.push(w(e))})):b.push(w(c))}return b}function Q(a){let b=a.nodeName.toLowerCase(),c=null;"ol"===b?c=E("number",a.start):"ul"===b&&(c=k.isHTMLElement(a)&&"check"===a.getAttribute("__lexicallisttype")?E("check"):E("bullet"));return{after:R,node:c}}let O={ol:"number",ul:"bullet"};function E(a,b=1){return h.$applyNodeReplacement(new M(a,b))} -function q(a){return a instanceof M}let S=h.createCommand("INSERT_UNORDERED_LIST_COMMAND"),T=h.createCommand("INSERT_ORDERED_LIST_COMMAND"),U=h.createCommand("INSERT_CHECK_LIST_COMMAND"),V=h.createCommand("REMOVE_LIST_COMMAND");exports.$createListItemNode=y;exports.$createListNode=E;exports.$getListDepth=n; -exports.$handleListInsertParagraph=function(){var a=h.$getSelection();if(!h.$isRangeSelection(a)||!a.isCollapsed())return!1;a=a.anchor.getNode();if(!p(a)||0!==a.getChildrenSize())return!1;var b=r(a),c=a.getParent();q(c)||l(40);let d=c.getParent(),e;if(h.$isRootOrShadowRoot(d))e=h.$createParagraphNode(),b.insertAfter(e);else if(p(d))e=y(),d.insertAfter(e);else return!1;e.select();b=a.getNextSiblings();if(0{g.remove();f.append(g)})}v(a);return!0};exports.$isListItemNode=p;exports.$isListNode=q;exports.INSERT_CHECK_LIST_COMMAND=U;exports.INSERT_ORDERED_LIST_COMMAND=T;exports.INSERT_UNORDERED_LIST_COMMAND=S;exports.ListItemNode=I;exports.ListNode=M;exports.REMOVE_LIST_COMMAND=V; -exports.insertList=function(a,b){a.update(()=>{var c=h.$getSelection();if(null!==c){var d=c.getNodes();c=c.getStartEndPoints();null===c&&l(143);[c]=c;c=c.getNode();var e=c.getParent();if(z(c,d))d=E(b),h.$isRootOrShadowRoot(e)?(c.replace(d),e=y(),h.$isElementNode(c)&&(e.setFormat(c.getFormatType()),e.setIndent(c.getIndent())),d.append(e)):p(c)&&(c=c.getParentOrThrow(),C(d,c.getChildren()),c.replace(d));else for(c=new Set,e=0;e{let b=h.$getSelection();if(h.$isRangeSelection(b)){var c=new Set,d=b.getNodes(),e=b.anchor.getNode();if(z(e,d))c.add(r(e));else for(e=0;ef.append(h));d=x();e=D(e);d.append(e);B(e,a.getNextSiblings());c.insertBefore(b);c.insertAfter(d);c.replace(a)}}}} +class G extends g.ElementNode{static getType(){return"listitem"}static clone(a){return new G(a.__value,a.__checked,a.__key)}constructor(a,b,c){super(c);this.__value=void 0===a?1:a;this.__checked=b}createDOM(a){let b=document.createElement("li"),c=this.getParent();q(c)&&"check"===c.getListType()&&H(b,this,null);b.value=this.__value;I(b,a.theme,this);return b}updateDOM(a,b,c){let d=this.getParent();q(d)&&"check"===d.getListType()&&H(b,this,a);b.value=this.__value;I(b,c.theme,this);return!1}static transform(){return a=> +{p(a)||l(144);if(null!=a.__checked){var b=a.getParent();q(b)&&"check"!==b.getListType()&&null!=a.getChecked()&&a.setChecked(void 0)}}}static importDOM(){return{li:()=>({conversion:J,priority:0})}}static importJSON(a){let b=x();b.setChecked(a.checked);b.setValue(a.value);b.setFormat(a.format);b.setDirection(a.direction);return b}exportDOM(a){a=this.createDOM(a._config);a.style.textAlign=this.getFormatType();return{element:a}}exportJSON(){return{...super.exportJSON(),checked:this.getChecked(),type:"listitem", +value:this.getValue(),version:1}}append(...a){for(let b=0;b{a.append(d)}));this.remove();0===c.getChildrenSize()&&c.remove();return a}insertAfter(a,b=!0){var c=this.getParentOrThrow();q(c)||l(39);if(p(a))return super.insertAfter(a,b);var d=this.getNextSiblings();if(q(a)){c=a;a=a.getChildren();for(d=a.length-1;0<=d;d--)c=a[d],this.insertAfter(c,b);return c}c.insertAfter(a,b);if(0!==d.length){let e=D(c.getListType());d.forEach(f=>e.append(f));a.insertAfter(e, +b)}return a}remove(a){let b=this.getPreviousSibling(),c=this.getNextSibling();super.remove(a);b&&c&&u(b)&&u(c)&&(E(b.getFirstChild(),c.getFirstChild()),c.remove())}insertNewAfter(a,b=!0){a=x(null==this.__checked?void 0:!1);this.insertAfter(a,b);return a}collapseAtStart(a){let b=g.$createParagraphNode();this.getChildren().forEach(f=>b.append(f));var c=this.getParentOrThrow(),d=c.getParentOrThrow();let e=p(d);1===c.getChildrenSize()?e?(c.remove(),d.select()):(c.insertBefore(b),c.remove(),c=a.anchor, +a=a.focus,d=b.getKey(),"element"===c.type&&c.getNode().is(this)&&c.set(d,c.offset,"element"),"element"===a.type&&a.getNode().is(this)&&a.set(d,a.offset,"element")):(c.insertBefore(b),this.remove());return!0}getValue(){return this.getLatest().__value}setValue(a){this.getWritable().__value=a}getChecked(){return this.getLatest().__checked}setChecked(a){this.getWritable().__checked=a}toggleChecked(){this.setChecked(!this.__checked)}getIndent(){var a=this.getParent();if(null===a)return this.getLatest().__indent; +a=a.getParentOrThrow();let b=0;for(;p(a);)a=a.getParentOrThrow().getParentOrThrow(),b++;return b}setIndent(a){"number"===typeof a&&-1q(m))?d.push(...h):e.push(...h));0{if(!q(a))throw Error("node is not a ListNode");let b="check"!==a.getListType(),c=a.getStart();for(let d of a.getChildren())p(d)&&(d.getValue()!==c&&d.setValue(c),b&&null!=d.getChecked()&&d.setChecked(void 0),q(d.getFirstChild())||c++)}}static importDOM(){return{ol:()=>({conversion:P,priority:0}),ul:()=>({conversion:P, +priority:0})}}static importJSON(a){let b=D(a.listType,a.start);b.setFormat(a.format);b.setIndent(a.indent);b.setDirection(a.direction);return b}exportDOM(a){({element:a}=super.exportDOM(a));a&&k.isHTMLElement(a)&&(1!==this.__start&&a.setAttribute("start",String(this.__start)),"check"===this.__listType&&a.setAttribute("__lexicalListType","check"));return{element:a}}exportJSON(){return{...super.exportJSON(),listType:this.getListType(),start:this.getStart(),tag:this.getTag(),type:"list",version:1}}canBeEmpty(){return!1}canIndent(){return!1}append(...a){for(let c= +0;c{q(e)&&b.push(w(e))})):b.push(w(c))}return b}function P(a){let b=a.nodeName.toLowerCase(),c=null;"ol"===b?c=D("number",a.start):"ul"===b&&(c=k.isHTMLElement(a)&&"check"===a.getAttribute("__lexicallisttype")?D("check"):D("bullet"));return{after:Q,node:c}}let N={ol:"number",ul:"bullet"};function D(a,b=1){return g.$applyNodeReplacement(new K(a,b))} +function q(a){return a instanceof K}let R=g.createCommand("INSERT_UNORDERED_LIST_COMMAND"),S=g.createCommand("INSERT_ORDERED_LIST_COMMAND"),T=g.createCommand("INSERT_CHECK_LIST_COMMAND"),U=g.createCommand("REMOVE_LIST_COMMAND");exports.$createListItemNode=x;exports.$createListNode=D;exports.$getListDepth=n; +exports.$handleListInsertParagraph=function(){var a=g.$getSelection();if(!g.$isRangeSelection(a)||!a.isCollapsed())return!1;a=a.anchor.getNode();if(!p(a)||0!==a.getChildrenSize())return!1;var b=r(a),c=a.getParent();q(c)||l(40);let d=c.getParent(),e;if(g.$isRootOrShadowRoot(d))e=g.$createParagraphNode(),b.insertAfter(e);else if(p(d))e=x(),d.insertAfter(e);else return!1;e.select();b=a.getNextSiblings();if(0{h.remove();f.append(h)})}v(a);return!0};exports.$isListItemNode=p;exports.$isListNode=q;exports.INSERT_CHECK_LIST_COMMAND=T;exports.INSERT_ORDERED_LIST_COMMAND=S;exports.INSERT_UNORDERED_LIST_COMMAND=R;exports.ListItemNode=G;exports.ListNode=K;exports.REMOVE_LIST_COMMAND=U; +exports.insertList=function(a,b){a.update(()=>{var c=g.$getSelection();if(null!==c){var d=c.getNodes();c=c.getStartEndPoints();null===c&&l(143);[c]=c;c=c.getNode();var e=c.getParent();if(A(c,d))d=D(b),g.$isRootOrShadowRoot(e)?(c.replace(d),e=x(),g.$isElementNode(c)&&(e.setFormat(c.getFormatType()),e.setIndent(c.getIndent())),d.append(e)):p(c)&&(c=c.getParentOrThrow(),B(d,c.getChildren()),c.replace(d));else for(c=new Set,e=0;e{let b=g.$getSelection();if(g.$isRangeSelection(b)){var c=new Set,d=b.getNodes(),e=b.anchor.getNode();if(A(e,d))c.add(r(e));else for(e=0;e void; static importDOM(): DOMConversionMap | null; static importJSON(serializedNode: SerializedListNode): ListNode; exportDOM(editor: LexicalEditor): DOMExportOutput; diff --git a/formatList.d.ts b/formatList.d.ts index d1f43e38e50680a1248a03ae8ea71f8541c33bc1..4359cbba12fa205eb6843ad1568e02c5efcc8ffc 100644 --- a/formatList.d.ts +++ b/formatList.d.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * */ -import { LexicalEditor, LexicalNode } from 'lexical'; +import { LexicalEditor } from 'lexical'; import { ListItemNode, ListNode } from './'; import { ListType } from './LexicalListNode'; /** @@ -36,12 +36,11 @@ export declare function mergeLists(list1: ListNode, list2: ListNode): void; export declare function removeList(editor: LexicalEditor): void; /** * Takes the value of a child ListItemNode and makes it the value the ListItemNode - * should be if it isn't already. If only certain children should be updated, they - * can be passed optionally in an array. + * should be if it isn't already. Also ensures that checked is undefined if the + * parent does not have a list type of 'check'. * @param list - The list whose children are updated. - * @param children - An array of the children to be updated. */ -export declare function updateChildrenListItemValue(list: ListNode, children?: Array): void; +export declare function updateChildrenListItemValue(list: ListNode): void; /** * Adds an empty ListNode/ListItemNode chain at listItemNode, so as to * create an indent effect. Won't indent ListItemNodes that have a ListNode as