HierMenus CENTRAL: HierMenus In Progress. HierMenus 5.2.1 Release Notes (2/2)
[previous] |
The Cure For Small Menus
In previous HM releases, our KeepInWindow logic always forced the lower edge of the menu to be (at least) just above the lower border of the browser window. When we introduced the KeepInWindow overrides in HM 5.2, however, we had to change this assumption; since it was possible that the user wanted the menu to remain exactly where it was, even if part of it was below the lower browser window border. Therefore, we needed to check for potential menu scrolling by looking at the locations of both the top and bottom of the menus:
if(((this.yPos WindowBottomEdge)){
This was all well and good; but what we forgot about is that the
MenuBottomEdge is not readjusted when the menu is repositioned upwards as
part of the normal KeepInWindow routine. So the actual
bottom edge of the menu in the window may no longer be where MenuBottomEdge
says it is. The fix for this, of course, is to ensure that MenuBottomEdge is
corrected whenever the menu is moved vertically:
if ((MenuBottomEdge > WindowBottomEdge) && (this.hasParent||this.tree.TopKeepInWindowY)) { var dif = MenuBottomEdge - WindowBottomEdge; this.yPos -= dif; // 5.2.1 MenuBottomEdge = WindowBottomEdge; }
This fix alone corrects both of the problems displayed on the previous page; since in both of those cases the standard KeepInWindow logic should have been applied. However, what if the user wanted a small, top level menu to appear at a specific spot (utilizing the KeepInWindow overrides), and that particular spot was near or at the lower border of the browser window?
In that case, we may still have a problem; since we added no checks to the logic to ensure that the menu itself was large enough to accommodate scrollbars. Our normal calculation for setting the scrolling height of a menu is to take the larger of the available space for the menu (which is either the height of the window itself or the difference between the current top of the menu and the bottom of the viewable area of the browser window) or the minimum scroll height (introduced with HierMenus 5.0) plus two times the scrollbar height. In pseudo-code:
ScrollHeight = Math.max(available space, minimum scroll height + 2x scroll bar height);
Nowhere in this calculation is the initial total height of the menu accounted for; and thus HM 5.2 will, in the right combination of circumstances, attempt to set the scrolling height of the menu to be taller than the menu's total height. This results in a confusing, unhelpful menu display; so beginning with HM 5.2.1 we will not apply scrollbars to a menu if its total height is less then the height we need to display scrollbars in the first place.
Spoofin' Safari
Safari, like most--if not all--other modern browsers, allows an end user to "spoof" a different browser; that is, it allows the user to surf to a site using Safari, while identifying itself as something other than "Safari." Like the other browsers, Safari accomplishes this spoofing by changing various identifiers within the browser itself. The most notable of these changes is the HTTP User Agent string, which can be accessed in JavaScript through navigator.userAgent.
In HM we try to avoid identifying specific browsers; preferring, where possible, to identify specific features of a browser or its general capabilities in order to make logical decisions. However, there are some cases where we need to identify a particular browser or browser version in order to work around an implementation difference within that browser that cannot easily be identified otherwise. For example, when Netscape changed the way offsetLeft and offsetTop were utilized between verion 6 and 6.1, it became necessary to identify these browsers and differentiate between them in order to properly support menu positioning in both. In the case of Safari, two HM behaviors are handled differently from its Gecko counterpart. The innerHeight property of the window object accounts for the space used or not used by the horizontal scroll bars (Gecko doesn't), and Safari does not support the onload handler of a frame element (later version Gecko browsers do).
In HM, when the need arises to identify a specfic browser, we turn to the various properties of the navigator object for the necessary information. This is the purpose of the navigator object, to provide general information about the client and its capabilities, and we prefer using it as opposed to sniffing for the existence (or absence) of unique--but unrelated--JavaScript objects or methods within that browser.
In past HM 5 versions, we've sniffed for Safari by looking for the "Safari" keyword in the userAgent string as mentioned above. When, spoofing, however, Safari's userAgent does not contain the term "Safari." (Note that this is unlike Opera, which does contain the "Opera" keyword even when spoofing.) Obviously, a different approach will be necessary to identify the Safari browser.
As a result, we've created a slight tweak within HM_ScriptDOM.js. The new code specifically related to Safari spoofing is as follows:
HM_IsSafari = ((parseInt(navigator.productSub)>=20020000)&& (navigator.vendor.indexOf("Apple Computer")!=-1)); HM_NS6 = ((navigator.product == "Gecko")||(HM_IsSafari));
While not the prettiest of code, it accomplishes our goal; which is to identify the browser utilizing only information within the navigator object. Safari does not appear to alter the productSub or vendor strings in any of its spoof settings, and to the best of our knowledge it is the only browser which supplies both as above (and do contact us if you know otherwise). Note that having identified Safari, we also include it in the HM_NS6 class of browsers, so that in general it will follow logic branches in the same manner that Gecko browsers do; true to Safari's "like Gecko" capabilities. The HM_NS6 variable itself is a misnomer (what we really mean is IsGecko) but for historical and compatibility reasons we're leaving it as is.
Conclusion
As we mentioned at the outset, you may or may not consider v 5.2.1 as being a required upgrade; but if you are an existing HM 5 user and you are seeing or concerned with either of the problems discussed here then you are encouraged to grab the new code. And new users, of course, are always encouraged to start out with the latest release.
Files Changed in HM 5.2.1
- HM_ScriptDOM.js
- HM_ScriptOPR.js
- HM_ScriptIE4.js
- HM_ScriptNS4.js
- optimized/HM_ScriptDOM.js
- optimized/HM_ScriptOPR.js
- optimized/HM_ScriptIE4.js
- optimized/HM_ScriptNS4.js
Created: September 18, 2003
Revised: September 18, 2003
URL: https://www.webreference.com/dhtml/hiermenus/inprogress/8/2.html