generate blob urls for text and json files

This commit is contained in:
Cassie Tarakajian 2016-10-22 16:42:43 -04:00
parent d262783ec1
commit 8c270c2ced
7 changed files with 44 additions and 5 deletions

View file

@ -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';

View file

@ -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;
}

View file

@ -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.';
} }

View file

@ -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;

View file

@ -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) {

View file

@ -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:

View file

@ -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",
@ -73,7 +74,7 @@
"dropzone": "^4.3.0", "dropzone": "^4.3.0",
"escape-string-regexp": "^1.0.5", "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",
"file-saver": "^1.3.2", "file-saver": "^1.3.2",
"file-type": "^3.8.0", "file-type": "^3.8.0",