SearchWidgetTracker.sys.mjs (3516B)
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 import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; 6 import { CustomizableUI } from "moz-src:///browser/components/customizableui/CustomizableUI.sys.mjs"; 7 8 const WIDGET_ID = "search-container"; 9 10 /** 11 * Updates persisted widths when the search bar is removed from any 12 * customizable area and put into the palette. Also automatically removes the 13 * search bar if it has not been used in a long time. 14 */ 15 export const SearchWidgetTracker = { 16 /** 17 * Main entrypoint to initializing the SearchWidgetTracker. 18 */ 19 init() { 20 CustomizableUI.addListener(this); 21 this._updateSearchBarVisibilityBasedOnUsage(); 22 }, 23 24 /** 25 * The callback for when a widget is moved via CustomizableUI. We use this 26 * to detect movement of the search bar. 27 * 28 * @param {Element} node 29 * The DOM node that was acted upon. 30 * @param {Element|null} _nextNode 31 * The DOM node (if any) that the widget was inserted before. 32 * @param {Element} _container 33 * The *actual* DOM container for the widget (could be an overflow panel in 34 * case of an overflowable toolbar). 35 * @param {boolean} wasRemoval 36 * True iff the action that happened was the removal of the DOM node. 37 */ 38 onWidgetAfterDOMChange(node, _nextNode, _container, wasRemoval) { 39 if (wasRemoval && node.id == WIDGET_ID) { 40 this.removePersistedWidths(); 41 } 42 }, 43 44 /** 45 * If the search bar is in the navigation toolbar, this method will check 46 * the lastUsed preference to see when the last time the search bar was 47 * actually used. If the number of days since it was last used exceeds a 48 * certain threshold, the widget is moved back into the customization 49 * palette. 50 */ 51 _updateSearchBarVisibilityBasedOnUsage() { 52 if (!this._widgetIsInNavBar) { 53 return; 54 } 55 let searchBarLastUsed = Services.prefs.getStringPref( 56 "browser.search.widget.lastUsed", 57 "" 58 ); 59 if (searchBarLastUsed) { 60 const removeAfterDaysUnused = Services.prefs.getIntPref( 61 "browser.search.widget.removeAfterDaysUnused" 62 ); 63 let saerchBarUnusedThreshold = 64 removeAfterDaysUnused * 24 * 60 * 60 * 1000; 65 if (new Date() - new Date(searchBarLastUsed) > saerchBarUnusedThreshold) { 66 CustomizableUI.removeWidgetFromArea(WIDGET_ID); 67 } 68 } 69 }, 70 71 /** 72 * Removes any widget customization on the search bar (which can be created 73 * with the resizer that appears if the search bar is placed immediately after 74 * the URL bar). Goes through each open browser window and removes the width 75 * property / style on each existant search bar. 76 */ 77 removePersistedWidths() { 78 Services.xulStore.removeValue( 79 AppConstants.BROWSER_CHROME_URL, 80 WIDGET_ID, 81 "width" 82 ); 83 for (let win of CustomizableUI.windows) { 84 let searchbar = 85 win.document.getElementById(WIDGET_ID) || 86 win.gNavToolbox.palette.querySelector("#" + WIDGET_ID); 87 searchbar.removeAttribute("width"); 88 searchbar.style.removeProperty("width"); 89 } 90 }, 91 92 /** 93 * True if the search bar is currently in the navigation toolbar area. 94 * 95 * @type {boolean} 96 */ 97 get _widgetIsInNavBar() { 98 let placement = CustomizableUI.getPlacementOfWidget(WIDGET_ID); 99 return placement?.area == CustomizableUI.AREA_NAVBAR; 100 }, 101 };