diff options
Diffstat (limited to 'ui')
44 files changed, 2526 insertions, 1580 deletions
diff --git a/ui/i18n/jquery.ui.datepicker-ar.js b/ui/i18n/jquery.ui.datepicker-ar.js index c799b48d8..9e37911c2 100644 --- a/ui/i18n/jquery.ui.datepicker-ar.js +++ b/ui/i18n/jquery.ui.datepicker-ar.js @@ -1,6 +1,5 @@ /* Arabic Translation for jQuery UI date picker plugin. */ -/* Khaled Al Horani -- koko.dw@gmail.com */ -/* خالد الحوراني -- koko.dw@gmail.com */ +/* Khaled Alhourani -- me@khaledalhourani.com */ /* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */ jQuery(function($){ $.datepicker.regional['ar'] = { @@ -10,13 +9,13 @@ jQuery(function($){ currentText: 'اليوم', monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'آذار', 'حزيران', 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], - monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], - dayNames: ['السبت', 'الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة'], - dayNamesShort: ['سبت', 'أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة'], - dayNamesMin: ['سبت', 'أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], weekHeader: 'أسبوع', dateFormat: 'dd/mm/yy', - firstDay: 0, + firstDay: 6, isRTL: true, showMonthAfterYear: false, yearSuffix: ''}; diff --git a/ui/i18n/jquery.ui.datepicker-fr.js b/ui/i18n/jquery.ui.datepicker-fr.js index 134bda65d..74ea1c231 100644 --- a/ui/i18n/jquery.ui.datepicker-fr.js +++ b/ui/i18n/jquery.ui.datepicker-fr.js @@ -1,23 +1,25 @@ /* French initialisation for the jQuery UI date picker plugin. */ -/* Written by Keith Wood (kbwood{at}iinet.com.au) and Stéphane Nahmani (sholby@sholby.net). */ +/* Written by Keith Wood (kbwood{at}iinet.com.au), + Stéphane Nahmani (sholby@sholby.net), + Stéphane Raimbault <stephane.raimbault@gmail.com> */ jQuery(function($){ $.datepicker.regional['fr'] = { closeText: 'Fermer', - prevText: '<Préc', - nextText: 'Suiv>', - currentText: 'Courant', + prevText: 'Précédent', + nextText: 'Suivant', + currentText: 'Aujourd\'hui', monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], - monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun', - 'Jul','Aoû','Sep','Oct','Nov','Déc'], + monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin', + 'Juil.','Août','Sept.','Oct.','Nov.','Déc.'], dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], - dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], - dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], - weekHeader: 'Sm', + dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'], + dayNamesMin: ['D','L','M','M','J','V','S'], + weekHeader: 'Sem.', dateFormat: 'dd/mm/yy', firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: ''}; $.datepicker.setDefaults($.datepicker.regional['fr']); -});
\ No newline at end of file +}); diff --git a/ui/i18n/jquery.ui.datepicker-gl.js b/ui/i18n/jquery.ui.datepicker-gl.js new file mode 100644 index 000000000..278403e8f --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-gl.js @@ -0,0 +1,23 @@ +/* Galician localization for 'UI date picker' jQuery extension. */ +/* Translated by Jorge Barreiro <yortx.barry@gmail.com>. */ +jQuery(function($){ + $.datepicker.regional['gl'] = { + closeText: 'Pechar', + prevText: '<Ant', + nextText: 'Seg>', + currentText: 'Hoxe', + monthNames: ['Xaneiro','Febreiro','Marzo','Abril','Maio','Xuño', + 'Xullo','Agosto','Setembro','Outubro','Novembro','Decembro'], + monthNamesShort: ['Xan','Feb','Mar','Abr','Mai','Xuñ', + 'Xul','Ago','Set','Out','Nov','Dec'], + dayNames: ['Domingo','Luns','Martes','Mércores','Xoves','Venres','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mér','Xov','Ven','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mé','Xo','Ve','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['gl']); +});
\ No newline at end of file diff --git a/ui/i18n/jquery.ui.datepicker-kz.js b/ui/i18n/jquery.ui.datepicker-kz.js new file mode 100644 index 000000000..f1f897b00 --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-kz.js @@ -0,0 +1,23 @@ +/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['kz'] = { + closeText: 'Жабу', + prevText: '<Алдыңғы', + nextText: 'Келесі>', + currentText: 'Бүгін', + monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым', + 'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'], + monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау', + 'Шіл','Там','Қыр','Қаз','Қар','Жел'], + dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'], + dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'], + dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'], + weekHeader: 'Не', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['kz']); +}); diff --git a/ui/i18n/jquery.ui.datepicker-no.js b/ui/i18n/jquery.ui.datepicker-no.js index 12b2356bf..6b3a498be 100644 --- a/ui/i18n/jquery.ui.datepicker-no.js +++ b/ui/i18n/jquery.ui.datepicker-no.js @@ -14,8 +14,8 @@ jQuery(function($){ dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'], dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'], weekHeader: 'Uke', - dateFormat: 'yy-mm-dd', - firstDay: 0, + dateFormat: 'dd.mm.yy', + firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: ''}; diff --git a/ui/i18n/jquery.ui.datepicker-pl.js b/ui/i18n/jquery.ui.datepicker-pl.js index d315bf523..61fa29ccd 100644 --- a/ui/i18n/jquery.ui.datepicker-pl.js +++ b/ui/i18n/jquery.ui.datepicker-pl.js @@ -14,7 +14,7 @@ jQuery(function($){ dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'], dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'], weekHeader: 'Tydz', - dateFormat: 'yy-mm-dd', + dateFormat: 'dd.mm.yy', firstDay: 1, isRTL: false, showMonthAfterYear: false, diff --git a/ui/i18n/jquery.ui.datepicker-pt-BR.js b/ui/i18n/jquery.ui.datepicker-pt-BR.js index 38818637d..3cc8c796c 100644 --- a/ui/i18n/jquery.ui.datepicker-pt-BR.js +++ b/ui/i18n/jquery.ui.datepicker-pt-BR.js @@ -10,9 +10,9 @@ jQuery(function($){ 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', 'Jul','Ago','Set','Out','Nov','Dez'], - dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sabado'], - dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sab'], - dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sab'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], weekHeader: 'Sm', dateFormat: 'dd/mm/yy', firstDay: 0, diff --git a/ui/i18n/jquery.ui.datepicker-pt.js b/ui/i18n/jquery.ui.datepicker-pt.js new file mode 100644 index 000000000..f09f5aeb0 --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-pt.js @@ -0,0 +1,22 @@ +/* Portuguese initialisation for the jQuery UI date picker plugin. */ +jQuery(function($){ + $.datepicker.regional['pt'] = { + closeText: 'Fechar', + prevText: '<Anterior', + nextText: 'Seguinte', + currentText: 'Hoje', + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + weekHeader: 'Sem', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pt']); +});
\ No newline at end of file diff --git a/ui/i18n/jquery.ui.datepicker-rm.js b/ui/i18n/jquery.ui.datepicker-rm.js new file mode 100644 index 000000000..cf03cd4c1 --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-rm.js @@ -0,0 +1,21 @@ +/* Romansh initialisation for the jQuery UI date picker plugin. */ +/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */ +jQuery(function($){ + $.datepicker.regional['rm'] = { + closeText: 'Serrar', + prevText: '<Suandant', + nextText: 'Precedent>', + currentText: 'Actual', + monthNames: ['Schaner','Favrer','Mars','Avrigl','Matg','Zercladur', 'Fanadur','Avust','Settember','October','November','December'], + monthNamesShort: ['Scha','Fev','Mar','Avr','Matg','Zer', 'Fan','Avu','Sett','Oct','Nov','Dec'], + dayNames: ['Dumengia','Glindesdi','Mardi','Mesemna','Gievgia','Venderdi','Sonda'], + dayNamesShort: ['Dum','Gli','Mar','Mes','Gie','Ven','Som'], + dayNamesMin: ['Du','Gl','Ma','Me','Gi','Ve','So'], + weekHeader: 'emna', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['rm']); +}); diff --git a/ui/i18n/jquery.ui.datepicker-ru.js b/ui/i18n/jquery.ui.datepicker-ru.js index b8091f9ec..50a461352 100644 --- a/ui/i18n/jquery.ui.datepicker-ru.js +++ b/ui/i18n/jquery.ui.datepicker-ru.js @@ -13,7 +13,7 @@ jQuery(function($){ dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'], - weekHeader: 'Не', + weekHeader: 'Нед', dateFormat: 'dd.mm.yy', firstDay: 1, isRTL: false, diff --git a/ui/i18n/jquery.ui.datepicker-sk.js b/ui/i18n/jquery.ui.datepicker-sk.js index e8e73e671..8a6771c1e 100644 --- a/ui/i18n/jquery.ui.datepicker-sk.js +++ b/ui/i18n/jquery.ui.datepicker-sk.js @@ -15,7 +15,7 @@ jQuery(function($){ dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'], weekHeader: 'Ty', dateFormat: 'dd.mm.yy', - firstDay: 0, + firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: ''}; diff --git a/ui/i18n/jquery.ui.datepicker-th.js b/ui/i18n/jquery.ui.datepicker-th.js index 978500ab1..c090c6b81 100644 --- a/ui/i18n/jquery.ui.datepicker-th.js +++ b/ui/i18n/jquery.ui.datepicker-th.js @@ -7,7 +7,7 @@ jQuery(function($){ nextText: 'ถัดไป »', currentText: 'วันนี้', monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน', - 'กรกฏาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'], + 'กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'], monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.', 'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'], dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'], diff --git a/ui/jquery.effects.blind.js b/ui/jquery.effects.blind.js index c510e6ef3..44f398a55 100644 --- a/ui/jquery.effects.blind.js +++ b/ui/jquery.effects.blind.js @@ -1,23 +1,23 @@ /* * jQuery UI Effects Blind @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Blind * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.blind = function(o) { return this.queue(function() { // Create element - var el = $(this), props = ['position','top','left']; + var el = $(this), props = ['position','top','bottom','left','right']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode diff --git a/ui/jquery.effects.bounce.js b/ui/jquery.effects.bounce.js index 1cfc00643..ec4a77ec4 100644 --- a/ui/jquery.effects.bounce.js +++ b/ui/jquery.effects.bounce.js @@ -1,23 +1,23 @@ /* * jQuery UI Effects Bounce @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Bounce * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.bounce = function(o) { return this.queue(function() { // Create element - var el = $(this), props = ['position','top','left']; + var el = $(this), props = ['position','top','bottom','left','right']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode diff --git a/ui/jquery.effects.clip.js b/ui/jquery.effects.clip.js index 2ad7622fc..9fa8df94a 100644 --- a/ui/jquery.effects.clip.js +++ b/ui/jquery.effects.clip.js @@ -1,23 +1,23 @@ /* * jQuery UI Effects Clip @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Clip * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.clip = function(o) { return this.queue(function() { // Create element - var el = $(this), props = ['position','top','left','height','width']; + var el = $(this), props = ['position','top','bottom','left','right','height','width']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode diff --git a/ui/jquery.effects.core.js b/ui/jquery.effects.core.js index ed7eb099e..bb88dcf19 100644 --- a/ui/jquery.effects.core.js +++ b/ui/jquery.effects.core.js @@ -1,13 +1,13 @@ /* * jQuery UI Effects @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/ */ -;jQuery.effects || (function($) { +;jQuery.effects || (function($, undefined) { $.effects = {}; @@ -19,7 +19,7 @@ $.effects = {}; // override the animation for color styles $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', - 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], + 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'], function(i, attr) { $.fx.step[attr] = function(fx) { if (!fx.colorInit) { @@ -231,8 +231,7 @@ $.effects.animateClass = function(value, duration, easing, callback) { easing = null; } - return this.each(function() { - + return this.queue('fx', function() { var that = $(this), originalStyleAttr = that.attr('style') || ' ', originalStyle = filterStyles(getElementStyles.call(this)), @@ -260,6 +259,13 @@ $.effects.animateClass = function(value, duration, easing, callback) { } if (callback) { callback.apply(this, arguments); } }); + + // $.animate adds a function to the end of the queue + // but we want it at the front + var queue = $.queue(this), + anim = queue.splice(queue.length - 1, 1)[0]; + queue.splice(1, 0, anim); + $.dequeue(this); }); }; @@ -382,7 +388,7 @@ $.extend($.effects, { props[pos] = 'auto'; } }); - element.css({position: 'relative', top: 0, left: 0 }); + element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' }); } return wrapper.css(props).show(); @@ -418,44 +424,72 @@ function _normalizeArguments(effect, options, speed, callback) { speed = null; options = {}; } - if ($.isFunction(speed)) { - callback = speed; - speed = null; - } - if (typeof options == 'number' || $.fx.speeds[options]) { + if (typeof options == 'number' || $.fx.speeds[options]) { callback = speed; speed = options; options = {}; } + if ($.isFunction(speed)) { + callback = speed; + speed = null; + } options = options || {}; speed = speed || options.duration; speed = $.fx.off ? 0 : typeof speed == 'number' - ? speed : $.fx.speeds[speed] || $.fx.speeds._default; + ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default; callback = callback || options.complete; return [effect, options, speed, callback]; } +function standardSpeed( speed ) { + // valid standard speeds + if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { + return true; + } + + // invalid strings - treat as "normal" speed + if ( typeof speed === "string" && !$.effects[ speed ] ) { + return true; + } + + return false; +} + $.fn.extend({ effect: function(effect, options, speed, callback) { var args = _normalizeArguments.apply(this, arguments), - // TODO: make effects takes actual parameters instead of a hash + // TODO: make effects take actual parameters instead of a hash args2 = { options: args[1], duration: args[2], callback: args[3] }, + mode = args2.options.mode, effectMethod = $.effects[effect]; - return effectMethod && !$.fx.off ? effectMethod.call(this, args2) : this; + if ( $.fx.off || !effectMethod ) { + // delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args2.duration, args2.callback ); + } else { + return this.each(function() { + if ( args2.callback ) { + args2.callback.call( this ); + } + }); + } + } + + return effectMethod.call(this, args2); }, _show: $.fn.show, show: function(speed) { - if (!speed || typeof speed == 'number' || $.fx.speeds[speed]) { + if ( standardSpeed( speed ) ) { return this._show.apply(this, arguments); } else { var args = _normalizeArguments.apply(this, arguments); @@ -466,7 +500,7 @@ $.fn.extend({ _hide: $.fn.hide, hide: function(speed) { - if (!speed || typeof speed == 'number' || $.fx.speeds[speed]) { + if ( standardSpeed( speed ) ) { return this._hide.apply(this, arguments); } else { var args = _normalizeArguments.apply(this, arguments); @@ -475,11 +509,10 @@ $.fn.extend({ } }, - // jQuery core overloads toggle and create _toggle + // jQuery core overloads toggle and creates _toggle __toggle: $.fn.toggle, toggle: function(speed) { - if (!speed || typeof speed == 'number' || $.fx.speeds[speed] || - typeof speed == 'boolean' || $.isFunction(speed)) { + if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { return this.__toggle.apply(this, arguments); } else { var args = _normalizeArguments.apply(this, arguments); diff --git a/ui/jquery.effects.drop.js b/ui/jquery.effects.drop.js index 6a637e49a..941508b2e 100644 --- a/ui/jquery.effects.drop.js +++ b/ui/jquery.effects.drop.js @@ -1,23 +1,23 @@ /* * jQuery UI Effects Drop @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Drop * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.drop = function(o) { return this.queue(function() { // Create element - var el = $(this), props = ['position','top','left','opacity']; + var el = $(this), props = ['position','top','bottom','left','right','opacity']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode diff --git a/ui/jquery.effects.explode.js b/ui/jquery.effects.explode.js index 8f4f413bf..05d9bcd39 100644 --- a/ui/jquery.effects.explode.js +++ b/ui/jquery.effects.explode.js @@ -1,16 +1,16 @@ /* * jQuery UI Effects Explode @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Explode * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.explode = function(o) { diff --git a/ui/jquery.effects.fade.js b/ui/jquery.effects.fade.js index c42a9f565..40483ee0c 100644 --- a/ui/jquery.effects.fade.js +++ b/ui/jquery.effects.fade.js @@ -1,16 +1,16 @@ /* * jQuery UI Effects Fade @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Fade * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.fade = function(o) { return this.queue(function() { diff --git a/ui/jquery.effects.fold.js b/ui/jquery.effects.fold.js index 1098ee420..f19ae1bf2 100644 --- a/ui/jquery.effects.fold.js +++ b/ui/jquery.effects.fold.js @@ -1,23 +1,23 @@ /* * jQuery UI Effects Fold @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Fold * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.fold = function(o) { return this.queue(function() { // Create element - var el = $(this), props = ['position','top','left']; + var el = $(this), props = ['position','top','bottom','left','right']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode diff --git a/ui/jquery.effects.highlight.js b/ui/jquery.effects.highlight.js index 4719abed9..bd6d21b25 100644 --- a/ui/jquery.effects.highlight.js +++ b/ui/jquery.effects.highlight.js @@ -1,16 +1,16 @@ /* * jQuery UI Effects Highlight @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Highlight * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.highlight = function(o) { return this.queue(function() { diff --git a/ui/jquery.effects.pulsate.js b/ui/jquery.effects.pulsate.js index ca1af19fd..4d325c4e1 100644 --- a/ui/jquery.effects.pulsate.js +++ b/ui/jquery.effects.pulsate.js @@ -1,16 +1,16 @@ /* * jQuery UI Effects Pulsate @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Pulsate * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.pulsate = function(o) { return this.queue(function() { diff --git a/ui/jquery.effects.scale.js b/ui/jquery.effects.scale.js index ee430e7b8..d980882db 100644 --- a/ui/jquery.effects.scale.js +++ b/ui/jquery.effects.scale.js @@ -1,16 +1,16 @@ /* * jQuery UI Effects Scale @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Scale * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.puff = function(o) { return this.queue(function() { @@ -84,8 +84,8 @@ $.effects.size = function(o) { return this.queue(function() { // Create element - var el = $(this), props = ['position','top','left','width','height','overflow','opacity']; - var props1 = ['position','top','left','overflow','opacity']; // Always restore + var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity']; + var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore var props2 = ['width','height','overflow']; // Copy for children var cProps = ['fontSize']; var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom']; diff --git a/ui/jquery.effects.shake.js b/ui/jquery.effects.shake.js index dd3e1cb61..b94e5a5ab 100644 --- a/ui/jquery.effects.shake.js +++ b/ui/jquery.effects.shake.js @@ -1,23 +1,23 @@ /* * jQuery UI Effects Shake @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Shake * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.shake = function(o) { return this.queue(function() { // Create element - var el = $(this), props = ['position','top','left']; + var el = $(this), props = ['position','top','bottom','left','right']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode diff --git a/ui/jquery.effects.slide.js b/ui/jquery.effects.slide.js index d84447d13..59f6dc578 100644 --- a/ui/jquery.effects.slide.js +++ b/ui/jquery.effects.slide.js @@ -1,23 +1,23 @@ /* * jQuery UI Effects Slide @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Slide * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.slide = function(o) { return this.queue(function() { // Create element - var el = $(this), props = ['position','top','left']; + var el = $(this), props = ['position','top','bottom','left','right']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode @@ -29,7 +29,7 @@ $.effects.slide = function(o) { var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true})); - if (mode == 'show') el.css(ref, motion == 'pos' ? -distance : distance); // Shift + if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift // Animation var animation = {}; diff --git a/ui/jquery.effects.transfer.js b/ui/jquery.effects.transfer.js index f597d4b43..2741e9d4b 100644 --- a/ui/jquery.effects.transfer.js +++ b/ui/jquery.effects.transfer.js @@ -1,16 +1,16 @@ /* * jQuery UI Effects Transfer @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Effects/Transfer * * Depends: * jquery.effects.core.js */ -(function($) { +(function( $, undefined ) { $.effects.transfer = function(o) { return this.queue(function() { diff --git a/ui/jquery.ui.accordion.js b/ui/jquery.ui.accordion.js index 0ac478b73..955030ccc 100644 --- a/ui/jquery.ui.accordion.js +++ b/ui/jquery.ui.accordion.js @@ -1,9 +1,9 @@ /* * jQuery UI Accordion @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Accordion * @@ -11,342 +11,401 @@ * jquery.ui.core.js * jquery.ui.widget.js */ -(function($) { +(function( $, undefined ) { -$.widget("ui.accordion", { +$.widget( "ui.accordion", { options: { active: 0, - animated: 'slide', - autoHeight: true, - clearStyle: false, + animated: "slide", collapsible: false, event: "click", - fillSpace: false, header: "> li > :first-child,> :not(li):even", + // TODO: set to "auto" in 2.0 (#5868, #5872) + heightStyle: null, // "auto" icons: { header: "ui-icon-triangle-1-e", headerSelected: "ui-icon-triangle-1-s" - }, - navigation: false, - navigationFilter: function() { - return this.href.toLowerCase() == location.href.toLowerCase(); } }, - _create: function() { - - var o = this.options, self = this; - this.running = 0; - - this.element.addClass("ui-accordion ui-widget ui-helper-reset"); - - // in lack of child-selectors in CSS we need to mark top-LIs in a UL-accordion for some IE-fix - if (this.element[0].nodeName == "UL") { - this.element.children("li").addClass("ui-accordion-li-fix"); - } - - this.headers = this.element.find(o.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all") - .bind("mouseenter.accordion", function(){ $(this).addClass('ui-state-hover'); }) - .bind("mouseleave.accordion", function(){ $(this).removeClass('ui-state-hover'); }) - .bind("focus.accordion", function(){ $(this).addClass('ui-state-focus'); }) - .bind("blur.accordion", function(){ $(this).removeClass('ui-state-focus'); }); - this.headers - .next() - .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); - - if ( o.navigation ) { - var current = this.element.find("a").filter(o.navigationFilter); - if ( current.length ) { - var header = current.closest(".ui-accordion-header"); - if ( header.length ) { - // anchor within header - this.active = header; - } else { - // anchor within content - this.active = current.closest(".ui-accordion-content").prev(); + _create: function() { + var self = this, + options = self.options; + + self.running = 0; + + self.element + .addClass( "ui-accordion ui-widget ui-helper-reset" ) + // in lack of child-selectors in CSS + // we need to mark top-LIs in a UL-accordion for some IE-fix + .children( "li" ) + .addClass( "ui-accordion-li-fix" ); + + self.headers = self.element.find( options.header ) + .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ) + .bind( "mouseenter.accordion", function() { + if ( options.disabled ) { + return; } - } - } - - this.active = this._findActive(this.active || o.active).toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"); - this.active.next().addClass('ui-accordion-content-active'); - - //Append icon elements - this._createIcons(); + $( this ).addClass( "ui-state-hover" ); + }) + .bind( "mouseleave.accordion", function() { + if ( options.disabled ) { + return; + } + $( this ).removeClass( "ui-state-hover" ); + }) + .bind( "focus.accordion", function() { + if ( options.disabled ) { + return; + } + $( this ).addClass( "ui-state-focus" ); + }) + .bind( "blur.accordion", function() { + if ( options.disabled ) { + return; + } + $( this ).removeClass( "ui-state-focus" ); + }); - this.resize(); + self.headers.next() + .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ); + self.headers.find( ":first-child" ).addClass( "ui-accordion-heading" ); - //ARIA - this.element.attr('role','tablist'); + self.active = self._findActive( self.active || options.active ) + .addClass( "ui-state-default ui-state-active" ) + .toggleClass( "ui-corner-all" ) + .toggleClass( "ui-corner-top" ); + self.active.next().addClass( "ui-accordion-content-active" ); - this.headers - .attr('role','tab') - .bind('keydown', function(event) { return self._keydown(event); }) + self._createIcons(); + self.resize(); + + // ARIA + self.element.attr( "role", "tablist" ); + + self.headers + .attr( "role", "tab" ) + .bind( "keydown.accordion", function( event ) { + return self._keydown( event ); + }) .next() - .attr('role','tabpanel'); - - this.headers - .not(this.active || "") - .attr('aria-expanded','false') - .attr("tabIndex", "-1") + .attr( "role", "tabpanel" ); + + self.headers + .not( self.active || "" ) + .attr({ + "aria-expanded": "false", + tabIndex: -1 + }) .next() - .hide(); + .hide(); // make sure at least one header is in the tab order - if (!this.active.length) { - this.headers.eq(0).attr('tabIndex','0'); + if ( !self.active.length ) { + self.headers.eq( 0 ).attr( "tabIndex", 0 ); } else { - this.active - .attr('aria-expanded','true') - .attr('tabIndex', '0'); + self.active + .attr({ + "aria-expanded": "true", + tabIndex: 0 + }); } - // only need links in taborder for Safari - if (!$.browser.safari) - this.headers.find('a').attr('tabIndex','-1'); + // only need links in tab order for Safari + if ( !$.browser.safari ) { + self.headers.find( "a" ).attr( "tabIndex", -1 ); + } - if (o.event) { - this.headers.bind((o.event) + ".accordion", function(event) { - self._clickHandler.call(self, event, this); + if ( options.event ) { + self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) { + self._clickHandler.call( self, event, this ); event.preventDefault(); }); } - }, - + _createIcons: function() { - var o = this.options; - if (o.icons) { - $("<span/>").addClass("ui-icon " + o.icons.header).prependTo(this.headers); - this.active.find(".ui-icon").toggleClass(o.icons.header).toggleClass(o.icons.headerSelected); - this.element.addClass("ui-accordion-icons"); + var options = this.options; + if ( options.icons ) { + $( "<span></span>" ) + .addClass( "ui-icon " + options.icons.header ) + .prependTo( this.headers ); + this.active.children( ".ui-icon" ) + .toggleClass(options.icons.header) + .toggleClass(options.icons.headerSelected); + this.element.addClass( "ui-accordion-icons" ); } }, - + _destroyIcons: function() { - this.headers.children(".ui-icon").remove(); - this.element.removeClass("ui-accordion-icons"); + this.headers.children( ".ui-icon" ).remove(); + this.element.removeClass( "ui-accordion-icons" ); }, destroy: function() { - var o = this.options; + var options = this.options; this.element - .removeClass("ui-accordion ui-widget ui-helper-reset") - .removeAttr("role") - .unbind('.accordion') - .removeData('accordion'); + .removeClass( "ui-accordion ui-widget ui-helper-reset" ) + .removeAttr( "role" ); this.headers - .unbind(".accordion") - .removeClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-corner-top") - .removeAttr("role").removeAttr("aria-expanded").removeAttr("tabIndex"); + .unbind( ".accordion" ) + .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) + .removeAttr( "role" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "tabIndex" ); - this.headers.find("a").removeAttr("tabIndex"); + this.headers.find( "a" ).removeAttr( "tabIndex" ); this._destroyIcons(); - var contents = this.headers.next().css("display", "").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active"); - if (o.autoHeight || o.fillHeight) { - contents.css("height", ""); + this.headers.find( "a:first-child" ).removeClass( "ui-accordion-heading" ); + var contents = this.headers.next() + .css( "display", "" ) + .removeAttr( "role" ) + .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" ); + if ( options.heightStyle !== "content" ) { + contents.css( "height", "" ); } - return this; + return $.Widget.prototype.destroy.call( this ); }, - - _setOption: function(key, value) { - $.Widget.prototype._setOption.apply(this, arguments); - - if (key == "active") { - this.activate(value); + + _setOption: function( key, value ) { + $.Widget.prototype._setOption.apply( this, arguments ); + + if ( key == "active" ) { + this.activate( value ); } - if (key == "icons") { + if ( key == "icons" ) { this._destroyIcons(); - if (value) { + if ( value ) { this._createIcons(); } } - + // #5332 - opacity doesn't cascade to positioned elements in IE + // so we need to add the disabled class to the headers and panels + if ( key == "disabled" ) { + this.headers.add(this.headers.next()) + .toggleClass( "ui-accordion-disabled ui-state-disabled", !!value ); + } }, - _keydown: function(event) { - - var o = this.options, keyCode = $.ui.keyCode; - - if (o.disabled || event.altKey || event.ctrlKey) + _keydown: function( event ) { + if ( this.options.disabled || event.altKey || event.ctrlKey ) { return; + } - var length = this.headers.length; - var currentIndex = this.headers.index(event.target); - var toFocus = false; + var keyCode = $.ui.keyCode, + length = this.headers.length, + currentIndex = this.headers.index( event.target ), + toFocus = false; - switch(event.keyCode) { + switch ( event.keyCode ) { case keyCode.RIGHT: case keyCode.DOWN: - toFocus = this.headers[(currentIndex + 1) % length]; + toFocus = this.headers[ ( currentIndex + 1 ) % length ]; break; case keyCode.LEFT: case keyCode.UP: - toFocus = this.headers[(currentIndex - 1 + length) % length]; + toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; break; case keyCode.SPACE: case keyCode.ENTER: - this._clickHandler({ target: event.target }, event.target); + this._clickHandler( { target: event.target }, event.target ); event.preventDefault(); } - if (toFocus) { - $(event.target).attr('tabIndex','-1'); - $(toFocus).attr('tabIndex','0'); + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); toFocus.focus(); return false; } return true; - }, resize: function() { + var options = this.options, + maxHeight; - var o = this.options, maxHeight; - - if (o.fillSpace) { - - if($.browser.msie) { var defOverflow = this.element.parent().css('overflow'); this.element.parent().css('overflow', 'hidden'); } + if ( options.heightStyle === "fill" ) { + if ( $.browser.msie ) { + var defOverflow = this.element.parent().css( "overflow" ); + this.element.parent().css( "overflow", "hidden"); + } maxHeight = this.element.parent().height(); - if($.browser.msie) { this.element.parent().css('overflow', defOverflow); } - - this.headers.each(function() { - maxHeight -= $(this).outerHeight(true); + this.element.siblings( ":visible" ).each(function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); }); + if ($.browser.msie) { + this.element.parent().css( "overflow", defOverflow ); + } - this.headers.next().each(function() { - $(this).height(Math.max(0, maxHeight - $(this).innerHeight() + $(this).height())); - }).css('overflow', 'auto'); + this.headers.each(function() { + maxHeight -= $( this ).outerHeight( true ); + }); - } else if ( o.autoHeight ) { + this.headers.next() + .each(function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + }) + .css( "overflow", "auto" ); + } else if ( options.heightStyle === "auto" ) { maxHeight = 0; - this.headers.next().each(function() { - maxHeight = Math.max(maxHeight, $(this).height()); - }).height(maxHeight); + this.headers.next() + .each(function() { + maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + }) + .height( maxHeight ); } return this; }, - activate: function(index) { + activate: function( index ) { // TODO this gets called on init, changing the option without an explicit call for that this.options.active = index; // call clickHandler with custom event - var active = this._findActive(index)[0]; - this._clickHandler({ target: active }, active); + var active = this._findActive( index )[ 0 ]; + this._clickHandler( { target: active }, active ); return this; }, - _findActive: function(selector) { + _findActive: function( selector ) { return selector - ? typeof selector == "number" - ? this.headers.filter(":eq(" + selector + ")") - : this.headers.not(this.headers.not(selector)) + ? typeof selector === "number" + ? this.headers.filter( ":eq(" + selector + ")" ) + : this.headers.not( this.headers.not( selector ) ) : selector === false - ? $([]) - : this.headers.filter(":eq(0)"); + ? $( [] ) + : this.headers.filter( ":eq(0)" ); }, - // TODO isn't event.target enough? why the seperate target argument? - _clickHandler: function(event, target) { - - var o = this.options; - if (o.disabled) + // TODO isn't event.target enough? why the separate target argument? + _clickHandler: function( event, target ) { + var options = this.options; + if ( options.disabled ) { return; + } // called only when using activate(false) to close all parts programmatically - if (!event.target) { - if (!o.collapsible) + if ( !event.target ) { + if ( !options.collapsible ) { return; - this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all") - .find(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header); - this.active.next().addClass('ui-accordion-content-active'); + } + this.active + .removeClass( "ui-state-active ui-corner-top" ) + .addClass( "ui-state-default ui-corner-all" ) + .children( ".ui-icon" ) + .removeClass( options.icons.headerSelected ) + .addClass( options.icons.header ); + this.active.next().addClass( "ui-accordion-content-active" ); var toHide = this.active.next(), data = { - options: o, - newHeader: $([]), - oldHeader: o.active, - newContent: $([]), + options: options, + newHeader: $( [] ), + oldHeader: options.active, + newContent: $( [] ), oldContent: toHide }, - toShow = (this.active = $([])); - this._toggle(toShow, toHide, data); + toShow = ( this.active = $( [] ) ); + this._toggle( toShow, toHide, data ); return; } // get the click target - var clicked = $(event.currentTarget || target); - var clickedIsActive = clicked[0] == this.active[0]; - + var clicked = $( event.currentTarget || target ), + clickedIsActive = clicked[0] === this.active[0]; + // TODO the option is changed, is that correct? // TODO if it is correct, shouldn't that happen after determining that the click is valid? - o.active = o.collapsible && clickedIsActive ? false : $('.ui-accordion-header', this.element).index(clicked); + options.active = options.collapsible && clickedIsActive ? + false : + this.headers.index( clicked ); // if animations are still active, or the active header is the target, ignore click - if (this.running || (!o.collapsible && clickedIsActive)) { + if ( this.running || ( !options.collapsible && clickedIsActive ) ) { return; } // switch classes - this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all") - .find(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header); - if (!clickedIsActive) { - clicked.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top") - .find(".ui-icon").removeClass(o.icons.header).addClass(o.icons.headerSelected); - clicked.next().addClass('ui-accordion-content-active'); + this.active + .removeClass( "ui-state-active ui-corner-top" ) + .addClass( "ui-state-default ui-corner-all" ) + .children( ".ui-icon" ) + .removeClass( options.icons.headerSelected ) + .addClass( options.icons.header ); + if ( !clickedIsActive ) { + clicked + .removeClass( "ui-state-default ui-corner-all" ) + .addClass( "ui-state-active ui-corner-top" ) + .children( ".ui-icon" ) + .removeClass( options.icons.header ) + .addClass( options.icons.headerSelected ); + clicked + .next() + .addClass( "ui-accordion-content-active" ); } // find elements to show and hide var toShow = clicked.next(), toHide = this.active.next(), data = { - options: o, - newHeader: clickedIsActive && o.collapsible ? $([]) : clicked, + options: options, + newHeader: clickedIsActive && options.collapsible ? $([]) : clicked, oldHeader: this.active, - newContent: clickedIsActive && o.collapsible ? $([]) : toShow, + newContent: clickedIsActive && options.collapsible ? $([]) : toShow, oldContent: toHide }, down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] ); this.active = clickedIsActive ? $([]) : clicked; - this._toggle(toShow, toHide, data, clickedIsActive, down); + this._toggle( toShow, toHide, data, clickedIsActive, down ); return; - }, - _toggle: function(toShow, toHide, data, clickedIsActive, down) { + _toggle: function( toShow, toHide, data, clickedIsActive, down ) { + var self = this, + options = self.options; - var o = this.options, self = this; + self.toShow = toShow; + self.toHide = toHide; + self.data = data; - this.toShow = toShow; - this.toHide = toHide; - this.data = data; - - var complete = function() { if(!self) return; return self._completed.apply(self, arguments); }; + var complete = function() { + if ( !self ) { + return; + } + return self._completed.apply( self, arguments ); + }; // trigger changestart event - this._trigger("changestart", null, this.data); + self._trigger( "changestart", null, self.data ); // count elements to animate - this.running = toHide.size() === 0 ? toShow.size() : toHide.size(); - - if (o.animated) { + self.running = toHide.size() === 0 ? toShow.size() : toHide.size(); + if ( options.animated ) { var animOptions = {}; - if ( o.collapsible && clickedIsActive ) { + if ( options.collapsible && clickedIsActive ) { animOptions = { - toShow: $([]), + toShow: $( [] ), toHide: toHide, complete: complete, down: down, - autoHeight: o.autoHeight || o.fillSpace + autoHeight: options.heightStyle !== "content" }; } else { animOptions = { @@ -354,101 +413,114 @@ $.widget("ui.accordion", { toHide: toHide, complete: complete, down: down, - autoHeight: o.autoHeight || o.fillSpace + autoHeight: options.heightStyle !== "content" }; } - if (!o.proxied) { - o.proxied = o.animated; + if ( !options.proxied ) { + options.proxied = options.animated; } - if (!o.proxiedDuration) { - o.proxiedDuration = o.duration; + if ( !options.proxiedDuration ) { + options.proxiedDuration = options.duration; } - o.animated = $.isFunction(o.proxied) ? - o.proxied(animOptions) : o.proxied; + options.animated = $.isFunction( options.proxied ) ? + options.proxied( animOptions ) : + options.proxied; - o.duration = $.isFunction(o.proxiedDuration) ? - o.proxiedDuration(animOptions) : o.proxiedDuration; + options.duration = $.isFunction( options.proxiedDuration ) ? + options.proxiedDuration( animOptions ) : + options.proxiedDuration; var animations = $.ui.accordion.animations, - duration = o.duration, - easing = o.animated; + duration = options.duration, + easing = options.animated; - if (easing && !animations[easing] && !$.easing[easing]) { - easing = 'slide'; + if ( easing && !animations[ easing ] && !$.easing[ easing ] ) { + easing = "slide"; } - if (!animations[easing]) { - animations[easing] = function(options) { - this.slide(options, { + if ( !animations[ easing ] ) { + animations[ easing ] = function( options ) { + this.slide( options, { easing: easing, duration: duration || 700 }); }; } - animations[easing](animOptions); - + animations[ easing ]( animOptions ); } else { - - if (o.collapsible && clickedIsActive) { + if ( options.collapsible && clickedIsActive ) { toShow.toggle(); } else { toHide.hide(); toShow.show(); } - complete(true); - + complete( true ); } // TODO assert that the blur and focus triggers are really necessary, remove otherwise - toHide.prev().attr('aria-expanded','false').attr("tabIndex", "-1").blur(); - toShow.prev().attr('aria-expanded','true').attr("tabIndex", "0").focus(); - + toHide.prev() + .attr({ + "aria-expanded": "false", + tabIndex: -1 + }) + .blur(); + toShow.prev() + .attr({ + "aria-expanded": "true", + tabIndex: 0 + }) + .focus(); }, - _completed: function(cancel) { - - var o = this.options; - + _completed: function( cancel ) { this.running = cancel ? 0 : --this.running; - if (this.running) return; + if ( this.running ) { + return; + } - if (o.clearStyle) { - this.toShow.add(this.toHide).css({ + if ( this.options.heightStyle === "content" ) { + this.toShow.add( this.toHide ).css({ height: "", overflow: "" }); } - + // other classes are removed before the animation; this one needs to stay until completed - this.toHide.removeClass("ui-accordion-content-active"); + this.toHide.removeClass( "ui-accordion-content-active" ); - this._trigger('change', null, this.data); + this._trigger( "change", null, this.data ); } - }); - -$.extend($.ui.accordion, { +$.extend( $.ui.accordion, { version: "@VERSION", animations: { - slide: function(options, additions) { + slide: function( options, additions ) { options = $.extend({ easing: "swing", duration: 300 - }, options, additions); + }, options, additions ); if ( !options.toHide.size() ) { - options.toShow.animate({height: "show"}, options); + options.toShow.animate({ + height: "show", + paddingTop: "show", + paddingBottom: "show" + }, options ); return; } if ( !options.toShow.size() ) { - options.toHide.animate({height: "hide"}, options); + options.toHide.animate({ + height: "hide", + paddingTop: "hide", + paddingBottom: "hide" + }, options ); return; } - var overflow = options.toShow.css('overflow'), + var overflow = options.toShow.css( "overflow" ), percentDone = 0, showProps = {}, hideProps = {}, @@ -457,45 +529,57 @@ $.extend($.ui.accordion, { // fix width before calculating height of hidden element var s = options.toShow; originalWidth = s[0].style.width; - s.width( parseInt(s.parent().width(),10) - parseInt(s.css("paddingLeft"),10) - parseInt(s.css("paddingRight"),10) - (parseInt(s.css("borderLeftWidth"),10) || 0) - (parseInt(s.css("borderRightWidth"),10) || 0) ); - - $.each(fxAttrs, function(i, prop) { - hideProps[prop] = 'hide'; - - var parts = ('' + $.css(options.toShow[0], prop)).match(/^([\d+-.]+)(.*)$/); - showProps[prop] = { - value: parts[1], - unit: parts[2] || 'px' + s.width( parseInt( s.parent().width(), 10 ) + - parseInt( s.css( "paddingLeft" ), 10 ) + - parseInt( s.css( "paddingRight" ), 10 ) + - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 ) + - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) ); + + $.each( fxAttrs, function( i, prop ) { + hideProps[ prop ] = "hide"; + + var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ ); + showProps[ prop ] = { + value: parts[ 1 ], + unit: parts[ 2 ] || "px" }; }); - options.toShow.css({ height: 0, overflow: 'hidden' }).show(); - options.toHide.filter(":hidden").each(options.complete).end().filter(":visible").animate(hideProps,{ - step: function(now, settings) { + options.toShow.css({ height: 0, overflow: "hidden" }).show(); + options.toHide + .filter( ":hidden" ) + .each( options.complete ) + .end() + .filter( ":visible" ) + .animate( hideProps, { + step: function( now, settings ) { // only calculate the percent when animating height // IE gets very inconsistent results when animating elements // with small values, which is common for padding - if (settings.prop == 'height') { + if ( settings.prop == "height" ) { percentDone = ( settings.end - settings.start === 0 ) ? 0 : - (settings.now - settings.start) / (settings.end - settings.start); + ( settings.now - settings.start ) / ( settings.end - settings.start ); } - - options.toShow[0].style[settings.prop] = - (percentDone * showProps[settings.prop].value) + showProps[settings.prop].unit; + + options.toShow[ 0 ].style[ settings.prop ] = + ( percentDone * showProps[ settings.prop ].value ) + + showProps[ settings.prop ].unit; }, duration: options.duration, easing: options.easing, complete: function() { if ( !options.autoHeight ) { - options.toShow.css("height", ""); + options.toShow.css( "height", "" ); } - options.toShow.css("width", originalWidth); - options.toShow.css({overflow: overflow}); + options.toShow.css({ + width: originalWidth, + overflow: overflow + }); options.complete(); } }); }, - bounceslide: function(options) { - this.slide(options, { + bounceslide: function( options ) { + this.slide( options, { easing: options.down ? "easeOutBounce" : "swing", duration: options.down ? 1000 : 200 }); @@ -503,4 +587,82 @@ $.extend($.ui.accordion, { } }); -})(jQuery); + + +// DEPRECATED + +// navigation options +(function( $, prototype ) { + $.extend( prototype.options, { + navigation: false, + navigationFilter: function() { + return this.href.toLowerCase() === location.href.toLowerCase(); + } + }); + + var _create = prototype._create; + prototype._create = function() { + if ( this.options.navigation ) { + var self = this, + headers = this.element.find( this.options.header ), + content = headers.next(); + current = headers.add( content ) + .find( "a" ) + .filter( this.options.navigationFilter ) + [ 0 ]; + if ( current ) { + headers.add( content ).each( function( index ) { + if ( $.contains( this, current ) ) { + self.options.active = Math.floor( index / 2 ); + return false; + } + }); + } + } + _create.call( this ); + }; +}( jQuery, jQuery.ui.accordion.prototype ) ); + +(function( $, prototype ) { + $.extend( prototype.options, { + autoHeight: true, // use heightStyle: "auto" + clearStyle: false, // use heightStyle: "content" + fillSpace: false // use heightStyle: "fill" + }); + + var _create = prototype._create, + _setOption = prototype._setOption; + + $.extend( prototype, { + _create: function() { + this.options.heightStyle = this.options.heightStyle || + this._mergeHeightStyle(); + _create.call( this ); + }, + + _setOption: function( key, value ) { + if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) { + this.options.heightStyle = this._mergeHeightStyle(); + } + _setOption.apply( this, arguments ); + }, + + _mergeHeightStyle: function() { + var options = this.options; + + if ( options.fillSpace ) { + return "fill"; + } + + if ( options.clearStyle ) { + return "content"; + } + + if ( options.autoHeight ) { + return "auto"; + } + } + }); +}( jQuery, jQuery.ui.accordion.prototype ) ); + +})( jQuery ); diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index bd55c1ed4..f48dc032a 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -1,9 +1,9 @@ /* * jQuery UI Autocomplete @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Autocomplete * @@ -13,16 +13,28 @@ * jquery.ui.position.js * jquery.ui.menu.js */ -(function( $ ) { +(function( $, undefined ) { $.widget( "ui.autocomplete", { options: { + appendTo: "body", + delay: 300, minLength: 1, - delay: 300 + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + source: null }, + + pending: 0, + _create: function() { var self = this, - doc = this.element[ 0 ].ownerDocument; + doc = this.element[ 0 ].ownerDocument, + suppressKeyPress; + this.element .addClass( "ui-autocomplete-input" ) .attr( "autocomplete", "off" ) @@ -33,6 +45,11 @@ $.widget( "ui.autocomplete", { "aria-haspopup": "true" }) .bind( "keydown.autocomplete", function( event ) { + if ( self.options.disabled || self.element.attr( "readonly" ) ) { + return; + } + + suppressKeyPress = false; var keyCode = $.ui.keyCode; switch( event.keyCode ) { case keyCode.PAGE_UP: @@ -52,8 +69,12 @@ $.widget( "ui.autocomplete", { event.preventDefault(); break; case keyCode.ENTER: - // when menu is open or has focus + case keyCode.NUMPAD_ENTER: + // when menu is open and has focus if ( self.menu.active ) { + // #6055 - Opera still allows the keypress to occur + // which causes forms to submit + suppressKeyPress = true; event.preventDefault(); } //passthrough - ENTER and TAB both select the current element @@ -67,30 +88,40 @@ $.widget( "ui.autocomplete", { self.element.val( self.term ); self.close( event ); break; - case keyCode.LEFT: - case keyCode.RIGHT: - case keyCode.SHIFT: - case keyCode.CONTROL: - case keyCode.ALT: - // ignore metakeys (shift, ctrl, alt) - break; default: // keypress is triggered before the input value is changed clearTimeout( self.searching ); self.searching = setTimeout(function() { - self.search( null, event ); + // only search if the value has changed + if ( self.term != self.element.val() ) { + self.selectedItem = null; + self.search( null, event ); + } }, self.options.delay ); break; } }) + .bind( "keypress.autocomplete", function( event ) { + if ( suppressKeyPress ) { + suppressKeyPress = false; + event.preventDefault(); + } + }) .bind( "focus.autocomplete", function() { + if ( self.options.disabled ) { + return; + } + self.selectedItem = null; self.previous = self.element.val(); }) .bind( "blur.autocomplete", function( event ) { + if ( self.options.disabled ) { + return; + } + clearTimeout( self.searching ); // clicks on the menu (or a button to trigger a search) will cause a blur event - // TODO try to implement this without a timeout, see clearTimeout in search() self.closing = setTimeout(function() { self.close( event ); self._change( event ); @@ -102,13 +133,37 @@ $.widget( "ui.autocomplete", { }; this.menu = $( "<ul></ul>" ) .addClass( "ui-autocomplete" ) - .appendTo( "body", doc ) + .appendTo( $( this.options.appendTo || "body", doc )[0] ) + // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown) + .mousedown(function( event ) { + // clicking on the scrollbar causes focus to shift to the body + // but we can't detect a mouseup or a click immediately afterward + // so we have to track the next mousedown and close the menu if + // the user clicks somewhere outside of the autocomplete + var menuElement = self.menu.element[ 0 ]; + if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { + setTimeout(function() { + $( document ).one( 'mousedown', function( event ) { + if ( event.target !== self.element[ 0 ] && + event.target !== menuElement && + !$.contains( menuElement, event.target ) ) { + self.close(); + } + }); + }, 1 ); + } + + // use another timeout to make sure the blur-event-handler on the input was already triggered + setTimeout(function() { + clearTimeout( self.closing ); + }, 13); + }) .menu({ // custom key handling for now input: $(), focus: function( event, ui ) { var item = ui.item.data( "item.autocomplete" ); - if ( false !== self._trigger( "focus", null, { item: item } ) ) { + if ( false !== self._trigger( "focus", event, { item: item } ) ) { // use value to match what will end up in the input, if it was a key event if ( /^key/.test(event.originalEvent.type) ) { self.element.val( item.value ); @@ -116,28 +171,42 @@ $.widget( "ui.autocomplete", { } }, select: function( event, ui ) { - var item = ui.item.data( "item.autocomplete" ); - if ( false !== self._trigger( "select", event, { item: item } ) ) { - self.element.val( item.value ); - } - self.close( event ); + var item = ui.item.data( "item.autocomplete" ), + previous = self.previous; + // only trigger when focus was lost (click on menu) - var previous = self.previous; if ( self.element[0] !== doc.activeElement ) { self.element.focus(); self.previous = previous; + // #6109 - IE triggers two focus events and the second + // is asynchronous, so we need to reset the previous + // term synchronously and asynchronously :-( + setTimeout(function() { + self.previous = previous; + self.selectedItem = item; + }, 1); } + + if ( false !== self._trigger( "select", event, { item: item } ) ) { + self.element.val( item.value ); + } + // reset the term after the select event + // this allows custom select handling to work properly + self.term = self.element.val(); + + self.close( event ); self.selectedItem = item; }, blur: function( event, ui ) { - if ( self.menu.element.is(":visible") ) { + // don't set the value of the text field if it's already correct + // this prevents moving the cursor unnecessarily + if ( self.menu.element.is(":visible") && + ( self.element.val() !== self.term ) ) { self.element.val( self.term ); } } }) .zIndex( this.element.zIndex() + 1 ) - // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 - .css({ top: 0, left: 0 }) .hide() .data( "menu" ); if ( $.fn.bgiframe ) { @@ -156,15 +225,22 @@ $.widget( "ui.autocomplete", { $.Widget.prototype.destroy.call( this ); }, - _setOption: function( key ) { + _setOption: function( key, value ) { $.Widget.prototype._setOption.apply( this, arguments ); if ( key === "source" ) { this._initSource(); } + if ( key === "appendTo" ) { + this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] ) + } + if ( key === "disabled" && value && this.xhr ) { + this.xhr.abort(); + } }, _initSource: function() { - var array, + var self = this, + array, url; if ( $.isArray(this.options.source) ) { array = this.options.source; @@ -174,7 +250,26 @@ $.widget( "ui.autocomplete", { } else if ( typeof this.options.source === "string" ) { url = this.options.source; this.source = function( request, response ) { - $.getJSON( url, request, response ); + if ( self.xhr ) { + self.xhr.abort(); + } + self.xhr = $.ajax({ + url: url, + data: request, + dataType: "json", + success: function( data, status, xhr ) { + if ( xhr === self.xhr ) { + response( data ); + } + self.xhr = null; + }, + error: function( xhr ) { + if ( xhr === self.xhr ) { + response( [] ); + } + self.xhr = null; + } + }); }; } else { this.source = this.options.source; @@ -183,12 +278,16 @@ $.widget( "ui.autocomplete", { search: function( value, event ) { value = value != null ? value : this.element.val(); + + // always save the actual value, not the one passed as an argument + this.term = this.element.val(); + if ( value.length < this.options.minLength ) { return this.close( event ); } clearTimeout( this.closing ); - if ( this._trigger("search") === false ) { + if ( this._trigger( "search", event ) === false ) { return; } @@ -196,31 +295,32 @@ $.widget( "ui.autocomplete", { }, _search: function( value ) { - this.term = this.element - .addClass( "ui-autocomplete-loading" ) - // always save the actual value, not the one passed as an argument - .val(); + this.pending++; + this.element.addClass( "ui-autocomplete-loading" ); this.source( { term: value }, this.response ); }, _response: function( content ) { - if ( content.length ) { + if ( !this.options.disabled && content && content.length ) { content = this._normalize( content ); this._suggest( content ); this._trigger( "open" ); } else { this.close(); } - this.element.removeClass( "ui-autocomplete-loading" ); + this.pending--; + if ( !this.pending ) { + this.element.removeClass( "ui-autocomplete-loading" ); + } }, close: function( event ) { clearTimeout( this.closing ); if ( this.menu.element.is(":visible") ) { - this._trigger( "close", event ); this.menu.element.hide(); this.menu.deactivate(); + this._trigger( "close", event ); } }, @@ -251,26 +351,29 @@ $.widget( "ui.autocomplete", { _suggest: function( items ) { var ul = this.menu.element - .empty() - .zIndex( this.element.zIndex() + 1 ), - menuWidth, - textWidth; + .empty() + .zIndex( this.element.zIndex() + 1 ); this._renderMenu( ul, items ); // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate this.menu.deactivate(); this.menu.refresh(); - this.menu.element.show().position({ - my: "left top", - at: "left bottom", - of: this.element, - collision: "none" - }); - menuWidth = ul.width( "" ).width(); - textWidth = this.element.width(); - ul.width( Math.max( menuWidth, textWidth ) ); + // size and position menu + ul.show(); + this._resizeMenu(); + ul.position( $.extend({ + of: this.element + }, this.options.position )); }, - + + _resizeMenu: function() { + var ul = this.menu.element; + ul.outerWidth( Math.max( + ul.width( "" ).outerWidth(), + this.element.outerWidth() + ) ); + }, + _renderMenu: function( ul, items ) { var self = this; $.each( items, function( index, item ) { @@ -281,7 +384,7 @@ $.widget( "ui.autocomplete", { _renderItem: function( ul, item) { return $( "<li></li>" ) .data( "item.autocomplete", item ) - .append( "<a>" + item.label + "</a>" ) + .append( $( "<a></a>" ).text( item.label ) ) .appendTo( ul ); }, @@ -306,7 +409,7 @@ $.widget( "ui.autocomplete", { $.extend( $.ui.autocomplete, { escapeRegex: function( value ) { - return value.replace( /([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1" ); + return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); }, filter: function(array, term) { var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js index ff2c1ebb6..78134e308 100644 --- a/ui/jquery.ui.button.js +++ b/ui/jquery.ui.button.js @@ -1,9 +1,9 @@ /* * jQuery UI Button @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Button * @@ -11,12 +11,12 @@ * jquery.ui.core.js * jquery.ui.widget.js */ -(function( $ ) { +(function( $, undefined ) { var lastActive, baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", - otherClasses = "ui-state-hover ui-state-active " + - "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon ui-button-text-only", + stateClasses = "ui-state-hover ui-state-active ", + typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", formResetHandler = function( event ) { $( ":ui-button", event.target.form ).each(function() { var inst = $( this ).data( "button" ); @@ -44,6 +44,7 @@ var lastActive, $.widget( "ui.button", { options: { + disabled: null, text: true, label: null, icons: { @@ -56,6 +57,10 @@ $.widget( "ui.button", { .unbind( "reset.button" ) .bind( "reset.button", formResetHandler ); + if ( typeof this.options.disabled !== "boolean" ) { + this.options.disabled = this.element.attr( "disabled" ); + } + this._determineButtonType(); this.hasTitle = !!this.buttonElement.attr( "title" ); @@ -196,7 +201,7 @@ $.widget( "ui.button", { // we don't search against the document in case the element // is disconnected from the DOM this.buttonElement = this.element.parents().last() - .find( "[for=" + this.element.attr("id") + "]" ); + .find( "label[for=" + this.element.attr("id") + "]" ); this.element.addClass( "ui-helper-hidden-accessible" ); var checked = this.element.is( ":checked" ); @@ -217,7 +222,7 @@ $.widget( "ui.button", { this.element .removeClass( "ui-helper-hidden-accessible" ); this.buttonElement - .removeClass( baseClasses + " " + otherClasses ) + .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) .removeAttr( "role" ) .removeAttr( "aria-pressed" ) .html( this.buttonElement.find(".ui-button-text").html() ); @@ -278,7 +283,7 @@ $.widget( "ui.button", { } return; } - var buttonElement = this.buttonElement, + var buttonElement = this.buttonElement.removeClass( typeClasses ), buttonText = $( "<span></span>" ) .addClass( "ui-button-text" ) .html( this.options.label ) @@ -288,7 +293,7 @@ $.widget( "ui.button", { multipleIcons = icons.primary && icons.secondary; if ( icons.primary || icons.secondary ) { buttonElement.addClass( "ui-button-text-icon" + - ( multipleIcons ? "s" : "" ) ); + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); if ( icons.primary ) { buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); } @@ -298,7 +303,7 @@ $.widget( "ui.button", { if ( !this.options.text ) { buttonElement .addClass( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ) - .removeClass( "ui-button-text-icons ui-button-text-icon" ); + .removeClass( "ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary" ); if ( !this.hasTitle ) { buttonElement.attr( "title", buttonText ); } @@ -310,9 +315,12 @@ $.widget( "ui.button", { }); $.widget( "ui.buttonset", { + options: { + items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)" + }, + _create: function() { this.element.addClass( "ui-buttonset" ); - this._init(); }, _init: function() { @@ -328,7 +336,7 @@ $.widget( "ui.buttonset", { }, refresh: function() { - this.buttons = this.element.find( ":button, :submit, :reset, :checkbox, :radio, a, :data(button)" ) + this.buttons = this.element.find( this.options.items ) .filter( ":ui-button" ) .button( "refresh" ) .end() @@ -356,7 +364,7 @@ $.widget( "ui.buttonset", { }) .removeClass( "ui-corner-left ui-corner-right" ) .end() - .button( "destroy" ) + .button( "destroy" ); $.Widget.prototype.destroy.call( this ); } diff --git a/ui/jquery.ui.core.js b/ui/jquery.ui.core.js index c0eab46b4..d41654b29 100644 --- a/ui/jquery.ui.core.js +++ b/ui/jquery.ui.core.js @@ -1,79 +1,33 @@ /*! * jQuery UI @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI */ -;jQuery.ui || (function($) { +(function( $, undefined ) { -//Helper functions and ui object -$.ui = { - version: "@VERSION", - - // $.ui.plugin is deprecated. Use the proxy pattern instead. - plugin: { - add: function(module, option, set) { - var proto = $.ui[module].prototype; - for(var i in set) { - proto.plugins[i] = proto.plugins[i] || []; - proto.plugins[i].push([option, set[i]]); - } - }, - call: function(instance, name, args) { - var set = instance.plugins[name]; - if(!set || !instance.element[0].parentNode) { return; } - - for (var i = 0; i < set.length; i++) { - if (instance.options[set[i][0]]) { - set[i][1].apply(instance.element, args); - } - } - } - }, - - contains: function(a, b) { - return document.compareDocumentPosition - ? a.compareDocumentPosition(b) & 16 - : a !== b && a.contains(b); - }, +// prevent duplicate loading +// this is only a problem because we proxy existing functions +// and we don't want to double proxy them +$.ui = $.ui || {}; +if ( $.ui.version ) { + return; +} - hasScroll: function(el, a) { - - //If overflow is hidden, the element might have extra content, but the user wants to hide it - if ($(el).css('overflow') == 'hidden') { return false; } - - var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop', - has = false; - - if (el[scroll] > 0) { return true; } - - // TODO: determine which cases actually cause this to happen - // if the element doesn't have the scroll set, see if it's possible to - // set the scroll - el[scroll] = 1; - has = (el[scroll] > 0); - el[scroll] = 0; - return has; - }, - - isOverAxis: function(x, reference, size) { - //Determines when x coordinate is over "b" element axis - return (x > reference) && (x < (reference + size)); - }, - - isOver: function(y, x, top, left, height, width) { - //Determines when x, y coordinates is over "b" element - return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width); - }, +$.extend( $.ui, { + version: "@VERSION", keyCode: { ALT: 18, BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, + COMMAND: 91, + COMMAND_LEFT: 91, // COMMAND + COMMAND_RIGHT: 93, CONTROL: 17, DELETE: 46, DOWN: 40, @@ -83,6 +37,7 @@ $.ui = { HOME: 36, INSERT: 45, LEFT: 37, + MENU: 93, // COMMAND_RIGHT NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, @@ -96,40 +51,31 @@ $.ui = { SHIFT: 16, SPACE: 32, TAB: 9, - UP: 38 + UP: 38, + WINDOWS: 91 // COMMAND } -}; +}); -//jQuery plugins +// plugins $.fn.extend({ _focus: $.fn.focus, - focus: function(delay, fn) { - return typeof delay === 'number' - ? this.each(function() { + focus: function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { var elem = this; setTimeout(function() { - $(elem).focus(); - (fn && fn.call(elem)); - }, delay); - }) - : this._focus.apply(this, arguments); - }, - - enableSelection: function() { - return this - .attr('unselectable', 'off') - .css('MozUserSelect', ''); - }, - - disableSelection: function() { - return this - .attr('unselectable', 'on') - .css('MozUserSelect', 'none'); + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + this._focus.apply( this, arguments ); }, scrollParent: function() { var scrollParent; - if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { + if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { scrollParent = this.parents().filter(function() { return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); }).eq(0); @@ -142,26 +88,25 @@ $.fn.extend({ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; }, - zIndex: function(zIndex) { - if (zIndex !== undefined) { - return this.css('zIndex', zIndex); + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); } - - if (this.length) { - var elem = $(this[0]), position, value; - while (elem.length && elem[0] !== document) { + + if ( this.length ) { + var elem = $( this[ 0 ] ), position, value; + while ( elem.length && elem[ 0 ] !== document ) { // Ignore z-index if position is set to a value where z-index is ignored by the browser // This makes behavior of this function consistent across browsers // WebKit always returns auto if the element is positioned - position = elem.css('position'); - if (position == 'absolute' || position == 'relative' || position == 'fixed') - { + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { // IE returns 0 when zIndex is not specified // other browsers return a string // we ignore the case of nested elements with an explicit value of 0 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> - value = parseInt(elem.css('zIndex')); - if (!isNaN(value) && value != 0) { + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { return value; } } @@ -170,33 +115,189 @@ $.fn.extend({ } return 0; + }, + + disableSelection: function() { + return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }, + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); } }); +$.each( [ "Width", "Height" ], function( i, name ) { + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + type = name.toLowerCase(), + orig = { + innerWidth: $.fn.innerWidth, + innerHeight: $.fn.innerHeight, + outerWidth: $.fn.outerWidth, + outerHeight: $.fn.outerHeight + }; + + function reduce( elem, size, border, margin ) { + $.each( side, function() { + size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0; + if ( border ) { + size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0; + } + }); + return size; + } -//Additional selectors -$.extend($.expr[':'], { - data: function(elem, i, match) { - return !!$.data(elem, match[3]); + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); + } + + return this.each(function() { + $( this ).css( type, reduce( this, size ) + "px" ); + }); + }; + + $.fn[ "outer" + name] = function( size, margin ) { + if ( typeof size !== "number" ) { + return orig[ "outer" + name ].call( this, size ); + } + + return this.each(function() { + $( this).css( type, reduce( this, size, true, margin ) + "px" ); + }); + }; +}); + +// selectors +function visible( element ) { + return !$( element ).parents().andSelf().filter(function() { + return $.curCSS( this, "visibility" ) === "hidden" || + $.expr.filters.hidden( this ); + }).length; +} + +$.extend( $.expr[ ":" ], { + data: function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); }, - focusable: function(element) { + focusable: function( element ) { var nodeName = element.nodeName.toLowerCase(), - tabIndex = $.attr(element, 'tabindex'); - return (/input|select|textarea|button|object/.test(nodeName) + tabIndex = $.attr( element, "tabindex" ); + if ( "area" === nodeName ) { + var map = element.parentNode, + mapName = map.name, + img; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap=#" + mapName + "]" )[0]; + return !!img && visible( img ); + } + return ( /input|select|textarea|button|object/.test( nodeName ) ? !element.disabled - : 'a' == nodeName || 'area' == nodeName - ? element.href || !isNaN(tabIndex) - : !isNaN(tabIndex)) + : "a" == nodeName + ? element.href || !isNaN( tabIndex ) + : !isNaN( tabIndex )) // the element and all of its ancestors must be visible - // the browser may report that the area is hidden - && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length; + && visible( element ); }, - tabbable: function(element) { - var tabIndex = $.attr(element, 'tabindex'); - return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable'); + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ); + return ( isNaN( tabIndex ) || tabIndex >= 0 ) && $( element ).is( ":focusable" ); + } +}); + +// support +$(function() { + var body = document.body, + div = body.appendChild( div = document.createElement( "div" ) ); + + $.extend( div.style, { + minHeight: "100px", + height: "auto", + padding: 0, + borderWidth: 0 + }); + + $.support.minHeight = div.offsetHeight === 100; + $.support.selectstart = "onselectstart" in div; + + // set display to none to avoid a layout bug in IE + // http://dev.jquery.com/ticket/4014 + body.removeChild( div ).style.display = "none"; +}); + + + + + +// deprecated +$.extend( $.ui, { + // $.ui.plugin is deprecated. Use the proxy pattern instead. + plugin: { + add: function( module, option, set ) { + var proto = $.ui[ module ].prototype; + for ( var i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args ) { + var set = instance.plugins[ name ]; + if ( !set || !instance.element[ 0 ].parentNode ) { + return; + } + + for ( var i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } + }, + + contains: $.contains, + + // only used by resizable + hasScroll: function( el, a ) { + + //If overflow is hidden, the element might have extra content, but the user wants to hide it + if ( $( el ).css( "overflow" ) === "hidden") { + return false; + } + + var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", + has = false; + + if ( el[ scroll ] > 0 ) { + return true; + } + + // TODO: determine which cases actually cause this to happen + // if the element doesn't have the scroll set, see if it's possible to + // set the scroll + el[ scroll ] = 1; + has = ( el[ scroll ] > 0 ); + el[ scroll ] = 0; + return has; + }, + + // these are odd functions, fix the API or move into individual plugins + isOverAxis: function( x, reference, size ) { + //Determines when x coordinate is over "b" element axis + return ( x > reference ) && ( x < ( reference + size ) ); + }, + isOver: function( y, x, top, left, height, width ) { + //Determines when x, y coordinates is over "b" element + return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width ); } }); -})(jQuery); +})( jQuery ); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index e41ae62a3..abcb37067 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -1,17 +1,16 @@ /* * jQuery UI Datepicker @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Datepicker * * Depends: * jquery.ui.core.js */ - -(function($) { // hide the namespace +(function( $, undefined ) { $.extend($.ui, { datepicker: { version: "@VERSION" } }); @@ -61,7 +60,7 @@ function Datepicker() { this._defaults = { // Global defaults for all the date picker instances showOn: 'focus', // 'focus' for popup on focus, // 'button' for trigger button, or 'both' for either - showAnim: 'show', // Name of jQuery animation for popup + showAnim: 'fadeIn', // Name of jQuery animation for popup showOptions: {}, // Options for enhanced animations defaultDate: null, // Used when field is blank: actual date, // +/-number for offset from today, null for today @@ -88,7 +87,7 @@ function Datepicker() { // string value starting with '+' for current year + value minDate: null, // The earliest selectable date, or null for no limit maxDate: null, // The latest selectable date, or null for no limit - duration: '_default', // Duration of display/closure + duration: 'fast', // Duration of display/closure beforeShowDay: null, // Function that takes a date and returns an array with // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', // [2] = cell title (optional), e.g. $.datepicker.noWeekends @@ -108,7 +107,7 @@ function Datepicker() { autoSize: false // True to size the input for the date format, false to leave as is }; $.extend(this._defaults, this.regional['']); - this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>'); + this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'); } $.extend(Datepicker.prototype, { @@ -153,8 +152,10 @@ $.extend(Datepicker.prototype, { } var nodeName = target.nodeName.toLowerCase(); var inline = (nodeName == 'div' || nodeName == 'span'); - if (!target.id) - target.id = 'dp' + (++this.uuid); + if (!target.id) { + this.uuid += 1; + target.id = 'dp' + this.uuid; + } var inst = this._newInst($(target), inline); inst.settings = $.extend({}, settings || {}, inlineSettings || {}); if (nodeName == 'input') { @@ -166,7 +167,7 @@ $.extend(Datepicker.prototype, { /* Create a new instance object. */ _newInst: function(target, inline) { - var id = target[0].id.replace(/([^A-Za-z0-9_])/g, '\\\\$1'); // escape jQuery meta chars + var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars return {id: id, input: target, // associated target selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection drawMonth: 0, drawYear: 0, // month being drawn @@ -271,6 +272,7 @@ $.extend(Datepicker.prototype, { this._setDate(inst, this._getDefaultDate(inst), true); this._updateDatepicker(inst); this._updateAlternate(inst); + inst.dpDiv.show(); }, /* Pop-up the date picker in a "dialog" box. @@ -285,7 +287,8 @@ $.extend(Datepicker.prototype, { _dialogDatepicker: function(input, date, onSelect, settings, pos) { var inst = this._dialogInst; // internal instance if (!inst) { - var id = 'dp' + (++this.uuid); + this.uuid += 1; + var id = 'dp' + this.uuid; this._dialogInput = $('<input type="text" id="' + id + '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'); this._dialogInput.keydown(this._doKeyDown); @@ -497,8 +500,8 @@ $.extend(Datepicker.prototype, { case 9: $.datepicker._hideDatepicker(); handled = false; break; // hide on tab out - case 13: var sel = $('td.' + $.datepicker._dayOverClass, inst.dpDiv). - add($('td.' + $.datepicker._currentClass, inst.dpDiv)); + case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + + $.datepicker._currentClass + ')', inst.dpDiv); if (sel[0]) $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); else @@ -562,7 +565,7 @@ $.extend(Datepicker.prototype, { if ($.datepicker._get(inst, 'constrainInput')) { var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); - return event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); + return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); } }, @@ -622,6 +625,8 @@ $.extend(Datepicker.prototype, { } var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; $.datepicker._pos = null; + //to avoid flashes on Firefox + inst.dpDiv.empty(); // determine sizing offscreen inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); $.datepicker._updateDatepicker(inst); @@ -636,10 +641,12 @@ $.extend(Datepicker.prototype, { var duration = $.datepicker._get(inst, 'duration'); var postProcess = function() { $.datepicker._datepickerShowing = true; - var borders = $.datepicker._getBorders(inst.dpDiv); - inst.dpDiv.find('iframe.ui-datepicker-cover'). // IE6- only - css({left: -borders[0], top: -borders[1], + var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only + if( !! cover.length ){ + var borders = $.datepicker._getBorders(inst.dpDiv); + cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}); + } }; inst.dpDiv.zIndex($(input).zIndex()+1); if ($.effects && $.effects[showAnim]) @@ -658,12 +665,12 @@ $.extend(Datepicker.prototype, { _updateDatepicker: function(inst) { var self = this; var borders = $.datepicker._getBorders(inst.dpDiv); - inst.dpDiv.empty().append(this._generateHTML(inst)) - .find('iframe.ui-datepicker-cover') // IE6- only - .css({left: -borders[0], top: -borders[1], - width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) - .end() - .find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a') + inst.dpDiv.empty().append(this._generateHTML(inst)); + var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only + if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6 + cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) + } + inst.dpDiv.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a') .bind('mouseout', function(){ $(this).removeClass('ui-state-hover'); if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); @@ -695,6 +702,17 @@ $.extend(Datepicker.prototype, { if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && inst.input.is(':visible') && !inst.input.is(':disabled')) inst.input.focus(); + // deffered render of the years select (to avoid flashes on Firefox) + if( inst.yearshtml ){ + var origyearshtml = inst.yearshtml; + setTimeout(function(){ + //assure that inst.yearshtml didn't change. + if( origyearshtml === inst.yearshtml ){ + inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); + } + origyearshtml = inst.yearshtml = null; + }, 0); + } }, /* Retrieve the size of left and top borders for an element. @@ -844,8 +862,11 @@ $.extend(Datepicker.prototype, { _clickMonthYear: function(id) { var target = $(id); var inst = this._getInst(target[0]); - if (inst.input && inst._selectingMonthYear && !$.browser.msie) - inst.input.focus(); + if (inst.input && inst._selectingMonthYear) { + setTimeout(function() { + inst.input.focus(); + }, 0); + } inst._selectingMonthYear = !inst._selectingMonthYear; }, @@ -963,9 +984,9 @@ $.extend(Datepicker.prototype, { }; // Extract a number from the string value var getNumber = function(match) { - lookAhead(match); + var isDoubled = lookAhead(match); var size = (match == '@' ? 14 : (match == '!' ? 20 : - (match == 'y' ? 4 : (match == 'o' ? 3 : 2)))); + (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2)))); var digits = new RegExp('^\\d{1,' + size + '}'); var num = value.substring(iValue).match(digits); if (!num) @@ -977,7 +998,7 @@ $.extend(Datepicker.prototype, { var getName = function(match, shortNames, longNames) { var names = (lookAhead(match) ? longNames : shortNames); for (var i = 0; i < names.length; i++) { - if (value.substr(iValue, names[i].length) == names[i]) { + if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) { iValue += names[i].length; return i + 1; } @@ -1295,16 +1316,16 @@ $.extend(Datepicker.prototype, { } return new Date(year, month, day); }; - date = (date == null ? defaultDate : (typeof date == 'string' ? offsetString(date) : - (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date))); - date = (date && date.toString() == 'Invalid Date' ? defaultDate : date); - if (date) { - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - date.setMilliseconds(0); + var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) : + (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); + newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate); + if (newDate) { + newDate.setHours(0); + newDate.setMinutes(0); + newDate.setSeconds(0); + newDate.setMilliseconds(0); } - return this._daylightSavingAdjust(date); + return this._daylightSavingAdjust(newDate); }, /* Handle switch to/from daylight saving. @@ -1321,13 +1342,13 @@ $.extend(Datepicker.prototype, { /* Set the date(s) directly. */ _setDate: function(inst, date, noChange) { - var clear = !(date); + var clear = !date; var origMonth = inst.selectedMonth; var origYear = inst.selectedYear; - date = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); - inst.selectedDay = inst.currentDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear(); + var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); + inst.selectedDay = inst.currentDay = newDate.getDate(); + inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); + inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) this._notifyChange(inst); this._adjustInstDate(inst); @@ -1543,6 +1564,7 @@ $.extend(Datepicker.prototype, { if (!showMonthAfterYear) html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); // year selection + inst.yearshtml = ''; if (secondary || !changeYear) html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; else { @@ -1559,16 +1581,24 @@ $.extend(Datepicker.prototype, { var endYear = Math.max(year, determineYear(years[1] || '')); year = (minDate ? Math.max(year, minDate.getFullYear()) : year); endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); - html += '<select class="ui-datepicker-year" ' + + inst.yearshtml += '<select class="ui-datepicker-year" ' + 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' + 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + '>'; for (; year <= endYear; year++) { - html += '<option value="' + year + '"' + + inst.yearshtml += '<option value="' + year + '"' + (year == drawYear ? ' selected="selected"' : '') + '>' + year + '</option>'; } - html += '</select>'; + inst.yearshtml += '</select>'; + //when showing there is no need for later update + if( ! $.browser.mozilla ){ + html += inst.yearshtml; + inst.yearshtml = null; + } else { + // will be replaced later with inst.yearshtml + html += '<select class="ui-datepicker-year"><option value="' + drawYear + '" selected="selected">' + drawYear + '</option></select>'; + } } html += this._get(inst, 'yearSuffix'); if (showMonthAfterYear) @@ -1596,9 +1626,9 @@ $.extend(Datepicker.prototype, { _restrictMinMax: function(inst, date) { var minDate = this._getMinMaxDate(inst, 'min'); var maxDate = this._getMinMaxDate(inst, 'max'); - date = (minDate && date < minDate ? minDate : date); - date = (maxDate && date > maxDate ? maxDate : date); - return date; + var newDate = (minDate && date < minDate ? minDate : date); + newDate = (maxDate && newDate > maxDate ? maxDate : newDate); + return newDate; }, /* Notify change of month/year. */ diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index 6e538b6e5..501772eb5 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -1,9 +1,9 @@ /* * jQuery UI Dialog @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Dialog * @@ -16,151 +16,163 @@ * jquery.ui.position.js * jquery.ui.resizable.js */ -(function($) { - -var uiDialogClasses = - 'ui-dialog ' + - 'ui-widget ' + - 'ui-widget-content ' + - 'ui-corner-all '; +(function( $, undefined ) { + +var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ", + sizeRelatedOptions = { + buttons: true, + height: true, + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true, + width: true + }, + resizableRelatedOptions = { + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true + }; $.widget("ui.dialog", { options: { autoOpen: true, buttons: {}, closeOnEscape: true, - closeText: 'close', - dialogClass: '', + closeText: "close", + dialogClass: "", draggable: true, hide: null, - height: 'auto', + height: "auto", maxHeight: false, maxWidth: false, minHeight: 150, minWidth: 150, modal: false, - position: 'center', + position: { + my: "center", + at: "center", + of: window, + collision: "fit", + // ensure that the titlebar is never outside the document + using: function( pos ) { + var topOffset = $( this ).css( pos ).offset().top; + if ( topOffset < 0 ) { + $( this ).css( "top", pos.top - topOffset ); + } + } + }, resizable: true, show: null, stack: true, - title: '', + title: "", width: 300, zIndex: 1000 }, + _create: function() { - this.originalTitle = this.element.attr('title'); + this.originalTitle = this.element.attr( "title" ); + // #5742 - .attr() might return a DOMElement + if ( typeof this.originalTitle !== "string" ) { + this.originalTitle = ""; + } + this.options.title = this.options.title || this.originalTitle; var self = this, options = self.options, - title = options.title || self.originalTitle || ' ', - titleId = $.ui.dialog.getTitleId(self.element), + title = options.title || " ", + titleId = $.ui.dialog.getTitleId( self.element ), - uiDialog = (self.uiDialog = $('<div></div>')) - .appendTo(document.body) + uiDialog = ( self.uiDialog = $( "<div>" ) ) + .appendTo( document.body ) .hide() - .addClass(uiDialogClasses + options.dialogClass) + .addClass( uiDialogClasses + options.dialogClass ) .css({ zIndex: options.zIndex }) // setting tabIndex makes the div focusable - // setting outline to 0 prevents a border on focus in Mozilla - .attr('tabIndex', -1).css('outline', 0).keydown(function(event) { - if (options.closeOnEscape && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE) { - - self.close(event); + .attr( "tabIndex", -1) + // TODO: move to stylesheet + .css( "outline", 0 ) + .keydown(function( event ) { + if ( options.closeOnEscape && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE ) { + self.close( event ); event.preventDefault(); } }) .attr({ - role: 'dialog', - 'aria-labelledby': titleId + role: "dialog", + "aria-labelledby": titleId }) - .mousedown(function(event) { - self.moveToTop(false, event); + .mousedown(function( event ) { + self.moveToTop( false, event ); }), uiDialogContent = self.element .show() - .removeAttr('title') - .addClass( - 'ui-dialog-content ' + - 'ui-widget-content') - .appendTo(uiDialog), - - uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>')) - .addClass( - 'ui-dialog-titlebar ' + - 'ui-widget-header ' + - 'ui-corner-all ' + - 'ui-helper-clearfix' - ) - .prependTo(uiDialog), - - uiDialogTitlebarClose = $('<a href="#"></a>') - .addClass( - 'ui-dialog-titlebar-close ' + - 'ui-corner-all' - ) - .attr('role', 'button') + .removeAttr( "title" ) + .addClass( "ui-dialog-content ui-widget-content" ) + .appendTo( uiDialog ), + + uiDialogTitlebar = ( self.uiDialogTitlebar = $( "<div>" ) ) + .addClass( "ui-dialog-titlebar ui-widget-header " + + "ui-corner-all ui-helper-clearfix" ) + .prependTo( uiDialog ), + + uiDialogTitlebarClose = $( "<a href='#'>" ) + .addClass( "ui-dialog-titlebar-close ui-corner-all" ) + .attr( "role", "button" ) .hover( function() { - uiDialogTitlebarClose.addClass('ui-state-hover'); + uiDialogTitlebarClose.addClass( "ui-state-hover" ); }, function() { - uiDialogTitlebarClose.removeClass('ui-state-hover'); + uiDialogTitlebarClose.removeClass( "ui-state-hover" ); } ) .focus(function() { - uiDialogTitlebarClose.addClass('ui-state-focus'); + uiDialogTitlebarClose.addClass( "ui-state-focus" ); }) .blur(function() { - uiDialogTitlebarClose.removeClass('ui-state-focus'); + uiDialogTitlebarClose.removeClass( "ui-state-focus" ); }) - .click(function(event) { - self.close(event); - return false; + .click(function( event ) { + event.preventDefault(); + self.close( event ); }) - .appendTo(uiDialogTitlebar), + .appendTo( uiDialogTitlebar ), - uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>')) - .addClass( - 'ui-icon ' + - 'ui-icon-closethick' - ) - .text(options.closeText) - .appendTo(uiDialogTitlebarClose), - - uiDialogTitle = $('<span></span>') - .addClass('ui-dialog-title') - .attr('id', titleId) - .html(title) - .prependTo(uiDialogTitlebar); + uiDialogTitlebarCloseText = ( self.uiDialogTitlebarCloseText = $( "<span>" ) ) + .addClass( "ui-icon ui-icon-closethick" ) + .text( options.closeText ) + .appendTo( uiDialogTitlebarClose ), - //handling of deprecated beforeclose (vs beforeClose) option - //Ticket #4669 http://dev.jqueryui.com/ticket/4669 - //TODO: remove in 1.9pre - if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) { - options.beforeClose = options.beforeclose; - } + uiDialogTitle = $( "<span>" ) + .addClass( "ui-dialog-title" ) + .attr( "id", titleId ) + .html( title ) + .prependTo( uiDialogTitlebar ); - uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); + uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); - if (options.draggable && $.fn.draggable) { + if ( options.draggable && $.fn.draggable ) { self._makeDraggable(); } - if (options.resizable && $.fn.resizable) { + if ( options.resizable && $.fn.resizable ) { self._makeResizable(); } - self._createButtons(options.buttons); + self._createButtons( options.buttons ); self._isOpen = false; - if ($.fn.bgiframe) { + if ( $.fn.bgiframe ) { uiDialog.bgiframe(); } }, + _init: function() { if ( this.options.autoOpen ) { this.open(); @@ -170,60 +182,63 @@ $.widget("ui.dialog", { destroy: function() { var self = this; - if (self.overlay) { + if ( self.overlay ) { self.overlay.destroy(); } self.uiDialog.hide(); self.element - .unbind('.dialog') - .removeData('dialog') - .removeClass('ui-dialog-content ui-widget-content') - .hide().appendTo('body'); + .removeClass( "ui-dialog-content ui-widget-content" ) + .hide() + .appendTo( "body" ); self.uiDialog.remove(); - if (self.originalTitle) { - self.element.attr('title', self.originalTitle); + if ( self.originalTitle ) { + self.element.attr( "title", self.originalTitle ); } + $.Widget.prototype.destroy.call( this ); return self; }, - + widget: function() { return this.uiDialog; }, - close: function(event) { + close: function( event ) { var self = this, - maxZ; + maxZ, thisZ; - if (false === self._trigger('beforeClose', event)) { + if ( false === self._trigger( "beforeClose", event ) ) { return; } - if (self.overlay) { + if ( self.overlay ) { self.overlay.destroy(); } - self.uiDialog.unbind('keypress.ui-dialog'); + self.uiDialog.unbind( "keypress.ui-dialog" ); self._isOpen = false; - if (self.options.hide) { - self.uiDialog.hide(self.options.hide, function() { - self._trigger('close', event); + if ( self.options.hide ) { + self.uiDialog.hide( self.options.hide, function() { + self._trigger( "close", event ); }); } else { self.uiDialog.hide(); - self._trigger('close', event); + self._trigger( "close", event ); } $.ui.dialog.overlay.resize(); // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) - if (self.options.modal) { + if ( self.options.modal ) { maxZ = 0; - $('.ui-dialog').each(function() { - if (this !== self.uiDialog[0]) { - maxZ = Math.max(maxZ, $(this).css('z-index')); + $( ".ui-dialog" ).each(function() { + if ( this !== self.uiDialog[0] ) { + thisZ = $( this ).css( "z-index" ); + if ( !isNaN( thisZ ) ) { + maxZ = Math.max( maxZ, thisZ ); + } } }); $.ui.dialog.maxZ = maxZ; @@ -238,67 +253,71 @@ $.widget("ui.dialog", { // the force parameter allows us to move modal dialogs to their correct // position on open - moveToTop: function(force, event) { + moveToTop: function( force, event ) { var self = this, options = self.options, saveScroll; - - if ((options.modal && !force) || - (!options.stack && !options.modal)) { - return self._trigger('focus', event); + + if ( ( options.modal && !force ) || + ( !options.stack && !options.modal ) ) { + return self._trigger( "focus", event ); } - - if (options.zIndex > $.ui.dialog.maxZ) { + + if ( options.zIndex > $.ui.dialog.maxZ ) { $.ui.dialog.maxZ = options.zIndex; } - if (self.overlay) { + if ( self.overlay ) { $.ui.dialog.maxZ += 1; - self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ); + $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ; + self.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); } - //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed. - // http://ui.jquery.com/bugs/ticket/3193 - saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') }; + // Save and then restore scroll + // Opera 9.5+ resets when parent z-index is changed. + // http://bugs.jqueryui.com/ticket/3193 + saveScroll = { + scrollTop: self.element.attr( "scrollTop" ), + scrollLeft: self.element.attr( "scrollLeft" ) + }; $.ui.dialog.maxZ += 1; - self.uiDialog.css('z-index', $.ui.dialog.maxZ); - self.element.attr(saveScroll); - self._trigger('focus', event); + self.uiDialog.css( "z-index", $.ui.dialog.maxZ ); + self.element.attr( saveScroll ); + self._trigger( "focus", event ); return self; }, open: function() { - if (this._isOpen) { return; } + if ( this._isOpen ) { + return; + } var self = this, options = self.options, uiDialog = self.uiDialog; - self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null; - if (uiDialog.next().length) { - uiDialog.appendTo('body'); - } + self.overlay = options.modal ? new $.ui.dialog.overlay( self ) : null; self._size(); - self._position(options.position); - uiDialog.show(options.show); - self.moveToTop(true); + self._position( options.position ); + uiDialog.show( options.show ); + self.moveToTop( true ); // prevent tabbing out of modal dialogs - if (options.modal) { - uiDialog.bind('keypress.ui-dialog', function(event) { - if (event.keyCode !== $.ui.keyCode.TAB) { + if ( options.modal ) { + uiDialog.bind( "keypress.ui-dialog", function( event ) { + if ( event.keyCode !== $.ui.keyCode.TAB ) { return; } - - var tabbables = $(':tabbable', this), - first = tabbables.filter(':first'), - last = tabbables.filter(':last'); - - if (event.target === last[0] && !event.shiftKey) { - first.focus(1); + + var tabbables = $( ":tabbable", this ), + first = tabbables.filter( ":first" ), + last = tabbables.filter( ":last" ); + + if ( event.target === last[0] && !event.shiftKey ) { + first.focus( 1 ); return false; - } else if (event.target === first[0] && event.shiftKey) { - last.focus(1); + } else if ( event.target === first[0] && event.shiftKey ) { + last.focus( 1 ); return false; } }); @@ -306,58 +325,60 @@ $.widget("ui.dialog", { // set focus to the first tabbable element in the content area or the first button // if there are no tabbable elements, set focus on the dialog itself - $([]) - .add(uiDialog.find('.ui-dialog-content :tabbable:first')) - .add(uiDialog.find('.ui-dialog-buttonpane :tabbable:first')) - .add(uiDialog) - .filter(':first') - .focus(); - - self._trigger('open'); + $( self.element.find( ":tabbable" ).get().concat( + uiDialog.find( ".ui-dialog-buttonpane :tabbable" ).get().concat( + uiDialog.get() ) ) ).eq( 0 ).focus(); + self._isOpen = true; + self._trigger( "open" ); return self; }, - _createButtons: function(buttons) { + _createButtons: function( buttons ) { var self = this, hasButtons = false, - uiDialogButtonPane = $('<div></div>') - .addClass( - 'ui-dialog-buttonpane ' + - 'ui-widget-content ' + - 'ui-helper-clearfix' - ); + uiDialogButtonPane = $( "<div>" ) + .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ), + uiButtonSet = $( "<div>" ) + .addClass( "ui-dialog-buttonset" ) + .appendTo( uiDialogButtonPane ); // if we already have a button pane, remove it - self.uiDialog.find('.ui-dialog-buttonpane').remove(); + self.uiDialog.find( ".ui-dialog-buttonpane" ).remove(); - if (typeof buttons === 'object' && buttons !== null) { - $.each(buttons, function() { + if ( typeof buttons === "object" && buttons !== null ) { + $.each( buttons, function() { return !(hasButtons = true); }); } - if (hasButtons) { - $.each(buttons, function(name, fn) { - var button = $('<button type="button"></button>') - .text(name) - .click(function() { fn.apply(self.element[0], arguments); }) - .appendTo(uiDialogButtonPane); - if ($.fn.button) { + if ( hasButtons ) { + $.each( buttons, function( name, props ) { + props = $.isFunction( props ) ? + { click: props, text: name } : + props; + var button = $( "<button type='button'>" ) + .attr( props, true ) + .unbind( "click" ) + .click(function() { + props.click.apply( self.element[0], arguments ); + }) + .appendTo( uiButtonSet ); + if ( $.fn.button ) { button.button(); } }); - uiDialogButtonPane.appendTo(self.uiDialog); + uiDialogButtonPane.appendTo( self.uiDialog ); } }, _makeDraggable: function() { var self = this, options = self.options, - doc = $(document), + doc = $( document ), heightBeforeDrag; - function filteredUi(ui) { + function filteredUi( ui ) { return { position: ui.position, offset: ui.offset @@ -365,40 +386,45 @@ $.widget("ui.dialog", { } self.uiDialog.draggable({ - cancel: '.ui-dialog-content, .ui-dialog-titlebar-close', - handle: '.ui-dialog-titlebar', - containment: 'document', - start: function(event, ui) { - heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height(); - $(this).height($(this).height()).addClass("ui-dialog-dragging"); - self._trigger('dragStart', event, filteredUi(ui)); + cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", + handle: ".ui-dialog-titlebar", + containment: "document", + start: function( event, ui ) { + heightBeforeDrag = options.height === "auto" ? "auto" : $( this ).height(); + $( this ) + .height( $( this ).height() ) + .addClass( "ui-dialog-dragging" ); + self._trigger( "dragStart", event, filteredUi( ui ) ); }, - drag: function(event, ui) { - self._trigger('drag', event, filteredUi(ui)); + drag: function( event, ui ) { + self._trigger( "drag", event, filteredUi( ui ) ); }, - stop: function(event, ui) { - options.position = [ui.position.left - doc.scrollLeft(), - ui.position.top - doc.scrollTop()]; - $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag); - self._trigger('dragStop', event, filteredUi(ui)); + stop: function( event, ui ) { + options.position = [ + ui.position.left - doc.scrollLeft(), + ui.position.top - doc.scrollTop() + ]; + $( this ) + .removeClass( "ui-dialog-dragging" ) + .height( heightBeforeDrag ); + self._trigger( "dragStop", event, filteredUi( ui ) ); $.ui.dialog.overlay.resize(); } }); }, - _makeResizable: function(handles) { + _makeResizable: function( handles ) { handles = (handles === undefined ? this.options.resizable : handles); var self = this, options = self.options, // .ui-resizable has position: relative defined in the stylesheet // but dialogs have to use absolute or fixed positioning - position = self.uiDialog.css('position'), - resizeHandles = (typeof handles === 'string' ? + position = self.uiDialog.css( "position" ), + resizeHandles = typeof handles === 'string' ? handles : - 'n,e,s,w,se,sw,ne,nw' - ); + "n,e,s,w,se,sw,ne,nw"; - function filteredUi(ui) { + function filteredUi( ui ) { return { originalPosition: ui.originalPosition, originalSize: ui.originalSize, @@ -408,209 +434,176 @@ $.widget("ui.dialog", { } self.uiDialog.resizable({ - cancel: '.ui-dialog-content', - containment: 'document', + cancel: ".ui-dialog-content", + containment: "document", alsoResize: self.element, maxWidth: options.maxWidth, maxHeight: options.maxHeight, minWidth: options.minWidth, minHeight: self._minHeight(), handles: resizeHandles, - start: function(event, ui) { - $(this).addClass("ui-dialog-resizing"); - self._trigger('resizeStart', event, filteredUi(ui)); + start: function( event, ui ) { + $( this ).addClass( "ui-dialog-resizing" ); + self._trigger( "resizeStart", event, filteredUi( ui ) ); }, - resize: function(event, ui) { - self._trigger('resize', event, filteredUi(ui)); + resize: function( event, ui ) { + self._trigger( "resize", event, filteredUi( ui ) ); }, - stop: function(event, ui) { - $(this).removeClass("ui-dialog-resizing"); - options.height = $(this).height(); - options.width = $(this).width(); - self._trigger('resizeStop', event, filteredUi(ui)); + stop: function( event, ui ) { + $( this ).removeClass( "ui-dialog-resizing" ); + options.height = $( this ).height(); + options.width = $( this ).width(); + self._trigger( "resizeStop", event, filteredUi( ui ) ); $.ui.dialog.overlay.resize(); } }) - .css('position', position) - .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se'); + .css( "position", position ) + .find( ".ui-resizable-se" ) + .addClass( "ui-icon ui-icon-grip-diagonal-se" ); }, _minHeight: function() { var options = this.options; - if (options.height === 'auto') { + if ( options.height === "auto" ) { return options.minHeight; } else { - return Math.min(options.minHeight, options.height); + return Math.min( options.minHeight, options.height ); } }, - _position: function(position) { + _position: function( position ) { var myAt = [], - offset = [0, 0], + offset = [ 0, 0 ], isVisible; - position = position || $.ui.dialog.prototype.options.position; + if ( position ) { + // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( + // if (typeof position == 'string' || $.isArray(position)) { + // myAt = $.isArray(position) ? position : position.split(' '); - // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( -// if (typeof position == 'string' || $.isArray(position)) { -// myAt = $.isArray(position) ? position : position.split(' '); + if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { + myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ]; + if ( myAt.length === 1 ) { + myAt[ 1 ] = myAt[ 0 ]; + } - if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) { - myAt = position.split ? position.split(' ') : [position[0], position[1]]; - if (myAt.length === 1) { - myAt[1] = myAt[0]; - } + $.each( [ "left", "top" ], function( i, offsetPosition ) { + if ( +myAt[ i ] === myAt[ i ] ) { + offset[ i ] = myAt[ i ]; + myAt[ i ] = offsetPosition; + } + }); - $.each(['left', 'top'], function(i, offsetPosition) { - if (+myAt[i] === myAt[i]) { - offset[i] = myAt[i]; - myAt[i] = offsetPosition; - } - }); - } else if (typeof position === 'object') { - if ('left' in position) { - myAt[0] = 'left'; - offset[0] = position.left; - } else if ('right' in position) { - myAt[0] = 'right'; - offset[0] = -position.right; - } + position = { + my: myAt.join( " " ), + at: myAt.join( " " ), + offset: offset.join( " " ) + }; + } - if ('top' in position) { - myAt[1] = 'top'; - offset[1] = position.top; - } else if ('bottom' in position) { - myAt[1] = 'bottom'; - offset[1] = -position.bottom; - } + position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); + } else { + position = $.ui.dialog.prototype.options.position; } // need to show the dialog to get the actual offset in the position plugin - isVisible = this.uiDialog.is(':visible'); - if (!isVisible) { + isVisible = this.uiDialog.is( ":visible" ); + if ( !isVisible ) { this.uiDialog.show(); } - this.uiDialog - // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 - .css({ top: 0, left: 0 }) - .position({ - my: myAt.join(' '), - at: myAt.join(' '), - offset: offset.join(' '), - of: window, - collision: 'fit', - // ensure that the titlebar is never outside the document - using: function(pos) { - var topOffset = $(this).css(pos).offset().top; - if (topOffset < 0) { - $(this).css('top', pos.top - topOffset); - } - } - }); - if (!isVisible) { + this.uiDialog.position( position ); + if ( !isVisible ) { this.uiDialog.hide(); } }, - _setOption: function(key, value){ + _setOptions: function( options ) { var self = this, - uiDialog = self.uiDialog, - isResizable = uiDialog.is(':data(resizable)'), + resizableOptions = {}, resize = false; - - switch (key) { - //handling of deprecated beforeclose (vs beforeClose) option - //Ticket #4669 http://dev.jqueryui.com/ticket/4669 - //TODO: remove in 1.9pre - case "beforeclose": - key = "beforeClose"; - break; + + $.each( options, function( key, value ) { + self._setOption( key, value ); + + if ( key in sizeRelatedOptions ) { + resize = true; + } + if ( key in resizableRelatedOptions ) { + resizableOptions[ key ] = value; + } + }); + + if ( resize ) { + this._size(); + } + if ( this.uiDialog.is( ":data(resizable)" ) ) { + this.uiDialog.resizable( "option", resizableOptions ); + } + }, + + _setOption: function( key, value ) { + var self = this, + uiDialog = self.uiDialog; + + switch ( key ) { case "buttons": - self._createButtons(value); + self._createButtons( value ); break; case "closeText": - // convert whatever was passed in to a string, for text() to not throw up - self.uiDialogTitlebarCloseText.text("" + value); + // ensure that we always pass a string + self.uiDialogTitlebarCloseText.text( "" + value ); break; case "dialogClass": uiDialog - .removeClass(self.options.dialogClass) - .addClass(uiDialogClasses + value); + .removeClass( self.options.dialogClass ) + .addClass( uiDialogClasses + value ); break; case "disabled": - if (value) { - uiDialog.addClass('ui-dialog-disabled'); + if ( value ) { + uiDialog.addClass( "ui-dialog-disabled" ); } else { - uiDialog.removeClass('ui-dialog-disabled'); + uiDialog.removeClass( "ui-dialog-disabled" ); } break; case "draggable": - if (value) { - self._makeDraggable(); - } else { - uiDialog.draggable('destroy'); - } - break; - case "height": - resize = true; - break; - case "maxHeight": - if (isResizable) { - uiDialog.resizable('option', 'maxHeight', value); + var isDraggable = uiDialog.is( ":data(draggable)" ); + if ( isDraggable && !value ) { + uiDialog.draggable( "destroy" ); } - resize = true; - break; - case "maxWidth": - if (isResizable) { - uiDialog.resizable('option', 'maxWidth', value); - } - resize = true; - break; - case "minHeight": - if (isResizable) { - uiDialog.resizable('option', 'minHeight', value); - } - resize = true; - break; - case "minWidth": - if (isResizable) { - uiDialog.resizable('option', 'minWidth', value); + + if ( !isDraggable && value ) { + self._makeDraggable(); } - resize = true; break; case "position": - self._position(value); + self._position( value ); break; case "resizable": // currently resizable, becoming non-resizable - if (isResizable && !value) { - uiDialog.resizable('destroy'); + var isResizable = uiDialog.is( ":data(resizable)" ); + if ( isResizable && !value ) { + uiDialog.resizable( "destroy" ); } // currently resizable, changing handles - if (isResizable && typeof value === 'string') { - uiDialog.resizable('option', 'handles', value); + if ( isResizable && typeof value === "string" ) { + uiDialog.resizable( "option", "handles", value ); } // currently non-resizable, becoming resizable - if (!isResizable && value !== false) { - self._makeResizable(value); + if ( !isResizable && value !== false ) { + self._makeResizable( value ); } break; case "title": // convert whatever was passed in o a string, for html() to not throw up - $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || ' ')); - break; - case "width": - resize = true; + $( ".ui-dialog-title", self.uiDialogTitlebar ) + .html( "" + ( value || " " ) ); break; } - $.Widget.prototype._setOption.apply(self, arguments); - if (resize) { - self._size(); - } + $.Widget.prototype._setOption.apply( self, arguments ); }, _size: function() { @@ -618,36 +611,51 @@ $.widget("ui.dialog", { * divs will both have width and height set, so we need to reset them */ var options = this.options, - nonContentHeight; + nonContentHeight, + minContentHeight, + isVisible = this.uiDialog.is( ":visible" ); // reset content sizing - // hide for non content measurement because height: 0 doesn't work in IE quirks mode (see #4350) - this.element.css({ - width: 'auto', + this.element.show().css({ + width: "auto", minHeight: 0, height: 0 }); + if ( options.minWidth > options.width ) { + options.width = options.minWidth; + } + // reset wrapper sizing // determine the height of all the non-content elements nonContentHeight = this.uiDialog.css({ - height: 'auto', + height: "auto", width: options.width }) .height(); + minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); + + if ( options.height === "auto" ) { + // only needed for IE6 support + if ( $.support.minHeight ) { + this.element.css({ + minHeight: minContentHeight, + height: "auto" + }); + } else { + this.uiDialog.show(); + var autoHeight = this.element.css( "height", "auto" ).height(); + if ( !isVisible ) { + this.uiDialog.hide(); + } + this.element.height( Math.max( autoHeight, minContentHeight ) ); + } + } else { + this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); + } - this.element - .css(options.height === 'auto' ? { - minHeight: Math.max(options.minHeight - nonContentHeight, 0), - height: 'auto' - } : { - minHeight: 0, - height: Math.max(options.height - nonContentHeight, 0) - }) - .show(); - - if (this.uiDialog.is(':data(resizable)')) { - this.uiDialog.resizable('option', 'minHeight', this._minHeight()); + if (this.uiDialog.is( ":data(resizable)" ) ) { + this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); } } }); @@ -659,83 +667,93 @@ $.extend($.ui.dialog, { maxZ: 0, getTitleId: function($el) { - var id = $el.attr('id'); - if (!id) { + var id = $el.attr( "id" ); + if ( !id ) { this.uuid += 1; id = this.uuid; } - return 'ui-dialog-title-' + id; + return "ui-dialog-title-" + id; }, - overlay: function(dialog) { - this.$el = $.ui.dialog.overlay.create(dialog); + overlay: function( dialog ) { + this.$el = $.ui.dialog.overlay.create( dialog ); } }); -$.extend($.ui.dialog.overlay, { +$.extend( $.ui.dialog.overlay, { instances: [], // reuse old instances due to IE memory leak with alpha transparency (see #5185) oldInstances: [], maxZ: 0, - events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','), - function(event) { return event + '.dialog-overlay'; }).join(' '), - create: function(dialog) { - if (this.instances.length === 0) { + events: $.map( + "focus,mousedown,mouseup,keydown,keypress,click".split( "," ), + function( event ) { + return event + ".dialog-overlay"; + } + ).join( " " ), + create: function( dialog ) { + if ( this.instances.length === 0 ) { // prevent use of anchors and inputs // we use a setTimeout in case the overlay is created from an // event that we're going to be cancelling (see #2804) setTimeout(function() { // handle $(el).dialog().dialog('close') (see #4065) - if ($.ui.dialog.overlay.instances.length) { - $(document).bind($.ui.dialog.overlay.events, function(event) { + if ( $.ui.dialog.overlay.instances.length ) { + $( document ).bind( $.ui.dialog.overlay.events, function( event ) { // stop events if the z-index of the target is < the z-index of the overlay - return ($(event.target).zIndex() >= $.ui.dialog.overlay.maxZ); + // we cannot return true when we don't want to cancel the event (#3523) + if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) { + return false; + } }); } - }, 1); + }, 1 ); // allow closing by pressing the escape key - $(document).bind('keydown.dialog-overlay', function(event) { - if (dialog.options.closeOnEscape && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE) { + $( document ).bind( "keydown.dialog-overlay", function( event ) { + if ( dialog.options.closeOnEscape && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE ) { - dialog.close(event); + dialog.close( event ); event.preventDefault(); } }); // handle window resize - $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize); + $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize ); } - var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay')) - .appendTo(document.body) + var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) ) + .appendTo( document.body ) .css({ width: this.width(), height: this.height() }); - if ($.fn.bgiframe) { + if ( $.fn.bgiframe ) { $el.bgiframe(); } - this.instances.push($el); + this.instances.push( $el ); return $el; }, - destroy: function($el) { - this.oldInstances.push(this.instances.splice($.inArray($el, this.instances), 1)[0]); + destroy: function( $el ) { + var indexOf = $.inArray( $el, this.instances ); + if ( indexOf !== -1 ) { + this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] ); + } - if (this.instances.length === 0) { - $([document, window]).unbind('.dialog-overlay'); + if ( this.instances.length === 0 ) { + $( [ document, window ] ).unbind( ".dialog-overlay" ); } $el.remove(); - + // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) var maxZ = 0; - $.each(this.instances, function() { - maxZ = Math.max(maxZ, this.css('z-index')); + $.each( this.instances, function() { + maxZ = Math.max( maxZ, this.css( "z-index" ) ); }); this.maxZ = maxZ; }, @@ -744,7 +762,7 @@ $.extend($.ui.dialog.overlay, { var scrollHeight, offsetHeight; // handle IE 6 - if ($.browser.msie && $.browser.version < 7) { + if ( $.browser.msie && $.browser.version < 7 ) { scrollHeight = Math.max( document.documentElement.scrollHeight, document.body.scrollHeight @@ -754,14 +772,14 @@ $.extend($.ui.dialog.overlay, { document.body.offsetHeight ); - if (scrollHeight < offsetHeight) { - return $(window).height() + 'px'; + if ( scrollHeight < offsetHeight ) { + return $( window ).height() + "px"; } else { - return scrollHeight + 'px'; + return scrollHeight + "px"; } // handle "good" browsers } else { - return $(document).height() + 'px'; + return $( document ).height() + "px"; } }, @@ -769,7 +787,7 @@ $.extend($.ui.dialog.overlay, { var scrollWidth, offsetWidth; // handle IE 6 - if ($.browser.msie && $.browser.version < 7) { + if ( $.browser.msie && $.browser.version < 7 ) { scrollWidth = Math.max( document.documentElement.scrollWidth, document.body.scrollWidth @@ -779,14 +797,14 @@ $.extend($.ui.dialog.overlay, { document.body.offsetWidth ); - if (scrollWidth < offsetWidth) { - return $(window).width() + 'px'; + if ( scrollWidth < offsetWidth ) { + return $( window ).width() + "px"; } else { - return scrollWidth + 'px'; + return scrollWidth + "px"; } // handle "good" browsers } else { - return $(document).width() + 'px'; + return $( document ).width() + "px"; } }, @@ -799,9 +817,9 @@ $.extend($.ui.dialog.overlay, { * This is handled by shrinking the overlay before setting it * to the full document size. */ - var $overlays = $([]); - $.each($.ui.dialog.overlay.instances, function() { - $overlays = $overlays.add(this); + var $overlays = $( [] ); + $.each( $.ui.dialog.overlay.instances, function() { + $overlays = $overlays.add( this ); }); $overlays.css({ @@ -814,10 +832,10 @@ $.extend($.ui.dialog.overlay, { } }); -$.extend($.ui.dialog.overlay.prototype, { +$.extend( $.ui.dialog.overlay.prototype, { destroy: function() { - $.ui.dialog.overlay.destroy(this.$el); + $.ui.dialog.overlay.destroy( this.$el ); } }); -}(jQuery)); +}( jQuery ) ); diff --git a/ui/jquery.ui.draggable.js b/ui/jquery.ui.draggable.js index 9496ce3f5..2d4947145 100644 --- a/ui/jquery.ui.draggable.js +++ b/ui/jquery.ui.draggable.js @@ -1,9 +1,9 @@ /* * jQuery UI Draggable @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Draggables * @@ -12,7 +12,7 @@ * jquery.ui.mouse.js * jquery.ui.widget.js */ -(function($) { +(function( $, undefined ) { $.widget("ui.draggable", $.ui.mouse, { widgetEventPrefix: "drag", @@ -284,7 +284,7 @@ $.widget("ui.draggable", $.ui.mouse, { // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { + if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } @@ -333,10 +333,10 @@ $.widget("ui.draggable", $.ui.mouse, { var o = this.options; if(o.containment == 'parent') o.containment = this.helper[0].parentNode; if(o.containment == 'document' || o.containment == 'window') this.containment = [ - 0 - this.offset.relative.left - this.offset.parent.left, - 0 - this.offset.relative.top - this.offset.parent.top, - $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, - ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top + (o.containment == 'document' ? 0 : $(window).scrollLeft()) - this.offset.relative.left - this.offset.parent.left, + (o.containment == 'document' ? 0 : $(window).scrollTop()) - this.offset.relative.top - this.offset.parent.top, + (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, + (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top ]; if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { @@ -360,7 +360,7 @@ $.widget("ui.draggable", $.ui.mouse, { if(!pos) pos = this.position; var mod = d == "absolute" ? 1 : -1; - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); return { top: ( @@ -381,7 +381,7 @@ $.widget("ui.draggable", $.ui.mouse, { _generatePosition: function(event) { - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); var pageX = event.pageX; var pageY = event.pageY; diff --git a/ui/jquery.ui.droppable.js b/ui/jquery.ui.droppable.js index 4cd7f56e2..084f845c7 100644 --- a/ui/jquery.ui.droppable.js +++ b/ui/jquery.ui.droppable.js @@ -1,9 +1,9 @@ /* * jQuery UI Droppable @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Droppables * @@ -13,7 +13,7 @@ * jquery.ui.mouse.js * jquery.ui.draggable.js */ -(function($) { +(function( $, undefined ) { $.widget("ui.droppable", { widgetEventPrefix: "drop", @@ -161,8 +161,8 @@ $.ui.intersect = function(draggable, droppable, toleranceMode) { switch (toleranceMode) { case 'fit': - return (l < x1 && x2 < r - && t < y1 && y2 < b); + return (l <= x1 && x2 <= r + && t <= y1 && y2 <= b); break; case 'intersect': return (l < x1 + (draggable.helperProportions.width / 2) // Right Half diff --git a/ui/jquery.ui.mouse.js b/ui/jquery.ui.mouse.js index 30c5f14a2..bfe8640a2 100644 --- a/ui/jquery.ui.mouse.js +++ b/ui/jquery.ui.mouse.js @@ -1,16 +1,16 @@ /*! * jQuery UI Mouse @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Mouse * * Depends: * jquery.ui.widget.js */ -(function($) { +(function( $, undefined ) { $.widget("ui.mouse", { options: { @@ -26,8 +26,8 @@ $.widget("ui.mouse", { return self._mouseDown(event); }) .bind('click.'+this.widgetName, function(event) { - if(self._preventClickEvent) { - self._preventClickEvent = false; + if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) { + $.removeData(event.target, self.widgetName + '.preventClickEvent'); event.stopImmediatePropagation(); return false; } @@ -86,18 +86,14 @@ $.widget("ui.mouse", { .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); - // preventDefault() is used to prevent the selection of text here - - // however, in Safari, this causes select boxes not to be selectable - // anymore, so this fix is needed - ($.browser.safari || event.preventDefault()); - + event.preventDefault(); event.originalEvent.mouseHandled = true; return true; }, _mouseMove: function(event) { // IE mouseup check - mouseup happened when mouse was out of window - if ($.browser.msie && !event.button) { + if ($.browser.msie && !(document.documentMode >= 9) && !event.button) { return this._mouseUp(event); } @@ -122,7 +118,11 @@ $.widget("ui.mouse", { if (this._mouseStarted) { this._mouseStarted = false; - this._preventClickEvent = (event.target == this._mouseDownEvent.target); + + if (event.target == this._mouseDownEvent.target) { + $.data(event.target, this.widgetName + '.preventClickEvent', true); + } + this._mouseStop(event); } diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 11f8baa06..3992e1c63 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -1,20 +1,19 @@ /* * jQuery UI Position @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Position */ -(function( $ ) { +(function( $, undefined ) { $.ui = $.ui || {}; var horizontalPositions = /left|center|right/, - horizontalDefault = "center", verticalPositions = /top|center|bottom/, - verticalDefault = "center", + center = "center", _position = $.fn.position, _offset = $.fn.offset; @@ -27,21 +26,22 @@ $.fn.position = function( options ) { options = $.extend( {}, options ); var target = $( options.of ), + targetElem = target[0], collision = ( options.collision || "flip" ).split( " " ), offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ], targetWidth, targetHeight, basePosition; - if ( options.of.nodeType === 9 ) { + if ( targetElem.nodeType === 9 ) { targetWidth = target.width(); targetHeight = target.height(); basePosition = { top: 0, left: 0 }; - } else if ( options.of.scrollTo && options.of.document ) { + } else if ( $.isWindow( targetElem ) ) { targetWidth = target.width(); targetHeight = target.height(); basePosition = { top: target.scrollTop(), left: target.scrollLeft() }; - } else if ( options.of.preventDefault ) { + } else if ( targetElem.preventDefault ) { // force left top to allow flipping options.at = "left top"; targetWidth = targetHeight = 0; @@ -58,13 +58,13 @@ $.fn.position = function( options ) { var pos = ( options[this] || "" ).split( " " ); if ( pos.length === 1) { pos = horizontalPositions.test( pos[0] ) ? - pos.concat( [verticalDefault] ) : + pos.concat( [center] ) : verticalPositions.test( pos[0] ) ? - [ horizontalDefault ].concat( pos ) : - [ horizontalDefault, verticalDefault ]; + [ center ].concat( pos ) : + [ center, center ]; } - pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : horizontalDefault; - pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : verticalDefault; + pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center; + pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center; options[ this ] = pos; }); @@ -82,13 +82,13 @@ $.fn.position = function( options ) { if ( options.at[0] === "right" ) { basePosition.left += targetWidth; - } else if (options.at[0] === horizontalDefault ) { + } else if (options.at[0] === center ) { basePosition.left += targetWidth / 2; } if ( options.at[1] === "bottom" ) { basePosition.top += targetHeight; - } else if ( options.at[1] === verticalDefault ) { + } else if ( options.at[1] === center ) { basePosition.top += targetHeight / 2; } @@ -99,23 +99,35 @@ $.fn.position = function( options ) { var elem = $( this ), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), - position = $.extend( {}, basePosition ); + marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0, + marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0, + collisionWidth = elemWidth + marginLeft + + parseInt( $.curCSS( this, "marginRight", true ) ) || 0, + collisionHeight = elemHeight + marginTop + + parseInt( $.curCSS( this, "marginBottom", true ) ) || 0, + position = $.extend( {}, basePosition ), + collisionPosition; if ( options.my[0] === "right" ) { position.left -= elemWidth; - } else if ( options.my[0] === horizontalDefault ) { + } else if ( options.my[0] === center ) { position.left -= elemWidth / 2; } if ( options.my[1] === "bottom" ) { position.top -= elemHeight; - } else if ( options.my[1] === verticalDefault ) { + } else if ( options.my[1] === center ) { position.top -= elemHeight / 2; } // prevent fractions (see #5280) - position.left = parseInt( position.left ); - position.top = parseInt( position.top ); + position.left = Math.round( position.left ); + position.top = Math.round( position.top ); + + collisionPosition = { + left: position.left - marginLeft, + top: position.top - marginTop + }; $.each( [ "left", "top" ], function( i, dir ) { if ( $.ui.position[ collision[i] ] ) { @@ -124,6 +136,9 @@ $.fn.position = function( options ) { targetHeight: targetHeight, elemWidth: elemWidth, elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, offset: offset, my: options.my, at: options.at @@ -142,41 +157,44 @@ $.ui.position = { fit: { left: function( position, data ) { var win = $( window ), - over = position.left + data.elemWidth - win.width() - win.scrollLeft(); - position.left = over > 0 ? position.left - over : Math.max( 0, position.left ); + over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(); + position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left ); }, top: function( position, data ) { var win = $( window ), - over = position.top + data.elemHeight - win.height() - win.scrollTop(); - position.top = over > 0 ? position.top - over : Math.max( 0, position.top ); + over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(); + position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top ); } }, flip: { left: function( position, data ) { - if ( data.at[0] === "center" ) { + if ( data.at[0] === center ) { return; } var win = $( window ), - over = position.left + data.elemWidth - win.width() - win.scrollLeft(), + over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(), myOffset = data.my[ 0 ] === "left" ? -data.elemWidth : data.my[ 0 ] === "right" ? data.elemWidth : 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + -data.targetWidth, offset = -2 * data.offset[ 0 ]; - position.left += position.left < 0 ? - myOffset + data.targetWidth + offset : + position.left += data.collisionPosition.left < 0 ? + myOffset + atOffset + offset : over > 0 ? - myOffset - data.targetWidth + offset : + myOffset + atOffset + offset : 0; }, top: function( position, data ) { - if ( data.at[1] === "center" ) { + if ( data.at[1] === center ) { return; } var win = $( window ), - over = position.top + data.elemHeight - win.height() - win.scrollTop(), + over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(), myOffset = data.my[ 1 ] === "top" ? -data.elemHeight : data.my[ 1 ] === "bottom" ? @@ -186,8 +204,8 @@ $.ui.position = { data.targetHeight : -data.targetHeight, offset = -2 * data.offset[ 1 ]; - position.top += position.top < 0 ? - myOffset + data.targetHeight + offset : + position.top += data.collisionPosition.top < 0 ? + myOffset + atOffset + offset : over > 0 ? myOffset + atOffset + offset : 0; diff --git a/ui/jquery.ui.progressbar.js b/ui/jquery.ui.progressbar.js index b38d826f0..009049d27 100644 --- a/ui/jquery.ui.progressbar.js +++ b/ui/jquery.ui.progressbar.js @@ -1,9 +1,9 @@ /* * jQuery UI Progressbar @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Progressbar * @@ -11,25 +11,30 @@ * jquery.ui.core.js * jquery.ui.widget.js */ -(function( $ ) { +(function( $, undefined ) { $.widget( "ui.progressbar", { options: { - value: 0 + value: 0, + max: 100 }, + + min: 0, + _create: function() { this.element .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) .attr({ role: "progressbar", - "aria-valuemin": this._valueMin(), - "aria-valuemax": this._valueMax(), + "aria-valuemin": this.min, + "aria-valuemax": this.options.max, "aria-valuenow": this._value() }); this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) .appendTo( this.element ); + this.oldValue = this._value(); this._refreshValue(); }, @@ -56,12 +61,12 @@ $.widget( "ui.progressbar", { }, _setOption: function( key, value ) { - switch ( key ) { - case "value": - this.options.value = value; - this._refreshValue(); - this._trigger( "change" ); - break; + if ( key === "value" ) { + this.options.value = value; + this._refreshValue(); + if ( this._value() === this.options.max ) { + this._trigger( "complete" ); + } } $.Widget.prototype._setOption.apply( this, arguments ); @@ -73,29 +78,25 @@ $.widget( "ui.progressbar", { if ( typeof val !== "number" ) { val = 0; } - if ( val < this._valueMin() ) { - val = this._valueMin(); - } - if ( val > this._valueMax() ) { - val = this._valueMax(); - } - - return val; + return Math.min( this.options.max, Math.max( this.min, val ) ); }, - _valueMin: function() { - return 0; - }, - - _valueMax: function() { - return 100; + _percentage: function() { + return 100 * this._value() / this.options.max; }, _refreshValue: function() { var value = this.value(); + var percentage = this._percentage(); + + if ( this.oldValue !== value ) { + this.oldValue = value; + this._trigger( "change" ); + } + this.valueDiv - [ value === this._valueMax() ? "addClass" : "removeClass"]( "ui-corner-right" ) - .width( value + "%" ); + .toggleClass( "ui-corner-right", value === this.options.max ) + .width( percentage.toFixed(0) + "%" ); this.element.attr( "aria-valuenow", value ); } }); diff --git a/ui/jquery.ui.resizable.js b/ui/jquery.ui.resizable.js index 4ba723884..a835ef9a8 100644 --- a/ui/jquery.ui.resizable.js +++ b/ui/jquery.ui.resizable.js @@ -1,9 +1,9 @@ /* * jQuery UI Resizable @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Resizables * @@ -12,7 +12,7 @@ * jquery.ui.mouse.js * jquery.ui.widget.js */ -(function($) { +(function( $, undefined ) { $.widget("ui.resizable", $.ui.mouse, { widgetEventPrefix: "resize", @@ -528,28 +528,29 @@ $.extend($.ui.resizable, { $.ui.plugin.add("resizable", "alsoResize", { - start: function(event, ui) { - + start: function (event, ui) { var self = $(this).data("resizable"), o = self.options; - var _store = function(exp) { + var _store = function (exp) { $(exp).each(function() { - $(this).data("resizable-alsoresize", { - width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10), - left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10) + var el = $(this); + el.data("resizable-alsoresize", { + width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), + left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10), + position: el.css('position') // to reset Opera on stop() }); }); }; if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { - if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } - else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); } + if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } + else { $.each(o.alsoResize, function (exp) { _store(exp); }); } }else{ _store(o.alsoResize); } }, - resize: function(event, ui){ + resize: function (event, ui) { var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition; var delta = { @@ -557,18 +558,19 @@ $.ui.plugin.add("resizable", "alsoResize", { top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 }, - _alsoResize = function(exp, c) { + _alsoResize = function (exp, c) { $(exp).each(function() { - var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left']; + var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, + css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; - $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) { + $.each(css, function (i, prop) { var sum = (start[prop]||0) + (delta[prop]||0); if (sum && sum >= 0) style[prop] = sum || null; }); - //Opera fixing relative position - if (/relative/.test(el.css('position')) && $.browser.opera) { + // Opera fixing relative position + if ($.browser.opera && /relative/.test(el.css('position'))) { self._revertToRelativePosition = true; el.css({ position: 'absolute', top: 'auto', left: 'auto' }); } @@ -578,22 +580,33 @@ $.ui.plugin.add("resizable", "alsoResize", { }; if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { - $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); }); + $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); }else{ _alsoResize(o.alsoResize); } }, - stop: function(event, ui){ - var self = $(this).data("resizable"); + stop: function (event, ui) { + var self = $(this).data("resizable"), o = self.options; - //Opera fixing relative position - if (self._revertToRelativePosition && $.browser.opera) { + var _reset = function (exp) { + $(exp).each(function() { + var el = $(this); + // reset position for Opera - no need to verify it was changed + el.css({ position: el.data("resizable-alsoresize").position }); + }); + }; + + if (self._revertToRelativePosition) { self._revertToRelativePosition = false; - el.css({ position: 'relative' }); + if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { + $.each(o.alsoResize, function (exp) { _reset(exp); }); + }else{ + _reset(o.alsoResize); + } } - $(this).removeData("resizable-alsoresize-start"); + $(this).removeData("resizable-alsoresize"); } }); diff --git a/ui/jquery.ui.selectable.js b/ui/jquery.ui.selectable.js index a14f720b7..e776e483d 100644 --- a/ui/jquery.ui.selectable.js +++ b/ui/jquery.ui.selectable.js @@ -1,9 +1,9 @@ /* * jQuery UI Selectable @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Selectables * @@ -12,7 +12,7 @@ * jquery.ui.mouse.js * jquery.ui.widget.js */ -(function($) { +(function( $, undefined ) { $.widget("ui.selectable", $.ui.mouse, { options: { @@ -56,9 +56,7 @@ $.widget("ui.selectable", $.ui.mouse, { this._mouseInit(); - this.helper = $(document.createElement('div')) - .css({border:'1px dotted black'}) - .addClass("ui-selectable-helper"); + this.helper = $("<div class='ui-selectable-helper'></div>"); }, destroy: function() { @@ -91,8 +89,6 @@ $.widget("ui.selectable", $.ui.mouse, { $(options.appendTo).append(this.helper); // position helper (lasso) this.helper.css({ - "z-index": 100, - "position": "absolute", "left": event.clientX, "top": event.clientY, "width": 0, @@ -121,14 +117,23 @@ $.widget("ui.selectable", $.ui.mouse, { $(event.target).parents().andSelf().each(function() { var selectee = $.data(this, "selectable-item"); if (selectee) { - selectee.$element.removeClass("ui-unselecting").addClass('ui-selecting'); - selectee.unselecting = false; - selectee.selecting = true; - selectee.selected = true; - // selectable SELECTING callback - self._trigger("selecting", event, { - selecting: selectee.element - }); + var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected'); + selectee.$element + .removeClass(doSelect ? "ui-unselecting" : "ui-selected") + .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); + selectee.unselecting = !doSelect; + selectee.selecting = doSelect; + selectee.selected = doSelect; + // selectable (UN)SELECTING callback + if (doSelect) { + self._trigger("selecting", event, { + selecting: selectee.element + }); + } else { + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } return false; } }); diff --git a/ui/jquery.ui.slider.js b/ui/jquery.ui.slider.js index 440e75635..d3b4744e3 100644 --- a/ui/jquery.ui.slider.js +++ b/ui/jquery.ui.slider.js @@ -1,9 +1,9 @@ /* * jQuery UI Slider @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Slider * @@ -12,8 +12,7 @@ * jquery.ui.mouse.js * jquery.ui.widget.js */ - -(function( $ ) { +(function( $, undefined ) { // number of pages in a slider // (how many times can you page up/down to go through the whole range) @@ -181,24 +180,24 @@ $.widget( "ui.slider", $.ui.mouse, { newVal = self._valueMax(); break; case $.ui.keyCode.PAGE_UP: - newVal = curVal + ( (self._valueMax() - self._valueMin()) / numPages ); + newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) ); break; case $.ui.keyCode.PAGE_DOWN: - newVal = curVal - ( (self._valueMax() - self._valueMin()) / numPages ); + newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) ); break; case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: if ( curVal === self._valueMax() ) { return; } - newVal = curVal + step; + newVal = self._trimAlignValue( curVal + step ); break; case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: if ( curVal === self._valueMin() ) { return; } - newVal = curVal - step; + newVal = self._trimAlignValue( curVal - step ); break; } @@ -310,8 +309,9 @@ $.widget( "ui.slider", $.ui.mouse, { ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) }; - normValue = this._normValueFromMouse( position ); - this._slide( event, index, normValue ); + if ( !this.handles.hasClass( "ui-state-hover" ) ) { + this._slide( event, index, normValue ); + } this._animateOff = true; return true; }, @@ -585,18 +585,18 @@ $.widget( "ui.slider", $.ui.mouse, { // returns the step-aligned value that val is closest to, between (inclusive) min and max _trimAlignValue: function( val ) { - if ( val < this._valueMin() ) { + if ( val <= this._valueMin() ) { return this._valueMin(); } - if ( val > this._valueMax() ) { + if ( val >= this._valueMax() ) { return this._valueMax(); } - var step = this.options.step, - valModStep = val % step, + var step = ( this.options.step > 0 ) ? this.options.step : 1, + valModStep = (val - this._valueMin()) % step; alignValue = val - valModStep; - if ( valModStep >= ( step / 2 ) ) { - alignValue += step; + if ( Math.abs(valModStep) * 2 >= step ) { + alignValue += ( valModStep > 0 ) ? step : ( -step ); } // Since JavaScript has problems with large floats, round diff --git a/ui/jquery.ui.sortable.js b/ui/jquery.ui.sortable.js index 0fa3a1253..32757d41c 100644 --- a/ui/jquery.ui.sortable.js +++ b/ui/jquery.ui.sortable.js @@ -1,9 +1,9 @@ /* * jQuery UI Sortable @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Sortables * @@ -12,7 +12,7 @@ * jquery.ui.mouse.js * jquery.ui.widget.js */ -(function($) { +(function( $, undefined ) { $.widget("ui.sortable", $.ui.mouse, { widgetEventPrefix: "sort", @@ -77,11 +77,10 @@ $.widget("ui.sortable", $.ui.mouse, { if ( key === "disabled" ) { this.options[ key ] = value; - this.widget() - [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" ); + this.widget().toggleClass( "ui-sortable-disabled", !!value ); } else { // Don't call widget base _setOption for disable as it adds ui-state-disabled class - $.Widget.prototype._setOption.apply(self, arguments); + $.Widget.prototype._setOption.apply(this, arguments); } }, @@ -294,8 +293,8 @@ $.widget("ui.sortable", $.ui.mouse, { if(itemElement != this.currentItem[0] //cannot intersect with itself && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before - && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked - && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true) + && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked + && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true) //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container ) { @@ -409,6 +408,10 @@ $.widget("ui.sortable", $.ui.mouse, { if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); }); + if(!str.length && o.key) { + str.push(o.key + '='); + } + return str.join('&'); }, @@ -687,13 +690,13 @@ $.widget("ui.sortable", $.ui.mouse, { for (var i = this.containers.length - 1; i >= 0; i--){ // never consider a container that's located within the item itself - if($.ui.contains(this.currentItem[0], this.containers[i].element[0])) + if($.contains(this.currentItem[0], this.containers[i].element[0])) continue; if(this._intersectsWith(this.containers[i].containerCache)) { // if we've already found a container and it's more "inner" than this, then continue - if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0])) + if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) continue; innermostContainer = this.containers[i]; @@ -721,7 +724,7 @@ $.widget("ui.sortable", $.ui.mouse, { //When entering a new container, we will find the item with the least distance and append our item near it var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; for (var j = this.items.length - 1; j >= 0; j--) { - if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; + if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; if(Math.abs(cur - base) < dist) { dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; @@ -796,7 +799,7 @@ $.widget("ui.sortable", $.ui.mouse, { // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { + if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } @@ -870,7 +873,7 @@ $.widget("ui.sortable", $.ui.mouse, { if(!pos) pos = this.position; var mod = d == "absolute" ? 1 : -1; - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); return { top: ( @@ -891,7 +894,7 @@ $.widget("ui.sortable", $.ui.mouse, { _generatePosition: function(event) { - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); // This is another very weird special case that only happens for relative elements: // 1. If the css position is relative @@ -988,10 +991,10 @@ $.widget("ui.sortable", $.ui.mouse, { if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed - if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element + if(!$.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); for (var i = this.containers.length - 1; i >= 0; i--){ - if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) { + if($.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) { delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i])); delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i])); } diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js new file mode 100644 index 000000000..39a498359 --- /dev/null +++ b/ui/jquery.ui.spinner.js @@ -0,0 +1,360 @@ +/* + * jQuery UI Spinner @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Spinner + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function($) { + +$.widget('ui.spinner', { + options: { + incremental: true, + max: null, + min: null, + numberformat: null, + page: 10, + step: null, + value: null + }, + + _create: function() { + this._draw(); + this._markupOptions(); + this._mousewheel(); + this._aria(); + }, + + _markupOptions: function() { + var _this = this; + $.each({ + min: -Number.MAX_VALUE, + max: Number.MAX_VALUE, + step: 1 + }, function(attr, defaultValue) { + if (_this.options[attr] === null) { + var value = _this.element.attr(attr); + _this.options[attr] = typeof value == "string" && value.length > 0 ? _this._parse(value) : defaultValue; + } + }); + this.value(this.options.value !== null ? this.options.value : this.element.val() || 0); + }, + + _draw: function() { + var self = this, + options = self.options; + + var uiSpinner = this.uiSpinner = self.element + .addClass('ui-spinner-input') + .attr('autocomplete', 'off') + .wrap(self._uiSpinnerHtml()) + .parent() + // add buttons + .append(self._buttonHtml()) + // add behaviours + .hover(function() { + if (!options.disabled) { + $(this).addClass('ui-state-hover'); + } + self.hovered = true; + }, function() { + $(this).removeClass('ui-state-hover'); + self.hovered = false; + }); + + this.element + .bind('keydown.spinner', function(event) { + if (self.options.disabled) { + return; + } + if (self._start(event)) { + return self._keydown(event); + } + return true; + }) + .bind('keyup.spinner', function(event) { + if (self.options.disabled) { + return; + } + if (self.spinning) { + self._stop(event); + self._change(event); + } + }) + .bind('focus.spinner', function() { + uiSpinner.addClass('ui-state-active'); + self.focused = true; + }) + .bind('blur.spinner', function(event) { + self.value(self.element.val()); + if (!self.hovered) { + uiSpinner.removeClass('ui-state-active'); + } + self.focused = false; + }); + + // button bindings + this.buttons = uiSpinner.find('.ui-spinner-button') + .attr("tabIndex", -1) + .button() + .removeClass("ui-corner-all") + .bind('mousedown', function(event) { + if (self.options.disabled) { + return; + } + if (self._start(event) === false) { + return false; + } + self._repeat(null, $(this).hasClass('ui-spinner-up') ? 1 : -1, event); + }) + .bind('mouseup', function(event) { + if (self.options.disabled) { + return; + } + if (self.spinning) { + self._stop(event); + self._change(event); + } + }) + .bind("mouseenter", function() { + if (self.options.disabled) { + return; + } + // button will add ui-state-active if mouse was down while mouseleave and kept down + if ($(this).hasClass("ui-state-active")) { + if (self._start(event) === false) { + return false; + } + self._repeat(null, $(this).hasClass('ui-spinner-up') ? 1 : -1, event); + } + }) + .bind("mouseleave", function() { + if (self.spinning) { + self._stop(event); + self._change(event); + } + }); + + // disable spinner if element was already disabled + if (options.disabled) { + this.disable(); + } + }, + + _keydown: function(event) { + var o = this.options, + KEYS = $.ui.keyCode; + + switch (event.keyCode) { + case KEYS.UP: + this._repeat(null, 1, event); + return false; + case KEYS.DOWN: + this._repeat(null, -1, event); + return false; + case KEYS.PAGE_UP: + this._repeat(null, this.options.page, event); + return false; + case KEYS.PAGE_DOWN: + this._repeat(null, -this.options.page, event); + return false; + + case KEYS.ENTER: + this.value(this.element.val()); + } + + return true; + }, + + _mousewheel: function() { + // need the delta normalization that mousewheel plugin provides + if (!$.fn.mousewheel) { + return; + } + var self = this; + this.element.bind("mousewheel.spinner", function(event, delta) { + if (self.options.disabled) { + return; + } + if (!self.spinning && !self._start(event)) { + return false; + } + self._spin((delta > 0 ? 1 : -1) * self.options.step, event); + clearTimeout(self.timeout); + self.timeout = setTimeout(function() { + if (self.spinning) { + self._stop(event); + self._change(event); + } + }, 100); + event.preventDefault(); + }); + }, + + _uiSpinnerHtml: function() { + return '<span role="spinbutton" class="ui-spinner ui-state-default ui-widget ui-widget-content ui-corner-all"></span>'; + }, + + _buttonHtml: function() { + return '<a class="ui-spinner-button ui-spinner-up ui-corner-tr"><span class="ui-icon ui-icon-triangle-1-n">▲</span></a>' + + '<a class="ui-spinner-button ui-spinner-down ui-corner-br"><span class="ui-icon ui-icon-triangle-1-s">▼</span></a>'; + }, + + _start: function(event) { + if (!this.spinning && this._trigger('start', event) !== false) { + if (!this.counter) { + this.counter = 1; + } + this.spinning = true; + return true; + } + return false; + }, + + _repeat: function(i, steps, event) { + var self = this; + i = i || 500; + + clearTimeout(this.timer); + this.timer = setTimeout(function() { + self._repeat(40, steps, event); + }, i); + + self._spin(steps * self.options.step, event); + }, + + _spin: function(step, event) { + if (!this.counter) { + this.counter = 1; + } + + // TODO refactor, maybe figure out some non-linear math + var newVal = this.value() + step * (this.options.incremental && + this.counter > 20 + ? this.counter > 100 + ? this.counter > 200 + ? 100 + : 10 + : 2 + : 1); + + if (this._trigger('spin', event, { value: newVal }) !== false) { + this.value(newVal); + this.counter++; + } + }, + + _stop: function(event) { + this.counter = 0; + if (this.timer) { + window.clearTimeout(this.timer); + } + this.element[0].focus(); + this.spinning = false; + this._trigger('stop', event); + }, + + _change: function(event) { + this._trigger('change', event); + }, + + _setOption: function(key, value) { + if (key == 'value') { + value = this._parse(value); + if (value < this.options.min) { + value = this.options.min; + } + if (value > this.options.max) { + value = this.options.max; + } + } + if (key == 'disabled') { + if (value) { + this.element.attr("disabled", true); + this.buttons.button("disable"); + } else { + this.element.removeAttr("disabled"); + this.buttons.button("enable"); + } + } + $.Widget.prototype._setOption.call( this, key, value ); + }, + + _setOptions: function( options ) { + $.Widget.prototype._setOptions.call( this, options ); + if ( "value" in options ) { + this._format( this.options.value ); + } + this._aria(); + }, + + _aria: function() { + this.element + .attr('aria-valuemin', this.options.min) + .attr('aria-valuemax', this.options.max) + .attr('aria-valuenow', this.options.value); + }, + + _parse: function(val) { + var input = val; + if (typeof val == 'string') { + // special case for currency formatting until Globalization handles currencies + if (this.options.numberformat == "C" && window.Globalization) { + // parseFloat should accept number format, including currency + var culture = Globalization.culture || Globalization.cultures['default']; + val = val.replace(culture.numberFormat.currency.symbol, ""); + } + val = window.Globalization && this.options.numberformat ? Globalization.parseFloat(val) : +val; + } + return isNaN(val) ? null : val; + }, + + _format: function(num) { + var num = this.options.value; + this.element.val( window.Globalization && this.options.numberformat ? Globalization.format(num, this.options.numberformat) : num ); + }, + + destroy: function() { + this.element + .removeClass('ui-spinner-input') + .removeAttr('disabled') + .removeAttr('autocomplete'); + $.Widget.prototype.destroy.call( this ); + this.uiSpinner.replaceWith(this.element); + }, + + stepUp: function(steps) { + this._spin((steps || 1) * this.options.step); + }, + + stepDown: function(steps) { + this._spin((steps || 1) * -this.options.step); + }, + + pageUp: function(pages) { + this.stepUp((pages || 1) * this.options.page); + }, + + pageDown: function(pages) { + this.stepDown((pages || 1) * this.options.page); + }, + + value: function(newVal) { + if (!arguments.length) { + return this._parse(this.element.val()); + } + this.option('value', newVal); + }, + + widget: function() { + return this.uiSpinner; + } +}); + +})(jQuery); diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 8b6d72329..82da51d5b 100644..100755 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -1,9 +1,9 @@ /* * jQuery UI Tabs @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Tabs * @@ -11,12 +11,20 @@ * jquery.ui.core.js * jquery.ui.widget.js */ -(function($) { +(function( $, undefined ) { var tabId = 0, listId = 0; -$.widget("ui.tabs", { +function getNextTabId() { + return ++tabId; +} + +function getNextListId() { + return ++listId; +} + +$.widget( "ui.tabs", { options: { add: null, ajaxOptions: null, @@ -26,619 +34,648 @@ $.widget("ui.tabs", { disable: null, disabled: [], enable: null, - event: 'click', + event: "click", fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } - idPrefix: 'ui-tabs-', + idPrefix: "ui-tabs-", load: null, - panelTemplate: '<div></div>', + panelTemplate: "<div></div>", remove: null, select: null, show: null, - spinner: '<em>Loading…</em>', - tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>' + spinner: "<em>Loading…</em>", + tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>" }, + _create: function() { - this._tabify(true); + this._tabify( true ); }, - _setOption: function(key, value) { - if (key == 'selected') { - if (this.options.collapsible && value == this.options.selected) { + _setOption: function( key, value ) { + if ( key == "selected" ) { + if (this.options.collapsible && value == this.options.selected ) { return; } - this.select(value); - } - else { - this.options[key] = value; + this.select( value ); + } else { + this.options[ key ] = value; this._tabify(); } }, - _tabId: function(a) { - return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') || - this.options.idPrefix + (++tabId); + _tabId: function( a ) { + return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) || + this.options.idPrefix + getNextTabId(); }, - _sanitizeSelector: function(hash) { - return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":" + _sanitizeSelector: function( hash ) { + // we need this because an id may contain a ":" + return hash.replace( /:/g, "\\:" ); }, _cookie: function() { - var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + (++listId)); - return $.cookie.apply(null, [cookie].concat($.makeArray(arguments))); + var cookie = this.cookie || + ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() ); + return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) ); }, - _ui: function(tab, panel) { + _ui: function( tab, panel ) { return { tab: tab, panel: panel, - index: this.anchors.index(tab) + index: this.anchors.index( tab ) }; }, _cleanup: function() { // restore all former loading tabs labels - this.lis.filter('.ui-state-processing').removeClass('ui-state-processing') - .find('span:data(label.tabs)') + this.lis.filter( ".ui-state-processing" ) + .removeClass( "ui-state-processing" ) + .find( "span:data(label.tabs)" ) .each(function() { - var el = $(this); - el.html(el.data('label.tabs')).removeData('label.tabs'); + var el = $( this ); + el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" ); }); }, - _tabify: function(init) { + _tabify: function( init ) { + var self = this, + o = this.options, + fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash - this.list = this.element.find('ol,ul').eq(0); - this.lis = $('li:has(a[href])', this.list); - this.anchors = this.lis.map(function() { return $('a', this)[0]; }); - this.panels = $([]); - - var self = this, o = this.options; - - var fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash - this.anchors.each(function(i, a) { - var href = $(a).attr('href'); + this.list = this.element.find( "ol,ul" ).eq( 0 ); + this.lis = $( " > li:has(a[href])", this.list ); + this.anchors = this.lis.map(function() { + return $( "a", this )[ 0 ]; + }); + this.panels = $( [] ); + this.anchors.each(function( i, a ) { + var href = $( a ).attr( "href" ); // For dynamically created HTML that contains a hash as href IE < 8 expands // such href to the full page url with hash and then misinterprets tab as ajax. // Same consideration applies for an added tab with a fragment identifier // since a[href=#fragment-identifier] does unexpectedly not match. // Thus normalize href attribute... - var hrefBase = href.split('#')[0], baseEl; - if (hrefBase && (hrefBase === location.toString().split('#')[0] || - (baseEl = $('base')[0]) && hrefBase === baseEl.href)) { + var hrefBase = href.split( "#" )[ 0 ], + baseEl; + if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] || + ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) { href = a.hash; a.href = href; } // inline tab - if (fragmentId.test(href)) { - self.panels = self.panels.add(self._sanitizeSelector(href)); - } - + if ( fragmentId.test( href ) ) { + self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) ); // remote tab - else if (href != '#') { // prevent loading the page itself if href is just "#" - $.data(a, 'href.tabs', href); // required for restore on destroy + // prevent loading the page itself if href is just "#" + } else if ( href && href !== "#" ) { + // required for restore on destroy + $.data( a, "href.tabs", href ); // TODO until #3808 is fixed strip fragment identifier from url // (IE fails to load from such url) - $.data(a, 'load.tabs', href.replace(/#.*$/, '')); // mutable data - - var id = self._tabId(a); - a.href = '#' + id; - var $panel = $('#' + id); - if (!$panel.length) { - $panel = $(o.panelTemplate).attr('id', id).addClass('ui-tabs-panel ui-widget-content ui-corner-bottom') - .insertAfter(self.panels[i - 1] || self.list); - $panel.data('destroy.tabs', true); + $.data( a, "load.tabs", href.replace( /#.*$/, "" ) ); + + var id = self._tabId( a ); + a.href = "#" + id; + var $panel = self.element.find( "#" + id ); + if ( !$panel.length ) { + $panel = $( o.panelTemplate ) + .attr( "id", id ) + .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) + .insertAfter( self.panels[ i - 1 ] || self.list ); + $panel.data( "destroy.tabs", true ); } - self.panels = self.panels.add($panel); - } - + self.panels = self.panels.add( $panel ); // invalid tab href - else { - o.disabled.push(i); + } else { + o.disabled.push( i ); } }); // initialization from scratch - if (init) { - + if ( init ) { // attach necessary classes for styling - this.element.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all'); - this.list.addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all'); - this.lis.addClass('ui-state-default ui-corner-top'); - this.panels.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom'); + this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ); + this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); + this.lis.addClass( "ui-state-default ui-corner-top" ); + this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ); // Selected tab // use "selected" option or try to retrieve: // 1. from fragment identifier in url // 2. from cookie // 3. from selected class attribute on <li> - if (o.selected === undefined) { - if (location.hash) { - this.anchors.each(function(i, a) { - if (a.hash == location.hash) { + if ( o.selected === undefined ) { + if ( location.hash ) { + this.anchors.each(function( i, a ) { + if ( a.hash == location.hash ) { o.selected = i; - return false; // break + return false; } }); } - if (typeof o.selected != 'number' && o.cookie) { - o.selected = parseInt(self._cookie(), 10); + if ( typeof o.selected !== "number" && o.cookie ) { + o.selected = parseInt( self._cookie(), 10 ); } - if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) { - o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected')); + if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) { + o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); } - o.selected = o.selected || (this.lis.length ? 0 : -1); - } - else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release + o.selected = o.selected || ( this.lis.length ? 0 : -1 ); + } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release o.selected = -1; } // sanity check - default to first tab... - o.selected = ((o.selected >= 0 && this.anchors[o.selected]) || o.selected < 0) ? o.selected : 0; + o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 ) + ? o.selected + : 0; // Take disabling tabs via class attribute from HTML // into account and update option properly. // A selected tab cannot become disabled. - o.disabled = $.unique(o.disabled.concat( - $.map(this.lis.filter('.ui-state-disabled'), - function(n, i) { return self.lis.index(n); } ) - )).sort(); - - if ($.inArray(o.selected, o.disabled) != -1) { - o.disabled.splice($.inArray(o.selected, o.disabled), 1); + o.disabled = $.unique( o.disabled.concat( + $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) { + return self.lis.index( n ); + }) + ) ).sort(); + + if ( $.inArray( o.selected, o.disabled ) != -1 ) { + o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 ); } // highlight selected tab - this.panels.addClass('ui-tabs-hide'); - this.lis.removeClass('ui-tabs-selected ui-state-active'); - if (o.selected >= 0 && this.anchors.length) { // check for length avoids error when initializing empty list - this.panels.eq(o.selected).removeClass('ui-tabs-hide'); - this.lis.eq(o.selected).addClass('ui-tabs-selected ui-state-active'); + this.panels.addClass( "ui-tabs-hide" ); + this.lis.removeClass( "ui-tabs-selected ui-state-active" ); + // check for length avoids error when initializing empty list + if ( o.selected >= 0 && this.anchors.length ) { + self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" ); + this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" ); // seems to be expected behavior that the show callback is fired - self.element.queue("tabs", function() { - self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected])); + self.element.queue( "tabs", function() { + self._trigger( "show", null, + self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ) ) ); }); - - this.load(o.selected); + + this.load( o.selected ); } // clean up to avoid memory leaks in certain versions of IE 6 - $(window).bind('unload', function() { - self.lis.add(self.anchors).unbind('.tabs'); + // TODO: namespace this event + $( window ).bind( "unload", function() { + self.lis.add( self.anchors ).unbind( ".tabs" ); self.lis = self.anchors = self.panels = null; }); - - } // update selected after add/remove - else { - o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected')); + } else { + o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); } - // update collapsible - this.element[o.collapsible ? 'addClass' : 'removeClass']('ui-tabs-collapsible'); + this.element.toggleClass( "ui-tabs-collapsible", o.collapsible ); // set or update cookie after init and add/remove respectively - if (o.cookie) { - this._cookie(o.selected, o.cookie); + if ( o.cookie ) { + this._cookie( o.selected, o.cookie ); } // disable tabs - for (var i = 0, li; (li = this.lis[i]); i++) { - $(li)[$.inArray(i, o.disabled) != -1 && - !$(li).hasClass('ui-tabs-selected') ? 'addClass' : 'removeClass']('ui-state-disabled'); + for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) { + $( li ).toggleClass( "ui-state-disabled", + $.inArray( i, o.disabled ) != -1 && !$( li ).hasClass( "ui-tabs-selected" ) ); } // reset cache if switching from cached to not cached - if (o.cache === false) { - this.anchors.removeData('cache.tabs'); + if ( o.cache === false ) { + this.anchors.removeData( "cache.tabs" ); } // remove all handlers before, tabify may run on existing tabs after add or option change - this.lis.add(this.anchors).unbind('.tabs'); + this.lis.add( this.anchors ).unbind( ".tabs" ); - if (o.event != 'mouseover') { - var addState = function(state, el) { - if (el.is(':not(.ui-state-disabled)')) { - el.addClass('ui-state-' + state); + if ( o.event !== "mouseover" ) { + var addState = function( state, el ) { + if ( el.is( ":not(.ui-state-disabled)" ) ) { + el.addClass( "ui-state-" + state ); } }; - var removeState = function(state, el) { - el.removeClass('ui-state-' + state); + var removeState = function( state, el ) { + el.removeClass( "ui-state-" + state ); }; - this.lis.bind('mouseover.tabs', function() { - addState('hover', $(this)); + this.lis.bind( "mouseover.tabs" , function() { + addState( "hover", $( this ) ); }); - this.lis.bind('mouseout.tabs', function() { - removeState('hover', $(this)); + this.lis.bind( "mouseout.tabs", function() { + removeState( "hover", $( this ) ); }); - this.anchors.bind('focus.tabs', function() { - addState('focus', $(this).closest('li')); + this.anchors.bind( "focus.tabs", function() { + addState( "focus", $( this ).closest( "li" ) ); }); - this.anchors.bind('blur.tabs', function() { - removeState('focus', $(this).closest('li')); + this.anchors.bind( "blur.tabs", function() { + removeState( "focus", $( this ).closest( "li" ) ); }); } // set up animations var hideFx, showFx; - if (o.fx) { - if ($.isArray(o.fx)) { - hideFx = o.fx[0]; - showFx = o.fx[1]; - } - else { + if ( o.fx ) { + if ( $.isArray( o.fx ) ) { + hideFx = o.fx[ 0 ]; + showFx = o.fx[ 1 ]; + } else { hideFx = showFx = o.fx; } } // Reset certain styles left over from animation // and prevent IE's ClearType bug... - function resetStyle($el, fx) { - $el.css({ display: '' }); - if (!$.support.opacity && fx.opacity) { - $el[0].style.removeAttribute('filter'); + function resetStyle( $el, fx ) { + $el.css( "display", "" ); + if ( !$.support.opacity && fx.opacity ) { + $el[ 0 ].style.removeAttribute( "filter" ); } } // Show a tab... - var showTab = showFx ? - function(clicked, $show) { - $(clicked).closest('li').addClass('ui-tabs-selected ui-state-active'); - $show.hide().removeClass('ui-tabs-hide') // avoid flicker that way - .animate(showFx, showFx.duration || 'normal', function() { - resetStyle($show, showFx); - self._trigger('show', null, self._ui(clicked, $show[0])); + var showTab = showFx + ? function( clicked, $show ) { + $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); + $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way + .animate( showFx, showFx.duration || "normal", function() { + resetStyle( $show, showFx ); + self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); }); - } : - function(clicked, $show) { - $(clicked).closest('li').addClass('ui-tabs-selected ui-state-active'); - $show.removeClass('ui-tabs-hide'); - self._trigger('show', null, self._ui(clicked, $show[0])); + } + : function( clicked, $show ) { + $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); + $show.removeClass( "ui-tabs-hide" ); + self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); }; // Hide a tab, $show is optional... - var hideTab = hideFx ? - function(clicked, $hide) { - $hide.animate(hideFx, hideFx.duration || 'normal', function() { - self.lis.removeClass('ui-tabs-selected ui-state-active'); - $hide.addClass('ui-tabs-hide'); - resetStyle($hide, hideFx); - self.element.dequeue("tabs"); + var hideTab = hideFx + ? function( clicked, $hide ) { + $hide.animate( hideFx, hideFx.duration || "normal", function() { + self.lis.removeClass( "ui-tabs-selected ui-state-active" ); + $hide.addClass( "ui-tabs-hide" ); + resetStyle( $hide, hideFx ); + self.element.dequeue( "tabs" ); }); - } : - function(clicked, $hide, $show) { - self.lis.removeClass('ui-tabs-selected ui-state-active'); - $hide.addClass('ui-tabs-hide'); - self.element.dequeue("tabs"); + } + : function( clicked, $hide, $show ) { + self.lis.removeClass( "ui-tabs-selected ui-state-active" ); + $hide.addClass( "ui-tabs-hide" ); + self.element.dequeue( "tabs" ); }; // attach tab event handler, unbind to avoid duplicates from former tabifying... - this.anchors.bind(o.event + '.tabs', function() { - var el = this, $li = $(this).closest('li'), $hide = self.panels.filter(':not(.ui-tabs-hide)'), - $show = $(self._sanitizeSelector(this.hash)); + this.anchors.bind( o.event + ".tabs", function( event ) { + event.preventDefault(); + var el = this, + $li = $(el).closest( "li" ), + $hide = self.panels.filter( ":not(.ui-tabs-hide)" ), + $show = self.element.find( self._sanitizeSelector( el.hash ) ); // If tab is already selected and not collapsible or tab disabled or // or is already loading or click callback returns false stop here. // Check if click handler returns false last so that it is not executed // for a disabled or loading tab! - if (($li.hasClass('ui-tabs-selected') && !o.collapsible) || - $li.hasClass('ui-state-disabled') || - $li.hasClass('ui-state-processing') || - self._trigger('select', null, self._ui(this, $show[0])) === false) { + if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) || + $li.hasClass( "ui-state-disabled" ) || + $li.hasClass( "ui-state-processing" ) || + self.panels.filter( ":animated" ).length || + self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) { this.blur(); - return false; + return; } - o.selected = self.anchors.index(this); + o.selected = self.anchors.index( this ); self.abort(); // if tab may be closed - if (o.collapsible) { - if ($li.hasClass('ui-tabs-selected')) { + if ( o.collapsible ) { + if ( $li.hasClass( "ui-tabs-selected" ) ) { o.selected = -1; - if (o.cookie) { - self._cookie(o.selected, o.cookie); + if ( o.cookie ) { + self._cookie( o.selected, o.cookie ); } - self.element.queue("tabs", function() { - hideTab(el, $hide); - }).dequeue("tabs"); - + self.element.queue( "tabs", function() { + hideTab( el, $hide ); + }).dequeue( "tabs" ); + this.blur(); - return false; - } - else if (!$hide.length) { - if (o.cookie) { - self._cookie(o.selected, o.cookie); + return; + } else if ( !$hide.length ) { + if ( o.cookie ) { + self._cookie( o.selected, o.cookie ); } - - self.element.queue("tabs", function() { - showTab(el, $show); + + self.element.queue( "tabs", function() { + showTab( el, $show ); }); - self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 - + // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 + self.load( self.anchors.index( this ) ); + this.blur(); - return false; + return; } } - if (o.cookie) { - self._cookie(o.selected, o.cookie); + if ( o.cookie ) { + self._cookie( o.selected, o.cookie ); } // show new tab - if ($show.length) { - if ($hide.length) { - self.element.queue("tabs", function() { - hideTab(el, $hide); + if ( $show.length ) { + if ( $hide.length ) { + self.element.queue( "tabs", function() { + hideTab( el, $hide ); }); } - self.element.queue("tabs", function() { - showTab(el, $show); + self.element.queue( "tabs", function() { + showTab( el, $show ); }); - - self.load(self.anchors.index(this)); - } - else { - throw 'jQuery UI Tabs: Mismatching fragment identifier.'; + + self.load( self.anchors.index( this ) ); + } else { + throw "jQuery UI Tabs: Mismatching fragment identifier."; } // Prevent IE from keeping other link focussed when using the back button // and remove dotted border from clicked link. This is controlled via CSS // in modern browsers; blur() removes focus from address bar in Firefox - // which can become a usability and annoying problem with tabs('rotate'). - if ($.browser.msie) { + // which can become a usability + if ( $.browser.msie ) { this.blur(); } - }); // disable click in any case - this.anchors.bind('click.tabs', function(){return false;}); + this.anchors.bind( "click.tabs", function( event ){ + event.preventDefault(); + }); + }, + + _getIndex: function( index ) { + // meta-function to give users option to provide a href string instead of a numerical index. + // also sanitizes numerical indexes to valid values. + if ( typeof index == "string" ) { + index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) ); + } + return index; }, destroy: function() { var o = this.options; this.abort(); - - this.element.unbind('.tabs') - .removeClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible') - .removeData('tabs'); - this.list.removeClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all'); + this.element + .unbind( ".tabs" ) + .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ) + .removeData( "tabs" ); + + this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); this.anchors.each(function() { - var href = $.data(this, 'href.tabs'); - if (href) { + var href = $.data( this, "href.tabs" ); + if ( href ) { this.href = href; } - var $this = $(this).unbind('.tabs'); - $.each(['href', 'load', 'cache'], function(i, prefix) { - $this.removeData(prefix + '.tabs'); + var $this = $( this ).unbind( ".tabs" ); + $.each( [ "href", "load", "cache" ], function( i, prefix ) { + $this.removeData( prefix + ".tabs" ); }); }); - this.lis.unbind('.tabs').add(this.panels).each(function() { - if ($.data(this, 'destroy.tabs')) { - $(this).remove(); - } - else { - $(this).removeClass([ - 'ui-state-default', - 'ui-corner-top', - 'ui-tabs-selected', - 'ui-state-active', - 'ui-state-hover', - 'ui-state-focus', - 'ui-state-disabled', - 'ui-tabs-panel', - 'ui-widget-content', - 'ui-corner-bottom', - 'ui-tabs-hide' - ].join(' ')); + this.lis.unbind( ".tabs" ).add( this.panels ).each(function() { + if ( $.data( this, "destroy.tabs" ) ) { + $( this ).remove(); + } else { + $( this ).removeClass([ + "ui-state-default", + "ui-corner-top", + "ui-tabs-selected", + "ui-state-active", + "ui-state-hover", + "ui-state-focus", + "ui-state-disabled", + "ui-tabs-panel", + "ui-widget-content", + "ui-corner-bottom", + "ui-tabs-hide" + ].join( " " ) ); } }); - if (o.cookie) { - this._cookie(null, o.cookie); + if ( o.cookie ) { + this._cookie( null, o.cookie ); } return this; }, - add: function(url, label, index) { - if (index === undefined) { - index = this.anchors.length; // append by default + add: function( url, label, index ) { + if ( index === undefined ) { + index = this.anchors.length; } - var self = this, o = this.options, - $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label)), - id = !url.indexOf('#') ? url.replace('#', '') : this._tabId($('a', $li)[0]); + var self = this, + o = this.options, + $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ), + id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] ); - $li.addClass('ui-state-default ui-corner-top').data('destroy.tabs', true); + $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true ); // try to find an existing element before creating a new one - var $panel = $('#' + id); - if (!$panel.length) { - $panel = $(o.panelTemplate).attr('id', id).data('destroy.tabs', true); - } - $panel.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide'); - - if (index >= this.lis.length) { - $li.appendTo(this.list); - $panel.appendTo(this.list[0].parentNode); + var $panel = self.element.find( "#" + id ); + if ( !$panel.length ) { + $panel = $( o.panelTemplate ) + .attr( "id", id ) + .data( "destroy.tabs", true ); } - else { - $li.insertBefore(this.lis[index]); - $panel.insertBefore(this.panels[index]); + $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" ); + + if ( index >= this.lis.length ) { + $li.appendTo( this.list ); + $panel.appendTo( this.list[ 0 ].parentNode ); + } else { + $li.insertBefore( this.lis[ index ] ); + $panel.insertBefore( this.panels[ index ] ); } - o.disabled = $.map(o.disabled, - function(n, i) { return n >= index ? ++n : n; }); + o.disabled = $.map( o.disabled, function( n, i ) { + return n >= index ? ++n : n; + }); this._tabify(); - if (this.anchors.length == 1) { // after tabify + if ( this.anchors.length == 1 ) { o.selected = 0; - $li.addClass('ui-tabs-selected ui-state-active'); - $panel.removeClass('ui-tabs-hide'); - this.element.queue("tabs", function() { - self._trigger('show', null, self._ui(self.anchors[0], self.panels[0])); + $li.addClass( "ui-tabs-selected ui-state-active" ); + $panel.removeClass( "ui-tabs-hide" ); + this.element.queue( "tabs", function() { + self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) ); }); - - this.load(0); + + this.load( 0 ); } - // callback - this._trigger('add', null, this._ui(this.anchors[index], this.panels[index])); + this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); return this; }, - remove: function(index) { - var o = this.options, $li = this.lis.eq(index).remove(), - $panel = this.panels.eq(index).remove(); + remove: function( index ) { + index = this._getIndex( index ); + var o = this.options, + $li = this.lis.eq( index ).remove(), + $panel = this.panels.eq( index ).remove(); // If selected tab was removed focus tab to the right or // in case the last tab was removed the tab to the left. - if ($li.hasClass('ui-tabs-selected') && this.anchors.length > 1) { - this.select(index + (index + 1 < this.anchors.length ? 1 : -1)); + if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) { + this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); } - o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }), - function(n, i) { return n >= index ? --n : n; }); + o.disabled = $.map( + $.grep( o.disabled, function(n, i) { + return n != index; + }), + function( n, i ) { + return n >= index ? --n : n; + }); this._tabify(); - // callback - this._trigger('remove', null, this._ui($li.find('a')[0], $panel[0])); + this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) ); return this; }, - enable: function(index) { + enable: function( index ) { + index = this._getIndex( index ); var o = this.options; - if ($.inArray(index, o.disabled) == -1) { + if ( $.inArray( index, o.disabled ) == -1 ) { return; } - this.lis.eq(index).removeClass('ui-state-disabled'); - o.disabled = $.grep(o.disabled, function(n, i) { return n != index; }); + this.lis.eq( index ).removeClass( "ui-state-disabled" ); + o.disabled = $.grep( o.disabled, function( n, i ) { + return n != index; + }); - // callback - this._trigger('enable', null, this._ui(this.anchors[index], this.panels[index])); + this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); return this; }, - disable: function(index) { + disable: function( index ) { + index = this._getIndex( index ); var self = this, o = this.options; - if (index != o.selected) { // cannot disable already selected tab - this.lis.eq(index).addClass('ui-state-disabled'); + // cannot disable already selected tab + if ( index != o.selected ) { + this.lis.eq( index ).addClass( "ui-state-disabled" ); - o.disabled.push(index); + o.disabled.push( index ); o.disabled.sort(); - // callback - this._trigger('disable', null, this._ui(this.anchors[index], this.panels[index])); + this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); } return this; }, - select: function(index) { - if (typeof index == 'string') { - index = this.anchors.index(this.anchors.filter('[href$=' + index + ']')); - } - else if (index === null) { // usage of null is deprecated, TODO remove in next release - index = -1; - } - if (index == -1 && this.options.collapsible) { - index = this.options.selected; + select: function( index ) { + index = this._getIndex( index ); + if ( index == -1 ) { + if ( this.options.collapsible && this.options.selected != -1 ) { + index = this.options.selected; + } else { + return this; + } } - - this.anchors.eq(index).trigger(this.options.event + '.tabs'); + this.anchors.eq( index ).trigger( this.options.event + ".tabs" ); return this; }, - load: function(index) { - var self = this, o = this.options, a = this.anchors.eq(index)[0], url = $.data(a, 'load.tabs'); + load: function( index ) { + index = this._getIndex( index ); + var self = this, + o = this.options, + a = this.anchors.eq( index )[ 0 ], + url = $.data( a, "load.tabs" ); this.abort(); // not remote or from cache - if (!url || this.element.queue("tabs").length !== 0 && $.data(a, 'cache.tabs')) { - this.element.dequeue("tabs"); + if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) { + this.element.dequeue( "tabs" ); return; } // load remote from here on - this.lis.eq(index).addClass('ui-state-processing'); + this.lis.eq( index ).addClass( "ui-state-processing" ); - if (o.spinner) { - var span = $('span', a); - span.data('label.tabs', span.html()).html(o.spinner); + if ( o.spinner ) { + var span = $( "span", a ); + span.data( "label.tabs", span.html() ).html( o.spinner ); } - this.xhr = $.ajax($.extend({}, o.ajaxOptions, { + this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, { url: url, - success: function(r, s) { - $(self._sanitizeSelector(a.hash)).html(r); + success: function( r, s ) { + self.element.find( self._sanitizeSelector( a.hash ) ).html( r ); // take care of tab labels self._cleanup(); - if (o.cache) { - $.data(a, 'cache.tabs', true); // if loaded once do not load them again + if ( o.cache ) { + $.data( a, "cache.tabs", true ); } - // callbacks - self._trigger('load', null, self._ui(self.anchors[index], self.panels[index])); + self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); try { - o.ajaxOptions.success(r, s); + o.ajaxOptions.success( r, s ); } - catch (e) {} + catch ( e ) {} }, - error: function(xhr, s, e) { + error: function( xhr, s, e ) { // take care of tab labels self._cleanup(); - // callbacks - self._trigger('load', null, self._ui(self.anchors[index], self.panels[index])); + self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); try { // Passing index avoid a race condition when this method is // called after the user has selected another tab. // Pass the anchor that initiated this request allows // loadError to manipulate the tab content panel via $(a.hash) - o.ajaxOptions.error(xhr, s, index, a); + o.ajaxOptions.error( xhr, s, index, a ); } - catch (e) {} + catch ( e ) {} } - })); + } ) ); // last, so that load event is fired before show... - self.element.dequeue("tabs"); + self.element.dequeue( "tabs" ); return this; }, abort: function() { // stop possibly running animations - this.element.queue([]); - this.panels.stop(false, true); + this.element.queue( [] ); + this.panels.stop( false, true ); // "tabs" queue must not contain more than two elements, // which are the callbacks for the latest clicked tab... - this.element.queue("tabs", this.element.queue("tabs").splice(-2, 2)); + this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) ); // terminate pending requests from other tabs - if (this.xhr) { + if ( this.xhr ) { this.xhr.abort(); delete this.xhr; } @@ -648,74 +685,18 @@ $.widget("ui.tabs", { return this; }, - url: function(index, url) { - this.anchors.eq(index).removeData('cache.tabs').data('load.tabs', url); + url: function( index, url ) { + this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url ); return this; }, length: function() { return this.anchors.length; } - -}); - -$.extend($.ui.tabs, { - version: '@VERSION' }); -/* - * Tabs Extensions - */ - -/* - * Rotate - */ -$.extend($.ui.tabs.prototype, { - rotation: null, - rotate: function(ms, continuing) { - - var self = this, o = this.options; - - var rotate = self._rotate || (self._rotate = function(e) { - clearTimeout(self.rotation); - self.rotation = setTimeout(function() { - var t = o.selected; - self.select( ++t < self.anchors.length ? t : 0 ); - }, ms); - - if (e) { - e.stopPropagation(); - } - }); - - var stop = self._unrotate || (self._unrotate = !continuing ? - function(e) { - if (e.clientX) { // in case of a true click - self.rotate(null); - } - } : - function(e) { - t = o.selected; - rotate(); - }); - - // start rotation - if (ms) { - this.element.bind('tabsshow', rotate); - this.anchors.bind(o.event + '.tabs', stop); - rotate(); - } - // stop rotation - else { - clearTimeout(self.rotation); - this.element.unbind('tabsshow', rotate); - this.anchors.unbind(o.event + '.tabs', stop); - delete this._rotate; - delete this._unrotate; - } - - return this; - } +$.extend( $.ui.tabs, { + version: "@VERSION" }); -})(jQuery); +})( jQuery ); diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index a9829d2e5..b5fb600d9 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -1,28 +1,38 @@ /*! * jQuery UI Widget @VERSION * - * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license * * http://docs.jquery.com/UI/Widget */ -(function( $ ) { - -var _remove = $.fn.remove; - -$.fn.remove = function( selector, keepData ) { - return this.each(function() { - if ( !keepData ) { - if ( !selector || $.filter( selector, [ this ] ).length ) { - $( "*", this ).add( this ).each(function() { - $( this ).triggerHandler( "remove" ); - }); - } +(function( $, undefined ) { + +// jQuery 1.4+ +if ( $.cleanData ) { + var _cleanData = $.cleanData; + $.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $( elem ).triggerHandler( "remove" ); } - return _remove.call( $(this), selector, keepData ); - }); -}; + _cleanData( elems ); + }; +} else { + var _remove = $.fn.remove; + $.fn.remove = function( selector, keepData ) { + return this.each(function() { + if ( !keepData ) { + if ( !selector || $.filter( selector, [ this ] ).length ) { + $( "*", this ).add( [ this ] ).each(function() { + $( this ).triggerHandler( "remove" ); + }); + } + } + return _remove.call( $(this), selector, keepData ); + }); + }; +} $.widget = function( name, base, prototype ) { var namespace = name.split( "." )[ 0 ], @@ -57,7 +67,7 @@ $.widget = function( name, base, prototype ) { // basePrototype[ key ] = $.extend( {}, val ); // } // }); - basePrototype.options = $.extend( {}, basePrototype.options ); + basePrototype.options = $.extend( true, {}, basePrototype.options ); $[ namespace ][ name ].prototype = $.extend( true, basePrototype, { namespace: namespace, widgetName: name, @@ -80,16 +90,21 @@ $.widget.bridge = function( name, object ) { options; // prevent calls to internal methods - if ( isMethodCall && options.substring( 0, 1 ) === "_" ) { + if ( isMethodCall && options.charAt( 0 ) === "_" ) { return returnValue; } if ( isMethodCall ) { this.each(function() { - var instance = $.data( this, name ), - methodValue = instance && $.isFunction( instance[options] ) ? - instance[ options ].apply( instance, args ) : - instance; + var instance = $.data( this, name ); + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + var methodValue = instance[ options ].apply( instance, args ); if ( methodValue !== instance && methodValue !== undefined ) { returnValue = methodValue; return false; @@ -99,10 +114,7 @@ $.widget.bridge = function( name, object ) { this.each(function() { var instance = $.data( this, name ); if ( instance ) { - if ( options ) { - instance.option( options ); - } - instance._init(); + instance.option( options || {} )._init(); } else { $.data( this, name, new object( options, this ) ); } @@ -129,10 +141,11 @@ $.Widget.prototype = { _createWidget: function( options, element ) { // $.widget.bridge stores the plugin instance, but we do it anyway // so that it's stored even before the _create function runs - this.element = $( element ).data( this.widgetName, this ); + $.data( element, this.widgetName, this ); + this.element = $( element ); this.options = $.extend( true, {}, this.options, - $.metadata && $.metadata.get( element )[ this.widgetName ], + this._getCreateOptions(), options ); var self = this; @@ -141,8 +154,12 @@ $.Widget.prototype = { }); this._create(); + this._trigger( "create" ); this._init(); }, + _getCreateOptions: function() { + return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; + }, _create: function() {}, _init: function() {}, @@ -163,12 +180,11 @@ $.Widget.prototype = { }, option: function( key, value ) { - var options = key, - self = this; + var options = key; if ( arguments.length === 0 ) { // don't return a reference to the internal hash - return $.extend( {}, self.options ); + return $.extend( {}, this.options ); } if (typeof key === "string" ) { @@ -179,20 +195,24 @@ $.Widget.prototype = { options[ key ] = value; } + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var self = this; $.each( options, function( key, value ) { self._setOption( key, value ); }); - return self; + return this; }, _setOption: function( key, value ) { this.options[ key ] = value; if ( key === "disabled" ) { this.widget() - [ value ? "addClass" : "removeClass"]( - this.widgetBaseClass + "-disabled" + " " + - "ui-state-disabled" ) + .toggleClass( this.widgetBaseClass + "-disabled ui-state-disabled", !!value ) .attr( "aria-disabled", value ); } |