]> err.no Git - sope/blob - sope-appserver/WOExtensions/JSImageFlyover.m
renamed packages as discussed in the developer list
[sope] / sope-appserver / WOExtensions / JSImageFlyover.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo 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   OGo 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 OGo; 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 // $Id$
22
23 #import <NGObjWeb/WODynamicElement.h>
24
25 @interface JSImageFlyover : WODynamicElement
26 {
27   WOAssociation *action;
28   WOAssociation *javaScriptFunction;
29   WOAssociation *pageName;
30   WOAssociation *selectedImage;
31   WOAssociation *unselectedImage;
32   WOAssociation *framework;
33   WOAssociation *targetWindow;
34
35   // Skyrix add-ons
36   WOAssociation *directActionName;
37   WOAssociation *actionClass;
38   BOOL          sidInUrl;
39   WOAssociation *queryDictionary;
40   NSDictionary  *queryParameters;
41   
42   WOElement     *template;
43 }
44
45 @end
46
47 #import <NGObjWeb/NGObjWeb.h>
48 #include "common.h"
49
50 @implementation JSImageFlyover
51
52 + (int)version {
53   return [super version] + 0 /* v2 */;
54 }
55 + (void)initialize {
56   NSAssert2([super version] == 2,
57             @"invalid superclass (%@) version %i !",
58             NSStringFromClass([self superclass]), [super version]);
59 }
60
61 - (NSDictionary *)extractQueryParameters: (NSDictionary *)_set {
62   NSMutableDictionary *paras = nil;
63   NSMutableArray      *paraKeys = nil;
64   NSEnumerator        *keys;
65   NSString            *key;
66
67   // locate query parameters
68   keys = [_set keyEnumerator];
69   while ((key = [keys nextObject])) {
70     if ([key hasPrefix:@"?"]) {
71       WOAssociation *value;
72
73       if ([key isEqualToString:@"?wosid"])
74         continue;
75
76       value = [_set objectForKey:key];
77           
78       if (paraKeys == nil)
79         paraKeys = [NSMutableArray arrayWithCapacity:8];
80       if (paras == nil)
81         paras = [NSMutableDictionary dictionaryWithCapacity:8];
82           
83       [paraKeys addObject:key];
84       [paras setObject:value forKey:[key substringFromIndex:1]];
85     }
86   }
87
88   // remove query parameters
89   if (paraKeys) {
90     unsigned cnt, count;
91     for (cnt = 0, count = [paraKeys count]; cnt < count; cnt++) {
92       [(NSMutableDictionary *)_set removeObjectForKey:
93                                      [paraKeys objectAtIndex:cnt]];
94     }
95   }
96
97   // assign parameters
98   return [paras copy];
99 }
100
101 - (id)initWithName:(NSString *)_name
102   associations:(NSDictionary *)_config
103   template:(WOElement *)_subs
104 {
105   if ((self = [super initWithName:_name associations:_config template:_subs]))
106   {
107     int           funcCount;
108     WOAssociation *sidInUrlAssoc;
109
110     
111     self->action             = WOExtGetProperty(_config, @"action");
112     self->javaScriptFunction = WOExtGetProperty(_config, @"javaScriptFunction");
113     self->pageName           = WOExtGetProperty(_config, @"pageName");
114     self->selectedImage      = WOExtGetProperty(_config, @"selectedImage");
115     self->unselectedImage    = WOExtGetProperty(_config, @"unselectedImage");
116     self->framework          = WOExtGetProperty(_config, @"framework");
117     self->targetWindow       = WOExtGetProperty(_config, @"targetWindow");
118
119     self->directActionName   = WOExtGetProperty(_config, @"directActionName");
120     self->actionClass        = WOExtGetProperty(_config, @"actionClass");
121     self->queryDictionary    = WOExtGetProperty(_config, @"queryDictionary");
122     self->queryParameters    = [self extractQueryParameters:_config];
123     
124     funcCount = 0;
125     if (self->action) funcCount++;
126     if (self->pageName) funcCount++;
127     if (self->javaScriptFunction) funcCount++;
128     if (self->directActionName) funcCount++;
129
130     if (funcCount > 1)
131       NSLog(@"WARNING: JSImageFlyover: choose only one of "
132             @"action | pageName | javaScriptFunction | directActionName");
133     if (funcCount < 1)
134       NSLog(@"WARNING: JSImageFlyover: no function declared - choose one of"
135             @"action | pageName | javaScriptFunction | directActionName");
136     if (!self->selectedImage)
137       NSLog(@"WARNING: JSImageFlyover: no value for 'selectedImage'");
138     if (!self->unselectedImage)
139       NSLog(@"WARNING: JSImageFlyover: no value for 'unselectedImage'");
140
141     /* for directActionName */
142     sidInUrlAssoc = WOExtGetProperty(_config, @"?wosid");
143     self->sidInUrl = (sidInUrlAssoc)
144       ? [sidInUrlAssoc boolValueInComponent:nil]
145       : YES;
146     
147
148     self->template = RETAIN(_subs);
149   }
150   return self;
151 }
152
153 - (void)dealloc {
154   RELEASE(self->action);
155   RELEASE(self->javaScriptFunction);
156   RELEASE(self->pageName);
157   RELEASE(self->selectedImage);
158   RELEASE(self->unselectedImage);
159   RELEASE(self->framework);
160   RELEASE(self->targetWindow);
161   RELEASE(self->template);
162
163   RELEASE(self->directActionName);
164   RELEASE(self->actionClass);
165   RELEASE(self->queryDictionary);
166   RELEASE(self->queryParameters);
167   
168   [super dealloc];
169 }
170
171 - (void)takeValuesFromRequest:(WORequest *)_request
172   inContext:(WOContext *)_ctx
173 {
174   [self->template takeValuesFromRequest:_request inContext:_ctx];
175 }
176
177 - (id)invokeActionForRequest:(WORequest *)_request
178   inContext:(WOContext *)_ctx
179 {
180   id          result;
181   NSString    *name;
182
183   if (self->pageName) {
184     name = [self->pageName stringValueInComponent: [_ctx component]];
185     result = [[_ctx application] pageWithName:name inContext:_ctx];
186   }
187   else if (self->action) {
188     result = [self->action valueInComponent:[_ctx component]];
189   }
190   else {
191     result = [self->template invokeActionForRequest:_request inContext:_ctx];
192   }
193   return result;
194 }
195
196
197 - (NSString *)imageByFilename:(NSString *)_name
198   inContext:(WOContext *)_ctx
199   framework:(NSString *)_framework
200 {
201   WOResourceManager *rm;
202   NSString          *tmp;
203   NSArray           *languages;
204
205   rm = [[_ctx application] resourceManager];
206     
207   languages = [_ctx hasSession]
208     ? [[_ctx session] languages]
209     : [[_ctx request] browserLanguages];
210     
211   tmp = [rm urlForResourceNamed:_name
212             inFramework:_framework
213             languages:languages
214             request:[_ctx request]];
215   return tmp;
216 }
217     
218
219 - (void)appendDirectActionURLToResponse:(WOResponse *)_response
220   inContext:(WOContext *)_ctx
221 {
222   WOComponent *comp;
223   NSString            *daName;
224   NSString            *daClass;
225   NSMutableDictionary *qd;
226   WOSession           *sn;
227   NSDictionary        *tdict;
228   NSString *s;
229   
230   comp    = [_ctx component];
231   daName  = [self->directActionName stringValueInComponent:comp];
232   daClass = [self->actionClass stringValueInComponent:comp];
233       
234   if (daClass) {
235     if (daName) {
236       if (![daClass isEqualToString:@"DirectAction"])
237         daName = [NSString stringWithFormat:@"%@/%@", daClass, daName];
238     }
239     else
240       daName = daClass;
241   }
242       
243   qd = [NSMutableDictionary dictionaryWithCapacity:16];
244
245   if (self->queryDictionary) {
246     if ((tdict = [self->queryDictionary valueInComponent:comp]))
247       [qd addEntriesFromDictionary:tdict];
248   }
249
250   if (self->queryParameters) {
251     NSEnumerator *keys;
252     NSString     *key;
253
254     keys = [self->queryParameters keyEnumerator];
255     while ((key = [keys nextObject])) {
256       id assoc, value;
257       assoc = [self->queryParameters objectForKey:key];
258       value = [assoc stringValueInComponent:comp];
259       [qd setObject:(value ? value : @"") forKey:key];
260     }
261   }
262       
263   if ((self->sidInUrl) && ([_ctx hasSession])) {
264     sn = [_ctx session];
265     [qd setObject:[sn sessionID] forKey:WORequestValueSessionID];
266     if (![sn isDistributionEnabled]) {
267       [qd setObject:[[WOApplication application] number]
268           forKey:WORequestValueInstance];
269     }
270   }
271       
272   s = [_ctx directActionURLForActionNamed:daName queryDictionary:qd];
273   [_response appendContentString:s];
274 }
275
276 - (void)appendToResponse:(WOResponse *)_response
277   inContext:(WOContext *)_ctx
278 {
279   WOComponent *comp;
280   NSString    *tmp;
281   NSString    *tunselected, *tselected, *tframework;
282   NSString    *elID;
283   NSArray     *ta;
284   NSString    *s;
285   
286   comp = [_ctx component];
287   tunselected = [self->unselectedImage stringValueInComponent:comp];
288   tselected   = [self->selectedImage   stringValueInComponent:comp];
289   tframework  = (self->framework)
290     ? [self->framework stringValueInComponent:comp]
291     : [comp frameworkName];
292
293   tunselected = [self imageByFilename: tunselected inContext:_ctx
294                       framework: tframework];
295   tselected   = [self imageByFilename: tselected inContext:_ctx
296                       framework: tframework];
297   
298   elID = [_ctx elementID];
299   /* javascript didn't work with #.#.#.# -> replacing to #x#x#x# */
300   ta = [[NSArray alloc] initWithArray:[elID componentsSeparatedByString:@"."]];
301   elID = [ta componentsJoinedByString:@"x"];
302   [ta release];
303   
304   /* template */
305   [self->template appendToResponse:_response inContext:_ctx];
306
307   /* script */
308   [_response appendContentString:@"<script language=\"JavaScript\">\n<!--\n"];
309
310   if (![_ctx valueForKey:@"JSImageFlyoverScriptDone"]) {
311     tmp = @"var JSImageFlyoverImages = new Array();\n"
312           @"function JSImageFlyover(imgName,imgKind) {\n"
313           @"  document.images[imgName].src = "
314           @"JSImageFlyoverImages[imgName][imgKind].src;\n"
315           @"}\n";
316     [_response appendContentString:tmp];
317     [_ctx takeValue:[NSNumber numberWithBool:YES]
318           forKey:@"JSImageFlyoverScriptDone"];
319   }
320
321   tmp = @"JSImageFlyoverImages['%@'] = new Array; \n"
322         @"JSImageFlyoverImages['%@'][0] = new Image; "
323         @"JSImageFlyoverImages['%@'][0].src = '%@'; \n"
324         @"JSImageFlyoverImages['%@'][1] = new Image; "
325         @"JSImageFlyoverImages['%@'][1].src = '%@'; \n";
326   
327   s = [[NSString alloc] initWithFormat:tmp,
328                           elID, elID, elID, tunselected,
329                           elID, elID, tselected];
330   [_response appendContentString:s];
331   [s release];
332   
333   [_response appendContentString:@"\n//-->\n</script>"];
334   
335   /* link containing onMouseOver, onMouseOut and HREF */
336   [_response appendContentString:@"<a onmouseover=\"JSImageFlyover('"];
337   [_response appendContentString:elID];
338   [_response appendContentString:@"',1)\""];
339   [_response appendContentString:@" onmouseout=\"JSImageFlyover('"];
340   [_response appendContentString:elID];
341   [_response appendContentString:@"',0)\""];
342   [_response appendContentString:@" href=\""];
343   
344   if (self->javaScriptFunction) {
345     [_response appendContentString:@"javascript:"];
346     [_response appendContentHTMLAttributeValue:
347                  [self->javaScriptFunction stringValueInComponent:comp]];
348   }
349   else if (self->directActionName)
350     [self appendDirectActionURLToResponse:_response inContext:_ctx];
351   else /* component action */
352     [_response appendContentString:[_ctx componentActionURL]];
353   
354   [_response appendContentString:@"\" "];
355
356   if (self->targetWindow) {
357     [_response appendContentString:@" target=\""];
358     [_response appendContentHTMLAttributeValue:
359                  [self->targetWindow stringValueInComponent: comp]];
360     [_response appendContentString:@"\" "];
361   }
362   [_response appendContentString:@" >"];
363
364   /* image itself */
365   [_response appendContentString:@"<img border='0' src=\""];
366   [_response appendContentString:tunselected];
367   [_response appendContentString:@"\" name=\""];
368   [_response appendContentString:elID];
369   [_response appendContentString:@"\" "];
370   [self appendExtraAttributesToResponse:_response inContext:_ctx];
371   [_response appendContentString:@" />"];
372
373   /* close link */
374   [_response appendContentString:@"</a>"];
375 }
376
377 @end /* JSImageFlyover */