diff options
Diffstat (limited to 'scripts/external')
| -rw-r--r-- | scripts/external/jquery-ui.js | 1508 |
1 files changed, 970 insertions, 538 deletions
diff --git a/scripts/external/jquery-ui.js b/scripts/external/jquery-ui.js index c26c4be7..ce8731b0 100644 --- a/scripts/external/jquery-ui.js +++ b/scripts/external/jquery-ui.js @@ -1,4 +1,4 @@ -/*! jQuery UI - v1.11.0 - 2014-06-26 +/*! jQuery UI - v1.11.2 - 2014-10-16 * http://jqueryui.com * Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ @@ -6,8 +6,8 @@ (function( factory ) { if ( typeof define === "function" && define.amd ) { - // AMD. Register as a named module. - define('jquery-ui', [ "jquery" ], factory ); + // AMD. Register as an anonymous module. + define([ "jquery" ], factory ); } else { // Browser globals @@ -15,7 +15,7 @@ } }(function( $ ) { /*! - * jQuery UI Core 1.11.0 + * jQuery UI Core 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -30,7 +30,7 @@ $.ui = $.ui || {}; $.extend( $.ui, { - version: "1.11.0", + version: "1.11.2", keyCode: { BACKSPACE: 8, @@ -54,15 +54,16 @@ $.extend( $.ui, { // plugins $.fn.extend({ - scrollParent: function() { + scrollParent: function( includeHidden ) { var position = this.css( "position" ), excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, scrollParent = this.parents().filter( function() { var parent = $( this ); if ( excludeStaticParent && parent.css( "position" ) === "static" ) { return false; } - return (/(auto|scroll)/).test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); }).eq( 0 ); return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; @@ -99,7 +100,7 @@ function focusable( element, isTabIndexNotNaN ) { if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { return false; } - img = $( "img[usemap=#" + mapName + "]" )[0]; + img = $( "img[usemap='#" + mapName + "']" )[ 0 ]; return !!img && visible( img ); } return ( /input|select|textarea|button|object/.test( nodeName ) ? @@ -308,7 +309,7 @@ $.ui.plugin = { /*! - * jQuery UI Widget 1.11.0 + * jQuery UI Widget 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -324,11 +325,18 @@ var widget_uuid = 0, $.cleanData = (function( orig ) { return function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); + + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + } catch ( e ) {} } orig( elems ); }; @@ -546,10 +554,6 @@ $.Widget.prototype = { this.element = $( element ); this.uuid = widget_uuid++; this.eventNamespace = "." + this.widgetName + this.uuid; - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); this.bindings = $(); this.hoverable = $(); @@ -572,6 +576,11 @@ $.Widget.prototype = { this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); } + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + this._create(); this._trigger( "create", null, this._getCreateEventData() ); this._init(); @@ -734,8 +743,14 @@ $.Widget.prototype = { }, _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + + this.eventNamespace; element.unbind( eventName ).undelegate( eventName ); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $( this.bindings.not( element ).get() ); + this.focusable = $( this.focusable.not( element ).get() ); + this.hoverable = $( this.hoverable.not( element ).get() ); }, _delay: function( handler, delay ) { @@ -841,7 +856,7 @@ var widget = $.widget; /*! - * jQuery UI Mouse 1.11.0 + * jQuery UI Mouse 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -858,7 +873,7 @@ $( document ).mouseup( function() { }); var mouse = $.widget("ui.mouse", { - version: "1.11.0", + version: "1.11.2", options: { cancel: "input,textarea,button,select,option", distance: 1, @@ -899,6 +914,8 @@ var mouse = $.widget("ui.mouse", { return; } + this._mouseMoved = false; + // we may have missed mouseup (out of window) (this._mouseStarted && this._mouseUp(event)); @@ -952,13 +969,23 @@ var mouse = $.widget("ui.mouse", { }, _mouseMove: function(event) { - // IE mouseup check - mouseup happened when mouse was out of window - if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { - return this._mouseUp(event); + // Only check for mouseups outside the document if you've moved inside the document + // at least once. This prevents the firing of mouseup in the case of IE<9, which will + // fire a mousemove event if content is placed under the cursor. See #7778 + // Support: IE <9 + if ( this._mouseMoved ) { + // IE mouseup check - mouseup happened when mouse was out of window + if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { + return this._mouseUp(event); + + // Iframe mouseup check - mouseup occurred in another document + } else if ( !event.which ) { + return this._mouseUp( event ); + } + } - // Iframe mouseup check - mouseup occurred in another document - } else if ( !event.which ) { - return this._mouseUp( event ); + if ( event.which || event.button ) { + this._mouseMoved = true; } if (this._mouseStarted) { @@ -1015,7 +1042,7 @@ var mouse = $.widget("ui.mouse", { /*! - * jQuery UI Position 1.11.0 + * jQuery UI Position 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -1129,8 +1156,11 @@ $.position = { offset: withinElement.offset() || { left: 0, top: 0 }, scrollLeft: withinElement.scrollLeft(), scrollTop: withinElement.scrollTop(), - width: isWindow ? withinElement.width() : withinElement.outerWidth(), - height: isWindow ? withinElement.height() : withinElement.outerHeight() + + // support: jQuery 1.6.x + // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows + width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), + height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() }; } }; @@ -1519,7 +1549,7 @@ var position = $.ui.position; /*! - * jQuery UI Accordion 1.11.0 + * jQuery UI Accordion 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -1531,7 +1561,7 @@ var position = $.ui.position; var accordion = $.widget( "ui.accordion", { - version: "1.11.0", + version: "1.11.2", options: { active: 0, animate: {}, @@ -1765,13 +1795,22 @@ var accordion = $.widget( "ui.accordion", { }, _processPanels: function() { + var prevHeaders = this.headers, + prevPanels = this.panels; + this.headers = this.element.find( this.options.header ) .addClass( "ui-accordion-header ui-state-default ui-corner-all" ); - this.headers.next() + this.panels = this.headers.next() .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) .filter( ":not(.ui-accordion-content-active)" ) .hide(); + + // Avoid memory leaks (#10056) + if ( prevPanels ) { + this._off( prevHeaders.not( this.headers ) ); + this._off( prevPanels.not( this.panels ) ); + } }, _refresh: function() { @@ -2080,7 +2119,7 @@ var accordion = $.widget( "ui.accordion", { /*! - * jQuery UI Menu 1.11.0 + * jQuery UI Menu 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -2092,7 +2131,7 @@ var accordion = $.widget( "ui.accordion", { var menu = $.widget( "ui.menu", { - version: "1.11.0", + version: "1.11.2", defaultElement: "<ul>", delay: 300, options: { @@ -2167,6 +2206,12 @@ var menu = $.widget( "ui.menu", { } }, "mouseenter .ui-menu-item": function( event ) { + // Ignore mouse events while typeahead is active, see #10458. + // Prevents focusing the wrong item when typeahead causes a scroll while the mouse + // is over an item in the menu + if ( this.previousFilter ) { + return; + } 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 @@ -2246,13 +2291,9 @@ var menu = $.widget( "ui.menu", { }, _keydown: function( event ) { - var match, prev, character, skip, regex, + var match, prev, character, skip, preventDefault = true; - function escape( value ) { - return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); - } - switch ( event.keyCode ) { case $.ui.keyCode.PAGE_UP: this.previousPage( event ); @@ -2301,10 +2342,7 @@ var menu = $.widget( "ui.menu", { character = prev + character; } - regex = new RegExp( "^" + escape( character ), "i" ); - match = this.activeMenu.find( this.options.items ).filter(function() { - return regex.test( $( this ).text() ); - }); + match = this._filterMenuItems( character ); match = skip && match.index( this.active.next() ) !== -1 ? this.active.nextAll( ".ui-menu-item" ) : match; @@ -2313,22 +2351,15 @@ var menu = $.widget( "ui.menu", { // to move down the menu to the first item that starts with that character if ( !match.length ) { character = String.fromCharCode( event.keyCode ); - regex = new RegExp( "^" + escape( character ), "i" ); - match = this.activeMenu.find( this.options.items ).filter(function() { - return regex.test( $( this ).text() ); - }); + match = this._filterMenuItems( character ); } if ( match.length ) { this.focus( event, match ); - if ( match.length > 1 ) { - this.previousFilter = character; - this.filterTimer = this._delay(function() { - delete this.previousFilter; - }, 1000 ); - } else { + this.previousFilter = character; + this.filterTimer = this._delay(function() { delete this.previousFilter; - } + }, 1000 ); } else { delete this.previousFilter; } @@ -2700,12 +2731,26 @@ var menu = $.widget( "ui.menu", { this.collapseAll( event, true ); } this._trigger( "select", event, ui ); + }, + + _filterMenuItems: function(character) { + var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), + regex = new RegExp( "^" + escapedCharacter, "i" ); + + return this.activeMenu + .find( this.options.items ) + + // Only match on items, not dividers or other content (#10571) + .filter( ".ui-menu-item" ) + .filter(function() { + return regex.test( $.trim( $( this ).text() ) ); + }); } }); /*! - * jQuery UI Autocomplete 1.11.0 + * jQuery UI Autocomplete 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -2717,7 +2762,7 @@ var menu = $.widget( "ui.menu", { $.widget( "ui.autocomplete", { - version: "1.11.0", + version: "1.11.2", defaultElement: "<input>", options: { appendTo: null, @@ -2820,7 +2865,9 @@ $.widget( "ui.autocomplete", { break; case keyCode.ESCAPE: if ( this.menu.element.is( ":visible" ) ) { - this._value( this.term ); + if ( !this.isMultiLine ) { + this._value( this.term ); + } this.close( event ); // Different browsers have different default behavior for escape // Single press can mean undo or clear @@ -2956,7 +3003,7 @@ $.widget( "ui.autocomplete", { // Announce the value in the liveRegion label = ui.item.attr( "aria-label" ) || item.value; - if ( label && jQuery.trim( label ).length ) { + if ( label && $.trim( label ).length ) { this.liveRegion.children().hide(); $( "<div>" ).text( label ).appendTo( this.liveRegion ); } @@ -3315,7 +3362,7 @@ var autocomplete = $.ui.autocomplete; /*! - * jQuery UI Button 1.11.0 + * jQuery UI Button 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -3354,7 +3401,7 @@ var lastActive, }; $.widget( "ui.button", { - version: "1.11.0", + version: "1.11.2", defaultElement: "<button>", options: { disabled: null, @@ -3650,7 +3697,7 @@ $.widget( "ui.button", { }); $.widget( "ui.buttonset", { - version: "1.11.0", + version: "1.11.2", options: { items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" }, @@ -3712,7 +3759,7 @@ var button = $.ui.button; /*! - * jQuery UI Datepicker 1.11.0 + * jQuery UI Datepicker 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -3723,7 +3770,7 @@ var button = $.ui.button; */ -$.extend($.ui, { datepicker: { version: "1.11.0" } }); +$.extend($.ui, { datepicker: { version: "1.11.2" } }); var datepicker_instActive; @@ -4499,12 +4546,16 @@ $.extend(Datepicker.prototype, { datepicker_instActive = inst; // for delegate hover events inst.dpDiv.empty().append(this._generateHTML(inst)); this._attachHandlers(inst); - inst.dpDiv.find("." + this._dayOverClass + " a"); var origyearshtml, numMonths = this._getNumberOfMonths(inst), cols = numMonths[1], - width = 17; + width = 17, + activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); + + if ( activeCell.length > 0 ) { + datepicker_handleMouseover.apply( activeCell.get( 0 ) ); + } inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); if (cols > 1) { @@ -4838,7 +4889,8 @@ $.extend(Datepicker.prototype, { var isDoubled = lookAhead(match), size = (match === "@" ? 14 : (match === "!" ? 20 : (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), - digits = new RegExp("^\\d{1," + size + "}"), + minSize = (match === "y" ? size : 1), + digits = new RegExp("^\\d{" + minSize + "," + size + "}"), num = value.substring(iValue).match(digits); if (!num) { throw "Missing number at position " + iValue; @@ -5699,18 +5751,20 @@ function datepicker_bindHover(dpDiv) { $(this).removeClass("ui-datepicker-next-hover"); } }) - .delegate(selector, "mouseover", function(){ - if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? dpDiv.parent()[0] : datepicker_instActive.input[0])) { - $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); - $(this).addClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).addClass("ui-datepicker-prev-hover"); - } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).addClass("ui-datepicker-next-hover"); - } - } - }); + .delegate( selector, "mouseover", datepicker_handleMouseover ); +} + +function datepicker_handleMouseover() { + if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { + $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); + $(this).addClass("ui-state-hover"); + if (this.className.indexOf("ui-datepicker-prev") !== -1) { + $(this).addClass("ui-datepicker-prev-hover"); + } + if (this.className.indexOf("ui-datepicker-next") !== -1) { + $(this).addClass("ui-datepicker-next-hover"); + } + } } /* jQuery extend now ignores nulls! */ @@ -5766,13 +5820,13 @@ $.fn.datepicker = function(options){ $.datepicker = new Datepicker(); // singleton instance $.datepicker.initialized = false; $.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.11.0"; +$.datepicker.version = "1.11.2"; var datepicker = $.datepicker; /*! - * jQuery UI Draggable 1.11.0 + * jQuery UI Draggable 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -5784,7 +5838,7 @@ var datepicker = $.datepicker; $.widget("ui.draggable", $.ui.mouse, { - version: "1.11.0", + version: "1.11.2", widgetEventPrefix: "drag", options: { addClasses: true, @@ -5819,8 +5873,8 @@ $.widget("ui.draggable", $.ui.mouse, { }, _create: function() { - if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { - this.element[0].style.position = "relative"; + if ( this.options.helper === "original" ) { + this._setPositionRelative(); } if (this.options.addClasses){ this.element.addClass("ui-draggable"); @@ -5836,6 +5890,7 @@ $.widget("ui.draggable", $.ui.mouse, { _setOption: function( key, value ) { this._super( key, value ); if ( key === "handle" ) { + this._removeHandleClassName(); this._setHandleClassName(); } }, @@ -5851,20 +5906,9 @@ $.widget("ui.draggable", $.ui.mouse, { }, _mouseCapture: function(event) { + var o = this.options; - var document = this.document[ 0 ], - o = this.options; - - // support: IE9 - // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> - try { - // Support: IE9+ - // If the <body> is blurred, IE will switch windows, see #9520 - if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { - // Blur any element that currently has focus, see #4261 - $( document.activeElement ).blur(); - } - } catch ( error ) {} + this._blurActiveElement( event ); // among others, prevent a drag on a resizable-handle if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { @@ -5877,20 +5921,54 @@ $.widget("ui.draggable", $.ui.mouse, { return false; } - $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { - $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") - .css({ - width: this.offsetWidth + "px", height: this.offsetHeight + "px", - position: "absolute", opacity: "0.001", zIndex: 1000 - }) - .css($(this).offset()) - .appendTo("body"); - }); + this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); return true; }, + _blockFrames: function( selector ) { + this.iframeBlocks = this.document.find( selector ).map(function() { + var iframe = $( this ); + + return $( "<div>" ) + .css( "position", "absolute" ) + .appendTo( iframe.parent() ) + .outerWidth( iframe.outerWidth() ) + .outerHeight( iframe.outerHeight() ) + .offset( iframe.offset() )[ 0 ]; + }); + }, + + _unblockFrames: function() { + if ( this.iframeBlocks ) { + this.iframeBlocks.remove(); + delete this.iframeBlocks; + } + }, + + _blurActiveElement: function( event ) { + var document = this.document[ 0 ]; + + // Only need to blur if the event occurred on the draggable itself, see #10527 + if ( !this.handleElement.is( event.target ) ) { + return; + } + + // support: IE9 + // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> + try { + + // Support: IE9, IE10 + // If the <body> is blurred, IE will switch windows, see #9520 + if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { + + // Blur any element that currently has focus, see #4261 + $( document.activeElement ).blur(); + } + } catch ( error ) {} + }, + _mouseStart: function(event) { var o = this.options; @@ -5918,28 +5996,15 @@ $.widget("ui.draggable", $.ui.mouse, { //Store the helper's css position this.cssPosition = this.helper.css( "position" ); - this.scrollParent = this.helper.scrollParent(); + this.scrollParent = this.helper.scrollParent( true ); this.offsetParent = this.helper.offsetParent(); - this.offsetParentCssPosition = this.offsetParent.css( "position" ); + this.hasFixedAncestor = this.helper.parents().filter(function() { + return $( this ).css( "position" ) === "fixed"; + }).length > 0; //The element's absolute position on the page minus margins - this.offset = this.positionAbs = this.element.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - //Reset scroll cache - this.offset.scroll = false; - - $.extend(this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper - }); + this.positionAbs = this.element.offset(); + this._refreshOffsets( event ); //Generate the original position this.originalPosition = this.position = this._generatePosition( event, false ); @@ -5966,6 +6031,10 @@ $.widget("ui.draggable", $.ui.mouse, { $.ui.ddmanager.prepareOffsets(this, event); } + // Reset helper's right/bottom css if they're set and set explicit width/height instead + // as this prevents resizing of elements with right/bottom set (see #7772) + this._normalizeRightBottom(); + this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) @@ -5976,9 +6045,24 @@ $.widget("ui.draggable", $.ui.mouse, { return true; }, + _refreshOffsets: function( event ) { + this.offset = { + top: this.positionAbs.top - this.margins.top, + left: this.positionAbs.left - this.margins.left, + scroll: false, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() + }; + + this.offset.click = { + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }; + }, + _mouseDrag: function(event, noPropagation) { // reset any necessary cached properties (see #5009) - if ( this.offsetParentCssPosition === "fixed" ) { + if ( this.hasFixedAncestor ) { this.offset.parent = this._getParentOffset(); } @@ -6036,19 +6120,19 @@ $.widget("ui.draggable", $.ui.mouse, { return false; }, - _mouseUp: function(event) { - //Remove frame helpers - $("div.ui-draggable-iframeFix").each(function() { - this.parentNode.removeChild(this); - }); + _mouseUp: function( event ) { + this._unblockFrames(); //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) if ( $.ui.ddmanager ) { $.ui.ddmanager.dragStop(this, event); } - // The interaction is over; whether or not the click resulted in a drag, focus the element - this.element.focus(); + // Only need to focus if the event occurred on the draggable itself, see #10527 + if ( this.handleElement.is( event.target ) ) { + // The interaction is over; whether or not the click resulted in a drag, focus the element + this.element.focus(); + } return $.ui.mouse.prototype._mouseUp.call(this, event); }, @@ -6072,25 +6156,36 @@ $.widget("ui.draggable", $.ui.mouse, { }, _setHandleClassName: function() { - this._removeHandleClassName(); - $( this.options.handle || this.element ).addClass( "ui-draggable-handle" ); + this.handleElement = this.options.handle ? + this.element.find( this.options.handle ) : this.element; + this.handleElement.addClass( "ui-draggable-handle" ); }, _removeHandleClassName: function() { - this.element.find( ".ui-draggable-handle" ) - .addBack() - .removeClass( "ui-draggable-handle" ); + this.handleElement.removeClass( "ui-draggable-handle" ); }, _createHelper: function(event) { var o = this.options, - helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[ 0 ], [ event ])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); + helperIsFunction = $.isFunction( o.helper ), + helper = helperIsFunction ? + $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : + ( o.helper === "clone" ? + this.element.clone().removeAttr( "id" ) : + this.element ); if (!helper.parents("body").length) { helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); } + // http://bugs.jqueryui.com/ticket/9446 + // a helper function can return the original element + // which wouldn't have been set to relative in _create + if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { + this._setPositionRelative(); + } + if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { helper.css("position", "absolute"); } @@ -6099,6 +6194,12 @@ $.widget("ui.draggable", $.ui.mouse, { }, + _setPositionRelative: function() { + if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { + this.element[ 0 ].style.position = "relative"; + } + }, + _adjustOffsetFromHelper: function(obj) { if (typeof obj === "string") { obj = obj.split(" "); @@ -6144,8 +6245,8 @@ $.widget("ui.draggable", $.ui.mouse, { } return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) }; }, @@ -6167,10 +6268,10 @@ $.widget("ui.draggable", $.ui.mouse, { _cacheMargins: function() { this.margins = { - left: (parseInt(this.element.css("marginLeft"),10) || 0), - top: (parseInt(this.element.css("marginTop"),10) || 0), - right: (parseInt(this.element.css("marginRight"),10) || 0), - bottom: (parseInt(this.element.css("marginBottom"),10) || 0) + left: (parseInt(this.element.css("marginLeft"), 10) || 0), + top: (parseInt(this.element.css("marginTop"), 10) || 0), + right: (parseInt(this.element.css("marginRight"), 10) || 0), + bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) }; }, @@ -6183,11 +6284,11 @@ $.widget("ui.draggable", $.ui.mouse, { _setContainment: function() { - var over, c, ce, + var isUserScrollable, c, ce, o = this.options, document = this.document[ 0 ]; - this.relative_container = null; + this.relativeContainer = null; if ( !o.containment ) { this.containment = null; @@ -6230,15 +6331,25 @@ $.widget("ui.draggable", $.ui.mouse, { return; } - over = c.css( "overflow" ) !== "hidden"; + isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); this.containment = [ ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), - ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right, - ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom + ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - + ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - + this.helperProportions.width - + this.margins.left - + this.margins.right, + ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - + ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - + this.helperProportions.height - + this.margins.top - + this.margins.bottom ]; - this.relative_container = c; + this.relativeContainer = c; }, _convertPositionTo: function(d, pos) { @@ -6291,8 +6402,8 @@ $.widget("ui.draggable", $.ui.mouse, { // If we are not dragging yet, we won't check for options if ( constrainPosition ) { if ( this.containment ) { - if ( this.relative_container ){ - co = this.relative_container.offset(); + if ( this.relativeContainer ){ + co = this.relativeContainer.offset(); containment = [ this.containment[ 0 ] + co.left, this.containment[ 1 ] + co.top, @@ -6366,16 +6477,29 @@ $.widget("ui.draggable", $.ui.mouse, { } }, + _normalizeRightBottom: function() { + if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) { + this.helper.width( this.helper.width() ); + this.helper.css( "right", "auto" ); + } + if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) { + this.helper.height( this.helper.height() ); + this.helper.css( "bottom", "auto" ); + } + }, + // From now on bulk stuff - mainly helpers - _trigger: function(type, event, ui) { + _trigger: function( type, event, ui ) { ui = ui || this._uiHash(); $.ui.plugin.call( this, type, [ event, ui, this ], true ); - //The absolute position has to be recalculated after plugins - if (type === "drag") { - this.positionAbs = this._convertPositionTo("absolute"); + + // Absolute position and offset (see #6884 ) have to be recalculated after plugins + if ( /^(drag|start|stop)/.test( type ) ) { + this.positionAbs = this._convertPositionTo( "absolute" ); + ui.offset = this.positionAbs; } - return $.Widget.prototype._trigger.call(this, type, event, ui); + return $.Widget.prototype._trigger.call( this, type, event, ui ); }, plugins: {}, @@ -6391,160 +6515,197 @@ $.widget("ui.draggable", $.ui.mouse, { }); -$.ui.plugin.add("draggable", "connectToSortable", { - start: function( event, ui, inst ) { +$.ui.plugin.add( "draggable", "connectToSortable", { + start: function( event, ui, draggable ) { + var uiSortable = $.extend( {}, ui, { + item: draggable.element + }); - var o = inst.options, - uiSortable = $.extend({}, ui, { item: inst.element }); - inst.sortables = []; - $(o.connectToSortable).each(function() { + draggable.sortables = []; + $( draggable.options.connectToSortable ).each(function() { var sortable = $( this ).sortable( "instance" ); - if (sortable && !sortable.options.disabled) { - inst.sortables.push({ - instance: sortable, - shouldRevert: sortable.options.revert - }); - sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). + + if ( sortable && !sortable.options.disabled ) { + draggable.sortables.push( sortable ); + + // refreshPositions is called at drag start to refresh the containerCache + // which is used in drag. This ensures it's initialized and synchronized + // with any changes that might have happened on the page since initialization. + sortable.refreshPositions(); sortable._trigger("activate", event, uiSortable); } }); - }, - stop: function( event, ui, inst ) { - - //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper + stop: function( event, ui, draggable ) { var uiSortable = $.extend( {}, ui, { - item: inst.element + item: draggable.element }); - $.each(inst.sortables, function() { - if (this.instance.isOver) { + draggable.cancelHelperRemoval = false; - this.instance.isOver = 0; + $.each( draggable.sortables, function() { + var sortable = this; - inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance - this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) + if ( sortable.isOver ) { + sortable.isOver = 0; - //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" - if (this.shouldRevert) { - this.instance.options.revert = this.shouldRevert; - } - - //Trigger the stop of the sortable - this.instance._mouseStop(event); + // Allow this sortable to handle removing the helper + draggable.cancelHelperRemoval = true; + sortable.cancelHelperRemoval = false; - this.instance.options.helper = this.instance.options._helper; + // Use _storedCSS To restore properties in the sortable, + // as this also handles revert (#9675) since the draggable + // may have modified them in unexpected ways (#8809) + sortable._storedCSS = { + position: sortable.placeholder.css( "position" ), + top: sortable.placeholder.css( "top" ), + left: sortable.placeholder.css( "left" ) + }; - //If the helper has been the original item, restore properties in the sortable - if (inst.options.helper === "original") { - this.instance.currentItem.css({ top: "auto", left: "auto" }); - } + sortable._mouseStop(event); + // Once drag has ended, the sortable should return to using + // its original helper, not the shared helper from draggable + sortable.options.helper = sortable.options._helper; } else { - this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance - this.instance._trigger("deactivate", event, uiSortable); - } + // Prevent this Sortable from removing the helper. + // However, don't set the draggable to remove the helper + // either as another connected Sortable may yet handle the removal. + sortable.cancelHelperRemoval = true; + sortable._trigger( "deactivate", event, uiSortable ); + } }); - }, - drag: function( event, ui, inst ) { - - var that = this; - - $.each(inst.sortables, function() { - + drag: function( event, ui, draggable ) { + $.each( draggable.sortables, function() { var innermostIntersecting = false, - thisSortable = this; + sortable = this; - //Copy over some variables to allow calling the sortable's native _intersectsWith - this.instance.positionAbs = inst.positionAbs; - this.instance.helperProportions = inst.helperProportions; - this.instance.offset.click = inst.offset.click; + // Copy over variables that sortable's _intersectsWith uses + sortable.positionAbs = draggable.positionAbs; + sortable.helperProportions = draggable.helperProportions; + sortable.offset.click = draggable.offset.click; - if (this.instance._intersectsWith(this.instance.containerCache)) { + if ( sortable._intersectsWith( sortable.containerCache ) ) { innermostIntersecting = true; - $.each(inst.sortables, function() { - this.instance.positionAbs = inst.positionAbs; - this.instance.helperProportions = inst.helperProportions; - this.instance.offset.click = inst.offset.click; - if (this !== thisSortable && - this.instance._intersectsWith(this.instance.containerCache) && - $.contains(thisSortable.instance.element[0], this.instance.element[0]) - ) { + + $.each( draggable.sortables, function() { + // Copy over variables that sortable's _intersectsWith uses + this.positionAbs = draggable.positionAbs; + this.helperProportions = draggable.helperProportions; + this.offset.click = draggable.offset.click; + + if ( this !== sortable && + this._intersectsWith( this.containerCache ) && + $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { innermostIntersecting = false; } + return innermostIntersecting; }); } - if (innermostIntersecting) { - //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once - if (!this.instance.isOver) { + if ( innermostIntersecting ) { + // If it intersects, we use a little isOver variable and set it once, + // so that the move-in stuff gets fired only once. + if ( !sortable.isOver ) { + sortable.isOver = 1; - this.instance.isOver = 1; - //Now we fake the start of dragging for the sortable instance, - //by cloning the list group item, appending it to the sortable and using it as inst.currentItem - //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) - this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); - this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it - this.instance.options.helper = function() { return ui.helper[0]; }; + sortable.currentItem = ui.helper + .appendTo( sortable.element ) + .data( "ui-sortable-item", true ); - event.target = this.instance.currentItem[0]; - this.instance._mouseCapture(event, true); - this.instance._mouseStart(event, true, true); + // Store helper option to later restore it + sortable.options._helper = sortable.options.helper; - //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes - this.instance.offset.click.top = inst.offset.click.top; - this.instance.offset.click.left = inst.offset.click.left; - this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; - this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; + sortable.options.helper = function() { + return ui.helper[ 0 ]; + }; - inst._trigger("toSortable", event); - inst.dropped = this.instance.element; //draggable revert needs that - //hack so receive/update callbacks work (mostly) - inst.currentItem = inst.element; - this.instance.fromOutside = inst; + // Fire the start events of the sortable with our passed browser event, + // and our own helper (so it doesn't create a new one) + event.target = sortable.currentItem[ 0 ]; + sortable._mouseCapture( event, true ); + sortable._mouseStart( event, true, true ); - } + // Because the browser event is way off the new appended portlet, + // modify necessary variables to reflect the changes + sortable.offset.click.top = draggable.offset.click.top; + sortable.offset.click.left = draggable.offset.click.left; + sortable.offset.parent.left -= draggable.offset.parent.left - + sortable.offset.parent.left; + sortable.offset.parent.top -= draggable.offset.parent.top - + sortable.offset.parent.top; + + draggable._trigger( "toSortable", event ); - //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable - if (this.instance.currentItem) { - this.instance._mouseDrag(event); + // Inform draggable that the helper is in a valid drop zone, + // used solely in the revert option to handle "valid/invalid". + draggable.dropped = sortable.element; + + // Need to refreshPositions of all sortables in the case that + // adding to one sortable changes the location of the other sortables (#9675) + $.each( draggable.sortables, function() { + this.refreshPositions(); + }); + + // hack so receive/update callbacks work (mostly) + draggable.currentItem = draggable.element; + sortable.fromOutside = draggable; } + if ( sortable.currentItem ) { + sortable._mouseDrag( event ); + // Copy the sortable's position because the draggable's can potentially reflect + // a relative position, while sortable is always absolute, which the dragged + // element has now become. (#8809) + ui.position = sortable.position; + } } else { + // If it doesn't intersect with the sortable, and it intersected before, + // we fake the drag stop of the sortable, but make sure it doesn't remove + // the helper by using cancelHelperRemoval. + if ( sortable.isOver ) { - //If it doesn't intersect with the sortable, and it intersected before, - //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval - if (this.instance.isOver) { - - this.instance.isOver = 0; - this.instance.cancelHelperRemoval = true; + sortable.isOver = 0; + sortable.cancelHelperRemoval = true; - //Prevent reverting on this forced stop - this.instance.options.revert = false; + // Calling sortable's mouseStop would trigger a revert, + // so revert must be temporarily false until after mouseStop is called. + sortable.options._revert = sortable.options.revert; + sortable.options.revert = false; - // The out event needs to be triggered independently - this.instance._trigger("out", event, this.instance._uiHash(this.instance)); + sortable._trigger( "out", event, sortable._uiHash( sortable ) ); + sortable._mouseStop( event, true ); - this.instance._mouseStop(event, true); - this.instance.options.helper = this.instance.options._helper; + // restore sortable behaviors that were modfied + // when the draggable entered the sortable area (#9481) + sortable.options.revert = sortable.options._revert; + sortable.options.helper = sortable.options._helper; - //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size - this.instance.currentItem.remove(); - if (this.instance.placeholder) { - this.instance.placeholder.remove(); + if ( sortable.placeholder ) { + sortable.placeholder.remove(); } - inst._trigger("fromSortable", event); - inst.dropped = false; //draggable revert needs that - } + // Recalculate the draggable's offset considering the sortable + // may have modified them in unexpected ways (#8809) + draggable._refreshOffsets( event ); + ui.position = draggable._generatePosition( event, true ); - } + draggable._trigger( "fromSortable", event ); - }); + // Inform draggable that the helper is no longer in a valid drop zone + draggable.dropped = false; + // Need to refreshPositions of all sortables just in case removing + // from one sortable changes the location of other sortables (#9675) + $.each( draggable.sortables, function() { + this.refreshPositions(); + }); + } + } + }); } }); @@ -6585,30 +6746,35 @@ $.ui.plugin.add("draggable", "opacity", { $.ui.plugin.add("draggable", "scroll", { start: function( event, ui, i ) { - if ( i.scrollParent[ 0 ] !== i.document[ 0 ] && i.scrollParent[ 0 ].tagName !== "HTML" ) { - i.overflowOffset = i.scrollParent.offset(); + if ( !i.scrollParentNotHidden ) { + i.scrollParentNotHidden = i.helper.scrollParent( false ); + } + + if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { + i.overflowOffset = i.scrollParentNotHidden.offset(); } }, drag: function( event, ui, i ) { var o = i.options, scrolled = false, + scrollParent = i.scrollParentNotHidden[ 0 ], document = i.document[ 0 ]; - if ( i.scrollParent[ 0 ] !== document && i.scrollParent[ 0 ].tagName !== "HTML" ) { - if (!o.axis || o.axis !== "x") { - if ((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; - } else if (event.pageY - i.overflowOffset.top < o.scrollSensitivity) { - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; + if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { + if ( !o.axis || o.axis !== "x" ) { + if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; + } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; } } - if (!o.axis || o.axis !== "y") { - if ((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; - } else if (event.pageX - i.overflowOffset.left < o.scrollSensitivity) { - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; + if ( !o.axis || o.axis !== "y" ) { + if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; + } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; } } @@ -6669,9 +6835,9 @@ $.ui.plugin.add("draggable", "snap", { for (i = inst.snapElements.length - 1; i >= 0; i--){ - l = inst.snapElements[i].left; + l = inst.snapElements[i].left - inst.margins.left; r = l + inst.snapElements[i].width; - t = inst.snapElements[i].top; + t = inst.snapElements[i].top - inst.margins.top; b = t + inst.snapElements[i].height; if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { @@ -6688,16 +6854,16 @@ $.ui.plugin.add("draggable", "snap", { ls = Math.abs(l - x2) <= d; rs = Math.abs(r - x1) <= d; if (ts) { - ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; + ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top; } if (bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; + ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top; } if (ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left; } if (rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left; } } @@ -6709,16 +6875,16 @@ $.ui.plugin.add("draggable", "snap", { ls = Math.abs(l - x1) <= d; rs = Math.abs(r - x2) <= d; if (ts) { - ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; + ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top; } if (bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; + ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top; } if (ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left; } if (rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left; } } @@ -6736,8 +6902,8 @@ $.ui.plugin.add("draggable", "stack", { start: function( event, ui, instance ) { var min, o = instance.options, - group = $.makeArray($(o.stack)).sort(function(a,b) { - return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); + group = $.makeArray($(o.stack)).sort(function(a, b) { + return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0); }); if (!group.length) { return; } @@ -6773,7 +6939,7 @@ var draggable = $.ui.draggable; /*! - * jQuery UI Resizable 1.11.0 + * jQuery UI Resizable 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -6785,7 +6951,7 @@ var draggable = $.ui.draggable; $.widget("ui.resizable", $.ui.mouse, { - version: "1.11.0", + version: "1.11.2", widgetEventPrefix: "resize", options: { alsoResize: false, @@ -6817,7 +6983,7 @@ $.widget("ui.resizable", $.ui.mouse, { }, _isNumber: function( value ) { - return !isNaN( parseInt( value , 10 ) ); + return !isNaN( parseInt( value, 10 ) ); }, _hasScroll: function( el, a ) { @@ -6858,7 +7024,7 @@ $.widget("ui.resizable", $.ui.mouse, { }); // Wrap the element if it cannot hold child nodes - if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { + if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { this.element.wrap( $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ @@ -6876,14 +7042,28 @@ $.widget("ui.resizable", $.ui.mouse, { this.elementIsWrapper = true; - this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); - this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); + this.element.css({ + marginLeft: this.originalElement.css("marginLeft"), + marginTop: this.originalElement.css("marginTop"), + marginRight: this.originalElement.css("marginRight"), + marginBottom: this.originalElement.css("marginBottom") + }); + this.originalElement.css({ + marginLeft: 0, + marginTop: 0, + marginRight: 0, + marginBottom: 0 + }); // support: Safari // Prevent Safari textarea resize this.originalResizeStyle = this.originalElement.css("resize"); this.originalElement.css("resize", "none"); - this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); + this._proportionallyResizeElements.push( this.originalElement.css({ + position: "static", + zoom: 1, + display: "block" + }) ); // support: IE9 // avoid IE jump (hard set the margin) @@ -6892,8 +7072,20 @@ $.widget("ui.resizable", $.ui.mouse, { this._proportionallyResize(); } - this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" }); - if(this.handles.constructor === String) { + this.handles = o.handles || + ( !$(".ui-resizable-handle", this.element).length ? + "e,s,se" : { + n: ".ui-resizable-n", + e: ".ui-resizable-e", + s: ".ui-resizable-s", + w: ".ui-resizable-w", + se: ".ui-resizable-se", + sw: ".ui-resizable-sw", + ne: ".ui-resizable-ne", + nw: ".ui-resizable-nw" + } ); + + if (this.handles.constructor === String) { if ( this.handles === "all") { this.handles = "n,e,s,w,se,sw,ne,nw"; @@ -6902,10 +7094,10 @@ $.widget("ui.resizable", $.ui.mouse, { n = this.handles.split(","); this.handles = {}; - for(i = 0; i < n.length; i++) { + for (i = 0; i < n.length; i++) { handle = $.trim(n[i]); - hname = "ui-resizable-"+handle; + hname = "ui-resizable-" + handle; axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); axis.css({ zIndex: o.zIndex }); @@ -6915,7 +7107,7 @@ $.widget("ui.resizable", $.ui.mouse, { axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); } - this.handles[handle] = ".ui-resizable-"+handle; + this.handles[handle] = ".ui-resizable-" + handle; this.element.append(axis); } @@ -6927,9 +7119,9 @@ $.widget("ui.resizable", $.ui.mouse, { target = target || this.element; - for(i in this.handles) { + for (i in this.handles) { - if(this.handles[i].constructor === String) { + if (this.handles[i].constructor === String) { this.handles[i] = this.element.children( this.handles[ i ] ).first().show(); } @@ -6951,7 +7143,7 @@ $.widget("ui.resizable", $.ui.mouse, { } // TODO: What's that good for? There's not anything to be executed left - if(!$(this.handles[i]).length) { + if (!$(this.handles[i]).length) { continue; } } @@ -6983,7 +7175,7 @@ $.widget("ui.resizable", $.ui.mouse, { $(this).removeClass("ui-resizable-autohide"); that._handles.show(); }) - .mouseleave(function(){ + .mouseleave(function() { if (o.disabled) { return; } @@ -7004,8 +7196,13 @@ $.widget("ui.resizable", $.ui.mouse, { var wrapper, _destroy = function(exp) { - $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") - .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); + $(exp) + .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") + .removeData("resizable") + .removeData("ui-resizable") + .unbind(".resizable") + .find(".ui-resizable-handle") + .remove(); }; // TODO: Unwrap at same DOM position @@ -7062,13 +7259,34 @@ $.widget("ui.resizable", $.ui.mouse, { this.offset = this.helper.offset(); this.position = { left: curleft, top: curtop }; - this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() }; - this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; + + this.size = this._helper ? { + width: this.helper.width(), + height: this.helper.height() + } : { + width: el.width(), + height: el.height() + }; + + this.originalSize = this._helper ? { + width: el.outerWidth(), + height: el.outerHeight() + } : { + width: el.width(), + height: el.height() + }; + + this.sizeDiff = { + width: el.outerWidth() - el.width(), + height: el.outerHeight() - el.height() + }; + this.originalPosition = { left: curleft, top: curtop }; - this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; this.originalMousePosition = { left: event.pageX, top: event.pageY }; - this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); + this.aspectRatio = (typeof o.aspectRatio === "number") ? + o.aspectRatio : + ((this.originalSize.width / this.originalSize.height) || 1); cursor = $(".ui-resizable-" + this.axis).css("cursor"); $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); @@ -7080,28 +7298,20 @@ $.widget("ui.resizable", $.ui.mouse, { _mouseDrag: function(event) { - var data, - el = this.helper, props = {}, + var data, props, smp = this.originalMousePosition, a = this.axis, - dx = (event.pageX-smp.left)||0, - dy = (event.pageY-smp.top)||0, + dx = (event.pageX - smp.left) || 0, + dy = (event.pageY - smp.top) || 0, trigger = this._change[a]; - this.prevPosition = { - top: this.position.top, - left: this.position.left - }; - this.prevSize = { - width: this.size.width, - height: this.size.height - }; + this._updatePrevProperties(); if (!trigger) { return false; } - data = trigger.apply(this, [event, dx, dy]); + data = trigger.apply(this, [ event, dx, dy ]); this._updateVirtualBoundaries(event.shiftKey); if (this._aspectRatio || event.shiftKey) { @@ -7114,26 +7324,16 @@ $.widget("ui.resizable", $.ui.mouse, { this._propagate("resize", event); - if ( this.position.top !== this.prevPosition.top ) { - props.top = this.position.top + "px"; - } - if ( this.position.left !== this.prevPosition.left ) { - props.left = this.position.left + "px"; - } - if ( this.size.width !== this.prevSize.width ) { - props.width = this.size.width + "px"; - } - if ( this.size.height !== this.prevSize.height ) { - props.height = this.size.height + "px"; - } - el.css( props ); + props = this._applyChanges(); if ( !this._helper && this._proportionallyResizeElements.length ) { this._proportionallyResize(); } if ( !$.isEmptyObject( props ) ) { + this._updatePrevProperties(); this._trigger( "resize", event, this.ui() ); + this._applyChanges(); } return false; @@ -7145,16 +7345,21 @@ $.widget("ui.resizable", $.ui.mouse, { var pr, ista, soffseth, soffsetw, s, left, top, o = this.options, that = this; - if(this._helper) { + if (this._helper) { pr = this._proportionallyResizeElements; ista = pr.length && (/textarea/i).test(pr[0].nodeName); - soffseth = ista && this._hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; + soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height; soffsetw = ista ? 0 : that.sizeDiff.width; - s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; - left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; - top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; + s = { + width: (that.helper.width() - soffsetw), + height: (that.helper.height() - soffseth) + }; + left = (parseInt(that.element.css("left"), 10) + + (that.position.left - that.originalPosition.left)) || null; + top = (parseInt(that.element.css("top"), 10) + + (that.position.top - that.originalPosition.top)) || null; if (!o.animate) { this.element.css($.extend(s, { top: top, left: left })); @@ -7182,6 +7387,38 @@ $.widget("ui.resizable", $.ui.mouse, { }, + _updatePrevProperties: function() { + this.prevPosition = { + top: this.position.top, + left: this.position.left + }; + this.prevSize = { + width: this.size.width, + height: this.size.height + }; + }, + + _applyChanges: function() { + var props = {}; + + if ( this.position.top !== this.prevPosition.top ) { + props.top = this.position.top + "px"; + } + if ( this.position.left !== this.prevPosition.left ) { + props.left = this.position.left + "px"; + } + if ( this.size.width !== this.prevSize.width ) { + props.width = this.size.width + "px"; + } + if ( this.size.height !== this.prevSize.height ) { + props.height = this.size.height + "px"; + } + + this.helper.css( props ); + + return props; + }, + _updateVirtualBoundaries: function(forceAspectRatio) { var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, o = this.options; @@ -7193,22 +7430,22 @@ $.widget("ui.resizable", $.ui.mouse, { maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity }; - if(this._aspectRatio || forceAspectRatio) { + if (this._aspectRatio || forceAspectRatio) { pMinWidth = b.minHeight * this.aspectRatio; pMinHeight = b.minWidth / this.aspectRatio; pMaxWidth = b.maxHeight * this.aspectRatio; pMaxHeight = b.maxWidth / this.aspectRatio; - if(pMinWidth > b.minWidth) { + if (pMinWidth > b.minWidth) { b.minWidth = pMinWidth; } - if(pMinHeight > b.minHeight) { + if (pMinHeight > b.minHeight) { b.minHeight = pMinHeight; } - if(pMaxWidth < b.maxWidth) { + if (pMaxWidth < b.maxWidth) { b.maxWidth = pMaxWidth; } - if(pMaxHeight < b.maxHeight) { + if (pMaxHeight < b.maxHeight) { b.maxHeight = pMaxHeight; } } @@ -7259,8 +7496,10 @@ $.widget("ui.resizable", $.ui.mouse, { var o = this._vBoundaries, a = this.axis, - ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), - isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), + ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), + ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), + isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), + isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height, cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); @@ -7300,32 +7539,56 @@ $.widget("ui.resizable", $.ui.mouse, { return data; }, + _getPaddingPlusBorderDimensions: function( element ) { + var i = 0, + widths = [], + borders = [ + element.css( "borderTopWidth" ), + element.css( "borderRightWidth" ), + element.css( "borderBottomWidth" ), + element.css( "borderLeftWidth" ) + ], + paddings = [ + element.css( "paddingTop" ), + element.css( "paddingRight" ), + element.css( "paddingBottom" ), + element.css( "paddingLeft" ) + ]; + + for ( ; i < 4; i++ ) { + widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 ); + widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 ); + } + + return { + height: widths[ 0 ] + widths[ 2 ], + width: widths[ 1 ] + widths[ 3 ] + }; + }, + _proportionallyResize: function() { if (!this._proportionallyResizeElements.length) { return; } - var i, j, borders, paddings, prel, + var prel, + i = 0, element = this.helper || this.element; - for ( i=0; i < this._proportionallyResizeElements.length; i++) { + for ( ; i < this._proportionallyResizeElements.length; i++) { prel = this._proportionallyResizeElements[i]; - if (!this.borderDif) { - this.borderDif = []; - borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; - paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; - - for ( j = 0; j < borders.length; j++ ) { - this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); - } + // TODO: Seems like a bug to cache this.outerDimensions + // considering that we are in a loop. + if (!this.outerDimensions) { + this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); } prel.css({ - height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, - width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 + height: (element.height() - this.outerDimensions.height) || 0, + width: (element.width() - this.outerDimensions.width) || 0 }); } @@ -7337,7 +7600,7 @@ $.widget("ui.resizable", $.ui.mouse, { var el = this.element, o = this.options; this.elementOffset = el.offset(); - if(this._helper) { + if (this._helper) { this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); @@ -7345,8 +7608,8 @@ $.widget("ui.resizable", $.ui.mouse, { width: this.element.outerWidth() - 1, height: this.element.outerHeight() - 1, position: "absolute", - left: this.elementOffset.left +"px", - top: this.elementOffset.top +"px", + left: this.elementOffset.left + "px", + top: this.elementOffset.top + "px", zIndex: ++o.zIndex //TODO: Don't modify option }); @@ -7376,21 +7639,25 @@ $.widget("ui.resizable", $.ui.mouse, { return { height: this.originalSize.height + dy }; }, se: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); + return $.extend(this._change.s.apply(this, arguments), + this._change.e.apply(this, [ event, dx, dy ])); }, sw: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); + return $.extend(this._change.s.apply(this, arguments), + this._change.w.apply(this, [ event, dx, dy ])); }, ne: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); + return $.extend(this._change.n.apply(this, arguments), + this._change.e.apply(this, [ event, dx, dy ])); }, nw: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); + return $.extend(this._change.n.apply(this, arguments), + this._change.w.apply(this, [ event, dx, dy ])); } }, _propagate: function(n, event) { - $.ui.plugin.call(this, n, [event, this.ui()]); + $.ui.plugin.call(this, n, [ event, this.ui() ]); (n !== "resize" && this._trigger(n, event, this.ui())); }, @@ -7404,9 +7671,7 @@ $.widget("ui.resizable", $.ui.mouse, { position: this.position, size: this.size, originalSize: this.originalSize, - originalPosition: this.originalPosition, - prevSize: this.prevSize, - prevPosition: this.prevPosition + originalPosition: this.originalPosition }; } @@ -7423,11 +7688,13 @@ $.ui.plugin.add("resizable", "animate", { o = that.options, pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), - soffseth = ista && that._hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, + soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height, soffsetw = ista ? 0 : that.sizeDiff.width, style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, - left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, - top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; + left = (parseInt(that.element.css("left"), 10) + + (that.position.left - that.originalPosition.left)) || null, + top = (parseInt(that.element.css("top"), 10) + + (that.position.top - that.originalPosition.top)) || null; that.element.animate( $.extend(style, top && left ? { top: top, left: left } : {}), { @@ -7520,7 +7787,7 @@ $.ui.plugin.add( "resizable", "containment", { } }, - resize: function( event, ui ) { + resize: function( event ) { var woset, hoset, isParent, isOffsetRelative, that = $( this ).resizable( "instance" ), o = that.options, @@ -7539,7 +7806,11 @@ $.ui.plugin.add( "resizable", "containment", { } if ( cp.left < ( that._helper ? co.left : 0 ) ) { - that.size.width = that.size.width + ( that._helper ? ( that.position.left - co.left ) : ( that.position.left - cop.left ) ); + that.size.width = that.size.width + + ( that._helper ? + ( that.position.left - co.left ) : + ( that.position.left - cop.left ) ); + if ( pRatio ) { that.size.height = that.size.width / that.aspectRatio; continueResize = false; @@ -7548,7 +7819,11 @@ $.ui.plugin.add( "resizable", "containment", { } if ( cp.top < ( that._helper ? co.top : 0 ) ) { - that.size.height = that.size.height + ( that._helper ? ( that.position.top - co.top ) : that.position.top ); + that.size.height = that.size.height + + ( that._helper ? + ( that.position.top - co.top ) : + that.position.top ); + if ( pRatio ) { that.size.width = that.size.height * that.aspectRatio; continueResize = false; @@ -7556,19 +7831,27 @@ $.ui.plugin.add( "resizable", "containment", { that.position.top = that._helper ? co.top : 0; } - that.offset.left = that.parentData.left + that.position.left; - that.offset.top = that.parentData.top + that.position.top; - - woset = Math.abs( ( that._helper ? that.offset.left - cop.left : ( that.offset.left - co.left ) ) + that.sizeDiff.width ); - hoset = Math.abs( ( that._helper ? that.offset.top - cop.top : ( that.offset.top - co.top ) ) + that.sizeDiff.height ); - isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); if ( isParent && isOffsetRelative ) { - woset -= Math.abs( that.parentData.left ); + that.offset.left = that.parentData.left + that.position.left; + that.offset.top = that.parentData.top + that.position.top; + } else { + that.offset.left = that.element.offset().left; + that.offset.top = that.element.offset().top; } + woset = Math.abs( that.sizeDiff.width + + (that._helper ? + that.offset.left - cop.left : + (that.offset.left - co.left)) ); + + hoset = Math.abs( that.sizeDiff.height + + (that._helper ? + that.offset.top - cop.top : + (that.offset.top - co.top)) ); + if ( woset + that.size.width >= that.parentData.width ) { that.size.width = that.parentData.width - woset; if ( pRatio ) { @@ -7586,14 +7869,14 @@ $.ui.plugin.add( "resizable", "containment", { } if ( !continueResize ){ - that.position.left = ui.prevPosition.left; - that.position.top = ui.prevPosition.top; - that.size.width = ui.prevSize.width; - that.size.height = ui.prevSize.height; + that.position.left = that.prevPosition.left; + that.position.top = that.prevPosition.top; + that.size.width = that.prevSize.width; + that.size.height = that.prevSize.height; } }, - stop: function(){ + stop: function() { var that = $( this ).resizable( "instance" ), o = that.options, co = that.containerOffset, @@ -7624,10 +7907,10 @@ $.ui.plugin.add( "resizable", "containment", { $.ui.plugin.add("resizable", "alsoResize", { - start: function () { + start: function() { var that = $(this).resizable( "instance" ), o = that.options, - _store = function (exp) { + _store = function(exp) { $(exp).each(function() { var el = $(this); el.data("ui-resizable-alsoresize", { @@ -7638,30 +7921,42 @@ $.ui.plugin.add("resizable", "alsoResize", { }; 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{ + 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 that = $(this).resizable( "instance" ), 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 + 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) { + _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"]; + 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); + $.each(css, function(i, prop) { + var sum = (start[prop] || 0) + (delta[prop] || 0); if (sum && sum >= 0) { style[prop] = sum || null; } @@ -7672,13 +7967,15 @@ $.ui.plugin.add("resizable", "alsoResize", { }; if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { - $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); - }else{ + $.each(o.alsoResize, function(exp, c) { + _alsoResize(exp, c); + }); + } else { _alsoResize(o.alsoResize); } }, - stop: function () { + stop: function() { $(this).removeData("resizable-alsoresize"); } }); @@ -7691,7 +7988,16 @@ $.ui.plugin.add("resizable", "ghost", { that.ghost = that.originalElement.clone(); that.ghost - .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) + .css({ + opacity: 0.25, + display: "block", + position: "relative", + height: cs.height, + width: cs.width, + margin: 0, + left: 0, + top: 0 + }) .addClass("ui-resizable-ghost") .addClass(typeof o.ghost === "string" ? o.ghost : ""); @@ -7699,10 +8005,14 @@ $.ui.plugin.add("resizable", "ghost", { }, - resize: function(){ + resize: function() { var that = $(this).resizable( "instance" ); if (that.ghost) { - that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); + that.ghost.css({ + position: "relative", + height: that.size.height, + width: that.size.width + }); } }, @@ -7718,15 +8028,16 @@ $.ui.plugin.add("resizable", "ghost", { $.ui.plugin.add("resizable", "grid", { resize: function() { - var that = $(this).resizable( "instance" ), + var outerDimensions, + that = $(this).resizable( "instance" ), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, - grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, - gridX = (grid[0]||1), - gridY = (grid[1]||1), + grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, + gridX = (grid[0] || 1), + gridY = (grid[1] || 1), ox = Math.round((cs.width - os.width) / gridX) * gridX, oy = Math.round((cs.height - os.height) / gridY) * gridY, newWidth = os.width + ox, @@ -7739,16 +8050,16 @@ $.ui.plugin.add("resizable", "grid", { o.grid = grid; if (isMinWidth) { - newWidth = newWidth + gridX; + newWidth += gridX; } if (isMinHeight) { - newHeight = newHeight + gridY; + newHeight += gridY; } if (isMaxWidth) { - newWidth = newWidth - gridX; + newWidth -= gridX; } if (isMaxHeight) { - newHeight = newHeight - gridY; + newHeight -= gridY; } if (/^(se|s|e)$/.test(a)) { @@ -7763,19 +8074,25 @@ $.ui.plugin.add("resizable", "grid", { that.size.height = newHeight; that.position.left = op.left - ox; } else { + if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) { + outerDimensions = that._getPaddingPlusBorderDimensions( this ); + } + if ( newHeight - gridY > 0 ) { that.size.height = newHeight; that.position.top = op.top - oy; } else { - that.size.height = gridY; - that.position.top = op.top + os.height - gridY; + newHeight = gridY - outerDimensions.height; + that.size.height = newHeight; + that.position.top = op.top + os.height - newHeight; } if ( newWidth - gridX > 0 ) { that.size.width = newWidth; that.position.left = op.left - ox; } else { - that.size.width = gridX; - that.position.left = op.left + os.width - gridX; + newWidth = gridY - outerDimensions.height; + that.size.width = newWidth; + that.position.left = op.left + os.width - newWidth; } } } @@ -7786,7 +8103,7 @@ var resizable = $.ui.resizable; /*! - * jQuery UI Dialog 1.11.0 + * jQuery UI Dialog 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -7798,7 +8115,7 @@ var resizable = $.ui.resizable; var dialog = $.widget( "ui.dialog", { - version: "1.11.0", + version: "1.11.2", options: { appendTo: "body", autoOpen: true, @@ -8028,11 +8345,24 @@ var dialog = $.widget( "ui.dialog", { this._position(); this._createOverlay(); this._moveToTop( null, true ); + + // Ensure the overlay is moved to the top with the dialog, but only when + // opening. The overlay shouldn't move after the dialog is open so that + // modeless dialogs opened after the modal dialog stack properly. + if ( this.overlay ) { + this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); + } + this._show( this.uiDialog, this.options.show, function() { that._focusTabbable(); that._trigger( "focus" ); }); + // Track the dialog immediately upon openening in case a focus event + // somehow occurs outside of the dialog before an element inside the + // dialog is focused (#10152) + this._makeFocusTarget(); + this._trigger( "open" ); }, @@ -8344,14 +8674,18 @@ var dialog = $.widget( "ui.dialog", { _trackFocus: function() { this._on( this.widget(), { - "focusin": function( event ) { - this._untrackInstance(); - this._trackingInstances().unshift( this ); + focusin: function( event ) { + this._makeFocusTarget(); this._focusedElement = $( event.target ); } }); }, + _makeFocusTarget: function() { + this._untrackInstance(); + this._trackingInstances().unshift( this ); + }, + _untrackInstance: function() { var instances = this._trackingInstances(), exists = $.inArray( this, instances ); @@ -8625,7 +8959,7 @@ var dialog = $.widget( "ui.dialog", { /*! - * jQuery UI Droppable 1.11.0 + * jQuery UI Droppable 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -8637,7 +8971,7 @@ var dialog = $.widget( "ui.dialog", { $.widget( "ui.droppable", { - version: "1.11.0", + version: "1.11.2", widgetEventPrefix: "drop", options: { accept: "*", @@ -8801,7 +9135,7 @@ $.widget( "ui.droppable", { !inst.options.disabled && inst.options.scope === draggable.options.scope && inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) && - $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance ) + $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event ) ) { childrenIntersection = true; return false; } }); if ( childrenIntersection ) { @@ -8839,15 +9173,14 @@ $.ui.intersect = (function() { return ( x >= reference ) && ( x < ( reference + size ) ); } - return function( draggable, droppable, toleranceMode ) { + return function( draggable, droppable, toleranceMode, event ) { if ( !droppable.offset ) { return false; } - var draggableLeft, draggableTop, - x1 = ( draggable.positionAbs || draggable.position.absolute ).left, - y1 = ( draggable.positionAbs || draggable.position.absolute ).top, + var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left, + y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top, x2 = x1 + draggable.helperProportions.width, y2 = y1 + draggable.helperProportions.height, l = droppable.offset.left, @@ -8864,9 +9197,7 @@ $.ui.intersect = (function() { t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 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 isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width ); + return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width ); case "touch": return ( ( y1 >= t && y1 <= b ) || // Top edge touching @@ -8936,7 +9267,7 @@ $.ui.ddmanager = { if ( !this.options ) { return; } - if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance ) ) { + if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { dropped = this._drop.call( this, event ) || dropped; } @@ -8973,7 +9304,7 @@ $.ui.ddmanager = { } var parentInstance, scope, parent, - intersects = $.ui.intersect( draggable, this, this.options.tolerance ), + intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null ); if ( !c ) { return; @@ -9025,7 +9356,7 @@ var droppable = $.ui.droppable; /*! - * jQuery UI Effects 1.11.0 + * jQuery UI Effects 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -9036,7 +9367,11 @@ var droppable = $.ui.droppable; */ -var dataSpace = "ui-effects-"; +var dataSpace = "ui-effects-", + + // Create a local jQuery because jQuery Color relies on it and the + // global may not exist with AMD and a custom build (#10199) + jQuery = $; $.effects = { effect: {} @@ -9645,7 +9980,7 @@ color.hook = function( hook ) { } try { elem.style[ hook ] = value; - } catch( e ) { + } catch ( e ) { // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' } } @@ -9916,7 +10251,7 @@ $.fn.extend({ (function() { $.extend( $.effects, { - version: "1.11.0", + version: "1.11.2", // Saves a set of properties in a data storage save: function( element, set ) { @@ -10010,7 +10345,7 @@ $.extend( $.effects, { // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 try { active.id; - } catch( e ) { + } catch ( e ) { active = document.body; } @@ -10312,7 +10647,7 @@ var effect = $.effects; /*! - * jQuery UI Effects Blind 1.11.0 + * jQuery UI Effects Blind 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -10389,7 +10724,7 @@ var effectBlind = $.effects.effect.blind = function( o, done ) { /*! - * jQuery UI Effects Bounce 1.11.0 + * jQuery UI Effects Bounce 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -10499,7 +10834,7 @@ var effectBounce = $.effects.effect.bounce = function( o, done ) { /*! - * jQuery UI Effects Clip 1.11.0 + * jQuery UI Effects Clip 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -10563,7 +10898,7 @@ var effectClip = $.effects.effect.clip = function( o, done ) { /*! - * jQuery UI Effects Drop 1.11.0 + * jQuery UI Effects Drop 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -10593,7 +10928,7 @@ var effectDrop = $.effects.effect.drop = function( o, done ) { el.show(); $.effects.createWrapper( el ); - distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; + distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; if ( show ) { el @@ -10625,7 +10960,7 @@ var effectDrop = $.effects.effect.drop = function( o, done ) { /*! - * jQuery UI Effects Explode 1.11.0 + * jQuery UI Effects Explode 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -10719,7 +11054,7 @@ var effectExplode = $.effects.effect.explode = function( o, done ) { /*! - * jQuery UI Effects Fade 1.11.0 + * jQuery UI Effects Fade 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -10746,7 +11081,7 @@ var effectFade = $.effects.effect.fade = function( o, done ) { /*! - * jQuery UI Effects Fold 1.11.0 + * jQuery UI Effects Fold 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -10819,7 +11154,7 @@ var effectFold = $.effects.effect.fold = function( o, done ) { /*! - * jQuery UI Effects Highlight 1.11.0 + * jQuery UI Effects Highlight 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -10866,7 +11201,7 @@ var effectHighlight = $.effects.effect.highlight = function( o, done ) { /*! - * jQuery UI Effects Size 1.11.0 + * jQuery UI Effects Size 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11086,7 +11421,7 @@ var effectSize = $.effects.effect.size = function( o, done ) { /*! - * jQuery UI Effects Scale 1.11.0 + * jQuery UI Effects Scale 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11161,7 +11496,7 @@ var effectScale = $.effects.effect.scale = function( o, done ) { /*! - * jQuery UI Effects Puff 1.11.0 + * jQuery UI Effects Puff 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11207,7 +11542,7 @@ var effectPuff = $.effects.effect.puff = function( o, done ) { /*! - * jQuery UI Effects Pulsate 1.11.0 + * jQuery UI Effects Pulsate 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11267,7 +11602,7 @@ var effectPulsate = $.effects.effect.pulsate = function( o, done ) { /*! - * jQuery UI Effects Shake 1.11.0 + * jQuery UI Effects Shake 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11338,7 +11673,7 @@ var effectShake = $.effects.effect.shake = function( o, done ) { /*! - * jQuery UI Effects Slide 1.11.0 + * jQuery UI Effects Slide 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11399,7 +11734,7 @@ var effectSlide = $.effects.effect.slide = function( o, done ) { /*! - * jQuery UI Effects Transfer 1.11.0 + * jQuery UI Effects Transfer 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11443,7 +11778,7 @@ var effectTransfer = $.effects.effect.transfer = function( o, done ) { /*! - * jQuery UI Progressbar 1.11.0 + * jQuery UI Progressbar 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11455,7 +11790,7 @@ var effectTransfer = $.effects.effect.transfer = function( o, done ) { var progressbar = $.widget( "ui.progressbar", { - version: "1.11.0", + version: "1.11.2", options: { max: 100, value: 0, @@ -11588,7 +11923,7 @@ var progressbar = $.widget( "ui.progressbar", { /*! - * jQuery UI Selectable 1.11.0 + * jQuery UI Selectable 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11600,7 +11935,7 @@ var progressbar = $.widget( "ui.progressbar", { var selectable = $.widget("ui.selectable", $.ui.mouse, { - version: "1.11.0", + version: "1.11.2", options: { appendTo: "body", autoRefresh: true, @@ -11860,7 +12195,7 @@ var selectable = $.widget("ui.selectable", $.ui.mouse, { /*! - * jQuery UI Selectmenu 1.11.0 + * jQuery UI Selectmenu 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -11872,7 +12207,7 @@ var selectable = $.widget("ui.selectable", $.ui.mouse, { var selectmenu = $.widget( "ui.selectmenu", { - version: "1.11.0", + version: "1.11.2", defaultElement: "<select>", options: { appendTo: null, @@ -11951,7 +12286,7 @@ var selectmenu = $.widget( "ui.selectmenu", { .appendTo( this.button ); this._setText( this.buttonText, this.element.find( "option:selected" ).text() ); - this._setOption( "width", this.options.width ); + this._resizeButton(); this._on( this.button, this._buttonEvents ); this.button.one( "focusin", function() { @@ -11989,6 +12324,12 @@ var selectmenu = $.widget( "ui.selectmenu", { role: "listbox", select: function( event, ui ) { event.preventDefault(); + + // support: IE8 + // If the item was selected via a click, the text selection + // will be destroyed in IE + that._setSelection(); + that._select( ui.item.data( "ui-selectmenu-item" ), event ); }, focus: function( event, ui ) { @@ -12031,7 +12372,9 @@ var selectmenu = $.widget( "ui.selectmenu", { refresh: function() { this._refreshMenu(); this._setText( this.buttonText, this._getSelectedItem().text() ); - this._setOption( "width", this.options.width ); + if ( !this.options.width ) { + this._resizeButton(); + } }, _refreshMenu: function() { @@ -12097,6 +12440,7 @@ var selectmenu = $.widget( "ui.selectmenu", { this.isOpen = false; this._toggleAttr(); + this.range = null; this._off( this.document ); this._trigger( "close", event ); @@ -12185,6 +12529,29 @@ var selectmenu = $.widget( "ui.selectmenu", { this[ this.isOpen ? "close" : "open" ]( event ); }, + _setSelection: function() { + var selection; + + if ( !this.range ) { + return; + } + + if ( window.getSelection ) { + selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange( this.range ); + + // support: IE8 + } else { + this.range.select(); + } + + // support: IE + // Setting the text selection kills the button focus in IE, but + // restoring the focus doesn't kill the selection. + this.button.focus(); + }, + _documentClick: { mousedown: function( event ) { if ( !this.isOpen ) { @@ -12198,7 +12565,28 @@ var selectmenu = $.widget( "ui.selectmenu", { }, _buttonEvents: { - click: "_toggle", + + // Prevent text selection from being reset when interacting with the selectmenu (#10144) + mousedown: function() { + var selection; + + if ( window.getSelection ) { + selection = window.getSelection(); + if ( selection.rangeCount ) { + this.range = selection.getRangeAt( 0 ); + } + + // support: IE8 + } else { + this.range = document.selection.createRange(); + } + }, + + click: function( event ) { + this._setSelection(); + this._toggle( event ); + }, + keydown: function( event ) { var preventDefault = true; switch ( event.keyCode ) { @@ -12320,10 +12708,7 @@ var selectmenu = $.widget( "ui.selectmenu", { } if ( key === "width" ) { - if ( !value ) { - value = this.element.outerWidth(); - } - this.button.outerWidth( value ); + this._resizeButton(); } }, @@ -12356,6 +12741,17 @@ var selectmenu = $.widget( "ui.selectmenu", { this.menu.attr( "aria-hidden", !this.isOpen ); }, + _resizeButton: function() { + var width = this.options.width; + + if ( !width ) { + width = this.element.show().outerWidth(); + this.element.hide(); + } + + this.button.outerWidth( width ); + }, + _resizeMenu: function() { this.menu.outerWidth( Math.max( this.button.outerWidth(), @@ -12399,7 +12795,7 @@ var selectmenu = $.widget( "ui.selectmenu", { /*! - * jQuery UI Slider 1.11.0 + * jQuery UI Slider 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -12411,7 +12807,7 @@ var selectmenu = $.widget( "ui.selectmenu", { var slider = $.widget( "ui.slider", $.ui.mouse, { - version: "1.11.0", + version: "1.11.2", widgetEventPrefix: "slide", options: { @@ -12443,6 +12839,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { this._handleIndex = null; this._detectOrientation(); this._mouseInit(); + this._calculateNewMax(); this.element .addClass( "ui-slider" + @@ -12839,6 +13236,9 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { .removeClass( "ui-slider-horizontal ui-slider-vertical" ) .addClass( "ui-slider-" + this.orientation ); this._refreshValue(); + + // Reset positioning from previous orientation + this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); break; case "value": this._animateOff = true; @@ -12854,9 +13254,11 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { } this._animateOff = false; break; + case "step": case "min": case "max": this._animateOff = true; + this._calculateNewMax(); this._refreshValue(); this._animateOff = false; break; @@ -12894,7 +13296,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { // .slice() creates a copy of the array // this copy gets trimmed by min and max and then returned vals = this.options.values.slice(); - for ( i = 0; i < vals.length; i+= 1) { + for ( i = 0; i < vals.length; i += 1) { vals[ i ] = this._trimAlignValue( vals[ i ] ); } @@ -12925,12 +13327,17 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { return parseFloat( alignValue.toFixed(5) ); }, + _calculateNewMax: function() { + var remainder = ( this.options.max - this._valueMin() ) % this.options.step; + this.max = this.options.max - remainder; + }, + _valueMin: function() { return this.options.min; }, _valueMax: function() { - return this.options.max; + return this.max; }, _refreshValue: function() { @@ -13072,7 +13479,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { /*! - * jQuery UI Sortable 1.11.0 + * jQuery UI Sortable 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -13084,7 +13491,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { var sortable = $.widget("ui.sortable", $.ui.mouse, { - version: "1.11.0", + version: "1.11.2", widgetEventPrefix: "sort", ready: false, options: { @@ -13969,6 +14376,10 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { } if(this.currentContainer === this.containers[innermostIndex]) { + if ( !this.currentContainer.containerCache.over ) { + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); + this.currentContainer.containerCache.over = 1; + } return; } @@ -14307,18 +14718,6 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { } this.dragging = false; - if(this.cancelHelperRemoval) { - if(!noPropagation) { - this._trigger("beforeStop", event, this._uiHash()); - for (i=0; i < delayedTriggers.length; i++) { - delayedTriggers[i].call(this, event); - } //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - - this.fromOutside = false; - return false; - } if(!noPropagation) { this._trigger("beforeStop", event, this._uiHash()); @@ -14327,10 +14726,12 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - if(this.helper[0] !== this.currentItem[0]) { - this.helper.remove(); + if ( !this.cancelHelperRemoval ) { + if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { + this.helper.remove(); + } + this.helper = null; } - this.helper = null; if(!noPropagation) { for (i=0; i < delayedTriggers.length; i++) { @@ -14340,7 +14741,7 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { } this.fromOutside = false; - return true; + return !this.cancelHelperRemoval; }, @@ -14367,7 +14768,7 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { /*! - * jQuery UI Spinner 1.11.0 + * jQuery UI Spinner 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -14390,7 +14791,7 @@ function spinner_modifier( fn ) { } var spinner = $.widget( "ui.spinner", { - version: "1.11.0", + version: "1.11.2", defaultElement: "<input>", widgetEventPrefix: "spin", options: { @@ -14866,7 +15267,7 @@ var spinner = $.widget( "ui.spinner", { /*! - * jQuery UI Tabs 1.11.0 + * jQuery UI Tabs 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -14878,7 +15279,7 @@ var spinner = $.widget( "ui.spinner", { var tabs = $.widget( "ui.tabs", { - version: "1.11.0", + version: "1.11.2", delay: 300, options: { active: null, @@ -14928,24 +15329,7 @@ var tabs = $.widget( "ui.tabs", { this.element .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) - .toggleClass( "ui-tabs-collapsible", options.collapsible ) - // Prevent users from focusing disabled tabs via click - .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { - if ( $( this ).is( ".ui-state-disabled" ) ) { - event.preventDefault(); - } - }) - // support: IE <9 - // Preventing the default action in mousedown doesn't prevent IE - // from focusing the element, so if the anchor gets focused, blur. - // We don't have to worry about focusing the previously focused - // element since clicking on a non-focusable element should focus - // the body anyway. - .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { - if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { - this.blur(); - } - }); + .toggleClass( "ui-tabs-collapsible", options.collapsible ); this._processTabs(); options.active = this._initialActive(); @@ -15242,11 +15626,33 @@ var tabs = $.widget( "ui.tabs", { }, _processTabs: function() { - var that = this; + var that = this, + prevTabs = this.tabs, + prevAnchors = this.anchors, + prevPanels = this.panels; this.tablist = this._getList() .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .attr( "role", "tablist" ); + .attr( "role", "tablist" ) + + // Prevent users from focusing disabled tabs via click + .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) { + if ( $( this ).is( ".ui-state-disabled" ) ) { + event.preventDefault(); + } + }) + + // support: IE <9 + // Preventing the default action in mousedown doesn't prevent IE + // from focusing the element, so if the anchor gets focused, blur. + // We don't have to worry about focusing the previously focused + // element since clicking on a non-focusable element should focus + // the body anyway. + .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { + if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { + this.blur(); + } + }); this.tabs = this.tablist.find( "> li:has(a[href])" ) .addClass( "ui-state-default ui-corner-top" ) @@ -15307,6 +15713,13 @@ var tabs = $.widget( "ui.tabs", { this.panels .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) .attr( "role", "tabpanel" ); + + // Avoid memory leaks (#10056) + if ( prevTabs ) { + this._off( prevTabs.not( this.tabs ) ); + this._off( prevAnchors.not( this.anchors ) ); + this._off( prevPanels.not( this.panels ) ); + } }, // allow overriding how to find the list for rare usage scenarios (#7715) @@ -15564,6 +15977,8 @@ var tabs = $.widget( "ui.tabs", { .removeAttr( "tabIndex" ) .removeUniqueId(); + this.tablist.unbind( this.eventNamespace ); + this.tabs.add( this.panels ).each(function() { if ( $.data( this, "ui-tabs-destroy" ) ) { $( this ).remove(); @@ -15718,7 +16133,7 @@ var tabs = $.widget( "ui.tabs", { /*! - * jQuery UI Tooltip 1.11.0 + * jQuery UI Tooltip 1.11.2 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -15730,7 +16145,7 @@ var tabs = $.widget( "ui.tabs", { var tooltip = $.widget( "ui.tooltip", { - version: "1.11.0", + version: "1.11.2", options: { content: function() { // support: IE<9, Opera in jQuery <1.7 @@ -15790,6 +16205,7 @@ var tooltip = $.widget( "ui.tooltip", { // IDs of generated tooltips, needed for destroy this.tooltips = {}; + // IDs of parent tooltips where we removed the title attribute this.parents = {}; @@ -15821,8 +16237,8 @@ var tooltip = $.widget( "ui.tooltip", { this._super( key, value ); if ( key === "content" ) { - $.each( this.tooltips, function( id, element ) { - that._updateContent( element ); + $.each( this.tooltips, function( id, tooltipData ) { + that._updateContent( tooltipData.element ); }); } }, @@ -15831,9 +16247,9 @@ var tooltip = $.widget( "ui.tooltip", { var that = this; // close open tooltips - $.each( this.tooltips, function( id, element ) { + $.each( this.tooltips, function( id, tooltipData ) { var event = $.Event( "blur" ); - event.target = event.currentTarget = element[0]; + event.target = event.currentTarget = tooltipData.element[ 0 ]; that.close( event, true ); }); @@ -15935,7 +16351,7 @@ var tooltip = $.widget( "ui.tooltip", { }, _open: function( event, target, content ) { - var tooltip, events, delayedShow, a11yContent, + var tooltipData, tooltip, events, delayedShow, a11yContent, positionOption = $.extend( {}, this.options.position ); if ( !content ) { @@ -15944,9 +16360,9 @@ var tooltip = $.widget( "ui.tooltip", { // Content can be updated multiple times. If the tooltip already // exists, then just update the content and bail. - tooltip = this._find( target ); - if ( tooltip.length ) { - tooltip.find( ".ui-tooltip-content" ).html( content ); + tooltipData = this._find( target ); + if ( tooltipData ) { + tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); return; } @@ -15965,7 +16381,8 @@ var tooltip = $.widget( "ui.tooltip", { } } - tooltip = this._tooltip( target ); + tooltipData = this._tooltip( target ); + tooltip = tooltipData.tooltip; this._addDescribedBy( target, tooltip.attr( "id" ) ); tooltip.find( ".ui-tooltip-content" ).html( content ); @@ -16045,13 +16462,21 @@ var tooltip = $.widget( "ui.tooltip", { }, close: function( event ) { - var that = this, + var tooltip, + that = this, target = $( event ? event.currentTarget : this.element ), - tooltip = this._find( target ); + tooltipData = this._find( target ); + + // The tooltip may already be closed + if ( !tooltipData ) { + return; + } + + tooltip = tooltipData.tooltip; // disabling closes the tooltip, so we need to track when we're closing // to avoid an infinite loop in case the tooltip becomes disabled on close - if ( this.closing ) { + if ( tooltipData.closing ) { return; } @@ -16066,6 +16491,7 @@ var tooltip = $.widget( "ui.tooltip", { this._removeDescribedBy( target ); + tooltipData.hiding = true; tooltip.stop( true ); this._hide( tooltip, this.options.hide, function() { that._removeTooltip( $( this ) ); @@ -16087,9 +16513,11 @@ var tooltip = $.widget( "ui.tooltip", { }); } - this.closing = true; + tooltipData.closing = true; this._trigger( "close", event, { tooltip: tooltip } ); - this.closing = false; + if ( !tooltipData.hiding ) { + tooltipData.closing = false; + } }, _tooltip: function( element ) { @@ -16104,13 +16532,16 @@ var tooltip = $.widget( "ui.tooltip", { .appendTo( tooltip ); tooltip.appendTo( this.document[0].body ); - this.tooltips[ id ] = element; - return tooltip; + + return this.tooltips[ id ] = { + element: element, + tooltip: tooltip + }; }, _find: function( target ) { var id = target.data( "ui-tooltip-id" ); - return id ? $( "#" + id ) : $(); + return id ? this.tooltips[ id ] : null; }, _removeTooltip: function( tooltip ) { @@ -16122,10 +16553,11 @@ var tooltip = $.widget( "ui.tooltip", { var that = this; // close open tooltips - $.each( this.tooltips, function( id, element ) { + $.each( this.tooltips, function( id, tooltipData ) { // Delegate to close method to handle common cleanup - var event = $.Event( "blur" ); - event.target = event.currentTarget = element[0]; + var event = $.Event( "blur" ), + element = tooltipData.element; + event.target = event.currentTarget = element[ 0 ]; that.close( event, true ); // Remove immediately; destroying an open tooltip doesn't use the @@ -16147,4 +16579,4 @@ var tooltip = $.widget( "ui.tooltip", { -})); +}));
\ No newline at end of file |
