khtml Library API Documentation

kjs_window.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /*
00003  *  This file is part of the KDE libraries
00004  *  Copyright (C) 2000-2003 Harri Porten (porten@kde.org)
00005  *  Copyright (C) 2001-2003 David Faure (faure@kde.org)
00006  *  Copyright (C) 2003 Apple Computer, Inc.
00007  *
00008  *  This library is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU Library General Public
00010  *  License as published by the Free Software Foundation; either
00011  *  version 2 of the License, or (at your option) any later version.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Library General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Library General Public
00019  *  License along with this library; if not, write to the Free Software
00020  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 #include "config.h"
00023 
00024 #include <qstylesheet.h>
00025 #include <qtimer.h>
00026 #include <qpaintdevicemetrics.h>
00027 #include <qapplication.h>
00028 #include <kdebug.h>
00029 #include <kmessagebox.h>
00030 #include <kinputdialog.h>
00031 #include <klocale.h>
00032 #include <kparts/browserinterface.h>
00033 #include <kwin.h>
00034 
00035 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00036 #include <kwinmodule.h> // schroder
00037 #endif
00038 
00039 #include <kbookmarkmanager.h>
00040 #include <kglobalsettings.h>
00041 #include <assert.h>
00042 #include <qstyle.h>
00043 #include <qobjectlist.h>
00044 #include <kstringhandler.h>
00045 
00046 #include "kjs_proxy.h"
00047 #include "kjs_window.h"
00048 #include "kjs_navigator.h"
00049 #include "kjs_mozilla.h"
00050 #include "kjs_html.h"
00051 #include "kjs_range.h"
00052 #include "kjs_traversal.h"
00053 #include "kjs_css.h"
00054 #include "kjs_events.h"
00055 #include "xmlhttprequest.h"
00056 #include "xmlserializer.h"
00057 
00058 #include "khtmlview.h"
00059 #include "khtml_part.h"
00060 #include "khtmlpart_p.h"
00061 #include "khtml_settings.h"
00062 #include "xml/dom2_eventsimpl.h"
00063 #include "xml/dom_docimpl.h"
00064 #include "misc/htmltags.h"
00065 #include "html/html_documentimpl.h"
00066 #include "rendering/render_frames.h"
00067 
00068 using namespace KJS;
00069 
00070 namespace KJS {
00071 
00072   class History : public ObjectImp {
00073     friend class HistoryFunc;
00074   public:
00075     History(ExecState *exec, KHTMLPart *p)
00076       : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
00077     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00078     Value getValueProperty(ExecState *exec, int token) const;
00079     virtual const ClassInfo* classInfo() const { return &info; }
00080     static const ClassInfo info;
00081     enum { Back, Forward, Go, Length };
00082   private:
00083     QGuardedPtr<KHTMLPart> part;
00084   };
00085 
00086   class External : public ObjectImp {
00087     friend class ExternalFunc;
00088   public:
00089     External(ExecState *exec, KHTMLPart *p)
00090       : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
00091     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00092     virtual const ClassInfo* classInfo() const { return &info; }
00093     static const ClassInfo info;
00094     enum { AddFavorite };
00095   private:
00096     QGuardedPtr<KHTMLPart> part;
00097   };
00098 
00099   class FrameArray : public ObjectImp {
00100   public:
00101     FrameArray(ExecState *exec, KHTMLPart *p)
00102       : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
00103     virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00104   private:
00105     QGuardedPtr<KHTMLPart> part;
00106   };
00107 
00108 #ifdef Q_WS_QWS
00109   class KonquerorFunc : public DOMFunction {
00110   public:
00111     KonquerorFunc(const Konqueror* k, const char* name)
00112       : DOMFunction(), konqueror(k), m_name(name) { }
00113     virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args);
00114 
00115   private:
00116     const Konqueror* konqueror;
00117     QCString m_name;
00118   };
00119 #endif
00120 } // namespace KJS
00121 
00122 #include "kjs_window.lut.h"
00123 #include "rendering/render_replaced.h"
00124 
00126 
00127 // table for screen object
00128 /*
00129 @begin ScreenTable 7
00130   height        Screen::Height      DontEnum|ReadOnly
00131   width         Screen::Width       DontEnum|ReadOnly
00132   colorDepth    Screen::ColorDepth  DontEnum|ReadOnly
00133   pixelDepth    Screen::PixelDepth  DontEnum|ReadOnly
00134   availLeft     Screen::AvailLeft   DontEnum|ReadOnly
00135   availTop      Screen::AvailTop    DontEnum|ReadOnly
00136   availHeight   Screen::AvailHeight DontEnum|ReadOnly
00137   availWidth    Screen::AvailWidth  DontEnum|ReadOnly
00138 @end
00139 */
00140 
00141 const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
00142 
00143 // We set the object prototype so that toString is implemented
00144 Screen::Screen(ExecState *exec)
00145   : ObjectImp(exec->interpreter()->builtinObjectPrototype()) {}
00146 
00147 Value Screen::get(ExecState *exec, const Identifier &p) const
00148 {
00149 #ifdef KJS_VERBOSE
00150   kdDebug(6070) << "Screen::get " << p.qstring() << endl;
00151 #endif
00152   return lookupGetValue<Screen,ObjectImp>(exec,p,&ScreenTable,this);
00153 }
00154 
00155 Value Screen::getValueProperty(ExecState *exec, int token) const
00156 {
00157 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00158   KWinModule info(0, KWinModule::INFO_DESKTOP);
00159 #endif
00160   QWidget *thisWidget = Window::retrieveActive(exec)->part()->widget();
00161   QRect sg = KGlobalSettings::desktopGeometry(thisWidget);
00162 
00163   switch( token ) {
00164   case Height:
00165     return Number(sg.height());
00166   case Width:
00167     return Number(sg.width());
00168   case ColorDepth:
00169   case PixelDepth: {
00170     QPaintDeviceMetrics m(QApplication::desktop());
00171     return Number(m.depth());
00172   }
00173   case AvailLeft: {
00174 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00175     QRect clipped = info.workArea().intersect(sg);
00176     return Number(clipped.x()-sg.x());
00177 #else
00178     return Number(10);
00179 #endif
00180   }
00181   case AvailTop: {
00182 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00183     QRect clipped = info.workArea().intersect(sg);
00184     return Number(clipped.y()-sg.y());
00185 #else
00186     return Number(10);
00187 #endif
00188   }
00189   case AvailHeight: {
00190 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00191     QRect clipped = info.workArea().intersect(sg);
00192     return Number(clipped.height());
00193 #else
00194     return Number(100);
00195 #endif
00196   }
00197   case AvailWidth: {
00198 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00199     QRect clipped = info.workArea().intersect(sg);
00200     return Number(clipped.width());
00201 #else
00202     return Number(100);
00203 #endif
00204   }
00205   default:
00206     kdDebug(6070) << "WARNING: Screen::getValueProperty unhandled token " << token << endl;
00207     return Undefined();
00208   }
00209 }
00210 
00212 
00213 const ClassInfo Window::info = { "Window", 0, &WindowTable, 0 };
00214 
00215 /*
00216 @begin WindowTable 87
00217   closed    Window::Closed      DontDelete|ReadOnly
00218   crypto    Window::Crypto      DontDelete|ReadOnly
00219   defaultStatus Window::DefaultStatus   DontDelete
00220   defaultstatus Window::DefaultStatus   DontDelete
00221   status    Window::Status      DontDelete
00222   document  Window::Document    DontDelete|ReadOnly
00223   Node      Window::Node        DontDelete
00224   Event     Window::EventCtor   DontDelete
00225   Range     Window::Range       DontDelete
00226   NodeFilter    Window::NodeFilter  DontDelete
00227   DOMException  Window::DOMException    DontDelete
00228   CSSRule   Window::CSSRule     DontDelete
00229   frames    Window::Frames      DontDelete|ReadOnly
00230   history   Window::_History    DontDelete|ReadOnly
00231   external  Window::_External   DontDelete|ReadOnly
00232   event     Window::Event       DontDelete|ReadOnly
00233   innerHeight   Window::InnerHeight DontDelete|ReadOnly
00234   innerWidth    Window::InnerWidth  DontDelete|ReadOnly
00235   length    Window::Length      DontDelete|ReadOnly
00236   location  Window::_Location   DontDelete
00237   name      Window::Name        DontDelete
00238   navigator Window::_Navigator  DontDelete|ReadOnly
00239   clientInformation Window::ClientInformation   DontDelete|ReadOnly
00240   konqueror Window::_Konqueror  DontDelete|ReadOnly
00241   offscreenBuffering    Window::OffscreenBuffering  DontDelete|ReadOnly
00242   opener    Window::Opener      DontDelete|ReadOnly
00243   outerHeight   Window::OuterHeight DontDelete|ReadOnly
00244   outerWidth    Window::OuterWidth  DontDelete|ReadOnly
00245   pageXOffset   Window::PageXOffset DontDelete|ReadOnly
00246   pageYOffset   Window::PageYOffset DontDelete|ReadOnly
00247   parent    Window::Parent      DontDelete|ReadOnly
00248   personalbar   Window::Personalbar DontDelete|ReadOnly
00249   screenX   Window::ScreenX     DontDelete|ReadOnly
00250   screenY   Window::ScreenY     DontDelete|ReadOnly
00251   scrollbars    Window::Scrollbars  DontDelete|ReadOnly
00252   scroll    Window::Scroll      DontDelete|Function 2
00253   scrollBy  Window::ScrollBy    DontDelete|Function 2
00254   scrollTo  Window::ScrollTo    DontDelete|Function 2
00255   moveBy    Window::MoveBy      DontDelete|Function 2
00256   moveTo    Window::MoveTo      DontDelete|Function 2
00257   resizeBy  Window::ResizeBy    DontDelete|Function 2
00258   resizeTo  Window::ResizeTo    DontDelete|Function 2
00259   self      Window::Self        DontDelete|ReadOnly
00260   window    Window::_Window     DontDelete|ReadOnly
00261   top       Window::Top     DontDelete|ReadOnly
00262   screen    Window::_Screen     DontDelete|ReadOnly
00263   Image     Window::Image       DontDelete|ReadOnly
00264   Option    Window::Option      DontDelete|ReadOnly
00265   XMLHttpRequest Window::XMLHttpRequest DontDelete|ReadOnly
00266   XMLSerializer Window::XMLSerializer   DontDelete|ReadOnly
00267   alert     Window::Alert       DontDelete|Function 1
00268   confirm   Window::Confirm     DontDelete|Function 1
00269   prompt    Window::Prompt      DontDelete|Function 2
00270   open      Window::Open        DontDelete|Function 3
00271   setTimeout    Window::SetTimeout  DontDelete|Function 2
00272   clearTimeout  Window::ClearTimeout    DontDelete|Function 1
00273   focus     Window::Focus       DontDelete|Function 0
00274   blur      Window::Blur        DontDelete|Function 0
00275   close     Window::Close       DontDelete|Function 0
00276   setInterval   Window::SetInterval DontDelete|Function 2
00277   clearInterval Window::ClearInterval   DontDelete|Function 1
00278   captureEvents Window::CaptureEvents   DontDelete|Function 0
00279   releaseEvents Window::ReleaseEvents   DontDelete|Function 0
00280   print     Window::Print       DontDelete|Function 0
00281   addEventListener  Window::AddEventListener    DontDelete|Function 3
00282   removeEventListener   Window::RemoveEventListener DontDelete|Function 3
00283 # IE extension
00284   navigate  Window::Navigate    DontDelete|Function 1
00285 # Mozilla extension
00286   sidebar   Window::SideBar     DontDelete|ReadOnly
00287 
00288 # Warning, when adding a function to this object you need to add a case in Window::get
00289 
00290 # Event handlers
00291 # IE also has: onactivate, onbefore/afterprint, onbeforedeactivate/unload, oncontrolselect,
00292 # ondeactivate, onhelp, onmovestart/end, onresizestart/end, onscroll.
00293 # It doesn't have onabort, onchange, ondragdrop (but NS has that last one).
00294   onabort   Window::Onabort     DontDelete
00295   onblur    Window::Onblur      DontDelete
00296   onchange  Window::Onchange    DontDelete
00297   onclick   Window::Onclick     DontDelete
00298   ondblclick    Window::Ondblclick  DontDelete
00299   ondragdrop    Window::Ondragdrop  DontDelete
00300   onerror   Window::Onerror     DontDelete
00301   onfocus   Window::Onfocus     DontDelete
00302   onkeydown Window::Onkeydown   DontDelete
00303   onkeypress    Window::Onkeypress  DontDelete
00304   onkeyup   Window::Onkeyup     DontDelete
00305   onload    Window::Onload      DontDelete
00306   onmousedown   Window::Onmousedown DontDelete
00307   onmousemove   Window::Onmousemove DontDelete
00308   onmouseout    Window::Onmouseout  DontDelete
00309   onmouseover   Window::Onmouseover DontDelete
00310   onmouseup Window::Onmouseup   DontDelete
00311   onmove    Window::Onmove      DontDelete
00312   onreset   Window::Onreset     DontDelete
00313   onresize  Window::Onresize    DontDelete
00314   onselect  Window::Onselect    DontDelete
00315   onsubmit  Window::Onsubmit    DontDelete
00316   onunload  Window::Onunload    DontDelete
00317 @end
00318 */
00319 IMPLEMENT_PROTOFUNC_DOM(WindowFunc)
00320 
00321 Window::Window(khtml::ChildFrame *p)
00322   : ObjectImp(/*no proto*/), m_frame(p), screen(0), history(0), external(0), m_frames(0), loc(0), m_evt(0)
00323 {
00324   winq = new WindowQObject(this);
00325   //kdDebug(6070) << "Window::Window this=" << this << " part=" << m_part << " " << m_part->name() << endl;
00326 }
00327 
00328 Window::~Window()
00329 {
00330   delete winq;
00331 }
00332 
00333 Window *Window::retrieveWindow(KParts::ReadOnlyPart *p)
00334 {
00335   Object obj = Object::dynamicCast( retrieve( p ) );
00336 #ifndef NDEBUG
00337   // obj should never be null, except when javascript has been disabled in that part.
00338   KHTMLPart *part = ::qt_cast<KHTMLPart *>(p);
00339   if ( part && part->jScriptEnabled() )
00340   {
00341     assert( !obj.isNull() );
00342 #ifndef QWS
00343     assert( dynamic_cast<KJS::Window*>(obj.imp()) ); // type checking
00344 #endif
00345   }
00346 #endif
00347   if ( obj.isNull() ) // JS disabled
00348     return 0;
00349   return static_cast<KJS::Window*>(obj.imp());
00350 }
00351 
00352 Window *Window::retrieveActive(ExecState *exec)
00353 {
00354   ValueImp *imp = exec->interpreter()->globalObject().imp();
00355   assert( imp );
00356 #ifndef QWS
00357   assert( dynamic_cast<KJS::Window*>(imp) );
00358 #endif
00359   return static_cast<KJS::Window*>(imp);
00360 }
00361 
00362 Value Window::retrieve(KParts::ReadOnlyPart *p)
00363 {
00364   assert(p);
00365   KHTMLPart * part = ::qt_cast<KHTMLPart *>(p);
00366   KJSProxy *proxy = 0L;
00367   if (!part) {
00368     part = ::qt_cast<KHTMLPart *>(p->parent());
00369     if (part)
00370       proxy = part->framejScript(p);
00371   } else
00372     proxy = part->jScript();
00373   if (proxy) {
00374 #ifdef KJS_VERBOSE
00375     kdDebug(6070) << "Window::retrieve part=" << part << " '" << part->name() << "' interpreter=" << proxy->interpreter() << " window=" << proxy->interpreter()->globalObject().imp() << endl;
00376 #endif
00377     return proxy->interpreter()->globalObject(); // the Global object is the "window"
00378   } else {
00379 #ifdef KJS_VERBOSE
00380     kdDebug(6070) << "Window::retrieve part=" << p << " '" << p->name() << "' no jsproxy." << endl;
00381 #endif
00382     return Undefined(); // This can happen with JS disabled on the domain of that window
00383   }
00384 }
00385 
00386 Location *Window::location() const
00387 {
00388   if (!loc)
00389     const_cast<Window*>(this)->loc = new Location(m_frame);
00390   return loc;
00391 }
00392 
00393 ObjectImp* Window::frames( ExecState* exec ) const
00394 {
00395   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
00396   if (part)
00397     return m_frames ? m_frames :
00398       (const_cast<Window*>(this)->m_frames = new FrameArray(exec, part));
00399   return 0L;
00400 }
00401 
00402 // reference our special objects during garbage collection
00403 void Window::mark()
00404 {
00405   ObjectImp::mark();
00406   if (screen && !screen->marked())
00407     screen->mark();
00408   if (history && !history->marked())
00409     history->mark();
00410   if (external && !external->marked())
00411     external->mark();
00412   if (m_frames && !m_frames->marked())
00413     m_frames->mark();
00414   //kdDebug(6070) << "Window::mark " << this << " marking loc=" << loc << endl;
00415   if (loc && !loc->marked())
00416     loc->mark();
00417   if (winq)
00418     winq->mark();
00419 }
00420 
00421 bool Window::hasProperty(ExecState *exec, const Identifier &p) const
00422 {
00423   // we don't want any operations on a closed window
00424   if (m_frame.isNull() || m_frame->m_part.isNull())
00425     return ( p == "closed" );
00426 
00427   if (ObjectImp::hasProperty(exec, p))
00428     return true;
00429 
00430   if (Lookup::findEntry(&WindowTable, p))
00431     return true;
00432 
00433   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
00434   if (!part)
00435       return false;
00436 
00437   QString q = p.qstring();
00438   if (part->findFramePart(p.qstring()))
00439     return true;
00440   // allow window[1] or parent[1] etc. (#56983)
00441   bool ok;
00442   unsigned int i = p.toArrayIndex(&ok);
00443   if (ok) {
00444     QPtrList<KParts::ReadOnlyPart> frames = part->frames();
00445     unsigned int len = frames.count();
00446     if (i < len)
00447       return true;
00448   }
00449 
00450   // allow shortcuts like 'Image1' instead of document.images.Image1
00451   if (part->document().isHTMLDocument()) { // might be XML
00452     DOM::HTMLDocument doc = part->htmlDocument();
00453     // Keep in sync with tryGet
00454     NamedTagLengthDeterminer::TagLength tags[3] = {
00455       {ID_IMG, 0, 0L}, {ID_FORM, 0, 0L}, {ID_APPLET, 0, 0L}
00456     };
00457     NamedTagLengthDeterminer(p.string(), tags, 3)(doc.handle());
00458     for (int i = 0; i < 3; i++)
00459       if (tags[i].length > 0)
00460         return true;
00461 
00462     return !doc.getElementById(p.string()).isNull();
00463   }
00464 
00465   return false;
00466 }
00467 
00468 UString Window::toString(ExecState *) const
00469 {
00470   return "[object Window]";
00471 }
00472 
00473 Value Window::get(ExecState *exec, const Identifier &p) const
00474 {
00475 #ifdef KJS_VERBOSE
00476   kdDebug(6070) << "Window("<<this<<")::get " << p.qstring() << endl;
00477 #endif
00478   // we don't want any operations on a closed window
00479   if (m_frame.isNull() || m_frame->m_part.isNull()) {
00480     if ( p == "closed" )
00481       return Boolean( true );
00482     return Undefined();
00483   }
00484 
00485   // Look for overrides first
00486   Value val = ObjectImp::get(exec, p);
00487   if (!val.isA(UndefinedType)) {
00488     //kdDebug(6070) << "Window::get found dynamic property '" << p.ascii() << "'" << endl;
00489     return isSafeScript(exec) ? val : Undefined();
00490   }
00491 
00492   const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
00493   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
00494 
00495   // properties that work on all windows
00496   if (entry) {
00497     // ReadOnlyPart first
00498     switch(entry->value) {
00499     case Closed:
00500       return Boolean( false );
00501     case _Location:
00502         // No isSafeScript test here, we must be able to _set_ location.href (#49819)
00503       return Value(location());
00504     case _Window:
00505     case Self:
00506       return retrieve(m_frame->m_part);
00507     default:
00508         break;
00509     }
00510     if (!part)
00511         return Undefined();
00512     // KHTMLPart next
00513     switch(entry->value) {
00514     case Frames:
00515       return Value(frames(exec));
00516     case Opener:
00517       if (!part->opener())
00518         return Null();    // ### a null Window might be better, but == null
00519       else                // doesn't work yet
00520         return retrieve(part->opener());
00521     case Parent:
00522       return retrieve(part->parentPart() ? part->parentPart() : (KHTMLPart*)part);
00523     case Top: {
00524       KHTMLPart *p = part;
00525       while (p->parentPart())
00526         p = p->parentPart();
00527       return retrieve(p);
00528     }
00529     case Alert:
00530     case Confirm:
00531     case Prompt:
00532     case Open:
00533     case Focus:
00534     case Blur:
00535       return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
00536     default:
00537       break;
00538     }
00539   } else if (!part) {
00540     // not a  KHTMLPart
00541     QString rvalue;
00542     KParts::LiveConnectExtension::Type rtype;
00543     unsigned long robjid;
00544     if (m_frame->m_liveconnect &&
00545         isSafeScript(exec) &&
00546         m_frame->m_liveconnect->get(0, p.qstring(), rtype, robjid, rvalue))
00547       return getLiveConnectValue(m_frame->m_liveconnect, p.qstring(), rtype, rvalue, robjid);
00548     return Undefined();
00549   }
00550   // properties that only work on safe windows
00551   if (isSafeScript(exec) &&  entry)
00552   {
00553     //kdDebug(6070) << "token: " << entry->value << endl;
00554     switch( entry->value ) {
00555     case Crypto:
00556       return Undefined(); // ###
00557     case DefaultStatus:
00558       return String(UString(part->jsDefaultStatusBarText()));
00559     case Status:
00560       return String(UString(part->jsStatusBarText()));
00561     case Document:
00562       if (part->document().isNull()) {
00563         kdDebug(6070) << "Document.write: adding <HTML><BODY> to create document" << endl;
00564         part->begin();
00565         part->write("<HTML><BODY>");
00566         part->end();
00567       }
00568       return getDOMNode(exec,part->document());
00569     case Node:
00570       return getNodeConstructor(exec);
00571     case Range:
00572       return getRangeConstructor(exec);
00573     case NodeFilter:
00574       return getNodeFilterConstructor(exec);
00575     case DOMException:
00576       return getDOMExceptionConstructor(exec);
00577     case CSSRule:
00578       return getCSSRuleConstructor(exec);
00579     case EventCtor:
00580       return getEventConstructor(exec);
00581     case _History:
00582       return Value(history ? history :
00583                    (const_cast<Window*>(this)->history = new History(exec,part)));
00584 
00585     case _External:
00586       return Value(external ? external :
00587                    (const_cast<Window*>(this)->external = new External(exec,part)));
00588 
00589     case Event:
00590       if (m_evt)
00591         return getDOMEvent(exec,*m_evt);
00592       else {
00593 #ifdef KJS_VERBOSE
00594         kdDebug(6070) << "WARNING: window(" << this << "," << part->name() << ").event, no event!" << endl;
00595 #endif
00596         return Undefined();
00597       }
00598     case InnerHeight:
00599       if (!part->view())
00600         return Undefined();
00601       khtml::RenderWidget::flushWidgetResizes(); // make sure frames have their final size
00602       return Number(part->view()->visibleHeight());
00603     case InnerWidth:
00604       if (!part->view())
00605         return Undefined();
00606       khtml::RenderWidget::flushWidgetResizes(); // make sure frames have their final size
00607       return Number(part->view()->visibleWidth());
00608     case Length:
00609       return Number(part->frames().count());
00610     case Name:
00611       return String(part->name());
00612     case SideBar:
00613       return Value(new MozillaSidebarExtension(exec, part));
00614     case _Navigator:
00615     case ClientInformation: {
00616       // Store the navigator in the object so we get the same one each time.
00617       Value nav( new Navigator(exec, part) );
00618       const_cast<Window *>(this)->put(exec, "navigator", nav, DontDelete|ReadOnly|Internal);
00619       const_cast<Window *>(this)->put(exec, "clientInformation", nav, DontDelete|ReadOnly|Internal);
00620       return nav;
00621     }
00622 #ifdef Q_WS_QWS
00623     case _Konqueror: {
00624       Value k( new Konqueror(exec, part) );
00625       const_cast<Window *>(this)->put(exec, "konqueror", k, DontDelete|ReadOnly|Internal);
00626       return k;
00627     }
00628 #endif
00629     case OffscreenBuffering:
00630       return Boolean(true);
00631     case OuterHeight:
00632     case OuterWidth:
00633     {
00634       if (!part->widget())
00635         return Number(0);
00636       KWin::WindowInfo inf = KWin::windowInfo(part->widget()->topLevelWidget()->winId());
00637       return Number(entry->value == OuterHeight ?
00638                     inf.geometry().height() : inf.geometry().width());
00639     }
00640     case PageXOffset:
00641       return Number(part->view()->contentsX());
00642     case PageYOffset:
00643       return Number(part->view()->contentsY());
00644     case Personalbar:
00645       return Undefined(); // ###
00646     case ScreenLeft:
00647     case ScreenX: {
00648       if (!part->view())
00649         return Undefined();
00650       QRect sg = KGlobalSettings::desktopGeometry(part->view());
00651       return Number(part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
00652     }
00653     case ScreenTop:
00654     case ScreenY: {
00655       if (!part->view())
00656         return Undefined();
00657       QRect sg = KGlobalSettings::desktopGeometry(part->view());
00658       return Number(part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
00659     }
00660     case ScrollX: {
00661       if (!part->view())
00662         return Undefined();
00663       return Number(part->view()->contentsX());
00664     }
00665     case ScrollY: {
00666       if (!part->view())
00667         return Undefined();
00668       return Number(part->view()->contentsY());
00669     }
00670     case Scrollbars:
00671       return Undefined(); // ###
00672     case _Screen:
00673       return Value(screen ? screen :
00674                    (const_cast<Window*>(this)->screen = new Screen(exec)));
00675     case Image:
00676       return Value(new ImageConstructorImp(exec, part->document()));
00677     case Option:
00678       return Value(new OptionConstructorImp(exec, part->document()));
00679     case XMLHttpRequest:
00680       return Value(new XMLHttpRequestConstructorImp(exec, part->document()));
00681     case XMLSerializer:
00682       return Value(new XMLSerializerConstructorImp(exec));
00683     case Close:
00684     case Scroll: // compatibility
00685     case ScrollBy:
00686     case ScrollTo:
00687     case MoveBy:
00688     case MoveTo:
00689     case ResizeBy:
00690     case ResizeTo:
00691     case CaptureEvents:
00692     case ReleaseEvents:
00693     case AddEventListener:
00694     case RemoveEventListener:
00695     case SetTimeout:
00696     case ClearTimeout:
00697     case SetInterval:
00698     case ClearInterval:
00699     case Print:
00700       return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
00701     // IE extension
00702     case Navigate:
00703       // Disabled in NS-compat mode. Supported by default - can't hurt, unless someone uses
00704       // if (navigate) to test for IE (unlikely).
00705       if ( exec->interpreter()->compatMode() == Interpreter::NetscapeCompat )
00706         return Undefined();
00707       return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
00708     case Onabort:
00709       return getListener(exec,DOM::EventImpl::ABORT_EVENT);
00710     case Onblur:
00711       return getListener(exec,DOM::EventImpl::BLUR_EVENT);
00712     case Onchange:
00713       return getListener(exec,DOM::EventImpl::CHANGE_EVENT);
00714     case Onclick:
00715       return getListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT);
00716     case Ondblclick:
00717       return getListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT);
00718     case Ondragdrop:
00719       return getListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT);
00720     case Onerror:
00721       return getListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT);
00722     case Onfocus:
00723       return getListener(exec,DOM::EventImpl::FOCUS_EVENT);
00724     case Onkeydown:
00725       return getListener(exec,DOM::EventImpl::KEYDOWN_EVENT);
00726     case Onkeypress:
00727       return getListener(exec,DOM::EventImpl::KHTML_KEYPRESS_EVENT);
00728     case Onkeyup:
00729       return getListener(exec,DOM::EventImpl::KEYUP_EVENT);
00730     case Onload:
00731       return getListener(exec,DOM::EventImpl::LOAD_EVENT);
00732     case Onmousedown:
00733       return getListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT);
00734     case Onmousemove:
00735       return getListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT);
00736     case Onmouseout:
00737       return getListener(exec,DOM::EventImpl::MOUSEOUT_EVENT);
00738     case Onmouseover:
00739       return getListener(exec,DOM::EventImpl::MOUSEOVER_EVENT);
00740     case Onmouseup:
00741       return getListener(exec,DOM::EventImpl::MOUSEUP_EVENT);
00742     case Onmove:
00743       return getListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT);
00744     case Onreset:
00745       return getListener(exec,DOM::EventImpl::RESET_EVENT);
00746     case Onresize:
00747       return getListener(exec,DOM::EventImpl::RESIZE_EVENT);
00748     case Onselect:
00749       return getListener(exec,DOM::EventImpl::SELECT_EVENT);
00750     case Onsubmit:
00751       return getListener(exec,DOM::EventImpl::SUBMIT_EVENT);
00752     case Onunload:
00753       return getListener(exec,DOM::EventImpl::UNLOAD_EVENT);
00754     }
00755   }
00756   KParts::ReadOnlyPart *rop = part->findFramePart( p.qstring() );
00757   if (rop)
00758     return retrieve(rop);
00759 
00760   // allow window[1] or parent[1] etc. (#56983)
00761   bool ok;
00762   unsigned int i = p.toArrayIndex(&ok);
00763   if (ok) {
00764     QPtrList<KParts::ReadOnlyPart> frames = part->frames();
00765     unsigned int len = frames.count();
00766     if (i < len) {
00767       KParts::ReadOnlyPart* frame = frames.at(i);
00768       if (frame)
00769         return Window::retrieve(frame);
00770     }
00771   }
00772 
00773   // allow shortcuts like 'Image1' instead of document.images.Image1
00774   if (isSafeScript(exec) &&
00775       part->document().isHTMLDocument()) { // might be XML
00776     // This is only for images, forms, layers and applets, see KJS::HTMLDocument::tryGet
00777     DOM::HTMLDocument doc = part->htmlDocument();
00778     NamedTagLengthDeterminer::TagLength tags[4] = {
00779       {ID_IMG, 0, 0L}, {ID_FORM, 0, 0L}, {ID_APPLET, 0, 0L}, {ID_LAYER, 0, 0L}
00780     };
00781     NamedTagLengthDeterminer(p.string(), tags, 4)(doc.handle());
00782     for (int i = 0; i < 4; i++)
00783       if (tags[i].length > 0) {
00784         if (tags[i].length == 1)
00785           return getDOMNode(exec, tags[i].last);
00786         // Get all the items with the same name
00787         return getDOMNodeList(exec, DOM::NodeList(new DOM::NamedTagNodeListImpl(doc.handle(), tags[i].id, p.string())));
00788     }
00789 
00790     DOM::Element element = doc.getElementById(p.string() );
00791     if ( !element.isNull() )
00792       return getDOMNode(exec, element );
00793   }
00794 
00795   // This isn't necessarily a bug. Some code uses if(!window.blah) window.blah=1
00796   // But it can also mean something isn't loaded or implemented, hence the WARNING to help grepping.
00797 #ifdef KJS_VERBOSE
00798   kdDebug(6070) << "WARNING: Window::get property not found: " << p.qstring() << endl;
00799 #endif
00800   return Undefined();
00801 }
00802 
00803 void Window::put(ExecState* exec, const Identifier &propertyName, const Value &value, int attr)
00804 {
00805   // Called by an internal KJS call (e.g. InterpreterImp's constructor) ?
00806   // If yes, save time and jump directly to ObjectImp.
00807   if ( (attr != None && attr != DontDelete) ||
00808        // Same thing if we have a local override (e.g. "var location")
00809        ( isSafeScript( exec ) && ObjectImp::getDirect(propertyName) ) )
00810   {
00811     ObjectImp::put( exec, propertyName, value, attr );
00812     return;
00813   }
00814 
00815   const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
00816   if (entry && !m_frame.isNull() && !m_frame->m_part.isNull())
00817   {
00818 #ifdef KJS_VERBOSE
00819     kdDebug(6070) << "Window("<<this<<")::put " << propertyName.qstring() << endl;
00820 #endif
00821     switch( entry->value) {
00822     case _Location:
00823       goURL(exec, value.toString(exec).qstring(), false /*don't lock history*/);
00824       return;
00825     default:
00826       break;
00827     }
00828     KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
00829     if (part) {
00830     switch( entry->value ) {
00831     case Status: {
00832       if  (isSafeScript(exec) && part->settings()->windowStatusPolicy(part->url().host())
00833         == KHTMLSettings::KJSWindowStatusAllow) {
00834       String s = value.toString(exec);
00835       part->setJSStatusBarText(s.value().qstring());
00836       }
00837       return;
00838     }
00839     case DefaultStatus: {
00840       if (isSafeScript(exec) && part->settings()->windowStatusPolicy(part->url().host())
00841         == KHTMLSettings::KJSWindowStatusAllow) {
00842       String s = value.toString(exec);
00843       part->setJSDefaultStatusBarText(s.value().qstring());
00844       }
00845       return;
00846     }
00847     case Onabort:
00848       if (isSafeScript(exec))
00849         setListener(exec, DOM::EventImpl::ABORT_EVENT,value);
00850       return;
00851     case Onblur:
00852       if (isSafeScript(exec))
00853         setListener(exec, DOM::EventImpl::BLUR_EVENT,value);
00854       return;
00855     case Onchange:
00856       if (isSafeScript(exec))
00857         setListener(exec, DOM::EventImpl::CHANGE_EVENT,value);
00858       return;
00859     case Onclick:
00860       if (isSafeScript(exec))
00861         setListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT,value);
00862       return;
00863     case Ondblclick:
00864       if (isSafeScript(exec))
00865         setListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT,value);
00866       return;
00867     case Ondragdrop:
00868       if (isSafeScript(exec))
00869         setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
00870       return;
00871     case Onerror:
00872       if (isSafeScript(exec))
00873         setListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT,value);
00874       return;
00875     case Onfocus:
00876       if (isSafeScript(exec))
00877         setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
00878       return;
00879     case Onkeydown:
00880       if (isSafeScript(exec))
00881         setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
00882       return;
00883     case Onkeypress:
00884       if (isSafeScript(exec))
00885         setListener(exec,DOM::EventImpl::KHTML_KEYPRESS_EVENT,value);
00886       return;
00887     case Onkeyup:
00888       if (isSafeScript(exec))
00889         setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
00890       return;
00891     case Onload:
00892       if (isSafeScript(exec))
00893         setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
00894       return;
00895     case Onmousedown:
00896       if (isSafeScript(exec))
00897         setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
00898       return;
00899     case Onmousemove:
00900       if (isSafeScript(exec))
00901         setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
00902       return;
00903     case Onmouseout:
00904       if (isSafeScript(exec))
00905         setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
00906       return;
00907     case Onmouseover:
00908       if (isSafeScript(exec))
00909         setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
00910       return;
00911     case Onmouseup:
00912       if (isSafeScript(exec))
00913         setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
00914       return;
00915     case Onmove:
00916       if (isSafeScript(exec))
00917         setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
00918       return;
00919     case Onreset:
00920       if (isSafeScript(exec))
00921         setListener(exec,DOM::EventImpl::RESET_EVENT,value);
00922       return;
00923     case Onresize:
00924       if (isSafeScript(exec))
00925         setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
00926       return;
00927     case Onselect:
00928       if (isSafeScript(exec))
00929         setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
00930       return;
00931     case Onsubmit:
00932       if (isSafeScript(exec))
00933         setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
00934       return;
00935     case Onunload:
00936       if (isSafeScript(exec))
00937         setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
00938       return;
00939     case Name:
00940       if (isSafeScript(exec))
00941         part->setName( value.toString(exec).qstring().local8Bit().data() );
00942       return;
00943     default:
00944       break;
00945     }
00946     }
00947   }
00948   if (m_frame->m_liveconnect &&
00949       isSafeScript(exec) &&
00950       m_frame->m_liveconnect->put(0, propertyName.qstring(), value.toString(exec).qstring()))
00951     return;
00952   if (isSafeScript(exec)) {
00953     //kdDebug(6070) << "Window("<<this<<")::put storing " << propertyName.qstring() << endl;
00954     ObjectImp::put(exec, propertyName, value, attr);
00955   }
00956 }
00957 
00958 bool Window::toBoolean(ExecState *) const
00959 {
00960   return !m_frame.isNull() && !m_frame->m_part.isNull();
00961 }
00962 
00963 void Window::scheduleClose()
00964 {
00965   kdDebug(6070) << "Window::scheduleClose window.close() " << m_frame << endl;
00966   Q_ASSERT(winq);
00967   QTimer::singleShot( 0, winq, SLOT( timeoutClose() ) );
00968 }
00969 
00970 void Window::closeNow()
00971 {
00972   if (m_frame.isNull() || m_frame->m_part.isNull()) {
00973     kdDebug(6070) << k_funcinfo << "part is deleted already" << endl;
00974   } else {
00975     KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
00976     if (!part) {
00977       kdDebug(6070) << "closeNow on non KHTML part" << endl;
00978     } else {
00979       //kdDebug(6070) << k_funcinfo << " -> closing window" << endl;
00980       // We want to make sure that window.open won't find this part by name.
00981       part->setName( 0 );
00982       part->deleteLater();
00983       part = 0;
00984     }
00985   }
00986 }
00987 
00988 void Window::afterScriptExecution()
00989 {
00990   DOM::DocumentImpl::updateDocumentsRendering();
00991   QValueList<DelayedAction> delayedActions = m_delayed;
00992   m_delayed.clear();
00993   QValueList<DelayedAction>::Iterator it = delayedActions.begin();
00994   for ( ; it != delayedActions.end() ; ++it )
00995   {
00996     switch ((*it).actionId) {
00997     case DelayedClose:
00998       scheduleClose();
00999       return; // stop here, in case of multiple actions
01000     case DelayedGoHistory:
01001       goHistory( (*it).param.toInt() );
01002       break;
01003     case NullAction:
01004       // FIXME: anything needs to be done here?  This is warning anyways.
01005       break;
01006     };
01007   }
01008 }
01009 
01010 bool Window::checkIsSafeScript(KParts::ReadOnlyPart *activePart) const
01011 {
01012   if (m_frame.isNull() || m_frame->m_part.isNull()) { // part deleted ? can't grant access
01013     kdDebug(6070) << "Window::isSafeScript: accessing deleted part !" << endl;
01014     return false;
01015   }
01016   if (!activePart) {
01017     kdDebug(6070) << "Window::isSafeScript: current interpreter's part is 0L!" << endl;
01018     return false;
01019   }
01020    if ( activePart == m_frame->m_part ) // Not calling from another frame, no problem.
01021      return true;
01022 
01023   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01024   if (!part)
01025     return true; // not a KHTMLPart
01026 
01027   if ( part->document().isNull() )
01028     return true; // allow to access a window that was just created (e.g. with window.open("about:blank"))
01029 
01030   DOM::HTMLDocument thisDocument = part->htmlDocument();
01031   if ( thisDocument.isNull() ) {
01032     kdDebug(6070) << "Window::isSafeScript: trying to access an XML document !?" << endl;
01033     return false;
01034   }
01035 
01036   KHTMLPart *activeKHTMLPart = ::qt_cast<KHTMLPart *>(activePart);
01037   if (!activeKHTMLPart)
01038     return true; // not a KHTMLPart
01039 
01040   DOM::HTMLDocument actDocument = activeKHTMLPart->htmlDocument();
01041   if ( actDocument.isNull() ) {
01042     kdDebug(6070) << "Window::isSafeScript: active part has no document!" << endl;
01043     return false;
01044   }
01045   DOM::DOMString actDomain = actDocument.domain();
01046   DOM::DOMString thisDomain = thisDocument.domain();
01047 
01048   if ( actDomain == thisDomain ) {
01049 #ifdef KJS_VERBOSE
01050     //kdDebug(6070) << "JavaScript: access granted, domain is '" << actDomain.string() << "'" << endl;
01051 #endif
01052     return true;
01053   }
01054 
01055   kdDebug(6070) << "WARNING: JavaScript: access denied for current frame '" << actDomain.string() << "' to frame '" << thisDomain.string() << "'" << endl;
01056   // TODO after 3.1: throw security exception (exec->setException())
01057   return false;
01058 }
01059 
01060 void Window::setListener(ExecState *exec, int eventId, Value func)
01061 {
01062   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01063   if (!part || !isSafeScript(exec))
01064     return;
01065   DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(part->htmlDocument().handle());
01066   if (!doc)
01067     return;
01068 
01069   doc->setHTMLWindowEventListener(eventId,getJSEventListener(func,true));
01070 }
01071 
01072 Value Window::getListener(ExecState *exec, int eventId) const
01073 {
01074   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01075   if (!part || !isSafeScript(exec))
01076     return Undefined();
01077   DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(part->htmlDocument().handle());
01078   if (!doc)
01079     return Undefined();
01080 
01081   DOM::EventListener *listener = doc->getHTMLWindowEventListener(eventId);
01082   if (listener && static_cast<JSEventListener*>(listener)->listenerObjImp())
01083     return static_cast<JSEventListener*>(listener)->listenerObj();
01084   else
01085     return Null();
01086 }
01087 
01088 
01089 JSEventListener *Window::getJSEventListener(const Value& val, bool html)
01090 {
01091   // This function is so hot that it's worth coding it directly with imps.
01092   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01093   if (!part || val.type() != ObjectType)
01094     return 0;
01095 
01096   // It's ObjectType, so it must be valid.
01097   Object listenerObject = Object::dynamicCast(val);
01098   ObjectImp *listenerObjectImp = listenerObject.imp();
01099 
01100   // 'listener' is not a simple ecma function. (Always use sanity checks: Better safe than sorry!)
01101   if (!listenerObject.implementsCall() && part && part->jScript() && part->jScript()->interpreter())
01102   {
01103     Interpreter *interpreter = part->jScript()->interpreter();
01104 
01105     // 'listener' probably is an EventListener object containing a 'handleEvent' function.
01106     Value handleEventValue = listenerObject.get(interpreter->globalExec(), Identifier("handleEvent"));
01107     Object handleEventObject = Object::dynamicCast(handleEventValue);
01108 
01109     if(handleEventObject.isValid() && handleEventObject.implementsCall())
01110     {
01111       listenerObject = handleEventObject;
01112       listenerObjectImp = handleEventObject.imp();
01113     }
01114   }
01115 
01116   JSEventListener *existingListener = jsEventListeners[listenerObjectImp];
01117   if (existingListener)
01118     return existingListener;
01119 
01120   // Note that the JSEventListener constructor adds it to our jsEventListeners list
01121   return new JSEventListener(listenerObject, listenerObjectImp, Object(this), html);
01122 }
01123 
01124 JSLazyEventListener *Window::getJSLazyEventListener(const QString& code, const QString& name, bool html)
01125 {
01126   return new JSLazyEventListener(code, name, Object(this), html);
01127 }
01128 
01129 void Window::clear( ExecState *exec )
01130 {
01131   delete winq;
01132   winq = 0L;
01133   // Get rid of everything, those user vars could hold references to DOM nodes
01134   deleteAllProperties( exec );
01135 
01136   // Break the dependency between the listeners and their object
01137   QPtrDictIterator<JSEventListener> it(jsEventListeners);
01138   for (; it.current(); ++it)
01139     it.current()->clear();
01140   // Forget about the listeners (the DOM::NodeImpls will delete them)
01141   jsEventListeners.clear();
01142 
01143   if (m_frame) {
01144     KJSProxy* proxy = m_frame->m_jscript;
01145     if (proxy) // i.e. JS not disabled
01146     {
01147       winq = new WindowQObject(this);
01148       // Now recreate a working global object for the next URL that will use us
01149       KJS::Interpreter *interpreter = proxy->interpreter();
01150       interpreter->initGlobalObject();
01151     }
01152   }
01153 }
01154 
01155 void Window::setCurrentEvent( DOM::Event *evt )
01156 {
01157   m_evt = evt;
01158   //kdDebug(6070) << "Window " << this << " (part=" << m_part << ")::setCurrentEvent m_evt=" << evt << endl;
01159 }
01160 
01161 void Window::goURL(ExecState* exec, const QString& url, bool lockHistory)
01162 {
01163   Window* active = Window::retrieveActive(exec);
01164   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01165   KHTMLPart *active_part = ::qt_cast<KHTMLPart *>(active->part());
01166   // Complete the URL using the "active part" (running interpreter)
01167   if (active_part && part) {
01168     if (url[0] == QChar('#')) {
01169       part->gotoAnchor(url.mid(1));
01170     } else {
01171       QString dstUrl = active_part->htmlDocument().completeURL(url).string();
01172       KURL dst( dstUrl );
01173       KURL partURL( part->url() );
01174       // Remove refs for the comparison
01175       dst.setRef( QString::null );
01176       partURL.setRef( QString::null );
01177       kdDebug(6070) << "Window::goURL dstUrl=" << dst.prettyURL() << " partURL=" << partURL.prettyURL()
01178                    << " identical: " << partURL.equals( dst, true ) << endl;
01179 
01180       // check if we're allowed to inject javascript
01181       // SYNC check with khtml_part.cpp::slotRedirect!
01182       if ( isSafeScript(exec) ||
01183             dstUrl.find(QString::fromLatin1("javascript:"), 0, false) != 0 )
01184           part->scheduleRedirection(-1,
01185                                 dstUrl,
01186                                   lockHistory);
01187     }
01188   } else if (!part && !m_frame->m_part.isNull()) {
01189     KParts::BrowserExtension *b = KParts::BrowserExtension::childObject(m_frame->m_part);
01190     if (b)
01191       b->emit openURLRequest(m_frame->m_frame->element()->getDocument()->completeURL(url));
01192     kdDebug() << "goURL for ROPart" << endl;
01193   }
01194 }
01195 
01196 KParts::ReadOnlyPart *Window::part() const {
01197     return m_frame.isNull() ? 0L : static_cast<KParts::ReadOnlyPart *>(m_frame->m_part);
01198 }
01199 
01200 void Window::delayedGoHistory( int steps )
01201 {
01202     m_delayed.append( DelayedAction( DelayedGoHistory, steps ) );
01203 }
01204 
01205 void Window::goHistory( int steps )
01206 {
01207   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01208   if(!part)
01209       // TODO history readonlypart
01210     return;
01211   KParts::BrowserExtension *ext = part->browserExtension();
01212   if(!ext)
01213     return;
01214   KParts::BrowserInterface *iface = ext->browserInterface();
01215 
01216   if ( !iface )
01217     return;
01218 
01219   iface->callMethod( "goHistory(int)", steps );
01220   //emit ext->goHistory(steps);
01221 }
01222 
01223 void KJS::Window::resizeTo(QWidget* tl, int width, int height)
01224 {
01225   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01226   if(!part)
01227       // TODO resizeTo readonlypart
01228     return;
01229   KParts::BrowserExtension *ext = part->browserExtension();
01230   if (!ext) {
01231     kdDebug(6070) << "Window::resizeTo found no browserExtension" << endl;
01232     return;
01233   }
01234 
01235   // Security check: within desktop limits and bigger than 100x100 (per spec)
01236   if ( width < 100 || height < 100 ) {
01237     kdDebug(6070) << "Window::resizeTo refused, window would be too small ("<<width<<","<<height<<")" << endl;
01238     return;
01239   }
01240 
01241   QRect sg = KGlobalSettings::desktopGeometry(tl);
01242 
01243   if ( width > sg.width() || height > sg.height() ) {
01244     kdDebug(6070) << "Window::resizeTo refused, window would be too big ("<<width<<","<<height<<")" << endl;
01245     return;
01246   }
01247 
01248   kdDebug(6070) << "resizing to " << width << "x" << height << endl;
01249 
01250   emit ext->resizeTopLevelWidget( width, height );
01251 
01252   // If the window is out of the desktop, move it up/left
01253   // (maybe we should use workarea instead of sg, otherwise the window ends up below kicker)
01254   int right = tl->x() + tl->frameGeometry().width();
01255   int bottom = tl->y() + tl->frameGeometry().height();
01256   int moveByX = 0;
01257   int moveByY = 0;
01258   if ( right > sg.right() )
01259     moveByX = - right + sg.right(); // always <0
01260   if ( bottom > sg.bottom() )
01261     moveByY = - bottom + sg.bottom(); // always <0
01262   if ( moveByX || moveByY )
01263     emit ext->moveTopLevelWidget( tl->x() + moveByX , tl->y() + moveByY );
01264 }
01265 
01266 Value Window::openWindow(ExecState *exec, const List& args)
01267 {
01268   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01269   if (!part)
01270     return Undefined();
01271   KHTMLView *widget = part->view();
01272   Value v = args[0];
01273   QString str = v.toString(exec).qstring();
01274 
01275   // prepare arguments
01276   KURL url;
01277   if (!str.isEmpty())
01278   {
01279     KHTMLPart* p = ::qt_cast<KHTMLPart *>(Window::retrieveActive(exec)->m_frame->m_part);
01280     if ( p )
01281       url = p->htmlDocument().completeURL(str).string();
01282     if ( !p ||
01283          !static_cast<DOM::DocumentImpl*>(p->htmlDocument().handle())->isURLAllowed(url.url()) )
01284       return Undefined();
01285   }
01286 
01287   KHTMLSettings::KJSWindowOpenPolicy policy =
01288         part->settings()->windowOpenPolicy(part->url().host());
01289   if ( policy == KHTMLSettings::KJSWindowOpenAsk ) {
01290     emit part->browserExtension()->requestFocus(part);
01291     QString caption;
01292     if (!part->url().host().isEmpty())
01293       caption = part->url().host() + " - ";
01294     caption += i18n( "Confirmation: JavaScript Popup" );
01295     if ( KMessageBox::questionYesNo(widget,
01296                                     str.isEmpty() ?
01297                                     i18n( "This site is requesting to open up a new browser "
01298                                           "window via JavaScript.\n"
01299                                           "Do you want to allow this?" ) :
01300                                     i18n( "<qt>This site is requesting to open<p>%1</p>in a new browser window via JavaScript.<br />"
01301                                           "Do you want to allow this?</qt>").arg(KStringHandler::csqueeze(url.htmlURL(),  100)),
01302                                     caption ) == KMessageBox::Yes )
01303       policy = KHTMLSettings::KJSWindowOpenAllow;
01304   } else if ( policy == KHTMLSettings::KJSWindowOpenSmart )
01305   {
01306     // window.open disabled unless from a key/mouse event
01307     if (static_cast<ScriptInterpreter *>(exec->interpreter())->isWindowOpenAllowed())
01308       policy = KHTMLSettings::KJSWindowOpenAllow;
01309   }
01310   if ( policy != KHTMLSettings::KJSWindowOpenAllow ) {
01311     return Undefined();
01312   } else {
01313     KParts::WindowArgs winargs;
01314 
01315     // scan feature argument
01316     QString features;
01317     if (args.size()>2) {
01318       features = args[2].toString(exec).qstring();
01319       // specifying window params means false defaults
01320       winargs.menuBarVisible = false;
01321       winargs.toolBarsVisible = false;
01322       winargs.statusBarVisible = false;
01323       QStringList flist = QStringList::split(',', features);
01324       QStringList::ConstIterator it = flist.begin();
01325       while (it != flist.end()) {
01326         QString s = *it++;
01327         QString key, val;
01328         int pos = s.find('=');
01329         if (pos >= 0) {
01330           key = s.left(pos).stripWhiteSpace().lower();
01331           val = s.mid(pos + 1).stripWhiteSpace().lower();
01332           QRect screen = KGlobalSettings::desktopGeometry(widget->topLevelWidget());
01333 
01334           if (key == "left" || key == "screenx") {
01335             winargs.x = (int)val.toFloat() + screen.x();
01336             if (winargs.x < screen.x() || winargs.x > screen.right())
01337               winargs.x = screen.x(); // only safe choice until size is determined
01338           } else if (key == "top" || key == "screeny") {
01339             winargs.y = (int)val.toFloat() + screen.y();
01340             if (winargs.y < screen.y() || winargs.y > screen.bottom())
01341               winargs.y = screen.y(); // only safe choice until size is determined
01342           } else if (key == "height") {
01343             winargs.height = (int)val.toFloat() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
01344             if (winargs.height > screen.height())  // should actually check workspace
01345               winargs.height = screen.height();
01346             if (winargs.height < 100)
01347               winargs.height = 100;
01348           } else if (key == "width") {
01349             winargs.width = (int)val.toFloat() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
01350             if (winargs.width > screen.width())    // should actually check workspace
01351               winargs.width = screen.width();
01352             if (winargs.width < 100)
01353               winargs.width = 100;
01354           } else {
01355             goto boolargs;
01356           }
01357           continue;
01358         } else {
01359           // leaving away the value gives true
01360           key = s.stripWhiteSpace().lower();
01361           val = "1";
01362         }
01363       boolargs:
01364         if (key == "menubar")
01365           winargs.menuBarVisible = (val == "1" || val == "yes");
01366         else if (key == "toolbar")
01367           winargs.toolBarsVisible = (val == "1" || val == "yes");
01368         else if (key == "location")  // ### missing in WindowArgs
01369           winargs.toolBarsVisible = (val == "1" || val == "yes");
01370         else if (key == "status" || key == "statusbar")
01371           winargs.statusBarVisible = (val == "1" || val == "yes");
01372         else if (key == "resizable")
01373           winargs.resizable = (val == "1" || val == "yes");
01374         else if (key == "fullscreen")
01375           winargs.fullscreen = (val == "1" || val == "yes");
01376       }
01377     }
01378 
01379     KParts::URLArgs uargs;
01380     KHTMLPart *p = part;
01381     uargs.frameName = args.size() > 1 ?
01382                       args[1].toString(exec).qstring()
01383                       : QString("_blank");
01384     if ( uargs.frameName.lower() == "_top" )
01385     {
01386       while ( p->parentPart() )
01387         p = p->parentPart();
01388       Window::retrieveWindow(p)->goURL(exec, url.url(), false /*don't lock history*/);
01389       return Window::retrieve(p);
01390     }
01391     if ( uargs.frameName.lower() == "_parent" )
01392     {
01393       if ( p->parentPart() )
01394         p = p->parentPart();
01395       Window::retrieveWindow(p)->goURL(exec, url.url(), false /*don't lock history*/);
01396       return Window::retrieve(p);
01397     }
01398     if ( uargs.frameName.lower() == "_self")
01399     {
01400       Window::retrieveWindow(p)->goURL(exec, url.url(), false /*don't lock history*/);
01401       return Window::retrieve(p);
01402     }
01403     if ( uargs.frameName.lower() == "replace" )
01404     {
01405       Window::retrieveWindow(p)->goURL(exec, url.url(), true /*lock history*/);
01406       return Window::retrieve(p);
01407     }
01408     uargs.serviceType = "text/html";
01409 
01410     // request window (new or existing if framename is set)
01411     KParts::ReadOnlyPart *newPart = 0L;
01412     emit p->browserExtension()->createNewWindow(KURL(), uargs,winargs,newPart);
01413     if (newPart && ::qt_cast<KHTMLPart*>(newPart)) {
01414       KHTMLPart *khtmlpart = static_cast<KHTMLPart*>(newPart);
01415       //qDebug("opener set to %p (this Window's part) in new Window %p  (this Window=%p)",part,win,window);
01416       khtmlpart->setOpener(p);
01417       khtmlpart->setOpenedByJS(true);
01418       if (khtmlpart->document().isNull()) {
01419         khtmlpart->begin();
01420         khtmlpart->write("<HTML><BODY>");
01421         khtmlpart->end();
01422         if ( p->docImpl() ) {
01423           //kdDebug(6070) << "Setting domain to " << p->docImpl()->domain().string() << endl;
01424           khtmlpart->docImpl()->setDomain( p->docImpl()->domain());
01425           khtmlpart->docImpl()->setBaseURL( p->docImpl()->baseURL() );
01426         }
01427       }
01428       uargs.serviceType = QString::null;
01429       if (uargs.frameName.lower() == "_blank")
01430         uargs.frameName = QString::null;
01431       if (!url.isEmpty())
01432         emit khtmlpart->browserExtension()->openURLRequest(url,uargs);
01433       return Window::retrieve(khtmlpart); // global object
01434     } else
01435       return Undefined();
01436   }
01437 }
01438 
01439 Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01440 {
01441   KJS_CHECK_THIS( Window, thisObj );
01442   Window *window = static_cast<Window *>(thisObj.imp());
01443   QString str, str2;
01444 
01445   KHTMLPart *part = ::qt_cast<KHTMLPart *>(window->m_frame->m_part);
01446   if (!part)
01447     return Undefined();
01448 
01449   KHTMLView *widget = part->view();
01450   Value v = args[0];
01451   UString s = v.toString(exec);
01452   str = s.qstring();
01453 
01454   QString caption;
01455   if (part && !part->url().host().isEmpty())
01456     caption = part->url().host() + " - ";
01457   caption += "JavaScript"; // TODO: i18n
01458   // functions that work everywhere
01459   switch(id) {
01460   case Window::Alert:
01461     if (!widget->dialogsAllowed())
01462       return Undefined();
01463     if ( part && part->xmlDocImpl() )
01464       part->xmlDocImpl()->updateRendering();
01465     if ( part )
01466       emit part->browserExtension()->requestFocus(part);
01467     KMessageBox::error(widget, str, caption);
01468     return Undefined();
01469   case Window::Confirm:
01470     if (!widget->dialogsAllowed())
01471       return Undefined();
01472     if ( part && part->xmlDocImpl() )
01473       part->xmlDocImpl()->updateRendering();
01474     if ( part )
01475       emit part->browserExtension()->requestFocus(part);
01476     return Boolean((KMessageBox::warningYesNo(widget, str, caption,
01477                                                 KStdGuiItem::ok(), KStdGuiItem::cancel()) == KMessageBox::Yes));
01478   case Window::Prompt:
01479     if (!widget->dialogsAllowed())
01480       return Undefined();
01481     if ( part && part->xmlDocImpl() )
01482       part->xmlDocImpl()->updateRendering();
01483     if ( part )
01484       emit part->browserExtension()->requestFocus(part);
01485     bool ok;
01486     if (args.size() >= 2)
01487       str2 = KInputDialog::getText(caption,
01488                                    QStyleSheet::convertFromPlainText(str),
01489                                    args[1].toString(exec).qstring(), &ok, widget);
01490     else
01491       str2 = KInputDialog::getText(caption,
01492                                    QStyleSheet::convertFromPlainText(str),
01493                                    QString::null, &ok, widget);
01494     if ( ok )
01495         return String(str2);
01496     else
01497         return Null();
01498   case Window::Open:
01499     return window->openWindow(exec, args);
01500   case Window::Navigate:
01501     window->goURL(exec, args[0].toString(exec).qstring(), false /*don't lock history*/);
01502     return Undefined();
01503   case Window::Focus: {
01504     KHTMLSettings::KJSWindowFocusPolicy policy =
01505         part->settings()->windowFocusPolicy(part->url().host());
01506     if(policy == KHTMLSettings::KJSWindowFocusAllow && widget) {
01507       widget->topLevelWidget()->raise();
01508       KWin::deIconifyWindow( widget->topLevelWidget()->winId() );
01509       widget->setActiveWindow();
01510       emit part->browserExtension()->requestFocus(part);
01511     }
01512     return Undefined();
01513   }
01514   case Window::Blur:
01515     // TODO
01516     return Undefined();
01517   };
01518 
01519 
01520   // now unsafe functions..
01521   if (!window->isSafeScript(exec))
01522     return Undefined();
01523 
01524   switch (id) {
01525   case Window::ScrollBy:
01526     if(args.size() == 2 && widget)
01527       widget->scrollBy(args[0].toInt32(exec), args[1].toInt32(exec));
01528     return Undefined();
01529   case Window::Scroll:
01530   case Window::ScrollTo:
01531     if(args.size() == 2 && widget)
01532       widget->setContentsPos(args[0].toInt32(exec), args[1].toInt32(exec));
01533     return Undefined();
01534   case Window::MoveBy: {
01535     KHTMLSettings::KJSWindowMovePolicy policy =
01536         part->settings()->windowMovePolicy(part->url().host());
01537     if(policy == KHTMLSettings::KJSWindowMoveAllow && args.size() == 2 && widget)
01538     {
01539       KParts::BrowserExtension *ext = part->browserExtension();
01540       if (ext) {
01541         QWidget * tl = widget->topLevelWidget();
01542         QRect sg = KGlobalSettings::desktopGeometry(tl);
01543 
01544         QPoint dest = tl->pos() + QPoint( args[0].toInt32(exec), args[1].toInt32(exec) );
01545         // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
01546         if ( dest.x() >= sg.x() && dest.y() >= sg.x() &&
01547              dest.x()+tl->width() <= sg.width()+sg.x() &&
01548              dest.y()+tl->height() <= sg.height()+sg.y() )
01549           emit ext->moveTopLevelWidget( dest.x(), dest.y() );
01550       }
01551     }
01552     return Undefined();
01553   }
01554   case Window::MoveTo: {
01555     KHTMLSettings::KJSWindowMovePolicy policy =
01556         part->settings()->windowMovePolicy(part->url().host());
01557     if(policy == KHTMLSettings::KJSWindowMoveAllow && args.size() == 2 && widget)
01558     {
01559       KParts::BrowserExtension *ext = part->browserExtension();
01560       if (ext) {
01561         QWidget * tl = widget->topLevelWidget();
01562         QRect sg = KGlobalSettings::desktopGeometry(tl);
01563 
01564         QPoint dest( args[0].toInt32(exec)+sg.x(), args[1].toInt32(exec)+sg.y() );
01565         // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
01566         if ( dest.x() >= sg.x() && dest.y() >= sg.y() &&
01567              dest.x()+tl->width() <= sg.width()+sg.x() &&
01568              dest.y()+tl->height() <= sg.height()+sg.y() )
01569         emit ext->moveTopLevelWidget( dest.x(), dest.y() );
01570       }
01571     }
01572     return Undefined();
01573   }
01574   case Window::ResizeBy: {
01575     KHTMLSettings::KJSWindowResizePolicy policy =
01576         part->settings()->windowResizePolicy(part->url().host());
01577     if(policy == KHTMLSettings::KJSWindowResizeAllow
01578             && args.size() == 2 && widget)
01579     {
01580       QWidget * tl = widget->topLevelWidget();
01581       QRect geom = tl->frameGeometry();
01582       window->resizeTo( tl,
01583                         geom.width() + args[0].toInt32(exec),
01584                         geom.height() + args[1].toInt32(exec) );
01585     }
01586     return Undefined();
01587   }
01588   case Window::ResizeTo: {
01589     KHTMLSettings::KJSWindowResizePolicy policy =
01590                part->settings()->windowResizePolicy(part->url().host());
01591     if(policy == KHTMLSettings::KJSWindowResizeAllow
01592                && args.size() == 2 && widget)
01593     {
01594       QWidget * tl = widget->topLevelWidget();
01595       window->resizeTo( tl, args[0].toInt32(exec), args[1].toInt32(exec) );
01596     }
01597     return Undefined();
01598   }
01599   case Window::SetTimeout:
01600   case Window::SetInterval: {
01601     bool singleShot;
01602     int i; // timeout interval
01603     if (args.size() == 0)
01604       return Undefined();
01605     if (args.size() > 1) {
01606       singleShot = (id == Window::SetTimeout);
01607       i = args[1].toInt32(exec);
01608     } else {
01609       // second parameter is missing. Emulate Mozilla behavior.
01610       singleShot = true;
01611       i = 4;
01612     }
01613     if (v.isA(StringType)) {
01614       int r = (const_cast<Window*>(window))->winq->installTimeout(Identifier(s), i, singleShot );
01615       return Number(r);
01616     }
01617     else if (v.isA(ObjectType) && Object::dynamicCast(v).implementsCall()) {
01618       Object func = Object::dynamicCast(v);
01619       List funcArgs;
01620       ListIterator it = args.begin();
01621       int argno = 0;
01622       while (it != args.end()) {
01623     Value arg = it++;
01624     if (argno++ >= 2)
01625         funcArgs.append(arg);
01626       }
01627       if (args.size() < 2)
01628     funcArgs.append(Number(i));
01629       int r = (const_cast<Window*>(window))->winq->installTimeout(func, funcArgs, i, singleShot );
01630       return Number(r);
01631     }
01632     else
01633       return Undefined();
01634   }
01635   case Window::ClearTimeout:
01636   case Window::ClearInterval:
01637     (const_cast<Window*>(window))->winq->clearTimeout(v.toInt32(exec));
01638     return Undefined();
01639   case Window::Close: {
01640     /* From http://developer.netscape.com/docs/manuals/js/client/jsref/window.htm :
01641        The close method closes only windows opened by JavaScript using the open method.
01642        If you attempt to close any other window, a confirm is generated, which
01643        lets the user choose whether the window closes.
01644        This is a security feature to prevent "mail bombs" containing self.close().
01645        However, if the window has only one document (the current one) in its
01646        session history, the close is allowed without any confirm. This is a
01647        special case for one-off windows that need to open other windows and
01648        then dispose of themselves.
01649     */
01650     bool doClose = false;
01651     if (!part->openedByJS())
01652     {
01653       // To conform to the SPEC, we only ask if the window
01654       // has more than one entry in the history (NS does that too).
01655       History history(exec,part);
01656 
01657       if ( history.get( exec, "length" ).toInt32(exec) <= 1 )
01658       {
01659         doClose = true;
01660       }
01661       else
01662       {
01663         // Can we get this dialog with tabs??? Does it close the window or the tab in that case?
01664         emit part->browserExtension()->requestFocus(part);
01665         if ( KMessageBox::questionYesNo( window->part()->widget(), i18n("Close window?"), i18n("Confirmation Required") )
01666              == KMessageBox::Yes )
01667           doClose = true;
01668       }
01669     }
01670     else
01671       doClose = true;
01672 
01673     if (doClose)
01674     {
01675       // If this is the current window (the one the interpreter runs in),
01676       // then schedule a delayed close (so that the script terminates first).
01677       // But otherwise, close immediately. This fixes w=window.open("","name");w.close();window.open("name");
01678       if ( Window::retrieveActive(exec) == window ) {
01679         if (widget) {
01680           // quit all dialogs of this view
01681           // this fixes 'setTimeout('self.close()',1000); alert("Hi");' crash
01682           widget->closeChildDialogs();
01683         }
01684         //kdDebug() << "scheduling delayed close"  << endl;
01685         // We'll close the window at the end of the script execution
01686         Window* w = const_cast<Window*>(window);
01687         w->m_delayed.append( Window::DelayedAction( Window::DelayedClose ) );
01688       } else {
01689         //kdDebug() << "closing NOW"  << endl;
01690         (const_cast<Window*>(window))->closeNow();
01691       }
01692     }
01693     return Undefined();
01694   }
01695   case Window::Print:
01696     if ( widget ) {
01697       // ### TODO emit onbeforeprint event
01698       widget->print();
01699       // ### TODO emit onafterprint event
01700     }
01701   case Window::CaptureEvents:
01702   case Window::ReleaseEvents:
01703     // Do nothing for now. These are NS-specific legacy calls.
01704     break;
01705   case Window::AddEventListener: {
01706         JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
01707         if (listener) {
01708         DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
01709             docimpl->addWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
01710         }
01711         return Undefined();
01712     }
01713   case Window::RemoveEventListener: {
01714         JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
01715         if (listener) {
01716         DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
01717             docimpl->removeWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
01718         }
01719         return Undefined();
01720     }
01721 
01722   }
01723   return Undefined();
01724 }
01725 
01727 
01728 // KDE 4: Make those parameters const ... &
01729 ScheduledAction::ScheduledAction(Object _func, List _args, QTime _nextTime, int _interval, bool _singleShot,
01730                   int _timerId)
01731 {
01732   //kdDebug(6070) << "ScheduledAction::ScheduledAction(isFunction) " << this << endl;
01733   func = static_cast<ObjectImp*>(_func.imp());
01734   args = _args;
01735   isFunction = true;
01736   singleShot = _singleShot;
01737   nextTime = _nextTime;
01738   interval = _interval;
01739   executing = false;
01740   timerId = _timerId;
01741 }
01742 
01743 // KDE 4: Make it const QString &
01744 ScheduledAction::ScheduledAction(QString _code, QTime _nextTime, int _interval, bool _singleShot, int _timerId)
01745 {
01746   //kdDebug(6070) << "ScheduledAction::ScheduledAction(!isFunction) " << this << endl;
01747   //func = 0;
01748   //args = 0;
01749   func = 0;
01750   code = _code;
01751   isFunction = false;
01752   singleShot = _singleShot;
01753   nextTime = _nextTime;
01754   interval = _interval;
01755   executing = false;
01756   timerId = _timerId;
01757 }
01758 
01759 bool ScheduledAction::execute(Window *window)
01760 {
01761   KHTMLPart *part = ::qt_cast<KHTMLPart *>(window->m_frame->m_part);
01762   if (!part || !part->jScriptEnabled())
01763     return false;
01764   ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(part->jScript()->interpreter());
01765 
01766   interpreter->setProcessingTimerCallback(true);
01767 
01768   //kdDebug(6070) << "ScheduledAction::execute " << this << endl;
01769   if (isFunction) {
01770     if (func->implementsCall()) {
01771       // #### check this
01772       Q_ASSERT( part );
01773       if ( part )
01774       {
01775         KJS::Interpreter *interpreter = part->jScript()->interpreter();
01776         ExecState *exec = interpreter->globalExec();
01777         Q_ASSERT( window == interpreter->globalObject().imp() );
01778         Object obj( window );
01779         func->call(exec,obj,args); // note that call() creates its own execution state for the func call
01780         if (exec->hadException())
01781           exec->clearException();
01782 
01783         // Update our document's rendering following the execution of the timeout callback.
01784         part->document().updateRendering();
01785       }
01786     }
01787   }
01788   else {
01789     part->executeScript(DOM::Node(), code);
01790   }
01791 
01792   interpreter->setProcessingTimerCallback(false);
01793   return true;
01794 }
01795 
01796 void ScheduledAction::mark()
01797 {
01798   if (func && !func->marked())
01799     func->mark();
01800   args.mark();
01801 }
01802 
01803 ScheduledAction::~ScheduledAction()
01804 {
01805   //kdDebug(6070) << "ScheduledAction::~ScheduledAction " << this << endl;
01806 }
01807 
01809 
01810 WindowQObject::WindowQObject(Window *w)
01811   : parent(w)
01812 {
01813   //kdDebug(6070) << "WindowQObject::WindowQObject " << this << endl;
01814   if ( !parent->m_frame )
01815       kdDebug(6070) << "WARNING: null part in " << k_funcinfo << endl;
01816   else
01817       connect( parent->m_frame, SIGNAL( destroyed() ),
01818                this, SLOT( parentDestroyed() ) );
01819   pausedTime = 0;
01820   lastTimerId = 0;
01821 }
01822 
01823 WindowQObject::~WindowQObject()
01824 {
01825   //kdDebug(6070) << "WindowQObject::~WindowQObject " << this << endl;
01826   parentDestroyed(); // reuse same code
01827 }
01828 
01829 void WindowQObject::parentDestroyed()
01830 {
01831   killTimers();
01832 
01833   QPtrListIterator<ScheduledAction> it(scheduledActions);
01834   for (; it.current(); ++it)
01835     delete it.current();
01836   scheduledActions.clear();
01837 }
01838 
01839 int WindowQObject::installTimeout(const Identifier &handler, int t, bool singleShot)
01840 {
01841   int id = ++lastTimerId;
01842   if (t < 10) t = 10;
01843   QTime nextTime = QTime::currentTime().addMSecs(-pausedTime).addMSecs(t);
01844   ScheduledAction *action = new ScheduledAction(handler.qstring(),nextTime,t,singleShot,id);
01845   scheduledActions.append(action);
01846   setNextTimer();
01847   return id;
01848 }
01849 
01850 int WindowQObject::installTimeout(const Value &func, List args, int t, bool singleShot)
01851 {
01852   Object objFunc = Object::dynamicCast( func );
01853   if (!objFunc.isValid())
01854     return 0;
01855   int id = ++lastTimerId;
01856   if (t < 10) t = 10;
01857   QTime nextTime = QTime::currentTime().addMSecs(-pausedTime).addMSecs(t);
01858   ScheduledAction *action = new ScheduledAction(objFunc,args,nextTime,t,singleShot,id);
01859   scheduledActions.append(action);
01860   setNextTimer();
01861   return id;
01862 }
01863 
01864 void WindowQObject::clearTimeout(int timerId)
01865 {
01866   QPtrListIterator<ScheduledAction> it(scheduledActions);
01867   for (; it.current(); ++it) {
01868     ScheduledAction *action = it.current();
01869     if (action->timerId == timerId) {
01870       scheduledActions.removeRef(action);
01871       if (!action->executing)
01872     delete action;
01873       return;
01874     }
01875   }
01876 }
01877 
01878 bool WindowQObject::hasTimers() const
01879 {
01880   return scheduledActions.count();
01881 }
01882 
01883 void WindowQObject::mark()
01884 {
01885   QPtrListIterator<ScheduledAction> it(scheduledActions);
01886   for (; it.current(); ++it)
01887     it.current()->mark();
01888 }
01889 
01890 void WindowQObject::timerEvent(QTimerEvent *)
01891 {
01892   killTimers();
01893 
01894   if (scheduledActions.isEmpty())
01895     return;
01896 
01897   QTime currentActual = QTime::currentTime();
01898   QTime currentAdjusted = currentActual.addMSecs(-pausedTime);
01899 
01900   // Work out which actions are to be executed. We take a separate copy of
01901   // this list since the main one may be modified during action execution
01902   QPtrList<ScheduledAction> toExecute;
01903   QPtrListIterator<ScheduledAction> it(scheduledActions);
01904   for (; it.current(); ++it)
01905     if (currentAdjusted >= it.current()->nextTime)
01906       toExecute.append(it.current());
01907 
01908   // ### verify that the window can't be closed (and action deleted) during execution
01909   it = QPtrListIterator<ScheduledAction>(toExecute);
01910   for (; it.current(); ++it) {
01911     ScheduledAction *action = it.current();
01912     if (!scheduledActions.containsRef(action)) // removed by clearTimeout()
01913       continue;
01914 
01915     action->executing = true; // prevent deletion in clearTimeout()
01916 
01917     if (action->singleShot)
01918       scheduledActions.removeRef(action);
01919     if (parent->part()) {
01920       bool ok = action->execute(parent);
01921       if ( !ok ) // e.g. JS disabled
01922         scheduledActions.removeRef( action );
01923     }
01924             
01925     action->executing = false;
01926 
01927     if (!scheduledActions.containsRef(action))
01928       delete action;
01929     else
01930       action->nextTime = action->nextTime.addMSecs(action->interval);
01931   }
01932 
01933   pausedTime += currentActual.msecsTo(QTime::currentTime());
01934 
01935   // Work out when next event is to occur
01936   setNextTimer();
01937 }
01938 
01939 void WindowQObject::setNextTimer()
01940 {
01941   if (scheduledActions.isEmpty())
01942     return;
01943 
01944   QPtrListIterator<ScheduledAction> it(scheduledActions);
01945   QTime nextTime = it.current()->nextTime;
01946   for (++it; it.current(); ++it)
01947     if (nextTime > it.current()->nextTime)
01948       nextTime = it.current()->nextTime;
01949 
01950   QTime nextTimeActual = nextTime.addMSecs(pausedTime);
01951   int nextInterval = QTime::currentTime().msecsTo(nextTimeActual);
01952   if (nextInterval < 0)
01953     nextInterval = 0;
01954   startTimer(nextInterval);
01955 }
01956 
01957 void WindowQObject::timeoutClose()
01958 {
01959   parent->closeNow();
01960 }
01961 
01962 Value FrameArray::get(ExecState *exec, const Identifier &p) const
01963 {
01964 #ifdef KJS_VERBOSE
01965   kdDebug(6070) << "FrameArray::get " << p.qstring() << " part=" << (void*)part << endl;
01966 #endif
01967   if (part.isNull())
01968     return Undefined();
01969 
01970   QPtrList<KParts::ReadOnlyPart> frames = part->frames();
01971   unsigned int len = frames.count();
01972   if (p == lengthPropertyName)
01973     return Number(len);
01974   else if (p== "location") // non-standard property, but works in NS and IE
01975   {
01976     Object obj = Object::dynamicCast( Window::retrieve( part ) );
01977     if ( !obj.isNull() )
01978       return obj.get( exec, "location" );
01979     return Undefined();
01980   }
01981 
01982   // check for the name or number
01983   KParts::ReadOnlyPart *frame = part->findFramePart(p.qstring());
01984   if (!frame) {
01985     bool ok;
01986     unsigned int i = p.toArrayIndex(&ok);
01987     if (ok && i < len)
01988       frame = frames.at(i);
01989   }
01990 
01991   // we are potentially fetching a reference to a another Window object here.
01992   // i.e. we may be accessing objects from another interpreter instance.
01993   // Therefore we have to be a bit careful with memory management.
01994   if (frame) {
01995     return Window::retrieve(frame);
01996   }
01997 
01998   return ObjectImp::get(exec, p);
01999 }
02000 
02002 
02003 const ClassInfo Location::info = { "Location", 0, &LocationTable, 0 };
02004 /*
02005 @begin LocationTable 11
02006   hash      Location::Hash      DontDelete
02007   host      Location::Host      DontDelete
02008   hostname  Location::Hostname  DontDelete
02009   href      Location::Href      DontDelete
02010   pathname  Location::Pathname  DontDelete
02011   port      Location::Port      DontDelete
02012   protocol  Location::Protocol  DontDelete
02013   search    Location::Search    DontDelete
02014   [[==]]    Location::EqualEqual    DontDelete|ReadOnly
02015   assign    Location::Assign    DontDelete|Function 1
02016   toString  Location::ToString  DontDelete|Function 0
02017   replace   Location::Replace   DontDelete|Function 1
02018   reload    Location::Reload    DontDelete|Function 0
02019 @end
02020 */
02021 IMPLEMENT_PROTOFUNC_DOM(LocationFunc)
02022 Location::Location(khtml::ChildFrame *f) : m_frame(f)
02023 {
02024   //kdDebug(6070) << "Location::Location " << this << " m_part=" << (void*)m_part << endl;
02025 }
02026 
02027 Location::~Location()
02028 {
02029   //kdDebug(6070) << "Location::~Location " << this << " m_part=" << (void*)m_part << endl;
02030 }
02031 
02032 KParts::ReadOnlyPart *Location::part() const {
02033   return m_frame ? static_cast<KParts::ReadOnlyPart *>(m_frame->m_part) : 0L;
02034 }
02035 
02036 Value Location::get(ExecState *exec, const Identifier &p) const
02037 {
02038 #ifdef KJS_VERBOSE
02039   kdDebug(6070) << "Location::get " << p.qstring() << " m_part=" << (void*)m_frame->m_part << endl;
02040 #endif
02041 
02042   if (m_frame.isNull() || m_frame->m_part.isNull())
02043     return Undefined();
02044 
02045   const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
02046 
02047   // properties that work on all Location objects
02048   if ( entry && entry->value == Replace )
02049       return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
02050 
02051   // XSS check
02052   const Window* window = Window::retrieveWindow( m_frame->m_part );
02053   if ( !window || !window->isSafeScript(exec) )
02054     return Undefined();
02055 
02056   KURL url = m_frame->m_part->url();
02057   if (entry)
02058     switch (entry->value) {
02059     case Hash:
02060       return String( url.ref().isNull() ? QString("") : "#" + url.ref() );
02061     case Host: {
02062       UString str = url.host();
02063       if (url.port())
02064         str += ":" + QString::number((int)url.port());
02065       return String(str);
02066       // Note: this is the IE spec. The NS spec swaps the two, it says
02067       // "The hostname property is the concatenation of the host and port properties, separated by a colon."
02068       // Bleh.
02069     }
02070     case Hostname:
02071       return String( url.host() );
02072     case Href:
02073       if (!url.hasPath())
02074         return String( url.prettyURL()+"/" );
02075       else
02076         return String( url.prettyURL() );
02077     case Pathname:
02078       return String( url.path().isEmpty() ? QString("/") : url.path() );
02079     case Port:
02080       return String( url.port() ? QString::number((int)url.port()) : QString::fromLatin1("") );
02081     case Protocol:
02082       return String( url.protocol()+":" );
02083     case Search:
02084       return String( url.query() );
02085     case EqualEqual: // [[==]]
02086       return String(toString(exec));
02087     case ToString:
02088       return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
02089     }
02090   // Look for overrides
02091   ValueImp * val = ObjectImp::getDirect(p);
02092   if (val)
02093     return Value(val);
02094   if (entry && (entry->attr & Function))
02095     return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
02096 
02097   return Undefined();
02098 }
02099 
02100 void Location::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
02101 {
02102 #ifdef KJS_VERBOSE
02103   kdDebug(6070) << "Location::put " << p.qstring() << " m_part=" << (void*)m_frame->m_part << endl;
02104 #endif
02105   if (m_frame.isNull() || m_frame->m_part.isNull())
02106     return;
02107 
02108   // XSS check
02109   const Window* window = Window::retrieveWindow( m_frame->m_part );
02110   if ( !window || !window->isSafeScript(exec) )
02111     return;
02112 
02113   QString str = v.toString(exec).qstring();
02114   KURL url = m_frame->m_part->url();
02115   const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
02116   if (entry)
02117     switch (entry->value) {
02118     case Href: {
02119       KHTMLPart* p =::qt_cast<KHTMLPart*>(Window::retrieveActive(exec)->part());
02120       if ( p )
02121         url = p->htmlDocument().completeURL( str ).string();
02122       else
02123         url = str;
02124       break;
02125     }
02126     case Hash:
02127       // when the hash is already the same ignore it
02128       if (str == url.ref()) return;
02129       url.setRef(str);
02130       break;
02131     case Host: {
02132       QString host = str.left(str.find(":"));
02133       QString port = str.mid(str.find(":")+1);
02134       url.setHost(host);
02135       url.setPort(port.toUInt());
02136       break;
02137     }
02138     case Hostname:
02139       url.setHost(str);
02140       break;
02141     case Pathname:
02142       url.setPath(str);
02143       break;
02144     case Port:
02145       url.setPort(str.toUInt());
02146       break;
02147     case Protocol:
02148       url.setProtocol(str);
02149       break;
02150     case Search:
02151       url.setQuery(str);
02152       break;
02153     }
02154   else {
02155     ObjectImp::put(exec, p, v, attr);
02156     return;
02157   }
02158 
02159   Window::retrieveWindow(m_frame->m_part)->goURL(exec, url.url(), false /* don't lock history*/ );
02160 }
02161 
02162 Value Location::toPrimitive(ExecState *exec, Type) const
02163 {
02164   if (m_frame) {
02165     Window* window = Window::retrieveWindow( m_frame->m_part );
02166     if ( window && window->isSafeScript(exec) )
02167       return String(toString(exec));
02168   }
02169   return Undefined();
02170 }
02171 
02172 UString Location::toString(ExecState *exec) const
02173 {
02174   if (m_frame) {
02175     Window* window = Window::retrieveWindow( m_frame->m_part );
02176     if ( window && window->isSafeScript(exec) )
02177     {
02178       if (!m_frame->m_part->url().hasPath())
02179         return m_frame->m_part->url().prettyURL()+"/";
02180       else
02181         return m_frame->m_part->url().prettyURL();
02182     }
02183   }
02184   return "";
02185 }
02186 
02187 Value LocationFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
02188 {
02189   KJS_CHECK_THIS( Location, thisObj );
02190   Location *location = static_cast<Location *>(thisObj.imp());
02191   KParts::ReadOnlyPart *part = location->part();
02192 
02193   if (!part) return Undefined();
02194 
02195   Window* window = Window::retrieveWindow(part);
02196 
02197   if ( !window->isSafeScript(exec) && id != Location::Replace)
02198       return Undefined();
02199 
02200   switch (id) {
02201   case Location::Assign:
02202   case Location::Replace:
02203     Window::retrieveWindow(part)->goURL(exec, args[0].toString(exec).qstring(),
02204             id == Location::Replace);
02205     break;
02206   case Location::Reload: {
02207     KHTMLPart *khtmlpart = ::qt_cast<KHTMLPart *>(part);
02208     if (part)
02209       khtmlpart->scheduleRedirection(-1, part->url().url(), true/*lock history*/);
02210     break;
02211   }
02212   case Location::ToString:
02213     return String(location->toString(exec));
02214   }
02215   return Undefined();
02216 }
02217 
02219 
02220 const ClassInfo External::info = { "External", 0, 0, 0 };
02221 /*
02222 @begin ExternalTable 4
02223   addFavorite   External::AddFavorite   DontDelete|Function 1
02224 @end
02225 */
02226 IMPLEMENT_PROTOFUNC_DOM(ExternalFunc)
02227 
02228 Value External::get(ExecState *exec, const Identifier &p) const
02229 {
02230   return lookupGetFunction<ExternalFunc,ObjectImp>(exec,p,&ExternalTable,this);
02231 }
02232 
02233 Value ExternalFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
02234 {
02235   KJS_CHECK_THIS( External, thisObj );
02236   External *external = static_cast<External *>(thisObj.imp());
02237 
02238   KHTMLPart *part = external->part;
02239   if (!part)
02240     return Undefined();
02241 
02242   KHTMLView *widget = part->view();
02243 
02244   switch (id) {
02245   case External::AddFavorite:
02246   {
02247     if (!widget->dialogsAllowed())
02248       return Undefined();
02249     part->xmlDocImpl()->updateRendering();
02250     if (args.size() != 1 && args.size() != 2)
02251       return Undefined();
02252 
02253     QString url = args[0].toString(exec).qstring();
02254     QString title;
02255     if (args.size() == 2)
02256       title = args[1].toString(exec).qstring();
02257 
02258     // AK - don't do anything yet, for the moment i
02259     // just wanted the base js handling code in cvs
02260     return Undefined();
02261 
02262     QString question;
02263     if ( title.isEmpty() )
02264       question = i18n("Do you want a bookmark pointing to the location \"%1\" to be added to your collection?")
02265                  .arg(url);
02266     else
02267       question = i18n("Do you want a bookmark pointing to the location \"%1\" titled \"%2\" to be added to your collection?")
02268                  .arg(url).arg(title);
02269 
02270     emit part->browserExtension()->requestFocus(part);
02271 
02272     QString caption;
02273     if (!part->url().host().isEmpty())
02274        caption = part->url().host() + " - ";
02275     caption += i18n("JavaScript Attempted Bookmark Insert");
02276 
02277     if (KMessageBox::warningYesNo(
02278           widget, question, caption,
02279           i18n("Insert"), i18n("Disallow")) == KMessageBox::Yes)
02280     {
02281       KBookmarkManager *mgr = KBookmarkManager::userBookmarksManager();
02282       mgr->addBookmarkDialog(url,title);
02283     }
02284     break;
02285   }
02286   default:
02287     return Undefined();
02288   }
02289 
02290   return Undefined();
02291 }
02292 
02294 
02295 const ClassInfo History::info = { "History", 0, 0, 0 };
02296 /*
02297 @begin HistoryTable 4
02298   length    History::Length     DontDelete|ReadOnly
02299   back      History::Back       DontDelete|Function 0
02300   forward   History::Forward    DontDelete|Function 0
02301   go        History::Go     DontDelete|Function 1
02302 @end
02303 */
02304 IMPLEMENT_PROTOFUNC_DOM(HistoryFunc)
02305 
02306 Value History::get(ExecState *exec, const Identifier &p) const
02307 {
02308   return lookupGet<HistoryFunc,History,ObjectImp>(exec,p,&HistoryTable,this);
02309 }
02310 
02311 Value History::getValueProperty(ExecState *, int token) const
02312 {
02313   // if previous or next is implemented, make sure its not a major
02314   // privacy leak (see i.e. http://security.greymagic.com/adv/gm005-op/)
02315   switch (token) {
02316   case Length:
02317   {
02318     KParts::BrowserExtension *ext = part->browserExtension();
02319     if ( !ext )
02320       return Number( 0 );
02321 
02322     KParts::BrowserInterface *iface = ext->browserInterface();
02323     if ( !iface )
02324       return Number( 0 );
02325 
02326     QVariant length = iface->property( "historyLength" );
02327 
02328     if ( length.type() != QVariant::UInt )
02329       return Number( 0 );
02330 
02331     return Number( length.toUInt() );
02332   }
02333   default:
02334     kdDebug(6070) << "WARNING: Unhandled token in History::getValueProperty : " << token << endl;
02335     return Undefined();
02336   }
02337 }
02338 
02339 Value HistoryFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
02340 {
02341   KJS_CHECK_THIS( History, thisObj );
02342   History *history = static_cast<History *>(thisObj.imp());
02343 
02344   Value v = args[0];
02345   Number n;
02346   if(!v.isNull())
02347     n = v.toInteger(exec);
02348 
02349   int steps;
02350   switch (id) {
02351   case History::Back:
02352     steps = -1;
02353     break;
02354   case History::Forward:
02355     steps = 1;
02356     break;
02357   case History::Go:
02358     steps = n.intValue();
02359     break;
02360   default:
02361     return Undefined();
02362   }
02363 
02364   // Special case for go(0) from a frame -> reload only the frame
02365   // go(i!=0) from a frame navigates into the history of the frame only,
02366   // in both IE and NS (but not in Mozilla).... we can't easily do that
02367   // in Konqueror...
02368   if (!steps) // add && history->part->parentPart() to get only frames, but doesn't matter
02369   {
02370     history->part->openURL( history->part->url() ); 
02371   } else
02372   {
02373     // Delay it.
02374     // Testcase: history.back(); alert("hello");
02375     Window* window = Window::retrieveWindow( history->part );
02376     window->delayedGoHistory( steps );
02377   }
02378   return Undefined();
02379 }
02380 
02382 
02383 #ifdef Q_WS_QWS
02384 
02385 const ClassInfo Konqueror::info = { "Konqueror", 0, 0, 0 };
02386 
02387 bool Konqueror::hasProperty(ExecState *exec, const Identifier &p) const
02388 {
02389   if ( p.qstring().startsWith( "goHistory" ) ) return false;
02390 
02391   return true;
02392 }
02393 
02394 Value Konqueror::get(ExecState *exec, const Identifier &p) const
02395 {
02396   if ( p == "goHistory" || part->url().protocol() != "http" || part->url().host() != "localhost" )
02397     return Undefined();
02398 
02399   KParts::BrowserExtension *ext = part->browserExtension();
02400   if ( ext ) {
02401     KParts::BrowserInterface *iface = ext->browserInterface();
02402     if ( iface ) {
02403       QVariant prop = iface->property( p.qstring().latin1() );
02404 
02405       if ( prop.isValid() ) {
02406         switch( prop.type() ) {
02407         case QVariant::Int:
02408           return Number( prop.toInt() );
02409         case QVariant::String:
02410           return String( prop.toString() );
02411         default:
02412           break;
02413         }
02414       }
02415     }
02416   }
02417 
02418   return Value( new KonquerorFunc(this, p.qstring().latin1() ) );
02419 }
02420 
02421 Value KonquerorFunc::tryCall(ExecState *exec, Object &, const List &args)
02422 {
02423   KParts::BrowserExtension *ext = konqueror->part->browserExtension();
02424 
02425   if(!ext)
02426     return Undefined();
02427 
02428   KParts::BrowserInterface *iface = ext->browserInterface();
02429 
02430   if ( !iface )
02431     return Undefined();
02432 
02433   QCString n = m_name.data();
02434   n += "()";
02435   iface->callMethod( n.data(), QVariant() );
02436 
02437   return Undefined();
02438 }
02439 
02440 UString Konqueror::toString(ExecState *) const
02441 {
02442   return UString("[object Konqueror]");
02443 }
02444 
02445 #endif
02446 
02447 
02448 #include "kjs_window.moc"
KDE Logo
This file is part of the documentation for khtml Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 30 10:22:22 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003