Merge branch 'upstream' into editor-accessibility-unique-key-warning

This commit is contained in:
omnikrll 2016-08-25 13:46:24 -04:00
commit c245a6a21e
7 changed files with 113 additions and 54 deletions

View file

@ -71,7 +71,8 @@ export function createFile(formProps) {
if (state.project.id) { if (state.project.id) {
const postParams = { const postParams = {
name: createUniqueName(formProps.name, state.files), name: createUniqueName(formProps.name, state.files),
url: formProps.url url: formProps.url,
content: formProps.content || ''
}; };
axios.post(`${ROOT_URL}/projects/${state.project.id}/files`, postParams, { withCredentials: true }) axios.post(`${ROOT_URL}/projects/${state.project.id}/files`, postParams, { withCredentials: true })
.then(response => { .then(response => {
@ -104,7 +105,8 @@ export function createFile(formProps) {
type: ActionTypes.CREATE_FILE, type: ActionTypes.CREATE_FILE,
name: createUniqueName(formProps.name, state.files), name: createUniqueName(formProps.name, state.files),
id: `${maxFileId + 1}`, id: `${maxFileId + 1}`,
url: formProps.url url: formProps.url,
content: formProps.content || ''
}); });
dispatch({ dispatch({
type: ActionTypes.HIDE_MODAL type: ActionTypes.HIDE_MODAL

View file

@ -1,65 +1,116 @@
import axios from 'axios'; import axios from 'axios';
import { createFile } from './files'; import { createFile } from './files';
const textFileRegex = /text\//;
const s3Bucket = `http://${process.env.S3_BUCKET}.s3.amazonaws.com/`; const s3Bucket = `http://${process.env.S3_BUCKET}.s3.amazonaws.com/`;
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';
function localIntercept(file, options = {}) {
return new Promise((resolve, reject) => {
if (!options.readType) {
// const mime = file.type;
// const textType = a(_textTypes).any(type => {
// const re = new RegExp(type);
// return re.test(mime);
// });
// options.readType = textType ? 'readAsText' : 'readAsDataURL';
options.readType = 'readAsText'; // eslint-disable-line
}
const reader = new window.FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = () => {
reject(reader.result);
};
// run the reader
reader[options.readType](file);
});
}
export function dropzoneAcceptCallback(file, done) { export function dropzoneAcceptCallback(file, done) {
return () => { return () => {
file.postData = []; // eslint-disable-line // for text files and small files
axios.post(`${ROOT_URL}/S3/sign`, { // check mime type
name: file.name, // if text, local interceptor
type: file.type, console.log(file.type);
size: file.size, if (file.type.match(textFileRegex)) {
// _csrf: document.getElementById('__createPostToken').value localIntercept(file).then(result => {
}, file.content = result; // eslint-disable-line
{ done();
withCredentials: true
}) })
.then(response => { .catch(result => {
file.custom_status = 'ready'; // eslint-disable-line done(`Failed to download file ${file.name}: ${result}`);
file.postData = response.data; // eslint-disable-line console.warn(file);
file.s3 = response.data.key; // eslint-disable-line });
file.previewTemplate.className += ' uploading'; // eslint-disable-line } else {
done(); file.postData = []; // eslint-disable-line
}) axios.post(`${ROOT_URL}/S3/sign`, {
.catch(response => { name: file.name,
file.custom_status = 'rejected'; // eslint-disable-line type: file.type,
if (response.data.responseText && response.data.responseText.message) { size: file.size,
done(response.data.responseText.message); // _csrf: document.getElementById('__createPostToken').value
} },
done('error preparing the upload'); {
}); withCredentials: true
})
.then(response => {
file.custom_status = 'ready'; // eslint-disable-line
file.postData = response.data; // eslint-disable-line
file.s3 = response.data.key; // eslint-disable-line
file.previewTemplate.className += ' uploading'; // eslint-disable-line
done();
})
.catch(response => {
file.custom_status = 'rejected'; // eslint-disable-line
if (response.data.responseText && response.data.responseText.message) {
done(response.data.responseText.message);
}
done('error preparing the upload');
});
}
}; };
} }
export function dropzoneSendingCallback(file, xhr, formData) { export function dropzoneSendingCallback(file, xhr, formData) {
return () => { return () => {
Object.keys(file.postData).forEach(key => { if (!file.type.match(textFileRegex)) {
formData.append(key, file.postData[key]); Object.keys(file.postData).forEach(key => {
}); formData.append(key, file.postData[key]);
formData.append('Content-type', ''); });
formData.append('Content-length', ''); formData.append('Content-type', '');
formData.append('acl', 'public-read'); formData.append('Content-length', '');
formData.append('acl', 'public-read');
}
}; };
} }
export function dropzoneCompleteCallback(file) { export function dropzoneCompleteCallback(file) {
return (dispatch, getState) => { // eslint-disable-line return (dispatch, getState) => { // eslint-disable-line
let inputHidden = '<input type="hidden" name="attachments[]" value="'; if (!file.type.match(textFileRegex)) {
const json = { let inputHidden = '<input type="hidden" name="attachments[]" value="';
url: `${s3Bucket}${file.postData.key}`, const json = {
originalFilename: file.name url: `${s3Bucket}${file.postData.key}`,
}; originalFilename: file.name
console.log(json, JSON.stringify(json), JSON.stringify(json).replace('"', '\\"')); };
inputHidden += `${window.btoa(JSON.stringify(json))}" />`; console.log(json, JSON.stringify(json), JSON.stringify(json).replace('"', '\\"'));
// document.getElementById('uploader').appendChild(inputHidden); inputHidden += `${window.btoa(JSON.stringify(json))}" />`;
document.getElementById('uploader').innerHTML += inputHidden; // document.getElementById('uploader').appendChild(inputHidden);
document.getElementById('uploader').innerHTML += inputHidden;
const formParams = { const formParams = {
name: file.name, name: file.name,
url: `${s3Bucket}${file.postData.key}` url: `${s3Bucket}${file.postData.key}`
}; };
createFile(formParams)(dispatch, getState); createFile(formParams)(dispatch, getState);
} else {
const formParams = {
name: file.name,
content: file.content
};
console.log(formParams);
createFile(formParams)(dispatch, getState);
}
}; };
} }

View file

@ -54,7 +54,8 @@ class Editor extends React.Component {
this.props.updateFileContent(this.props.file.name, this._cm.getValue()); this.props.updateFileContent(this.props.file.name, this._cm.getValue());
})); }));
this._cm.on('keyup', () => { this._cm.on('keyup', () => {
this.props.updateLineNumber(parseInt((this._cm.getCursor().line) + 1, 10)); const temp = `line ${parseInt((this._cm.getCursor().line) + 1, 10)}`;
document.getElementById('current-line').innerHTML = temp;
}); });
// this._cm.on('change', () => { // eslint-disable-line // this._cm.on('change', () => { // eslint-disable-line
// // this.props.updateFileContent('sketch.js', this._cm.getValue()); // // this.props.updateFileContent('sketch.js', this._cm.getValue());

View file

@ -28,7 +28,7 @@ class EditorAccessibility extends React.Component {
{messages} {messages}
</ul> </ul>
<p> Current line <p> Current line
<span className="editor-linenumber" aria-live="polite" aria-atomic="true" id="current-line"> {this.props.lineNumber} </span> <span className="editor-linenumber" aria-live="polite" aria-atomic="true" id="current-line"> </span>
</p> </p>
</div> </div>
); );

View file

@ -23,11 +23,16 @@ class FileUploader extends React.Component {
maxThumbnailFilesize: 8, // 3MB maxThumbnailFilesize: 8, // 3MB
thumbnailWidth: 200, thumbnailWidth: 200,
thumbnailHeight: 200, thumbnailHeight: 200,
acceptedFiles: 'image/bmp,image/gif,image/jpg,image/jpeg,image/png,audio/*', // TODO what is a good list of MIME types????
acceptedFiles: 'image/*,audio/*,text/javascript,text/html,text/css,application/json,application/x-font-ttf,application/x-font-truetype',
dictDefaultMessage: 'Drop files here to upload or click to use the file browser', dictDefaultMessage: 'Drop files here to upload or click to use the file browser',
accept: this.props.dropzoneAcceptCallback, accept: this.props.dropzoneAcceptCallback,
sending: this.props.dropzoneSendingCallback, sending: this.props.dropzoneSendingCallback,
complete: this.props.dropzoneCompleteCallback complete: this.props.dropzoneCompleteCallback,
error: (file, errorMessage) => {
console.log(file);
console.log(errorMessage);
}
}); });
} }

View file

@ -104,7 +104,7 @@ class PreviewFrame extends React.Component {
let jsFileStrings = newJSFile.content.match(/(['"])((\\\1|.)*?)\1/gm); let jsFileStrings = newJSFile.content.match(/(['"])((\\\1|.)*?)\1/gm);
jsFileStrings = jsFileStrings || []; jsFileStrings = jsFileStrings || [];
jsFileStrings.forEach(jsFileString => { jsFileStrings.forEach(jsFileString => {
if (jsFileString.match(/^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg)('|")$/)) { if (jsFileString.match(/^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json)('|")$/i)) {
const filePath = jsFileString.substr(1, jsFileString.length - 2); const filePath = jsFileString.substr(1, jsFileString.length - 2);
let fileName = filePath; let fileName = filePath;
if (fileName.match(/^\.\//)) { if (fileName.match(/^\.\//)) {

View file

@ -74,7 +74,7 @@ const files = (state = initialState, action) => {
case ActionTypes.RESET_PROJECT: case ActionTypes.RESET_PROJECT:
return initialState; return initialState;
case ActionTypes.CREATE_FILE: case ActionTypes.CREATE_FILE:
return [...state, { name: action.name, id: action.id, content: '', url: action.url }]; return [...state, { name: action.name, id: action.id, content: action.content, url: action.url }];
case ActionTypes.SHOW_FILE_OPTIONS: case ActionTypes.SHOW_FILE_OPTIONS:
return state.map(file => { return state.map(file => {
if (file.id !== action.id) { if (file.id !== action.id) {
@ -131,9 +131,9 @@ export const setSelectedFile = (state, id) =>
}); });
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 getHTMLFile = (state) => state.filter(file => file.name.match(/.*\.html$/i))[0];
export const getJSFiles = (state) => state.filter(file => file.name.match(/.*\.js$/)); export const getJSFiles = (state) => state.filter(file => file.name.match(/.*\.js$/i));
export const getCSSFiles = (state) => state.filter(file => file.name.match(/.*\.css$/)); export const getCSSFiles = (state) => state.filter(file => file.name.match(/.*\.css$/i));
export const getLinkedFiles = (state) => state.filter(file => file.url); export const getLinkedFiles = (state) => state.filter(file => file.url);
export default files; export default files;