]> source.dussan.org Git - jquery-ui.git/commitdiff
Widget: Untrack classes elements when they are removed from the DOM
authorAlexander Schmitz <arschmitz@gmail.com>
Mon, 12 Sep 2016 14:26:24 +0000 (10:26 -0400)
committerAlexander Schmitz <arschmitz@gmail.com>
Tue, 13 Sep 2016 19:11:34 +0000 (15:11 -0400)
Fixes #15043
Closes gh-1744

tests/unit/widget/classes.js
ui/widget.js

index d355c3a363265a17f0b4ba786ebff2527e2f9935..28f61f272e6652aad06c6b5831fb0455b2a9df45 100644 (file)
@@ -15,6 +15,8 @@ QUnit.module( "widget factory classes", {
                        },
                        _create: function() {
                                this.span = $( "<span>" )
+                                       .add( "<span>" )
+                                       .add( "<span>" )
                                        .appendTo( this.element );
 
                                this.element.wrap( "<div>" );
@@ -68,9 +70,9 @@ function elementHasClasses( widget, method, assert ) {
                "_" + method + "Class works with ( null, extra" + toggle + " )" );
        assert.hasClasses( widget.parent(), "ui-classes-widget ui-theme-widget",
                "_" + method + "Class works with ( element, null, extra" + toggle + " )" );
-       assert.hasClasses( widget.find( "span" ), "ui-classes-span ui-core-span",
+       assert.hasClasses( widget.find( "span" )[ 0 ], "ui-classes-span ui-core-span",
                "_" + method + "Class works with ( element, keys, extra" + toggle + " )" );
-       assert.hasClasses( widget.find( "span" ), "ui-core-span-null",
+       assert.hasClasses( widget.find( "span" )[ 0 ], "ui-core-span-null",
                "_" + method + "Class works with ( element, keys, null" + toggle + " )" );
 }
 function elementLacksClasses( widget, method, assert ) {
@@ -84,9 +86,9 @@ function elementLacksClasses( widget, method, assert ) {
                "_" + method + "Class works with ( null, extra" + toggle + " )" );
        assert.lacksClasses( widget.parent(), "ui-classes-widget ui-theme-widget",
                "_" + method + "Class works with ( element, null, extra" + toggle + " )" );
-       assert.lacksClasses( widget.find( "span" ), "ui-classes-span ui-core-span",
+       assert.lacksClasses( widget.find( "span" )[ 0 ], "ui-classes-span ui-core-span",
                "_" + method + "Class works with ( element, keys, extra" + toggle + " )" );
-       assert.lacksClasses( widget.find( "span" ), "ui-core-span-null",
+       assert.lacksClasses( widget.find( "span" )[ 0 ], "ui-core-span-null",
                "_" + method + "Class works with ( element, keys, null" + toggle + " )" );
 }
 
@@ -113,7 +115,7 @@ QUnit.test( ".option() - classes setter", function( assert ) {
                "Setting to empty value leaves structure class" );
        assert.lacksClasses( testWidget.element, "ui-theme-element-2",
                "Setting empty value removes previous value classes" );
-       assert.hasClasses( testWidget.span, "ui-classes-span custom-theme-span",
+       assert.hasClasses( testWidget.span[ 0 ], "ui-classes-span custom-theme-span",
                "Adding a class to an empty value works as expected" );
        assert.hasClasses( testWidget.wrapper, "ui-classes-widget custom-theme-widget",
                "Appending a class to the current value works as expected" );
@@ -144,4 +146,34 @@ QUnit.test( "._add/_remove/_toggleClass()", function( assert ) {
        elementLacksClasses( widget, "remove", assert );
 } );
 
+QUnit.test( "Classes elements are untracked as they are removed from the DOM", function( assert ) {
+       assert.expect( 9 );
+
+       var widget = $( "#widget" ).classesWidget();
+       var instance = widget.classesWidget( "instance" );
+
+       assert.equal( instance.classesElementLookup[ "ui-classes-span" ].length, 3,
+               "Widget is tracking 3 ui-classes-span elements" );
+       assert.equal( instance.classesElementLookup[ "ui-core-span-null" ].length, 3,
+               "Widget is tracking 3 ui-core-span-null elements" );
+       assert.equal( instance.classesElementLookup[ "ui-core-span" ].length, 3,
+               "Widget is tracking 3 ui-core-span elements" );
+
+       widget.find( "span" ).eq( 0 ).remove();
+       assert.equal( instance.classesElementLookup[ "ui-classes-span" ].length, 2,
+               "After removing 1 span from dom 2 ui-classes-span elements are tracked" );
+       assert.equal( instance.classesElementLookup[ "ui-core-span-null" ].length, 2,
+               "After removing 1 span from dom 2 ui-core-span-null elements are tracked" );
+       assert.equal( instance.classesElementLookup[ "ui-core-span" ].length, 2,
+               "After removing 1 span from dom 2 ui-core-span elements are tracked" );
+
+       widget.find( "span" ).remove();
+       assert.equal( instance.classesElementLookup[ "ui-classes-span" ].length, 0,
+               "No ui-classes-span elements are tracked after removing all spans" );
+       assert.equal( instance.classesElementLookup[ "ui-core-span-null" ].length, 0,
+               "No ui-core-span-null elements are tracked after removing all spans" );
+       assert.equal( instance.classesElementLookup[ "ui-core-span" ].length, 0,
+               "No ui-core-span elements are tracked after removing all spans" );
+} );
+
 } );
index 06a3ce88e27225fe6072024f971c39a743474167..a3922675f1d8e884ec7873d527963cd18d978a0f 100644 (file)
@@ -514,6 +514,10 @@ $.Widget.prototype = {
                        }
                }
 
+               this._on( options.element, {
+                       "remove": "_untrackClassesElement"
+               } );
+
                if ( options.keys ) {
                        processClassString( options.keys.match( /\S+/g ) || [], true );
                }
@@ -524,6 +528,15 @@ $.Widget.prototype = {
                return full.join( " " );
        },
 
+       _untrackClassesElement: function( event ) {
+               var that = this;
+               $.each( that.classesElementLookup, function( key, value ) {
+                       if ( $.inArray( event.target, value ) !== -1 ) {
+                               that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
+                       }
+               } );
+       },
+
        _removeClass: function( element, keys, extra ) {
                return this._toggleClass( element, keys, extra, false );
        },