Making the domain more visible in the address bar
-
This was in one of my screenshots, but I never posted it here. @cafosse suggested I share it.
Preview
This iteration of the mod basically strips out as much of the domain as possible, then centres it in the address bar. It doesn't show any of the path or protocol, with the intent that it makes it easier to see (it's not perfect, see below).
Installation
Comes in two parts that need to be installedA
css
mod:/** * Domain Only (a mod for vivaldi) * LonM * For other languages, replace "Site info" with whatever your locale string is */ div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:not(:focus):not(:focus-within):not(:hover){ opacity: 0; } div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:hover, div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus, div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus-within{ opacity: 1; background: var(--colorBgLight); } .animation-on div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield { transition: all 0.3s ease; } .animation-on div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:hover { transition-delay: 0.3s; } .animation-on div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus, .animation-on div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus-within { transition: none; } .private div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus, .private div.addressfield > button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus-within{ background: var(--colorFgIntense); } div.addressfield > div.progressing + button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus, div.addressfield > div.progressing + button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus-within, .private div.addressfield > div.progressing + button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus, .private div.addressfield > div.progressing + button[title="Site info"] + form:not([data-url=""]) input.url.vivaldi-addressfield:focus-within{ background: transparent; } div.addressfield > button[title="Site info"] + form:before { content: attr(data-url); width: calc(100% - 88px); display: block; text-align: center; position: absolute; top: 0px; left: 0px; pointer-events: none; cursor: text; margin: 0px 0px 0px 44px; height: 100%; line-height: 1.8; border-radius: 0px var(--radius) var(--radius) 0px; } div.addressfield > div.progressing + button[title="Site info"] + form:focus:before, div.addressfield > div.progressing + button[title="Site info"] + form:focus-within:before { display: none; } div.addressfield > button.insecure[title="Site info"] + form:before { background: #f30; color: white; }
And a
Javascript
mod:/* * Domain Only (a mod for Vivaldi) * LonM */ (function domainOnly(){ "use strict"; /* Add the mask in again when no longer focused */ function addressBarUnFocused(event){ textChanged(event.target); } /* If text box doesn't have focus and the input changes, activate or update the mod */ function textChanged(target){ const newText = target.value; if(newText===""){ setTldPlusOne(""); } if(!newText){ return; } const tldText = getTldPlusOne(newText); if(tldText.indexOf("view-source:")===0){ setTldPlusOne(""); return; } if(tldText==="chrome-extension:"){ const extensionIdPlusPath = newText.replace("chrome-extension://", ""); const extensionIdOnly = extensionIdPlusPath.split("/")[0]; chrome.management.get(extensionIdOnly, extInfo => { setTldPlusOne("chrome-extension: "+extInfo.name); }); return; } setTldPlusOne(tldText); } /** * Get the tld plus one part of domain from the full url * If IP address, return it in full * @param {string} fullUrl * @returns {string} of the tld plus first part of domain */ function getTldPlusOne(fullUrl){ let noProtocol = fullUrl; if(fullUrl.indexOf("://") > -1 && fullUrl.indexOf("://") < 10){ noProtocol = fullUrl.split("://")[1]; } let domainOnly = noProtocol; if(noProtocol.indexOf("/") > -1) { domainOnly = noProtocol.split("/")[0]; } const guffDomains = ["www", "m"]; for (let index = 0; index < guffDomains.length; index++) { const guffDomain = guffDomains[index]; if(domainOnly.indexOf(guffDomain+".")===0){ domainOnly = domainOnly.replace(guffDomain+".", ""); } } return domainOnly; } /** * Set the tldPlusOne text * @param {string} tldPlusOne */ function setTldPlusOne(tldPlusOne){ const form = document.querySelector("div.addressfield > form"); form.setAttribute("data-url", tldPlusOne); } /** * Change to address bar ocurred */ const addressBarTextChanged = new MutationObserver(mutationRecords => { if(mutationRecords[0].attributeName === "value"){ textChanged(mutationRecords[0].target); } }); /** * Initialise the mod, listen and observe for changes * Also set the initial values * @param {DomElement} addressBarElement */ function init(addressBarElement){ addressBarElement.addEventListener("blur", addressBarUnFocused); addressBarTextChanged.observe(addressBarElement, {attributes: true}); textChanged({target:addressBarElement}); } /** * Wait for browser to load */ setTimeout(function wait(){ "use strict"; const addressBarElement = document.querySelector("input.url.vivaldi-addressfield"); if(addressBarElement){ init(addressBarElement); } else { setTimeout(wait, 500); } }, 500); })();
TODOs and Bugs
If you have any suggestions on how to fix the following, please share:
- It does nothing to help the situation where a phishing attacker uses a really long domain to trick the user
- I don't actually know if this helps people counter phishing. It helps me, but I don't know about anyone else.
Updates
2019-03-02: Use a nicer transition, delayed hover reveal
2018-12-07: Move it a bit more left to be centred.
2018-12-06: Initial Release -
In an older iteration of the mod, I simply highlighted the domain while keeping the rest of the path visible.
I don't know if I ever shared this elsewhere. on the forum. I thought I had, but I can't seem to find it now... This is a screenshot of it running at the time, I'm not sure if it still works on the latest versions:
Installation
This was one singleJS
file:/* * Domains Highlighted (a mod for Vivaldi) * Written by LonM * No Copyright Reserved */ (function(){ function domainsHighlighted(addressBarElement){ "use strict"; /* Get rid of mod when text box has focus */ function addressBarFocused(event){ clearMask(); } /* Add the mask in again when no longer focused */ function addressBarUnFocused(event){ textChanged(event.target); } /* remove the mask */ function clearMask(){ applyMask(""); } /* If text box doesn't have focus and the input changes, activate or update the mod */ function textChanged(target){ if(target === document.activeElement){ return clearMask(); } const newText = target.value; if(!newText){ return; } if(newText.indexOf("://")>-1){ maskProtocolAndAddress(newText); } else { maskSimplifiedAddress(newText); } } /* Handle simplified address */ function maskSimplifiedAddress(newText){ const positionStart = newText.indexOf("/"); if(isNaN(positionStart) || positionStart<=0){ return clearMask(); } const widthToSlash = checkTextWidth(newText.substring(0,positionStart)); const mask = createWebkitMask(0, widthToSlash+10); applyMask(mask); } /* Handle protocol + address */ function maskProtocolAndAddress(newText){ const positionData = getDomainTextPositions(newText); if(!positionData){ return clearMask(); } const mask = createWebkitMask(positionData[0], positionData[1]); applyMask(mask); } /* Find the position of the base domaina and TLD in the url return [start position in pixels, end position in pixels] */ function getDomainTextPositions(text){ /* voiski ip checkers */ const ipv6 = /https?:\/\/((([a-fA-F0-9]{1,4}|):){1,7}([a-fA-F0-9]{1,4}|:))/g; const ipv4 = /https?:\/\/(((25[0-5]|2[0-4]\d|[01]?\d{1,2}|\*)\.){3}(25[0-5]|2[0-4]\d|[01]?\d{1,2}|\*))/g; /* generic catch-all for domains */ const domain = /https?:\/\/([\w\.:\-]*)\/?/g; if(!text || text === ""){ return; } let ipv4match = ipv4.exec(text); let ipv6match = ipv6.exec(text); let domainMatch = domain.exec(text); let full, important = ""; if(ipv4match && ipv4match.length > 0){ important = ipv4match[1]; full = ipv4match[0]; } else if(ipv6match && ipv6match.length > 0){ important = ipv6match[1]; full = ipv6match[0]; } else if(domainMatch && domainMatch.length > 0){ important = domainMatch[1]; full = domainMatch[0]; } else { return; } const styleOffsetStart = 0; const styleOffsetEnd = 6; const fullWidth = checkTextWidth(full); const importantWidth = checkTextWidth(important); const start = fullWidth - importantWidth + styleOffsetStart; const end = fullWidth + styleOffsetEnd; return [start, end]; } /* Make a special element to check the expected width of text */ function checkTextWidth(text){ const dummyElement = document.createElement("div"); dummyElement.style = "font-family: 'Segoe UI'; font-size: 13px; font-weight: 400; opacity: 0;"; dummyElement.innerText = text; const dummyParent = document.getElementById("status_info"); dummyParent.appendChild(dummyElement); const textWidth = dummyElement.getBoundingClientRect().width; dummyParent.removeChild(dummyElement); return textWidth; } /* Make the mask given which area to highlight */ function createWebkitMask(darkStart, darkEnd){ return `-webkit-mask-image: -webkit-linear-gradient( 0deg, rgba(0,0,0,0.5) `+darkStart+`px, black `+darkStart+`px, black `+darkEnd+`px, rgba(0,0,0,0.5) `+darkEnd+`px );`; } /* activate or update the mask style */ function applyMask(maskText){ addressBarElement.style = maskText; } const addressBarTextChanged = new MutationObserver(mutationRecords => { if(mutationRecords[0].attributeName === "value"){ textChanged(mutationRecords[0].target); } }); /* Add Event Listeners */ addressBarElement.addEventListener("focus", addressBarFocused); addressBarElement.addEventListener("blur", addressBarUnFocused); addressBarTextChanged.observe(addressBarElement, {attributes: true}); textChanged({target:addressBarElement}); } setTimeout(function wait(){ "use strict"; const addressBarElement = document.querySelector("input.url.vivaldi-addressfield"); const vivaldiTooltip = document.getElementById("vivaldi-tooltip"); if(addressBarElement && vivaldiTooltip){ domainsHighlighted(addressBarElement); } else { setTimeout(wait, 500); } }, 500); }());
Notes
The method I used to figure out the placement of the highlighting was never perfect and was quite tricky to figure out. Feel free to try and play with it if you think you can fix it. -
For what is it good?
-