OSDN Git Service

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