Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Widget: Hook into jQuery.cleanData to auto-destroy widgets. Fixes #60…

…08 - Widget: auto-destroy is broken in jQuery 1.4.
  • Loading branch information...
commit 0a0a39f896f83412dc91bedd6819c3a3a0932302 1 parent e5f3bfc
Scott González authored
4  tests/unit/widget/widget.html
@@ -29,7 +29,9 @@ <h2 id="qunit-userAgent"></h2>
29 29
 <div id="main" style="position: absolute; top: -10000px; left: -10000px;">
30 30
 
31 31
 <div id="widget-wrapper">
32  
-	<div id="widget"></div>
  32
+	<div id="widget">
  33
+		<div>...</div>
  34
+	</div>
33 35
 </div>
34 36
 
35 37
 </div>
67  tests/unit/widget/widget_core.js
@@ -409,4 +409,71 @@ test( "._trigger() - provide event and ui", function() {
409 409
 	.testWidget( "testEvent" );
410 410
 });
411 411
 
  412
+test( "auto-destroy - .remove()", function() {
  413
+	expect( 1 );
  414
+	$.widget( "ui.testWidget", {
  415
+		_create: function() {},
  416
+		destroy: function() {
  417
+			ok( true, "destroyed from .remove()" );
  418
+		}
  419
+	});
  420
+	$( "#widget" ).testWidget().remove();
  421
+});
  422
+
  423
+test( "auto-destroy - .remove() on parent", function() {
  424
+	expect( 1 );
  425
+	$.widget( "ui.testWidget", {
  426
+		_create: function() {},
  427
+		destroy: function() {
  428
+			ok( true, "destroyed from .remove() on parent" );
  429
+		}
  430
+	});
  431
+	$( "#widget" ).testWidget().parent().remove();
  432
+});
  433
+
  434
+test( "auto-destroy - .remove() on child", function() {
  435
+	$.widget( "ui.testWidget", {
  436
+		_create: function() {},
  437
+		destroy: function() {
  438
+			ok( false, "destroyed from .remove() on child" );
  439
+		}
  440
+	});
  441
+	$( "#widget" ).testWidget().children().remove();
  442
+	// http://github.com/jquery/qunit/pull/34
  443
+	$.ui.testWidget.prototype.destroy = $.noop;
  444
+});
  445
+
  446
+test( "auto-destroy - .empty()", function() {
  447
+	$.widget( "ui.testWidget", {
  448
+		_create: function() {},
  449
+		destroy: function() {
  450
+			ok( false, "destroyed from .empty()" );
  451
+		}
  452
+	});
  453
+	$( "#widget" ).testWidget().empty();
  454
+	// http://github.com/jquery/qunit/pull/34
  455
+	$.ui.testWidget.prototype.destroy = $.noop;
  456
+});
  457
+
  458
+test( "auto-destroy - .empty() on parent", function() {
  459
+	expect( 1 );
  460
+	$.widget( "ui.testWidget", {
  461
+		_create: function() {},
  462
+		destroy: function() {
  463
+			ok( true, "destroyed from .empty() on parent" );
  464
+		}
  465
+	});
  466
+	$( "#widget" ).testWidget().parent().empty();
  467
+});
  468
+
  469
+test( "auto-destroy - .detach()", function() {
  470
+	$.widget( "ui.testWidget", {
  471
+		_create: function() {},
  472
+		destroy: function() {
  473
+			ok( false, "destroyed from .detach()" );
  474
+		}
  475
+	});
  476
+	$( "#widget" ).testWidget().detach();
  477
+});
  478
+
412 479
 })( jQuery );
36  ui/jquery.ui.widget.js
@@ -9,20 +9,30 @@
9 9
  */
10 10
 (function( $, undefined ) {
11 11
 
12  
-var _remove = $.fn.remove;
13  
-
14  
-$.fn.remove = function( selector, keepData ) {
15  
-	return this.each(function() {
16  
-		if ( !keepData ) {
17  
-			if ( !selector || $.filter( selector, [ this ] ).length ) {
18  
-				$( "*", this ).add( [ this ] ).each(function() {
19  
-					$( this ).triggerHandler( "remove" );
20  
-				});
21  
-			}
  12
+// jQuery 1.4+
  13
+if ( $.cleanData ) {
  14
+	var _cleanData = $.cleanData;
  15
+	$.cleanData = function( elems ) {
  16
+		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
  17
+			$( elem ).triggerHandler( "remove" );
22 18
 		}
23  
-		return _remove.call( $(this), selector, keepData );
24  
-	});
25  
-};
  19
+		_cleanData( elems );
  20
+	};
  21
+} else {
  22
+	var _remove = $.fn.remove;
  23
+	$.fn.remove = function( selector, keepData ) {
  24
+		return this.each(function() {
  25
+			if ( !keepData ) {
  26
+				if ( !selector || $.filter( selector, [ this ] ).length ) {
  27
+					$( "*", this ).add( [ this ] ).each(function() {
  28
+						$( this ).triggerHandler( "remove" );
  29
+					});
  30
+				}
  31
+			}
  32
+			return _remove.call( $(this), selector, keepData );
  33
+		});
  34
+	};
  35
+}
26 36
 
27 37
 $.widget = function( name, base, prototype ) {
28 38
 	var namespace = name.split( "." )[ 0 ],

2 notes on commit 0a0a39f

Eric Hynds

Why destroy widgets on detach?

Scott González

We don't, the test makes sure that destroy isn't called on .detach().

Bora Man

There's an additional (internal) argument 'acceptData' in jQuery.cleanData - why's that not passed here?
(seems to be a perf.opt. as it just prevents some duplicate calls to jQuery.acceptData)

Scott González

Notice the word internal that you used? Also, it doesn't exist in all versions.

Bora Man

Absolutely - but doesn't that also apply to the whole .cleanData itself?
(Did you already think about using $.event.special instead of hooking into cleanData and changing some of its behavior?)

Scott González

Think about it? yes? Actually try it? no. Would you like to send a pull request along with performance tests?

Bora Man

Ok, I'll give it a try. Could you give me a hint how to submit performance tests? (sorry - I'm new in here...)

Please sign in to comment.
Something went wrong with that request. Please try again.