diff --git a/extension/background.ts b/extension/background.ts index acc1c4b..d6d2e28 100644 --- a/extension/background.ts +++ b/extension/background.ts @@ -5,34 +5,37 @@ const MIGRATION = ':MIGRATION' const CURRENT_VERSION = 100021; +const badIdentifiersReasons: { [id: string]: BadIdentifierReason } = {}; +const badIdentifiers: { [id: string]: true } = {}; + // If a user labels one of these URLs, they're making a mistake. Ignore the label. // This list includes: -// * Social networks that are not supported +// * Social networks that are not supported (SN) // * System pages of supported social networks -// * Archival and link shortening sites. +// * Archival and link shortening sites. (AR) // * Reddit bots. const badIdentifiersArray = [ - 'archive.is', - 'archive.org', - 'ask.fm', + 'archive.is=AR', + 'archive.org=AR', + 'ask.fm=SN', 'assets.tumblr.com', 'bing.com', 'bit.ly', 'blogspot.com', 'change.org', 'chrome.google.com', - 'curiouscat.me', - 'deviantart.com', - 'discord-store.com', - 'discord.gg', - 'discordapp.com', + 'curiouscat.me=SN', + 'deviantart.com=SN', + 'discord-store.com=SN', + 'discord.gg=SN', + 'discordapp.com=SN', 'disqus.com', 'docs.google.com', 'drive.google.com', 'duckduckgo.com', 'en.wikipedia.org', 'en.wikiquote.org', - 'etsy.com', + 'etsy.com=SN', 'facebook.com', 'facebook.com/a', 'facebook.com/ad_campaign', @@ -99,25 +102,25 @@ const badIdentifiersArray = [ 'facebook.com/story.php', 'facebook.com/ufi', 'facebook.com/watch', - 'flickr.com', + 'flickr.com=SN', 'goo.gl', 'google.com', 'googleusercontent.com', 'i.imgur.com', 'i.reddituploads.com', - 'imdb.com', + 'imdb.com=SN', 'imgur.com', - 'instagram.com', - 'itunes.apple.com', - 'ko-fi.com', - 'linkedin.com', + 'instagram.com=SN', + 'itunes.apple.com=SN', + 'ko-fi.com=SN', + 'linkedin.com=SN', 'mail.google.com', 'media.tumblr.com', 'medium.com', 'news.google.com', - 'patreon.com', - 'paypal.com', - 'paypal.me', + 'patreon.com=SN', + 'paypal.com=SN', + 'paypal.me=SN', 'play.google.com', 'plus.google.com', 'rationalwiki.org', @@ -224,25 +227,29 @@ const badIdentifiersArray = [ 'reddituploads.com', 'removeddit.com', 'sites.google.com', - 'snapchat.com', - 'soundcloud.com', - 'steamcommunity.com', + 'snapchat.com=SN', + 'soundcloud.com=SN', + 'steamcommunity.com=SN', 't.co', 't.umblr.com', - 'tapatalk.com', + 'tapatalk.com=SN', 'tmblr.co', 'tumblr.com', - 'twitch.tv', + 'twitch.tv=SN', 'twitter.com', + 'twitter.com/explore', 'twitter.com/hashtag', + 'twitter.com/home', 'twitter.com/i', + 'twitter.com/messages', + 'twitter.com/notifications', 'twitter.com/search', 'twitter.com/settings', 'twitter.com/threader_app', 'twitter.com/threadreaderapp', 'twitter.com/who_to_follow', - 'vimeo.com', - 'vk.com', + 'vimeo.com=SN', + 'vk.com=SN', 'wikipedia.org', 'wordpress.com', 'www.tumblr.com', @@ -251,9 +258,13 @@ const badIdentifiersArray = [ 'youtube.com/playlist', 'youtube.com/redirect', 'youtube.com/watch', -]; -const badIdentifiers: { [id: string]: true } = {}; -badIdentifiersArray.forEach(x => badIdentifiers[x] = true); +].map(x => { + const arr = x.split('='); + const id = arr[0]; + if (arr[1]) badIdentifiersReasons[id] = arr[1]; + badIdentifiers[id] = true; + return id; +}); var lastSubmissionError: string = null; @@ -321,7 +332,7 @@ browser.runtime.onMessage.addListener{ updateAllLabels: true }); + sendMessageToContent(tabs[i].id, null, { updateAllLabels: true }); } catch (e) { } } }); @@ -457,11 +468,11 @@ function saveLabel(response: ShinigamiEyesSubmission) { getPendingSubmissions().push(response); submitPendingRatings(); //console.log(response); - browser.tabs.sendMessage(response.tabId, { + sendMessageToContent(response.tabId, response.frameId, { updateAllLabels: true, confirmSetIdentifier: response.identifier, - confirmSetLabel: response.mark - }); + confirmSetLabel: response.mark || 'none' + }); //browser.tabs.executeScript(response.tabId, {code: 'updateAllLabels()'}); return; } @@ -482,6 +493,14 @@ function openOptions() { }) } + + +function sendMessageToContent(tabId: number, frameId: number, message: ShinigamiEyesCommand) { + const options = frameId === null ? undefined : { frameId: frameId }; + console.log(message); + browser.tabs.sendMessage(tabId, message, options); +} + browser.contextMenus.onClicked.addListener(function (info, tab) { if (info.menuItemId == 'help') { openHelp(); @@ -505,16 +524,18 @@ browser.contextMenus.onClicked.addListener(function (info, tab) { // elementId: info.targetElementId, debug: overrides.debug }, { frameId: frameId }, response => { - if (!response.identifier){ - browser.tabs.sendMessage(response.tabId, { - updateAllLabels: true, - confirmSetIdentifier: response.identifier, - confirmSetLabel: response.mark - }); + if (!response || !response.identifier) { return; } if (response.mark) { - if (badIdentifiers[response.identifier]) return; + if (badIdentifiers[response.identifier]) { + sendMessageToContent(tabId, frameId, { + confirmSetIdentifier: response.identifier, + confirmSetLabel: 'bad-identifier', + badIdentifierReason: badIdentifiersReasons[response.identifier] + }); + return; + } if (response.secondaryIdentifier && badIdentifiers[response.secondaryIdentifier]) response.secondaryIdentifier = null; } diff --git a/extension/content.ts b/extension/content.ts index 8f9f284..bd90639 100644 --- a/extension/content.ts +++ b/extension/content.ts @@ -530,26 +530,72 @@ function getSnippet(node: HTMLElement) { return null; } -function displayConfirmation(identifier: string, label: LabelKind){ +function getBadIdentifierReason(identifier: string, url: string) { + identifier = identifier || ''; + url = url || ''; + if ( + identifier.startsWith('reddit.com/user/') || + identifier == 'twitter.com/threadreaderapp' || + identifier == 'twitter.com/threader_app') return 'This is user is a bot.'; + if (identifier == 'twitter.com/hashtag') return 'Hashtags cannot be labeled, only users.'; + if (url.includes('youtube.com/watch')) return 'Only channels can be labeled, not specific videos.'; + if (url.includes('wiki') && url.includes('#')) return 'Wiki paragraphs cannot be labeled, only whole articles.'; + return null; +} + +var previousConfirmationMessage: HTMLElement = null; + +function displayConfirmation(identifier: string, label: LabelKind, badIdentifierReason: BadIdentifierReason, url: string) { + if (previousConfirmationMessage) { + previousConfirmationMessage.remove(); + previousConfirmationMessage = null; + } + if (!label) return; + if (isSocialNetwork && label != 'bad-identifier') return; + const confirmation = document.createElement('div'); - confirmation.style.cssText = 'position: fixed; padding: 15px; z-index: 99999999;'; - confirmation.textContent = identifier + ( - label == 't-friendly' ? ' will be displayed as trans-friendly' : - label == 'transphobic' ? ' will be displayed as anti-trans' : - ' has been cleared.' - ) + ' on search engines and social networks.' + const background = + label == 't-friendly' ? '#eaffcf' : + label == 'transphobic' ? '#f5d7d7' : + '#eeeeee'; + confirmation.style.cssText = `transition: opacity 7s ease-in-out; opacity: 1; position: fixed; padding: 30px 15px; z-index: 99999999; white-space: pre-wrap; top: 200px; left: 30%; right: 30%; background: ${background}; color: black; font-weight: bold; font-family: Arial; box-shadow: 0px 5px 10px #ddd; border: 1px solid #ccc; font-size: 11pt;`; + let text: string; + + if (label == 'bad-identifier') { + const displayReason = getBadIdentifierReason(identifier, url); + if (displayReason) text = displayReason; + else if (badIdentifierReason == 'SN') text = 'This social network is not supported: ' + identifier + '.'; + else if (badIdentifierReason == 'AR') text = 'This is an archival link, it cannot be labeled: ' + identifier; + else text = `This item could not be labeled. Possible reasons: + • It doesn't represent a specific user or page + • It's not a kind of object supported by Shinigami Eyes + + ${identifier || url} +`; + } else { + text = identifier + ( + label == 't-friendly' ? ' will be displayed as trans-friendly on search engines and social networks.' : + label == 'transphobic' ? ' will be displayed as anti-trans on search engines and social networks.' : + ' has been cleared.' + ); + } + confirmation.textContent = text; document.body.appendChild(confirmation); + previousConfirmationMessage = confirmation; + confirmation.addEventListener('mousedown', () => confirmation.remove()); + setTimeout(() => { + confirmation.style.opacity = '0'; + }, 2000); + setTimeout(() => { confirmation.remove(); - }, 3000); + }, 9000); } browser.runtime.onMessage.addListener((message, sender, sendResponse) => { - if (message.updateAllLabels) { - if(!isSocialNetwork && message.confirmSetLabel){ - displayConfirmation(message.confirmSetIdentifier, message.confirmSetLabel); - } + if (message.updateAllLabels || message.confirmSetLabel) { + displayConfirmation(message.confirmSetIdentifier, message.confirmSetLabel, message.badIdentifierReason, message.url); updateAllLabels(true); return; } @@ -565,7 +611,10 @@ browser.runtime.onMessage.addListenertarget).href != message.url) target = null; var identifier = target ? getIdentifier(target) : getIdentifier(message.url); - if (!identifier) return; + if (!identifier) { + displayConfirmation(null, 'bad-identifier', null, message.url); + return; + } message.identifier = identifier; if (identifier.startsWith('facebook.com/')) diff --git a/extension/definitions.d.ts b/extension/definitions.d.ts index 53fafbc..0a721e2 100644 --- a/extension/definitions.d.ts +++ b/extension/definitions.d.ts @@ -10,7 +10,7 @@ interface LabelToSolve { element: HTMLAnchorElement identifier: string } -type LabelKind = 't-friendly' | 'transphobic' | 'none' | ''; +type LabelKind = 't-friendly' | 'transphobic' | 'none' | '' | 'bad-identifier'; interface ShinigamiEyesSubmission { mark?: LabelKind url?: string @@ -35,6 +35,7 @@ interface ShinigamiEyesCommand { setTheme?: string confirmSetIdentifier?: string confirmSetLabel?: LabelKind + badIdentifierReason?: BadIdentifierReason } type LabelMap = { [identifier: string]: LabelKind }; @@ -42,3 +43,4 @@ interface ShinigamiEyesMessage extends ShinigamiEyesSubmission, ShinigamiEyesCom } type ContextMenuCommand = 'mark-t-friendly' | 'mark-transphobic' | 'mark-none' | 'help' | 'options'; +type BadIdentifierReason = 'SN' | 'AR'; \ No newline at end of file