summaryrefslogtreecommitdiffstats
path: root/browser/components/customizableui/PanelWideWidgetTracker.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/customizableui/PanelWideWidgetTracker.jsm')
-rw-r--r--browser/components/customizableui/PanelWideWidgetTracker.jsm172
1 files changed, 0 insertions, 172 deletions
diff --git a/browser/components/customizableui/PanelWideWidgetTracker.jsm b/browser/components/customizableui/PanelWideWidgetTracker.jsm
deleted file mode 100644
index 768cebbca..000000000
--- a/browser/components/customizableui/PanelWideWidgetTracker.jsm
+++ /dev/null
@@ -1,172 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-this.EXPORTED_SYMBOLS = ["PanelWideWidgetTracker"];
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
- "resource:///modules/CustomizableUI.jsm");
-
-var gPanel = CustomizableUI.AREA_PANEL;
-// We keep track of the widget placements for the panel locally:
-var gPanelPlacements = [];
-
-// All the wide widgets we know of:
-var gWideWidgets = new Set();
-// All the widgets we know of:
-var gSeenWidgets = new Set();
-
-var PanelWideWidgetTracker = {
- // Listeners used to validate panel contents whenever they change:
- onWidgetAdded: function(aWidgetId, aArea, aPosition) {
- if (aArea == gPanel) {
- gPanelPlacements = CustomizableUI.getWidgetIdsInArea(gPanel);
- let moveForward = this.shouldMoveForward(aWidgetId, aPosition);
- this.adjustWidgets(aWidgetId, moveForward);
- }
- },
- onWidgetMoved: function(aWidgetId, aArea, aOldPosition, aNewPosition) {
- if (aArea == gPanel) {
- gPanelPlacements = CustomizableUI.getWidgetIdsInArea(gPanel);
- let moveForward = this.shouldMoveForward(aWidgetId, aNewPosition);
- this.adjustWidgets(aWidgetId, moveForward);
- }
- },
- onWidgetRemoved: function(aWidgetId, aPrevArea) {
- if (aPrevArea == gPanel) {
- gPanelPlacements = CustomizableUI.getWidgetIdsInArea(gPanel);
- this.adjustWidgets(aWidgetId, false);
- }
- },
- onWidgetReset: function(aWidgetId) {
- gPanelPlacements = CustomizableUI.getWidgetIdsInArea(gPanel);
- },
- // Listener to keep abreast of any new nodes. We use the DOM one because
- // we need access to the actual node's classlist, so we can't use the ones above.
- // Furthermore, onWidgetCreated only fires for API-based widgets, not for XUL ones.
- onWidgetAfterDOMChange: function(aNode, aNextNode, aContainer) {
- if (!gSeenWidgets.has(aNode.id)) {
- if (aNode.classList.contains(CustomizableUI.WIDE_PANEL_CLASS)) {
- gWideWidgets.add(aNode.id);
- }
- gSeenWidgets.add(aNode.id);
- }
- },
- // When widgets get destroyed, we remove them from our sets of stuff we care about:
- onWidgetDestroyed: function(aWidgetId) {
- gSeenWidgets.delete(aWidgetId);
- gWideWidgets.delete(aWidgetId);
- },
- shouldMoveForward: function(aWidgetId, aPosition) {
- let currentWidgetAtPosition = gPanelPlacements[aPosition + 1];
- let rv = gWideWidgets.has(currentWidgetAtPosition) && !gWideWidgets.has(aWidgetId);
- // We might now think we can move forward, but for that we need at least 2 more small
- // widgets to be present:
- if (rv) {
- let furtherWidgets = gPanelPlacements.slice(aPosition + 2);
- let realWidgets = 0;
- if (furtherWidgets.length >= 2) {
- while (furtherWidgets.length && realWidgets < 2) {
- let w = furtherWidgets.shift();
- if (!gWideWidgets.has(w) && this.checkWidgetStatus(w)) {
- realWidgets++;
- }
- }
- }
- if (realWidgets < 2) {
- rv = false;
- }
- }
- return rv;
- },
- adjustWidgets: function(aWidgetId, aMoveForwards) {
- if (this.adjusting) {
- return;
- }
- this.adjusting = true;
- let widgetsAffected = gPanelPlacements.filter((w) => gWideWidgets.has(w));
- // If we're moving the wide widgets forwards (down/to the right in the panel)
- // we want to start with the last widgets. Otherwise we move widgets over other wide
- // widgets, which might mess up their order. Likewise, if moving backwards we should start with
- // the first widget and work our way down/right from there.
- let compareFn = aMoveForwards ? ((a, b) => a < b) : ((a, b) => a > b);
- widgetsAffected.sort((a, b) => compareFn(gPanelPlacements.indexOf(a),
- gPanelPlacements.indexOf(b)));
- for (let widget of widgetsAffected) {
- this.adjustPosition(widget, aMoveForwards);
- }
- this.adjusting = false;
- },
- // This function is called whenever an item gets moved in the menu panel. It
- // adjusts the position of widgets within the panel to prevent "gaps" between
- // wide widgets that could be filled up with single column widgets
- adjustPosition: function(aWidgetId, aMoveForwards) {
- // Make sure that there are n % columns = 0 narrow buttons before the widget.
- let placementIndex = gPanelPlacements.indexOf(aWidgetId);
- let prevSiblingCount = 0;
- let fixedPos = null;
- while (placementIndex--) {
- let thisWidgetId = gPanelPlacements[placementIndex];
- if (gWideWidgets.has(thisWidgetId)) {
- continue;
- }
- let widgetStatus = this.checkWidgetStatus(thisWidgetId);
- if (!widgetStatus) {
- continue;
- }
- if (widgetStatus == "public-only") {
- fixedPos = !fixedPos ? placementIndex : Math.min(fixedPos, placementIndex);
- prevSiblingCount = 0;
- } else {
- prevSiblingCount++;
- }
- }
-
- if (fixedPos !== null || prevSiblingCount % CustomizableUI.PANEL_COLUMN_COUNT) {
- let desiredPos = (fixedPos !== null) ? fixedPos : gPanelPlacements.indexOf(aWidgetId);
- let desiredChange = -(prevSiblingCount % CustomizableUI.PANEL_COLUMN_COUNT);
- if (aMoveForwards && fixedPos == null) {
- // +1 because otherwise we'd count ourselves:
- desiredChange = CustomizableUI.PANEL_COLUMN_COUNT + desiredChange + 1;
- }
- desiredPos += desiredChange;
- CustomizableUI.moveWidgetWithinArea(aWidgetId, desiredPos);
- }
- },
-
- /*
- * Check whether a widget id is actually known anywhere.
- * @returns false if the widget doesn't exist,
- * "public-only" if it's not shown in private windows
- * "real" if it does exist and is shown even in private windows
- */
- checkWidgetStatus: function(aWidgetId) {
- let widgetWrapper = CustomizableUI.getWidget(aWidgetId);
- // This widget might not actually exist:
- if (!widgetWrapper) {
- return false;
- }
- // This widget might still not actually exist:
- if (widgetWrapper.provider == CustomizableUI.PROVIDER_XUL &&
- widgetWrapper.instances.length == 0) {
- return false;
- }
-
- // Or it might only be there some of the time:
- if (widgetWrapper.provider == CustomizableUI.PROVIDER_API &&
- widgetWrapper.showInPrivateBrowsing === false) {
- return "public-only";
- }
- return "real";
- },
-
- init: function() {
- // Initialize our local placements copy and register the listener
- gPanelPlacements = CustomizableUI.getWidgetIdsInArea(gPanel);
- CustomizableUI.addListener(this);
- },
-};