스마트에디터2 추가

This commit is contained in:
thisgun
2014-07-17 14:21:37 +09:00
parent 85930d5564
commit 264866ab93
85 changed files with 45263 additions and 0 deletions

View File

@ -0,0 +1,339 @@
jQuery.fn.bindAll = function(options) {
var $this = this;
jQuery.each(options, function(key, val){
$this.bind(key, val);
});
return this;
}
jQuery(function ($) {
'use strict';
// Change this to the location of your server-side upload handler:
var gnu = {
url : './php/',
container_el : 'body',
dreg_area : '#drag_area',
dreg_area_list : '#drag_area > ul',
progress_bar : '#progress .progress-bar',
filter : /^(image\/bmp|image\/gif|image\/jpg|image\/jpeg|image\/png)$/i,
files : [],
file_limit : 10, //한번에 올릴수 파일갯수 제한
imgw : 100,
imgh : 70,
file_api_support : !!(window.ProgressEvent && window.FileReader),
$elTextGuide : $("#guide_text"),
init : function(){
$(this.dreg_area_list).sortable({
'cursor':'pointer',
'placeholder':'placeholder'
});
$(this.dreg_area_list).disableSelection();
if( this.file_api_support ) this.$elTextGuide.removeClass("hidebg").addClass("showbg");
},
file_push : function(file){
var othis = this,
last = othis.files.length;
othis.files.push(file);
},
_readymodebg : function(){
if( this.file_api_support ) {
var sClass = this.$elTextGuide.attr('class');
if(sClass.indexOf('hidebg') > 0){
this.$elTextGuide.removeClass('hidebg');
this.$elTextGuide.addClass('showbg');
}
}
},
_startmodebg : function(){
if( this.file_api_support ) {
var sClass = this.$elTextGuide.attr('class');
if(sClass.indexOf('hidebg') < 0){
this.$elTextGuide.removeClass('showbg');
this.$elTextGuide.addClass('hidebg');
}
}
},
_delete : function(e){
e.preventDefault();
var othis = gnu,
$button = $(e.currentTarget),
delete_url = $button.attr("data-delete");
if( delete_url ){
$.ajax({
url: othis.url+"?del=1&file="+ delete_url
}).done(function (result) {
});
}
$button.parents('li.sort_list').fadeOut(300, function(){
$(this).remove();
var $dreg_area = $(othis.dreg_area_list);
$dreg_area.sortable('refresh');
if( !$dreg_area.children('li').length ) othis._readymodebg();
});
},
_add : function(e, data, preload){
var othis = this;
othis._startmodebg();
data.context = $('<li/>').addClass("sort_list").appendTo(this.dreg_area_list);
$.each(data.files, function (index, file) {
if ( !preload && !othis.filter.test(file.type)) {
data.context.remove();
alert('이미지만 허용합니다.');
return true;
}
var node = $('<div/>')
.append($('<span/>').text(file.name))
.append($('<span/>').addClass("delete_img").attr({"data-delete":file.name,"data-url":file.url}).html("<img src='./img/system_delete.png' alt='삭제' title='삭제' >")),
$img = "<img src='./img/loading.gif' class='pre_thumb' />",
size_text = '';
if ( preload && preload != 'swfupload' ){
var ret = othis.get_ratio( file.width, file.height ),
size_text = file.width+" x "+file.height;
$img = "<img src='"+file.url+"' width='"+ret['width']+"' height='"+ret['height']+"' class='pre_thumb' />";
}
if (!index) {
node
.prepend('<br>')
.prepend($img);
if(size_text){
node.append('<br>')
.append($('<span/>').text(size_text))
}
}
node.appendTo(data.context);
node.find(".delete_img").on("click", othis._delete);
});
$(othis.dreg_area_list).sortable('refresh');
},
get_file_all : function(){
var othis = this,
oDate = new Date();
$.ajax({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
//url: $('#fileupload').fileupload('option', 'url'),
url: this.url+"?t="+ oDate.getTime(),
dataType: 'json',
context: $('#fileupload')[0]
}).always(function () {
//$(this).removeClass('fileupload-processing');
}).done(function (result) {
$.each(result.files, function (index, data) {
var tmp = { files : [] };
tmp.files[0] = data;
othis._add( $.Event('add'), tmp, 'preload' );
});
});
},
_processalways : function(e, data){
var index = data.index,
file = data.files[index],
node = $(data.context.children()[index]);
if (file.error) {
node
.append('<br>')
.append($('<span class="text-danger"/>').text(file.error));
}
if (index + 1 === data.files.length) {
data.context.find('button')
.text('Upload')
.prop('disabled', !!data.files.error);
}
},
obj_to_arr : function(obj){
var array = $.map(obj, function(value, index) {
return [value];
});
return array;
},
_done : function(e, data){
var othis = this;
$.each(data.result.files, function (index, file) {
if (file.url) {
var ret = othis.get_ratio( file.width, file.height ),
node = $(data.context.children()[index]),
size_text = file.width+" x "+file.height,
//$img = "<img src='"+file.url+"' width='"+ret['width']+"' height='"+ret['height']+"' />",
link = $('<a>')
.attr('target', '_blank')
.prop('href', file.url);
node
//.wrap(link)
.append('<br>')
.append($('<span/>').text(size_text))
.find("img.pre_thumb").attr({"src":file.url,"width":ret['width'],"height":ret['height']})
.end().find(".delete_img").attr({"data-delete":file.name,"data-url":file.url});
} else if (file.error) {
var error = $('<span class="text-danger"/>').text(file.error);
$(data.context.children()[index])
.append('<br>')
.append(error);
}
othis.file_push(file);
});
},
get_ratio : function(width, height){
var ratio = 0,
ret_img = [];
if( !width || !height ){
ret_img['width'] = this.imgw;
ret_img['height'] = this.imgh;
return ret_img;
}
if(width > this.imgw){
ratio = this.imgw / width;
height = height * ratio;
width = this.imgw;
}
if( height > this.imgh ){
ratio = this.imgh / height;
width = width * ratio;
height = this.imgh;
}
ret_img['width'] = parseInt(width);
ret_img['height'] = parseInt(height);
return ret_img;
},
setPhotoToEditor : function(oFileInfo){
if (!!opener && !!opener.nhn && !!opener.nhn.husky && !!opener.nhn.husky.PopUpManager) {
//스마트 에디터 플러그인을 통해서 넣는 방법 (oFileInfo는 Array)
opener.nhn.husky.PopUpManager.setCallback(window, 'SET_PHOTO', [oFileInfo]);
//본문에 바로 tag를 넣는 방법 (oFileInfo는 String으로 <img src=....> )
//opener.nhn.husky.PopUpManager.setCallback(window, 'PASTE_HTML', [oFileInfo]);
}
}
}
$('#fileupload').fileupload({
url: gnu.url,
dataType: 'json',
container_el: gnu.container_el,
dropZone: $(gnu.dreg_area),
autoUpload: true,
sequentialUploads: true,
acceptFileTypes: /(\.|\/)(gif|jpe?g|bmp|png)$/i,
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: true,
limit_filesLength : gnu.file_limit
}).on('fileuploadadd', function (e, data) {
gnu._add(e, data);
}).on('fileuploadprocessalways', function (e, data) {
gnu._processalways(e, data);
}).on('fileuploaddone', function (e, data) {
gnu._done( e, data );
}).on('fileuploadfail', function (e, data) {
$.each(data.files, function (index, file) {
var error = $('<span class="text-danger"/>').text('File upload failed.');
$(data.context.children()[index])
.append('<br>')
.append(error);
});
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
gnu.init();
var listeners = {
data : {},
log : false,
swfuploadLoaded: function(event){
if(this.log) $('.log', this).append('<li>Loaded</li>');
},
fileQueued: function(event, file){
if(this.log) $('.log', this).append('<li>File queued - '+file.name+'</li>');
// start the upload once it is queued
// but only if this queue is not disabled
if (!$('input[name=disabled]:checked', this).length) {
$(this).swfupload('startUpload');
}
},
fileQueueError: function(event, file, errorCode, message){
switch (errorCode)
{
case -100 :
alert("파일을 "+message+"개 이하로 선택해주세요.");
break;
}
if(this.log) $('.log', this).append('<li>File queue error - '+message+'</li>');
},
fileDialogStart: function(event){
if(this.log) $('.log', this).append('<li>File dialog start</li>');
},
fileDialogComplete: function(event, numFilesSelected, numFilesQueued){
if(this.log) $('.log', this).append('<li>File dialog complete</li>');
},
uploadStart: function(event, file){
listeners.data.files = $.makeArray(file);
gnu._add( event, listeners.data, 'swfupload' );
if(this.log) $('.log', this).append('<li>Upload start - '+file.name+'</li>');
},
uploadProgress: function(event, file, bytesLoaded){
if(this.log) $('.log', this).append('<li>Upload progress - '+bytesLoaded+'</li>');
},
uploadSuccess: function(event, file, serverData){
listeners.data.result = jQuery.parseJSON( serverData );
gnu._done( event, listeners.data );
if(this.log) $('.log', this).append('<li>Upload success - '+file.name+'</li>');
},
uploadComplete: function(event, file){
if(this.log) $('.log', this).append('<li>Upload complete - '+file.name+'</li>');
// upload has completed, lets try the next one in the queue
// but only if this queue is not disabled
if (!$('input[name=disabled]:checked', this).length) {
$(this).swfupload('startUpload');
}
},
uploadError: function(event, file, errorCode, message){
if(this.log) $('.log', this).append('<li>Upload error - '+message+'</li>');
}
};
$(gnu.container_el).bindAll(listeners);
/* listeners이벤트 */
$(gnu.dreg_area).bind('drop dragover', function (e) {
e.preventDefault();
if( !gnu.file_api_support && e.type == 'drop' ) alert("브라우저가 드래그 앤 드랍을 지원하지 않습니다.");
});
$("#all_remove_btn").bind("click", function(e){
e.preventDefault();
if( $(gnu.dreg_area_list).children().length ){
if (confirm("추가한 이미지가 있습니다.정말 삭제 하시겠습니까?")){
$(gnu.dreg_area_list).find(".delete_img").each( function(i){
$(this).trigger("click");
});
$(gnu.dreg_area_list).sortable('refresh');
}
}
});
$("#img_upload_submit").bind("click", function(e){
e.preventDefault();
var aResult = [], j = 0;
$(gnu.dreg_area_list).find(".delete_img").each( function(i, f){
if( !$(this).attr("data-url") ) return true;
aResult[j] = [];
aResult[j]['bNewLine'] = 'true';
aResult[j]['sAlign'] = '';
aResult[j]['sFileName'] = $(this).attr("data-delete");
aResult[j]['sFileURL'] = $(this).attr("data-url");
j++;
});
if( aResult.length ){
gnu.setPhotoToEditor(aResult);
aResult = null;
}
window.close();
});
$("#close_w_btn").bind("click", function(e){
e.preventDefault();
window.close();
});
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,172 @@
/*
* jQuery File Upload Processing Plugin 1.3.0
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, window */
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'./jquery.fileupload'
], factory);
} else {
// Browser globals:
factory(
window.jQuery
);
}
}(function ($) {
'use strict';
var originalAdd = $.blueimp.fileupload.prototype.options.add;
// The File Upload Processing plugin extends the fileupload widget
// with file processing functionality:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
options: {
// The list of processing actions:
processQueue: [
/*
{
action: 'log',
type: 'debug'
}
*/
],
add: function (e, data) {
var $this = $(this);
data.process(function () {
return $this.fileupload('process', data);
});
originalAdd.call(this, e, data);
}
},
processActions: {
/*
log: function (data, options) {
console[options.type](
'Processing "' + data.files[data.index].name + '"'
);
}
*/
},
_processFile: function (data, originalData) {
var that = this,
dfd = $.Deferred().resolveWith(that, [data]),
chain = dfd.promise();
this._trigger('process', null, data);
$.each(data.processQueue, function (i, settings) {
var func = function (data) {
if (originalData.errorThrown) {
return $.Deferred()
.rejectWith(that, [originalData]).promise();
}
return that.processActions[settings.action].call(
that,
data,
settings
);
};
chain = chain.pipe(func, settings.always && func);
});
chain
.done(function () {
that._trigger('processdone', null, data);
that._trigger('processalways', null, data);
})
.fail(function () {
that._trigger('processfail', null, data);
that._trigger('processalways', null, data);
});
return chain;
},
// Replaces the settings of each processQueue item that
// are strings starting with an "@", using the remaining
// substring as key for the option map,
// e.g. "@autoUpload" is replaced with options.autoUpload:
_transformProcessQueue: function (options) {
var processQueue = [];
$.each(options.processQueue, function () {
var settings = {},
action = this.action,
prefix = this.prefix === true ? action : this.prefix;
$.each(this, function (key, value) {
if ($.type(value) === 'string' &&
value.charAt(0) === '@') {
settings[key] = options[
value.slice(1) || (prefix ? prefix +
key.charAt(0).toUpperCase() + key.slice(1) : key)
];
} else {
settings[key] = value;
}
});
processQueue.push(settings);
});
options.processQueue = processQueue;
},
// Returns the number of files currently in the processsing queue:
processing: function () {
return this._processing;
},
// Processes the files given as files property of the data parameter,
// returns a Promise object that allows to bind callbacks:
process: function (data) {
var that = this,
options = $.extend({}, this.options, data);
if (options.processQueue && options.processQueue.length) {
this._transformProcessQueue(options);
if (this._processing === 0) {
this._trigger('processstart');
}
$.each(data.files, function (index) {
var opts = index ? $.extend({}, options) : options,
func = function () {
if (data.errorThrown) {
return $.Deferred()
.rejectWith(that, [data]).promise();
}
return that._processFile(opts, data);
};
opts.index = index;
that._processing += 1;
that._processingQueue = that._processingQueue.pipe(func, func)
.always(function () {
that._processing -= 1;
if (that._processing === 0) {
that._trigger('processstop');
}
});
});
}
return this._processingQueue;
},
_create: function () {
this._super();
this._processing = 0;
this._processingQueue = $.Deferred().resolveWith(this)
.promise();
}
});
}));

View File

@ -0,0 +1,699 @@
/*
* jQuery File Upload User Interface Plugin 9.5.2
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, window */
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'tmpl',
'./jquery.fileupload-image',
'./jquery.fileupload-audio',
'./jquery.fileupload-video',
'./jquery.fileupload-validate'
], factory);
} else {
// Browser globals:
factory(
window.jQuery,
window.tmpl
);
}
}(function ($, tmpl) {
'use strict';
$.blueimp.fileupload.prototype._specialOptions.push(
'filesContainer',
'uploadTemplateId',
'downloadTemplateId'
);
// The UI version extends the file upload widget
// and adds complete user interface interaction:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
options: {
// By default, files added to the widget are uploaded as soon
// as the user clicks on the start buttons. To enable automatic
// uploads, set the following option to true:
autoUpload: false,
// The ID of the upload template:
uploadTemplateId: 'template-upload',
// The ID of the download template:
downloadTemplateId: 'template-download',
// The container for the list of files. If undefined, it is set to
// an element with class "files" inside of the widget element:
filesContainer: undefined,
// By default, files are appended to the files container.
// Set the following option to true, to prepend files instead:
prependFiles: false,
// The expected data type of the upload response, sets the dataType
// option of the $.ajax upload requests:
dataType: 'json',
// Function returning the current number of files,
// used by the maxNumberOfFiles validation:
getNumberOfFiles: function () {
return this.filesContainer.children()
.not('.processing').length;
},
// Callback to retrieve the list of files from the server response:
getFilesFromResponse: function (data) {
if (data.result && $.isArray(data.result.files)) {
return data.result.files;
}
return [];
},
// The add callback is invoked as soon as files are added to the fileupload
// widget (via file input selection, drag & drop or add API call).
// See the basic file upload widget for more information:
add: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
var $this = $(this),
that = $this.data('blueimp-fileupload') ||
$this.data('fileupload'),
options = that.options;
data.context = that._renderUpload(data.files)
.data('data', data)
.addClass('processing');
options.filesContainer[
options.prependFiles ? 'prepend' : 'append'
](data.context);
that._forceReflow(data.context);
that._transition(data.context);
data.process(function () {
return $this.fileupload('process', data);
}).always(function () {
data.context.each(function (index) {
$(this).find('.size').text(
that._formatFileSize(data.files[index].size)
);
}).removeClass('processing');
that._renderPreviews(data);
}).done(function () {
data.context.find('.start').prop('disabled', false);
if ((that._trigger('added', e, data) !== false) &&
(options.autoUpload || data.autoUpload) &&
data.autoUpload !== false) {
data.submit();
}
}).fail(function () {
if (data.files.error) {
data.context.each(function (index) {
var error = data.files[index].error;
if (error) {
$(this).find('.error').text(error);
}
});
}
});
},
// Callback for the start of each file upload request:
send: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload');
if (data.context && data.dataType &&
data.dataType.substr(0, 6) === 'iframe') {
// Iframe Transport does not support progress events.
// In lack of an indeterminate progress bar, we set
// the progress to 100%, showing the full animated bar:
data.context
.find('.progress').addClass(
!$.support.transition && 'progress-animated'
)
.attr('aria-valuenow', 100)
.children().first().css(
'width',
'100%'
);
}
return that._trigger('sent', e, data);
},
// Callback for successful uploads:
done: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
getFilesFromResponse = data.getFilesFromResponse ||
that.options.getFilesFromResponse,
files = getFilesFromResponse(data),
template,
deferred;
if (data.context) {
data.context.each(function (index) {
var file = files[index] ||
{error: 'Empty file upload result'};
deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
var node = $(this);
template = that._renderDownload([file])
.replaceAll(node);
that._forceReflow(template);
that._transition(template).done(
function () {
data.context = $(this);
that._trigger('completed', e, data);
that._trigger('finished', e, data);
deferred.resolve();
}
);
}
);
});
} else {
template = that._renderDownload(files)[
that.options.prependFiles ? 'prependTo' : '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) {
if (e.isDefaultPrevented()) {
return false;
}
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
template,
deferred;
if (data.context) {
data.context.each(function (index) {
if (data.errorThrown !== 'abort') {
var file = data.files[index];
file.error = file.error || data.errorThrown ||
true;
deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
var node = $(this);
template = that._renderDownload([file])
.replaceAll(node);
that._forceReflow(template);
that._transition(template).done(
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();
}
);
}
});
} else if (data.errorThrown !== 'abort') {
data.context = that._renderUpload(data.files)[
that.options.prependFiles ? 'prependTo' : '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:
progress: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
var progress = Math.floor(data.loaded / data.total * 100);
if (data.context) {
data.context.each(function () {
$(this).find('.progress')
.attr('aria-valuenow', progress)
.children().first().css(
'width',
progress + '%'
);
});
}
},
// Callback for global upload progress events:
progressall: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
var $this = $(this),
progress = Math.floor(data.loaded / data.total * 100),
globalProgressNode = $this.find('.fileupload-progress'),
extendedProgressNode = globalProgressNode
.find('.progress-extended');
if (extendedProgressNode.length) {
extendedProgressNode.html(
($this.data('blueimp-fileupload') || $this.data('fileupload'))
._renderExtendedProgress(data)
);
}
globalProgressNode
.find('.progress')
.attr('aria-valuenow', progress)
.children().first().css(
'width',
progress + '%'
);
},
// Callback for uploads start, equivalent to the global ajaxStart event:
start: function (e) {
if (e.isDefaultPrevented()) {
return false;
}
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload');
that._resetFinishedDeferreds();
that._transition($(this).find('.fileupload-progress')).done(
function () {
that._trigger('started', e);
}
);
},
// Callback for uploads stop, equivalent to the global ajaxStop event:
stop: function (e) {
if (e.isDefaultPrevented()) {
return false;
}
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')
.children().first().css('width', '0%');
$(this).find('.progress-extended').html('&nbsp;');
deferred.resolve();
}
);
},
processstart: function (e) {
if (e.isDefaultPrevented()) {
return false;
}
$(this).addClass('fileupload-processing');
},
processstop: function (e) {
if (e.isDefaultPrevented()) {
return false;
}
$(this).removeClass('fileupload-processing');
},
// Callback for file deletion:
destroy: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
removeNode = function () {
that._transition(data.context).done(
function () {
$(this).remove();
that._trigger('destroyed', e, data);
}
);
};
if (data.url) {
data.dataType = data.dataType || that.options.dataType;
$.ajax(data).done(removeNode).fail(function () {
that._trigger('destroyfailed', e, data);
});
} else {
removeNode();
}
}
},
_resetFinishedDeferreds: function () {
this._finishedUploads = [];
},
_addFinishedDeferreds: function (deferred) {
if (!deferred) {
deferred = $.Deferred();
}
this._finishedUploads.push(deferred);
return deferred;
},
_getFinishedDeferreds: function () {
return this._finishedUploads;
},
// Link handler, that allows to download files
// by drag & drop of the links to the desktop:
_enableDragToDesktop: function () {
var link = $(this),
url = link.prop('href'),
name = link.prop('download'),
type = 'application/octet-stream';
link.bind('dragstart', function (e) {
try {
e.originalEvent.dataTransfer.setData(
'DownloadURL',
[type, name, url].join(':')
);
} catch (ignore) {}
});
},
_formatFileSize: function (bytes) {
if (typeof bytes !== 'number') {
return '';
}
if (bytes >= 1000000000) {
return (bytes / 1000000000).toFixed(2) + ' GB';
}
if (bytes >= 1000000) {
return (bytes / 1000000).toFixed(2) + ' MB';
}
return (bytes / 1000).toFixed(2) + ' KB';
},
_formatBitrate: function (bits) {
if (typeof bits !== 'number') {
return '';
}
if (bits >= 1000000000) {
return (bits / 1000000000).toFixed(2) + ' Gbit/s';
}
if (bits >= 1000000) {
return (bits / 1000000).toFixed(2) + ' Mbit/s';
}
if (bits >= 1000) {
return (bits / 1000).toFixed(2) + ' kbit/s';
}
return bits.toFixed(2) + ' bit/s';
},
_formatTime: function (seconds) {
var date = new Date(seconds * 1000),
days = Math.floor(seconds / 86400);
days = days ? days + 'd ' : '';
return days +
('0' + date.getUTCHours()).slice(-2) + ':' +
('0' + date.getUTCMinutes()).slice(-2) + ':' +
('0' + date.getUTCSeconds()).slice(-2);
},
_formatPercentage: function (floatValue) {
return (floatValue * 100).toFixed(2) + ' %';
},
_renderExtendedProgress: function (data) {
return this._formatBitrate(data.bitrate) + ' | ' +
this._formatTime(
(data.total - data.loaded) * 8 / data.bitrate
) + ' | ' +
this._formatPercentage(
data.loaded / data.total
) + ' | ' +
this._formatFileSize(data.loaded) + ' / ' +
this._formatFileSize(data.total);
},
_renderTemplate: function (func, files) {
if (!func) {
return $();
}
var result = func({
files: files,
formatFileSize: this._formatFileSize,
options: this.options
});
if (result instanceof $) {
return result;
}
return $(this.options.templatesContainer).html(result).children();
},
_renderPreviews: function (data) {
data.context.find('.preview').each(function (index, elm) {
$(elm).append(data.files[index].preview);
});
},
_renderUpload: function (files) {
return this._renderTemplate(
this.options.uploadTemplate,
files
);
},
_renderDownload: function (files) {
return this._renderTemplate(
this.options.downloadTemplate,
files
).find('a[download]').each(this._enableDragToDesktop).end();
},
_startHandler: function (e) {
e.preventDefault();
var button = $(e.currentTarget),
template = button.closest('.template-upload'),
data = template.data('data');
button.prop('disabled', true);
if (data && data.submit) {
data.submit();
}
},
_cancelHandler: function (e) {
e.preventDefault();
var template = $(e.currentTarget)
.closest('.template-upload,.template-download'),
data = template.data('data') || {};
data.context = data.context || template;
if (data.abort) {
data.abort();
} else {
data.errorThrown = 'abort';
this._trigger('fail', e, data);
}
},
_deleteHandler: function (e) {
e.preventDefault();
var button = $(e.currentTarget);
this._trigger('destroy', e, $.extend({
context: button.closest('.template-download'),
type: 'DELETE'
}, button.data()));
},
_forceReflow: function (node) {
return $.support.transition && node.length &&
node[0].offsetWidth;
},
_transition: function (node) {
var dfd = $.Deferred();
if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
node.bind(
$.support.transition.end,
function (e) {
// Make sure we don't respond to other transitions events
// in the container element, e.g. from button elements:
if (e.target === node[0]) {
node.unbind($.support.transition.end);
dfd.resolveWith(node);
}
}
).toggleClass('in');
} else {
node.toggleClass('in');
dfd.resolveWith(node);
}
return dfd;
},
_initButtonBarEventHandlers: function () {
var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
filesList = this.options.filesContainer;
this._on(fileUploadButtonBar.find('.start'), {
click: function (e) {
e.preventDefault();
filesList.find('.start').click();
}
});
this._on(fileUploadButtonBar.find('.cancel'), {
click: function (e) {
e.preventDefault();
filesList.find('.cancel').click();
}
});
this._on(fileUploadButtonBar.find('.delete'), {
click: function (e) {
e.preventDefault();
filesList.find('.toggle:checked')
.closest('.template-download')
.find('.delete').click();
fileUploadButtonBar.find('.toggle')
.prop('checked', false);
}
});
this._on(fileUploadButtonBar.find('.toggle'), {
change: function (e) {
filesList.find('.toggle').prop(
'checked',
$(e.currentTarget).is(':checked')
);
}
});
},
_destroyButtonBarEventHandlers: function () {
this._off(
this.element.find('.fileupload-buttonbar')
.find('.start, .cancel, .delete'),
'click'
);
this._off(
this.element.find('.fileupload-buttonbar .toggle'),
'change.'
);
},
_initEventHandlers: function () {
this._super();
this._on(this.options.filesContainer, {
'click .start': this._startHandler,
'click .cancel': this._cancelHandler,
'click .delete': this._deleteHandler
});
this._initButtonBarEventHandlers();
},
_destroyEventHandlers: function () {
this._destroyButtonBarEventHandlers();
this._off(this.options.filesContainer, 'click');
this._super();
},
_enableFileInputButton: function () {
this.element.find('.fileinput-button input')
.prop('disabled', false)
.parent().removeClass('disabled');
},
_disableFileInputButton: function () {
this.element.find('.fileinput-button input')
.prop('disabled', true)
.parent().addClass('disabled');
},
_initTemplates: function () {
var options = this.options;
options.templatesContainer = this.document[0].createElement(
options.filesContainer.prop('nodeName')
);
if (tmpl) {
if (options.uploadTemplateId) {
options.uploadTemplate = tmpl(options.uploadTemplateId);
}
if (options.downloadTemplateId) {
options.downloadTemplate = tmpl(options.downloadTemplateId);
}
}
},
_initFilesContainer: function () {
var options = this.options;
if (options.filesContainer === undefined) {
options.filesContainer = this.element.find('.files');
} else if (!(options.filesContainer instanceof $)) {
options.filesContainer = $(options.filesContainer);
}
},
_initSpecialOptions: function () {
this._super();
this._initFilesContainer();
this._initTemplates();
},
_create: function () {
this._super();
this._resetFinishedDeferreds();
if (!$.support.fileInput) {
this._disableFileInputButton();
}
},
enable: function () {
var wasDisabled = false;
if (this.options.disabled) {
wasDisabled = true;
}
this._super();
if (wasDisabled) {
this.element.find('input, button').prop('disabled', false);
this._enableFileInputButton();
}
},
disable: function () {
if (!this.options.disabled) {
this.element.find('input, button').prop('disabled', true);
this._disableFileInputButton();
}
this._super();
}
});
}));

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,214 @@
/*
* jQuery Iframe Transport Plugin 1.8.2
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
/* global define, window, document */
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['jquery'], factory);
} else {
// Browser globals:
factory(window.jQuery);
}
}(function ($) {
'use strict';
// Helper variable to create unique names for the transport iframes:
var counter = 0;
// The iframe transport accepts four additional options:
// options.fileInput: a jQuery collection of file input fields
// options.paramName: the parameter name for the file form data,
// overrides the name property of the file input field(s),
// can be a string or an array of strings.
// options.formData: an array of objects with name and value properties,
// equivalent to the return data of .serializeArray(), e.g.:
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
// options.initialIframeSrc: the URL of the initial iframe src,
// by default set to "javascript:false;"
$.ajaxTransport('iframe', function (options) {
if (options.async) {
// javascript:false as initial iframe src
// prevents warning popups on HTTPS in IE6:
/*jshint scripturl: true */
var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
/*jshint scripturl: false */
form,
iframe,
addParamChar;
return {
send: function (_, completeCallback) {
form = $('<form style="display:none;"></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';
}
// IE versions below IE8 cannot set the name property of
// elements that have already been added to the DOM,
// so we set the name along with the iframe HTML markup:
counter += 1;
iframe = $(
'<iframe src="' + initialIframeSrc +
'" name="iframe-transport-' + counter + '"></iframe>'
).bind('load', function () {
var fileInputClones,
paramNames = $.isArray(options.paramName) ?
options.paramName : [options.paramName];
iframe
.unbind('load')
.bind('load', function () {
var response;
// Wrap in a try/catch block to catch exceptions thrown
// when trying to access cross-domain iframe contents:
try {
response = iframe.contents();
// Google Chrome and Firefox do not throw an
// exception when calling iframe.contents() on
// cross-domain requests, so we unify the response:
if (!response.length || !response[0].firstChild) {
throw new Error();
}
} catch (e) {
response = undefined;
}
// The complete callback returns the
// iframe content document as response object:
completeCallback(
200,
'success',
{'iframe': response}
);
// Fix for IE endless progress bar activity bug
// (happens on form submits to iframe targets):
$('<iframe src="' + initialIframeSrc + '"></iframe>')
.appendTo(form);
window.setTimeout(function () {
// Removing the form in a setTimeout call
// allows Chrome's developer tools to display
// the response result
form.remove();
}, 0);
});
form
.prop('target', iframe.prop('name'))
.prop('action', options.url)
.prop('method', options.type);
if (options.formData) {
$.each(options.formData, function (index, field) {
$('<input type="hidden"/>')
.prop('name', field.name)
.val(field.value)
.appendTo(form);
});
}
if (options.fileInput && options.fileInput.length &&
options.type === 'POST') {
fileInputClones = options.fileInput.clone();
// Insert a clone for each file input field:
options.fileInput.after(function (index) {
return fileInputClones[index];
});
if (options.paramName) {
options.fileInput.each(function (index) {
$(this).prop(
'name',
paramNames[index] || options.paramName
);
});
}
// Appending the file input fields to the hidden form
// removes them from their original location:
form
.append(options.fileInput)
.prop('enctype', 'multipart/form-data')
// enctype must be set as encoding for IE:
.prop('encoding', 'multipart/form-data');
// Remove the HTML5 form attribute from the input(s):
options.fileInput.removeAttr('form');
}
form.submit();
// Insert the file input fields at their original location
// by replacing the clones with the originals:
if (fileInputClones && fileInputClones.length) {
options.fileInput.each(function (index, input) {
var clone = $(fileInputClones[index]);
// Restore the original name and form properties:
$(input)
.prop('name', clone.prop('name'))
.attr('form', clone.attr('form'));
clone.replaceWith(input);
});
}
});
form.append(iframe).appendTo(document.body);
},
abort: function () {
if (iframe) {
// javascript:false as iframe src aborts the request
// and prevents warning popups on HTTPS in IE6.
// concat is used to avoid the "Script URL" JSLint error:
iframe
.unbind('load')
.prop('src', initialIframeSrc);
}
if (form) {
form.remove();
}
}
};
}
});
// The iframe transport returns the iframe content document as response.
// The following adds converters from iframe to text, json, html, xml
// and script.
// Please note that the Content-Type for JSON responses has to be text/plain
// or text/html, if the browser doesn't include application/json in the
// Accept header, else IE will show a download dialog.
// The Content-Type for XML responses on the other hand has to be always
// application/xml or text/xml, so IE properly parses the XML response.
// See also
// https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
$.ajaxSetup({
converters: {
'iframe text': function (iframe) {
return iframe && $(iframe[0].body).text();
},
'iframe json': function (iframe) {
return iframe && $.parseJSON($(iframe[0].body).text());
},
'iframe html': function (iframe) {
return iframe && $(iframe[0].body).html();
},
'iframe xml': function (iframe) {
var xmlDoc = iframe && iframe[0];
return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
$.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
$(xmlDoc.body).html());
},
'iframe script': function (iframe) {
return iframe && $.globalEval($(iframe[0].body).text());
}
}
});
}));

View File

@ -0,0 +1,530 @@
/*!
* jQuery UI Widget 1.10.4+amd
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2014 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/jQuery.widget/
*/
(function (factory) {
if (typeof define === "function" && define.amd) {
// Register as an anonymous AMD module:
define(["jquery"], factory);
} else {
// Browser globals:
factory(jQuery);
}
}(function( $, undefined ) {
var uuid = 0,
slice = Array.prototype.slice,
_cleanData = $.cleanData;
$.cleanData = function( elems ) {
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
try {
$( elem ).triggerHandler( "remove" );
// http://bugs.jquery.com/ticket/8235
} catch( e ) {}
}
_cleanData( 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 ];
fullName = namespace + "-" + name;
if ( !prototype ) {
prototype = base;
base = $.Widget;
}
// create selector for plugin
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
return !!$.data( elem, fullName );
};
$[ namespace ] = $[ namespace ] || {};
existingConstructor = $[ namespace ][ name ];
constructor = $[ namespace ][ name ] = function( options, element ) {
// allow instantiation without "new" keyword
if ( !this._createWidget ) {
return new constructor( options, element );
}
// allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if ( arguments.length ) {
this._createWidget( options, element );
}
};
// extend with the existing constructor to carry over any static properties
$.extend( constructor, existingConstructor, {
version: prototype.version,
// copy the object used to create the prototype in case we need to
// redefine the widget later
_proto: $.extend( {}, prototype ),
// track widgets that inherit from this widget in case this widget is
// redefined after a widget inherits from it
_childConstructors: []
});
basePrototype = new base();
// 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
// inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options );
$.each( prototype, function( prop, value ) {
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: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
}, proxiedPrototype, {
constructor: constructor,
namespace: namespace,
widgetName: name,
widgetFullName: fullName
});
// 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
// the new version of this widget. We're essentially trying to replace one
// level in the prototype chain.
if ( existingConstructor ) {
$.each( existingConstructor._childConstructors, function( i, child ) {
var childPrototype = child.prototype;
// redefine the child widget using the same prototype that was
// originally used, but inherit from the new version of the base
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
});
// remove the list of existing child constructors from the old constructor
// so the old child constructors can be garbage collected
delete existingConstructor._childConstructors;
} else {
base._childConstructors.push( constructor );
}
$.widget.bridge( name, constructor );
};
$.widget.extend = function( target ) {
var input = slice.call( arguments, 1 ),
inputIndex = 0,
inputLength = input.length,
key,
value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
// Clone objects
if ( $.isPlainObject( value ) ) {
target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value );
// Copy everything else by reference
} else {
target[ key ] = value;
}
}
}
}
return target;
};
$.widget.bridge = function( name, object ) {
var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
args = slice.call( arguments, 1 ),
returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
$.widget.extend.apply( null, [ options ].concat(args) ) :
options;
if ( isMethodCall ) {
this.each(function() {
var methodValue,
instance = $.data( this, fullName );
if ( !instance ) {
return $.error( "cannot call methods on " + name + " prior to initialization; " +
"attempted to call method '" + options + "'" );
}
if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
return $.error( "no such method '" + options + "' for " + name + " widget instance" );
}
methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue && methodValue.jquery ?
returnValue.pushStack( methodValue.get() ) :
methodValue;
return false;
}
});
} else {
this.each(function() {
var instance = $.data( this, fullName );
if ( instance ) {
instance.option( options || {} )._init();
} else {
$.data( this, fullName, new object( options, this ) );
}
});
}
return returnValue;
};
};
$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];
$.Widget.prototype = {
widgetName: "widget",
widgetEventPrefix: "",
defaultElement: "<div>",
options: {
disabled: false,
// callbacks
create: null
},
_createWidget: function( options, element ) {
element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element );
this.uuid = uuid++;
this.eventNamespace = "." + this.widgetName + this.uuid;
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
this.bindings = $();
this.hoverable = $();
this.focusable = $();
if ( element !== this ) {
$.data( element, this.widgetFullName, this );
this._on( true, this.element, {
remove: function( event ) {
if ( event.target === element ) {
this.destroy();
}
}
});
this.document = $( element.style ?
// element within the document
element.ownerDocument :
// element is window or document
element.document || element );
this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
}
this._create();
this._trigger( "create", null, this._getCreateEventData() );
this._init();
},
_getCreateOptions: $.noop,
_getCreateEventData: $.noop,
_create: $.noop,
_init: $.noop,
destroy: function() {
this._destroy();
// we can probably remove the unbind calls in 2.0
// all event bindings should go through this._on()
this.element
.unbind( this.eventNamespace )
// 1.9 BC for #7810
// TODO remove dual storage
.removeData( this.widgetName )
.removeData( this.widgetFullName )
// support: jquery <1.6.3
// http://bugs.jquery.com/ticket/9413
.removeData( $.camelCase( this.widgetFullName ) );
this.widget()
.unbind( this.eventNamespace )
.removeAttr( "aria-disabled" )
.removeClass(
this.widgetFullName + "-disabled " +
"ui-state-disabled" );
// clean up events and states
this.bindings.unbind( this.eventNamespace );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
},
_destroy: $.noop,
widget: function() {
return this.element;
},
option: function( key, value ) {
var options = key,
parts,
curOption,
i;
if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
return $.widget.extend( {}, this.options );
}
if ( typeof key === "string" ) {
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {};
parts = key.split( "." );
key = parts.shift();
if ( parts.length ) {
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
for ( i = 0; i < parts.length - 1; i++ ) {
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
curOption = curOption[ parts[ i ] ];
}
key = parts.pop();
if ( arguments.length === 1 ) {
return curOption[ key ] === undefined ? null : curOption[ key ];
}
curOption[ key ] = value;
} else {
if ( arguments.length === 1 ) {
return this.options[ key ] === undefined ? null : this.options[ key ];
}
options[ key ] = value;
}
}
this._setOptions( options );
return this;
},
_setOptions: function( options ) {
var key;
for ( key in options ) {
this._setOption( key, options[ key ] );
}
return this;
},
_setOption: function( key, value ) {
this.options[ key ] = value;
if ( key === "disabled" ) {
this.widget()
.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
.attr( "aria-disabled", value );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
}
return this;
},
enable: function() {
return this._setOption( "disabled", false );
},
disable: function() {
return this._setOption( "disabled", true );
},
_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;
element = this.element;
delegateElement = this.widget();
} else {
// accept selectors, DOM elements
element = delegateElement = $( element );
this.bindings = this.bindings.add( element );
}
$.each( handlers, function( event, handler ) {
function handlerProxy() {
// allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
if ( !suppressDisabledCheck &&
( instance.options.disabled === true ||
$( this ).hasClass( "ui-state-disabled" ) ) ) {
return;
}
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
// copy the guid so direct unbinding works
if ( typeof handler !== "string" ) {
handlerProxy.guid = handler.guid =
handler.guid || handlerProxy.guid || $.guid++;
}
var match = event.match( /^(\w+)\s*(.*)$/ ),
eventName = match[1] + instance.eventNamespace,
selector = match[2];
if ( selector ) {
delegateElement.delegate( selector, eventName, handlerProxy );
} else {
element.bind( eventName, handlerProxy );
}
});
},
_off: function( element, eventName ) {
eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
element.unbind( eventName ).undelegate( eventName );
},
_delay: function( handler, delay ) {
function handlerProxy() {
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
var instance = this;
return setTimeout( handlerProxy, delay || 0 );
},
_hoverable: function( element ) {
this.hoverable = this.hoverable.add( element );
this._on( element, {
mouseenter: function( event ) {
$( event.currentTarget ).addClass( "ui-state-hover" );
},
mouseleave: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-hover" );
}
});
},
_focusable: function( element ) {
this.focusable = this.focusable.add( element );
this._on( element, {
focusin: function( event ) {
$( event.currentTarget ).addClass( "ui-state-focus" );
},
focusout: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-focus" );
}
});
},
_trigger: function( type, event, data ) {
var prop, orig,
callback = this.options[ type ];
data = data || {};
event = $.Event( event );
event.type = ( type === this.widgetEventPrefix ?
type :
this.widgetEventPrefix + type ).toLowerCase();
// the original event may come from any element
// so we need to reset the target on the new event
event.target = this.element[ 0 ];
// copy original event properties over to the new event
orig = event.originalEvent;
if ( orig ) {
for ( prop in orig ) {
if ( !( prop in event ) ) {
event[ prop ] = orig[ prop ];
}
}
}
this.element.trigger( event, data );
return !( $.isFunction( callback ) &&
callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
event.isDefaultPrevented() );
}
};
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
if ( typeof options === "string" ) {
options = { effect: options };
}
var hasOptions,
effectName = !options ?
method :
options === true || typeof options === "number" ?
defaultEffect :
options.effect || defaultEffect;
options = options || {};
if ( typeof options === "number" ) {
options = { duration: options };
}
hasOptions = !$.isEmptyObject( options );
options.complete = callback;
if ( options.delay ) {
element.delay( options.delay );
}
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) {
element[ effectName ]( options.duration, options.easing, callback );
} else {
element.queue(function( next ) {
$( this )[ method ]();
if ( callback ) {
callback.call( element[ 0 ] );
}
next();
});
}
};
});
}));