From 116395766e721b2d4881e578bfe04ac01dafbb96 Mon Sep 17 00:00:00 2001 From: shinigami-eyes <43276258+shinigami-eyes@users.noreply.github.com> Date: Wed, 17 Jul 2019 23:35:00 +0200 Subject: [PATCH] Support for different color schemes --- .vscode/settings.json | 1 + extension/background.ts | 31 +++++++++++- extension/content.css | 24 ++++++++- extension/content.ts | 17 +++++-- extension/definitions.d.ts | 4 +- extension/help.css | 30 +++++++++-- extension/help.html | 1 + extension/help.ts | 4 +- extension/manifest.json | 2 +- extension/options.html | 97 ++++++++++++++++++++++++++++++++++++ extension/options.js | 27 ++++++++++ extension/options.ts | 36 +++++++++++++ extension/webextensions.d.ts | 14 +++--- 13 files changed, 264 insertions(+), 24 deletions(-) create mode 100644 extension/options.html create mode 100644 extension/options.js create mode 100644 extension/options.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 7a9990d..de6de36 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,6 @@ "extension/background.js": true, "extension/content.js": true, "extension/help.js": true, + "extension/options.js": true, } } \ No newline at end of file diff --git a/extension/background.ts b/extension/background.ts index d528e2a..593e565 100644 --- a/extension/background.ts +++ b/extension/background.ts @@ -258,8 +258,9 @@ var overrides: LabelMap = null; var accepted = false; var installationId: string = null; +var theme: string = ''; -browser.storage.local.get(['overrides', 'accepted', 'installationId'], v => { +browser.storage.local.get(['overrides', 'accepted', 'installationId', 'theme'], v => { if (!v.installationId) { installationId = (Math.random() + '.' + Math.random() + '.' + Math.random()).replace(/\./g, ''); browser.storage.local.set({ installationId: installationId }); @@ -269,6 +270,7 @@ browser.storage.local.get(['overrides', 'accepted', 'installationId'], v => { accepted = v.accepted overrides = v.overrides || {} + theme = v.theme; const migration = overrides[MIGRATION] || 0; if (migration < CURRENT_VERSION) { @@ -312,13 +314,26 @@ async function loadBloomFilter(name: LabelKind) { browser.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.setTheme) { + theme = message.setTheme; + browser.storage.local.set({ theme: message.setTheme }); + chrome.tabs.query({}, function (tabs) { + for (var i = 0; i < tabs.length; ++i) { + try { + browser.tabs.sendMessage(tabs[i].id, { updateAllLabels: true }); + } catch (e) { } + } + }); + } if (message.acceptClicked !== undefined) { accepted = message.acceptClicked; browser.storage.local.set({ accepted: accepted }); - browser.tabs.remove(sender.tab.id); if (accepted && uncommittedResponse) saveLabel(uncommittedResponse) uncommittedResponse = null; + } + if (message.closeCallingTab) { + browser.tabs.remove(sender.tab.id); return; } const response: LabelMap = {}; @@ -340,6 +355,7 @@ browser.runtime.onMessage.addListenertheme; sendResponse(response); }); @@ -373,6 +389,8 @@ function createContextMenu(text: string, id: ContextMenuCommand) { createContextMenu('Mark as anti-trans', 'mark-transphobic'); createContextMenu('Mark as t-friendly', 'mark-t-friendly'); createContextMenu('Clear', 'mark-none'); +browser.contextMenus.create({ type: 'separator' }); +createContextMenu('Settings', 'options'); createContextMenu('Help', 'help'); var uncommittedResponse: ShinigamiEyesSubmission = null; @@ -440,12 +458,21 @@ function openHelp() { } +function openOptions() { + browser.tabs.create({ + url: browser.extension.getURL('options.html') + }) +} browser.contextMenus.onClicked.addListener(function (info, tab) { if (info.menuItemId == 'help') { openHelp(); return; } + if (info.menuItemId == 'options') { + openOptions(); + return; + } const tabId = tab.id; const frameId = info.frameId; diff --git a/extension/content.css b/extension/content.css index 947e02c..6636434 100644 --- a/extension/content.css +++ b/extension/content.css @@ -1,5 +1,25 @@ -.assigned-label-transphobic, a.assigned-label-transphobic { color: #991515 !important; } -.assigned-label-t-friendly, a.assigned-label-t-friendly { color: #77B91E !important; } +body { + --ShinigamiEyesTFriendly: #77B91E; + --ShinigamiEyesTransphobic: #991515; +} + +.shinigami-eyes-theme-green-red-max { + --ShinigamiEyesTFriendly: #00FF00; + --ShinigamiEyesTransphobic: #FF0000; +} + +.shinigami-eyes-theme-purple-yellow { + --ShinigamiEyesTFriendly: rgb(153, 0, 255); + --ShinigamiEyesTransphobic: rgb(179, 152, 0); +} + +.shinigami-eyes-theme-cyan-orange { + --ShinigamiEyesTFriendly: rgb(98, 161, 197); + --ShinigamiEyesTransphobic: #FB6A4A; +} + +.assigned-label-transphobic, a.assigned-label-transphobic { color: var(--ShinigamiEyesTransphobic) !important; } +.assigned-label-t-friendly, a.assigned-label-t-friendly { color: var(--ShinigamiEyesTFriendly) !important; } .has-assigned-label * { color: inherit !important; } .shinigami-eyes-debug-snippet-highlight { diff --git a/extension/content.ts b/extension/content.ts index 6b93a5c..3fd8470 100644 --- a/extension/content.ts +++ b/extension/content.ts @@ -26,13 +26,13 @@ function fixupSiteStyles() { `); } else if (domainIs(hostname, 'tumblr.com')) { addStyleSheet(` - .assigned-label-transphobic { outline: 2px solid #991515 !important; } - .assigned-label-t-friendly { outline: 1px solid #77B91E !important; } + .assigned-label-transphobic { outline: 2px solid var(--ShinigamiEyesTransphobic) !important; } + .assigned-label-t-friendly { outline: 1px solid var(--ShinigamiEyesTFriendly) !important; } `); } else if (hostname.indexOf('wiki') != -1) { addStyleSheet(` - .assigned-label-transphobic { outline: 1px solid #991515 !important; } - .assigned-label-t-friendly { outline: 1px solid #77B91E !important; } + .assigned-label-transphobic { outline: 1px solid var(--ShinigamiEyesTransphobic) !important; } + .assigned-label-t-friendly { outline: 1px solid var(--ShinigamiEyesTFriendly) !important; } `); } else if (hostname == 'twitter.com') { myself = getIdentifier(document.querySelector('.DashUserDropdown-userInfo a')); @@ -167,6 +167,7 @@ function updateAllLabels(refresh?: boolean) { } var knownLabels: LabelMap = {}; +var currentlyAppliedTheme = '_none_'; var labelsToSolve: LabelToSolve[] = []; function solvePendingLabels() { @@ -175,8 +176,14 @@ function solvePendingLabels() { var tosolve = labelsToSolve; labelsToSolve = []; browser.runtime.sendMessage({ ids: uniqueIdentifiers, myself: myself }, (response: LabelMap) => { + const theme = response[':theme']; + if (theme != currentlyAppliedTheme) { + if (currentlyAppliedTheme) document.body.classList.remove('shinigami-eyes-theme-' + currentlyAppliedTheme); + if (theme) document.body.classList.add('shinigami-eyes-theme-' + theme); + currentlyAppliedTheme = theme; + } for (const item of tosolve) { - var label = response[item.identifier]; + const label = response[item.identifier]; knownLabels[item.identifier] = label || ''; applyLabel(item.element, item.identifier); } diff --git a/extension/definitions.d.ts b/extension/definitions.d.ts index 680069b..471cbe7 100644 --- a/extension/definitions.d.ts +++ b/extension/definitions.d.ts @@ -30,10 +30,12 @@ interface ShinigamiEyesCommand { myself?: string ids?: string[] updateAllLabels?: boolean + closeCallingTab?: boolean + setTheme?: string } type LabelMap = { [identifier: string]: LabelKind }; interface ShinigamiEyesMessage extends ShinigamiEyesSubmission, ShinigamiEyesCommand { } -type ContextMenuCommand = 'mark-t-friendly' | 'mark-transphobic' | 'mark-none' | 'help'; +type ContextMenuCommand = 'mark-t-friendly' | 'mark-transphobic' | 'mark-none' | 'help' | 'options'; diff --git a/extension/help.css b/extension/help.css index 664cc7d..0885c81 100644 --- a/extension/help.css +++ b/extension/help.css @@ -7,9 +7,10 @@ body { padding: 0; } - -.assigned-label-transphobic { color: #991515 !important; } -.assigned-label-t-friendly { color: #77B91E !important; } +.assigned-label-unknown { + color: rgb(56, 88, 152); /* Facebook default link color */ + cursor: help; +} h1 { font-size: 40pt; @@ -52,9 +53,8 @@ section { .section-faq { background-color: rgb(213, 183, 255); } -.section-guidelines { +.section-guidelines, .section-options { background-color: white; - /*background-color: rgb(190, 245, 151);*/ } .section-footer { @@ -123,4 +123,24 @@ section { font-size: 10pt; } +.website-checkbox { + display: block; + user-select: none; +} +.website-checkbox i { + color: gray; +} +#theme-settings label { + user-select: none; + font-weight: bold; + display: block; +} +#save-button { + font-weight: bold; + background-color: rgb(108, 212, 76); +} + +label, button { + cursor: pointer; +} diff --git a/extension/help.html b/extension/help.html index 8d2027f..defed59 100644 --- a/extension/help.html +++ b/extension/help.html @@ -4,6 +4,7 @@ Shinigami Eyes + + + + +
+ +
+
+

Shinigami Eyes settings

+
+
+ + +
+
+ +

Colors

+
+
+ + + +

Guidelines

+ Go to Guidelines for an overview of what kind of content should be marked one + way or the other. + +

+ + +


+
+
+ + + + + +
+ + + + \ No newline at end of file diff --git a/extension/options.js b/extension/options.js new file mode 100644 index 0000000..33c231a --- /dev/null +++ b/extension/options.js @@ -0,0 +1,27 @@ +var browser = browser || chrome; +browser.storage.local.get(['theme'], obj => { + var theme = obj.theme || 'green-red'; + var themeSettingsContainer = document.getElementById('theme-settings'); + [ + 'green-red', + 'purple-yellow', + 'cyan-orange', + ].map(x => { + themeSettingsContainer.insertAdjacentHTML('beforeend', ` + + `); + }); +}); +document.getElementById('save-button').addEventListener('click', async () => { + var theme = [...document.querySelectorAll('.shinigami-eyes-theme input')] + .filter(x => x.checked)[0].dataset.theme; + browser.runtime.sendMessage({ closeCallingTab: true, setTheme: theme }, () => { }); +}); +document.getElementById('cancel-button').addEventListener('click', async () => { + browser.runtime.sendMessage({ closeCallingTab: true }, () => { }); +}); diff --git a/extension/options.ts b/extension/options.ts new file mode 100644 index 0000000..527b47c --- /dev/null +++ b/extension/options.ts @@ -0,0 +1,36 @@ +var browser: Browser = browser || chrome; + +browser.storage.local.get(['theme'], obj => { + + var theme: string = obj.theme || 'green-red'; + var themeSettingsContainer = document.getElementById('theme-settings'); + + [ + 'green-red', + 'purple-yellow', + 'cyan-orange', + ].map(x => { + themeSettingsContainer.insertAdjacentHTML('beforeend', ` + + `); + }); + +}); + +document.getElementById('save-button').addEventListener('click', async () => { + var theme = ( + [...document.querySelectorAll('.shinigami-eyes-theme input')] + .filter(x => (x).checked)[0] + ).dataset.theme; + browser.runtime.sendMessage({ closeCallingTab: true, setTheme: theme }, () => { }); +}); + + +document.getElementById('cancel-button').addEventListener('click', async () => { + browser.runtime.sendMessage({ closeCallingTab: true }, () => { }); +}); diff --git a/extension/webextensions.d.ts b/extension/webextensions.d.ts index 539a8a2..48100cd 100644 --- a/extension/webextensions.d.ts +++ b/extension/webextensions.d.ts @@ -18,16 +18,18 @@ declare type Browser = { create(options: { url: string }): void + query(query: {}, callback: (tabs: { id: number }[]) => void): void; } extension: { getURL(relativeUrl: string): string } contextMenus: { create(options: { - id: string - title: string - contexts: 'link'[] - targetUrlPatterns: string[] + id?: string + title?: string + contexts?: 'link'[] + targetUrlPatterns?: string[] + type?: 'normal' | 'separator' }): void onClicked: { addListener(listener: (info: { @@ -41,12 +43,12 @@ declare type Browser = { } } type MessageSender = { - tab?: {id: number}; + tab?: { id: number }; frameId?: number; id?: string; url?: string; tlsChannelId?: string; - }; +}; declare type BrowserStorage = { get(names: string[], callback: (obj: any) => void): void set(obj: { [name: string]: any }): void;