HierMenus CENTRAL: HierMenus In Progress. HierMenus 5.3 Release Notes (4/7)
[previous] [next] |
Following Directions
It's recently been brought to our attention that HM does not display menus properly in HTML pages in which the text direction of the HTML document was set to rtl (right-to-left). After investigating the issues involved in the faulty display, we found that some of the problematic behavior was due to simple bugs or "misunderstandings" between HM and various browser's handling of rtl documents; while other problems resulted primarily from HM not properly applying the correct behavior to its own menus in rtl settings. On this page, we'll discuss the behavioral adjustments we've made to HM to allow it to render rtl pages as we believe document authors actually intend; on the next page we'll discuss those internal problems and misunderstandings, which partially affect both the Internet Explorer and Gecko-based browsers.
Introducing dir
For those unfamiliar with the HTML dir attribute, a quick introduction is in order. Available since the HTML 4.0 recommendation, the dir attribute, when placed on an element, defines the default directionality of contained text and tables which themselves do not have specific directionality applied; via subsequent lower level dir settings or precise UNICODE definitions. A full description of the dir attribute can be found here:
https://www.w3.org/TR/html4/struct/dirlang.html#adef-dir
While we won't dwell at length on the individual properties of right-to-left language script (indeed, we would hardly be qualified, anyway), you should know that when the dir attribute is set to rtl on the <html> and/or <body> element of a document, the browser significantly changes certain aspects of that page's display. It is precisely these changes that prompted our behavioral changes in HM 5.3. While this is certainly not an exhaustive listing (a full understanding of the bidi--Bi-Directional Algorithm--is necessary for that, and well beyond the scope of this document) these more general adjustments are worthy of our immediate attention.
Most elements are right-aligned.
This includes the document's text and tables. And since the dir attribute is automatically inherited by almost all elements of a page, this right alignment will occur within the page's individual container elements, as well.
Table layouts are reversed.
This is a main feature of dir. When a table is set to dir="rtl" (or the table is neutral and one of the table's containing elements is set to dir="rtl"), then the individual columns of the table are reversed; that is, the first column of the table is placed at the far right of the table layout, the second column to the left of the first column, and so on.
The vertical scroll bar, if one is present, is moved to the left side of the page.
This last behavior is, at least as of this writing, applied by default only in Internet Explorer v5 or later.
HM Behavior When dir="rtl"
Not all browsers support the above dir behaviors; most older browsers (including NS4, IE4, and IE5 Mac) will simply ignore the dir attribute and display the page as it would normally.
For the first point, that of elements and their contents being right-aligned, it's important to note that this right alignment will be applied to the contents of HM menus as well; meaning that your menu item descriptions will be right-aligned within the menu items themselves. This is due to the fact that dir settings are inherited from parent items, and all HierMenus have, as their immediate parent item, the document's body element. This actually happens automatically with no changes or intepretations necessary in the HM script, therefore no changes were necessary to accommodate this behavior.
We were tempted to ignore the second point--i.e., table layouts being reversed--since HM doesn't create tables (menus and menu items within them are represented internally as <div> elements). However, a good argument could be made that our horizontal menus strongly resemble table layouts; both in the way they are displayed and in the way they are defined (via the HM_Arrays definitions). Therefore, horizontal menus on pages where the direction setting is right-to-left will indeed be reversed, beginning with HM 5.3. You needn't do anything internally in HM to accomplish this; it will happen automatically as a result of the dir="rtl" setting of the document's <html> and/or <body> tag. The exception will be when HM's own HM_RightToLeft parameter is explicitly set on the menus, a scenario that will be discussed a little later on this page.
Finally, point 3 of the above page-behavior modifications required multiple adjustments to the HM code; but all of these were a result of bugs in HM or incorrect interpretation of Internet Explorer behavior where rtl processing is concerned. For those who are interested, these points are described on the next page.
What About HM_RightToLeft?
HierMenus has long supported the global, page, and menu specific parameter RightToLeft which indicates whether or not a menu should, by default, spawn child menus from the left side of the menu or the right side of the menu (and the corresponding "more" image is also positioned on the right or left, accordingly). Prior to HM 5.3, the default setting of HM_RightToLeft was false; but beginning with HM 5.3, HM_RightToLeft will take on the default directionality of the document in question (assuming that you have not specifically set HM_RightToLeft in your own configurations, in which case your specific setting always wins). In other words, if you specify dir="rtl" in your document, and you do not explicitly set HM_RightToLeft on the global, page, or menu specific level, and a visitor hits your pages with a browser capable of rtl rendering, then HM will assume that the HM_RightToLeft setting for that scenario is true. In all other scenarios, including the scenario where a user hits your site with a browser incapable of rtl rendering (such as NS4), HM_RightToLeft is set as false.
Two other minor behavioral differences are being introduced in conjunction with HM_RightToLeft. First, if the page itself is set to right-to-left processing (i.e., dir="rtl" is set on the page's <html> and/or <body> tag) but the HM_RightToLeft parameter has been set to false, then the menus will be created as if there was no rtl setting on the page. This allows page authors to set up pages where the general directionality of the page is right-to-left, but where the individual menus themselves--including the menu item contents--are displayed left-to-right. Secondly, for variable width menus that display their first child menus via the position_under parameter, those child menus will be right-aligned with their parent menu items when displayed, instead of left-aligned:
In this standard menu with position_under set, the page directionality
is set to ltr and the child menu aligns itself with the left side of
its parent item.
Here's the same menu; this time with page directionality set to rtl.
Note that here the child menu is aligned with the right edge of
its parent item. Note also that the menu items have been reversed; the first menu
item is displayed at the far left of the menu.
Having introduced new behaviors for the HM_RightToLeft parameter, we need to provide a new documentation entry for it:
HM_GL_RightToLeft and HM_PG_RightToLeft
- Description:
- Controls the cascade direction of child menus, right/left positioning of more images, and horizontal alignment of position_under child menus in relation to their parent items.
- Value:
- Boolean (true/false,1/0) or any expression that evaluates to a true/false value.
- Comments:
- This parameter can also be set on the menu tree level, as the 18th parameter in the configuration array of top level menu items.
Prior to HM 5.3, RightToLeft had no effect on the horizontal positioning of position_under child menus. This behavior was added with HM 5.3.
Prior to HM 5.3, the default for RightToLeft was always false. Beginning with HM 5.3, the default RightToLeft setting follows the directionality setting of the document, in combination with the browser's rtl display capabilities. i.e., If the browser is incapable of rtl displays, then HM_RightToLeft is set to false by default. If the browser is capable of rtl displays and the page is marked as an rtl page, then HM_RightToLeft is set to true.
Prior to HM 5.3, specifying HM_RightToLeft as false on a page where directionality is set to rtl would only affect the placement of the more image and which side of the menu child menus are spawned from; it would not alter the actual dir setting of the menu, which would contnue to display right-aligned items. Beginning with HM 5.3, when HM_RightToLeft is set to false on a page where dir="rtl", then all menus that it (HM_RightToLeft) pertains to are explicitly set to dir="ltr", allowing the page author to truly override the directionality on a menu tree by menu tree basis.- Examples:
- RightToLeft processing should be applied to menus:
HM_GL_RightToLeft = true;RightToLeft processing should not be applied to menus:
HM_PG_RightToLeft = 0;- Default:
- Follows the HTML dir setting of the page. Default is false for all browsers that do not support dir.
Advanced Topics
Adjusting Menu PopUp Location
By default, menus that pop up from an in-page link will be displayed at the current mouse position. That is, the top-left corner of the menu will be displayed at whereever the mouse was when the popup menu was triggered. In some cases this isn't appropriate for pages where directionality is set to rtl, since the links are most likely right-aligned on the page. You can therefore use the following menu positioning code in your own HM_Arrays implementations to conditionally place either the top-left corner of the menu at the mouse location, or the top-right corner of the menu at the mouse location:
function HM_f_GetMenuOffset(menuNum) { var menuID = HM_MenuIDPrefix + menuNum; var WidthEL = HM_DOM ? HM_MenusTarget.document.getElementById(menuID) : HM_IE ? HM_MenusTarget.document.all(menuID) : HM_MenusTarget[menuID]; var menuWidth = 0; if (WidthEL) { if (HM_NS4) { return WidthEL.clip.width; } else { if (!WidthEL.sizeFixed) WidthEL.fixSize(false); menuWidth = WidthEL.offsetWidth; } } if(HM_IE&&HM_DOM) return (menuWidth+16); else return menuWidth; } HM_Array1 = [ [150, // menu width "mouse_x_position - " + "(HM_f_RTLCheck() ? HM_f_GetMenuOffset(1) : 0)", // left_position , // top_position ,,,,,], // etc. ["Experts","/experts/",1,0,1], ["Contents","/index2.html",1,0,0], ...
In the above code, we use a custom routine which returns the width of the menu specified (pass the menu array number in as the argument) and we subtract that number from the current mouse position if the page is being displayed in rtl mode. If the page is being displayed in standard ltr mode, then the mouse position is used as is without any change. The page directionality check is facilitated via a built in HM procedure, HM_f_RTLCheck, which you are welcome to call on your own. It returns a simple true or false, and it is included in all of the HM scripts so you can use it generically in your menu array configurations (in the IE4 and NS4 scripts it simply returns false immediately).
Adjusting PopUps for IE Quirk
A quirk of the IE browser, which we'll go into a bit more thoroughly on page 6, makes it extremely difficult to know if the mouse position reported when the menu actually pops up is accurate in rtl settings. For this reason, if you use dir="rtl" and your vertical page scrollbar is always visible, we recommend that for Internet Explorer you always adjust the mouse position by the width of the scrollbar (typically about 16px). In the above solution we accomplished this by adding the 16px within HM_f_GetMenuOffset, but you could just as easily add it directly to your menu positioning logic:
HM_Array1 = [ [150, // menu width "mouse_x_position - "+ "(HM_DOM&&HM_IE&&HM_f_RTLCheck() ? 16 : 0)", // left_position , // top_position ,,,,,], // etc. ["Experts","/experts/",1,0,1], ["Contents","/index2.html",1,0,0], ...
This is admittedly kludgey, but as we'll describe on page 6, a more graceful means of discovering the perfect pixel location of the mouse in Internet Explorer pages where rtl is set has so far eluded us. Since the offset is fairly small, you might choose to subtract about 8px from the mouse left position of popped up menus, as a compromise solution that will look a little awkward, but still acceptable.
Having discussed HM's new behavior in regards to right-to-left processing, we'll now turn our attention to some of the behind-the-scenes details. Those not interested in knowing or understanding the finer aspects of cross-browser compatibility and JavaScript right-to-left processing might wish to jump to the last page of this article, where we'll discuss the remaining fixes incorporated into this HM release.
Created: October 23, 2003
Revised: October 23, 2003
URL: https://www.webreference.com/dhtml/hiermenus/inprogress/9/4.html