]> source.dussan.org Git - gitea.git/commitdiff
Always pass 6-digit hex color to monaco (#25780)
authorsilverwind <me@silverwind.io>
Sun, 9 Jul 2023 10:17:22 +0000 (12:17 +0200)
committerGitHub <noreply@github.com>
Sun, 9 Jul 2023 10:17:22 +0000 (12:17 +0200)
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: https://github.com/go-gitea/gitea/issues/25770
package-lock.json
package.json
web_src/js/components/ContextPopup.vue
web_src/js/features/codeeditor.js
web_src/js/features/repo-projects.js
web_src/js/utils/color.js
web_src/js/utils/color.test.js

index 25c2ab74a93e8bcea44aa1d6460527d5bdb070b5..92e4087b084950a338526d7e8ffef326b064a4b0 100644 (file)
@@ -41,6 +41,7 @@
         "sortablejs": "1.15.0",
         "swagger-ui-dist": "5.1.0",
         "throttle-debounce": "5.0.0",
+        "tinycolor2": "1.6.0",
         "tippy.js": "6.3.7",
         "toastify-js": "1.12.0",
         "tributejs": "5.1.3",
       "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==",
       "dev": true
     },
+    "node_modules/tinycolor2": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz",
+      "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="
+    },
     "node_modules/tinypool": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.6.0.tgz",
index 7aefa71c4312e62716b1f9c7f56343461b63fd0c..10956595b68912135f6d6c86faf6ad042b8fc0a7 100644 (file)
@@ -40,6 +40,7 @@
     "sortablejs": "1.15.0",
     "swagger-ui-dist": "5.1.0",
     "throttle-debounce": "5.0.0",
+    "tinycolor2": "1.6.0",
     "tippy.js": "6.3.7",
     "toastify-js": "1.12.0",
     "tributejs": "5.1.3",
index 420c271fcccee92f074d4c1f06d090c760169706..b6852655f6c4b44bc6ff5b44bd2d086bb7afe698 100644 (file)
@@ -26,7 +26,8 @@
 <script>
 import $ from 'jquery';
 import {SvgIcon} from '../svg.js';
-import {useLightTextOnBackground, hexToRGBColor} from '../utils/color.js';
+import {useLightTextOnBackground} from '../utils/color.js';
+import tinycolor from 'tinycolor2';
 
 const {appSubUrl, i18n} = window.config;
 
@@ -77,7 +78,7 @@ export default {
     labels() {
       return this.issue.labels.map((label) => {
         let textColor;
-        const [r, g, b] = hexToRGBColor(label.color);
+        const {r, g, b} = tinycolor(label.color).toRgb();
         if (useLightTextOnBackground(r, g, b)) {
           textColor = '#eeeeee';
         } else {
index 76eeaa9898d4da624b659adeef6e99b8bce09da7..7dbbcd3dd62a9b5c2fa2bc792a2f9938a9e30f76 100644 (file)
@@ -1,3 +1,4 @@
+import tinycolor from 'tinycolor2';
 import {basename, extname, isObject, isDarkTheme} from '../utils.js';
 import {onInputDebounce} from '../utils/dom.js';
 
@@ -69,33 +70,34 @@ export async function createMonaco(textarea, filename, editorOpts) {
   textarea.parentNode.append(container);
 
   // https://github.com/microsoft/monaco-editor/issues/2427
+  // also, monaco can only parse 6-digit hex colors, so we convert the colors to that format
   const styles = window.getComputedStyle(document.documentElement);
-  const getProp = (name) => styles.getPropertyValue(name).trim();
+  const getColor = (name) => tinycolor(styles.getPropertyValue(name).trim()).toString('hex6');
 
   monaco.editor.defineTheme('gitea', {
     base: isDarkTheme() ? 'vs-dark' : 'vs',
     inherit: true,
     rules: [
       {
-        background: getProp('--color-code-bg'),
+        background: getColor('--color-code-bg'),
       }
     ],
     colors: {
-      'editor.background': getProp('--color-code-bg'),
-      'editor.foreground': getProp('--color-text'),
-      'editor.inactiveSelectionBackground': getProp('--color-primary-light-4'),
-      'editor.lineHighlightBackground': getProp('--color-editor-line-highlight'),
-      'editor.selectionBackground': getProp('--color-primary-light-3'),
-      'editor.selectionForeground': getProp('--color-primary-light-3'),
-      'editorLineNumber.background': getProp('--color-code-bg'),
-      'editorLineNumber.foreground': getProp('--color-secondary-dark-6'),
-      'editorWidget.background': getProp('--color-body'),
-      'editorWidget.border': getProp('--color-secondary'),
-      'input.background': getProp('--color-input-background'),
-      'input.border': getProp('--color-input-border'),
-      'input.foreground': getProp('--color-input-text'),
-      'scrollbar.shadow': getProp('--color-shadow'),
-      'progressBar.background': getProp('--color-primary'),
+      'editor.background': getColor('--color-code-bg'),
+      'editor.foreground': getColor('--color-text'),
+      'editor.inactiveSelectionBackground': getColor('--color-primary-light-4'),
+      'editor.lineHighlightBackground': getColor('--color-editor-line-highlight'),
+      'editor.selectionBackground': getColor('--color-primary-light-3'),
+      'editor.selectionForeground': getColor('--color-primary-light-3'),
+      'editorLineNumber.background': getColor('--color-code-bg'),
+      'editorLineNumber.foreground': getColor('--color-secondary-dark-6'),
+      'editorWidget.background': getColor('--color-body'),
+      'editorWidget.border': getColor('--color-secondary'),
+      'input.background': getColor('--color-input-background'),
+      'input.border': getColor('--color-input-border'),
+      'input.foreground': getColor('--color-input-text'),
+      'scrollbar.shadow': getColor('--color-shadow'),
+      'progressBar.background': getColor('--color-primary'),
     }
   });
 
index 82814ec8b6b0a2943cd583e062f1b800db1ae0be..b1f419a21d6f006dc9f90ac071c807f2f0394916 100644 (file)
@@ -1,5 +1,6 @@
 import $ from 'jquery';
-import {useLightTextOnBackground, hexToRGBColor} from '../utils/color.js';
+import {useLightTextOnBackground} from '../utils/color.js';
+import tinycolor from 'tinycolor2';
 
 const {csrfToken} = window.config;
 
@@ -210,7 +211,7 @@ export function initRepoProject() {
 }
 
 function setLabelColor(label, color) {
-  const [r, g, b] = hexToRGBColor(color);
+  const {r, g, b} = tinycolor(color).toRgb();
   if (useLightTextOnBackground(r, g, b)) {
     label.removeClass('dark-label').addClass('light-label');
   } else {
index 389e2d095f019e819354fda4ec1a3a03ed377992..5d9c4ca45dfd2663fa392c40410d275a62735250 100644 (file)
@@ -13,27 +13,6 @@ function getLuminance(r, g, b) {
   return 0.2126 * R + 0.7152 * G + 0.0722 * B;
 }
 
-// Get color as RGB values in 0..255 range from the hex color string (with or without #)
-export function hexToRGBColor(backgroundColorStr) {
-  let backgroundColor = backgroundColorStr;
-  if (backgroundColorStr[0] === '#') {
-    backgroundColor = backgroundColorStr.substring(1);
-  }
-  // only support transfer of rgb, rgba, rrggbb and rrggbbaa
-  // if not in these formats, use default values 0, 0, 0
-  if (![3, 4, 6, 8].includes(backgroundColor.length)) {
-    return [0, 0, 0];
-  }
-  if ([3, 4].includes(backgroundColor.length)) {
-    const [r, g, b] = backgroundColor;
-    backgroundColor = `${r}${r}${g}${g}${b}${b}`;
-  }
-  const r = parseInt(backgroundColor.substring(0, 2), 16);
-  const g = parseInt(backgroundColor.substring(2, 4), 16);
-  const b = parseInt(backgroundColor.substring(4, 6), 16);
-  return [r, g, b];
-}
-
 // Reference from: https://firsching.ch/github_labels.html
 // In the future WCAG 3 APCA may be a better solution.
 // Check if text should use light color based on RGB of background
index 592e93b0f2325f4f552f461c2a64866e46929179..7d45d191a0919f175b12e44c231170da07affd7b 100644 (file)
@@ -1,17 +1,5 @@
 import {test, expect} from 'vitest';
-import {hexToRGBColor, useLightTextOnBackground} from './color.js';
-
-test('hexToRGBColor', () => {
-  expect(hexToRGBColor('2b8685')).toEqual([43, 134, 133]);
-  expect(hexToRGBColor('1e1')).toEqual([17, 238, 17]);
-  expect(hexToRGBColor('#1e1')).toEqual([17, 238, 17]);
-  expect(hexToRGBColor('1e16')).toEqual([17, 238, 17]);
-  expect(hexToRGBColor('3bb6b3')).toEqual([59, 182, 179]);
-  expect(hexToRGBColor('#3bb6b399')).toEqual([59, 182, 179]);
-  expect(hexToRGBColor('#0')).toEqual([0, 0, 0]);
-  expect(hexToRGBColor('#00000')).toEqual([0, 0, 0]);
-  expect(hexToRGBColor('#1234567')).toEqual([0, 0, 0]);
-});
+import {useLightTextOnBackground} from './color.js';
 
 test('useLightTextOnBackground', () => {
   expect(useLightTextOnBackground(215, 58, 74)).toBe(true);