mirror of
https://github.com/facebook/react.git
synced 2026-02-25 13:13:03 +00:00
196 lines
5.6 KiB
JavaScript
196 lines
5.6 KiB
JavaScript
var BenchmarkQueue = React.createClass({
|
|
propTypes: {
|
|
debug: React.PropTypes.bool,
|
|
onChange: React.PropTypes.func.isRequired,
|
|
initialQueue: React.PropTypes.array.isRequired,
|
|
maxTime: React.PropTypes.number,
|
|
onCompleteEach: React.PropTypes.func,
|
|
onError: React.PropTypes.func
|
|
},
|
|
|
|
getDefaultProps: function(){
|
|
return {
|
|
maxTime: 5
|
|
};
|
|
},
|
|
|
|
getInitialState: function(){
|
|
return {
|
|
queue: this.props.initialQueue.slice()
|
|
};
|
|
},
|
|
|
|
setItemState: function(state){
|
|
state.test = this.state.queue[0].test;
|
|
state.react = this.state.queue[0].react;
|
|
this.props.onChange(state);
|
|
},
|
|
|
|
handleContextReady: function(window){
|
|
var benchmark = window.Benchmark(window.exports);
|
|
benchmark.options.maxTime = this.props.maxTime; //DEBUG
|
|
|
|
var itemState = {
|
|
testRunnerURL: window.location.href,
|
|
|
|
name: window.exports.name,
|
|
platform: window.Benchmark.platform.description,
|
|
reactVersion: window.React.version,
|
|
|
|
isMinified: (function(){
|
|
var code = window.React.renderComponent.toString();
|
|
return code.indexOf(',') - code.indexOf('(') <= 2;
|
|
}())
|
|
};
|
|
|
|
this.setItemState(itemState);
|
|
|
|
var self = this;
|
|
benchmark.on('start error cycle complete', function(){
|
|
var stats = JSON.parse(JSON.stringify(benchmark.stats));
|
|
itemState.stats = stats;
|
|
itemState.isRunning = benchmark.running;
|
|
itemState.error = benchmark.error;
|
|
self.setItemState(itemState);
|
|
});
|
|
if (this.props.onError) {
|
|
benchmark.on('error', this.props.onError);
|
|
}
|
|
benchmark.on('complete', function(){
|
|
var queue = self.state.queue.slice();
|
|
var queueItem = queue.shift();
|
|
if (self.props.onCompleteEach) {
|
|
self.props.onCompleteEach(queueItem);
|
|
}
|
|
self.setState({ queue:queue });
|
|
});
|
|
benchmark.run({async:true});
|
|
},
|
|
|
|
shouldComponentUpdate: function(nextProps, nextState){
|
|
return nextState.queue.length < this.state.queue.length;
|
|
},
|
|
|
|
render: function(){
|
|
if (!(this.state.queue && this.state.queue.length > 0)){
|
|
return React.DOM.div({style:{display:'none'}});
|
|
}
|
|
return BrowserPerfRunnerContext({
|
|
debug: this.props.debug,
|
|
test: this.state.queue[0].test,
|
|
react: this.state.queue[0].react,
|
|
onReady: this.handleContextReady
|
|
});
|
|
}
|
|
});
|
|
|
|
var BrowserPerfRunnerContext = React.createClass({
|
|
|
|
propTypes: {
|
|
debug: React.PropTypes.bool,
|
|
test: function(object, key){
|
|
React.PropTypes.string.isRequired(object, key);
|
|
if (/\.jsx?$/i.test(object[key])) return;
|
|
throw Error('Expected `' + key + '` to be a test file name with extension `.js` or `.jsx`');
|
|
},
|
|
react: function(object, key){
|
|
React.PropTypes.string.isRequired(object, key);
|
|
if (/^(?:builds\/.+|edge|previous|(?:\d+\.){2}\d+)$/.test(object[key])) return;
|
|
throw Error('Expected `' + key + '` prop to be a valid react version string, build string or "edge" or "previous"');
|
|
},
|
|
onReady: React.PropTypes.func.isRequired
|
|
},
|
|
|
|
getInitialState: function(){
|
|
return {
|
|
testRunnerURL:'about:blank'
|
|
};
|
|
},
|
|
|
|
// _handleFrameError: function(error){
|
|
// console.error('BrowserPerfRunnerContext', error);
|
|
// },
|
|
//
|
|
// _handleFrameLoad: function(event){
|
|
// console.log('BrowserPerfRunnerContext', event);
|
|
// },
|
|
//
|
|
_handleMessage: function(event){
|
|
if (location.href.indexOf(event.origin) !== 0)
|
|
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message from ' + event.origin);
|
|
if (event.source.location.href.indexOf(this.state.testRunnerURL) === -1)
|
|
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message from ' + event.source.location.href);
|
|
if (event.data !== 'Ready!')
|
|
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message ' + JSON.stringify(event.data));
|
|
|
|
this.props.onReady(event.source);
|
|
},
|
|
|
|
_getTestRunnerURL: function(props){
|
|
return 'runner.html' +
|
|
'?' +
|
|
'debug=' + (props.debug ? 1 : 0) +
|
|
'&' +
|
|
'react=' + encodeURIComponent(props.react) +
|
|
'&' +
|
|
'test=' + encodeURIComponent(props.test)
|
|
},
|
|
|
|
_renderState: function(props){
|
|
return {
|
|
testRunnerURL: this._getTestRunnerURL(props)
|
|
};
|
|
},
|
|
|
|
componentDidMount: function(){
|
|
var node = this.refs.iframe.getDOMNode();
|
|
// node.onload = this._handleFrameLoad;
|
|
// node.onerror = this._handleFrameError;
|
|
if (window.addEventListener) {
|
|
window.addEventListener('message', this._handleMessage, false);
|
|
} else if (window.attachEvent) {
|
|
window.attachEvent('onmessage', this._handleMessage);
|
|
} else {
|
|
throw Error('cannot attach onmessage listener');
|
|
}
|
|
this.setState(this._renderState(this.props));
|
|
},
|
|
|
|
componentWillUnmount: function(){
|
|
if (window.removeEventListener) {
|
|
window.removeEventListener('message', this._handleMessage);
|
|
} else if (window.detachEvent) {
|
|
window.detachEvent('onmessage', this._handleMessage);
|
|
} else {
|
|
throw Error('cannot detach onmessage listener');
|
|
}
|
|
this.refs.iframe.getDOMNode().src = '';
|
|
},
|
|
|
|
componentWillReceiveProps: function(nextProps){
|
|
this.setState(this._renderState(nextProps));
|
|
},
|
|
|
|
shouldComponentUpdate: function(nextProps, nextState){
|
|
return nextState.testRunnerURL != this.state.testRunnerURL;
|
|
},
|
|
|
|
render: function(){
|
|
return (
|
|
React.DOM.iframe({
|
|
ref: 'iframe',
|
|
name: "BrowserPerfRunnerContextFrame",
|
|
style: this.style,
|
|
src: this.state.testRunnerURL
|
|
})
|
|
);
|
|
},
|
|
|
|
style: {
|
|
position: 'absolute',
|
|
right: '100%',
|
|
bottom: '100%'
|
|
}
|
|
|
|
});
|