Skip to content
This repository was archived by the owner on Oct 8, 2021. It is now read-only.

Commit 39f500a

Browse files
committed
Merge branch 'memory-leaks'
2 parents 80c34d3 + c05e0ff commit 39f500a

File tree

7 files changed

+93
-52
lines changed

7 files changed

+93
-52
lines changed

js/widgets/forms/slider.js

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,11 @@ $.widget( "mobile.slider", $.mobile.widget, {
152152
self.refresh( val(), true );
153153
});
154154

155-
// prevent screen drag when slider activated
156-
$( document ).bind( "vmousemove", function( event ) {
155+
this._preventDocumentDrag = function( event ) {
157156
// NOTE: we don't do this in refresh because we still want to
158157
// support programmatic alteration of disabled inputs
159158
if ( self.dragging && !self.options.disabled ) {
159+
160160
// self.mouseMoved must be updated before refresh() because it will be used in the control "change" event
161161
self.mouseMoved = true;
162162

@@ -171,7 +171,9 @@ $.widget( "mobile.slider", $.mobile.widget, {
171171
self.userModified = self.beforeStart !== control[0].selectedIndex;
172172
return false;
173173
}
174-
});
174+
}
175+
176+
$( document ).bind( "vmousemove", this._preventDocumentDrag );
175177

176178
// it appears the clicking the up and down buttons in chrome on
177179
// range/number inputs doesn't trigger a change until the field is
@@ -199,42 +201,36 @@ $.widget( "mobile.slider", $.mobile.widget, {
199201
})
200202
.bind( "vclick", false );
201203

202-
slider.add( document )
203-
.bind( "vmouseup", function() {
204-
if ( self.dragging ) {
205-
206-
self.dragging = false;
204+
this._sliderMouseUp = function() {
205+
if ( self.dragging ) {
206+
self.dragging = false;
207207

208-
if ( cType === "select") {
209-
210-
// make the handle move with a smooth transition
211-
handle.addClass( "ui-slider-handle-snapping" );
212-
213-
if ( self.mouseMoved ) {
214-
215-
// this is a drag, change the value only if user dragged enough
216-
if ( self.userModified ) {
217-
self.refresh( self.beforeStart === 0 ? 1 : 0 );
218-
}
219-
else {
220-
self.refresh( self.beforeStart );
221-
}
208+
if ( cType === "select") {
209+
// make the handle move with a smooth transition
210+
handle.addClass( "ui-slider-handle-snapping" );
222211

212+
if ( self.mouseMoved ) {
213+
// this is a drag, change the value only if user dragged enough
214+
if ( self.userModified ) {
215+
self.refresh( self.beforeStart === 0 ? 1 : 0 );
223216
}
224217
else {
225-
// this is just a click, change the value
226-
self.refresh( self.beforeStart === 0 ? 1 : 0 );
218+
self.refresh( self.beforeStart );
227219
}
228-
229220
}
230-
231-
self.mouseMoved = false;
232-
233-
self._trigger( "stop" );
234-
return false;
221+
else {
222+
// this is just a click, change the value
223+
self.refresh( self.beforeStart === 0 ? 1 : 0 );
224+
}
235225
}
236-
});
237226

227+
self.mouseMoved = false;
228+
self._trigger( "stop" );
229+
return false;
230+
}
231+
};
232+
233+
slider.add( document ).bind( "vmouseup", this._sliderMouseUp );
238234
slider.insertAfter( control );
239235

240236
// Only add focus class to toggle switch, sliders get it automatically from ui-btn
@@ -327,6 +323,11 @@ $.widget( "mobile.slider", $.mobile.widget, {
327323
parseFloat( this.element.val() ) : this.element[0].selectedIndex;
328324
},
329325

326+
_destroy: function() {
327+
$( document ).unbind( "vmousemove", this._preventDocumentDrag );
328+
$( document ).unbind( "vmouseup", this._sliderMouseUp );
329+
},
330+
330331
refresh: function( val, isfromControl, preventInputUpdate ) {
331332

332333
// NOTE: we don't return here because we want to support programmatic

js/widgets/forms/textinput.js

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ $.widget( "mobile.textinput", $.mobile.widget, {
2121

2222
_create: function() {
2323

24-
var input = this.element,
24+
var self = this,
25+
input = this.element,
2526
o = this.options,
2627
theme = o.theme || $.mobile.getInheritedTheme( this.element, "c" ),
2728
themeclass = " ui-body-" + theme,
@@ -106,61 +107,64 @@ $.widget( "mobile.textinput", $.mobile.widget, {
106107
if ( input.is( "textarea" ) ) {
107108
var extraLineHeight = 15,
108109
keyupTimeoutBuffer = 100,
109-
keyup = function() {
110-
var scrollHeight = input[ 0 ].scrollHeight,
111-
clientHeight = input[ 0 ].clientHeight;
112-
113-
if ( clientHeight < scrollHeight ) {
114-
input.height(scrollHeight + extraLineHeight);
115-
}
116-
},
117110
keyupTimeout;
118111

112+
this._keyup = function() {
113+
var scrollHeight = input[ 0 ].scrollHeight,
114+
clientHeight = input[ 0 ].clientHeight;
115+
116+
if ( clientHeight < scrollHeight ) {
117+
input.height(scrollHeight + extraLineHeight);
118+
}
119+
};
120+
119121
input.keyup(function() {
120122
clearTimeout( keyupTimeout );
121-
keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer );
123+
keyupTimeout = setTimeout( self._keyup, keyupTimeoutBuffer );
122124
});
123125

124126
// binding to pagechange here ensures that for pages loaded via
125127
// ajax the height is recalculated without user input
126-
$( document ).one( "pagechange", keyup );
128+
$( document ).one( "pagechange", this._keyup );
127129

128130
// Issue 509: the browser is not providing scrollHeight properly until the styles load
129131
if ( $.trim( input.val() ) ) {
130132
// bind to the window load to make sure the height is calculated based on BOTH
131133
// the DOM and CSS
132-
$( window ).load( keyup );
134+
$( window ).load( this._keyup );
133135
}
134136
}
135137
if ( input.attr( "disabled" ) ) {
136138
this.disable();
137139
}
138140
},
139141

140-
disable: function() {
142+
_destroy: function() {
143+
$( window ).unbind( "load", this._keyup );
144+
},
141145

146+
disable: function() {
142147
var $el;
143148
if ( this.element.attr( "disabled", true ).is( "[type='search'], :jqmData(type='search')" ) ) {
144149
$el = this.element.parent();
145150
} else {
146151
$el = this.element;
147-
}
152+
}
148153
$el.addClass( "ui-disabled" );
149154
return this._setOption( "disabled", true );
150-
151155
},
152156

153157
enable: function() {
154-
155158
var $el;
159+
160+
// TODO using more than one line of code is acceptable ;)
156161
if ( this.element.attr( "disabled", false ).is( "[type='search'], :jqmData(type='search')" ) ) {
157162
$el = this.element.parent();
158163
} else {
159164
$el = this.element;
160-
}
165+
}
161166
$el.removeClass( "ui-disabled" );
162167
return this._setOption( "disabled", false );
163-
164168
}
165169
});
166170

tests/unit/slider/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ <h2 id="qunit-userAgent"></h2>
106106
<label for="mouseup-refresh">Input slider:</label>
107107
<input type="range" name="slider" id="mouseup-refresh" value="25" min="0" max="100"/>
108108
</div>
109+
110+
<div data-role="fieldcontain">
111+
<label for="remove-events-slider">Input slider:</label>
112+
<input type="range" name="remove-events-slider" id="remove-events-slider" value="25" min="0" max="100"/>
113+
</div>
109114
</div>
110115

111116
<div id="enhancetest">

tests/unit/slider/slider_core.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@
6262
expect( 1 );
6363
var slider = $( "#mouseup-refresh" );
6464

65-
6665
slider.val( parseInt(slider.val(), 10) + 10 );
6766
slider.change(function() {
6867
ok( true, "slider changed" );

tests/unit/slider/slider_events.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,15 +386,33 @@
386386
},
387387

388388
"slidestart", function( timeout ) {
389-
ok( !timeout, "slidermovestart fired" );
389+
ok( !timeout, "slidestart fired" );
390390
slider.trigger( "mouseup" );
391391
},
392392

393393
"slidestop", function( timeout ) {
394-
ok( !timeout, "slidermovestop fired" );
394+
ok( !timeout, "slidestop fired" );
395395
start();
396396
}
397397
], 500);
398398
});
399399

400+
test( "slider should detach event", function() {
401+
var slider = $( "#remove-events-slider" ),
402+
doc = $( document ),
403+
vmouseupLength,
404+
vmousemoveLength;
405+
406+
function getDocumentEventsLength( name ){
407+
return (doc.data( 'events' )[name] || []).length;
408+
}
409+
410+
vmouseupLength = getDocumentEventsLength( "vmouseup" );
411+
vmousemoveLength = getDocumentEventsLength( "vmousemove" );
412+
413+
slider.remove();
414+
415+
equal(getDocumentEventsLength( "vmouseup" ), (vmouseupLength - 1), 'vmouseup event was removed');
416+
equal(getDocumentEventsLength( "vmousemove" ), (vmousemoveLength - 1), 'vmousemove event was removed');
417+
});
400418
})(jQuery);

tests/unit/textinput/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ <h2 id="qunit-userAgent"></h2>
5454
</textarea>
5555
<a href="external.html" id="external">external</a>
5656

57+
<textarea id="destroycorrectly">Test Value</textarea>
58+
5759
<input type="search" id="search-input">
5860
</div>
5961
</body>

tests/unit/textinput/textinput_core.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@
44
(function($){
55
module( "jquery.mobile.forms.textinput.js" );
66

7+
test( "input is cleaned up on destroy", function(){
8+
var input = $( "#destroycorrectly" ),
9+
win = $( window ),
10+
loadLen;
11+
12+
loadLen = win.data("events").load.length;
13+
14+
input.remove();
15+
16+
equal(win.data("events").load.length, (loadLen-1), "window load event was not removed");
17+
});
18+
719
test( "inputs without type specified are enhanced", function(){
820
ok( $( "#typeless-input" ).hasClass( "ui-input-text" ) );
921
});

0 commit comments

Comments
 (0)