diff options
author | Felix Nagel <info@felixnagel.com> | 2012-12-12 16:44:19 +0100 |
---|---|---|
committer | Felix Nagel <info@felixnagel.com> | 2012-12-12 16:44:19 +0100 |
commit | f6372bd7eac41ae2c022ef510ec414d016e820ed (patch) | |
tree | b764593154e334e03701dbc896dbac0154c5d136 /ui | |
parent | d1350f9f1113ef5590ec010f16da7068646aec01 (diff) | |
parent | 747d8534520fc3abad81b3c171fa931149398d99 (diff) | |
download | jquery-ui-f6372bd7eac41ae2c022ef510ec414d016e820ed.tar.gz jquery-ui-f6372bd7eac41ae2c022ef510ec414d016e820ed.zip |
Merge branch 'master' into selectmenu
Diffstat (limited to 'ui')
-rw-r--r-- | ui/i18n/jquery.ui.datepicker-be.js | 23 | ||||
-rw-r--r-- | ui/i18n/jquery.ui.datepicker-nb.js | 22 | ||||
-rw-r--r-- | ui/i18n/jquery.ui.datepicker-nn.js | 22 | ||||
-rw-r--r-- | ui/jquery.ui.accordion.js | 1 | ||||
-rw-r--r-- | ui/jquery.ui.autocomplete.js | 3 | ||||
-rw-r--r-- | ui/jquery.ui.core.js | 12 | ||||
-rw-r--r-- | ui/jquery.ui.datepicker.js | 7 | ||||
-rw-r--r-- | ui/jquery.ui.dialog.js | 360 | ||||
-rw-r--r-- | ui/jquery.ui.droppable.js | 6 | ||||
-rw-r--r-- | ui/jquery.ui.menu.js | 1 | ||||
-rw-r--r-- | ui/jquery.ui.position.js | 54 | ||||
-rw-r--r-- | ui/jquery.ui.progressbar.js | 95 | ||||
-rw-r--r-- | ui/jquery.ui.resizable.js | 122 | ||||
-rw-r--r-- | ui/jquery.ui.slider.js | 1 | ||||
-rw-r--r-- | ui/jquery.ui.sortable.js | 12 | ||||
-rw-r--r-- | ui/jquery.ui.tabs.js | 73 | ||||
-rw-r--r-- | ui/jquery.ui.widget.js | 55 |
17 files changed, 488 insertions, 381 deletions
diff --git a/ui/i18n/jquery.ui.datepicker-be.js b/ui/i18n/jquery.ui.datepicker-be.js new file mode 100644 index 000000000..be605dab4 --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-be.js @@ -0,0 +1,23 @@ +/* Belarusian initialisation for the jQuery UI date picker plugin. */
+/* Written by Pavel Selitskas <p.selitskas@gmail.com> */
+jQuery(function($){
+ $.datepicker.regional['be'] = {
+ 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['be']);
+});
diff --git a/ui/i18n/jquery.ui.datepicker-nb.js b/ui/i18n/jquery.ui.datepicker-nb.js new file mode 100644 index 000000000..845a5052d --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-nb.js @@ -0,0 +1,22 @@ +/* Norwegian Bokmål initialisation for the jQuery UI date picker plugin. */ +/* Written by Bjørn Johansen (post@bjornjohansen.no). */ +jQuery(function($){ + $.datepicker.regional['nb'] = { + closeText: 'Lukk', + prevText: '«Forrige', + nextText: 'Neste»', + currentText: 'I dag', + monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], + monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], + dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], + dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], + dayNamesMin: ['sø','ma','ti','on','to','fr','lø'], + weekHeader: 'Uke', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: '' + }; + $.datepicker.setDefaults($.datepicker.regional['nb']); +}); diff --git a/ui/i18n/jquery.ui.datepicker-nn.js b/ui/i18n/jquery.ui.datepicker-nn.js new file mode 100644 index 000000000..b55245ee6 --- /dev/null +++ b/ui/i18n/jquery.ui.datepicker-nn.js @@ -0,0 +1,22 @@ +/* Norwegian Nynorsk initialisation for the jQuery UI date picker plugin. */ +/* Written by Bjørn Johansen (post@bjornjohansen.no). */ +jQuery(function($){ + $.datepicker.regional['nn'] = { + closeText: 'Lukk', + prevText: '«Førre', + nextText: 'Neste»', + currentText: 'I dag', + monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], + monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], + dayNamesShort: ['sun','mån','tys','ons','tor','fre','lau'], + dayNames: ['sundag','måndag','tysdag','onsdag','torsdag','fredag','laurdag'], + dayNamesMin: ['su','må','ty','on','to','fr','la'], + weekHeader: 'Veke', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: '' + }; + $.datepicker.setDefaults($.datepicker.regional['nn']); +}); diff --git a/ui/jquery.ui.accordion.js b/ui/jquery.ui.accordion.js index 7914f7c5f..60475b8ba 100644 --- a/ui/jquery.ui.accordion.js +++ b/ui/jquery.ui.accordion.js @@ -166,6 +166,7 @@ $.widget( "ui.accordion", { }, _keydown: function( event ) { + /*jshint maxcomplexity:15*/ if ( event.altKey || event.ctrlKey ) { return; } diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index 5edb84d44..a858b3382 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -66,6 +66,7 @@ $.widget( "ui.autocomplete", { this._on( this.element, { keydown: function( event ) { + /*jshint maxcomplexity:15*/ if ( this.element.prop( "readOnly" ) ) { suppressKeyPress = true; suppressInput = true; @@ -313,7 +314,7 @@ $.widget( "ui.autocomplete", { this._initSource(); } if ( key === "appendTo" ) { - this.menu.element.appendTo( this.document.find( value || "body" )[0] ); + this.menu.element.appendTo( this._appendTo() ); } if ( key === "disabled" && value && this.xhr ) { this.xhr.abort(); diff --git a/ui/jquery.ui.core.js b/ui/jquery.ui.core.js index 288634376..bd3e30758 100644 --- a/ui/jquery.ui.core.js +++ b/ui/jquery.ui.core.js @@ -289,8 +289,6 @@ $.extend( $.ui, { } }, - contains: $.contains, - // only used by resizable hasScroll: function( el, a ) { @@ -313,16 +311,6 @@ $.extend( $.ui, { 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 ); } }); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 9f480bf38..4ab1fa201 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -497,6 +497,13 @@ $.extend(Datepicker.prototype, { if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { inst.settings.maxDate = this._formatDate(inst, maxDate); } + if ( "disabled" in settings ) { + if ( settings.disabled ) { + this._disableDatepicker(target); + } else { + this._enableDatepicker(target); + } + } this._attachments($(target), inst); this._autoSize(inst); this._setDate(inst, date); diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index 808d31d5b..26989959e 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -19,8 +19,7 @@ */ (function( $, undefined ) { -var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front ", - sizeRelatedOptions = { +var sizeRelatedOptions = { buttons: true, height: true, maxHeight: true, @@ -36,19 +35,20 @@ var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ui-fr minWidth: true }; -$.widget("ui.dialog", { +$.widget( "ui.dialog", { version: "@VERSION", options: { + appendTo: "body", autoOpen: true, - buttons: {}, + buttons: [], closeOnEscape: true, closeText: "close", dialogClass: "", draggable: true, hide: null, height: "auto", - maxHeight: false, - maxWidth: false, + maxHeight: null, + maxWidth: null, minHeight: 150, minWidth: 150, modal: false, @@ -57,7 +57,7 @@ $.widget("ui.dialog", { at: "center", of: window, collision: "fit", - // ensure that the titlebar is never outside the document + // Ensure the titlebar is always visible using: function( pos ) { var topOffset = $( this ).css( pos ).offset().top; if ( topOffset < 0 ) { @@ -84,19 +84,26 @@ $.widget("ui.dialog", { }, _create: function() { - this.originalTitle = this.element.attr( "title" ); - this.options.title = this.options.title || this.originalTitle; - this.oldPosition = { + this.originalCss = { + display: this.element[0].style.display, + width: this.element[0].style.width, + minHeight: this.element[0].style.minHeight, + maxHeight: this.element[0].style.maxHeight, + height: this.element[0].style.height + }; + this.originalPosition = { parent: this.element.parent(), index: this.element.parent().children().index( this.element ) }; + this.originalTitle = this.element.attr("title"); + this.options.title = this.options.title || this.originalTitle; this._createWrapper(); this.element .show() - .removeAttr( "title" ) - .addClass( "ui-dialog-content ui-widget-content" ) + .removeAttr("title") + .addClass("ui-dialog-content ui-widget-content") .appendTo( this.uiDialog ); this._createTitlebar(); @@ -118,31 +125,39 @@ $.widget("ui.dialog", { } }, + _appendTo: function() { + var element = this.options.appendTo; + if ( element && (element.jquery || element.nodeType) ) { + return $( element ); + } + return this.document.find( element || "body" ).eq( 0 ); + }, + _destroy: function() { var next, - oldPosition = this.oldPosition; + originalPosition = this.originalPosition; this._destroyOverlay(); this.element .removeUniqueId() - .removeClass( "ui-dialog-content ui-widget-content" ) - .hide() - // without detaching first, the following becomes really slow + .removeClass("ui-dialog-content ui-widget-content") + .css( this.originalCss ) + // Without detaching first, the following becomes really slow .detach(); - this.uiDialog.remove(); + this.uiDialog.stop( true, true ).remove(); if ( this.originalTitle ) { this.element.attr( "title", this.originalTitle ); } - next = oldPosition.parent.children().eq( oldPosition.index ); + next = originalPosition.parent.children().eq( originalPosition.index ); // Don't try to place the dialog next to itself (#8613) - if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { + if ( next.length && next[0] !== this.element[0] ) { next.before( this.element ); } else { - oldPosition.parent.append( this.element ); + originalPosition.parent.append( this.element ); } }, @@ -156,23 +171,18 @@ $.widget("ui.dialog", { close: function( event ) { var that = this; - if ( !this._isOpen ) { - return; - } - - if ( this._trigger( "beforeClose", event ) === false ) { + if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { return; } this._isOpen = false; - this._destroyOverlay(); - if ( !this.opener.filter( ":focusable" ).focus().length ) { + if ( !this.opener.filter(":focusable").focus().length ) { // Hiding a focused element doesn't trigger blur in WebKit // so in case we have nothing to focus on, explicitly blur the active element // https://bugs.webkit.org/show_bug.cgi?id=47182 - $( this.document[ 0 ].activeElement ).blur(); + $( this.document[0].activeElement ).blur(); } this._hide( this.uiDialog, this.options.hide, function() { @@ -189,8 +199,8 @@ $.widget("ui.dialog", { }, _moveToTop: function( event, silent ) { - var moved = !!this.uiDialog.nextAll( ":visible" ).insertBefore( this.uiDialog ).length; - if ( !silent && moved ) { + var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; + if ( moved && !silent ) { this._trigger( "focus", event ); } return moved; @@ -204,7 +214,7 @@ $.widget("ui.dialog", { return; } - this.opener = $( this.document[ 0 ].activeElement ); + this.opener = $( this.document[0].activeElement ); this._size(); this._position(); @@ -215,40 +225,38 @@ $.widget("ui.dialog", { this._focusTabbable(); this._isOpen = true; - this._trigger( "open" ); - this._trigger( "focus" ); - - return this; + this._trigger("open"); + this._trigger("focus"); }, _focusTabbable: function() { - // set focus to the first match: - // 1. first element inside the dialog matching [autofocus] - // 2. tabbable element inside the content element - // 3. tabbable element inside the buttonpane - // 4. the close button - // 5. the dialog itself - var hasFocus = this.element.find( "[autofocus]" ); + // Set focus to the first match: + // 1. First element inside the dialog matching [autofocus] + // 2. Tabbable element inside the content element + // 3. Tabbable element inside the buttonpane + // 4. The close button + // 5. The dialog itself + var hasFocus = this.element.find("[autofocus]"); if ( !hasFocus.length ) { - hasFocus = this.element.find( ":tabbable" ); - if ( !hasFocus.length ) { - hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); - if ( !hasFocus.length ) { - hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); - if ( !hasFocus.length ) { - hasFocus = this.uiDialog; - } - } - } + hasFocus = this.element.find(":tabbable"); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialogButtonPane.find(":tabbable"); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialog; } hasFocus.eq( 0 ).focus(); }, _keepFocus: function( event ) { function checkFocus() { - var activeElement = this.document[ 0 ].activeElement, - isActive = this.uiDialog[ 0 ] === activeElement || - $.contains( this.uiDialog[ 0 ], activeElement ); + var activeElement = this.document[0].activeElement, + isActive = this.uiDialog[0] === activeElement || + $.contains( this.uiDialog[0], activeElement ); if ( !isActive ) { this._focusTabbable(); } @@ -262,15 +270,16 @@ $.widget("ui.dialog", { }, _createWrapper: function() { - this.uiDialog = $( "<div>" ) - .addClass( uiDialogClasses + this.options.dialogClass ) + this.uiDialog = $("<div>") + .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + + this.options.dialogClass ) .hide() .attr({ - // setting tabIndex makes the div focusable + // Setting tabIndex makes the div focusable tabIndex: -1, role: "dialog" }) - .appendTo( this.document[ 0 ].body ); + .appendTo( this._appendTo() ); this._on( this.uiDialog, { keydown: function( event ) { @@ -285,16 +294,16 @@ $.widget("ui.dialog", { if ( event.keyCode !== $.ui.keyCode.TAB ) { return; } - var tabbables = this.uiDialog.find( ":tabbable" ), - first = tabbables.filter( ":first" ), - last = tabbables.filter( ":last" ); + var tabbables = this.uiDialog.find(":tabbable"), + first = tabbables.filter(":first"), + last = tabbables.filter(":last"); - if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && !event.shiftKey ) { + if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { first.focus( 1 ); - return false; - } else if ( ( event.target === first[ 0 ] || event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { + event.preventDefault(); + } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { last.focus( 1 ); - return false; + event.preventDefault(); } }, mousedown: function( event ) { @@ -307,9 +316,9 @@ $.widget("ui.dialog", { // We assume that any existing aria-describedby attribute means // that the dialog content is marked up properly // otherwise we brute force the content as the description - if ( !this.element.find( "[aria-describedby]" ).length ) { + if ( !this.element.find("[aria-describedby]").length ) { this.uiDialog.attr({ - "aria-describedby": this.element.uniqueId().attr( "id" ) + "aria-describedby": this.element.uniqueId().attr("id") }); } }, @@ -317,22 +326,22 @@ $.widget("ui.dialog", { _createTitlebar: function() { var uiDialogTitle; - this.uiDialogTitlebar = $( "<div>" ) - .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" ) + this.uiDialogTitlebar = $("<div>") + .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") .prependTo( this.uiDialog ); this._on( this.uiDialogTitlebar, { mousedown: function( event ) { // Don't prevent click on close button (#8838) // Focusing a dialog that is partially scrolled out of view // causes the browser to scroll it into view, preventing the click event - if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { + if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { // Dialog isn't getting focus when dragging (#8063) this.uiDialog.focus(); } } }); - this.uiDialogTitlebarClose = $( "<button></button>" ) + this.uiDialogTitlebarClose = $("<button></button>") .button({ label: this.options.closeText, icons: { @@ -340,40 +349,40 @@ $.widget("ui.dialog", { }, text: false }) - .addClass( "ui-dialog-titlebar-close" ) + .addClass("ui-dialog-titlebar-close") .appendTo( this.uiDialogTitlebar ); this._on( this.uiDialogTitlebarClose, { - "click": function( event ) { + click: function( event ) { event.preventDefault(); this.close( event ); } }); - uiDialogTitle = $( "<span>" ) + uiDialogTitle = $("<span>") .uniqueId() - .addClass( "ui-dialog-title" ) + .addClass("ui-dialog-title") .prependTo( this.uiDialogTitlebar ); this._title( uiDialogTitle ); this.uiDialog.attr({ - "aria-labelledby": uiDialogTitle.attr( "id" ) + "aria-labelledby": uiDialogTitle.attr("id") }); }, _title: function( title ) { if ( !this.options.title ) { - title.html( " " ); + title.html(" "); } title.text( this.options.title ); }, _createButtonPane: function() { - var uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) ) - .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); + this.uiDialogButtonPane = $("<div>") + .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); - this.uiButtonSet = $( "<div>" ) - .addClass( "ui-dialog-buttonset" ) - .appendTo( uiDialogButtonPane ); + this.uiButtonSet = $("<div>") + .addClass("ui-dialog-buttonset") + .appendTo( this.uiDialogButtonPane ); this._createButtons(); }, @@ -386,34 +395,35 @@ $.widget("ui.dialog", { this.uiDialogButtonPane.remove(); this.uiButtonSet.empty(); - if ( !$.isEmptyObject( buttons ) ) { - $.each( buttons, function( name, props ) { - var click, buttonOptions; - props = $.isFunction( props ) ? - { click: props, text: name } : - props; - // Default to a non-submitting button - props = $.extend( { type: "button" }, props ); - // Change the context for the click callback to be the main element - click = props.click; - props.click = function() { - click.apply( that.element[0], arguments ); - }; - buttonOptions = { - icons: props.icons, - text: props.showText - }; - delete props.icons; - delete props.showText; - $( "<button></button>", props ) - .button( buttonOptions ) - .appendTo( that.uiButtonSet ); - }); - this.uiDialog.addClass( "ui-dialog-buttons" ); - this.uiDialogButtonPane.appendTo( this.uiDialog ); - } else { - this.uiDialog.removeClass( "ui-dialog-buttons" ); + if ( $.isEmptyObject( buttons ) ) { + this.uiDialog.removeClass("ui-dialog-buttons"); + return; } + + $.each( buttons, function( name, props ) { + var click, buttonOptions; + props = $.isFunction( props ) ? + { click: props, text: name } : + props; + // Default to a non-submitting button + props = $.extend( { type: "button" }, props ); + // Change the context for the click callback to be the main element + click = props.click; + props.click = function() { + click.apply( that.element[0], arguments ); + }; + buttonOptions = { + icons: props.icons, + text: props.showText + }; + delete props.icons; + delete props.showText; + $( "<button></button>", props ) + .button( buttonOptions ) + .appendTo( that.uiButtonSet ); + }); + this.uiDialog.addClass("ui-dialog-buttons"); + this.uiDialogButtonPane.appendTo( this.uiDialog ); }, _makeDraggable: function() { @@ -432,8 +442,7 @@ $.widget("ui.dialog", { handle: ".ui-dialog-titlebar", containment: "document", start: function( event, ui ) { - $( this ) - .addClass( "ui-dialog-dragging" ); + $( this ).addClass("ui-dialog-dragging"); that._trigger( "dragStart", event, filteredUi( ui ) ); }, drag: function( event, ui ) { @@ -444,8 +453,7 @@ $.widget("ui.dialog", { ui.position.left - that.document.scrollLeft(), ui.position.top - that.document.scrollTop() ]; - $( this ) - .removeClass( "ui-dialog-dragging" ); + $( this ).removeClass("ui-dialog-dragging"); that._trigger( "dragStop", event, filteredUi( ui ) ); } }); @@ -457,7 +465,7 @@ $.widget("ui.dialog", { handles = options.resizable, // .ui-resizable has position: relative defined in the stylesheet // but dialogs have to use absolute or fixed positioning - position = this.uiDialog.css( "position" ), + position = this.uiDialog.css("position"), resizeHandles = typeof handles === 'string' ? handles : "n,e,s,w,se,sw,ne,nw"; @@ -481,37 +489,33 @@ $.widget("ui.dialog", { minHeight: this._minHeight(), handles: resizeHandles, start: function( event, ui ) { - $( this ).addClass( "ui-dialog-resizing" ); + $( this ).addClass("ui-dialog-resizing"); that._trigger( "resizeStart", event, filteredUi( ui ) ); }, resize: function( event, ui ) { that._trigger( "resize", event, filteredUi( ui ) ); }, stop: function( event, ui ) { - $( this ).removeClass( "ui-dialog-resizing" ); options.height = $( this ).height(); options.width = $( this ).width(); + $( this ).removeClass("ui-dialog-resizing"); that._trigger( "resizeStop", event, filteredUi( ui ) ); } }) - .css( "position", position ) - .find( ".ui-resizable-se" ) - .addClass( "ui-icon ui-icon-grip-diagonal-se" ); + .css( "position", position ); }, _minHeight: function() { var options = this.options; - if ( options.height === "auto" ) { - return options.minHeight; - } else { - return Math.min( options.minHeight, options.height ); - } + return options.height === "auto" ? + options.minHeight : + Math.min( options.minHeight, options.height ); }, _position: function() { - // need to show the dialog to get the actual offset in the position plugin - var isVisible = this.uiDialog.is( ":visible" ); + // Need to show the dialog to get the actual offset in the position plugin + var isVisible = this.uiDialog.is(":visible"); if ( !isVisible ) { this.uiDialog.show(); } @@ -523,8 +527,8 @@ $.widget("ui.dialog", { _setOptions: function( options ) { var that = this, - resizableOptions = {}, - resize = false; + resize = false, + resizableOptions = {}; $.each( options, function( key, value ) { that._setOption( key, value ); @@ -541,12 +545,13 @@ $.widget("ui.dialog", { this._size(); this._position(); } - if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { + if ( this.uiDialog.is(":data(ui-resizable)") ) { this.uiDialog.resizable( "option", resizableOptions ); } }, _setOption: function( key, value ) { + /*jshint maxcomplexity:15*/ var isDraggable, isResizable, uiDialog = this.uiDialog; @@ -562,21 +567,25 @@ $.widget("ui.dialog", { this._super( key, value ); + if ( key === "appendTo" ) { + this.uiDialog.appendTo( this._appendTo() ); + } + if ( key === "buttons" ) { this._createButtons(); } if ( key === "closeText" ) { this.uiDialogTitlebarClose.button({ - // ensure that we always pass a string + // Ensure that we always pass a string label: "" + value }); } if ( key === "draggable" ) { - isDraggable = uiDialog.is( ":data(ui-draggable)" ); + isDraggable = uiDialog.is(":data(ui-draggable)"); if ( isDraggable && !value ) { - uiDialog.draggable( "destroy" ); + uiDialog.draggable("destroy"); } if ( !isDraggable && value ) { @@ -590,9 +599,9 @@ $.widget("ui.dialog", { if ( key === "resizable" ) { // currently resizable, becoming non-resizable - isResizable = uiDialog.is( ":data(ui-resizable)" ); + isResizable = uiDialog.is(":data(ui-resizable)"); if ( isResizable && !value ) { - uiDialog.resizable( "destroy" ); + uiDialog.resizable("destroy"); } // currently resizable, changing handles @@ -607,21 +616,21 @@ $.widget("ui.dialog", { } if ( key === "title" ) { - this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); + this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); } }, _size: function() { - // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content // divs will both have width and height set, so we need to reset them - var nonContentHeight, minContentHeight, + var nonContentHeight, minContentHeight, maxContentHeight, options = this.options; - // reset content sizing + // Reset content sizing this.element.show().css({ width: "auto", minHeight: 0, + maxHeight: "none", height: 0 }); @@ -637,17 +646,21 @@ $.widget("ui.dialog", { }) .outerHeight(); minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); + maxContentHeight = typeof options.maxHeight === "number" ? + Math.max( 0, options.maxHeight - nonContentHeight ) : + "none"; if ( options.height === "auto" ) { this.element.css({ minHeight: minContentHeight, + maxHeight: maxContentHeight, height: "auto" }); } else { - this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); + this.element.height( Math.max( 0, options.height - nonContentHeight ) ); } - if (this.uiDialog.is( ":data(ui-resizable)" ) ) { + if (this.uiDialog.is(":data(ui-resizable)") ) { this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); } }, @@ -656,57 +669,50 @@ $.widget("ui.dialog", { if ( !this.options.modal ) { return; } - if ( $.ui.dialog.overlay.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( "focusin.dialog-overlay", function( event ) { - if ( !$( event.target ).closest( ".ui-dialog").length ) { - event.preventDefault(); - $( ".ui-dialog:visible:last .ui-dialog-content" ).data( "ui-dialog" )._focusTabbable(); + + if ( !$.ui.dialog.overlayInstances ) { + // Prevent use of anchors and inputs. + // We use a delay in case the overlay is created from an + // event that we're going to be cancelling. (#2804) + this._delay(function() { + // Handle .dialog().dialog("close") (#4065) + if ( $.ui.dialog.overlayInstances ) { + this._on( this.document, { + focusin: function( event ) { + if ( !$( event.target ).closest(".ui-dialog").length ) { + event.preventDefault(); + $(".ui-dialog:visible:last .ui-dialog-content") + .data("ui-dialog")._focusTabbable(); + } } }); } - }, 1 ); + }); } - // reuse old instances due to IE memory leak with alpha transparency (see #5185) - var $el = this.overlay = ( $.ui.dialog.overlay.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay ui-front" ) ); - - $el.appendTo( document.body ); - - this._on( $el, { + this.overlay = $("<div>") + .addClass("ui-widget-overlay ui-front") + .appendTo( this.document[0].body ); + this._on( this.overlay, { mousedown: "_keepFocus" }); - - $.ui.dialog.overlay.instances.push( $el ); + $.ui.dialog.overlayInstances++; }, _destroyOverlay: function() { if ( !this.options.modal ) { return; } - var indexOf = $.inArray( this.overlay, $.ui.dialog.overlay.instances ); - if ( indexOf !== -1 ) { - $.ui.dialog.overlay.oldInstances.push( $.ui.dialog.overlay.instances.splice( indexOf, 1 )[ 0 ] ); + $.ui.dialog.overlayInstances--; + if ( !$.ui.dialog.overlayInstances ) { + this._off( this.document, "focusin" ); } - - if ( $.ui.dialog.overlay.instances.length === 0 ) { - $( [ document, window ] ).unbind( ".dialog-overlay" ); - } - this.overlay.remove(); } }); -$.ui.dialog.overlay = { - instances: [], - oldInstances: [] -}; +$.ui.dialog.overlayInstances = 0; // DEPRECATED if ( $.uiBackCompat !== false ) { @@ -721,9 +727,9 @@ if ( $.uiBackCompat !== false ) { if ( position ) { if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { - myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ]; + myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; if ( myAt.length === 1 ) { - myAt[ 1 ] = myAt[ 0 ]; + myAt[1] = myAt[0]; } $.each( [ "left", "top" ], function( i, offsetPosition ) { @@ -736,7 +742,7 @@ if ( $.uiBackCompat !== false ) { position = { my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), - at: myAt.join( " " ) + at: myAt.join(" ") }; } @@ -746,7 +752,7 @@ if ( $.uiBackCompat !== false ) { } // need to show the dialog to get the actual offset in the position plugin - isVisible = this.uiDialog.is( ":visible" ); + isVisible = this.uiDialog.is(":visible"); if ( !isVisible ) { this.uiDialog.show(); } diff --git a/ui/jquery.ui.droppable.js b/ui/jquery.ui.droppable.js index 9d904992d..e2da0b9f6 100644 --- a/ui/jquery.ui.droppable.js +++ b/ui/jquery.ui.droppable.js @@ -16,6 +16,10 @@ */ (function( $, undefined ) { +function isOverAxis( x, reference, size ) { + return ( x > reference ) && ( x < ( reference + size ) ); +} + $.widget("ui.droppable", { version: "@VERSION", widgetEventPrefix: "drop", @@ -203,7 +207,7 @@ $.ui.intersect = function(draggable, droppable, toleranceMode) { case 'pointer': draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); - return $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); + return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); case 'touch': return ( (y1 >= t && y1 <= b) || // Top edge touching diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 45c1ec2e4..41a69c472 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -173,6 +173,7 @@ $.widget( "ui.menu", { }, _keydown: function( event ) { + /*jshint maxcomplexity:20*/ var match, prev, character, skip, regex, preventDefault = true; diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index a5dc31834..dbfadedd1 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -29,10 +29,41 @@ function getOffsets( offsets, width, height ) { parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) ]; } + function parseCss( element, property ) { return parseInt( $.css( element, property ), 10 ) || 0; } +function getDimensions( elem ) { + var raw = elem[0]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( $.isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; +} + $.position = { scrollbarWidth: function() { if ( cachedScrollbarWidth !== undefined ) { @@ -91,32 +122,21 @@ $.fn.position = function( options ) { // make a copy, we don't want to modify arguments options = $.extend( {}, options ); - var atOffset, targetWidth, targetHeight, targetOffset, basePosition, + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, target = $( options.of ), within = $.position.getWithinInfo( options.within ), scrollInfo = $.position.getScrollInfo( within ), - targetElem = target[0], collision = ( options.collision || "flip" ).split( " " ), offsets = {}; - if ( targetElem.nodeType === 9 ) { - targetWidth = target.width(); - targetHeight = target.height(); - targetOffset = { top: 0, left: 0 }; - } else if ( $.isWindow( targetElem ) ) { - targetWidth = target.width(); - targetHeight = target.height(); - targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; - } else if ( targetElem.preventDefault ) { + dimensions = getDimensions( target ); + if ( target[0].preventDefault ) { // force left top to allow flipping options.at = "left top"; - targetWidth = targetHeight = 0; - targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; - } else { - targetWidth = target.outerWidth(); - targetHeight = target.outerHeight(); - targetOffset = target.offset(); } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; // clone to reuse original targetOffset later basePosition = $.extend( {}, targetOffset ); diff --git a/ui/jquery.ui.progressbar.js b/ui/jquery.ui.progressbar.js index 0b1ee8aba..163bb06cd 100644 --- a/ui/jquery.ui.progressbar.js +++ b/ui/jquery.ui.progressbar.js @@ -17,29 +17,31 @@ $.widget( "ui.progressbar", { version: "@VERSION", options: { + max: 100, value: 0, - max: 100 + + change: null, + complete: null }, min: 0, _create: function() { // Constrain initial value - this.options.value = this._constrainedValue(); + this.oldValue = this.options.value = this._constrainedValue(); this.element .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) .attr({ + // Only set static values, aria-valuenow and aria-valuemax are + // set inside _refreshValue() role: "progressbar", - "aria-valuemin": this.min, - "aria-valuemax": this.options.max, - "aria-valuenow": this.options.value + "aria-valuemin": this.min }); - this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'><div></div></div>" ) + this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) .appendTo( this.element ); - this.oldValue = this.options.value; this._refreshValue(); }, @@ -59,85 +61,82 @@ $.widget( "ui.progressbar", { return this.options.value; } - this._setOption( "value", this._constrainedValue( newValue ) ); - return this; + this.options.value = this._constrainedValue( newValue ); + this._refreshValue(); }, _constrainedValue: function( newValue ) { - var val; if ( newValue === undefined ) { - val = this.options.value; - } else { - val = newValue; + newValue = this.options.value; } - this.indeterminate = val === false; + this.indeterminate = newValue === false; // sanitize value - if ( typeof val !== "number" ) { - val = 0; + if ( typeof newValue !== "number" ) { + newValue = 0; } - return this.indeterminate ? false : Math.min( this.options.max, Math.max( this.min, val ) ); + + return this.indeterminate ? false : + Math.min( this.options.max, Math.max( this.min, newValue ) ); }, _setOptions: function( options ) { - var val = options.value; - // Ensure "value" option is set after other values (like max) + var value = options.value; delete options.value; + this._super( options ); - if ( val !== undefined ) { - this._setOption( "value", val ); - } + this.options.value = this._constrainedValue( value ); + this._refreshValue(); }, _setOption: function( key, value ) { if ( key === "max" ) { // Don't allow a max less than min - this.options.max = Math.max( this.min, value ); - this.options.value = this._constrainedValue(); - } - if ( key === "value" ) { - this.options.value = this._constrainedValue( value ); - } - else { - this._super( key, value ); + value = Math.max( this.min, value ); } - this._refreshValue(); + this._super( key, value ); }, _percentage: function() { - return this.indeterminate ? 100 : 100 * this.options.value / this.options.max; + return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); }, _refreshValue: function() { var value = this.options.value, - percentage = this._percentage(), - overlay = this.valueDiv.children().eq( 0 ); - - overlay.toggleClass( "ui-progressbar-overlay", this.indeterminate ); - this.valueDiv.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); - - if ( this.oldValue !== value ) { - this.oldValue = value; - this._trigger( "change" ); - } - if ( value === this.options.max ) { - this._trigger( "complete" ); - } + percentage = this._percentage(); this.valueDiv .toggle( this.indeterminate || value > this.min ) .toggleClass( "ui-corner-right", value === this.options.max ) + .toggleClass( "ui-progressbar-indeterminate", this.indeterminate ) .width( percentage.toFixed(0) + "%" ); + if ( this.indeterminate ) { - this.element.removeAttr( "aria-valuemax" ); this.element.removeAttr( "aria-valuenow" ); + if ( !this.overlayDiv ) { + this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); + } } else { - this.element.attr( "aria-valuemax", this.options.max ); - this.element.attr( "aria-valuenow", value ); + this.element.attr({ + "aria-valuemax": this.options.max, + "aria-valuenow": value + }); + if ( this.overlayDiv ) { + this.overlayDiv.remove(); + this.overlayDiv = null; + } + } + + if ( this.oldValue !== value ) { + this.oldValue = value; + this._trigger( "change" ); + } + if ( value === this.options.max ) { + this._trigger( "complete" ); } } }); diff --git a/ui/jquery.ui.resizable.js b/ui/jquery.ui.resizable.js index 4a019336e..b417288d8 100644 --- a/ui/jquery.ui.resizable.js +++ b/ui/jquery.ui.resizable.js @@ -643,67 +643,6 @@ $.widget("ui.resizable", $.ui.mouse, { * Resizable Extensions */ -$.ui.plugin.add("resizable", "alsoResize", { - - start: function () { - var that = $(this).data("ui-resizable"), - o = that.options, - _store = function (exp) { - $(exp).each(function() { - var el = $(this); - el.data("ui-resizable-alsoresize", { - width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), - left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10) - }); - }); - }; - - 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) { _store(exp); }); } - }else{ - _store(o.alsoResize); - } - }, - - resize: function (event, ui) { - var that = $(this).data("ui-resizable"), - o = that.options, - os = that.originalSize, - op = that.originalPosition, - delta = { - height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, - top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 - }, - - _alsoResize = function (exp, c) { - $(exp).each(function() { - var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, - css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; - - $.each(css, function (i, prop) { - var sum = (start[prop]||0) + (delta[prop]||0); - if (sum && sum >= 0) { - style[prop] = sum || null; - } - }); - - el.css(style); - }); - }; - - if (typeof(o.alsoResize) === 'object' && !o.alsoResize.nodeType) { - $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); - }else{ - _alsoResize(o.alsoResize); - } - }, - - stop: function () { - $(this).removeData("resizable-alsoresize"); - } -}); - $.ui.plugin.add("resizable", "animate", { stop: function( event ) { @@ -871,6 +810,67 @@ $.ui.plugin.add("resizable", "containment", { } }); +$.ui.plugin.add("resizable", "alsoResize", { + + start: function () { + var that = $(this).data("ui-resizable"), + o = that.options, + _store = function (exp) { + $(exp).each(function() { + var el = $(this); + el.data("ui-resizable-alsoresize", { + width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), + left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10) + }); + }); + }; + + 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) { _store(exp); }); } + }else{ + _store(o.alsoResize); + } + }, + + resize: function (event, ui) { + var that = $(this).data("ui-resizable"), + o = that.options, + os = that.originalSize, + op = that.originalPosition, + delta = { + height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, + top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 + }, + + _alsoResize = function (exp, c) { + $(exp).each(function() { + var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, + css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; + + $.each(css, function (i, prop) { + var sum = (start[prop]||0) + (delta[prop]||0); + if (sum && sum >= 0) { + style[prop] = sum || null; + } + }); + + el.css(style); + }); + }; + + if (typeof(o.alsoResize) === 'object' && !o.alsoResize.nodeType) { + $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); + }else{ + _alsoResize(o.alsoResize); + } + }, + + stop: function () { + $(this).removeData("resizable-alsoresize"); + } +}); + $.ui.plugin.add("resizable", "ghost", { start: function() { diff --git a/ui/jquery.ui.slider.js b/ui/jquery.ui.slider.js index d9fc1b132..02fee8364 100644 --- a/ui/jquery.ui.slider.js +++ b/ui/jquery.ui.slider.js @@ -119,6 +119,7 @@ $.widget( "ui.slider", $.ui.mouse, { this._on( this.handles, { keydown: function( event ) { + /*jshint maxcomplexity:25*/ var allowed, curVal, newVal, step, index = $( event.target ).data( "ui-slider-handle-index" ); diff --git a/ui/jquery.ui.sortable.js b/ui/jquery.ui.sortable.js index b1fb642fe..e142a0ede 100644 --- a/ui/jquery.ui.sortable.js +++ b/ui/jquery.ui.sortable.js @@ -17,6 +17,10 @@ /*jshint loopfunc: true */ +function isOverAxis( x, reference, size ) { + return ( x > reference ) && ( x < ( reference + size ) ); +} + $.widget("ui.sortable", $.ui.mouse, { version: "@VERSION", widgetEventPrefix: "sort", @@ -536,8 +540,8 @@ $.widget("ui.sortable", $.ui.mouse, { _intersectsWithPointer: function(item) { - var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), - isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), + var isOverElementHeight = (this.options.axis === 'x') || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), + isOverElementWidth = (this.options.axis === 'y') || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), isOverElement = isOverElementHeight && isOverElementWidth, verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); @@ -554,8 +558,8 @@ $.widget("ui.sortable", $.ui.mouse, { _intersectsWithSides: function(item) { - var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), - isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), + var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), + isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index dcb0c2768..fb66ec6a5 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -23,12 +23,8 @@ function getNextTabId() { function isLocal( anchor ) { return anchor.hash.length > 1 && - anchor.href.replace( rhash, "" ) === - location.href.replace( rhash, "" ) - // support: Safari 5.1 - // Safari 5.1 doesn't encode spaces in window.location - // but it does encode spaces from anchors (#8777) - .replace( /\s/g, "%20" ); + decodeURIComponent( anchor.href.replace( rhash, "" ) ) === + decodeURIComponent( location.href.replace( rhash, "" ) ); } $.widget( "ui.tabs", { @@ -51,9 +47,7 @@ $.widget( "ui.tabs", { _create: function() { var that = this, - options = this.options, - active = options.active, - locationHash = location.hash.substring( 1 ); + options = this.options; this.running = false; @@ -79,6 +73,36 @@ $.widget( "ui.tabs", { }); this._processTabs(); + options.active = this._initialActive(); + + // Take disabling tabs via class attribute from HTML + // into account and update option properly. + if ( $.isArray( options.disabled ) ) { + options.disabled = $.unique( options.disabled.concat( + $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { + return that.tabs.index( li ); + }) + ) ).sort(); + } + + // check for length avoids error when initializing empty list + if ( this.options.active !== false && this.anchors.length ) { + this.active = this._findActive( options.active ); + } else { + this.active = $(); + } + + this._refresh(); + + if ( this.active.length ) { + this.load( options.active ); + } + }, + + _initialActive: function() { + var active = this.options.active, + collapsible = this.options.collapsible, + locationHash = location.hash.substring( 1 ); if ( active === null ) { // check the fragment identifier in the URL @@ -106,38 +130,16 @@ $.widget( "ui.tabs", { if ( active !== false ) { active = this.tabs.index( this.tabs.eq( active ) ); if ( active === -1 ) { - active = options.collapsible ? false : 0; + active = collapsible ? false : 0; } } - options.active = active; // don't allow collapsible: false and active: false - if ( !options.collapsible && options.active === false && this.anchors.length ) { - options.active = 0; - } - - // Take disabling tabs via class attribute from HTML - // into account and update option properly. - if ( $.isArray( options.disabled ) ) { - options.disabled = $.unique( options.disabled.concat( - $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { - return that.tabs.index( li ); - }) - ) ).sort(); + if ( !collapsible && active === false && this.anchors.length ) { + active = 0; } - // check for length avoids error when initializing empty list - if ( this.options.active !== false && this.anchors.length ) { - this.active = this._findActive( this.options.active ); - } else { - this.active = $(); - } - - this._refresh(); - - if ( this.active.length ) { - this.load( options.active ); - } + return active; }, _getCreateEventData: function() { @@ -148,6 +150,7 @@ $.widget( "ui.tabs", { }, _tabKeydown: function( event ) { + /*jshint maxcomplexity:15*/ var focusedTab = $( this.document[0].activeElement ).closest( "li" ), selectedIndex = this.tabs.index( focusedTab ), goingForward = true; diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index 06f25576a..239492992 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -25,6 +25,9 @@ $.cleanData = function( elems ) { $.widget = function( name, base, prototype ) { var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, namespace = name.split( "." )[ 0 ]; name = name.split( "." )[ 1 ]; @@ -71,38 +74,40 @@ $.widget = function( name, base, prototype ) { // inheriting from basePrototype.options = $.widget.extend( {}, basePrototype.options ); $.each( prototype, function( prop, value ) { - if ( $.isFunction( value ) ) { - prototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); + if ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); }); constructor.prototype = $.widget.extend( basePrototype, { // TODO: remove support for widgetEventPrefix // always use the name + a colon as the prefix, e.g., draggable:start // don't prefix for widgets that aren't DOM-based widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name - }, prototype, { + }, proxiedPrototype, { constructor: constructor, namespace: namespace, widgetName: name, |