diff --git a/JS/bookmarksMenuAndButtonShortcuts.uc.js b/JS/bookmarksMenuAndButtonShortcuts.uc.js index ecbd5d11..2bb25232 100644 --- a/JS/bookmarksMenuAndButtonShortcuts.uc.js +++ b/JS/bookmarksMenuAndButtonShortcuts.uc.js @@ -1,148 +1,149 @@ -// ==UserScript== -// @name Bookmarks Menu & Button Shortcuts -// @version 1.2.2 -// @author aminomancer -// @homepage https://github.com/aminomancer/uc.css.js -// @description Adds some shortcuts for bookmarking pages. First, middle-clicking the bookmarks or library toolbar button will bookmark the current tab, or un-bookmark it if it's already bookmarked. Second, a menu item is added to the bookmarks toolbar button's popup, which bookmarks the current tab, or, if the page is already bookmarked, opens the bookmark editor popup. These are added primarily so that bookmarks can be added or removed with a single click, and can still be quickly added even if the bookmark page action is hidden for whatever reason. Third, another menu item is added to replicate the "Search bookmarks" button in the app menu's bookmarks panel. Clicking it will open the urlbar in bookmarks search mode. -// @license This Source Code Form is subject to the terms of the Creative Commons Attribution-NonCommercial-ShareAlike International License, v. 4.0. If a copy of the CC BY-NC-SA 4.0 was not distributed with this file, You can obtain one at http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. -// ==/UserScript== - -const ucBookmarksShortcuts = { - create(aDoc, tag, props, isHTML = false) { - let el = isHTML ? aDoc.createElement(tag) : aDoc.createXULElement(tag); - for (let prop in props) el.setAttribute(prop, props[prop]); - return el; - }, - async bookmarkClick(e) { - if (e.button !== 1 || e.target.tagName !== "toolbarbutton") return; - let bm = await PlacesUtils.bookmarks.fetch({ url: new URL(BookmarkingUI._uri.spec) }); - bm ? PlacesTransactions.Remove(bm.guid).transact() : this.starCmd(); - e.preventDefault(); - e.stopPropagation(); - }, - async starCmd() { - if (!BookmarkingUI._pendingUpdate) { - if (!!BookmarkingUI.starAnimBox && !(BookmarkingUI._itemGuids.size > 0)) { - BrowserUIUtils.setToolbarButtonHeightProperty(BookmarkingUI.star); - document - .getElementById("star-button-animatable-box") - .addEventListener( - "animationend", - () => BookmarkingUI.star.removeAttribute("animate"), - { once: true } - ); - BookmarkingUI.star.setAttribute("animate", "true"); - } - let browser = gBrowser.selectedBrowser; - let url = new URL(browser.currentURI.spec); - let parentGuid = await PlacesUIUtils.defaultParentGuid; - let info = { url, parentGuid }; - let charset = null; - let isErrorPage = false; - if (browser.documentURI) - isErrorPage = /^about:(neterror|certerror|blocked)/.test(browser.documentURI.spec); - try { - if (isErrorPage) { - let entry = await PlacesUtils.history.fetch(browser.currentURI); - if (entry) info.title = entry.title; - } else info.title = browser.contentTitle; - info.title = info.title || url.href; - charset = browser.characterSet; - } catch (e) {} - info.guid = await PlacesTransactions.NewBookmark(info).transact(); - if (charset) PlacesUIUtils.setCharsetForPage(url, charset, window); - gURLBar.handleRevert(); - StarUI.showConfirmation(); - } - }, - addMenuitems(popup) { - let doc = popup.ownerDocument; - this.bookmarkTab = doc.createXULElement("menuitem"); - this.bookmarkTab = this.create(doc, "menuitem", { - id: "BMB_bookmarkThisPage", - label: "", - class: "menuitem-iconic subviewbutton", - onclick: "ucBookmarksShortcuts.updateMenuItem()", - oncommand: "BookmarkingUI.onStarCommand(event);", - key: "addBookmarkAsKb", - image: "chrome://browser/skin/bookmark-hollow.svg", - }); - popup.insertBefore(this.bookmarkTab, popup.firstElementChild); - popup.addEventListener("popupshowing", this.updateMenuItem, false); - this.bookmarkTab.ownerDocument.l10n.setAttributes( - this.bookmarkTab, - "bookmarks-current-tab" - ); - this.searchBookmarks = popup.querySelector("#BMB_viewBookmarksSidebar").after( - this.create(doc, "menuitem", { - id: "BMB_searchBookmarks", - class: "menuitem-iconic subviewbutton", - "data-l10n-id": "bookmarks-search", - oncommand: "PlacesCommandHook.searchBookmarks();", - image: "chrome://global/skin/icons/search-glass.svg", - }) - ); - }, - onLocationChange(browser, _prog, _req, location, _flags) { - if (browser !== gBrowser.selectedBrowser) return; - this.updateMenuItem(null, location); - }, - handlePlacesEvents(events) { - for (let e of events) if (e.url && e.url == BookmarkingUI._uri?.spec) this.updateMenuItem(); - }, - async updateMenuItem(_e, location) { - let uri; - let menuitem = ucBookmarksShortcuts.bookmarkTab; - if (location) uri = new URL(location?.spec); - if (BookmarkingUI._uri) uri = new URL(BookmarkingUI._uri.spec); - if (!uri) return; - let isStarred = await PlacesUtils.bookmarks.fetch({ url: uri }); - menuitem.ownerDocument.l10n.setAttributes( - menuitem, - isStarred ? "bookmarks-bookmark-edit-panel" : "bookmarks-current-tab" - ); - menuitem.setAttribute( - "image", - isStarred - ? "chrome://browser/skin/bookmark.svg" - : "chrome://browser/skin/bookmark-hollow.svg" - ); - }, - init() { - // delete these two lines if you don't want the confirmation hint to show when you bookmark a page. - Services.prefs.setIntPref("browser.bookmarks.editDialog.confirmationHintShowCount", 0); - Services.prefs.lockPref("browser.bookmarks.editDialog.confirmationHintShowCount"); - BookmarkingUI.button.setAttribute("onclick", "ucBookmarksShortcuts.bookmarkClick(event)"); - CustomizableUI.getWidget("library-button") - .forWindow(window) - .node?.setAttribute("onclick", "ucBookmarksShortcuts.bookmarkClick(event)"); - this.addMenuitems(document.getElementById("BMB_bookmarksPopup")); - gBrowser.addTabsProgressListener(this); - PlacesUtils.bookmarks.addObserver(this); - PlacesUtils.observers.addListener( - ["bookmark-added", "bookmark-removed"], - this.handlePlacesEvents.bind(this) - ); - // set the "positionend" attribute on the view bookmarks sidebar menuitem. - // this way we can swap between the left/right sidebar icons based on which side the sidebar is on, - // like the sidebar toolbar widget does. - document.getElementById("BMB_viewBookmarksSidebar").appendChild( - this.create(document, "observes", { - "element": "sidebar-box", - "attribute": "positionend", - }) - ); - }, - QueryInterface: ChromeUtils.generateQI(["nsINavBookmarkObserver"]), -}; - -if (gBrowserInit.delayedStartupFinished) ucBookmarksShortcuts.init(); -else { - let delayedListener = (subject, topic) => { - if (topic == "browser-delayed-startup-finished" && subject == window) { - Services.obs.removeObserver(delayedListener, topic); - ucBookmarksShortcuts.init(); - } - }; - Services.obs.addObserver(delayedListener, "browser-delayed-startup-finished"); -} +// ==UserScript== +// @name Bookmarks Menu & Button Shortcuts +// @version 1.2.3 +// @author aminomancer +// @homepage https://github.com/aminomancer/uc.css.js +// @description Adds some shortcuts for bookmarking pages. First, middle-clicking the bookmarks or library toolbar button will bookmark the current tab, or un-bookmark it if it's already bookmarked. Second, a menu item is added to the bookmarks toolbar button's popup, which bookmarks the current tab, or, if the page is already bookmarked, opens the bookmark editor popup. These are added primarily so that bookmarks can be added or removed with a single click, and can still be quickly added even if the bookmark page action is hidden for whatever reason. Third, another menu item is added to replicate the "Search bookmarks" button in the app menu's bookmarks panel. Clicking it will open the urlbar in bookmarks search mode. +// @license This Source Code Form is subject to the terms of the Creative Commons Attribution-NonCommercial-ShareAlike International License, v. 4.0. If a copy of the CC BY-NC-SA 4.0 was not distributed with this file, You can obtain one at http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. +// ==/UserScript== + +const ucBookmarksShortcuts = { + create(aDoc, tag, props, isHTML = false) { + let el = isHTML ? aDoc.createElement(tag) : aDoc.createXULElement(tag); + for (let prop in props) el.setAttribute(prop, props[prop]); + return el; + }, + async bookmarkClick(e) { + if (e.button !== 1 || e.target.tagName !== "toolbarbutton") return; + let bm = await PlacesUtils.bookmarks.fetch({ url: new URL(BookmarkingUI._uri.spec) }); + bm ? PlacesTransactions.Remove(bm.guid).transact() : this.starCmd(); + e.preventDefault(); + e.stopPropagation(); + }, + async starCmd() { + if (!BookmarkingUI._pendingUpdate) { + if (!!BookmarkingUI.starAnimBox && !(BookmarkingUI._itemGuids.size > 0)) { + BrowserUIUtils.setToolbarButtonHeightProperty(BookmarkingUI.star); + document + .getElementById("star-button-animatable-box") + .addEventListener( + "animationend", + () => BookmarkingUI.star.removeAttribute("animate"), + { once: true } + ); + BookmarkingUI.star.setAttribute("animate", "true"); + } + let browser = gBrowser.selectedBrowser; + let url = new URL(browser.currentURI.spec); + let parentGuid = await PlacesUIUtils.defaultParentGuid; + let info = { url, parentGuid }; + let charset = null; + let isErrorPage = false; + if (browser.documentURI) + isErrorPage = /^about:(neterror|certerror|blocked)/.test(browser.documentURI.spec); + try { + if (isErrorPage) { + let entry = await PlacesUtils.history.fetch(browser.currentURI); + if (entry) info.title = entry.title; + } else info.title = browser.contentTitle; + info.title = info.title || url.href; + charset = browser.characterSet; + } catch (e) {} + info.guid = await PlacesTransactions.NewBookmark(info).transact(); + if (charset) PlacesUIUtils.setCharsetForPage(url, charset, window); + gURLBar.handleRevert(); + StarUI.showConfirmation(); + } + }, + addMenuitems(popup) { + let doc = popup.ownerDocument; + this.bookmarkTab = doc.createXULElement("menuitem"); + this.bookmarkTab = this.create(doc, "menuitem", { + id: "BMB_bookmarkThisPage", + label: "", + class: "menuitem-iconic subviewbutton", + onclick: "ucBookmarksShortcuts.updateMenuItem()", + oncommand: "BookmarkingUI.onStarCommand(event);", + key: "addBookmarkAsKb", + image: "chrome://browser/skin/bookmark-hollow.svg", + }); + popup.insertBefore(this.bookmarkTab, popup.firstElementChild); + popup.addEventListener("popupshowing", this.updateMenuItem, false); + this.bookmarkTab.setAttribute("data-l10n-id", "bookmarks-current-tab"); + this.searchBookmarks = popup.querySelector("#BMB_viewBookmarksSidebar").after( + this.create(doc, "menuitem", { + id: "BMB_searchBookmarks", + class: "menuitem-iconic subviewbutton", + "data-l10n-id": "bookmarks-search", + oncommand: "PlacesCommandHook.searchBookmarks();", + image: "chrome://global/skin/icons/search-glass.svg", + }) + ); + }, + onLocationChange(browser, _prog, _req, location, _flags) { + if (browser !== gBrowser.selectedBrowser) return; + this.updateMenuItem(null, location); + }, + handlePlacesEvents(events) { + for (let e of events) if (e.url && e.url == BookmarkingUI._uri?.spec) this.updateMenuItem(); + }, + async updateMenuItem(_e, location) { + let uri; + let menuitem = ucBookmarksShortcuts.bookmarkTab; + if (location) uri = new URL(location?.spec); + if (BookmarkingUI._uri) uri = new URL(BookmarkingUI._uri.spec); + if (!uri) return; + let isStarred = await PlacesUtils.bookmarks.fetch({ url: uri }); + if ("l10n" in menuitem.ownerDocument && menuitem.ownerDocument.l10n) + menuitem.ownerDocument.l10n.setAttributes( + menuitem, + isStarred ? "bookmarks-bookmark-edit-panel" : "bookmarks-current-tab" + ); + menuitem.setAttribute( + "image", + isStarred + ? "chrome://browser/skin/bookmark.svg" + : "chrome://browser/skin/bookmark-hollow.svg" + ); + }, + init() { + let { node } = CustomizableUI.getWidget("bookmarks-menu-button")?.forWindow(window); + // delete these two lines if you don't want the confirmation hint to show when you bookmark a page. + Services.prefs.setIntPref("browser.bookmarks.editDialog.confirmationHintShowCount", 0); + Services.prefs.lockPref("browser.bookmarks.editDialog.confirmationHintShowCount"); + BookmarkingUI.button.setAttribute("onclick", "ucBookmarksShortcuts.bookmarkClick(event)"); + CustomizableUI.getWidget("library-button") + .forWindow(window) + .node?.setAttribute("onclick", "ucBookmarksShortcuts.bookmarkClick(event)"); + this.addMenuitems(node.querySelector("#BMB_bookmarksPopup")); + gBrowser.addTabsProgressListener(this); + PlacesUtils.bookmarks.addObserver(this); + PlacesUtils.observers.addListener( + ["bookmark-added", "bookmark-removed"], + this.handlePlacesEvents.bind(this) + ); + // set the "positionend" attribute on the view bookmarks sidebar menuitem. + // this way we can swap between the left/right sidebar icons based on which side the sidebar is on, + // like the sidebar toolbar widget does. + let sidebarItem = node.querySelector("#BMB_viewBookmarksSidebar"); + if (sidebarItem) + sidebarItem.appendChild( + this.create(document, "observes", { + "element": "sidebar-box", + "attribute": "positionend", + }) + ); + }, + QueryInterface: ChromeUtils.generateQI(["nsINavBookmarkObserver"]), +}; + +if (gBrowserInit.delayedStartupFinished) ucBookmarksShortcuts.init(); +else { + let delayedListener = (subject, topic) => { + if (topic == "browser-delayed-startup-finished" && subject == window) { + Services.obs.removeObserver(delayedListener, topic); + ucBookmarksShortcuts.init(); + } + }; + Services.obs.addObserver(delayedListener, "browser-delayed-startup-finished"); +} diff --git a/JS/floatingSidebarResizer.uc.js b/JS/floatingSidebarResizer.uc.js index 2f9e9063..eecdb296 100644 --- a/JS/floatingSidebarResizer.uc.js +++ b/JS/floatingSidebarResizer.uc.js @@ -1,195 +1,197 @@ -// ==UserScript== -// @name Floating Sidebar Resizer -// @version 1.2.1 -// @author aminomancer -// @homepage https://github.com/aminomancer -// @description A floating sidebar that you can still resize, plus some better shortcut hotkeys. The default sidebar in firefox is nice, it can move from the left side to the right side and you can resize it. But it squeezes the browser content area out of the way. That might be desirable for some people. That way the entire contents of the page are still visible when the sidebar is open. That works well with responsive page layouts but doesn't work well with elements that try to preserve some explicit aspect ratio. It also doesn't look very aesthetic when you open the sidebar and the entire page makes this jarring transformation as everything shifts left or right to make way for the sidebar. So say your browser window is sized precisely to 16:9 dimensions. Maybe you have ocd like me and don't want to see any letterbox when you watch netflix. By default when you open the sidebar, it pushes the whole content area to the side, which changes the content area width:height ratio. So the player setup needs to resize the video element, resulting in a letterbox effect. It's easy enough to make the sidebar "float" over the content though. You can do it with pure css. The major downside is that you lose the ability to resize the sidebar. You'd have to set the width manually. That's because the native implementation of resizing relies on the old-school proprietary -moz-box spec. The space within #browser is finite and the -moz-boxes within fill that space based on some css rules. The resizing is actually handled by the separator, which is a totally independent element. So within #browser you have: content | separator | sidebar. And moving the separator defines how big the sidebar and content area are, but this only works *because* they can't occupy the same space. To make the sidebar float over the content area you need to change its display and position rules, which means the separator no longer packs right next to the sidebar. It's sort of like plucking the sidebar out of the flexbox. The separator moves all the way to the end of the screen and the content area expands to fill that space. So the separator becomes useless and we lose the ability to resize the sidebar. So the main thing this does is add a resizer to the sidebar. It doesn't make the sidebar float by itself. That's what the css files in this repo are for. It also remaps the ctrl+b shortcut to simply toggle the sidebar rather than exclusively opening the bookmarks sidebar. So if you previously had the synced tabs sidebar open before you closed it, ctrl+b will open the sidebar to the synced tabs page, rather than opening to the bookmarks view. The bookmarks view is instead remapped to ctrl+shift+b. This overrides the built-in ctrl+shift+b command, which opens the bookmarks toolbar. I don't use the bookmarks toolbar myself but I figure someone who does use it probably wants it open 24/7 and isn't likely to need a hotkey to hide/show it. FYI the hotkey depends on your os, like other firefox shortcuts. e.g. On macOS it'll be Cmd+B, not Ctrl+B. It also depends on your accel key setting, so if you change the key in about:config, this hotkey will use your modifier key. Anyway, the hotkey changes can be disabled in about:config by setting userchrome.floating-sidebar.hotkey to false. -// @license This Source Code Form is subject to the terms of the Creative Commons Attribution-NonCommercial-ShareAlike International License, v. 4.0. If a copy of the CC BY-NC-SA 4.0 was not distributed with this file, You can obtain one at http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. -// ==/UserScript== - -(() => { - function startup() { - // outer box - let box = SidebarUI._box; - let prefsvc = Services.prefs; - let sidebarBundle = Services.strings.createBundle( - "chrome://browser/locale/customizableui/customizableWidgets.properties" - ); - // boolean pref: whether sidebar is on the left or right side of the browser content area. - let anchor = "sidebar.position_start"; - // string pref: we set this so we can remember user's sidebar width when rebooting or opening a new window. - let widthPref = "userChrome.floating-sidebar.width"; - // boolean pref: whether the ctrl+B hotkey should be changed or not. - let hotkey = "userChrome.floating-sidebar.hotkey"; - // string representing the built-in ctrl+B command - let cB = "viewBookmarksSidebarKb"; - // string representing the built-in ctrl+shift+B command - let csB = "viewBookmarksToolbarKb"; - // invisible little bar by which to drag the sidebar to resize it - let resizer = document.createElement("div"); - // the actual ctrl+B command - let sidebarCmd = document.getElementById(cB); - // the actual ctrl+shift+B command - let toolbarCmd = document.getElementById(csB); - // the bookmarks button that appears in the switcher menu at the top of the sidebar - let sidebarSwitch = document.getElementById("sidebar-switcher-bookmarks"); - // the bookmarks button that appears in the titlebar menubar under view > sidebar > bookmarks - let menuSwitch = document.getElementById("menu_bookmarksSidebar"); - let frame = false; - let startWidth; - let startX; - - function initDrag(e) { - resizer.style.width = "200%"; // this is not directly visible since the element has no background or content. this just means that while you're clicking+dragging the resizer, its width expands to double the size of the entire sidebar. sounds weird but this is done because there are iframes under the cursor... an iframe in the sidebar, on one side of the cursor, and an iframe in the browser on the other side. when the cursor moves over these elements, the CSS changes the cursor from "ew-resize" to "default" or "pointer" or whatever. at the same time, the script kicks in and sets the width of the sidebar to follow the cursor. if these actually happened simultaneously then it wouldn't matter, since the sidebar would always resize instantly, meaning the resizer would always be directly underneath the cursor. but they don't happen simultaneously, the CSS changes the cursor and THEN the sidebar is resized. meaning that during the intervening period, the cursor flickers to something else. when you're actually resizing, this is happening like dozens of times a second or more, so you would see really rapid flickering of the cursor. if we were designing a web app this would be easy to solve, just use javascript to modulate document.body.style.cursor on mousedown and mouseup. but since this is a userChrome script, and the cursor is on top of iframes with documents that are very complicated to access from the global execution context, we should just work around it. so instead of trying to manually set cursor rules for every element the cursor might intersect, we'll just make the invisible resizer so big that there's no way to move your mouse outside of it before the sidebar catches up. then we set its size back to normal on mouseup. - resizer.style.marginInline = "-100%"; // we want the resizer to expand massively in both directions, right and left. since the sidebar itself is always bounded by the window itself on one side, this rule causes the resizer to "align" itself horizontally with its center at the edge it normally exists at. so if the sidebar is on the right side, this will keep the resizer centered on the sidebar's left edge. and vice versa. if you look at it in the inspector you can see it's as if the resizer is expanding massively from where it already is. there are other ways to do this but this uses the fewest rules and assignments as far as i could tell. - startX = e.screenX; // of all the values this seems to be the least jittery. the others seem to work poorly because there's an iframe right next to the dragger that your cursor will hover over sometimes, which will change the event target and momentarily disrupt the value of e.clientX. if we added logic to check the event target i think that'd be slower than just using screenX instead. - startWidth = parseInt(document.defaultView.getComputedStyle(box).width, 10); - document.documentElement.addEventListener("mousemove", doDrag, true); // listen to mouse movements - document.documentElement.addEventListener("mouseup", stopDrag, false); // listen for mouseup so we can kill all the listeners except mousedown (which calls this) - } - - function doDrag(e) { - if (frame) return; // throttling, since mousemove events can fire way faster than even a 144Hz monitor can render frames. - frame = true; // this will "ignore" any events sent in between the execution of this line, and the execution of requestAnimationFrame(...frame=false). therefore, only one width update per frame rendered, and that update will happen during the draw phase. this isn't necessary for most other types of events but this one could potentially cause stutters otherwise depending on your input hardware. - requestAnimationFrame(() => { - SidebarUI._positionStart // check which side of the screen the sidebar is on - ? (box.style.width = startWidth + e.screenX - startX + "px") // if it's on the left side then we add the cursor's X coordinate since that integer increases as we move the cursor right, and we obviously move the mouse *right* to "drag" the box rightwards. - : (box.style.width = startWidth - e.screenX + startX + "px"); // if it's on the right side then we subtract screenX and add startX since we're going to be moving the cursor leftwards to expand the sidebar box, and screenX will get smaller as the cursor moves left. - frame = false; // denote that execution has finished so the function can accept another event - }); - } - - function stopDrag(_e) { - resizer.style.width = "4px"; // this is the neutral/idle size. when you're not clicking/dragging it's just a 4px vertical "border" - resizer.style.removeProperty("margin-inline"); // remove the -100% margin-inline rule we set while dragging. - document.documentElement.removeEventListener("mousemove", doDrag, true); // stop listening for mouse movements since we let go of the left mouse button. - document.documentElement.removeEventListener("mouseup", stopDrag, false); // stop listening for mouseup since we already released the LMB. - prefsvc.setStringPref(widthPref, box.style.width); // now that we've stopped moving the mouse, permanently record the sidebar width so we can restore from it later. we do this only on mouseup instead of mousemove since we don't want to spend resources needlessly calling the prefs service. the mouse needs to be released eventually and there's no realistic reason we'd ever need to restore from the pref while the LMB is still being held down. the only way is if you click, hold, drag the resizer, and while still dragging, hit ctrl+N on your keyboard to open a new window. but... lol why - } - - function alignObserve(_sub, _top, pref) { - // we want the resizer to go on the left side of the sidebar when the sidebar is on the right side of the window, and vice versa. - // mozilla implements this by just making the sidebar a -moz-box and changing -moz-box-ordinal-group to change the order. the children of #browser are packed horizontally so that works fine. but -moz-box works kinda like flexbox and makes it a bitch to implement something like this "floating sidebar." the whole purpose of this is to make it so opening the sidebar *doesn't* squeeze the browser content area. so we do this kinda thing manually instead. - prefsvc.getBoolPref(pref) - ? (resizer.style.right = "0") - : resizer.style.removeProperty("right"); - } - - function exitSideBar(e) { - if (e.code === "Escape") { - if (e.repeat || e.shiftKey || e.altKey || e.ctrlKey || this.hidden) return; - SidebarUI.toggle(); - e.preventDefault(); - } - } - - function hotkeyObserve(_sub, _top, pref) { - if (prefsvc.getBoolPref(pref)) { - sidebarCmd.setAttribute("oncommand", "SidebarUI.toggle();"); // ctrl+B to toggle - toolbarCmd.setAttribute( - "oncommand", - "SidebarUI.toggle('viewBookmarksSidebar');" // ctrl+shift+B to open bookmarks sidebar - ); - menuSwitch.setAttribute("key", csB); // show ctrl+shift+B as the shortcut for view > sidebar > bookmarks - sidebarSwitch.setAttribute("key", csB); // show ctrl+shift+B as the shortcut in the sidebar switcher menu - if (BMB_viewBookmarksSidebar) BMB_viewBookmarksSidebar.setAttribute("key", csB); // same for bookmarks toolbar button popup - // this generates the shortcut label from the key attribute. better to do it this way so it'll correctly show the modifier key depending on your settings and OS. like if accel key is cmd/meta then it'll say so, if you set it to alt for some reason it should say that as well. although it won't dynamically update if you change your accel key setting during runtime, since that would be extremely rare. - SidebarUI.updateShortcut({ button: sidebarSwitch }); - // change the hotkey in the bookmarks toolbar button's tooltip to reflect the bookmarks sidebar hotkey rather than the bookmarks manager hotkey, since the history toolbar button shows its sidebar hotkey. it's just to clear up a minor inconsistency. - nodeToShortcutMap["bookmarks-menu-button"] = csB; - // when right-clicking a toolbar there's a "bookmarks toolbar" menu, where the ctrl+shift+B command is shown in the acceltext of the menuitems. we'll use CSS to hide it, since the acceltext is applied dynamically and it's a bitch to change that. - ["toolbar-context-menu", "placesContext"].forEach((id) => - document.getElementById(id).setAttribute("bmb-command-disabled", true) - ); - } else { - // (mostly) factory reset - sidebarCmd.setAttribute("oncommand", "SidebarUI.toggle('viewBookmarksSidebar');"); - toolbarCmd.setAttribute( - "oncommand", - "BookmarkingUI.toggleBookmarksToolbar('shortcut');" - ); - menuSwitch.setAttribute("key", cB); - sidebarSwitch.setAttribute("key", cB); - if (BMB_viewBookmarksSidebar) BMB_viewBookmarksSidebar.setAttribute("key", cB); - SidebarUI.updateShortcut({ button: sidebarSwitch }); - nodeToShortcutMap["bookmarks-menu-button"] = cB; - ["toolbar-context-menu", "placesContext"].forEach((id) => - document.getElementById(id).removeAttribute("bmb-command-disabled") - ); - } - CustomizableUI.getWidget("sidebar-button") - .forWindow(window) - .node.setAttribute( - "tooltiptext", - `${sidebarBundle.GetStringFromName( - "sidebar-button.tooltiptext2" - )} (${ShortcutUtils.prettifyShortcut(sidebarCmd)})` - ); - gDynamicTooltipCache.delete("bookmarks-menu-button"); - } - - async function prefSet(pref, val) { - return prefsvc.setBoolPref(pref, val); // but you promised~... - } - - // for initial startup - async function setHotkeyPref() { - try { - hotkeyObserve(null, null, hotkey); // will reliably throw if the pref hasn't already been made, so we can use try/catch like if/else - } catch (e) { - await prefSet(hotkey, true); // create the pref if it doesn't already exist... - hotkeyObserve(null, null, hotkey); // then pass the new pref to the function that sets the hotkey stuff - } - } - - function domSetup() { - resizer.className = "dragger"; // for stylesheets i guess - resizer.style.cssText = - "display: inline-block; height: 100%; position: absolute; width: 4px; cursor: ew-resize;"; - box.appendChild(resizer); // can't be the first child or it'll break native functions - box.style.minWidth = "18em"; // set a min width so you can't resize it to 0px. we choose 18em since that's the width of the searchbox. any smaller and you'd have to change the searchbox rules, since resizing below 18em would result in the searchbox not shrinking and instead overflowing and bleeding off of the window. - box.style.maxWidth = "100%"; // since we used screenX it could grow beyond the window's width. so we set it here. setting the max width with CSS actually results in smoother animation than using logic in the width-setting script to limit the value. css is really underrated for things like that. - try { - box.style.width = prefsvc.getStringPref(widthPref); // on window startup, set the sidebar width equal to the value of the custom pref we set up. - } catch (e) { - box.style.width = "18em"; // if the pref doesn't already exist (e.g. on first script run) then use the built-in default. - } - // on initial setup, if the sidebar is on the left side, move the resizer to the right edge. - if (prefsvc.getBoolPref(anchor)) resizer.style.right = "0"; // align resizer to the right edge - } - - function attachListeners() { - // SidebarUI._switcherTarget.addEventListener("SidebarShown", (e) => console.log(e)); // could conceivably use this to do something when the sidebar opens. but the event doesn't pop until after the sidebar has already been rendered so it's not useful for instantiating visual changes. - resizer.addEventListener("mousedown", initDrag, false); // listen for clicks on the resizer - window.addEventListener("unload", uninit, false); // listen for unload so we can clean up after ourselves explicitly - prefsvc.addObserver(anchor, alignObserve); // watch the pref set by the "Move Sidebar to Left/Right" button - prefsvc.addObserver(hotkey, hotkeyObserve); // watch the custom hotkey pref - box.addEventListener("keypress", exitSideBar, true); - } - - // since some of this stuff is for global interfaces we wanna destroy the listeners for a window when it's gone. probably not necessary but not a bad habit - function uninit() { - // remove itself - window.removeEventListener("unload", uninit, false); - // remove the pref observers - prefsvc.removeObserver(anchor, alignObserve); - prefsvc.removeObserver(hotkey, hotkeyObserve); - } - - setHotkeyPref(); - domSetup(); - attachListeners(); - } - // wait until components are initialized so we can access SidebarUI - if (gBrowserInit.delayedStartupFinished) { - startup(); - } else { - let delayedListener = (subject, topic) => { - if (topic == "browser-delayed-startup-finished" && subject == window) { - Services.obs.removeObserver(delayedListener, topic); - startup(); - } - }; - Services.obs.addObserver(delayedListener, "browser-delayed-startup-finished"); - } -})(); +// ==UserScript== +// @name Floating Sidebar Resizer +// @version 1.2.3 +// @author aminomancer +// @homepage https://github.com/aminomancer +// @description A floating sidebar that you can still resize, plus some better shortcut hotkeys. The default sidebar in firefox is nice, it can move from the left side to the right side and you can resize it. But it squeezes the browser content area out of the way. That might be desirable for some people. That way the entire contents of the page are still visible when the sidebar is open. That works well with responsive page layouts but doesn't work well with elements that try to preserve some explicit aspect ratio. It also doesn't look very aesthetic when you open the sidebar and the entire page makes this jarring transformation as everything shifts left or right to make way for the sidebar. So say your browser window is sized precisely to 16:9 dimensions. Maybe you have ocd like me and don't want to see any letterbox when you watch netflix. By default when you open the sidebar, it pushes the whole content area to the side, which changes the content area width:height ratio. So the player setup needs to resize the video element, resulting in a letterbox effect. It's easy enough to make the sidebar "float" over the content though. You can do it with pure css. The major downside is that you lose the ability to resize the sidebar. You'd have to set the width manually. That's because the native implementation of resizing relies on the old-school proprietary -moz-box spec. The space within #browser is finite and the -moz-boxes within fill that space based on some css rules. The resizing is actually handled by the separator, which is a totally independent element. So within #browser you have: content | separator | sidebar. And moving the separator defines how big the sidebar and content area are, but this only works *because* they can't occupy the same space. To make the sidebar float over the content area you need to change its display and position rules, which means the separator no longer packs right next to the sidebar. It's sort of like plucking the sidebar out of the flexbox. The separator moves all the way to the end of the screen and the content area expands to fill that space. So the separator becomes useless and we lose the ability to resize the sidebar. So the main thing this does is add a resizer to the sidebar. It doesn't make the sidebar float by itself. That's what the css files in this repo are for. It also remaps the ctrl+b shortcut to simply toggle the sidebar rather than exclusively opening the bookmarks sidebar. So if you previously had the synced tabs sidebar open before you closed it, ctrl+b will open the sidebar to the synced tabs page, rather than opening to the bookmarks view. The bookmarks view is instead remapped to ctrl+shift+b. This overrides the built-in ctrl+shift+b command, which opens the bookmarks toolbar. I don't use the bookmarks toolbar myself but I figure someone who does use it probably wants it open 24/7 and isn't likely to need a hotkey to hide/show it. FYI the hotkey depends on your os, like other firefox shortcuts. e.g. On macOS it'll be Cmd+B, not Ctrl+B. It also depends on your accel key setting, so if you change the key in about:config, this hotkey will use your modifier key. Anyway, the hotkey changes can be disabled in about:config by setting userchrome.floating-sidebar.hotkey to false. +// @license This Source Code Form is subject to the terms of the Creative Commons Attribution-NonCommercial-ShareAlike International License, v. 4.0. If a copy of the CC BY-NC-SA 4.0 was not distributed with this file, You can obtain one at http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. +// ==/UserScript== + +(() => { + function startup() { + // outer box + let box = SidebarUI._box; + let prefsvc = Services.prefs; + let sidebarBundle = Services.strings.createBundle( + "chrome://browser/locale/customizableui/customizableWidgets.properties" + ); + // boolean pref: whether sidebar is on the left or right side of the browser content area. + let anchor = "sidebar.position_start"; + // string pref: we set this so we can remember user's sidebar width when rebooting or opening a new window. + let widthPref = "userChrome.floating-sidebar.width"; + // boolean pref: whether the ctrl+B hotkey should be changed or not. + let hotkey = "userChrome.floating-sidebar.hotkey"; + // string representing the built-in ctrl+B command + let cB = "viewBookmarksSidebarKb"; + // string representing the built-in ctrl+shift+B command + let csB = "viewBookmarksToolbarKb"; + // invisible little bar by which to drag the sidebar to resize it + let resizer = document.createElement("div"); + // the actual ctrl+B command + let sidebarCmd = document.getElementById(cB); + // the actual ctrl+shift+B command + let toolbarCmd = document.getElementById(csB); + // the bookmarks button that appears in the switcher menu at the top of the sidebar + let sidebarSwitch = document.getElementById("sidebar-switcher-bookmarks"); + // the bookmarks button that appears in the titlebar menubar under view > sidebar > bookmarks + let menuSwitch = document.getElementById("menu_bookmarksSidebar"); + let frame = false; + let startWidth; + let startX; + + function initDrag(e) { + resizer.style.width = "200%"; // this is not directly visible since the element has no background or content. this just means that while you're clicking+dragging the resizer, its width expands to double the size of the entire sidebar. sounds weird but this is done because there are iframes under the cursor... an iframe in the sidebar, on one side of the cursor, and an iframe in the browser on the other side. when the cursor moves over these elements, the CSS changes the cursor from "ew-resize" to "default" or "pointer" or whatever. at the same time, the script kicks in and sets the width of the sidebar to follow the cursor. if these actually happened simultaneously then it wouldn't matter, since the sidebar would always resize instantly, meaning the resizer would always be directly underneath the cursor. but they don't happen simultaneously, the CSS changes the cursor and THEN the sidebar is resized. meaning that during the intervening period, the cursor flickers to something else. when you're actually resizing, this is happening like dozens of times a second or more, so you would see really rapid flickering of the cursor. if we were designing a web app this would be easy to solve, just use javascript to modulate document.body.style.cursor on mousedown and mouseup. but since this is a userChrome script, and the cursor is on top of iframes with documents that are very complicated to access from the global execution context, we should just work around it. so instead of trying to manually set cursor rules for every element the cursor might intersect, we'll just make the invisible resizer so big that there's no way to move your mouse outside of it before the sidebar catches up. then we set its size back to normal on mouseup. + resizer.style.marginInline = "-100%"; // we want the resizer to expand massively in both directions, right and left. since the sidebar itself is always bounded by the window itself on one side, this rule causes the resizer to "align" itself horizontally with its center at the edge it normally exists at. so if the sidebar is on the right side, this will keep the resizer centered on the sidebar's left edge. and vice versa. if you look at it in the inspector you can see it's as if the resizer is expanding massively from where it already is. there are other ways to do this but this uses the fewest rules and assignments as far as i could tell. + startX = e.screenX; // of all the values this seems to be the least jittery. the others seem to work poorly because there's an iframe right next to the dragger that your cursor will hover over sometimes, which will change the event target and momentarily disrupt the value of e.clientX. if we added logic to check the event target i think that'd be slower than just using screenX instead. + startWidth = parseInt(document.defaultView.getComputedStyle(box).width, 10); + document.documentElement.addEventListener("mousemove", doDrag, true); // listen to mouse movements + document.documentElement.addEventListener("mouseup", stopDrag, false); // listen for mouseup so we can kill all the listeners except mousedown (which calls this) + } + + function doDrag(e) { + if (frame) return; // throttling, since mousemove events can fire way faster than even a 144Hz monitor can render frames. + frame = true; // this will "ignore" any events sent in between the execution of this line, and the execution of requestAnimationFrame(...frame=false). therefore, only one width update per frame rendered, and that update will happen during the draw phase. this isn't necessary for most other types of events but this one could potentially cause stutters otherwise depending on your input hardware. + requestAnimationFrame(() => { + SidebarUI._positionStart // check which side of the screen the sidebar is on + ? (box.style.width = startWidth + e.screenX - startX + "px") // if it's on the left side then we add the cursor's X coordinate since that integer increases as we move the cursor right, and we obviously move the mouse *right* to "drag" the box rightwards. + : (box.style.width = startWidth - e.screenX + startX + "px"); // if it's on the right side then we subtract screenX and add startX since we're going to be moving the cursor leftwards to expand the sidebar box, and screenX will get smaller as the cursor moves left. + frame = false; // denote that execution has finished so the function can accept another event + }); + } + + function stopDrag(_e) { + resizer.style.width = "4px"; // this is the neutral/idle size. when you're not clicking/dragging it's just a 4px vertical "border" + resizer.style.removeProperty("margin-inline"); // remove the -100% margin-inline rule we set while dragging. + document.documentElement.removeEventListener("mousemove", doDrag, true); // stop listening for mouse movements since we let go of the left mouse button. + document.documentElement.removeEventListener("mouseup", stopDrag, false); // stop listening for mouseup since we already released the LMB. + prefsvc.setStringPref(widthPref, box.style.width); // now that we've stopped moving the mouse, permanently record the sidebar width so we can restore from it later. we do this only on mouseup instead of mousemove since we don't want to spend resources needlessly calling the prefs service. the mouse needs to be released eventually and there's no realistic reason we'd ever need to restore from the pref while the LMB is still being held down. the only way is if you click, hold, drag the resizer, and while still dragging, hit ctrl+N on your keyboard to open a new window. but... lol why + } + + function alignObserve(_sub, _top, pref) { + // we want the resizer to go on the left side of the sidebar when the sidebar is on the right side of the window, and vice versa. + // mozilla implements this by just making the sidebar a -moz-box and changing -moz-box-ordinal-group to change the order. the children of #browser are packed horizontally so that works fine. but -moz-box works kinda like flexbox and makes it a bitch to implement something like this "floating sidebar." the whole purpose of this is to make it so opening the sidebar *doesn't* squeeze the browser content area. so we do this kinda thing manually instead. + prefsvc.getBoolPref(pref) + ? (resizer.style.right = "0") + : resizer.style.removeProperty("right"); + } + + function exitSideBar(e) { + if (e.code === "Escape") { + if (e.repeat || e.shiftKey || e.altKey || e.ctrlKey || this.hidden) return; + SidebarUI.toggle(); + e.preventDefault(); + } + } + + function hotkeyObserve(_sub, _top, pref) { + let { node } = CustomizableUI.getWidget("bookmarks-menu-button")?.forWindow(window); + let sidebarItem = node.querySelector("#BMB_viewBookmarksSidebar"); + if (prefsvc.getBoolPref(pref)) { + sidebarCmd.setAttribute("oncommand", "SidebarUI.toggle();"); // ctrl+B to toggle + toolbarCmd.setAttribute( + "oncommand", + "SidebarUI.toggle('viewBookmarksSidebar');" // ctrl+shift+B to open bookmarks sidebar + ); + menuSwitch.setAttribute("key", csB); // show ctrl+shift+B as the shortcut for view > sidebar > bookmarks + sidebarSwitch.setAttribute("key", csB); // show ctrl+shift+B as the shortcut in the sidebar switcher menu + if (sidebarItem) sidebarItem.setAttribute("key", csB); // same for bookmarks toolbar button popup + // this generates the shortcut label from the key attribute. better to do it this way so it'll correctly show the modifier key depending on your settings and OS. like if accel key is cmd/meta then it'll say so, if you set it to alt for some reason it should say that as well. although it won't dynamically update if you change your accel key setting during runtime, since that would be extremely rare. + SidebarUI.updateShortcut({ button: sidebarSwitch }); + // change the hotkey in the bookmarks toolbar button's tooltip to reflect the bookmarks sidebar hotkey rather than the bookmarks manager hotkey, since the history toolbar button shows its sidebar hotkey. it's just to clear up a minor inconsistency. + nodeToShortcutMap["bookmarks-menu-button"] = csB; + // when right-clicking a toolbar there's a "bookmarks toolbar" menu, where the ctrl+shift+B command is shown in the acceltext of the menuitems. we'll use CSS to hide it, since the acceltext is applied dynamically and it's a bitch to change that. + ["toolbar-context-menu", "placesContext"].forEach((id) => + document.getElementById(id).setAttribute("bmb-command-disabled", true) + ); + } else { + // (mostly) factory reset + sidebarCmd.setAttribute("oncommand", "SidebarUI.toggle('viewBookmarksSidebar');"); + toolbarCmd.setAttribute( + "oncommand", + "BookmarkingUI.toggleBookmarksToolbar('shortcut');" + ); + menuSwitch.setAttribute("key", cB); + sidebarSwitch.setAttribute("key", cB); + if (sidebarItem) sidebarItem.setAttribute("key", cB); + SidebarUI.updateShortcut({ button: sidebarSwitch }); + nodeToShortcutMap["bookmarks-menu-button"] = cB; + ["toolbar-context-menu", "placesContext"].forEach((id) => + document.getElementById(id).removeAttribute("bmb-command-disabled") + ); + } + CustomizableUI.getWidget("sidebar-button") + .forWindow(window) + .node.setAttribute( + "tooltiptext", + `${sidebarBundle.GetStringFromName( + "sidebar-button.tooltiptext2" + )} (${ShortcutUtils.prettifyShortcut(sidebarCmd)})` + ); + gDynamicTooltipCache.delete("bookmarks-menu-button"); + } + + async function prefSet(pref, val) { + return prefsvc.setBoolPref(pref, val); // but you promised~... + } + + // for initial startup + async function setHotkeyPref() { + try { + hotkeyObserve(null, null, hotkey); // will reliably throw if the pref hasn't already been made, so we can use try/catch like if/else + } catch (e) { + await prefSet(hotkey, true); // create the pref if it doesn't already exist... + hotkeyObserve(null, null, hotkey); // then pass the new pref to the function that sets the hotkey stuff + } + } + + function domSetup() { + resizer.className = "dragger"; // for stylesheets i guess + resizer.style.cssText = + "display: inline-block; height: 100%; position: absolute; width: 4px; cursor: ew-resize;"; + box.appendChild(resizer); // can't be the first child or it'll break native functions + box.style.minWidth = "18em"; // set a min width so you can't resize it to 0px. we choose 18em since that's the width of the searchbox. any smaller and you'd have to change the searchbox rules, since resizing below 18em would result in the searchbox not shrinking and instead overflowing and bleeding off of the window. + box.style.maxWidth = "100%"; // since we used screenX it could grow beyond the window's width. so we set it here. setting the max width with CSS actually results in smoother animation than using logic in the width-setting script to limit the value. css is really underrated for things like that. + try { + box.style.width = prefsvc.getStringPref(widthPref); // on window startup, set the sidebar width equal to the value of the custom pref we set up. + } catch (e) { + box.style.width = "18em"; // if the pref doesn't already exist (e.g. on first script run) then use the built-in default. + } + // on initial setup, if the sidebar is on the left side, move the resizer to the right edge. + if (prefsvc.getBoolPref(anchor)) resizer.style.right = "0"; // align resizer to the right edge + } + + function attachListeners() { + // SidebarUI._switcherTarget.addEventListener("SidebarShown", (e) => console.log(e)); // could conceivably use this to do something when the sidebar opens. but the event doesn't pop until after the sidebar has already been rendered so it's not useful for instantiating visual changes. + resizer.addEventListener("mousedown", initDrag, false); // listen for clicks on the resizer + window.addEventListener("unload", uninit, false); // listen for unload so we can clean up after ourselves explicitly + prefsvc.addObserver(anchor, alignObserve); // watch the pref set by the "Move Sidebar to Left/Right" button + prefsvc.addObserver(hotkey, hotkeyObserve); // watch the custom hotkey pref + box.addEventListener("keypress", exitSideBar, true); + } + + // since some of this stuff is for global interfaces we wanna destroy the listeners for a window when it's gone. probably not necessary but not a bad habit + function uninit() { + // remove itself + window.removeEventListener("unload", uninit, false); + // remove the pref observers + prefsvc.removeObserver(anchor, alignObserve); + prefsvc.removeObserver(hotkey, hotkeyObserve); + } + + setHotkeyPref(); + domSetup(); + attachListeners(); + } + // wait until components are initialized so we can access SidebarUI + if (gBrowserInit.delayedStartupFinished) { + startup(); + } else { + let delayedListener = (subject, topic) => { + if (topic == "browser-delayed-startup-finished" && subject == window) { + Services.obs.removeObserver(delayedListener, topic); + startup(); + } + }; + Services.obs.addObserver(delayedListener, "browser-delayed-startup-finished"); + } +})(); diff --git a/README.md b/README.md index 28124115..31ebcbc6 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,7 @@ I also recommend setting the following prefs in `about:config`. There are two pr | userChrome.tabs.pinned-tabs.close-buttons.disabled | Boolean | true | This controls whether close buttons are shown on pinned tabs | | userChrome.tabs.rounded-outer-corners.disabled | Boolean | false | This controls whether tabs have rounded bottom corners
| | userChrome.tabs.tooltip.always-show-lock-icon | Boolean | false | There's an icon in the tab tooltip representing page security. It's expanded by [this script](/JS/restoreTabSoundButton.uc.js) to show many security types. But by default, the icon is hidden on fully secure web pages. Setting this pref to true shows the icon on ALL pages | +| userChrome.urlbar.focus-ring-enabled | Boolean | true | Outline the urlbar/searchbar when focused | | userChrome.urlbar.hide-bookmarks-button-on-system-pages | Boolean | true | Hides the urlbar's bookmark button on about:blank & new tab page | | userChrome.urlbar.hide-pointless-icons | Boolean | true | Hide urlbar notification icons that don't offer any action (e.g. DRM icon) | | userChrome.urlbar-results.disable\_animation | Boolean | false | Toggle to true if you don't want the urlbar results to animate as they pop up | diff --git a/uc-findbar.css b/uc-findbar.css index f7eb36b2..38f8a6c8 100644 --- a/uc-findbar.css +++ b/uc-findbar.css @@ -333,14 +333,14 @@ findbar .matches-indicator { [anonid="findbar-textbox-wrapper"] { outline: 0 solid transparent !important; - transition: var(--findbar-textbox-outline-transition-duration, 100ms) outline ease-in !important; + transition: var(--textbox-outline-transition-duration, 100ms) outline ease-in !important; } [anonid="findbar-textbox-wrapper"]:focus-within { outline-width: 2px !important; outline-color: var(--search-box-focus-outline-color, -moz-accent-color) !important; transition-duration: calc( - var(--findbar-textbox-outline-transition-duration, 100ms) * 0.6 + var(--textbox-outline-transition-duration, 100ms) * 0.6 ) !important; transition-timing-function: ease-out !important; } diff --git a/uc-globals.css b/uc-globals.css index 29d9ba5d..8d003147 100644 --- a/uc-globals.css +++ b/uc-globals.css @@ -317,7 +317,7 @@ but other than that these variables should be available everywhere. */ --subviewbutton-height: 28px; --subview-subheader-padding: 5px 3px; --findbar-height: 22px; - --findbar-textbox-outline-transition-duration: 100ms; + --textbox-outline-transition-duration: 100ms; --findbar-textbox-bg-transition-duration: 200ms; --findbar-textbox-bg-notfound-transition-duration: 300ms; --default-identity-icon: url(chrome://userchrome/content/info-filled.svg); diff --git a/uc-misc.css b/uc-misc.css index 84681f09..70fe8888 100644 --- a/uc-misc.css +++ b/uc-misc.css @@ -601,6 +601,7 @@ toolbar:not(#PersonalToolbar) .toolbarbutton-1:focus-visible > .toolbarbutton-ba .dialog-button-box button { font-family: SF Pro Text, SF Arabic, Segoe UI, sans-serif !important; + font-weight: var(--uc-font-weight-bold, 600) !important; } #protections-popup-milestones-text { diff --git a/uc-urlbar.css b/uc-urlbar.css index a3285c4b..40ce71a3 100644 --- a/uc-urlbar.css +++ b/uc-urlbar.css @@ -41,7 +41,6 @@ toolbarpaletteitem[place="palette"] > #search-container { .widget-overflow-list #searchbar { box-shadow: none !important; - outline: none !important; min-height: var(--subviewbutton-height) !important; font-size: revert !important; } @@ -63,7 +62,7 @@ toolbarpaletteitem[place="palette"] > #search-container { } .widget-overflow-list #searchbar .searchbar-textbox { - min-height: unset !important; + min-height: var(--subviewbutton-height) !important; } .widget-overflow-list #searchbar .searchbar-textbox::placeholder { @@ -71,11 +70,16 @@ toolbarpaletteitem[place="palette"] > #search-container { color: var(--lwt-text-color) !important; } +.widget-overflow-list #searchbar .search-go-container { + -moz-box-pack: center !important; + -moz-box-align: center !important; +} + .widget-overflow-list #searchbar .search-go-button { box-sizing: border-box !important; - width: calc(var(--subviewbutton-height) - 2px) !important; - height: calc(var(--subviewbutton-height) - 2px) !important; - padding: calc((var(--subviewbutton-height) - 16px) / 2) !important; + width: calc(var(--subviewbutton-height) - 4px) !important; + height: calc(var(--subviewbutton-height) - 4px) !important; + padding: calc((var(--subviewbutton-height) - 16px - 2px) / 2) !important; } .widget-overflow-list #searchbar:not([disabled]) .searchbar-search-icon, @@ -103,10 +107,36 @@ toolbarpaletteitem[place="palette"] > #search-container { box-shadow: none !important; -moz-box-align: center; border-radius: var(--toolbarbutton-border-radius) !important; - outline: none !important; border: none !important; } +#searchbar { + outline: none !important; +} + +@supports -moz-bool-pref("userChrome.urlbar.focus-ring-enabled") { + #urlbar-input-container, + #searchbar { + outline: 0 solid transparent !important; + outline-offset: 0 !important; + transition: var(--textbox-outline-transition-duration, 100ms) outline ease-in !important; + } + + .widget-overflow-list #searchbar { + outline-offset: -2px !important; + } + + #urlbar[focused="true"] #urlbar-input-container, + #searchbar:focus-within { + outline-width: 2px !important; + outline-color: var(--search-box-focus-outline-color, -moz-accent-color) !important; + transition-duration: calc( + var(--textbox-outline-transition-duration, 100ms) * 0.6 + ) !important; + transition-timing-function: ease-out !important; + } +} + #urlbar-search-splitter { min-width: 12px !important; margin-inline: -7px !important;