From 0bd738b49f9157dd50e450b8fef36d6dd291ff40 Mon Sep 17 00:00:00 2001 From: Rob Garrison Date: Sat, 2 Feb 2019 07:01:08 -0600 Subject: [PATCH 1/7] Set updateDate on editSave. Closes #663 --- background/style-manager.js | 1 + 1 file changed, 1 insertion(+) diff --git a/background/style-manager.js b/background/style-manager.js index b12b4231..c2b92382 100644 --- a/background/style-manager.js +++ b/background/style-manager.js @@ -177,6 +177,7 @@ const styleManager = (() => { } else { data = Object.assign(createNewStyle(), data); } + data.updateDate = Date.now(); return saveStyle(data) .then(newData => handleSave(newData, 'editSave')); } From dfb9db34c39186329c308910eba7e955f39aa427 Mon Sep 17 00:00:00 2001 From: eight Date: Mon, 4 Feb 2019 03:00:13 +0800 Subject: [PATCH 2/7] Fix: update live preview when the style is toggled/replaced (#662) --- edit/sections-editor.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/edit/sections-editor.js b/edit/sections-editor.js index 7e2f8063..99772f2b 100644 --- a/edit/sections-editor.js +++ b/edit/sections-editor.js @@ -197,6 +197,7 @@ function createSectionsEditor({style, onTitleChanged}) { dirty.modify('enabled', style.enabled, newValue); style.enabled = newValue; enabledEl.checked = newValue; + updateLivePreview(); } function nextEditor(cm, cycle = true) { @@ -565,6 +566,7 @@ function createSectionsEditor({style, onTitleChanged}) { $('#heading').textContent = t('editStyleHeading'); } livePreview.show(Boolean(style.id)); + updateLivePreview(); }); function reinit() { From 4262882ac96bfe0bf386293f2612aa91e677421b Mon Sep 17 00:00:00 2001 From: eight Date: Thu, 14 Feb 2019 09:09:18 +0800 Subject: [PATCH 3/7] Add: enable usercss updateURL (#661) * Add: use metadata.updateURL as style.updateUrl * Change: only use the installation URL as the update URL if not specified in usercss * Fix: hide live reload checkbox according to installationUrl --- install-usercss/install-usercss.js | 6 +++--- js/usercss.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/install-usercss/install-usercss.js b/install-usercss/install-usercss.js index 889da8b8..afbd6419 100644 --- a/install-usercss/install-usercss.js +++ b/install-usercss/install-usercss.js @@ -307,9 +307,9 @@ // set updateUrl const checker = $('.set-update-url input[type=checkbox]'); - // prefer the installation URL unless drag'n'dropped on the manage page + // only use the installation URL if not specified in usercss const installationUrl = (params.get('updateUrl') || '').replace(/^blob.+/, ''); - const updateUrl = new URL(installationUrl || style.updateUrl || DUMMY_URL); + const updateUrl = new URL(style.updateUrl || installationUrl || DUMMY_URL); if (dup && dup.updateUrl === updateUrl.href) { checker.checked = true; // there is no way to "unset" updateUrl, you can only overwrite it. @@ -335,7 +335,7 @@ // live reload const setLiveReload = $('.live-reload input[type=checkbox]'); - if (updateUrl.protocol !== 'file:') { + if (!installationUrl || !installationUrl.startsWith('file:')) { setLiveReload.parentNode.remove(); } else { setLiveReload.addEventListener('change', () => { diff --git a/js/usercss.js b/js/usercss.js index 360743c0..deebcbbb 100644 --- a/js/usercss.js +++ b/js/usercss.js @@ -7,7 +7,7 @@ const usercss = (() => { author: undefined, description: undefined, homepageURL: 'url', - // updateURL: 'updateUrl', + updateURL: 'updateUrl', name: undefined, }; const RX_META = /\/\*!?\s*==userstyle==[\s\S]*?==\/userstyle==\s*\*\//i; From 1ff34fc44914927369243687319d02de80129ca4 Mon Sep 17 00:00:00 2001 From: eight Date: Sun, 3 Mar 2019 22:29:26 +0800 Subject: [PATCH 4/7] Fix: return true in icon API (#669) --- background/background.js | 6 ++++-- content/apply.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/background/background.js b/background/background.js index 2f2835d5..a3542665 100644 --- a/background/background.js +++ b/background/background.js @@ -42,9 +42,11 @@ window.API_METHODS = Object.assign(window.API_METHODS || {}, { // Chrome 49 doesn't report own extension pages in webNavigation apparently // so we do a force update which doesn't use the cache. if (CHROME && CHROME < 2661 && this.sender.tab.url.startsWith(URLS.ownOrigin)) { - return updateIconBadgeForce(this.sender.tab.id, count); + updateIconBadgeForce(this.sender.tab.id, count); + } else { + updateIconBadge(this.sender.tab.id, count); } - return updateIconBadge(this.sender.tab.id, count); + return true; }, // exposed for stuff that requires followup sendMessage() like popup::openSettings diff --git a/content/apply.js b/content/apply.js index 0ff751a6..307d812b 100644 --- a/content/apply.js +++ b/content/apply.js @@ -299,7 +299,7 @@ const APPLY = (() => { method: 'invokeAPI', name: 'updateIconBadge', args: [count] - }).catch(msg.ignoreError); + }).catch(console.error); } function applyStyleState({id, enabled}) { From cdc7f98150afd2143562335e19efe2656af3720f Mon Sep 17 00:00:00 2001 From: eight Date: Mon, 4 Mar 2019 06:54:37 +0800 Subject: [PATCH 5/7] Add: user-frendly exclusions (#666) * WIP: popup UI * Fix: use simple menu toggle * Add: inclusion/exclusion API * Add: hook exclusion UI * Fix: minor * Fix: don't self-edit * Icons and accessibility * Icons and accessibility * Fix: disable redundant exclude-by-url checkbox * Disabled cursor and delete leftover code * Generic menu button tooltip and tweak menu item cursors * Generic menu button tooltip and tweak menu item cursors * Generic menu button tooltip and tweak menu item cursors --- _locales/en/messages.json | 21 ++++++-- background/background.js | 5 ++ background/style-manager.js | 61 ++++++++++++++++----- popup.html | 70 +++++++++++++++++------- popup/popup.css | 105 +++++++++++++++++++++++++++++++++--- popup/popup.js | 52 +++++++++++++++++- 6 files changed, 271 insertions(+), 43 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 3c5964f3..87a5a533 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -315,6 +315,15 @@ "message": "Enable", "description": "Label for the button to enable a style" }, + "excludeStyleByDomainLabel": { + "message": "Exclude the current domain" + }, + "excludeStyleByUrlLabel": { + "message": "Exclude the current URL" + }, + "excludeStyleByUrlRedundant": { + "message": "The current URL is the domain page" + }, "exportLabel": { "message": "Export", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" @@ -1026,6 +1035,10 @@ "message": "Stylus failed to parse usercss:", "description": "The error message to show when stylus failed to parse usercss" }, + "popupAutoResort": { + "message": "Resort styles in popup after toggling", + "description": "Label for the checkbox controlling popup resorting." + }, "popupBorders": { "message": "Add white borders on the sides" }, @@ -1044,6 +1057,10 @@ "message": "Shift-click or right-click opens manager with styles applicable for current site", "description": "Tooltip for the 'Manage' button in the popup." }, + "popupMenuButtonTooltip": { + "message": "Action menu", + "description": "Tooltip for menu button in popup." + }, "popupOpenEditInWindow": { "message": "Open editor in a new window", "description": "Label for the checkbox controlling 'edit' action behavior in the popup." @@ -1056,10 +1073,6 @@ "message": "Styles before commands", "description": "Label for the checkbox controlling section order in the popup." }, - "popupAutoResort": { - "message": "Resort styles in popup after toggling", - "description": "Label for the checkbox controlling popup resorting." - }, "prefShowBadge": { "message": "Number of styles active for the current site", "description": "Label for the checkbox controlling toolbar badge text." diff --git a/background/background.js b/background/background.js index a3542665..b74067f3 100644 --- a/background/background.js +++ b/background/background.js @@ -22,6 +22,11 @@ window.API_METHODS = Object.assign(window.API_METHODS || {}, { styleExists: styleManager.styleExists, toggleStyle: styleManager.toggleStyle, + addInclusion: styleManager.addInclusion, + removeInclusion: styleManager.removeInclusion, + addExclusion: styleManager.addExclusion, + removeExclusion: styleManager.removeExclusion, + getTabUrlPrefix() { return this.sender.tab.url.match(/^([\w-]+:\/+[^/#]+)/)[1]; }, diff --git a/background/style-manager.js b/background/style-manager.js index c2b92382..1560f13e 100644 --- a/background/style-manager.js +++ b/background/style-manager.js @@ -57,10 +57,13 @@ const styleManager = (() => { importStyle, importMany, toggleStyle, - setStyleExclusions, getAllStyles, // used by import-export getStylesByUrl, // used by popup styleExists, + addExclusion, + removeExclusion, + addInclusion, + removeInclusion }); function handleLivePreviewConnections() { @@ -92,6 +95,11 @@ const styleManager = (() => { }); } + function escapeRegExp(text) { + // https://github.com/lodash/lodash/blob/0843bd46ef805dd03c0c8d804630804f3ba0ca3c/lodash.js#L152 + return text.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&'); + } + function get(id, noCode = false) { const data = styles.get(id).data; return noCode ? getStyleWithNoCode(data) : data; @@ -182,10 +190,46 @@ const styleManager = (() => { .then(newData => handleSave(newData, 'editSave')); } - function setStyleExclusions(id, exclusions) { - const data = Object.assign({}, styles.get(id).data, {exclusions}); + function addIncludeExclude(id, rule, type) { + const data = Object.assign({}, styles.get(id).data); + if (!data[type]) { + data[type] = []; + } + if (data[type].includes(rule)) { + throw new Error('The rule already exists'); + } + data[type] = data[type].concat([rule]); return saveStyle(data) - .then(newData => handleSave(newData, 'exclusions')); + .then(newData => handleSave(newData, 'styleSettings')); + } + + function removeIncludeExclude(id, rule, type) { + const data = Object.assign({}, styles.get(id).data); + if (!data[type]) { + return; + } + if (!data[type].includes(rule)) { + return; + } + data[type] = data[type].filter(r => r !== rule); + return saveStyle(data) + .then(newData => handleSave(newData, 'styleSettings')); + } + + function addExclusion(id, rule) { + return addIncludeExclude(id, rule, 'exclusions'); + } + + function removeExclusion(id, rule) { + return removeIncludeExclude(id, rule, 'exclusions'); + } + + function addInclusion(id, rule) { + return addIncludeExclude(id, rule, 'inclusions'); + } + + function removeInclusion(id, rule) { + return removeIncludeExclude(id, rule, 'inclusions'); } function deleteStyle(id) { @@ -479,14 +523,7 @@ const styleManager = (() => { } function buildGlob(text) { - const prefix = text[0] === '^' ? '' : '\\b'; - const suffix = text[text.length - 1] === '$' ? '' : '\\b'; - return `${prefix}${escape(text)}${suffix}`; - - function escape(text) { - // FIXME: using .* everywhere is slow - return text.replace(/[.*]/g, m => m === '.' ? '\\.' : '.*'); - } + return '^' + escapeRegExp(text).replace(/\\\\\\\*|\\\*/g, m => m.length > 2 ? m : '.*') + '$'; } function getDomain(url) { diff --git a/popup.html b/popup.html index baf48db3..c9d4f720 100644 --- a/popup.html +++ b/popup.html @@ -24,25 +24,55 @@