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