Bug 1397169 - Properly implement openLink; r=rickychien
MozReview-Commit-ID: HdelvmPW1Zm
--- a/devtools/client/dom/content/components/dom-tree.js
+++ b/devtools/client/dom/content/components/dom-tree.js
@@ -25,20 +25,21 @@ const PropTypes = React.PropTypes;
/**
* Renders DOM panel tree.
*/
var DomTree = React.createClass({
displayName: "DomTree",
propTypes: {
- object: PropTypes.any,
+ dispatch: PropTypes.func.isRequired,
filter: PropTypes.string,
- dispatch: PropTypes.func.isRequired,
grips: PropTypes.object,
+ object: PropTypes.any,
+ openLink: PropTypes.func,
},
/**
* Filter DOM properties. Return true if the object
* should be visible in the tree.
*/
onFilter: function (object) {
if (!this.props.filter) {
@@ -47,39 +48,47 @@ var DomTree = React.createClass({
return (object.name && object.name.indexOf(this.props.filter) > -1);
},
/**
* Render DOM panel content
*/
render: function () {
+ let {
+ dispatch,
+ grips,
+ object,
+ openLink,
+ } = this.props;
+
let columns = [{
"id": "value"
}];
// This is the integration point with Reps. The DomTree is using
// Reps to render all values. The code also specifies default rep
// used for data types that don't have its own specific template.
let renderValue = props => {
return Rep(Object.assign({}, props, {
defaultRep: Grip,
cropLimit: 50,
}));
};
return (
TreeView({
- object: this.props.object,
- provider: new GripProvider(this.props.grips, this.props.dispatch),
+ columns,
decorator: new DomDecorator(),
mode: MODE.SHORT,
- columns: columns,
- renderValue: renderValue,
- onFilter: this.onFilter
+ object,
+ onFilter: this.onFilter,
+ openLink,
+ provider: new GripProvider(grips, dispatch),
+ renderValue,
})
);
}
});
const mapStateToProps = (state) => {
return {
grips: state.grips,
--- a/devtools/client/dom/content/components/main-frame.js
+++ b/devtools/client/dom/content/components/main-frame.js
@@ -1,54 +1,62 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ /* globals DomProvider */
+
"use strict";
// React & Redux
const React = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
// DOM Panel
const DomTree = React.createFactory(require("./dom-tree"));
const MainToolbar = React.createFactory(require("./main-toolbar"));
// Shortcuts
const { div } = React.DOM;
const PropTypes = React.PropTypes;
/**
- * Renders basic layout of the DOM panel. The DOM panel cotent consists
+ * Renders basic layout of the DOM panel. The DOM panel content consists
* from two main parts: toolbar and tree.
*/
var MainFrame = React.createClass({
displayName: "MainFrame",
propTypes: {
- object: PropTypes.any,
+ dispatch: PropTypes.func.isRequired,
filter: PropTypes.string,
- dispatch: PropTypes.func.isRequired,
+ object: PropTypes.any,
},
/**
* Render DOM panel content
*/
render: function () {
+ let {
+ filter,
+ object,
+ } = this.props;
+
return (
div({className: "mainFrame"},
MainToolbar({
dispatch: this.props.dispatch,
object: this.props.object
}),
div({className: "treeTableBox"},
DomTree({
- object: this.props.object,
- filter: this.props.filter,
+ filter,
+ object,
+ openLink: url => DomProvider.openLink(url),
})
)
)
);
}
});
// Transform state into props
--- a/devtools/client/dom/content/dom-view.js
+++ b/devtools/client/dom/content/dom-view.js
@@ -56,10 +56,10 @@ DomView.prototype = {
if (typeof this[method] == "function") {
this[method](data.args);
}
},
};
// Construct DOM panel view object and expose it to tests.
-// Tests can access it throught: |panel.panelWin.view|
+// Tests can access it through: |panel.panelWin.view|
window.view = new DomView(store);
--- a/devtools/client/dom/dom-panel.js
+++ b/devtools/client/dom/dom-panel.js
@@ -62,18 +62,20 @@ DomPanel.prototype = {
initialize: function () {
this.panelWin.addEventListener("devtools/content/message",
this.onContentMessage, true);
this.target.on("navigate", this.onTabNavigated);
this._toolbox.on("select", this.onPanelVisibilityChange);
+ // Export provider object with useful API for DOM panel.
let provider = {
- getPrototypeAndProperties: this.getPrototypeAndProperties.bind(this)
+ getPrototypeAndProperties: this.getPrototypeAndProperties.bind(this),
+ openLink: this.openLink.bind(this),
};
exportIntoContentScope(this.panelWin, provider, "DomProvider");
this.shouldRefresh = true;
},
destroy: Task.async(function* () {
@@ -111,17 +113,17 @@ DomPanel.prototype = {
this.getRootGrip().then(rootGrip => {
this.postContentMessage("initialize", rootGrip);
});
},
/**
* Make sure the panel is refreshed when the page is reloaded.
- * The panel is refreshed immediatelly if it's currently selected
+ * The panel is refreshed immediately if it's currently selected
* or lazily when the user actually selects it.
*/
onTabNavigated: function () {
this.shouldRefresh = true;
this.refresh();
},
/**
@@ -172,16 +174,23 @@ DomPanel.prototype = {
}
});
this.pendingRequests.set(grip.actor, deferred.promise);
return deferred.promise;
},
+ openLink: function (url) {
+ let parentDoc = this._toolbox.doc;
+ let iframe = parentDoc.getElementById("this._toolbox");
+ let top = iframe.ownerDocument.defaultView.top;
+ top.openUILinkIn(url, "tab");
+ },
+
getRootGrip: function () {
let deferred = defer();
// Attach Console. It might involve RDP communication, so wait
// asynchronously for the result
this.target.activeConsole.evaluateJSAsync("window", res => {
deferred.resolve(res.result);
});