Fixed buggy loading of files in the web application

This commit is contained in:
josdejong 2013-09-12 21:48:47 +02:00
parent 34a337874c
commit 0915c8366c
6 changed files with 71 additions and 77 deletions

View File

@ -8,6 +8,7 @@ http://jsoneditoronline.org
- Implemented an option `modes`, which creates a menu in the editor - Implemented an option `modes`, which creates a menu in the editor
where the user can switch between the selected editor modes. where the user can switch between the selected editor modes.
- Fixed wrong title on fields with value `null`. - Fixed wrong title on fields with value `null`.
- Fixed buggy loading of files in the web application.
## 2013-08-01, version 2.2.2 ## 2013-08-01, version 2.2.2

View File

@ -229,7 +229,6 @@ task('webapp', ['build', 'minify'], function () {
jake.cpR(webAppSrc + 'robots.txt', webApp); jake.cpR(webAppSrc + 'robots.txt', webApp);
jake.cpR(webAppSrc + 'datapolicy.txt', webApp); jake.cpR(webAppSrc + 'datapolicy.txt', webApp);
jake.cpR(webAppSrc + 'index.html', webApp); jake.cpR(webAppSrc + 'index.html', webApp);
jake.cpR(webAppSrc + 'chrome_app_counter.html', webApp);
jake.cpR(webAppSrc + 'favicon.ico', webApp); jake.cpR(webAppSrc + 'favicon.ico', webApp);
jake.cpR(webAppSrc + 'fileretriever.php', webApp); jake.cpR(webAppSrc + 'fileretriever.php', webApp);
jake.cpR(webAppSrc + 'googlea47c4a0b36d11021.html', webApp); jake.cpR(webAppSrc + 'googlea47c4a0b36d11021.html', webApp);

View File

@ -21,6 +21,10 @@ div.fileretriever-border {
background-color: white; background-color: white;
border: 1px solid gray; border: 1px solid gray;
border-radius: 2px; border-radius: 2px;
-moz-box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
-webkit-box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
} }
form.fileretriever-form { form.fileretriever-form {

View File

@ -214,9 +214,9 @@ FileRetriever.prototype.loadUrl = function (url, callback) {
* A file explorer will be opened to select a file and press ok. * A file explorer will be opened to select a file and press ok.
* In case of Internet Explorer, an upload form will be shown where the * In case of Internet Explorer, an upload form will be shown where the
* user has to select a file via a file explorer after that click load. * user has to select a file via a file explorer after that click load.
* @param {function} callback Callback method, called with parameters: * @param {function} [callback] Callback method, called with parameters:
* {Error} error * {Error} error
* {string} data * {string} data
*/ */
FileRetriever.prototype.loadFile = function (callback) { FileRetriever.prototype.loadFile = function (callback) {
// loading notification // loading notification
@ -246,54 +246,21 @@ FileRetriever.prototype.loadFile = function (callback) {
} }
}; };
// create an iframe for uploading files // create a form to select a file and submit
// the iframe must have an unique name, allowing multiple var useFileReader = (me.options.html5 && window.File && window.FileReader);
// FileRetrievers. The name is needed as target for the uploadForm
var iframeName = 'fileretriever-upload-' + Math.round(Math.random() * 1E15);
var iframe = document.createElement('iframe');
iframe.name = iframeName;
me._hide(iframe);
iframe.onload = function () {
// when a downloaded file is retrieved, send a callback with
// the retrieved data
var id = iframe.contentWindow.document.body.innerHTML;
if (id) {
var url = me.scriptUrl + '?id=' + id + '&filename=' + me.getFilename();
ajax.get(url, me.headers, function (data, status) {
if (status == 200) {
callbackOnce(null, data);
}
else {
var err = new Error('Error loading file ' + me.getFilename());
callbackOnce(err, null);
}
});
}
};
document.body.appendChild(iframe);
var isIE = (navigator.appName == 'Microsoft Internet Explorer'); if (useFileReader) {
if (!isIE) { this.prompt({
// create a hidden form to select a file title: 'Open file',
var domForm = document.createElement('form'); titleSubmit: 'Open',
domForm.action = this.scriptUrl; description: 'Select a file on your computer.',
domForm.method = 'POST'; inputType: 'file',
domForm.enctype = 'multipart/form-data'; inputName: 'file',
domForm.target = iframeName; callback: function (value, field) {
this._hide(domForm); if (value) {
var domFile = document.createElement('input'); if (useFileReader) {
domFile.type = 'file';
domFile.name = 'file';
domFile.onchange = function () {
startLoading();
// there is a file selected
setTimeout(function () { // Timeout needed for IE
var filename = domFile.value;
if (filename.length) {
if (me.options.html5 && window.File && window.FileReader) {
// load file via HTML5 FileReader (no size limits) // load file via HTML5 FileReader (no size limits)
var file = domFile.files[0]; var file = field.files[0];
var reader = new FileReader(); var reader = new FileReader();
reader.onload = function(event) { reader.onload = function(event) {
var data = event.target.result; var data = event.target.result;
@ -303,35 +270,51 @@ FileRetriever.prototype.loadFile = function (callback) {
// Read in the image file as a data URL. // Read in the image file as a data URL.
reader.readAsText(file); reader.readAsText(file);
} }
else {
// load by uploading to server
// TODO: how to check the file size? (on older browsers)
//console.log('submitting...');
domForm.submit(); startLoading();
}
} }
else { }
// cancel });
callbackOnce(null, null); // TODO: handle a cancel
}
}, 0);
};
domForm.appendChild(domFile);
document.body.appendChild(domForm);
// activate file selection (the click is done after a timeout,
// as in Opera and Safari, the form is not yet rendered)
setTimeout(function () {
domFile.click();
}, 0);
} }
else { else {
// create a visual form and submit manually (for IE) // no html5 filereader available
// create an iframe for uploading files
// the iframe must have an unique name, allowing multiple
// FileRetrievers. The name is needed as target for the uploadForm
var iframeName = 'fileretriever-upload-' + Math.round(Math.random() * 1E15);
var iframe = document.createElement('iframe');
iframe.name = iframeName;
me._hide(iframe);
iframe.onload = function () {
// when a downloaded file is retrieved, send a callback with
// the retrieved data
var id = iframe.contentWindow.document.body.innerHTML;
if (id) {
var url = me.scriptUrl + '?id=' + id + '&filename=' + me.getFilename();
ajax.get(url, me.headers, function (data, status) {
if (status == 200) {
callbackOnce(null, data);
}
else {
var err = new Error('Error loading file ' + me.getFilename());
callbackOnce(err, null);
}
// cleanup the frame again
if (iframe.parentNode === document.body) {
document.body.removeChild(iframe);
}
});
}
};
document.body.appendChild(iframe);
this.prompt({ this.prompt({
title: 'Open file', title: 'Open file',
titleSubmit: 'Open', titleSubmit: 'Open',
description: 'Select a file from disk and click the button Open to load it.', description: 'Select a file on your computer.',
inputType: 'file', inputType: 'file',
inputName: 'file', inputName: 'file',
formAction: this.scriptUrl, formAction: this.scriptUrl,
@ -380,7 +363,7 @@ FileRetriever.prototype.loadUrlDialog = function (callback) {
* The propmt can either: * The propmt can either:
* - Post a form when formAction, and formMethod are provided. * - Post a form when formAction, and formMethod are provided.
* Will call callback on submit. * Will call callback on submit.
* - Call the callback method "callback" with the entered value as parameter. * - Call the callback method "callback" with the entered value as first parameter and the created DOM field as second.
* This happens when a callback parameter is provided. * This happens when a callback parameter is provided.
* @param {Object} params Available parameters: * @param {Object} params Available parameters:
* {String} title * {String} title
@ -439,11 +422,11 @@ FileRetriever.prototype.prompt = function (params) {
form.onsubmit = function () { form.onsubmit = function () {
if (field.value) { if (field.value) {
setTimeout(function () { setTimeout(function () {
// remove after the submit has taken place! // remove *after* the submit has taken place!
removeDialog(); removeDialog();
}, 0); }, 0);
if (params.callback) { if (params.callback) {
params.callback(field.value); params.callback(field.value, field);
} }
return (params.formAction != undefined && params.formMethod != undefined); return (params.formAction != undefined && params.formMethod != undefined);
} }
@ -500,6 +483,13 @@ FileRetriever.prototype.prompt = function (params) {
var background = document.createElement('div'); var background = document.createElement('div');
background.className = 'fileretriever-background'; background.className = 'fileretriever-background';
background.appendChild(border); background.appendChild(border);
background.onclick = function (event) {
event = event || window.event;
var target = event.target || event.srcElement;
if (target == background) {
onCancel();
}
};
document.body.appendChild(background); document.body.appendChild(background);
field.focus(); field.focus();

2
jsoneditor-min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -28,7 +28,7 @@
* *
* @author Jos de Jong, <wjosdejong@gmail.com> * @author Jos de Jong, <wjosdejong@gmail.com>
* @version 2.3.0-SNAPSHOT * @version 2.3.0-SNAPSHOT
* @date 2013-08-28 * @date 2013-09-12
*/ */
(function () { (function () {