Add: toggle dark/night mode styles automatically (#736)
* Add: color-scheme.js * Add: handle color scheme * Add: styleManager.setMeta * Add: make setupLivePrefs work with radio * Change: drop setupRadioButtons * Add: UI for schemeSwitcher * Add: prefer-scheme select in installation page * Fix: add alarm listener * Add: display excluded reason in popup * Fix: rely on data-value-type instead of input name * Fix: oldValue and newValue should have the same type * Change: detect media change in content script * Fix: duplicate capitalize * Fix: minor * Update web-ext * Fix: valueAsNumber doesn't work for all inputs * Fix: disable colorscheme selection after install * Fix: API error
This commit is contained in:
parent
19ebeedf6a
commit
6c13db1468
|
@ -596,6 +596,18 @@
|
|||
"message": "Update style",
|
||||
"description": "Label for update button"
|
||||
},
|
||||
"installPreferSchemeLabel": {
|
||||
"message": "The style should be applied:"
|
||||
},
|
||||
"installPreferSchemeNone": {
|
||||
"message": "Always"
|
||||
},
|
||||
"installPreferSchemeDark": {
|
||||
"message": "In Dark Mode"
|
||||
},
|
||||
"installPreferSchemeLight": {
|
||||
"message": "In Light Mode"
|
||||
},
|
||||
"installUpdate": {
|
||||
"message": "Install update",
|
||||
"description": "Label for the button to install an update for a single style"
|
||||
|
@ -1053,6 +1065,18 @@
|
|||
"optionsAdvancedNewStyleAsUsercss": {
|
||||
"message": "Write new style as usercss"
|
||||
},
|
||||
"optionsAdvancedAutoSwitchScheme": {
|
||||
"message": "Toggle Light/Dark Mode styles automatically"
|
||||
},
|
||||
"optionsAdvancedAutoSwitchSchemeNever": {
|
||||
"message": "Never"
|
||||
},
|
||||
"optionsAdvancedAutoSwitchSchemeBySystem": {
|
||||
"message": "By system preference"
|
||||
},
|
||||
"optionsAdvancedAutoSwitchSchemeByTime": {
|
||||
"message": "By night time:"
|
||||
},
|
||||
"optionsAdvancedPatchCsp": {
|
||||
"message": "Patch <code>CSP</code> to allow style assets"
|
||||
},
|
||||
|
@ -1533,6 +1557,12 @@
|
|||
"message": "Style was not applied due to its incorrect usage of 'regexp()'",
|
||||
"description": "Tooltip in the popup for styles that were not applied at all"
|
||||
},
|
||||
"styleNotAppliedSchemeDark": {
|
||||
"message": "This style is only applied in Dark Mode"
|
||||
},
|
||||
"styleNotAppliedSchemeLight": {
|
||||
"message": "This style is only applied in Light Mode"
|
||||
},
|
||||
"styleRegexpInvalidExplanation": {
|
||||
"message": "Some 'regexp()' rules that could not be compiled at all."
|
||||
},
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
findExistingTab
|
||||
openURL
|
||||
*/ // toolbox.js
|
||||
/* global colorScheme */ // color-scheme.js
|
||||
'use strict';
|
||||
|
||||
//#region API
|
||||
|
@ -41,6 +42,7 @@ addAPI(/** @namespace API */ {
|
|||
updater: updateMan,
|
||||
usercss: usercssMan,
|
||||
usw: uswApi,
|
||||
colorScheme,
|
||||
/** @type {BackgroundWorker} */
|
||||
worker: createWorker({url: '/background/background-worker'}),
|
||||
|
||||
|
|
100
background/color-scheme.js
Normal file
100
background/color-scheme.js
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* global prefs */
|
||||
/* exported colorScheme */
|
||||
|
||||
'use strict';
|
||||
|
||||
const colorScheme = (() => {
|
||||
let systemPreferDark = false;
|
||||
let timePreferDark = false;
|
||||
const changeListeners = new Set();
|
||||
|
||||
const checkTime = ['schemeSwitcher.nightStart', 'schemeSwitcher.nightEnd'];
|
||||
prefs.subscribe(checkTime, (key, value) => {
|
||||
updateTimePreferDark();
|
||||
createAlarm(key, value);
|
||||
});
|
||||
checkTime.forEach(key => createAlarm(key, prefs.get(key)));
|
||||
|
||||
prefs.subscribe(['schemeSwitcher.enabled'], emitChange);
|
||||
|
||||
chrome.alarms.onAlarm.addListener(info => {
|
||||
if (checkTime.includes(info.name)) {
|
||||
updateTimePreferDark();
|
||||
}
|
||||
});
|
||||
|
||||
updateSystemPreferDark();
|
||||
updateTimePreferDark();
|
||||
|
||||
return {shouldIncludeStyle, onChange, updateSystemPreferDark};
|
||||
|
||||
function createAlarm(key, value) {
|
||||
const date = new Date();
|
||||
applyDate(date, value);
|
||||
if (date.getTime() < Date.now()) {
|
||||
date.setDate(date.getDate() + 1);
|
||||
}
|
||||
chrome.alarms.create(key, {
|
||||
when: date.getTime(),
|
||||
periodInMinutes: 24 * 60,
|
||||
});
|
||||
}
|
||||
|
||||
function shouldIncludeStyle(style) {
|
||||
const isDark = style.preferScheme === 'dark';
|
||||
const isLight = style.preferScheme === 'light';
|
||||
if (!isDark && !isLight) {
|
||||
return true;
|
||||
}
|
||||
const switcherState = prefs.get('schemeSwitcher.enabled');
|
||||
if (switcherState === 'never') {
|
||||
return true;
|
||||
}
|
||||
if (switcherState === 'system') {
|
||||
return systemPreferDark && isDark ||
|
||||
!systemPreferDark && isLight;
|
||||
}
|
||||
return timePreferDark && isDark ||
|
||||
!timePreferDark && isLight;
|
||||
}
|
||||
|
||||
function updateSystemPreferDark() {
|
||||
const oldValue = systemPreferDark;
|
||||
systemPreferDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
if (systemPreferDark !== oldValue) {
|
||||
emitChange();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function updateTimePreferDark() {
|
||||
const oldValue = timePreferDark;
|
||||
const date = new Date();
|
||||
const now = date.getTime();
|
||||
applyDate(date, prefs.get('schemeSwitcher.nightStart'));
|
||||
const start = date.getTime();
|
||||
applyDate(date, prefs.get('schemeSwitcher.nightEnd'));
|
||||
const end = date.getTime();
|
||||
timePreferDark = start > end ?
|
||||
now >= start || now < end :
|
||||
now >= start && now < end;
|
||||
if (timePreferDark !== oldValue) {
|
||||
emitChange();
|
||||
}
|
||||
}
|
||||
|
||||
function applyDate(date, time) {
|
||||
const [h, m] = time.split(':').map(Number);
|
||||
date.setHours(h, m, 0, 0);
|
||||
}
|
||||
|
||||
function onChange(listener) {
|
||||
changeListeners.add(listener);
|
||||
}
|
||||
|
||||
function emitChange() {
|
||||
for (const listener of changeListeners) {
|
||||
listener();
|
||||
}
|
||||
}
|
||||
})();
|
|
@ -6,6 +6,7 @@
|
|||
/* global prefs */
|
||||
/* global tabMan */
|
||||
/* global usercssMan */
|
||||
/* global colorScheme */
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
|
@ -61,6 +62,14 @@ const styleMan = (() => {
|
|||
let ready = init();
|
||||
|
||||
chrome.runtime.onConnect.addListener(handleLivePreview);
|
||||
// function handleColorScheme() {
|
||||
colorScheme.onChange(() => {
|
||||
for (const {style: data} of dataMap.values()) {
|
||||
if (data.preferScheme === 'dark' || data.preferScheme === 'light') {
|
||||
broadcastStyleUpdated(data, 'colorScheme', undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//#endregion
|
||||
//#region Exports
|
||||
|
@ -183,6 +192,7 @@ const styleMan = (() => {
|
|||
const query = createMatchQuery(url);
|
||||
for (const style of styles) {
|
||||
let excluded = false;
|
||||
let excludedScheme = false;
|
||||
let sloppy = false;
|
||||
let sectionMatched = false;
|
||||
const match = urlMatchStyle(query, style);
|
||||
|
@ -193,6 +203,9 @@ const styleMan = (() => {
|
|||
if (match === 'excluded') {
|
||||
excluded = true;
|
||||
}
|
||||
if (match === 'excludedScheme') {
|
||||
excludedScheme = true;
|
||||
}
|
||||
for (const section of style.sections) {
|
||||
if (styleSectionGlobal(section) && styleCodeEmpty(section.code)) {
|
||||
continue;
|
||||
|
@ -207,7 +220,7 @@ const styleMan = (() => {
|
|||
}
|
||||
}
|
||||
if (sectionMatched) {
|
||||
result.push(/** @namespace StylesByUrlResult */ {style, excluded, sloppy});
|
||||
result.push(/** @namespace StylesByUrlResult */ {style, excluded, sloppy, excludedScheme});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -546,6 +559,9 @@ const styleMan = (() => {
|
|||
if (!style.enabled) {
|
||||
return 'disabled';
|
||||
}
|
||||
if (!colorScheme.shouldIncludeStyle(style)) {
|
||||
return 'excludedScheme';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,13 @@
|
|||
window.addEventListener(orphanEventId, orphanCheck, true);
|
||||
}
|
||||
|
||||
// detect media change in content script
|
||||
// FIXME: move this to background page when following bugs are fixed:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1561546
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=968651
|
||||
const media = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
media.addListener(() => API.colorScheme.updateSystemPreferDark().catch(console.error));
|
||||
|
||||
function onInjectorUpdate() {
|
||||
if (!isOrphaned) {
|
||||
updateCount();
|
||||
|
|
|
@ -50,6 +50,14 @@
|
|||
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
||||
<span i18n-text="liveReloadLabel"></span>
|
||||
</label>
|
||||
<label class="set-prefer-scheme">
|
||||
<span i18n-text="installPreferSchemeLabel"></span>
|
||||
<select>
|
||||
<option value="none" i18n-text="installPreferSchemeNone"></option>
|
||||
<option value="dark" i18n-text="installPreferSchemeDark"></option>
|
||||
<option value="light" i18n-text="installPreferSchemeLight"></option>
|
||||
</select>
|
||||
</label>
|
||||
<p hidden class="installed-actions">
|
||||
<a href="manage.html" tabindex="0"><button i18n-text="openManage"></button></a>
|
||||
<a href="edit.html?id=" tabindex="0"><button i18n-text="editStyleLabel"></button></a>
|
||||
|
|
|
@ -242,7 +242,6 @@ h2.installed.active ~ .configure-usercss:hover svg {
|
|||
.set-update-url {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.set-update-url p {
|
||||
word-break: break-all;
|
||||
opacity: .5;
|
||||
|
@ -250,6 +249,10 @@ h2.installed.active ~ .configure-usercss:hover svg {
|
|||
margin: .25em 0 .25em;
|
||||
}
|
||||
|
||||
label.set-prefer-scheme:not(.unavailable) {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.external {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -299,6 +302,7 @@ li {
|
|||
}
|
||||
|
||||
label {
|
||||
/* FIXME: why do we want to give all labels a padding? */
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
@ -135,6 +135,13 @@ setTimeout(() => !cm && showSpinner($('#header')), 200);
|
|||
$('.set-update-url p').textContent = updateUrl.href.length < 300 ? updateUrl.href :
|
||||
updateUrl.href.slice(0, 300) + '...';
|
||||
|
||||
// set prefer scheme
|
||||
const preferScheme = $('.set-prefer-scheme select');
|
||||
preferScheme.onchange = () => {
|
||||
style.preferScheme = preferScheme.value;
|
||||
};
|
||||
preferScheme.onchange();
|
||||
|
||||
if (URLS.isLocalhost(initialUrl)) {
|
||||
$('.live-reload input').onchange = liveReload.onToggled;
|
||||
} else {
|
||||
|
@ -167,6 +174,9 @@ function updateMeta(style, dup = installedDup) {
|
|||
$('.meta-name').textContent = data.name;
|
||||
$('.meta-version').textContent = data.version;
|
||||
$('.meta-description').textContent = data.description;
|
||||
$('.set-prefer-scheme select').value =
|
||||
style.preferScheme === 'dark' ? 'dark' :
|
||||
style.preferScheme === 'light' ? 'light' : 'none';
|
||||
|
||||
if (data.author) {
|
||||
$('.meta-author').parentNode.style.display = '';
|
||||
|
@ -305,6 +315,7 @@ function install(style) {
|
|||
$('.set-update-url input[type=checkbox]').disabled = true;
|
||||
$('.set-update-url').title = style.updateUrl ?
|
||||
t('installUpdateFrom', style.updateUrl) : '';
|
||||
$('.set-prefer-scheme select').disabled = true;
|
||||
enablePostActions();
|
||||
updateMeta(style);
|
||||
}
|
||||
|
|
59
js/dom.js
59
js/dom.js
|
@ -291,39 +291,64 @@ function scrollElementIntoView(element, {invalidMarginRatio = 0} = {}) {
|
|||
* Accepts an array of pref names (values are fetched via prefs.get)
|
||||
* and establishes a two-way connection between the document elements and the actual prefs
|
||||
*/
|
||||
function setupLivePrefs(ids = prefs.knownKeys.filter(id => $('#' + id))) {
|
||||
function setupLivePrefs(ids = prefs.knownKeys.filter(id => $(`#${CSS.escape(id)}, [name=${CSS.escape(id)}]`))) {
|
||||
let forceUpdate = true;
|
||||
prefs.subscribe(ids, updateElement, {runNow: true});
|
||||
forceUpdate = false;
|
||||
ids.forEach(id => $('#' + id).on('change', onChange));
|
||||
|
||||
for (const id of ids) {
|
||||
const elements = $$(`#${CSS.escape(id)}, [name=${CSS.escape(id)}]`);
|
||||
for (const element of elements) {
|
||||
element.addEventListener('change', onChange);
|
||||
}
|
||||
}
|
||||
|
||||
function onChange() {
|
||||
prefs.set(this.id, this[getPropName(this)]);
|
||||
if (!this.checkValidity()) {
|
||||
return;
|
||||
}
|
||||
if (this.type === 'radio' && !this.checked) {
|
||||
return;
|
||||
}
|
||||
prefs.set(this.id || this.name, getValue(this));
|
||||
}
|
||||
|
||||
function getPropName(el) {
|
||||
return el.type === 'checkbox' ? 'checked'
|
||||
: el.type === 'number' ? 'valueAsNumber' :
|
||||
'value';
|
||||
function getValue(el) {
|
||||
const type = el.dataset.valueType || el.type;
|
||||
return type === 'checkbox' ? el.checked :
|
||||
// https://stackoverflow.com/questions/18062069/why-does-valueasnumber-return-nan-as-a-value
|
||||
// valueAsNumber is not applicable for input[text/radio] or select
|
||||
type === 'number' ? Number(el.value) :
|
||||
el.value;
|
||||
}
|
||||
|
||||
function isSame(el, propName, value) {
|
||||
return el[propName] === value ||
|
||||
function isSame(el, oldValue, value) {
|
||||
return oldValue === value ||
|
||||
typeof value === 'boolean' &&
|
||||
el.tagName === 'SELECT' &&
|
||||
el[propName] === `${value}`;
|
||||
oldValue === `${value}` ||
|
||||
el.type === 'radio' && (oldValue === value) === el.checked;
|
||||
}
|
||||
|
||||
function updateElement(id, value) {
|
||||
const el = $('#' + id);
|
||||
if (el) {
|
||||
const prop = getPropName(el);
|
||||
if (!isSame(el, prop, value) || forceUpdate) {
|
||||
el[prop] = value;
|
||||
const els = $$(`#${CSS.escape(id)}, [name=${CSS.escape(id)}]`);
|
||||
if (!els.length) {
|
||||
// FIXME: why do we unsub all ids when a single id is missing from the page
|
||||
prefs.unsubscribe(ids, updateElement);
|
||||
return;
|
||||
}
|
||||
for (const el of els) {
|
||||
const oldValue = getValue(el);
|
||||
if (!isSame(el, oldValue, value) || forceUpdate) {
|
||||
if (el.type === 'radio') {
|
||||
el.checked = value === oldValue;
|
||||
} else if (el.type === 'checkbox') {
|
||||
el.checked = value;
|
||||
} else {
|
||||
el.value = value;
|
||||
}
|
||||
el.dispatchEvent(new Event('change', {bubbles: true}));
|
||||
}
|
||||
} else {
|
||||
prefs.unsubscribe(ids, updateElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
// checkbox in style config dialog
|
||||
'config.autosave': true,
|
||||
|
||||
'schemeSwitcher.enabled': 'never',
|
||||
'schemeSwitcher.nightStart': '18:00',
|
||||
'schemeSwitcher.nightEnd': '06:00',
|
||||
|
||||
'popup.breadcrumbs': true, // display 'New style' links as URL breadcrumbs
|
||||
'popup.breadcrumbs.usePath': false, // use URL path for 'this URL'
|
||||
'popup.enabledFirst': true, // display enabled styles before disabled styles
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
"background/common.js",
|
||||
|
||||
"background/db.js",
|
||||
"background/color-scheme.js",
|
||||
"background/icon-manager.js",
|
||||
"background/navigation-manager.js",
|
||||
"background/style-search-db.js",
|
||||
|
|
24
options.html
24
options.html
|
@ -52,7 +52,7 @@
|
|||
<label>
|
||||
<span i18n-text="optionsIconDark"></span>
|
||||
<div class="iconset">
|
||||
<input type="radio" name="iconset">
|
||||
<input type="radio" name="iconset" value="0" data-value-type="number">
|
||||
<img src="/images/icon/16.png">
|
||||
<img src="/images/icon/16w.png">
|
||||
<img src="/images/icon/16x.png">
|
||||
|
@ -61,7 +61,7 @@
|
|||
<label>
|
||||
<span i18n-text="optionsIconLight"></span>
|
||||
<div class="iconset">
|
||||
<input type="radio" name="iconset">
|
||||
<input type="radio" name="iconset" value="1" data-value-type="number">
|
||||
<img src="/images/icon/light/16.png">
|
||||
<img src="/images/icon/light/16w.png">
|
||||
<img src="/images/icon/light/16x.png">
|
||||
|
@ -272,6 +272,26 @@
|
|||
<span></span>
|
||||
</span>
|
||||
</label>
|
||||
<div class="radio-group">
|
||||
<span i18n-text="optionsAdvancedAutoSwitchScheme" class="radio-group-label"></span>
|
||||
<label class="radio-group-item">
|
||||
<input type="radio" value="never" name="schemeSwitcher.enabled" class="radio">
|
||||
<span i18n-text="optionsAdvancedAutoSwitchSchemeNever"></span>
|
||||
</label>
|
||||
<label class="radio-group-item">
|
||||
<input type="radio" value="system" name="schemeSwitcher.enabled" class="radio">
|
||||
<span i18n-text="optionsAdvancedAutoSwitchSchemeBySystem"></span>
|
||||
</label>
|
||||
<label class="radio-group-item">
|
||||
<input type="radio" value="time" name="schemeSwitcher.enabled" class="radio">
|
||||
<span>
|
||||
<span i18n-text="optionsAdvancedAutoSwitchSchemeByTime"></span>
|
||||
<input type="text" pattern="\d{2}:\d{2}" required id="schemeSwitcher.nightStart" class="input-sm">
|
||||
~
|
||||
<input type="text" pattern="\d{2}:\d{2}" required id="schemeSwitcher.nightEnd" class="input-sm">
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -192,7 +192,8 @@ input[type=number] {
|
|||
text-align: right;
|
||||
}
|
||||
|
||||
input[type=number]:invalid {
|
||||
input[type=number]:invalid,
|
||||
input[type=text]:invalid {
|
||||
background-color: rgba(255, 0, 0, 0.1);
|
||||
color: darkred;
|
||||
}
|
||||
|
@ -376,6 +377,40 @@ html:not(.firefox):not(.opera) #updates {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
/* radio group */
|
||||
.radio-group-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 1.5em;
|
||||
}
|
||||
.radio-group-item > input {
|
||||
margin: 0 8px 0 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
.radio-group-label {
|
||||
display: block;
|
||||
margin: 0 0 .3em;
|
||||
}
|
||||
|
||||
.input-sm {
|
||||
width: 3em;
|
||||
}
|
||||
|
||||
/* pixel perfect radio */
|
||||
input[type="radio"].radio::after {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
left: -1px;
|
||||
height: auto;
|
||||
width: auto;
|
||||
transform: scale(0);
|
||||
}
|
||||
input[type="radio"].radio:checked::after {
|
||||
transform: scale(.65);
|
||||
}
|
||||
|
||||
@keyframes fadeinout {
|
||||
0% { opacity: 0 }
|
||||
10% { opacity: 1 }
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
'use strict';
|
||||
|
||||
setupLivePrefs();
|
||||
setupRadioButtons();
|
||||
$$('input[min], input[max]').forEach(enforceInputRange);
|
||||
|
||||
if (CHROME_POPUP_BORDER_BUG) {
|
||||
|
@ -196,29 +195,6 @@ function checkUpdates() {
|
|||
}
|
||||
}
|
||||
|
||||
function setupRadioButtons() {
|
||||
const sets = {};
|
||||
const onChange = function () {
|
||||
const newValue = sets[this.name].indexOf(this);
|
||||
if (newValue >= 0 && prefs.get(this.name) !== newValue) {
|
||||
prefs.set(this.name, newValue);
|
||||
}
|
||||
};
|
||||
// group all radio-inputs by name="prefName" attribute
|
||||
for (const el of $$('input[type="radio"][name]')) {
|
||||
(sets[el.name] = sets[el.name] || []).push(el);
|
||||
el.on('change', onChange);
|
||||
}
|
||||
// select the input corresponding to the actual pref value
|
||||
for (const name in sets) {
|
||||
sets[name][prefs.get(name)].checked = true;
|
||||
}
|
||||
// listen to pref changes and update the values
|
||||
prefs.subscribe(Object.keys(sets), (key, value) => {
|
||||
sets[key][value].checked = true;
|
||||
});
|
||||
}
|
||||
|
||||
function customizeHotkeys() {
|
||||
// command name -> i18n id
|
||||
const hotkeys = new Map([
|
||||
|
|
8349
package-lock.json
generated
8349
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -27,7 +27,7 @@
|
|||
"make-fetch-happen": "^8.0.7",
|
||||
"sync-version": "^1.0.1",
|
||||
"tiny-glob": "^0.2.6",
|
||||
"web-ext": "^5.5.0"
|
||||
"web-ext": "^6.5.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint \"**/*.js\" --cache",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
CHROME_POPUP_BORDER_BUG
|
||||
FIREFOX
|
||||
URLS
|
||||
capitalize
|
||||
getActiveTab
|
||||
isEmptyObj
|
||||
*/// toolbox.js
|
||||
|
@ -372,13 +373,14 @@ function createStyleElement(style) {
|
|||
const styleName = $('.style-name', entry);
|
||||
styleName.lastChild.textContent = style.customName || style.name;
|
||||
setTimeout(() => {
|
||||
styleName.title = entry.styleMeta.sloppy ?
|
||||
t('styleNotAppliedRegexpProblemTooltip') :
|
||||
styleName.scrollWidth > styleName.clientWidth + 1 ?
|
||||
styleName.textContent : '';
|
||||
styleName.title =
|
||||
entry.styleMeta.sloppy ? t('styleNotAppliedRegexpProblemTooltip') :
|
||||
entry.styleMeta.excludedScheme ? t(`styleNotAppliedScheme${capitalize(entry.styleMeta.preferScheme)}`) :
|
||||
styleName.scrollWidth > styleName.clientWidth + 1 ? styleName.textContent :
|
||||
'';
|
||||
});
|
||||
|
||||
entry.classList.toggle('not-applied', style.excluded || style.sloppy);
|
||||
entry.classList.toggle('not-applied', style.excluded || style.sloppy || style.excludedScheme);
|
||||
entry.classList.toggle('regexp-partial', style.sloppy);
|
||||
|
||||
$('.exclude-by-domain-checkbox', entry).checked = Events.isStyleExcluded(style, 'domain');
|
||||
|
|
Loading…
Reference in New Issue
Block a user