multiple files rendering
This commit is contained in:
parent
ebfd1fce0d
commit
7a164d9cdd
6 changed files with 66 additions and 29 deletions
|
@ -1,5 +1,6 @@
|
||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import escapeStringRegexp from 'escape-string-regexp';
|
||||||
|
|
||||||
class PreviewFrame extends React.Component {
|
class PreviewFrame extends React.Component {
|
||||||
|
|
||||||
|
@ -11,11 +12,12 @@ class PreviewFrame extends React.Component {
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
if (this.props.isPlaying !== prevProps.isPlaying) {
|
if (this.props.isPlaying !== prevProps.isPlaying) {
|
||||||
if (this.props.isPlaying) {
|
|
||||||
this.renderSketch();
|
this.renderSketch();
|
||||||
} else {
|
// if (this.props.isPlaying) {
|
||||||
this.clearPreview();
|
// this.renderSketch();
|
||||||
}
|
// } else {
|
||||||
|
// this.clearPreview();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.isPlaying && this.props.content !== prevProps.content) {
|
if (this.props.isPlaying && this.props.content !== prevProps.content) {
|
||||||
|
@ -28,22 +30,47 @@ class PreviewFrame extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
clearPreview() {
|
clearPreview() {
|
||||||
const doc = ReactDOM.findDOMNode(this).contentDocument;
|
const doc = ReactDOM.findDOMNode(this);
|
||||||
doc.write('');
|
doc.srcDoc = '';
|
||||||
doc.close();
|
}
|
||||||
|
|
||||||
|
injectLocalFiles() {
|
||||||
|
let htmlFile = this.props.htmlFile.content;
|
||||||
|
|
||||||
|
this.props.jsFiles.forEach(jsFile => {
|
||||||
|
const fileName = escapeStringRegexp(jsFile.name);
|
||||||
|
const fileRegex = new RegExp(`<script.*?src=('|")((\.\/)|\/)?${fileName}('|").*?>([\s\S]*?)<\/script>`, 'gmi');
|
||||||
|
htmlFile = htmlFile.replace(fileRegex, `<script>\n${jsFile.content}\n</script>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const htmlHead = htmlFile.match(/(?:<head.*?>)([\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 += '<link rel="stylesheet" type="text/css" href="/preview-styles.css" />\n';
|
||||||
|
htmlFile = htmlFile.replace(/(?:<head.*?>)([\s\S]*?)(?:<\/head>)/gmi, `<head>\n${htmlHeadContents}\n</head>`);
|
||||||
|
|
||||||
|
return htmlFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSketch() {
|
renderSketch() {
|
||||||
const doc = ReactDOM.findDOMNode(this).contentDocument;
|
const doc = ReactDOM.findDOMNode(this);
|
||||||
this.clearPreview();
|
if (this.props.isPlaying) {
|
||||||
ReactDOM.render(this.props.head, doc.head);
|
doc.srcdoc = this.injectLocalFiles();
|
||||||
const p5Script = doc.createElement('script');
|
} else {
|
||||||
p5Script.setAttribute('src', 'https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.min.js');
|
doc.srcdoc = '';
|
||||||
doc.body.appendChild(p5Script);
|
}
|
||||||
|
|
||||||
const sketchScript = doc.createElement('script');
|
// this.clearPreview();
|
||||||
sketchScript.textContent = this.props.content;
|
// ReactDOM.render(this.props.head, doc.head);
|
||||||
doc.body.appendChild(sketchScript);
|
// const p5Script = doc.createElement('script');
|
||||||
|
// p5Script.setAttribute('src', 'https://cdnjs.cloudflare.com/ajax/libs/
|
||||||
|
// p5.js/0.5.0/p5.min.js');
|
||||||
|
// doc.body.appendChild(p5Script);
|
||||||
|
|
||||||
|
// const sketchScript = doc.createElement('script');
|
||||||
|
// sketchScript.textContent = this.props.content;
|
||||||
|
// doc.body.appendChild(sketchScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFrameContents() {
|
renderFrameContents() {
|
||||||
|
@ -70,7 +97,11 @@ class PreviewFrame extends React.Component {
|
||||||
PreviewFrame.propTypes = {
|
PreviewFrame.propTypes = {
|
||||||
isPlaying: PropTypes.bool.isRequired,
|
isPlaying: PropTypes.bool.isRequired,
|
||||||
head: PropTypes.object.isRequired,
|
head: PropTypes.object.isRequired,
|
||||||
|
content: PropTypes.string.isRequired,
|
||||||
|
htmlFile: PropTypes.shape({
|
||||||
content: PropTypes.string.isRequired
|
content: PropTypes.string.isRequired
|
||||||
|
}),
|
||||||
|
jsFiles: PropTypes.array.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PreviewFrame;
|
export default PreviewFrame;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import * as FileActions from '../actions/files';
|
||||||
import * as IDEActions from '../actions/ide';
|
import * as IDEActions from '../actions/ide';
|
||||||
import * as PreferencesActions from '../actions/preferences';
|
import * as PreferencesActions from '../actions/preferences';
|
||||||
import * as ProjectActions from '../actions/project';
|
import * as ProjectActions from '../actions/project';
|
||||||
import { getFile } from '../reducers/files';
|
import { getFile, getHTMLFile, getJSFiles } from '../reducers/files';
|
||||||
|
|
||||||
class IDEView extends React.Component {
|
class IDEView extends React.Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -58,6 +58,9 @@ class IDEView extends React.Component {
|
||||||
files={this.props.files}
|
files={this.props.files}
|
||||||
/>
|
/>
|
||||||
<PreviewFrame
|
<PreviewFrame
|
||||||
|
htmlFile={this.props.htmlFile}
|
||||||
|
jsFiles={this.props.jsFiles}
|
||||||
|
files={this.props.files}
|
||||||
content={this.props.selectedFile.content}
|
content={this.props.selectedFile.content}
|
||||||
head={
|
head={
|
||||||
<link type="text/css" rel="stylesheet" href="/preview-styles.css" />
|
<link type="text/css" rel="stylesheet" href="/preview-styles.css" />
|
||||||
|
@ -100,13 +103,17 @@ IDEView.propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
content: PropTypes.string.isRequired
|
content: PropTypes.string.isRequired
|
||||||
}),
|
}),
|
||||||
setSelectedFile: PropTypes.func.isRequired
|
setSelectedFile: PropTypes.func.isRequired,
|
||||||
|
htmlFile: PropTypes.object.isRequired,
|
||||||
|
jsFiles: PropTypes.array.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {
|
return {
|
||||||
files: state.files,
|
files: state.files,
|
||||||
selectedFile: getFile(state.files, state.ide.selectedFile),
|
selectedFile: getFile(state.files, state.ide.selectedFile),
|
||||||
|
htmlFile: getHTMLFile(state.files),
|
||||||
|
jsFiles: getJSFiles(state.files),
|
||||||
ide: state.ide,
|
ide: state.ide,
|
||||||
preferences: state.preferences,
|
preferences: state.preferences,
|
||||||
user: state.user,
|
user: state.user,
|
||||||
|
|
|
@ -13,6 +13,7 @@ const defaultHTML =
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="sketch.js"></script>
|
<script src="sketch.js"></script>
|
||||||
|
@ -55,5 +56,7 @@ const files = (state = initialState, action) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getFile = (state, id) => state.filter(file => file.id === id)[0];
|
export const getFile = (state, id) => state.filter(file => file.id === id)[0];
|
||||||
|
export const getHTMLFile = (state) => state.filter(file => file.name.match(/.*html$/))[0];
|
||||||
|
export const getJSFiles = (state) => state.filter(file => file.name.match(/.*.js$/));
|
||||||
|
|
||||||
export default files;
|
export default files;
|
||||||
|
|
|
@ -8,17 +8,11 @@ const initialState = {
|
||||||
const ide = (state = initialState, action) => {
|
const ide = (state = initialState, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case ActionTypes.TOGGLE_SKETCH:
|
case ActionTypes.TOGGLE_SKETCH:
|
||||||
return {
|
return Object.assign({}, state, { isPlaying: !state.isPlaying });
|
||||||
isPlaying: !state.isPlaying
|
|
||||||
};
|
|
||||||
case ActionTypes.START_SKETCH:
|
case ActionTypes.START_SKETCH:
|
||||||
return {
|
return Object.assign({}, state, { isPlaying: true });
|
||||||
isPlaying: true
|
|
||||||
};
|
|
||||||
case ActionTypes.STOP_SKETCH:
|
case ActionTypes.STOP_SKETCH:
|
||||||
return {
|
return Object.assign({}, state, { isPlaying: false });
|
||||||
isPlaying: false
|
|
||||||
};
|
|
||||||
case ActionTypes.SET_SELECTED_FILE:
|
case ActionTypes.SET_SELECTED_FILE:
|
||||||
case ActionTypes.SET_PROJECT:
|
case ActionTypes.SET_PROJECT:
|
||||||
case ActionTypes.NEW_PROJECT:
|
case ActionTypes.NEW_PROJECT:
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
"connect-mongo": "^1.2.0",
|
"connect-mongo": "^1.2.0",
|
||||||
"cookie-parser": "^1.4.1",
|
"cookie-parser": "^1.4.1",
|
||||||
"dotenv": "^2.0.0",
|
"dotenv": "^2.0.0",
|
||||||
|
"escape-string-regexp": "^1.0.5",
|
||||||
"eslint-loader": "^1.3.0",
|
"eslint-loader": "^1.3.0",
|
||||||
"express": "^4.13.4",
|
"express": "^4.13.4",
|
||||||
"express-session": "^1.13.0",
|
"express-session": "^1.13.0",
|
||||||
|
|
|
@ -16,6 +16,7 @@ const defaultHTML =
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="sketch.js"></script>
|
<script src="sketch.js"></script>
|
||||||
|
|
Loading…
Reference in a new issue