[Pkg-mozext-commits] [firebug] 18/82: Issue 5873: Closure inspector DOM panel integration
David Prévot
taffit at moszumanska.debian.org
Mon Mar 31 22:45:37 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 59c0339b223dd703a426a3ee3a11d16c44dceb33
Author: Simon Lindholm <simon.lindholm10 at gmail.com>
Date: Tue Dec 18 01:29:39 2012 +0100
Issue 5873: Closure inspector DOM panel integration
---
extension/content/firebug/chrome/reps.js | 32 +++++++
.../content/firebug/console/closureInspector.js | 83 ++++++++++++++++-
extension/content/firebug/dom/domPanel.js | 103 +++++++++++++++++----
extension/content/firebug/js/watchPanel.js | 3 +-
extension/content/firebug/lib/options.js | 2 +-
extension/defaults/preferences/firebug.js | 1 +
extension/locale/en-US/firebug.properties | 15 ++-
extension/skin/classic/console.css | 3 +
8 files changed, 218 insertions(+), 24 deletions(-)
diff --git a/extension/content/firebug/chrome/reps.js b/extension/content/firebug/chrome/reps.js
index dd9df92..ed3bfe0 100644
--- a/extension/content/firebug/chrome/reps.js
+++ b/extension/content/firebug/chrome/reps.js
@@ -3320,6 +3320,37 @@ 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 = Object.getPrototypeOf(object).scope;
+ 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,
@@ -3377,6 +3408,7 @@ Firebug.registerRep(
FirebugReps.NamedNodeMap,
FirebugReps.Reference,
FirebugReps.EventLog,
+ FirebugReps.ClosureScope,
FirebugReps.OptimizedAway
);
diff --git a/extension/content/firebug/console/closureInspector.js b/extension/content/firebug/console/closureInspector.js
index af04315..94730ee 100644
--- a/extension/content/firebug/console/closureInspector.js
+++ b/extension/content/firebug/console/closureInspector.js
@@ -18,6 +18,7 @@ function(Obj, Firebug, Wrapper) {
const Ci = Components.interfaces;
const Cu = Components.utils;
+const ScopeProxy = function() {};
const OptimizedAway = Object.create(null);
Object.freeze(OptimizedAway);
@@ -123,6 +124,7 @@ var ClosureInspector =
names.push("constructor");
}
+ // XXX keep a Map of scopes, and take the highest container of the first one or the (first) deepest one or something
for (var i = 0; i < names.length; ++i)
{
// We assume that the first own property, or the first
@@ -344,7 +346,86 @@ var ClosureInspector =
return Proxy.create(handler);
},
- extendLanguageSyntax: function (expr, win, context)
+ 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.scopeIsInteresting(scope))
+ return;
+ }
+ catch (exc)
+ {
+ if (FBTrace.DBG_COMMANDLINE)
+ FBTrace.sysout("ClosureInspector; getScopeWrapper failed", exc);
+ return;
+ }
+
+ var dbg = this.getInactiveDebuggerForContext(context);
+ var dwin = dbg.addDebuggee(win);
+
+ var scopeDataHolder = Object.create(ScopeProxy.prototype);
+ scopeDataHolder.scope = scope;
+
+ var names, namesSet;
+ var lazyCreateNames = function()
+ {
+ lazyCreateNames = function() {};
+ names = scope.names();
+ namesSet = new Set;
+ for (var i = 0; i < names.length; ++i)
+ namesSet.add(names[i]);
+ };
+
+ var self = this;
+ return Proxy.create({
+ desc: function(name)
+ {
+ if (!this.has(name))
+ return;
+ return {
+ get: function() {
+ var dval = self.getVariableOrOptimizedAway(scope, name);
+ if (self.isSimple(dval))
+ return dval;
+ var uwWin = Wrapper.getContentView(win);
+ return self.unwrap(uwWin, dwin, dval);
+ },
+ set: function(value) {
+ var dval = dwin.makeDebuggeeValue(value);
+ scope.setVariable(name, dval);
+ }
+ };
+ },
+ 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;
+ },
+
+ extendLanguageSyntax: function(expr, win, context)
{
var fname = "__fb_scopedVars";
diff --git a/extension/content/firebug/dom/domPanel.js b/extension/content/firebug/dom/domPanel.js
index eb0a25d..1829162 100644
--- a/extension/content/firebug/dom/domPanel.js
+++ b/extension/content/firebug/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) {
@@ -440,6 +441,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.
@@ -543,44 +546,47 @@ 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")
{
if (isClassFunction(val))
{
if (Dom.isDOMMember(object, name))
- this.addMember(object, "domClass", domClasses, name, val, level, domMembers[name], context);
+ this.addMember(object, "domClass", domClasses, name, val, level, domMembers[name], context, isScope);
else
- this.addMember(object, "userClass", userClasses, name, val, level, 0, context);
+ this.addMember(object, "userClass", userClasses, name, val, level, 0, context, isScope);
}
else if (Dom.isDOMMember(object, name))
{
- this.addMember(object, "domFunction", domFuncs, name, val, level, domMembers[name], context);
+ this.addMember(object, "domFunction", domFuncs, name, val, level, domMembers[name], 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)
{
@@ -675,7 +681,7 @@ 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 (= QI, for XPCOM things) reveals contents.
var rep = Firebug.getRep(value);
@@ -690,6 +696,18 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
(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.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.
hasChildren = hasChildren || (!!value && isArguments(value));
@@ -726,7 +744,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
prefix: "",
readOnly: (descriptor && !descriptor.writable && !descriptor.set),
// XXX should probably move the tests from getContextMenuItems here
- deletable: !(descriptor && !descriptor.configurable)
+ deletable: (!parentIsScope && !(descriptor && !descriptor.configurable))
};
// The context doesn't have to be specified (e.g. in case of Watch panel that is based
@@ -734,7 +752,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);
@@ -777,6 +795,38 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
return member;
},
+ // Add the magic "(closure)" property.
+ maybeAddClosureMember: function(object, type, props, level, context, isScope)
+ {
+ var win = 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 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: "",
+ readOnly: true,
+ deletable: false,
+ ignoredPath: true
+ };
+ props.push(member);
+ },
+
// recursion starts with offset=0, level=0
expandMembers: function (members, toggles, offset, level, context)
{
@@ -976,6 +1026,14 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
{
var member = row.domObject, name = member.name;
+ // Fake "(closure)" properties.
+ if (member.ignoredPath)
+ return ["", ""];
+
+ // Closure variables.
+ if (ClosureInspector.isScopeWrapper(member.object))
+ return [".%", name];
+
// Ordinals.
if (name.match(/^[\d]+$/))
return ["", "["+name+"]"];
@@ -1404,6 +1462,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];
@@ -1492,6 +1552,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");
@@ -1503,7 +1564,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",
@@ -1514,6 +1575,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"),
@@ -1534,7 +1597,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
var items = [];
- if (row && row.domObject)
+ if (row && row.domObject && !row.domObject.ignoredPath)
{
var member = row.domObject;
var rowName = member.name;
@@ -1882,6 +1945,8 @@ function getPropertyDescriptor(object, propName)
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;
}
@@ -1911,7 +1976,7 @@ function getParentRow(row)
}
}
-// Return an array of JS parts that build up (and uniquely identify) a row
+// Return an array of parts that uniquely identifies a row (not always all JavaScript)
function getPath(row)
{
var name = getRowName(row);
diff --git a/extension/content/firebug/js/watchPanel.js b/extension/content/firebug/js/watchPanel.js
index 8b74c21..aa29044 100644
--- a/extension/content/firebug/js/watchPanel.js
+++ b/extension/content/firebug/js/watchPanel.js
@@ -365,14 +365,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/extension/content/firebug/lib/options.js b/extension/content/firebug/lib/options.js
index f1155f8..47bd02f 100644
--- a/extension/content/firebug/lib/options.js
+++ b/extension/content/firebug/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/extension/defaults/preferences/firebug.js b/extension/defaults/preferences/firebug.js
index ecf0d48..969de18 100644
--- a/extension/defaults/preferences/firebug.js
+++ b/extension/defaults/preferences/firebug.js
@@ -103,6 +103,7 @@ pref("extensions.firebug.showDOMProps", true);
pref("extensions.firebug.showDOMFuncs", false);
pref("extensions.firebug.showDOMConstants", false);
pref("extensions.firebug.showInlineEventHandlers", false);
+pref("extensions.firebug.showClosures", false);
pref("extensions.firebug.ObjectShortIteratorMax", 3);
pref("extensions.firebug.showEnumerableProperties", true);
pref("extensions.firebug.showOwnProperties", false);
diff --git a/extension/locale/en-US/firebug.properties b/extension/locale/en-US/firebug.properties
index 48c459a..2d53464 100644
--- a/extension/locale/en-US/firebug.properties
+++ b/extension/locale/en-US/firebug.properties
@@ -222,6 +222,17 @@ html.tip.Break_On_Element_Removal=Stop JavaScript execution when the element is
# or collapse it.
html.label.Expand/Contract_All=Expand/Contract All
html.tip.Expand/Contract_All=Expand/collapse all the children recursively
+# LOCALIZATION NOTE (dom.scopeName): Used within the DOM panel to name the fake property that
+# contains the innermost closure scope of a function.
+dom.scopeName=(closure)
+# LOCALIZATION NOTE (dom.scopeParentName): Used within the DOM panel to name the fake property
+# that contains the parent of a closure scope.
+dom.scopeParentName=(parent scope)
+# LOCALIZATION NOTE (firebug.reps.declarativeScope, firebug.reps.objectScope, firebug.reps.withScope):
+# Labels shown to describe different types of closure scopes.
+firebug.reps.declarativeScope=[declarative scope]
+firebug.reps.objectScope=[object scope]
+firebug.reps.withScope=[with scope]
# LOCALIZATION NOTE (firebug.reps.optimizedAway): Label shown to denote a closure variable that has
# been optimized away.
firebug.reps.optimizedAway=(optimized away)
@@ -371,8 +382,10 @@ ShowDOMFuncs=Show DOM Functions
dom.option.tip.Show_DOM_Funcs=Show functions specified inside the DOM
ShowDOMConstants=Show DOM Constants
dom.option.tip.Show_DOM_Constants=Show constants specified inside the DOM
+ShowClosures=Show Closures
+dom.option.tip.Show_Closures=Show the closures associated with various functions (activates the debugger)
ShowInlineEventHandlers=Show Inline Event Handlers
-ShowInlineEventHandlersTooltip=Show available inline event handlers, that are not associated with a function
+ShowInlineEventHandlersTooltip=Show available inline event handlers that are not associated with functions
ShowOwnProperties=Show Own Properties Only
ShowOwnPropertiesTooltip=Don't show prototype chain
ShowEnumerableProperties=Show Enumerable Properties Only
diff --git a/extension/skin/classic/console.css b/extension/skin/classic/console.css
index 18ba6b5..e713648 100644
--- a/extension/skin/classic/console.css
+++ b/extension/skin/classic/console.css
@@ -166,6 +166,9 @@
color: #787878;
}
+.objectBox-scope {
+ color: #707070;
+}
.objectBox-optimizedAway {
color: #909090;
}
--
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