Bug Tracker

Ticket #1731: 1731.2.diff

File 1731.2.diff, 6.5 KB (added by brandon, 15 years ago)

Fixes leaks in remove, html, empty and expands small variables

  • src/core.js

     
    12461246
    12471247        remove: function( selector ) {
    12481248                if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
    1249                         jQuery.removeData( this );
     1249                        // Prevent memory leaks
     1250                        jQuery( "*", this ).add(this).each(function(){
     1251                                jQuery.event.remove(this);
     1252                                jQuery.removeData(this);
     1253                        });
    12501254                        this.parentNode.removeChild( this );
    12511255                }
    12521256        },
    12531257
    12541258        empty: function() {
    1255                 // Clean up the cache
    1256                 jQuery( "*", this ).each(function(){
    1257                         jQuery.removeData(this);
    1258                 });
    1259 
     1259                // Remove element nodes and prevent memory leaks
     1260                jQuery( ">*", this ).remove();
     1261               
     1262                // Remove any remaining nodes
    12601263                while ( this.firstChild )
    12611264                        this.removeChild( this.firstChild );
    12621265        }
  • src/event.js

     
    4343                // Init the element's event structure
    4444                var events = jQuery.data(element, "events") || jQuery.data(element, "events", {});
    4545               
    46                 var handle = jQuery.data(element, "handle", function(){
     46                var handle = jQuery.data(element, "handle") || jQuery.data(element, "handle", function(){
    4747                        // returned undefined or false
    4848                        var val;
    4949
     
    149149                } else {
    150150                        var val, ret, fn = jQuery.isFunction( element[ type ] || null ),
    151151                                // Check to see if we need to provide a fake event, or not
    152                                 evt = !data[0] || !data[0].preventDefault;
     152                                event = !data[0] || !data[0].preventDefault;
    153153                       
    154154                        // Pass along a fake event
    155                         if ( evt )
     155                        if ( event )
    156156                                data.unshift( this.fix({ type: type, target: element }) );
    157157
    158158                        // Enforce the right trigger type
     
    167167                                val = false;
    168168
    169169                        // Extra functions don't get the custom event object
    170                         if ( evt )
     170                        if ( event )
    171171                                data.shift();
    172172
    173173                        // Handle triggering of extra function
     
    197197                var parts = event.type.split(".");
    198198                event.type = parts[0];
    199199
    200                 var c = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
     200                var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
    201201                args.unshift( event );
    202202
    203                 for ( var j in c ) {
     203                for ( var j in handlers ) {
     204                        var handler = handlers[j];
    204205                        // Pass in a reference to the handler function itself
    205206                        // So that we can later remove it
    206                         args[0].handler = c[j];
    207                         args[0].data = c[j].data;
     207                        args[0].handler = handler;
     208                        args[0].data = handler.data;
    208209
    209210                        // Filter the functions by class
    210                         if ( !parts[1] || c[j].type == parts[1] ) {
    211                                 var tmp = c[j].apply( this, args );
     211                        if ( !parts[1] || handler.type == parts[1] ) {
     212                                var ret = handler.apply( this, args );
    212213
    213214                                if ( val !== false )
    214                                         val = tmp;
     215                                        val = ret;
    215216
    216                                 if ( tmp === false ) {
     217                                if ( ret === false ) {
    217218                                        event.preventDefault();
    218219                                        event.stopPropagation();
    219220                                }
     
    265266
    266267                // Calculate pageX/Y if missing and clientX/Y available
    267268                if ( event.pageX == null && event.clientX != null ) {
    268                         var e = document.documentElement, b = document.body;
    269                         event.pageX = event.clientX + (e && e.scrollLeft || b && b.scrollLeft || 0);
    270                         event.pageY = event.clientY + (e && e.scrollTop || b && b.scrollTop || 0);
     269                        var doc = document.documentElement, body = document.body;
     270                        event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0);
     271                        event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0);
    271272                }
    272273                       
    273274                // Add which for key events
     
    322323
    323324        toggle: function() {
    324325                // Save reference to arguments for access in closure
    325                 var a = arguments;
     326                var args = arguments;
    326327
    327                 return this.click(function(e) {
     328                return this.click(function(event) {
    328329                        // Figure out which function to execute
    329330                        this.lastToggle = 0 == this.lastToggle ? 1 : 0;
    330331                       
    331332                        // Make sure that clicks stop
    332                         e.preventDefault();
     333                        event.preventDefault();
    333334                       
    334335                        // and execute the function
    335                         return a[this.lastToggle].apply( this, [e] ) || false;
     336                        return args[this.lastToggle].apply( this, [event] ) || false;
    336337                });
    337338        },
    338339
    339         hover: function(f,g) {
     340        hover: function(fnOver, fnOut) {
    340341               
    341342                // A private function for handling mouse 'hovering'
    342                 function handleHover(e) {
     343                function handleHover(event) {
    343344                        // Check if mouse(over|out) are still within the same parent element
    344                         var p = e.relatedTarget;
     345                        var parent = event.relatedTarget;
    345346       
    346347                        // Traverse up the tree
    347                         while ( p && p != this ) try { p = p.parentNode; } catch(e) { p = this; };
     348                        while ( parent && parent != this ) try { parent = parent.parentNode; } catch(error) { parent = this; };
    348349                       
    349350                        // If we actually just moused on to a sub-element, ignore it
    350                         if ( p == this ) return false;
     351                        if ( parent == this ) return false;
    351352                       
    352353                        // Execute the right function
    353                         return (e.type == "mouseover" ? f : g).apply(this, [e]);
     354                        return (event.type == "mouseover" ? fnOver : fnOut).apply(this, [event]);
    354355                }
    355356               
    356357                // Bind the function to the two event listeners
    357358                return this.mouseover(handleHover).mouseout(handleHover);
    358359        },
    359360       
    360         ready: function(f) {
     361        ready: function(fn) {
    361362                // Attach the listeners
    362363                bindReady();
    363364
    364365                // If the DOM is already ready
    365366                if ( jQuery.isReady )
    366367                        // Execute the function immediately
    367                         f.apply( document, [jQuery] );
     368                        fn.apply( document, [jQuery] );
    368369                       
    369370                // Otherwise, remember the function for later
    370371                else
    371372                        // Add the function to the wait list
    372                         jQuery.readyList.push( function() { return f.apply(this, [jQuery]); } );
     373                        jQuery.readyList.push( function() { return fn.apply(this, [jQuery]); } );
    373374       
    374375                return this;
    375376        }
     
    409410
    410411jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
    411412        "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
    412         "submit,keydown,keypress,keyup,error").split(","), function(i,o){
     413        "submit,keydown,keypress,keyup,error").split(","), function(i, name){
    413414       
    414415        // Handle event binding
    415         jQuery.fn[o] = function(f){
    416                 return f ? this.bind(o, f) : this.trigger(o);
     416        jQuery.fn[name] = function(fn){
     417                return fn ? this.bind(name, fn) : this.trigger(name);
    417418        };
    418419});
    419420
     
    451452        // A fallback to window.onload, that will always work
    452453        jQuery.event.add( window, "load", jQuery.ready );
    453454}
     455
     456// Prevent memory leaks in IE
     457if ( jQuery.browser.msie )
     458        jQuery(window).bind("unload", function() {
     459                $("*").add([document, window]).unbind();
     460        });