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