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 {