Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Panel Actions (A Mod for Vivaldi)
- * LonM.vivaldi.net
- * No Copyright Reserved
- */
- (function panel_actions(){
- "use strict";
- const ZOOM_STEP = 0.1; /*Step amount. 0.1 is 10%*/
- /*
- Dictionary of panel actions.
- They will be added to the toolbar in the order specified below.
- key must be unique
- title: string for tooltip
- script: (target, webview) => {}: void. target is button that was clicked. webview is the webview attached to the button
- for content scripts, Call doContentScript with the webview and a () => {}: void
- display: string of html - The innerHTML of the toolbar button
- display_class: string - One or more classes to give the button
- */
- const ACTIONS = {
- zoom_out: {
- title: "Decrease zoom",
- script: function(target, webview){
- webview.getZoom(current => {
- changeZoom(webview, current -= ZOOM_STEP);
- });
- },
- display: `-`,
- display_class: `zoom-out`
- },
- zoom_reset: {
- title: "Set zoom to 100%",
- script: function(target, webview){
- changeZoom(webview, 1);
- },
- display: `100%`,
- display_class: `zoom-reset`
- },
- zoom_in: {
- title: "Increase zoom",
- script: function(target, webview){
- webview.getZoom(current => {
- changeZoom(webview, current += ZOOM_STEP);
- });
- },
- display: `+`,
- display_class: `zoom-in`
- },
- invert: {
- title: "Invert the colours on the page",
- script: function(target, webview){
- doContentScript(webview, () => {
- const style_element = document.createElement('style');
- style_element.innerHTML = `
- html { background-color: white;}
- body.inverted {filter: invert(1) hue-rotate(180deg);}
- body.inverted img,
- body.inverted video {filter: invert(1) hue-rotate(180deg);}`;
- document.body.appendChild(style_element);
- document.body.classList.toggle("inverted");
- });
- },
- display: `<svg viewBox="-4 -4 20 20" xmlns="http://www.w3.org/2000/svg">
- <path d="M 7.984375 0 A 7.9850645 7.9850645 0 0 0 0 7.984375 A 7.9850645 7.9850645 0 0 0 7.984375 15.970703 A 7.9850645 7.9850645 0 0 0 15.970703 7.984375 A 7.9850645 7.9850645 0 0 0 7.984375 0 z M 7.9960938 0.74804688 L 7.9960938 7.984375 L 7.9960938 15.222656 A 7.2378569 7.2378569 0 0 1 1.7265625 11.603516 A 7.2378569 7.2378569 0 0 1 1.7265625 4.3652344 A 7.2378569 7.2378569 0 0 1 7.9960938 0.74804688 z " fill=""></path>
- </svg>`,
- display_class: "panel-action-invert"
- },
- terminate: {
- title: "Kills the panel to free memory. WARNING! This will also kill any tabs using the same process.",
- script: function(target, webview){
- webview.terminate();
- },
- display: `x`,
- display_class: `panel-action-terminate`
- },
- mute: {
- title: "Mute this panel",
- script: function(target, webview){
- webview.isAudioMuted(mute => {
- webview.setAudioMuted(!mute);
- target.innerHTML = mute ? `<svg viewBox="-4 -4 20 20" xmlns="http://www.w3.org/2000/svg"><path d="m 10.425781,0 -5.5410155,4.96094 h -4.234375 v 4.74805 h 4.1074219 l 5.6679686,5.23047 z m 1.767579,1.50782 v 0.59961 c 0.628524,0 1.262682,0.52233 1.751953,1.49023 0.489269,0.96789 0.804686,2.34168 0.804686,3.86133 0,1.51964 -0.315417,2.89148 -0.804686,3.85937 -0.489271,0.9679 -1.123429,1.49219 -1.751953,1.49219 v 0.59961 c 0.949262,0 1.742407,-0.74276 2.287109,-1.82031 0.544702,-1.07756 0.869141,-2.52926 0.869141,-4.13086 0,-1.60161 -0.324439,-3.05525 -0.869141,-4.13281 -0.544702,-1.07755 -1.337847,-1.81836 -2.287109,-1.81836 z m -0.921875,1.97851 v 0.59961 c 0.378754,0 0.787693,0.3227 1.113281,0.9668 0.325586,0.64409 0.539061,1.57016 0.539061,2.5957 1e-6,1.02554 -0.213475,1.95161 -0.539061,2.5957 -0.325588,0.64409 -0.734527,0.9668 -1.113281,0.9668 v 0.59961 c 0.699491,0 1.267416,-0.54311 1.648436,-1.29687 0.381021,-0.75375 0.603517,-1.75774 0.603517,-2.86524 0,-1.1075 -0.222496,-2.11344 -0.603517,-2.86719 -0.38102,-0.75375 -0.948945,-1.29492 -1.648436,-1.29492 z"></path></svg>`
- : `<svg viewBox="-4 -4 20 20" xmlns="http://www.w3.org/2000/svg"><path d="m 10.425781,-0.1412354 -5.5410155,4.96094 H 0.6503908 v 4.75 h 4.1074217 l 5.6679685,5.2285204 z m 0.853516,4.1211 -0.707031,0.70703 1.917969,1.91797 -1.917969,1.91992 0.707031,0.70703 1.917969,-1.91992 1.919922,1.91992 0.707031,-0.70703 -1.919922,-1.91992 1.919922,-1.91797 -0.707031,-0.70703 -1.919922,1.91796 z"></path></svg>`;
- target.title = mute ? "Mute this panel" : "Panel Muted. Click to Un-Mute";
- });
- },
- display: `<svg viewBox="-4 -4 20 20" xmlns="http://www.w3.org/2000/svg">
- <path d="m 10.425781,0 -5.5410155,4.96094 h -4.234375 v 4.74805 h 4.1074219 l 5.6679686,5.23047 z m 1.767579,1.50782 v 0.59961 c 0.628524,0 1.262682,0.52233 1.751953,1.49023 0.489269,0.96789 0.804686,2.34168 0.804686,3.86133 0,1.51964 -0.315417,2.89148 -0.804686,3.85937 -0.489271,0.9679 -1.123429,1.49219 -1.751953,1.49219 v 0.59961 c 0.949262,0 1.742407,-0.74276 2.287109,-1.82031 0.544702,-1.07756 0.869141,-2.52926 0.869141,-4.13086 0,-1.60161 -0.324439,-3.05525 -0.869141,-4.13281 -0.544702,-1.07755 -1.337847,-1.81836 -2.287109,-1.81836 z m -0.921875,1.97851 v 0.59961 c 0.378754,0 0.787693,0.3227 1.113281,0.9668 0.325586,0.64409 0.539061,1.57016 0.539061,2.5957 1e-6,1.02554 -0.213475,1.95161 -0.539061,2.5957 -0.325588,0.64409 -0.734527,0.9668 -1.113281,0.9668 v 0.59961 c 0.699491,0 1.267416,-0.54311 1.648436,-1.29687 0.381021,-0.75375 0.603517,-1.75774 0.603517,-2.86524 0,-1.1075 -0.222496,-2.11344 -0.603517,-2.86719 -0.38102,-0.75375 -0.948945,-1.29492 -1.648436,-1.29492 z"></path>
- </svg>`,
- display_class: `panel-action-mute`
- }/*,
- template: {
- title: "",
- script: function(event, webview){
- },
- display: ``,
- display_class: ``
- },*/
- };
- /**
- * Change the zoom
- * @param webview to update
- * @param zoom new zoom factor
- */
- function changeZoom(webview, zoom){
- webview.setZoom(zoom, () => {
- updateZoomLabel(webview);
- });
- }
- /**
- * Update the zoom label
- * @param webview to get zoom value from
- */
- function updateZoomLabel(webview){
- const panelZoom = webview.parentElement.parentElement.querySelector(".zoom-reset");
- if(!panelZoom){
- console.error("[lonm-panel-actions] Panel Zoom Label Missing");
- return;
- }
- webview.getZoom(current => {
- const newValue = Math.floor(current * 100);
- panelZoom.innerHTML = newValue + "%";
- });
- }
- /**
- * Inject a script as a content script
- * @param webview to use
- * @param scriptMethod Method to inject
- */
- function doContentScript(webview, scriptMethod){
- const scriptText = "("+scriptMethod+")()";
- webview.executeScript({code: scriptText});
- }
- /**
- * Create a panel action button
- * REMARK: For some reason the button click currentTarget is not always the button
- * @param action object
- * @param webview dom object button will attach to
- * @returns dom object
- */
- function createActionButton(action, webview){
- const newBtn = document.createElement("button");
- newBtn.className = action.display_class+" button-toolbar-small mod-panel-action";
- newBtn.innerHTML = action.display;
- newBtn.addEventListener("click", event => {
- let eventSource = event.target;
- while(eventSource.tagName.toLowerCase()!== "button"){
- eventSource = eventSource.parentElement;
- }
- action.script(eventSource, webview);
- });
- newBtn.title = action.title;
- return newBtn;
- }
- /**
- * Add the panel action controls
- * @param panel dom node
- */
- function addPanelControls(panel){
- const alreadyAdded = panel.querySelector("footer");
- if(alreadyAdded){return;}
- const footer = document.createElement("footer");
- const webview = panel.querySelector("webview");
- for(const key in ACTIONS){
- const action = ACTIONS[key];
- const newButton = createActionButton(action, webview);
- footer.appendChild(newButton);
- }
- panel.appendChild(footer);
- }
- /**
- * upgrade a web panel by adding controls, listeners, etc.
- * @param panel dom node
- */
- function upgradePanel(panel){
- addPanelControls(panel);
- const webview = panel.querySelector("webview");
- webview.addEventListener("zoomchange", () => {
- updateZoomLabel(webview);
- });
- webview.addEventListener("loadcommit", () => {
- updateZoomLabel(webview);
- });
- }
- /**
- * Observe changes to the panels
- * Remark: This will either be to upgrade a panel when it is first created
- * or to re-add the panel controls if removed after a panel was toggled
- */
- const PANEL_CHANGE_OBSERVER = new MutationObserver(records => {
- records.forEach(record => {
- if(record.type==="attributes"){
- const targetClasses = record.target.classList;
- if(targetClasses.contains("visible") && targetClasses.contains("webpanel")){
- addPanelControls(record.target);
- }
- } else if (record.type==="childList") {
- record.addedNodes.forEach(node => {
- if(node.classList && node.classList.contains("webpanel")){
- upgradePanel(node);
- }
- });
- }
- });
- });
- /**
- * Begin observing the changes to panels
- * @param webPanelStack The web panel stack div
- */
- function beginObservation(webPanelStack){
- PANEL_CHANGE_OBSERVER.observe(webPanelStack, {
- attributes: true,
- attributeFilter: ["class"],
- childList: true,
- subtree: true
- });
- }
- /**
- * Initialise the mod
- */
- function initMod(){
- const webPanels = document.querySelector("#panels");
- if(webPanels){
- beginObservation(webPanels);
- const alreadyOpenPanel = document.querySelector(".panel.webpanel.visible");
- if(alreadyOpenPanel){
- upgradePanel(alreadyOpenPanel);
- }
- } else { setTimeout(initMod, 500); }
- }
- /* Start 500ms after the browser is opened */
- setTimeout(initMod, 500);
- })();
- /*
- * Site Security Box Favicons (a mod for Vivaldi)
- * Written by LonM
- * No Copyright Reserved
- * This mod takes the favicon from a tab and places it into the address bar site info box
- * Assumes presence of both the tab bar and the address bar
- */
- // Constant CSS Selectors
- const SECURITY_ZONE_ICON = "div.addressfield > button.button-addressfield.addressfield-siteinfo > div > svg";
- const ACTIVE_TAB = ".tab.active .favicon";
- const SECURITY_ZONE = "div.addressfield > button.button-addressfield.addressfield-siteinfo > div.siteinfo-symbol";
- // Selectors and config for observers
- const BROWSER_STATE_INDICATOR = "#browser"
- const BROWSER_STATE_INDICATOR_CONFIG = {attributes: true}
- const TAB_CHANGE_INDICATOR = ".tab-strip";
- const TAB_CHANGE_INDICATOR_CONFIG = {attributes: true, subtree: true}
- // Observer for changes to tab and browser state
- const browserStateChangeObserver = new MutationObserver(browser_state_changed)
- const differentTabActivatedObserver = new MutationObserver(tab_changed);
- // The browser changed state,
- // May need to re-observe deleted elements
- // E.g. if enter and exit of fullscreen / hide UI mode
- function browser_state_changed(m, o){
- //console.log("BROWSER STATE CHANGE");
- remove_existing_cloned_favicon();
- clone_favicon_and_add_to_security();
- differentTabActivatedObserver.disconnect();
- browserStateChangeObserver.disconnect();
- load_favicon_security_mod();
- }
- // The tab was changed, so favicon needs changing
- // this will cover changes to the .active tab AND
- // cover changes to the favicon span thru subtree
- function tab_changed(m, o){
- //console.log("TAB STRIP ATTRIBUTE CHANGE");
- clone_favicon_and_add_to_security();
- }
- // Clone the favicon and add a copy to the security zone
- // also style it appropriately
- function clone_favicon_and_add_to_security(){
- // make sure everything we need to access exists
- const sz_icon = document.querySelector(SECURITY_ZONE_ICON);
- const favicon_original = document.querySelector(ACTIVE_TAB);
- const siteinfo = document.querySelector(SECURITY_ZONE);
- if(!favicon_original || !sz_icon || !siteinfo){return;}
- remove_existing_cloned_favicon();
- // copy, style and set the favicon
- // use deep clone to also copy svg icons
- const favicon = favicon_original.cloneNode(true);
- favicon.style.width = "16px";
- favicon.style.height = "16px";
- favicon.style.display = "block";
- favicon.style.margin = "3px";
- siteinfo.style.display = "flex";
- sz_icon.parentNode.insertBefore(favicon, sz_icon);
- }
- // Remove any existing cloned favicon
- function remove_existing_cloned_favicon(){
- const old_sz_favicon = document.querySelector(SECURITY_ZONE+" .favicon");
- if(old_sz_favicon){
- old_sz_favicon.parentElement.removeChild(old_sz_favicon);
- }
- }
- // Load the mod
- function load_favicon_security_mod(){
- const browser = document.querySelector(BROWSER_STATE_INDICATOR)
- const tab_change_indicator = document.querySelector(TAB_CHANGE_INDICATOR);
- if (browser && tab_change_indicator) {
- browserStateChangeObserver.observe(browser, BROWSER_STATE_INDICATOR_CONFIG);
- differentTabActivatedObserver.observe(tab_change_indicator, TAB_CHANGE_INDICATOR_CONFIG);
- clone_favicon_and_add_to_security();
- } else {
- setTimeout(load_favicon_security_mod, 100);
- }
- }
- // BROWSER LOADED - entry point
- setTimeout(load_favicon_security_mod, 500);
- // Fixes the white flash when navigating away from the start page and the white blank page, by setting their color to the current theme's background color.
- (function() {
- var bodyStyles, colorBg;
- var observer = new MutationObserver(getBgColor);
- observer.observe(document.body, {
- attributes: true,
- attributeFilter: ['style']
- });
- function getBgColor() {
- bodyStyles = window.getComputedStyle(document.body);
- colorBg = bodyStyles.getPropertyValue('--colorBg');
- chrome.tabs.query({}, tabs => {
- tabs.forEach(tab => injectScript(tab.url, tab.id));
- });
- }
- chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => injectScript(tab.url, tab.id));
- function injectScript(tabUrl, tabId) {
- if(tabUrl === "about:blank" || tabUrl === "chrome-extension://mpognobbkildjkofajifpdfhcoklimli/components/startpage/startpage.html") {
- var css =`
- * {
- background-color: ${colorBg} !important;
- }`;
- var addCss =
- `if(!cssText){
- var cssText = document.createElement('style');
- cssText.setAttribute('description', 'Added by white-flash-fix.js');
- }
- cssText.textContent = \`${css}\`;
- document.head.appendChild(cssText);`;
- chrome.tabs.executeScript(tabId, {code: addCss, allFrames: true});
- }
- }
- })();
- /* Panel Toggle */
- function panelToggle() {
- const adr = document.querySelector('.toolbar-addressbar.toolbar');
- var panel = document.getElementById('panels-container');
- var paneltog = document.querySelector('.paneltogglefooter');
- var panelsvg = document.querySelector('.paneltogglefooter svg');
- var panelpath = document.querySelector('.paneltogglefooter svg path');
- var sright = 'd: path("M20 8v10h-14v-10h14zm-2 8v-6h-4v6h4z")';
- var sleft = 'd: path("M20 8v10h-14v-10h14zm-8 8v-6h-4v6h4z")';
- paneltog.classList.add('button-toolbar');
- paneltog.classList.remove('button-toolbar-small');
- paneltog.style.order = 'unset';
- panelsvg.style.transform = 'none';
- panelsvg.setAttributeNS(null, 'viewBox', '0 0 26 26');
- if (panel.classList.contains('right')) {
- adr.appendChild(paneltog);
- var pof = sright;
- var pon = sleft;
- }
- else {
- adr.insertBefore(paneltog,adr.firstChild);
- var pof = sleft;
- var pon = sright;
- }
- if (panel.classList.contains('switcher')) {
- panelpath.style = pof;
- }
- else {
- panelpath.style = pon;
- }
- paneltog.addEventListener('click', function(event) {
- if (!event.altKey) {
- if (panel.classList.contains('switcher')) {
- panelpath.style = pon;
- }
- else {
- panelpath.style = pof;
- }
- }
- });
- };
- /* Tools Menu */
- function create() {
- const adr = document.querySelector('.toolbar-addressbar.toolbar');
- const footer = document.getElementById('footer')
- footer.classList.add('disabled','zeig');
- var spanT = document.createElement('span');
- var divT = document.createElement('div');
- divT.id = 'droptool';
- var btnT = document.createElement('button');
- btnT.id = 'tools';
- btnT.classList.add('button-toolbar');
- btnT.setAttribute('tabindex', '-1');
- btnT.setAttribute('title', 'Tools');
- btnT.innerHTML = '<svg width="26" height="26" viewBox="-150 -150 812 812" xmlns="http://www.w3.org/2000/svg"><path d="M483.97,105.709c-2.491-9.958-14.903-13.424-22.157-6.165l-58.913,58.914c-13.083,13.077-34.291,13.077-47.372,0 l-27.03-27.031c-13.082-13.081-13.082-34.289,0-47.372l58.196-58.197c7.307-7.307,3.751-19.838-6.306-22.193 c-13.772-3.218-28.327-4.406-43.339-3.208c-64.522,5.148-123.907,65.649-127.923,130.254c-1.521,24.503,3.43,47.667,13.077,68.186 L16.253,375.878c-9.263,7.96-14.81,19.401-15.323,31.602c-0.519,12.201,4.042,24.068,12.599,32.78l34.902,35.541 c8.64,8.802,20.57,13.586,32.899,13.19c12.33-0.399,23.928-5.936,31.986-15.271l178.388-206.684 c19.917,8.889,42.21,13.424,65.747,11.956c65.041-4.058,125.554-63.92,130.29-128.91 C488.863,134.686,487.482,119.777,483.97,105.709z"></path>';
- var infdiv = document.createElement('div');
- infdiv.id = 'divID';
- infdiv.innerHTML = '<button id="toggle-links" title="Hide Status Info" class="button-toolbar-small" tabindex="-1"><svg width="16" height="16" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg"><path d="M17.6 20.4l-1.6 1.6-9-9 9-9 1.6 1.6-7.2 7.4 7.2 7.4z" fill="var(--colorHighlightBg)"></path></svg></button>';
- adr.insertBefore(spanT,document.querySelector('.searchfield').nextSibling);
- spanT.appendChild(btnT);
- spanT.appendChild(divT);
- divT.appendChild(footer);
- footer.appendChild(infdiv);
- };
- function cssT() {
- var styleS = document.createElement('style');
- styleS.type = 'text/css';
- styleS.innerHTML = '#droptool {position: absolute;z-index: 1;right: 0;box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);}.callout {bottom: unset;margin-top: 1px;}.callout::before, .callout::after {display: none;}#divID {order: 1 }.sync-status {order: 2;}.status-toolbar {order: 3;}#footer {border-right: none;}#status_info {display: none;}#footer.zeig #status_info.visible {display: flex;max-width: 500px;}';
- document.getElementsByTagName('head')[0].appendChild(styleS);
- };
- function menuT() {
- if (footer.classList.contains('disabled')) {
- footer.classList.remove('disabled');
- }
- else {
- footer.classList.add('disabled');
- }
- };
- function statusT() {
- const fill = document.querySelector('#toggle-links svg path');
- const infbtn = document.getElementById('toggle-links');
- if (footer.classList.contains('zeig')) {
- footer.classList.remove('zeig');
- fill.setAttribute('fill', 'var(--colorFg)');
- infbtn.setAttribute('title', 'Show Status Info');
- }
- else {
- footer.classList.add('zeig');
- fill.setAttribute('fill', 'var(--colorHighlightBg)');
- infbtn.setAttribute('title', 'Hide Status Info');
- }
- };
- function toolsMenu() {
- create();
- cssT();
- document.getElementById('tools').addEventListener('click', menuT);
- document.getElementById('toggle-links').addEventListener('click', statusT);
- };
- setTimeout(function wait() {
- const adr = document.querySelector('.toolbar-addressbar.toolbar');
- if (adr) {
- toolsMenu();
- panelToggle();
- }
- else {
- setTimeout(wait, 300);
- }
- }, 300);
Advertisement
Add Comment
Please, Sign In to add comment