diff --git a/background/context-menus.js b/background/context-menus.js index 53101dea..148616af 100644 --- a/background/context-menus.js +++ b/background/context-menus.js @@ -1,7 +1,7 @@ /* global browserCommands */// background.js /* global msg */ /* global prefs */ -/* global CHROME FIREFOX URLS ignoreChromeError */// toolbox.js +/* global CHROME URLS ignoreChromeError */// toolbox.js 'use strict'; (() => { @@ -28,7 +28,7 @@ click: browserCommands.reload, }, 'editor.contextDelete': { - presentIf: () => !FIREFOX && prefs.get('editor.contextDelete'), + presentIf: () => CHROME && prefs.get('editor.contextDelete'), title: 'editDeleteText', type: 'normal', contexts: ['editable'], @@ -40,14 +40,7 @@ }, }; - // "Delete" item in context menu for browsers that don't have it - if (CHROME && - // looking at the end of UA string - /(Vivaldi|Safari)\/[\d.]+$/.test(navigator.userAgent) && - // skip forks with Flash as those are likely to have the menu e.g. CentBrowser - !Array.from(navigator.plugins).some(p => p.name === 'Shockwave Flash')) { - prefs.__defaults['editor.contextDelete'] = true; - } + prefs.__defaults['editor.contextDelete'] = Boolean(CHROME); const keys = Object.keys(contextMenus); prefs.subscribe(keys.filter(id => typeof prefs.defaults[id] === 'boolean'), diff --git a/js/dom.js b/js/dom.js index ff2390c9..dd9f8d62 100644 --- a/js/dom.js +++ b/js/dom.js @@ -1,4 +1,4 @@ -/* global FIREFOX debounce */// toolbox.js +/* global FIREFOX WINDOWS debounce */// toolbox.js /* global prefs */ 'use strict'; @@ -418,9 +418,7 @@ async function waitForSheet({ window.on('mousedown', suppressFocusRingOnClick, {passive: true}); window.on('keydown', keepFocusRingOnTabbing, {passive: true}); - if (!/^Win\d+/.test(navigator.platform)) { - document.documentElement.classList.add('non-windows'); - } + document.documentElement.classList.toggle('non-windows', !WINDOWS); // set language for a) CSS :lang pseudo and b) hyphenation document.documentElement.setAttribute('lang', chrome.i18n.getUILanguage()); document.on('keypress', clickDummyLinkOnEnter); diff --git a/js/prefs.js b/js/prefs.js index 3d7b93fa..67b06852 100644 --- a/js/prefs.js +++ b/js/prefs.js @@ -1,5 +1,5 @@ /* global API msg */// msg.js -/* global debounce deepMerge */// toolbox.js - not used in content scripts +/* global MOBILE WINDOWS debounce deepMerge */// toolbox.js - not used in content scripts 'use strict'; (() => { @@ -51,7 +51,7 @@ 'manage.backup.expanded': true, 'manage.filters.expanded': true, // the new compact layout doesn't look good on Android yet - 'manage.newUI': !navigator.appVersion.includes('Android'), + 'manage.newUI': chrome.tabs ? !MOBILE : false, 'manage.newUI.favicons': false, // show favicons for the sites in applies-to 'manage.newUI.faviconsGray': true, // gray out favicons 'manage.newUI.targets': 3, // max number of applies-to targets visible: 0 = none @@ -65,7 +65,7 @@ 'editor.smartIndent': true, // 'smart' indent 'editor.indentWithTabs': false, // smart indent with tabs 'editor.tabSize': 4, // tab width, in spaces - 'editor.keyMap': navigator.appVersion.indexOf('Windows') > 0 ? 'sublime' : 'default', + 'editor.keyMap': chrome.tabs && WINDOWS ? 'sublime' : 'default', 'editor.theme': 'default', // CSS theme // CSS beautifier 'editor.beautify': { diff --git a/js/toolbox.js b/js/toolbox.js index 55f5422b..5f23587a 100644 --- a/js/toolbox.js +++ b/js/toolbox.js @@ -2,7 +2,9 @@ /* exported CHROME_POPUP_BORDER_BUG + MOBILE RX_META + WINDOWS capitalize closeCurrentTab deepEqual @@ -22,10 +24,37 @@ waitForTabUrl */ -const CHROME = Boolean(chrome.app) && Number(navigator.userAgent.match(/Chrom\w+\/(\d+)|$/)[1]); -const OPERA = Boolean(chrome.app) && parseFloat(navigator.userAgent.match(/\bOPR\/(\d+\.\d+)|$/)[1]); -const VIVALDI = Boolean(chrome.app) && navigator.userAgent.includes('Vivaldi'); -let FIREFOX = !chrome.app && parseFloat(navigator.userAgent.match(/\bFirefox\/(\d+\.\d+)|$/)[1]); +let { + CHROME = false, + OPERA = false, + VIVALDI = false, + FIREFOX = false, + Windows: WINDOWS = false, + mobile: MOBILE = false, + // New Vivaldi doesn't expose itself via `brands` or UA, only via `extData` on a Tab object. +} = (() => { + const MAP = { + OPR: 'OPERA', + Chromium: 'CHROME', + 'Google Chrome': 'CHROME', + }; + const uaData = navigator.userAgentData || { + // Accessing `userAgent` shows a warning in devtools. + brands: navigator.userAgent.match(/\b(\w+)\/(\d+\.\d+)/g) + .map(s => s.split('/')) + .map(([brand, version]) => ({brand, version})), + mobile: navigator.userAgent.includes('Android'), + }; + const res = { + mobile: uaData.mobile, + // Vivaldi bug: no `platform` in uaData + [uaData.platform || navigator.userAgent.match(/\((\S+)|$/)[1]]: true, + }; + for (const {brand, version} of uaData.brands) { + res[MAP[brand] || brand.toUpperCase()] = Number(version); + } + return res; +})(); // see PR #781 const CHROME_POPUP_BORDER_BUG = CHROME >= 62 && CHROME <= 74;