Merge mozilla-central and ux-central

This commit is contained in:
Gijs Kruitbosch 2013-06-08 00:09:29 +02:00
Родитель 7eb58c5052 cb36543bc9
Коммит 9068f66933
191 изменённых файлов: 8320 добавлений и 3852 удалений

Просмотреть файл

@ -417,11 +417,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:
@ -1264,3 +1263,6 @@ pref("media.webaudio.enabled", true);
// If this turns true, Moz*Gesture events are not called stopPropagation()
// before content.
pref("dom.debug.propagate_gesture_events_through_content", false);
// Enable CustomizableUI debug logging.
pref("browser.uiCustomization.debug", true);

Просмотреть файл

@ -415,3 +415,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 + ")");
},
};

Просмотреть файл

@ -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>

Просмотреть файл

@ -0,0 +1,102 @@
# -*- 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;
}
},
_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();
TabsInTitlebar.allowedBy("customizing-toolbars", false);
},
_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();
}
TabsInTitlebar.allowedBy("customizing-toolbars", true);
// 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();
}
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
@ -571,11 +571,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);

Просмотреть файл

@ -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

Просмотреть файл

@ -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;"

Просмотреть файл

@ -994,8 +994,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 +1006,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 +1030,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 +1101,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 +1147,8 @@ let BookmarkingUI = {
customizeDone: function BUI_customizeDone() {
delete this._button;
delete this._star;
delete this._anchor;
this.onToolbarVisibilityChange();
this._updateToolbarStyle();
},
@ -1162,7 +1168,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 +1217,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 +1244,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 +1258,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 +1272,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

Просмотреть файл

@ -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()"/>

Просмотреть файл

@ -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);
},
// ----------

Просмотреть файл

@ -13,6 +13,37 @@ 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");
}
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 +70,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 +83,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 +117,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 +141,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 +172,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 +211,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 +221,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 +314,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;
}
@ -438,14 +446,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,
@ -696,3 +696,8 @@ chatbox:-moz-full-screen-ancestor > .chat-titlebar {
*:-moz-full-screen-ancestor #social-sidebar-box:not(:-moz-full-screen-ancestor) {
display: none;
}
#customization-reset-button[hidden="true"] {
display: -moz-box;
visibility: hidden;
}

Просмотреть файл

@ -91,6 +91,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");
@ -147,6 +153,7 @@ let gInitialPages = [
];
#include browser-addons.js
#include browser-customization.js
#include browser-feeds.js
#include browser-fullScreen.js
#include browser-fullZoom.js
@ -936,13 +943,12 @@ 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();
@ -1031,7 +1037,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();
LightweightThemeListener.init();
AddonManager.addAddonListener(AddonsMgrListener);
WebrtcIndicator.init();
@ -1078,11 +1090,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 = {};
@ -1217,15 +1224,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) {
@ -1237,26 +1235,14 @@ 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);
gCustomizeMode.init();
// End startup crash tracking after a delay to catch crashes while restoring
// tabs and to postpone saving the pref to disk.
try {
@ -1315,8 +1301,6 @@ var gBrowserInit = {
BookmarkingUI.uninit();
TabsOnTop.uninit();
TabsInTitlebar.uninit();
var enumerator = Services.wm.getEnumerator(null);
@ -1369,6 +1353,9 @@ var gBrowserInit = {
IndexedDBPromptHelper.uninit();
AddonManager.removeAddonListener(AddonsMgrListener);
SocialUI.uninit();
LightweightThemeListener.uninit();
gCustomizeMode.uninit();
PanelUI.uninit();
}
// Final window teardown, do this last.
@ -2662,8 +2649,8 @@ var PrintPreviewListener = {
if (this._chromeState.sidebarOpen)
toggleSidebar(this._sidebarCommand);
#ifdef MENUBAR_CAN_AUTOHIDE
updateAppButtonDisplay();
#ifdef CAN_DRAW_IN_TITLEBAR
updateTitlebarDisplay();
#endif
},
_hideChrome: function () {
@ -2783,35 +2770,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)
{
@ -3328,119 +3286,13 @@ 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) {
@ -3504,9 +3356,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,
@ -3517,13 +3366,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.
@ -3553,9 +3396,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.
@ -3565,22 +3405,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");
}
}
}
@ -3611,8 +3439,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) ||
@ -3642,8 +3470,6 @@ var XULBrowserWindow = {
},
init: function () {
this.throbberElement = document.getElementById("navigator-throbber");
// Bug 666809 - SecurityUI support for e10s
if (gMultiProcessBrowser)
return;
@ -3657,7 +3483,6 @@ var XULBrowserWindow = {
destroy: function () {
// XXXjag to avoid leaks :-/, see bug 60729
delete this.throbberElement;
delete this.stopCommand;
delete this.reloadCommand;
delete this.statusTextField;
@ -3782,10 +3607,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();
@ -3830,10 +3651,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);
}
@ -3902,17 +3719,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;
@ -3989,12 +3795,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;
@ -4172,8 +3974,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 {
@ -4498,8 +4299,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"));
@ -4528,72 +4327,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
},
@ -4603,17 +4360,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";
},
@ -4624,16 +4387,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();
@ -4641,45 +4421,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 = "";
}
},
@ -4687,36 +4521,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
@ -6807,12 +6650,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) {
@ -6829,7 +6666,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);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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"/>

Просмотреть файл

@ -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>

Просмотреть файл

@ -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()"/>

Просмотреть файл

@ -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;

Просмотреть файл

@ -3150,10 +3150,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>
@ -3505,9 +3501,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) {
@ -3808,8 +3802,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
@ -4296,7 +4289,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>

Просмотреть файл

@ -138,9 +138,7 @@ _BROWSER_FILES = \
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 +166,12 @@ _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 +239,6 @@ _BROWSER_FILES = \
browser_visibleTabs_bookmarkAllTabs.js \
browser_visibleTabs_tabPreview.js \
bug592338.html \
disablechrome.html \
discovery.html \
domplate_test.js \
file_bug822367_1.html \

Просмотреть файл

@ -13,9 +13,8 @@ function test() {
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;
// open the toolbars menu
toolbarMenu = document.getElementById("viewToolbarsMenu").firstElementChild;
toolbarMenu.addEventListener("popupshown", onToolbarMenuShown, false);
toolbarMenu.addEventListener("popuphidden", onToolbarMenuHidden, false);
toolbarMenu.openPopup();
@ -54,9 +53,8 @@ function test() {
topMenu.hidePopup();
}
// open the appmenu or view menu
topMenu = document.getElementById("appmenu-popup") ||
document.getElementById("menu_viewPopup");
// open the view menu
topMenu = document.getElementById("menu_viewPopup");
topMenu.addEventListener("popupshown", onTopMenuShown, false);
topMenu.addEventListener("popuphidden", onTopMenuHidden, false);
topMenu.openPopup();

Просмотреть файл

@ -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");

Просмотреть файл

@ -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();
}
}

Просмотреть файл

@ -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");
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);
}

Просмотреть файл

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

Просмотреть файл

@ -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) {

Просмотреть файл

@ -925,7 +925,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>
@ -934,7 +934,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>
@ -1157,7 +1157,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>
@ -1166,7 +1166,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>
@ -1443,7 +1443,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>
@ -1494,120 +1494,6 @@
</implementation>
</binding>
<binding id="splitmenu">
<content>
<xul:hbox anonid="menuitem" flex="1"
class="splitmenu-menuitem"
xbl:inherits="iconic,label,disabled,onclick=oncommand,_moz-menuactive=active"/>
<xul:menu anonid="menu" class="splitmenu-menu"
xbl:inherits="disabled,_moz-menuactive=active"
oncommand="event.stopPropagation();">
<children includes="menupopup"/>
</xul:menu>
</content>
<implementation implements="nsIDOMEventListener">
<constructor><![CDATA[
this._parentMenupopup.addEventListener("DOMMenuItemActive", this, false);
this._parentMenupopup.addEventListener("popuphidden", this, false);
]]></constructor>
<destructor><![CDATA[
this._parentMenupopup.removeEventListener("DOMMenuItemActive", this, false);
this._parentMenupopup.removeEventListener("popuphidden", this, false);
]]></destructor>
<field name="menuitem" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "menuitem");
</field>
<field name="menu" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "menu");
</field>
<field name="_menuDelay">600</field>
<field name="_parentMenupopup"><![CDATA[
this._getParentMenupopup(this);
]]></field>
<method name="_getParentMenupopup">
<parameter name="aNode"/>
<body><![CDATA[
let node = aNode.parentNode;
while (node) {
if (node.localName == "menupopup")
break;
node = node.parentNode;
}
return node;
]]></body>
</method>
<method name="handleEvent">
<parameter name="event"/>
<body><![CDATA[
switch (event.type) {
case "DOMMenuItemActive":
if (this.getAttribute("active") == "true" &&
event.target != this &&
this._getParentMenupopup(event.target) == this._parentMenupopup)
this.removeAttribute("active");
break;
case "popuphidden":
if (event.target == this._parentMenupopup)
this.removeAttribute("active");
break;
}
]]></body>
</method>
</implementation>
<handlers>
<handler event="mouseover"><![CDATA[
if (this.getAttribute("active") != "true") {
this.setAttribute("active", "true");
let event = document.createEvent("Events");
event.initEvent("DOMMenuItemActive", true, false);
this.dispatchEvent(event);
if (this.getAttribute("disabled") != "true") {
let self = this;
setTimeout(function () {
if (self.getAttribute("active") == "true")
self.menu.open = true;
}, this._menuDelay);
}
}
]]></handler>
<handler event="popupshowing"><![CDATA[
if (event.target == this.firstChild &&
this._parentMenupopup._currentPopup)
this._parentMenupopup._currentPopup.hidePopup();
]]></handler>
<handler event="click" phase="capturing"><![CDATA[
if (this.getAttribute("disabled") == "true") {
// Prevent the command from being carried out
event.stopPropagation();
return;
}
let node = event.originalTarget;
while (true) {
if (node == this.menuitem)
break;
if (node == this)
return;
node = node.parentNode;
}
this._parentMenupopup.hidePopup();
]]></handler>
</handlers>
</binding>
<binding id="menuitem-tooltip" extends="chrome://global/content/bindings/menu.xml#menuitem">
<implementation>
<constructor><![CDATA[
@ -1641,7 +1527,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>

Просмотреть файл

@ -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)

Просмотреть файл

@ -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"

Просмотреть файл

@ -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

Просмотреть файл

@ -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 " ">

Просмотреть файл

@ -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

Просмотреть файл

@ -84,6 +84,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);

Просмотреть файл

@ -107,6 +107,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)

Просмотреть файл

@ -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>

Просмотреть файл

@ -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>

Просмотреть файл

@ -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

Просмотреть файл

@ -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/.

Просмотреть файл

@ -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[view="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] {
transition: height 150ms;
}

Просмотреть файл

@ -0,0 +1,79 @@
<!-- 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"
consumeoutsideclicks="true"
noautofocus="true">
<panelmultiview id="PanelUI-multiView" mainViewId="PanelUI-mainView">
<panelview id="PanelUI-mainView" flex="1" 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'); PanelUI.hide();"/>
</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"
consumeoutsideclicks="true">
<vbox id="widget-overflow-list">
</vbox>
</panel>

Просмотреть файл

@ -0,0 +1,252 @@
/* 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();
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.
*/
ensureRegistered: function() {
CustomizableUI.registerMenuPanel(this.contents);
},
/**
* 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");
}
},
/**
* 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);
}
};

Просмотреть файл

@ -0,0 +1,318 @@
<?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">
<xul:stack anonid="viewStack" view="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>
<property name="showingSubView" readonly="true"
onget="return this._viewStack.getAttribute('view') == '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);"/>
<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);
}
]]></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._viewStack.setAttribute("view", "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._viewStack.setAttribute("view", "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.showingSubView) {
this._viewContainer.style.height =
this._subViews.scrollHeight + "px";
}
]]></body>
</method>
<method name="_syncContainerWithMainView">
<body><![CDATA[
if (!this.showingSubView && !this._transitioning) {
this._viewContainer.style.height =
this._mainViewContainer.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>

Просмотреть файл

@ -0,0 +1,270 @@
<?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>
</bindings>

Просмотреть файл

@ -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',
]

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,454 @@
/* 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";
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);
}
}
}
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);
doc.defaultView.PanelUI.hide();
}
});
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"));
if (inPanel)
node.setAttribute("flex", "1");
node.classList.add("chromeclass-toolbar-additional");
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);
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 (aWidgetId != this.id)
return;
updateWidgetStyle(aArea == CustomizableUI.AREA_PANEL);
}.bind(this),
onWidgetRemoved: function(aWidgetId, aPrevArea) {
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 (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"));
if (inPanel)
node.setAttribute("flex", "1");
node.classList.add("chromeclass-toolbar-additional");
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 (aWidgetId != this.id)
return;
updateWidgetStyle(aArea == CustomizableUI.AREA_PANEL);
}.bind(this),
onWidgetRemoved: function(aWidgetId, aPrevArea) {
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 (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);
}
},
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");
}
}
}];

Просмотреть файл

@ -0,0 +1,971 @@
/* 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";
this.EXPORTED_SYMBOLS = ["CustomizeMode"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
const kPaletteId = "customization-palette";
const kAboutURI = "about:customizing";
const kDragDataTypePrefix = "text/toolbarwrapper-id/";
const kPlaceholderClass = "panel-customization-placeholder";
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/CustomizableUI.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let gModuleName = "[CustomizeMode]";
#include logging.js
function CustomizeMode(aWindow) {
this.window = aWindow;
this.document = aWindow.document;
this.browser = aWindow.gBrowser;
};
CustomizeMode.prototype = {
_changed: false,
window: null,
document: null,
// areas is used to cache the customizable areas when in customization mode.
areas: null,
// When in customizing mode, we swap out the reference to the invisible
// palette in gNavToolbox.palette for our visiblePalette. This way, for the
// customizing browser window, when widgets are removed from customizable
// areas and added to the palette, they're added to the visible palette.
// _stowedPalette is a reference to the old invisible palette so we can
// restore gNavToolbox.palette to its original state after exiting
// customization mode.
_stowedPalette: null,
_dragOverItem: null,
_customizing: false,
get resetButton() {
return this.document.getElementById("customization-reset-button");
},
get panelUIContents() {
return this.document.getElementById("PanelUI-contents");
},
init: function() {
// There are two palettes - there's the palette that can be overlayed with
// toolbar items in browser.xul. This is invisible, and never seen by the
// user. Then there's the visible palette, which gets populated and displayed
// to the user when in customizing mode.
this.visiblePalette = this.document.getElementById(kPaletteId);
this.browser.tabContainer.addEventListener("TabSelect", this, false);
this.browser.addTabsProgressListener(this);
},
uninit: function() {
this.browser.tabContainer.removeEventListener("TabSelect", this, false);
this.browser.removeTabsProgressListener(this);
},
enter: function() {
if (this._customizing) {
return;
}
// We don't need to switch to kAboutURI, or open a new tab at
// kAboutURI if we're already on it.
if (this.browser.selectedBrowser.currentURI.spec != kAboutURI) {
this.window.switchToTabHavingURI(kAboutURI, true);
return;
}
this.dispatchToolboxEvent("beforecustomization");
let window = this.window;
let document = this.document;
let customizer = document.getElementById("customization-container");
customizer.hidden = false;
CustomizableUI.addListener(this);
// The menu panel is lazy, and registers itself when the popup shows. We
// need to force the menu panel to register itself, or else customization
// is really not going to work.
window.PanelUI.ensureRegistered();
// Add a keypress listener and click listener to the tab-view-deck so that
// we can quickly exit customization mode when pressing ESC or clicking on
// the blueprint outside the customization container.
let deck = document.getElementById("tab-view-deck");
deck.addEventListener("keypress", this, false);
deck.addEventListener("click", this, false);
// Same goes for the menu button - if we're customizing, a click to the
// menu button means a quick exit from customization mode.
window.PanelUI.menuButton.addEventListener("click", this, false);
window.PanelUI.menuButton.disabled = true;
// Let everybody in this window know that we're about to customize.
this.dispatchToolboxEvent("customizationstarting");
customizer.parentNode.selectedPanel = customizer;
window.PanelUI.hide();
// Move the mainView in the panel to the holder so that we can see it
// while customizing.
let panelHolder = document.getElementById("customization-panelHolder");
panelHolder.appendChild(window.PanelUI.mainView);
this._showPanelCustomizationPlaceholders();
let self = this;
deck.addEventListener("transitionend", function customizeTransitionEnd() {
deck.removeEventListener("transitionend", customizeTransitionEnd);
self.dispatchToolboxEvent("customizationready");
});
this._wrapToolbarItems();
this.populatePalette();
window.PanelUI.mainView.addEventListener("contextmenu", this, true);
this.visiblePalette.addEventListener("dragstart", this, true);
this.visiblePalette.addEventListener("dragover", this, true);
this.visiblePalette.addEventListener("dragexit", this, true);
this.visiblePalette.addEventListener("drop", this, true);
this.visiblePalette.addEventListener("dragend", this, true);
this.resetButton.hidden = CustomizableUI.inDefaultState;
let customizableToolbars = document.querySelectorAll("toolbar[customizable=true]:not([autohide=true]):not([collapsed=true])");
for (let toolbar of customizableToolbars)
toolbar.setAttribute("customizing", true);
document.documentElement.setAttribute("customizing", true);
this._customizing = true;
},
exit: function() {
if (!this._customizing) {
return;
}
CustomizableUI.removeListener(this);
let deck = this.document.getElementById("tab-view-deck");
deck.removeEventListener("keypress", this, false);
deck.removeEventListener("click", this, false);
this.window.PanelUI.menuButton.removeEventListener("click", this, false);
this.window.PanelUI.menuButton.disabled = false;
this._removePanelCustomizationPlaceholders();
this.depopulatePalette();
this.window.PanelUI.mainView.removeEventListener("contextmenu", this, true);
this.visiblePalette.removeEventListener("dragstart", this, true);
this.visiblePalette.removeEventListener("dragover", this, true);
this.visiblePalette.removeEventListener("dragexit", this, true);
this.visiblePalette.removeEventListener("drop", this, true);
this.visiblePalette.removeEventListener("dragend", this, true);
let window = this.window;
let document = this.document;
let documentElement = document.documentElement;
documentElement.setAttribute("customize-exiting", "true");
let tabViewDeck = document.getElementById("tab-view-deck");
tabViewDeck.addEventListener("transitionend", function onTransitionEnd(evt) {
if (evt.propertyName != "padding-top")
return;
tabViewDeck.removeEventListener("transitionend", onTransitionEnd);
documentElement.removeAttribute("customize-exiting");
});
this._unwrapToolbarItems();
if (this._changed) {
// XXXmconley: At first, it seems strange to also persist the old way with
// currentset - but this might actually be useful for switching
// to old builds. We might want to keep this around for a little
// bit.
this.persistCurrentSets();
}
// And drop all area references.
this.areas = [];
// Let everybody in this window know that we're starting to
// exit customization mode.
this.dispatchToolboxEvent("customizationending");
window.PanelUI.setMainView(window.PanelUI.mainView);
let browser = document.getElementById("browser");
browser.parentNode.selectedPanel = browser;
// We need to set this._customizing to false before removing the tab
// or the TabSelect event handler will think that we are exiting
// customization mode for a second time.
this._customizing = false;
if (this.browser.selectedBrowser.currentURI.spec == kAboutURI) {
let custBrowser = this.browser.selectedBrowser;
if (custBrowser.canGoBack) {
// If there's history to this tab, just go back.
custBrowser.goBack();
} else {
// If we can't go back, we're removing the about:customization tab.
// We only do this if we're the top window for this window (so not
// a dialog window, for example).
if (this.window.getTopWin(true) == this.window) {
let customizationTab = this.browser.selectedTab;
if (this.browser.browsers.length == 1) {
this.window.BrowserOpenTab();
}
this.browser.removeTab(customizationTab);
}
}
}
let deck = document.getElementById("tab-view-deck");
let self = this;
deck.addEventListener("transitionend", function customizeTransitionEnd() {
deck.removeEventListener("transitionend", customizeTransitionEnd);
self.dispatchToolboxEvent("aftercustomization");
});
documentElement.removeAttribute("customizing");
let customizableToolbars = document.querySelectorAll("toolbar[customizable=true]:not([autohide=true])");
for (let toolbar of customizableToolbars)
toolbar.removeAttribute("customizing");
let customizer = document.getElementById("customization-container");
customizer.hidden = true;
this._changed = false;
},
dispatchToolboxEvent: function(aEventType, aDetails={}) {
let evt = this.document.createEvent("CustomEvent");
evt.initCustomEvent(aEventType, true, true, {changed: this._changed});
let result = this.window.gNavToolbox.dispatchEvent(evt);
},
addToToolbar: function(aNode) {
CustomizableUI.addWidgetToArea(aNode.id, CustomizableUI.AREA_NAVBAR);
},
removeFromPanel: function(aNode) {
CustomizableUI.removeWidgetFromArea(aNode.id);
},
populatePalette: function() {
let toolboxPalette = this.window.gNavToolbox.palette;
let unusedWidgets = CustomizableUI.getUnusedWidgets(toolboxPalette);
for (let widget of unusedWidgets) {
let paletteItem = this.makePaletteItem(widget, "palette");
this.visiblePalette.appendChild(paletteItem);
}
this._stowedPalette = this.window.gNavToolbox.palette;
this.window.gNavToolbox.palette = this.visiblePalette;
},
//XXXunf Maybe this should use -moz-element instead of wrapping the node?
// Would ensure no weird interactions/event handling from original node,
// and makes it possible to put this in a lazy-loaded iframe/real tab
// while still getting rid of the need for overlays.
makePaletteItem: function(aWidget, aPlace) {
let widgetNode = aWidget.forWindow(this.window).node;
let wrapper = this.createWrapper(widgetNode, aPlace);
wrapper.appendChild(widgetNode);
return wrapper;
},
depopulatePalette: function() {
let paletteChild = this.visiblePalette.firstChild;
let nextChild;
while (paletteChild) {
nextChild = paletteChild.nextElementSibling;
let provider = CustomizableUI.getWidget(paletteChild.id).provider;
if (provider == CustomizableUI.PROVIDER_XUL) {
let unwrappedPaletteItem = this.unwrapToolbarItem(paletteChild);
this._stowedPalette.appendChild(unwrappedPaletteItem);
} else if (provider == CustomizableUI.PROVIDER_API) {
//XXXunf Currently this doesn't destroy the (now unused) node. It would
// be good to do so, but we need to keep strong refs to it in
// CustomizableUI (can't iterate of WeakMaps), and there's the
// question of what behavior wrappers should have if consumers
// keep hold of them.
//widget.destroyInstance(widgetNode);
} else if (provider == CustomizableUI.PROVIDER_SPECIAL) {
this.visiblePalette.removeChild(paletteChild);
}
paletteChild = nextChild;
}
this.window.gNavToolbox.palette = this._stowedPalette;
},
isCustomizableItem: function(aNode) {
return aNode.localName == "toolbarbutton" ||
aNode.localName == "toolbaritem" ||
aNode.localName == "toolbarseparator" ||
aNode.localName == "toolbarspring" ||
aNode.localName == "toolbarspacer";
},
isWrappedToolbarItem: function(aNode) {
return aNode.localName == "toolbarpaletteitem";
},
wrapToolbarItem: function(aNode, aPlace) {
if (!this.isCustomizableItem(aNode)) {
return aNode;
}
let wrapper = this.createWrapper(aNode, aPlace);
// It's possible that this toolbar node is "mid-flight" and doesn't have
// a parent, in which case we skip replacing it. This can happen if a
// toolbar item has been dragged into the palette. In that case, we tell
// CustomizableUI to remove the widget from its area before putting the
// widget in the palette - so the node will have no parent.
if (aNode.parentNode) {
aNode = aNode.parentNode.replaceChild(wrapper, aNode);
}
wrapper.appendChild(aNode);
return wrapper;
},
createWrapper: function(aNode, aPlace) {
let wrapper = this.document.createElement("toolbarpaletteitem");
// "place" is used by toolkit to add the toolbarpaletteitem-palette
// binding to a toolbarpaletteitem, which gives it a label node for when
// it's sitting in the palette.
wrapper.setAttribute("place", aPlace);
// Ensure the wrapped item doesn't look like it's in any special state, and
// can't be interactved with when in the customization palette.
if (aNode.hasAttribute("command")) {
wrapper.setAttribute("itemcommand", aNode.getAttribute("command"));
aNode.removeAttribute("command");
}
if (aNode.checked) {
wrapper.setAttribute("itemchecked", "true");
aNode.checked = false;
}
if (aNode.disabled) {
wrapper.setAttribute("itemdisabled", "true");
aNode.disabled = false;
}
if (aNode.hasAttribute("id")) {
wrapper.setAttribute("id", "wrapper-" + aNode.getAttribute("id"));
}
if (aNode.hasAttribute("title")) {
wrapper.setAttribute("title", aNode.getAttribute("title"));
} else if (aNode.hasAttribute("label")) {
wrapper.setAttribute("title", aNode.getAttribute("label"));
}
if (aNode.hasAttribute("flex")) {
wrapper.setAttribute("flex", aNode.getAttribute("flex"));
}
wrapper.addEventListener("mousedown", this);
wrapper.addEventListener("mouseup", this);
return wrapper;
},
unwrapToolbarItem: function(aWrapper) {
if (aWrapper.nodeName != "toolbarpaletteitem") {
return aWrapper;
}
aWrapper.removeEventListener("mousedown", this);
aWrapper.removeEventListener("mouseup", this);
let toolbarItem = aWrapper.firstChild;
if (aWrapper.hasAttribute("itemdisabled")) {
toolbarItem.disabled = true;
}
if (aWrapper.hasAttribute("itemchecked")) {
toolbarItem.checked = true;
}
if (aWrapper.hasAttribute("itemcommand")) {
let commandID = aWrapper.getAttribute("itemcommand");
toolbarItem.setAttribute("command", commandID);
//XXX Bug 309953 - toolbarbuttons aren't in sync with their commands after customizing
let command = this.document.getElementById(commandID);
if (command && command.hasAttribute("disabled")) {
toolbarItem.setAttribute("disabled", command.getAttribute("disabled"));
}
}
if (aWrapper.parentNode) {
aWrapper.parentNode.replaceChild(toolbarItem, aWrapper);
}
return toolbarItem;
},
_wrapToolbarItems: function() {
let window = this.window;
// Add drag-and-drop event handlers to all of the customizable areas.
this.areas = [];
for (let area of CustomizableUI.areas) {
let target = CustomizableUI.getCustomizeTargetForArea(area, window);
target.addEventListener("dragstart", this, true);
target.addEventListener("dragover", this, true);
target.addEventListener("dragexit", this, true);
target.addEventListener("drop", this, true);
target.addEventListener("dragend", this, true);
for (let child of target.children) {
if (this.isCustomizableItem(child)) {
this.wrapToolbarItem(child, getPlaceForItem(child));
}
}
this.areas.push(target);
}
},
_unwrapToolbarItems: function() {
for (let target of this.areas) {
for (let toolbarItem of target.children) {
if (this.isWrappedToolbarItem(toolbarItem)) {
this.unwrapToolbarItem(toolbarItem);
}
}
target.removeEventListener("dragstart", this, true);
target.removeEventListener("dragover", this, true);
target.removeEventListener("dragexit", this, true);
target.removeEventListener("drop", this, true);
target.removeEventListener("dragend", this, true);
}
},
persistCurrentSets: function() {
let document = this.document;
let toolbars = document.querySelectorAll("toolbar[customizable='true']");
for (let toolbar of toolbars) {
let set = toolbar.currentSet;
toolbar.setAttribute("currentset", set);
LOG("Setting currentset of " + toolbar.id + " as " + set);
// Persist the currentset attribute directly on hardcoded toolbars.
document.persist(toolbar.id, "currentset");
}
},
reset: function() {
this._removePanelCustomizationPlaceholders();
this.depopulatePalette();
this._unwrapToolbarItems();
CustomizableUI.reset();
this._wrapToolbarItems();
this.populatePalette();
let document = this.document;
let toolbars = document.querySelectorAll("toolbar[customizable='true']");
for (let toolbar of toolbars) {
let set = toolbar.currentSet;
toolbar.removeAttribute("currentset");
LOG("[RESET] Removing currentset of " + toolbar.id);
// Persist the currentset attribute directly on hardcoded toolbars.
document.persist(toolbar.id, "currentset");
}
this.resetButton.hidden = CustomizableUI.inDefaultState;
this._showPanelCustomizationPlaceholders();
},
onWidgetMoved: function(aWidgetId, aArea, aOldPosition, aNewPosition) {
this._onUIChange();
},
onWidgetAdded: function(aWidgetId, aArea, aPosition) {
this._onUIChange();
},
onWidgetRemoved: function(aWidgetId, aArea) {
this._onUIChange();
},
onWidgetCreated: function(aWidgetId) {
},
onWidgetDestroyed: function(aWidgetId) {
},
_onUIChange: function() {
this._changed = true;
this.resetButton.hidden = CustomizableUI.inDefaultState;
this.dispatchToolboxEvent("customizationchange");
},
handleEvent: function(aEvent) {
switch(aEvent.type) {
case "contextmenu":
aEvent.preventDefault();
aEvent.stopPropagation();
break;
case "dragstart":
this._onDragStart(aEvent);
break;
case "dragover":
this._onDragOver(aEvent);
break;
case "drop":
this._onDragDrop(aEvent);
break;
case "dragexit":
this._onDragExit(aEvent);
break;
case "dragend":
this._onDragEnd(aEvent);
break;
case "mousedown":
this._onMouseDown(aEvent);
break;
case "mouseup":
this._onMouseUp(aEvent);
break;
case "keypress":
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
this.exit();
}
break;
case "click":
if (aEvent.button == 0 &&
(aEvent.originalTarget == this.window.PanelUI.menuButton) ||
(aEvent.originalTarget == this.document.getElementById("tab-view-deck"))) {
this.exit();
aEvent.preventDefault();
}
break;
case "TabSelect":
this._onTabSelect(aEvent);
break;
}
},
_onDragStart: function(aEvent) {
__dumpDragData(aEvent);
let item = aEvent.target;
while (item && item.localName != "toolbarpaletteitem") {
if (item.localName == "toolbar" ||
item.classList.contains(kPlaceholderClass)) {
return;
}
item = item.parentNode;
}
let dt = aEvent.dataTransfer;
let documentId = aEvent.target.ownerDocument.documentElement.id;
let draggedItem = item.firstChild;
let draggedItemWidth = draggedItem.getBoundingClientRect().width + "px";
let data = {
id: draggedItem.id,
width: draggedItemWidth,
};
dt.mozSetDataAt(kDragDataTypePrefix + documentId, data, 0);
dt.effectAllowed = "move";
// Hack needed so that the dragimage will still show the
// item as it appeared before it was hidden.
let win = aEvent.target.ownerDocument.defaultView;
win.setTimeout(function() {
item.hidden = true;
this._showPanelCustomizationPlaceholders();
}.bind(this), 0);
},
_onDragOver: function(aEvent) {
__dumpDragData(aEvent);
let document = aEvent.target.ownerDocument;
let documentId = document.documentElement.id;
if (!aEvent.dataTransfer.mozTypesAt(0)) {
return;
}
let {id: draggedItemId, width: draggedItemWidth} =
aEvent.dataTransfer.mozGetDataAt(kDragDataTypePrefix + documentId, 0);
let draggedWrapper = document.getElementById("wrapper-" + draggedItemId);
let targetArea = this._getCustomizableParent(aEvent.currentTarget);
let originArea = this._getCustomizableParent(draggedWrapper);
// Do nothing if the target or origin are not customizable.
if (!targetArea || !originArea) {
return;
}
// Do nothing if the widget is not allowed to be removed.
if (targetArea.id == kPaletteId &&
!CustomizableUI.isWidgetRemovable(draggedItemId)) {
return;
}
// Do nothing if the widget is not allowed to move to the target area.
if (targetArea.id != kPaletteId &&
!CustomizableUI.canWidgetMoveToArea(draggedItemId, targetArea.id)) {
return;
}
let targetNode = this._getDragOverNode(aEvent.target, targetArea);
let targetParent = targetNode.parentNode;
// We need to determine the place that the widget is being dropped in
// the target.
let dragOverItem;
let atEnd = false;
if (targetNode == targetArea.customizationTarget) {
dragOverItem = targetNode.lastChild;
atEnd = true;
} else {
let position = Array.indexOf(targetParent.children, targetNode);
dragOverItem = position == -1 ? targetParent.lastChild : targetParent.children[position];
}
if (this._dragOverItem && dragOverItem != this._dragOverItem) {
this._setDragActive(this._dragOverItem, false);
}
if (dragOverItem != this._dragOverItem) {
this._setDragActive(dragOverItem, true, draggedItemWidth, atEnd);
this._dragOverItem = dragOverItem;
}
aEvent.preventDefault();
aEvent.stopPropagation();
},
_onDragDrop: function(aEvent) {
__dumpDragData(aEvent);
this._setDragActive(this._dragOverItem, false);
this._removePanelCustomizationPlaceholders();
let document = aEvent.target.ownerDocument;
let documentId = document.documentElement.id;
let {id: draggedItemId} =
aEvent.dataTransfer.mozGetDataAt(kDragDataTypePrefix + documentId, 0);
let draggedWrapper = document.getElementById("wrapper-" + draggedItemId);
draggedWrapper.hidden = false;
draggedWrapper.removeAttribute("mousedown");
let targetArea = this._getCustomizableParent(aEvent.currentTarget);
let originArea = this._getCustomizableParent(draggedWrapper);
// Do nothing if the target area or origin area are not customizable.
if (!targetArea || !originArea) {
return;
}
let targetNode = this._getDragOverNode(aEvent.target, targetArea);
// Do nothing if the target was dropped onto itself (ie, no change in area
// or position).
if (draggedWrapper == targetNode) {
return;
}
// Is the target area the customization palette? If so, we have two cases -
// either the originArea was the palette, or a customizable area.
if (targetArea.id == kPaletteId) {
if (originArea.id !== kPaletteId) {
if (!CustomizableUI.isWidgetRemovable(draggedItemId)) {
return;
}
let widget = this.unwrapToolbarItem(draggedWrapper);
CustomizableUI.removeWidgetFromArea(draggedItemId);
draggedWrapper = this.wrapToolbarItem(widget, "palette");
}
// If the targetNode is the palette itself, just append
if (targetNode == this.visiblePalette) {
this.visiblePalette.appendChild(draggedWrapper);
} else {
this.visiblePalette.insertBefore(draggedWrapper, targetNode);
}
this._showPanelCustomizationPlaceholders();
return;
}
if (!CustomizableUI.canWidgetMoveToArea(draggedItemId, targetArea.id)) {
return;
}
// Is the target the customization area itself? If so, we just add the
// widget to the end of the area.
if (targetNode == targetArea.customizationTarget) {
let widget = this.unwrapToolbarItem(draggedWrapper);
CustomizableUI.addWidgetToArea(draggedItemId, targetArea.id);
this.wrapToolbarItem(widget, getPlaceForItem(targetNode));
this._showPanelCustomizationPlaceholders();
return;
}
// We need to determine the place that the widget is being dropped in
// the target.
let placement;
if (!targetNode.classList.contains(kPlaceholderClass)) {
let targetNodeId = (targetNode.nodeName == "toolbarpaletteitem") ?
targetNode.firstChild && targetNode.firstChild.id :
targetNode.id;
placement = CustomizableUI.getPlacementOfWidget(targetNodeId);
}
if (!placement) {
LOG("Could not get a position for " + targetNode + "#" + targetNode.id + "." + targetNode.className);
}
let position = placement ? placement.position :
targetArea.childElementCount;
// Is the target area the same as the origin? Since we've already handled
// the possibility that the target is the customization palette, we know
// that the widget is moving within a customizable area.
if (targetArea == originArea) {
let properPlace = getPlaceForItem(targetNode);
// We unwrap the moving widget, as well as the widget that we're dropping
// on (the target) so that moveWidgetWithinArea can correctly insert the
// moving widget before the target widget.
let widget = this.unwrapToolbarItem(draggedWrapper);
let targetWidget = this.unwrapToolbarItem(targetNode);
CustomizableUI.moveWidgetWithinArea(draggedItemId, position);
this.wrapToolbarItem(targetWidget, properPlace);
this.wrapToolbarItem(widget, properPlace);
this._showPanelCustomizationPlaceholders();
return;
}
// A little hackery - we quickly unwrap the item and use CustomizableUI's
// addWidgetToArea to move the widget to the right place for every window,
// then we re-wrap the widget. We have to unwrap the target widget too so
// that addWidgetToArea inserts the new widget into the right place.
let properPlace = getPlaceForItem(targetNode);
let widget = this.unwrapToolbarItem(draggedWrapper);
let targetWidget = this.unwrapToolbarItem(targetNode);
CustomizableUI.addWidgetToArea(draggedItemId, targetArea.id, position);
this.wrapToolbarItem(targetWidget, properPlace);
draggedWrapper = this.wrapToolbarItem(widget, properPlace);
this._showPanelCustomizationPlaceholders();
},
_onDragExit: function(aEvent) {
__dumpDragData(aEvent);
if (this._dragOverItem) {
this._setDragActive(this._dragOverItem, false);
}
},
_onDragEnd: function(aEvent) {
__dumpDragData(aEvent);
let document = aEvent.target.ownerDocument;
document.documentElement.removeAttribute("customizing-movingItem");
let documentId = document.documentElement.id;
if (!aEvent.dataTransfer.mozTypesAt(0)) {
return;
}
let {id: draggedItemId} =
aEvent.dataTransfer.mozGetDataAt(kDragDataTypePrefix + documentId, 0);
let draggedWrapper = document.getElementById("wrapper-" + draggedItemId);
draggedWrapper.hidden = false;
draggedWrapper.removeAttribute("mousedown");
this._showPanelCustomizationPlaceholders();
},
_setDragActive: function(aItem, aValue, aWidth, aAtEnd) {
if (!aItem) {
return;
}
let node = aItem;
let window = aItem.ownerDocument.defaultView;
let direction = window.getComputedStyle(aItem, null).direction;
let value = direction == "ltr" ? "left" : "right";
if (aItem.localName == "toolbar" || aAtEnd) {
value = direction == "ltr"? "right" : "left";
if (aItem.localName == "toolbar") {
node = aItem.lastChild;
}
}
if (!node) {
return;
}
if (aValue) {
if (!node.hasAttribute("dragover")) {
node.setAttribute("dragover", value);
if (aWidth) {
if (value == "left") {
node.style.borderLeftWidth = aWidth;
} else {
node.style.borderRightWidth = aWidth;
}
}
}
} else {
node.removeAttribute("dragover");
// Remove both property values in the case that the end padding
// had been set.
node.style.removeProperty("border-left-width");
node.style.removeProperty("border-right-width");
}
},
_getCustomizableParent: function(aElement) {
let areas = CustomizableUI.areas;
areas.push(kPaletteId);
while (aElement) {
if (areas.indexOf(aElement.id) != -1) {
return aElement;
}
aElement = aElement.parentNode;
}
return null;
},
_getDragOverNode: function(aElement, aAreaElement) {
let expectedParent = aAreaElement.customizationTarget || aAreaElement;
let targetNode = aElement;
while (targetNode && targetNode.parentNode != expectedParent) {
targetNode = targetNode.parentNode;
}
return targetNode || aElement;
},
_onMouseDown: function(aEvent) {
LOG("_onMouseDown");
let doc = aEvent.target.ownerDocument;
doc.documentElement.setAttribute("customizing-movingItem", true);
let item = this._getWrapper(aEvent.target);
if (item) {
item.setAttribute("mousedown", "true");
}
},
_onMouseUp: function(aEvent) {
LOG("_onMouseUp");
let doc = aEvent.target.ownerDocument;
doc.documentElement.removeAttribute("customizing-movingItem");
let item = this._getWrapper(aEvent.target);
if (item) {
item.removeAttribute("mousedown");
}
},
_getWrapper: function(aElement) {
while (aElement && aElement.localName != "toolbarpaletteitem") {
if (aElement.localName == "toolbar")
return null;
aElement = aElement.parentNode;
}
return aElement;
},
_onTabSelect: function(aEvent) {
this._toggleCustomizationModeIfNecessary();
},
onLocationChange: function(aBrowser, aProgress, aRequest, aLocation, aFlags) {
if (this.browser.selectedBrowser != aBrowser) {
return;
}
this._toggleCustomizationModeIfNecessary();
},
/**
* Looks at the currently selected browser tab, and if the location
* is set to kAboutURI and we're not customizing, enters customize mode.
* If we're not at kAboutURI and we are customizing, exits customize mode.
*/
_toggleCustomizationModeIfNecessary: function() {
let browser = this.browser.selectedBrowser;
if (browser.currentURI.spec == kAboutURI &&
!this._customizing) {
this.enter();
} else if (browser.currentURI.spec != kAboutURI &&
this._customizing) {
this.exit();
}
},
_showPanelCustomizationPlaceholders: function() {
const kColumns = 3;
this._removePanelCustomizationPlaceholders();
let doc = this.document;
let contents = this.panelUIContents;
let visibleChildren = contents.querySelectorAll("toolbarpaletteitem:not([hidden])");
let hangingItems = visibleChildren.length % kColumns;
let newPlaceholders = kColumns - hangingItems;
while (newPlaceholders--) {
let placeholder = doc.createElement("toolbarpaletteitem");
placeholder.classList.add(kPlaceholderClass);
//XXXjaws The toolbarbutton child here is only necessary to get
// the styling right here.
let placeholderChild = doc.createElement("toolbarbutton");
placeholderChild.classList.add(kPlaceholderClass + "-child");
placeholder.appendChild(placeholderChild);
contents.appendChild(placeholder);
}
},
_removePanelCustomizationPlaceholders: function() {
let contents = this.panelUIContents;
let oldPlaceholders = contents.getElementsByClassName(kPlaceholderClass);
while (oldPlaceholders.length) {
contents.removeChild(oldPlaceholders[0]);
}
}
};
function getPlaceForItem(aElement) {
let place;
let node = aElement;
while (node && !place) {
if (node.localName == "toolbar")
place = "toolbar";
else if (node.id == CustomizableUI.AREA_PANEL)
place = "panel";
else if (node.id == kPaletteId)
place = "palette";
node = node.parentNode;
}
return place;
}
function __dumpDragData(aEvent, caller) {
let str = "Dumping drag data (CustomizeMode.jsm) {\n";
str += " type: " + aEvent["type"] + "\n";
for (let el of ["target", "currentTarget", "relatedTarget"]) {
if (aEvent[el]) {
str += " " + el + ": " + aEvent[el] + "(localName=" + aEvent[el].localName + "; id=" + aEvent[el].id + ")\n";
}
}
for (let prop in aEvent.dataTransfer) {
if (typeof aEvent.dataTransfer[prop] != "function") {
str += " dataTransfer[" + prop + "]: " + aEvent.dataTransfer[prop] + "\n";
}
}
str += "}";
LOG(str);
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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/.

Просмотреть файл

@ -0,0 +1,21 @@
# 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 \
head.js \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,75 @@
/* 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]);
}
},
{
desc: "Add separators around the downloads button.",
run: function() {
CustomizableUI.addWidgetToArea("separator", kToolbarName, 1);
CustomizableUI.addWidgetToArea("separator", kToolbarName, 3);
assertAreaPlacements(kToolbarName,
[/customizableui-special-spring\d+/,
/customizableui-special-separator\d+/,
"downloads-button",
/customizableui-special-separator\d+/,
/customizableui-special-spring\d+/]);
let [,separator1Id,,separator2Id,] = getAreaWidgetIds(kToolbarName);
isnot(separator1Id, separator2Id, "Separator ids shouldn't be equal.");
}
},
{
desc: "Add spacers around the downloads button.",
run: function() {
CustomizableUI.addWidgetToArea("spacer", kToolbarName, 2);
CustomizableUI.addWidgetToArea("spacer", kToolbarName, 4);
assertAreaPlacements(kToolbarName,
[/customizableui-special-spring\d+/,
/customizableui-special-separator\d+/,
/customizableui-special-spacer\d+/,
"downloads-button",
/customizableui-special-spacer\d+/,
/customizableui-special-separator\d+/,
/customizableui-special-spring\d+/]);
let [,,spacer1Id,,spacer2Id,,] = getAreaWidgetIds(kToolbarName);
isnot(spacer1Id, spacer2Id, "Spacer ids shouldn't be equal.");
}
}
];
function cleanup() {
removeCustomToolbars();
resetCustomization();
}
function test() {
waitForExplicitFinish();
registerCleanupFunction(cleanup);
runTests(gTests);
}

Просмотреть файл

@ -0,0 +1,64 @@
/* 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 cleanup() {
removeCustomToolbars();
resetCustomization();
}
function test() {
waitForExplicitFinish();
registerCleanupFunction(cleanup);
runTests(gTests);
}

Просмотреть файл

@ -0,0 +1,32 @@
/* 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 cleanup() {
removeCustomToolbars();
resetCustomization();
}
function test() {
waitForExplicitFinish();
registerCleanupFunction(cleanup);
runTests(gTests);
}

Просмотреть файл

@ -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/. */
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 cleanup() {
resetCustomization();
}
function test() {
waitForExplicitFinish();
registerCleanupFunction(cleanup);
runTests(gTests);
}

Просмотреть файл

@ -0,0 +1,153 @@
/* 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/commonjs/sdk/core/promise.js", 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() {
if (document.documentElement.hasAttribute("customizing")) {
window.gCustomizeMode.reset();
window.gCustomizeMode.exit();
} else {
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 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();
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 deferredEndCustomizing.promise;
}
// 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 Promise.all(deferredEndCustomizing.promise, 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) {
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();
}
}
function runTests(testAry) {
Task.spawn(testRunner(gTests)).then(finish, ex => {
ok(false, "Unexpected exception: " + ex);
finish();
});
}

Просмотреть файл

Просмотреть файл

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

Просмотреть файл

@ -1179,7 +1179,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 {
@ -1369,6 +1369,61 @@ BrowserGlue.prototype = {
catch (ex) {}
}
if (currentUIVersion < 14) {
// Migrate users from text or text&icons mode to icons mode.
let toolbarResources = [this._rdf.GetResource(BROWSER_DOCURL + "navigator-toolbox"),
this._rdf.GetResource(BROWSER_DOCURL + "nav-bar"),
this._rdf.GetResource(BROWSER_DOCURL + "PersonalToolbar"),
this._rdf.GetResource(BROWSER_DOCURL + "addon-bar")];
let modeResource = this._rdf.GetResource("mode");
let iconsizeResource = this._rdf.GetResource("iconsize");
for (let toolbarResource of toolbarResources) {
let toolbarMode = this._getPersist(toolbarResource, modeResource);
if (toolbarMode != "icons") {
this._setPersist(toolbarResource, modeResource, "icons");
// If the user wasn't previously using icons mode, switch
// them to the default (large icon mode).
this._setPersist(toolbarResource, iconsizeResource, "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();

Просмотреть файл

@ -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");
}
}

Просмотреть файл

@ -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">
@ -68,7 +71,6 @@ 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">
@ -156,22 +158,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">
@ -187,7 +182,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">
@ -307,8 +301,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">
@ -321,16 +313,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">
@ -533,16 +528,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 "[">
@ -652,6 +639,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">

Просмотреть файл

@ -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/.
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.
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…

Просмотреть файл

@ -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)

Просмотреть файл

@ -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) {

Двоичные данные
browser/themes/linux/appmenu.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 247 B

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -10,12 +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 conditionalForwardWithUrlbar_small window:not([chromehidden~=toolbar]) :-moz-any(#nav-bar[currentset*="unified-back-forward-button,urlbar-container"][iconsize=small],#nav-bar:not([currentset])[iconsize=small]) > #nav-bar-customizationtarget > #unified-back-forward-button
%define conditionalForwardWithUrlbarWidth 32
%define conditionalForwardWithUrlbarWidth_small 24
@ -31,14 +31,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 +45,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 +110,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 +232,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 +240,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 +249,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 +265,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 +275,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 +366,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 +374,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 +456,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 +478,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 +497,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 +505,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 +532,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;
@ -654,23 +635,15 @@ 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");
}
@ -687,38 +660,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");
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");
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");
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);
}
@ -819,14 +792,11 @@ toolbar[iconsize="small"] #downloads-button {
-moz-image-region: rect(0px 16px 16px 0px);
}
toolbar[iconsize="small"] #webrtc-status-button /* temporary placeholder (bug 824825) */,
toolbar[iconsize="small"] #history-button {
toolbar[iconsize="small"] #webrtc-status-button /* temporary placeholder (bug 824825) */ {
-moz-image-region: rect(0px 32px 16px 16px);
}
toolbar[iconsize="small"] #bookmarks-button,
toolbar[iconsize="small"] #bookmarks-menu-button,
#bookmarks-menu-button.bookmark-item {
toolbar[iconsize="small"] #bookmarks-button {
-moz-image-region: rect(0px 48px 16px 32px);
}
@ -1525,17 +1495,28 @@ 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 {
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);
}
#bookmarks-menu-button[disabled] > .toolbarbutton-icon,
#bookmarks-menu-button[disabled] > .toolbarbutton-menu-dropmarker,
#bookmarks-menu-button[disabled] > .toolbarbutton-menubutton-dropmarker,
@ -1598,143 +1579,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");
}
@ -1758,7 +1652,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 */
@ -1769,11 +1664,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 */
@ -1894,10 +1788,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 {
@ -1935,44 +1825,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 {
@ -2282,6 +2134,45 @@ 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 */
.click-to-play-plugins-notification-content {
margin: -10px;
}

Двоичные данные
browser/themes/linux/customizableui/background-noise-toolbar.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 15 KiB

Двоичные данные
browser/themes/linux/customizableui/customizeMode-gridTexture.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 118 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичные данные
browser/themes/linux/customizableui/menuPanel-icons.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 18 KiB

Двоичные данные
browser/themes/linux/customizableui/menuPanel-small-icons.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.5 KiB

Просмотреть файл

@ -0,0 +1,41 @@
/* 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
#PanelUI-contents #cut-button {
list-style-image: url("moz-icon://stock/gtk-cut?size=toolbar");
}
#PanelUI-contents #cut-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-cut?size=toolbar&state=disabled");
}
#PanelUI-contents #copy-button {
list-style-image: url("moz-icon://stock/gtk-copy?size=toolbar");
}
#PanelUI-contents #copy-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-copy?size=toolbar&state=disabled");
}
#PanelUI-contents #paste-button {
list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar");
}
#PanelUI-contents #paste-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar&state=disabled");
}
#PanelUI-contents #zoom-out-button {
list-style-image: url("moz-icon://stock/gtk-zoom-out?size=toolbar");
padding-left: 12px;
padding-right: 12px;
}
#PanelUI-contents #zoom-in-button {
list-style-image: url("moz-icon://stock/gtk-zoom-in?size=toolbar");
padding-left: 12px;
padding-right: 12px;
}

Просмотреть файл

@ -18,8 +18,16 @@ 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/customizableui/menuPanel-icons.png (customizableui/menuPanel-icons.png)
skin/classic/browser/customizableui/menuPanel-small-icons.png (customizableui/menuPanel-small-icons.png)
* skin/classic/browser/engineManager.css
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
@ -57,6 +65,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/buttons.png (downloads/buttons.png)
skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png)
skin/classic/browser/downloads/download-glow-small.png (downloads/download-glow-small.png)
@ -82,7 +91,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)
@ -90,7 +98,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)
@ -113,8 +120,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)

Просмотреть файл

@ -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)

Двоичные данные
browser/themes/linux/places/pageStarred.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 767 B

Двоичные данные
browser/themes/linux/places/starPage.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 723 B

Двоичные данные
browser/themes/linux/tabbrowser/tab-active-middle.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 388 B

Двоичные данные
browser/themes/linux/tabbrowser/tab-background-end.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.0 KiB

Двоичные данные
browser/themes/linux/tabbrowser/tab-background-middle.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 308 B

Двоичные данные
browser/themes/linux/tabbrowser/tab-background-start.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1019 B

Двоичные данные
browser/themes/linux/tabbrowser/tab-separator.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 192 B

Двоичные данные
browser/themes/linux/tabbrowser/tab-stroke-end.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичные данные
browser/themes/linux/tabbrowser/tab-stroke-start.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичные данные
browser/themes/osx/Toolbar-background-noise.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 15 KiB

Двоичные данные
browser/themes/osx/appmenu.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 247 B

Просмотреть файл

@ -0,0 +1,28 @@
/* 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 shared.inc
/*
* 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;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Двоичные данные
browser/themes/osx/customizableui/background-noise-toolbar.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 15 KiB

Двоичные данные
browser/themes/osx/customizableui/customizeMode-gridTexture.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 118 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичные данные
browser/themes/osx/customizableui/menuPanel-icons.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 18 KiB

Двоичные данные
browser/themes/osx/customizableui/menuPanel-icons@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Двоичные данные
browser/themes/osx/customizableui/menuPanel-small-icons.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.5 KiB

Двоичные данные
browser/themes/osx/customizableui/menuPanel-small-icons@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше