[Pkg-mozext-commits] [firebug] 80/82: FBTrace: fix the tracing console for Firebug 1.11
David Prévot
taffit at moszumanska.debian.org
Mon Mar 31 22:45:43 UTC 2014
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to tag fbtest-1.11.2
in repository firebug.
commit 891dbd27d4e6fc4d22d83b94e7164d7ebc5b55dc
Author: Jan Odvarko <odvarko at gmail.com>
Date: Wed Feb 6 14:58:33 2013 +0100
FBTrace: fix the tracing console for Firebug 1.11
---
.../chrome/firebug/content/branch.properties | 2 +-
.../chrome/firebug/content/chrome/activation.js | 2 +
.../FBTrace/chrome/firebug/content/chrome/reps.js | 149 +++--
.../firebug/content/console/autoCompleter.js | 188 ++++--
.../firebug/content/console/closureInspector.js | 505 +++++++++++++++
.../chrome/firebug/content/console/commandLine.js | 101 ++-
.../firebug/content/console/commandLineExposed.js | 79 ++-
.../firebug/content/console/commandLineHelp.js | 106 +++-
.../firebug/content/console/commandLineInclude.js | 63 +-
.../chrome/firebug/content/console/consolePanel.js | 5 +-
.../chrome/firebug/content/cookies/breakpoints.js | 6 +-
.../FBTrace/chrome/firebug/content/css/cssPanel.js | 52 +-
.../chrome/firebug/content/css/stylePanel.js | 4 +
.../FBTrace/chrome/firebug/content/dom/domPanel.js | 361 ++++++-----
.../chrome/firebug/content/editor/editor.js | 2 +-
trace/FBTrace/chrome/firebug/content/firebug.js | 15 +-
.../firebug/content/firefox/browserOverlay.js | 6 +-
.../firebug/content/firefox/browserOverlayLib.js | 7 +-
.../chrome/firebug/content/html/highlighter.css | 1 +
.../chrome/firebug/content/html/htmlPanel.js | 1 +
.../chrome/firebug/content/html/inspector.js | 39 +-
.../FBTrace/chrome/firebug/content/html/layout.js | 4 +-
.../FBTrace/chrome/firebug/content/js/debugger.js | 22 +-
.../chrome/firebug/content/js/scriptPanel.js | 7 +-
.../chrome/firebug/content/js/watchPanel.js | 21 +-
trace/FBTrace/chrome/firebug/content/lib/array.js | 21 +-
trace/FBTrace/chrome/firebug/content/lib/css.js | 17 +-
trace/FBTrace/chrome/firebug/content/lib/dom.js | 704 ++++++++++++++++++---
.../FBTrace/chrome/firebug/content/lib/domplate.js | 29 +-
trace/FBTrace/chrome/firebug/content/lib/lib.js | 7 +-
trace/FBTrace/chrome/firebug/content/lib/object.js | 12 -
.../FBTrace/chrome/firebug/content/lib/options.js | 2 +-
trace/FBTrace/chrome/firebug/content/lib/string.js | 6 +-
.../FBTrace/chrome/firebug/content/lib/wrapper.js | 13 +-
.../chrome/firebug/content/net/netDebugger.js | 6 +-
trace/FBTrace/chrome/firebug/content/net/spy.js | 7 +
.../chrome/firebug/modules/firebug-service.js | 35 +-
trace/FBTrace/chrome/firebug/modules/loader.js | 11 +-
trace/FBTrace/chrome/firebug/modules/prefLoader.js | 3 +-
.../chrome/firebug/skin/classic/console.css | 18 +-
40 files changed, 2051 insertions(+), 588 deletions(-)
diff --git a/trace/FBTrace/chrome/firebug/content/branch.properties b/trace/FBTrace/chrome/firebug/content/branch.properties
index 9ab088f..83e7e2c 100644
--- a/trace/FBTrace/chrome/firebug/content/branch.properties
+++ b/trace/FBTrace/chrome/firebug/content/branch.properties
@@ -1,5 +1,5 @@
# DO NOT MERGE INTO TRUNK
-RELEASE=.0
+RELEASE=.2
VERSION=1.11
TRUNK=
# To allow build.xml to drop the xpi directly into the svn working copy for getfirebug.com
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/activation.js b/trace/FBTrace/chrome/firebug/content/chrome/activation.js
index c1e1f75..3fd256f 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/activation.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/activation.js
@@ -171,8 +171,10 @@ Firebug.Activation = Obj.extend(Firebug.Module,
catch (exc)
{
if (FBTrace.DBG_ERRORS)
+ {
FBTrace.sysout("pageHasAnnotation FAILS for url: " + url + " which gave uri " +
(uri ? uri.spec : "null"), exc);
+ }
}
},
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/reps.js b/trace/FBTrace/chrome/firebug/content/chrome/reps.js
index 71e124f..1b9d25e 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/reps.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/reps.js
@@ -24,12 +24,13 @@ define([
"firebug/lib/xml",
"firebug/dom/toggleBranch",
"firebug/console/eventMonitor",
+ "firebug/console/closureInspector",
"firebug/chrome/menu",
"arch/compilationunit",
],
function(Obj, Arr, Firebug, Domplate, Firefox, Xpcom, Locale, HTMLLib, Events, Wrapper, Options,
Url, SourceLink, StackFrame, Css, Dom, Win, System, Xpath, Str, Xml, ToggleBranch,
- EventMonitor, Menu, CompilationUnit) {
+ EventMonitor, ClosureInspector, Menu, CompilationUnit) {
with (Domplate) {
@@ -58,10 +59,10 @@ catch (err)
// use pre here to keep line breaks while copying multiline strings
var OBJECTBOX = FirebugReps.OBJECTBOX =
- PRE({"class": "objectBox inline objectBox-$className", role : "presentation"});
+ PRE({"class": "objectBox inline objectBox-$className", role: "presentation"});
var OBJECTBLOCK = FirebugReps.OBJECTBLOCK =
- DIV({"class": "objectBox objectBox-$className focusRow subLogRow", role : "listitem"});
+ DIV({"class": "objectBox objectBox-$className focusRow subLogRow", role: "listitem"});
var OBJECTLINK = FirebugReps.OBJECTLINK =
A({
@@ -209,7 +210,7 @@ FirebugReps.Caption = domplate(Firebug.Rep,
FirebugReps.Warning = domplate(Firebug.Rep,
{
- tag: DIV({"class": "warning focusRow", role : 'listitem'}, "$object|STR")
+ tag: DIV({"class": "warning focusRow", role: "listitem"}, "$object|STR")
});
// ********************************************************************************************* //
@@ -792,62 +793,19 @@ FirebugReps.ArrayLikeObject = domplate(FirebugReps.ArrBase,
getTitle: function(obj, context)
{
- var arr = Wrapper.unwrapObject(obj);
- const re =/\[object ([^\]]*)/;
- var label = Str.safeToString(arr);
- var m = re.exec(label);
- if (m)
- return m[1] || label;
-
- if ((arr instanceof Ci.nsIDOMDOMTokenList) || (this.isTokenList_Fx19(obj)))
+ if (Arr._isDOMTokenList(obj))
return "DOMTokenList";
- return "";
+ const re = /\[object ([^\]]*)/;
+ var label = Object.prototype.toString.call(obj);
+ var m = re.exec(label);
+ return (m ? m[1] : label);
},
isArray: function(obj)
{
- if (this.isArrayLike_Fx19(obj))
- return true;
-
return Arr.isArrayLike(obj);
- },
-
- /**
- * Hack for Firefox 19 where obj instanceof Ci.nsIDOMDOMTokenList doesn't work.
- */
- isTokenList_Fx19: function(obj)
- {
- var context = Firebug.currentContext;
- if (!context)
- return false;
-
- var view = Wrapper.getContentView(context.window);
- if (!view)
- return false;
-
- obj = Wrapper.unwrapObject(obj);
- return (obj instanceof view.DOMTokenList);
- },
-
- /**
- * Hack for Firefox 19 where obj instanceof Ci.nsIDOMDOMTokenList,
- * Ci.nsIDOMHTMLCollection and nsIDOMNodeList doesn't work.
- */
- isArrayLike_Fx19: function(obj)
- {
- var context = Firebug.currentContext;
- if (!context)
- return false;
-
- var view = Wrapper.getContentView(context.window);
- if (!view)
- return false;
-
- obj = Wrapper.unwrapObject(obj);
- return (obj instanceof view.DOMTokenList) || (obj instanceof view.HTMLCollection) ||
- (obj instanceof view.NodeList);
- },
+ }
});
// ********************************************************************************************* //
@@ -1234,6 +1192,20 @@ FirebugReps.Element = domplate(Firebug.Rep,
return true;
},
+ ignoreTarget: function(target)
+ {
+ // XXX: Temporary fix for issue 5577.
+ var repNode = target && Firebug.getRepNode(target);
+ return (repNode && repNode.classList.contains("cssRule"));
+ },
+
+ highlightObject: function(object, context, target)
+ {
+ if (this.ignoreTarget(target))
+ return;
+ Firebug.Inspector.highlightObject(object, context);
+ },
+
persistObject: function(elt, context)
{
var xpath = Xpath.getElementXPath(elt);
@@ -1258,8 +1230,7 @@ FirebugReps.Element = domplate(Firebug.Rep,
getContextMenuItems: function(elt, target, context)
{
- // XXX: Temporary fix for issue 5577.
- if (Dom.getAncestorByClass(target, "cssElementRuleContainer"))
+ if (this.ignoreTarget(target))
return;
var type;
@@ -1927,7 +1898,10 @@ FirebugReps.SourceLink = domplate(Firebug.Rep,
try
{
- var fileName = Url.getFileName(sourceLink.href);
+ // XXX This is wrong for at least data: URLs. E.g. evaluating
+ // "%2f" in the command line shows as "/".
+ var fileName = sourceLink.href;
+ fileName = Url.getFileName(fileName);
fileName = decodeURIComponent(fileName);
}
catch(exc)
@@ -1935,8 +1909,6 @@ FirebugReps.SourceLink = domplate(Firebug.Rep,
if (FBTrace.DBG_ERRORS)
FBTrace.sysout("reps.getSourceLinkTitle decodeURIComponent fails for \'" +
sourceLink.href + "\': " + exc, exc);
-
- fileName = sourceLink.href;
}
var maxWidth = Firebug.sourceLinkLabelWidth;
@@ -2331,7 +2303,7 @@ FirebugReps.StackTrace = domplate(Firebug.Rep,
frameIterator: function(frames)
{
// Skip Firebug internal frames.
- // xxxHonza: this is anoter place where stack frame is peeling off.
+ // xxxHonza: this is another place where we peel off stack frames.
var result = [];
for (var i=0; frames && i<frames.length; i++)
{
@@ -3068,8 +3040,9 @@ FirebugReps.Description = domplate(Firebug.Rep,
{
className: "Description",
+ // Use SPAN to make sure the description is nicely inserted into existing text inline.
tag:
- DIV({onclick: "$onClickLink"}),
+ SPAN({onclick: "$onClickLink"}),
render: function(text, parentNode, listener)
{
@@ -3319,6 +3292,58 @@ FirebugReps.ErrorCopy = function(message)
this.message = message;
};
+//********************************************************************************************** //
+
+FirebugReps.ClosureScope = domplate(Firebug.Rep,
+{
+ tag: OBJECTBOX({_repObject: "$object"}, "$object|getTitle"),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ className: "scope",
+
+ getTitle: function(object)
+ {
+ var scope = ClosureInspector.getScopeFromWrapper(object);
+ var type = scope.type, title;
+ if (type === "declarative")
+ title = Locale.$STR("firebug.reps.declarativeScope");
+ else if (type === "object")
+ title = Locale.$STR("firebug.reps.objectScope");
+ else if (type === "with")
+ title = Locale.$STR("firebug.reps.withScope");
+ else
+ title = "<unknown scope \"" + type + "\">"; // shouldn't happen
+ return title;
+ },
+
+ supportsObject: function(object, type)
+ {
+ return ClosureInspector.isScopeWrapper(object);
+ }
+});
+
+// ********************************************************************************************* //
+
+FirebugReps.OptimizedAway = domplate(Firebug.Rep,
+{
+ tag: OBJECTBOX({_repObject: "$object"}, "$object|getTitle"),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ className: "optimizedAway",
+
+ getTitle: function(object)
+ {
+ return Locale.$STR("firebug.reps.optimizedAway");
+ },
+
+ supportsObject: function(object, type)
+ {
+ return ClosureInspector.isOptimizedAway(object);
+ }
+});
+
// ********************************************************************************************* //
// Registration
@@ -3354,7 +3379,9 @@ Firebug.registerRep(
FirebugReps.Date,
FirebugReps.NamedNodeMap,
FirebugReps.Reference,
- FirebugReps.EventLog
+ FirebugReps.EventLog,
+ FirebugReps.ClosureScope,
+ FirebugReps.OptimizedAway
);
Firebug.setDefaultReps(FirebugReps.Func, FirebugReps.Obj);
diff --git a/trace/FBTrace/chrome/firebug/content/console/autoCompleter.js b/trace/FBTrace/chrome/firebug/content/console/autoCompleter.js
index 2a23b88..76a9dbb 100644
--- a/trace/FBTrace/chrome/firebug/content/console/autoCompleter.js
+++ b/trace/FBTrace/chrome/firebug/content/console/autoCompleter.js
@@ -10,9 +10,10 @@ define([
"firebug/lib/dom",
"firebug/lib/string",
"firebug/lib/array",
+ "firebug/console/closureInspector",
"firebug/editor/editor"
],
-function(Obj, Firebug, Domplate, Locale, Events, Wrapper, Dom, Str, Arr, Editor) {
+function(Obj, Firebug, Domplate, Locale, Events, Wrapper, Dom, Str, Arr, ClosureInspector, Editor) {
// ********************************************************************************************* //
// Constants
@@ -89,6 +90,15 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
};
/**
+ * Completely reset the auto-completer.
+ */
+ this.reset = function()
+ {
+ this.hide();
+ this.revertValue = null;
+ };
+
+ /**
* Hide completions for this expression (/completion base). Appending further
* characters to the variable name will not make completions appear, but
* adding, say, a semicolon and typing something else will.
@@ -812,6 +822,7 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
try
{
this.completionPopup.hidePopup();
+ this.selectedPopupElement = null;
}
catch (err)
{
@@ -890,6 +901,54 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
}
};
+/**
+ * Transform expressions that use .% into more JavaScript-friendly function calls.
+ * (This is unrelated to the auto-completer, but autoCompleter.js has so many nice
+ * helper functions.)
+ */
+Firebug.JSAutoCompleter.transformScopeOperator = function(expr, fname)
+{
+ var sexpr = simplifyExpr(expr);
+ if (!sexpr)
+ return expr;
+ var search = 0;
+ for (;;)
+ {
+ // Find the next occurrance of .%.
+ var end = sexpr.indexOf(".%", search);
+ if (end === -1)
+ break;
+
+ var start = getExpressionOffset(sexpr, end);
+ if (/^-?[0-9]*$/.test(expr.substring(start, end)))
+ {
+ // False alarm - the operator was actually a number and the modulo operator.
+ search = end + 1;
+ }
+ else
+ {
+ // Substitute "expr.%prop" with "scopeGetter(expr).prop", or, if used
+ // in a "new" expression, "(scopeGetter(expr)).prop" (so that the scope
+ // getter isn't used as a constructor). We don't want to use the first
+ // thing unconditionally though, because it messes with ASI.
+ var newPos = (start === 0 ? -1 : sexpr.lastIndexOf("new", start-1));
+ var hasNew = (newPos !== -1 && !/[a-zA-Z0-9_$.]/.test(sexpr.charAt(newPos-1)) &&
+ sexpr.substring(newPos + 3, start).trim() === "");
+ var subst = function(expr)
+ {
+ return expr.substr(0, start) + (hasNew ? "(" : "") + fname + "(" +
+ expr.substring(start, end) + ")" + (hasNew ? ")" : "") + "." +
+ expr.substr(end+2);
+ };
+ expr = subst(expr);
+ sexpr = subst(sexpr);
+
+ search = end + fname.length + (hasNew ? 5 : 3); // |(()).| or |().|
+ }
+ }
+ return expr;
+};
+
// ********************************************************************************************* //
/**
@@ -955,7 +1014,7 @@ function EditorJSAutoCompleter(box, completionBox, options)
var ac = new Firebug.JSAutoCompleter(box, completionBox, options);
this.destroy = Obj.bindFixed(ac.shutdown, ac);
- this.reset = Obj.bindFixed(ac.hide, ac);
+ this.reset = Obj.bindFixed(ac.reset, ac);
this.complete = Obj.bind(ac.complete, ac);
this.handleKeyPress = Obj.bind(ac.handleKeyPress, ac);
}
@@ -966,15 +1025,16 @@ function EditorJSAutoCompleter(box, completionBox, options)
/**
* Try to find the position at which the expression to be completed starts.
*/
-function getExpressionOffset(command)
+function getExpressionOffset(command, start)
{
- var bracketCount = 0;
+ if (typeof start === 'undefined')
+ start = command.length;
- var start = command.length, instr = false;
+ var bracketCount = 0, instr = false;
// When completing []-accessed properties, start instead from the last [.
- var lastBr = command.lastIndexOf("[");
- if (lastBr !== -1 && /^" *$/.test(command.substr(lastBr+1)))
+ var lastBr = command.lastIndexOf("[", start);
+ if (lastBr !== -1 && /^" *$/.test(command.substring(lastBr+1, start)))
start = lastBr;
for (var i = start-1; i >= 0; --i)
@@ -998,7 +1058,10 @@ function getExpressionOffset(command)
else if (bracketCount === 0)
{
if (c === '"') instr = !instr;
- else if (!instr && !reJSChar.test(c) && c !== ".")
+ else if (instr || reJSChar.test(c) || c === "." ||
+ (c === "%" && command[i-1] === "."))
+ ;
+ else
break;
}
}
@@ -1006,7 +1069,8 @@ function getExpressionOffset(command)
// The 'new' operator has higher precedence than function calls, so, if
// present, it should be included if the expression contains a parenthesis.
- if (i-4 >= 0 && command.indexOf("(", i) !== -1 && command.substr(i-4, 4) === "new ")
+ var ind = command.indexOf("(", i+1);
+ if (i-4 >= 0 && ind !== -1 && ind < start && command.substr(i-4, 4) === "new ")
{
i -= 4;
}
@@ -1025,10 +1089,10 @@ function getPropertyOffset(expr)
return lastBr+2;
var lastDot = expr.lastIndexOf(".");
- if (lastDot !== -1)
- return lastDot+1;
+ if (lastDot !== -1 && expr.charAt(lastDot+1) === "%")
+ return lastDot+2;
- return 0;
+ return (lastDot === -1 ? 0 : lastDot+1);
}
/**
@@ -1258,7 +1322,8 @@ function killCompletions(expr, origExpr)
return true;
if (reJSChar.test(expr[expr.length-1]) ||
- expr[expr.length-1] === ".")
+ expr.slice(-1) === "." ||
+ expr.slice(-2) === ".%")
{
// An expression at the end - we're fine.
}
@@ -1516,9 +1581,10 @@ var AutoCompletionKnownTypes = {
var LinkType = {
"PROPERTY": 0,
- "INDEX": 1,
- "CALL": 2,
- "RETVAL_HEURISTIC": 3
+ "SCOPED_VARS": 1,
+ "INDEX": 2,
+ "CALL": 3,
+ "RETVAL_HEURISTIC": 4
};
function getKnownType(t)
@@ -1643,7 +1709,9 @@ function propertiesToHide(expr, obj)
);
// Hide ourselves.
- ret.push("_FirebugCommandLine", "_firebug");
+ ret.push("_FirebugCommandLine", "_firebug",
+ "_firebugUnwrappedDebuggerObject", "__fb_scopedVars"
+ );
}
// Old and ugly.
@@ -1658,7 +1726,6 @@ function propertiesToHide(expr, obj)
return ret;
}
-
function setCompletionsFromObject(out, object, context)
{
// 'object' is a user-level, non-null object.
@@ -1671,7 +1738,7 @@ function setCompletionsFromObject(out, object, context)
// to cross-window properties, nor just '!Object.getPrototypeOf(obj)'
// because of Object.create.
return !Object.getPrototypeOf(obj) && "hasOwnProperty" in obj;
- }
+ };
var obj = object;
while (obj !== null)
@@ -1716,12 +1783,36 @@ function setCompletionsFromObject(out, object, context)
catch (exc)
{
if (FBTrace.DBG_COMMANDLINE)
- FBTrace.sysout("autoCompleter.getCompletionsFromPrototypeChain failed", exc);
+ FBTrace.sysout("autoCompleter.setCompletionsFromObject failed", exc);
+ }
+}
+
+function setCompletionsFromScope(out, object, context)
+{
+ out.completions = ClosureInspector.getClosureVariablesList(object, context);
+
+ // Hide "arguments"; it almost never holds a value.
+ out.completions = Arr.unique(out.completions);
+ var ind = out.completions.indexOf("arguments");
+ if (ind !== -1)
+ {
+ out.completions.splice(ind, 1);
+ out.hiddenCompletions.push("arguments");
}
}
function propChainBuildComplete(out, context, tempExpr, result)
{
+ if (out.scopeCompletion)
+ {
+ if (tempExpr.fake)
+ return;
+ if (typeof result !== "object" && typeof result !== "function")
+ return;
+ setCompletionsFromScope(out, result, context);
+ return;
+ }
+
var done = function(result)
{
if (result !== undefined && result !== null)
@@ -1786,6 +1877,10 @@ function evalPropChainStep(step, tempExpr, evalChain, out, context)
else
return;
}
+ else
+ {
+ return;
+ }
evalPropChainStep(step+1, tempExpr, evalChain, out, context);
}
else
@@ -1800,6 +1895,11 @@ function evalPropChainStep(step, tempExpr, evalChain, out, context)
tempExpr.thisCommand = tempExpr.command;
tempExpr.command += "." + link.name;
}
+ else if (type === LinkType.SCOPED_VARS)
+ {
+ tempExpr.thisCommand = "window";
+ tempExpr.command += ".%" + link.name;
+ }
else if (type === LinkType.INDEX)
{
tempExpr.thisCommand = "window";
@@ -1986,10 +2086,15 @@ function evalPropChain(out, preExpr, origExpr, context)
if (ch === ".")
{
// Property access
- var nextLink = eatProp(preExpr, linkStart+1);
- lastProp = preExpr.substring(linkStart+1, nextLink);
+ var scope = (preExpr.charAt(linkStart+1) === "%");
+ linkStart += (scope ? 2 : 1);
+ var nextLink = eatProp(preExpr, linkStart);
+ lastProp = preExpr.substring(linkStart, nextLink);
linkStart = nextLink;
- evalChain.push({"type": LinkType.PROPERTY, "name": lastProp});
+ evalChain.push({
+ "type": (scope ? LinkType.SCOPED_VARS : LinkType.PROPERTY),
+ "name": lastProp
+ });
}
else if (ch === "(")
{
@@ -2043,7 +2148,7 @@ function autoCompleteEval(context, preExpr, spreExpr, includeCurrentScope)
spreExpr: spreExpr,
completions: [],
hiddenCompletions: [],
- window: context.baseWindow || context.window
+ window: context.stoppedGlobal || context.baseWindow || context.window
};
var indexCompletion = false;
@@ -2055,24 +2160,25 @@ function autoCompleteEval(context, preExpr, spreExpr, includeCurrentScope)
// In case of array indexing, remove the bracket and set a flag to
// escape completions.
+ out.scopeCompletion = false;
var len = spreExpr.length;
if (len >= 2 && spreExpr[len-2] === "[" && spreExpr[len-1] === '"')
{
indexCompletion = true;
out.indexQuoteType = preExpr[len-1];
- spreExpr = spreExpr.substr(0, len-2);
- preExpr = preExpr.substr(0, len-2);
+ len -= 2;
+ }
+ else if (spreExpr.slice(-2) === ".%")
+ {
+ out.scopeCompletion = true;
+ len -= 2;
}
else
{
- // Remove the trailing dot (if there is one)
- var lastDot = spreExpr.lastIndexOf(".");
- if (lastDot !== -1)
- {
- spreExpr = spreExpr.substr(0, lastDot);
- preExpr = preExpr.substr(0, lastDot);
- }
+ len -= 1;
}
+ spreExpr = spreExpr.substr(0, len);
+ preExpr = preExpr.substr(0, len);
if (FBTrace.DBG_COMMANDLINE)
FBTrace.sysout("commandLine.autoCompleteEval pre:'" + preExpr +
@@ -2105,9 +2211,9 @@ function autoCompleteEval(context, preExpr, spreExpr, includeCurrentScope)
}
}
- // Add "] to properties if we are doing index-completions.
if (indexCompletion)
{
+ // If we are doing index-completions, add "] to everything.
function convertQuotes(x)
{
x = (out.indexQuoteType === '"') ? Str.escapeJS(x): Str.escapeSingleQuoteJS(x);
@@ -2116,15 +2222,15 @@ function autoCompleteEval(context, preExpr, spreExpr, includeCurrentScope)
out.completions = out.completions.map(convertQuotes);
out.hiddenCompletions = out.hiddenCompletions.map(convertQuotes);
}
-
- // Remove numeric keys.
- var rePositiveNumber = /^[1-9][0-9]*$/;
- var nonNumeric = function(x)
+ else if (out.completions.indexOf("length") !== -1 && out.completions.indexOf("0") !== -1)
{
- return x !== '0' && !rePositiveNumber.test(x);
+ // ... otherwise remove numeric keys from array-like things.
+ var rePositiveNumber = /^[1-9][0-9]*$/;
+ out.completions = out.completions.filter(function(x)
+ {
+ return !rePositiveNumber.test(x) && x !== "0";
+ });
}
- out.completions = out.completions.filter(nonNumeric);
- out.hiddenCompletions = out.hiddenCompletions.filter(nonNumeric);
// Sort the completions, and avoid duplicates.
// XXX: If we make it possible to show both regular and hidden completions
diff --git a/trace/FBTrace/chrome/firebug/content/console/closureInspector.js b/trace/FBTrace/chrome/firebug/content/console/closureInspector.js
new file mode 100644
index 0000000..84309f2
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/console/closureInspector.js
@@ -0,0 +1,505 @@
+/* See license.txt for terms of usage */
+/*jshint esnext:true, es5:true, curly:false */
+/*global FBTrace:true, Components:true, Proxy:true, define:true */
+
+// A note on terminology: here a "closure"/"environment" is generally thought
+// of as a container of "scopes".
+
+define([
+ "firebug/firebug",
+ "firebug/lib/wrapper"
+],
+function(Firebug, Wrapper) {
+"use strict";
+
+// ********************************************************************************************* //
+// Constants
+
+const Cu = Components.utils;
+
+const ScopeProxy = function() {};
+const OptimizedAway = Object.create(null);
+Object.freeze(OptimizedAway);
+
+// ********************************************************************************************* //
+
+var ClosureInspector =
+{
+ hasInit: false,
+ Debugger: null,
+ debuggeeCache: new WeakMap(),
+
+ getInactiveDebuggerForContext: function(context)
+ {
+ if (context.inactiveDebugger)
+ return context.inactiveDebugger;
+
+ if (!this.hasInit)
+ {
+ this.hasInit = true;
+ try
+ {
+ Cu.import("resource://gre/modules/jsdebugger.jsm");
+ window.addDebuggerToGlobal(window);
+ this.Debugger = window.Debugger;
+ }
+ catch (exc)
+ {
+ if (FBTrace.DBG_COMMANDLINE)
+ FBTrace.sysout("ClosureInspector; Debugger not found", exc);
+ }
+ }
+ if (!this.Debugger)
+ return;
+
+ var dbg = new this.Debugger();
+ dbg.enabled = false;
+ context.inactiveDebugger = dbg;
+ return dbg;
+ },
+
+ getDebuggeeObject: function(context, global)
+ {
+ var dbg = this.getInactiveDebuggerForContext(context);
+
+ // Because (outer) windows persist between reloads, use their documents
+ // as keys into the cache instead.
+ var cacheKey = global.document || global;
+
+ var dglobal = this.debuggeeCache.get(cacheKey);
+ if (dglobal)
+ return dglobal;
+
+ // Note: for no purposes is it actually important that the global is
+ // held as a debuggee; it just makes things slower.
+ dglobal = dbg.addDebuggee(global);
+ dbg.removeDebuggee(global);
+
+ this.debuggeeCache.set(cacheKey, dglobal);
+ return dglobal;
+ },
+
+ getVariableOrOptimizedAway: function(scope, name)
+ {
+ try
+ {
+ var ret = scope.getVariable(name);
+ if (ret !== undefined)
+ return ret;
+
+ if (scope.type === "declarative")
+ {
+ // The variable is either optimized away or actually set to
+ // undefined. Optimized-away ones are apparently not settable,
+ // so try to detect them by that (it seems rather safe).
+ scope.setVariable(name, 0);
+ if (scope.getVariable(name) === undefined)
+ return OptimizedAway;
+ scope.setVariable(name, undefined);
+ }
+
+ return undefined;
+ }
+ catch (exc)
+ {
+ // E.g. optimized-away "arguments" can throw "Debugger scope is not live".
+ if (FBTrace.DBG_COMMANDLINE)
+ FBTrace.sysout("ClosureInspector; getVariableOrOptimizedAway caught an exception", exc);
+ return OptimizedAway;
+ }
+ },
+
+ isOptimizedAway: function(obj)
+ {
+ return obj === OptimizedAway;
+ },
+
+ isSimple: function(dobj)
+ {
+ return (typeof dobj !== "object" || dobj === OptimizedAway);
+ },
+
+ unwrap: function(global, dglobal, obj)
+ {
+ dglobal.defineProperty("_firebugUnwrappedDebuggerObject", {
+ value: obj,
+ writable: true,
+ configurable: true
+ });
+ return global._firebugUnwrappedDebuggerObject;
+ },
+
+ isScopeInteresting: function(scope)
+ {
+ return !!scope.parent;
+ },
+
+ getFunctionFromObject: function(obj)
+ {
+ var first = true;
+ while (obj)
+ {
+ var names = obj.getOwnPropertyNames(), pd;
+
+ // "constructor" is boring, use it last
+ var ind = names.indexOf("constructor");
+ if (ind !== -1)
+ {
+ names.splice(ind, 1);
+ names.push("constructor");
+ }
+
+ for (var i = 0; i < names.length; ++i)
+ {
+ // We assume that the first own property, or the first
+ // enumerable property of the prototype (or "constructor"),
+ // that is a function with some scope (i.e., it is interpreted,
+ // JSScript-backed, and without optimized-away scope) shares
+ // this scope with 'obj'.
+ // (Since, in the current implementation, Firefox seems to give
+ // all functions in a particular scope (except self-contained
+ // ones) the same environment, the first is as good as any,
+ // and it's probably near the definition of 'obj').
+
+ var name = names[i];
+ try
+ {
+ pd = obj.getOwnPropertyDescriptor(name);
+ }
+ catch (e)
+ {
+ // getOwnPropertyDescriptor sometimes fails with
+ // "Illegal operation on WrappedNative prototype object",
+ // for instance on [window].proto.gopd("localStorage").
+ continue;
+ }
+ if (!pd || (!first && !pd.enumerable && name !== "constructor"))
+ continue;
+
+ var toTest = [pd.get, pd.set, pd.value];
+ for (var j = 0; j < toTest.length; ++j)
+ {
+ var f = toTest[j];
+ if (f && f.environment && this.isScopeInteresting(f.environment))
+ return f;
+ }
+ }
+
+ if (!first)
+ break;
+ first = false;
+ obj = obj.proto;
+ }
+
+ // None found. :(
+ return undefined;
+ },
+
+ // Within the security context of the (wrapped) window 'win', find a relevant
+ // closure for the content object 'obj' (may be from another frame).
+ // Throws exceptions on error.
+ getEnvironmentForObject: function(win, obj, context)
+ {
+ var dbg = this.getInactiveDebuggerForContext(context);
+ if (!dbg)
+ throw new Error("debugger not available");
+
+ if (!obj || !(typeof obj === "object" || typeof obj === "function"))
+ throw new TypeError("can't get scope of non-object");
+
+ var objGlobal = Cu.getGlobalForObject(obj);
+ if (win !== objGlobal && !(win.document && objGlobal.document &&
+ win.document.nodePrincipal.subsumes(objGlobal.document.nodePrincipal)))
+ {
+ throw new Error("permission denied to access cross origin scope");
+ }
+
+ // Create a view of the object as seen from its own global - 'environment'
+ // will not be accessible otherwise.
+ var dglobal = this.getDebuggeeObject(context, objGlobal);
+
+ var dobj = dglobal.makeDebuggeeValue(obj);
+
+ if (typeof obj === "object")
+ dobj = this.getFunctionFromObject(dobj);
+
+ if (!dobj || !dobj.environment || !this.isScopeInteresting(dobj.environment))
+ throw new Error("missing closure");
+
+ return dobj.environment;
+ },
+
+ getClosureVariablesList: function(obj, context)
+ {
+ var ret = [];
+
+ // Avoid 'window' and 'document' getting associated with closures.
+ var win = context.stoppedGlobal || context.baseWindow || context.window;
+ if (obj === win || obj === win.document)
+ return ret;
+
+ try
+ {
+ var env = this.getEnvironmentForObject(win, obj, context);
+ for (var scope = env; scope; scope = scope.parent)
+ {
+ if (scope.type === "with" && scope.getVariable("profileEnd"))
+ {
+ // Almost certainly the with(_FirebugCommandLine) block,
+ // which is at the top of the scope chain on objects
+ // defined through the console. Hide it for a nicer display.
+ break;
+ }
+ if (!this.isScopeInteresting(scope))
+ break;
+
+ ret.push.apply(ret, scope.names());
+ }
+ }
+ catch (exc)
+ {
+ if (FBTrace.DBG_COMMANDLINE)
+ FBTrace.sysout("ClosureInspector; getClosureVariablesList failed", exc);
+ }
+ return ret;
+ },
+
+ getClosureWrapper: function(obj, win, context)
+ {
+ function throwUserError(exc)
+ {
+ // Throw an exception into user-land, where we hope it lands
+ // safely in commandLineExposed.js for internals to be hidden.
+ exc._dropFrames = true;
+ throw exc;
+ }
+
+ var env, dglobal;
+ try
+ {
+ env = this.getEnvironmentForObject(win, obj, context);
+
+ dglobal = this.getDebuggeeObject(context, win);
+ }
+ catch (exc)
+ {
+ throwUserError(exc);
+ }
+
+ // Return a wrapper for its scoped variables.
+ var self = this;
+ var handler = {};
+ handler.getOwnPropertyDescriptor = function(name)
+ {
+ if (name === "__exposedProps__")
+ {
+ // Expose mostly everything, rw, through another proxy.
+ return {
+ value: Proxy.create({
+ getPropertyDescriptor: function(name)
+ {
+ if (name === "__exposedProps__" || name === "__proto__")
+ return;
+ return {value: "rw", enumerable: true};
+ }
+ })
+ };
+ }
+
+ return {
+ get: function()
+ {
+ try
+ {
+ var scope = env.find(name);
+ if (!scope)
+ return undefined;
+ var dval = self.getVariableOrOptimizedAway(scope, name);
+ if (self.isSimple(dval))
+ return dval;
+ var uwWin = Wrapper.getContentView(win);
+ return self.unwrap(uwWin, dglobal, dval);
+ }
+ catch (exc)
+ {
+ if (FBTrace.DBG_COMMANDLINE)
+ FBTrace.sysout("ClosureInspector; failed to return value from getter", exc);
+ return undefined;
+ }
+ },
+
+ set: function(value)
+ {
+ var dvalue = dglobal.makeDebuggeeValue(value);
+ var scope = env.find(name);
+ if (!scope)
+ throwUserError(new Error("can't create new closure variable"));
+ if (self.getVariableOrOptimizedAway(scope, name) === OptimizedAway)
+ throwUserError(new Error("can't set optimized-away closure variable"));
+ scope.setVariable(name, dvalue);
+ }
+ };
+ };
+ handler.getPropertyDescriptor = handler.getOwnPropertyDescriptor;
+ handler.delete = function(name)
+ {
+ throwUserError(new Error("can't delete closure variable"));
+ };
+ // Other traps are syntactically inaccessible, so we don't need to implement them.
+ return Proxy.create(handler);
+ },
+
+ getScopeWrapper: function(obj, win, context, isScope)
+ {
+ var scope;
+ try
+ {
+ if (isScope)
+ scope = Object.getPrototypeOf(obj).scope.parent;
+ else
+ scope = this.getEnvironmentForObject(win, obj, context);
+ if (!scope || !this.isScopeInteresting(scope))
+ return;
+ }
+ catch (exc)
+ {
+ if (FBTrace.DBG_COMMANDLINE)
+ FBTrace.sysout("ClosureInspector; getScopeWrapper failed", exc);
+ return;
+ }
+
+ var dwin = this.getDebuggeeObject(context, win);
+
+ var scopeDataHolder = Object.create(ScopeProxy.prototype);
+ scopeDataHolder.scope = scope;
+
+ var self = this;
+ var names, namesSet;
+ var lazyCreateNames = function()
+ {
+ lazyCreateNames = function() {};
+ names = scope.names();
+
+ // Due to weird Firefox behavior, we sometimes have to skip over duplicate
+ // scopes (see issue 6184).
+ if (names.length === 1 && scope.type === "declarative" &&
+ scope.parent && scope.parent.type === "declarative")
+ {
+ var par = scope.parent, parNames = par.names();
+ if (parNames.length === 1 && parNames[0] === names[0])
+ scopeDataHolder.scope = scope = par;
+ }
+
+ // "arguments" is almost always present and optimized away, so hide it
+ // for a nicer display.
+ var ind = names.indexOf("arguments");
+ if (ind !== -1 && self.getVariableOrOptimizedAway(scope, "arguments") === OptimizedAway)
+ names.splice(ind, 1);
+
+ namesSet = new Set();
+ for (var i = 0; i < names.length; ++i)
+ namesSet.add(names[i]);
+ };
+
+ return Proxy.create({
+ desc: function(name)
+ {
+ if (!this.has(name))
+ return;
+ var dval = self.getVariableOrOptimizedAway(scope, name);
+ return {
+ get: function() {
+ if (self.isSimple(dval))
+ return dval;
+ var uwWin = Wrapper.getContentView(win);
+ return self.unwrap(uwWin, dwin, dval);
+ },
+ set: (dval === OptimizedAway ? undefined : function(value) {
+ dval = dwin.makeDebuggeeValue(value);
+ scope.setVariable(name, dval);
+ }),
+ enumerable: true,
+ configurable: false
+ };
+ },
+ has: function(name)
+ {
+ lazyCreateNames();
+ return namesSet.has(name);
+ },
+ hasOwn: function(name) { return this.has(name); },
+ getOwnPropertyDescriptor: function(name) { return this.desc(name); },
+ getPropertyDescriptor: function(name) { return this.desc(name); },
+ keys: function()
+ {
+ lazyCreateNames();
+ return names;
+ },
+ enumerate: function() { return this.keys(); },
+ getOwnPropertyNames: function() { return this.keys(); },
+ getPropertyNames: function() { return this.keys(); }
+ }, scopeDataHolder);
+ },
+
+ isScopeWrapper: function(obj)
+ {
+ return obj instanceof ScopeProxy;
+ },
+
+ getScopeFromWrapper: function(obj)
+ {
+ return Object.getPrototypeOf(obj).scope;
+ },
+
+ extendLanguageSyntax: function(expr, win, context)
+ {
+ // Temporary FireClosure compatibility.
+ if (Firebug.JSAutoCompleter.transformScopeExpr)
+ return expr;
+
+ // Note: this is also hard-coded elsewhere.
+ var fname = "__fb_scopedVars";
+
+ var newExpr = Firebug.JSAutoCompleter.transformScopeOperator(expr, fname);
+ if (expr === newExpr)
+ return expr;
+
+ if (FBTrace.DBG_COMMANDLINE)
+ {
+ FBTrace.sysout("ClosureInspector; transforming expression: `" +
+ expr + "` -> `" + newExpr + "`");
+ }
+
+ // Stick the helper function for .%-expressions on the window object.
+ // This really belongs on the command line object, but that doesn't
+ // work when stopped in the debugger (issue 5321, which depends on
+ // integrating JSD2) and we really need this to work there.
+ // To avoid leaking capabilities into arbitrary web pages, this is
+ // only injected when needed.
+ try
+ {
+ var self = this;
+ Object.defineProperty(Wrapper.getContentView(win), fname, {
+ value: function(obj)
+ {
+ return self.getClosureWrapper(obj, win, context);
+ },
+ writable: true,
+ configurable: true
+ });
+ }
+ catch (exc)
+ {
+ if (FBTrace.DBG_COMMANDLINE)
+ FBTrace.sysout("ClosureInspector; failed to inject " + fname, exc);
+ }
+
+ return newExpr;
+ }
+};
+
+Firebug.ClosureInspector = ClosureInspector;
+return ClosureInspector;
+
+// ********************************************************************************************* //
+});
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandLine.js b/trace/FBTrace/chrome/firebug/content/console/commandLine.js
index d0dada8..6df9c06 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandLine.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandLine.js
@@ -23,12 +23,13 @@ define([
"firebug/console/commandLineHelp",
"firebug/console/commandLineInclude",
"firebug/console/commandLineExposed",
+ "firebug/console/closureInspector",
"firebug/console/autoCompleter",
"firebug/console/commandHistory"
],
function(Obj, Firebug, FirebugReps, Locale, Events, Wrapper, Url, Css, Dom, Firefox, Win, System,
- Xpath, Str, Xml, Arr, Persist, Keywords, Console, CommandLineHelp,
- CommandLineInclude, CommandLineExposed) {
+ Xpath, Str, Xml, Arr, Persist, Keywords, Console, CommandLineHelp, CommandLineInclude,
+ CommandLineExposed, ClosureInspector) {
// ********************************************************************************************* //
// Constants
@@ -71,32 +72,34 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
}
},
- // returns user-level wrapped object I guess.
evaluate: function(expr, context, thisValue, targetWindow, successConsoleFunction,
exceptionFunction, noStateChange)
{
if (!context)
return;
+ targetWindow = targetWindow || context.stoppedGlobal || context.baseWindow || context.window;
+
try
{
- var result = null;
var debuggerState = Firebug.Debugger.beginInternalOperation();
+ var newExpr = ClosureInspector.extendLanguageSyntax(expr, targetWindow, context);
+
if (this.isSandbox(context))
{
- result = this.evaluateInSandbox(expr, context, thisValue, targetWindow,
- successConsoleFunction, exceptionFunction);
+ this.evaluateInSandbox(newExpr, context, thisValue, targetWindow,
+ successConsoleFunction, exceptionFunction, expr);
}
else if (Firebug.Debugger.hasValidStack(context))
{
- result = this.evaluateInDebugFrame(expr, context, thisValue, targetWindow,
- successConsoleFunction, exceptionFunction);
+ this.evaluateInDebugFrame(newExpr, context, thisValue, targetWindow,
+ successConsoleFunction, exceptionFunction, expr);
}
else
{
- result = this.evaluateByEventPassing(expr, context, thisValue, targetWindow,
- successConsoleFunction, exceptionFunction);
+ this.evaluateByEventPassing(newExpr, context, thisValue, targetWindow,
+ successConsoleFunction, exceptionFunction, expr);
}
if (!noStateChange)
@@ -115,15 +118,12 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
{
Firebug.Debugger.endInternalOperation(debuggerState);
}
-
- return result;
},
evaluateByEventPassing: function(expr, context, thisValue, targetWindow,
- successConsoleFunction, exceptionFunction)
+ successConsoleFunction, exceptionFunction, origExpr)
{
- var win = targetWindow ? targetWindow :
- (context.baseWindow ? context.baseWindow : context.window);
+ var win = targetWindow || context.stoppedGlobal || context.baseWindow || context.window;
if (!win)
{
@@ -177,8 +177,9 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
event.initEvent("firebugCommandLine", true, false);
win.document.setUserData("firebug-methodName", "evaluate", null);
- expr = expr.toString();
+ origExpr = "with(_FirebugCommandLine){\n" + (origExpr || expr) + "\n};";
expr = "with(_FirebugCommandLine){\n" + expr + "\n};";
+ win.document.setUserData("firebug-expr-orig", origExpr, null);
win.document.setUserData("firebug-expr", expr, null);
var consoleHandler = Firebug.Console.injector.getConsoleHandler(context, win);
@@ -256,9 +257,7 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
{
var result = null;
- // targetWindow may be frame in HTML
- var win = targetWindow ? targetWindow :
- (context.baseWindow ? context.baseWindow : context.window);
+ var win = targetWindow || context.stoppedGlobal || context.baseWindow || context.window;
if (!context.commandLineAPI)
context.commandLineAPI = new FirebugCommandLineAPI(context);
@@ -287,9 +286,7 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
evaluateByPostMessage: function(expr, context, thisValue, targetWindow,
successConsoleFunction, exceptionFunction)
{
- // targetWindow may be frame in HTML
- var win = targetWindow ? targetWindow :
- (context.baseWindow ? context.baseWindow : context.window);
+ var win = targetWindow || context.stoppedGlobal || context.baseWindow || context.window;
if (!win)
{
@@ -352,8 +349,8 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
evaluateInWebPage: function(expr, context, targetWindow)
{
- var win = targetWindow ? targetWindow :
- (context.baseWindow ? context.baseWindow : context.window);
+ var win = targetWindow || context.stoppedGlobal || context.baseWindow || context.window;
+
var element = Dom.addScript(win.document, "_firebugInWebPage", expr);
if (!element)
return;
@@ -715,16 +712,27 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
showPanel: function(browser, panel)
{
- if (!Firebug.currentContext)
+ var context = Firebug.currentContext;
+ if (!context)
return;
+ // Warn that FireClosure is integrated and will conflict.
+ if (Firebug.JSAutoCompleter && Firebug.JSAutoCompleter.transformScopeExpr &&
+ !this.hasWarnedAboutFireClosure)
+ {
+ this.hasWarnedAboutFireClosure = true;
+ // Use English because this only reaches ~200 users anyway.
+ var msg = "FireClosure has been integrated into Firebug. To avoid conflicts, please uninstall it and restart your browser.";
+ Firebug.Console.logFormatted([msg], context, "warn");
+ }
+
var chrome = Firebug.chrome;
var panelState = Persist.getPersistedState(this, "console");
if (panelState.commandLineText)
{
var value = panelState.commandLineText;
var commandLine = this.getCommandLine(browser);
- Firebug.currentContext.commandLineText = value;
+ context.commandLineText = value;
commandLine.value = value;
@@ -745,10 +753,8 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
this.setAutoCompleter();
},
- // called by users of command line, currently:
- // 1) Console on focus command line,
- // 2) Watch onfocus, and
- // 3) debugger loadedContext if watches exist
+ // Attach the command line. Currently called by evaluate() et al. and
+ // watch onfocus (see chrome.js; probably unnecessary).
isReadyElsePreparing: function(context, win)
{
if (FBTrace.DBG_COMMANDLINE)
@@ -792,11 +798,6 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
onCommandLineKeyDown: function(event)
{
- // XXX: Temporary hack to make FireClosure work (until that gets a new
- // release out)
- if (!this.autoCompleter.shouldIncludeHint && Firebug.JSAutoCompleter.transformScopeExpr)
- this.setAutoCompleter();
-
var context = Firebug.currentContext;
this.autoCompleter.handleKeyDown(event, context);
@@ -938,7 +939,6 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
{
return Firebug.CommandEditor;
}
-
});
// ********************************************************************************************* //
@@ -1169,25 +1169,33 @@ function FirebugCommandLineAPI(context)
this.traceAll = function()
{
- Firebug.Debugger.traceAll(Firebug.currentContext);
+ // See issue 6220
+ Firebug.Console.log(Locale.$STR("commandline.MethodDisabled"));
+ //Firebug.Debugger.traceAll(Firebug.currentContext);
return Firebug.Console.getDefaultReturnValue(context.window);
};
this.untraceAll = function()
{
- Firebug.Debugger.untraceAll(Firebug.currentContext);
+ // See issue 6220
+ Firebug.Console.log(Locale.$STR("commandline.MethodDisabled"));
+ //Firebug.Debugger.untraceAll(Firebug.currentContext);
return Firebug.Console.getDefaultReturnValue(context.window);
};
this.traceCalls = function(fn)
{
- Firebug.Debugger.traceCalls(Firebug.currentContext, fn);
+ // See issue 6220
+ Firebug.Console.log(Locale.$STR("commandline.MethodDisabled"));
+ //Firebug.Debugger.traceCalls(Firebug.currentContext, fn);
return Firebug.Console.getDefaultReturnValue(context.window);
};
this.untraceCalls = function(fn)
{
- Firebug.Debugger.untraceCalls(Firebug.currentContext, fn);
+ // See issue 6220
+ Firebug.Console.log(Locale.$STR("commandline.MethodDisabled"));
+ //Firebug.Debugger.untraceCalls(Firebug.currentContext, fn);
return Firebug.Console.getDefaultReturnValue(context.window);
};
@@ -1400,8 +1408,8 @@ function CommandLineHandler(context, win)
if (FBTrace.DBG_COMMANDLINE)
{
- FBTrace.sysout("commandLine.handleEvent('firebugExecuteCommand') " +
- "event in context.baseWindow " + context.baseWindow.location, event);
+ FBTrace.sysout("commandLine.handleEvent() " +
+ " window: " + Win.safeGetWindowLocation(win), {win: win, ev: event});
}
// Appends variables into the api.
@@ -1430,15 +1438,6 @@ function CommandLineHandler(context, win)
var methodName = win.document.getUserData("firebug-methodName");
Firebug.Console.log(Locale.$STRF("commandline.MethodNotSupported", [methodName]));
}
-
- if (FBTrace.DBG_COMMANDLINE)
- {
- FBTrace.sysout("commandLine.handleEvent() " +
- win.document.getUserData("firebug-methodName") +
- " context.baseWindow: " +
- (context.baseWindow ? context.baseWindow.location : "no basewindow"),
- context.baseWindow);
- }
};
}
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandLineExposed.js b/trace/FBTrace/chrome/firebug/content/console/commandLineExposed.js
index bc29ef3..adb9f39 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandLineExposed.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandLineExposed.js
@@ -1,10 +1,13 @@
/* See license.txt for terms of usage */
+/*jshint esnext:true, es5:true, curly:false, evil:true */
+/*global Firebug:true, FBTrace:true, Components:true, define:true */
define([
"firebug/lib/wrapper",
"firebug/lib/events",
],
function(Wrapper, Events) {
+"use strict";
// ********************************************************************************************* //
// Command Line APIs
@@ -56,19 +59,19 @@ function createFirebugCommandLine(context, win)
function createCommandHandler(cmd) {
return function() {
return notifyFirebug(arguments, cmd, "firebugExecuteCommand");
- }
+ };
}
function createShortcutHandler(cmd) {
return function() {
return console[cmd].apply(console, arguments);
- }
+ };
}
function createVariableHandler(prop) {
return function() {
return notifyFirebug(arguments, prop, "firebugExecuteCommand");
- }
+ };
}
// Define command line methods
@@ -146,10 +149,7 @@ function createFirebugCommandLine(context, win)
FBTrace.sysout("commandLine.Exposed.attachCommandLine; " + window.location);
if (!contentView.console)
- {
- var console = createFirebugConsole(context, win);
contentView.console = console;
- }
Events.addEventListener(contentView.document, "firebugCommandLine",
firebugEvalEvent, true);
@@ -174,18 +174,20 @@ function createFirebugCommandLine(context, win)
// see commandLine.js
var expr = contentView.document.getUserData("firebug-expr");
- evaluate(expr);
+ var origExpr = contentView.document.getUserData("firebug-expr-orig");
+ evaluate(expr, origExpr);
if (FBTrace.DBG_COMMANDLINE)
FBTrace.sysout("commandLine.Exposed; did evaluate on " + expr);
}
- function evaluate(expr)
+ function evaluate(expr, origExpr)
{
+ var result;
try
{
var line = Components.stack.lineNumber;
- var result = contentView.eval(expr);
+ result = contentView.eval(expr);
// See Issue 5221
//var result = FirebugEvaluate(expr, contentView);
@@ -195,20 +197,40 @@ function createFirebugCommandLine(context, win)
{
// change source and line number of exeptions from commandline code
// create new error since properties of nsIXPCException are not modifiable
- var shouldModify, isXPCException;
- if (exc.filename == Components.stack.filename)
- shouldModify = isXPCException = true;
- else if (exc.fileName == Components.stack.filename)
- shouldModify = true;
+ var shouldModify = false, isXPCException = false, dropFrames = false;
+ var fileName = exc.filename || exc.fileName, lineNumber;
+ if (fileName.lastIndexOf("chrome:", 0) === 0)
+ {
+ if (fileName === Components.stack.filename)
+ {
+ shouldModify = true;
+ if (exc.filename)
+ isXPCException = true;
+ lineNumber = exc.lineNumber;
+ }
+ else if (exc._dropFrames)
+ {
+ dropFrames = true;
+ lineNumber = findLineNumberInExceptionStack(exc.stack);
+ shouldModify = (lineNumber !== null);
+ }
+ }
if (shouldModify)
{
- var result = new Error;
+ result = new Error();
result.stack = null;
result.source = expr;
result.message = exc.message;
- result.lineNumber = exc.lineNumber - line;
- result.fileName = "data:," + encodeURIComponent(expr);
+ result.lineNumber = lineNumber - line;
+
+ // Lie and show the pre-transformed expression instead.
+ result.fileName = "data:," + encodeURIComponent(origExpr);
+
+ // The error message can also contain post-transform details about the
+ // source, but it's harder to lie about. Make it prettier, at least.
+ if (typeof result.message === "string")
+ result.message = result.message.replace(/__fb_scopedVars\(/g, "<get closure>(");
if (!isXPCException)
result.name = exc.name;
@@ -239,15 +261,14 @@ function createFirebugCommandLine(context, win)
if (FBTrace.DBG_COMMANDLINE)
{
FBTrace.sysout("commandLine.Exposed; dispatched event " + methodName + " via " +
- eventID + " with " + objs.length + " user objects, [0]:" +
- commandLine.userObjects[0]);
+ eventID + " with " + objs.length + " user objects", commandLine.userObjects);
}
var result;
- if (contentView.document.getUserData("firebug-retValueType") == "array")
+ if (contentView.document.getUserData("firebug-retValueType") === "array")
result = [];
- if (!result && commandLine.userObjects.length == length + 1)
+ if (!result && commandLine.userObjects.length === length + 1)
return commandLine.userObjects[length];
for (var i=length; i<commandLine.userObjects.length && result; i++)
@@ -257,7 +278,7 @@ function createFirebugCommandLine(context, win)
}
return commandLine;
-};
+}
/* see Issue 5221
// chrome: urls are filtered out by debugger, so we create script with a data url
@@ -268,6 +289,20 @@ script.src = evalFileSrc;
document.documentElement.appendChild(script);
*/
+function findLineNumberInExceptionStack(strStack) {
+ if (typeof strStack !== "string")
+ return null;
+ var stack = strStack.split("\n");
+ var fileName = Components.stack.filename, re = /^.*@(.*):(.*)$/;
+ for (var i = 0; i < stack.length; ++i)
+ {
+ var m = re.exec(stack[i]);
+ if (m && m[1] === fileName)
+ return +m[2];
+ }
+ return null;
+}
+
// ********************************************************************************************* //
// User Commands
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandLineHelp.js b/trace/FBTrace/chrome/firebug/content/console/commandLineHelp.js
index b0e385e..001a452 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandLineHelp.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandLineHelp.js
@@ -9,8 +9,9 @@ define([
"firebug/chrome/window",
"firebug/lib/xpcom",
"firebug/lib/events",
+ "firebug/lib/object",
],
-function(Firebug, Domplate, Locale, Dom, CommandLineExposed, Win, Xpcom, Events) {
+function(Firebug, Domplate, Locale, Dom, CommandLineExposed, Win, Xpcom, Events, Obj) {
with (Domplate) {
// ********************************************************************************************* //
@@ -25,8 +26,10 @@ var CMD_TYPE_PROPERTY = 3;
const prompts = Xpcom.CCSV("@mozilla.org/embedcomp/prompt-service;1", "nsIPromptService");
+var CLOSURE_INSPECTOR_HELP_URL = "https://getfirebug.com/wiki/index.php/Closure_Inspector";
+
// ********************************************************************************************* //
-// Domplates
+// Command Line Help
var HelpCaption = domplate(
{
@@ -128,12 +131,67 @@ var HelpEntry = domplate(
});
// ********************************************************************************************* //
+// Command Line Tips
+
+var TipsCaption = domplate(
+{
+ tag:
+ SPAN({"class": "helpTitle"},
+ SPAN({"class": "helpCaption"},
+ Locale.$STR("console.cmd.tip_title")
+ ),
+ SPAN({"class": "helpCaptionDesc"},
+ Locale.$STR("console.cmd.tip_title_desc")
+ )
+ )
+});
+
+var TipsList = domplate(
+{
+ tag:
+ DIV({"class": "tipsContent"},
+ UL({"class": "tipsList"})
+ )
+});
+
+var Tip = domplate(
+{
+ loop:
+ FOR("tip", "$tips",
+ TAG("$tag", "$tip")
+ ),
+
+ tag:
+ LI({"class": "tip"},
+ SPAN({"class": "text"}, "$tip|getText"),
+ SPAN(" "),
+ SPAN({"class": "example"},"$tip|getExample")
+ ),
+
+ getText: function(object)
+ {
+ return object.nol10n ? object.text : Locale.$STR(object.text);
+ },
+
+ getExample: function(object)
+ {
+ return object.example;
+ }
+});
+
+// ********************************************************************************************* //
// Help Object
var CommandLineHelp = domplate(
{
render: function(context)
{
+ this.renderHelp(context);
+ this.renderTips(context);
+ },
+
+ renderHelp: function(context)
+ {
var row = Firebug.Console.openGroup("help", context, "help",
HelpCaption, true, null, true);
Firebug.Console.closeGroup(context, true);
@@ -144,11 +202,18 @@ var CommandLineHelp = domplate(
var commands = [];
+ var ignore = ["traceCalls", "untraceCalls", "traceAll", "untraceAll"];
for (var i=0; i<CommandLineExposed.commands.length; i++)
{
+ var cmd = CommandLineExposed.commands[i];
+
+ // See Issue 5221
+ if (ignore.indexOf(cmd) >= 0)
+ continue;
+
commands.push({
- name: CommandLineExposed.commands[i],
- desc: "console.cmd.help." + CommandLineExposed.commands[i],
+ name: cmd,
+ desc: "console.cmd.help." + cmd,
type: CMD_TYPE_COMMAND,
})
}
@@ -189,8 +254,39 @@ var CommandLineHelp = domplate(
// Generate table
HelpEntry.tag.insertRows({commands: commands}, tBody);
+ },
+
+ renderTips: function(context)
+ {
+ var row = Firebug.Console.openGroup("help", context, "help",
+ TipsCaption, true, null, true);
+ Firebug.Console.closeGroup(context, true);
+
+ var logGroupBody = row.lastChild;
+ var table = TipsList.tag.replace({}, logGroupBody);
+ var list = table.lastChild;
+
+ // #1) Render basic command line syntaxt tip
+ var tip = {
+ example: "1 + 1",
+ text: "console.cmd.tip.javascript"
+ };
+ Tip.tag.append({tip: tip}, list);
+
+ // #2) Render closure syntax tip
+ tip = {
+ example: "myObject.%closureVarName",
+ text: "console.cmd.tip.closures"
+ };
+
+ function onClickLink()
+ {
+ Win.openNewTab(CLOSURE_INSPECTOR_HELP_URL);
+ }
- return row;
+ var node = Tip.tag.append({tip: tip}, list);
+ var textNode = node.getElementsByClassName("text").item(0);
+ FirebugReps.Description.render(Locale.$STR(tip.text), textNode, onClickLink);
}
});
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandLineInclude.js b/trace/FBTrace/chrome/firebug/content/console/commandLineInclude.js
index c5489b1..cffee45 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandLineInclude.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandLineInclude.js
@@ -124,14 +124,14 @@ var CommandLineIncludeRep = domplate(FirebugReps.Table,
// NOTE: that piece of code has not been tested since deleting aliases through the table
// has been disabled.
// Once it is enabled again, make sure FBTests is available for this feature
- var store = CommandLine.getStore();
- if (! Options.get(removeConfirmation))
+ var store = CommandLineInclude.getStore();
+ if (!Options.get(removeConfirmation))
{
var check = {value: false};
var flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_YES +
prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_NO;
- if (prompts.confirmEx(context.chrome.window, Locale.$STR("Firebug"),
+ if (prompts.confirmEx(context.chrome.window, Locale.$STR("Firebug"),
Locale.$STR("commandline.include.confirmDelete"), flags, "", "", "",
Locale.$STR("Do_not_show_this_message_again"), check) > 0)
{
@@ -304,9 +304,9 @@ function CommandLineIncludeObject()
// ********************************************************************************************* //
-var CommandLineInclude =
+var CommandLineInclude = Obj.extend(Firebug.Module,
{
- onSuccess: function(newAlias, context, loadingMsgRow, xhr)
+ onSuccess: function(newAlias, context, loadingMsgRow, xhr, hasWarnings)
{
var urlComponent = xhr.channel.URI.QueryInterface(Ci.nsIURL);
var filename = urlComponent.fileName, url = urlComponent.spec;
@@ -320,7 +320,8 @@ var CommandLineInclude =
this.log("aliasCreated", [newAlias], [context, "info"]);
}
- this.log("includeSuccess", [filename], [context, "info", true]);
+ if (!hasWarnings)
+ this.log("includeSuccess", [filename], [context, "info", true]);
},
onError: function(context, url, loadingMsgRow)
@@ -339,6 +340,14 @@ var CommandLineInclude =
{
if (!this.store)
this.store = storageScope.StorageService.getStorage("includeAliases.json");
+
+ // let's log when the store could not be opened:
+ if (!this.store)
+ {
+ if (FBTrace.DBG_COMMANDLINE)
+ FBTrace.sysout("CommandLineInclude.getStore; can't open or create the store");
+ }
+
return this.store;
},
@@ -432,9 +441,19 @@ var CommandLineInclude =
if (xhr.status !== 200)
return errorFunction.apply(this, arguments);
var codeToEval = xhr.responseText;
+ var hasWarnings = false;
+
+ // test if the content is an HTML file, which is the most current after a mistake
+ if (!isValidJS(codeToEval))
+ {
+ CommandLineInclude.log("invalidSyntax", [], [context, "warn"]);
+ CommandLineInclude.clearLoadingMessage(loadingMsgRow);
+ hasWarnings = true;
+ }
+
Firebug.CommandLine.evaluateInWebPage(codeToEval, context);
if (successFunction)
- successFunction(xhr);
+ successFunction(xhr, hasWarnings);
}
if (errorFunction)
@@ -467,8 +486,18 @@ var CommandLineInclude =
xhr.send(null);
// xxxFlorent: TODO show XHR progress
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Module events:
+
+ resetAllOptions: function()
+ {
+ var store = this.getStore();
+ if (store)
+ store.clear(true);
}
-};
+});
// ********************************************************************************************* //
// Command Handler
@@ -525,6 +554,22 @@ IncludeEditor.prototype = domplate(Firebug.InlineEditor.prototype,
}
});
+function isValidJS(codeToCheck)
+{
+ try
+ {
+ new Function(codeToCheck);
+ return true;
+ }
+ catch(ex)
+ {
+ if (ex instanceof SyntaxError)
+ return false;
+ else
+ throw ex;
+ }
+};
+
// ********************************************************************************************* //
// Registration
@@ -536,6 +581,8 @@ Firebug.registerCommand("include", {
Firebug.registerRep(CommandLineIncludeRep);
+Firebug.registerModule(CommandLineInclude);
+
return CommandLineInclude;
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/console/consolePanel.js b/trace/FBTrace/chrome/firebug/content/console/consolePanel.js
index 20778b8..08ce40f 100644
--- a/trace/FBTrace/chrome/firebug/content/console/consolePanel.js
+++ b/trace/FBTrace/chrome/firebug/content/console/consolePanel.js
@@ -579,13 +579,14 @@ Firebug.ConsolePanel.prototype = Obj.extend(Firebug.ActivablePanel,
var part = parts[i];
if (part && typeof(part) == "object")
{
- var object = objects[objIndex++];
+ var object = objects[objIndex];
if (part.type == "%c")
lastStyle = object.toString();
- else if (typeof(object) != "undefined")
+ else if (objIndex < objects.length)
node = this.appendObject(object, row, part.rep);
else
node = this.appendObject(part.type, row, FirebugReps.Text);
+ objIndex++;
}
else
{
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/breakpoints.js b/trace/FBTrace/chrome/firebug/content/cookies/breakpoints.js
index 31ee9d6..9396cac 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/breakpoints.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/breakpoints.js
@@ -349,11 +349,13 @@ Breakpoints.Breakpoint.prototype =
"; with (scope) { return " + this.condition + ";}})();"
// Evaluate condition using Firebug's command line.
- var rc = Firebug.CommandLine.evaluate(expr, context, null, context.window,
+ Firebug.CommandLine.evaluate(expr, context, null, context.window,
this.onEvaluateSucceeds, this.onEvaluateFails);
if (FBTrace.DBG_COOKIES)
- FBTrace.sysout("cookies.evaluateCondition; rc " + rc, {expr: expr, scope: scope});
+ {
+ FBTrace.sysout("cookies.evaluateCondition", {expr: expr, scope: scope});
+ }
return !!context.breakingCause;
}
diff --git a/trace/FBTrace/chrome/firebug/content/css/cssPanel.js b/trace/FBTrace/chrome/firebug/content/css/cssPanel.js
index 89e1f29..90f70a0 100644
--- a/trace/FBTrace/chrome/firebug/content/css/cssPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/css/cssPanel.js
@@ -83,8 +83,8 @@ var CSSPropTag = domplate(CSSDomplateBase,
// Use a space here, so that "copy to clipboard" has it (issue 3266).
SPAN({"class": "cssColon"}, ": "),
- SPAN({"class": "cssPropValue", $editable: "$rule|isEditable",
- _repObject: "$prop.value$prop.important"}, "$prop|getPropertyValue$prop.important"
+ SPAN({"class": "cssPropValue", $editable: "$rule|isEditable"},
+ "$prop|getPropertyValue$prop.important"
),
SPAN({"class": "cssSemi"}, ";")
)
@@ -798,7 +798,7 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
disabledMap.set(rule, []);
var map = disabledMap.get(rule);
- var propValue = Firebug.getRepObject(Dom.getChildByClass(row, "cssPropValue"));
+ var propValue = Dom.getChildByClass(row, "cssPropValue").textContent;
var parsedValue = parsePriority(propValue);
CSSModule.disableProperty(Css.hasClass(row, "disabledStyle"), rule,
@@ -1470,10 +1470,12 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
{
var rule = child.repObject;
if (rule)
+ {
return {
line: getRuleLine(rule),
offset: panelNode.scrollTop-child.offsetTop
};
+ }
}
}
return 0;
@@ -1619,7 +1621,7 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
continue;
var name = Dom.getChildByClass(row, "cssPropName").textContent;
- var value = Firebug.getRepObject(Dom.getChildByClass(row, "cssPropValue"));
+ var value = Dom.getChildByClass(row, "cssPropValue").textContent;
lines.push(name + ": " + value + ";");
}
@@ -1738,8 +1740,6 @@ CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
var parsedValue = parsePriority(value);
CSSModule.setProperty(rule, propName, parsedValue.value,
parsedValue.priority);
- // Save in rep object.
- Dom.getAncestorByClass(target, "cssPropValue").repObject = value;
}
else if (previousValue && previousValue != "null")
{
@@ -1837,7 +1837,7 @@ CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
var rule = Firebug.getRepObject(cssRule);
var baseText = rule.style ? rule.style.cssText : rule.cssText;
var prop = Dom.getAncestorByClass(target, "cssProp");
- var propValue = Firebug.getRepObject(Dom.getChildByClass(prop, "cssPropValue"));
+ var propValue = Dom.getChildByClass(prop, "cssPropValue").textContent;
var parsedValue = parsePriority(propValue);
if (previous)
@@ -1881,20 +1881,6 @@ CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
}
},
- getInitialValue: function(target, value)
- {
- if (value == "")
- return value;
-
- var propValue = Dom.getAncestorByClass(target, "cssPropValue");
- if (propValue)
- {
- var row = Dom.getAncestorByClass(target, "cssProp");
- value = Firebug.getRepObject(propValue);
- }
- return value;
- },
-
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
getAutoCompleteRange: function(value, offset)
@@ -2363,7 +2349,7 @@ CSSRuleEditor.prototype = domplate(SelectorEditor.prototype,
if (!Css.hasClass(propEl, "disabledStyle"))
{
var propName = Dom.getChildByClass(propEl, "cssPropName").textContent;
- var propValue = Dom.getChildByClass(propEl, "cssPropValue").repObject;
+ var propValue = Dom.getChildByClass(propEl, "cssPropValue").textContent;
cssText.push(propName + ":" + propValue + ";");
}
}
@@ -2645,27 +2631,7 @@ function getRuleLine(rule)
{
return Dom.domUtils.getRuleLine(rule);
}
- catch(e)
- {
-
- }
- return 0;
-}
-
-function getTopmostRuleLine(panelNode)
-{
- for (var child = panelNode.firstChild; child; child = child.nextSibling)
- {
- if (child.offsetTop+child.offsetHeight > panelNode.scrollTop)
- {
- var rule = child.repObject;
- if (rule)
- return {
- line: getRuleLine(rule),
- offset: panelNode.scrollTop-child.offsetTop
- };
- }
- }
+ catch (e) {}
return 0;
}
diff --git a/trace/FBTrace/chrome/firebug/content/css/stylePanel.js b/trace/FBTrace/chrome/firebug/content/css/stylePanel.js
index f18b80d..51379d4 100644
--- a/trace/FBTrace/chrome/firebug/content/css/stylePanel.js
+++ b/trace/FBTrace/chrome/firebug/content/css/stylePanel.js
@@ -157,6 +157,10 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
for (var i = 0; i < props.length; i++)
{
+ // XXX Avoid FireFile NPE
+ if (!this.template.CSSFontPropValueTag)
+ break;
+
var prop = props[i];
var propName = prop.getElementsByClassName("cssPropName").item(0).textContent;
if (propName == "font-family" || propName == "font")
diff --git a/trace/FBTrace/chrome/firebug/content/dom/domPanel.js b/trace/FBTrace/chrome/firebug/content/dom/domPanel.js
index d9eee6f..3165392 100644
--- a/trace/FBTrace/chrome/firebug/content/dom/domPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/dom/domPanel.js
@@ -16,6 +16,7 @@ define([
"firebug/lib/string",
"firebug/lib/array",
"firebug/lib/persist",
+ "firebug/console/closureInspector",
"firebug/dom/toggleBranch",
"firebug/lib/system",
"firebug/chrome/menu",
@@ -25,8 +26,8 @@ define([
"firebug/dom/domModule",
"firebug/console/autoCompleter"
],
-function(Obj, Firebug, Domplate, FirebugReps, Locale, Events, Wrapper,
- SourceLink, StackFrame, Dom, Css, Search, Str, Arr, Persist, ToggleBranch, System, Menu) {
+function(Obj, Firebug, Domplate, FirebugReps, Locale, Events, Wrapper, SourceLink, StackFrame,
+ Dom, Css, Search, Str, Arr, Persist, ClosureInspector, ToggleBranch, System, Menu) {
with (Domplate) {
@@ -75,14 +76,14 @@ const DirTablePlate = domplate(Firebug.Rep,
disabledBreakpoint: "$member.disabledBreakpoint"},
TD({"class": "memberHeaderCell"},
DIV({"class": "sourceLine memberRowHeader", onclick: "$onClickRowHeader"},
- " "
+ " "
)
),
TD({"class": "memberLabelCell", style: "padding-left: $member.indent\\px",
role: "presentation"},
- DIV({"class": "memberLabel $member.type\\Label"},
+ DIV({"class": "memberLabel $member.type\\Label", title: "$member.title"},
SPAN({"class": "memberLabelPrefix"}, "$member.prefix"),
- SPAN("$member.name")
+ SPAN({title: "$member|getMemberNameTooltip"}, "$member.name")
)
),
TD({"class": "memberValueCell", $readOnly: "$member.readOnly",
@@ -141,6 +142,11 @@ const DirTablePlate = domplate(Firebug.Rep,
}];
},
+ getMemberNameTooltip: function(member)
+ {
+ return member.title || member.scopeNameTooltip;
+ },
+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
onClick: function(event)
@@ -174,9 +180,10 @@ const DirTablePlate = domplate(Firebug.Rep,
var panel = row.parentNode.parentNode.domPanel;
if (panel)
{
+ // XXX this should use member.value
var rowValue = panel.getRowPropertyValue(row);
- if (typeof(rowValue) == "boolean")
- panel.setPropertyValue(row, !rowValue);
+ if (typeof rowValue == "boolean")
+ panel.setPropertyValue(row, ""+!rowValue);
else
panel.editProperty(row);
Events.cancelEvent(event);
@@ -187,7 +194,7 @@ const DirTablePlate = domplate(Firebug.Rep,
toggleRow: function(row)
{
- var level = parseInt(row.getAttribute("level"));
+ var level = parseInt(row.getAttribute("level"), 10);
var table = Dom.getAncestorByClass(row, "domTable");
var toggles = table.toggles;
if (!toggles)
@@ -239,7 +246,7 @@ const DirTablePlate = domplate(Firebug.Rep,
{
for (var firstRow = row.nextSibling; firstRow; firstRow = row.nextSibling)
{
- if (parseInt(firstRow.getAttribute("level")) <= level)
+ if (parseInt(firstRow.getAttribute("level"), 10) <= level)
break;
tbody.removeChild(firstRow);
@@ -252,12 +259,11 @@ const DirTablePlate = domplate(Firebug.Rep,
Css.setClass(row, "opened");
if (isString)
{
- var rowValue = row.domObject.value
+ var rowValue = row.domObject.value;
row.lastChild.firstChild.textContent = '"' + rowValue + '"';
}
else
{
-
if (toggles)
{
var path = getPath(row);
@@ -363,10 +369,10 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
{
if (!Firebug.viewChrome)
{
+ // Unwrap native, wrapped objects.
var contentView = Wrapper.getContentView(object);
- if (!contentView && FBTrace.DBG_DOM)
- FBTrace.sysout("getObjectView: no contentView for " + object);
- return contentView || object;
+ if (contentView)
+ return contentView;
}
return object;
},
@@ -440,6 +446,8 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
var proto = [];
var domHandlers = [];
+ var isScope = ClosureInspector.isScopeWrapper(object);
+
try
{
// Special case for "arguments", which is not enumerable by for...in statement.
@@ -448,25 +456,30 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
try
{
+ // Make sure not to touch the prototype chain of the magic scope objects.
+ var ownOnly = Firebug.showOwnProperties || isScope;
+ var enumerableOnly = Firebug.showEnumerableProperties;
+
var contentView = this.getObjectView(object);
- var properties = this.getObjectProperties(contentView,
- Firebug.showEnumerableProperties, Firebug.showOwnProperties);
+ var properties = this.getObjectProperties(contentView, enumerableOnly, ownOnly);
properties = Arr.sortUnique(properties);
- if (contentView.hasOwnProperty("constructor") &&
- properties.indexOf("constructor") == -1)
- {
- properties.push("constructor");
- }
-
- if (contentView.hasOwnProperty("prototype") &&
- properties.indexOf("prototype") == -1)
+ var addOwn = function(prop)
{
- properties.push("prototype");
- }
+ // Apparently, Object.prototype.hasOwnProperty.call(contentView, p) lies
+ // when 'contentView' is content and 'Object' is chrome... Bug 658909?
+ if (Object.getOwnPropertyDescriptor(contentView, prop) &&
+ properties.indexOf(prop) === -1)
+ {
+ properties.push(prop);
+ }
+ };
+ addOwn("constructor");
+ addOwn("prototype");
+ addOwn("wrappedJSObject");
- // If showOwnProperties is false the __proto__ can be already in.
- // If showOwnProperties is true the __proto__ should not be in.
+ // __proto__ never shows in enumerations, so add it here. We currently
+ // we don't want it when only showing own properties.
if (contentView.__proto__ && Obj.hasProperties(contentView.__proto__) &&
properties.indexOf("__proto__") == -1 && !Firebug.showOwnProperties)
{
@@ -475,7 +488,12 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
}
catch (exc)
{
- // workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=648560
+ if (FBTrace.DBG_ERRORS || FBTrace.DBG_DOM)
+ FBTrace.sysout("dom.getMembers: property lookups failed", exc);
+
+ // workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=648560
+ // XXX can't reproduce, and it's at most relevant to Chromebug.
+ /*
if (contentView.wrappedJSObject)
{
if (FBTrace.DBG_ERRORS || FBTrace.DBG_DOM)
@@ -495,11 +513,9 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
object = contentView;
}
+ */
}
- if (contentView.wrappedJSObject)
- properties.push("wrappedJSObject");
-
var domMembers = Dom.getDOMMembers(object);
for (var i = 0; i < properties.length; i++)
{
@@ -519,7 +535,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
var val;
try
{
- val = contentView[name]; // getter is safe
+ val = contentView[name];
}
catch (exc)
{
@@ -533,51 +549,45 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
var ordinal = parseInt(name);
if (ordinal || ordinal == 0)
{
- this.addMember(object, "ordinal", ordinals, name, val, level, 0, context);
+ this.addMember(object, "ordinal", ordinals, name, val, level, 0, context, isScope);
}
- else if (typeof(val) == "function")
+ else if (typeof val === "function")
{
- if (isClassFunction(val))
- {
- if (Dom.isDOMMember(object, name))
- this.addMember(object, "domClass", domClasses, name, val, level, domMembers[name], context);
- else
- this.addMember(object, "userClass", userClasses, name, val, level, 0, context);
- }
- else if (Dom.isDOMMember(object, name))
- {
- this.addMember(object, "domFunction", domFuncs, name, val, level, domMembers[name], context);
- }
+ var classFunc = isClassFunction(val), domMember = Dom.isDOMMember(object, name);
+ if (domMember && classFunc)
+ this.addMember(object, "domClass", domClasses, name, val, level, domMembers[name], context, isScope);
+ else if (domMember)
+ this.addMember(object, "domFunction", domFuncs, name, val, level, domMembers[name], context, isScope);
+ else if (classFunc)
+ this.addMember(object, "userClass", userClasses, name, val, level, 0, context, isScope);
else if (!Firebug.showUserFuncs && Firebug.showInlineEventHandlers)
- {
- this.addMember(object, "userFunction", domHandlers, name, val, level, 0, context);
- }
+ this.addMember(object, "userFunction", domHandlers, name, val, level, 0, context, isScope);
else
- {
- this.addMember(object, "userFunction", userFuncs, name, val, level, 0, context);
- }
+ this.addMember(object, "userFunction", userFuncs, name, val, level, 0, context, isScope);
}
else
{
if (isPrototype(name))
- this.addMember(object, "proto", proto, name, val, level, 0, context);
+ this.addMember(object, "proto", proto, name, val, level, 0, context, isScope);
else if (Dom.isDOMMember(object, name))
- this.addMember(object, "dom", domProps, name, val, level, domMembers[name], context);
+ this.addMember(object, "dom", domProps, name, val, level, domMembers[name], context, isScope);
else if (Dom.isDOMConstant(object, name))
- this.addMember(object, "dom", domConstants, name, val, level, 0, context);
+ this.addMember(object, "dom", domConstants, name, val, level, 0, context, isScope);
else if (Dom.isInlineEventHandler(name))
- this.addMember(object, "user", domHandlers, name, val, level, 0, context);
+ this.addMember(object, "user", domHandlers, name, val, level, 0, context, isScope);
else
- this.addMember(object, "user", userProps, name, val, level, 0, context);
+ this.addMember(object, "user", userProps, name, val, level, 0, context, isScope);
}
}
+
+ if (isScope || (typeof object === "function" && Firebug.showClosures && context))
+ this.maybeAddClosureMember(object, "proto", proto, level, context, isScope);
}
catch (exc)
{
// Sometimes we get exceptions just from trying to iterate the members
// of certain objects, like StorageList, but don't let that gum up the works
- //throw exc;
- if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM)
+ if (FBTrace.DBG_DOM)
FBTrace.sysout("dom.getMembers FAILS: ", exc);
}
@@ -622,7 +632,6 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
if (Firebug.showDOMConstants)
members.push.apply(members, domConstants);
- // The prototype is always displayed at the end.
members.push.apply(members, proto);
if (Firebug.showInlineEventHandlers)
@@ -654,7 +663,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
return members;
},
- addMember: function(object, type, props, name, value, level, order, context)
+ addMember: function()
{
try
{
@@ -667,36 +676,54 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
}
},
- addMemberInternal: function(object, type, props, name, value, level, order, context)
+ addMemberInternal: function(object, type, props, name, value, level, order, context, parentIsScope)
{
- // do this first in case a call to instanceof reveals contents
+ // Do this first in case a call to instanceof (= QI, for XPCOM things) reveals contents.
var rep = Firebug.getRep(value);
var tag = rep.shortTag ? rep.shortTag : rep.tag;
var hasProperties = Obj.hasProperties(value, !Firebug.showEnumerableProperties,
Firebug.showOwnProperties);
- var valueType = typeof(value);
+ var valueType = typeof value;
var hasChildren = hasProperties && !(value instanceof FirebugReps.ErrorCopy) &&
- (valueType == "function" || (valueType == "object" && value != null)
- || (valueType == "string" && value.length > Firebug.stringCropLength));
+ ((valueType == "function") ||
+ (valueType == "object" && value != null) ||
+ (valueType == "string" && value.length > Firebug.stringCropLength));
+
+ // Special case for closure inspection.
+ if (!hasChildren && valueType === "function" && Firebug.showClosures && context)
+ {
+ try
+ {
+ var win = context.stoppedGlobal || context.baseWindow || context.window;
+ ClosureInspector.getEnvironmentForObject(win, value, context);
+ hasChildren = true;
+ }
+ catch (e) {}
+ }
// Special case for "arguments", which is not enumerable by for...in statement
// and so, Obj.hasProperties always returns false.
- if (!hasChildren && value) // arguments will never be falsy if the arguments exist
- hasChildren = isArguments(value);
+ hasChildren = hasChildren || (!!value && isArguments(value));
- if (value)
+ if (valueType === "function" && !hasChildren)
{
- var proto = Obj.getPrototype(value);
- // Special case for functions with a prototype that has values
- if (valueType === "function" && proto)
+ try
{
- hasChildren = hasChildren || Obj.hasProperties(proto,
- !Firebug.showEnumerableProperties, Firebug.showOwnProperties);
+ // Special case for functions with a prototype that has values
+ var proto = value.prototype;
+ if (proto)
+ {
+ hasChildren = Obj.hasProperties(proto, !Firebug.showEnumerableProperties,
+ Firebug.showOwnProperties);
+ }
}
+ catch (exc) {}
}
+ var descriptor = getPropertyDescriptor(object, name);
+
var member = {
object: object,
name: name,
@@ -710,7 +737,9 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
hasChildren: hasChildren,
tag: tag,
prefix: "",
- readOnly: false
+ readOnly: (descriptor && !descriptor.writable && !descriptor.set),
+ // XXX should probably move the tests from getContextMenuItems here
+ deletable: (!parentIsScope && !(descriptor && !descriptor.configurable))
};
// The context doesn't have to be specified (e.g. in case of Watch panel that is based
@@ -718,7 +747,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
if (context)
{
// xxxHonza: Support for object change not implemented yet.
- member.breakable = !hasChildren;
+ member.breakable = !hasChildren && !parentIsScope;
var breakpoints = context.dom.breakpoints;
var bp = breakpoints.findBreakpoint(object, name);
@@ -729,8 +758,13 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
}
}
+ if (parentIsScope)
+ member.scopeNameTooltip = Locale.$STRF("dom.tip.scopeMemberName", ["%" + name]);
+
// Set prefix for user defined properties. This prefix help the user to distinguish
// among simple properties and those defined using getter and/or (only a) setter.
+ // XXX This should be rewritten to use 'descriptor', and I believe the unwrapping
+ // test is wrong (see issue 5377).
var o = this.getObjectView(object);
if (o && !Dom.isDOMMember(object, name) && (XPCNativeWrapper.unwrap(object) !== object))
{
@@ -751,19 +785,48 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
// only setter
if (!getter && setter)
{
- member.readOnly = true;
member.prefix = "set";
}
}
- var readOnly = isReadOnly(object, name);
- if (typeof(readOnly) != "undefined")
- member.readOnly = readOnly;
-
props.push(member);
return member;
},
+ // Add the magic "(closure)" property.
+ maybeAddClosureMember: function(object, type, props, level, context, isScope)
+ {
+ var win = context.stoppedGlobal || context.baseWindow || context.window;
+ var wrapper = ClosureInspector.getScopeWrapper(object, win, context, isScope);
+ if (!wrapper)
+ return;
+
+ var name = (isScope ? Locale.$STR("dom.scopeParentName") : Locale.$STR("dom.scopeName"));
+ var title = (isScope ? undefined : Locale.$STR("dom.tip.scopeName"));
+ var rep = Firebug.getRep(wrapper);
+ var tag = rep.shortTag ? rep.shortTag : rep.tag;
+
+ var member = {
+ object: object,
+ name: name,
+ value: wrapper,
+ type: type,
+ rowClass: "memberRow-" + type,
+ open: "",
+ order: 0,
+ level: level,
+ indent: level*16,
+ hasChildren: true,
+ tag: tag,
+ prefix: "",
+ title: title,
+ readOnly: true,
+ deletable: false,
+ ignoredPath: true
+ };
+ props.push(member);
+ },
+
// recursion starts with offset=0, level=0
expandMembers: function (members, toggles, offset, level, context)
{
@@ -771,7 +834,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
for (var i = offset; i < members.length; ++i)
{
var member = members[i];
- if (member.level > level)
+ if (member.level < level)
break;
if (toggles.get(member.name))
@@ -799,10 +862,10 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
member.level, member);
}
- expanded += newMembers.length;
-
- i += newMembers.length + this.expandMembers(members, toggles.get(member.name),
- i+1, level+1, context);
+ var moreExpanded = newMembers.length +
+ this.expandMembers(members, toggles.get(member.name), i+1, level+1, context);
+ i += moreExpanded;
+ expanded += moreExpanded;
}
}
@@ -961,14 +1024,26 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
getRowPathName: function(row)
{
- var name = row.domObject.name;
+ var member = row.domObject, name = member.name;
+
+ // Fake "(closure)" properties.
+ if (member.ignoredPath)
+ return ["", ""];
+
+ // Closure variables.
+ if (ClosureInspector.isScopeWrapper(member.object))
+ return [".%", name];
- if(name.match(/^[\d]+$/))//ordinal
+ // Ordinals.
+ if (name.match(/^[\d]+$/))
return ["", "["+name+"]"];
- else if(name.match(rxIdentifier))//identifier
+
+ // Identifiers.
+ if (name.match(rxIdentifier))
return [".", name];
- else//map keys
- return ["", "[\""+name.replace(/\\/g, "\\\\").replace(/"/g,"\\\"") + "\"]"];
+
+ // Other, weird, names.
+ return ["", "[\""+name.replace(/\\/g, "\\\\").replace(/"/g,"\\\"") + "\"]"];
},
copyName: function(row)
@@ -991,7 +1066,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
getPropertyPath: function(row)
{
var path = [];
- for(var current = row; current ; current = getParentRow(current))
+ for (var current = row; current ; current = getParentRow(current))
path = this.getRowPathName(current).concat(path);
path.shift(); //don't want the first separator
return path;
@@ -1026,9 +1101,9 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
{
var propValue = this.getRowPropertyValue(row);
- var type = typeof(propValue);
+ var type = typeof propValue;
if (type == "undefined" || type == "number" || type == "boolean")
- editValue = propValue;
+ editValue = "" + propValue;
else if (type == "string")
editValue = "\"" + Str.escapeJS(propValue) + "\"";
else if (propValue == null)
@@ -1036,7 +1111,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
else if (object instanceof window.Window || object instanceof StackFrame.StackFrame)
editValue = getRowName(row);
else
- editValue = "this." + getRowName(row);
+ editValue = "this." + getRowName(row); // XXX "this." doesn't actually work
}
Firebug.Editor.startEditing(row, editValue);
@@ -1051,17 +1126,14 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
}
else
{
- var object = getRowOwnerObject(row);
- if (!object)
- object = this.selection;
- object = this.getObjectView(object);
+ var member = row.domObject;
+ var object = this.getObjectView(member.object);
- if (object)
+ if (member.deletable)
{
- var name = getRowName(row);
try
{
- delete object[name];
+ delete object[member.name];
}
catch (exc)
{
@@ -1076,26 +1148,29 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
setPropertyValue: function(row, value) // value must be string
{
+ var member = row.domObject;
+ var name = member.name;
+
if (FBTrace.DBG_DOM)
{
- FBTrace.sysout("row: " + row);
- FBTrace.sysout("value: " + value + " type " + typeof(value), value);
+ FBTrace.sysout("setPropertyValue: " + name + " set to " +
+ (typeof value === "string" ? "\"" + value + "\"" : "non-string!?!?"), row);
}
- var name = getRowName(row);
if (name == "this")
return;
var object = this.getRealRowObject(row);
if (object && !(object instanceof StackFrame.StackFrame))
{
- Firebug.CommandLine.evaluate(value, this.context, object, this.context.getGlobalScope(),
+ var win = this.context.stoppedGlobal || this.context.baseWindow || this.context.window;
+ Firebug.CommandLine.evaluate(value, this.context, object, win,
function success(result, context)
{
if (FBTrace.DBG_DOM)
{
- FBTrace.sysout("setPropertyValue evaluate success object[" + name + "]=" +
- result + " type " + typeof(result), result);
+ FBTrace.sysout("setPropertyValue evaluate success object[" + name + "]" +
+ " set to type " + typeof result, result);
}
object[name] = result;
},
@@ -1105,19 +1180,15 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
{
if (FBTrace.DBG_DOM)
{
- FBTrace.sysout("setPropertyValue evaluate failed with exc:" + exc +
- " object[" + name + "]=" + value + " type " + typeof(value), exc);
+ FBTrace.sysout("setPropertyValue evaluate FAILED", exc);
}
// If the value doesn't parse, then just store it as a string.
// Some users will not realize they're supposed to enter a JavaScript
// expression and just type literal text
- object[name] = String(value); // unwrappedJSobject.property = string
- }
- catch (exc)
- {
- return;
+ object[name] = value;
}
+ catch (exc) {}
}
);
}
@@ -1132,7 +1203,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
try
{
// See catch block above...
- object[name] = String(value); // unwrappedJSobject.property = string
+ object[name] = value;
}
catch (exc)
{
@@ -1161,10 +1232,6 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
if (!member.breakable)
return;
- //xxxHonza: don't use getRowName to get the prop name. From some reason
- // unwatch doesn't work if row.firstChild.textContent is used.
- // It works only from within the watch handler method if the passed param
- // name is used.
var name = member.name;
if (name == "this")
return;
@@ -1345,7 +1412,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
if (object == null)
return 1000;
- if (typeof(object) == "undefined")
+ if (typeof object == "undefined")
return 1000;
else if (object instanceof SourceLink.SourceLink)
return 0;
@@ -1361,7 +1428,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
updateSelection: function(object)
{
if (FBTrace.DBG_DOM)
- FBTrace.sysout("dom.updateSelection; object=" + object, object);
+ FBTrace.sysout("dom.updateSelection", object);
var previousIndex = this.pathIndex;
var previousView = previousIndex == -1 ? null : this.viewPath[previousIndex];
@@ -1396,6 +1463,8 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
return;
}
+ // XXX This is wrong with closures, but I haven't noticed anything
+ // break and I don't know how to fix, so let's just leave it...
for (var i = 0; i < newPath.length; ++i)
{
var name = newPath[i];
@@ -1445,7 +1514,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
}
this.panelNode.scrollTop = 0;
- this.rebuild();
+ this.rebuild(false);
}
else
{
@@ -1460,7 +1529,6 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
this.rebuild(false, view ? view.scrollTop : 0);
}
-
},
getObjectPath: function(object)
@@ -1470,7 +1538,8 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
getDefaultSelection: function()
{
- return this.getObjectView(this.context.getGlobalScope());
+ // Default to showing the top window.
+ return this.getObjectView(this.context.window);
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -1485,6 +1554,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
options.add("showDOMFuncs");
options.add("showDOMConstants");
options.add("showInlineEventHandlers");
+ options.add("showClosures");
options.add("showOwnProperties");
options.add("showEnumerableProperties");
@@ -1496,7 +1566,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
{
return [
Menu.optionMenu("ShowUserProps", "showUserProps",
- "dom.option.tip.Show User Props"),
+ "dom.option.tip.Show_User_Props"),
Menu.optionMenu("ShowUserFuncs", "showUserFuncs",
"dom.option.tip.Show_User_Funcs"),
Menu.optionMenu("ShowDOMProps", "showDOMProps",
@@ -1507,6 +1577,8 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
"dom.option.tip.Show_DOM_Constants"),
Menu.optionMenu("ShowInlineEventHandlers", "showInlineEventHandlers",
"ShowInlineEventHandlersTooltip"),
+ Menu.optionMenu("ShowClosures", "showClosures",
+ "dom.option.tip.Show_Closures"),
"-",
Menu.optionMenu("ShowOwnProperties", "showOwnProperties",
"ShowOwnPropertiesTooltip"),
@@ -1527,12 +1599,12 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
var items = [];
- if (row)
+ if (row && row.domObject && !row.domObject.ignoredPath)
{
- var rowName = getRowName(row);
- var rowObject = this.getRowObject(row);
- var rowValue = this.getRowPropertyValue(row);
var member = row.domObject;
+ var rowName = member.name;
+ var rowObject = member.object;
+ var rowValue = member.value;
var isWatch = Css.hasClass(row, "watchRow");
var isStackFrame = rowObject instanceof StackFrame.StackFrame;
@@ -1552,7 +1624,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
}
);
- if (typeof(rowValue) == "string" || typeof(rowValue) == "number")
+ if (typeof rowValue == "string" || typeof rowValue == "number")
{
// Functions already have a copy item in their context menu
items.push(
@@ -1580,7 +1652,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
tooltiptext = "dom.tip.Edit_Property";
}
- var readOnly = (!isWatch && !isStackFrame && member && member.readOnly);
+ var readOnly = (!isWatch && !isStackFrame && member.readOnly);
if (!readOnly)
{
items.push(
@@ -1593,7 +1665,8 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
);
}
- if (isWatch || (!isStackFrame && !Dom.isDOMMember(rowObject, rowName)))
+ if (isWatch ||
+ (member.deletable && !isStackFrame && !Dom.isDOMMember(rowObject, rowName)))
{
items.push(
{
@@ -1853,7 +1926,7 @@ function isPrototype(name)
return (name == "prototype" || name == "__proto__");
}
-function isReadOnly(object, propName)
+function getPropertyDescriptor(object, propName)
{
try
{
@@ -1862,18 +1935,20 @@ function isReadOnly(object, propName)
{
desc = Object.getOwnPropertyDescriptor(object, propName);
if (desc)
- break;
+ return desc;
object = Object.getPrototypeOf(object);
}
- return (desc && !desc.writable && !desc.set);
}
catch (e)
{
}
+ return undefined;
}
function getRowName(row)
{
+ // XXX This can return not only property names but also just descriptive ones,
+ // like "(closure)", and indeed the collapse remembering logic relies on that.
var labelNode = row.getElementsByClassName("memberLabelCell").item(0);
return labelNode.textContent;
}
@@ -1893,24 +1968,26 @@ function getRowOwnerObject(row)
function getParentRow(row)
{
- var level = parseInt(row.getAttribute("level"))-1;
- // If it's top level object the level is now set to -1, is that a problem?
+ var level = "" + (parseInt(row.getAttribute("level"), 10) - 1);
+ if (level == "-1")
+ return;
for (row = row.previousSibling; row; row = row.previousSibling)
{
- if (parseInt(row.getAttribute("level")) == level)
+ if (row.getAttribute("level") === level)
return row;
}
}
+// Return an array of parts that uniquely identifies a row (not always all JavaScript)
function getPath(row)
{
var name = getRowName(row);
var path = [name];
- var level = parseInt(row.getAttribute("level"))-1;
- for (row = row.previousSibling; row; row = row.previousSibling)
+ var level = parseInt(row.getAttribute("level"), 10) - 1;
+ for (row = row.previousSibling; row && level >= 0; row = row.previousSibling)
{
- if (parseInt(row.getAttribute("level")) == level)
+ if (parseInt(row.getAttribute("level"), 10) === level)
{
var name = getRowName(row);
path.splice(0, 0, name);
diff --git a/trace/FBTrace/chrome/firebug/content/editor/editor.js b/trace/FBTrace/chrome/firebug/content/editor/editor.js
index 9e08249..05f36a6 100644
--- a/trace/FBTrace/chrome/firebug/content/editor/editor.js
+++ b/trace/FBTrace/chrome/firebug/content/editor/editor.js
@@ -669,7 +669,7 @@ Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor,
panel.panelNode.appendChild(this.box);
this.input.select();
- if (selectionData) //transfer selection to input element
+ if (selectionData) // transfer selection to input element
this.setSelection(selectionData);
// Insert the "expander" to cover the target element with white space
diff --git a/trace/FBTrace/chrome/firebug/content/firebug.js b/trace/FBTrace/chrome/firebug/content/firebug.js
index e1d93e2..b0b108b 100644
--- a/trace/FBTrace/chrome/firebug/content/firebug.js
+++ b/trace/FBTrace/chrome/firebug/content/firebug.js
@@ -22,10 +22,14 @@ define([
"firebug/lib/dom",
"firebug/lib/http",
"firebug/trace/traceListener",
- "firebug/console/commandLineExposed",
+
+ // xxxHonza: FBTrace says that Firebug is undefined in commandLineExposed module
+ // This works in Firebug 1.12 so, we can live with this hack for 1.11 I guess.
+ // See also register and unregisterCommand methods.
+ // "firebug/console/commandLineExposed",
],
function(FBL, Obj, Firefox, ChromeFactory, Domplate, Options, Locale, Events,
- Wrapper, Url, Css, Win, Str, Arr, Dom, Http, TraceListener, CommandLineExposed) {
+ Wrapper, Url, Css, Win, Str, Arr, Dom, Http, TraceListener/*, CommandLineExposed*/) {
// ********************************************************************************************* //
// Constants
@@ -83,7 +87,7 @@ if (window.Firebug)
*/
window.Firebug =
{
- version: "1.10",
+ version: "1.11",
dispatchName: "Firebug",
modules: modules,
@@ -664,12 +668,13 @@ window.Firebug =
registerCommand: function(name, config)
{
- return CommandLineExposed.registerCommand(name, config);
+ // See top of this file
+ //return Firebug.CommandLineExposed.registerCommand(name, config);
},
unregistereCommand: function(name)
{
- return CommandLineExposed.unregisterCommand(name);
+ //return CommandLineExposed.unregisterCommand(name);
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.js b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.js
index 82da56a..e4eaa89 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.js
+++ b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.js
@@ -301,9 +301,13 @@ BrowserOverlay.prototype =
var items = [];
var currPos = Options.get("framePosition");
- for each (var pos in ["detached", "top", "bottom", "left", "right"])
+
+ var positions = ["detached", "top", "bottom", "left", "right"];
+ for (var i=0; i<positions.length; i++)
{
+ var pos = positions[i];
var label = pos.charAt(0).toUpperCase() + pos.slice(1);
+
var item = $menuitem(this.doc, {
label: Locale.$STR("firebug.menu." + label),
tooltiptext: Locale.$STR("firebug.menu.tip." + label),
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/browserOverlayLib.js b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlayLib.js
index e5e967e..bb04c3d 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/browserOverlayLib.js
+++ b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlayLib.js
@@ -60,8 +60,8 @@ var BrowserOverlayLib =
for (var a in attributes)
el.setAttribute(a, attributes[a]);
- for each (var a in children)
- el.appendChild(a);
+ for (var i=0; children && i<children.length; i++)
+ el.appendChild(children[i]);
if (parent)
{
@@ -255,8 +255,9 @@ function updatePersistedValues(doc, options)
return target.Value;
}
- for each(var attr in persist)
+ for (var i=0; i<persist.length; i++)
{
+ var attr = persist[i];
var val = getPersist(attr);
if (val)
options[attr] = val;
diff --git a/trace/FBTrace/chrome/firebug/content/html/highlighter.css b/trace/FBTrace/chrome/firebug/content/html/highlighter.css
index a8aad6c..049ed82 100644
--- a/trace/FBTrace/chrome/firebug/content/html/highlighter.css
+++ b/trace/FBTrace/chrome/firebug/content/html/highlighter.css
@@ -20,6 +20,7 @@
box-shadow: none !important;
background: transparent none !important;
pointer-events: none !important;
+ white-space: normal !important;
}
.firebugBlockBackgroundColor {
diff --git a/trace/FBTrace/chrome/firebug/content/html/htmlPanel.js b/trace/FBTrace/chrome/firebug/content/html/htmlPanel.js
index 1d71977..eb9897d 100644
--- a/trace/FBTrace/chrome/firebug/content/html/htmlPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/html/htmlPanel.js
@@ -327,6 +327,7 @@ Firebug.HTMLPanel.prototype = Obj.extend(WalkingPanel,
editor.innerEditMode = node.localName in Css.innerEditableTags;
var html = editor.innerEditMode ? node.innerHTML : Xml.getElementHTML(node);
+ html = Str.escapeForHtmlEditor(html);
Firebug.Editor.startEditing(box, html, editor);
},
diff --git a/trace/FBTrace/chrome/firebug/content/html/inspector.js b/trace/FBTrace/chrome/firebug/content/html/inspector.js
index 4b21ca1..da1f7f6 100644
--- a/trace/FBTrace/chrome/firebug/content/html/inspector.js
+++ b/trace/FBTrace/chrome/firebug/content/html/inspector.js
@@ -23,7 +23,7 @@ function(Obj, Firebug, Firefox, FirebugReps, Locale, Events, Wrapper, Arr, Css,
// Constants
const inspectDelay = 200;
-const highlightCSS = "chrome://firebug/content/html/highlighter.css";
+const highlightCssUrl = "chrome://firebug/content/html/highlighter.css";
const ident = HighlighterCache.ident;
const Cu = Components.utils;
@@ -1276,7 +1276,7 @@ Firebug.Inspector.FrameHighlighter.prototype =
FBTrace.sysout("FrameHighlighter needsAppend: " + highlighter.ownerDocument.documentURI +
" !?= " + body.ownerDocument.documentURI, highlighter);
- attachStyles(context, body);
+ attachStyles(context, body.ownerDocument);
try
{
@@ -1495,7 +1495,7 @@ BoxModelHighlighter.prototype =
if (needsAppend)
{
- attachStyles(context, body);
+ attachStyles(context, body.ownerDocument);
body.appendChild(nodes.offset);
}
@@ -1634,27 +1634,26 @@ function getNonFrameBody(elt)
return (body.localName && body.localName.toUpperCase() === "FRAMESET") ? null : body;
}
-function attachStyles(context, body)
+function attachStyles(context, doc)
{
- if (FBTrace.DBG_ERRORS && context.highlightStyle && Cu.isDeadWrapper(context.highlightStyle))
- FBTrace.sysout("inspector.attachStyles; ERROR can't access dead object");
+ if (!context.highlightStyleCache)
+ context.highlightStyleCache = new WeakMap();
+ var highlightStyleCache = context.highlightStyleCache;
- var doc = body.ownerDocument;
-
- if (!context.highlightStyle)
- context.highlightStyle = Css.createStyleSheet(doc, highlightCSS);
-
- var parentNode = context.highlightStyle.parentNode;
- if (!parentNode || context.highlightStyle.ownerDocument != doc)
+ var style;
+ if (highlightStyleCache.has(doc))
+ {
+ style = highlightStyleCache.get(doc);
+ }
+ else
{
- // Clone the <style> element so, it doesn't adopt the new document as parent.
- // The other doc (except of the original one that is always the top doc) comes
- // from an iframe, which can be reloaded (within the context life-time) and
- // consequent access to context.highlightStyle would fire "can't access dead object"
- // exception (see issue 6013).
- var style = parentNode ? context.highlightStyle.cloneNode(true) : context.highlightStyle;
- Css.addStyleSheet(body.ownerDocument, style);
+ style = Css.createStyleSheet(doc, highlightCssUrl);
+ highlightStyleCache.set(doc, style);
}
+
+ // Cater for the possiblity that someone might have removed our stylesheet.
+ if (!style.parentNode)
+ Css.addStyleSheet(doc, style);
}
function createProxiesForDisabledElements(body)
diff --git a/trace/FBTrace/chrome/firebug/content/html/layout.js b/trace/FBTrace/chrome/firebug/content/html/layout.js
index b13a3c5..34a060f 100644
--- a/trace/FBTrace/chrome/firebug/content/html/layout.js
+++ b/trace/FBTrace/chrome/firebug/content/html/layout.js
@@ -352,9 +352,9 @@ LayoutPanel.prototype = Obj.extend(Firebug.Panel,
"absoluteEdge";
}
- var node;
+ var node = this.panelNode.getElementsByClassName("outerLayoutBox").item(0);
// If the layout panel content was already created, just fill in the new values
- if (this.panelNode.getElementsByClassName("outerLayoutBox").item(0))
+ if (node)
{
// The styles for the positionLayoutBox need to be set manually
var positionLayoutBox = this.panelNode.getElementsByClassName("positionLayoutBox").
diff --git a/trace/FBTrace/chrome/firebug/content/js/debugger.js b/trace/FBTrace/chrome/firebug/content/js/debugger.js
index 810c673..f21f78b 100644
--- a/trace/FBTrace/chrome/firebug/content/js/debugger.js
+++ b/trace/FBTrace/chrome/firebug/content/js/debugger.js
@@ -122,6 +122,11 @@ Firebug.Debugger = Obj.extend(Firebug.ActivableModule,
});
},
+ _temporaryTransformSyntax: function(expr, win, context)
+ {
+ return Firebug.ClosureInspector.extendLanguageSyntax(expr, win, context);
+ },
+
/**
* Used by autocomplete in commandLine
* @return array of locally visible property names for each scope we are in
@@ -129,7 +134,8 @@ Firebug.Debugger = Obj.extend(Firebug.ActivableModule,
getCurrentFrameKeys: function(context) // TODO remote, on bti
{
// return is safe
- var globals = Arr.keys(Wrapper.getContentView(context.getGlobalScope()));
+ var win = context.stoppedGlobal || context.baseWindow || context.window;
+ var globals = Arr.keys(Wrapper.getContentView(win));
if (context.currentFrame)
return this.getFrameKeys(context.currentFrame, globals);
@@ -295,12 +301,23 @@ Firebug.Debugger = Obj.extend(Firebug.ActivableModule,
context.stoppedFrame = frame; // the frame we stopped in, don't change this elsewhere.
context.currentFrame = frame; // the frame we show to user, depends on selection
context.stopped = true;
+ try
+ {
+ context.stoppedGlobal = XPCNativeWrapper(
+ Wrapper.unwrapIValue(frame.executionContext.globalObject));
+ }
+ catch (exc)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("debugger.stop failed to get global scope");
+ }
- var hookReturn = Firebug.connection.dispatch("onStop",[context,frame, type,rv]);
+ var hookReturn = Firebug.connection.dispatch("onStop", [context, frame, type, rv]);
if ( hookReturn && hookReturn >= 0 )
{
delete context.stopped;
delete context.stoppedFrame;
+ delete context.stoppedGlobal;
delete context.currentFrame;
if (FBTrace.DBG_UI_LOOP)
@@ -1012,6 +1029,7 @@ Firebug.Debugger = Obj.extend(Firebug.ActivableModule,
{
delete context.stopped;
delete context.stoppedFrame;
+ delete context.stoppedGlobal;
delete context.currentFrame;
context.executingSourceFile = null;
delete context.breakLineNumber;
diff --git a/trace/FBTrace/chrome/firebug/content/js/scriptPanel.js b/trace/FBTrace/chrome/firebug/content/js/scriptPanel.js
index d27112a..b99b623 100644
--- a/trace/FBTrace/chrome/firebug/content/js/scriptPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/js/scriptPanel.js
@@ -503,7 +503,8 @@ Firebug.ScriptPanel.prototype = Obj.extend(Firebug.SourceBoxPanel,
var self = this;
// If the evaluate fails, then we report an error and don't show the infotip
- Firebug.CommandLine.evaluate(expr, this.context, null, this.context.getGlobalScope(),
+ var win = this.context.stoppedGlobal || this.context.baseWindow || this.context.window;
+ Firebug.CommandLine.evaluate(expr, this.context, null, win,
function success(result, context)
{
var rep = Firebug.getRep(result, context);
@@ -1622,9 +1623,7 @@ Firebug.ScriptPanel.prototype = Obj.extend(Firebug.SourceBoxPanel,
if (!chrome)
{
if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("debugger.syncCommand, context with no chrome: " +
- context.getGlobalScope());
-
+ FBTrace.sysout("debugger.syncCommand, context with no chrome", context);
return;
}
diff --git a/trace/FBTrace/chrome/firebug/content/js/watchPanel.js b/trace/FBTrace/chrome/firebug/content/js/watchPanel.js
index b9d0a2a..21fedf7 100644
--- a/trace/FBTrace/chrome/firebug/content/js/watchPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/js/watchPanel.js
@@ -120,10 +120,12 @@ Firebug.WatchPanel.prototype = Obj.extend(Firebug.DOMBasePanel.prototype,
}
var scopes;
+ var context = this.context;
+ var win = context.stoppedGlobal || context.baseWindow || context.window;
if (frame instanceof StackFrame.StackFrame)
scopes = frame.getScopes(Firebug.viewChrome);
else
- scopes = [this.context.getGlobalScope()];
+ scopes = [win];
if (FBTrace.DBG_STACK)
FBTrace.sysout("dom watch frame isStackFrame " +
@@ -139,7 +141,7 @@ Firebug.WatchPanel.prototype = Obj.extend(Firebug.DOMBasePanel.prototype,
var expr = this.watches[i];
var value = null;
- Firebug.CommandLine.evaluate(expr, this.context, null, this.context.getGlobalScope(),
+ Firebug.CommandLine.evaluate(expr, context, null, win,
function success(result, context)
{
value = result;
@@ -151,10 +153,10 @@ Firebug.WatchPanel.prototype = Obj.extend(Firebug.DOMBasePanel.prototype,
}
);
- this.addMember(scopes[0], "watch", members, expr, value, 0);
+ this.addMember(scopes[0], "watch", members, expr, value, 0, 0, context);
if (FBTrace.DBG_DOM)
- FBTrace.sysout("watch.updateSelection " + expr + " = " + value,
+ FBTrace.sysout("watch.updateSelection \"" + expr + "\"",
{expr: expr, value: value, members: members})
}
}
@@ -163,16 +165,16 @@ Firebug.WatchPanel.prototype = Obj.extend(Firebug.DOMBasePanel.prototype,
{
var thisVar = frame.getThisValue();
if (thisVar)
- this.addMember(scopes[0], "user", members, "this", thisVar, 0);
+ this.addMember(scopes[0], "user", members, "this", thisVar, 0, 0, context);
// locals, pre-expanded
- members.push.apply(members, this.getMembers(scopes[0], 0, this.context));
+ members.push.apply(members, this.getMembers(scopes[0], 0, context));
for (var i=1; i<scopes.length; i++)
- this.addMember(scopes[i], "scopes", members, scopes[i].toString(), scopes[i], 0);
+ this.addMember(scopes[i], "scopes", members, scopes[i].toString(), scopes[i], 0, 0, context);
}
- this.expandMembers(members, this.toggles, 0, 0, this.context);
+ this.expandMembers(members, this.toggles, 0, 0, context);
this.showMembers(members, false);
if (FBTrace.DBG_STACK)
@@ -364,14 +366,13 @@ Firebug.WatchPanel.prototype = Obj.extend(Firebug.DOMBasePanel.prototype,
return;
var row = Dom.getAncestorByClass(target, "memberRow");
- if (!row)
+ if (!row || row.domObject.ignoredPath)
return;
var path = this.getPropertyPath(row);
if (!path || !path.length)
return;
-
// Ignore top level variables in the Watch panel.
if (panel.name == "watches" && path.length == 1)
return;
diff --git a/trace/FBTrace/chrome/firebug/content/lib/array.js b/trace/FBTrace/chrome/firebug/content/lib/array.js
index 724683d..a24283c 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/array.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/array.js
@@ -9,6 +9,7 @@ function(FBTrace) {
// Constants
const Ci = Components.interfaces;
+const Cu = Components.utils;
var Arr = {};
// ********************************************************************************************* //
@@ -33,17 +34,29 @@ Arr.isArrayLike = function(obj)
return true;
if (typeof obj.splice === "function") // jQuery etc.
return true;
- if (obj instanceof Ci.nsIDOMHTMLCollection)
+ if (Arr._isDOMTokenList(obj))
return true;
- if (obj instanceof Ci.nsIDOMNodeList)
- return true;
- if (obj instanceof Ci.nsIDOMDOMTokenList)
+ var str = Object.prototype.toString.call(obj);
+ if (str === "[object HTMLCollection]" || str === "[object NodeList]")
return true;
}
catch (exc) {}
return false;
};
+Arr._isDOMTokenList = function(obj)
+{
+ // When minVersion is 19 or so, we can replace this whole function with
+ // (Object.prototype.toString.call(obj) === "[object DOMTokenList]").
+ try
+ {
+ var uwGlobal = XPCNativeWrapper.unwrap(Cu.getGlobalForObject(obj));
+ return obj instanceof uwGlobal.DOMTokenList;
+ }
+ catch (exc) {}
+ return false;
+};
+
// At least sometimes the keys will be on user-level window objects
Arr.keys = function(map)
{
diff --git a/trace/FBTrace/chrome/firebug/content/lib/css.js b/trace/FBTrace/chrome/firebug/content/lib/css.js
index d1f449c..2f5da52 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/css.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/css.js
@@ -239,14 +239,15 @@ Css.copyBoxStyles = function(fromNode, toNode, style)
if (!style)
style = view.getComputedStyle(fromNode, "");
- toNode.style.marginTop = style.getPropertyCSSValue("margin-top").cssText;
- toNode.style.marginRight = style.getPropertyCSSValue("margin-right").cssText;
- toNode.style.marginBottom = style.getPropertyCSSValue("margin-bottom").cssText;
- toNode.style.marginLeft = style.getPropertyCSSValue("margin-left").cssText;
- toNode.style.borderTopWidth = style.getPropertyCSSValue("border-top-width").cssText;
- toNode.style.borderRightWidth = style.getPropertyCSSValue("border-right-width").cssText;
- toNode.style.borderBottomWidth = style.getPropertyCSSValue("border-bottom-width").cssText;
- toNode.style.borderLeftWidth = style.getPropertyCSSValue("border-left-width").cssText;
+ toNode.style.marginTop = style.marginTop;
+ toNode.style.marginRight = style.marginRight;
+ toNode.style.marginBottom = style.marginBottom;
+ toNode.style.marginLeft = style.marginLeft;
+ toNode.style.borderTopWidth = style.borderTopWidth;
+ toNode.style.borderRightWidth = style.borderRightWidth;
+ toNode.style.borderBottomWidth = style.borderBottomWidth;
+ toNode.style.borderLeftWidth = style.borderLeftWidth;
+ toNode.style.unicodeBidi = style.unicodeBidi;
return style;
}
diff --git a/trace/FBTrace/chrome/firebug/content/lib/dom.js b/trace/FBTrace/chrome/firebug/content/lib/dom.js
index 81e2f17..d2bcdf1 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/dom.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/dom.js
@@ -181,7 +181,7 @@ Dom.setOuterHTML = function(element, html)
{
try
{
- var fragment = DOM.markupToDocFragment(html, element);
+ var fragment = Dom.markupToDocFragment(html, element);
var first = fragment.firstChild;
var last = fragment.lastChild;
@@ -812,51 +812,39 @@ Dom.getDOMMembers = function(object)
{ return domMemberCache.Node; }
else if (object instanceof Event || object instanceof Dom.EventCopy)
{ return domMemberCache.Event; }
- else if (object instanceof Object)
- { return domMemberCache.Object; }
return null;
};
Dom.isDOMMember = function(object, propName)
{
+ // We use "in" here instead of "hasOwnProperty" so that things on Object.prototype
+ // also get treated as DOM members.
+ // XXXsimon: Non-DOM objects should also get this behavior.
var members = Dom.getDOMMembers(object);
return members && propName in members;
};
Dom.isDOMConstant = function(object, name)
{
- if (name == undefined)
- return Dom.isDOMConstantDep({},object);
-
- // The constant map has also its own prototype, but it isn't considered to be a constant.
- if (name == "__proto__")
+ if (!Dom.domConstantMap.hasOwnProperty(name))
return false;
- // object isn't recognized as such when using ===,
- // so use this as workaround
- var str = Object.prototype.toString.call(object);
- var isDOMProperty = ["[object Window]", "[object Node]", "[object Location]",
- "[object Event]"].indexOf(str) !== -1;
-
- if (!(object === window.Window ||
- object === window.Object ||
- object === window.Node ||
- object === window.Location ||
- object === window.Event ||
- object === Dom.EventCopy ||
- object instanceof window.Window ||
- object instanceof window.Node ||
- object instanceof window.Location ||
- object instanceof window.Event ||
- object instanceof Dom.EventCopy ||
- isDOMProperty))
+ try
+ {
+ // Test for nativeness. This is a fragile piece of dark magic, and might be
+ // equivalent to |Cu.isXrayWrapper(XPCNativeWrapper(object))| in >= Fx 20.
+ object = XPCNativeWrapper.unwrap(object);
+ var isNative = (XPCNativeWrapper(object).toString !== XPCNativeWrapper(object.toString));
+ return (isNative ||
+ object instanceof window.Event ||
+ object instanceof Dom.EventCopy);
+ }
+ catch (exc)
{
return false;
}
-
- return Dom.domConstantMap.hasOwnProperty(name);
-}
+};
Dom.isInlineEventHandler = function(name)
{
@@ -875,12 +863,13 @@ Dom.EventCopy = function(event)
}
}
-var isDOMConstantDep = Deprecated.deprecated(
- "isDOMConstant(name) signature changed (object,name)",
- Dom.isDOMConstant);
-
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Note: Missing HTML elements:
+// <tbody>, <object>, <embed>, <video>, <audio>, <source>, <option>, <select>, <textarea>, <br>,
+// <frame>, <iframe>, <frameset>, <link>, <meta>, <style>, probably more
+// Instead of adding them, effort should rather be spent on automatic scanning.
+
domMemberMap.Window =
[
"document",
@@ -993,18 +982,15 @@ domMemberMap.Window =
"btoa",
"updateCommands",
"XPCNativeWrapper",
- "GeckoActiveXObject",
"applicationCache", // FF3
- "GetWeakReference", // Gecko
- "XPCSafeJSObjectWrapper", // Gecko
"postMessage",
"localStorage", // FF3.5
"showModalDialog", // FF 3.0, MS IE4
"InstallTrigger",
- "performance", // https://developer.mozilla.org/en/Navigation_timing
- "matchMedia", // https://developer.mozilla.org/en/DOM/window.matchMedia
+ "performance",
+ "matchMedia",
"getInterface",
@@ -1016,7 +1002,6 @@ domMemberMap.Window =
"EventTarget",
"History",
"MimeTypeArray",
- "MozURLProperty",
"Navigator",
"NodeList",
"OfflineResourceList",
@@ -1029,47 +1014,66 @@ domMemberMap.Window =
"CharacterData",
"DOMTokenList",
"Text",
+ "Proxy",
+ "Blob",
+ "File",
+ "Image",
+ "Option",
+
+ "HTMLDocument",
+ "HTMLByteRanges",
+ "HTMLCollection",
+ "HTMLOptionsCollection",
+ "HTMLPropertiesCollection",
+ "HTMLElement",
+ "HTMLUnknownElement",
"HTMLAnchorElement",
+ "HTMLAppletElement",
+ "HTMLAreaElement",
"HTMLAudioElement",
"HTMLBaseElement",
+ "HTMLBodyElement",
+ "HTMLBRElement",
"HTMLButtonElement",
- "HTMLCollection",
"HTMLCanvasElement",
+ "HTMLCommandElement",
"HTMLDataListElement",
+ "HTMLDirectoryElement",
+ "HTMLDivElement",
"HTMLDListElement",
- "HTMLDocument",
- "HTMLElement",
"HTMLEmbedElement",
- "HTMLHtmlElement",
- "HTMLBRElement",
- "HTMLBodyElement",
- "HTMLCollection",
- "HTMLDivElement",
- "HTMLDocument",
- "HTMLElement",
+ "HTMLFieldSetElement",
+ "HTMLFontElement",
"HTMLFormElement",
- "HTMLHRElement",
+ "HTMLFrameElement",
+ "HTMLFrameSetElement",
"HTMLHeadElement",
"HTMLHeadingElement",
+ "HTMLHRElement",
+ "HTMLHtmlElement",
"HTMLHtmlElement",
"HTMLIFrameElement",
"HTMLImageElement",
"HTMLInputElement",
"HTMLLabelElement",
"HTMLLegendElement",
+ "HTMLLIElement",
"HTMLLinkElement",
"HTMLMapElement",
"HTMLMediaElement",
"HTMLMenuElement",
+ "HTMLMenuItemElement",
"HTMLMetaElement",
"HTMLMeterElement",
"HTMLModElement",
"HTMLObjectElement",
"HTMLOListElement",
+ "HTMLOptGroupElement",
"HTMLOptionElement",
- "HTMLOptionsCollection",
"HTMLOutputElement",
+ "HTMLParagraphElement",
+ "HTMLParamElement",
"HTMLPreElement",
"HTMLProgressElement",
"HTMLQuoteElement",
@@ -1078,26 +1082,24 @@ domMemberMap.Window =
"HTMLSourceElement",
"HTMLSpanElement",
"HTMLStyleElement",
+ "HTMLTableCaptionElement",
"HTMLTableCellElement",
+ "HTMLTableColElement",
"HTMLTableElement",
"HTMLTableRowElement",
"HTMLTableSectionElement",
"HTMLTextAreaElement",
"HTMLTitleElement",
"HTMLUListElement",
- "HTMLUnknownElement",
"HTMLVideoElement",
- "Infinity",
"JSON",
"Location",
"Math",
- "NaN",
"Node",
"StopIteration",
"Window",
"XULElement",
- "undefined",
"CSS2Properties",
"CSSStyleDeclaration",
"Error",
@@ -1156,46 +1158,453 @@ domMemberMap.Window =
"uneval",
"Performance",
"PerformanceNavigation",
- "PerformanceTiming"
-];
+ "PerformanceTiming",
+
+ "AnimationEvent",
+ "BeforeUnloadEvent",
+ "CommandEvent",
+ "CompositionEvent",
+ "DataContainerEvent",
+ "DataErrorEvent",
+ "DeviceMotionEvent",
+ "DragEvent",
+ "IDBVersionChangeEvent",
+ "KeyEvent",
+ "KeyboardEvent",
+ "LSProgressEvent",
+ "MessageEvent",
+ "MouseScrollEvent",
+ "MozSmsEvent",
+ "MutationEvent",
+ "NSEvent",
+ "NotifyAudioAvailableEvent",
+ "NotifyPaintEvent",
+ "SVGEvent",
+ "SVGZoomEvent",
+ "ScrollAreaEvent",
+ "SimpleGestureEvent",
+ "SmartCardEvent",
+ "TimeEvent",
+ "TransitionEvent",
+ "USSDReceivedEvent",
+ "XMLHttpProgressEvent",
+ "XULCommandEvent",
+
+ "Event",
+ "CloseEvent",
+ "CustomEvent",
+ "DOMTransactionEvent",
+ "DeviceLightEvent",
+ "DeviceOrientationEvent",
+ "DeviceProximityEvent",
+ "DeviceStorageChangeEvent",
+ "HashChangeEvent",
+ "MouseEvent",
+ "MozApplicationEvent",
+ "MozContactChangeEvent",
+ "MozSettingsEvent",
+ "PageTransitionEvent",
+ "PopStateEvent",
+ "PopupBlockedEvent",
+ "ProgressEvent",
+ "StorageEvent",
+ "UIEvent",
+ "UserProximityEvent",
+ "WheelEvent",
+
+ "AsyncScrollEventDetail",
+ "BatteryManager",
+ "BoxObject",
+ "CRMFObject",
+ "CSSCharsetRule",
+ "CSSConditionRule",
+ "CSSFontFaceRule",
+ "CSSGroupRuleRuleList",
+ "CSSGroupingRule",
+ "CSSImportRule",
+ "CSSMediaRule",
+ "CSSMozDocumentRule",
+ "CSSNameSpaceRule",
+ "CSSPageRule",
+ "CSSRect",
+ "CSSRule",
+ "CSSRuleList",
+ "CSSStyleRule",
+ "CSSStyleSheet",
+ "CSSSupportsRule",
+ "CSSUnknownRule",
+ "CameraCapabilities",
+ "CameraControl",
+ "CameraManager",
+ "CanvasGradient",
+ "CanvasPattern",
+ "ChromeWindow",
+ "ClientInformation",
+ "ClientRect",
+ "Contact",
+ "ContactAddress",
+ "ContactField",
+ "ContactFindOptions",
+ "ContactManager",
+ "ContactProperties",
+ "ContactTelField",
+ "Counter",
+ "CryptoDialogs",
+ "DOMError",
+ "DOMRequest",
+ "DataChannel",
+ "DataTransfer",
+ "DesktopNotification",
+ "DesktopNotificationCenter",
+ "DeviceAcceleration",
+ "DeviceRotationRate",
+ "DeviceStorage",
+ "DeviceStorageCursor",
+ "DeviceStorageStat",
+ "DocumentTouch",
+ "DocumentXBL",
+ "ElementCSSInlineStyle",
+ "ElementTimeControl",
+ "EventListener",
+ "EventListenerInfo",
+ "FileRequest",
+ "FontFace",
+ "FontFaceList",
+ "GeoGeolocation",
+ "GeoPosition",
+ "GeoPositionCallback",
+ "GeoPositionCoords",
+ "GeoPositionError",
+ "GeoPositionErrorCallback",
+ "GetSVGDocument",
+ "GetUserMediaErrorCallback",
+ "GetUserMediaSuccessCallback",
+ "GlobalObjectConstructor",
+ "GlobalPropertyInitializer",
+ "IDBCursor",
+ "IDBCursorWithValue",
+ "IDBDatabase",
+ "IDBFactory",
+ "IDBIndex",
+ "IDBKeyRange",
+ "IDBObjectStore",
+ "IDBOpenDBRequest",
+ "IDBRequest",
+ "IDBTransaction",
+ "ImageDocument",
+ "JSWindow",
+ "LinkStyle",
+ "LoadStatus",
+ "LocalMediaStream",
+ "LockedFile",
+ "MediaError",
+ "MediaList",
+ "MediaQueryList",
+ "MediaQueryListListener",
+ "MediaStream",
+ "MimeType",
+ "ModalContentWindow",
+ "MozAlarmsManager",
+ "MozBrowserFrame",
+ "MozCSSKeyframeRule",
+ "MozCSSKeyframesRule",
+ "MozCanvasPrintState",
+ "MozConnection",
+ "MozNavigatorNetwork",
+ "MozNavigatorSms",
+ "MozPowerManager",
+ "MozSmsCursor",
+ "MozSmsManager",
+ "MozSmsMessage",
+ "MozSmsRequest",
+ "MozSmsSegmentInfo",
+ "MozWakeLock",
+ "MozWakeLockListener",
+ "NSEditableElement",
+ "NSXPathExpression",
+ "NamedNodeMap",
+ "NavigatorCamera",
+ "NavigatorDesktopNotification",
+ "NavigatorDeviceStorage",
+ "NavigatorGeolocation",
+ "NavigatorUserMedia",
+ "NodeFilter",
+ "NodeIterator",
+ "NodeSelector",
+ "OpenWindowEventDetail",
+ "Parser",
+ "PermissionSettings",
+ "Pkcs11",
+ "Plugin",
+ "PluginArray",
+ "RTCIceCandidate",
+ "RTCPeerConnection",
+ "RTCSessionDescription",
+ "Range",
+ "RequestService",
+ "Selection",
+ "Serializer",
+ "SettingsLock",
+ "SettingsManager",
+ "StorageIndexedDB",
+ "StorageItem",
+ "StorageManager",
+ "StorageObsolete",
+ "StyleSheet",
+ "StyleSheetList",
+ "TCPSocket",
+ "TextMetrics",
+ "TimeRanges",
+ "ToString",
+ "TreeColumn",
+ "TreeColumns",
+ "TreeContentView",
+ "TreeSelection",
+ "TreeWalker",
+ "UserDataHandler",
+ "ValidityState",
+ "WindowCollection",
+ "WindowInternal",
+ "WindowPerformance",
+ "WindowUtils",
+ "XMLDocument",
+ "XMLStylesheetProcessingInstruction",
+ "XPathExpression",
+ "XPathNSResolver",
+ "XPathNamespace",
+ "XPathResult",
+
+ "Audio",
+ "AudioBuffer",
+ "AudioBufferSourceNode",
+ "AudioDestinationNode",
+ "AudioListener",
+ "AudioNode",
+ "AudioParam",
+ "AudioSourceNode",
+ "BiquadFilterNode",
+ "CDATASection",
+ "CSSPrimitiveValue",
+ "CSSValue",
+ "CSSValueList",
+ "CanvasRenderingContext2D",
+ "CaretPosition",
+ "ClientRectList",
+ "Comment",
+ "DOMImplementation",
+ "DOMParser",
+ "DOMSettableTokenList",
+ "DelayNode",
+ "DocumentFragment",
+ "DocumentType",
+ "DynamicsCompressorNode",
+ "EventSource",
+ "FileHandle",
+ "FileList",
+ "FileReader",
+ "FormData",
+ "GainNode",
+ "ImageData",
+ "MozSmsFilter",
+ "MutationObserver",
+ "MutationRecord",
+ "PaintRequest",
+ "PaintRequestList",
+ "PannerNode",
+ "ProcessingInstruction",
+ "PropertyNodeList",
+ "RGBColor",
+ "Rect",
+ "TextDecoder",
+ "TextEncoder",
+ "WebGLActiveInfo",
+ "WebGLRenderingContext",
+ "WebGLShaderPrecisionFormat",
+ "WebSocket",
+ "XMLHttpRequest",
+ "XMLHttpRequestUpload",
+ "XMLSerializer",
+ "XPathEvaluator",
+ "XSLTProcessor",
+
+ "SVGAElement",
+ "SVGAltGlyphElement",
+ "SVGAngle",
+ "SVGAnimatedAngle",
+ "SVGAnimatedBoolean",
+ "SVGAnimatedEnumeration",
+ "SVGAnimatedInteger",
+ "SVGAnimatedLength",
+ "SVGAnimatedLengthList",
+ "SVGAnimatedNumber",
+ "SVGAnimatedNumberList",
+ "SVGAnimatedPathData",
+ "SVGAnimatedPoints",
+ "SVGAnimatedPreserveAspectRatio",
+ "SVGAnimatedRect",
+ "SVGAnimatedString",
+ "SVGAnimatedTransformList",
+ "SVGAnimateElement",
+ "SVGAnimateMotionElement",
+ "SVGAnimateTransformElement",
+ "SVGAnimationElement",
+ "SVGCircleElement",
+ "SVGClipPathElement",
+ "SVGComponentTransferFunctionElement",
+ "SVGDefsElement",
+ "SVGDescElement",
+ "SVGDocument",
+ "SVGElement",
+ "SVGEllipseElement",
+ "SVGFEBlendElement",
+ "SVGFEColorMatrixElement",
+ "SVGFEComponentTransferElement",
+ "SVGFECompositeElement",
+ "SVGFEConvolveMatrixElement",
+ "SVGFEDiffuseLightingElement",
+ "SVGFEDisplacementMapElement",
+ "SVGFEDistantLightElement",
+ "SVGFEFloodElement",
+ "SVGFEFuncAElement",
+ "SVGFEFuncBElement",
+ "SVGFEFuncGElement",
+ "SVGFEFuncRElement",
+ "SVGFEGaussianBlurElement",
+ "SVGFEImageElement",
+ "SVGFEMergeElement",
+ "SVGFEMergeNodeElement",
+ "SVGFEMorphologyElement",
+ "SVGFEOffsetElement",
+ "SVGFEPointLightElement",
+ "SVGFESpecularLightingElement",
+ "SVGFESpotLightElement",
+ "SVGFETileElement",
+ "SVGFETurbulenceElement",
+ "SVGFilterElement",
+ "SVGFilterPrimitiveStandardAttributes",
+ "SVGFitToViewBox",
+ "SVGForeignObjectElement",
+ "SVGGElement",
+ "SVGGradientElement",
+ "SVGGraphicsElement",
+ "SVGImageElement",
+ "SVGLength",
+ "SVGLengthList",
+ "SVGLinearGradientElement",
+ "SVGLineElement",
+ "SVGLocatable",
+ "SVGLocatableElement",
+ "SVGMarkerElement",
+ "SVGMaskElement",
+ "SVGMatrix",
+ "SVGMetadataElement",
+ "SVGMpathElement",
+ "SVGMPathElement",
+ "SVGNumber",
+ "SVGNumberList",
+ "SVGPathElement",
+ "SVGPathSeg",
+ "SVGPathSegArcAbs",
+ "SVGPathSegArcRel",
+ "SVGPathSegClosePath",
+ "SVGPathSegCurvetoCubicAbs",
+ "SVGPathSegCurvetoCubicRel",
+ "SVGPathSegCurvetoCubicSmoothAbs",
+ "SVGPathSegCurvetoCubicSmoothRel",
+ "SVGPathSegCurvetoQuadraticAbs",
+ "SVGPathSegCurvetoQuadraticRel",
+ "SVGPathSegCurvetoQuadraticSmoothAbs",
+ "SVGPathSegCurvetoQuadraticSmoothRel",
+ "SVGPathSegLinetoAbs",
+ "SVGPathSegLinetoHorizontalAbs",
+ "SVGPathSegLinetoHorizontalRel",
+ "SVGPathSegLinetoRel",
+ "SVGPathSegLinetoVerticalAbs",
+ "SVGPathSegLinetoVerticalRel",
+ "SVGPathSegList",
+ "SVGPathSegMovetoAbs",
+ "SVGPathSegMovetoRel",
+ "SVGPatternElement",
+ "SVGPoint",
+ "SVGPointList",
+ "SVGPolygonElement",
+ "SVGPolylineElement",
+ "SVGPreserveAspectRatio",
+ "SVGRadialGradientElement",
+ "SVGRect",
+ "SVGRectElement",
+ "SVGScriptElement",
+ "SVGSetElement",
+ "SVGStopElement",
+ "SVGStringList",
+ "SVGStyleElement",
+ "SVGSVGElement",
+ "SVGSwitchElement",
+ "SVGSymbolElement",
+ "SVGTests",
+ "SVGTextContentElement",
+ "SVGTextElement",
+ "SVGTextPathElement",
+ "SVGTextPositioningElement",
+ "SVGTitleElement",
+ "SVGTransform",
+ "SVGTransformable",
+ "SVGTransformableElement",
+ "SVGTransformList",
+ "SVGTSpanElement",
+ "SVGUnitTypes",
+ "SVGURIReference",
+ "SVGUseElement",
+ "SVGViewElement",
+
+ "XULButtonElement",
+ "XULCheckboxElement",
+ "XULCommandDispatcher",
+ "XULContainerElement",
+ "XULContainerItemElement",
+ "XULControlElement",
+ "XULDescriptionElement",
+ "XULDocument",
+ "XULImageElement",
+ "XULLabelElement",
+ "XULLabeledControlElement",
+ "XULMenuListElement",
+ "XULMultiSelectControlElement",
+ "XULPopupElement",
+ "XULRelatedElement",
+ "XULSelectControlElement",
+ "XULSelectControlItemElement",
+ "XULTemplateBuilder",
+ "XULTextBoxElement",
+ "XULTreeBuilder",
+ "XULTreeElement",
+
+ "mozAudioContext",
+ "BrowserFeedWriter",
+ "CSS",
+ "DOMStringMap",
+ "WebGLBuffer",
+ "WebGLFramebuffer",
+ "WebGLProgram",
+ "WebGLRenderbuffer",
+ "WebGLShader",
+ "WebGLTexture",
+ "WebGLUniformLocation",
+ "mozContact",
+ "mozRTCIceCandidate",
+ "mozRTCPeerConnection",
+ "mozRTCSessionDescription",
+
+ "devicePixelRatio",
+ "external",
+ "mozIndexedDB",
+ "sidebar",
+ "getDefaultComputedStyle",
-domMemberMap.Object =
-[
- "arguments",
- "caller",
- "length",
- "name",
- "__defineGetter__",
- "__defineSetter__",
- "__lookupGetter__",
- "__lookupSetter__",
- "apply",
- "bind",
- "call",
- "constructor",
- "create",
- "defineProperties",
- "defineProperty",
- "freeze",
- "getOwnPropertyDescriptor",
- "getOwnPropertyNames",
- "getPrototypeOf",
- "hasOwnProperty",
- "isExtensible",
- "isFrozen",
- "isGenerator",
- "isPrototypeOf",
- "isSealed",
- "keys",
- "preventExtensions",
- "propertyIsEnumerable",
- "seal",
- "toLocaleString",
- "toSource",
- "toString",
- "unwatch",
- "valueOf",
- "watch"
+ "Infinity",
+ "NaN",
+ "undefined",
+ "eval"
];
domMemberMap.Location =
@@ -1231,6 +1640,7 @@ domMemberMap.Node =
"ownerDocument",
"parentNode",
+ "parentElement",
"offsetParent",
"nextSibling",
"previousSibling",
@@ -1238,6 +1648,7 @@ domMemberMap.Node =
"lastChild",
"childNodes",
"attributes",
+ "contains",
"dir",
"baseURI",
@@ -1273,6 +1684,7 @@ domMemberMap.Document = Arr.extendArray(domMemberMap.Node,
[
"documentElement",
"body",
+ "head",
"title",
"location",
"referrer",
@@ -1318,7 +1730,6 @@ domMemberMap.Document = Arr.extendArray(domMemberMap.Node,
"hasFocus",
"activeElement",
- /* These are also in domMemberMap.Element, but it reflects the real interface definition */
"getElementsByClassName",
"querySelector",
"querySelectorAll",
@@ -1403,7 +1814,25 @@ domMemberMap.Document = Arr.extendArray(domMemberMap.Node,
"normalizeDocument",
"getFeature",
"getUserData",
- "setUserData"
+ "setUserData",
+
+ "hidden",
+ "mozFullScreen",
+ "mozFullScreenElement",
+ "mozFullScreenEnabled",
+ "mozHidden",
+ "mozPointerLockElement",
+ "mozSyntheticDocument",
+ "mozVisibilityState",
+ "currentScript",
+ "scripts",
+ "visibilityState",
+ "caretPositionFromPoint",
+ "getItems",
+ "mozCancelFullScreen",
+ "mozExitPointerLock",
+ "mozSetImageElement",
+ "releaseCapture"
]);
domMemberMap.Element = Arr.extendArray(domMemberMap.Node,
@@ -1432,6 +1861,7 @@ domMemberMap.Element = Arr.extendArray(domMemberMap.Node,
"dispatchEvent",
"focus",
"blur",
+ "click",
"cloneNode",
"appendChild",
"insertBefore",
@@ -1486,10 +1916,30 @@ domMemberMap.Element = Arr.extendArray(domMemberMap.Node,
"querySelectorAll",
"scrollIntoView",
- "onLoad",//FF4.0
- "hidden",//FF4.0
- "setCapture",//FF4.0
- "releaseCapture"//FF4.0
+ "isContentEditable",
+ "dataset",
+ "contextMenu",
+ "accessKey",
+ "accessKeyLabel",
+ "outerHTML",
+ "properties",
+ "scrollLeftMax",
+ "scrollTopMax",
+ "insertAdjacentHTML",
+ "mozRequestFullScreen",
+ "mozRequestPointerLock",
+
+ "itemId",
+ "itemRef",
+ "itemScope",
+ "itemProp",
+ "itemType",
+ "itemValue",
+
+ "onload",
+ "hidden",
+ "setCapture",
+ "releaseCapture"
]);
domMemberMap.SVGElement = Arr.extendArray(domMemberMap.Element,
@@ -1619,6 +2069,8 @@ domMemberMap.HTMLAnchorElement = Arr.extendArray(domMemberMap.Element,
"type",
"rel",
"rev",
+ "ping",
+ "download",
"charset"
]);
@@ -1698,7 +2150,15 @@ domMemberMap.HTMLTableCellElement = Arr.extendArray(domMemberMap.Element,
domMemberMap.HTMLScriptElement = Arr.extendArray(domMemberMap.Element,
[
- "src"
+ "src",
+ "type",
+ "async",
+ "charset",
+ "crossOrigin",
+ "defer",
+ "event",
+ "htmlFor",
+ "text"
]);
domMemberMap.HTMLButtonElement = Arr.extendArray(domMemberMap.Element,
@@ -1710,6 +2170,19 @@ domMemberMap.HTMLButtonElement = Arr.extendArray(domMemberMap.Element,
"type",
"value",
+ "autofocus",
+ "formAction",
+ "formEnctype",
+ "formMethod",
+ "formNoValidate",
+ "formTarget",
+
+ "validity",
+ "validationMessage",
+ "willValidate",
+ "checkValidity",
+ "setCustomValidity",
+
"click"
]);
@@ -1754,6 +2227,24 @@ domMemberMap.HTMLInputElement = Arr.extendArray(domMemberMap.Element,
"placeholder",
"required",
+ "height",
+ "width",
+ "inputmode",
+ "max",
+ "min",
+ "step",
+ "selectionDirection",
+ "validity",
+ "validationMessage",
+ "willValidate",
+ "checkValidity",
+ "setCustomValidity",
+ "valueAsDate",
+ "valueAsNumber",
+ "mozIsTextField",
+ "stepUp",
+ "stepDown",
+
"click",
"select",
"setSelectionRange"
@@ -1776,6 +2267,10 @@ domMemberMap.HTMLFormElement = Arr.extendArray(domMemberMap.Element,
"text",
"url",
+ "checkValidity",
+ "noValidate",
+ "autocomplete",
+
"reset",
"submit"
]);
@@ -1805,6 +2300,7 @@ domMemberMap.Text = Arr.extendArray(domMemberMap.Node,
"insertData",
"replaceData",
"splitText",
+ "wholeText",
"substringData"
]);
@@ -1898,6 +2394,12 @@ var domConstantMap = Dom.domConstantMap =
"MEDIA_RULE": 1,
"FONT_FACE_RULE": 1,
"PAGE_RULE": 1,
+ "KEYFRAMES_RULE": 1,
+ "KEYFRAME_RULE": 1,
+ "MOZ_KEYFRAMES_RULE": 1,
+ "MOZ_KEYFRAME_RULE": 1,
+ "NAMESPACE_RULE": 1,
+ "SUPPORTS_RULE": 1,
"CAPTURING_PHASE": 1,
"AT_TARGET": 1,
diff --git a/trace/FBTrace/chrome/firebug/content/lib/domplate.js b/trace/FBTrace/chrome/firebug/content/lib/domplate.js
index c2ba7f3..bd19e29 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/domplate.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/domplate.js
@@ -134,7 +134,7 @@ DomplateTag.prototype =
var val = parseValue(args[name]);
readPartNames(val, this.vars);
- if (Str.hasPrefix(name, "on"))
+ if (name.lastIndexOf("on", 0) == 0)
{
var eventName = name.substr(2);
if (!this.listeners)
@@ -157,7 +157,7 @@ DomplateTag.prototype =
}
else
{
- if (name == "class" && this.attrs.hasOwnProperty(name) )
+ if (name == "class" && this.attrs.hasOwnProperty(name))
this.attrs[name] += " " + val;
else
this.attrs[name] = val;
@@ -230,6 +230,16 @@ DomplateTag.prototype =
return Str.escapeForElementAttribute(value);
}
+ function __attr__(name, valueParts)
+ {
+ // Will be called with valueParts = [,arg,arg,...], but we don't
+ // care that the first element is undefined.
+ if (valueParts.length === 2 && valueParts[1] === undefined)
+ return "";
+ var value = valueParts.join("");
+ return ' ' + name + '="' + __escape__(value) + '"';
+ }
+
function isArray(it)
{
return Object.prototype.toString.call(it) === "[object Array]";
@@ -318,12 +328,11 @@ DomplateTag.prototype =
if (name != "class")
{
var val = this.attrs[name];
- topBlock.push(', " ', name, '=\\""');
- addParts(val, ',', topBlock, info, true);
- topBlock.push(', "\\""');
+ topBlock.push(',__attr__("', name, '",[');
+ addParts(val, ',', topBlock, info, false);
+ topBlock.push('])');
}
}
-
if (this.listeners)
{
for (var i = 0; i < this.listeners.length; i += 2)
@@ -336,12 +345,12 @@ DomplateTag.prototype =
readPartNames(this.props[name], topOuts);
}
- if ( this.attrs.hasOwnProperty("class") || this.classes)
+ if (this.attrs.hasOwnProperty("class") || this.classes)
{
topBlock.push(', " class=\\""');
if (this.attrs.hasOwnProperty("class"))
addParts(this.attrs["class"], ',', topBlock, info, true);
- topBlock.push(', " "');
+ topBlock.push(', " "');
for (var name in this.classes)
{
topBlock.push(', (');
@@ -976,8 +985,8 @@ function creator(tag, cons)
{
var fn = function()
{
- var tag = arguments.callee.tag;
- var cons = arguments.callee.cons;
+ var tag = fn.tag;
+ var cons = fn.cons;
var newTag = new cons();
return newTag.merge(arguments, tag);
}
diff --git a/trace/FBTrace/chrome/firebug/content/lib/lib.js b/trace/FBTrace/chrome/firebug/content/lib/lib.js
index 26be09c..e6550d6 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/lib.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/lib.js
@@ -122,11 +122,6 @@ for (var p in Firefox)
FBL.deprecated = Deprecated.deprecated;
FBL.SourceLink = SourceLink.SourceLink;
-//FBL.ErrorCopy = FirebugReps.ErrorCopy;
-//FBL.ErrorMessageObj = FirebugReps.ErrorMessageObj;
-//FBL.EventCopy = Dom.EventCopy;
-//FBL.PropertyObj = FirebugReps.PropertyObj;
-
// deprecated
FBL.$ = function(id, doc)
{
@@ -164,4 +159,4 @@ FBL.reUpperCase = /[A-Z]/;
return FBL;
// ********************************************************************************************* //
-});
\ No newline at end of file
+});
diff --git a/trace/FBTrace/chrome/firebug/content/lib/object.js b/trace/FBTrace/chrome/firebug/content/lib/object.js
index 5656d57..d5dc624 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/object.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/object.js
@@ -80,13 +80,7 @@ Obj.hasProperties = function(ob, nonEnumProps, ownPropsOnly)
if (!nonEnumProps && !ownPropsOnly)
{
for (var name in ob)
- {
- // Try to access the property before declaring existing properties.
- // It's because some properties can't be read see:
- // issue 3843, https://bugzilla.mozilla.org/show_bug.cgi?id=455013
- var value = ob[name];
return true;
- }
return false;
}
@@ -103,13 +97,7 @@ Obj.hasProperties = function(ob, nonEnumProps, ownPropsOnly)
props = Object.keys(ob);
if (props.length)
- {
- // Try to access the property before declaring existing properties.
- // It's because some properties can't be read see:
- // issue 3843, https://bugzilla.mozilla.org/show_bug.cgi?id=455013
- var value = ob[props[0]];
return true;
- }
// Not interested in inherited properties, bail out.
if (ownPropsOnly)
diff --git a/trace/FBTrace/chrome/firebug/content/lib/options.js b/trace/FBTrace/chrome/firebug/content/lib/options.js
index f1155f8..47bd02f 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/options.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/options.js
@@ -62,7 +62,7 @@ const prefNames = // XXXjjb TODO distribute to modules
// DOM
"showUserProps", "showUserFuncs", "showDOMProps", "showDOMFuncs", "showDOMConstants",
"ObjectShortIteratorMax", "showEnumerableProperties", "showOwnProperties",
- "showInlineEventHandlers",
+ "showInlineEventHandlers", "showClosures",
// Layout
"showRulers",
diff --git a/trace/FBTrace/chrome/firebug/content/lib/string.js b/trace/FBTrace/chrome/firebug/content/lib/string.js
index c638a18..b82d517 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/string.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/string.js
@@ -110,6 +110,8 @@ e(0xfeff, "#65279", attr, text, white, editor); // ZERO WIDTH NO-BREAK SPACE
e(0x200d, "zwj", attr, text, white, editor);
e(0x200e, "lrm", attr, text, white, editor);
e(0x200f, "rlm", attr, text, white, editor);
+e(0x202d, "#8237", attr, text, white, editor); // left-to-right override
+e(0x202e, "#8238", attr, text, white, editor); // right-to-left override
// ********************************************************************************************* //
// Entity escaping
@@ -360,9 +362,9 @@ function unescapeEntities(str, lists)
// String escaping
var escapeForTextNode = Str.escapeForTextNode = createSimpleEscape("text", "normal");
-var escapeForHtmlEditor = Str.escapeForHtmlEditor = createSimpleEscape("editor", "normal");
var escapeForElementAttribute = Str.escapeForElementAttribute = createSimpleEscape("attributes", "normal");
-var escapeForCss = Str.escapeForCss = createSimpleEscape("css", "normal");
+Str.escapeForHtmlEditor = createSimpleEscape("editor", "normal");
+Str.escapeForCss = createSimpleEscape("css", "normal");
// deprecated compatibility functions
Str.deprecateEscapeHTML = createSimpleEscape("text", "normal");
diff --git a/trace/FBTrace/chrome/firebug/content/lib/wrapper.js b/trace/FBTrace/chrome/firebug/content/lib/wrapper.js
index 232365a..aefbc9a 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/wrapper.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/wrapper.js
@@ -16,10 +16,10 @@ var Wrapper = {};
Wrapper.getContentView = function(object)
{
- if (typeof(object) === "undefined" || object == null)
- return false;
+ if (typeof object !== "object" && typeof object !== "function")
+ return object;
- return (object.wrappedJSObject);
+ return object.wrappedJSObject;
}
Wrapper.unwrapObject = function(object)
@@ -96,9 +96,6 @@ Wrapper.unwrapIValueObject = function(scope, viewChrome)
Wrapper.ignoreVars =
{
- "__firebug__": 1,
- "eval": 1,
-
// We are forced to ignore Java-related variables, because
// trying to access them causes browser freeze
"sun": 1,
@@ -111,9 +108,9 @@ Wrapper.ignoreVars =
// internal firebug things XXXjjb todo we should privatize these
"_firebug": 1,
- "_createFirebugConsole": 1,
+ "_firebugUnwrappedDebuggerObject": 1,
+ "__fb_scopedVars": 1,
"_FirebugCommandLine": 1,
- "loadFirebugConsole": 1,
};
Wrapper.shouldIgnore = function(name)
diff --git a/trace/FBTrace/chrome/firebug/content/net/netDebugger.js b/trace/FBTrace/chrome/firebug/content/net/netDebugger.js
index e8bafc5..8789707 100644
--- a/trace/FBTrace/chrome/firebug/content/net/netDebugger.js
+++ b/trace/FBTrace/chrome/firebug/content/net/netDebugger.js
@@ -90,12 +90,14 @@ Breakpoint.prototype =
// The callbacks will set this if the condition is true or if the eval faults.
delete context.breakingCause;
- var rc = Firebug.CommandLine.evaluate(expr, context, null, context.window,
+ Firebug.CommandLine.evaluate(expr, context, null, context.window,
this.onEvaluateSucceeds, this.onEvaluateFails );
if (FBTrace.DBG_NET)
- FBTrace.sysout("net.evaluateCondition; rc " + rc, {expr: expr,scope: scope,
+ {
+ FBTrace.sysout("net.evaluateCondition", {expr: expr, scope: scope,
json: JSON.stringify(scope)});
+ }
return !!context.breakingCause;
}
diff --git a/trace/FBTrace/chrome/firebug/content/net/spy.js b/trace/FBTrace/chrome/firebug/content/net/spy.js
index 7387922..e084449 100644
--- a/trace/FBTrace/chrome/firebug/content/net/spy.js
+++ b/trace/FBTrace/chrome/firebug/content/net/spy.js
@@ -1009,6 +1009,13 @@ Firebug.Spy.XHR = domplate(Firebug.Rep,
{
try
{
+ if (!context.window)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("spy.resend; ERROR no context");
+ return;
+ }
+
// xxxHonza: must be done through Console RDP
var win = Wrapper.unwrapObject(context.window);
var request = new win.XMLHttpRequest();
diff --git a/trace/FBTrace/chrome/firebug/modules/firebug-service.js b/trace/FBTrace/chrome/firebug/modules/firebug-service.js
index 3ecc89f..84b9215 100644
--- a/trace/FBTrace/chrome/firebug/modules/firebug-service.js
+++ b/trace/FBTrace/chrome/firebug/modules/firebug-service.js
@@ -844,9 +844,11 @@ var fbs =
// make sure to unregister all the hooks
var hookNames = ["error", "script", "breakpoint", "debugger", "debug", "interrupt",
"throw", "topLevel", "function", "debug"];
- for each (var hook in hookNames)
+ for (var i=0; i<hookNames.length; i++)
{
- try {
+ var hook = hookNames[i];
+ try
+ {
jsd[hook + "Hook"] = null;
}
catch (exc)
@@ -1229,6 +1231,7 @@ var fbs =
}
bp.condition = condition;
+ delete bp.transformedCondition;
dispatch(debuggers, "onToggleBreakpoint", [sourceFile.href, lineNo, true, bp]);
@@ -3292,6 +3295,7 @@ var fbs =
if (props)
{
bp.condition = props.condition;
+ delete bp.transformedCondition;
bp.onTrue = props.onTrue;
bp.hitCount = props.hitCount;
if (bp.condition || bp.hitCount > 0)
@@ -4347,7 +4351,32 @@ function testBreakpoint(frame, bp)
var result = {};
frame.scope.refresh();
- if (frame.eval(bp.condition, "", 1, result))
+ // ugly hack for closure getter syntax
+ // (see also transformedCondition elsewhere in the code)
+ var cond = bp.condition;
+ if (cond.indexOf(".%") !== -1)
+ {
+ var frameScopeRoot = fbs.getOutermostScope(frame);
+ if (frameScopeRoot)
+ {
+ if (bp.transformedCondition && "__fb_scopedVars" in frameScopeRoot.wrappedJSObject)
+ {
+ // Fast path: everything is already prepared for us.
+ cond = bp.transformedCondition;
+ }
+ else
+ {
+ var debuggr = fbs.findDebugger(frame);
+ var context = debuggr.breakContext;
+ delete debuggr.breakContext;
+
+ cond = debuggr._temporaryTransformSyntax(cond, frameScopeRoot, context);
+ bp.transformedCondition = cond;
+ }
+ }
+ }
+
+ if (frame.eval(cond, "", 1, result))
{
if (bp.onTrue)
{
diff --git a/trace/FBTrace/chrome/firebug/modules/loader.js b/trace/FBTrace/chrome/firebug/modules/loader.js
index 7b9fd9e..07e74bc 100644
--- a/trace/FBTrace/chrome/firebug/modules/loader.js
+++ b/trace/FBTrace/chrome/firebug/modules/loader.js
@@ -74,8 +74,9 @@ var FirebugLoader =
var XPIProviderBP = Cu.import("resource://gre/modules/XPIProvider.jsm", {});
var bootstrapScopes = XPIProviderBP.XPIProvider.bootstrapScopes;
- for each(var scope in bootstrapScopes)
+ for (var id in bootstrapScopes)
{
+ var scope = bootstrapScopes[id];
try
{
if (scope.firebugStartup)
@@ -117,9 +118,12 @@ var FirebugLoader =
[getRoots(win.document), getRoots(win.gNavToolbox.palette),
fbug.browserOverlay.nodesToRemove].forEach(function(list)
{
- for each(var el in list)
+ for (var i=0; i<list.length; i++)
+ {
+ var el = list[i];
if (el && el.parentNode)
el.parentNode.removeChild(el);
+ }
});
win.Firebug.browserOverlay.unloadContextMenuOverlay(win);
@@ -166,8 +170,9 @@ var FirebugLoader =
dispatchToScopes: function(name, arguments)
{
- for each (var e in this.bootstrapScopes)
+ for (var id in this.bootstrapScopes)
{
+ var e = this.bootstrapScopes[id];
try
{
if (name in e)
diff --git a/trace/FBTrace/chrome/firebug/modules/prefLoader.js b/trace/FBTrace/chrome/firebug/modules/prefLoader.js
index e40ff59..8c546d5 100644
--- a/trace/FBTrace/chrome/firebug/modules/prefLoader.js
+++ b/trace/FBTrace/chrome/firebug/modules/prefLoader.js
@@ -59,8 +59,9 @@ function clearDefaultPrefs(domain)
var pb = Services.prefs.getDefaultBranch(domain);
var names = pb.getChildList("");
- for each (var name in names)
+ for (var i=0; i<names.length; i++)
{
+ var name = names[i];
if (!pb.prefHasUserValue(name))
pb.deleteBranch(name);
}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/console.css b/trace/FBTrace/chrome/firebug/skin/classic/console.css
index 289cfaf..490eb94 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/console.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/console.css
@@ -166,6 +166,13 @@
color: #787878;
}
+.objectBox-scope {
+ color: #707070;
+}
+.objectBox-optimizedAway {
+ color: #909090;
+}
+
.objectLink-sourceLink {
position: absolute;
right: 4px;
@@ -436,7 +443,16 @@
}
.logRow-help .commandDesc {
- color: gray
+ color: gray;
+}
+
+.logRow-help .tipsContent .tip {
+ margin-bottom: 5px;
+}
+
+.logRow-help .tipsContent .tip .example {
+ color: green;
+ font-family: monospace;
}
/*************************************************************************************************/
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/firebug.git
More information about the Pkg-mozext-commits
mailing list