diff --git a/_locales/en/messages.json b/_locales/en/messages.json index b9e9c971..b39dba4a 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -205,18 +205,6 @@ "configOnChangeTooltip": { "message": "Autosave and apply changes automatically" }, - "genericAdd": { - "message": "Add", - "description": "Used in various places to select/perform an add action." - }, - "genericDelete": { - "message": "Delete", - "description": "Used in various places to select/perform a delete action." - }, - "genericEdit": { - "message": "Edit", - "description": "Used in various places to select/perform an edit action." - }, "genericError": { "message": "Error", "description": "Used in various places to indicate some error occurred." @@ -380,42 +368,29 @@ "description": "Label for a full url with a subdirectory to be used as the beginning portion of a URL to match to exclude a style" }, "exclusionsAddTitle": { - "message": "Add excluded page", - "description": "Title of popup to add an excluded page (URL)" - }, - "exclusionsEditTitle": { - "message": "Edit excluded page(s)", - "description": "Title of popup to edit an excluded page (URL)" - }, - "exclusionsEmpty": { - "message": "No exclusions", - "description": "Label shown when there are no global exclusions" - }, - "exclusionsDeleteConfirmation": { - "message": "Are you sure you want to delete $number$ entries?", - "description": "Delete confirmation dialog message", - "placeholders": { - "number": { - "content": "$1" - } - } + "message": "Add exclusion", + "description": "Title of popup to add an excluded site or page (URL)" }, "exclusionsHeader": { - "message": "Excluded Pages", + "message": "Excluded", "description": "Title of user configurable lists of site urls to exclude per style" }, "exclusionsHelp": { - "message": "Add one or more exclusions for each style. An exclusion is a string that will match a web location (URL). If a match is found, the given style (and all internal sections) will not be applied to that page. A list of exclusions is set separately from the userstyle so that it will not be effected when updating or editing the style itself.\n\nThis is useful because you can exclude websites that would be effected by a global style.\n\nThe exclusion string may contain wildcards (\"*\") to match any portion of the URL, e.g. \"forum.*.com\" will exclude the forum sub-domains of all dot-com top level domains.\n\nRegular expressions are not supported.", + "message": "Exclusion entries are only checked when a style is set to be applied to a page, and if an exclusion is found, the given style (and all internal sections) will not be applied to that page.\n\nThe list of exclusions is set separately from the userstyle so that it will not be effected when updating or editing the style itself. This is useful because you can exclude pages that would be otherwise be effected by a global style.\n\nAdd one or more exclusion entries for each style. An exclusion entry string contains a pattern that will match a web location (URL). This string may contain wildcards (\"*\") to match any portion of a URL, e.g. \"forum.*.com\" will exclude the forum sub-domains of all top level dot-com domains. Regular expressions are allowed, except `.` and `*` are altered, and are saved as a string so character classes must be doubly escaped (e.g. `\\w`).\n\nExcluded pages are automatically updated while typing; invalid entries will be removed on page reload!", "description": "Help text for user set style exclusions" }, "exclusionsHelpTitle": { "message": "Set Style Exclusions", "description": "Header text for help modal" }, - "exclusionsInvalidUrl": { + "exclusionsvalidateEntry": { "message": "Enter a unique and valid URL", "description": "Text for an alert notifying the user that an entered URL is not unique or invalid" }, + "exclusionsPopupTitle": { + "message": "Exclude the site or page", + "description": "Title of exclusion popup dialog within the extension popup" + }, "exclusionsPopupTip": { "message": "Right-click to edit exclusions on this page", "description": "Title on the checkbox in the popup to let the user know how to edit exclusions on the current page" @@ -425,7 +400,7 @@ "description": "Prefix label added to the applies to column in the style manager" }, "exclusionsStatus": { - "message": "$number$ sites", + "message": "$number$ pages", "description": "Label added next to the Excluded Pages header when 'number' is not zero", "placeholders": { "number": { diff --git a/background/storage.js b/background/storage.js index 8e828654..b0f6c12d 100644 --- a/background/storage.js +++ b/background/storage.js @@ -19,6 +19,7 @@ var cachedStyles = { byId: new Map(), // all styles indexed by id filters: new Map(), // filterStyles() parameters mapped to the returned results, 10k max regexps: new Map(), // compiled style regexps + exclusions: new Map(), // compiled exclusion regexps urlDomains: new Map(), // getDomain() results for 100 last checked urls needTransitionPatch: new Map(), // FF bug workaround mutex: { @@ -250,6 +251,7 @@ function filterStyles({ strictRegexp, blankHash, cacheKey, + omitCode, }); } if (!omitCode) return styles; @@ -275,6 +277,7 @@ function filterStylesInternal({ strictRegexp, blankHash, cacheKey, + omitCode, }) { if (matchUrl && !cachedStyles.urlDomains.has(matchUrl)) { cachedStyles.urlDomains.set(matchUrl, getDomains(matchUrl)); @@ -309,6 +312,7 @@ function filterStylesInternal({ stopOnFirst: !asHash, skipUrlCheck: true, matchUrlBase, + omitCode, }); if (asHash) { if (sections.length) { @@ -423,10 +427,9 @@ function saveStyle(style) { style.id = style.id || event.target.result; invalidateCache(existed ? {updated: style} : {added: style}); if (notify) { - notifyAllTabs({ - method: existed ? 'styleUpdated' : 'styleAdded', - style, codeIsUpdated, reason, - }); + const method = reason === 'exclusionsUpdate' ? reason : + existed ? 'styleUpdated' : 'styleAdded'; + notifyAllTabs({method, style, codeIsUpdated, reason}); } return style; } @@ -444,12 +447,28 @@ function deleteStyle({id, notify = true}) { }); } -function checkExclusions(matchUrl, exclusions = {}) { - const values = Object.values(exclusions); - return values.length && - values.reduce((acc, exclude) => acc || tryRegExp(exclude).test(matchUrl), false); + +function compileExclusionRegexps(exclusions) { + exclusions.forEach(exclusion => { + if (!cachedStyles.exclusions.get(exclusion)) { + cachedStyles.exclusions.set(exclusion, tryRegExp(exclusion) || false); + } + }); } +function isPageExcluded(matchUrl, exclusions = {}) { + const values = Object.values(exclusions); + if (!values.length) { + return false; + } + compileExclusionRegexps(values); + return values.some(exclude => { + const rx = cachedStyles.exclusions.get(exclude); + return rx && rx.test(matchUrl); + }); +} + + function getApplicableSections({ style, matchUrl, @@ -458,12 +477,13 @@ function getApplicableSections({ stopOnFirst, skipUrlCheck, matchUrlBase = matchUrl.includes('#') && matchUrl.split('#', 1)[0], + omitCode, // 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) || checkExclusions(matchUrl, style.exclusions)) { + if (!skipUrlCheck && !URLS.supported(matchUrl) || omitCode !== false && isPageExcluded(matchUrl, style.exclusions)) { return []; } const sections = []; @@ -642,6 +662,7 @@ function updateFiltersCache(style) { matchUrlBase, strictRegexp, skipUrlCheck: true, + omitCode: false }); if (sections.length) { styles[id] = sections; @@ -830,8 +851,8 @@ function detectSloppyRegexps({matchUrl, ids}) { } } if (!hasRegExp) continue; - const applied = getApplicableSections({style, matchUrl}); - const wannabe = getApplicableSections({style, matchUrl, strictRegexp: false}); + const applied = getApplicableSections({style, matchUrl, omitCode: false}); + const wannabe = getApplicableSections({style, matchUrl, omitCode: false, strictRegexp: false}); results.push({ id, applied, diff --git a/edit.html b/edit.html index 90eac15b..a2a9f8cf 100644 --- a/edit.html +++ b/edit.html @@ -172,6 +172,16 @@ + +