import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import escapeStringRegexp from 'escape-string-regexp';
import srcDoc from 'srcdoc-polyfill';
/**
* Stringify all of the console objects from an array for proxying
*/
function stringifyArgs(args) {
var newArgs = [];
// TODO this was forEach but when the array is [undefined] it wouldn't
// iterate over them
var i = 0, length = args.length, arg;
for(; i < length; i++) {
arg = args[i];
if (typeof arg === 'undefined') {
newArgs.push('undefined');
} else {
newArgs.push(stringify(arg));
}
}
return newArgs;
};
function hijackConsoleScript(lineOffset) {
return ``;
}
class PreviewFrame extends React.Component {
componentDidMount() {
if (this.props.isPlaying) {
this.renderFrameContents();
}
if (this.props.dispatchConsoleEvent) {
window.addEventListener('message', (msg) => {
if (msg.data.source === 'sketch') {
this.props.dispatchConsoleEvent(msg);
}
});
}
}
componentDidUpdate(prevProps) {
if (this.props.isPlaying !== prevProps.isPlaying) {
this.renderSketch();
}
if (this.props.isPlaying && this.props.content !== prevProps.content) {
this.renderSketch();
}
// I apologize for this, it is a hack.
if (this.props.isPlaying && this.props.files[0].id !== prevProps.files[0].id) {
this.renderSketch();
}
}
componentWillUnmount() {
ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(this).contentDocument.body);
}
clearPreview() {
const doc = ReactDOM.findDOMNode(this);
doc.srcDoc = '';
}
injectLocalFiles() {
let htmlFile = this.props.htmlFile.content;
// have to build the array manually because the spread operator is only
// one level down...
const jsFiles = [];
this.props.jsFiles.forEach(jsFile => {
const newJSFile = { ...jsFile };
let jsFileStrings = newJSFile.content.match(/(['"])((\\\1|.)*?)\1/gm);
jsFileStrings = jsFileStrings || [];
jsFileStrings.forEach(jsFileString => {
if (jsFileString.match(/^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json)('|")$/i)) {
const filePath = jsFileString.substr(1, jsFileString.length - 2);
let fileName = filePath;
if (fileName.match(/^\.\//)) {
fileName = fileName.substr(2, fileName.length - 1);
} else if (fileName.match(/^\//)) {
fileName = fileName.substr(1, fileName.length - 1);
}
this.props.files.forEach(file => {
if (file.name === fileName) {
newJSFile.content = newJSFile.content.replace(filePath, file.blobURL); // eslint-disable-line
}
});
}
});
jsFiles.push(newJSFile);
});
jsFiles.forEach(jsFile => {
const fileName = escapeStringRegexp(jsFile.name);
const fileRegex = new RegExp(`([\s\S]*?)<\/script>`, 'gmi');
htmlFile = htmlFile.replace(fileRegex, ``);
});
this.props.cssFiles.forEach(cssFile => {
const fileName = escapeStringRegexp(cssFile.name);
const fileRegex = new RegExp(``, 'gmi');
htmlFile = htmlFile.replace(fileRegex, ``);
});
if (this.props.textOutput || this.props.isTextOutputPlaying) {
const htmlHead = htmlFile.match(/(?:)([\s\S]*?)(?:<\/head>)/gmi);
const headRegex = new RegExp('head', 'i');
let htmlHeadContents = htmlHead[0].split(headRegex)[1];
htmlHeadContents = htmlHeadContents.slice(1, htmlHeadContents.length - 2);
htmlHeadContents += '\n';
htmlHeadContents += '\n';
htmlHeadContents += '\n';
htmlHeadContents += '';
htmlFile = htmlFile.replace(/(?:)([\s\S]*?)(?:<\/head>)/gmi, `\n${htmlHeadContents}\n`);
}
var lineOffset = htmlFile.substring(0, htmlFile.indexOf('