1 // -*- c-basic-offset: 2 -*-
3 * This file is part of the KDE libraries
4 * Copyright (C) 2000-2003 Harri Porten (porten@kde.org)
5 * Copyright (C) 2001-2003 David Faure (faure@kde.org)
6 * Copyright (C) 2003 Apple Computer, Inc.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "kjs_window.h"
25 #include <khtmlview.h>
26 #include <khtml_part.h>
27 #include <khtmlpart_p.h>
28 #include <khtml_settings.h>
29 #include <xml/dom2_eventsimpl.h>
30 #include <xml/dom_docimpl.h>
31 #include <dom/html_document.h>
32 #include <misc/htmltags.h>
33 #include <html/html_documentimpl.h>
34 #include <rendering/render_frames.h>
38 #include <QtCore/QTimer>
39 #include <QtGui/QApplication>
41 #include <kmessagebox.h>
42 #include <kinputdialog.h>
45 #include <kparts/browserinterface.h>
46 #include <kwindowsystem.h>
49 #include <kbookmarkmanager.h>
50 #include <kbookmarkdialog.h>
52 #include <kglobalsettings.h>
54 #include <QtGui/QStyle>
55 #include <QtCore/QObject>
56 #include <QtGui/QTextDocument>
57 #include <kstringhandler.h>
59 #include "kjs_proxy.h"
60 #include "kjs_navigator.h"
61 #include "kjs_mozilla.h"
63 #include "kjs_range.h"
64 #include "kjs_traversal.h"
66 #include "kjs_events.h"
67 #include "kjs_views.h"
68 #include "kjs_audio.h"
69 #include "kjs_context2d.h"
70 #include "xmlhttprequest.h"
71 #include "xmlserializer.h"
72 #include "domparser.h"
74 #include <rendering/render_replaced.h>
82 class History
: public JSObject
{
83 friend class HistoryFunc
;
85 History(ExecState
*exec
, KHTMLPart
*p
)
86 : JSObject(exec
->lexicalInterpreter()->builtinObjectPrototype()), part(p
) { }
87 virtual bool getOwnPropertySlot(ExecState
*exec
, const Identifier
& propertyName
, PropertySlot
& slot
);
88 JSValue
*getValueProperty(ExecState
*exec
, int token
) const;
89 virtual const ClassInfo
* classInfo() const { return &info
; }
90 static const ClassInfo info
;
91 enum { Back
, Forward
, Go
, Length
};
93 QPointer
<KHTMLPart
> part
;
96 class External
: public JSObject
{
97 friend class ExternalFunc
;
99 External(ExecState
*exec
, KHTMLPart
*p
)
100 : JSObject(exec
->lexicalInterpreter()->builtinObjectPrototype()), part(p
) { }
101 virtual bool getOwnPropertySlot(ExecState
*exec
, const Identifier
& propertyName
, PropertySlot
& slot
);
102 virtual const ClassInfo
* classInfo() const { return &info
; }
103 static const ClassInfo info
;
104 enum { AddFavorite
};
106 QPointer
<KHTMLPart
> part
;
110 #include "kjs_window.lut.h"
114 ////////////////////// Screen Object ////////////////////////
116 // table for screen object
119 height Screen::Height DontEnum|ReadOnly
120 width Screen::Width DontEnum|ReadOnly
121 colorDepth Screen::ColorDepth DontEnum|ReadOnly
122 pixelDepth Screen::PixelDepth DontEnum|ReadOnly
123 availLeft Screen::AvailLeft DontEnum|ReadOnly
124 availTop Screen::AvailTop DontEnum|ReadOnly
125 availHeight Screen::AvailHeight DontEnum|ReadOnly
126 availWidth Screen::AvailWidth DontEnum|ReadOnly
130 const ClassInfo
Screen::info
= { "Screen", 0, &ScreenTable
, 0 };
132 // We set the object prototype so that toString is implemented
133 Screen::Screen(ExecState
*exec
)
134 : JSObject(exec
->lexicalInterpreter()->builtinObjectPrototype()) {}
136 bool Screen::getOwnPropertySlot(ExecState
*exec
, const Identifier
& propertyName
, PropertySlot
& slot
)
139 kDebug(6070) << "Screen::getPropertyName " << propertyName
.qstring();
141 return getStaticValueSlot
<Screen
, JSObject
>(exec
, &ScreenTable
, this, propertyName
, slot
);
144 JSValue
*Screen::getValueProperty(ExecState
*exec
, int token
) const
146 QWidget
*thisWidget
= Window::retrieveActive(exec
)->part()->widget();
147 QRect sg
= KGlobalSettings::desktopGeometry(thisWidget
);
151 return jsNumber(sg
.height());
153 return jsNumber(sg
.width());
156 return jsNumber(thisWidget
->depth());
158 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
159 QRect clipped
= KWindowSystem::workArea().intersect(sg
);
160 return jsNumber(clipped
.x()-sg
.x());
166 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
167 QRect clipped
= KWindowSystem::workArea().intersect(sg
);
168 return jsNumber(clipped
.y()-sg
.y());
174 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
175 QRect clipped
= KWindowSystem::workArea().intersect(sg
);
176 return jsNumber(clipped
.height());
178 return jsNumber(100);
182 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
183 QRect clipped
= KWindowSystem::workArea().intersect(sg
);
184 return jsNumber(clipped
.width());
186 return jsNumber(100);
190 kDebug(6070) << "WARNING: Screen::getValueProperty unhandled token " << token
;
191 return jsUndefined();
195 ////////////////////// Window Object ////////////////////////
197 const ClassInfo
Window::info
= { "Window", &DOMAbstractView::info
, &WindowTable
, 0 };
200 @begin WindowTable 233
201 atob Window::AToB DontDelete|Function 1
202 btoa Window::BToA DontDelete|Function 1
203 closed Window::Closed DontDelete|ReadOnly
204 crypto Window::Crypto DontDelete|ReadOnly
205 defaultStatus Window::DefaultStatus DontDelete
206 defaultstatus Window::DefaultStatus DontDelete
207 status Window::Status DontDelete
208 document Window::Document DontDelete|ReadOnly
209 frameElement Window::FrameElement DontDelete|ReadOnly
210 frames Window::Frames DontDelete
211 history Window::_History DontDelete|ReadOnly
212 external Window::_External DontDelete|ReadOnly
213 event Window::Event DontDelete|ReadOnly
214 innerHeight Window::InnerHeight DontDelete|ReadOnly
215 innerWidth Window::InnerWidth DontDelete|ReadOnly
216 length Window::Length DontDelete
217 location Window::_Location DontDelete
218 name Window::Name DontDelete
219 navigator Window::_Navigator DontDelete|ReadOnly
220 clientInformation Window::ClientInformation DontDelete|ReadOnly
221 konqueror Window::_Konqueror DontDelete
222 offscreenBuffering Window::OffscreenBuffering DontDelete|ReadOnly
223 opener Window::Opener DontDelete|ReadOnly
224 outerHeight Window::OuterHeight DontDelete|ReadOnly
225 outerWidth Window::OuterWidth DontDelete|ReadOnly
226 pageXOffset Window::PageXOffset DontDelete|ReadOnly
227 pageYOffset Window::PageYOffset DontDelete|ReadOnly
228 parent Window::Parent DontDelete
229 personalbar Window::Personalbar DontDelete
230 screenX Window::ScreenX DontDelete|ReadOnly
231 screenY Window::ScreenY DontDelete|ReadOnly
232 scrollbars Window::Scrollbars DontDelete|ReadOnly
233 scroll Window::Scroll DontDelete|Function 2
234 scrollBy Window::ScrollBy DontDelete|Function 2
235 scrollTo Window::ScrollTo DontDelete|Function 2
236 scrollX Window::ScrollX DontDelete|ReadOnly
237 scrollY Window::ScrollY DontDelete|ReadOnly
238 moveBy Window::MoveBy DontDelete|Function 2
239 moveTo Window::MoveTo DontDelete|Function 2
240 resizeBy Window::ResizeBy DontDelete|Function 2
241 resizeTo Window::ResizeTo DontDelete|Function 2
242 self Window::Self DontDelete|ReadOnly
243 window Window::_Window DontDelete|ReadOnly
244 top Window::Top DontDelete
245 screen Window::_Screen DontDelete|ReadOnly
246 alert Window::Alert DontDelete|Function 1
247 confirm Window::Confirm DontDelete|Function 1
248 prompt Window::Prompt DontDelete|Function 2
249 open Window::Open DontDelete|Function 3
250 setTimeout Window::SetTimeout DontDelete|Function 2
251 clearTimeout Window::ClearTimeout DontDelete|Function 1
252 focus Window::Focus DontDelete|Function 0
253 blur Window::Blur DontDelete|Function 0
254 close Window::Close DontDelete|Function 0
255 setInterval Window::SetInterval DontDelete|Function 2
256 clearInterval Window::ClearInterval DontDelete|Function 1
257 captureEvents Window::CaptureEvents DontDelete|Function 0
258 releaseEvents Window::ReleaseEvents DontDelete|Function 0
259 print Window::Print DontDelete|Function 0
260 addEventListener Window::AddEventListener DontDelete|Function 3
261 removeEventListener Window::RemoveEventListener DontDelete|Function 3
262 # Normally found in prototype. Add to window object itself to make them
263 # accessible in closed and cross-site windows
264 valueOf Window::ValueOf DontEnum|DontDelete|Function 0
265 toString Window::ToString DontEnum|DontDelete|Function 0
267 navigate Window::Navigate DontDelete|Function 1
269 sidebar Window::SideBar DontDelete|ReadOnly
270 getComputedStyle Window::GetComputedStyle DontDelete|Function 2
272 # Warning, when adding a function to this object you need to add a case in Window::get
275 # IE also has: onactivate, onbefore/afterprint, onbeforedeactivate/unload, oncontrolselect,
276 # ondeactivate, onhelp, onmovestart/end, onresizestart/end.
277 # It doesn't have onabort, onchange, ondragdrop (but NS has that last one).
278 onabort Window::Onabort DontDelete
279 onblur Window::Onblur DontDelete
280 onchange Window::Onchange DontDelete
281 onclick Window::Onclick DontDelete
282 ondblclick Window::Ondblclick DontDelete
283 ondragdrop Window::Ondragdrop DontDelete
284 onerror Window::Onerror DontDelete
285 onfocus Window::Onfocus DontDelete
286 onkeydown Window::Onkeydown DontDelete
287 onkeypress Window::Onkeypress DontDelete
288 onkeyup Window::Onkeyup DontDelete
289 onload Window::Onload DontDelete
290 onmousedown Window::Onmousedown DontDelete
291 onmousemove Window::Onmousemove DontDelete
292 onmouseout Window::Onmouseout DontDelete
293 onmouseover Window::Onmouseover DontDelete
294 onmouseup Window::Onmouseup DontDelete
295 onmove Window::Onmove DontDelete
296 onreset Window::Onreset DontDelete
297 onresize Window::Onresize DontDelete
298 onscroll Window::Onscroll DontDelete
299 onselect Window::Onselect DontDelete
300 onsubmit Window::Onsubmit DontDelete
301 onunload Window::Onunload DontDelete
303 # Constructors/constant tables
304 Node Window::Node DontEnum|DontDelete
305 Event Window::EventCtor DontEnum|DontDelete
306 Range Window::Range DontEnum|DontDelete
307 NodeFilter Window::NodeFilter DontEnum|DontDelete
308 NodeList Window::NodeList DontEnum|DontDelete
309 DOMException Window::DOMException DontEnum|DontDelete
310 RangeException Window::RangeException DontEnum|DontDelete
311 CSSRule Window::CSSRule DontEnum|DontDelete
312 MutationEvent Window::MutationEventCtor DontEnum|DontDelete
313 KeyboardEvent Window::KeyboardEventCtor DontEnum|DontDelete
314 EventException Window::EventExceptionCtor DontEnum|DontDelete
315 Audio Window::Audio DontEnum|DontDelete
316 Image Window::Image DontEnum|DontDelete
317 Option Window::Option DontEnum|DontDelete
318 XMLHttpRequest Window::XMLHttpRequest DontEnum|DontDelete
319 XMLSerializer Window::XMLSerializer DontEnum|DontDelete
320 DOMParser Window::DOMParser DontEnum|DontDelete
322 # Mozilla dom emulation ones.
323 Element Window::ElementCtor DontEnum|DontDelete
324 Document Window::DocumentCtor DontEnum|DontDelete
325 #this one is an alias since we don't have a separate XMLDocument
326 XMLDocument Window::DocumentCtor DontEnum|DontDelete
327 HTMLElement Window::HTMLElementCtor DontEnum|DontDelete
328 HTMLDocument Window::HTMLDocumentCtor DontEnum|DontDelete
329 HTMLHtmlElement Window::HTMLHtmlElementCtor DontEnum|DontDelete
330 HTMLHeadElement Window::HTMLHeadElementCtor DontEnum|DontDelete
331 HTMLLinkElement Window::HTMLLinkElementCtor DontEnum|DontDelete
332 HTMLTitleElement Window::HTMLTitleElementCtor DontEnum|DontDelete
333 HTMLMetaElement Window::HTMLMetaElementCtor DontEnum|DontDelete
334 HTMLBaseElement Window::HTMLBaseElementCtor DontEnum|DontDelete
335 HTMLIsIndexElement Window::HTMLIsIndexElementCtor DontEnum|DontDelete
336 HTMLStyleElement Window::HTMLStyleElementCtor DontEnum|DontDelete
337 HTMLBodyElement Window::HTMLBodyElementCtor DontEnum|DontDelete
338 HTMLFormElement Window::HTMLFormElementCtor DontEnum|DontDelete
339 HTMLSelectElement Window::HTMLSelectElementCtor DontEnum|DontDelete
340 HTMLOptGroupElement Window::HTMLOptGroupElementCtor DontEnum|DontDelete
341 HTMLOptionElement Window::HTMLOptionElementCtor DontEnum|DontDelete
342 HTMLInputElement Window::HTMLInputElementCtor DontEnum|DontDelete
343 HTMLTextAreaElement Window::HTMLTextAreaElementCtor DontEnum|DontDelete
344 HTMLButtonElement Window::HTMLButtonElementCtor DontEnum|DontDelete
345 HTMLLabelElement Window::HTMLLabelElementCtor DontEnum|DontDelete
346 HTMLFieldSetElement Window::HTMLFieldSetElementCtor DontEnum|DontDelete
347 HTMLLegendElement Window::HTMLLegendElementCtor DontEnum|DontDelete
348 HTMLUListElement Window::HTMLUListElementCtor DontEnum|DontDelete
349 HTMLOListElement Window::HTMLOListElementCtor DontEnum|DontDelete
350 HTMLDListElement Window::HTMLDListElementCtor DontEnum|DontDelete
351 HTMLDirectoryElement Window::HTMLDirectoryElementCtor DontEnum|DontDelete
352 HTMLMenuElement Window::HTMLMenuElementCtor DontEnum|DontDelete
353 HTMLLIElement Window::HTMLLIElementCtor DontEnum|DontDelete
354 HTMLDivElement Window::HTMLDivElementCtor DontEnum|DontDelete
355 HTMLParagraphElement Window::HTMLParagraphElementCtor DontEnum|DontDelete
356 HTMLHeadingElement Window::HTMLHeadingElementCtor DontEnum|DontDelete
357 HTMLBlockQuoteElement Window::HTMLBlockQuoteElementCtor DontEnum|DontDelete
358 HTMLQuoteElement Window::HTMLQuoteElementCtor DontEnum|DontDelete
359 HTMLPreElement Window::HTMLPreElementCtor DontEnum|DontDelete
360 HTMLBRElement Window::HTMLBRElementCtor DontEnum|DontDelete
361 HTMLBaseFontElement Window::HTMLBaseFontElementCtor DontEnum|DontDelete
362 HTMLFontElement Window::HTMLFontElementCtor DontEnum|DontDelete
363 HTMLHRElement Window::HTMLHRElementCtor DontEnum|DontDelete
364 HTMLModElement Window::HTMLModElementCtor DontEnum|DontDelete
365 HTMLAnchorElement Window::HTMLAnchorElementCtor DontEnum|DontDelete
366 HTMLImageElement Window::HTMLImageElementCtor DontEnum|DontDelete
367 HTMLObjectElement Window::HTMLObjectElementCtor DontEnum|DontDelete
368 HTMLParamElement Window::HTMLParamElementCtor DontEnum|DontDelete
369 HTMLAppletElement Window::HTMLAppletElementCtor DontEnum|DontDelete
370 HTMLMapElement Window::HTMLMapElementCtor DontEnum|DontDelete
371 HTMLAreaElement Window::HTMLAreaElementCtor DontEnum|DontDelete
372 HTMLScriptElement Window::HTMLScriptElementCtor DontEnum|DontDelete
373 HTMLTableElement Window::HTMLTableElementCtor DontEnum|DontDelete
374 HTMLTableCaptionElement Window::HTMLTableCaptionElementCtor DontEnum|DontDelete
375 HTMLTableColElement Window::HTMLTableColElementCtor DontEnum|DontDelete
376 HTMLTableSectionElement Window::HTMLTableSectionElementCtor DontEnum|DontDelete
377 HTMLTableRowElement Window::HTMLTableRowElementCtor DontEnum|DontDelete
378 HTMLTableCellElement Window::HTMLTableCellElementCtor DontEnum|DontDelete
379 HTMLFrameSetElement Window::HTMLFrameSetElementCtor DontEnum|DontDelete
380 HTMLLayerElement Window::HTMLLayerElementCtor DontEnum|DontDelete
381 HTMLFrameElement Window::HTMLFrameElementCtor DontEnum|DontDelete
382 HTMLIFrameElement Window::HTMLIFrameElementCtor DontEnum|DontDelete
383 HTMLCollection Window::HTMLCollectionCtor DontEnum|DontDelete
384 HTMLCanvasElement Window::HTMLCanvasElementCtor DontEnum|DontDelete
385 CSSStyleDeclaration Window::CSSStyleDeclarationCtor DontEnum|DontDelete
386 CanvasRenderingContext2D Window::Context2DCtor DontEnum|DontDelete
389 KJS_IMPLEMENT_PROTOFUNC(WindowFunc
)
391 Window::Window(khtml::ChildFrame
*p
)
392 : JSGlobalObject(/*no proto*/), m_frame(p
), screen(0), history(0), external(0), loc(0), m_evt(0)
394 winq
= new WindowQObject(this);
395 //kDebug(6070) << "Window::Window this=" << this << " part=" << m_part << " " << m_part->name();
403 Window
*Window::retrieveWindow(KParts::ReadOnlyPart
*p
)
405 JSObject
*obj
= retrieve( p
)->getObject();
407 // obj should never be null, except when javascript has been disabled in that part.
408 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(p
);
409 if ( part
&& part
->jScriptEnabled() )
413 assert( dynamic_cast<KJS::Window
*>(obj
) ); // type checking
417 if ( !obj
) // JS disabled
419 return static_cast<KJS::Window
*>(obj
);
422 Window
*Window::retrieveActive(ExecState
*exec
)
424 JSValue
*imp
= exec
->dynamicInterpreter()->globalObject();
427 assert( dynamic_cast<KJS::Window
*>(imp
) );
429 return static_cast<KJS::Window
*>(imp
);
432 JSValue
*Window::retrieve(KParts::ReadOnlyPart
*p
)
435 KHTMLPart
* part
= qobject_cast
<KHTMLPart
*>(p
);
436 KJSProxy
*proxy
= 0L;
438 part
= qobject_cast
<KHTMLPart
*>(p
->parent());
440 proxy
= part
->framejScript(p
);
442 proxy
= part
->jScript();
445 kDebug(6070) << "Window::retrieve part=" << part
<< " '" << part
->objectName() << "' interpreter=" << proxy
->interpreter() << " window=" << proxy
->interpreter()->globalObject();
447 return proxy
->interpreter()->globalObject(); // the Global object is the "window"
450 kDebug(6070) << "Window::retrieve part=" << p
<< " '" << p
->objectName() << "' no jsproxy.";
452 return jsUndefined(); // This can happen with JS disabled on the domain of that window
456 Location
*Window::location() const
459 const_cast<Window
*>(this)->loc
= new Location(m_frame
);
463 // reference our special objects during garbage collection
467 if (screen
&& !screen
->marked())
469 if (history
&& !history
->marked())
471 if (external
&& !external
->marked())
473 //kDebug(6070) << "Window::mark " << this << " marking loc=" << loc;
474 if (loc
&& !loc
->marked())
480 UString
Window::toString(ExecState
*) const
482 return "[object Window]";
485 bool Window::getOwnPropertySlot(ExecState
*exec
, const Identifier
& propertyName
, PropertySlot
& slot
)
488 kDebug(6070) << "Window("<<this<<")::getOwnPropertySlot " << propertyName
.qstring();
491 // we want only limited operations on a closed window
492 if (m_frame
.isNull() || m_frame
->m_part
.isNull()) {
493 const HashEntry
* entry
= Lookup::findEntry(&WindowTable
, propertyName
);
495 switch (entry
->value
) {
500 getSlotFromEntry
<WindowFunc
, Window
>(entry
, this, slot
);
506 slot
.setUndefined(this);
510 // Look for overrides first
511 JSValue
**val
= getDirectLocation(propertyName
);
513 if (isSafeScript(exec
))
514 fillDirectLocationSlot(slot
, val
);
516 slot
.setUndefined(this);
520 const HashEntry
* entry
= Lookup::findEntry(&WindowTable
, propertyName
);
521 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
523 // properties that work on all windows
525 // ReadOnlyPart first
527 switch(entry
->value
) {
529 case _Location
: // No isSafeScript test here, we must be able to _set_ location.href (#49819)
532 getSlotFromEntry
<WindowFunc
, Window
>(entry
, this, slot
);
538 slot
.setUndefined(this);
543 switch(entry
->value
) {
559 getSlotFromEntry
<WindowFunc
, Window
>(entry
, this, slot
);
567 KParts::LiveConnectExtension::Type rtype
;
568 unsigned long robjid
;
569 if (m_frame
->m_liveconnect
&&
570 isSafeScript(exec
) &&
571 m_frame
->m_liveconnect
->get(0, propertyName
.qstring(), rtype
, robjid
, rvalue
))
572 return getImmediateValueSlot(this,
573 getLiveConnectValue(m_frame
->m_liveconnect
, propertyName
.qstring(), rtype
, rvalue
, robjid
), slot
);
575 slot
.setUndefined(this);
579 // properties that only work on safe windows - we can handle them now..
580 if (isSafeScript(exec
) && entry
)
582 // Disabled in NS-compat mode. Supported by default - can't hurt, unless someone uses
583 // if (navigate) to test for IE (unlikely).
584 if (entry
->value
== Navigate
&& exec
->dynamicInterpreter()->compatMode() == Interpreter::NetscapeCompat
) {
585 slot
.setUndefined(this);
589 getSlotFromEntry
<WindowFunc
, Window
>(entry
, this, slot
);
593 KParts::ReadOnlyPart
*rop
= part
->findFramePart( propertyName
.qstring() );
596 slot
.setCustom(this, framePartGetter
);
600 // allow window[1] or parent[1] etc. (#56983)
602 unsigned int i
= propertyName
.toArrayIndex(&ok
);
603 if (ok
&& frameByIndex(i
)) {
604 slot
.setCustomIndex(this, i
, indexGetterAdapter
<Window
>);
608 // allow shortcuts like 'Image1' instead of document.images.Image1
609 DOM::DocumentImpl
*doc
= part
->xmlDocImpl();
610 if (isSafeScript(exec
) && doc
&& doc
->isHTMLDocument()) {
611 DOM::ElementMappingCache::ItemInfo
* info
= doc
->underDocNamedCache().get(propertyName
.qstring());
612 if (info
|| doc
->getElementById(propertyName
.domString())) {
613 slot
.setCustom(this, namedItemGetter
);
618 // This isn't necessarily a bug. Some code uses if(!window.blah) window.blah=1
619 // But it can also mean something isn't loaded or implemented, hence the WARNING to help grepping.
621 kDebug(6070) << "WARNING: Window::get property not found: " << propertyName
.qstring();
624 return JSObject::getOwnPropertySlot(exec
, propertyName
, slot
);
627 KParts::ReadOnlyPart
* Window::frameByIndex(unsigned i
)
629 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
630 QList
<KParts::ReadOnlyPart
*> frames
= part
->frames();
631 unsigned int len
= frames
.count();
633 KParts::ReadOnlyPart
* frame
= frames
.at(i
);
639 JSValue
* Window::indexGetter(ExecState
*exec
, unsigned index
)
641 KParts::ReadOnlyPart
* frame
= frameByIndex(index
);
643 return Window::retrieve(frame
);
644 return jsUndefined(); //### ?
647 JSValue
*Window::framePartGetter(ExecState
*exec
, JSObject
*, const Identifier
& propertyName
, const PropertySlot
& slot
)
649 Window
* thisObj
= static_cast<Window
*>(slot
.slotBase());
650 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(thisObj
->m_frame
->m_part
);
651 KParts::ReadOnlyPart
*rop
= part
->findFramePart( propertyName
.qstring() );
652 return thisObj
->retrieve(rop
);
655 JSValue
*Window::namedItemGetter(ExecState
*exec
, JSObject
*, const Identifier
& p
, const PropertySlot
& slot
)
657 Window
* thisObj
= static_cast<Window
*>(slot
.slotBase());
658 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(thisObj
->m_frame
->m_part
);
659 DOM::DocumentImpl
* doc
= part
->xmlDocImpl();
661 DOM::ElementMappingCache::ItemInfo
* info
= doc
->underDocNamedCache().get(p
.qstring());
664 return getDOMNode(exec
, info
->nd
);
666 //No cached mapping, do it by hand...
667 DOM::HTMLMappedNameCollectionImpl
* coll
= new DOM::HTMLMappedNameCollectionImpl(doc
,
668 DOM::HTMLCollectionImpl::DOCUMENT_NAMED_ITEMS
, p
.domString());
670 if (coll
->length() == 1) {
671 info
->nd
= static_cast<DOM::ElementImpl
*>(coll
->firstItem());
673 return getDOMNode(exec
, info
->nd
);
675 return getHTMLCollection(exec
, coll
);
679 DOM::ElementImpl
* element
= doc
->getElementById(p
.domString());
680 return getDOMNode(exec
, element
);
683 JSValue
* Window::getValueProperty(ExecState
*exec
, int token
)
685 KHTMLPart
*part
= m_frame
.isNull() ? 0 : qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
689 return jsBoolean(true);
693 return jsUndefined();
699 return jsBoolean(!part
);
701 // No isSafeScript test here, we must be able to _set_ location.href (#49819)
705 return retrieve(part
);
710 return jsNull(); // ### a null Window might be better, but == null
711 else // doesn't work yet
712 return retrieve(part
->opener());
714 return retrieve(part
&& part
->parentPart() ? part
->parentPart() : (KHTMLPart
*)part
);
717 while (p
->parentPart())
722 return jsUndefined(); // ###
724 return jsString(UString(part
->jsDefaultStatusBarText()));
726 return jsString(UString(part
->jsStatusBarText()));
728 if (!part
->xmlDocImpl()) {
729 kDebug(6070) << "Document.write: adding <HTML><BODY> to create document";
731 part
->write("<HTML><BODY>");
734 return getDOMNode(exec
, part
->xmlDocImpl());
736 if (m_frame
->m_partContainerElement
)
737 return getDOMNode(exec
,m_frame
->m_partContainerElement
);
739 return jsUndefined();
741 return NodeConstructor::self(exec
);
743 return getRangeConstructor(exec
);
745 return getNodeFilterConstructor(exec
);
747 return NodeListPseudoCtor::self(exec
);
749 return getDOMExceptionConstructor(exec
);
751 return RangeExceptionPseudoCtor::self(exec
);
753 return getCSSRuleConstructor(exec
);
755 return ElementPseudoCtor::self(exec
);
756 case HTMLElementCtor
:
757 return HTMLElementPseudoCtor::self(exec
);
758 case HTMLHtmlElementCtor
:
759 return HTMLHtmlElementPseudoCtor::self(exec
);
760 case HTMLHeadElementCtor
:
761 return HTMLHeadElementPseudoCtor::self(exec
);
762 case HTMLLinkElementCtor
:
763 return HTMLLinkElementPseudoCtor::self(exec
);
764 case HTMLTitleElementCtor
:
765 return HTMLTitleElementPseudoCtor::self(exec
);
766 case HTMLMetaElementCtor
:
767 return HTMLMetaElementPseudoCtor::self(exec
);
768 case HTMLBaseElementCtor
:
769 return HTMLBaseElementPseudoCtor::self(exec
);
770 case HTMLIsIndexElementCtor
:
771 return HTMLIsIndexElementPseudoCtor::self(exec
);
772 case HTMLStyleElementCtor
:
773 return HTMLStyleElementPseudoCtor::self(exec
);
774 case HTMLBodyElementCtor
:
775 return HTMLBodyElementPseudoCtor::self(exec
);
776 case HTMLFormElementCtor
:
777 return HTMLFormElementPseudoCtor::self(exec
);
778 case HTMLSelectElementCtor
:
779 return HTMLSelectElementPseudoCtor::self(exec
);
780 case HTMLOptGroupElementCtor
:
781 return HTMLOptGroupElementPseudoCtor::self(exec
);
782 case HTMLOptionElementCtor
:
783 return HTMLOptionElementPseudoCtor::self(exec
);
784 case HTMLInputElementCtor
:
785 return HTMLInputElementPseudoCtor::self(exec
);
786 case HTMLTextAreaElementCtor
:
787 return HTMLTextAreaElementPseudoCtor::self(exec
);
788 case HTMLButtonElementCtor
:
789 return HTMLButtonElementPseudoCtor::self(exec
);
790 case HTMLLabelElementCtor
:
791 return HTMLLabelElementPseudoCtor::self(exec
);
792 case HTMLFieldSetElementCtor
:
793 return HTMLFieldSetElementPseudoCtor::self(exec
);
794 case HTMLLegendElementCtor
:
795 return HTMLLegendElementPseudoCtor::self(exec
);
796 case HTMLUListElementCtor
:
797 return HTMLUListElementPseudoCtor::self(exec
);
798 case HTMLOListElementCtor
:
799 return HTMLOListElementPseudoCtor::self(exec
);
800 case HTMLDListElementCtor
:
801 return HTMLDListElementPseudoCtor::self(exec
);
802 case HTMLDirectoryElementCtor
:
803 return HTMLDirectoryElementPseudoCtor::self(exec
);
804 case HTMLMenuElementCtor
:
805 return HTMLMenuElementPseudoCtor::self(exec
);
806 case HTMLLIElementCtor
:
807 return HTMLLIElementPseudoCtor::self(exec
);
808 case HTMLDivElementCtor
:
809 return HTMLDivElementPseudoCtor::self(exec
);
810 case HTMLParagraphElementCtor
:
811 return HTMLParagraphElementPseudoCtor::self(exec
);
812 case HTMLHeadingElementCtor
:
813 return HTMLHeadingElementPseudoCtor::self(exec
);
814 case HTMLBlockQuoteElementCtor
:
815 return HTMLBlockQuoteElementPseudoCtor::self(exec
);
816 case HTMLQuoteElementCtor
:
817 return HTMLQuoteElementPseudoCtor::self(exec
);
818 case HTMLPreElementCtor
:
819 return HTMLPreElementPseudoCtor::self(exec
);
820 case HTMLBRElementCtor
:
821 return HTMLBRElementPseudoCtor::self(exec
);
822 case HTMLBaseFontElementCtor
:
823 return HTMLBaseFontElementPseudoCtor::self(exec
);
824 case HTMLFontElementCtor
:
825 return HTMLFontElementPseudoCtor::self(exec
);
826 case HTMLHRElementCtor
:
827 return HTMLHRElementPseudoCtor::self(exec
);
828 case HTMLModElementCtor
:
829 return HTMLModElementPseudoCtor::self(exec
);
830 case HTMLAnchorElementCtor
:
831 return HTMLAnchorElementPseudoCtor::self(exec
);
832 case HTMLImageElementCtor
:
833 return HTMLImageElementPseudoCtor::self(exec
);
834 case HTMLObjectElementCtor
:
835 return HTMLObjectElementPseudoCtor::self(exec
);
836 case HTMLParamElementCtor
:
837 return HTMLParamElementPseudoCtor::self(exec
);
838 case HTMLAppletElementCtor
:
839 return HTMLAppletElementPseudoCtor::self(exec
);
840 case HTMLMapElementCtor
:
841 return HTMLMapElementPseudoCtor::self(exec
);
842 case HTMLAreaElementCtor
:
843 return HTMLAreaElementPseudoCtor::self(exec
);
844 case HTMLScriptElementCtor
:
845 return HTMLScriptElementPseudoCtor::self(exec
);
846 case HTMLTableElementCtor
:
847 return HTMLTableElementPseudoCtor::self(exec
);
848 case HTMLTableCaptionElementCtor
:
849 return HTMLTableCaptionElementPseudoCtor::self(exec
);
850 case HTMLTableColElementCtor
:
851 return HTMLTableColElementPseudoCtor::self(exec
);
852 case HTMLTableSectionElementCtor
:
853 return HTMLTableSectionElementPseudoCtor::self(exec
);
854 case HTMLTableRowElementCtor
:
855 return HTMLTableRowElementPseudoCtor::self(exec
);
856 case HTMLTableCellElementCtor
:
857 return HTMLTableCellElementPseudoCtor::self(exec
);
858 case HTMLFrameSetElementCtor
:
859 return HTMLFrameSetElementPseudoCtor::self(exec
);
860 case HTMLLayerElementCtor
:
861 return HTMLLayerElementPseudoCtor::self(exec
);
862 case HTMLFrameElementCtor
:
863 return HTMLFrameElementPseudoCtor::self(exec
);
864 case HTMLIFrameElementCtor
:
865 return HTMLIFrameElementPseudoCtor::self(exec
);
866 case HTMLCollectionCtor
:
867 return HTMLCollectionPseudoCtor::self(exec
);
868 case HTMLCanvasElementCtor
:
869 return HTMLCanvasElementPseudoCtor::self(exec
);
871 return Context2DPseudoCtor::self(exec
);
873 return DocumentPseudoCtor::self(exec
);
874 case HTMLDocumentCtor
:
875 return HTMLDocumentPseudoCtor::self(exec
);
876 case CSSStyleDeclarationCtor
:
877 return CSSStyleDeclarationPseudoCtor::self(exec
);
879 return EventConstructor::self(exec
);
880 case MutationEventCtor
:
881 return getMutationEventConstructor(exec
);
882 case KeyboardEventCtor
:
883 return getKeyboardEventConstructor(exec
);
884 case EventExceptionCtor
:
885 return getEventExceptionConstructor(exec
);
887 return history
? history
:
888 (const_cast<Window
*>(this)->history
= new History(exec
,part
));
891 return external
? external
:
892 (const_cast<Window
*>(this)->external
= new External(exec
,part
));
896 return getDOMEvent(exec
,m_evt
);
899 kDebug(6070) << "WARNING: window(" << this << "," << part
->objectName() << ").event, no event!";
901 return jsUndefined();
906 return jsUndefined();
907 int ret
= part
->view()->visibleHeight();
908 // match Gecko which does not subtract the scrollbars
909 if (part
->view()->horizontalScrollBar()->isVisible()) {
910 ret
+= part
->view()->style()->pixelMetric(QStyle::PM_ScrollBarExtent
);
911 int lvs
= part
->view()->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing
);
915 return jsNumber(ret
);
920 return jsUndefined();
921 int ret
= part
->view()->visibleWidth();
922 // match Gecko which does not subtract the scrollbars
923 if (part
->view()->verticalScrollBar()->isVisible()) {
924 ret
+= part
->view()->style()->pixelMetric(QStyle::PM_ScrollBarExtent
);
925 int lhs
= part
->view()->style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing
);
929 return jsNumber(ret
);
932 return jsNumber(part
->frames().count());
934 return jsString(part
->objectName());
936 return new MozillaSidebarExtension(exec
, part
);
938 case ClientInformation
: {
939 // Store the navigator in the object so we get the same one each time.
940 JSValue
*nav( new Navigator(exec
, part
) );
941 const_cast<Window
*>(this)->put(exec
, "navigator", nav
, DontDelete
|ReadOnly
|Internal
);
942 const_cast<Window
*>(this)->put(exec
, "clientInformation", nav
, DontDelete
|ReadOnly
|Internal
);
946 case OffscreenBuffering
:
947 return jsBoolean(true);
951 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
954 KWindowInfo inf
= KWindowSystem::windowInfo(part
->widget()->topLevelWidget()->winId(), NET::WMGeometry
);
955 return jsNumber(token
== OuterHeight
?
956 inf
.geometry().height() : inf
.geometry().width());
958 return jsNumber(token
== OuterHeight
?
959 part
->view()->height() : part
->view()->width());
963 return jsNumber(part
->view()->contentsX());
965 return jsNumber(part
->view()->contentsY());
967 return jsUndefined(); // ###
971 return jsUndefined();
972 QRect sg
= KGlobalSettings::desktopGeometry(part
->view());
973 return jsNumber(part
->view()->mapToGlobal(QPoint(0,0)).x() + sg
.x());
978 return jsUndefined();
979 QRect sg
= KGlobalSettings::desktopGeometry(part
->view());
980 return jsNumber(part
->view()->mapToGlobal(QPoint(0,0)).y() + sg
.y());
984 return jsUndefined();
985 return jsNumber(part
->view()->contentsX());
989 return jsUndefined();
990 return jsNumber(part
->view()->contentsY());
993 return new JSObject(); // ###
995 return screen
? screen
:
996 (const_cast<Window
*>(this)->screen
= new Screen(exec
));
998 return new AudioConstructorImp(exec
, part
->xmlDocImpl());
1000 return new ImageConstructorImp(exec
, part
->xmlDocImpl());
1002 return new OptionConstructorImp(exec
, part
->xmlDocImpl());
1003 case XMLHttpRequest
:
1004 return new XMLHttpRequestConstructorImp(exec
, part
->xmlDocImpl());
1006 return new XMLSerializerConstructorImp(exec
);
1008 return new DOMParserConstructorImp(exec
, part
->xmlDocImpl());
1010 return getListener(exec
,DOM::EventImpl::ABORT_EVENT
);
1012 return getListener(exec
,DOM::EventImpl::BLUR_EVENT
);
1014 return getListener(exec
,DOM::EventImpl::CHANGE_EVENT
);
1016 return getListener(exec
,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT
);
1018 return getListener(exec
,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT
);
1020 return getListener(exec
,DOM::EventImpl::KHTML_DRAGDROP_EVENT
);
1022 return getListener(exec
,DOM::EventImpl::ERROR_EVENT
);
1024 return getListener(exec
,DOM::EventImpl::FOCUS_EVENT
);
1026 return getListener(exec
,DOM::EventImpl::KEYDOWN_EVENT
);
1028 return getListener(exec
,DOM::EventImpl::KEYPRESS_EVENT
);
1030 return getListener(exec
,DOM::EventImpl::KEYUP_EVENT
);
1032 return getListener(exec
,DOM::EventImpl::LOAD_EVENT
);
1034 return getListener(exec
,DOM::EventImpl::MOUSEDOWN_EVENT
);
1036 return getListener(exec
,DOM::EventImpl::MOUSEMOVE_EVENT
);
1038 return getListener(exec
,DOM::EventImpl::MOUSEOUT_EVENT
);
1040 return getListener(exec
,DOM::EventImpl::MOUSEOVER_EVENT
);
1042 return getListener(exec
,DOM::EventImpl::MOUSEUP_EVENT
);
1044 return getListener(exec
,DOM::EventImpl::KHTML_MOVE_EVENT
);
1046 return getListener(exec
,DOM::EventImpl::RESET_EVENT
);
1048 return getListener(exec
,DOM::EventImpl::RESIZE_EVENT
);
1050 return getListener(exec
,DOM::EventImpl::SCROLL_EVENT
);
1052 return getListener(exec
,DOM::EventImpl::SELECT_EVENT
);
1054 return getListener(exec
,DOM::EventImpl::SUBMIT_EVENT
);
1056 return getListener(exec
,DOM::EventImpl::UNLOAD_EVENT
);
1059 return jsUndefined();
1062 void Window::put(ExecState
* exec
, const Identifier
&propertyName
, JSValue
*value
, int attr
)
1064 // we don't want any operations on a closed window
1065 if (m_frame
.isNull() || m_frame
->m_part
.isNull()) {
1066 // ### throw exception? allow setting of some props like location?
1070 // Called by an internal KJS call (e.g. InterpreterImp's constructor) ?
1071 // If yes, save time and jump directly to JSObject. We also have
1072 // to do this now since calling isSafeScript() may not work yet.
1073 if (attr
!= None
&& attr
!= DontDelete
)
1075 JSObject::put( exec
, propertyName
, value
, attr
);
1080 // If we already have a variable, that's writeable w/o a getter/setter mess, just write to it.
1081 bool safe
= isSafeScript(exec
);
1083 if (JSValue
** slot
= getDirectWriteLocation(propertyName
)) {
1089 const HashEntry
* entry
= Lookup::findEntry(&WindowTable
, propertyName
);
1090 if (entry
&& !m_frame
.isNull() && !m_frame
->m_part
.isNull())
1093 kDebug(6070) << "Window("<<this<<")::put " << propertyName
.qstring();
1095 switch( entry
->value
) {
1097 goURL(exec
, value
->toString(exec
).qstring(), false /*don't lock history*/);
1102 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1104 switch( entry
->value
) {
1106 if (isSafeScript(exec
) && part
->settings()->windowStatusPolicy(part
->url().host())
1107 == KHTMLSettings::KJSWindowStatusAllow
) {
1108 UString s
= value
->toString(exec
);
1109 part
->setJSStatusBarText(s
.qstring());
1113 case DefaultStatus
: {
1114 if (isSafeScript(exec
) && part
->settings()->windowStatusPolicy(part
->url().host())
1115 == KHTMLSettings::KJSWindowStatusAllow
) {
1116 UString s
= value
->toString(exec
);
1117 part
->setJSDefaultStatusBarText(s
.qstring());
1122 if (isSafeScript(exec
))
1123 setListener(exec
, DOM::EventImpl::ABORT_EVENT
,value
);
1126 if (isSafeScript(exec
))
1127 setListener(exec
, DOM::EventImpl::BLUR_EVENT
,value
);
1130 if (isSafeScript(exec
))
1131 setListener(exec
, DOM::EventImpl::CHANGE_EVENT
,value
);
1134 if (isSafeScript(exec
))
1135 setListener(exec
,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT
,value
);
1138 if (isSafeScript(exec
))
1139 setListener(exec
,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT
,value
);
1142 if (isSafeScript(exec
))
1143 setListener(exec
,DOM::EventImpl::KHTML_DRAGDROP_EVENT
,value
);
1146 if (isSafeScript(exec
))
1147 setListener(exec
,DOM::EventImpl::ERROR_EVENT
,value
);
1150 if (isSafeScript(exec
))
1151 setListener(exec
,DOM::EventImpl::FOCUS_EVENT
,value
);
1154 if (isSafeScript(exec
))
1155 setListener(exec
,DOM::EventImpl::KEYDOWN_EVENT
,value
);
1158 if (isSafeScript(exec
))
1159 setListener(exec
,DOM::EventImpl::KEYPRESS_EVENT
,value
);
1162 if (isSafeScript(exec
))
1163 setListener(exec
,DOM::EventImpl::KEYUP_EVENT
,value
);
1166 if (isSafeScript(exec
))
1167 setListener(exec
,DOM::EventImpl::LOAD_EVENT
,value
);
1170 if (isSafeScript(exec
))
1171 setListener(exec
,DOM::EventImpl::MOUSEDOWN_EVENT
,value
);
1174 if (isSafeScript(exec
))
1175 setListener(exec
,DOM::EventImpl::MOUSEMOVE_EVENT
,value
);
1178 if (isSafeScript(exec
))
1179 setListener(exec
,DOM::EventImpl::MOUSEOUT_EVENT
,value
);
1182 if (isSafeScript(exec
))
1183 setListener(exec
,DOM::EventImpl::MOUSEOVER_EVENT
,value
);
1186 if (isSafeScript(exec
))
1187 setListener(exec
,DOM::EventImpl::MOUSEUP_EVENT
,value
);
1190 if (isSafeScript(exec
))
1191 setListener(exec
,DOM::EventImpl::KHTML_MOVE_EVENT
,value
);
1194 if (isSafeScript(exec
))
1195 setListener(exec
,DOM::EventImpl::RESET_EVENT
,value
);
1198 if (isSafeScript(exec
))
1199 setListener(exec
,DOM::EventImpl::RESIZE_EVENT
,value
);
1202 if (isSafeScript(exec
))
1203 setListener(exec
,DOM::EventImpl::SCROLL_EVENT
,value
);
1206 if (isSafeScript(exec
))
1207 setListener(exec
,DOM::EventImpl::SELECT_EVENT
,value
);
1210 if (isSafeScript(exec
))
1211 setListener(exec
,DOM::EventImpl::SUBMIT_EVENT
,value
);
1214 if (isSafeScript(exec
))
1215 setListener(exec
,DOM::EventImpl::UNLOAD_EVENT
,value
);
1218 if (isSafeScript(exec
))
1219 part
->setObjectName( value
->toString(exec
).qstring().toLocal8Bit().data() );
1226 if (m_frame
->m_liveconnect
&&
1227 isSafeScript(exec
) &&
1228 m_frame
->m_liveconnect
->put(0, propertyName
.qstring(), value
->toString(exec
).qstring()))
1231 //kDebug(6070) << "Window("<<this<<")::put storing " << propertyName.qstring();
1232 JSObject::put(exec
, propertyName
, value
, attr
);
1236 bool Window::toBoolean(ExecState
*) const
1238 return !m_frame
.isNull() && !m_frame
->m_part
.isNull();
1241 DOM::AbstractViewImpl
* Window::toAbstractView() const
1243 KHTMLPart
*part
= ::qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1244 if (!part
|| !part
->xmlDocImpl())
1246 return part
->xmlDocImpl()->defaultView();
1249 void Window::scheduleClose()
1251 kDebug(6070) << "Window::scheduleClose window.close() " << m_frame
;
1253 QTimer::singleShot( 0, winq
, SLOT( timeoutClose() ) );
1256 void Window::closeNow()
1258 if (m_frame
.isNull() || m_frame
->m_part
.isNull()) {
1259 kDebug(6070) << "part is deleted already";
1261 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1263 kDebug(6070) << "closeNow on non KHTML part";
1265 //kDebug(6070) << " -> closing window";
1266 // We want to make sure that window.open won't find this part by name.
1267 part
->setObjectName( QString() );
1268 part
->deleteLater();
1274 void Window::afterScriptExecution()
1276 DOM::DocumentImpl::updateDocumentsRendering();
1277 const QList
<DelayedAction
> delayedActions
= m_delayed
;
1279 QList
<DelayedAction
>::ConstIterator it
= delayedActions
.begin();
1280 for ( ; it
!= delayedActions
.end() ; ++it
)
1282 switch ((*it
).actionId
) {
1285 return; // stop here, in case of multiple actions
1286 case DelayedGoHistory
:
1287 goHistory( (*it
).param
.toInt() );
1290 // FIXME: anything needs to be done here? This is warning anyways.
1296 bool Window::checkIsSafeScript(KParts::ReadOnlyPart
*activePart
) const
1298 if (m_frame
.isNull() || m_frame
->m_part
.isNull()) { // part deleted ? can't grant access
1299 kDebug(6070) << "Window::isSafeScript: accessing deleted part !";
1303 kDebug(6070) << "Window::isSafeScript: current interpreter's part is 0L!";
1306 if ( activePart
== m_frame
->m_part
) // Not calling from another frame, no problem.
1309 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1311 return true; // not a KHTMLPart
1313 if ( !part
->xmlDocImpl() )
1314 return true; // allow to access a window that was just created (e.g. with window.open("about:blank"))
1316 DOM::DocumentImpl
* thisDocument
= part
->xmlDocImpl();
1318 KHTMLPart
*activeKHTMLPart
= qobject_cast
<KHTMLPart
*>(activePart
);
1319 if (!activeKHTMLPart
)
1320 return true; // not a KHTMLPart
1322 DOM::DocumentImpl
* actDocument
= activeKHTMLPart
->xmlDocImpl();
1323 if ( !actDocument
) {
1324 kDebug(6070) << "Window::isSafeScript: active part has no document!";
1327 DOM::DOMString actDomain
= actDocument
->domain();
1328 DOM::DOMString thisDomain
= thisDocument
->domain();
1330 if ( actDomain
== thisDomain
) {
1332 //kDebug(6070) << "JavaScript: access granted, domain is '" << actDomain.string() << "'";
1337 kDebug(6070) << "WARNING: JavaScript: access denied for current frame '" << actDomain
.string() << "' to frame '" << thisDomain
.string() << "'";
1338 // TODO after 3.1: throw security exception (exec->setException())
1342 void Window::setListener(ExecState
*exec
, int eventId
, JSValue
*func
)
1344 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1345 if (!part
|| !isSafeScript(exec
))
1347 DOM::DocumentImpl
*doc
= static_cast<DOM::DocumentImpl
*>(part
->htmlDocument().handle());
1351 doc
->setHTMLWindowEventListener(eventId
,getJSEventListener(func
,true));
1354 JSValue
*Window::getListener(ExecState
*exec
, int eventId
) const
1356 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1357 if (!part
|| !isSafeScript(exec
))
1358 return jsUndefined();
1359 DOM::DocumentImpl
*doc
= static_cast<DOM::DocumentImpl
*>(part
->htmlDocument().handle());
1361 return jsUndefined();
1363 DOM::EventListener
*listener
= doc
->getHTMLWindowEventListener(eventId
);
1364 if (listener
&& static_cast<JSEventListener
*>(listener
)->listenerObj())
1365 return static_cast<JSEventListener
*>(listener
)->listenerObj();
1371 JSEventListener
*Window::getJSEventListener(JSValue
*val
, bool html
)
1373 // This function is so hot that it's worth coding it directly with imps.
1374 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1375 if (!part
|| val
->type() != ObjectType
)
1378 // It's ObjectType, so it must be valid.
1379 JSObject
*listenerObject
= val
->getObject();
1380 JSObject
*thisObject
= listenerObject
;
1382 // 'listener' is not a simple ecma function. (Always use sanity checks: Better safe than sorry!)
1383 if (!listenerObject
->implementsCall() && part
&& part
->jScript() && part
->jScript()->interpreter())
1385 Interpreter
*interpreter
= part
->jScript()->interpreter();
1387 // 'listener' probably is an EventListener object containing a 'handleEvent' function.
1388 JSValue
*handleEventValue
= listenerObject
->get(interpreter
->globalExec(), Identifier("handleEvent"));
1389 JSObject
*handleEventObject
= handleEventValue
->getObject();
1391 if(handleEventObject
&& handleEventObject
->implementsCall())
1393 thisObject
= listenerObject
;
1394 listenerObject
= handleEventObject
;
1398 JSEventListener
*existingListener
= jsEventListeners
[QPair
<void*, bool>(thisObject
, html
)];
1399 if (existingListener
) {
1400 assert( existingListener
->isHTMLEventListener() == html
);
1401 return existingListener
;
1404 // Note that the JSEventListener constructor adds it to our jsEventListeners list
1405 return new JSEventListener(listenerObject
, thisObject
, this, html
);
1408 JSLazyEventListener
*Window::getJSLazyEventListener(const QString
& code
, const QString
& srcUrl
, int line
,
1409 const QString
& name
, DOM::NodeImpl
*node
, bool svg
)
1411 return new JSLazyEventListener(code
, srcUrl
, line
, name
, this, node
, svg
);
1414 void Window::clear( ExecState
*exec
)
1418 // Get rid of everything, those user vars could hold references to DOM nodes
1421 // Ditto for the special subobjects.
1426 setPrototype(jsNull());
1428 // Break the dependency between the listeners and their object
1429 QHashIterator
<const QPair
<void*, bool>, JSEventListener
*> it(jsEventListeners
);
1430 while ( it
.hasNext() ) {
1432 it
.value()->clear();
1435 // Forget about the listeners (the DOM::NodeImpls will delete them)
1436 jsEventListeners
.clear();
1439 KJSProxy
* proxy
= m_frame
->m_jscript
;
1440 if (proxy
) // i.e. JS not disabled
1442 winq
= new WindowQObject(this);
1443 // Now recreate a working global object for the next URL that will use us
1444 KJS::Interpreter
*interpreter
= proxy
->interpreter();
1445 interpreter
->initGlobalObject();
1450 void Window::setCurrentEvent( DOM::EventImpl
*evt
)
1453 //kDebug(6070) << "Window " << this << " (part=" << m_part << ")::setCurrentEvent m_evt=" << evt;
1456 void Window::goURL(ExecState
* exec
, const QString
& url
, bool lockHistory
)
1458 Window
* active
= Window::retrieveActive(exec
);
1459 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1460 KHTMLPart
*active_part
= qobject_cast
<KHTMLPart
*>(active
->part());
1461 // Complete the URL using the "active part" (running interpreter)
1462 if (active_part
&& part
) {
1463 QString dstUrl
= active_part
->htmlDocument().completeURL(url
).string();
1464 kDebug(6070) << "Window::goURL dstUrl=" << dstUrl
;
1466 // check if we're allowed to inject javascript
1467 if ( isSafeScript(exec
) ||
1468 !KHTMLPartPrivate::isJavaScriptURL(dstUrl
) )
1469 part
->scheduleRedirection(-1,
1472 } else if (!part
&& m_frame
->m_partContainerElement
) {
1473 KParts::BrowserExtension
*b
= KParts::BrowserExtension::childObject(m_frame
->m_part
);
1475 emit b
->openUrlRequest(m_frame
->m_partContainerElement
->document()->completeURL(url
));
1476 kDebug() << "goURL for ROPart";
1480 void Window::delayedGoHistory( int steps
)
1482 m_delayed
.append( DelayedAction( DelayedGoHistory
, steps
) );
1485 void Window::goHistory( int steps
)
1487 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1489 // TODO history readonlypart
1491 KParts::BrowserExtension
*ext
= part
->browserExtension();
1494 KParts::BrowserInterface
*iface
= ext
->browserInterface();
1499 iface
->callMethod( "goHistory", steps
);
1500 //emit ext->goHistory(steps);
1503 void KJS::Window::resizeTo(QWidget
* tl
, int width
, int height
)
1505 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1507 // TODO resizeTo readonlypart
1509 KParts::BrowserExtension
*ext
= part
->browserExtension();
1511 kDebug(6070) << "Window::resizeTo found no browserExtension";
1515 // Security check: within desktop limits and bigger than 100x100 (per spec)
1516 if ( width
< 100 || height
< 100 ) {
1517 kDebug(6070) << "Window::resizeTo refused, window would be too small ("<<width
<<","<<height
<<")";
1521 QRect sg
= KGlobalSettings::desktopGeometry(tl
);
1523 if ( width
> sg
.width() || height
> sg
.height() ) {
1524 kDebug(6070) << "Window::resizeTo refused, window would be too big ("<<width
<<","<<height
<<")";
1528 kDebug(6070) << "resizing to " << width
<< "x" << height
;
1530 emit ext
->resizeTopLevelWidget( width
, height
);
1532 // If the window is out of the desktop, move it up/left
1533 // (maybe we should use workarea instead of sg, otherwise the window ends up below kicker)
1534 int right
= tl
->x() + tl
->frameGeometry().width();
1535 int bottom
= tl
->y() + tl
->frameGeometry().height();
1538 if ( right
> sg
.right() )
1539 moveByX
= - right
+ sg
.right(); // always <0
1540 if ( bottom
> sg
.bottom() )
1541 moveByY
= - bottom
+ sg
.bottom(); // always <0
1542 if ( moveByX
|| moveByY
)
1543 emit ext
->moveTopLevelWidget( tl
->x() + moveByX
, tl
->y() + moveByY
);
1546 bool Window::targetIsExistingWindow(KHTMLPart
* ourPart
, const QString
& frameName
)
1548 QString normalized
= frameName
.toLower();
1549 if (normalized
== "_top" || normalized
== "_self" || normalized
== "_parent")
1552 // Find the highest parent part we can access.
1553 KHTMLPart
* p
= ourPart
;
1554 while (p
->parentPart() && p
->parentPart()->checkFrameAccess(ourPart
))
1555 p
= p
->parentPart();
1557 return p
->findFrame(frameName
);
1560 JSValue
*Window::openWindow(ExecState
*exec
, const List
& args
)
1562 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1564 return jsUndefined();
1565 KHTMLView
*widget
= part
->view();
1566 JSValue
*v
= args
[0];
1568 if (!v
->isUndefinedOrNull())
1569 str
= v
->toString(exec
).qstring();
1571 // prepare arguments
1575 KHTMLPart
* p
= qobject_cast
<KHTMLPart
*>(Window::retrieveActive(exec
)->m_frame
->m_part
);
1577 url
= p
->htmlDocument().completeURL(str
).string();
1579 !static_cast<DOM::DocumentImpl
*>(p
->htmlDocument().handle())->isURLAllowed(url
.url()) )
1580 return jsUndefined();
1583 KHTMLSettings::KJSWindowOpenPolicy policy
=
1584 part
->settings()->windowOpenPolicy(part
->url().host());
1586 QString frameName
= args
.size() > 1 ? args
[1]->toString(exec
).qstring() : QString("_blank");
1588 // Always permit opening in an exist frame (including _self, etc.)
1589 if ( targetIsExistingWindow( part
, frameName
) )
1590 policy
= KHTMLSettings::KJSWindowOpenAllow
;
1592 if ( policy
== KHTMLSettings::KJSWindowOpenAsk
) {
1593 emit part
->browserExtension()->requestFocus(part
);
1595 if (!part
->url().host().isEmpty())
1596 caption
= part
->url().host() + " - ";
1597 caption
+= i18n( "Confirmation: JavaScript Popup" );
1598 if ( KMessageBox::questionYesNo(widget
,
1600 i18n( "This site is requesting to open up a new browser "
1601 "window via JavaScript.\n"
1602 "Do you want to allow this?" ) :
1603 i18n( "<qt>This site is requesting to open<p>%1</p>in a new browser window via JavaScript.<br />"
1604 "Do you want to allow this?</qt>", KStringHandler::csqueeze(Qt::escape(url
.prettyUrl()), 100)),
1605 caption
, KGuiItem(i18n("Allow")), KGuiItem(i18n("Do Not Allow")) ) == KMessageBox::Yes
)
1606 policy
= KHTMLSettings::KJSWindowOpenAllow
;
1607 } else if ( policy
== KHTMLSettings::KJSWindowOpenSmart
)
1609 // window.open disabled unless from a key/mouse event
1610 if (static_cast<ScriptInterpreter
*>(exec
->dynamicInterpreter())->isWindowOpenAllowed())
1611 policy
= KHTMLSettings::KJSWindowOpenAllow
;
1616 if (v
&& v
->type() != UndefinedType
&& v
->toString(exec
).size() > 0) {
1617 features
= v
->toString(exec
).qstring();
1618 // Buggy scripts have ' at beginning and end, cut those
1619 if (features
.startsWith(QLatin1Char('\'')) &&
1620 features
.endsWith(QLatin1Char('\'')))
1621 features
= features
.mid(1, features
.length()-2);
1624 if ( policy
!= KHTMLSettings::KJSWindowOpenAllow
) {
1625 if ( url
.isEmpty() )
1626 part
->setSuppressedPopupIndicator(true, 0);
1628 part
->setSuppressedPopupIndicator(true, part
);
1629 m_suppressedWindowInfo
.append( SuppressedWindowInfo( url
, frameName
, features
) );
1631 return jsUndefined();
1633 return executeOpenWindow(exec
, url
, frameName
, features
);
1637 JSValue
*Window::executeOpenWindow(ExecState
*exec
, const KUrl
& url
, const QString
& frameName
, const QString
& features
)
1639 KHTMLPart
*p
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1640 KHTMLView
*widget
= p
->view();
1641 KParts::WindowArgs winargs
;
1643 // scan feature argument
1644 if (!features
.isEmpty()) {
1645 // specifying window params means false defaults
1646 winargs
.setMenuBarVisible(false);
1647 winargs
.setToolBarsVisible(false);
1648 winargs
.setStatusBarVisible(false);
1649 winargs
.setScrollBarsVisible(false);
1650 const QStringList flist
= features
.split(',');
1651 QStringList::ConstIterator it
= flist
.begin();
1652 while (it
!= flist
.end()) {
1655 int pos
= s
.indexOf('=');
1657 key
= s
.left(pos
).trimmed().toLower();
1658 val
= s
.mid(pos
+ 1).trimmed().toLower();
1659 QRect screen
= KGlobalSettings::desktopGeometry(widget
->topLevelWidget());
1661 if (key
== "left" || key
== "screenx") {
1662 winargs
.setX((int)val
.toFloat() + screen
.x());
1663 if (winargs
.x() < screen
.x() || winargs
.x() > screen
.right())
1664 winargs
.setX(screen
.x()); // only safe choice until size is determined
1665 } else if (key
== "top" || key
== "screeny") {
1666 winargs
.setY((int)val
.toFloat() + screen
.y());
1667 if (winargs
.y() < screen
.y() || winargs
.y() > screen
.bottom())
1668 winargs
.setY(screen
.y()); // only safe choice until size is determined
1669 } else if (key
== "height") {
1670 winargs
.setHeight((int)val
.toFloat() + 2*qApp
->style()->pixelMetric( QStyle::PM_DefaultFrameWidth
) + 2);
1671 if (winargs
.height() > screen
.height()) // should actually check workspace
1672 winargs
.setHeight(screen
.height());
1673 if (winargs
.height() < 100)
1674 winargs
.setHeight(100);
1675 } else if (key
== "width") {
1676 winargs
.setWidth((int)val
.toFloat() + 2*qApp
->style()->pixelMetric( QStyle::PM_DefaultFrameWidth
) + 2);
1677 if (winargs
.width() > screen
.width()) // should actually check workspace
1678 winargs
.setWidth(screen
.width());
1679 if (winargs
.width() < 100)
1680 winargs
.setWidth(100);
1686 // leaving away the value gives true
1687 key
= s
.trimmed().toLower();
1691 if (key
== "menubar")
1692 winargs
.setMenuBarVisible(val
== "1" || val
== "yes");
1693 else if (key
== "toolbar")
1694 winargs
.setToolBarsVisible(val
== "1" || val
== "yes");
1695 else if (key
== "location") // ### missing in WindowArgs
1696 winargs
.setToolBarsVisible(val
== "1" || val
== "yes");
1697 else if (key
== "status" || key
== "statusbar")
1698 winargs
.setStatusBarVisible(val
== "1" || val
== "yes");
1699 else if (key
== "scrollbars")
1700 winargs
.setScrollBarsVisible(val
== "1" || val
== "yes");
1701 else if (key
== "resizable")
1702 winargs
.setResizable(val
== "1" || val
== "yes");
1703 else if (key
== "fullscreen")
1704 winargs
.setFullScreen(val
== "1" || val
== "yes");
1708 KParts::OpenUrlArguments args
;
1709 KParts::BrowserArguments browserArgs
;
1710 browserArgs
.frameName
= frameName
;
1712 if ( browserArgs
.frameName
.toLower() == "_top" )
1714 while ( p
->parentPart() )
1715 p
= p
->parentPart();
1716 Window::retrieveWindow(p
)->goURL(exec
, url
.url(), false /*don't lock history*/);
1717 return Window::retrieve(p
);
1719 if ( browserArgs
.frameName
.toLower() == "_parent" )
1721 if ( p
->parentPart() )
1722 p
= p
->parentPart();
1723 Window::retrieveWindow(p
)->goURL(exec
, url
.url(), false /*don't lock history*/);
1724 return Window::retrieve(p
);
1726 if ( browserArgs
.frameName
.toLower() == "_self")
1728 Window::retrieveWindow(p
)->goURL(exec
, url
.url(), false /*don't lock history*/);
1729 return Window::retrieve(p
);
1731 if ( browserArgs
.frameName
.toLower() == "replace" )
1733 Window::retrieveWindow(p
)->goURL(exec
, url
.url(), true /*lock history*/);
1734 return Window::retrieve(p
);
1736 args
.setMimeType("text/html");
1737 args
.setActionRequestedByUser(false);
1739 // request window (new or existing if framename is set)
1740 KParts::ReadOnlyPart
*newPart
= 0;
1741 emit p
->browserExtension()->createNewWindow(KUrl(), args
, browserArgs
, winargs
, &newPart
);
1742 if (newPart
&& qobject_cast
<KHTMLPart
*>(newPart
)) {
1743 KHTMLPart
*khtmlpart
= static_cast<KHTMLPart
*>(newPart
);
1744 //qDebug("opener set to %p (this Window's part) in new Window %p (this Window=%p)",part,win,window);
1745 khtmlpart
->setOpener(p
);
1746 khtmlpart
->setOpenedByJS(true);
1747 if (khtmlpart
->document().isNull()) {
1749 khtmlpart
->write("<HTML><BODY>");
1751 if ( p
->docImpl() ) {
1752 //kDebug(6070) << "Setting domain to " << p->docImpl()->domain().string();
1753 khtmlpart
->docImpl()->setDomain( p
->docImpl()->domain());
1754 khtmlpart
->docImpl()->setBaseURL( p
->docImpl()->baseURL() );
1757 args
.setMimeType(QString());
1758 if (browserArgs
.frameName
.toLower() == "_blank")
1759 browserArgs
.frameName
.clear();
1761 emit khtmlpart
->browserExtension()->openUrlRequest(url
, args
, browserArgs
);
1762 return Window::retrieve(khtmlpart
); // global object
1764 return jsUndefined();
1767 void Window::forgetSuppressedWindows()
1769 m_suppressedWindowInfo
.clear();
1772 void Window::showSuppressedWindows()
1774 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(m_frame
->m_part
);
1775 KJS::Interpreter
*interpreter
= part
->jScript()->interpreter();
1776 ExecState
*exec
= interpreter
->globalExec();
1778 QList
<SuppressedWindowInfo
> suppressedWindowInfo
= m_suppressedWindowInfo
;
1779 m_suppressedWindowInfo
.clear();
1780 foreach ( const SuppressedWindowInfo
&info
, suppressedWindowInfo
) {
1781 executeOpenWindow(exec
, info
.url
, info
.frameName
, info
.features
);
1785 JSValue
*WindowFunc::callAsFunction(ExecState
*exec
, JSObject
*thisObj
, const List
&args
)
1787 KJS_CHECK_THIS( Window
, thisObj
);
1789 // these should work no matter whether the window is already
1791 if (id
== Window::ValueOf
|| id
== Window::ToString
) {
1792 return jsString("[object Window]");
1795 Window
*window
= static_cast<Window
*>(thisObj
);
1798 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(window
->m_frame
->m_part
);
1800 return jsUndefined();
1802 KHTMLView
*widget
= part
->view();
1803 JSValue
*v
= args
[0];
1805 if (!v
->isUndefinedOrNull()) {
1806 s
= v
->toString(exec
);
1811 if (part
&& !part
->url().host().isEmpty())
1812 caption
= part
->url().host() + " - ";
1813 caption
+= "JavaScript"; // TODO: i18n
1814 // functions that work everywhere
1816 case Window::Alert
: {
1817 TimerPauser
pause(exec
);
1818 if (!widget
->dialogsAllowed())
1819 return jsUndefined();
1820 if ( part
&& part
->xmlDocImpl() )
1821 part
->xmlDocImpl()->updateRendering();
1823 emit part
->browserExtension()->requestFocus(part
);
1824 KMessageBox::error(widget
, Qt::convertFromPlainText(str
, Qt::WhiteSpaceNormal
), caption
);
1825 return jsUndefined();
1827 case Window::Confirm
: {
1828 TimerPauser
pause(exec
);
1829 if (!widget
->dialogsAllowed())
1830 return jsUndefined();
1831 if ( part
&& part
->xmlDocImpl() )
1832 part
->xmlDocImpl()->updateRendering();
1834 emit part
->browserExtension()->requestFocus(part
);
1835 return jsBoolean((KMessageBox::warningYesNo(widget
, Qt::convertFromPlainText(str
), caption
,
1836 KStandardGuiItem::ok(), KStandardGuiItem::cancel()) == KMessageBox::Yes
));
1838 case Window::Prompt
: {
1839 TimerPauser
pause(exec
);
1840 #ifndef KONQ_EMBEDDED
1841 if (!widget
->dialogsAllowed())
1842 return jsUndefined();
1843 if ( part
&& part
->xmlDocImpl() )
1844 part
->xmlDocImpl()->updateRendering();
1846 emit part
->browserExtension()->requestFocus(part
);
1848 if (args
.size() >= 2)
1849 str2
= KInputDialog::getText(caption
,
1850 Qt::convertFromPlainText(str
),
1851 args
[1]->toString(exec
).qstring(), &ok
, widget
);
1853 str2
= KInputDialog::getText(caption
,
1854 Qt::convertFromPlainText(str
),
1855 QString(), &ok
, widget
);
1857 return jsString(UString(str2
));
1861 return jsUndefined();
1864 case Window::GetComputedStyle
: {
1865 if ( !part
|| !part
->xmlDocImpl() )
1866 return jsUndefined();
1867 DOM::NodeImpl
* arg0
= toNode(args
[0]);
1868 if (!arg0
|| arg0
->nodeType() != DOM::Node::ELEMENT_NODE
)
1869 return jsUndefined(); // throw exception?
1871 return getDOMCSSStyleDeclaration(exec
, part
->xmlDocImpl()->defaultView()->getComputedStyle(
1872 static_cast<DOM::ElementImpl
*>(arg0
), args
[1]->toString(exec
).domString().implementation()));
1875 return window
->openWindow(exec
, args
);
1876 case Window::Close
: {
1877 /* From http://developer.netscape.com/docs/manuals/js/client/jsref/window.htm :
1878 The close method closes only windows opened by JavaScript using the open method.
1879 If you attempt to close any other window, a confirm is generated, which
1880 lets the user choose whether the window closes.
1881 This is a security feature to prevent "mail bombs" containing self.close().
1882 However, if the window has only one document (the current one) in its
1883 session history, the close is allowed without any confirm. This is a
1884 special case for one-off windows that need to open other windows and
1885 then dispose of themselves.
1887 bool doClose
= false;
1888 if (!part
->openedByJS())
1890 // To conform to the SPEC, we only ask if the window
1891 // has more than one entry in the history (NS does that too).
1892 History
history(exec
,part
);
1894 if ( history
.get( exec
, "length" )->toInt32(exec
) <= 1 )
1900 // Can we get this dialog with tabs??? Does it close the window or the tab in that case?
1901 emit part
->browserExtension()->requestFocus(part
);
1902 if ( KMessageBox::questionYesNo( window
->part()->widget(),
1903 i18n("Close window?"), i18n("Confirmation Required"),
1904 KStandardGuiItem::close(), KStandardGuiItem::cancel() )
1905 == KMessageBox::Yes
)
1914 // If this is the current window (the one the interpreter runs in),
1915 // then schedule a delayed close (so that the script terminates first).
1916 // But otherwise, close immediately. This fixes w=window.open("","name");w.close();window.open("name");
1917 if ( Window::retrieveActive(exec
) == window
) {
1919 // quit all dialogs of this view
1920 // this fixes 'setTimeout('self.close()',1000); alert("Hi");' crash
1921 widget
->closeChildDialogs();
1923 //kDebug() << "scheduling delayed close";
1924 // We'll close the window at the end of the script execution
1925 Window
* w
= const_cast<Window
*>(window
);
1926 w
->m_delayed
.append( Window::DelayedAction( Window::DelayedClose
) );
1928 //kDebug() << "closing NOW";
1929 (const_cast<Window
*>(window
))->closeNow();
1932 return jsUndefined();
1934 case Window::Navigate
:
1935 window
->goURL(exec
, args
[0]->toString(exec
).qstring(), false /*don't lock history*/);
1936 return jsUndefined();
1937 case Window::Focus
: {
1938 KHTMLSettings::KJSWindowFocusPolicy policy
=
1939 part
->settings()->windowFocusPolicy(part
->url().host());
1940 if(policy
== KHTMLSettings::KJSWindowFocusAllow
&& widget
) {
1941 widget
->topLevelWidget()->raise();
1943 KWindowSystem::unminimizeWindow( widget
->topLevelWidget()->winId() );
1947 widget
->activateWindow();
1948 emit part
->browserExtension()->requestFocus(part
);
1950 return jsUndefined();
1954 return jsUndefined();
1956 case Window::AToB
: {
1958 return jsUndefined();
1960 char *binData
= s
.ascii();
1961 in
= QByteArray( binData
, s
.size() );
1962 if (id
== Window::AToB
)
1963 out
= QByteArray::fromBase64(in
);
1965 out
= in
.toBase64();
1966 UChar
*d
= new UChar
[out
.size()];
1967 for (int i
= 0; i
< out
.size(); i
++)
1968 d
[i
].uc
= (uchar
) out
[i
];
1969 UString
ret(d
, out
.size(), false /*no copy*/);
1970 return jsString(ret
);
1976 // now unsafe functions..
1977 if (!window
->isSafeScript(exec
))
1978 return jsUndefined();
1981 case Window::ScrollBy
:
1982 if(args
.size() == 2 && widget
)
1983 widget
->scrollBy(args
[0]->toInt32(exec
), args
[1]->toInt32(exec
));
1984 return jsUndefined();
1985 case Window::Scroll
:
1986 case Window::ScrollTo
:
1987 if(args
.size() == 2 && widget
)
1988 widget
->setContentsPos(args
[0]->toInt32(exec
), args
[1]->toInt32(exec
));
1989 return jsUndefined();
1990 case Window::MoveBy
: {
1991 KHTMLSettings::KJSWindowMovePolicy policy
=
1992 part
->settings()->windowMovePolicy(part
->url().host());
1993 if(policy
== KHTMLSettings::KJSWindowMoveAllow
&& args
.size() == 2 && widget
)
1995 KParts::BrowserExtension
*ext
= part
->browserExtension();
1997 QWidget
* tl
= widget
->topLevelWidget();
1998 QRect sg
= KGlobalSettings::desktopGeometry(tl
);
2000 QPoint dest
= tl
->pos() + QPoint( args
[0]->toInt32(exec
), args
[1]->toInt32(exec
) );
2001 // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
2002 if ( dest
.x() >= sg
.x() && dest
.y() >= sg
.x() &&
2003 dest
.x()+tl
->width() <= sg
.width()+sg
.x() &&
2004 dest
.y()+tl
->height() <= sg
.height()+sg
.y() )
2005 emit ext
->moveTopLevelWidget( dest
.x(), dest
.y() );
2008 return jsUndefined();
2010 case Window::MoveTo
: {
2011 KHTMLSettings::KJSWindowMovePolicy policy
=
2012 part
->settings()->windowMovePolicy(part
->url().host());
2013 if(policy
== KHTMLSettings::KJSWindowMoveAllow
&& args
.size() == 2 && widget
)
2015 KParts::BrowserExtension
*ext
= part
->browserExtension();
2017 QWidget
* tl
= widget
->topLevelWidget();
2018 QRect sg
= KGlobalSettings::desktopGeometry(tl
);
2020 QPoint
dest( args
[0]->toInt32(exec
)+sg
.x(), args
[1]->toInt32(exec
)+sg
.y() );
2021 // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
2022 if ( dest
.x() >= sg
.x() && dest
.y() >= sg
.y() &&
2023 dest
.x()+tl
->width() <= sg
.width()+sg
.x() &&
2024 dest
.y()+tl
->height() <= sg
.height()+sg
.y() )
2025 emit ext
->moveTopLevelWidget( dest
.x(), dest
.y() );
2028 return jsUndefined();
2030 case Window::ResizeBy
: {
2031 KHTMLSettings::KJSWindowResizePolicy policy
=
2032 part
->settings()->windowResizePolicy(part
->url().host());
2033 if(policy
== KHTMLSettings::KJSWindowResizeAllow
2034 && args
.size() == 2 && widget
)
2036 QWidget
* tl
= widget
->topLevelWidget();
2037 QRect geom
= tl
->frameGeometry();
2038 window
->resizeTo( tl
,
2039 geom
.width() + args
[0]->toInt32(exec
),
2040 geom
.height() + args
[1]->toInt32(exec
) );
2042 return jsUndefined();
2044 case Window::ResizeTo
: {
2045 KHTMLSettings::KJSWindowResizePolicy policy
=
2046 part
->settings()->windowResizePolicy(part
->url().host());
2047 if(policy
== KHTMLSettings::KJSWindowResizeAllow
2048 && args
.size() == 2 && widget
)
2050 QWidget
* tl
= widget
->topLevelWidget();
2051 window
->resizeTo( tl
, args
[0]->toInt32(exec
), args
[1]->toInt32(exec
) );
2053 return jsUndefined();
2055 case Window::SetTimeout
:
2056 case Window::SetInterval
: {
2058 int i
; // timeout interval
2059 if (args
.size() == 0)
2060 return jsUndefined();
2061 if (args
.size() > 1) {
2062 singleShot
= (id
== Window::SetTimeout
);
2063 i
= args
[1]->toInt32(exec
);
2065 // second parameter is missing. Emulate Mozilla behavior.
2069 if (v
->type() == StringType
) {
2070 int r
= (const_cast<Window
*>(window
))->winq
->installTimeout(Identifier(s
), i
, singleShot
);
2073 else if (v
->type() == ObjectType
&& v
->getObject()->implementsCall()) {
2074 JSObject
*func
= v
->getObject();
2076 ListIterator it
= args
.begin();
2078 while (it
!= args
.end()) {
2079 JSValue
*arg
= it
++;
2081 funcArgs
.append(arg
);
2083 if (args
.size() < 2)
2084 funcArgs
.append(jsNumber(i
));
2085 int r
= (const_cast<Window
*>(window
))->winq
->installTimeout(func
, funcArgs
, i
, singleShot
);
2089 return jsUndefined();
2091 case Window::ClearTimeout
:
2092 case Window::ClearInterval
:
2093 (const_cast<Window
*>(window
))->winq
->clearTimeout(v
->toInt32(exec
));
2094 return jsUndefined();
2097 // ### TODO emit onbeforeprint event
2099 // ### TODO emit onafterprint event
2101 case Window::CaptureEvents
:
2102 case Window::ReleaseEvents
:
2103 // Do nothing for now. These are NS-specific legacy calls.
2105 case Window::AddEventListener
: {
2106 JSEventListener
*listener
= Window::retrieveActive(exec
)->getJSEventListener(args
[1]);
2108 DOM::DocumentImpl
* docimpl
= static_cast<DOM::DocumentImpl
*>(part
->document().handle());
2109 docimpl
->addWindowEventListener(EventName::fromString(args
[0]->toString(exec
).domString()),listener
,args
[2]->toBoolean(exec
));
2111 return jsUndefined();
2113 case Window::RemoveEventListener
: {
2114 JSEventListener
*listener
= Window::retrieveActive(exec
)->getJSEventListener(args
[1]);
2116 DOM::DocumentImpl
* docimpl
= static_cast<DOM::DocumentImpl
*>(part
->document().handle());
2117 docimpl
->removeWindowEventListener(EventName::fromString(args
[0]->toString(exec
).domString()),listener
,args
[2]->toBoolean(exec
));
2119 return jsUndefined();
2123 return jsUndefined();
2126 ////////////////////// ScheduledAction ////////////////////////
2128 // KDE 4: Make those parameters const ... &
2129 ScheduledAction::ScheduledAction(JSObject
* _func
, List _args
, DateTimeMS _nextTime
, int _interval
, bool _singleShot
,
2132 //kDebug(6070) << "ScheduledAction::ScheduledAction(isFunction) " << this;
2133 func
= static_cast<JSObject
*>(_func
);
2136 singleShot
= _singleShot
;
2137 nextTime
= _nextTime
;
2138 interval
= _interval
;
2143 // KDE 4: Make it const QString &
2144 ScheduledAction::ScheduledAction(QString _code
, DateTimeMS _nextTime
, int _interval
, bool _singleShot
, int _timerId
)
2146 //kDebug(6070) << "ScheduledAction::ScheduledAction(!isFunction) " << this;
2152 singleShot
= _singleShot
;
2153 nextTime
= _nextTime
;
2154 interval
= _interval
;
2159 bool ScheduledAction::execute(Window
*window
)
2161 KHTMLPart
*part
= qobject_cast
<KHTMLPart
*>(window
->m_frame
->m_part
);
2162 if (!part
|| !part
->jScriptEnabled())
2164 ScriptInterpreter
*interpreter
= static_cast<ScriptInterpreter
*>(part
->jScript()->interpreter());
2166 interpreter
->setProcessingTimerCallback(true);
2168 //kDebug(6070) << "ScheduledAction::execute " << this;
2170 if (func
->implementsCall()) {
2175 KJS::Interpreter
*interpreter
= part
->jScript()->interpreter();
2176 ExecState
*exec
= interpreter
->globalExec();
2177 Q_ASSERT( window
== interpreter
->globalObject() );
2178 JSObject
*obj( window
);
2179 func
->call(exec
,obj
,args
); // note that call() creates its own execution state for the func call
2180 if (exec
->hadException())
2181 exec
->clearException();
2183 // Update our document's rendering following the execution of the timeout callback.
2184 part
->document().updateRendering();
2189 part
->executeScript(DOM::Node(), code
);
2192 interpreter
->setProcessingTimerCallback(false);
2196 void ScheduledAction::mark()
2198 if (func
&& !func
->marked())
2202 ScheduledAction::~ScheduledAction()
2205 //kDebug(6070) << "ScheduledAction::~ScheduledAction " << this;
2208 ////////////////////// WindowQObject ////////////////////////
2210 WindowQObject::WindowQObject(Window
*w
)
2213 //kDebug(6070) << "WindowQObject::WindowQObject " << this;
2214 if ( !parent
->m_frame
)
2215 kDebug(6070) << "WARNING: null part in " ;
2217 connect( parent
->m_frame
, SIGNAL( destroyed() ),
2218 this, SLOT( parentDestroyed() ) );
2221 currentlyDispatching
= false;
2224 WindowQObject::~WindowQObject()
2226 //kDebug(6070) << "WindowQObject::~WindowQObject " << this;
2227 parentDestroyed(); // reuse same code
2230 void WindowQObject::parentDestroyed()
2234 while (!scheduledActions
.isEmpty())
2235 delete scheduledActions
.takeFirst();
2236 scheduledActions
.clear();
2239 void WindowQObject::pauseTimers()
2242 if (pauseLevel
== 1)
2243 pauseStart
= DateTimeMS::now();
2246 void WindowQObject::resumeTimers()
2249 if (pauseLevel
== 0) {
2250 // Adjust all timers by the delay length, making sure there is a minimum
2251 // margin from current time, however, so we don't go stampeding off if
2252 // there is some unwanted recursion, etc.
2253 DateTimeMS curTime
= DateTimeMS::now();
2254 DateTimeMS earliestDispatch
= curTime
.addMSecs(5);
2255 int delay
= pauseStart
.msecsTo(curTime
);
2256 foreach (ScheduledAction
*action
, scheduledActions
) {
2257 action
->nextTime
= action
->nextTime
.addMSecs(delay
);
2258 if (earliestDispatch
> action
->nextTime
)
2259 action
->nextTime
= earliestDispatch
;
2262 // Dispatch any timers that may have been ignored if ::timerEvent fell in the middle
2268 int WindowQObject::installTimeout(const Identifier
&handler
, int t
, bool singleShot
)
2270 int id
= ++lastTimerId
;
2272 DateTimeMS nextTime
= DateTimeMS::now().addMSecs(t
);
2274 ScheduledAction
*action
= new ScheduledAction(handler
.qstring(),nextTime
,t
,singleShot
,id
);
2275 scheduledActions
.append(action
);
2280 int WindowQObject::installTimeout(JSValue
*func
, List args
, int t
, bool singleShot
)
2282 JSObject
*objFunc
= func
->getObject();
2285 int id
= ++lastTimerId
;
2288 DateTimeMS nextTime
= DateTimeMS::now().addMSecs(t
);
2289 ScheduledAction
*action
= new ScheduledAction(objFunc
,args
,nextTime
,t
,singleShot
,id
);
2290 scheduledActions
.append(action
);
2295 void WindowQObject::clearTimeout(int timerId
)
2297 foreach (ScheduledAction
*action
, scheduledActions
)
2299 if (action
->timerId
== timerId
)
2301 scheduledActions
.removeAll(action
);
2302 if (!action
->executing
)
2309 bool WindowQObject::hasTimers() const
2311 return scheduledActions
.count();
2314 void WindowQObject::mark()
2316 foreach (ScheduledAction
*action
, scheduledActions
)
2322 void WindowQObject::timerEvent(QTimerEvent
*)
2326 if (scheduledActions
.isEmpty())
2332 currentlyDispatching
= true;
2335 DateTimeMS current
= DateTimeMS::now();
2337 // Work out which actions are to be executed. We take a separate copy of
2338 // this list since the main one may be modified during action execution
2339 QList
<ScheduledAction
*> toExecute
;
2340 foreach (ScheduledAction
*action
, scheduledActions
)
2342 if (current
>= action
->nextTime
)
2343 toExecute
.append(action
);
2346 // ### verify that the window can't be closed (and action deleted) during execution
2347 foreach (ScheduledAction
*action
, toExecute
)
2349 if (!scheduledActions
.count(action
)) // removed by clearTimeout()
2352 action
->executing
= true; // prevent deletion in clearTimeout()
2354 if (parent
->part()) {
2355 bool ok
= action
->execute(parent
);
2356 if ( !ok
) // e.g. JS disabled
2357 scheduledActions
.removeAll( action
);
2360 if (action
->singleShot
)
2361 scheduledActions
.removeAll(action
);
2363 action
->executing
= false;
2365 if (!scheduledActions
.count(action
))
2368 action
->nextTime
= action
->nextTime
.addMSecs(action
->interval
);
2371 currentlyDispatching
= false;
2373 // Work out when next event is to occur
2377 DateTimeMS
DateTimeMS::addMSecs(int s
) const
2379 DateTimeMS c
= *this;
2380 c
.mTime
= mTime
.addMSecs(s
);
2383 if (c
.mTime
< mTime
)
2384 c
.mDate
= mDate
.addDays(1);
2388 if (c
.mTime
> mTime
)
2389 c
.mDate
= mDate
.addDays(-1);
2394 bool DateTimeMS::operator >(const DateTimeMS
&other
) const
2396 if (mDate
> other
.mDate
)
2399 if (mDate
< other
.mDate
)
2402 return mTime
> other
.mTime
;
2405 bool DateTimeMS::operator >=(const DateTimeMS
&other
) const
2407 if (mDate
> other
.mDate
)
2410 if (mDate
< other
.mDate
)
2413 return mTime
>= other
.mTime
;
2416 int DateTimeMS::msecsTo(const DateTimeMS
&other
) const
2418 int d
= mDate
.daysTo(other
.mDate
);
2419 int ms
= mTime
.msecsTo(other
.mTime
);
2420 return d
*24*60*60*1000 + ms
;
2424 DateTimeMS
DateTimeMS::now()
2427 QTime before
= QTime::currentTime();
2428 t
.mDate
= QDate::currentDate();
2429 t
.mTime
= QTime::currentTime();
2430 if (t
.mTime
< before
)
2431 t
.mDate
= QDate::currentDate(); // prevent race condition in hacky way :)
2435 void WindowQObject::setNextTimer()
2437 if (currentlyDispatching
)
2438 return; // Will schedule at the end
2440 if (scheduledActions
.isEmpty())
2443 QListIterator
<ScheduledAction
*> it(scheduledActions
);
2444 DateTimeMS nextTime
= it
.next()->nextTime
;
2445 while (it
.hasNext())
2447 const DateTimeMS
& currTime
= it
.next()->nextTime
;
2448 if (nextTime
> currTime
)
2449 nextTime
= currTime
;
2453 int nextInterval
= DateTimeMS::now().msecsTo(nextTime
);
2454 if (nextInterval
< 0)
2456 timerIds
.append(startTimer(nextInterval
));
2459 void WindowQObject::killTimers()
2461 for (int i
= 0; i
< timerIds
.size(); ++i
)
2463 killTimer(timerIds
.at(i
));
2468 void WindowQObject::timeoutClose()
2473 ////////////////////// Location Object ////////////////////////
2475 const ClassInfo
Location::info
= { "Location", 0, &LocationTable
, 0 };
2477 @begin LocationTable 11
2478 hash Location::Hash DontDelete
2479 host Location::Host DontDelete
2480 hostname Location::Hostname DontDelete
2481 href Location::Href DontDelete
2482 pathname Location::Pathname DontDelete
2483 port Location::Port DontDelete
2484 protocol Location::Protocol DontDelete
2485 search Location::Search DontDelete
2486 [[==]] Location::EqualEqual DontDelete|ReadOnly
2487 assign Location::Assign DontDelete|Function 1
2488 toString Location::ToString DontDelete|Function 0
2489 replace Location::Replace DontDelete|Function 1
2490 reload Location::Reload DontDelete|Function 0
2493 KJS_IMPLEMENT_PROTOFUNC(LocationFunc
)
2494 Location::Location(khtml::ChildFrame
*f
) : m_frame(f
)
2496 //kDebug(6070) << "Location::Location " << this << " m_part=" << (void*)m_part;
2499 Location::~Location()
2501 //kDebug(6070) << "Location::~Location " << this << " m_part=" << (void*)m_part;
2504 KParts::ReadOnlyPart
*Location::part() const {
2505 return m_frame
? static_cast<KParts::ReadOnlyPart
*>(m_frame
->m_part
) : 0L;
2508 bool Location::getOwnPropertySlot(ExecState
*exec
, const Identifier
&p
, PropertySlot
& slot
)
2511 kDebug(6070) << "Location::getOwnPropertySlot " << p
.qstring() << " m_part=" << (void*)m_frame
->m_part
;
2514 if (m_frame
.isNull() || m_frame
->m_part
.isNull())
2515 return jsUndefined();
2517 const HashEntry
*entry
= Lookup::findEntry(&LocationTable
, p
);
2520 // properties that work on all Location objects
2521 if (entry
->value
== Replace
) {
2522 getSlotFromEntry
<LocationFunc
, Location
>(entry
, this, slot
);
2527 const Window
* window
= Window::retrieveWindow( m_frame
->m_part
);
2528 if ( !window
|| !window
->isSafeScript(exec
) ) {
2529 slot
.setUndefined(this);
2533 // XSS check passed - can now dispatch normally.
2534 getSlotFromEntry
<LocationFunc
, Location
>(entry
, this, slot
);
2538 return JSObject::getOwnPropertySlot(exec
, p
, slot
);
2541 JSValue
* Location::getValueProperty(ExecState
*exec
, int token
) const
2543 KUrl url
= m_frame
->m_part
->url();
2546 return jsString( UString(url
.htmlRef().isNull() ? QString("") : '#' + url
.htmlRef()) );
2548 UString str
= url
.host();
2550 str
= str
+ QString(":") + QString::number((int)url
.port());
2551 return jsString(str
);
2552 // Note: this is the IE spec. The NS spec swaps the two, it says
2553 // "The hostname property is the concatenation of the host and port properties, separated by a colon."
2557 return jsString( UString(url
.host()) );
2560 return jsString("about:blank");
2561 else if (!url
.hasPath())
2562 return jsString( UString(url
.prettyUrl()+'/') );
2564 return jsString( UString(url
.prettyUrl()) );
2567 return jsString("");
2568 return jsString( UString(url
.path().isEmpty() ? QString("/") : url
.path()) );
2570 return jsString( UString(url
.port() > 0 ? QString::number((int)url
.port()) : QLatin1String("")) );
2572 return jsString( UString(url
.protocol()+':') );
2574 return jsString( UString(url
.query()) );
2575 case EqualEqual
: // [[==]]
2576 return jsString(toString(exec
));
2578 return jsUndefined();
2581 void Location::put(ExecState
*exec
, const Identifier
&p
, JSValue
*v
, int attr
)
2584 kDebug(6070) << "Location::put " << p
.qstring() << " m_part=" << (void*)m_frame
->m_part
;
2586 if (m_frame
.isNull() || m_frame
->m_part
.isNull())
2589 const Window
* window
= Window::retrieveWindow( m_frame
->m_part
);
2593 KUrl url
= m_frame
->m_part
->url();
2595 const HashEntry
*entry
= Lookup::findEntry(&LocationTable
, p
);
2599 // XSS check. Only new hrefs can be set from other sites
2600 if (entry
->value
!= Href
&& !window
->isSafeScript(exec
))
2603 QString str
= v
->toString(exec
).qstring();
2604 switch (entry
->value
) {
2606 KHTMLPart
* p
=qobject_cast
<KHTMLPart
*>(Window::retrieveActive(exec
)->part());
2608 url
= p
->htmlDocument().completeURL( str
).string();
2614 // Strip any leading # --- setting hash to #foo is the same as setting it to foo.
2615 if (str
.startsWith(QLatin1Char('#')))
2618 // Note that we want to do gotoAnchor even when the hash is already set, so we
2619 // scroll the destination into view
2623 QString host
= str
.left(str
.indexOf(":"));
2624 QString port
= str
.mid(str
.indexOf(":")+1);
2626 url
.setPort(port
.toUInt());
2636 url
.setPort(str
.toUInt());
2639 url
.setProtocol(str
);
2646 JSObject::put(exec
, p
, v
, attr
);
2650 Window::retrieveWindow(m_frame
->m_part
)->goURL(exec
, url
.url(), false /* don't lock history*/ );
2653 JSValue
*Location::toPrimitive(ExecState
*exec
, JSType
) const
2656 Window
* window
= Window::retrieveWindow( m_frame
->m_part
);
2657 if ( window
&& window
->isSafeScript(exec
) )
2658 return jsString(toString(exec
));
2660 return jsUndefined();
2663 UString
Location::toString(ExecState
*exec
) const
2666 Window
* window
= Window::retrieveWindow( m_frame
->m_part
);
2667 if ( window
&& window
->isSafeScript(exec
) )
2669 KUrl url
= m_frame
->m_part
->url();
2671 return "about:blank";
2672 else if (!url
.hasPath())
2673 return url
.prettyUrl()+'/';
2675 return url
.prettyUrl();
2681 JSValue
*LocationFunc::callAsFunction(ExecState
*exec
, JSObject
*thisObj
, const List
&args
)
2683 KJS_CHECK_THIS( Location
, thisObj
);
2684 Location
*location
= static_cast<Location
*>(thisObj
);
2685 KParts::ReadOnlyPart
*part
= location
->part();
2687 if (!part
) return jsUndefined();
2689 Window
* window
= Window::retrieveWindow(part
);
2691 if ( !window
->isSafeScript(exec
) && id
!= Location::Replace
)
2692 return jsUndefined();
2695 case Location::Assign
:
2696 case Location::Replace
:
2697 Window::retrieveWindow(part
)->goURL(exec
, args
[0]->toString(exec
).qstring(),
2698 id
== Location::Replace
);
2700 case Location::Reload
: {
2701 KHTMLPart
*khtmlpart
= qobject_cast
<KHTMLPart
*>(part
);
2703 khtmlpart
->scheduleRedirection(-1, part
->url().url(), true/*lock history*/);
2705 part
->openUrl(part
->url());
2708 case Location::ToString
:
2709 return jsString(location
->toString(exec
));
2711 return jsUndefined();
2714 ////////////////////// External Object ////////////////////////
2716 const ClassInfo
External::info
= { "External", 0, 0, 0 };
2718 @begin ExternalTable 4
2719 addFavorite External::AddFavorite DontDelete|Function 1
2722 KJS_IMPLEMENT_PROTOFUNC(ExternalFunc
)
2724 bool External::getOwnPropertySlot(ExecState
*exec
, const Identifier
&p
, PropertySlot
& propertySlot
)
2726 return getStaticFunctionSlot
<ExternalFunc
,JSObject
>(exec
, &ExternalTable
, this, p
, propertySlot
);
2729 JSValue
*ExternalFunc::callAsFunction(ExecState
*exec
, JSObject
*thisObj
, const List
&args
)
2731 KJS_CHECK_THIS( External
, thisObj
);
2732 External
*external
= static_cast<External
*>(thisObj
);
2734 KHTMLPart
*part
= external
->part
;
2736 return jsUndefined();
2738 KHTMLView
*widget
= part
->view();
2741 case External::AddFavorite
:
2743 #ifndef KONQ_EMBEDDED
2744 if (!widget
->dialogsAllowed())
2745 return jsUndefined();
2746 part
->xmlDocImpl()->updateRendering();
2747 if (args
.size() != 1 && args
.size() != 2)
2748 return jsUndefined();
2750 QString url
= args
[0]->toString(exec
).qstring();
2752 if (args
.size() == 2)
2753 title
= args
[1]->toString(exec
).qstring();
2755 // AK - don't do anything yet, for the moment i
2756 // just wanted the base js handling code in cvs
2757 return jsUndefined();
2760 if ( title
.isEmpty() )
2761 question
= i18n("Do you want a bookmark pointing to the location \"%1\" to be added to your collection?",
2764 question
= i18n("Do you want a bookmark pointing to the location \"%1\" titled \"%2\" to be added to your collection?",
2767 emit part
->browserExtension()->requestFocus(part
);
2770 if (!part
->url().host().isEmpty())
2771 caption
= part
->url().host() + " - ";
2772 caption
+= i18n("JavaScript Attempted Bookmark Insert");
2774 if (KMessageBox::warningYesNo(
2775 widget
, question
, caption
,
2776 KGuiItem(i18n("Insert")), KGuiItem(i18n("Disallow"))) == KMessageBox::Yes
)
2778 KBookmarkManager
*mgr
= KBookmarkManager::userBookmarksManager();
2779 KBookmarkDialog
dlg(mgr
, 0);
2780 dlg
.addBookmark(title
, url
);
2783 return jsUndefined();
2788 return jsUndefined();
2791 return jsUndefined();
2794 ////////////////////// History Object ////////////////////////
2796 const ClassInfo
History::info
= { "History", 0, 0, 0 };
2798 @begin HistoryTable 4
2799 length History::Length DontDelete|ReadOnly
2800 back History::Back DontDelete|Function 0
2801 forward History::Forward DontDelete|Function 0
2802 go History::Go DontDelete|Function 1
2805 KJS_IMPLEMENT_PROTOFUNC(HistoryFunc
)
2807 bool History::getOwnPropertySlot(ExecState
*exec
, const Identifier
&p
, PropertySlot
& slot
)
2809 return getStaticPropertySlot
<HistoryFunc
,History
,JSObject
>(exec
, &HistoryTable
, this, p
, slot
);
2812 JSValue
*History::getValueProperty(ExecState
*, int token
) const
2814 // if previous or next is implemented, make sure its not a major
2815 // privacy leak (see i.e. http://security.greymagic.com/adv/gm005-op/)
2820 return jsNumber( 0 );
2822 KParts::BrowserExtension
*ext
= part
->browserExtension();
2824 return jsNumber( 0 );
2826 KParts::BrowserInterface
*iface
= ext
->browserInterface();
2828 return jsNumber( 0 );
2830 QVariant length
= iface
->property( "historyLength" );
2832 if ( length
.type() != QVariant::UInt
)
2833 return jsNumber( 0 );
2835 return jsNumber( length
.toUInt() );
2838 kDebug(6070) << "WARNING: Unhandled token in History::getValueProperty : " << token
;
2839 return jsUndefined();
2843 JSValue
*HistoryFunc::callAsFunction(ExecState
*exec
, JSObject
*thisObj
, const List
&args
)
2845 KJS_CHECK_THIS( History
, thisObj
);
2846 History
*history
= static_cast<History
*>(thisObj
);
2848 JSValue
*v
= args
[0];
2851 n
= v
->toInteger(exec
);
2858 case History::Forward
:
2865 return jsUndefined();
2868 // Special case for go(0) from a frame -> reload only the frame
2869 // go(i!=0) from a frame navigates into the history of the frame only,
2870 // in both IE and NS (but not in Mozilla).... we can't easily do that
2872 if (!steps
) // add && history->part->parentPart() to get only frames, but doesn't matter
2874 history
->part
->openUrl( history
->part
->url() ); /// ## need args.reload=true?
2878 // Testcase: history.back(); alert("hello");
2879 Window
* window
= Window::retrieveWindow( history
->part
);
2880 window
->delayedGoHistory( steps
);
2882 return jsUndefined();
2888 #include "kjs_window.moc"