From d8281a6e2209654dfcda1f3b809a25797c41fcfd Mon Sep 17 00:00:00 2001 From: Aparajita Fishman Date: Sat, 27 Jul 2013 09:27:58 -0400 Subject: [PATCH] Fixed: simplified the overlay scroller test, documented the technique. Previously the inner element's offsetWidth was tested before and after setting the overflow to scroll. This is unnecessary, we can just set the overflow to scroll and test the outer element's clientWidth vs. offsetWidth. By definition, clientWidth does not include scrollbars, whereas offsetWidth does. So if they are equal then overlay scrollers must be in use. Note that FireFox (as of version 22) does not support overlay scrollers, so even if the system does, Cappuccino will not on FireFox unless the programmer forces overlay scrollers. --- AppKit/CPScrollView.j | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/AppKit/CPScrollView.j b/AppKit/CPScrollView.j index 17cc94de9..439489982 100644 --- a/AppKit/CPScrollView.j +++ b/AppKit/CPScrollView.j @@ -34,38 +34,44 @@ /*! @ignore */ -var _isSystemUsingOverlayScrollers = function() +var _isBrowserUsingOverlayScrollers = function() { #if PLATFORM(DOM) - var inner = document.createElement('p'), - outer = document.createElement('div'); + /* + Even if the system supports overlay (Lion) scrollers, + the browser (e.g. FireFox *cough*) may not. - inner.style.width = "100%"; - inner.style.height = "200px"; + To determine if the browser is using overlay scrollbars, + we put a

element inside a shorter

and set its + overflow to scroll. If the browser is using visible scrollers, + the outer div's clientWidth will less than the offsetWidth, because + clientWidth does not include scrollbars, whereas offsetWidth does. + So if clientWidth === offsetWidth, the scrollers must be overlay. + Even IE gets this right. + */ + var outer = document.createElement('div'), + inner = document.createElement('p'); + // position it absolute so it doesn't affect existing DOM elements outer.style.position = "absolute"; outer.style.top = "0px"; outer.style.left = "0px"; outer.style.visibility = "hidden"; outer.style.width = "200px"; outer.style.height = "150px"; - outer.style.overflow = "hidden"; + outer.style.overflow = "scroll"; + + inner.style.width = "100%"; + inner.style.height = "200px"; outer.appendChild(inner); document.body.appendChild(outer); - var w1 = inner.offsetWidth; - - outer.style.overflow = 'scroll'; - - var w2 = inner.offsetWidth; - - if (w1 === w2) - w2 = outer.clientWidth; + var usingOverlayScrollers = outer.clientWidth === outer.offsetWidth; document.body.removeChild(outer); - return (w1 === w2); + return usingOverlayScrollers; #else return NO; #endif @@ -135,7 +141,7 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay, var globalValue = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPScrollersGlobalStyle"]; if (globalValue === nil || globalValue === -1) - CPScrollerStyleGlobal = _isSystemUsingOverlayScrollers() ? CPScrollerStyleOverlay : CPScrollerStyleLegacy + CPScrollerStyleGlobal = _isBrowserUsingOverlayScrollers() ? CPScrollerStyleOverlay : CPScrollerStyleLegacy else CPScrollerStyleGlobal = globalValue; }