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