/*
 *  Copyright (C) 2000 Harri Porten (porten@kde.org)
 *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reseved.
 *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 *  USA
 */

#include "config.h"
#include "kjs_window.h"

#include "Base64.h"
#include "CString.h"
#include "Chrome.h"
#include "DOMWindow.h"
#include "Element.h"
#include "EventListener.h"
#include "EventNames.h"
#include "ExceptionCode.h"
#include "FloatRect.h"
#include "Frame.h"
#include "FrameLoadRequest.h"
#include "FrameLoader.h"
#include "FrameTree.h"
#include "GCController.h"
#include "HTMLDocument.h"
#include "JSDOMWindow.h"
#include "JSEvent.h"
#include "JSAudioConstructor.h"
#include "JSHTMLCollection.h"
#include "JSHTMLOptionElementConstructor.h"
#include "JSXMLHttpRequest.h"
#include "JSLocation.h"
#include "Logging.h"
#include "MediaPlayer.h"
#include "Page.h"
#include "PausedTimeouts.h"
#include "PlatformScreen.h"
#include "PluginInfoStore.h"
#include "RenderView.h"
#include "ScheduledAction.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include "WindowFeatures.h"
#include "htmlediting.h"
#include "kjs_css.h"
#include "kjs_events.h"
#include "kjs_navigator.h"
#include "kjs_proxy.h"
#include <wtf/AlwaysInline.h>
#include <wtf/MathExtras.h>

#if ENABLE(XSLT)
#include "JSXSLTProcessor.h"
#endif

using namespace WebCore;
using namespace EventNames;

namespace KJS {

static int lastUsedTimeoutId;

static int timerNestingLevel = 0;
const int cMaxTimerNestingLevel = 5;
const double cMinimumTimerInterval = 0.010;

struct WindowPrivate {
    WindowPrivate()
        : loc(0)
        , m_evt(0)
        , m_returnValueSlot(0)
    {
    }

    Window::ListenersMap jsEventListeners;
    Window::ListenersMap jsHTMLEventListeners;
    Window::UnprotectedListenersMap jsUnprotectedEventListeners;
    Window::UnprotectedListenersMap jsUnprotectedHTMLEventListeners;
    mutable WebCore::JSLocation* loc;
    WebCore::Event* m_evt;
    JSValue** m_returnValueSlot;

    typedef HashMap<int, DOMWindowTimer*> TimeoutsMap;
    TimeoutsMap m_timeouts;
};

class DOMWindowTimer : public TimerBase {
public:
    DOMWindowTimer(int timeoutId, int nestingLevel, Window* object, WebCore::ScheduledAction* action)
        : m_timeoutId(timeoutId)
        , m_nestingLevel(nestingLevel)
        , m_object(object)
        , m_action(action)
    {
    }

    virtual ~DOMWindowTimer()
    {
        JSLock lock;
        delete m_action;
    }

    int timeoutId() const { return m_timeoutId; }

    int nestingLevel() const { return m_nestingLevel; }
    void setNestingLevel(int n) { m_nestingLevel = n; }

    WebCore::ScheduledAction* action() const { return m_action; }
    WebCore::ScheduledAction* takeAction() { WebCore::ScheduledAction* a = m_action; m_action = 0; return a; }

private:
    virtual void fired();

    int m_timeoutId;
    int m_nestingLevel;
    Window* m_object;
    WebCore::ScheduledAction* m_action;
};

} // namespace KJS

#include "kjs_window.lut.h"

namespace KJS {

////////////////////// Window Object ////////////////////////

const ClassInfo Window::info = { "Window", 0, &WindowTable };

/*
@begin WindowTable 118
# Warning, when adding a function to this object you need to add a case in Window::get
# -- Functions --
  atob                  windowProtoFuncAToB                DontDelete|Function 1
  btoa                  windowProtoFuncBToA                DontDelete|Function 1
  open                  windowProtoFuncOpen                DontDelete|Function 3
  setTimeout            windowProtoFuncSetTimeout          DontDelete|Function 2
  clearTimeout          windowProtoFuncClearTimeout        DontDelete|Function 1
  setInterval           windowProtoFuncSetInterval         DontDelete|Function 2
  clearInterval         windowProtoFuncClearTimeout        DontDelete|Function 1
  addEventListener      windowProtoFuncAddEventListener    DontDelete|Function 3
  removeEventListener   windowProtoFuncRemoveEventListener DontDelete|Function 3
  showModalDialog       windowProtoFuncShowModalDialog     DontDelete|Function 1
# Not implemented
  captureEvents         windowProtoFuncNotImplemented      DontDelete|Function 0
  releaseEvents         windowProtoFuncNotImplemented      DontDelete|Function 0

# -- Attributes --
  crypto                Window::Crypto              DontDelete|ReadOnly
  event                 Window::Event_              DontDelete
  location              Window::Location_           DontDelete
  navigator             Window::Navigator_          DontDelete
  clientInformation     Window::ClientInformation   DontDelete
# -- Event Listeners --
  onabort               Window::Onabort             DontDelete
  onblur                Window::Onblur              DontDelete
  onchange              Window::Onchange            DontDelete
  onclick               Window::Onclick             DontDelete
  ondblclick            Window::Ondblclick          DontDelete
  onerror               Window::Onerror             DontDelete
  onfocus               Window::Onfocus             DontDelete
  onkeydown             Window::Onkeydown           DontDelete
  onkeypress            Window::Onkeypress          DontDelete
  onkeyup               Window::Onkeyup             DontDelete
  onload                Window::Onload              DontDelete
  onmousedown           Window::Onmousedown         DontDelete
  onmousemove           Window::Onmousemove         DontDelete
  onmouseout            Window::Onmouseout          DontDelete
  onmouseover           Window::Onmouseover         DontDelete
  onmouseup             Window::Onmouseup           DontDelete
  onmousewheel          Window::OnWindowMouseWheel  DontDelete
  onreset               Window::Onreset             DontDelete
  onresize              Window::Onresize            DontDelete
  onscroll              Window::Onscroll            DontDelete
  onsearch              Window::Onsearch            DontDelete
  onselect              Window::Onselect            DontDelete
  onsubmit              Window::Onsubmit            DontDelete
  onunload              Window::Onunload            DontDelete
  onbeforeunload        Window::Onbeforeunload      DontDelete
# -- Constructors --
  Audio                 Window::Audio               DontDelete
  Image                 Window::Image               DontDelete
  Option                Window::Option              DontDelete
  XMLHttpRequest        Window::XMLHttpRequest      DontDelete
  XSLTProcessor         Window::XSLTProcessor_      DontDelete
@end
*/

Window::Window(JSObject* prototype, DOMWindow* window)
    : JSGlobalObject(prototype)
    , m_impl(window)
    , d(new WindowPrivate)
{
    // Window destruction is not thread-safe because of
    // the non-thread-safe WebCore structures it references.
    Collector::collectOnMainThreadOnly(this);

    // Time in milliseconds before the script timeout handler kicks in.
    setTimeoutTime(10000);
}

Window::~Window()
{
    clearAllTimeouts();

    // Clear any backpointers to the window

    ListenersMap::iterator i2 = d->jsEventListeners.begin();
    ListenersMap::iterator e2 = d->jsEventListeners.end();
    for (; i2 != e2; ++i2)
        i2->second->clearWindowObj();
    i2 = d->jsHTMLEventListeners.begin();
    e2 = d->jsHTMLEventListeners.end();
    for (; i2 != e2; ++i2)
        i2->second->clearWindowObj();

    UnprotectedListenersMap::iterator i1 = d->jsUnprotectedEventListeners.begin();
    UnprotectedListenersMap::iterator e1 = d->jsUnprotectedEventListeners.end();
    for (; i1 != e1; ++i1)
        i1->second->clearWindowObj();
    i1 = d->jsUnprotectedHTMLEventListeners.begin();
    e1 = d->jsUnprotectedHTMLEventListeners.end();
    for (; i1 != e1; ++i1)
        i1->second->clearWindowObj();
}

Window* Window::retrieveWindow(Frame* frame)
{
    JSObject* o = retrieve(frame)->getObject();

    ASSERT(o || !frame->scriptProxy()->isEnabled());
    return static_cast<Window*>(o);
}

Window* Window::retrieveActive(ExecState* exec)
{
    JSGlobalObject* globalObject = exec->dynamicGlobalObject();
    ASSERT(globalObject);
    return static_cast<Window*>(globalObject);
}

JSValue* Window::retrieve(Frame* frame)
{
    ASSERT(frame);
    if (frame->scriptProxy()->isEnabled())
        return frame->scriptProxy()->globalObject(); // the Global object is the "window"

    return jsUndefined(); // This can happen with JS disabled on the domain of that window
}

WebCore::JSLocation* Window::location() const
{
    if (!d->loc)
        d->loc = new JSLocation(0, impl()->frame()); // FIXME: we need to pass a prototype.
    return d->loc;
}

void Window::mark()
{
    Base::mark();
    if (d->loc && !d->loc->marked())
        d->loc->mark();
}

static bool allowPopUp(ExecState* exec)
{
    Frame* frame = Window::retrieveActive(exec)->impl()->frame();

    ASSERT(frame);
    if (frame->scriptProxy()->processingUserGesture())
        return true;
    Settings* settings = frame->settings();
    return settings && settings->JavaScriptCanOpenWindowsAutomatically();
}

static HashMap<String, String> parseModalDialogFeatures(const String& featuresArg)
{
    HashMap<String, String> map;

    Vector<String> features = featuresArg.split(';');
    Vector<String>::const_iterator end = features.end();
    for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) {
        String s = *it;
        int pos = s.find('=');
        int colonPos = s.find(':');
        if (pos >= 0 && colonPos >= 0)
            continue; // ignore any strings that have both = and :
        if (pos < 0)
            pos = colonPos;
        if (pos < 0) {
            // null string for value means key without value
            map.set(s.stripWhiteSpace().lower(), String());
        } else {
            String key = s.left(pos).stripWhiteSpace().lower();
            String val = s.substring(pos + 1).stripWhiteSpace().lower();
            int spacePos = val.find(' ');
            if (spacePos != -1)
                val = val.left(spacePos);
            map.set(key, val);
        }
    }

    return map;
}

static Frame* createWindow(ExecState* exec, Frame* openerFrame, const String& url,
    const String& frameName, const WindowFeatures& windowFeatures, JSValue* dialogArgs)
{
    Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();

    ResourceRequest request;

    request.setHTTPReferrer(activeFrame->loader()->outgoingReferrer());
    FrameLoadRequest frameRequest(request, frameName);

    // FIXME: It's much better for client API if a new window starts with a URL, here where we
    // know what URL we are going to open. Unfortunately, this code passes the empty string
    // for the URL, but there's a reason for that. Before loading we have to set up the opener,
    // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently
    // do an allowsAccessFrom call using the window we create, which can't be done before creating it.
    // We'd have to resolve all those issues to pass the URL instead of "".

    bool created;
    // We pass in the opener frame here so it can be used for looking up the frame name, in case the active frame
    // is different from the opener frame, and the name references a frame relative to the opener frame, for example
    // "_self" or "_parent".
    Frame* newFrame = activeFrame->loader()->createWindow(openerFrame->loader(), frameRequest, windowFeatures, created);
    if (!newFrame)
        return 0;

    newFrame->loader()->setOpener(openerFrame);
    newFrame->loader()->setOpenedByDOM();

    Window* newWindow = Window::retrieveWindow(newFrame);

    if (dialogArgs)
        newWindow->putDirect("dialogArguments", dialogArgs);

    if (!url.startsWith("javascript:", false) || newWindow->allowsAccessFrom(exec)) {
        String completedURL = url.isEmpty() ? url : activeFrame->document()->completeURL(url);
        bool userGesture = activeFrame->scriptProxy()->processingUserGesture();

        if (created) {
            newFrame->loader()->changeLocation(KURL(completedURL.deprecatedString()), activeFrame->loader()->outgoingReferrer(), false, userGesture);
            if (Document* oldDoc = openerFrame->document())
                newFrame->document()->setBaseURL(oldDoc->baseURL());
        } else if (!url.isEmpty())
            newFrame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture);
    }

    return newFrame;
}

static bool canShowModalDialog(const Frame* frame)
{
    if (!frame)
        return false;
    return frame->page()->chrome()->canRunModal();
}

static bool canShowModalDialogNow(const Frame* frame)
{
    if (!frame)
        return false;
    return frame->page()->chrome()->canRunModalNow();
}

static JSValue* showModalDialog(ExecState* exec, Frame* frame, const String& url, JSValue* dialogArgs, const String& featureArgs)
{
    if (!canShowModalDialogNow(frame) || !allowPopUp(exec))
        return jsUndefined();

    const HashMap<String, String> features = parseModalDialogFeatures(featureArgs);

    const bool trusted = false;

    // The following features from Microsoft's documentation are not implemented:
    // - default font settings
    // - width, height, left, and top specified in units other than "px"
    // - edge (sunken or raised, default is raised)
    // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print
    // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)
    // - unadorned: trusted && boolFeature(features, "unadorned");

    if (!frame)
        return jsUndefined();

    FloatRect screenRect = screenAvailableRect(frame->view());

    WindowFeatures wargs;
    wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE
    wargs.widthSet = true;
    wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE
    wargs.heightSet = true;

    wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1);
    wargs.xSet = wargs.x > 0;
    wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1);
    wargs.ySet = wargs.y > 0;

    if (WindowFeatures::boolFeature(features, "center", true)) {
        if (!wargs.xSet) {
            wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2;
            wargs.xSet = true;
        }
        if (!wargs.ySet) {
            wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2;
            wargs.ySet = true;
        }
    }

    wargs.dialog = true;
    wargs.resizable = WindowFeatures::boolFeature(features, "resizable");
    wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true);
    wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted);
    wargs.menuBarVisible = false;
    wargs.toolBarVisible = false;
    wargs.locationBarVisible = false;
    wargs.fullscreen = false;

    Frame* dialogFrame = createWindow(exec, frame, url, "", wargs, dialogArgs);
    if (!dialogFrame)
        return jsUndefined();

    Window* dialogWindow = Window::retrieveWindow(dialogFrame);

    // Get the return value either just before clearing the dialog window's
    // properties (in Window::clear), or when on return from runModal.
    JSValue* returnValue = 0;
    dialogWindow->setReturnValueSlot(&returnValue);
    dialogFrame->page()->chrome()->runModal();
    dialogWindow->setReturnValueSlot(0);

    // If we don't have a return value, get it now.
    // Either Window::clear was not called yet, or there was no return value,
    // and in that case, there's no harm in trying again (no benefit either).
    if (!returnValue)
        returnValue = dialogWindow->getDirect("returnValue");

    return returnValue ? returnValue : jsUndefined();
}

JSValue *Window::getValueProperty(ExecState *exec, int token) const
{
   ASSERT(impl()->frame());

   switch (token) {
   case Crypto:
      return jsUndefined(); // FIXME: implement this
    case Event_:
      if (!allowsAccessFrom(exec))
        return jsUndefined();
      if (!d->m_evt)
        return jsUndefined();
      return toJS(exec, d->m_evt);
    case Location_:
      return location();
    case Navigator_:
    case ClientInformation: {
      if (!allowsAccessFrom(exec))
        return jsUndefined();
      // Store the navigator in the object so we get the same one each time.
      Navigator* n = new Navigator(exec->lexicalGlobalObject()->objectPrototype(), impl()->frame());
      // FIXME: this will make the "navigator" object accessible from windows that fail
      // the security check the first time, but not subsequent times, seems weird.
      const_cast<Window *>(this)->putDirect("navigator", n, DontDelete);
      const_cast<Window *>(this)->putDirect("clientInformation", n, DontDelete);
      return n;
    }
    case Image:
      if (!allowsAccessFrom(exec))
        return jsUndefined();
      // FIXME: this property (and the few below) probably shouldn't create a new object every
      // time
      return new ImageConstructorImp(exec, impl()->frame()->document());
    case Option:
      if (!allowsAccessFrom(exec))
        return jsUndefined();
      return new JSHTMLOptionElementConstructor(exec, impl()->frame()->document());
    case XMLHttpRequest:
      if (!allowsAccessFrom(exec))
        return jsUndefined();
      return new JSXMLHttpRequestConstructorImp(exec, impl()->frame()->document());
    case Audio:
#if ENABLE(VIDEO)
      if (!allowsAccessFrom(exec))
        return jsUndefined();
      if (!MediaPlayer::isAvailable())
        return jsUndefined();
      return new JSAudioConstructor(exec, impl()->frame()->document());
#else
      return jsUndefined();
#endif
#if ENABLE(XSLT)
    case XSLTProcessor_:
      if (!allowsAccessFrom(exec))
        return jsUndefined();
      return new XSLTProcessorConstructorImp(exec);
#else
    case XSLTProcessor_:
      return jsUndefined();
#endif
   }

   if (!allowsAccessFrom(exec))
     return jsUndefined();

   switch (token) {
   case Onabort:
     return getListener(exec, abortEvent);
   case Onblur:
     return getListener(exec, blurEvent);
   case Onchange:
     return getListener(exec, changeEvent);
   case Onclick:
     return getListener(exec, clickEvent);
   case Ondblclick:
     return getListener(exec, dblclickEvent);
   case Onerror:
     return getListener(exec, errorEvent);
   case Onfocus:
     return getListener(exec, focusEvent);
   case Onkeydown:
     return getListener(exec, keydownEvent);
   case Onkeypress:
     return getListener(exec, keypressEvent);
   case Onkeyup:
     return getListener(exec, keyupEvent);
   case Onload:
     return getListener(exec, loadEvent);
   case Onmousedown:
     return getListener(exec, mousedownEvent);
   case Onmousemove:
     return getListener(exec, mousemoveEvent);
   case Onmouseout:
     return getListener(exec, mouseoutEvent);
   case Onmouseover:
     return getListener(exec, mouseoverEvent);
   case Onmouseup:
     return getListener(exec, mouseupEvent);
   case OnWindowMouseWheel:
     return getListener(exec, mousewheelEvent);
   case Onreset:
     return getListener(exec, resetEvent);
   case Onresize:
     return getListener(exec,resizeEvent);
   case Onscroll:
     return getListener(exec,scrollEvent);
   case Onsearch:
     return getListener(exec,searchEvent);
   case Onselect:
     return getListener(exec,selectEvent);
   case Onsubmit:
     return getListener(exec,submitEvent);
   case Onbeforeunload:
     return getListener(exec, beforeunloadEvent);
   case Onunload:
     return getListener(exec, unloadEvent);
   }
   ASSERT_NOT_REACHED();
   return jsUndefined();
}

JSValue* Window::childFrameGetter(ExecState*, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
{
    return retrieve(static_cast<Window*>(slot.slotBase())->impl()->frame()->tree()->child(AtomicString(propertyName)));
}

JSValue* Window::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
{
    return retrieve(static_cast<Window*>(slot.slotBase())->impl()->frame()->tree()->child(slot.index()));
}

JSValue* Window::namedItemGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot)
{
    Window* thisObj = static_cast<Window*>(slot.slotBase());
    Document* doc = thisObj->impl()->frame()->document();
    ASSERT(thisObj->allowsAccessFrom(exec));
    ASSERT(doc);
    ASSERT(doc->isHTMLDocument());

    RefPtr<WebCore::HTMLCollection> collection = doc->windowNamedItems(propertyName);
    if (collection->length() == 1)
        return toJS(exec, collection->firstItem());
    return toJS(exec, collection.get());
}

bool Window::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    // Check for child frames by name before built-in properties to
    // match Mozilla. This does not match IE, but some sites end up
    // naming frames things that conflict with window properties that
    // are in Moz but not IE. Since we have some of these, we have to do
    // it the Moz way.
    if (impl()->frame()->tree()->child(propertyName)) {
        slot.setCustom(this, childFrameGetter);
        return true;
    }

    const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
    if (entry) {
        if (entry->attr & Function) {
            if (entry->value.functionValue == windowProtoFuncShowModalDialog) {
                if (!canShowModalDialog(impl()->frame()))
                    return false;
            }
            if (allowsAccessFrom(exec))
                slot.setStaticEntry(this, entry, staticFunctionGetter);
            else
                slot.setUndefined(this);
        } else
            slot.setStaticEntry(this, entry, staticValueGetter<Window>);
        return true;
    }

    // Do prototype lookup early so that functions and attributes in the prototype can have
    // precedence over the index and name getters.  
    JSValue* proto = prototype();
    if (proto->isObject()) {
        if (static_cast<JSObject*>(proto)->getOwnPropertySlot(exec, propertyName, slot)) {
            if (!allowsAccessFrom(exec))
                slot.setUndefined(this);
            return true;
        }
    }

    // FIXME: Search the whole frame hierachy somewhere around here.
    // We need to test the correct priority order.

    // allow window[1] or parent[1] etc. (#56983)
    bool ok;
    unsigned i = propertyName.toArrayIndex(&ok);
    if (ok && i < impl()->frame()->tree()->childCount()) {
        slot.setCustomIndex(this, i, indexGetter);
        return true;
    }

    if (!allowsAccessFrom(exec)) {
        slot.setUndefined(this);
        return true;
    }

    // Allow shortcuts like 'Image1' instead of document.images.Image1
    Document* doc = impl()->frame()->document();
    if (doc && doc->isHTMLDocument()) {
        AtomicString atomicPropertyName = propertyName;
        if (static_cast<HTMLDocument*>(doc)->hasNamedItem(atomicPropertyName) || doc->getElementById(atomicPropertyName)) {
            slot.setCustom(this, namedItemGetter);
            return true;
        }
    }

    return Base::getOwnPropertySlot(exec, propertyName, slot);
}

void Window::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
{
  const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
  if (entry) {
     if (entry->attr & Function) {
       if (allowsAccessFrom(exec))
         Base::put(exec, propertyName, value, attr);
       return;
    }
    if (entry->attr & ReadOnly)
      return;

    switch (entry->value.intValue) {
    case Location_: {
      if (Frame* p = Window::retrieveActive(exec)->impl()->frame()) {
        // To avoid breaking old widgets, make "var location =" in a top-level frame create
        // a property named "location" instead of performing a navigation (<rdar://problem/5688039>).
        if (Settings* settings = p->settings()) {
          if (settings->usesDashboardBackwardCompatibilityMode() && !p->tree()->parent()) {
            if (allowsAccessFrom(exec))
              putDirect(propertyName, value, attr);
            return;
          }
        }

        if (!p->loader()->shouldAllowNavigation(impl()->frame()))
          return;
        String dstUrl = p->loader()->completeURL(value->toString(exec)).string();
        if (!dstUrl.startsWith("javascript:", false) || allowsAccessFrom(exec)) {
          bool userGesture = p->scriptProxy()->processingUserGesture();
          // We want a new history item if this JS was called via a user gesture
          impl()->frame()->loader()->scheduleLocationChange(dstUrl, p->loader()->outgoingReferrer(), false, userGesture);
        }
      }
      return;
    }
    case Onabort:
      if (allowsAccessFrom(exec))
        setListener(exec, abortEvent,value);
      return;
    case Onblur:
      if (allowsAccessFrom(exec))
        setListener(exec, blurEvent,value);
      return;
    case Onchange:
      if (allowsAccessFrom(exec))
        setListener(exec, changeEvent,value);
      return;
    case Onclick:
      if (allowsAccessFrom(exec))
        setListener(exec,clickEvent,value);
      return;
    case Ondblclick:
      if (allowsAccessFrom(exec))
        setListener(exec, dblclickEvent,value);
      return;
    case Onerror:
      if (allowsAccessFrom(exec))
        setListener(exec, errorEvent, value);
      return;
    case Onfocus:
      if (allowsAccessFrom(exec))
        setListener(exec,focusEvent,value);
      return;
    case Onkeydown:
      if (allowsAccessFrom(exec))
        setListener(exec,keydownEvent,value);
      return;
    case Onkeypress:
      if (allowsAccessFrom(exec))
        setListener(exec,keypressEvent,value);
      return;
    case Onkeyup:
      if (allowsAccessFrom(exec))
        setListener(exec,keyupEvent,value);
      return;
    case Onload:
      if (allowsAccessFrom(exec))
        setListener(exec,loadEvent,value);
      return;
    case Onmousedown:
      if (allowsAccessFrom(exec))
        setListener(exec,mousedownEvent,value);
      return;
    case Onmousemove:
      if (allowsAccessFrom(exec))
        setListener(exec,mousemoveEvent,value);
      return;
    case Onmouseout:
      if (allowsAccessFrom(exec))
        setListener(exec,mouseoutEvent,value);
      return;
    case Onmouseover:
      if (allowsAccessFrom(exec))
        setListener(exec,mouseoverEvent,value);
      return;
    case Onmouseup:
      if (allowsAccessFrom(exec))
        setListener(exec,mouseupEvent,value);
      return;
    case OnWindowMouseWheel:
      if (allowsAccessFrom(exec))
        setListener(exec, mousewheelEvent,value);
      return;
    case Onreset:
      if (allowsAccessFrom(exec))
        setListener(exec,resetEvent,value);
      return;
    case Onresize:
      if (allowsAccessFrom(exec))
        setListener(exec,resizeEvent,value);
      return;
    case Onscroll:
      if (allowsAccessFrom(exec))
        setListener(exec,scrollEvent,value);
      return;
    case Onsearch:
        if (allowsAccessFrom(exec))
            setListener(exec,searchEvent,value);
        return;
    case Onselect:
      if (allowsAccessFrom(exec))
        setListener(exec,selectEvent,value);
      return;
    case Onsubmit:
      if (allowsAccessFrom(exec))
        setListener(exec,submitEvent,value);
      return;
    case Onbeforeunload:
      if (allowsAccessFrom(exec))
        setListener(exec, beforeunloadEvent, value);
      return;
    case Onunload:
      if (allowsAccessFrom(exec))
        setListener(exec, unloadEvent, value);
      return;
    default:
      break;
    }
  }
  if (allowsAccessFrom(exec))
    Base::put(exec, propertyName, value, attr);
}

bool Window::allowsAccessFrom(const JSGlobalObject* other) const
{
    SecurityOrigin::Reason reason;
    if (allowsAccessFromPrivate(other, reason))
        return true;
    printErrorMessage(crossDomainAccessErrorMessage(other, reason));
    return false;
}

bool Window::allowsAccessFrom(ExecState* exec) const
{
    SecurityOrigin::Reason reason;
    if (allowsAccessFromPrivate(exec, reason))
        return true;
    printErrorMessage(crossDomainAccessErrorMessage(exec->dynamicGlobalObject(), reason));
    return false;
}
    
bool Window::allowsAccessFromNoErrorMessage(ExecState* exec) const
{
    SecurityOrigin::Reason reason;
    return allowsAccessFromPrivate(exec, reason);
}

bool Window::allowsAccessFrom(ExecState* exec, String& message) const
{
    SecurityOrigin::Reason reason;
    if (allowsAccessFromPrivate(exec, reason))
        return true;
    message = crossDomainAccessErrorMessage(exec->dynamicGlobalObject(), reason);
    return false;
}
    
ALWAYS_INLINE bool Window::allowsAccessFromPrivate(const ExecState* exec, SecurityOrigin::Reason& reason) const
{
    if (allowsAccessFromPrivate(exec->dynamicGlobalObject(), reason))
        return true;
    if (reason == SecurityOrigin::DomainSetInDOMMismatch) {
        // If the only reason the access failed was a domainSetInDOM bit mismatch, try again against 
        // lexical global object <rdar://problem/5698200>
        if (allowsAccessFromPrivate(exec->lexicalGlobalObject(), reason))
            return true;
    }
    return false;
}

ALWAYS_INLINE bool Window::allowsAccessFromPrivate(const JSGlobalObject* other, SecurityOrigin::Reason& reason) const
{
    const Frame* originFrame = static_cast<const Window*>(other)->impl()->frame();
    if (!originFrame) {
        reason = SecurityOrigin::GenericMismatch;
        return false;
    }

    const Frame* targetFrame = impl()->frame();

    if (originFrame == targetFrame)
        return true;
    
    if (!targetFrame) {
        reason = SecurityOrigin::GenericMismatch;
        return false;
    }

    WebCore::Document* targetDocument = targetFrame->document();

    // JS may be attempting to access the "window" object, which should be valid,
    // even if the document hasn't been constructed yet.  If the document doesn't
    // exist yet allow JS to access the window object.
    if (!targetDocument)
        return true;

    WebCore::Document* originDocument = originFrame->document();

    const SecurityOrigin* originSecurityOrigin = originDocument->securityOrigin();
    const SecurityOrigin* targetSecurityOrigin = targetDocument->securityOrigin();

    if (originSecurityOrigin->canAccess(targetSecurityOrigin, reason))
        return true;

    return false;
}

String Window::crossDomainAccessErrorMessage(const JSGlobalObject* other, SecurityOrigin::Reason) const
{
    const Frame* originFrame = static_cast<const Window*>(other)->impl()->frame();
    const Frame* targetFrame = impl()->frame();
    if (!originFrame || !targetFrame)
        return String();
    WebCore::Document* targetDocument = targetFrame->document();
    WebCore::Document* originDocument = originFrame->document();
    if (!originDocument || !targetDocument)
        return String();
    // FIXME: this error message should contain more specifics of why the same origin check has failed.
    return String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains, protocols and ports must match.\n",
                          targetDocument->url().utf8().data(), originDocument->url().utf8().data());
}

void Window::printErrorMessage(const String& message) const
{
    if (message.isEmpty())
        return;

    Frame* frame = impl()->frame();
    if (!frame)
        return;

    if (frame->settings()->privateBrowsingEnabled())
        return;

    if (Interpreter::shouldPrintExceptions())
        printf("%s", message.utf8().data());

    if (Page* page = frame->page())
        page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL.
}

ExecState* Window::globalExec()
{
    // We need to make sure that any script execution happening in this
    // frame does not destroy it
    ASSERT(impl()->frame());
    impl()->frame()->keepAlive();
    return Base::globalExec();
}

bool Window::shouldInterruptScript() const
{
    ASSERT(impl()->frame());
    Page* page = impl()->frame()->page();

    // See <rdar://problem/5479443>. We don't think that page can ever be NULL
    // in this case, but if it is, we've gotten into a state where we may have
    // hung the UI, with no way to ask the client whether to cancel execution.
    // For now, our solution is just to cancel execution no matter what,
    // ensuring that we never hang. We might want to consider other solutions
    // if we discover problems with this one.
    ASSERT(page);
    if (!page)
        return true;

    return page->chrome()->shouldInterruptJavaScript();
}

void Window::setListener(ExecState* exec, const AtomicString& eventType, JSValue* func)
{
    ASSERT(impl()->frame());
    Document* doc = impl()->frame()->document();
    if (!doc)
        return;

    doc->setHTMLWindowEventListener(eventType, findOrCreateJSEventListener(func, true));
}

JSValue* Window::getListener(ExecState* exec, const AtomicString& eventType) const
{
    ASSERT(impl()->frame());
    Document* doc = impl()->frame()->document();
    if (!doc)
        return jsUndefined();

    WebCore::EventListener* listener = doc->getHTMLWindowEventListener(eventType);
    if (listener && static_cast<JSEventListener*>(listener)->listenerObj())
        return static_cast<JSEventListener*>(listener)->listenerObj();
    return jsNull();
}

JSEventListener* Window::findJSEventListener(JSValue* val, bool html)
{
    if (!val->isObject())
        return 0;
    JSObject* object = static_cast<JSObject*>(val);
    ListenersMap& listeners = html ? d->jsHTMLEventListeners : d->jsEventListeners;
    return listeners.get(object);
}

JSEventListener* Window::findOrCreateJSEventListener(JSValue* val, bool html)
{
    JSEventListener* listener = findJSEventListener(val, html);
    if (listener)
        return listener;

    if (!val->isObject())
        return 0;
    JSObject* object = static_cast<JSObject*>(val);

    // Note that the JSEventListener constructor adds it to our jsEventListeners list
    return new JSEventListener(object, this, html);
}

JSUnprotectedEventListener* Window::findJSUnprotectedEventListener(JSValue* val, bool html)
{
    if (!val->isObject())
        return 0;
    JSObject* object = static_cast<JSObject*>(val);
    UnprotectedListenersMap& listeners = html ? d->jsUnprotectedHTMLEventListeners : d->jsUnprotectedEventListeners;
    return listeners.get(object);
}

JSUnprotectedEventListener* Window::findOrCreateJSUnprotectedEventListener(JSValue* val, bool html)
{
    JSUnprotectedEventListener* listener = findJSUnprotectedEventListener(val, html);
    if (listener)
        return listener;
    if (!val->isObject())
        return 0;
    JSObject* object = static_cast<JSObject*>(val);

    // The JSUnprotectedEventListener constructor adds it to our jsUnprotectedEventListeners map.
    return new JSUnprotectedEventListener(object, this, html);
}

void Window::clearHelperObjectProperties()
{
    d->loc = 0;
    d->m_evt = 0;
}

void Window::clear()
{
  JSLock lock;

  if (d->m_returnValueSlot && !*d->m_returnValueSlot)
    *d->m_returnValueSlot = getDirect("returnValue");

  clearAllTimeouts();
  clearHelperObjectProperties();

  // Now recreate a working global object for the next URL that will use us; but only if we haven't been
  // disconnected yet
  if (Frame* frame = impl()->frame())
    frame->scriptProxy()->globalObject()->reset(JSDOMWindowPrototype::self());

  // there's likely to be lots of garbage now
  gcController().garbageCollectSoon();
}

void Window::setCurrentEvent(Event* evt)
{
    d->m_evt = evt;
}

Event* Window::currentEvent()
{
    return d->m_evt;
}

JSValue* windowProtoFuncAToB(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);
    if (!static_cast<Window*>(thisObj)->allowsAccessFrom(exec)) 
        return jsUndefined();

    if (args.size() < 1)
        return throwError(exec, SyntaxError, "Not enough arguments");

    JSValue* v = args[0];
    if (v->isNull())
        return jsString();

    UString s = v->toString(exec);
    if (!s.is8Bit()) {
        setDOMException(exec, INVALID_CHARACTER_ERR);
        return jsUndefined();
    }

    Vector<char> in(s.size());
    for (int i = 0; i < s.size(); ++i)
        in[i] = static_cast<char>(s.data()[i].unicode());
    Vector<char> out;

    if (!base64Decode(in, out))
        return throwError(exec, GeneralError, "Cannot decode base64");

    return jsString(String(out.data(), out.size()));
}

JSValue* windowProtoFuncBToA(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);
    if (!static_cast<Window*>(thisObj)->allowsAccessFrom(exec)) 
        return jsUndefined();

    if (args.size() < 1)
        return throwError(exec, SyntaxError, "Not enough arguments");

    JSValue* v = args[0];
    if (v->isNull())
        return jsString();

    UString s = v->toString(exec);
    if (!s.is8Bit()) {
        setDOMException(exec, INVALID_CHARACTER_ERR);
        return jsUndefined();
    }

    Vector<char> in(s.size());
    for (int i = 0; i < s.size(); ++i)
        in[i] = static_cast<char>(s.data()[i].unicode());
    Vector<char> out;

    base64Encode(in, out);

    return jsString(String(out.data(), out.size()));
}

JSValue* windowProtoFuncOpen(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);
    Window* window = static_cast<Window*>(thisObj);
    if (!window->allowsAccessFrom(exec)) 
        return jsUndefined();

    Frame* frame = window->impl()->frame();
    if (!frame)
        return jsUndefined();
    Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
    if (!activeFrame)
        return  jsUndefined();

    Page* page = frame->page();

    String urlString = valueToStringWithUndefinedOrNullCheck(exec, args[0]);
    AtomicString frameName = args[1]->isUndefinedOrNull() ? "_blank" : AtomicString(args[1]->toString(exec));

    // Because FrameTree::find() returns true for empty strings, we must check for empty framenames.
    // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
    if (!allowPopUp(exec) && (frameName.isEmpty() || !frame->tree()->find(frameName)))
        return jsUndefined();

    // Get the target frame for the special cases of _top and _parent.  In those
    // cases, we can schedule a location change right now and return early.
    bool topOrParent = false;
    if (frameName == "_top") {
        frame = frame->tree()->top();
        topOrParent = true;
    } else if (frameName == "_parent") {
        if (Frame* parent = frame->tree()->parent())
            frame = parent;
        topOrParent = true;
    }
    if (topOrParent) {
        if (!activeFrame->loader()->shouldAllowNavigation(frame))
            return jsUndefined();

        String completedURL;
        if (!urlString.isEmpty())
            completedURL = activeFrame->document()->completeURL(urlString);

        const Window* targetedWindow = Window::retrieveWindow(frame);
        if (!completedURL.isEmpty() && (!completedURL.startsWith("javascript:", false) || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) {
            bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
            frame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture);
        }
        return Window::retrieve(frame);
    }

    // In the case of a named frame or a new window, we'll use the createWindow() helper
    WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args[2]));
    FloatRect windowRect(windowFeatures.x, windowFeatures.y, windowFeatures.width, windowFeatures.height);
    WebCore::DOMWindow::adjustWindowRect(screenAvailableRect(page->mainFrame()->view()), windowRect, windowRect);

    windowFeatures.x = windowRect.x();
    windowFeatures.y = windowRect.y();
    windowFeatures.height = windowRect.height();
    windowFeatures.width = windowRect.width();

    frame = createWindow(exec, frame, urlString, frameName, windowFeatures, 0);

    if (!frame)
        return jsUndefined();

    return Window::retrieve(frame); // global object
}

JSValue* windowProtoFuncSetTimeout(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);
    Window* window = static_cast<Window*>(thisObj);
    if (!window->allowsAccessFrom(exec)) 
        return jsUndefined();

    JSValue* v = args[0];
    if (v->isString())
        return jsNumber(window->installTimeout(v->toString(exec), args[1]->toInt32(exec), true /*single shot*/));
    if (v->isObject() && static_cast<JSObject*>(v)->implementsCall()) {
        List argsTail;
        args.getSlice(2, argsTail);
        return jsNumber(window->installTimeout(v, argsTail, args[1]->toInt32(exec), true /*single shot*/));
    }

    return jsUndefined();
}

JSValue* windowProtoFuncClearTimeout(ExecState* exec, JSObject* thisObj, const List& args)
{
    // Also the implementation for window.clearInterval()

    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);
    Window* window = static_cast<Window*>(thisObj);
    if (!window->allowsAccessFrom(exec)) 
        return jsUndefined();

    window->clearTimeout(args[0]->toInt32(exec));
    return jsUndefined();
}

JSValue* windowProtoFuncSetInterval(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);
    Window* window = static_cast<Window*>(thisObj);
    if (!window->allowsAccessFrom(exec)) 
        return jsUndefined();

    if (args.size() >= 2) {
        JSValue* v = args[0];
        int delay = args[1]->toInt32(exec);
        if (v->isString())
            return jsNumber(window->installTimeout(v->toString(exec), delay, false));
        if (v->isObject() && static_cast<JSObject*>(v)->implementsCall()) {
            List argsTail;
            args.getSlice(2, argsTail);
            return jsNumber(window->installTimeout(v, argsTail, delay, false));
        }
    }

    return jsUndefined();

}

JSValue* windowProtoFuncAddEventListener(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);
    Window* window = static_cast<Window*>(thisObj);
    if (!window->allowsAccessFrom(exec)) 
        return jsUndefined();
    Frame* frame = window->impl()->frame();
    if (!frame)
        return jsUndefined();

    if (JSEventListener* listener = window->findOrCreateJSEventListener(args[1])) {
        if (Document* doc = frame->document())
            doc->addWindowEventListener(AtomicString(args[0]->toString(exec)), listener, args[2]->toBoolean(exec));
    }

    return jsUndefined();
}

JSValue* windowProtoFuncRemoveEventListener(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);
    Window* window = static_cast<Window*>(thisObj);
    if (!window->allowsAccessFrom(exec)) 
        return jsUndefined();
    Frame* frame = window->impl()->frame();
    if (!frame)
        return jsUndefined();

    if (JSEventListener* listener = window->findJSEventListener(args[1])) {
        if (Document* doc = frame->document())
            doc->removeWindowEventListener(AtomicString(args[0]->toString(exec)), listener, args[2]->toBoolean(exec));
    }

    return jsUndefined();
}

JSValue* windowProtoFuncShowModalDialog(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);
    Window* window = static_cast<Window*>(thisObj);
    Frame* frame = window->impl()->frame();
    if (!frame)
        return jsUndefined();

    return showModalDialog(exec, frame, valueToStringWithUndefinedOrNullCheck(exec, args[0]), args[1], valueToStringWithUndefinedOrNullCheck(exec, args[2]));
}

JSValue* windowProtoFuncNotImplemented(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&Window::info))
        return throwError(exec, TypeError);

    return jsUndefined();
}

void Window::setReturnValueSlot(JSValue** slot)
{
    d->m_returnValueSlot = slot;
}

////////////////////// timeouts ////////////////////////

void Window::clearAllTimeouts()
{
    deleteAllValues(d->m_timeouts);
    d->m_timeouts.clear();
}

int Window::installTimeout(WebCore::ScheduledAction* a, int t, bool singleShot)
{
    int timeoutId = ++lastUsedTimeoutId;

    // avoid wraparound going negative on us
    if (timeoutId <= 0)
        timeoutId = 1;

    int nestLevel = timerNestingLevel + 1;
    DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, nestLevel, this, a);
    ASSERT(!d->m_timeouts.get(timeoutId));
    d->m_timeouts.set(timeoutId, timer);
    // Use a minimum interval of 10 ms to match other browsers, but only once we've
    // nested enough to notice that we're repeating.
    // Faster timers might be "better", but they're incompatible.
    double interval = max(0.001, t * 0.001);
    if (interval < cMinimumTimerInterval && nestLevel >= cMaxTimerNestingLevel)
        interval = cMinimumTimerInterval;
    if (singleShot)
        timer->startOneShot(interval);
    else
        timer->startRepeating(interval);
    return timeoutId;
}

int Window::installTimeout(const UString& handler, int t, bool singleShot)
{
    return installTimeout(new WebCore::ScheduledAction(handler), t, singleShot);
}

int Window::installTimeout(JSValue* func, const List& args, int t, bool singleShot)
{
    return installTimeout(new WebCore::ScheduledAction(func, args), t, singleShot);
}

WebCore::PausedTimeouts* Window::pauseTimeouts()
{
    size_t count = d->m_timeouts.size();
    if (count == 0)
        return 0;

    PausedTimeout* t = new PausedTimeout [count];
    PausedTimeouts* result = new PausedTimeouts(t, count);

    WindowPrivate::TimeoutsMap::iterator it = d->m_timeouts.begin();
    for (size_t i = 0; i != count; ++i, ++it) {
        int timeoutId = it->first;
        DOMWindowTimer* timer = it->second;
        t[i].timeoutId = timeoutId;
        t[i].nestingLevel = timer->nestingLevel();
        t[i].nextFireInterval = timer->nextFireInterval();
        t[i].repeatInterval = timer->repeatInterval();
        t[i].action = timer->takeAction();
    }
    ASSERT(it == d->m_timeouts.end());

    deleteAllValues(d->m_timeouts);
    d->m_timeouts.clear();

    return result;
}

void Window::resumeTimeouts(PausedTimeouts* timeouts)
{
    if (!timeouts)
        return;
    size_t count = timeouts->numTimeouts();
    PausedTimeout* array = timeouts->takeTimeouts();
    for (size_t i = 0; i != count; ++i) {
        int timeoutId = array[i].timeoutId;
        DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, array[i].nestingLevel, this, array[i].action);
        d->m_timeouts.set(timeoutId, timer);
        timer->start(array[i].nextFireInterval, array[i].repeatInterval);
    }
    delete [] array;
}

void Window::clearTimeout(int timeoutId, bool delAction)
{
    // timeout IDs have to be positive, and 0 and -1 are unsafe to
    // even look up since they are the empty and deleted value
    // respectively
    if (timeoutId <= 0)
        return;

    delete d->m_timeouts.take(timeoutId);
}

void Window::timerFired(DOMWindowTimer* timer)
{
    // Simple case for non-one-shot timers.
    if (timer->isActive()) {
        int timeoutId = timer->timeoutId();

        timer->action()->execute(this);
        // The DOMWindowTimer object may have been deleted or replaced during execution,
        // so we re-fetch it.
        timer = d->m_timeouts.get(timeoutId);
        if (!timer)
            return;

        if (timer->repeatInterval() && timer->repeatInterval() < cMinimumTimerInterval) {
            timer->setNestingLevel(timer->nestingLevel() + 1);
            if (timer->nestingLevel() >= cMaxTimerNestingLevel)
                timer->augmentRepeatInterval(cMinimumTimerInterval - timer->repeatInterval());
        }
        return;
    }

    // Delete timer before executing the action for one-shot timers.
    WebCore::ScheduledAction* action = timer->takeAction();
    d->m_timeouts.remove(timer->timeoutId());
    delete timer;
    action->execute(this);

    JSLock lock;
    delete action;
}

void Window::disconnectFrame()
{
    clearAllTimeouts();
    if (d->loc)
        d->loc->m_frame = 0;
}

Window::ListenersMap& Window::jsEventListeners()
{
    return d->jsEventListeners;
}

Window::ListenersMap& Window::jsHTMLEventListeners()
{
    return d->jsHTMLEventListeners;
}

Window::UnprotectedListenersMap& Window::jsUnprotectedEventListeners()
{
    return d->jsUnprotectedEventListeners;
}

Window::UnprotectedListenersMap& Window::jsUnprotectedHTMLEventListeners()
{
    return d->jsUnprotectedHTMLEventListeners;
}

/////////////////////////////////////////////////////////////////////////////

void DOMWindowTimer::fired()
{
    timerNestingLevel = m_nestingLevel;
    m_object->timerFired(this);
    timerNestingLevel = 0;
}

} // namespace KJS

using namespace KJS;

namespace WebCore {

JSValue* toJS(ExecState*, DOMWindow* domWindow)
{
    if (!domWindow)
        return jsNull();
    Frame* frame = domWindow->frame();
    if (!frame)
        return jsNull();
    return Window::retrieve(frame);
}

} // namespace WebCore
