[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("&nbsp"),
+            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