├── Extras ├── 16.png ├── 256.png ├── 32.png ├── 48.png ├── EdgeIcon.ico ├── EdgeIcon.png └── edgelogobig.png ├── INSTALLATION.md ├── README.md ├── ffroot ├── config.js └── defaults │ └── pref │ ├── channel-prefs.js │ └── config-prefs.js ├── images ├── edgelogo.png ├── example.png └── guide.png └── profile └── chrome ├── JS ├── activity_throbber.uc.js ├── change-toolbar-icon-values.uc.js ├── favicon_in_urlbar.uc.js └── space_and_separator_restorer.uc.js ├── alltabs.png ├── arrow.png ├── checkmark.png ├── cheveron.png ├── close.png ├── ie.png ├── internet.png ├── items ├── copy.png ├── cut.png ├── download.png ├── email.png ├── extensions.png ├── favorites.png ├── fullscreen.png ├── history.png ├── home.png ├── left.png ├── paste.png ├── personal.png ├── print.png ├── reload.png ├── right.png ├── search.png └── stop.png ├── newtab.png ├── radio.png ├── spinnerdown.png ├── throbber.gif ├── throbber_busy.gif ├── user.png ├── userChrome.css └── utils ├── BootstrapLoader.jsm ├── RDFDataSource.jsm ├── RDFManifestConverter.jsm ├── aboutconfig ├── aboutconfig.xhtml ├── config.css └── config.js ├── boot.jsm ├── chrome.manifest ├── passwordmgr ├── passwordManager.js ├── passwordManager.xhtml └── passwordmgr.css ├── userChrome.jsm ├── userPrefs.jsm └── xPref.jsm /Extras/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/Extras/16.png -------------------------------------------------------------------------------- /Extras/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/Extras/256.png -------------------------------------------------------------------------------- /Extras/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/Extras/32.png -------------------------------------------------------------------------------- /Extras/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/Extras/48.png -------------------------------------------------------------------------------- /Extras/EdgeIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/Extras/EdgeIcon.ico -------------------------------------------------------------------------------- /Extras/EdgeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/Extras/EdgeIcon.png -------------------------------------------------------------------------------- /Extras/edgelogobig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/Extras/edgelogobig.png -------------------------------------------------------------------------------- /INSTALLATION.md: -------------------------------------------------------------------------------- 1 | # Installation Instructions 2 | ## Copying files 3 | In Firefox, go to about:profiles and look for the profile in use. Open the "Root Directory" folder. Copy the contents of /profile into this folder. 4 | Next you can go to your Firefox installation directory (It should be C:/Program Files (x86)/Mozilla Firefox. Copy the contents of /ffroot into this directory, you may need administrator permissions. 5 | 6 | ## Setting up 7 | After restarting, you're going to need to go to about:config and enable these flags: 8 | - toolkit.legacyUserProfileCustomizations.stylesheets - set to true 9 | - svg.context-properties.content.enabled - set to true 10 | - ui.prefersReducedMotion - set to 1, you may need to create a new "Number" value 11 | - widget.non-native-theme.enabled - set to false, 12 | - extensions.unifiedExtensions.enabled - set to true, 109+ only 13 | 14 | then restart Firefox. 15 | 16 | ## UI Configuration 17 | After installation, right click on the tabs toolbar and press "Customize Toolbar". Here is a guide to help you: 18 | 19 | ![Installation Guide](https://raw.githubusercontent.com/SoniKast/Edge2003/main/images/guide.png) 20 | 21 | **Make sure to enable Title Bar!!** 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Edge2003 2 | ![Edge2003 Logo](https://raw.githubusercontent.com/SoniKast/Edge2003/main/images/edgelogo.png) 3 | 4 | ## What is this? 5 | **Edge2003** is a Firefox CSS mod that replicates **MondySpartan**'s [Microsoft Edge in 2003 Mockup](https://www.reddit.com/r/Windows_Redesign/comments/11mj5zr/microsoft_edge_in_2003_made_before_that_edge_from/) (to the best of my abilities). 6 | 7 | It was developed on Firefox 111, so it should work on most recent versions of Firefox, unless they mess everything up (and they probably will lol). 8 | UPDATE: The icons no longer display properly when you run this skin on Firefox 112... so, I'm gonna be working on that 9 | 10 | This theme is based on the IE6 theme made for the Windows eXPerience iso, which... you can find in [**Windows eXPerience**](https://archive.org/details/windows-experience-freestyle/), go check it out! And the page is based on [Aerofox by NWinXP.](https://github.com/NWinXP/Aerofox) 11 | 12 | ## Supported operating systems 13 | While you can use the theme on macOS or Linux, it will probably not look right. This theme was made to work with Windows 10 using a version of [BasicThemer](https://github.com/arukateru/BasicThemer5) and the [PerfectLuna10 theme](https://winclassic.boards.net/thread/1528/noir10-perfectluna10). While it has not been tested on other Windows versions, it should work as long as you have an XP-based theme. 14 | 15 | Tested on: 16 | - Windows 10 (Version 22H2) x64 17 | - Windows 10 (Version 1809) x64 18 | 19 | ## Screenshots 20 | - Windows 10 1809 x64 with BasicThemer3, SecureUxTheme and PerfectLuna10 21 | 22 | ![Edge2003 Window](https://raw.githubusercontent.com/SoniKast/Edge2003/main/images/example.png) 23 | 24 | ## Download 25 | Go to the [releases](https://github.com/SoniKast/Edge2003/releases "releases") page and download the linked .ZIP file. 26 | 27 | ## FAQ 28 | - **Why though?** 29 | No particular reason, I just thought the mockup looked really cool, like an improvement over IE6's base design. 30 | - **How do I install it?** 31 | Read [INSTALLATION.md](https://github.com/SoniKast/Edge2003/blob/main/INSTALLATION.md "INSTALLATION.md") for more detailed installation instructions. 32 | - **Can I have the Edge2003 icon?** 33 | Check out the Extras folder for [those](https://github.com/SoniKast/Edge2003/tree/main/Extras). 34 | - **Can I modify it?** 35 | You are free to do whatever you want with this theme, it's freely available after all! 36 | - **The icons are broken...** 37 | I'm working on a fix right now, don't worry. Though it's only compatible with Firefox 115 ESR. 38 | 39 | ###### Internet Explorer and Edge are a trademark of Microsoft Corporation. All assets from Internet Explorer used in this project belong to Microsoft Corporation. 40 | ###### Firefox and the Firefox logo are trademarks of the Mozilla Foundation. 41 | ###### Edge2003 assets by MondySpartan. 42 | -------------------------------------------------------------------------------- /ffroot/config.js: -------------------------------------------------------------------------------- 1 | // skip 1st line 2 | try { 3 | 4 | let { 5 | classes: Cc, 6 | interfaces: Ci, 7 | manager: Cm, 8 | utils: Cu 9 | } = Components; 10 | 11 | let cmanifest = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties).get('UChrm', Ci.nsIFile); 12 | cmanifest.append('utils'); 13 | cmanifest.append('chrome.manifest'); 14 | 15 | if(cmanifest.exists()){ 16 | Cm.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(cmanifest); 17 | Cu.import('chrome://userchromejs/content/boot.jsm'); 18 | } 19 | 20 | } catch(ex) {}; -------------------------------------------------------------------------------- /ffroot/defaults/pref/channel-prefs.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | // 5 | // This pref is in its own file for complex reasons. See the comment in 6 | // browser/app/Makefile.in, bug 756325, and bug 1431342 for details. Do not add 7 | // other prefs to this file. 8 | 9 | pref("app.update.channel", "release"); 10 | -------------------------------------------------------------------------------- /ffroot/defaults/pref/config-prefs.js: -------------------------------------------------------------------------------- 1 | pref("general.config.obscure_value", 0); 2 | pref("general.config.filename", "config.js"); 3 | // Sandbox needs to be disabled in release and Beta versions 4 | pref("general.config.sandbox_enabled", false); -------------------------------------------------------------------------------- /images/edgelogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/images/edgelogo.png -------------------------------------------------------------------------------- /images/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/images/example.png -------------------------------------------------------------------------------- /images/guide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/images/guide.png -------------------------------------------------------------------------------- /profile/chrome/JS/activity_throbber.uc.js: -------------------------------------------------------------------------------- 1 | Components.utils.import("resource:///modules/CustomizableUI.jsm"); 2 | var {Services} = Components.utils.import("resource://gre/modules/Services.jsm", {}); 3 | var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService); 4 | 5 | var at_label = "Download Status"; 6 | 7 | var ActivityThrobber = { 8 | init: function() { 9 | 10 | try { 11 | 12 | document.addEventListener("TabAttrModified", _ActivityThrobber, false); 13 | document.addEventListener('TabSelect', _ActivityThrobber, false); 14 | document.addEventListener('TabOpen', _ActivityThrobber, false); 15 | document.addEventListener('TabClose', _ActivityThrobber, false); 16 | document.addEventListener('load', _ActivityThrobber, false); 17 | 18 | // add or remove 'busy' tab from activity item 19 | function _ActivityThrobber() { 20 | 21 | if(gBrowser.selectedTab.hasAttribute('busy')) { 22 | document.querySelector('#download_status').setAttribute('busy','true'); 23 | } else document.querySelector('#download_status').removeAttribute('busy'); 24 | 25 | } 26 | 27 | // create a default toolbar button 28 | CustomizableUI.createWidget({ 29 | id: "download_status", // button id 30 | defaultArea: CustomizableUI.AREA_MENUBAR, 31 | removable: false, 32 | label: at_label, // button title 33 | onCreated: function(button) { 34 | return button; 35 | } 36 | 37 | }); 38 | } catch (e) { Components.utils.reportError(e); } 39 | 40 | } 41 | 42 | }; 43 | 44 | document.addEventListener("DOMContentLoaded", ActivityThrobber.init(), false); -------------------------------------------------------------------------------- /profile/chrome/JS/change-toolbar-icon-values.uc.js: -------------------------------------------------------------------------------- 1 | function waitForElm(selector) { 2 | return new Promise(resolve => { 3 | if (document.querySelector(selector)) { 4 | return resolve(document.querySelector(selector)); 5 | } 6 | 7 | const observer = new MutationObserver(mutations => { 8 | if (document.querySelector(selector)) { 9 | resolve(document.querySelector(selector)); 10 | observer.disconnect(); 11 | } 12 | }); 13 | 14 | observer.observe(document.body, { 15 | childList: true, 16 | subtree: true 17 | }); 18 | }); 19 | } 20 | 21 | waitForElm('#find-button').then((elm) => { 22 | var find = document.querySelector("#find-button label.toolbarbutton-text"); 23 | find.setAttribute("value", "Search"); 24 | }); 25 | 26 | setTimeout(function () { 27 | waitForElm('#nav-bar').then((elm) => { 28 | var library = document.querySelector("#bookmarks-menu-button label.toolbarbutton-text"); 29 | library.setAttribute("value", "Favorites"); 30 | }); 31 | }, 0); 32 | 33 | waitForElm('#bookmarksMenu').then((elm) => { 34 | var bookmarksmenu = document.querySelector("#bookmarksMenu label.menubar-text"); 35 | bookmarksmenu.setAttribute("value", "Favorites"); 36 | bookmarksmenu.setAttribute("accesskey", "a"); 37 | }); 38 | 39 | waitForElm('#bookmarksMenu').then((elm) => { 40 | var bookmarksmenu = document.querySelector("#bookmarksMenu"); 41 | bookmarksmenu.setAttribute("accesskey", "a"); 42 | }); -------------------------------------------------------------------------------- /profile/chrome/JS/favicon_in_urlbar.uc.js: -------------------------------------------------------------------------------- 1 | // 'Favicon in urlbars identity box' script for Firefox 92+ by Aris 2 | // 3 | // This script restores current pages favicon inside urlbar (aka location bar, address bar or awesome bar). 4 | // [!] If a page does not offer a favicon, browser branches default icon is shown. 5 | // [!] In a multi-window environment pages without favicons might show wrong icons. 6 | // option: set icon for pages without favicon 7 | 8 | var i_icon = 'chrome://global/skin/icons/info.svg'; 9 | var sheet = 'chrome://global/skin/icons/Portrait.png'; 10 | var brand = 'https://cdn.discordapp.com/attachments/407220400578101257/1089237043521015949/ie.png'; 11 | var globe = 'https://cdn.discordapp.com/attachments/407220400578101257/1089237043521015949/ie.png'; 12 | 13 | var icon_for_pages_without_favicon = brand; // i_icon, sheet, globe or brand (colorized Fx channel icon) 14 | 15 | var favicon_click_opens_page_info_window = false; 16 | 17 | var FaviconInUrlbar = { 18 | init: function() { 19 | try { 20 | 21 | var favimginurlbar = document.createXULElement("image"); 22 | favimginurlbar.setAttribute("id","favimginurlbar"); 23 | 24 | if(favicon_click_opens_page_info_window) 25 | favimginurlbar.setAttribute("onclick","gIdentityHandler.handleMoreInfoClick(event);"); 26 | 27 | favimginurlbar.style.width = "16px"; 28 | favimginurlbar.style.height = "16px"; 29 | favimginurlbar.style.marginLeft = "3px"; 30 | favimginurlbar.style.marginRight = "3px"; 31 | favimginurlbar.style.marginTop = "3px"; 32 | favimginurlbar.style.marginBottom = "3px"; 33 | 34 | //document.getElementById('identity-box').insertBefore(favimginurlbar,document.getElementById('identity-box').firstChild); 35 | document.getElementById('identity-box').appendChild(favimginurlbar); 36 | 37 | // update script every time tab attributes get modified (switch/open tabs/windows) 38 | document.addEventListener("TabAttrModified", updateIcon, false); 39 | document.addEventListener('TabSelect', updateIcon, false); 40 | document.addEventListener('TabOpen', updateIcon, false); 41 | document.addEventListener('TabClose', updateIcon, false); 42 | document.addEventListener('load', updateIcon, false); 43 | document.addEventListener("DOMContentLoaded", updateIcon, false); 44 | 45 | 46 | function updateIcon() { 47 | 48 | setTimeout(function(){ // timeout fixes wrong icon detection in some cases 49 | 50 | // get current tabs favicon 51 | var favicon_in_urlbar = gBrowser.selectedTab.image; 52 | 53 | // if current tab offers no icon, use selected icon (icon_for_pages_without_favicon) 54 | if(!gBrowser.selectedTab.image || gBrowser.selectedTab.image == null) 55 | if(!icon_for_pages_without_favicon) favicon_in_urlbar = brand; 56 | else favicon_in_urlbar = icon_for_pages_without_favicon; 57 | 58 | document.querySelector('#favimginurlbar').style.listStyleImage = "url("+favicon_in_urlbar+")"; 59 | 60 | },1); 61 | 62 | } 63 | 64 | } catch(e) {} 65 | } 66 | }; 67 | 68 | // initiate script after DOM/browser content is loaded 69 | document.addEventListener("DOMContentLoaded", FaviconInUrlbar.init(), false); 70 | -------------------------------------------------------------------------------- /profile/chrome/JS/space_and_separator_restorer.uc.js: -------------------------------------------------------------------------------- 1 | // Restore 'Space & Separator' items script for Firefox 60+ by Aris 2 | // 3 | // Default browser scripts always remove spaces and separators from default palette, so 4 | // because of that they are added to an own toolbar now. 5 | // 6 | // - spaces and separators can be moved to any toolbar 7 | // - to remove spaces or separators move them into palette 8 | // - configuration toolbar behaves like a default toolbar, items and buttons can be placed on it 9 | // - configuration toolbar is not visible outside customizing mode 10 | // - default "Flexible Space" item is hidden from palette and added to configuration toolbar 11 | // [!] BUG: do not move spaces, flexible spaces or separator to configuration toolbar or it will cause glitches 12 | // [!] BUG: do not move main 'space'-item to palette or it will be hidden until customizing mode gets reopened 13 | 14 | // [!] Fix for WebExtensions with own windows by 黒仪大螃蟹 (for 1-N scripts) 15 | 16 | 17 | Components.utils.import("resource:///modules/CustomizableUI.jsm"); 18 | var {Services} = Components.utils.import("resource://gre/modules/Services.jsm", {}); 19 | var appversion = parseInt(Services.appinfo.version); 20 | 21 | var AddSeparator = { 22 | init: function() { 23 | 24 | if (appversion >= 76 && location != 'chrome://browser/content/browser.xhtml') 25 | return; 26 | 27 | /* blank tab workaround */ 28 | try { 29 | if(gBrowser.selectedBrowser.getAttribute('blank')) gBrowser.selectedBrowser.removeAttribute('blank'); 30 | } catch(e) {} 31 | 32 | var tb_config_label = "Configuration Toolbar"; 33 | var tb_spacer_label = "Space"; 34 | var tb_sep_label = "Separator"; 35 | var tb_spring_label = "Flexible Space"; 36 | 37 | try { 38 | if(document.getElementById('configuration_toolbar') == null) { 39 | 40 | if(appversion <= 62) var tb_config = document.createElement("toolbar"); 41 | else var tb_config = document.createXULElement("toolbar"); 42 | tb_config.setAttribute("id","configuration_toolbar"); 43 | tb_config.setAttribute("customizable","true"); 44 | tb_config.setAttribute("class","toolbar-primary chromeclass-toolbar browser-toolbar customization-target"); 45 | tb_config.setAttribute("mode","icons"); 46 | tb_config.setAttribute("iconsize","small"); 47 | tb_config.setAttribute("toolboxid","navigator-toolbox"); 48 | tb_config.setAttribute("lockiconsize","true"); 49 | tb_config.setAttribute("ordinal","1005"); 50 | tb_config.setAttribute("defaultset","toolbarspacer,toolbarseparator"); 51 | 52 | document.querySelector('#navigator-toolbox').appendChild(tb_config); 53 | 54 | CustomizableUI.registerArea("configuration_toolbar", {legacy: true}); 55 | if(appversion >= 65) CustomizableUI.registerToolbarNode(tb_config); 56 | 57 | if(appversion <= 62) var tb_label = document.createElement("label"); 58 | else var tb_label = document.createXULElement("label"); 59 | tb_label.setAttribute("label", tb_config_label+": "); 60 | tb_label.setAttribute("value", tb_config_label+": "); 61 | tb_label.setAttribute("id","tb_config_tb_label"); 62 | tb_label.setAttribute("removable","false"); 63 | 64 | tb_config.appendChild(tb_label); 65 | 66 | 67 | if(appversion <= 62) var tb_spacer = document.createElement("toolbarspacer"); 68 | else var tb_spacer = document.createXULElement("toolbarspacer"); 69 | tb_spacer.setAttribute("id","spacer"); 70 | tb_spacer.setAttribute("class","chromeclass-toolbar-additional"); 71 | tb_spacer.setAttribute("customizableui-areatype","toolbar"); 72 | tb_spacer.setAttribute("removable","false"); 73 | tb_spacer.setAttribute("label", tb_spacer_label); 74 | 75 | tb_config.appendChild(tb_spacer); 76 | 77 | 78 | if(appversion <= 62) var tb_sep = document.createElement("toolbarseparator"); 79 | else var tb_sep = document.createXULElement("toolbarseparator"); 80 | tb_sep.setAttribute("id","separator"); 81 | tb_sep.setAttribute("class","chromeclass-toolbar-additional"); 82 | tb_sep.setAttribute("customizableui-areatype","toolbar"); 83 | tb_sep.setAttribute("removable","false"); 84 | tb_sep.setAttribute("label", tb_sep_label); 85 | 86 | tb_config.appendChild(tb_sep); 87 | 88 | 89 | if(appversion <= 62) var tb_spring = document.createElement("toolbarspring"); 90 | else var tb_spring = document.createXULElement("toolbarspring"); 91 | tb_spring.setAttribute("id","spring"); 92 | tb_spring.setAttribute("class","chromeclass-toolbar-additional"); 93 | tb_spring.setAttribute("customizableui-areatype","toolbar"); 94 | tb_spring.setAttribute("removable","false"); 95 | tb_spring.setAttribute("flex","1"); 96 | tb_spring.setAttribute("label", tb_spring_label); 97 | 98 | tb_config.appendChild(tb_spring); 99 | 100 | // CSS 101 | var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService); 102 | 103 | var uri = Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent('\ 104 | \ 105 | #configuration_toolbar { \ 106 | -moz-appearance: none !important; \ 107 | background-color: var(--toolbar-bgcolor); \ 108 | background-image: var(--toolbar-bgimage); \ 109 | background-clip: padding-box; \ 110 | color: var(--toolbar-color, inherit); \ 111 | } \ 112 | #main-window:not([customizing]) #configuration_toolbar { \ 113 | visibility: collapse; \ 114 | }\ 115 | #main-window[customizing] #configuration_toolbar #tb_config_tb_label { \ 116 | font-weight: bold !important; \ 117 | }\ 118 | #main-window[customizing] #configuration_toolbar :-moz-any(#spacer,#separator,#spring) { \ 119 | -moz-margin-start: 20px; \ 120 | }\ 121 | #main-window[customizing] #configuration_toolbar :-moz-any(#wrapper-spacer,#wrapper-separator,#wrapper-spring) .toolbarpaletteitem-label { \ 122 | display: block !important; \ 123 | -moz-margin-end: 20px; \ 124 | }\ 125 | #main-window[customizing] #wrapper-spacer #spacer { \ 126 | margin: 2px 0 !important; \ 127 | }\ 128 | #main-window[customizing] #configuration_toolbar #wrapper-spring #spring { \ 129 | margin: -1px 0 !important; \ 130 | min-width: 80px !important; \ 131 | }\ 132 | #main-window[customizing] #configuration_toolbar > * { \ 133 | padding: 10px !important; \ 134 | }\ 135 | #main-window[customizing] #configuration_toolbar > :-moz-any(#wrapper-spacer,#wrapper-separator,#wrapper-spring) { \ 136 | border: 1px dotted !important; \ 137 | -moz-margin-start: 2px !important; \ 138 | -moz-margin-end: 2px !important; \ 139 | }\ 140 | #main-window[customizing] toolbarspacer { \ 141 | border: 1px solid !important; \ 142 | }\ 143 | toolbar[orient="vertical"] toolbarseparator { \ 144 | -moz-appearance: none !important; \ 145 | border-top: 1px solid rgba(15,17,38, 0.5) !important; \ 146 | border-bottom: 1px solid rgba(255,255,255, 0.3) !important; \ 147 | margin: 2px 2px !important; \ 148 | height: 1px !important; \ 149 | width: 18px !important; \ 150 | }\ 151 | toolbar[orient="vertical"] toolbarspacer { \ 152 | -moz-appearance: none !important; \ 153 | height: 18px !important; \ 154 | width: 18px !important; \ 155 | }\ 156 | #customization-palette toolbarpaletteitem[id^="wrapper-customizableui-special-spring"], \ 157 | #customization-palette-container :-moz-any(#spring,#wrapper-spring) { \ 158 | display: none !important; \ 159 | }\ 160 | #main-window:not([customizing]) toolbar:not(#configuration_toolbar) toolbarspring {\ 161 | max-width: 100% !important; \ 162 | }\ 163 | \ 164 | '), null, null); 165 | 166 | sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET); 167 | } 168 | } catch(e){} 169 | 170 | } 171 | 172 | } 173 | 174 | /* initialization delay workaround */ 175 | document.addEventListener("DOMContentLoaded", AddSeparator.init(), false); 176 | /* Use the below code instead of the one above this line, if issues occur */ 177 | /* 178 | setTimeout(function(){ 179 | AddSeparator.init(); 180 | },2000); 181 | */ 182 | -------------------------------------------------------------------------------- /profile/chrome/alltabs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/alltabs.png -------------------------------------------------------------------------------- /profile/chrome/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/arrow.png -------------------------------------------------------------------------------- /profile/chrome/checkmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/checkmark.png -------------------------------------------------------------------------------- /profile/chrome/cheveron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/cheveron.png -------------------------------------------------------------------------------- /profile/chrome/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/close.png -------------------------------------------------------------------------------- /profile/chrome/ie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/ie.png -------------------------------------------------------------------------------- /profile/chrome/internet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/internet.png -------------------------------------------------------------------------------- /profile/chrome/items/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/copy.png -------------------------------------------------------------------------------- /profile/chrome/items/cut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/cut.png -------------------------------------------------------------------------------- /profile/chrome/items/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/download.png -------------------------------------------------------------------------------- /profile/chrome/items/email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/email.png -------------------------------------------------------------------------------- /profile/chrome/items/extensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/extensions.png -------------------------------------------------------------------------------- /profile/chrome/items/favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/favorites.png -------------------------------------------------------------------------------- /profile/chrome/items/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/fullscreen.png -------------------------------------------------------------------------------- /profile/chrome/items/history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/history.png -------------------------------------------------------------------------------- /profile/chrome/items/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/home.png -------------------------------------------------------------------------------- /profile/chrome/items/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/left.png -------------------------------------------------------------------------------- /profile/chrome/items/paste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/paste.png -------------------------------------------------------------------------------- /profile/chrome/items/personal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/personal.png -------------------------------------------------------------------------------- /profile/chrome/items/print.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/print.png -------------------------------------------------------------------------------- /profile/chrome/items/reload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/reload.png -------------------------------------------------------------------------------- /profile/chrome/items/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/right.png -------------------------------------------------------------------------------- /profile/chrome/items/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/search.png -------------------------------------------------------------------------------- /profile/chrome/items/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/items/stop.png -------------------------------------------------------------------------------- /profile/chrome/newtab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/newtab.png -------------------------------------------------------------------------------- /profile/chrome/radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/radio.png -------------------------------------------------------------------------------- /profile/chrome/spinnerdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/spinnerdown.png -------------------------------------------------------------------------------- /profile/chrome/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/throbber.gif -------------------------------------------------------------------------------- /profile/chrome/throbber_busy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/throbber_busy.gif -------------------------------------------------------------------------------- /profile/chrome/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoniKast/Edge2003/879c3c4555d268a3b2b4ec8546a1479ca4e34b1a/profile/chrome/user.png -------------------------------------------------------------------------------- /profile/chrome/userChrome.css: -------------------------------------------------------------------------------- 1 | #main-window[privatebrowsingmode=temporary]:root, :root { 2 | --toolbar-bgcolor: -moz-Dialog !important; 3 | --toolbar-bgimage: none !important; 4 | --toolbar-color: -moz-DialogText !important; 5 | --lwt-text-color: -moz-DialogText !important; 6 | --lwt-toolbarbutton-icon-fill: -moz-DialogText !important; 7 | --toolbar-field-focus-border-color: Highlight !important; 8 | --lwt-toolbar-field-background-color: -moz-Field !important; 9 | --lwt-toolbar-field-color: -moz-FieldText !important; 10 | --lwt-toolbar-field-border-color: rgb(204, 204, 204) !important; 11 | --lwt-toolbar-field-focus: -moz-Field !important; 12 | --lwt-toolbar-field-focus-color: -moz-FieldText !important; 13 | --toolbarbutton-vertical-text-padding: calc(var(--toolbarbutton-inner-padding) - 1px) !important; 14 | --toolbarbutton-border-radius: 2px !important; 15 | --toolbarbutton-icon-fill-opacity: 1 !important; 16 | --panel-separator-color: ThreeDLightShadow !important; 17 | --arrowpanel-background: -moz-Field !important; 18 | --arrowpanel-color: -moz-FieldText !important; 19 | --arrowpanel-border-color: ThreeDShadow !important; 20 | --arrowpanel-dimmed: hsla(0,0%,80%,.35) !important; 21 | --arrowpanel-dimmed-further: hsla(0,0%,80%,.5) !important; 22 | --arrowpanel-dimmed-even-further: hsla(0,0%,80%,.8) !important; 23 | --urlbar-separator-color: ThreeDLightShadow !important; 24 | --chrome-content-separator-color: ThreeDShadow !important; 25 | --toolbarbutton-hover-transition-duration: 0 !important; 26 | --toolbarbutton-outer-padding: 2px !important; 27 | --toolbarbutton-inner-padding: 6px !important; 28 | --toolbarbutton-focus-outline: 2px solid currentColor !important; 29 | --autocomplete-popup-background: -moz-Field !important; 30 | --autocomplete-popup-color: -moz-FieldText !important; 31 | --toolbarbutton-hover-background: var(hsla(240,5%,5%,.1)) !important; 32 | --toolbarbutton-active-background: var(hsla(240,5%,5%,.15)) !important; 33 | --autocomplete-popup-highlight-background: Highlight !important; 34 | --autocomplete-popup-highlight-color: HighlightText !important; 35 | --tab-min-height: 12px !important; 36 | --arrowpanel-border-radius: 0px !important; 37 | --panel-item-hover-bgcolor: Highlight !important; 38 | --panel-separator-color: #ACA899 !important; 39 | } 40 | 41 | toolbarbutton menupopup[placespopup] { 42 | --panel-border-radius: 0 !important; 43 | --panel-padding: 2px !important; 44 | --arrowpanel-menuitem-margin: 0 !important; 45 | } 46 | 47 | toolbarbutton menupopup > :is(menu, menuitem) { 48 | min-height: 17px !important; 49 | } 50 | 51 | toolbox, 52 | toolbar, 53 | toolbarbutton:not(#sidebar-close):not(#sidebar-switcher-target):not(#download_status):not(#PanelUI-menu-button):not(#PlacesChevron), 54 | tab, 55 | .toolbarbutton-icon, 56 | #urlbar-background, 57 | .toolbarbutton-text 58 | { 59 | box-shadow: none !important; 60 | border: 0 !important; 61 | -moz-appearance: auto !important; 62 | background-color: transparent !important; 63 | } 64 | 65 | .tabbrowser-tab { 66 | } 67 | 68 | .toolbarbutton-badge-stack 69 | { 70 | background-color: transparent !important; 71 | } 72 | 73 | #download_status .toolbarbutton-icon, 74 | #toolbar-menubar spacer, 75 | #alltabs-button, 76 | .tab-background, 77 | #tracking-protection-icon-container, 78 | #identity-icon-box, 79 | #identity-permission-box, 80 | identity-icon-box, 81 | #star-button-box 82 | { 83 | display: none !important; 84 | } 85 | 86 | #download_status 87 | { 88 | width: 38px !important; 89 | height: 22px !important; 90 | position: relative !important; 91 | background-color: rgb(255, 255, 255) !important; 92 | background-position: center center; 93 | background-repeat: no-repeat; 94 | background-image: url('throbber.gif'); 95 | } 96 | 97 | #download_status[busy] 98 | { 99 | background-image: url('throbber_busy.gif'); 100 | } 101 | 102 | #download_status::after 103 | { 104 | content: ''; 105 | display: inline-block; 106 | width: 23px !important; 107 | height: 1px !important; 108 | appearance: toolbar !important; 109 | transform: rotate(-0.250006turn); 110 | position: absolute !important; 111 | left: -12px !important; 112 | bottom: 9px !important; 113 | z-index: 999999999 !important; 114 | } 115 | 116 | #menubar-items > #main-menubar > menu { 117 | height: 19px !important; 118 | margin-top: 1px !important; 119 | } 120 | 121 | .menubar-text { 122 | margin: 1px 9px !important; 123 | } 124 | 125 | #additional_top_toolbar1 #PlacesToolbarItems { 126 | width: 0 !important; 127 | max-width: 0 !important; 128 | } 129 | 130 | #additional_top_toolbar1 #PlacesToolbar { 131 | -moz-box-align: center !important; 132 | } 133 | 134 | #toolbar-menubar { 135 | padding-left: 2px !important; 136 | } 137 | 138 | #additional_top_toolbar1 #PlacesToolbar::before { 139 | content: 'Links'; 140 | display: inline-block; 141 | margin-inline: 4px !important; 142 | color: Scrollbar !important; 143 | } 144 | 145 | #additional_top_toolbar1 #personal-bookmarks::before { 146 | content: ''; 147 | display: inline-block; 148 | width: 23px !important; 149 | height: 1px !important; 150 | appearance: toolbar !important; 151 | transform: rotate(-0.250006turn); 152 | position: absolute !important; 153 | left: -12px !important; 154 | bottom: 9px !important; 155 | z-index: 999999999 !important; 156 | } 157 | 158 | #additional_top_toolbar1 #personal-bookmarks { 159 | margin-left: 2px !important; 160 | } 161 | 162 | #tabbrowser-tabs, #tabbrowser-arrowscrollbox, #tabbrowser-tabs[positionpinnedtabs] > #tabbrowser-arrowscrollbox > .tabbrowser-tab[pinned] { 163 | min-height: 0 !important; 164 | } 165 | 166 | .tabbrowser-tab:first-of-type:last-of-type, 167 | .tabbrowser-tab:first-of-type:last-of-type ~ #tabbrowser-arrowscrollbox-periphery { 168 | display: none !important; 169 | } 170 | 171 | #additional_top_toolbar1 { 172 | -moz-box-ordinal-group: 3 !important; 173 | padding-top: 2px; 174 | position: relative; 175 | height: 23px !important; 176 | } 177 | 178 | #TabsToolbar { 179 | padding-inline: 2px !important; 180 | -moz-box-ordinal-group: 4 !important; 181 | } 182 | 183 | #additional_top_toolbar1::before { 184 | content: ''; 185 | display: inline-block; 186 | height: 1px; 187 | width: 100%; 188 | appearance: toolbar; 189 | position: absolute; 190 | top: 0; 191 | } 192 | 193 | #additional_top_toolbar1::after { 194 | content: 'Address'; 195 | display: inline-block; 196 | margin-inline: 5px !important; 197 | -moz-box-ordinal-group: 0 !important; 198 | line-height: 22px !important; 199 | color: Scrollbar !important; 200 | } 201 | 202 | #urlbar-container { 203 | --urlbar-container-height: 32px !important; 204 | margin-inline: 3px !important; 205 | padding-block: 0 !important; 206 | min-width: unset !important; 207 | } 208 | 209 | #urlbar-container.chromeclass-location 210 | { 211 | top: 8px !important; 212 | } 213 | 214 | #urlbar { 215 | --urlbar-height: 22px !important; 216 | --urlbar-toolbar-height: 22px !important; 217 | appearance: listbox !important; 218 | -moz-default-appearance: listbox !important; 219 | font: -moz-pull-down-menu !important; 220 | min-height: 22px !important; 221 | z-index: 9999999 !important; 222 | } 223 | 224 | #urlbar-background { 225 | appearance: listbox !important; 226 | -moz-default-appearance: listbox !important; 227 | } 228 | 229 | #urlbar[breakout][breakout-extend] #urlbar-background { 230 | height: var(--urlbar-height) !important; 231 | } 232 | 233 | #urlbar[breakout]:not([breakout-extend]) #urlbar-background { 234 | display: none !important; 235 | } 236 | 237 | #urlbar[breakout][breakout-extend] { 238 | appearance: none !important; 239 | -moz-default-appearance: none !important; 240 | width: 100% !important; 241 | left: 0 !important; 242 | z-index: 999999 !important; 243 | } 244 | 245 | .urlbarView { 246 | width: 100% !important; 247 | background-color: rgb(255, 255, 255) !important; 248 | border: 1px solid rgb(0, 0, 0) !important; 249 | margin-inline: 0 !important; 250 | z-index: 999999 !important; 251 | } 252 | 253 | #urlbar[breakout][breakout-extend] > #urlbar-input-container { 254 | height: 22px !important; 255 | } 256 | 257 | #urlbar[open] > .urlbarView > .urlbarView-body-outer > .urlbarView-body-inner { 258 | border: 0 !important; 259 | } 260 | 261 | #urlbar .search-one-offs:not([hidden]) { 262 | display: none !important; 263 | } 264 | 265 | #urlbar-input-container { 266 | padding: 0 !important; 267 | border: 0 !important; 268 | } 269 | 270 | #urlbar[breakout] { 271 | top: 0 !important; 272 | } 273 | 274 | .urlbarView-row[label][dynamicType="quickactions"] { 275 | display: none !important; 276 | } 277 | 278 | .urlbarView-results, 279 | .urlbarView-row { 280 | padding-block: 0 !important; 281 | min-height: 16px !important; 282 | border-radius: 0 !important; 283 | border: 0 !important; 284 | } 285 | 286 | .urlbarView-row-inner { 287 | border-radius: 0 !important; 288 | padding-block: 0 !important; 289 | min-height: 16px !important; 290 | padding-inline: 0 !important; 291 | margin-left: 3px !important; 292 | flex: unset !important; 293 | padding-right: 1px !important; 294 | } 295 | 296 | .urlbarView-row[row-selectable]:not([selected]):hover { 297 | background-color: Highlight !important; 298 | color: HighlightText !important; 299 | } 300 | 301 | .urlbarView-row[label] { 302 | margin-block-start: 0 !important; 303 | } 304 | 305 | .urlbarView-row[label]::before { 306 | display: none !important; 307 | } 308 | 309 | .urlbarView-favicon { 310 | padding-right: 3px !important; 311 | margin-inline-end: 1px !important;\ 312 | } 313 | 314 | .urlbarView-row[selectable]:hover > .urlbarView-row-inner { 315 | background-color: var(--autocomplete-popup-highlight-background) !important; 316 | color: var(--autocomplete-popup-highlight-color) !important; 317 | } 318 | 319 | .urlbarView-tags, .urlbarView-url, .urlbarView-title:not(:empty) ~ .urlbarView-action { 320 | font-size: unset !important; 321 | } 322 | 323 | .urlbarView-title-separator::before { 324 | display: none !important; 325 | } 326 | 327 | .urlbarView-title-separator { 328 | margin-inline: 4px !important; 329 | } 330 | 331 | .urlbarView-row[selectable]:hover > .urlbarView-row-inner .urlbarView-url, .urlbarView-row-inner[selectable]:hover .urlbarView-url { 332 | color: var(--autocomplete-popup-highlight-color) !important; 333 | } 334 | 335 | #PersonalToolbar{ 336 | z-index: 99999 !important; 337 | overflow: hidden !important; 338 | } 339 | 340 | #PlacesChevron, #nav-bar-overflow-button { 341 | list-style-image: none !important; 342 | min-height: 18px !important; 343 | width: 10px !important; 344 | margin-left: 4px !important; 345 | } 346 | 347 | #PlacesChevron .toolbarbutton-icon, #nav-bar-overflow-button .toolbarbutton-icon { 348 | background-image: url('cheveron.png') !important; 349 | padding: 0 !important; 350 | background-repeat: no-repeat !important; 351 | background-position: center top !important; 352 | height: 10px !important; 353 | width: 10px !important; 354 | } 355 | 356 | #PanelUI-menu-button { 357 | list-style-image: none !important; 358 | margin-inline-end: 0 !important; 359 | padding: 0 !important; 360 | margin: 0 !important; 361 | min-width: 0 !important; 362 | } 363 | 364 | #PanelUI-menu-button .toolbarbutton-badge-stack { 365 | padding: 0 !important; 366 | display: none !important; 367 | } 368 | 369 | .browserStack > browser { 370 | box-shadow: inset -1px -1px 0 ThreeDHighlight, inset 1px 1px 0 ThreeDShadow, inset -2px -2px 0 ThreeDFace, inset 2px 2px 0 ThreeDDarkShadow !important; 371 | padding: 2px !important; 372 | } 373 | 374 | #statuspanel[inactive], 375 | #statuspanel { 376 | opacity: 1 !important; 377 | visibility: visible !important; 378 | width: 100% !important; 379 | height: 22px !important; 380 | -moz-appearance: statusbar !important; 381 | padding-top: 0 !important; 382 | padding-inline: 16px !important; 383 | display: flex !important; 384 | align-items: center !important; 385 | position: fixed !important; 386 | bottom: 0 !important; 387 | left: 0 !important; 388 | } 389 | 390 | :root[sizemode="fullscreen"] #statuspanel { 391 | display: none !important; 392 | } 393 | 394 | :root[sizemode="fullscreen"] #tabbrowser-tabpanels { 395 | margin-bottom: 0 !important; 396 | } 397 | 398 | #sidebar-box { 399 | margin-bottom: 23px !important; 400 | } 401 | 402 | #statuspanel::after { 403 | content: 'Internet'; 404 | display: block; 405 | position: fixed !important; 406 | right: 86px !important; 407 | bottom: 2px !important; 408 | padding-left: 20px !important; 409 | height: 16px; 410 | line-height: 16px; 411 | background-image: url('internet.png') !important; 412 | background-repeat: no-repeat; 413 | } 414 | 415 | #statuspanel::before { 416 | content: '' !important; 417 | display: inline-block; 418 | background-image: url('ie.png') !important; 419 | background-repeat: no-repeat; 420 | height: 16px; 421 | line-height: 17px; 422 | padding-left: 20px !important; 423 | margin-top: 1px !important; 424 | position: absolute; 425 | left: 2px !important; 426 | } 427 | 428 | #statuspanel[inactive]::before { 429 | content: 'Done' !important; 430 | width: 16px !important; 431 | } 432 | 433 | #statuspanel[inactive] #statuspanel-label::before { 434 | opacity: 0 !important; 435 | visibility: collapse !important; 436 | } 437 | 438 | #statuspanel-label { 439 | background-color: transparent !important; 440 | border: 0 !important; 441 | padding: 0 !important; 442 | margin-inline: 0 !important; 443 | height: 22px !important; 444 | width: calc(100% - 138px) !important; 445 | appearance: statusbarpanel !important; 446 | margin-top: 8px !important; 447 | margin-left: 6px !important; 448 | color: #000000 !important; 449 | } 450 | 451 | :root[sizemode="fullscreen"] .browserStack > browser { 452 | padding: 0 !important; 453 | box-shadow: none !important; 454 | } 455 | 456 | #back-button, 457 | #forward-button, 458 | #stop-button, 459 | #reload-button, 460 | #home-button, 461 | #downloads-button, 462 | #history-panelmenu, 463 | #bookmarks-menu-button, 464 | #print-button, 465 | #new-window-button, 466 | #cut-button, 467 | #copy-button, 468 | #paste-button, 469 | #fullscreen-button, 470 | #find-button, 471 | #email-link-button, 472 | #sidebar-button, 473 | #unified-extensions-button, 474 | #fxa-toolbar-menu-button{ 475 | width: 38px !important; 476 | list-style-image: none !important; 477 | -moz-context-properties: unset !important; 478 | fill: unset !important; 479 | opacity: unset !important; 480 | } 481 | 482 | #back-button > .toolbarbutton-icon, 483 | #forward-button > .toolbarbutton-icon, 484 | #reload-button > .toolbarbutton-icon, 485 | #stop-button > .toolbarbutton-icon, 486 | #home-button > .toolbarbutton-icon, 487 | #find-button > .toolbarbutton-icon, 488 | #bookmarks-menu-button > .toolbarbutton-icon, 489 | #history-panelmenu > .toolbarbutton-icon, 490 | #print-button > .toolbarbutton-icon, 491 | #copy-button > .toolbarbutton-icon, 492 | #cut-button > .toolbarbutton-icon, 493 | #paste-button > .toolbarbutton-icon, 494 | #downloads-button > .toolbarbutton-icon, 495 | #downloads-button > .toolbarbutton-badge-stack, 496 | #unified-extensions-button > .toolbarbutton-icon, 497 | #new-window-button > .toolbarbutton-icon, 498 | #fullscreen-button > .toolbarbutton-icon, 499 | #email-link-button > .toolbarbutton-icon, 500 | #sidebar-button > .toolbarbutton-icon, 501 | #fxa-toolbar-menu-button > .toolbarbutton-badge-stack{ 502 | padding: 0 !important; 503 | opacity: unset !important; 504 | width: 25px !important; 505 | list-style-image: url('list.png'); 506 | height: 25px !important; 507 | } 508 | 509 | #nav-bar .toolbarbutton-1 { 510 | min-height: 31px !important; 511 | } 512 | 513 | #nav-bar .toolbarbutton-1:active, 514 | #nav-bar .toolbarbutton-1[open="true"] { 515 | color: #ffffff !important; 516 | } 517 | 518 | .toolbarbutton-1:not(#activity_throbber) { 519 | border: 1px solid transparent; 520 | } 521 | 522 | toolbarbutton:where([disabled="true"]) { 523 | color: ThreeDShadow !important; 524 | text-shadow: 1px 1px 0 ThreeDHighlight; 525 | } 526 | 527 | #nav-bar #back-button:where([disabled="true"]), 528 | #nav-bar #forward-button:where([disabled="true"]) { 529 | border-color: transparent !important; 530 | filter: grayscale(1); 531 | } 532 | 533 | #nav-bar #back-button:where([disabled="true"]) .toolbarbutton-icon, 534 | #nav-bar #forward-button:where([disabled="true"]) .toolbarbutton-icon { 535 | opacity: 0.5 !important;; 536 | } 537 | 538 | toolbar:not(#nav-bar) .webextension-browser-action { 539 | padding: 0 4px !important; 540 | } 541 | 542 | #PersonalToolbar .toolbarbutton-1:not([disabled="true"]):is([open], [checked], :hover:active), #tabbrowser-arrowscrollbox:not([scrolledtostart="true"])::part(scrollbutton-up):hover:active, #tabbrowser-arrowscrollbox:not([scrolledtoend="true"])::part(scrollbutton-down):hover:active, toolbarbutton.bookmark-item:hover:active:not(.subviewbutton, [disabled="true"]), toolbarbutton.bookmark-item[open="true"], toolbar .toolbarbutton-1:not([disabled="true"]):is([open], [checked], :hover:active) > .toolbarbutton-icon, toolbar .toolbarbutton-1:not([disabled="true"]):is([open], [checked], :hover:active) > .toolbarbutton-text, toolbar .toolbarbutton-1:not([disabled="true"]):is([open], [checked], :hover:active) > .toolbarbutton-badge-stack { 543 | background: transparent !important; 544 | } 545 | 546 | #nav-bar .toolbarbutton-icon { 547 | margin-left: 3px !important; 548 | margin-right: 2px !important; 549 | } 550 | 551 | #nav-bar #back-button[disabled="true"] > *, 552 | #nav-bar #forward-button[disabled="true"] > * { 553 | transform: none !important; 554 | } 555 | 556 | #nav-bar #back-button[disabled="true"] .toolbarbutton-text { 557 | text-shadow: 1px 1px 0 ThreeDHighlight !important; 558 | } 559 | 560 | 561 | #nav-bar .toolbarbutton-1:not(#back-button[disabled="true"]):not(#forward-button[disabled="true"]):hover .toolbarbutton-icon, 562 | #nav-bar .toolbarbutton-1:not(#back-button[disabled="true"]):not(#forward-button[disabled="true"]):active .toolbarbutton-icon, 563 | #nav-bar .toolbarbutton-1:not(#back-button[disabled="true"]):not(#forward-button[disabled="true"])[open="true"] .toolbarbutton-icon { 564 | filter: none !important; 565 | } 566 | 567 | #nav-bar-customization-target > :is(toolbarbutton, toolbaritem):first-child, #nav-bar-customization-target > toolbarpaletteitem:first-child > :is(toolbarbutton, toolbaritem) { 568 | padding-inline-start: 0 !important; 569 | } 570 | 571 | #nav-bar { 572 | height: 40px; 573 | padding-left: 2px !important; 574 | } 575 | 576 | #nav-bar .toolbarbutton-1 .toolbarbutton-text { 577 | padding-left: 3px !important; 578 | padding-top: 0 !important; 579 | padding-bottom: 0 !important; 580 | min-height: unset !important; 581 | } 582 | 583 | #nav-bar .toolbarbutton-1 > .toolbarbutton-icon, #nav-bar .toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbarbutton-icon { 584 | width: 25px !important; 585 | height: 25px !important; 586 | } 587 | 588 | #nav-bar .toolbarbutton-1 > .toolbarbutton-badge-stack { 589 | padding: 0 !important; 590 | } 591 | 592 | #nav-bar .toolbarbutton-1 { 593 | height: 100% !important; 594 | } 595 | 596 | #back-button { 597 | -moz-image-region: rect(0px 25px 25px 0px) !important; 598 | } 599 | 600 | #forward-button { 601 | -moz-image-region: rect(0px 50px 25px 25px) !important; 602 | } 603 | 604 | #reload-button { 605 | -moz-image-region: rect(0px 75px 25px 50px) !important; 606 | } 607 | 608 | #stop-button { 609 | -moz-image-region: rect(0px 100px 25px 75px) !important; 610 | } 611 | 612 | #home-button { 613 | -moz-image-region: rect(0px 125px 25px 100px) !important; 614 | } 615 | 616 | #find-button { 617 | -moz-image-region: rect(0px 150px 25px 125px) !important; 618 | } 619 | 620 | #bookmarks-menu-button { 621 | -moz-image-region: rect(0px 175px 25px 150px) !important; 622 | } 623 | 624 | #history-panelmenu { 625 | -moz-image-region: rect(0px 200px 25px 175px) !important; 626 | } 627 | 628 | #downloads-button { 629 | width: 38px !important; 630 | -moz-image-region: rect(0px 325px 25px 300px) !important; 631 | } 632 | 633 | #print-button { 634 | -moz-image-region: rect(0px 225px 25px 200px) !important; 635 | } 636 | 637 | #email-link-button { 638 | -moz-image-region: rect(0px 375px 25px 350px) !important; 639 | } 640 | 641 | #cut-button { 642 | -moz-image-region: rect(0px 275px 25px 250px) !important; 643 | } 644 | 645 | #copy-button { 646 | -moz-image-region: rect(0px 250px 25px 225px) !important; 647 | } 648 | 649 | #paste-button { 650 | -moz-image-region: rect(0px 300px 25px 275px) !important; 651 | } 652 | 653 | #sidebar-button { 654 | -moz-image-region: rect(0px 224px 16px 208px) !important; 655 | } 656 | 657 | #fullscreen-button { 658 | -moz-image-region: rect(0px 400px 25px 375px) !important; 659 | } 660 | 661 | #new-window-button { 662 | -moz-image-region: rect(0px 272px 16px 256px) !important; 663 | } 664 | 665 | #unified-extensions-button { 666 | -moz-image-region: rect(0px 350px 25px 325px) !important; 667 | } 668 | 669 | #fxa-toolbar-menu-button { 670 | width: unset !important; 671 | padding-left: 3px !important; 672 | -moz-image-region: rect(0px 428px 25px 403px) !important; 673 | } 674 | 675 | #fxa-toolbar-menu-button::after { 676 | color: black; 677 | content: 'Personal'; 678 | padding-right: 5px !important; 679 | padding-left: 3px !important; 680 | } 681 | 682 | #fxa-toolbar-menu-button::before { 683 | content: ''; 684 | padding-right: 5px !important; 685 | -moz-box-ordinal-group: 2 !important; 686 | background-image: url('alltabs.png') !important; 687 | background-repeat: no-repeat; 688 | display: inline-block; 689 | width: 5px; 690 | height: 3px; 691 | margin-top: 2px !important; 692 | } 693 | 694 | #edit-controls { 695 | margin: 0 !important; 696 | display: flex; 697 | } 698 | 699 | #edit-controls separator { 700 | display: none !important; 701 | } 702 | 703 | #edit-controls .toolbarbutton-1 { 704 | width: 33px !important; 705 | height: 100% !important; 706 | } 707 | 708 | #downloads-button .toolbarbutton-animatable-box { 709 | display: none !important; 710 | } 711 | 712 | #downloads-button[indicator] > .toolbarbutton-badge-stack > image.toolbarbutton-icon { 713 | display: unset !important; 714 | } 715 | 716 | #downloads-button .toolbarbutton-badge-stack > .toolbarbutton-icon { 717 | margin: 0 !important; 718 | } 719 | 720 | #favimginurlbar { 721 | margin: 2px !important; 722 | } 723 | 724 | #identity-box { 725 | margin-inline-end: 2px !important; 726 | } 727 | 728 | #urlbar[breakout][breakout-extend] #favimginurlbar { 729 | margin-top: 3px !important; 730 | margin-left: 3px !important; 731 | } 732 | 733 | .tab-label-container { 734 | height: 15px !important; 735 | } 736 | 737 | .tab-label { 738 | line-height: 0 !important; 739 | } 740 | 741 | .tab-icon-sound-label { 742 | display: none !important; 743 | } 744 | 745 | #tabs-newtab-button .toolbarbutton-icon { 746 | width: 16px !important; 747 | height: 16px !important; 748 | padding: 0 !important; 749 | } 750 | 751 | .tab-close-button { 752 | width: 16px !important; 753 | height: 16px !important; 754 | padding: 0 !important; 755 | display: none !important; 756 | } 757 | 758 | .tab-content { 759 | padding: 0 2px !important; 760 | } 761 | 762 | .tab-icon-image { 763 | margin-inline-end: 2px !important; 764 | } 765 | 766 | #TabsToolbar .toolbarbutton-1 { 767 | margin: 0 !important; 768 | } 769 | 770 | #tabs-newtab-button .toolbarbutton-icon { 771 | border-radius: 0 !important; 772 | } 773 | 774 | .tabbrowser-tab:not([visuallyselected="true"]) { 775 | margin-top: 4px !important; 776 | } 777 | 778 | #tabs-newtab-button { 779 | list-style-image: url('newtab.png') !important; 780 | padding: 0 !important; 781 | } 782 | 783 | #tabbrowser-tabs[haspinnedtabs]:not([positionpinnedtabs]) > #tabbrowser-arrowscrollbox > .tabbrowser-tab[first-visible-unpinned-tab] { 784 | margin-inline-start: 0 !important; 785 | } 786 | 787 | #context-navigation { 788 | -moz-box-orient: vertical !important; 789 | } 790 | 791 | #context-navigation menuitem { 792 | -moz-box-pack: end !important; 793 | -moz-box-direction: reverse !important; 794 | list-style-image: none !important; 795 | } 796 | 797 | #context-navigation .menu-iconic-icon { 798 | width: 16px !important; 799 | margin: 0 !important; 800 | margin-right: 8px !important; 801 | margin-left: 5px !important; 802 | } 803 | 804 | #context-navigation menuitem::before { 805 | content: attr(aria-label); 806 | margin-left: -11px !important; 807 | } 808 | 809 | menupopup { 810 | appearance: none !important; 811 | padding: 1px !important; 812 | } 813 | 814 | menuseparator { 815 | appearance: none !important; 816 | padding: 0 !important; 817 | margin-block: 2px !important; 818 | } 819 | 820 | menuitem { 821 | appearance: none !important; 822 | height: 17px !important; 823 | } 824 | 825 | .menu-text { 826 | appearance: none !important; 827 | } 828 | 829 | .menuitem-iconic > .menu-iconic-left { 830 | appearance: none !important; 831 | padding-top: 0 !important; 832 | } 833 | 834 | /* 835 | menuitem:is([type="checkbox"], [checked="true"]) > .menu-iconic-left { 836 | background-image: url('checkmark.png') !important; 837 | appearance: none !important; 838 | }*/ 839 | 840 | menuitem[type="radio"][checked="true"] > .menu-iconic-left { 841 | background-image: url('radio.png') !important; 842 | } 843 | 844 | menuitem:is([type="checkbox"], [checked="true"], [type="radio"]) > .menu-iconic-left > .menu-iconic-icon { 845 | display: -moz-Box !important; 846 | } 847 | 848 | .menu-right { 849 | appearance: none !important; 850 | -moz-default-appearance: none !important; 851 | height: 17px !important; 852 | } 853 | 854 | /* 855 | .menu-right image { 856 | width: 16px !important; 857 | height: 16px !important; 858 | background-image: url('arrow.png') !important; 859 | }*/ 860 | 861 | menu { 862 | appearance: none !important; 863 | } 864 | 865 | menuitem[type="radio"] > .menu-iconic-left { 866 | appearance: none !important; 867 | } 868 | 869 | toolbarpaletteitem[place="toolbar"][id^="wrapper-customizableui-special-spring"], toolbarspring { 870 | width: 100% !important; 871 | max-width: 100% !important; 872 | } 873 | 874 | toolbarpaletteitem[removable="false"] { 875 | opacity: 1 !important; 876 | } 877 | 878 | #personal-toolbar-empty-description, toolbarbutton.bookmark-item:not(.subviewbutton) { 879 | height: 22px !important; 880 | margin: 0 !important; 881 | } 882 | 883 | #PersonalToolbar { 884 | padding-inline: 0 !important; 885 | } 886 | 887 | #PersonalToolbar::after { 888 | -moz-box-ordinal-group: 0 !important; 889 | line-height: 26px !important; 890 | color: scrollbar !important; 891 | margin-inline: 5px !important; 892 | } 893 | 894 | .tabbrowser-tab[visuallyselected="true"] { 895 | font-weight: bold; 896 | } 897 | 898 | .searchbar-textbox { 899 | margin-block: 4px !important; 900 | } 901 | 902 | #sidebar-header { 903 | appearance: toolbox !important; 904 | font-size: 8pt !important; 905 | padding: 0 6px !important; 906 | height: 23px !important; 907 | box-shadow: inset 0 -1px 0 ThreeDDarkShadow !important; 908 | } 909 | 910 | .sidebar-splitter { 911 | margin-inline-start: 0 !important; 912 | } 913 | 914 | #sidebar-close { 915 | background-color: transparent !important; 916 | border-radius: 0 !important; 917 | list-style-image: url('close.png') !important; 918 | width: 8px !important; 919 | height: 7px !important; 920 | padding: 0 !important; 921 | margin-top: -4px !important; 922 | } 923 | 924 | #sidebar-box { 925 | z-index: 1 !important; 926 | background-color: #F1F2EE !important; 927 | border-top: 1px solid #E0E2E8 !important; 928 | } 929 | 930 | .sidebar-placesTree { 931 | margin: 6px !important; 932 | border: 1px solid #85878C !important; 933 | background-color: #FFFFFF !important; 934 | } 935 | 936 | #sidebar-switcher-target { 937 | padding: 0 !important; 938 | padding-inline: 0 !important; 939 | background-color: transparent !important; 940 | } 941 | 942 | #sidebar-title { 943 | padding-inline: 0 !important; 944 | } 945 | 946 | #sidebar-switcher-arrow { 947 | list-style-image: none !important; 948 | background-position: center center !important; 949 | background-repeat: no-repeat !important; 950 | background-image: url('alltabs.png') !important; 951 | width: 12px !important; 952 | background-color: #DFDEE2 !important; 953 | height: 100% !important; 954 | opacity: 1 !important; 955 | box-shadow: inset 1px 0 0 #FFFFFF, inset 0 1px 0.5px #D2D1D3, inset 0 -1px 0.5px rgb(255 255 255 / 20%) !important; 956 | } 957 | 958 | #sidebar-box { 959 | margin-bottom: 23px !important; 960 | } 961 | 962 | #sidebar-search-container { 963 | border-bottom: 2px solid -moz-Dialog !important; 964 | } 965 | 966 | #sidebar-search-container::before { 967 | content: 'Search for:'; 968 | display: block; 969 | margin-bottom: 7px !important; 970 | font-family: 'MS Sans Serif' !important; 971 | } 972 | 973 | #sidebar-search-container { 974 | display: flex; 975 | flex-direction: column; 976 | padding: 11px 6px !important; 977 | } 978 | 979 | #sidebar-icon, #sidebar-switcher-arrow { 980 | display: none !important; 981 | } 982 | 983 | #search-box { 984 | font-family: 'MS Sans Serif' !important; 985 | height: 23px !important; 986 | } 987 | 988 | .textbox-search-sign { 989 | display: none !important; 990 | } 991 | 992 | #viewButton { 993 | width: 75px !important; 994 | margin-inline-start : 0 !important; 995 | appearance: button !important; 996 | margin-top: 6px !important; 997 | position: relative !important; 998 | } 999 | 1000 | #viewButton > .button-box > .button-menu-dropmarker { 1001 | display: none !important; 1002 | } 1003 | 1004 | #urlbar-input::placeholder, .searchbar-textbox::placeholder { 1005 | opacity: 1 !important; 1006 | color: #B4B4B4 !important; 1007 | } 1008 | 1009 | .searchbar-textbox { 1010 | margin-block: 4px !important; 1011 | } 1012 | 1013 | #PanelUI-menu-button { 1014 | min-width: 0 !important; 1015 | } 1016 | 1017 | #page-action-buttons::after { 1018 | content: ''; 1019 | display: inline-block; 1020 | height: calc(100% - 1px) !important; 1021 | appearance: spinner-downbutton; 1022 | } 1023 | 1024 | #page-action-buttons { 1025 | position: relative; 1026 | } 1027 | 1028 | #page-action-buttons::before { 1029 | content: ''; 1030 | width: 9px; 1031 | height: 6px; 1032 | position: absolute; 1033 | top: 7px; 1034 | right: 3px; 1035 | background-image: url('spinnerdown.png'); 1036 | z-index: 999; 1037 | } 1038 | 1039 | #reload-button:not([displaystop]) { 1040 | display: -moz-Box !important; 1041 | } 1042 | 1043 | #stop-button { 1044 | -moz-box-ordinal-group: 0 !important; 1045 | } 1046 | 1047 | #favimginurlbar[style='width: 16px; height: 16px; margin: 3px; list-style-image: url("chrome://branding/content/icon32.png");'] { 1048 | list-style-image: url('ie.png') !important; 1049 | } 1050 | 1051 | #favimginurlbar[style='width: 16px; height: 16px; margin: 3px; list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABgUExURYaGhv///5mZmVVVVf/78ABmzDMzMwAAgDNm//Hx8czMzHd3d2aZmZnMzDMzzGb//+rq6pmZZv//mQDM/+fn1v/MmcyZZjNmzF9fXwAzmcDAwABmmYCAADMzZgQEBAAAANSdJEsAAAAgdFJOU/////////////////////////////////////////8AXFwb7QAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAIpJREFUKFNNjFsWgyAMREUIRGhTbOlLW7P/XRoD2t6Tj8w9k3TM3O3IzipMpbeHcEpvxOwCwDnrvVcRQHA4xD7ZTYTTmegCg8tRvnQcxqvU6QZDLnET6Y7bCUAuKtLjidKQg1Ibr/GNOE2Ec2t86EsoSG4/iJdlnjVXwZRMliDTBKd40IT9oeIP5hU1fA8vue4FsgAAAABJRU5ErkJggg==");'] { 1052 | list-style-image: url('ie.png') !important; 1053 | } 1054 | 1055 | .tab-icon-image[src="chrome://branding/content/icon32.png"] { 1056 | content: url('ie.png') !important; 1057 | } 1058 | 1059 | .tab-icon-image[src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABgUExURYaGhv///5mZmVVVVf/78ABmzDMzMwAAgDNm//Hx8czMzHd3d2aZmZnMzDMzzGb//+rq6pmZZv//mQDM/+fn1v/MmcyZZjNmzF9fXwAzmcDAwABmmYCAADMzZgQEBAAAANSdJEsAAAAgdFJOU/////////////////////////////////////////8AXFwb7QAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAIpJREFUKFNNjFsWgyAMREUIRGhTbOlLW7P/XRoD2t6Tj8w9k3TM3O3IzipMpbeHcEpvxOwCwDnrvVcRQHA4xD7ZTYTTmegCg8tRvnQcxqvU6QZDLnET6Y7bCUAuKtLjidKQg1Ibr/GNOE2Ec2t86EsoSG4/iJdlnjVXwZRMliDTBKd40IT9oeIP5hU1fA8vue4FsgAAAABJRU5ErkJggg=="] { 1060 | content: url('ie.png') !important; 1061 | } 1062 | 1063 | #urlbar[breakout][breakout-extend] #page-action-buttons { 1064 | display: none !important; 1065 | } 1066 | 1067 | menu[_moz-menuactive="true"] { 1068 | background-color: Highlight !important; 1069 | color: HighlightText !important; 1070 | } 1071 | 1072 | .menu-iconic > .menu-iconic-left, .menuitem-iconic > .menu-iconic-left { 1073 | appearance: none !important; 1074 | } 1075 | 1076 | toolbarbutton menupopup[placespopup] > :is(menu, menuitem):not([disabled])[_moz-menuactive] { 1077 | color: HighlightText !important; 1078 | } 1079 | 1080 | toolbarbutton menupopup[placespopup] > :is(menu, menuitem) > .menu-accel-container > :is(.menu-accel, .menu-iconic-accel) { 1081 | color: inherit !important; 1082 | padding-inline-end: 16px !important; 1083 | } 1084 | 1085 | toolbarbutton menupopup[placespopup] > :is(.menu-iconic, .menuitem-iconic) > .menu-iconic-left { 1086 | margin-inline-end: 2px !important; 1087 | } 1088 | 1089 | toolbarbutton menupopup[placespopup] > menu > .menu-right { 1090 | list-style-image: none !important; 1091 | } 1092 | 1093 | toolbarbutton menupopup[placespopup] .menu-text { 1094 | margin-left: 18px !important; 1095 | } 1096 | 1097 | toolbarbutton menupopup[placespopup] menuseparator { 1098 | margin: 3px 0 5px 0 !important; 1099 | } 1100 | 1101 | toolbarbutton menupopup[placespopup] { 1102 | --panel-shadow: 2px 2px 2px rgb(0 0 0 / 50%) !important; 1103 | } 1104 | 1105 | #userScriptsMenu { 1106 | display: none !important; 1107 | } 1108 | 1109 | #searchFilter { 1110 | appearance: listbox !important; 1111 | } 1112 | 1113 | #statuspanel-label::after { 1114 | content: ''; 1115 | appearance: resizer; 1116 | position: absolute; 1117 | right: 0; 1118 | bottom: 0; 1119 | } 1120 | 1121 | #statuspanel[inactive="true"] #statuspanel-label::before { 1122 | display: none !important; 1123 | } 1124 | 1125 | #statuspanel-label::before { 1126 | margin-left: 5px; 1127 | margin-top: 3px; 1128 | } 1129 | 1130 | findbar { 1131 | transition: none !important; 1132 | background-color: -moz-Dialog !important; 1133 | border-top: 0 !important; 1134 | } 1135 | 1136 | #tabbrowser-tabpanels { 1137 | margin-bottom: 22px !important; 1138 | } 1139 | 1140 | #main-window[privatebrowsingmode=temporary] label 1141 | { 1142 | color: black; 1143 | } 1144 | 1145 | #main-window[privatebrowsingmode=temporary] menu-text 1146 | { 1147 | color: white; 1148 | } 1149 | 1150 | #main-window[privatebrowsingmode=temporary] #fxa-toolbar-menu-button::after, #main-window[privatebrowsingmode=temporary] content, #main-window[privatebrowsingmode=temporary] #statuspanel 1151 | { 1152 | color: black; 1153 | } 1154 | 1155 | #main-window[privatebrowsingmode=temporary] #fxa-toolbar-menu-button:enabled 1156 | { 1157 | color: white; 1158 | } -------------------------------------------------------------------------------- /profile/chrome/utils/BootstrapLoader.jsm: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | 'use strict'; 6 | 7 | let EXPORTED_SYMBOLS = []; 8 | 9 | const { XPCOMUtils } = ChromeUtils.import('resource://gre/modules/XPCOMUtils.jsm'); 10 | 11 | XPCOMUtils.defineLazyModuleGetters(this, { 12 | Blocklist: 'resource://gre/modules/Blocklist.jsm', 13 | ConsoleAPI: 'resource://gre/modules/Console.jsm', 14 | InstallRDF: 'chrome://userchromejs/content/RDFManifestConverter.jsm', 15 | Services: 'resource://gre/modules/Services.jsm', 16 | }); 17 | 18 | // signing bypass by onemen 19 | const Constants = ChromeUtils.import('resource://gre/modules/AppConstants.jsm'); 20 | const temp = Object.assign({}, Constants.AppConstants); 21 | temp.MOZ_REQUIRE_SIGNING = false 22 | Constants.AppConstants = Object.freeze(temp); 23 | 24 | Services.obs.addObserver(doc => { 25 | if (doc.location.protocol + doc.location.pathname === 'about:addons' || 26 | doc.location.protocol + doc.location.pathname === 'chrome:/content/extensions/aboutaddons.html') { 27 | const win = doc.defaultView; 28 | let handleEvent_orig = win.customElements.get('addon-card').prototype.handleEvent; 29 | win.customElements.get('addon-card').prototype.handleEvent = function (e) { 30 | if (e.type === 'click' && 31 | e.target.getAttribute('action') === 'preferences' && 32 | this.addon.optionsType == 1/*AddonManager.OPTIONS_TYPE_DIALOG*/) { 33 | var windows = Services.wm.getEnumerator(null); 34 | while (windows.hasMoreElements()) { 35 | var win2 = windows.getNext(); 36 | if (win2.closed) { 37 | continue; 38 | } 39 | if (win2.document.documentURI == this.addon.optionsURL) { 40 | win2.focus(); 41 | return; 42 | } 43 | } 44 | var features = 'chrome,titlebar,toolbar,centerscreen'; 45 | win.docShell.rootTreeItem.domWindow.openDialog(this.addon.optionsURL, this.addon.id, features); 46 | } else { 47 | handleEvent_orig.apply(this, arguments); 48 | } 49 | } 50 | let update_orig = win.customElements.get('addon-options').prototype.update; 51 | win.customElements.get('addon-options').prototype.update = function (card, addon) { 52 | update_orig.apply(this, arguments); 53 | if (addon.optionsType == 1/*AddonManager.OPTIONS_TYPE_DIALOG*/) 54 | this.querySelector('panel-item[data-l10n-id="preferences-addon-button"]').hidden = false; 55 | } 56 | } 57 | }, 'chrome-document-loaded'); 58 | 59 | const {AddonManager} = ChromeUtils.import('resource://gre/modules/AddonManager.jsm'); 60 | const {XPIDatabase, AddonInternal} = ChromeUtils.import('resource://gre/modules/addons/XPIDatabase.jsm'); 61 | 62 | const { defineAddonWrapperProperty } = Cu.import('resource://gre/modules/addons/XPIDatabase.jsm'); 63 | defineAddonWrapperProperty('optionsType', function optionsType() { 64 | if (!this.isActive) { 65 | return null; 66 | } 67 | 68 | let addon = this.__AddonInternal__; 69 | let hasOptionsURL = !!this.optionsURL; 70 | 71 | if (addon.optionsType) { 72 | switch (parseInt(addon.optionsType, 10)) { 73 | case 1/*AddonManager.OPTIONS_TYPE_DIALOG*/: 74 | case AddonManager.OPTIONS_TYPE_TAB: 75 | case AddonManager.OPTIONS_TYPE_INLINE_BROWSER: 76 | return hasOptionsURL ? addon.optionsType : null; 77 | } 78 | return null; 79 | } 80 | 81 | return null; 82 | }); 83 | 84 | XPIDatabase.isDisabledLegacy = () => false; 85 | 86 | XPCOMUtils.defineLazyGetter(this, 'BOOTSTRAP_REASONS', () => { 87 | const {XPIProvider} = ChromeUtils.import('resource://gre/modules/addons/XPIProvider.jsm'); 88 | return XPIProvider.BOOTSTRAP_REASONS; 89 | }); 90 | 91 | const {Log} = ChromeUtils.import('resource://gre/modules/Log.jsm'); 92 | var logger = Log.repository.getLogger('addons.bootstrap'); 93 | 94 | /** 95 | * Valid IDs fit this pattern. 96 | */ 97 | var gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i; 98 | 99 | // Properties that exist in the install manifest 100 | const PROP_METADATA = ['id', 'version', 'type', 'internalName', 'updateURL', 101 | 'optionsURL', 'optionsType', 'aboutURL', 'iconURL']; 102 | const PROP_LOCALE_SINGLE = ['name', 'description', 'creator', 'homepageURL']; 103 | const PROP_LOCALE_MULTI = ['developers', 'translators', 'contributors']; 104 | 105 | // Map new string type identifiers to old style nsIUpdateItem types. 106 | // Retired values: 107 | // 32 = multipackage xpi file 108 | // 8 = locale 109 | // 256 = apiextension 110 | // 128 = experiment 111 | // theme = 4 112 | const TYPES = { 113 | extension: 2, 114 | dictionary: 64, 115 | }; 116 | 117 | const COMPATIBLE_BY_DEFAULT_TYPES = { 118 | extension: true, 119 | dictionary: true, 120 | }; 121 | 122 | const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); 123 | 124 | function isXPI(filename) { 125 | let ext = filename.slice(-4).toLowerCase(); 126 | return ext === '.xpi' || ext === '.zip'; 127 | } 128 | 129 | /** 130 | * Gets an nsIURI for a file within another file, either a directory or an XPI 131 | * file. If aFile is a directory then this will return a file: URI, if it is an 132 | * XPI file then it will return a jar: URI. 133 | * 134 | * @param {nsIFile} aFile 135 | * The file containing the resources, must be either a directory or an 136 | * XPI file 137 | * @param {string} aPath 138 | * The path to find the resource at, '/' separated. If aPath is empty 139 | * then the uri to the root of the contained files will be returned 140 | * @returns {nsIURI} 141 | * An nsIURI pointing at the resource 142 | */ 143 | function getURIForResourceInFile(aFile, aPath) { 144 | if (!isXPI(aFile.leafName)) { 145 | let resource = aFile.clone(); 146 | if (aPath) 147 | aPath.split('/').forEach(part => resource.append(part)); 148 | 149 | return Services.io.newFileURI(resource); 150 | } 151 | 152 | return buildJarURI(aFile, aPath); 153 | } 154 | 155 | /** 156 | * Creates a jar: URI for a file inside a ZIP file. 157 | * 158 | * @param {nsIFile} aJarfile 159 | * The ZIP file as an nsIFile 160 | * @param {string} aPath 161 | * The path inside the ZIP file 162 | * @returns {nsIURI} 163 | * An nsIURI for the file 164 | */ 165 | function buildJarURI(aJarfile, aPath) { 166 | let uri = Services.io.newFileURI(aJarfile); 167 | uri = 'jar:' + uri.spec + '!/' + aPath; 168 | return Services.io.newURI(uri); 169 | } 170 | 171 | var BootstrapLoader = { 172 | name: 'bootstrap', 173 | manifestFile: 'install.rdf', 174 | async loadManifest(pkg) { 175 | /** 176 | * Reads locale properties from either the main install manifest root or 177 | * an em:localized section in the install manifest. 178 | * 179 | * @param {Object} aSource 180 | * The resource to read the properties from. 181 | * @param {boolean} isDefault 182 | * True if the locale is to be read from the main install manifest 183 | * root 184 | * @param {string[]} aSeenLocales 185 | * An array of locale names already seen for this install manifest. 186 | * Any locale names seen as a part of this function will be added to 187 | * this array 188 | * @returns {Object} 189 | * an object containing the locale properties 190 | */ 191 | function readLocale(aSource, isDefault, aSeenLocales) { 192 | let locale = {}; 193 | if (!isDefault) { 194 | locale.locales = []; 195 | for (let localeName of aSource.locales || []) { 196 | if (!localeName) { 197 | logger.warn('Ignoring empty locale in localized properties'); 198 | continue; 199 | } 200 | if (aSeenLocales.includes(localeName)) { 201 | logger.warn('Ignoring duplicate locale in localized properties'); 202 | continue; 203 | } 204 | aSeenLocales.push(localeName); 205 | locale.locales.push(localeName); 206 | } 207 | 208 | if (locale.locales.length == 0) { 209 | logger.warn('Ignoring localized properties with no listed locales'); 210 | return null; 211 | } 212 | } 213 | 214 | for (let prop of [...PROP_LOCALE_SINGLE, ...PROP_LOCALE_MULTI]) { 215 | if (hasOwnProperty(aSource, prop)) { 216 | locale[prop] = aSource[prop]; 217 | } 218 | } 219 | 220 | return locale; 221 | } 222 | 223 | let manifestData = await pkg.readString('install.rdf'); 224 | let manifest = InstallRDF.loadFromString(manifestData).decode(); 225 | 226 | let addon = new AddonInternal(); 227 | for (let prop of PROP_METADATA) { 228 | if (hasOwnProperty(manifest, prop)) { 229 | addon[prop] = manifest[prop]; 230 | } 231 | } 232 | 233 | if (!addon.type) { 234 | addon.type = 'extension'; 235 | } else { 236 | let type = addon.type; 237 | addon.type = null; 238 | for (let name in TYPES) { 239 | if (TYPES[name] == type) { 240 | addon.type = name; 241 | break; 242 | } 243 | } 244 | } 245 | 246 | if (!(addon.type in TYPES)) 247 | throw new Error('Install manifest specifies unknown type: ' + addon.type); 248 | 249 | if (!addon.id) 250 | throw new Error('No ID in install manifest'); 251 | if (!gIDTest.test(addon.id)) 252 | throw new Error('Illegal add-on ID ' + addon.id); 253 | if (!addon.version) 254 | throw new Error('No version in install manifest'); 255 | 256 | addon.strictCompatibility = (!(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) || 257 | manifest.strictCompatibility == 'true'); 258 | 259 | // Only read these properties for extensions. 260 | if (addon.type == 'extension') { 261 | if (manifest.bootstrap != 'true') { 262 | throw new Error('Non-restartless extensions no longer supported'); 263 | } 264 | 265 | if (addon.optionsType && 266 | addon.optionsType != 1/*AddonManager.OPTIONS_TYPE_DIALOG*/ && 267 | addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE_BROWSER && 268 | addon.optionsType != AddonManager.OPTIONS_TYPE_TAB) { 269 | throw new Error('Install manifest specifies unknown optionsType: ' + addon.optionsType); 270 | } 271 | 272 | if (addon.optionsType) 273 | addon.optionsType = parseInt(addon.optionsType); 274 | } 275 | 276 | addon.defaultLocale = readLocale(manifest, true); 277 | 278 | let seenLocales = []; 279 | addon.locales = []; 280 | for (let localeData of manifest.localized || []) { 281 | let locale = readLocale(localeData, false, seenLocales); 282 | if (locale) 283 | addon.locales.push(locale); 284 | } 285 | 286 | let dependencies = new Set(manifest.dependencies); 287 | addon.dependencies = Object.freeze(Array.from(dependencies)); 288 | 289 | let seenApplications = []; 290 | addon.targetApplications = []; 291 | for (let targetApp of manifest.targetApplications || []) { 292 | if (!targetApp.id || !targetApp.minVersion || 293 | !targetApp.maxVersion) { 294 | logger.warn('Ignoring invalid targetApplication entry in install manifest'); 295 | continue; 296 | } 297 | if (seenApplications.includes(targetApp.id)) { 298 | logger.warn('Ignoring duplicate targetApplication entry for ' + targetApp.id + 299 | ' in install manifest'); 300 | continue; 301 | } 302 | seenApplications.push(targetApp.id); 303 | addon.targetApplications.push(targetApp); 304 | } 305 | 306 | // Note that we don't need to check for duplicate targetPlatform entries since 307 | // the RDF service coalesces them for us. 308 | addon.targetPlatforms = []; 309 | for (let targetPlatform of manifest.targetPlatforms || []) { 310 | let platform = { 311 | os: null, 312 | abi: null, 313 | }; 314 | 315 | let pos = targetPlatform.indexOf('_'); 316 | if (pos != -1) { 317 | platform.os = targetPlatform.substring(0, pos); 318 | platform.abi = targetPlatform.substring(pos + 1); 319 | } else { 320 | platform.os = targetPlatform; 321 | } 322 | 323 | addon.targetPlatforms.push(platform); 324 | } 325 | 326 | addon.userDisabled = false; 327 | addon.softDisabled = addon.blocklistState == Blocklist.STATE_SOFTBLOCKED; 328 | addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT; 329 | 330 | addon.userPermissions = null; 331 | 332 | addon.icons = {}; 333 | if (await pkg.hasResource('icon.png')) { 334 | addon.icons[32] = 'icon.png'; 335 | addon.icons[48] = 'icon.png'; 336 | } 337 | 338 | if (await pkg.hasResource('icon64.png')) { 339 | addon.icons[64] = 'icon64.png'; 340 | } 341 | 342 | return addon; 343 | }, 344 | 345 | loadScope(addon) { 346 | let file = addon.file || addon._sourceBundle; 347 | let uri = getURIForResourceInFile(file, 'bootstrap.js').spec; 348 | let principal = Services.scriptSecurityManager.getSystemPrincipal(); 349 | 350 | let sandbox = new Cu.Sandbox(principal, { 351 | sandboxName: uri, 352 | addonId: addon.id, 353 | wantGlobalProperties: ['ChromeUtils'], 354 | metadata: { addonID: addon.id, URI: uri }, 355 | }); 356 | 357 | try { 358 | Object.assign(sandbox, BOOTSTRAP_REASONS); 359 | 360 | XPCOMUtils.defineLazyGetter(sandbox, 'console', () => 361 | new ConsoleAPI({ consoleID: `addon/${addon.id}` })); 362 | 363 | Services.scriptloader.loadSubScript(uri, sandbox); 364 | } catch (e) { 365 | logger.warn(`Error loading bootstrap.js for ${addon.id}`, e); 366 | } 367 | 368 | function findMethod(name) { 369 | if (sandbox[name]) { 370 | return sandbox[name]; 371 | } 372 | 373 | try { 374 | let method = Cu.evalInSandbox(name, sandbox); 375 | return method; 376 | } catch (err) { } 377 | 378 | return () => { 379 | logger.warn(`Add-on ${addon.id} is missing bootstrap method ${name}`); 380 | }; 381 | } 382 | 383 | let install = findMethod('install'); 384 | let uninstall = findMethod('uninstall'); 385 | let startup = findMethod('startup'); 386 | let shutdown = findMethod('shutdown'); 387 | 388 | return { 389 | install(...args) { 390 | install(...args); 391 | // Forget any cached files we might've had from this extension. 392 | Services.obs.notifyObservers(null, 'startupcache-invalidate'); 393 | }, 394 | 395 | uninstall(...args) { 396 | uninstall(...args); 397 | // Forget any cached files we might've had from this extension. 398 | Services.obs.notifyObservers(null, 'startupcache-invalidate'); 399 | }, 400 | 401 | startup(...args) { 402 | if (addon.type == 'extension') { 403 | logger.debug(`Registering manifest for ${file.path}\n`); 404 | Components.manager.addBootstrappedManifestLocation(file); 405 | } 406 | return startup(...args); 407 | }, 408 | 409 | shutdown(data, reason) { 410 | try { 411 | return shutdown(data, reason); 412 | } catch (err) { 413 | throw err; 414 | } finally { 415 | if (reason != BOOTSTRAP_REASONS.APP_SHUTDOWN) { 416 | logger.debug(`Removing manifest for ${file.path}\n`); 417 | Components.manager.removeBootstrappedManifestLocation(file); 418 | } 419 | } 420 | }, 421 | }; 422 | }, 423 | }; 424 | 425 | AddonManager.addExternalExtensionLoader(BootstrapLoader); 426 | 427 | if (AddonManager.isReady) { 428 | AddonManager.getAllAddons().then(addons => { 429 | addons.forEach(addon => { 430 | if (addon.type == 'extension' && !addon.isWebExtension && !addon.userDisabled) { 431 | addon.reload(); 432 | }; 433 | }); 434 | }); 435 | } 436 | -------------------------------------------------------------------------------- /profile/chrome/utils/RDFDataSource.jsm: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | /** 6 | * This module creates a new API for accessing and modifying RDF graphs. The 7 | * goal is to be able to serialise the graph in a human readable form. Also 8 | * if the graph was originally loaded from an RDF/XML the serialisation should 9 | * closely match the original with any new data closely following the existing 10 | * layout. The output should always be compatible with Mozilla's RDF parser. 11 | * 12 | * This is all achieved by using a DOM Document to hold the current state of the 13 | * graph in XML form. This can be initially loaded and parsed from disk or 14 | * a blank document used for an empty graph. As assertions are added to the 15 | * graph, appropriate DOM nodes are added to the document to represent them 16 | * along with any necessary whitespace to properly layout the XML. 17 | * 18 | * In general the order of adding assertions to the graph will impact the form 19 | * the serialisation takes. If a resource is first added as the object of an 20 | * assertion then it will eventually be serialised inside the assertion's 21 | * property element. If a resource is first added as the subject of an assertion 22 | * then it will be serialised at the top level of the XML. 23 | */ 24 | 25 | const NS_XML = "http://www.w3.org/XML/1998/namespace"; 26 | const NS_XMLNS = "http://www.w3.org/2000/xmlns/"; 27 | const NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; 28 | const NS_NC = "http://home.netscape.com/NC-rdf#"; 29 | 30 | /* eslint prefer-template: 1 */ 31 | 32 | var EXPORTED_SYMBOLS = ["RDFLiteral", "RDFBlankNode", "RDFResource", "RDFDataSource"]; 33 | 34 | const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); 35 | 36 | XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser", "Element", "fetch"]); 37 | 38 | ChromeUtils.defineModuleGetter(this, "Services", 39 | "resource://gre/modules/Services.jsm"); 40 | 41 | function isElement(obj) { 42 | return Element.isInstance(obj); 43 | } 44 | function isText(obj) { 45 | return obj && typeof obj == "object" && ChromeUtils.getClassName(obj) == "Text"; 46 | } 47 | 48 | /** 49 | * Returns either an rdf namespaced attribute or an un-namespaced attribute 50 | * value. Returns null if neither exists, 51 | */ 52 | function getRDFAttribute(element, name) { 53 | if (element.hasAttributeNS(NS_RDF, name)) 54 | return element.getAttributeNS(NS_RDF, name); 55 | if (element.hasAttribute(name)) 56 | return element.getAttribute(name); 57 | return undefined; 58 | } 59 | 60 | /** 61 | * Represents an assertion in the datasource 62 | */ 63 | class RDFAssertion { 64 | constructor(subject, predicate, object) { 65 | // The subject on this assertion, an RDFSubject 66 | this._subject = subject; 67 | // The predicate, a string 68 | this._predicate = predicate; 69 | // The object, an RDFNode 70 | this._object = object; 71 | // The datasource this assertion exists in 72 | this._ds = this._subject._ds; 73 | // Marks that _DOMnode is the subject's element 74 | this._isSubjectElement = false; 75 | // The DOM node that represents this assertion. Could be a property element, 76 | // a property attribute or the subject's element for rdf:type 77 | this._DOMNode = null; 78 | } 79 | 80 | getPredicate() { 81 | return this._predicate; 82 | } 83 | 84 | getObject() { 85 | return this._object; 86 | } 87 | } 88 | 89 | class RDFNode { 90 | equals(rdfnode) { 91 | return (rdfnode.constructor === this.constructor && 92 | rdfnode._value == this._value); 93 | } 94 | } 95 | 96 | /** 97 | * A simple literal value 98 | */ 99 | class RDFLiteral extends RDFNode { 100 | constructor(value) { 101 | super(); 102 | this._value = value; 103 | } 104 | 105 | getValue() { 106 | return this._value; 107 | } 108 | } 109 | 110 | /** 111 | * This is an RDF node that can be a subject so a resource or a blank node 112 | */ 113 | class RDFSubject extends RDFNode { 114 | constructor(ds) { 115 | super(); 116 | // A lookup of the assertions with this as the subject. Keyed on predicate 117 | this._assertions = {}; 118 | // A lookup of the assertions with this as the object. Keyed on predicate 119 | this._backwards = {}; 120 | // The datasource this subject belongs to 121 | this._ds = ds; 122 | // The DOM elements in the document that represent this subject. Array of Element 123 | this._elements = []; 124 | } 125 | 126 | /** 127 | * Parses the given Element from the DOM document 128 | */ 129 | /* eslint-disable complexity */ 130 | _parseElement(element) { 131 | this._elements.push(element); 132 | 133 | // There might be an inferred rdf:type assertion in the element name 134 | if (element.namespaceURI != NS_RDF || 135 | element.localName != "Description") { 136 | var assertion = new RDFAssertion(this, RDF_R("type"), 137 | this._ds.getResource(element.namespaceURI + element.localName)); 138 | assertion._DOMnode = element; 139 | assertion._isSubjectElement = true; 140 | this._addAssertion(assertion); 141 | } 142 | 143 | // Certain attributes can be literal properties 144 | for (let attr of element.attributes) { 145 | if (attr.namespaceURI == NS_XML || attr.namespaceURI == NS_XMLNS || 146 | attr.nodeName == "xmlns") 147 | continue; 148 | if ((attr.namespaceURI == NS_RDF || !attr.namespaceURI) && 149 | (["nodeID", "about", "resource", "ID", "parseType"].includes(attr.localName))) 150 | continue; 151 | var object = null; 152 | if (attr.namespaceURI == NS_RDF) { 153 | if (attr.localName == "type") 154 | object = this._ds.getResource(attr.nodeValue); 155 | } 156 | if (!object) 157 | object = new RDFLiteral(attr.nodeValue); 158 | assertion = new RDFAssertion(this, attr.namespaceURI + attr.localName, object); 159 | assertion._DOMnode = attr; 160 | this._addAssertion(assertion); 161 | } 162 | 163 | var child = element.firstChild; 164 | element.listCounter = 1; 165 | while (child) { 166 | if (isElement(child)) { 167 | object = null; 168 | var predicate = child.namespaceURI + child.localName; 169 | if (child.namespaceURI == NS_RDF) { 170 | if (child.localName == "li") { 171 | predicate = RDF_R(`_${element.listCounter}`); 172 | element.listCounter++; 173 | } 174 | } 175 | 176 | // Check for and bail out on unknown attributes on the property element 177 | for (let attr of child.attributes) { 178 | // Ignore XML namespaced attributes 179 | if (attr.namespaceURI == NS_XML) 180 | continue; 181 | // These are reserved by XML for future use 182 | if (attr.localName.substring(0, 3).toLowerCase() == "xml") 183 | continue; 184 | // We can handle these RDF attributes 185 | if ((!attr.namespaceURI || attr.namespaceURI == NS_RDF) && 186 | ["resource", "nodeID"].includes(attr.localName)) 187 | continue; 188 | // This is a special attribute we handle for compatibility with Mozilla RDF 189 | if (attr.namespaceURI == NS_NC && 190 | attr.localName == "parseType") 191 | continue; 192 | } 193 | 194 | var parseType = child.getAttributeNS(NS_NC, "parseType"); 195 | 196 | var resource = getRDFAttribute(child, "resource"); 197 | var nodeID = getRDFAttribute(child, "nodeID"); 198 | 199 | if (resource !== undefined) { 200 | var base = Services.io.newURI(element.baseURI); 201 | object = this._ds.getResource(base.resolve(resource)); 202 | } else if (nodeID !== undefined) { 203 | object = this._ds.getBlankNode(nodeID); 204 | } else { 205 | var hasText = false; 206 | var childElement = null; 207 | var subchild = child.firstChild; 208 | while (subchild) { 209 | if (isText(subchild) && /\S/.test(subchild.nodeValue)) { 210 | hasText = true; 211 | } else if (isElement(subchild)) { 212 | childElement = subchild; 213 | } 214 | subchild = subchild.nextSibling; 215 | } 216 | 217 | if (childElement) { 218 | object = this._ds._getSubjectForElement(childElement); 219 | object._parseElement(childElement); 220 | } else 221 | object = new RDFLiteral(child.textContent); 222 | } 223 | 224 | assertion = new RDFAssertion(this, predicate, object); 225 | this._addAssertion(assertion); 226 | assertion._DOMnode = child; 227 | } 228 | child = child.nextSibling; 229 | } 230 | } 231 | /* eslint-enable complexity */ 232 | 233 | /** 234 | * Adds a new assertion to the internal hashes. Should be called for every 235 | * new assertion parsed or created programmatically. 236 | */ 237 | _addAssertion(assertion) { 238 | var predicate = assertion.getPredicate(); 239 | if (predicate in this._assertions) 240 | this._assertions[predicate].push(assertion); 241 | else 242 | this._assertions[predicate] = [ assertion ]; 243 | 244 | var object = assertion.getObject(); 245 | if (object instanceof RDFSubject) { 246 | // Create reverse assertion 247 | if (predicate in object._backwards) 248 | object._backwards[predicate].push(assertion); 249 | else 250 | object._backwards[predicate] = [ assertion ]; 251 | } 252 | } 253 | 254 | /** 255 | * Returns all objects in assertions with this subject and the given predicate. 256 | */ 257 | getObjects(predicate) { 258 | if (predicate in this._assertions) 259 | return Array.from(this._assertions[predicate], 260 | i => i.getObject()); 261 | 262 | return []; 263 | } 264 | 265 | /** 266 | * Retrieves the first property value for the given predicate. 267 | */ 268 | getProperty(predicate) { 269 | if (predicate in this._assertions) 270 | return this._assertions[predicate][0].getObject(); 271 | return null; 272 | } 273 | } 274 | 275 | /** 276 | * Creates a new RDFResource for the datasource. Private. 277 | */ 278 | class RDFResource extends RDFSubject { 279 | constructor(ds, uri) { 280 | super(ds); 281 | // This is the uri that the resource represents. 282 | this._uri = uri; 283 | } 284 | } 285 | 286 | /** 287 | * Creates a new blank node. Private. 288 | */ 289 | class RDFBlankNode extends RDFSubject { 290 | constructor(ds, nodeID) { 291 | super(ds); 292 | // The nodeID of this node. May be null if there is no ID. 293 | this._nodeID = nodeID; 294 | } 295 | 296 | /** 297 | * Sets attributes on the DOM element to mark it as representing this node 298 | */ 299 | _applyToElement(element) { 300 | if (!this._nodeID) 301 | return; 302 | if (USE_RDFNS_ATTR) { 303 | var prefix = this._ds._resolvePrefix(element, RDF_R("nodeID")); 304 | element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._nodeID); 305 | } else { 306 | element.setAttribute("nodeID", this._nodeID); 307 | } 308 | } 309 | 310 | /** 311 | * Creates a new Element in the document for holding assertions about this 312 | * subject. The URI controls what tagname to use. 313 | */ 314 | _createNewElement(uri) { 315 | // If there are already nodes representing this in the document then we need 316 | // a nodeID to match them 317 | if (!this._nodeID && this._elements.length > 0) { 318 | this._ds._createNodeID(this); 319 | for (let element of this._elements) 320 | this._applyToElement(element); 321 | } 322 | 323 | return super._createNewElement.call(uri); 324 | } 325 | 326 | /** 327 | * Adds a reference to this node to the given property Element. 328 | */ 329 | _addReferenceToElement(element) { 330 | if (this._elements.length > 0 && !this._nodeID) { 331 | // In document elsewhere already 332 | // Create a node ID and update the other nodes referencing 333 | this._ds._createNodeID(this); 334 | for (let element of this._elements) 335 | this._applyToElement(element); 336 | } 337 | 338 | if (this._nodeID) { 339 | if (USE_RDFNS_ATTR) { 340 | let prefix = this._ds._resolvePrefix(element, RDF_R("nodeID")); 341 | element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._nodeID); 342 | } else { 343 | element.setAttribute("nodeID", this._nodeID); 344 | } 345 | } else { 346 | // Add the empty blank node, this is generally right since further 347 | // assertions will be added to fill this out 348 | var newelement = this._ds._addElement(element, RDF_R("Description")); 349 | newelement.listCounter = 1; 350 | this._elements.push(newelement); 351 | } 352 | } 353 | 354 | /** 355 | * Removes any reference to this node from the given property Element. 356 | */ 357 | _removeReferenceFromElement(element) { 358 | if (element.hasAttributeNS(NS_RDF, "nodeID")) 359 | element.removeAttributeNS(NS_RDF, "nodeID"); 360 | if (element.hasAttribute("nodeID")) 361 | element.removeAttribute("nodeID"); 362 | } 363 | 364 | getNodeID() { 365 | return this._nodeID; 366 | } 367 | } 368 | 369 | /** 370 | * Creates a new RDFDataSource from the given document. The document will be 371 | * changed as assertions are added and removed to the RDF. Pass a null document 372 | * to start with an empty graph. 373 | */ 374 | class RDFDataSource { 375 | constructor(document) { 376 | // All known resources, indexed on URI 377 | this._resources = {}; 378 | // All blank nodes 379 | this._allBlankNodes = []; 380 | 381 | // The underlying DOM document for this datasource 382 | this._document = document; 383 | this._parseDocument(); 384 | } 385 | 386 | static loadFromString(text) { 387 | let parser = new DOMParser(); 388 | let document = parser.parseFromString(text, "application/xml"); 389 | 390 | return new this(document); 391 | } 392 | 393 | /** 394 | * Returns an rdf subject for the given DOM Element. If the subject has not 395 | * been seen before a new one is created. 396 | */ 397 | _getSubjectForElement(element) { 398 | var about = getRDFAttribute(element, "about"); 399 | 400 | if (about !== undefined) { 401 | let base = Services.io.newURI(element.baseURI); 402 | return this.getResource(base.resolve(about)); 403 | } 404 | return this.getBlankNode(null); 405 | } 406 | 407 | /** 408 | * Parses the document for subjects at the top level. 409 | */ 410 | _parseDocument() { 411 | var domnode = this._document.documentElement.firstChild; 412 | while (domnode) { 413 | if (isElement(domnode)) { 414 | var subject = this._getSubjectForElement(domnode); 415 | subject._parseElement(domnode); 416 | } 417 | domnode = domnode.nextSibling; 418 | } 419 | } 420 | 421 | /** 422 | * Gets a blank node. nodeID may be null and if so a new blank node is created. 423 | * If a nodeID is given then the blank node with that ID is returned or created. 424 | */ 425 | getBlankNode(nodeID) { 426 | var rdfnode = new RDFBlankNode(this, nodeID); 427 | this._allBlankNodes.push(rdfnode); 428 | return rdfnode; 429 | } 430 | 431 | /** 432 | * Gets the resource for the URI. The resource is created if it has not been 433 | * used already. 434 | */ 435 | getResource(uri) { 436 | if (uri in this._resources) 437 | return this._resources[uri]; 438 | 439 | var resource = new RDFResource(this, uri); 440 | this._resources[uri] = resource; 441 | return resource; 442 | } 443 | } 444 | -------------------------------------------------------------------------------- /profile/chrome/utils/RDFManifestConverter.jsm: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | "use strict"; 5 | 6 | var EXPORTED_SYMBOLS = ["InstallRDF"]; 7 | 8 | ChromeUtils.defineModuleGetter(this, "RDFDataSource", 9 | "chrome://userchromejs/content/RDFDataSource.jsm"); 10 | 11 | const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest"; 12 | 13 | function EM_R(aProperty) { 14 | return `http://www.mozilla.org/2004/em-rdf#${aProperty}`; 15 | } 16 | 17 | function getValue(literal) { 18 | return literal && literal.getValue(); 19 | } 20 | 21 | function getProperty(resource, property) { 22 | return getValue(resource.getProperty(EM_R(property))); 23 | } 24 | 25 | class Manifest { 26 | constructor(ds) { 27 | this.ds = ds; 28 | } 29 | 30 | static loadFromString(text) { 31 | return new this(RDFDataSource.loadFromString(text)); 32 | } 33 | } 34 | 35 | class InstallRDF extends Manifest { 36 | _readProps(source, obj, props) { 37 | for (let prop of props) { 38 | let val = getProperty(source, prop); 39 | if (val != null) { 40 | obj[prop] = val; 41 | } 42 | } 43 | } 44 | 45 | _readArrayProp(source, obj, prop, target, decode = getValue) { 46 | let result = Array.from(source.getObjects(EM_R(prop)), 47 | target => decode(target)); 48 | if (result.length) { 49 | obj[target] = result; 50 | } 51 | } 52 | 53 | _readArrayProps(source, obj, props, decode = getValue) { 54 | for (let [prop, target] of Object.entries(props)) { 55 | this._readArrayProp(source, obj, prop, target, decode); 56 | } 57 | } 58 | 59 | _readLocaleStrings(source, obj) { 60 | this._readProps(source, obj, ["name", "description", "creator", "homepageURL"]); 61 | this._readArrayProps(source, obj, { 62 | locale: "locales", 63 | developer: "developers", 64 | translator: "translators", 65 | contributor: "contributors", 66 | }); 67 | } 68 | 69 | decode() { 70 | let root = this.ds.getResource(RDFURI_INSTALL_MANIFEST_ROOT); 71 | let result = {}; 72 | 73 | let props = ["id", "version", "type", "updateURL", "optionsURL", 74 | "optionsType", "aboutURL", "iconURL", 75 | "bootstrap", "unpack", "strictCompatibility"]; 76 | this._readProps(root, result, props); 77 | 78 | let decodeTargetApplication = source => { 79 | let app = {}; 80 | this._readProps(source, app, ["id", "minVersion", "maxVersion"]); 81 | return app; 82 | }; 83 | 84 | let decodeLocale = source => { 85 | let localized = {}; 86 | this._readLocaleStrings(source, localized); 87 | return localized; 88 | }; 89 | 90 | this._readLocaleStrings(root, result); 91 | 92 | this._readArrayProps(root, result, {"targetPlatform": "targetPlatforms"}); 93 | this._readArrayProps(root, result, {"targetApplication": "targetApplications"}, 94 | decodeTargetApplication); 95 | this._readArrayProps(root, result, {"localized": "localized"}, 96 | decodeLocale); 97 | this._readArrayProps(root, result, {"dependency": "dependencies"}, 98 | source => getProperty(source, "id")); 99 | 100 | return result; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /profile/chrome/utils/aboutconfig/aboutconfig.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 22 | 23 |