
--------------------------
The JavaScript Layers Menu
--------------------------

Browser detection
-----------------

The following cases are considered:
IE4 --> internet explorer 4
NS4 --> Netscape 4.x
DOM --> Document Object Model ( http://www.w3c.org/DOM/ )

We make the simplifying assumption that sufficiently recent browsers
(Mozilla >= 0.6, NS6, Opera 5, IE >= 5) can be considered compliant
to the DOM specifications if only not-so-much-advanced features are employed :)

Working principle
-----------------

The generation of layers is based on a depth-first search over the tree,
as it can be easily understood examining layersmenu.txt.
The depth-first search allows to logically arrange in a one-dimension
sequence the tree's nodes, just as the directories in file managers
providing a tree view (for example, the Gnome's "gmc" and the ms windows'
file browser) when all branches are expanded, to show all subdirectories.

Nodes-layers correspondence
---------------------------

In the categories tree, the "root node" is represented by the "Top" category,
that does not appear in the layers menu.
Then we have to consider the children of the root node, i.e. the "first-level"
subcategories (of "Top"), that have to be handled differently
from the other nodes, as they have to be always visible on the page.
Finally, we have to distinguish leaf nodes - i.e. the ones without children -
(categories without corresponding subcategories) from all the other nodes;
such distinction is significant also for the children of the root node
("first-level" subcategories); in the subsequent part of the present document
it will be clear why leaf nodes have to be handled a bit differently
from the other nodes.

Layers menu <--> Tree menu, the underlying algorithm
----------------------------------------------------

The algorithm employed to generate the needed layers follows the same
scan of nodes performed in the Tree Menu 1.1, authored by
Bjorge Dijkstra <bjorge@gmx.net> and published at
http://www.zinc.f2s.com/scriptorium/index.php/treemenu
In fact, the Layers menu scans the nodes reading a file with the same "format"
used by the TreeMenu 1.1; such "format" choice has been done just to guarantee
the same interface for the final users.

Only a little clarification about the integration of the TreeMenu
into PgMarket.
In PgMarket, also no-frame use of the TreeMenu is foreseen,
hence the URL must be able to contain the list of nodes to be expanded.
To avoid ambiguity, in the file format, "|" has been replaces by "^".
For uniformity reasons, this change has been extended also to the
version of the Layers menu integrated in PgMarket.
Another obvious difference: the versions of TreeMenu and Layers menu
integrated in PgMarket do not scan nodes reading inside a file;
they scan a string generated "on the fly" querying the database
w.r.t. the categories structure.

To achieve format compatibility with TreeMenu, the "off-line" version
of the Layers menu does not present the above mentioned differences:
it reads just from a file and the file format foresees the use of "|", not "^".

Implementation driving rules
----------------------------

Each layer lists all the children of a not-leaf node;
each of these children has a link to the corresponding URL associated with.

The root node's children (i.e. the subcategories of "Top") can be considered
as belonging to a "special" layer, as they have to be always visible
on the page, while, in the general case, all other layers are hidden.

Each layer is defined when it is involved by the depth-first search;
its geometrical placement is identified by its top-left corner coordinates
and it depends by the route leading to it.
In particular, its horizontal coordinate is determined by an offset
plus a quantity directly proportional to the hierarchical level of the
"father node" ("subcategory level"), while its vertical coordinate has to be
related to the vertical coordinate of the link corresponding to the
"father node" (as much as possible...).

We define a popUp([layername]) function, that is used to set as visible
the layer labeled as [layername]; for a given layer, the label (name)
is obtained as 'L[N]', where [N] is a progressive integer number,
identifying the position (line) of the father node inside the depth-first
search result (starting from 0 for the root node).

We define a shutdown() function, that is used to set as hidden all the layers
(only links related the root node's children are always visible on the page).

For each layer, a popUplayername() function is defined, that is used to set
as visible all layers corresponding to the route leading to the layer,
starting from the link related to a root node's child.
All other layers have to be hidden, hence such a function starts calling
the shutdown() and the set as visible all the layers on the name route.

We impose that the Layers menu behaviour is completely analogous
to the behaviour of the Gnome and KDE main menus and of the "start" menu
of ms windows.
This last rule implies the following sub rules.

	In any case, a click event outside of visible layers
	has to trigger the hiding (shutdown()) of all the layers.

	The positioning of the mouse pointer over a link corresponding
	to a non-lead node has to trigger the visibility of all the layers
	on the route to the layer containing the "children of the link",
	and only of that layers, while all the others have to be hidden.

	The positioning of the mouse pointer over a link corresponding
	to a leaf node (category without subcategories) has to trigger
	the visibility of all the layers on the route to the layer
	under the mouse pointer, and only of that layers,
	while all the others have to be hidden.
	This rule implies also that, if the mouse pointer exits from a link
	corresponding to a non-leaf node and goes over a link corresponding
	to a leaf node, then the "highest level" layer among the visible ones,
	will become hidden.
	For a leaf node which is a root node's child, this rule simply implies
	a shutdown().

Useful hints
------------

In layersmenu-header.inc.php there are two "if" blocks to handle
the root node's children differently from children with hierarchical level > 1.
In these blocks, there are some commented out lines of code.
They are intended as an alternative to the corresponding non-commented out
lines of code.
The corresponding alternative can be useful when you want to associate links
only to leaf nodes, i.e. when non-leaf subcategories are intended to be empty
(you are associating products only to leaf subcategories) and, hence,
it is unuseful to visit them.

It has been chosen to add to each layer a title, corresponding to the name
of the father node, for the following reason.
In a layers menu, there is not a strict visual correspondence
between a given layer and its "father link"; this correspondence may become
more evident if the layer has a title recalling the "father".
Moreover, while providing the flexibility related to "simple and free text"
links, it is difficult to exactly estimate the position of the text
for a generic link.
Currently, a reasonable assumption is made for the number of pixels
vertically occupied by a link; then the vertical coordinate of a link
inside its layer is estimated as an offset plus the product
of the assumed number of pixels and a progressive number identifying
the link inside its layer.
It has to be pointed out also that the vertical text size depends also
on the browser used on the client side and on the zoom selected for it,
if applicable (as an example, Mozilla provides this feature).
If the above mentioned assumption about the number of pixels is not exact,
in layers containing many links, the vertical coordinate estimate
can be rather rough especially for the latest links, and the alignment
between a given link and its "child" layer may be inaccurate.
In such cases, the layer title visually allows to more easily associate
a generic link and its "child" layer to each other.

How do you detect if a node is a leaf ?
Well, with all the tree ordered according to a depth-first search,
a node is a leaf if one of the following two conditions is true;
- it is the last node of the tree;
- it is not the last node of the tree, and the hierarchical level associated
  to the subsequent node is larger or equal to the current hierarchical level.
It should be rather easy to become convinced of this statement if the view
corresponding to a completely expanded tree menu is considered.

--
Marco Pratesi
http://www.telug.it
pratesi@telug.it

