Add "Open file" button to elements inspector

Summary:
Depends on #6351

Now you can open file directly from Elements Inspector!

Credit for the original implementation goes to jaredly

![zcichu7kem](https://cloud.githubusercontent.com/assets/192222/14573876/cb100f6e-030c-11e6-925f-6a6dff510145.gif)

**Test plan**

Made sure it doesn't crash the app with or without #6351 (i.e. can be merged safely before #6351 gets in).
Closes https://github.com/facebook/react-native/pull/7005

Differential Revision: D3313714

Pulled By: frantic

fbshipit-source-id: 3b80abd3e81a0db5ca5136e2d2c94c775fa04f3a
This commit is contained in:
Alex Kotliarskyi 2016-05-17 20:55:28 -07:00 committed by Facebook Github Bot 0
parent 17be4c754e
commit f203c5d78c
3 changed files with 56 additions and 2 deletions

View File

@ -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 = (
<TouchableHighlight
style={styles.openButton}
onPress={this._openFile.bind(null, fileName, lineNumber)}>
<Text style={styles.openButtonTitle} numberOfLines={1}>
{fileNameShort}:{lineNumber}
</Text>
</TouchableHighlight>
);
}
// 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({
)}
</View>
<View style={styles.row}>
<StyleInspector style={style} />
<View style={styles.col}>
<StyleInspector style={style} />
{openFileButton}
</View>
<BoxInspector style={style} frame={this.props.frame} />
</View>
</View>
</TouchableWithoutFeedback>
);
}
},
_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;

View File

@ -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,
},
});
}

View File

@ -41,6 +41,7 @@ class InspectorPanel extends React.Component {
<ElementProperties
style={this.props.inspected.style}
frame={this.props.inspected.frame}
source={this.props.inspected.source}
hierarchy={this.props.hierarchy}
selection={this.props.selection}
setSelection={this.props.setSelection}