Display site labeling confirmation messages and errors.

This commit is contained in:
shinigami-eyes 2019-10-06 16:31:46 +02:00
parent 6f77313363
commit 5c8735cd66
3 changed files with 127 additions and 55 deletions

View File

@ -5,34 +5,37 @@ const MIGRATION = ':MIGRATION'
const CURRENT_VERSION = 100021; 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. // If a user labels one of these URLs, they're making a mistake. Ignore the label.
// This list includes: // This list includes:
// * Social networks that are not supported // * Social networks that are not supported (SN)
// * System pages of supported social networks // * System pages of supported social networks
// * Archival and link shortening sites. // * Archival and link shortening sites. (AR)
// * Reddit bots. // * Reddit bots.
const badIdentifiersArray = [ const badIdentifiersArray = [
'archive.is', 'archive.is=AR',
'archive.org', 'archive.org=AR',
'ask.fm', 'ask.fm=SN',
'assets.tumblr.com', 'assets.tumblr.com',
'bing.com', 'bing.com',
'bit.ly', 'bit.ly',
'blogspot.com', 'blogspot.com',
'change.org', 'change.org',
'chrome.google.com', 'chrome.google.com',
'curiouscat.me', 'curiouscat.me=SN',
'deviantart.com', 'deviantart.com=SN',
'discord-store.com', 'discord-store.com=SN',
'discord.gg', 'discord.gg=SN',
'discordapp.com', 'discordapp.com=SN',
'disqus.com', 'disqus.com',
'docs.google.com', 'docs.google.com',
'drive.google.com', 'drive.google.com',
'duckduckgo.com', 'duckduckgo.com',
'en.wikipedia.org', 'en.wikipedia.org',
'en.wikiquote.org', 'en.wikiquote.org',
'etsy.com', 'etsy.com=SN',
'facebook.com', 'facebook.com',
'facebook.com/a', 'facebook.com/a',
'facebook.com/ad_campaign', 'facebook.com/ad_campaign',
@ -99,25 +102,25 @@ const badIdentifiersArray = [
'facebook.com/story.php', 'facebook.com/story.php',
'facebook.com/ufi', 'facebook.com/ufi',
'facebook.com/watch', 'facebook.com/watch',
'flickr.com', 'flickr.com=SN',
'goo.gl', 'goo.gl',
'google.com', 'google.com',
'googleusercontent.com', 'googleusercontent.com',
'i.imgur.com', 'i.imgur.com',
'i.reddituploads.com', 'i.reddituploads.com',
'imdb.com', 'imdb.com=SN',
'imgur.com', 'imgur.com',
'instagram.com', 'instagram.com=SN',
'itunes.apple.com', 'itunes.apple.com=SN',
'ko-fi.com', 'ko-fi.com=SN',
'linkedin.com', 'linkedin.com=SN',
'mail.google.com', 'mail.google.com',
'media.tumblr.com', 'media.tumblr.com',
'medium.com', 'medium.com',
'news.google.com', 'news.google.com',
'patreon.com', 'patreon.com=SN',
'paypal.com', 'paypal.com=SN',
'paypal.me', 'paypal.me=SN',
'play.google.com', 'play.google.com',
'plus.google.com', 'plus.google.com',
'rationalwiki.org', 'rationalwiki.org',
@ -224,25 +227,29 @@ const badIdentifiersArray = [
'reddituploads.com', 'reddituploads.com',
'removeddit.com', 'removeddit.com',
'sites.google.com', 'sites.google.com',
'snapchat.com', 'snapchat.com=SN',
'soundcloud.com', 'soundcloud.com=SN',
'steamcommunity.com', 'steamcommunity.com=SN',
't.co', 't.co',
't.umblr.com', 't.umblr.com',
'tapatalk.com', 'tapatalk.com=SN',
'tmblr.co', 'tmblr.co',
'tumblr.com', 'tumblr.com',
'twitch.tv', 'twitch.tv=SN',
'twitter.com', 'twitter.com',
'twitter.com/explore',
'twitter.com/hashtag', 'twitter.com/hashtag',
'twitter.com/home',
'twitter.com/i', 'twitter.com/i',
'twitter.com/messages',
'twitter.com/notifications',
'twitter.com/search', 'twitter.com/search',
'twitter.com/settings', 'twitter.com/settings',
'twitter.com/threader_app', 'twitter.com/threader_app',
'twitter.com/threadreaderapp', 'twitter.com/threadreaderapp',
'twitter.com/who_to_follow', 'twitter.com/who_to_follow',
'vimeo.com', 'vimeo.com=SN',
'vk.com', 'vk.com=SN',
'wikipedia.org', 'wikipedia.org',
'wordpress.com', 'wordpress.com',
'www.tumblr.com', 'www.tumblr.com',
@ -251,9 +258,13 @@ const badIdentifiersArray = [
'youtube.com/playlist', 'youtube.com/playlist',
'youtube.com/redirect', 'youtube.com/redirect',
'youtube.com/watch', 'youtube.com/watch',
]; ].map(x => {
const badIdentifiers: { [id: string]: true } = {}; const arr = x.split('=');
badIdentifiersArray.forEach(x => badIdentifiers[x] = true); const id = arr[0];
if (arr[1]) badIdentifiersReasons[id] = <BadIdentifierReason>arr[1];
badIdentifiers[id] = true;
return id;
});
var lastSubmissionError: string = null; var lastSubmissionError: string = null;
@ -321,7 +332,7 @@ browser.runtime.onMessage.addListener<ShinigamiEyesMessage, ShinigamiEyesMessage
chrome.tabs.query({}, function (tabs) { chrome.tabs.query({}, function (tabs) {
for (var i = 0; i < tabs.length; ++i) { for (var i = 0; i < tabs.length; ++i) {
try { try {
browser.tabs.sendMessage(tabs[i].id, <ShinigamiEyesCommand>{ updateAllLabels: true }); sendMessageToContent(tabs[i].id, null, { updateAllLabels: true });
} catch (e) { } } catch (e) { }
} }
}); });
@ -457,11 +468,11 @@ function saveLabel(response: ShinigamiEyesSubmission) {
getPendingSubmissions().push(response); getPendingSubmissions().push(response);
submitPendingRatings(); submitPendingRatings();
//console.log(response); //console.log(response);
browser.tabs.sendMessage(response.tabId, <ShinigamiEyesCommand>{ sendMessageToContent(response.tabId, response.frameId, {
updateAllLabels: true, updateAllLabels: true,
confirmSetIdentifier: response.identifier, confirmSetIdentifier: response.identifier,
confirmSetLabel: response.mark confirmSetLabel: response.mark || 'none'
}); });
//browser.tabs.executeScript(response.tabId, {code: 'updateAllLabels()'}); //browser.tabs.executeScript(response.tabId, {code: 'updateAllLabels()'});
return; 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<ShinigamiEyesCommand, void>(tabId, message, options);
}
browser.contextMenus.onClicked.addListener(function (info, tab) { browser.contextMenus.onClicked.addListener(function (info, tab) {
if (info.menuItemId == 'help') { if (info.menuItemId == 'help') {
openHelp(); openHelp();
@ -505,16 +524,18 @@ browser.contextMenus.onClicked.addListener(function (info, tab) {
// elementId: info.targetElementId, // elementId: info.targetElementId,
debug: <any>overrides.debug debug: <any>overrides.debug
}, { frameId: frameId }, response => { }, { frameId: frameId }, response => {
if (!response.identifier){ if (!response || !response.identifier) {
browser.tabs.sendMessage(response.tabId, <ShinigamiEyesCommand>{
updateAllLabels: true,
confirmSetIdentifier: response.identifier,
confirmSetLabel: response.mark
});
return; return;
} }
if (response.mark) { 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]) if (response.secondaryIdentifier && badIdentifiers[response.secondaryIdentifier])
response.secondaryIdentifier = null; response.secondaryIdentifier = null;
} }

View File

@ -530,26 +530,72 @@ function getSnippet(node: HTMLElement) {
return null; 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'); const confirmation = document.createElement('div');
confirmation.style.cssText = 'position: fixed; padding: 15px; z-index: 99999999;'; const background =
confirmation.textContent = identifier + ( label == 't-friendly' ? '#eaffcf' :
label == 't-friendly' ? ' will be displayed as trans-friendly' : label == 'transphobic' ? '#f5d7d7' :
label == 'transphobic' ? ' will be displayed as anti-trans' : '#eeeeee';
' has been cleared.' 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;`;
) + ' on search engines and social networks.' 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); document.body.appendChild(confirmation);
previousConfirmationMessage = confirmation;
confirmation.addEventListener('mousedown', () => confirmation.remove());
setTimeout(() => {
confirmation.style.opacity = '0';
}, 2000);
setTimeout(() => { setTimeout(() => {
confirmation.remove(); confirmation.remove();
}, 3000); }, 9000);
} }
browser.runtime.onMessage.addListener<ShinigamiEyesMessage, ShinigamiEyesSubmission>((message, sender, sendResponse) => { browser.runtime.onMessage.addListener<ShinigamiEyesMessage, ShinigamiEyesSubmission>((message, sender, sendResponse) => {
if (message.updateAllLabels) { if (message.updateAllLabels || message.confirmSetLabel) {
if(!isSocialNetwork && message.confirmSetLabel){ displayConfirmation(message.confirmSetIdentifier, message.confirmSetLabel, message.badIdentifierReason, message.url);
displayConfirmation(message.confirmSetIdentifier, message.confirmSetLabel);
}
updateAllLabels(true); updateAllLabels(true);
return; return;
} }
@ -565,7 +611,10 @@ browser.runtime.onMessage.addListener<ShinigamiEyesMessage, ShinigamiEyesSubmiss
if (target && (<HTMLAnchorElement>target).href != message.url) target = null; if (target && (<HTMLAnchorElement>target).href != message.url) target = null;
var identifier = target ? getIdentifier(<HTMLAnchorElement>target) : getIdentifier(message.url); var identifier = target ? getIdentifier(<HTMLAnchorElement>target) : getIdentifier(message.url);
if (!identifier) return; if (!identifier) {
displayConfirmation(null, 'bad-identifier', null, message.url);
return;
}
message.identifier = identifier; message.identifier = identifier;
if (identifier.startsWith('facebook.com/')) if (identifier.startsWith('facebook.com/'))

View File

@ -10,7 +10,7 @@ interface LabelToSolve {
element: HTMLAnchorElement element: HTMLAnchorElement
identifier: string identifier: string
} }
type LabelKind = 't-friendly' | 'transphobic' | 'none' | ''; type LabelKind = 't-friendly' | 'transphobic' | 'none' | '' | 'bad-identifier';
interface ShinigamiEyesSubmission { interface ShinigamiEyesSubmission {
mark?: LabelKind mark?: LabelKind
url?: string url?: string
@ -35,6 +35,7 @@ interface ShinigamiEyesCommand {
setTheme?: string setTheme?: string
confirmSetIdentifier?: string confirmSetIdentifier?: string
confirmSetLabel?: LabelKind confirmSetLabel?: LabelKind
badIdentifierReason?: BadIdentifierReason
} }
type LabelMap = { [identifier: string]: LabelKind }; 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 ContextMenuCommand = 'mark-t-friendly' | 'mark-transphobic' | 'mark-none' | 'help' | 'options';
type BadIdentifierReason = 'SN' | 'AR';