Back out 3d8d5d2cb384 (bug 980835) and 47bce8cc31b4 (bug 757866) for test failures
authorPhil Ringnalda <philringnalda@gmail.com>
Sat, 08 Mar 2014 17:33:50 -0800
changeset 190927 7231e8751ad5b69504a817c48faa403c0190eacc
parent 190926 3d8d5d2cb3848e413dabd47ed8bcc10d4464599c
child 190928 92284ece76a5b0aa7bad1380cb0a1deae18a5344
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs980835, 757866
milestone30.0a1
backs out3d8d5d2cb3848e413dabd47ed8bcc10d4464599c
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out 3d8d5d2cb384 (bug 980835) and 47bce8cc31b4 (bug 757866) for test failures
browser/devtools/framework/toolbox.js
browser/devtools/styleinspector/style-inspector.js
browser/devtools/webconsole/console-output.js
browser/devtools/webconsole/test/browser.ini
browser/devtools/webconsole/test/browser_webconsole_output_04.js
browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_01.js
browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_02.js
browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_03.js
browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_04.js
browser/devtools/webconsole/test/head.js
browser/devtools/webconsole/test/test-console-output-dom-elements.html
browser/devtools/webconsole/webconsole.js
browser/locales/en-US/chrome/browser/devtools/webconsole.properties
browser/themes/shared/devtools/webconsole.inc.css
toolkit/devtools/server/actors/highlighter.js
toolkit/devtools/server/actors/inspector.js
--- a/browser/devtools/framework/toolbox.js
+++ b/browser/devtools/framework/toolbox.js
@@ -460,17 +460,17 @@ Toolbox.prototype = {
   /**
    * Handle any custom key events.  Returns true if there was a custom key binding run
    * @param {string} toolId
    *        Which tool to run the command on (skip if not current)
    */
   fireCustomKey: function(toolId) {
     let toolDefinition = gDevTools.getToolDefinition(toolId);
 
-    if (toolDefinition.onkey &&
+    if (toolDefinition.onkey && 
         ((this.currentToolId === toolId) ||
           (toolId == "webconsole" && this.splitConsole))) {
       toolDefinition.onkey(this.getCurrentPanel(), this);
     }
   },
 
   /**
    * Build the buttons for changing hosts. Called every time
@@ -1088,27 +1088,37 @@ Toolbox.prototype = {
     }
   },
 
   /**
    * Initialize the inspector/walker/selection/highlighter fronts.
    * Returns a promise that resolves when the fronts are initialized
    */
   initInspector: function() {
-    if (!this._initInspector) {
-      this._initInspector = Task.spawn(function*() {
-        this._inspector = InspectorFront(this._target.client, this._target.form);
-        this._walker = yield this._inspector.getWalker();
+    let deferred = promise.defer();
+
+    if (!this._inspector) {
+      this._inspector = InspectorFront(this._target.client, this._target.form);
+      this._inspector.getWalker().then(walker => {
+        this._walker = walker;
         this._selection = new Selection(this._walker);
         if (this.highlighterUtils.isRemoteHighlightable) {
-          this._highlighter = yield this._inspector.getHighlighter();
+          this._inspector.getHighlighter().then(highlighter => {
+            this._highlighter = highlighter;
+            deferred.resolve();
+          });
+        } else {
+          deferred.resolve();
         }
-      }.bind(this));
+      });
+    } else {
+      deferred.resolve();
     }
-    return this._initInspector;
+
+    return deferred.promise;
   },
 
   /**
    * Destroy the inspector/walker/selection fronts
    * Returns a promise that resolves when the fronts are destroyed
    */
   destroyInspector: function() {
     if (!this._inspector) {
--- a/browser/devtools/styleinspector/style-inspector.js
+++ b/browser/devtools/styleinspector/style-inspector.js
@@ -85,20 +85,16 @@ function RuleViewTool(aInspector, aWindo
 
   this.onSelect();
 }
 
 exports.RuleViewTool = RuleViewTool;
 
 RuleViewTool.prototype = {
   onSelect: function RVT_onSelect(aEvent) {
-    if (!this.view) {
-      // Skip the event if RuleViewTool has been destroyed.
-      return;
-    }
     this.view.setPageStyle(this.inspector.pageStyle);
 
     if (!this.inspector.selection.isConnected() ||
         !this.inspector.selection.isElementNode()) {
       this.view.highlight(null);
       return;
     }
 
@@ -157,20 +153,16 @@ function ComputedViewTool(aInspector, aW
   this.onSelect();
 }
 
 exports.ComputedViewTool = ComputedViewTool;
 
 ComputedViewTool.prototype = {
   onSelect: function CVT_onSelect(aEvent)
   {
-    if (!this.view) {
-      // Skip the event if ComputedViewTool has been destroyed.
-      return;
-    }
     this.view.setPageStyle(this.inspector.pageStyle);
 
     if (!this.inspector.selection.isConnected() ||
         !this.inspector.selection.isElementNode()) {
       this.view.highlight(null);
       return;
     }
 
--- a/browser/devtools/webconsole/console-output.js
+++ b/browser/devtools/webconsole/console-output.js
@@ -4,18 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const {Cc, Ci, Cu} = require("chrome");
 
 loader.lazyImporter(this, "VariablesView", "resource:///modules/devtools/VariablesView.jsm");
 loader.lazyImporter(this, "escapeHTML", "resource:///modules/devtools/VariablesView.jsm");
-loader.lazyImporter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm");
-loader.lazyImporter(this, "Task","resource://gre/modules/Task.jsm");
 
 const Heritage = require("sdk/core/heritage");
 const XHTML_NS = "http://www.w3.org/1999/xhtml";
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const STRINGS_URI = "chrome://browser/locale/devtools/webconsole.properties";
 
 const WebConsoleUtils = require("devtools/toolkit/webconsole/utils").Utils;
 const l10n = new WebConsoleUtils.l10n(STRINGS_URI);
@@ -128,17 +126,17 @@ ConsoleOutput.prototype = {
     return this.owner.outputNode;
   },
 
   /**
    * The document that holds the output.
    * @type DOMDocument
    */
   get document() {
-    return this.owner ? this.owner.document : null;
+    return this.owner.document;
   },
 
   /**
    * The DOM window that holds the output.
    * @type Window
    */
   get window() {
     return this.owner.window;
@@ -148,24 +146,16 @@ ConsoleOutput.prototype = {
    * Getter for the debugger WebConsoleClient.
    * @type object
    */
   get webConsoleClient() {
     return this.owner.webConsoleClient;
   },
 
   /**
-   * Getter for the current toolbox debuggee target.
-   * @type Target
-   */
-  get toolboxTarget() {
-    return this.owner.owner.target;
-  },
-
-  /**
    * Release an actor.
    *
    * @private
    * @param string actorId
    *        The actor ID you want to release.
    */
   _releaseObject: function(actorId)
   {
@@ -512,25 +502,16 @@ Messages.BaseMessage.prototype = {
    * @private
    * @param Event event
    *        The DOM event that invoked this function.
    */
   _onClickAnchor: function(event)
   {
     this.output.openLink(event.target.href);
   },
-
-  destroy: function()
-  {
-    // Destroy all widgets that have registered themselves in this.widgets
-    for (let widget of this.widgets) {
-      widget.destroy();
-    }
-    this.widgets.clear();
-  }
 }; // Messages.BaseMessage.prototype
 
 
 /**
  * The NavigationMarker is used to show a page load event.
  *
  * @constructor
  * @extends Messages.BaseMessage
@@ -2031,17 +2012,16 @@ Widgets.ObjectRenderers.add({
     }
 
     switch (preview.nodeType) {
       case Ci.nsIDOMNode.DOCUMENT_NODE:
       case Ci.nsIDOMNode.ATTRIBUTE_NODE:
       case Ci.nsIDOMNode.TEXT_NODE:
       case Ci.nsIDOMNode.COMMENT_NODE:
       case Ci.nsIDOMNode.DOCUMENT_FRAGMENT_NODE:
-      case Ci.nsIDOMNode.ELEMENT_NODE:
         return true;
       default:
         return false;
     }
   },
 
   render: function()
   {
@@ -2060,19 +2040,16 @@ Widgets.ObjectRenderers.add({
         this._renderTextNode();
         break;
       case Ci.nsIDOMNode.COMMENT_NODE:
         this._renderCommentNode();
         break;
       case Ci.nsIDOMNode.DOCUMENT_FRAGMENT_NODE:
         this._renderDocumentFragmentNode();
         break;
-      case Ci.nsIDOMNode.ELEMENT_NODE:
-        this._renderElementNode();
-        break;
       default:
         throw new Error("Unsupported nodeType: " + preview.nodeType);
     }
   },
 
   _renderDocumentNode: function()
   {
     let fn = Widgets.ObjectRenderers.byKind.ObjectWithURL.prototype._renderElement;
@@ -2156,178 +2133,16 @@ Widgets.ObjectRenderers.add({
 
       let n = preview.childNodesLength - shown;
       let str = VariablesView.stringifiers._getNMoreString(n);
       this._anchor(str);
     }
 
     this._text(" ]");
   },
-
-  _renderElementNode: function()
-  {
-    let doc = this.document;
-    let {attributes, nodeName} = this.objectActor.preview;
-
-    this.element = this.el("span." + "kind-" + this.objectActor.preview.kind + ".elementNode");
-
-    let openTag = this.el("span.cm-tag");
-    openTag.textContent = "<";
-    this.element.appendChild(openTag);
-
-    let tagName = this._anchor(nodeName, {
-      className: "cm-tag",
-      appendTo: openTag
-    });
-
-    if (this.options.concise) {
-      if (attributes.id) {
-        tagName.appendChild(this.el("span.cm-attribute", "#" + attributes.id));
-      }
-      if (attributes.class) {
-        tagName.appendChild(this.el("span.cm-attribute", "." + attributes.class.split(" ").join(".")));
-      }
-    } else {
-      for (let name of Object.keys(attributes)) {
-        let attr = this._renderAttributeNode(" " + name, attributes[name]);
-        this.element.appendChild(attr);
-      }
-    }
-
-    let closeTag = this.el("span.cm-tag");
-    closeTag.textContent = ">";
-    this.element.appendChild(closeTag);
-
-    // Register this widget in the owner message so that it gets destroyed when
-    // the message is destroyed.
-    this.message.widgets.add(this);
-
-    this.linkToInspector();
-  },
-
-  /**
-   * If the DOMNode being rendered can be highlit in the page, this function
-   * will attach mouseover/out event listeners to do so, and the inspector icon
-   * to open the node in the inspector.
-   * @return a promise (always the same) that resolves when the node has been
-   * linked to the inspector, or rejects if it wasn't (either if no toolbox
-   * could be found to access the inspector, or if the node isn't present in the
-   * inspector, i.e. if the node is in a DocumentFragment or not part of the
-   * tree, or not of type Ci.nsIDOMNode.ELEMENT_NODE).
-   */
-  linkToInspector: function()
-  {
-    if (this._linkedToInspector) {
-      return this._linkedToInspector;
-    }
-
-    this._linkedToInspector = Task.spawn(function*() {
-      // Checking the node type
-      if (this.objectActor.preview.nodeType !== Ci.nsIDOMNode.ELEMENT_NODE) {
-        throw null;
-      }
-
-      // Checking the presence of a toolbox
-      let target = this.message.output.toolboxTarget;
-      this.toolbox = gDevTools.getToolbox(target);
-      if (!this.toolbox) {
-        throw null;
-      }
-
-      // Checking that the inspector supports the node
-      yield this.toolbox.initInspector();
-      this._nodeFront = yield this.toolbox.walker.getNodeActorFromObjectActor(this.objectActor.actor);
-      if (!this._nodeFront) {
-        throw null;
-      }
-
-      // At this stage, the message may have been cleared already
-      if (!this.document) {
-        throw null;
-      }
-
-      this.highlightDomNode = this.highlightDomNode.bind(this);
-      this.element.addEventListener("mouseover", this.highlightDomNode, false);
-      this.unhighlightDomNode = this.unhighlightDomNode.bind(this);
-      this.element.addEventListener("mouseout", this.unhighlightDomNode, false);
-
-      this._openInspectorNode = this._anchor("", {
-        className: "open-inspector",
-        onClick: this.openNodeInInspector.bind(this)
-      });
-      this._openInspectorNode.title = l10n.getStr("openNodeInInspector");
-    }.bind(this));
-
-    return this._linkedToInspector;
-  },
-
-  /**
-   * Highlight the DOMNode corresponding to the ObjectActor in the page.
-   * @return a promise that resolves when the node has been highlighted, or
-   * rejects if the node cannot be highlighted (detached from the DOM)
-   */
-  highlightDomNode: function()
-  {
-    return Task.spawn(function*() {
-      yield this.linkToInspector();
-      let isAttached = yield this.toolbox.walker.isInDOMTree(this._nodeFront);
-      if (isAttached) {
-        yield this.toolbox.highlighterUtils.highlightNodeFront(this._nodeFront);
-      } else {
-        throw null;
-      }
-    }.bind(this));
-  },
-
-  /**
-   * Unhighlight a previously highlit node
-   * @see highlightDomNode
-   * @return a promise that resolves when the highlighter has been hidden
-   */
-  unhighlightDomNode: function()
-  {
-    return this.linkToInspector().then(() => {
-      return this.toolbox.highlighterUtils.unhighlight();
-    });
-  },
-
-  /**
-   * Open the DOMNode corresponding to the ObjectActor in the inspector panel
-   * @return a promise that resolves when the inspector has been switched to
-   * and the node has been selected, or rejects if the node cannot be selected
-   * (detached from the DOM). Note that in any case, the inspector panel will
-   * be switched to.
-   */
-  openNodeInInspector: function()
-  {
-    return Task.spawn(function*() {
-      yield this.linkToInspector();
-      yield this.toolbox.selectTool("inspector");
-
-      let isAttached = yield this.toolbox.walker.isInDOMTree(this._nodeFront);
-      if (isAttached) {
-        let onReady = this.toolbox.inspector.once("inspector-updated");
-        yield this.toolbox.selection.setNodeFront(this._nodeFront, "console");
-        yield onReady;
-      } else {
-        throw null;
-      }
-    }.bind(this));
-  },
-
-  destroy: function()
-  {
-    if (this.toolbox && this._nodeFront) {
-      this.element.removeEventListener("mouseover", this.highlightDomNode, false);
-      this.element.removeEventListener("mouseout", this.unhighlightDomNode, false);
-      this._openInspectorNode.removeEventListener("mousedown", this.openNodeInInspector, true);
-      this.toolbox = null;
-      this._nodeFront = null;
-    }
-  },
 }); // Widgets.ObjectRenderers.byKind.DOMNode
 
 /**
  * The widget used for displaying generic JS object previews.
  */
 Widgets.ObjectRenderers.add({
   byKind: "Object",
 
--- a/browser/devtools/webconsole/test/browser.ini
+++ b/browser/devtools/webconsole/test/browser.ini
@@ -64,17 +64,16 @@ support-files =
   test-console-count.html
   test-console-count-external-file.js
   test-console-extras.html
   test-console-replaced-api.html
   test-console.html
   test-console-output-02.html
   test-console-output-03.html
   test-console-output-04.html
-  test-console-output-dom-elements.html
   test-console-output-events.html
   test-consoleiframes.html
   test-data.json
   test-data.json^headers^
   test-duplicate-error.html
   test-encoding-ISO-8859-1.html
   test-error.html
   test-eval-in-stackframe.html
@@ -262,17 +261,13 @@ run-if = os == "mac"
 [browser_webconsole_expandable_timestamps.js]
 [browser_webconsole_autocomplete_in_debugger_stackframe.js]
 [browser_webconsole_autocomplete_popup_close_on_tab_switch.js]
 [browser_console_hide_jsterm_when_devtools_chrome_enabled_false.js]
 [browser_webconsole_output_01.js]
 [browser_webconsole_output_02.js]
 [browser_webconsole_output_03.js]
 [browser_webconsole_output_04.js]
-[browser_webconsole_output_dom_elements_01.js]
-[browser_webconsole_output_dom_elements_02.js]
-[browser_webconsole_output_dom_elements_03.js]
-[browser_webconsole_output_dom_elements_04.js]
 [browser_webconsole_output_events.js]
 [browser_console_variables_view_highlighter.js]
 [browser_webconsole_start_netmon_first.js]
 [browser_webconsole_console_trace_duplicates.js]
 [browser_webconsole_cd_iframe.js]
--- a/browser/devtools/webconsole/test/browser_webconsole_output_04.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_04.js
@@ -24,17 +24,17 @@ let inputTests = [
     printOutput: "[object Comment]",
     inspectable: true,
     noClick: true,
   },
 
   // 2
   {
     input: "testDocumentFragment()",
-    output: 'DocumentFragment [ <div#foo1.bar>, <div#foo3> ]',
+    output: 'DocumentFragment [ <div#foo1>, <div#foo3> ]',
     printOutput: "[object DocumentFragment]",
     inspectable: true,
     variablesViewLabel: "DocumentFragment[2]",
   },
 
   // 3
   {
     input: "testError()",
deleted file mode 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_01.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// Test the webconsole output for various types of DOM Nodes.
-
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console-output-dom-elements.html";
-
-let inputTests = [
-  {
-    input: "testBodyNode()",
-    output: '<body id="body-id" class="body-class">',
-    printOutput: "[object HTMLBodyElement]",
-    inspectable: true,
-    noClick: true,
-    inspectorIcon: true
-  },
-
-  {
-    input: "testDocumentElement()",
-    output: '<html lang="en-US" dir="ltr">',
-    printOutput: "[object HTMLHtmlElement]",
-    inspectable: true,
-    noClick: true,
-    inspectorIcon: true
-  },
-
-  {
-    input: "testDocument()",
-    output: 'HTMLDocument \u2192 ' + TEST_URI,
-    printOutput: "[object HTMLDocument]",
-    inspectable: true,
-    noClick: true,
-    inspectorIcon: false
-  },
-
-  {
-    input: "testNode()",
-    output: '<p some-attribute="some-value">',
-    printOutput: "[object HTMLParagraphElement]",
-    inspectable: true,
-    noClick: true,
-    inspectorIcon: true
-  },
-
-  {
-    input: "testNodeList()",
-    output: 'NodeList [ <html>, <head>, <meta>, <title>, <body#body-id.body-class>, <p>, <iframe>, <script> ]',
-    printOutput: "[object NodeList]",
-    inspectable: true,
-    noClick: true,
-    inspectorIcon: true
-  },
-
-  {
-    input: "testNodeInIframe()",
-    output: '<p>',
-    printOutput: "[object HTMLParagraphElement]",
-    inspectable: true,
-    noClick: true,
-    inspectorIcon: true
-  },
-
-  {
-    input: "testDocumentFragment()",
-    output: 'DocumentFragment [ <span.foo>, <div#fragdiv> ]',
-    printOutput: "[object DocumentFragment]",
-    inspectable: true,
-    noClick: true,
-    inspectorIcon: false
-  },
-
-  {
-    input: "testNodeInDocumentFragment()",
-    output: '<span class="foo" data-lolz="hehe">',
-    printOutput: "[object HTMLSpanElement]",
-    inspectable: true,
-    noClick: true,
-    inspectorIcon: false
-  },
-
-  {
-    input: "testUnattachedNode()",
-    output: '<p class="such-class" data-data="such-data">',
-    printOutput: "[object HTMLParagraphElement]",
-    inspectable: true,
-    noClick: true,
-    inspectorIcon: false
-  }
-];
-
-function test() {
-  Task.spawn(function*() {
-    let {tab} = yield loadTab(TEST_URI);
-    let hud = yield openConsole(tab);
-    yield checkOutputForInputs(hud, inputTests);
-  }).then(finishTest);
-}
deleted file mode 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_02.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// Test the inspector links in the webconsole output for DOM Nodes actually
-// open the inspector and select the right node
-
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console-output-dom-elements.html";
-
-const TEST_DATA = [
-  {
-    // The first test shouldn't be returning the body element as this is the
-    // default selected node, so re-selecting it won't fire the inspector-updated
-    // event
-    input: "testNode()",
-    output: '<p some-attribute="some-value">'
-  },
-  {
-    input: "testBodyNode()",
-    output: '<body id="body-id" class="body-class">'
-  },
-  {
-    input: "testNodeInIframe()",
-    output: '<p>'
-  },
-  {
-    input: "testDocumentElement()",
-    output: '<html lang="en-US" dir="ltr">'
-  }
-];
-
-function test() {
-  Task.spawn(function*() {
-    let {tab} = yield loadTab(TEST_URI);
-    let hud = yield openConsole(tab);
-    let toolbox = gDevTools.getToolbox(hud.target);
-
-    // Loading the inspector panel at first, to make it possible to listen for
-    // new node selections
-    yield toolbox.selectTool("inspector");
-    let inspector = toolbox.getCurrentPanel();
-    yield toolbox.selectTool("webconsole");
-
-    info("Iterating over the test data");
-    for (let data of TEST_DATA) {
-      let [result] = yield jsEval(data.input, hud, {text: data.output});
-      let {widget, msg} = yield getWidgetAndMessage(result);
-
-      let inspectorIcon = msg.querySelector(".open-inspector");
-      ok(inspectorIcon, "Inspector icon found in the ElementNode widget");
-
-      info("Clicking on the inspector icon and waiting for the inspector to be selected");
-      let onInspectorSelected = toolbox.once("inspector-selected");
-      let onInspectorUpdated = inspector.once("inspector-updated");
-
-      EventUtils.synthesizeMouseAtCenter(inspectorIcon, {},
-        inspectorIcon.ownerDocument.defaultView);
-      yield onInspectorSelected;
-      yield onInspectorUpdated;
-      ok(true, "Inspector selected and new node got selected");
-
-      let rawNode = content.wrappedJSObject[data.input.replace(/\(\)/g, "")]();
-      is(inspector.selection.node.wrappedJSObject, rawNode,
-         "The current inspector selection is correct");
-
-      info("Switching back to the console");
-      yield toolbox.selectTool("webconsole");
-    }
-  }).then(finishTest);
-}
-
-function jsEval(input, hud, message) {
-  info("Executing '" + input + "' in the web console");
-
-  hud.jsterm.clearOutput();
-  hud.jsterm.execute(input);
-
-  return waitForMessages({
-    webconsole: hud,
-    messages: [message]
-  });
-}
-
-function* getWidgetAndMessage(result) {
-  info("Getting the output ElementNode widget");
-
-  let msg = [...result.matched][0];
-  let widget = [...msg._messageObject.widgets][0];
-  ok(widget, "ElementNode widget found in the output");
-
-  info("Waiting for the ElementNode widget to be linked to the inspector");
-  yield widget.linkToInspector();
-
-  return {widget: widget, msg: msg};
-}
deleted file mode 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_03.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// Test that inspector links in webconsole outputs for DOM Nodes highlight
-// the actual DOM Nodes on hover
-
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console-output-dom-elements.html";
-
-function test() {
-  Task.spawn(function*() {
-    let {tab} = yield loadTab(TEST_URI);
-    let hud = yield openConsole(tab);
-    let toolbox = gDevTools.getToolbox(hud.target);
-
-    // Loading the inspector panel at first, to make it possible to listen for
-    // new node selections
-    yield toolbox.loadTool("inspector");
-    let inspector = toolbox.getPanel("inspector");
-
-    info("Executing 'testNode()' in the web console to output a DOM Node");
-    let [result] = yield jsEval("testNode()", hud, {
-      text: '<p some-attribute="some-value">'
-    });
-
-    let elementNodeWidget = yield getWidget(result);
-
-    let nodeFront = yield hoverOverWidget(elementNodeWidget, toolbox);
-    let attrs = nodeFront.attributes;
-    is(nodeFront.tagName, "P", "The correct node was highlighted");
-    is(attrs[0].name, "some-attribute", "The correct node was highlighted");
-    is(attrs[0].value, "some-value", "The correct node was highlighted");
-  }).then(finishTest);
-}
-
-function jsEval(input, hud, message) {
-  hud.jsterm.execute(input);
-  return waitForMessages({
-    webconsole: hud,
-    messages: [message]
-  });
-}
-
-function* getWidget(result) {
-  info("Getting the output ElementNode widget");
-
-  let msg = [...result.matched][0];
-  let elementNodeWidget = [...msg._messageObject.widgets][0];
-  ok(elementNodeWidget, "ElementNode widget found in the output");
-
-  info("Waiting for the ElementNode widget to be linked to the inspector");
-  yield elementNodeWidget.linkToInspector();
-
-  return elementNodeWidget;
-}
-
-function* hoverOverWidget(widget, toolbox) {
-  info("Hovering over the output to highlight the node");
-
-  let onHighlight = toolbox.once("node-highlight");
-  EventUtils.sendMouseEvent({type: "mouseover"}, widget.element,
-    widget.element.ownerDocument.defaultView);
-  let nodeFront = yield onHighlight;
-  ok(true, "The highlighter was shown on a node");
-  return nodeFront;
-}
deleted file mode 100644
--- a/browser/devtools/webconsole/test/browser_webconsole_output_dom_elements_04.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// Test that inspector links in the webconsole output for DOM Nodes do not try
-// to highlight or select nodes once they have been detached
-
-const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console-output-dom-elements.html";
-
-const TEST_DATA = [
-  {
-    // The first test shouldn't be returning the body element as this is the
-    // default selected node, so re-selecting it won't fire the inspector-updated
-    // event
-    input: "testNode()",
-    output: '<p some-attribute="some-value">'
-  },
-  {
-    input: "testBodyNode()",
-    output: '<body id="body-id" class="body-class">'
-  },
-  {
-    input: "testNodeInIframe()",
-    output: '<p>'
-  },
-  {
-    input: "testDocumentElement()",
-    output: '<html lang="en-US" dir="ltr">'
-  }
-];
-
-const PREF = "devtools.webconsole.persistlog";
-
-function test() {
-  Services.prefs.setBoolPref(PREF, true);
-  registerCleanupFunction(() => Services.prefs.clearUserPref(PREF));
-
-  Task.spawn(function*() {
-    let {tab} = yield loadTab(TEST_URI);
-    let hud = yield openConsole(tab);
-    let toolbox = gDevTools.getToolbox(hud.target);
-
-    info("Executing the test data");
-    let widgets = [];
-    for (let data of TEST_DATA) {
-      let [result] = yield jsEval(data.input, hud, {text: data.output});
-      let {widget} = yield getWidgetAndMessage(result);
-      widgets.push(widget);
-    }
-
-    info("Reloading the page");
-    yield reloadPage();
-
-    info("Iterating over the ElementNode widgets");
-    for (let widget of widgets) {
-      // Verify that openNodeInInspector rejects since the associated dom node
-      // doesn't exist anymore
-      yield widget.openNodeInInspector().then(() => {
-        ok(false, "The openNodeInInspector promise resolved");
-      }, () => {
-        ok(true, "The openNodeInInspector promise rejected as expected");
-      });
-      yield toolbox.selectTool("webconsole");
-
-      // Verify that highlightDomNode rejects too, for the same reason
-      yield widget.highlightDomNode().then(() => {
-        ok(false, "The highlightDomNode promise resolved");
-      }, () => {
-        ok(true, "The highlightDomNode promise rejected as expected");
-      });
-    }
-  }).then(finishTest);
-}
-
-function jsEval(input, hud, message) {
-  info("Executing '" + input + "' in the web console");
-  hud.jsterm.execute(input);
-  return waitForMessages({
-    webconsole: hud,
-    messages: [message]
-  });
-}
-
-function* getWidgetAndMessage(result) {
-  info("Getting the output ElementNode widget");
-
-  let msg = [...result.matched][0];
-  let widget = [...msg._messageObject.widgets][0];
-  ok(widget, "ElementNode widget found in the output");
-
-  info("Waiting for the ElementNode widget to be linked to the inspector");
-  yield widget.linkToInspector();
-
-  return {widget: widget, msg: msg};
-}
-
-function reloadPage() {
-  let def = promise.defer();
-  gBrowser.selectedBrowser.addEventListener("load", function onload() {
-    gBrowser.selectedBrowser.removeEventListener("load", onload, true);
-    def.resolve();
-  }, true);
-  content.location.reload();
-  return def.promise;
-}
--- a/browser/devtools/webconsole/test/head.js
+++ b/browser/devtools/webconsole/test/head.js
@@ -1309,20 +1309,16 @@ function whenDelayedStartupFinished(aWin
  *        builds).
  *
  *        - printOutput: string|RegExp, optional, expected output for
  *        |print(input)|. If this is not provided, printOutput = output.
  *
  *        - variablesViewLabel: string|RegExp, optional, the expected variables
  *        view label when the object is inspected. If this is not provided, then
  *        |output| is used.
- *
- *        - inspectorIcon: boolean, when true, the test runner expects the
- *        result widget to contain an inspectorIcon element (className
- *        open-inspector).
  */
 function checkOutputForInputs(hud, inputTests)
 {
   let eventHandlers = new Set();
 
   function* runner()
   {
     for (let [i, entry] of inputTests.entries()) {
@@ -1337,35 +1333,30 @@ function checkOutputForInputs(hud, input
 
   function* checkInput(entry)
   {
     yield checkConsoleLog(entry);
     yield checkPrintOutput(entry);
     yield checkJSEval(entry);
   }
 
-  function* checkConsoleLog(entry)
+  function checkConsoleLog(entry)
   {
     hud.jsterm.clearOutput();
     hud.jsterm.execute("console.log(" + entry.input + ")");
 
-    let [result] = yield waitForMessages({
+    return waitForMessages({
       webconsole: hud,
       messages: [{
         name: "console.log() output: " + entry.output,
         text: entry.output,
         category: CATEGORY_WEBDEV,
         severity: SEVERITY_LOG,
       }],
     });
-
-    if (typeof entry.inspectorIcon == "boolean") {
-      let msg = [...result.matched][0];
-      yield checkLinkToInspector(entry, msg);
-    }
   }
 
   function checkPrintOutput(entry)
   {
     hud.jsterm.clearOutput();
     hud.jsterm.execute("print(" + entry.input + ")");
 
     let printOutput = entry.printOutput || entry.output;
@@ -1389,23 +1380,20 @@ function checkOutputForInputs(hud, input
       webconsole: hud,
       messages: [{
         name: "JS eval output: " + entry.output,
         text: entry.output,
         category: CATEGORY_OUTPUT,
       }],
     });
 
-    let msg = [...result.matched][0];
     if (!entry.noClick) {
+      let msg = [...result.matched][0];
       yield checkObjectClick(entry, msg);
     }
-    if (typeof entry.inspectorIcon == "boolean") {
-      yield checkLinkToInspector(entry, msg);
-    }
   }
 
   function checkObjectClick(entry, msg)
   {
     let body = msg.querySelector(".body a") || msg.querySelector(".body");
     ok(body, "the message body");
 
     let deferred = promise.defer();
@@ -1420,39 +1408,16 @@ function checkOutputForInputs(hud, input
     if (entry.inspectable) {
       info("message body tagName '" + body.tagName +  "' className '" + body.className + "'");
       return deferred.promise; // wait for the panel to open if we need to.
     }
 
     return promise.resolve(null);
   }
 
-  function checkLinkToInspector(entry, msg)
-  {
-    let elementNodeWidget = [...msg._messageObject.widgets][0];
-    if (!elementNodeWidget) {
-      ok(!entry.inspectorIcon, "The message has no ElementNode widget");
-      return;
-    }
-
-    return elementNodeWidget.linkToInspector().then(() => {
-      // linkToInspector resolved, check for the .open-inspector element
-      if (entry.inspectorIcon) {
-        ok(msg.querySelectorAll(".open-inspector").length,
-          "The ElementNode widget is linked to the inspector");
-      } else {
-        ok(!msg.querySelectorAll(".open-inspector").length,
-          "The ElementNode widget isn't linked to the inspector");
-      }
-    }, () => {
-      // linkToInspector promise rejected, node not linked to inspector
-      ok(!entry.inspectorIcon, "The ElementNode widget isn't linked to the inspector");
-    });
-  }
-
   function onVariablesViewOpen(entry, deferred, event, view, options)
   {
     let label = entry.variablesViewLabel || entry.output;
     if (typeof label == "string" && options.label != label) {
       return;
     }
     if (label instanceof RegExp && !label.test(options.label)) {
       return;
deleted file mode 100644
--- a/browser/devtools/webconsole/test/test-console-output-dom-elements.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE HTML>
-<html dir="ltr" lang="en-US">
-<head>
-  <meta charset="utf-8">
-  <title>Test the web console output - 05</title>
-  <!--
-  - Any copyright is dedicated to the Public Domain.
-  - http://creativecommons.org/publicdomain/zero/1.0/
-  -->
-</head>
-<body class="body-class" id="body-id">
-  <p some-attribute="some-value">hello world!</p>
-  <iframe src="data:text/html,<p>hello from iframe</p>"></iframe>
-  <script type="text/javascript">
-function testBodyNode() {
-  return document.body;
-}
-
-function testDocumentElement() {
-  return document.documentElement;
-}
-
-function testDocument() {
-  return document;
-}
-
-function testNode() {
-  return document.querySelector("p");
-}
-
-function testNodeList() {
-  return document.querySelectorAll("*");
-}
-
-function testNodeInIframe() {
-  return document.querySelector("iframe").contentWindow.document.querySelector("p");
-}
-
-function testDocumentFragment() {
-  var frag = document.createDocumentFragment();
-
-  var span = document.createElement("span");
-  span.className = 'foo';
-  span.dataset.lolz = 'hehe';
-
-  var div = document.createElement('div')
-  div.id = 'fragdiv';
-
-  frag.appendChild(span);
-  frag.appendChild(div);
-
-  return frag;
-}
-
-function testNodeInDocumentFragment() {
-  var frag = testDocumentFragment();
-  return frag.firstChild;
-}
-
-function testUnattachedNode() {
-  var p = document.createElement("p");
-  p.className = "such-class";
-  p.dataset.data = "such-data";
-  return p;
-}
-  </script>
-</body>
-</html>
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -2357,20 +2357,16 @@ WebConsoleFrame.prototype = {
   /**
    * Remove a given message from the output.
    *
    * @param nsIDOMNode aNode
    *        The message node you want to remove.
    */
   removeOutputMessage: function WCF_removeOutputMessage(aNode)
   {
-    if (aNode._messageObject) {
-      aNode._messageObject.destroy();
-    }
-
     if (aNode._objectActors) {
       for (let actor of aNode._objectActors) {
         this._releaseObject(actor);
       }
       aNode._objectActors.clear();
     }
 
     if (aNode.category == CATEGORY_CSS ||
--- a/browser/locales/en-US/chrome/browser/devtools/webconsole.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/webconsole.properties
@@ -209,16 +209,11 @@ emptyPropertiesList=No properties to dis
 # when you hover the red bubble that shows how many times a message is repeated
 # in the web console output.
 # This is a semi-colon list of plural forms.
 # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # #1 number of message repeats
 # example: 3 repeats
 messageRepeats.tooltip2=#1 repeat;#1 repeats
 
-# LOCALIZATION NOTE (openNodeInInspector): the text that is displayed in a
-# tooltip when hovering over the inspector icon next to a DOM Node in the console
-# output
-openNodeInInspector=Click to select the node in the inspector
-
 # LOCALIZATION NOTE (cdFunctionInvalidArgument): the text that is displayed when
 # cd() is invoked with an invalid argument.
 cdFunctionInvalidArgument=Cannot cd() to the given window. Invalid argument.
--- a/browser/themes/shared/devtools/webconsole.inc.css
+++ b/browser/themes/shared/devtools/webconsole.inc.css
@@ -376,33 +376,16 @@ a {
   text-decoration: none;
 }
 
 .cm-s-mozilla a[class]:hover,
 .cm-s-mozilla a[class]:focus {
   text-decoration: underline;
 }
 
-/* Open DOMNode in inspector button */
-.open-inspector {
-  background: url("chrome://browser/skin/devtools/vview-open-inspector.png") no-repeat 0 0;
-  padding-left: 16px;
-  margin-left: 5px;
-  cursor: pointer;
-}
-
-.elementNode:hover .open-inspector,
-.open-inspector:hover {
-  background-position: -32px 0;
-}
-
-.open-inspector:active {
-  background-position: -16px 0;
-}
-
 /* Replace these values with CSS variables as available */
 .theme-dark .jsterm-input-container {
   background-color: #252c33; /* tabToolbarBackgroundColor */
   border-color: #14171a; /* mainBackgroundColor */
 }
 
 .theme-dark .jsterm-input-node {
   color: #a9bacb; /* textColor */
--- a/toolkit/devtools/server/actors/highlighter.js
+++ b/toolkit/devtools/server/actors/highlighter.js
@@ -78,17 +78,17 @@ let HighlighterActor = protocol.ActorCla
    * the highlighter instance to these nodes.
    *
    * @param NodeActor The node to be highlighted
    * @param Options See the request part for existing options. Note that not
    * all options may be supported by all types of highlighters. The simple
    * outline highlighter for instance does not scrollIntoView
    */
   showBoxModel: method(function(node, options={}) {
-    if (node && this._isNodeValidForHighlighting(node.rawNode)) {
+    if (this._isNodeValidForHighlighting(node.rawNode)) {
       this._boxModelHighlighter.show(node.rawNode, options);
     } else {
       this._boxModelHighlighter.hide();
     }
   }, {
     request: {
       node: Arg(0, "domnode"),
       scrollIntoView: Option(1)
--- a/toolkit/devtools/server/actors/inspector.js
+++ b/toolkit/devtools/server/actors/inspector.js
@@ -2046,76 +2046,36 @@ var WalkerActor = protocol.ActorClass({
     }
 
     // Need to force a release of this node, because those nodes can't
     // be accessed anymore.
     this.releaseNode(documentActor, { force: true });
   },
 
   /**
-   * Check if a node is attached to the DOM tree of the current page.
-   * @param {nsIDomNode} rawNode
-   * @return {Boolean} false if the node is removed from the tree or within a
-   * document fragment
-   */
-  _isInDOMTree: function(rawNode) {
-    let walker = documentWalker(rawNode, this.rootWin);
-    let current = walker.currentNode;
-
-    // Reaching the top of tree
-    while (walker.parentNode()) {
-      current = walker.currentNode;
-    }
-
-    // The top of the tree is a fragment or is not rootDoc, hence rawNode isn't
-    // attached
-    if (current.nodeType === Ci.nsIDOMNode.DOCUMENT_FRAGMENT_NODE ||
-        current !== this.rootDoc) {
-      return false;
-    }
-
-    // Otherwise the top of the tree is rootDoc, hence rawNode is in rootDoc
-    return true;
-  },
-
-  /**
-   * @see _isInDomTree
-   */
-  isInDOMTree: method(function(node) {
-    return node ? this._isInDOMTree(node.rawNode) : false;
-  }, {
-    request: { node: Arg(0, "domnode") },
-    response: { attached: RetVal("boolean") }
-  }),
-
-  /**
    * Given an ObjectActor (identified by its ID), commonly used in the debugger,
    * webconsole and variablesView, return the corresponding inspector's NodeActor
    */
   getNodeActorFromObjectActor: method(function(objectActorID) {
-    let debuggerObject = this.conn.getActor(objectActorID).obj;
+    let debuggerObject = this.conn.poolFor(objectActorID).get(objectActorID).obj;
     let rawNode = debuggerObject.unsafeDereference();
 
-    if (!this._isInDOMTree(rawNode)) {
-      return null;
-    }
-
     // This is a special case for the document object whereby it is considered
     // as document.documentElement (the <html> node)
     if (rawNode.defaultView && rawNode === rawNode.defaultView.document) {
       rawNode = rawNode.documentElement;
     }
 
     return this.attachElement(rawNode);
   }, {
     request: {
       objectActorID: Arg(0, "string")
     },
     response: {
-      nodeFront: RetVal("nullable:disconnectedNode")
+      nodeFront: RetVal("disconnectedNode")
     }
   }),
 });
 
 /**
  * Client side of the DOM walker.
  */
 var WalkerFront = exports.WalkerFront = protocol.FrontClass(WalkerActor, {
@@ -2243,17 +2203,17 @@ var WalkerFront = exports.WalkerFront = 
       return response.node;
     });
   }, {
     impl: "_querySelector"
   }),
 
   getNodeActorFromObjectActor: protocol.custom(function(objectActorID) {
     return this._getNodeActorFromObjectActor(objectActorID).then(response => {
-      return response ? response.node : null;
+      return response.node;
     });
   }, {
     impl: "_getNodeActorFromObjectActor"
   }),
 
   _releaseFront: function(node, force) {
     if (node.retained && !force) {
       node.reparent(null);