Mask for the address bar
-
What?
- Initially I wanted to make vivaldi's address bar the same as other browsers, the page address can highlight the domain name by blurring other parts. But then I want more customization for color and structure.
- Finally I decided to create a mod that can change any element in the site address with CSS on the elements created with JS, a layer mask covers the address field.
Demo
-
theme-1
-
theme-2
-
theme-3
Installation
- You can learn how to install here
- Mod supports 3 themes:
theme-1
,theme-2
,theme-3
and you can customize your own themes with CSS - To change between themes, change the line
const theme = 'theme-1';
in code javascript into the theme you want. Example you want to usetheme-2
, change the code toconst theme = 'theme-2';
Javascript:
/* * Mask for the address bar * Written by Tam710562 * Thanks to sjudenim and LonM for bug fixes and new ideas */ window.gnoh = Object.assign(window.gnoh || {}, { encode: { html: function (rawStr) { return !rawStr ? rawStr : rawStr.replace(/[\u00A0-\u9999<>\&"'%]/gi, function (i) { return '&#' + i.charCodeAt(0) + ';'; }); } }, createElement: function (element, attribute, parent, inner) { if (typeof element === 'undefined') { return false; } var el = document.createElement(element); if (!!attribute && typeof attribute === 'object') { Object.assign(el, attribute); if (typeof attribute.text !== 'undefined') { el.textContent = attribute.text; } if (typeof attribute.html !== 'undefined') { el.innerHTML = attribute.html; } if (typeof attribute.style === 'object') { for (var css in attribute.style) { el.style[css] = attribute.style[css]; } } if (typeof attribute.events === 'object') { for (let key in attribute.events) { if (typeof attribute.events[key] === 'function') { el.addEventListener(key, attribute.events[key]); } } } for (var key in attribute) { if (key !== 'style' && key !== 'events' && key !== 'text' && key !== 'html') { if (typeof attribute[key] === 'object') { attribute[key] = JSON.stringify(attribute[key]); } el.setAttribute(key, attribute[key]); } } } if (!!inner) { if (!Array.isArray(inner)) { inner = [inner]; } for (var k = 0; k < inner.length; k++) { if (inner[k].nodeName) { el.append(inner[k]); } else { el.append(this.createElementFromHTML(inner[k])); } } } if (typeof parent === 'string') { parent = document.querySelector(parent); } if (!!parent) { parent.append(el); } return el; }, observeDOM: function (obj, callback, config) { const obs = new MutationObserver(function (mutations, observer) { if (config) { callback(mutations, observer); } else { if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) { callback(mutations, observer); } } }); obs.observe(obj, config || { childList: true, subtree: true }); }, timeOut: function (callback, conditon, timeout) { setTimeout(function wait() { var result; if (!conditon) { result = document.getElementById('browser'); } else if (typeof conditon === 'string') { result = document.querySelector(conditon); } else if (typeof conditon === 'function') { result = conditon(); } else { return; } if (result) { callback(result); } else { setTimeout(wait, timeout || 300); } }, timeout || 300); }, override: function (obj, functionName, callback, conditon) { obj[functionName] = (function (_super) { return function () { var result; if (typeof conditon === 'function' && conditon.apply(this, arguments) || conditon === undefined || conditon === true) { result = _super.apply(this, arguments); } callback.apply(this, arguments); return result; }; })(obj[functionName]); }, getReactEventHandlersKey: function (element) { if (!this.reactEventHandlersKey) { if (!element) { element = document.getElementById('browser'); } else if (typeof element === 'string') { element = document.querySelector(element); } if (!element) { return; } this.reactEventHandlersKey = Object.keys(element).find(function (key) { return key.startsWith('__reactEventHandlers'); }); } return this.reactEventHandlersKey; } }); (function () { const theme = 'theme-2'; let enableDecodeURL = false; let isPrivate = false; let searchEngines = { default: undefined, defaultPrivate: undefined, engines: {} }; let extensions = {}; const themeSettings = { 'theme-1': { decodeURL: false }, 'theme-2': { decodeURL: true }, 'theme-3': { decodeURL: false }, }; const pattern = { url: { full: /(([a-z-]+):(?!\/\/))?(([^\/]+):\/\/)?(([^\/?#:]+)(:([^\/?#]*))?)?(\/[^?#]*)?(\?[^#]*)?(#(.*))?/i, path: /\/([^/]*)/gi, search: /[?&]([^=&]+)?(=([^&]*))?/gi, host: { hostSub: { topLevel1: /((.*)\.)?([^.]+\.[a-z]{2,4})$/i, topLevel2: /((.*)\.)?([^.]+\.[a-z]{2,3}\.[a-z]{2})$/i, }, ipv4: /^(?=\d+\.\d+\.\d+\.\d+$)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.?){4}$/i, extensions: undefined } }, searchEngines: undefined }; function setSettings(theme, addressfieldMaskEl, addressfieldEl) { if (theme && typeof theme === 'string') { if (themeSettings[theme]) { enableDecodeURL = themeSettings[theme].decodeURL; } addressfieldMaskEl.classList.add(theme); addressfieldEl.classList.add(theme); } } function urlConvertEncodeHTML(urlConvert) { Object.keys(urlConvert).forEach(function (key) { urlConvert[key + 'HTML'] = gnoh.encode.html(urlConvert[key]); }); return urlConvert; } function changeValue(addressfieldMaskEl, addressfieldEl, isChange) { if (addressfieldMaskEl.dataset.value !== addressfieldEl.value || isChange === true) { addressfieldMaskEl.dataset.value = addressfieldEl.value; addressfieldMaskEl.innerHTML = getURLColorEl(addressfieldEl.value); } } function createPatternSearchEngines(searchEngineCollection) { searchEngines = { default: undefined, defaultPrivate: undefined, engines: {} }; pattern.searchEngines = undefined; const engines = searchEngineCollection.engines.filter(e => e.removed !== true); if (engines.length > 0) { const regKeywords = []; engines.forEach(function (engine) { searchEngines.engines[engine.keyword] = engine; searchEngines.engines[engine.keyword].keywordHTML = gnoh.encode.html(engine.keyword); searchEngines.engines[engine.keyword].nameHTML = gnoh.encode.html(engine.name); regKeywords.push(engine.keyword.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')); if (engine.id === searchEngineCollection.default) { searchEngines.default = searchEngines.engines[engine.keyword]; } if (engine.id === searchEngineCollection.defaultPrivate) { searchEngines.defaultPrivate = searchEngines.engines[engine.keyword]; } }); pattern.searchEngines = new RegExp('^(' + regKeywords.join('|') + ')\\s(.*)', 'i'); } } function createPatternExtensions(extensionCollection, callback) { extensions = {}; pattern.url.host.extensions = undefined; extensionCollection = extensionCollection.filter(e => e.enabled === true); if (extensionCollection.length > 0) { const regKeywords = []; extensionCollection.forEach(function (extension) { extensions[extension.id] = extension; extensions[extension.id].nameHTML = gnoh.encode.html(extension.name); regKeywords.push(extension.id); }); pattern.url.host.extensions = new RegExp('^(?=[a-z]{32})(?:(' + regKeywords.join('|') + '))$', 'i'); } if (typeof callback === 'function') { callback(); } } function updatePatternExtensions(callback) { chrome.management.getAll(function (extensionCollection) { createPatternExtensions(extensionCollection, callback); }); } chrome.storage.local.get({ 'SEARCH_ENGINE_COLLECTION': { engines: [] } }, function (res) { createPatternSearchEngines(res.SEARCH_ENGINE_COLLECTION); }); updatePatternExtensions(); function createMask(addressfieldEl, addressfieldParentEl) { addressfieldParentEl = addressfieldParentEl || addressfieldEl.parentElement; const addressfieldMaskEl = gnoh.createElement('div', { class: addressfieldEl.className, placeholder: addressfieldEl.placeholder }, addressfieldParentEl); addressfieldMaskEl.classList.add('addressfield-mask'); setSettings(theme, addressfieldMaskEl, addressfieldEl); changeValue(addressfieldMaskEl, addressfieldEl); chrome.storage.local.onChanged.addListener(function (changes, namespace) { if (changes.SEARCH_ENGINE_COLLECTION) { createPatternSearchEngines(changes.SEARCH_ENGINE_COLLECTION.newValue); changeValue(addressfieldMaskEl, addressfieldEl, true); } }); ['onEnabled', 'onDisabled', 'onInstalled', 'onUninstalled'].forEach(function (event) { chrome.management[event].addListener(function () { updatePatternExtensions(function () { changeValue(addressfieldMaskEl, addressfieldEl, true); }); }); }); gnoh.observeDOM(addressfieldEl, function (mutations, observer) { if (mutations[0].attributeName === 'value') { changeValue(addressfieldMaskEl, mutations[0].target); } }, { attributes: true }); } function getURLColorEl(url) { const arr = pattern.url.full.exec(url); if (arr) { const urlConvert = urlConvertEncodeHTML({ protocolSubFull: arr[1], protocolSub: arr[2], protocolFull: arr[3], protocol: arr[4], hostFull: arr[5], host: arr[6], postFull: arr[7], post: arr[8], path: arr[9], search: arr[10], hashFull: arr[11], hash: arr[12], }); return [ typeof urlConvert.protocolSub !== 'undefined' ? '<div class="protocol-sub" data-protocol-sub="' + urlConvert.protocolSubHTML + '">' + urlConvert.protocolSubHTML + '</div>' : '', typeof urlConvert.protocol !== 'undefined' ? '<div class="protocol" data-protocol="' + urlConvert.protocolHTML + '">' + urlConvert.protocolHTML + '</div>' : '', typeof urlConvert.hostFull !== 'undefined' ? [ '<div class="host-full" data-host-full="' + urlConvert.hostFullHTML + '">', typeof urlConvert.host !== 'undefined' ? getURLHostEl(urlConvert.host, urlConvert) : '', typeof urlConvert.postFull !== 'undefined' ? '<div class="post" data-post="' + urlConvert.postHTML + '">' + urlConvert.postHTML + '</div>' : '', '</div>' ].join('') : '', (typeof urlConvert.path !== 'undefined' || typeof urlConvert.search !== 'undefined' || typeof urlConvert.hashFull !== 'undefined') ? [ '<div class="path-full">', urlConvert.path === '/' ? '<div class="path" data-path="/"></div>' : typeof urlConvert.path !== 'undefined' ? '<div class="path" data-path="' + urlConvert.pathHTML + '">' + getURLPathEl(urlConvert.path) + '</div>' : '', urlConvert.search === '?' ? '<div class="search" data-search="?"></div>' : typeof urlConvert.search !== 'undefined' ? '<div class="search" data-search="' + urlConvert.searchHTML + '">' + getURLSearchEl(urlConvert.search) + '</div>' : '', typeof urlConvert.hashFull !== 'undefined' ? '<div class="hash" data-hash="' + urlConvert.hashFullHTML + '">' + (enableDecodeURL === true ? decodeURIComponent(urlConvert.hashHTML) : urlConvert.hashHTML) + '</div>' : '', '</div>' ].join('') : '', ].join(''); } else { return url || ''; } } function getURLHostEl(host, urlConvert) { if (host.match(pattern.url.host.hostSub.topLevel2)) { let hostSubHTML, hostMainHTML; return host.replace(pattern.url.host.hostSub.topLevel2, function (match, hostSubFull, hostSub, hostMain) { hostSubHTML = gnoh.encode.html(hostSub); hostMainHTML = gnoh.encode.html(hostMain); return [ '<div class="host with-sub" data-host="' + urlConvert.hostHTML + '">', typeof hostSub !== 'undefined' ? '<div class="host-sub" data-host-sub="' + hostSubHTML + '">' + hostSubHTML + '</div>' : '', typeof hostMain !== 'undefined' ? '<div class="host-main" data-host-main="' + hostMainHTML + '">' + hostMainHTML + '</div>' : '', '</div>' ].join(''); }); } else if (host.match(pattern.url.host.hostSub.topLevel1)) { let hostSubHTML, hostMainHTML; return host.replace(pattern.url.host.hostSub.topLevel1, function (match, hostSubFull, hostSub, hostMain) { hostSubHTML = gnoh.encode.html(hostSub); hostMainHTML = gnoh.encode.html(hostMain); return [ '<div class="host with-sub" data-host="' + urlConvert.hostHTML + '">', typeof hostSub !== 'undefined' ? '<div class="host-sub" data-host-sub="' + hostSubHTML + '">' + hostSubHTML + '</div>' : '', typeof hostMain !== 'undefined' ? '<div class="host-main" data-host-main="' + hostMainHTML + '">' + hostMainHTML + '</div>' : '', '</div>' ].join(''); }); } else if (pattern.searchEngines && host.match(pattern.searchEngines)) { let searchQueryHTML; return host.replace(pattern.searchEngines, function (match, searchNickname, searchQuery) { searchQueryHTML = gnoh.encode.html(searchQuery); return [ '<div class="search-engine with-nickname">', typeof searchNickname !== 'undefined' ? '<div class="search-nickname" data-search-nickname="' + searchEngines.engines[searchNickname].keywordHTML + '" data-search-name="' + searchEngines.engines[searchNickname].nameHTML + '">' + searchEngines.engines[searchNickname].keywordHTML + '</div>' : '', typeof searchQuery !== 'undefined' ? '<div class="search-query" data-search-query="' + searchQueryHTML + '">' + (enableDecodeURL === true ? decodeURIComponent(searchQueryHTML) : searchQueryHTML) + '</div>' : '', '</div>' ].join(''); }); } else if (typeof urlConvert.protocol !== 'chrome-extension' && pattern.url.host.extensions && host.match(pattern.url.host.extensions)) { return '<div class="host extension" data-host="' + urlConvert.hostHTML + '"><div class="host-extension" data-host-extension="' + urlConvert.hostHTML + '" data-host-extension-name="' + extensions[host].nameHTML + '">' + urlConvert.hostHTML + '</div></div>'; } else if (host.match(pattern.url.host.ipv4)) { return '<div class="host ipv4" data-host="' + urlConvert.hostHTML + '"><div class="host-main" data-host-main="' + urlConvert.hostHTML + '">' + urlConvert.hostHTML + '</div></div>'; } else if (typeof urlConvert.protocolSub !== 'undefined' || typeof urlConvert.protocol !== 'undefined') { return '<div class="host other" data-host="' + urlConvert.hostHTML + '"><div class="host-other" data-host-other="' + urlConvert.hostHTML + '">' + urlConvert.hostHTML + '</div></div>'; } else { const searchDefault = isPrivate ? searchEngines.defaultPrivate : searchEngines.default; return '<div class="search-engine default" data-search-nickname-default="' + searchDefault.keywordHTML + '" data-search-name-default="' + searchDefault.nameHTML + '"><div class="search-query" data-search-query="' + urlConvert.hostHTML + '">' + urlConvert.hostHTML + '</div></div>'; } } function getURLPathEl(path) { let pathItemHTML; return path.replace(pattern.url.path, function (match, pathItem) { pathItemHTML = gnoh.encode.html(pathItem); return (typeof match !== 'undefined' ? '<div class="path-item" data-path-item="' + pathItemHTML + '">' + (enableDecodeURL === true ? decodeURIComponent(pathItemHTML) : pathItemHTML) + '</div>' : ''); }); } function getURLSearchEl(search) { let keyHTML, valueHTML; return search.replace(pattern.url.search, function (match, key, valueFull, value) { keyHTML = gnoh.encode.html(key); valueHTML = gnoh.encode.html(value); return [ '<div class="search-item">', typeof key !== 'undefined' ? '<div class="search-key" data-search-key="' + keyHTML + '">' + (enableDecodeURL === true ? decodeURIComponent(keyHTML) : keyHTML) + '</div>' : '', typeof valueFull !== 'undefined' ? '<div class="search-value" data-search-value="' + valueHTML + '">' + (enableDecodeURL === true ? decodeURIComponent(valueHTML) : valueHTML) + '</div>' : '', '</div>' ].join(''); }); } gnoh.timeOut(function (addressfieldEl) { isPrivate = document.getElementById('browser').classList.contains('private'); createMask(addressfieldEl); gnoh.override(HTMLElement.prototype, 'appendChild', function (element) { var key = gnoh.getReactEventHandlersKey(this); if (this[key] && this[key].className && this[key].className.indexOf('UrlField') > -1 && element[key] && element[key].className.indexOf('url vivaldi-addressfield') > -1) { createMask(element, this); } }); }, 'input.url.vivaldi-addressfield'); })();
CSS:
/* * Mask for the address bar * Written by Tam710562 * Thanks to sjudenim and LonM for bug fixes and new ideas */ #browser .UrlBar-AddressField > .UrlBar-UrlFieldWrapper .UrlFragment-Wrapper { display: none; opacity: 0; } #browser:not(.isblurred) .UrlBar-AddressField > .UrlBar-UrlFieldWrapper:hover input.UrlBar-UrlField.vivaldi-addressfield:not(:focus) ~ .UrlFragment-Wrapper { display: block; opacity: 1; } .UrlBar-UrlObfuscationWarning { display: none; } .UrlField .UrlBar-UrlField.addressfield-mask { cursor: text; padding: 0; padding-left: 6px; width: 100%; height: 22px; line-height: normal; background-color: transparent; border: 0; box-shadow: none; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; display: flex; align-items: center; overflow: hidden; z-index: -1; opacity: 1; } .addressfield-mask:empty:before { content: attr(placeholder); opacity: 0.45; } .addressfield-mask div, .addressfield-mask div:after, .addressfield-mask div:before { display: inline-flex; position: relative; white-space: pre; height: 100%; align-items: center; } .UrlField input.UrlBar-UrlField.vivaldi-addressfield:not([value=""]) { opacity: 0; } .UrlBar-AddressField .UrlField:not(:focus-within) { position: relative; } #browser:not(.isblurred) .UrlBar-AddressField > .UrlBar-UrlFieldWrapper:hover .addressfield-mask, #browser:not(.isblurred) .UrlBar-AddressField > .UrlBar-UrlFieldWrapper input.UrlBar-UrlField.vivaldi-addressfield:focus ~ .addressfield-mask, #browser:not(.isblurred) .UrlBar-AddressField > .UrlBar-UrlFieldWrapper input.UrlBar-UrlField.vivaldi-addressfield:first-child:nth-last-child(4) ~ .addressfield-mask { display: none; } /* #browser:not(.isblurred) .UrlBar-AddressField > .UrlBar-UrlFieldWrapper:hover input.UrlBar-UrlField.vivaldi-addressfield, */ #browser:not(.isblurred) .UrlBar-AddressField > .UrlBar-UrlFieldWrapper input.UrlBar-UrlField.vivaldi-addressfield:focus, #browser:not(.isblurred) .UrlBar-AddressField > .UrlBar-UrlFieldWrapper input.UrlBar-UrlField.vivaldi-addressfield:first-child:nth-last-child(4) { opacity: 1; } /* Theme 1 */ .theme-1.addressfield-mask .protocol-sub, .theme-1.addressfield-mask .protocol, .theme-1.addressfield-mask .protocol:after, .theme-1.addressfield-mask .host .host-sub, .theme-1.addressfield-mask .post, .theme-1.addressfield-mask .path-full { /* color: var(--colorFgFadedMore); */ /* color: graytext; */ color: var(--colorFg); opacity: 0.7; } .theme-1.addressfield-mask .host { color: var(--colorFg); } .UrlBar-AddressField > .secure + .UrlBar-UrlFieldWrapper .theme-1.addressfield-mask .protocol, .UrlBar-AddressField > .certified + .UrlBar-UrlFieldWrapper .theme-1.addressfield-mask .protocol { color: #46c235; opacity: 1; } .theme-1.addressfield-mask .protocol[data-protocol="vivaldi"] { color: var(--colorHighlightBg); opacity: 1; } .theme-1.addressfield-mask .protocol-sub:after { content: ':'; } .theme-1.addressfield-mask .protocol:after { content: '://'; } .theme-1.addressfield-mask .host .host-sub:after { content: '.'; } .theme-1.addressfield-mask .search-engine .search-nickname:after { content: ' '; } .theme-1.addressfield-mask .post:before { content: ':'; } .theme-1.addressfield-mask .path:before, .theme-1.addressfield-mask .path .path-item:not(:first-child):before { content: '/'; } .theme-1.addressfield-mask .search:before { content: '?'; } .theme-1.addressfield-mask .search .search-item:not(:first-child):before { content: '&'; } .theme-1.addressfield-mask .search .search-item .search-value:before { content: '='; } .theme-1.addressfield-mask .hash:before { content: '#'; } .private .theme-1.addressfield-mask .protocol-sub, .private .theme-1.addressfield-mask .protocol, .private .theme-1.addressfield-mask .protocol:after, .private .theme-1.addressfield-mask .host .host-sub, .private .theme-1.addressfield-mask .post, .private .theme-1.addressfield-mask .path-full, .private .theme-1.addressfield-mask .host { color: var(--colorBgIntense); } .private .theme-1.addressfield-mask .protocol[data-protocol="vivaldi"] { color: var(--colorHighlightBg); } /* Theme 2 */ .theme-2.addressfield-mask .path-full > div:not(:empty):before { content: ''; height: 12px; position: absolute; left: -6px; top: 50%; margin-top: -6px; border-left: 1px solid var(--colorFg); } .theme-2.addressfield-mask .path-full > div:not(:empty) { margin-left: 6px; } .theme-2.addressfield-mask .protocol-sub, .theme-2.addressfield-mask .protocol, .theme-2.addressfield-mask .host, .theme-2.addressfield-mask .search-engine .search-nickname, .theme-2.addressfield-mask .search-engine .search-query:not(:empty), .theme-2.addressfield-mask .search-engine.default:before, .theme-2.addressfield-mask .post:not(:empty), .theme-2.addressfield-mask .path-item:not(:empty), .theme-2.addressfield-mask .hash { background-color: var(--colorFg); color: var(--colorBgIntense); margin-right: 5px; padding-left: 3px; padding-right: 3px; border-radius: var(--radiusRoundedLess); } .theme-2.addressfield-mask .search .search-item { margin-right: 5px; } .UrlBar-AddressField > .secure + .UrlBar-UrlFieldWrapper .theme-2.addressfield-mask .protocol, .UrlBar-AddressField > .certified + .UrlBar-UrlFieldWrapper .theme-2.addressfield-mask .protocol { color: #46c235; background-color: rgba(85, 204, 68, 0.2); } .theme-2.addressfield-mask .host, .theme-2.addressfield-mask .search-engine .search-nickname, .theme-2.addressfield-mask .search-engine.default:before { background-color: var(--colorAccentBg); color: var(--colorAccentFg); font-weight: 700; } .theme-2.addressfield-mask .host .host-sub { opacity: 0.7; } .theme-2.addressfield-mask .host .host-sub:after { content: '.'; } .theme-2.addressfield-mask .host .host-extension, .theme-2.addressfield-mask .search-engine .search-nickname { text-indent: -9999px; } .theme-2.addressfield-mask .host .host-extension:after { text-indent: 0; content: attr(data-host-extension-name); } .theme-2.addressfield-mask .search-engine .search-nickname:after { text-indent: 0; content: attr(data-search-name); } .theme-2.addressfield-mask .search-engine.default:before { content: attr(data-search-name-default); } .theme-2.addressfield-mask .search .search-item .search-key { background-color: var(--colorAccentBgDarker); color: var(--colorAccentFg); padding-left: 3px; padding-right: 3px; border-top-left-radius: var(--radiusRoundedLess); border-bottom-left-radius: var(--radiusRoundedLess); } .theme-2.addressfield-mask .search .search-item .search-key:last-child { border-top-right-radius: var(--radiusRoundedLess); border-bottom-right-radius: var(--radiusRoundedLess); } .theme-2.addressfield-mask .search .search-item .search-value { background-color: var(--colorFg); color: var(--colorBgIntense); padding-left: 3px; padding-right: 3px; border-top-right-radius: var(--radiusRoundedLess); border-bottom-right-radius: var(--radiusRoundedLess); } .theme-2.addressfield-mask .search .search-item .search-value:first-child { border-top-left-radius: var(--radiusRoundedLess); border-bottom-left-radius: var(--radiusRoundedLess); } .private .theme-2.addressfield-mask .path-full > div:not(:empty):before { background-color: var(--colorBgIntense); } .private .theme-2.addressfield-mask .protocol-sub, .private .theme-2.addressfield-mask .protocol, .private .theme-2.addressfield-mask .search-engine .search-nickname, .private .theme-2.addressfield-mask .search-engine .search-query:not(:empty), .private .theme-2.addressfield-mask .post:not(:empty), .private .theme-2.addressfield-mask .path-item:not(:empty), .private .theme-2.addressfield-mask .hash, .private .theme-2.addressfield-mask .search .search-item .search-value { background-color: var(--colorBgIntense); color: var(--colorFgIntense); } /* Theme 3 */ .theme-3.addressfield-mask { justify-content: center; } .theme-3.addressfield-mask .protocol-sub, .theme-3.addressfield-mask .protocol, .theme-3.addressfield-mask .host .host-sub, .theme-3.addressfield-mask .search-engine .search-nickname, .theme-3.addressfield-mask .post { opacity: 0.7; } .theme-3.addressfield-mask .protocol:not([data-protocol="file"]):not([data-protocol="vivaldi"]):not([data-protocol="chrome"]):not([data-protocol="chrome-extension"]), .theme-3.addressfield-mask .path-full { display: none; } .theme-3.addressfield-mask .host .host-extension, .theme-3.addressfield-mask .search-engine .search-nickname { text-indent: -9999px; } .theme-3.addressfield-mask .host .host-extension:after { text-indent: 0; content: attr(data-host-extension-name); } .theme-3.addressfield-mask .search-engine .search-nickname:after { text-indent: 0; content: attr(data-search-name); margin-right: 5px; } .theme-3.addressfield-mask .protocol-sub:after { content: ':'; } .theme-3.addressfield-mask .protocol:not([data-protocol="file"]):after { content: '://'; } .theme-3.addressfield-mask .host .host-sub:after { content: '.'; } .theme-3.addressfield-mask .post:before { content: ':'; } .theme-3.addressfield-mask .path:before, .theme-3.addressfield-mask .path .path-item:not(:first-child):before { content: '/'; } .theme-3.addressfield-mask .search:before { content: '?'; } .theme-3.addressfield-mask .search .search-item:not(:first-child):before { content: '&'; } .theme-3.addressfield-mask .search .search-item .search-value:before { content: '='; } .theme-3.addressfield-mask .hash:before { content: '#'; } input.theme-3.url { text-align: center; }
Diagram of render classes:
.addressfield-mask ├── .protocol-sub[data-protocol-sub] ├── .protocol[data-protocol] ├── .host-full[data-host-full] │ ├── .host[data-host]┌── .with-sub │ │ │ ├── .host-sub[data-host-sub] │ │ │ └── .host-main[data-host-main] │ │ ├── .extension │ │ │ └── .host-extension[data-host-extension][data-host-extension-name] │ │ ├── .ipv4 │ │ │ └── .host-main[data-host-main] │ │ └── .other │ │ └── .host-other[data-host-other] │ ├── .post[data-post] │ └── .search-engine ┌── .with-nickname │ │ ├── .search-nickname[data-search-nickname][data-search-name] │ │ └── .search-query[data-search-query] │ └── .default[data-search-nickname-default][data-search-name-default] │ └── .search-query[data-search-query] └── .path-full ├── .path[data-path] │ └── .path-item[data-path-item] ├── .search[data-search] │ └── .search-item │ ├── .search-key[data-search-key] │ └── .search-value[data-search-value] └── .hash[data-hash]
Changelog
23/05/2019
- Create the first version.
21/07/2019
- Fix the error for Vivaldi Snapshot 2.7.1609.4
- Add theme class to addressfield input to align with theme
- Add extension name for url of chrome-extension
13/08/2019
- Fix the error for Vivaldi Snapshot 2.7.1628.12
02/09/2019
- Fix the error for Vivaldi Snapshot 2.8.1650.3
05/09/2019
- Fix crashed browser in some cases when the address bar contains
%
character
16/09/2020
- Fix the error for Vivaldi Snapshot 3.4.2038.4
18/09/2020
-
Thanks for sharing.
Theme-3
is inconsistent though, the url left justifies when the field is selected.I haven't tested it in this mod, but I've been using this
.addressfield form input.url {text-align: center}
-
This is amanzing, though I wish I could combine theme 1 and 3. Also as @sjudenim said, hovering over the url makes it align to the left.
In fact, hovering over the url anytime disables any of the themes completely. I think that should only happen once you click on the url.
Also a few other things that I noticed:
- Theme 3 moves the url from left to the center as the page loads (could be due to these elements, but I'm not sure).
- Text and font in theme 1 is altered when I hover over the url, everything moves slightly down (see here).
- Theme 3 ignores show full address bar setting (I'm assuming this might be intentional).
- Focus to the address field is lost for new tabs.
-
I remember the addon LocationBar2 on Firefox:
How I could bold "strong":
1.- the domain "vivaldi.net"
2.- all between // and .netThank for your work
-
This is a really cool address bar mod. Much much better than the one I attempted to make.
What might be a good integration would be if theme 2 worked with ctrl+click selection to navigate "up a level" to other parts on the URL.
Update: There seems to be some interference with this mod and focusing the address bar
-
I've found a fix for the bug where the address bar doesn't get the focus on creation of a new tab, or pressing "F8". These lines:
input.vivaldi-addressfield { display: none; } ... #browser:not(.isblurred) .addressfield > form:hover input.vivaldi-addressfield, #browser:not(.isblurred) .addressfield > form input.vivaldi-addressfield:focus, #browser:not(.isblurred) .addressfield > form input.vivaldi-addressfield:first-child:nth-last-child(3) { display: inline-block; }
Need to be changed to use
opacity: 0
to hide, andopacity: 1
to make it visible:input.vivaldi-addressfield { opacity: 0; } ... #browser:not(.isblurred) .addressfield > form:hover input.vivaldi-addressfield, #browser:not(.isblurred) .addressfield > form input.vivaldi-addressfield:focus, #browser:not(.isblurred) .addressfield > form input.vivaldi-addressfield:first-child:nth-last-child(3) { opacity: 1; }
The browser optimises elements with display: none to completely remove interaction with them, which makes it impossible to programatically focus an element not visible.
-
@AltCode said in Mask for the address bar:
This is amanzing, though I wish I could combine theme 1 and 3.
Do you mean that you want the full address like in
theme 1
but centred as intheme 3
?.theme-1.addressfield-mask { justify-content: center; }
-
@barbudo2005 said in Mask for the address bar:
How I could bold "strong":
1.- the domain "vivaldi.net"
2.- all between // and .netYou didn't specify for which theme so I'll demonstrate on the first one
.theme-1.addressfield-mask .protocol-sub, .theme-1.addressfield-mask .protocol, .theme-1.addressfield-mask .protocol:after, .theme-1.addressfield-mask .host .host-sub, .theme-1.addressfield-mask .post, .theme-1.addressfield-mask .path-full { color: var(--colorFg); opacity: .7; font-weight: initial } .theme-1.addressfield-mask .host { color: var(--colorFg); font-weight: bold }
You can replace
bold
withbolder
or fine tune it more with500
600
700
,etc. -
The highlighting of when you've entered a search term is nice. It is possible to achieve something similar for chrome-extension URLs. E.g. from this:
To This
Using the chrome extension management API
-
@sjudenim said in Mask for the address bar:
Theme-3
is inconsistent though, the url left justifies when the field is selected.I haven't tested it in this mod, but I've been using this
.addressfield form input.url {text-align: center}
You may be right, the field should be centered in theme-3 when selected
@AltCode said in Mask for the address bar:
In fact, hovering over the url anytime disables any of the themes completely. I think that should only happen once you click on the url.
This is because I have not found a better way without depending on javascript. But when I looked at @LonM's solution to focus on the new tab, I thought I found a solution
- Theme 3 moves the url from left to the center as the page loads (could be due to these elements, but I'm not sure).
That's exactly what caused the error.
- Text and font in theme 1 is altered when I hover over the url, everything moves slightly down (see here).
I don't see this in my vivaldi, probably because of different operating systems. I am using windows
- Theme 3 ignores show full address bar setting (I'm assuming this might be intentional).
Are you talking about http, https?
@LonM said in Mask for the address bar:
The highlighting of when you've entered a search term is nice. It is possible to achieve something similar for chrome-extension URLs. E.g. from this:
To This
Using the chrome extension management API
A good idea, I'll try it
-
@tam710562 said in Mask for the address bar:
- Text and font in theme 1 is altered when I hover over the url, everything moves slightly down (see here).
I don't see this in my vivaldi, probably because of different operating systems. I am using windows
I am using macOS. Luckily I was able to find a partial solution. For it to display to not move up and down on macOS, the line:
line-height: 22px;
Needs to be changed to:
line-height: 20px;
I am not sure what needs to be changed to prevent the shrinking of the url width every time I hover over the address bar.
- Theme 3 ignores show full address bar setting (I'm assuming this might be intentional).
Are you talking about http, https?
I'm talking about this setting
It does more than just display http and https. In some websites, such as youtube, it displays everything else after the domain that is normally hidden away.
@sjudenim said in Mask for the address bar:
Do you mean that you want the full address like in
theme 1
but centred as intheme 3
?No, I meant the colored parts in the address. These are absent from theme 3, but what you offered here is great too.
-
I decided to hide the protocol for times when it's not needed:
.protocol[data-protocol=https], .protocol[data-protocol=vivaldi], .protocol[data-protocol=chrome-extension], .protocol[data-protocol=file] { display: none; }
The only protocol that will show is
http
as that's one I want to be warned about. -
This post is deleted! -
Thank you very much for so great Mod ! !
Unfortunately, it doesn't work anymore
Any solution? Some help?
Thanks to all who can collaborate with the solution
-
Updated a version to fix the error for Vivaldi Snapshot 2.7.1628.12
-
Thanks
I'll test it
-
Perfect
It's working
I love this mod
Thanks again ! !
-
This was one of the few things that i was missing since moving to Vivaldi just recently.
Nice work!
-
Oops, copied the wrong one. The Update code wasn't working but the top most post is working
-
@sjudenim that's the code for 2.7.1609.4 but when vivaldi updated to 2.7.1628.12, the mod is broken again so I updated the main topic. I will delete the update to avoid confusion