Make the theme colors use CSS custom properties.
This commit is contained in:
parent
38bca9721a
commit
abb09bc671
|
@ -69,6 +69,7 @@
|
||||||
"confirm",
|
"confirm",
|
||||||
"document",
|
"document",
|
||||||
"FileReader",
|
"FileReader",
|
||||||
|
"getComputedStyle",
|
||||||
"performance",
|
"performance",
|
||||||
"window"
|
"window"
|
||||||
],
|
],
|
||||||
|
|
|
@ -9,7 +9,6 @@ import {
|
||||||
isValidHexColor,
|
isValidHexColor,
|
||||||
setSettings
|
setSettings
|
||||||
} from './utilities';
|
} from './utilities';
|
||||||
import {themeColors} from './theme-colors';
|
|
||||||
|
|
||||||
export async function importSettingsHandler(event: MouseEvent): Promise<void> {
|
export async function importSettingsHandler(event: MouseEvent): Promise<void> {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -53,9 +52,7 @@ export async function importFileHandler(event: Event): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
newSettings.data.userLabels.push({
|
newSettings.data.userLabels.push({
|
||||||
color: isValidHexColor(label.color)
|
color: isValidHexColor(label.color) ? label.color : '#f0f',
|
||||||
? label.color
|
|
||||||
: themeColors.white.backgroundAlt,
|
|
||||||
id: newSettings.data.userLabels.length + 1,
|
id: newSettings.data.userLabels.length + 1,
|
||||||
priority: Number.isNaN(label.priority) ? 0 : label.priority,
|
priority: Number.isNaN(label.priority) ? 0 : label.priority,
|
||||||
text: typeof label.text === 'undefined' ? 'Label' : label.text,
|
text: typeof label.text === 'undefined' ? 'Label' : label.text,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {Except} from 'type-fest';
|
import {Except} from 'type-fest';
|
||||||
import debounce from 'debounce';
|
import debounce from 'debounce';
|
||||||
import {ColorKey, ThemeKey, themeColors} from '../theme-colors';
|
import {ColorKey, themeColors} from '../theme-colors';
|
||||||
import {
|
import {
|
||||||
getSettings,
|
getSettings,
|
||||||
Settings,
|
Settings,
|
||||||
|
@ -8,7 +8,7 @@ import {
|
||||||
createElementFromString,
|
createElementFromString,
|
||||||
UserLabel,
|
UserLabel,
|
||||||
isInTopicListing,
|
isInTopicListing,
|
||||||
getCurrentThemeKey,
|
getCSSCustomPropertyValue,
|
||||||
isColorBright,
|
isColorBright,
|
||||||
setSettings,
|
setSettings,
|
||||||
appendStyleAttribute,
|
appendStyleAttribute,
|
||||||
|
@ -28,16 +28,12 @@ import {
|
||||||
labelColorInputHandler
|
labelColorInputHandler
|
||||||
} from './user-labels/handlers';
|
} from './user-labels/handlers';
|
||||||
|
|
||||||
let theme: typeof themeColors[ThemeKey];
|
|
||||||
|
|
||||||
(async (): Promise<void> => {
|
(async (): Promise<void> => {
|
||||||
const settings: Settings = await getSettings();
|
const settings: Settings = await getSettings();
|
||||||
if (!settings.features.userLabels) {
|
if (!settings.features.userLabels) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const themeKey: ThemeKey = getCurrentThemeKey();
|
|
||||||
theme = themeColors[themeKey];
|
|
||||||
addLabelsToUsernames(settings);
|
addLabelsToUsernames(settings);
|
||||||
const existingLabelForm: HTMLElement | null = document.querySelector(
|
const existingLabelForm: HTMLElement | null = document.querySelector(
|
||||||
'#trx-user-label-form'
|
'#trx-user-label-form'
|
||||||
|
@ -47,10 +43,13 @@ let theme: typeof themeColors[ThemeKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
const themeSelectOptions: string[] = [];
|
const themeSelectOptions: string[] = [];
|
||||||
for (const color in theme) {
|
for (const color in themeColors) {
|
||||||
if (Object.hasOwnProperty.call(theme, color)) {
|
if (Object.hasOwnProperty.call(themeColors, color)) {
|
||||||
|
const colorValue = getCSSCustomPropertyValue(
|
||||||
|
themeColors[color as ColorKey]
|
||||||
|
);
|
||||||
themeSelectOptions.push(
|
themeSelectOptions.push(
|
||||||
`<option value="${theme[color as ColorKey]}">${color}</option>`
|
`<option value="${colorValue}">${color}</option>`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +87,8 @@ let theme: typeof themeColors[ThemeKey];
|
||||||
document.body.append(labelForm);
|
document.body.append(labelForm);
|
||||||
labelForm.setAttribute(
|
labelForm.setAttribute(
|
||||||
'style',
|
'style',
|
||||||
`background-color: ${theme.background}; border-color: ${theme.foregroundAlt};`
|
`background-color: var(${themeColors.backgroundPrimary});` +
|
||||||
|
`border-color: var(${themeColors.foregroundSecondary});`
|
||||||
);
|
);
|
||||||
|
|
||||||
const labelColorInput: HTMLInputElement = querySelector(
|
const labelColorInput: HTMLInputElement = querySelector(
|
||||||
|
@ -103,7 +103,9 @@ let theme: typeof themeColors[ThemeKey];
|
||||||
'#trx-user-label-form-color > select'
|
'#trx-user-label-form-color > select'
|
||||||
);
|
);
|
||||||
presetColorSelect.addEventListener('change', presetColorSelectHandler);
|
presetColorSelect.addEventListener('change', presetColorSelectHandler);
|
||||||
presetColorSelect.value = theme.backgroundAlt;
|
presetColorSelect.value = getCSSCustomPropertyValue(
|
||||||
|
themeColors.backgroundSecondary
|
||||||
|
);
|
||||||
|
|
||||||
const labelTextInput: HTMLInputElement = querySelector(
|
const labelTextInput: HTMLInputElement = querySelector(
|
||||||
'#trx-user-label-input > input'
|
'#trx-user-label-input > input'
|
||||||
|
@ -113,8 +115,8 @@ let theme: typeof themeColors[ThemeKey];
|
||||||
const labelPreview: HTMLDivElement = querySelector('#trx-user-label-preview');
|
const labelPreview: HTMLDivElement = querySelector('#trx-user-label-preview');
|
||||||
labelPreview.setAttribute(
|
labelPreview.setAttribute(
|
||||||
'style',
|
'style',
|
||||||
`background-color: ${theme.background};` +
|
`background-color: var(${themeColors.backgroundPrimary});` +
|
||||||
`border-color: ${theme.foregroundAlt};`
|
`border-color: var(${themeColors.foregroundSecondary});`
|
||||||
);
|
);
|
||||||
|
|
||||||
const formSaveButton: HTMLAnchorElement = querySelector(
|
const formSaveButton: HTMLAnchorElement = querySelector(
|
||||||
|
@ -201,7 +203,10 @@ function addLabelsToUsernames(settings: Settings): void {
|
||||||
);
|
);
|
||||||
if (!isInTopicListing()) {
|
if (!isInTopicListing()) {
|
||||||
element.insertAdjacentElement('afterend', addLabelSpan);
|
element.insertAdjacentElement('afterend', addLabelSpan);
|
||||||
appendStyleAttribute(addLabelSpan, `color: ${theme.foreground};`);
|
appendStyleAttribute(
|
||||||
|
addLabelSpan,
|
||||||
|
`color: var(${themeColors.foregroundPrimary});`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const userLabels: UserLabel[] = settings.data.userLabels.filter(
|
const userLabels: UserLabel[] = settings.data.userLabels.filter(
|
||||||
|
@ -214,7 +219,10 @@ function addLabelsToUsernames(settings: Settings): void {
|
||||||
!element.nextElementSibling.className.includes('trx-user-label'))
|
!element.nextElementSibling.className.includes('trx-user-label'))
|
||||||
) {
|
) {
|
||||||
element.insertAdjacentElement('afterend', addLabelSpan);
|
element.insertAdjacentElement('afterend', addLabelSpan);
|
||||||
appendStyleAttribute(addLabelSpan, `color: ${theme.foreground};`);
|
appendStyleAttribute(
|
||||||
|
addLabelSpan,
|
||||||
|
`color: var(${themeColors.foregroundPrimary});`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -248,7 +256,7 @@ function addLabelsToUsernames(settings: Settings): void {
|
||||||
'style',
|
'style',
|
||||||
`background-color: ${userLabel.color};`
|
`background-color: ${userLabel.color};`
|
||||||
);
|
);
|
||||||
if (isColorBright(userLabel.color)) {
|
if (isColorBright(userLabel.color.trim())) {
|
||||||
userLabelSpan.classList.add('trx-bright');
|
userLabelSpan.classList.add('trx-bright');
|
||||||
} else {
|
} else {
|
||||||
userLabelSpan.classList.remove('trx-bright');
|
userLabelSpan.classList.remove('trx-bright');
|
||||||
|
|
|
@ -2,11 +2,11 @@ import {
|
||||||
log,
|
log,
|
||||||
isValidHexColor,
|
isValidHexColor,
|
||||||
UserLabel,
|
UserLabel,
|
||||||
getCurrentThemeKey,
|
querySelector,
|
||||||
querySelector
|
getCSSCustomPropertyValue
|
||||||
} from '../../utilities';
|
} from '../../utilities';
|
||||||
import {findLabelByID} from '../user-labels';
|
import {findLabelByID} from '../user-labels';
|
||||||
import {themeColors, ThemeKey} from '../../theme-colors';
|
import {themeColors} from '../../theme-colors';
|
||||||
import {
|
import {
|
||||||
getLabelForm,
|
getLabelForm,
|
||||||
setLabelFormColor,
|
setLabelFormColor,
|
||||||
|
@ -19,8 +19,6 @@ import {
|
||||||
updatePreview
|
updatePreview
|
||||||
} from './label-form';
|
} from './label-form';
|
||||||
|
|
||||||
const theme: typeof themeColors[ThemeKey] = themeColors[getCurrentThemeKey()];
|
|
||||||
|
|
||||||
export function addLabelHandler(
|
export function addLabelHandler(
|
||||||
event: MouseEvent,
|
event: MouseEvent,
|
||||||
element: HTMLSpanElement
|
element: HTMLSpanElement
|
||||||
|
@ -30,7 +28,7 @@ export function addLabelHandler(
|
||||||
setLabelFormTitle('Add New Label');
|
setLabelFormTitle('Add New Label');
|
||||||
setLabelFormUsername(element.getAttribute('data-trx-username')!);
|
setLabelFormUsername(element.getAttribute('data-trx-username')!);
|
||||||
setLabelFormPriority(0);
|
setLabelFormPriority(0);
|
||||||
setLabelFormColor(theme.backgroundAlt);
|
setLabelFormColor(getCSSCustomPropertyValue(themeColors.backgroundSecondary));
|
||||||
setLabelFormText('');
|
setLabelFormText('');
|
||||||
showLabelForm(element);
|
showLabelForm(element);
|
||||||
updatePreview();
|
updatePreview();
|
||||||
|
|
|
@ -4,13 +4,10 @@ import {
|
||||||
UserLabel,
|
UserLabel,
|
||||||
log,
|
log,
|
||||||
isColorBright,
|
isColorBright,
|
||||||
getCurrentThemeKey,
|
|
||||||
querySelector,
|
querySelector,
|
||||||
isValidTildesUsername
|
isValidTildesUsername
|
||||||
} from '../../utilities';
|
} from '../../utilities';
|
||||||
import {themeColors, ThemeKey} from '../../theme-colors';
|
import {themeColors} from '../../theme-colors';
|
||||||
|
|
||||||
const theme: typeof themeColors[ThemeKey] = themeColors[getCurrentThemeKey()];
|
|
||||||
|
|
||||||
export function getLabelForm(): HTMLFormElement {
|
export function getLabelForm(): HTMLFormElement {
|
||||||
return querySelector('#trx-user-label-form');
|
return querySelector('#trx-user-label-form');
|
||||||
|
@ -134,11 +131,12 @@ export function updatePreview(color?: string, text?: string): void {
|
||||||
const labelPreview: HTMLDivElement = querySelector('#trx-user-label-preview');
|
const labelPreview: HTMLDivElement = querySelector('#trx-user-label-preview');
|
||||||
labelPreview.setAttribute(
|
labelPreview.setAttribute(
|
||||||
'style',
|
'style',
|
||||||
`background-color: ${color}; border-color: ${theme.foregroundAlt};`
|
`background-color: ${color}; ` +
|
||||||
|
`border-color: var(${themeColors.foregroundSecondary});`
|
||||||
);
|
);
|
||||||
labelPreview.firstElementChild!.textContent = text;
|
labelPreview.firstElementChild!.textContent = text;
|
||||||
|
|
||||||
if (isColorBright(color)) {
|
if (isColorBright(color.trim())) {
|
||||||
labelPreview.classList.add('trx-bright');
|
labelPreview.classList.add('trx-bright');
|
||||||
} else {
|
} else {
|
||||||
labelPreview.classList.remove('trx-bright');
|
labelPreview.classList.remove('trx-bright');
|
||||||
|
|
|
@ -1,113 +1,15 @@
|
||||||
export type ThemeKey = keyof typeof themeColors;
|
export type ColorKey = keyof typeof themeColors;
|
||||||
export type ColorKey = keyof typeof themeColors[ThemeKey];
|
|
||||||
|
|
||||||
export const themeColors = {
|
export const themeColors = {
|
||||||
atomOneDark: {
|
backgroundPrimary: '--background-primary-color',
|
||||||
background: '#282C34',
|
backgroundSecondary: '--background-secondary-color',
|
||||||
backgroundAlt: '#21242b',
|
foregroundPrimary: '--foreground-primary-color',
|
||||||
foreground: '#ABB2BF',
|
foregroundSecondary: '--foreground-secondary-color',
|
||||||
foregroundAlt: '#828997',
|
exemplary: '--comment-label-exemplary-color',
|
||||||
cyan: '#56B6C2',
|
offtopic: '--comment-label-offtopic-color',
|
||||||
blue: '#61AFEF',
|
joke: '--comment-label-joke-color',
|
||||||
purple: '#C678DD',
|
noise: '--comment-label-noise-color',
|
||||||
green: '#98C379',
|
malice: '--comment-label-malice-color',
|
||||||
red: '#E06C75',
|
mine: '--stripe-mine-color',
|
||||||
orange: '#D19A66'
|
official: '--alert-color'
|
||||||
},
|
|
||||||
black: {
|
|
||||||
background: '#000',
|
|
||||||
backgroundAlt: '#222',
|
|
||||||
foreground: '#ccc',
|
|
||||||
foregroundAlt: '#888',
|
|
||||||
cyan: '#2aa198',
|
|
||||||
blue: '#268bd2',
|
|
||||||
purple: '#6c71c4',
|
|
||||||
green: '#859900',
|
|
||||||
red: '#f00',
|
|
||||||
orange: '#b58900'
|
|
||||||
},
|
|
||||||
dracula: {
|
|
||||||
background: '#282a36',
|
|
||||||
backgroundAlt: '#44475a',
|
|
||||||
foreground: '#f8f8f2',
|
|
||||||
foregroundAlt: '#6272a4',
|
|
||||||
cyan: '#8be9fd',
|
|
||||||
blue: '#6272a4',
|
|
||||||
purple: '#bd93f9',
|
|
||||||
green: '#50fa7b',
|
|
||||||
red: '#ff5555',
|
|
||||||
orange: '#ffb86c'
|
|
||||||
},
|
|
||||||
gruvboxDark: {
|
|
||||||
background: '#282828',
|
|
||||||
backgroundAlt: '#3c3836',
|
|
||||||
foreground: '#fbf1c7',
|
|
||||||
foregroundAlt: '#ebdbb2',
|
|
||||||
cyan: '#689d6a',
|
|
||||||
blue: '#458588',
|
|
||||||
purple: '#b16286',
|
|
||||||
green: '#98971a',
|
|
||||||
red: '#fb4934',
|
|
||||||
orange: '#fabd2f'
|
|
||||||
},
|
|
||||||
gruvboxLight: {
|
|
||||||
background: '#fbf1c7',
|
|
||||||
backgroundAlt: '#ebdbb2',
|
|
||||||
foreground: '#282828',
|
|
||||||
foregroundAlt: '#3c3836',
|
|
||||||
cyan: '#689d6a',
|
|
||||||
blue: '#458588',
|
|
||||||
purple: '#b16286',
|
|
||||||
green: '#98971a',
|
|
||||||
red: '#fb4934',
|
|
||||||
orange: '#fabd2f'
|
|
||||||
},
|
|
||||||
solarizedLight: {
|
|
||||||
background: '#fdf6e3',
|
|
||||||
backgroundAlt: '#eee8d5',
|
|
||||||
foreground: '#657b83',
|
|
||||||
foregroundAlt: '#93a1a1',
|
|
||||||
cyan: '#2aa198',
|
|
||||||
blue: '#268bd2',
|
|
||||||
purple: '#6c71c4',
|
|
||||||
green: '#859900',
|
|
||||||
red: '#dc322f',
|
|
||||||
orange: '#cb4b16'
|
|
||||||
},
|
|
||||||
solarizedDark: {
|
|
||||||
background: '#002b36',
|
|
||||||
backgroundAlt: '#073642',
|
|
||||||
foreground: '#839496',
|
|
||||||
foregroundAlt: '#586e75',
|
|
||||||
cyan: '#2aa198',
|
|
||||||
blue: '#268bd2',
|
|
||||||
purple: '#6c71c4',
|
|
||||||
green: '#859900',
|
|
||||||
red: '#dc322f',
|
|
||||||
orange: '#cb4b16'
|
|
||||||
},
|
|
||||||
white: {
|
|
||||||
background: '#fff',
|
|
||||||
backgroundAlt: '#eee',
|
|
||||||
foreground: '#333',
|
|
||||||
foregroundAlt: '#888',
|
|
||||||
cyan: '#1e824c',
|
|
||||||
blue: '#1460aa',
|
|
||||||
purple: '#551a8b',
|
|
||||||
green: '#4b6319',
|
|
||||||
red: '#d91e18',
|
|
||||||
orange: '#e66b00'
|
|
||||||
},
|
|
||||||
zenburn: {
|
|
||||||
background: '#3f3f3f',
|
|
||||||
backgroundAlt: '#4f4f4f',
|
|
||||||
foreground: '#dcdccc',
|
|
||||||
foregroundAlt: '#aaa',
|
|
||||||
cyan: '#8cd0d3',
|
|
||||||
blue: '#80d4aa',
|
|
||||||
purple: '#bc8cbc',
|
|
||||||
green: '#7f9f7f',
|
|
||||||
red: '#dc8c6c',
|
|
||||||
orange: '#efef8f'
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import {browser, Manifest} from 'webextension-polyfill-ts';
|
import {browser, Manifest} from 'webextension-polyfill-ts';
|
||||||
import {themeColors, ThemeKey} from './theme-colors';
|
|
||||||
|
|
||||||
export interface UserLabel {
|
export interface UserLabel {
|
||||||
color: string;
|
color: string;
|
||||||
|
@ -171,31 +170,8 @@ export function getManifest(): {nodeEnv?: string} & Manifest.ManifestBase {
|
||||||
return {...manifest};
|
return {...manifest};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCurrentThemeKey(): ThemeKey {
|
export function getCSSCustomPropertyValue(property: string): string {
|
||||||
const body: HTMLBodyElement = querySelector('body');
|
return getComputedStyle(document.body).getPropertyValue(property);
|
||||||
const classes: string | null = body.getAttribute('class');
|
|
||||||
if (classes === null || !classes.includes('theme-')) {
|
|
||||||
return 'white';
|
|
||||||
}
|
|
||||||
|
|
||||||
const themeIndex: number = classes.indexOf('theme-');
|
|
||||||
const themeKey: ThemeKey = kebabToCamel(
|
|
||||||
classes.slice(
|
|
||||||
themeIndex + 'theme-'.length,
|
|
||||||
classes.includes(' ', themeIndex)
|
|
||||||
? classes.indexOf(' ', themeIndex)
|
|
||||||
: classes.length
|
|
||||||
)
|
|
||||||
) as ThemeKey;
|
|
||||||
if (typeof themeColors[themeKey] === 'undefined') {
|
|
||||||
log(
|
|
||||||
`Attempted to retrieve theme key that's not defined: "${themeKey}" Using the white theme as fallback.`,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
return 'white';
|
|
||||||
}
|
|
||||||
|
|
||||||
return themeKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adapted from https://stackoverflow.com/a/12043228/12251171.
|
// Adapted from https://stackoverflow.com/a/12043228/12251171.
|
||||||
|
|
Loading…
Reference in New Issue