KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lobobrowser > html > js > Window


1 /*
2     GNU LESSER GENERAL PUBLIC LICENSE
3     Copyright (C) 2006 The Lobo Project
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19     Contact info: xamjadmin@users.sourceforge.net
20 */

21 /*
22  * Created on Nov 12, 2005
23  */

24 package org.lobobrowser.html.js;
25
26 import java.util.*;
27 import java.lang.ref.*;
28 import javax.swing.Timer JavaDoc;
29 import java.awt.event.*;
30 import java.util.logging.*;
31
32 import org.lobobrowser.html.*;
33 import org.lobobrowser.html.domimpl.*;
34 import org.lobobrowser.js.*;
35 import org.lobobrowser.util.ID;
36 import org.mozilla.javascript.Context;
37 import org.mozilla.javascript.Function;
38 import org.mozilla.javascript.Scriptable;
39 import org.mozilla.javascript.ScriptableObject;
40 import org.w3c.dom.Document JavaDoc;
41 import org.w3c.dom.html2.*;
42
43 public class Window extends AbstractScriptableDelegate {
44     private static final Logger logger = Logger.getLogger(Window.class.getName());
45     private static final Map CONTEXT_WINDOWS = new WeakHashMap();
46     //private static final JavaClassWrapper IMAGE_WRAPPER = JavaClassWrapperFactory.getInstance().getClassWrapper(Image.class);
47
private static final JavaClassWrapper XMLHTTPREQUEST_WRAPPER = JavaClassWrapperFactory.getInstance().getClassWrapper(XMLHttpRequest.class);
48     
49     private final HtmlRendererContext rcontext;
50     private final UserAgentContext uaContext;
51
52     private Navigator navigator;
53     private Screen screen;
54     private Location location;
55     private Map taskMap;
56     private volatile Document JavaDoc document;
57     
58     public Window(HtmlRendererContext rcontext, UserAgentContext uaContext) {
59         //TODO: Probably need to create a new Window instance
60
//for every document. Sharing of Window state between
61
//different documents is not correct.
62
this.rcontext = rcontext;
63         this.uaContext = uaContext;
64     }
65
66     public HtmlRendererContext getHtmlRendererContext() {
67         return this.rcontext;
68     }
69     
70     public void setDocument(Document JavaDoc document) {
71         Document JavaDoc prevDocument = this.document;
72         if(prevDocument != document) {
73             this.forgetAllTasks();
74             Function onunload = this.onunload;
75             if(onunload != null) {
76                 HTMLDocumentImpl oldDoc = (HTMLDocumentImpl) this.document;
77                 Executor.executeFunction(this.getWindowScope(), onunload, oldDoc.getDocumentURL(), this.uaContext);
78                 this.onunload = null;
79             }
80             this.document = document;
81         }
82     }
83
84     public Document JavaDoc getDocument() {
85         return this.document;
86     }
87
88     private void putTask(Integer JavaDoc timeoutID, Timer JavaDoc timer) {
89         synchronized(this) {
90             Map taskMap = this.taskMap;
91             if(taskMap == null) {
92                 taskMap = new HashMap();
93                 this.taskMap = taskMap;
94             }
95             taskMap.put(timeoutID, timer);
96         }
97     }
98     
99     private void forgetTask(Integer JavaDoc timeoutID, boolean cancel) {
100         synchronized(this) {
101             Map taskMap = this.taskMap;
102             if(taskMap != null) {
103                 Timer JavaDoc timer = (Timer JavaDoc) taskMap.remove(timeoutID);
104                 if(timer != null && cancel) {
105                     timer.stop();
106                 }
107             }
108         }
109     }
110     
111     private void forgetAllTasks() {
112         synchronized(this) {
113             Map taskMap = this.taskMap;
114             if(taskMap != null) {
115                 Iterator i = taskMap.values().iterator();
116                 while(i.hasNext()) {
117                     Timer JavaDoc timer = (Timer JavaDoc) i.next();
118                     timer.stop();
119                 }
120                 this.taskMap = null;
121             }
122         }
123     }
124
125     // private Timer getTask(Long timeoutID) {
126
// synchronized(this) {
127
// Map taskMap = this.taskMap;
128
// if(taskMap != null) {
129
// return (Timer) taskMap.get(timeoutID);
130
// }
131
// }
132
// return null;
133
// }
134

135     public void alert(String JavaDoc message) {
136         if(this.rcontext != null) {
137             this.rcontext.alert(message);
138         }
139     }
140     
141     public void back() {
142         HtmlRendererContext rcontext = this.rcontext;
143         if(rcontext != null) {
144             rcontext.back();
145         }
146     }
147     
148     public void blur() {
149         HtmlRendererContext rcontext = this.rcontext;
150         if(rcontext != null) {
151             rcontext.blur();
152         }
153     }
154     
155     public void clearTimeout(int timeoutID) {
156         Integer JavaDoc key = new Integer JavaDoc(timeoutID);
157         this.forgetTask(key, true);
158     }
159     
160     public void close() {
161         HtmlRendererContext rcontext = this.rcontext;
162         if(rcontext != null) {
163             rcontext.close();
164         }
165     }
166     
167     public boolean confirm(String JavaDoc message) {
168         HtmlRendererContext rcontext = this.rcontext;
169         if(rcontext != null) {
170             return rcontext.confirm(message);
171         }
172         else {
173             return false;
174         }
175     }
176     
177     public Object JavaDoc eval(String JavaDoc javascript) {
178         HTMLDocumentImpl document = (HTMLDocumentImpl) this.document;
179         if(document == null) {
180             throw new IllegalStateException JavaDoc("Cannot evaluate if document is not set.");
181         }
182         Context ctx = Executor.createContext(document.getDocumentURL(), this.uaContext);
183         try {
184             Scriptable scope = this.getWindowScope();
185             if(scope == null) {
186                 throw new IllegalStateException JavaDoc("Scriptable (scope) instance was expected to be keyed as UserData to document using " + Executor.SCOPE_KEY);
187             }
188             String JavaDoc scriptURI = "window.eval";
189             if(logger.isLoggable(Level.INFO)) {
190                 logger.info("eval(): javascript follows...\r\n" + javascript);
191             }
192             return ctx.evaluateString(scope, javascript, scriptURI, 1, null);
193         } finally {
194             Context.exit();
195         }
196     }
197     
198     public void focus() {
199         HtmlRendererContext rcontext = this.rcontext;
200         if(rcontext != null) {
201             rcontext.focus();
202         }
203     }
204
205     private ScriptableObject windowScope;
206
207     public Scriptable getWindowScope() {
208         synchronized(this) {
209             ScriptableObject windowScope = this.windowScope;
210             if(windowScope != null) {
211                 return windowScope;
212             }
213             // Context.enter() OK in this particular case.
214
Context ctx = Context.enter();
215             try {
216                 // Window scope needs to be top-most scope.
217
windowScope = (ScriptableObject) JavaScript.getInstance().getJavascriptObject(this, null);
218                 ctx.initStandardObjects(windowScope);
219
220                 // Special Javascript class: XMLHttpRequest
221
final Scriptable ws = windowScope;
222                 JavaInstantiator xi = new JavaInstantiator() {
223                     public Object JavaDoc newInstance() {
224                         HTMLDocumentImpl doc = (HTMLDocumentImpl) document;
225                         if(doc == null) {
226                             throw new IllegalStateException JavaDoc("Cannot perform operation when document is unset.");
227                         }
228                         return new XMLHttpRequest(uaContext, doc.getDocumentURL(), ws);
229                     }
230                 };
231                 Function xmlHttpRequestC = JavaObjectWrapper.getConstructor("XMLHttpRequest", XMLHTTPREQUEST_WRAPPER, windowScope, xi);
232                 ScriptableObject.defineProperty(windowScope, "XMLHttpRequest", xmlHttpRequestC, ScriptableObject.READONLY);
233
234                 // HTML element classes
235
this.defineElementClass(windowScope, "Image", "img", HTMLImageElementImpl.class);
236                 this.defineElementClass(windowScope, "Script", "script", HTMLScriptElementImpl.class);
237                 this.defineElementClass(windowScope, "IFrame", "iframe", HTMLIFrameElementImpl.class);
238                 this.defineElementClass(windowScope, "Option", "option", HTMLOptionElementImpl.class);
239                 this.defineElementClass(windowScope, "Select", "select", HTMLSelectElementImpl.class);
240                 
241                 this.windowScope = windowScope;
242                 return windowScope;
243             } finally {
244                 Context.exit();
245             }
246         }
247     }
248     
249     private final void defineElementClass(Scriptable scope, final String JavaDoc jsClassName, final String JavaDoc elementName, Class JavaDoc javaClass) {
250         JavaInstantiator ji = new JavaInstantiator() {
251             public Object JavaDoc newInstance() {
252                 Document JavaDoc document = Window.this.document;
253                 if(document == null) {
254                     throw new IllegalStateException JavaDoc("Document not set in current context.");
255                 }
256                 return document.createElement(elementName);
257             }
258         };
259         JavaClassWrapper classWrapper = JavaClassWrapperFactory.getInstance().getClassWrapper(javaClass);
260         Function constructorFunction = JavaObjectWrapper.getConstructor(jsClassName, classWrapper, scope, ji);
261         ScriptableObject.defineProperty(scope, jsClassName, constructorFunction, ScriptableObject.READONLY);
262     }
263     
264     public static Window getWindow(HtmlRendererContext rcontext) {
265         if(rcontext == null) {
266             return null;
267         }
268         synchronized(CONTEXT_WINDOWS) {
269             Reference wref = (Reference) CONTEXT_WINDOWS.get(rcontext);
270             if(wref != null) {
271                 Window window = (Window) wref.get();
272                 if(window != null) {
273                     return window;
274                 }
275             }
276             Window window = new Window(rcontext, rcontext.getUserAgentContext());
277             CONTEXT_WINDOWS.put(rcontext, new WeakReference(window));
278             return window;
279         }
280     }
281     
282     public Window open(String JavaDoc relativeUrl, String JavaDoc windowName, String JavaDoc windowFeatures, boolean replace) {
283         HtmlRendererContext rcontext = this.rcontext;
284         if(rcontext != null) {
285             java.net.URL JavaDoc url;
286             Object JavaDoc document = this.document;
287             if(document instanceof HTMLDocumentImpl) {
288                 url = ((HTMLDocumentImpl) document).getFullURL(relativeUrl);
289             }
290             else {
291                 try {
292                     url = new java.net.URL JavaDoc(relativeUrl);
293                 } catch(java.net.MalformedURLException JavaDoc mfu) {
294                     throw new IllegalArgumentException JavaDoc("Malformed URI: " + relativeUrl);
295                 }
296             }
297             HtmlRendererContext newContext = rcontext.open(url, windowName, windowFeatures, replace);
298             return getWindow(newContext);
299         }
300         else {
301             return null;
302         }
303     }
304
305     public Window open(String JavaDoc url, String JavaDoc windowName) {
306         return this.open(url, windowName, "", false);
307     }
308
309     public Window open(String JavaDoc url, String JavaDoc windowName, String JavaDoc windowFeatures) {
310         return this.open(url, windowName, windowFeatures, false);
311     }
312
313     public String JavaDoc prompt(String JavaDoc message) {
314         return this.prompt(message, "");
315     }
316     
317     public String JavaDoc prompt(String JavaDoc message, int inputDefault) {
318         return this.prompt(message, String.valueOf(inputDefault));
319     }
320
321     public String JavaDoc prompt(String JavaDoc message, String JavaDoc inputDefault) {
322         HtmlRendererContext rcontext = this.rcontext;
323         if(rcontext != null) {
324             return rcontext.prompt(message, inputDefault);
325         }
326         else {
327             return null;
328         }
329     }
330
331     public void scroll(int x, int y) {
332         HtmlRendererContext rcontext = this.rcontext;
333         if(rcontext != null) {
334             rcontext.scroll(x, y);
335         }
336     }
337     
338     public int setTimeout(final String JavaDoc expr, double millis) {
339         final int timeID = ID.generateInt();
340         final Integer JavaDoc timeIDInt = new Integer JavaDoc(timeID);
341         ActionListener task = new ActionListener() {
342             public void actionPerformed(ActionEvent e) {
343                 // This executes in the GUI thread and that's good.
344
Window.this.forgetTask(timeIDInt, false);
345                 Window.this.eval(expr);
346             }
347         };
348         if(millis > Integer.MAX_VALUE || millis < 0) {
349             throw new IllegalArgumentException JavaDoc("Timeout value " + millis + " is not supported.");
350         }
351         Timer JavaDoc timer = new Timer JavaDoc((int) millis, task);
352         timer.setRepeats(false);
353         timer.start();
354         this.putTask(timeIDInt, timer);
355         return timeID;
356     }
357     
358     public int setTimeout(final Function function, double millis) {
359         final int timeID = ID.generateInt();
360         final Integer JavaDoc timeIDInt = new Integer JavaDoc(timeID);
361         ActionListener task = new ActionListener() {
362             public void actionPerformed(ActionEvent e) {
363                 // This executes in the GUI thread and that's good.
364
Window.this.forgetTask(timeIDInt, false);
365                 HTMLDocumentImpl doc = (HTMLDocumentImpl) document;
366                 if(doc == null) {
367                     throw new IllegalStateException JavaDoc("Cannot perform operation when document is unset.");
368                 }
369                 Executor.executeFunction(getWindowScope(), function, doc.getDocumentURL(), uaContext);
370             }
371         };
372         if(millis > Integer.MAX_VALUE || millis < 0) {
373             throw new IllegalArgumentException JavaDoc("Timeout value " + millis + " is not supported.");
374         }
375         Timer JavaDoc timer = new Timer JavaDoc((int) millis, task);
376         timer.setRepeats(false);
377         timer.start();
378         this.putTask(timeIDInt, timer);
379         return timeID;
380     }
381
382     public boolean isClosed() {
383         HtmlRendererContext rcontext = this.rcontext;
384         if(rcontext != null) {
385             return rcontext.isClosed();
386         }
387         else {
388             return false;
389         }
390     }
391     
392     public String JavaDoc getDefaultStatus() {
393         HtmlRendererContext rcontext = this.rcontext;
394         if(rcontext != null) {
395             return rcontext.getDefaultStatus();
396         }
397         else {
398             return null;
399         }
400     }
401     
402     public HTMLCollection getFrames() {
403         Document JavaDoc doc = this.document;
404         if(doc instanceof HTMLDocumentImpl) {
405             return ((HTMLDocumentImpl) doc).getFrames();
406         }
407         return null;
408     }
409     
410     /**
411      * Gets the number of frames.
412      */

413     public int getLength() {
414         HTMLCollection frames = this.getFrames();
415         return frames == null ? 0 : frames.getLength();
416     }
417     
418     public String JavaDoc getName() {
419         HtmlRendererContext rcontext = this.rcontext;
420         if(rcontext != null) {
421             return rcontext.getName();
422         }
423         else {
424             return null;
425         }
426     }
427     
428     public Window getParent() {
429         HtmlRendererContext rcontext = this.rcontext;
430         if(rcontext != null) {
431             return Window.getWindow(rcontext.getParent());
432         }
433         else {
434             return null;
435         }
436     }
437     
438     public Window getOpener() {
439         HtmlRendererContext rcontext = this.rcontext;
440         if(rcontext != null) {
441             return Window.getWindow(rcontext.getOpener());
442         }
443         else {
444             return null;
445         }
446     }
447     
448     public void setOpener(Window opener) {
449         HtmlRendererContext rcontext = this.rcontext;
450         if(rcontext != null) {
451             if(opener == null) {
452                 rcontext.setOpener(null);
453             }
454             else {
455                 rcontext.setOpener(opener.rcontext);
456             }
457         }
458     }
459     
460     public Window getSelf() {
461         return this;
462     }
463     
464     public String JavaDoc getStatus() {
465         HtmlRendererContext rcontext = this.rcontext;
466         if(rcontext != null) {
467             return rcontext.getStatus();
468         }
469         else {
470             return null;
471         }
472     }
473     
474     public void setStatus(String JavaDoc message) {
475         HtmlRendererContext rcontext = this.rcontext;
476         if(rcontext != null) {
477             rcontext.setStatus(message);
478         }
479     }
480         
481     public Window getTop() {
482         HtmlRendererContext rcontext = this.rcontext;
483         if(rcontext != null) {
484             return Window.getWindow(rcontext.getTop());
485         }
486         else {
487             return null;
488         }
489     }
490     
491     public Window getWindow() {
492         return this;
493     }
494     
495     
496     public Navigator getNavigator() {
497         synchronized(this) {
498             Navigator nav = this.navigator;
499             if(nav == null) {
500                 nav = new Navigator(this.uaContext);
501                 this.navigator = nav;
502             }
503             return nav;
504         }
505     }
506     
507     public Screen getScreen() {
508         synchronized(this) {
509             Screen nav = this.screen;
510             if(nav == null) {
511                 nav = new Screen();
512                 this.screen = nav;
513             }
514             return nav;
515         }
516     }
517     
518     public Location getLocation() {
519         synchronized(this) {
520             Location location = this.location;
521             if(location == null) {
522                 location = new Location(this);
523                 this.location = location;
524             }
525             return location;
526         }
527     }
528     
529     public void setLocation(String JavaDoc location) {
530         this.getLocation().setHref(location);
531     }
532     
533     public Function getOnload() {
534         Document JavaDoc doc = this.document;
535         if(doc instanceof HTMLDocumentImpl) {
536             return ((HTMLDocumentImpl) doc).getOnloadHandler();
537         }
538         else {
539             return null;
540         }
541     }
542
543     public void setOnload(Function onload) {
544         //Note that body.onload overrides
545
//window.onload.
546
Document JavaDoc doc = this.document;
547         if(doc instanceof HTMLDocumentImpl) {
548             ((HTMLDocumentImpl) doc).setOnloadHandler(onload);
549         }
550     }
551
552     private Function onunload;
553
554     public Function getOnunload() {
555         return onunload;
556     }
557
558     public void setOnunload(Function onunload) {
559         this.onunload = onunload;
560     }
561 }
562
563
Popular Tags