This commit is contained in:
Jared Wein 2013-07-03 12:40:14 -04:00
commit f907175807
220 changed files with 9914 additions and 4940 deletions

View File

@ -426,11 +426,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:
@ -1277,3 +1276,6 @@ pref("dom.debug.propagate_gesture_events_through_content", false);
// The request URL of the GeoLocation backend.
pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_API_KEY%");
// CustomizableUI debug logging.
pref("browser.uiCustomization.debug", false);

View File

@ -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,58 @@ 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);
this.updateStyleSheet("url(" + themeData.headerURL + ")");
},
};

View File

@ -1,400 +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/.
<menupopup id="appmenu-popup"
onpopupshowing="if (event.target == this) {
updateEditUIVisibility();
#ifdef MOZ_SERVICES_SYNC
gSyncUI.updateUI();
#endif
return;
}
updateCharacterEncodingMenuState();
if (event.target.parentNode.parentNode.parentNode.parentNode == this)
this._currentPopup = event.target;">
<hbox>
<vbox id="appmenuPrimaryPane">
<splitmenu id="appmenu_newTab"
label="&tabCmd.label;"
command="cmd_newNavigatorTab">
<menupopup>
<menuitem id="appmenu_newTab_popup"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab"/>
<menuitem id="appmenu_newNavigator"
label="&newNavigatorCmd.label;"
command="cmd_newNavigator"
key="key_newNavigator"/>
<menuseparator/>
<menuitem id="appmenu_openFile"
label="&openFileCmd.label;"
command="Browser:OpenFile"
key="openFileKb"/>
</menupopup>
</splitmenu>
<menuitem id="appmenu_newPrivateWindow"
class="menuitem-iconic menuitem-iconic-tooltip"
label="&newPrivateWindow.label;"
command="Tools:PrivateBrowsing"
key="key_privatebrowsing"/>
<menuitem label="&goOfflineCmd.label;"
id="appmenu_offlineModeRecovery"
type="checkbox"
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
<menuseparator class="appmenu-menuseparator"/>
<hbox>
<menuitem id="appmenu-edit-label"
label="&appMenuEdit.label;"
disabled="true"/>
<toolbarbutton id="appmenu-cut"
class="appmenu-edit-button"
command="cmd_cut"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&cutButton.tooltip;"/>
<toolbarbutton id="appmenu-copy"
class="appmenu-edit-button"
command="cmd_copy"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&copyButton.tooltip;"/>
<toolbarbutton id="appmenu-paste"
class="appmenu-edit-button"
command="cmd_paste"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&pasteButton.tooltip;"/>
<spacer flex="1"/>
<menu id="appmenu-editmenu">
<menupopup id="appmenu-editmenu-menupopup">
<menuitem id="appmenu-editmenu-cut"
class="menuitem-iconic"
label="&cutCmd.label;"
key="key_cut"
command="cmd_cut"/>
<menuitem id="appmenu-editmenu-copy"
class="menuitem-iconic"
label="&copyCmd.label;"
key="key_copy"
command="cmd_copy"/>
<menuitem id="appmenu-editmenu-paste"
class="menuitem-iconic"
label="&pasteCmd.label;"
key="key_paste"
command="cmd_paste"/>
<menuseparator/>
<menuitem id="appmenu-editmenu-undo"
label="&undoCmd.label;"
key="key_undo"
command="cmd_undo"/>
<menuitem id="appmenu-editmenu-redo"
label="&redoCmd.label;"
key="key_redo"
command="cmd_redo"/>
<menuseparator/>
<menuitem id="appmenu-editmenu-selectAll"
label="&selectAllCmd.label;"
key="key_selectAll"
command="cmd_selectAll"/>
<menuseparator/>
<menuitem id="appmenu-editmenu-delete"
label="&deleteCmd.label;"
key="key_delete"
command="cmd_delete"/>
</menupopup>
</menu>
</hbox>
<menuitem id="appmenu_find"
class="menuitem-tooltip"
label="&appMenuFind.label;"
command="cmd_find"
key="key_find"/>
<menuseparator class="appmenu-menuseparator"/>
<menuitem id="appmenu_savePage"
class="menuitem-tooltip"
label="&savePageCmd.label;"
command="Browser:SavePage"
key="key_savePage"/>
<menuitem id="appmenu_sendLink"
label="&emailPageCmd.label;"
command="Browser:SendLink"/>
<splitmenu id="appmenu_print"
iconic="true"
label="&printCmd.label;"
command="cmd_print">
<menupopup>
<menuitem id="appmenu_print_popup"
class="menuitem-iconic"
label="&printCmd.label;"
command="cmd_print"
key="printKb"/>
<menuitem id="appmenu_printPreview"
label="&printPreviewCmd.label;"
command="cmd_printPreview"/>
<menuitem id="appmenu_printSetup"
label="&printSetupCmd.label;"
command="cmd_pageSetup"/>
</menupopup>
</splitmenu>
<menuseparator class="appmenu-menuseparator"/>
<splitmenu id="appmenu_webDeveloper"
command="Tools:DevToolbox"
label="&appMenuWebDeveloper.label;">
<menupopup id="appmenu_webDeveloper_popup">
<menuitem id="appmenu_devToolbox"
observes="devtoolsMenuBroadcaster_DevToolbox"/>
<menuseparator id="appmenu_devtools_separator"/>
<menuitem id="appmenu_devToolbar"
observes="devtoolsMenuBroadcaster_DevToolbar"/>
<menuitem id="appmenu_chromeDebugger"
observes="devtoolsMenuBroadcaster_ChromeDebugger"/>
<menuitem id="appmenu_browserConsole"
observes="devtoolsMenuBroadcaster_BrowserConsole"/>
<menuitem id="appmenu_responsiveUI"
observes="devtoolsMenuBroadcaster_ResponsiveUI"/>
<menuitem id="appmenu_scratchpad"
observes="devtoolsMenuBroadcaster_Scratchpad"/>
<menuitem id="appmenu_pageSource"
observes="devtoolsMenuBroadcaster_PageSource"/>
<menuitem id="appmenu_errorConsole"
observes="devtoolsMenuBroadcaster_ErrorConsole"/>
<menuitem id="appmenu_devtools_connect"
observes="devtoolsMenuBroadcaster_connect"/>
<menuseparator id="appmenu_devToolsEndSeparator"/>
<menuitem id="appmenu_getMoreDevtools"
observes="devtoolsMenuBroadcaster_GetMoreTools"/>
<menuseparator/>
#define ID_PREFIX appmenu_developer_
#define OMIT_ACCESSKEYS
#include browser-charsetmenu.inc
#undef ID_PREFIX
#undef OMIT_ACCESSKEYS
<menuitem label="&goOfflineCmd.label;"
type="checkbox"
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
</menupopup>
</splitmenu>
<menuseparator class="appmenu-menuseparator"/>
#define ID_PREFIX appmenu_
#define OMIT_ACCESSKEYS
#include browser-charsetmenu.inc
#undef ID_PREFIX
#undef OMIT_ACCESSKEYS
<menuitem id="appmenu_fullScreen"
class="menuitem-tooltip"
label="&fullScreenCmd.label;"
type="checkbox"
observes="View:FullScreen"
key="key_fullScreen"/>
#ifdef MOZ_SERVICES_SYNC
<!-- only one of sync-setup or sync-syncnow will be showing at once -->
<menuitem id="sync-setup-appmenu"
label="&syncSetup.label;"
observes="sync-setup-state"
oncommand="gSyncUI.openSetup()"/>
<menuitem id="sync-syncnowitem-appmenu"
label="&syncSyncNowItem.label;"
observes="sync-syncnow-state"
oncommand="gSyncUI.doSync(event);"/>
#endif
<menuitem id="appmenu-quit"
class="menuitem-iconic"
#ifdef XP_WIN
label="&quitApplicationCmdWin.label;"
#else
label="&quitApplicationCmd.label;"
#endif
command="cmd_quitApplication"/>
</vbox>
<vbox id="appmenuSecondaryPane">
<splitmenu id="appmenu_bookmarks"
iconic="true"
label="&bookmarksMenu.label;"
command="Browser:ShowAllBookmarks">
<menupopup id="appmenu_bookmarksPopup"
placespopup="true"
context="placesContext"
openInTabs="children"
oncommand="BookmarksEventHandler.onCommand(event, this.parentNode._placesView);"
onclick="BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
onpopupshowing="BookmarkingUI.onPopupShowing(event);
if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="appmenu_showAllBookmarks"
label="&showAllBookmarks2.label;"
command="Browser:ShowAllBookmarks"
context=""
key="manBookmarkKb"/>
<menuseparator/>
<menuitem id="appmenu_bookmarkThisPage"
class="menuitem-iconic"
label="&bookmarkThisPageCmd.label;"
command="Browser:AddBookmarkAs"
key="addBookmarkAsKb"/>
<menuitem id="appmenu_subscribeToPage"
class="menuitem-iconic"
label="&subscribeToPageMenuitem.label;"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"
observes="singleFeedMenuitemState"/>
<menu id="appmenu_subscribeToPageMenu"
class="menu-iconic"
label="&subscribeToPageMenupopup.label;"
observes="multipleFeedsMenuState">
<menupopup id="appmenu_subscribeToPageMenupopup"
onpopupshowing="return FeedHandler.buildFeedList(event.target);"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"/>
</menu>
<menuseparator/>
<menu id="appmenu_bookmarksToolbar"
placesanonid="toolbar-autohide"
class="menu-iconic bookmark-item"
label="&personalbarCmd.label;"
container="true">
<menupopup id="appmenu_bookmarksToolbarPopup"
placespopup="true"
context="placesContext"
onpopupshowing="if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
</menu>
<menuseparator/>
<!-- Bookmarks menu items -->
<menuseparator builder="end"
class="hide-if-empty-places-result"/>
<menuitem id="appmenu_unsortedBookmarks"
label="&appMenuUnsorted.label;"
oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"
class="menuitem-iconic"/>
</menupopup>
</splitmenu>
<splitmenu id="appmenu_history"
iconic="true"
label="&historyMenu.label;"
command="Browser:ShowAllHistory">
<menupopup id="appmenu_historyMenupopup"
placespopup="true"
oncommand="this.parentNode._placesView._onCommand(event);"
onclick="checkForMiddleClick(this, event);"
onpopupshowing="if (!this.parentNode._placesView)
new HistoryMenu(event);"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="appmenu_showAllHistory"
label="&showAllHistoryCmd2.label;"
command="Browser:ShowAllHistory"
key="showAllHistoryKb"/>
<menuseparator/>
<menuitem id="appmenu_sanitizeHistory"
label="&clearRecentHistory.label;"
key="key_sanitize"
command="Tools:Sanitize"/>
<menuseparator class="hide-if-empty-places-result"/>
#ifdef MOZ_SERVICES_SYNC
<menuitem id="appmenu_sync-tabs"
class="syncTabsMenuItem"
label="&syncTabsMenu2.label;"
oncommand="BrowserOpenSyncTabs();"
disabled="true"/>
#endif
<menuitem id="appmenu_restoreLastSession"
label="&historyRestoreLastSession.label;"
command="Browser:RestoreLastSession"/>
<menu id="appmenu_recentlyClosedTabsMenu"
class="recentlyClosedTabsMenu"
label="&historyUndoMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedTabsMenupopup"
onpopupshowing="document.getElementById('appmenu_history')._placesView.populateUndoSubmenu();"/>
</menu>
<menu id="appmenu_recentlyClosedWindowsMenu"
class="recentlyClosedWindowsMenu"
label="&historyUndoWindowMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedWindowsMenupopup"
onpopupshowing="document.getElementById('appmenu_history')._placesView.populateUndoWindowSubmenu();"/>
</menu>
<menuseparator/>
</menupopup>
</splitmenu>
<menuitem id="appmenu_downloads"
class="menuitem-tooltip"
label="&downloads.label;"
command="Tools:Downloads"
key="key_openDownloads"/>
<spacer id="appmenuSecondaryPane-spacer"/>
<menuitem id="appmenu_addons"
class="menuitem-iconic menuitem-iconic-tooltip"
label="&addons.label;"
command="Tools:Addons"
key="key_openAddons"/>
<splitmenu id="appmenu_customize"
#ifdef XP_UNIX
label="&preferencesCmdUnix.label;"
#else
label="&preferencesCmd2.label;"
#endif
oncommand="openPreferences();">
<menupopup id="appmenu_customizeMenu"
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleToolbarsSeparator'));">
<menuitem id="appmenu_preferences"
#ifdef XP_UNIX
label="&preferencesCmdUnix.label;"
#else
label="&preferencesCmd2.label;"
#endif
oncommand="openPreferences();"/>
<menuseparator/>
<menuseparator id="appmenu_toggleToolbarsSeparator"/>
<menuitem id="appmenu_toggleTabsOnTop"
label="&viewTabsOnTop.label;"
type="checkbox"
command="cmd_ToggleTabsOnTop"/>
<menuitem id="appmenu_toolbarLayout"
label="&appMenuToolbarLayout.label;"
command="cmd_CustomizeToolbars"/>
</menupopup>
</splitmenu>
<splitmenu id="appmenu_help"
label="&helpMenu.label;"
oncommand="openHelpLink('firefox-help')">
<menupopup id="appmenu_helpMenupopup">
<menuitem id="appmenu_openHelp"
label="&helpMenu.label;"
oncommand="openHelpLink('firefox-help')"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="appmenu_gettingStarted"
label="&appMenuGettingStarted.label;"
oncommand="gBrowser.loadOneTab('https://www.mozilla.org/firefox/central/', {inBackground: false});"
onclick="checkForMiddleClick(this, event);"/>
#ifdef MOZ_SERVICES_HEALTHREPORT
<menuitem id="appmenu_healthReport"
label="&healthReport.label;"
oncommand="openHealthReport()"
onclick="checkForMiddleClick(this, event);"/>
#endif
<menuitem id="appmenu_troubleshootingInfo"
label="&helpTroubleshootingInfo.label;"
oncommand="openTroubleshootingPage()"
onclick="checkForMiddleClick(this,event);"/>
<menuitem id="appmenu_feedbackPage"
label="&helpFeedbackPage.label;"
oncommand="openFeedbackPage()"
onclick="checkForMiddleClick(this, event);"/>
<menuseparator/>
<menuitem id="appmenu_safeMode"
label="&appMenuSafeMode.label;"
oncommand="safeModeRestart();"/>
<menuseparator/>
<menuitem id="appmenu_about"
label="&aboutProduct.label;"
oncommand="openAboutDialog();"/>
</menupopup>
</splitmenu>
</vbox>
</hbox>
</menupopup>

View File

@ -0,0 +1,104 @@
# -*- 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();
setUrlAndSearchBarWidthForConditionalForwardButton();
// Update the urlbar
if (gURLBar) {
URLBarSetURI();
XULBrowserWindow.asyncUpdateUI();
BookmarkingUI.updateStarState();
SocialMark.updateMarkState();
}
// 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");
// make sure to re-enable click-and-hold
if (!getBoolPref("ui.click_hold_context_menus", false)) {
SetClickAndHoldHandlers();
}
gBrowser.selectedBrowser.focus();
}
}

View File

@ -8,66 +8,50 @@
* 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");
container.appendChild(item);
}
return true;
},
@ -76,7 +60,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

View File

@ -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,8 @@ 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);
}
}
restoreAttr("mode");
restoreAttr("iconsize");
restoreAttr("context");
el.setAttribute("context", el.getAttribute("saved-context"));
el.removeAttribute("saved-context");
el.removeAttribute("inFullscreen");
}
} else {
@ -571,11 +552,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);

View File

@ -390,6 +390,7 @@ var FullZoom = {
* prefs store.
*/
_applyZoomToPref: function FullZoom__applyZoomToPref() {
Services.obs.notifyObservers(null, "browser-fullZoom:zoomChange", "");
if (!this.siteSpecific ||
gInPrintPreviewMode ||
content.document.mozSyntheticDocument)
@ -407,6 +408,7 @@ var FullZoom = {
* Removes from the content prefs store the zoom level of the current browser.
*/
_removePref: function FullZoom__removePref() {
Services.obs.notifyObservers(null, "browser-fullZoom:zoomReset", "");
if (content.document.mozSyntheticDocument)
return;
let ctxt = this._loadContextFromWindow(gBrowser.contentWindow);
@ -417,6 +419,7 @@ var FullZoom = {
});
},
//**************************************************************************//
// Utilities

View File

@ -185,11 +185,6 @@
accesskey="&viewToolbarsMenu.accesskey;">
<menupopup onpopupshowing="onViewToolbarsPopupShowing(event);">
<menuseparator/>
<menuitem id="menu_tabsOnTop"
command="cmd_ToggleTabsOnTop"
type="checkbox"
label="&viewTabsOnTop.label;"
accesskey="&viewTabsOnTop.accesskey;"/>
<menuitem id="menu_customizeToolbars"
label="&viewCustomizeToolbar.label;"
accesskey="&viewCustomizeToolbar.accesskey;"

View File

@ -134,9 +134,6 @@ var StarUI = {
document.loadOverlay(
"chrome://browser/content/places/editBookmarkOverlay.xul",
(function (aSubject, aTopic, aData) {
//XXX We just caused localstore.rdf to be re-applied (bug 640158)
retrieveToolbarIconsizesFromTheme();
// Move the header (star, title, button) into the grid,
// so that it aligns nicely with the other items (bug 484022).
let header = this._element("editBookmarkPanelHeader");
@ -994,8 +991,7 @@ let PlacesToolbarHelper = {
//// BookmarkingUI
/**
* Handles the bookmarks star button in the URL bar, as well as the bookmark
* menu button.
* Handles the bookmarks menu-button in the toolbar.
*/
let BookmarkingUI = {
@ -1007,18 +1003,22 @@ let BookmarkingUI = {
},
get star() {
if (!this._star) {
this._star = document.getElementById("star-button");
if (!this._star && this.button) {
this._star = document.getAnonymousElementByAttribute(this.button,
"anonid",
"button");
}
return this._star;
},
get anchor() {
if (this.star && isElementVisible(this.star)) {
if (!this._anchor && this.star && isElementVisible(this.star)) {
// Anchor to the icon, so the panel looks more natural.
return this.star;
this._anchor = document.getAnonymousElementByAttribute(this.star,
"class",
"toolbarbutton-icon");
}
return null;
return this._anchor;
},
STATUS_UPDATING: -1,
@ -1027,9 +1027,9 @@ let BookmarkingUI = {
get status() {
if (this._pendingStmt)
return this.STATUS_UPDATING;
return this.star &&
this.star.hasAttribute("starred") ? this.STATUS_STARRED
: this.STATUS_UNSTARRED;
return this.button &&
this.button.hasAttribute("starred") ? this.STATUS_STARRED
: this.STATUS_UNSTARRED;
},
get _starredTooltip()
@ -1098,11 +1098,12 @@ let BookmarkingUI = {
if (aState == "invalid") {
this.star.setAttribute("disabled", "true");
this.star.removeAttribute("starred");
this.button.removeAttribute("starred");
}
else {
this.star.removeAttribute("disabled");
}
this._updateToolbarStyle();
},
_updateToolbarStyle: function BUI__updateToolbarStyle() {
@ -1143,6 +1144,8 @@ let BookmarkingUI = {
customizeDone: function BUI_customizeDone() {
delete this._button;
delete this._star;
delete this._anchor;
this.onToolbarVisibilityChange();
this._updateToolbarStyle();
},
@ -1162,7 +1165,7 @@ let BookmarkingUI = {
},
updateStarState: function BUI_updateStarState() {
if (!this.star || (this._uri && gBrowser.currentURI.equals(this._uri))) {
if (!this.button || (this._uri && gBrowser.currentURI.equals(this._uri))) {
return;
}
@ -1211,17 +1214,17 @@ let BookmarkingUI = {
},
_updateStar: function BUI__updateStar() {
if (!this.star) {
if (!this.button) {
return;
}
if (this._itemIds.length > 0) {
this.star.setAttribute("starred", "true");
this.star.setAttribute("tooltiptext", this._starredTooltip);
this.button.setAttribute("starred", "true");
this.button.setAttribute("tooltiptext", this._starredTooltip);
}
else {
this.star.removeAttribute("starred");
this.star.setAttribute("tooltiptext", this._unstarredTooltip);
this.button.removeAttribute("starred");
this.button.setAttribute("tooltiptext", this._unstarredTooltip);
}
},
@ -1238,6 +1241,10 @@ let BookmarkingUI = {
// nsINavBookmarkObserver
onItemAdded: function BUI_onItemAdded(aItemId, aParentId, aIndex, aItemType,
aURI) {
if (!this.button) {
return;
}
if (aURI && aURI.equals(this._uri)) {
// If a new bookmark has been added to the tracked uri, register it.
if (this._itemIds.indexOf(aItemId) == -1) {
@ -1248,6 +1255,10 @@ let BookmarkingUI = {
},
onItemRemoved: function BUI_onItemRemoved(aItemId) {
if (!this.button) {
return;
}
let index = this._itemIds.indexOf(aItemId);
// If one of the tracked bookmarks has been removed, unregister it.
if (index != -1) {
@ -1258,6 +1269,10 @@ let BookmarkingUI = {
onItemChanged: function BUI_onItemChanged(aItemId, aProperty,
aIsAnnotationProperty, aNewValue) {
if (!this.button) {
return;
}
if (aProperty == "uri") {
let index = this._itemIds.indexOf(aItemId);
// If the changed bookmark was tracked, check if it is now pointing to

View File

@ -32,7 +32,6 @@
<command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
<command id="cmd_close" oncommand="BrowserCloseTabOrWindow()"/>
<command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
<command id="cmd_ToggleTabsOnTop" oncommand="TabsOnTop.toggle()"/>
<command id="cmd_CustomizeToolbars" oncommand="BrowserCustomizeToolbar()"/>
<command id="cmd_quitApplication" oncommand="goQuitApplication()"/>
@ -108,7 +107,6 @@
oncommand="OpenBrowserWindow({private: true});"/>
<command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
<command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
<command id="Browser:ToggleAddonBar" oncommand="toggleAddonBar();"/>
<command id="Social:TogglePageMark" oncommand="SocialMark.togglePageMark();" disabled="true"/>
<command id="Social:SharePage" oncommand="SocialShare.sharePage();" disabled="true"/>
<command id="Social:ToggleSidebar" oncommand="Social.toggleSidebar();"/>
@ -413,8 +411,6 @@
#expand <key id="key_selectTab8" oncommand="gBrowser.selectTabAtIndex(7, event);" key="8" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
#expand <key id="key_selectLastTab" oncommand="gBrowser.selectTabAtIndex(-1, event);" key="9" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
<key id="key_toggleAddonBar" command="Browser:ToggleAddonBar" key="&toggleAddonBarCmd.key;" modifiers="accel"/>
</keyset>
# Used by baseMenuOverlay

View File

@ -797,9 +797,7 @@ SocialShare = {
iframe.setAttribute("src", shareEndpoint);
let navBar = document.getElementById("nav-bar");
let anchor = navBar.getAttribute("mode") == "text" ?
document.getAnonymousElementByAttribute(this.shareButton, "class", "toolbarbutton-text") :
document.getAnonymousElementByAttribute(this.shareButton, "class", "toolbarbutton-icon");
let anchor = document.getAnonymousElementByAttribute(this.shareButton, "class", "toolbarbutton-icon");
this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
Social.setErrorListener(iframe, this.setErrorMessage.bind(this));
},
@ -1238,9 +1236,7 @@ SocialToolbar = {
});
let navBar = document.getElementById("nav-bar");
let anchor = navBar.getAttribute("mode") == "text" ?
document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-text") :
document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-badge-container");
let anchor = document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-badge-container");
// Bug 849216 - open the popup in a setTimeout so we avoid the auto-rollup
// handling from preventing it being opened in some cases.
setTimeout(function() {

View File

@ -420,16 +420,13 @@ let TabView = {
let toolbar = document.getElementById("TabsToolbar");
let currentSet = toolbar.currentSet.split(",");
let alltabsPos = currentSet.indexOf("alltabs-button");
if (-1 == alltabsPos)
return;
currentSet[alltabsPos] += "," + buttonId;
currentSet = currentSet.join(",");
toolbar.currentSet = currentSet;
toolbar.setAttribute("currentset", currentSet);
document.persist(toolbar.id, "currentset");
let allTabsBtn = document.getElementById("alltabs-button");
let nextItem = allTabsBtn.nextSibling;
toolbar.insertItem(buttonId, nextItem);
},
// ----------

View File

@ -13,6 +13,59 @@ browser[remote="true"] {
-moz-binding: url("chrome://global/content/bindings/remote-browser.xml#remote-browser");
}
toolbar[customizable="true"] {
-moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#toolbar");
}
%ifdef XP_MACOSX
toolbar[customizable="true"]:not([nowindowdrag="true"]) {
-moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#toolbar-drag");
}
%endif
#toolbar-menubar[autohide="true"] {
-moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#toolbar-menubar-autohide");
}
#addon-bar {
-moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#addonbar-delegating");
visibility: visible;
margin: 0;
height: 0 !important;
overflow: hidden;
padding: 0;
border: 0 none;
}
#addonbar-closebutton {
visibility: visible;
height: 0 !important;
}
#status-bar {
height: 0 !important;
-moz-binding: none;
padding: 0;
margin: 0;
}
panelmultiview {
-moz-binding: url("chrome://browser/content/customizableui/panelUI.xml#panelmultiview");
}
panelview {
-moz-binding: url("chrome://browser/content/customizableui/panelUI.xml#panelview");
-moz-box-orient: vertical;
}
.panel-mainview {
transition: transform 150ms;
}
panelview:not([mainview]):not([current]) {
display: none;
}
tabbrowser {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
}
@ -39,11 +92,11 @@ tabbrowser {
.tabbrowser-tab:not([pinned]) {
-moz-box-flex: 100;
max-width: 250px;
max-width: 180px;
min-width: 100px;
width: 0;
transition: min-width 200ms ease-out,
max-width 250ms ease-out,
max-width 230ms ease-out,
opacity 50ms ease-out 20ms /* hide the tab for the first 20ms of the max-width transition */;
}
@ -52,8 +105,8 @@ tabbrowser {
min-width: 0.1px;
opacity: 0 !important;
transition: min-width 200ms ease-out,
max-width 250ms ease-out,
opacity 50ms ease-out 180ms /* hide the tab for the last 20ms of the max-width transition */;
max-width 230ms ease-out,
opacity 50ms ease-out 160ms /* hide the tab for the last 20ms of the max-width transition */;
}
.tab-throbber:not([fadein]):not([pinned]),
@ -86,20 +139,13 @@ toolbar[printpreview="true"] {
-moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
}
#toolbar-menubar {
-moz-box-ordinal-group: 5;
toolbar[overflowable] > .customization-target {
overflow: hidden;
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
-moz-box-ordinal-group: 50;
}
#TabsToolbar {
-moz-box-ordinal-group: 100;
}
#TabsToolbar[tabsontop="true"] {
-moz-box-ordinal-group: 10;
toolbar[customizing][overflowable] > .overflow-button,
toolbar[overflowable]:not([overflowing]) > .overflow-button {
display: none;
}
%ifdef CAN_DRAW_IN_TITLEBAR
@ -117,10 +163,26 @@ toolbar[printpreview="true"] {
pointer-events: none;
}
#main-window[tabsintitlebar] #appmenu-button-container,
#main-window[tabsintitlebar] #titlebar-buttonbox {
position: relative;
}
#titlebar-buttonbox {
-moz-appearance: -moz-window-button-box;
}
%ifdef XP_MACOSX
#titlebar-fullscreen-button {
-moz-appearance: -moz-mac-fullscreen-button;
}
%endif
%ifdef XP_WIN
#main-window[sizemode="maximized"] #titlebar-buttonbox {
-moz-appearance: -moz-window-button-box-maximized;
}
%endif
%endif
.bookmarks-toolbar-customize,
@ -132,28 +194,27 @@ toolbar[printpreview="true"] {
display: -moz-box;
}
#main-window[disablechrome] #navigator-toolbox[tabsontop="true"] > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
visibility: collapse;
}
#wrapper-urlbar-container #urlbar-container > #urlbar > toolbarbutton,
#urlbar-container:not([combined]) > #urlbar > toolbarbutton,
#urlbar-container[combined] + #reload-button + #stop-button,
#urlbar-container[combined] + #reload-button,
toolbar:not([mode="icons"]) > #urlbar-container > #urlbar > toolbarbutton,
toolbar[mode="icons"] > #urlbar-container > #urlbar > #urlbar-reload-button:not([displaystop]) + #urlbar-stop-button,
toolbar[mode="icons"] > #urlbar-container > #urlbar > #urlbar-reload-button[displaystop],
toolbar[mode="icons"] > #reload-button:not([displaystop]) + #stop-button,
toolbar[mode="icons"] > #reload-button[displaystop] {
#urlbar-reload-button:not([displaystop]) + #urlbar-stop-button,
#urlbar-reload-button[displaystop],
#reload-button:not([displaystop]) + #stop-button,
#reload-button[displaystop] {
visibility: collapse;
}
#feed-button > .toolbarbutton-menu-dropmarker {
display: none;
#PanelUI-feeds > .feed-toolbarbutton:-moz-locale-dir(rtl) {
direction: rtl;
}
#feed-menu > .feed-menuitem:-moz-locale-dir(rtl) {
direction: rtl;
#urlbar-container {
min-width: 50ch;
}
#search-container {
min-width: 25ch;
}
#main-window:-moz-lwtheme {
@ -172,27 +233,6 @@ toolbar[mode="icons"] > #reload-button[displaystop] {
background-position: bottom left;
}
splitmenu {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#splitmenu");
}
.splitmenu-menuitem {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem");
list-style-image: inherit;
-moz-image-region: inherit;
}
.splitmenu-menuitem[iconic="true"] {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
.splitmenu-menu > .menu-text,
:-moz-any(.splitmenu-menu, .splitmenu-menuitem) > .menu-accel-container,
#appmenu-editmenu > .menu-text,
#appmenu-editmenu > .menu-accel-container {
display: none;
}
.menuitem-tooltip {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#menuitem-tooltip");
}
@ -203,18 +243,6 @@ splitmenu {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#menuitem-iconic-tooltip");
}
%ifdef MENUBAR_CAN_AUTOHIDE
%ifndef CAN_DRAW_IN_TITLEBAR
#appmenu-toolbar-button > .toolbarbutton-text {
display: -moz-box;
}
%endif
#appmenu_offlineModeRecovery:not([checked=true]) {
display: none;
}
%endif
/* Hide menu elements intended for keyboard access support */
#main-menubar[openedwithkey=false] .show-only-for-keyboard {
display: none;
@ -308,18 +336,20 @@ toolbarbutton.bookmark-item {
max-width: 13em;
}
%ifdef MENUBAR_CAN_AUTOHIDE
#toolbar-menubar:not([autohide="true"]) ~ toolbar > #bookmarks-menu-button,
#toolbar-menubar:not([autohide="true"]) > #bookmarks-menu-button {
display: none;
}
%endif
#editBMPanel_tagsSelector {
/* override default listbox width from xul.css */
width: auto;
}
/* The star doesn't make sense as text */
toolbar[mode="text"] #bookmarks-menu-button > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
display: -moz-box !important;
}
toolbar[mode="text"] #bookmarks-menu-button > .toolbarbutton-menubutton-button > .toolbarbutton-text,
toolbar[mode="full"] #bookmarks-menu-button.bookmark-item > .toolbarbutton-menubutton-button > .toolbarbutton-text {
display: none;
}
menupopup[emptyplacesresult="true"] > .hide-if-empty-places-result {
display: none;
}
@ -344,7 +374,6 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
}
#navigator-toolbox ,
#status-bar ,
#mainPopupSet {
min-width: 1px;
}
@ -443,14 +472,6 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
min-width: 1px;
}
#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-icon {
display: -moz-box;
}
#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-text {
display: none;
}
/* ::::: Ctrl-Tab Panel ::::: */
.ctrlTab-preview > html|img,
@ -515,17 +536,6 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#plugin-popupnotification-center-item");
}
/* override hidden="true" for the status bar compatibility shim
in case it was persisted for the real status bar */
#status-bar {
display: -moz-box;
}
/* Remove the resizer from the statusbar compatibility shim */
#status-bar[hideresizer] > .statusbar-resizerpanel {
display: none;
}
browser[tabmodalPromptShowing] {
-moz-user-focus: none !important;
}

View File

@ -94,6 +94,12 @@ XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
"resource:///modules/AboutHomeUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "gCustomizeMode", function() {
let scope = {};
Cu.import("resource:///modules/CustomizeMode.jsm", scope);
return new scope.CustomizeMode(window);
});
#ifdef MOZ_SERVICES_SYNC
XPCOMUtils.defineLazyModuleGetter(this, "Weave",
"resource://services-sync/main.js");
@ -154,6 +160,7 @@ let gInitialPages = [
];
#include browser-addons.js
#include browser-customization.js
#include browser-feeds.js
#include browser-fullScreen.js
#include browser-fullZoom.js
@ -927,9 +934,6 @@ var gBrowserInit = {
document.documentElement.setAttribute("height", defaultHeight);
}
if (!gShowPageResizers)
document.getElementById("status-bar").setAttribute("hideresizer", "true");
if (!window.toolbar.visible) {
// adjust browser UI for popups
if (gURLBar) {
@ -939,16 +943,14 @@ var gBrowserInit = {
goSetCommandEnabled("cmd_newNavigatorTab", false);
}
#ifdef MENUBAR_CAN_AUTOHIDE
updateAppButtonDisplay();
#ifdef CAN_DRAW_IN_TITLEBAR
updateTitlebarDisplay();
#endif
// Misc. inits.
CombinedStopReload.init();
TabsOnTop.init();
gPrivateBrowsingUI.init();
TabsInTitlebar.init();
retrieveToolbarIconsizesFromTheme();
// Wait until chrome is painted before executing code not critical to making the window visible
this._boundDelayedStartup = this._delayedStartup.bind(this, uriToLoad, mustLoadSidebar);
@ -1045,8 +1047,13 @@ var gBrowserInit = {
OfflineApps.init();
IndexedDBPromptHelper.init();
gFormSubmitObserver.init();
// Initialize the full zoom setting.
// We do this before the session restore service gets initialized so we can
// apply full zoom settings to tabs restored by the session restore service.
FullZoom.init();
PanelUI.init();
SocialUI.init();
AddonManager.addAddonListener(AddonsMgrListener);
LightweightThemeListener.init();
WebrtcIndicator.init();
// Ensure login manager is up and running.
@ -1092,11 +1099,6 @@ var gBrowserInit = {
if (!getBoolPref("ui.click_hold_context_menus", false))
SetClickAndHoldHandlers();
// Initialize the full zoom setting.
// We do this before the session restore service gets initialized so we can
// apply full zoom settings to tabs restored by the session restore service.
FullZoom.init();
// Bug 666804 - NetworkPrioritizer support for e10s
if (!gMultiProcessBrowser) {
let NP = {};
@ -1231,15 +1233,6 @@ var gBrowserInit = {
cmd.removeAttribute("hidden");
}
#ifdef MENUBAR_CAN_AUTOHIDE
// If the user (or the locale) hasn't enabled the top-level "Character
// Encoding" menu via the "browser.menu.showCharacterEncoding" preference,
// hide it.
if ("true" != gPrefService.getComplexValue("browser.menu.showCharacterEncoding",
Ci.nsIPrefLocalizedString).data)
document.getElementById("appmenu_charsetMenu").hidden = true;
#endif
// Enable Responsive UI?
let responsiveUIEnabled = gPrefService.getBoolPref("devtools.responsiveUI.enabled");
if (responsiveUIEnabled) {
@ -1251,26 +1244,12 @@ var gBrowserInit = {
// Add Devtools menuitems and listeners
gDevToolsBrowser.registerBrowserWindow(window);
let appMenuButton = document.getElementById("appmenu-button");
let appMenuPopup = document.getElementById("appmenu-popup");
if (appMenuButton && appMenuPopup) {
let appMenuOpening = null;
appMenuButton.addEventListener("mousedown", function(event) {
if (event.button == 0)
appMenuOpening = new Date();
}, false);
appMenuPopup.addEventListener("popupshown", function(event) {
if (event.target != appMenuPopup || !appMenuOpening)
return;
let duration = new Date() - appMenuOpening;
appMenuOpening = null;
Services.telemetry.getHistogramById("FX_APP_MENU_OPEN_MS").add(duration);
}, false);
}
window.addEventListener("mousemove", MousePosTracker, false);
window.addEventListener("dragover", MousePosTracker, false);
gNavToolbox.addEventListener("customizationstarting", CustomizationHandler);
gNavToolbox.addEventListener("customizationending", CustomizationHandler);
// End startup crash tracking after a delay to catch crashes while restoring
// tabs and to postpone saving the pref to disk.
try {
@ -1329,8 +1308,6 @@ var gBrowserInit = {
BookmarkingUI.uninit();
TabsOnTop.uninit();
TabsInTitlebar.uninit();
var enumerator = Services.wm.getEnumerator(null);
@ -1381,8 +1358,9 @@ var gBrowserInit = {
BrowserOffline.uninit();
OfflineApps.uninit();
IndexedDBPromptHelper.uninit();
AddonManager.removeAddonListener(AddonsMgrListener);
SocialUI.uninit();
LightweightThemeListener.uninit();
PanelUI.uninit();
}
// Final window teardown, do this last.
@ -1408,7 +1386,7 @@ var gBrowserInit = {
'viewToolbarsMenu', 'viewSidebarMenuMenu', 'Browser:Reload',
'viewFullZoomMenu', 'pageStyleMenu', 'charsetMenu', 'View:PageSource', 'View:FullScreen',
'viewHistorySidebar', 'Browser:AddBookmarkAs', 'Browser:BookmarkAllTabs',
'View:PageInfo', 'Browser:ToggleTabView', 'Browser:ToggleAddonBar'];
'View:PageInfo', 'Browser:ToggleTabView'];
var element;
for (let disabledItem of disabledItems) {
@ -2690,8 +2668,8 @@ var PrintPreviewListener = {
if (this._chromeState.sidebarOpen)
toggleSidebar(this._sidebarCommand);
#ifdef MENUBAR_CAN_AUTOHIDE
updateAppButtonDisplay();
#ifdef CAN_DRAW_IN_TITLEBAR
updateTitlebarDisplay();
#endif
},
_hideChrome: function () {
@ -2706,9 +2684,6 @@ var PrintPreviewListener = {
notificationBox.notificationsHidden = true;
document.getElementById("sidebar").setAttribute("src", "about:blank");
var addonBar = document.getElementById("addon-bar");
this._chromeState.addonBarOpen = !addonBar.collapsed;
addonBar.collapsed = true;
gBrowser.updateWindowResizers();
this._chromeState.findOpen = gFindBarInitialized && !gFindBar.hidden;
@ -2730,11 +2705,6 @@ var PrintPreviewListener = {
if (this._chromeState.notificationsOpen)
gBrowser.getNotificationBox().notificationsHidden = false;
if (this._chromeState.addonBarOpen) {
document.getElementById("addon-bar").collapsed = false;
gBrowser.updateWindowResizers();
}
if (this._chromeState.findOpen)
gFindBar.open();
@ -2811,35 +2781,6 @@ function openHomeDialog(aURL)
}
}
var bookmarksButtonObserver = {
onDrop: function (aEvent)
{
let name = { };
let url = browserDragAndDrop.drop(aEvent, name);
try {
PlacesUIUtils.showBookmarkDialog({ action: "add"
, type: "bookmark"
, uri: makeURI(url)
, title: name
, hiddenRows: [ "description"
, "location"
, "loadInSidebar"
, "keyword" ]
}, window);
} catch(ex) { }
},
onDragOver: function (aEvent)
{
browserDragAndDrop.dragOver(aEvent);
aEvent.dropEffect = "link";
},
onDragExit: function (aEvent)
{
}
}
var newTabButtonObserver = {
onDragOver: function (aEvent)
{
@ -3358,154 +3299,18 @@ function OpenBrowserWindow(options)
return win;
}
var gCustomizeSheet = false;
//XXXunf Are these still useful to keep around?
function BrowserCustomizeToolbar() {
// Disable the toolbar context menu items
var menubar = document.getElementById("main-menubar");
for (let childNode of menubar.childNodes)
childNode.setAttribute("disabled", true);
var cmd = document.getElementById("cmd_CustomizeToolbars");
cmd.setAttribute("disabled", "true");
var splitter = document.getElementById("urlbar-search-splitter");
if (splitter)
splitter.parentNode.removeChild(splitter);
CombinedStopReload.uninit();
PlacesToolbarHelper.customizeStart();
BookmarkingUI.customizeStart();
DownloadsButton.customizeStart();
TabsInTitlebar.allowedBy("customizing-toolbars", false);
var customizeURL = "chrome://global/content/customizeToolbar.xul";
gCustomizeSheet = getBoolPref("toolbar.customization.usesheet", false);
if (gCustomizeSheet) {
let sheetFrame = document.createElement("iframe");
let panel = document.getElementById("customizeToolbarSheetPopup");
sheetFrame.id = "customizeToolbarSheetIFrame";
sheetFrame.toolbox = gNavToolbox;
sheetFrame.panel = panel;
sheetFrame.setAttribute("style", panel.getAttribute("sheetstyle"));
panel.appendChild(sheetFrame);
// Open the panel, but make it invisible until the iframe has loaded so
// that the user doesn't see a white flash.
panel.style.visibility = "hidden";
gNavToolbox.addEventListener("beforecustomization", function onBeforeCustomization() {
gNavToolbox.removeEventListener("beforecustomization", onBeforeCustomization, false);
panel.style.removeProperty("visibility");
}, false);
sheetFrame.setAttribute("src", customizeURL);
panel.openPopup(gNavToolbox, "after_start", 0, 0);
} else {
window.openDialog(customizeURL,
"CustomizeToolbar",
"chrome,titlebar,toolbar,location,resizable,dependent",
gNavToolbox);
}
gCustomizeMode.enter();
}
function BrowserToolboxCustomizeDone(aToolboxChanged) {
if (gCustomizeSheet) {
document.getElementById("customizeToolbarSheetPopup").hidePopup();
let iframe = document.getElementById("customizeToolbarSheetIFrame");
iframe.parentNode.removeChild(iframe);
}
// Update global UI elements that may have been added or removed
if (aToolboxChanged) {
gURLBar = document.getElementById("urlbar");
gProxyFavIcon = document.getElementById("page-proxy-favicon");
gHomeButton.updateTooltip();
gIdentityHandler._cacheElements();
window.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();
setUrlAndSearchBarWidthForConditionalForwardButton();
// Update the urlbar
if (gURLBar) {
URLBarSetURI();
XULBrowserWindow.asyncUpdateUI();
BookmarkingUI.updateStarState();
SocialMark.updateMarkState();
SocialShare.update();
}
TabsInTitlebar.allowedBy("customizing-toolbars", true);
// Re-enable parts of the UI we disabled during the dialog
var menubar = document.getElementById("main-menubar");
for (let childNode of menubar.childNodes)
childNode.setAttribute("disabled", false);
var cmd = document.getElementById("cmd_CustomizeToolbars");
cmd.removeAttribute("disabled");
// make sure to re-enable click-and-hold
if (!getBoolPref("ui.click_hold_context_menus", false))
SetClickAndHoldHandlers();
gBrowser.selectedBrowser.focus();
gCustomizeMode.exit(aToolboxChanged);
}
function BrowserToolboxCustomizeChange(aType) {
switch (aType) {
case "iconsize":
case "mode":
retrieveToolbarIconsizesFromTheme();
break;
default:
gHomeButton.updatePersonalToolbarStyle();
BookmarkingUI.customizeChange();
}
}
/**
* Allows themes to override the "iconsize" attribute on toolbars.
*/
function retrieveToolbarIconsizesFromTheme() {
function retrieveToolbarIconsize(aToolbar) {
if (aToolbar.localName != "toolbar")
return;
// The theme indicates that it wants to override the "iconsize" attribute
// by specifying a special value for the "counter-reset" property on the
// toolbar. A custom property cannot be used because getComputedStyle can
// only return the values of standard CSS properties.
let counterReset = getComputedStyle(aToolbar).counterReset;
if (counterReset == "smallicons 0")
aToolbar.setAttribute("iconsize", "small");
else if (counterReset == "largeicons 0")
aToolbar.setAttribute("iconsize", "large");
}
Array.forEach(gNavToolbox.childNodes, retrieveToolbarIconsize);
gNavToolbox.externalToolbars.forEach(retrieveToolbarIconsize);
gHomeButton.updatePersonalToolbarStyle();
BookmarksMenuButton.customizeChange();
}
/**
@ -3534,9 +3339,6 @@ function updateEditUIVisibility()
let editMenuPopupState = document.getElementById("menu_EditPopup").state;
let contextMenuPopupState = document.getElementById("contentAreaContextMenu").state;
let placesContextMenuPopupState = document.getElementById("placesContext").state;
#ifdef MENUBAR_CAN_AUTOHIDE
let appMenuPopupState = document.getElementById("appmenu-popup").state;
#endif
// The UI is visible if the Edit menu is opening or open, if the context menu
// is open, or if the toolbar has been customized to include the Cut, Copy,
@ -3547,13 +3349,7 @@ function updateEditUIVisibility()
contextMenuPopupState == "open" ||
placesContextMenuPopupState == "showing" ||
placesContextMenuPopupState == "open" ||
#ifdef MENUBAR_CAN_AUTOHIDE
appMenuPopupState == "showing" ||
appMenuPopupState == "open" ||
#endif
document.getElementById("cut-button") ||
document.getElementById("copy-button") ||
document.getElementById("paste-button") ? true : false;
document.getElementById("edit-controls") ? true : false;
// If UI is visible, update the edit commands' enabled state to reflect
// whether or not they are actually enabled for the current focus/selection.
@ -3583,9 +3379,6 @@ function updateEditUIVisibility()
function updateCharacterEncodingMenuState()
{
let charsetMenu = document.getElementById("charsetMenu");
let appCharsetMenu = document.getElementById("appmenu_charsetMenu");
let appDevCharsetMenu =
document.getElementById("appmenu_developer_charsetMenu");
// gBrowser is null on Mac when the menubar shows in the context of
// non-browser windows. The above elements may be null depending on
// what parts of the menubar are present. E.g. no app menu on Mac.
@ -3595,22 +3388,10 @@ function updateCharacterEncodingMenuState()
if (charsetMenu) {
charsetMenu.removeAttribute("disabled");
}
if (appCharsetMenu) {
appCharsetMenu.removeAttribute("disabled");
}
if (appDevCharsetMenu) {
appDevCharsetMenu.removeAttribute("disabled");
}
} else {
if (charsetMenu) {
charsetMenu.setAttribute("disabled", "true");
}
if (appCharsetMenu) {
appCharsetMenu.setAttribute("disabled", "true");
}
if (appDevCharsetMenu) {
appDevCharsetMenu.setAttribute("disabled", "true");
}
}
}
@ -3642,8 +3423,8 @@ var XULBrowserWindow = {
startTime: 0,
statusText: "",
isBusy: false,
inContentWhitelist: ["about:addons", "about:downloads", "about:permissions",
"about:sync-progress", "about:preferences"],
// Left here for add-on compatibility, see bug 752434
inContentWhitelist: [],
QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIWebProgressListener) ||
@ -3673,8 +3454,6 @@ var XULBrowserWindow = {
},
init: function () {
this.throbberElement = document.getElementById("navigator-throbber");
// Bug 666809 - SecurityUI support for e10s
if (gMultiProcessBrowser)
return;
@ -3688,7 +3467,6 @@ var XULBrowserWindow = {
destroy: function () {
// XXXjag to avoid leaks :-/, see bug 60729
delete this.throbberElement;
delete this.stopCommand;
delete this.reloadCommand;
delete this.statusTextField;
@ -3813,10 +3591,6 @@ var XULBrowserWindow = {
if (!(aStateFlags & nsIWebProgressListener.STATE_RESTORING)) {
this._busyUI = true;
// Turn the throbber on.
if (this.throbberElement)
this.throbberElement.setAttribute("busy", "true");
// XXX: This needs to be based on window activity...
this.stopCommand.removeAttribute("disabled");
CombinedStopReload.switchToStop();
@ -3861,10 +3635,6 @@ var XULBrowserWindow = {
if (this._busyUI) {
this._busyUI = false;
// Turn the throbber off.
if (this.throbberElement)
this.throbberElement.removeAttribute("busy");
this.stopCommand.setAttribute("disabled", "true");
CombinedStopReload.switchToReload(aRequest instanceof Ci.nsIRequest);
}
@ -3933,17 +3703,6 @@ var XULBrowserWindow = {
SocialShare.update();
}
// Show or hide browser chrome based on the whitelist
if (this.hideChromeForLocation(location)) {
document.documentElement.setAttribute("disablechrome", "true");
} else {
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
if (ss.getTabValue(gBrowser.selectedTab, "appOrigin"))
document.documentElement.setAttribute("disablechrome", "true");
else
document.documentElement.removeAttribute("disablechrome");
}
// Utility functions for disabling find
var shouldDisableFind = function shouldDisableFind(aDocument) {
let docElt = aDocument.documentElement;
@ -4003,6 +3762,17 @@ var XULBrowserWindow = {
// fix bug 253793 - turn off highlight when page changes
gFindBar.getElement("highlight").checked = false;
}
// Try not to instantiate gCustomizeMode as much as possible,
// so don't use CustomizeMode.jsm to check for URI or customizing.
let customizingURI = "about:customizing";
if (location == customizingURI &&
!CustomizationHandler.isCustomizing()) {
gCustomizeMode.enter();
} else if (location != customizingURI &&
CustomizationHandler.isCustomizing()) {
gCustomizeMode.exit();
}
}
UpdateBackForwardCommands(gBrowser.webNavigation);
@ -4020,12 +3790,8 @@ var XULBrowserWindow = {
FeedHandler.updateFeeds();
},
hideChromeForLocation: function(aLocation) {
aLocation = aLocation.toLowerCase();
return this.inContentWhitelist.some(function(aSpec) {
return aSpec == aLocation;
});
},
// Left here for add-on compatibility, see bug 752434
hideChromeForLocation: function() {},
onStatusChange: function (aWebProgress, aRequest, aStatus, aMessage) {
this.status = aMessage;
@ -4203,8 +3969,7 @@ var CombinedStopReload = {
var stop = document.getElementById("stop-button");
if (urlbar) {
if (urlbar.parentNode.getAttribute("mode") != "icons" ||
!reload || urlbar.nextSibling != reload ||
if (!reload || urlbar.nextSibling != reload ||
!stop || reload.nextSibling != stop)
urlbar.removeAttribute("combined");
else {
@ -4518,7 +4283,6 @@ function onViewToolbarsPopupShowing(aEvent, aInsertPoint) {
var firstMenuItem = aInsertPoint || popup.firstChild;
let toolbarNodes = Array.slice(gNavToolbox.childNodes);
toolbarNodes.push(document.getElementById("addon-bar"));
for (let toolbar of toolbarNodes) {
let toolbarName = toolbar.getAttribute("toolbarname");
@ -4531,8 +4295,6 @@ function onViewToolbarsPopupShowing(aEvent, aInsertPoint) {
menuItem.setAttribute("type", "checkbox");
menuItem.setAttribute("label", toolbarName);
menuItem.setAttribute("checked", toolbar.getAttribute(hidingAttribute) != "true");
if (popup.id != "appmenu_customizeMenu")
menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
if (popup.id != "toolbar-context-menu")
menuItem.setAttribute("key", toolbar.getAttribute("key"));
@ -4561,72 +4323,30 @@ function setToolbarVisibility(toolbar, isVisible) {
BookmarkingUI.onToolbarVisibilityChange();
gBrowser.updateWindowResizers();
#ifdef MENUBAR_CAN_AUTOHIDE
updateAppButtonDisplay();
#ifdef CAN_DRAW_IN_TITLEBAR
updateTitlebarDisplay();
#endif
}
var TabsOnTop = {
init: function TabsOnTop_init() {
Services.prefs.addObserver(this._prefName, this, false);
// Only show the toggle UI if the user disabled tabs on top.
if (Services.prefs.getBoolPref(this._prefName)) {
for (let item of document.querySelectorAll("menuitem[command=cmd_ToggleTabsOnTop]"))
item.parentNode.removeChild(item);
}
},
uninit: function TabsOnTop_uninit() {
Services.prefs.removeObserver(this._prefName, this);
},
toggle: function () {
this.enabled = !Services.prefs.getBoolPref(this._prefName);
},
syncUI: function () {
let userEnabled = Services.prefs.getBoolPref(this._prefName);
let enabled = userEnabled && gBrowser.tabContainer.visible;
document.getElementById("cmd_ToggleTabsOnTop")
.setAttribute("checked", userEnabled);
document.documentElement.setAttribute("tabsontop", enabled);
document.getElementById("navigator-toolbox").setAttribute("tabsontop", enabled);
document.getElementById("TabsToolbar").setAttribute("tabsontop", enabled);
document.getElementById("nav-bar").setAttribute("tabsontop", enabled);
gBrowser.tabContainer.setAttribute("tabsontop", enabled);
TabsInTitlebar.allowedBy("tabs-on-top", enabled);
},
get enabled () {
return gNavToolbox.getAttribute("tabsontop") == "true";
},
set enabled (val) {
Services.prefs.setBoolPref(this._prefName, !!val);
return val;
},
observe: function (subject, topic, data) {
if (topic == "nsPref:changed")
this.syncUI();
},
_prefName: "browser.tabs.onTop"
}
var TabsInTitlebar = {
init: function () {
#ifdef CAN_DRAW_IN_TITLEBAR
this._readPref();
Services.prefs.addObserver(this._prefName, this, false);
// Don't trust the initial value of the sizemode attribute; wait for
// the resize event (handled in tabbrowser.xml).
this.allowedBy("sizemode", false);
// We need to update the appearance of the titlebar when the menu changes
// from the active to the inactive state. We can't, however, rely on
// DOMMenuBarInactive, because the menu fires this event and then removes
// the inactive attribute after an event-loop spin.
//
// Because updating the appearance involves sampling the heights and margins
// of various elements, it's important that the layout be more or less
// settled before updating the titlebar. So instead of listening to
// DOMMenuBarActive and DOMMenuBarInactive, we use a MutationObserver to
// watch the "invalid" attribute directly.
let menu = document.getElementById("toolbar-menubar");
this._menuObserver = new MutationObserver(this._onMenuMutate);
this._menuObserver.observe(menu, {attributes: true});
this._initialized = true;
#endif
},
@ -4636,17 +4356,23 @@ var TabsInTitlebar = {
if (allow) {
if (condition in this._disallowed) {
delete this._disallowed[condition];
this._update();
this._update(true);
}
} else {
if (!(condition in this._disallowed)) {
this._disallowed[condition] = null;
this._update();
this._update(true);
}
}
#endif
},
updateAppearance: function updateAppearance(aForce) {
#ifdef CAN_DRAW_IN_TITLEBAR
this._update(aForce);
#endif
},
get enabled() {
return document.documentElement.getAttribute("tabsintitlebar") == "true";
},
@ -4657,16 +4383,33 @@ var TabsInTitlebar = {
this._readPref();
},
_onMenuMutate: function (aMutations) {
// We don't care about restored windows, since the menu shouldn't be
// pushing the tab-strip down.
if (document.documentElement.getAttribute("sizemode") == "normal") {
return;
}
for (let mutation of aMutations) {
if (mutation.attributeName == "inactive" ||
mutation.attributeName == "autohide") {
TabsInTitlebar._update(true);
return;
}
}
},
_initialized: false,
_disallowed: {},
_prefName: "browser.tabs.drawInTitlebar",
_lastSizeMode: null,
_readPref: function () {
this.allowedBy("pref",
Services.prefs.getBoolPref(this._prefName));
},
_update: function () {
_update: function (aForce=false) {
function $(id) document.getElementById(id);
function rect(ele) ele.getBoundingClientRect();
@ -4674,45 +4417,99 @@ var TabsInTitlebar = {
return;
let allowed = true;
if (!aForce) {
// _update is called on resize events, because the window is not ready
// after sizemode events. However, we only care about the event when the
// sizemode is different from the last time we updated the appearance of
// the tabs in the titlebar.
let sizemode = document.documentElement.getAttribute("sizemode");
if (this._lastSizeMode == sizemode) {
return;
}
this._lastSizeMode = sizemode;
}
for (let something in this._disallowed) {
allowed = false;
break;
}
if (allowed == this.enabled)
return;
function $(id) document.getElementById(id);
let titlebar = $("titlebar");
let titlebarContent = $("titlebar-content");
let menubar = $("toolbar-menubar");
// Reset the margins and padding that _update modifies so that we can take
// accurate measurements.
titlebarContent.style.marginBottom = "";
titlebar.style.marginBottom = "";
menubar.style.paddingBottom = "";
if (allowed) {
let tabsToolbar = $("TabsToolbar");
#ifdef MENUBAR_CAN_AUTOHIDE
let appmenuButtonBox = $("appmenu-button-container");
this._sizePlaceholder("appmenu-button", rect(appmenuButtonBox).width);
#endif
let captionButtonsBox = $("titlebar-buttonbox");
this._sizePlaceholder("caption-buttons", rect(captionButtonsBox).width);
let tabsToolbarRect = rect(tabsToolbar);
let titlebarTop = rect($("titlebar-content")).top;
titlebar.style.marginBottom = - Math.min(tabsToolbarRect.top - titlebarTop,
tabsToolbarRect.height) + "px";
// We set the tabsintitlebar attribute first so that our CSS for
// tabsintitlebar manifests before we do our measurements.
document.documentElement.setAttribute("tabsintitlebar", "true");
if (!this._draghandle) {
let captionButtonsBox = $("titlebar-buttonbox");
this._sizePlaceholder("caption-buttons", rect(captionButtonsBox).width);
#ifdef XP_MACOSX
let fullscreenButton = $("titlebar-fullscreen-button");
this._sizePlaceholder("fullscreen-button", rect(fullscreenButton).width);
#endif
let titlebarContentHeight = rect(titlebarContent).height;
let menuHeight = this._outerHeight(menubar);
// If the titlebar is taller than the menubar, add more padding to the
// bottom of the menubar so that it matches.
if (menuHeight && titlebarContentHeight > menuHeight) {
let menuTitlebarDelta = titlebarContentHeight - menuHeight;
menubar.style.paddingBottom = menuTitlebarDelta + "px";
menuHeight += menuTitlebarDelta;
}
// Next, we calculate how much we need to stretch the titlebar down to
// go all the way to the bottom of the tab strip.
let tabsToolbar = $("TabsToolbar");
let tabAndMenuHeight = this._outerHeight(tabsToolbar) + menuHeight;
titlebarContent.style.marginBottom = tabAndMenuHeight + "px";
// Finally, we have to determine how much to bring up the elements below
// the titlebar. We start with a baseHeight of tabAndMenuHeight, to offset
// the amount we added to the titlebar content. Then, we have two cases:
//
// 1) The titlebar is larger than the tabAndMenuHeight. This can happen in
// large font mode with the menu autohidden. In this case, we want to
// add tabAndMenuHeight, since this should line up the bottom of the
// tabstrip with the bottom of the titlebar.
//
// 2) The titlebar is equal to or smaller than the tabAndMenuHeight. This
// is the more common case, and occurs with normal font sizes. In this
// case, we want to bring the menu and tabstrip right up to the top of
// the titlebar, so we add the titlebarContentHeight to the baseHeight.
let baseHeight = tabAndMenuHeight;
baseHeight += (titlebarContentHeight > tabAndMenuHeight) ? tabAndMenuHeight
: titlebarContentHeight;
titlebar.style.marginBottom = "-" + baseHeight + "px";
if (!this._draghandles) {
this._draghandles = {};
let tmp = {};
Components.utils.import("resource://gre/modules/WindowDraggingUtils.jsm", tmp);
this._draghandle = new tmp.WindowDraggingElement(tabsToolbar);
this._draghandle.mouseDownCheck = function () {
let mouseDownCheck = function () {
return !this._dragBindingAlive && TabsInTitlebar.enabled;
};
this._draghandles.tabsToolbar = new tmp.WindowDraggingElement(tabsToolbar);
this._draghandles.tabsToolbar.mouseDownCheck = mouseDownCheck;
this._draghandles.navToolbox = new tmp.WindowDraggingElement(gNavToolbox);
this._draghandles.navToolbox.mouseDownCheck = mouseDownCheck;
}
} else {
document.documentElement.removeAttribute("tabsintitlebar");
titlebar.style.marginBottom = "";
}
},
@ -4720,36 +4517,45 @@ var TabsInTitlebar = {
Array.forEach(document.querySelectorAll(".titlebar-placeholder[type='"+ type +"']"),
function (node) { node.width = width; });
},
/**
* Retrieve the height of an element, including its top and bottom
* margins.
*
* @param ele
* The element to measure.
* @return
* The height and margins as an integer. If the height of the element
* is 0, then this returns 0, regardless of what the margins are.
*/
_outerHeight: function (ele) {
let cstyle = document.defaultView.getComputedStyle(ele);
let margins = parseInt(cstyle.marginTop) + parseInt(cstyle.marginBottom);
let height = ele.getBoundingClientRect().height;
return height > 0 ? Math.abs(height + margins) : 0;
},
#endif
uninit: function () {
#ifdef CAN_DRAW_IN_TITLEBAR
this._initialized = false;
Services.prefs.removeObserver(this._prefName, this);
this._menuObserver.disconnect();
#endif
}
};
#ifdef MENUBAR_CAN_AUTOHIDE
function updateAppButtonDisplay() {
var displayAppButton =
!gInPrintPreviewMode &&
window.menubar.visible &&
document.getElementById("toolbar-menubar").getAttribute("autohide") == "true";
#ifdef CAN_DRAW_IN_TITLEBAR
document.getElementById("titlebar").hidden = !displayAppButton;
function updateTitlebarDisplay() {
let drawInTitlebar = !gInPrintPreviewMode && window.toolbar.visible;
document.getElementById("titlebar").hidden = !drawInTitlebar;
if (displayAppButton)
if (drawInTitlebar)
document.documentElement.setAttribute("chromemargin", "0,2,2,2");
else
document.documentElement.removeAttribute("chromemargin");
TabsInTitlebar.allowedBy("drawing-in-titlebar", displayAppButton);
#else
document.getElementById("appmenu-toolbar-button").hidden =
!displayAppButton;
#endif
TabsInTitlebar.allowedBy("drawing-in-titlebar", drawInTitlebar);
}
#endif
@ -6972,12 +6778,6 @@ let gPrivateBrowsingUI = {
document.getElementById("Tools:Sanitize").setAttribute("disabled", "true");
if (window.location.href == getBrowserURL()) {
#ifdef XP_MACOSX
if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
document.documentElement.setAttribute("drawintitlebar", true);
}
#endif
// Adjust the window's title
let docElement = document.documentElement;
if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
@ -6994,7 +6794,6 @@ let gPrivateBrowsingUI = {
// Adjust the New Window menu entries
[
{ normal: "menu_newNavigator", private: "menu_newPrivateWindow" },
{ normal: "appmenu_newNavigator", private: "appmenu_newPrivateWindow" },
].forEach(function(menu) {
let newWindow = document.getElementById(menu.normal);
let newPrivateWindow = document.getElementById(menu.private);
@ -7208,11 +7007,6 @@ function duplicateTabIn(aTab, where, delta) {
}
}
function toggleAddonBar() {
let addonBar = document.getElementById("addon-bar");
setToolbarVisibility(addonBar, addonBar.collapsed);
}
var Scratchpad = {
prefEnabledName: "devtools.scratchpad.enabled",

File diff suppressed because it is too large Load Diff

View File

@ -9,5 +9,6 @@
<script type="application/javascript" src="chrome://browser/content/browser.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/downloads.js"/>
<script type="application/javascript" src="chrome://browser/content/downloads/indicator.js"/>
<script type="application/javascript" src="chrome://browser/content/customizableui/panelUI.js"/>
<script type="application/javascript" src="chrome://global/content/inlineSpellCheckUI.js"/>
<script type="application/javascript" src="chrome://global/content/viewSourceUtils.js"/>

View File

@ -31,6 +31,7 @@
label="&newtab.undo.restoreButton;"
class="newtab-undo-button" />
<xul:toolbarbutton id="newtab-undo-close-button" tabindex="-1"
class="close-icon"
tooltiptext="&newtab.undo.closeTooltip;" />
</div>
</div>

View File

@ -83,7 +83,7 @@
<content>
<xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type">
<xul:toolbarbutton ondblclick="event.stopPropagation();"
class="messageCloseButton tabbable"
class="messageCloseButton close-icon tabbable"
xbl:inherits="hidden=hideclose"
tooltiptext="&closeNotification.tooltip;"
oncommand="document.getBindingParent(this).close()"/>

View File

@ -41,6 +41,7 @@ tabpanels {
z-index: 2;
}
.tab-icon-image:not([src]):not([pinned]),
.tab-throbber:not([busy]),
.tab-throbber[busy] + .tab-icon-image {
display: none;

View File

@ -140,8 +140,7 @@
if (!window.gShowPageResizers)
return;
var show = document.getElementById("addon-bar").collapsed &&
window.windowState == window.STATE_NORMAL;
var show = window.windowState == window.STATE_NORMAL;
for (let i = 0; i < this.browsers.length; i++) {
this.browsers[i].showWindowResizer = show;
}
@ -1343,8 +1342,7 @@
b.setAttribute("remote", "true");
}
if (window.gShowPageResizers && document.getElementById("addon-bar").collapsed &&
window.windowState == window.STATE_NORMAL) {
if (window.gShowPageResizers && window.windowState == window.STATE_NORMAL) {
b.setAttribute("showresizer", "true");
}
@ -3199,10 +3197,6 @@
document.getElementById("menu_close").setAttribute("label",
this.tabbrowser.mStringBundle.getString(visible ? "tabs.closeTab" : "tabs.close"));
goSetCommandEnabled("cmd_ToggleTabsOnTop", visible);
TabsOnTop.syncUI();
TabsInTitlebar.allowedBy("tabs-visible", visible);
]]></body>
</method>
@ -3554,9 +3548,7 @@
if (aEvent.target != window)
break;
let sizemode = document.documentElement.getAttribute("sizemode");
TabsInTitlebar.allowedBy("sizemode",
sizemode == "maximized" || sizemode == "fullscreen");
TabsInTitlebar.updateAppearance();
var width = this.mTabstrip.boxObject.width;
if (width != this.mTabstripWidth) {
@ -3857,8 +3849,7 @@
// When the tabbar has an unified appearance with the titlebar
// and menubar, a double-click in it should have the same behavior
// as double-clicking the titlebar
if (TabsInTitlebar.enabled ||
(TabsOnTop.enabled && this.parentNode._dragBindingAlive))
if (TabsInTitlebar.enabled || this.parentNode._dragBindingAlive)
return;
#endif
@ -4289,7 +4280,7 @@
var clickedOnce = false;
function enableDblClick(event) {
var target = event.originalTarget;
if (target.className == 'tab-close-button')
if (target.classList.contains("tab-close-button"))
target._ignoredClick = true;
if (!clickedOnce) {
clickedOnce = true;
@ -4345,7 +4336,7 @@
role="presentation"/>
<xul:toolbarbutton anonid="close-button"
xbl:inherits="fadein,pinned,selected"
class="tab-close-button"/>
class="tab-close-button close-icon"/>
</xul:hbox>
</xul:stack>
</content>

View File

@ -137,10 +137,7 @@ MOCHITEST_BROWSER_FILES = \
browser_bug595507.js \
browser_bug596687.js \
browser_bug597218.js \
browser_bug598923.js \
browser_bug599325.js \
browser_bug609700.js \
browser_bug616836.js \
browser_bug623155.js \
browser_bug623893.js \
browser_bug624734.js \
@ -168,14 +165,12 @@ MOCHITEST_BROWSER_FILES = \
browser_bug832435.js \
browser_bug839103.js \
browser_canonizeURL.js \
browser_customize.js \
browser_findbarClose.js \
browser_homeDrop.js \
browser_keywordBookmarklets.js \
browser_contextSearchTabPosition.js \
browser_ctrlTab.js \
browser_customize_popupNotification.js \
browser_disablechrome.js \
browser_discovery.js \
browser_duplicateIDs.js \
browser_fullscreen-window-open.js \
@ -243,7 +238,6 @@ MOCHITEST_BROWSER_FILES = \
browser_visibleTabs_bookmarkAllTabs.js \
browser_visibleTabs_tabPreview.js \
bug592338.html \
disablechrome.html \
discovery.html \
domplate_test.js \
file_bug822367_1.html \
@ -287,9 +281,6 @@ MOCHITEST_BROWSER_FILES = \
app_bug575561.html \
app_subframe_bug575561.html \
browser_contentAreaClick.js \
browser_addon_bar_close_button.js \
browser_addon_bar_shortcut.js \
browser_addon_bar_aomlistener.js \
test_bug628179.html \
browser_wyciwyg_urlbarCopying.js \
test_wyciwyg_copying.html \

View File

@ -1,63 +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/. */
function test() {
waitForExplicitFinish();
let addonbar = document.getElementById("addon-bar");
ok(addonbar.collapsed, "addon bar is collapsed by default");
let topMenu, toolbarMenu;
function onTopMenuShown(event) {
ok(1, "top menu popupshown listener called");
event.currentTarget.removeEventListener("popupshown", arguments.callee, false);
// open the customize or toolbars menu
toolbarMenu = document.getElementById("appmenu_customizeMenu") ||
document.getElementById("viewToolbarsMenu").firstElementChild;
toolbarMenu.addEventListener("popupshown", onToolbarMenuShown, false);
toolbarMenu.addEventListener("popuphidden", onToolbarMenuHidden, false);
toolbarMenu.openPopup();
}
function onTopMenuHidden(event) {
ok(1, "top menu popuphidden listener called");
event.currentTarget.removeEventListener("popuphidden", arguments.callee, false);
finish();
}
function onToolbarMenuShown(event) {
ok(1, "sub menu popupshown listener called");
event.currentTarget.removeEventListener("popupshown", arguments.callee, false);
// test the menu item's default state
let menuitem = document.getElementById("toggle_addon-bar");
ok(menuitem, "found the menu item");
is(menuitem.getAttribute("checked"), "false", "menuitem is not checked by default");
// click on the menu item
// TODO: there's got to be a way to check+command in one shot
menuitem.setAttribute("checked", "true");
menuitem.click();
// now the addon bar should be visible and the menu checked
is(addonbar.getAttribute("collapsed"), "false", "addon bar is visible after executing the command");
is(menuitem.getAttribute("checked"), "true", "menuitem is checked after executing the command");
toolbarMenu.hidePopup();
}
function onToolbarMenuHidden(event) {
ok(1, "toolbar menu popuphidden listener called");
event.currentTarget.removeEventListener("popuphidden", arguments.callee, false);
topMenu.hidePopup();
}
// open the appmenu or view menu
topMenu = document.getElementById("appmenu-popup") ||
document.getElementById("menu_viewPopup");
topMenu.addEventListener("popupshown", onTopMenuShown, false);
topMenu.addEventListener("popuphidden", onTopMenuHidden, false);
topMenu.openPopup();
}

View File

@ -1,67 +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/. */
function test() {
let addonbar = document.getElementById("addon-bar");
ok(addonbar.collapsed, "addon bar is collapsed by default");
function addItem(id) {
let button = document.createElement("toolbarbutton");
button.id = id;
let palette = document.getElementById("navigator-toolbox").palette;
palette.appendChild(button);
addonbar.insertItem(id, null, null, false);
}
// call onInstalling
AddonsMgrListener.onInstalling();
// add item to the bar
let id = "testbutton";
addItem(id);
// call onInstalled
AddonsMgrListener.onInstalled();
// confirm bar is visible
ok(!addonbar.collapsed, "addon bar is not collapsed after toggle");
// call onUninstalling
AddonsMgrListener.onUninstalling();
// remove item from the bar
addonbar.currentSet = addonbar.currentSet.replace("," + id, "");
// call onUninstalled
AddonsMgrListener.onUninstalled();
// confirm bar is not visible
ok(addonbar.collapsed, "addon bar is collapsed after toggle");
// call onEnabling
AddonsMgrListener.onEnabling();
// add item to the bar
let id = "testbutton";
addItem(id);
// call onEnabled
AddonsMgrListener.onEnabled();
// confirm bar is visible
ok(!addonbar.collapsed, "addon bar is not collapsed after toggle");
// call onDisabling
AddonsMgrListener.onDisabling();
// remove item from the bar
addonbar.currentSet = addonbar.currentSet.replace("," + id, "");
// call onDisabled
AddonsMgrListener.onDisabled();
// confirm bar is not visible
ok(addonbar.collapsed, "addon bar is collapsed after toggle");
}

View File

@ -1,19 +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/. */
function test() {
let addonbar = document.getElementById("addon-bar");
ok(addonbar.collapsed, "addon bar is collapsed by default");
// make add-on bar visible
setToolbarVisibility(addonbar, true);
ok(!addonbar.collapsed, "addon bar is not collapsed after toggle");
// click the close button
let closeButton = document.getElementById("addonbar-closebutton");
EventUtils.synthesizeMouseAtCenter(closeButton, {});
// confirm addon bar is closed
ok(addonbar.collapsed, "addon bar is collapsed after clicking close button");
}

View File

@ -1,18 +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/. */
function test() {
let addonbar = document.getElementById("addon-bar");
ok(addonbar.collapsed, "addon bar is collapsed by default");
// show the add-on bar
EventUtils.synthesizeKey("/", { accelKey: true }, window);
ok(!addonbar.collapsed, "addon bar is not collapsed after toggle");
// hide the add-on bar
EventUtils.synthesizeKey("/", { accelKey: true }, window);
// confirm addon bar is closed
ok(addonbar.collapsed, "addon bar is collapsed after toggle");
}

View File

@ -34,16 +34,9 @@ function step3()
is(gBrowser.selectedTab, tab1, "2nd click on selected tab1 keeps tab selected");
isnot(document.activeElement, tab1, "2nd click on selected tab1 does not activate tab");
if (gNavToolbox.getAttribute("tabsontop") == "true") {
ok(true, "[tabsontop=true] focusing URLBar then sending 1 Shift+Tab.");
gURLBar.focus();
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
} else {
ok(true, "[tabsontop=false] focusing SearchBar then sending Tab(s) until out of nav-bar.");
document.getElementById("searchbar").focus();
while (focus_in_navbar())
EventUtils.synthesizeKey("VK_TAB", { });
}
ok(true, "focusing URLBar then sending 1 Shift+Tab.");
gURLBar.focus();
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
is(gBrowser.selectedTab, tab1, "tab key to selected tab1 keeps tab selected");
is(document.activeElement, tab1, "tab key to selected tab1 activates tab");

View File

@ -1,33 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Test:
// * if add-on is installed to the add-on bar, the bar is made visible.
// * if add-on is uninstalled from the add-on bar, and no more add-ons there,
// the bar is hidden.
function test() {
let aml = AddonsMgrListener;
ok(aml, "AddonsMgrListener exists");
// check is hidden
is(aml.addonBar.collapsed, true, "add-on bar is hidden initially");
// aob gets the count
AddonsMgrListener.onInstalling();
// add an item
let element = document.createElement("toolbaritem");
element.id = "bug598923-addon-item";
aml.addonBar.appendChild(element);
// aob checks the count, makes visible
AddonsMgrListener.onInstalled();
// check is visible
is(aml.addonBar.collapsed, false, "add-on bar has been made visible");
// aob gets the count
AddonsMgrListener.onUninstalling();
// remove an item
aml.addonBar.removeChild(element);
// aob checks the count, makes hidden
AddonsMgrListener.onUninstalled();
// check is hidden
is(aml.addonBar.collapsed, true, "add-on bar is hidden again");
}

View File

@ -1,21 +0,0 @@
function test() {
waitForExplicitFinish();
let addonBar = document.getElementById("addon-bar");
ok(addonBar, "got addon bar");
ok(!isElementVisible(addonBar), "addon bar initially hidden");
openToolbarCustomizationUI(function () {
ok(isElementVisible(addonBar),
"add-on bar is visible during toolbar customization");
closeToolbarCustomizationUI(onClose);
});
function onClose() {
ok(!isElementVisible(addonBar),
"addon bar is hidden after toolbar customization");
finish();
}
}

View File

@ -1,4 +0,0 @@
function test() {
is(document.querySelectorAll("#appmenu-popup [accesskey]").length, 0,
"there should be no items with access keys in the app menu popup");
}

View File

@ -11,10 +11,10 @@ function test() {
tab.linkedBrowser.addEventListener("load", (function(event) {
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
is(BookmarkingUI.star.getAttribute("tooltiptext"),
is(BookmarkingUI.button.getAttribute("tooltiptext"),
BookmarkingUI._unstarredTooltip,
"Star icon should have the unstarred tooltip text");
gBrowser.removeCurrentTab();
finish();
}), true);

View File

@ -1,24 +0,0 @@
function test() {
waitForExplicitFinish();
openToolbarCustomizationUI(customizationWindowLoaded);
}
function customizationWindowLoaded(win) {
let x = win.screenX;
let iconModeList = win.document.getElementById("modelist");
iconModeList.addEventListener("popupshown", function popupshown() {
iconModeList.removeEventListener("popupshown", popupshown, false);
executeSoon(function () {
is(win.screenX, x,
"toolbar customization window shouldn't move when the iconmode menulist is opened");
iconModeList.open = false;
closeToolbarCustomizationUI(finish);
});
}, false);
iconModeList.open = true;
}

View File

@ -1,216 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Tests that the disablechrome attribute gets propogated to the main UI
const HTTPSRC = "http://example.com/browser/browser/base/content/test/";
function is_element_hidden(aElement) {
var style = window.getComputedStyle(document.getElementById("nav-bar"), "");
if (style.visibility != "visible" || style.display == "none")
return true;
if (aElement.ownerDocument != aElement.parentNode)
return is_element_hidden(aElement.parentNode);
return false;
}
function is_chrome_hidden() {
is(document.documentElement.getAttribute("disablechrome"), "true", "Attribute should be set");
if (TabsOnTop.enabled)
ok(is_element_hidden(document.getElementById("nav-bar")), "Toolbar should be hidden");
else
ok(!is_element_hidden(document.getElementById("nav-bar")), "Toolbar should not be hidden");
}
function is_chrome_visible() {
isnot(document.getElementById("main-window").getAttribute("disablechrome"), "true", "Attribute should not be set");
ok(!is_element_hidden(document.getElementById("nav-bar")), "Toolbar should not be hidden");
}
function load_page(aURL, aCanHide, aCallback) {
gNewBrowser.addEventListener("pageshow", function() {
// Filter out about:blank loads
if (gNewBrowser.currentURI.spec != aURL)
return;
gNewBrowser.removeEventListener("pageshow", arguments.callee, false);
if (aCanHide)
is_chrome_hidden();
else
is_chrome_visible();
if (aURL == "about:addons") {
function check_after_init() {
if (aCanHide)
is_chrome_hidden();
else
is_chrome_visible();
aCallback();
}
if (gNewBrowser.contentWindow.gIsInitializing) {
gNewBrowser.contentDocument.addEventListener("Initialized", function() {
gNewBrowser.contentDocument.removeEventListener("Initialized", arguments.callee, false);
check_after_init();
}, false);
}
else {
check_after_init();
}
}
else {
executeSoon(aCallback);
}
}, false);
gNewBrowser.loadURI(aURL);
}
var gOldTab;
var gNewTab;
var gNewBrowser;
function test() {
// Opening the add-ons manager and waiting for it to load the discovery pane
// takes more time in windows debug builds
requestLongerTimeout(2);
var gOldTabsOnTop = TabsOnTop.enabled;
registerCleanupFunction(function() {
TabsOnTop.enabled = gOldTabsOnTop;
});
waitForExplicitFinish();
gOldTab = gBrowser.selectedTab;
gNewTab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
gNewBrowser = gBrowser.selectedBrowser;
info("Tabs on top");
TabsOnTop.enabled = true;
run_http_test_1();
}
function end_test() {
gBrowser.removeTab(gNewTab);
finish();
}
function test_url(aURL, aCanHide, aNextTest) {
is_chrome_visible();
info("Page load");
load_page(aURL, aCanHide, function() {
info("Switch away");
gBrowser.selectedTab = gOldTab;
is_chrome_visible();
info("Switch back");
gBrowser.selectedTab = gNewTab;
if (aCanHide)
is_chrome_hidden();
else
is_chrome_visible();
gBrowser.removeTab(gNewTab);
gNewTab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
gNewBrowser = gBrowser.selectedBrowser;
gBrowser.selectedTab = gOldTab;
info("Background load");
load_page(aURL, false, function() {
info("Switch back");
gBrowser.selectedTab = gNewTab;
if (aCanHide)
is_chrome_hidden();
else
is_chrome_visible();
load_page("about:blank", false, aNextTest);
});
});
}
// Should never hide the chrome
function run_http_test_1() {
info("HTTP tests");
test_url(HTTPSRC + "disablechrome.html", false, run_chrome_about_test);
}
// Should hide the chrome
function run_chrome_about_test() {
info("Chrome about: tests");
test_url("about:addons", true, function() {
info("Tabs on bottom");
TabsOnTop.enabled = false;
run_http_test_2();
});
}
// Should never hide the chrome
function run_http_test_2() {
info("HTTP tests");
test_url(HTTPSRC + "disablechrome.html", false, run_chrome_about_test_2);
}
// Should not hide the chrome
function run_chrome_about_test_2() {
info("Chrome about: tests");
test_url("about:addons", true, run_http_test3);
}
function run_http_test3() {
info("HTTP tests");
test_url(HTTPSRC + "disablechrome.html", false, run_chrome_about_test_3);
}
// Should not hide the chrome
function run_chrome_about_test_3() {
info("Chrome about: tests");
test_url("about:Addons", true, function(){
info("Tabs on top");
TabsOnTop.enabled = true;
run_http_test4();
});
}
function run_http_test4() {
info("HTTP tests");
test_url(HTTPSRC + "disablechrome.html", false, run_chrome_about_test_4);
}
function run_chrome_about_test_4() {
info("Chrome about: tests");
test_url("about:Addons", true, run_http_test5);
}
function run_http_test5() {
info("HTTP tests");
test_url(HTTPSRC + "disablechrome.html", false, run_chrome_about_test_5);
}
// Should hide the chrome
function run_chrome_about_test_5() {
info("Chrome about: tests");
test_url("about:preferences", true, function(){
info("Tabs on bottom");
TabsOnTop.enabled = false;
run_http_test6();
});
}
function run_http_test6() {
info("HTTP tests");
test_url(HTTPSRC + "disablechrome.html", false, run_chrome_about_test_6);
}
function run_chrome_about_test_6() {
info("Chrome about: tests");
test_url("about:preferences", true, end_test);
}

View File

@ -1,4 +0,0 @@
<html>
<body>
</body>
</html>

View File

@ -37,49 +37,27 @@ function updateTabContextMenu(tab) {
menu.hidePopup();
}
function findToolbarCustomizationWindow(aBrowserWin) {
if (!aBrowserWin)
aBrowserWin = window;
let iframe = aBrowserWin.document.getElementById("customizeToolbarSheetIFrame");
let win = iframe && iframe.contentWindow;
if (win)
return win;
win = findChromeWindowByURI("chrome://global/content/customizeToolbar.xul");
if (win && win.opener == aBrowserWin)
return win;
throw Error("Failed to find the customization window");
}
function openToolbarCustomizationUI(aCallback, aBrowserWin) {
if (!aBrowserWin)
aBrowserWin = window;
aBrowserWin.document.getElementById("cmd_CustomizeToolbars").doCommand();
aBrowserWin.gCustomizeMode.enter();
aBrowserWin.gNavToolbox.addEventListener("beforecustomization", function UI_loaded() {
aBrowserWin.gNavToolbox.removeEventListener("beforecustomization", UI_loaded);
let win = findToolbarCustomizationWindow(aBrowserWin);
waitForFocus(function () {
aCallback(win);
}, win);
aBrowserWin.gNavToolbox.addEventListener("customizationready", function UI_loaded() {
aBrowserWin.gNavToolbox.removeEventListener("customizationready", UI_loaded);
executeSoon(function() {
aCallback(aBrowserWin)
});
});
}
function closeToolbarCustomizationUI(aCallback, aBrowserWin) {
let win = findToolbarCustomizationWindow(aBrowserWin);
win.addEventListener("unload", function unloaded() {
win.removeEventListener("unload", unloaded);
aBrowserWin.gNavToolbox.addEventListener("aftercustomization", function unloaded() {
aBrowserWin.gNavToolbox.removeEventListener("aftercustomization", unloaded);
executeSoon(aCallback);
});
let button = win.document.getElementById("donebutton");
button.focus();
button.doCommand();
aBrowserWin.gCustomizeMode.exit();
}
function waitForCondition(condition, nextTest, errorMsg) {

View File

@ -937,7 +937,7 @@
<xul:menupopup anonid="menupopup"
xbl:inherits="oncommand=menucommand">
<children/>
<xul:menuitem class="menuitem-iconic popup-notification-closeitem"
<xul:menuitem class="menuitem-iconic popup-notification-closeitem close-icon"
label="&closeNotificationItem.label;"
xbl:inherits="oncommand=closeitemcommand"/>
</xul:menupopup>
@ -946,7 +946,7 @@
</xul:vbox>
<xul:vbox pack="start">
<xul:toolbarbutton anonid="closebutton"
class="messageCloseButton popup-notification-closebutton tabbable"
class="messageCloseButton close-icon popup-notification-closebutton tabbable"
xbl:inherits="oncommand=closebuttoncommand"
tooltiptext="&closeNotification.tooltip;"/>
</xul:vbox>
@ -1169,7 +1169,7 @@
<xul:menupopup anonid="menupopup"
xbl:inherits="oncommand=menucommand">
<children/>
<xul:menuitem class="menuitem-iconic popup-notification-closeitem"
<xul:menuitem class="menuitem-iconic popup-notification-closeitem close-icon"
label="&closeNotificationItem.label;"
xbl:inherits="oncommand=closeitemcommand"/>
</xul:menupopup>
@ -1178,7 +1178,7 @@
</xul:vbox>
<xul:vbox pack="start">
<xul:toolbarbutton anonid="closebutton"
class="messageCloseButton popup-notification-closebutton tabbable"
class="messageCloseButton close-icon popup-notification-closebutton tabbable"
xbl:inherits="oncommand=closebuttoncommand"
tooltiptext="&closeNotification.tooltip;"/>
</xul:vbox>
@ -1508,7 +1508,7 @@
<xul:label class="text-link click-to-play-plugins-notification-link" anonid="click-to-play-plugins-notification-link" />
</xul:description>
<xul:toolbarbutton anonid="closebutton"
class="messageCloseButton popup-notification-closebutton tabbable"
class="messageCloseButton popup-notification-closebutton tabbable close-icon"
xbl:inherits="oncommand=closebuttoncommand"
tooltiptext="&closeNotification.tooltip;"/>
</xul:hbox>
@ -2008,7 +2008,7 @@
onclick="document.getBindingParent(this).onLinkClick();"/>
</xul:description>
</xul:hbox>
<xul:toolbarbutton class="panel-promo-closebutton"
<xul:toolbarbutton class="panel-promo-closebutton close-icon"
oncommand="document.getBindingParent(this).onCloseButtonCommand();"
tooltiptext="&closeNotification.tooltip;"/>
</xul:hbox>

View File

@ -13,8 +13,7 @@ browser.jar:
#endif
% overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul
% overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul
% style chrome://global/content/customizeToolbar.xul chrome://browser/content/browser.css
% style chrome://global/content/customizeToolbar.xul chrome://browser/skin/
* content/browser/aboutDialog.xul (content/aboutDialog.xul)
* content/browser/aboutDialog.js (content/aboutDialog.js)
content/browser/aboutDialog.css (content/aboutDialog.css)

View File

@ -8,7 +8,7 @@
# BrandFullNameInternal is used for some registry and file system values
# instead of BrandFullName and typically should not be modified.
!define BrandFullNameInternal "Nightly"
!define BrandFullNameInternal "UX"
!define CompanyName "mozilla.org"
!define URLInfoAbout "http://www.mozilla.org"
!define URLUpdateInfo "http://www.mozilla.org/projects/firefox"

View File

@ -2,4 +2,4 @@
# 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/.
MOZ_APP_DISPLAYNAME=Nightly
MOZ_APP_DISPLAYNAME=UX

View File

@ -2,7 +2,7 @@
- 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/. -->
<!ENTITY brandShortName "Nightly">
<!ENTITY brandFullName "Nightly">
<!ENTITY brandShortName "UX">
<!ENTITY brandFullName "UX">
<!ENTITY vendorShortName "Mozilla">
<!ENTITY trademarkInfo.part1 " ">

View File

@ -2,8 +2,8 @@
# 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/.
brandShortName=Nightly
brandFullName=Nightly
brandShortName=UX
brandFullName=UX
vendorShortName=Mozilla
syncBrandShortName=Sync

View File

@ -86,6 +86,8 @@ static RedirEntry kRedirMap[] = {
{ "healthreport", "chrome://browser/content/abouthealthreport/abouthealth.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
#endif
{ "customizing", "chrome://browser/content/customizableui/aboutCustomizing.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
};
static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap);

View File

@ -108,6 +108,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
#ifdef MOZ_SERVICES_HEALTHREPORT
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "healthreport", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "customizing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#if defined(XP_WIN)
{ NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID },
#elif defined(XP_MACOSX)

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
%browserDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml"
disablefastfind="true">
<head>
<title>&customizeMode.tabTitle;</title>
</head>
<body></body>
</html>

View File

@ -0,0 +1,29 @@
<!-- 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/. -->
<hbox id="customization-container" flex="1" hidden="true">
<vbox flex="1" id="customization-palette-container">
<label id="customization-header" value="&customizeMode.menuAndToolbars.header;"/>
<vbox id="customization-palette" flex="1"/>
<hbox pack="start">
<button id="customization-reset-button" oncommand="gCustomizeMode.reset();" label="&customizeMode.restoreDefaults;" class="customizationmode-button"/>
</hbox>
</vbox>
<vbox id="customization-panel-container">
<vbox id="customization-panelWrapper">
<html:style html:type="text/html" scoped="scoped">
@import url(chrome://global/skin/popup.css);
</html:style>
<box class="panel-arrowbox">
<box flex="1"/>
<image class="panel-arrow" side="top"/>
</box>
<box class="panel-arrowcontent" flex="1">
<hbox id="customization-panelHolder"/>
<box class="panel-inner-arrowcontentfooter" hidden="true"/>
</box>
</vbox>
<spacer flex="1"/>
</vbox>
</hbox>

View File

@ -0,0 +1,11 @@
# 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/.
browser.jar:
content/browser/customizableui/aboutCustomizing.xhtml
content/browser/customizableui/panelUI.css
content/browser/customizableui/panelUI.js
content/browser/customizableui/panelUI.xml
content/browser/customizableui/toolbar.xml

View File

@ -0,0 +1,6 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.

View File

@ -0,0 +1,31 @@
/* 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/. */
.panel-viewstack[viewtype="main"] > .panel-clickcapturer {
pointer-events: none;
}
.panel-mainview,
.panel-viewcontainer,
.panel-viewstack {
overflow: hidden;
}
.panel-viewstack {
position: relative;
}
.panel-subviews {
-moz-stack-sizing: ignore;
transform: translateX(0);
overflow-y: hidden;
}
.panel-subviews[panelopen] {
transition: transform 150ms;
}
.panel-viewcontainer[panelopen]:-moz-any(:not([viewtype="main"]),[transitioning="true"]) {
transition: height 150ms;
}

View File

@ -0,0 +1,81 @@
<!-- 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/. -->
<panel id="PanelUI-popup"
role="group"
type="arrow"
level="top"
hidden="true"
consumeoutsideclicks="true"
noautofocus="true">
<panelmultiview id="PanelUI-multiView" mainViewId="PanelUI-mainView">
<panelview id="PanelUI-mainView" contextmenu="customizationPanelContextMenu">
<vbox id="PanelUI-contents" type="grid"/>
<vbox id="PanelUI-mainView-spring" flex="1"/>
<footer class="PanelUI-footer" align="center">
<!-- The parentNode is used so that the footer is presented as the anchor
instead of just the button being the anchor. -->
<toolbarbutton id="PanelUI-help-btn" label="&helpMenu.label;"
onclick="PanelUI.showHelpView(this.parentNode);"/>
<spacer flex="1"/>
<toolbarbutton id="PanelUI-customize-btn" label="&appMenuCustomize.label;"
command="cmd_CustomizeToolbars"/>
</footer>
</panelview>
<panelview id="PanelUI-history" flex="1">
<label value="&appMenuHistory.label;"/>
<toolbarbutton id="appMenuClearRecentHistory"
label="&appMenuHistory.clearRecent.label;"
command="Tools:Sanitize"/>
<toolbarbutton id="appMenuRestoreLastSession"
label="&appMenuHistory.restoreSession.label;"
command="Browser:RestoreLastSession"/>
<vbox id="PanelUI-historyItems"/>
<label value="&appMenuHistory.showAll.label;"
id="PanelUI-historyMore"
class="text-link"
onclick="PlacesCommandHook.showPlacesOrganizer('History'); CustomizableUI.hidePanelForNode(this);"/>
</panelview>
<panelview id="PanelUI-feeds" flex="1" oncommand="FeedHandler.subscribeToFeed(null, event);"></panelview>
<panelview id="PanelUI-help" flex="1">
<label value="&helpMenu.label;"/>
<vbox id="PanelUI-helpItems"/>
</panelview>
</panelmultiview>
<popupset id="customizationContextMenus">
<menupopup id="customizationContextMenu">
<menuitem oncommand="gCustomizeMode.addToToolbar(document.popupNode)"
accesskey="&customizeMenu.addToToolbar.accesskey;"
label="&customizeMenu.addToToolbar.label;"/>
<menuitem oncommand="gCustomizeMode.removeFromPanel(document.popupNode)"
accesskey="&customizeMenu.removeFromMenu.accesskey;"
label="&customizeMenu.removeFromMenu.label;"/>
<menuseparator/>
<menuitem command="cmd_CustomizeToolbars"
accesskey="&viewCustomizeToolbar.accesskey;"
label="&viewCustomizeToolbar.label;"/>
</menupopup>
<menupopup id="customizationPanelContextMenu">
<menuitem command="cmd_CustomizeToolbars"
accesskey="&customizeMenu.addMoreItems.accesskey;"
label="&customizeMenu.addMoreItems.label;"/>
</menupopup>
</popupset>
</panel>
<panel id="widget-overflow"
role="group"
type="arrow"
level="top"
hidden="true"
consumeoutsideclicks="true">
<vbox id="widget-overflow-list">
</vbox>
</panel>

View File

@ -0,0 +1,280 @@
/* 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/. */
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
"resource:///modules/CustomizableUI.jsm");
/**
* Maintains the state and dispatches events for the main menu panel.
*/
const PanelUI = {
/** Panel events that we listen for. **/
get kEvents() ["popupshowing", "popupshown", "popuphiding", "popuphidden"],
/**
* Used for lazily getting and memoizing elements from the document. Lazy
* getters are set in init, and memoizing happens after the first retrieval.
*/
get kElements() {
return {
contents: "PanelUI-contents",
mainView: "PanelUI-mainView",
multiView: "PanelUI-multiView",
helpView: "PanelUI-help",
menuButton: "PanelUI-menu-button",
panel: "PanelUI-popup"
};
},
init: function() {
for (let [k, v] of Iterator(this.kElements)) {
// Need to do fresh let-bindings per iteration
let getKey = k;
let id = v;
this.__defineGetter__(getKey, function() {
delete this[getKey];
return this[getKey] = document.getElementById(id);
});
}
for (let event of this.kEvents) {
this.panel.addEventListener(event, this);
}
this.helpView.addEventListener("ViewShowing", this._onHelpViewShow, false);
this.helpView.addEventListener("ViewHiding", this._onHelpViewHide, false);
},
uninit: function() {
for (let event of this.kEvents) {
this.panel.removeEventListener(event, this);
}
this.helpView.removeEventListener("ViewShowing", this._onHelpViewShow);
this.helpView.removeEventListener("ViewHiding", this._onHelpViewHide);
},
/**
* Customize mode extracts the mainView and puts it somewhere else while the
* user customizes. Upon completion, this function can be called to put the
* panel back to where it belongs in normal browsing mode.
*
* @param aMainView
* The mainView node to put back into place.
*/
setMainView: function(aMainView) {
this.multiView.setMainView(aMainView);
},
/**
* Opens the menu panel if it's closed, or closes it if it's
* open. If the event target has a child with the toolbarbutton-icon
* attribute, the panel will be anchored on that child. Otherwise, the panel
* is anchored on the event target itself.
*
* @param aEvent the event that triggers the toggle.
*/
toggle: function(aEvent) {
if (this.panel.state == "open") {
this.hide();
} else if (this.panel.state == "closed") {
this.ensureRegistered();
this.panel.hidden = false;
let anchor = aEvent.target;
let iconAnchor =
document.getAnonymousElementByAttribute(anchor, "class",
"toolbarbutton-icon");
this.panel.openPopup(iconAnchor || anchor, "bottomcenter topright");
}
},
/**
* If the menu panel is being shown, hide it.
*/
hide: function() {
this.panel.hidePopup();
},
handleEvent: function(aEvent) {
switch (aEvent.type) {
case "popupshowing":
// Fall through
case "popupshown":
// Fall through
case "popuphiding":
// Fall through
case "popuphidden": {
this._updatePanelButton(aEvent.target);
break;
}
}
},
/**
* Registering the menu panel is done lazily for performance reasons. This
* method is exposed so that CustomizationMode can force registration in the
* event that customization mode is started before the panel has had a chance
* to register itself.
*
* @param aCustomizing (optional) set to true if this was called while entering
* customization mode. If that's the case, we trust that customization
* mode will handle calling beginBatchUpdate and endBatchUpdate.
*/
ensureRegistered: function(aCustomizing=false) {
if (aCustomizing) {
CustomizableUI.registerMenuPanel(this.contents);
} else {
this.beginBatchUpdate();
CustomizableUI.registerMenuPanel(this.contents);
this.endBatchUpdate();
}
},
/**
* Switch the panel to the main view if it's not already
* in that view.
*/
showMainView: function() {
this.multiView.showMainView();
},
/**
* Switch the panel to the help view if it's not already
* in that view.
*/
showHelpView: function(aAnchor) {
this.multiView.showSubView("PanelUI-help", aAnchor);
},
/**
* Shows a subview in the panel with a given ID.
*
* @param aViewId the ID of the subview to show.
* @param aAnchor the element that spawned the subview.
* @param aPlacementArea the CustomizableUI area that aAnchor is in.
*/
showSubView: function(aViewId, aAnchor, aPlacementArea) {
let viewNode = document.getElementById(aViewId);
if (!viewNode) {
Cu.reportError("Could not show panel subview with id: " + aViewId);
return;
}
if (!aAnchor) {
Cu.reportError("Expected an anchor when opening subview with id: " + aViewId);
return;
}
if (aPlacementArea == CustomizableUI.AREA_PANEL) {
this.multiView.showSubView(aViewId, aAnchor);
} else {
// Emit the ViewShowing event so that the widget definition has a chance
// to lazily populate the subview with things.
let evt = document.createEvent("CustomEvent");
evt.initCustomEvent("ViewShowing", true, true, viewNode);
viewNode.dispatchEvent(evt);
if (evt.defaultPrevented) {
return;
}
let tempPanel = document.createElement("panel");
tempPanel.setAttribute("type", "arrow");
tempPanel.setAttribute("id", "customizationui-widget-panel");
document.getElementById(CustomizableUI.AREA_NAVBAR).appendChild(tempPanel);
let multiView = document.createElement("panelmultiview");
tempPanel.appendChild(multiView);
multiView.setMainView(viewNode);
tempPanel.addEventListener("command", PanelUI._onWidgetPanelCommand);
tempPanel.addEventListener("popuphidden", function panelRemover() {
tempPanel.removeEventListener("popuphidden", panelRemover);
tempPanel.removeEventListener("command", PanelUI._onWidgetPanelCommand);
this.multiView.appendChild(viewNode);
tempPanel.parentElement.removeChild(tempPanel);
}.bind(this));
let iconAnchor =
document.getAnonymousElementByAttribute(aAnchor, "class",
"toolbarbutton-icon");
tempPanel.openPopup(iconAnchor || aAnchor, "bottomcenter topright");
}
},
/**
* Signal that we're about to make a lot of changes to the contents of the
* panels all at once. For performance, we ignore the mutations.
*/
beginBatchUpdate: function() {
this.multiView.ignoreMutations = true;
},
/**
* Signal that we're done making bulk changes to the panel. We now pay
* attention to mutations. This automatically synchronizes the multiview
* container with whichever view is displayed if the panel is open.
*/
endBatchUpdate: function(aReason) {
this.multiView.ignoreMutations = false;
},
/**
* Sets the anchor node into the open or closed state, depending
* on the state of the panel.
*/
_updatePanelButton: function() {
this.menuButton.open = this.panel.state == "open" ||
this.panel.state == "showing";
},
_onWidgetPanelCommand: function(aEvent) {
if (!aEvent.originalTarget.hasAttribute("noautoclose")) {
aEvent.currentTarget.hidePopup();
}
},
_onHelpViewCommand: function(aEvent) {
if (!aEvent.originalTarget.hasAttribute("noautoclose")) {
PanelUI.hide();
}
},
_onHelpViewShow: function(aEvent) {
// Call global menu setup function
buildHelpMenu();
let helpMenu = document.getElementById("menu_HelpPopup");
let items = this.getElementsByTagName("vbox")[0];
let attrs = ["oncommand", "onclick", "label", "key", "disabled"];
let NSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
// Remove all buttons from the view
while (items.firstChild) {
items.removeChild(items.firstChild);
}
// Add the current set of menuitems of the Help menu to this view
let menuItems = Array.prototype.slice.call(helpMenu.getElementsByTagName("menuitem"));
let fragment = document.createDocumentFragment();
for (let node of menuItems) {
if (node.hidden)
continue;
let button = document.createElementNS(NSXUL, "toolbarbutton");
// Copy specific attributes from a menuitem of the Help menu
for (let attrName of attrs) {
if (!node.hasAttribute(attrName))
continue;
button.setAttribute(attrName, node.getAttribute(attrName));
}
fragment.appendChild(button);
}
items.appendChild(fragment);
this.addEventListener("command", PanelUI._onHelpViewCommand);
},
_onHelpViewHide: function(aEvent) {
this.removeEventListener("command", PanelUI._onHelpViewCommand);
}
};

View File

@ -0,0 +1,349 @@
<?xml version="1.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/. -->
<bindings id="browserPanelUIBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="toolbarbutton" display="xul:button"
extends="chrome://global/content/bindings/button.xml#button-base">
<resources>
<stylesheet src="chrome://global/skin/toolbarbutton.css"/>
</resources>
<content>
<children includes="observes|template|menupopup|panel|tooltip"/>
<xul:hbox align="center" flex="1">
<xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label"/>
<xul:vbox flex="1">
<xul:label class="toolbarbutton-text" crop="right" flex="1"
xbl:inherits="value=label,accesskey,crop"/>
<xul:hbox pack="end">
<xul:label class="toolbarbutton-acceltext" crop="middle"
xbl:inherits="value=acceltext"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
<implementation implements="nsIAccessibleProvider">
<property name="accessibleType" readonly="true">
<getter>
return Components.interfaces.nsIAccessibleProvider.XULToolbarButton;
</getter>
</property>
</implementation>
</binding>
<binding id="panelmultiview">
<resources>
<stylesheet src="chrome://browser/content/customizableui/panelUI.css"/>
</resources>
<content>
<xul:box anonid="viewContainer" class="panel-viewcontainer" xbl:inherits="panelopen,viewtype,transitioning">
<xul:stack anonid="viewStack" xbl:inherits="viewtype" viewtype="main" class="panel-viewstack">
<xul:vbox anonid="mainViewContainer" class="panel-mainview"/>
<!-- Used to capture click events over the PanelUI-mainView if we're in
subview mode. That way, any click on the PanelUI-mainView causes us
to revert to the mainView mode, whereupon PanelUI-click-capture then
allows click events to go through it. -->
<xul:vbox anonid="clickCapturer" class="panel-clickcapturer"/>
<!-- We manually set display: none (via a CSS attribute selector) on the
subviews that are not being displayed. We're using this over a deck
because a deck assumes the size of its largest child, regardless of
whether or not it is shown. That's not good for our case, since we
want to allow each subview to be uniquely sized. -->
<xul:vbox anonid="subViews" class="panel-subviews" xbl:inherits="panelopen">
<children includes="panelview"/>
</xul:vbox>
</xul:stack>
</xul:box>
</content>
<implementation implements="nsIDOMEventListener">
<field name="_clickCapturer" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "clickCapturer");
</field>
<field name="_viewContainer" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "viewContainer");
</field>
<field name="_mainViewContainer" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "mainViewContainer");
</field>
<field name="_subViews" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "subViews");
</field>
<field name="_viewStack" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "viewStack");
</field>
<field name="_panel" readonly="true">
this.parentNode;
</field>
<field name="_currentSubView">null</field>
<field name="_anchorElement">null</field>
<field name="_mainViewHeight">0</field>
<field name="_subViewObserver">null</field>
<field name="__transitioning">false</field>
<field name="_ignoreMutations">false</field>
<property name="showingSubView" readonly="true"
onget="return this._viewStack.getAttribute('viewtype') == 'subview'"/>
<property name="_mainViewId" onget="return this.getAttribute('mainViewId');" onset="this.setAttribute('mainViewId', val); return val;"/>
<property name="_mainView" readonly="true"
onget="return document.getElementById(this._mainViewId);"/>
<property name="ignoreMutations">
<getter>
return this._ignoreMutations;
</getter>
<setter><![CDATA[
this._ignoreMutations = val;
if (!val && this._panel.state == "open") {
if (this.showingSubView) {
this._syncContainerWithSubView();
} else {
this._syncContainerWithMainView();
}
}
]]></setter>
</property>
<property name="_transitioning">
<getter>
return this.__transitioning;
</getter>
<setter><![CDATA[
this.__transitioning = val;
if (val) {
this.setAttribute("transitioning", "true");
} else {
this.removeAttribute("transitioning");
}
]]></setter>
</property>
<constructor><![CDATA[
this._clickCapturer.addEventListener("click", this);
this._panel.addEventListener("popupshowing", this);
this._panel.addEventListener("popuphidden", this);
this._subViews.addEventListener("overflow", this);
this._mainViewContainer.addEventListener("overflow", this);
// Get a MutationObserver ready to react to subview size changes. We
// only attach this MutationObserver when a subview is being displayed.
this._subViewObserver =
new MutationObserver(this._syncContainerWithSubView.bind(this));
this._mainViewObserver =
new MutationObserver(this._syncContainerWithMainView.bind(this));
this._mainViewContainer.setAttribute("panelid",
this._panel.id);
if (this._mainView) {
this.setMainView(this._mainView);
}
this.setAttribute("viewtype", "main");
]]></constructor>
<destructor><![CDATA[
if (this._mainView) {
this._mainView.removeAttribute("mainview");
}
this._mainViewObserver.disconnect();
this._subViewObserver.disconnect();
this._panel.removeEventListener("popupshowing", this);
this._panel.removeEventListener("popuphidden", this);
this._subViews.removeEventListener("overflow", this);
this._mainViewContainer.removeEventListener("overflow", this);
this._clickCapturer.removeEventListener("click", this);
]]></destructor>
<method name="setMainView">
<parameter name="aNewMainView"/>
<body><![CDATA[
if (this._mainView) {
this._mainViewObserver.disconnect();
this._subViews.appendChild(this._mainView);
this._mainView.removeAttribute("mainview");
}
this._mainViewId = aNewMainView.id;
aNewMainView.setAttribute("mainview", "true");
this._mainViewContainer.appendChild(aNewMainView);
]]></body>
</method>
<method name="showMainView">
<body><![CDATA[
if (this.showingSubView) {
let viewNode = this._currentSubView;
let evt = document.createEvent("CustomEvent");
evt.initCustomEvent("ViewHiding", true, true, viewNode);
viewNode.dispatchEvent(evt);
viewNode.removeAttribute("current");
this._currentSubView = null;
this._subViewObserver.disconnect();
this._transitioning = true;
this._viewContainer.addEventListener("transitionend", function trans() {
this._viewContainer.removeEventListener("transitionend", trans);
this._transitioning = false;
}.bind(this));
this._viewContainer.style.height = this._mainViewHeight + "px";
this.setAttribute("viewtype", "main");
}
this._mainViewObserver.observe(this._mainView, {
attributes: true,
characterData: true,
childList: true,
subtree: true
});
this._shiftMainView();
]]></body>
</method>
<method name="showSubView">
<parameter name="aViewId"/>
<parameter name="aAnchor"/>
<body><![CDATA[
let viewNode = this.querySelector("#" + aViewId);
viewNode.setAttribute("current", true);
// Emit the ViewShowing event so that the widget definition has a chance
// to lazily populate the subview with things.
let evt = document.createEvent("CustomEvent");
evt.initCustomEvent("ViewShowing", true, true, viewNode);
viewNode.dispatchEvent(evt);
if (evt.defaultPrevented) {
return;
}
this._currentSubView = viewNode;
// Now we have to transition to transition the panel. There are a few parts
// to this:
//
// 1) The main view content gets shifted so that the center of the anchor
// node is at the left-most edge of the panel.
// 2) The subview deck slides in so that it takes up almost all of the
// panel.
// 3) If the subview is taller then the main panel contents, then the panel
// must grow to meet that new height. Otherwise, it must shrink.
//
// All three of these actions make use of CSS transformations, so they
// should all occur simultaneously.
this.setAttribute("viewtype", "subview");
this._shiftMainView(aAnchor);
this._mainViewHeight = this._viewStack.clientHeight;
this._transitioning = true;
this._viewContainer.addEventListener("transitionend", function trans() {
this._viewContainer.removeEventListener("transitionend", trans);
this._transitioning = false;
}.bind(this));
this._viewContainer.style.height = this._subViews.scrollHeight + "px";
this._subViewObserver.observe(viewNode, {
attributes: true,
characterData: true,
childList: true,
subtree: true
});
]]></body>
</method>
<method name="_shiftMainView">
<parameter name="aAnchor"/>
<body><![CDATA[
if (aAnchor) {
// We need to find the left edge of the anchor, relative to the main
// panel. Then we need to add half the width of the anchor. This is the
// target that we need to transition to.
let anchorRect = aAnchor.getBoundingClientRect();
let mainViewRect = this._mainViewContainer.getBoundingClientRect();
let leftEdge = anchorRect.left - mainViewRect.left;
let center = aAnchor.clientWidth / 2;
let target = leftEdge + center;
this._mainViewContainer.style.transform = "translateX(-" + target + "px)";
aAnchor.classList.add("panel-multiview-anchor");
} else {
this._mainViewContainer.style.transform = "";
if (this.anchorElement)
this.anchorElement.classList.remove("panel-multiview-anchor");
}
this.anchorElement = aAnchor;
]]></body>
</method>
<method name="handleEvent">
<parameter name="aEvent"/>
<body><![CDATA[
switch(aEvent.type) {
case "click":
if (aEvent.originalTarget == this._clickCapturer) {
this.showMainView();
}
break;
case "overflow":
// Resize the right view on the next tick.
if (this.showingSubView) {
setTimeout(this._syncContainerWithSubView.bind(this), 0);
} else if (!this.transitioning) {
setTimeout(this._syncContainerWithMainView.bind(this), 0);
}
break;
case "popupshowing":
this.setAttribute("panelopen", "true");
this._syncContainerWithMainView();
break;
case "popuphidden":
this.removeAttribute("panelopen");
this.showMainView();
break;
}
]]></body>
</method>
<method name="_syncContainerWithSubView">
<body><![CDATA[
if (!this.ignoreMutations && this.showingSubView) {
this._viewContainer.style.height =
this._subViews.scrollHeight + "px";
}
]]></body>
</method>
<method name="_syncContainerWithMainView">
<body><![CDATA[
if (!this.ignoreMutations && !this.showingSubView && !this._transitioning) {
this._viewContainer.style.height =
this._mainView.scrollHeight + "px";
}
]]></body>
</method>
</implementation>
</binding>
<binding id="panelview">
<implementation>
<property name="panelMultiView" readonly="true">
<getter><![CDATA[
if (this.parentNode.localName != "panelmultiview") {
return document.getBindingParent(this.parentNode);
}
return this.parentNode;
]]></getter>
</property>
</implementation>
</binding>
</bindings>

View File

@ -0,0 +1,447 @@
<?xml version="1.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/. -->
<bindings id="browserToolbarBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="toolbar">
<resources>
<stylesheet src="chrome://global/skin/toolbar.css"/>
</resources>
<implementation implements="nsIAccessibleProvider">
<property name="accessibleType" readonly="true">
<getter>
return Components.interfaces.nsIAccessibleProvider.XULToolbar;
</getter>
</property>
<constructor><![CDATA[
if (document.readyState == "complete") {
this._init();
} else {
// Need to wait until XUL overlays are loaded. See bug 554279.
let self = this;
document.addEventListener("readystatechange", function onReadyStateChange() {
if (document.readyState != "complete")
return;
document.removeEventListener("readystatechange", onReadyStateChange, false);
self._init();
}, false);
}
]]></constructor>
<method name="_init">
<body><![CDATA[
let scope = {};
Cu.import("resource:///modules/CustomizableUI.jsm", scope);
let CustomizableUI = scope.CustomizableUI;
// Searching for the toolbox palette in the toolbar binding because
// toolbars are constructed first.
let toolbox = this.toolbox;
if (toolbox && !toolbox.palette) {
for (let node of toolbox.children) {
if (node.localName == "toolbarpalette") {
// Hold on to the palette but remove it from the document.
toolbox.palette = node;
toolbox.removeChild(node);
}
}
}
CustomizableUI.registerToolbar(this);
]]></body>
</method>
<method name="insertItem">
<parameter name="aId"/>
<parameter name="aBeforeElt"/>
<parameter name="aWrapper"/>
<body><![CDATA[
if (aWrapper) {
Cu.reportError("Can't insert " + aId + ": using insertItem " +
"no longer supports wrapper elements.");
return null;
}
// Hack, the customizable UI code makes this be the last position
let pos = null;
if (aBeforeElt) {
let beforeInfo = CustomizableUI.getPlacementOfWidget(aBeforeElt.id);
if (beforeInfo.area != this.id) {
Cu.reportError("Can't insert " + aId + " before " +
aBeforeElt.id + " which isn't in this area (" +
this.id + ").");
return null;
}
pos = beforeInfo.position;
}
CustomizableUI.addWidgetToArea(aId, this.id, pos);
return this.ownerDocument.getElementById(aId);
]]></body>
</method>
<property name="toolbarName"
onget="return this.getAttribute('toolbarname');"
onset="this.setAttribute('toolbarname', val); return val;"/>
<property name="customizationTarget" readonly="true">
<getter><![CDATA[
if (this._customizationTarget)
return this._customizationTarget;
let id = this.getAttribute("customizationtarget");
if (id)
this._customizationTarget = document.getElementById(id);
if (this._customizationTarget)
this._customizationTarget.insertItem = this.insertItem.bind(this);
else
this._customizationTarget = this;
return this._customizationTarget;
]]></getter>
</property>
<property name="toolbox" readonly="true">
<getter><![CDATA[
if (this._toolbox)
return this._toolbox;
let toolboxId = this.getAttribute("toolboxid");
if (toolboxId) {
let toolbox = document.getElementById(toolboxId);
if (toolbox) {
if (toolbox.externalToolbars.indexOf(this) == -1)
toolbox.externalToolbars.push(this);
this._toolbox = toolbox;
}
}
if (!this._toolbox && this.parentNode &&
this.parentNode.localName == "toolbox") {
this._toolbox = this.parentNode;
}
return this._toolbox;
]]></getter>
</property>
<property name="currentSet" readonly="true">
<getter><![CDATA[
if (!this._customizationTarget)
return "";
return [node.id for (node of this._customizationTarget.children)].join(',');
]]></getter>
</property>
</implementation>
</binding>
<!-- The toolbar-menubar-autohide and toolbar-drag bindings are almost
verbatim copies of their toolkit counterparts - they just inherit from
the customizableui's toolbar binding instead of toolkit's. We're currently
OK with the maintainance burden of having two copies of a binding, since
the long term goal is to move the customization framework into toolkit. -->
<binding id="toolbar-menubar-autohide"
extends="chrome://browser/content/customizableui/toolbar.xml#toolbar">
<implementation>
<constructor>
this._setInactive();
</constructor>
<destructor>
this._setActive();
</destructor>
<field name="_inactiveTimeout">null</field>
<field name="_contextMenuListener"><![CDATA[({
toolbar: this,
contextMenu: null,
get active () !!this.contextMenu,
init: function (event) {
let node = event.target;
while (node != this.toolbar) {
if (node.localName == "menupopup")
return;
node = node.parentNode;
}
let contextMenuId = this.toolbar.getAttribute("context");
if (!contextMenuId)
return;
this.contextMenu = document.getElementById(contextMenuId);
if (!this.contextMenu)
return;
this.contextMenu.addEventListener("popupshown", this, false);
this.contextMenu.addEventListener("popuphiding", this, false);
this.toolbar.addEventListener("mousemove", this, false);
},
handleEvent: function (event) {
switch (event.type) {
case "popupshown":
this.toolbar.removeEventListener("mousemove", this, false);
break;
case "popuphiding":
case "mousemove":
this.toolbar._setInactiveAsync();
this.toolbar.removeEventListener("mousemove", this, false);
this.contextMenu.removeEventListener("popuphiding", this, false);
this.contextMenu.removeEventListener("popupshown", this, false);
this.contextMenu = null;
break;
}
}
})]]></field>
<method name="_setInactive">
<body><![CDATA[
this.setAttribute("inactive", "true");
]]></body>
</method>
<method name="_setInactiveAsync">
<body><![CDATA[
this._inactiveTimeout = setTimeout(function (self) {
if (self.getAttribute("autohide") == "true") {
self._inactiveTimeout = null;
self._setInactive();
}
}, 0, this);
]]></body>
</method>
<method name="_setActive">
<body><![CDATA[
if (this._inactiveTimeout) {
clearTimeout(this._inactiveTimeout);
this._inactiveTimeout = null;
}
this.removeAttribute("inactive");
]]></body>
</method>
</implementation>
<handlers>
<handler event="DOMMenuBarActive" action="this._setActive();"/>
<handler event="popupshowing" action="this._setActive();"/>
<handler event="mousedown" button="2" action="this._contextMenuListener.init(event);"/>
<handler event="DOMMenuBarInactive"><![CDATA[
if (!this._contextMenuListener.active)
this._setInactiveAsync();
]]></handler>
</handlers>
</binding>
<binding id="toolbar-drag"
extends="chrome://browser/content/customizableui/toolbar.xml#toolbar">
<implementation>
<field name="_dragBindingAlive">true</field>
<constructor><![CDATA[
if (!this._draggableStarted) {
this._draggableStarted = true;
try {
let tmp = {};
Components.utils.import("resource://gre/modules/WindowDraggingUtils.jsm", tmp);
let draggableThis = new tmp.WindowDraggingElement(this);
draggableThis.mouseDownCheck = function(e) {
// Don't move while customizing.
return this._dragBindingAlive &&
this.getAttribute("customizing") != "true";
};
} catch (e) {}
}
]]></constructor>
</implementation>
</binding>
<!-- This is a peculiar binding. It is here to deal with overlayed/inserted add-on content,
and immediately direct such content elsewhere. -->
<binding id="addonbar-delegating">
<implementation>
<constructor><![CDATA[
// Reading these immediately so nobody messes with them anymore:
this._delegatingToolbar = this.getAttribute("toolbar-delegate");
// Leaving those in here to unbreak some code:
if (document.readyState == "complete") {
this._init();
} else {
// Need to wait until XUL overlays are loaded. See bug 554279.
let self = this;
document.addEventListener("readystatechange", function onReadyStateChange() {
if (document.readyState != "complete")
return;
document.removeEventListener("readystatechange", onReadyStateChange, false);
self._init();
}, false);
}
]]></constructor>
<method name="_init">
<body><![CDATA[
// Searching for the toolbox palette in the toolbar binding because
// toolbars are constructed first.
let toolbox = this.toolbox;
if (toolbox && !toolbox.palette) {
for (let node of toolbox.children) {
if (node.localName == "toolbarpalette") {
// Hold on to the palette but remove it from the document.
toolbox.palette = node;
toolbox.removeChild(node);
}
}
}
CustomizableUI.registerToolbar(this);
this.evictNodes();
// We can't easily use |this| or strong bindings for the observer fn here
// because that creates leaky circular references when the node goes away,
// and XBL destructors are unreliable.
let mutationObserver = new MutationObserver(function(mutations) {
if (!mutations.length) {
return;
}
let toolbar = mutations[0].target;
if (!toolbar._isModifying) {
toolbar.evictNodes();
}
});
mutationObserver.observe(this, {childList: true});
]]></body>
</method>
<method name="evictNodes">
<body><![CDATA[
this._isModifying = true;
let i = this.childNodes.length;
while (i--) {
let node = this.childNodes[i];
if (this.childNodes[i].id) {
this.evictNode(this.childNodes[i]);
} else {
node.remove();
}
}
this._isModifying = false;
]]></body>
</method>
<method name="evictNode">
<parameter name="aNode"/>
<body>
<![CDATA[
if (this._whiteListed.has(aNode.id) || CustomizableUI.isSpecialWidget(aNode.id)) {
return;
}
const kItemMaxWidth = 100;
let oldParent = aNode.parentNode;
try {
aNode.setAttribute("removable", "true");
let nodeWidth = aNode.getBoundingClientRect().width;
if (nodeWidth == 0 || nodeWidth > kItemMaxWidth) {
throw new Error(aNode.id + " is too big (" + nodeWidth +
"px wide), moving to the palette");
}
CustomizableUI.addWidgetToArea(aNode.id, this._delegatingToolbar);
} catch (ex) {
Cu.reportError(ex);
// This will throw if the node is too big, or can't be moved there for
// some reason. Try to remove it anyway:
try {
CustomizableUI.removeWidgetFromArea(aNode.id);
} catch (ex) {
Cu.reportError(ex);
aNode.remove();
}
}
// Surprise: addWidgetToArea(palette) will get you nothing if the palette
// is not constructed yet. Fix:
if (aNode.parentNode == oldParent) {
let palette = this.toolbox.palette;
if (palette && oldParent != palette) {
palette.appendChild(aNode);
}
}
]]></body>
</method>
<method name="insertItem">
<parameter name="aId"/>
<parameter name="aBeforeElt"/>
<parameter name="aWrapper"/>
<body><![CDATA[
if (aWrapper) {
Cu.reportError("Can't insert " + aId + ": using insertItem " +
"no longer supports wrapper elements.");
return null;
}
let widget = CustomizableUI.getWidget(aId);
widget = widget && widget.forWindow(window);
let node = widget && widget.node;
if (!node) {
return null;
}
this._isModifying = true;
// Temporarily add it here so it can have a width, then ditch it:
this.appendChild(node);
this.evictNode(node);
this._isModifying = false;
// We will now have moved stuff around; kick off an aftercustomization event
// so add-ons know we've just moved their stuff:
if (window.gCustomizeMode) {
window.gCustomizeMode.dispatchToolboxEvent("aftercustomization");
}
return node;
]]></body>
</method>
<property name="customizationTarget" readonly="true">
<getter><![CDATA[
return this;
]]></getter>
</property>
<property name="currentSet">
<getter><![CDATA[
return [node.id for (node of this.children)].join(',');
]]></getter>
<setter><![CDATA[
let v = val.split(',');
let newButtons = v.filter(x => x && (!this._whiteListed.has(x) &&
!CustomizableUI.isSpecialWidget(x) &&
!this._currentSetMigrated.has(x)));
for (x of newButtons) {
this._currentSetMigrated.add(x);
this.insertItem(x);
}
]]></setter>
</property>
<property name="toolbox" readonly="true">
<getter><![CDATA[
if (!this._toolbox && this.parentNode &&
this.parentNode.localName == "toolbox") {
this._toolbox = this.parentNode;
}
return this._toolbox;
]]></getter>
</property>
<field name="_whiteListed" readonly="true">new Set(["addonbar-closebutton", "status-bar"])</field>
<field name="_isModifying">false</field>
<field name="_currentSetMigrated">new Set()</field>
</implementation>
</binding>
</bindings>

View File

@ -0,0 +1,11 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
PARALLEL_DIRS += [
'content',
'src',
'test',
]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,520 @@
/* 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 = ["CustomizableWidgets"];
Cu.import("resource:///modules/CustomizableUI.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
const kWidePanelItemClass = "panel-combined-item";
let gModuleName = "[CustomizableWidgets]";
#include logging.js
function setAttributes(aNode, aAttrs) {
for (let [name, value] of Iterator(aAttrs)) {
if (!value) {
if (aNode.hasAttribute(name))
aNode.removeAttribute(name);
} else {
if (name == "label" || name == "tooltiptext")
value = CustomizableUI.getLocalizedProperty(aAttrs, name);
aNode.setAttribute(name, value);
}
}
}
// This function is called whenever an item gets moved in the menu panel. It
// adjusts the position of widgets within the panel to reduce single-column
// buttons from being placed in a row by themselves.
function adjustPosition(aNode) {
// TODO(bug 885574): Merge this constant with the one in CustomizeMode.jsm,
// maybe just use a pref for this.
const kColumnsInMenuPanel = 3;
// Make sure that there are n % columns = 0 narrow buttons before the widget.
let prevSibling = aNode.previousElementSibling;
let previousSiblingCount = 0;
while (prevSibling) {
if (!prevSibling.classList.contains(kWidePanelItemClass)) {
previousSiblingCount++;
}
prevSibling = prevSibling.previousElementSibling;
}
if (previousSiblingCount % kColumnsInMenuPanel) {
let previousElement = aNode.previousElementSibling;
if (!previousElement ||
previousElement.classList.contains(kWidePanelItemClass)) {
return;
}
let position = Array.prototype.indexOf.call(aNode.parentNode.children, aNode);
// We don't need to move all of the items in this pass, because
// this move will trigger adjustPosition to get called again. The
// function will stop recursing when it finds that there is no
// more work that is needed.
CustomizableUI.moveWidgetWithinArea(aNode.id, position - 1);
}
}
const CustomizableWidgets = [{
id: "history-panelmenu",
type: "view",
viewId: "PanelUI-history",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL, CustomizableUI.AREA_NAVBAR],
onViewShowing: function(aEvent) {
// Populate our list of history
const kMaxResults = 15;
let doc = aEvent.detail.ownerDocument;
let options = PlacesUtils.history.getNewQueryOptions();
options.excludeQueries = true;
options.includeHidden = false;
options.resultType = options.RESULTS_AS_URI;
options.queryType = options.QUERY_TYPE_HISTORY;
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
options.maxResults = kMaxResults;
let query = PlacesUtils.history.getNewQuery();
let items = doc.getElementById("PanelUI-historyItems");
// Clear previous history items.
while (items.firstChild) {
items.removeChild(items.firstChild);
}
PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
.asyncExecuteLegacyQueries([query], 1, options, {
handleResult: function (aResultSet) {
let fragment = doc.createDocumentFragment();
for (let row, i = 0; (row = aResultSet.getNextRow()); i++) {
try {
let uri = row.getResultByIndex(1);
let title = row.getResultByIndex(2);
let icon = row.getResultByIndex(6);
let item = doc.createElementNS(kNSXUL, "toolbarbutton");
item.setAttribute("label", title || uri);
item.addEventListener("click", function(aEvent) {
if (aEvent.button == 0) {
doc.defaultView.openUILink(uri, aEvent);
CustomizableUI.hidePanelForNode(item);
}
});
if (icon)
item.setAttribute("image", "moz-anno:favicon:" + icon);
fragment.appendChild(item);
} catch (e) {
ERROR("Error while showing history subview: " + e);
}
}
items.appendChild(fragment);
},
handleError: function (aError) {
LOG("History view tried to show but had an error: " + aError);
},
handleCompletion: function (aReason) {
LOG("History view is being shown!");
},
});
},
onViewHiding: function(aEvent) {
LOG("History view is being hidden!");
}
}, {
id: "privatebrowsing-button",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL],
onCommand: function(e) {
if (e.target && e.target.ownerDocument && e.target.ownerDocument.defaultView) {
let win = e.target.ownerDocument.defaultView;
if (typeof win.OpenBrowserWindow == "function") {
win.OpenBrowserWindow({private: true});
}
}
}
}, {
id: "save-page-button",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL],
onCommand: function(aEvent) {
let win = aEvent.target &&
aEvent.target.ownerDocument &&
aEvent.target.ownerDocument.defaultView;
if (win && typeof win.saveDocument == "function") {
win.saveDocument(win.content.document);
}
}
}, {
id: "find-button",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL],
onCommand: function(aEvent) {
let win = aEvent.target &&
aEvent.target.ownerDocument &&
aEvent.target.ownerDocument.defaultView;
if (win && win.gFindBar) {
win.gFindBar.onFindCommand();
}
}
}, {
id: "open-file-button",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL],
onCommand: function(aEvent) {
let win = aEvent.target
&& aEvent.target.ownerDocument
&& aEvent.target.ownerDocument.defaultView;
if (win && typeof win.BrowserOpenFileWindow == "function") {
win.BrowserOpenFileWindow();
}
}
}, {
id: "developer-button",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL],
onCommand: function(aEvent) {
let win = aEvent.target &&
aEvent.target.ownerDocument &&
aEvent.target.ownerDocument.defaultView;
if (win && win.gDevToolsBrowser) {
win.gDevToolsBrowser.toggleToolboxCommand(win.gBrowser);
}
}
}, {
id: "add-ons-button",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL],
onCommand: function(aEvent) {
let win = aEvent.target &&
aEvent.target.ownerDocument &&
aEvent.target.ownerDocument.defaultView;
if (win && typeof win.BrowserOpenAddonsMgr == "function") {
win.BrowserOpenAddonsMgr();
}
}
}, {
id: "preferences-button",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL],
onCommand: function(aEvent) {
let win = aEvent.target &&
aEvent.target.ownerDocument &&
aEvent.target.ownerDocument.defaultView;
if (win && typeof win.openPreferences == "function") {
win.openPreferences();
}
}
}, {
id: "zoom-controls",
type: "custom",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL, CustomizableUI.AREA_NAVBAR],
onBuild: function(aDocument) {
let inPanel = (this.currentArea == CustomizableUI.AREA_PANEL);
let noautoclose = inPanel ? "true" : null;
let flex = inPanel ? "1" : null;
let cls = inPanel ? "panel-combined-button" : "toolbarbutton-1";
let buttons = [{
id: "zoom-out-button",
noautoclose: noautoclose,
command: "cmd_fullZoomReduce",
flex: flex,
class: cls,
label: true,
tooltiptext: true
}, {
id: "zoom-reset-button",
noautoclose: noautoclose,
command: "cmd_fullZoomReset",
flex: flex,
class: cls,
tooltiptext: true
}, {
id: "zoom-in-button",
noautoclose: noautoclose,
command: "cmd_fullZoomEnlarge",
flex: flex,
class: cls,
label: true,
tooltiptext: true
}];
let node = aDocument.createElementNS(kNSXUL, "toolbaritem");
node.setAttribute("id", "zoom-controls");
node.setAttribute("title", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
// Set this as an attribute in addition to the property to make sure we can style correctly.
node.setAttribute("removable", "true");
if (inPanel)
node.setAttribute("flex", "1");
node.classList.add("chromeclass-toolbar-additional");
node.classList.add(kWidePanelItemClass);
buttons.forEach(function(aButton) {
let btnNode = aDocument.createElementNS(kNSXUL, "toolbarbutton");
setAttributes(btnNode, aButton);
node.appendChild(btnNode);
});
// The middle node is the 'Reset Zoom' button.
let zoomResetButton = node.childNodes[1];
let window = aDocument.defaultView;
function updateZoomResetButton() {
zoomResetButton.setAttribute("label", CustomizableUI.getLocalizedProperty(
buttons[1], "label", [Math.floor(window.ZoomManager.zoom * 100)]
));
};
// Register ourselves with the service so we know when the zoom prefs change.
Services.obs.addObserver(updateZoomResetButton, "browser-fullZoom:zoomChange", false);
Services.obs.addObserver(updateZoomResetButton, "browser-fullZoom:zoomReset", false);
Services.obs.addObserver(updateZoomResetButton, "browser-fullZoom:locationChange", false);
updateZoomResetButton();
if (!inPanel)
zoomResetButton.setAttribute("hidden", "true");
function updateWidgetStyle(aInPanel) {
let attrs = {
noautoclose: aInPanel ? "true" : null,
flex: aInPanel ? "1" : null,
class: aInPanel ? "panel-combined-button" : "toolbarbutton-1"
};
for (let i = 0, l = node.childNodes.length; i < l; ++i) {
setAttributes(node.childNodes[i], attrs);
}
zoomResetButton.setAttribute("hidden", aInPanel ? "false" : "true");
if (aInPanel)
node.setAttribute("flex", "1");
else if (node.hasAttribute("flex"))
node.removeAttribute("flex");
}
let listener = {
onWidgetAdded: function(aWidgetId, aArea, aPosition) {
if (this.currentArea == CustomizableUI.AREA_PANEL) {
adjustPosition(node);
}
if (aWidgetId != this.id)
return;
updateWidgetStyle(aArea == CustomizableUI.AREA_PANEL);
}.bind(this),
onWidgetRemoved: function(aWidgetId, aPrevArea) {
if (this.currentArea == CustomizableUI.AREA_PANEL) {
adjustPosition(node);
}
if (aWidgetId != this.id)
return;
// When a widget is demoted to the palette ('removed'), it's visual
// style should change.
updateWidgetStyle(false);
zoomResetButton.setAttribute("hidden", "true");
}.bind(this),
onWidgetReset: function(aWidgetId) {
if (aWidgetId != this.id)
return;
updateWidgetStyle(this.currentArea == CustomizableUI.AREA_PANEL);
}.bind(this),
onWidgetMoved: function(aWidgetId, aArea) {
if (this.currentArea == CustomizableUI.AREA_PANEL) {
adjustPosition(node);
}
if (aWidgetId != this.id)
return;
updateWidgetStyle(aArea == CustomizableUI.AREA_PANEL);
}.bind(this),
onWidgetInstanceRemoved: function(aWidgetId, aDoc) {
if (aWidgetId != this.id || aDoc != aDocument)
return;
CustomizableUI.removeListener(listener);
Services.obs.removeObserver(updateZoomResetButton, "browser-fullZoom:zoomChange");
Services.obs.removeObserver(updateZoomResetButton, "browser-fullZoom:zoomReset");
}.bind(this)
};
CustomizableUI.addListener(listener);
return node;
}
}, {
id: "edit-controls",
type: "custom",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL, CustomizableUI.AREA_NAVBAR],
onBuild: function(aDocument) {
let inPanel = (this.currentArea == CustomizableUI.AREA_PANEL);
let flex = inPanel ? "1" : null;
let cls = inPanel ? "panel-combined-button" : "toolbarbutton-1";
let buttons = [{
id: "cut-button",
command: "cmd_cut",
flex: flex,
class: cls,
label: true,
tooltiptext: true
}, {
id: "copy-button",
command: "cmd_copy",
flex: flex,
class: cls,
label: true,
tooltiptext: true
}, {
id: "paste-button",
command: "cmd_paste",
flex: flex,
class: cls,
label: true,
tooltiptext: true
}];
let node = aDocument.createElementNS(kNSXUL, "toolbaritem");
node.setAttribute("id", "edit-controls");
node.setAttribute("title", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
// Set this as an attribute in addition to the property to make sure we can style correctly.
node.setAttribute("removable", "true");
if (inPanel)
node.setAttribute("flex", "1");
node.classList.add("chromeclass-toolbar-additional");
node.classList.add(kWidePanelItemClass);
buttons.forEach(function(aButton) {
let btnNode = aDocument.createElementNS(kNSXUL, "toolbarbutton");
setAttributes(btnNode, aButton);
node.appendChild(btnNode);
});
function updateWidgetStyle(aInPanel) {
let attrs = {
flex: aInPanel ? "1" : null,
class: aInPanel ? "panel-combined-button" : "toolbarbutton-1"
};
for (let i = 0, l = node.childNodes.length; i < l; ++i) {
setAttributes(node.childNodes[i], attrs);
}
if (aInPanel)
node.setAttribute("flex", "1");
else if (node.hasAttribute("flex"))
node.removeAttribute("flex");
}
let listener = {
onWidgetAdded: function(aWidgetId, aArea, aPosition) {
if (this.currentArea == CustomizableUI.AREA_PANEL) {
adjustPosition(node);
}
if (aWidgetId != this.id)
return;
updateWidgetStyle(aArea == CustomizableUI.AREA_PANEL);
}.bind(this),
onWidgetRemoved: function(aWidgetId, aPrevArea) {
if (this.currentArea == CustomizableUI.AREA_PANEL) {
adjustPosition(node);
}
if (aWidgetId != this.id)
return;
// When a widget is demoted to the palette ('removed'), it's visual
// style should change.
updateWidgetStyle(false);
}.bind(this),
onWidgetReset: function(aWidgetId) {
if (aWidgetId != this.id)
return;
updateWidgetStyle(this.currentArea == CustomizableUI.AREA_PANEL);
}.bind(this),
onWidgetMoved: function(aWidgetId, aArea) {
if (this.currentArea == CustomizableUI.AREA_PANEL) {
adjustPosition(node);
}
if (aWidgetId != this.id)
return;
updateWidgetStyle(aArea == CustomizableUI.AREA_PANEL);
}.bind(this),
onWidgetInstanceRemoved: function(aWidgetId, aDoc) {
if (aWidgetId != this.id || aDoc != aDocument)
return;
CustomizableUI.removeListener(listener);
}.bind(this)
};
CustomizableUI.addListener(listener);
return node;
}
},
{
id: "feed-button",
type: "view",
viewId: "PanelUI-feeds",
removable: true,
defaultArea: CustomizableUI.AREA_PANEL,
allowedAreas: [CustomizableUI.AREA_PANEL, CustomizableUI.AREA_NAVBAR],
onClick: function(aEvent) {
let win = aEvent.target.ownerDocument.defaultView;
let feeds = win.gBrowser.selectedBrowser.feeds;
// Here, we only care about the case where we have exactly 1 feed and the
// user clicked...
let isClick = (aEvent.button == 0 || aEvent.button == 1);
if (feeds && feeds.length == 1 && isClick) {
aEvent.preventDefault();
aEvent.stopPropagation();
win.FeedHandler.subscribeToFeed(feeds[0].href, aEvent);
CustomizableUI.hidePanelForNode(aEvent.target);
}
},
onViewShowing: function(aEvent) {
let doc = aEvent.detail.ownerDocument;
let container = doc.getElementById("PanelUI-feeds");
let gotView = doc.defaultView.FeedHandler.buildFeedList(container, true);
// For no feeds or only a single one, don't show the panel.
if (!gotView) {
aEvent.preventDefault();
aEvent.stopPropagation();
return;
}
},
onCreated: function(node) {
let win = node.ownerDocument.defaultView;
let selectedBrowser = win.gBrowser.selectedBrowser;
let feeds = selectedBrowser && selectedBrowser.feeds;
if (!feeds || !feeds.length) {
node.setAttribute("disabled", "true");
}
}
}];

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
EXTRA_PP_JS_MODULES = \
CustomizableUI.jsm \
CustomizableWidgets.jsm \
CustomizeMode.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,25 @@
#if 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/. */
#endif
XPCOMUtils.defineLazyModuleGetter(this, "console",
"resource://gre/modules/devtools/Console.jsm");
let gDebug = false;
try {
gDebug = Services.prefs.getBoolPref(kPrefCustomizationDebug);
} catch (e) {}
function LOG(...args) {
if (gDebug) {
args.unshift(gModuleName);
console.log.apply(console, args);
}
}
function ERROR(...args) {
args.unshift(gModuleName);
console.error.apply(console, args);
}

View File

@ -0,0 +1,6 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.

View File

@ -0,0 +1,22 @@
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
MOCHITEST_BROWSER_FILES = \
browser_873501_handle_specials.js \
browser_877178_unregisterArea.js \
browser_877447_skip_missing_ids.js \
browser_878452_drag_to_panel.js \
browser_880382_drag_wide_widgets_in_panel.js \
head.js \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,91 @@
/* 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/. */
const kToolbarName = "test-specials-toolbar";
let gTests = [
{
desc: "Add a toolbar with two springs and the downloads button.",
run: function() {
// Create the toolbar with a single spring:
createToolbarWithPlacements(kToolbarName, ["spring"]);
ok(document.getElementById(kToolbarName), "Toolbar should be created.");
// Check it's there with a generated ID:
assertAreaPlacements(kToolbarName, [/customizableui-special-spring\d+/]);
let [springId] = getAreaWidgetIds(kToolbarName);
// Add a second spring, check if that's there and doesn't share IDs
CustomizableUI.addWidgetToArea("spring", kToolbarName);
assertAreaPlacements(kToolbarName, [springId,
/customizableui-special-spring\d+/]);
let [, spring2Id] = getAreaWidgetIds(kToolbarName);
isnot(springId, spring2Id, "Springs shouldn't have identical IDs.");
// Try moving the downloads button to this new toolbar, between the two springs:
CustomizableUI.addWidgetToArea("downloads-button", kToolbarName, 1);
assertAreaPlacements(kToolbarName, [springId, "downloads-button", spring2Id]);
},
teardown: removeCustomToolbars
},
{
desc: "Add separators around the downloads button.",
run: function() {
createToolbarWithPlacements(kToolbarName, ["separator"]);
ok(document.getElementById(kToolbarName), "Toolbar should be created.");
// Check it's there with a generated ID:
assertAreaPlacements(kToolbarName, [/customizableui-special-separator\d+/]);
let [separatorId] = getAreaWidgetIds(kToolbarName);
CustomizableUI.addWidgetToArea("separator", kToolbarName);
assertAreaPlacements(kToolbarName, [separatorId,
/customizableui-special-separator\d+/]);
let [, separator2Id] = getAreaWidgetIds(kToolbarName);
isnot(separatorId, separator2Id, "Separator ids shouldn't be equal.");
CustomizableUI.addWidgetToArea("downloads-button", kToolbarName, 1);
assertAreaPlacements(kToolbarName, [separatorId, "downloads-button", separator2Id]);
},
teardown: removeCustomToolbars
},
{
desc: "Add spacers around the downloads button.",
run: function() {
createToolbarWithPlacements(kToolbarName, ["spacer"]);
ok(document.getElementById(kToolbarName), "Toolbar should be created.");
// Check it's there with a generated ID:
assertAreaPlacements(kToolbarName, [/customizableui-special-spacer\d+/]);
let [spacerId] = getAreaWidgetIds(kToolbarName);
CustomizableUI.addWidgetToArea("spacer", kToolbarName);
assertAreaPlacements(kToolbarName, [spacerId,
/customizableui-special-spacer\d+/]);
let [, spacer2Id] = getAreaWidgetIds(kToolbarName);
isnot(spacerId, spacer2Id, "Spacer ids shouldn't be equal.");
CustomizableUI.addWidgetToArea("downloads-button", kToolbarName, 1);
assertAreaPlacements(kToolbarName, [spacerId, "downloads-button", spacer2Id]);
},
teardown: removeCustomToolbars
}
];
function asyncCleanup() {
yield resetCustomization();
}
function cleanup() {
removeCustomToolbars();
}
function test() {
waitForExplicitFinish();
registerCleanupFunction(cleanup);
runTests(gTests, asyncCleanup);
}

View File

@ -0,0 +1,67 @@
/* 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/. */
let gTests = [
{
desc: "Sanity checks",
run: function() {
SimpleTest.doesThrow(function() CustomizableUI.registerArea("@foo"),
"Registering areas with an invalid ID should throw.");
SimpleTest.doesThrow(function() CustomizableUI.registerArea([]),
"Registering areas with an invalid ID should throw.");
SimpleTest.doesThrow(function() CustomizableUI.registerArea(CustomizableUI.AREA_NAVBAR),
"Registering an area with an ID that's already registered should throw.");
SimpleTest.doesThrow(function() CustomizableUI.unregisterArea("@foo"),
"Unregistering areas with an invalid ID should throw.");
SimpleTest.doesThrow(function() CustomizableUI.unregisterArea([]),
"Unregistering areas with an invalid ID should throw.");
SimpleTest.doesThrow(function() CustomizableUI.unregisterArea("unknown"),
"Unregistering an area that's not registered should throw.");
}
},
{
desc: "Check areas are loaded with their default placements.",
run: function() {
ok(CustomizableUI.inDefaultState, "Everything should be in its default state.");
}
},
{
desc: "Check registering and unregistering a new area.",
run: function() {
const kToolbarId = "test-registration-toolbar";
const kButtonId = "test-registration-button";
createDummyXULButton(kButtonId);
createToolbarWithPlacements(kToolbarId, ["spring", kButtonId, "spring"]);
assertAreaPlacements(kToolbarId,
[/customizableui-special-spring\d+/,
kButtonId,
/customizableui-special-spring\d+/]);
ok(CustomizableUI.inDefaultState, "With a new toolbar and default placements, " +
"everything should still be in a default state.");
removeCustomToolbars(); // Will call unregisterArea for us
ok(CustomizableUI.inDefaultState, "When the toolbar is unregistered, " +
"everything should still be in a default state.");
}
}
];
function asyncCleanup() {
yield resetCustomization();
}
function cleanup() {
removeCustomToolbars();
}
function test() {
waitForExplicitFinish();
registerCleanupFunction(cleanup);
runTests(gTests, asyncCleanup);
}

View File

@ -0,0 +1,35 @@
/* 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/. */
let gTests = [
{
run: function() {
const kButtonId = "look-at-me-disappear-button";
CustomizableUI.reset();
ok(CustomizableUI.inDefaultState, "Should be in the default state.");
let btn = createDummyXULButton(kButtonId, "Gone!");
CustomizableUI.addWidgetToArea(kButtonId, CustomizableUI.AREA_NAVBAR);
ok(!CustomizableUI.inDefaultState, "Should no longer be in the default state.");
is(btn.parentNode.parentNode.id, CustomizableUI.AREA_NAVBAR, "Button should be in navbar");
btn.remove();
is(btn.parentNode, null, "Button is no longer in the navbar");
ok(CustomizableUI.inDefaultState, "Should be back in the default state, " +
"despite unknown button ID in placements.");
}
}
];
function asyncCleanup() {
yield resetCustomization();
}
function cleanup() {
removeCustomToolbars();
}
function test() {
waitForExplicitFinish();
registerCleanupFunction(cleanup);
runTests(gTests, asyncCleanup);
}

View File

@ -0,0 +1,80 @@
/* 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/. */
let gTests = [
{
desc: "Dragging an item from the palette to another button in the panel should work.",
setup: startCustomizing,
run: function() {
let btn = document.getElementById("developer-button");
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
let lastButtonIndex = placements.length - 1;
let lastButton = placements[lastButtonIndex];
let placementsAfterInsert = placements.slice(0, lastButtonIndex).concat(["developer-button", lastButton]);
let lastButtonNode = document.getElementById(lastButton);
simulateItemDrag(btn, lastButtonNode);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterInsert);
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
let palette = document.getElementById("customization-palette");
simulateItemDrag(btn, palette);
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
},
teardown: endCustomizing
},
{
desc: "Dragging an item from the palette to the panel itself should also work.",
setup: startCustomizing,
run: function() {
let btn = document.getElementById("developer-button");
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
let placements = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
let placementsAfterAppend = placements.concat(["developer-button"]);
simulateItemDrag(btn, panel);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterAppend);
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
let palette = document.getElementById("customization-palette");
simulateItemDrag(btn, palette);
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
},
teardown: endCustomizing
},
{
desc: "Dragging an item from the palette to an empty panel should also work.",
setup: function() {
let widgetIds = getAreaWidgetIds(CustomizableUI.AREA_PANEL);
while (widgetIds.length) {
CustomizableUI.removeWidgetFromArea(widgetIds.shift());
}
return startCustomizing()
},
run: function() {
let btn = document.getElementById("developer-button");
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
assertAreaPlacements(panel.id, []);
let placementsAfterAppend = ["developer-button"];
simulateItemDrag(btn, panel);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterAppend);
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
let palette = document.getElementById("customization-palette");
simulateItemDrag(btn, palette);
assertAreaPlacements(panel.id, []);
},
teardown: endCustomizing
}
];
function asyncCleanup() {
yield resetCustomization();
}
function test() {
waitForExplicitFinish();
runTests(gTests, asyncCleanup);
}

View File

@ -0,0 +1,414 @@
/* 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/. */
let gTests = [
{
desc: "Dragging the zoom controls to be before the print button " +
"should not move any controls.",
setup: startCustomizing,
run: function() {
let zoomControls = document.getElementById("zoom-controls");
let printButton = document.getElementById("print-button");
let placementsAfterMove = ["edit-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"zoom-controls",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(zoomControls, printButton);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
let newWindowButton = document.getElementById("new-window-button");
simulateItemDrag(zoomControls, newWindowButton);
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
},
teardown: endCustomizing
},
{
desc: "Dragging the zoom controls to be before the save button " +
"should not move any controls.",
setup: startCustomizing,
run: function() {
let zoomControls = document.getElementById("zoom-controls");
let savePageButton = document.getElementById("save-page-button");
let placementsAfterMove = ["edit-controls",
"zoom-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(zoomControls, savePageButton);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
ok(CustomizableUI.inDefaultState, "Should be in default state.");
},
teardown: endCustomizing
},
{
desc: "Dragging the zoom controls to be before the new-window " +
"button should not move any widgets.",
setup: startCustomizing,
run: function() {
let zoomControls = document.getElementById("zoom-controls");
let newWindowButton = document.getElementById("new-window-button");
let placementsAfterMove = ["edit-controls",
"zoom-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(zoomControls, newWindowButton);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
},
teardown: endCustomizing
},
{
desc: "Dragging the zoom controls to be before the history-panelmenu " +
"should move the zoom-controls in to the row higher than the " +
"history-panelmenu.",
setup: startCustomizing,
run: function() {
let zoomControls = document.getElementById("zoom-controls");
let historyPanelMenu = document.getElementById("history-panelmenu");
let placementsAfterMove = ["edit-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"zoom-controls",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(zoomControls, historyPanelMenu);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
let newWindowButton = document.getElementById("new-window-button");
simulateItemDrag(zoomControls, newWindowButton);
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
},
teardown: endCustomizing
},
{
desc: "Dragging the zoom controls to be before the preferences-button " +
"should move the zoom-controls in to the row higher than the " +
"preferences-button.",
setup: startCustomizing,
run: function() {
let zoomControls = document.getElementById("zoom-controls");
let preferencesButton = document.getElementById("preferences-button");
let placementsAfterMove = ["edit-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"zoom-controls",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(zoomControls, preferencesButton);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
let newWindowButton = document.getElementById("new-window-button");
simulateItemDrag(zoomControls, newWindowButton);
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
},
teardown: endCustomizing
},
{
desc: "Dragging an item from the palette to before the zoom-controls " +
"should move it and two other buttons before the zoom controls.",
setup: startCustomizing,
run: function() {
let developerButton = document.getElementById("developer-button");
let zoomControls = document.getElementById("zoom-controls");
let expectedPlacementsAfterInsert = ["edit-controls",
"developer-button",
"new-window-button",
"privatebrowsing-button",
"zoom-controls",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(developerButton, zoomControls);
// Currently, the developer-button is placed after the zoom-controls, but it should be
// placed like expectedPlacementsAfterInsert describes.
todoAssertAreaPlacements(CustomizableUI.AREA_PANEL, expectedPlacementsAfterInsert);
let actualPlacementsAfterInsert = ["edit-controls",
"zoom-controls",
"developer-button",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
assertAreaPlacements(CustomizableUI.AREA_PANEL, actualPlacementsAfterInsert);
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
let palette = document.getElementById("customization-palette");
// Check that the palette items are re-wrapped correctly.
let feedWrapper = document.getElementById("wrapper-feed-button");
let feedButton = document.getElementById("feed-button");
is(feedButton.parentNode, feedWrapper,
"feed-button should be a child of wrapper-feed-button");
is(feedWrapper.getAttribute("place"), "palette",
"The feed-button wrapper should have it's place set to 'palette'");
simulateItemDrag(developerButton, palette);
is(developerButton.parentNode.tagName, "toolbarpaletteitem",
"The developer-button should be wrapped by a toolbarpaletteitem");
let newWindowButton = document.getElementById("new-window-button");
simulateItemDrag(zoomControls, newWindowButton);
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
},
teardown: endCustomizing
},
{
desc: "Dragging the edit-controls to be before the zoom-controls button " +
"should not move any widgets.",
setup: startCustomizing,
run: function() {
let editControls = document.getElementById("edit-controls");
let zoomControls = document.getElementById("zoom-controls");
let placementsAfterMove = ["edit-controls",
"zoom-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(editControls, zoomControls);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
},
teardown: endCustomizing
},
{
desc: "Dragging the edit-controls to be before the new-window-button should " +
"move the zoom-controls before the edit-controls.",
setup: startCustomizing,
run: function() {
let editControls = document.getElementById("edit-controls");
let newWindowButton = document.getElementById("new-window-button");
let placementsAfterMove = ["zoom-controls",
"edit-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(editControls, newWindowButton);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
let zoomControls = document.getElementById("zoom-controls");
simulateItemDrag(editControls, zoomControls);
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
},
teardown: endCustomizing
},
{
desc: "Dragging the edit-controls to be before the privatebrowsing-button " +
"should move the edit-controls in to the row higher than the " +
"privatebrowsing-button.",
setup: startCustomizing,
run: function() {
let editControls = document.getElementById("edit-controls");
let privateBrowsingButton = document.getElementById("privatebrowsing-button");
let placementsAfterMove = ["zoom-controls",
"edit-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(editControls, privateBrowsingButton);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
let zoomControls = document.getElementById("zoom-controls");
simulateItemDrag(editControls, zoomControls);
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
},
teardown: endCustomizing
},
{
desc: "Dragging the edit-controls to be before the save-page-button " +
"should move the edit-controls in to the row higher than the " +
"save-page-button.",
setup: startCustomizing,
run: function() {
let editControls = document.getElementById("edit-controls");
let savePageButton = document.getElementById("save-page-button");
let placementsAfterMove = ["zoom-controls",
"edit-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
simulateItemDrag(editControls, savePageButton);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
let zoomControls = document.getElementById("zoom-controls");
simulateItemDrag(editControls, zoomControls);
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
},
teardown: endCustomizing
},
{
desc: "Dragging the edit-controls to the panel itself should append " +
"the edit controls to the bottom of the panel.",
setup: startCustomizing,
run: function() {
let editControls = document.getElementById("edit-controls");
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
let placementsAfterMove = ["zoom-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button",
"edit-controls"];
simulateItemDrag(editControls, panel);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
let zoomControls = document.getElementById("zoom-controls");
simulateItemDrag(editControls, zoomControls);
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
},
teardown: endCustomizing
},
{
desc: "Dragging the edit-controls to the customization-palette and " +
"back should work.",
setup: startCustomizing,
run: function() {
let editControls = document.getElementById("edit-controls");
let palette = document.getElementById("customization-palette");
let placementsAfterMove = ["zoom-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button"];
let paletteChildElementCount = palette.childElementCount;
simulateItemDrag(editControls, palette);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
is(paletteChildElementCount + 1, palette.childElementCount,
"The palette should have a new child, congratulations!");
is(editControls.parentNode.id, "wrapper-edit-controls",
"The edit-controls should be properly wrapped.");
is(editControls.parentNode.getAttribute("place"), "palette",
"The edit-controls should have the place of 'palette'.");
let zoomControls = document.getElementById("zoom-controls");
simulateItemDrag(editControls, zoomControls);
is(paletteChildElementCount, palette.childElementCount,
"The palette child count should have returned to its prior value.");
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
},
teardown: endCustomizing
},
{
desc: "Dragging the edit-controls to each of the panel placeholders " +
"should append the edit-controls to the bottom of the panel.",
setup: startCustomizing,
run: function() {
let editControls = document.getElementById("edit-controls");
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
for (let i = 0; i < 3; i++) {
// NB: We can't just iterate over all of the placeholders
// because each drag-drop action recreates them.
let placeholder = panel.getElementsByClassName("panel-customization-placeholder")[i];
let placementsAfterMove = ["zoom-controls",
"new-window-button",
"privatebrowsing-button",
"save-page-button",
"print-button",
"history-panelmenu",
"fullscreen-button",
"find-button",
"preferences-button",
"add-ons-button",
"edit-controls"];
simulateItemDrag(editControls, placeholder);
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
let zoomControls = document.getElementById("zoom-controls");
simulateItemDrag(editControls, zoomControls);
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
}
},
teardown: endCustomizing
},
{
desc: "Dragging the developer-button back on to itself should work.",
setup: startCustomizing,
run: function() {
let developerButton = document.getElementById("developer-button");
is(developerButton.parentNode.tagName, "toolbarpaletteitem",
"developer-button should be wrapped by a toolbarpaletteitem");
simulateItemDrag(developerButton, developerButton);
is(developerButton.parentNode.tagName, "toolbarpaletteitem",
"developer-button should be wrapped by a toolbarpaletteitem");
let editControls = document.getElementById("edit-controls");
is(editControls.parentNode.tagName, "toolbarpaletteitem",
"edit-controls should be wrapped by a toolbarpaletteitem");
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
},
teardown: endCustomizing
},
];
function asyncCleanup() {
yield resetCustomization();
}
function test() {
waitForExplicitFinish();
requestLongerTimeout(5);
runTests(gTests, asyncCleanup);
}

View File

@ -0,0 +1,172 @@
/* 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/. */
// Avoid leaks by using tmp for imports...
let tmp = {};
Cu.import("resource://gre/modules/Promise.jsm", tmp);
Cu.import("resource://gre/modules/Task.jsm", tmp);
Cu.import("resource:///modules/CustomizableUI.jsm", tmp);
let {Promise, Task, CustomizableUI} = tmp;
let ChromeUtils = {};
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", ChromeUtils);
let {synthesizeDragStart, synthesizeDrop} = ChromeUtils;
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
function createDummyXULButton(id, label) {
let btn = document.createElementNS(kNSXUL, "toolbarbutton");
btn.id = id;
btn.setAttribute("label", label || id);
btn.className = "toolbarbutton-1 chromeclass-toolbar-additional";
window.gNavToolbox.palette.appendChild(btn);
return btn;
}
function createToolbarWithPlacements(id, placements) {
let tb = document.createElementNS(kNSXUL, "toolbar");
tb.id = id;
tb.setAttribute("customizable", "true");
document.getElementById("customToolbars").appendChild(tb);
CustomizableUI.registerArea(id, {
type: CustomizableUI.TYPE_TOOLBAR,
defaultPlacements: placements
});
}
function removeCustomToolbars() {
let customToolbarSet = document.getElementById("customToolbars");
while (customToolbarSet.lastChild) {
CustomizableUI.unregisterArea(customToolbarSet.lastChild.id);
customToolbarSet.lastChild.remove();
}
}
function resetCustomization() {
return CustomizableUI.reset();
}
function assertAreaPlacements(areaId, expectedPlacements) {
let actualPlacements = getAreaWidgetIds(areaId);
is(actualPlacements.length, expectedPlacements.length,
"Area " + areaId + " should have " + expectedPlacements.length + " items.");
let minItems = Math.min(expectedPlacements.length, actualPlacements.length);
for (let i = 0; i < minItems; i++) {
if (typeof expectedPlacements[i] == "string") {
is(actualPlacements[i], expectedPlacements[i],
"Item " + i + " in " + areaId + " should match expectations.");
} else if (expectedPlacements[i] instanceof RegExp) {
ok(expectedPlacements[i].test(actualPlacements[i]),
"Item " + i + " (" + actualPlacements[i] + ") in " +
areaId + " should match " + expectedPlacements[i]);
} else {
ok(false, "Unknown type of expected placement passed to " +
" assertAreaPlacements. Is your test broken?");
}
}
}
function todoAssertAreaPlacements(areaId, expectedPlacements) {
let actualPlacements = getAreaWidgetIds(areaId);
let isPassing = actualPlacements.length == expectedPlacements.length;
let minItems = Math.min(expectedPlacements.length, actualPlacements.length);
for (let i = 0; i < minItems; i++) {
if (typeof expectedPlacements[i] == "string") {
isPassing = isPassing && actualPlacements[i] == expectedPlacements[i];
} else if (expectedPlacements[i] instanceof RegExp) {
isPassing = isPassing && expectedPlacements[i].test(actualPlacements[i]);
} else {
ok(false, "Unknown type of expected placement passed to " +
" assertAreaPlacements. Is your test broken?");
}
}
todo(isPassing, "The area placements for " + areaId +
" should equal the expected placements.")
}
function getAreaWidgetIds(areaId) {
let widgetAry = CustomizableUI.getWidgetsInArea(areaId);
return widgetAry.map(x => x.id);
}
function simulateItemDrag(toDrag, target) {
let docId = toDrag.ownerDocument.documentElement.id;
let dragData = [[{type: 'text/toolbarwrapper-id/' + docId,
data: {id: toDrag.id, width: toDrag.getBoundingClientRect().width + 'px'}}]];
synthesizeDragStart(toDrag.parentNode, dragData);
synthesizeDrop(target, target, dragData);
}
function endCustomizing() {
let deferredEndCustomizing = Promise.defer();
function onCustomizationEnds() {
window.gNavToolbox.removeEventListener("aftercustomization", onCustomizationEnds);
deferredEndCustomizing.resolve();
}
window.gNavToolbox.addEventListener("aftercustomization", onCustomizationEnds);
window.gCustomizeMode.exit();
return deferredEndCustomizing.promise.then(function() {
let deferredLoadNewTab = Promise.defer();
//XXXgijs so some tests depend on this tab being about:blank. Make it so.
let newTabBrowser = window.gBrowser.selectedBrowser;
newTabBrowser.stop();
// If we stop early enough, this might actually be about:blank.
if (newTabBrowser.contentDocument.location.href == "about:blank") {
return;
}
// Otherwise, make it be about:blank, and wait for that to be done.
function onNewTabLoaded(e) {
newTabBrowser.removeEventListener("load", onNewTabLoaded, true);
deferredLoadNewTab.resolve();
}
newTabBrowser.addEventListener("load", onNewTabLoaded, true);
newTabBrowser.contentDocument.location.replace("about:blank");
return deferredLoadNewTab.promise;
});
}
function startCustomizing() {
let deferred = Promise.defer();
function onCustomizing() {
window.gNavToolbox.removeEventListener("customizationready", onCustomizing);
deferred.resolve();
}
window.gNavToolbox.addEventListener("customizationready", onCustomizing);
window.gCustomizeMode.enter();
return deferred.promise;
}
function testRunner(testAry, asyncCleanup) {
for (let test of testAry) {
info(test.desc);
if (test.setup)
yield test.setup();
info("Running test");
yield test.run();
info("Cleanup");
if (test.teardown)
yield test.teardown();
}
if (asyncCleanup) {
yield asyncCleanup();
}
}
function runTests(testAry, asyncCleanup) {
Task.spawn(testRunner(gTests, asyncCleanup)).then(finish, ex => {
// The stack of ok() here is misleading due to Promises. The stack of the
// actual exception is likely much more valuable, hence concatentating it.
ok(false, "Unexpected exception: " + ex + " With stack: " + ex.stack);
finish();
});
}

View File

@ -631,11 +631,6 @@ const DownloadsOverlayLoader = {
this._overlayLoading = false;
this._loadedOverlays[aOverlay] = true;
// Loading the overlay causes all the persisted XUL attributes to be
// reapplied, including "iconsize" on the toolbars. Until bug 640158 is
// fixed, we must recalculate the correct "iconsize" attributes manually.
retrieveToolbarIconsizesFromTheme();
this.processPendingRequests();
}

View File

@ -523,7 +523,14 @@ const DownloadsIndicatorView = {
DownloadsCommon.getIndicatorData(window).attention = false;
BrowserDownloadsUI();
} else {
DownloadsPanel.showPanel();
// If the downloads button is in the menu panel, open the Library
let widgetGroup = CustomizableUI.getWidget("downloads-button");
let widget = widgetGroup.forWindow(window);
if (widget.areaType == CustomizableUI.TYPE_MENU_PANEL) {
DownloadsPanel.showDownloadsHistory();
} else {
DownloadsPanel.showPanel();
}
}
aEvent.stopPropagation();

View File

@ -7,6 +7,7 @@
PARALLEL_DIRS += [
'about',
'certerror',
'customizableui',
'dirprovider',
'downloads',
'feeds',

View File

@ -1268,7 +1268,7 @@ BrowserGlue.prototype = {
},
_migrateUI: function BG__migrateUI() {
const UI_VERSION = 13;
const UI_VERSION = 16;
const BROWSER_DOCURL = "chrome://browser/content/browser.xul#";
let currentUIVersion = 0;
try {
@ -1458,6 +1458,60 @@ BrowserGlue.prototype = {
catch (ex) {}
}
if (currentUIVersion < 14) {
// Migrate users from text or text&icons mode to icons mode.
let updateToolbars = function (aToolbarIds, aResourceName, aResourceValue) {
let resource = this._rdf.GetResource(aResourceName);
for (toolbarId of aToolbarIds) {
let toolbar = this._rdf.GetResource(BROWSER_DOCURL + toolbarId);
let oldValue = this._getPersist(toolbar, resource);
if (oldValue && oldValue != aResourceValue) {
this._setPersist(toolbar, resource, aResourceValue);
}
}
}.bind(this);
updateToolbars(["navigator-toolbox", "nav-bar", "PersonalToolbar", "addon-bar"], "mode", "icons");
// Exclude PersonalToolbar and addon-bar since they have lockiconsize="true".
updateToolbars(["navigator-toolbox", "nav-bar"], "iconsize", "large");
}
if (currentUIVersion < 15) {
let toolbarResource = this._rdf.GetResource(BROWSER_DOCURL + "nav-bar");
let collapsedResource = this._rdf.GetResource("collapsed");
let isCollapsed = this._getPersist(toolbarResource, collapsedResource);
if (isCollapsed == "true") {
this._setPersist(toolbarResource, collapsedResource, "false");
}
}
// Insert the bookmarks-menu-button into the nav-bar if it isn't already
// there.
if (currentUIVersion < 16) {
let currentsetResource = this._rdf.GetResource("currentset");
let toolbarResource = this._rdf.GetResource(BROWSER_DOCURL + "nav-bar");
let currentset = this._getPersist(toolbarResource, currentsetResource);
// Need to migrate only if toolbar is customized.
if (currentset) {
if (!currentset.contains("bookmarks-menu-button")) {
// The button isn't in the nav-bar, so let's look for an appropriate
// place to put it.
if (currentset.contains("downloads-button")) {
currentset = currentset.replace(/(^|,)downloads-button($|,)/,
"$1bookmarks-menu-button,downloads-button$2");
} else if (currentset.contains("home-button")) {
currentset = currentset.replace(/(^|,)home-button($|,)/,
"$1bookmarks-menu-button,home-button$2");
} else {
// Just append.
currentset = currentset.replace(/(^|,)window-controls($|,)/,
"$1bookmarks-menu-button,window-controls$2")
}
this._setPersist(toolbarResource, currentsetResource, currentset);
}
}
}
if (this._dirty)
this._dataSource.QueryInterface(Ci.nsIRDFRemoteDataSource).Flush();

View File

@ -1,6 +1,9 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource:///modules/CustomizableUI.jsm");
function test() {
let cw;
let win;
@ -31,10 +34,7 @@ function test() {
let pos = currentSet.indexOf(buttonId);
if (-1 < pos) {
currentSet.splice(pos, 1);
toolbar.setAttribute("currentset", currentSet.join(","));
toolbar.currentSet = currentSet.join(",");
win.document.persist(toolbar.id, "currentset");
CustomizableUI.removeWidgetFromArea("tabview-button");
}
}

View File

@ -15,6 +15,9 @@
inside the private browsing mode -->
<!ENTITY mainWindow.titlePrivateBrowsingSuffix "(Private Browsing)">
<!ENTITY appmenu.title "Customize and Control &brandFullName;">
<!ENTITY navbarOverflow.label "More tools…">
<!-- Tab context menu -->
<!ENTITY reloadTab.label "Reload Tab">
<!ENTITY reloadTab.accesskey "R">
@ -73,12 +76,9 @@ can reach it easily. -->
<!ENTITY menubarCmd.label "Menu Bar">
<!ENTITY menubarCmd.accesskey "M">
<!ENTITY navbarCmd.label "Navigation Toolbar">
<!ENTITY navbarCmd.accesskey "N">
<!ENTITY personalbarCmd.label "Bookmarks Toolbar">
<!ENTITY personalbarCmd.accesskey "B">
<!ENTITY bookmarksToolbarItem.label "Bookmarks Toolbar Items">
<!ENTITY addonBarCmd.label "Add-on Bar">
<!ENTITY addonBarCmd.accesskey "A">
<!ENTITY pageSourceCmd.label "Page Source">
<!ENTITY pageSourceCmd.accesskey "o">
@ -161,22 +161,15 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY backForwardItem.title "Back/Forward">
<!ENTITY locationItem.title "Location">
<!ENTITY searchItem.title "Search">
<!ENTITY throbberItem.title "Activity Indicator">
<!ENTITY bookmarksItem.title "Bookmarks">
<!-- Toolbar items -->
<!ENTITY appMenuButton.label "Menu">
<!ENTITY appMenuButton.tooltip "Open &brandShortName; menu">
<!ENTITY homeButton.label "Home">
<!ENTITY tabGroupsButton.label "Tab Groups">
<!ENTITY tabGroupsButton.tooltip "Group your tabs">
<!ENTITY feedButton.label "Subscribe">
<!ENTITY feedButton.tooltip "Subscribe to this page…">
<!ENTITY bookmarksButton.label "Bookmarks">
<!ENTITY bookmarksButton.tooltip "Display your bookmarks">
<!ENTITY bookmarksCmd.commandkey "b">
<!ENTITY bookmarksMenuButton.label "Bookmarks">
@ -192,7 +185,6 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY bookmarksWinCmd.commandkey "i">
<!ENTITY historyButton.label "History">
<!ENTITY historyButton.tooltip "Display pages you've viewed recently">
<!ENTITY historySidebarCmd.commandKey "h">
<!ENTITY toolsMenu.label "Tools">
@ -316,8 +308,6 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY viewSidebarMenu.accesskey "e">
<!ENTITY viewCustomizeToolbar.label "Customize…">
<!ENTITY viewCustomizeToolbar.accesskey "C">
<!ENTITY viewTabsOnTop.label "Tabs on Top">
<!ENTITY viewTabsOnTop.accesskey "T">
<!ENTITY historyMenu.label "History">
<!ENTITY historyMenu.accesskey "s">
@ -330,16 +320,19 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY showAllHistoryCmd2.label "Show All History">
<!ENTITY showAllHistoryCmd.commandkey "H">
<!ENTITY appMenuEdit.label "Edit">
<!ENTITY appMenuCustomize.label "Customize">
<!ENTITY appMenuToolbarLayout.label "Toolbar Layout…">
<!ENTITY appMenuSidebars.label "Sidebars">
<!ENTITY appMenuFind.label "Find…">
<!ENTITY appMenuUnsorted.label "Unsorted Bookmarks">
<!ENTITY appMenuWebDeveloper.label "Web Developer">
<!ENTITY appMenuGettingStarted.label "Getting Started">
<!ENTITY appMenuSafeMode.label "Restart with Add-ons Disabled…">
<!ENTITY appMenuSafeMode.accesskey "R">
<!ENTITY appMenuBookmarks.label "Bookmarks">
<!ENTITY appMenuHistory.label "History">
<!ENTITY appMenuHistory.showAll.label "Show All History">
<!ENTITY appMenuHistory.clearRecent.label "Clear Recent History…">
<!ENTITY appMenuHistory.restoreSession.label "Restore Previous Session">
<!ENTITY customizeMenu.addToToolbar.label "Add to Toolbar">
<!ENTITY customizeMenu.addToToolbar.accesskey "A">
<!ENTITY customizeMenu.removeFromMenu.label "Remove from Menu">
<!ENTITY customizeMenu.removeFromMenu.accesskey "R">
<!ENTITY customizeMenu.addMoreItems.label "Add More Items…">
<!ENTITY customizeMenu.addMoreItems.accesskey "A">
<!ENTITY openCmd.commandkey "l">
<!ENTITY urlbar.placeholder2 "Search or enter address">
@ -544,16 +537,8 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY newWindowButton.tooltip "Open a new window">
<!ENTITY sidebarCloseButton.tooltip "Close sidebar">
<!ENTITY cutButton.tooltip "Cut">
<!ENTITY copyButton.tooltip "Copy">
<!ENTITY pasteButton.tooltip "Paste">
<!ENTITY fullScreenButton.tooltip "Display the window in full screen">
<!ENTITY zoomOutButton.tooltip "Zoom out">
<!ENTITY zoomInButton.tooltip "Zoom in">
<!ENTITY zoomControls.label "Zoom Controls">
<!ENTITY quitApplicationCmdWin.label "Exit">
<!ENTITY quitApplicationCmdWin.accesskey "x">
<!ENTITY goBackCmd.commandKey "[">
@ -641,9 +626,6 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY syncSyncNowItem.accesskey "S">
<!ENTITY syncToolbarButton.label "Sync">
<!ENTITY addonBarCloseButton.tooltip "Close Add-on Bar">
<!ENTITY toggleAddonBarCmd.key "/">
<!ENTITY socialToolbar.title "Social Toolbar Button">
<!ENTITY social.notLoggedIn.label "Not logged in">
@ -665,6 +647,13 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY social.learnMore.accesskey "l">
<!ENTITY social.closeNotificationItem.label "Not Now">
<!ENTITY customizeMode.tabTitle "Customize &brandShortName;">
<!ENTITY customizeMode.menuAndToolbars.label "Menu and toolbars">
<!ENTITY customizeMode.menuAndToolbars.header "More Tools to Add to the Menu and Toolbar">
<!ENTITY customizeMode.restoreDefaults "Restore Defaults">
<!ENTITY social.chatBar.commandkey "c">
<!ENTITY social.chatBar.label "Focus chats">
<!ENTITY social.chatBar.accesskey "c">

View File

@ -0,0 +1,69 @@
# 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/.
history-panelmenu.label = History
# LOCALIZATION NOTE (history-panelmenu.tooltiptext): Use the unicode ellipsis char,
# \u2026, or use "..." if \u2026 doesn't suit traditions in your locale.
history-panelmenu.tooltiptext = History…
# LOCALIZATION NOTE (privatebrowsing-button.label): Use the unicode ellipsis char,
# \u2026, or use "..." if \u2026 doesn't suit traditions in your locale.
privatebrowsing-button.label = Private Browsing…
privatebrowsing-button.tooltiptext = Open a new Private Browsing window
save-page-button.label = Save Page
save-page-button.tooltiptext = Save this page
save-page-button.shortcut = Ctrl+S
find-button.label = Find
find-button.tooltiptext = Find in this page
find-button.shortcut = Ctrl+F
open-file-button.label = Open File
open-file-button.tooltiptext = Open file
open-file-button.shortcut = Ctrl+O
developer-button.label = Developer
developer-button.tooltiptext = Toggle Developer Tools
developer-button.shortcut = Shift+F11
add-ons-button.label = Add-ons
add-ons-button.tooltiptext = Add-ons Manager
add-ons-button.shortcut = Ctrl+Shift+A
preferences-button.label = Preferences
# LOCALIZATION NOTE (preferences-button.tooltiptext): Use the unicode ellipsis char,
# \u2026, or use "..." if \u2026 doesn't suit traditions in your locale.
preferences-button.tooltiptext = Preferences…
preferences-button.shortcut = Ctrl+Shift+O
zoom-controls.label = Zoom Controls
zoom-controls.tooltiptext = Zoom Controls
zoom-out-button.label = Zoom out
zoom-out-button.tooltiptext = Zoom out
# LOCALIZATION NOTE(zoom-reset-button.label): %S is the current zoom level,
# %% will be displayed as a single % character (% is commonly used to define
# format specifiers, so it needs to be escaped).
zoom-reset-button.label = %S%%
zoom-reset-button.tooltiptext = Reset zoom level
zoom-in-button.label = Zoom in
zoom-in-button.tooltiptext = Zoom in
edit-controls.label = Edit Controls
edit-controls.tooltiptext = Edit Controls
cut-button.label = Cut
cut-button.tooltiptext = Cut
copy-button.label = Copy
copy-button.tooltiptext = Copy
paste-button.label = Paste
paste-button.tooltiptext = Paste
feed-button.label = Subscribe
feed-button.tooltiptext = Subscribe to this page…

View File

@ -22,6 +22,7 @@
locale/browser/browser.dtd (%chrome/browser/browser.dtd)
locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd)
locale/browser/browser.properties (%chrome/browser/browser.properties)
locale/browser/customizableui/customizableWidgets.properties (%chrome/browser/customizableui/customizableWidgets.properties)
locale/browser/devtools/appcacheutils.properties (%chrome/browser/devtools/appcacheutils.properties)
locale/browser/devtools/debugger.dtd (%chrome/browser/devtools/debugger.dtd)
locale/browser/devtools/debugger.properties (%chrome/browser/devtools/debugger.properties)

View File

@ -47,45 +47,6 @@ this.webappsUI = {
}
},
openURL: function(aUrl, aOrigin) {
let browserEnumerator = Services.wm.getEnumerator("navigator:browser");
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
// Check each browser instance for our URL
let found = false;
while (!found && browserEnumerator.hasMoreElements()) {
let browserWin = browserEnumerator.getNext();
let tabbrowser = browserWin.gBrowser;
// Check each tab of this browser instance
let numTabs = tabbrowser.tabs.length;
for (let index = 0; index < numTabs; index++) {
let tab = tabbrowser.tabs[index];
let appURL = ss.getTabValue(tab, "appOrigin");
if (appURL == aOrigin) {
// The URL is already opened. Select this tab.
tabbrowser.selectedTab = tab;
browserWin.focus();
found = true;
break;
}
}
}
// Our URL isn't open. Open it now.
if (!found) {
let recentWindow = Services.wm.getMostRecentWindow("navigator:browser");
if (recentWindow) {
// Use an existing browser window
let browser = recentWindow.gBrowser;
let tab = browser.addTab(aUrl);
browser.pinTab(tab);
browser.selectedTab = tab;
ss.setTabValue(tab, "appOrigin", aOrigin);
}
}
},
_getBrowserForId: function(aId) {
let content = Services.wm.getOuterWindowWithId(aId);
if (content) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

View File

@ -0,0 +1,29 @@
/* 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/. */
%include linuxShared.inc
%filter substitution
/*
* LightweightThemeListener will append the current lightweight theme's header
* image to the background-image for each of the following rulesets.
*/
/* Lightweight theme on tabs */
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-start[selected=true]:-moz-lwtheme::before,
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-end[selected=true]:-moz-lwtheme::before {
background-attachment: scroll, fixed;
background-color: transparent;
background-image: @fgTabTextureLWT@;/*, lwtHeader;*/
background-position: 0 0, right top;
}
#tabbrowser-tabs:not([movingtab]) > .tabbrowser-tab > .tab-stack > .tab-background > .tab-background-middle[selected=true]:-moz-lwtheme {
background-attachment: scroll, scroll, fixed;
background-color: transparent;
background-image: url(chrome://browser/skin/tabbrowser/tab-active-middle.png),
@fgTabTextureLWT@;/*,
lwtHeader;*/
background-position: 0 0, 0 0, right top;
}

View File

@ -10,14 +10,12 @@
@namespace html url("http://www.w3.org/1999/xhtml");
%include ../shared/browser.inc
%include linuxShared.inc
%filter substitution
%define toolbarHighlight rgba(255,255,255,.3)
%define selectedTabHighlight rgba(255,255,255,.8) 1px, rgba(255,255,255,.5) 3px
%define forwardTransitionLength 150ms
%define conditionalForwardWithUrlbar window:not([chromehidden~=toolbar]) :-moz-any(#nav-bar[currentset*="unified-back-forward-button,urlbar-container"][mode=icons], #nav-bar:not([currentset])[mode=icons]) > #unified-back-forward-button
%define conditionalForwardWithUrlbar_small window:not([chromehidden~=toolbar]) :-moz-any(#nav-bar[currentset*="unified-back-forward-button,urlbar-container"][mode=icons][iconsize=small],#nav-bar:not([currentset])[mode=icons][iconsize=small]) > #unified-back-forward-button
%define conditionalForwardWithUrlbar window:not([chromehidden~=toolbar]) :-moz-any(#nav-bar[currentset*="unified-back-forward-button,urlbar-container"], #nav-bar:not([currentset])) > #nav-bar-customizationtarget > #unified-back-forward-button
%define conditionalForwardWithUrlbarWidth 32
%define conditionalForwardWithUrlbarWidth_small 24
#menubar-items {
-moz-box-orient: vertical; /* for flex hack */
@ -31,14 +29,10 @@
-moz-appearance: none;
background-color: transparent;
border-top: none;
}
#main-window:not([disablechrome]) #navigator-toolbox[tabsontop=true] {
border-bottom: 1px solid ThreeDShadow;
}
#navigator-toolbox[tabsontop=true] > toolbar:not(:-moz-lwtheme):not(#toolbar-menubar):not(#TabsToolbar),
#navigator-toolbox[tabsontop=false] > toolbar:not(:-moz-lwtheme):not(#toolbar-menubar) {
#navigator-toolbox > toolbar:not(:-moz-lwtheme):not(#toolbar-menubar):not(#TabsToolbar) {
-moz-appearance: none;
border-style: none;
background-color: -moz-Dialog;
@ -49,13 +43,31 @@
padding-bottom: 1px;
}
#nav-bar:not(:-moz-lwtheme),
#nav-bar[collapsed=true] + toolbar:not(:-moz-lwtheme),
#nav-bar[collapsed=true] + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
#nav-bar[tabsontop=true],
#nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + toolbar,
#nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar {
#nav-bar,
#nav-bar[collapsed=true] + toolbar,
#nav-bar[collapsed=true] + #customToolbars + #PersonalToolbar {
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
margin-top: -1px; /* Move up 1px into the TabsToolbar */
/* Position the toolbar above the bottom of background tabs */
position: relative;
z-index: 1;
}
#nav-bar-overflow-button {
-moz-image-region: rect(-5px, 12px, 11px, -4px);
}
#widget-overflow-list > .overflowedItem {
width: 100%;
min-height: 36px;
background-repeat: no-repeat;
background-position: 0 center;
}
#widget-overflow-list > .overflowedItem > .toolbarbutton-text {
-moz-padding-start: 10px;
text-align: start;
}
#personal-bookmarks {
@ -96,7 +108,7 @@ toolbarbutton.bookmark-item[open="true"] {
}
/* Prevent [mode="icons"] from hiding the label */
/* Force the display of the label for bookmarks */
.bookmark-item > .toolbarbutton-text {
display: -moz-box !important;
}
@ -218,7 +230,6 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
#appmenu_newNavigator,
#placesContext_open\:newwindow,
#menu_newNavigator,
#context-openlink,
@ -227,8 +238,6 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
-moz-image-region: rect(0px 80px 16px 64px);
}
#appmenu_newTab,
#appmenu_newTab_popup,
#placesContext_open\:newtab,
#placesContext_openContainer\:tabs,
#menu_newNavigatorTab,
@ -238,7 +247,6 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
-moz-image-region: rect(0px 64px 16px 48px);
}
#appmenu_openFile,
#menu_openFile {
list-style-image: url("moz-icon://stock/gtk-open?size=menu");
}
@ -255,7 +263,6 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-media-pause?size=menu");
}
#appmenu_savePage,
#menu_savePage,
#context-savelink,
#context-saveimage,
@ -266,19 +273,15 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-save-as?size=menu");
}
#appmenu_printPreview,
#menu_printPreview {
list-style-image: url("moz-icon://stock/gtk-print-preview?size=menu");
}
#appmenu_print,
#appmenu_print_popup,
#menu_print,
#context-printframe {
list-style-image: url("moz-icon://stock/gtk-print?size=menu");
}
#appmenu-quit,
#menu_FileQuitItem {
list-style-image: url("moz-icon://stock/gtk-quit?size=menu");
}
@ -361,7 +364,6 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-select-all?size=menu");
}
#appmenu_find,
#menu_find {
list-style-image: url("moz-icon://stock/gtk-find?size=menu");
}
@ -370,8 +372,6 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-find?size=menu&state=disabled");
}
#appmenu_customize,
#appmenu_preferences,
#menu_preferences {
list-style-image: url("moz-icon://stock/gtk-preferences?size=menu");
}
@ -454,15 +454,11 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-home?size=menu");
}
#appmenu_history,
#appmenu_showAllHistory,
#menu_showAllHistory {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 32px 16px 16px);
}
#appmenu_bookmarks,
#appmenu_showAllBookmarks,
#bookmarksShowAll {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 48px 16px 32px);
@ -480,21 +476,15 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
}
#BMB_bookmarkThisPage {
list-style-image: url("chrome://browser/skin/places/starPage.png");
}
#BMB_unsortedBookmarks {
list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
}
#appmenu_downloads,
#menu_openDownloads {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
#appmenu_addons,
#menu_openAddons {
list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
}
@ -505,8 +495,6 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-info?size=menu");
}
#appmenu_privateBrowsing,
#appmenu_newPrivateWindow,
#privateBrowsingItem {
list-style-image: url("chrome://browser/skin/Privacy-16.png");
}
@ -515,18 +503,14 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-properties?size=menu");
}
#appmenu_sanitizeHistory,
#sanitizeItem {
list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
}
#appmenu_help,
#appmenu_openHelp,
#menu_openHelp {
list-style-image: url("moz-icon://stock/gtk-help?size=menu");
}
#appmenu_about,
#aboutName {
list-style-image: url("moz-icon://stock/gtk-about?size=menu");
}
@ -546,11 +530,6 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
-moz-margin-end: 0;
}
toolbar[mode="full"] .toolbarbutton-1:not([type="menu-button"]),
toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
min-width: 57px;
}
.toolbarbutton-1:not([type="menu-button"]),
.toolbarbutton-1 > .toolbarbutton-menubutton-button {
padding: 5px;
@ -561,6 +540,10 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
}
/* 24px primary toolbar buttons */
#PanelUI-menu-button {
list-style-image: url("chrome://browser/skin/appmenu.png");
}
#back-button {
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar");
}
@ -654,27 +637,19 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
-moz-image-region: rect(0px 24px 24px 0px);
}
#history-button {
toolbar > .customization-target > #history-panelmenu,
toolbar > .customization-target > toolbarpaletteitem > #history-panelmenu {
-moz-image-region: rect(0px 48px 24px 24px);
}
#bookmarks-button,
#bookmarks-menu-button {
#bookmarks-button {
-moz-image-region: rect(0px 72px 24px 48px);
}
#bookmarks-menu-button.bookmark-item {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
}
#bookmarks-menu-button.toolbarbutton-1 {
-moz-box-orient: horizontal;
}
#print-button {
list-style-image: url("moz-icon://stock/gtk-print?size=toolbar");
}
#print-button[disabled="true"] {
:not(toolbarpaletteitem) > #print-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-print?size=toolbar&state=disabled");
}
@ -687,38 +662,38 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
}
#cut-button {
list-style-image: url("moz-icon://stock/gtk-cut?size=toolbar");
list-style-image: url("moz-icon://stock/gtk-cut?size=toolbar") !important;
}
#cut-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-cut?size=toolbar&state=disabled");
:not(toolbarpaletteitem) > #edit-controls > #cut-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-cut?size=toolbar&state=disabled") !important;
}
#copy-button {
list-style-image: url("moz-icon://stock/gtk-copy?size=toolbar");
list-style-image: url("moz-icon://stock/gtk-copy?size=toolbar") !important;
}
#copy-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-copy?size=toolbar&state=disabled");
:not(toolbarpaletteitem) > #edit-controls > #copy-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-copy?size=toolbar&state=disabled") !important;
}
#paste-button {
list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar");
list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar") !important;
}
#paste-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar&state=disabled");
:not(toolbarpaletteitem) > #edit-controls > #paste-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar&state=disabled") !important;
}
#zoom-out-button {
list-style-image: url("moz-icon://stock/gtk-zoom-out?size=toolbar") !important;
}
#zoom-in-button {
list-style-image: url("moz-icon://stock/gtk-zoom-in?size=toolbar") !important;
}
#fullscreen-button {
list-style-image: url("moz-icon://stock/gtk-fullscreen?size=toolbar");
}
#zoom-out-button {
list-style-image: url("moz-icon://stock/gtk-zoom-out?size=toolbar");
}
#zoom-in-button {
list-style-image: url("moz-icon://stock/gtk-zoom-in?size=toolbar");
}
#sync-button {
-moz-image-region: rect(0px 144px 24px 120px);
}
@ -731,7 +706,7 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
-moz-image-region: rect(0px 168px 24px 144px);
}
#feed-button[disabled] > .toolbarbutton-icon {
:not(toolbarpaletteitem) > #feed-button[disabled] > .toolbarbutton-icon {
opacity: .4;
}
@ -739,160 +714,28 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
-moz-image-region: rect(0px 192px 24px 168px);
}
/* 16px primary toolbar buttons */
toolbar[iconsize="small"] .toolbarbutton-1:not([type="menu-button"]) {
-moz-box-orient: vertical;
min-width: 0;
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
}
toolbar[iconsize="small"] .toolbarbutton-1[type="menu-button"] {
border: 0 !important;
}
toolbar[iconsize="small"] #back-button {
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu");
}
.unified-nav-back[_moz-menuactive] {
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu") !important;
}
toolbar[iconsize="small"] #back-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu&state=disabled");
}
toolbar[iconsize="small"] #back-button:-moz-locale-dir(rtl) {
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu");
}
.unified-nav-back[_moz-menuactive]:-moz-locale-dir(rtl) {
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu") !important;
}
toolbar[iconsize="small"] #back-button[disabled="true"]:-moz-locale-dir(rtl) {
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu&state=disabled");
}
toolbar[iconsize=small] #forward-button,
@conditionalForwardWithUrlbar_small@ > #forward-button {
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu");
}
.unified-nav-forward[_moz-menuactive] {
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu") !important;
}
toolbar[iconsize=small] #forward-button[disabled] {
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu&state=disabled");
}
toolbar[iconsize=small] #forward-button:-moz-locale-dir(rtl),
@conditionalForwardWithUrlbar_small@ > #forward-button:-moz-locale-dir(rtl) {
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu");
}
.unified-nav-forward[_moz-menuactive]:-moz-locale-dir(rtl) {
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu") !important;
}
toolbar[iconsize=small] #forward-button[disabled]:-moz-locale-dir(rtl) {
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu&state=disabled");
}
toolbar[iconsize="small"] #stop-button {
list-style-image: url("moz-icon://stock/gtk-stop?size=menu");
}
toolbar[iconsize="small"] #stop-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-stop?size=menu&state=disabled");
}
toolbar[iconsize="small"] #reload-button {
list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
}
toolbar[iconsize="small"] #reload-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-refresh?size=menu&state=disabled");
}
toolbar[iconsize="small"] #home-button,
#home-button.bookmark-item {
list-style-image: url("moz-icon://stock/gtk-home?size=menu");
}
toolbar[iconsize="small"] #home-button[disabled="true"],
#home-button.bookmark-item[disabled="true"] {
:not(toolbarpaletteitem) > #home-button.bookmark-item[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-home?size=menu&state=disabled");
}
toolbar[iconsize="small"] #downloads-button {
-moz-image-region: rect(0px 16px 16px 0px);
}
/* Menu panel buttons */
toolbar[iconsize="small"] #webrtc-status-button /* temporary placeholder (bug 824825) */,
toolbar[iconsize="small"] #history-button {
-moz-image-region: rect(0px 32px 16px 16px);
}
toolbar[iconsize="small"] #bookmarks-button,
toolbar[iconsize="small"] #bookmarks-menu-button,
#bookmarks-menu-button.bookmark-item {
-moz-image-region: rect(0px 48px 16px 32px);
}
toolbar[iconsize="small"] #print-button {
list-style-image: url("moz-icon://stock/gtk-print?size=menu");
}
toolbar[iconsize="small"] #print-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-print?size=menu&state=disabled");
}
toolbar[iconsize="small"] #new-tab-button {
-moz-image-region: rect(0px 64px 16px 48px);
}
toolbar[iconsize="small"] #new-window-button {
-moz-image-region: rect(0px 80px 16px 64px);
}
toolbar[iconsize="small"] #cut-button {
list-style-image: url("moz-icon://stock/gtk-cut?size=menu");
}
toolbar[iconsize="small"] #cut-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-cut?size=menu&state=disabled");
}
toolbar[iconsize="small"] #copy-button {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
}
toolbar[iconsize="small"] #copy-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu&state=disabled");
}
toolbar[iconsize="small"] #paste-button {
list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
}
toolbar[iconsize="small"] #paste-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-paste?size=menu&state=disabled");
}
toolbar[iconsize="small"] #fullscreen-button {
list-style-image: url("moz-icon://stock/gtk-fullscreen?size=menu");
}
toolbar[iconsize="small"] #zoom-out-button {
list-style-image: url("moz-icon://stock/gtk-zoom-out?size=menu");
}
toolbar[iconsize="small"] #zoom-in-button {
list-style-image: url("moz-icon://stock/gtk-zoom-in?size=menu");
}
toolbar[iconsize="small"] #sync-button {
-moz-image-region: rect(0px 96px 16px 80px);
}
toolbar[iconsize="small"] #sync-button[status="active"] {
list-style-image: url("chrome://browser/skin/sync-16-throbber.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
toolbar[iconsize="small"] #feed-button {
-moz-image-region: rect(0px 112px 16px 96px);
}
toolbar[iconsize="small"] #webrtc-status-button {
-moz-image-region: rect(0px 128px 16px 112px);
}
%include ../shared/menupanel.inc
/* Fullscreen window controls */
#window-controls {
@ -943,11 +786,6 @@ toolbar[iconsize="small"] #webrtc-status-button {
pointer-events: none;
}
@conditionalForwardWithUrlbar_small@ + #urlbar-container {
-moz-padding-start: @conditionalForwardWithUrlbarWidth_small@px;
-moz-margin-start: -@conditionalForwardWithUrlbarWidth_small@px;
}
@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar {
pointer-events: all;
}
@ -963,12 +801,6 @@ toolbar[iconsize="small"] #webrtc-status-button {
@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container > #urlbar:-moz-locale-dir(rtl) {
margin-right: -@conditionalForwardWithUrlbarWidth@px;
}
@conditionalForwardWithUrlbar_small@[forwarddisabled] + #urlbar-container > #urlbar:-moz-locale-dir(ltr) {
margin-left: -@conditionalForwardWithUrlbarWidth_small@px;
}
@conditionalForwardWithUrlbar_small@[forwarddisabled] + #urlbar-container > #urlbar:-moz-locale-dir(rtl) {
margin-right: -@conditionalForwardWithUrlbarWidth_small@px;
}
#urlbar-icons {
-moz-box-align: center;
@ -1515,22 +1347,33 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
-moz-image-region: rect(0, 16px, 16px, 0);
}
/* Star button */
#star-button {
list-style-image: url("chrome://browser/skin/places/starPage.png");
}
#star-button[starred="true"] {
list-style-image: url("chrome://browser/skin/places/pageStarred.png");
}
/* bookmarks menu-button */
#bookmarks-menu-button[disabled] > .toolbarbutton-icon,
#bookmarks-menu-button[disabled] > .toolbarbutton-menu-dropmarker,
#bookmarks-menu-button[disabled] > .toolbarbutton-menubutton-dropmarker,
#bookmarks-menu-button[disabled] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
#bookmarks-menu-button > .toolbarbutton-menubutton-button[disabled] > .toolbarbutton-icon {
#bookmarks-menu-button {
list-style-image: url("chrome://browser/skin/Toolbar.png");
-moz-image-region: rect(0px 216px 24px 192px);
}
#bookmarks-menu-button[starred] {
-moz-image-region: rect(24px 216px 48px 192px);
}
toolbar[iconsize="small"] #bookmarks-menu-button,
#bookmarks-menu-button.bookmark-item {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 144px 16px 128px);
}
toolbar[iconsize="small"] #bookmarks-menu-button[starred],
#bookmarks-menu-button.bookmark-item[starred] {
-moz-image-region: rect(16px 144px 32px 128px);
}
:not(toolbarpaletteitem) > #bookmarks-menu-button[disabled] > .toolbarbutton-icon,
:not(toolbarpaletteitem) > #bookmarks-menu-button[disabled] > .toolbarbutton-menu-dropmarker,
:not(toolbarpaletteitem) > #bookmarks-menu-button[disabled] > .toolbarbutton-menubutton-dropmarker,
:not(toolbarpaletteitem) > #bookmarks-menu-button[disabled] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
:not(toolbarpaletteitem) > #bookmarks-menu-button > .toolbarbutton-menubutton-button[disabled] > .toolbarbutton-icon {
opacity: .4;
}
@ -1588,143 +1431,56 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
background-color: Window;
}
/* Throbber */
#navigator-throbber {
width: 16px;
min-height: 16px;
margin: 0 3px;
}
#navigator-throbber[busy="true"] {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
#navigator-throbber,
#wrapper-navigator-throbber > #navigator-throbber {
list-style-image: url("chrome://global/skin/icons/notloading_16.png");
}
/* Tabstrip */
%include ../shared/tabs.inc.css
#tabbrowser-tabs {
/* override the global style to allow the selected tab to be above the nav-bar */
z-index: auto;
}
#TabsToolbar {
min-height: 0;
padding: 0;
position: relative;
}
#TabsToolbar[tabsontop=true]:not(:-moz-lwtheme) {
/*
* Draw the bottom border of the tabstrip:
*/
#TabsToolbar::after {
content: "";
position: absolute;
bottom: 1px;
left: 0;
right: 0;
z-index: 0;
border-bottom: 1px solid hsla(0,0%,0%,.3);
}
#TabsToolbar:not(:-moz-lwtheme) {
-moz-appearance: menubar;
color: -moz-menubartext;
box-shadow: 0 -1px 0 rgba(0,0,0,.1) inset;
}
#TabsToolbar[tabsontop=true]:not(:-moz-lwtheme):-moz-system-metric(menubar-drag) {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
#toolbar-menubar:not([autohide="true"]):not(:-moz-lwtheme):-moz-system-metric(menubar-drag),
#TabsToolbar:not(:-moz-lwtheme):-moz-system-metric(menubar-drag) {
-moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#toolbar-drag");
}
#TabsToolbar[tabsontop=false] {
background-image: linear-gradient(to top, rgba(0,0,0,.3) 1px, rgba(0,0,0,.05) 1px, transparent 50%);
#TabsToolbar:not(:-moz-lwtheme) > #tabbrowser-tabs > .tabbrowser-tab:not([selected]) {
color: -moz-menubartext;
}
.tabbrowser-tab,
.tabs-newtab-button {
position: static;
-moz-appearance: none;
background: linear-gradient(hsla(0,0%,100%,.2), hsla(0,0%,45%,.2) 2px, hsla(0,0%,32%,.2) 80%);
background-origin: border-box;
background-position: 1px 2px;
background-size: 100% calc(100% - 2px);
background-repeat: no-repeat;
color: inherit;
margin: 0;
padding: 0;
border-width: 4px 5px 3px 6px;
border-style: solid;
border-image: url(tabbrowser/tab.png) 4 5 3 6 fill repeat stretch;
border-radius: 10px 8px 0 0;
min-height: 25px; /* reserve space for the sometimes hidden close button */
}
.tabbrowser-tab:hover,
.tabs-newtab-button:hover {
background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.2) 4px, hsla(0,0%,75%,.2) 80%);
}
.tabbrowser-tab[selected="true"] {
background-image: linear-gradient(@selectedTabHighlight@, @toolbarHighlight@ 32%),
linear-gradient(-moz-dialog, -moz-dialog);
color: -moz-dialogtext;
}
#main-window[tabsontop=false]:not([disablechrome]) .tabbrowser-tab[selected=true]:not(:-moz-lwtheme) {
background-image: linear-gradient(to top, rgba(0,0,0,.3) 1px, transparent 1px),
linear-gradient(@selectedTabHighlight@, @toolbarHighlight@ 32%),
linear-gradient(-moz-dialog, -moz-dialog);
}
.tabbrowser-tab[selected="true"]:-moz-lwtheme {
background-image: linear-gradient(@selectedTabHighlight@, @toolbarHighlight@ 32%);
.tabbrowser-tab:-moz-lwtheme {
color: inherit;
}
.tabbrowser-tab:-moz-lwtheme-brighttext:not([selected="true"]),
.tabs-newtab-button:-moz-lwtheme-brighttext {
background-image: linear-gradient(hsla(0,0%,60%,.6), hsla(0,0%,40%,.6) 4px, hsla(0,0%,30%,.6) 80%);
}
.tabbrowser-tab:-moz-lwtheme-brighttext:not([selected="true"]):hover,
.tabs-newtab-button:-moz-lwtheme-brighttext:hover {
background-image: linear-gradient(hsla(0,0%,80%,.6), hsla(0,0%,60%,.6) 4px, hsla(0,0%,45%,.6) 80%);
}
.tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]),
.tabs-newtab-button:-moz-lwtheme-darktext {
background-image: linear-gradient(hsla(0,0%,100%,.5), hsla(0,0%,60%,.5) 4px, hsla(0,0%,45%,.5) 80%);
}
.tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]):hover,
.tabs-newtab-button:-moz-lwtheme-darktext:hover {
background-image: linear-gradient(hsla(0,0%,100%,.5), hsla(0,0%,80%,.5) 4px, hsla(0,0%,60%,.5) 80%);
}
.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]) {
background-image: radial-gradient(circle farthest-corner at 50% 3px, rgba(233,242,252,1) 3%, rgba(172,206,255,.75) 40%, rgba(87,151,201,.5) 80%, rgba(87,151,201,0));
}
.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]):hover {
background-image: linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.6) 2px, hsla(0,0%,75%,.2) 80%),
radial-gradient(circle farthest-corner at 50% 3px, rgba(233,242,252,1) 3%, rgba(172,206,255,.75) 40%, rgba(87,151,201,.5) 80%, rgba(87,151,201,0));
}
#tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab > .tab-stack > .tab-content[pinned] {
min-height: 18px; /* corresponds to the max. height of non-textual tab contents, i.e. the tab close button */
}
.tabbrowser-tab:focus > .tab-stack {
.tabbrowser-tab:focus > .tab-stack > .tab-content > .tab-label {
outline: 1px dotted;
}
.tab-throbber,
.tab-icon-image {
width: 16px;
height: 16px;
-moz-margin-end: 3px;
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
}
.tab-throbber {
list-style-image: url("chrome://browser/skin/tabbrowser/connecting.png");
}
.tab-throbber[progress] {
list-style-image: url("chrome://browser/skin/tabbrowser/loading.png");
}
.tab-throbber[pinned],
.tab-icon-image[pinned],
.tabs-newtab-button > .toolbarbutton-icon {
-moz-margin-start: 2px;
-moz-margin-end: 2px;
}
#context_reloadTab {
list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
}
@ -1748,7 +1504,8 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
/* Tab drag and drop */
.tab-drop-indicator {
list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
margin-bottom: -11px;
margin-bottom: -9px;
z-index: 3;
}
/* In-tab close button */
@ -1759,11 +1516,10 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
}
.tab-close-button {
padding: 0;
list-style-image: url("moz-icon://stock/gtk-close?size=menu");
margin-top: -1px;
margin-top: 0;
margin-bottom: -1px;
-moz-margin-end: -1px;
-moz-margin-end: -4px;
}
/* Tabstrip new tab button */
@ -1884,10 +1640,6 @@ toolbarbutton.chevron > .toolbarbutton-icon {
margin: 0;
}
toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
display: -moz-box; /* display chevron icon in text mode */
}
/* Ctrl-Tab */
.ctrlTab-preview {
@ -1925,80 +1677,6 @@ toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
margin-top: 10px;
}
/* Application button menu */
.splitmenu-menuitem {
-moz-margin-end: 1px;
}
#appmenu-toolbar-button:not(:hover):not([open]):not(:-moz-lwtheme) {
color: inherit;
}
#appmenu-toolbar-button > .toolbarbutton-text,
#appmenu-toolbar-button > .toolbarbutton-menu-dropmarker {
margin-top: -2px !important;
margin-bottom: -2px !important;
}
#appmenuSecondaryPane {
-moz-border-start: 1px solid ThreeDShadow;
}
#appmenuSecondaryPane-spacer {
min-height: 1em;
}
#appmenu-cut,
#appmenu-editmenu-cut {
list-style-image: url("moz-icon://stock/gtk-cut?size=menu");
}
#appmenu-copy,
#appmenu-editmenu-copy {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
}
#appmenu-paste,
#appmenu-editmenu-paste {
list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
}
#wrapper-appmenu-toolbar-button,
.appmenu-edit-button[disabled="true"] {
opacity: .3;
}
/* Add-on bar */
#addon-bar {
box-shadow: 0 1px 0 rgba(0,0,0,.15) inset;
padding: 0;
min-height: 20px;
}
#status-bar {
min-height: 0;
-moz-appearance: none;
background-color: transparent;
border: none;
}
#addon-bar[customizing] > #status-bar {
opacity: .5;
background-image: repeating-linear-gradient(135deg,
rgba(255,255,255,.3), rgba(255,255,255,.3) 5px,
rgba(0,0,0,.3) 5px, rgba(0,0,0,.3) 10px);
}
#status-bar > statusbarpanel {
border-width: 0;
-moz-appearance: none;
}
#addonbar-closebutton {
list-style-image: url("moz-icon://stock/gtk-close?size=menu");
}
#addonbar-closebutton > .toolbarbutton-icon {
margin-top: -2px;
margin-bottom: -2px;
}
/* Status panel */
.statuspanel-label {
@ -2196,6 +1874,46 @@ chatbox {
border-top-right-radius: 2.5px;
}
/* Customization mode */
%include ../shared/customizableui/customizeMode.inc.css
#main-window[customizing] #tab-view-deck {
background-image: url("chrome://browser/skin/customizableui/customizeMode-gridTexture.png"),
url("chrome://browser/skin/customizableui/background-noise-toolbar.png"),
linear-gradient(to bottom, #bcbcbc, #b5b5b5);
background-attachment: fixed;
}
#main-window[customizing] #tab-view-deck {
padding: 2em;
}
#main-window[customizing] #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar),
#main-window[customizing] #customization-container {
border: 3px solid hsla(0,0%,0%,.1);
border-top-width: 0;
background-clip: padding-box;
background-origin: padding-box;
-moz-border-right-colors: hsla(0,0%,0%,.05) hsla(0,0%,0%,.1) hsla(0,0%,0%,.2);
-moz-border-bottom-colors: hsla(0,0%,0%,.05) hsla(0,0%,0%,.1) hsla(0,0%,0%,.2);
-moz-border-left-colors: hsla(0,0%,0%,.05) hsla(0,0%,0%,.1) hsla(0,0%,0%,.2);
}
#main-window[customizing] #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
border-bottom-width: 0;
}
#main-window[customizing] #TabsToolbar {
-moz-appearance: none;
background-clip: padding-box;
border-right: 3px solid transparent;
border-left: 3px solid transparent;
}
/* End customization mode */
#main-window[privatebrowsingmode=temporary] #TabsToolbar::before {
display: -moz-box;
content: "";

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,8 @@
/* 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/. */
%filter substitution
%define menuPanelWidth 23em
%include ../../shared/customizableui/panelUIOverlay.inc.css

View File

@ -19,8 +19,14 @@ browser.jar:
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/actionicon-tab.png
skin/classic/browser/appmenu.png
* skin/classic/browser/browser.css
* skin/classic/browser/browser-lightweightTheme.css
skin/classic/browser/click-to-play-warning-stripes.png
skin/classic/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/browser/customizableui/customizeMode-gridTexture.png (customizableui/customizeMode-gridTexture.png)
skin/classic/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
* skin/classic/browser/engineManager.css
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
@ -31,6 +37,8 @@ browser.jar:
skin/classic/browser/identity-icons-https-ev.png
skin/classic/browser/identity-icons-https-mixed-active.png
skin/classic/browser/Info.png
skin/classic/browser/menuPanel.png
skin/classic/browser/menuPanel-small.png
skin/classic/browser/mixed-content-blocked-16.png
skin/classic/browser/mixed-content-blocked-64.png
skin/classic/browser/monitor.png
@ -58,6 +66,7 @@ browser.jar:
skin/classic/browser/webRTC-shareDevice-16.png
skin/classic/browser/webRTC-shareDevice-64.png
skin/classic/browser/webRTC-sharingDevice-16.png
* skin/classic/browser/customizableui/panelUIOverlay.css (customizableui/panelUIOverlay.css)
skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
skin/classic/browser/downloads/contentAreaDownloadsView.css (downloads/contentAreaDownloadsView.css)
@ -84,7 +93,6 @@ browser.jar:
skin/classic/browser/places/calendar.png (places/calendar.png)
* skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
skin/classic/browser/places/livemark-item.png (places/livemark-item.png)
skin/classic/browser/places/pageStarred.png (places/pageStarred.png)
skin/classic/browser/places/star-icons.png (places/star-icons.png)
skin/classic/browser/places/starred48.png (places/starred48.png)
skin/classic/browser/places/unstarred48.png (places/unstarred48.png)
@ -92,7 +100,6 @@ browser.jar:
skin/classic/browser/places/organizer.css (places/organizer.css)
skin/classic/browser/places/organizer.xml (places/organizer.xml)
skin/classic/browser/places/query.png (places/query.png)
skin/classic/browser/places/starPage.png (places/starPage.png)
skin/classic/browser/places/tag.png (places/tag.png)
skin/classic/browser/places/toolbarDropMarker.png (places/toolbarDropMarker.png)
skin/classic/browser/places/unsortedBookmarks.png (places/unsortedBookmarks.png)
@ -115,8 +122,15 @@ browser.jar:
skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png)
skin/classic/browser/tabbrowser/tab.png (tabbrowser/tab.png)
skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
skin/classic/browser/tabbrowser/tab-active-middle.png (tabbrowser/tab-active-middle.png)
skin/classic/browser/tabbrowser/tab-background-end.png (tabbrowser/tab-background-end.png)
skin/classic/browser/tabbrowser/tab-background-middle.png (tabbrowser/tab-background-middle.png)
skin/classic/browser/tabbrowser/tab-background-start.png (tabbrowser/tab-background-start.png)
skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
skin/classic/browser/tabbrowser/tab-stroke-end.png (tabbrowser/tab-stroke-end.png)
skin/classic/browser/tabbrowser/tab-stroke-start.png (tabbrowser/tab-stroke-start.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
skin/classic/browser/tabbrowser/tab-separator.png (tabbrowser/tab-separator.png)
skin/classic/browser/tabview/edit-light.png (tabview/edit-light.png)
skin/classic/browser/tabview/search.png (tabview/search.png)
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)

View File

@ -0,0 +1,10 @@
/* 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/. */
%filter substitution
%define toolbarHighlight rgba(255,255,255,.3)
%define fgTabTexture linear-gradient(transparent 0px, transparent 2px, hsla(0,0%,100%,0.35) 2px, hsla(0,0%,100%,0.35) 3px, hsla(0,0%,100%,0.65) 3px, hsla(0,0%,100%,0.65) 4px, @toolbarHighlight@)
%define fgTabTextureLWT @fgTabTexture@
%define fgTabBackgroundMiddle linear-gradient(transparent 0px, transparent 2px, -moz-dialog 2px, -moz-dialog)

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 767 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Some files were not shown because too many files have changed in this diff Show More