зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1123517 - Refactor sidebar code. r=florian
--HG-- extra : transplant_source : %04%FAZ%B3%DD%EB%8C%28%9Bj%CB%B3%D1%89%D9AJ%22%08%C6
This commit is contained in:
Родитель
5717dba3fe
Коммит
40d4ef0e6c
|
@ -138,7 +138,7 @@
|
|||
<broadcaster id="Social:PageShareOrMark" disabled="true"/>
|
||||
<broadcaster id="viewBookmarksSidebar" autoCheck="false" label="&bookmarksButton.label;"
|
||||
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/bookmarks/bookmarksPanel.xul"
|
||||
oncommand="toggleSidebar('viewBookmarksSidebar');"/>
|
||||
oncommand="SidebarUI.toggle('viewBookmarksSidebar');"/>
|
||||
|
||||
<!-- for both places and non-places, the sidebar lives at
|
||||
chrome://browser/content/history/history-panel.xul so there are no
|
||||
|
@ -146,11 +146,11 @@
|
|||
<broadcaster id="viewHistorySidebar" autoCheck="false" sidebartitle="&historyButton.label;"
|
||||
type="checkbox" group="sidebar"
|
||||
sidebarurl="chrome://browser/content/history/history-panel.xul"
|
||||
oncommand="toggleSidebar('viewHistorySidebar');"/>
|
||||
oncommand="SidebarUI.toggle('viewHistorySidebar');"/>
|
||||
|
||||
<broadcaster id="viewWebPanelsSidebar" autoCheck="false"
|
||||
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/web-panels.xul"
|
||||
oncommand="toggleSidebar('viewWebPanelsSidebar');"/>
|
||||
oncommand="SidebarUI.toggle('viewWebPanelsSidebar');"/>
|
||||
|
||||
<broadcaster id="bookmarkThisPageBroadcaster"
|
||||
label="&bookmarkThisPageCmd.label;"
|
||||
|
|
|
@ -0,0 +1,309 @@
|
|||
# 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/.
|
||||
|
||||
/**
|
||||
* SidebarUI controls showing and hiding the browser sidebar.
|
||||
*
|
||||
* @note
|
||||
* Some of these methods take a commandID argument - we expect to find a
|
||||
* xul:broadcaster element with the specified ID.
|
||||
* The following attributes on that element may be used and/or modified:
|
||||
* - id (required) the string to match commandID. The convention
|
||||
* is to use this naming scheme: 'view<sidebar-name>Sidebar'.
|
||||
* - sidebarurl (required) specifies the URL to load in this sidebar.
|
||||
* - sidebartitle or label (in that order) specify the title to
|
||||
* display on the sidebar.
|
||||
* - checked indicates whether the sidebar is currently displayed.
|
||||
* Note that toggleSidebar updates this attribute when
|
||||
* it changes the sidebar's visibility.
|
||||
* - group this attribute must be set to "sidebar".
|
||||
*/
|
||||
let SidebarUI = {
|
||||
browser: null,
|
||||
|
||||
_box: null,
|
||||
_title: null,
|
||||
_splitter: null,
|
||||
|
||||
init() {
|
||||
this._box = document.getElementById("sidebar-box");
|
||||
this.browser = document.getElementById("sidebar");
|
||||
this._title = document.getElementById("sidebar-title");
|
||||
this._splitter = document.getElementById("sidebar-splitter");
|
||||
|
||||
if (window.opener && !window.opener.closed &&
|
||||
window.opener.document.documentURIObject.schemeIs("chrome") &&
|
||||
PrivateBrowsingUtils.isWindowPrivate(window) == PrivateBrowsingUtils.isWindowPrivate(window.opener)) {
|
||||
this.adoptFromWindow(window.opener);
|
||||
} else {
|
||||
let commandID = this._box.getAttribute("sidebarcommand");
|
||||
if (commandID) {
|
||||
let command = document.getElementById(commandID);
|
||||
if (command) {
|
||||
this._delayedLoad = true;
|
||||
this._box.hidden = false;
|
||||
this._splitter.hidden = false;
|
||||
command.setAttribute("checked", "true");
|
||||
} else {
|
||||
// Remove the |sidebarcommand| attribute, because the element it
|
||||
// refers to no longer exists, so we should assume this sidebar
|
||||
// panel has been uninstalled. (249883)
|
||||
this._box.removeAttribute("sidebarcommand");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
uninit() {
|
||||
let enumerator = Services.wm.getEnumerator(null);
|
||||
enumerator.getNext();
|
||||
if (!enumerator.hasMoreElements()) {
|
||||
document.persist("sidebar-box", "sidebarcommand");
|
||||
document.persist("sidebar-box", "width");
|
||||
document.persist("sidebar-box", "src");
|
||||
document.persist("sidebar-title", "value");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adopt the status of the sidebar from another window.
|
||||
* @param {Window} sourceWindow - Window to use as a source for sidebar status.
|
||||
*/
|
||||
adoptFromWindow(sourceWindow) {
|
||||
// If the opener had a sidebar, open the same sidebar in our window.
|
||||
// The opener can be the hidden window too, if we're coming from the state
|
||||
// where no windows are open, and the hidden window has no sidebar box.
|
||||
let sourceUI = sourceWindow.SidebarUI;
|
||||
if (!sourceUI || sourceUI._box.hidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
let commandID = sourceUI._box.getAttribute("sidebarcommand");
|
||||
let commandElem = document.getElementById(commandID);
|
||||
|
||||
// dynamically generated sidebars will fail this check.
|
||||
if (!commandElem) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._title.setAttribute("value",
|
||||
sourceUI._title.getAttribute("value"));
|
||||
this._box.setAttribute("width", sourceUI._box.boxObject.width);
|
||||
|
||||
this._box.setAttribute("sidebarcommand", commandID);
|
||||
// Note: we're setting 'src' on this._box, which is a <vbox>, not on
|
||||
// the <browser id="sidebar">. This lets us delay the actual load until
|
||||
// delayedStartup().
|
||||
this._box.setAttribute("src", sourceUI.browser.getAttribute("src"));
|
||||
this._delayedLoad = true;
|
||||
|
||||
this._box.hidden = false;
|
||||
this._splitter.hidden = false;
|
||||
commandElem.setAttribute("checked", "true");
|
||||
},
|
||||
|
||||
/**
|
||||
* If loading a sidebar was delayed on startup, start the load now.
|
||||
*/
|
||||
startDelayedLoad() {
|
||||
if (!this._delayedLoad) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.browser.setAttribute("src", this._box.getAttribute("src"));
|
||||
},
|
||||
|
||||
/**
|
||||
* Fire a "SidebarFocused" event on the sidebar's |window| to give the sidebar
|
||||
* a chance to adjust focus as needed. An additional event is needed, because
|
||||
* we don't want to focus the sidebar when it's opened on startup or in a new
|
||||
* window, only when the user opens the sidebar.
|
||||
*/
|
||||
_fireFocusedEvent() {
|
||||
let event = new CustomEvent("SidebarFocused", {bubbles: true});
|
||||
this.browser.contentWindow.dispatchEvent(event);
|
||||
|
||||
// Run the original function for backwards compatibility.
|
||||
fireSidebarFocusedEvent();
|
||||
},
|
||||
|
||||
/**
|
||||
* True if the sidebar is currently open.
|
||||
*/
|
||||
get isOpen() {
|
||||
return !this._box.hidden;
|
||||
},
|
||||
|
||||
/**
|
||||
* The ID of the current sidebar (ie, the ID of the broadcaster being used).
|
||||
* This can be set even if the sidebar is hidden.
|
||||
*/
|
||||
get currentID() {
|
||||
return this._box.getAttribute("sidebarcommand");
|
||||
},
|
||||
|
||||
get title() {
|
||||
return this._title.value;
|
||||
},
|
||||
|
||||
set title(value) {
|
||||
this._title.value = value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle the visibility of the sidebar. If the sidebar is hidden or is open
|
||||
* with a different commandID, then the sidebar will be opened using the
|
||||
* specified commandID. Otherwise the sidebar will be hidden.
|
||||
*
|
||||
* @param {string} commandID ID of the xul:broadcaster element to use.
|
||||
* @return {Promise}
|
||||
*/
|
||||
toggle(commandID = this.currentID) {
|
||||
if (this.isOpen && commandID == this.currentID) {
|
||||
this.hide();
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return this.show(commandID);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the sidebar, using the parameters from the specified broadcaster.
|
||||
* @see SidebarUI note.
|
||||
*
|
||||
* @param {string} commandID ID of the xul:broadcaster element to use.
|
||||
*/
|
||||
show(commandID) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let sidebarBroadcaster = document.getElementById(commandID);
|
||||
if (!sidebarBroadcaster || sidebarBroadcaster.localName != "broadcaster") {
|
||||
reject(new Error("Invalid sidebar broadcaster specified"));
|
||||
return;
|
||||
}
|
||||
|
||||
let broadcasters = document.getElementsByAttribute("group", "sidebar");
|
||||
for (let broadcaster of broadcasters) {
|
||||
// skip elements that observe sidebar broadcasters and random
|
||||
// other elements
|
||||
if (broadcaster.localName != "broadcaster") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (broadcaster != sidebarBroadcaster) {
|
||||
broadcaster.removeAttribute("checked");
|
||||
} else {
|
||||
sidebarBroadcaster.setAttribute("checked", "true");
|
||||
}
|
||||
}
|
||||
|
||||
this._box.hidden = false;
|
||||
this._splitter.hidden = false;
|
||||
|
||||
this._box.setAttribute("sidebarcommand", sidebarBroadcaster.id);
|
||||
|
||||
let title = sidebarBroadcaster.getAttribute("sidebartitle");
|
||||
if (!title) {
|
||||
title = sidebarBroadcaster.getAttribute("label");
|
||||
}
|
||||
this._title.value = title;
|
||||
|
||||
let url = sidebarBroadcaster.getAttribute("sidebarurl");
|
||||
this.browser.setAttribute("src", url); // kick off async load
|
||||
|
||||
// We set this attribute here in addition to setting it on the <browser>
|
||||
// element itself, because the code in SidebarUI.uninit() persists this
|
||||
// attribute, not the "src" of the <browser id="sidebar">. The reason it
|
||||
// does that is that we want to delay sidebar load a bit when a browser
|
||||
// window opens. See delayedStartup() and SidebarUI.startDelayedLoad().
|
||||
this._box.setAttribute("src", url);
|
||||
|
||||
if (this.browser.contentDocument.location.href != url) {
|
||||
let onLoad = event => {
|
||||
this.browser.removeEventListener("load", onLoad, true);
|
||||
|
||||
// We're handling the 'load' event before it bubbles up to the usual
|
||||
// (non-capturing) event handlers. Let it bubble up before firing the
|
||||
// SidebarFocused event.
|
||||
setTimeout(() => this._fireFocusedEvent(), 0);
|
||||
|
||||
// Run the original function for backwards compatibility.
|
||||
sidebarOnLoad(event);
|
||||
|
||||
resolve();
|
||||
};
|
||||
|
||||
this.browser.addEventListener("load", onLoad, true);
|
||||
} else {
|
||||
// Older code handled this case, so we do it too.
|
||||
this._fireFocusedEvent();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the sidebar.
|
||||
*/
|
||||
hide() {
|
||||
if (!this.isOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
let commandID = this._box.getAttribute("sidebarcommand");
|
||||
let sidebarBroadcaster = document.getElementById(commandID);
|
||||
|
||||
if (sidebarBroadcaster.getAttribute("checked") != "true") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Replace the document currently displayed in the sidebar with about:blank
|
||||
// so that we can free memory by unloading the page. We need to explicitly
|
||||
// create a new content viewer because the old one doesn't get destroyed
|
||||
// until about:blank has loaded (which does not happen as long as the
|
||||
// element is hidden).
|
||||
this.browser.setAttribute("src", "about:blank");
|
||||
this.browser.docShell.createAboutBlankContentViewer(null);
|
||||
|
||||
sidebarBroadcaster.removeAttribute("checked");
|
||||
this._box.setAttribute("sidebarcommand", "");
|
||||
this._title.value = "";
|
||||
this._box.hidden = true;
|
||||
this._splitter.hidden = true;
|
||||
gBrowser.selectedBrowser.focus();
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* This exists for backards compatibility - it will be called once a sidebar is
|
||||
* ready, following any request to show it.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
function fireSidebarFocusedEvent() {}
|
||||
|
||||
/**
|
||||
* This exists for backards compatibility - it gets called when a sidebar has
|
||||
* been loaded.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
function sidebarOnLoad(event) {}
|
||||
|
||||
/**
|
||||
* This exists for backards compatibility, and is equivilent to
|
||||
* SidebarUI.toggle() without the forceOpen param. With forceOpen set to true,
|
||||
* it is equalivent to SidebarUI.show().
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
function toggleSidebar(commandID, forceOpen = false) {
|
||||
Deprecated.warning("toggleSidebar() is deprecated, please use SidebarUI.toggle() or SidebarUI.show() instead",
|
||||
"https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Sidebar");
|
||||
|
||||
if (forceOpen) {
|
||||
SidebarUI.show(commandID);
|
||||
} else {
|
||||
SidebarUI.toggle(commandID);
|
||||
}
|
||||
}
|
|
@ -12,6 +12,9 @@ Cu.import("resource://gre/modules/NotificationDB.jsm");
|
|||
Cu.import("resource:///modules/RecentWindow.jsm");
|
||||
Cu.import("resource://gre/modules/WindowsPrefSync.jsm");
|
||||
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
|
||||
"resource://gre/modules/Deprecated.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
|
||||
"resource:///modules/BrowserUITelemetry.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
|
||||
|
@ -223,6 +226,7 @@ let gInitialPages = [
|
|||
#include browser-places.js
|
||||
#include browser-plugins.js
|
||||
#include browser-safebrowsing.js
|
||||
#include browser-sidebar.js
|
||||
#include browser-social.js
|
||||
#include browser-tabview.js
|
||||
#include browser-thumbnails.js
|
||||
|
@ -899,8 +903,6 @@ var gBrowserInit = {
|
|||
delayedStartupFinished: false,
|
||||
|
||||
onLoad: function() {
|
||||
var mustLoadSidebar = false;
|
||||
|
||||
gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
|
||||
|
||||
Services.obs.addObserver(gPluginHandler.pluginCrashed, "plugin-crashed", false);
|
||||
|
@ -952,61 +954,7 @@ var gBrowserInit = {
|
|||
// setup history swipe animation
|
||||
gHistorySwipeAnimation.init();
|
||||
|
||||
if (window.opener && !window.opener.closed &&
|
||||
window.opener.document.documentURIObject.schemeIs("chrome") &&
|
||||
PrivateBrowsingUtils.isWindowPrivate(window) == PrivateBrowsingUtils.isWindowPrivate(window.opener)) {
|
||||
let openerSidebarBox = window.opener.document.getElementById("sidebar-box");
|
||||
// If the opener had a sidebar, open the same sidebar in our window.
|
||||
// The opener can be the hidden window too, if we're coming from the state
|
||||
// where no windows are open, and the hidden window has no sidebar box.
|
||||
if (openerSidebarBox && !openerSidebarBox.hidden) {
|
||||
let sidebarCmd = openerSidebarBox.getAttribute("sidebarcommand");
|
||||
let sidebarCmdElem = document.getElementById(sidebarCmd);
|
||||
|
||||
// dynamically generated sidebars will fail this check.
|
||||
if (sidebarCmdElem) {
|
||||
let sidebarBox = document.getElementById("sidebar-box");
|
||||
let sidebarTitle = document.getElementById("sidebar-title");
|
||||
|
||||
sidebarTitle.setAttribute(
|
||||
"value", window.opener.document.getElementById("sidebar-title").getAttribute("value"));
|
||||
sidebarBox.setAttribute("width", openerSidebarBox.boxObject.width);
|
||||
|
||||
sidebarBox.setAttribute("sidebarcommand", sidebarCmd);
|
||||
// Note: we're setting 'src' on sidebarBox, which is a <vbox>, not on
|
||||
// the <browser id="sidebar">. This lets us delay the actual load until
|
||||
// delayedStartup().
|
||||
sidebarBox.setAttribute(
|
||||
"src", window.opener.document.getElementById("sidebar").getAttribute("src"));
|
||||
mustLoadSidebar = true;
|
||||
|
||||
sidebarBox.hidden = false;
|
||||
document.getElementById("sidebar-splitter").hidden = false;
|
||||
sidebarCmdElem.setAttribute("checked", "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
let box = document.getElementById("sidebar-box");
|
||||
if (box.hasAttribute("sidebarcommand")) {
|
||||
let commandID = box.getAttribute("sidebarcommand");
|
||||
if (commandID) {
|
||||
let command = document.getElementById(commandID);
|
||||
if (command) {
|
||||
mustLoadSidebar = true;
|
||||
box.hidden = false;
|
||||
document.getElementById("sidebar-splitter").hidden = false;
|
||||
command.setAttribute("checked", "true");
|
||||
}
|
||||
else {
|
||||
// Remove the |sidebarcommand| attribute, because the element it
|
||||
// refers to no longer exists, so we should assume this sidebar
|
||||
// panel has been uninstalled. (249883)
|
||||
box.removeAttribute("sidebarcommand");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SidebarUI.init();
|
||||
|
||||
// Certain kinds of automigration rely on this notification to complete
|
||||
// their tasks BEFORE the browser window is shown. SessionStore uses it to
|
||||
|
@ -1095,7 +1043,7 @@ var gBrowserInit = {
|
|||
ToolbarIconColor.init();
|
||||
|
||||
// Wait until chrome is painted before executing code not critical to making the window visible
|
||||
this._boundDelayedStartup = this._delayedStartup.bind(this, mustLoadSidebar);
|
||||
this._boundDelayedStartup = this._delayedStartup.bind(this);
|
||||
window.addEventListener("MozAfterPaint", this._boundDelayedStartup);
|
||||
|
||||
this._loadHandled = true;
|
||||
|
@ -1106,7 +1054,7 @@ var gBrowserInit = {
|
|||
this._boundDelayedStartup = null;
|
||||
},
|
||||
|
||||
_delayedStartup: function(mustLoadSidebar) {
|
||||
_delayedStartup: function() {
|
||||
let tmp = {};
|
||||
Cu.import("resource://gre/modules/TelemetryTimestamps.jsm", tmp);
|
||||
let TelemetryTimestamps = tmp.TelemetryTimestamps;
|
||||
|
@ -1269,11 +1217,7 @@ var gBrowserInit = {
|
|||
|
||||
Services.telemetry.getHistogramById("E10S_WINDOW").add(gMultiProcessBrowser);
|
||||
|
||||
if (mustLoadSidebar) {
|
||||
let sidebar = document.getElementById("sidebar");
|
||||
let sidebarBox = document.getElementById("sidebar-box");
|
||||
sidebar.setAttribute("src", sidebarBox.getAttribute("src"));
|
||||
}
|
||||
SidebarUI.startDelayedLoad();
|
||||
|
||||
UpdateUrlbarSearchSplitterState();
|
||||
|
||||
|
@ -1535,14 +1479,7 @@ var gBrowserInit = {
|
|||
|
||||
gMenuButtonUpdateBadge.uninit();
|
||||
|
||||
var enumerator = Services.wm.getEnumerator(null);
|
||||
enumerator.getNext();
|
||||
if (!enumerator.hasMoreElements()) {
|
||||
document.persist("sidebar-box", "sidebarcommand");
|
||||
document.persist("sidebar-box", "width");
|
||||
document.persist("sidebar-box", "src");
|
||||
document.persist("sidebar-title", "value");
|
||||
}
|
||||
SidebarUI.uninit();
|
||||
|
||||
// Now either cancel delayedStartup, or clean up the services initialized from
|
||||
// it.
|
||||
|
@ -1769,7 +1706,7 @@ function HandleAppCommandEvent(evt) {
|
|||
BrowserSearch.webSearch();
|
||||
break;
|
||||
case "Bookmarks":
|
||||
toggleSidebar('viewBookmarksSidebar');
|
||||
SidebarUI.toggle("viewBookmarksSidebar");
|
||||
break;
|
||||
case "Home":
|
||||
BrowserHome();
|
||||
|
@ -3139,23 +3076,19 @@ var PrintPreviewListener = {
|
|||
else
|
||||
this._showChrome();
|
||||
|
||||
if (this._chromeState.sidebarOpen)
|
||||
toggleSidebar(this._sidebarCommand);
|
||||
|
||||
TabsInTitlebar.allowedBy("print-preview", !gInPrintPreviewMode);
|
||||
},
|
||||
_hideChrome: function () {
|
||||
this._chromeState = {};
|
||||
|
||||
var sidebar = document.getElementById("sidebar-box");
|
||||
this._chromeState.sidebarOpen = !sidebar.hidden;
|
||||
this._sidebarCommand = sidebar.getAttribute("sidebarcommand");
|
||||
this._chromeState.sidebarOpen = SidebarUI.isOpen;
|
||||
this._sidebarCommand = SidebarUI.currentID;
|
||||
SidebarUI.hide();
|
||||
|
||||
var notificationBox = gBrowser.getNotificationBox();
|
||||
this._chromeState.notificationsOpen = !notificationBox.notificationsHidden;
|
||||
notificationBox.notificationsHidden = true;
|
||||
|
||||
document.getElementById("sidebar").setAttribute("src", "about:blank");
|
||||
gBrowser.updateWindowResizers();
|
||||
|
||||
this._chromeState.findOpen = gFindBarInitialized && !gFindBar.hidden;
|
||||
|
@ -3185,6 +3118,9 @@ var PrintPreviewListener = {
|
|||
|
||||
if (this._chromeState.syncNotificationsOpen)
|
||||
document.getElementById("sync-notifications").notificationsHidden = false;
|
||||
|
||||
if (this._chromeState.sidebarOpen)
|
||||
SidebarUI.show(this._sidebarCommand);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5213,121 +5149,6 @@ function displaySecurityInfo()
|
|||
BrowserPageInfo(null, "securityTab");
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens or closes the sidebar identified by commandID.
|
||||
*
|
||||
* @param commandID a string identifying the sidebar to toggle; see the
|
||||
* note below. (Optional if a sidebar is already open.)
|
||||
* @param forceOpen boolean indicating whether the sidebar should be
|
||||
* opened regardless of its current state (optional).
|
||||
* @note
|
||||
* We expect to find a xul:broadcaster element with the specified ID.
|
||||
* The following attributes on that element may be used and/or modified:
|
||||
* - id (required) the string to match commandID. The convention
|
||||
* is to use this naming scheme: 'view<sidebar-name>Sidebar'.
|
||||
* - sidebarurl (required) specifies the URL to load in this sidebar.
|
||||
* - sidebartitle or label (in that order) specify the title to
|
||||
* display on the sidebar.
|
||||
* - checked indicates whether the sidebar is currently displayed.
|
||||
* Note that toggleSidebar updates this attribute when
|
||||
* it changes the sidebar's visibility.
|
||||
* - group this attribute must be set to "sidebar".
|
||||
*/
|
||||
function toggleSidebar(commandID, forceOpen) {
|
||||
|
||||
var sidebarBox = document.getElementById("sidebar-box");
|
||||
if (!commandID)
|
||||
commandID = sidebarBox.getAttribute("sidebarcommand");
|
||||
|
||||
var sidebarBroadcaster = document.getElementById(commandID);
|
||||
var sidebar = document.getElementById("sidebar"); // xul:browser
|
||||
var sidebarTitle = document.getElementById("sidebar-title");
|
||||
var sidebarSplitter = document.getElementById("sidebar-splitter");
|
||||
|
||||
if (sidebarBroadcaster.getAttribute("checked") == "true") {
|
||||
if (!forceOpen) {
|
||||
// Replace the document currently displayed in the sidebar with about:blank
|
||||
// so that we can free memory by unloading the page. We need to explicitly
|
||||
// create a new content viewer because the old one doesn't get destroyed
|
||||
// until about:blank has loaded (which does not happen as long as the
|
||||
// element is hidden).
|
||||
sidebar.setAttribute("src", "about:blank");
|
||||
sidebar.docShell.createAboutBlankContentViewer(null);
|
||||
|
||||
sidebarBroadcaster.removeAttribute("checked");
|
||||
sidebarBox.setAttribute("sidebarcommand", "");
|
||||
sidebarTitle.value = "";
|
||||
sidebarBox.hidden = true;
|
||||
sidebarSplitter.hidden = true;
|
||||
gBrowser.selectedBrowser.focus();
|
||||
} else {
|
||||
fireSidebarFocusedEvent();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// now we need to show the specified sidebar
|
||||
|
||||
// ..but first update the 'checked' state of all sidebar broadcasters
|
||||
var broadcasters = document.getElementsByAttribute("group", "sidebar");
|
||||
for (let broadcaster of broadcasters) {
|
||||
// skip elements that observe sidebar broadcasters and random
|
||||
// other elements
|
||||
if (broadcaster.localName != "broadcaster")
|
||||
continue;
|
||||
|
||||
if (broadcaster != sidebarBroadcaster)
|
||||
broadcaster.removeAttribute("checked");
|
||||
else
|
||||
sidebarBroadcaster.setAttribute("checked", "true");
|
||||
}
|
||||
|
||||
sidebarBox.hidden = false;
|
||||
sidebarSplitter.hidden = false;
|
||||
|
||||
var url = sidebarBroadcaster.getAttribute("sidebarurl");
|
||||
var title = sidebarBroadcaster.getAttribute("sidebartitle");
|
||||
if (!title)
|
||||
title = sidebarBroadcaster.getAttribute("label");
|
||||
sidebar.setAttribute("src", url); // kick off async load
|
||||
sidebarBox.setAttribute("sidebarcommand", sidebarBroadcaster.id);
|
||||
sidebarTitle.value = title;
|
||||
|
||||
// We set this attribute here in addition to setting it on the <browser>
|
||||
// element itself, because the code in gBrowserInit.onUnload persists this
|
||||
// attribute, not the "src" of the <browser id="sidebar">. The reason it
|
||||
// does that is that we want to delay sidebar load a bit when a browser
|
||||
// window opens. See delayedStartup().
|
||||
sidebarBox.setAttribute("src", url);
|
||||
|
||||
if (sidebar.contentDocument.location.href != url)
|
||||
sidebar.addEventListener("load", sidebarOnLoad, true);
|
||||
else // older code handled this case, so we do it too
|
||||
fireSidebarFocusedEvent();
|
||||
}
|
||||
|
||||
function sidebarOnLoad(event) {
|
||||
var sidebar = document.getElementById("sidebar");
|
||||
sidebar.removeEventListener("load", sidebarOnLoad, true);
|
||||
// We're handling the 'load' event before it bubbles up to the usual
|
||||
// (non-capturing) event handlers. Let it bubble up before firing the
|
||||
// SidebarFocused event.
|
||||
setTimeout(fireSidebarFocusedEvent, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire a "SidebarFocused" event on the sidebar's |window| to give the sidebar
|
||||
* a chance to adjust focus as needed. An additional event is needed, because
|
||||
* we don't want to focus the sidebar when it's opened on startup or in a new
|
||||
* window, only when the user opens the sidebar.
|
||||
*/
|
||||
function fireSidebarFocusedEvent() {
|
||||
var sidebar = document.getElementById("sidebar");
|
||||
var event = document.createEvent("Events");
|
||||
event.initEvent("SidebarFocused", true, false);
|
||||
sidebar.contentWindow.dispatchEvent(event);
|
||||
}
|
||||
|
||||
|
||||
var gHomeButton = {
|
||||
prefDomain: "browser.startup.homepage",
|
||||
|
@ -5474,38 +5295,37 @@ function getBrowserSelection(aCharLen) {
|
|||
}
|
||||
|
||||
var gWebPanelURI;
|
||||
function openWebPanel(aTitle, aURI)
|
||||
{
|
||||
// Ensure that the web panels sidebar is open.
|
||||
toggleSidebar('viewWebPanelsSidebar', true);
|
||||
function openWebPanel(title, uri) {
|
||||
// Ensure that the web panels sidebar is open.
|
||||
SidebarUI.show("viewWebPanelsSidebar");
|
||||
|
||||
// Set the title of the panel.
|
||||
document.getElementById("sidebar-title").value = aTitle;
|
||||
// Set the title of the panel.
|
||||
SidebarUI.title = title;
|
||||
|
||||
// Tell the Web Panels sidebar to load the bookmark.
|
||||
var sidebar = document.getElementById("sidebar");
|
||||
if (sidebar.docShell && sidebar.contentDocument && sidebar.contentDocument.getElementById('web-panels-browser')) {
|
||||
sidebar.contentWindow.loadWebPanel(aURI);
|
||||
if (gWebPanelURI) {
|
||||
gWebPanelURI = "";
|
||||
sidebar.removeEventListener("load", asyncOpenWebPanel, true);
|
||||
}
|
||||
// Tell the Web Panels sidebar to load the bookmark.
|
||||
if (SidebarUI.browser.docShell && SidebarUI.browser.contentDocument &&
|
||||
SidebarUI.browser.contentDocument.getElementById("web-panels-browser")) {
|
||||
SidebarUI.browser.contentWindow.loadWebPanel(uri);
|
||||
if (gWebPanelURI) {
|
||||
gWebPanelURI = "";
|
||||
SidebarUI.browser.removeEventListener("load", asyncOpenWebPanel, true);
|
||||
}
|
||||
else {
|
||||
// The panel is still being constructed. Attach an onload handler.
|
||||
if (!gWebPanelURI)
|
||||
sidebar.addEventListener("load", asyncOpenWebPanel, true);
|
||||
gWebPanelURI = aURI;
|
||||
} else {
|
||||
// The panel is still being constructed. Attach an onload handler.
|
||||
if (!gWebPanelURI) {
|
||||
SidebarUI.browser.addEventListener("load", asyncOpenWebPanel, true);
|
||||
}
|
||||
gWebPanelURI = uri;
|
||||
}
|
||||
}
|
||||
|
||||
function asyncOpenWebPanel(event)
|
||||
{
|
||||
var sidebar = document.getElementById("sidebar");
|
||||
if (gWebPanelURI && sidebar.contentDocument && sidebar.contentDocument.getElementById('web-panels-browser'))
|
||||
sidebar.contentWindow.loadWebPanel(gWebPanelURI);
|
||||
gWebPanelURI = "";
|
||||
sidebar.removeEventListener("load", asyncOpenWebPanel, true);
|
||||
function asyncOpenWebPanel(event) {
|
||||
if (gWebPanelURI && SidebarUI.browser.contentDocument &&
|
||||
SidebarUI.browser.contentDocument.getElementById("web-panels-browser")) {
|
||||
SidebarUI.browser.contentWindow.loadWebPanel(gWebPanelURI);
|
||||
}
|
||||
gWebPanelURI = "";
|
||||
SidebarUI.browser.removeEventListener("load", asyncOpenWebPanel, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -885,7 +885,7 @@
|
|||
class="subviewbutton"
|
||||
label="&viewBookmarksSidebar2.label;"
|
||||
type="checkbox"
|
||||
oncommand="toggleSidebar('viewBookmarksSidebar');">
|
||||
oncommand="SidebarUI.toggle('viewBookmarksSidebar');">
|
||||
<observes element="viewBookmarksSidebar" attribute="checked"/>
|
||||
</menuitem>
|
||||
<!-- NB: temporary solution for bug 985024, this should go away soon. -->
|
||||
|
@ -1138,7 +1138,7 @@
|
|||
<sidebarheader id="sidebar-header" align="center">
|
||||
<label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
|
||||
<image id="sidebar-throbber"/>
|
||||
<toolbarbutton class="close-icon tabbable" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="toggleSidebar();"/>
|
||||
<toolbarbutton class="close-icon tabbable" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="SidebarUI.hide();"/>
|
||||
</sidebarheader>
|
||||
<browser id="sidebar" flex="1" autoscroll="false" disablehistory="true"
|
||||
style="min-width: 14em; width: 18em; max-width: 36em;"/>
|
||||
|
|
|
@ -4,7 +4,7 @@ function test() {
|
|||
// XXX This looks a bit odd, but is needed to avoid throwing when removing the
|
||||
// event listeners below. See bug 310955.
|
||||
document.getElementById("sidebar").addEventListener("load", delayedOpenUrl, true);
|
||||
toggleSidebar("viewWebPanelsSidebar", true);
|
||||
SidebarUI.show("viewWebPanelsSidebar");
|
||||
}
|
||||
|
||||
function delayedOpenUrl() {
|
||||
|
@ -75,7 +75,7 @@ function contextMenuClosed()
|
|||
var sidebar = document.getElementById("sidebar");
|
||||
sidebar.contentDocument.removeEventListener("popuphidden", contextMenuClosed, false);
|
||||
|
||||
toggleSidebar("viewWebPanelsSidebar");
|
||||
SidebarUI.hide();
|
||||
|
||||
ok(document.getElementById("sidebar-box").hidden, "Sidebar successfully hidden");
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
type="checkbox"
|
||||
class="subviewbutton"
|
||||
key="key_gotoHistory"
|
||||
oncommand="toggleSidebar('viewHistorySidebar'); PanelUI.hide();">
|
||||
oncommand="SidebarUI.toggle('viewHistorySidebar'); PanelUI.hide();">
|
||||
<observes element="viewHistorySidebar" attribute="checked"/>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton id="appMenuClearRecentHistory"
|
||||
|
@ -108,7 +108,7 @@
|
|||
label="&viewBookmarksSidebar2.label;"
|
||||
class="subviewbutton"
|
||||
key="viewBookmarksSidebarKb"
|
||||
oncommand="toggleSidebar('viewBookmarksSidebar'); PanelUI.hide();">
|
||||
oncommand="SidebarUI.toggle('viewBookmarksSidebar'); PanelUI.hide();">
|
||||
<observes element="viewBookmarksSidebar" attribute="checked"/>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton id="panelMenu_viewBookmarksToolbar"
|
||||
|
|
|
@ -22,7 +22,7 @@ registerCleanupFunction(() => {
|
|||
|
||||
// Ensure sidebar is hidden after each test:
|
||||
if (!document.getElementById("sidebar-box").hidden) {
|
||||
toggleSidebar("", false);
|
||||
SidebarUI.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -16,7 +16,9 @@ add_task(function* test() {
|
|||
}
|
||||
|
||||
let sidebar = yield promiseLoadedSidebar("viewBookmarksSidebar");
|
||||
registerCleanupFunction(toggleSidebar);
|
||||
registerCleanupFunction(() => {
|
||||
SidebarUI.hide();
|
||||
});
|
||||
|
||||
// Focus the tree and check if its controller is returned.
|
||||
let tree = sidebar.contentDocument.getElementById("bookmarks-view");
|
||||
|
@ -59,6 +61,6 @@ function promiseLoadedSidebar(cmd) {
|
|||
resolve(sidebar);
|
||||
}, true);
|
||||
|
||||
toggleSidebar(cmd, true);
|
||||
SidebarUI.show(cmd);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ gTests.push({
|
|||
finish: function() {
|
||||
// Close window, toggle sidebar and goto next test.
|
||||
this.window.document.documentElement.cancelDialog();
|
||||
toggleSidebar(this.sidebar, false);
|
||||
SidebarUI.hide();
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
|
@ -138,7 +138,7 @@ gTests.push({
|
|||
|
||||
finish: function() {
|
||||
this.window.document.documentElement.cancelDialog();
|
||||
toggleSidebar(this.sidebar, false);
|
||||
SidebarUI.hide();
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
|
@ -232,7 +232,7 @@ gTests.push({
|
|||
},
|
||||
|
||||
finish: function() {
|
||||
toggleSidebar(this.sidebar, false);
|
||||
SidebarUI.hide();
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
|
@ -291,7 +291,7 @@ gTests.push({
|
|||
|
||||
finish: function() {
|
||||
// Window is already closed.
|
||||
toggleSidebar(this.sidebar, false);
|
||||
SidebarUI.hide();
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
|
@ -390,7 +390,7 @@ gTests.push({
|
|||
},
|
||||
|
||||
finish: function() {
|
||||
toggleSidebar(this.sidebar, false);
|
||||
SidebarUI.hide();
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
|
@ -468,7 +468,7 @@ gTests.push({
|
|||
},
|
||||
|
||||
finish: function() {
|
||||
toggleSidebar(this.sidebar, false);
|
||||
SidebarUI.hide();
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
|
@ -529,7 +529,7 @@ function execute_test_in_sidebar() {
|
|||
// Need to executeSoon since the tree is initialized on sidebar load.
|
||||
executeSoon(open_properties_dialog);
|
||||
}, true);
|
||||
toggleSidebar(gCurrentTest.sidebar, true);
|
||||
SidebarUI.show(gCurrentTest.sidebar);
|
||||
}
|
||||
|
||||
function open_properties_dialog() {
|
||||
|
|
|
@ -44,7 +44,7 @@ function continue_test() {
|
|||
transition: hs.TRANSITION_TYPED});
|
||||
}
|
||||
PlacesTestUtils.addVisits(places).then(() => {
|
||||
toggleSidebar("viewHistorySidebar", true);
|
||||
SidebarUI.show("viewHistorySidebar");
|
||||
});
|
||||
|
||||
sidebar.addEventListener("load", function() {
|
||||
|
@ -63,7 +63,7 @@ function continue_test() {
|
|||
check_sidebar_tree_order(pages.length);
|
||||
|
||||
// Cleanup.
|
||||
toggleSidebar("viewHistorySidebar", false);
|
||||
SidebarUI.hide();
|
||||
PlacesTestUtils.clearHistory().then(finish);
|
||||
});
|
||||
}, true);
|
||||
|
|
|
@ -18,7 +18,7 @@ function test() {
|
|||
// If a sidebar is already open, close it.
|
||||
if (!document.getElementById("sidebar-box").hidden) {
|
||||
info("Unexpected sidebar found - a previous test failed to cleanup correctly");
|
||||
toggleSidebar();
|
||||
SidebarUI.hide();
|
||||
}
|
||||
|
||||
let sidebar = document.getElementById("sidebar");
|
||||
|
@ -76,7 +76,7 @@ function test() {
|
|||
|
||||
function testPlacesPanel(preFunc, postFunc) {
|
||||
currentTest.init(function() {
|
||||
toggleSidebar(currentTest.sidebarName);
|
||||
SidebarUI.show(currentTest.sidebarName);
|
||||
});
|
||||
|
||||
sidebar.addEventListener("load", function() {
|
||||
|
@ -95,7 +95,7 @@ function test() {
|
|||
aSubject.Dialog.ui.button0.click();
|
||||
|
||||
executeSoon(function () {
|
||||
toggleSidebar(currentTest.sidebarName);
|
||||
SidebarUI.hide();
|
||||
currentTest.cleanup(postFunc);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ function openBookmarksSidebar() {
|
|||
// Need to executeSoon since the tree is initialized on sidebar load.
|
||||
executeSoon(startTest);
|
||||
}, true);
|
||||
toggleSidebar("viewBookmarksSidebar", true);
|
||||
SidebarUI.show("viewBookmarksSidebar");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -171,7 +171,7 @@ function startTest() {
|
|||
*/
|
||||
function finishTest() {
|
||||
// Close bookmarks sidebar.
|
||||
toggleSidebar("viewBookmarksSidebar", false);
|
||||
SidebarUI.hide();
|
||||
|
||||
// Collapse the personal toolbar if needed.
|
||||
if (wasCollapsed) {
|
||||
|
|
|
@ -33,7 +33,7 @@ function test() {
|
|||
resolve(win);
|
||||
}, true);
|
||||
|
||||
win.toggleSidebar(sidebarID, true);
|
||||
win.SidebarUI.show(sidebarID);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
|
|
@ -2865,7 +2865,7 @@ let SessionStoreInternal = {
|
|||
}
|
||||
var sidebar = aWindow.document.getElementById("sidebar-box");
|
||||
if (sidebar.getAttribute("sidebarcommand") != aSidebar) {
|
||||
aWindow.toggleSidebar(aSidebar);
|
||||
aWindow.SidebarUI.show(aSidebar);
|
||||
}
|
||||
// since resizing/moving a window brings it to the foreground,
|
||||
// we might want to re-focus the last focused window
|
||||
|
|
Загрузка…
Ссылка в новой задаче