Merge m-c to s-c.

This commit is contained in:
Richard Newman 2013-02-03 00:51:21 -08:00
commit 082460c692
1197 changed files with 19363 additions and 40491 deletions

View File

@ -15,4 +15,4 @@
#
# Note: The description below will be part of the error message shown to users.
#
Bug 830231 - Remove nsIDOMDOM(Settable)TokenList (Needs clobber on at least Windows)
Bug 788293 - Remove e4x support

View File

@ -121,9 +121,17 @@ SettingsListener.observe('language.current', 'en-US', function(value) {
Ci.nsIPrefLocalizedString).data;
} catch(e) {}
// Bug 830782 - Homescreen is in English instead of selected locale after
// the first run experience.
// In order to ensure the current intl value is reflected on the child
// process let's always write a user value, even if this one match the
// current localized pref value.
if (!((new RegExp('^' + value + '[^a-z-_] *[,;]?', 'i')).test(intl))) {
Services.prefs.setCharPref(prefName, value + ', ' + intl);
value = value + ', ' + intl;
} else {
value = intl;
}
Services.prefs.setCharPref(prefName, value);
if (shell.hasStarted() == false) {
shell.start();
@ -197,13 +205,37 @@ SettingsListener.observe('devtools.debugger.remote-enabled', false, function(val
value ? RemoteDebugger.start() : RemoteDebugger.stop();
#ifdef MOZ_WIDGET_GONK
let enableAdb = value;
if (Services.prefs.getBoolPref('marionette.defaultPrefs.enabled')) {
// Marionette is enabled. Force adb on, since marionette requires remote
// debugging to be disabled (we don't want adb to track the remote debugger
// setting).
enableAdb = true;
}
// Configure adb.
try {
let current = libcutils.property_get("persist.sys.usb.config");
let prefix = current.replace(/,adb/, "");
libcutils.property_set("persist.sys.usb.config",
prefix + (value ? ",adb" : ""));
current = libcutils.property_get("persist.sys.usb.config");
let currentConfig = libcutils.property_get("persist.sys.usb.config");
let configFuncs = currentConfig.split(",");
let adbIndex = configFuncs.indexOf("adb");
if (enableAdb) {
// Add adb to the list of functions, if not already present
if (adbIndex < 0) {
configFuncs.push("adb");
}
} else {
// Remove adb from the list of functions, if present
if (adbIndex >= 0) {
configFuncs.splice(adbIndex,1);
}
}
let newConfig = configFuncs.join(",");
if (newConfig != currentConfig) {
libcutils.property_set("persist.sys.usb.config", newConfig);
}
} catch(e) {
dump("Error configuring adb: " + e);
}

View File

@ -13,6 +13,8 @@ Cu.import("resource://gre/modules/Services.jsm");
const XRE_OS_UPDATE_APPLY_TO_DIR = "OSUpdApplyToD"
const UPDATE_ARCHIVE_DIR = "UpdArchD"
const LOCAL_DIR = "/data/local";
const UPDATES_DIR = "updates/0";
const FOTA_DIR = "updates/fota";
XPCOMUtils.defineLazyServiceGetter(Services, "env",
"@mozilla.org/process/environment;1",
@ -64,10 +66,17 @@ DirectoryProvider.prototype = {
persistent.value = true;
return file;
}
if (prop == XRE_OS_UPDATE_APPLY_TO_DIR ||
prop == UPDATE_ARCHIVE_DIR) {
let file = this.getUpdateDir(persistent);
return file;
if (prop == UPDATE_ARCHIVE_DIR) {
// getUpdateDir will set persistent to false since it may toggle between
// /data/local/ and /mnt/sdcard based on free space and/or availability
// of the sdcard.
return this.getUpdateDir(persistent, UPDATES_DIR);
}
if (prop == XRE_OS_UPDATE_APPLY_TO_DIR) {
// getUpdateDir will set persistent to false since it may toggle between
// /data/local/ and /mnt/sdcard based on free space and/or availability
// of the sdcard.
return this.getUpdateDir(persistent, FOTA_DIR);
}
#endif
return null;
@ -92,14 +101,14 @@ DirectoryProvider.prototype = {
return requiredSpace <= stat.freeBytes;
},
findUpdateDirWithFreeSpace: function dp_findUpdateDirWithFreeSpace(requiredSpace) {
findUpdateDirWithFreeSpace: function dp_findUpdateDirWithFreeSpace(requiredSpace, subdir) {
if (!Services.volumeService) {
return this.createUpdatesDir(LOCAL_DIR);
return this.createUpdatesDir(LOCAL_DIR, subdir);
}
let activeUpdate = Services.um.activeUpdate;
if (gUseSDCard) {
if (this.volumeHasFreeSpace(gExtStorage, requiredSpace)) {
let extUpdateDir = this.createUpdatesDir(gExtStorage);
let extUpdateDir = this.createUpdatesDir(gExtStorage, subdir);
if (extUpdateDir !== null) {
return extUpdateDir;
}
@ -109,7 +118,7 @@ DirectoryProvider.prototype = {
}
if (this.volumeHasFreeSpace(LOCAL_DIR, requiredSpace)) {
let localUpdateDir = this.createUpdatesDir(LOCAL_DIR);
let localUpdateDir = this.createUpdatesDir(LOCAL_DIR, subdir);
if (localUpdateDir !== null) {
return localUpdateDir;
}
@ -120,7 +129,7 @@ DirectoryProvider.prototype = {
return null;
},
getUpdateDir: function dp_getUpdateDir(persistent) {
getUpdateDir: function dp_getUpdateDir(persistent, subdir) {
let defaultUpdateDir = this.getDefaultUpdateDir();
persistent.value = false;
@ -139,7 +148,7 @@ DirectoryProvider.prototype = {
}
let requiredSpace = selectedPatch.size * 2;
let updateDir = this.findUpdateDirWithFreeSpace(requiredSpace, persistent);
let updateDir = this.findUpdateDirWithFreeSpace(requiredSpace, subdir);
if (updateDir) {
return updateDir;
}
@ -152,24 +161,25 @@ DirectoryProvider.prototype = {
throw Cr.NS_ERROR_FILE_TOO_BIG;
},
createUpdatesDir: function dp_createUpdatesDir(root) {
createUpdatesDir: function dp_createUpdatesDir(root, subdir) {
let dir = Cc["@mozilla.org/file/local;1"]
.createInstance(Ci.nsILocalFile);
dir.initWithPath(root);
if (!dir.isWritable()) {
log("Error: " + dir.path + " isn't writable");
return null;
}
dir.appendRelativePath("updates/0");
dir.appendRelativePath(subdir);
if (dir.exists()) {
if (dir.isDirectory() && dir.isWritable()) {
return dir;
}
// updates/0 is either a file or isn't writable. In either case we
// subdir is either a file or isn't writable. In either case we
// can't use it.
log("Error: " + dir.path + " is a file or isn't writable");
return null;
}
// updates/0 doesn't exist, and the parent is writable, so try to
// subdir doesn't exist, and the parent is writable, so try to
// create it. This can fail if a file named updates exists.
try {
dir.create(Ci.nsIFile.DIRECTORY_TYPE, 0770);

View File

@ -19,7 +19,12 @@ function log(msg) {
#ifdef MOZ_WIDGET_GONK
let librecovery = (function() {
let library = ctypes.open("librecovery.so");
try {
let library = ctypes.open("librecovery.so");
} catch (e) {
log("Unable to open librecovery.so");
throw Cr.NS_ERROR_FAILURE;
}
let FotaUpdateStatus = new ctypes.StructType("FotaUpdateStatus", [
{ result: ctypes.int },
{ updatePath: ctypes.char.ptr }
@ -73,7 +78,6 @@ RecoveryService.prototype = {
log("Error: FOTA install failed");
}
#endif
throw Cr.NS_ERROR_FAILURE;
},
@ -81,6 +85,7 @@ RecoveryService.prototype = {
let status = Ci.nsIRecoveryService.FOTA_UPDATE_UNKNOWN;
#ifdef MOZ_WIDGET_GONK
let cStatus = librecovery.FotaUpdateStatus();
if (librecovery.getFotaUpdateStatus(cStatus.address()) == 0) {
status = cStatus.result;
}

View File

@ -8,6 +8,7 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
@ -374,16 +375,21 @@ UpdatePrompt.prototype = {
},
finishOSUpdate: function UP_finishOSUpdate(aOsUpdatePath) {
let recoveryService = Cc["@mozilla.org/recovery-service;1"]
.getService(Ci.nsIRecoveryService);
log("Rebooting into recovery to apply FOTA update: " + aOsUpdatePath);
try {
let recoveryService = Cc["@mozilla.org/recovery-service;1"]
.getService(Ci.nsIRecoveryService);
recoveryService.installFotaUpdate(aOsUpdatePath);
} catch(e) {
log("Error: Couldn't reboot into recovery to apply FOTA update " +
aOsUpdatePath);
aUpdate = Services.um.activeUpdate;
if (aUpdate) {
aUpdate.errorCode = Cr.NS_ERROR_FAILURE;
aUpdate.statusText = "fota-reboot-failed";
this.showUpdateError(aUpdate);
}
}
},

View File

@ -20,5 +20,6 @@
"vcs": "hgtool",
"root": "http://hg.mozilla.org/gaia-l10n"
}
}
},
"upload_platform": "panda_gaia_central"
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1358893928000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1359495205000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -207,6 +207,10 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i258" id="helperbar@helperbar.com">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
<versionRange minVersion="0.1" maxVersion="*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
@ -302,6 +306,10 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i262" id="{167d9323-f7cc-48f5-948a-6f012831a69f}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i196" id="info@wxdownloadmanager.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
@ -509,7 +517,11 @@
<match name="filename" exp="AdobePDFViewerNPAPI\.plugin" /> <versionRange minVersion="0" maxVersion="10.1.3" severity="1"></versionRange>
</pluginItem>
<pluginItem blockID="p94">
<match name="filename" exp="Flash\ Player\.plugin" /> <versionRange minVersion="0" maxVersion="10.2.159.1" severity="0"></versionRange>
<match name="filename" exp="Flash\ Player\.plugin" /> <versionRange minVersion="0" maxVersion="10.2.159.1" severity="0">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="0" maxVersion="17.*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p102">
<match name="filename" exp="npmozax\.dll" /> <versionRange minVersion="0" maxVersion="*"></versionRange>
@ -684,6 +696,13 @@
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p260">
<match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" /> <versionRange minVersion="0" maxVersion="10.2.9999" severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="18.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
</pluginItems>
<gfxItems>

View File

@ -521,9 +521,10 @@ pref("browser.gesture.pinch.out.shift", "");
pref("browser.gesture.pinch.in.shift", "");
#endif
pref("browser.gesture.twist.latched", false);
pref("browser.gesture.twist.threshold", 25);
pref("browser.gesture.twist.right", "");
pref("browser.gesture.twist.left", "");
pref("browser.gesture.twist.threshold", 0);
pref("browser.gesture.twist.right", "cmd_gestureRotateRight");
pref("browser.gesture.twist.left", "cmd_gestureRotateLeft");
pref("browser.gesture.twist.end", "cmd_gestureRotateEnd");
pref("browser.gesture.tap", "cmd_fullZoomReset");
// 0: Nothing happens

View File

@ -11,6 +11,7 @@
#endif
return;
}
updateCharacterEncodingMenuState();
if (event.target.parentNode.parentNode.parentNode.parentNode == this)
this._currentPopup = event.target;">
<hbox>

View File

@ -1,22 +1,11 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
Cu.import("resource://services-common/log4moz.js");
# 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/.
/**
* Represents an info bar that shows a data submission notification.
*/
function DataNotificationInfoBar() {
let log4moz = Cu.import("resource://services-common/log4moz.js", {}).Log4Moz;
this._log = log4moz.repository.getLogger("Services.DataReporting.InfoBar");
this._notificationBox = null;
}
DataNotificationInfoBar.prototype = {
let gDataNotificationInfoBar = {
_OBSERVERS: [
"datareporting:notify-data-policy:request",
"datareporting:notify-data-policy:close",
@ -24,6 +13,14 @@ DataNotificationInfoBar.prototype = {
_DATA_REPORTING_NOTIFICATION: "data-reporting",
_notificationBox: null,
get _log() {
let log4moz = Cu.import("resource://services-common/log4moz.js", {}).Log4Moz;
delete this._log;
return this._log = log4moz.repository.getLogger("Services.DataReporting.InfoBar");
},
init: function() {
window.addEventListener("unload", function onUnload() {
window.removeEventListener("unload", onUnload, false);

View File

@ -178,7 +178,8 @@
<menu id="view-menu" label="&viewMenu.label;"
accesskey="&viewMenu.accesskey;">
<menupopup id="menu_viewPopup">
<menupopup id="menu_viewPopup"
onpopupshowing="updateCharacterEncodingMenuState();">
<menu id="viewToolbarsMenu"
label="&viewToolbarsMenu.label;"
accesskey="&viewToolbarsMenu.accesskey;">

View File

@ -84,6 +84,9 @@
<command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
<command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/>
<command id="cmd_fullZoomToggle" oncommand="ZoomManager.toggleZoom();"/>
<command id="cmd_gestureRotateLeft" oncommand="gGestureSupport.rotate(event.sourceEvent)"/>
<command id="cmd_gestureRotateRight" oncommand="gGestureSupport.rotate(event.sourceEvent)"/>
<command id="cmd_gestureRotateEnd" oncommand="gGestureSupport.rotateEnd()"/>
<command id="Browser:OpenLocation" oncommand="openLocation();"/>
<command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="true"/>

View File

@ -159,8 +159,6 @@ let gInitialPages = [
#ifdef MOZ_DATA_REPORTING
#include browser-data-submission-info-bar.js
let gDataNotificationInfoBar = new DataNotificationInfoBar();
#endif
#ifdef MOZ_SERVICES_SYNC
@ -172,9 +170,7 @@ XPCOMUtils.defineLazyGetter(this, "Win7Features", function () {
const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
if (WINTASKBAR_CONTRACTID in Cc &&
Cc[WINTASKBAR_CONTRACTID].getService(Ci.nsIWinTaskbar).available) {
let temp = {};
Cu.import("resource:///modules/WindowsPreviewPerTab.jsm", temp);
let AeroPeek = temp.AeroPeek;
let AeroPeek = Cu.import("resource:///modules/WindowsPreviewPerTab.jsm", {}).AeroPeek;
return {
onOpenWindow: function () {
AeroPeek.onOpenWindow(window);
@ -740,6 +736,10 @@ const gFormSubmitObserver = {
// the capturing phase and call stopPropagation on every event.
let gGestureSupport = {
_currentRotation: 0,
_lastRotateDelta: 0,
_rotateMomentumThreshold: .75,
/**
* Add or remove mouse gesture event listeners
*
@ -800,6 +800,10 @@ let gGestureSupport = {
aEvent.preventDefault();
this._doAction(aEvent, ["tap"]);
break;
case "MozRotateGesture":
aEvent.preventDefault();
this._doAction(aEvent, ["twist", "end"]);
break;
/* case "MozPressTapGesture":
break; */
}
@ -916,7 +920,7 @@ let gGestureSupport = {
let cmdEvent = document.createEvent("xulcommandevent");
cmdEvent.initCommandEvent("command", true, true, window, 0,
aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
aEvent.metaKey, null);
aEvent.metaKey, aEvent);
node.dispatchEvent(cmdEvent);
}
} else {
@ -976,6 +980,123 @@ let gGestureSupport = {
return aDef;
}
},
/**
* Perform rotation for ImageDocuments
*
* @param aEvent
* The MozRotateGestureUpdate event triggering this call
*/
rotate: function(aEvent) {
if (!(content.document instanceof ImageDocument))
return;
let contentElement = content.document.body.firstElementChild;
if (!contentElement)
return;
this.rotation = Math.round(this.rotation + aEvent.delta);
contentElement.style.transform = "rotate(" + this.rotation + "deg)";
this._lastRotateDelta = aEvent.delta;
},
/**
* Perform a rotation end for ImageDocuments
*/
rotateEnd: function() {
if (!(content.document instanceof ImageDocument))
return;
let contentElement = content.document.body.firstElementChild;
if (!contentElement)
return;
let transitionRotation = 0;
// The reason that 360 is allowed here is because when rotating between
// 315 and 360, setting rotate(0deg) will cause it to rotate the wrong
// direction around--spinning wildly.
if (this.rotation <= 45)
transitionRotation = 0;
else if (this.rotation > 45 && this.rotation <= 135)
transitionRotation = 90;
else if (this.rotation > 135 && this.rotation <= 225)
transitionRotation = 180;
else if (this.rotation > 225 && this.rotation <= 315)
transitionRotation = 270;
else
transitionRotation = 360;
// If we're going fast enough, and we didn't already snap ahead of rotation,
// then snap ahead of rotation to simulate momentum
if (this._lastRotateDelta > this._rotateMomentumThreshold &&
this.rotation > transitionRotation)
transitionRotation += 90;
else if (this._lastRotateDelta < -1 * this._rotateMomentumThreshold &&
this.rotation < transitionRotation)
transitionRotation -= 90;
contentElement.classList.add("completeRotation");
contentElement.addEventListener("transitionend", this._clearCompleteRotation);
contentElement.style.transform = "rotate(" + transitionRotation + "deg)";
this.rotation = transitionRotation;
},
/**
* Gets the current rotation for the ImageDocument
*/
get rotation() {
return this._currentRotation;
},
/**
* Sets the current rotation for the ImageDocument
*
* @param aVal
* The new value to take. Can be any value, but it will be bounded to
* 0 inclusive to 360 exclusive.
*/
set rotation(aVal) {
this._currentRotation = aVal % 360;
if (this._currentRotation < 0)
this._currentRotation += 360;
return this._currentRotation;
},
/**
* When the location/tab changes, need to reload the current rotation for the
* image
*/
restoreRotationState: function() {
if (!(content.document instanceof ImageDocument))
return;
let contentElement = content.document.body.firstElementChild;
let transformValue = content.window.getComputedStyle(contentElement, null)
.transform;
if (transformValue == "none") {
this.rotation = 0;
return;
}
// transformValue is a rotation matrix--split it and do mathemagic to
// obtain the real rotation value
transformValue = transformValue.split("(")[1]
.split(")")[0]
.split(",");
this.rotation = Math.round(Math.atan2(transformValue[1], transformValue[0]) *
(180 / Math.PI));
},
/**
* Removes the transition rule by removing the completeRotation class
*/
_clearCompleteRotation: function() {
this.classList.remove("completeRotation");
this.removeEventListener("transitionend", this._clearCompleteRotation);
},
};
var gBrowserInit = {
@ -1265,7 +1386,7 @@ var gBrowserInit = {
gBrowser.addEventListener("pageshow", function(event) {
// Filter out events that are not about the document load we are interested in
if (event.target == content.document)
if (content && event.target == content.document)
setTimeout(pageShowEventHandlers, 0, event);
}, true);
@ -1350,10 +1471,9 @@ var gBrowserInit = {
#ifdef XP_WIN
if (Win7Features) {
let tempScope = {};
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm",
tempScope);
tempScope.DownloadTaskbarProgress.onBrowserWindowLoad(window);
let DownloadTaskbarProgress =
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
DownloadTaskbarProgress.onBrowserWindowLoad(window);
}
#endif
}, 10000);
@ -3767,6 +3887,44 @@ function updateEditUIVisibility()
#endif
}
/**
* Makes the Character Encoding menu enabled or disabled as appropriate.
* To be called when the View menu or the app menu is opened.
*/
function updateCharacterEncodingMenuState()
{
let charsetMenu = document.getElementById("charsetMenu");
let appCharsetMenu = document.getElementById("appmenu_charsetMenu");
let appDevCharsetMenu =
document.getElementById("appmenu_developer_charsetMenu");
// gBrowser is null on Mac when the menubar shows in the context of
// non-browser windows. The above elements may be null depending on
// what parts of the menubar are present. E.g. no app menu on Mac.
if (gBrowser &&
gBrowser.docShell &&
gBrowser.docShell.mayEnableCharacterEncodingMenu) {
if (charsetMenu) {
charsetMenu.removeAttribute("disabled");
}
if (appCharsetMenu) {
appCharsetMenu.removeAttribute("disabled");
}
if (appDevCharsetMenu) {
appDevCharsetMenu.removeAttribute("disabled");
}
} else {
if (charsetMenu) {
charsetMenu.setAttribute("disabled", "true");
}
if (appCharsetMenu) {
appCharsetMenu.setAttribute("disabled", "true");
}
if (appDevCharsetMenu) {
appDevCharsetMenu.setAttribute("disabled", "true");
}
}
}
/**
* Returns true if |aMimeType| is text-based, false otherwise.
*
@ -4189,6 +4347,8 @@ var XULBrowserWindow = {
}
UpdateBackForwardCommands(gBrowser.webNavigation);
gGestureSupport.restoreRotationState();
// See bug 358202, when tabs are switched during a drag operation,
// timers don't fire on windows (bug 203573)
if (aRequest)
@ -7117,15 +7277,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "gDevToolsBrowser",
"resource:///modules/devtools/gDevTools.jsm");
XPCOMUtils.defineLazyGetter(this, "HUDConsoleUI", function () {
let tempScope = {};
Cu.import("resource:///modules/HUDService.jsm", tempScope);
try {
return tempScope.HUDService.consoleUI;
}
catch (ex) {
Components.utils.reportError(ex);
return null;
}
return Cu.import("resource:///modules/HUDService.jsm", {}).HUDService.consoleUI;
});
// Prompt user to restart the browser in safe mode

View File

@ -80,6 +80,7 @@ html|*.highlighter-nodeinfobar-classes,
html|*.highlighter-nodeinfobar-pseudo-classes,
html|*.highlighter-nodeinfobar-tagname {
-moz-user-select: text;
-moz-user-focus: normal;
cursor: text;
}

View File

@ -33,7 +33,7 @@ function test()
test_commandset = document.getElementById("mainCommandSet");
test_swipeGestures();
test_latchedGesture("pinch", "out", "in", "MozMagnifyGesture");
test_latchedGesture("twist", "right", "left", "MozRotateGesture");
// We don't latch the rotate event (see bug 833511)
test_thresholdGesture("pinch", "out", "in", "MozMagnifyGesture");
test_thresholdGesture("twist", "right", "left", "MozRotateGesture");
}

View File

@ -35,6 +35,9 @@ Cu.import("resource:///modules/source-editor.jsm");
Cu.import("resource:///modules/devtools/LayoutHelpers.jsm");
Cu.import("resource:///modules/devtools/VariablesView.jsm");
XPCOMUtils.defineLazyModuleGetter(this,
"Reflect", "resource://gre/modules/reflect.jsm");
/**
* Object defining the debugger controller components.
*/
@ -426,6 +429,9 @@ function StackFrames() {
this._onFrames = this._onFrames.bind(this);
this._onFramesCleared = this._onFramesCleared.bind(this);
this._afterFramesCleared = this._afterFramesCleared.bind(this);
this._fetchScopeVariables = this._fetchScopeVariables.bind(this);
this._fetchVarProperties = this._fetchVarProperties.bind(this);
this._addVarExpander = this._addVarExpander.bind(this);
this.evaluate = this.evaluate.bind(this);
}
@ -684,7 +690,7 @@ StackFrames.prototype = {
// Handle additions to the innermost scope.
if (environment == frame.environment) {
this._insertScopeFrameReferences(scope, frame);
this._fetchScopeVariables(scope, environment);
this._addScopeExpander(scope, environment);
// Always expand the innermost scope by default.
scope.expand();
}
@ -710,12 +716,12 @@ StackFrames.prototype = {
* The scope's environment.
*/
_addScopeExpander: function SF__addScopeExpander(aScope, aEnv) {
let callback = this._fetchScopeVariables.bind(this, aScope, aEnv);
aScope._sourceEnvironment = aEnv;
// It's a good idea to be prepared in case of an expansion.
aScope.addEventListener("mouseover", callback, false);
aScope.addEventListener("mouseover", this._fetchScopeVariables, false);
// Make sure that variables are always available on expansion.
aScope.onexpand = callback;
aScope.onexpand = this._fetchScopeVariables;
},
/**
@ -732,15 +738,15 @@ StackFrames.prototype = {
if (VariablesView.isPrimitive({ value: aGrip })) {
return;
}
let callback = this._fetchVarProperties.bind(this, aVar, aGrip);
aVar._sourceGrip = aGrip;
// Some variables are likely to contain a very large number of properties.
// It's a good idea to be prepared in case of an expansion.
if (aVar.name == "window" || aVar.name == "this") {
aVar.addEventListener("mouseover", callback, false);
aVar.addEventListener("mouseover", this._fetchVarProperties, false);
}
// Make sure that properties are always available on expansion.
aVar.onexpand = callback;
aVar.onexpand = this._fetchVarProperties;
},
/**
@ -788,21 +794,20 @@ StackFrames.prototype = {
*
* @param Scope aScope
* The scope where the variables will be placed into.
* @param object aEnv
* The scope's environment.
*/
_fetchScopeVariables: function SF__fetchScopeVariables(aScope, aEnv) {
_fetchScopeVariables: function SF__fetchScopeVariables(aScope) {
// Fetch the variables only once.
if (aScope._fetched) {
return;
}
aScope._fetched = true;
let env = aScope._sourceEnvironment;
switch (aEnv.type) {
switch (env.type) {
case "with":
case "object":
// Add nodes for every variable in scope.
this.activeThread.pauseGrip(aEnv.object).getPrototypeAndProperties(function(aResponse) {
this.activeThread.pauseGrip(env.object).getPrototypeAndProperties(function(aResponse) {
this._insertScopeVariables(aResponse.ownProperties, aScope);
// Signal that variables have been fetched.
@ -813,15 +818,15 @@ StackFrames.prototype = {
case "block":
case "function":
// Add nodes for every argument and every other variable in scope.
this._insertScopeArguments(aEnv.bindings.arguments, aScope);
this._insertScopeVariables(aEnv.bindings.variables, aScope);
this._insertScopeArguments(env.bindings.arguments, aScope);
this._insertScopeVariables(env.bindings.variables, aScope);
// No need to signal that variables have been fetched, since
// the scope arguments and variables are already attached to the
// environment bindings, so pausing the active thread is unnecessary.
break;
default:
Cu.reportError("Unknown Debugger.Environment type: " + aEnv.type);
Cu.reportError("Unknown Debugger.Environment type: " + env.type);
break;
}
},
@ -899,27 +904,27 @@ StackFrames.prototype = {
*
* @param Variable aVar
* The variable where the properties will be placed into.
* @param any aGrip
* The grip of the variable.
*/
_fetchVarProperties: function SF__fetchVarProperties(aVar, aGrip) {
_fetchVarProperties: function SF__fetchVarProperties(aVar) {
// Fetch the properties only once.
if (aVar._fetched) {
return;
}
aVar._fetched = true;
let grip = aVar._sourceGrip;
this.activeThread.pauseGrip(aGrip).getPrototypeAndProperties(function(aResponse) {
this.activeThread.pauseGrip(grip).getPrototypeAndProperties(function(aResponse) {
let { ownProperties, prototype } = aResponse;
let sortable = VARIABLES_VIEW_NON_SORTABLE.indexOf(aGrip.class) == -1;
let sortable = VARIABLES_VIEW_NON_SORTABLE.indexOf(grip.class) == -1;
// Add all the variable properties.
if (ownProperties) {
aVar.addProperties(ownProperties, { sorted: sortable });
// Expansion handlers must be set after the properties are added.
for (let name in ownProperties) {
this._addVarExpander(aVar.get(name), ownProperties[name].value);
}
aVar.addProperties(ownProperties, {
// Not all variables need to force sorted properties.
sorted: sortable,
// Expansion handlers must be set after the properties are added.
callback: this._addVarExpander
});
}
// Add the variable's __proto__.
@ -1002,17 +1007,37 @@ StackFrames.prototype = {
syncWatchExpressions: function SF_syncWatchExpressions() {
let list = DebuggerView.WatchExpressions.getExpressions();
if (list.length) {
// Sanity check all watch expressions before syncing them. To avoid
// having the whole watch expressions array throw because of a single
// faulty expression, simply convert it to a string describing the error.
// There's no other information necessary to be offered in such cases.
let sanitizedExpressions = list.map(function(str) {
// Reflect.parse throws when encounters a syntax error.
try {
Reflect.parse(str);
return str; // Watch expression can be executed safely.
} catch (e) {
return "\"" + e.name + ": " + e.message + "\""; // Syntax error.
}
});
if (sanitizedExpressions.length) {
this.syncedWatchExpressions =
this.currentWatchExpressions = "[" + list.map(function(str)
// Avoid yielding an empty pseudo-array when evaluating `arguments`,
// since they're overridden by the expression's closure scope.
"(function(arguments) {" +
// Make sure all the quotes are escaped in the expression's syntax.
"try { return eval(\"" + str.replace(/"/g, "\\$&") + "\"); }" +
"catch(e) { return e.name + ': ' + e.message; }" +
"})(arguments)"
).join(",") + "]";
this.currentWatchExpressions =
"[" +
sanitizedExpressions.map(function(str)
"eval(\"" +
"try {" +
// Make sure all quotes are escaped in the expression's syntax,
// and add a newline after the statement to avoid comments
// breaking the code integrity inside the eval block.
str.replace(/"/g, "\\$&") + "\" + " + "'\\n'" + " + \"" +
"} catch (e) {" +
"e.name + ': ' + e.message;" + // FIXME: bug 812765, 812764
"}" +
"\")"
).join(",") +
"]";
} else {
this.syncedWatchExpressions =
this.currentWatchExpressions = null;

View File

@ -952,8 +952,6 @@ function WatchExpressionsView() {
this._onClose = this._onClose.bind(this);
this._onBlur = this._onBlur.bind(this);
this._onKeyPress = this._onKeyPress.bind(this);
this._onMouseOver = this._onMouseOver.bind(this);
this._onMouseOut = this._onMouseOut.bind(this);
}
create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
@ -997,7 +995,7 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
unsorted: true,
relaxed: true,
attachment: {
expression: "",
currentExpression: "",
initialExpression: aExpression,
id: this._generateId()
}
@ -1046,7 +1044,7 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
*/
switchExpression: function DVWE_switchExpression(aVar, aExpression) {
let expressionItem =
[i for (i of this._cache) if (i.attachment.expression == aVar.name)][0];
[i for (i of this._cache) if (i.attachment.currentExpression == aVar.name)][0];
// Remove the watch expression if it's going to be a duplicate.
if (!aExpression || this.getExpressions().indexOf(aExpression) != -1) {
@ -1055,7 +1053,7 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
}
// Save the watch expression code string.
expressionItem.attachment.expression = aExpression;
expressionItem.attachment.currentExpression = aExpression;
expressionItem.target.inputNode.value = aExpression;
// Synchronize with the controller's watch expressions store.
@ -1070,7 +1068,7 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
*/
deleteExpression: function DVWE_deleteExpression(aVar) {
let expressionItem =
[i for (i of this._cache) if (i.attachment.expression == aVar.name)][0];
[i for (i of this._cache) if (i.attachment.currentExpression == aVar.name)][0];
// Remove the watch expression at its respective index.
this.removeExpressionAt(this._cache.indexOf(expressionItem));
@ -1088,7 +1086,7 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
* The watch expression code string.
*/
getExpression: function DVWE_getExpression(aIndex) {
return this._cache[aIndex].attachment.expression;
return this._cache[aIndex].attachment.currentExpression;
},
/**
@ -1098,7 +1096,7 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
* The watch expressions code strings.
*/
getExpressions: function DVWE_getExpressions() {
return [item.attachment.expression for (item of this._cache)];
return [item.attachment.currentExpression for (item of this._cache)];
},
/**
@ -1120,8 +1118,6 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
closeNode.addEventListener("click", this._onClose, false);
inputNode.addEventListener("blur", this._onBlur, false);
inputNode.addEventListener("keypress", this._onKeyPress, false);
aElementNode.addEventListener("mouseover", this._onMouseOver, false);
aElementNode.addEventListener("mouseout", this._onMouseOut, false);
aElementNode.appendChild(arrowNode);
aElementNode.appendChild(inputNode);
@ -1187,7 +1183,7 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
*/
_onBlur: function DVWE__onBlur({ target: textbox }) {
let expressionItem = this.getItemForElement(textbox);
let oldExpression = expressionItem.attachment.expression;
let oldExpression = expressionItem.attachment.currentExpression;
let newExpression = textbox.value.trim();
// Remove the watch expression if it's empty.
@ -1200,10 +1196,7 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
}
// Expression is eligible.
else {
// Save the watch expression code string.
expressionItem.attachment.expression = newExpression;
// Make sure the close button is hidden when the textbox is unfocused.
expressionItem.target.closeNode.hidden = true;
expressionItem.attachment.currentExpression = newExpression;
}
// Synchronize with the controller's watch expressions store.
@ -1223,20 +1216,6 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
}
},
/**
* The mouse over listener for a watch expression.
*/
_onMouseOver: function DVWE__onMouseOver({ target: element }) {
this.getItemForElement(element).target.closeNode.hidden = false;
},
/**
* The mouse out listener for a watch expression.
*/
_onMouseOut: function DVWE__onMouseOut({ target: element }) {
this.getItemForElement(element).target.closeNode.hidden = true;
},
/**
* Gets an identifier for a new watch expression item in the current cache.
* @return string

View File

@ -1018,6 +1018,14 @@ FilterView.prototype = {
this._searchboxPanel.hidePopup();
},
/**
* Called when the variables focus key sequence was pressed.
*/
_doVariablesFocus: function DVG__doVariablesFocus() {
DebuggerView.showPanesSoon();
DebuggerView.Variables.focusFirstVisibleNode();
},
_searchbox: null,
_searchboxPanel: null,
_globalOperatorButton: null,

View File

@ -39,6 +39,15 @@
overflow: hidden;
}
/**
* Watch expressions view
*/
#expressions {
overflow-x: hidden;
overflow-y: auto;
}
/**
* Variables view
*/
@ -52,21 +61,20 @@
* Scope, variable and property elements
*/
#variables .details:not([open]) {
.details:not([open]) {
display: none;
}
.scope,
.variable,
.property {
-moz-user-focus: normal;
}
.scope[non-header] > .title,
.variable[non-header] > .title,
.property[non-header] > .title {
display: none;
}
/**
* Variables and properties searching
*/
.variable[non-match] > .title,
.property[non-header] > .title,
.property[non-match] > .title {
display: none;
}

View File

@ -43,6 +43,8 @@
oncommand="DebuggerView.Filtering._doLineSearch()"/>
<command id="variableSearchCommand"
oncommand="DebuggerView.Filtering._doVariableSearch()"/>
<command id="variablesFocusCommand"
oncommand="DebuggerView.Filtering._doVariablesFocus()"/>
<command id="addBreakpointCommand"
oncommand="DebuggerView.Breakpoints._onCmdAddBreakpoint()"/>
<command id="addConditionalBreakpointCommand"
@ -108,6 +110,11 @@
accesskey="&debuggerUI.searchVariable.key;"
key="variableSearchKey"
command="variableSearchCommand"/>
<menuitem id="se-dbg-cMenu-focusVariables"
label="&debuggerUI.focusVariables;"
accesskey="&debuggerUI.focusVariables.key;"
key="variablesFocusKey"
command="variablesFocusCommand"/>
</menupopup>
<menupopup id="debuggerWatchExpressionsContextMenu">
@ -184,6 +191,10 @@
key="&debuggerUI.searchVariable.key;"
modifiers="accel alt"
command="variableSearchCommand"/>
<key id="variablesFocusKey"
key="&debuggerUI.focusVariables.key;"
modifiers="accel shift"
command="variablesFocusCommand"/>
<key id="addBreakpointKey"
key="&debuggerUI.seMenuBreak.key;"
modifiers="accel"

View File

@ -32,9 +32,11 @@ MOCHITEST_BROWSER_TESTS = \
browser_dbg_propertyview-08.js \
browser_dbg_propertyview-09.js \
browser_dbg_propertyview-10.js \
browser_dbg_propertyview-edit.js \
browser_dbg_propertyview-edit-value.js \
browser_dbg_propertyview-edit-watch.js \
browser_dbg_propertyview-big-data.js \
browser_dbg_propertyview-data-big.js \
browser_dbg_propertyview-data-getset-01.js \
browser_dbg_propertyview-data-getset-02.js \
browser_dbg_propertyview-data.js \
browser_dbg_propertyview-filter-01.js \
browser_dbg_propertyview-filter-02.js \

View File

@ -23,10 +23,7 @@ function test()
gWatch = gDebugger.DebuggerView.WatchExpressions;
gDebugger.DebuggerView.togglePanes({ visible: true, animated: false });
executeSoon(function() {
performTest();
});
performTest();
});
function performTest()
@ -129,9 +126,9 @@ function test()
is(gWatch.getItemForElement(element).attachment.initialExpression, "",
"The initial expression at index " + index + " should be correct (2)");
is(gWatch.getItemAtIndex(index).attachment.expression, string,
is(gWatch.getItemAtIndex(index).attachment.currentExpression, string,
"The expression at index " + index + " should be correct (1)");
is(gWatch.getItemForElement(element).attachment.expression, string,
is(gWatch.getItemForElement(element).attachment.currentExpression, string,
"The expression at index " + index + " should be correct (2)");
is(gWatch.getExpression(index), string,
@ -195,9 +192,9 @@ function test()
is(gWatch.getItemForElement(element).attachment.initialExpression, string,
"The initial expression at index " + index + " should be correct (2)");
is(gWatch.getItemAtIndex(index).attachment.expression, string,
is(gWatch.getItemAtIndex(index).attachment.currentExpression, string,
"The expression at index " + index + " should be correct (1)");
is(gWatch.getItemForElement(element).attachment.expression, string,
is(gWatch.getItemForElement(element).attachment.currentExpression, string,
"The expression at index " + index + " should be correct (2)");
is(gWatch.getExpression(index), string,
@ -230,9 +227,9 @@ function test()
is(gWatch.getItemForElement(element).attachment.initialExpression, string,
"The initial expression at index " + index + " should be correct (2)");
is(gWatch.getItemAtIndex(index).attachment.expression, string,
is(gWatch.getItemAtIndex(index).attachment.currentExpression, string,
"The expression at index " + index + " should be correct (1)");
is(gWatch.getItemForElement(element).attachment.expression, string,
is(gWatch.getItemForElement(element).attachment.currentExpression, string,
"The expression at index " + index + " should be correct (2)");
is(gWatch.getExpression(index), string,

View File

@ -37,6 +37,8 @@ function test()
gWatch.addExpression("\"a''\"");
gWatch.addExpression("?");
gWatch.addExpression("a");
gWatch.addExpression("this");
gWatch.addExpression("this.canada");
gWatch.addExpression("[1, 2, 3]");
gWatch.addExpression("x = [1, 2, 3]");
gWatch.addExpression("y = [1, 2, 3]; y.test = 4");
@ -45,14 +47,25 @@ function test()
gWatch.addExpression("arguments[0]");
gWatch.addExpression("encodeURI(\"\\\")");
gWatch.addExpression("decodeURI(\"\\\")");
gWatch.addExpression("decodeURIComponent(\"%\")");
gWatch.addExpression("//");
gWatch.addExpression("// 42");
gWatch.addExpression("{}.foo");
gWatch.addExpression("{}.foo()");
gWatch.addExpression("({}).foo()");
gWatch.addExpression("new Array(-1)");
gWatch.addExpression("4.2.toExponential(-4.2)");
gWatch.addExpression("throw new Error(\"bazinga\")");
gWatch.addExpression("({ get error() { throw new Error(\"bazinga\") } }).error");
gWatch.addExpression("throw { get name() { throw \"bazinga\" } }");
}
function performTest()
{
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 0,
"There should be 0 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 14,
"There should be 14 visible nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 27,
"There should be 27 visible nodes in the watch expressions container");
test1(function() {
test2(function() {
@ -79,8 +92,8 @@ function test()
{
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 0,
"There should be 0 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 13,
"There should be 13 visible nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 27,
"There should be 27 visible nodes in the watch expressions container");
closeDebuggerAndFinish();
}
@ -88,18 +101,26 @@ function test()
function test1(callback) {
waitForWatchExpressions(function() {
info("Performing test1");
checkWatchExpressions("ReferenceError: a is not defined", undefined);
checkWatchExpressions("ReferenceError: a is not defined",
{ type: "object", class: "Object" },
{ type: "object", class: "String" },
undefined,
26);
callback();
});
executeSoon(function() {
gDebuggee.ermahgerd(); // ermahgerd!!
gDebuggee.test(); // ermahgerd!!
});
}
function test2(callback) {
waitForWatchExpressions(function() {
info("Performing test2");
checkWatchExpressions(undefined, "sensational");
checkWatchExpressions(undefined,
{ type: "object", class: "Proxy" },
undefined,
"sensational",
26);
callback();
});
EventUtils.sendMouseEvent({ type: "mousedown" },
@ -110,7 +131,11 @@ function test()
function test3(callback) {
waitForWatchExpressions(function() {
info("Performing test3");
checkWatchExpressions({ type: "object", class: "Object" }, "sensational");
checkWatchExpressions({ type: "object", class: "Object" },
{ type: "object", class: "Proxy" },
undefined,
"sensational",
26);
callback();
});
EventUtils.sendMouseEvent({ type: "mousedown" },
@ -121,7 +146,11 @@ function test()
function test4(callback) {
waitForWatchExpressions(function() {
info("Performing test4");
checkWatchExpressions(5, "sensational", 13);
checkWatchExpressions(5,
{ type: "object", class: "Proxy" },
undefined,
"sensational",
27);
callback();
});
executeSoon(function() {
@ -133,7 +162,11 @@ function test()
function test5(callback) {
waitForWatchExpressions(function() {
info("Performing test5");
checkWatchExpressions(5, "sensational", 13);
checkWatchExpressions(5,
{ type: "object", class: "Proxy" },
undefined,
"sensational",
27);
callback();
});
executeSoon(function() {
@ -145,7 +178,11 @@ function test()
function test6(callback) {
waitForWatchExpressions(function() {
info("Performing test6");
checkWatchExpressions(5, "sensational", 13);
checkWatchExpressions(5,
{ type: "object", class: "Proxy" },
undefined,
"sensational",
27);
callback();
})
executeSoon(function() {
@ -157,7 +194,11 @@ function test()
function test7(callback) {
waitForWatchExpressions(function() {
info("Performing test7");
checkWatchExpressions(5, "sensational", 13);
checkWatchExpressions(5,
{ type: "object", class: "Proxy" },
undefined,
"sensational",
27);
callback();
});
executeSoon(function() {
@ -169,7 +210,11 @@ function test()
function test8(callback) {
waitForWatchExpressions(function() {
info("Performing test8");
checkWatchExpressions(5, "sensational", 13);
checkWatchExpressions(5,
{ type: "object", class: "Proxy" },
undefined,
"sensational",
27);
callback();
});
executeSoon(function() {
@ -202,7 +247,12 @@ function test()
}, false);
}
function checkWatchExpressions(expected_a, expected_arguments, total = 12) {
function checkWatchExpressions(expected_a,
expected_this,
expected_prop,
expected_arguments,
total)
{
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, total,
"There should be " + total + " hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
@ -220,13 +270,27 @@ function test()
let w4 = scope.get("\"a''\"");
let w5 = scope.get("?");
let w6 = scope.get("a");
let w7 = scope.get("x = [1, 2, 3]");
let w8 = scope.get("y = [1, 2, 3]; y.test = 4");
let w9 = scope.get("z = [1, 2, 3]; z.test = 4; z");
let w10 = scope.get("t = [1, 2, 3]; t.test = 4; !t");
let w11 = scope.get("arguments[0]");
let w12 = scope.get("encodeURI(\"\\\")");
let w13 = scope.get("decodeURI(\"\\\")");
let w7 = scope.get("this");
let w8 = scope.get("this.canada");
let w9 = scope.get("[1, 2, 3]");
let w10 = scope.get("x = [1, 2, 3]");
let w11 = scope.get("y = [1, 2, 3]; y.test = 4");
let w12 = scope.get("z = [1, 2, 3]; z.test = 4; z");
let w13 = scope.get("t = [1, 2, 3]; t.test = 4; !t");
let w14 = scope.get("arguments[0]");
let w15 = scope.get("encodeURI(\"\\\")");
let w16 = scope.get("decodeURI(\"\\\")");
let w17 = scope.get("decodeURIComponent(\"%\")");
let w18 = scope.get("//");
let w19 = scope.get("// 42");
let w20 = scope.get("{}.foo");
let w21 = scope.get("{}.foo()");
let w22 = scope.get("({}).foo()");
let w23 = scope.get("new Array(-1)");
let w24 = scope.get("4.2.toExponential(-4.2)");
let w25 = scope.get("throw new Error(\"bazinga\")");
let w26 = scope.get("({ get error() { throw new Error(\"bazinga\") } }).error");
let w27 = scope.get("throw { get name() { throw \"bazinga\" } }");
ok(w1, "The first watch expression should be present in the scope");
ok(w2, "The second watch expression should be present in the scope");
@ -239,8 +303,22 @@ function test()
ok(w9, "The ninth watch expression should be present in the scope");
ok(w10, "The tenth watch expression should be present in the scope");
ok(w11, "The eleventh watch expression should be present in the scope");
ok(!w12, "The twelveth watch expression should not be present in the scope");
ok(!w13, "The thirteenth watch expression should not be present in the scope");
ok(w12, "The twelfth watch expression should be present in the scope");
ok(w13, "The 13th watch expression should be present in the scope");
ok(w14, "The 14th watch expression should be present in the scope");
ok(w15, "The 15th watch expression should be present in the scope");
ok(w16, "The 16th watch expression should be present in the scope");
ok(w17, "The 17th watch expression should be present in the scope");
ok(w18, "The 18th watch expression should be present in the scope");
ok(w19, "The 19th watch expression should be present in the scope");
ok(w20, "The 20th watch expression should be present in the scope");
ok(w21, "The 21st watch expression should be present in the scope");
ok(w22, "The 22nd watch expression should be present in the scope");
ok(w23, "The 23nd watch expression should be present in the scope");
ok(w24, "The 24th watch expression should be present in the scope");
ok(w25, "The 25th watch expression should be present in the scope");
ok(w26, "The 26th watch expression should be present in the scope");
ok(!w27, "The 27th watch expression should not be present in the scope");
is(w1.value, "a", "The first value is correct");
is(w2.value, "a", "The second value is correct");
@ -255,13 +333,42 @@ function test()
is(w6.value, expected_a, "The sixth value is correct");
}
is(w7.value.type, "object", "The seventh value type is correct");
is(w7.value.class, "Array", "The seventh value class is correct");
is(w8.value, "4", "The eight value is correct");
if (typeof expected_this == "object") {
is(w7.value.type, expected_this.type, "The seventh value type is correct");
is(w7.value.class, expected_this.class, "The seventh value class is correct");
} else {
is(w7.value, expected_this, "The seventh value is correct");
}
if (typeof expected_prop == "object") {
is(w8.value.type, expected_prop.type, "The eighth value type is correct");
is(w8.value.class, expected_prop.class, "The eighth value class is correct");
} else {
is(w8.value, expected_prop, "The eighth value is correct");
}
is(w9.value.type, "object", "The ninth value type is correct");
is(w9.value.class, "Array", "The ninth value class is correct");
is(w10.value, false, "The tenth value is correct");
is(w11.value, expected_arguments, "The eleventh value is correct");
is(w10.value.type, "object", "The tenth value type is correct");
is(w10.value.class, "Array", "The tenth value class is correct");
is(w11.value, "4", "The eleventh value is correct");
is(w12.value.type, "object", "The eleventh value type is correct");
is(w12.value.class, "Array", "The twelfth value class is correct");
is(w13.value, false, "The 13th value is correct");
is(w14.value, expected_arguments, "The 14th value is correct");
is(w15.value, "SyntaxError: unterminated string literal", "The 15th value is correct");
is(w16.value, "SyntaxError: unterminated string literal", "The 16th value is correct");
is(w17.value, "URIError: malformed URI sequence", "The 17th value is correct");
is(w18.value, undefined, "The 18th value is correct");
is(w19.value, undefined, "The 19th value is correct");
is(w20.value, "SyntaxError: syntax error", "The 20th value is correct");
is(w21.value, "SyntaxError: syntax error", "The 21th value is correct");
is(w22.value, "TypeError: (intermediate value).foo is not a function", "The 22th value is correct");
is(w23.value, "RangeError: invalid array length", "The 23th value is correct");
is(w24.value, "RangeError: precision -4 out of range", "The 24st value is correct");
is(w25.value, "Error: bazinga", "The 25nd value is correct");
is(w26.value, "Error: bazinga", "The 26rd value is correct");
}
registerCleanupFunction(function() {

View File

@ -11,6 +11,11 @@
var a = 1;
var b = { a: a };
var c = { a: 1, b: "beta", c: true, d: b };
var myVar = {
_prop: 42,
get prop() { return this._prop; },
set prop(val) { this._prop = val; }
};
debugger;
}

View File

@ -139,8 +139,8 @@ function testSimpleCall() {
testVar.target.querySelector(".title"),
gDebugger);
ok(!testVar.expanded,
"Clicking the testVar title div shouldn't expand it.");
ok(testVar.expanded,
"Clicking the testVar title div should expand it again.");
testScope.show();
@ -185,8 +185,8 @@ function testSimpleCall() {
testVar.get("child").target.querySelector(".title"),
gDebugger);
ok(!testVar.get("child").expanded,
"Clicking the testVar child property title div shouldn't expand it.");
ok(testVar.get("child").expanded,
"Clicking the testVar child property title div should expand it again.");
gDebugger.DebuggerView.Variables.empty();

View File

@ -40,7 +40,7 @@ function testFrameParameters()
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
"Should have three frames.");
is(localNodes.length, 11,
is(localNodes.length, 12,
"The localScope should contain all the created variable elements.");
is(localNodes[0].querySelector(".value").getAttribute("value"), "[object Proxy]",

View File

@ -40,7 +40,7 @@ function testFrameParameters()
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
"Should have three frames.");
is(localNodes.length + localNonEnums.length, 11,
is(localNodes.length + localNonEnums.length, 12,
"The localScope and localNonEnums should contain all the created variable elements.");
is(localNodes[0].querySelector(".value").getAttribute("value"), "[object Proxy]",
@ -74,9 +74,9 @@ function testFrameParameters()
"The global scope should be collapsed by default.");
let thisNode = gVars.getVariableOrPropertyForNode(localNodes[0]);
let argumentsNode = gVars.getVariableOrPropertyForNode(localNodes[8]);
let cNode = gVars.getVariableOrPropertyForNode(localNodes[10]);
let thisNode = gVars.getItemForNode(localNodes[0]);
let argumentsNode = gVars.getItemForNode(localNodes[8]);
let cNode = gVars.getItemForNode(localNodes[10]);
is(thisNode.expanded, false,
"The thisNode should not be expanded at this point.");
@ -180,20 +180,20 @@ function testFrameParameters()
"Should have the right value for 'c.c'.");
is(gVars.getVariableOrPropertyForNode(
is(gVars.getItemForNode(
cNode.target.querySelectorAll(".property")[0]).target,
cNode.target.querySelectorAll(".property")[0],
"getVariableOrPropertyForNode([0]) didn't return the expected property.");
"getItemForNode([0]) didn't return the expected property.");
is(gVars.getVariableOrPropertyForNode(
is(gVars.getItemForNode(
cNode.target.querySelectorAll(".property")[1]).target,
cNode.target.querySelectorAll(".property")[1],
"getVariableOrPropertyForNode([1]) didn't return the expected property.");
"getItemForNode([1]) didn't return the expected property.");
is(gVars.getVariableOrPropertyForNode(
is(gVars.getItemForNode(
cNode.target.querySelectorAll(".property")[2]).target,
cNode.target.querySelectorAll(".property")[2],
"getVariableOrPropertyForNode([2]) didn't return the expected property.");
"getItemForNode([2]) didn't return the expected property.");
is(cNode.find(

View File

@ -53,7 +53,7 @@ function testFrameParameters()
is(globalNodes[0].querySelector(".name").getAttribute("value"), "InstallTrigger",
"Should have the right property name for |InstallTrigger|.");
is(globalNodes[0].querySelector(".value").getAttribute("value"), "undefined",
is(globalNodes[0].querySelector(".value").getAttribute("value"), "",
"Should have the right property value for |InstallTrigger|.");
is(globalNodes[1].querySelector(".name").getAttribute("value"), "SpecialPowers",

View File

@ -64,7 +64,7 @@ function testWithFrame()
is(globalNodes[0].querySelector(".name").getAttribute("value"), "InstallTrigger",
"Should have the right property name for |InstallTrigger|.");
is(globalNodes[0].querySelector(".value").getAttribute("value"), "undefined",
is(globalNodes[0].querySelector(".value").getAttribute("value"), "",
"Should have the right property value for |InstallTrigger|.");
let len = globalNodes.length - 1;

View File

@ -0,0 +1,343 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view knows how to edit getters and setters.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gVars = null;
var gWatch = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gVars = gDebugger.DebuggerView.Variables;
gWatch = gDebugger.DebuggerView.WatchExpressions;
gVars.switch = function() {};
gVars.delete = function() {};
prepareVariablesView();
});
}
function prepareVariablesView() {
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
testVariablesView();
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function testVariablesView()
{
executeSoon(function() {
addWatchExpressions(function() {
testEdit("set", "this._prop = value + ' BEER CAN'", function() {
testEdit("set", "{ this._prop = value + ' BEACON' }", function() {
testEdit("set", "{ this._prop = value + ' BEACON;'; }", function() {
testEdit("set", "{ return this._prop = value + ' BEACON;;'; }", function() {
testEdit("set", "function(value) { this._prop = value + ' BACON' }", function() {
testEdit("get", "'brelx BEER CAN'", function() {
testEdit("get", "{ 'brelx BEACON' }", function() {
testEdit("get", "{ 'brelx BEACON;'; }", function() {
testEdit("get", "{ return 'brelx BEACON;;'; }", function() {
testEdit("get", "function() { return 'brelx BACON'; }", function() {
testEdit("get", "bogus", function() {
testEdit("set", "sugob", function() {
testEdit("get", "", function() {
testEdit("set", "", function() {
waitForWatchExpressions(function() {
testEdit("self", "2507", function() {
closeDebuggerAndFinish();
}, {
"myVar.prop": 2507,
"myVar.prop + 42": "250742"
});
})
gWatch.deleteExpression({ name: "myVar.prop = 'xlerb'" });
}, {
"myVar.prop": "xlerb",
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": undefined,
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined"
});
}, {
"myVar.prop": "ReferenceError: bogus is not defined",
"myVar.prop + 42": "ReferenceError: bogus is not defined",
"myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined"
});
}, {
"myVar.prop": "ReferenceError: bogus is not defined",
"myVar.prop + 42": "ReferenceError: bogus is not defined",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "brelx BACON",
"myVar.prop + 42": "brelx BACON42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "brelx BEACON;;",
"myVar.prop + 42": "brelx BEACON;;42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": undefined,
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": undefined,
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "brelx BEER CAN",
"myVar.prop + 42": "brelx BEER CAN42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BACON",
"myVar.prop + 42": "xlerb BACON42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BEACON;;",
"myVar.prop + 42": "xlerb BEACON;;42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BEACON;",
"myVar.prop + 42": "xlerb BEACON;42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BEACON",
"myVar.prop + 42": "xlerb BEACON42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BEER CAN",
"myVar.prop + 42": "xlerb BEER CAN42",
"myVar.prop = 'xlerb'": "xlerb"
});
});
});
}
function addWatchExpressions(callback)
{
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 1, "There should be 1 evaluation availalble");
let w1 = scope.get("myVar.prop");
let w2 = scope.get("myVar.prop + 42");
let w3 = scope.get("myVar.prop = 'xlerb'");
ok(w1, "The first watch expression should be present in the scope");
ok(!w2, "The second watch expression should not be present in the scope");
ok(!w3, "The third watch expression should not be present in the scope");
is(w1.value, 42, "The first value is correct.");
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 2, "There should be 2 evaluations availalble");
let w1 = scope.get("myVar.prop");
let w2 = scope.get("myVar.prop + 42");
let w3 = scope.get("myVar.prop = 'xlerb'");
ok(w1, "The first watch expression should be present in the scope");
ok(w2, "The second watch expression should be present in the scope");
ok(!w3, "The third watch expression should not be present in the scope");
is(w1.value, "42", "The first expression value is correct.");
is(w2.value, "84", "The second expression value is correct.");
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 3, "There should be 3 evaluations availalble");
let w1 = scope.get("myVar.prop");
let w2 = scope.get("myVar.prop + 42");
let w3 = scope.get("myVar.prop = 'xlerb'");
ok(w1, "The first watch expression should be present in the scope");
ok(w2, "The second watch expression should be present in the scope");
ok(w3, "The third watch expression should be present in the scope");
is(w1.value, "xlerb", "The first expression value is correct.");
is(w2.value, "xlerb42", "The second expression value is correct.");
is(w3.value, "xlerb", "The third expression value is correct.");
callback();
});
gWatch.addExpression("myVar.prop = 'xlerb'");
gDebugger.editor.focus();
});
gWatch.addExpression("myVar.prop + 42");
gDebugger.editor.focus();
});
gWatch.addExpression("myVar.prop");
gDebugger.editor.focus();
}
function testEdit(what, string, callback, expected)
{
let localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".scope")[1],
localNodes = localScope.querySelector(".details").childNodes,
myVar = gVars.getItemForNode(localNodes[11]);
waitForProperties(function() {
let prop = myVar.get("prop");
let getterOrSetter = (what != "self" ? prop.get(what) : prop);
EventUtils.sendMouseEvent({ type: "mousedown" },
getterOrSetter._target.querySelector(".title > .value"),
gDebugger);
waitForElement(".element-value-input", true, function() {
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
let w1 = scope.get(Object.keys(expected)[0]);
let w2 = scope.get(Object.keys(expected)[1]);
let w3 = scope.get(Object.keys(expected)[2]);
if (w1) {
if (isNaN(expected[w1.name]) && typeof expected[w1.name] == "number") {
ok(isNaN(w1.value),
"The first expression value is correct after the edit (NaN).");
} else {
is(w1.value, expected[w1.name],
"The first expression value is correct after the edit.");
}
info(w1.value + " is equal to " + expected[w1.name]);
}
if (w2) {
if (isNaN(expected[w2.name]) && typeof expected[w2.name] == "number") {
ok(isNaN(w2.value),
"The second expression value is correct after the edit (NaN).");
} else {
is(w2.value, expected[w2.name],
"The second expression value is correct after the edit.");
}
info(w2.value + " is equal to " + expected[w2.name]);
}
if (w3) {
if (isNaN(expected[w3.name]) && typeof expected[w3.name] == "number") {
ok(isNaN(w3.value),
"The third expression value is correct after the edit (NaN).");
} else {
is(w3.value, expected[w3.name],
"The third expression value is correct after the edit.");
}
info(w3.value + " is equal to " + expected[w3.name]);
}
callback();
});
info("Changing the " + what + "ter with '" + string + "'.");
write(string);
EventUtils.sendKey("RETURN", gDebugger);
});
});
myVar.expand();
gVars.clearHierarchy();
}
function waitForWatchExpressions(callback) {
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function onFetch() {
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", onFetch, false);
executeSoon(callback);
}, false);
}
function waitForProperties(callback) {
gDebugger.addEventListener("Debugger:FetchedProperties", function onFetch() {
gDebugger.removeEventListener("Debugger:FetchedProperties", onFetch, false);
executeSoon(callback);
}, false);
}
function waitForElement(selector, exists, callback)
{
// Poll every few milliseconds until the element are retrieved.
let count = 0;
let intervalID = window.setInterval(function() {
info("count: " + count + " ");
if (++count > 50) {
ok(false, "Timed out while polling for the element.");
window.clearInterval(intervalID);
return closeDebuggerAndFinish();
}
if (!!gVars._list.querySelector(selector) != exists) {
return;
}
// We got the element, it's safe to callback.
window.clearInterval(intervalID);
callback();
}, 100);
}
function write(text) {
if (!text) {
EventUtils.sendKey("BACK_SPACE", gDebugger);
return;
}
for (let i = 0; i < text.length; i++) {
EventUtils.sendChar(text[i], gDebugger);
}
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gVars = null;
gWatch = null;
});

View File

@ -0,0 +1,185 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view is able to override getter properties
* to plain value properties.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gVars = null;
var gWatch = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gVars = gDebugger.DebuggerView.Variables;
gWatch = gDebugger.DebuggerView.WatchExpressions;
gVars.switch = function() {};
gVars.delete = function() {};
prepareVariablesView();
});
}
function prepareVariablesView() {
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
testVariablesView();
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function testVariablesView()
{
executeSoon(function() {
addWatchExpressions(function() {
testEdit("\"xlerb\"", "xlerb", function() {
closeDebuggerAndFinish();
});
});
});
}
function addWatchExpressions(callback)
{
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 1, "There should be 1 evaluation availalble");
let expr = scope.get("myVar.prop");
ok(expr, "The watch expression should be present in the scope");
is(expr.value, 42, "The value is correct.");
callback();
});
gWatch.addExpression("myVar.prop");
gDebugger.editor.focus();
}
function testEdit(string, expected, callback)
{
let localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".scope")[1],
localNodes = localScope.querySelector(".details").childNodes,
myVar = gVars.getItemForNode(localNodes[11]);
waitForProperties(function() {
let prop = myVar.get("prop");
is(prop.ownerView.name, "myVar",
"The right owner property name wasn't found.");
is(prop.name, "prop",
"The right property name wasn't found.");
is(prop.ownerView.value.type, "object",
"The right owner property value type wasn't found.");
is(prop.ownerView.value.class, "Object",
"The right owner property value class wasn't found.");
is(prop.name, "prop",
"The right property name wasn't found.");
is(prop.value, undefined,
"The right property value wasn't found.");
ok(prop.getter,
"The right property getter wasn't found.");
ok(prop.setter,
"The right property setter wasn't found.");
EventUtils.sendMouseEvent({ type: "mousedown" },
prop._target.querySelector(".dbg-variable-edit"),
gDebugger);
waitForElement(".element-value-input", true, function() {
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
let expr = scope.get("myVar.prop");
is(expr.value, expected, "The value is correct.");
callback();
});
write(string);
EventUtils.sendKey("RETURN", gDebugger);
});
});
myVar.expand();
gVars.clearHierarchy();
}
function waitForWatchExpressions(callback) {
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function onFetch() {
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", onFetch, false);
executeSoon(callback);
}, false);
}
function waitForProperties(callback) {
gDebugger.addEventListener("Debugger:FetchedProperties", function onFetch() {
gDebugger.removeEventListener("Debugger:FetchedProperties", onFetch, false);
executeSoon(callback);
}, false);
}
function waitForElement(selector, exists, callback)
{
// Poll every few milliseconds until the element are retrieved.
let count = 0;
let intervalID = window.setInterval(function() {
info("count: " + count + " ");
if (++count > 50) {
ok(false, "Timed out while polling for the element.");
window.clearInterval(intervalID);
return closeDebuggerAndFinish();
}
if (!!gVars._list.querySelector(selector) != exists) {
return;
}
// We got the element, it's safe to callback.
window.clearInterval(intervalID);
callback();
}, 100);
}
function write(text) {
if (!text) {
EventUtils.sendKey("BACK_SPACE", gDebugger);
return;
}
for (let i = 0; i < text.length; i++) {
EventUtils.sendChar(text[i], gDebugger);
}
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gVars = null;
gWatch = null;
});

View File

@ -21,6 +21,7 @@ function test()
gDebugger = gPane.panelWin;
gVariablesView = gDebugger.DebuggerView.Variables;
gDebugger.DebuggerView.togglePanes({ visible: true, animated: false });
testVariablesView();
});
}
@ -61,6 +62,9 @@ function testVariablesView()
set someProp7(value) { arr[0] = value }
};
gVariablesView.eval = function() {};
gVariablesView.switch = function() {};
gVariablesView.delete = function() {};
gVariablesView.rawObject = test;
testHierarchy();
@ -70,10 +74,6 @@ function testVariablesView()
testThirdLevelContents();
testIntegrity(arr, obj);
gVariablesView.eval = function() {};
gVariablesView.switch = function() {};
gVariablesView.delete = function() {};
let fooScope = gVariablesView.addScope("foo");
let anonymousVar = fooScope.addVar();
@ -83,9 +83,14 @@ function testVariablesView()
testAnonymousHeaders(fooScope, anonymousVar, anonymousScope, barVar, bazProperty);
testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar, bazProperty);
testClearHierarchy();
closeDebuggerAndFinish();
executeSoon(function() {
testKeyboardAccessibility(function() {
testClearHierarchy();
closeDebuggerAndFinish();
});
});
}
function testHierarchy() {
@ -582,11 +587,268 @@ function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar,
"The eval and switch functions got mixed up in the property.");
}
function testKeyboardAccessibility(callback) {
gDebugger.DebuggerView.Filtering._doVariablesFocus();
gDebugger.DebuggerView.Variables.pageSize = 5;
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should be focused.");
gVariablesView.focusNextItem();
is(gVariablesView.getFocusedItem().name, "someProp1",
"The someProp1 item should be focused.");
gVariablesView.focusPrevItem();
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should be focused again.");
ok(!gVariablesView._list.querySelector(".element-value-input"),
"There shouldn't be a value input element created.");
EventUtils.synthesizeKey("VK_ENTER", {}, gDebugger);
waitForElement(".element-value-input", true, function() {
ok(gVariablesView._list.querySelector(".element-value-input"),
"There should be a value input element created.");
EventUtils.sendKey("ESCAPE", gDebugger);
waitForElement(".element-value-input", false, function() {
ok(!gVariablesView._list.querySelector(".element-value-input"),
"There shouldn't be a value input element anymore.");
ok(!gVariablesView._list.querySelector(".element-name-input"),
"There shouldn't be a name input element created.");
EventUtils.synthesizeKey("VK_ENTER", { shiftKey: true }, gDebugger);
waitForElement(".element-name-input", true, function() {
ok(gVariablesView._list.querySelector(".element-name-input"),
"There should be a name input element created.");
EventUtils.sendKey("ESCAPE", gDebugger);
waitForElement(".element-name-input", false, function() {
ok(!gVariablesView._list.querySelector(".element-name-input"),
"There shouldn't be a name input element anymore.");
EventUtils.sendKey("DOWN", gDebugger);
executeSoon(function() {
is(gVariablesView._parent.scrollTop, 0,
"The variables view shouldn't scroll when pressing the DOWN key.");
EventUtils.sendKey("UP", gDebugger);
executeSoon(function() {
is(gVariablesView._parent.scrollTop, 0,
"The variables view shouldn't scroll when pressing the UP key.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The someProp5 item should be focused now.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "0",
"The 0 item should be focused now.");
EventUtils.sendKey("END", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo item should be focused now.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo item should still be focused now.");
EventUtils.sendKey("RIGHT", gDebugger);
is(gVariablesView.getFocusedItem().name, "bar",
"The bar item should still be focused now.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo item should still be focused now.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The __proto__ item should be focused now.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "set",
"The set item should be focused now.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "get",
"The get item should be focused now.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "p8",
"The p8 item should be focused now.");
EventUtils.sendKey("HOME", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should be focused now.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should still be focused now.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should still be focused now.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should still be focused now.");
for (let i = 0; i < 16; i++) {
// Advance to the first collapsed __proto__ property.
EventUtils.sendKey("RIGHT", gDebugger);
}
is(gVariablesView.getFocusedItem().name, "__proto__",
"The __proto__ item should be focused now.");
is(gVariablesView.getFocusedItem().expanded, false,
"The __proto__ item shouldn't be expanded yet.");
EventUtils.sendKey("RIGHT", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The __proto__ item should still be focused.");
is(gVariablesView.getFocusedItem().expanded, true,
"The __proto__ item should be expanded now.");
for (let i = 0; i < 2; i++) {
// Advance to the fifth top-level someProp5 property.
EventUtils.sendKey("LEFT", gDebugger);
}
is(gVariablesView.getFocusedItem().name, "5",
"The fifth array item should be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The fifth array item should not be expanded now.");
for (let i = 0; i < 6; i++) {
// Advance to the fifth top-level someProp5 property.
EventUtils.sendKey("UP", gDebugger);
}
is(gVariablesView.getFocusedItem().name, "someProp5",
"The someProp5 item should be focused now.");
is(gVariablesView.getFocusedItem().expanded, true,
"The someProp5 item should already be expanded.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The someProp5 item should still be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The someProp5 item should not be expanded now.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp4",
"The someProp4 item should be focused.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp3",
"The someProp3 item should be focused.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp2",
"The someProp2 item should be focused.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp1",
"The someProp1 item should be focused.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should be focused.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should still be focused.");
for (let i = 0; i < 32; i++) {
// Advance to the last property in this scope.
EventUtils.sendKey("DOWN", gDebugger);
}
is(gVariablesView.getFocusedItem().name, "__proto__",
"The top-level __proto__ item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo scope should be focused now.");
is(gVariablesView.getFocusedItem().expanded, true,
"The foo scope should already be expanded yet.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo scope should be focused now.");
is(gVariablesView.getFocusedItem().expanded, false,
"The foo scope shouldn't be expanded now.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo scope should still be focused.");
is(gVariablesView.getFocusedItem().expanded, true,
"The foo scope should be expanded now.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "bar",
"The bar variable should still be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The bar variable shouldn't be expanded.");
is(gVariablesView.getFocusedItem().visible, true,
"The bar variable shouldn't be hidden.");
EventUtils.sendKey("BACK_SPACE", gDebugger);
is(gVariablesView.getFocusedItem().name, "bar",
"The bar variable should still be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The bar variable should still not be expanded.");
is(gVariablesView.getFocusedItem().visible, false,
"The bar variable should be hidden.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo scope should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The top-level __proto__ item should be focused.");
executeSoon(callback);
});
});
});
});
});
});
}
function waitForElement(selector, exists, callback)
{
// Poll every few milliseconds until the element are retrieved.
let count = 0;
let intervalID = window.setInterval(function() {
info("count: " + count + " ");
if (++count > 50) {
ok(false, "Timed out while polling for the element.");
window.clearInterval(intervalID);
return closeDebuggerAndFinish();
}
if (!!gVariablesView._list.querySelector(selector) != exists) {
return;
}
// We got the element, it's safe to callback.
window.clearInterval(intervalID);
callback();
}, 100);
}
function testClearHierarchy() {
gVariablesView.clearHierarchy();
is (gVariablesView._prevHierarchy.size, 0,
ok(!gVariablesView._prevHierarchy.size,
"The previous hierarchy should have been cleared.");
is (gVariablesView._currHierarchy.size, 0,
ok(!gVariablesView._currHierarchy.size,
"The current hierarchy should have been cleared.");
}

View File

@ -69,7 +69,7 @@ function testModification(aVar, aCallback, aNewValue, aNewResult) {
EventUtils.sendKey("RETURN", gDebugger);
}
EventUtils.sendMouseEvent({ type: "click" },
EventUtils.sendMouseEvent({ type: "mousedown" },
aVar.querySelector(".value"),
gDebugger);

View File

@ -68,7 +68,7 @@ function testFrameEval() {
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 5, "There should be 5 evaluations availalble");
is(scope.get("this")._isShown, true,
is(scope.get("this")._isContentVisible, true,
"Should have the right visibility state for 'this'.");
is(scope.get("this").target.querySelectorAll(".dbg-variable-delete").length, 1,
"Should have the one close button visible for 'this'.");
@ -79,7 +79,7 @@ function testFrameEval() {
is(scope.get("this").value.class, "Proxy",
"Should have the right value type for 'this'.");
is(scope.get("ermahgerd")._isShown, true,
is(scope.get("ermahgerd")._isContentVisible, true,
"Should have the right visibility state for 'ermahgerd'.");
is(scope.get("ermahgerd").target.querySelectorAll(".dbg-variable-delete").length, 1,
"Should have the one close button visible for 'ermahgerd'.");
@ -90,7 +90,7 @@ function testFrameEval() {
is(scope.get("ermahgerd").value.class, "Function",
"Should have the right value type for 'ermahgerd'.");
is(scope.get("aArg")._isShown, true,
is(scope.get("aArg")._isContentVisible, true,
"Should have the right visibility state for 'aArg'.");
is(scope.get("aArg").target.querySelectorAll(".dbg-variable-delete").length, 1,
"Should have the one close button visible for 'aArg'.");
@ -99,7 +99,7 @@ function testFrameEval() {
is(scope.get("aArg").value, undefined,
"Should have the right value for 'aArg'.");
is(scope.get("document.title")._isShown, true,
is(scope.get("document.title")._isContentVisible, true,
"Should have the right visibility state for 'document.title'.");
is(scope.get("document.title").target.querySelectorAll(".dbg-variable-delete").length, 1,
"Should have the one close button visible for 'document.title'.");
@ -110,7 +110,7 @@ function testFrameEval() {
is(typeof scope.get("document.title").value, "string",
"Should have the right value type for 'document.title'.");
is(scope.get("document.title = 42")._isShown, true,
is(scope.get("document.title = 42")._isContentVisible, true,
"Should have the right visibility state for 'document.title = 42'.");
is(scope.get("document.title = 42").target.querySelectorAll(".dbg-variable-delete").length, 1,
"Should have the one close button visible for 'document.title = 42'.");
@ -340,23 +340,23 @@ function test1(scope) {
is(gWatch._cache[0].target.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "document.title = 43",
is(gWatch._cache[0].attachment.currentExpression, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "document.title",
is(gWatch._cache[1].attachment.currentExpression, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[2].target.inputNode.value, "aArg",
"The third textbox input value is not the correct one");
is(gWatch._cache[2].attachment.expression, "aArg",
is(gWatch._cache[2].attachment.currentExpression, "aArg",
"The third textbox input value is not the correct one");
is(gWatch._cache[3].target.inputNode.value, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[3].attachment.expression, "ermahgerd",
is(gWatch._cache[3].attachment.currentExpression, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[4].target.inputNode.value, "this",
"The fifth textbox input value is not the correct one");
is(gWatch._cache[4].attachment.expression, "this",
is(gWatch._cache[4].attachment.currentExpression, "this",
"The fifth textbox input value is not the correct one");
}
@ -371,23 +371,23 @@ function test2(scope) {
is(gWatch._cache[0].target.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "document.title = 43",
is(gWatch._cache[0].attachment.currentExpression, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "document.title",
is(gWatch._cache[1].attachment.currentExpression, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[2].target.inputNode.value, "aArg = 44",
"The third textbox input value is not the correct one");
is(gWatch._cache[2].attachment.expression, "aArg = 44",
is(gWatch._cache[2].attachment.currentExpression, "aArg = 44",
"The third textbox input value is not the correct one");
is(gWatch._cache[3].target.inputNode.value, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[3].attachment.expression, "ermahgerd",
is(gWatch._cache[3].attachment.currentExpression, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[4].target.inputNode.value, "this",
"The fifth textbox input value is not the correct one");
is(gWatch._cache[4].attachment.expression, "this",
is(gWatch._cache[4].attachment.currentExpression, "this",
"The fifth textbox input value is not the correct one");
}
@ -402,19 +402,19 @@ function test3(scope) {
is(gWatch._cache[0].target.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "document.title = 43",
is(gWatch._cache[0].attachment.currentExpression, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "document.title",
is(gWatch._cache[1].attachment.currentExpression, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[2].target.inputNode.value, "ermahgerd",
"The third textbox input value is not the correct one");
is(gWatch._cache[2].attachment.expression, "ermahgerd",
is(gWatch._cache[2].attachment.currentExpression, "ermahgerd",
"The third textbox input value is not the correct one");
is(gWatch._cache[3].target.inputNode.value, "this",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[3].attachment.expression, "this",
is(gWatch._cache[3].attachment.currentExpression, "this",
"The fourth textbox input value is not the correct one");
}
@ -429,15 +429,15 @@ function test4(scope) {
is(gWatch._cache[0].target.inputNode.value, "document.title",
"The first textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "document.title",
is(gWatch._cache[0].attachment.currentExpression, "document.title",
"The first textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "ermahgerd",
is(gWatch._cache[1].attachment.currentExpression, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch._cache[2].target.inputNode.value, "this",
"The third textbox input value is not the correct one");
is(gWatch._cache[2].attachment.expression, "this",
is(gWatch._cache[2].attachment.currentExpression, "this",
"The third textbox input value is not the correct one");
}
@ -452,11 +452,11 @@ function test5(scope) {
is(gWatch._cache[0].target.inputNode.value, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "ermahgerd",
is(gWatch._cache[0].attachment.currentExpression, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "this",
"The third textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "this",
is(gWatch._cache[1].attachment.currentExpression, "this",
"The third textbox input value is not the correct one");
}
@ -471,7 +471,7 @@ function test6(scope) {
is(gWatch._cache[0].target.inputNode.value, "ermahgerd",
"The third textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "ermahgerd",
is(gWatch._cache[0].attachment.currentExpression, "ermahgerd",
"The third textbox input value is not the correct one");
}

View File

@ -6,6 +6,9 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="text/javascript">
function test() {
ermahgerd.call({ canada: new String("eh") });
}
function ermahgerd(aArg) {
var t = document.title;
debugger;
@ -17,6 +20,7 @@
}("sensational"));
}
</script>
</head>
<body>
</body>

View File

@ -33,6 +33,7 @@ browser.jar:
content/browser/devtools/profiler/cleopatra/css/ui.css (profiler/cleopatra/css/ui.css)
content/browser/devtools/profiler/cleopatra/css/tree.css (profiler/cleopatra/css/tree.css)
content/browser/devtools/profiler/cleopatra/css/devtools.css (profiler/cleopatra/css/devtools.css)
content/browser/devtools/profiler/cleopatra/js/strings.js (profiler/cleopatra/js/strings.js)
content/browser/devtools/profiler/cleopatra/js/parser.js (profiler/cleopatra/js/parser.js)
content/browser/devtools/profiler/cleopatra/js/parserWorker.js (profiler/cleopatra/js/parserWorker.js)
content/browser/devtools/profiler/cleopatra/js/tree.js (profiler/cleopatra/js/tree.js)

View File

@ -0,0 +1,43 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Cu = Components.utils;
const ProfilerProps = "chrome://browser/locale/devtools/profiler.properties";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
this.EXPORTED_SYMBOLS = ["L10N"];
/**
* Localization helper methods.
*/
let L10N = {
/**
* Returns a simple localized string.
*
* @param string name
* @return string
*/
getStr: function L10N_getStr(name) {
return this.stringBundle.GetStringFromName(name);
},
/**
* Returns formatted localized string.
*
* @param string name
* @param array params
* @return string
*/
getFormatStr: function L10N_getFormatStr(name, params) {
return this.stringBundle.formatStringFromName(name, params, params.length);
}
};
XPCOMUtils.defineLazyGetter(L10N, "stringBundle", function () {
return Services.strings.createBundle(ProfilerProps);
});

View File

@ -7,6 +7,7 @@
const Cu = Components.utils;
Cu.import("resource:///modules/devtools/ProfilerController.jsm");
Cu.import("resource:///modules/devtools/ProfilerHelpers.jsm");
Cu.import("resource://gre/modules/commonjs/promise/core.js");
Cu.import("resource:///modules/devtools/EventEmitter.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -249,12 +250,11 @@ ProfilerPanel.prototype = {
item.setAttribute("id", "profile-" + uid);
item.setAttribute("data-uid", uid);
item.addEventListener("click", function (ev) {
let uid = parseInt(ev.target.getAttribute("data-uid"), 10);
this.switchToProfile(this.profiles.get(uid));
}.bind(this), false);
wrap.className = "profile-name";
wrap.textContent = "Profile " + uid;
wrap.textContent = L10N.getFormatStr("profiler.profileName", [uid]);
item.appendChild(wrap);
list.appendChild(item);

View File

@ -12,6 +12,7 @@
<link rel="stylesheet" type="text/css" href="profiler/cleopatra/css/tree.css">
<link rel="stylesheet" type="text/css" href="profiler/cleopatra/css/devtools.css">
<script src="profiler/cleopatra/js/strings.js"></script>
<script src="profiler/cleopatra/js/parser.js"></script>
<script src="profiler/cleopatra/js/tree.js"></script>
<script src="profiler/cleopatra/js/ui.js"></script>

View File

@ -85,24 +85,29 @@ function initUI() {
document.body.appendChild(container);
var startButton = document.createElement("button");
startButton.innerHTML = "Start";
startButton.innerHTML = gStrings.getStr("profiler.start");
startButton.addEventListener("click", function (event) {
event.target.setAttribute("disabled", true);
notifyParent("start");
}, false);
var stopButton = document.createElement("button");
stopButton.innerHTML = "Stop";
stopButton.innerHTML = gStrings.getStr("profiler.stop");
stopButton.addEventListener("click", function (event) {
event.target.setAttribute("disabled", true);
notifyParent("stop");
}, false);
var controlPane = document.createElement("div");
var startProfiling = gStrings.getFormatStr("profiler.startProfiling",
["<span class='btn'></span>"]);
var stopProfiling = gStrings.getFormatStr("profiler.stopProfiling",
["<span class='btn'></span>"]);
controlPane.className = "controlPane";
controlPane.innerHTML =
"<p id='startWrapper'>Click <span class='btn'></span> to start profiling.</p>" +
"<p id='stopWrapper'>Click <span class='btn'></span> to stop profiling.</p>";
"<p id='startWrapper'>" + startProfiling + "</p>" +
"<p id='stopWrapper'>" + stopProfiling + "</p>";
controlPane.querySelector("#startWrapper > span.btn").appendChild(startButton);
controlPane.querySelector("#stopWrapper > span.btn").appendChild(stopButton);
@ -153,9 +158,9 @@ function enterFinishedProfileUI() {
gTreeManager = new ProfileTreeManager();
gTreeManager.treeView.setColumns([
{ name: "sampleCount", title: "Running time" },
{ name: "selfSampleCount", title: "Self" },
{ name: "resource", title: "" },
{ name: "sampleCount", title: gStrings["Running Time"] },
{ name: "selfSampleCount", title: gStrings["Self"] },
{ name: "resource", title: "" }
]);
currRow = pane.insertRow(rowIndex++);

View File

@ -0,0 +1,23 @@
const Cu = Components.utils;
Cu.import("resource:///modules/devtools/ProfilerHelpers.jsm");
/**
* Shortcuts for the L10N helper functions. Used in Cleopatra.
*/
var gStrings = {
// This strings are here so that Cleopatra code could use a simple object
// lookup. This makes it easier to merge upstream changes.
"Complete Profile": L10N.getStr("profiler.completeProfile"),
"Sample Range": L10N.getStr("profiler.sampleRange"),
"Running Time": L10N.getStr("profiler.runningTime"),
"Self": L10N.getStr("profiler.self"),
"Symbol Name": L10N.getStr("profiler.symbolName"),
getStr: function (name) {
return L10N.getStr(name);
},
getFormatStr: function (name, params) {
return L10N.getFormatStr(name, params);
}
};

View File

@ -153,10 +153,10 @@ function treeObjSort(a, b) {
function ProfileTreeManager() {
this.treeView = new TreeView();
this.treeView.setColumns([
{ name: "sampleCount", title: "Running time" },
{ name: "selfSampleCount", title: "Self" },
{ name: "sampleCount", title: gStrings["Running Time"] },
{ name: "selfSampleCount", title: gStrings["Self"] },
{ name: "resource", title: "" },
{ name: "symbolName", title: "Symbol Name"}
{ name: "symbolName", title: gStrings["Symbol Name"] }
]);
var self = this;
this.treeView.addEventListener("select", function (frameData) {
@ -752,7 +752,7 @@ RangeSelector.prototype = {
var newFilterChain = gSampleFilters.concat({ type: "RangeSampleFilter", start: start, end: end });
var self = this;
self._transientRestrictionEnteringAffordance = gBreadcrumbTrail.add({
title: "Sample Range [" + start + ", " + (end + 1) + "]",
title: gStrings["Sample Range"] + " [" + start + ", " + (end + 1) + "]",
enterCallback: function () {
gSampleFilters = newFilterChain;
self.collapseHistogramSelection();
@ -1774,7 +1774,7 @@ function enterFinishedProfileUI() {
var currentBreadcrumb = gSampleFilters;
gBreadcrumbTrail.add({
title: "Complete Profile",
title: gStrings["Complete Profile"],
enterCallback: function () {
gSampleFilters = [];
filtersChanged();

View File

@ -10,6 +10,11 @@
<?xml-stylesheet href="chrome://browser/content/splitview.css"?>
<?xml-stylesheet href="chrome://browser/content/profiler.css"?>
<!DOCTYPE window [
<!ENTITY % profilerDTD SYSTEM "chrome://browser/locale/devtools/profiler.dtd">
%profilerDTD;
]>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<box flex="1" id="profiler-chrome" class="splitview-root">
<box class="splitview-controller" width="180px">
@ -29,7 +34,7 @@
<toolbar class="devtools-toolbar" mode="full">
<toolbarbutton id="profiler-create"
class="devtools-toolbarbutton"
label="New"
label="&profilerNew.label;"
disabled="true"/>
</toolbar>
</box> <!-- splitview-nav-container -->

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@ _BROWSER_TEST_FILES = \
browser_styleeditor_pretty.js \
browser_styleeditor_private_perwindowpb.js \
browser_styleeditor_readonly.js \
$(filter disabled-for-intermittent-failures--bug-707891, browser_styleeditor_reopen.js) \
browser_styleeditor_reopen.js \
browser_styleeditor_sv_keynav.js \
browser_styleeditor_sv_resize.js \
head.js \

View File

@ -889,6 +889,7 @@ xpicleanup@BIN_SUFFIX@
components/BrowserElementParent.js
components/BrowserElementParent.manifest
components/BrowserElementPromptService.jsm
components/BrowserElementParent.jsm
components/contentAreaDropListener.js
components/contentSecurityPolicy.js
components/crypto-SDR.js

View File

@ -94,6 +94,11 @@
<!ENTITY debuggerUI.searchVariable "Filter variables">
<!ENTITY debuggerUI.searchVariable.key "V">
<!-- LOCALIZATION NOTE (debuggerUI.focusVariables): This is the text that appears
- in the source editor's context menu for the variables focus operation. -->
<!ENTITY debuggerUI.focusVariables "Focus variables tree">
<!ENTITY debuggerUI.focusVariables.key "V">
<!-- LOCALIZATION NOTE (debuggerUI.condBreakPanelTitle): This is the text that
- appears in the conditional breakpoint panel popup as a description. -->
<!ENTITY debuggerUI.condBreakPanelTitle "This breakpoint will stop execution only if the following expression is true">

View File

@ -196,13 +196,17 @@ ToolboxDebugger.tooltip=JavaScript Debugger
variablesEditableNameTooltip=Double click to edit
# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed
# in the variables list on an item with an editable name.
# in the variables list on an item with an editable value.
variablesEditableValueTooltip=Click to change value
# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed
# in the variables list on an item with which can be removed.
# in the variables list on an item which can be removed.
variablesCloseButtonTooltip=Click to remove
# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed
# in the variables list on a getter or setter which can be edited.
variablesEditButtonTooltip=Click to set value
# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed
# in the variables list as a separator between the name and value.
variablesSeparatorLabel=:

View File

@ -0,0 +1,15 @@
<!-- 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 Profiler strings -->
<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
- keep it in English, or another language commonly spoken among web developers.
- You want to make that choice consistent across the developer tools.
- A good criteria is the language in which you'd find the best
- documentation on web development on the web. -->
<!-- LOCALIZATION NOTE (profilerNew.label): This is the label for the
- button that creates a new profile. -->
<!ENTITY profilerNew.label "New">

View File

@ -19,3 +19,48 @@ profiler.label=Profiler
# This string is displayed in the tooltip of the tab when the profiler is
# displayed inside the developer tools window.
profiler.tooltip=Profiler
# LOCALIZATION NOTE (profiler.profileName):
# This string is the default name for new profiles. Its parameter is a number.
# For example: "Profile 1", "Profile 2", etc.
profiler.profileName=Profile %S
# LOCALIZATION NOTE (profiler.completeProfile):
# This string is displayed as a tab in the profiler UI. Clicking on it
# displays everything that the profiler has generated so far.
profiler.completeProfile=Complete Profile
# LOCALIZATION NOTE (profiler.sampleRange):
# This string is displayed as a tab in the profiler UI. Clicking on it
# displays a sample range of data selected by user themselves.
profiler.sampleRange=Sample Range
# LOCALIZATION NOTE (profiler.runningTime):
# This string is displayed as a table header in the profiler UI.
profiler.runningTime=Running Time
# LOCALIZATION NOTE (profiler.self):
# This string is displayed as a table header in the profiler UI.
profiler.self=Self
# LOCALIZATION NOTE (profiler.symbolName)
# This string is displayed as a table header in the profiler UI.
profiler.symbolName=Symbol Name
# LOCALIZATION NOTE (profiler.startProfiling)
# This string is displayed around the button that starts the profiler.
# String argument will be replaced with a Start button.
profiler.startProfiling=Click here %S to start profiling
# LOCALIZATION NOTE (profiler.stopProfiling)
# This string is displayed around the button that stops the profiler.
# String argument will be replaced with a Stop button.
profiler.stopProfiling = Click here %S to stop profiling
# LOCALIZATION NOTE (profiler.start)
# This string is displayed on the button that starts the profiler.
profiler.start=Start
# LOCALIZATION NOTE (profiler.stop)
# This string is displayed on the button that stops the profiler.
profiler.stop=Stop

View File

@ -38,6 +38,7 @@
locale/browser/devtools/webConsole.dtd (%chrome/browser/devtools/webConsole.dtd)
locale/browser/devtools/sourceeditor.properties (%chrome/browser/devtools/sourceeditor.properties)
locale/browser/devtools/sourceeditor.dtd (%chrome/browser/devtools/sourceeditor.dtd)
locale/browser/devtools/profiler.dtd (%chrome/browser/devtools/profiler.dtd)
locale/browser/devtools/profiler.properties (%chrome/browser/devtools/profiler.properties)
locale/browser/devtools/layoutview.dtd (%chrome/browser/devtools/layoutview.dtd)
locale/browser/devtools/responsiveUI.properties (%chrome/browser/devtools/responsiveUI.properties)

View File

@ -120,7 +120,6 @@ this.Social = {
try {
let active = Services.prefs.getBoolPref("social.active");
if (active) {
Services.prefs.clearUserPref("social.active");
currentProvider = providers[0];
currentProvider.active = true;
}

View File

@ -175,7 +175,6 @@
*/
#stackframes\+breakpoints {
background-color: white;
min-width: 50px;
}
@ -188,7 +187,6 @@
*/
#variables\+expressions {
background-color: white;
min-width: 50px;
}
@ -201,7 +199,6 @@
*/
#stackframes {
background-color: white;
min-height: 10px;
}
@ -223,7 +220,6 @@
*/
#breakpoints {
background-color: white;
min-height: 10px;
}
@ -257,8 +253,8 @@
*/
#expressions {
background-color: white;
min-height: 10px;
max-height: 125px;
}
.dbg-expression {
@ -276,8 +272,17 @@
font: 9pt monospace;
}
.dbg-expression-delete:not(:hover) {
.dbg-expression-delete {
opacity: 0;
}
.dbg-expression-delete:hover {
opacity: 1;
}
.dbg-expression:hover > .dbg-expression-delete:not(:hover) {
opacity: 0.5;
transition: opacity 0.2s ease-in-out;
}
/**
@ -285,16 +290,32 @@
*/
#variables {
background-color: white;
min-height: 10px;
}
.dbg-variable-delete:not(:hover) {
.dbg-variable-delete {
opacity: 0;
}
.dbg-variable-delete:hover {
opacity: 1;
}
.variable-or-property:hover > .title > .dbg-variable-delete:not(:hover),
.variable-or-property:focus > .title > .dbg-variable-delete:not(:hover) {
opacity: 0.5;
transition: opacity 0.2s ease-in-out;
}
.dbg-variable-edit {
background: url("chrome://browser/skin/tabview/edit-light.png") center no-repeat;
width: 20px;
height: 16px;
cursor: pointer;
}
.dbg-variable-throbber {
background: url("chrome://global/skin/icons/loading_16.png");
background: url("chrome://global/skin/icons/loading_16.png") center no-repeat;
width: 16px;
height: 16px;
}
@ -303,6 +324,11 @@
* Scope element
*/
.scope:focus > .title {
background: Highlight;
color: HighlightText;
}
.scope > .title {
text-shadow: 0 1px #222;
color: #fff;
@ -310,7 +336,7 @@
.scope > .details {
-moz-margin-start: 2px;
-moz-margin-end: 2px;
-moz-margin-end: 1px;
}
.scope > .details.nonenum:not(:empty) {
@ -325,7 +351,6 @@
-moz-margin-start: 1px;
-moz-margin-end: 1px;
border-bottom: 1px solid #eee;
background: #fff;
transition: background 1s ease-in-out;
}
@ -334,16 +359,29 @@
transition-duration: 0.4s;
}
.variable:focus > .title {
background: Highlight;
color: HighlightText;
border-radius: 4px;
}
.variable > .title > .name {
color: #048;
font-weight: 600;
}
.variable:not(:focus) > .title > .name {
color: #048;
}
.variable > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.variable[editable] > .title > .value {
cursor: text;
}
.variable:not([non-header]) > .details {
-moz-margin-start: 10px;
}
@ -353,7 +391,6 @@
*/
.property {
background: #fff;
transition: background 1s ease-in-out;
}
@ -362,7 +399,13 @@
transition-duration: 0.4s;
}
.property > .title > .name {
.property:focus > .title {
background: Highlight;
color: HighlightText;
border-radius: 4px;
}
.property:not(:focus) > .title > .name {
color: #881090;
}
@ -371,12 +414,16 @@
-moz-padding-end: 4px;
}
.property[editable] > .title > .value {
cursor: text;
}
.property:not([non-header]) > .details {
-moz-margin-start: 10px;
}
/**
* Non enumerable, configurable and writable variables and properties.
* Non enumerable, configurable and writable variables and properties
*/
.variable[proto] > .title > .name,
@ -414,8 +461,8 @@
}
}
.variable[exception] > .title > .name,
.property[exception] > .title > .name {
.variable[exception]:not(:focus) > .title > .name,
.property[exception]:not(:focus) > .title > .name {
color: #a00;
text-shadow: 0 0 8px #fcc;
}
@ -438,18 +485,23 @@
* Variables and properties editing
*/
#variables .element-value-input {
overflow: hidden;
max-width: 30em;
-moz-margin-start: 5px !important;
.element-value-input {
-moz-margin-start: 4px !important;
}
#variables .element-name-input {
-moz-margin-start: -1px !important;
.element-name-input {
-moz-margin-start: -2px !important;
color: #048;
font-weight: 600;
}
.element-value-input,
.element-name-input {
max-width: 30em;
border: 1px solid #999 !important;
box-shadow: 1px 2px 4px #aaa;
}
/**
* Variables and properties searching
*/
@ -468,28 +520,28 @@
* Token value colors
*/
.token-undefined {
.variable-or-property:not(:focus) > .title > .token-undefined {
color: #bbb;
}
.token-null {
.variable-or-property:not(:focus) > .title > .token-null {
color: #999;
}
.token-boolean {
.variable-or-property:not(:focus) > .title > .token-boolean {
color: #777;
}
.token-number {
.variable-or-property:not(:focus) > .title > .token-number {
color: #c40a16;
}
.token-string {
.variable-or-property:not(:focus) > .title > .token-string {
max-width: 30em;
color: #1c00cf;
}
.token-other {
.variable-or-property:not(:focus) > .title > .token-other {
color: #333;
}

View File

@ -1045,7 +1045,7 @@ toolbar[mode="icons"] #forward-button:-moz-lwtheme {
}
#zoom-in-button {
-moz-image-region: rect(0, 480px, 40px, 440px);
-moz-image-region: rect(0, 840px, 40px, 800px);
}
}

View File

@ -177,7 +177,6 @@
*/
#stackframes\+breakpoints {
background-color: white;
min-width: 50px;
}
@ -190,7 +189,6 @@
*/
#variables\+expressions {
background-color: white;
min-width: 50px;
}
@ -203,7 +201,6 @@
*/
#stackframes {
background-color: white;
min-height: 10px;
}
@ -225,7 +222,6 @@
*/
#breakpoints {
background-color: white;
min-height: 10px;
}
@ -259,8 +255,8 @@
*/
#expressions {
background-color: white;
min-height: 10px;
max-height: 125px;
}
.dbg-expression {
@ -279,11 +275,20 @@
}
.dbg-expression-delete {
-moz-image-region: rect(0, 32px, 16px, 16px);
opacity: 0;
}
.dbg-expression-delete:not(:hover) {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.dbg-expression-delete:hover {
opacity: 1;
}
.dbg-expression:hover > .dbg-expression-delete:not(:hover) {
opacity: 0.5;
transition: opacity 0.2s ease-in-out;
}
/**
@ -291,17 +296,36 @@
*/
#variables {
background-color: white;
min-height: 10px;
}
.dbg-variable-delete {
opacity: 0;
}
.dbg-variable-delete:not(:hover) {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.dbg-variable-delete:hover {
opacity: 1;
}
.variable-or-property:hover > .title > .dbg-variable-delete:not(:hover),
.variable-or-property:focus > .title > .dbg-variable-delete:not(:hover) {
opacity: 0.5;
transition: opacity 0.2s ease-in-out;
}
.dbg-variable-edit {
background: url("chrome://browser/skin/tabview/edit-light.png") center no-repeat;
width: 20px;
height: 16px;
cursor: pointer;
}
.dbg-variable-throbber {
background: url("chrome://global/skin/icons/loading_16.png");
background: url("chrome://global/skin/icons/loading_16.png") center no-repeat;
width: 16px;
height: 16px;
}
@ -310,6 +334,11 @@
* Scope element
*/
.scope:focus > .title {
background: Highlight;
color: HighlightText;
}
.scope > .title {
text-shadow: 0 1px #222;
color: #fff;
@ -317,7 +346,7 @@
.scope > .details {
-moz-margin-start: 2px;
-moz-margin-end: 2px;
-moz-margin-end: 1px;
}
.scope > .details.nonenum:not(:empty) {
@ -332,7 +361,6 @@
-moz-margin-start: 1px;
-moz-margin-end: 1px;
border-bottom: 1px solid #eee;
background: #fff;
transition: background 1s ease-in-out;
}
@ -341,16 +369,29 @@
transition-duration: 0.4s;
}
.variable:focus > .title {
background: Highlight;
color: HighlightText;
border-radius: 4px;
}
.variable > .title > .name {
color: #048;
font-weight: 600;
}
.variable:not(:focus) > .title > .name {
color: #048;
}
.variable > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.variable[editable] > .title > .value {
cursor: text;
}
.variable:not([non-header]) > .details {
-moz-margin-start: 10px;
}
@ -360,7 +401,6 @@
*/
.property {
background: #fff;
transition: background 1s ease-in-out;
}
@ -369,7 +409,13 @@
transition-duration: 0.4s;
}
.property > .title > .name {
.property:focus > .title {
background: Highlight;
color: HighlightText;
border-radius: 4px;
}
.property:not(:focus) > .title > .name {
color: #881090;
}
@ -378,12 +424,16 @@
-moz-padding-end: 4px;
}
.property[editable] > .title > .value {
cursor: text;
}
.property:not([non-header]) > .details {
-moz-margin-start: 10px;
}
/**
* Non enumerable, configurable and writable variables and properties.
* Non enumerable, configurable and writable variables and properties
*/
.variable[proto] > .title > .name,
@ -421,8 +471,8 @@
}
}
.variable[exception] > .title > .name,
.property[exception] > .title > .name {
.variable[exception]:not(:focus) > .title > .name,
.property[exception]:not(:focus) > .title > .name {
color: #a00;
text-shadow: 0 0 8px #fcc;
}
@ -445,18 +495,23 @@
* Variables and properties editing
*/
#variables .element-value-input {
overflow: hidden;
max-width: 30em;
-moz-margin-start: 5px !important;
.element-value-input {
-moz-margin-start: 4px !important;
}
#variables .element-name-input {
-moz-margin-start: -1px !important;
.element-name-input {
-moz-margin-start: -2px !important;
color: #048;
font-weight: 600;
}
.element-value-input,
.element-name-input {
max-width: 30em;
border: 1px solid #999 !important;
box-shadow: 1px 2px 4px #aaa;
}
/**
* Variables and properties searching
*/
@ -475,28 +530,28 @@
* Token value colors
*/
.token-undefined {
.variable-or-property:not(:focus) > .title > .token-undefined {
color: #bbb;
}
.token-null {
.variable-or-property:not(:focus) > .title > .token-null {
color: #999;
}
.token-boolean {
.variable-or-property:not(:focus) > .title > .token-boolean {
color: #777;
}
.token-number {
.variable-or-property:not(:focus) > .title > .token-number {
color: #c40a16;
}
.token-string {
.variable-or-property:not(:focus) > .title > .token-string {
max-width: 30em;
color: #1c00cf;
}
.token-other {
.variable-or-property:not(:focus) > .title > .token-other {
color: #333;
}

View File

@ -1252,11 +1252,6 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
padding: 2px 2px;
}
.urlbar-icon:-moz-system-metric(touch-enabled) {
-moz-margin-end: 1px !important;
padding: 0 3px !important;
}
.urlbar-icon:hover {
background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.3), hsla(200,100%,70%,0));
}
@ -1383,10 +1378,6 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
-moz-image-region: rect(0px, 11px, 14px, 0px);
}
.urlbar-history-dropmarker:-moz-system-metric(touch-enabled) {
min-width: 6.4mozmm;
}
.urlbar-history-dropmarker:hover {
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), hsla(205,100%,70%,0));
-moz-image-region: rect(0px, 22px, 14px, 11px);
@ -1928,10 +1919,6 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
list-style-image: url("chrome://global/skin/icons/close.png");
}
.tab-close-button:-moz-system-metric(touch-enabled) {
transform: scale(1.2);
}
.tab-close-button:hover,
.tab-close-button:hover[selected="true"] {
-moz-image-region: rect(0, 32px, 16px, 16px);
@ -1948,22 +1935,6 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
/* Tab scrollbox arrow, tabstrip new tab and all-tabs buttons */
@media (-moz-touch-enabled) {
.tabbrowser-arrowscrollbox > .scrollbutton-up,
.tabbrowser-arrowscrollbox > .scrollbutton-down,
#TabsToolbar .toolbarbutton-1 {
min-width: 8.1mozmm;
}
.tabs-newtab-button {
min-width: 10mozmm;
}
.tab-content {
min-height: calc(6.8mozmm - 7px); /* subtract borders from the desired height */
}
}
.tabbrowser-arrowscrollbox > .scrollbutton-up,
.tabbrowser-arrowscrollbox > .scrollbutton-down {
list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");

View File

@ -183,7 +183,6 @@
*/
#stackframes\+breakpoints {
background-color: white;
min-width: 50px;
}
@ -196,7 +195,6 @@
*/
#variables\+expressions {
background-color: white;
min-width: 50px;
}
@ -209,7 +207,6 @@
*/
#stackframes {
background-color: white;
min-height: 10px;
}
@ -231,7 +228,6 @@
*/
#breakpoints {
background-color: white;
min-height: 10px;
}
@ -265,8 +261,8 @@
*/
#expressions {
background-color: white;
min-height: 10px;
max-height: 125px;
}
.dbg-expression {
@ -285,11 +281,20 @@
}
.dbg-expression-delete {
-moz-image-region: rect(0, 32px, 16px, 16px);
opacity: 0;
}
.dbg-expression-delete:not(:hover) {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.dbg-expression-delete:hover {
opacity: 1;
}
.dbg-expression:hover > .dbg-expression-delete:not(:hover) {
opacity: 0.5;
transition: opacity 0.2s ease-in-out;
}
/**
@ -297,17 +302,36 @@
*/
#variables {
background-color: white;
min-height: 10px;
}
.dbg-variable-delete {
opacity: 0;
}
.dbg-variable-delete:not(:hover) {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.dbg-variable-delete:hover {
opacity: 1;
}
.variable-or-property:hover > .title > .dbg-variable-delete:not(:hover),
.variable-or-property:focus > .title > .dbg-variable-delete:not(:hover) {
opacity: 0.5;
transition: opacity 0.2s ease-in-out;
}
.dbg-variable-edit {
background: url("chrome://browser/skin/tabview/edit-light.png") center no-repeat;
width: 20px;
height: 16px;
cursor: pointer;
}
.dbg-variable-throbber {
background: url("chrome://global/skin/icons/loading_16.png");
background: url("chrome://global/skin/icons/loading_16.png") center no-repeat;
width: 16px;
height: 16px;
}
@ -316,6 +340,11 @@
* Scope element
*/
.scope:focus > .title {
background: Highlight;
color: HighlightText;
}
.scope > .title {
text-shadow: 0 1px #222;
color: #fff;
@ -323,7 +352,7 @@
.scope > .details {
-moz-margin-start: 2px;
-moz-margin-end: 2px;
-moz-margin-end: 1px;
}
.scope > .details.nonenum:not(:empty) {
@ -338,7 +367,6 @@
-moz-margin-start: 1px;
-moz-margin-end: 1px;
border-bottom: 1px solid #eee;
background: #fff;
transition: background 1s ease-in-out;
}
@ -347,16 +375,29 @@
transition-duration: 0.4s;
}
.variable:focus > .title {
background: Highlight;
color: HighlightText;
border-radius: 4px;
}
.variable > .title > .name {
color: #048;
font-weight: 600;
}
.variable:not(:focus) > .title > .name {
color: #048;
}
.variable > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.variable[editable] > .title > .value {
cursor: text;
}
.variable:not([non-header]) > .details {
-moz-margin-start: 10px;
}
@ -366,7 +407,6 @@
*/
.property {
background: #fff;
transition: background 1s ease-in-out;
}
@ -375,13 +415,24 @@
transition-duration: 0.4s;
}
.property > .title > .name {
.property:focus > .title {
background: Highlight;
color: HighlightText;
border-radius: 4px;
}
.property:not(:focus) > .title > .name {
color: #881090;
}
.property > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
cursor: text;
}
.property[editable] > .title > .value {
cursor: text;
}
.property:not([non-header]) > .details {
@ -389,7 +440,7 @@
}
/**
* Non enumerable, configurable and writable variables and properties.
* Non enumerable, configurable and writable variables and properties
*/
.variable[proto] > .title > .name,
@ -427,8 +478,8 @@
}
}
.variable[exception] > .title > .name,
.property[exception] > .title > .name {
.variable[exception]:not(:focus) > .title > .name,
.property[exception]:not(:focus) > .title > .name {
color: #a00;
text-shadow: 0 0 8px #fcc;
}
@ -451,18 +502,23 @@
* Variables and properties editing
*/
#variables .element-value-input {
overflow: hidden;
max-width: 30em;
-moz-margin-start: 5px !important;
.element-value-input {
-moz-margin-start: 4px !important;
}
#variables .element-name-input {
-moz-margin-start: -1px !important;
.element-name-input {
-moz-margin-start: -2px !important;
color: #048;
font-weight: 600;
}
.element-value-input,
.element-name-input {
max-width: 30em;
border: 1px solid #999 !important;
box-shadow: 1px 2px 4px #aaa;
}
/**
* Variables and properties searching
*/
@ -481,28 +537,28 @@
* Token value colors
*/
.token-undefined {
.variable-or-property:not(:focus) > .title > .token-undefined {
color: #bbb;
}
.token-null {
.variable-or-property:not(:focus) > .title > .token-null {
color: #999;
}
.token-boolean {
.variable-or-property:not(:focus) > .title > .token-boolean {
color: #777;
}
.token-number {
.variable-or-property:not(:focus) > .title > .token-number {
color: #c40a16;
}
.token-string {
.variable-or-property:not(:focus) > .title > .token-string {
max-width: 30em;
color: #1c00cf;
}
.token-other {
.variable-or-property:not(:focus) > .title > .token-other {
color: #333;
}

View File

@ -64,11 +64,6 @@
-moz-image-region: rect(0px 16px 16px 0px);
}
.search-go-button:-moz-system-metric(touch-enabled) {
-moz-padding-start: 5px;
-moz-padding-end: 3px;
}
.search-go-button:-moz-locale-dir(rtl) {
transform: scaleX(-1);
}

View File

@ -17,13 +17,13 @@ fi
if test "$GXX" = "yes"; then
GNU_CXX=1
CXX_VERSION=`$CXX -v 2>&1 | grep 'gcc version'`
changequote(,)
GCC_VERSION_FULL=`echo "$CXX_VERSION" | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'`
GCC_VERSION=`echo "$GCC_VERSION_FULL" | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'`
changequote([,])
changequote(<<,>>)
GCC_VERSION_FULL=`echo "$CXX_VERSION" | $PERL -pe 's/^.*gcc version ([^ ]*).*/<<$>>1/'`
GCC_VERSION=`echo "$GCC_VERSION_FULL" | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/<<$>>1/;'`
GCC_MAJOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print $1 }'`
GCC_MINOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print $2 }'`
GCC_MAJOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print <<$>>1 }'`
GCC_MINOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print <<$>>2 }'`
changequote([,])
fi
if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then

View File

@ -38,7 +38,7 @@ _slashSqueeze =$(foreach val,$(getargv),$(call getPathPrefix,$(val))$(subst $(sp
# Squeeze extraneous directory slashes from the path
# o protect embedded spaces within the path
# o replace //+ sequences with /
slash_strip =\
slash_strip = \
$(strip \
$(subst <--[**]-->,$(space),\
$(call _slashSqueeze,\
@ -62,20 +62,13 @@ mkdir_deps =$(foreach dir,$(getargv),$(call slash_strip,$(dir)/.mkdir.done))
# 198001010000 would translate to something older than FAT epoch.
@$(TOUCH) -t 198001030000 "$@"
# A handful of makefiles are attempting "mkdir dot". Likely not intended
# or stale logic so add a stub target to handle the request and warn for now.
.mkdir.done:
ifndef NOWARN_AUTOTARGETS # {
@echo "WARNING: $(MKDIR) -dot- requested by $(MAKE) -C $(CURDIR) $(MAKECMDGOALS)"
@$(TOUCH) -t 198001030000 $@
endif #}
INCLUDED_AUTOTARGETS_MK = 1
endif #}
## Accumulate deps and cleanup
ifneq (,$(GENERATED_DIRS))
GENERATED_DIRS := $(strip $(sort $(GENERATED_DIRS)))
tmpauto :=$(call mkdir_deps,GENERATED_DIRS)
GENERATED_DIRS_DEPS +=$(tmpauto)
GARBAGE_DIRS +=$(GENERATED_DIRS)
@ -88,6 +81,7 @@ endif
#################################################################
AUTO_DEPS +=$(GENERATED_DIRS_DEPS)
AUTO_DEPS := $(strip $(sort $(AUTO_DEPS)))
# Complain loudly if deps have not loaded so getargv != $(NULL)
$(call requiredfunction,getargv)

View File

@ -45,11 +45,11 @@ subargv =$(wordlist $(1),$(words $(getargv)),$(getargv))
# $(NULL)
# target: $(target-preqs)
banner =\
$(info )\
$(info ***************************************************************************)\
$(info ** $(getargv))\
$(info ***************************************************************************)\
banner = \
$(info ) \
$(info ***************************************************************************) \
$(info ** $(getargv)) \
$(info ***************************************************************************) \
$(NULL)
#####################################################################

View File

@ -11,8 +11,6 @@ endif
space=$(null) $(null)
GENERATED_DIRS = bogus # test data
NOWARN_AUTOTARGETS = 1 # Unit test includes makefile twice.
undefine USE_AUTOTARGETS_MK
undefine INCLUDED_AUTOTARGETS_MK
include $(topsrcdir)/config/makefiles/autotargets.mk
@ -25,7 +23,7 @@ $(call requiredfunction,mkdir_deps)
# Verify test data populated makefile vars correctly
vars = AUTO_DEPS GARBAGE_DIRS GENERATED_DIRS_DEPS
vars = AUTO_DEPS GARBAGE_DIRS GENERATED_DIRS_DEPS
$(foreach var,$(vars),$(call errorIfEmpty,$(var)))
# Data should also be valid

View File

@ -116,7 +116,7 @@ cppunittests-remote:
--localLib=$(DEPTH)/dist/$(MOZ_APP_NAME) \
--dm_trans=$(DM_TRANS) \
--deviceIP=${TEST_DEVICE} \
$(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)) $(EXTRA_TEST_ARGS); \
$(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)) $(EXTRA_TEST_ARGS); \
else \
echo "please prepare your host with environment variables for TEST_DEVICE"; \
fi

View File

@ -47,6 +47,7 @@
#include "nsEvent.h"
#include "nsAttrValue.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "nsIHTMLCollection.h"
class nsIDOMEventListener;
class nsIFrame;
@ -62,7 +63,6 @@ class nsAttrValueOrString;
class ContentUnbinder;
class nsClientRect;
class nsClientRectList;
class nsIHTMLCollection;
class nsContentList;
class nsDOMTokenList;
struct nsRect;
@ -121,8 +121,8 @@ class UndoManager;
// IID for the dom::Element interface
#define NS_ELEMENT_IID \
{ 0xc6c049a1, 0x96e8, 0x4580, \
{ 0xa6, 0x93, 0xb9, 0x5f, 0x53, 0xbe, 0xe8, 0x1c } }
{ 0xcae9f7e7, 0x6163, 0x47b5, \
{ 0xa1, 0x63, 0x30, 0xc8, 0x1d, 0x2d, 0x79, 0x39 } }
class Element : public FragmentOrElement
{
@ -447,31 +447,24 @@ public:
nsIAtom* aPrefix,
const nsAttrValueOrString& aValue,
bool aNotify, nsAttrValue& aOldValue,
uint8_t* aModType, bool* aHasListeners)
{
if (MaybeCheckSameAttrVal(aNamespaceID, aName, aPrefix, aValue, aNotify,
aOldValue, aModType, aHasListeners)) {
nsAutoScriptBlocker scriptBlocker;
nsNodeUtils::AttributeSetToCurrentValue(this, aNamespaceID, aName);
return true;
}
return false;
}
uint8_t* aModType, bool* aHasListeners);
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
const nsAString& aValue, bool aNotify);
nsresult SetParsedAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
nsAttrValue& aParsedValue, bool aNotify);
virtual bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
nsAString& aResult) const;
virtual bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const;
// GetAttr is not inlined on purpose, to keep down codesize from all
// the inlined nsAttrValue bits for C++ callers.
bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
nsAString& aResult) const;
inline bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const;
// aCaseSensitive == eIgnoreCaase means ASCII case-insensitive matching.
virtual bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
const nsAString& aValue,
nsCaseTreatment aCaseSensitive) const;
virtual bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
nsIAtom* aValue,
nsCaseTreatment aCaseSensitive) const;
inline bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
const nsAString& aValue,
nsCaseTreatment aCaseSensitive) const;
inline bool AttrValueIs(int32_t aNameSpaceID, nsIAtom* aName,
nsIAtom* aValue,
nsCaseTreatment aCaseSensitive) const;
virtual int32_t FindAttrValueIn(int32_t aNameSpaceID,
nsIAtom* aName,
AttrValuesArray* aValues,
@ -1164,6 +1157,43 @@ private:
NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
inline bool
Element::HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const
{
NS_ASSERTION(nullptr != aName, "must have attribute name");
NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
"must have a real namespace ID!");
return mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID) >= 0;
}
inline bool
Element::AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
const nsAString& aValue,
nsCaseTreatment aCaseSensitive) const
{
NS_ASSERTION(aName, "Must have attr name");
NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
return val && val->Equals(aValue, aCaseSensitive);
}
inline bool
Element::AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
nsIAtom* aValue,
nsCaseTreatment aCaseSensitive) const
{
NS_ASSERTION(aName, "Must have attr name");
NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
NS_ASSERTION(aValue, "Null value atom");
const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
return val && val->Equals(aValue, aCaseSensitive);
}
} // namespace dom
} // namespace mozilla

View File

@ -34,8 +34,8 @@ enum nsLinkState {
// IID for the nsIContent interface
#define NS_ICONTENT_IID \
{ 0xe2985850, 0x81ca, 0x4b5d, \
{ 0xb0, 0xf3, 0xe3, 0x95, 0xd5, 0x0d, 0x85, 0x64 } }
{ 0x8a8b4b1d, 0x72d8, 0x428e, \
{ 0x95, 0x75, 0xf9, 0x18, 0xba, 0xf6, 0x9e, 0xa1 } }
/**
* A node of content in a document's content model. This interface
@ -372,8 +372,8 @@ public:
* @returns true if the attribute was set (even when set to empty string)
* false when not set.
*/
virtual bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
nsAString& aResult) const = 0;
bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
nsAString& aResult) const;
/**
* Determine if an attribute has been set (empty string or otherwise).
@ -382,7 +382,7 @@ public:
* @param aAttr the attribute name
* @return whether an attribute exists
*/
virtual bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const = 0;
bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const;
/**
* Test whether this content node's given attribute has the given value. If
@ -394,13 +394,10 @@ public:
* @param aValue The value to compare to.
* @param aCaseSensitive Whether to do a case-sensitive compare on the value.
*/
virtual bool AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
const nsAString& aValue,
nsCaseTreatment aCaseSensitive) const
{
return false;
}
bool AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
const nsAString& aValue,
nsCaseTreatment aCaseSensitive) const;
/**
* Test whether this content node's given attribute has the given value. If
@ -412,13 +409,10 @@ public:
* @param aValue The value to compare to. Must not be null.
* @param aCaseSensitive Whether to do a case-sensitive compare on the value.
*/
virtual bool AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
nsIAtom* aValue,
nsCaseTreatment aCaseSensitive) const
{
return false;
}
bool AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
nsIAtom* aValue,
nsCaseTreatment aCaseSensitive) const;
enum {
ATTR_MISSING = -1,

View File

@ -388,6 +388,7 @@ protected:
virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
bool *aTriedToWrap)
{
MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapNode");
*aTriedToWrap = false;
return nullptr;
}

View File

@ -5,7 +5,8 @@
#ifndef nsViewportInfo_h___
#define nsViewportInfo_h___
#include "nsContentUtils.h"
#include "mozilla/StandardInteger.h"
#include "nscore.h"
/**
* Default values for the nsViewportInfo class.

View File

@ -62,15 +62,6 @@ public:
{
return NS_OK;
}
virtual bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
nsAString& aResult) const
{
return false;
}
virtual bool HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const
{
return false;
}
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
bool aNotify)
{

View File

@ -1728,6 +1728,23 @@ Element::MaybeCheckSameAttrVal(int32_t aNamespaceID,
return false;
}
bool
Element::OnlyNotifySameValueSet(int32_t aNamespaceID, nsIAtom* aName,
nsIAtom* aPrefix,
const nsAttrValueOrString& aValue,
bool aNotify, nsAttrValue& aOldValue,
uint8_t* aModType, bool* aHasListeners)
{
if (!MaybeCheckSameAttrVal(aNamespaceID, aName, aPrefix, aValue, aNotify,
aOldValue, aModType, aHasListeners)) {
return false;
}
nsAutoScriptBlocker scriptBlocker;
nsNodeUtils::AttributeSetToCurrentValue(this, aNamespaceID, aName);
return true;
}
nsresult
Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
@ -1967,43 +1984,6 @@ Element::GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
return haveAttr;
}
bool
Element::HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const
{
NS_ASSERTION(nullptr != aName, "must have attribute name");
NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
"must have a real namespace ID!");
return mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID) >= 0;
}
bool
Element::AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
const nsAString& aValue,
nsCaseTreatment aCaseSensitive) const
{
NS_ASSERTION(aName, "Must have attr name");
NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
return val && val->Equals(aValue, aCaseSensitive);
}
bool
Element::AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
nsIAtom* aValue,
nsCaseTreatment aCaseSensitive) const
{
NS_ASSERTION(aName, "Must have attr name");
NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
NS_ASSERTION(aValue, "Null value atom");
const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
return val && val->Equals(aValue, aCaseSensitive);
}
int32_t
Element::FindAttrValueIn(int32_t aNameSpaceID,
nsIAtom* aName,

View File

@ -843,6 +843,43 @@ nsIContent::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
return NS_OK;
}
bool
nsIContent::GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
nsAString& aResult) const
{
if (IsElement()) {
return AsElement()->GetAttr(aNameSpaceID, aName, aResult);
}
aResult.Truncate();
return false;
}
bool
nsIContent::HasAttr(int32_t aNameSpaceID, nsIAtom* aName) const
{
return IsElement() && AsElement()->HasAttr(aNameSpaceID, aName);
}
bool
nsIContent::AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
const nsAString& aValue,
nsCaseTreatment aCaseSensitive) const
{
return IsElement() &&
AsElement()->AttrValueIs(aNameSpaceID, aName, aValue, aCaseSensitive);
}
bool
nsIContent::AttrValueIs(int32_t aNameSpaceID,
nsIAtom* aName,
nsIAtom* aValue,
nsCaseTreatment aCaseSensitive) const
{
return IsElement() &&
AsElement()->AttrValueIs(aNameSpaceID, aName, aValue, aCaseSensitive);
}
const nsAttrValue*
FragmentOrElement::DoGetClasses() const
{

View File

@ -5,7 +5,7 @@
#ifndef mozAutoDocUpdate_h_
#define mozAutoDocUpdate_h_
#include "nsContentUtils.h"
#include "nsContentUtils.h" // For AddScriptBlocker() and RemoveScriptBlocker().
#include "nsIDocument.h"
#include "nsIDocumentObserver.h"

View File

@ -9,6 +9,7 @@
#include "nsHTMLFormElement.h"
#include "mozilla/dom/FormDataBinding.h"
#include "mozilla/dom/BindingUtils.h"
#include "nsContentUtils.h"
using namespace mozilla;
using namespace mozilla::dom;

View File

@ -86,6 +86,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "nsIAppsService.h"
#include "sampler.h"
#include "jsapi.h"
#include "nsHTMLIFrameElement.h"
@ -411,6 +412,8 @@ nsFrameLoader::ReallyStartLoadingInternal()
{
NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInDoc());
SAMPLE_LABEL("nsFrameLoader", "ReallyStartLoading");
nsresult rv = MaybeCreateDocShell();
if (NS_FAILED(rv)) {
return rv;
@ -2030,6 +2033,8 @@ nsFrameLoader::TryRemoteBrowser()
return false;
}
SAMPLE_LABEL("nsFrameLoader", "CreateRemoteBrowser");
MutableTabContext context;
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
nsCOMPtr<mozIApplication> containingApp = GetContainingApp();

View File

@ -1129,10 +1129,7 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope)
nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
bool allowXML = Preferences::GetBool("javascript.options.xml.chrome");
JS_SetOptions(cx, JS_GetOptions(cx) |
JSOPTION_PRIVATE_IS_NSISUPPORTS |
(allowXML ? JSOPTION_ALLOW_XML : 0));
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_PRIVATE_IS_NSISUPPORTS);
JS_SetVersion(cx, JSVERSION_LATEST);
JS_SetErrorReporter(cx, ContentScriptErrorReporter);

View File

@ -577,21 +577,6 @@ nsGenericDOMDataNode::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
return NS_OK;
}
bool
nsGenericDOMDataNode::GetAttr(int32_t aNameSpaceID, nsIAtom *aAttr,
nsAString& aResult) const
{
aResult.Truncate();
return false;
}
bool
nsGenericDOMDataNode::HasAttr(int32_t aNameSpaceID, nsIAtom *aAttribute) const
{
return false;
}
const nsAttrName*
nsGenericDOMDataNode::GetAttrNameAt(uint32_t aIndex) const
{

View File

@ -115,9 +115,6 @@ public:
bool aNotify);
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
bool aNotify);
virtual bool GetAttr(int32_t aNameSpaceID, nsIAtom *aAttribute,
nsAString& aResult) const;
virtual bool HasAttr(int32_t aNameSpaceID, nsIAtom *aAttribute) const;
virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const;
virtual uint32_t GetAttrCount() const;
virtual const nsTextFragment *GetText();

View File

@ -1245,3 +1245,16 @@ nsImageLoadingContent::GetCORSMode()
{
return CORS_NONE;
}
nsImageLoadingContent::ImageObserver::ImageObserver(imgINotificationObserver* aObserver)
: mObserver(aObserver)
, mNext(nullptr)
{
MOZ_COUNT_CTOR(ImageObserver);
}
nsImageLoadingContent::ImageObserver::~ImageObserver()
{
MOZ_COUNT_DTOR(ImageObserver);
NS_CONTENT_DELETE_LIST_MEMBER(ImageObserver, this, mNext);
}

View File

@ -17,15 +17,19 @@
#include "imgIOnloadBlocker.h"
#include "mozilla/CORSMode.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h" // NS_CONTENT_DELETE_LIST_MEMBER
#include "nsEventStates.h"
#include "nsIImageLoadingContent.h"
#include "nsIRequest.h"
#include "mozilla/ErrorResult.h"
#include "nsAutoPtr.h"
class nsIURI;
class nsIDocument;
class imgILoader;
class nsIIOService;
class nsPresContext;
class nsIContent;
class imgRequestProxy;
class nsImageLoadingContent : public nsIImageLoadingContent,
public imgIOnloadBlocker
@ -186,17 +190,8 @@ private:
* Struct used to manage the image observers.
*/
struct ImageObserver {
ImageObserver(imgINotificationObserver* aObserver) :
mObserver(aObserver),
mNext(nullptr)
{
MOZ_COUNT_CTOR(ImageObserver);
}
~ImageObserver()
{
MOZ_COUNT_DTOR(ImageObserver);
NS_CONTENT_DELETE_LIST_MEMBER(ImageObserver, this, mNext);
}
ImageObserver(imgINotificationObserver* aObserver);
~ImageObserver();
nsCOMPtr<imgINotificationObserver> mObserver;
ImageObserver* mNext;

View File

@ -84,7 +84,15 @@ public:
// Update the security UI in the tab with the allowed mixed active content
nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
if (eventSink) {
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
// If mixed display content is loaded, make sure to include that in the state.
if (rootDoc->GetHasMixedDisplayContentLoaded()) {
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
} else {
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
}
}
} else if (mType == eMixedDisplay) {
@ -97,7 +105,15 @@ public:
// Update the security UI in the tab with the allowed mixed display content.
nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
if (eventSink) {
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
// If mixed active content is loaded, make sure to include that in the state.
if (rootDoc->GetHasMixedActiveContentLoaded()) {
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
} else {
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
}
}
}
@ -160,7 +176,10 @@ nsMixedContentBlocker::ShouldLoad(uint32_t aContentType,
//
// TYPE_OBJECT_SUBREQUEST could actually be either active content (e.g. a
// script that a plugin will execute) or display content (e.g. Flash video
// content).
// content). Until we have a way to determine active vs passive content
// from plugin requests (bug 836352), we will treat this as passive content.
// This is to prevent false positives from causing users to become
// desensitized to the mixed content blocker.
//
// TYPE_CSP_REPORT: High-risk because they directly leak information about
// the content of the page, and because blocking them does not have any
@ -220,6 +239,7 @@ nsMixedContentBlocker::ShouldLoad(uint32_t aContentType,
// these will be blocked according to the mixed display preference
case TYPE_IMAGE:
case TYPE_MEDIA:
case TYPE_OBJECT_SUBREQUEST:
case TYPE_PING:
classification = eMixedDisplay;
break;
@ -231,7 +251,6 @@ nsMixedContentBlocker::ShouldLoad(uint32_t aContentType,
case TYPE_DTD:
case TYPE_FONT:
case TYPE_OBJECT:
case TYPE_OBJECT_SUBREQUEST:
case TYPE_SCRIPT:
case TYPE_STYLESHEET:
case TYPE_SUBDOCUMENT:
@ -364,10 +383,15 @@ nsMixedContentBlocker::ShouldLoad(uint32_t aContentType,
nsCOMPtr<nsIDocShell> rootShell = do_GetInterface(sameTypeRoot);
NS_ASSERTION(rootShell, "No root docshell from document shell root tree item.");
uint32_t State = nsIWebProgressListener::STATE_IS_BROKEN;
nsCOMPtr<nsISecureBrowserUI> SecurityUI;
rootShell->GetSecurityUI(getter_AddRefs(SecurityUI));
NS_ASSERTION(SecurityUI, "No SecurityUI from the root docShell.");
nsresult stateRV = SecurityUI->GetState(&State);
nsCOMPtr<nsISecureBrowserUI> securityUI;
rootShell->GetSecurityUI(getter_AddRefs(securityUI));
// If there is no securityUI, document doesn't have a security state.
// Allow load and return early.
if (!securityUI) {
*aDecision = nsIContentPolicy::ACCEPT;
return NS_OK;
}
nsresult stateRV = securityUI->GetState(&State);
// If the content is display content, and the pref says display content should be blocked, block it.
if (sBlockMixedDisplay && classification == eMixedDisplay) {
@ -400,9 +424,12 @@ nsMixedContentBlocker::ShouldLoad(uint32_t aContentType,
// User has decided to override the pref and the root is https, so change the Security State.
if (rootDoc->GetHasMixedDisplayContentLoaded()) {
// If mixed display content is loaded, make sure to include that in the state.
eventSink->OnSecurityChange(aRequestingContext, (nsIWebProgressListener::STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT | nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
eventSink->OnSecurityChange(aRequestingContext, (nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
} else {
eventSink->OnSecurityChange(aRequestingContext, (nsIWebProgressListener::STATE_IS_BROKEN | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
eventSink->OnSecurityChange(aRequestingContext, (nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
}
return NS_OK;
} else {

View File

@ -15,7 +15,6 @@
#include "nsImageLoadingContent.h"
#include "nsIStreamListener.h"
#include "nsFrameLoader.h"
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
#include "nsIObjectLoadingContent.h"
@ -23,6 +22,7 @@
#include "nsPluginInstanceOwner.h"
#include "nsIThreadInternal.h"
#include "nsIFrame.h"
#include "nsIFrameLoader.h"
class nsAsyncInstantiateEvent;
class nsStopPluginRunnable;
@ -30,6 +30,7 @@ class AutoNotifier;
class AutoFallback;
class AutoSetInstantiatingToFalse;
class nsObjectFrame;
class nsFrameLoader;
class nsObjectLoadingContent : public nsImageLoadingContent
, public nsIStreamListener

View File

@ -398,20 +398,6 @@ ParseTypeAttribute(const nsAString& aType, JSVersion* aVersion)
return false;
}
nsAutoString value;
rv = parser.GetParameter("e4x", value);
if (NS_SUCCEEDED(rv)) {
if (value.Length() == 1 && value[0] == '1') {
// This happens in about 2 web pages. Enable E4X no matter what JS
// version number was selected. We do this by turning on the "moar
// XML" version bit. This is OK even if version has
// JSVERSION_UNKNOWN (-1).
*aVersion = js::VersionSetMoarXML(*aVersion, true);
}
} else if (rv != NS_ERROR_INVALID_ARG) {
return false;
}
return true;
}

View File

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsViewportInfo.h"
#include "mozilla/Assertions.h"
#include <algorithm>
void

View File

@ -31,7 +31,6 @@
#include "nsITimer.h"
#include "nsIDOMProgressEvent.h"
#include "nsDOMEventTargetHelper.h"
#include "nsContentUtils.h"
#include "nsDOMFile.h"
#include "nsDOMBlobBuilder.h"
#include "nsIPrincipal.h"

View File

@ -6,7 +6,7 @@
#include "base/basictypes.h"
#include "CanvasRenderingContext2D.h"
#include "nsIDOMXULElement.h"
#include "nsXULElement.h"
#include "prenv.h"
@ -3234,7 +3234,7 @@ CanvasRenderingContext2D::DrawWindow(nsIDOMWindow* window, double x,
}
void
CanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* elem,
CanvasRenderingContext2D::AsyncDrawXULElement(nsXULElement& elem,
double x, double y,
double w, double h,
const nsAString& bgColor,
@ -3255,7 +3255,7 @@ CanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* elem,
}
#if 0
nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(elem);
nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(&elem);
if (!loaderOwner) {
error.Throw(NS_ERROR_FAILURE);
return;

View File

@ -24,7 +24,7 @@
#define NS_CANVASPATTERNAZURE_PRIVATE_IID \
{0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
class nsIDOMXULElement;
class nsXULElement;
namespace mozilla {
namespace gfx {
@ -438,7 +438,7 @@ public:
void DrawWindow(nsIDOMWindow* window, double x, double y, double w, double h,
const nsAString& bgColor, uint32_t flags,
mozilla::ErrorResult& error);
void AsyncDrawXULElement(nsIDOMXULElement* elem, double x, double y, double w,
void AsyncDrawXULElement(nsXULElement& elem, double x, double y, double w,
double h, const nsAString& bgColor, uint32_t flags,
mozilla::ErrorResult& error);

View File

@ -68,6 +68,7 @@ CPPSRCS += \
LOCAL_INCLUDES += \
-I$(topsrcdir)/js/xpconnect/wrappers \
-I$(topsrcdir)/content/xul/content/src \
$(NULL)
else

View File

@ -6,6 +6,7 @@
#include "WebGLBuffer.h"
#include "WebGLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "nsContentUtils.h"
using namespace mozilla;

View File

@ -5,6 +5,7 @@
#include "WebGLContext.h"
#include "WebGLExtensions.h"
#include "nsContentUtils.h"
using namespace mozilla;

View File

@ -6,6 +6,7 @@
#include "WebGLContext.h"
#include "WebGLFramebuffer.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "nsContentUtils.h"
using namespace mozilla;

View File

@ -6,6 +6,7 @@
#include "WebGLContext.h"
#include "WebGLProgram.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "nsContentUtils.h"
using namespace mozilla;

View File

@ -6,6 +6,7 @@
#include "WebGLContext.h"
#include "WebGLRenderbuffer.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "nsContentUtils.h"
using namespace mozilla;

View File

@ -6,6 +6,7 @@
#include "WebGLShader.h"
#include "WebGLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "nsContentUtils.h"
using namespace mozilla;

View File

@ -7,6 +7,7 @@
#include "WebGLTexture.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include <algorithm>
#include "nsContentUtils.h"
using namespace mozilla;

View File

@ -3902,6 +3902,18 @@ public:
nsCOMPtr<nsIContent> mTarget;
};
/*static*/ bool
nsEventStateManager::IsHandlingUserInput()
{
if (sUserInputEventDepth <= 0) {
return false;
}
TimeDuration timeout = nsContentUtils::HandlingUserInputTimeout();
return timeout <= TimeDuration(0) ||
(TimeStamp::Now() - sHandlingInputStart) <= timeout;
}
nsIFrame*
nsEventStateManager::DispatchMouseEvent(nsGUIEvent* aEvent, uint32_t aMessage,
nsIContent* aTargetContent,

View File

@ -6,6 +6,8 @@
#ifndef nsEventStateManager_h__
#define nsEventStateManager_h__
#include "mozilla/TypedEnum.h"
#include "nsEvent.h"
#include "nsGUIEvent.h"
#include "nsIContent.h"
@ -24,7 +26,6 @@
#include "nsIDocument.h"
#include "nsEventStates.h"
#include "mozilla/TimeStamp.h"
#include "nsContentUtils.h"
#include "nsIFrame.h"
class nsIPresShell;
@ -173,15 +174,7 @@ public:
* dom.event.handling-user-input-time-limit pref (default 1 second), this
* function also returns false.
*/
static bool IsHandlingUserInput()
{
if (sUserInputEventDepth <= 0) {
return false;
}
TimeDuration timeout = nsContentUtils::HandlingUserInputTimeout();
return timeout <= TimeDuration(0) ||
(TimeStamp::Now() - sHandlingInputStart) <= timeout;
}
static bool IsHandlingUserInput();
nsPresContext* GetPresContext() { return mPresContext; }

View File

@ -10,6 +10,7 @@
#include "nsAttrValueInlines.h"
#include "nsMappedAttributes.h"
#include "nsRuleData.h"
#include "nsContentUtils.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(Font)
DOMCI_NODE_DATA(HTMLFontElement, mozilla::dom::HTMLFontElement)

View File

@ -23,6 +23,7 @@
#include "nsNPAPIPluginInstance.h"
#include "nsIConstraintValidation.h"
#include "nsIWidget.h"
#include "nsContentUtils.h"
namespace mozilla {
namespace dom {
@ -106,8 +107,8 @@ public:
void StartObjectLoad() { StartObjectLoad(true); }
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLObjectElement,
nsGenericHTMLFormElement)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLObjectElement,
nsGenericHTMLFormElement)
virtual nsXPCClassInfo* GetClassInfo();
@ -171,8 +172,13 @@ HTMLObjectElement::DoneAddingChildren(bool aHaveNotified)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLObjectElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
nsObjectLoadingContent::Traverse(tmp, cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLObjectElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(HTMLObjectElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLObjectElement, Element)

View File

@ -13,6 +13,7 @@
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/HTMLCollectionBinding.h"
#include "mozilla/dom/HTMLTableElementBinding.h"
#include "nsContentUtils.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(Table)
DOMCI_NODE_DATA(HTMLTableElement, mozilla::dom::HTMLTableElement)

View File

@ -12,6 +12,8 @@
#include "nsRuleData.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/HTMLTableRowElementBinding.h"
#include "nsContentList.h"
#include "nsContentUtils.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(TableRow)
DOMCI_NODE_DATA(HTMLTableRowElement, mozilla::dom::HTMLTableRowElement)

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