From e3d1258a269c0199679013a23cc6f28e61448ac5 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Fri, 25 Jan 2013 09:04:50 +0100 Subject: [PATCH] Updating to latest jquery fileupload version --- .../cors/jquery.postmessage-transport.js | 0 .../cors/jquery.xdr-transport.js | 12 +- .../jquery-fileupload/jquery.fileupload-fp.js | 0 .../jquery-fileupload/jquery.fileupload-ui.js | 116 ++++++++++++++---- .../jquery-fileupload/jquery.fileupload.js | 114 ++++++++++++----- .../jquery.iframe-transport.js | 34 ++--- .../vendor/jquery.ui.widget.js | 96 ++++++++------- 7 files changed, 253 insertions(+), 119 deletions(-) mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js diff --git a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js b/vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js b/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js old mode 100644 new mode 100755 index c42c548..d769f45 --- a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js +++ b/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js @@ -1,5 +1,5 @@ /* - * jQuery XDomainRequest Transport Plugin 1.1.2 + * jQuery XDomainRequest Transport Plugin 1.1.3 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2011, Sebastian Tschan @@ -36,6 +36,7 @@ var xdr; return { send: function (headers, completeCallback) { + var addParamChar = /\?/.test(s.url) ? '&' : '?'; function callback(status, statusText, responses, responseHeaders) { xdr.onload = xdr.onerror = xdr.ontimeout = $.noop; xdr = null; @@ -44,12 +45,13 @@ xdr = new XDomainRequest(); // XDomainRequest only supports GET and POST: if (s.type === 'DELETE') { - s.url = s.url + (/\?/.test(s.url) ? '&' : '?') + - '_method=DELETE'; + s.url = s.url + addParamChar + '_method=DELETE'; s.type = 'POST'; } else if (s.type === 'PUT') { - s.url = s.url + (/\?/.test(s.url) ? '&' : '?') + - '_method=PUT'; + s.url = s.url + addParamChar + '_method=PUT'; + s.type = 'POST'; + } else if (s.type === 'PATCH') { + s.url = s.url + addParamChar + '_method=PATCH'; s.type = 'POST'; } xdr.open(s.type, s.url); diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js old mode 100644 new mode 100755 diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js old mode 100644 new mode 100755 index ad7f2f8..a23efdb --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js @@ -1,5 +1,5 @@ /* - * jQuery File Upload User Interface Plugin 6.11 + * jQuery File Upload User Interface Plugin 7.3 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan @@ -83,7 +83,8 @@ // widget (via file input selection, drag & drop or add API call). // See the basic file upload widget for more information: add: function (e, data) { - var that = $(this).data('fileupload'), + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'), options = that.options, files = data.files; $(this).fileupload('process', data).done(function () { @@ -94,7 +95,7 @@ options.filesContainer[ options.prependFiles ? 'prepend' : 'append' ](data.context); - that._renderPreviews(files, data.context); + that._renderPreviews(data); that._forceReflow(data.context); that._transition(data.context).done( function () { @@ -109,7 +110,8 @@ }, // Callback for the start of each file upload request: send: function (e, data) { - var that = $(this).data('fileupload'); + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'); if (!data.isValidated) { if (!data.maxNumberOfFilesAdjusted) { that._adjustMaxNumberOfFiles(-data.files.length); @@ -138,13 +140,16 @@ }, // Callback for successful uploads: done: function (e, data) { - var that = $(this).data('fileupload'), - template; + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'), + files = that._getFilesFromResponse(data), + template, + deferred; if (data.context) { data.context.each(function (index) { - var file = ($.isArray(data.result) && - data.result[index]) || - {error: 'Empty file upload result'}; + var file = files[index] || + {error: 'Empty file upload result'}, + deferred = that._addFinishedDeferreds(); if (file.error) { that._adjustMaxNumberOfFiles(1); } @@ -158,14 +163,16 @@ function () { data.context = $(this); that._trigger('completed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); } ); } ); }); } else { - if ($.isArray(data.result)) { - $.each(data.result, function (index, file) { + if (files.length) { + $.each(files, function (index, file) { if (data.maxNumberOfFilesAdjusted && file.error) { that._adjustMaxNumberOfFiles(1); } else if (!data.maxNumberOfFilesAdjusted && @@ -175,21 +182,26 @@ }); data.maxNumberOfFilesAdjusted = true; } - template = that._renderDownload(data.result) + template = that._renderDownload(files) .appendTo(that.options.filesContainer); that._forceReflow(template); + deferred = that._addFinishedDeferreds(); that._transition(template).done( function () { data.context = $(this); that._trigger('completed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); } ); } }, // Callback for failed (abort or error) uploads: fail: function (e, data) { - var that = $(this).data('fileupload'), - template; + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'), + template, + deferred; if (data.maxNumberOfFilesAdjusted) { that._adjustMaxNumberOfFiles(data.files.length); } @@ -199,6 +211,7 @@ var file = data.files[index]; file.error = file.error || data.errorThrown || true; + deferred = that._addFinishedDeferreds(); that._transition($(this)).done( function () { var node = $(this); @@ -209,15 +222,20 @@ function () { data.context = $(this); that._trigger('failed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); } ); } ); } else { + deferred = that._addFinishedDeferreds(); that._transition($(this)).done( function () { $(this).remove(); that._trigger('failed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); } ); } @@ -227,14 +245,19 @@ .appendTo(that.options.filesContainer) .data('data', data); that._forceReflow(data.context); + deferred = that._addFinishedDeferreds(); that._transition(data.context).done( function () { data.context = $(this); that._trigger('failed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); } ); } else { that._trigger('failed', e, data); + that._trigger('finished', e, data); + that._addFinishedDeferreds().resolve(); } }, // Callback for upload progress events: @@ -258,7 +281,8 @@ .find('.progress-extended'); if (extendedProgressNode.length) { extendedProgressNode.html( - $this.data('fileupload')._renderExtendedProgress(data) + ($this.data('blueimp-fileupload') || $this.data('fileupload')) + ._renderExtendedProgress(data) ); } globalProgressNode @@ -271,7 +295,9 @@ }, // Callback for uploads start, equivalent to the global ajaxStart event: start: function (e) { - var that = $(this).data('fileupload'); + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'); + that._resetFinishedDeferreds(); that._transition($(this).find('.fileupload-progress')).done( function () { that._trigger('started', e); @@ -280,20 +306,27 @@ }, // Callback for uploads stop, equivalent to the global ajaxStop event: stop: function (e) { - var that = $(this).data('fileupload'); + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'), + deferred = that._addFinishedDeferreds(); + $.when.apply($, that._getFinishedDeferreds()) + .done(function () { + that._trigger('stopped', e); + }); that._transition($(this).find('.fileupload-progress')).done( function () { $(this).find('.progress') .attr('aria-valuenow', '0') .find('.bar').css('width', '0%'); $(this).find('.progress-extended').html(' '); - that._trigger('stopped', e); + deferred.resolve(); } ); }, // Callback for file deletion: destroy: function (e, data) { - var that = $(this).data('fileupload'); + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'); if (data.url) { $.ajax(data); that._adjustMaxNumberOfFiles(1); @@ -307,6 +340,29 @@ } }, + _resetFinishedDeferreds: function () { + this._finishedUploads = []; + }, + + _addFinishedDeferreds: function (deferred) { + if (!deferred) { + deferred = $.Deferred(); + } + this._finishedUploads.push(deferred); + return deferred; + }, + + _getFinishedDeferreds: function () { + return this._finishedUploads; + }, + + _getFilesFromResponse: function (data) { + if (data.result && $.isArray(data.result.files)) { + return data.result.files; + } + return []; + }, + // Link handler, that allows to download files // by drag & drop of the links to the desktop: _enableDragToDesktop: function () { @@ -361,7 +417,7 @@ if (bits >= 1000) { return (bits / 1000).toFixed(2) + ' kbit/s'; } - return bits + ' bit/s'; + return bits.toFixed(2) + ' bit/s'; }, _formatTime: function (seconds) { @@ -472,18 +528,22 @@ )) || dfd.resolveWith(node)) && dfd; }, - _renderPreviews: function (files, nodes) { + _renderPreviews: function (data) { var that = this, options = this.options; - nodes.find('.preview span').each(function (index, element) { - var file = files[index]; + data.context.find('.preview span').each(function (index, element) { + var file = data.files[index]; if (options.previewSourceFileTypes.test(file.type) && ($.type(options.previewSourceMaxFileSize) !== 'number' || file.size < options.previewSourceMaxFileSize)) { that._processingQueue = that._processingQueue.pipe(function () { - var dfd = $.Deferred(); + var dfd = $.Deferred(), + ev = $.Event('previewdone', { + target: element + }); that._renderPreview(file, $(element)).done( function () { + that._trigger(ev.type, ev, data); dfd.resolveWith(that); } ); @@ -691,6 +751,13 @@ this._initRegExpOptions(); }, + _setOption: function (key, value) { + this._super(key, value); + if (key === 'maxNumberOfFiles') { + this._adjustMaxNumberOfFiles(0); + } + }, + _create: function () { this._super(); this._refreshOptionsList.push( @@ -704,6 +771,7 @@ return this._processingQueue; }; } + this._resetFinishedDeferreds(); }, enable: function () { diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js old mode 100644 new mode 100755 index 6356012..04caf69 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js @@ -1,5 +1,5 @@ /* - * jQuery File Upload Plugin 5.19.3 + * jQuery File Upload Plugin 5.21 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan @@ -10,7 +10,7 @@ */ /*jslint nomen: true, unparam: true, regexp: true */ -/*global define, window, document, Blob, FormData, location */ +/*global define, window, document, File, Blob, FormData, location */ (function (factory) { 'use strict'; @@ -33,6 +33,21 @@ $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader); $.support.xhrFormDataFileUpload = !!window.FormData; + // The form.elements propHook is added to filter serialized elements + // to not include file inputs in jQuery 1.9.0. + // This hooks directly into jQuery.fn.serializeArray. + // For more info, see http://bugs.jquery.com/ticket/13306 + $.propHooks.elements = { + get: function (form) { + if ($.nodeName(form, 'form')) { + return $.grep(form.elements, function (elem) { + return !$.nodeName(elem, 'input') || elem.type !== 'file'; + }); + } + return null; + } + }; + // The fileupload widget listens for change events on file input fields defined // via fileInput setting and paste or drop events of the given dropZone. // In addition to the default jQuery Widget methods, the fileupload widget @@ -140,33 +155,58 @@ }, // Other callbacks: + // Callback for the submit event of each file upload: // submit: function (e, data) {}, // .bind('fileuploadsubmit', func); + // Callback for the start of each file upload request: // send: function (e, data) {}, // .bind('fileuploadsend', func); + // Callback for successful uploads: // done: function (e, data) {}, // .bind('fileuploaddone', func); + // Callback for failed (abort or error) uploads: // fail: function (e, data) {}, // .bind('fileuploadfail', func); + // Callback for completed (success, abort or error) requests: // always: function (e, data) {}, // .bind('fileuploadalways', func); + // Callback for upload progress events: // progress: function (e, data) {}, // .bind('fileuploadprogress', func); + // Callback for global upload progress events: // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func); + // Callback for uploads start, equivalent to the global ajaxStart event: // start: function (e) {}, // .bind('fileuploadstart', func); + // Callback for uploads stop, equivalent to the global ajaxStop event: // stop: function (e) {}, // .bind('fileuploadstop', func); + // Callback for change events of the fileInput(s): // change: function (e, data) {}, // .bind('fileuploadchange', func); + // Callback for paste events to the pasteZone(s): // paste: function (e, data) {}, // .bind('fileuploadpaste', func); + // Callback for drop events of the dropZone(s): // drop: function (e, data) {}, // .bind('fileuploaddrop', func); + // Callback for dragover events of the dropZone(s): // dragover: function (e) {}, // .bind('fileuploaddragover', func); + // Callback for the start of each chunk upload request: + // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func); + + // Callback for successful chunk uploads: + // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func); + + // Callback for failed (abort or error) chunk uploads: + // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func); + + // Callback for completed (success, abort or error) chunk upload requests: + // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func); + // The plugin options are used as settings object for the ajax calls. // The following are jQuery ajax settings required for the file uploads: processData: false, @@ -209,10 +249,10 @@ if (typeof options.formData === 'function') { return options.formData(options.form); } - if ($.isArray(options.formData)) { + if ($.isArray(options.formData)) { return options.formData; } - if (options.formData) { + if (options.formData) { formData = []; $.each(options.formData, function (name, value) { formData.push({name: name, value: value}); @@ -341,14 +381,15 @@ if (options.blob) { options.headers['Content-Disposition'] = 'attachment; filename="' + encodeURI(file.name) + '"'; - options.headers['Content-Description'] = encodeURI(file.type); formData.append(paramName, options.blob, file.name); } else { $.each(options.files, function (index, file) { - // File objects are also Blob instances. + // Files are also Blob instances, but some browsers + // (Firefox 3.6) support the File API but not Blobs. // This check allows the tests to run with // dummy objects: - if (file instanceof Blob) { + if ((window.Blob && file instanceof Blob) || + (window.File && file instanceof File)) { formData.append( options.paramName[index] || paramName, file, @@ -438,7 +479,8 @@ // The HTTP request method must be "POST" or "PUT": options.type = (options.type || options.form.prop('method') || '') .toUpperCase(); - if (options.type !== 'POST' && options.type !== 'PUT') { + if (options.type !== 'POST' && options.type !== 'PUT' && + options.type !== 'PATCH') { options.type = 'POST'; } if (!options.formAcceptCharset) { @@ -525,7 +567,8 @@ o.blob = slice.call( file, ub, - ub + mcs + ub + mcs, + file.type ); // Store the current chunk size, as the blob itself // will be dereferenced after data processing: @@ -537,13 +580,15 @@ that._initXHRData(o); // Add progress listeners for this chunk upload: that._initProgressListener(o); - jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context)) + jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) || + that._getXHRPromise(false, o.context)) .done(function (result, textStatus, jqXHR) { ub = that._getUploadedBytes(jqXHR) || (ub + o.chunkSize); - // Create a progress event if upload is done and - // no progress event has been invoked for this chunk: - if (!o.loaded) { + // Create a progress event if upload is done and no progress + // event has been invoked for this chunk, or there has been + // no progress event with loaded equaling total: + if (!o.loaded || o.loaded < o.total) { that._onProgress($.Event('progress', { lengthComputable: true, loaded: ub - o.uploadedBytes, @@ -551,6 +596,11 @@ }), o); } options.uploadedBytes = o.uploadedBytes = ub; + o.result = result; + o.textStatus = textStatus; + o.jqXHR = jqXHR; + that._trigger('chunkdone', null, o); + that._trigger('chunkalways', null, o); if (ub < fs) { // File upload not yet complete, // continue with the next chunk: @@ -563,6 +613,11 @@ } }) .fail(function (jqXHR, textStatus, errorThrown) { + o.jqXHR = jqXHR; + o.textStatus = textStatus; + o.errorThrown = errorThrown; + that._trigger('chunkfail', null, o); + that._trigger('chunkalways', null, o); dfd.rejectWith( o.context, [jqXHR, textStatus, errorThrown] @@ -593,12 +648,16 @@ }, _onDone: function (result, textStatus, jqXHR, options) { - if (!this._isXHRUpload(options)) { - // Create a progress event for each iframe load: + if (!this._isXHRUpload(options) || !options.loaded || + options.loaded < options.total) { + var total = this._getTotal(options.files) || 1; + // Create a progress event for each iframe load, + // or if there has been no progress event with + // loaded equaling total for XHR uploads: this._onProgress($.Event('progress', { lengthComputable: true, - loaded: 1, - total: 1 + loaded: total, + total: total }), options); } options.result = result; @@ -621,15 +680,9 @@ }, _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { + // jqXHRorResult, textStatus and jqXHRorError are added to the + // options object via done and fail callbacks this._active -= 1; - options.textStatus = textStatus; - if (jqXHRorError && jqXHRorError.always) { - options.jqXHR = jqXHRorError; - options.result = jqXHRorResult; - } else { - options.jqXHR = jqXHRorResult; - options.errorThrown = jqXHRorError; - } this._trigger('always', null, options); if (this._active === 0) { // The stop callback is triggered when all uploads have @@ -758,7 +811,8 @@ that._onSend(e, this); return this.jqXHR; }; - return (result = that._trigger('add', e, newData)); + result = that._trigger('add', e, newData); + return result; }); return result; }, @@ -949,10 +1003,12 @@ }, _onDrop: function (e) { - e.preventDefault(); var that = this, dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer, data = {}; + if (dataTransfer && dataTransfer.files && dataTransfer.files.length) { + e.preventDefault(); + } this._getDroppedFiles(dataTransfer).always(function (files) { data.files = files; if (that._trigger('drop', e, data) !== false) { @@ -966,10 +1022,10 @@ if (this._trigger('dragover', e) === false) { return false; } - if (dataTransfer) { + if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1) { dataTransfer.dropEffect = 'copy'; + e.preventDefault(); } - e.preventDefault(); }, _initEventHandlers: function () { diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js b/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js old mode 100644 new mode 100755 index 3b10b5c..ed25895 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js @@ -1,5 +1,5 @@ /* - * jQuery Iframe Transport Plugin 1.5 + * jQuery Iframe Transport Plugin 1.6.1 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2011, Sebastian Tschan @@ -36,13 +36,26 @@ // equivalent to the return data of .serializeArray(), e.g.: // [{name: 'a', value: 1}, {name: 'b', value: 2}] $.ajaxTransport('iframe', function (options) { - if (options.async && (options.type === 'POST' || options.type === 'GET')) { + if (options.async) { var form, - iframe; + iframe, + addParamChar; return { send: function (_, completeCallback) { form = $('
'); form.attr('accept-charset', options.formAcceptCharset); + addParamChar = /\?/.test(options.url) ? '&' : '?'; + // XDomainRequest only supports GET and POST: + if (options.type === 'DELETE') { + options.url = options.url + addParamChar + '_method=DELETE'; + options.type = 'POST'; + } else if (options.type === 'PUT') { + options.url = options.url + addParamChar + '_method=PUT'; + options.type = 'POST'; + } else if (options.type === 'PATCH') { + options.url = options.url + addParamChar + '_method=PATCH'; + options.type = 'POST'; + } // javascript:false as initial iframe src // prevents warning popups on HTTPS in IE6. // IE versions below IE8 cannot set the name property of @@ -96,13 +109,6 @@ .val(field.value) .appendTo(form); }); - // Add a hidden `X-Requested-With` field with the value `IFrame` to the - // form, to help server-side code to determine that the upload happened - // through this transport. - $('') - .prop('name', 'X-Requested-With') - .val('IFrame') - .appendTo(form); } if (options.fileInput && options.fileInput.length && options.type === 'POST') { @@ -162,16 +168,16 @@ $.ajaxSetup({ converters: { 'iframe text': function (iframe) { - return $(iframe[0].body).text(); + return iframe && $(iframe[0].body).text(); }, 'iframe json': function (iframe) { - return $.parseJSON($(iframe[0].body).text()); + return iframe && $.parseJSON($(iframe[0].body).text()); }, 'iframe html': function (iframe) { - return $(iframe[0].body).html(); + return iframe && $(iframe[0].body).html(); }, 'iframe script': function (iframe) { - return $.globalEval($(iframe[0].body).text()); + return iframe && $.globalEval($(iframe[0].body).text()); } } }); diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js b/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js old mode 100644 new mode 100755 index 886aff6..f5d71a1 --- a/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js +++ b/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js @@ -1,8 +1,8 @@ /* - * jQuery UI Widget 1.9.1+amd + * jQuery UI Widget 1.10.0+amd * https://github.com/blueimp/jQuery-File-Upload * - * Copyright 2012 jQuery Foundation and other contributors + * Copyright 2013 jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license * @@ -34,6 +34,9 @@ $.cleanData = function( elems ) { $.widget = function( name, base, prototype ) { var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, namespace = name.split( "." )[ 0 ]; name = name.split( "." )[ 1 ]; @@ -80,43 +83,43 @@ $.widget = function( name, base, prototype ) { // inheriting from basePrototype.options = $.widget.extend( {}, basePrototype.options ); $.each( prototype, function( prop, value ) { - if ( $.isFunction( value ) ) { - prototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); + if ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); }); constructor.prototype = $.widget.extend( basePrototype, { // TODO: remove support for widgetEventPrefix // always use the name + a colon as the prefix, e.g., draggable:start // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: basePrototype.widgetEventPrefix || name - }, prototype, { + widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name + }, proxiedPrototype, { constructor: constructor, namespace: namespace, widgetName: name, - // TODO remove widgetBaseClass, see #8155 - widgetBaseClass: fullName, widgetFullName: fullName }); @@ -169,7 +172,7 @@ $.widget.extend = function( target ) { }; $.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName; + var fullName = object.prototype.widgetFullName || name; $.fn[ name ] = function( options ) { var isMethodCall = typeof options === "string", args = slice.call( arguments, 1 ), @@ -205,7 +208,7 @@ $.widget.bridge = function( name, object ) { if ( instance ) { instance.option( options || {} )._init(); } else { - new object( options, this ); + $.data( this, fullName, new object( options, this ) ); } }); } @@ -242,11 +245,8 @@ $.Widget.prototype = { this.focusable = $(); if ( element !== this ) { - // 1.9 BC for #7810 - // TODO remove dual storage - $.data( element, this.widgetName, this ); $.data( element, this.widgetFullName, this ); - this._on( this.element, { + this._on( true, this.element, { remove: function( event ) { if ( event.target === element ) { this.destroy(); @@ -370,9 +370,17 @@ $.Widget.prototype = { return this._setOption( "disabled", true ); }, - _on: function( element, handlers ) { + _on: function( suppressDisabledCheck, element, handlers ) { var delegateElement, instance = this; + + // no suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + // no element argument, shuffle and use this.element if ( !handlers ) { handlers = element; @@ -389,8 +397,9 @@ $.Widget.prototype = { // allow widgets to customize the disabled handling // - disabled as an array instead of boolean // - disabled class as method for disabling individual parts - if ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) { + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { return; } return ( typeof handler === "string" ? instance[ handler ] : handler ) @@ -502,7 +511,7 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { if ( options.delay ) { element.delay( options.delay ); } - if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { element[ method ]( options ); } else if ( effectName !== method && element[ effectName ] ) { element[ effectName ]( options.duration, options.easing, callback ); @@ -518,11 +527,4 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { }; }); -// DEPRECATED -if ( $.uiBackCompat !== false ) { - $.Widget.prototype._getCreateOptions = function() { - return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; - }; -} - }));