Skip to content

Commit 99774d8

Browse files
Add unit tests and scope list marker font size removal to tables
Only remove the list marker font size when the list is inside a table cell, and add unit tests covering table detection and marker font size. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent af587e4 commit 99774d8

2 files changed

Lines changed: 98 additions & 5 deletions

File tree

packages/roosterjs-content-model-plugins/lib/paste/PowerPoint/processPastedContentFromPowerPoint.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,12 @@ export function processPastedContentFromPowerPoint(
9999
clearListItemStyles(listItem.levels[listItem.levels.length - 1].format);
100100
clearListItemStyles(listItem.format);
101101

102-
// Remove the font size from the list marker so it does not inherit the
103-
// list's font size. Otherwise a large marker may be rendered outside of
104-
// the table cell when the list is inside a table.
105-
delete listItem.formatHolder.format.fontSize;
102+
// When the list is inside a table cell, remove the font size from the
103+
// list marker so it does not inherit the list's font size. Otherwise a
104+
// large marker may be rendered outside of the table cell.
105+
if (element.closest('td,th')) {
106+
delete listItem.formatHolder.format.fontSize;
107+
}
106108
});
107109
} else {
108110
context.defaultElementProcessors.element?.(group, element, context);

packages/roosterjs-content-model-plugins/test/paste/powerPoint/processPastedContentFromPowerPointTest.ts

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import * as moveChildNodes from 'roosterjs-content-model-dom/lib/domUtils/moveChildNodes';
22
import { createDefaultDomToModelContext } from '../../TestHelper';
3+
import { createDomToModelContext, domToContentModel } from 'roosterjs-content-model-dom';
34
import { processPastedContentFromPowerPoint } from '../../../lib/paste/PowerPoint/processPastedContentFromPowerPoint';
4-
import type { BeforePasteEvent, ClipboardData, DOMCreator } from 'roosterjs-content-model-types';
5+
import type {
6+
BeforePasteEvent,
7+
ClipboardData,
8+
ContentModelListItem,
9+
DOMCreator,
10+
} from 'roosterjs-content-model-types';
511

612
const getPasteEvent = (): BeforePasteEvent => {
713
return {
@@ -120,3 +126,88 @@ describe('processPastedContentFromPowerPointTest |', () => {
120126
expect(moveChildNodes.moveChildNodes).not.toHaveBeenCalled();
121127
});
122128
});
129+
130+
describe('processPastedContentFromPowerPoint list handling |', () => {
131+
const domCreator: DOMCreator = {
132+
htmlToDOM: (html: string) => new DOMParser().parseFromString(html, 'text/html'),
133+
};
134+
135+
const bulletHtml =
136+
"<span style='font-size:7.0pt'>" +
137+
"<span style='mso-special-format:bullet;font-family:Arial'>\u2022</span>" +
138+
'</span>';
139+
140+
function convert(html: string) {
141+
const ev = getPasteEvent();
142+
ev.clipboardData.html = html;
143+
ev.clipboardData.text = 'text';
144+
145+
processPastedContentFromPowerPoint(ev, domCreator);
146+
147+
const container = document.createElement('div');
148+
container.innerHTML = html;
149+
150+
const context = createDomToModelContext(undefined, ev.domToModelOption);
151+
152+
return domToContentModel(container, context);
153+
}
154+
155+
it('Converts a PowerPoint bullet div into a list item', () => {
156+
const model = convert(
157+
"<div style='margin-top:10.0pt;direction:ltr;text-align:left'>" +
158+
bulletHtml +
159+
"<span style='font-size:7.0pt;color:black'>Item</span>" +
160+
'</div>'
161+
);
162+
163+
expect(model.blocks.length).toBe(1);
164+
expect(model.blocks[0].blockType).toBe('BlockGroup');
165+
expect((model.blocks[0] as ContentModelListItem).blockGroupType).toBe('ListItem');
166+
});
167+
168+
it('Keeps the list marker font size when the list is not inside a table', () => {
169+
const model = convert(
170+
"<div style='margin-top:10.0pt;direction:ltr;text-align:left;font-size:7.0pt'>" +
171+
bulletHtml +
172+
"<span style='font-size:7.0pt;color:black'>Item</span>" +
173+
'</div>'
174+
);
175+
176+
const listItem = model.blocks[0] as ContentModelListItem;
177+
178+
expect(listItem.blockGroupType).toBe('ListItem');
179+
expect(listItem.formatHolder.format.fontSize).toBe('7pt');
180+
});
181+
182+
it('Removes the list marker font size when the list is inside a table', () => {
183+
const model = convert(
184+
'<table><tbody><tr><td>' +
185+
"<div style='margin-top:10.0pt;direction:ltr;text-align:left;font-size:7.0pt'>" +
186+
bulletHtml +
187+
"<span style='font-size:7.0pt;color:black'>Item</span>" +
188+
'</div>' +
189+
'</td></tr></tbody></table>'
190+
);
191+
192+
const table = model.blocks[0] as any;
193+
const listItem = table.rows[0].cells[0].blocks[0] as ContentModelListItem;
194+
195+
expect(model.blocks[0].blockType).toBe('Table');
196+
expect(listItem.blockGroupType).toBe('ListItem');
197+
expect(listItem.formatHolder.format.fontSize).toBeUndefined();
198+
});
199+
200+
it('Does not convert a table element into a list when it contains a bullet', () => {
201+
const model = convert(
202+
'<table><tbody><tr><td>' +
203+
"<div style='margin-top:10.0pt;direction:ltr;text-align:left'>" +
204+
bulletHtml +
205+
"<span style='font-size:7.0pt;color:black'>Item</span>" +
206+
'</div>' +
207+
'</td></tr></tbody></table>'
208+
);
209+
210+
expect(model.blocks.length).toBe(1);
211+
expect(model.blocks[0].blockType).toBe('Table');
212+
});
213+
});

0 commit comments

Comments
 (0)