00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qstylesheet.h>
00022 #include <qtimer.h>
00023 #include <qpaintdevicemetrics.h>
00024 #include <qapplication.h>
00025 #include <kdebug.h>
00026 #include <kmessagebox.h>
00027 #include <klineeditdlg.h>
00028 #include <klocale.h>
00029 #include <kparts/browserinterface.h>
00030 #include <kwin.h>
00031 #include <kwinmodule.h>
00032 #include <kconfig.h>
00033 #include <assert.h>
00034 #include <qstyle.h>
00035 #include <qobjectlist.h>
00036
00037 #include "kjs_proxy.h"
00038 #include "kjs_window.h"
00039 #include "kjs_navigator.h"
00040 #include "kjs_html.h"
00041 #include "kjs_range.h"
00042 #include "kjs_traversal.h"
00043 #include "kjs_css.h"
00044 #include "kjs_events.h"
00045
00046 #include "khtmlview.h"
00047 #include "khtml_part.h"
00048 #include "khtml_settings.h"
00049 #include "xml/dom2_eventsimpl.h"
00050 #include "xml/dom_docimpl.h"
00051 #include "html/html_documentimpl.h"
00052
00053 using namespace KJS;
00054
00055 namespace KJS {
00056
00058
00059 class History : public ObjectImp {
00060 friend class HistoryFunc;
00061 public:
00062 History(ExecState *exec, KHTMLPart *p)
00063 : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
00064 virtual Value get(ExecState *exec, const UString &propertyName) const;
00065 Value getValueProperty(ExecState *exec, int token) const;
00066 virtual const ClassInfo* classInfo() const { return &info; }
00067 static const ClassInfo info;
00068 enum { Back, Forward, Go, Length };
00069 private:
00070 QGuardedPtr<KHTMLPart> part;
00071 };
00072
00073 class FrameArray : public ObjectImp {
00074 public:
00075 FrameArray(ExecState *exec, KHTMLPart *p)
00076 : ObjectImp(exec->interpreter()->builtinObjectPrototype()), part(p) { }
00077 virtual Value get(ExecState *exec, const UString &propertyName) const;
00078 private:
00079 QGuardedPtr<KHTMLPart> part;
00080 };
00081
00082 #ifdef Q_WS_QWS
00083 class KonquerorFunc : public DOMFunction {
00084 public:
00085 KonquerorFunc(const Konqueror* k, const char* name)
00086 : DOMFunction(), konqueror(k), m_name(name) { }
00087 virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args);
00088
00089 private:
00090 const Konqueror* konqueror;
00091 QCString m_name;
00092 };
00093 #endif
00094 };
00095
00096 #include "kjs_window.lut.h"
00097
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
00115
00116
00117 Screen::Screen(ExecState *exec)
00118 : ObjectImp(exec->interpreter()->builtinObjectPrototype()) {}
00119
00120 Value Screen::get(ExecState *exec, const UString &p) const
00121 {
00122 #ifdef KJS_VERBOSE
00123 kdDebug(6070) << "Screen::get " << p.qstring() << endl;
00124 #endif
00125 return lookupGetValue<Screen,ObjectImp>(exec,p,&ScreenTable,this);
00126 }
00127
00128 Value Screen::getValueProperty(ExecState *exec, int token) const
00129 {
00130 KWinModule info;
00131 QWidget *thisWidget = Window::retrieveActive(exec)->part()->view();
00132 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(thisWidget));
00133
00134 switch( token ) {
00135 case Height:
00136 return Number(sg.height());
00137 case Width:
00138 return Number(sg.width());
00139 case ColorDepth:
00140 case PixelDepth: {
00141 QPaintDeviceMetrics m(QApplication::desktop());
00142 return Number(m.depth());
00143 }
00144 case AvailLeft: {
00145 QRect clipped = info.workArea().intersect(sg);
00146 return Number(clipped.x()-sg.x());
00147 }
00148 case AvailTop: {
00149 QRect clipped = info.workArea().intersect(sg);
00150 return Number(clipped.y()-sg.y());
00151 }
00152 case AvailHeight: {
00153 QRect clipped = info.workArea().intersect(sg);
00154 return Number(clipped.height());
00155 }
00156 case AvailWidth: {
00157 QRect clipped = info.workArea().intersect(sg);
00158 return Number(clipped.width());
00159 }
00160 default:
00161 kdWarning(6070) << "Screen::getValueProperty unhandled token " << token << endl;
00162 return Undefined();
00163 }
00164 }
00165
00167
00168 const ClassInfo Window::info = { "Window", 0, &WindowTable, 0 };
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
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 IMPLEMENT_PROTOFUNC_DOM(WindowFunc)
00264
00265 Window::Window(KHTMLPart *p)
00266 : ObjectImp(), m_part(p), screen(0), history(0), m_frames(0), loc(0), m_evt(0)
00267 {
00268 winq = new WindowQObject(this);
00269
00270 }
00271
00272 Window::~Window()
00273 {
00274 kdDebug(6070) << "Window::~Window this=" << this << " part=" << m_part << endl;
00275 delete winq;
00276 }
00277
00278 Window *Window::retrieveWindow(KHTMLPart *p)
00279 {
00280 Object obj = Object::dynamicCast( retrieve( p ) );
00281 #ifndef NDEBUG
00282
00283 if ( p && p->jScriptEnabled() )
00284 {
00285 assert( !obj.isNull() );
00286 #ifndef QWS
00287 assert( dynamic_cast<KJS::Window*>(obj.imp()) );
00288 #endif
00289 }
00290 #endif
00291 if ( obj.isNull() )
00292 return 0;
00293 return static_cast<KJS::Window*>(obj.imp());
00294 }
00295
00296 Window *Window::retrieveActive(ExecState *exec)
00297 {
00298 ValueImp *imp = exec->interpreter()->globalObject().imp();
00299 assert( imp );
00300 #ifndef QWS
00301 assert( dynamic_cast<KJS::Window*>(imp) );
00302 #endif
00303 return static_cast<KJS::Window*>(imp);
00304 }
00305
00306 Value Window::retrieve(KHTMLPart *p)
00307 {
00308 assert(p);
00309 KJSProxy *proxy = KJSProxy::proxy( p );
00310 if (proxy) {
00311 #ifdef KJS_VERBOSE
00312 kdDebug(6070) << "Window::retrieve part=" << p << " '" << p->name() << "' interpreter=" << proxy->interpreter() << " window=" << proxy->interpreter()->globalObject().imp() << endl;
00313 #endif
00314 return proxy->interpreter()->globalObject();
00315 } else {
00316 #ifdef KJS_VERBOSE
00317 kdDebug(6070) << "Window::retrieve part=" << p << " '" << p->name() << "' no jsproxy." << endl;
00318 #endif
00319 return Undefined();
00320 }
00321 }
00322
00323 Location *Window::location() const
00324 {
00325 if (!loc)
00326 const_cast<Window*>(this)->loc = new Location(m_part);
00327 return loc;
00328 }
00329
00330 ObjectImp* Window::frames( ExecState* exec ) const
00331 {
00332 return m_frames ? m_frames :
00333 (const_cast<Window*>(this)->m_frames = new FrameArray(exec,m_part));
00334 }
00335
00336
00337 void Window::mark()
00338 {
00339 ObjectImp::mark();
00340 if (screen && !screen->marked())
00341 screen->mark();
00342 if (history && !history->marked())
00343 history->mark();
00344 if (m_frames && !m_frames->marked())
00345 m_frames->mark();
00346
00347 if (loc && !loc->marked())
00348 loc->mark();
00349 }
00350
00351 bool Window::hasProperty(ExecState *exec, const UString &p) const
00352 {
00353 if (p == "closed")
00354 return true;
00355
00356
00357 if (m_part.isNull())
00358 return false;
00359
00360 if (ObjectImp::hasProperty(exec, p))
00361 return true;
00362
00363 if (Lookup::findEntry(&WindowTable, p))
00364 return true;
00365
00366 QString q = p.qstring();
00367 if (m_part->findFrame(p.qstring()))
00368 return true;
00369
00370
00371 if (m_part->document().isHTMLDocument()) {
00372 DOM::HTMLCollection coll = m_part->htmlDocument().all();
00373 DOM::HTMLElement element = coll.namedItem(q);
00374 if (!element.isNull())
00375 return true;
00376 }
00377
00378 return false;
00379 }
00380
00381 UString Window::toString(ExecState *) const
00382 {
00383 return "[object Window]";
00384 }
00385
00386 Value Window::get(ExecState *exec, const UString &p) const
00387 {
00388 #ifdef KJS_VERBOSE
00389 kdDebug(6070) << "Window("<<this<<")::get " << p.qstring() << endl;
00390 #endif
00391 if ( p == "closed" )
00392 return Boolean(m_part.isNull());
00393
00394
00395 if (m_part.isNull())
00396 return Undefined();
00397
00398
00399 Value val = ObjectImp::get(exec, p);
00400 if (!val.isA(UndefinedType)) {
00401
00402 return isSafeScript(exec) ? val : Undefined();
00403 }
00404
00405 const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
00406
00407
00408 if (entry) {
00409 switch(entry->value) {
00410 case Closed:
00411 return Boolean( false );
00412 case _Location:
00413
00414 return Value(location());
00415 case Frames:
00416 return Value(frames(exec));
00417 case Opener:
00418 if (!m_part->opener())
00419 return Null();
00420 else
00421 return retrieve(m_part->opener());
00422 case Parent:
00423 return retrieve(m_part->parentPart() ? m_part->parentPart() : (KHTMLPart*)m_part);
00424 case _Window:
00425 case Self:
00426 return retrieve(m_part);
00427 case Top: {
00428 KHTMLPart *p = m_part;
00429 while (p->parentPart())
00430 p = p->parentPart();
00431 return retrieve(p);
00432 }
00433 case Alert:
00434 case Confirm:
00435 case Prompt:
00436 case Open:
00437 case Focus:
00438 case Blur:
00439 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
00440 default:
00441 break;
00442 }
00443 }
00444
00445
00446 if (isSafeScript(exec) && entry)
00447 {
00448
00449 switch( entry->value ) {
00450 case Crypto:
00451 return Undefined();
00452 case DefaultStatus:
00453 return String(UString(m_part->jsDefaultStatusBarText()));
00454 case Status:
00455 return String(UString(m_part->jsStatusBarText()));
00456 case Document:
00457 if (m_part->document().isNull()) {
00458 kdDebug(6070) << "Document.write: adding <HTML><BODY> to create document" << endl;
00459 m_part->begin();
00460 m_part->write("<HTML><BODY>");
00461 m_part->end();
00462 }
00463 return getDOMNode(exec,m_part->document());
00464 case Node:
00465 return getNodeConstructor(exec);
00466 case Range:
00467 return getRangeConstructor(exec);
00468 case NodeFilter:
00469 return getNodeFilterConstructor(exec);
00470 case DOMException:
00471 return getDOMExceptionConstructor(exec);
00472 case CSSRule:
00473 return getCSSRuleConstructor(exec);
00474 case EventCtor:
00475 return getEventConstructor(exec);
00476 case _History:
00477 return Value(history ? history :
00478 (const_cast<Window*>(this)->history = new History(exec,m_part)));
00479
00480 case Event:
00481 if (m_evt)
00482 return getDOMEvent(exec,*m_evt);
00483 else {
00484 #ifdef KJS_VERBOSE
00485 kdWarning(6070) << "window(" << this << "," << m_part->name() << ").event, no event!" << endl;
00486 #endif
00487 return Undefined();
00488 }
00489 case InnerHeight:
00490 if (!m_part->view())
00491 return Undefined();
00492 return Number(m_part->view()->visibleHeight());
00493 case InnerWidth:
00494 if (!m_part->view())
00495 return Undefined();
00496 return Number(m_part->view()->visibleWidth());
00497 case Length:
00498 return Number(m_part->frames().count());
00499 case Name:
00500 return String(m_part->name());
00501 case _Navigator:
00502 case ClientInformation: {
00503
00504 Value nav( new Navigator(exec, m_part) );
00505 const_cast<Window *>(this)->put(exec, "navigator", nav, DontDelete|ReadOnly|Internal);
00506 const_cast<Window *>(this)->put(exec, "clientInformation", nav, DontDelete|ReadOnly|Internal);
00507 return nav;
00508 }
00509 #ifdef Q_WS_QWS
00510 case _Konqueror: {
00511 Value k( new Konqueror(exec, m_part) );
00512 const_cast<Window *>(this)->put(exec, "konqueror", k, DontDelete|ReadOnly|Internal);
00513 return k;
00514 }
00515 #endif
00516 case OffscreenBuffering:
00517 return Boolean(true);
00518 case OuterHeight:
00519 case OuterWidth:
00520 {
00521 if (!m_part->widget())
00522 return Number(0);
00523 KWin::Info inf = KWin::info(m_part->widget()->topLevelWidget()->winId());
00524 return Number(entry->value == OuterHeight ?
00525 inf.geometry.height() : inf.geometry.width());
00526 }
00527 case PageXOffset:
00528 return Number(m_part->view()->contentsX());
00529 case PageYOffset:
00530 return Number(m_part->view()->contentsY());
00531 case Personalbar:
00532 return Undefined();
00533 case ScreenLeft:
00534 case ScreenX: {
00535 if (!m_part->view())
00536 return Undefined();
00537 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
00538 return Number(m_part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
00539 }
00540 case ScreenTop:
00541 case ScreenY: {
00542 if (!m_part->view())
00543 return Undefined();
00544 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
00545 return Number(m_part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
00546 }
00547 case ScrollX: {
00548 if (!m_part->view())
00549 return Undefined();
00550 return Number(m_part->view()->contentsX());
00551 }
00552 case ScrollY: {
00553 if (!m_part->view())
00554 return Undefined();
00555 return Number(m_part->view()->contentsY());
00556 }
00557 case Scrollbars:
00558 return Undefined();
00559 case _Screen:
00560 return Value(screen ? screen :
00561 (const_cast<Window*>(this)->screen = new Screen(exec)));
00562 case Image:
00563 return Value(new ImageConstructorImp(exec, m_part->document()));
00564 case Option:
00565 return Value(new OptionConstructorImp(exec, m_part->document()));
00566 case Close:
00567 case Scroll:
00568 case ScrollBy:
00569 case ScrollTo:
00570 case MoveBy:
00571 case MoveTo:
00572 case ResizeBy:
00573 case ResizeTo:
00574 case AddEventListener:
00575 case RemoveEventListener:
00576 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
00577 case SetTimeout:
00578 case ClearTimeout:
00579 case SetInterval:
00580 case ClearInterval:
00581 case Print:
00582 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
00583 case Onabort:
00584 return getListener(exec,DOM::EventImpl::ABORT_EVENT);
00585 case Onblur:
00586 return getListener(exec,DOM::EventImpl::BLUR_EVENT);
00587 case Onchange:
00588 return getListener(exec,DOM::EventImpl::CHANGE_EVENT);
00589 case Onclick:
00590 return getListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT);
00591 case Ondblclick:
00592 return getListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT);
00593 case Ondragdrop:
00594 return getListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT);
00595 case Onerror:
00596 return getListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT);
00597 case Onfocus:
00598 return getListener(exec,DOM::EventImpl::FOCUS_EVENT);
00599 case Onkeydown:
00600 return getListener(exec,DOM::EventImpl::KHTML_KEYDOWN_EVENT);
00601 case Onkeypress:
00602 return getListener(exec,DOM::EventImpl::KHTML_KEYPRESS_EVENT);
00603 case Onkeyup:
00604 return getListener(exec,DOM::EventImpl::KHTML_KEYUP_EVENT);
00605 case Onload:
00606 return getListener(exec,DOM::EventImpl::LOAD_EVENT);
00607 case Onmousedown:
00608 return getListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT);
00609 case Onmousemove:
00610 return getListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT);
00611 case Onmouseout:
00612 return getListener(exec,DOM::EventImpl::MOUSEOUT_EVENT);
00613 case Onmouseover:
00614 return getListener(exec,DOM::EventImpl::MOUSEOVER_EVENT);
00615 case Onmouseup:
00616 return getListener(exec,DOM::EventImpl::MOUSEUP_EVENT);
00617 case Onmove:
00618 return getListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT);
00619 case Onreset:
00620 return getListener(exec,DOM::EventImpl::RESET_EVENT);
00621 case Onresize:
00622 return getListener(exec,DOM::EventImpl::RESIZE_EVENT);
00623 case Onselect:
00624 return getListener(exec,DOM::EventImpl::SELECT_EVENT);
00625 case Onsubmit:
00626 return getListener(exec,DOM::EventImpl::SUBMIT_EVENT);
00627 case Onunload:
00628 return getListener(exec,DOM::EventImpl::UNLOAD_EVENT);
00629 }
00630 }
00631 KHTMLPart *kp = m_part->findFrame( p.qstring() );
00632 if (kp)
00633 return retrieve(kp);
00634
00635
00636 if (isSafeScript(exec) &&
00637 m_part->document().isHTMLDocument()) {
00638 DOM::HTMLCollection coll = m_part->htmlDocument().all();
00639 DOM::HTMLElement element = coll.namedItem(p.string());
00640 if (!element.isNull()) {
00641 return getDOMNode(exec,element);
00642 }
00643 }
00644
00645 #if 0
00646 // give access to functions (and variables ?) from parent frameset
00647 if (m_part->parentPart())
00648 {
00649 Object parentObject = Object::dynamicCast( retrieve(m_part->parentPart()) );
00650 if ( !parentObject.isNull() )
00651 {
00652 Value ret = parentObject.get(exec,p);
00653 if (ret.type() != UndefinedType ) {
00654 #ifdef KJS_VERBOSE
00655 kdDebug(6070) << "Window::get property " << p.qstring() << " found in parent part" << endl;
00656 #endif
00657 return ret;
00658 }
00659 }
00660 }
00661 #endif
00662
00663
00664
00665 #ifdef KJS_VERBOSE
00666 kdDebug(6070) << "WARNING: Window::get property not found: " << p.qstring() << endl;
00667 #endif
00668 return Undefined();
00669 }
00670
00671 void Window::put(ExecState* exec, const UString &propertyName, const Value &value, int attr)
00672 {
00673
00674
00675 if ( (attr != None && attr != DontDelete)
00676
00677 || ( ObjectImp::getDirect(propertyName) && isSafeScript(exec)) )
00678 {
00679 ObjectImp::put( exec, propertyName, value, attr );
00680 return;
00681 }
00682
00683 const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
00684 if (entry)
00685 {
00686 #ifdef KJS_VERBOSE
00687 kdDebug(6070) << "Window("<<this<<")::put " << propertyName.qstring() << endl;
00688 #endif
00689 switch( entry->value ) {
00690 case Status: {
00691 if ( isSafeScript(exec) ) {
00692 String s = value.toString(exec);
00693 m_part->setJSStatusBarText(s.value().qstring());
00694 }
00695 return;
00696 }
00697 case DefaultStatus: {
00698 if ( isSafeScript(exec) ) {
00699 String s = value.toString(exec);
00700 m_part->setJSDefaultStatusBarText(s.value().qstring());
00701 }
00702 return;
00703 }
00704 case _Location:
00705 goURL(exec, value.toString(exec).qstring());
00706 return;
00707 case Onabort:
00708 if (isSafeScript(exec))
00709 setListener(exec, DOM::EventImpl::ABORT_EVENT,value);
00710 return;
00711 case Onblur:
00712 if (isSafeScript(exec))
00713 setListener(exec, DOM::EventImpl::BLUR_EVENT,value);
00714 return;
00715 case Onchange:
00716 if (isSafeScript(exec))
00717 setListener(exec, DOM::EventImpl::CHANGE_EVENT,value);
00718 return;
00719 case Onclick:
00720 if (isSafeScript(exec))
00721 setListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT,value);
00722 return;
00723 case Ondblclick:
00724 if (isSafeScript(exec))
00725 setListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT,value);
00726 return;
00727 case Ondragdrop:
00728 if (isSafeScript(exec))
00729 setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
00730 return;
00731 case Onerror:
00732 if (isSafeScript(exec))
00733 setListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT,value);
00734 return;
00735 case Onfocus:
00736 if (isSafeScript(exec))
00737 setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
00738 return;
00739 case Onkeydown:
00740 if (isSafeScript(exec))
00741 setListener(exec,DOM::EventImpl::KHTML_KEYDOWN_EVENT,value);
00742 return;
00743 case Onkeypress:
00744 if (isSafeScript(exec))
00745 setListener(exec,DOM::EventImpl::KHTML_KEYPRESS_EVENT,value);
00746 return;
00747 case Onkeyup:
00748 if (isSafeScript(exec))
00749 setListener(exec,DOM::EventImpl::KHTML_KEYUP_EVENT,value);
00750 return;
00751 case Onload:
00752 if (isSafeScript(exec))
00753 setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
00754 return;
00755 case Onmousedown:
00756 if (isSafeScript(exec))
00757 setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
00758 return;
00759 case Onmousemove:
00760 if (isSafeScript(exec))
00761 setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
00762 return;
00763 case Onmouseout:
00764 if (isSafeScript(exec))
00765 setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
00766 return;
00767 case Onmouseover:
00768 if (isSafeScript(exec))
00769 setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
00770 return;
00771 case Onmouseup:
00772 if (isSafeScript(exec))
00773 setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
00774 return;
00775 case Onmove:
00776 if (isSafeScript(exec))
00777 setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
00778 return;
00779 case Onreset:
00780 if (isSafeScript(exec))
00781 setListener(exec,DOM::EventImpl::RESET_EVENT,value);
00782 return;
00783 case Onresize:
00784 if (isSafeScript(exec))
00785 setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
00786 return;
00787 case Onselect:
00788 if (isSafeScript(exec))
00789 setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
00790 return;
00791 case Onsubmit:
00792 if (isSafeScript(exec))
00793 setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
00794 return;
00795 case Onunload:
00796 if (isSafeScript(exec))
00797 setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
00798 return;
00799 case Name:
00800 if (isSafeScript(exec))
00801 m_part->setName( value.toString(exec).qstring().local8Bit().data() );
00802 return;
00803 default:
00804 break;
00805 }
00806 }
00807 if (isSafeScript(exec)) {
00808
00809 ObjectImp::put(exec, propertyName, value, attr);
00810 }
00811 }
00812
00813 bool Window::toBoolean(ExecState *) const
00814 {
00815 return !m_part.isNull();
00816 }
00817
00818 int Window::installTimeout(const UString &handler, int t, bool singleShot)
00819 {
00820 return winq->installTimeout(handler, t, singleShot);
00821 }
00822
00823 void Window::clearTimeout(int timerId)
00824 {
00825 winq->clearTimeout(timerId);
00826 }
00827
00828 void Window::scheduleClose()
00829 {
00830 kdDebug(6070) << "Window::scheduleClose window.close() " << m_part << endl;
00831 Q_ASSERT(winq);
00832 QTimer::singleShot( 0, winq, SLOT( timeoutClose() ) );
00833 }
00834
00835 void Window::closeNow()
00836 {
00837 if (!m_part.isNull())
00838 {
00839
00840
00841 m_part->setName( 0 );
00842 m_part->deleteLater();
00843 m_part = 0;
00844 } else
00845 kdDebug(6070) << k_funcinfo << "part is deleted already" << endl;
00846 }
00847
00848 void Window::afterScriptExecution()
00849 {
00850 DOM::DocumentImpl::updateDocumentsRendering();
00851 QValueList<DelayedAction> delayedActions = m_delayed;
00852 m_delayed.clear();
00853 QValueList<DelayedAction>::Iterator it = delayedActions.begin();
00854 for ( ; it != delayedActions.end() ; ++it )
00855 {
00856 switch ((*it).actionId) {
00857 case DelayedClose:
00858 scheduleClose();
00859 return;
00860 case DelayedGoHistory:
00861 goHistory( (*it).param.toInt() );
00862 break;
00863 };
00864 }
00865 }
00866
00867 bool Window::isSafeScript(ExecState *exec) const
00868 {
00869 if (m_part.isNull()) {
00870 kdDebug(6070) << "Window::isSafeScript: accessing deleted part !" << endl;
00871 return false;
00872 }
00873 KHTMLPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->interpreter() )->part();
00874 if (!activePart) {
00875 kdDebug(6070) << "Window::isSafeScript: current interpreter's part is 0L!" << endl;
00876 return false;
00877 }
00878 if ( activePart == m_part )
00879 return true;
00880
00881 if ( m_part->document().isNull() )
00882 return true;
00883
00884 DOM::HTMLDocument thisDocument = m_part->htmlDocument();
00885 if ( thisDocument.isNull() ) {
00886 kdDebug(6070) << "Window::isSafeScript: trying to access an XML document !?" << endl;
00887 return false;
00888 }
00889
00890 DOM::HTMLDocument actDocument = activePart->htmlDocument();
00891 if ( actDocument.isNull() ) {
00892 kdDebug(6070) << "Window::isSafeScript: active part has no document!" << endl;
00893 return false;
00894 }
00895 DOM::DOMString actDomain = actDocument.domain();
00896 DOM::DOMString thisDomain = thisDocument.domain();
00897
00898 if ( actDomain == thisDomain ) {
00899
00900 return true;
00901 }
00902
00903 kdWarning(6070) << "JavaScript: access denied for current frame '" << actDomain.string() << "' to frame '" << thisDomain.string() << "'" << endl;
00904
00905 return false;
00906 }
00907
00908 void Window::setListener(ExecState *exec, int eventId, Value func)
00909 {
00910 if (!isSafeScript(exec))
00911 return;
00912 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(m_part->htmlDocument().handle());
00913 if (!doc)
00914 return;
00915
00916 doc->setWindowEventListener(eventId,getJSEventListener(func,true));
00917 }
00918
00919 Value Window::getListener(ExecState *exec, int eventId) const
00920 {
00921 if (!isSafeScript(exec))
00922 return Undefined();
00923 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(m_part->htmlDocument().handle());
00924 if (!doc)
00925 return Undefined();
00926
00927 DOM::EventListener *listener = doc->getWindowEventListener(eventId);
00928 if (listener)
00929 return static_cast<JSEventListener*>(listener)->listenerObj();
00930 else
00931 return Null();
00932 }
00933
00934
00935 JSEventListener *Window::getJSEventListener(const Value& val, bool html)
00936 {
00937
00938 if (val.type() != ObjectType)
00939 return 0;
00940 ObjectImp *listenerObject = static_cast<ObjectImp *>(val.imp());
00941
00942 QPtrListIterator<JSEventListener> it(jsEventListeners);
00943 for (; it.current(); ++it)
00944 if (it.current()->listenerObjImp() == listenerObject)
00945 return it.current();
00946
00947
00948 return new JSEventListener(Object(listenerObject), Object(this), html);
00949 }
00950
00951 void Window::clear( ExecState *exec )
00952 {
00953 kdDebug(6070) << "Window::clear " << this << endl;
00954 delete winq;
00955 winq = 0L;
00956
00957 deleteAllProperties( exec );
00958
00959
00960 QPtrListIterator<JSEventListener> it(jsEventListeners);
00961 for (; it.current(); ++it)
00962 it.current()->clear();
00963
00964 jsEventListeners.clear();
00965
00966 if (!m_part.isNull()) {
00967 KJSProxy* proxy = KJSProxy::proxy( m_part );
00968 if (proxy)
00969 {
00970 winq = new WindowQObject(this);
00971
00972 KJS::Interpreter *interpreter = proxy->interpreter();
00973 interpreter->initGlobalObject();
00974 }
00975 }
00976 }
00977
00978 void Window::setCurrentEvent( DOM::Event *evt )
00979 {
00980 m_evt = evt;
00981
00982 }
00983
00984 void Window::goURL(ExecState* exec, const QString& url, bool lockHistory)
00985 {
00986 Window* active = Window::retrieveActive(exec);
00987
00988 if (active->part()) {
00989 QString dstUrl = active->part()->htmlDocument().completeURL(url).string();
00990 kdDebug() << "Window::goURL dstUrl=" << dstUrl << " m_part->url()=" << m_part->url().url() << endl;
00991
00992 if ( m_part->url().cmp( KURL(dstUrl), true ) )
00993 return;
00994
00995
00996
00997 if ( isSafeScript(exec) ||
00998 dstUrl.find(QString::fromLatin1("javascript:"), 0, false) != 0 )
00999 m_part->scheduleRedirection(-1,
01000 dstUrl,
01001 lockHistory);
01002 }
01003 }
01004
01005 void Window::delayedGoHistory( int steps )
01006 {
01007 m_delayed.append( DelayedAction( DelayedGoHistory, steps ) );
01008 }
01009
01010 void Window::goHistory( int steps )
01011 {
01012 KParts::BrowserExtension *ext = m_part->browserExtension();
01013 if(!ext)
01014 return;
01015 KParts::BrowserInterface *iface = ext->browserInterface();
01016
01017 if ( !iface )
01018 return;
01019
01020 iface->callMethod( "goHistory(int)", steps );
01021
01022 }
01023
01024 void KJS::Window::resizeTo(QWidget* tl, int width, int height)
01025 {
01026
01027 if ( width < 100 || height < 100 ) {
01028 kdDebug(6070) << "Window::resizeTo refused, window would be too small ("<<width<<","<<height<<")" << endl;
01029 return;
01030 }
01031 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
01032 if ( width > sg.width() || height > sg.height() ) {
01033 kdDebug(6070) << "Window::resizeTo refused, window would be too big ("<<width<<","<<height<<")" << endl;
01034 return;
01035 }
01036
01037
01038
01039 int deltaWidth = tl->frameGeometry().width() - tl->width();
01040 int deltaHeight = tl->frameGeometry().height() - tl->height();
01041
01042 kdDebug() << "resizing to " << width - deltaWidth << "x" << height - deltaHeight << endl;
01043
01044 tl->resize( width - deltaWidth, height - deltaHeight );
01045
01046
01047
01048 int right = tl->x() + tl->frameGeometry().width();
01049 int bottom = tl->y() + tl->frameGeometry().height();
01050 int moveByX = 0;
01051 int moveByY = 0;
01052 if ( right > sg.right() )
01053 moveByX = - right + sg.right();
01054 if ( bottom > sg.bottom() )
01055 moveByY = - bottom + sg.bottom();
01056 if ( moveByX || moveByY )
01057 tl->move( tl->x() + moveByX , tl->y() + moveByY );
01058 }
01059
01060 Value Window::openWindow(ExecState *exec, const List& args)
01061 {
01062 KHTMLView *widget = m_part->view();
01063 Value v = args[0];
01064 UString s = v.toString(exec);
01065 QString str = s.qstring();
01066
01067 KConfig *config = new KConfig( "konquerorrc" );
01068 config->setGroup( "Java/JavaScript Settings" );
01069 int policy = config->readUnsignedNumEntry( "WindowOpenPolicy", 0 );
01070 delete config;
01071 if ( policy == 1 ) {
01072 if ( KMessageBox::questionYesNo(widget,
01073 i18n( "This site is trying to open up a new browser "
01074 "window using JavaScript.\n"
01075 "Do you want to allow this?" ),
01076 i18n( "Confirmation: JavaScript Popup" ) ) == KMessageBox::Yes )
01077 policy = 0;
01078 } else if ( policy == 3 )
01079 {
01080
01081 if (static_cast<ScriptInterpreter *>(exec->interpreter())->isWindowOpenAllowed())
01082 policy = 0;
01083 }
01084 if ( policy != 0 ) {
01085 return Undefined();
01086 } else {
01087 KParts::WindowArgs winargs;
01088
01089
01090 QString features;
01091 if (args.size()>2) {
01092 features = args[2].toString(exec).qstring();
01093
01094 winargs.menuBarVisible = false;
01095 winargs.toolBarsVisible = false;
01096 winargs.statusBarVisible = false;
01097 QStringList flist = QStringList::split(',', features);
01098 QStringList::ConstIterator it = flist.begin();
01099 while (it != flist.end()) {
01100 QString s = *it++;
01101 QString key, val;
01102 int pos = s.find('=');
01103 if (pos >= 0) {
01104 key = s.left(pos).stripWhiteSpace().lower();
01105 val = s.mid(pos + 1).stripWhiteSpace().lower();
01106
01107 int scnum = QApplication::desktop()->screenNumber(widget->topLevelWidget());
01108
01109 QRect screen = QApplication::desktop()->screenGeometry(scnum);
01110 if (key == "left" || key == "screenx") {
01111 winargs.x = val.toInt() + screen.x();
01112 if (winargs.x < screen.x() || winargs.x > screen.right())
01113 winargs.x = screen.x();
01114 } else if (key == "top" || key == "screeny") {
01115 winargs.y = val.toInt() + screen.y();
01116 if (winargs.y < screen.y() || winargs.y > screen.bottom())
01117 winargs.y = screen.y();
01118 } else if (key == "height") {
01119 winargs.height = val.toInt() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
01120 if (winargs.height > screen.height())
01121 winargs.height = screen.height();
01122 if (winargs.height < 100)
01123 winargs.height = 100;
01124 } else if (key == "width") {
01125 winargs.width = val.toInt() + 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
01126 if (winargs.width > screen.width())
01127 winargs.width = screen.width();
01128 if (winargs.width < 100)
01129 winargs.width = 100;
01130 } else {
01131 goto boolargs;
01132 }
01133 continue;
01134 } else {
01135
01136 key = s.stripWhiteSpace().lower();
01137 val = "1";
01138 }
01139 boolargs:
01140 if (key == "menubar")
01141 winargs.menuBarVisible = (val == "1" || val == "yes");
01142 else if (key == "toolbar")
01143 winargs.toolBarsVisible = (val == "1" || val == "yes");
01144 else if (key == "location")
01145 winargs.toolBarsVisible = (val == "1" || val == "yes");
01146 else if (key == "status" || key == "statusbar")
01147 winargs.statusBarVisible = (val == "1" || val == "yes");
01148 else if (key == "resizable")
01149 winargs.resizable = (val == "1" || val == "yes");
01150 else if (key == "fullscreen")
01151 winargs.fullscreen = (val == "1" || val == "yes");
01152 }
01153 }
01154
01155
01156 KURL url;
01157 if (!str.isEmpty())
01158 {
01159 KHTMLPart* p = Window::retrieveActive(exec)->m_part;
01160 if ( p )
01161 url = p->htmlDocument().completeURL(str).string();
01162 if ( !p ||
01163 !static_cast<DOM::DocumentImpl*>(p->htmlDocument().handle())->isURLAllowed(url.url()) )
01164 return Undefined();
01165 }
01166
01167 KParts::URLArgs uargs;
01168 KHTMLPart *p = m_part;
01169 uargs.frameName = args.size() > 1 ?
01170 args[1].toString(exec).qstring()
01171 : QString("_blank");
01172 if ( uargs.frameName == "_top" )
01173 {
01174 while ( p->parentPart() )
01175 p = p->parentPart();
01176 Window::retrieveWindow(p)->goURL(exec, url.url(), false );
01177 return Window::retrieve(p);
01178 }
01179 if ( uargs.frameName == "_parent" )
01180 {
01181 if ( p->parentPart() )
01182 p = p->parentPart();
01183 Window::retrieveWindow(p)->goURL(exec, url.url(), false );
01184 return Window::retrieve(p);
01185 }
01186 uargs.serviceType = "text/html";
01187
01188
01189 KParts::ReadOnlyPart *newPart = 0L;
01190 emit p->browserExtension()->createNewWindow("", uargs,winargs,newPart);
01191 if (newPart && newPart->inherits("KHTMLPart")) {
01192 KHTMLPart *khtmlpart = static_cast<KHTMLPart*>(newPart);
01193
01194 khtmlpart->setOpener(p);
01195 khtmlpart->setOpenedByJS(true);
01196 if (khtmlpart->document().isNull()) {
01197 khtmlpart->begin();
01198 khtmlpart->write("<HTML><BODY>");
01199 khtmlpart->end();
01200 if ( p->docImpl() ) {
01201 kdDebug(6070) << "Setting domain to " << p->docImpl()->domain().string() << endl;
01202 khtmlpart->docImpl()->setDomain( p->docImpl()->domain());
01203 khtmlpart->docImpl()->setBaseURL( p->docImpl()->baseURL() );
01204 }
01205 }
01206 uargs.serviceType = QString::null;
01207 if (uargs.frameName == "_blank")
01208 uargs.frameName = QString::null;
01209 if (!url.isEmpty())
01210 emit khtmlpart->browserExtension()->openURLRequest(url,uargs);
01211 return Window::retrieve(khtmlpart);
01212 } else
01213 return Undefined();
01214 }
01215 }
01216
01217 Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01218 {
01219 KJS_CHECK_THIS( Window, thisObj );
01220 Window *window = static_cast<Window *>(thisObj.imp());
01221 QString str, str2;
01222
01223 KHTMLPart *part = window->m_part;
01224 if (!part)
01225 return Undefined();
01226
01227 KHTMLView *widget = part->view();
01228 Value v = args[0];
01229 UString s = v.toString(exec);
01230 str = s.qstring();
01231
01232
01233 switch(id) {
01234 case Window::Alert:
01235 if (!widget->dialogsAllowed())
01236 return Undefined();
01237 part->xmlDocImpl()->updateRendering();
01238 KMessageBox::error(widget, QStyleSheet::convertFromPlainText(str), "JavaScript");
01239 return Undefined();
01240 case Window::Confirm:
01241 if (!widget->dialogsAllowed())
01242 return Undefined();
01243 part->xmlDocImpl()->updateRendering();
01244 return Boolean((KMessageBox::warningYesNo(widget, QStyleSheet::convertFromPlainText(str), "JavaScript",
01245 i18n("OK"), i18n("Cancel")) == KMessageBox::Yes));
01246 case Window::Prompt:
01247 part->xmlDocImpl()->updateRendering();
01248 bool ok;
01249 if (args.size() >= 2)
01250 str2 = KLineEditDlg::getText(i18n("Konqueror: Prompt"),
01251 QStyleSheet::convertFromPlainText(str),
01252 args[1].toString(exec).qstring(), &ok);
01253 else
01254 str2 = KLineEditDlg::getText(i18n("Konqueror: Prompt"),
01255 QStyleSheet::convertFromPlainText(str),
01256 QString::null, &ok);
01257 if ( ok )
01258 return String(str2);
01259 else
01260 return Null();
01261 case Window::Open:
01262 return window->openWindow(exec, args);
01263 case Window::Focus: {
01264 if(widget)
01265 widget->setActiveWindow();
01266 return Undefined();
01267 }
01268 case Window::Blur:
01269
01270 return Undefined();
01271 };
01272
01273
01274
01275 if (!window->isSafeScript(exec))
01276 return Undefined();
01277
01278 switch (id) {
01279 case Window::Scroll:
01280 case Window::ScrollBy:
01281 if(args.size() == 2 && widget)
01282 widget->scrollBy(args[0].toInt32(exec), args[1].toInt32(exec));
01283 return Undefined();
01284 case Window::ScrollTo:
01285 if(args.size() == 2 && widget)
01286 widget->setContentsPos(args[0].toInt32(exec), args[1].toInt32(exec));
01287 return Undefined();
01288 case Window::MoveBy: {
01289 if(args.size() == 2 && widget)
01290 {
01291 QWidget * tl = widget->topLevelWidget();
01292 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
01293 QPoint dest = tl->pos() + QPoint( args[0].toInt32(exec), args[1].toInt32(exec) );
01294
01295 if ( dest.x() >= sg.x() && dest.y() >= sg.x() &&
01296 dest.x()+tl->width() <= sg.width()+sg.x() &&
01297 dest.y()+tl->height() <= sg.height()+sg.y() )
01298 tl->move( dest );
01299 }
01300 return Undefined();
01301 }
01302 case Window::MoveTo: {
01303 if(args.size() == 2 && widget)
01304 {
01305 QWidget * tl = widget->topLevelWidget();
01306 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
01307 QPoint dest( args[0].toInt32(exec)+sg.x(), args[1].toInt32(exec)+sg.y() );
01308
01309 if ( dest.x() >= sg.x() && dest.y() >= sg.y() &&
01310 dest.x()+tl->width() <= sg.width()+sg.x() &&
01311 dest.y()+tl->height() <= sg.height()+sg.y() )
01312 tl->move( dest );
01313 }
01314 return Undefined();
01315 }
01316 case Window::ResizeBy: {
01317 if(args.size() == 2 && widget)
01318 {
01319 QWidget * tl = widget->topLevelWidget();
01320 window->resizeTo( tl, tl->width() + args[0].toInt32(exec), tl->height() + args[1].toInt32(exec) );
01321 }
01322 return Undefined();
01323 }
01324 case Window::ResizeTo: {
01325 if(args.size() == 2 && widget)
01326 {
01327 QWidget * tl = widget->topLevelWidget();
01328 window->resizeTo( tl, args[0].toInt32(exec), args[1].toInt32(exec) );
01329 }
01330 return Undefined();
01331 }
01332 case Window::SetTimeout:
01333 if (args.size() == 2 && v.isA(StringType)) {
01334 int i = args[1].toInt32(exec);
01335 int r = (const_cast<Window*>(window))->installTimeout(s, i, true );
01336 return Number(r);
01337 }
01338 else if (args.size() >= 2 && v.isA(ObjectType) && Object::dynamicCast(v).implementsCall()) {
01339 Value func = args[0];
01340 int i = args[1].toInt32(exec);
01341 #if 0
01342
01343 List *funcArgs = args.copy();
01344 funcArgs->removeFirst();
01345 funcArgs->removeFirst();
01346 #endif
01347 if ( args.size() > 2 )
01348 kdWarning(6070) << "setTimeout(more than 2 args) is not fully implemented!" << endl;
01349 int r = (const_cast<Window*>(window))->installTimeout(s, i, true );
01350 return Number(r);
01351 }
01352 else
01353 return Undefined();
01354 case Window::SetInterval:
01355 if (args.size() >= 2 && v.isA(StringType)) {
01356 int i = args[1].toInt32(exec);
01357 int r = (const_cast<Window*>(window))->installTimeout(s, i, false);
01358 return Number(r);
01359 }
01360 else if (args.size() >= 2 && !Object::dynamicCast(v).isNull() &&
01361 Object::dynamicCast(v).implementsCall()) {
01362 Value func = args[0];
01363 int i = args[1].toInt32(exec);
01364 #if 0
01365
01366 List *funcArgs = args.copy();
01367 funcArgs->removeFirst();
01368 funcArgs->removeFirst();
01369 #endif
01370 int r = (const_cast<Window*>(window))->installTimeout(s, i, false);
01371 return Number(r);
01372 }
01373 else
01374 return Undefined();
01375 case Window::ClearTimeout:
01376 case Window::ClearInterval:
01377 (const_cast<Window*>(window))->clearTimeout(v.toInt32(exec));
01378 return Undefined();
01379 case Window::Blur:
01380
01381 return Undefined();
01382 case Window::Close: {
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393 bool doClose = false;
01394 if (!part->openedByJS())
01395 {
01396
01397
01398 History history(exec,part);
01399 if ( history.get( exec, "length" ).toInt32(exec) <= 1 ||
01400 KMessageBox::questionYesNo( window->part()->widget(), i18n("Close window?"), i18n("Confirmation Required") ) == KMessageBox::Yes )
01401 doClose = true;
01402 }
01403 else
01404 doClose = true;
01405
01406 if (doClose)
01407 {
01408
01409
01410
01411 if ( Window::retrieveActive(exec) == window ) {
01412 if (widget) {
01413
01414
01415 widget->closeChildDialogs();
01416 }
01417
01418
01419 Window* w = const_cast<Window*>(window);
01420 w->m_delayed.append( Window::DelayedAction( Window::DelayedClose ) );
01421 } else {
01422
01423 (const_cast<Window*>(window))->closeNow();
01424 }
01425 }
01426 return Undefined();
01427 }
01428 case Window::Print:
01429 if ( widget ) {
01430
01431 widget->print();
01432
01433 }
01434 case Window::AddEventListener: {
01435 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
01436 DOM::Document doc = part->document();
01437 if (doc.isHTMLDocument()) {
01438 DOM::HTMLDocument htmlDoc = doc;
01439 htmlDoc.body().addEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
01440 }
01441 else
01442 doc.addEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
01443 return Undefined();
01444 }
01445 case Window::RemoveEventListener: {
01446 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
01447 DOM::Document doc = part->document();
01448 if (doc.isHTMLDocument()) {
01449 DOM::HTMLDocument htmlDoc = doc;
01450 htmlDoc.body().removeEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
01451 }
01452 else
01453 doc.removeEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
01454 return Undefined();
01455 }
01456 break;
01457 }
01458 return Undefined();
01459 }
01460
01462
01463 ScheduledAction::ScheduledAction(Object _func, List _args, bool _singleShot)
01464 {
01465
01466 func = _func;
01467 args = _args;
01468 isFunction = true;
01469 singleShot = _singleShot;
01470 }
01471
01472 ScheduledAction::ScheduledAction(QString _code, bool _singleShot)
01473 {
01474
01475
01476
01477 code = _code;
01478 isFunction = false;
01479 singleShot = _singleShot;
01480 }
01481
01482 void ScheduledAction::execute(Window *window)
01483 {
01484 ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(KJSProxy::proxy(window->m_part)->interpreter());
01485
01486 interpreter->setProcessingTimerCallback(true);
01487
01488
01489 if (isFunction) {
01490 if (func.implementsCall()) {
01491
01492 Q_ASSERT( window->m_part );
01493 if ( window->m_part )
01494 {
01495 KJS::Interpreter *interpreter = KJSProxy::proxy( window->m_part )->interpreter();
01496 ExecState *exec = interpreter->globalExec();
01497 Q_ASSERT( window == interpreter->globalObject().imp() );
01498 Object obj( window );
01499 func.call(exec,obj,args);
01500 }
01501 }
01502 }
01503 else {
01504 window->m_part->executeScript(code);
01505 }
01506
01507 interpreter->setProcessingTimerCallback(false);
01508 }
01509
01510 ScheduledAction::~ScheduledAction()
01511 {
01512
01513 }
01514
01516
01517 WindowQObject::WindowQObject(Window *w)
01518 : parent(w)
01519 {
01520
01521 part = parent->m_part;
01522 if ( !part )
01523 kdWarning(6070) << "null part in " << k_funcinfo << endl;
01524 else
01525 connect( part, SIGNAL( destroyed() ),
01526 this, SLOT( parentDestroyed() ) );
01527 }
01528
01529 WindowQObject::~WindowQObject()
01530 {
01531
01532 parentDestroyed();
01533 }
01534
01535 void WindowQObject::parentDestroyed()
01536 {
01537
01538 killTimers();
01539 QMapIterator<int,ScheduledAction*> it;
01540 for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
01541 ScheduledAction *action = *it;
01542
01543 delete action;
01544 }
01545 scheduledActions.clear();
01546 }
01547
01548 int WindowQObject::installTimeout(const UString &handler, int t, bool singleShot)
01549 {
01550
01551 if (t < 10) t = 10;
01552 int id = startTimer(t);
01553 ScheduledAction *action = new ScheduledAction(handler.qstring(),singleShot);
01554 scheduledActions.insert(id, action);
01555
01556 return id;
01557 }
01558
01559 int WindowQObject::installTimeout(const Value &func, List args, int t, bool singleShot)
01560 {
01561 Object objFunc = Object::dynamicCast( func );
01562 if (t < 10) t = 10;
01563 int id = startTimer(t);
01564 scheduledActions.insert(id, new ScheduledAction(objFunc,args,singleShot));
01565 return id;
01566 }
01567
01568 void WindowQObject::clearTimeout(int timerId, bool delAction)
01569 {
01570
01571 killTimer(timerId);
01572 if (delAction) {
01573 QMapIterator<int,ScheduledAction*> it = scheduledActions.find(timerId);
01574 if (it != scheduledActions.end()) {
01575 ScheduledAction *action = *it;
01576 scheduledActions.remove(it);
01577 delete action;
01578 }
01579 }
01580 }
01581
01582 void WindowQObject::timerEvent(QTimerEvent *e)
01583 {
01584 QMapIterator<int,ScheduledAction*> it = scheduledActions.find(e->timerId());
01585 if (it != scheduledActions.end()) {
01586 ScheduledAction *action = *it;
01587 bool singleShot = action->singleShot;
01588
01589
01590
01591 if (singleShot)
01592 {
01593 clearTimeout(e->timerId(),false);
01594 scheduledActions.remove(it);
01595 }
01596 if (!parent->part().isNull())
01597 action->execute(parent);
01598
01599
01600
01601
01602 if (singleShot)
01603 delete action;
01604 } else
01605 kdWarning(6070) << "WindowQObject::timerEvent this=" << this << " timer " << e->timerId()
01606 << " not found (" << scheduledActions.count() << " actions in map)" << endl;
01607 }
01608
01609 void WindowQObject::timeoutClose()
01610 {
01611 parent->closeNow();
01612 }
01613
01614 Value FrameArray::get(ExecState *exec, const UString &p) const
01615 {
01616 #ifdef KJS_VERBOSE
01617 kdDebug(6070) << "FrameArray::get " << p.qstring() << " part=" << (void*)part << endl;
01618 #endif
01619 if (part.isNull())
01620 return Undefined();
01621
01622 QPtrList<KParts::ReadOnlyPart> frames = part->frames();
01623 int len = frames.count();
01624 if (p == "length")
01625 return Number(len);
01626 else if (p== "location")
01627 {
01628 Object obj = Object::dynamicCast( Window::retrieve( part ) );
01629 if ( !obj.isNull() )
01630 return obj.get( exec, "location" );
01631 return Undefined();
01632 }
01633
01634
01635 KParts::ReadOnlyPart *frame = part->findFrame(p.qstring());
01636 if (!frame) {
01637 int i = (int)p.toDouble();
01638 if (i >= 0 && i < len)
01639 frame = frames.at(i);
01640 }
01641
01642
01643
01644
01645 if (frame && frame->inherits("KHTMLPart")) {
01646 KHTMLPart *khtml = static_cast<KHTMLPart*>(frame);
01647 return Window::retrieve(khtml);
01648 }
01649
01650 return ObjectImp::get(exec, p);
01651 }
01652
01654
01655 const ClassInfo Location::info = { "Location", 0, &LocationTable, 0 };
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673 IMPLEMENT_PROTOFUNC_DOM(LocationFunc)
01674 Location::Location(KHTMLPart *p) : m_part(p)
01675 {
01676
01677 }
01678
01679 Location::~Location()
01680 {
01681
01682 }
01683
01684 Value Location::get(ExecState *exec, const UString &p) const
01685 {
01686 #ifdef KJS_VERBOSE
01687 kdDebug(6070) << "Location::get " << p.qstring() << " m_part=" << (void*)m_part << endl;
01688 #endif
01689
01690 if (m_part.isNull())
01691 return Undefined();
01692
01693 const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
01694
01695
01696 if ( entry && entry->value == Replace )
01697 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
01698
01699
01700 const Window* window = Window::retrieveWindow( m_part );
01701 if ( !window || !window->isSafeScript(exec) )
01702 return Undefined();
01703
01704 KURL url = m_part->url();
01705 if (entry)
01706 switch (entry->value) {
01707 case Hash:
01708 return String( url.ref().isNull() ? QString("") : "#" + url.ref() );
01709 case Host: {
01710 UString str = url.host();
01711 if (url.port())
01712 str += ":" + QString::number((int)url.port());
01713 return String(str);
01714
01715
01716
01717 }
01718 case Hostname:
01719 return String( url.host() );
01720 case Href:
01721 if (!url.hasPath())
01722 return String( url.prettyURL()+"/" );
01723 else
01724 return String( url.prettyURL() );
01725 case Pathname:
01726 return String( url.path().isEmpty() ? QString("/") : url.path() );
01727 case Port:
01728 return String( url.port() ? QString::number((int)url.port()) : QString::fromLatin1("") );
01729 case Protocol:
01730 return String( url.protocol()+":" );
01731 case Search:
01732 return String( url.query() );
01733 case EqualEqual:
01734 return String(toString(exec));
01735 case ToString:
01736 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
01737 }
01738
01739 ValueImp * val = ObjectImp::getDirect(p);
01740 if (val)
01741 return Value(val);
01742 if (entry && (entry->attr & Function))
01743 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
01744
01745 return Undefined();
01746 }
01747
01748 void Location::put(ExecState *exec, const UString &p, const Value &v, int attr)
01749 {
01750 #ifdef KJS_VERBOSE
01751 kdDebug(6070) << "Location::put " << p.qstring() << " m_part=" << (void*)m_part << endl;
01752 #endif
01753 if (m_part.isNull())
01754 return;
01755
01756
01757 const Window* window = Window::retrieveWindow( m_part );
01758 if ( !window || !window->isSafeScript(exec) )
01759 return;
01760
01761 QString str = v.toString(exec).qstring();
01762 KURL url = m_part->url();
01763 const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
01764 if (entry)
01765 switch (entry->value) {
01766 case Href: {
01767 KHTMLPart* p = Window::retrieveActive(exec)->part();
01768 if ( p )
01769 url = p->htmlDocument().completeURL( str ).string();
01770 else
01771 url = str;
01772 break;
01773 }
01774 case Hash:
01775
01776 if (str == url.ref()) return;
01777 url.setRef(str);
01778 break;
01779 case Host: {
01780 QString host = str.left(str.find(":"));
01781 QString port = str.mid(str.find(":")+1);
01782 url.setHost(host);
01783 url.setPort(port.toUInt());
01784 break;
01785 }
01786 case Hostname:
01787 url.setHost(str);
01788 break;
01789 case Pathname:
01790 url.setPath(str);
01791 break;
01792 case Port:
01793 url.setPort(str.toUInt());
01794 break;
01795 case Protocol:
01796 url.setProtocol(str);
01797 break;
01798 case Search:
01799 url.setQuery(str);
01800 break;
01801 }
01802 else {
01803 ObjectImp::put(exec, p, v, attr);
01804 return;
01805 }
01806
01807 Window::retrieveWindow(m_part)->goURL(exec, url.url(), false );
01808 }
01809
01810 Value Location::toPrimitive(ExecState *exec, Type) const
01811 {
01812 Window* window = Window::retrieveWindow( m_part );
01813 if ( window && window->isSafeScript(exec) )
01814 return String(toString(exec));
01815 return Undefined();
01816 }
01817
01818 UString Location::toString(ExecState *exec) const
01819 {
01820 Window* window = Window::retrieveWindow( m_part );
01821 if ( window && window->isSafeScript(exec) )
01822 {
01823 if (!m_part->url().hasPath())
01824 return m_part->url().prettyURL()+"/";
01825 else
01826 return m_part->url().prettyURL();
01827 }
01828 return "";
01829 }
01830
01831 Value LocationFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01832 {
01833 KJS_CHECK_THIS( Location, thisObj );
01834 Location *location = static_cast<Location *>(thisObj.imp());
01835 KHTMLPart *part = location->part();
01836
01837 if (!part) return Undefined();
01838
01839 Window* window = Window::retrieveWindow(part);
01840
01841 if ( !window->isSafeScript(exec) && id != Location::Replace)
01842 return Undefined();
01843
01844 switch (id) {
01845 case Location::Assign:
01846 case Location::Replace:
01847 Window::retrieveWindow(part)->goURL(exec, args[0].toString(exec).qstring(),
01848 id == Location::Replace);
01849 break;
01850 case Location::Reload:
01851 part->scheduleRedirection(-1, part->url().url(), true);
01852 break;
01853 case Location::ToString:
01854 return String(location->toString(exec));
01855 }
01856 return Undefined();
01857 }
01858
01860
01861 const ClassInfo History::info = { "History", 0, 0, 0 };
01862
01863
01864
01865
01866
01867
01868
01869
01870 IMPLEMENT_PROTOFUNC_DOM(HistoryFunc)
01871
01872 Value History::get(ExecState *exec, const UString &p) const
01873 {
01874 return lookupGet<HistoryFunc,History,ObjectImp>(exec,p,&HistoryTable,this);
01875 }
01876
01877 Value History::getValueProperty(ExecState *, int token) const
01878 {
01879 switch (token) {
01880 case Length:
01881 {
01882 KParts::BrowserExtension *ext = part->browserExtension();
01883 if ( !ext )
01884 return Number( 0 );
01885
01886 KParts::BrowserInterface *iface = ext->browserInterface();
01887 if ( !iface )
01888 return Number( 0 );
01889
01890 QVariant length = iface->property( "historyLength" );
01891
01892 if ( length.type() != QVariant::UInt )
01893 return Number( 0 );
01894
01895 return Number( length.toUInt() );
01896 }
01897 default:
01898 kdWarning(6070) << "Unhandled token in History::getValueProperty : " << token << endl;
01899 return Undefined();
01900 }
01901 }
01902
01903 Value HistoryFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
01904 {
01905 KJS_CHECK_THIS( History, thisObj );
01906 History *history = static_cast<History *>(thisObj.imp());
01907
01908 Value v = args[0];
01909 Number n;
01910 if(!v.isNull())
01911 n = v.toInteger(exec);
01912
01913 int steps;
01914 switch (id) {
01915 case History::Back:
01916 steps = -1;
01917 break;
01918 case History::Forward:
01919 steps = 1;
01920 break;
01921 case History::Go:
01922 steps = n.intValue();
01923 break;
01924 default:
01925 return Undefined();
01926 }
01927
01928
01929
01930
01931
01932 if (!steps)
01933 {
01934 history->part->openURL( history->part->url() );
01935 } else
01936 {
01937
01938
01939 Window* window = Window::retrieveWindow( history->part );
01940 window->delayedGoHistory( steps );
01941 }
01942 return Undefined();
01943 }
01944
01946
01947 #ifdef Q_WS_QWS
01948
01949 const ClassInfo Konqueror::info = { "Konqueror", 0, 0, 0 };
01950
01951 bool Konqueror::hasProperty(ExecState *exec, const UString &p) const
01952 {
01953 if ( p.qstring().startsWith( "goHistory" ) ) return false;
01954
01955 return true;
01956 }
01957
01958 Value Konqueror::get(ExecState *exec, const UString &p) const
01959 {
01960 if ( p == "goHistory" || part->url().protocol() != "http" || part->url().host() != "localhost" )
01961 return Undefined();
01962
01963 KParts::BrowserExtension *ext = part->browserExtension();
01964 if ( ext ) {
01965 KParts::BrowserInterface *iface = ext->browserInterface();
01966 if ( iface ) {
01967 QVariant prop = iface->property( p.qstring().latin1() );
01968
01969 if ( prop.isValid() ) {
01970 switch( prop.type() ) {
01971 case QVariant::Int:
01972 return Number( prop.toInt() );
01973 case QVariant::String:
01974 return String( prop.toString() );
01975 default:
01976 break;
01977 }
01978 }
01979 }
01980 }
01981
01982 return ( new KonquerorFunc(this, p.qstring().latin1() ) );
01983 }
01984
01985 Value KonquerorFunc::tryCall(ExecState *exec, Object &, const List &args)
01986 {
01987 KParts::BrowserExtension *ext = konqueror->part->browserExtension();
01988
01989 if(!ext)
01990 return Undefined();
01991
01992 KParts::BrowserInterface *iface = ext->browserInterface();
01993
01994 if ( !iface )
01995 return Undefined();
01996
01997 QCString n = m_name.data();
01998 n += "()";
01999 iface->callMethod( n.data(), QVariant() );
02000
02001 return Undefined();
02002 }
02003
02004 UString Konqueror::toString(ExecState *) const
02005 {
02006 return UString("[object Konqueror]");
02007 }
02008
02009 #endif
02010
02011
02012 #include "kjs_window.moc"