From 3cdc161ad90a2849f0c9e8c21100c1eb5c43912a Mon Sep 17 00:00:00 2001 From: jisong Date: Wed, 9 Nov 2022 22:40:59 -0800 Subject: [PATCH 1/2] Fix list style issue --- .../lib/list/VListItem.ts | 31 ++++++++++++++++--- .../lib/list/setListItemStyle.ts | 3 +- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/roosterjs-editor-dom/lib/list/VListItem.ts b/packages/roosterjs-editor-dom/lib/list/VListItem.ts index c83475365b9..cb00b960a30 100644 --- a/packages/roosterjs-editor-dom/lib/list/VListItem.ts +++ b/packages/roosterjs-editor-dom/lib/list/VListItem.ts @@ -7,6 +7,7 @@ import safeInstanceOf from '../utils/safeInstanceOf'; import setBulletListMarkers from './setBulletListMarkers'; import setListItemStyle from './setListItemStyle'; import setNumberingListMarkers from './setNumberingListMarkers'; +import setStyles from '../style/setStyles'; import toArray from '../jsUtils/toArray'; import unwrap from '../utils/unwrap'; import wrap from '../utils/wrap'; @@ -366,10 +367,21 @@ export default class VListItem { // 5. If this is not a list item now, need to unwrap the LI node and do proper handling if (this.listTypes.length <= 1) { + // If original
  • node has styles for font and color, we need to apply it to new parent + const isLi = getTagOfNode(this.node) == 'LI'; + const stylesToApply = isLi + ? { + 'font-family': this.node.style.fontFamily, + 'font-size': this.node.style.fontSize, + color: this.node.style.color, + } + : undefined; + wrapIfNotBlockNode( - getTagOfNode(this.node) == 'LI' ? getChildrenAndUnwrap(this.node) : [this.node], + isLi ? getChildrenAndUnwrap(this.node) : [this.node], true /*checkFirst*/, - true /*checkLast*/ + true /*checkLast*/, + stylesToApply ); } } @@ -459,13 +471,24 @@ function createListElement( return result; } -function wrapIfNotBlockNode(nodes: Node[], checkFirst: boolean, checkLast: boolean): Node[] { +function wrapIfNotBlockNode( + nodes: Node[], + checkFirst: boolean, + checkLast: boolean, + styles?: Record +): Node[] { if ( nodes.length > 0 && (!checkFirst || !isBlockElement(nodes[0])) && (!checkLast || !isBlockElement(nodes[nodes.length])) ) { - nodes = [wrap(nodes)]; + const parent = wrap(nodes); + + if (styles) { + setStyles(parent, styles); + } + + nodes = [parent]; } return nodes; diff --git a/packages/roosterjs-editor-dom/lib/list/setListItemStyle.ts b/packages/roosterjs-editor-dom/lib/list/setListItemStyle.ts index 4f23570e2c8..9cf862d73ba 100644 --- a/packages/roosterjs-editor-dom/lib/list/setListItemStyle.ts +++ b/packages/roosterjs-editor-dom/lib/list/setListItemStyle.ts @@ -48,7 +48,8 @@ function getInlineChildElementsStyle(element: HTMLElement, styles: string[]) { while ( currentNode && currentNode !== element && - safeInstanceOf(currentNode, 'HTMLElement') + safeInstanceOf(currentNode, 'HTMLElement') && + (currentNode.textContent?.trim().length || 0) > 0 ) { styles.forEach(styleName => { const styleValue = (currentNode as HTMLElement).style.getPropertyValue(styleName); From 1b32bd3d2d596c3fabc224980b0ef41612abcaf1 Mon Sep 17 00:00:00 2001 From: JiuqingSong Date: Thu, 10 Nov 2022 10:51:01 -0800 Subject: [PATCH 2/2] fix bug and test cases --- .../test/utils/toggleListTypeTest.ts | 4 +- .../lib/list/VListItem.ts | 43 +++++++++++-------- .../lib/list/setListItemStyle.ts | 11 +++-- .../test/list/VListTest.ts | 4 +- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/packages/roosterjs-editor-api/test/utils/toggleListTypeTest.ts b/packages/roosterjs-editor-api/test/utils/toggleListTypeTest.ts index c89bfefc22a..58bfa7c0661 100644 --- a/packages/roosterjs-editor-api/test/utils/toggleListTypeTest.ts +++ b/packages/roosterjs-editor-api/test/utils/toggleListTypeTest.ts @@ -36,7 +36,7 @@ describe('toggleListTypeTest()', () => { '

    ' + '
    ' + '
    • test
    ' + - '
    ' + + '
    ' + '
    ' ); }); @@ -62,7 +62,7 @@ describe('toggleListTypeTest()', () => { '

    ' + '
    ' + '
    • test
    ' + - '
    ' + + '
    ' + '
    • test
    ' + '
    ' ); diff --git a/packages/roosterjs-editor-dom/lib/list/VListItem.ts b/packages/roosterjs-editor-dom/lib/list/VListItem.ts index cb00b960a30..7a9df3a3cc5 100644 --- a/packages/roosterjs-editor-dom/lib/list/VListItem.ts +++ b/packages/roosterjs-editor-dom/lib/list/VListItem.ts @@ -1,5 +1,6 @@ import contains from '../utils/contains'; import getListTypeFromNode from './getListTypeFromNode'; +import getStyles from '../style/getStyles'; import getTagOfNode from '../utils/getTagOfNode'; import isBlockElement from '../utils/isBlockElement'; import moveChildNodes from '../utils/moveChildNodes'; @@ -377,12 +378,27 @@ export default class VListItem { } : undefined; - wrapIfNotBlockNode( - isLi ? getChildrenAndUnwrap(this.node) : [this.node], - true /*checkFirst*/, - true /*checkLast*/, - stylesToApply - ); + const childNodes = isLi ? getChildrenAndUnwrap(this.node) : [this.node]; + + if (stylesToApply) { + for (let i = 0; i < childNodes.length; i++) { + if (safeInstanceOf(childNodes[i], 'Text')) { + childNodes[i] = wrap(childNodes[i], 'span'); + } + + const node = childNodes[i]; + + if (safeInstanceOf(node, 'HTMLElement')) { + const styles = { + ...stylesToApply, + ...getStyles(node), + }; + setStyles(node, styles); + } + } + } + + wrapIfNotBlockNode(childNodes, true /*checkFirst*/, true /*checkLast*/); } } @@ -471,24 +487,13 @@ function createListElement( return result; } -function wrapIfNotBlockNode( - nodes: Node[], - checkFirst: boolean, - checkLast: boolean, - styles?: Record -): Node[] { +function wrapIfNotBlockNode(nodes: Node[], checkFirst: boolean, checkLast: boolean): Node[] { if ( nodes.length > 0 && (!checkFirst || !isBlockElement(nodes[0])) && (!checkLast || !isBlockElement(nodes[nodes.length])) ) { - const parent = wrap(nodes); - - if (styles) { - setStyles(parent, styles); - } - - nodes = [parent]; + nodes = [wrap(nodes)]; } return nodes; diff --git a/packages/roosterjs-editor-dom/lib/list/setListItemStyle.ts b/packages/roosterjs-editor-dom/lib/list/setListItemStyle.ts index 9cf862d73ba..12d1e125ffc 100644 --- a/packages/roosterjs-editor-dom/lib/list/setListItemStyle.ts +++ b/packages/roosterjs-editor-dom/lib/list/setListItemStyle.ts @@ -39,20 +39,25 @@ function getInlineChildElementsStyle(element: HTMLElement, styles: string[]) { while (contentTraverser.currentInlineElement != currentInlineElement) { currentInlineElement = contentTraverser.currentInlineElement; let currentNode = currentInlineElement?.getContainerNode() || null; - const currentStyle: Record = {}; + let currentStyle: Record | null = null; currentNode = currentNode ? findClosestElementAncestor(currentNode) : null; - // we should consider of when it is the single childnode of element, the parentNode's style should add + // we should consider of when it is the single child node of element, the parentNode's style should add // such as the "i", "b", "span" node in
  • aa
  • while ( currentNode && currentNode !== element && safeInstanceOf(currentNode, 'HTMLElement') && - (currentNode.textContent?.trim().length || 0) > 0 + (result.length == 0 || (currentNode.textContent?.trim().length || 0) > 0) ) { styles.forEach(styleName => { const styleValue = (currentNode as HTMLElement).style.getPropertyValue(styleName); + + if (!currentStyle) { + currentStyle = {}; + } + if (styleValue && !currentStyle[styleName]) { currentStyle[styleName] = styleValue; } diff --git a/packages/roosterjs-editor-dom/test/list/VListTest.ts b/packages/roosterjs-editor-dom/test/list/VListTest.ts index 9615c369746..dd3af36b065 100644 --- a/packages/roosterjs-editor-dom/test/list/VListTest.ts +++ b/packages/roosterjs-editor-dom/test/list/VListTest.ts @@ -426,7 +426,7 @@ describe('VList.writeBack', () => { listTypes: [ListType.Ordered], }, ], - '
    item2
    1. item3
    ' + '
    item2
    1. item3
    ' ); }); @@ -498,7 +498,7 @@ describe('VList.writeBack', () => { listTypes: [ListType.Ordered], }, ], - '
    text
    1. item3
    2. item4
    text
    1. item5
    ', + '
    text
    1. item3
    2. item4
    text
    1. item5
    ', ol ); });