generate blob urls for text and json files
This commit is contained in:
parent
d262783ec1
commit
8c270c2ced
7 changed files with 44 additions and 5 deletions
|
@ -41,6 +41,7 @@ export const SET_SELECTED_FILE = 'SET_SELECTED_FILE';
|
||||||
export const SHOW_MODAL = 'SHOW_MODAL';
|
export const SHOW_MODAL = 'SHOW_MODAL';
|
||||||
export const HIDE_MODAL = 'HIDE_MODAL';
|
export const HIDE_MODAL = 'HIDE_MODAL';
|
||||||
export const CREATE_FILE = 'CREATE_FILE';
|
export const CREATE_FILE = 'CREATE_FILE';
|
||||||
|
export const SET_BLOB_URL = 'SET_BLOB_URL';
|
||||||
|
|
||||||
export const EXPAND_SIDEBAR = 'EXPAND_SIDEBAR';
|
export const EXPAND_SIDEBAR = 'EXPAND_SIDEBAR';
|
||||||
export const COLLAPSE_SIDEBAR = 'COLLAPSE_SIDEBAR';
|
export const COLLAPSE_SIDEBAR = 'COLLAPSE_SIDEBAR';
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import * as ActionTypes from '../../../constants';
|
import * as ActionTypes from '../../../constants';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import objectID from 'bson-objectid';
|
import objectID from 'bson-objectid';
|
||||||
|
import blobUtil from 'blob-util';
|
||||||
|
|
||||||
const ROOT_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:8000/api' : '/api';
|
const ROOT_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:8000/api' : '/api';
|
||||||
|
|
||||||
|
@ -222,3 +223,21 @@ export function hideFolderChildren(id) {
|
||||||
id
|
id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setBlobUrl(file, blobURL) {
|
||||||
|
return {
|
||||||
|
type: ActionTypes.SET_BLOB_URL,
|
||||||
|
name: file.name,
|
||||||
|
blobURL
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBlobUrl(file) {
|
||||||
|
if (file.blobUrl) {
|
||||||
|
blobUtil.revokeObjectURL(file.blobUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileBlob = blobUtil.createBlob([file.content], { type: 'text/plain' });
|
||||||
|
const blobURL = blobUtil.createObjectURL(fileBlob);
|
||||||
|
return blobURL;
|
||||||
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ function validate(formProps) {
|
||||||
|
|
||||||
if (!formProps.name) {
|
if (!formProps.name) {
|
||||||
errors.name = 'Please enter a name';
|
errors.name = 'Please enter a name';
|
||||||
} else if (!formProps.name.match(/(.+\.js$|.+\.css$|.+\.json$|.+\.txt)/i)) {
|
} else if (!formProps.name.match(/(.+\.js$|.+\.css$|.+\.json$|.+\.txt$)/i)) {
|
||||||
errors.name = 'File must be of type JavaScript, CSS, JSON, or TXT.';
|
errors.name = 'File must be of type JavaScript, CSS, JSON, or TXT.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import escapeStringRegexp from 'escape-string-regexp';
|
||||||
import srcDoc from 'srcdoc-polyfill';
|
import srcDoc from 'srcdoc-polyfill';
|
||||||
|
|
||||||
import loopProtect from 'loop-protect';
|
import loopProtect from 'loop-protect';
|
||||||
|
import { getBlobUrl } from '../actions/files';
|
||||||
|
|
||||||
const startTag = '@fs-';
|
const startTag = '@fs-';
|
||||||
|
|
||||||
|
@ -167,12 +167,13 @@ class PreviewFrame extends React.Component {
|
||||||
|
|
||||||
htmlFile = hijackConsoleLogsScript() + htmlFile;
|
htmlFile = hijackConsoleLogsScript() + htmlFile;
|
||||||
const mediaFiles = this.props.files.filter(file => file.url);
|
const mediaFiles = this.props.files.filter(file => file.url);
|
||||||
|
const textFiles = this.props.files.filter(file => file.name.match(/(.+\.json$|.+\.txt$)/i));
|
||||||
|
|
||||||
const jsFiles = [];
|
const jsFiles = [];
|
||||||
this.props.jsFiles.forEach(jsFile => {
|
this.props.jsFiles.forEach(jsFile => {
|
||||||
const newJSFile = { ...jsFile };
|
const newJSFile = { ...jsFile };
|
||||||
let jsFileStrings = newJSFile.content.match(/(['"])((\\\1|.)*?)\1/gm);
|
let jsFileStrings = newJSFile.content.match(/(['"])((\\\1|.)*?)\1/gm);
|
||||||
const jsFileRegex = /^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json)('|")$/i;
|
const jsFileRegex = /^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json|txt)('|")$/i;
|
||||||
jsFileStrings = jsFileStrings || [];
|
jsFileStrings = jsFileStrings || [];
|
||||||
jsFileStrings.forEach(jsFileString => {
|
jsFileStrings.forEach(jsFileString => {
|
||||||
if (jsFileString.match(jsFileRegex)) {
|
if (jsFileString.match(jsFileRegex)) {
|
||||||
|
@ -184,6 +185,13 @@ class PreviewFrame extends React.Component {
|
||||||
newJSFile.content = newJSFile.content.replace(filePath, file.url); // eslint-disable-line
|
newJSFile.content = newJSFile.content.replace(filePath, file.url); // eslint-disable-line
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
textFiles.forEach(file => {
|
||||||
|
if (file.name === fileName) {
|
||||||
|
const blobURL = getBlobUrl(file);
|
||||||
|
this.props.setBlobUrl(file, blobURL);
|
||||||
|
newJSFile.content = newJSFile.content.replace(filePath, blobURL);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
newJSFile.content = loopProtect(newJSFile.content);
|
newJSFile.content = loopProtect(newJSFile.content);
|
||||||
|
@ -280,6 +288,7 @@ PreviewFrame.propTypes = {
|
||||||
endSketchRefresh: PropTypes.func.isRequired,
|
endSketchRefresh: PropTypes.func.isRequired,
|
||||||
previewIsRefreshing: PropTypes.bool.isRequired,
|
previewIsRefreshing: PropTypes.bool.isRequired,
|
||||||
fullView: PropTypes.bool,
|
fullView: PropTypes.bool,
|
||||||
|
setBlobUrl: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PreviewFrame;
|
export default PreviewFrame;
|
||||||
|
|
|
@ -327,6 +327,7 @@ class IDEView extends React.Component {
|
||||||
previewIsRefreshing={this.props.ide.previewIsRefreshing}
|
previewIsRefreshing={this.props.ide.previewIsRefreshing}
|
||||||
endSketchRefresh={this.props.endSketchRefresh}
|
endSketchRefresh={this.props.endSketchRefresh}
|
||||||
stopSketch={this.props.stopSketch}
|
stopSketch={this.props.stopSketch}
|
||||||
|
setBlobUrl={this.props.setBlobUrl}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</SplitPane>
|
</SplitPane>
|
||||||
|
@ -568,7 +569,8 @@ IDEView.propTypes = {
|
||||||
setAutorefresh: PropTypes.func.isRequired,
|
setAutorefresh: PropTypes.func.isRequired,
|
||||||
startSketchAndRefresh: PropTypes.func.isRequired,
|
startSketchAndRefresh: PropTypes.func.isRequired,
|
||||||
endSketchRefresh: PropTypes.func.isRequired,
|
endSketchRefresh: PropTypes.func.isRequired,
|
||||||
startRefreshSketch: PropTypes.func.isRequired
|
startRefreshSketch: PropTypes.func.isRequired,
|
||||||
|
setBlobUrl: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
|
|
|
@ -119,6 +119,13 @@ const files = (state, action) => {
|
||||||
|
|
||||||
return Object.assign({}, file, { content: action.content });
|
return Object.assign({}, file, { content: action.content });
|
||||||
});
|
});
|
||||||
|
case ActionTypes.SET_BLOB_URL:
|
||||||
|
return state.map(file => {
|
||||||
|
if (file.name !== action.name) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
return Object.assign({}, file, { blobURL: action.blobURL });
|
||||||
|
});
|
||||||
case ActionTypes.NEW_PROJECT:
|
case ActionTypes.NEW_PROJECT:
|
||||||
return [...action.files];
|
return [...action.files];
|
||||||
case ActionTypes.SET_PROJECT:
|
case ActionTypes.SET_PROJECT:
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
"axios": "^0.12.0",
|
"axios": "^0.12.0",
|
||||||
"babel-core": "^6.8.0",
|
"babel-core": "^6.8.0",
|
||||||
"bcrypt-nodejs": "0.0.3",
|
"bcrypt-nodejs": "0.0.3",
|
||||||
|
"blob-util": "^1.2.1",
|
||||||
"body-parser": "^1.15.1",
|
"body-parser": "^1.15.1",
|
||||||
"bson-objectid": "^1.1.4",
|
"bson-objectid": "^1.1.4",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
|
|
Loading…
Reference in a new issue