diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/i18n/jquery.ui.datepicker-ca.js | 26 | ||||
-rw-r--r-- | ui/i18n/jquery.ui.datepicker-cy-GB.js | 23 | ||||
-rw-r--r-- | ui/i18n/jquery.ui.datepicker-kk.js (renamed from ui/i18n/jquery.ui.datepicker-kz.js) | 4 | ||||
-rw-r--r-- | ui/i18n/jquery.ui.datepicker-lb.js | 23 | ||||
-rw-r--r-- | ui/i18n/jquery.ui.datepicker-mk.js | 23 | ||||
-rw-r--r-- | ui/i18n/jquery.ui.datepicker-nl-BE.js | 23 | ||||
-rw-r--r-- | ui/jquery.effects.core.js | 34 | ||||
-rw-r--r-- | ui/jquery.effects.scale.js | 21 | ||||
-rw-r--r-- | ui/jquery.ui.accordion.js | 16 | ||||
-rw-r--r-- | ui/jquery.ui.autocomplete.js | 53 | ||||
-rw-r--r-- | ui/jquery.ui.button.js | 4 | ||||
-rw-r--r-- | ui/jquery.ui.core.js | 2 | ||||
-rw-r--r-- | ui/jquery.ui.dialog.js | 18 | ||||
-rw-r--r-- | ui/jquery.ui.draggable.js | 2 | ||||
-rw-r--r-- | ui/jquery.ui.menu.js | 51 | ||||
-rw-r--r-- | ui/jquery.ui.popup.js | 140 | ||||
-rw-r--r-- | ui/jquery.ui.position.js | 45 | ||||
-rw-r--r-- | ui/jquery.ui.resizable.js | 2 | ||||
-rw-r--r-- | ui/jquery.ui.selectable.js | 1 | ||||
-rw-r--r-- | ui/jquery.ui.spinner.js | 23 | ||||
-rw-r--r-- | ui/jquery.ui.tabs.js | 2 | ||||
-rw-r--r-- | ui/jquery.ui.tooltip.js | 4 | ||||
-rw-r--r-- | ui/jquery.ui.widget.js | 19 |
23 files changed, 412 insertions, 147 deletions
diff --git a/ui/i18n/jquery.ui.datepicker-ca.js b/ui/i18n/jquery.ui.datepicker-ca.js index 23c5c8c81..a10b549c2 100644 --- a/ui/i18n/jquery.ui.datepicker-ca.js +++ b/ui/i18n/jquery.ui.datepicker-ca.js @@ -1,23 +1,23 @@ -/* Inicialització en català per a l'extenció 'calendar' per jQuery. */ +/* Inicialització en català per a l'extensió 'UI date picker' per jQuery. */ /* Writers: (joan.leon@gmail.com). */ jQuery(function($){ $.datepicker.regional['ca'] = { - closeText: 'Tancar', - prevText: '<Ant', - nextText: 'Seg>', + closeText: 'Tanca', + prevText: 'Anterior', + nextText: 'Següent', currentText: 'Avui', - monthNames: ['Gener','Febrer','Març','Abril','Maig','Juny', - 'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'], - monthNamesShort: ['Gen','Feb','Mar','Abr','Mai','Jun', - 'Jul','Ago','Set','Oct','Nov','Des'], - dayNames: ['Diumenge','Dilluns','Dimarts','Dimecres','Dijous','Divendres','Dissabte'], - dayNamesShort: ['Dug','Dln','Dmt','Dmc','Djs','Dvn','Dsb'], - dayNamesMin: ['Dg','Dl','Dt','Dc','Dj','Dv','Ds'], - weekHeader: 'Sm', + monthNames: ['gener','febrer','març','abril','maig','juny', + 'juliol','agost','setembre','octubre','novembre','desembre'], + monthNamesShort: ['gen','feb','març','abr','maig','juny', + 'jul','ag','set','oct','nov','des'], + dayNames: ['diumenge','dilluns','dimarts','dimecres','dijous','divendres','dissabte'], + dayNamesShort: ['dg','dl','dt','dc','dj','dv','ds'], + dayNamesMin: ['dg','dl','dt','dc','dj','dv','ds'], + weekHeader: 'Set', dateFormat: 'dd/mm/yy', firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: ''}; $.datepicker.setDefaults($.datepicker.regional['ca']); -});
\ No newline at end of file +}); diff --git a/ui/i18n/jquery.ui.datepicker-cy-GB.js b/ui/i18n/jquery.ui.datepicker-cy-GB.js new file mode 100644 index 000000000..dfee2f9d4 --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-cy-GB.js @@ -0,0 +1,23 @@ +/* Welsh/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by William Griffiths. */ +jQuery(function($){ + $.datepicker.regional['cy-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin', + 'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'], + monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh', + 'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'], + dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'], + dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'], + dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'], + weekHeader: 'Wy', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['cy-GB']); +});
\ No newline at end of file diff --git a/ui/i18n/jquery.ui.datepicker-kz.js b/ui/i18n/jquery.ui.datepicker-kk.js index 658c21275..dcd6a65df 100644 --- a/ui/i18n/jquery.ui.datepicker-kz.js +++ b/ui/i18n/jquery.ui.datepicker-kk.js @@ -1,7 +1,7 @@ /* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ jQuery(function($){ - $.datepicker.regional['kz'] = { + $.datepicker.regional['kk'] = { closeText: 'Жабу', prevText: '<Алдыңғы', nextText: 'Келесі>', @@ -19,5 +19,5 @@ jQuery(function($){ isRTL: false, showMonthAfterYear: false, yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['kz']); + $.datepicker.setDefaults($.datepicker.regional['kk']); }); diff --git a/ui/i18n/jquery.ui.datepicker-lb.js b/ui/i18n/jquery.ui.datepicker-lb.js new file mode 100644 index 000000000..87c79d594 --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-lb.js @@ -0,0 +1,23 @@ +/* Luxembourgish initialisation for the jQuery UI date picker plugin. */ +/* Written by Michel Weimerskirch <michel@weimerskirch.net> */ +jQuery(function($){ + $.datepicker.regional['lb'] = { + closeText: 'Fäerdeg', + prevText: 'Zréck', + nextText: 'Weider', + currentText: 'Haut', + monthNames: ['Januar','Februar','Mäerz','Abrëll','Mee','Juni', + 'Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan', 'Feb', 'Mäe', 'Abr', 'Mee', 'Jun', + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], + dayNames: ['Sonndeg', 'Méindeg', 'Dënschdeg', 'Mëttwoch', 'Donneschdeg', 'Freideg', 'Samschdeg'], + dayNamesShort: ['Son', 'Méi', 'Dën', 'Mët', 'Don', 'Fre', 'Sam'], + dayNamesMin: ['So','Mé','Dë','Më','Do','Fr','Sa'], + weekHeader: 'W', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lb']); +}); diff --git a/ui/i18n/jquery.ui.datepicker-mk.js b/ui/i18n/jquery.ui.datepicker-mk.js new file mode 100644 index 000000000..554ad20ba --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-mk.js @@ -0,0 +1,23 @@ +/* Macedonian i18n for the jQuery UI date picker plugin. */ +/* Written by Stojce Slavkovski. */ +jQuery(function($){ + $.datepicker.regional['mk'] = { + 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['mk']); +}); diff --git a/ui/i18n/jquery.ui.datepicker-nl-BE.js b/ui/i18n/jquery.ui.datepicker-nl-BE.js new file mode 100644 index 000000000..56207cb04 --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-nl-BE.js @@ -0,0 +1,23 @@ +/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */ +/* David De Sloovere @DavidDeSloovere */ +jQuery(function($){ + $.datepicker.regional['nl-BE'] = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', + 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['nl-BE']); +});
\ No newline at end of file diff --git a/ui/jquery.effects.core.js b/ui/jquery.effects.core.js index 3dc0a4e67..233b4f96d 100644 --- a/ui/jquery.effects.core.js +++ b/ui/jquery.effects.core.js @@ -224,7 +224,7 @@ $.effects.animateClass = function( value, duration, easing, callback ) { return this.queue( function() { var animated = $( this ), baseClass = animated.attr( "class" ) || "", - finalClass, + applyClassChange, allAnimations = o.children ? animated.find( "*" ).andSelf() : animated; // map the animated objects to store the original styles. @@ -232,18 +232,19 @@ $.effects.animateClass = function( value, duration, easing, callback ) { var el = $( this ); return { el: el, - originalStyleAttr: el.attr( "style" ) || " ", start: getElementStyles.call( this ) }; }); // apply class change - $.each( classAnimationActions, function(i, action) { - if ( value[ action ] ) { - animated[ action + "Class" ]( value[ action ] ); - } - }); - finalClass = animated.attr( "class" ); + applyClassChange = function() { + $.each( classAnimationActions, function(i, action) { + if ( value[ action ] ) { + animated[ action + "Class" ]( value[ action ] ); + } + }); + }; + applyClassChange(); // map all animated objects again - calculate new styles and diff allAnimations = allAnimations.map(function() { @@ -275,16 +276,15 @@ $.effects.animateClass = function( value, duration, easing, callback ) { $.when.apply( $, allAnimations.get() ).done(function() { // set the final class - animated.attr( "class", finalClass ); + applyClassChange(); - // for each animated element + // for each animated element, + // clear all css properties that were animated $.each( arguments, function() { - if ( typeof this.el.attr( "style" ) === "object" ) { - this.el.attr( "style" ).cssText = ""; - this.el.attr( "style" ).cssText = this.originalStyleAttr; - } else { - this.el.attr( "style", this.originalStyleAttr ); - } + var el = this.el; + $.each( this.diff, function(key) { + el.css( key, '' ); + }); }); // this is guarnteed to be there if you use jQuery.speed() @@ -425,7 +425,7 @@ $.extend( $.effects, { $( active ).focus(); } - wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element + wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element // transfer positioning properties to the wrapper if ( element.css( "position" ) === "static" ) { diff --git a/ui/jquery.effects.scale.js b/ui/jquery.effects.scale.js index 000fdee28..96a9269ec 100644 --- a/ui/jquery.effects.scale.js +++ b/ui/jquery.effects.scale.js @@ -117,9 +117,7 @@ $.effects.effect.size = function( o, done ) { scale = o.scale || "both", origin = o.origin || [ "middle", "center" ], original, baseline, factor, - position = el.css( "position" ), - originalVerticalPositioning = el.css( "bottom" ) !== "auto" ? "bottom" : "top"; - originalHorizontalPositioning = el.css( "right" ) !== "auto" ? "right" : "left"; + position = el.css( "position" ); if ( mode === "show" ) { el.show(); @@ -260,32 +258,19 @@ $.effects.effect.size = function( o, done ) { left: el.to.left }); } else { - $.each([ originalVerticalPositioning, originalHorizontalPositioning ], function( idx, pos ) { + $.each([ "top", "left" ], function( idx, pos ) { el.css( pos, function( _, str ) { var val = parseInt( str, 10 ), toRef = idx ? el.to.left : el.to.top, delta = idx ? el.to.outerWidth - el.from.outerWidth: el.to.outerHeight - el.from.outerHeight, same = origin[ idx ] === pos, - mid = origin[ idx ] === "middle" || origin[ idx ] === "center", - direction = pos == "left" || pos == "top"; + mid = origin[ idx ] === "middle" || origin[ idx ] === "center"; // if original was "auto", recalculate the new value from wrapper if ( str === "auto" ) { return toRef + "px"; } - // if not setting left or top - if ( !direction ) { - - // if the position is relative, bottom/right are reversed meaning - if ( position === "relative" ) { - toRef *= -1; - - // otherwise, if its NOT a midpoint origin, compensate for the outerWidth difference - } else if ( !mid ) { - toRef -= delta * ( same ? -1 : 1 ); - } - } return val + toRef + "px"; }); }); diff --git a/ui/jquery.ui.accordion.js b/ui/jquery.ui.accordion.js index 580009d33..8289ee81b 100644 --- a/ui/jquery.ui.accordion.js +++ b/ui/jquery.ui.accordion.js @@ -483,11 +483,11 @@ $.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 ) ); + s.width( s.parent().width() + - parseFloat( s.css( "paddingLeft" ) ) + - parseFloat( s.css( "paddingRight" ) ) + - ( parseFloat( s.css( "borderLeftWidth" ) ) || 0 ) + - ( parseFloat( s.css( "borderRightWidth" ) ) || 0 ) ); $.each( fxAttrs, function( i, prop ) { hideProps[ prop ] = "hide"; @@ -628,8 +628,10 @@ if ( $.uiBackCompat !== false ) { var _createIcons = prototype._createIcons; prototype._createIcons = function() { - this.options.icons.activeHeader = this.options.icons.activeHeader || - this.options.icons.headerSelected; + if ( this.options.icons ) { + this.options.icons.activeHeader = this.options.icons.activeHeader || + this.options.icons.headerSelected; + } _createIcons.call( this ); }; }( jQuery, jQuery.ui.accordion.prototype ) ); diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index 6b06cfe2c..4e528dce4 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -47,8 +47,15 @@ $.widget( "ui.autocomplete", { _create: function() { var self = this, - doc = this.element[ 0 ].ownerDocument, + // Some browsers only repeat keydown events, not keypress events, + // so we use the suppressKeyPress flag to determine if we've already + // handled the keydown event. #7269 + // Unfortunately the code for & in keypress is the same as the up arrow, + // so we use the suppressKeyPressRepeat flag to avoid handling keypress + // events when we know the keydown event was used to modify the + // search term. #7799 suppressKeyPress, + suppressKeyPressRepeat, suppressInput; this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; @@ -66,11 +73,13 @@ $.widget( "ui.autocomplete", { if ( self.options.disabled || self.element.prop( "readOnly" ) ) { suppressKeyPress = true; suppressInput = true; + suppressKeyPressRepeat = true; return; } suppressKeyPress = false; suppressInput = false; + suppressKeyPressRepeat = false; var keyCode = $.ui.keyCode; switch( event.keyCode ) { case keyCode.PAGE_UP: @@ -110,10 +119,13 @@ $.widget( "ui.autocomplete", { self.menu.select( event ); break; case keyCode.ESCAPE: - self._value( self.term ); - self.close( event ); + if ( self.menu.element.is(":visible") ) { + self._value( self.term ); + self.close( event ); + } break; default: + suppressKeyPressRepeat = true; // search timeout should be triggered before the input value is changed self._searchTimeout( event ); break; @@ -125,6 +137,9 @@ $.widget( "ui.autocomplete", { event.preventDefault(); return; } + if ( suppressKeyPressRepeat ) { + return; + } // replicate some key handlers to allow them to repeat in Firefox and Opera var keyCode = $.ui.keyCode; @@ -181,7 +196,7 @@ $.widget( "ui.autocomplete", { }; this.menu = $( "<ul></ul>" ) .addClass( "ui-autocomplete" ) - .appendTo( $( this.options.appendTo || "body", doc )[0] ) + .appendTo( this.document.find( this.options.appendTo || "body" )[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 @@ -191,7 +206,7 @@ $.widget( "ui.autocomplete", { var menuElement = self.menu.element[ 0 ]; if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { setTimeout(function() { - $( document ).one( 'mousedown', function( event ) { + self.document.one( 'mousedown', function( event ) { if ( event.target !== self.element[ 0 ] && event.target !== menuElement && !$.contains( menuElement, event.target ) ) { @@ -223,7 +238,7 @@ $.widget( "ui.autocomplete", { previous = self.previous; // only trigger when focus was lost (click on menu) - if ( self.element[0] !== doc.activeElement ) { + if ( self.element[0] !== self.document[0].activeElement ) { self.element.focus(); self.previous = previous; // #6109 - IE triggers two focus events and the second @@ -244,22 +259,24 @@ $.widget( "ui.autocomplete", { self.close( event ); self.selectedItem = item; - }, - blur: function( event, ui ) { - // 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._value() !== self.term ) ) { - self._value( self.term ); - } } }) .zIndex( this.element.zIndex() + 1 ) .hide() .data( "menu" ); + if ( $.fn.bgiframe ) { this.menu.element.bgiframe(); } + + // turning off autocomplete prevents the browser from remembering the + // value when navigating through history, so we re-enable autocomplete + // if the page is unloaded before the widget is destroyed. #7790 + this._bind( this.window, { + beforeunload: function() { + this.element.removeAttr( "autocomplete" ); + } + }); }, _destroy: function() { @@ -279,7 +296,7 @@ $.widget( "ui.autocomplete", { this._initSource(); } if ( key === "appendTo" ) { - this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] ) + this.menu.element.appendTo( this.document.find( value || "body" )[0] ); } if ( key === "disabled" && value && this.xhr ) { this.xhr.abort(); @@ -328,7 +345,7 @@ $.widget( "ui.autocomplete", { clearTimeout( self.searching ); self.searching = setTimeout(function() { // only search if the value has changed - if ( self.term != self._value() ) { + if ( self.term !== self._value() ) { self.selectedItem = null; self.search( null, event ); } @@ -435,7 +452,9 @@ $.widget( "ui.autocomplete", { _resizeMenu: function() { var ul = this.menu.element; ul.outerWidth( Math.max( - ul.width( "" ).outerWidth(), + // Firefox wraps long text (possibly a rounding bug) + // so we add 1px to avoid the wrapping (#7513) + ul.width( "" ).outerWidth() + 1, this.element.outerWidth() ) ); }, diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js index 1d9393d37..20eb2ca89 100644 --- a/ui/jquery.ui.button.js +++ b/ui/jquery.ui.button.js @@ -174,7 +174,7 @@ $.widget( "ui.button", { } $( this ).addClass( "ui-state-active" ); lastActive = this; - $( document ).one( "mouseup", function() { + self.document.one( "mouseup", function() { lastActive = null; }); }) @@ -319,7 +319,7 @@ $.widget( "ui.button", { return; } var buttonElement = this.buttonElement.removeClass( typeClasses ), - buttonText = $( "<span></span>" ) + buttonText = $( "<span></span>", this.document[0] ) .addClass( "ui-button-text" ) .html( this.options.label ) .appendTo( buttonElement.empty() ) diff --git a/ui/jquery.ui.core.js b/ui/jquery.ui.core.js index 8bcc4c441..f0cf89ba7 100644 --- a/ui/jquery.ui.core.js +++ b/ui/jquery.ui.core.js @@ -255,7 +255,7 @@ $.extend( $.ui, { }, call: function( instance, name, args ) { var set = instance.plugins[ name ]; - if ( !set || !instance.element[ 0 ].parentNode ) { + if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { return; } diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index 065d640fb..9c9a9b6fc 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -372,8 +372,7 @@ $.widget("ui.dialog", { _makeDraggable: function() { var self = this, - options = self.options, - doc = $( document ); + options = self.options; function filteredUi( ui ) { return { @@ -396,8 +395,8 @@ $.widget("ui.dialog", { }, stop: function( event, ui ) { options.position = [ - ui.position.left - doc.scrollLeft(), - ui.position.top - doc.scrollTop() + ui.position.left - self.document.scrollLeft(), + ui.position.top - self.document.scrollTop() ]; $( this ) .removeClass( "ui-dialog-dragging" ); @@ -715,12 +714,11 @@ $.extend( $.ui.dialog.overlay, { $( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize ); } - var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) ) - .appendTo( document.body ) - .css({ - width: this.width(), - height: this.height() - }); + var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) ); + $el.appendTo( document.body ).css({ + width: this.width(), + height: this.height() + }); if ( $.fn.bgiframe ) { $el.bgiframe(); diff --git a/ui/jquery.ui.draggable.js b/ui/jquery.ui.draggable.js index 6475ebd61..92dd13c0d 100644 --- a/ui/jquery.ui.draggable.js +++ b/ui/jquery.ui.draggable.js @@ -208,7 +208,7 @@ $.widget("ui.draggable", $.ui.mouse, { } //if the original element is removed, don't bother to continue - if(!this.element[0] || !this.element[0].parentNode) + if((!this.element[0] || !this.element[0].parentNode) && this.options.helper === "original") return false; if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 6d9db8879..bf36a77fe 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -24,10 +24,12 @@ $.widget( "ui.menu", { position: { my: "left top", at: "right top" - } + }, + trigger: null }, _create: function() { this.activeMenu = this.element; + this.isScrolling = false; this.menuId = this.element.attr( "id" ) || "ui-menu-" + idIncrement++; if ( this.element.find( ".ui-icon" ).length ) { this.element.addClass( "ui-menu-icons" ); @@ -38,6 +40,16 @@ $.widget( "ui.menu", { id: this.menuId, role: "menu" }) + // Prevent focus from sticking to links inside menu after clicking + // them (focus should always stay on UL during navigation). + // If the link is clicked, redirect focus to the menu. + // TODO move to _bind below + .bind( "mousedown.menu", function( event ) { + if ( $( event.target).is( "a" ) ) { + event.preventDefault(); + $( this ).focus( 1 ); + } + }) // need to catch all clicks on disabled menu // not possible through _bind .bind( "click.menu", $.proxy( function( event ) { @@ -57,10 +69,13 @@ $.widget( "ui.menu", { }, "mouseover .ui-menu-item": function( event ) { event.stopImmediatePropagation(); - var target = $( event.currentTarget ); - // Remove ui-state-active class from siblings of the newly focused menu item to avoid a jump caused by adjacent elements both having a class with a border - target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); - this.focus( event, target ); + if ( !this.isScrolling ) { + var target = $( event.currentTarget ); + // Remove ui-state-active class from siblings of the newly focused menu item to avoid a jump caused by adjacent elements both having a class with a border + target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); + this.focus( event, target ); + } + this.isScrolling = false; }, "mouseleave": "collapseAll", "mouseleave .ui-menu": "collapseAll", @@ -70,10 +85,14 @@ $.widget( "ui.menu", { }, blur: function( event ) { this._delay( function() { - if ( ! $.contains( this.element[0], document.activeElement ) ) { + if ( ! $.contains( this.element[0], this.document[0].activeElement ) ) { this.collapseAll( event ); } }, 0); + }, + scroll: function( event ) { + // Keep track of scrolling to prevent mouseover from firing inadvertently when scrolling the menu + this.isScrolling = true; } }); @@ -188,17 +207,31 @@ $.widget( "ui.menu", { } }); - this._bind( document, { + this._bind( this.document, { click: function( event ) { if ( !$( event.target ).closest( ".ui-menu" ).length ) { this.collapseAll( event ); } } }); + + if ( this.options.trigger ) { + this.element.popup({ + trigger: this.options.trigger, + managed: true, + focusPopup: $.proxy( function( event, ui ) { + this.focus( event, this.element.children( ".ui-menu-item" ).first() ); + this.element.focus( 1 ); + }, this) + }); + } }, _destroy: function() { //destroy (sub)menus + if ( this.options.trigger ) { + this.element.popup( "destroy" ); + } this.element .removeAttr( "aria-activedescendant" ) .find( ".ui-menu" ) @@ -500,6 +533,10 @@ $.widget( "ui.menu", { item: this.active }; this.collapseAll( event, true ); + if ( this.options.trigger ) { + $( this.options.trigger ).focus( 1 ); + this.element.popup( "close" ); + } this._trigger( "select", event, ui ); } }); diff --git a/ui/jquery.ui.popup.js b/ui/jquery.ui.popup.js index ce7a565db..128464cc2 100644 --- a/ui/jquery.ui.popup.js +++ b/ui/jquery.ui.popup.js @@ -14,7 +14,8 @@ */ (function($) { -var idIncrement = 0; +var idIncrement = 0, + suppressExpandOnFocus = false; $.widget( "ui.popup", { version: "@VERSION", @@ -23,6 +24,8 @@ $.widget( "ui.popup", { my: "left top", at: "left bottom" }, + managed: false, + expandOnFocus: false, show: { effect: "slideDown", duration: "fast" @@ -43,9 +46,10 @@ $.widget( "ui.popup", { } if ( !this.element.attr( "role" ) ) { - // TODO alternatives to tooltip are dialog and menu, all three aren't generic popups - this.element.attr( "role", "dialog" ); - this.generatedRole = true; + if ( !this.options.managed ) { + this.element.attr( "role", "dialog" ); + this.generatedRole = true; + } } this.options.trigger @@ -59,37 +63,87 @@ $.widget( "ui.popup", { this._bind(this.options.trigger, { keydown: function( event ) { - // prevent space-to-open to scroll the page, only happens for anchor ui.button - if ( $.ui.button && this.options.trigger.is( "a:ui-button" ) && event.keyCode == $.ui.keyCode.SPACE ) { - event.preventDefault(); - } - // TODO handle SPACE to open popup? only when not handled by ui.button - if ( event.keyCode == $.ui.keyCode.SPACE && this.options.trigger.is( "a:not(:ui-button)" ) ) { - this.options.trigger.trigger( "click", event ); - } - // translate keydown to click - // opens popup and let's tooltip hide itself - if ( event.keyCode == $.ui.keyCode.DOWN ) { - // prevent scrolling - event.preventDefault(); - this.options.trigger.trigger( "click", event ); + switch ( event.keyCode ) { + case $.ui.keyCode.TAB: + // Waiting for close() will make popup hide too late, which breaks tab key behavior + this.element.hide(); + this.close( event ); + break; + case $.ui.keyCode.ESCAPE: + if ( this.isOpen ) { + this.close( event ); + } + break; + case $.ui.keyCode.SPACE: + // prevent space-to-open to scroll the page, only happens for anchor ui.button + // TODO check for $.ui.button before using custom selector, once more below + if ( this.options.trigger.is( "a:ui-button" ) ) { + event.preventDefault(); + } + + else if (this.options.trigger.is( "a:not(:ui-button)" ) ) { + this.options.trigger.trigger( "click", event ); + } + break; + case $.ui.keyCode.DOWN: + case $.ui.keyCode.UP: + // prevent scrolling + event.preventDefault(); + clearTimeout( this.closeTimer ); + this._delay(function() { + this.open( event ); + this.focusPopup( event ); + }, 1); + break; } }, click: function( event ) { + event.stopPropagation(); event.preventDefault(); + }, + mousedown: function( event ) { + var noFocus = false; + /* TODO: Determine in which cases focus should stay on the trigger after the popup opens + (should apply for any trigger that has other interaction besides opening the popup, e.g. a text field) */ + if ( $( event.target ).is( "input" ) ) { + noFocus = true; + } if (this.isOpen) { - // let it propagate to close + suppressExpandOnFocus = true; + this.close(); return; } + this.open( event ); clearTimeout( this.closeTimer ); - this._delay(function() { - this.open( event ); - }, 1); + this._delay( function() { + if ( !noFocus ) { + this.focusPopup(); + } + }, 1 ); } }); - if ( !$.ui.menu || !this.element.is( ":ui-menu" ) ) { - // default use case, wrap tab order in popup + if ( this.options.expandOnFocus ) { + this._bind( this.options.trigger, { + focus : function( event ) { + if ( !suppressExpandOnFocus ) { + this._delay( function() { + if ( !this.isOpen ) { + this.open( event ); + } + }, 1); + } + this._delay( function() { + suppressExpandOnFocus = false; + }, 100); + }, + blur: function( event ) { + suppressExpandOnFocus = false; + } + }); + } + if ( !this.options.managed ) { + //default use case, wrap tab order in popup this._bind({ keydown : function( event ) { if ( event.keyCode !== $.ui.keyCode.TAB ) { return; @@ -114,29 +168,28 @@ $.widget( "ui.popup", { // handle the closing instead of opening again this.closeTimer = this._delay( function() { this.close( event ); - }, 100); + }, 150); }, focusin: function( event ) { clearTimeout( this.closeTimer ); + }, + mouseup: function( event ) { + clearTimeout( this.closeTimer ); } }); this._bind({ - // TODO only triggered on element if it can receive focus - // bind to document instead? - // either element itself or a child should be focusable keyup: function( event ) { if ( event.keyCode == $.ui.keyCode.ESCAPE && this.element.is( ":visible" ) ) { this.close( event ); - // TODO move this to close()? would allow menu.select to call popup.close, and get focus back to trigger - this.options.trigger.focus(); + this.focusTrigger(); } } }); - this._bind(document, { + this._bind( this.document, { click: function( event ) { - if ( this.isOpen && !$(event.target).closest(".ui-popup").length ) { + if ( this.isOpen && !$( event.target ).closest( this.element.add( this.options.trigger ) ).length ) { this.close( event ); } } @@ -174,11 +227,14 @@ $.widget( "ui.popup", { .attr( "aria-expanded", "true" ) .position( position ); - // can't use custom selector when menu isn't loaded - if ( $.ui.menu && this.element.is( ":ui-menu" ) ) { - this.element.menu( "focus", event, this.element.children( "li" ).first() ); - this.element.focus(); - } else { + // take trigger out of tab order to allow shift-tab to skip trigger + this.options.trigger.attr( "tabindex", -1 ); + this.isOpen = true; + this._trigger( "open", event ); + }, + + focusPopup: function( event ) { + if ( !this.options.managed ) { // set focus to the first tabbable element in the popup container // if there are no tabbable elements, set focus on the popup itself var tabbables = this.element.find( ":tabbable" ); @@ -192,11 +248,13 @@ $.widget( "ui.popup", { } tabbables.first().focus( 1 ); } + this._trigger( "focusPopup", event ); + }, - // take trigger out of tab order to allow shift-tab to skip trigger - this.options.trigger.attr( "tabindex", -1 ); - this.isOpen = true; - this._trigger( "open", event ); + focusTrigger: function( event ) { + suppressExpandOnFocus = true; + this.options.trigger.focus(); + this._trigger( "focusTrigger", event ); }, close: function( event ) { diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 74530b948..9a520f845 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -183,6 +183,12 @@ $.fn.position = function( options ) { position.left += myOffset[ 0 ]; position.top += myOffset[ 1 ]; + // if the browser doesn't support fractions, then round for consistent results + if ( !$.support.offsetFractions ) { + position.left = Math.round( position.left ); + position.top = Math.round( position.top ); + } + collisionPosition = { marginLeft: marginLeft, marginTop: marginTop @@ -406,6 +412,45 @@ $.ui.position = { } }; +// fraction support test +(function () { + var testElement, testElementParent, testElementStyle, offsetLeft, i + body = document.getElementsByTagName( "body" )[ 0 ], + div = document.createElement( "div" ); + + //Create a "fake body" for testing based on method used in jQuery.support + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + jQuery.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || document.documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + div.style.cssText = "position: absolute; left: 10.7432222px;"; + + offsetLeft = $( div ).offset().left; + $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); +})(); + // DEPRECATED if ( $.uiBackCompat !== false ) { // offset option diff --git a/ui/jquery.ui.resizable.js b/ui/jquery.ui.resizable.js index 673a8fd75..baca11f83 100644 --- a/ui/jquery.ui.resizable.js +++ b/ui/jquery.ui.resizable.js @@ -292,7 +292,7 @@ $.widget("ui.resizable", $.ui.mouse, { if (!trigger) return false; // Calculate the attrs that will be change - var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; + var data = trigger.apply(this, [event, dx, dy]); // Put this in the mouseDrag handler since the user can start pressing shift while resizing this._updateVirtualBoundaries(event.shiftKey); diff --git a/ui/jquery.ui.selectable.js b/ui/jquery.ui.selectable.js index 75f1cee66..d7b24d4e3 100644 --- a/ui/jquery.ui.selectable.js +++ b/ui/jquery.ui.selectable.js @@ -34,6 +34,7 @@ $.widget("ui.selectable", $.ui.mouse, { var selectees; this.refresh = function() { selectees = $(self.options.filter, self.element[0]); + selectees.addClass("ui-selectee"); selectees.each(function() { var $this = $(this); var pos = $this.offset(); diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js index 31de2c9da..5623722db 100644 --- a/ui/jquery.ui.spinner.js +++ b/ui/jquery.ui.spinner.js @@ -49,6 +49,15 @@ $.widget( "ui.spinner", { this._draw(); this._bind( this._events ); this._refresh(); + + // turning off autocomplete prevents the browser from remembering the + // value when navigating through history, so we re-enable autocomplete + // if the page is unloaded before the widget is destroyed. #7790 + this._bind( this.window, { + beforeunload: function() { + this.element.removeAttr( "autocomplete" ); + } + }); }, _getCreateOptions: function() { @@ -93,7 +102,7 @@ $.widget( "ui.spinner", { this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); clearTimeout( this.mousewheelTimer ); - this.mousewheelTimer = setTimeout(function() { + this.mousewheelTimer = this._delay(function() { if ( this.spinning ) { this._stop( event ); } @@ -103,7 +112,7 @@ $.widget( "ui.spinner", { "mousedown .ui-spinner-button": function( event ) { // ensure focus is on (or stays on) the text field event.preventDefault(); - if ( document.activeElement !== this.element[ 0 ] ) { + if ( this.document[0].activeElement !== this.element[ 0 ] ) { this.element.focus(); } @@ -151,7 +160,8 @@ $.widget( "ui.spinner", { // IE 6 doesn't understand height: 50% for the buttons // unless the wrapper has an explicit height - if ( this.buttons.height() === uiSpinner.height() && uiSpinner.height() > 0 ) { + if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && + uiSpinner.height() > 0 ) { uiSpinner.height( uiSpinner.height() ); } @@ -301,6 +311,13 @@ $.widget( "ui.spinner", { }, _setOption: function( key, value ) { + if ( key === "culture" || key === "numberFormat" ) { + var prevValue = this._parse( this.element.val() ); + this.options[ key ] = value; + this.element.val( this._format( prevValue ) ); + return; + } + this._super( "_setOption", key, value ); if ( key === "disabled" ) { diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 4127ddf84..5eaab1aae 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -561,7 +561,7 @@ $.widget( "ui.tabs", { if ( jqXHR === self.xhr ) { delete self.xhr; } - }); + }, 1 ); }); } diff --git a/ui/jquery.ui.tooltip.js b/ui/jquery.ui.tooltip.js index 2f8d92969..35b6f9b50 100644 --- a/ui/jquery.ui.tooltip.js +++ b/ui/jquery.ui.tooltip.js @@ -166,7 +166,7 @@ $.widget( "ui.tooltip", { // don't close if the element has focus // this prevents the tooltip from closing if you hover while focused - if ( !force && document.activeElement === target[0] ) { + if ( !force && this.document[0].activeElement === target[0] ) { return; } @@ -200,7 +200,7 @@ $.widget( "ui.tooltip", { $( "<div>" ) .addClass( "ui-tooltip-content" ) .appendTo( tooltip ); - tooltip.appendTo( document.body ); + tooltip.appendTo( this.document[0].body ); if ( $.fn.bgiframe ) { tooltip.bgiframe(); } diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index 31328a455..294e321a9 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -195,6 +195,12 @@ $.Widget.prototype = { if ( element !== this ) { $.data( element, this.widgetName, this ); this._bind({ remove: "destroy" }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); } this._create(); @@ -270,10 +276,11 @@ $.Widget.prototype = { return this; }, _setOptions: function( options ) { - var that = this; - $.each( options, function( key, value ) { - that._setOption( key, value ); - }); + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } return this; }, @@ -386,6 +393,10 @@ $.Widget.prototype = { } } + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[0]; + this.element.trigger( event, data ); args = $.isArray( data ) ? |