00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023
00024 #include "khtmlview.h"
00025 #include "khtml_part.h"
00026 #include "khtmlpart_p.h"
00027 #include "khtml_settings.h"
00028 #include "xml/dom2_eventsimpl.h"
00029 #include "xml/dom_docimpl.h"
00030 #include "misc/htmltags.h"
00031 #include "html/html_documentimpl.h"
00032 #include "rendering/render_frames.h"
00033
00034 #include <qstylesheet.h>
00035 #include <qtimer.h>
00036 #include <qpaintdevicemetrics.h>
00037 #include <qapplication.h>
00038 #include <kdebug.h>
00039 #include <kmessagebox.h>
00040 #include <kinputdialog.h>
00041 #include <klocale.h>
00042 #include <kmdcodec.h>
00043 #include <kparts/browserinterface.h>
00044 #include <kwin.h>
00045
00046 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00047 #include <kwinmodule.h>
00048 #endif
00049
00050 #ifndef KONQ_EMBEDDED
00051 #include <kbookmarkmanager.h>
00052 #endif
00053 #include <kglobalsettings.h>
00054 #include <assert.h>
00055 #include <qstyle.h>
00056 #include <qobjectlist.h>
00057 #include <kstringhandler.h>
00058
00059 #include "kjs_proxy.h"
00060 #include "kjs_window.h"
00061 #include "kjs_navigator.h"
00062 #include "kjs_mozilla.h"
00063 #include "kjs_html.h"
00064 #include "kjs_range.h"
00065 #include "kjs_traversal.h"
00066 #include "kjs_css.h"
00067 #include "kjs_events.h"
00068 #include "kjs_views.h"
00069 #include "xmlhttprequest.h"
00070 #include "xmlserializer.h"
00071 #include "domparser.h"
00072
00073 using namespace KJS;
00074
00075 namespace KJS {
00076
00077 class History : public ObjectImp {
00078 friend class HistoryFunc;
00079 public:
00080 History(ExecState *exec, KHTMLPart *p)
00081 : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
00082 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00083 Value getValueProperty(ExecState *exec, int token) const;
00084 virtual const ClassInfo* classInfo() const { return &info; }
00085 static const ClassInfo info;
00086 enum { Back, Forward, Go, Length };
00087 private:
00088 QGuardedPtr<KHTMLPart> part;
00089 };
00090
00091 class External : public ObjectImp {
00092 friend class ExternalFunc;
00093 public:
00094 External(ExecState *exec, KHTMLPart *p)
00095 : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
00096 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00097 virtual const ClassInfo* classInfo() const { return &info; }
00098 static const ClassInfo info;
00099 enum { AddFavorite };
00100 private:
00101 QGuardedPtr<KHTMLPart> part;
00102 };
00103
00104 class FrameArray : public ObjectImp {
00105 public:
00106 FrameArray(ExecState *exec, KHTMLPart *p)
00107 : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
00108 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00109 virtual Value call(ExecState *exec, Object &thisObj, const List &args);
00110 virtual bool implementsCall() const { return true; }
00111 private:
00112 QGuardedPtr<KHTMLPart> part;
00113 };
00114
00115 #ifdef Q_WS_QWS
00116 class KonquerorFunc : public DOMFunction {
00117 public:
00118 KonquerorFunc(ExecState *exec, const Konqueror* k, const char* name)
00119 : DOMFunction(exec), konqueror(k), m_name(name) { }
00120 virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args);
00121
00122 private:
00123 const Konqueror* konqueror;
00124 QCString m_name;
00125 };
00126 #endif
00127 }
00128
00129 #include "kjs_window.lut.h"
00130 #include "rendering/render_replaced.h"
00131
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
00149
00150
00151 Screen::Screen(ExecState *exec)
00152 : ObjectImp(exec->interpreter()->builtinObjectPrototype()) {}
00153
00154 Value Screen::get(ExecState *exec, const Identifier &p) const
00155 {
00156 #ifdef KJS_VERBOSE
00157 kdDebug(6070) << "Screen::get " << p.qstring() << endl;
00158 #endif
00159 return lookupGetValue<Screen,ObjectImp>(exec,p,&ScreenTable,this);
00160 }
00161
00162 Value Screen::getValueProperty(ExecState *exec, int token) const
00163 {
00164 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00165 KWinModule info(0, KWinModule::INFO_DESKTOP);
00166 #endif
00167 QWidget *thisWidget = Window::retrieveActive(exec)->part()->widget();
00168 QRect sg = KGlobalSettings::desktopGeometry(thisWidget);
00169
00170 switch( token ) {
00171 case Height:
00172 return Number(sg.height());
00173 case Width:
00174 return Number(sg.width());
00175 case ColorDepth:
00176 case PixelDepth: {
00177 QPaintDeviceMetrics m(QApplication::desktop());
00178 return Number(m.depth());
00179 }
00180 case AvailLeft: {
00181 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00182 QRect clipped = info.workArea().intersect(sg);
00183 return Number(clipped.x()-sg.x());
00184 #else
00185 return Number(10);
00186 #endif
00187 }
00188 case AvailTop: {
00189 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00190 QRect clipped = info.workArea().intersect(sg);
00191 return Number(clipped.y()-sg.y());
00192 #else
00193 return Number(10);
00194 #endif
00195 }
00196 case AvailHeight: {
00197 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00198 QRect clipped = info.workArea().intersect(sg);
00199 return Number(clipped.height());
00200 #else
00201 return Number(100);
00202 #endif
00203 }
00204 case AvailWidth: {
00205 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00206 QRect clipped = info.workArea().intersect(sg);
00207 return Number(clipped.width());
00208 #else
00209 return Number(100);
00210 #endif
00211 }
00212 default:
00213 kdDebug(6070) << "WARNING: Screen::getValueProperty unhandled token " << token << endl;
00214 return Undefined();
00215 }
00216 }
00217
00219
00220 const ClassInfo Window::info = { "Window", &DOMAbstractView::info, &WindowTable, 0 };
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 IMPLEMENT_PROTOFUNC_DOM(WindowFunc)
00339
00340 Window::Window(khtml::ChildFrame *p)
00341 : ObjectImp(), m_frame(p), screen(0), history(0), external(0), m_frames(0), loc(0), m_evt(0)
00342 {
00343 winq = new WindowQObject(this);
00344
00345 }
00346
00347 Window::~Window()
00348 {
00349 delete winq;
00350 }
00351
00352 Window *Window::retrieveWindow(KParts::ReadOnlyPart *p)
00353 {
00354 Object obj = Object::dynamicCast( retrieve( p ) );
00355 #ifndef NDEBUG
00356
00357 KHTMLPart *part = ::qt_cast<KHTMLPart *>(p);
00358 if ( part && part->jScriptEnabled() )
00359 {
00360 assert( obj.isValid() );
00361 #ifndef QWS
00362 assert( dynamic_cast<KJS::Window*>(obj.imp()) );
00363 #endif
00364 }
00365 #endif
00366 if ( !obj.isValid() )
00367 return 0;
00368 return static_cast<KJS::Window*>(obj.imp());
00369 }
00370
00371 Window *Window::retrieveActive(ExecState *exec)
00372 {
00373 ValueImp *imp = exec->interpreter()->globalObject().imp();
00374 assert( imp );
00375 #ifndef QWS
00376 assert( dynamic_cast<KJS::Window*>(imp) );
00377 #endif
00378 return static_cast<KJS::Window*>(imp);
00379 }
00380
00381 Value Window::retrieve(KParts::ReadOnlyPart *p)
00382 {
00383 assert(p);
00384 KHTMLPart * part = ::qt_cast<KHTMLPart *>(p);
00385 KJSProxy *proxy = 0L;
00386 if (!part) {
00387 part = ::qt_cast<KHTMLPart *>(p->parent());
00388 if (part)
00389 proxy = part->framejScript(p);
00390 } else
00391 proxy = part->jScript();
00392 if (proxy) {
00393 #ifdef KJS_VERBOSE
00394 kdDebug(6070) << "Window::retrieve part=" << part << " '" << part->name() << "' interpreter=" << proxy->interpreter() << " window=" << proxy->interpreter()->globalObject().imp() << endl;
00395 #endif
00396 return proxy->interpreter()->globalObject();
00397 } else {
00398 #ifdef KJS_VERBOSE
00399 kdDebug(6070) << "Window::retrieve part=" << p << " '" << p->name() << "' no jsproxy." << endl;
00400 #endif
00401 return Undefined();
00402 }
00403 }
00404
00405 Location *Window::location() const
00406 {
00407 if (!loc)
00408 const_cast<Window*>(this)->loc = new Location(m_frame);
00409 return loc;
00410 }
00411
00412 ObjectImp* Window::frames( ExecState* exec ) const
00413 {
00414 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
00415 if (part)
00416 return m_frames ? m_frames :
00417 (const_cast<Window*>(this)->m_frames = new FrameArray(exec, part));
00418 return 0L;
00419 }
00420
00421
00422 void Window::mark()
00423 {
00424 ObjectImp::mark();
00425 if (screen && !screen->marked())
00426 screen->mark();
00427 if (history && !history->marked())
00428 history->mark();
00429 if (external && !external->marked())
00430 external->mark();
00431 if (m_frames && !m_frames->marked())
00432 m_frames->mark();
00433
00434 if (loc && !loc->marked())
00435 loc->mark();
00436 if (winq)
00437 winq->mark();
00438 }
00439
00440 bool Window::hasProperty(ExecState *exec, const Identifier &p) const
00441 {
00442
00443 if (m_frame.isNull() || m_frame->m_part.isNull())
00444 return ( p == "closed" );
00445
00446 if (ObjectImp::hasProperty(exec, p))
00447 return true;
00448
00449 if (Lookup::findEntry(&WindowTable, p))
00450 return true;
00451
00452 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
00453 if (!part)
00454 return false;
00455
00456 QString q = p.qstring();
00457 if (part->findFramePart(p.qstring()))
00458 return true;
00459
00460 bool ok;
00461 unsigned int i = p.toArrayIndex(&ok);
00462 if (ok) {
00463 QPtrList<KParts::ReadOnlyPart> frames = part->frames();
00464 unsigned int len = frames.count();
00465 if (i < len)
00466 return true;
00467 }
00468
00469
00470 if (part->document().isHTMLDocument()) {
00471 DOM::HTMLDocument doc = part->htmlDocument();
00472
00473
00474 if (static_cast<DOM::DocumentImpl*>(doc.handle())->underDocNamedCache().get(p.qstring()))
00475 return true;
00476
00477 return !doc.getElementById(p.string()).isNull();
00478 }
00479
00480 return false;
00481 }
00482
00483 UString Window::toString(ExecState *) const
00484 {
00485 return "[object Window]";
00486 }
00487
00488 Value Window::get(ExecState *exec, const Identifier &p) const
00489 {
00490 #ifdef KJS_VERBOSE
00491 kdDebug(6070) << "Window("<<this<<")::get " << p.qstring() << endl;
00492 #endif
00493
00494 if (m_frame.isNull() || m_frame->m_part.isNull()) {
00495 if ( p == "closed" )
00496 return Boolean( true );
00497 return Undefined();
00498 }
00499
00500
00501 ValueImp *val = getDirect(p);
00502 if (val) {
00503
00504 return isSafeScript(exec) ? Value(val) : Undefined();
00505 }
00506
00507 const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
00508 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
00509
00510
00511 if (entry) {
00512
00513 switch(entry->value) {
00514 case Closed:
00515 return Boolean( false );
00516 case _Location:
00517
00518 return Value(location());
00519 case _Window:
00520 case Self:
00521 return retrieve(m_frame->m_part);
00522 default:
00523 break;
00524 }
00525 if (!part)
00526 return Undefined();
00527
00528 switch(entry->value) {
00529 case Frames:
00530 return Value(frames(exec));
00531 case Opener:
00532 if (!part->opener())
00533 return Null();
00534 else
00535 return retrieve(part->opener());
00536 case Parent:
00537 return retrieve(part->parentPart() ? part->parentPart() : (KHTMLPart*)part);
00538 case Top: {
00539 KHTMLPart *p = part;
00540 while (p->parentPart())
00541 p = p->parentPart();
00542 return retrieve(p);
00543 }
00544 case Alert:
00545 case Confirm:
00546 case Prompt:
00547 case Open:
00548 case Close:
00549 case Focus:
00550 case Blur:
00551 case AToB:
00552 case BToA:
00553 case GetComputedStyle:
00554 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
00555 default:
00556 break;
00557 }
00558 } else if (!part) {
00559
00560 QString rvalue;
00561 KParts::LiveConnectExtension::Type rtype;
00562 unsigned long robjid;
00563 if (m_frame->m_liveconnect &&
00564 isSafeScript(exec) &&
00565 m_frame->m_liveconnect->get(0, p.qstring(), rtype, robjid, rvalue))
00566 return getLiveConnectValue(m_frame->m_liveconnect, p.qstring(), rtype, rvalue, robjid);
00567 return Undefined();
00568 }
00569
00570 if (isSafeScript(exec) && entry)
00571 {
00572
00573 switch( entry->value ) {
00574 case Crypto:
00575 return Undefined();
00576 case DefaultStatus:
00577 return String(UString(part->jsDefaultStatusBarText()));
00578 case Status:
00579 return String(UString(part->jsStatusBarText()));
00580 case Document:
00581 if (part->document().isNull()) {
00582 kdDebug(6070) << "Document.write: adding <HTML><BODY> to create document" << endl;
00583 part->begin();
00584 part->write("<HTML><BODY>");
00585 part->end();
00586 }
00587 return getDOMNode(exec,part->document());
00588 case FrameElement:
00589 if (m_frame->m_frame)
00590 return getDOMNode(exec,m_frame->m_frame->element());
00591 else
00592 return Undefined();
00593 case Node:
00594 return getNodeConstructor(exec);
00595 case Range:
00596 return getRangeConstructor(exec);
00597 case NodeFilter:
00598 return getNodeFilterConstructor(exec);
00599 case DOMException:
00600 return getDOMExceptionConstructor(exec);
00601 case CSSRule:
00602 return getCSSRuleConstructor(exec);
00603 case EventCtor:
00604 return getEventConstructor(exec);
00605 case MutationEventCtor:
00606 return getMutationEventConstructor(exec);
00607 case KeyboardEventCtor:
00608 return getKeyboardEventConstructor(exec);
00609 case EventExceptionCtor:
00610 return getEventExceptionConstructor(exec);
00611 case _History:
00612 return Value(history ? history :
00613 (const_cast<Window*>(this)->history = new History(exec,part)));
00614
00615 case _External:
00616 return Value(external ? external :
00617 (const_cast<Window*>(this)->external = new External(exec,part)));
00618
00619 case Event:
00620 if (m_evt)
00621 return getDOMEvent(exec,*m_evt);
00622 else {
00623 #ifdef KJS_VERBOSE
00624 kdDebug(6070) << "WARNING: window(" << this << "," << part->name() << ").event, no event!" << endl;
00625 #endif
00626 return Undefined();
00627 }
00628 case InnerHeight:
00629 if (!part->view())
00630 return Undefined();
00631 khtml::RenderWidget::flushWidgetResizes();
00632 return Number(part->view()->visibleHeight());
00633 case InnerWidth:
00634 if (!part->view())
00635 return Undefined();
00636 khtml::RenderWidget::flushWidgetResizes();
00637 return Number(part->view()->visibleWidth());
00638 case Length:
00639 return Number(part->frames().count());
00640 case Name:
00641 return String(part->name());
00642 case SideBar:
00643 return Value(new MozillaSidebarExtension(exec, part));
00644 case _Navigator:
00645 case ClientInformation: {
00646
00647 Value nav( new Navigator(exec, part) );
00648 const_cast<Window *>(this)->put(exec, "navigator", nav, DontDelete|ReadOnly|Internal);
00649 const_cast<Window *>(this)->put(exec, "clientInformation", nav, DontDelete|ReadOnly|Internal);
00650 return nav;
00651 }
00652 #ifdef Q_WS_QWS
00653 case _Konqueror: {
00654 Value k( new Konqueror(part) );
00655 const_cast<Window *>(this)->put(exec, "konqueror", k, DontDelete|ReadOnly|Internal);
00656 return k;
00657 }
00658 #endif
00659 case OffscreenBuffering:
00660 return Boolean(true);
00661 case OuterHeight:
00662 case OuterWidth:
00663 {
00664 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00665 if (!part->widget())
00666 return Number(0);
00667 KWin::WindowInfo inf = KWin::windowInfo(part->widget()->topLevelWidget()->winId());
00668 return Number(entry->value == OuterHeight ?
00669 inf.geometry().height() : inf.geometry().width());
00670 #else
00671 return Number(entry->value == OuterHeight ?
00672 part->view()->height() : part->view()->width());
00673 #endif
00674 }
00675 case PageXOffset:
00676 return Number(part->view()->contentsX());
00677 case PageYOffset:
00678 return Number(part->view()->contentsY());
00679 case Personalbar:
00680 return Undefined();
00681 case ScreenLeft:
00682 case ScreenX: {
00683 if (!part->view())
00684 return Undefined();
00685 QRect sg = KGlobalSettings::desktopGeometry(part->view());
00686 return Number(part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
00687 }
00688 case ScreenTop:
00689 case ScreenY: {
00690 if (!part->view())
00691 return Undefined();
00692 QRect sg = KGlobalSettings::desktopGeometry(part->view());
00693 return Number(part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
00694 }
00695 case ScrollX: {
00696 if (!part->view())
00697 return Undefined();
00698 return Number(part->view()->contentsX());
00699 }
00700 case ScrollY: {
00701 if (!part->view())
00702 return Undefined();
00703 return Number(part->view()->contentsY());
00704 }
00705 case Scrollbars:
00706 return Undefined();
00707 case _Screen:
00708 return Value(screen ? screen :
00709 (const_cast<Window*>(this)->screen = new Screen(exec)));
00710 case Image:
00711 return Value(new ImageConstructorImp(exec, part->document()));
00712 case Option:
00713 return Value(new OptionConstructorImp(exec, part->document()));
00714 case XMLHttpRequest:
00715 return Value(new XMLHttpRequestConstructorImp(exec, part->document()));
00716 case XMLSerializer:
00717 return Value(new XMLSerializerConstructorImp(exec));
00718 case DOMParser:
00719 return Value(new DOMParserConstructorImp(exec, part->xmlDocImpl()));
00720 case Scroll:
00721 case ScrollBy:
00722 case ScrollTo:
00723 case MoveBy:
00724 case MoveTo:
00725 case ResizeBy:
00726 case ResizeTo:
00727 case CaptureEvents:
00728 case ReleaseEvents:
00729 case AddEventListener:
00730 case RemoveEventListener:
00731 case SetTimeout:
00732 case ClearTimeout:
00733 case SetInterval:
00734 case ClearInterval:
00735 case Print:
00736 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
00737
00738 case Navigate:
00739
00740
00741 if ( exec->interpreter()->compatMode() == Interpreter::NetscapeCompat )
00742 return Undefined();
00743 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
00744 case Onabort:
00745 return getListener(exec,DOM::EventImpl::ABORT_EVENT);
00746 case Onblur:
00747 return getListener(exec,DOM::EventImpl::BLUR_EVENT);
00748 case Onchange:
00749 return getListener(exec,DOM::EventImpl::CHANGE_EVENT);
00750 case Onclick:
00751 return getListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT);
00752 case Ondblclick:
00753 return getListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT);
00754 case Ondragdrop:
00755 return getListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT);
00756 case Onerror:
00757 return getListener(exec,DOM::EventImpl::ERROR_EVENT);
00758 case Onfocus:
00759 return getListener(exec,DOM::EventImpl::FOCUS_EVENT);
00760 case Onkeydown:
00761 return getListener(exec,DOM::EventImpl::KEYDOWN_EVENT);
00762 case Onkeypress:
00763 return getListener(exec,DOM::EventImpl::KEYPRESS_EVENT);
00764 case Onkeyup:
00765 return getListener(exec,DOM::EventImpl::KEYUP_EVENT);
00766 case Onload:
00767 return getListener(exec,DOM::EventImpl::LOAD_EVENT);
00768 case Onmousedown:
00769 return getListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT);
00770 case Onmousemove:
00771 return getListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT);
00772 case Onmouseout:
00773 return getListener(exec,DOM::EventImpl::MOUSEOUT_EVENT);
00774 case Onmouseover:
00775 return getListener(exec,DOM::EventImpl::MOUSEOVER_EVENT);
00776 case Onmouseup:
00777 return getListener(exec,DOM::EventImpl::MOUSEUP_EVENT);
00778 case Onmove:
00779 return getListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT);
00780 case Onreset:
00781 return getListener(exec,DOM::EventImpl::RESET_EVENT);
00782 case Onresize:
00783 return getListener(exec,DOM::EventImpl::RESIZE_EVENT);
00784 case Onselect:
00785 return getListener(exec,DOM::EventImpl::SELECT_EVENT);
00786 case Onsubmit:
00787 return getListener(exec,DOM::EventImpl::SUBMIT_EVENT);
00788 case Onunload:
00789 return getListener(exec,DOM::EventImpl::UNLOAD_EVENT);
00790 }
00791 }
00792
00793
00794
00795
00796 Object proto = Object::dynamicCast(prototype());
00797 assert(proto.isValid());
00798 if (p == specialPrototypePropertyName)
00799 return isSafeScript(exec) ? Value(proto) : Undefined();
00800 Value val2 = proto.get(exec, p);
00801 if (!val2.isA(UndefinedType)) {
00802 return isSafeScript(exec) ? val2 : Undefined();
00803 }
00804
00805 KParts::ReadOnlyPart *rop = part->findFramePart( p.qstring() );
00806 if (rop)
00807 return retrieve(rop);
00808
00809
00810 bool ok;
00811 unsigned int i = p.toArrayIndex(&ok);
00812 if (ok) {
00813 QPtrList<KParts::ReadOnlyPart> frames = part->frames();
00814 unsigned int len = frames.count();
00815 if (i < len) {
00816 KParts::ReadOnlyPart* frame = frames.at(i);
00817 if (frame)
00818 return Window::retrieve(frame);
00819 }
00820 }
00821
00822
00823 if (isSafeScript(exec) && part->document().isHTMLDocument()) {
00824 DOM::DocumentImpl* docImpl = part->xmlDocImpl();
00825 DOM::ElementMappingCache::ItemInfo* info = docImpl->underDocNamedCache().get(p.qstring());
00826 if (info) {
00827
00828
00829
00830 DOM::DOMString propertyDOMString = p.string();
00831 if (info->nd && DOM::HTMLMappedNameCollectionImpl::matchesName(info->nd,
00832 DOM::HTMLCollectionImpl::WINDOW_NAMED_ITEMS, propertyDOMString)) {
00833 return getDOMNode(exec, info->nd);
00834 } else {
00835
00836 DOM::HTMLMappedNameCollection coll(docImpl, DOM::HTMLCollectionImpl::WINDOW_NAMED_ITEMS, propertyDOMString);
00837
00838 if (coll.length() == 1)
00839 return getDOMNode(exec, coll.firstItem());
00840 else if (coll.length() > 1)
00841 return getHTMLCollection(exec, coll);
00842 }
00843 }
00844 DOM::Element element = part->document().getElementById(p.string());
00845 if ( !element.isNull() )
00846 return getDOMNode(exec, element );
00847 }
00848
00849
00850
00851 #ifdef KJS_VERBOSE
00852 kdDebug(6070) << "WARNING: Window::get property not found: " << p.qstring() << endl;
00853 #endif
00854 return Undefined();
00855 }
00856
00857 void Window::put(ExecState* exec, const Identifier &propertyName, const Value &value, int attr)
00858 {
00859
00860 if (m_frame.isNull() || m_frame->m_part.isNull()) {
00861
00862 return;
00863 }
00864
00865
00866
00867 if ( (attr != None && attr != DontDelete) ||
00868
00869 ( isSafeScript( exec ) && ObjectImp::getDirect(propertyName) ) )
00870 {
00871 ObjectImp::put( exec, propertyName, value, attr );
00872 return;
00873 }
00874
00875 const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
00876 if (entry && !m_frame.isNull() && !m_frame->m_part.isNull())
00877 {
00878 #ifdef KJS_VERBOSE
00879 kdDebug(6070) << "Window("<<this<<")::put " << propertyName.qstring() << endl;
00880 #endif
00881 switch( entry->value) {
00882 case _Location:
00883 goURL(exec, value.toString(exec).qstring(), false );
00884 return;
00885 default:
00886 break;
00887 }
00888 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
00889 if (part) {
00890 switch( entry->value ) {
00891 case Status: {
00892 if (isSafeScript(exec) && part->settings()->windowStatusPolicy(part->url().host())
00893 == KHTMLSettings::KJSWindowStatusAllow) {
00894 String s = value.toString(exec);
00895 part->setJSStatusBarText(s.value().qstring());
00896 }
00897 return;
00898 }
00899 case DefaultStatus: {
00900 if (isSafeScript(exec) && part->settings()->windowStatusPolicy(part->url().host())
00901 == KHTMLSettings::KJSWindowStatusAllow) {
00902 String s = value.toString(exec);
00903 part->setJSDefaultStatusBarText(s.value().qstring());
00904 }
00905 return;
00906 }
00907 case Onabort:
00908 if (isSafeScript(exec))
00909 setListener(exec, DOM::EventImpl::ABORT_EVENT,value);
00910 return;
00911 case Onblur:
00912 if (isSafeScript(exec))
00913 setListener(exec, DOM::EventImpl::BLUR_EVENT,value);
00914 return;
00915 case Onchange:
00916 if (isSafeScript(exec))
00917 setListener(exec, DOM::EventImpl::CHANGE_EVENT,value);
00918 return;
00919 case Onclick:
00920 if (isSafeScript(exec))
00921 setListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT,value);
00922 return;
00923 case Ondblclick:
00924 if (isSafeScript(exec))
00925 setListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT,value);
00926 return;
00927 case Ondragdrop:
00928 if (isSafeScript(exec))
00929 setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
00930 return;
00931 case Onerror:
00932 if (isSafeScript(exec))
00933 setListener(exec,DOM::EventImpl::ERROR_EVENT,value);
00934 return;
00935 case Onfocus:
00936 if (isSafeScript(exec))
00937 setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
00938 return;
00939 case Onkeydown:
00940 if (isSafeScript(exec))
00941 setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
00942 return;
00943 case Onkeypress:
00944 if (isSafeScript(exec))
00945 setListener(exec,DOM::EventImpl::KEYPRESS_EVENT,value);
00946 return;
00947 case Onkeyup:
00948 if (isSafeScript(exec))
00949 setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
00950 return;
00951 case Onload:
00952 if (isSafeScript(exec))
00953 setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
00954 return;
00955 case Onmousedown:
00956 if (isSafeScript(exec))
00957 setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
00958 return;
00959 case Onmousemove:
00960 if (isSafeScript(exec))
00961 setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
00962 return;
00963 case Onmouseout:
00964 if (isSafeScript(exec))
00965 setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
00966 return;
00967 case Onmouseover:
00968 if (isSafeScript(exec))
00969 setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
00970 return;
00971 case Onmouseup:
00972 if (isSafeScript(exec))
00973 setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
00974 return;
00975 case Onmove:
00976 if (isSafeScript(exec))
00977 setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
00978 return;
00979 case Onreset:
00980 if (isSafeScript(exec))
00981 setListener(exec,DOM::EventImpl::RESET_EVENT,value);
00982 return;
00983 case Onresize:
00984 if (isSafeScript(exec))
00985 setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
00986 return;
00987 case Onselect:
00988 if (isSafeScript(exec))
00989 setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
00990 return;
00991 case Onsubmit:
00992 if (isSafeScript(exec))
00993 setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
00994 return;
00995 case Onunload:
00996 if (isSafeScript(exec))
00997 setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
00998 return;
00999 case Name:
01000 if (isSafeScript(exec))
01001 part->setName( value.toString(exec).qstring().local8Bit().data() );
01002 return;
01003 default:
01004 break;
01005 }
01006 }
01007 }
01008 if (m_frame->m_liveconnect &&
01009 isSafeScript(exec) &&
01010 m_frame->m_liveconnect->put(0, propertyName.qstring(), value.toString(exec).qstring()))
01011 return;
01012 if (isSafeScript(exec)) {
01013
01014 ObjectImp::put(exec, propertyName, value, attr);
01015 }
01016 }
01017
01018 bool Window::toBoolean(ExecState *) const
01019 {
01020 return !m_frame.isNull() && !m_frame->m_part.isNull();
01021 }
01022
01023 DOM::AbstractView Window::toAbstractView() const
01024 {
01025 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01026 if (!part)
01027 return DOM::AbstractView();
01028 return part->document().defaultView();
01029 }
01030
01031 void Window::scheduleClose()
01032 {
01033 kdDebug(6070) << "Window::scheduleClose window.close() " << m_frame << endl;
01034 Q_ASSERT(winq);
01035 QTimer::singleShot( 0, winq, SLOT( timeoutClose() ) );
01036 }
01037
01038 void Window::closeNow()
01039 {
01040 if (m_frame.isNull() || m_frame->m_part.isNull()) {
01041 kdDebug(6070) << k_funcinfo << "part is deleted already" << endl;
01042 } else {
01043 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01044 if (!part) {
01045 kdDebug(6070) << "closeNow on non KHTML part" << endl;
01046 } else {
01047
01048
01049 part->setName( 0 );
01050 part->deleteLater();
01051 part = 0;
01052 }
01053 }
01054 }
01055
01056 void Window::afterScriptExecution()
01057 {
01058 DOM::DocumentImpl::updateDocumentsRendering();
01059 QValueList<DelayedAction> delayedActions = m_delayed;
01060 m_delayed.clear();
01061 QValueList<DelayedAction>::Iterator it = delayedActions.begin();
01062 for ( ; it != delayedActions.end() ; ++it )
01063 {
01064 switch ((*it).actionId) {
01065 case DelayedClose:
01066 scheduleClose();
01067 return;
01068 case DelayedGoHistory:
01069 goHistory( (*it).param.toInt() );
01070 break;
01071 case NullAction:
01072
01073 break;
01074 };
01075 }
01076 }
01077
01078 bool Window::checkIsSafeScript(KParts::ReadOnlyPart *activePart) const
01079 {
01080 if (m_frame.isNull() || m_frame->m_part.isNull()) {
01081 kdDebug(6070) << "Window::isSafeScript: accessing deleted part !" << endl;
01082 return false;
01083 }
01084 if (!activePart) {
01085 kdDebug(6070) << "Window::isSafeScript: current interpreter's part is 0L!" << endl;
01086 return false;
01087 }
01088 if ( activePart == m_frame->m_part )
01089 return true;
01090
01091 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01092 if (!part)
01093 return true;
01094
01095 if ( part->document().isNull() )
01096 return true;
01097
01098 DOM::HTMLDocument thisDocument = part->htmlDocument();
01099 if ( thisDocument.isNull() ) {
01100 kdDebug(6070) << "Window::isSafeScript: trying to access an XML document !?" << endl;
01101 return false;
01102 }
01103
01104 KHTMLPart *activeKHTMLPart = ::qt_cast<KHTMLPart *>(activePart);
01105 if (!activeKHTMLPart)
01106 return true;
01107
01108 DOM::HTMLDocument actDocument = activeKHTMLPart->htmlDocument();
01109 if ( actDocument.isNull() ) {
01110 kdDebug(6070) << "Window::isSafeScript: active part has no document!" << endl;
01111 return false;
01112 }
01113 DOM::DOMString actDomain = actDocument.domain();
01114 DOM::DOMString thisDomain = thisDocument.domain();
01115
01116 if ( actDomain == thisDomain ) {
01117 #ifdef KJS_VERBOSE
01118
01119 #endif
01120 return true;
01121 }
01122
01123 kdDebug(6070) << "WARNING: JavaScript: access denied for current frame '" << actDomain.string() << "' to frame '" << thisDomain.string() << "'" << endl;
01124
01125 return false;
01126 }
01127
01128 void Window::setListener(ExecState *exec, int eventId, Value func)
01129 {
01130 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01131 if (!part || !isSafeScript(exec))
01132 return;
01133 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(part->htmlDocument().handle());
01134 if (!doc)
01135 return;
01136
01137 doc->setHTMLWindowEventListener(eventId,getJSEventListener(func,true));
01138 }
01139
01140 Value Window::getListener(ExecState *exec, int eventId) const
01141 {
01142 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01143 if (!part || !isSafeScript(exec))
01144 return Undefined();
01145 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(part->htmlDocument().handle());
01146 if (!doc)
01147 return Undefined();
01148
01149 DOM::EventListener *listener = doc->getHTMLWindowEventListener(eventId);
01150 if (listener && static_cast<JSEventListener*>(listener)->listenerObjImp())
01151 return static_cast<JSEventListener*>(listener)->listenerObj();
01152 else
01153 return Null();
01154 }
01155
01156
01157 JSEventListener *Window::getJSEventListener(const Value& val, bool html)
01158 {
01159
01160 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01161 if (!part || val.type() != ObjectType)
01162 return 0;
01163
01164
01165 Object listenerObject = Object::dynamicCast(val);
01166 ObjectImp *listenerObjectImp = listenerObject.imp();
01167
01168
01169 if (!listenerObject.implementsCall() && part && part->jScript() && part->jScript()->interpreter())
01170 {
01171 Interpreter *interpreter = part->jScript()->interpreter();
01172
01173
01174 Value handleEventValue = listenerObject.get(interpreter->globalExec(), Identifier("handleEvent"));
01175 Object handleEventObject = Object::dynamicCast(handleEventValue);
01176
01177 if(handleEventObject.isValid() && handleEventObject.implementsCall())
01178 {
01179 listenerObject = handleEventObject;
01180 listenerObjectImp = handleEventObject.imp();
01181 }
01182 }
01183
01184 JSEventListener *existingListener = jsEventListeners[listenerObjectImp];
01185 if (existingListener) {
01186 if ( existingListener->isHTMLEventListener() != html )
01187
01188 kdWarning() << "getJSEventListener: event listener already found but with html=" << !html << " - please report this, we thought it would never happen" << endl;
01189 return existingListener;
01190 }
01191
01192
01193 return new JSEventListener(listenerObject, listenerObjectImp, Object(this), html);
01194 }
01195
01196 JSLazyEventListener *Window::getJSLazyEventListener(const QString& code, const QString& name, DOM::NodeImpl *node)
01197 {
01198 return new JSLazyEventListener(code, name, Object(this), node);
01199 }
01200
01201 void Window::clear( ExecState *exec )
01202 {
01203 delete winq;
01204 winq = 0L;
01205
01206 deleteAllProperties( exec );
01207
01208
01209 QPtrDictIterator<JSEventListener> it(jsEventListeners);
01210 for (; it.current(); ++it)
01211 it.current()->clear();
01212
01213 jsEventListeners.clear();
01214
01215 if (m_frame) {
01216 KJSProxy* proxy = m_frame->m_jscript;
01217 if (proxy)
01218 {
01219 winq = new WindowQObject(this);
01220
01221 KJS::Interpreter *interpreter = proxy->interpreter();
01222 interpreter->initGlobalObject();
01223 }
01224 }
01225 }
01226
01227 void Window::setCurrentEvent( DOM::Event *evt )
01228 {
01229 m_evt = evt;
01230
01231 }
01232
01233 void Window::goURL(ExecState* exec, const QString& url, bool lockHistory)
01234 {
01235 Window* active = Window::retrieveActive(exec);
01236 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01237 KHTMLPart *active_part = ::qt_cast<KHTMLPart *>(active->part());
01238
01239 if (active_part && part) {
01240 if (url[0] == QChar('#')) {
01241 part->gotoAnchor(url.mid(1));
01242 } else {
01243 QString dstUrl = active_part->htmlDocument().completeURL(url).string();
01244 kdDebug(6070) << "Window::goURL dstUrl=" << dstUrl << endl;
01245
01246
01247
01248 if ( isSafeScript(exec) ||
01249 dstUrl.find(QString::fromLatin1("javascript:"), 0, false) != 0 )
01250 part->scheduleRedirection(-1,
01251 dstUrl,
01252 lockHistory);
01253 }
01254 } else if (!part && !m_frame->m_part.isNull()) {
01255 KParts::BrowserExtension *b = KParts::BrowserExtension::childObject(m_frame->m_part);
01256 if (b)
01257 b->emit openURLRequest(m_frame->m_frame->element()->getDocument()->completeURL(url));
01258 kdDebug() << "goURL for ROPart" << endl;
01259 }
01260 }
01261
01262 KParts::ReadOnlyPart *Window::part() const {
01263 return m_frame.isNull() ? 0L : static_cast<KParts::ReadOnlyPart *>(m_frame->m_part);
01264 }
01265
01266 void Window::delayedGoHistory( int steps )
01267 {
01268 m_delayed.append( DelayedAction( DelayedGoHistory, steps ) );
01269 }
01270
01271 void Window::goHistory( int steps )
01272 {
01273 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01274 if(!part)
01275
01276 return;
01277 KParts::BrowserExtension *ext = part->browserExtension();
01278 if(!ext)
01279 return;
01280 KParts::BrowserInterface *iface = ext->browserInterface();
01281
01282 if ( !iface )
01283 return;
01284
01285 iface->callMethod( "goHistory(int)", steps );
01286
01287 }
01288
01289 void KJS::Window::resizeTo(QWidget* tl, int width, int height)
01290 {
01291 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01292 if(!part)
01293
01294 return;
01295 KParts::BrowserExtension *ext = part->browserExtension();
01296 if (!ext) {
01297 kdDebug(6070) << "Window::resizeTo found no browserExtension" << endl;
01298 return;
01299 }
01300
01301
01302 if ( width < 100 || height < 100 ) {
01303 kdDebug(6070) << "Window::resizeTo refused, window would be too small ("<<width<<","<<height<<")" << endl;
01304 return;
01305 }
01306
01307 QRect sg = KGlobalSettings::desktopGeometry(tl);
01308
01309 if ( width > sg.width() || height > sg.height() ) {
01310 kdDebug(6070) << "Window::resizeTo refused, window would be too big ("<<width<<","<<height<<")" << endl;
01311 return;
01312 }
01313
01314 kdDebug(6070) << "resizing to " << width << "x" << height << endl;
01315
01316 emit ext->resizeTopLevelWidget( width, height );
01317
01318
01319
01320 int right = tl->x() + tl->frameGeometry().width();
01321 int bottom = tl->y() + tl->frameGeometry().height();
01322 int moveByX = 0;
01323 int moveByY = 0;
01324 if ( right > sg.right() )
01325 moveByX = - right + sg.right();
01326 if ( bottom > sg.bottom() )
01327 moveByY = - bottom + sg.bottom();
01328 if ( moveByX || moveByY )
01329 emit ext->moveTopLevelWidget( tl->x() + moveByX , tl->y() + moveByY );
01330 }
01331
01332 Value Window::openWindow(ExecState *exec, const List& args)
01333 {
01334 KHTMLPart *part = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01335 if (!part)
01336 return Undefined();
01337 KHTMLView *widget = part->view();
01338 Value v = args[0];
01339 QString str;
01340 if (v.isValid() && !v.isA(UndefinedType))
01341 str = v.toString(exec).qstring();
01342
01343
01344 KURL url;
01345 if (!str.isEmpty())
01346 {
01347 KHTMLPart* p = ::qt_cast<KHTMLPart *>(Window::retrieveActive(exec)->m_frame->m_part);
01348 if ( p )
01349 url = p->htmlDocument().completeURL(str).string();
01350 if ( !p ||
01351 !static_cast<DOM::DocumentImpl*>(p->htmlDocument().handle())->isURLAllowed(url.url()) )
01352 return Undefined();
01353 }
01354
01355 KHTMLSettings::KJSWindowOpenPolicy policy =
01356 part->settings()->windowOpenPolicy(part->url().host());
01357 if ( policy == KHTMLSettings::KJSWindowOpenAsk ) {
01358 emit part->browserExtension()->requestFocus(part);
01359 QString caption;
01360 if (!part->url().host().isEmpty())
01361 caption = part->url().host() + " - ";
01362 caption += i18n( "Confirmation: JavaScript Popup" );
01363 if ( KMessageBox::questionYesNo(widget,
01364 str.isEmpty() ?
01365 i18n( "This site is requesting to open up a new browser "
01366 "window via JavaScript.\n"
01367 "Do you want to allow this?" ) :
01368 i18n( "<qt>This site is requesting to open<p>%1</p>in a new browser window via JavaScript.<br />"
01369 "Do you want to allow this?</qt>").arg(KStringHandler::csqueeze(url.htmlURL(), 100)),
01370 caption, i18n("Allow"), i18n("Do Not Allow") ) == KMessageBox::Yes )
01371 policy = KHTMLSettings::KJSWindowOpenAllow;
01372 } else if ( policy == KHTMLSettings::KJSWindowOpenSmart )
01373 {
01374
01375 if (static_cast<ScriptInterpreter *>(exec->interpreter())->isWindowOpenAllowed())
01376 policy = KHTMLSettings::KJSWindowOpenAllow;
01377 }
01378
01379 QString frameName = args.size() > 1 ? args[1].toString(exec).qstring() : QString("_blank");
01380
01381 v = args[2];
01382 QString features;
01383 if (!v.isNull() && v.type() != UndefinedType && v.toString(exec).size() > 0) {
01384 features = v.toString(exec).qstring();
01385
01386 if (features.startsWith("\'") && features.endsWith("\'"))
01387 features = features.mid(1, features.length()-2);
01388 }
01389
01390 if ( policy != KHTMLSettings::KJSWindowOpenAllow ) {
01391 if ( url.isEmpty() )
01392 part->setSuppressedPopupIndicator(true, 0);
01393 else {
01394 part->setSuppressedPopupIndicator(true, part);
01395 m_suppressedWindowInfo.append( SuppressedWindowInfo( url, frameName, features ) );
01396 }
01397 return Undefined();
01398 } else {
01399 return executeOpenWindow(exec, url, frameName, features);
01400 }
01401 }
01402
01403 Value Window::executeOpenWindow(ExecState *exec, const KURL& url, const QString& frameName, const QString& features)
01404 {
01405 KHTMLPart *p = ::qt_cast<KHTMLPart *>(m_frame->m_part);
01406 KHTMLView *widget = p->view();
01407 KParts::WindowArgs winargs;
01408
01409
01410 if (!features.isEmpty()) {
01411
01412 winargs.menuBarVisible = false;
01413 winargs.toolBarsVisible = false;
01414 winargs.statusBarVisible = false;
01415 winargs.scrollBarsVisible = false;
01416 QStringList flist = QStringList::split(',', features);
01417 QStringList::ConstIterator it = flist.begin();
01418 while (it != flist.end()) {
01419 QString s = *it++;
01420 QString key, val;
01421 int pos = s.find('=');
01422 if (pos >= 0) {
01423 key = s.left(pos).stripWhiteSpace().lower();
01424 val = s.mid(pos + 1).stripWhiteSpace().lower();
01425 QRect screen = KGlobalSettings::desktopGeometry(widget->topLevelWidget());
01426
01427 if (key == "left" || key == "screenx") {
01428 winargs.x = (int)val.toFloat() + screen.x();
01429 if (winargs.x < screen.x() || winargs.x > screen.right())
01430 winargs.x = screen.x();
01431 } else if (key == "top" || key == "screeny") {
01432 winargs.y = (int)val.toFloat() + screen.y();
01433 if (winargs.y < screen.y() || winargs.y > screen.bottom())
01434 winargs.y = screen.y();
01435 } else if (key == "height") {
01436 winargs.height = (int)val.toFloat() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
01437 if (winargs.height > screen.height())
01438 winargs.height = screen.height();
01439 if (winargs.height < 100)
01440 winargs.height = 100;
01441 } else if (key == "width") {
01442 winargs.width = (int)val.toFloat() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
01443 if (winargs.width > screen.width())
01444 winargs.width = screen.width();
01445 if (winargs.width < 100)
01446 winargs.width = 100;
01447 } else {
01448 goto boolargs;
01449 }
01450 continue;
01451 } else {
01452
01453 key = s.stripWhiteSpace().lower();
01454 val = "1";
01455 }
01456 boolargs:
01457 if (key == "menubar")
01458 winargs.menuBarVisible = (val == "1" || val == "yes");
01459 else if (key == "toolbar")
01460 winargs.toolBarsVisible = (val == "1" || val == "yes");
01461 else if (key == "location")
01462 winargs.toolBarsVisible = (val == "1" || val == "yes");
01463 else if (key == "status" || key == "statusbar")
01464 winargs.statusBarVisible = (val == "1" || val == "yes");
01465 else if (key == "scrollbars")
01466 winargs.scrollBarsVisible = (val == "1" || val == "yes");
01467 else if (key == "resizable")
01468 winargs.resizable = (val == "1" || val == "yes");
01469 else if (key == "fullscreen")
01470 winargs.fullscreen = (val == "1" || val == "yes");
01471 }
01472 }
01473
01474 KParts::URLArgs uargs;
01475 uargs.frameName = frameName;
01476
01477 if ( uargs.frameName.lower() == "_top" )
01478 {
01479 while ( p->parentPart() )
01480 p = p->parentPart();
01481 Window::retrieveWindow(p)->goURL(exec, url.url(), false );
01482 return Window::retrieve(p);
01483 }
01484 if ( uargs.frameName.lower() == "_parent" )
01485 {
01486 if ( p->parentPart() )
01487 p = p->parentPart();
01488 Window::retrieveWindow(p)->goURL(exec, url.url(), false );
01489 return Window::retrieve(p);
01490 }
01491 if ( uargs.frameName.lower() == "_self")
01492 {
01493 Window::retrieveWindow(p)->goURL(exec, url.url(), false );
01494 return Window::retrieve(p);
01495 }
01496 if ( uargs.frameName.lower() == "replace" )
01497 {
01498 Window::retrieveWindow(p)->goURL(exec, url.url(), true );
01499 return Window::retrieve(p);
01500 }
01501 uargs.serviceType = "text/html";
01502
01503
01504 KParts::ReadOnlyPart *newPart = 0L;
01505 emit p->browserExtension()->createNewWindow(KURL(), uargs,winargs,newPart);
01506 if (newPart && ::qt_cast<KHTMLPart*>(newPart)) {
01507 KHTMLPart *khtmlpart = static_cast<KHTMLPart*>(newPart);
01508
01509 khtmlpart->setOpener(p);
01510 khtmlpart->setOpenedByJS(true);
01511 if (khtmlpart->document().isNull()) {
01512 khtmlpart->begin();
01513 khtmlpart->write("<HTML><BODY>");
01514 khtmlpart->end();
01515 if ( p->docImpl() ) {
01516
01517 khtmlpart->docImpl()->setDomain( p->docImpl()->domain());
01518 khtmlpart->docImpl()->setBaseURL( p->docImpl()->baseURL() );
01519 }
01520 }
01521 uargs.serviceType = QString::null;
01522 if (uargs.frameName.lower() == "_blank")
01523 uargs.frameName = QString::null;
01524 if (!url.isEmpty())
01525 emit khtmlpart->browserExtension()->openURLRequest(url,uargs);
01526 return Window::retrieve(khtmlpart);
01527 } else
01528 return Undefined();
01529 }
01530
01531 void Window::forgetSuppressedWindows()
01532 {
01533 m_suppressedWindowInfo.clear();
01534 }
01535
01536 void Window::showSuppressedWindows()
01537 {
01538 KHTMLPart *part = ::qt_cast<KHTMLPart *>( m_frame->m_part );
01539 KJS::Interpreter *interpreter = part->jScript()->interpreter();
01540 ExecState *exec = interpreter->globalExec();
01541
01542 QValueList<SuppressedWindowInfo> suppressedWindowInfo = m_suppressedWindowInfo;
01543 m_suppressedWindowInfo.clear();
01544 QValueList<SuppressedWindowInfo>::Iterator it = suppressedWindowInfo.begin();
01545 for ( ; it != suppressedWindowInfo.end() ; ++it ) {
01546 executeOpenWindow(exec, (*it).url, (*it).frameName, (*it).features);
01547 }
01548 }
01549
01550 Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01551 {
01552 KJS_CHECK_THIS( Window, thisObj );
01553 Window *window = static_cast<Window *>(thisObj.imp());
01554 QString str, str2;
01555
01556 KHTMLPart *part = ::qt_cast<KHTMLPart *>(window->m_frame->m_part);
01557 if (!part)
01558 return Undefined();
01559
01560 KHTMLView *widget = part->view();
01561 Value v = args[0];
01562 UString s;
01563 if (v.isValid() && !v.isA(UndefinedType)) {
01564 s = v.toString(exec);
01565 str = s.qstring();
01566 }
01567
01568 QString caption;
01569 if (part && !part->url().host().isEmpty())
01570 caption = part->url().host() + " - ";
01571 caption += "JavaScript";
01572
01573 switch(id) {
01574 case Window::Alert:
01575 if (!widget->dialogsAllowed())
01576 return Undefined();
01577 if ( part && part->xmlDocImpl() )
01578 part->xmlDocImpl()->updateRendering();
01579 if ( part )
01580 emit part->browserExtension()->requestFocus(part);
01581 KMessageBox::error(widget, QStyleSheet::convertFromPlainText(str), caption);
01582 return Undefined();
01583 case Window::Confirm:
01584 if (!widget->dialogsAllowed())
01585 return Undefined();
01586 if ( part && part->xmlDocImpl() )
01587 part->xmlDocImpl()->updateRendering();
01588 if ( part )
01589 emit part->browserExtension()->requestFocus(part);
01590 return Boolean((KMessageBox::warningYesNo(widget, QStyleSheet::convertFromPlainText(str), caption,
01591 KStdGuiItem::ok(), KStdGuiItem::cancel()) == KMessageBox::Yes));
01592 case Window::Prompt:
01593 #ifndef KONQ_EMBEDDED
01594 if (!widget->dialogsAllowed())
01595 return Undefined();
01596 if ( part && part->xmlDocImpl() )
01597 part->xmlDocImpl()->updateRendering();
01598 if ( part )
01599 emit part->browserExtension()->requestFocus(part);
01600 bool ok;
01601 if (args.size() >= 2)
01602 str2 = KInputDialog::getText(caption,
01603 QStyleSheet::convertFromPlainText(str),
01604 args[1].toString(exec).qstring(), &ok, widget);
01605 else
01606 str2 = KInputDialog::getText(caption,
01607 QStyleSheet::convertFromPlainText(str),
01608 QString::null, &ok, widget);
01609 if ( ok )
01610 return String(str2);
01611 else
01612 return Null();
01613 #else
01614 return Undefined();
01615 #endif
01616 case Window::GetComputedStyle: {
01617 if ( !part || !part->xmlDocImpl() )
01618 return Undefined();
01619 DOM::Node arg0 = toNode(args[0]);
01620 if (arg0.nodeType() != DOM::Node::ELEMENT_NODE)
01621 return Undefined();
01622 else
01623 return getDOMCSSStyleDeclaration(exec, part->document().defaultView().getComputedStyle(static_cast<DOM::Element>(arg0),
01624 args[1].toString(exec).string()));
01625 }
01626 case Window::Open:
01627 return window->openWindow(exec, args);
01628 case Window::Close: {
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639 bool doClose = false;
01640 if (!part->openedByJS())
01641 {
01642
01643
01644 History history(exec,part);
01645
01646 if ( history.get( exec, "length" ).toInt32(exec) <= 1 )
01647 {
01648 doClose = true;
01649 }
01650 else
01651 {
01652
01653 emit part->browserExtension()->requestFocus(part);
01654 if ( KMessageBox::questionYesNo( window->part()->widget(),
01655 i18n("Close window?"), i18n("Confirmation Required"),
01656 KStdGuiItem::close(), KStdGuiItem::cancel() )
01657 == KMessageBox::Yes )
01658 doClose = true;
01659 }
01660 }
01661 else
01662 doClose = true;
01663
01664 if (doClose)
01665 {
01666
01667
01668
01669 if ( Window::retrieveActive(exec) == window ) {
01670 if (widget) {
01671
01672
01673 widget->closeChildDialogs();
01674 }
01675
01676
01677 Window* w = const_cast<Window*>(window);
01678 w->m_delayed.append( Window::DelayedAction( Window::DelayedClose ) );
01679 } else {
01680
01681 (const_cast<Window*>(window))->closeNow();
01682 }
01683 }
01684 return Undefined();
01685 }
01686 case Window::Navigate:
01687 window->goURL(exec, args[0].toString(exec).qstring(), false );
01688 return Undefined();
01689 case Window::Focus: {
01690 KHTMLSettings::KJSWindowFocusPolicy policy =
01691 part->settings()->windowFocusPolicy(part->url().host());
01692 if(policy == KHTMLSettings::KJSWindowFocusAllow && widget) {
01693 widget->topLevelWidget()->raise();
01694 KWin::deIconifyWindow( widget->topLevelWidget()->winId() );
01695 widget->setActiveWindow();
01696 emit part->browserExtension()->requestFocus(part);
01697 }
01698 return Undefined();
01699 }
01700 case Window::Blur:
01701
01702 return Undefined();
01703 case Window::BToA:
01704 case Window::AToB: {
01705 if (!s.is8Bit())
01706 return Undefined();
01707 QByteArray in, out;
01708 char *binData = s.ascii();
01709 in.setRawData( binData, s.size() );
01710 if (id == Window::AToB)
01711 KCodecs::base64Decode( in, out );
01712 else
01713 KCodecs::base64Encode( in, out );
01714 in.resetRawData( binData, s.size() );
01715 UChar *d = new UChar[out.size()];
01716 for (uint i = 0; i < out.size(); i++)
01717 d[i].uc = (uchar) out[i];
01718 UString ret(d, out.size(), false );
01719 return String(ret);
01720 }
01721
01722 };
01723
01724
01725
01726 if (!window->isSafeScript(exec))
01727 return Undefined();
01728
01729 switch (id) {
01730 case Window::ScrollBy:
01731 if(args.size() == 2 && widget)
01732 widget->scrollBy(args[0].toInt32(exec), args[1].toInt32(exec));
01733 return Undefined();
01734 case Window::Scroll:
01735 case Window::ScrollTo:
01736 if(args.size() == 2 && widget)
01737 widget->setContentsPos(args[0].toInt32(exec), args[1].toInt32(exec));
01738 return Undefined();
01739 case Window::MoveBy: {
01740 KHTMLSettings::KJSWindowMovePolicy policy =
01741 part->settings()->windowMovePolicy(part->url().host());
01742 if(policy == KHTMLSettings::KJSWindowMoveAllow && args.size() == 2 && widget)
01743 {
01744 KParts::BrowserExtension *ext = part->browserExtension();
01745 if (ext) {
01746 QWidget * tl = widget->topLevelWidget();
01747 QRect sg = KGlobalSettings::desktopGeometry(tl);
01748
01749 QPoint dest = tl->pos() + QPoint( args[0].toInt32(exec), args[1].toInt32(exec) );
01750
01751 if ( dest.x() >= sg.x() && dest.y() >= sg.x() &&
01752 dest.x()+tl->width() <= sg.width()+sg.x() &&
01753 dest.y()+tl->height() <= sg.height()+sg.y() )
01754 emit ext->moveTopLevelWidget( dest.x(), dest.y() );
01755 }
01756 }
01757 return Undefined();
01758 }
01759 case Window::MoveTo: {
01760 KHTMLSettings::KJSWindowMovePolicy policy =
01761 part->settings()->windowMovePolicy(part->url().host());
01762 if(policy == KHTMLSettings::KJSWindowMoveAllow && args.size() == 2 && widget)
01763 {
01764 KParts::BrowserExtension *ext = part->browserExtension();
01765 if (ext) {
01766 QWidget * tl = widget->topLevelWidget();
01767 QRect sg = KGlobalSettings::desktopGeometry(tl);
01768
01769 QPoint dest( args[0].toInt32(exec)+sg.x(), args[1].toInt32(exec)+sg.y() );
01770
01771 if ( dest.x() >= sg.x() && dest.y() >= sg.y() &&
01772 dest.x()+tl->width() <= sg.width()+sg.x() &&
01773 dest.y()+tl->height() <= sg.height()+sg.y() )
01774 emit ext->moveTopLevelWidget( dest.x(), dest.y() );
01775 }
01776 }
01777 return Undefined();
01778 }
01779 case Window::ResizeBy: {
01780 KHTMLSettings::KJSWindowResizePolicy policy =
01781 part->settings()->windowResizePolicy(part->url().host());
01782 if(policy == KHTMLSettings::KJSWindowResizeAllow
01783 && args.size() == 2 && widget)
01784 {
01785 QWidget * tl = widget->topLevelWidget();
01786 QRect geom = tl->frameGeometry();
01787 window->resizeTo( tl,
01788 geom.width() + args[0].toInt32(exec),
01789 geom.height() + args[1].toInt32(exec) );
01790 }
01791 return Undefined();
01792 }
01793 case Window::ResizeTo: {
01794 KHTMLSettings::KJSWindowResizePolicy policy =
01795 part->settings()->windowResizePolicy(part->url().host());
01796 if(policy == KHTMLSettings::KJSWindowResizeAllow
01797 && args.size() == 2 && widget)
01798 {
01799 QWidget * tl = widget->topLevelWidget();
01800 window->resizeTo( tl, args[0].toInt32(exec), args[1].toInt32(exec) );
01801 }
01802 return Undefined();
01803 }
01804 case Window::SetTimeout:
01805 case Window::SetInterval: {
01806 bool singleShot;
01807 int i;
01808 if (args.size() == 0)
01809 return Undefined();
01810 if (args.size() > 1) {
01811 singleShot = (id == Window::SetTimeout);
01812 i = args[1].toInt32(exec);
01813 } else {
01814
01815 singleShot = true;
01816 i = 4;
01817 }
01818 if (v.isA(StringType)) {
01819 int r = (const_cast<Window*>(window))->winq->installTimeout(Identifier(s), i, singleShot );
01820 return Number(r);
01821 }
01822 else if (v.isA(ObjectType) && Object::dynamicCast(v).implementsCall()) {
01823 Object func = Object::dynamicCast(v);
01824 List funcArgs;
01825 ListIterator it = args.begin();
01826 int argno = 0;
01827 while (it != args.end()) {
01828 Value arg = it++;
01829 if (argno++ >= 2)
01830 funcArgs.append(arg);
01831 }
01832 if (args.size() < 2)
01833 funcArgs.append(Number(i));
01834 int r = (const_cast<Window*>(window))->winq->installTimeout(func, funcArgs, i, singleShot );
01835 return Number(r);
01836 }
01837 else
01838 return Undefined();
01839 }
01840 case Window::ClearTimeout:
01841 case Window::ClearInterval:
01842 (const_cast<Window*>(window))->winq->clearTimeout(v.toInt32(exec));
01843 return Undefined();
01844 case Window::Print:
01845 if ( widget ) {
01846
01847 widget->print();
01848
01849 }
01850 case Window::CaptureEvents:
01851 case Window::ReleaseEvents:
01852
01853 break;
01854 case Window::AddEventListener: {
01855 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
01856 if (listener) {
01857 DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
01858 docimpl->addWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
01859 }
01860 return Undefined();
01861 }
01862 case Window::RemoveEventListener: {
01863 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
01864 if (listener) {
01865 DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
01866 docimpl->removeWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
01867 }
01868 return Undefined();
01869 }
01870
01871 }
01872 return Undefined();
01873 }
01874
01876
01877
01878 ScheduledAction::ScheduledAction(Object _func, List _args, DateTimeMS _nextTime, int _interval, bool _singleShot,
01879 int _timerId)
01880 {
01881
01882 func = static_cast<ObjectImp*>(_func.imp());
01883 args = _args;
01884 isFunction = true;
01885 singleShot = _singleShot;
01886 nextTime = _nextTime;
01887 interval = _interval;
01888 executing = false;
01889 timerId = _timerId;
01890 }
01891
01892
01893 ScheduledAction::ScheduledAction(QString _code, DateTimeMS _nextTime, int _interval, bool _singleShot, int _timerId)
01894 {
01895
01896
01897
01898 func = 0;
01899 code = _code;
01900 isFunction = false;
01901 singleShot = _singleShot;
01902 nextTime = _nextTime;
01903 interval = _interval;
01904 executing = false;
01905 timerId = _timerId;
01906 }
01907
01908 bool ScheduledAction::execute(Window *window)
01909 {
01910 KHTMLPart *part = ::qt_cast<KHTMLPart *>(window->m_frame->m_part);
01911 if (!part || !part->jScriptEnabled())
01912 return false;
01913 ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(part->jScript()->interpreter());
01914
01915 interpreter->setProcessingTimerCallback(true);
01916
01917
01918 if (isFunction) {
01919 if (func->implementsCall()) {
01920
01921 Q_ASSERT( part );
01922 if ( part )
01923 {
01924 KJS::Interpreter *interpreter = part->jScript()->interpreter();
01925 ExecState *exec = interpreter->globalExec();
01926 Q_ASSERT( window == interpreter->globalObject().imp() );
01927 Object obj( window );
01928 func->call(exec,obj,args);
01929 if (exec->hadException())
01930 exec->clearException();
01931
01932
01933 part->document().updateRendering();
01934 }
01935 }
01936 }
01937 else {
01938 part->executeScript(DOM::Node(), code);
01939 }
01940
01941 interpreter->setProcessingTimerCallback(false);
01942 return true;
01943 }
01944
01945 void ScheduledAction::mark()
01946 {
01947 if (func && !func->marked())
01948 func->mark();
01949 args.mark();
01950 }
01951
01952 ScheduledAction::~ScheduledAction()
01953 {
01954
01955 }
01956
01958
01959 WindowQObject::WindowQObject(Window *w)
01960 : parent(w)
01961 {
01962
01963 if ( !parent->m_frame )
01964 kdDebug(6070) << "WARNING: null part in " << k_funcinfo << endl;
01965 else
01966 connect( parent->m_frame, SIGNAL( destroyed() ),
01967 this, SLOT( parentDestroyed() ) );
01968 pausedTime = 0;
01969 lastTimerId = 0;
01970 currentlyDispatching = false;
01971 }
01972
01973 WindowQObject::~WindowQObject()
01974 {
01975
01976 parentDestroyed();
01977 }
01978
01979 void WindowQObject::parentDestroyed()
01980 {
01981 killTimers();
01982
01983 QPtrListIterator<ScheduledAction> it(scheduledActions);
01984 for (; it.current(); ++it)
01985 delete it.current();
01986 scheduledActions.clear();
01987 }
01988
01989 int WindowQObject::installTimeout(const Identifier &handler, int t, bool singleShot)
01990 {
01991 int id = ++lastTimerId;
01992 if (t < 10) t = 10;
01993 DateTimeMS nextTime = DateTimeMS::now().addMSecs(-pausedTime + t);
01994
01995 ScheduledAction *action = new ScheduledAction(handler.qstring(),nextTime,t,singleShot,id);
01996 scheduledActions.append(action);
01997 setNextTimer();
01998 return id;
01999 }
02000
02001 int WindowQObject::installTimeout(const Value &func, List args, int t, bool singleShot)
02002 {
02003 Object objFunc = Object::dynamicCast( func );
02004 if (!objFunc.isValid())
02005 return 0;
02006 int id = ++lastTimerId;
02007 if (t < 10) t = 10;
02008
02009 DateTimeMS nextTime = DateTimeMS::now().addMSecs(-pausedTime + t);
02010 ScheduledAction *action = new ScheduledAction(objFunc,args,nextTime,t,singleShot,id);
02011 scheduledActions.append(action);
02012 setNextTimer();
02013 return id;
02014 }
02015
02016 void WindowQObject::clearTimeout(int timerId)
02017 {
02018 QPtrListIterator<ScheduledAction> it(scheduledActions);
02019 for (; it.current(); ++it) {
02020 ScheduledAction *action = it.current();
02021 if (action->timerId == timerId) {
02022 scheduledActions.removeRef(action);
02023 if (!action->executing)
02024 delete action;
02025 return;
02026 }
02027 }
02028 }
02029
02030 bool WindowQObject::hasTimers() const
02031 {
02032 return scheduledActions.count();
02033 }
02034
02035 void WindowQObject::mark()
02036 {
02037 QPtrListIterator<ScheduledAction> it(scheduledActions);
02038 for (; it.current(); ++it)
02039 it.current()->mark();
02040 }
02041
02042 void WindowQObject::timerEvent(QTimerEvent *)
02043 {
02044 killTimers();
02045
02046 if (scheduledActions.isEmpty())
02047 return;
02048
02049 currentlyDispatching = true;
02050
02051
02052 DateTimeMS currentActual = DateTimeMS::now();
02053 DateTimeMS currentAdjusted = currentActual.addMSecs(-pausedTime);
02054
02055
02056
02057 QPtrList<ScheduledAction> toExecute;
02058 QPtrListIterator<ScheduledAction> it(scheduledActions);
02059 for (; it.current(); ++it)
02060 if (currentAdjusted >= it.current()->nextTime)
02061 toExecute.append(it.current());
02062
02063
02064 it = QPtrListIterator<ScheduledAction>(toExecute);
02065 for (; it.current(); ++it) {
02066 ScheduledAction *action = it.current();
02067 if (!scheduledActions.containsRef(action))
02068 continue;
02069
02070 action->executing = true;
02071
02072 if (parent->part()) {
02073 bool ok = action->execute(parent);
02074 if ( !ok )
02075 scheduledActions.removeRef( action );
02076 }
02077
02078 if (action->singleShot) {
02079 scheduledActions.removeRef(action);
02080 }
02081
02082 action->executing = false;
02083
02084 if (!scheduledActions.containsRef(action))
02085 delete action;
02086 else
02087 action->nextTime = action->nextTime.addMSecs(action->interval);
02088 }
02089
02090 pausedTime += currentActual.msecsTo(DateTimeMS::now());
02091
02092 currentlyDispatching = false;
02093
02094
02095 setNextTimer();
02096 }
02097
02098 DateTimeMS DateTimeMS::addMSecs(int s) const
02099 {
02100 DateTimeMS c = *this;
02101 c.mTime = mTime.addMSecs(s);
02102 if (s > 0)
02103 {
02104 if (c.mTime < mTime)
02105 c.mDate = mDate.addDays(1);
02106 }
02107 else
02108 {
02109 if (c.mTime > mTime)
02110 c.mDate = mDate.addDays(-1);
02111 }
02112 return c;
02113 }
02114
02115 bool DateTimeMS::operator >(const DateTimeMS &other) const
02116 {
02117 if (mDate > other.mDate)
02118 return true;
02119
02120 if (mDate < other.mDate)
02121 return false;
02122
02123 return mTime > other.mTime;
02124 }
02125
02126 bool DateTimeMS::operator >=(const DateTimeMS &other) const
02127 {
02128 if (mDate > other.mDate)
02129 return true;
02130
02131 if (mDate < other.mDate)
02132 return false;
02133
02134 return mTime >= other.mTime;
02135 }
02136
02137 int DateTimeMS::msecsTo(const DateTimeMS &other) const
02138 {
02139 int d = mDate.daysTo(other.mDate);
02140 int ms = mTime.msecsTo(other.mTime);
02141 return d*24*60*60*1000 + ms;
02142 }
02143
02144
02145 DateTimeMS DateTimeMS::now()
02146 {
02147 DateTimeMS t;
02148 QTime before = QTime::currentTime();
02149 t.mDate = QDate::currentDate();
02150 t.mTime = QTime::currentTime();
02151 if (t.mTime < before)
02152 t.mDate = QDate::currentDate();
02153 return t;
02154 }
02155
02156 void WindowQObject::setNextTimer()
02157 {
02158 if (currentlyDispatching)
02159 return;
02160
02161 if (scheduledActions.isEmpty())
02162 return;
02163
02164 QPtrListIterator<ScheduledAction> it(scheduledActions);
02165 DateTimeMS nextTime = it.current()->nextTime;
02166 for (++it; it.current(); ++it)
02167 if (nextTime > it.current()->nextTime)
02168 nextTime = it.current()->nextTime;
02169
02170 DateTimeMS nextTimeActual = nextTime.addMSecs(pausedTime);
02171 int nextInterval = DateTimeMS::now().msecsTo(nextTimeActual);
02172 if (nextInterval < 0)
02173 nextInterval = 0;
02174 startTimer(nextInterval);
02175 }
02176
02177 void WindowQObject::timeoutClose()
02178 {
02179 parent->closeNow();
02180 }
02181
02182 Value FrameArray::get(ExecState *exec, const Identifier &p) const
02183 {
02184 #ifdef KJS_VERBOSE
02185 kdDebug(6070) << "FrameArray::get " << p.qstring() << " part=" << (void*)part << endl;
02186 #endif
02187 if (part.isNull())
02188 return Undefined();
02189
02190 QPtrList<KParts::ReadOnlyPart> frames = part->frames();
02191 unsigned int len = frames.count();
02192 if (p == lengthPropertyName)
02193 return Number(len);
02194 else if (p== "location")
02195 {
02196 Object obj = Object::dynamicCast( Window::retrieve( part ) );
02197 if ( obj.isValid() )
02198 return obj.get( exec, "location" );
02199 return Undefined();
02200 }
02201
02202
02203 KParts::ReadOnlyPart *frame = part->findFramePart(p.qstring());
02204 if (!frame) {
02205 bool ok;
02206 unsigned int i = p.toArrayIndex(&ok);
02207 if (ok && i < len)
02208 frame = frames.at(i);
02209 }
02210
02211
02212
02213
02214 if (frame) {
02215 return Window::retrieve(frame);
02216 }
02217
02218
02219
02220
02221 DOM::DocumentImpl* doc = static_cast<DOM::DocumentImpl*>(part->document().handle());
02222 DOM::HTMLCollectionImpl docuAll(doc, DOM::HTMLCollectionImpl::DOC_ALL);
02223 DOM::NodeImpl* node = docuAll.namedItem(p.string());
02224 if (node) {
02225 if (node->id() == ID_FRAME || node->id() == ID_IFRAME) {
02226
02227 KHTMLPart* part = static_cast<DOM::HTMLFrameElementImpl*>(node)->contentPart();
02228 if (part)
02229 return Value(Window::retrieveWindow(part));
02230 else
02231 return Undefined();
02232 } else {
02233
02234 return getDOMNode(exec, node);
02235 }
02236 }
02237
02238 return ObjectImp::get(exec, p);
02239 }
02240
02241 Value FrameArray::call(ExecState *exec, Object &, const List &args)
02242 {
02243
02244
02245
02246
02247 if (args.size() == 1)
02248 return get(exec, Identifier(args[0].toString(exec)));
02249
02250 return Undefined();
02251 }
02252
02253
02255
02256 const ClassInfo Location::info = { "Location", 0, &LocationTable, 0 };
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274 IMPLEMENT_PROTOFUNC_DOM(LocationFunc)
02275 Location::Location(khtml::ChildFrame *f) : m_frame(f)
02276 {
02277
02278 }
02279
02280 Location::~Location()
02281 {
02282
02283 }
02284
02285 KParts::ReadOnlyPart *Location::part() const {
02286 return m_frame ? static_cast<KParts::ReadOnlyPart *>(m_frame->m_part) : 0L;
02287 }
02288
02289 Value Location::get(ExecState *exec, const Identifier &p) const
02290 {
02291 #ifdef KJS_VERBOSE
02292 kdDebug(6070) << "Location::get " << p.qstring() << " m_part=" << (void*)m_frame->m_part << endl;
02293 #endif
02294
02295 if (m_frame.isNull() || m_frame->m_part.isNull())
02296 return Undefined();
02297
02298 const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
02299
02300
02301 if ( entry && entry->value == Replace )
02302 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
02303
02304
02305 const Window* window = Window::retrieveWindow( m_frame->m_part );
02306 if ( !window || !window->isSafeScript(exec) )
02307 return Undefined();
02308
02309 KURL url = m_frame->m_part->url();
02310 if (entry)
02311 switch (entry->value) {
02312 case Hash:
02313 return String( url.ref().isNull() ? QString("") : "#" + url.ref() );
02314 case Host: {
02315 UString str = url.host();
02316 if (url.port())
02317 str += ":" + QString::number((int)url.port());
02318 return String(str);
02319
02320
02321
02322 }
02323 case Hostname:
02324 return String( url.host() );
02325 case Href:
02326 if (!url.hasPath())
02327 return String( url.prettyURL()+"/" );
02328 else
02329 return String( url.prettyURL() );
02330 case Pathname:
02331 return String( url.path().isEmpty() ? QString("/") : url.path() );
02332 case Port:
02333 return String( url.port() ? QString::number((int)url.port()) : QString::fromLatin1("") );
02334 case Protocol:
02335 return String( url.protocol()+":" );
02336 case Search:
02337 return String( url.query() );
02338 case EqualEqual:
02339 return String(toString(exec));
02340 case ToString:
02341 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
02342 }
02343
02344 ValueImp * val = ObjectImp::getDirect(p);
02345 if (val)
02346 return Value(val);
02347 if (entry && (entry->attr & Function))
02348 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
02349
02350 return Undefined();
02351 }
02352
02353 void Location::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
02354 {
02355 #ifdef KJS_VERBOSE
02356 kdDebug(6070) << "Location::put " << p.qstring() << " m_part=" << (void*)m_frame->m_part << endl;
02357 #endif
02358 if (m_frame.isNull() || m_frame->m_part.isNull())
02359 return;
02360
02361 const Window* window = Window::retrieveWindow( m_frame->m_part );
02362 if ( !window )
02363 return;
02364
02365 KURL url = m_frame->m_part->url();
02366
02367 const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
02368
02369 if (entry) {
02370
02371
02372 if (entry->value != Href && !window->isSafeScript(exec))
02373 return;
02374
02375 QString str = v.toString(exec).qstring();
02376 switch (entry->value) {
02377 case Href: {
02378 KHTMLPart* p =::qt_cast<KHTMLPart*>(Window::retrieveActive(exec)->part());
02379 if ( p )
02380 url = p->htmlDocument().completeURL( str ).string();
02381 else
02382 url = str;
02383 break;
02384 }
02385 case Hash:
02386
02387 if (str == url.ref()) return;
02388 url.setRef(str);
02389 break;
02390 case Host: {
02391 QString host = str.left(str.find(":"));
02392 QString port = str.mid(str.find(":")+1);
02393 url.setHost(host);
02394 url.setPort(port.toUInt());
02395 break;
02396 }
02397 case Hostname:
02398 url.setHost(str);
02399 break;
02400 case Pathname:
02401 url.setPath(str);
02402 break;
02403 case Port:
02404 url.setPort(str.toUInt());
02405 break;
02406 case Protocol:
02407 url.setProtocol(str);
02408 break;
02409 case Search:
02410 url.setQuery(str);
02411 break;
02412 }
02413 } else {
02414 ObjectImp::put(exec, p, v, attr);
02415 return;
02416 }
02417
02418 Window::retrieveWindow(m_frame->m_part)->goURL(exec, url.url(), false );
02419 }
02420
02421 Value Location::toPrimitive(ExecState *exec, Type) const
02422 {
02423 if (m_frame) {
02424 Window* window = Window::retrieveWindow( m_frame->m_part );
02425 if ( window && window->isSafeScript(exec) )
02426 return String(toString(exec));
02427 }
02428 return Undefined();
02429 }
02430
02431 UString Location::toString(ExecState *exec) const
02432 {
02433 if (m_frame) {
02434 Window* window = Window::retrieveWindow( m_frame->m_part );
02435 if ( window && window->isSafeScript(exec) )
02436 {
02437 if (!m_frame->m_part->url().hasPath())
02438 return m_frame->m_part->url().prettyURL()+"/";
02439 else
02440 return m_frame->m_part->url().prettyURL();
02441 }
02442 }
02443 return "";
02444 }
02445
02446 Value LocationFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
02447 {
02448 KJS_CHECK_THIS( Location, thisObj );
02449 Location *location = static_cast<Location *>(thisObj.imp());
02450 KParts::ReadOnlyPart *part = location->part();
02451
02452 if (!part) return Undefined();
02453
02454 Window* window = Window::retrieveWindow(part);
02455
02456 if ( !window->isSafeScript(exec) && id != Location::Replace)
02457 return Undefined();
02458
02459 switch (id) {
02460 case Location::Assign:
02461 case Location::Replace:
02462 Window::retrieveWindow(part)->goURL(exec, args[0].toString(exec).qstring(),
02463 id == Location::Replace);
02464 break;
02465 case Location::Reload: {
02466 KHTMLPart *khtmlpart = ::qt_cast<KHTMLPart *>(part);
02467 if (part)
02468 khtmlpart->scheduleRedirection(-1, part->url().url(), true);
02469 break;
02470 }
02471 case Location::ToString:
02472 return String(location->toString(exec));
02473 }
02474 return Undefined();
02475 }
02476
02478
02479 const ClassInfo External::info = { "External", 0, 0, 0 };
02480
02481
02482
02483
02484
02485 IMPLEMENT_PROTOFUNC_DOM(ExternalFunc)
02486
02487 Value External::get(ExecState *exec, const Identifier &p) const
02488 {
02489 return lookupGetFunction<ExternalFunc,ObjectImp>(exec,p,&ExternalTable,this);
02490 }
02491
02492 Value ExternalFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
02493 {
02494 KJS_CHECK_THIS( External, thisObj );
02495 External *external = static_cast<External *>(thisObj.imp());
02496
02497 KHTMLPart *part = external->part;
02498 if (!part)
02499 return Undefined();
02500
02501 KHTMLView *widget = part->view();
02502
02503 switch (id) {
02504 case External::AddFavorite:
02505 {
02506 #ifndef KONQ_EMBEDDED
02507 if (!widget->dialogsAllowed())
02508 return Undefined();
02509 part->xmlDocImpl()->updateRendering();
02510 if (args.size() != 1 && args.size() != 2)
02511 return Undefined();
02512
02513 QString url = args[0].toString(exec).qstring();
02514 QString title;
02515 if (args.size() == 2)
02516 title = args[1].toString(exec).qstring();
02517
02518
02519
02520 return Undefined();
02521
02522 QString question;
02523 if ( title.isEmpty() )
02524 question = i18n("Do you want a bookmark pointing to the location \"%1\" to be added to your collection?")
02525 .arg(url);
02526 else
02527 question = i18n("Do you want a bookmark pointing to the location \"%1\" titled \"%2\" to be added to your collection?")
02528 .arg(url).arg(title);
02529
02530 emit part->browserExtension()->requestFocus(part);
02531
02532 QString caption;
02533 if (!part->url().host().isEmpty())
02534 caption = part->url().host() + " - ";
02535 caption += i18n("JavaScript Attempted Bookmark Insert");
02536
02537 if (KMessageBox::warningYesNo(
02538 widget, question, caption,
02539 i18n("Insert"), i18n("Disallow")) == KMessageBox::Yes)
02540 {
02541 KBookmarkManager *mgr = KBookmarkManager::userBookmarksManager();
02542 mgr->addBookmarkDialog(url,title);
02543 }
02544 #else
02545 return Undefined();
02546 #endif
02547 break;
02548 }
02549 default:
02550 return Undefined();
02551 }
02552
02553 return Undefined();
02554 }
02555
02557
02558 const ClassInfo History::info = { "History", 0, 0, 0 };
02559
02560
02561
02562
02563
02564
02565
02566
02567 IMPLEMENT_PROTOFUNC_DOM(HistoryFunc)
02568
02569 Value History::get(ExecState *exec, const Identifier &p) const
02570 {
02571 return lookupGet<HistoryFunc,History,ObjectImp>(exec,p,&HistoryTable,this);
02572 }
02573
02574 Value History::getValueProperty(ExecState *, int token) const
02575 {
02576
02577
02578 switch (token) {
02579 case Length:
02580 {
02581 if ( !part )
02582 return Number( 0 );
02583
02584 KParts::BrowserExtension *ext = part->browserExtension();
02585 if ( !ext )
02586 return Number( 0 );
02587
02588 KParts::BrowserInterface *iface = ext->browserInterface();
02589 if ( !iface )
02590 return Number( 0 );
02591
02592 QVariant length = iface->property( "historyLength" );
02593
02594 if ( length.type() != QVariant::UInt )
02595 return Number( 0 );
02596
02597 return Number( length.toUInt() );
02598 }
02599 default:
02600 kdDebug(6070) << "WARNING: Unhandled token in History::getValueProperty : " << token << endl;
02601 return Undefined();
02602 }
02603 }
02604
02605 Value HistoryFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
02606 {
02607 KJS_CHECK_THIS( History, thisObj );
02608 History *history = static_cast<History *>(thisObj.imp());
02609
02610 Value v = args[0];
02611 Number n;
02612 if(v.isValid())
02613 n = v.toInteger(exec);
02614
02615 int steps;
02616 switch (id) {
02617 case History::Back:
02618 steps = -1;
02619 break;
02620 case History::Forward:
02621 steps = 1;
02622 break;
02623 case History::Go:
02624 steps = n.intValue();
02625 break;
02626 default:
02627 return Undefined();
02628 }
02629
02630
02631
02632
02633
02634 if (!steps)
02635 {
02636 history->part->openURL( history->part->url() );
02637 } else
02638 {
02639
02640
02641 Window* window = Window::retrieveWindow( history->part );
02642 window->delayedGoHistory( steps );
02643 }
02644 return Undefined();
02645 }
02646
02648
02649 #ifdef Q_WS_QWS
02650
02651 const ClassInfo Konqueror::info = { "Konqueror", 0, 0, 0 };
02652
02653 bool Konqueror::hasProperty(ExecState *exec, const Identifier &p) const
02654 {
02655 if ( p.qstring().startsWith( "goHistory" ) ) return false;
02656
02657 return true;
02658 }
02659
02660 Value Konqueror::get(ExecState *exec, const Identifier &p) const
02661 {
02662 if ( p == "goHistory" || part->url().protocol() != "http" || part->url().host() != "localhost" )
02663 return Undefined();
02664
02665 KParts::BrowserExtension *ext = part->browserExtension();
02666 if ( ext ) {
02667 KParts::BrowserInterface *iface = ext->browserInterface();
02668 if ( iface ) {
02669 QVariant prop = iface->property( p.qstring().latin1() );
02670
02671 if ( prop.isValid() ) {
02672 switch( prop.type() ) {
02673 case QVariant::Int:
02674 return Number( prop.toInt() );
02675 case QVariant::String:
02676 return String( prop.toString() );
02677 default:
02678 break;
02679 }
02680 }
02681 }
02682 }
02683
02684 return Value( new KonquerorFunc(exec, this, p.qstring().latin1() ) );
02685 }
02686
02687 Value KonquerorFunc::tryCall(ExecState *exec, Object &, const List &args)
02688 {
02689 KParts::BrowserExtension *ext = konqueror->part->browserExtension();
02690
02691 if (!ext)
02692 return Undefined();
02693
02694 KParts::BrowserInterface *iface = ext->browserInterface();
02695
02696 if ( !iface )
02697 return Undefined();
02698
02699 QCString n = m_name.data();
02700 n += "()";
02701 iface->callMethod( n.data(), QVariant() );
02702
02703 return Undefined();
02704 }
02705
02706 UString Konqueror::toString(ExecState *) const
02707 {
02708 return UString("[object Konqueror]");
02709 }
02710
02711 #endif
02712
02713
02714 #include "kjs_window.moc"