diff --git a/CLOBBER b/CLOBBER
index b02b8fc90d36..cc2cb7ee4f26 100644
--- a/CLOBBER
+++ b/CLOBBER
@@ -18,4 +18,4 @@
# Modifying this file will now automatically clobber the buildbot machines \o/
#
-Bug 928390 requires a clobber because of bug 939416.
+Australis landing.
diff --git a/accessible/tests/mochitest/events/test_focus_general.html b/accessible/tests/mochitest/events/test_focus_general.html
index 55f71d5f7b55..e1a09c614956 100644
--- a/accessible/tests/mochitest/events/test_focus_general.html
+++ b/accessible/tests/mochitest/events/test_focus_general.html
@@ -96,7 +96,7 @@
gQueue.push(new focusElmWhileSubdocIsFocused("link"));
gQueue.push(new synthTab(editableDoc, new focusChecker(editableDoc)));
- if (WIN) {
+ if (WIN || LINUX) {
// Alt key is used to active menubar and focus menu item on Windows,
// other platforms requires setting a ui.key.menuAccessKeyFocuses
// preference.
diff --git a/accessible/tests/mochitest/events/test_menu.xul b/accessible/tests/mochitest/events/test_menu.xul
index a286964a1fbb..bae36fb71239 100644
--- a/accessible/tests/mochitest/events/test_menu.xul
+++ b/accessible/tests/mochitest/events/test_menu.xul
@@ -156,7 +156,7 @@
// Alt key is used to active menubar and focus menu item on Windows,
// other platforms requires setting a ui.key.menuAccessKeyFocuses
// preference.
- if (WIN) {
+ if (WIN || LINUX) {
gQueue.push(new focusFileMenu());
gQueue.push(new focusEditMenu());
gQueue.push(new leaveMenubar());
diff --git a/addon-sdk/source/test/test-ui-button.js b/addon-sdk/source/test/test-ui-button.js
index f481fae29062..3f05eeb77449 100644
--- a/addon-sdk/source/test/test-ui-button.js
+++ b/addon-sdk/source/test/test-ui-button.js
@@ -11,7 +11,7 @@ module.metadata = {
const { Cu } = require('chrome');
const { Loader } = require('sdk/test/loader');
-const data = require('./fixtures');
+const { data } = require('sdk/self');
const { open, focus, close } = require('sdk/window/helpers');
const { setTimeout } = require('sdk/timers');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
index bb29699a8f77..88dc128fb812 100644
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -444,11 +444,10 @@ pref("browser.tabs.loadDivertedInBackground", false);
pref("browser.tabs.loadBookmarksInBackground", false);
pref("browser.tabs.tabClipWidth", 140);
pref("browser.tabs.animate", true);
-pref("browser.tabs.onTop", true);
-#ifdef XP_WIN
-pref("browser.tabs.drawInTitlebar", true);
-#else
+#ifdef UNIX_BUT_NOT_MAC
pref("browser.tabs.drawInTitlebar", false);
+#else
+pref("browser.tabs.drawInTitlebar", true);
#endif
// Where to show tab close buttons:
@@ -1332,3 +1331,6 @@ pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%G
// Necko IPC security checks only needed for app isolation for cookies/cache/etc:
// currently irrelevant for desktop e10s
pref("network.disable.ipc.security", true);
+
+// CustomizableUI debug logging.
+pref("browser.uiCustomization.debug", false);
diff --git a/browser/base/content/browser-addons.js b/browser/base/content/browser-addons.js
index b638f31f9ea2..fe40e408a2a7 100644
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -178,50 +178,6 @@ const gXPInstallObserver = {
}
};
-/*
- * When addons are installed/uninstalled, check and see if the number of items
- * on the add-on bar changed:
- * - If an add-on was installed, incrementing the count, show the bar.
- * - If an add-on was uninstalled, and no more items are left, hide the bar.
- */
-let AddonsMgrListener = {
- get addonBar() document.getElementById("addon-bar"),
- get statusBar() document.getElementById("status-bar"),
- getAddonBarItemCount: function() {
- // Take into account the contents of the status bar shim for the count.
- var itemCount = this.statusBar.childNodes.length;
-
- var defaultOrNoninteractive = this.addonBar.getAttribute("defaultset")
- .split(",")
- .concat(["separator", "spacer", "spring"]);
- for (let item of this.addonBar.currentSet.split(",")) {
- if (defaultOrNoninteractive.indexOf(item) == -1)
- itemCount++;
- }
-
- return itemCount;
- },
- onInstalling: function(aAddon) {
- this.lastAddonBarCount = this.getAddonBarItemCount();
- },
- onInstalled: function(aAddon) {
- if (this.getAddonBarItemCount() > this.lastAddonBarCount)
- setToolbarVisibility(this.addonBar, true);
- },
- onUninstalling: function(aAddon) {
- this.lastAddonBarCount = this.getAddonBarItemCount();
- },
- onUninstalled: function(aAddon) {
- if (this.getAddonBarItemCount() == 0)
- setToolbarVisibility(this.addonBar, false);
- },
- onEnabling: function(aAddon) this.onInstalling(),
- onEnabled: function(aAddon) this.onInstalled(),
- onDisabling: function(aAddon) this.onUninstalling(),
- onDisabled: function(aAddon) this.onUninstalled(),
-};
-
-
var LightWeightThemeWebInstaller = {
handleEvent: function (event) {
switch (event.type) {
@@ -415,3 +371,60 @@ var LightWeightThemeWebInstaller = {
node.baseURI);
}
}
+
+/*
+ * Listen for Lightweight Theme styling changes and update the browser's theme accordingly.
+ */
+let LightweightThemeListener = {
+ _modifiedStyles: [],
+
+ init: function () {
+ XPCOMUtils.defineLazyGetter(this, "styleSheet", function() {
+ for (let i = document.styleSheets.length - 1; i >= 0; i--) {
+ let sheet = document.styleSheets[i];
+ if (sheet.href == "chrome://browser/skin/browser-lightweightTheme.css")
+ return sheet;
+ }
+ });
+
+ Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
+ if (document.documentElement.hasAttribute("lwtheme"))
+ this.updateStyleSheet(document.documentElement.style.backgroundImage);
+ },
+
+ uninit: function () {
+ Services.obs.removeObserver(this, "lightweight-theme-styling-update");
+ },
+
+ /**
+ * Append the headerImage to the background-image property of all rulesets in
+ * browser-lightweightTheme.css.
+ *
+ * @param headerImage - a string containing a CSS image for the lightweight theme header.
+ */
+ updateStyleSheet: function(headerImage) {
+ if (!this.styleSheet)
+ return;
+ for (let i = 0; i < this.styleSheet.cssRules.length; i++) {
+ let rule = this.styleSheet.cssRules[i];
+ if (!rule.style.backgroundImage)
+ continue;
+
+ if (!this._modifiedStyles[i])
+ this._modifiedStyles[i] = { backgroundImage: rule.style.backgroundImage };
+
+ rule.style.backgroundImage = this._modifiedStyles[i].backgroundImage + ", " + headerImage;
+ }
+ },
+
+ // nsIObserver
+ observe: function (aSubject, aTopic, aData) {
+ if (aTopic != "lightweight-theme-styling-update" || !this.styleSheet)
+ return;
+
+ let themeData = JSON.parse(aData);
+ if (!themeData)
+ return;
+ this.updateStyleSheet("url(" + themeData.headerURL + ")");
+ },
+};
diff --git a/browser/base/content/browser-appmenu.inc b/browser/base/content/browser-appmenu.inc
deleted file mode 100644
index 0cd58f2ecf49..000000000000
--- a/browser/base/content/browser-appmenu.inc
+++ /dev/null
@@ -1,406 +0,0 @@
-# -*- Mode: HTML -*-
-# 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/.
-
-
diff --git a/browser/base/content/browser-customization.js b/browser/base/content/browser-customization.js
new file mode 100644
index 000000000000..369f6cbd22cf
--- /dev/null
+++ b/browser/base/content/browser-customization.js
@@ -0,0 +1,97 @@
+# -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+# 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/.
+
+/**
+ * Customization handler prepares this browser window for entering and exiting
+ * customization mode by handling customizationstarting and customizationending
+ * events.
+ */
+let CustomizationHandler = {
+ handleEvent: function(aEvent) {
+ switch(aEvent.type) {
+ case "customizationstarting":
+ this._customizationStarting();
+ break;
+ case "customizationending":
+ this._customizationEnding(aEvent.detail);
+ break;
+ }
+ },
+
+ isCustomizing: function() {
+ return document.documentElement.hasAttribute("customizing") ||
+ document.documentElement.hasAttribute("customize-exiting");
+ },
+
+ _customizationStarting: function() {
+ // Disable the toolbar context menu items
+ let menubar = document.getElementById("main-menubar");
+ for (let childNode of menubar.childNodes)
+ childNode.setAttribute("disabled", true);
+
+ let cmd = document.getElementById("cmd_CustomizeToolbars");
+ cmd.setAttribute("disabled", "true");
+
+ let splitter = document.getElementById("urlbar-search-splitter");
+ if (splitter) {
+ splitter.parentNode.removeChild(splitter);
+ }
+
+ CombinedStopReload.uninit();
+ PlacesToolbarHelper.customizeStart();
+ BookmarkingUI.customizeStart();
+ DownloadsButton.customizeStart();
+ },
+
+ _customizationEnding: function(aDetails) {
+ // Update global UI elements that may have been added or removed
+ if (aDetails.changed) {
+ gURLBar = document.getElementById("urlbar");
+
+ gProxyFavIcon = document.getElementById("page-proxy-favicon");
+ gHomeButton.updateTooltip();
+ gIdentityHandler._cacheElements();
+ XULBrowserWindow.init();
+
+#ifndef XP_MACOSX
+ updateEditUIVisibility();
+#endif
+
+ // Hacky: update the PopupNotifications' object's reference to the iconBox,
+ // if it already exists, since it may have changed if the URL bar was
+ // added/removed.
+ if (!window.__lookupGetter__("PopupNotifications")) {
+ PopupNotifications.iconBox =
+ document.getElementById("notification-popup-box");
+ }
+
+ }
+
+ PlacesToolbarHelper.customizeDone();
+ BookmarkingUI.customizeDone();
+ DownloadsButton.customizeDone();
+
+ // The url bar splitter state is dependent on whether stop/reload
+ // and the location bar are combined, so we need this ordering
+ CombinedStopReload.init();
+ UpdateUrlbarSearchSplitterState();
+
+ // Update the urlbar
+ if (gURLBar) {
+ URLBarSetURI();
+ XULBrowserWindow.asyncUpdateUI();
+ BookmarkingUI.updateStarState();
+ }
+
+ // Re-enable parts of the UI we disabled during the dialog
+ let menubar = document.getElementById("main-menubar");
+ for (let childNode of menubar.childNodes)
+ childNode.setAttribute("disabled", false);
+ let cmd = document.getElementById("cmd_CustomizeToolbars");
+ cmd.removeAttribute("disabled");
+
+ gBrowser.selectedBrowser.focus();
+ }
+}
diff --git a/browser/base/content/browser-feeds.js b/browser/base/content/browser-feeds.js
index 7bba39540824..2bdb33cd09eb 100644
--- a/browser/base/content/browser-feeds.js
+++ b/browser/base/content/browser-feeds.js
@@ -8,66 +8,53 @@
* and shows UI when they are discovered.
*/
var FeedHandler = {
- /**
- * The click handler for the Feed icon in the toolbar. Opens the
- * subscription page if user is not given a choice of feeds.
- * (Otherwise the list of available feeds will be presented to the
- * user in a popup menu.)
- */
- onFeedButtonClick: function(event) {
- event.stopPropagation();
-
- let feeds = gBrowser.selectedBrowser.feeds || [];
- // If there are multiple feeds, the menu will open, so no need to do
- // anything. If there are no feeds, nothing to do either.
- if (feeds.length != 1)
- return;
-
- if (event.eventPhase == Event.AT_TARGET &&
- (event.button == 0 || event.button == 1)) {
- this.subscribeToFeed(feeds[0].href, event);
- }
- },
-
- /** Called when the user clicks on the Subscribe to This Page... menu item.
+ /** Called when the user clicks on the Subscribe to This Page... menu item,
+ * or when the user clicks the feed button when the page contains multiple
+ * feeds.
* Builds a menu of unique feeds associated with the page, and if there
* is only one, shows the feed inline in the browser window.
- * @param menuPopup
- * The feed list menupopup to be populated.
- * @returns true if the menu should be shown, false if there was only
+ * @param container
+ * The feed list container (menupopup or subview) to be populated.
+ * @param isSubview
+ * Whether we're creating a subview (true) or menu (false/undefined)
+ * @returns true if the menu/subview should be shown, false if there was only
* one feed and the feed should be shown inline in the browser
- * window (do not show the menupopup).
+ * window (do not show the menupopup/subview).
*/
- buildFeedList: function(menuPopup) {
+ buildFeedList: function(container, isSubview) {
var feeds = gBrowser.selectedBrowser.feeds;
- if (feeds == null) {
+ if (!isSubview && feeds == null) {
// XXX hack -- menu opening depends on setting of an "open"
// attribute, and the menu refuses to open if that attribute is
// set (because it thinks it's already open). onpopupshowing gets
// called after the attribute is unset, and it doesn't get unset
// if we return false. so we unset it here; otherwise, the menu
// refuses to work past this point.
- menuPopup.parentNode.removeAttribute("open");
+ container.parentNode.removeAttribute("open");
return false;
}
- while (menuPopup.firstChild)
- menuPopup.removeChild(menuPopup.firstChild);
+ while (container.firstChild)
+ container.removeChild(container.firstChild);
- if (feeds.length <= 1)
+ if (!feeds || feeds.length <= 1)
return false;
// Build the menu showing the available feed choices for viewing.
+ var itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
for (let feedInfo of feeds) {
- var menuItem = document.createElement("menuitem");
+ var item = document.createElement(itemNodeType);
var baseTitle = feedInfo.title || feedInfo.href;
var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
- menuItem.setAttribute("class", "feed-menuitem");
- menuItem.setAttribute("label", labelStr);
- menuItem.setAttribute("feed", feedInfo.href);
- menuItem.setAttribute("tooltiptext", feedInfo.href);
- menuItem.setAttribute("crop", "center");
- menuPopup.appendChild(menuItem);
+ item.setAttribute("class", "feed-" + itemNodeType);
+ item.setAttribute("label", labelStr);
+ item.setAttribute("feed", feedInfo.href);
+ item.setAttribute("tooltiptext", feedInfo.href);
+ item.setAttribute("crop", "center");
+ if (isSubview) {
+ item.setAttribute("tabindex", "0");
+ }
+ container.appendChild(item);
}
return true;
},
@@ -76,7 +63,7 @@ var FeedHandler = {
* Subscribe to a given feed. Called when
* 1. Page has a single feed and user clicks feed icon in location bar
* 2. Page has a single feed and user selects Subscribe menu item
- * 3. Page has multiple feeds and user selects from feed icon popup
+ * 3. Page has multiple feeds and user selects from feed icon popup (or subview)
* 4. Page has multiple feeds and user selects from Subscribe submenu
* @param href
* The feed to subscribe to. May be null, in which case the
diff --git a/browser/base/content/browser-fullScreen.js b/browser/base/content/browser-fullScreen.js
index a8ffa754ad02..4e416ef0437e 100644
--- a/browser/base/content/browser-fullScreen.js
+++ b/browser/base/content/browser-fullScreen.js
@@ -17,7 +17,7 @@ var FullScreen = {
enterFS = !enterFS;
// Toggle the View:FullScreen command, which controls elements like the
- // fullscreen menuitem, menubars, and the appmenu.
+ // fullscreen menuitem, and menubars.
let fullscreenCommand = document.getElementById("View:FullScreen");
if (enterFS) {
fullscreenCommand.setAttribute("checked", enterFS);
@@ -517,15 +517,6 @@ var FullScreen = {
// XXX don't interfere with previously collapsed toolbars
if (el.getAttribute("fullscreentoolbar") == "true") {
if (!aShow) {
-
- var toolbarMode = el.getAttribute("mode");
- if (toolbarMode != "text") {
- el.setAttribute("saved-mode", toolbarMode);
- el.setAttribute("saved-iconsize", el.getAttribute("iconsize"));
- el.setAttribute("mode", "icons");
- el.setAttribute("iconsize", "small");
- }
-
// Give the main nav bar and the tab bar the fullscreen context menu,
// otherwise remove context menu to prevent breakage
el.setAttribute("saved-context", el.getAttribute("context"));
@@ -539,18 +530,10 @@ var FullScreen = {
el.setAttribute("inFullscreen", true);
}
else {
- var restoreAttr = function restoreAttr(attrName) {
- var savedAttr = "saved-" + attrName;
- if (el.hasAttribute(savedAttr)) {
- el.setAttribute(attrName, el.getAttribute(savedAttr));
- el.removeAttribute(savedAttr);
- }
+ if (el.hasAttribute("saved-context")) {
+ el.setAttribute("context", el.getAttribute("saved-context"));
+ el.removeAttribute("saved-context");
}
-
- restoreAttr("mode");
- restoreAttr("iconsize");
- restoreAttr("context");
-
el.removeAttribute("inFullscreen");
}
} else {
@@ -571,11 +554,9 @@ var FullScreen = {
document.documentElement.setAttribute("inFullscreen", true);
}
- // In tabs-on-top mode, move window controls to the tab bar,
- // and in tabs-on-bottom mode, move them back to the navigation toolbar.
var fullscreenctls = document.getElementById("window-controls");
var navbar = document.getElementById("nav-bar");
- var ctlsOnTabbar = window.toolbar.visible && (navbar.collapsed || TabsOnTop.enabled);
+ var ctlsOnTabbar = window.toolbar.visible;
if (fullscreenctls.parentNode == navbar && ctlsOnTabbar) {
fullscreenctls.removeAttribute("flex");
document.getElementById("TabsToolbar").appendChild(fullscreenctls);
diff --git a/browser/base/content/browser-fullZoom.js b/browser/base/content/browser-fullZoom.js
index d92dfcc625e1..55f02c38b9e6 100644
--- a/browser/base/content/browser-fullZoom.js
+++ b/browser/base/content/browser-fullZoom.js
@@ -397,6 +397,7 @@ var FullZoom = {
* @param browser The zoom of this browser will be saved. Required.
*/
_applyZoomToPref: function FullZoom__applyZoomToPref(browser) {
+ Services.obs.notifyObservers(null, "browser-fullZoom:zoomChange", "");
if (!this.siteSpecific ||
gInPrintPreviewMode ||
browser.contentDocument.mozSyntheticDocument)
@@ -417,6 +418,7 @@ var FullZoom = {
* @param browser The zoom of this browser will be removed. Required.
*/
_removePref: function FullZoom__removePref(browser) {
+ Services.obs.notifyObservers(null, "browser-fullZoom:zoomReset", "");
if (browser.contentDocument.mozSyntheticDocument)
return;
let ctxt = this._loadContextFromWindow(browser.contentWindow);
diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc
index 856f81b92f1b..1db9222eb731 100644
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -185,11 +185,6 @@
accesskey="&viewToolbarsMenu.accesskey;">
-
#ifndef XP_WIN
-
+
#endif
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -782,16 +906,23 @@
-
+
-
-#ifdef MENUBAR_CAN_AUTOHIDE
-#ifndef CAN_DRAW_IN_TITLEBAR
-#define APPMENU_ON_TABBAR
-#endif
-#endif
-
-
-
-
-#ifdef APPMENU_ON_TABBAR
-
-#endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-#ifdef CAN_DRAW_IN_TITLEBAR
-
-
-#endif
+
+
+
+
@@ -919,31 +969,13 @@
# or removing default items with the toolbarbutton-1 class.
+#ifdef XP_MACOSX
+ command="cmd_print"
+#else
+ command="cmd_printPreview"
+#endif
+ label="&printButton.label;" tooltiptext="&printButton.tooltip;"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#ifdef MOZ_SERVICES_SYNC
#endif
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+ flex="1"
+ style="min-width: 14em; width: 18em; max-width: 36em;"/>
+
+
+
+#include ../../components/customizableui/content/customizeMode.inc.xul
+
@@ -1119,56 +1109,28 @@
tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
#endif
-
-
-
-
-
-#ifndef XP_UNIX
+#include tab-shape.inc.svg
+
+#ifndef XP_UNIX
-
+
-
#endif
#ifdef XP_MACOSX
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
#endif
+
#