#2284 jQuery Fileupload 업데이트

- 9.22.0
This commit is contained in:
bnu 2018-08-17 16:13:19 +09:00 committed by Kijin Sung
parent cb66b4e5df
commit d9a7b89a74
19 changed files with 863 additions and 593 deletions

View file

@ -0,0 +1,21 @@
MIT License
Copyright © 2010 Sebastian Tschan, https://blueimp.net
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,20 +1,20 @@
@charset "UTF-8"; @charset "UTF-8";
/* /*
* jQuery File Upload Plugin NoScript CSS 1.2.0 * jQuery File Upload Plugin NoScript CSS
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2013, Sebastian Tschan * Copyright 2013, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
.fileinput-button input { .fileinput-button input {
position: static; position: static;
opacity: 1; opacity: 1;
filter: none; filter: none;
font-size: inherit; font-size: inherit !important;
direction: inherit; direction: inherit;
} }
.fileinput-button span { .fileinput-button span {

View file

@ -1,13 +1,13 @@
@charset "UTF-8"; @charset "UTF-8";
/* /*
* jQuery File Upload UI Plugin NoScript CSS 8.8.5 * jQuery File Upload UI Plugin NoScript CSS
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2012, Sebastian Tschan * Copyright 2012, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
.fileinput-button i, .fileinput-button i,

View file

@ -1,13 +1,13 @@
@charset "UTF-8"; @charset "UTF-8";
/* /*
* jQuery File Upload UI Plugin CSS 9.0.0 * jQuery File Upload UI Plugin CSS
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2010, Sebastian Tschan * Copyright 2010, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
.fileupload-buttonbar .btn, .fileupload-buttonbar .btn,

View file

@ -1,18 +1,19 @@
@charset "UTF-8"; @charset "UTF-8";
/* /*
* jQuery File Upload Plugin CSS 1.3.0 * jQuery File Upload Plugin CSS
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2013, Sebastian Tschan * Copyright 2013, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
.fileinput-button { .fileinput-button {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
display: inline-block;
} }
.fileinput-button input { .fileinput-button input {
position: absolute; position: absolute;
@ -21,7 +22,7 @@
margin: 0; margin: 0;
opacity: 0; opacity: 0;
-ms-filter: 'alpha(opacity=0)'; -ms-filter: 'alpha(opacity=0)';
font-size: 200px; font-size: 200px !important;
direction: ltr; direction: ltr;
cursor: pointer; cursor: pointer;
} }

View file

@ -1,18 +1,18 @@
/* /*
* jQuery File Upload Plugin Angular JS Example 1.2.1 * jQuery File Upload Plugin Angular JS Example
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2013, Sebastian Tschan * Copyright 2013, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* jshint nomen:false */ /* jshint nomen:false */
/* global window, angular */ /* global window, angular */
(function () { ;(function () {
'use strict'; 'use strict';
var isOnGitHub = window.location.hostname === 'blueimp.github.io', var isOnGitHub = window.location.hostname === 'blueimp.github.io',

View file

@ -1,17 +1,17 @@
/* /*
* jQuery postMessage Transport Plugin 1.1.2 * jQuery postMessage Transport Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2011, Sebastian Tschan * Copyright 2011, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* global define, require, window, document */ /* global define, require, window, document */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
@ -64,6 +64,12 @@
loc = $('<a>').prop('href', options.postMessage)[0], loc = $('<a>').prop('href', options.postMessage)[0],
target = loc.protocol + '//' + loc.host, target = loc.protocol + '//' + loc.host,
xhrUpload = options.xhr().upload; xhrUpload = options.xhr().upload;
// IE always includes the port for the host property of a link
// element, but not in the location.host or origin property for the
// default http port 80 and https port 443, so we strip it:
if (/^(http:\/\/.+:80)|(https:\/\/.+:443)$/.test(target)) {
target = target.replace(/:(80|443)$/, '');
}
return { return {
send: function (_, completeCallback) { send: function (_, completeCallback) {
counter += 1; counter += 1;

View file

@ -1,12 +1,12 @@
/* /*
* jQuery XDomainRequest Transport Plugin 1.1.4 * jQuery XDomainRequest Transport Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2011, Sebastian Tschan * Copyright 2011, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
* *
* Based on Julian Aubourg's ajaxHooks xdr.js: * Based on Julian Aubourg's ajaxHooks xdr.js:
* https://github.com/jaubourg/ajaxHooks/ * https://github.com/jaubourg/ajaxHooks/
@ -14,7 +14,7 @@
/* global define, require, window, XDomainRequest */ /* global define, require, window, XDomainRequest */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:

View file

@ -1,18 +1,18 @@
/* /*
* jQuery File Upload AngularJS Plugin 2.2.0 * jQuery File Upload AngularJS Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2013, Sebastian Tschan * Copyright 2013, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* jshint nomen:false */ /* jshint nomen:false */
/* global define, angular */ /* global define, angular, require */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
@ -24,6 +24,16 @@
'./jquery.fileupload-video', './jquery.fileupload-video',
'./jquery.fileupload-validate' './jquery.fileupload-validate'
], factory); ], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(
require('jquery'),
require('angular'),
require('./jquery.fileupload-image'),
require('./jquery.fileupload-audio'),
require('./jquery.fileupload-video'),
require('./jquery.fileupload-validate')
);
} else { } else {
factory(); factory();
} }
@ -91,7 +101,7 @@
angular.forEach(data.files, function (file) { angular.forEach(data.files, function (file) {
filesCopy.push(file); filesCopy.push(file);
}); });
scope.$apply(function () { scope.$parent.$applyAsync(function () {
addFileMethods(scope, data); addFileMethods(scope, data);
var method = scope.option('prependFiles') ? var method = scope.option('prependFiles') ?
'unshift' : 'push'; 'unshift' : 'push';
@ -100,7 +110,7 @@
data.process(function () { data.process(function () {
return scope.process(data); return scope.process(data);
}).always(function () { }).always(function () {
scope.$apply(function () { scope.$parent.$applyAsync(function () {
addFileMethods(scope, data); addFileMethods(scope, data);
scope.replace(filesCopy, data.files); scope.replace(filesCopy, data.files);
}); });
@ -112,12 +122,6 @@
} }
}); });
}, },
progress: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
data.scope.$apply();
},
done: function (e, data) { done: function (e, data) {
if (e.isDefaultPrevented()) { if (e.isDefaultPrevented()) {
return false; return false;
@ -197,8 +201,8 @@
// The FileUploadController initializes the fileupload widget and // The FileUploadController initializes the fileupload widget and
// provides scope methods to control the File Upload functionality: // provides scope methods to control the File Upload functionality:
.controller('FileUploadController', [ .controller('FileUploadController', [
'$scope', '$element', '$attrs', '$window', 'fileUpload', '$scope', '$element', '$attrs', '$window', 'fileUpload','$q',
function ($scope, $element, $attrs, $window, fileUpload) { function ($scope, $element, $attrs, $window, fileUpload, $q) {
var uploadMethods = { var uploadMethods = {
progress: function () { progress: function () {
return $element.fileupload('progress'); return $element.fileupload('progress');
@ -260,19 +264,21 @@
$scope.applyOnQueue = function (method) { $scope.applyOnQueue = function (method) {
var list = this.queue.slice(0), var list = this.queue.slice(0),
i, i,
file; file,
promises = [];
for (i = 0; i < list.length; i += 1) { for (i = 0; i < list.length; i += 1) {
file = list[i]; file = list[i];
if (file[method]) { if (file[method]) {
file[method](); promises.push(file[method]());
} }
} }
return $q.all(promises);
}; };
$scope.submit = function () { $scope.submit = function () {
this.applyOnQueue('$submit'); return this.applyOnQueue('$submit');
}; };
$scope.cancel = function () { $scope.cancel = function () {
this.applyOnQueue('$cancel'); return this.applyOnQueue('$cancel');
}; };
// Add upload methods to the scope: // Add upload methods to the scope:
angular.extend($scope, uploadMethods); angular.extend($scope, uploadMethods);
@ -320,9 +326,11 @@
'fileuploadprocessalways', 'fileuploadprocessalways',
'fileuploadprocessstop' 'fileuploadprocessstop'
].join(' '), function (e, data) { ].join(' '), function (e, data) {
$scope.$parent.$applyAsync(function () {
if ($scope.$emit(e.type, data).defaultPrevented) { if ($scope.$emit(e.type, data).defaultPrevented) {
e.preventDefault(); e.preventDefault();
} }
});
}).on('remove', function () { }).on('remove', function () {
// Remove upload methods from the scope, // Remove upload methods from the scope,
// when the widget is removed: // when the widget is removed:

View file

@ -1,18 +1,18 @@
/* /*
* jQuery File Upload Audio Preview Plugin 1.0.4 * jQuery File Upload Audio Preview Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2013, Sebastian Tschan * Copyright 2013, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* jshint nomen:false */ /* jshint nomen:false */
/* global define, require, window, document */ /* global define, require, window, document */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
@ -25,7 +25,8 @@
// Node/CommonJS: // Node/CommonJS:
factory( factory(
require('jquery'), require('jquery'),
require('load-image') require('blueimp-load-image/js/load-image'),
require('./jquery.fileupload-process')
); );
} else { } else {
// Browser globals: // Browser globals:

View file

@ -1,18 +1,18 @@
/* /*
* jQuery File Upload Image Preview & Resize Plugin 1.7.3 * jQuery File Upload Image Preview & Resize Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2013, Sebastian Tschan * Copyright 2013, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* jshint nomen:false */ /* jshint nomen:false */
/* global define, require, window, Blob */ /* global define, require, window, Blob */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
@ -20,8 +20,8 @@
'jquery', 'jquery',
'load-image', 'load-image',
'load-image-meta', 'load-image-meta',
'load-image-scale',
'load-image-exif', 'load-image-exif',
'load-image-ios',
'canvas-to-blob', 'canvas-to-blob',
'./jquery.fileupload-process' './jquery.fileupload-process'
], factory); ], factory);
@ -29,7 +29,12 @@
// Node/CommonJS: // Node/CommonJS:
factory( factory(
require('jquery'), require('jquery'),
require('load-image') require('blueimp-load-image/js/load-image'),
require('blueimp-load-image/js/load-image-meta'),
require('blueimp-load-image/js/load-image-scale'),
require('blueimp-load-image/js/load-image-exif'),
require('blueimp-canvas-to-blob'),
require('./jquery.fileupload-process')
); );
} else { } else {
// Browser globals: // Browser globals:

View file

@ -1,25 +1,31 @@
/* /*
* jQuery File Upload jQuery UI Plugin 8.7.2 * jQuery File Upload jQuery UI Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2013, Sebastian Tschan * Copyright 2013, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* jshint nomen:false */ /* jshint nomen:false */
/* global define, require, window */ /* global define, require, window */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
define(['jquery', './jquery.fileupload-ui'], factory); define([
'jquery',
'./jquery.fileupload-ui'
], factory);
} else if (typeof exports === 'object') { } else if (typeof exports === 'object') {
// Node/CommonJS: // Node/CommonJS:
factory(require('jquery')); factory(
require('jquery'),
require('./jquery.fileupload-ui')
);
} else { } else {
// Browser globals: // Browser globals:
factory(window.jQuery); factory(window.jQuery);

View file

@ -1,18 +1,18 @@
/* /*
* jQuery File Upload Processing Plugin 1.3.1 * jQuery File Upload Processing Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2012, Sebastian Tschan * Copyright 2012, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* jshint nomen:false */ /* jshint nomen:false */
/* global define, require, window */ /* global define, require, window */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
@ -22,7 +22,10 @@
], factory); ], factory);
} else if (typeof exports === 'object') { } else if (typeof exports === 'object') {
// Node/CommonJS: // Node/CommonJS:
factory(require('jquery')); factory(
require('jquery'),
require('./jquery.fileupload')
);
} else { } else {
// Browser globals: // Browser globals:
factory( factory(
@ -84,7 +87,7 @@
settings settings
); );
}; };
chain = chain.pipe(func, settings.always && func); chain = chain.then(func, settings.always && func);
}); });
chain chain
.done(function () { .done(function () {
@ -151,7 +154,7 @@
}; };
opts.index = index; opts.index = index;
that._processing += 1; that._processing += 1;
that._processingQueue = that._processingQueue.pipe(func, func) that._processingQueue = that._processingQueue.then(func, func)
.always(function () { .always(function () {
that._processing -= 1; that._processing -= 1;
if (that._processing === 0) { if (that._processing === 0) {

View file

@ -1,24 +1,24 @@
/* /*
* jQuery File Upload User Interface Plugin 9.6.1 * jQuery File Upload User Interface Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2010, Sebastian Tschan * Copyright 2010, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* jshint nomen:false */ /* jshint nomen:false */
/* global define, require, window */ /* global define, require, window */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
define([ define([
'jquery', 'jquery',
'tmpl', 'blueimp-tmpl',
'./jquery.fileupload-image', './jquery.fileupload-image',
'./jquery.fileupload-audio', './jquery.fileupload-audio',
'./jquery.fileupload-video', './jquery.fileupload-video',
@ -28,7 +28,11 @@
// Node/CommonJS: // Node/CommonJS:
factory( factory(
require('jquery'), require('jquery'),
require('tmpl') require('blueimp-tmpl'),
require('./jquery.fileupload-image'),
require('./jquery.fileupload-audio'),
require('./jquery.fileupload-video'),
require('./jquery.fileupload-validate')
); );
} else { } else {
// Browser globals: // Browser globals:

View file

@ -1,17 +1,17 @@
/* /*
* jQuery File Upload Validation Plugin 1.1.3 * jQuery File Upload Validation Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2013, Sebastian Tschan * Copyright 2013, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* global define, require, window */ /* global define, require, window */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
@ -21,7 +21,10 @@
], factory); ], factory);
} else if (typeof exports === 'object') { } else if (typeof exports === 'object') {
// Node/CommonJS: // Node/CommonJS:
factory(require('jquery')); factory(
require('jquery'),
require('./jquery.fileupload-process')
);
} else { } else {
// Browser globals: // Browser globals:
factory( factory(

View file

@ -1,18 +1,18 @@
/* /*
* jQuery File Upload Video Preview Plugin 1.0.4 * jQuery File Upload Video Preview Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2013, Sebastian Tschan * Copyright 2013, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* jshint nomen:false */ /* jshint nomen:false */
/* global define, require, window, document */ /* global define, require, window, document */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
@ -25,7 +25,8 @@
// Node/CommonJS: // Node/CommonJS:
factory( factory(
require('jquery'), require('jquery'),
require('load-image') require('blueimp-load-image/js/load-image'),
require('./jquery.fileupload-process')
); );
} else { } else {
// Browser globals: // Browser globals:

View file

@ -1,24 +1,24 @@
/* /*
* jQuery File Upload Plugin 5.42.3 * jQuery File Upload Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2010, Sebastian Tschan * Copyright 2010, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* jshint nomen:false */ /* jshint nomen:false */
/* global define, require, window, document, location, Blob, FormData */ /* global define, require, window, document, location, Blob, FormData */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
define([ define([
'jquery', 'jquery',
'jquery.ui.widget' 'jquery-ui/ui/widget'
], factory); ], factory);
} else if (typeof exports === 'object') { } else if (typeof exports === 'object') {
// Node/CommonJS: // Node/CommonJS:
@ -43,7 +43,7 @@
'|(Kindle/(1\\.0|2\\.[05]|3\\.0))' '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
).test(window.navigator.userAgent) || ).test(window.navigator.userAgent) ||
// Feature detection for all other devices: // Feature detection for all other devices:
$('<input type="file">').prop('disabled')); $('<input type="file"/>').prop('disabled'));
// The FileReader API is not actually used, but works as feature detection, // The FileReader API is not actually used, but works as feature detection,
// as some Safari versions (5?) support XHR file uploads via the FormData API, // as some Safari versions (5?) support XHR file uploads via the FormData API,
@ -453,7 +453,7 @@
} }
if (!multipart || options.blob || !this._isInstanceOf('File', file)) { if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
options.headers['Content-Disposition'] = 'attachment; filename="' + options.headers['Content-Disposition'] = 'attachment; filename="' +
encodeURI(file.name) + '"'; encodeURI(file.uploadName || file.name) + '"';
} }
if (!multipart) { if (!multipart) {
options.contentType = file.type || 'application/octet-stream'; options.contentType = file.type || 'application/octet-stream';
@ -489,7 +489,11 @@
}); });
} }
if (options.blob) { if (options.blob) {
formData.append(paramName, options.blob, file.name); formData.append(
paramName,
options.blob,
file.uploadName || file.name
);
} else { } else {
$.each(options.files, function (index, file) { $.each(options.files, function (index, file) {
// This check allows the tests to run with // This check allows the tests to run with
@ -652,7 +656,7 @@
data.process = function (resolveFunc, rejectFunc) { data.process = function (resolveFunc, rejectFunc) {
if (resolveFunc || rejectFunc) { if (resolveFunc || rejectFunc) {
data._processQueue = this._processQueue = data._processQueue = this._processQueue =
(this._processQueue || getPromise([this])).pipe( (this._processQueue || getPromise([this])).then(
function () { function () {
if (data.errorThrown) { if (data.errorThrown) {
return $.Deferred() return $.Deferred()
@ -660,7 +664,7 @@
} }
return getPromise(arguments); return getPromise(arguments);
} }
).pipe(resolveFunc, rejectFunc); ).then(resolveFunc, rejectFunc);
} }
return this._processQueue || getPromise([this]); return this._processQueue || getPromise([this]);
}; };
@ -730,7 +734,7 @@
promise = dfd.promise(), promise = dfd.promise(),
jqXHR, jqXHR,
upload; upload;
if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) || if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) ||
options.data) { options.data) {
return false; return false;
} }
@ -753,7 +757,7 @@
o.blob = slice.call( o.blob = slice.call(
file, file,
ub, ub,
ub + mcs, ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),
file.type file.type
); );
// Store the current chunk size, as the blob itself // Store the current chunk size, as the blob itself
@ -945,9 +949,9 @@
if (this.options.limitConcurrentUploads > 1) { if (this.options.limitConcurrentUploads > 1) {
slot = $.Deferred(); slot = $.Deferred();
this._slots.push(slot); this._slots.push(slot);
pipe = slot.pipe(send); pipe = slot.then(send);
} else { } else {
this._sequence = this._sequence.pipe(send, send); this._sequence = this._sequence.then(send, send);
pipe = this._sequence; pipe = this._sequence;
} }
// Return the piped Promise object, enhanced with an abort method, // Return the piped Promise object, enhanced with an abort method,
@ -1046,13 +1050,19 @@
_replaceFileInput: function (data) { _replaceFileInput: function (data) {
var input = data.fileInput, var input = data.fileInput,
inputClone = input.clone(true); inputClone = input.clone(true),
restoreFocus = input.is(document.activeElement);
// Add a reference for the new cloned file input to the data argument: // Add a reference for the new cloned file input to the data argument:
data.fileInputClone = inputClone; data.fileInputClone = inputClone;
$('<form></form>').append(inputClone)[0].reset(); $('<form></form>').append(inputClone)[0].reset();
// Detaching allows to insert the fileInput on another form // Detaching allows to insert the fileInput on another form
// without loosing the file input value: // without loosing the file input value:
input.after(inputClone).detach(); input.after(inputClone).detach();
// If the fileInput had focus before it was detached,
// restore focus to the inputClone.
if (restoreFocus) {
inputClone.focus();
}
// Avoid memory leaks with the detached file input: // Avoid memory leaks with the detached file input:
$.cleanData(input.unbind('remove')); $.cleanData(input.unbind('remove'));
// Replace the original file input element in the fileInput // Replace the original file input element in the fileInput
@ -1074,6 +1084,8 @@
_handleFileTreeEntry: function (entry, path) { _handleFileTreeEntry: function (entry, path) {
var that = this, var that = this,
dfd = $.Deferred(), dfd = $.Deferred(),
entries = [],
dirReader,
errorHandler = function (e) { errorHandler = function (e) {
if (e && !e.entry) { if (e && !e.entry) {
e.entry = entry; e.entry = entry;
@ -1101,8 +1113,7 @@
readEntries(); readEntries();
} }
}, errorHandler); }, errorHandler);
}, };
dirReader, entries = [];
path = path || ''; path = path || '';
if (entry.isFile) { if (entry.isFile) {
if (entry._file) { if (entry._file) {
@ -1119,7 +1130,7 @@
dirReader = entry.createReader(); dirReader = entry.createReader();
readEntries(); readEntries();
} else { } else {
// Return an empy list for file system items // Return an empty list for file system items
// other than files or directories: // other than files or directories:
dfd.resolve([]); dfd.resolve([]);
} }
@ -1133,7 +1144,7 @@
$.map(entries, function (entry) { $.map(entries, function (entry) {
return that._handleFileTreeEntry(entry, path); return that._handleFileTreeEntry(entry, path);
}) })
).pipe(function () { ).then(function () {
return Array.prototype.concat.apply( return Array.prototype.concat.apply(
[], [],
arguments arguments
@ -1202,7 +1213,7 @@
return $.when.apply( return $.when.apply(
$, $,
$.map(fileInput, this._getSingleFileInputFiles) $.map(fileInput, this._getSingleFileInputFiles)
).pipe(function () { ).then(function () {
return Array.prototype.concat.apply( return Array.prototype.concat.apply(
[], [],
arguments arguments
@ -1305,6 +1316,10 @@
this._off(this.options.fileInput, 'change'); this._off(this.options.fileInput, 'change');
}, },
_destroy: function () {
this._destroyEventHandlers();
},
_setOption: function (key, value) { _setOption: function (key, value) {
var reinit = $.inArray(key, this._specialOptions) !== -1; var reinit = $.inArray(key, this._specialOptions) !== -1;
if (reinit) { if (reinit) {

View file

@ -1,17 +1,17 @@
/* /*
* jQuery Iframe Transport Plugin 1.8.3 * jQuery Iframe Transport Plugin
* https://github.com/blueimp/jQuery-File-Upload * https://github.com/blueimp/jQuery-File-Upload
* *
* Copyright 2011, Sebastian Tschan * Copyright 2011, Sebastian Tschan
* https://blueimp.net * https://blueimp.net
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
/* global define, require, window, document */ /* global define, require, window, document, JSON */
(function (factory) { ;(function (factory) {
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module: // Register as an anonymous AMD module:
@ -27,7 +27,14 @@
'use strict'; 'use strict';
// Helper variable to create unique names for the transport iframes: // Helper variable to create unique names for the transport iframes:
var counter = 0; var counter = 0,
jsonAPI = $,
jsonParse = 'parseJSON';
if ('JSON' in window && 'parse' in JSON) {
jsonAPI = JSON;
jsonParse = 'parse';
}
// The iframe transport accepts four additional options: // The iframe transport accepts four additional options:
// options.fileInput: a jQuery collection of file input fields // options.fileInput: a jQuery collection of file input fields
@ -197,7 +204,7 @@
return iframe && $(iframe[0].body).text(); return iframe && $(iframe[0].body).text();
}, },
'iframe json': function (iframe) { 'iframe json': function (iframe) {
return iframe && $.parseJSON($(iframe[0].body).text()); return iframe && jsonAPI[jsonParse]($(iframe[0].body).text());
}, },
'iframe html': function (iframe) { 'iframe html': function (iframe) {
return iframe && $(iframe[0].body).html(); return iframe && $(iframe[0].body).html();

View file

@ -1,43 +1,53 @@
/*! jQuery UI - v1.11.1+CommonJS - 2014-09-17 /*! jQuery UI - v1.12.1+CommonJS - 2018-02-10
* http://jqueryui.com * http://jqueryui.com
* Includes: widget.js * Includes: widget.js
* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ * Copyright jQuery Foundation and other contributors; Licensed MIT */
(function( factory ) { (function( factory ) {
if ( typeof define === "function" && define.amd ) { if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module. // AMD. Register as an anonymous module.
define([ "jquery" ], factory ); define([ "jquery" ], factory );
} else if ( typeof exports === "object" ) {
} else if (typeof exports === "object") { // Node/CommonJS
// Node/CommonJS: factory( require( "jquery" ) );
factory(require("jquery"));
} else { } else {
// Browser globals // Browser globals
factory( jQuery ); factory( jQuery );
} }
}(function( $ ) { }(function( $ ) {
/*!
* jQuery UI Widget 1.11.1 $.ui = $.ui || {};
var version = $.ui.version = "1.12.1";
/*!
* jQuery UI Widget 1.12.1
* http://jqueryui.com * http://jqueryui.com
* *
* Copyright 2014 jQuery Foundation and other contributors * Copyright jQuery Foundation and other contributors
* Released under the MIT license. * Released under the MIT license.
* http://jquery.org/license * http://jquery.org/license
*
* http://api.jqueryui.com/jQuery.widget/
*/ */
//>>label: Widget
//>>group: Core
//>>description: Provides a factory for creating stateful widgets with a common API.
//>>docs: http://api.jqueryui.com/jQuery.widget/
//>>demos: http://jqueryui.com/widget/
var widget_uuid = 0,
widget_slice = Array.prototype.slice;
$.cleanData = (function( orig ) {
var widgetUuid = 0;
var widgetSlice = Array.prototype.slice;
$.cleanData = ( function( orig ) {
return function( elems ) { return function( elems ) {
var events, elem, i; var events, elem, i;
for ( i = 0; (elem = elems[i]) != null; i++ ) { for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
try { try {
// Only trigger remove when necessary to save time // Only trigger remove when necessary to save time
@ -46,29 +56,34 @@ $.cleanData = (function( orig ) {
$( elem ).triggerHandler( "remove" ); $( elem ).triggerHandler( "remove" );
} }
// http://bugs.jquery.com/ticket/8235 // Http://bugs.jquery.com/ticket/8235
} catch( e ) {} } catch ( e ) {}
} }
orig( elems ); orig( elems );
}; };
})( $.cleanData ); } )( $.cleanData );
$.widget = function( name, base, prototype ) { $.widget = function( name, base, prototype ) {
var fullName, existingConstructor, constructor, basePrototype, var existingConstructor, constructor, basePrototype;
// proxiedPrototype allows the provided prototype to remain unmodified
// ProxiedPrototype allows the provided prototype to remain unmodified
// so that it can be used as a mixin for multiple widgets (#8876) // so that it can be used as a mixin for multiple widgets (#8876)
proxiedPrototype = {}, var proxiedPrototype = {};
namespace = name.split( "." )[ 0 ];
var namespace = name.split( "." )[ 0 ];
name = name.split( "." )[ 1 ]; name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name; var fullName = namespace + "-" + name;
if ( !prototype ) { if ( !prototype ) {
prototype = base; prototype = base;
base = $.Widget; base = $.Widget;
} }
// create selector for plugin if ( $.isArray( prototype ) ) {
prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
}
// Create selector for plugin
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
return !!$.data( elem, fullName ); return !!$.data( elem, fullName );
}; };
@ -76,30 +91,35 @@ $.widget = function( name, base, prototype ) {
$[ namespace ] = $[ namespace ] || {}; $[ namespace ] = $[ namespace ] || {};
existingConstructor = $[ namespace ][ name ]; existingConstructor = $[ namespace ][ name ];
constructor = $[ namespace ][ name ] = function( options, element ) { constructor = $[ namespace ][ name ] = function( options, element ) {
// allow instantiation without "new" keyword
// Allow instantiation without "new" keyword
if ( !this._createWidget ) { if ( !this._createWidget ) {
return new constructor( options, element ); return new constructor( options, element );
} }
// allow instantiation without initializing for simple inheritance // Allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args) // must use "new" keyword (the code above always passes args)
if ( arguments.length ) { if ( arguments.length ) {
this._createWidget( options, element ); this._createWidget( options, element );
} }
}; };
// extend with the existing constructor to carry over any static properties
// Extend with the existing constructor to carry over any static properties
$.extend( constructor, existingConstructor, { $.extend( constructor, existingConstructor, {
version: prototype.version, version: prototype.version,
// copy the object used to create the prototype in case we need to
// Copy the object used to create the prototype in case we need to
// redefine the widget later // redefine the widget later
_proto: $.extend( {}, prototype ), _proto: $.extend( {}, prototype ),
// track widgets that inherit from this widget in case this widget is
// Track widgets that inherit from this widget in case this widget is
// redefined after a widget inherits from it // redefined after a widget inherits from it
_childConstructors: [] _childConstructors: []
}); } );
basePrototype = new base(); basePrototype = new base();
// we need to make the options hash a property directly on the new instance
// We need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're // otherwise we'll modify the options hash on the prototype that we're
// inheriting from // inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options ); basePrototype.options = $.widget.extend( {}, basePrototype.options );
@ -108,17 +128,19 @@ $.widget = function( name, base, prototype ) {
proxiedPrototype[ prop ] = value; proxiedPrototype[ prop ] = value;
return; return;
} }
proxiedPrototype[ prop ] = (function() { proxiedPrototype[ prop ] = ( function() {
var _super = function() { function _super() {
return base.prototype[ prop ].apply( this, arguments ); return base.prototype[ prop ].apply( this, arguments );
}, }
_superApply = function( args ) {
function _superApply( args ) {
return base.prototype[ prop ].apply( this, args ); return base.prototype[ prop ].apply( this, args );
}; }
return function() { return function() {
var __super = this._super, var __super = this._super;
__superApply = this._superApply, var __superApply = this._superApply;
returnValue; var returnValue;
this._super = _super; this._super = _super;
this._superApply = _superApply; this._superApply = _superApply;
@ -130,19 +152,20 @@ $.widget = function( name, base, prototype ) {
return returnValue; return returnValue;
}; };
})(); } )();
}); } );
constructor.prototype = $.widget.extend( basePrototype, { constructor.prototype = $.widget.extend( basePrototype, {
// TODO: remove support for widgetEventPrefix // TODO: remove support for widgetEventPrefix
// always use the name + a colon as the prefix, e.g., draggable:start // always use the name + a colon as the prefix, e.g., draggable:start
// don't prefix for widgets that aren't DOM-based // don't prefix for widgets that aren't DOM-based
widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
}, proxiedPrototype, { }, proxiedPrototype, {
constructor: constructor, constructor: constructor,
namespace: namespace, namespace: namespace,
widgetName: name, widgetName: name,
widgetFullName: fullName widgetFullName: fullName
}); } );
// If this widget is being redefined then we need to find all widgets that // If this widget is being redefined then we need to find all widgets that
// are inheriting from it and redefine all of them so that they inherit from // are inheriting from it and redefine all of them so that they inherit from
@ -152,11 +175,13 @@ $.widget = function( name, base, prototype ) {
$.each( existingConstructor._childConstructors, function( i, child ) { $.each( existingConstructor._childConstructors, function( i, child ) {
var childPrototype = child.prototype; var childPrototype = child.prototype;
// redefine the child widget using the same prototype that was // Redefine the child widget using the same prototype that was
// originally used, but inherit from the new version of the base // originally used, but inherit from the new version of the base
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
}); child._proto );
// remove the list of existing child constructors from the old constructor } );
// Remove the list of existing child constructors from the old constructor
// so the old child constructors can be garbage collected // so the old child constructors can be garbage collected
delete existingConstructor._childConstructors; delete existingConstructor._childConstructors;
} else { } else {
@ -166,24 +191,28 @@ $.widget = function( name, base, prototype ) {
$.widget.bridge( name, constructor ); $.widget.bridge( name, constructor );
return constructor; return constructor;
}; };
$.widget.extend = function( target ) {
var input = widgetSlice.call( arguments, 1 );
var inputIndex = 0;
var inputLength = input.length;
var key;
var value;
$.widget.extend = function( target ) {
var input = widget_slice.call( arguments, 1 ),
inputIndex = 0,
inputLength = input.length,
key,
value;
for ( ; inputIndex < inputLength; inputIndex++ ) { for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) { for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ]; value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
// Clone objects // Clone objects
if ( $.isPlainObject( value ) ) { if ( $.isPlainObject( value ) ) {
target[ key ] = $.isPlainObject( target[ key ] ) ? target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) : $.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects // Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value ); $.widget.extend( {}, value );
// Copy everything else by reference // Copy everything else by reference
} else { } else {
target[ key ] = value; target[ key ] = value;
@ -192,45 +221,60 @@ $.widget.extend = function( target ) {
} }
} }
return target; return target;
}; };
$.widget.bridge = function( name, object ) { $.widget.bridge = function( name, object ) {
var fullName = object.prototype.widgetFullName || name; var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) { $.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string", var isMethodCall = typeof options === "string";
args = widget_slice.call( arguments, 1 ), var args = widgetSlice.call( arguments, 1 );
returnValue = this; var returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
$.widget.extend.apply( null, [ options ].concat(args) ) :
options;
if ( isMethodCall ) { if ( isMethodCall ) {
this.each(function() {
var methodValue, // If this is an empty collection, we need to have the instance method
instance = $.data( this, fullName ); // return undefined instead of the jQuery instance
if ( !this.length && options === "instance" ) {
returnValue = undefined;
} else {
this.each( function() {
var methodValue;
var instance = $.data( this, fullName );
if ( options === "instance" ) { if ( options === "instance" ) {
returnValue = instance; returnValue = instance;
return false; return false;
} }
if ( !instance ) { if ( !instance ) {
return $.error( "cannot call methods on " + name + " prior to initialization; " + return $.error( "cannot call methods on " + name +
" prior to initialization; " +
"attempted to call method '" + options + "'" ); "attempted to call method '" + options + "'" );
} }
if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
return $.error( "no such method '" + options + "' for " + name + " widget instance" ); if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
return $.error( "no such method '" + options + "' for " + name +
" widget instance" );
} }
methodValue = instance[ options ].apply( instance, args ); methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) { if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue && methodValue.jquery ? returnValue = methodValue && methodValue.jquery ?
returnValue.pushStack( methodValue.get() ) : returnValue.pushStack( methodValue.get() ) :
methodValue; methodValue;
return false; return false;
} }
}); } );
}
} else { } else {
this.each(function() {
// Allow multiple hashes to be passed on init
if ( args.length ) {
options = $.widget.extend.apply( null, [ options ].concat( args ) );
}
this.each( function() {
var instance = $.data( this, fullName ); var instance = $.data( this, fullName );
if ( instance ) { if ( instance ) {
instance.option( options || {} ); instance.option( options || {} );
@ -240,39 +284,39 @@ $.widget.bridge = function( name, object ) {
} else { } else {
$.data( this, fullName, new object( options, this ) ); $.data( this, fullName, new object( options, this ) );
} }
}); } );
} }
return returnValue; return returnValue;
}; };
}; };
$.Widget = function( /* options, element */ ) {}; $.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = []; $.Widget._childConstructors = [];
$.Widget.prototype = { $.Widget.prototype = {
widgetName: "widget", widgetName: "widget",
widgetEventPrefix: "", widgetEventPrefix: "",
defaultElement: "<div>", defaultElement: "<div>",
options: { options: {
classes: {},
disabled: false, disabled: false,
// callbacks // Callbacks
create: null create: null
}, },
_createWidget: function( options, element ) { _createWidget: function( options, element ) {
element = $( element || this.defaultElement || this )[ 0 ]; element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element ); this.element = $( element );
this.uuid = widget_uuid++; this.uuid = widgetUuid++;
this.eventNamespace = "." + this.widgetName + this.uuid; this.eventNamespace = "." + this.widgetName + this.uuid;
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
this.bindings = $(); this.bindings = $();
this.hoverable = $(); this.hoverable = $();
this.focusable = $(); this.focusable = $();
this.classesElementLookup = {};
if ( element !== this ) { if ( element !== this ) {
$.data( element, this.widgetFullName, this ); $.data( element, this.widgetFullName, this );
@ -282,46 +326,63 @@ $.Widget.prototype = {
this.destroy(); this.destroy();
} }
} }
}); } );
this.document = $( element.style ? this.document = $( element.style ?
// element within the document
// Element within the document
element.ownerDocument : element.ownerDocument :
// element is window or document
// Element is window or document
element.document || element ); element.document || element );
this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
} }
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
this._create(); this._create();
if ( this.options.disabled ) {
this._setOptionDisabled( this.options.disabled );
}
this._trigger( "create", null, this._getCreateEventData() ); this._trigger( "create", null, this._getCreateEventData() );
this._init(); this._init();
}, },
_getCreateOptions: $.noop,
_getCreateOptions: function() {
return {};
},
_getCreateEventData: $.noop, _getCreateEventData: $.noop,
_create: $.noop, _create: $.noop,
_init: $.noop, _init: $.noop,
destroy: function() { destroy: function() {
var that = this;
this._destroy(); this._destroy();
// we can probably remove the unbind calls in 2.0 $.each( this.classesElementLookup, function( key, value ) {
that._removeClass( value, key );
} );
// We can probably remove the unbind calls in 2.0
// all event bindings should go through this._on() // all event bindings should go through this._on()
this.element this.element
.unbind( this.eventNamespace ) .off( this.eventNamespace )
.removeData( this.widgetFullName ) .removeData( this.widgetFullName );
// support: jquery <1.6.3
// http://bugs.jquery.com/ticket/9413
.removeData( $.camelCase( this.widgetFullName ) );
this.widget() this.widget()
.unbind( this.eventNamespace ) .off( this.eventNamespace )
.removeAttr( "aria-disabled" ) .removeAttr( "aria-disabled" );
.removeClass(
this.widgetFullName + "-disabled " +
"ui-state-disabled" );
// clean up events and states // Clean up events and states
this.bindings.unbind( this.eventNamespace ); this.bindings.off( this.eventNamespace );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
}, },
_destroy: $.noop, _destroy: $.noop,
widget: function() { widget: function() {
@ -329,18 +390,20 @@ $.Widget.prototype = {
}, },
option: function( key, value ) { option: function( key, value ) {
var options = key, var options = key;
parts, var parts;
curOption, var curOption;
i; var i;
if ( arguments.length === 0 ) { if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
// Don't return a reference to the internal hash
return $.widget.extend( {}, this.options ); return $.widget.extend( {}, this.options );
} }
if ( typeof key === "string" ) { if ( typeof key === "string" ) {
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {}; options = {};
parts = key.split( "." ); parts = key.split( "." );
key = parts.shift(); key = parts.shift();
@ -367,6 +430,7 @@ $.Widget.prototype = {
return this; return this;
}, },
_setOptions: function( options ) { _setOptions: function( options ) {
var key; var key;
@ -376,42 +440,152 @@ $.Widget.prototype = {
return this; return this;
}, },
_setOption: function( key, value ) { _setOption: function( key, value ) {
if ( key === "classes" ) {
this._setOptionClasses( value );
}
this.options[ key ] = value; this.options[ key ] = value;
if ( key === "disabled" ) { if ( key === "disabled" ) {
this.widget() this._setOptionDisabled( value );
.toggleClass( this.widgetFullName + "-disabled", !!value );
// If the widget is becoming disabled, then nothing is interactive
if ( value ) {
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
}
} }
return this; return this;
}, },
enable: function() { _setOptionClasses: function( value ) {
return this._setOptions({ disabled: false }); var classKey, elements, currentElements;
for ( classKey in value ) {
currentElements = this.classesElementLookup[ classKey ];
if ( value[ classKey ] === this.options.classes[ classKey ] ||
!currentElements ||
!currentElements.length ) {
continue;
}
// We are doing this to create a new jQuery object because the _removeClass() call
// on the next line is going to destroy the reference to the current elements being
// tracked. We need to save a copy of this collection so that we can add the new classes
// below.
elements = $( currentElements.get() );
this._removeClass( currentElements, classKey );
// We don't use _addClass() here, because that uses this.options.classes
// for generating the string of classes. We want to use the value passed in from
// _setOption(), this is the new value of the classes option which was passed to
// _setOption(). We pass this value directly to _classes().
elements.addClass( this._classes( {
element: elements,
keys: classKey,
classes: value,
add: true
} ) );
}
}, },
_setOptionDisabled: function( value ) {
this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
// If the widget is becoming disabled, then nothing is interactive
if ( value ) {
this._removeClass( this.hoverable, null, "ui-state-hover" );
this._removeClass( this.focusable, null, "ui-state-focus" );
}
},
enable: function() {
return this._setOptions( { disabled: false } );
},
disable: function() { disable: function() {
return this._setOptions({ disabled: true }); return this._setOptions( { disabled: true } );
},
_classes: function( options ) {
var full = [];
var that = this;
options = $.extend( {
element: this.element,
classes: this.options.classes || {}
}, options );
function processClassString( classes, checkOption ) {
var current, i;
for ( i = 0; i < classes.length; i++ ) {
current = that.classesElementLookup[ classes[ i ] ] || $();
if ( options.add ) {
current = $( $.unique( current.get().concat( options.element.get() ) ) );
} else {
current = $( current.not( options.element ).get() );
}
that.classesElementLookup[ classes[ i ] ] = current;
full.push( classes[ i ] );
if ( checkOption && options.classes[ classes[ i ] ] ) {
full.push( options.classes[ classes[ i ] ] );
}
}
}
this._on( options.element, {
"remove": "_untrackClassesElement"
} );
if ( options.keys ) {
processClassString( options.keys.match( /\S+/g ) || [], true );
}
if ( options.extra ) {
processClassString( options.extra.match( /\S+/g ) || [] );
}
return full.join( " " );
},
_untrackClassesElement: function( event ) {
var that = this;
$.each( that.classesElementLookup, function( key, value ) {
if ( $.inArray( event.target, value ) !== -1 ) {
that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
}
} );
},
_removeClass: function( element, keys, extra ) {
return this._toggleClass( element, keys, extra, false );
},
_addClass: function( element, keys, extra ) {
return this._toggleClass( element, keys, extra, true );
},
_toggleClass: function( element, keys, extra, add ) {
add = ( typeof add === "boolean" ) ? add : extra;
var shift = ( typeof element === "string" || element === null ),
options = {
extra: shift ? keys : extra,
keys: shift ? element : keys,
element: shift ? this.element : element,
add: add
};
options.element.toggleClass( this._classes( options ), add );
return this;
}, },
_on: function( suppressDisabledCheck, element, handlers ) { _on: function( suppressDisabledCheck, element, handlers ) {
var delegateElement, var delegateElement;
instance = this; var instance = this;
// no suppressDisabledCheck flag, shuffle arguments // No suppressDisabledCheck flag, shuffle arguments
if ( typeof suppressDisabledCheck !== "boolean" ) { if ( typeof suppressDisabledCheck !== "boolean" ) {
handlers = element; handlers = element;
element = suppressDisabledCheck; element = suppressDisabledCheck;
suppressDisabledCheck = false; suppressDisabledCheck = false;
} }
// no element argument, shuffle and use this.element // No element argument, shuffle and use this.element
if ( !handlers ) { if ( !handlers ) {
handlers = element; handlers = element;
element = this.element; element = this.element;
@ -423,7 +597,8 @@ $.Widget.prototype = {
$.each( handlers, function( event, handler ) { $.each( handlers, function( event, handler ) {
function handlerProxy() { function handlerProxy() {
// allow widgets to customize the disabled handling
// Allow widgets to customize the disabled handling
// - disabled as an array instead of boolean // - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts // - disabled class as method for disabling individual parts
if ( !suppressDisabledCheck && if ( !suppressDisabledCheck &&
@ -435,26 +610,33 @@ $.Widget.prototype = {
.apply( instance, arguments ); .apply( instance, arguments );
} }
// copy the guid so direct unbinding works // Copy the guid so direct unbinding works
if ( typeof handler !== "string" ) { if ( typeof handler !== "string" ) {
handlerProxy.guid = handler.guid = handlerProxy.guid = handler.guid =
handler.guid || handlerProxy.guid || $.guid++; handler.guid || handlerProxy.guid || $.guid++;
} }
var match = event.match( /^([\w:-]*)\s*(.*)$/ ), var match = event.match( /^([\w:-]*)\s*(.*)$/ );
eventName = match[1] + instance.eventNamespace, var eventName = match[ 1 ] + instance.eventNamespace;
selector = match[2]; var selector = match[ 2 ];
if ( selector ) { if ( selector ) {
delegateElement.delegate( selector, eventName, handlerProxy ); delegateElement.on( eventName, selector, handlerProxy );
} else { } else {
element.bind( eventName, handlerProxy ); element.on( eventName, handlerProxy );
} }
}); } );
}, },
_off: function( element, eventName ) { _off: function( element, eventName ) {
eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
element.unbind( eventName ).undelegate( eventName ); this.eventNamespace;
element.off( eventName ).off( eventName );
// Clear the stack to avoid memory leaks (#10056)
this.bindings = $( this.bindings.not( element ).get() );
this.focusable = $( this.focusable.not( element ).get() );
this.hoverable = $( this.hoverable.not( element ).get() );
}, },
_delay: function( handler, delay ) { _delay: function( handler, delay ) {
@ -470,40 +652,41 @@ $.Widget.prototype = {
this.hoverable = this.hoverable.add( element ); this.hoverable = this.hoverable.add( element );
this._on( element, { this._on( element, {
mouseenter: function( event ) { mouseenter: function( event ) {
$( event.currentTarget ).addClass( "ui-state-hover" ); this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
}, },
mouseleave: function( event ) { mouseleave: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-hover" ); this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
} }
}); } );
}, },
_focusable: function( element ) { _focusable: function( element ) {
this.focusable = this.focusable.add( element ); this.focusable = this.focusable.add( element );
this._on( element, { this._on( element, {
focusin: function( event ) { focusin: function( event ) {
$( event.currentTarget ).addClass( "ui-state-focus" ); this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
}, },
focusout: function( event ) { focusout: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-focus" ); this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
} }
}); } );
}, },
_trigger: function( type, event, data ) { _trigger: function( type, event, data ) {
var prop, orig, var prop, orig;
callback = this.options[ type ]; var callback = this.options[ type ];
data = data || {}; data = data || {};
event = $.Event( event ); event = $.Event( event );
event.type = ( type === this.widgetEventPrefix ? event.type = ( type === this.widgetEventPrefix ?
type : type :
this.widgetEventPrefix + type ).toLowerCase(); this.widgetEventPrefix + type ).toLowerCase();
// the original event may come from any element
// The original event may come from any element
// so we need to reset the target on the new event // so we need to reset the target on the new event
event.target = this.element[ 0 ]; event.target = this.element[ 0 ];
// copy original event properties over to the new event // Copy original event properties over to the new event
orig = event.originalEvent; orig = event.originalEvent;
if ( orig ) { if ( orig ) {
for ( prop in orig ) { for ( prop in orig ) {
@ -515,48 +698,54 @@ $.Widget.prototype = {
this.element.trigger( event, data ); this.element.trigger( event, data );
return !( $.isFunction( callback ) && return !( $.isFunction( callback ) &&
callback.apply( this.element[0], [ event ].concat( data ) ) === false || callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
event.isDefaultPrevented() ); event.isDefaultPrevented() );
} }
}; };
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) { $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
if ( typeof options === "string" ) { if ( typeof options === "string" ) {
options = { effect: options }; options = { effect: options };
} }
var hasOptions,
effectName = !options ? var hasOptions;
var effectName = !options ?
method : method :
options === true || typeof options === "number" ? options === true || typeof options === "number" ?
defaultEffect : defaultEffect :
options.effect || defaultEffect; options.effect || defaultEffect;
options = options || {}; options = options || {};
if ( typeof options === "number" ) { if ( typeof options === "number" ) {
options = { duration: options }; options = { duration: options };
} }
hasOptions = !$.isEmptyObject( options ); hasOptions = !$.isEmptyObject( options );
options.complete = callback; options.complete = callback;
if ( options.delay ) { if ( options.delay ) {
element.delay( options.delay ); element.delay( options.delay );
} }
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
element[ method ]( options ); element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) { } else if ( effectName !== method && element[ effectName ] ) {
element[ effectName ]( options.duration, options.easing, callback ); element[ effectName ]( options.duration, options.easing, callback );
} else { } else {
element.queue(function( next ) { element.queue( function( next ) {
$( this )[ method ](); $( this )[ method ]();
if ( callback ) { if ( callback ) {
callback.call( element[ 0 ] ); callback.call( element[ 0 ] );
} }
next(); next();
}); } );
} }
}; };
}); } );
var widget = $.widget;
var widget = $.widget;