mirror of
https://github.com/status-im/react-native.git
synced 2025-02-10 08:26:23 +00:00
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:
parent
17be4c754e
commit
f203c5d78c
@ -20,6 +20,8 @@ var Text = require('Text');
|
|||||||
var TouchableHighlight = require('TouchableHighlight');
|
var TouchableHighlight = require('TouchableHighlight');
|
||||||
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
|
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
|
||||||
var View = require('View');
|
var View = require('View');
|
||||||
|
var {SourceCode} = require('NativeModules');
|
||||||
|
var {fetch} = require('fetch');
|
||||||
|
|
||||||
var flattenStyle = require('flattenStyle');
|
var flattenStyle = require('flattenStyle');
|
||||||
var mapWithSeparator = require('mapWithSeparator');
|
var mapWithSeparator = require('mapWithSeparator');
|
||||||
@ -32,11 +34,31 @@ var ElementProperties = React.createClass({
|
|||||||
PropTypes.array,
|
PropTypes.array,
|
||||||
PropTypes.number,
|
PropTypes.number,
|
||||||
]),
|
]),
|
||||||
|
source: PropTypes.shape({
|
||||||
|
fileName: PropTypes.string,
|
||||||
|
lineNumber: PropTypes.number,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var style = flattenStyle(this.props.style);
|
var style = flattenStyle(this.props.style);
|
||||||
var selection = this.props.selection;
|
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
|
// Without the `TouchableWithoutFeedback`, taps on this inspector pane
|
||||||
// would change the inspected element to whatever is under the inspector
|
// would change the inspected element to whatever is under the inspector
|
||||||
return (
|
return (
|
||||||
@ -63,13 +85,26 @@ var ElementProperties = React.createClass({
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
|
<View style={styles.col}>
|
||||||
<StyleInspector style={style} />
|
<StyleInspector style={style} />
|
||||||
|
{openFileButton}
|
||||||
|
</View>
|
||||||
<BoxInspector style={style} frame={this.props.frame} />
|
<BoxInspector style={style} frame={this.props.frame} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</TouchableWithoutFeedback>
|
</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({
|
var styles = StyleSheet.create({
|
||||||
@ -101,6 +136,9 @@ var styles = StyleSheet.create({
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
},
|
},
|
||||||
|
col: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
info: {
|
info: {
|
||||||
padding: 10,
|
padding: 10,
|
||||||
},
|
},
|
||||||
@ -108,6 +146,17 @@ var styles = StyleSheet.create({
|
|||||||
color: 'white',
|
color: 'white',
|
||||||
fontSize: 9,
|
fontSize: 9,
|
||||||
},
|
},
|
||||||
|
openButton: {
|
||||||
|
padding: 10,
|
||||||
|
backgroundColor: '#000',
|
||||||
|
marginVertical: 5,
|
||||||
|
marginRight: 5,
|
||||||
|
borderRadius: 2,
|
||||||
|
},
|
||||||
|
openButtonTitle: {
|
||||||
|
color: 'white',
|
||||||
|
fontSize: 8,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = ElementProperties;
|
module.exports = ElementProperties;
|
||||||
|
@ -129,11 +129,13 @@ class Inspector extends React.Component {
|
|||||||
// if we inspect a stateless component we can't use the getPublicInstance method
|
// if we inspect a stateless component we can't use the getPublicInstance method
|
||||||
// therefore we use the internal _instance property directly.
|
// therefore we use the internal _instance property directly.
|
||||||
var publicInstance = instance['_instance'] || {};
|
var publicInstance = instance['_instance'] || {};
|
||||||
|
var source = instance._currentElement && instance._currentElement._source;
|
||||||
UIManager.measure(instance.getNativeNode(), (x, y, width, height, left, top) => {
|
UIManager.measure(instance.getNativeNode(), (x, y, width, height, left, top) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
inspected: {
|
inspected: {
|
||||||
frame: {left, top, width, height},
|
frame: {left, top, width, height},
|
||||||
style: publicInstance.props ? publicInstance.props.style : {},
|
style: publicInstance.props ? publicInstance.props.style : {},
|
||||||
|
source,
|
||||||
},
|
},
|
||||||
selection: i,
|
selection: i,
|
||||||
});
|
});
|
||||||
@ -149,6 +151,7 @@ class Inspector extends React.Component {
|
|||||||
// therefore we use the internal _instance property directly.
|
// therefore we use the internal _instance property directly.
|
||||||
var publicInstance = instance._instance || {};
|
var publicInstance = instance._instance || {};
|
||||||
var props = publicInstance.props || {};
|
var props = publicInstance.props || {};
|
||||||
|
var source = instance._currentElement && instance._currentElement._source;
|
||||||
this.setState({
|
this.setState({
|
||||||
panelPos: pointerY > Dimensions.get('window').height / 2 ? 'top' : 'bottom',
|
panelPos: pointerY > Dimensions.get('window').height / 2 ? 'top' : 'bottom',
|
||||||
selection: hierarchy.length - 1,
|
selection: hierarchy.length - 1,
|
||||||
@ -156,6 +159,7 @@ class Inspector extends React.Component {
|
|||||||
inspected: {
|
inspected: {
|
||||||
style: props.style || {},
|
style: props.style || {},
|
||||||
frame,
|
frame,
|
||||||
|
source,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ class InspectorPanel extends React.Component {
|
|||||||
<ElementProperties
|
<ElementProperties
|
||||||
style={this.props.inspected.style}
|
style={this.props.inspected.style}
|
||||||
frame={this.props.inspected.frame}
|
frame={this.props.inspected.frame}
|
||||||
|
source={this.props.inspected.source}
|
||||||
hierarchy={this.props.hierarchy}
|
hierarchy={this.props.hierarchy}
|
||||||
selection={this.props.selection}
|
selection={this.props.selection}
|
||||||
setSelection={this.props.setSelection}
|
setSelection={this.props.setSelection}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user