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_position.h"
63 #include "html/html_documentimpl.h"
65 #include "misc/htmltags.h"
67 using DOM::DocumentImpl;
71 using khtml::TypingCommand;
77 ////////////////////// History Object ////////////////////////
79 class History : public ObjectImp {
80 friend class HistoryFunc;
82 History(ExecState *exec, KHTMLPart *p)
83 : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
84 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
85 Value getValueProperty(ExecState *exec, int token) const;
86 virtual const ClassInfo* classInfo() const { return &info; }
87 static const ClassInfo info;
88 enum { Back, Forward, Go, Length };
89 virtual UString toString(ExecState *exec) const;
91 QGuardedPtr<KHTMLPart> part;
94 class FrameArray : public ObjectImp {
96 FrameArray(ExecState *exec, KHTMLPart *p)
97 : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()), part(p) { }
98 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
99 virtual UString toString(ExecState *exec) const;
101 QGuardedPtr<KHTMLPart> part;
105 class KonquerorFunc : public DOMFunction {
107 KonquerorFunc(const Konqueror* k, const char* name)
108 : DOMFunction(), konqueror(k), m_name(name) { }
109 virtual Value tryCall(ExecState *exec, Object &thisObj, const List &args);
112 const Konqueror* konqueror;
118 #include "kjs_window.lut.h"
120 ////////////////////// Screen Object ////////////////////////
122 // table for screen object
125 height Screen::Height DontEnum|ReadOnly
126 width Screen::Width DontEnum|ReadOnly
127 colorDepth Screen::ColorDepth DontEnum|ReadOnly
128 pixelDepth Screen::PixelDepth DontEnum|ReadOnly
129 availLeft Screen::AvailLeft DontEnum|ReadOnly
130 availTop Screen::AvailTop DontEnum|ReadOnly
131 availHeight Screen::AvailHeight DontEnum|ReadOnly
132 availWidth Screen::AvailWidth DontEnum|ReadOnly
136 const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
138 // We set the object prototype so that toString is implemented
139 Screen::Screen(ExecState *exec)
140 : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype()) {}
142 Value Screen::get(ExecState *exec, const Identifier &p) const
145 kdDebug(6070) << "Screen::get " << p.qstring() << endl;
147 return lookupGetValue<Screen,ObjectImp>(exec,p,&ScreenTable,this);
150 Value Screen::getValueProperty(ExecState *exec, int token) const
153 QWidget *thisWidget = Window::retrieveActive(exec)->part()->view();
154 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(thisWidget));
158 return Number(sg.height());
160 return Number(sg.width());
163 QPaintDeviceMetrics m(QApplication::desktop());
164 return Number(m.depth());
167 QRect clipped = info.workArea().intersect(sg);
168 return Number(clipped.x()-sg.x());
171 QRect clipped = info.workArea().intersect(sg);
172 return Number(clipped.y()-sg.y());
175 QRect clipped = info.workArea().intersect(sg);
176 return Number(clipped.height());
179 QRect clipped = info.workArea().intersect(sg);
180 return Number(clipped.width());
183 kdWarning() << "Screen::getValueProperty unhandled token " << token << endl;
188 ////////////////////// Window Object ////////////////////////
190 const ClassInfo Window::info = { "Window", 0, &WindowTable, 0 };
193 @begin WindowTable 91
194 closed Window::Closed DontDelete|ReadOnly
195 crypto Window::Crypto DontDelete|ReadOnly
196 defaultStatus Window::DefaultStatus DontDelete
197 defaultstatus Window::DefaultStatus DontDelete
198 status Window::Status DontDelete
199 document Window::Document DontDelete|ReadOnly
200 Node Window::Node DontDelete
201 Event Window::EventCtor DontDelete
202 Range Window::Range DontDelete
203 NodeFilter Window::NodeFilter DontDelete
204 DOMException Window::DOMException DontDelete
205 CSSRule Window::CSSRule DontDelete
206 frames Window::Frames DontDelete|ReadOnly
207 history Window::_History DontDelete|ReadOnly
208 event Window::Event DontDelete
209 innerHeight Window::InnerHeight DontDelete|ReadOnly
210 innerWidth Window::InnerWidth DontDelete|ReadOnly
211 length Window::Length DontDelete|ReadOnly
212 location Window::_Location DontDelete
213 locationbar Window::Locationbar DontDelete
214 name Window::Name DontDelete
215 navigator Window::_Navigator DontDelete|ReadOnly
216 clientInformation Window::ClientInformation DontDelete|ReadOnly
217 konqueror Window::_Konqueror DontDelete|ReadOnly
218 menubar Window::Menubar DontDelete|ReadOnly
219 offscreenBuffering Window::OffscreenBuffering DontDelete|ReadOnly
220 opener Window::Opener DontDelete|ReadOnly
221 outerHeight Window::OuterHeight DontDelete|ReadOnly
222 outerWidth Window::OuterWidth DontDelete|ReadOnly
223 pageXOffset Window::PageXOffset DontDelete|ReadOnly
224 pageYOffset Window::PageYOffset DontDelete|ReadOnly
225 parent Window::Parent DontDelete|ReadOnly
226 personalbar Window::Personalbar DontDelete|ReadOnly
227 screenX Window::ScreenX DontDelete|ReadOnly
228 screenY Window::ScreenY DontDelete|ReadOnly
229 screenLeft Window::ScreenLeft DontDelete|ReadOnly
230 screenTop Window::ScreenTop DontDelete|ReadOnly
231 scrollbars Window::Scrollbars DontDelete|ReadOnly
232 statusbar Window::Statusbar DontDelete|ReadOnly
233 toolbar Window::Toolbar DontDelete|ReadOnly
234 scroll Window::Scroll DontDelete|Function 2
235 scrollBy Window::ScrollBy DontDelete|Function 2
236 scrollTo Window::ScrollTo DontDelete|Function 2
237 scrollX Window::ScrollX DontDelete|ReadOnly
238 scrollY Window::ScrollY DontDelete|ReadOnly
239 moveBy Window::MoveBy DontDelete|Function 2
240 moveTo Window::MoveTo DontDelete|Function 2
241 resizeBy Window::ResizeBy DontDelete|Function 2
242 resizeTo Window::ResizeTo DontDelete|Function 2
243 self Window::Self DontDelete|ReadOnly
244 window Window::_Window DontDelete|ReadOnly
245 top Window::Top DontDelete|ReadOnly
246 screen Window::_Screen DontDelete|ReadOnly
247 Image Window::Image DontDelete|ReadOnly
248 Option Window::Option DontDelete|ReadOnly
249 XMLHttpRequest Window::XMLHttpRequest DontDelete|ReadOnly
250 XMLSerializer Window::XMLSerializer DontDelete|ReadOnly
251 alert Window::Alert DontDelete|Function 1
252 confirm Window::Confirm DontDelete|Function 1
253 prompt Window::Prompt DontDelete|Function 2
254 open Window::Open DontDelete|Function 3
255 print Window::Print DontDelete|Function 2
256 setTimeout Window::SetTimeout DontDelete|Function 2
257 clearTimeout Window::ClearTimeout DontDelete|Function 1
258 focus Window::Focus DontDelete|Function 0
259 getSelection Window::GetSelection DontDelete|Function 0
260 blur Window::Blur DontDelete|Function 0
261 close Window::Close DontDelete|Function 0
262 setInterval Window::SetInterval DontDelete|Function 2
263 clearInterval Window::ClearInterval DontDelete|Function 1
264 captureEvents Window::CaptureEvents DontDelete|Function 0
265 releaseEvents Window::ReleaseEvents DontDelete|Function 0
266 # Warning, when adding a function to this object you need to add a case in Window::get
267 addEventListener Window::AddEventListener DontDelete|Function 3
268 removeEventListener Window::RemoveEventListener DontDelete|Function 3
269 onabort Window::Onabort DontDelete
270 onblur Window::Onblur DontDelete
271 onchange Window::Onchange DontDelete
272 onclick Window::Onclick DontDelete
273 ondblclick Window::Ondblclick DontDelete
274 ondragdrop Window::Ondragdrop DontDelete
275 onerror Window::Onerror DontDelete
276 onfocus Window::Onfocus DontDelete
277 onkeydown Window::Onkeydown DontDelete
278 onkeypress Window::Onkeypress DontDelete
279 onkeyup Window::Onkeyup DontDelete
280 onload Window::Onload DontDelete
281 onmousedown Window::Onmousedown DontDelete
282 onmousemove Window::Onmousemove DontDelete
283 onmouseout Window::Onmouseout DontDelete
284 onmouseover Window::Onmouseover DontDelete
285 onmouseup Window::Onmouseup DontDelete
286 onmove Window::Onmove DontDelete
287 onreset Window::Onreset DontDelete
288 onresize Window::Onresize DontDelete
289 onscroll Window::Onscroll DontDelete
290 onsearch Window::Onsearch DontDelete
291 onselect Window::Onselect DontDelete
292 onsubmit Window::Onsubmit DontDelete
293 onunload Window::Onunload DontDelete
296 IMPLEMENT_PROTOFUNC(WindowFunc)
298 Window::Window(KHTMLPart *p)
299 : ObjectImp(/*no proto*/)
314 winq = new WindowQObject(this);
315 //kdDebug(6070) << "Window::Window this=" << this << " part=" << m_part << " " << m_part->name() << endl;
320 kdDebug(6070) << "Window::~Window this=" << this << " part=" << m_part << endl;
324 KJS::Interpreter *Window::interpreter() const
326 return KJSProxy::proxy( m_part )->interpreter();
329 Window *Window::retrieveWindow(KHTMLPart *p)
331 Object obj = Object::dynamicCast( retrieve( p ) );
333 // obj should never be null, except when javascript has been disabled in that part.
334 if ( p && p->jScriptEnabled() )
336 assert( !obj.isNull() );
338 //assert( dynamic_cast<KJS::Window*>(obj.imp()) ); // type checking
342 if ( obj.isNull() ) // JS disabled
344 return static_cast<KJS::Window*>(obj.imp());
347 Window *Window::retrieveActive(ExecState *exec)
349 ValueImp *imp = exec->dynamicInterpreter()->globalObject().imp();
352 //assert( dynamic_cast<KJS::Window*>(imp) );
354 return static_cast<KJS::Window*>(imp);
357 Value Window::retrieve(KHTMLPart *p)
360 KJSProxy *proxy = KJSProxy::proxy( p );
363 kdDebug(6070) << "Window::retrieve part=" << p << " interpreter=" << proxy->interpreter() << " window=" << proxy->interpreter()->globalObject().imp() << endl;
365 return proxy->interpreter()->globalObject(); // the Global object is the "window"
367 return Undefined(); // This can happen with JS disabled on the domain of that window
370 Location *Window::location() const
373 const_cast<Window*>(this)->loc = new Location(m_part);
377 Selection *Window::selection() const
380 const_cast<Window*>(this)->m_selection = new Selection(m_part);
384 BarInfo *Window::locationbar(ExecState *exec) const
387 const_cast<Window*>(this)->m_locationbar = new BarInfo(exec, m_part, BarInfo::Locationbar);
388 return m_locationbar;
391 BarInfo *Window::menubar(ExecState *exec) const
394 const_cast<Window*>(this)->m_menubar = new BarInfo(exec, m_part, BarInfo::Menubar);
398 BarInfo *Window::personalbar(ExecState *exec) const
401 const_cast<Window*>(this)->m_personalbar = new BarInfo(exec, m_part, BarInfo::Personalbar);
402 return m_personalbar;
405 BarInfo *Window::statusbar(ExecState *exec) const
408 const_cast<Window*>(this)->m_statusbar = new BarInfo(exec, m_part, BarInfo::Statusbar);
412 BarInfo *Window::toolbar(ExecState *exec) const
415 const_cast<Window*>(this)->m_toolbar = new BarInfo(exec, m_part, BarInfo::Toolbar);
419 BarInfo *Window::scrollbars(ExecState *exec) const
422 const_cast<Window*>(this)->m_scrollbars = new BarInfo(exec, m_part, BarInfo::Scrollbars);
426 // reference our special objects during garbage collection
430 if (screen && !screen->marked())
432 if (history && !history->marked())
434 if (frames && !frames->marked())
436 //kdDebug(6070) << "Window::mark " << this << " marking loc=" << loc << endl;
437 if (loc && !loc->marked())
439 if (m_selection && !m_selection->marked())
441 if (m_locationbar && !m_locationbar->marked())
442 m_locationbar->mark();
443 if (m_menubar && !m_menubar->marked())
445 if (m_personalbar && !m_personalbar->marked())
446 m_personalbar->mark();
447 if (m_scrollbars && !m_scrollbars->marked())
448 m_scrollbars->mark();
449 if (m_statusbar && !m_statusbar->marked())
451 if (m_toolbar && !m_toolbar->marked())
455 UString Window::toString(ExecState *) const
457 return "[object Window]";
460 Value Window::get(ExecState *exec, const Identifier &p) const
463 kdDebug(6070) << "Window("<<this<<")::get " << p.qstring() << endl;
466 return Boolean(m_part.isNull());
468 // we don't want any properties other than "closed" on a closed window
472 // Look for overrides first
473 ValueImp * val = ObjectImp::getDirect(p);
475 //kdDebug(6070) << "Window::get found dynamic property '" << p.ascii() << "'" << endl;
476 if (isSafeScript(exec))
480 // Check for child frames by name before built-in properties to
481 // match behavior of other browsers.
482 KHTMLPart *childFrame = m_part->childFrameNamed(p.ustring().qstring());
484 return retrieve(childFrame);
486 const HashEntry* entry = Lookup::findEntry(&WindowTable, p);
489 //kdDebug(6070) << "token: " << entry->value << endl;
490 switch( entry->value ) {
492 return Undefined(); // ###
494 return String(UString(m_part->jsDefaultStatusBarText()));
496 return String(UString(m_part->jsStatusBarText()));
498 if (isSafeScript(exec))
500 if (m_part->document().isNull()) {
502 KWQ(m_part)->createEmptyDocument();
504 kdDebug(6070) << "Document.write: adding <HTML><BODY> to create document" << endl;
506 m_part->write("<HTML><BODY>");
509 Value val = getDOMNode(exec,m_part->document());
515 return getNodeConstructor(exec);
517 return getRangeConstructor(exec);
519 return getNodeFilterConstructor(exec);
521 return getDOMExceptionConstructor(exec);
523 return getCSSRuleConstructor(exec);
525 return getEventConstructor(exec);
527 return Value(frames ? frames :
528 (const_cast<Window*>(this)->frames = new FrameArray(exec,m_part)));
530 return Value(history ? history :
531 (const_cast<Window*>(this)->history = new History(exec,m_part)));
535 return getDOMEvent(exec,*m_evt);
538 kdWarning(6070) << "window(" << this << "," << m_part->name() << ").event, no event!" << endl;
546 return Number(m_part->view()->visibleHeight());
551 return Number(m_part->view()->visibleWidth());
553 return Number(m_part->frames().count());
555 return Value(location());
557 return String(m_part->name());
559 case ClientInformation: {
560 // Store the navigator in the object so we get the same one each time.
561 Navigator *n = new Navigator(exec, m_part);
562 const_cast<Window *>(this)->putDirect("navigator", n, DontDelete|ReadOnly);
563 const_cast<Window *>(this)->putDirect("clientInformation", n, DontDelete|ReadOnly);
568 return Value(new Konqueror(m_part));
571 return Value(locationbar(exec));
573 return Value(menubar(exec));
574 case OffscreenBuffering:
575 return Boolean(true);
577 if (!m_part->opener())
578 return Null(); // ### a null Window might be better, but == null
579 else // doesn't work yet
580 return retrieve(m_part->opener());
586 KWin::Info inf = KWin::info(m_part->view()->topLevelWidget()->winId());
587 return Number(entry->value == OuterHeight ?
588 inf.geometry.height() : inf.geometry.width());
594 return Number(m_part->view()->contentsX());
599 return Number(m_part->view()->contentsY());
601 return Value(retrieve(m_part->parentPart() ? m_part->parentPart() : (KHTMLPart*)m_part));
603 return Value(personalbar(exec));
609 // We want to use frameGeometry here instead of mapToGlobal because it goes through
610 // the windowFrame method of the WebKit's UI delegate. Also we don't want to try
611 // to do anything relative to the screen the window is on, so the code below is no
612 // good of us anyway.
613 return Number(m_part->view()->topLevelWidget()->frameGeometry().x());
615 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
616 return Number(m_part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
624 // See comment above in ScreenX.
625 return Number(m_part->view()->topLevelWidget()->frameGeometry().y());
627 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
628 return Number(m_part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
635 return Number(m_part->view()->contentsX());
641 return Number(m_part->view()->contentsY());
644 return Value(scrollbars(exec));
646 return Value(statusbar(exec));
648 return Value(toolbar(exec));
651 return Value(retrieve(m_part));
653 KHTMLPart *p = m_part;
654 while (p->parentPart())
656 return Value(retrieve(p));
659 return Value(screen ? screen :
660 (const_cast<Window*>(this)->screen = new Screen(exec)));
662 return Value(new ImageConstructorImp(exec, m_part->document()));
664 return Value(new OptionConstructorImp(exec, m_part->document()));
666 return Value(new XMLHttpRequestConstructorImp(exec, m_part->document()));
668 return Value(new XMLSerializerConstructorImp(exec));
672 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
680 case Scroll: // compatibility
689 case AddEventListener:
690 case RemoveEventListener:
696 if (isSafeScript(exec))
697 return lookupOrCreateFunction<WindowFunc>(exec,p,this,entry->value,entry->params,entry->attr);
701 if (isSafeScript(exec))
702 return getListener(exec,DOM::EventImpl::ABORT_EVENT);
706 if (isSafeScript(exec))
707 return getListener(exec,DOM::EventImpl::BLUR_EVENT);
711 if (isSafeScript(exec))
712 return getListener(exec,DOM::EventImpl::CHANGE_EVENT);
716 if (isSafeScript(exec))
717 return getListener(exec,DOM::EventImpl::KHTML_CLICK_EVENT);
721 if (isSafeScript(exec))
722 return getListener(exec,DOM::EventImpl::KHTML_DBLCLICK_EVENT);
726 if (isSafeScript(exec))
727 return getListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT);
731 if (isSafeScript(exec))
732 return getListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT);
736 if (isSafeScript(exec))
737 return getListener(exec,DOM::EventImpl::FOCUS_EVENT);
741 if (isSafeScript(exec))
742 return getListener(exec,DOM::EventImpl::KEYDOWN_EVENT);
746 if (isSafeScript(exec))
747 return getListener(exec,DOM::EventImpl::KEYPRESS_EVENT);
751 if (isSafeScript(exec))
752 return getListener(exec,DOM::EventImpl::KEYUP_EVENT);
756 if (isSafeScript(exec))
757 return getListener(exec,DOM::EventImpl::LOAD_EVENT);
761 if (isSafeScript(exec))
762 return getListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT);
766 if (isSafeScript(exec))
767 return getListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT);
771 if (isSafeScript(exec))
772 return getListener(exec,DOM::EventImpl::MOUSEOUT_EVENT);
776 if (isSafeScript(exec))
777 return getListener(exec,DOM::EventImpl::MOUSEOVER_EVENT);
781 if (isSafeScript(exec))
782 return getListener(exec,DOM::EventImpl::MOUSEUP_EVENT);
786 if (isSafeScript(exec))
787 return getListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT);
791 if (isSafeScript(exec))
792 return getListener(exec,DOM::EventImpl::RESET_EVENT);
796 if (isSafeScript(exec))
797 return getListener(exec,DOM::EventImpl::RESIZE_EVENT);
801 if (isSafeScript(exec))
802 return getListener(exec,DOM::EventImpl::SCROLL_EVENT);
807 if (isSafeScript(exec))
808 return getListener(exec,DOM::EventImpl::SEARCH_EVENT);
813 if (isSafeScript(exec))
814 return getListener(exec,DOM::EventImpl::SELECT_EVENT);
818 if (isSafeScript(exec))
819 return getListener(exec,DOM::EventImpl::SUBMIT_EVENT);
823 if (isSafeScript(exec))
824 return getListener(exec,DOM::EventImpl::UNLOAD_EVENT);
830 KHTMLPart *kp = m_part->findFrame( p.qstring() );
832 return Value(retrieve(kp));
834 // allow window[1] or parent[1] etc. (#56983)
836 unsigned int i = p.toArrayIndex(&ok);
838 QPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
839 unsigned int len = frames.count();
841 KParts::ReadOnlyPart* frame = frames.at(i);
842 if (frame && frame->inherits("KHTMLPart")) {
843 KHTMLPart *khtml = static_cast<KHTMLPart*>(frame);
844 return Window::retrieve(khtml);
849 // allow shortcuts like 'Image1' instead of document.images.Image1
850 if (isSafeScript(exec) &&
851 m_part->document().isHTMLDocument()) { // might be XML
852 DOM::HTMLCollection coll = m_part->htmlDocument().all();
853 DOM::HTMLElement element = coll.namedItem(p.string());
854 if (!element.isNull()) {
856 Value domValue = getDOMNode(exec,element);
857 ObjectImp *imp = static_cast<ObjectImp *>(domValue.imp());
858 if (!imp->forwardingScriptMessage() &&
859 (element.handle()->id() == ID_APPLET || element.handle()->id() == ID_EMBED || element.handle()->id() == ID_OBJECT)) {
860 Value v = getRuntimeObject(exec,element,domValue);
866 return getDOMNode(exec,element);
871 // This isn't necessarily a bug. Some code uses if(!window.blah) window.blah=1
872 // But it can also mean something isn't loaded or implemented, hence the WARNING to help grepping.
874 kdDebug(6070) << "WARNING: Window::get property not found: " << p.qstring() << endl;
877 if (isSafeScript(exec))
878 return ObjectImp::get(exec, p);
883 bool Window::hasProperty(ExecState *exec, const Identifier &p) const
885 // matches logic in get function above, but no need to handle numeric values (frame indices)
888 return p == "closed";
893 if (Lookup::findEntry(&WindowTable, p))
896 if (m_part->findFrame(p.qstring()))
899 if (!m_part->htmlDocument().all().namedItem(p.string()).isNull())
905 void Window::put(ExecState* exec, const Identifier &propertyName, const Value &value, int attr)
907 // Called by an internal KJS call (e.g. InterpreterImp's constructor) ?
908 // If yes, save time and jump directly to ObjectImp.
909 if ( (attr != None && attr != DontDelete)
910 // Same thing if we have a local override (e.g. "var location")
911 || ( ObjectImp::getDirect(propertyName) && isSafeScript(exec)) )
913 ObjectImp::put( exec, propertyName, value, attr );
917 const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
921 kdDebug(6070) << "Window("<<this<<")::put " << propertyName.qstring() << endl;
923 switch( entry->value ) {
925 String s = value.toString(exec);
926 m_part->setJSStatusBarText(s.value().qstring());
929 case DefaultStatus: {
930 String s = value.toString(exec);
931 m_part->setJSDefaultStatusBarText(s.value().qstring());
935 KHTMLPart* p = Window::retrieveActive(exec)->m_part;
937 QString dstUrl = p->htmlDocument().completeURL(value.toString(exec).string()).string();
938 if (!dstUrl.startsWith("javascript:", false) || isSafeScript(exec))
940 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
942 // We want a new history item if this JS was called via a user gesture
943 m_part->scheduleLocationChange(dstUrl, !userGesture, userGesture);
945 m_part->scheduleLocationChange(dstUrl, false /*don't lock history*/, userGesture);
952 if (isSafeScript(exec))
953 setListener(exec, DOM::EventImpl::ABORT_EVENT,value);
956 if (isSafeScript(exec))
957 setListener(exec, DOM::EventImpl::BLUR_EVENT,value);
960 if (isSafeScript(exec))
961 setListener(exec, DOM::EventImpl::CHANGE_EVENT,value);
964 if (isSafeScript(exec))
965 setListener(exec,DOM::EventImpl::KHTML_CLICK_EVENT,value);
968 if (isSafeScript(exec))
969 setListener(exec,DOM::EventImpl::KHTML_DBLCLICK_EVENT,value);
972 if (isSafeScript(exec))
973 setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
976 if (isSafeScript(exec))
977 setListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT,value);
980 if (isSafeScript(exec))
981 setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
984 if (isSafeScript(exec))
985 setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
988 if (isSafeScript(exec))
989 setListener(exec,DOM::EventImpl::KEYPRESS_EVENT,value);
992 if (isSafeScript(exec))
993 setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
996 if (isSafeScript(exec))
997 setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
1000 if (isSafeScript(exec))
1001 setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
1004 if (isSafeScript(exec))
1005 setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
1008 if (isSafeScript(exec))
1009 setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
1012 if (isSafeScript(exec))
1013 setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
1016 if (isSafeScript(exec))
1017 setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
1020 if (isSafeScript(exec))
1021 setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
1024 if (isSafeScript(exec))
1025 setListener(exec,DOM::EventImpl::RESET_EVENT,value);
1028 if (isSafeScript(exec))
1029 setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
1032 if (isSafeScript(exec))
1033 setListener(exec,DOM::EventImpl::SCROLL_EVENT,value);
1037 if (isSafeScript(exec))
1038 setListener(exec,DOM::EventImpl::SEARCH_EVENT,value);
1042 if (isSafeScript(exec))
1043 setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
1046 if (isSafeScript(exec))
1047 setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
1050 if (isSafeScript(exec))
1051 setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
1054 if (isSafeScript(exec))
1056 m_part->setName( value.toString(exec).qstring() );
1058 m_part->setName( value.toString(exec).qstring().local8Bit().data() );
1065 if (isSafeScript(exec)) {
1066 //kdDebug(6070) << "Window("<<this<<")::put storing " << propertyName.qstring() << endl;
1067 ObjectImp::put(exec, propertyName, value, attr);
1071 bool Window::toBoolean(ExecState *) const
1073 return !m_part.isNull();
1076 int Window::installTimeout(const UString &handler, int t, bool singleShot)
1078 return winq->installTimeout(handler, t, singleShot);
1081 int Window::installTimeout(const Value &function, List &args, int t, bool singleShot)
1083 return winq->installTimeout(function, args, t, singleShot);
1086 void Window::clearTimeout(int timerId)
1088 winq->clearTimeout(timerId);
1092 bool Window::hasTimeouts()
1094 return winq->hasTimeouts();
1097 QMap<int, ScheduledAction*> *Window::pauseTimeouts(const void *key)
1099 return winq->pauseTimeouts(key);
1102 void Window::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
1104 return winq->resumeTimeouts(sa, key);
1108 void Window::scheduleClose()
1110 kdDebug(6070) << "Window::scheduleClose window.close() " << m_part << endl;
1113 KWQ(m_part)->scheduleClose();
1115 QTimer::singleShot( 0, winq, SLOT( timeoutClose() ) );
1119 static bool shouldLoadAsEmptyDocument(const KURL &url)
1121 return url.protocol().lower() == "about" || url.isEmpty();
1124 bool Window::isSafeScript (const KJS::ScriptInterpreter *origin, const KJS::ScriptInterpreter *target)
1126 if (origin == target)
1129 KHTMLPart *originPart = origin->part();
1130 KHTMLPart *targetPart = target->part();
1132 // JS may be attempting to access the "window" object, which should be valid,
1133 // even if the document hasn't been constructed yet. If the document doesn't
1134 // exist yet allow JS to access the window object.
1135 if (!targetPart->xmlDocImpl())
1138 DOM::DocumentImpl *originDocument = originPart->xmlDocImpl();
1139 DOM::DocumentImpl *targetDocument = targetPart->xmlDocImpl();
1141 if (!targetDocument) {
1145 DOM::DOMString targetDomain = targetDocument->domain();
1147 // Always allow local pages to execute any JS.
1148 if (targetDomain.isNull())
1151 DOM::DOMString originDomain = originDocument->domain();
1153 // if this document is being initially loaded as empty by its parent
1154 // or opener, allow access from any document in the same domain as
1155 // the parent or opener.
1156 if (shouldLoadAsEmptyDocument(targetPart->url())) {
1157 KHTMLPart *ancestorPart = targetPart->opener() ? targetPart->opener() : targetPart->parentPart();
1158 while (ancestorPart && shouldLoadAsEmptyDocument(ancestorPart->url())) {
1159 ancestorPart = ancestorPart->parentPart();
1163 originDomain = ancestorPart->xmlDocImpl()->domain();
1166 if ( targetDomain == originDomain )
1169 if (Interpreter::shouldPrintExceptions()) {
1170 printf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1171 targetDocument->URL().latin1(), originDocument->URL().latin1());
1173 message.sprintf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1174 targetDocument->URL().latin1(), originDocument->URL().latin1());
1175 KWQ(targetPart)->addMessageToConsole(message, 1, QString()); //fixme: provide a real line number and sourceurl
1181 bool Window::isSafeScript(ExecState *exec) const
1183 if (m_part.isNull()) { // part deleted ? can't grant access
1184 kdDebug(6070) << "Window::isSafeScript: accessing deleted part !" << endl;
1187 KHTMLPart *activePart = static_cast<KJS::ScriptInterpreter *>( exec->dynamicInterpreter() )->part();
1189 kdDebug(6070) << "Window::isSafeScript: current interpreter's part is 0L!" << endl;
1192 if ( activePart == m_part ) // Not calling from another frame, no problem.
1195 // JS may be attempting to access the "window" object, which should be valid,
1196 // even if the document hasn't been constructed yet. If the document doesn't
1197 // exist yet allow JS to access the window object.
1198 if (!m_part->xmlDocImpl())
1201 DOM::DocumentImpl* thisDocument = m_part->xmlDocImpl();
1202 DOM::DocumentImpl* actDocument = activePart->xmlDocImpl();
1205 kdDebug(6070) << "Window::isSafeScript: active part has no document!" << endl;
1209 DOM::DOMString actDomain = actDocument->domain();
1211 // Always allow local pages to execute any JS.
1212 if (actDomain.isNull())
1215 DOM::DOMString thisDomain = thisDocument->domain();
1217 // if this document is being initially loaded as empty by its parent
1218 // or opener, allow access from any document in the same domain as
1219 // the parent or opener.
1220 if (shouldLoadAsEmptyDocument(m_part->url())) {
1221 KHTMLPart *ancestorPart = m_part->opener() ? m_part->opener() : m_part->parentPart();
1222 while (ancestorPart && shouldLoadAsEmptyDocument(ancestorPart->url())) {
1223 ancestorPart = ancestorPart->parentPart();
1227 thisDomain = ancestorPart->xmlDocImpl()->domain();
1230 //kdDebug(6070) << "current domain:" << actDomain.string() << ", frame domain:" << thisDomain.string() << endl;
1231 if ( actDomain == thisDomain )
1235 if (Interpreter::shouldPrintExceptions()) {
1236 printf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1237 thisDocument->URL().latin1(), actDocument->URL().latin1());
1239 message.sprintf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1240 thisDocument->URL().latin1(), actDocument->URL().latin1());
1241 KWQ(m_part)->addMessageToConsole(message, 1, QString()); //fixme: provide a real line number and sourceurl
1245 kdWarning(6070) << "Javascript: access denied for current frame '" << actDomain.string() << "' to frame '" << thisDomain.string() << "'" << endl;
1249 void Window::setListener(ExecState *exec, int eventId, Value func)
1251 if (!isSafeScript(exec))
1253 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(m_part->htmlDocument().handle());
1257 doc->setHTMLWindowEventListener(eventId,getJSEventListener(func,true));
1260 Value Window::getListener(ExecState *exec, int eventId) const
1262 if (!isSafeScript(exec))
1264 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(m_part->htmlDocument().handle());
1268 DOM::EventListener *listener = doc->getHTMLWindowEventListener(eventId);
1269 if (listener && static_cast<JSEventListener*>(listener)->listenerObjImp())
1270 return static_cast<JSEventListener*>(listener)->listenerObj();
1276 JSEventListener *Window::getJSEventListener(const Value& val, bool html)
1278 // This function is so hot that it's worth coding it directly with imps.
1279 if (val.type() != ObjectType)
1281 ObjectImp *listenerObject = static_cast<ObjectImp *>(val.imp());
1283 JSEventListener *existingListener = jsEventListeners[listenerObject];
1284 if (existingListener)
1285 return existingListener;
1287 // Note that the JSEventListener constructor adds it to our jsEventListeners list
1288 return new JSEventListener(Object(listenerObject), Object(this), html);
1291 JSLazyEventListener *Window::getJSLazyEventListener(const QString& code, bool html, int lineNumber)
1293 return new JSLazyEventListener(code, Object(this), html, lineNumber);
1296 void Window::clear( ExecState *exec )
1298 KJS::Interpreter::lock();
1299 kdDebug(6070) << "Window::clear " << this << endl;
1301 winq = new WindowQObject(this);;
1302 // Get rid of everything, those user vars could hold references to DOM nodes
1303 deleteAllProperties( exec );
1304 // Really delete those properties, so that the DOM nodes get deref'ed
1305 KJS::Collector::collect();
1306 // Now recreate a working global object for the next URL that will use us
1307 KJS::Interpreter *interpreter = KJSProxy::proxy( m_part )->interpreter();
1308 interpreter->initGlobalObject();
1309 KJS::Interpreter::unlock();
1312 void Window::setCurrentEvent( DOM::Event *evt )
1315 //kdDebug(6070) << "Window " << this << " (part=" << m_part << ")::setCurrentEvent m_evt=" << evt << endl;
1318 Value WindowFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
1320 if (!thisObj.inherits(&Window::info)) {
1321 Object err = Error::create(exec,TypeError);
1322 exec->setException(err);
1325 Window *window = static_cast<Window *>(thisObj.imp());
1328 KHTMLPart *part = window->m_part;
1332 KHTMLView *widget = part->view();
1334 UString s = v.toString(exec);
1339 if (part && part->xmlDocImpl())
1340 part->xmlDocImpl()->updateRendering();
1342 KWQ(part)->runJavaScriptAlert(str);
1344 KMessageBox::error(widget, QStyleSheet::convertFromPlainText(str), "JavaScript");
1347 case Window::Confirm:
1348 if (part && part->xmlDocImpl())
1349 part->xmlDocImpl()->updateRendering();
1351 return Boolean(KWQ(part)->runJavaScriptConfirm(str));
1353 return Boolean((KMessageBox::warningYesNo(widget, QStyleSheet::convertFromPlainText(str), "JavaScript",
1354 i18n("OK"), i18n("Cancel")) == KMessageBox::Yes));
1356 case Window::Prompt:
1357 if (part && part->xmlDocImpl())
1358 part->xmlDocImpl()->updateRendering();
1361 ok = KWQ(part)->runJavaScriptPrompt(str, args.size() >= 2 ? args[1].toString(exec).qstring() : QString::null, str2);
1363 if (args.size() >= 2)
1364 str2 = QInputDialog::getText(i18n("Konqueror: Prompt"),
1365 QStyleSheet::convertFromPlainText(str),
1367 args[1].toString(exec).qstring(), &ok);
1369 str2 = QInputDialog::getText(i18n("Konqueror: Prompt"),
1370 QStyleSheet::convertFromPlainText(str),
1372 QString::null, &ok);
1375 return String(str2);
1380 KConfig *config = new KConfig("konquerorrc");
1381 config->setGroup("Java/JavaScript Settings");
1383 int policy = config->readUnsignedNumEntry( "WindowOpenPolicy", 0 ); // 0=allow, 1=ask, 2=deny, 3=smart
1385 int policy = config->readUnsignedNumEntry( part->settings(), "WindowOpenPolicy", 0 ); // 0=allow, 1=ask, 2=deny, 3=smart
1388 if ( policy == 1 ) {
1390 if ( KMessageBox::questionYesNo(widget,
1391 i18n( "This site is trying to open up a new browser "
1392 "window using Javascript.\n"
1393 "Do you want to allow this?" ),
1394 i18n( "Confirmation: Javascript Popup" ) ) == KMessageBox::Yes )
1397 } else if ( policy == 3 ) // smart
1399 // window.open disabled unless from a key/mouse event
1400 if (static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture())
1406 LOG(PopupBlocking, "Allowed JavaScript window open of %s", args[0].toString(exec).qstring().ascii());
1408 LOG(PopupBlocking, "Blocked JavaScript window open of %s", args[0].toString(exec).qstring().ascii());
1413 QString frameName = !args[1].isNull() && args[1].type() != UndefinedType ?
1414 args[1].toString(exec).qstring()
1415 : QString("_blank");
1417 if ( policy != 0 && !(part->findFrame(frameName) || frameName == "_top" || frameName == "_parent" || frameName == "_self")) {
1420 if (v.type() == UndefinedType)
1423 KParts::WindowArgs winargs;
1425 // scan feature argument
1428 if (!v.isNull() && v.type() != UndefinedType && v.toString(exec).size() > 0) {
1429 features = v.toString(exec).qstring();
1430 // specifying window params means false defaults
1431 winargs.menuBarVisible = false;
1432 winargs.toolBarsVisible = false;
1433 winargs.statusBarVisible = false;
1435 winargs.scrollbarsVisible = true;
1437 QStringList flist = QStringList::split(',', features);
1438 QStringList::ConstIterator it = flist.begin();
1439 while (it != flist.end()) {
1442 int pos = s.find('=');
1444 key = s.left(pos).stripWhiteSpace().lower();
1445 val = s.mid(pos + 1).stripWhiteSpace().lower();
1446 int spacePos = val.find(' ');
1447 if (spacePos != -1) {
1448 val = val.left(spacePos);
1451 int scnum = QApplication::desktop()->screenNumber(widget->topLevelWidget());
1453 QRect screen = QApplication::desktop()->screenGeometry(scnum);
1454 if (key == "left" || key == "screenx") {
1456 double d = val.toDouble(&ok);
1459 if (d < screen.x() || d > screen.right())
1460 d = screen.x(); // only safe choice until size is determined
1463 winargs.xSet = true;
1466 } else if (key == "top" || key == "screeny") {
1468 double d = val.toDouble(&ok);
1471 if (d < screen.y() || d > screen.bottom())
1472 d = screen.y(); // only safe choice until size is determined
1475 winargs.ySet = true;
1478 } else if (key == "height") {
1480 double d = val.toDouble(&ok);
1483 d += 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
1485 if (d > screen.height()) // should actually check workspace
1486 d = screen.height();
1489 winargs.height = (int)d;
1491 winargs.heightSet = true;
1494 } else if (key == "width") {
1496 double d = val.toDouble(&ok);
1499 d += 2*qApp->style().pixelMetric( QStyle::PM_DefaultFrameWidth ) + 2;
1501 if (d > screen.width()) // should actually check workspace
1505 winargs.width = (int)d;
1507 winargs.widthSet = true;
1515 // leaving away the value gives true
1516 key = s.stripWhiteSpace().lower();
1520 if (key == "menubar")
1521 winargs.menuBarVisible = (val == "1" || val == "yes");
1522 else if (key == "toolbar")
1523 winargs.toolBarsVisible = (val == "1" || val == "yes");
1524 else if (key == "location") // ### missing in WindowArgs
1525 winargs.toolBarsVisible = (val == "1" || val == "yes");
1526 else if (key == "status" || key == "statusbar")
1527 winargs.statusBarVisible = (val == "1" || val == "yes");
1528 else if (key == "resizable")
1529 winargs.resizable = (val == "1" || val == "yes");
1530 else if (key == "fullscreen")
1531 winargs.fullscreen = (val == "1" || val == "yes");
1533 else if (key == "scrollbars")
1534 winargs.scrollbarsVisible = !(val == "0" || val == "no");
1539 // prepare arguments
1543 KHTMLPart* p = Window::retrieveActive(exec)->m_part;
1545 url = p->htmlDocument().completeURL(str).string();
1548 KParts::URLArgs uargs;
1549 uargs.frameName = frameName;
1550 if ( uargs.frameName == "_top" )
1553 while ( part->parentPart() )
1554 part = part->parentPart();
1556 const Window* window = Window::retrieveWindow(part);
1557 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
1558 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1559 part->scheduleLocationChange(url.url(), false/*don't lock history*/, userGesture);
1561 return Window::retrieve(part);
1563 if ( uargs.frameName == "_parent" )
1566 if ( part->parentPart() )
1567 part = part->parentPart();
1569 const Window* window = Window::retrieveWindow(part);
1570 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
1571 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1572 part->scheduleLocationChange(url.url(), false/*don't lock history*/, userGesture);
1574 return Window::retrieve(part);
1576 uargs.serviceType = "text/html";
1578 // request window (new or existing if framename is set)
1579 KParts::ReadOnlyPart *newPart = 0L;
1580 emit part->browserExtension()->createNewWindow("", uargs,winargs,newPart);
1581 if (newPart && newPart->inherits("KHTMLPart")) {
1582 KHTMLPart *khtmlpart = static_cast<KHTMLPart*>(newPart);
1583 //qDebug("opener set to %p (this Window's part) in new Window %p (this Window=%p)",part,win,window);
1584 khtmlpart->setOpener(part);
1585 khtmlpart->setOpenedByJS(true);
1587 if (khtmlpart->document().isNull()) {
1588 DocumentImpl *oldDoc = part->xmlDocImpl();
1589 if (oldDoc && oldDoc->baseURL() != 0)
1590 khtmlpart->begin(oldDoc->baseURL());
1594 khtmlpart->write("<HTML><BODY>");
1598 kdDebug(6070) << "Setting domain to " << oldDoc->domain().string() << endl;
1599 khtmlpart->xmlDocImpl()->setDomain( oldDoc->domain(), true );
1600 khtmlpart->xmlDocImpl()->setBaseURL( oldDoc->baseURL() );
1604 if (!url.isEmpty()) {
1605 const Window* window = Window::retrieveWindow(khtmlpart);
1606 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
1607 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1608 // FIXME: Need to pass referrer here.
1609 khtmlpart->scheduleLocationChange(url.url(), false, userGesture);
1613 uargs.serviceType = QString::null;
1614 if (uargs.frameName == "_blank")
1615 uargs.frameName = QString::null;
1617 // FIXME: need to pass referrer here
1618 emit khtmlpart->browserExtension()->openURLRequest(url,uargs);
1620 return Window::retrieve(khtmlpart); // global object
1630 case Window::ScrollBy:
1631 window->updateLayout();
1632 if(args.size() >= 2 && widget)
1633 widget->scrollBy(args[0].toInt32(exec), args[1].toInt32(exec));
1635 case Window::Scroll:
1636 case Window::ScrollTo:
1637 window->updateLayout();
1638 if(args.size() >= 2 && widget)
1639 widget->setContentsPos(args[0].toInt32(exec), args[1].toInt32(exec));
1641 case Window::MoveBy:
1642 if(args.size() >= 2 && widget)
1644 QWidget * tl = widget->topLevelWidget();
1645 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1646 QPoint dest = tl->pos() + QPoint( args[0].toInt32(exec), args[1].toInt32(exec) );
1647 // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
1648 if ( dest.x() >= sg.x() && dest.y() >= sg.x() &&
1649 dest.x()+tl->width() <= sg.width()+sg.x() &&
1650 dest.y()+tl->height() <= sg.height()+sg.y() )
1654 case Window::MoveTo:
1655 if(args.size() >= 2 && widget)
1657 QWidget * tl = widget->topLevelWidget();
1658 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1659 QPoint dest( args[0].toInt32(exec)+sg.x(), args[1].toInt32(exec)+sg.y() );
1660 // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
1661 if ( dest.x() >= sg.x() && dest.y() >= sg.y() &&
1662 dest.x()+tl->width() <= sg.width()+sg.x() &&
1663 dest.y()+tl->height() <= sg.height()+sg.y() )
1667 case Window::ResizeBy:
1668 if(args.size() >= 2 && widget)
1670 QWidget * tl = widget->topLevelWidget();
1671 QSize dest = tl->size() + QSize( args[0].toInt32(exec), args[1].toInt32(exec) );
1672 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1673 // Security check: within desktop limits and bigger than 100x100 (per spec)
1674 if ( tl->x()+dest.width() <= sg.x()+sg.width() &&
1675 tl->y()+dest.height() <= sg.y()+sg.height() &&
1676 dest.width() >= 100 && dest.height() >= 100 )
1678 // Take into account the window frame
1679 int deltaWidth = tl->frameGeometry().width() - tl->width();
1680 int deltaHeight = tl->frameGeometry().height() - tl->height();
1681 tl->resize( dest.width() - deltaWidth, dest.height() - deltaHeight );
1685 case Window::ResizeTo:
1686 if(args.size() >= 2 && widget)
1688 QWidget * tl = widget->topLevelWidget();
1689 QSize dest = QSize( args[0].toInt32(exec), args[1].toInt32(exec) );
1690 QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(tl));
1691 // Security check: within desktop limits and bigger than 100x100 (per spec)
1692 if ( tl->x()+dest.width() <= sg.x()+sg.width() &&
1693 tl->y()+dest.height() <= sg.y()+sg.height() &&
1694 dest.width() >= 100 && dest.height() >= 100 )
1696 // Take into account the window frame
1697 int deltaWidth = tl->frameGeometry().width() - tl->width();
1698 int deltaHeight = tl->frameGeometry().height() - tl->height();
1699 tl->resize( dest.width() - deltaWidth, dest.height() - deltaHeight );
1703 case Window::SetTimeout:
1704 if (!window->isSafeScript(exec))
1706 if (args.size() >= 2 && v.isA(StringType)) {
1707 int i = args[1].toInt32(exec);
1708 int r = (const_cast<Window*>(window))->installTimeout(s, i, true /*single shot*/);
1711 else if (args.size() >= 2 && v.isA(ObjectType) && Object::dynamicCast(v).implementsCall()) {
1712 Value func = args[0];
1713 int i = args[1].toInt32(exec);
1715 // All arguments after the second should go to the function
1716 // FIXME: could be more efficient
1717 List funcArgs = args.copyTail().copyTail();
1719 int r = (const_cast<Window*>(window))->installTimeout(func, funcArgs, i, true /*single shot*/);
1724 case Window::SetInterval:
1725 if (!window->isSafeScript(exec))
1727 if (args.size() >= 2 && v.isA(StringType)) {
1728 int i = args[1].toInt32(exec);
1729 int r = (const_cast<Window*>(window))->installTimeout(s, i, false);
1732 else if (args.size() >= 2 && !Object::dynamicCast(v).isNull() &&
1733 Object::dynamicCast(v).implementsCall()) {
1734 Value func = args[0];
1735 int i = args[1].toInt32(exec);
1737 // All arguments after the second should go to the function
1738 // FIXME: could be more efficient
1739 List funcArgs = args.copyTail().copyTail();
1741 int r = (const_cast<Window*>(window))->installTimeout(func, funcArgs, i, false);
1746 case Window::ClearTimeout:
1747 case Window::ClearInterval:
1748 if (!window->isSafeScript(exec))
1750 (const_cast<Window*>(window))->clearTimeout(v.toInt32(exec));
1754 widget->setActiveWindow();
1756 case Window::GetSelection:
1757 if (!window->isSafeScript(exec))
1759 return Value(window->selection());
1762 KWQ(part)->unfocusWindow();
1768 /* From http://developer.netscape.com/docs/manuals/js/client/jsref/window.htm :
1769 The close method closes only windows opened by JavaScript using the open method.
1770 If you attempt to close any other window, a confirm is generated, which
1771 lets the user choose whether the window closes.
1772 This is a security feature to prevent "mail bombs" containing self.close().
1773 However, if the window has only one document (the current one) in its
1774 session history, the close is allowed without any confirm. This is a
1775 special case for one-off windows that need to open other windows and
1776 then dispose of themselves.
1778 if (!part->openedByJS())
1780 // To conform to the SPEC, we only ask if the window
1781 // has more than one entry in the history (NS does that too).
1782 History history(exec,part);
1783 if ( history.get( exec, lengthPropertyName ).toInt32(exec) <= 1
1785 // FIXME: How are we going to handle this?
1787 || KMessageBox::questionYesNo( window->part()->view(), i18n("Close window?"), i18n("Confirmation Required") ) == KMessageBox::Yes
1790 (const_cast<Window*>(window))->scheduleClose();
1794 (const_cast<Window*>(window))->scheduleClose();
1797 case Window::CaptureEvents:
1798 case Window::ReleaseEvents:
1799 // If anyone implements these, they need the safescript security check.
1800 if (!window->isSafeScript(exec))
1803 // Do nothing for now. These are NS-specific legacy calls.
1805 case Window::AddEventListener: {
1806 if (!window->isSafeScript(exec))
1808 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
1810 DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
1812 docimpl->addWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
1816 case Window::RemoveEventListener: {
1817 if (!window->isSafeScript(exec))
1819 JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
1821 DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(part->document().handle());
1823 docimpl->removeWindowEventListener(DOM::EventImpl::typeToId(args[0].toString(exec).string()),listener,args[2].toBoolean(exec));
1832 void Window::updateLayout() const
1834 DOM::DocumentImpl* docimpl = static_cast<DOM::DocumentImpl *>(m_part->document().handle());
1836 docimpl->updateLayoutIgnorePendingStylesheets();
1841 ////////////////////// ScheduledAction ////////////////////////
1843 ScheduledAction::ScheduledAction(Object _func, List _args, bool _singleShot)
1845 //kdDebug(6070) << "ScheduledAction::ScheduledAction(isFunction) " << this << endl;
1849 singleShot = _singleShot;
1852 ScheduledAction::ScheduledAction(const QString &_code, bool _singleShot)
1854 //kdDebug(6070) << "ScheduledAction::ScheduledAction(!isFunction) " << this << endl;
1859 singleShot = _singleShot;
1863 void ScheduledAction::execute(Window *window)
1865 ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(KJSProxy::proxy(window->m_part)->interpreter());
1867 interpreter->setProcessingTimerCallback(true);
1869 //kdDebug(6070) << "ScheduledAction::execute " << this << endl;
1871 if (func.implementsCall()) {
1873 Q_ASSERT( window->m_part );
1874 if ( window->m_part )
1876 KJS::Interpreter *interpreter = KJSProxy::proxy( window->m_part )->interpreter();
1877 ExecState *exec = interpreter->globalExec();
1878 Q_ASSERT( window == interpreter->globalObject().imp() );
1879 Object obj( window );
1880 Interpreter::lock();
1881 func.call(exec,obj,args); // note that call() creates its own execution state for the func call
1882 Interpreter::unlock();
1883 if ( exec->hadException() ) {
1885 Interpreter::lock();
1886 char *message = exec->exception().toObject(exec).get(exec, messagePropertyName).toString(exec).ascii();
1887 int lineNumber = exec->exception().toObject(exec).get(exec, "line").toInt32(exec);
1888 Interpreter::unlock();
1889 if (Interpreter::shouldPrintExceptions()) {
1890 printf("(timer):%s\n", message);
1892 KWQ(window->m_part)->addMessageToConsole(message, lineNumber, QString());
1894 exec->clearException();
1900 window->m_part->executeScript(code);
1903 // Update our document's rendering following the execution of the timeout callback.
1904 DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(window->m_part->document().handle());
1905 doc->updateRendering();
1907 interpreter->setProcessingTimerCallback(false);
1910 ScheduledAction::~ScheduledAction()
1912 //kdDebug(6070) << "ScheduledAction::~ScheduledAction " << this << endl;
1915 ////////////////////// WindowQObject ////////////////////////
1917 WindowQObject::WindowQObject(Window *w)
1920 //kdDebug(6070) << "WindowQObject::WindowQObject " << this << endl;
1921 part = parent->m_part;
1922 connect( parent->m_part, SIGNAL( destroyed() ),
1923 this, SLOT( parentDestroyed() ) );
1926 WindowQObject::~WindowQObject()
1928 //kdDebug(6070) << "WindowQObject::~WindowQObject " << this << endl;
1929 parentDestroyed(); // reuse same code
1932 void WindowQObject::parentDestroyed()
1934 //kdDebug(6070) << "WindowQObject::parentDestroyed " << this << " we have " << scheduledActions.count() << " actions in the map" << endl;
1936 QMapIterator<int,ScheduledAction*> it;
1937 for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
1938 ScheduledAction *action = *it;
1939 //kdDebug(6070) << "WindowQObject::parentDestroyed deleting action " << action << endl;
1942 scheduledActions.clear();
1945 int WindowQObject::installTimeout(const UString &handler, int t, bool singleShot)
1947 //kdDebug(6070) << "WindowQObject::installTimeout " << this << " " << handler.ascii() << endl;
1948 int id = startTimer(t);
1949 ScheduledAction *action = new ScheduledAction(handler.qstring(),singleShot);
1950 scheduledActions.insert(id, action);
1951 //kdDebug(6070) << this << " got id=" << id << " action=" << action << " - now having " << scheduledActions.count() << " actions"<<endl;
1955 int WindowQObject::installTimeout(const Value &func, List args, int t, bool singleShot)
1957 Object objFunc = Object::dynamicCast( func );
1958 int id = startTimer(t);
1959 scheduledActions.insert(id, new ScheduledAction(objFunc,args,singleShot));
1963 QMap<int, ScheduledAction*> *WindowQObject::pauseTimeouts(const void *key)
1965 QMapIterator<int,ScheduledAction*> it;
1967 QMap<int, KJS::ScheduledAction*>*pausedActions = new QMap<int, KJS::ScheduledAction*>;
1968 for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
1969 int timerId = it.key();
1970 pauseTimer (timerId, key);
1971 pausedActions->insert(timerId, it.data());
1973 scheduledActions.clear();
1974 return pausedActions;
1977 void WindowQObject::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
1979 QMapIterator<int,ScheduledAction*> it;
1980 for (it = sa->begin(); it != sa->end(); ++it) {
1981 int timerId = it.key();
1982 scheduledActions.insert(timerId, it.data());
1985 resumeTimers (key, this);
1988 void WindowQObject::clearTimeout(int timerId, bool delAction)
1990 //kdDebug(6070) << "WindowQObject::clearTimeout " << this << " timerId=" << timerId << " delAction=" << delAction << endl;
1993 QMapIterator<int,ScheduledAction*> it = scheduledActions.find(timerId);
1994 if (it != scheduledActions.end()) {
1995 ScheduledAction *action = *it;
1996 scheduledActions.remove(it);
2002 void WindowQObject::timerEvent(QTimerEvent *e)
2004 QMapIterator<int,ScheduledAction*> it = scheduledActions.find(e->timerId());
2005 if (it != scheduledActions.end()) {
2006 ScheduledAction *action = *it;
2007 bool singleShot = action->singleShot;
2008 //kdDebug(6070) << "WindowQObject::timerEvent " << this << " action=" << action << " singleShot:" << singleShot << endl;
2010 // remove single shots installed by setTimeout()
2013 clearTimeout(e->timerId(),false);
2014 scheduledActions.remove(it);
2017 if (!parent->part().isNull())
2018 action->execute(parent);
2020 // It is important to test singleShot and not action->singleShot here - the
2021 // action could have been deleted already if not single shot and if the
2022 // JS code called by execute() calls clearTimeout().
2026 kdWarning(6070) << "WindowQObject::timerEvent this=" << this << " timer " << e->timerId()
2027 << " not found (" << scheduledActions.count() << " actions in map)" << endl;
2030 void WindowQObject::timeoutClose()
2032 if (!parent->part().isNull())
2034 //kdDebug(6070) << "WindowQObject::timeoutClose -> closing window" << endl;
2035 delete parent->m_part;
2040 bool WindowQObject::hasTimeouts()
2042 return scheduledActions.count();
2046 Value FrameArray::get(ExecState *exec, const Identifier &p) const
2049 kdDebug(6070) << "FrameArray::get " << p.qstring() << " part=" << (void*)part << endl;
2054 QPtrList<KParts::ReadOnlyPart> frames = part->frames();
2055 unsigned int len = frames.count();
2056 if (p == lengthPropertyName)
2058 else if (p== "location") // non-standard property, but works in NS and IE
2060 Object obj = Object::dynamicCast( Window::retrieve( part ) );
2061 if ( !obj.isNull() )
2062 return obj.get( exec, "location" );
2066 // check for the name or number
2067 KParts::ReadOnlyPart *frame = part->findFrame(p.qstring());
2070 unsigned int i = p.toArrayIndex(&ok);
2072 frame = frames.at(i);
2075 // we are potentially fetching a reference to a another Window object here.
2076 // i.e. we may be accessing objects from another interpreter instance.
2077 // Therefore we have to be a bit careful with memory managment.
2078 if (frame && frame->inherits("KHTMLPart")) {
2079 KHTMLPart *khtml = static_cast<KHTMLPart*>(frame);
2080 return Window::retrieve(khtml);
2083 return ObjectImp::get(exec, p);
2086 UString FrameArray::toString(ExecState *) const
2088 return "[object FrameArray]";
2091 ////////////////////// Location Object ////////////////////////
2093 const ClassInfo Location::info = { "Location", 0, 0, 0 };
2095 @begin LocationTable 11
2096 hash Location::Hash DontDelete
2097 host Location::Host DontDelete
2098 hostname Location::Hostname DontDelete
2099 href Location::Href DontDelete
2100 pathname Location::Pathname DontDelete
2101 port Location::Port DontDelete
2102 protocol Location::Protocol DontDelete
2103 search Location::Search DontDelete
2104 [[==]] Location::EqualEqual DontDelete|ReadOnly
2105 toString Location::ToString DontDelete|Function 0
2106 replace Location::Replace DontDelete|Function 1
2107 reload Location::Reload DontDelete|Function 0
2110 IMPLEMENT_PROTOFUNC(LocationFunc)
2111 Location::Location(KHTMLPart *p) : m_part(p)
2113 //kdDebug(6070) << "Location::Location " << this << " m_part=" << (void*)m_part << endl;
2116 Location::~Location()
2118 //kdDebug(6070) << "Location::~Location " << this << " m_part=" << (void*)m_part << endl;
2121 Value Location::get(ExecState *exec, const Identifier &p) const
2124 kdDebug(6070) << "Location::get " << p.qstring() << " m_part=" << (void*)m_part << endl;
2127 if (m_part.isNull())
2130 const Window* window = Window::retrieveWindow(m_part);
2131 if (!window || !window->isSafeScript(exec))
2134 KURL url = m_part->url();
2135 const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
2137 switch (entry->value) {
2139 return String( url.ref().isNull() ? QString("") : "#" + url.ref() );
2141 UString str = url.host();
2143 str += ":" + QString::number((int)url.port());
2145 // Note: this is the IE spec. The NS spec swaps the two, it says
2146 // "The hostname property is the concatenation of the host and port properties, separated by a colon."
2150 return String( url.host() );
2153 return String( url.prettyURL()+"/" );
2155 return String( url.prettyURL() );
2157 return String( url.path().isEmpty() ? QString("/") : url.path() );
2159 return String( url.port() ? QString::number((int)url.port()) : QString::fromLatin1("") );
2161 return String( url.protocol()+":" );
2163 return String( url.query() );
2164 case EqualEqual: // [[==]]
2165 return String(toString(exec));
2167 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2169 // Look for overrides
2170 ValueImp * val = ObjectImp::getDirect(p);
2174 switch (entry->value) {
2176 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2178 return lookupOrCreateFunction<LocationFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2184 void Location::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
2187 kdDebug(6070) << "Location::put " << p.qstring() << " m_part=" << (void*)m_part << endl;
2189 if (m_part.isNull())
2192 QString str = v.toString(exec).qstring();
2193 KURL url = m_part->url();
2194 const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
2196 switch (entry->value) {
2198 KHTMLPart* p = Window::retrieveActive(exec)->part();
2200 url = p->htmlDocument().completeURL( str ).string();
2209 QString host = str.left(str.find(":"));
2210 QString port = str.mid(str.find(":")+1);
2212 url.setPort(port.toUInt());
2222 url.setPort(str.toUInt());
2225 url.setProtocol(str);
2232 ObjectImp::put(exec, p, v, attr);
2236 const Window* window = Window::retrieveWindow(m_part);
2237 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2238 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2240 // We want a new history item if this JS was called via a user gesture
2241 m_part->scheduleLocationChange(url.url(), !userGesture, userGesture);
2243 m_part->scheduleLocationChange(url.url(), false /*don't lock history*/, userGesture);
2248 Value Location::toPrimitive(ExecState *exec, Type) const
2250 return String(toString(exec));
2253 UString Location::toString(ExecState *) const
2255 if (!m_part->url().hasPath())
2256 return m_part->url().prettyURL()+"/";
2258 return m_part->url().prettyURL();
2261 Value LocationFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
2263 if (!thisObj.inherits(&Location::info)) {
2264 Object err = Error::create(exec,TypeError);
2265 exec->setException(err);
2268 Location *location = static_cast<Location *>(thisObj.imp());
2269 KHTMLPart *part = location->part();
2272 Window* window = Window::retrieveWindow(part);
2273 if (!window->isSafeScript(exec) && id != Location::Replace)
2277 case Location::Replace:
2279 QString str = args[0].toString(exec).qstring();
2280 KHTMLPart* p = Window::retrieveActive(exec)->part();
2282 const Window* window = Window::retrieveWindow(part);
2283 if (!str.startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2284 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2285 part->scheduleLocationChange(p->htmlDocument().completeURL(str).string(), true /*lock history*/, userGesture);
2290 case Location::Reload:
2292 const Window* window = Window::retrieveWindow(part);
2293 if (!part->url().url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2294 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2295 part->scheduleLocationChange(part->url().url(), true/*lock history*/, userGesture);
2299 case Location::ToString:
2300 return String(location->toString(exec));
2303 kdDebug(6070) << "LocationFunc::tryExecute - no part!" << endl;
2307 ////////////////////// Selection Object ////////////////////////
2309 const ClassInfo Selection::info = { "Selection", 0, 0, 0 };
2311 @begin SelectionTable 19
2312 anchorNode Selection::AnchorNode DontDelete|ReadOnly
2313 anchorOffset Selection::AnchorOffset DontDelete|ReadOnly
2314 focusNode Selection::FocusNode DontDelete|ReadOnly
2315 focusOffset Selection::FocusOffset DontDelete|ReadOnly
2316 baseNode Selection::AnchorNode DontDelete|ReadOnly
2317 baseOffset Selection::AnchorOffset DontDelete|ReadOnly
2318 extentNode Selection::FocusNode DontDelete|ReadOnly
2319 extentOffset Selection::FocusOffset DontDelete|ReadOnly
2320 isCollapsed Selection::IsCollapsed DontDelete|ReadOnly
2321 type Selection::_Type DontDelete|ReadOnly
2322 [[==]] Selection::EqualEqual DontDelete|ReadOnly
2323 toString Selection::ToString DontDelete|Function 0
2324 collapse Selection::Collapse DontDelete|Function 2
2325 collapseToEnd Selection::CollapseToEnd DontDelete|Function 0
2326 collapseToStart Selection::CollapseToStart DontDelete|Function 0
2327 empty Selection::Empty DontDelete|Function 0
2328 setBaseAndExtent Selection::SetBaseAndExtent DontDelete|Function 4
2329 setPosition Selection::SetPosition DontDelete|Function 2
2330 modify Selection::Modify DontDelete|Function 3
2333 IMPLEMENT_PROTOFUNC(SelectionFunc)
2334 Selection::Selection(KHTMLPart *p) : m_part(p)
2336 //kdDebug(6070) << "Selection::Selection " << this << " m_part=" << (void*)m_part << endl;
2339 Selection::~Selection()
2341 //kdDebug(6070) << "Selection::~Selection " << this << " m_part=" << (void*)m_part << endl;
2344 Value Selection::get(ExecState *exec, const Identifier &p) const
2347 kdDebug(6070) << "Selection::get " << p.qstring() << " m_part=" << (void*)m_part << endl;
2350 if (m_part.isNull())
2353 const Window* window = Window::retrieveWindow(m_part);
2354 if (!window || !window->isSafeScript(exec))
2357 DocumentImpl *docimpl = m_part->xmlDocImpl();
2359 docimpl->updateLayoutIgnorePendingStylesheets();
2361 KURL url = m_part->url();
2362 const HashEntry *entry = Lookup::findEntry(&SelectionTable, p);
2364 switch (entry->value) {
2367 return getDOMNode(exec, Node(m_part->selection().base().node()));
2370 return Number(m_part->selection().base().offset());
2373 return getDOMNode(exec, Node(m_part->selection().extent().node()));
2376 return Number(m_part->selection().extent().offset());
2378 return Boolean(!m_part->selection().isRange());
2380 switch (m_part->selection().state()) {
2381 case khtml::Selection::NONE:
2382 return String("None");
2383 case khtml::Selection::CARET:
2384 return String("Caret");
2385 case khtml::Selection::RANGE:
2386 return String("Range");
2390 return String(toString(exec));
2392 return lookupOrCreateFunction<SelectionFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2394 // Look for overrides
2395 ValueImp * val = ObjectImp::getDirect(p);
2399 switch (entry->value) {
2402 case CollapseToStart:
2404 case SetBaseAndExtent:
2407 return lookupOrCreateFunction<SelectionFunc>(exec,p,this,entry->value,entry->params,entry->attr);
2413 void Selection::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
2417 Value Selection::toPrimitive(ExecState *exec, Type) const
2419 return String(toString(exec));
2422 UString Selection::toString(ExecState *) const
2424 if (!m_part->selection().isRange())
2426 return UString(m_part->selection().toRange().toString());
2429 Value SelectionFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
2431 if (!thisObj.inherits(&Selection::info)) {
2432 Object err = Error::create(exec,TypeError);
2433 exec->setException(err);
2436 Selection *selection = static_cast<Selection *>(thisObj.imp());
2437 KHTMLPart *part = selection->part();
2439 DocumentImpl *docimpl = part->xmlDocImpl();
2441 docimpl->updateLayoutIgnorePendingStylesheets();
2444 case Selection::Collapse:
2445 TypingCommand::closeTyping(part->lastEditCommand());
2446 part->setSelection(khtml::Selection(Position(KJS::toNode(args[0]).handle(), args[1].toInt32(exec))));
2448 case Selection::CollapseToEnd:
2449 TypingCommand::closeTyping(part->lastEditCommand());
2450 part->setSelection(khtml::Selection(part->selection().end()));
2452 case Selection::CollapseToStart:
2453 TypingCommand::closeTyping(part->lastEditCommand());
2454 part->setSelection(khtml::Selection(part->selection().start()));
2456 case Selection::Empty:
2457 TypingCommand::closeTyping(part->lastEditCommand());
2458 part->clearSelection();
2460 case Selection::SetBaseAndExtent: {
2461 TypingCommand::closeTyping(part->lastEditCommand());
2462 Position base(KJS::toNode(args[0]).handle(), args[1].toInt32(exec));
2463 Position extent(KJS::toNode(args[2]).handle(), args[3].toInt32(exec));
2464 part->setSelection(khtml::Selection(base, extent));
2467 case Selection::SetPosition:
2468 TypingCommand::closeTyping(part->lastEditCommand());
2469 part->setSelection(khtml::Selection(Position(KJS::toNode(args[0]).handle(), args[1].toInt32(exec))));
2471 case Selection::Modify: {
2472 TypingCommand::closeTyping(part->lastEditCommand());
2473 khtml::Selection s(part->selection());
2474 khtml::Selection::EAlter alter = khtml::Selection::MOVE;
2475 if (args[0].toString(exec).string().lower() == "extend")
2476 alter = khtml::Selection::EXTEND;
2477 DOMString directionString = args[1].toString(exec).string().lower();
2478 khtml::Selection::EDirection direction = khtml::Selection::FORWARD;
2479 if (directionString == "backward")
2480 direction = khtml::Selection::BACKWARD;
2481 else if (directionString == "left")
2482 direction = khtml::Selection::LEFT;
2483 if (directionString == "right")
2484 direction = khtml::Selection::RIGHT;
2485 khtml::ETextGranularity granularity = khtml::CHARACTER;
2486 DOMString granularityString = args[2].toString(exec).string().lower();
2487 if (granularityString == "word")
2488 granularity = khtml::WORD;
2489 else if (granularityString == "line")
2490 granularity = khtml::LINE;
2491 else if (granularityString == "pargraph")
2492 granularity = khtml::PARAGRAPH;
2493 s.modify(alter, direction, granularity);
2494 part->setSelection(s);
2502 ////////////////////// BarInfo Object ////////////////////////
2504 const ClassInfo BarInfo::info = { "BarInfo", 0, 0, 0 };
2506 @begin BarInfoTable 1
2507 visible BarInfo::Visible DontDelete|ReadOnly
2510 BarInfo::BarInfo(ExecState *exec, KHTMLPart *p, Type barType)
2511 : ObjectImp(exec->lexicalInterpreter()->builtinObjectPrototype())
2521 Value BarInfo::get(ExecState *exec, const Identifier &p) const
2523 if (m_part.isNull())
2526 const HashEntry *entry = Lookup::findEntry(&BarInfoTable, p);
2527 if (entry && entry->value == Visible) {
2531 return Boolean(KWQ(m_part)->locationbarVisible());
2535 return Boolean(KWQ(m_part)->locationbarVisible());
2539 return Boolean(KWQ(m_part)->personalbarVisible());
2543 return Boolean(KWQ(m_part)->scrollbarsVisible());
2547 return Boolean(KWQ(m_part)->statusbarVisible());
2551 return Boolean(KWQ(m_part)->toolbarVisible());
2554 return Boolean(false);
2561 void BarInfo::put(ExecState *exec, const Identifier &p, const Value &v, int attr)
2565 ////////////////////// History Object ////////////////////////
2567 const ClassInfo History::info = { "History", 0, 0, 0 };
2569 @begin HistoryTable 4
2570 length History::Length DontDelete|ReadOnly
2571 back History::Back DontDelete|Function 0
2572 forward History::Forward DontDelete|Function 0
2573 go History::Go DontDelete|Function 1
2576 IMPLEMENT_PROTOFUNC(HistoryFunc)
2578 Value History::get(ExecState *exec, const Identifier &p) const
2580 return lookupGet<HistoryFunc,History,ObjectImp>(exec,p,&HistoryTable,this);
2583 Value History::getValueProperty(ExecState *, int token) const
2588 KParts::BrowserExtension *ext = part->browserExtension();
2592 KParts::BrowserInterface *iface = ext->browserInterface();
2596 QVariant length = iface->property( "historyLength" );
2598 if ( length.type() != QVariant::UInt )
2601 return Number( length.toUInt() );
2604 kdWarning() << "Unhandled token in History::getValueProperty : " << token << endl;
2609 UString History::toString(ExecState *exec) const
2611 return "[object History]";
2614 Value HistoryFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
2616 if (!thisObj.inherits(&History::info)) {
2617 Object err = Error::create(exec,TypeError);
2618 exec->setException(err);
2621 History *history = static_cast<History *>(thisObj.imp());
2628 case History::Forward:
2632 steps = args[0].toInt32(exec);
2638 history->part->scheduleHistoryNavigation(steps);
2642 /////////////////////////////////////////////////////////////////////////////
2646 const ClassInfo Konqueror::info = { "Konqueror", 0, 0, 0 };
2648 bool Konqueror::hasProperty(ExecState *exec, const Identifier &p) const
2650 if ( p.qstring().startsWith( "goHistory" ) ) return false;
2655 Value Konqueror::get(ExecState *exec, const Identifier &p) const
2657 if ( p == "goHistory" || part->url().protocol() != "http" || part->url().host() != "localhost" )
2660 KParts::BrowserExtension *ext = part->browserExtension();
2662 KParts::BrowserInterface *iface = ext->browserInterface();
2664 QVariant prop = iface->property( p.qstring().latin1() );
2666 if ( prop.isValid() ) {
2667 switch( prop.type() ) {
2669 return Number( prop.toInt() );
2670 case QVariant::String:
2671 return String( prop.toString() );
2679 return /*Function*/( new KonquerorFunc(this, p.qstring().latin1() ) );
2682 Value KonquerorFunc::tryCall(ExecState *exec, Object &, const List &args)
2684 KParts::BrowserExtension *ext = konqueror->part->browserExtension();
2689 KParts::BrowserInterface *iface = ext->browserInterface();
2694 QCString n = m_name.data();
2696 iface->callMethod( n.data(), QVariant() );
2701 UString Konqueror::toString(ExecState *) const
2703 return UString("[object Konqueror]");
2707 /////////////////////////////////////////////////////////////////////////////
2709 #include "kjs_window.moc"