Skip to content

Commit 286d52f

Browse files
committed
fix table header color
1 parent febf50f commit 286d52f

File tree

2 files changed

+197
-26
lines changed

2 files changed

+197
-26
lines changed

packages/roosterjs-content-model-dom/lib/modelApi/editing/setTableCellBackgroundColor.ts

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function setTableCellBackgroundColor(
4646
}
4747

4848
if (applyToSegments) {
49-
setAdaptiveCellColor(cell);
49+
setAdaptiveCellColor(cell, color);
5050
}
5151
} else {
5252
delete cell.format.backgroundColor;
@@ -64,14 +64,16 @@ function removeAdaptiveCellColor(cell: ShallowMutableContentModelTableCell) {
6464

6565
if (
6666
block.segmentFormat?.textColor &&
67-
shouldRemoveColor(block.segmentFormat?.textColor, cell.format.backgroundColor || '')
67+
(isSameColor(block.segmentFormat.textColor, White) ||
68+
isSameColor(block.segmentFormat.textColor, Black))
6869
) {
6970
delete block.segmentFormat.textColor;
7071
}
7172
block.segments.forEach(segment => {
7273
if (
7374
segment.format.textColor &&
74-
shouldRemoveColor(segment.format.textColor, cell.format.backgroundColor || '')
75+
(isSameColor(segment.format.textColor, White) ||
76+
isSameColor(segment.format.textColor, Black))
7577
) {
7678
delete segment.format.textColor;
7779
}
@@ -80,20 +82,26 @@ function removeAdaptiveCellColor(cell: ShallowMutableContentModelTableCell) {
8082
});
8183
}
8284

83-
function setAdaptiveCellColor(cell: ShallowMutableContentModelTableCell) {
85+
function setAdaptiveCellColor(cell: ShallowMutableContentModelTableCell, backgroundColor: string) {
8486
if (cell.format.textColor) {
8587
cell.blocks.forEach(readonlyBlock => {
8688
if (readonlyBlock.blockType == 'Paragraph') {
8789
const block = mutateBlock(readonlyBlock);
8890

89-
if (!block.segmentFormat?.textColor) {
91+
if (
92+
!block.segmentFormat?.textColor ||
93+
isSameColor(backgroundColor, block.segmentFormat.textColor)
94+
) {
9095
block.segmentFormat = {
9196
...block.segmentFormat,
9297
textColor: cell.format.textColor,
9398
};
9499
}
95100
block.segments.forEach(segment => {
96-
if (!segment.format?.textColor) {
101+
if (
102+
!segment.format?.textColor ||
103+
isSameColor(backgroundColor, segment.format.textColor)
104+
) {
97105
segment.format = {
98106
...segment.format,
99107
textColor: cell.format.textColor,
@@ -105,25 +113,6 @@ function setAdaptiveCellColor(cell: ShallowMutableContentModelTableCell) {
105113
}
106114
}
107115

108-
/**
109-
* If the cell background color is too dark or too bright, and the text color is white or black, we should remove the text color
110-
* @param textColor the segment or block text color
111-
* @param cellBackgroundColor the cell background color
112-
* @returns
113-
*/
114-
function shouldRemoveColor(textColor: string, cellBackgroundColor: string) {
115-
const lightness = calculateLightness(cellBackgroundColor);
116-
if (
117-
([White, 'rgb(255,255,255)'].indexOf(textColor) > -1 &&
118-
(lightness > BRIGHT_COLORS_LIGHTNESS || cellBackgroundColor == '')) ||
119-
([Black, 'rgb(0,0,0)'].indexOf(textColor) > -1 &&
120-
(lightness < DARK_COLORS_LIGHTNESS || cellBackgroundColor == ''))
121-
) {
122-
return true;
123-
}
124-
return false;
125-
}
126-
127116
function calculateLightness(color: string) {
128117
const colorValues = parseColor(color);
129118

@@ -140,3 +129,16 @@ function calculateLightness(color: string) {
140129
return 255;
141130
}
142131
}
132+
133+
/**
134+
* Check if two colors are the same by comparing their RGB values
135+
*/
136+
function isSameColor(color1: string, color2: string): boolean {
137+
const rgb1 = parseColor(color1);
138+
const rgb2 = parseColor(color2);
139+
140+
if (rgb1 && rgb2) {
141+
return rgb1[0] === rgb2[0] && rgb1[1] === rgb2[1] && rgb1[2] === rgb2[2];
142+
}
143+
return false;
144+
}

packages/roosterjs-content-model-dom/test/modelApi/editing/setTableCellBackgroundColorTest.ts

Lines changed: 170 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createTableCell } from 'roosterjs-content-model-dom';
1+
import { createParagraph, createTableCell, createText } from 'roosterjs-content-model-dom';
22
import { setTableCellBackgroundColor } from '../../../lib/modelApi/editing/setTableCellBackgroundColor';
33

44
describe('setTableCellBackgroundColor', () => {
@@ -124,4 +124,173 @@ describe('setTableCellBackgroundColor', () => {
124124
blocks: [],
125125
});
126126
});
127+
128+
it('Set dark background color with applyToSegments - should apply white text to segments', () => {
129+
const paragraph = createParagraph();
130+
const text = createText('test');
131+
paragraph.segments.push(text);
132+
133+
const cell = createTableCell(1, 1, false);
134+
cell.blocks.push(paragraph);
135+
136+
setTableCellBackgroundColor(cell, '#000000', false, true);
137+
138+
expect(cell.format.backgroundColor).toBe('#000000');
139+
expect(cell.format.textColor).toBe('#ffffff');
140+
expect(paragraph.segmentFormat?.textColor).toBe('#ffffff');
141+
expect(text.format.textColor).toBe('#ffffff');
142+
});
143+
144+
it('Set bright background color with applyToSegments - should apply black text to segments', () => {
145+
const paragraph = createParagraph();
146+
const text = createText('test');
147+
paragraph.segments.push(text);
148+
149+
const cell = createTableCell(1, 1, false);
150+
cell.blocks.push(paragraph);
151+
152+
setTableCellBackgroundColor(cell, '#ffffff', false, true);
153+
154+
expect(cell.format.backgroundColor).toBe('#ffffff');
155+
expect(cell.format.textColor).toBe('#000000');
156+
expect(paragraph.segmentFormat?.textColor).toBe('#000000');
157+
expect(text.format.textColor).toBe('#000000');
158+
});
159+
160+
it('Set dark background with applyToSegments - should not override existing text color', () => {
161+
const paragraph = createParagraph();
162+
const text = createText('test', { textColor: 'red' });
163+
paragraph.segments.push(text);
164+
165+
const cell = createTableCell(1, 1, false);
166+
cell.blocks.push(paragraph);
167+
168+
setTableCellBackgroundColor(cell, '#000000', false, true);
169+
170+
expect(cell.format.backgroundColor).toBe('#000000');
171+
expect(cell.format.textColor).toBe('#ffffff');
172+
expect(text.format.textColor).toBe('red');
173+
});
174+
175+
it('Set dark background with applyToSegments - should override text color if same as background', () => {
176+
const paragraph = createParagraph();
177+
const text = createText('test', { textColor: '#000000' });
178+
paragraph.segments.push(text);
179+
180+
const cell = createTableCell(1, 1, false);
181+
cell.blocks.push(paragraph);
182+
183+
setTableCellBackgroundColor(cell, '#000000', false, true);
184+
185+
expect(cell.format.backgroundColor).toBe('#000000');
186+
expect(cell.format.textColor).toBe('#ffffff');
187+
expect(text.format.textColor).toBe('#ffffff');
188+
});
189+
190+
it('Set bright background with applyToSegments - should override text color if same as background (rgb format)', () => {
191+
const paragraph = createParagraph();
192+
const text = createText('test', { textColor: 'rgb(255, 255, 255)' });
193+
paragraph.segments.push(text);
194+
195+
const cell = createTableCell(1, 1, false);
196+
cell.blocks.push(paragraph);
197+
198+
setTableCellBackgroundColor(cell, '#ffffff', false, true);
199+
200+
expect(cell.format.backgroundColor).toBe('#ffffff');
201+
expect(cell.format.textColor).toBe('#000000');
202+
expect(text.format.textColor).toBe('#000000');
203+
});
204+
205+
it('Remove background color with applyToSegments - should remove white text color from segments', () => {
206+
const paragraph = createParagraph(false, {}, { textColor: '#ffffff' });
207+
const text = createText('test', { textColor: '#ffffff' });
208+
paragraph.segments.push(text);
209+
210+
const cell = createTableCell(1, 1, false, {
211+
backgroundColor: '#000000',
212+
textColor: '#ffffff',
213+
});
214+
cell.blocks.push(paragraph);
215+
216+
setTableCellBackgroundColor(cell, null, false, true);
217+
218+
expect(cell.format.backgroundColor).toBeUndefined();
219+
expect(cell.format.textColor).toBeUndefined();
220+
expect(paragraph.segmentFormat?.textColor).toBeUndefined();
221+
expect(text.format.textColor).toBeUndefined();
222+
});
223+
224+
it('Remove background color with applyToSegments - should remove black text color from segments', () => {
225+
const paragraph = createParagraph(false, {}, { textColor: '#000000' });
226+
const text = createText('test', { textColor: '#000000' });
227+
paragraph.segments.push(text);
228+
229+
const cell = createTableCell(1, 1, false, {
230+
backgroundColor: '#ffffff',
231+
textColor: '#000000',
232+
});
233+
cell.blocks.push(paragraph);
234+
235+
setTableCellBackgroundColor(cell, null, false, true);
236+
237+
expect(cell.format.backgroundColor).toBeUndefined();
238+
expect(cell.format.textColor).toBeUndefined();
239+
expect(paragraph.segmentFormat?.textColor).toBeUndefined();
240+
expect(text.format.textColor).toBeUndefined();
241+
});
242+
243+
it('Remove background color with applyToSegments - should remove rgb white text color from segments', () => {
244+
const paragraph = createParagraph(false, {}, { textColor: 'rgb(255, 255, 255)' });
245+
const text = createText('test', { textColor: 'rgb(255,255,255)' });
246+
paragraph.segments.push(text);
247+
248+
const cell = createTableCell(1, 1, false, {
249+
backgroundColor: '#000000',
250+
textColor: '#ffffff',
251+
});
252+
cell.blocks.push(paragraph);
253+
254+
setTableCellBackgroundColor(cell, null, false, true);
255+
256+
expect(cell.format.backgroundColor).toBeUndefined();
257+
expect(cell.format.textColor).toBeUndefined();
258+
expect(paragraph.segmentFormat?.textColor).toBeUndefined();
259+
expect(text.format.textColor).toBeUndefined();
260+
});
261+
262+
it('Remove background color with applyToSegments - should not remove non-adaptive text colors', () => {
263+
const paragraph = createParagraph(false, {}, { textColor: 'red' });
264+
const text = createText('test', { textColor: 'blue' });
265+
paragraph.segments.push(text);
266+
267+
const cell = createTableCell(1, 1, false, {
268+
backgroundColor: '#000000',
269+
textColor: '#ffffff',
270+
});
271+
cell.blocks.push(paragraph);
272+
273+
setTableCellBackgroundColor(cell, null, false, true);
274+
275+
expect(cell.format.backgroundColor).toBeUndefined();
276+
expect(cell.format.textColor).toBeUndefined();
277+
expect(paragraph.segmentFormat?.textColor).toBe('red');
278+
expect(text.format.textColor).toBe('blue');
279+
});
280+
281+
it('Set medium lightness background - should not apply text color to segments', () => {
282+
const paragraph = createParagraph();
283+
const text = createText('test');
284+
paragraph.segments.push(text);
285+
286+
const cell = createTableCell(1, 1, false);
287+
cell.blocks.push(paragraph);
288+
289+
setTableCellBackgroundColor(cell, '#808080', false, true);
290+
291+
expect(cell.format.backgroundColor).toBe('#808080');
292+
expect(cell.format.textColor).toBeUndefined();
293+
expect(paragraph.segmentFormat?.textColor).toBeUndefined();
294+
expect(text.format.textColor).toBeUndefined();
295+
});
127296
});

0 commit comments

Comments
 (0)