PageSourceSearch

http://web.fsct.com/SpryAssets/SpryMenuBar.js

js fsct.com collected 2026-10-01 14:41:00 UTC 23,188 bytes, 805 lines download raw bytes

1// SpryMenuBar.js - version 0.13 - Spry Pre-Release 1.6.1
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
41(function() { // BeginSpryComponent
42
43if (typeof Spry == "undefined") window.Spry = {}; if (!Spry.Widget) Spry.Widget = {};
44
45Spry.BrowserSniff = function()
46{
47	var b = navigator.appName.toString();
48	var up = navigator.platform.toString();
49	var ua = navigator.userAgent.toString();
50
51	this.mozilla = this.ie = this.opera = this.safari = false;
52	var re_opera = /Opera.([0-9\.]*)/i;
53	var re_msie = /MSIE.([0-9\.]*)/i;
54	var re_gecko = /gecko/i;
55	var re_safari = /(applewebkit|safari)\/([\d\.]*)/i;
56	var r = false;
57
58	if ( (r = ua.match(re_opera))) {
59		this.opera = true;
60		this.version = parseFloat(r[1]);
61	} else if ( (r = ua.match(re_msie))) {
62		this.ie = true;
63		this.version = parseFloat(r[1]);
64	} else if ( (r = ua.match(re_safari))) {
65		this.safari = true;
66		this.version = parseFloat(r[2]);
67	} else if (ua.match(re_gecko)) {
68		var re_gecko_version = /rv:\s*([0-9\.]+)/i;
69		r = ua.match(re_gecko_version);
70		this.mozilla = true;
71		this.version = parseFloat(r[1]);
72	}
73	this.windows = this.mac = this.linux = false;
74
75	this.Platform = ua.match(/windows/i) ? "windows" :
76					(ua.match(/linux/i) ? "linux" :
77					(ua.match(/mac/i) ? "mac" :
78					ua.match(/unix/i)? "unix" : "unknown"));
79	this[this.Platform] = true;
80	this.v = this.version;
81
82	if (this.safari && this.mac && this.mozilla) {
83		this.mozilla = false;
84	}
85};
86
87Spry.is = new Spry.BrowserSniff();
88
89// Constructor for Menu Bar
90// element should be an ID of an unordered list (<ul> tag)
91// preloadImage1 and preloadImage2 are images for the rollover state of a menu
92Spry.Widget.MenuBar = function(element, opts)
93{
94	this.init(element, opts);
95};
96
97Spry.Widget.MenuBar.prototype.init = function(element, opts)
98{
99	this.element = this.getElement(element);
100
101	// represents the current (sub)menu we are operating on
102	this.currMenu = null;
103	this.showDelay = 250;
104	this.hideDelay = 600;
105	if(typeof document.getElementById == 'undefined' || (navigator.vendor == 'Apple Computer, Inc.' && typeof window.XMLHttpRequest == 'undefined') || (Spry.is.ie && typeof document.uniqueID == 'undefined'))
106	{
107		// bail on older unsupported browsers
108		return;
109	}
110
111	// Fix IE6 CSS images flicker
112	if (Spry.is.ie && Spry.is.version < 7){
113		try {
114			document.execCommand("BackgroundImageCache", false, true);
115		} catch(err) {}
116	}
117
118	this.upKeyCode = Spry.Widget.MenuBar.KEY_UP;
119	this.downKeyCode = Spry.Widget.MenuBar.KEY_DOWN;
120	this.leftKeyCode = Spry.Widget.MenuBar.KEY_LEFT;
121	this.rightKeyCode = Spry.Widget.MenuBar.KEY_RIGHT;
122	this.escKeyCode = Spry.Widget.MenuBar.KEY_ESC;
123
124	this.hoverClass = 'MenuBarItemHover';
125	this.subHoverClass = 'MenuBarItemSubmenuHover';
126	this.subVisibleClass ='MenuBarSubmenuVisible';
127	this.hasSubClass = 'MenuBarItemSubmenu';
128	this.activeClass = 'MenuBarActive';
129	this.isieClass = 'MenuBarItemIE';
130	this.verticalClass = 'MenuBarVertical';
131	this.horizontalClass = 'MenuBarHorizontal';
132	this.enableKeyboardNavigation = true;
133
134	this.hasFocus = false;
135	// load hover images now
136	if(opts)
137	{
138		for(var k in opts)
139		{
140			if (typeof this[k] == 'undefined')
141			{
142				var rollover = new Image;
143				rollover.src = opts[k];
144			}
145		}
146		Spry.Widget.MenuBar.setOptions(this, opts);
147	}
148
149	// safari doesn't support tabindex
150	if (Spry.is.safari)
151		this.enableKeyboardNavigation = false;
152
153	if(this.element)
154	{
155		this.currMenu = this.element;
156		var items = this.element.getElementsByTagName('li');
157		for(var i=0; i<items.length; i++)
158		{
159			if (i > 0 && this.enableKeyboardNavigation)
160				items[i].getElementsByTagName('a')[0].tabIndex='-1';
161
162			this.initialize(items[i], element);
163			if(Spry.is.ie)
164			{
165				this.addClassName(items[i], this.isieClass);
166				items[i].style.position = "static";
167			}
168		}
169		if (this.enableKeyboardNavigation)
170		{
171			var self = this;
172			this.addEventListener(document, 'keydown', function(e){self.keyDown(e); }, false);
173		}
174
175		if(Spry.is.ie)
176		{
177			if(this.hasClassName(this.element, this.verticalClass))
178			{
179				this.element.style.position = "relative";
180			}
181			var linkitems = this.element.getElementsByTagName('a');
182			for(var i=0; i<linkitems.length; i++)
183			{
184				linkitems[i].style.position = "relative";
185			}
186		}
187	}
188};
189Spry.Widget.MenuBar.KEY_ESC = 27;
190Spry.Widget.MenuBar.KEY_UP = 38;
191Spry.Widget.MenuBar.KEY_DOWN = 40;
192Spry.Widget.MenuBar.KEY_LEFT = 37;
193Spry.Widget.MenuBar.KEY_RIGHT = 39;
194
195Spry.Widget.MenuBar.prototype.getElement = function(ele)
196{
197	if (ele && typeof ele == "string")
198		return document.getElementById(ele);
199	return ele;
200};
201
202Spry.Widget.MenuBar.prototype.hasClassName = function(ele, className)
203{
204	if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)
205	{
206		return false;
207	}
208	return true;
209};
210
211Spry.Widget.MenuBar.prototype.addClassName = function(ele, className)
212{
213	if (!ele || !className || this.hasClassName(ele, className))
214		return;
215	ele.className += (ele.className ? " " : "") + className;
216};
217
218Spry.Widget.MenuBar.prototype.removeClassName = function(ele, className)
219{
220	if (!ele || !className || !this.hasClassName(ele, className))
221		return;
222	ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
223};
224
225// addEventListener for Menu Bar
226// attach an event to a tag without creating obtrusive HTML code
227Spry.Widget.MenuBar.prototype.addEventListener = function(element, eventType, handler, capture)
228{
229	try
230	{
231		if (element.addEventListener)
232		{
233			element.addEventListener(eventType, handler, capture);
234		}
235		else if (element.attachEvent)
236		{
237			element.attachEvent('on' + eventType, handler);
238		}
239	}
240	catch (e) {}
241};
242
243// createIframeLayer for Menu Bar
244// creates an IFRAME underneath a menu so that it will show above form controls and ActiveX
245Spry.Widget.MenuBar.prototype.createIframeLayer = function(menu)
246{
247	var layer = document.createElement('iframe');
248	layer.tabIndex = '-1';
249	layer.src = 'javascript:""';
250	layer.frameBorder = '0';
251	layer.scrolling = 'no';
252	menu.parentNode.appendChild(layer);
253	
254	layer.style.left = menu.offsetLeft + 'px';
255	layer.style.top = menu.offsetTop + 'px';
256	layer.style.width = menu.offsetWidth + 'px';
257	layer.style.height = menu.offsetHeight + 'px';
258};
259
260// removeIframeLayer for Menu Bar
261// removes an IFRAME underneath a menu to reveal any form controls and ActiveX
262Spry.Widget.MenuBar.prototype.removeIframeLayer =  function(menu)
263{
264	var layers = ((menu == this.element) ? menu : menu.parentNode).getElementsByTagName('iframe');
265	while(layers.length > 0)
266	{
267		layers[0].parentNode.removeChild(layers[0]);
268	}
269};
270
271// clearMenus for Menu Bar
272// root is the top level unordered list (<ul> tag)
273Spry.Widget.MenuBar.prototype.clearMenus = function(root)
274{
275	var menus = root.getElementsByTagName('ul');
276	for(var i=0; i<menus.length; i++)
277		this.hideSubmenu(menus[i]);
278
279	this.removeClassName(this.element, this.activeClass);
280};
281
282// bubbledTextEvent for Menu Bar
283// identify bubbled up text events in Safari so we can ignore them
284Spry.Widget.MenuBar.prototype.bubbledTextEvent = function()
285{
286	return Spry.is.safari && (event.target == event.relatedTarget.parentNode || (event.eventPhase == 3 && event.target.parentNode == event.relatedTarget));
287};
288
289// showSubmenu for Menu Bar
290// set the proper CSS class on this menu to show it
291Spry.Widget.MenuBar.prototype.showSubmenu = function(menu)
292{
293	if(this.currMenu)
294	{
295		this.clearMenus(this.currMenu);
296		this.currMenu = null;
297	}
298	
299	if(menu)
300	{
301		this.addClassName(menu, this.subVisibleClass);
302		if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE')
303		{
304			if(!this.hasClassName(this.element, this.horizontalClass) || menu.parentNode.parentNode != this.element)
305			{
306				menu.style.top = menu.parentNode.offsetTop + 'px';
307			}
308		}
309		if(Spry.is.ie && Spry.is.version < 7)
310		{
311			this.createIframeLayer(menu);
312		}
313	}
314	this.addClassName(this.element, this.activeClass);
315};
316
317// hideSubmenu for Menu Bar
318// remove the proper CSS class on this menu to hide it
319Spry.Widget.MenuBar.prototype.hideSubmenu = function(menu)
320{
321	if(menu)
322	{
323		this.removeClassName(menu, this.subVisibleClass);
324		if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE')
325		{
326			menu.style.top = '';
327			menu.style.left = '';
328		}
329		if(Spry.is.ie && Spry.is.version < 7)
330			this.removeIframeLayer(menu);
331	}
332};
333
334// initialize for Menu Bar
335// create event listeners for the Menu Bar widget so we can properly
336// show and hide submenus
337Spry.Widget.MenuBar.prototype.initialize = function(listitem, element)
338{
339	var opentime, closetime;
340	var link = listitem.getElementsByTagName('a')[0];
341	var submenus = listitem.getElementsByTagName('ul');
342	var menu = (submenus.length > 0 ? submenus[0] : null);
343
344	if(menu)
345		this.addClassName(link, this.hasSubClass);
346
347	if(!Spry.is.ie)
348	{
349		// define a simple function that comes standard in IE to determine
350		// if a node is within another node
351		listitem.contains = function(testNode)
352		{
353			// this refers to the list item
354			if(testNode == null)
355				return false;
356
357			if(testNode == this)
358				return true;
359			else
360				return this.contains(testNode.parentNode);
361		};
362	}
363
364	// need to save this for scope further down
365	var self = this;
366	this.addEventListener(listitem, 'mouseover', function(e){self.mouseOver(listitem, e);}, false);
367	this.addEventListener(listitem, 'mouseclick', function(e){self.mouseclick(listitem, e);}, false);
368	this.addEventListener(listitem, 'mouseout', function(e){if (self.enableKeyboardNavigation) self.clearSelection(); self.mouseOut(listitem, e);}, false);
369
370	if (this.enableKeyboardNavigation)
371	{
372		this.addEventListener(link, 'blur', function(e){self.onBlur(listitem);}, false);
373		this.addEventListener(link, 'focus', function(e){self.keyFocus(listitem, e);}, false);
374	}
375};
376Spry.Widget.MenuBar.prototype.keyFocus = function (listitem, e)
377{
378	this.lastOpen = listitem.getElementsByTagName('a')[0];
379	this.addClassName(this.lastOpen, listitem.getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass);
380	this.hasFocus = true;
381};
382Spry.Widget.MenuBar.prototype.onBlur = function (listitem)
383{
384	this.clearSelection(listitem);
385};
386Spry.Widget.MenuBar.prototype.clearSelection = function(el){
387	//search any intersection with the current open element
388	if (!this.lastOpen)
389		return;
390
391	if (el)
392	{
393		el = el.getElementsByTagName('a')[0];
394		
395		// check children
396		var item = this.lastOpen;
397		while (item != this.element)
398		{
399			var tmp = el;
400			while (tmp != this.element)
401			{
402				if (tmp == item)
403					return;
404				try{
405					tmp = tmp.parentNode;
406				}catch(err){break;}
407			}
408			item = item.parentNode;
409		}
410	}
411	var item = this.lastOpen;
412	while (item != this.element)
413	{
414		this.hideSubmenu(item.parentNode);
415		var link = item.getElementsByTagName('a')[0];
416		this.removeClassName(link, this.hoverClass);
417		this.removeClassName(link, this.subHoverClass);
418		item = item.parentNode;
419	}
420	this.lastOpen = false;
421};
422Spry.Widget.MenuBar.prototype.keyDown = function (e)
423{
424	if (!this.hasFocus)
425		return;
426
427	if (!this.lastOpen)
428	{
429		this.hasFocus = false;
430		return;
431	}
432
433	var e = e|| event;
434	var listitem = this.lastOpen.parentNode;
435	var link = this.lastOpen;
436	var submenus = listitem.getElementsByTagName('ul');
437	var menu = (submenus.length > 0 ? submenus[0] : null);
438	var hasSubMenu = (menu) ? true : false;
439
440	var opts = [listitem, menu, null, this.getSibling(listitem, 'previousSibling'), this.getSibling(listitem, 'nextSibling')];
441	
442	if (!opts[3])
443		opts[2] = (listitem.parentNode.parentNode.nodeName.toLowerCase() == 'li')?listitem.parentNode.parentNode:null;
444
445	var found = 0;
446	switch (e.keyCode){
447		case this.upKeyCode:
448			found = this.getElementForKey(opts, 'y', 1);
449			break;
450		case this.downKeyCode:
451			found = this.getElementForKey(opts, 'y', -1);
452			break;
453		case this.leftKeyCode:
454			found = this.getElementForKey(opts, 'x', 1);
455			break;
456		case this.rightKeyCode:
457			found = this.getElementForKey(opts, 'x', -1);
458			break;
459		case this.escKeyCode:
460		case 9:
461			this.clearSelection();
462			this.hasFocus = false;
463		default: return;
464	}
465	switch (found)
466	{
467		case 0: return;
468		case 1:
469			//subopts
470			this.mouseOver(listitem, e);
471			break;
472		case 2:
473			//parent
474			this.mouseOut(opts[2], e);
475			break;
476		case 3:
477			this.mouseclick(listitem, e);
478			break;
479		case 4:
480			// left - right
481			this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
482			break;
483	}
484	var link = opts[found].getElementsByTagName('a')[0];
485	if (opts[found].nodeName.toLowerCase() == 'ul')
486		opts[found] = opts[found].getElementsByTagName('li')[0];
487
488	this.addClassName(link, opts[found].getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass);
489	this.lastOpen = link;
490	opts[found].getElementsByTagName('a')[0].focus();
491  
492        //stop further event handling by the browser
493	return Spry.Widget.MenuBar.stopPropagation(e);
494};
495Spry.Widget.MenuBar.prototype.mouseOver = function (listitem, e)
496{
497	var link = listitem.getElementsByTagName('a')[0];
498	var submenus = listitem.getElementsByTagName('ul');
499	var menu = (submenus.length > 0 ? submenus[0] : null);
500	var hasSubMenu = (menu) ? true : false;
501	if (this.enableKeyboardNavigation)
502		this.clearSelection(listitem);
503
504	if(this.bubbledTextEvent())
505	{
506		// ignore bubbled text events
507		return;
508	}
509
510	if (listitem.closetime)
511		clearTimeout(listitem.closetime);
512
513	if(this.currMenu == listitem)
514	{
515		this.currMenu = null;
516	}
517
518	// move the focus too
519	if (this.hasFocus)
520		link.focus();
521
522	// show menu highlighting
523	this.addClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
524	this.lastOpen = link;
525	if(menu && !this.hasClassName(menu, this.subHoverClass))
526	{
527		var self = this;
528		listitem.opentime = window.setTimeout(function(){self.showSubmenu(menu);}, this.showDelay);
529	}
530};
531
532Spry.Widget.MenuBar.prototype.mouseclick = function (listitem, e)
533{
534	var link = listitem.getElementsByTagName('a')[0];
535	var submenus = listitem.getElementsByTagName('ul');
536	var menu = (submenus.length > 0 ? submenus[0] : null);
537	var hasSubMenu = (menu) ? true : false;
538	if (this.enableKeyboardNavigation)
539		this.clearSelection(listitem);
540
541	if(this.bubbledTextEvent())
542	{
543		// ignore bubbled text events
544		return;
545	}
546
547	if (listitem.closetime)
548		clearTimeout(listitem.closetime);
549
550	if(this.currMenu == listitem)
551	{
552		this.currMenu = null;
553	}
554
555	// move the focus too
556	if (this.hasFocus)
557		link.focus();
558
559	// show menu highlighting
560	this.addClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
561	this.lastOpen = link;
562	if(menu && !this.hasClassName(menu, this.subHoverClass))
563	{
564		var self = this;
565		listitem.opentime = window.setTimeout(function(){self.showSubmenu(menu);}, this.showDelay);
566	}
567};
568
569
570Spry.Widget.MenuBar.prototype.mouseOut = function (listitem, e)
571{
572	var link = listitem.getElementsByTagName('a')[0];
573	var submenus = listitem.getElementsByTagName('ul');
574	var menu = (submenus.length > 0 ? submenus[0] : null);
575	var hasSubMenu = (menu) ? true : false;
576	if(this.bubbledTextEvent())
577	{
578		// ignore bubbled text events
579		return;
580	}
581
582	var related = (typeof e.relatedTarget != 'undefined' ? e.relatedTarget : e.toElement);
583	if(!listitem.contains(related))
584	{
585		if (listitem.opentime) 
586			clearTimeout(listitem.opentime);
587		this.currMenu = listitem;
588
589		// remove menu highlighting
590		this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
591		if(menu)
592		{
593			var self = this;
594			listitem.closetime = window.setTimeout(function(){self.hideSubmenu(menu);}, this.hideDelay);
595		}
596		if (this.hasFocus)
597			link.blur();
598	}
599};
600Spry.Widget.MenuBar.prototype.getSibling = function(element, sibling)
601{
602	var child = element[sibling];
603	while (child && child.nodeName.toLowerCase() !='li')
604		child = child[sibling];
605
606	return child;
607};
608Spry.Widget.MenuBar.prototype.getElementForKey = function(els, prop, dir)
609{
610	var found = 0;
611	var rect = Spry.Widget.MenuBar.getPosition;
612	var ref = rect(els[found]);
613
614	var hideSubmenu = false;
615	//make the subelement visible to compute the position
616	if (els[1] && !this.hasClassName(els[1], this.MenuBarSubmenuVisible))
617	{
618		els[1].style.visibility = 'hidden';
619		this.showSubmenu(els[1]);
620		hideSubmenu = true;
621	}
622
623	var isVert = this.hasClassName(this.element, this.verticalClass);
624	var hasParent = els[0].parentNode.parentNode.nodeName.toLowerCase() == 'li' ? true : false;
625	
626	for (var i = 1; i < els.length; i++){
627		//when navigating on the y axis in vertical menus, ignore children and parents
628		if(prop=='y' && isVert && (i==1 || i==2))
629		{
630			continue;
631		}
632		//when navigationg on the x axis in the FIRST LEVEL of horizontal menus, ignore children and parents
633		if(prop=='x' && !isVert && !hasParent && (i==1 || i==2))
634		{
635			continue;
636		}
637			
638		if (els[i])
639		{
640			var tmp = rect(els[i]); 
641			if ( (dir * tmp[prop]) < (dir * ref[prop]))
642			{
643				ref = tmp;
644				found = i;
645			}
646		}
647	}
648	
649	// hide back the submenu
650	if (els[1] && hideSubmenu){
651		this.hideSubmenu(els[1]);
652		els[1].style.visibility =  '';
653	}
654
655	return found;
656};
657Spry.Widget.MenuBar.camelize = function(str)
658{
659	if (str.indexOf('-') == -1){
660		return str;	
661	}
662	var oStringList = str.split('-');
663	var isFirstEntry = true;
664	var camelizedString = '';
665
666	for(var i=0; i < oStringList.length; i++)
667	{
668		if(oStringList[i].length>0)
669		{
670			if(isFirstEntry)
671			{
672				camelizedString = oStringList[i];
673				isFirstEntry = false;
674			}
675			else
676			{
677				var s = oStringList[i];
678				camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
679			}
680		}
681	}
682
683	return camelizedString;
684};
685
686Spry.Widget.MenuBar.getStyleProp = function(element, prop)
687{
688	var value;
689	try
690	{
691		if (element.style)
692			value = element.style[Spry.Widget.MenuBar.camelize(prop)];
693
694		if (!value)
695			if (document.defaultView && document.defaultView.getComputedStyle)
696			{
697				var css = document.defaultView.getComputedStyle(element, null);
698				value = css ? css.getPropertyValue(prop) : null;
699			}
700			else if (element.currentStyle) 
701			{
702					value = element.currentStyle[Spry.Widget.MenuBar.camelize(prop)];
703			}
704	}
705	catch (e) {}
706
707	return value == 'auto' ? null : value;
708};
709Spry.Widget.MenuBar.getIntProp = function(element, prop)
710{
711	var a = parseInt(Spry.Widget.MenuBar.getStyleProp(element, prop),10);
712	if (isNaN(a))
713		return 0;
714	return a;
715};
716
717Spry.Widget.MenuBar.getPosition = function(el, doc)
718{
719	doc = doc || document;
720	if (typeof(el) == 'string') {
721		el = doc.getElementById(el);
722	}
723
724	if (!el) {
725		return false;
726	}
727
728	if (el.parentNode === null || Spry.Widget.MenuBar.getStyleProp(el, 'display') == 'none') {
729		//element must be visible to have a box
730		return false;
731	}
732
733	var ret = {x:0, y:0};
734	var parent = null;
735	var box;
736
737	if (el.getBoundingClientRect) { // IE
738		box = el.getBoundingClientRect();
739		var scrollTop = doc.documentElement.scrollTop || doc.body.scrollTop;
740		var scrollLeft = doc.documentElement.scrollLeft || doc.body.scrollLeft;
741		ret.x = box.left + scrollLeft;
742		ret.y = box.top + scrollTop;
743	} else if (doc.getBoxObjectFor) { // gecko
744		box = doc.getBoxObjectFor(el);
745		ret.x = box.x;
746		ret.y = box.y;
747	} else { // safari/opera
748		ret.x = el.offsetLeft;
749		ret.y = el.offsetTop;
750		parent = el.offsetParent;
751		if (parent != el) {
752			while (parent) {
753				ret.x += parent.offsetLeft;
754				ret.y += parent.offsetTop;
755				parent = parent.offsetParent;
756			}
757		}
758		// opera & (safari absolute) incorrectly account for body offsetTop
759		if (Spry.is.opera || Spry.is.safari && Spry.Widget.MenuBar.getStyleProp(el, 'position') == 'absolute')
760			ret.y -= doc.body.offsetTop;
761	}
762	if (el.parentNode)
763			parent = el.parentNode;
764	else
765		parent = null;
766	if (parent.nodeName){
767		var cas = parent.nodeName.toUpperCase();
768		while (parent && cas != 'BODY' && cas != 'HTML') {
769			cas = parent.nodeName.toUpperCase();
770			ret.x -= parent.scrollLeft;
771			ret.y -= parent.scrollTop;
772			if (parent.parentNode)
773				parent = parent.parentNode;
774			else
775				parent = null;
776		}
777	}
778	return ret;
779};
780
781Spry.Widget.MenuBar.stopPropagation = function(ev)
782{
783	if (ev.stopPropagation)
784		ev.stopPropagation();
785	else
786		ev.cancelBubble = true;
787	if (ev.preventDefault) 
788		ev.preventDefault();
789	else 
790		ev.returnValue = false;
791};
792
793Spry.Widget.MenuBar.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
794{
795	if (!optionsObj)
796		return;
797	for (var optionName in optionsObj)
798	{
799		if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
800			continue;
801		obj[optionName] = optionsObj[optionName];
802	}
803};
804
805})(); // EndSpryComponent

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.