diff --git a/Libraries/Inspector/ElementProperties.js b/Libraries/Inspector/ElementProperties.js
index 1e808d0d172905..bbbf248407c304 100644
--- a/Libraries/Inspector/ElementProperties.js
+++ b/Libraries/Inspector/ElementProperties.js
@@ -20,6 +20,8 @@ var Text = require('Text');
var TouchableHighlight = require('TouchableHighlight');
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
var View = require('View');
+var {SourceCode} = require('NativeModules');
+var {fetch} = require('fetch');
var flattenStyle = require('flattenStyle');
var mapWithSeparator = require('mapWithSeparator');
@@ -32,11 +34,31 @@ var ElementProperties = React.createClass({
PropTypes.array,
PropTypes.number,
]),
+ source: PropTypes.shape({
+ fileName: PropTypes.string,
+ lineNumber: PropTypes.number,
+ }),
},
render: function() {
var style = flattenStyle(this.props.style);
var selection = this.props.selection;
+ var openFileButton;
+ var source = this.props.source;
+ var {fileName, lineNumber} = source || {};
+ if (fileName && lineNumber) {
+ var parts = fileName.split('/');
+ var fileNameShort = parts[parts.length - 1];
+ openFileButton = (
+
+
+ {fileNameShort}:{lineNumber}
+
+
+ );
+ }
// Without the `TouchableWithoutFeedback`, taps on this inspector pane
// would change the inspected element to whatever is under the inspector
return (
@@ -63,13 +85,26 @@ var ElementProperties = React.createClass({
)}
-
+
+
+ {openFileButton}
+
);
- }
+ },
+
+ _openFile: function(fileName: string, lineNumber: number) {
+ var match = SourceCode.scriptURL && SourceCode.scriptURL.match(/^https?:\/\/.*?\//);
+ var baseURL = match ? match[0] : 'http://localhost:8081/';
+
+ fetch(baseURL + 'open-stack-frame', {
+ method: 'POST',
+ body: JSON.stringify({file: fileName, lineNumber}),
+ });
+ },
});
var styles = StyleSheet.create({
@@ -101,6 +136,9 @@ var styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'space-between',
},
+ col: {
+ flex: 1,
+ },
info: {
padding: 10,
},
@@ -108,6 +146,17 @@ var styles = StyleSheet.create({
color: 'white',
fontSize: 9,
},
+ openButton: {
+ padding: 10,
+ backgroundColor: '#000',
+ marginVertical: 5,
+ marginRight: 5,
+ borderRadius: 2,
+ },
+ openButtonTitle: {
+ color: 'white',
+ fontSize: 8,
+ }
});
module.exports = ElementProperties;
diff --git a/Libraries/Inspector/Inspector.js b/Libraries/Inspector/Inspector.js
index 620f13be0fb31a..5d9b7b0727dcba 100644
--- a/Libraries/Inspector/Inspector.js
+++ b/Libraries/Inspector/Inspector.js
@@ -129,11 +129,13 @@ class Inspector extends React.Component {
// if we inspect a stateless component we can't use the getPublicInstance method
// therefore we use the internal _instance property directly.
var publicInstance = instance['_instance'] || {};
+ var source = instance._currentElement && instance._currentElement._source;
UIManager.measure(instance.getNativeNode(), (x, y, width, height, left, top) => {
this.setState({
inspected: {
frame: {left, top, width, height},
style: publicInstance.props ? publicInstance.props.style : {},
+ source,
},
selection: i,
});
@@ -149,6 +151,7 @@ class Inspector extends React.Component {
// therefore we use the internal _instance property directly.
var publicInstance = instance._instance || {};
var props = publicInstance.props || {};
+ var source = instance._currentElement && instance._currentElement._source;
this.setState({
panelPos: pointerY > Dimensions.get('window').height / 2 ? 'top' : 'bottom',
selection: hierarchy.length - 1,
@@ -156,6 +159,7 @@ class Inspector extends React.Component {
inspected: {
style: props.style || {},
frame,
+ source,
},
});
}
diff --git a/Libraries/Inspector/InspectorPanel.js b/Libraries/Inspector/InspectorPanel.js
index 0b62999d11e745..9078a8e46673e1 100644
--- a/Libraries/Inspector/InspectorPanel.js
+++ b/Libraries/Inspector/InspectorPanel.js
@@ -41,6 +41,7 @@ class InspectorPanel extends React.Component {