From cf9c4c30f7491a92c7017de4e79e7498986042e5 Mon Sep 17 00:00:00 2001 From: David Byers <david.byers@liu.se> Date: Fri, 22 Jan 2021 12:55:26 +0100 Subject: [PATCH] Added support for copying the original URL. New icon. Code cleanup. --- extension/assets/shield.png | Bin 692 -> 0 bytes extension/background.js | 33 +++++++++--- extension/common.js | 21 ++++++++ extension/content.js | 100 ++++++++++++++---------------------- extension/icon.svg | 23 ++++++++- extension/manifest.json | 65 ++++++++++++----------- extension/style.css | 36 ++++++------- 7 files changed, 159 insertions(+), 119 deletions(-) delete mode 100755 extension/assets/shield.png create mode 100644 extension/common.js diff --git a/extension/assets/shield.png b/extension/assets/shield.png deleted file mode 100755 index d22b20a9cd4d436f465d19dd3f42439f701c856d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 692 zcmV;l0!#ggP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00006VoOIv0RI60 z0RN!9r;`8x0%=J^K~!jg?U_Gl6hRcme;O4G5pyDfNr=}Q5)xyV($3fiNx)KU(g@ay zy`-{H5Q#!CT_BBr5DVcH1WgD+iVMU_g<wcPJacEUd&l0~?%SQ&*`0Xo2M=y`-h1<X zvv1~R?w~+-;wW$pcmuo!ru}D!9wp!oPz4%_RsFt_Gj;;Xzyh#KCvnwwec!SJo*kG1 zR)7QIiK}+t$4=!<I#}Nl!F}Lij8D^YStn9`2W<<O2Tu8MI&USDby6l-eZR+hGwLkr zmX@`3lBB->0#AWULLL(VR@RA>_&4wv7)hB&$E*n0#;fnsDf2iHa1-dYkjJWkBQXOf z^_5^Wdm#uN|Gzk&NGJrjMj^m83IVRs)dFg{v53c?sE%Vo&_2*_VelQpxZs^&FUm<0 z@RN1{rbhykBgi1|EztfE<tUX<)nH&-m{i)4TqFTs?Qk)|xYCZ~A_@3lhl>%eDD8?# zl40CjM23NSAij>bCXDdKfq>ge{3ppd?u+b&0f96)4%||nEvHF1g!jusUT@%r5?ce# zrx5_Kl#_rHz@`%WEG>C}3ECG`Rs!xSadlwKh5&#knxu6FT*fPxVB8~H<iXp<erXa< zD&P#Tp~UQ9q4rhGY7$Q(pbz*M5;J3)d=t-O$m$5_16D))7c=4xz)8YqOjp1K;B$y? z#UCS6oWna@nF_cLd=K&40M2I2y@erQJ%ofL;3Duc!e<Q_$ccLkCF1{PY5;S<JE8v- zc5Z$~=mGB2xrZmQ8gS3g;T&Vgv#i=%VAKWCI7}n&QWfB;Gj<x703P7oWvl*Y^_p0q aEAS8dkoUiK1nWZp0000<MNUMnLSTYTdoybQ diff --git a/extension/background.js b/extension/background.js index c336d48..1618c3a 100644 --- a/extension/background.js +++ b/extension/background.js @@ -1,8 +1,25 @@ -browser.messageDisplayScripts.register({ - css: [{ - file: "/style.css", - }], - js: [{ - file: "/content.js", - }], -}); +browser.messageDisplayScripts.register({ + css: [ + {file: "/style.css"} + ], + js: [ + {file: "/common.js"}, + {file: "/content.js"} + ], +}); + + +browser.menus.create({ + id: "liu-safelinks-copy", + title: "Copy original link", + contexts: ["link"], + visible: true, + targetUrlPatterns: ["*://*.safelinks.protection.outlook.com/*"], +}); + +browser.menus.onClicked.addListener((info, tab) => { + if (info.menuItemId == "liu-safelinks-copy") { + navigator.clipboard.writeText(untangleLink(info.linkUrl)); + } +}); + diff --git a/extension/common.js b/extension/common.js new file mode 100644 index 0000000..e872137 --- /dev/null +++ b/extension/common.js @@ -0,0 +1,21 @@ +const safelinksRegexp = new RegExp( + 'https?://[^.]+[.]safelinks[.]protection[.]outlook[.]com/[?]url=([^&]+)&.*', + 'gi' +); + +function untangleLink(link) { + return link.replaceAll( + safelinksRegexp, (match, url) => { + try { + return decodeURIComponent(url); + } + catch (e) { + console.log(e); + return url; + } + }); +} + +function isTangledLink(link) { + return link.match(safelinksRegexp); +} diff --git a/extension/content.js b/extension/content.js index 4542ea3..32b8707 100644 --- a/extension/content.js +++ b/extension/content.js @@ -1,61 +1,39 @@ -// Modify the displayed message to clarify where safelinks are -// inserted and to show the actual link targets. - -const safelinksRegexp = new RegExp( - 'https?://[^.]+[.]safelinks[.]protection[.]outlook[.]com/[?]url=([^&]+)&.*', - 'gi' -); - -function getTextNodes(elem) { - var result = []; - if (elem) { - for (var nodes = elem.childNodes, i = nodes.length; i--;) { - let node = nodes[i]; - let nodeType = node.nodeType; - - if (nodeType == Node.TEXT_NODE) { - result.push(node); - } - else if (nodeType == Node.ELEMENT_NODE - || nodeType == Node.DOCUMENT_NODE - || nodeType == Node.DOCUMENT_FRAGMENT_NODE) { - result = result.concat(getTextNodes(node)); - } - } - } - return result; -} - -for (const link of document.links) { - let display = link.innerHTML; - - // Mangle the link text - for (const node of getTextNodes(link)) { - node.textContent = node.textContent.replaceAll( - safelinksRegexp, (match, url) => { - try { - return decodeURIComponent(url); - } - catch (e) { - return url; - } - }); - } - - // Generate the tooltip and set link class - for (const match of link.href.matchAll(safelinksRegexp)) { - link.classList.add('liu_safelinks_link'); - - let tooltiptext = match[1]; - let tooltip = document.createElement('span'); - tooltip.classList.add('liu_safelinks_tooltip'); - try { - tooltiptext = decodeURIComponent(tooltiptext); - } - catch (e) { - } - tooltip.textContent = tooltiptext; - link.appendChild(tooltip); - break; - } -} +// Modify the displayed message to clarify where safelinks are +// inserted and to show the actual link targets. + +function getTextNodes(elem) { + var result = []; + if (elem) { + for (var nodes = elem.childNodes, i = nodes.length; i--;) { + let node = nodes[i]; + let nodeType = node.nodeType; + + if (nodeType == Node.TEXT_NODE) { + result.push(node); + } + else if (nodeType == Node.ELEMENT_NODE + || nodeType == Node.DOCUMENT_NODE + || nodeType == Node.DOCUMENT_FRAGMENT_NODE) { + result = result.concat(getTextNodes(node)); + } + } + } + return result; +} + +for (const link of document.links) { + // Mangle the link text + for (const node of getTextNodes(link)) { + node.textContent = untangleLink(node.textContent); + } + + // Generate the tooltip and set link class + if (isTangledLink(link.href)) { + let tooltiptext = untangleLink(link.href); + let tooltip = document.createElement('span'); + tooltip.classList.add('liu_safelinks_tooltip'); + tooltip.textContent = tooltiptext; + link.classList.add('liu_safelinks_link'); + link.prepend(tooltip); + } +} diff --git a/extension/icon.svg b/extension/icon.svg index 3fb919a..dc540fd 100644 --- a/extension/icon.svg +++ b/extension/icon.svg @@ -1 +1,22 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><linearGradient id="0" gradientUnits="userSpaceOnUse" y1="227.63" x2="0" y2="171.63"><stop stop-color="#2fae61"/><stop offset="1" stop-color="#4bdf88"/></linearGradient></defs><g transform="matrix(.92857 0 0 .92857-676.99-152.79)"><path d="m789.32 182.93c-.017-1.302-1.019-2.377-2.315-2.496-10.772-1.01-19.563-6.764-22.461-8.87-.606-.442-1.426-.442-2.032 0-2.893 2.106-11.683 7.863-22.456 8.87-1.296.119-2.293 1.194-2.315 2.496-.13 8.497 1.234 37.34 25.14 43.762.425.113.872.113 1.296 0 23.905-6.413 25.27-35.27 25.14-43.762" fill="url(#0)"/><path d="m773.85 193.97l-1.89-1.89c-.259-.259-.574-.389-.945-.389-.371 0-.686.13-.945.389l-9.116 9.13-4.085-4.099c-.259-.259-.574-.389-.945-.389-.371 0-.686.13-.945.389l-1.89 1.89c-.259.259-.389.574-.389.945 0 .37.13.686.389.945l5.03 5.03 1.89 1.89c.259.259.574.389.945.389.37 0 .685-.13.945-.389l1.89-1.89 10.06-10.06c.259-.259.389-.574.389-.945 0-.37-.13-.685-.389-.945" fill="#fff" fill-opacity=".851"/></g></svg> +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 283.46 283.46" style="enable-background:new 0 0 283.46 283.46;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:#231F20;} + .st1{fill:none;stroke:#231F20;stroke-width:36;stroke-linecap:round;stroke-miterlimit:10;} + .st2{fill:#ED1C24;} + .st3{fill:#FFFFFF;} +</style> +<g> + <path class="st0" d="M209.46,74v135.46H74V74H209.46 M283.46,0H0v283.46h283.46V0L283.46,0z"/> +</g> +<path class="st1" d="M15.14,199.56"/> +<path class="st1" d="M15.14,216.86"/> +<g> + <polygon class="st2" points="97.71,88.66 150.06,36.3 99.24,-14.5 297.96,-14.5 297.96,184.2 246.66,132.89 194.3,185.25 "/> + <path class="st3" d="M283.46,0v149.2l-36.81-36.81l-52.36,52.36l-76.09-76.09l52.36-52.36L134.26,0H283.46 M312.46-29h-29H134.26 + H64.23l49.52,49.51l15.8,15.79L97.71,68.15L77.2,88.66l20.51,20.51l76.09,76.09l20.51,20.51l20.51-20.51l31.85-31.85l16.3,16.3 + l49.51,49.51V149.2V0V-29L312.46-29z"/> +</g> +</svg> diff --git a/extension/manifest.json b/extension/manifest.json index 5fb87ff..5164f28 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,31 +1,34 @@ -{ - "manifest_version": 2, - "name": "Safelinks Cleaner", - "description": "Clean up display of Microsoft Advanced Threat Protection Safe Links", - "version": "1.0", - "author": "David Byers", - "homepage_url": "https://gitlab.liu.se/davby02/safelinkscleaner/", - "icons": { - "48": "icon.svg", - "96": "icon.svg", - "144": "icon.svg", - "192": "icon.svg" - }, - "applications": { - "gecko": { - "id": "safelinkscleaner@it.liu.se", - "strict_min_version": "78.4" - } - }, - "background": { - "scripts": [ - "background.js" - ] - }, - "permissions": [ - "messagesModify" - ], - "web_accessible_resources": [ - "assets/*.png" - ] -} +{ + "manifest_version": 2, + "name": "Safelinks Cleaner", + "description": "Clean up display of Microsoft Advanced Threat Protection Safe Links", + "version": "1.0", + "author": "David Byers", + "homepage_url": "https://gitlab.liu.se/davby02/safelinkscleaner/", + "icons": { + "48": "icon.svg", + "96": "icon.svg", + "144": "icon.svg", + "192": "icon.svg" + }, + "applications": { + "gecko": { + "id": "safelinkscleaner@it.liu.se", + "strict_min_version": "78.4" + } + }, + "background": { + "scripts": [ + "common.js", + "background.js" + ] + }, + "permissions": [ + "messagesModify", + "clipboardWrite", + "menus" + ], + "web_accessible_resources": [ + "assets/*.png" + ] +} diff --git a/extension/style.css b/extension/style.css index f23373c..47f6371 100644 --- a/extension/style.css +++ b/extension/style.css @@ -1,18 +1,18 @@ -a:hover .liu_safelinks_tooltip { - display: block; -} - -.liu_safelinks_tooltip { - display: none; - background: #fffff0 url(assets/shield.png) no-repeat 3px; - background-size: 14px 14px; - color: black; - padding: 3px 3px 4px 22px; - position: absolute; - z-index: 1000; - border: 1px solid black; - -webkit-box-shadow: 0px 0px 6px 1px rgba(0,0,0,0.5); - -moz-box-shadow: 0px 0px 6px 1px rgba(0,0,0,0.5); - box-shadow: 0px 0px 6px 1px rgba(0,0,0,0.5); - font: 14px sans-serif; -} +a:hover .liu_safelinks_tooltip { + display: block; +} + +.liu_safelinks_tooltip { + display: none; + background: #fffff0 url(assets/shield.png) no-repeat 3px; + background-size: 14px 14px; + color: black; + padding: 3px 3px 4px 22px; + position: absolute; + z-index: 1000; + border: 1px solid black; + -webkit-box-shadow: 0px 0px 6px 1px rgba(0,0,0,0.5); + -moz-box-shadow: 0px 0px 6px 1px rgba(0,0,0,0.5); + box-shadow: 0px 0px 6px 1px rgba(0,0,0,0.5); + font: 14px sans-serif; +} -- GitLab