# khtml Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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 Close:
    00534     case Focus:
    00535     case Blur:
    00536       return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
    00537     default:
    00538       break;
    00539     }
    00540   } else if (!part) {
    00541     // not a  KHTMLPart
    00542     QString rvalue;
    00543     KParts::LiveConnectExtension::Type rtype;
    00544     unsigned long robjid;
    00545     if (m_frame->m_liveconnect &&
    00546         isSafeScript(exec) &&
    00547         m_frame->m_liveconnect->get(0, p.qstring(), rtype, robjid, rvalue))
    00548       return getLiveConnectValue(m_frame->m_liveconnect, p.qstring(), rtype, rvalue, robjid);
    00549     return Undefined();
    00550   }
    00551   // properties that only work on safe windows
    00552   if (isSafeScript(exec) &&  entry)
    00553   {
    00554     //kdDebug(6070) << "token: " << entry->value << endl;
    00555     switch( entry->value ) {
    00556     case Crypto:
    00557       return Undefined(); // ###
    00558     case DefaultStatus:
    00559       return String(UString(part->jsDefaultStatusBarText()));
    00560     case Status:
    00561       return String(UString(part->jsStatusBarText()));
    00562     case Document:
    00563       if (part->document().isNull()) {
    00564         kdDebug(6070) << "Document.write: adding <HTML><BODY> to create document" << endl;
    00565         part->begin();
    00566         part->write("<HTML><BODY>");
    00567         part->end();
    00568       }
    00569       return getDOMNode(exec,part->document());
    00570     case Node:
    00571       return getNodeConstructor(exec);
    00572     case Range:
    00573       return getRangeConstructor(exec);
    00574     case NodeFilter:
    00575       return getNodeFilterConstructor(exec);
    00576     case DOMException:
    00577       return getDOMExceptionConstructor(exec);
    00578     case CSSRule:
    00579       return getCSSRuleConstructor(exec);
    00580     case EventCtor:
    00581       return getEventConstructor(exec);
    00582     case _History:
    00583       return Value(history ? history :
    00584                    (const_cast<Window*>(this)->history = new History(exec,part)));
    00585
    00586     case _External:
    00587       return Value(external ? external :
    00588                    (const_cast<Window*>(this)->external = new External(exec,part)));
    00589
    00590     case Event:
    00591       if (m_evt)
    00592         return getDOMEvent(exec,*m_evt);
    00593       else {
    00594 #ifdef KJS_VERBOSE
    00595         kdDebug(6070) << "WARNING: window(" << this << "," << part->name() << ").event, no event!" << endl;
    00596 #endif
    00597         return Undefined();
    00598       }
    00599     case InnerHeight:
    00600       if (!part->view())
    00601         return Undefined();
    00602       khtml::RenderWidget::flushWidgetResizes(); // make sure frames have their final size
    00603       return Number(part->view()->visibleHeight());
    00604     case InnerWidth:
    00605       if (!part->view())
    00606         return Undefined();
    00607       khtml::RenderWidget::flushWidgetResizes(); // make sure frames have their final size
    00608       return Number(part->view()->visibleWidth());
    00609     case Length:
    00610       return Number(part->frames().count());
    00611     case Name:
    00612       return String(part->name());
    00613     case SideBar:
    00614       return Value(new MozillaSidebarExtension(exec, part));
    00615     case _Navigator:
    00616     case ClientInformation: {
    00617       // Store the navigator in the object so we get the same one each time.
    00618       Value nav( new Navigator(exec, part) );
    00619       const_cast<Window *>(this)->put(exec, "navigator", nav, DontDelete|ReadOnly|Internal);
    00620       const_cast<Window *>(this)->put(exec, "clientInformation", nav, DontDelete|ReadOnly|Internal);
    00621       return nav;
    00622     }
    00623 #ifdef Q_WS_QWS
    00624     case _Konqueror: {
    00625       Value k( new Konqueror(exec, part) );
    00626       const_cast<Window *>(this)->put(exec, "konqueror", k, DontDelete|ReadOnly|Internal);
    00627       return k;
    00628     }
    00629 #endif
    00630     case OffscreenBuffering:
    00631       return Boolean(true);
    00632     case OuterHeight:
    00633     case OuterWidth:
    00634     {
    00635       if (!part->widget())
    00636         return Number(0);
    00637       KWin::WindowInfo inf = KWin::windowInfo(part->widget()->topLevelWidget()->winId());
    00638       return Number(entry->value == OuterHeight ?
    00639                     inf.geometry().height() : inf.geometry().width());
    00640     }
    00641     case PageXOffset:
    00642       return Number(part->view()->contentsX());
    00643     case PageYOffset:
    00644       return Number(part->view()->contentsY());
    00645     case Personalbar:
    00646       return Undefined(); // ###
    00647     case ScreenLeft:
    00648     case ScreenX: {
    00649       if (!part->view())
    00650         return Undefined();
    00651       QRect sg = KGlobalSettings::desktopGeometry(part->view());
    00652       return Number(part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
    00653     }
    00654     case ScreenTop:
    00655     case ScreenY: {
    00656       if (!part->view())
    00657         return Undefined();
    00658       QRect sg = KGlobalSettings::desktopGeometry(part->view());
    00659       return Number(part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
    00660     }
    00661     case ScrollX: {
    00662       if (!part->view())
    00663         return Undefined();
    00664       return Number(part->view()->contentsX());
    00665     }
    00666     case ScrollY: {
    00667       if (!part->view())
    00668         return Undefined();
    00669       return Number(part->view()->contentsY());
    00670     }
    00671     case Scrollbars:
    00672       return Undefined(); // ###
    00673     case _Screen:
    00674       return Value(screen ? screen :
    00675                    (const_cast<Window*>(this)->screen = new Screen(exec)));
    00676     case Image:
    00677       return Value(new ImageConstructorImp(exec, part->document()));
    00678     case Option:
    00679       return Value(new OptionConstructorImp(exec, part->document()));
    00680     case XMLHttpRequest:
    00681       return Value(new XMLHttpRequestConstructorImp(exec, part->document()));
    00682     case XMLSerializer:
    00683       return Value(new XMLSerializerConstructorImp(exec));
    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       kdDebug(6070) << "Window::goURL dstUrl=" << dstUrl << endl;
    01173
    01174       // check if we're allowed to inject javascript
    01175       // SYNC check with khtml_part.cpp::slotRedirect!
    01176       if ( isSafeScript(exec) ||
    01177             dstUrl.find(QString::fromLatin1("javascript:"), 0, false) != 0 )
    01178         part->scheduleRedirection(-1,
    01179                                   dstUrl,
    01180                                   lockHistory);
    01181     }
    01182   } else if (!part && !m_frame->m_part.isNull()) {
    01183     KParts::BrowserExtension *b = KParts::BrowserExtension::childObject(m_frame->m_part);
    01184     if (b)
    01185       b->emit openURLRequest(m_frame->m_frame->element()->getDocument()->completeURL(url));
    01186     kdDebug() << "goURL for ROPart" << endl;
    01187   }
    01188 }
    01189
    01190 KParts::ReadOnlyPart *Window::part() const {
    01191     return m_frame.isNull() ? 0L : static_cast<KParts::ReadOnlyPart *>(m_frame->m_part);
    01192 }
    01193
    01194 void Window::delayedGoHistory( int steps )
    01195 {
    01196     m_delayed.append( DelayedAction( DelayedGoHistory, steps ) );
    01197 }
    01198
    01199 void Window::goHistory( int steps )
    01200 {
    01201   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
    01202   if(!part)
    01203       // TODO history readonlypart
    01204     return;
    01205   KParts::BrowserExtension *ext = part->browserExtension();
    01206   if(!ext)
    01207     return;
    01208   KParts::BrowserInterface *iface = ext->browserInterface();
    01209
    01210   if ( !iface )
    01211     return;
    01212
    01213   iface->callMethod( "goHistory(int)", steps );
    01214   //emit ext->goHistory(steps);
    01215 }
    01216
    01217 void KJS::Window::resizeTo(QWidget* tl, int width, int height)
    01218 {
    01219   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
    01220   if(!part)
    01221       // TODO resizeTo readonlypart
    01222     return;
    01223   KParts::BrowserExtension *ext = part->browserExtension();
    01224   if (!ext) {
    01225     kdDebug(6070) << "Window::resizeTo found no browserExtension" << endl;
    01226     return;
    01227   }
    01228
    01229   // Security check: within desktop limits and bigger than 100x100 (per spec)
    01230   if ( width < 100 || height < 100 ) {
    01231     kdDebug(6070) << "Window::resizeTo refused, window would be too small ("<<width<<","<<height<<")" << endl;
    01232     return;
    01233   }
    01234
    01235   QRect sg = KGlobalSettings::desktopGeometry(tl);
    01236
    01237   if ( width > sg.width() || height > sg.height() ) {
    01238     kdDebug(6070) << "Window::resizeTo refused, window would be too big ("<<width<<","<<height<<")" << endl;
    01239     return;
    01240   }
    01241
    01242   kdDebug(6070) << "resizing to " << width << "x" << height << endl;
    01243
    01244   emit ext->resizeTopLevelWidget( width, height );
    01245
    01246   // If the window is out of the desktop, move it up/left
    01247   // (maybe we should use workarea instead of sg, otherwise the window ends up below kicker)
    01248   int right = tl->x() + tl->frameGeometry().width();
    01249   int bottom = tl->y() + tl->frameGeometry().height();
    01250   int moveByX = 0;
    01251   int moveByY = 0;
    01252   if ( right > sg.right() )
    01253     moveByX = - right + sg.right(); // always <0
    01254   if ( bottom > sg.bottom() )
    01255     moveByY = - bottom + sg.bottom(); // always <0
    01256   if ( moveByX || moveByY )
    01257     emit ext->moveTopLevelWidget( tl->x() + moveByX , tl->y() + moveByY );
    01258 }
    01259
    01260 Value Window::openWindow(ExecState *exec, const List& args)
    01261 {
    01262   KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
    01263   if (!part)
    01264     return Undefined();
    01265   KHTMLView *widget = part->view();
    01266   Value v = args[0];
    01267   QString str = v.toString(exec).qstring();
    01268
    01269   // prepare arguments
    01270   KURL url;
    01271   if (!str.isEmpty())
    01272   {
    01273     KHTMLPart* p = ::qt_cast<KHTMLPart *>(Window::retrieveActive(exec)->m_frame->m_part);
    01274     if ( p )
    01275       url = p->htmlDocument().completeURL(str).string();
    01276     if ( !p ||
    01277          !static_cast<DOM::DocumentImpl*>(p->htmlDocument().handle())->isURLAllowed(url.url()) )
    01278       return Undefined();
    01279   }
    01280
    01281   KHTMLSettings::KJSWindowOpenPolicy policy =
    01282         part->settings()->windowOpenPolicy(part->url().host());
    01283   if ( policy == KHTMLSettings::KJSWindowOpenAsk ) {
    01284     emit part->browserExtension()->requestFocus(part);
    01285     QString caption;
    01286     if (!part->url().host().isEmpty())
    01287       caption = part->url().host() + " - ";
    01288     caption += i18n( "Confirmation: JavaScript Popup" );
    01289     if ( KMessageBox::questionYesNo(widget,
    01290                                     str.isEmpty() ?
    01291                                     i18n( "This site is requesting to open up a new browser "
    01292                                           "window via JavaScript.\n"
    01293                                           "Do you want to allow this?" ) :
    01294                                     i18n( "<qt>This site is requesting to open<p>%1</p>in a new browser window via JavaScript.<br />"
    01295                                           "Do you want to allow this?</qt>").arg(KStringHandler::csqueeze(url.htmlURL(),  100)),
    01296                                     caption ) == KMessageBox::Yes )
    01297       policy = KHTMLSettings::KJSWindowOpenAllow;
    01298   } else if ( policy == KHTMLSettings::KJSWindowOpenSmart )
    01299   {
    01300     // window.open disabled unless from a key/mouse event
    01301     if (static_cast<ScriptInterpreter *>(exec->interpreter())->isWindowOpenAllowed())
    01302       policy = KHTMLSettings::KJSWindowOpenAllow;
    01303   }
    01304   if ( policy != KHTMLSettings::KJSWindowOpenAllow ) {
    01305     part->setSuppressedPopupIndicator(true);
    01306     return Undefined();
    01307   } else {
    01308     KParts::WindowArgs winargs;
    01309
    01310     // scan feature argument
    01311     QString features;
    01312     if (args.size()>2) {
    01313       features = args[2].toString(exec).qstring();
    01314       // specifying window params means false defaults
    01315       winargs.menuBarVisible = false;
    01316       winargs.toolBarsVisible = false;
    01317       winargs.statusBarVisible = false;
    01318       QStringList flist = QStringList::split(',', features);
    01319       QStringList::ConstIterator it = flist.begin();
    01320       while (it != flist.end()) {
    01321         QString s = *it++;
    01322         QString key, val;
    01323         int pos = s.find('=');
    01324         if (pos >= 0) {
    01325           key = s.left(pos).stripWhiteSpace().lower();
    01326           val = s.mid(pos + 1).stripWhiteSpace().lower();
    01327           QRect screen = KGlobalSettings::desktopGeometry(widget->topLevelWidget());
    01328
    01329           if (key == "left" || key == "screenx") {
    01330             winargs.x = (int)val.toFloat() + screen.x();
    01331             if (winargs.x < screen.x() || winargs.x > screen.right())
    01332               winargs.x = screen.x(); // only safe choice until size is determined
    01333           } else if (key == "top" || key == "screeny") {
    01334             winargs.y = (int)val.toFloat() + screen.y();
    01335             if (winargs.y < screen.y() || winargs.y > screen.bottom())
    01336               winargs.y = screen.y(); // only safe choice until size is determined
    01337           } else if (key == "height") {
    01338             winargs.height = (int)val.toFloat() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
    01339             if (winargs.height > screen.height())  // should actually check workspace
    01340               winargs.height = screen.height();
    01341             if (winargs.height < 100)
    01342               winargs.height = 100;
    01343           } else if (key == "width") {
    01344             winargs.width = (int)val.toFloat() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
    01345             if (winargs.width > screen.width())    // should actually check workspace
    01346               winargs.width = screen.width();
    01347             if (winargs.width < 100)
    01348               winargs.width = 100;
    01349           } else {
    01350             goto boolargs;
    01351           }
    01352           continue;
    01353         } else {
    01354           // leaving away the value gives true
    01355           key = s.stripWhiteSpace().lower();
    01356           val = "1";
    01357         }
    01358       boolargs:
    01359         if (key == "menubar")
    01360           winargs.menuBarVisible = (val == "1" || val == "yes");
    01361         else if (key == "toolbar")
    01362           winargs.toolBarsVisible = (val == "1" || val == "yes");
    01363         else if (key == "location")  // ### missing in WindowArgs
    01364           winargs.toolBarsVisible = (val == "1" || val == "yes");
    01365         else if (key == "status" || key == "statusbar")
    01366           winargs.statusBarVisible = (val == "1" || val == "yes");
    01367         else if (key == "resizable")
    01368           winargs.resizable = (val == "1" || val == "yes");
    01369         else if (key == "fullscreen")
    01370           winargs.fullscreen = (val == "1" || val == "yes");
    01371       }
    01372     }
    01373
    01374     KParts::URLArgs uargs;
    01375     KHTMLPart *p = part;
    01376     uargs.frameName = args.size() > 1 ?
    01377                       args[1].toString(exec).qstring()
    01378                       : QString("_blank");
    01379     if ( uargs.frameName.lower() == "_top" )
    01380     {
    01381       while ( p->parentPart() )
    01382         p = p->parentPart();
    01383       Window::retrieveWindow(p)->goURL(exec, url.url(), false /*don't lock history*/);
    01384       return Window::retrieve(p);
    01385     }
    01386     if ( uargs.frameName.lower() == "_parent" )
    01387     {
    01388       if ( p->parentPart() )
    01389         p = p->parentPart();
    01390       Window::retrieveWindow(p)->goURL(exec, url.url(), false /*don't lock history*/);
    01391       return Window::retrieve(p);
    01392     }
    01393     if ( uargs.frameName.lower() == "_self")
    01394     {
    01395       Window::retrieveWindow(p)->goURL(exec, url.url(), false /*don't lock history*/);
    01396       return Window::retrieve(p);
    01397     }
    01398     if ( uargs.frameName.lower() == "replace" )
    01399     {
    01400       Window::retrieveWindow(p)->goURL(exec, url.url(), true /*lock history*/);
    01401       return Window::retrieve(p);
    01402     }
    01403     uargs.serviceType = "text/html";
    01404
    01405     // request window (new or existing if framename is set)
    01406     KParts::ReadOnlyPart *newPart = 0L;
    01407     emit p->browserExtension()->createNewWindow(KURL(), uargs,winargs,newPart);
    01408     if (newPart && ::qt_cast<KHTMLPart*>(newPart)) {
    01409       KHTMLPart *khtmlpart = static_cast<KHTMLPart*>(newPart);
    01410       //qDebug("opener set to %p (this Window's part) in new Window %p  (this Window=%p)",part,win,window);
    01411       khtmlpart->setOpener(p);
    01412       khtmlpart->setOpenedByJS(true);
    01413       if (khtmlpart->document().isNull()) {
    01414         khtmlpart->begin();
    01415         khtmlpart->write("<HTML><BODY>");
    01416         khtmlpart->end();
    01417         if ( p->docImpl() ) {
    01418           //kdDebug(6070) << "Setting domain to " << p->docImpl()->domain().string() << endl;
    01419           khtmlpart->docImpl()->setDomain( p->docImpl()->domain());
    01420           khtmlpart->docImpl()->setBaseURL( p->docImpl()->baseURL() );
    01421         }
    01422       }
    01423       uargs.serviceType = QString::null;
    01424       if (uargs.frameName.lower() == "_blank")
    01425         uargs.frameName = QString::null;
    01426       if (!url.isEmpty())
    01427         emit khtmlpart->browserExtension()->openURLRequest(url,uargs);
    01428       return Window::retrieve(khtmlpart); // global object
    01429     } else
    01430       return Undefined();
    01431   }
    01432 }
    01433
    01434 Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    01435 {
    01436   KJS_CHECK_THIS( Window, thisObj );
    01437   Window *window = static_cast<Window *>(thisObj.imp());
    01438   QString str, str2;
    01439
    01440   KHTMLPart *part = ::qt_cast<KHTMLPart *>(window->m_frame->m_part);
    01441   if (!part)
    01442     return Undefined();
    01443
    01444   KHTMLView *widget = part->view();
    01445   Value v = args[0];
    01446   UString s = v.toString(exec);
    01447   str = s.qstring();
    01448
    01449   QString caption;
    01450   if (part && !part->url().host().isEmpty())
    01451     caption = part->url().host() + " - ";
    01452   caption += "JavaScript"; // TODO: i18n
    01453   // functions that work everywhere
    01454   switch(id) {
    01455   case Window::Alert:
    01456     if (!widget->dialogsAllowed())
    01457       return Undefined();
    01458     if ( part && part->xmlDocImpl() )
    01459       part->xmlDocImpl()->updateRendering();
    01460     if ( part )
    01461       emit part->browserExtension()->requestFocus(part);
    01462     KMessageBox::error(widget, str, caption);
    01463     return Undefined();
    01464   case Window::Confirm:
    01465     if (!widget->dialogsAllowed())
    01466       return Undefined();
    01467     if ( part && part->xmlDocImpl() )
    01468       part->xmlDocImpl()->updateRendering();
    01469     if ( part )
    01470       emit part->browserExtension()->requestFocus(part);
    01471     return Boolean((KMessageBox::warningYesNo(widget, str, caption,
    01472                                                 KStdGuiItem::ok(), KStdGuiItem::cancel()) == KMessageBox::Yes));
    01473   case Window::Prompt:
    01474     if (!widget->dialogsAllowed())
    01475       return Undefined();
    01476     if ( part && part->xmlDocImpl() )
    01477       part->xmlDocImpl()->updateRendering();
    01478     if ( part )
    01479       emit part->browserExtension()->requestFocus(part);
    01480     bool ok;
    01481     if (args.size() >= 2)
    01482       str2 = KInputDialog::getText(caption,
    01483                                    QStyleSheet::convertFromPlainText(str),
    01484                                    args[1].toString(exec).qstring(), &ok, widget);
    01485     else
    01486       str2 = KInputDialog::getText(caption,
    01487                                    QStyleSheet::convertFromPlainText(str),
    01488                                    QString::null, &ok, widget);
    01489     if ( ok )
    01490         return String(str2);
    01491     else
    01492         return Null();
    01493   case Window::Open:
    01494     return window->openWindow(exec, args);
    01495   case Window::Close: {
    01496     /* From http://developer.netscape.com/docs/manuals/js/client/jsref/window.htm :
    01497        The close method closes only windows opened by JavaScript using the open method.
    01498        If you attempt to close any other window, a confirm is generated, which
    01499        lets the user choose whether the window closes.
    01500        This is a security feature to prevent "mail bombs" containing self.close().
    01501        However, if the window has only one document (the current one) in its
    01502        session history, the close is allowed without any confirm. This is a
    01503        special case for one-off windows that need to open other windows and
    01504        then dispose of themselves.
    01505     */
    01506     bool doClose = false;
    01507     if (!part->openedByJS())
    01508     {
    01509       // To conform to the SPEC, we only ask if the window
    01510       // has more than one entry in the history (NS does that too).
    01511       History history(exec,part);
    01512
    01513       if ( history.get( exec, "length" ).toInt32(exec) <= 1 )
    01514       {
    01515         doClose = true;
    01516       }
    01517       else
    01518       {
    01519         // Can we get this dialog with tabs??? Does it close the window or the tab in that case?
    01520         emit part->browserExtension()->requestFocus(part);
    01521         if ( KMessageBox::questionYesNo( window->part()->widget(), i18n("Close window?"), i18n("Confirmation Required") )
    01522              == KMessageBox::Yes )
    01523           doClose = true;
    01524       }
    01525     }
    01526     else
    01527       doClose = true;
    01528
    01529     if (doClose)
    01530     {
    01531       // If this is the current window (the one the interpreter runs in),
    01532       // then schedule a delayed close (so that the script terminates first).
    01533       // But otherwise, close immediately. This fixes w=window.open("","name");w.close();window.open("name");
    01534       if ( Window::retrieveActive(exec) == window ) {
    01535         if (widget) {
    01536           // quit all dialogs of this view
    01537           // this fixes 'setTimeout('self.close()',1000); alert("Hi");' crash
    01538           widget->closeChildDialogs();
    01539         }
    01540         //kdDebug() << "scheduling delayed close"  << endl;
    01541         // We'll close the window at the end of the script execution
    01542         Window* w = const_cast<Window*>(window);
    01543         w->m_delayed.append( Window::DelayedAction( Window::DelayedClose ) );
    01544       } else {
    01545         //kdDebug() << "closing NOW"  << endl;
    01546         (const_cast<Window*>(window))->closeNow();
    01547       }
    01548     }
    01549     return Undefined();
    01550   }
    01551   case Window::Navigate:
    01552     window->goURL(exec, args[0].toString(exec).qstring(), false /*don't lock history*/);
    01553     return Undefined();
    01554   case Window::Focus: {
    01555     KHTMLSettings::KJSWindowFocusPolicy policy =
    01556         part->settings()->windowFocusPolicy(part->url().host());
    01557     if(policy == KHTMLSettings::KJSWindowFocusAllow && widget) {
    01558       widget->topLevelWidget()->raise();
    01559       KWin::deIconifyWindow( widget->topLevelWidget()->winId() );
    01560       widget->setActiveWindow();
    01561       emit part->browserExtension()->requestFocus(part);
    01562     }
    01563     return Undefined();
    01564   }
    01565   case Window::Blur:
    01566     // TODO
    01567     return Undefined();
    01568   };
    01569
    01570
    01571   // now unsafe functions..
    01572   if (!window->isSafeScript(exec))
    01573     return Undefined();
    01574
    01575   switch (id) {
    01576   case Window::ScrollBy:
    01577     if(args.size() == 2 && widget)
    01578       widget->scrollBy(args[0].toInt32(exec), args[1].toInt32(exec));
    01579     return Undefined();
    01580   case Window::Scroll:
    01581   case Window::ScrollTo:
    01582     if(args.size() == 2 && widget)
    01583       widget->setContentsPos(args[0].toInt32(exec), args[1].toInt32(exec));
    01584     return Undefined();
    01585   case Window::MoveBy: {
    01586     KHTMLSettings::KJSWindowMovePolicy policy =
    01587         part->settings()->windowMovePolicy(part->url().host());
    01588     if(policy == KHTMLSettings::KJSWindowMoveAllow && args.size() == 2 && widget)
    01589     {
    01590       KParts::BrowserExtension *ext = part->browserExtension();
    01591       if (ext) {
    01592         QWidget * tl = widget->topLevelWidget();
    01593         QRect sg = KGlobalSettings::desktopGeometry(tl);
    01594
    01595         QPoint dest = tl->pos() + QPoint( args[0].toInt32(exec), args[1].toInt32(exec) );
    01596         // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
    01597         if ( dest.x() >= sg.x() && dest.y() >= sg.x() &&
    01598              dest.x()+tl->width() <= sg.width()+sg.x() &&
    01599              dest.y()+tl->height() <= sg.height()+sg.y() )
    01600           emit ext->moveTopLevelWidget( dest.x(), dest.y() );
    01601       }
    01602     }
    01603     return Undefined();
    01604   }
    01605   case Window::MoveTo: {
    01606     KHTMLSettings::KJSWindowMovePolicy policy =
    01607         part->settings()->windowMovePolicy(part->url().host());
    01608     if(policy == KHTMLSettings::KJSWindowMoveAllow && args.size() == 2 && widget)
    01609     {
    01610       KParts::BrowserExtension *ext = part->browserExtension();
    01611       if (ext) {
    01612         QWidget * tl = widget->topLevelWidget();
    01613         QRect sg = KGlobalSettings::desktopGeometry(tl);
    01614
    01615         QPoint dest( args[0].toInt32(exec)+sg.x(), args[1].toInt32(exec)+sg.y() );
    01616         // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
    01617         if ( dest.x() >= sg.x() && dest.y() >= sg.y() &&
    01618              dest.x()+tl->width() <= sg.width()+sg.x() &&
    01619              dest.y()+tl->height() <= sg.height()+sg.y() )
    01620         emit ext->moveTopLevelWidget( dest.x(), dest.y() );
    01621       }
    01622     }
    01623     return Undefined();
    01624   }
    01625   case Window::ResizeBy: {
    01626     KHTMLSettings::KJSWindowResizePolicy policy =
    01627         part->settings()->windowResizePolicy(part->url().host());
    01628     if(policy == KHTMLSettings::KJSWindowResizeAllow
    01629             && args.size() == 2 && widget)
    01630     {
    01631       QWidget * tl = widget->topLevelWidget();
    01632       QRect geom = tl->frameGeometry();
    01633       window->resizeTo( tl,
    01634                         geom.width() + args[0].toInt32(exec),
    01635                         geom.height() + args[1].toInt32(exec) );
    01636     }
    01637     return Undefined();
    01638   }
    01639   case Window::ResizeTo: {
    01640     KHTMLSettings::KJSWindowResizePolicy policy =
    01641                part->settings()->windowResizePolicy(part->url().host());
    01642     if(policy == KHTMLSettings::KJSWindowResizeAllow
    01643                && args.size() == 2 && widget)
    01644     {
    01645       QWidget * tl = widget->topLevelWidget();
    01646       window->resizeTo( tl, args[0].toInt32(exec), args[1].toInt32(exec) );
    01647     }
    01648     return Undefined();
    01649   }
    01650   case Window::SetTimeout:
    01651   case Window::SetInterval: {
    01652     bool singleShot;
    01653     int i; // timeout interval
    01654     if (args.size() == 0)
    01655       return Undefined();
    01656     if (args.size() > 1) {
    01657       singleShot = (id == Window::SetTimeout);
    01658       i = args[1].toInt32(exec);
    01659     } else {
    01660       // second parameter is missing. Emulate Mozilla behavior.
    01661       singleShot = true;
    01662       i = 4;
    01663     }
    01664     if (v.isA(StringType)) {
    01665       int r = (const_cast<Window*>(window))->winq->installTimeout(Identifier(s), i, singleShot );
    01666       return Number(r);
    01667     }
    01668     else if (v.isA(ObjectType) && Object::dynamicCast(v).implementsCall()) {
    01669       Object func = Object::dynamicCast(v);
    01670       List funcArgs;
    01671       ListIterator it = args.begin();
    01672       int argno = 0;
    01673       while (it != args.end()) {
    01674     Value arg = it++;
    01675     if (argno++ >= 2)
    01676         funcArgs.append(arg);
    01677       }
    01678       if (args.size() < 2)
    01679     funcArgs.append(Number(i));
    01680       int r = (const_cast<Window*>(window))->winq->installTimeout(func, funcArgs, i, singleShot );
    01681       return Number(r);
    01682     }
    01683     else
    01684       return Undefined();
    01685   }
    01686   case Window::ClearTimeout:
    01687   case Window::ClearInterval:
    01688     (const_cast<Window*>(window))->winq->clearTimeout(v.toInt32(exec));
    01689     return Undefined();
    01690   case Window::Print:
    01691     if ( widget ) {
    01692       // ### TODO emit onbeforeprint event
    01693       widget->print();
    01694       // ### TODO emit onafterprint event
    01695     }
    01696   case Window::CaptureEvents:
    01697   case Window::ReleaseEvents:
    01698     // Do nothing for now. These are NS-specific legacy calls.
    01699     break;
    01700   case Window::AddEventListener: {
    01701         JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
    01702         if (listener) {
    01703         DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
    01704             docimpl->addWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
    01705         }
    01706         return Undefined();
    01707     }
    01708   case Window::RemoveEventListener: {
    01709         JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
    01710         if (listener) {
    01711         DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
    01712             docimpl->removeWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
    01713         }
    01714         return Undefined();
    01715     }
    01716
    01717   }
    01718   return Undefined();
    01719 }
    01720
    01722
    01723 // KDE 4: Make those parameters const ... &
    01724 ScheduledAction::ScheduledAction(Object _func, List _args, QTime _nextTime, int _interval, bool _singleShot,
    01725                   int _timerId)
    01726 {
    01727   //kdDebug(6070) << "ScheduledAction::ScheduledAction(isFunction) " << this << endl;
    01728   func = static_cast<ObjectImp*>(_func.imp());
    01729   args = _args;
    01730   isFunction = true;
    01731   singleShot = _singleShot;
    01732   nextTime = _nextTime;
    01733   interval = _interval;
    01734   executing = false;
    01735   timerId = _timerId;
    01736 }
    01737
    01738 // KDE 4: Make it const QString &
    01739 ScheduledAction::ScheduledAction(QString _code, QTime _nextTime, int _interval, bool _singleShot, int _timerId)
    01740 {
    01741   //kdDebug(6070) << "ScheduledAction::ScheduledAction(!isFunction) " << this << endl;
    01742   //func = 0;
    01743   //args = 0;
    01744   func = 0;
    01745   code = _code;
    01746   isFunction = false;
    01747   singleShot = _singleShot;
    01748   nextTime = _nextTime;
    01749   interval = _interval;
    01750   executing = false;
    01751   timerId = _timerId;
    01752 }
    01753
    01754 bool ScheduledAction::execute(Window *window)
    01755 {
    01756   KHTMLPart *part = ::qt_cast<KHTMLPart *>(window->m_frame->m_part);
    01757   if (!part || !part->jScriptEnabled())
    01758     return false;
    01759   ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(part->jScript()->interpreter());
    01760
    01761   interpreter->setProcessingTimerCallback(true);
    01762
    01763   //kdDebug(6070) << "ScheduledAction::execute " << this << endl;
    01764   if (isFunction) {
    01765     if (func->implementsCall()) {
    01766       // #### check this
    01767       Q_ASSERT( part );
    01768       if ( part )
    01769       {
    01770         KJS::Interpreter *interpreter = part->jScript()->interpreter();
    01771         ExecState *exec = interpreter->globalExec();
    01772         Q_ASSERT( window == interpreter->globalObject().imp() );
    01773         Object obj( window );
    01774         func->call(exec,obj,args); // note that call() creates its own execution state for the func call
    01775         if (exec->hadException())
    01776           exec->clearException();
    01777
    01778         // Update our document's rendering following the execution of the timeout callback.
    01779         part->document().updateRendering();
    01780       }
    01781     }
    01782   }
    01783   else {
    01784     part->executeScript(DOM::Node(), code);
    01785   }
    01786
    01787   interpreter->setProcessingTimerCallback(false);
    01788   return true;
    01789 }
    01790
    01791 void ScheduledAction::mark()
    01792 {
    01793   if (func && !func->marked())
    01794     func->mark();
    01795   args.mark();
    01796 }
    01797
    01798 ScheduledAction::~ScheduledAction()
    01799 {
    01800   //kdDebug(6070) << "ScheduledAction::~ScheduledAction " << this << endl;
    01801 }
    01802
    01804
    01805 WindowQObject::WindowQObject(Window *w)
    01806   : parent(w)
    01807 {
    01808   //kdDebug(6070) << "WindowQObject::WindowQObject " << this << endl;
    01809   if ( !parent->m_frame )
    01810       kdDebug(6070) << "WARNING: null part in " << k_funcinfo << endl;
    01811   else
    01812       connect( parent->m_frame, SIGNAL( destroyed() ),
    01813                this, SLOT( parentDestroyed() ) );
    01814   pausedTime = 0;
    01815   lastTimerId = 0;
    01816 }
    01817
    01818 WindowQObject::~WindowQObject()
    01819 {
    01820   //kdDebug(6070) << "WindowQObject::~WindowQObject " << this << endl;
    01821   parentDestroyed(); // reuse same code
    01822 }
    01823
    01824 void WindowQObject::parentDestroyed()
    01825 {
    01826   killTimers();
    01827
    01828   QPtrListIterator<ScheduledAction> it(scheduledActions);
    01829   for (; it.current(); ++it)
    01830     delete it.current();
    01831   scheduledActions.clear();
    01832 }
    01833
    01834 int WindowQObject::installTimeout(const Identifier &handler, int t, bool singleShot)
    01835 {
    01836   int id = ++lastTimerId;
    01837   if (t < 10) t = 10;
    01838   QTime nextTime = QTime::currentTime().addMSecs(-pausedTime).addMSecs(t);
    01839   ScheduledAction *action = new ScheduledAction(handler.qstring(),nextTime,t,singleShot,id);
    01840   scheduledActions.append(action);
    01841   setNextTimer();
    01842   return id;
    01843 }
    01844
    01845 int WindowQObject::installTimeout(const Value &func, List args, int t, bool singleShot)
    01846 {
    01847   Object objFunc = Object::dynamicCast( func );
    01848   if (!objFunc.isValid())
    01849     return 0;
    01850   int id = ++lastTimerId;
    01851   if (t < 10) t = 10;
    01852   QTime nextTime = QTime::currentTime().addMSecs(-pausedTime).addMSecs(t);
    01853   ScheduledAction *action = new ScheduledAction(objFunc,args,nextTime,t,singleShot,id);
    01854   scheduledActions.append(action);
    01855   setNextTimer();
    01856   return id;
    01857 }
    01858
    01859 void WindowQObject::clearTimeout(int timerId)
    01860 {
    01861   QPtrListIterator<ScheduledAction> it(scheduledActions);
    01862   for (; it.current(); ++it) {
    01863     ScheduledAction *action = it.current();
    01864     if (action->timerId == timerId) {
    01865       scheduledActions.removeRef(action);
    01866       if (!action->executing)
    01867     delete action;
    01868       return;
    01869     }
    01870   }
    01871 }
    01872
    01873 bool WindowQObject::hasTimers() const
    01874 {
    01875   return scheduledActions.count();
    01876 }
    01877
    01878 void WindowQObject::mark()
    01879 {
    01880   QPtrListIterator<ScheduledAction> it(scheduledActions);
    01881   for (; it.current(); ++it)
    01882     it.current()->mark();
    01883 }
    01884
    01885 void WindowQObject::timerEvent(QTimerEvent *)
    01886 {
    01887   killTimers();
    01888
    01889   if (scheduledActions.isEmpty())
    01890     return;
    01891
    01892   QTime currentActual = QTime::currentTime();
    01893   QTime currentAdjusted = currentActual.addMSecs(-pausedTime);
    01894
    01895   // Work out which actions are to be executed. We take a separate copy of
    01896   // this list since the main one may be modified during action execution
    01897   QPtrList<ScheduledAction> toExecute;
    01898   QPtrListIterator<ScheduledAction> it(scheduledActions);
    01899   for (; it.current(); ++it)
    01900     if (currentAdjusted >= it.current()->nextTime)
    01901       toExecute.append(it.current());
    01902
    01903   // ### verify that the window can't be closed (and action deleted) during execution
    01904   it = QPtrListIterator<ScheduledAction>(toExecute);
    01905   for (; it.current(); ++it) {
    01906     ScheduledAction *action = it.current();
    01907     if (!scheduledActions.containsRef(action)) // removed by clearTimeout()
    01908       continue;
    01909
    01910     action->executing = true; // prevent deletion in clearTimeout()
    01911
    01912     if (action->singleShot)
    01913       scheduledActions.removeRef(action);
    01914     if (parent->part()) {
    01915       bool ok = action->execute(parent);
    01916       if ( !ok ) // e.g. JS disabled
    01917         scheduledActions.removeRef( action );
    01918     }
    01919
    01920     action->executing = false;
    01921
    01922     if (!scheduledActions.containsRef(action))
    01923       delete action;
    01924     else
    01925       action->nextTime = action->nextTime.addMSecs(action->interval);
    01926   }
    01927
    01928   pausedTime += currentActual.msecsTo(QTime::currentTime());
    01929
    01930   // Work out when next event is to occur
    01931   setNextTimer();
    01932 }
    01933
    01934 void WindowQObject::setNextTimer()
    01935 {
    01936   if (scheduledActions.isEmpty())
    01937     return;
    01938
    01939   QPtrListIterator<ScheduledAction> it(scheduledActions);
    01940   QTime nextTime = it.current()->nextTime;
    01941   for (++it; it.current(); ++it)
    01942     if (nextTime > it.current()->nextTime)
    01943       nextTime = it.current()->nextTime;
    01944
    01945   QTime nextTimeActual = nextTime.addMSecs(pausedTime);
    01946   int nextInterval = QTime::currentTime().msecsTo(nextTimeActual);
    01947   if (nextInterval < 0)
    01948     nextInterval = 0;
    01949   startTimer(nextInterval);
    01950 }
    01951
    01952 void WindowQObject::timeoutClose()
    01953 {
    01954   parent->closeNow();
    01955 }
    01956
    01957 Value FrameArray::get(ExecState *exec, const Identifier &p) const
    01958 {
    01959 #ifdef KJS_VERBOSE
    01960   kdDebug(6070) << "FrameArray::get " << p.qstring() << " part=" << (void*)part << endl;
    01961 #endif
    01962   if (part.isNull())
    01963     return Undefined();
    01964
    01965   QPtrList<KParts::ReadOnlyPart> frames = part->frames();
    01966   unsigned int len = frames.count();
    01967   if (p == lengthPropertyName)
    01968     return Number(len);
    01969   else if (p== "location") // non-standard property, but works in NS and IE
    01970   {
    01971     Object obj = Object::dynamicCast( Window::retrieve( part ) );
    01972     if ( !obj.isNull() )
    01973       return obj.get( exec, "location" );
    01974     return Undefined();
    01975   }
    01976
    01977   // check for the name or number
    01978   KParts::ReadOnlyPart *frame = part->findFramePart(p.qstring());
    01979   if (!frame) {
    01980     bool ok;
    01981     unsigned int i = p.toArrayIndex(&ok);
    01982     if (ok && i < len)
    01983       frame = frames.at(i);
    01984   }
    01985
    01986   // we are potentially fetching a reference to a another Window object here.
    01987   // i.e. we may be accessing objects from another interpreter instance.
    01988   // Therefore we have to be a bit careful with memory management.
    01989   if (frame) {
    01990     return Window::retrieve(frame);
    01991   }
    01992
    01993   return ObjectImp::get(exec, p);
    01994 }
    01995
    01997
    01998 const ClassInfo Location::info = { "Location", 0, &LocationTable, 0 };
    01999 /*
    02000 @begin LocationTable 11
    02001   hash      Location::Hash      DontDelete
    02002   host      Location::Host      DontDelete
    02003   hostname  Location::Hostname  DontDelete
    02004   href      Location::Href      DontDelete
    02005   pathname  Location::Pathname  DontDelete
    02006   port      Location::Port      DontDelete
    02007   protocol  Location::Protocol  DontDelete
    02008   search    Location::Search    DontDelete
    02009   [[==]]    Location::EqualEqual    DontDelete|ReadOnly
    02010   assign    Location::Assign    DontDelete|Function 1
    02011   toString  Location::ToString  DontDelete|Function 0
    02012   replace   Location::Replace   DontDelete|Function 1
    02013   reload    Location::Reload    DontDelete|Function 0
    02014 @end
    02015 */
    02016 IMPLEMENT_PROTOFUNC_DOM(LocationFunc)
    02017 Location::Location(khtml::ChildFrame *f) : m_frame(f)
    02018 {
    02019   //kdDebug(6070) << "Location::Location " << this << " m_part=" << (void*)m_part << endl;
    02020 }
    02021
    02022 Location::~Location()
    02023 {
    02024   //kdDebug(6070) << "Location::~Location " << this << " m_part=" << (void*)m_part << endl;
    02025 }
    02026
    02027 KParts::ReadOnlyPart *Location::part() const {
    02028   return m_frame ? static_cast<KParts::ReadOnlyPart *>(m_frame->m_part) : 0L;
    02029 }
    02030
    02031 Value Location::get(ExecState *exec, const Identifier &p) const
    02032 {
    02033 #ifdef KJS_VERBOSE
    02034   kdDebug(6070) << "Location::get " << p.qstring() << " m_part=" << (void*)m_frame->m_part << endl;
    02035 #endif
    02036
    02037   if (m_frame.isNull() || m_frame->m_part.isNull())
    02038     return Undefined();
    02039
    02040   const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
    02041
    02042   // properties that work on all Location objects
    02043   if ( entry && entry->value == Replace )
    02044       return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
    02045
    02046   // XSS check
    02047   const Window* window = Window::retrieveWindow( m_frame->m_part );
    02048   if ( !window || !window->isSafeScript(exec) )
    02049     return Undefined();
    02050
    02051   KURL url = m_frame->m_part->url();
    02052   if (entry)
    02053     switch (entry->value) {
    02054     case Hash:
    02055       return String( url.ref().isNull() ? QString("") : "#" + url.ref() );
    02056     case Host: {
    02057       UString str = url.host();
    02058       if (url.port())
    02059         str += ":" + QString::number((int)url.port());
    02060       return String(str);
    02061       // Note: this is the IE spec. The NS spec swaps the two, it says
    02062       // "The hostname property is the concatenation of the host and port properties, separated by a colon."
    02063       // Bleh.
    02064     }
    02065     case Hostname:
    02066       return String( url.host() );
    02067     case Href:
    02068       if (!url.hasPath())
    02069         return String( url.prettyURL()+"/" );
    02070       else
    02071         return String( url.prettyURL() );
    02072     case Pathname:
    02073       return String( url.path().isEmpty() ? QString("/") : url.path() );
    02074     case Port:
    02075       return String( url.port() ? QString::number((int)url.port()) : QString::fromLatin1("") );
    02076     case Protocol:
    02077       return String( url.protocol()+":" );
    02078     case Search:
    02079       return String( url.query() );
    02080     case EqualEqual: // [[==]]
    02081       return String(toString(exec));
    02082     case ToString:
    02083       return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
    02084     }
    02085   // Look for overrides
    02086   ValueImp * val = ObjectImp::getDirect(p);
    02087   if (val)
    02088     return Value(val);
    02089   if (entry && (entry->attr & Function))
    02090     return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
    02091
    02092   return Undefined();
    02093 }
    02094
    02095 void Location::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
    02096 {
    02097 #ifdef KJS_VERBOSE
    02098   kdDebug(6070) << "Location::put " << p.qstring() << " m_part=" << (void*)m_frame->m_part << endl;
    02099 #endif
    02100   if (m_frame.isNull() || m_frame->m_part.isNull())
    02101     return;
    02102
    02103   const Window* window = Window::retrieveWindow( m_frame->m_part );
    02104   if ( !window )
    02105     return;
    02106
    02107   KURL url = m_frame->m_part->url();
    02108
    02109   const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
    02110
    02111   if (entry) {
    02112
    02113     // XSS check. Only new hrefs can be set from other sites
    02114     if (entry->value != Href && !window->isSafeScript(exec))
    02115       return;
    02116
    02117     QString str = v.toString(exec).qstring();
    02118     switch (entry->value) {
    02119     case Href: {
    02120       KHTMLPart* p =::qt_cast<KHTMLPart*>(Window::retrieveActive(exec)->part());
    02121       if ( p )
    02122         url = p->htmlDocument().completeURL( str ).string();
    02123       else
    02124         url = str;
    02125       break;
    02126     }
    02127     case Hash:
    02128       // when the hash is already the same ignore it
    02129       if (str == url.ref()) return;
    02130       url.setRef(str);
    02131       break;
    02132     case Host: {
    02133       QString host = str.left(str.find(":"));
    02134       QString port = str.mid(str.find(":")+1);
    02135       url.setHost(host);
    02136       url.setPort(port.toUInt());
    02137       break;
    02138     }
    02139     case Hostname:
    02140       url.setHost(str);
    02141       break;
    02142     case Pathname:
    02143       url.setPath(str);
    02144       break;
    02145     case Port:
    02146       url.setPort(str.toUInt());
    02147       break;
    02148     case Protocol:
    02149       url.setProtocol(str);
    02150       break;
    02151     case Search:
    02152       url.setQuery(str);
    02153       break;
    02154     }
    02155   } else {
    02156     ObjectImp::put(exec, p, v, attr);
    02157     return;
    02158   }
    02159
    02160   Window::retrieveWindow(m_frame->m_part)->goURL(exec, url.url(), false /* don't lock history*/ );
    02161 }
    02162
    02163 Value Location::toPrimitive(ExecState *exec, Type) const
    02164 {
    02165   if (m_frame) {
    02166     Window* window = Window::retrieveWindow( m_frame->m_part );
    02167     if ( window && window->isSafeScript(exec) )
    02168       return String(toString(exec));
    02169   }
    02170   return Undefined();
    02171 }
    02172
    02173 UString Location::toString(ExecState *exec) const
    02174 {
    02175   if (m_frame) {
    02176     Window* window = Window::retrieveWindow( m_frame->m_part );
    02177     if ( window && window->isSafeScript(exec) )
    02178     {
    02179       if (!m_frame->m_part->url().hasPath())
    02180         return m_frame->m_part->url().prettyURL()+"/";
    02181       else
    02182         return m_frame->m_part->url().prettyURL();
    02183     }
    02184   }
    02185   return "";
    02186 }
    02187
    02188 Value LocationFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    02189 {
    02190   KJS_CHECK_THIS( Location, thisObj );
    02191   Location *location = static_cast<Location *>(thisObj.imp());
    02192   KParts::ReadOnlyPart *part = location->part();
    02193
    02194   if (!part) return Undefined();
    02195
    02196   Window* window = Window::retrieveWindow(part);
    02197
    02198   if ( !window->isSafeScript(exec) && id != Location::Replace)
    02199       return Undefined();
    02200
    02201   switch (id) {
    02202   case Location::Assign:
    02203   case Location::Replace:
    02204     Window::retrieveWindow(part)->goURL(exec, args[0].toString(exec).qstring(),
    02205             id == Location::Replace);
    02206     break;
    02207   case Location::Reload: {
    02208     KHTMLPart *khtmlpart = ::qt_cast<KHTMLPart *>(part);
    02209     if (part)
    02210       khtmlpart->scheduleRedirection(-1, part->url().url(), true/*lock history*/);
    02211     break;
    02212   }
    02213   case Location::ToString:
    02214     return String(location->toString(exec));
    02215   }
    02216   return Undefined();
    02217 }
    02218
    02220
    02221 const ClassInfo External::info = { "External", 0, 0, 0 };
    02222 /*
    02223 @begin ExternalTable 4
    02224   addFavorite   External::AddFavorite   DontDelete|Function 1
    02225 @end
    02226 */
    02227 IMPLEMENT_PROTOFUNC_DOM(ExternalFunc)
    02228
    02229 Value External::get(ExecState *exec, const Identifier &p) const
    02230 {
    02231   return lookupGetFunction<ExternalFunc,ObjectImp>(exec,p,&ExternalTable,this);
    02232 }
    02233
    02234 Value ExternalFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    02235 {
    02236   KJS_CHECK_THIS( External, thisObj );
    02237   External *external = static_cast<External *>(thisObj.imp());
    02238
    02239   KHTMLPart *part = external->part;
    02240   if (!part)
    02241     return Undefined();
    02242
    02243   KHTMLView *widget = part->view();
    02244
    02245   switch (id) {
    02246   case External::AddFavorite:
    02247   {
    02248     if (!widget->dialogsAllowed())
    02249       return Undefined();
    02250     part->xmlDocImpl()->updateRendering();
    02251     if (args.size() != 1 && args.size() != 2)
    02252       return Undefined();
    02253
    02254     QString url = args[0].toString(exec).qstring();
    02255     QString title;
    02256     if (args.size() == 2)
    02257       title = args[1].toString(exec).qstring();
    02258
    02259     // AK - don't do anything yet, for the moment i
    02260     // just wanted the base js handling code in cvs
    02261     return Undefined();
    02262
    02263     QString question;
    02264     if ( title.isEmpty() )
    02265       question = i18n("Do you want a bookmark pointing to the location \"%1\" to be added to your collection?")
    02266                  .arg(url);
    02267     else
    02268       question = i18n("Do you want a bookmark pointing to the location \"%1\" titled \"%2\" to be added to your collection?")
    02269                  .arg(url).arg(title);
    02270
    02271     emit part->browserExtension()->requestFocus(part);
    02272
    02273     QString caption;
    02274     if (!part->url().host().isEmpty())
    02275        caption = part->url().host() + " - ";
    02276     caption += i18n("JavaScript Attempted Bookmark Insert");
    02277
    02278     if (KMessageBox::warningYesNo(
    02279           widget, question, caption,
    02280           i18n("Insert"), i18n("Disallow")) == KMessageBox::Yes)
    02281     {
    02282       KBookmarkManager *mgr = KBookmarkManager::userBookmarksManager();
    02283       mgr->addBookmarkDialog(url,title);
    02284     }
    02285     break;
    02286   }
    02287   default:
    02288     return Undefined();
    02289   }
    02290
    02291   return Undefined();
    02292 }
    02293
    02295
    02296 const ClassInfo History::info = { "History", 0, 0, 0 };
    02297 /*
    02298 @begin HistoryTable 4
    02299   length    History::Length     DontDelete|ReadOnly
    02300   back      History::Back       DontDelete|Function 0
    02301   forward   History::Forward    DontDelete|Function 0
    02302   go        History::Go     DontDelete|Function 1
    02303 @end
    02304 */
    02305 IMPLEMENT_PROTOFUNC_DOM(HistoryFunc)
    02306
    02307 Value History::get(ExecState *exec, const Identifier &p) const
    02308 {
    02309   return lookupGet<HistoryFunc,History,ObjectImp>(exec,p,&HistoryTable,this);
    02310 }
    02311
    02312 Value History::getValueProperty(ExecState *, int token) const
    02313 {
    02314   // if previous or next is implemented, make sure its not a major
    02315   // privacy leak (see i.e. http://security.greymagic.com/adv/gm005-op/)
    02316   switch (token) {
    02317   case Length:
    02318   {
    02319     KParts::BrowserExtension *ext = part->browserExtension();
    02320     if ( !ext )
    02321       return Number( 0 );
    02322
    02323     KParts::BrowserInterface *iface = ext->browserInterface();
    02324     if ( !iface )
    02325       return Number( 0 );
    02326
    02327     QVariant length = iface->property( "historyLength" );
    02328
    02329     if ( length.type() != QVariant::UInt )
    02330       return Number( 0 );
    02331
    02332     return Number( length.toUInt() );
    02333   }
    02334   default:
    02335     kdDebug(6070) << "WARNING: Unhandled token in History::getValueProperty : " << token << endl;
    02336     return Undefined();
    02337   }
    02338 }
    02339
    02340 Value HistoryFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    02341 {
    02342   KJS_CHECK_THIS( History, thisObj );
    02343   History *history = static_cast<History *>(thisObj.imp());
    02344
    02345   Value v = args[0];
    02346   Number n;
    02347   if(!v.isNull())
    02348     n = v.toInteger(exec);
    02349
    02350   int steps;
    02351   switch (id) {
    02352   case History::Back:
    02353     steps = -1;
    02354     break;
    02355   case History::Forward:
    02356     steps = 1;
    02357     break;
    02358   case History::Go:
    02359     steps = n.intValue();
    02360     break;
    02361   default:
    02362     return Undefined();
    02363   }
    02364
    02365   // Special case for go(0) from a frame -> reload only the frame
    02366   // go(i!=0) from a frame navigates into the history of the frame only,
    02367   // in both IE and NS (but not in Mozilla).... we can't easily do that
    02368   // in Konqueror...
    02369   if (!steps) // add && history->part->parentPart() to get only frames, but doesn't matter
    02370   {
    02371     history->part->openURL( history->part->url() );
    02372   } else
    02373   {
    02374     // Delay it.
    02375     // Testcase: history.back(); alert("hello");
    02376     Window* window = Window::retrieveWindow( history->part );
    02377     window->delayedGoHistory( steps );
    02378   }
    02379   return Undefined();
    02380 }
    02381
    02383
    02384 #ifdef Q_WS_QWS
    02385
    02386 const ClassInfo Konqueror::info = { "Konqueror", 0, 0, 0 };
    02387
    02388 bool Konqueror::hasProperty(ExecState *exec, const Identifier &p) const
    02389 {
    02390   if ( p.qstring().startsWith( "goHistory" ) ) return false;
    02391
    02392   return true;
    02393 }
    02394
    02395 Value Konqueror::get(ExecState *exec, const Identifier &p) const
    02396 {
    02397   if ( p == "goHistory" || part->url().protocol() != "http" || part->url().host() != "localhost" )
    02398     return Undefined();
    02399
    02400   KParts::BrowserExtension *ext = part->browserExtension();
    02401   if ( ext ) {
    02402     KParts::BrowserInterface *iface = ext->browserInterface();
    02403     if ( iface ) {
    02404       QVariant prop = iface->property( p.qstring().latin1() );
    02405
    02406       if ( prop.isValid() ) {
    02407         switch( prop.type() ) {
    02408         case QVariant::Int:
    02409           return Number( prop.toInt() );
    02410         case QVariant::String:
    02411           return String( prop.toString() );
    02412         default:
    02413           break;
    02414         }
    02415       }
    02416     }
    02417   }
    02418
    02419   return Value( new KonquerorFunc(this, p.qstring().latin1() ) );
    02420 }
    02421
    02422 Value KonquerorFunc::tryCall(ExecState *exec, Object &, const List &args)
    02423 {
    02424   KParts::BrowserExtension *ext = konqueror->part->browserExtension();
    02425
    02426   if(!ext)
    02427     return Undefined();
    02428
    02429   KParts::BrowserInterface *iface = ext->browserInterface();
    02430
    02431   if ( !iface )
    02432     return Undefined();
    02433
    02434   QCString n = m_name.data();
    02435   n += "()";
    02436   iface->callMethod( n.data(), QVariant() );
    02437
    02438   return Undefined();
    02439 }
    02440
    02441 UString Konqueror::toString(ExecState *) const
    02442 {
    02443   return UString("[object Konqueror]");
    02444 }
    02445
    02446 #endif
    02447
    02448
    02449 #include "kjs_window.moc"

This file is part of the documentation for khtml Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:33:19 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003