KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > wings > plaf > css > FrameCG


1 /*
2  * $Id: FrameCG.java,v 1.43 2005/06/08 19:13:20 neurolabs Exp $
3  * Copyright 2000,2005 wingS development team.
4  *
5  * This file is part of wingS (http://www.j-wings.org).
6  *
7  * wingS is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1
10  * of the License, or (at your option) any later version.
11  *
12  * Please see COPYING for the complete licence.
13  */

14 package org.wings.plaf.css;
15
16
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19 import org.wings.*;
20 import org.wings.externalizer.ExternalizeManager;
21 import org.wings.header.Link;
22 import org.wings.header.Script;
23 import org.wings.io.Device;
24 import org.wings.plaf.CGManager;
25 import org.wings.resource.ClassPathStylesheetResource;
26 import org.wings.resource.ClasspathResource;
27 import org.wings.resource.DefaultURLResource;
28 import org.wings.resource.DynamicCodeResource;
29 import org.wings.script.DynamicScriptResource;
30 import org.wings.script.JavaScriptListener;
31 import org.wings.script.ScriptListener;
32 import org.wings.session.Browser;
33 import org.wings.session.BrowserType;
34 import org.wings.session.SessionManager;
35 import org.wings.style.CSSSelector;
36 import org.wings.style.DynamicStyleSheetResource;
37
38 import java.io.IOException JavaDoc;
39 import java.util.*;
40
41 public class FrameCG implements org.wings.plaf.FrameCG {
42     private final transient static Log log = LogFactory.getLog(FrameCG.class);
43
44     /**
45      * The default DOCTYPE enforcing standard (non-quirks mode) in all current browsers.
46      * Please be aware, that changing the DOCTYPE may change the way how browser renders the generate
47      * document i.e. esp. the CSS attribute inheritance does not work correctly on <code>table</code> elements.
48      * See i.e. http://www.ericmeyeroncss.com/bonus/render-mode.html
49      */

50     public final static String JavaDoc STRICT_DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" " +
51             "\"http://www.w3.org/TR/REC-html40/strict.dtd\">";
52
53     /**
54      * The HTML DOCTYPE setting all browsers to Quirks mode.
55      * We need this to force IE to use the correct box rendering model. It's the only browser
56      * you cannot reconfigure via an CSS tag.
57      */

58     public final static String JavaDoc QUIRKS_DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">";
59
60     private String JavaDoc documentType = STRICT_DOCTYPE;
61
62     private Boolean JavaDoc renderXmlDeclaration = Boolean.FALSE;
63     /**
64      * Initialize properties from config
65      */

66     public FrameCG() {
67         final CGManager manager = SessionManager.getSession().getCGManager();
68         final String JavaDoc userDocType = (String JavaDoc) manager.getObject("FrameCG.userDocType", String JavaDoc.class);
69         final Boolean JavaDoc userRenderXmlDecl = (Boolean JavaDoc) manager.getObject("FrameCG.renderXmlDeclaration", Boolean JavaDoc.class);
70
71         if (userDocType != null)
72             setDocumentType(userDocType);
73
74         if (userRenderXmlDecl != null)
75             setRenderXmlDeclaration(userRenderXmlDecl);
76     }
77
78     private static final String JavaDoc PROPERTY_STYLESHEET = "Stylesheet.";
79     private static final String JavaDoc BROWSER_DEFAULT = "default";
80     
81     private final static Set javascriptResourceKeys;
82     static {
83         javascriptResourceKeys = new HashSet();
84         javascriptResourceKeys.add("JScripts.domlib");
85         javascriptResourceKeys.add("JScripts.domtt");
86     }
87     
88     
89     /**
90      * Externalizes the style sheet(s) for this session.
91      * Look up according style sheet file name in org.wings.plaf.css.properties file under Stylesheet.BROWSERNAME.
92      * The style sheet is loaded from the class path.
93      * @return the URLs under which the css file(s) was externalized
94      */

95     private List externalizeBrowserStylesheets() {
96         final ExternalizeManager extManager = SessionManager.getSession().getExternalizeManager();
97         final CGManager manager = SessionManager.getSession().getCGManager();
98         final String JavaDoc browserName = SessionManager.getSession().getUserAgent().getBrowserType().getShortName();
99         final String JavaDoc cssResource = PROPERTY_STYLESHEET + browserName;
100         String JavaDoc cssClassPaths = (String JavaDoc)manager.getObject(cssResource, String JavaDoc.class);
101         // catch missing browser entry in properties file
102
if (cssClassPaths == null) {
103             cssClassPaths = (String JavaDoc)manager.getObject(PROPERTY_STYLESHEET + BROWSER_DEFAULT, String JavaDoc.class);
104         }
105
106         StringTokenizer tokenizer = new StringTokenizer(cssClassPaths,",");
107         ArrayList cssUrls = new ArrayList();
108         while (tokenizer.hasMoreTokens()) {
109             String JavaDoc cssClassPath = tokenizer.nextToken();
110             ClassPathStylesheetResource res = new ClassPathStylesheetResource(cssClassPath, "text/css");
111             String JavaDoc cssUrl = extManager.externalize(res, ExternalizeManager.GLOBAL);
112             if (cssUrl != null)
113                 cssUrls.add(cssUrl);
114         }
115
116         return cssUrls;
117     }
118
119
120     /**
121      * @param jsResKey
122      * @return
123      */

124     private String JavaDoc externalizeJavaScript(String JavaDoc jsResKey) {
125         final ExternalizeManager extManager = SessionManager.getSession().getExternalizeManager();
126         final CGManager manager = SessionManager.getSession().getCGManager();
127         String JavaDoc jsClassPath = (String JavaDoc)manager.getObject(jsResKey, String JavaDoc.class);
128         // catch missing script entry in properties file
129
if (jsClassPath != null) {
130             ClasspathResource res = new ClasspathResource(jsClassPath, "text/javascript");
131             return extManager.externalize(res, ExternalizeManager.GLOBAL);
132         }
133         return null;
134     }
135
136     public static final String JavaDoc UTILS_SCRIPT = (String JavaDoc) SessionManager
137             .getSession().getCGManager().getObject("JScripts.utils",
138                     String JavaDoc.class);
139
140     public static final String JavaDoc FORM_SCRIPT = (String JavaDoc) SessionManager
141             .getSession().getCGManager().getObject("JScripts.form",
142                     String JavaDoc.class);
143
144     public static final JavaScriptListener FOCUS_SCRIPT =
145             new JavaScriptListener("onfocus", "storeFocus(event)");
146
147     public static final JavaScriptListener SCROLL_POSITION_SCRIPT =
148             new JavaScriptListener("onscroll", "storeScrollPosition(event)");
149
150
151     public void installCG(final SComponent comp) {
152         final SFrame component = (SFrame) comp;
153
154         DynamicCodeResource dynamicCodeRessource;
155         DynamicStyleSheetResource styleSheetResource;
156         DynamicScriptResource scriptResource;
157         Link stylesheetLink;
158
159         // dynamic code resource.
160
dynamicCodeRessource = new DynamicCodeResource(component);
161         component.addDynamicResource(dynamicCodeRessource);
162
163         // dynamic stylesheet resource.
164
styleSheetResource = new DynamicStyleSheetResource(component);
165         stylesheetLink = new Link("stylesheet", null, "text/css", null, styleSheetResource);
166         component.addDynamicResource(styleSheetResource);
167         component.addHeader(stylesheetLink);
168
169         // dynamic java script resource.
170
scriptResource = new DynamicScriptResource(component);
171         component.addDynamicResource(scriptResource);
172         component.addHeader(new Script("text/javascript", scriptResource));
173
174         Iterator iter = javascriptResourceKeys.iterator();
175         while (iter.hasNext()) {
176             String JavaDoc jsResKey = (String JavaDoc) iter.next();
177             String JavaDoc jScriptUrl = externalizeJavaScript(jsResKey);
178             if (jScriptUrl != null) {
179                 component.addHeader(new Script("text/javascript", new DefaultURLResource(jScriptUrl)));
180             }
181         }
182
183         final List externalizedBrowserCssUrls = externalizeBrowserStylesheets();
184         for (int i = 0; i < externalizedBrowserCssUrls.size(); i++) {
185               component.headers().add(i, new Link("stylesheet", null, "text/css", null, new DefaultURLResource((String JavaDoc) externalizedBrowserCssUrls.get(i))));;
186         }
187
188         addExternalizedHeader(component, UTILS_SCRIPT, "text/javascript");
189         addExternalizedHeader(component, FORM_SCRIPT, "text/javascript");
190         component.addScriptListener(FOCUS_SCRIPT);
191         component.addScriptListener(SCROLL_POSITION_SCRIPT);
192         CaptureDefaultBindingsScriptListener.install(component);
193     }
194
195     /**
196      * adds the file found at the classPath to the parentFrame header with
197      * the specified mimeType
198      * @param classPath the classPath to look in for the file
199      * @param mimeType the mimetype of the file
200      */

201     private void addExternalizedHeader(SFrame parentFrame, String JavaDoc classPath, String JavaDoc mimeType) {
202         ClasspathResource res = new ClasspathResource(classPath, mimeType);
203         String JavaDoc jScriptUrl = SessionManager.getSession().getExternalizeManager().externalize(res, ExternalizeManager.GLOBAL);
204         parentFrame.addHeader(new Script(mimeType, new DefaultURLResource(jScriptUrl)));
205     }
206
207     public void uninstallCG(final SComponent comp) {
208         final SFrame component = (SFrame) comp;
209
210         component.removeDynamicResource(DynamicCodeResource.class);
211         component.removeDynamicResource(DynamicStyleSheetResource.class);
212         component.removeDynamicResource(DynamicScriptResource.class);
213         component.clearHeaders();
214     }
215
216     public void write(final Device device, final SComponent _c)
217             throws IOException JavaDoc {
218         if (!_c.isVisible()) return;
219         _c.fireRenderEvent(SComponent.START_RENDERING);
220         final SFrame component = (SFrame) _c;
221
222         Browser browser = SessionManager.getSession().getUserAgent();
223         SFrame frame = (SFrame) component;
224         String JavaDoc language = SessionManager.getSession().getLocale().getLanguage();
225         String JavaDoc title = frame.getTitle();
226         List headers = frame.headers();
227         String JavaDoc encoding = SessionManager.getSession().getCharacterEncoding();
228
229         /**
230          * We need to put IE6 into quirks mode
231          * for box model compatibility. (border-box).
232          * For that we make use of a comment in the first line.
233          * This is a known bug in IE6
234          */

235         if (BrowserType.IE.equals(browser.getBrowserType())) {
236             if (browser.getMajorVersion() == 6) {
237                 device.print("<!-- IE6 quirks mode switch -->\n");
238             }
239         }
240
241         if (renderXmlDeclaration == null || renderXmlDeclaration.booleanValue()) {
242             device.print("<?xml version=\"1.0\" encoding=\"");
243             Utils.write(device, encoding);
244             device.print("\"?>\n");
245         }
246
247         Utils.writeRaw(device, documentType);
248         device.print("\n");
249         device.print("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"");
250         Utils.write(device, language);
251         device.print("\" lang=\"");
252         Utils.write(device, language);
253         device.print("\">\n");
254
255         /* Insert version and compile time.
256          * Since the Version Class is generated on compile time, build errors
257          * in SDK's are quite normal. Just run the Version.java ant task.
258          */

259         device.print("<!-- This is wingS (http://www.j-wings.org) version ");
260         device.print(Version.getVersion());
261         device.print(" (Build date: ");
262         device.print(Version.getCompileTime());
263         device.print(") -->\n");
264         
265         device.print("<head>");
266         if (title != null) {
267             device.print("<title>");
268             Utils.write(device, title);
269             device.print("</title>\n");
270         }
271
272         device.print("<meta http-equiv=\"Content-type\" content=\"text/html; charset=");
273         Utils.write(device, encoding);
274         device.print("\"/>\n");
275
276         for (Iterator iterator = headers.iterator(); iterator.hasNext();) {
277             Object JavaDoc next = iterator.next();
278             if (next instanceof Renderable) {
279                 ((Renderable) next).write(device);
280             } else {
281                 Utils.write(device, next.toString());
282             }
283             device.print("\n");
284         }
285
286         SComponent focus = frame.getFocus();
287         Object JavaDoc lastFocus = frame.getClientProperty("focus");
288         if (focus != lastFocus) {
289             if (lastFocus != null) {
290                 ScriptListener[] scriptListeners = frame.getScriptListeners();
291
292                 for (int i = 0; i < scriptListeners.length; i++) {
293                     ScriptListener scriptListener = scriptListeners[i];
294                     if (scriptListener instanceof FocusScriptListener)
295                         component.removeScriptListener(scriptListener);
296                 }
297             }
298             if (focus != null) {
299                 FocusScriptListener listener = new FocusScriptListener("onload", "requestFocus('" + focus.getName() + "')");
300                 frame.addScriptListener(listener);
301             }
302             frame.putClientProperty("focus", focus);
303         }
304         
305         // let ie understand hover css styles on elements other than anchors
306
if (BrowserType.IE.equals(browser.getBrowserType())) {
307             // externalize hover behavior
308
final String JavaDoc classPath = (String JavaDoc)SessionManager.getSession().getCGManager().getObject("Behaviors.ieHover", String JavaDoc.class);
309             ClasspathResource res = new ClasspathResource(classPath, "text/x-component");
310             String JavaDoc behaviorUrl = SessionManager.getSession().getExternalizeManager().externalize(res, ExternalizeManager.GLOBAL);
311             device.print("<style type=\"text/css\" media=\"screen\">\n");
312             device.print("body{behavior:url(");
313             device.print(behaviorUrl);
314             device.print(");}\n");
315             device.print("</style>\n");
316         }
317         
318
319
320         // TODO: move this to a dynamic script resource
321
SToolTipManager toolTipManager = component.getSession().getToolTipManager();
322         device
323                 .print("<script type=\"text/javascript\">\n")
324                 .print("domTT_addPredefined('default', 'caption', false");
325         if (toolTipManager.isFollowMouse())
326             device.print(", 'trail', true");
327         device.print(", 'delay', ").print(toolTipManager.getInitialDelay());
328         device.print(", 'lifetime', ").print(toolTipManager.getDismissDelay());
329         device
330                 .print(");\n")
331                 .print("</script>\n");
332         
333         device.print("</head>\n");
334         device.print("<body");
335         Utils.optAttribute(device, "id", frame.getName());
336         Utils.optAttribute(device, "class", frame.getStyle());
337         Utils.writeEvents(device, frame);
338         device.print(">\n");
339         if (frame.isVisible()) {
340             frame.getLayout().write(device);
341             device.print("\n");
342             // now add all menus
343
Iterator iter = frame.getMenus().iterator();
344             while (iter.hasNext()) {
345                 SComponent menu = (SComponent)iter.next();
346                 menu.write(device);
347             }
348         }
349         device.print("\n</body></html>\n");
350         _c.fireRenderEvent(SComponent.DONE_RENDERING);
351     }
352
353     public String JavaDoc getDocumentType() {
354         return documentType;
355     }
356
357     public void setDocumentType(String JavaDoc documentType) {
358         this.documentType = documentType;
359     }
360
361     /**
362      * @return The current rendered DOCTYPE of this document. {@link #STRICT_DOCTYPE}
363      */

364     public Boolean JavaDoc getRenderXmlDeclaration() {
365         return renderXmlDeclaration;
366     }
367
368     public void setRenderXmlDeclaration(Boolean JavaDoc renderXmlDeclaration) {
369         this.renderXmlDeclaration = renderXmlDeclaration;
370     }
371
372     public CSSSelector mapSelector(SComponent addressedComponent, CSSSelector selector) {
373         // Default: Do not map/modify the passed CSS selector.
374
return selector;
375     }
376 }
377
Popular Tags