Merge mozilla-central into build-system

This commit is contained in:
Gregory Szorc 2012-12-22 15:29:20 -08:00
commit d6afe62e9b
780 changed files with 59277 additions and 24325 deletions

View File

@ -6,6 +6,7 @@
#include "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "DocAccessible.h"
#include "nsMai.h"

View File

@ -6,6 +6,7 @@
#include "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "HyperTextAccessible.h"
#include "nsMai.h"

View File

@ -6,6 +6,7 @@
#include "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "HyperTextAccessible.h"
#include "nsMai.h"
#include "nsMaiHyperlink.h"

View File

@ -6,6 +6,7 @@
#include "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "nsMai.h"
#include "mozilla/Likely.h"

View File

@ -6,6 +6,7 @@
#include "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "HyperTextAccessible.h"
#include "nsMai.h"

View File

@ -5,7 +5,7 @@
#include "AccIterator.h"
#include "nsAccessibilityService.h"
#include "Accessible.h"
#include "Accessible-inl.h"
#include "mozilla/dom/Element.h"
#include "nsBindingManager.h"

View File

@ -9,6 +9,7 @@
#define _nsARIAMap_H_
#include "ARIAStateMap.h"
#include "mozilla/a11y/AccTypes.h"
#include "mozilla/a11y/Role.h"
#include "nsIAtom.h"
@ -149,6 +150,12 @@ struct nsRoleMapEntry
bool Is(nsIAtom* aARIARole) const
{ return *roleAtom == aARIARole; }
/**
* Return true if ARIA role has the given accessible type.
*/
bool IsOfType(mozilla::a11y::AccGenericType aType) const
{ return accTypes & aType; }
/**
* Return ARIA role.
*/

View File

@ -31,12 +31,11 @@ Accessible::ARIARole()
return ARIATransformRole(mRoleMapEntry->role);
}
inline void
Accessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
inline bool
Accessible::HasGenericType(AccGenericType aType) const
{
mRoleMapEntry = aRoleMapEntry;
if (mRoleMapEntry)
mGenericTypes |= mRoleMapEntry->accTypes;
return (mGenericTypes & aType) ||
(mRoleMapEntry && mRoleMapEntry->IsOfType(aType));
}
inline bool

View File

@ -304,7 +304,8 @@ public:
/**
* Set the ARIA role map entry for a new accessible.
*/
void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
{ mRoleMapEntry = aRoleMapEntry; }
/**
* Update the children cache.
@ -468,17 +469,17 @@ public:
bool IsApplication() const { return mType == eApplicationType; }
bool IsAutoComplete() const { return mGenericTypes & eAutoComplete; }
bool IsAutoComplete() const { return HasGenericType(eAutoComplete); }
bool IsAutoCompletePopup() const
{ return mGenericTypes & eAutoCompletePopup; }
{ return HasGenericType(eAutoCompletePopup); }
bool IsCombobox() const { return mGenericTypes & eCombobox; }
bool IsCombobox() const { return HasGenericType(eCombobox); }
bool IsDoc() const { return mGenericTypes & eDocument; }
bool IsDoc() const { return HasGenericType(eDocument); }
DocAccessible* AsDoc();
bool IsHyperText() const { return mGenericTypes & eHyperText; }
bool IsHyperText() const { return HasGenericType(eHyperText); }
HyperTextAccessible* AsHyperText();
bool IsHTMLFileInput() const { return mType == eHTMLFileInputType; }
@ -494,11 +495,11 @@ public:
bool IsImageMap() const { return mType == eImageMapType; }
HTMLImageMapAccessible* AsImageMap();
bool IsList() const { return mGenericTypes & eList; }
bool IsList() const { return HasGenericType(eList); }
bool IsListControl() const { return mGenericTypes & eListControl; }
bool IsListControl() const { return HasGenericType(eListControl); }
bool IsMenuButton() const { return mGenericTypes & eMenuButton; }
bool IsMenuButton() const { return HasGenericType(eMenuButton); }
bool IsMenuPopup() const { return mType == eMenuPopupType; }
@ -507,14 +508,14 @@ public:
bool IsRoot() const { return mType == eRootType; }
a11y::RootAccessible* AsRoot();
bool IsSelect() const { return mGenericTypes & eSelect; }
bool IsSelect() const { return HasGenericType(eSelect); }
bool IsTable() const { return mGenericTypes & eTable; }
bool IsTable() const { return HasGenericType(eTable); }
virtual TableAccessible* AsTable() { return nullptr; }
virtual TableCellAccessible* AsTableCell() { return nullptr; }
bool IsTableRow() const { return mGenericTypes & eTableRow; }
bool IsTableRow() const { return HasGenericType(eTableRow); }
bool IsTextLeaf() const { return mType == eTextLeafType; }
TextLeafAccessible* AsTextLeaf();
@ -524,6 +525,11 @@ public:
bool IsXULTree() const { return mType == eXULTreeType; }
XULTreeAccessible* AsXULTree();
/**
* Return true if the accessible belongs to the given accessible type.
*/
bool HasGenericType(AccGenericType aType) const;
//////////////////////////////////////////////////////////////////////////////
// ActionAccessible

View File

@ -5,6 +5,7 @@
#include "OuterDocAccessible.h"
#include "Accessible-inl.h"
#include "nsAccUtils.h"
#include "DocAccessible.h"
#include "Role.h"

View File

@ -69,9 +69,6 @@ this.TouchAdapter = {
target.addEventListener('mousemove', this, true, true);
target.addEventListener('mouseenter', this, true, true);
target.addEventListener('mouseleave', this, true, true);
target.addEventListener('mousedown', this, true, true);
target.addEventListener('mouseup', this, true, true);
target.addEventListener('click', this, true, true);
target.addEventListener('touchend', this, true, true);
target.addEventListener('touchmove', this, true, true);
@ -97,9 +94,6 @@ this.TouchAdapter = {
target.removeEventListener('mousemove', this, true, true);
target.removeEventListener('mouseenter', this, true, true);
target.removeEventListener('mouseleave', this, true, true);
target.removeEventListener('mousedown', this, true, true);
target.removeEventListener('mouseup', this, true, true);
target.removeEventListener('click', this, true, true);
target.removeEventListener('touchend', this, true, true);
target.removeEventListener('touchmove', this, true, true);
@ -128,7 +122,9 @@ this.TouchAdapter = {
for (var i = 0; i < changedTouches.length; i++) {
let touch = changedTouches[i];
let touchPoint = new TouchPoint(touch, timeStamp, this._dpi);
this._touchPoints[touch.identifier || this.HOVER_ID] = touchPoint;
let identifier = (touch.identifier == undefined) ?
this.HOVER_ID : touch.identifier;
this._touchPoints[identifier] = touchPoint;
this._lastExploreTime = timeStamp + this.SWIPE_MAX_DURATION;
}
this._dwellTimeout = this.chromeWin.setTimeout(
@ -140,7 +136,9 @@ this.TouchAdapter = {
case 'touchmove':
for (var i = 0; i < changedTouches.length; i++) {
let touch = changedTouches[i];
let touchPoint = this._touchPoints[touch.identifier || this.HOVER_ID];
let identifier = (touch.identifier == undefined) ?
this.HOVER_ID : touch.identifier;
let touchPoint = this._touchPoints[identifier];
if (touchPoint)
touchPoint.update(touch, timeStamp);
}
@ -153,7 +151,9 @@ this.TouchAdapter = {
case 'touchend':
for (var i = 0; i < changedTouches.length; i++) {
let touch = changedTouches[i];
let touchPoint = this._touchPoints[touch.identifier || this.HOVER_ID];
let identifier = (touch.identifier == undefined) ?
this.HOVER_ID : touch.identifier;
let touchPoint = this._touchPoints[identifier];
if (touchPoint) {
touchPoint.update(touch, timeStamp);
touchPoint.finish();

View File

@ -7,6 +7,7 @@
#import "mozHTMLAccessible.h"
#import "Accessible-inl.h"
#import "HyperTextAccessible.h"
#import "nsCocoaUtils.h"

View File

@ -3,7 +3,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/. */
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "TextLeafAccessible.h"

View File

@ -5,6 +5,7 @@
#include "XULAlertAccessible.h"
#include "Accessible-inl.h"
#include "Role.h"
#include "States.h"

View File

@ -6,6 +6,7 @@
#include "XULTreeAccessible.h"
#include "Accessible-inl.h"
#include "DocAccessible-inl.h"
#include "nsAccCache.h"
#include "nsAccUtils.h"

View File

@ -615,3 +615,6 @@ pref("memory.free_dirty_pages", true);
// UAProfile settings
pref("wap.UAProf.url", "");
pref("wap.UAProf.tagname", "x-wap-profile");
// Wait up to this much milliseconds when orientation changed
pref("layers.orientation.sync.timeout", 1000);

View File

@ -64,14 +64,10 @@ let FormAssistant = {
},
setFocusedElement: function fa_setFocusedElement(element) {
if (element instanceof HTMLOptionElement)
element = element.parentNode;
if (element === this.focusedElement)
return;
if (this.focusedElement) {
this.focusedElement.removeEventListener('click', this);
this.focusedElement.removeEventListener('mousedown', this);
this.focusedElement.removeEventListener('mouseup', this);
if (!element) {
@ -80,7 +76,6 @@ let FormAssistant = {
}
if (element) {
element.addEventListener('click', this);
element.addEventListener('mousedown', this);
element.addEventListener('mouseup', this);
}
@ -97,17 +92,13 @@ let FormAssistant = {
if (this.isTextInputElement(target) && this.isIMEDisabled())
return;
// We got input focus, but don't open the virtual keyboard unless we
// get a 'click' event, i.e. the user is tapping the input element.
if (target && this.isFocusableElement(target)) {
this.setFocusedElement(target);
}
if (target && this.isFocusableElement(target))
this.showKeyboard(target);
break;
case "blur":
if (this.focusedElement)
this.hideKeyboard();
this.setFocusedElement(null);
break;
case 'mousedown':
@ -128,14 +119,6 @@ let FormAssistant = {
}
break;
case 'click':
// We only listen for click events on the currently focused element.
// Gecko fires a click event if the user "taps" an input element
// without dragging. This is how we differentiate tap gestures to set
// input focus (and open the keyboard) from simply panning the page.
this.showKeyboard();
break;
case "resize":
if (!this.isKeyboardOpened)
return;
@ -228,19 +211,24 @@ let FormAssistant = {
return disabled;
},
showKeyboard: function fa_showKeyboard() {
showKeyboard: function fa_showKeyboard(target) {
if (this.isKeyboardOpened)
return;
let target = this.focusedElement;
if (target instanceof HTMLOptionElement)
target = target.parentNode;
let kbOpened = this.sendKeyboardState(target);
if (this.isTextInputElement(target))
this.isKeyboardOpened = kbOpened;
this.setFocusedElement(target);
},
hideKeyboard: function fa_hideKeyboard() {
sendAsyncMessage("Forms:Input", { "type": "blur" });
this.isKeyboardOpened = false;
this.setFocusedElement(null);
},
isFocusableElement: function fa_isFocusableElement(element) {

View File

@ -741,10 +741,16 @@ var AlertsHelper = {
uid, name, null);
},
receiveMessage: function alert_receiveMessage(message) {
let data = message.data;
receiveMessage: function alert_receiveMessage(aMessage) {
if (!aMessage.target.assertPermission("desktop-notification")) {
Cu.reportError("Desktop-notification message " + aMessage.name +
" from a content process with no desktop-notification privileges.");
return null;
}
let data = aMessage.data;
let listener = {
mm: message.target,
mm: aMessage.target,
title: data.title,
text: data.text,
manifestURL: data.manifestURL,

View File

@ -120,6 +120,9 @@ ContentPermissionPrompt.prototype = {
let principal = request.principal;
let isApp = principal.appStatus != Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED;
let remember = principal.appStatus == Ci.nsIPrincipal.APP_STATUS_PRIVILEGED
? true
: request.remember;
let details = {
type: "permission-prompt",
@ -127,7 +130,7 @@ ContentPermissionPrompt.prototype = {
id: requestId,
origin: principal.origin,
isApp: isApp,
remember: request.remember
remember: remember
};
this._permission = access;

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1354916891000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1356125617000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -46,7 +46,7 @@
</versionRange>
</emItem>
<emItem blockID="i236" id="{EEE6C361-6118-11DC-9C72-001320C79847}">
<versionRange minVersion="0" maxVersion="*" severity="1">
<versionRange minVersion="0" maxVersion="1.7.999" severity="1">
</versionRange>
</emItem>
<emItem blockID="i64" id="royal@facebook.com">
@ -555,32 +555,16 @@
</versionRange>
</pluginItem>
<pluginItem blockID="p152">
<match name="filename" exp="npctrl\.dll" /> <versionRange minVersion="0" maxVersion="4.1.10328.0" severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="4.0" maxVersion="16.*" />
</targetApplication>
</versionRange>
<match name="filename" exp="npctrl\.dll" /> <versionRange minVersion="0" maxVersion="4.1.10328.0" severity="0" vulnerabilitystatus="1"></versionRange>
</pluginItem>
<pluginItem blockID="p154">
<match name="filename" exp="npctrl\.dll" /> <versionRange minVersion="5.0" maxVersion="5.1.10410.0" severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="4.0" maxVersion="16.*" />
</targetApplication>
</versionRange>
<match name="filename" exp="npctrl\.dll" /> <versionRange minVersion="5.0" maxVersion="5.1.10410.0" severity="0" vulnerabilitystatus="1"></versionRange>
</pluginItem>
<pluginItem blockID="p156">
<match name="filename" exp="nppdf32\.dll" /> <versionRange minVersion="0" maxVersion="9.5.1" severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="4.0" maxVersion="16.*" />
</targetApplication>
</versionRange>
<match name="filename" exp="nppdf32\.dll" /> <versionRange minVersion="0" maxVersion="9.5.1" severity="0" vulnerabilitystatus="1"></versionRange>
</pluginItem>
<pluginItem blockID="p158">
<match name="filename" exp="nppdf32\.dll" /> <versionRange minVersion="10.0" maxVersion="10.1.3" severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="4.0" maxVersion="16.*" />
</targetApplication>
</versionRange>
<match name="filename" exp="nppdf32\.dll" /> <versionRange minVersion="10.0" maxVersion="10.1.3" severity="0" vulnerabilitystatus="1"></versionRange>
</pluginItem>
<pluginItem blockID="p160">
<match name="filename" exp="NPSWF32\.dll" /> <versionRange minVersion="0" maxVersion="10.2.9999" severity="0" vulnerabilitystatus="1">
@ -606,42 +590,42 @@
<pluginItem blockID="p180">
<match name="filename" exp="JavaAppletPlugin\.plugin" /> <versionRange minVersion="Java 7 Update 07" maxVersion="Java 7 Update 08" severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="18.0a1" maxVersion="*" />
<versionRange minVersion="17.0" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p182">
<match name="name" exp="Java\(TM\) Platform SE 7 U[7-8](\s[^\d\._U]|$)" /> <match name="filename" exp="npjp2\.dll" /> <versionRange severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="18.0a1" maxVersion="*" />
<versionRange minVersion="17.0" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p184">
<match name="name" exp="Java\(TM\) Plug-in 1\.7\.0(_0?([7-8]))?([^\d\._]|$)" /> <match name="filename" exp="libnpjp2\.so" /> <versionRange severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="18.0a1" maxVersion="*" />
<versionRange minVersion="17.0" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p186">
<match name="name" exp="Java\(TM\) Platform SE 6 U3[3-6](\s[^\d\._U]|$)" /> <match name="filename" exp="npjp2\.dll" /> <versionRange severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="18.0a1" maxVersion="*" />
<versionRange minVersion="17.0" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p188">
<match name="filename" exp="JavaAppletPlugin\.plugin" /> <versionRange minVersion="Java 6 Update 0" maxVersion="Java 6 Update 36" severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="18.0a1" maxVersion="*" />
<versionRange minVersion="17.0" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p190">
<match name="name" exp="Java\(TM\) Plug-in 1\.6\.0_3[3-6]([^\d\._]|$)" /> <match name="filename" exp="libnpjp2\.so" /> <versionRange severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="18.0a1" maxVersion="*" />
<versionRange minVersion="17.0" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
@ -666,6 +650,16 @@
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p240">
<match name="filename" exp="DivXBrowserPlugin\.plugin" /> <versionRange minVersion="0" maxVersion="1.4" severity="1"></versionRange>
</pluginItem>
<pluginItem os="Darwin" blockID="p242">
<match name="description" exp="Flip4Mac" /> <versionRange minVersion="0" maxVersion="2.4.3.999" severity="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="18.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
</pluginItems>
<gfxItems>

View File

@ -1035,7 +1035,6 @@ pref("devtools.debugger.remote-connection-retries", 3);
pref("devtools.debugger.remote-timeout", 20000);
// The default Debugger UI settings
pref("devtools.debugger.ui.height", 250);
pref("devtools.debugger.ui.win-x", 0);
pref("devtools.debugger.ui.win-y", 0);
pref("devtools.debugger.ui.win-width", 900);

View File

@ -147,7 +147,8 @@
</menupopup>
</splitmenu>
<menuseparator class="appmenu-menuseparator"/>
<menu id="appmenu_webDeveloper"
<splitmenu id="appmenu_webDeveloper"
command="Tools:DevToolbox"
label="&appMenuWebDeveloper.label;">
<menupopup id="appmenu_webDeveloper_popup">
<menuitem id="appmenu_devToolbox"
@ -165,7 +166,6 @@
observes="devtoolsMenuBroadcaster_PageSource"/>
<menuitem id="appmenu_errorConsole"
observes="devtoolsMenuBroadcaster_ErrorConsole"/>
<menuseparator id="appmenu_devToolsConnectSeparator"/>
<menuitem id="appmenu_devtools_connect"
observes="devtoolsMenuBroadcaster_connect"/>
<menuseparator id="appmenu_devToolsEndSeparator"/>
@ -182,7 +182,7 @@
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
</menupopup>
</menu>
</splitmenu>
<menuseparator class="appmenu-menuseparator"/>
#define ID_PREFIX appmenu_
#define OMIT_ACCESSKEYS

View File

@ -584,7 +584,6 @@
<menuitem id="javascriptConsole"
observes="devtoolsMenuBroadcaster_ErrorConsole"
accesskey="&errorConsoleCmd.accesskey;"/>
<menuseparator id="menu_devToolsConnectSeparator"/>
<menuitem id="menu_devtools_connect"
observes="devtoolsMenuBroadcaster_connect"/>
<menuseparator id="devToolsEndSeparator"/>

View File

@ -440,7 +440,7 @@ var PlacesCommandHook = {
* @param aLeftPaneRoot
* The query to select in the organizer window - options
* are: History, AllBookmarks, BookmarksMenu, BookmarksToolbar,
* UnfiledBookmarks and Tags.
* UnfiledBookmarks, Tags and Downloads.
*/
showPlacesOrganizer: function PCH_showPlacesOrganizer(aLeftPaneRoot) {
var organizer = Services.wm.getMostRecentWindow("Places:Organizer");

View File

@ -97,7 +97,7 @@
<command id="Tools:ResponsiveUI" oncommand="ResponsiveUI.toggle();" disabled="true" hidden="true"/>
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
<command id="Tools:ErrorConsole" oncommand="toJavaScriptConsole()" disabled="true" hidden="true"/>
<command id="Tools:DevToolsConnect" oncommand="gDevToolsBrowser.openConnectScreen(gBrowser)"/>
<command id="Tools:DevToolsConnect" oncommand="gDevToolsBrowser.openConnectScreen(gBrowser)" disabled="true" hidden="true"/>
<command id="Tools:Sanitize"
oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
<command id="Tools:PrivateBrowsing"
@ -351,12 +351,10 @@
<key id="sharePage" key="&sharePageCmd.commandkey;" command="Social:SharePage" modifiers="accel,shift"/>
<key id="focusChatBar" key="&social.chatBar.commandkey;" command="Social:FocusChat" modifiers="accel,shift"/>
# don't use |command="Browser:Stop"|, ESC is being used to freeze animated gifs,
# even if the stop button and menuitem are disabled (see Bug 284140)
<key id="key_stop" keycode="VK_ESCAPE" oncommand="BrowserStop();"/>
<key id="key_stop" keycode="VK_ESCAPE" command="Browser:Stop"/>
#ifdef XP_MACOSX
<key id="key_stop_mac" modifiers="accel" key="&stopCmd.macCommandKey;" oncommand="BrowserStop();"/>
<key id="key_stop_mac" modifiers="accel" key="&stopCmd.macCommandKey;" command="Browser:Stop"/>
#endif
<key id="key_gotoHistory"

View File

@ -1444,6 +1444,14 @@ var gBrowserInit = {
cmd.removeAttribute("hidden");
}
// Enable DevTools connection screen, if the preference allows this.
let devtoolsRemoteEnabled = gPrefService.getBoolPref("devtools.debugger.remote-enabled");
if (devtoolsRemoteEnabled) {
let cmd = document.getElementById("Tools:DevToolsConnect");
cmd.removeAttribute("disabled");
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,
@ -1754,6 +1762,7 @@ function HandleAppCommandEvent(evt) {
BrowserReloadSkipCache();
break;
case "Stop":
if (XULBrowserWindow.stopCommand.getAttribute("disabled") != "true")
BrowserStop();
break;
case "Search":

View File

@ -44,7 +44,6 @@
windowtype="navigator:browser"
macanimationtype="document"
screenX="4" screenY="4"
browsingmode="normal"
fullscreenbutton="true"
persist="screenX screenY width height sizemode">
@ -444,6 +443,27 @@
<label class="tooltip-label" value="&backForwardButtonMenu.tooltip;"/>
#endif
</tooltip>
<popupnotification id="webRTC-shareDevices-notification" hidden="true">
<popupnotificationcontent id="webRTC-selectCamera" orient="vertical">
<separator class="thin"/>
<label value="&getUserMedia.selectCamera.label;"
accesskey="&getUserMedia.selectCamera.accesskey;"
control="webRTC-selectCamera-menulist"/>
<menulist id="webRTC-selectCamera-menulist">
<menupopup id="webRTC-selectCamera-menupopup"/>
</menulist>
</popupnotificationcontent>
<popupnotificationcontent id="webRTC-selectMicrophone" orient="vertical">
<separator class="thin"/>
<label value="&getUserMedia.selectMicrophone.label;"
accesskey="&getUserMedia.selectMicrophone.accesskey;"
control="webRTC-selectMicrophone-menulist"/>
<menulist id="webRTC-selectMicrophone-menulist">
<menupopup id="webRTC-selectMicrophone-menupopup"/>
</menulist>
</popupnotificationcontent>
</popupnotification>
</popupset>
#ifdef CAN_DRAW_IN_TITLEBAR

View File

@ -88,11 +88,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=377611
var feeds = [];
for each (var aFeed in discovered) {
for (var aFeed of discovered) {
feeds[aFeed.href] = true;
}
for each (var aLink in document.getElementsByTagName("link")) {
for (var aLink of document.getElementsByTagName("link")) {
// ignore real stylesheets, and anything without an href property
if (aLink.type != "text/css" && aLink.href) {
if (/bogus/i.test(aLink.title)) {

View File

@ -12,7 +12,6 @@ include $(DEPTH)/config/autoconf.mk
_BROWSER_FILES = \
head.js \
browser_social.js \
browser_social_toolbar.js \
browser_social_shareButton.js \
browser_social_sidebar.js \
@ -30,6 +29,12 @@ _BROWSER_FILES = \
social_worker.js \
$(NULL)
ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
_BROWSER_FILES += \
browser_social.js \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk
libs:: $(_BROWSER_FILES)

View File

@ -16,6 +16,7 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/DownloadUtils.jsm");
Cu.import("resource:///modules/DownloadsCommon.jsm");
Cu.import("resource://gre/modules/PlacesUtils.jsm");
const nsIDM = Ci.nsIDownloadManager;
@ -29,6 +30,8 @@ const DOWNLOAD_VIEW_SUPPORTED_COMMANDS =
"downloadsCmd_open", "downloadsCmd_show", "downloadsCmd_retry",
"downloadsCmd_openReferrer"];
const NOT_AVAILABLE = Number.MAX_VALUE;
function GetFileForFileURI(aFileURI)
Cc["@mozilla.org/network/protocol;1?name=file"]
.getService(Ci.nsIFileProtocolHandler)
@ -60,14 +63,18 @@ function GetFileForFileURI(aFileURI)
* The data item of a the session download. Required if aPlacesNode is not set
* @param [optional] aPlacesNode
* The places node for a past download. Required if aDataItem is not set.
* @param [optional] aAnnotations
* Map containing annotations values, to speed up the initial loading.
*/
function DownloadElementShell(aDataItem, aPlacesNode) {
function DownloadElementShell(aDataItem, aPlacesNode, aAnnotations) {
this._element = document.createElement("richlistitem");
this._element._shell = this;
this._element.classList.add("download");
this._element.classList.add("download-state");
if (aAnnotations)
this._annotations = aAnnotations;
if (aDataItem)
this.dataItem = aDataItem;
if (aPlacesNode)
@ -79,10 +86,11 @@ DownloadElementShell.prototype = {
get element() this._element,
// The data item for the download
_dataItem: null,
get dataItem() this._dataItem,
set dataItem(aValue) {
if (this._dataItem = aValue) {
if ((this._dataItem = aValue)) {
this._wasDone = this._dataItem.done;
this._wasInProgress = this._dataItem.inProgress;
}
@ -95,10 +103,15 @@ DownloadElementShell.prototype = {
return aValue;
},
_placesNode: null,
get placesNode() this._placesNode,
set placesNode(aNode) {
if (this._placesNode != aNode) {
// Preserve the annotations map if this is the first loading and we got
// cached values.
if (this._placesNode || !this._annotations) {
this._annotations = new Map();
}
this._placesNode = aNode;
if (!this._dataItem && this._placesNode) {
this._wasInProgress = false;
@ -136,21 +149,30 @@ DownloadElementShell.prototype = {
// Helper for getting a places annotation set for the download.
_getAnnotation: function DES__getAnnotation(aAnnotation, aDefaultValue) {
if (this._annotations.has(aAnnotation))
return this._annotations.get(aAnnotation);
let value;
if (this._annotations.has(aAnnotation))
value = this._annotations.get(aAnnotation);
// If the value is cached, or we know it doesn't exist, avoid a database
// lookup.
if (value === undefined) {
try {
value = PlacesUtils.annotations.getPageAnnotation(
this._downloadURIObj, aAnnotation);
}
catch(ex) {
value = NOT_AVAILABLE;
}
}
if (value === NOT_AVAILABLE) {
if (aDefaultValue === undefined) {
throw new Error("Could not get required annotation '" + aAnnotation +
"' for download with url '" + this.downloadURI + "'");
}
value = aDefaultValue;
}
this._annotations.set(aAnnotation, value);
return value;
},
@ -427,6 +449,7 @@ DownloadElementShell.prototype = {
case "downloadsCmd_cancel":
return this._dataItem != null;
}
return false;
},
_getTargetFileOrPartFileIfExists: function DES__getTargetFileOrPartFileIfExists() {
@ -522,6 +545,7 @@ DownloadElementShell.prototype = {
case nsIDM.DOWNLOAD_BLOCKED_POLICY:
return "downloadsCmd_openReferrer";
}
return "";
}
let command = getDefaultCommandForState(this._state);
if (this.isCommandEnabled(command))
@ -583,6 +607,38 @@ DownloadsPlacesView.prototype = {
}
},
_getAnnotationsFor: function DPV_getAnnotationsFor(aURI) {
if (!this._cachedAnnotations) {
this._cachedAnnotations = new Map();
for (let name of [ DESTINATION_FILE_URI_ANNO,
DESTINATION_FILE_NAME_ANNO,
DOWNLOAD_STATE_ANNO ]) {
let results = PlacesUtils.annotations.getAnnotationsWithName(name);
for (let result of results) {
let url = result.uri.spec;
if (!this._cachedAnnotations.has(url))
this._cachedAnnotations.set(url, new Map());
let m = this._cachedAnnotations.get(url);
m.set(result.annotationName, result.annotationValue);
}
}
}
let annotations = this._cachedAnnotations.get(aURI);
if (!annotations) {
// There are no annotations for this entry, that means it is quite old.
// Make up a fake annotations entry with default values.
annotations = new Map();
annotations.set(DESTINATION_FILE_URI_ANNO, NOT_AVAILABLE);
annotations.set(DESTINATION_FILE_NAME_ANNO, NOT_AVAILABLE);
}
// The state annotation has been added recently, so it's likely missing.
if (!annotations.has(DOWNLOAD_STATE_ANNO)) {
annotations.set(DOWNLOAD_STATE_ANNO, NOT_AVAILABLE);
}
return annotations;
},
/**
* Given a data item for a session download, or a places node for a past
* download, updates the view as necessary.
@ -611,7 +667,8 @@ DownloadsPlacesView.prototype = {
* to the richlistbox at the end.
*/
_addDownloadData:
function DPV_addDownload(aDataItem, aPlacesNode, aNewest = false, aDocumentFragment = null) {
function DPV_addDownloadData(aDataItem, aPlacesNode, aNewest = false,
aDocumentFragment = null) {
let downloadURI = aPlacesNode ? aPlacesNode.uri : aDataItem.uri;
let shellsForURI = this._downloadElementsShellsForURI.get(downloadURI, null);
if (!shellsForURI) {
@ -657,9 +714,9 @@ DownloadsPlacesView.prototype = {
}
if (shouldCreateShell) {
let shell = new DownloadElementShell(aDataItem, aPlacesNode);
let shell = new DownloadElementShell(aDataItem, aPlacesNode,
this._getAnnotationsFor(downloadURI));
newOrUpdatedShell = shell;
element = shell.element;
shellsForURI.add(shell);
if (aDataItem)
this._viewItemsForDataItems.set(aDataItem, shell);
@ -762,8 +819,8 @@ DownloadsPlacesView.prototype = {
}
},
_place: "",
get place() this._place,
set place(val) {
// Don't reload everything if we don't have to.
if (this._place == val) {
@ -786,6 +843,7 @@ DownloadsPlacesView.prototype = {
return val;
},
_result: null,
get result() this._result,
set result(val) {
if (this._result == val)
@ -1022,6 +1080,7 @@ DownloadsPlacesView.prototype = {
// Set the state attribute so that only the appropriate items are displayed.
let contextMenu = document.getElementById("downloadsContextMenu");
contextMenu.setAttribute("state", element._shell._state);
return true;
},
onKeyPress: function DPV_onKeyPress(aEvent) {

View File

@ -21,13 +21,14 @@
<richlistbox id="downloadsRichListBox"/>
<commandset id="downloadCommands"/>
<menupopup id="downloadsContextMenu"/>
3. Make sure your window also has the editMenuOverlay overlay applied,
3. Make sure your window has the editMenuOverlay overlay applied,
because the view implements cmd_copy and cmd_delete.
4. To initialize the view
4. Make sure your window has the globalOverlay.js script loaded.
5. To initialize the view
let view = new DownloadsPlacesView(document.getElementById("downloadsRichListBox"));
// This is what the Places Library uses. It could be tweaked a bit as long as the
// transition-type is set correctly
view.places = "place:transition=7&sort=4";
view.place = "place:transition=7&sort=4";
-->
<overlay id="downloadsViewOverlay"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

View File

@ -0,0 +1,10 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
let ContentAreaDownloadsView = {
init: function CADV_init() {
let view = new DownloadsPlacesView(document.getElementById("downloadsRichListBox"));
view.place = "place:transition=7&sort=4";
}
};

View File

@ -0,0 +1,32 @@
<?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/.
<?xml-stylesheet href="chrome://global/skin/"?>
<?xul-overlay href="chrome://browser/content/downloads/allDownloadsViewOverlay.xul"?>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
<window id="contentAreaDownloadsView"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="ContentAreaDownloadsView.init();">
<script type="application/javascript"
src="chrome://global/content/globalOverlay.js"/>
<script type="application/javascript"
src="chrome://browser/content/downloads/contentAreaDownloadsView.js"/>
<commandset id="editMenuCommands"/>
<keyset id="editMenuKeys">
#ifdef XP_MACOSX
<key id="key_delete2" keycode="VK_BACK" command="cmd_delete"/>
#endif
</keyset>
<richlistbox id="downloadsRichListBox"/>
<commandset id="downloadCommands"/>
<menupopup id="downloadsContextMenu"/>
</window>

View File

@ -41,5 +41,5 @@ richlistitem.download button {
.download-state:not( [state="1"] /* Finished */)
.downloadShow
{
visibility: hidden;
display: none;
}

View File

@ -84,17 +84,17 @@
crop="end"
xbl:inherits="value=status,tooltiptext=statusTip"/>
</xul:vbox>
<xul:stack>
<xul:button class="downloadButton downloadCancel"
command="downloadsCmd_cancel"
oncommand="goDoCommand('downloadsCmd_cancel')"
tooltiptext="&cmd.cancel.label;"/>
<xul:button class="downloadButton downloadRetry"
command="downloadsCmd_retry"
oncommand="goDoCommand('downloadsCmd_retry')"
tooltiptext="&cmd.retry.label;"/>
<xul:button class="downloadButton downloadShow"
command="downloadsCmd_show"
oncommand="goDoCommand('downloadsCmd_show')"
tooltiptext="&cmd.show.label;"/>
</xul:stack>
</content>
</binding>
</bindings>

View File

@ -13,3 +13,5 @@ browser.jar:
* content/browser/downloads/allDownloadsViewOverlay.xul (content/allDownloadsViewOverlay.xul)
content/browser/downloads/allDownloadsViewOverlay.js (content/allDownloadsViewOverlay.js)
content/browser/downloads/allDownloadsViewOverlay.css (content/allDownloadsViewOverlay.css)
* content/browser/downloads/contentAreaDownloadsView.xul (content/contentAreaDownloadsView.xul)
content/browser/downloads/contentAreaDownloadsView.js (content/contentAreaDownloadsView.js)

View File

@ -30,6 +30,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
XPCOMUtils.defineLazyServiceGetter(this, "gBrowserGlue",
"@mozilla.org/browser/browserglue;1",
"nsIBrowserGlue");
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
"resource:///modules/RecentWindow.jsm");
////////////////////////////////////////////////////////////////////////////////
//// DownloadsUI
@ -72,25 +74,29 @@ DownloadsUI.prototype = {
let browserWin = gBrowserGlue.getMostRecentBrowserWindow();
if (!browserWin || browserWin.windowState == kMinimized) {
this._toolkitUI.show(aWindowContext, aID, aReason);
this._showDownloadManagerUI(aWindowContext, aID, aReason);
}
else {
// If the indicator is visible, then new download notifications are
// already handled by the panel service.
browserWin.DownloadsButton.checkIsVisible(function(isVisible) {
if (!isVisible) {
this._toolkitUI.show(aWindowContext, aID, aReason);
this._showDownloadManagerUI(aWindowContext, aID, aReason);
}
}.bind(this));
}
} else {
this._toolkitUI.show(aWindowContext, aID, aReason);
this._showDownloadManagerUI(aWindowContext, aID, aReason);
}
},
get visible()
{
return this._toolkitUI.visible;
// If we're still using the toolkit downloads manager, delegate the call
// to it. Otherwise, return true for now, until we decide on how we want
// to indicate that a new download has started if a browser window is
// not available or minimized.
return DownloadsCommon.useToolkitUI ? this._toolkitUI.visible : true;
},
getAttention: function DUI_getAttention()
@ -98,6 +104,54 @@ DownloadsUI.prototype = {
if (DownloadsCommon.useToolkitUI) {
this._toolkitUI.getAttention();
}
},
/**
* Helper function that opens the right download manager UI. Either the
* new Downloads View in Places, or the toolkit download window if the
* Places Downloads View is not enabled.
*/
_showDownloadManagerUI:
function DUI_showDownloadManagerUI(aWindowContext, aID, aReason)
{
// First, determine if the Places Downloads view is preffed on.
let usePlacesView = false;
try {
usePlacesView =
Services.prefs.getBoolPref("browser.library.useNewDownloadsView");
} catch(e) {}
if (!usePlacesView) {
// If we got here, then the browser.library.useNewDownloadsView pref
// either didn't exist or was false, so just show the toolkit downloads
// manager.
this._toolkitUI.show(aWindowContext, aID, aReason);
return;
}
let organizer = Services.wm.getMostRecentWindow("Places:Organizer");
if (!organizer) {
let parentWindow = aWindowContext;
// If we weren't given a window context, try to find a browser window
// to use as our parent - and if that doesn't work, error out and give
// up.
if (!parentWindow) {
parentWindow = RecentWindow.getMostRecentBrowserWindow();
if (!parentWindow) {
Components.utils
.reportError("Couldn't find a browser window to open " +
"the Places Downloads View from.");
return;
}
}
parentWindow.openDialog("chrome://browser/content/places/places.xul",
"", "chrome,toolbar=yes,dialog=no,resizable",
"Downloads");
}
else {
organizer.PlacesOrganizer.selectLeftPaneQuery("Downloads");
organizer.focus();
}
}
};

View File

@ -141,8 +141,11 @@ PlacesController.prototype = {
case "placesCmd_delete":
return this._hasRemovableSelection(false);
case "placesCmd_deleteDataHost":
return this._hasRemovableSelection(false) &&
!PlacesUIUtils.privateBrowsing.privateBrowsingEnabled;
return this._hasRemovableSelection(false)
#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
&& !PlacesUIUtils.privateBrowsing.privateBrowsingEnabled
#endif
;
case "placesCmd_moveBookmarks":
return this._hasRemovableSelection(true);
case "cmd_copy":
@ -601,8 +604,12 @@ PlacesController.prototype = {
// We allow pasting into tag containers, so special case that.
var hideIfNoIP = item.getAttribute("hideifnoinsertionpoint") == "true" &&
noIp && !(ip && ip.isTag && item.id == "placesContext_paste");
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
var hideIfPB = false;
#else
var hideIfPB = item.getAttribute("hideifprivatebrowsing") == "true" &&
PlacesUIUtils.privateBrowsing.privateBrowsingEnabled;
#endif
item.hidden = hideIfNoIP || hideIfPB ||
!this._shouldShowMenuItem(item, metadata);

View File

@ -15,7 +15,7 @@ browser.jar:
content/browser/places/placesOverlay.xul (content/placesOverlay.xul)
* content/browser/places/menu.xml (content/menu.xml)
content/browser/places/tree.xml (content/tree.xml)
content/browser/places/controller.js (content/controller.js)
* content/browser/places/controller.js (content/controller.js)
content/browser/places/treeView.js (content/treeView.js)
* content/browser/places/browserPlacesViews.js (content/browserPlacesViews.js)
# keep the Places version of the history sidebar at history/history-panel.xul

View File

@ -15,7 +15,7 @@ EXTRA_COMPONENTS = \
PlacesProtocolHandler.js \
$(NULL)
EXTRA_JS_MODULES = \
EXTRA_PP_JS_MODULES = \
PlacesUIUtils.jsm \
$(NULL)

View File

@ -1009,9 +1009,11 @@ XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ellipsis", function() {
Ci.nsIPrefLocalizedString).data;
});
#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
XPCOMUtils.defineLazyServiceGetter(PlacesUIUtils, "privateBrowsing",
"@mozilla.org/privatebrowsing;1",
"nsIPrivateBrowsingService");
#endif
XPCOMUtils.defineLazyServiceGetter(this, "URIFixup",
"@mozilla.org/docshell/urifixup;1",

View File

@ -54,7 +54,7 @@ function test() {
PO._places.selectNode(histContainer.getChild(0));
// Select the first history entry.
let doc = organizer.document;
let tree = PO._content;
let tree = organizer.ContentTree.view;
let selection = tree.view.selection;
selection.clearSelection();
selection.rangedSelect(0, 0, true);

View File

@ -13,9 +13,10 @@ include $(topsrcdir)/config/config.mk
EXTRA_COMPONENTS = \
nsSessionStore.manifest \
nsSessionStore.js \
nsSessionStartup.js \
$(NULL)
EXTRA_PP_COMPONENTS := nsSessionStartup.js
JS_MODULES_PATH := $(FINAL_TARGET)/modules/sessionstore
EXTRA_JS_MODULES := \

View File

@ -73,11 +73,15 @@ SessionStartup.prototype = {
init: function sss_init() {
debug("init starting");
// do not need to initialize anything in auto-started private browsing sessions
if (PrivateBrowsingUtils.permanentPrivateBrowsing)
return;
#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
let pbs = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
if (PrivateBrowsingUtils.permanentPrivateBrowsing ||
pbs.lastChangedByCommandLine)
if (pbs.lastChangedByCommandLine)
return;
#endif
// Session state is unknown until we read the file.
this._sessionType = null;
_SessionFile.read().then(

View File

@ -7,9 +7,6 @@ function test() {
waitForExplicitFinish();
let pb = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
// set the pref to 1 greater than it currently is so we have room for an extra
// closed window
let closedWindowCount = ss.getClosedWindowCount();

View File

@ -173,12 +173,6 @@ DebuggerUI.prototype = {
return '_chromeDebugger' in this ? this._chromeDebugger : null;
},
/**
* Get the preferences associated with the debugger frontend.
* @return object
*/
get preferences() Prefs,
/**
* Currently, there can only be one debugger per tab.
* Show an asynchronous notification which asks the user to switch the
@ -279,7 +273,6 @@ DebuggerPane.prototype = {
this._splitter.setAttribute("class", "devtools-horizontal-splitter");
this._frame = ownerDocument.createElement("iframe");
this._frame.height = Prefs.height;
this._nbox = gBrowser.getNotificationBox(this._tab.linkedBrowser);
this._nbox.appendChild(this._splitter);
@ -326,7 +319,6 @@ DebuggerPane.prototype = {
}, true)
}
Prefs.height = this._frame.height;
this._frame.removeEventListener("Debugger:Unloaded", this.close, true);
this._nbox.removeChild(this._splitter);
this._nbox.removeChild(this._frame);
@ -599,21 +591,7 @@ XPCOMUtils.defineLazyGetter(L10N, "stringBundle", function() {
/**
* Shortcuts for accessing various debugger preferences.
*/
let Prefs = {
/**
* Gets the preferred height of the debugger pane.
* @return number
*/
get height()
Services.prefs.getIntPref("devtools.debugger.ui.height"),
/**
* Sets the preferred height of the debugger pane.
* @param number aValue
*/
set height(aValue)
Services.prefs.setIntPref("devtools.debugger.ui.height", aValue)
};
let Prefs = {};
/**
* Gets the preferred default remote debugging host.

View File

@ -11,6 +11,7 @@ const Cu = Components.utils;
const DBG_STRINGS_URI = "chrome://browser/locale/devtools/debugger.properties";
const NEW_SCRIPT_DISPLAY_DELAY = 200; // ms
const FETCH_SOURCE_RESPONSE_DELAY = 50; // ms
const FRAME_STEP_CLEAR_DELAY = 100; // ms
const CALL_STACK_PAGE_SIZE = 25; // frames
@ -1166,6 +1167,7 @@ SourceScripts.prototype = {
DebuggerView.Sources.push(label, url, {
forced: aOptions.forced,
tooltip: url,
attachment: aSource
});
},
@ -1177,18 +1179,29 @@ SourceScripts.prototype = {
* The source object coming from the active thread.
* @param function aCallback
* Function called after the source text has been loaded.
* @param function aOnTimeout
* Function called when the source text takes too long to fetch.
*/
getText: function SS_getText(aSource, aCallback) {
getText: function SS_getText(aSource, aCallback, aOnTimeout) {
// If already loaded, return the source text immediately.
if (aSource.loaded) {
aCallback(aSource.url, aSource.text);
return;
}
// If the source text takes too long to fetch, invoke a timeout to
// avoid blocking any operations.
if (aOnTimeout) {
var fetchTimeout = window.setTimeout(aOnTimeout, FETCH_SOURCE_RESPONSE_DELAY);
}
// Get the source text from the active thread.
this.activeThread.source(aSource.source).source(function(aResponse) {
window.clearTimeout(fetchTimeout);
if (aResponse.error) {
Cu.reportError("Error loading " + aUrl);
Cu.reportError("Error loading " + aSource.url + "\n" + aResponse.error);
aCallback(aSource.url, "");
return;
}
aSource.loaded = true;
@ -1609,7 +1622,6 @@ let Prefs = {
}
};
Prefs.map("Int", "height", "devtools.debugger.ui.height");
Prefs.map("Int", "windowX", "devtools.debugger.ui.win-x");
Prefs.map("Int", "windowY", "devtools.debugger.ui.win-y");
Prefs.map("Int", "windowWidth", "devtools.debugger.ui.win-width");

View File

@ -1260,6 +1260,7 @@ function GlobalSearchView() {
MenuContainer.call(this);
this._startSearch = this._startSearch.bind(this);
this._onFetchSourceFinished = this._onFetchSourceFinished.bind(this);
this._onFetchSourceTimeout = this._onFetchSourceTimeout.bind(this);
this._onFetchSourcesFinished = this._onFetchSourcesFinished.bind(this);
this._createItemView = this._createItemView.bind(this);
this._onScroll = this._onScroll.bind(this);
@ -1402,25 +1403,29 @@ create({ constructor: GlobalSearchView, proto: MenuContainer.prototype }, {
this._sourcesCount = locations.length;
this._searchedToken = aQuery;
this._fetchSources(
this._onFetchSourceFinished,
this._onFetchSourcesFinished, locations);
this._fetchSources(locations, {
onFetch: this._onFetchSourceFinished,
onTimeout: this._onFetchSourceTimeout,
onFinished: this._onFetchSourcesFinished
});
},
/**
* Starts fetching all the sources, silently.
*
* @param function aFetchCallback
* Called after each source is fetched.
* @param function aFetchedCallback
* Called if all the sources were already fetched.
* @param array aLocations
* The locations for the sources to fetch.
* @param object aCallbacks
* An object containing the callback functions to invoke:
* - onFetch: called after each source is fetched
* - onTimeout: called when a source's text takes too long to fetch
* - onFinished: called if all the sources were already fetched
*/
_fetchSources: function DVGS__fetchSources(aFetchCallback, aFetchedCallback, aLocations) {
_fetchSources:
function DVGS__fetchSources(aLocations, { onFetch, onTimeout, onFinished }) {
// If all the sources were already fetched, then don't do anything.
if (this._cache.size == aLocations.length) {
aFetchedCallback();
onFinished();
return;
}
@ -1430,7 +1435,8 @@ create({ constructor: GlobalSearchView, proto: MenuContainer.prototype }, {
continue;
}
let sourceItem = DebuggerView.Sources.getItemByValue(location);
DebuggerController.SourceScripts.getText(sourceItem.attachment, aFetchCallback);
let sourceObject = sourceItem.attachment;
DebuggerController.SourceScripts.getText(sourceObject, onFetch, onTimeout);
}
},
@ -1452,10 +1458,24 @@ create({ constructor: GlobalSearchView, proto: MenuContainer.prototype }, {
}
},
/**
* Called when a source's text takes too long to fetch.
*/
_onFetchSourceTimeout: function DVGS__onFetchSourceTimeout() {
// Remove the source from the load queue.
this._sourcesCount--;
// Check if the remaining sources were fetched and stored in the cache.
if (this._cache.size == this._sourcesCount) {
this._onFetchSourcesFinished();
}
},
/**
* Called when all the sources have been fetched.
*/
_onFetchSourcesFinished: function DVGS__onFetchSourcesFinished() {
// At least one source needs to be present to perform a global search.
if (!this._sourcesCount) {
return;
}

View File

@ -11,7 +11,6 @@
*/
function ToolbarView() {
dumpn("ToolbarView was instantiated");
this._onCloseClick = this._onCloseClick.bind(this);
this._onTogglePanesPressed = this._onTogglePanesPressed.bind(this);
this._onResumePressed = this._onResumePressed.bind(this);
this._onStepOverPressed = this._onStepOverPressed.bind(this);
@ -108,13 +107,6 @@ ToolbarView.prototype = {
this._sources.setAttribute("hidden", !aVisibleFlag);
},
/**
* Listener handling the close button click event.
*/
_onCloseClick: function DVT__onCloseClick() {
DebuggerController._shutdownDebugger();
},
/**
* Listener handling the toggle button click event.
*/

View File

@ -618,6 +618,7 @@ MenuContainer.prototype = {
* - unsorted: true if the items should not always remain sorted
* - relaxed: true if this container should allow dupes & degenerates
* - description: an optional description of the item
* - tooltip: an optional tooltip for the item
* - attachment: some attached primitive/object
* @return MenuItem
* The item associated with the displayed element if a forced push,
@ -629,7 +630,7 @@ MenuContainer.prototype = {
// Batch the item to be added later.
if (!aOptions.forced) {
this._stagedItems.push(item);
this._stagedItems.push({ item: item, options: aOptions });
}
// Immediately insert the item at the specified index.
else if (aOptions.forced && aOptions.forced.atIndex !== undefined) {
@ -657,11 +658,12 @@ MenuContainer.prototype = {
// By default, sort the items before adding them to this container.
if (!aOptions.unsorted) {
stagedItems.sort(function(a, b) a.label.toLowerCase() > b.label.toLowerCase());
stagedItems.sort(function(a, b) a.item.label.toLowerCase() >
b.item.label.toLowerCase());
}
// Append the prepared items to this container.
for (let item of stagedItems) {
this._appendItem(item, aOptions);
for (let { item, options } of stagedItems) {
this._appendItem(item, options);
}
// Recreate the temporary items list for ulterior pushes.
this._stagedItems = [];
@ -750,7 +752,7 @@ MenuContainer.prototype = {
*/
containsLabel: function DVMC_containsLabel(aLabel) {
return this._itemsByLabel.has(aLabel) ||
this._stagedItems.some(function(o) o.label == aLabel);
this._stagedItems.some(function({item}) item.label == aLabel);
},
/**
@ -764,7 +766,7 @@ MenuContainer.prototype = {
*/
containsValue: function DVMC_containsValue(aValue) {
return this._itemsByValue.has(aValue) ||
this._stagedItems.some(function(o) o.value == aValue);
this._stagedItems.some(function({item}) item.value == aValue);
},
/**
@ -788,7 +790,7 @@ MenuContainer.prototype = {
return true;
}
}
return this._stagedItems.some(function(o) aTrim(o.value) == trimmedValue);
return this._stagedItems.some(function({item}) aTrim(item.value) == trimmedValue);
},
/**
@ -1046,8 +1048,15 @@ MenuContainer.prototype = {
return null;
}
return this._entangleItem(aItem, this._container.appendItem(
this._entangleItem(aItem, this._container.appendItem(
aItem.label, aItem.value, "", aOptions.attachment));
// Handle any additional options after entangling the item.
if (aOptions.tooltip) {
aItem._target.setAttribute("tooltiptext", aOptions.tooltip);
}
return aItem;
},
/**
@ -1068,8 +1077,15 @@ MenuContainer.prototype = {
return null;
}
return this._entangleItem(aItem, this._container.insertItemAt(
this._entangleItem(aItem, this._container.insertItemAt(
aIndex, aItem.label, aItem.value, "", aOptions.attachment));
// Handle any additional options after entangling the item.
if (aOptions.tooltip) {
aItem._target.setAttribute("tooltiptext", aOptions.tooltip);
}
return aItem;
},
/**

View File

@ -114,6 +114,16 @@ ToolSidebar.prototype = {
return currentID;
},
/**
* Returns the requested tab based on the id.
*
* @param String id
* unique id of the requested tab.
*/
getTab: function ToolSidebar_getTab(id) {
return this._tabbox.tabpanels.querySelector("#sidebar-panel-" + id);
},
/**
* Event handler.
*/
@ -176,7 +186,7 @@ ToolSidebar.prototype = {
}
this._destroyed = true;
this._tabbox.removeEventListener("select", this, true);
this._tabbox.tabpanels.removeEventListener("select", this, true);
while (this._tabbox.tabpanels.hasChildNodes()) {
this._tabbox.tabpanels.removeChild(this._tabbox.tabpanels.firstChild);

View File

@ -295,9 +295,10 @@ TabWebProgressListener.prototype = {
onSecurityChange: function() {},
onStatusChange: function() {},
onLocationChange: function TwPL_onLocationChange(webProgress) {
onLocationChange: function TwPL_onLocationChange(webProgress, request, URI, flags) {
if (this.target &&
!(flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT)) {
let window = webProgress.DOMWindow;
if (this.target) {
this.target.emit("navigate", window);
}
},

View File

@ -69,6 +69,8 @@ let webConsoleDefinition = {
icon: "chrome://browser/skin/devtools/webconsole-tool-icon.png",
url: "chrome://browser/content/devtools/webconsole.xul",
label: l10n("ToolboxWebconsole.label", webConsoleStrings),
tooltip: l10n("ToolboxWebconsole.tooltip", webConsoleStrings),
isTargetSupported: function(target) {
return true;
},
@ -88,6 +90,7 @@ let debuggerDefinition = {
icon: "chrome://browser/skin/devtools/tools-icons-small.png",
url: "chrome://browser/content/debugger.xul",
label: l10n("ToolboxDebugger.label", debuggerStrings),
tooltip: l10n("ToolboxDebugger.tooltip", debuggerStrings),
isTargetSupported: function(target) {
return true;
@ -108,6 +111,7 @@ let inspectorDefinition = {
icon: "chrome://browser/skin/devtools/tools-icons-small.png",
url: "chrome://browser/content/devtools/inspector/inspector.xul",
label: l10n("inspector.label", inspectorStrings),
tooltip: l10n("inspector.tooltip", inspectorStrings),
isTargetSupported: function(target) {
return !target.isRemote;
@ -127,6 +131,7 @@ let styleEditorDefinition = {
modifiers: "shift",
label: l10n("ToolboxStyleEditor.label", styleEditorStrings),
url: "chrome://browser/content/styleeditor.xul",
tooltip: l10n("ToolboxStyleEditor.tooltip", styleEditorStrings),
isTargetSupported: function(target) {
return !target.isRemote && !target.isChrome;
@ -144,6 +149,7 @@ let profilerDefinition = {
icon: "chrome://browser/skin/devtools/tools-icons-small.png",
url: "chrome://browser/content/profiler.xul",
label: l10n("profiler.label", profilerStrings),
tooltip: l10n("profiler.tooltip", profilerStrings),
isTargetSupported: function (target) {
if (target.isRemote || target.isChrome) {

View File

@ -16,6 +16,17 @@ XPCOMUtils.defineLazyModuleGetter(this, "Hosts",
"resource:///modules/devtools/ToolboxHosts.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "CommandUtils",
"resource:///modules/devtools/DeveloperToolbar.jsm");
XPCOMUtils.defineLazyGetter(this, "toolboxStrings", function() {
let bundle = Services.strings.createBundle("chrome://browser/locale/devtools/toolbox.properties");
let l10n = function(name) {
try {
return bundle.GetStringFromName(name);
} catch (ex) {
Services.console.logStringMessage("Error reading '" + name + "'");
}
};
return l10n;
});
// DO NOT put Require.jsm or gcli.jsm into lazy getters as this breaks the
// requisition import a few lines down.
@ -285,6 +296,8 @@ Toolbox.prototype = {
let button = this.doc.createElement("toolbarbutton");
button.id = "toolbox-dock-" + position;
button.className = "toolbox-dock-button";
button.setAttribute("tooltiptext", toolboxStrings("toolboxDockButtons." +
position + ".tooltip"));
button.addEventListener("command", function(position) {
this.switchHost(position);
}.bind(this, position));
@ -348,6 +361,7 @@ Toolbox.prototype = {
radio.className = "toolbox-tab devtools-tab";
radio.id = "toolbox-tab-" + id;
radio.setAttribute("toolid", id);
radio.setAttribute("tooltiptext", toolDefinition.tooltip);
let ordinal = (typeof toolDefinition.ordinal == "number") ?
toolDefinition.ordinal : MAX_ORDINAL;

View File

@ -1,14 +1,25 @@
html {
background: url("chrome://browser/skin/newtab/noise.png");
background-color: #111;
background-image: url("chrome://browser/skin/newtab/noise.png");
}
body {
font-family: Arial;
padding: 20px;
border-radius: 3px;
font-family: Arial, sans-serif;
color: white;
max-width: 600px;
min-height: 400px;
margin: 10px auto 0;
margin: 30px auto 0;
box-shadow: 0 2px 3px black;
background-color: #3C3E40;
}
h1 {
margin: 0;
padding: 20px;
background-color: rgba(0,0,0,0.12);
background-image: radial-gradient(ellipse farthest-corner at center top , rgb(159, 223, 255), rgba(101, 203, 255, 0.3)), radial-gradient(ellipse farthest-side at center top , rgba(101, 203, 255, 0.4), rgba(101, 203, 255, 0));
background-size: 100% 2px, 100% 5px;
background-repeat: no-repeat;
border-bottom: 1px solid rgba(0,0,0,0.1);
}
label {
@ -29,18 +40,21 @@ label > span {
margin-left: 160px;
}
#actors, #connection-form {
margin: 20px;
input:invalid {
box-shadow: 0 0 2px 2px #F06;
}
input {
border: 1px solid grey;
section {
min-height: 160px;
margin: 60px 20px;
display: none; /* By default, hidden */
}
#connection-form,
#connecting,
#actors-list {
.error-message {
color: red;
}
.error-message:not(.active) {
display: none;
}
@ -60,20 +74,9 @@ body.connecting > #connecting {
text-align: center;
}
#throbber {
height: 7px; width: 7px;
border-radius: 50%;
background: black;
display: inline-block;
animation-duration: 0.6s;
animation-name: anim;
animation-direction: alternate;
animation-iteration-count: infinite;
animation-timing-function: linear;
#connecting > p > img {
vertical-align: top;
}
@keyframes anim {to {
transform: scale(0.5) rotate(0.1deg);
}}
#actors {
padding-left: 0;
@ -84,4 +87,22 @@ body.connecting > #connecting {
display: block;
margin: 5px;
padding: 5px;
color: white;
}
.remote-process {
font-style: italic;
opacity: 0.8;
}
footer {
padding: 10px;
background-color: rgba(0,0,0,0.12);
border-top: 1px solid rgba(0,0,0,0.1);
font-size: small;
}
footer > a,
footer > a:visited {
color: white;
}

View File

@ -10,37 +10,68 @@ const Cu = Components.utils;
Cu.import("resource:///modules/devtools/Target.jsm");
Cu.import("resource:///modules/devtools/Toolbox.jsm");
Cu.import("resource:///modules/devtools/gDevTools.jsm");
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
let gClient;
let gConnectionTimeout;
XPCOMUtils.defineLazyGetter(window, 'l10n', function () {
return Services.strings.createBundle('chrome://browser/locale/devtools/connection-screen.properties');
});
/**
* Once DOM is ready, we prefil the host/port inputs with
* pref-stored values.
*/
window.addEventListener("DOMContentLoaded", function onDOMReady() {
window.removeEventListener("DOMContentLoaded", onDOMReady, true);
let host = Services.prefs.getCharPref("devtools.debugger.remote-host");
let port = Services.prefs.getIntPref("devtools.debugger.remote-port");
if (host) {
document.getElementById("host").value = host;
}
if (port) {
document.getElementById("port").value = port;
}
}, true);
/**
* Called when the "connect" button is clicked.
*/
function submit() {
// Show the "connecting" screen
document.body.classList.add("connecting");
// Save the host/port values
let host = document.getElementById("host").value;
let port = document.getElementById("port").value;
if (!host) {
host = Services.prefs.getCharPref("devtools.debugger.remote-host");
} else {
Services.prefs.setCharPref("devtools.debugger.remote-host", host);
}
if (!port) {
port = Services.prefs.getIntPref("devtools.debugger.remote-port");
} else {
let port = document.getElementById("port").value;
Services.prefs.setIntPref("devtools.debugger.remote-port", port);
// Initiate the connection
let transport = debuggerSocketConnect(host, port);
gClient = new DebuggerClient(transport);
let delay = Services.prefs.getIntPref("devtools.debugger.remote-timeout");
gConnectionTimeout = setTimeout(handleConnectionTimeout, delay);
gClient.connect(onConnectionReady);
}
let transport = debuggerSocketConnect(host, port);
let client = gClient = new DebuggerClient(transport);
client.connect(function(aType, aTraits) {
client.listTabs(function(aResponse) {
/**
* Connection is ready. List actors and build buttons.
*/
function onConnectionReady(aType, aTraits) {
clearTimeout(gConnectionTimeout);
gClient.listTabs(function(aResponse) {
document.body.classList.remove("connecting");
document.body.classList.add("actors-mode");
let parent = document.getElementById("actors");
let focusSet = false;
// Add Global Process debugging...
let globals = JSON.parse(JSON.stringify(aResponse));
@ -48,53 +79,89 @@ function submit() {
delete globals.selected;
// ...only if there are appropriate actors (a 'from' property will always
// be there).
// Add one entry for each open tab.
for (let i = 0; i < aResponse.tabs.length; i++) {
buildLink(aResponse.tabs[i], parent, i == aResponse.selected);
}
// Build the Remote Process button
if (Object.keys(globals).length > 1) {
let a = document.createElement("a");
a.onclick = function() {
connect(globals, true);
openToolbox(globals, true);
}
a.title = a.textContent = "Remote process";
a.title = a.textContent = window.l10n.GetStringFromName("remoteProcess");
a.className = "remote-process";
a.href = "#";
parent.appendChild(a);
}
// Add one entry for each open tab.
if (aResponse.tabs.length > 0) {
let header = document.createElement("div");
header.innerHTML = "Tabs:";
parent.appendChild(header);
// Move the selected tab on top
let selectedLink = parent.querySelector("a.selected");
if (selectedLink) {
parent.insertBefore(selectedLink, parent.firstChild);
}
for (let i = 0; i < aResponse.tabs.length; i++) {
let tab = aResponse.tabs[i];
// Ensure the first link is focused
let firstLink = parent.querySelector("a:first-of-type");
if (firstLink) {
firstLink.focus();
}
});
}
/**
* Build one button for an actor.
*/
function buildLink(tab, parent, selected) {
let a = document.createElement("a");
a.onclick = function() {
connect(tab);
openToolbox(tab);
}
a.title = a.textContent = tab.title;
a.textContent = tab.title;
a.title = tab.url;
if (!a.textContent) {
a.textContent = tab.url;
}
a.href = "#";
if (i == aResponse.selected) {
a.title += " [*]";
a.textContent = a.title;
if (selected) {
a.classList.add("selected");
}
parent.appendChild(a);
if (!focusSet) {
a.focus();
focusSet = true;
}
}
});
});
}
function connect(form, chrome=false) {
/**
* An error occured. Let's show it and return to the first screen.
*/
function showError(type) {
document.body.className = "error";
let activeError = document.querySelector(".error-message.active");
if (activeError) {
activeError.classList.remove("active");
}
activeError = document.querySelector(".error-" + type);
if (activeError) {
activeError.classList.add("active");
}
}
/**
* Connection timeout.
*/
function handleConnectionTimeout() {
showError("timeout");
}
/**
* The user clicked on one of the buttons.
* Opens the toolbox.
*/
function openToolbox(form, chrome=false) {
let target = TargetFactory.forRemote(form, gClient, chrome);
gDevTools.showToolbox(target, "webconsole", Toolbox.HostType.WINDOW);
window.close();
}

View File

@ -12,34 +12,37 @@
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<head>
<title>&title;</title>
<link rel="stylesheet" href="chrome://browser/skin/devtools/common.css" type="text/css"/>
<link rel="stylesheet" href="chrome://browser/content/devtools/connect.css" type="text/css"/>
<script type="application/javascript;version=1.8" src="connect.js"></script>
</head>
<body>
<p>
</p>
<h1>&header;</h1>
<section id="connection-form">
<form onsubmit="window.submit()" action="#">
<form validate="validate" onsubmit="window.submit()" action="#">
<label>
<span>&host;</span>
<input id="host" type="text" placeholder="localhost"></input>
<input required="required" class="devtools-textinput" id="host" type="text"></input>
</label>
<label>
<span>&port;</span>
<input id="port" type="number" placeholder="6000"></input>
<input required="required" class="devtools-textinput" id="port" type="number" pattern="\d+"></input>
</label>
<label>
<input id="submit" type="submit" value="&connect;"></input>
<input class="devtools-toolbarbutton" id="submit" type="submit" value="&connect;"></input>
</label>
</form>
<p class="error-message error-timeout">&errorTimeout;</p>
<p class="error-message error-refused">&errorRefused;</p>
<p class="error-message error-unexpected">&errorUnexpected;</p>
</section>
<section id="actors-list">
<p>&availability;</p>
<ul id="actors"></ul>
</section>
<section id="connecting">
<p>&connecting;</p>
<div id="throbber"></div>
<p><img src="chrome://browser/skin/tabbrowser/loading.png"></img> &connecting;</p>
</section>
<footer>&help;</footer>
</body>
</html>

View File

@ -2,6 +2,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/. -->
<!DOCTYPE window [
<!ENTITY % toolboxDTD SYSTEM "chrome://browser/locale/devtools/toolbox.dtd" >
%toolboxDTD;
]>
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/devtools/shared/common.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/devtools/framework/toolbox.css" type="text/css"?>
@ -15,7 +19,9 @@
<toolbar class="devtools-tabbar">
#ifdef XP_MACOSX
<hbox id="toolbox-controls">
<toolbarbutton id="toolbox-close" class="devtools-closebutton"></toolbarbutton>
<toolbarbutton id="toolbox-close"
class="devtools-closebutton"
tooltiptext="&toolboxCloseButton.tooltip;"/>
<hbox id="toolbox-dock-buttons"/>
</hbox>
#endif
@ -25,7 +31,9 @@
#ifndef XP_MACOSX
<hbox id="toolbox-controls">
<hbox id="toolbox-dock-buttons"/>
<toolbarbutton id="toolbox-close" class="devtools-closebutton"></toolbarbutton>
<toolbarbutton id="toolbox-close"
class="devtools-closebutton"
tooltiptext="&toolboxCloseButton.tooltip;"/>
</hbox>
#endif
</toolbar>

View File

@ -83,7 +83,6 @@ HTMLBreadcrumbs.prototype = {
this.update = this.update.bind(this);
this.updateSelectors = this.updateSelectors.bind(this);
this.selection.on("new-node", this.update);
this.selection.on("detached", this.update);
this.selection.on("pseudoclass", this.updateSelectors);
this.selection.on("attribute-changed", this.updateSelectors);
this.update();
@ -296,7 +295,6 @@ HTMLBreadcrumbs.prototype = {
});
this.selection.off("new-node", this.update);
this.selection.off("detached", this.update);
this.selection.off("pseudoclass", this.updateSelectors);
this.selection.off("attribute-changed", this.updateSelectors);

View File

@ -133,7 +133,6 @@ Highlighter.prototype = {
this.selection.on("new-node", this.highlight);
this.selection.on("new-node", this.updateInfobar);
this.selection.on("detached", this.highlight);
this.selection.on("pseudoclass", this.updateInfobar);
this.selection.on("attribute-changed", this.updateInfobar);
@ -168,7 +167,6 @@ Highlighter.prototype = {
this.selection.off("new-node", this.highlight);
this.selection.off("new-node", this.updateInfobar);
this.selection.off("detached", this.highlight);
this.selection.off("pseudoclass", this.updateInfobar);
this.selection.off("attribute-changed", this.updateInfobar);

View File

@ -68,6 +68,8 @@ InspectorPanel.prototype = {
this._selection = new Selection();
this.onNewSelection = this.onNewSelection.bind(this);
this.selection.on("new-node", this.onNewSelection);
this.onDetached = this.onDetached.bind(this);
this.selection.on("detached", this.onDetached);
this.breadcrumbs = new HTMLBreadcrumbs(this);
@ -170,6 +172,7 @@ InspectorPanel.prototype = {
}.bind(this);
this.sidebar.on("select", this._setDefaultSidebar);
this.toggleHighlighter = this.toggleHighlighter.bind(this);
this.sidebar.addTab("ruleview",
"chrome://browser/content/devtools/cssruleview.xul",
@ -183,6 +186,10 @@ InspectorPanel.prototype = {
"chrome://browser/content/devtools/layoutview/view.xhtml",
"layoutview" == defaultTab);
let ruleViewTab = this.sidebar.getTab("ruleview");
ruleViewTab.addEventListener("mouseover", this.toggleHighlighter, false);
ruleViewTab.addEventListener("mouseout", this.toggleHighlighter, false);
this.sidebar.show();
},
@ -275,6 +282,15 @@ InspectorPanel.prototype = {
this.cancelLayoutChange();
},
/**
* When a node is deleted, select its parent node.
*/
onDetached: function InspectorPanel_onDetached(event, parentNode) {
this.cancelLayoutChange();
this.breadcrumbs.cutAfter(this.breadcrumbs.indexOf(parentNode));
this.selection.setNode(parentNode, "detached");
},
/**
* Destroy the inspector.
*/
@ -310,6 +326,7 @@ InspectorPanel.prototype = {
this.nodemenu.removeEventListener("popuphiding", this._resetNodeMenu, true);
this.breadcrumbs.destroy();
this.selection.off("new-node", this.onNewSelection);
this.selection.off("detached", this.onDetached);
this._destroyMarkup();
this._selection.destroy();
this._selection = null;
@ -447,6 +464,19 @@ InspectorPanel.prototype = {
this.selection.emit("pseudoclass");
},
/**
* Toggle the highlighter when ruleview is hovered.
*/
toggleHighlighter: function InspectorPanel_toggleHighlighter(event)
{
if (event.type == "mouseover") {
this.highlighter.hide();
}
else if (event.type == "mouseout") {
this.highlighter.show();
}
},
/**
* Copy the innerHTML of the selected Node to the clipboard.
*/

View File

@ -70,12 +70,14 @@ Selection.prototype = {
_onMutations: function(mutations) {
let attributeChange = false;
let detached = false;
let parentNode = null;
for (let m of mutations) {
if (!attributeChange && m.type == "attributes") {
attributeChange = true;
}
if (m.type == "childList") {
if (!detached && !this.isConnected()) {
parentNode = m.target;
detached = true;
}
}
@ -84,7 +86,7 @@ Selection.prototype = {
if (attributeChange)
this.emit("attribute-changed");
if (detached)
this.emit("detached");
this.emit("detached", parentNode);
},
_attachEvents: function SN__attachEvents() {

View File

@ -35,6 +35,7 @@ _BROWSER_FILES = \
browser_inspector_highlighter_autohide.js \
browser_inspector_changes.js \
browser_inspector_bug_674871.js \
browser_inspector_bug_817558_delete_node.js \
head.js \
helpers.js \
$(NULL)

View File

@ -104,7 +104,7 @@ function test() {
is(para.textContent, "test2", "paragraph content is correct");
let root = content.document.documentElement;
ok(inspector.selection.node, root, "Selection is the root of the new page.");
is(inspector.selection.node, root, "Selection is the root of the new page.");
ok(alertActive1_called, "first notification box has been showed");
ok(alertActive2_called, "second notification box has been showed");

View File

@ -0,0 +1,50 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test()
{
waitForExplicitFinish();
//ignoreAllUncaughtExceptions();
let node, iframe, inspector;
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
waitForFocus(setupTest, content);
}, true);
content.location = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_destroyselection.html";
function setupTest()
{
iframe = content.document.querySelector("iframe");
node = iframe.contentDocument.querySelector("span");
openInspector(runTests);
}
function runTests(aInspector)
{
inspector = aInspector;
inspector.selection.setNode(node);
let parentNode = node.parentNode;
parentNode.removeChild(node);
let tmp = {};
Cu.import("resource:///modules/devtools/LayoutHelpers.jsm", tmp);
ok(!tmp.LayoutHelpers.isNodeConnected(node), "Node considered as disconnected.");
executeSoon(function() {
is(inspector.selection.node, parentNode, "parent of selection got selected");
finishUp();
});
}
function finishUp() {
node = null;
gBrowser.removeCurrentTab();
finish();
}
}

View File

@ -35,7 +35,6 @@ LayoutView.prototype = {
this.update = this.update.bind(this);
this.onNewNode = this.onNewNode.bind(this);
this.onHighlighterLocked = this.onHighlighterLocked.bind(this);
this.inspector.selection.on("detached", this.onNewNode);
this.inspector.selection.on("new-node", this.onNewNode);
this.inspector.sidebar.on("layoutview-selected", this.onNewNode);
if (this.inspector.highlighter) {
@ -101,7 +100,6 @@ LayoutView.prototype = {
destroy: function LV_destroy() {
this.inspector.sidebar.off("layoutview-selected", this.onNewNode);
this.inspector.selection.off("new-node", this.onNewNode);
this.inspector.selection.off("detached", this.onNewNode);
if (this.browser) {
this.browser.removeEventListener("MozAfterPaint", this.update, true);
}

View File

@ -12,6 +12,7 @@ const Ci = Components.interfaces;
const PAGE_SIZE = 10;
const PREVIEW_AREA = 700;
const DEFAULT_MAX_CHILDREN = 100;
this.EXPORTED_SYMBOLS = ["MarkupView"];
@ -20,6 +21,7 @@ Cu.import("resource:///modules/devtools/CssRuleView.jsm");
Cu.import("resource:///modules/devtools/Templater.jsm");
Cu.import("resource:///modules/devtools/Undo.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
/**
* Vocabulary for the purposes of this file:
@ -46,6 +48,12 @@ this.MarkupView = function MarkupView(aInspector, aFrame, aControllerWindow)
this.doc = this._frame.contentDocument;
this._elt = this.doc.querySelector("#root");
try {
this.maxChildren = Services.prefs.getIntPref("devtools.markup.pagesize");
} catch(ex) {
this.maxChildren = DEFAULT_MAX_CHILDREN;
}
this.undo = new UndoStack();
this.undo.installController(aControllerWindow);
@ -69,7 +77,7 @@ this.MarkupView = function MarkupView(aInspector, aFrame, aControllerWindow)
MarkupView.prototype = {
_selectedContainer: null,
template: function MT_template(aName, aDest, aOptions)
template: function MT_template(aName, aDest, aOptions={stack: "markup-view.xhtml"})
{
let node = this.doc.getElementById("template-" + aName).cloneNode(true);
node.removeAttribute("id");
@ -288,7 +296,6 @@ MarkupView.prototype = {
let walker = documentWalker(aNode);
let parent = walker.parentNode();
if (parent) {
// Make sure parents of this node are imported too.
var container = new MarkupContainer(this, aNode);
} else {
var container = new RootContainer(this, aNode);
@ -298,12 +305,15 @@ MarkupView.prototype = {
// Fake a childList mutation here.
this._mutationObserver([{target: aEvent.target, type: "childList"}]);
}.bind(this), true);
}
this._containers.set(aNode, container);
// FIXME: set an expando to prevent the the wrapper from disappearing
// See bug 819131 for details.
aNode.__preserveHack = true;
container.expanded = aExpand;
container.childrenDirty = true;
this._updateChildren(container);
if (parent) {
@ -327,6 +337,7 @@ MarkupView.prototype = {
if (mutation.type === "attributes" || mutation.type === "characterData") {
container.update();
} else if (mutation.type === "childList") {
container.childrenDirty = true;
this._updateChildren(container);
}
}
@ -339,10 +350,12 @@ MarkupView.prototype = {
*/
showNode: function MT_showNode(aNode, centered)
{
this.importNode(aNode);
let container = this.importNode(aNode);
this._updateChildren(container);
let walker = documentWalker(aNode);
let parent;
while (parent = walker.parentNode()) {
this._updateChildren(this.getContainer(parent));
this.expandNode(parent);
}
LayoutHelpers.scrollIntoViewIfNeeded(this._containers.get(aNode).editor.elt, centered);
@ -421,9 +434,32 @@ MarkupView.prototype = {
this._selectedContainer.selected = true;
}
this._ensureSelectionVisible();
return true;
},
/**
* Make sure that every ancestor of the selection are updated
* and included in the list of visible children.
*/
_ensureSelectionVisible: function MT_ensureSelectionVisible()
{
let node = this._selectedContainer.node;
let walker = documentWalker(node);
while (node) {
let container = this._containers.get(node);
let parent = walker.parentNode();
if (!container.elt.parentNode) {
let parentContainer = this._containers.get(parent);
parentContainer.childrenDirty = true;
this._updateChildren(parentContainer, node);
}
node = parent;
}
},
/**
* Unmark selected node (no node selected).
*/
@ -448,29 +484,139 @@ MarkupView.prototype = {
/**
* Make sure all children of the given container's node are
* imported and attached to the container in the right order.
* @param aCentered If provided, this child will be included
* in the visible subset, and will be roughly centered
* in that list.
*/
_updateChildren: function MT__updateChildren(aContainer)
_updateChildren: function MT__updateChildren(aContainer, aCentered)
{
if (!aContainer.childrenDirty) {
return false;
}
// Get a tree walker pointing at the first child of the node.
let treeWalker = documentWalker(aContainer.node);
let child = treeWalker.firstChild();
aContainer.hasChildren = !!child;
if (aContainer.expanded) {
let lastContainer = null;
while (child) {
if (!aContainer.expanded) {
return;
}
aContainer.childrenDirty = false;
let children = this._getVisibleChildren(aContainer, aCentered);
let fragment = this.doc.createDocumentFragment();
for (child of children.children) {
let container = this.importNode(child, false);
// Make sure children are in the right order.
let before = lastContainer ? lastContainer.nextSibling : aContainer.children.firstChild;
aContainer.children.insertBefore(container.elt, before);
lastContainer = container.elt;
child = treeWalker.nextSibling();
fragment.appendChild(container.elt);
}
while (aContainer.children.lastChild != lastContainer) {
aContainer.children.removeChild(aContainer.children.lastChild);
while (aContainer.children.firstChild) {
aContainer.children.removeChild(aContainer.children.firstChild);
}
if (!(children.hasFirst && children.hasLast)) {
let data = {
showing: this.strings.GetStringFromName("markupView.more.showing"),
showAll: this.strings.formatStringFromName(
"markupView.more.showAll",
[aContainer.node.children.length.toString()], 1),
allButtonClick: function() {
aContainer.maxChildren = -1;
aContainer.childrenDirty = true;
this._updateChildren(aContainer);
}.bind(this)
};
if (!children.hasFirst) {
let span = this.template("more-nodes", data);
fragment.insertBefore(span, fragment.firstChild);
}
if (!children.hasLast) {
let span = this.template("more-nodes", data);
fragment.appendChild(span);
}
}
aContainer.children.appendChild(fragment);
return true;
},
/**
* Return a list of the children to display for this container.
*/
_getVisibleChildren: function MV__getVisibleChildren(aContainer, aCentered)
{
let maxChildren = aContainer.maxChildren || this.maxChildren;
if (maxChildren == -1) {
maxChildren = Number.MAX_VALUE;
}
let firstChild = documentWalker(aContainer.node).firstChild();
let lastChild = documentWalker(aContainer.node).lastChild();
if (!firstChild) {
// No children, we're done.
return { hasFirst: true, hasLast: true, children: [] };
}
// By default try to put the selected child in the middle of the list.
let start = aCentered || firstChild;
// Start by reading backward from the starting point....
let nodes = [];
let backwardWalker = documentWalker(start);
if (backwardWalker.previousSibling()) {
let backwardCount = Math.floor(maxChildren / 2);
let backwardNodes = this._readBackward(backwardWalker, backwardCount);
nodes = backwardNodes;
}
// Then read forward by any slack left in the max children...
let forwardWalker = documentWalker(start);
let forwardCount = maxChildren - nodes.length;
nodes = nodes.concat(this._readForward(forwardWalker, forwardCount));
// If there's any room left, it means we've run all the way to the end.
// In that case, there might still be more items at the front.
let remaining = maxChildren - nodes.length;
if (remaining > 0 && nodes[0] != firstChild) {
let firstNodes = this._readBackward(backwardWalker, remaining);
// Then put it all back together.
nodes = firstNodes.concat(nodes);
}
return {
hasFirst: nodes[0] == firstChild,
hasLast: nodes[nodes.length - 1] == lastChild,
children: nodes
};
},
_readForward: function MV__readForward(aWalker, aCount)
{
let ret = [];
let node = aWalker.currentNode;
do {
ret.push(node);
node = aWalker.nextSibling();
} while (node && --aCount);
return ret;
},
_readBackward: function MV__readBackward(aWalker, aCount)
{
let ret = [];
let node = aWalker.currentNode;
do {
ret.push(node);
node = aWalker.previousSibling();
} while(node && --aCount);
ret.reverse();
return ret;
},
/**
@ -618,9 +764,7 @@ function MarkupContainer(aMarkupView, aNode)
this.expander = null;
this.codeBox = null;
this.children = null;
let options = { stack: "markup-view.xhtml" };
this.markup.template("container", this, options);
this.markup.template("container", this);
this.elt.container = this;
this.expander.addEventListener("click", function() {
@ -734,7 +878,7 @@ MarkupContainer.prototype = {
if (focusable) {
focusable.focus();
}
}
},
}
/**
@ -841,13 +985,12 @@ function ElementEditor(aContainer, aNode)
this.attrList = null;
this.newAttr = null;
this.closeElt = null;
let options = { stack: "markup-view.xhtml" };
// Create the main editor
this.template("element", this, options);
this.template("element", this);
// Create the closing tag
this.template("elementClose", this, options);
this.template("elementClose", this);
// Make the tag name editable (unless this is a document element)
if (aNode != aNode.ownerDocument.documentElement) {
@ -927,8 +1070,7 @@ ElementEditor.prototype = {
let data = {
attrName: aAttr.name,
};
let options = { stack: "markup-view.xhtml" };
this.template("attribute", data, options);
this.template("attribute", data);
var {attr, inner, name, val} = data;
// Figure out where we should place the attribute.
@ -1260,3 +1402,8 @@ function whitespaceTextFilter(aNode)
return Ci.nsIDOMNodeFilter.FILTER_ACCEPT;
}
}
XPCOMUtils.defineLazyGetter(MarkupView.prototype, "strings", function () {
return Services.strings.createBundle(
"chrome://browser/locale/devtools/inspector.properties");
});

View File

@ -16,6 +16,8 @@
<div id="templates" style="display:none">
<ul>
<li id="template-container" save="${elt}" class="container"><span save="${expander}" class="expander"></span><span save="${codeBox}" class="codebox"><ul save="${children}" class="children"></ul></span></li>
<li id="template-more-nodes" class="more-nodes devtools-class-comment" save="${elt}"><span>${showing}</span> <button href="#" onclick="${allButtonClick}">${showAll}</button></li>
</ul>
<span id="template-element" save="${elt}" class="editor"><span>&lt;</span><span save="${tag}" class="tagname devtools-theme-tagname"></span><span save="${attrList}"></span><span save="${newAttr}" class="newattr" tabindex="0"></span>&gt;</span>

View File

@ -18,6 +18,8 @@ _BROWSER_FILES = \
browser_inspector_markup_mutation.js \
browser_inspector_markup_edit.html \
browser_inspector_markup_edit.js \
browser_inspector_markup_subset.html \
browser_inspector_markup_subset.js \
head.js \
$(NULL)

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html class="html">
<body class="body">
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="d"></div>
<div id="e"></div>
<div id="f"></div>
<div id="g"></div>
<div id="h"></div>
<div id="i"></div>
<div id="j"></div>
<div id="k"></div>
<div id="l"></div>
<div id="m"></div>
<div id="n"></div>
<div id="o"></div>
<div id="p"></div>
<div id="q"></div>
<div id="r"></div>
<div id="s"></div>
<div id="t"></div>
<div id="u"></div>
<div id="v"></div>
<div id="w"></div>
<div id="x"></div>
<div id="y"></div>
<div id="z"></div>
</body>
</html>

View File

@ -0,0 +1,146 @@
/* Any copyright", " is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the markup view loads only as many nodes as specified
* by the devtools.markup.pagesize preference.
*/
registerCleanupFunction(function() {
Services.prefs.clearUserPref("devtools.markup.pagesize");
});
Services.prefs.setIntPref("devtools.markup.pagesize", 5);
function test() {
waitForExplicitFinish();
// Will hold the doc we're viewing
let doc;
let inspector;
// Holds the MarkupTool object we're testing.
let markup;
function assertChildren(expected)
{
let container = markup.getContainer(doc.querySelector("body"));
let found = [];
for (let child of container.children.children) {
if (child.classList.contains("more-nodes")) {
found += "*more*";
} else {
found += child.container.node.getAttribute("id");
}
}
is(expected, found, "Got the expected children.");
}
function forceReload()
{
let container = markup.getContainer(doc.querySelector("body"));
container.childrenDirty = true;
}
let selections = [
{
desc: "Select the first item",
selector: "#a",
before: function() {
},
after: function() {
assertChildren("abcde*more*");
}
},
{
desc: "Select the last item",
selector: "#z",
before: function() {},
after: function() {
assertChildren("*more*vwxyz");
}
},
{
desc: "Select an already-visible item",
selector: "#v",
before: function() {},
after: function() {
// Because "v" was already visible, we shouldn't have loaded
// a different page.
assertChildren("*more*vwxyz");
},
},
{
desc: "Verify childrenDirty reloads the page",
selector: "#w",
before: function() {
forceReload();
},
after: function() {
// But now that we don't already have a loaded page, selecting
// w should center around w.
assertChildren("*more*uvwxy*more*");
},
},
];
// Create the helper tab for parsing...
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
doc = content.document;
waitForFocus(setupTest, content);
}, true);
content.location = "http://mochi.test:8888/browser/browser/devtools/markupview/test/browser_inspector_markup_subset.html";
function setupTest() {
var target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
toolbox.once("inspector-selected", function SE_selected(id, aInspector) {
inspector = aInspector;
markup = inspector.markup;
runNextSelection();
});
});
}
function runTests() {
inspector.selection.once("new-node", startTests);
executeSoon(function() {
inspector.selection.setNode(doc.body);
});
}
function runNextSelection() {
let selection = selections.shift();
if (!selection) {
clickMore();
return;
}
info(selection.desc);
selection.before();
inspector.selection.once("new-node", function() {
selection.after();
runNextSelection();
});
inspector.selection.setNode(doc.querySelector(selection.selector));
}
function clickMore() {
info("Check that clicking more loads the whole thing.");
// Make sure that clicking the "more" button loads all the nodes.
let container = markup.getContainer(doc.querySelector("body"));
let button = container.elt.querySelector("button");
button.click();
assertChildren("abcdefghijklmnopqrstuvwxyz");
finishUp();
}
function finishUp() {
doc = inspector = null;
gBrowser.removeCurrentTab();
finish();
}
}

View File

@ -158,9 +158,6 @@ function ResponsiveUI(aWindow, aTab)
this.buildUI();
this.checkMenus();
let target = TargetFactory.forTab(this.tab);
this.toolboxWasOpen = !!gDevTools.getToolbox(target);
try {
if (Services.prefs.getBoolPref("devtools.responsiveUI.rotate")) {
this.rotate();
@ -239,18 +236,10 @@ ResponsiveUI.prototype = {
if (aEvent.keyCode == this.mainWindow.KeyEvent.DOM_VK_ESCAPE &&
this.mainWindow.gBrowser.selectedBrowser == this.browser) {
// If the toolbox wasn't open at first but is open now,
// we don't want to close the Responsive Mode on Escape.
// We let the toolbox close first.
let target = TargetFactory.forTab(this.tab);
let isToolboxOpen = !!gDevTools.getToolbox(target);
if (this.toolboxWasOpen || !isToolboxOpen) {
aEvent.preventDefault();
aEvent.stopPropagation();
this.close();
}
}
},
/**

View File

@ -69,11 +69,29 @@ this.ScratchpadManager = {
saveOpenWindows: function SPM_saveOpenWindows() {
this._scratchpads = [];
function clone(src) {
let dest = {};
for (let key in src) {
if (src.hasOwnProperty(key)) {
dest[key] = src[key];
}
}
return dest;
}
// We need to clone objects we get from Scratchpad instances
// because such (cross-window) objects have a property 'parent'
// that holds on to a ChromeWindow instance. This means that
// such objects are not primitive-values-only anymore so they
// can leak.
let enumerator = Services.wm.getEnumerator("devtools:scratchpad");
while (enumerator.hasMoreElements()) {
let win = enumerator.getNext();
if (!win.closed && win.Scratchpad.initialized) {
this._scratchpads.push(win.Scratchpad.getState());
this._scratchpads.push(clone(win.Scratchpad.getState()));
}
}
},
@ -106,6 +124,7 @@ this.ScratchpadManager = {
let win = Services.ww.openWindow(null, SCRATCHPAD_WINDOW_URL, "_blank",
SCRATCHPAD_WINDOW_FEATURES, params);
// Only add the shutdown observer if we've opened a scratchpad window.
ShutdownObserver.init();
@ -128,6 +147,7 @@ var ShutdownObserver = {
}
Services.obs.addObserver(this, "quit-application-granted", false);
this._initialized = true;
},

View File

@ -133,6 +133,7 @@ this.CssHtmlTree = function CssHtmlTree(aStyleInspector)
this.getRTLAttr = chromeReg.isLocaleRTL("global") ? "rtl" : "ltr";
// Create bound methods.
this.siFocusWindow = this.focusWindow.bind(this);
this.siBoundMenuUpdate = this.computedViewMenuUpdate.bind(this);
this.siBoundCopy = this.computedViewCopy.bind(this);
this.siBoundCopyDeclaration = this.computedViewCopyDeclaration.bind(this);
@ -140,6 +141,7 @@ this.CssHtmlTree = function CssHtmlTree(aStyleInspector)
this.siBoundCopyPropertyValue = this.computedViewCopyPropertyValue.bind(this);
this.styleDocument.addEventListener("copy", this.siBoundCopy);
this.styleDocument.addEventListener("mousedown", this.siFocusWindow);
// Nodes used in templating
this.root = this.styleDocument.getElementById("root");
@ -557,6 +559,17 @@ CssHtmlTree.prototype = {
menuitem.disabled = disablePropertyItems;
},
/**
* Focus the window on mousedown.
*
* @param aEvent The event object
*/
focusWindow: function si_focusWindow(aEvent)
{
let win = this.styleDocument.defaultView;
win.focus();
},
/**
* Copy selected text.
*
@ -704,6 +717,7 @@ CssHtmlTree.prototype = {
// Remove bound listeners
this.styleDocument.removeEventListener("copy", this.siBoundCopy);
this.styleDocument.removeEventListener("mousedown", this.siFocusWindow);
// Nodes used in templating
delete this.root;

View File

@ -1402,6 +1402,8 @@ RuleEditor.prototype = {
}.bind(this), false);
this.element.addEventListener("mousedown", function() {
this.doc.defaultView.focus();
let editorNodes =
this.doc.querySelectorAll(".styleinspector-propertyeditor");

View File

@ -181,7 +181,6 @@ TiltVisualizer.prototype = {
if (panel) {
this.inspector = panel;
this.inspector.selection.on("new-node", this.onNewNodeFromInspector);
this.inspector.selection.on("detached", this.onNewNodeFromInspector);
this.onNewNodeFromInspector();
}
}
@ -196,7 +195,6 @@ TiltVisualizer.prototype = {
if (this.inspector) {
this.inspector.selection.off("new-node", this.onNewNodeFromInspector);
this.inspector.selection.off("detached", this.onNewNodeFromInspector);
this.inspector = null;
}
@ -217,7 +215,6 @@ TiltVisualizer.prototype = {
if (toolbox.target.tab === this._browserTab) {
this.inspector = panel;
this.inspector.selection.on("new-node", this.onNewNodeFromInspector);
this.inspector.selection.on("detached", this.onNewNodeFromInspector);
this.onNewNodeFromTilt();
}
},
@ -231,7 +228,6 @@ TiltVisualizer.prototype = {
this.inspector) {
if (this.inspector.selection) {
this.inspector.selection.off("new-node", this.onNewNodeFromInspector);
this.inspector.selection.off("detached", this.onNewNodeFromInspector);
}
this.inspector = null;
}

View File

@ -623,3 +623,8 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY social.chatBar.commandkey "c">
<!ENTITY social.chatBar.label "Focus chats">
<!ENTITY social.chatBar.accesskey "c">
<!ENTITY getUserMedia.selectCamera.label "Camera to share:">
<!ENTITY getUserMedia.selectCamera.accesskey "C">
<!ENTITY getUserMedia.selectMicrophone.label "Microphone to share:">
<!ENTITY getUserMedia.selectMicrophone.accesskey "M">

View File

@ -442,17 +442,15 @@ identity.loggedIn.signOut.label = Sign Out
identity.loggedIn.signOut.accessKey = O
# LOCALIZATION NOTE (getUserMedia.shareCamera.message, getUserMedia.shareMicrophone.message, getUserMedia.shareCameraAndMicrophone.message): %S is the website origin (e.g. www.mozilla.org)
# LOCALIZATION NOTE (getUserMedia.shareMicrophone.message, getUserMedia.shareSpecificMicrophone.label): %S is the website origin (e.g. www.mozilla.org)
# LOCALIZATION NOTE (getUserMedia.shareMicrophone.message): %S is the website origin (e.g. www.mozilla.org)
# LOCALIZATION NOTE (getUserMedia.shareSelectedDevices.label):
# Semi-colon list of plural forms. See:
# http://developer.mozilla.org/en/docs/Localization_and_Plurals
# The number of devices can be either one or two.
getUserMedia.shareCamera.message = Would you like to share your camera with %S?
getUserMedia.shareCamera.label = Share Camera
getUserMedia.shareCamera.accesskey = S
getUserMedia.shareSpecificCamera.label = Share Camera: %S
getUserMedia.shareMicrophone.message = Would you like to share your microphone with %S?
getUserMedia.shareMicrophone.label = Share Microphone
getUserMedia.shareMicrophone.accesskey = S
getUserMedia.shareSpecificMicrophone.label = Share Microphone: %S
getUserMedia.shareCameraAndMicrophone.message = Would you like to share your camera and microphone with %S?
getUserMedia.shareCameraAndMicrophone.label = Share Camera and Microphone
getUserMedia.shareCameraAndMicrophone.accesskey = S
getUserMedia.shareSelectedDevices.label = Share Selected Device;Share Selected Devices
getUserMedia.shareSelectedDevices.accesskey = S
getUserMedia.denyRequest.label = Don't Share
getUserMedia.denyRequest.accesskey = D

View File

@ -2,14 +2,21 @@
- 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/. -->
<!-- LOCALIZATION NOTE : FILE This file contains the Remove Connection strings.
- The Remote Connection window can be start by running the command:
- `devtools connect`
<!-- LOCALIZATION NOTE : FILE This file contains the Remote Connection strings.
- The Remote Connection window can reached from the "connect…" menuitem
- in the Web Developer menu.
- -->
<!ENTITY title "Connect">
<!ENTITY header "Connect to remote device">
<!ENTITY host "Host:">
<!ENTITY port "Port:">
<!ENTITY connect "Connect">
<!ENTITY connecting "Connecting…">
<!ENTITY availability "Available remote objects:">
<!ENTITY remoteProcess "remote process">
<!ENTITY connectionError "Error:">
<!ENTITY errorTimeout "Error: connection timeout.">
<!ENTITY errorRefused "Error: connection refused.">
<!ENTITY errorUnexpected "Unexpected error.">
<!ENTITY help "Firefox Developer Tools can debug remote devices (Firefox for Android and Firefox OS for example). Make sure that you have turned on the 'Debugger Server' option on the remote device. See <a target='_' href='https://developer.mozilla.org/en-US/docs/Tools/Debugger#Remote_Debugging'>documentation</a>.">

View File

@ -0,0 +1,9 @@
# 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/.
# LOCALIZATION NOTE : FILE This file contains the Remote Connection strings.
# The Remote Connection window can reached from the "connect…" menuitem
# in the Web Developer menu.
remoteProcess=Remote Process

View File

@ -186,6 +186,11 @@ globalScopeLabel=Global
# displayed inside the developer tools window and in the Developer Tools Menu.
ToolboxDebugger.label=Debugger
# LOCALIZATION NOTE (ToolboxDebugger.tooltip):
# This string is displayed in the tooltip of the tab when the debugger is
# displayed inside the developer tools window..
ToolboxDebugger.tooltip=JavaScript Debugger
# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed
# in the variables list on an item with an editable name.
variablesEditableNameTooltip=Double click to edit

View File

@ -33,3 +33,10 @@ nodeMenu.tooltiptext=Node operations
inspector.label=Inspector
inspector.commandkey=I
inspector.accesskey=I
# LOCALIZATION NOTE (markupView.more.*)
# When there are too many nodes to load at once, we will offer to
# show all the nodes.
markupView.more.showing=Some nodes were hidden.
markupView.more.showAll=Show All %S Nodes
inspector.tooltip=DOM and Style Inspector

View File

@ -14,3 +14,8 @@
# This string is displayed in the title of the tab when the profiler is
# displayed inside the developer tools window and in the Developer Tools Menu.
profiler.label=Profiler
# LOCALIZATION NOTE (profiler.tooltip):
# This string is displayed in the tooltip of the tab when the profiler is
# displayed inside the developer tools window.
profiler.tooltip=Profiler

View File

@ -78,3 +78,8 @@ redo.commandkey=Z
# This string is displayed in the title of the tab when the debugger is
# displayed inside the developer tools window and in the Developer Tools Menu.
ToolboxStyleEditor.label=Style Editor
# LOCALIZATION NOTE (ToolboxStyleEditor.tooltip):
# This string is displayed in the tooltip of the tab when the debugger is
# displayed inside the developer tools window.
ToolboxStyleEditor.tooltip=CSS Stylesheets Editor

View File

@ -5,3 +5,5 @@
<!ENTITY window.title "Developer Tools">
<!ENTITY closeCmd.key "W">
<!ENTITY toolboxCloseButton.tooltip "Close Developer Tools">

View File

@ -0,0 +1,3 @@
toolboxDockButtons.bottom.tooltip=Dock to bottom of browser window
toolboxDockButtons.side.tooltip=Dock to side of browser window
toolboxDockButtons.window.tooltip=Show in separate window

View File

@ -174,6 +174,11 @@ listTabs.globalConsoleActor=*Global Console*
# as webConsoleWindowTitleAndURL before the '-'
ToolboxWebconsole.label=Web Console
# LOCALIZATION NOTE (ToolboxWebconsole.tooltip):
# This string is displayed in the tooltip of the tab when the web console is
# displayed inside the developer tools window.
ToolboxWebconsole.tooltip=Web Console
# LOCALIZATION NOTE (longStringEllipsis): The string displayed after a long
# string. This string is clickable such that the rest of the string is retrieved
# from the server.

View File

@ -41,6 +41,7 @@
locale/browser/devtools/toolbox.dtd (%chrome/browser/devtools/toolbox.dtd)
locale/browser/devtools/inspector.dtd (%chrome/browser/devtools/inspector.dtd)
locale/browser/devtools/connection-screen.dtd (%chrome/browser/devtools/connection-screen.dtd)
locale/browser/devtools/connection-screen.properties (%chrome/browser/devtools/connection-screen.properties)
locale/browser/newTab.dtd (%chrome/browser/newTab.dtd)
locale/browser/newTab.properties (%chrome/browser/newTab.properties)
locale/browser/openLocation.dtd (%chrome/browser/openLocation.dtd)

View File

@ -7,9 +7,11 @@
this.EXPORTED_SYMBOLS = ["webrtcUI"];
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PluralForm.jsm");
this.webrtcUI = {
init: function () {
@ -72,47 +74,58 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
return;
let host = aBrowser.contentDocument.documentURIObject.asciiHost;
let chromeWin = aBrowser.ownerDocument.defaultView;
let chromeDoc = aBrowser.ownerDocument;
let chromeWin = chromeDoc.defaultView;
let stringBundle = chromeWin.gNavigatorBundle;
let message = stringBundle.getFormattedString("getUserMedia." + requestType + ".message",
[ host ]);
function listDevices(menupopup, devices) {
while (menupopup.lastChild)
menupopup.removeChild(menupopup.lastChild);
let deviceIndex = 0;
for (let device of devices) {
let menuitem = chromeDoc.createElement("menuitem");
menuitem.setAttribute("value", deviceIndex);
menuitem.setAttribute("label", device.name);
menuitem.setAttribute("tooltiptext", device.name);
menupopup.appendChild(menuitem);
deviceIndex++;
}
}
chromeDoc.getElementById("webRTC-selectCamera").hidden = !videoDevices.length;
chromeDoc.getElementById("webRTC-selectMicrophone").hidden = !audioDevices.length;
listDevices(chromeDoc.getElementById("webRTC-selectCamera-menupopup"), videoDevices);
listDevices(chromeDoc.getElementById("webRTC-selectMicrophone-menupopup"), audioDevices);
let mainAction = {
label: stringBundle.getString("getUserMedia." + requestType + ".label"),
accessKey: stringBundle.getString("getUserMedia." + requestType + ".accesskey"),
label: PluralForm.get(requestType == "shareCameraAndMicrophone" ? 2 : 1,
stringBundle.getString("getUserMedia.shareSelectedDevices.label")),
accessKey: stringBundle.getString("getUserMedia.shareSelectedDevices.accesskey"),
callback: function () {
Services.obs.notifyObservers(null, "getUserMedia:response:allow", aCallID);
let allowedDevices = Cc["@mozilla.org/supports-array;1"]
.createInstance(Ci.nsISupportsArray);
if (videoDevices.length) {
let videoDeviceIndex = chromeDoc.getElementById("webRTC-selectCamera-menulist").value;
allowedDevices.AppendElement(videoDevices[videoDeviceIndex]);
}
if (audioDevices.length) {
let audioDeviceIndex = chromeDoc.getElementById("webRTC-selectMicrophone-menulist").value;
allowedDevices.AppendElement(audioDevices[audioDeviceIndex]);
}
Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
}
};
let secondaryActions = [];
let selectableDevices = videoDevices.length ? videoDevices : audioDevices;
if (selectableDevices.length > 1) {
let selectableDeviceNumber = 0;
for (let device of selectableDevices) {
// See bug 449811 for why we do this
let actual_device = device;
selectableDeviceNumber++;
secondaryActions.push({
label: stringBundle.getFormattedString(
device.type == "audio" ?
"getUserMedia.shareSpecificMicrophone.label" :
"getUserMedia.shareSpecificCamera.label",
[ device.name ]),
accessKey: selectableDeviceNumber,
callback: function () {
Services.obs.notifyObservers(actual_device, "getUserMedia:response:allow", aCallID);
}
});
}
}
secondaryActions.push({
let secondaryActions = [{
label: stringBundle.getString("getUserMedia.denyRequest.label"),
accessKey: stringBundle.getString("getUserMedia.denyRequest.accesskey"),
callback: function () {
Services.obs.notifyObservers(null, "getUserMedia:response:deny", aCallID);
}
});
}];
let options = {
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -128,27 +128,33 @@
margin: 0 3px;
}
/* Search input */
/* Text input */
.devtools-textinput,
.devtools-searchinput {
-moz-appearance: none;
margin: 0 3px;
border: 1px solid hsla(210,8%,5%,.6);
border-radius: 2px;
background-color: transparent;
background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
background-repeat: no-repeat;
background-position: 4px center, top left, top left;
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 12px;
background-image: -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
padding: 3px;
box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
0 0 0 1px hsla(210,16%,76%,.1) inset,
0 1px 0 hsla(210,16%,76%,.15);
color: inherit;
}
.devtools-searchinput {
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 12px;
background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
background-position: 4px center, top left, top left;
background-repeat: no-repeat;
}
.devtools-searchinput:-moz-locale-dir(rtl) {
background-position: calc(100% - 4px) center, top left, top left;
}

View File

@ -49,6 +49,10 @@ li.container {
-moz-appearance: treetwistyopen;
}
.more-nodes {
padding-left: 16px;
}
.styleinspector-propertyeditor {
border: 1px solid #CCC;
}

View File

@ -173,13 +173,13 @@ richlistitem[type="download"][state="1"]:hover {
-moz-image-region: rect(32px, 48px, 48px, 32px);
}
richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow {
richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow {
-moz-image-region: rect(48px, 16px, 64px, 0px);
}
richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:hover {
richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:hover {
-moz-image-region: rect(48px, 32px, 64px, 16px);
}
richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:active {
richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:active {
-moz-image-region: rect(48px, 48px, 64px, 32px);
}

View File

@ -134,14 +134,24 @@
border: 0;
}
/* Search input */
/* Text input */
.devtools-textinput,
.devtools-searchinput {
-moz-appearance: none;
margin: 0 3px;
background-color: transparent;
border: 1px solid hsla(210,8%,5%,.6);
border-radius: 20px;
background-image: -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
padding: 3px;
box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
0 0 0 1px hsla(210,16%,76%,.1) inset,
0 1px 0 hsla(210,16%,76%,.15);
color: inherit;
}
.devtools-searchinput {
background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
background-repeat: no-repeat;
background-position: 4px center, top left, top left;
@ -149,10 +159,6 @@
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 12px;
box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
0 0 0 1px hsla(210,16%,76%,.1) inset,
0 1px 0 hsla(210,16%,76%,.15);
color: inherit;
}
.devtools-searchinput:-moz-locale-dir(rtl) {

View File

@ -52,6 +52,10 @@ li.container {
-moz-appearance: treetwistyopen;
}
.more-nodes {
padding-left: 16px;
}
.styleinspector-propertyeditor {
border: 1px solid #CCC;
}

View File

@ -132,8 +132,9 @@
-moz-box-align: center;
}
/* Search input */
/* Text input */
.devtools-textinput,
.devtools-searchinput {
-moz-appearance: none;
margin: 0 3px;
@ -141,6 +142,15 @@
box-shadow: inset 0 1px 0 hsla(211,68%,6%,.05), 0 0 0 1px hsla(210,40%,83%,.1);
border-radius: 2px;
background-color: transparent;
background-image: -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
padding: 3px;
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease;
color: inherit;
}
.devtools-searchinput {
background-image: url(magnifying-glass.png), -moz-linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
background-repeat: no-repeat;
background-position: 4px center, top left, top left;
@ -148,10 +158,6 @@
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 12px;
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease;
color: inherit;
}
.devtools-searchinput[focused] {

View File

@ -54,6 +54,10 @@ li.container {
background-image: url("chrome://global/skin/tree/twisty-open.png");
}
.more-nodes {
padding-left: 16px;
}
.styleinspector-propertyeditor {
border: 1px solid #CCC;
}

View File

@ -0,0 +1,35 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%define WINSTRIPE_AERO
%include allDownloadsViewOverlay.css
%undef WINSTRIPE_AERO
@media (-moz-windows-default-theme) {
/*
-moz-appearance: menuitem is almost right, but the hover effect is not
transparent and is lighter than desired.
Copied from the autocomplete richlistbox styling in
toolkit/themes/winstripe/global/autocomplete.css
This styling should be kept in sync with the style from the above file.
*/
#downloadsRichListBox > richlistitem.download[selected] {
color: inherit;
background-color: transparent;
/* four gradients for the bevel highlights on each edge, one for blue background */
background-image:
-moz-linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, rgba(255,255,255,0) 3px),
-moz-linear-gradient(to right, rgba(255,255,255,0.5) 3px, rgba(255,255,255,0) 3px),
-moz-linear-gradient(to left, rgba(255,255,255,0.5) 3px, rgba(255,255,255,0) 3px),
-moz-linear-gradient(to top, rgba(255,255,255,0.4) 3px, rgba(255,255,255,0) 3px),
-moz-linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
background-clip: content-box;
border-radius: 6px;
outline: 1px solid rgb(124,163,206);
-moz-outline-radius: 3px;
outline-offset: -2px;
}
}

View File

@ -2,100 +2,23 @@
* 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 and outer controls ***/
#downloadsPanel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
#downloadsListBox {
background-color: transparent;
padding: 4px;
color: inherit;
}
#downloadsPanel:not([hasdownloads]) > #downloadsListBox {
display: none;
}
#downloadsHistory {
background: transparent;
color: -moz-nativehyperlinktext;
cursor: pointer;
}
#downloadsHistory > .button-box {
margin: 1em;
}
@media (-moz-windows-default-theme) {
#downloadsPanel[hasdownloads] > #downloadsFooter {
%ifdef WINSTRIPE_AERO
background-color: #f1f5fb;
%else
background-color: hsla(216,45%,88%,.98);
%endif
box-shadow: 0px 1px 2px rgb(204,214,234) inset;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
}
/*** Downloads Summary and List items ***/
#downloadsSummary,
richlistitem[type="download"] {
height: 7em;
-moz-padding-end: 0;
color: inherit;
}
#downloadsSummary {
padding: 8px 38px 8px 12px;
cursor: pointer;
-moz-user-focus: normal;
}
#downloadsSummary:-moz-focusring {
outline: 1px -moz-dialogtext dotted;
outline-offset: -5px;
}
#downloadsSummary > .downloadTypeIcon {
height: 24px;
width: 24px;
list-style-image: url("chrome://mozapps/skin/downloads/downloadIcon.png");
}
#downloadsSummaryDescription {
color: -moz-nativehyperlinktext;
}
richlistitem[type="download"] {
#downloadsRichListBox {
-moz-appearance: none;
margin: 0;
border-top: 1px solid hsla(0,0%,100%,.3);
border-bottom: 1px solid hsla(220,18%,51%,.25);
background: transparent;
padding: 8px;
}
richlistitem[type="download"]:first-child {
border-top: 1px solid transparent;
}
@media (-moz-windows-default-theme) {
richlistitem[type="download"]:last-child {
border-bottom: 1px solid transparent;
}
}
#downloadsListBox:-moz-focusring > richlistitem[type="download"][selected] {
outline: 1px -moz-dialogtext dotted;
outline-offset: -1px;
#downloadsRichListBox > richlistitem.download {
height: 6em;
%ifndef WINSTRIPE_AERO
padding: 5px 8px;
%endif
}
.downloadTypeIcon {
-moz-margin-end: 8px;
%ifdef WINSTRIPE_AERO
-moz-margin-start: 8px;
%endif
/* Prevent flickering when changing states. */
min-height: 32px;
min-width: 32px;
@ -106,214 +29,37 @@ richlistitem[type="download"]:first-child {
}
.downloadTarget {
margin-bottom: 6px;
margin-bottom: 3px;
cursor: inherit;
}
.downloadDetails {
opacity: 0.6;
font-size: 90%;
opacity: 0.7;
font-size: 95%;
cursor: inherit;
}
.downloadButton {
-moz-appearance: none;
background: transparent;
min-width: 0;
min-height: 0;
margin: 3px;
border: none;
background: transparent;
padding: 5px;
list-style-image: url("chrome://browser/skin/downloads/buttons.png");
}
.downloadButton > .button-box {
padding: 0;
}
/*** Highlighted list items ***/
richlistitem[type="download"][state="1"]:hover {
border-radius: 3px;
border-top: 1px solid hsla(0,0%,100%,.2);
border-bottom: 1px solid hsla(0,0%,0%,.2);
background-color: Highlight;
color: HighlightText;
cursor: pointer;
}
/*** Button icons ***/
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
.downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 48px, 16px, 32px);
}
.downloadButton.downloadShow {
-moz-image-region: rect(16px, 16px, 32px, 0px);
}
.downloadButton.downloadShow:hover {
-moz-image-region: rect(16px, 32px, 32px, 16px);
}
.downloadButton.downloadShow:active {
-moz-image-region: rect(16px, 48px, 32px, 32px);
}
.downloadButton.downloadRetry {
-moz-image-region: rect(32px, 16px, 48px, 0px);
}
.downloadButton.downloadRetry:hover {
-moz-image-region: rect(32px, 32px, 48px, 16px);
}
.downloadButton.downloadRetry:active {
-moz-image-region: rect(32px, 48px, 48px, 32px);
}
%ifdef WINSTRIPE_AERO
@media not all and (-moz-windows-default-theme) {
%endif
richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow {
-moz-image-region: rect(48px, 16px, 64px, 0px);
}
richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:hover {
-moz-image-region: rect(48px, 32px, 64px, 16px);
}
richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:active {
-moz-image-region: rect(48px, 48px, 64px, 32px);
}
%ifdef WINSTRIPE_AERO
}
%endif
/*** Status and progress indicator ***/
#downloads-indicator-anchor {
/* Makes the outermost stack element positioned, so that its contents are
rendered over the main browser window in the Z order. This is required by
the animated event notification. */
position: relative;
}
/*** Main indicator icon ***/
#downloads-indicator-icon {
background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
0, 108, 18, 90) center no-repeat;
min-width: 18px;
min-height: 18px;
}
#downloads-indicator-icon:-moz-lwtheme-brighttext {
background: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"),
0, 108, 18, 90) center no-repeat;
}
#downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
background-image: url("chrome://browser/skin/downloads/download-glow.png");
}
#downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
0, 108, 18, 90) center no-repeat;
background-size: 12px;
}
#downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
background-image: url("chrome://browser/skin/downloads/download-glow.png");
}
/*** Event notification ***/
#downloads-indicator-notification {
opacity: 0;
background: url("chrome://browser/skin/downloads/download-notification.png")
center no-repeat;
background-size: 16px;
}
@keyframes downloadsIndicatorNotificationRight {
from { opacity: 0; transform: translate(-128px, 128px) scale(8); }
20% { opacity: .85; animation-timing-function: ease-out; }
to { opacity: 0; transform: translate(0) scale(1); }
}
@keyframes downloadsIndicatorNotificationLeft {
from { opacity: 0; transform: translate(128px, 128px) scale(8); }
20% { opacity: .85; animation-timing-function: ease-out; }
to { opacity: 0; transform: translate(0) scale(1); }
}
#downloads-indicator[notification] > #downloads-indicator-anchor > #downloads-indicator-notification {
animation-name: downloadsIndicatorNotificationRight;
animation-duration: 1s;
}
#downloads-indicator[notification]:-moz-locale-dir(rtl) > #downloads-indicator-anchor > #downloads-indicator-notification {
animation-name: downloadsIndicatorNotificationLeft;
}
/*** Progress bar and text ***/
#downloads-indicator-counter {
height: 9px;
margin: -3px 0px 0px 0px;
color: hsl(0,0%,30%);
text-shadow: hsla(0,0%,100%,.5) 0 1px;
font-size: 9px;
line-height: 9px;
text-align: center;
}
#downloads-indicator-counter:-moz-lwtheme-brighttext {
color: white;
text-shadow: 0 0 1px rgba(0,0,0,.7),
0 1px 1.5px rgba(0,0,0,.5);
}
#downloads-indicator-progress {
width: 16px;
height: 5px;
min-width: 0;
min-height: 0;
margin-top: 1px;
margin-bottom: 2px;
border-radius: 2px;
box-shadow: 0 1px 0 hsla(0,0%,100%,.4);
}
#downloads-indicator-progress > .progress-bar {
-moz-appearance: none;
min-width: 0;
min-height: 0;
background-color: rgb(90, 201, 66);
background-image: linear-gradient(transparent 1px, rgba(255, 255, 255, 0.4) 1px, rgba(255, 255, 255, 0.4) 2px, transparent 2px);
border: 1px solid;
border-color: rgba(0,43,86,.6) rgba(0,43,86,.4) rgba(0,43,86,.4);
border-radius: 2px 0 0 2px;
}
#downloads-indicator-progress > .progress-remainder {
-moz-appearance: none;
min-width: 0;
min-height: 0;
background-image: linear-gradient(#505050, #575757);
border: 1px solid;
border-color: hsla(0,0%,0%,.6) hsla(0,0%,0%,.4) hsla(0,0%,0%,.4);
-moz-border-start: none;
border-radius: 0 2px 2px 0;
}
#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-bar {
background-color: rgb(220, 230, 81);
}
#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-remainder {
background-image: linear-gradient(#4b5000, #515700);
}

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