Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'memory-leaks'

  • Loading branch information...
commit 39f500a0f66a09655be21153d3c351ec56419b56 2 parents 80c34d3 + c05e0ff
John Bender johnbender authored
63 js/widgets/forms/slider.js
View
@@ -152,11 +152,11 @@ $.widget( "mobile.slider", $.mobile.widget, {
self.refresh( val(), true );
});
- // prevent screen drag when slider activated
- $( document ).bind( "vmousemove", function( event ) {
+ this._preventDocumentDrag = function( event ) {
// NOTE: we don't do this in refresh because we still want to
// support programmatic alteration of disabled inputs
if ( self.dragging && !self.options.disabled ) {
+
// self.mouseMoved must be updated before refresh() because it will be used in the control "change" event
self.mouseMoved = true;
@@ -171,7 +171,9 @@ $.widget( "mobile.slider", $.mobile.widget, {
self.userModified = self.beforeStart !== control[0].selectedIndex;
return false;
}
- });
+ }
+
+ $( document ).bind( "vmousemove", this._preventDocumentDrag );
// it appears the clicking the up and down buttons in chrome on
// range/number inputs doesn't trigger a change until the field is
@@ -199,42 +201,36 @@ $.widget( "mobile.slider", $.mobile.widget, {
})
.bind( "vclick", false );
- slider.add( document )
- .bind( "vmouseup", function() {
- if ( self.dragging ) {
-
- self.dragging = false;
+ this._sliderMouseUp = function() {
+ if ( self.dragging ) {
+ self.dragging = false;
- if ( cType === "select") {
-
- // make the handle move with a smooth transition
- handle.addClass( "ui-slider-handle-snapping" );
-
- if ( self.mouseMoved ) {
-
- // this is a drag, change the value only if user dragged enough
- if ( self.userModified ) {
- self.refresh( self.beforeStart === 0 ? 1 : 0 );
- }
- else {
- self.refresh( self.beforeStart );
- }
+ if ( cType === "select") {
+ // make the handle move with a smooth transition
+ handle.addClass( "ui-slider-handle-snapping" );
+ if ( self.mouseMoved ) {
+ // this is a drag, change the value only if user dragged enough
+ if ( self.userModified ) {
+ self.refresh( self.beforeStart === 0 ? 1 : 0 );
}
else {
- // this is just a click, change the value
- self.refresh( self.beforeStart === 0 ? 1 : 0 );
+ self.refresh( self.beforeStart );
}
-
}
-
- self.mouseMoved = false;
-
- self._trigger( "stop" );
- return false;
+ else {
+ // this is just a click, change the value
+ self.refresh( self.beforeStart === 0 ? 1 : 0 );
+ }
}
- });
+ self.mouseMoved = false;
+ self._trigger( "stop" );
+ return false;
+ }
+ };
+
+ slider.add( document ).bind( "vmouseup", this._sliderMouseUp );
slider.insertAfter( control );
// Only add focus class to toggle switch, sliders get it automatically from ui-btn
@@ -327,6 +323,11 @@ $.widget( "mobile.slider", $.mobile.widget, {
parseFloat( this.element.val() ) : this.element[0].selectedIndex;
},
+ _destroy: function() {
+ $( document ).unbind( "vmousemove", this._preventDocumentDrag );
+ $( document ).unbind( "vmouseup", this._sliderMouseUp );
+ },
+
refresh: function( val, isfromControl, preventInputUpdate ) {
// NOTE: we don't return here because we want to support programmatic
40 js/widgets/forms/textinput.js
View
@@ -21,7 +21,8 @@ $.widget( "mobile.textinput", $.mobile.widget, {
_create: function() {
- var input = this.element,
+ var self = this,
+ input = this.element,
o = this.options,
theme = o.theme || $.mobile.getInheritedTheme( this.element, "c" ),
themeclass = " ui-body-" + theme,
@@ -106,30 +107,31 @@ $.widget( "mobile.textinput", $.mobile.widget, {
if ( input.is( "textarea" ) ) {
var extraLineHeight = 15,
keyupTimeoutBuffer = 100,
- keyup = function() {
- var scrollHeight = input[ 0 ].scrollHeight,
- clientHeight = input[ 0 ].clientHeight;
-
- if ( clientHeight < scrollHeight ) {
- input.height(scrollHeight + extraLineHeight);
- }
- },
keyupTimeout;
+ this._keyup = function() {
+ var scrollHeight = input[ 0 ].scrollHeight,
+ clientHeight = input[ 0 ].clientHeight;
+
+ if ( clientHeight < scrollHeight ) {
+ input.height(scrollHeight + extraLineHeight);
+ }
+ };
+
input.keyup(function() {
clearTimeout( keyupTimeout );
- keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer );
+ keyupTimeout = setTimeout( self._keyup, keyupTimeoutBuffer );
});
// binding to pagechange here ensures that for pages loaded via
// ajax the height is recalculated without user input
- $( document ).one( "pagechange", keyup );
+ $( document ).one( "pagechange", this._keyup );
// Issue 509: the browser is not providing scrollHeight properly until the styles load
if ( $.trim( input.val() ) ) {
// bind to the window load to make sure the height is calculated based on BOTH
// the DOM and CSS
- $( window ).load( keyup );
+ $( window ).load( this._keyup );
}
}
if ( input.attr( "disabled" ) ) {
@@ -137,30 +139,32 @@ $.widget( "mobile.textinput", $.mobile.widget, {
}
},
- disable: function() {
+ _destroy: function() {
+ $( window ).unbind( "load", this._keyup );
+ },
+ disable: function() {
var $el;
if ( this.element.attr( "disabled", true ).is( "[type='search'], :jqmData(type='search')" ) ) {
$el = this.element.parent();
} else {
$el = this.element;
- }
+ }
$el.addClass( "ui-disabled" );
return this._setOption( "disabled", true );
-
},
enable: function() {
-
var $el;
+
+ // TODO using more than one line of code is acceptable ;)
if ( this.element.attr( "disabled", false ).is( "[type='search'], :jqmData(type='search')" ) ) {
$el = this.element.parent();
} else {
$el = this.element;
- }
+ }
$el.removeClass( "ui-disabled" );
return this._setOption( "disabled", false );
-
}
});
5 tests/unit/slider/index.html
View
@@ -106,6 +106,11 @@ <h2 id="qunit-userAgent"></h2>
<label for="mouseup-refresh">Input slider:</label>
<input type="range" name="slider" id="mouseup-refresh" value="25" min="0" max="100"/>
</div>
+
+ <div data-role="fieldcontain">
+ <label for="remove-events-slider">Input slider:</label>
+ <input type="range" name="remove-events-slider" id="remove-events-slider" value="25" min="0" max="100"/>
+ </div>
</div>
<div id="enhancetest">
1  tests/unit/slider/slider_core.js
View
@@ -62,7 +62,6 @@
expect( 1 );
var slider = $( "#mouseup-refresh" );
-
slider.val( parseInt(slider.val(), 10) + 10 );
slider.change(function() {
ok( true, "slider changed" );
22 tests/unit/slider/slider_events.js
View
@@ -386,15 +386,33 @@
},
"slidestart", function( timeout ) {
- ok( !timeout, "slidermovestart fired" );
+ ok( !timeout, "slidestart fired" );
slider.trigger( "mouseup" );
},
"slidestop", function( timeout ) {
- ok( !timeout, "slidermovestop fired" );
+ ok( !timeout, "slidestop fired" );
start();
}
], 500);
});
+ test( "slider should detach event", function() {
+ var slider = $( "#remove-events-slider" ),
+ doc = $( document ),
+ vmouseupLength,
+ vmousemoveLength;
+
+ function getDocumentEventsLength( name ){
+ return (doc.data( 'events' )[name] || []).length;
+ }
+
+ vmouseupLength = getDocumentEventsLength( "vmouseup" );
+ vmousemoveLength = getDocumentEventsLength( "vmousemove" );
+
+ slider.remove();
+
+ equal(getDocumentEventsLength( "vmouseup" ), (vmouseupLength - 1), 'vmouseup event was removed');
+ equal(getDocumentEventsLength( "vmousemove" ), (vmousemoveLength - 1), 'vmousemove event was removed');
+ });
})(jQuery);
2  tests/unit/textinput/index.html
View
@@ -54,6 +54,8 @@ <h2 id="qunit-userAgent"></h2>
</textarea>
<a href="external.html" id="external">external</a>
+ <textarea id="destroycorrectly">Test Value</textarea>
+
<input type="search" id="search-input">
</div>
</body>
12 tests/unit/textinput/textinput_core.js
View
@@ -4,6 +4,18 @@
(function($){
module( "jquery.mobile.forms.textinput.js" );
+ test( "input is cleaned up on destroy", function(){
+ var input = $( "#destroycorrectly" ),
+ win = $( window ),
+ loadLen;
+
+ loadLen = win.data("events").load.length;
+
+ input.remove();
+
+ equal(win.data("events").load.length, (loadLen-1), "window load event was not removed");
+ });
+
test( "inputs without type specified are enhanced", function(){
ok( $( "#typeless-input" ).hasClass( "ui-input-text" ) );
});
Please sign in to comment.
Something went wrong with that request. Please try again.