Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F775817
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Feb 6, 7:35 AM
Size
21 KB
Mime Type
text/x-diff
Expires
Sat, Feb 8, 7:35 AM (1 d, 15 h)
Engine
blob
Format
Raw Data
Handle
558329
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.0.x/core/admin_templates/js/uploader/uploader.js
===================================================================
--- branches/5.0.x/core/admin_templates/js/uploader/uploader.js (revision 12233)
+++ branches/5.0.x/core/admin_templates/js/uploader/uploader.js (revision 12234)
@@ -1,629 +1,629 @@
// this js class name is hardcoded in flash object :(
var SWFUpload = function () {};
SWFUpload.instances = {};
function Uploader(id, params) {
this.id = id;
this._moved = false; // flash was moved outside scroll container
// normalize params
if (isNaN(parseInt(params.multiple))) {
// ensure that maximal file number is greather then zero
params.multiple = 1;
}
params.allowedFilesize = this._normalizeFilesize(params.allowedFilesize);
// set params to uploader
this._eventQueue = [];
this.uploadCancelled = false;
this.params = params;
this._ensureDefaultValues();
this.files_count = 0;
this.files = new Array();
this.deleted = new Array()
this.uploadURL = params.uploadURL;
this.deleteURL = params.deleteURL;
this._resetCounters();
}
/* ==== Private methods ==== */
Uploader.prototype._ensureDefaultValues = function() {
// Upload backend settings
var $defaults = {
baseUrl: '',
uploadURL : '',
useQueryString : false,
requeueOnError : false,
httpSuccess : '',
filePostName : 'Filedata',
allowedFiletypes : '*.*',
allowedFiletypesDescription : 'All Files',
allowedFilesize : 0, // Default zero means "unlimited"
multiple : 0,
fileQueueLimit : 0,
buttonImageURL : '',
buttonWidth : 1,
buttonHeight : 1,
buttonText : '',
buttonTextTopPadding : 0,
buttonTextLeftPadding : 0,
buttonTextStyle : 'color: #000000; font-size: 16pt;',
buttonAction : parseInt(this.params.multiple) == 1 ? -100 : -110, // SELECT_FILE : -100, SELECT_FILES : -110
buttonDisabled : true, //false,
buttonCursor : -1, // ARROW : -1, HAND : -2
wmode : 'transparent', // "window", "transparent", "opaque"
buttonPlaceholderId: false
}
for (var $param_name in $defaults) {
if (this.params[$param_name] == null) {
// console.log('setting default value [', $defaults[$param_name], '] for missing parameter [', $param_name, '] instead of [', this.params[$param_name], ']');
this.params[$param_name] = $defaults[$param_name];
}
}
}
Uploader.prototype._normalizeFilesize = function($file_size) {
var $normalize_size = parseInt($file_size);
if (isNaN($normalize_size)) {
return $file_size;
}
// in kilobytes (flash doesn't recognize numbers, that are longer, then 9 digits)
return $normalize_size / 1024;
}
Uploader.prototype._prepareFiles = function() {
var ids = '';
var names = '';
for (var f = 0; f < this.files.length; f++) {
if (isset(this.files[f].uploaded) && !isset(this.files[f].temp)) {
continue;
}
ids += this.files[f].id + '|'
names += this.files[f].name + '|'
}
ids = ids.replace(/\|$/, '', ids);
names = names.replace(/\|$/, '', names);
document.getElementById(this.id+'[tmp_ids]').value = ids;
document.getElementById(this.id+'[tmp_names]').value = names;
document.getElementById(this.id+'[tmp_deleted]').value = this.deleted.join('|');
}
Uploader.prototype._getMicroTime = function() {
var $now = new Date();
return Math.round($now.getTime() / 1000); // because miliseconds are returned too
}
Uploader.prototype._getEstimatedTime = function() {
return Math.ceil((100 - this.ProgressPercent) * this.ProgressTime / this.ProgressPercent);
}
Uploader.prototype._formatTime = function ($seconds) {
$seconds = parseInt($seconds);
var $minutes = Math.floor($seconds / 60);
if ($minutes < 10) $minutes = '0' + $minutes;
$seconds = $seconds % 60;
if ($seconds < 10) $seconds = '0' + $seconds;
return $minutes + ':' + $seconds;
}
Uploader.prototype._formatSize = function (bytes) {
var kb = Math.round(bytes / 1024);
if (kb < 1024) return kb+'Kb';
var mb = Math.round(kb / 1024 * 100)/100;
return mb+'Mb';
}
Uploader.prototype._executeNextEvent = function () {
var f = this._eventQueue ? this._eventQueue.shift() : null;
if (typeof(f) === 'function') {
f.apply(this);
}
};
/* ==== Public methods ==== */
Uploader.prototype.init = function() {
if (this.params.buttonPlaceholderId !== false) {
// use given container
var holder = document.getElementById(this.params.buttonPlaceholderId);
}
else {
// create container on the fly
var holder = document.createElement('DIV');
document.body.appendChild(holder);
}
if (UploadsManager.useTransparency) {
document.getElementById($form_name).style.display = 'block';
}
// moving out progress div to overcome loosing of flash object after setting opacity
this.div = document.getElementById(this.id+'_progress');
var clone = this.div.cloneNode(true);
this.div.parentNode.removeChild(this.div)
this.div = document.body.appendChild(clone);
this.IconPath = this.params.IconPath ? this.params.IconPath : '../admin_templates/img/browser/icons';
this.filename = document.getElementById(this.id+'_progress_filename');
this.progress = document.getElementById(this.id+'_progress_progress');
this.elapsed = document.getElementById(this.id+'_progress_elapsed');
this.remaining = document.getElementById(this.id+'_progress_remaining');
this.percent = document.getElementById(this.id+'_percent');
this.done = document.getElementById(this.id+'_done');
// initialize flash object
this.flash_id = UploadsManager._nextFlashId();
// add callbacks for every event, because none of callbacks will work in other case (see swfupload documentation)
SWFUpload.instances[this.flash_id] = this;
SWFUpload.instances[this.flash_id].flashReady = function () { UploadsManager.onFlashReady(this.id); };
SWFUpload.instances[this.flash_id].fileDialogStart = UploadsManager.onHandleEverything;
SWFUpload.instances[this.flash_id].fileQueued = UploadsManager.onFileQueued;
SWFUpload.instances[this.flash_id].fileQueueError = UploadsManager.onFileQueueError;
SWFUpload.instances[this.flash_id].fileDialogComplete = UploadsManager.onHandleEverything;
SWFUpload.instances[this.flash_id].uploadStart = UploadsManager.onUploadStart;
SWFUpload.instances[this.flash_id].uploadProgress = UploadsManager.onUploadProgress;
SWFUpload.instances[this.flash_id].uploadError = UploadsManager.onUploadError;
SWFUpload.instances[this.flash_id].uploadSuccess = UploadsManager.onHandleEverything;
SWFUpload.instances[this.flash_id].uploadComplete = UploadsManager.onUploadComplete;
SWFUpload.instances[this.flash_id].debug = UploadsManager.onDebug;
this.swf = new SWFObject(this.params.baseUrl + '/swfupload.swf', this.flash_id, this.params.buttonWidth, this.params.buttonHeight, '9', '#FFFFFF');
this.swf.setAttribute('style', '');
this.swf.addParam('wmode', escape(this.params.wmode));
this.swf.addVariable('movieName', escape(this.flash_id));
this.swf.addVariable('fileUploadLimit', escape(this.params.multiple));
this.swf.addVariable('fileQueueLimit', escape(this.params.fileQueueLimit));
this.swf.addVariable('fileSizeLimit', escape(this.params.allowedFilesize)); // in kilobytes
this.swf.addVariable('fileTypes', escape(this.params.allowedFiletypes));
this.swf.addVariable('fileTypesDescription', escape(this.params.allowedFiletypesDescription));
this.swf.addVariable('uploadURL', escape(this.params.uploadURL));
// upload button appearance
this.swf.addVariable('buttonImageURL', escape(this.params.buttonImageURL));
this.swf.addVariable('buttonWidth', escape(this.params.buttonWidth));
this.swf.addVariable('buttonHeight', escape(this.params.buttonHeight));
this.swf.addVariable('buttonText', escape(this.params.buttonText));
this.swf.addVariable('buttonTextTopPadding', escape(this.params.buttonTextTopPadding));
this.swf.addVariable('buttonTextLeftPadding', escape(this.params.buttonTextLeftPadding));
this.swf.addVariable('buttonTextStyle', escape(this.params.buttonTextStyle));
this.swf.addVariable('buttonAction', escape(this.params.buttonAction));
this.swf.addVariable('buttonDisabled', escape(this.params.buttonDisabled));
this.swf.addVariable('buttonCursor', escape(this.params.buttonCursor));
if (UploadsManager._debugMode) {
this.swf.addVariable('debugEnabled', escape('true')); // flash var
}
- if (this.params.buttonPlaceholderId === false) {
+ if (this.params.buttonPlaceholderId === false || !UploadsManager.useTransparency) {
// only write flash, when button placeholder is not used
this.swf.write(holder);
this.flash = document.getElementById(this.flash_id);
}
if (this.params.urls != '') {
var urls = this.params.urls.split('|');
var names = this.params.names.split('|');
var sizes = this.params.sizes.split('|');
for (var i = 0; i < urls.length; i++) {
var a_file = {
id : names[i],
name : names[i],
url : urls[i],
size: sizes[i],
uploaded : 1
}
this.files.push(a_file)
this.files_count++;
}
this.updateInfo();
}
}
Uploader.prototype.moveOutside = function() {
// move flash outside scroll_container, but keeps it's position on screen
if (!UploadsManager.useTransparency) {
// moving only needed when transparency us used (e.g. in admin)
return ;
}
var $new_container = document.createElement('DIV');
$new_container.id = this.params.buttonPlaceholderId + '_outside';
$new_container.style.position = 'absolute';
var $old_container = document.getElementById(this.params.buttonPlaceholderId);
$new_container.style.top = getRealTop($old_container) + 'px';
$new_container.style.left = getRealLeft($old_container) + 'px';
var $holder_dimensions = getDimensions($old_container);
$new_container.style.width = $holder_dimensions.innerWidth + 'px';
$new_container.style.height = $holder_dimensions.innerHeight + 'px';
document.body.appendChild($new_container);
this.swf.write($new_container); // write flash outside scroll_container
this.flash = document.getElementById(this.flash_id); // fix reference to flash object
this._moved = true;
}
Uploader.prototype.remove = function() {
var id = this._moved ? this.params.buttonPlaceholderId + '_outside' : this.params.buttonPlaceholderId;
var obj = document.getElementById(id);
if (obj/* && obj.nodeName == "OBJECT"*/) {
var u = navigator.userAgent.toLowerCase();
var p = navigator.platform.toLowerCase();
var windows = p ? /win/.test(p) : /win/.test(u);
var $me = this;
if (document.all && windows) {
obj.style.display = "none";
(function(){
if (obj.readyState == 4) {
$me.removeObjectInIE(id);
}
else {
setTimeout(arguments.callee, 10);
}
})();
}
else {
obj.parentNode.removeChild(obj);
}
}
}
Uploader.prototype.removeObjectInIE = function(id) {
var obj = document.getElementById(id);
if (obj) {
for (var i in obj) {
if (typeof obj[i] == 'function') {
obj[i] = null;
}
}
obj.parentNode.removeChild(obj);
}
}
Uploader.prototype.syncBrowseButton = function() {
// when flash is moved outside scroll_container, keeps it's position on screen during scroll operations
if (!this._moved) {
return ;
}
var $scroll_container = UploadsManager._getScrollContainer();
var $scroll_container_top = getRealTop($scroll_container);
var $scroll_container_left = getRealLeft($scroll_container);
var $scroll_top = $scroll_container.scrollTop;
var $scroll_left = $scroll_container.scrollLeft;
var $old_container = document.getElementById(this.params.buttonPlaceholderId);
var $new_container = document.getElementById(this.params.buttonPlaceholderId + '_outside');
var $old_container_top = getRealTop($old_container);
var $old_container_left = getRealLeft($old_container);
if ($scroll_container_top <= $old_container_top - $scroll_top) {
// prevents moving outside $scroll_container
$new_container.style.top = ($old_container_top - $scroll_top) + 'px';
}
else {
// move browse button outside visible area
$new_container.style.top = -this.params.buttonHeight + 'px';
}
if ($scroll_container_left <= $old_container_left - $scroll_left) {
// prevents moving outside $scroll_container
$new_container.style.left = ($old_container_left - $scroll_left) + 'px';
}
else {
// move browse button outside visible area
$new_container.style.left = -this.params.buttonWidth + 'px';
}
}
Uploader.prototype.updateInfo = function() {
var $o = '';
var $icon = '';
var $filename = '';
var $delete_code = '';
for (var f = 0; f < this.files.length; f++) {
this.files[f].name.match(/\.([^.]*)$/);
var ext = RegExp.$1.toLowerCase();
$icon = ext.match(/^(ai|avi|bmp|cs|dll|doc|dot|exe|fla|gif|htm|html|jpg|js|mdb|mp3|pdf|ppt|rdp|swf|swt|txt|vsd|xls|xml|zip)$/) ? ext : 'default.icon';
$icon = '<img src="' + this.IconPath + '/' + $icon + '.gif"/> ';
if (isset(this.files[f].uploaded)) {
$filename = '<a href="' + this.files[f].url + '" target="_new">' + this.files[f].name + '</a> (' + this._formatSize(this.files[f].size) + ')';
$delete_code = 'UploadsManager.DeleteFile(\'' + this.id + '\', \'' + this.files[f].name + '\')';
}
else {
$filename = this.files[f].name + ' (' + this._formatSize(this.files[f].size) + ')';
$delete_code = 'UploadsManager.CancelFile(\'' + UploadsManager._getUploader(this.files[f]).id + '\', \'' + this.files[f].id + '\')';
}
$o += '<tr><td>' + $icon + '</td><td style="font: 11px arial, sans-serif;">' + $filename + ' [<a href="javascript:' + $delete_code + '">Delete</a>]</td></tr>';
}
document.getElementById(this.id+'_queueinfo').innerHTML = '<table cellpadding="0" cellspacing="0">' + $o + '</table>';
this._prepareFiles();
// sync position of all uploaders below current, because file queue height change will not affect their positions
UploadsManager.iterate('syncBrowseButton');
}
Uploader.prototype.removeFile = function (file) {
var n_files = new Array();
var count = 0;
var $new_total = 0;
for (var f = 0; f < this.files.length; f++) {
if (this.files[f].id != file.id && this.files[f].name != file.id) {
n_files.push(this.files[f]);
if (!isset(this.files[f].uploaded)) {
$new_total += file.size;
}
count++;
}
}
if (this.StartTime == 0) {
// don't update total during upload, because that breaks progress bar
this.total = $new_total;
}
this.files = n_files;
this.files_count = count;
this.updateInfo();
}
Uploader.prototype.hasQueue = function() {
for (var f = 0; f < this.files.length; f++) {
if (isset(this.files[f].uploaded)) {
continue;
}
return true;
}
return false;
}
Uploader.prototype.startUpload = function() {
UploadsManager.uploadCancelled = this.uploadCancelled = false;
if (!this.hasQueue()) {
return;
}
if (UploadsManager.useTransparency) {
Request.setOpacity(30, UploadsManager._getFormContainer());
}
if (!document.all) {
var $winW = window.innerWidth;
var $winH = window.innerHeight;
}
else {
var $winW = window.document.body.offsetWidth;
var $winH = window.document.body.offsetHeight;
}
var left = Math.round(($winW - 350)/2)+'px';
var top = Math.round(($winH - 110)/2)+'px';
this.div.style.top = top;
this.div.style.left = left;
this.div.style.display = 'block';
if (UploadsManager.useTransparency) {
Request.setOpacity(100, this.div);
}
this.StartTime = this._getMicroTime();
this.ProgressPercent = 0; // progress percent
this.ProgressTime = new Array();
this.uploaded = 0;
this.total = 0;
for (var f = 0; f < this.files.length; f++) {
if (isset(this.files[f].uploaded)) {
// get total bytes of non-uploaded files
continue;
}
this.total += this.files[f].size;
}
this.callFlash('StartUpload');
}
Uploader.prototype.cancelUpload = function() {
this.callFlash('StopUpload');
var $stats = this.callFlash('GetStats');
while ($stats.files_queued > 0) {
this.callFlash('CancelUpload');
$stats = this.callFlash('GetStats');
}
UploadsManager.uploadCancelled = this.uploadCancelled = true;
}
Uploader.prototype.UploadFileStart = function(file) {
this.filename.innerHTML = file.name;
this.callFlash('AddFileParam', [file.id, 'field', this.params.field]);
this.callFlash('AddFileParam', [file.id, 'id', file.id]);
this.callFlash('AddFileParam', [file.id, 'flashsid', this.params.flashsid]);
UploadsManager.iterate('disableBrowse', true); // disable all "Browse" buttons (not just for current uploader)!
// we can prevent user from adding any files here :)
this.callFlash('ReturnUploadStart', [true]);
}
Uploader.prototype.UploadProgress = function(file, bytesLoaded, bytesTotal) {
this.cur_file_uploaded = bytesLoaded;
var uploaded = this.uploaded + this.cur_file_uploaded;
this.ProgressTime = this._getMicroTime() - this.StartTime;
var speed = 0;
if (this.ProgressTime > 0) {
speed = Math.round(uploaded / this.ProgressTime * 100) / 100;
}
this.progress.innerHTML = this._formatSize(uploaded) + ' / ' + this._formatSize(this.total) + ' (' + this._formatSize(speed) + '/s)';
this.ProgressPercent = Math.round(uploaded / this.total * 100);
this.done.style.width = this.ProgressPercent + '%';
this.percent.innerHTML = this.ProgressPercent + '%';
this.elapsed.innerHTML = this._formatTime(this.ProgressTime );
this.remaining.innerHTML = this._formatTime( this._getEstimatedTime() );
}
Uploader.prototype.UploadFileComplete = function(file) {
this.uploaded += this.cur_file_uploaded;
for (var f = 0; f < this.files.length; f++) {
if (this.files[f].id == file.id) {
this.files[f].uploaded = 1;
this.files[f].temp = 1;
this.files[f].url = this.params.tmp_url.replace('#ID#', file.id).replace('#FILE#', file.name).replace('#FIELD#', this.params.field);
}
}
this.updateInfo();
// upload next file in queue
var $stats = this.callFlash('GetStats');
if ($stats.files_queued > 0 && !UploadsManager.uploadCancelled) {
this.callFlash('StartUpload');
} else {
// all files in queue are uploaded OR upload was cancelled globally
if (UploadsManager.uploadCancelled) {
// when upload was cancelled globally -> cancel it for any other uploader
this.cancelUpload();
}
UploadsManager.UploadQueueComplete(this);
}
}
Uploader.prototype.queueEvent = function (function_body) {
// Warning: Don't call this.debug inside here or you'll create an infinite loop
var self = this;
// Queue the event
this._eventQueue.push(function_body);
// Execute the next queued event
setTimeout(
function () {
self._executeNextEvent();
}, 0
);
};
// Private: callFlash handles function calls made to the Flash element.
// Calls are made with a setTimeout for some functions to work around
// bugs in the ExternalInterface library.
Uploader.prototype.callFlash = function (functionName, argumentArray) {
argumentArray = argumentArray || [];
var returnValue;
if (typeof this.flash[functionName] === 'function') {
// We have to go through all this if/else stuff because the Flash functions don't have apply() and only accept the exact number of arguments.
if (argumentArray.length === 0) {
returnValue = this.flash[functionName]();
} else if (argumentArray.length === 1) {
returnValue = this.flash[functionName](argumentArray[0]);
} else if (argumentArray.length === 2) {
returnValue = this.flash[functionName](argumentArray[0], argumentArray[1]);
} else if (argumentArray.length === 3) {
returnValue = this.flash[functionName](argumentArray[0], argumentArray[1], argumentArray[2]);
} else {
throw 'Too many arguments';
}
// Unescape file post param values
if (returnValue != undefined && typeof returnValue.post === 'object') {
returnValue = this.unescapeFilePostParams(returnValue);
}
return returnValue;
} else {
// alert('invalid function name: ' + functionName);
throw "Invalid function name: " + functionName;
}
};
// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
// properties that contain characters that are not valid for JavaScript identifiers. To work around this
// the Flash Component escapes the parameter names and we must unescape again before passing them along.
Uploader.prototype.unescapeFilePostParams = function (file) {
var reg = /[$]([0-9a-f]{4})/i;
var unescapedPost = {};
var uk;
if (file != undefined) {
for (var k in file.post) {
if (file.post.hasOwnProperty(k)) {
uk = k;
var match;
while ((match = reg.exec(uk)) !== null) {
uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
}
unescapedPost[uk] = file.post[k];
}
}
file.post = unescapedPost;
}
return file;
};
Uploader.prototype.onFlashReady = function() {
this.disableBrowse(false);
UploadsManager.iterate('syncBrowseButton');
}
Uploader.prototype.disableBrowse = function($disabled) {
if (!isset($disabled)) {
$disabled = true;
}
this.queueEvent(
function() {
this.callFlash('SetButtonDisabled', [$disabled]);
}
);
}
Uploader.prototype._resetCounters = function() {
this.StartTime = 0; // time, when upload was started
this.ProgressPercent = 0; // upload progress in percents
this.ProgressTime = 0; // flash upload process callback times
this.total = 0; // total bytes to upload (from all queued files)
this.uploaded = 0; // total uploaded bytes (from all queued files)
}
Uploader.prototype.finalizeUpload = function() {
// hide progress bar only of uploader, that completed it's queue
this.div.style.display = 'none';
this._resetCounters();
}
\ No newline at end of file
Event Timeline
Log In to Comment