Reviewed by Trey.
[WebKit-https.git] / WebCore / khtml / ecma / kjs_window.cpp
1 // -*- c-basic-offset: 2 -*-
2 /*
3  *  This file is part of the KDE libraries
4  *  Copyright (C) 2000 Harri Porten (porten@kde.org)
5  *  Copyright (C) 2003 Apple Computer, Inc.
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <qstylesheet.h>
23 #include <qtimer.h>
24 #include <qinputdialog.h>
25 #include <qpaintdevicemetrics.h>
26 #include <qapplication.h>
27 #include <kdebug.h>
28 #include <kmessagebox.h>
29 #include <klocale.h>
30 #include <kparts/browserinterface.h>
31 #include <kwin.h>
32 #include <kwinmodule.h>
33 #include <kconfig.h>
34 #include <assert.h>
35 #include <qstyle.h>
36 #include "rendering/render_canvas.h"
37
38 #if APPLE_CHANGES
39 #include "KWQLogging.h"
40 #include "KWQKConfigBase.h"
41 #endif
42 #include <kjs/collector.h>
43 #include "kjs_proxy.h"
44 #include "kjs_window.h"
45 #include "kjs_navigator.h"
46 #include "kjs_html.h"
47 #include "kjs_range.h"
48 #include "kjs_traversal.h"
49 #include "kjs_css.h"
50 #include "kjs_events.h"
51 #include "xmlhttprequest.h"
52 #include "xmlserializer.h"
53
54 #include "khtmlview.h"
55 #include "khtml_part.h"
56 #include "dom/dom_string.h"
57 #include "dom/dom_node.h"
58 #include "editing/htmlediting.h"
59 #include "xml/dom2_eventsimpl.h"
60 #include "xml/dom_docimpl.h"
61 #include "xml/dom_position.h"
62 #include "xml/dom_selection.h"
63 #include "html/html_documentimpl.h"
64
65 using DOM::DocumentImpl;
66 using DOM::DOMString;
67 using DOM::Node;
68 using DOM::Position;
69 using khtml::TypingCommand;
70
71 using namespace KJS;
72
73 namespace KJS {
74
75 ////////////////////// History Object ////////////////////////
76
77   class History : public ObjectImp {
78     friend class HistoryFunc;
79   public:
80     History(ExecState *exec, KHTMLPart *p)
81       : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
82     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
83     Value getValueProperty(ExecState *exec, int token) const;
84     virtual const ClassInfo* classInfo() const { return &info; }
85     static const ClassInfo info;
86     enum { Back, Forward, Go, Length };
87     virtual UString toString(ExecState *exec) const;
88   private:
89     QGuardedPtr<KHTMLPart> part;
90   };
91
92   class FrameArray : public ObjectImp {
93   public:
94     FrameArray(ExecState *exec, KHTMLPart *p)
95       : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
96     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
97     virtual UString toString(ExecState *exec) const;
98   private:
99     QGuardedPtr<KHTMLPart> part;
100   };
101
102 #ifdef Q_WS_QWS
103   class KonquerorFunc : public DOMFunction {
104   public:
105     KonquerorFunc(const Konqueror* k, const char* name)
106       : DOMFunction(), konqueror(k), m_name(name) { }
107     virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args);
108
109   private:
110     const Konqueror* konqueror;
111     QCString m_name;
112   };
113 #endif
114 }; // namespace KJS
115
116 #include "kjs_window.lut.h"
117
118 ////////////////////// Screen Object ////////////////////////
119
120 // table for screen object
121 /*
122 @begin ScreenTable 7
123   height        Screen::Height          DontEnum|ReadOnly
124   width         Screen::Width           DontEnum|ReadOnly
125   colorDepth    Screen::ColorDepth      DontEnum|ReadOnly
126   pixelDepth    Screen::PixelDepth      DontEnum|ReadOnly
127   availLeft     Screen::AvailLeft       DontEnum|ReadOnly
128   availTop      Screen::AvailTop        DontEnum|ReadOnly
129   availHeight   Screen::AvailHeight     DontEnum|ReadOnly
130   availWidth    Screen::AvailWidth      DontEnum|ReadOnly
131 @end
132 */
133
134 const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
135
136 // We set the object prototype so that toString is implemented
137 Screen::Screen(ExecState *exec)
138   : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()) {}
139
140 Value Screen::get(ExecState *exec, const Identifier &p) const
141 {
142 #ifdef KJS_VERBOSE
143   kdDebug(6070) << "Screen::get " << p.qstring() << endl;
144 #endif
145   return lookupGetValue<Screen,ObjectImp>(exec,p,&ScreenTable,this);
146 }
147
148 Value Screen::getValueProperty(ExecState *exec, int token) const
149 {
150   KWinModule info;
151   QWidget *thisWidget = Window::retrieveActive(exec)->part()->view();
152   QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(thisWidget));
153
154   switch( token ) {
155   case Height:
156     return Number(sg.height());
157   case Width:
158     return Number(sg.width());
159   case ColorDepth:
160   case PixelDepth: {
161     QPaintDeviceMetrics m(QApplication::desktop());
162     return Number(m.depth());
163   }
164   case AvailLeft: {
165     QRect clipped = info.workArea().intersect(sg);
166     return Number(clipped.x()-sg.x());
167   }
168   case AvailTop: {
169     QRect clipped = info.workArea().intersect(sg);
170     return Number(clipped.y()-sg.y());
171   }
172   case AvailHeight: {
173     QRect clipped = info.workArea().intersect(sg);
174     return Number(clipped.height());
175   }
176   case AvailWidth: {
177     QRect clipped = info.workArea().intersect(sg);
178     return Number(clipped.width());
179   }
180   default:
181     kdWarning() << "Screen::getValueProperty unhandled token " << token << endl;
182     return Undefined();
183   }
184 }
185
186 ////////////////////// Window Object ////////////////////////
187
188 const ClassInfo Window::info = { "Window", 0, &WindowTable, 0 };
189
190 /*
191 @begin WindowTable 91
192   closed        Window::Closed          DontDelete|ReadOnly
193   crypto        Window::Crypto          DontDelete|ReadOnly
194   defaultStatus Window::DefaultStatus   DontDelete
195   defaultstatus Window::DefaultStatus   DontDelete
196   status        Window::Status          DontDelete
197   document      Window::Document        DontDelete|ReadOnly
198   Node          Window::Node            DontDelete
199   Event         Window::EventCtor       DontDelete
200   Range         Window::Range           DontDelete
201   NodeFilter    Window::NodeFilter      DontDelete
202   DOMException  Window::DOMException    DontDelete
203   CSSRule       Window::CSSRule         DontDelete
204   frames        Window::Frames          DontDelete|ReadOnly
205   history       Window::_History        DontDelete|ReadOnly
206   event         Window::Event           DontDelete
207   innerHeight   Window::InnerHeight     DontDelete|ReadOnly
208   innerWidth    Window::InnerWidth      DontDelete|ReadOnly
209   length        Window::Length          DontDelete|ReadOnly
210   location      Window::_Location       DontDelete
211   locationbar   Window::Locationbar     DontDelete
212   name          Window::Name            DontDelete
213   navigator     Window::_Navigator      DontDelete|ReadOnly
214   clientInformation     Window::ClientInformation       DontDelete|ReadOnly
215   konqueror     Window::_Konqueror      DontDelete|ReadOnly
216   menubar       Window::Menubar         DontDelete|ReadOnly
217   offscreenBuffering    Window::OffscreenBuffering      DontDelete|ReadOnly
218   opener        Window::Opener          DontDelete|ReadOnly
219   outerHeight   Window::OuterHeight     DontDelete|ReadOnly
220   outerWidth    Window::OuterWidth      DontDelete|ReadOnly
221   pageXOffset   Window::PageXOffset     DontDelete|ReadOnly
222   pageYOffset   Window::PageYOffset     DontDelete|ReadOnly
223   parent        Window::Parent          DontDelete|ReadOnly
224   personalbar   Window::Personalbar     DontDelete|ReadOnly
225   screenX       Window::ScreenX         DontDelete|ReadOnly
226   screenY       Window::ScreenY         DontDelete|ReadOnly
227   screenLeft    Window::ScreenLeft      DontDelete|ReadOnly
228   screenTop     Window::ScreenTop       DontDelete|ReadOnly
229   scrollbars    Window::Scrollbars      DontDelete|ReadOnly
230   statusbar     Window::Statusbar       DontDelete|ReadOnly
231   toolbar       Window::Toolbar         DontDelete|ReadOnly
232   scroll        Window::Scroll          DontDelete|Function 2
233   scrollBy      Window::ScrollBy        DontDelete|Function 2
234   scrollTo      Window::ScrollTo        DontDelete|Function 2
235   scrollX       Window::ScrollX         DontDelete|ReadOnly
236   scrollY       Window::ScrollY         DontDelete|ReadOnly
237   moveBy        Window::MoveBy          DontDelete|Function 2
238   moveTo        Window::MoveTo          DontDelete|Function 2
239   resizeBy      Window::ResizeBy        DontDelete|Function 2
240   resizeTo      Window::ResizeTo        DontDelete|Function 2
241   self          Window::Self            DontDelete|ReadOnly
242   window        Window::_Window         DontDelete|ReadOnly
243   top           Window::Top             DontDelete|ReadOnly
244   screen        Window::_Screen         DontDelete|ReadOnly
245   Image         Window::Image           DontDelete|ReadOnly
246   Option        Window::Option          DontDelete|ReadOnly
247   XMLHttpRequest        Window::XMLHttpRequest  DontDelete|ReadOnly
248   XMLSerializer Window::XMLSerializer   DontDelete|ReadOnly
249   alert         Window::Alert           DontDelete|Function 1
250   confirm       Window::Confirm         DontDelete|Function 1
251   prompt        Window::Prompt          DontDelete|Function 2
252   open          Window::Open            DontDelete|Function 3
253   print         Window::Print           DontDelete|Function 2
254   setTimeout    Window::SetTimeout      DontDelete|Function 2
255   clearTimeout  Window::ClearTimeout    DontDelete|Function 1
256   focus         Window::Focus           DontDelete|Function 0
257   getSelection  Window::GetSelection    DontDelete|Function 0
258   blur          Window::Blur            DontDelete|Function 0
259   close         Window::Close           DontDelete|Function 0
260   setInterval   Window::SetInterval     DontDelete|Function 2
261   clearInterval Window::ClearInterval   DontDelete|Function 1
262   captureEvents Window::CaptureEvents   DontDelete|Function 0
263   releaseEvents Window::ReleaseEvents   DontDelete|Function 0
264 # Warning, when adding a function to this object you need to add a case in Window::get
265   addEventListener      Window::AddEventListener        DontDelete|Function 3
266   removeEventListener   Window::RemoveEventListener     DontDelete|Function 3
267   onabort       Window::Onabort         DontDelete
268   onblur        Window::Onblur          DontDelete
269   onchange      Window::Onchange        DontDelete
270   onclick       Window::Onclick         DontDelete
271   ondblclick    Window::Ondblclick      DontDelete
272   ondragdrop    Window::Ondragdrop      DontDelete
273   onerror       Window::Onerror         DontDelete
274   onfocus       Window::Onfocus         DontDelete
275   onkeydown     Window::Onkeydown       DontDelete
276   onkeypress    Window::Onkeypress      DontDelete
277   onkeyup       Window::Onkeyup         DontDelete
278   onload        Window::Onload          DontDelete
279   onmousedown   Window::Onmousedown     DontDelete
280   onmousemove   Window::Onmousemove     DontDelete
281   onmouseout    Window::Onmouseout      DontDelete
282   onmouseover   Window::Onmouseover     DontDelete
283   onmouseup     Window::Onmouseup       DontDelete
284   onmove        Window::Onmove          DontDelete
285   onreset       Window::Onreset         DontDelete
286   onresize      Window::Onresize        DontDelete
287   onscroll      Window::Onscroll        DontDelete
288   onsearch      Window::Onsearch        DontDelete
289   onselect      Window::Onselect        DontDelete
290   onsubmit      Window::Onsubmit        DontDelete
291   onunload      Window::Onunload        DontDelete
292 @end
293 */
294 IMPLEMENT_PROTOFUNC(WindowFunc)
295
296 Window::Window(KHTMLPart *p)
297   : ObjectImp(/*no proto*/)
298   , m_part(p)
299   , screen(0)
300   , history(0)
301   , frames(0)
302   , loc(0)
303   , m_selection(0)
304   , m_locationbar(0)
305   , m_menubar(0)
306   , m_personalbar(0)
307   , m_scrollbars(0)
308   , m_statusbar(0)
309   , m_toolbar(0)
310   , m_evt(0)
311 {
312   winq = new WindowQObject(this);
313   //kdDebug(6070) << "Window::Window this=" << this << " part=" << m_part << " " << m_part->name() << endl;
314 }
315
316 Window::~Window()
317 {
318   kdDebug(6070) << "Window::~Window this=" << this << " part=" << m_part << endl;
319   delete winq;
320 }
321
322 Window *Window::retrieveWindow(KHTMLPart *p)
323 {
324   Object obj = Object::dynamicCast( retrieve( p ) );
325 #ifndef NDEBUG
326   // obj should never be null, except when javascript has been disabled in that part.
327   if ( p && p->jScriptEnabled() )
328   {
329     assert( !obj.isNull() );
330 #ifndef QWS
331     assert( dynamic_cast<KJS::Window*>(obj.imp()) ); // type checking
332 #endif
333   }
334 #endif
335   if ( obj.isNull() ) // JS disabled
336     return 0;
337   return static_cast<KJS::Window*>(obj.imp());
338 }
339
340 Window *Window::retrieveActive(ExecState *exec)
341 {
342   ValueImp *imp = exec->dynamicInterpreter()->globalObject().imp();
343   assert( imp );
344 #ifndef QWS
345   assert( dynamic_cast<KJS::Window*>(imp) );
346 #endif
347   return static_cast<KJS::Window*>(imp);
348 }
349
350 Value Window::retrieve(KHTMLPart *p)
351 {
352   assert(p);
353   KJSProxy *proxy = KJSProxy::proxy( p );
354   if (proxy) {
355 #ifdef KJS_VERBOSE
356     kdDebug(6070) << "Window::retrieve part=" << p << " interpreter=" << proxy->interpreter() << " window=" << proxy->interpreter()->globalObject().imp() << endl;
357 #endif
358     return proxy->interpreter()->globalObject(); // the Global object is the "window"
359   } else
360     return Undefined(); // This can happen with JS disabled on the domain of that window
361 }
362
363 Location *Window::location() const
364 {
365   if (!loc)
366     const_cast<Window*>(this)->loc = new Location(m_part);
367   return loc;
368 }
369
370 Selection *Window::selection() const
371 {
372   if (!m_selection)
373     const_cast<Window*>(this)->m_selection = new Selection(m_part);
374   return m_selection;
375 }
376
377 BarInfo *Window::locationbar(ExecState *exec) const
378 {
379   if (!m_locationbar)
380     const_cast<Window*>(this)->m_locationbar = new BarInfo(exec, m_part, BarInfo::Locationbar);
381   return m_locationbar;
382 }
383
384 BarInfo *Window::menubar(ExecState *exec) const
385 {
386   if (!m_menubar)
387     const_cast<Window*>(this)->m_menubar = new BarInfo(exec, m_part, BarInfo::Menubar);
388   return m_menubar;
389 }
390
391 BarInfo *Window::personalbar(ExecState *exec) const
392 {
393   if (!m_personalbar)
394     const_cast<Window*>(this)->m_personalbar = new BarInfo(exec, m_part, BarInfo::Personalbar);
395   return m_personalbar;
396 }
397
398 BarInfo *Window::statusbar(ExecState *exec) const
399 {
400   if (!m_statusbar)
401     const_cast<Window*>(this)->m_statusbar = new BarInfo(exec, m_part, BarInfo::Statusbar);
402   return m_statusbar;
403 }
404
405 BarInfo *Window::toolbar(ExecState *exec) const
406 {
407   if (!m_toolbar)
408     const_cast<Window*>(this)->m_toolbar = new BarInfo(exec, m_part, BarInfo::Toolbar);
409   return m_toolbar;
410 }
411
412 BarInfo *Window::scrollbars(ExecState *exec) const
413 {
414   if (!m_scrollbars)
415     const_cast<Window*>(this)->m_scrollbars = new BarInfo(exec, m_part, BarInfo::Scrollbars);
416   return m_scrollbars;
417 }
418
419 // reference our special objects during garbage collection
420 void Window::mark()
421 {
422   ObjectImp::mark();
423   if (screen && !screen->marked())
424     screen->mark();
425   if (history && !history->marked())
426     history->mark();
427   if (frames && !frames->marked())
428     frames->mark();
429   //kdDebug(6070) << "Window::mark " << this << " marking loc=" << loc << endl;
430   if (loc && !loc->marked())
431     loc->mark();
432   if (m_selection && !m_selection->marked())
433     m_selection->mark();
434   if (m_locationbar && !m_locationbar->marked())
435     m_locationbar->mark();
436   if (m_menubar && !m_menubar->marked())
437     m_menubar->mark();
438   if (m_personalbar && !m_personalbar->marked())
439     m_personalbar->mark();
440   if (m_scrollbars && !m_scrollbars->marked())
441     m_scrollbars->mark();
442   if (m_statusbar && !m_statusbar->marked())
443     m_statusbar->mark();
444   if (m_toolbar && !m_toolbar->marked())
445     m_toolbar->mark();
446 }
447
448 bool Window::hasProperty(ExecState * /*exec*/, const Identifier &/*p*/) const
449 {
450   //fprintf( stderr, "Window::hasProperty: always saying true\n" );
451
452   // emulate IE behaviour: it doesn't throw exceptions when undeclared
453   // variables are used. Returning true here will lead to get() returning
454   // 'undefined' in those cases.
455   return true;
456 }
457
458 UString Window::toString(ExecState *) const
459 {
460   return "[object Window]";
461 }
462
463 Value Window::get(ExecState *exec, const Identifier &p) const
464 {
465 #ifdef KJS_VERBOSE
466   kdDebug(6070) << "Window("<<this<<")::get " << p.qstring() << endl;
467 #endif
468   if ( p == "closed" )
469     return Boolean(m_part.isNull());
470
471   // we don't want any operations on a closed window
472   if (m_part.isNull())
473     return Undefined();
474
475   // Look for overrides first
476   ValueImp * val = ObjectImp::getDirect(p);
477   if (val) {
478     //kdDebug(6070) << "Window::get found dynamic property '" << p.ascii() << "'" << endl;
479     if (isSafeScript(exec))
480       return Value(val);
481   }
482
483   const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
484   if (entry)
485   {
486     //kdDebug(6070) << "token: " << entry->value << endl;
487     switch( entry->value ) {
488     case Crypto:
489       return Undefined(); // ###
490     case DefaultStatus:
491       return String(UString(m_part->jsDefaultStatusBarText()));
492     case Status:
493       return String(UString(m_part->jsStatusBarText()));
494     case Document:
495       if (isSafeScript(exec))
496       {
497         if (m_part->document().isNull()) {
498 #if APPLE_CHANGES
499           KWQ(m_part)->createEmptyDocument();
500 #endif
501           kdDebug(6070) << "Document.write: adding <HTML><BODY> to create document" << endl;
502           m_part->begin();
503           m_part->write("<HTML><BODY>");
504           m_part->end();
505         }
506         Value val = getDOMNode(exec,m_part->document());
507         return val;
508       }
509       else
510         return Undefined();
511     case Node:
512       return getNodeConstructor(exec);
513     case Range:
514       return getRangeConstructor(exec);
515     case NodeFilter:
516       return getNodeFilterConstructor(exec);
517     case DOMException:
518       return getDOMExceptionConstructor(exec);
519     case CSSRule:
520       return getCSSRuleConstructor(exec);
521     case EventCtor:
522       return getEventConstructor(exec);
523     case Frames:
524       return Value(frames ? frames :
525                    (const_cast<Window*>(this)->frames = new FrameArray(exec,m_part)));
526     case _History:
527       return Value(history ? history :
528                    (const_cast<Window*>(this)->history = new History(exec,m_part)));
529
530     case Event:
531       if (m_evt)
532         return getDOMEvent(exec,*m_evt);
533       else {
534 #ifdef KJS_VERBOSE
535         kdWarning(6070) << "window(" << this << "," << m_part->name() << ").event, no event!" << endl;
536 #endif
537         return Undefined();
538       }
539     case InnerHeight:
540       if (!m_part->view())
541         return Undefined();
542       updateLayout();
543       return Number(m_part->view()->visibleHeight());
544     case InnerWidth:
545       if (!m_part->view())
546         return Undefined();
547       updateLayout();
548       return Number(m_part->view()->visibleWidth());
549     case Length:
550       return Number(m_part->frames().count());
551     case _Location:
552       return Value(location());
553     case Name:
554       return String(m_part->name());
555     case _Navigator:
556     case ClientInformation: {
557       // Store the navigator in the object so we get the same one each time.
558       Navigator *n = new Navigator(exec, m_part);
559       const_cast<Window *>(this)->putDirect("navigator", n, DontDelete|ReadOnly);
560       const_cast<Window *>(this)->putDirect("clientInformation", n, DontDelete|ReadOnly);
561       return Value(n);
562     }
563 #ifdef Q_WS_QWS
564     case _Konqueror:
565       return Value(new Konqueror(m_part));
566 #endif
567     case Locationbar:
568       return Value(locationbar(exec));
569     case Menubar:
570       return Value(menubar(exec));
571     case OffscreenBuffering:
572       return Boolean(true);
573     case Opener:
574       if (!m_part->opener())
575         return Null();    // ### a null Window might be better, but == null
576       else                // doesn't work yet
577         return retrieve(m_part->opener());
578     case OuterHeight:
579     case OuterWidth:
580     {
581       if (!m_part->view())
582         return Number(0);
583       KWin::Info inf = KWin::info(m_part->view()->topLevelWidget()->winId());
584       return Number(entry->value == OuterHeight ?
585                     inf.geometry.height() : inf.geometry.width());
586     }
587     case PageXOffset:
588       if (!m_part->view())
589         return Undefined();
590       updateLayout();
591       return Number(m_part->view()->contentsX());
592     case PageYOffset:
593       if (!m_part->view())
594         return Undefined();
595       updateLayout();
596       return Number(m_part->view()->contentsY());
597     case Parent:
598       return Value(retrieve(m_part->parentPart() ? m_part->parentPart() : (KHTMLPart*)m_part));
599     case Personalbar:
600       return Value(personalbar(exec));
601     case ScreenLeft:
602     case ScreenX: {
603       if (!m_part->view())
604         return Undefined();
605       QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
606       return Number(m_part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
607     }
608     case ScreenTop:
609     case ScreenY: {
610       if (!m_part->view())
611         return Undefined();
612       QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
613       return Number(m_part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
614     }
615     case ScrollX: {
616       if (!m_part->view())
617         return Undefined();
618       updateLayout();
619       return Number(m_part->view()->contentsX());
620     }
621     case ScrollY: {
622       if (!m_part->view())
623         return Undefined();
624       updateLayout();
625       return Number(m_part->view()->contentsY());
626     }
627     case Scrollbars:
628       return Value(scrollbars(exec));
629     case Statusbar:
630       return Value(statusbar(exec));
631     case Toolbar:
632       return Value(toolbar(exec));
633     case Self:
634     case _Window:
635       return Value(retrieve(m_part));
636     case Top: {
637       KHTMLPart *p = m_part;
638       while (p->parentPart())
639         p = p->parentPart();
640       return Value(retrieve(p));
641     }
642     case _Screen:
643       return Value(screen ? screen :
644                    (const_cast<Window*>(this)->screen = new Screen(exec)));
645     case Image:
646       return Value(new ImageConstructorImp(exec, m_part->document()));
647     case Option:
648       return Value(new OptionConstructorImp(exec, m_part->document()));
649     case XMLHttpRequest:
650       return Value(new XMLHttpRequestConstructorImp(exec, m_part->document()));
651     case XMLSerializer:
652       return Value(new XMLSerializerConstructorImp(exec));
653     case Alert:
654     case Confirm:
655     case Prompt:
656     case Open:
657 #if APPLE_CHANGES
658     case Print:
659 #endif
660     case Focus:
661     case Blur:
662     case Close:
663     case Scroll: // compatibility
664     case ScrollBy:
665     case ScrollTo:
666     case MoveBy:
667     case MoveTo:
668     case ResizeBy:
669     case ResizeTo:
670         return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
671     case CaptureEvents:
672     case ReleaseEvents:
673     case AddEventListener:
674     case RemoveEventListener:
675     case SetTimeout:
676     case ClearTimeout:
677     case SetInterval:
678     case ClearInterval:
679     case GetSelection:
680       if (isSafeScript(exec))
681         return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
682       else
683         return Undefined();
684     case Onabort:
685       if (isSafeScript(exec))
686         return getListener(exec,DOM::EventImpl::ABORT_EVENT);
687       else
688         return Undefined();
689     case Onblur:
690       if (isSafeScript(exec))
691         return getListener(exec,DOM::EventImpl::BLUR_EVENT);
692       else
693         return Undefined();
694     case Onchange:
695       if (isSafeScript(exec))
696         return getListener(exec,DOM::EventImpl::CHANGE_EVENT);
697       else
698         return Undefined();
699     case Onclick:
700       if (isSafeScript(exec))
701         return getListener(exec,DOM::EventImpl::KHTML_CLICK_EVENT);
702       else
703         return Undefined();
704     case Ondblclick:
705       if (isSafeScript(exec))
706         return getListener(exec,DOM::EventImpl::KHTML_DBLCLICK_EVENT);
707       else
708         return Undefined();
709     case Ondragdrop:
710       if (isSafeScript(exec))
711         return getListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT);
712       else
713         return Undefined();
714     case Onerror:
715       if (isSafeScript(exec))
716         return getListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT);
717       else
718         return Undefined();
719     case Onfocus:
720       if (isSafeScript(exec))
721         return getListener(exec,DOM::EventImpl::FOCUS_EVENT);
722       else
723         return Undefined();
724     case Onkeydown:
725       if (isSafeScript(exec))
726         return getListener(exec,DOM::EventImpl::KEYDOWN_EVENT);
727       else
728         return Undefined();
729     case Onkeypress:
730       if (isSafeScript(exec))
731         return getListener(exec,DOM::EventImpl::KEYPRESS_EVENT);
732       else
733         return Undefined();
734     case Onkeyup:
735       if (isSafeScript(exec))
736         return getListener(exec,DOM::EventImpl::KEYUP_EVENT);
737       else
738         return Undefined();
739     case Onload:
740       if (isSafeScript(exec))
741         return getListener(exec,DOM::EventImpl::LOAD_EVENT);
742       else
743         return Undefined();
744     case Onmousedown:
745       if (isSafeScript(exec))
746         return getListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT);
747       else
748         return Undefined();
749     case Onmousemove:
750       if (isSafeScript(exec))
751         return getListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT);
752       else
753         return Undefined();
754     case Onmouseout:
755       if (isSafeScript(exec))
756         return getListener(exec,DOM::EventImpl::MOUSEOUT_EVENT);
757       else
758         return Undefined();
759     case Onmouseover:
760       if (isSafeScript(exec))
761         return getListener(exec,DOM::EventImpl::MOUSEOVER_EVENT);
762       else
763         return Undefined();
764     case Onmouseup:
765       if (isSafeScript(exec))
766         return getListener(exec,DOM::EventImpl::MOUSEUP_EVENT);
767       else
768         return Undefined();
769     case Onmove:
770       if (isSafeScript(exec))
771         return getListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT);
772       else
773         return Undefined();
774     case Onreset:
775       if (isSafeScript(exec))
776         return getListener(exec,DOM::EventImpl::RESET_EVENT);
777       else
778         return Undefined();
779     case Onresize:
780       if (isSafeScript(exec))
781         return getListener(exec,DOM::EventImpl::RESIZE_EVENT);
782       else
783         return Undefined();
784     case Onscroll:
785         if (isSafeScript(exec))
786             return getListener(exec,DOM::EventImpl::SCROLL_EVENT);
787         else
788             return Undefined();
789 #if APPLE_CHANGES
790     case Onsearch:
791         if (isSafeScript(exec))
792             return getListener(exec,DOM::EventImpl::SEARCH_EVENT);
793         else
794             return Undefined();
795 #endif
796     case Onselect:
797       if (isSafeScript(exec))
798         return getListener(exec,DOM::EventImpl::SELECT_EVENT);
799       else
800         return Undefined();
801     case Onsubmit:
802       if (isSafeScript(exec))
803         return getListener(exec,DOM::EventImpl::SUBMIT_EVENT);
804       else
805         return Undefined();
806     case Onunload:
807       if (isSafeScript(exec))
808         return getListener(exec,DOM::EventImpl::UNLOAD_EVENT);
809       else
810         return Undefined();
811     }
812   }
813
814   KHTMLPart *kp = m_part->findFrame( p.qstring() );
815   if (kp)
816     return Value(retrieve(kp));
817
818   // allow window[1] or parent[1] etc. (#56983)
819   bool ok;
820   unsigned int i = p.toArrayIndex(&ok);
821   if (ok) {
822     QPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
823     unsigned int len = frames.count();
824     if (i < len) {
825       KParts::ReadOnlyPart* frame = frames.at(i);
826       if (frame && frame->inherits("KHTMLPart")) {
827         KHTMLPart *khtml = static_cast<KHTMLPart*>(frame);
828         return Window::retrieve(khtml);
829       }
830     }
831   }
832
833   // allow shortcuts like 'Image1' instead of document.images.Image1
834   if (isSafeScript(exec) &&
835       m_part->document().isHTMLDocument()) { // might be XML
836     DOM::HTMLCollection coll = m_part->htmlDocument().all();
837     DOM::HTMLElement element = coll.namedItem(p.string());
838     if (!element.isNull()) {
839       return getDOMNode(exec,element);
840     }
841   }
842
843   // This isn't necessarily a bug. Some code uses if(!window.blah) window.blah=1
844   // But it can also mean something isn't loaded or implemented, hence the WARNING to help grepping.
845 #ifdef KJS_VERBOSE
846   kdDebug(6070) << "WARNING: Window::get property not found: " << p.qstring() << endl;
847 #endif
848   return Undefined();
849 }
850
851 void Window::put(ExecState* exec, const Identifier &propertyName, const Value &value, int attr)
852 {
853   // Called by an internal KJS call (e.g. InterpreterImp's constructor) ?
854   // If yes, save time and jump directly to ObjectImp.
855   if ( (attr != None && attr != DontDelete)
856        // Same thing if we have a local override (e.g. "var location")
857        || ( ObjectImp::getDirect(propertyName) && isSafeScript(exec)) )
858   {
859     ObjectImp::put( exec, propertyName, value, attr );
860     return;
861   }
862
863   const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
864   if (entry)
865   {
866 #ifdef KJS_VERBOSE
867     kdDebug(6070) << "Window("<<this<<")::put " << propertyName.qstring() << endl;
868 #endif
869     switch( entry->value ) {
870     case Status: {
871       String s = value.toString(exec);
872       m_part->setJSStatusBarText(s.value().qstring());
873       return;
874     }
875     case DefaultStatus: {
876       String s = value.toString(exec);
877       m_part->setJSDefaultStatusBarText(s.value().qstring());
878       return;
879     }
880     case _Location: {
881       KHTMLPart* p = Window::retrieveActive(exec)->m_part;
882       if (p) {
883         QString dstUrl = p->htmlDocument().completeURL(value.toString(exec).string()).string();
884         if (dstUrl.find("javascript:", 0, false) || isSafeScript(exec))
885         {
886           bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
887 #if APPLE_CHANGES
888           // We want a new history item if this JS was called via a user gesture
889           m_part->scheduleRedirection(0, dstUrl, !userGesture, userGesture);
890 #else
891           m_part->scheduleRedirection(0,
892                                       dstUrl,
893                                       false /*don't lock history*/, userGesture);
894 #endif
895         }
896       }
897       return;
898     }
899     case Onabort:
900       if (isSafeScript(exec))
901         setListener(exec, DOM::EventImpl::ABORT_EVENT,value);
902       return;
903     case Onblur:
904       if (isSafeScript(exec))
905         setListener(exec, DOM::EventImpl::BLUR_EVENT,value);
906       return;
907     case Onchange:
908       if (isSafeScript(exec))
909         setListener(exec, DOM::EventImpl::CHANGE_EVENT,value);
910       return;
911     case Onclick:
912       if (isSafeScript(exec))
913         setListener(exec,DOM::EventImpl::KHTML_CLICK_EVENT,value);
914       return;
915     case Ondblclick:
916       if (isSafeScript(exec))
917         setListener(exec,DOM::EventImpl::KHTML_DBLCLICK_EVENT,value);
918       return;
919     case Ondragdrop:
920       if (isSafeScript(exec))
921         setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
922       return;
923     case Onerror:
924       if (isSafeScript(exec))
925         setListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT,value);
926       return;
927     case Onfocus:
928       if (isSafeScript(exec))
929         setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
930       return;
931     case Onkeydown:
932       if (isSafeScript(exec))
933         setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
934       return;
935     case Onkeypress:
936       if (isSafeScript(exec))
937         setListener(exec,DOM::EventImpl::KEYPRESS_EVENT,value);
938       return;
939     case Onkeyup:
940       if (isSafeScript(exec))
941         setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
942       return;
943     case Onload:
944       if (isSafeScript(exec))
945         setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
946       return;
947     case Onmousedown:
948       if (isSafeScript(exec))
949         setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
950       return;
951     case Onmousemove:
952       if (isSafeScript(exec))
953         setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
954       return;
955     case Onmouseout:
956       if (isSafeScript(exec))
957         setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
958       return;
959     case Onmouseover:
960       if (isSafeScript(exec))
961         setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
962       return;
963     case Onmouseup:
964       if (isSafeScript(exec))
965         setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
966       return;
967     case Onmove:
968       if (isSafeScript(exec))
969         setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
970       return;
971     case Onreset:
972       if (isSafeScript(exec))
973         setListener(exec,DOM::EventImpl::RESET_EVENT,value);
974       return;
975     case Onresize:
976       if (isSafeScript(exec))
977         setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
978       return;
979     case Onscroll:
980       if (isSafeScript(exec))
981         setListener(exec,DOM::EventImpl::SCROLL_EVENT,value);
982       return;
983 #if APPLE_CHANGES
984     case Onsearch:
985         if (isSafeScript(exec))
986             setListener(exec,DOM::EventImpl::SEARCH_EVENT,value);
987         return;
988 #endif
989     case Onselect:
990       if (isSafeScript(exec))
991         setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
992       return;
993     case Onsubmit:
994       if (isSafeScript(exec))
995         setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
996       return;
997     case Onunload:
998       if (isSafeScript(exec))
999         setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
1000       return;
1001     case Name:
1002       if (isSafeScript(exec))
1003 #if APPLE_CHANGES
1004         m_part->setName( value.toString(exec).qstring() );
1005 #else
1006         m_part->setName( value.toString(exec).qstring().local8Bit().data() );
1007 #endif
1008       return;
1009     default:
1010       break;
1011     }
1012   }
1013   if (isSafeScript(exec)) {
1014     //kdDebug(6070) << "Window("<<this<<")::put storing " << propertyName.qstring() << endl;
1015     ObjectImp::put(exec, propertyName, value, attr);
1016   }
1017 }
1018
1019 bool Window::toBoolean(ExecState *) const
1020 {
1021   return !m_part.isNull();
1022 }
1023
1024 int Window::installTimeout(const UString &handler, int t, bool singleShot)
1025 {
1026   return winq->installTimeout(handler, t, singleShot);
1027 }
1028
1029 int Window::installTimeout(const Value &function, List &args, int t, bool singleShot)
1030 {
1031   return winq->installTimeout(function, args, t, singleShot);
1032 }
1033
1034 void Window::clearTimeout(int timerId)
1035 {
1036   winq->clearTimeout(timerId);
1037 }
1038
1039 #if APPLE_CHANGES
1040 bool Window::hasTimeouts()
1041 {
1042     return winq->hasTimeouts();
1043 }
1044
1045 QMap<int, ScheduledAction*> *Window::pauseTimeouts(const void *key)
1046 {
1047     return winq->pauseTimeouts(key);
1048 }
1049
1050 void Window::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
1051 {
1052     return winq->resumeTimeouts(sa, key);
1053 }
1054 #endif
1055
1056 void Window::scheduleClose()
1057 {
1058   kdDebug(6070) << "Window::scheduleClose window.close() " << m_part << endl;
1059   Q_ASSERT(winq);
1060 #if APPLE_CHANGES
1061   KWQ(m_part)->scheduleClose();
1062 #else
1063   QTimer::singleShot( 0, winq, SLOT( timeoutClose() ) );
1064 #endif
1065 }
1066
1067 static bool shouldLoadAsEmptyDocument(const KURL &url)
1068 {
1069   return url.protocol().lower() == "about" || url.isEmpty();
1070 }
1071
1072 bool Window::isSafeScript(ExecState *exec) const
1073 {
1074   if (m_part.isNull()) { // part deleted ? can't grant access
1075     kdDebug(6070) << "Window::isSafeScript: accessing deleted part !" << endl;
1076     return false;
1077   }
1078   KHTMLPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->dynamicInterpreter() )->part();
1079   if (!activePart) {
1080     kdDebug(6070) << "Window::isSafeScript: current interpreter's part is 0L!" << endl;
1081     return false;
1082   }
1083   if ( activePart == m_part ) // Not calling from another frame, no problem.
1084     return true;
1085
1086   // JS may be attempting to access the "window" object, which should be valid,
1087   // even if the document hasn't been constructed yet.  If the document doesn't
1088   // exist yet allow JS to access the window object.
1089   if (!m_part->xmlDocImpl())
1090       return true;
1091
1092   DOM::DocumentImpl* thisDocument = m_part->xmlDocImpl();
1093   DOM::DocumentImpl* actDocument = activePart->xmlDocImpl();
1094
1095   if (!actDocument) {
1096     kdDebug(6070) << "Window::isSafeScript: active part has no document!" << endl;
1097     return false;
1098   }
1099
1100   DOM::DOMString actDomain = actDocument->domain();
1101   
1102   // Always allow local pages to execute any JS.
1103   if (actDomain.isNull())
1104     return true;
1105   
1106   DOM::DOMString thisDomain = thisDocument->domain();
1107
1108   // if this document is being initially loaded as empty by its parent
1109   // or opener, allow access from any document in the same domain as
1110   // the parent or opener.
1111   if (shouldLoadAsEmptyDocument(m_part->url())) {
1112     KHTMLPart *ancestorPart = m_part->opener() ? m_part->opener() : m_part->parentPart();
1113     while (ancestorPart && shouldLoadAsEmptyDocument(ancestorPart->url())) {
1114       ancestorPart = ancestorPart->parentPart();
1115     }
1116     
1117     if (ancestorPart)
1118       thisDomain = ancestorPart->docImpl()->domain();
1119   }
1120
1121   //kdDebug(6070) << "current domain:" << actDomain.string() << ", frame domain:" << thisDomain.string() << endl;
1122   if ( actDomain == thisDomain )
1123     return true;
1124
1125 #if APPLE_CHANGES
1126   if (Interpreter::shouldPrintExceptions()) {
1127       printf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n", 
1128              thisDocument->URL().latin1(), actDocument->URL().latin1());
1129       QString message;
1130       message.sprintf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n", 
1131                       thisDocument->URL().latin1(), actDocument->URL().latin1());
1132       KWQ(m_part)->addMessageToConsole(message, 1, QString()); //fixme: provide a real line number and sourceurl
1133   }
1134 #endif
1135   
1136   kdWarning(6070) << "Javascript: access denied for current frame '" << actDomain.string() << "' to frame '" << thisDomain.string() << "'" << endl;
1137   return false;
1138 }
1139
1140 void Window::setListener(ExecState *exec, int eventId, Value func)
1141 {
1142   if (!isSafeScript(exec))
1143     return;
1144   DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(m_part->htmlDocument().handle());
1145   if (!doc)
1146     return;
1147
1148   doc->setHTMLWindowEventListener(eventId,getJSEventListener(func,true));
1149 }
1150
1151 Value Window::getListener(ExecState *exec, int eventId) const
1152 {
1153   if (!isSafeScript(exec))
1154     return Undefined();
1155   DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(m_part->htmlDocument().handle());
1156   if (!doc)
1157     return Undefined();
1158
1159   DOM::EventListener *listener = doc->getHTMLWindowEventListener(eventId);
1160   if (listener && static_cast<JSEventListener*>(listener)->listenerObjImp())
1161     return static_cast<JSEventListener*>(listener)->listenerObj();
1162   else
1163     return Null();
1164 }
1165
1166
1167 JSEventListener *Window::getJSEventListener(const Value& val, bool html)
1168 {
1169   // This function is so hot that it's worth coding it directly with imps.
1170   if (val.type() != ObjectType)
1171     return 0;
1172   ObjectImp *listenerObject = static_cast<ObjectImp *>(val.imp());
1173
1174   JSEventListener *existingListener = jsEventListeners[listenerObject];
1175   if (existingListener)
1176     return existingListener;
1177
1178   // Note that the JSEventListener constructor adds it to our jsEventListeners list
1179   return new JSEventListener(Object(listenerObject), Object(this), html);
1180 }
1181
1182 JSLazyEventListener *Window::getJSLazyEventListener(const QString& code, bool html, int lineNumber)
1183 {
1184   return new JSLazyEventListener(code, Object(this), html, lineNumber);
1185 }
1186
1187 void Window::clear( ExecState *exec )
1188 {
1189   KJS::Interpreter::lock();
1190   kdDebug(6070) << "Window::clear " << this << endl;
1191   delete winq;
1192   winq = new WindowQObject(this);;
1193   // Get rid of everything, those user vars could hold references to DOM nodes
1194   deleteAllProperties( exec );
1195   // Really delete those properties, so that the DOM nodes get deref'ed
1196   KJS::Collector::collect();
1197   // Now recreate a working global object for the next URL that will use us
1198   KJS::Interpreter *interpreter = KJSProxy::proxy( m_part )->interpreter();
1199   interpreter->initGlobalObject();
1200   KJS::Interpreter::unlock();
1201 }
1202
1203 void Window::setCurrentEvent( DOM::Event *evt )
1204 {
1205   m_evt = evt;
1206   //kdDebug(6070) << "Window " << this << " (part=" << m_part << ")::setCurrentEvent m_evt=" << evt << endl;
1207 }
1208
1209 Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
1210 {
1211   if (!thisObj.inherits(&Window::info)) {
1212     Object err = Error::create(exec,TypeError);
1213     exec->setException(err);
1214     return err;
1215   }
1216   Window *window = static_cast<Window *>(thisObj.imp());
1217   QString str, str2;
1218
1219   KHTMLPart *part = window->m_part;
1220   if (!part)
1221     return Undefined();
1222
1223   KHTMLView *widget = part->view();
1224   Value v = args[0];
1225   UString s = v.toString(exec);
1226   str = s.qstring();
1227
1228   switch (id) {
1229   case Window::Alert:
1230     if (part && part->xmlDocImpl())
1231       part->xmlDocImpl()->updateRendering();
1232 #if APPLE_CHANGES
1233     KWQ(part)->runJavaScriptAlert(str);
1234 #else
1235     KMessageBox::error(widget, QStyleSheet::convertFromPlainText(str), "JavaScript");
1236 #endif
1237     return Undefined();
1238   case Window::Confirm:
1239     if (part && part->xmlDocImpl())
1240       part->xmlDocImpl()->updateRendering();
1241 #if APPLE_CHANGES
1242     return Boolean(KWQ(part)->runJavaScriptConfirm(str));
1243 #else
1244     return Boolean((KMessageBox::warningYesNo(widget, QStyleSheet::convertFromPlainText(str), "JavaScript",
1245                                                 i18n("OK"), i18n("Cancel")) == KMessageBox::Yes));
1246 #endif
1247   case Window::Prompt:
1248     if (part && part->xmlDocImpl())
1249       part->xmlDocImpl()->updateRendering();
1250     bool ok;
1251 #if APPLE_CHANGES
1252     ok = KWQ(part)->runJavaScriptPrompt(str, args.size() >= 2 ? args[1].toString(exec).qstring() : QString::null, str2);
1253 #else
1254     if (args.size() >= 2)
1255       str2 = QInputDialog::getText(i18n("Konqueror: Prompt"),
1256                                    QStyleSheet::convertFromPlainText(str),
1257                                    QLineEdit::Normal,
1258                                    args[1].toString(exec).qstring(), &ok);
1259     else
1260       str2 = QInputDialog::getText(i18n("Konqueror: Prompt"),
1261                                    QStyleSheet::convertFromPlainText(str),
1262                                    QLineEdit::Normal,
1263                                    QString::null, &ok);
1264 #endif
1265     if ( ok )
1266         return String(str2);
1267     else
1268         return Null();
1269   case Window::Open:
1270   {
1271     KConfig *config = new KConfig("konquerorrc");
1272     config->setGroup("Java/JavaScript Settings");
1273 #if !APPLE_CHANGES
1274     int policy = config->readUnsignedNumEntry( "WindowOpenPolicy", 0 ); // 0=allow, 1=ask, 2=deny, 3=smart
1275 #else    
1276     int policy = config->readUnsignedNumEntry( part->settings(), "WindowOpenPolicy", 0 ); // 0=allow, 1=ask, 2=deny, 3=smart
1277 #endif
1278     delete config;
1279     if ( policy == 1 ) {
1280 #if !APPLE_CHANGES
1281       if ( KMessageBox::questionYesNo(widget,
1282                                       i18n( "This site is trying to open up a new browser "
1283                                             "window using Javascript.\n"
1284                                             "Do you want to allow this?" ),
1285                                       i18n( "Confirmation: Javascript Popup" ) ) == KMessageBox::Yes )
1286 #endif
1287         policy = 0;
1288     } else if ( policy == 3 ) // smart
1289     {
1290       // window.open disabled unless from a key/mouse event
1291       if (static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture())
1292 #if !APPLE_CHANGES
1293         policy = 0;
1294 #else
1295       {
1296         policy = 0;
1297         LOG(PopupBlocking, "Allowed JavaScript window open of %s", args[0].toString(exec).qstring().ascii());
1298       } else {
1299         LOG(PopupBlocking, "Blocked JavaScript window open of %s", args[0].toString(exec).qstring().ascii());
1300       }
1301 #endif
1302     }
1303
1304     QString frameName = !args[1].isNull() && args[1].type() != UndefinedType ?
1305                         args[1].toString(exec).qstring()
1306                         : QString("_blank");
1307
1308     if ( policy != 0 && !(part->findFrame(frameName) || frameName == "_top" || frameName == "_parent" || frameName == "_self")) {
1309       return Undefined();
1310     } else {
1311       if (v.type() == UndefinedType)
1312         str = QString();
1313
1314       KParts::WindowArgs winargs;
1315
1316       // scan feature argument
1317       v = args[2];
1318       QString features;
1319       if (!v.isNull() && v.type() != UndefinedType && v.toString(exec).size() > 0) {
1320         features = v.toString(exec).qstring();
1321         // specifying window params means false defaults
1322         winargs.menuBarVisible = false;
1323         winargs.toolBarsVisible = false;
1324         winargs.statusBarVisible = false;
1325 #if APPLE_CHANGES
1326         winargs.scrollbarsVisible = true;
1327 #endif
1328         QStringList flist = QStringList::split(',', features);
1329         QStringList::ConstIterator it = flist.begin();
1330         while (it != flist.end()) {
1331           QString s = *it++;
1332           QString key, val;
1333           int pos = s.find('=');
1334           if (pos >= 0) {
1335             key = s.left(pos).stripWhiteSpace().lower();
1336             val = s.mid(pos + 1).stripWhiteSpace().lower();
1337             int spacePos = val.find(' ');
1338             if (spacePos != -1) {
1339               val = val.left(spacePos);
1340             }
1341
1342             int scnum = QApplication::desktop()->screenNumber(widget->topLevelWidget());
1343
1344             QRect screen = QApplication::desktop()->screenGeometry(scnum);
1345             if (key == "left" || key == "screenx") {
1346               bool ok;
1347               double d = val.toDouble(&ok);
1348               if (d != 0 || ok) {
1349                 d += screen.x();
1350                 if (d < screen.x() || d > screen.right())
1351                   d = screen.x(); // only safe choice until size is determined
1352                 winargs.x = (int)d;
1353 #if APPLE_CHANGES
1354                 winargs.xSet = true;
1355 #endif
1356               }
1357             } else if (key == "top" || key == "screeny") {
1358               bool ok;
1359               double d = val.toDouble(&ok);
1360               if (d != 0 || ok) {
1361                 d += screen.y();
1362                 if (d < screen.y() || d > screen.bottom())
1363                   d = screen.y(); // only safe choice until size is determined
1364                 winargs.y = (int)d;
1365 #if APPLE_CHANGES
1366                 winargs.ySet = true;
1367 #endif
1368               }
1369             } else if (key == "height") {
1370               bool ok;
1371               double d = val.toDouble(&ok);
1372               if (d != 0 || ok) {
1373 #if !APPLE_CHANGES
1374                 d += 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
1375 #endif
1376                 if (d > screen.height())  // should actually check workspace
1377                   d = screen.height();
1378                 if (d < 100)
1379                   d = 100;
1380                 winargs.height = (int)d;
1381 #if APPLE_CHANGES
1382                 winargs.heightSet = true;
1383 #endif
1384               }
1385             } else if (key == "width") {
1386               bool ok;
1387               double d = val.toDouble(&ok);
1388               if (d != 0 || ok) {
1389 #if !APPLE_CHANGES
1390                 d += 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
1391 #endif
1392                 if (d > screen.width())    // should actually check workspace
1393                   d = screen.width();
1394                 if (d < 100)
1395                   d = 100;
1396                 winargs.width = (int)d;
1397 #if APPLE_CHANGES
1398                 winargs.widthSet = true;
1399 #endif
1400               }
1401             } else {
1402               goto boolargs;
1403             }
1404             continue;
1405           } else {
1406             // leaving away the value gives true
1407             key = s.stripWhiteSpace().lower();
1408             val = "1";
1409           }
1410         boolargs:
1411           if (key == "menubar")
1412             winargs.menuBarVisible = (val == "1" || val == "yes");
1413           else if (key == "toolbar")
1414             winargs.toolBarsVisible = (val == "1" || val == "yes");
1415           else if (key == "location")  // ### missing in WindowArgs
1416             winargs.toolBarsVisible = (val == "1" || val == "yes");
1417           else if (key == "status" || key == "statusbar")
1418             winargs.statusBarVisible = (val == "1" || val == "yes");
1419           else if (key == "resizable")
1420             winargs.resizable = (val == "1" || val == "yes");
1421           else if (key == "fullscreen")
1422             winargs.fullscreen = (val == "1" || val == "yes");
1423 #if APPLE_CHANGES
1424           else if (key == "scrollbars")
1425             winargs.scrollbarsVisible = !(val == "0" || val == "no");
1426 #endif
1427         }
1428       }
1429
1430       // prepare arguments
1431       KURL url;
1432       if (!str.isEmpty())
1433       {
1434         KHTMLPart* p = Window::retrieveActive(exec)->m_part;
1435         if ( p )
1436           url = p->htmlDocument().completeURL(str).string();
1437       }
1438
1439       KParts::URLArgs uargs;
1440       uargs.frameName = frameName;
1441       if ( uargs.frameName == "_top" )
1442       {
1443           // FIXME: referrer?
1444           while ( part->parentPart() )
1445               part = part->parentPart();
1446           bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1447           part->scheduleRedirection(0, url.url(), false/*don't lock history*/, userGesture);
1448           return Window::retrieve(part);
1449       }
1450       if ( uargs.frameName == "_parent" )
1451       {
1452           // FIXME: referrer?
1453           if ( part->parentPart() )
1454               part = part->parentPart();
1455           bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1456           part->scheduleRedirection(0, url.url(), false/*don't lock history*/, userGesture);
1457           return Window::retrieve(part);
1458       }
1459       uargs.serviceType = "text/html";
1460
1461       // request window (new or existing if framename is set)
1462       KParts::ReadOnlyPart *newPart = 0L;
1463       emit part->browserExtension()->createNewWindow("", uargs,winargs,newPart);
1464       if (newPart && newPart->inherits("KHTMLPart")) {
1465         KHTMLPart *khtmlpart = static_cast<KHTMLPart*>(newPart);
1466         //qDebug("opener set to %p (this Window's part) in new Window %p  (this Window=%p)",part,win,window);
1467         khtmlpart->setOpener(part);
1468         khtmlpart->setOpenedByJS(true);
1469         if (khtmlpart->document().isNull()) {
1470           khtmlpart->begin();
1471           khtmlpart->write("<HTML><BODY>");
1472           khtmlpart->end();
1473
1474           if (part->xmlDocImpl()) {
1475             kdDebug(6070) << "Setting domain to " << part->xmlDocImpl()->domain().string() << endl;
1476             khtmlpart->xmlDocImpl()->setDomain( part->docImpl()->domain(), true );
1477           }
1478           
1479           if ( part->docImpl() )
1480             khtmlpart->docImpl()->setBaseURL( part->docImpl()->baseURL() );
1481         }
1482 #if APPLE_CHANGES
1483         if (!url.isEmpty()) {
1484           bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1485           // FIXME: Need to pass referrer here.
1486           khtmlpart->scheduleRedirection(0, url.url(), false, userGesture);
1487         }
1488 #else
1489         uargs.serviceType = QString::null;
1490         if (uargs.frameName == "_blank")
1491           uargs.frameName = QString::null;
1492         if (!url.isEmpty())
1493           // FIXME: need to pass referrer here
1494           emit khtmlpart->browserExtension()->openURLRequest(url,uargs);
1495 #endif
1496         return Window::retrieve(khtmlpart); // global object
1497       } else
1498         return Undefined();
1499     }
1500   }
1501 #if APPLE_CHANGES
1502   case Window::Print:
1503     part->print();
1504     return Undefined();
1505 #endif
1506   case Window::ScrollBy:
1507     window->updateLayout();
1508     if(args.size() >= 2 && widget)
1509       widget->scrollBy(args[0].toInt32(exec), args[1].toInt32(exec));
1510     return Undefined();
1511   case Window::Scroll:
1512   case Window::ScrollTo:
1513     window->updateLayout();
1514     if(args.size() >= 2 && widget)
1515       widget->setContentsPos(args[0].toInt32(exec), args[1].toInt32(exec));
1516     return Undefined();
1517   case Window::MoveBy:
1518     if(args.size() >= 2 && widget)
1519     {
1520       QWidget * tl = widget->topLevelWidget();
1521           QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1522       QPoint dest = tl->pos() + QPoint( args[0].toInt32(exec), args[1].toInt32(exec) );
1523       // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
1524       if ( dest.x() >= sg.x() && dest.y() >= sg.x() &&
1525            dest.x()+tl->width() <= sg.width()+sg.x() &&
1526            dest.y()+tl->height() <= sg.height()+sg.y() )
1527         tl->move( dest );
1528     }
1529     return Undefined();
1530   case Window::MoveTo:
1531     if(args.size() >= 2 && widget)
1532     {
1533       QWidget * tl = widget->topLevelWidget();
1534           QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1535       QPoint dest( args[0].toInt32(exec)+sg.x(), args[1].toInt32(exec)+sg.y() );
1536       // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
1537       if ( dest.x() >= sg.x() && dest.y() >= sg.y() &&
1538            dest.x()+tl->width() <= sg.width()+sg.x() &&
1539            dest.y()+tl->height() <= sg.height()+sg.y() )
1540         tl->move( dest );
1541     }
1542     return Undefined();
1543   case Window::ResizeBy:
1544     if(args.size() >= 2 && widget)
1545     {
1546       QWidget * tl = widget->topLevelWidget();
1547       QSize dest = tl->size() + QSize( args[0].toInt32(exec), args[1].toInt32(exec) );
1548           QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1549       // Security check: within desktop limits and bigger than 100x100 (per spec)
1550       if ( tl->x()+dest.width() <= sg.x()+sg.width() &&
1551            tl->y()+dest.height() <= sg.y()+sg.height() &&
1552            dest.width() >= 100 && dest.height() >= 100 )
1553       {
1554         // Take into account the window frame
1555         int deltaWidth = tl->frameGeometry().width() - tl->width();
1556         int deltaHeight = tl->frameGeometry().height() - tl->height();
1557         tl->resize( dest.width() - deltaWidth, dest.height() - deltaHeight );
1558       }
1559     }
1560     return Undefined();
1561   case Window::ResizeTo:
1562     if(args.size() >= 2 && widget)
1563     {
1564       QWidget * tl = widget->topLevelWidget();
1565       QSize dest = QSize( args[0].toInt32(exec), args[1].toInt32(exec) );
1566           QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1567       // Security check: within desktop limits and bigger than 100x100 (per spec)
1568       if ( tl->x()+dest.width() <= sg.x()+sg.width() &&
1569            tl->y()+dest.height() <= sg.y()+sg.height() &&
1570            dest.width() >= 100 && dest.height() >= 100 )
1571       {
1572         // Take into account the window frame
1573         int deltaWidth = tl->frameGeometry().width() - tl->width();
1574         int deltaHeight = tl->frameGeometry().height() - tl->height();
1575         tl->resize( dest.width() - deltaWidth, dest.height() - deltaHeight );
1576       }
1577     }
1578     return Undefined();
1579   case Window::SetTimeout:
1580     if (!window->isSafeScript(exec))
1581         return Undefined();
1582     if (args.size() >= 2 && v.isA(StringType)) {
1583       int i = args[1].toInt32(exec);
1584       int r = (const_cast<Window*>(window))->installTimeout(s, i, true /*single shot*/);
1585       return Number(r);
1586     }
1587     else if (args.size() >= 2 && v.isA(ObjectType) && Object::dynamicCast(v).implementsCall()) {
1588       Value func = args[0];
1589       int i = args[1].toInt32(exec);
1590
1591       // All arguments after the second should go to the function
1592       // FIXME: could be more efficient
1593       List funcArgs = args.copyTail().copyTail();
1594
1595       int r = (const_cast<Window*>(window))->installTimeout(func, funcArgs, i, true /*single shot*/);
1596       return Number(r);
1597     }
1598     else
1599       return Undefined();
1600   case Window::SetInterval:
1601     if (!window->isSafeScript(exec))
1602         return Undefined();
1603     if (args.size() >= 2 && v.isA(StringType)) {
1604       int i = args[1].toInt32(exec);
1605       int r = (const_cast<Window*>(window))->installTimeout(s, i, false);
1606       return Number(r);
1607     }
1608     else if (args.size() >= 2 && !Object::dynamicCast(v).isNull() &&
1609              Object::dynamicCast(v).implementsCall()) {
1610       Value func = args[0];
1611       int i = args[1].toInt32(exec);
1612
1613       // All arguments after the second should go to the function
1614       // FIXME: could be more efficient
1615       List funcArgs = args.copyTail().copyTail();
1616
1617       int r = (const_cast<Window*>(window))->installTimeout(func, funcArgs, i, false);
1618       return Number(r);
1619     }
1620     else
1621       return Undefined();
1622   case Window::ClearTimeout:
1623   case Window::ClearInterval:
1624     if (!window->isSafeScript(exec))
1625         return Undefined();
1626     (const_cast<Window*>(window))->clearTimeout(v.toInt32(exec));
1627     return Undefined();
1628   case Window::Focus:
1629     if (widget)
1630       widget->setActiveWindow();
1631     return Undefined();
1632   case Window::GetSelection:
1633     if (!window->isSafeScript(exec))
1634         return Undefined();
1635     return Value(window->selection());
1636   case Window::Blur:
1637 #if APPLE_CHANGES
1638     KWQ(part)->unfocusWindow();
1639 #else
1640     // TODO
1641 #endif
1642     return Undefined();
1643   case Window::Close:
1644     /* From http://developer.netscape.com/docs/manuals/js/client/jsref/window.htm :
1645        The close method closes only windows opened by JavaScript using the open method.
1646        If you attempt to close any other window, a confirm is generated, which
1647        lets the user choose whether the window closes.
1648        This is a security feature to prevent "mail bombs" containing self.close().
1649        However, if the window has only one document (the current one) in its
1650        session history, the close is allowed without any confirm. This is a
1651        special case for one-off windows that need to open other windows and
1652        then dispose of themselves.
1653     */
1654     if (!part->openedByJS())
1655     {
1656       // To conform to the SPEC, we only ask if the window
1657       // has more than one entry in the history (NS does that too).
1658       History history(exec,part);
1659       if ( history.get( exec, lengthPropertyName ).toInt32(exec) <= 1
1660 #if APPLE_CHANGES
1661            // FIXME: How are we going to handle this?
1662 #else
1663            || KMessageBox::questionYesNo( window->part()->view(), i18n("Close window?"), i18n("Confirmation Required") ) == KMessageBox::Yes
1664 #endif
1665            )
1666         (const_cast<Window*>(window))->scheduleClose();
1667     }
1668     else
1669     {
1670       (const_cast<Window*>(window))->scheduleClose();
1671     }
1672     return Undefined();
1673   case Window::CaptureEvents:
1674   case Window::ReleaseEvents:
1675         // If anyone implements these, they need the safescript security check.
1676         if (!window->isSafeScript(exec))
1677             return Undefined();
1678
1679     // Do nothing for now. These are NS-specific legacy calls.
1680     break;
1681   case Window::AddEventListener: {
1682         if (!window->isSafeScript(exec))
1683             return Undefined();
1684         
1685         JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
1686         if (listener) {
1687             DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
1688             docimpl->addWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
1689         }
1690         return Undefined();
1691     }
1692   case Window::RemoveEventListener: {
1693         if (!window->isSafeScript(exec))
1694             return Undefined();
1695         JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
1696         if (listener) {
1697             DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
1698             docimpl->removeWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
1699         }
1700         return Undefined();
1701     }
1702
1703   }
1704   return Undefined();
1705 }
1706
1707 void Window::updateLayout() const
1708 {
1709   DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(m_part->document().handle());
1710   if (docimpl) {
1711     docimpl->updateLayout();
1712   }
1713 }
1714
1715
1716 ////////////////////// ScheduledAction ////////////////////////
1717
1718 ScheduledAction::ScheduledAction(Object _func, List _args, bool _singleShot)
1719 {
1720   //kdDebug(6070) << "ScheduledAction::ScheduledAction(isFunction) " << this << endl;
1721   func = _func;
1722   args = _args;
1723   isFunction = true;
1724   singleShot = _singleShot;
1725 }
1726
1727 ScheduledAction::ScheduledAction(const QString &_code, bool _singleShot)
1728 {
1729   //kdDebug(6070) << "ScheduledAction::ScheduledAction(!isFunction) " << this << endl;
1730   //func = 0;
1731   //args = 0;
1732   code = _code;
1733   isFunction = false;
1734   singleShot = _singleShot;
1735 }
1736
1737 void ScheduledAction::execute(Window *window)
1738 {
1739   ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(KJSProxy::proxy(window->m_part)->interpreter());
1740
1741   interpreter->setProcessingTimerCallback(true);
1742
1743   //kdDebug(6070) << "ScheduledAction::execute " << this << endl;
1744   if (isFunction) {
1745     if (func.implementsCall()) {
1746       // #### check this
1747       Q_ASSERT( window->m_part );
1748       if ( window->m_part )
1749       {
1750         KJS::Interpreter *interpreter = KJSProxy::proxy( window->m_part )->interpreter();
1751         ExecState *exec = interpreter->globalExec();
1752         Q_ASSERT( window == interpreter->globalObject().imp() );
1753         Object obj( window );
1754         Interpreter::lock();
1755         func.call(exec,obj,args); // note that call() creates its own execution state for the func call
1756         Interpreter::unlock();
1757         if ( exec->hadException() ) {
1758 #if APPLE_CHANGES
1759           Interpreter::lock();
1760           char *message = exec->exception().toObject(exec).get(exec, messagePropertyName).toString(exec).ascii();
1761           int lineNumber =  exec->exception().toObject(exec).get(exec, "line").toInt32(exec);
1762           Interpreter::unlock();
1763           if (Interpreter::shouldPrintExceptions()) {
1764             printf("(timer):%s\n", message);
1765           }
1766           KWQ(window->m_part)->addMessageToConsole(message, lineNumber, QString());
1767 #endif
1768           exec->clearException();
1769         }
1770       }
1771     }
1772   }
1773   else {
1774     window->m_part->executeScript(code);
1775   }
1776
1777   // Update our document's rendering following the execution of the timeout callback.
1778   DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(window->m_part->document().handle());
1779   doc->updateRendering();
1780   
1781   interpreter->setProcessingTimerCallback(false);
1782 }
1783
1784 ScheduledAction::~ScheduledAction()
1785 {
1786   //kdDebug(6070) << "ScheduledAction::~ScheduledAction " << this << endl;
1787 }
1788
1789 ////////////////////// WindowQObject ////////////////////////
1790
1791 WindowQObject::WindowQObject(Window *w)
1792   : parent(w)
1793 {
1794   //kdDebug(6070) << "WindowQObject::WindowQObject " << this << endl;
1795   part = parent->m_part;
1796   connect( parent->m_part, SIGNAL( destroyed() ),
1797            this, SLOT( parentDestroyed() ) );
1798 }
1799
1800 WindowQObject::~WindowQObject()
1801 {
1802   //kdDebug(6070) << "WindowQObject::~WindowQObject " << this << endl;
1803   parentDestroyed(); // reuse same code
1804 }
1805
1806 void WindowQObject::parentDestroyed()
1807 {
1808   //kdDebug(6070) << "WindowQObject::parentDestroyed " << this << " we have " << scheduledActions.count() << " actions in the map" << endl;
1809   killTimers();
1810   QMapIterator<int,ScheduledAction*> it;
1811   for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
1812     ScheduledAction *action = *it;
1813     //kdDebug(6070) << "WindowQObject::parentDestroyed deleting action " << action << endl;
1814     delete action;
1815   }
1816   scheduledActions.clear();
1817 }
1818
1819 int WindowQObject::installTimeout(const UString &handler, int t, bool singleShot)
1820 {
1821   //kdDebug(6070) << "WindowQObject::installTimeout " << this << " " << handler.ascii() << endl;
1822   int id = startTimer(t);
1823   ScheduledAction *action = new ScheduledAction(handler.qstring(),singleShot);
1824   scheduledActions.insert(id, action);
1825   //kdDebug(6070) << this << " got id=" << id << " action=" << action << " - now having " << scheduledActions.count() << " actions"<<endl;
1826   return id;
1827 }
1828
1829 int WindowQObject::installTimeout(const Value &func, List args, int t, bool singleShot)
1830 {
1831   Object objFunc = Object::dynamicCast( func );
1832   int id = startTimer(t);
1833   scheduledActions.insert(id, new ScheduledAction(objFunc,args,singleShot));
1834   return id;
1835 }
1836
1837 QMap<int, ScheduledAction*> *WindowQObject::pauseTimeouts(const void *key)
1838 {
1839     QMapIterator<int,ScheduledAction*> it;
1840
1841     QMap<int, KJS::ScheduledAction*>*pausedActions = new QMap<int, KJS::ScheduledAction*>;
1842     for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
1843         int timerId = it.key();
1844         pauseTimer (timerId, key);
1845         pausedActions->insert(timerId, it.data());
1846     }
1847     scheduledActions.clear();
1848     return pausedActions;
1849 }
1850
1851 void WindowQObject::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
1852 {
1853     QMapIterator<int,ScheduledAction*> it;
1854     for (it = sa->begin(); it != sa->end(); ++it) {
1855         int timerId = it.key();
1856         scheduledActions.insert(timerId, it.data());
1857     }
1858     sa->clear();
1859     resumeTimers (key, this);
1860 }
1861
1862 void WindowQObject::clearTimeout(int timerId, bool delAction)
1863 {
1864   //kdDebug(6070) << "WindowQObject::clearTimeout " << this << " timerId=" << timerId << " delAction=" << delAction << endl;
1865   killTimer(timerId);
1866   if (delAction) {
1867     QMapIterator<int,ScheduledAction*> it = scheduledActions.find(timerId);
1868     if (it != scheduledActions.end()) {
1869       ScheduledAction *action = *it;
1870       scheduledActions.remove(it);
1871       delete action;
1872     }
1873   }
1874 }
1875
1876 void WindowQObject::timerEvent(QTimerEvent *e)
1877 {
1878   QMapIterator<int,ScheduledAction*> it = scheduledActions.find(e->timerId());
1879   if (it != scheduledActions.end()) {
1880     ScheduledAction *action = *it;
1881     bool singleShot = action->singleShot;
1882     //kdDebug(6070) << "WindowQObject::timerEvent " << this << " action=" << action << " singleShot:" << singleShot << endl;
1883
1884     // remove single shots installed by setTimeout()
1885     if (singleShot)
1886     {
1887       clearTimeout(e->timerId(),false);
1888       scheduledActions.remove(it);
1889     }
1890         
1891     if (!parent->part().isNull())
1892       action->execute(parent);
1893
1894     // It is important to test singleShot and not action->singleShot here - the
1895     // action could have been deleted already if not single shot and if the
1896     // JS code called by execute() calls clearTimeout().
1897     if (singleShot)
1898       delete action;
1899   } else
1900     kdWarning(6070) << "WindowQObject::timerEvent this=" << this << " timer " << e->timerId()
1901                     << " not found (" << scheduledActions.count() << " actions in map)" << endl;
1902 }
1903
1904 void WindowQObject::timeoutClose()
1905 {
1906   if (!parent->part().isNull())
1907   {
1908     //kdDebug(6070) << "WindowQObject::timeoutClose -> closing window" << endl;
1909     delete parent->m_part;
1910   }
1911 }
1912
1913 #if APPLE_CHANGES
1914 bool WindowQObject::hasTimeouts()
1915 {
1916     return scheduledActions.count();
1917 }
1918 #endif
1919
1920 Value FrameArray::get(ExecState *exec, const Identifier &p) const
1921 {
1922 #ifdef KJS_VERBOSE
1923   kdDebug(6070) << "FrameArray::get " << p.qstring() << " part=" << (void*)part << endl;
1924 #endif
1925   if (part.isNull())
1926     return Undefined();
1927
1928   QPtrList<KParts::ReadOnlyPart> frames = part->frames();
1929   unsigned int len = frames.count();
1930   if (p == lengthPropertyName)
1931     return Number(len);
1932   else if (p== "location") // non-standard property, but works in NS and IE
1933   {
1934     Object obj = Object::dynamicCast( Window::retrieve( part ) );
1935     if ( !obj.isNull() )
1936       return obj.get( exec, "location" );
1937     return Undefined();
1938   }
1939
1940   // check for the name or number
1941   KParts::ReadOnlyPart *frame = part->findFrame(p.qstring());
1942   if (!frame) {
1943     bool ok;
1944     unsigned int i = p.toArrayIndex(&ok);
1945     if (ok && i < len)
1946       frame = frames.at(i);
1947   }
1948
1949   // we are potentially fetching a reference to a another Window object here.
1950   // i.e. we may be accessing objects from another interpreter instance.
1951   // Therefore we have to be a bit careful with memory managment.
1952   if (frame && frame->inherits("KHTMLPart")) {
1953     KHTMLPart *khtml = static_cast<KHTMLPart*>(frame);
1954     return Window::retrieve(khtml);
1955   }
1956
1957   return ObjectImp::get(exec, p);
1958 }
1959
1960 UString FrameArray::toString(ExecState *) const
1961 {
1962   return "[object FrameArray]";
1963 }
1964
1965 ////////////////////// Location Object ////////////////////////
1966
1967 const ClassInfo Location::info = { "Location", 0, 0, 0 };
1968 /*
1969 @begin LocationTable 11
1970   hash          Location::Hash          DontDelete
1971   host          Location::Host          DontDelete
1972   hostname      Location::Hostname      DontDelete
1973   href          Location::Href          DontDelete
1974   pathname      Location::Pathname      DontDelete
1975   port          Location::Port          DontDelete
1976   protocol      Location::Protocol      DontDelete
1977   search        Location::Search        DontDelete
1978   [[==]]        Location::EqualEqual    DontDelete|ReadOnly
1979   toString      Location::ToString      DontDelete|Function 0
1980   replace       Location::Replace       DontDelete|Function 1
1981   reload        Location::Reload        DontDelete|Function 0
1982 @end
1983 */
1984 IMPLEMENT_PROTOFUNC(LocationFunc)
1985 Location::Location(KHTMLPart *p) : m_part(p)
1986 {
1987   //kdDebug(6070) << "Location::Location " << this << " m_part=" << (void*)m_part << endl;
1988 }
1989
1990 Location::~Location()
1991 {
1992   //kdDebug(6070) << "Location::~Location " << this << " m_part=" << (void*)m_part << endl;
1993 }
1994
1995 Value Location::get(ExecState *exec, const Identifier &p) const
1996 {
1997 #ifdef KJS_VERBOSE
1998   kdDebug(6070) << "Location::get " << p.qstring() << " m_part=" << (void*)m_part << endl;
1999 #endif
2000
2001   if (m_part.isNull())
2002     return Undefined();
2003   
2004   const Window* window = Window::retrieveWindow(m_part);
2005   if (!window || !window->isSafeScript(exec))
2006       return Undefined();
2007
2008   KURL url = m_part->url();
2009   const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
2010   if (entry)
2011     switch (entry->value) {
2012     case Hash:
2013       return String( url.ref().isNull() ? QString("") : "#" + url.ref() );
2014     case Host: {
2015       UString str = url.host();
2016       if (url.port())
2017         str += ":" + QString::number((int)url.port());
2018       return String(str);
2019       // Note: this is the IE spec. The NS spec swaps the two, it says
2020       // "The hostname property is the concatenation of the host and port properties, separated by a colon."
2021       // Bleh.
2022     }
2023     case Hostname:
2024       return String( url.host() );
2025     case Href:
2026       if (!url.hasPath())
2027         return String( url.prettyURL()+"/" );
2028       else
2029         return String( url.prettyURL() );
2030     case Pathname:
2031       return String( url.path().isEmpty() ? QString("/") : url.path() );
2032     case Port:
2033       return String( url.port() ? QString::number((int)url.port()) : QString::fromLatin1("") );
2034     case Protocol:
2035       return String( url.protocol()+":" );
2036     case Search:
2037       return String( url.query() );
2038     case EqualEqual: // [[==]]
2039       return String(toString(exec));
2040     case ToString:
2041       return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2042     }
2043   // Look for overrides
2044   ValueImp * val = ObjectImp::getDirect(p);
2045   if (val)
2046     return Value(val);
2047   if (entry)
2048     switch (entry->value) {
2049     case Replace:
2050       return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2051     case Reload:
2052       return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2053     }
2054
2055   return Undefined();
2056 }
2057
2058 void Location::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
2059 {
2060 #ifdef KJS_VERBOSE
2061   kdDebug(6070) << "Location::put " << p.qstring() << " m_part=" << (void*)m_part << endl;
2062 #endif
2063   if (m_part.isNull())
2064     return;
2065
2066   QString str = v.toString(exec).qstring();
2067   KURL url = m_part->url();
2068   const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
2069   if (entry)
2070     switch (entry->value) {
2071     case Href: {
2072       KHTMLPart* p = Window::retrieveActive(exec)->part();
2073       if ( p )
2074         url = p->htmlDocument().completeURL( str ).string();
2075       else
2076         url = str;
2077       break;
2078     }
2079     case Hash:
2080       url.setRef(str);
2081       break;
2082     case Host: {
2083       QString host = str.left(str.find(":"));
2084       QString port = str.mid(str.find(":")+1);
2085       url.setHost(host);
2086       url.setPort(port.toUInt());
2087       break;
2088     }
2089     case Hostname:
2090       url.setHost(str);
2091       break;
2092     case Pathname:
2093       url.setPath(str);
2094       break;
2095     case Port:
2096       url.setPort(str.toUInt());
2097       break;
2098     case Protocol:
2099       url.setProtocol(str);
2100       break;
2101     case Search:
2102       url.setQuery(str);
2103       break;
2104     }
2105   else {
2106     ObjectImp::put(exec, p, v, attr);
2107     return;
2108   }
2109   bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2110 #if APPLE_CHANGES
2111   // We want a new history item if this JS was called via a user gesture
2112   m_part->scheduleRedirection(0, url.url(), !userGesture, userGesture);
2113 #else
2114   m_part->scheduleRedirection(0, url.url(), false /*don't lock history*/, userGesture);
2115 #endif
2116 }
2117
2118 Value Location::toPrimitive(ExecState *exec, Type) const
2119 {
2120   return String(toString(exec));
2121 }
2122
2123 UString Location::toString(ExecState *) const
2124 {
2125   if (!m_part->url().hasPath())
2126     return m_part->url().prettyURL()+"/";
2127   else
2128     return m_part->url().prettyURL();
2129 }
2130
2131 Value LocationFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
2132 {
2133   if (!thisObj.inherits(&Location::info)) {
2134     Object err = Error::create(exec,TypeError);
2135     exec->setException(err);
2136     return err;
2137   }
2138   Location *location = static_cast<Location *>(thisObj.imp());
2139   KHTMLPart *part = location->part();
2140   if (part) {
2141       
2142     Window* window = Window::retrieveWindow(part);
2143     if (!window->isSafeScript(exec) && id != Location::Replace)
2144         return Undefined();
2145       
2146     switch (id) {
2147     case Location::Replace:
2148     {
2149       QString str = args[0].toString(exec).qstring();
2150       KHTMLPart* p = Window::retrieveActive(exec)->part();
2151       if ( p ) {
2152         bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2153         part->scheduleRedirection(0, p->htmlDocument().completeURL(str).string(), true /*lock history*/, userGesture);
2154       }
2155       break;
2156     }
2157     case Location::Reload:
2158     {
2159       bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2160       part->scheduleRedirection(0, part->url().url(), true/*lock history*/, userGesture);
2161       break;
2162     }
2163     case Location::ToString:
2164       return String(location->toString(exec));
2165     }
2166   } else
2167     kdDebug(6070) << "LocationFunc::tryExecute - no part!" << endl;
2168   return Undefined();
2169 }
2170
2171 ////////////////////// Selection Object ////////////////////////
2172
2173 const ClassInfo Selection::info = { "Selection", 0, 0, 0 };
2174 /*
2175 @begin SelectionTable 19
2176   anchorNode                Selection::AnchorNode                        DontDelete|ReadOnly
2177   anchorOffset              Selection::AnchorOffset                  DontDelete|ReadOnly
2178   focusNode                 Selection::FocusNode                         DontDelete|ReadOnly
2179   focusOffset               Selection::FocusOffset                       DontDelete|ReadOnly
2180   baseNode                  Selection::AnchorNode                        DontDelete|ReadOnly
2181   baseOffset                Selection::AnchorOffset              DontDelete|ReadOnly
2182   extentNode                Selection::FocusNode                 DontDelete|ReadOnly
2183   extentOffset              Selection::FocusOffset                       DontDelete|ReadOnly
2184   isCollapsed               Selection::IsCollapsed                       DontDelete|ReadOnly
2185   type                      Selection::_Type                     DontDelete|ReadOnly
2186   [[==]]                        Selection::EqualEqual                DontDelete|ReadOnly
2187   toString                  Selection::ToString                  DontDelete|Function 0
2188   collapse                  Selection::Collapse                  DontDelete|Function 2
2189   collapseToEnd             Selection::CollapseToEnd             DontDelete|Function 0
2190   collapseToStart           Selection::CollapseToStart           DontDelete|Function 0
2191   empty                     Selection::Empty                     DontDelete|Function 0
2192   setBaseAndExtent          Selection::SetBaseAndExtent          DontDelete|Function 4
2193   setPosition               Selection::SetPosition               DontDelete|Function 2
2194   modify                    Selection::Modify                    DontDelete|Function 3
2195 @end
2196 */
2197 IMPLEMENT_PROTOFUNC(SelectionFunc)
2198 Selection::Selection(KHTMLPart *p) : m_part(p)
2199 {
2200   //kdDebug(6070) << "Selection::Selection " << this << " m_part=" << (void*)m_part << endl;
2201 }
2202
2203 Selection::~Selection()
2204 {
2205   //kdDebug(6070) << "Selection::~Selection " << this << " m_part=" << (void*)m_part << endl;
2206 }
2207
2208 Value Selection::get(ExecState *exec, const Identifier &p) const
2209 {
2210 #ifdef KJS_VERBOSE
2211   kdDebug(6070) << "Selection::get " << p.qstring() << " m_part=" << (void*)m_part << endl;
2212 #endif
2213
2214   if (m_part.isNull())
2215     return Undefined();
2216   
2217   const Window* window = Window::retrieveWindow(m_part);
2218   if (!window || !window->isSafeScript(exec))
2219       return Undefined();
2220
2221   DocumentImpl *docimpl = m_part->xmlDocImpl();
2222   if (docimpl)
2223     docimpl->updateLayout();
2224
2225   KURL url = m_part->url();
2226   const HashEntry *entry = Lookup::findEntry(&SelectionTable, p);
2227   if (entry)
2228     switch (entry->value) {
2229         case AnchorNode:
2230         case BaseNode:
2231             return getDOMNode(exec, Node(m_part->selection().base().node()));
2232         case AnchorOffset:
2233         case BaseOffset:
2234             return Number(m_part->selection().base().offset());
2235         case FocusNode:
2236         case ExtentNode:
2237             return getDOMNode(exec, Node(m_part->selection().extent().node()));
2238         case FocusOffset:
2239         case ExtentOffset:
2240             return Number(m_part->selection().extent().offset());
2241         case IsCollapsed:
2242             return Boolean(m_part->selection().state() == DOM::Selection::CARET);
2243         case _Type: {
2244             switch (m_part->selection().state()) {
2245                 case DOM::Selection::NONE:
2246                     return String("None");
2247                 case DOM::Selection::CARET:
2248                     return String("Caret");
2249                 case DOM::Selection::RANGE:
2250                     return String("Range");
2251             }
2252         }
2253         case EqualEqual:
2254             return String(toString(exec));
2255         case ToString:
2256           return lookupOrCreateFunction<SelectionFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2257     }
2258     // Look for overrides
2259     ValueImp * val = ObjectImp::getDirect(p);
2260     if (val)
2261         return Value(val);
2262     if (entry)
2263         switch (entry->value) {
2264             case Collapse:
2265             case CollapseToEnd:
2266             case CollapseToStart:
2267             case Empty:
2268             case SetBaseAndExtent:
2269             case SetPosition:
2270             case Modify:
2271                 return lookupOrCreateFunction<SelectionFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2272         }
2273
2274     return Undefined();
2275 }
2276
2277 void Selection::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
2278 {
2279 }
2280
2281 Value Selection::toPrimitive(ExecState *exec, Type) const
2282 {
2283   return String(toString(exec));
2284 }
2285
2286 UString Selection::toString(ExecState *) const
2287 {
2288     if (m_part->selection().state() != DOM::Selection::RANGE)
2289         return UString("");
2290     return UString(m_part->selection().toRange().toString());
2291 }
2292
2293 Value SelectionFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
2294 {
2295     if (!thisObj.inherits(&Selection::info)) {
2296         Object err = Error::create(exec,TypeError);
2297         exec->setException(err);
2298         return err;
2299     }
2300     Selection *selection = static_cast<Selection *>(thisObj.imp());
2301     KHTMLPart *part = selection->part();
2302     if (part) {
2303         DocumentImpl *docimpl = part->xmlDocImpl();
2304         if (docimpl)
2305             docimpl->updateLayout();
2306             
2307         switch (id) {
2308             case Selection::Collapse:
2309                 TypingCommand::closeTyping(part->lastEditCommand());
2310                 part->setSelection(DOM::Selection(Position(KJS::toNode(args[0]).handle(), args[1].toInt32(exec))));
2311                 break;
2312             case Selection::CollapseToEnd:
2313                 TypingCommand::closeTyping(part->lastEditCommand());
2314                 part->setSelection(DOM::Selection(part->selection().end()));
2315                 break;
2316             case Selection::CollapseToStart:
2317                 TypingCommand::closeTyping(part->lastEditCommand());
2318                 part->setSelection(DOM::Selection(part->selection().start()));
2319                 break;
2320             case Selection::Empty:
2321                 TypingCommand::closeTyping(part->lastEditCommand());
2322                 part->clearSelection();
2323                 break;
2324             case Selection::SetBaseAndExtent: {
2325                 TypingCommand::closeTyping(part->lastEditCommand());
2326                 Position base(KJS::toNode(args[0]).handle(), args[1].toInt32(exec));
2327                 Position extent(KJS::toNode(args[2]).handle(), args[3].toInt32(exec));
2328                 part->setSelection(DOM::Selection(base, extent));
2329                 break;
2330             }
2331             case Selection::SetPosition:
2332                 TypingCommand::closeTyping(part->lastEditCommand());
2333                 part->setSelection(DOM::Selection(Position(KJS::toNode(args[0]).handle(), args[1].toInt32(exec))));
2334                 break;
2335             case Selection::Modify: {
2336                 TypingCommand::closeTyping(part->lastEditCommand());
2337                 DOM::Selection s(part->selection());
2338                 DOM::Selection::EAlter alter = DOM::Selection::MOVE;
2339                 if (args[0].toString(exec).string().lower() == "extend")
2340                     alter = DOM::Selection::EXTEND;
2341                 DOMString directionString = args[1].toString(exec).string().lower();
2342                 DOM::Selection::EDirection direction = DOM::Selection::FORWARD;
2343                 if (directionString == "backward")
2344                     direction = DOM::Selection::BACKWARD;
2345                 else if (directionString == "left")
2346                     direction = DOM::Selection::LEFT;
2347                 if (directionString == "right")
2348                     direction = DOM::Selection::RIGHT;
2349                 DOM::Selection::ETextGranularity granularity = DOM::Selection::CHARACTER;
2350                 DOMString granularityString = args[2].toString(exec).string().lower();
2351                 if (granularityString == "word")
2352                     granularity = DOM::Selection::WORD;
2353                 else if (granularityString == "line")
2354                     granularity = DOM::Selection::LINE;
2355                 s.modify(alter, direction, granularity);
2356                 part->setSelection(s);
2357             }
2358         }
2359     }
2360
2361     return Undefined();
2362 }
2363
2364 ////////////////////// BarInfo Object ////////////////////////
2365
2366 const ClassInfo BarInfo::info = { "BarInfo", 0, 0, 0 };
2367 /*
2368 @begin BarInfoTable 1
2369   visible                BarInfo::Visible                        DontDelete|ReadOnly
2370 @end
2371 */
2372 BarInfo::BarInfo(ExecState *exec, KHTMLPart *p, Type barType) 
2373   : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype())
2374   , m_part(p)
2375   , m_type(barType)
2376 {
2377 }
2378
2379 BarInfo::~BarInfo()
2380 {
2381 }
2382
2383 Value BarInfo::get(ExecState *exec, const Identifier &p) const
2384 {
2385   if (m_part.isNull())
2386     return Undefined();
2387   
2388   const HashEntry *entry = Lookup::findEntry(&BarInfoTable, p);
2389   if (entry && entry->value == Visible) {
2390     switch (m_type) {
2391     case Locationbar:
2392 #if APPLE_CHANGES
2393       return Boolean(KWQ(m_part)->locationbarVisible());
2394 #endif
2395     case Menubar: 
2396 #if APPLE_CHANGES
2397       return Boolean(KWQ(m_part)->locationbarVisible());
2398 #endif
2399     case Personalbar:
2400 #if APPLE_CHANGES
2401       return Boolean(KWQ(m_part)->personalbarVisible());
2402 #endif
2403     case Scrollbars: 
2404 #if APPLE_CHANGES
2405       return Boolean(KWQ(m_part)->scrollbarsVisible());
2406 #endif
2407     case Statusbar:
2408 #if APPLE_CHANGES
2409       return Boolean(KWQ(m_part)->statusbarVisible());
2410 #endif
2411     case Toolbar:
2412 #if APPLE_CHANGES
2413       return Boolean(KWQ(m_part)->toolbarVisible());
2414 #endif
2415     default:
2416       return Boolean(false);
2417     }
2418   }
2419   
2420   return Undefined();
2421 }
2422
2423 void BarInfo::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
2424 {
2425 }
2426
2427 ////////////////////// History Object ////////////////////////
2428
2429 const ClassInfo History::info = { "History", 0, 0, 0 };
2430 /*
2431 @begin HistoryTable 4
2432   length        History::Length         DontDelete|ReadOnly
2433   back          History::Back           DontDelete|Function 0
2434   forward       History::Forward        DontDelete|Function 0
2435   go            History::Go             DontDelete|Function 1
2436 @end
2437 */
2438 IMPLEMENT_PROTOFUNC(HistoryFunc)
2439
2440 Value History::get(ExecState *exec, const Identifier &p) const
2441 {
2442   return lookupGet<HistoryFunc,History,ObjectImp>(exec,p,&HistoryTable,this);
2443 }
2444
2445 Value History::getValueProperty(ExecState *, int token) const
2446 {
2447   switch (token) {
2448   case Length:
2449   {
2450     KParts::BrowserExtension *ext = part->browserExtension();
2451     if ( !ext )
2452       return Number( 0 );
2453
2454     KParts::BrowserInterface *iface = ext->browserInterface();
2455     if ( !iface )
2456       return Number( 0 );
2457
2458     QVariant length = iface->property( "historyLength" );
2459
2460     if ( length.type() != QVariant::UInt )
2461       return Number( 0 );
2462
2463     return Number( length.toUInt() );
2464   }
2465   default:
2466     kdWarning() << "Unhandled token in History::getValueProperty : " << token << endl;
2467     return Undefined();
2468   }
2469 }
2470
2471 UString History::toString(ExecState *exec) const
2472 {
2473   return "[object History]";
2474 }
2475
2476 Value HistoryFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
2477 {
2478   if (!thisObj.inherits(&History::info)) {
2479     Object err = Error::create(exec,TypeError);
2480     exec->setException(err);
2481     return err;
2482   }
2483   History *history = static_cast<History *>(thisObj.imp());
2484
2485   int steps;
2486   switch (id) {
2487   case History::Back:
2488     steps = -1;
2489     break;
2490   case History::Forward:
2491     steps = 1;
2492     break;
2493   case History::Go:
2494     steps = args[0].toInt32(exec);
2495     break;
2496   default:
2497     return Undefined();
2498   }
2499
2500   history->part->scheduleHistoryNavigation(steps);
2501   return Undefined();
2502 }
2503
2504 /////////////////////////////////////////////////////////////////////////////
2505
2506 #ifdef Q_WS_QWS
2507
2508 const ClassInfo Konqueror::info = { "Konqueror", 0, 0, 0 };
2509
2510 bool Konqueror::hasProperty(ExecState *exec, const Identifier &p) const
2511 {
2512   if ( p.qstring().startsWith( "goHistory" ) ) return false;
2513
2514   return true;
2515 }
2516
2517 Value Konqueror::get(ExecState *exec, const Identifier &p) const
2518 {
2519   if ( p == "goHistory" || part->url().protocol() != "http" || part->url().host() != "localhost" )
2520     return Undefined();
2521
2522   KParts::BrowserExtension *ext = part->browserExtension();
2523   if ( ext ) {
2524     KParts::BrowserInterface *iface = ext->browserInterface();
2525     if ( iface ) {
2526       QVariant prop = iface->property( p.qstring().latin1() );
2527
2528       if ( prop.isValid() ) {
2529         switch( prop.type() ) {
2530         case QVariant::Int:
2531           return Number( prop.toInt() );
2532         case QVariant::String:
2533           return String( prop.toString() );
2534         default:
2535           break;
2536         }
2537       }
2538     }
2539   }
2540
2541   return /*Function*/( new KonquerorFunc(this, p.qstring().latin1() ) );
2542 }
2543
2544 Value KonquerorFunc::tryCall(ExecState *exec, Object &, const List &args)
2545 {
2546   KParts::BrowserExtension *ext = konqueror->part->browserExtension();
2547
2548   if(!ext)
2549     return Undefined();
2550
2551   KParts::BrowserInterface *iface = ext->browserInterface();
2552
2553   if ( !iface )
2554     return Undefined();
2555
2556   QCString n = m_name.data();
2557   n += "()";
2558   iface->callMethod( n.data(), QVariant() );
2559
2560   return Undefined();
2561 }
2562
2563 UString Konqueror::toString(ExecState *) const
2564 {
2565   return UString("[object Konqueror]");
2566 }
2567
2568 #endif
2569 /////////////////////////////////////////////////////////////////////////////
2570
2571 #include "kjs_window.moc"
2572