diff options
Diffstat (limited to 'ui/widget.js')
-rw-r--r-- | ui/widget.js | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/ui/widget.js b/ui/widget.js index 726f70735..c101e59d4 100644 --- a/ui/widget.js +++ b/ui/widget.js @@ -26,6 +26,7 @@ }( function( $ ) { var widgetUuid = 0; +var widgetHasOwnProperty = Array.prototype.hasOwnProperty; var widgetSlice = Array.prototype.slice; $.cleanData = ( function( orig ) { @@ -64,7 +65,7 @@ $.widget = function( name, base, prototype ) { } // Create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { return !!$.data( elem, fullName ); }; @@ -183,7 +184,7 @@ $.widget.extend = function( target ) { for ( ; inputIndex < inputLength; inputIndex++ ) { for ( key in input[ inputIndex ] ) { value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { // Clone objects if ( $.isPlainObject( value ) ) { @@ -493,12 +494,30 @@ $.Widget.prototype = { classes: this.options.classes || {} }, options ); + function bindRemoveEvent() { + options.element.each( function( _, element ) { + var isTracked = $.map( that.classesElementLookup, function( elements ) { + return elements; + } ) + .some( function( elements ) { + return elements.is( element ); + } ); + + if ( !isTracked ) { + that._on( $( element ), { + remove: "_untrackClassesElement" + } ); + } + } ); + } + function processClassString( classes, checkOption ) { var current, i; for ( i = 0; i < classes.length; i++ ) { current = that.classesElementLookup[ classes[ i ] ] || $(); if ( options.add ) { - current = $( $.unique( current.get().concat( options.element.get() ) ) ); + bindRemoveEvent(); + current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); } else { current = $( current.not( options.element ).get() ); } @@ -510,10 +529,6 @@ $.Widget.prototype = { } } - this._on( options.element, { - "remove": "_untrackClassesElement" - } ); - if ( options.keys ) { processClassString( options.keys.match( /\S+/g ) || [], true ); } @@ -531,6 +546,8 @@ $.Widget.prototype = { that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); } } ); + + this._off( $( event.target ) ); }, _removeClass: function( element, keys, extra ) { @@ -611,7 +628,7 @@ $.Widget.prototype = { _off: function( element, eventName ) { eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.off( eventName ).off( eventName ); + element.off( eventName ); // Clear the stack to avoid memory leaks (#10056) this.bindings = $( this.bindings.not( element ).get() ); |