Skip to content

Commit

Permalink
Fix Table Selection CSS Rule when selecting big table (#1929)
Browse files Browse the repository at this point in the history
* fix

* small fix
  • Loading branch information
BryanValverdeU authored Jun 30, 2023
1 parent 0d59804 commit 8ee97a1
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
29 changes: 24 additions & 5 deletions packages/roosterjs-editor-core/lib/coreApi/selectTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const CONTENT_DIV_ID = 'contentDiv_';
const STYLE_ID = 'tableStyle';
const SELECTED_CSS_RULE =
'{background-color: rgb(198,198,198) !important; caret-color: transparent}';
const MAX_RULE_SELECTOR_LENGTH = 9000;

/**
* @internal
Expand Down Expand Up @@ -76,7 +77,7 @@ function buildCss(
table: HTMLTableElement,
coordinates: TableSelection,
contentDivSelector: string
): { css: string; ranges: Range[]; isWholeTableSelected: boolean } {
): { cssRules: string[]; ranges: Range[]; isWholeTableSelected: boolean } {
const ranges: Range[] = [];
const selectors: string[] = [];

Expand All @@ -88,9 +89,20 @@ function buildCss(
handleTableSelected(coordinates, vTable, contentDivSelector, selectors, ranges);
}

const css = selectors.length ? `${selectors.join(',')} ${SELECTED_CSS_RULE}` : '';
const cssRules: string[] = [];
let currentRules: string = '';
while (selectors.length > 0) {
currentRules += (currentRules.length > 0 ? ',' : '') + selectors.shift() || '';
if (
currentRules.length + (selectors[0]?.length || 0) > MAX_RULE_SELECTOR_LENGTH ||
selectors.length == 0
) {
cssRules.push(currentRules + ' ' + SELECTED_CSS_RULE);
currentRules = '';
}
}

return { css, ranges, isWholeTableSelected: isAllTableSelected };
return { cssRules, ranges, isWholeTableSelected: isAllTableSelected };
}

function handleAllTableSelected(
Expand Down Expand Up @@ -193,8 +205,15 @@ function select(
coordinates: TableSelection
): { ranges: Range[]; isWholeTableSelected: boolean } {
const contentDivSelector = '#' + core.contentDiv.id;
let { css, ranges, isWholeTableSelected } = buildCss(table, coordinates, contentDivSelector);
setGlobalCssStyles(core.contentDiv.ownerDocument, css, STYLE_ID + core.contentDiv.id);
let { cssRules, ranges, isWholeTableSelected } = buildCss(
table,
coordinates,
contentDivSelector
);
cssRules.forEach(css =>
setGlobalCssStyles(core.contentDiv.ownerDocument, css, STYLE_ID + core.contentDiv.id)
);

return { ranges, isWholeTableSelected };
}

Expand Down
47 changes: 47 additions & 0 deletions packages/roosterjs-editor-core/test/coreApi/selectTableTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ describe('selectTable |', () => {
'> tr:nth-child(2)>TD:nth-child(1) * {background-color: rgb(198,198,198) !important; caret-color: transparent}',
STYLE_ID + div!.id
);
expect(setGlobalCssStyles.default).toHaveBeenCalledTimes(1);
});

it('Select TH and TR in the same row', () => {
Expand Down Expand Up @@ -152,6 +153,7 @@ describe('selectTable |', () => {
'> tr:nth-child(2)>TH:nth-child(1) * {background-color: rgb(198,198,198) !important; caret-color: transparent}',
STYLE_ID + div!.id
);
expect(setGlobalCssStyles.default).toHaveBeenCalledTimes(1);
});

it('Select Table Cells THEAD, TBODY', () => {
Expand Down Expand Up @@ -216,6 +218,7 @@ describe('selectTable |', () => {
'>TFOOT> tr:nth-child(1)>TD:nth-child(2) * {background-color: rgb(198,198,198) !important; caret-color: transparent}',
STYLE_ID + div!.id
);
expect(setGlobalCssStyles.default).toHaveBeenCalledTimes(1);
});

it('Select Table Cells THEAD, TBODY, TFOOT', () => {
Expand Down Expand Up @@ -264,6 +267,7 @@ describe('selectTable |', () => {
'>TFOOT> tr:nth-child(1)>TD:nth-child(2) * {background-color: rgb(198,198,198) !important; caret-color: transparent}',
STYLE_ID + div!.id
);
expect(setGlobalCssStyles.default).toHaveBeenCalledTimes(1);
});

it('Select Table Cells THEAD, TFOOT', () => {
Expand Down Expand Up @@ -296,6 +300,7 @@ describe('selectTable |', () => {
'>TFOOT> tr:nth-child(1)>TD:nth-child(2) * {background-color: rgb(198,198,198) !important; caret-color: transparent}',
STYLE_ID + div!.id
);
expect(setGlobalCssStyles.default).toHaveBeenCalledTimes(1);
});

it('Select All', () => {
Expand All @@ -320,6 +325,7 @@ describe('selectTable |', () => {
' * {background-color: rgb(198,198,198) !important; caret-color: transparent}',
STYLE_ID + div!.id
);
expect(setGlobalCssStyles.default).toHaveBeenCalledTimes(1);
});

it('remove duplicated ID', () => {
Expand All @@ -337,6 +343,20 @@ describe('selectTable |', () => {
});

expect(table.id).not.toEqual(table1.id);
expect(setGlobalCssStyles.default).toHaveBeenCalledTimes(1);
});

it('Select massive table', () => {
// 20x32
table = createTable(20, 32);
div?.appendChild(table);

selectTable(core, table, <TableSelection>{
firstCell: { x: 0, y: 0 },
lastCell: { x: 20, y: 31 },
});

expect(setGlobalCssStyles.default).toHaveBeenCalledTimes(7);
});
});

Expand Down Expand Up @@ -513,3 +533,30 @@ function buildTable(tbody: boolean, thead: boolean = false, tfoot: boolean = fal
document
) as HTMLTableElement;
}

function createTable(row: number, column: number) {
const children: CreateElementData[] = [];
for (let index = 0; index < row; index++) {
const row: CreateElementData = {
tag: 'TR',
children: [],
};

for (let cIndex = 0; cIndex < column; cIndex++) {
row.children?.push({
tag: 'TD',
children: ['test'],
});
}

children.push(row);
}

return createElement(
{
tag: 'table',
children,
},
document
) as HTMLTableElement;
}

0 comments on commit 8ee97a1

Please sign in to comment.