also find styles for URLs with stripped #hash

kinda fixes #155

as per spec the fragment portion is ignored in @-moz-document:
https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-of-doc
but we still respect url("foo#hash") set in userstyles
because the spec is outdated and doesn't account for SPA sites

collateral damage: simplified URLS.supported()
This commit is contained in:
tophf 2017-08-16 20:40:24 +03:00
parent d24b62461c
commit 815f8ca959
4 changed files with 34 additions and 27 deletions

View File

@ -129,12 +129,7 @@ function filterStyles({
exposeIframes: prefs.get('exposeIframes'), exposeIframes: prefs.get('exposeIframes'),
}; };
if (matchUrl && ( if (matchUrl && !URLS.supported(matchUrl)) {
// Web Store doesn't run content scripts
matchUrl.startsWith(URLS.browserWebStore) ||
// Chrome 61.0.3161+ doesn't run content scripts on NTP
URLS.chromeProtectsNTP && matchUrl.startsWith('chrome://newtab/')
)) {
return asHash ? {} : []; return asHash ? {} : [];
} }
@ -193,6 +188,7 @@ function filterStylesInternal({
} }
const needSections = asHash || matchUrl !== null; const needSections = asHash || matchUrl !== null;
const matchUrlBase = matchUrl && matchUrl.includes('#') && matchUrl.split('#', 1)[0];
let style; let style;
for (let i = 0; (style = styles[i]); i++) { for (let i = 0; (style = styles[i]); i++) {
@ -200,7 +196,14 @@ function filterStylesInternal({
&& (url === null || style.url === url) && (url === null || style.url === url)
&& (id === null || style.id === id)) { && (id === null || style.id === id)) {
const sections = needSections && const sections = needSections &&
getApplicableSections({style, matchUrl, strictRegexp, stopOnFirst: !asHash}); getApplicableSections({
style,
matchUrl,
strictRegexp,
stopOnFirst: !asHash,
skipUrlCheck: true,
matchUrlBase,
});
if (asHash) { if (asHash) {
if (sections.length) { if (sections.length) {
filtered[style.id] = sections; filtered[style.id] = sections;
@ -322,11 +325,20 @@ function deleteStyle({id, notify = true}) {
} }
function getApplicableSections({style, matchUrl, strictRegexp = true, stopOnFirst}) { function getApplicableSections({
if (!matchUrl.startsWith('http') style,
&& !matchUrl.startsWith('ftp') matchUrl,
&& !matchUrl.startsWith('file') strictRegexp = true,
&& !matchUrl.startsWith(URLS.ownOrigin)) { // filterStylesInternal() sets the following to avoid recalc on each style:
stopOnFirst,
skipUrlCheck,
matchUrlBase = matchUrl.includes('#') && matchUrl.split('#', 1)[0],
// as per spec the fragment portion is ignored in @-moz-document:
// https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-of-doc
// but the spec is outdated and doesn't account for SPA sites
// so we only respect it in case of url("http://exact.url/without/hash")
}) {
if (!skipUrlCheck && !URLS.supported(matchUrl)) {
return []; return [];
} }
const sections = []; const sections = [];
@ -335,7 +347,7 @@ function getApplicableSections({style, matchUrl, strictRegexp = true, stopOnFirs
const isGlobal = !urls.length && !urlPrefixes.length && !domains.length && !regexps.length; const isGlobal = !urls.length && !urlPrefixes.length && !domains.length && !regexps.length;
const isMatching = !isGlobal && ( const isMatching = !isGlobal && (
urls.length urls.length
&& urls.indexOf(matchUrl) >= 0 && (urls.includes(matchUrl) || matchUrlBase && urls.includes(matchUrlBase))
|| urlPrefixes.length || urlPrefixes.length
&& arraySomeIsPrefix(urlPrefixes, matchUrl) && arraySomeIsPrefix(urlPrefixes, matchUrl)
|| domains.length || domains.length

View File

@ -1862,7 +1862,7 @@ function showRegExpTester(event, section = getSectionForChild(this)) {
}); });
queryTabs().then(tabs => { queryTabs().then(tabs => {
const supported = tabs.map(tab => tab.url) const supported = tabs.map(tab => tab.url)
.filter(url => URLS.supported.test(url)); .filter(url => URLS.supported(url));
const unique = [...new Set(supported).values()]; const unique = [...new Set(supported).values()];
for (const rxData of regexps) { for (const rxData of regexps) {
const {rx, urls} = rxData; const {rx, urls} = rxData;

View File

@ -31,20 +31,15 @@ const URLS = {
chromeProtectsNTP: chromeProtectsNTP:
parseInt(navigator.userAgent.match(/Chrom\w+\/(?:\d+\.){2}(\d+)|$/)[1]) >= 3161, parseInt(navigator.userAgent.match(/Chrom\w+\/(?:\d+\.){2}(\d+)|$/)[1]) >= 3161,
supported: null, supported: url => (
url.startsWith('http') && !url.startsWith(URLS.browserWebStore) ||
url.startsWith('ftp') ||
url.startsWith('file') ||
url.startsWith(URLS.ownOrigin) ||
!URLS.chromeProtectsNTP && url.startsWith('chrome://newtab/')
),
}; };
URLS.supported = new RegExp(
'^(file|ftps?|http)://|' +
`^https://(?!${
URLS.browserWebStore.split('://')[1].replace(/\./g, '\\.')
})|` +
(URLS.chromeProtectsNTP
? '^chrome://(?!newtab)/|'
: '') +
'^' + chrome.runtime.getURL('')
);
let BG = chrome.extension.getBackgroundPage(); let BG = chrome.extension.getBackgroundPage();
if (BG && !BG.getStyles && BG !== window) { if (BG && !BG.getStyles && BG !== window) {
// own page like editor/manage is being loaded on browser startup // own page like editor/manage is being loaded on browser startup

View File

@ -9,7 +9,7 @@ const ENTRY_ID_PREFIX_RAW = 'style-';
const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW; const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW;
getActiveTabRealURL().then(url => { getActiveTabRealURL().then(url => {
tabURL = URLS.supported.test(url) ? url : ''; tabURL = URLS.supported(url) ? url : '';
Promise.all([ Promise.all([
tabURL && getStylesSafe({matchUrl: tabURL}), tabURL && getStylesSafe({matchUrl: tabURL}),
onDOMready().then(() => { onDOMready().then(() => {