OSDN Git Service

add eclipse related files
[cloudmanganw/git_repo.git] / src / jp / sourceforge / manganetwork / page / javascripts / spinelz / menubar.js
1 // Copyright (c) 2005 spinelz.org (http://script.spinelz.org/)
2 // 
3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
10 // 
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 var MenuBar = Class.create();
23 MenuBar.cssNames = {
24   container:        'menubar',
25   menu:             'menubar_menu',
26   menuBody:         'menubar_menuBody',
27   menuBodyHover:    'menubar_menuBodyHover',
28   subMenu:          'menubar_subMenu',
29   subMenuBody:      'menubar_subMenuBody',
30   subMenuBodyHover: 'menubar_subMenuBodyHover',
31   subMenuContainer: 'menubar_menuContainer',
32   dirMark:          'menubar_dirMark'
33 }
34
35 MenuBar.mark = {
36   dir: '>>'
37 }
38
39 MenuBar.prototype = {
40
41   initialize: function(element) {
42     this.options = Object.extend({
43       hideOnClickSubmenu: true
44     }, arguments[1]);
45
46     this.element = $(element);
47     Element.setStyle(this.element, {visibility: 'hidden'});
48     Element.hide(this.element);
49     
50     var options = Object.extend({
51       cssPrefix: 'custom_'
52     }, arguments[1] || {});
53     
54     var customCss = CssUtil.appendPrefix(options.cssPrefix, MenuBar.cssNames);
55     this.classNames = new CssUtil([MenuBar.cssNames, customCss]);
56     
57     this.clicked = [];
58     var topMenus = [];
59     var nodes = this.element.childNodes;
60     
61     for (var i = 0; i < nodes.length; i++) {
62       if (nodes[i].nodeType == 1) {
63         this.build(nodes[i], 'menu');
64         topMenus.push(nodes[i]);
65       }    
66     }
67     
68     this.menubar = Builder.node('DIV', topMenus)
69     this.classNames.addClassNames(this.menubar, 'container');
70     this.element.appendChild(this.menubar);
71     
72     Event.observe(document, "click", this.hideAllTrigger(this.menubar).bindAsEventListener(this));
73     Element.setStyle(this.element, {visibility: 'visible'});
74     Element.show(this.element);
75   },
76   
77   build: function(element, className) {
78     this.classNames.addClassNames(element, className);
79         
80     var bodyContents = new Array();
81     var subMenus = new Array();
82     var nodes = element.childNodes;
83     
84     for (var i = 0; i < nodes.length; i++) {
85       if (nodes[i].nodeType == 1 && nodes[i].tagName == 'DIV') {
86         this.build(nodes[i], 'subMenu');
87         subMenus.push(nodes[i]);
88       } else {
89         bodyContents.push(nodes[i]);
90       }
91     }
92     
93     var bodyClass= className + 'Body';
94     var body = Builder.node('DIV', bodyContents);
95     this.classNames.addClassNames(body, bodyClass);
96     new Hover(body);
97     element.appendChild(body);
98     
99     if (subMenus.length > 0) {
100       if (className == 'subMenu') {
101         var subMenu = Builder.node('DIV', [MenuBar.mark.dir]);
102         this.classNames.addClassNames(subMenu, 'dirMark');
103         body.appendChild(subMenu);
104       }
105       
106       var container = Builder.node('DIV', subMenus);
107       this.classNames.addClassNames(container, 'subMenuContainer');
108       element.appendChild(container);
109       
110       this.hide(container);
111     }
112     Event.observe(element, "click", this.onClick.bindAsEventListener(this, body));
113   },
114   
115   onClick: function(event, menuBody) {
116     var menu = menuBody.parentNode;
117     var parentContainer = this.getParentContainer(menu);
118     
119     var container = this.getContainer(menu);
120     var className = MenuBar.cssNames.menu;
121     if (Element.hasClassName(menu, className)) {
122       if (this.clicked.length > 0) {
123         this.hideAll(this.menubar);
124         this.clicked = [];
125       }
126       if (container) this.showAtBottom(container, menuBody);
127
128     } else {
129       if (container) {
130         var lastMenuBody = this.clicked.pop();
131         var lastMenu = lastMenuBody.parentNode;
132         var lastContainer = this.getContainer(lastMenu);
133         var lastParentContainer = this.getParentContainer(lastMenu);
134         
135         if (lastMenu == menu) {
136           this.hide(container);
137         
138         } else if (Element.hasClassName(lastContainer, MenuBar.cssNames.container)) {
139           this.clicked.push(last);
140         
141         } else if (lastParentContainer == parentContainer) {
142           this.hide(lastContainer);
143         
144         } else {
145           this.clicked.push(lastMenuBody);
146         }
147         this.showAtLeft(container, menu);
148       } else if (this.options.hideOnClickSubmenu) {
149         this.hideAll(this.menubar);
150       }
151     }
152     
153     if (container) this.clicked.push(menuBody);
154     Event.stop(event);
155   },
156   
157   showAtBottom: function(contents, menuBody) {
158     var offset = Position.positionedOffset(menuBody);
159     var height = 0;
160       
161     if (menuBody.style.height) height = Element.getHeight(menuBody);
162     else height = menuBody.clientHeight;
163     height += offset[1];
164     height += (document.all) ? 4 : 3;
165       
166     contents.style.top = height + 'px';
167     contents.style.left = offset[0] + 'px';
168       
169     this.show(contents);
170   },
171   
172   showAtLeft: function(contents, menuBody) {
173     var offset = Position.positionedOffset(menuBody);
174     
175     contents.style.top = (offset[1] - 1) + 'px';
176     contents.style.left = (offset[0] + menuBody.offsetWidth + 2) + 'px';
177     
178     this.show(contents);
179   },
180
181   hideAllTrigger: function(element) {
182     return function(event) {
183       if (!this.isMenuElement(Event.element(event))) this.hideAll(element);
184     }
185   },
186   
187   hideAll: function(element) {
188     var nodes = element.childNodes;
189     for (var i = 0; i < nodes.length; i++) {
190       if (nodes[i].nodeType == 1) {
191         if (Element.hasClassName(nodes[i], MenuBar.cssNames.subMenuContainer)) {
192           this.hide(nodes[i]);
193         }
194           
195         this.hideAll(nodes[i]);
196       }
197     }
198   },
199   
200   show: function(element) {
201     element.style.visibility = 'visible';
202   }, 
203   
204   hide: function(element) {
205     element.style.visibility = 'hidden';
206   },
207   
208   getContainer: function(element) {
209     
210     if (!element) return;
211     return document.getElementsByClassName(MenuBar.cssNames.subMenuContainer, element)[0];
212   },
213   
214   getParentContainer: function(element) {
215     var container = Element.getParentByClassName(MenuBar.cssNames.subMenuContainer, element);
216     if (!container) {
217       container = Element.getParentByClassName(MenuBar.cssNames.container, element);
218     }
219     
220     return container;
221   },
222
223   isMenuElement: function(element) {
224     return Element.hasClassName(element, MenuBar.cssNames.menuBodyHover)
225       || Element.hasClassName(element, MenuBar.cssNames.subMenuBodyHover)
226       || Element.hasClassName(element, MenuBar.cssNames.dirMark);
227   }
228 }