1 // -*- c-basic-offset: 2 -*-
3 * This file is part of the KDE libraries
4 * Copyright (C) 2000 Harri Porten (porten@kde.org)
5 * Copyright (C) 2003 Apple Computer, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <qstylesheet.h>
24 #include <qinputdialog.h>
25 #include <qpaintdevicemetrics.h>
26 #include <qapplication.h>
28 #include <kmessagebox.h>
30 #include <kparts/browserinterface.h>
32 #include <kwinmodule.h>
36 #include "rendering/render_canvas.h"
39 #include "KWQLogging.h"
40 #include "KWQKConfigBase.h"
42 #include <kjs/collector.h>
43 #include "kjs_proxy.h"
44 #include "kjs_window.h"
45 #include "kjs_navigator.h"
47 #include "kjs_range.h"
48 #include "kjs_traversal.h"
50 #include "kjs_events.h"
51 #include "xmlhttprequest.h"
52 #include "xmlserializer.h"
54 #include "khtmlview.h"
55 #include "khtml_part.h"
56 #include "dom/dom_string.h"
57 #include "dom/dom_node.h"
58 #include "editing/htmlediting.h"
59 #include "editing/selection.h"
60 #include "xml/dom2_eventsimpl.h"
61 #include "xml/dom_docimpl.h"
62 #include "xml/dom_elementimpl.h"
63 #include "xml/dom_position.h"
64 #include "html/html_documentimpl.h"
66 #include "misc/htmltags.h"
68 using DOM::DocumentImpl;
70 using DOM::ElementImpl;
73 using khtml::TypingCommand;
79 ////////////////////// History Object ////////////////////////
81 class History : public ObjectImp {
82 friend class HistoryFunc;
84 History(ExecState *exec, KHTMLPart *p)
85 : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
86 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
87 Value getValueProperty(ExecState *exec, int token) const;
88 virtual const ClassInfo* classInfo() const { return &info; }
89 static const ClassInfo info;
90 enum { Back, Forward, Go, Length };
91 virtual UString toString(ExecState *exec) const;
93 QGuardedPtr<KHTMLPart> part;
96 class FrameArray : public ObjectImp {
98 FrameArray(ExecState *exec, KHTMLPart *p)
99 : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
100 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
101 virtual UString toString(ExecState *exec) const;
103 QGuardedPtr<KHTMLPart> part;
107 class KonquerorFunc : public DOMFunction {
109 KonquerorFunc(const Konqueror* k, const char* name)
110 : DOMFunction(), konqueror(k), m_name(name) { }
111 virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args);
114 const Konqueror* konqueror;
120 #include "kjs_window.lut.h"
122 ////////////////////// Screen Object ////////////////////////
124 // table for screen object
127 height Screen::Height DontEnum|ReadOnly
128 width Screen::Width DontEnum|ReadOnly
129 colorDepth Screen::ColorDepth DontEnum|ReadOnly
130 pixelDepth Screen::PixelDepth DontEnum|ReadOnly
131 availLeft Screen::AvailLeft DontEnum|ReadOnly
132 availTop Screen::AvailTop DontEnum|ReadOnly
133 availHeight Screen::AvailHeight DontEnum|ReadOnly
134 availWidth Screen::AvailWidth DontEnum|ReadOnly
138 const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
140 // We set the object prototype so that toString is implemented
141 Screen::Screen(ExecState *exec)
142 : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()) {}
144 Value Screen::get(ExecState *exec, const Identifier &p) const
147 kdDebug(6070) << "Screen::get " << p.qstring() << endl;
149 return lookupGetValue<Screen,ObjectImp>(exec,p,&ScreenTable,this);
152 Value Screen::getValueProperty(ExecState *exec, int token) const
155 QWidget *thisWidget = Window::retrieveActive(exec)->part()->view();
156 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(thisWidget));
160 return Number(sg.height());
162 return Number(sg.width());
165 QPaintDeviceMetrics m(QApplication::desktop());
166 return Number(m.depth());
169 QRect clipped = info.workArea().intersect(sg);
170 return Number(clipped.x()-sg.x());
173 QRect clipped = info.workArea().intersect(sg);
174 return Number(clipped.y()-sg.y());
177 QRect clipped = info.workArea().intersect(sg);
178 return Number(clipped.height());
181 QRect clipped = info.workArea().intersect(sg);
182 return Number(clipped.width());
185 kdWarning() << "Screen::getValueProperty unhandled token " << token << endl;
190 ////////////////////// Window Object ////////////////////////
192 const ClassInfo Window::info = { "Window", 0, &WindowTable, 0 };
195 @begin WindowTable 91
196 closed Window::Closed DontDelete|ReadOnly
197 crypto Window::Crypto DontDelete|ReadOnly
198 defaultStatus Window::DefaultStatus DontDelete
199 defaultstatus Window::DefaultStatus DontDelete
200 status Window::Status DontDelete
201 document Window::Document DontDelete|ReadOnly
202 Node Window::Node DontDelete
203 Event Window::EventCtor DontDelete
204 Range Window::Range DontDelete
205 NodeFilter Window::NodeFilter DontDelete
206 DOMException Window::DOMException DontDelete
207 CSSRule Window::CSSRule DontDelete
208 frames Window::Frames DontDelete|ReadOnly
209 history Window::_History DontDelete|ReadOnly
210 event Window::Event DontDelete
211 innerHeight Window::InnerHeight DontDelete|ReadOnly
212 innerWidth Window::InnerWidth DontDelete|ReadOnly
213 length Window::Length DontDelete|ReadOnly
214 location Window::_Location DontDelete
215 locationbar Window::Locationbar DontDelete
216 name Window::Name DontDelete
217 navigator Window::_Navigator DontDelete|ReadOnly
218 clientInformation Window::ClientInformation DontDelete|ReadOnly
219 konqueror Window::_Konqueror DontDelete|ReadOnly
220 menubar Window::Menubar DontDelete|ReadOnly
221 offscreenBuffering Window::OffscreenBuffering DontDelete|ReadOnly
222 opener Window::Opener DontDelete|ReadOnly
223 outerHeight Window::OuterHeight DontDelete|ReadOnly
224 outerWidth Window::OuterWidth DontDelete|ReadOnly
225 pageXOffset Window::PageXOffset DontDelete|ReadOnly
226 pageYOffset Window::PageYOffset DontDelete|ReadOnly
227 parent Window::Parent DontDelete|ReadOnly
228 personalbar Window::Personalbar DontDelete|ReadOnly
229 screenX Window::ScreenX DontDelete|ReadOnly
230 screenY Window::ScreenY DontDelete|ReadOnly
231 screenLeft Window::ScreenLeft DontDelete|ReadOnly
232 screenTop Window::ScreenTop DontDelete|ReadOnly
233 scrollbars Window::Scrollbars DontDelete|ReadOnly
234 statusbar Window::Statusbar DontDelete|ReadOnly
235 toolbar Window::Toolbar DontDelete|ReadOnly
236 scroll Window::Scroll DontDelete|Function 2
237 scrollBy Window::ScrollBy DontDelete|Function 2
238 scrollTo Window::ScrollTo DontDelete|Function 2
239 scrollX Window::ScrollX DontDelete|ReadOnly
240 scrollY Window::ScrollY DontDelete|ReadOnly
241 moveBy Window::MoveBy DontDelete|Function 2
242 moveTo Window::MoveTo DontDelete|Function 2
243 resizeBy Window::ResizeBy DontDelete|Function 2
244 resizeTo Window::ResizeTo DontDelete|Function 2
245 self Window::Self DontDelete|ReadOnly
246 window Window::_Window DontDelete|ReadOnly
247 top Window::Top DontDelete|ReadOnly
248 screen Window::_Screen DontDelete|ReadOnly
249 Image Window::Image DontDelete|ReadOnly
250 Option Window::Option DontDelete|ReadOnly
251 XMLHttpRequest Window::XMLHttpRequest DontDelete|ReadOnly
252 XMLSerializer Window::XMLSerializer DontDelete|ReadOnly
253 alert Window::Alert DontDelete|Function 1
254 confirm Window::Confirm DontDelete|Function 1
255 prompt Window::Prompt DontDelete|Function 2
256 open Window::Open DontDelete|Function 3
257 print Window::Print DontDelete|Function 2
258 setTimeout Window::SetTimeout DontDelete|Function 2
259 clearTimeout Window::ClearTimeout DontDelete|Function 1
260 focus Window::Focus DontDelete|Function 0
261 getSelection Window::GetSelection DontDelete|Function 0
262 blur Window::Blur DontDelete|Function 0
263 close Window::Close DontDelete|Function 0
264 setInterval Window::SetInterval DontDelete|Function 2
265 clearInterval Window::ClearInterval DontDelete|Function 1
266 captureEvents Window::CaptureEvents DontDelete|Function 0
267 releaseEvents Window::ReleaseEvents DontDelete|Function 0
268 # Warning, when adding a function to this object you need to add a case in Window::get
269 addEventListener Window::AddEventListener DontDelete|Function 3
270 removeEventListener Window::RemoveEventListener DontDelete|Function 3
271 onabort Window::Onabort DontDelete
272 onblur Window::Onblur DontDelete
273 onchange Window::Onchange DontDelete
274 onclick Window::Onclick DontDelete
275 ondblclick Window::Ondblclick DontDelete
276 ondragdrop Window::Ondragdrop DontDelete
277 onerror Window::Onerror DontDelete
278 onfocus Window::Onfocus DontDelete
279 onkeydown Window::Onkeydown DontDelete
280 onkeypress Window::Onkeypress DontDelete
281 onkeyup Window::Onkeyup DontDelete
282 onload Window::Onload DontDelete
283 onmousedown Window::Onmousedown DontDelete
284 onmousemove Window::Onmousemove DontDelete
285 onmouseout Window::Onmouseout DontDelete
286 onmouseover Window::Onmouseover DontDelete
287 onmouseup Window::Onmouseup DontDelete
288 onmousewheel Window::OnWindowMouseWheel DontDelete
289 onmove Window::Onmove DontDelete
290 onreset Window::Onreset DontDelete
291 onresize Window::Onresize DontDelete
292 onscroll Window::Onscroll DontDelete
293 onsearch Window::Onsearch DontDelete
294 onselect Window::Onselect DontDelete
295 onsubmit Window::Onsubmit DontDelete
296 onunload Window::Onunload DontDelete
297 frameElement Window::FrameElement DontDelete|ReadOnly
300 IMPLEMENT_PROTOFUNC(WindowFunc)
302 Window::Window(KHTMLPart *p)
303 : ObjectImp(/*no proto*/)
318 winq = new WindowQObject(this);
319 //kdDebug(6070) << "Window::Window this=" << this << " part=" << m_part << " " << m_part->name() << endl;
324 kdDebug(6070) << "Window::~Window this=" << this << " part=" << m_part << endl;
328 KJS::Interpreter *Window::interpreter() const
330 return KJSProxy::proxy( m_part )->interpreter();
333 Window *Window::retrieveWindow(KHTMLPart *p)
335 Object obj = Object::dynamicCast( retrieve( p ) );
337 // obj should never be null, except when javascript has been disabled in that part.
338 if ( p && p->jScriptEnabled() )
340 assert( !obj.isNull() );
342 //assert( dynamic_cast<KJS::Window*>(obj.imp()) ); // type checking
346 if ( obj.isNull() ) // JS disabled
348 return static_cast<KJS::Window*>(obj.imp());
351 Window *Window::retrieveActive(ExecState *exec)
353 ValueImp *imp = exec->dynamicInterpreter()->globalObject().imp();
356 //assert( dynamic_cast<KJS::Window*>(imp) );
358 return static_cast<KJS::Window*>(imp);
361 Value Window::retrieve(KHTMLPart *p)
364 KJSProxy *proxy = KJSProxy::proxy( p );
367 kdDebug(6070) << "Window::retrieve part=" << p << " interpreter=" << proxy->interpreter() << " window=" << proxy->interpreter()->globalObject().imp() << endl;
369 return proxy->interpreter()->globalObject(); // the Global object is the "window"
371 return Undefined(); // This can happen with JS disabled on the domain of that window
374 Location *Window::location() const
377 const_cast<Window*>(this)->loc = new Location(m_part);
381 Selection *Window::selection() const
384 const_cast<Window*>(this)->m_selection = new Selection(m_part);
388 BarInfo *Window::locationbar(ExecState *exec) const
391 const_cast<Window*>(this)->m_locationbar = new BarInfo(exec, m_part, BarInfo::Locationbar);
392 return m_locationbar;
395 BarInfo *Window::menubar(ExecState *exec) const
398 const_cast<Window*>(this)->m_menubar = new BarInfo(exec, m_part, BarInfo::Menubar);
402 BarInfo *Window::personalbar(ExecState *exec) const
405 const_cast<Window*>(this)->m_personalbar = new BarInfo(exec, m_part, BarInfo::Personalbar);
406 return m_personalbar;
409 BarInfo *Window::statusbar(ExecState *exec) const
412 const_cast<Window*>(this)->m_statusbar = new BarInfo(exec, m_part, BarInfo::Statusbar);
416 BarInfo *Window::toolbar(ExecState *exec) const
419 const_cast<Window*>(this)->m_toolbar = new BarInfo(exec, m_part, BarInfo::Toolbar);
423 BarInfo *Window::scrollbars(ExecState *exec) const
426 const_cast<Window*>(this)->m_scrollbars = new BarInfo(exec, m_part, BarInfo::Scrollbars);
430 // reference our special objects during garbage collection
434 if (screen && !screen->marked())
436 if (history && !history->marked())
438 if (frames && !frames->marked())
440 //kdDebug(6070) << "Window::mark " << this << " marking loc=" << loc << endl;
441 if (loc && !loc->marked())
443 if (m_selection && !m_selection->marked())
445 if (m_locationbar && !m_locationbar->marked())
446 m_locationbar->mark();
447 if (m_menubar && !m_menubar->marked())
449 if (m_personalbar && !m_personalbar->marked())
450 m_personalbar->mark();
451 if (m_scrollbars && !m_scrollbars->marked())
452 m_scrollbars->mark();
453 if (m_statusbar && !m_statusbar->marked())
455 if (m_toolbar && !m_toolbar->marked())
459 UString Window::toString(ExecState *) const
461 return "[object Window]";
464 static ElementImpl *frameElement(ExecState *exec, KHTMLPart *part)
466 // Find the frame element.
467 DocumentImpl *document = part->xmlDocImpl();
470 ElementImpl *frameElement = document->ownerElement();
474 // Find the window object for the frame element, and do a cross-domain check.
475 DocumentImpl *frameElementDocument = frameElement->getDocument();
476 if (!frameElementDocument)
478 KHTMLPart *frameElementPart = frameElementDocument->part();
479 if (!frameElementPart)
481 Window *frameElementWindow = Window::retrieveWindow(frameElementPart);
482 if (!frameElementWindow)
484 if (!frameElementWindow->isSafeScript(exec))
490 Value Window::get(ExecState *exec, const Identifier &p) const
493 kdDebug(6070) << "Window("<<this<<")::get " << p.qstring() << endl;
496 return Boolean(m_part.isNull());
498 // we don't want any properties other than "closed" on a closed window
502 // Look for overrides first
503 ValueImp * val = ObjectImp::getDirect(p);
505 //kdDebug(6070) << "Window::get found dynamic property '" << p.ascii() << "'" << endl;
506 if (isSafeScript(exec))
510 // Check for child frames by name before built-in properties to
511 // match behavior of other browsers.
512 KHTMLPart *childFrame = m_part->childFrameNamed(p.ustring().qstring());
514 return retrieve(childFrame);
516 const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
519 //kdDebug(6070) << "token: " << entry->value << endl;
520 switch( entry->value ) {
522 return Undefined(); // ###
524 return String(UString(m_part->jsDefaultStatusBarText()));
526 return String(UString(m_part->jsStatusBarText()));
528 if (isSafeScript(exec))
530 if (m_part->document().isNull()) {
532 KWQ(m_part)->createEmptyDocument();
534 kdDebug(6070) << "Document.write: adding <HTML><BODY> to create document" << endl;
536 m_part->write("<HTML><BODY>");
539 Value val = getDOMNode(exec,m_part->document());
545 return getNodeConstructor(exec);
547 return getRangeConstructor(exec);
549 return getNodeFilterConstructor(exec);
551 return getDOMExceptionConstructor(exec);
553 return getCSSRuleConstructor(exec);
555 return getEventConstructor(exec);
557 return Value(frames ? frames :
558 (const_cast<Window*>(this)->frames = new FrameArray(exec,m_part)));
560 return Value(history ? history :
561 (const_cast<Window*>(this)->history = new History(exec,m_part)));
565 return getDOMEvent(exec,*m_evt);
568 kdWarning(6070) << "window(" << this << "," << m_part->name() << ").event, no event!" << endl;
575 return Number(m_part->view()->visibleHeight());
579 return Number(m_part->view()->visibleWidth());
581 return Number(m_part->frames().count());
583 return Value(location());
585 return String(m_part->name());
587 case ClientInformation: {
588 // Store the navigator in the object so we get the same one each time.
589 Navigator *n = new Navigator(exec, m_part);
590 const_cast<Window *>(this)->putDirect("navigator", n, DontDelete|ReadOnly);
591 const_cast<Window *>(this)->putDirect("clientInformation", n, DontDelete|ReadOnly);
596 return Value(new Konqueror(m_part));
599 return Value(locationbar(exec));
601 return Value(menubar(exec));
602 case OffscreenBuffering:
603 return Boolean(true);
605 if (!m_part->opener())
606 return Null(); // ### a null Window might be better, but == null
607 else // doesn't work yet
608 return retrieve(m_part->opener());
614 KWin::Info inf = KWin::info(m_part->view()->topLevelWidget()->winId());
615 return Number(entry->value == OuterHeight ?
616 inf.geometry.height() : inf.geometry.width());
622 return Number(m_part->view()->contentsX());
627 return Number(m_part->view()->contentsY());
629 return Value(retrieve(m_part->parentPart() ? m_part->parentPart() : (KHTMLPart*)m_part));
631 return Value(personalbar(exec));
637 // We want to use frameGeometry here instead of mapToGlobal because it goes through
638 // the windowFrame method of the WebKit's UI delegate. Also we don't want to try
639 // to do anything relative to the screen the window is on, so the code below is no
640 // good of us anyway.
641 return Number(m_part->view()->topLevelWidget()->frameGeometry().x());
643 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
644 return Number(m_part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
652 // See comment above in ScreenX.
653 return Number(m_part->view()->topLevelWidget()->frameGeometry().y());
655 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
656 return Number(m_part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
663 return Number(m_part->view()->contentsX());
669 return Number(m_part->view()->contentsY());
672 return Value(scrollbars(exec));
674 return Value(statusbar(exec));
676 return Value(toolbar(exec));
679 return Value(retrieve(m_part));
681 KHTMLPart *p = m_part;
682 while (p->parentPart())
684 return Value(retrieve(p));
687 return Value(screen ? screen :
688 (const_cast<Window*>(this)->screen = new Screen(exec)));
690 return Value(new ImageConstructorImp(exec, m_part->document()));
692 return Value(new OptionConstructorImp(exec, m_part->document()));
694 return Value(new XMLHttpRequestConstructorImp(exec, m_part->document()));
696 return Value(new XMLSerializerConstructorImp(exec));
700 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
708 case Scroll: // compatibility
717 case AddEventListener:
718 case RemoveEventListener:
724 if (isSafeScript(exec))
725 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
729 if (isSafeScript(exec))
730 return getListener(exec,DOM::EventImpl::ABORT_EVENT);
734 if (isSafeScript(exec))
735 return getListener(exec,DOM::EventImpl::BLUR_EVENT);
739 if (isSafeScript(exec))
740 return getListener(exec,DOM::EventImpl::CHANGE_EVENT);
744 if (isSafeScript(exec))
745 return getListener(exec,DOM::EventImpl::KHTML_CLICK_EVENT);
749 if (isSafeScript(exec))
750 return getListener(exec,DOM::EventImpl::KHTML_DBLCLICK_EVENT);
754 if (isSafeScript(exec))
755 return getListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT);
759 if (isSafeScript(exec))
760 return getListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT);
764 if (isSafeScript(exec))
765 return getListener(exec,DOM::EventImpl::FOCUS_EVENT);
769 if (isSafeScript(exec))
770 return getListener(exec,DOM::EventImpl::KEYDOWN_EVENT);
774 if (isSafeScript(exec))
775 return getListener(exec,DOM::EventImpl::KEYPRESS_EVENT);
779 if (isSafeScript(exec))
780 return getListener(exec,DOM::EventImpl::KEYUP_EVENT);
784 if (isSafeScript(exec))
785 return getListener(exec,DOM::EventImpl::LOAD_EVENT);
789 if (isSafeScript(exec))
790 return getListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT);
794 if (isSafeScript(exec))
795 return getListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT);
799 if (isSafeScript(exec))
800 return getListener(exec,DOM::EventImpl::MOUSEOUT_EVENT);
804 if (isSafeScript(exec))
805 return getListener(exec,DOM::EventImpl::MOUSEOVER_EVENT);
809 if (isSafeScript(exec))
810 return getListener(exec,DOM::EventImpl::MOUSEUP_EVENT);
813 case OnWindowMouseWheel:
814 if (isSafeScript(exec))
815 return getListener(exec, DOM::EventImpl::MOUSEWHEEL_EVENT);
819 if (isSafeScript(exec))
820 return getListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT);
824 if (isSafeScript(exec))
825 return getListener(exec,DOM::EventImpl::RESET_EVENT);
829 if (isSafeScript(exec))
830 return getListener(exec,DOM::EventImpl::RESIZE_EVENT);
834 if (isSafeScript(exec))
835 return getListener(exec,DOM::EventImpl::SCROLL_EVENT);
840 if (isSafeScript(exec))
841 return getListener(exec,DOM::EventImpl::SEARCH_EVENT);
846 if (isSafeScript(exec))
847 return getListener(exec,DOM::EventImpl::SELECT_EVENT);
851 if (isSafeScript(exec))
852 return getListener(exec,DOM::EventImpl::SUBMIT_EVENT);
856 if (isSafeScript(exec))
857 return getListener(exec,DOM::EventImpl::UNLOAD_EVENT);
861 ElementImpl *fe = frameElement(exec, m_part);
864 return getDOMNode(exec, fe);
869 KHTMLPart *kp = m_part->findFrame( p.qstring() );
871 return Value(retrieve(kp));
873 // allow window[1] or parent[1] etc. (#56983)
875 unsigned int i = p.toArrayIndex(&ok);
877 QPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
878 unsigned int len = frames.count();
880 KParts::ReadOnlyPart* frame = frames.at(i);
881 if (frame && frame->inherits("KHTMLPart")) {
882 KHTMLPart *khtml = static_cast<KHTMLPart*>(frame);
883 return Window::retrieve(khtml);
888 // allow shortcuts like 'Image1' instead of document.images.Image1
889 if (isSafeScript(exec) &&
890 m_part->document().isHTMLDocument()) { // might be XML
891 DOM::HTMLCollection coll = m_part->htmlDocument().all();
892 DOM::HTMLElement element = coll.namedItem(p.string());
893 if (!element.isNull()) {
894 return getDOMNode(exec,element);
898 // This isn't necessarily a bug. Some code uses if(!window.blah) window.blah=1
899 // But it can also mean something isn't loaded or implemented, hence the WARNING to help grepping.
901 kdDebug(6070) << "WARNING: Window::get property not found: " << p.qstring() << endl;
904 if (isSafeScript(exec))
905 return ObjectImp::get(exec, p);
910 bool Window::hasProperty(ExecState *exec, const Identifier &p) const
912 // matches logic in get function above, but no need to handle numeric values (frame indices)
915 return p == "closed";
920 if (Lookup::findEntry(&WindowTable, p))
923 if (m_part->findFrame(p.qstring()))
926 if (!m_part->htmlDocument().all().namedItem(p.string()).isNull())
932 void Window::put(ExecState* exec, const Identifier &propertyName, const Value &value, int attr)
934 // Called by an internal KJS call (e.g. InterpreterImp's constructor) ?
935 // If yes, save time and jump directly to ObjectImp.
936 if ( (attr != None && attr != DontDelete)
937 // Same thing if we have a local override (e.g. "var location")
938 || ( ObjectImp::getDirect(propertyName) && isSafeScript(exec)) )
940 ObjectImp::put( exec, propertyName, value, attr );
944 const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
948 kdDebug(6070) << "Window("<<this<<")::put " << propertyName.qstring() << endl;
950 switch( entry->value ) {
952 String s = value.toString(exec);
953 m_part->setJSStatusBarText(s.value().qstring());
956 case DefaultStatus: {
957 String s = value.toString(exec);
958 m_part->setJSDefaultStatusBarText(s.value().qstring());
962 KHTMLPart* p = Window::retrieveActive(exec)->m_part;
964 QString dstUrl = p->htmlDocument().completeURL(value.toString(exec).string()).string();
965 if (!dstUrl.startsWith("javascript:", false) || isSafeScript(exec))
967 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
969 // We want a new history item if this JS was called via a user gesture
970 m_part->scheduleLocationChange(dstUrl, p->referrer(), !userGesture, userGesture);
972 m_part->scheduleLocationChange(dstUrl, p->referrer(), false /*don't lock history*/, userGesture);
979 if (isSafeScript(exec))
980 setListener(exec, DOM::EventImpl::ABORT_EVENT,value);
983 if (isSafeScript(exec))
984 setListener(exec, DOM::EventImpl::BLUR_EVENT,value);
987 if (isSafeScript(exec))
988 setListener(exec, DOM::EventImpl::CHANGE_EVENT,value);
991 if (isSafeScript(exec))
992 setListener(exec,DOM::EventImpl::KHTML_CLICK_EVENT,value);
995 if (isSafeScript(exec))
996 setListener(exec,DOM::EventImpl::KHTML_DBLCLICK_EVENT,value);
999 if (isSafeScript(exec))
1000 setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
1003 if (isSafeScript(exec))
1004 setListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT,value);
1007 if (isSafeScript(exec))
1008 setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
1011 if (isSafeScript(exec))
1012 setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
1015 if (isSafeScript(exec))
1016 setListener(exec,DOM::EventImpl::KEYPRESS_EVENT,value);
1019 if (isSafeScript(exec))
1020 setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
1023 if (isSafeScript(exec))
1024 setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
1027 if (isSafeScript(exec))
1028 setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
1031 if (isSafeScript(exec))
1032 setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
1035 if (isSafeScript(exec))
1036 setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
1039 if (isSafeScript(exec))
1040 setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
1043 if (isSafeScript(exec))
1044 setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
1046 case OnWindowMouseWheel:
1047 if (isSafeScript(exec))
1048 setListener(exec, DOM::EventImpl::MOUSEWHEEL_EVENT,value);
1051 if (isSafeScript(exec))
1052 setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
1055 if (isSafeScript(exec))
1056 setListener(exec,DOM::EventImpl::RESET_EVENT,value);
1059 if (isSafeScript(exec))
1060 setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
1063 if (isSafeScript(exec))
1064 setListener(exec,DOM::EventImpl::SCROLL_EVENT,value);
1068 if (isSafeScript(exec))
1069 setListener(exec,DOM::EventImpl::SEARCH_EVENT,value);
1073 if (isSafeScript(exec))
1074 setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
1077 if (isSafeScript(exec))
1078 setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
1081 if (isSafeScript(exec))
1082 setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
1085 if (isSafeScript(exec))
1087 m_part->setName( value.toString(exec).qstring() );
1089 m_part->setName( value.toString(exec).qstring().local8Bit().data() );
1096 if (isSafeScript(exec)) {
1097 //kdDebug(6070) << "Window("<<this<<")::put storing " << propertyName.qstring() << endl;
1098 ObjectImp::put(exec, propertyName, value, attr);
1102 bool Window::toBoolean(ExecState *) const
1104 return !m_part.isNull();
1107 int Window::installTimeout(const UString &handler, int t, bool singleShot)
1109 return winq->installTimeout(handler, t, singleShot);
1112 int Window::installTimeout(const Value &function, List &args, int t, bool singleShot)
1114 return winq->installTimeout(function, args, t, singleShot);
1117 void Window::clearTimeout(int timerId)
1119 winq->clearTimeout(timerId);
1123 bool Window::hasTimeouts()
1125 return winq->hasTimeouts();
1128 QMap<int, ScheduledAction*> *Window::pauseTimeouts(const void *key)
1130 return winq->pauseTimeouts(key);
1133 void Window::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
1135 return winq->resumeTimeouts(sa, key);
1139 void Window::scheduleClose()
1141 kdDebug(6070) << "Window::scheduleClose window.close() " << m_part << endl;
1144 KWQ(m_part)->scheduleClose();
1146 QTimer::singleShot( 0, winq, SLOT( timeoutClose() ) );
1150 static bool shouldLoadAsEmptyDocument(const KURL &url)
1152 return url.protocol().lower() == "about" || url.isEmpty();
1155 bool Window::isSafeScript (const KJS::ScriptInterpreter *origin, const KJS::ScriptInterpreter *target)
1157 if (origin == target)
1160 KHTMLPart *originPart = origin->part();
1161 KHTMLPart *targetPart = target->part();
1163 // JS may be attempting to access the "window" object, which should be valid,
1164 // even if the document hasn't been constructed yet. If the document doesn't
1165 // exist yet allow JS to access the window object.
1166 if (!targetPart->xmlDocImpl())
1169 DOM::DocumentImpl *originDocument = originPart->xmlDocImpl();
1170 DOM::DocumentImpl *targetDocument = targetPart->xmlDocImpl();
1172 if (!targetDocument) {
1176 DOM::DOMString targetDomain = targetDocument->domain();
1178 // Always allow local pages to execute any JS.
1179 if (targetDomain.isNull())
1182 DOM::DOMString originDomain = originDocument->domain();
1184 // if this document is being initially loaded as empty by its parent
1185 // or opener, allow access from any document in the same domain as
1186 // the parent or opener.
1187 if (shouldLoadAsEmptyDocument(targetPart->url())) {
1188 KHTMLPart *ancestorPart = targetPart->opener() ? targetPart->opener() : targetPart->parentPart();
1189 while (ancestorPart && shouldLoadAsEmptyDocument(ancestorPart->url())) {
1190 ancestorPart = ancestorPart->parentPart();
1194 originDomain = ancestorPart->xmlDocImpl()->domain();
1197 if ( targetDomain == originDomain )
1200 if (Interpreter::shouldPrintExceptions()) {
1201 printf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1202 targetDocument->URL().latin1(), originDocument->URL().latin1());
1205 message.sprintf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1206 targetDocument->URL().latin1(), originDocument->URL().latin1());
1207 KWQ(targetPart)->addMessageToConsole(message, 1, QString()); //fixme: provide a real line number and sourceurl
1212 bool Window::isSafeScript(ExecState *exec) const
1214 if (m_part.isNull()) { // part deleted ? can't grant access
1215 kdDebug(6070) << "Window::isSafeScript: accessing deleted part !" << endl;
1218 KHTMLPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->dynamicInterpreter() )->part();
1220 kdDebug(6070) << "Window::isSafeScript: current interpreter's part is 0L!" << endl;
1223 if ( activePart == m_part ) // Not calling from another frame, no problem.
1226 // JS may be attempting to access the "window" object, which should be valid,
1227 // even if the document hasn't been constructed yet. If the document doesn't
1228 // exist yet allow JS to access the window object.
1229 if (!m_part->xmlDocImpl())
1232 DOM::DocumentImpl* thisDocument = m_part->xmlDocImpl();
1233 DOM::DocumentImpl* actDocument = activePart->xmlDocImpl();
1236 kdDebug(6070) << "Window::isSafeScript: active part has no document!" << endl;
1240 DOM::DOMString actDomain = actDocument->domain();
1242 // Always allow local pages to execute any JS.
1243 if (actDomain.isNull())
1246 DOM::DOMString thisDomain = thisDocument->domain();
1248 // if this document is being initially loaded as empty by its parent
1249 // or opener, allow access from any document in the same domain as
1250 // the parent or opener.
1251 if (shouldLoadAsEmptyDocument(m_part->url())) {
1252 KHTMLPart *ancestorPart = m_part->opener() ? m_part->opener() : m_part->parentPart();
1253 while (ancestorPart && shouldLoadAsEmptyDocument(ancestorPart->url())) {
1254 ancestorPart = ancestorPart->parentPart();
1258 thisDomain = ancestorPart->xmlDocImpl()->domain();
1261 //kdDebug(6070) << "current domain:" << actDomain.string() << ", frame domain:" << thisDomain.string() << endl;
1262 if ( actDomain == thisDomain )
1266 if (Interpreter::shouldPrintExceptions()) {
1267 printf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1268 thisDocument->URL().latin1(), actDocument->URL().latin1());
1271 message.sprintf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1272 thisDocument->URL().latin1(), actDocument->URL().latin1());
1273 KWQ(m_part)->addMessageToConsole(message, 1, QString());
1276 kdWarning(6070) << "Javascript: access denied for current frame '" << actDomain.string() << "' to frame '" << thisDomain.string() << "'" << endl;
1280 void Window::setListener(ExecState *exec, int eventId, Value func)
1282 if (!isSafeScript(exec))
1284 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(m_part->htmlDocument().handle());
1288 doc->setHTMLWindowEventListener(eventId,getJSEventListener(func,true));
1291 Value Window::getListener(ExecState *exec, int eventId) const
1293 if (!isSafeScript(exec))
1295 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(m_part->htmlDocument().handle());
1299 DOM::EventListener *listener = doc->getHTMLWindowEventListener(eventId);
1300 if (listener && static_cast<JSEventListener*>(listener)->listenerObjImp())
1301 return static_cast<JSEventListener*>(listener)->listenerObj();
1306 JSEventListener *Window::getJSEventListener(const Value& val, bool html)
1308 // This function is so hot that it's worth coding it directly with imps.
1309 if (val.type() != ObjectType)
1311 ObjectImp *listenerObject = static_cast<ObjectImp *>(val.imp());
1313 JSEventListener *existingListener = jsEventListeners[listenerObject];
1314 if (existingListener)
1315 return existingListener;
1317 // Note that the JSEventListener constructor adds it to our jsEventListeners list
1318 return new JSEventListener(Object(listenerObject), Object(this), html);
1321 JSUnprotectedEventListener *Window::getJSUnprotectedEventListener(const Value& val, bool html)
1323 // This function is so hot that it's worth coding it directly with imps.
1324 if (val.type() != ObjectType)
1326 ObjectImp *listenerObject = static_cast<ObjectImp *>(val.imp());
1328 JSUnprotectedEventListener *existingListener = jsUnprotectedEventListeners[listenerObject];
1329 if (existingListener)
1330 return existingListener;
1332 // Note that the JSUnprotectedEventListener constructor adds it to
1333 // our jsUnprotectedEventListeners list
1334 return new JSUnprotectedEventListener(Object(listenerObject), Object(this), html);
1337 JSLazyEventListener *Window::getJSLazyEventListener(const QString& code, DOM::NodeImpl *node, int lineNumber)
1339 return new JSLazyEventListener(code, Object(this), node, lineNumber);
1342 void Window::clear( ExecState *exec )
1344 KJS::Interpreter::lock();
1345 kdDebug(6070) << "Window::clear " << this << endl;
1347 winq = new WindowQObject(this);;
1348 // Get rid of everything, those user vars could hold references to DOM nodes
1349 deleteAllProperties( exec );
1350 // Really delete those properties, so that the DOM nodes get deref'ed
1351 KJS::Collector::collect();
1352 // Now recreate a working global object for the next URL that will use us
1353 KJS::Interpreter *interpreter = KJSProxy::proxy( m_part )->interpreter();
1354 interpreter->initGlobalObject();
1355 KJS::Interpreter::unlock();
1358 void Window::setCurrentEvent( DOM::Event *evt )
1361 //kdDebug(6070) << "Window " << this << " (part=" << m_part << ")::setCurrentEvent m_evt=" << evt << endl;
1364 Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
1366 if (!thisObj.inherits(&Window::info)) {
1367 Object err = Error::create(exec,TypeError);
1368 exec->setException(err);
1371 Window *window = static_cast<Window *>(thisObj.imp());
1374 KHTMLPart *part = window->m_part;
1378 KHTMLView *widget = part->view();
1380 UString s = v.toString(exec);
1385 if (part && part->xmlDocImpl())
1386 part->xmlDocImpl()->updateRendering();
1388 KWQ(part)->runJavaScriptAlert(str);
1390 KMessageBox::error(widget, QStyleSheet::convertFromPlainText(str), "JavaScript");
1393 case Window::Confirm:
1394 if (part && part->xmlDocImpl())
1395 part->xmlDocImpl()->updateRendering();
1397 return Boolean(KWQ(part)->runJavaScriptConfirm(str));
1399 return Boolean((KMessageBox::warningYesNo(widget, QStyleSheet::convertFromPlainText(str), "JavaScript",
1400 i18n("OK"), i18n("Cancel")) == KMessageBox::Yes));
1402 case Window::Prompt:
1403 if (part && part->xmlDocImpl())
1404 part->xmlDocImpl()->updateRendering();
1407 ok = KWQ(part)->runJavaScriptPrompt(str, args.size() >= 2 ? args[1].toString(exec).qstring() : QString::null, str2);
1409 if (args.size() >= 2)
1410 str2 = QInputDialog::getText(i18n("Konqueror: Prompt"),
1411 QStyleSheet::convertFromPlainText(str),
1413 args[1].toString(exec).qstring(), &ok);
1415 str2 = QInputDialog::getText(i18n("Konqueror: Prompt"),
1416 QStyleSheet::convertFromPlainText(str),
1418 QString::null, &ok);
1421 return String(str2);
1426 KConfig *config = new KConfig("konquerorrc");
1427 config->setGroup("Java/JavaScript Settings");
1429 int policy = config->readUnsignedNumEntry( "WindowOpenPolicy", 0 ); // 0=allow, 1=ask, 2=deny, 3=smart
1431 int policy = config->readUnsignedNumEntry( part->settings(), "WindowOpenPolicy", 0 ); // 0=allow, 1=ask, 2=deny, 3=smart
1434 if ( policy == 1 ) {
1436 if ( KMessageBox::questionYesNo(widget,
1437 i18n( "This site is trying to open up a new browser "
1438 "window using Javascript.\n"
1439 "Do you want to allow this?" ),
1440 i18n( "Confirmation: Javascript Popup" ) ) == KMessageBox::Yes )
1443 } else if ( policy == 3 ) // smart
1445 // window.open disabled unless from a key/mouse event
1446 if (static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture())
1452 LOG(PopupBlocking, "Allowed JavaScript window open of %s", args[0].toString(exec).qstring().ascii());
1454 LOG(PopupBlocking, "Blocked JavaScript window open of %s", args[0].toString(exec).qstring().ascii());
1459 QString frameName = !args[1].isNull() && args[1].type() != UndefinedType ?
1460 args[1].toString(exec).qstring()
1461 : QString("_blank");
1463 if ( policy != 0 && !(part->findFrame(frameName) || frameName == "_top" || frameName == "_parent" || frameName == "_self")) {
1466 if (v.type() == UndefinedType)
1469 KParts::WindowArgs winargs;
1471 // scan feature argument
1474 if (!v.isNull() && v.type() != UndefinedType && v.toString(exec).size() > 0) {
1475 features = v.toString(exec).qstring();
1476 // specifying window params means false defaults
1477 winargs.menuBarVisible = false;
1478 winargs.toolBarsVisible = false;
1479 winargs.statusBarVisible = false;
1481 winargs.scrollbarsVisible = true;
1483 QStringList flist = QStringList::split(',', features);
1484 QStringList::ConstIterator it = flist.begin();
1485 while (it != flist.end()) {
1488 int pos = s.find('=');
1490 key = s.left(pos).stripWhiteSpace().lower();
1491 val = s.mid(pos + 1).stripWhiteSpace().lower();
1492 int spacePos = val.find(' ');
1493 if (spacePos != -1) {
1494 val = val.left(spacePos);
1497 int scnum = QApplication::desktop()->screenNumber(widget->topLevelWidget());
1499 QRect screen = QApplication::desktop()->screenGeometry(scnum);
1500 if (key == "left" || key == "screenx") {
1502 double d = val.toDouble(&ok);
1505 if (d < screen.x() || d > screen.right())
1506 d = screen.x(); // only safe choice until size is determined
1509 winargs.xSet = true;
1512 } else if (key == "top" || key == "screeny") {
1514 double d = val.toDouble(&ok);
1517 if (d < screen.y() || d > screen.bottom())
1518 d = screen.y(); // only safe choice until size is determined
1521 winargs.ySet = true;
1524 } else if (key == "height") {
1526 double d = val.toDouble(&ok);
1529 d += 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
1531 if (d > screen.height()) // should actually check workspace
1532 d = screen.height();
1535 winargs.height = (int)d;
1537 winargs.heightSet = true;
1540 } else if (key == "width") {
1542 double d = val.toDouble(&ok);
1545 d += 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
1547 if (d > screen.width()) // should actually check workspace
1551 winargs.width = (int)d;
1553 winargs.widthSet = true;
1561 // leaving away the value gives true
1562 key = s.stripWhiteSpace().lower();
1566 if (key == "menubar")
1567 winargs.menuBarVisible = (val == "1" || val == "yes");
1568 else if (key == "toolbar")
1569 winargs.toolBarsVisible = (val == "1" || val == "yes");
1570 else if (key == "location") // ### missing in WindowArgs
1571 winargs.toolBarsVisible = (val == "1" || val == "yes");
1572 else if (key == "status" || key == "statusbar")
1573 winargs.statusBarVisible = (val == "1" || val == "yes");
1574 else if (key == "resizable")
1575 winargs.resizable = (val == "1" || val == "yes");
1576 else if (key == "fullscreen")
1577 winargs.fullscreen = (val == "1" || val == "yes");
1579 else if (key == "scrollbars")
1580 winargs.scrollbarsVisible = !(val == "0" || val == "no");
1585 // prepare arguments
1587 KHTMLPart* activePart = Window::retrieveActive(exec)->m_part;
1591 url = activePart->htmlDocument().completeURL(str).string();
1594 KParts::URLArgs uargs;
1595 uargs.frameName = frameName;
1596 if ( uargs.frameName == "_top" )
1598 while ( part->parentPart() )
1599 part = part->parentPart();
1601 const Window* window = Window::retrieveWindow(part);
1602 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
1603 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1604 part->scheduleLocationChange(url.url(), activePart->referrer(), false/*don't lock history*/, userGesture);
1606 return Window::retrieve(part);
1608 if ( uargs.frameName == "_parent" )
1610 if ( part->parentPart() )
1611 part = part->parentPart();
1613 const Window* window = Window::retrieveWindow(part);
1614 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
1615 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1616 part->scheduleLocationChange(url.url(), activePart->referrer(), false/*don't lock history*/, userGesture);
1618 return Window::retrieve(part);
1620 uargs.serviceType = "text/html";
1622 // request window (new or existing if framename is set)
1623 KParts::ReadOnlyPart *newPart = 0L;
1624 uargs.metaData()["referrer"] = activePart->referrer();
1625 emit part->browserExtension()->createNewWindow("", uargs,winargs,newPart);
1626 if (newPart && newPart->inherits("KHTMLPart")) {
1627 KHTMLPart *khtmlpart = static_cast<KHTMLPart*>(newPart);
1628 //qDebug("opener set to %p (this Window's part) in new Window %p (this Window=%p)",part,win,window);
1629 khtmlpart->setOpener(part);
1630 khtmlpart->setOpenedByJS(true);
1632 if (khtmlpart->document().isNull()) {
1633 DocumentImpl *oldDoc = part->xmlDocImpl();
1634 if (oldDoc && oldDoc->baseURL() != 0)
1635 khtmlpart->begin(oldDoc->baseURL());
1639 khtmlpart->write("<HTML><BODY>");
1643 kdDebug(6070) << "Setting domain to " << oldDoc->domain().string() << endl;
1644 khtmlpart->xmlDocImpl()->setDomain( oldDoc->domain(), true );
1645 khtmlpart->xmlDocImpl()->setBaseURL( oldDoc->baseURL() );
1649 if (!url.isEmpty()) {
1650 const Window* window = Window::retrieveWindow(khtmlpart);
1651 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
1652 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1653 khtmlpart->scheduleLocationChange(url.url(), activePart->referrer(), false, userGesture);
1657 uargs.serviceType = QString::null;
1658 if (uargs.frameName == "_blank")
1659 uargs.frameName = QString::null;
1660 if (!url.isEmpty()) {
1661 uargs.metaData()["referrer"] = activePart->referrer();
1662 emit khtmlpart->browserExtension()->openURLRequest(url,uargs);
1665 return Window::retrieve(khtmlpart); // global object
1675 case Window::ScrollBy:
1676 window->updateLayout();
1677 if(args.size() >= 2 && widget)
1678 widget->scrollBy(args[0].toInt32(exec), args[1].toInt32(exec));
1680 case Window::Scroll:
1681 case Window::ScrollTo:
1682 window->updateLayout();
1683 if(args.size() >= 2 && widget)
1684 widget->setContentsPos(args[0].toInt32(exec), args[1].toInt32(exec));
1686 case Window::MoveBy:
1687 if(args.size() >= 2 && widget)
1689 QWidget * tl = widget->topLevelWidget();
1690 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1691 QPoint dest = tl->pos() + QPoint( args[0].toInt32(exec), args[1].toInt32(exec) );
1692 // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
1693 if ( dest.x() >= sg.x() && dest.y() >= sg.x() &&
1694 dest.x()+tl->width() <= sg.width()+sg.x() &&
1695 dest.y()+tl->height() <= sg.height()+sg.y() )
1699 case Window::MoveTo:
1700 if(args.size() >= 2 && widget)
1702 QWidget * tl = widget->topLevelWidget();
1703 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1704 QPoint dest( args[0].toInt32(exec)+sg.x(), args[1].toInt32(exec)+sg.y() );
1705 // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
1706 if ( dest.x() >= sg.x() && dest.y() >= sg.y() &&
1707 dest.x()+tl->width() <= sg.width()+sg.x() &&
1708 dest.y()+tl->height() <= sg.height()+sg.y() )
1712 case Window::ResizeBy:
1713 if(args.size() >= 2 && widget)
1715 QWidget * tl = widget->topLevelWidget();
1716 QSize dest = tl->size() + QSize( args[0].toInt32(exec), args[1].toInt32(exec) );
1717 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1718 // Security check: within desktop limits and bigger than 100x100 (per spec)
1719 if ( tl->x()+dest.width() <= sg.x()+sg.width() &&
1720 tl->y()+dest.height() <= sg.y()+sg.height() &&
1721 dest.width() >= 100 && dest.height() >= 100 )
1723 // Take into account the window frame
1724 int deltaWidth = tl->frameGeometry().width() - tl->width();
1725 int deltaHeight = tl->frameGeometry().height() - tl->height();
1726 tl->resize( dest.width() - deltaWidth, dest.height() - deltaHeight );
1730 case Window::ResizeTo:
1731 if(args.size() >= 2 && widget)
1733 QWidget * tl = widget->topLevelWidget();
1734 QSize dest = QSize( args[0].toInt32(exec), args[1].toInt32(exec) );
1735 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1736 // Security check: within desktop limits and bigger than 100x100 (per spec)
1737 if ( tl->x()+dest.width() <= sg.x()+sg.width() &&
1738 tl->y()+dest.height() <= sg.y()+sg.height() &&
1739 dest.width() >= 100 && dest.height() >= 100 )
1741 // Take into account the window frame
1742 int deltaWidth = tl->frameGeometry().width() - tl->width();
1743 int deltaHeight = tl->frameGeometry().height() - tl->height();
1744 tl->resize( dest.width() - deltaWidth, dest.height() - deltaHeight );
1748 case Window::SetTimeout:
1749 if (!window->isSafeScript(exec))
1751 if (args.size() >= 2 && v.isA(StringType)) {
1752 int i = args[1].toInt32(exec);
1753 int r = (const_cast<Window*>(window))->installTimeout(s, i, true /*single shot*/);
1756 else if (args.size() >= 2 && v.isA(ObjectType) && Object::dynamicCast(v).implementsCall()) {
1757 Value func = args[0];
1758 int i = args[1].toInt32(exec);
1760 // All arguments after the second should go to the function
1761 // FIXME: could be more efficient
1762 List funcArgs = args.copyTail().copyTail();
1764 int r = (const_cast<Window*>(window))->installTimeout(func, funcArgs, i, true /*single shot*/);
1769 case Window::SetInterval:
1770 if (!window->isSafeScript(exec))
1772 if (args.size() >= 2 && v.isA(StringType)) {
1773 int i = args[1].toInt32(exec);
1774 int r = (const_cast<Window*>(window))->installTimeout(s, i, false);
1777 else if (args.size() >= 2 && !Object::dynamicCast(v).isNull() &&
1778 Object::dynamicCast(v).implementsCall()) {
1779 Value func = args[0];
1780 int i = args[1].toInt32(exec);
1782 // All arguments after the second should go to the function
1783 // FIXME: could be more efficient
1784 List funcArgs = args.copyTail().copyTail();
1786 int r = (const_cast<Window*>(window))->installTimeout(func, funcArgs, i, false);
1791 case Window::ClearTimeout:
1792 case Window::ClearInterval:
1793 if (!window->isSafeScript(exec))
1795 (const_cast<Window*>(window))->clearTimeout(v.toInt32(exec));
1799 widget->setActiveWindow();
1801 case Window::GetSelection:
1802 if (!window->isSafeScript(exec))
1804 return Value(window->selection());
1807 KWQ(part)->unfocusWindow();
1813 /* From http://developer.netscape.com/docs/manuals/js/client/jsref/window.htm :
1814 The close method closes only windows opened by JavaScript using the open method.
1815 If you attempt to close any other window, a confirm is generated, which
1816 lets the user choose whether the window closes.
1817 This is a security feature to prevent "mail bombs" containing self.close().
1818 However, if the window has only one document (the current one) in its
1819 session history, the close is allowed without any confirm. This is a
1820 special case for one-off windows that need to open other windows and
1821 then dispose of themselves.
1823 if (!part->openedByJS())
1825 // To conform to the SPEC, we only ask if the window
1826 // has more than one entry in the history (NS does that too).
1827 History history(exec,part);
1828 if ( history.get( exec, lengthPropertyName ).toInt32(exec) <= 1
1830 // FIXME: How are we going to handle this?
1832 || KMessageBox::questionYesNo( window->part()->view(), i18n("Close window?"), i18n("Confirmation Required") ) == KMessageBox::Yes
1835 (const_cast<Window*>(window))->scheduleClose();
1839 (const_cast<Window*>(window))->scheduleClose();
1842 case Window::CaptureEvents:
1843 case Window::ReleaseEvents:
1844 // If anyone implements these, they need the safescript security check.
1845 if (!window->isSafeScript(exec))
1848 // Do nothing for now. These are NS-specific legacy calls.
1850 case Window::AddEventListener: {
1851 if (!window->isSafeScript(exec))
1853 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
1855 DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
1857 docimpl->addWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
1861 case Window::RemoveEventListener: {
1862 if (!window->isSafeScript(exec))
1864 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
1866 DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
1868 docimpl->removeWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
1877 void Window::updateLayout() const
1879 DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(m_part->document().handle());
1881 docimpl->updateLayoutIgnorePendingStylesheets();
1885 ////////////////////// ScheduledAction ////////////////////////
1887 ScheduledAction::ScheduledAction(Object _func, List _args, bool _singleShot)
1889 //kdDebug(6070) << "ScheduledAction::ScheduledAction(isFunction) " << this << endl;
1893 singleShot = _singleShot;
1896 ScheduledAction::ScheduledAction(const QString &_code, bool _singleShot)
1898 //kdDebug(6070) << "ScheduledAction::ScheduledAction(!isFunction) " << this << endl;
1903 singleShot = _singleShot;
1907 void ScheduledAction::execute(Window *window)
1909 ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(KJSProxy::proxy(window->m_part)->interpreter());
1911 interpreter->setProcessingTimerCallback(true);
1913 //kdDebug(6070) << "ScheduledAction::execute " << this << endl;
1915 if (func.implementsCall()) {
1917 Q_ASSERT( window->m_part );
1918 if ( window->m_part )
1920 KJS::Interpreter *interpreter = KJSProxy::proxy( window->m_part )->interpreter();
1921 ExecState *exec = interpreter->globalExec();
1922 Q_ASSERT( window == interpreter->globalObject().imp() );
1923 Object obj( window );
1924 Interpreter::lock();
1925 func.call(exec,obj,args); // note that call() creates its own execution state for the func call
1926 Interpreter::unlock();
1927 if ( exec->hadException() ) {
1929 Interpreter::lock();
1930 char *message = exec->exception().toObject(exec).get(exec, messagePropertyName).toString(exec).ascii();
1931 int lineNumber = exec->exception().toObject(exec).get(exec, "line").toInt32(exec);
1932 Interpreter::unlock();
1933 if (Interpreter::shouldPrintExceptions()) {
1934 printf("(timer):%s\n", message);
1936 KWQ(window->m_part)->addMessageToConsole(message, lineNumber, QString());
1938 exec->clearException();
1944 window->m_part->executeScript(code);
1947 // Update our document's rendering following the execution of the timeout callback.
1948 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(window->m_part->document().handle());
1949 doc->updateRendering();
1951 interpreter->setProcessingTimerCallback(false);
1954 ScheduledAction::~ScheduledAction()
1956 //kdDebug(6070) << "ScheduledAction::~ScheduledAction " << this << endl;
1959 ////////////////////// WindowQObject ////////////////////////
1961 WindowQObject::WindowQObject(Window *w)
1964 //kdDebug(6070) << "WindowQObject::WindowQObject " << this << endl;
1965 part = parent->m_part;
1966 connect( parent->m_part, SIGNAL( destroyed() ),
1967 this, SLOT( parentDestroyed() ) );
1970 WindowQObject::~WindowQObject()
1972 //kdDebug(6070) << "WindowQObject::~WindowQObject " << this << endl;
1973 parentDestroyed(); // reuse same code
1976 void WindowQObject::parentDestroyed()
1978 //kdDebug(6070) << "WindowQObject::parentDestroyed " << this << " we have " << scheduledActions.count() << " actions in the map" << endl;
1980 QMapIterator<int,ScheduledAction*> it;
1981 for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
1982 ScheduledAction *action = *it;
1983 //kdDebug(6070) << "WindowQObject::parentDestroyed deleting action " << action << endl;
1986 scheduledActions.clear();
1989 int WindowQObject::installTimeout(const UString &handler, int t, bool singleShot)
1991 //kdDebug(6070) << "WindowQObject::installTimeout " << this << " " << handler.ascii() << endl;
1992 int id = startTimer(t);
1993 ScheduledAction *action = new ScheduledAction(handler.qstring(),singleShot);
1994 scheduledActions.insert(id, action);
1995 //kdDebug(6070) << this << " got id=" << id << " action=" << action << " - now having " << scheduledActions.count() << " actions"<<endl;
1999 int WindowQObject::installTimeout(const Value &func, List args, int t, bool singleShot)
2001 Object objFunc = Object::dynamicCast( func );
2002 int id = startTimer(t);
2003 scheduledActions.insert(id, new ScheduledAction(objFunc,args,singleShot));
2007 QMap<int, ScheduledAction*> *WindowQObject::pauseTimeouts(const void *key)
2009 QMapIterator<int,ScheduledAction*> it;
2011 QMap<int, KJS::ScheduledAction*>*pausedActions = new QMap<int, KJS::ScheduledAction*>;
2012 for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
2013 int timerId = it.key();
2014 pauseTimer (timerId, key);
2015 pausedActions->insert(timerId, it.data());
2017 scheduledActions.clear();
2018 return pausedActions;
2021 void WindowQObject::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
2023 QMapIterator<int,ScheduledAction*> it;
2024 for (it = sa->begin(); it != sa->end(); ++it) {
2025 int timerId = it.key();
2026 scheduledActions.insert(timerId, it.data());
2029 resumeTimers (key, this);
2032 void WindowQObject::clearTimeout(int timerId, bool delAction)
2034 //kdDebug(6070) << "WindowQObject::clearTimeout " << this << " timerId=" << timerId << " delAction=" << delAction << endl;
2037 QMapIterator<int,ScheduledAction*> it = scheduledActions.find(timerId);
2038 if (it != scheduledActions.end()) {
2039 ScheduledAction *action = *it;
2040 scheduledActions.remove(it);
2046 void WindowQObject::timerEvent(QTimerEvent *e)
2048 QMapIterator<int,ScheduledAction*> it = scheduledActions.find(e->timerId());
2049 if (it != scheduledActions.end()) {
2050 ScheduledAction *action = *it;
2051 bool singleShot = action->singleShot;
2052 //kdDebug(6070) << "WindowQObject::timerEvent " << this << " action=" << action << " singleShot:" << singleShot << endl;
2054 // remove single shots installed by setTimeout()
2057 clearTimeout(e->timerId(),false);
2058 scheduledActions.remove(it);
2061 if (!parent->part().isNull())
2062 action->execute(parent);
2064 // It is important to test singleShot and not action->singleShot here - the
2065 // action could have been deleted already if not single shot and if the
2066 // JS code called by execute() calls clearTimeout().
2070 kdWarning(6070) << "WindowQObject::timerEvent this=" << this << " timer " << e->timerId()
2071 << " not found (" << scheduledActions.count() << " actions in map)" << endl;
2074 void WindowQObject::timeoutClose()
2076 if (!parent->part().isNull())
2078 //kdDebug(6070) << "WindowQObject::timeoutClose -> closing window" << endl;
2079 delete parent->m_part;
2084 bool WindowQObject::hasTimeouts()
2086 return scheduledActions.count();
2090 Value FrameArray::get(ExecState *exec, const Identifier &p) const
2093 kdDebug(6070) << "FrameArray::get " << p.qstring() << " part=" << (void*)part << endl;
2098 QPtrList<KParts::ReadOnlyPart> frames = part->frames();
2099 unsigned int len = frames.count();
2100 if (p == lengthPropertyName)
2102 else if (p== "location") // non-standard property, but works in NS and IE
2104 Object obj = Object::dynamicCast( Window::retrieve( part ) );
2105 if ( !obj.isNull() )
2106 return obj.get( exec, "location" );
2110 // check for the name or number
2111 KParts::ReadOnlyPart *frame = part->findFrame(p.qstring());
2114 unsigned int i = p.toArrayIndex(&ok);
2116 frame = frames.at(i);
2119 // we are potentially fetching a reference to a another Window object here.
2120 // i.e. we may be accessing objects from another interpreter instance.
2121 // Therefore we have to be a bit careful with memory managment.
2122 if (frame && frame->inherits("KHTMLPart")) {
2123 KHTMLPart *khtml = static_cast<KHTMLPart*>(frame);
2124 return Window::retrieve(khtml);
2127 return ObjectImp::get(exec, p);
2130 UString FrameArray::toString(ExecState *) const
2132 return "[object FrameArray]";
2135 ////////////////////// Location Object ////////////////////////
2137 const ClassInfo Location::info = { "Location", 0, 0, 0 };
2139 @begin LocationTable 11
2140 hash Location::Hash DontDelete
2141 host Location::Host DontDelete
2142 hostname Location::Hostname DontDelete
2143 href Location::Href DontDelete
2144 pathname Location::Pathname DontDelete
2145 port Location::Port DontDelete
2146 protocol Location::Protocol DontDelete
2147 search Location::Search DontDelete
2148 [[==]] Location::EqualEqual DontDelete|ReadOnly
2149 toString Location::ToString DontDelete|Function 0
2150 replace Location::Replace DontDelete|Function 1
2151 reload Location::Reload DontDelete|Function 0
2154 IMPLEMENT_PROTOFUNC(LocationFunc)
2155 Location::Location(KHTMLPart *p) : m_part(p)
2157 //kdDebug(6070) << "Location::Location " << this << " m_part=" << (void*)m_part << endl;
2160 Location::~Location()
2162 //kdDebug(6070) << "Location::~Location " << this << " m_part=" << (void*)m_part << endl;
2165 Value Location::get(ExecState *exec, const Identifier &p) const
2168 kdDebug(6070) << "Location::get " << p.qstring() << " m_part=" << (void*)m_part << endl;
2171 if (m_part.isNull())
2174 const Window* window = Window::retrieveWindow(m_part);
2175 if (!window || !window->isSafeScript(exec))
2178 KURL url = m_part->url();
2179 const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
2181 switch (entry->value) {
2183 return String( url.ref().isNull() ? QString("") : "#" + url.ref() );
2185 UString str = url.host();
2187 str += ":" + QString::number((int)url.port());
2189 // Note: this is the IE spec. The NS spec swaps the two, it says
2190 // "The hostname property is the concatenation of the host and port properties, separated by a colon."
2194 return String( url.host() );
2197 return String( url.prettyURL()+"/" );
2199 return String( url.prettyURL() );
2201 return String( url.path().isEmpty() ? QString("/") : url.path() );
2203 return String( url.port() ? QString::number((int)url.port()) : QString::fromLatin1("") );
2205 return String( url.protocol()+":" );
2207 return String( url.query() );
2208 case EqualEqual: // [[==]]
2209 return String(toString(exec));
2211 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2213 // Look for overrides
2214 ValueImp * val = ObjectImp::getDirect(p);
2218 switch (entry->value) {
2220 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2222 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2228 void Location::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
2231 kdDebug(6070) << "Location::put " << p.qstring() << " m_part=" << (void*)m_part << endl;
2233 if (m_part.isNull())
2236 QString str = v.toString(exec).qstring();
2237 KURL url = m_part->url();
2238 const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
2240 switch (entry->value) {
2242 KHTMLPart* p = Window::retrieveActive(exec)->part();
2244 url = p->htmlDocument().completeURL( str ).string();
2253 QString host = str.left(str.find(":"));
2254 QString port = str.mid(str.find(":")+1);
2256 url.setPort(port.toUInt());
2266 url.setPort(str.toUInt());
2269 url.setProtocol(str);
2276 ObjectImp::put(exec, p, v, attr);
2280 const Window* window = Window::retrieveWindow(m_part);
2281 KHTMLPart* activePart = Window::retrieveActive(exec)->part();
2282 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2283 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2285 // We want a new history item if this JS was called via a user gesture
2286 m_part->scheduleLocationChange(url.url(), activePart->referrer(), !userGesture, userGesture);
2288 m_part->scheduleLocationChange(url.url(), activePart->referrer(), false /*don't lock history*/, userGesture);
2293 Value Location::toPrimitive(ExecState *exec, Type) const
2295 return String(toString(exec));
2298 UString Location::toString(ExecState *) const
2300 if (!m_part->url().hasPath())
2301 return m_part->url().prettyURL()+"/";
2303 return m_part->url().prettyURL();
2306 Value LocationFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
2308 if (!thisObj.inherits(&Location::info)) {
2309 Object err = Error::create(exec,TypeError);
2310 exec->setException(err);
2313 Location *location = static_cast<Location *>(thisObj.imp());
2314 KHTMLPart *part = location->part();
2317 Window* window = Window::retrieveWindow(part);
2318 if (!window->isSafeScript(exec) && id != Location::Replace)
2322 case Location::Replace:
2324 QString str = args[0].toString(exec).qstring();
2325 KHTMLPart* p = Window::retrieveActive(exec)->part();
2327 const Window* window = Window::retrieveWindow(part);
2328 if (!str.startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2329 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2330 part->scheduleLocationChange(p->htmlDocument().completeURL(str).string(), p->referrer(), true /*lock history*/, userGesture);
2335 case Location::Reload:
2337 const Window* window = Window::retrieveWindow(part);
2338 KHTMLPart* activePart = Window::retrieveActive(exec)->part();
2339 if (!part->url().url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2340 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2341 part->scheduleLocationChange(part->url().url(), activePart->referrer(), true/*lock history*/, userGesture);
2345 case Location::ToString:
2346 return String(location->toString(exec));
2349 kdDebug(6070) << "LocationFunc::tryExecute - no part!" << endl;
2353 ////////////////////// Selection Object ////////////////////////
2355 const ClassInfo Selection::info = { "Selection", 0, 0, 0 };
2357 @begin SelectionTable 19
2358 anchorNode Selection::AnchorNode DontDelete|ReadOnly
2359 anchorOffset Selection::AnchorOffset DontDelete|ReadOnly
2360 focusNode Selection::FocusNode DontDelete|ReadOnly
2361 focusOffset Selection::FocusOffset DontDelete|ReadOnly
2362 baseNode Selection::AnchorNode DontDelete|ReadOnly
2363 baseOffset Selection::AnchorOffset DontDelete|ReadOnly
2364 extentNode Selection::FocusNode DontDelete|ReadOnly
2365 extentOffset Selection::FocusOffset DontDelete|ReadOnly
2366 isCollapsed Selection::IsCollapsed DontDelete|ReadOnly
2367 type Selection::_Type DontDelete|ReadOnly
2368 [[==]] Selection::EqualEqual DontDelete|ReadOnly
2369 toString Selection::ToString DontDelete|Function 0
2370 collapse Selection::Collapse DontDelete|Function 2
2371 collapseToEnd Selection::CollapseToEnd DontDelete|Function 0
2372 collapseToStart Selection::CollapseToStart DontDelete|Function 0
2373 empty Selection::Empty DontDelete|Function 0
2374 setBaseAndExtent Selection::SetBaseAndExtent DontDelete|Function 4
2375 setPosition Selection::SetPosition DontDelete|Function 2
2376 modify Selection::Modify DontDelete|Function 3
2379 IMPLEMENT_PROTOFUNC(SelectionFunc)
2380 Selection::Selection(KHTMLPart *p) : m_part(p)
2382 //kdDebug(6070) << "Selection::Selection " << this << " m_part=" << (void*)m_part << endl;
2385 Selection::~Selection()
2387 //kdDebug(6070) << "Selection::~Selection " << this << " m_part=" << (void*)m_part << endl;
2390 Value Selection::get(ExecState *exec, const Identifier &p) const
2393 kdDebug(6070) << "Selection::get " << p.qstring() << " m_part=" << (void*)m_part << endl;
2396 if (m_part.isNull())
2399 const Window* window = Window::retrieveWindow(m_part);
2400 if (!window || !window->isSafeScript(exec))
2403 DocumentImpl *docimpl = m_part->xmlDocImpl();
2405 docimpl->updateLayoutIgnorePendingStylesheets();
2407 KURL url = m_part->url();
2408 const HashEntry *entry = Lookup::findEntry(&SelectionTable, p);
2410 switch (entry->value) {
2413 return getDOMNode(exec, Node(m_part->selection().base().node()));
2416 return Number(m_part->selection().base().offset());
2419 return getDOMNode(exec, Node(m_part->selection().extent().node()));
2422 return Number(m_part->selection().extent().offset());
2424 return Boolean(!m_part->selection().isRange());
2426 switch (m_part->selection().state()) {
2427 case khtml::Selection::NONE:
2428 return String("None");
2429 case khtml::Selection::CARET:
2430 return String("Caret");
2431 case khtml::Selection::RANGE:
2432 return String("Range");
2436 return String(toString(exec));
2438 return lookupOrCreateFunction<SelectionFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2440 // Look for overrides
2441 ValueImp * val = ObjectImp::getDirect(p);
2445 switch (entry->value) {
2448 case CollapseToStart:
2450 case SetBaseAndExtent:
2453 return lookupOrCreateFunction<SelectionFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2459 void Selection::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
2463 Value Selection::toPrimitive(ExecState *exec, Type) const
2465 return String(toString(exec));
2468 UString Selection::toString(ExecState *) const
2470 if (!m_part->selection().isRange())
2472 return UString(m_part->selection().toRange().toString());
2475 Value SelectionFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
2477 if (!thisObj.inherits(&Selection::info)) {
2478 Object err = Error::create(exec,TypeError);
2479 exec->setException(err);
2482 Selection *selection = static_cast<Selection *>(thisObj.imp());
2483 KHTMLPart *part = selection->part();
2485 DocumentImpl *docimpl = part->xmlDocImpl();
2487 docimpl->updateLayoutIgnorePendingStylesheets();
2490 case Selection::Collapse:
2491 TypingCommand::closeTyping(part->lastEditCommand());
2492 part->setSelection(khtml::Selection(Position(KJS::toNode(args[0]).handle(), args[1].toInt32(exec)), khtml::SEL_DEFAULT_AFFINITY));
2494 case Selection::CollapseToEnd:
2495 TypingCommand::closeTyping(part->lastEditCommand());
2496 part->setSelection(khtml::Selection(part->selection().end(), part->selection().endAffinity()));
2498 case Selection::CollapseToStart:
2499 TypingCommand::closeTyping(part->lastEditCommand());
2500 part->setSelection(khtml::Selection(part->selection().start(), part->selection().startAffinity()));
2502 case Selection::Empty:
2503 TypingCommand::closeTyping(part->lastEditCommand());
2504 part->clearSelection();
2506 case Selection::SetBaseAndExtent: {
2507 TypingCommand::closeTyping(part->lastEditCommand());
2508 Position base(KJS::toNode(args[0]).handle(), args[1].toInt32(exec));
2509 Position extent(KJS::toNode(args[2]).handle(), args[3].toInt32(exec));
2510 part->setSelection(khtml::Selection(base, khtml::SEL_DEFAULT_AFFINITY, extent, khtml::SEL_DEFAULT_AFFINITY));
2513 case Selection::SetPosition:
2514 TypingCommand::closeTyping(part->lastEditCommand());
2515 part->setSelection(khtml::Selection(Position(KJS::toNode(args[0]).handle(), args[1].toInt32(exec)), khtml::SEL_DEFAULT_AFFINITY));
2517 case Selection::Modify: {
2518 TypingCommand::closeTyping(part->lastEditCommand());
2519 khtml::Selection s(part->selection());
2520 khtml::Selection::EAlter alter = khtml::Selection::MOVE;
2521 if (args[0].toString(exec).string().lower() == "extend")
2522 alter = khtml::Selection::EXTEND;
2523 DOMString directionString = args[1].toString(exec).string().lower();
2524 khtml::Selection::EDirection direction = khtml::Selection::FORWARD;
2525 if (directionString == "backward")
2526 direction = khtml::Selection::BACKWARD;
2527 else if (directionString == "left")
2528 direction = khtml::Selection::LEFT;
2529 if (directionString == "right")
2530 direction = khtml::Selection::RIGHT;
2531 khtml::ETextGranularity granularity = khtml::CHARACTER;
2532 DOMString granularityString = args[2].toString(exec).string().lower();
2533 if (granularityString == "word")
2534 granularity = khtml::WORD;
2535 else if (granularityString == "line")
2536 granularity = khtml::LINE;
2537 else if (granularityString == "pargraph")
2538 granularity = khtml::PARAGRAPH;
2539 s.modify(alter, direction, granularity);
2540 part->setSelection(s);
2541 part->setSelectionGranularity(granularity);
2549 ////////////////////// BarInfo Object ////////////////////////
2551 const ClassInfo BarInfo::info = { "BarInfo", 0, 0, 0 };
2553 @begin BarInfoTable 1
2554 visible BarInfo::Visible DontDelete|ReadOnly
2557 BarInfo::BarInfo(ExecState *exec, KHTMLPart *p, Type barType)
2558 : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype())
2568 Value BarInfo::get(ExecState *exec, const Identifier &p) const
2570 if (m_part.isNull())
2573 const HashEntry *entry = Lookup::findEntry(&BarInfoTable, p);
2574 if (entry && entry->value == Visible) {
2578 return Boolean(KWQ(m_part)->locationbarVisible());
2582 return Boolean(KWQ(m_part)->locationbarVisible());
2586 return Boolean(KWQ(m_part)->personalbarVisible());
2590 return Boolean(KWQ(m_part)->scrollbarsVisible());
2594 return Boolean(KWQ(m_part)->statusbarVisible());
2598 return Boolean(KWQ(m_part)->toolbarVisible());
2601 return Boolean(false);
2608 void BarInfo::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
2612 ////////////////////// History Object ////////////////////////
2614 const ClassInfo History::info = { "History", 0, 0, 0 };
2616 @begin HistoryTable 4
2617 length History::Length DontDelete|ReadOnly
2618 back History::Back DontDelete|Function 0
2619 forward History::Forward DontDelete|Function 0
2620 go History::Go DontDelete|Function 1
2623 IMPLEMENT_PROTOFUNC(HistoryFunc)
2625 Value History::get(ExecState *exec, const Identifier &p) const
2627 return lookupGet<HistoryFunc,History,ObjectImp>(exec,p,&HistoryTable,this);
2630 Value History::getValueProperty(ExecState *, int token) const
2635 KParts::BrowserExtension *ext = part->browserExtension();
2639 KParts::BrowserInterface *iface = ext->browserInterface();
2643 QVariant length = iface->property( "historyLength" );
2645 if ( length.type() != QVariant::UInt )
2648 return Number( length.toUInt() );
2651 kdWarning() << "Unhandled token in History::getValueProperty : " << token << endl;
2656 UString History::toString(ExecState *exec) const
2658 return "[object History]";
2661 Value HistoryFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
2663 if (!thisObj.inherits(&History::info)) {
2664 Object err = Error::create(exec,TypeError);
2665 exec->setException(err);
2668 History *history = static_cast<History *>(thisObj.imp());
2675 case History::Forward:
2679 steps = args[0].toInt32(exec);
2685 history->part->scheduleHistoryNavigation(steps);
2689 /////////////////////////////////////////////////////////////////////////////
2693 const ClassInfo Konqueror::info = { "Konqueror", 0, 0, 0 };
2695 bool Konqueror::hasProperty(ExecState *exec, const Identifier &p) const
2697 if ( p.qstring().startsWith( "goHistory" ) ) return false;
2702 Value Konqueror::get(ExecState *exec, const Identifier &p) const
2704 if ( p == "goHistory" || part->url().protocol() != "http" || part->url().host() != "localhost" )
2707 KParts::BrowserExtension *ext = part->browserExtension();
2709 KParts::BrowserInterface *iface = ext->browserInterface();
2711 QVariant prop = iface->property( p.qstring().latin1() );
2713 if ( prop.isValid() ) {
2714 switch( prop.type() ) {
2716 return Number( prop.toInt() );
2717 case QVariant::String:
2718 return String( prop.toString() );
2726 return /*Function*/( new KonquerorFunc(this, p.qstring().latin1() ) );
2729 Value KonquerorFunc::tryCall(ExecState *exec, Object &, const List &args)
2731 KParts::BrowserExtension *ext = konqueror->part->browserExtension();
2736 KParts::BrowserInterface *iface = ext->browserInterface();
2741 QCString n = m_name.data();
2743 iface->callMethod( n.data(), QVariant() );
2748 UString Konqueror::toString(ExecState *) const
2750 return UString("[object Konqueror]");
2754 /////////////////////////////////////////////////////////////////////////////
2756 #include "kjs_window.moc"