PageSourceSearch

http://www.kwiaht.org/SpryAssets/SpryMenuBar.js

js kwiaht.org collected 2026-09-24 09:58:53 UTC 9,732 bytes, 332 lines download raw bytes

1/* SpryMenuBar.js - Revision: Spry Preview Release 1.4 */
2
3// Copyright (c) 2006. Adobe Systems Incorporated.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8//
9//   * Redistributions of source code must retain the above copyright notice,
10//     this list of conditions and the following disclaimer.
11//   * Redistributions in binary form must reproduce the above copyright notice,
12//     this list of conditions and the following disclaimer in the documentation
13//     and/or other materials provided with the distribution.
14//   * Neither the name of Adobe Systems Incorporated nor the names of its
15//     contributors may be used to endorse or promote products derived from this
16//     software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28// POSSIBILITY OF SUCH DAMAGE.
29
30/*******************************************************************************
31
32 SpryMenuBar.js
33 This file handles the JavaScript for Spry Menu Bar.  You should have no need
34 to edit this file.  Some highlights of the MenuBar object is that timers are
35 used to keep submenus from showing up until the user has hovered over the parent
36 menu item for some time, as well as a timer for when they leave a submenu to keep
37 showing that submenu until the timer fires.
38
39 *******************************************************************************/
40
41var Spry;
42if(!Spry)
43{
44	Spry = {};
45}
46if(!Spry.Widget)
47{
48	Spry.Widget = {};
49}
50
51// Constructor for Menu Bar
52// element should be an ID of an unordered list (<ul> tag)
53// preloadImage1 and preloadImage2 are images for the rollover state of a menu
54Spry.Widget.MenuBar = function(element, opts)
55{
56	this.init(element, opts);
57};
58
59Spry.Widget.MenuBar.prototype.init = function(element, opts)
60{
61	this.element = this.getElement(element);
62
63	// represents the current (sub)menu we are operating on
64	this.currMenu = null;
65
66	var isie = (typeof document.all != 'undefined' && typeof window.opera == 'undefined' && navigator.vendor != 'KDE');
67	if(typeof document.getElementById == 'undefined' || (navigator.vendor == 'Apple Computer, Inc.' && typeof window.XMLHttpRequest == 'undefined') || (isie && typeof document.uniqueID == 'undefined'))
68	{
69		// bail on older unsupported browsers
70		return;
71	}
72
73	// load hover images now
74	if(opts)
75	{
76		for(var k in opts)
77		{
78			var rollover = new Image;
79			rollover.src = opts[k];
80		}
81	}
82
83	if(this.element)
84	{
85		this.currMenu = this.element;
86		var items = this.element.getElementsByTagName('li');
87		for(var i=0; i<items.length; i++)
88		{
89			this.initialize(items[i], element, isie);
90			if(isie)
91			{
92				this.addClassName(items[i], "MenuBarItemIE");
93				items[i].style.position = "static";
94			}
95		}
96		if(isie)
97		{
98			if(this.hasClassName(this.element, "MenuBarVertical"))
99			{
100				this.element.style.position = "relative";
101			}
102			var linkitems = this.element.getElementsByTagName('a');
103			for(var i=0; i<linkitems.length; i++)
104			{
105				linkitems[i].style.position = "relative";
106			}
107		}
108	}
109};
110
111Spry.Widget.MenuBar.prototype.getElement = function(ele)
112{
113	if (ele && typeof ele == "string")
114		return document.getElementById(ele);
115	return ele;
116};
117
118Spry.Widget.MenuBar.prototype.hasClassName = function(ele, className)
119{
120	if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)
121	{
122		return false;
123	}
124	return true;
125};
126
127Spry.Widget.MenuBar.prototype.addClassName = function(ele, className)
128{
129	if (!ele || !className || this.hasClassName(ele, className))
130		return;
131	ele.className += (ele.className ? " " : "") + className;
132};
133
134Spry.Widget.MenuBar.prototype.removeClassName = function(ele, className)
135{
136	if (!ele || !className || !this.hasClassName(ele, className))
137		return;
138	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
139};
140
141// addEventListener for Menu Bar
142// attach an event to a tag without creating obtrusive HTML code
143Spry.Widget.MenuBar.prototype.addEventListener = function(element, eventType, handler, capture)
144{
145	try
146	{
147		if (element.addEventListener)
148		{
149			element.addEventListener(eventType, handler, capture);
150		}
151		else if (element.attachEvent)
152		{
153			element.attachEvent('on' + eventType, handler);
154		}
155	}
156	catch (e) {}
157};
158
159// createIframeLayer for Menu Bar
160// creates an IFRAME underneath a menu so that it will show above form controls and ActiveX
161Spry.Widget.MenuBar.prototype.createIframeLayer = function(menu)
162{
163	var layer = document.createElement('iframe');
164	layer.tabIndex = '-1';
165	layer.src = 'javascript:false;';
166	menu.parentNode.appendChild(layer);
167	
168	layer.style.left = menu.offsetLeft + 'px';
169	layer.style.top = menu.offsetTop + 'px';
170	layer.style.width = menu.offsetWidth + 'px';
171	layer.style.height = menu.offsetHeight + 'px';
172};
173
174// removeIframeLayer for Menu Bar
175// removes an IFRAME underneath a menu to reveal any form controls and ActiveX
176Spry.Widget.MenuBar.prototype.removeIframeLayer =  function(menu)
177{
178	var layers = menu.parentNode.getElementsByTagName('iframe');
179	while(layers.length > 0)
180	{
181		layers[0].parentNode.removeChild(layers[0]);
182	}
183};
184
185// clearMenus for Menu Bar
186// root is the top level unordered list (<ul> tag)
187Spry.Widget.MenuBar.prototype.clearMenus = function(root)
188{
189	var menus = root.getElementsByTagName('ul');
190	for(var i=0; i<menus.length; i++)
191	{
192		this.hideSubmenu(menus[i]);
193	}
194	this.removeClassName(this.element, "MenuBarActive");
195};
196
197// bubbledTextEvent for Menu Bar
198// identify bubbled up text events in Safari so we can ignore them
199Spry.Widget.MenuBar.prototype.bubbledTextEvent = function()
200{
201	return (navigator.vendor == 'Apple Computer, Inc.' && (event.target == event.relatedTarget.parentNode || (event.eventPhase == 3 && event.target.parentNode == event.relatedTarget)));
202};
203
204// showSubmenu for Menu Bar
205// set the proper CSS class on this menu to show it
206Spry.Widget.MenuBar.prototype.showSubmenu = function(menu)
207{
208	if(this.currMenu)
209	{
210		this.clearMenus(this.currMenu);
211		this.currMenu = null;
212	}
213	
214	if(menu)
215	{
216		this.addClassName(menu, "MenuBarSubmenuVisible");
217		if(typeof document.all != 'undefined' && typeof window.opera == 'undefined' && navigator.vendor != 'KDE')
218		{
219			if(!this.hasClassName(this.element, "MenuBarHorizontal") || menu.parentNode.parentNode != this.element)
220			{
221				menu.style.top = menu.parentNode.offsetTop + 'px';
222			}
223		}
224		if(typeof document.uniqueID != "undefined")
225		{
226			this.createIframeLayer(menu);
227		}
228	}
229	this.addClassName(this.element, "MenuBarActive");
230};
231
232// hideSubmenu for Menu Bar
233// remove the proper CSS class on this menu to hide it
234Spry.Widget.MenuBar.prototype.hideSubmenu = function(menu)
235{
236	if(menu)
237	{
238		this.removeClassName(menu, "MenuBarSubmenuVisible");
239		if(typeof document.all != 'undefined' && typeof window.opera == 'undefined' && navigator.vendor != 'KDE')
240		{
241			menu.style.top = '';
242			menu.style.left = '';
243		}
244		this.removeIframeLayer(menu);
245	}
246};
247
248// initialize for Menu Bar
249// create event listeners for the Menu Bar widget so we can properly
250// show and hide submenus
251Spry.Widget.MenuBar.prototype.initialize = function(listitem, element, isie)
252{
253	var opentime, closetime;
254	var link = listitem.getElementsByTagName('a')[0];
255	var submenus = listitem.getElementsByTagName('ul');
256	var menu = (submenus.length > 0 ? submenus[0] : null);
257
258	var hasSubMenu = false;
259	if(menu)
260	{
261		this.addClassName(link, "MenuBarItemSubmenu");
262		hasSubMenu = true;
263	}
264
265	if(!isie)
266	{
267		// define a simple function that comes standard in IE to determine
268		// if a node is within another node
269		listitem.contains = function(testNode)
270		{
271			// this refers to the list item
272			if(testNode == null)
273			{
274				return false;
275			}
276			if(testNode == this)
277			{
278				return true;
279			}
280			else
281			{
282				return this.contains(testNode.parentNode);
283			}
284		};
285	}
286	
287	// need to save this for scope further down
288	var self = this;
289
290	this.addEventListener(listitem, 'mouseover', function(e)
291	{
292		if(self.bubbledTextEvent())
293		{
294			// ignore bubbled text events
295			return;
296		}
297		clearTimeout(closetime);
298		if(self.currMenu == listitem)
299		{
300			self.currMenu = null;
301		}
302		// show menu highlighting
303		self.addClassName(link, hasSubMenu ? "MenuBarItemSubmenuHover" : "MenuBarItemHover");
304		if(menu && !self.hasClassName(menu, "MenuBarSubmenuVisible"))
305		{
306			opentime = window.setTimeout(function(){self.showSubmenu(menu);}, 250);
307		}
308	}, false);
309
310	this.addEventListener(listitem, 'mouseout', function(e)
311	{
312		if(self.bubbledTextEvent())
313		{
314			// ignore bubbled text events
315			return;
316		}
317
318		var related = (typeof e.relatedTarget != 'undefined' ? e.relatedTarget : e.toElement);
319		if(!listitem.contains(related))
320		{
321			clearTimeout(opentime);
322			self.currMenu = listitem;
323
324			// remove menu highlighting
325			self.removeClassName(link, hasSubMenu ? "MenuBarItemSubmenuHover" : "MenuBarItemHover");
326			if(menu)
327			{
328				closetime = window.setTimeout(function(){self.hideSubmenu(menu);}, 600);
329			}
330		}
331	}, false);
332};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.