1/*
2  Copyright (C) 2000-2005 SKYRIX Software AG
3
4  This file is part of SOPE.
5
6  SOPE is free software; you can redistribute it and/or modify it under
7  the terms of the GNU Lesser General Public License as published by the
8  Free Software Foundation; either version 2, or (at your option) any
9  later version.
10
11  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12  WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14  License for more details.
15
16  You should have received a copy of the GNU Lesser General Public
17  License along with SOPE; see the file COPYING.  If not, write to the
18  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19  02111-1307, USA.
20*/
21
22#include "JSMenu.h"
23#include "JSMenuItem.h"
24#include <NGObjWeb/NGObjWeb.h>
25#include <NGObjWeb/WEClientCapabilities.h>
26#include "common.h"
27
28@implementation JSMenu
29
30- (id)initWithName:(NSString *)_name
31  associations:(NSDictionary *)_config
32  template:(WOElement *)_subs
33{
34  if((self = [super initWithName:_name associations:_config template:_subs])) {
35    self->fgColor     = OWGetProperty(_config,@"fgColor");
36    self->bgColor     = OWGetProperty(_config,@"bgColor");
37    self->fgColorHigh = OWGetProperty(_config,@"fgColorHigh");
38    self->bgColorHigh = OWGetProperty(_config,@"bgColorHigh");
39    self->borderColor = OWGetProperty(_config,@"borderColor");
40    self->borderWidth = OWGetProperty(_config,@"borderWidth");
41    self->fontSize    = OWGetProperty(_config,@"fontSize");
42    self->width       = OWGetProperty(_config,@"width");
43    self->leftPadding = OWGetProperty(_config,@"leftPadding");
44    self->string      = OWGetProperty(_config,@"string");
45    self->bindAtId    = OWGetProperty(_config,@"bindAtId");
46    self->align       = OWGetProperty(_config,@"align");
47    self->tag         = OWGetProperty(_config,@"tag");
48
49    self->template = [_subs retain];
50  }
51  return self;
52}
53
54- (void)dealloc {
55  [self->fgColor     release];
56  [self->bgColor     release];
57  [self->fgColorHigh release];
58  [self->bgColorHigh release];
59  [self->borderWidth release];
60  [self->fontSize    release];
61  [self->width       release];
62  [self->leftPadding release];
63  [self->string      release];
64  [self->bindAtId    release];
65  [self->align       release];
66  [self->tag         release];
67  [self->template    release];
68  [super dealloc];
69}
70
71/* handling requests */
72
73- (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
74  return [self->template invokeActionForRequest:_req inContext:_ctx];
75}
76
77/* generate response */
78
79- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
80  WOComponent          *comp;
81  NSString             *tmp;
82  NSString             *eid; // [_ctx elementID]
83  WEClientCapabilities *ccaps;
84  BOOL                 ie, ns;
85
86  if ([_ctx isRenderingDisabled]) {
87    [self->template appendToResponse:_response inContext:_ctx];
88    return;
89  }
90
91  eid   = [[[_ctx elementID] componentsSeparatedByString:@"."]
92                  componentsJoinedByString:@"_"];
93  comp  = [_ctx component];
94  ccaps = [[_ctx request] clientCapabilities];
95  ie    = [ccaps isJavaScriptBrowser] && [ccaps isInternetExplorer];
96  ns    = [ccaps isJavaScriptBrowser] && [ccaps isNetscape];
97
98  [_ctx setObject:eid forKey:@"eid"];
99
100  if (!ie) {
101    return;
102
103    [_response appendContentString:@"<font size=\"-1\">["];
104    [self->template appendToResponse:_response inContext:_ctx];
105    [_response appendContentString:@"]</font>"];
106    return;
107  }
108
109  if (ie) {
110    if ([_ctx objectForKey:@"jsmenu_included"] == nil) {
111      [_ctx setObject:@"done" forKey:@"jsmenu_included"];
112      tmp = [[NSString alloc] initWithFormat:
113                      @"<style>\n"
114                      @".menuItem {\n"
115                      @"  font:%@pt sans-serif;\n"
116                      @"  width:%@;\n"
117                      @"  padding-left:%@;\n"
118                      @"  background-Color:%@;\n"
119                      @"  color:%@;\n"
120                      @"  text-align:%@\n"
121                      @"}\n"
122                      @".highlightItem {\n"
123                      @"  font:%@pt sans-serif;\n"
124                      @"  width:%@;\n"
125                      @"  padding-left:%@;\n"
126                      @"  background-Color:%@;\n"
127                      @"  color:%@\n"
128                      @"  text-align:%@\n"
129                      @"}\n"
130                      @"</style>\n",
131                      [self->fontSize stringValueInComponent:comp],
132                      [self->width stringValueInComponent:comp],
133                      [self->leftPadding stringValueInComponent:comp],
134                      [self->bgColor stringValueInComponent:comp],
135                      [self->fgColor stringValueInComponent:comp],
136                      [self->align stringValueInComponent:comp],
137                      [self->fontSize stringValueInComponent:comp],
138                      [self->width stringValueInComponent:comp],
139                      [self->leftPadding stringValueInComponent:comp],
140                      [self->bgColorHigh stringValueInComponent:comp],
141                      [self->fgColorHigh stringValueInComponent:comp],
142                      [self->align stringValueInComponent:comp]];
143      [_response appendContentString:tmp];
144      [tmp release];
145
146      tmp = [[NSString alloc] initWithFormat:
147                      @"<script language=\"javascript\">\n"
148                      @"var menuOpened;\n"
149                      @"function displayMenu(m) {\n"
150                      @"  closeMenu();\n"
151                      @"  if(m.parentNode != event.srcElement)\n"
152                      @"    return false;\n"
153                      @"  menuOpened=m;\n"
154                      @"  m.style.posLeft=event.clientX+document.body.scrollLeft;\n"
155                      @"  m.style.posTop=event.clientY+document.body.scrollTop;\n"
156                      @"  if(document.body.clientWidth<event.clientX+%@+5)\n"
157                      @"    m.style.posLeft-=%@;\n"
158                      @"  m.style.display=\"\";\n"
159                      @"  m.setCapture();\n"
160                      @"  return false;\n"
161                      @"}\n"
162                      @"function switchMenu() {\n"
163                      @"  el=event.srcElement;\n"
164                      @"  if(el.className==\"menuItem\")\n"
165                      @"    el.className=\"highlightItem\";\n"
166                      @"  else if(el.className==\"highlightItem\")\n"
167                      @"    el.className=\"menuItem\";\n"
168                      @"}\n"
169                      @"function clickMenu(m) {\n"
170                      @"  m.releaseCapture();\n"
171                      @"  m.style.display=\"none\";\n"
172                      @"  el=event.srcElement;\n"
173                      @"  if(m==el.parentNode)window.location=el.url;\n"
174                      @"  return false;\n"
175                      @"}\n"
176                      @"function closeMenu() {\n"
177                      @"  if(menuOpened==null)"
178                      @"    return;\n"
179                      @"  menuOpened.releaseCapture();\n"
180                      @"  menuOpened.style.display=\"none\";\n"
181                      @"  menuOpened=null;\n"
182                      @"}\n"
183                      @"</script>\n",
184                      [self->width stringValueInComponent:comp],
185                      [self->width stringValueInComponent:comp]];
186      [_response appendContentString:tmp];
187      [tmp release];
188    }
189    tmp = [[NSString alloc] initWithFormat:
190                    @"<div id=\"m%@\" onclick=\"return clickMenu(m%@);\" "
191                    @"onmouseover=\"switchMenu();\" "
192                    @"onmouseout=\"switchMenu();\" "
193                    @"style=\"position:absolute;display:none;width:%@;"
194                    @"background-Color:%@;border:outset %@px %@;"
195                    @"text-decoration:none\">",
196                    eid, eid,
197                    [self->width       stringValueInComponent:comp],
198                    [self->bgColor     stringValueInComponent:comp],
199                    [self->borderWidth stringValueInComponent:comp],
200                    [self->borderColor stringValueInComponent:comp]];
201    [_response appendContentString:tmp];
202    [tmp release];
203
204    [self->template appendToResponse:_response inContext:_ctx];
205
206    [_response appendContentString:@"</div>"];
207#if 0
208    if ([self->tag stringValueInComponent:comp] != nil)
209      tmp = [[NSString alloc] initWithFormat:
210                      @"<script id=\"s%@\" language=\"javascript\">"
211                      @"function c%@(){return displayMenu(m%@);}"
212                      @"tmp=document.getElementById(\"s%@\");"
213                      @"i=5;"
214                      @"while((tmp.tagName!=\"%@\")&&i--)"
215                      @"tmp=tmp.parentNode;"
216                      @"tmp.oncontextmenu=c%@;"
217                      @"</script>",
218                      eid, eid, eid, eid,
219                      [self->tag stringValueInComponent:comp], eid];
220    else
221#endif
222      tmp = [[NSString alloc] initWithFormat:
223                      @"<script id=\"s%@\" language=\"javascript\">"
224                      @"function c%@() { return displayMenu(m%@); }"
225                      @"s%@.parentNode.oncontextmenu=c%@;"
226                      @"</script>",
227                      eid, eid, eid, eid, eid];
228    [_response appendContentString:tmp];
229    [tmp release];
230  }
231#if 0
232  if (ns) {
233    if ([_ctx objectForKey:@"jsmenu_included"] == nil) {
234      tmp = [[NSString alloc] initWithFormat:
235                      @"<script language=\"javascript1.2\" "
236                      @"src=\"http://inster:9000/sascha/menu07.js\">"
237                      @"</script>\n"
238                      @"<script language=\"javascript1.2\">"
239                      @"function onLoad(){m%@.writeMenus();}</script>\n",
240                      eid];
241      [_response appendContentString:tmp];
242      [tmp release];
243    }
244
245    tmp = [[NSString alloc] initWithFormat:
246                    @"<script language=\"javascript1.2\">\n"
247                    @"m%@=new Menu();",eid];
248    [_response appendContentString:tmp];
249    [tmp release];
250
251    [self->template appendToResponse:_response inContext:_ctx];
252
253    tmp = [[NSString alloc] initWithFormat:
254                    @"</script>\n"
255                    @"<a href=\"#\" onclick=\"showMenu(m%@);return false;\">"
256                    @"M</a>", eid];
257    [_response appendContentString:tmp];
258    [tmp release];
259
260    [_ctx setObject:@"done" forKey:@"jsmenu_included"];
261  }
262#endif
263}
264
265@end /* JSMenu */
266