From dafc6fd33607fb30c6a759eec4eb65614e9bef75 Mon Sep 17 00:00:00 2001 From: Anthony Fiti Date: Thu, 21 Apr 2011 10:34:48 -0700 Subject: [PATCH 1/2] Fixed for the first issue in #1422 - IE7 locks up in infinite JS resize events. The fix is to change how the detectResolutionBreakpoints function adds and removes classes from $html. The problem is that removing and adding those class names triggers the resize event again, resulting in infinite resize events. The solution is to come up with a new way to change the class names - by copying them off $html, adding and removing them locally in a variable, then checking to see if the class names have changed and applying the changed className string. Note that this would not be thread safe (any changes to $html.className would be lost if it were made between the read and the write) but since JS isn't threaded so we don't have to worry about that. --- js/jquery.mobile.media.js | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/js/jquery.mobile.media.js b/js/jquery.mobile.media.js index 7c0dbde0c25..130e75f1f18 100644 --- a/js/jquery.mobile.media.js +++ b/js/jquery.mobile.media.js @@ -59,24 +59,35 @@ function detectResolutionBreakpoints(){ minBreakpoints = [], maxBreakpoints = [], unit = "px", - breakpointClasses; - - $html.removeClass( minPrefix + resolutionBreakpoints.join(unit + " " + minPrefix) + unit + " " + - maxPrefix + resolutionBreakpoints.join( unit + " " + maxPrefix) + unit ); + breakpointClasses = "", + allBreakpointClasses = "", + newHtmlClassList = [], + finalClasses = ""; + newHtmlClassList = $html.attr('className').split(/\s+/); + + allBreakpointClasses = (minPrefix + resolutionBreakpoints.join(unit + " " + minPrefix) + unit + " " + + maxPrefix + resolutionBreakpoints.join( unit + " " + maxPrefix) + unit).split(/\s+/); + + $.each(allBreakpointClasses, function (i, breakpointClassName) { + var loc = jQuery.inArray(breakpointClassName, newHtmlClassList); + if (loc != -1) newHtmlClassList.splice(loc,1); + }); + $.each(resolutionBreakpoints,function( i, breakPoint ){ if( currWidth >= breakPoint ){ - minBreakpoints.push( minPrefix + breakPoint + unit ); + minBreakpoints.push( minPrefix + breakPoint + unit ); } if( currWidth <= breakPoint ){ - maxBreakpoints.push( maxPrefix + breakPoint + unit ); + maxBreakpoints.push( maxPrefix + breakPoint + unit ); } }); - + if( minBreakpoints.length ){ breakpointClasses = minBreakpoints.join(" "); } - if( maxBreakpoints.length ){ breakpointClasses += " " + maxBreakpoints.join(" "); } - - $html.addClass( breakpointClasses ); + if( maxBreakpoints.length ){ breakpointClasses += " " + maxBreakpoints.join(" "); } + + finalClasses = newHtmlClassList.join(" ") + " " + breakpointClasses; + if ($html.attr('className') != finalClasses) $html.attr('className', finalClasses); }; /* $.mobile.addResolutionBreakpoints method: From d3ca4f326184b2a33cb99c1d22a5f8f6667aa0e2 Mon Sep 17 00:00:00 2001 From: Anthony Fiti Date: Fri, 29 Apr 2011 08:42:39 -0700 Subject: [PATCH 2/2] Fixed style and added comments --- js/jquery.mobile.media.js | 52 ++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/js/jquery.mobile.media.js b/js/jquery.mobile.media.js index 130e75f1f18..d74cb2e5278 100644 --- a/js/jquery.mobile.media.js +++ b/js/jquery.mobile.media.js @@ -64,30 +64,42 @@ function detectResolutionBreakpoints(){ newHtmlClassList = [], finalClasses = ""; - newHtmlClassList = $html.attr('className').split(/\s+/); - - allBreakpointClasses = (minPrefix + resolutionBreakpoints.join(unit + " " + minPrefix) + unit + " " + - maxPrefix + resolutionBreakpoints.join( unit + " " + maxPrefix) + unit).split(/\s+/); - - $.each(allBreakpointClasses, function (i, breakpointClassName) { - var loc = jQuery.inArray(breakpointClassName, newHtmlClassList); - if (loc != -1) newHtmlClassList.splice(loc,1); + // Get classes, strip any existing resolution breakpoint classes + newHtmlClassList = $html.attr( 'className' ).split(/\s+/); + + allBreakpointClasses = ( minPrefix + resolutionBreakpoints.join( unit + " " + minPrefix ) + unit + " " + + maxPrefix + resolutionBreakpoints.join( unit + " " + maxPrefix ) + unit ).split(/\s+/); + + $.each( allBreakpointClasses, function ( i, breakpointClassName ) { + var loc = jQuery.inArray( breakpointClassName, newHtmlClassList ); + if ( loc !== -1 ) { + newHtmlClassList.splice( loc, 1 ); + } }); - - $.each(resolutionBreakpoints,function( i, breakPoint ){ - if( currWidth >= breakPoint ){ - minBreakpoints.push( minPrefix + breakPoint + unit ); + + // Calculate new resolution breakpoint classes for window size + $.each(resolutionBreakpoints,function( i, breakPoint ) { + if ( currWidth >= breakPoint ) { + minBreakpoints.push( minPrefix + breakPoint + unit ); } - if( currWidth <= breakPoint ){ - maxBreakpoints.push( maxPrefix + breakPoint + unit ); + if ( currWidth <= breakPoint ) { + maxBreakpoints.push( maxPrefix + breakPoint + unit ); } }); - - if( minBreakpoints.length ){ breakpointClasses = minBreakpoints.join(" "); } - if( maxBreakpoints.length ){ breakpointClasses += " " + maxBreakpoints.join(" "); } - - finalClasses = newHtmlClassList.join(" ") + " " + breakpointClasses; - if ($html.attr('className') != finalClasses) $html.attr('className', finalClasses); + + if ( minBreakpoints.length ) { + breakpointClasses = minBreakpoints.join( " " ); + } + if ( maxBreakpoints.length ) { + breakpointClasses += " " + maxBreakpoints.join( " " ); + } + + // Compose new class list, compare with current class assignment and assign only if necessary + // Fixes #1422 - IE7 infinite event loop - changing className fires resize event, which calls this f(x) + finalClasses = newHtmlClassList.join( " " ) + " " + breakpointClasses; + if ( $html.attr( 'className' ) !== finalClasses ) { + $html.attr( 'className', finalClasses ); + } }; /* $.mobile.addResolutionBreakpoints method: