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