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) 2006 Jon Shier (jshier@iastate.edu)
6 * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "kjs_window.h"
27 #include "DOMWindow.h"
29 #include "EventListener.h"
30 #include "EventNames.h"
31 #include "FloatRect.h"
33 #include "FrameLoadRequest.h"
34 #include "FrameTree.h"
35 #include "HTMLDocument.h"
36 #include "JSCSSRule.h"
37 #include "JSCSSValue.h"
38 #include "JSDOMWindow.h"
40 #include "JSHTMLOptionElementConstructor.h"
41 #include "JSMutationEvent.h"
43 #include "JSNodeFilter.h"
45 #include "JSXMLHttpRequest.h"
49 #include "PlugInInfoStore.h"
50 #include "RenderView.h"
52 #include "SelectionController.h"
53 #include "htmlediting.h"
55 #include "kjs_events.h"
56 #include "kjs_navigator.h"
57 #include "kjs_proxy.h"
58 #include "kjs_traversal.h"
59 #include <wtf/MathExtras.h>
62 #include "JSXSLTProcessor.h"
65 using namespace WebCore;
66 using namespace EventNames;
70 static int lastUsedTimeoutId;
72 class DOMWindowTimer : public TimerBase {
74 DOMWindowTimer(int timeoutId, Window* o, ScheduledAction* a)
75 : m_timeoutId(timeoutId), m_object(o), m_action(a) { }
76 virtual ~DOMWindowTimer() { delete m_action; }
78 int timeoutId() const { return m_timeoutId; }
79 ScheduledAction* action() const { return m_action; }
80 ScheduledAction* takeAction() { ScheduledAction* a = m_action; m_action = 0; return a; }
87 ScheduledAction* m_action;
93 double nextFireInterval;
94 double repeatInterval;
95 ScheduledAction *action;
98 ////////////////////// History Object ////////////////////////
100 class History : public DOMObject {
101 friend class HistoryFunc;
103 History(ExecState *exec, Frame *f)
106 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
108 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
109 JSValue *getValueProperty(ExecState *exec, int token) const;
110 virtual const ClassInfo* classInfo() const { return &info; }
111 static const ClassInfo info;
112 enum { Back, Forward, Go, Length };
113 virtual UString toString(ExecState *exec) const;
114 void disconnectFrame() { m_frame = 0; }
120 class FrameArray : public DOMObject {
122 FrameArray(ExecState *exec, Frame *f)
125 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
127 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
128 JSValue *getValueProperty(ExecState *exec, int token);
129 virtual UString toString(ExecState *exec) const;
130 enum { Length, Location };
131 void disconnectFrame() { m_frame = 0; }
133 static JSValue *indexGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
134 static JSValue *nameGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
136 virtual const ClassInfo* classInfo() const { return &info; }
137 static const ClassInfo info;
144 #include "kjs_window.lut.h"
148 ////////////////////// Screen Object ////////////////////////
150 // table for screen object
153 height Screen::Height DontEnum|ReadOnly
154 width Screen::Width DontEnum|ReadOnly
155 colorDepth Screen::ColorDepth DontEnum|ReadOnly
156 pixelDepth Screen::PixelDepth DontEnum|ReadOnly
157 availLeft Screen::AvailLeft DontEnum|ReadOnly
158 availTop Screen::AvailTop DontEnum|ReadOnly
159 availHeight Screen::AvailHeight DontEnum|ReadOnly
160 availWidth Screen::AvailWidth DontEnum|ReadOnly
164 const ClassInfo Screen::info = { "Screen", 0, &ScreenTable, 0 };
166 // We set the object prototype so that toString is implemented
167 Screen::Screen(ExecState* exec, Frame* f)
170 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
173 bool Screen::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
175 return getStaticValueSlot<Screen, JSObject>(exec, &ScreenTable, this, propertyName, slot);
178 JSValue* Screen::getValueProperty(ExecState*, int token) const
180 Page* page = m_frame ? m_frame->page() : 0;
184 return jsNumber(screenRect(page).height());
186 return jsNumber(screenRect(page).width());
189 return jsNumber(screenDepth(page));
191 return jsNumber(usableScreenRect(page).x() - screenRect(page).x());
193 return jsNumber(usableScreenRect(page).y() - screenRect(page).y());
195 return jsNumber(usableScreenRect(page).height());
197 return jsNumber(usableScreenRect(page).width());
199 return jsUndefined();
203 ////////////////////// Window Object ////////////////////////
205 const ClassInfo Window::info = { "Window", 0, &WindowTable, 0 };
208 @begin WindowTable 103
209 closed Window::Closed DontDelete|ReadOnly
210 crypto Window::Crypto DontDelete|ReadOnly
211 defaultStatus Window::DefaultStatus DontDelete
212 defaultstatus Window::DefaultStatus DontDelete
213 status Window::Status DontDelete
214 DOMException Window::DOMException DontDelete
215 frames Window::Frames DontDelete|ReadOnly
216 history Window::History_ DontDelete|ReadOnly
217 event Window::Event_ DontDelete
218 innerHeight Window::InnerHeight DontDelete|ReadOnly
219 innerWidth Window::InnerWidth DontDelete|ReadOnly
220 length Window::Length DontDelete|ReadOnly
221 location Window::Location_ DontDelete
222 locationbar Window::Locationbar DontDelete
223 name Window::Name DontDelete
224 navigator Window::Navigator_ DontDelete|ReadOnly
225 clientInformation Window::ClientInformation DontDelete|ReadOnly
226 menubar Window::Menubar DontDelete|ReadOnly
227 offscreenBuffering Window::OffscreenBuffering DontDelete|ReadOnly
228 opener Window::Opener DontDelete|ReadOnly
229 outerHeight Window::OuterHeight DontDelete|ReadOnly
230 outerWidth Window::OuterWidth DontDelete|ReadOnly
231 pageXOffset Window::PageXOffset DontDelete|ReadOnly
232 pageYOffset Window::PageYOffset DontDelete|ReadOnly
233 parent Window::Parent DontDelete|ReadOnly
234 personalbar Window::Personalbar DontDelete|ReadOnly
235 screenX Window::ScreenX DontDelete|ReadOnly
236 screenY Window::ScreenY DontDelete|ReadOnly
237 screenLeft Window::ScreenLeft DontDelete|ReadOnly
238 screenTop Window::ScreenTop DontDelete|ReadOnly
239 scrollbars Window::Scrollbars DontDelete|ReadOnly
240 statusbar Window::Statusbar DontDelete|ReadOnly
241 toolbar Window::Toolbar DontDelete|ReadOnly
242 scroll Window::Scroll DontDelete|Function 2
243 scrollBy Window::ScrollBy DontDelete|Function 2
244 scrollTo Window::ScrollTo DontDelete|Function 2
245 scrollX Window::ScrollX DontDelete|ReadOnly
246 scrollY Window::ScrollY DontDelete|ReadOnly
247 moveBy Window::MoveBy DontDelete|Function 2
248 moveTo Window::MoveTo DontDelete|Function 2
249 resizeBy Window::ResizeBy DontDelete|Function 2
250 resizeTo Window::ResizeTo DontDelete|Function 2
251 self Window::Self DontDelete|ReadOnly
252 window Window::Window_ DontDelete|ReadOnly
253 top Window::Top DontDelete|ReadOnly
254 screen Window::Screen_ DontDelete|ReadOnly
255 Image Window::Image DontDelete
256 Option Window::Option DontDelete
257 XMLHttpRequest Window::XMLHttpRequest DontDelete
258 XSLTProcessor Window::XSLTProcessor_ DontDelete
259 alert Window::Alert DontDelete|Function 1
260 confirm Window::Confirm DontDelete|Function 1
261 prompt Window::Prompt DontDelete|Function 2
262 open Window::Open DontDelete|Function 3
263 print Window::Print DontDelete|Function 2
264 setTimeout Window::SetTimeout DontDelete|Function 2
265 clearTimeout Window::ClearTimeout DontDelete|Function 1
266 focus Window::Focus DontDelete|Function 0
267 getSelection Window::GetSelection DontDelete|Function 0
268 blur Window::Blur DontDelete|Function 0
269 close Window::Close DontDelete|Function 0
270 setInterval Window::SetInterval DontDelete|Function 2
271 clearInterval Window::ClearInterval DontDelete|Function 1
272 captureEvents Window::CaptureEvents DontDelete|Function 0
273 releaseEvents Window::ReleaseEvents DontDelete|Function 0
274 # Warning, when adding a function to this object you need to add a case in Window::get
275 addEventListener Window::AddEventListener DontDelete|Function 3
276 removeEventListener Window::RemoveEventListener DontDelete|Function 3
277 onabort Window::Onabort DontDelete
278 onblur Window::Onblur DontDelete
279 onchange Window::Onchange DontDelete
280 onclick Window::Onclick DontDelete
281 ondblclick Window::Ondblclick DontDelete
282 ondragdrop Window::Ondragdrop DontDelete
283 onerror Window::Onerror DontDelete
284 onfocus Window::Onfocus DontDelete
285 onkeydown Window::Onkeydown DontDelete
286 onkeypress Window::Onkeypress DontDelete
287 onkeyup Window::Onkeyup DontDelete
288 onload Window::Onload DontDelete
289 onmousedown Window::Onmousedown DontDelete
290 onmousemove Window::Onmousemove DontDelete
291 onmouseout Window::Onmouseout DontDelete
292 onmouseover Window::Onmouseover DontDelete
293 onmouseup Window::Onmouseup DontDelete
294 onmousewheel Window::OnWindowMouseWheel DontDelete
295 onmove Window::Onmove DontDelete
296 onreset Window::Onreset DontDelete
297 onresize Window::Onresize DontDelete
298 onscroll Window::Onscroll DontDelete
299 onsearch Window::Onsearch DontDelete
300 onselect Window::Onselect DontDelete
301 onsubmit Window::Onsubmit DontDelete
302 onunload Window::Onunload DontDelete
303 onbeforeunload Window::Onbeforeunload DontDelete
304 frameElement Window::FrameElement DontDelete|ReadOnly
305 showModalDialog Window::ShowModalDialog DontDelete|Function 1
308 KJS_IMPLEMENT_PROTOFUNC(WindowFunc)
310 Window::Window(DOMWindow* window)
311 : m_frame(window->frame())
324 , m_returnValueSlot(0)
332 // Clear any backpointers to the window
334 ListenersMap::iterator i2 = jsEventListeners.begin();
335 ListenersMap::iterator e2 = jsEventListeners.end();
336 for (; i2 != e2; ++i2)
337 i2->second->clearWindowObj();
338 i2 = jsHTMLEventListeners.begin();
339 e2 = jsHTMLEventListeners.end();
340 for (; i2 != e2; ++i2)
341 i2->second->clearWindowObj();
343 UnprotectedListenersMap::iterator i1 = jsUnprotectedEventListeners.begin();
344 UnprotectedListenersMap::iterator e1 = jsUnprotectedEventListeners.end();
345 for (; i1 != e1; ++i1)
346 i1->second->clearWindowObj();
347 i1 = jsUnprotectedHTMLEventListeners.begin();
348 e1 = jsUnprotectedHTMLEventListeners.end();
349 for (; i1 != e1; ++i1)
350 i1->second->clearWindowObj();
353 DOMWindow* Window::impl() const
355 return m_frame->domWindow();
358 ScriptInterpreter *Window::interpreter() const
360 return m_frame->jScript()->interpreter();
363 Window *Window::retrieveWindow(Frame *f)
365 JSObject *o = retrieve(f)->getObject();
367 ASSERT(o || !f->jScriptEnabled());
368 return static_cast<Window *>(o);
371 Window *Window::retrieveActive(ExecState *exec)
373 JSValue *imp = exec->dynamicInterpreter()->globalObject();
375 return static_cast<Window*>(imp);
378 JSValue *Window::retrieve(Frame *p)
381 if (KJSProxy *proxy = p->jScript())
382 return proxy->interpreter()->globalObject(); // the Global object is the "window"
384 return jsUndefined(); // This can happen with JS disabled on the domain of that window
387 Location *Window::location() const
390 loc = new Location(m_frame);
394 Selection *Window::selection() const
397 m_selection = new Selection(m_frame);
401 BarInfo *Window::locationbar(ExecState *exec) const
404 m_locationbar = new BarInfo(exec, m_frame, BarInfo::Locationbar);
405 return m_locationbar;
408 BarInfo *Window::menubar(ExecState *exec) const
411 m_menubar = new BarInfo(exec, m_frame, BarInfo::Menubar);
415 BarInfo *Window::personalbar(ExecState *exec) const
418 m_personalbar = new BarInfo(exec, m_frame, BarInfo::Personalbar);
419 return m_personalbar;
422 BarInfo *Window::statusbar(ExecState *exec) const
425 m_statusbar = new BarInfo(exec, m_frame, BarInfo::Statusbar);
429 BarInfo *Window::toolbar(ExecState *exec) const
432 m_toolbar = new BarInfo(exec, m_frame, BarInfo::Toolbar);
436 BarInfo *Window::scrollbars(ExecState *exec) const
439 m_scrollbars = new BarInfo(exec, m_frame, BarInfo::Scrollbars);
443 // reference our special objects during garbage collection
447 if (screen && !screen->marked())
449 if (history && !history->marked())
451 if (frames && !frames->marked())
453 if (loc && !loc->marked())
455 if (m_selection && !m_selection->marked())
457 if (m_locationbar && !m_locationbar->marked())
458 m_locationbar->mark();
459 if (m_menubar && !m_menubar->marked())
461 if (m_personalbar && !m_personalbar->marked())
462 m_personalbar->mark();
463 if (m_scrollbars && !m_scrollbars->marked())
464 m_scrollbars->mark();
465 if (m_statusbar && !m_statusbar->marked())
467 if (m_toolbar && !m_toolbar->marked())
471 UString Window::toString(ExecState *) const
473 return "[object Window]";
476 static bool allowPopUp(ExecState *exec, Window *window)
478 return window->frame()
479 && (window->frame()->settings()->JavaScriptCanOpenWindowsAutomatically()
480 || static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture());
483 static HashMap<String, String> parseModalDialogFeatures(ExecState *exec, JSValue *featuresArg)
485 HashMap<String, String> map;
487 Vector<String> features = String(featuresArg->toString(exec)).split(';');
488 Vector<String>::const_iterator end = features.end();
489 for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) {
491 int pos = s.find('=');
492 int colonPos = s.find(':');
493 if (pos >= 0 && colonPos >= 0)
494 continue; // ignore any strings that have both = and :
498 // null string for value means key without value
499 map.set(s.stripWhiteSpace().lower(), String());
501 String key = s.left(pos).stripWhiteSpace().lower();
502 String val = s.substring(pos + 1).stripWhiteSpace().lower();
503 int spacePos = val.find(' ');
505 val = val.left(spacePos);
513 static bool boolFeature(const HashMap<String, String>& features, const char* key, bool defaultValue = false)
515 HashMap<String, String>::const_iterator it = features.find(key);
516 if (it == features.end())
518 const String& value = it->second;
519 return value.isNull() || value == "1" || value == "yes" || value == "on";
522 static float floatFeature(const HashMap<String, String> &features, const char *key, float min, float max, float defaultValue)
524 HashMap<String, String>::const_iterator it = features.find(key);
525 if (it == features.end())
527 // FIXME: Can't distinguish "0q" from string with no digits in it -- both return d == 0 and ok == false.
528 // Would be good to tell them apart somehow since string with no digits should be default value and
529 // "0q" should be minimum value.
531 double d = it->second.toDouble(&ok);
532 if ((d == 0 && !ok) || isnan(d))
534 if (d < min || max <= min)
538 return static_cast<int>(d);
541 static Frame *createNewWindow(ExecState *exec, Window *openerWindow, const DeprecatedString &URL,
542 const DeprecatedString &frameName, const WindowArgs &windowArgs, JSValue *dialogArgs)
544 Frame* openerPart = openerWindow->frame();
545 Frame* activePart = Window::retrieveActive(exec)->frame();
547 FrameLoadRequest frameRequest;
548 frameRequest.m_request = ResourceRequest(KURL(""));
549 frameRequest.m_frameName = frameName;
551 frameRequest.m_request.setReferrer(activePart->referrer());
553 // FIXME: It's much better for client API if a new window starts with a URL, here where we
554 // know what URL we are going to open. Unfortunately, this code passes the empty string
555 // for the URL, but there's a reason for that. Before loading we have to set up the opener,
556 // openedByJS, and dialogArguments values. Also, to decide whether to use the URL we currently
557 // do an isSafeScript call using the window we create, which can't be done before creating it.
558 // We'd have to resolve all those issues to pass the URL instead of "".
561 openerPart->browserExtension()->createNewWindow(frameRequest, windowArgs, newFrame);
566 Window* newWindow = Window::retrieveWindow(newFrame);
568 newFrame->setOpener(openerPart);
569 newFrame->setOpenedByJS(true);
571 newWindow->putDirect("dialogArguments", dialogArgs);
573 Document *activeDoc = activePart ? activePart->document() : 0;
574 if (!URL.isEmpty() && activeDoc) {
575 DeprecatedString completedURL = activeDoc->completeURL(URL);
576 if (!completedURL.startsWith("javascript:", false) || newWindow->isSafeScript(exec)) {
577 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
578 newFrame->changeLocation(completedURL, activePart->referrer(), false, userGesture);
585 static bool canShowModalDialog(const Window *window)
587 Frame *frame = window->frame();
588 return frame && static_cast<BrowserExtension *>(frame->browserExtension())->canRunModal();
591 static bool canShowModalDialogNow(const Window *window)
593 Frame *frame = window->frame();
594 return frame && static_cast<BrowserExtension *>(frame->browserExtension())->canRunModalNow();
597 static JSValue* showModalDialog(ExecState* exec, Window* openerWindow, const List& args)
599 UString URL = args[0]->toString(exec);
601 if (!canShowModalDialogNow(openerWindow) || !allowPopUp(exec, openerWindow))
602 return jsUndefined();
604 const HashMap<String, String> features = parseModalDialogFeatures(exec, args[2]);
606 bool trusted = false;
610 // The following features from Microsoft's documentation are not implemented:
611 // - default font settings
612 // - width, height, left, and top specified in units other than "px"
613 // - edge (sunken or raised, default is raised)
614 // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print
615 // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)
616 // - unadorned: trusted && boolFeature(features, "unadorned");
618 FloatRect screenRect = usableScreenRect(openerWindow->frame()->page());
620 wargs.width = floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE
621 wargs.widthSet = true;
622 wargs.height = floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE
623 wargs.heightSet = true;
625 wargs.x = floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1);
626 wargs.xSet = wargs.x > 0;
627 wargs.y = floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1);
628 wargs.ySet = wargs.y > 0;
630 if (boolFeature(features, "center", true)) {
632 wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2;
636 wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2;
642 wargs.resizable = boolFeature(features, "resizable");
643 wargs.scrollbarsVisible = boolFeature(features, "scroll", true);
644 wargs.statusBarVisible = boolFeature(features, "status", !trusted);
645 wargs.menuBarVisible = false;
646 wargs.toolBarVisible = false;
647 wargs.locationBarVisible = false;
648 wargs.fullscreen = false;
650 Frame* dialogFrame = createNewWindow(exec, openerWindow, URL, "", wargs, args[1]);
652 return jsUndefined();
654 Window* dialogWindow = Window::retrieveWindow(dialogFrame);
656 // Get the return value either just before clearing the dialog window's
657 // properties (in Window::clear), or when on return from runModal.
658 JSValue* returnValue = 0;
659 dialogWindow->setReturnValueSlot(&returnValue);
660 static_cast<BrowserExtension *>(dialogFrame->browserExtension())->runModal();
661 dialogWindow->setReturnValueSlot(0);
663 // If we don't have a return value, get it now.
664 // Either Window::clear was not called yet, or there was no return value,
665 // and in that case, there's no harm in trying again (no benefit either).
667 returnValue = dialogWindow->getDirect("returnValue");
669 return returnValue ? returnValue : jsUndefined();
672 JSValue *Window::getValueProperty(ExecState *exec, int token) const
674 ASSERT(token == Closed || m_frame);
678 return jsBoolean(!m_frame);
680 return jsUndefined(); // ###
682 return jsString(UString(m_frame->jsDefaultStatusBarText()));
684 return getDOMExceptionConstructor(exec);
686 return jsString(UString(m_frame->jsStatusBarText()));
689 frames = new FrameArray(exec, m_frame);
693 history = new History(exec, m_frame);
697 return jsUndefined();
698 return toJS(exec, m_evt);
700 if (!m_frame->view())
701 return jsUndefined();
702 return jsNumber(m_frame->view()->visibleHeight());
704 if (!m_frame->view())
705 return jsUndefined();
706 return jsNumber(m_frame->view()->visibleWidth());
708 return jsNumber(m_frame->tree()->childCount());
712 return jsString(m_frame->tree()->name());
714 case ClientInformation: {
715 // Store the navigator in the object so we get the same one each time.
716 Navigator *n = new Navigator(exec, m_frame);
717 // FIXME: this will make the "navigator" object accessible from windows that fail
718 // the security check the first time, but not subsequent times, seems weird.
719 const_cast<Window *>(this)->putDirect("navigator", n, DontDelete|ReadOnly);
720 const_cast<Window *>(this)->putDirect("clientInformation", n, DontDelete|ReadOnly);
724 return locationbar(exec);
726 return menubar(exec);
727 case OffscreenBuffering:
728 return jsBoolean(true);
730 if (m_frame->opener())
731 return retrieve(m_frame->opener());
735 return jsNumber(m_frame->page()->windowRect().height());
737 return jsNumber(m_frame->page()->windowRect().width());
739 if (!m_frame->view())
740 return jsUndefined();
742 return jsNumber(m_frame->view()->contentsX());
744 if (!m_frame->view())
745 return jsUndefined();
747 return jsNumber(m_frame->view()->contentsY());
749 return retrieve(m_frame->tree()->parent() ? m_frame->tree()->parent() : m_frame);
751 return personalbar(exec);
754 return jsNumber(m_frame->page()->windowRect().x());
757 return jsNumber(m_frame->page()->windowRect().y());
759 if (!m_frame->view())
760 return jsUndefined();
762 return jsNumber(m_frame->view()->contentsX());
764 if (!m_frame->view())
765 return jsUndefined();
767 return jsNumber(m_frame->view()->contentsY());
769 return scrollbars(exec);
771 return statusbar(exec);
773 return toolbar(exec);
776 return retrieve(m_frame);
778 return retrieve(m_frame->page()->mainFrame());
781 screen = new Screen(exec, m_frame);
784 // FIXME: this property (and the few below) probably shouldn't create a new object every
786 return new ImageConstructorImp(exec, m_frame->document());
788 return new JSHTMLOptionElementConstructor(exec, m_frame->document());
790 return new JSXMLHttpRequestConstructorImp(exec, m_frame->document());
793 return new XSLTProcessorConstructorImp(exec);
796 return jsUndefined();
799 if (Document* doc = m_frame->document())
800 if (Element* fe = doc->ownerElement())
801 if (checkNodeSecurity(exec, fe))
802 return toJS(exec, fe);
803 return jsUndefined();
806 if (!isSafeScript(exec))
807 return jsUndefined();
811 return getListener(exec, abortEvent);
813 return getListener(exec, blurEvent);
815 return getListener(exec, changeEvent);
817 return getListener(exec, clickEvent);
819 return getListener(exec, dblclickEvent);
821 return getListener(exec, khtmlDragdropEvent);
823 return getListener(exec, errorEvent);
825 return getListener(exec, focusEvent);
827 return getListener(exec, keydownEvent);
829 return getListener(exec, keypressEvent);
831 return getListener(exec, keyupEvent);
833 return getListener(exec, loadEvent);
835 return getListener(exec, mousedownEvent);
837 return getListener(exec, mousemoveEvent);
839 return getListener(exec, mouseoutEvent);
841 return getListener(exec, mouseoverEvent);
843 return getListener(exec, mouseupEvent);
844 case OnWindowMouseWheel:
845 return getListener(exec, mousewheelEvent);
847 return getListener(exec, khtmlMoveEvent);
849 return getListener(exec, resetEvent);
851 return getListener(exec,resizeEvent);
853 return getListener(exec,scrollEvent);
855 return getListener(exec,searchEvent);
857 return getListener(exec,selectEvent);
859 return getListener(exec,submitEvent);
861 return getListener(exec, beforeunloadEvent);
863 return getListener(exec, unloadEvent);
866 return jsUndefined();
869 JSValue* Window::childFrameGetter(ExecState*, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
871 return retrieve(static_cast<Window*>(slot.slotBase())->m_frame->tree()->child(AtomicString(propertyName)));
874 JSValue* Window::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
876 return retrieve(static_cast<Window*>(slot.slotBase())->m_frame->tree()->child(slot.index()));
879 JSValue *Window::namedItemGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
881 Window *thisObj = static_cast<Window *>(slot.slotBase());
882 Document *doc = thisObj->m_frame->document();
883 ASSERT(thisObj->isSafeScript(exec) && doc && doc->isHTMLDocument());
885 String name = propertyName;
886 RefPtr<WebCore::HTMLCollection> collection = doc->windowNamedItems(name);
887 if (collection->length() == 1)
888 return toJS(exec, collection->firstItem());
890 return getHTMLCollection(exec, collection.get());
893 bool Window::getOverridePropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
895 // we don't want any properties other than "closed" on a closed window
897 if (propertyName == "closed") {
898 slot.setStaticEntry(this, Lookup::findEntry(&WindowTable, "closed"), staticValueGetter<Window>);
901 if (propertyName == "close") {
902 const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
903 slot.setStaticEntry(this, entry, staticFunctionGetter<WindowFunc>);
907 slot.setUndefined(this);
911 // Look for overrides first
912 JSValue **val = getDirectLocation(propertyName);
914 if (isSafeScript(exec))
915 slot.setValueSlot(this, val);
917 slot.setUndefined(this);
924 bool Window::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
926 // Check for child frames by name before built-in properties to
927 // match Mozilla. This does not match IE, but some sites end up
928 // naming frames things that conflict with window properties that
929 // are in Moz but not IE. Since we have some of these, we have to do
931 AtomicString atomicPropertyName = propertyName;
932 if (m_frame->tree()->child(atomicPropertyName)) {
933 slot.setCustom(this, childFrameGetter);
937 const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
939 if (entry->attr & Function) {
940 switch (entry->value) {
944 slot.setStaticEntry(this, entry, staticFunctionGetter<WindowFunc>);
946 case ShowModalDialog:
947 if (!canShowModalDialog(this))
951 if (isSafeScript(exec))
952 slot.setStaticEntry(this, entry, staticFunctionGetter<WindowFunc>);
954 slot.setUndefined(this);
957 slot.setStaticEntry(this, entry, staticValueGetter<Window>);
961 // FIXME: Search the whole frame hierachy somewhere around here.
962 // We need to test the correct priority order.
964 // allow window[1] or parent[1] etc. (#56983)
966 unsigned i = propertyName.toArrayIndex(&ok);
967 if (ok && i < m_frame->tree()->childCount()) {
968 slot.setCustomIndex(this, i, indexGetter);
972 // allow shortcuts like 'Image1' instead of document.images.Image1
973 Document *doc = m_frame->document();
974 if (isSafeScript(exec) && doc && doc->isHTMLDocument()) {
975 AtomicString atomicPropertyName = propertyName;
976 if (static_cast<HTMLDocument*>(doc)->hasNamedItem(atomicPropertyName) || doc->getElementById(atomicPropertyName)) {
977 slot.setCustom(this, namedItemGetter);
982 if (!isSafeScript(exec)) {
983 slot.setUndefined(this);
987 return JSObject::getOwnPropertySlot(exec, propertyName, slot);
990 void Window::put(ExecState* exec, const Identifier &propertyName, JSValue *value, int attr)
992 // Called by an internal KJS call.
993 // If yes, save time and jump directly to JSObject.
994 if ((attr != None && attr != DontDelete)
995 // Same thing if we have a local override (e.g. "var location")
996 || (JSObject::getDirect(propertyName) && isSafeScript(exec))) {
997 JSObject::put( exec, propertyName, value, attr );
1001 const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
1003 switch(entry->value) {
1005 m_frame->setJSStatusBarText(value->toString(exec));
1008 m_frame->setJSDefaultStatusBarText(value->toString(exec));
1011 Frame* p = Window::retrieveActive(exec)->m_frame;
1013 DeprecatedString dstUrl = p->document()->completeURL(DeprecatedString(value->toString(exec)));
1014 if (!dstUrl.startsWith("javascript:", false) || isSafeScript(exec)) {
1015 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1016 // We want a new history item if this JS was called via a user gesture
1017 m_frame->scheduleLocationChange(dstUrl, p->referrer(), !userGesture, userGesture);
1023 if (isSafeScript(exec))
1024 setListener(exec, abortEvent,value);
1027 if (isSafeScript(exec))
1028 setListener(exec, blurEvent,value);
1031 if (isSafeScript(exec))
1032 setListener(exec, changeEvent,value);
1035 if (isSafeScript(exec))
1036 setListener(exec,clickEvent,value);
1039 if (isSafeScript(exec))
1040 setListener(exec, dblclickEvent,value);
1043 if (isSafeScript(exec))
1044 setListener(exec,khtmlDragdropEvent,value);
1047 if (isSafeScript(exec))
1048 setListener(exec, errorEvent, value);
1051 if (isSafeScript(exec))
1052 setListener(exec,focusEvent,value);
1055 if (isSafeScript(exec))
1056 setListener(exec,keydownEvent,value);
1059 if (isSafeScript(exec))
1060 setListener(exec,keypressEvent,value);
1063 if (isSafeScript(exec))
1064 setListener(exec,keyupEvent,value);
1067 if (isSafeScript(exec))
1068 setListener(exec,loadEvent,value);
1071 if (isSafeScript(exec))
1072 setListener(exec,mousedownEvent,value);
1075 if (isSafeScript(exec))
1076 setListener(exec,mousemoveEvent,value);
1079 if (isSafeScript(exec))
1080 setListener(exec,mouseoutEvent,value);
1083 if (isSafeScript(exec))
1084 setListener(exec,mouseoverEvent,value);
1087 if (isSafeScript(exec))
1088 setListener(exec,mouseupEvent,value);
1090 case OnWindowMouseWheel:
1091 if (isSafeScript(exec))
1092 setListener(exec, mousewheelEvent,value);
1095 if (isSafeScript(exec))
1096 setListener(exec,khtmlMoveEvent,value);
1099 if (isSafeScript(exec))
1100 setListener(exec,resetEvent,value);
1103 if (isSafeScript(exec))
1104 setListener(exec,resizeEvent,value);
1107 if (isSafeScript(exec))
1108 setListener(exec,scrollEvent,value);
1111 if (isSafeScript(exec))
1112 setListener(exec,searchEvent,value);
1115 if (isSafeScript(exec))
1116 setListener(exec,selectEvent,value);
1119 if (isSafeScript(exec))
1120 setListener(exec,submitEvent,value);
1122 case Onbeforeunload:
1123 if (isSafeScript(exec))
1124 setListener(exec, beforeunloadEvent, value);
1127 if (isSafeScript(exec))
1128 setListener(exec, unloadEvent, value);
1131 if (isSafeScript(exec))
1132 m_frame->tree()->setName(value->toString(exec));
1138 if (isSafeScript(exec))
1139 JSObject::put(exec, propertyName, value, attr);
1142 bool Window::toBoolean(ExecState *) const
1147 void Window::scheduleClose()
1149 m_frame->scheduleClose();
1152 static bool shouldLoadAsEmptyDocument(const KURL &url)
1154 return url.protocol().lower() == "about" || url.isEmpty();
1157 bool Window::isSafeScript(const ScriptInterpreter *origin, const ScriptInterpreter *target)
1159 if (origin == target)
1162 Frame *originPart = origin->frame();
1163 Frame *targetPart = target->frame();
1165 // JS may be attempting to access the "window" object, which should be valid,
1166 // even if the document hasn't been constructed yet. If the document doesn't
1167 // exist yet allow JS to access the window object.
1168 if (!targetPart->document())
1171 WebCore::Document *originDocument = originPart->document();
1172 WebCore::Document *targetDocument = targetPart->document();
1174 if (!targetDocument) {
1178 WebCore::String targetDomain = targetDocument->domain();
1180 // Always allow local pages to execute any JS.
1181 if (targetDomain.isNull())
1184 WebCore::String originDomain = originDocument->domain();
1186 // if this document is being initially loaded as empty by its parent
1187 // or opener, allow access from any document in the same domain as
1188 // the parent or opener.
1189 if (shouldLoadAsEmptyDocument(targetPart->url())) {
1190 Frame *ancestorPart = targetPart->opener() ? targetPart->opener() : targetPart->tree()->parent();
1191 while (ancestorPart && shouldLoadAsEmptyDocument(ancestorPart->url())) {
1192 ancestorPart = ancestorPart->tree()->parent();
1196 originDomain = ancestorPart->document()->domain();
1199 if ( targetDomain == originDomain )
1202 if (Interpreter::shouldPrintExceptions()) {
1203 printf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1204 targetDocument->URL().latin1(), originDocument->URL().latin1());
1206 String message = String::sprintf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1207 targetDocument->URL().latin1(), originDocument->URL().latin1());
1208 targetPart->addMessageToConsole(message, 1, String()); //fixme: provide a real line number and sourceurl
1213 bool Window::isSafeScript(ExecState *exec) const
1215 if (!m_frame) // frame deleted ? can't grant access
1217 Frame *activePart = static_cast<ScriptInterpreter *>( exec->dynamicInterpreter() )->frame();
1220 if ( activePart == m_frame ) // Not calling from another frame, no problem.
1223 // JS may be attempting to access the "window" object, which should be valid,
1224 // even if the document hasn't been constructed yet. If the document doesn't
1225 // exist yet allow JS to access the window object.
1226 if (!m_frame->document())
1229 WebCore::Document* thisDocument = m_frame->document();
1230 WebCore::Document* actDocument = activePart->document();
1232 WebCore::String actDomain;
1235 actDomain = activePart->url().host();
1237 actDomain = actDocument->domain();
1239 // FIXME: this really should be explicitly checking for the "file:" protocol instead
1240 // Always allow local pages to execute any JS.
1241 if (actDomain.isEmpty())
1244 WebCore::String thisDomain = thisDocument->domain();
1246 // if this document is being initially loaded as empty by its parent
1247 // or opener, allow access from any document in the same domain as
1248 // the parent or opener.
1249 if (shouldLoadAsEmptyDocument(m_frame->url())) {
1250 Frame *ancestorPart = m_frame->opener() ? m_frame->opener() : m_frame->tree()->parent();
1251 while (ancestorPart && shouldLoadAsEmptyDocument(ancestorPart->url())) {
1252 ancestorPart = ancestorPart->tree()->parent();
1256 thisDomain = ancestorPart->document()->domain();
1259 // FIXME: this should check that URL scheme and port match too, probably
1260 if (actDomain == thisDomain)
1263 if (Interpreter::shouldPrintExceptions()) {
1264 printf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1265 thisDocument->URL().latin1(), actDocument->URL().latin1());
1267 String message = String::sprintf("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains must match.\n",
1268 thisDocument->URL().latin1(), actDocument->URL().latin1());
1269 m_frame->addMessageToConsole(message, 1, String());
1274 void Window::setListener(ExecState *exec, const AtomicString &eventType, JSValue *func)
1276 if (!isSafeScript(exec))
1278 WebCore::Document *doc = m_frame->document();
1282 doc->setHTMLWindowEventListener(eventType, getJSEventListener(func,true));
1285 JSValue *Window::getListener(ExecState *exec, const AtomicString &eventType) const
1287 if (!isSafeScript(exec))
1288 return jsUndefined();
1289 WebCore::Document *doc = m_frame->document();
1291 return jsUndefined();
1293 WebCore::EventListener *listener = doc->getHTMLWindowEventListener(eventType);
1294 if (listener && static_cast<JSEventListener*>(listener)->listenerObj())
1295 return static_cast<JSEventListener*>(listener)->listenerObj();
1300 JSEventListener *Window::getJSEventListener(JSValue *val, bool html)
1302 if (!val->isObject())
1304 JSObject *object = static_cast<JSObject *>(val);
1306 ListenersMap& listeners = html ? jsHTMLEventListeners : jsEventListeners;
1307 if (JSEventListener* listener = listeners.get(object))
1310 // Note that the JSEventListener constructor adds it to our jsEventListeners list
1311 return new JSEventListener(object, this, html);
1314 JSUnprotectedEventListener *Window::getJSUnprotectedEventListener(JSValue *val, bool html)
1316 if (!val->isObject())
1318 JSObject* object = static_cast<JSObject *>(val);
1320 UnprotectedListenersMap& listeners = html ? jsUnprotectedHTMLEventListeners : jsUnprotectedEventListeners;
1321 if (JSUnprotectedEventListener* listener = listeners.get(object))
1324 // The JSUnprotectedEventListener constructor adds it to our jsUnprotectedEventListeners map.
1325 return new JSUnprotectedEventListener(object, this, html);
1328 void Window::clear()
1332 if (m_returnValueSlot && !*m_returnValueSlot)
1333 *m_returnValueSlot = getDirect("returnValue");
1337 setPrototype(JSDOMWindowProto::self()); // clear the prototype
1339 // Now recreate a working global object for the next URL that will use us
1340 interpreter()->initGlobalObject();
1342 // there's likely to be lots of garbage now
1343 Collector::collect();
1346 void Window::setCurrentEvent(Event *evt)
1351 static void setWindowFeature(const String& keyString, const String& valueString, WindowArgs& windowArgs)
1355 if (valueString.length() == 0 || // listing a key with no value is shorthand for key=yes
1356 valueString == "yes")
1359 value = valueString.toInt();
1361 if (keyString == "left" || keyString == "screenx") {
1362 windowArgs.xSet = true;
1363 windowArgs.x = value;
1364 } else if (keyString == "top" || keyString == "screeny") {
1365 windowArgs.ySet = true;
1366 windowArgs.y = value;
1367 } else if (keyString == "width" || keyString == "innerwidth") {
1368 windowArgs.widthSet = true;
1369 windowArgs.width = value;
1370 } else if (keyString == "height" || keyString == "innerheight") {
1371 windowArgs.heightSet = true;
1372 windowArgs.height = value;
1373 } else if (keyString == "menubar")
1374 windowArgs.menuBarVisible = value;
1375 else if (keyString == "toolbar")
1376 windowArgs.toolBarVisible = value;
1377 else if (keyString == "location")
1378 windowArgs.locationBarVisible = value;
1379 else if (keyString == "status")
1380 windowArgs.statusBarVisible = value;
1381 else if (keyString == "resizable")
1382 windowArgs.resizable = value;
1383 else if (keyString == "fullscreen")
1384 windowArgs.fullscreen = value;
1385 else if (keyString == "scrollbars")
1386 windowArgs.scrollbarsVisible = value;
1389 // Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
1390 static bool isSeparator(::UChar c)
1392 return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
1395 static void parseWindowFeatures(const String& features, WindowArgs& windowArgs)
1398 The IE rule is: all features except for channelmode and fullscreen default to YES, but
1399 if the user specifies a feature string, all features default to NO. (There is no public
1400 standard that applies to this method.)
1402 <http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/open_0.asp>
1405 windowArgs.dialog = false;
1406 windowArgs.fullscreen = false;
1408 windowArgs.xSet = false;
1409 windowArgs.ySet = false;
1410 windowArgs.widthSet = false;
1411 windowArgs.heightSet = false;
1413 if (features.length() == 0) {
1414 windowArgs.menuBarVisible = true;
1415 windowArgs.statusBarVisible = true;
1416 windowArgs.toolBarVisible = true;
1417 windowArgs.locationBarVisible = true;
1418 windowArgs.scrollbarsVisible = true;
1419 windowArgs.resizable = true;
1424 windowArgs.menuBarVisible = false;
1425 windowArgs.statusBarVisible = false;
1426 windowArgs.toolBarVisible = false;
1427 windowArgs.locationBarVisible = false;
1428 windowArgs.scrollbarsVisible = false;
1429 windowArgs.resizable = false;
1431 // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
1432 int keyBegin, keyEnd;
1433 int valueBegin, valueEnd;
1436 int length = features.length();
1437 String buffer = features.lower();
1438 while (i < length) {
1439 // skip to first non-separator, but don't skip past the end of the string
1440 while (isSeparator(buffer[i])) {
1447 // skip to first separator
1448 while (!isSeparator(buffer[i]))
1452 // skip to first '=', but don't skip past a ',' or the end of the string
1453 while (buffer[i] != '=') {
1454 if (buffer[i] == ',' || i >= length)
1459 // skip to first non-separator, but don't skip past a ',' or the end of the string
1460 while (isSeparator(buffer[i])) {
1461 if (buffer[i] == ',' || i >= length)
1467 // skip to first separator
1468 while (!isSeparator(buffer[i]))
1472 assert(i <= length);
1474 String keyString(buffer.substring(keyBegin, keyEnd - keyBegin));
1475 String valueString(buffer.substring(valueBegin, valueEnd - valueBegin));
1476 setWindowFeature(keyString, valueString, windowArgs);
1480 static void constrainToVisible(const FloatRect& screen, WindowArgs& windowArgs)
1482 windowArgs.x += screen.x();
1483 if (windowArgs.x < screen.x() || windowArgs.x >= screen.right())
1484 windowArgs.x = screen.x(); // only safe choice until size is determined
1486 windowArgs.y += screen.y();
1487 if (windowArgs.y < screen.y() || windowArgs.y >= screen.bottom())
1488 windowArgs.y = screen.y(); // only safe choice until size is determined
1490 if (windowArgs.height > screen.height()) // should actually check workspace
1491 windowArgs.height = screen.height();
1492 if (windowArgs.height < 100)
1493 windowArgs.height = 100;
1495 if (windowArgs.width > screen.width()) // should actually check workspace
1496 windowArgs.width = screen.width();
1497 if (windowArgs.width < 100)
1498 windowArgs.width = 100;
1501 JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
1503 if (!thisObj->inherits(&Window::info))
1504 return throwError(exec, TypeError);
1505 Window *window = static_cast<Window *>(thisObj);
1506 Frame *frame = window->m_frame;
1508 return jsUndefined();
1510 FrameView *widget = frame->view();
1511 Page* page = frame->page();
1512 JSValue *v = args[0];
1513 UString s = v->toString(exec);
1519 if (frame && frame->document())
1520 frame->document()->updateRendering();
1521 exec->dynamicInterpreter()->pauseTimeoutCheck();
1522 frame->runJavaScriptAlert(str);
1523 exec->dynamicInterpreter()->resumeTimeoutCheck();
1524 return jsUndefined();
1525 case Window::Confirm: {
1526 if (frame && frame->document())
1527 frame->document()->updateRendering();
1528 exec->dynamicInterpreter()->pauseTimeoutCheck();
1529 bool result = frame->runJavaScriptConfirm(str);
1530 exec->dynamicInterpreter()->resumeTimeoutCheck();
1531 return jsBoolean(result);
1533 case Window::Prompt:
1535 if (frame && frame->document())
1536 frame->document()->updateRendering();
1537 String message = args.size() >= 2 ? args[1]->toString(exec) : UString();
1538 bool ok = frame->runJavaScriptPrompt(str, message, str2);
1540 return jsString(str2);
1546 AtomicString frameName = args[1]->isUndefinedOrNull()
1547 ? "_blank" : AtomicString(args[1]->toString(exec));
1548 // Because FrameTree::find() returns true for empty strings, we must check for empty framenames.
1549 // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
1550 if (!allowPopUp(exec, window) && (frameName.isEmpty() || !frame->tree()->find(frameName)))
1551 return jsUndefined();
1553 WindowArgs windowArgs;
1554 String features = args[2]->isUndefinedOrNull() ? UString() : args[2]->toString(exec);
1555 parseWindowFeatures(features, windowArgs);
1556 constrainToVisible(screenRect(page), windowArgs);
1558 // prepare arguments
1560 Frame* activePart = Window::retrieveActive(exec)->m_frame;
1561 if (!str.isEmpty() && activePart)
1562 url = activePart->document()->completeURL(str.deprecatedString());
1564 FrameLoadRequest frameRequest;
1565 frameRequest.m_request.setURL(url);
1566 frameRequest.m_frameName = frameName.deprecatedString();
1567 if (frameRequest.m_frameName == "_top") {
1568 while (frame->tree()->parent())
1569 frame = frame->tree()->parent();
1571 const Window* window = Window::retrieveWindow(frame);
1572 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
1573 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1574 frame->scheduleLocationChange(url.url(), activePart->referrer(), false/*don't lock history*/, userGesture);
1576 return Window::retrieve(frame);
1578 if (frameRequest.m_frameName == "_parent") {
1579 if (frame->tree()->parent())
1580 frame = frame->tree()->parent();
1582 const Window* window = Window::retrieveWindow(frame);
1583 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
1584 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1585 frame->scheduleLocationChange(url.url(), activePart->referrer(), false/*don't lock history*/, userGesture);
1587 return Window::retrieve(frame);
1590 // request window (new or existing if framename is set)
1591 Frame* newFrame = 0;
1592 frameRequest.m_request.setReferrer(activePart->referrer());
1593 frame->browserExtension()->createNewWindow(frameRequest, windowArgs, newFrame);
1595 return jsUndefined();
1596 newFrame->setOpener(frame);
1597 newFrame->setOpenedByJS(true);
1599 if (!newFrame->document()) {
1600 Document* oldDoc = frame->document();
1601 if (oldDoc && oldDoc->baseURL() != 0)
1602 newFrame->begin(oldDoc->baseURL());
1605 newFrame->write("<HTML><BODY>");
1608 newFrame->document()->setDomain(oldDoc->domain(), true);
1609 newFrame->document()->setBaseURL(oldDoc->baseURL());
1612 if (!url.isEmpty()) {
1613 const Window* window = Window::retrieveWindow(newFrame);
1614 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
1615 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
1616 newFrame->scheduleLocationChange(url.url(), activePart->referrer(), false, userGesture);
1619 return Window::retrieve(newFrame); // global object
1623 return jsUndefined();
1624 case Window::ScrollBy:
1625 window->updateLayout();
1626 if(args.size() >= 2 && widget)
1627 widget->scrollBy(args[0]->toInt32(exec), args[1]->toInt32(exec));
1628 return jsUndefined();
1629 case Window::Scroll:
1630 case Window::ScrollTo:
1631 window->updateLayout();
1632 if (args.size() >= 2 && widget)
1633 widget->setContentsPos(args[0]->toInt32(exec), args[1]->toInt32(exec));
1634 return jsUndefined();
1635 case Window::MoveBy:
1636 if (args.size() >= 2 && page) {
1637 FloatRect r = page->windowRect();
1638 r.move(args[0]->toNumber(exec), args[1]->toNumber(exec));
1639 // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
1640 if (screenRect(page).contains(r))
1641 page->setWindowRect(r);
1643 return jsUndefined();
1644 case Window::MoveTo:
1645 if (args.size() >= 2 && page) {
1646 FloatRect r = page->windowRect();
1647 FloatRect sr = screenRect(page);
1648 r.setLocation(sr.location());
1649 r.move(args[0]->toNumber(exec), args[1]->toNumber(exec));
1650 // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
1652 page->setWindowRect(r);
1654 return jsUndefined();
1655 case Window::ResizeBy:
1656 if (args.size() >= 2 && page) {
1657 FloatRect r = page->windowRect();
1658 FloatSize dest = r.size() + FloatSize(args[0]->toNumber(exec), args[1]->toNumber(exec));
1659 FloatRect sg = screenRect(page);
1660 // Security check: within desktop limits and bigger than 100x100 (per spec)
1661 if (r.x() + dest.width() <= sg.right() && r.y() + dest.height() <= sg.bottom()
1662 && dest.width() >= 100 && dest.height() >= 100)
1663 page->setWindowRect(FloatRect(r.location(), dest));
1665 return jsUndefined();
1666 case Window::ResizeTo:
1667 if (args.size() >= 2 && page) {
1668 FloatRect r = page->windowRect();
1669 FloatSize dest = FloatSize(args[0]->toNumber(exec), args[1]->toNumber(exec));
1670 FloatRect sg = screenRect(page);
1671 // Security check: within desktop limits and bigger than 100x100 (per spec)
1672 if (r.x() + dest.width() <= sg.right() && r.y() + dest.height() <= sg.bottom() &&
1673 dest.width() >= 100 && dest.height() >= 100)
1674 page->setWindowRect(FloatRect(r.location(), dest));
1676 return jsUndefined();
1677 case Window::SetTimeout:
1678 if (!window->isSafeScript(exec))
1679 return jsUndefined();
1680 if (args.size() >= 2 && v->isString()) {
1681 int i = args[1]->toInt32(exec);
1682 int r = (const_cast<Window*>(window))->installTimeout(s, i, true /*single shot*/);
1685 else if (args.size() >= 2 && v->isObject() && static_cast<JSObject *>(v)->implementsCall()) {
1686 JSValue *func = args[0];
1687 int i = args[1]->toInt32(exec);
1689 // All arguments after the second should go to the function
1690 // FIXME: could be more efficient
1691 List funcArgs = args.copyTail().copyTail();
1693 int r = (const_cast<Window*>(window))->installTimeout(func, funcArgs, i, true /*single shot*/);
1697 return jsUndefined();
1698 case Window::SetInterval:
1699 if (!window->isSafeScript(exec))
1700 return jsUndefined();
1701 if (args.size() >= 2 && v->isString()) {
1702 int i = args[1]->toInt32(exec);
1703 int r = (const_cast<Window*>(window))->installTimeout(s, i, false);
1706 else if (args.size() >= 2 && v->isObject() && static_cast<JSObject *>(v)->implementsCall()) {
1707 JSValue *func = args[0];
1708 int i = args[1]->toInt32(exec);
1710 // All arguments after the second should go to the function
1711 // FIXME: could be more efficient
1712 List funcArgs = args.copyTail().copyTail();
1714 int r = (const_cast<Window*>(window))->installTimeout(func, funcArgs, i, false);
1718 return jsUndefined();
1719 case Window::ClearTimeout:
1720 case Window::ClearInterval:
1721 if (!window->isSafeScript(exec))
1722 return jsUndefined();
1723 (const_cast<Window*>(window))->clearTimeout(v->toInt32(exec));
1724 return jsUndefined();
1726 frame->focusWindow();
1727 return jsUndefined();
1728 case Window::GetSelection:
1729 if (!window->isSafeScript(exec))
1730 return jsUndefined();
1731 return window->selection();
1733 frame->unfocusWindow();
1734 return jsUndefined();
1736 /* From http://developer.netscape.com/docs/manuals/js/client/jsref/window.htm :
1737 The close method closes only windows opened by JavaScript using the open method.
1738 If you attempt to close any other window, a confirm is generated, which
1739 lets the user choose whether the window closes.
1740 This is a security feature to prevent "mail bombs" containing self.close().
1741 However, if the window has only one document (the current one) in its
1742 session history, the close is allowed without any confirm. This is a
1743 special case for one-off windows that need to open other windows and
1744 then dispose of themselves.
1746 if (!frame->openedByJS())
1748 // To conform to the SPEC, we only ask if the window
1749 // has more than one entry in the history (NS does that too).
1750 History history(exec, frame);
1751 if ( history.get( exec, lengthPropertyName )->toInt32(exec) <= 1
1752 // FIXME: How are we going to handle this?
1754 (const_cast<Window*>(window))->scheduleClose();
1758 (const_cast<Window*>(window))->scheduleClose();
1760 return jsUndefined();
1761 case Window::CaptureEvents:
1762 case Window::ReleaseEvents:
1763 // If anyone implements these, they need the safescript security check.
1764 if (!window->isSafeScript(exec))
1765 return jsUndefined();
1767 // Do nothing for now. These are NS-specific legacy calls.
1769 case Window::AddEventListener:
1770 if (!window->isSafeScript(exec))
1771 return jsUndefined();
1772 if (JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]))
1773 if (Document *doc = frame->document())
1774 doc->addWindowEventListener(AtomicString(args[0]->toString(exec)), listener, args[2]->toBoolean(exec));
1775 return jsUndefined();
1776 case Window::RemoveEventListener:
1777 if (!window->isSafeScript(exec))
1778 return jsUndefined();
1779 if (JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]))
1780 if (Document *doc = frame->document())
1781 doc->removeWindowEventListener(AtomicString(args[0]->toString(exec)), listener, args[2]->toBoolean(exec));
1782 return jsUndefined();
1783 case Window::ShowModalDialog: {
1784 exec->dynamicInterpreter()->pauseTimeoutCheck();
1785 JSValue* result = showModalDialog(exec, window, args);
1786 exec->dynamicInterpreter()->resumeTimeoutCheck();
1790 return jsUndefined();
1793 void Window::updateLayout() const
1795 WebCore::Document* docimpl = m_frame->document();
1797 docimpl->updateLayoutIgnorePendingStylesheets();
1800 ////////////////////// ScheduledAction ////////////////////////
1802 void ScheduledAction::execute(Window *window)
1804 if (!window->m_frame || !window->m_frame->jScript())
1807 ScriptInterpreter *interpreter = window->m_frame->jScript()->interpreter();
1809 interpreter->setProcessingTimerCallback(true);
1811 if (JSValue* func = m_func.get()) {
1812 if (func->isObject() && static_cast<JSObject *>(func)->implementsCall()) {
1813 ExecState *exec = interpreter->globalExec();
1814 ASSERT(window == interpreter->globalObject());
1816 interpreter->startTimeoutCheck();
1817 static_cast<JSObject *>(func)->call(exec, window, m_args);
1818 interpreter->stopTimeoutCheck();
1819 if (exec->hadException()) {
1820 JSObject* exception = exec->exception()->toObject(exec);
1821 exec->clearException();
1822 String message = exception->get(exec, messagePropertyName)->toString(exec);
1823 int lineNumber = exception->get(exec, "line")->toInt32(exec);
1824 if (Interpreter::shouldPrintExceptions())
1825 printf("(timer):%s\n", message.utf8().data());
1826 window->m_frame->addMessageToConsole(message, lineNumber, String());
1830 window->m_frame->executeScript(0, m_code);
1832 // Update our document's rendering following the execution of the timeout callback.
1833 // FIXME: Why? Why not other documents, for example?
1834 Document *doc = window->m_frame->document();
1836 doc->updateRendering();
1838 interpreter->setProcessingTimerCallback(false);
1841 ////////////////////// timeouts ////////////////////////
1843 void Window::clearAllTimeouts()
1845 deleteAllValues(m_timeouts);
1849 int Window::installTimeout(ScheduledAction* a, int t, bool singleShot)
1851 int timeoutId = ++lastUsedTimeoutId;
1852 DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, this, a);
1853 ASSERT(!m_timeouts.get(timeoutId));
1854 m_timeouts.set(timeoutId, timer);
1855 // Use a minimum interval of 10 ms to match other browsers.
1856 // Faster timers might be "better", but they're incompatible.
1857 double interval = t <= 10 ? 0.010 : t * 0.001;
1859 timer->startOneShot(interval);
1861 timer->startRepeating(interval);
1865 int Window::installTimeout(const UString& handler, int t, bool singleShot)
1867 return installTimeout(new ScheduledAction(handler), t, singleShot);
1870 int Window::installTimeout(JSValue* func, const List& args, int t, bool singleShot)
1872 return installTimeout(new ScheduledAction(func, args), t, singleShot);
1875 PausedTimeouts* Window::pauseTimeouts()
1877 size_t count = m_timeouts.size();
1881 PausedTimeout* t = new PausedTimeout [count];
1882 PausedTimeouts* result = new PausedTimeouts(t, count);
1884 TimeoutsMap::iterator it = m_timeouts.begin();
1885 for (size_t i = 0; i != count; ++i, ++it) {
1886 int timeoutId = it->first;
1887 DOMWindowTimer* timer = it->second;
1888 t[i].timeoutId = timeoutId;
1889 t[i].nextFireInterval = timer->nextFireInterval();
1890 t[i].repeatInterval = timer->repeatInterval();
1891 t[i].action = timer->takeAction();
1893 ASSERT(it == m_timeouts.end());
1895 deleteAllValues(m_timeouts);
1901 void Window::resumeTimeouts(PausedTimeouts* timeouts)
1905 size_t count = timeouts->numTimeouts();
1906 PausedTimeout* array = timeouts->takeTimeouts();
1907 for (size_t i = 0; i != count; ++i) {
1908 int timeoutId = array[i].timeoutId;
1909 DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, this, array[i].action);
1910 m_timeouts.set(timeoutId, timer);
1911 timer->start(array[i].nextFireInterval, array[i].repeatInterval);
1916 void Window::clearTimeout(int timeoutId, bool delAction)
1918 TimeoutsMap::iterator it = m_timeouts.find(timeoutId);
1919 if (it == m_timeouts.end())
1921 DOMWindowTimer* timer = it->second;
1922 m_timeouts.remove(it);
1926 void Window::timerFired(DOMWindowTimer* timer)
1928 // Simple case for non-one-shot timers.
1929 if (timer->isActive()) {
1930 timer->action()->execute(this);
1934 // Delete timer before executing the action for one-shot timers.
1935 ScheduledAction* action = timer->takeAction();
1936 m_timeouts.remove(timer->timeoutId());
1938 action->execute(this);
1942 void Window::disconnectFrame()
1949 m_selection->m_frame = 0;
1951 m_locationbar->m_frame = 0;
1953 m_menubar->m_frame = 0;
1955 m_personalbar->m_frame = 0;
1957 m_statusbar->m_frame = 0;
1959 m_toolbar->m_frame = 0;
1961 m_scrollbars->m_frame = 0;
1963 frames->disconnectFrame();
1965 history->disconnectFrame();
1968 const ClassInfo FrameArray::info = { "FrameArray", 0, &FrameArrayTable, 0 };
1971 @begin FrameArrayTable 2
1972 length FrameArray::Length DontDelete|ReadOnly
1973 location FrameArray::Location DontDelete|ReadOnly
1977 JSValue *FrameArray::getValueProperty(ExecState *exec, int token)
1981 return jsNumber(m_frame->tree()->childCount());
1983 // non-standard property, but works in NS and IE
1984 if (JSObject *obj = Window::retrieveWindow(m_frame))
1985 return obj->get(exec, "location");
1986 return jsUndefined();
1989 return jsUndefined();
1993 JSValue* FrameArray::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
1995 return Window::retrieve(static_cast<FrameArray*>(slot.slotBase())->m_frame->tree()->child(slot.index()));
1998 JSValue* FrameArray::nameGetter(ExecState*, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
2000 return Window::retrieve(static_cast<FrameArray*>(slot.slotBase())->m_frame->tree()->child(AtomicString(propertyName)));
2003 bool FrameArray::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
2006 slot.setUndefined(this);
2010 const HashEntry* entry = Lookup::findEntry(&FrameArrayTable, propertyName);
2012 slot.setStaticEntry(this, entry, staticValueGetter<FrameArray>);
2016 // check for the name or number
2017 if (m_frame->tree()->child(propertyName)) {
2018 slot.setCustom(this, nameGetter);
2023 unsigned i = propertyName.toArrayIndex(&ok);
2024 if (ok && i < m_frame->tree()->childCount()) {
2025 slot.setCustomIndex(this, i, indexGetter);
2029 return JSObject::getOwnPropertySlot(exec, propertyName, slot);
2032 UString FrameArray::toString(ExecState *) const
2034 return "[object FrameArray]";
2037 ////////////////////// Location Object ////////////////////////
2039 const ClassInfo Location::info = { "Location", 0, 0, 0 };
2041 @begin LocationTable 12
2042 assign Location::Assign DontDelete|Function 1
2043 hash Location::Hash DontDelete
2044 host Location::Host DontDelete
2045 hostname Location::Hostname DontDelete
2046 href Location::Href DontDelete
2047 pathname Location::Pathname DontDelete
2048 port Location::Port DontDelete
2049 protocol Location::Protocol DontDelete
2050 search Location::Search DontDelete
2051 [[==]] Location::EqualEqual DontDelete|ReadOnly
2052 toString Location::ToString DontDelete|Function 0
2053 replace Location::Replace DontDelete|Function 1
2054 reload Location::Reload DontDelete|Function 0
2057 KJS_IMPLEMENT_PROTOFUNC(LocationFunc)
2058 Location::Location(Frame *p) : m_frame(p)
2062 JSValue *Location::getValueProperty(ExecState *exec, int token) const
2064 KURL url = m_frame->url();
2067 return jsString(url.ref().isNull() ? "" : "#" + url.ref());
2069 // Note: this is the IE spec. The NS spec swaps the two, it says
2070 // "The hostname property is the concatenation of the host and port properties, separated by a colon."
2072 UString str = url.host();
2074 str += ":" + String::number((int)url.port());
2075 return jsString(str);
2078 return jsString(url.host());
2081 return jsString(url.prettyURL() + "/");
2083 return jsString(url.prettyURL());
2085 return jsString(url.path().isEmpty() ? "/" : url.path());
2087 return jsString(url.port() ? String::number((int)url.port()) : "");
2089 return jsString(url.protocol() + ":");
2091 return jsString(url.query());
2094 return jsUndefined();
2098 bool Location::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
2103 const Window* window = Window::retrieveWindow(m_frame);
2104 if (!window || !window->isSafeScript(exec)) {
2105 slot.setUndefined(this);
2109 return getStaticPropertySlot<LocationFunc, Location, JSObject>(exec, &LocationTable, this, propertyName, slot);
2112 void Location::put(ExecState *exec, const Identifier &p, JSValue *v, int attr)
2117 DeprecatedString str = v->toString(exec);
2118 KURL url = m_frame->url();
2119 const HashEntry *entry = Lookup::findEntry(&LocationTable, p);
2121 switch (entry->value) {
2123 Frame* p = Window::retrieveActive(exec)->frame();
2125 url = p->document()->completeURL( str );
2131 if (str.startsWith("#"))
2134 if (url.ref() == str)
2141 DeprecatedString host = str.left(str.find(":"));
2142 DeprecatedString port = str.mid(str.find(":")+1);
2144 url.setPort(port.toUInt());
2154 url.setPort(str.toUInt());
2157 url.setProtocol(str);
2164 JSObject::put(exec, p, v, attr);
2168 const Window* window = Window::retrieveWindow(m_frame);
2169 Frame* activePart = Window::retrieveActive(exec)->frame();
2170 if (!url.url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2171 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2172 // We want a new history item if this JS was called via a user gesture
2173 m_frame->scheduleLocationChange(url.url(), activePart->referrer(), !userGesture, userGesture);
2177 JSValue *Location::toPrimitive(ExecState *exec, JSType) const
2179 return jsString(toString(exec));
2182 UString Location::toString(ExecState *) const
2184 if (!m_frame->url().hasPath())
2185 return m_frame->url().prettyURL()+"/";
2187 return m_frame->url().prettyURL();
2190 JSValue *LocationFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
2192 if (!thisObj->inherits(&Location::info))
2193 return throwError(exec, TypeError);
2194 Location *location = static_cast<Location *>(thisObj);
2195 Frame *frame = location->frame();
2198 Window* window = Window::retrieveWindow(frame);
2199 if (!window->isSafeScript(exec) && id != Location::Replace)
2200 return jsUndefined();
2203 case Location::Replace:
2205 DeprecatedString str = args[0]->toString(exec);
2206 Frame* p = Window::retrieveActive(exec)->frame();
2208 const Window* window = Window::retrieveWindow(frame);
2209 if (!str.startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2210 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2211 frame->scheduleLocationChange(p->document()->completeURL(str), p->referrer(), true /*lock history*/, userGesture);
2216 case Location::Reload:
2218 const Window* window = Window::retrieveWindow(frame);
2219 if (!frame->url().url().startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2220 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2221 frame->scheduleRefresh(userGesture);
2225 case Location::Assign:
2227 Frame *p = Window::retrieveActive(exec)->frame();
2229 const Window *window = Window::retrieveWindow(frame);
2230 DeprecatedString dstUrl = p->document()->completeURL(DeprecatedString(args[0]->toString(exec)));
2231 if (!dstUrl.startsWith("javascript:", false) || (window && window->isSafeScript(exec))) {
2232 bool userGesture = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter())->wasRunByUserGesture();
2233 // We want a new history item if this JS was called via a user gesture
2234 frame->scheduleLocationChange(dstUrl, p->referrer(), !userGesture, userGesture);
2239 case Location::ToString:
2240 return jsString(location->toString(exec));
2243 return jsUndefined();
2246 ////////////////////// Selection Object ////////////////////////
2248 const ClassInfo Selection::info = { "Selection", 0, 0, 0 };
2250 @begin SelectionTable 19
2251 anchorNode Selection::AnchorNode DontDelete|ReadOnly
2252 anchorOffset Selection::AnchorOffset DontDelete|ReadOnly
2253 focusNode Selection::FocusNode DontDelete|ReadOnly
2254 focusOffset Selection::FocusOffset DontDelete|ReadOnly
2255 baseNode Selection::BaseNode DontDelete|ReadOnly
2256 baseOffset Selection::BaseOffset DontDelete|ReadOnly
2257 extentNode Selection::ExtentNode DontDelete|ReadOnly
2258 extentOffset Selection::ExtentOffset DontDelete|ReadOnly
2259 isCollapsed Selection::IsCollapsed DontDelete|ReadOnly
2260 type Selection::_Type DontDelete|ReadOnly
2261 [[==]] Selection::EqualEqual DontDelete|ReadOnly
2262 toString Selection::ToString DontDelete|Function 0
2263 collapse Selection::Collapse DontDelete|Function 2
2264 collapseToEnd Selection::CollapseToEnd DontDelete|Function 0
2265 collapseToStart Selection::CollapseToStart DontDelete|Function 0
2266 empty Selection::Empty DontDelete|Function 0
2267 setBaseAndExtent Selection::SetBaseAndExtent DontDelete|Function 4
2268 setPosition Selection::SetPosition DontDelete|Function 2
2269 modify Selection::Modify DontDelete|Function 3
2270 getRangeAt Selection::GetRangeAt DontDelete|Function 1
2273 KJS_IMPLEMENT_PROTOFUNC(SelectionFunc)
2274 Selection::Selection(Frame *p) : m_frame(p)
2278 JSValue *Selection::getValueProperty(ExecState *exec, int token) const
2280 SelectionController* s = m_frame->selectionController();
2281 const Window* window = Window::retrieveWindow(m_frame);
2283 return jsUndefined();
2287 return toJS(exec, s->anchorNode());
2289 return toJS(exec, s->baseNode());
2291 return jsNumber(s->anchorOffset());
2293 return jsNumber(s->baseOffset());
2295 return toJS(exec, s->focusNode());
2297 return toJS(exec, s->extentNode());
2299 return jsNumber(s->focusOffset());
2301 return jsNumber(s->extentOffset());
2303 return jsBoolean(s->isCollapsed());
2305 return jsString(s->type());
2308 return jsUndefined();
2312 bool Selection::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
2317 return getStaticPropertySlot<SelectionFunc, Selection, JSObject>(exec, &SelectionTable, this, propertyName, slot);
2320 JSValue *Selection::toPrimitive(ExecState *exec, JSType) const
2322 return jsString(toString(exec));
2325 UString Selection::toString(ExecState *) const
2327 return UString(m_frame->selectionController()->toString());
2330 JSValue *SelectionFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
2332 if (!thisObj->inherits(&Selection::info))
2333 return throwError(exec, TypeError);
2334 Selection *selection = static_cast<Selection *>(thisObj);
2335 Frame *frame = selection->frame();
2337 SelectionController* s = frame->selectionController();
2340 case Selection::Collapse:
2341 s->collapse(toNode(args[0]), args[1]->toInt32(exec));
2343 case Selection::CollapseToEnd:
2346 case Selection::CollapseToStart:
2347 s->collapseToStart();
2349 case Selection::Empty:
2352 case Selection::SetBaseAndExtent:
2353 s->setBaseAndExtent(toNode(args[0]), args[1]->toInt32(exec), toNode(args[2]), args[3]->toInt32(exec));
2355 case Selection::SetPosition:
2356 s->setPosition(toNode(args[0]), args[1]->toInt32(exec));
2358 case Selection::Modify:
2359 s->modify(args[0]->toString(exec), args[1]->toString(exec), args[2]->toString(exec));
2361 case Selection::GetRangeAt:
2362 return toJS(exec, s->getRangeAt(args[0]->toInt32(exec)).get());
2363 case Selection::ToString:
2364 return jsString(s->toString());
2368 return jsUndefined();
2371 ////////////////////// BarInfo Object ////////////////////////
2373 const ClassInfo BarInfo::info = { "BarInfo", 0, 0, 0 };
2375 @begin BarInfoTable 1
2376 visible BarInfo::Visible DontDelete|ReadOnly
2379 BarInfo::BarInfo(ExecState *exec, Frame *f, Type barType)
2383 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
2386 JSValue *BarInfo::getValueProperty(ExecState *exec, int token) const
2388 ASSERT(token == Visible);
2391 return jsBoolean(m_frame->locationbarVisible());
2393 return jsBoolean(m_frame->locationbarVisible());
2395 return jsBoolean(m_frame->personalbarVisible());
2397 return jsBoolean(m_frame->scrollbarsVisible());
2399 return jsBoolean(m_frame->statusbarVisible());
2401 return jsBoolean(m_frame->toolbarVisible());
2403 return jsBoolean(false);
2407 bool BarInfo::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
2412 return getStaticValueSlot<BarInfo, JSObject>(exec, &BarInfoTable, this, propertyName, slot);
2415 ////////////////////// History Object ////////////////////////
2417 const ClassInfo History::info = { "History", 0, 0, 0 };
2419 @begin HistoryTable 4
2420 length History::Length DontDelete|ReadOnly
2421 back History::Back DontDelete|Function 0
2422 forward History::Forward DontDelete|Function 0
2423 go History::Go DontDelete|Function 1
2426 KJS_IMPLEMENT_PROTOFUNC(HistoryFunc)
2428 bool History::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
2430 return getStaticPropertySlot<HistoryFunc, History, JSObject>(exec, &HistoryTable, this, propertyName, slot);
2433 JSValue *History::getValueProperty(ExecState *, int token) const
2438 BrowserExtension *ext = m_frame->browserExtension();
2442 return jsNumber(ext->getHistoryLength());
2445 return jsUndefined();
2449 UString History::toString(ExecState *exec) const
2451 return "[object History]";
2454 JSValue *HistoryFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
2456 if (!thisObj->inherits(&History::info))
2457 return throwError(exec, TypeError);
2458 History *history = static_cast<History *>(thisObj);
2465 case History::Forward:
2469 steps = args[0]->toInt32(exec);
2472 return jsUndefined();
2475 history->m_frame->scheduleHistoryNavigation(steps);
2476 return jsUndefined();
2479 /////////////////////////////////////////////////////////////////////////////
2481 PausedTimeouts::~PausedTimeouts()
2483 PausedTimeout *array = m_array;
2486 size_t count = m_length;
2487 for (size_t i = 0; i != count; ++i)
2488 delete array[i].action;
2492 void DOMWindowTimer::fired()
2494 m_object->timerFired(this);
2499 using namespace KJS;
2503 JSValue* toJS(ExecState*, DOMWindow* domWindow)
2507 Frame* frame = domWindow->frame();
2510 return Window::retrieve(frame);
2513 DOMWindow* toDOMWindow(JSValue* val)
2515 return val->isObject(&JSDOMWindow::info) ? static_cast<JSDOMWindow*>(val)->impl() : 0;
2518 } // namespace WebCore