Skip to content

Commit 38844e0

Browse files
authoredJul 9, 2023
Always pass 6-digit hex color to monaco (#25780)
Monaco can not deal with color formats other than 6-digit hex, so we convert the colors for it via new [`tinycolor2`](https://github.com/bgrins/TinyColor) dependency (5kB minzipped). Also, with the addition of the module, we can replace the existing `hexToRGBColor` usage, I verified it is compatible with the current tests before removing the function. Fixes: #25770
1 parent d58096e commit 38844e0

File tree

7 files changed

+33
-55
lines changed

7 files changed

+33
-55
lines changed
 

‎package-lock.json

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"sortablejs": "1.15.0",
4141
"swagger-ui-dist": "5.1.0",
4242
"throttle-debounce": "5.0.0",
43+
"tinycolor2": "1.6.0",
4344
"tippy.js": "6.3.7",
4445
"toastify-js": "1.12.0",
4546
"tributejs": "5.1.3",

‎web_src/js/components/ContextPopup.vue

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
<script>
2727
import $ from 'jquery';
2828
import {SvgIcon} from '../svg.js';
29-
import {useLightTextOnBackground, hexToRGBColor} from '../utils/color.js';
29+
import {useLightTextOnBackground} from '../utils/color.js';
30+
import tinycolor from 'tinycolor2';
3031
3132
const {appSubUrl, i18n} = window.config;
3233
@@ -77,7 +78,7 @@ export default {
7778
labels() {
7879
return this.issue.labels.map((label) => {
7980
let textColor;
80-
const [r, g, b] = hexToRGBColor(label.color);
81+
const {r, g, b} = tinycolor(label.color).toRgb();
8182
if (useLightTextOnBackground(r, g, b)) {
8283
textColor = '#eeeeee';
8384
} else {

‎web_src/js/features/codeeditor.js

+19-17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import tinycolor from 'tinycolor2';
12
import {basename, extname, isObject, isDarkTheme} from '../utils.js';
23
import {onInputDebounce} from '../utils/dom.js';
34

@@ -69,33 +70,34 @@ export async function createMonaco(textarea, filename, editorOpts) {
6970
textarea.parentNode.append(container);
7071

7172
// https://github.com/microsoft/monaco-editor/issues/2427
73+
// also, monaco can only parse 6-digit hex colors, so we convert the colors to that format
7274
const styles = window.getComputedStyle(document.documentElement);
73-
const getProp = (name) => styles.getPropertyValue(name).trim();
75+
const getColor = (name) => tinycolor(styles.getPropertyValue(name).trim()).toString('hex6');
7476

7577
monaco.editor.defineTheme('gitea', {
7678
base: isDarkTheme() ? 'vs-dark' : 'vs',
7779
inherit: true,
7880
rules: [
7981
{
80-
background: getProp('--color-code-bg'),
82+
background: getColor('--color-code-bg'),
8183
}
8284
],
8385
colors: {
84-
'editor.background': getProp('--color-code-bg'),
85-
'editor.foreground': getProp('--color-text'),
86-
'editor.inactiveSelectionBackground': getProp('--color-primary-light-4'),
87-
'editor.lineHighlightBackground': getProp('--color-editor-line-highlight'),
88-
'editor.selectionBackground': getProp('--color-primary-light-3'),
89-
'editor.selectionForeground': getProp('--color-primary-light-3'),
90-
'editorLineNumber.background': getProp('--color-code-bg'),
91-
'editorLineNumber.foreground': getProp('--color-secondary-dark-6'),
92-
'editorWidget.background': getProp('--color-body'),
93-
'editorWidget.border': getProp('--color-secondary'),
94-
'input.background': getProp('--color-input-background'),
95-
'input.border': getProp('--color-input-border'),
96-
'input.foreground': getProp('--color-input-text'),
97-
'scrollbar.shadow': getProp('--color-shadow'),
98-
'progressBar.background': getProp('--color-primary'),
86+
'editor.background': getColor('--color-code-bg'),
87+
'editor.foreground': getColor('--color-text'),
88+
'editor.inactiveSelectionBackground': getColor('--color-primary-light-4'),
89+
'editor.lineHighlightBackground': getColor('--color-editor-line-highlight'),
90+
'editor.selectionBackground': getColor('--color-primary-light-3'),
91+
'editor.selectionForeground': getColor('--color-primary-light-3'),
92+
'editorLineNumber.background': getColor('--color-code-bg'),
93+
'editorLineNumber.foreground': getColor('--color-secondary-dark-6'),
94+
'editorWidget.background': getColor('--color-body'),
95+
'editorWidget.border': getColor('--color-secondary'),
96+
'input.background': getColor('--color-input-background'),
97+
'input.border': getColor('--color-input-border'),
98+
'input.foreground': getColor('--color-input-text'),
99+
'scrollbar.shadow': getColor('--color-shadow'),
100+
'progressBar.background': getColor('--color-primary'),
99101
}
100102
});
101103

‎web_src/js/features/repo-projects.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import $ from 'jquery';
2-
import {useLightTextOnBackground, hexToRGBColor} from '../utils/color.js';
2+
import {useLightTextOnBackground} from '../utils/color.js';
3+
import tinycolor from 'tinycolor2';
34

45
const {csrfToken} = window.config;
56

@@ -210,7 +211,7 @@ export function initRepoProject() {
210211
}
211212

212213
function setLabelColor(label, color) {
213-
const [r, g, b] = hexToRGBColor(color);
214+
const {r, g, b} = tinycolor(color).toRgb();
214215
if (useLightTextOnBackground(r, g, b)) {
215216
label.removeClass('dark-label').addClass('light-label');
216217
} else {

‎web_src/js/utils/color.js

-21
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,6 @@ function getLuminance(r, g, b) {
1313
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
1414
}
1515

16-
// Get color as RGB values in 0..255 range from the hex color string (with or without #)
17-
export function hexToRGBColor(backgroundColorStr) {
18-
let backgroundColor = backgroundColorStr;
19-
if (backgroundColorStr[0] === '#') {
20-
backgroundColor = backgroundColorStr.substring(1);
21-
}
22-
// only support transfer of rgb, rgba, rrggbb and rrggbbaa
23-
// if not in these formats, use default values 0, 0, 0
24-
if (![3, 4, 6, 8].includes(backgroundColor.length)) {
25-
return [0, 0, 0];
26-
}
27-
if ([3, 4].includes(backgroundColor.length)) {
28-
const [r, g, b] = backgroundColor;
29-
backgroundColor = `${r}${r}${g}${g}${b}${b}`;
30-
}
31-
const r = parseInt(backgroundColor.substring(0, 2), 16);
32-
const g = parseInt(backgroundColor.substring(2, 4), 16);
33-
const b = parseInt(backgroundColor.substring(4, 6), 16);
34-
return [r, g, b];
35-
}
36-
3716
// Reference from: https://firsching.ch/github_labels.html
3817
// In the future WCAG 3 APCA may be a better solution.
3918
// Check if text should use light color based on RGB of background

‎web_src/js/utils/color.test.js

+1-13
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
11
import {test, expect} from 'vitest';
2-
import {hexToRGBColor, useLightTextOnBackground} from './color.js';
3-
4-
test('hexToRGBColor', () => {
5-
expect(hexToRGBColor('2b8685')).toEqual([43, 134, 133]);
6-
expect(hexToRGBColor('1e1')).toEqual([17, 238, 17]);
7-
expect(hexToRGBColor('#1e1')).toEqual([17, 238, 17]);
8-
expect(hexToRGBColor('1e16')).toEqual([17, 238, 17]);
9-
expect(hexToRGBColor('3bb6b3')).toEqual([59, 182, 179]);
10-
expect(hexToRGBColor('#3bb6b399')).toEqual([59, 182, 179]);
11-
expect(hexToRGBColor('#0')).toEqual([0, 0, 0]);
12-
expect(hexToRGBColor('#00000')).toEqual([0, 0, 0]);
13-
expect(hexToRGBColor('#1234567')).toEqual([0, 0, 0]);
14-
});
2+
import {useLightTextOnBackground} from './color.js';
153

164
test('useLightTextOnBackground', () => {
175
expect(useLightTextOnBackground(215, 58, 74)).toBe(true);

0 commit comments

Comments
 (0)
Please sign in to comment.