431 lines
12 KiB
JavaScript
431 lines
12 KiB
JavaScript
/**
|
|
* plupload.html4.js
|
|
*
|
|
* Copyright 2010, Ryan Demmer
|
|
* Copyright 2009, Moxiecode Systems AB
|
|
* Released under GPL License.
|
|
*
|
|
* License: http://www.plupload.com/license
|
|
* Contributing: http://www.plupload.com/contributing
|
|
*/
|
|
|
|
// JSLint defined globals
|
|
/*global plupload:false, window:false */
|
|
|
|
(function(window, document, plupload, undef) {
|
|
function getById(id) {
|
|
return document.getElementById(id);
|
|
}
|
|
|
|
/**
|
|
* HTML4 implementation. This runtime has no special features it uses an form that posts files into an hidden iframe.
|
|
*
|
|
* @static
|
|
* @class plupload.runtimes.Html4
|
|
* @extends plupload.Runtime
|
|
*/
|
|
plupload.runtimes.Html4 = plupload.addRuntime("html4", {
|
|
/**
|
|
* Returns a list of supported features for the runtime.
|
|
*
|
|
* @return {Object} Name/value object with supported features.
|
|
*/
|
|
getFeatures : function() {
|
|
// Only multipart feature
|
|
return {
|
|
multipart: true,
|
|
|
|
// WebKit and Gecko 2+ can trigger file dialog progrmmatically
|
|
triggerDialog: (plupload.ua.gecko && window.FormData || plupload.ua.webkit)
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Initializes the upload runtime.
|
|
*
|
|
* @method init
|
|
* @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
|
|
* @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
|
|
*/
|
|
init : function(uploader, callback) {
|
|
uploader.bind("Init", function(up) {
|
|
var container = document.body, iframe, url = "javascript", currentFile,
|
|
input, currentFileId, fileIds = [], IE = /MSIE/.test(navigator.userAgent), mimes = [],
|
|
filters = up.settings.filters, i, ext, type, y;
|
|
|
|
// Convert extensions to mime types list
|
|
no_type_restriction:
|
|
for (i = 0; i < filters.length; i++) {
|
|
ext = filters[i].extensions.split(/,/);
|
|
|
|
for (y = 0; y < ext.length; y++) {
|
|
|
|
// If there's an asterisk in the list, then accept attribute is not required
|
|
if (ext[y] === '*') {
|
|
mimes = [];
|
|
break no_type_restriction;
|
|
}
|
|
|
|
type = plupload.mimeTypes[ext[y]];
|
|
|
|
if (type && plupload.inArray(type, mimes) === -1) {
|
|
mimes.push(type);
|
|
}
|
|
}
|
|
}
|
|
|
|
mimes = mimes.join(',');
|
|
|
|
function createForm() {
|
|
var form, input, bgcolor, browseButton;
|
|
|
|
// Setup unique id for form
|
|
currentFileId = plupload.guid();
|
|
|
|
// Save id for Destroy handler
|
|
fileIds.push(currentFileId);
|
|
|
|
// Create form
|
|
form = document.createElement('form');
|
|
form.setAttribute('id', 'form_' + currentFileId);
|
|
form.setAttribute('method', 'post');
|
|
form.setAttribute('enctype', 'multipart/form-data');
|
|
form.setAttribute('encoding', 'multipart/form-data');
|
|
form.setAttribute("target", up.id + '_iframe');
|
|
form.style.position = 'absolute';
|
|
|
|
// Create input and set attributes
|
|
input = document.createElement('input');
|
|
input.setAttribute('id', 'input_' + currentFileId);
|
|
input.setAttribute('type', 'file');
|
|
input.setAttribute('accept', mimes);
|
|
input.setAttribute('size', 1);
|
|
|
|
browseButton = getById(up.settings.browse_button);
|
|
|
|
// Route click event to input element programmatically, if possible
|
|
if (up.features.triggerDialog && browseButton) {
|
|
plupload.addEvent(getById(up.settings.browse_button), 'click', function(e) {
|
|
if (!input.disabled) {
|
|
input.click();
|
|
}
|
|
e.preventDefault();
|
|
}, up.id);
|
|
}
|
|
|
|
// Set input styles
|
|
plupload.extend(input.style, {
|
|
width : '100%',
|
|
height : '100%',
|
|
opacity : 0,
|
|
fontSize: '99px', // force input element to be bigger then needed to occupy whole space
|
|
cursor: 'pointer'
|
|
});
|
|
|
|
plupload.extend(form.style, {
|
|
overflow: 'hidden'
|
|
});
|
|
|
|
// Show the container if shim_bgcolor is specified
|
|
bgcolor = up.settings.shim_bgcolor;
|
|
if (bgcolor) {
|
|
form.style.background = bgcolor;
|
|
}
|
|
|
|
// no opacity in IE
|
|
if (IE) {
|
|
plupload.extend(input.style, {
|
|
filter : "alpha(opacity=0)"
|
|
});
|
|
}
|
|
|
|
// add change event
|
|
plupload.addEvent(input, 'change', function(e) {
|
|
var element = e.target, name, files = [], topElement;
|
|
|
|
if (element.value) {
|
|
getById('form_' + currentFileId).style.top = -0xFFFFF + "px";
|
|
|
|
// Get file name
|
|
name = element.value.replace(/\\/g, '/');
|
|
name = name.substring(name.length, name.lastIndexOf('/') + 1);
|
|
|
|
// Push files
|
|
files.push(new plupload.File(currentFileId, name));
|
|
|
|
// Clean-up events - they won't be needed anymore
|
|
if (!up.features.triggerDialog) {
|
|
plupload.removeAllEvents(form, up.id);
|
|
} else {
|
|
plupload.removeEvent(browseButton, 'click', up.id);
|
|
}
|
|
plupload.removeEvent(input, 'change', up.id);
|
|
|
|
// Create and position next form
|
|
createForm();
|
|
|
|
// Fire FilesAdded event
|
|
if (files.length) {
|
|
uploader.trigger("FilesAdded", files);
|
|
}
|
|
}
|
|
}, up.id);
|
|
|
|
// append to container
|
|
form.appendChild(input);
|
|
container.appendChild(form);
|
|
|
|
up.refresh();
|
|
}
|
|
|
|
|
|
function createIframe() {
|
|
var temp = document.createElement('div');
|
|
|
|
// Create iframe using a temp div since IE 6 won't be able to set the name using setAttribute or iframe.name
|
|
temp.innerHTML = '<iframe id="' + up.id + '_iframe" name="' + up.id + '_iframe" src="' + url + ':""" style="display:none"></iframe>';
|
|
iframe = temp.firstChild;
|
|
container.appendChild(iframe);
|
|
|
|
// Add IFrame onload event
|
|
plupload.addEvent(iframe, 'load', function(e) {
|
|
var n = e.target, el, result;
|
|
|
|
// Ignore load event if there is no file
|
|
if (!currentFile) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
el = n.contentWindow.document || n.contentDocument || window.frames[n.id].document;
|
|
} catch (ex) {
|
|
// Probably a permission denied error
|
|
up.trigger('Error', {
|
|
code : plupload.SECURITY_ERROR,
|
|
message : plupload.translate('Security error.'),
|
|
file : currentFile
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
// Get result
|
|
result = el.documentElement.innerText || el.documentElement.textContent;
|
|
|
|
// Assume no error
|
|
if (result) {
|
|
currentFile.status = plupload.DONE;
|
|
currentFile.loaded = 1025;
|
|
currentFile.percent = 100;
|
|
|
|
up.trigger('UploadProgress', currentFile);
|
|
up.trigger('FileUploaded', currentFile, {
|
|
response : result
|
|
});
|
|
}
|
|
}, up.id);
|
|
} // end createIframe
|
|
|
|
if (up.settings.container) {
|
|
container = getById(up.settings.container);
|
|
if (plupload.getStyle(container, 'position') === 'static') {
|
|
container.style.position = 'relative';
|
|
}
|
|
}
|
|
|
|
// Upload file
|
|
up.bind("UploadFile", function(up, file) {
|
|
var form, input;
|
|
|
|
// File upload finished
|
|
if (file.status == plupload.DONE || file.status == plupload.FAILED || up.state == plupload.STOPPED) {
|
|
return;
|
|
}
|
|
|
|
// Get the form and input elements
|
|
form = getById('form_' + file.id);
|
|
input = getById('input_' + file.id);
|
|
|
|
// Set input element name attribute which allows it to be submitted
|
|
input.setAttribute('name', up.settings.file_data_name);
|
|
|
|
// Store action
|
|
form.setAttribute("action", up.settings.url);
|
|
|
|
// Append multipart parameters
|
|
plupload.each(plupload.extend({name : file.target_name || file.name}, up.settings.multipart_params), function(value, name) {
|
|
var hidden = document.createElement('input');
|
|
|
|
plupload.extend(hidden, {
|
|
type : 'hidden',
|
|
name : name,
|
|
value : value
|
|
});
|
|
|
|
form.insertBefore(hidden, form.firstChild);
|
|
});
|
|
|
|
currentFile = file;
|
|
|
|
// Hide the current form
|
|
getById('form_' + currentFileId).style.top = -0xFFFFF + "px";
|
|
|
|
form.submit();
|
|
});
|
|
|
|
|
|
|
|
up.bind('FileUploaded', function(up) {
|
|
up.refresh(); // just to get the form back on top of browse_button
|
|
});
|
|
|
|
up.bind('StateChanged', function(up) {
|
|
if (up.state == plupload.STARTED) {
|
|
createIframe();
|
|
} else if (up.state == plupload.STOPPED) {
|
|
window.setTimeout(function() {
|
|
plupload.removeEvent(iframe, 'load', up.id);
|
|
if (iframe.parentNode) { // #382
|
|
iframe.parentNode.removeChild(iframe);
|
|
}
|
|
}, 0);
|
|
}
|
|
|
|
plupload.each(up.files, function(file, i) {
|
|
if (file.status === plupload.DONE || file.status === plupload.FAILED) {
|
|
var form = getById('form_' + file.id);
|
|
|
|
if(form){
|
|
form.parentNode.removeChild(form);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
// Refresh button, will reposition the input form
|
|
up.bind("Refresh", function(up) {
|
|
var browseButton, topElement, hoverClass, activeClass, browsePos, browseSize, inputContainer, inputFile, zIndex;
|
|
|
|
browseButton = getById(up.settings.browse_button);
|
|
if (browseButton) {
|
|
browsePos = plupload.getPos(browseButton, getById(up.settings.container));
|
|
browseSize = plupload.getSize(browseButton);
|
|
inputContainer = getById('form_' + currentFileId);
|
|
inputFile = getById('input_' + currentFileId);
|
|
|
|
plupload.extend(inputContainer.style, {
|
|
top : browsePos.y + 'px',
|
|
left : browsePos.x + 'px',
|
|
width : browseSize.w + 'px',
|
|
height : browseSize.h + 'px'
|
|
});
|
|
|
|
// for IE and WebKit place input element underneath the browse button and route onclick event
|
|
// TODO: revise when browser support for this feature will change
|
|
if (up.features.triggerDialog) {
|
|
if (plupload.getStyle(browseButton, 'position') === 'static') {
|
|
plupload.extend(browseButton.style, {
|
|
position : 'relative'
|
|
});
|
|
}
|
|
|
|
zIndex = parseInt(browseButton.style.zIndex, 10);
|
|
|
|
if (isNaN(zIndex)) {
|
|
zIndex = 0;
|
|
}
|
|
|
|
plupload.extend(browseButton.style, {
|
|
zIndex : zIndex
|
|
});
|
|
|
|
plupload.extend(inputContainer.style, {
|
|
zIndex : zIndex - 1
|
|
});
|
|
}
|
|
|
|
/* Since we have to place input[type=file] on top of the browse_button for some browsers (FF, Opera),
|
|
browse_button loses interactivity, here we try to neutralize this issue highlighting browse_button
|
|
with a special class
|
|
TODO: needs to be revised as things will change */
|
|
hoverClass = up.settings.browse_button_hover;
|
|
activeClass = up.settings.browse_button_active;
|
|
topElement = up.features.triggerDialog ? browseButton : inputContainer;
|
|
|
|
if (hoverClass) {
|
|
plupload.addEvent(topElement, 'mouseover', function() {
|
|
plupload.addClass(browseButton, hoverClass);
|
|
}, up.id);
|
|
plupload.addEvent(topElement, 'mouseout', function() {
|
|
plupload.removeClass(browseButton, hoverClass);
|
|
}, up.id);
|
|
}
|
|
|
|
if (activeClass) {
|
|
plupload.addEvent(topElement, 'mousedown', function() {
|
|
plupload.addClass(browseButton, activeClass);
|
|
}, up.id);
|
|
plupload.addEvent(document.body, 'mouseup', function() {
|
|
plupload.removeClass(browseButton, activeClass);
|
|
}, up.id);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Remove files
|
|
uploader.bind("FilesRemoved", function(up, files) {
|
|
var i, n;
|
|
|
|
for (i = 0; i < files.length; i++) {
|
|
n = getById('form_' + files[i].id);
|
|
if (n) {
|
|
n.parentNode.removeChild(n);
|
|
}
|
|
}
|
|
});
|
|
|
|
uploader.bind("DisableBrowse", function(up, disabled) {
|
|
var input = document.getElementById('input_' + currentFileId);
|
|
if (input) {
|
|
input.disabled = disabled;
|
|
}
|
|
});
|
|
|
|
|
|
// Completely destroy the runtime
|
|
uploader.bind("Destroy", function(up) {
|
|
var name, element, form,
|
|
elements = {
|
|
inputContainer: 'form_' + currentFileId,
|
|
inputFile: 'input_' + currentFileId,
|
|
browseButton: up.settings.browse_button
|
|
};
|
|
|
|
// Unbind event handlers
|
|
for (name in elements) {
|
|
element = getById(elements[name]);
|
|
if (element) {
|
|
plupload.removeAllEvents(element, up.id);
|
|
}
|
|
}
|
|
plupload.removeAllEvents(document.body, up.id);
|
|
|
|
// Remove mark-up
|
|
plupload.each(fileIds, function(id, i) {
|
|
form = getById('form_' + id);
|
|
if (form) {
|
|
form.parentNode.removeChild(form);
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
// Create initial form
|
|
createForm();
|
|
});
|
|
|
|
callback({success : true});
|
|
}
|
|
});
|
|
})(window, document, plupload);
|