Changeset 28794 in webkit


Ignore:
Timestamp:
Dec 16, 2007 8:50:53 PM (16 years ago)
Author:
weinig@apple.com
Message:

Reviewed by Maciej.

Yet more of http://bugs.webkit.org/show_bug.cgi?id=16385
Cleanup kjs_window

  • Move ScheduledAction into its own file and put it in the WebCore namespace.
  • WebCore.pro:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • WebCoreSources.bkl:
  • bindings/js/PausedTimeouts.cpp:
  • bindings/js/PausedTimeouts.h:
  • bindings/js/ScheduledAction.cpp: Copied from bindings/js/kjs_window.cpp. (WebCore::ScheduledAction::ScheduledAction): (WebCore::ScheduledAction::execute):
  • bindings/js/ScheduledAction.h: Copied from bindings/js/kjs_window.h. (WebCore::ScheduledAction::ScheduledAction):
  • bindings/js/kjs_window.cpp: (KJS::DOMWindowTimer::DOMWindowTimer): (KJS::DOMWindowTimer::action): (KJS::DOMWindowTimer::takeAction): (KJS::Window::installTimeout): (KJS::Window::timerFired):
  • bindings/js/kjs_window.h:
Location:
trunk/WebCore
Files:
9 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r28792 r28794  
     12007-12-16  Sam Weinig  <sam@webkit.org>
     2
     3        Reviewed by Maciej.
     4
     5        Yet more of http://bugs.webkit.org/show_bug.cgi?id=16385
     6        Cleanup kjs_window
     7
     8        - Move ScheduledAction into its own file and put it in the WebCore namespace.
     9
     10        * WebCore.pro:
     11        * WebCore.vcproj/WebCore.vcproj:
     12        * WebCore.xcodeproj/project.pbxproj:
     13        * WebCoreSources.bkl:
     14        * bindings/js/PausedTimeouts.cpp:
     15        * bindings/js/PausedTimeouts.h:
     16        * bindings/js/ScheduledAction.cpp: Copied from bindings/js/kjs_window.cpp.
     17        (WebCore::ScheduledAction::ScheduledAction):
     18        (WebCore::ScheduledAction::execute):
     19        * bindings/js/ScheduledAction.h: Copied from bindings/js/kjs_window.h.
     20        (WebCore::ScheduledAction::ScheduledAction):
     21        * bindings/js/kjs_window.cpp:
     22        (KJS::DOMWindowTimer::DOMWindowTimer):
     23        (KJS::DOMWindowTimer::action):
     24        (KJS::DOMWindowTimer::takeAction):
     25        (KJS::Window::installTimeout):
     26        (KJS::Window::timerFired):
     27        * bindings/js/kjs_window.h:
     28
    1292007-12-16  Alp Toker  <alp@atoker.com>
    230
  • trunk/WebCore/WebCore.pro

    r28792 r28794  
    420420    bindings/js/kjs_window.cpp \
    421421    bindings/js/PausedTimeouts.cpp \
     422    bindings/js/ScheduledAction.cpp \
    422423    css/CSSBorderImageValue.cpp \
    423424    css/CSSCharsetRule.cpp \
  • trunk/WebCore/WebCore.vcproj/WebCore.vcproj

    r28790 r28794  
    76487648                                        >
    76497649                                </File>
     7650                                <File
     7651                                        RelativePath="..\bindings\js\ScheduledAction.cpp"
     7652                                        >
     7653                                </File>
     7654                                <File
     7655                                        RelativePath="..\bindings\js\ScheduledAction.h"
     7656                                        >
     7657                                </File>
    76507658                        </Filter>
    76517659                </Filter>
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r28791 r28794  
    36443644                BCA378160D15C64600B793D6 /* PausedTimeouts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA378140D15C64600B793D6 /* PausedTimeouts.cpp */; };
    36453645                BCA378170D15C64600B793D6 /* PausedTimeouts.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA378150D15C64600B793D6 /* PausedTimeouts.h */; };
     3646                BCA378BC0D15F64200B793D6 /* ScheduledAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA378BA0D15F64200B793D6 /* ScheduledAction.cpp */; };
     3647                BCA378BD0D15F64200B793D6 /* ScheduledAction.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA378BB0D15F64200B793D6 /* ScheduledAction.h */; };
    36463648                BCA85A100C3AEAF4006F8308 /* DOMSVGNumberInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA85A0F0C3AEAF4006F8308 /* DOMSVGNumberInternal.h */; };
    36473649                BCAA90C30A7EBA60008B1229 /* ScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCAA90C20A7EBA60008B1229 /* ScrollBar.cpp */; };
     
    76557657                BCA378140D15C64600B793D6 /* PausedTimeouts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PausedTimeouts.cpp; sourceTree = "<group>"; };
    76567658                BCA378150D15C64600B793D6 /* PausedTimeouts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PausedTimeouts.h; sourceTree = "<group>"; };
     7659                BCA378BA0D15F64200B793D6 /* ScheduledAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScheduledAction.cpp; sourceTree = "<group>"; };
     7660                BCA378BB0D15F64200B793D6 /* ScheduledAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScheduledAction.h; sourceTree = "<group>"; };
    76577661                BCA85A0F0C3AEAF4006F8308 /* DOMSVGNumberInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMSVGNumberInternal.h; sourceTree = "<group>"; };
    76587662                BCAA90C20A7EBA60008B1229 /* ScrollBar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ScrollBar.cpp; path = platform/ScrollBar.cpp; sourceTree = SOURCE_ROOT; };
     
    1141011414                                BCA378140D15C64600B793D6 /* PausedTimeouts.cpp */,
    1141111415                                BCA378150D15C64600B793D6 /* PausedTimeouts.h */,
     11416                                BCA378BA0D15F64200B793D6 /* ScheduledAction.cpp */,
     11417                                BCA378BB0D15F64200B793D6 /* ScheduledAction.h */,
    1141211418                        );
    1141311419                        path = js;
     
    1410714113                                B28BC31A0D135E5400CDBA27 /* JSEventTargetBase.lut.h in Headers */,
    1410814114                                BCA378170D15C64600B793D6 /* PausedTimeouts.h in Headers */,
     14115                                BCA378BD0D15F64200B793D6 /* ScheduledAction.h in Headers */,
    1410914116                        );
    1411014117                        runOnlyForDeploymentPostprocessing = 0;
     
    1581915826                                BC4BF9E40D11E133007D247F /* ClassNames.cpp in Sources */,
    1582015827                                BCA378160D15C64600B793D6 /* PausedTimeouts.cpp in Sources */,
     15828                                BCA378BC0D15F64200B793D6 /* ScheduledAction.cpp in Sources */,
    1582115829                        );
    1582215830                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/WebCore/WebCoreSources.bkl

    r28779 r28794  
    9494        bindings/js/kjs_window.cpp
    9595        bindings/js/PausedTimeouts.cpp
     96        bindings/js/ScheduledAction.cpp
    9697    </set>
    9798   
  • trunk/WebCore/bindings/js/PausedTimeouts.cpp

    r28779 r28794  
    2424#include "PausedTimeouts.h"
    2525
    26 #include "kjs_window.h"
     26#include "ScheduledAction.h"
    2727
    2828namespace WebCore {
  • trunk/WebCore/bindings/js/PausedTimeouts.h

    r28779 r28794  
    2323#include <wtf/Noncopyable.h>
    2424
    25 namespace KJS {
     25namespace WebCore {
     26
    2627    class ScheduledAction;
    27 }
    28 
    29 namespace WebCore {
    3028
    3129    struct PausedTimeout {
     
    3432        double nextFireInterval;
    3533        double repeatInterval;
    36         KJS::ScheduledAction* action;
     34        ScheduledAction* action;
    3735    };
    3836
  • trunk/WebCore/bindings/js/ScheduledAction.cpp

    r28779 r28794  
    1 // -*- c-basic-offset: 4 -*-
    21/*
    32 *  Copyright (C) 2000 Harri Porten (porten@kde.org)
     
    2322
    2423#include "config.h"
    25 #include "kjs_window.h"
     24#include "ScheduledAction.h"
    2625
    27 #include "Base64.h"
    2826#include "CString.h"
    2927#include "Chrome.h"
    3028#include "DOMWindow.h"
    31 #include "Element.h"
    32 #include "EventListener.h"
    33 #include "EventNames.h"
    34 #include "ExceptionCode.h"
    35 #include "FloatRect.h"
     29#include "Document.h"
    3630#include "Frame.h"
    37 #include "FrameLoadRequest.h"
    3831#include "FrameLoader.h"
    39 #include "FrameTree.h"
    40 #include "GCController.h"
    41 #include "HTMLDocument.h"
    42 #include "JSDOMExceptionConstructor.h"
    43 #include "JSDOMWindow.h"
    44 #include "JSEvent.h"
    45 #include "JSHTMLAudioElementConstructor.h"
    46 #include "JSHTMLCollection.h"
    47 #include "JSHTMLOptionElementConstructor.h"
    48 #include "JSXMLHttpRequest.h"
    49 #include "Logging.h"
    5032#include "Page.h"
    51 #include "PausedTimeouts.h"
    52 #include "PlatformScreen.h"
    53 #include "PlugInInfoStore.h"
    54 #include "RenderView.h"
    55 #include "SecurityOrigin.h"
    56 #include "Settings.h"
    57 #include "WindowFeatures.h"
    58 #include "htmlediting.h"
    59 #include "kjs_css.h"
    60 #include "kjs_events.h"
    61 #include "kjs_navigator.h"
    6233#include "kjs_proxy.h"
    63 #include <wtf/MathExtras.h>
     34#include "kjs_window.h"
    6435
    65 #if ENABLE(XSLT)
    66 #include "JSXSLTProcessor.h"
    67 #endif
     36using namespace KJS;
    6837
    69 using namespace WebCore;
    70 using namespace EventNames;
     38namespace WebCore {
    7139
    72 namespace KJS {
    73 
    74 static int lastUsedTimeoutId;
    75 
    76 static int timerNestingLevel = 0;
    77 const int cMaxTimerNestingLevel = 5;
    78 const double cMinimumTimerInterval = 0.010;
    79 
    80 struct WindowPrivate {
    81     WindowPrivate()
    82         : loc(0)
    83         , m_evt(0)
    84         , m_returnValueSlot(0)
    85     {
    86     }
    87 
    88     Window::ListenersMap jsEventListeners;
    89     Window::ListenersMap jsHTMLEventListeners;
    90     Window::UnprotectedListenersMap jsUnprotectedEventListeners;
    91     Window::UnprotectedListenersMap jsUnprotectedHTMLEventListeners;
    92     mutable Location* loc;
    93     WebCore::Event* m_evt;
    94     JSValue** m_returnValueSlot;
    95 
    96     typedef HashMap<int, DOMWindowTimer*> TimeoutsMap;
    97     TimeoutsMap m_timeouts;
    98 };
    99 
    100 class DOMWindowTimer : public TimerBase {
    101 public:
    102     DOMWindowTimer(int timeoutId, int nestingLevel, Window* object, ScheduledAction* action)
    103         : m_timeoutId(timeoutId)
    104         , m_nestingLevel(nestingLevel)
    105         , m_object(object)
    106         , m_action(action)
    107     {
    108     }
    109 
    110     virtual ~DOMWindowTimer()
    111     {
    112         JSLock lock;
    113         delete m_action;
    114     }
    115 
    116     int timeoutId() const { return m_timeoutId; }
    117 
    118     int nestingLevel() const { return m_nestingLevel; }
    119     void setNestingLevel(int n) { m_nestingLevel = n; }
    120 
    121     ScheduledAction* action() const { return m_action; }
    122     ScheduledAction* takeAction() { ScheduledAction* a = m_action; m_action = 0; return a; }
    123 
    124 private:
    125     virtual void fired();
    126 
    127     int m_timeoutId;
    128     int m_nestingLevel;
    129     Window* m_object;
    130     ScheduledAction* m_action;
    131 };
    132 
    133 } // namespace KJS
    134 
    135 #include "kjs_window.lut.h"
    136 
    137 namespace KJS {
    138 
    139 ////////////////////// Window Object ////////////////////////
    140 
    141 const ClassInfo Window::info = { "Window", 0, &WindowTable };
    142 
    143 /*
    144 @begin WindowTable 118
    145 # Warning, when adding a function to this object you need to add a case in Window::get
    146 # -- Functions --
    147   atob                  &WindowProtoFuncAToB::create                DontDelete|Function 1
    148   btoa                  &WindowProtoFuncBToA::create                DontDelete|Function 1
    149   open                  &WindowProtoFuncOpen::create                DontDelete|Function 3
    150   setTimeout            &WindowProtoFuncSetTimeout::create          DontDelete|Function 2
    151   clearTimeout          &WindowProtoFuncClearTimeout::create        DontDelete|Function 1
    152   setInterval           &WindowProtoFuncSetInterval::create         DontDelete|Function 2
    153   clearInterval         &WindowProtoFuncClearTimeout::create        DontDelete|Function 1
    154   addEventListener      &WindowProtoFuncAddEventListener::create    DontDelete|Function 3
    155   removeEventListener   &WindowProtoFuncRemoveEventListener::create DontDelete|Function 3
    156   showModalDialog       &WindowProtoFuncShowModalDialog::create     DontDelete|Function 1
    157 # Not implemented
    158   captureEvents         &WindowProtoFuncNotImplemented::create      DontDelete|Function 0
    159   releaseEvents         &WindowProtoFuncNotImplemented::create      DontDelete|Function 0
    160 
    161 # -- Attributes --
    162   crypto                Window::Crypto              DontDelete|ReadOnly
    163   event                 Window::Event_              DontDelete
    164   location              Window::Location_           DontDelete
    165   navigator             Window::Navigator_          DontDelete|ReadOnly
    166   clientInformation     Window::ClientInformation   DontDelete|ReadOnly
    167 # -- Event Listeners --
    168   onabort               Window::Onabort             DontDelete
    169   onblur                Window::Onblur              DontDelete
    170   onchange              Window::Onchange            DontDelete
    171   onclick               Window::Onclick             DontDelete
    172   ondblclick            Window::Ondblclick          DontDelete
    173   onerror               Window::Onerror             DontDelete
    174   onfocus               Window::Onfocus             DontDelete
    175   onkeydown             Window::Onkeydown           DontDelete
    176   onkeypress            Window::Onkeypress          DontDelete
    177   onkeyup               Window::Onkeyup             DontDelete
    178   onload                Window::Onload              DontDelete
    179   onmousedown           Window::Onmousedown         DontDelete
    180   onmousemove           Window::Onmousemove         DontDelete
    181   onmouseout            Window::Onmouseout          DontDelete
    182   onmouseover           Window::Onmouseover         DontDelete
    183   onmouseup             Window::Onmouseup           DontDelete
    184   onmousewheel          Window::OnWindowMouseWheel  DontDelete
    185   onreset               Window::Onreset             DontDelete
    186   onresize              Window::Onresize            DontDelete
    187   onscroll              Window::Onscroll            DontDelete
    188   onsearch              Window::Onsearch            DontDelete
    189   onselect              Window::Onselect            DontDelete
    190   onsubmit              Window::Onsubmit            DontDelete
    191   onunload              Window::Onunload            DontDelete
    192   onbeforeunload        Window::Onbeforeunload      DontDelete
    193 # -- Constructors --
    194   Audio                 Window::Audio               DontDelete
    195   DOMException          Window::DOMException        DontDelete
    196   Image                 Window::Image               DontDelete
    197   Option                Window::Option              DontDelete
    198   XMLHttpRequest        Window::XMLHttpRequest      DontDelete
    199   XSLTProcessor         Window::XSLTProcessor_      DontDelete
    200 @end
    201 */
    202 
    203 Window::Window(DOMWindow* window)
    204     : m_impl(window)
    205     , d(new WindowPrivate)
     40ScheduledAction::ScheduledAction(JSValue* func, const List& args)
     41    : m_func(func)
    20642{
    207     // Window destruction is not thread-safe because of
    208     // the non-thread-safe WebCore structures it references.
    209     Collector::collectOnMainThreadOnly(this);
    210 
    211     // Time in milliseconds before the script timeout handler kicks in.
    212     setTimeoutTime(10000);
     43    List::const_iterator end = args.end();
     44    for (List::const_iterator it = args.begin(); it != end; ++it)
     45        m_args.append(*it);
    21346}
    21447
    215 Window::~Window()
    216 {
    217     clearAllTimeouts();
    218 
    219     // Clear any backpointers to the window
    220 
    221     ListenersMap::iterator i2 = d->jsEventListeners.begin();
    222     ListenersMap::iterator e2 = d->jsEventListeners.end();
    223     for (; i2 != e2; ++i2)
    224         i2->second->clearWindowObj();
    225     i2 = d->jsHTMLEventListeners.begin();
    226     e2 = d->jsHTMLEventListeners.end();
    227     for (; i2 != e2; ++i2)
    228         i2->second->clearWindowObj();
    229 
    230     UnprotectedListenersMap::iterator i1 = d->jsUnprotectedEventListeners.begin();
    231     UnprotectedListenersMap::iterator e1 = d->jsUnprotectedEventListeners.end();
    232     for (; i1 != e1; ++i1)
    233         i1->second->clearWindowObj();
    234     i1 = d->jsUnprotectedHTMLEventListeners.begin();
    235     e1 = d->jsUnprotectedHTMLEventListeners.end();
    236     for (; i1 != e1; ++i1)
    237         i1->second->clearWindowObj();
    238 }
    239 
    240 Window* Window::retrieveWindow(Frame* frame)
    241 {
    242     JSObject* o = retrieve(frame)->getObject();
    243 
    244     ASSERT(o || !frame->settings() || !frame->settings()->isJavaScriptEnabled());
    245     return static_cast<Window*>(o);
    246 }
    247 
    248 Window* Window::retrieveActive(ExecState* exec)
    249 {
    250     JSGlobalObject* globalObject = exec->dynamicGlobalObject();
    251     ASSERT(globalObject);
    252     return static_cast<Window*>(globalObject);
    253 }
    254 
    255 JSValue* Window::retrieve(Frame* frame)
    256 {
    257     ASSERT(frame);
    258     if (KJSProxy* proxy = frame->scriptProxy())
    259         return proxy->globalObject(); // the Global object is the "window"
    260 
    261     return jsUndefined(); // This can happen with JS disabled on the domain of that window
    262 }
    263 
    264 Location* Window::location() const
    265 {
    266     if (!d->loc)
    267         d->loc = new Location(impl()->frame());
    268     return d->loc;
    269 }
    270 
    271 // reference our special objects during garbage collection
    272 void Window::mark()
    273 {
    274     JSGlobalObject::mark();
    275     if (d->loc && !d->loc->marked())
    276         d->loc->mark();
    277 }
    278 
    279 static bool allowPopUp(Frame* frame)
    280 {
    281     if (!frame)
    282         return false;
    283     if (frame->scriptProxy()->processingUserGesture())
    284         return true;
    285     Settings* settings = frame->settings();
    286     return settings && settings->JavaScriptCanOpenWindowsAutomatically();
    287 }
    288 
    289 static HashMap<String, String> parseModalDialogFeatures(const String& featuresArg)
    290 {
    291     HashMap<String, String> map;
    292 
    293     Vector<String> features = featuresArg.split(';');
    294     Vector<String>::const_iterator end = features.end();
    295     for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) {
    296         String s = *it;
    297         int pos = s.find('=');
    298         int colonPos = s.find(':');
    299         if (pos >= 0 && colonPos >= 0)
    300             continue; // ignore any strings that have both = and :
    301         if (pos < 0)
    302             pos = colonPos;
    303         if (pos < 0) {
    304             // null string for value means key without value
    305             map.set(s.stripWhiteSpace().lower(), String());
    306         } else {
    307             String key = s.left(pos).stripWhiteSpace().lower();
    308             String val = s.substring(pos + 1).stripWhiteSpace().lower();
    309             int spacePos = val.find(' ');
    310             if (spacePos != -1)
    311                 val = val.left(spacePos);
    312             map.set(key, val);
    313         }
    314     }
    315 
    316     return map;
    317 }
    318 
    319 static Frame* createWindow(ExecState* exec, Frame* openerFrame, const String& url,
    320     const String& frameName, const WindowFeatures& windowFeatures, JSValue* dialogArgs)
    321 {
    322     Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
    323 
    324     ResourceRequest request;
    325     if (activeFrame)
    326         request.setHTTPReferrer(activeFrame->loader()->outgoingReferrer());
    327     FrameLoadRequest frameRequest(request, frameName);
    328 
    329     // FIXME: It's much better for client API if a new window starts with a URL, here where we
    330     // know what URL we are going to open. Unfortunately, this code passes the empty string
    331     // for the URL, but there's a reason for that. Before loading we have to set up the opener,
    332     // openedByDOM, and dialogArguments values. Also, to decide whether to use the URL we currently
    333     // do an allowsAccessFrom call using the window we create, which can't be done before creating it.
    334     // We'd have to resolve all those issues to pass the URL instead of "".
    335 
    336     bool created;
    337     Frame* newFrame = openerFrame->loader()->createWindow(frameRequest, windowFeatures, created);
    338     if (!newFrame)
    339         return 0;
    340 
    341     newFrame->loader()->setOpener(openerFrame);
    342     newFrame->loader()->setOpenedByDOM();
    343 
    344     Window* newWindow = Window::retrieveWindow(newFrame);
    345 
    346     if (dialogArgs)
    347         newWindow->putDirect("dialogArguments", dialogArgs);
    348 
    349     if (!url.startsWith("javascript:", false) || newWindow->allowsAccessFrom(exec)) {
    350         String completedURL = url.isEmpty() ? url : activeFrame->document()->completeURL(url);
    351         bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
    352 
    353         if (created) {
    354             newFrame->loader()->changeLocation(KURL(completedURL.deprecatedString()), activeFrame->loader()->outgoingReferrer(), false, userGesture);
    355             if (Document* oldDoc = openerFrame->document()) {
    356                 newFrame->document()->setDomainInternal(oldDoc->domain());
    357                 newFrame->document()->setBaseURL(oldDoc->baseURL());
    358             }
    359         } else if (!url.isEmpty())
    360             newFrame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture);
    361     }
    362 
    363     return newFrame;
    364 }
    365 
    366 static bool canShowModalDialog(const Frame* frame)
    367 {
    368     if (!frame)
    369         return false;
    370     return frame->page()->chrome()->canRunModal();
    371 }
    372 
    373 static bool canShowModalDialogNow(const Frame* frame)
    374 {
    375     if (!frame)
    376         return false;
    377     return frame->page()->chrome()->canRunModalNow();
    378 }
    379 
    380 static JSValue* showModalDialog(ExecState* exec, Frame* frame, const String& url, JSValue* dialogArgs, const String& featureArgs)
    381 {
    382     if (!canShowModalDialogNow(frame) || !allowPopUp(frame))
    383         return jsUndefined();
    384 
    385     const HashMap<String, String> features = parseModalDialogFeatures(featureArgs);
    386 
    387     const bool trusted = false;
    388 
    389     // The following features from Microsoft's documentation are not implemented:
    390     // - default font settings
    391     // - width, height, left, and top specified in units other than "px"
    392     // - edge (sunken or raised, default is raised)
    393     // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print
    394     // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)
    395     // - unadorned: trusted && boolFeature(features, "unadorned");
    396 
    397     if (!frame)
    398         return jsUndefined();
    399 
    400     FloatRect screenRect = screenAvailableRect(frame->view());
    401 
    402     WindowFeatures wargs;
    403     wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE
    404     wargs.widthSet = true;
    405     wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE
    406     wargs.heightSet = true;
    407 
    408     wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1);
    409     wargs.xSet = wargs.x > 0;
    410     wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1);
    411     wargs.ySet = wargs.y > 0;
    412 
    413     if (WindowFeatures::boolFeature(features, "center", true)) {
    414         if (!wargs.xSet) {
    415             wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2;
    416             wargs.xSet = true;
    417         }
    418         if (!wargs.ySet) {
    419             wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2;
    420             wargs.ySet = true;
    421         }
    422     }
    423 
    424     wargs.dialog = true;
    425     wargs.resizable = WindowFeatures::boolFeature(features, "resizable");
    426     wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true);
    427     wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted);
    428     wargs.menuBarVisible = false;
    429     wargs.toolBarVisible = false;
    430     wargs.locationBarVisible = false;
    431     wargs.fullscreen = false;
    432 
    433     Frame* dialogFrame = createWindow(exec, frame, url, "", wargs, dialogArgs);
    434     if (!dialogFrame)
    435         return jsUndefined();
    436 
    437     Window* dialogWindow = Window::retrieveWindow(dialogFrame);
    438 
    439     // Get the return value either just before clearing the dialog window's
    440     // properties (in Window::clear), or when on return from runModal.
    441     JSValue* returnValue = 0;
    442     dialogWindow->setReturnValueSlot(&returnValue);
    443     dialogFrame->page()->chrome()->runModal();
    444     dialogWindow->setReturnValueSlot(0);
    445 
    446     // If we don't have a return value, get it now.
    447     // Either Window::clear was not called yet, or there was no return value,
    448     // and in that case, there's no harm in trying again (no benefit either).
    449     if (!returnValue)
    450         returnValue = dialogWindow->getDirect("returnValue");
    451 
    452     return returnValue ? returnValue : jsUndefined();
    453 }
    454 
    455 JSValue *Window::getValueProperty(ExecState *exec, int token) const
    456 {
    457    ASSERT(impl()->frame());
    458 
    459    switch (token) {
    460    case Crypto:
    461       return jsUndefined(); // FIXME: implement this
    462    case DOMException:
    463       if (!allowsAccessFrom(exec))
    464         return jsUndefined();
    465       return getDOMExceptionConstructor(exec);
    466     case Event_:
    467       if (!allowsAccessFrom(exec))
    468         return jsUndefined();
    469       if (!d->m_evt)
    470         return jsUndefined();
    471       return toJS(exec, d->m_evt);
    472     case Location_:
    473       return location();
    474     case Navigator_:
    475     case ClientInformation: {
    476       if (!allowsAccessFrom(exec))
    477         return jsUndefined();
    478       // Store the navigator in the object so we get the same one each time.
    479       Navigator *n = new Navigator(exec, impl()->frame());
    480       // FIXME: this will make the "navigator" object accessible from windows that fail
    481       // the security check the first time, but not subsequent times, seems weird.
    482       const_cast<Window *>(this)->putDirect("navigator", n, DontDelete|ReadOnly);
    483       const_cast<Window *>(this)->putDirect("clientInformation", n, DontDelete|ReadOnly);
    484       return n;
    485     }
    486     case Image:
    487       if (!allowsAccessFrom(exec))
    488         return jsUndefined();
    489       // FIXME: this property (and the few below) probably shouldn't create a new object every
    490       // time
    491       return new ImageConstructorImp(exec, impl()->frame()->document());
    492     case Option:
    493       if (!allowsAccessFrom(exec))
    494         return jsUndefined();
    495       return new JSHTMLOptionElementConstructor(exec, impl()->frame()->document());
    496     case XMLHttpRequest:
    497       if (!allowsAccessFrom(exec))
    498         return jsUndefined();
    499       return new JSXMLHttpRequestConstructorImp(exec, impl()->frame()->document());
    500     case Audio:
    501 #if ENABLE(VIDEO)
    502       return new JSHTMLAudioElementConstructor(exec, impl()->frame()->document());
    503 #else
    504       return jsUndefined();
    505 #endif
    506 #if ENABLE(XSLT)
    507     case XSLTProcessor_:
    508       if (!allowsAccessFrom(exec))
    509         return jsUndefined();
    510       return new XSLTProcessorConstructorImp(exec);
    511 #else
    512     case XSLTProcessor_:
    513       return jsUndefined();
    514 #endif
    515    }
    516 
    517    if (!allowsAccessFrom(exec))
    518      return jsUndefined();
    519 
    520    switch (token) {
    521    case Onabort:
    522      return getListener(exec, abortEvent);
    523    case Onblur:
    524      return getListener(exec, blurEvent);
    525    case Onchange:
    526      return getListener(exec, changeEvent);
    527    case Onclick:
    528      return getListener(exec, clickEvent);
    529    case Ondblclick:
    530      return getListener(exec, dblclickEvent);
    531    case Onerror:
    532      return getListener(exec, errorEvent);
    533    case Onfocus:
    534      return getListener(exec, focusEvent);
    535    case Onkeydown:
    536      return getListener(exec, keydownEvent);
    537    case Onkeypress:
    538      return getListener(exec, keypressEvent);
    539    case Onkeyup:
    540      return getListener(exec, keyupEvent);
    541    case Onload:
    542      return getListener(exec, loadEvent);
    543    case Onmousedown:
    544      return getListener(exec, mousedownEvent);
    545    case Onmousemove:
    546      return getListener(exec, mousemoveEvent);
    547    case Onmouseout:
    548      return getListener(exec, mouseoutEvent);
    549    case Onmouseover:
    550      return getListener(exec, mouseoverEvent);
    551    case Onmouseup:
    552      return getListener(exec, mouseupEvent);
    553    case OnWindowMouseWheel:
    554      return getListener(exec, mousewheelEvent);
    555    case Onreset:
    556      return getListener(exec, resetEvent);
    557    case Onresize:
    558      return getListener(exec,resizeEvent);
    559    case Onscroll:
    560      return getListener(exec,scrollEvent);
    561    case Onsearch:
    562      return getListener(exec,searchEvent);
    563    case Onselect:
    564      return getListener(exec,selectEvent);
    565    case Onsubmit:
    566      return getListener(exec,submitEvent);
    567    case Onbeforeunload:
    568      return getListener(exec, beforeunloadEvent);
    569    case Onunload:
    570      return getListener(exec, unloadEvent);
    571    }
    572    ASSERT_NOT_REACHED();
    573    return jsUndefined();
    574 }
    575 
    576 JSValue* Window::childFrameGetter(ExecState*, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
    577 {
    578     return retrieve(static_cast<Window*>(slot.slotBase())->impl()->frame()->tree()->child(AtomicString(propertyName)));
    579 }
    580 
    581 JSValue* Window::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
    582 {
    583     return retrieve(static_cast<Window*>(slot.slotBase())->impl()->frame()->tree()->child(slot.index()));
    584 }
    585 
    586 JSValue *Window::namedItemGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
    587 {
    588   Window *thisObj = static_cast<Window *>(slot.slotBase());
    589   Document *doc = thisObj->impl()->frame()->document();
    590   ASSERT(thisObj->allowsAccessFrom(exec) && doc && doc->isHTMLDocument());
    591 
    592   String name = propertyName;
    593   RefPtr<WebCore::HTMLCollection> collection = doc->windowNamedItems(name);
    594   if (collection->length() == 1)
    595     return toJS(exec, collection->firstItem());
    596   return toJS(exec, collection.get());
    597 }
    598 
    599 bool Window::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
    600 {
    601   // Check for child frames by name before built-in properties to
    602   // match Mozilla. This does not match IE, but some sites end up
    603   // naming frames things that conflict with window properties that
    604   // are in Moz but not IE. Since we have some of these, we have to do
    605   // it the Moz way.
    606   if (impl()->frame()->tree()->child(propertyName)) {
    607     slot.setCustom(this, childFrameGetter);
    608     return true;
    609   }
    610 
    611   const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
    612   if (entry) {
    613     if (entry->attr & Function) {
    614       if (entry->value.functionValue == &WindowProtoFuncShowModalDialog::create) {
    615         if (!canShowModalDialog(impl()->frame()))
    616           return false;
    617       }
    618       if (allowsAccessFrom(exec))
    619         slot.setStaticEntry(this, entry, staticFunctionGetter);
    620       else
    621         slot.setUndefined(this);
    622     } else
    623       slot.setStaticEntry(this, entry, staticValueGetter<Window>);
    624     return true;
    625   }
    626 
    627   // FIXME: Search the whole frame hierachy somewhere around here.
    628   // We need to test the correct priority order.
    629 
    630   // allow window[1] or parent[1] etc. (#56983)
    631   bool ok;
    632   unsigned i = propertyName.toArrayIndex(&ok);
    633   if (ok && i < impl()->frame()->tree()->childCount()) {
    634     slot.setCustomIndex(this, i, indexGetter);
    635     return true;
    636   }
    637 
    638   // allow shortcuts like 'Image1' instead of document.images.Image1
    639   Document* doc = impl()->frame()->document();
    640   if (doc && doc->isHTMLDocument()) {
    641     if (!allowsAccessFrom(exec)) {
    642       slot.setUndefined(this);
    643       return true;
    644     }
    645 
    646     AtomicString atomicPropertyName = propertyName;
    647     if (static_cast<HTMLDocument*>(doc)->hasNamedItem(atomicPropertyName) || doc->getElementById(atomicPropertyName)) {
    648       slot.setCustom(this, namedItemGetter);
    649       return true;
    650     }
    651   }
    652 
    653   if (!allowsAccessFrom(exec)) {
    654     slot.setUndefined(this);
    655     return true;
    656   }
    657 
    658   return JSObject::getOwnPropertySlot(exec, propertyName, slot);
    659 }
    660 
    661 void Window::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
    662 {
    663   const HashEntry* entry = Lookup::findEntry(&WindowTable, propertyName);
    664   if (entry) {
    665      if (entry->attr & Function) {
    666        if (allowsAccessFrom(exec))
    667          JSObject::put(exec, propertyName, value, attr);
    668        return;
    669     }
    670     if (entry->attr & ReadOnly)
    671       return;
    672 
    673     switch (entry->value.intValue) {
    674     case Location_: {
    675       Frame* p = Window::retrieveActive(exec)->impl()->frame();
    676       if (p) {
    677         if (!p->loader()->shouldAllowNavigation(impl()->frame()))
    678           return;
    679         String dstUrl = p->loader()->completeURL(value->toString(exec)).string();
    680         if (!dstUrl.startsWith("javascript:", false) || allowsAccessFrom(exec)) {
    681           bool userGesture = p->scriptProxy()->processingUserGesture();
    682           // We want a new history item if this JS was called via a user gesture
    683           impl()->frame()->loader()->scheduleLocationChange(dstUrl, p->loader()->outgoingReferrer(), false, userGesture);
    684         }
    685       }
    686       return;
    687     }
    688     case Onabort:
    689       if (allowsAccessFrom(exec))
    690         setListener(exec, abortEvent,value);
    691       return;
    692     case Onblur:
    693       if (allowsAccessFrom(exec))
    694         setListener(exec, blurEvent,value);
    695       return;
    696     case Onchange:
    697       if (allowsAccessFrom(exec))
    698         setListener(exec, changeEvent,value);
    699       return;
    700     case Onclick:
    701       if (allowsAccessFrom(exec))
    702         setListener(exec,clickEvent,value);
    703       return;
    704     case Ondblclick:
    705       if (allowsAccessFrom(exec))
    706         setListener(exec, dblclickEvent,value);
    707       return;
    708     case Onerror:
    709       if (allowsAccessFrom(exec))
    710         setListener(exec, errorEvent, value);
    711       return;
    712     case Onfocus:
    713       if (allowsAccessFrom(exec))
    714         setListener(exec,focusEvent,value);
    715       return;
    716     case Onkeydown:
    717       if (allowsAccessFrom(exec))
    718         setListener(exec,keydownEvent,value);
    719       return;
    720     case Onkeypress:
    721       if (allowsAccessFrom(exec))
    722         setListener(exec,keypressEvent,value);
    723       return;
    724     case Onkeyup:
    725       if (allowsAccessFrom(exec))
    726         setListener(exec,keyupEvent,value);
    727       return;
    728     case Onload:
    729       if (allowsAccessFrom(exec))
    730         setListener(exec,loadEvent,value);
    731       return;
    732     case Onmousedown:
    733       if (allowsAccessFrom(exec))
    734         setListener(exec,mousedownEvent,value);
    735       return;
    736     case Onmousemove:
    737       if (allowsAccessFrom(exec))
    738         setListener(exec,mousemoveEvent,value);
    739       return;
    740     case Onmouseout:
    741       if (allowsAccessFrom(exec))
    742         setListener(exec,mouseoutEvent,value);
    743       return;
    744     case Onmouseover:
    745       if (allowsAccessFrom(exec))
    746         setListener(exec,mouseoverEvent,value);
    747       return;
    748     case Onmouseup:
    749       if (allowsAccessFrom(exec))
    750         setListener(exec,mouseupEvent,value);
    751       return;
    752     case OnWindowMouseWheel:
    753       if (allowsAccessFrom(exec))
    754         setListener(exec, mousewheelEvent,value);
    755       return;
    756     case Onreset:
    757       if (allowsAccessFrom(exec))
    758         setListener(exec,resetEvent,value);
    759       return;
    760     case Onresize:
    761       if (allowsAccessFrom(exec))
    762         setListener(exec,resizeEvent,value);
    763       return;
    764     case Onscroll:
    765       if (allowsAccessFrom(exec))
    766         setListener(exec,scrollEvent,value);
    767       return;
    768     case Onsearch:
    769         if (allowsAccessFrom(exec))
    770             setListener(exec,searchEvent,value);
    771         return;
    772     case Onselect:
    773       if (allowsAccessFrom(exec))
    774         setListener(exec,selectEvent,value);
    775       return;
    776     case Onsubmit:
    777       if (allowsAccessFrom(exec))
    778         setListener(exec,submitEvent,value);
    779       return;
    780     case Onbeforeunload:
    781       if (allowsAccessFrom(exec))
    782         setListener(exec, beforeunloadEvent, value);
    783       return;
    784     case Onunload:
    785       if (allowsAccessFrom(exec))
    786         setListener(exec, unloadEvent, value);
    787       return;
    788     default:
    789       break;
    790     }
    791   }
    792   if (allowsAccessFrom(exec))
    793     JSObject::put(exec, propertyName, value, attr);
    794 }
    795 
    796 bool Window::allowsAccessFrom(const JSGlobalObject* other) const
    797 {
    798     const Frame* originFrame = static_cast<const Window*>(other)->impl()->frame();
    799     if (!originFrame)
    800         return false;
    801 
    802     const Frame* targetFrame = impl()->frame();
    803     if (!targetFrame)
    804         return false;
    805 
    806     if (originFrame == targetFrame)
    807         return true;
    808 
    809     WebCore::Document* targetDocument = targetFrame->document();
    810 
    811     // JS may be attempting to access the "window" object, which should be valid,
    812     // even if the document hasn't been constructed yet.  If the document doesn't
    813     // exist yet allow JS to access the window object.
    814     if (!targetDocument)
    815         return true;
    816 
    817     WebCore::Document* originDocument = originFrame->document();
    818 
    819     const SecurityOrigin& originSecurityOrigin = originDocument->securityOrigin();
    820     const SecurityOrigin& targetSecurityOrigin = targetDocument->securityOrigin();
    821 
    822     if (originSecurityOrigin.canAccess(targetSecurityOrigin))
    823         return true;
    824 
    825     if (!targetFrame->settings()->privateBrowsingEnabled()) {
    826         // FIXME: this error message should contain more specifics of why the same origin check has failed.
    827         String message = String::format("Unsafe JavaScript attempt to access frame with URL %s from frame with URL %s. Domains, protocols and ports must match.\n",
    828                                         targetDocument->url().utf8().data(), originDocument->url().utf8().data());
    829 
    830         if (Interpreter::shouldPrintExceptions())
    831             printf("%s", message.utf8().data());
    832 
    833         if (Page* page = targetFrame->page())
    834             page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL.
    835     }
    836 
    837     return false;
    838 }
    839 
    840 ExecState* Window::globalExec()
    841 {
    842     // We need to make sure that any script execution happening in this
    843     // frame does not destroy it
    844     ASSERT(impl()->frame());
    845     impl()->frame()->keepAlive();
    846     return JSGlobalObject::globalExec();
    847 }
    848 
    849 bool Window::shouldInterruptScript() const
    850 {
    851     ASSERT(impl()->frame());
    852     Page* page = impl()->frame()->page();
    853 
    854     // See <rdar://problem/5479443>. We don't think that page can ever be NULL
    855     // in this case, but if it is, we've gotten into a state where we may have
    856     // hung the UI, with no way to ask the client whether to cancel execution.
    857     // For now, our solution is just to cancel execution no matter what,
    858     // ensuring that we never hang. We might want to consider other solutions
    859     // if we discover problems with this one.
    860     ASSERT(page);
    861     if (!page)
    862         return true;
    863 
    864     return page->chrome()->shouldInterruptJavaScript();
    865 }
    866 
    867 void Window::setListener(ExecState* exec, const AtomicString& eventType, JSValue* func)
    868 {
    869     ASSERT(impl()->frame());
    870     Document* doc = impl()->frame()->document();
    871     if (!doc)
    872         return;
    873 
    874     doc->setHTMLWindowEventListener(eventType, findOrCreateJSEventListener(func, true));
    875 }
    876 
    877 JSValue* Window::getListener(ExecState* exec, const AtomicString& eventType) const
    878 {
    879     ASSERT(impl()->frame());
    880     Document* doc = impl()->frame()->document();
    881     if (!doc)
    882         return jsUndefined();
    883 
    884     WebCore::EventListener* listener = doc->getHTMLWindowEventListener(eventType);
    885     if (listener && static_cast<JSEventListener*>(listener)->listenerObj())
    886         return static_cast<JSEventListener*>(listener)->listenerObj();
    887     return jsNull();
    888 }
    889 
    890 JSEventListener* Window::findJSEventListener(JSValue* val, bool html)
    891 {
    892     if (!val->isObject())
    893         return 0;
    894     JSObject* object = static_cast<JSObject*>(val);
    895     ListenersMap& listeners = html ? d->jsHTMLEventListeners : d->jsEventListeners;
    896     return listeners.get(object);
    897 }
    898 
    899 JSEventListener* Window::findOrCreateJSEventListener(JSValue* val, bool html)
    900 {
    901     JSEventListener* listener = findJSEventListener(val, html);
    902     if (listener)
    903         return listener;
    904 
    905     if (!val->isObject())
    906         return 0;
    907     JSObject* object = static_cast<JSObject*>(val);
    908 
    909     // Note that the JSEventListener constructor adds it to our jsEventListeners list
    910     return new JSEventListener(object, this, html);
    911 }
    912 
    913 JSUnprotectedEventListener* Window::findJSUnprotectedEventListener(JSValue* val, bool html)
    914 {
    915     if (!val->isObject())
    916         return 0;
    917     JSObject* object = static_cast<JSObject*>(val);
    918     UnprotectedListenersMap& listeners = html ? d->jsUnprotectedHTMLEventListeners : d->jsUnprotectedEventListeners;
    919     return listeners.get(object);
    920 }
    921 
    922 JSUnprotectedEventListener* Window::findOrCreateJSUnprotectedEventListener(JSValue* val, bool html)
    923 {
    924     JSUnprotectedEventListener* listener = findJSUnprotectedEventListener(val, html);
    925     if (listener)
    926         return listener;
    927     if (!val->isObject())
    928         return 0;
    929     JSObject* object = static_cast<JSObject*>(val);
    930 
    931     // The JSUnprotectedEventListener constructor adds it to our jsUnprotectedEventListeners map.
    932     return new JSUnprotectedEventListener(object, this, html);
    933 }
    934 
    935 void Window::clearHelperObjectProperties()
    936 {
    937     d->loc = 0;
    938     d->m_evt = 0;
    939 }
    940 
    941 void Window::clear()
    942 {
    943   JSLock lock;
    944 
    945   if (d->m_returnValueSlot && !*d->m_returnValueSlot)
    946     *d->m_returnValueSlot = getDirect("returnValue");
    947 
    948   clearAllTimeouts();
    949   clearProperties();
    950   clearHelperObjectProperties();
    951 
    952   // Now recreate a working global object for the next URL that will use us; but only if we haven't been
    953   // disconnected yet
    954   if (Frame* frame = impl()->frame())
    955     frame->scriptProxy()->globalObject()->reset(JSDOMWindowPrototype::self());
    956 
    957   // there's likely to be lots of garbage now
    958   gcController().garbageCollectSoon();
    959 }
    960 
    961 void Window::setCurrentEvent(Event* evt)
    962 {
    963     d->m_evt = evt;
    964 }
    965 
    966 Event* Window::currentEvent()
    967 {
    968     return d->m_evt;
    969 }
    970 
    971 JSValue* WindowProtoFuncAToB::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    972 {
    973     if (!thisObj->inherits(&Window::info))
    974         return throwError(exec, TypeError);
    975 
    976     if (args.size() < 1)
    977         return throwError(exec, SyntaxError, "Not enough arguments");
    978 
    979     JSValue* v = args[0];
    980     if (v->isNull())
    981         return jsString();
    982 
    983     UString s = v->toString(exec);
    984     if (!s.is8Bit()) {
    985         setDOMException(exec, INVALID_CHARACTER_ERR);
    986         return jsUndefined();
    987     }
    988 
    989     Vector<char> in(s.size());
    990     for (int i = 0; i < s.size(); ++i)
    991         in[i] = static_cast<char>(s.data()[i].unicode());
    992     Vector<char> out;
    993 
    994     if (!base64Decode(in, out))
    995         return throwError(exec, GeneralError, "Cannot decode base64");
    996 
    997     return jsString(String(out.data(), out.size()));
    998 }
    999 
    1000 JSValue* WindowProtoFuncBToA::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1001 {
    1002     if (!thisObj->inherits(&Window::info))
    1003         return throwError(exec, TypeError);
    1004 
    1005     if (args.size() < 1)
    1006         return throwError(exec, SyntaxError, "Not enough arguments");
    1007 
    1008     JSValue* v = args[0];
    1009     if (v->isNull())
    1010         return jsString();
    1011 
    1012     UString s = v->toString(exec);
    1013     if (!s.is8Bit()) {
    1014         setDOMException(exec, INVALID_CHARACTER_ERR);
    1015         return jsUndefined();
    1016     }
    1017 
    1018     Vector<char> in(s.size());
    1019     for (int i = 0; i < s.size(); ++i)
    1020         in[i] = static_cast<char>(s.data()[i].unicode());
    1021     Vector<char> out;
    1022 
    1023     base64Encode(in, out);
    1024 
    1025     return jsString(String(out.data(), out.size()));
    1026 }
    1027 
    1028 JSValue* WindowProtoFuncOpen::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1029 {
    1030     if (!thisObj->inherits(&Window::info))
    1031         return throwError(exec, TypeError);
    1032     Window* window = static_cast<Window*>(thisObj);
    1033     Frame* frame = window->impl()->frame();
    1034     if (!frame)
    1035         return jsUndefined();
    1036     Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
    1037     if (!activeFrame)
    1038         return  jsUndefined();
    1039 
    1040     Page* page = frame->page();
    1041 
    1042     String urlString = valueToStringWithUndefinedOrNullCheck(exec, args[0]);
    1043     AtomicString frameName = args[1]->isUndefinedOrNull() ? "_blank" : AtomicString(args[1]->toString(exec));
    1044 
    1045     // Because FrameTree::find() returns true for empty strings, we must check for empty framenames.
    1046     // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
    1047     if (!allowPopUp(frame) && (frameName.isEmpty() || !frame->tree()->find(frameName)))
    1048         return jsUndefined();
    1049 
    1050     // Get the target frame for the special cases of _top and _parent.  In those
    1051     // cases, we can schedule a location change right now and return early.
    1052     bool topOrParent = false;
    1053     if (frameName == "_top") {
    1054         frame = frame->tree()->top();
    1055         topOrParent = true;
    1056     } else if (frameName == "_parent") {
    1057         if (Frame* parent = frame->tree()->parent())
    1058             frame = parent;
    1059         if (!activeFrame->loader()->shouldAllowNavigation(frame))
    1060             return jsUndefined();
    1061         topOrParent = true;
    1062     }
    1063     if (topOrParent) {
    1064         String completedURL;
    1065         if (!urlString.isEmpty())
    1066             completedURL = activeFrame->document()->completeURL(urlString);
    1067 
    1068         const Window* targetedWindow = Window::retrieveWindow(frame);
    1069         if (!completedURL.isEmpty() && (!completedURL.startsWith("javascript:", false) || (targetedWindow && targetedWindow->allowsAccessFrom(exec)))) {
    1070             bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
    1071             frame->loader()->scheduleLocationChange(completedURL, activeFrame->loader()->outgoingReferrer(), false, userGesture);
    1072         }
    1073         return Window::retrieve(frame);
    1074     }
    1075 
    1076     // In the case of a named frame or a new window, we'll use the createWindow() helper
    1077     WindowFeatures windowFeatures(valueToStringWithUndefinedOrNullCheck(exec, args[2]));
    1078     FloatRect windowRect(windowFeatures.x, windowFeatures.y, windowFeatures.width, windowFeatures.height);
    1079     WebCore::DOMWindow::adjustWindowRect(screenAvailableRect(page->mainFrame()->view()), windowRect, windowRect);
    1080 
    1081     windowFeatures.x = windowRect.x();
    1082     windowFeatures.y = windowRect.y();
    1083     windowFeatures.height = windowRect.height();
    1084     windowFeatures.width = windowRect.width();
    1085 
    1086     frame = createWindow(exec, frame, urlString, frameName, windowFeatures, 0);
    1087 
    1088     if (!frame)
    1089         return jsUndefined();
    1090 
    1091     return Window::retrieve(frame); // global object
    1092 }
    1093 
    1094 JSValue* WindowProtoFuncSetTimeout::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1095 {
    1096     if (!thisObj->inherits(&Window::info))
    1097         return throwError(exec, TypeError);
    1098     Window* window = static_cast<Window*>(thisObj);
    1099 
    1100     JSValue* v = args[0];
    1101     if (v->isString())
    1102         return jsNumber(window->installTimeout(v->toString(exec), args[1]->toInt32(exec), true /*single shot*/));
    1103     if (v->isObject() && static_cast<JSObject*>(v)->implementsCall()) {
    1104         List argsTail;
    1105         args.getSlice(2, argsTail);
    1106         return jsNumber(window->installTimeout(v, argsTail, args[1]->toInt32(exec), true /*single shot*/));
    1107     }
    1108 
    1109     return jsUndefined();
    1110 }
    1111 
    1112 JSValue* WindowProtoFuncClearTimeout::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1113 {
    1114     // Also the implementation for window.clearInterval()
    1115 
    1116     if (!thisObj->inherits(&Window::info))
    1117         return throwError(exec, TypeError);
    1118     Window* window = static_cast<Window*>(thisObj);
    1119 
    1120     window->clearTimeout(args[0]->toInt32(exec));
    1121     return jsUndefined();
    1122 }
    1123 
    1124 JSValue* WindowProtoFuncSetInterval::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1125 {
    1126     if (!thisObj->inherits(&Window::info))
    1127         return throwError(exec, TypeError);
    1128     Window* window = static_cast<Window*>(thisObj);
    1129 
    1130     if (args.size() >= 2) {
    1131         JSValue* v = args[0];
    1132         int delay = args[1]->toInt32(exec);
    1133         if (v->isString())
    1134             return jsNumber(window->installTimeout(v->toString(exec), delay, false));
    1135         if (v->isObject() && static_cast<JSObject*>(v)->implementsCall()) {
    1136             List argsTail;
    1137             args.getSlice(2, argsTail);
    1138             return jsNumber(window->installTimeout(v, argsTail, delay, false));
    1139         }
    1140     }
    1141 
    1142     return jsUndefined();
    1143 
    1144 }
    1145 
    1146 JSValue* WindowProtoFuncAddEventListener::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1147 {
    1148     if (!thisObj->inherits(&Window::info))
    1149         return throwError(exec, TypeError);
    1150     Window* window = static_cast<Window*>(thisObj);
    1151     Frame* frame = window->impl()->frame();
    1152     if (!frame)
    1153         return jsUndefined();
    1154 
    1155     if (JSEventListener* listener = window->findOrCreateJSEventListener(args[1])) {
    1156         if (Document* doc = frame->document())
    1157             doc->addWindowEventListener(AtomicString(args[0]->toString(exec)), listener, args[2]->toBoolean(exec));
    1158     }
    1159 
    1160     return jsUndefined();
    1161 }
    1162 
    1163 JSValue* WindowProtoFuncRemoveEventListener::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1164 {
    1165     if (!thisObj->inherits(&Window::info))
    1166         return throwError(exec, TypeError);
    1167     Window* window = static_cast<Window*>(thisObj);
    1168     Frame* frame = window->impl()->frame();
    1169     if (!frame)
    1170         return jsUndefined();
    1171 
    1172     if (JSEventListener* listener = window->findJSEventListener(args[1])) {
    1173         if (Document* doc = frame->document())
    1174             doc->removeWindowEventListener(AtomicString(args[0]->toString(exec)), listener, args[2]->toBoolean(exec));
    1175     }
    1176 
    1177     return jsUndefined();
    1178 }
    1179 
    1180 JSValue* WindowProtoFuncShowModalDialog::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1181 {
    1182     if (!thisObj->inherits(&Window::info))
    1183         return throwError(exec, TypeError);
    1184     Window* window = static_cast<Window*>(thisObj);
    1185     Frame* frame = window->impl()->frame();
    1186     if (!frame)
    1187         return jsUndefined();
    1188 
    1189     return showModalDialog(exec, frame, valueToStringWithUndefinedOrNullCheck(exec, args[0]), args[1], valueToStringWithUndefinedOrNullCheck(exec, args[2]));
    1190 }
    1191 
    1192 JSValue* WindowProtoFuncNotImplemented::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1193 {
    1194     if (!thisObj->inherits(&Window::info))
    1195         return throwError(exec, TypeError);
    1196 
    1197     return jsUndefined();
    1198 }
    1199 
    1200 void Window::setReturnValueSlot(JSValue** slot)
    1201 {
    1202     d->m_returnValueSlot = slot;
    1203 }
    1204 
    1205 ////////////////////// ScheduledAction ////////////////////////
    120648
    120749void ScheduledAction::execute(Window* window)
     
    122769            List args;
    122870            size_t size = m_args.size();
    1229             for (size_t i = 0; i < size; ++i) {
     71            for (size_t i = 0; i < size; ++i)
    123072                args.append(m_args[i]);
    1231             }
    123273
    123374            globalObject->startTimeoutCheck();
     
    1259100}
    1260101
    1261 ////////////////////// timeouts ////////////////////////
    1262 
    1263 void Window::clearAllTimeouts()
    1264 {
    1265     deleteAllValues(d->m_timeouts);
    1266     d->m_timeouts.clear();
    1267 }
    1268 
    1269 int Window::installTimeout(ScheduledAction* a, int t, bool singleShot)
    1270 {
    1271     int timeoutId = ++lastUsedTimeoutId;
    1272 
    1273     // avoid wraparound going negative on us
    1274     if (timeoutId <= 0)
    1275         timeoutId = 1;
    1276 
    1277     int nestLevel = timerNestingLevel + 1;
    1278     DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, nestLevel, this, a);
    1279     ASSERT(!d->m_timeouts.get(timeoutId));
    1280     d->m_timeouts.set(timeoutId, timer);
    1281     // Use a minimum interval of 10 ms to match other browsers, but only once we've
    1282     // nested enough to notice that we're repeating.
    1283     // Faster timers might be "better", but they're incompatible.
    1284     double interval = max(0.001, t * 0.001);
    1285     if (interval < cMinimumTimerInterval && nestLevel >= cMaxTimerNestingLevel)
    1286         interval = cMinimumTimerInterval;
    1287     if (singleShot)
    1288         timer->startOneShot(interval);
    1289     else
    1290         timer->startRepeating(interval);
    1291     return timeoutId;
    1292 }
    1293 
    1294 ScheduledAction::ScheduledAction(JSValue* func, const List& args)
    1295     : m_func(func)
    1296 {
    1297     List::const_iterator end = args.end();
    1298     for (List::const_iterator it = args.begin(); it != end; ++it)
    1299         m_args.append(*it);
    1300 }
    1301 
    1302 int Window::installTimeout(const UString& handler, int t, bool singleShot)
    1303 {
    1304     return installTimeout(new ScheduledAction(handler), t, singleShot);
    1305 }
    1306 
    1307 int Window::installTimeout(JSValue* func, const List& args, int t, bool singleShot)
    1308 {
    1309     return installTimeout(new ScheduledAction(func, args), t, singleShot);
    1310 }
    1311 
    1312 WebCore::PausedTimeouts* Window::pauseTimeouts()
    1313 {
    1314     size_t count = d->m_timeouts.size();
    1315     if (count == 0)
    1316         return 0;
    1317 
    1318     PausedTimeout* t = new PausedTimeout [count];
    1319     PausedTimeouts* result = new PausedTimeouts(t, count);
    1320 
    1321     WindowPrivate::TimeoutsMap::iterator it = d->m_timeouts.begin();
    1322     for (size_t i = 0; i != count; ++i, ++it) {
    1323         int timeoutId = it->first;
    1324         DOMWindowTimer* timer = it->second;
    1325         t[i].timeoutId = timeoutId;
    1326         t[i].nestingLevel = timer->nestingLevel();
    1327         t[i].nextFireInterval = timer->nextFireInterval();
    1328         t[i].repeatInterval = timer->repeatInterval();
    1329         t[i].action = timer->takeAction();
    1330     }
    1331     ASSERT(it == d->m_timeouts.end());
    1332 
    1333     deleteAllValues(d->m_timeouts);
    1334     d->m_timeouts.clear();
    1335 
    1336     return result;
    1337 }
    1338 
    1339 void Window::resumeTimeouts(PausedTimeouts* timeouts)
    1340 {
    1341     if (!timeouts)
    1342         return;
    1343     size_t count = timeouts->numTimeouts();
    1344     PausedTimeout* array = timeouts->takeTimeouts();
    1345     for (size_t i = 0; i != count; ++i) {
    1346         int timeoutId = array[i].timeoutId;
    1347         DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, array[i].nestingLevel, this, array[i].action);
    1348         d->m_timeouts.set(timeoutId, timer);
    1349         timer->start(array[i].nextFireInterval, array[i].repeatInterval);
    1350     }
    1351     delete [] array;
    1352 }
    1353 
    1354 void Window::clearTimeout(int timeoutId, bool delAction)
    1355 {
    1356     // timeout IDs have to be positive, and 0 and -1 are unsafe to
    1357     // even look up since they are the empty and deleted value
    1358     // respectively
    1359     if (timeoutId <= 0)
    1360         return;
    1361 
    1362     delete d->m_timeouts.take(timeoutId);
    1363 }
    1364 
    1365 void Window::timerFired(DOMWindowTimer* timer)
    1366 {
    1367     // Simple case for non-one-shot timers.
    1368     if (timer->isActive()) {
    1369         int timeoutId = timer->timeoutId();
    1370 
    1371         timer->action()->execute(this);
    1372         if (d->m_timeouts.contains(timeoutId) && timer->repeatInterval() && timer->repeatInterval() < cMinimumTimerInterval) {
    1373             timer->setNestingLevel(timer->nestingLevel() + 1);
    1374             if (timer->nestingLevel() >= cMaxTimerNestingLevel)
    1375                 timer->augmentRepeatInterval(cMinimumTimerInterval - timer->repeatInterval());
    1376         }
    1377         return;
    1378     }
    1379 
    1380     // Delete timer before executing the action for one-shot timers.
    1381     ScheduledAction* action = timer->takeAction();
    1382     d->m_timeouts.remove(timer->timeoutId());
    1383     delete timer;
    1384     action->execute(this);
    1385 
    1386     JSLock lock;
    1387     delete action;
    1388 }
    1389 
    1390 void Window::disconnectFrame()
    1391 {
    1392     clearAllTimeouts();
    1393     if (d->loc)
    1394         d->loc->m_frame = 0;
    1395 }
    1396 
    1397 Window::ListenersMap& Window::jsEventListeners()
    1398 {
    1399     return d->jsEventListeners;
    1400 }
    1401 
    1402 Window::ListenersMap& Window::jsHTMLEventListeners()
    1403 {
    1404     return d->jsHTMLEventListeners;
    1405 }
    1406 
    1407 Window::UnprotectedListenersMap& Window::jsUnprotectedEventListeners()
    1408 {
    1409     return d->jsUnprotectedEventListeners;
    1410 }
    1411 
    1412 Window::UnprotectedListenersMap& Window::jsUnprotectedHTMLEventListeners()
    1413 {
    1414     return d->jsUnprotectedHTMLEventListeners;
    1415 }
    1416 
    1417 ////////////////////// Location Object ////////////////////////
    1418 
    1419 const ClassInfo Location::info = { "Location", 0, &LocationTable };
    1420 /*
    1421 @begin LocationTable 12
    1422   assign        &LocationProtoFuncAssign::create        DontDelete|Function 1
    1423   hash          Location::Hash                          DontDelete
    1424   host          Location::Host                          DontDelete
    1425   hostname      Location::Hostname                      DontDelete
    1426   href          Location::Href                          DontDelete
    1427   pathname      Location::Pathname                      DontDelete
    1428   port          Location::Port                          DontDelete
    1429   protocol      Location::Protocol                      DontDelete
    1430   search        Location::Search                        DontDelete
    1431   toString      &LocationProtoFuncToString::create      DontEnum|DontDelete|Function 0
    1432   replace       &LocationProtoFuncReplace::create       DontDelete|Function 1
    1433   reload        &LocationProtoFuncReload::create        DontDelete|Function 0
    1434 @end
    1435 */
    1436 
    1437 Location::Location(Frame* frame)
    1438     : m_frame(frame)
    1439 {
    1440 }
    1441 
    1442 JSValue *Location::getValueProperty(ExecState* exec, int token) const
    1443 {
    1444   KURL url = m_frame->loader()->url();
    1445   switch (token) {
    1446   case Hash:
    1447     return jsString(url.ref().isNull() ? "" : "#" + url.ref());
    1448   case Host: {
    1449     // Note: this is the IE spec. The NS spec swaps the two, it says
    1450     // "The hostname property is the concatenation of the host and port properties, separated by a colon."
    1451     // Bleh.
    1452     UString str = url.host();
    1453     if (url.port())
    1454         str += ":" + String::number((int)url.port());
    1455     return jsString(str);
    1456   }
    1457   case Hostname:
    1458     return jsString(url.host());
    1459   case Href:
    1460     if (!url.hasPath())
    1461       return jsString(url.prettyURL() + "/");
    1462     return jsString(url.prettyURL());
    1463   case Pathname:
    1464     return jsString(url.path().isEmpty() ? "/" : url.path());
    1465   case Port:
    1466     return jsString(url.port() ? String::number((int)url.port()) : "");
    1467   case Protocol:
    1468     return jsString(url.protocol() + ":");
    1469   case Search:
    1470     return jsString(url.query());
    1471   default:
    1472     ASSERT_NOT_REACHED();
    1473     return jsUndefined();
    1474   }
    1475 }
    1476 
    1477 bool Location::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
    1478 {
    1479   if (!m_frame)
    1480     return false;
    1481 
    1482   const Window* window = Window::retrieveWindow(m_frame);
    1483 
    1484   const HashEntry* entry = Lookup::findEntry(&LocationTable, propertyName);
    1485   if (!entry || !(entry->attr & KJS::Function) || (entry->value.functionValue != &LocationProtoFuncReplace::create
    1486                                                    && entry->value.functionValue != &LocationProtoFuncReload::create
    1487                                                    && entry->value.functionValue != &LocationProtoFuncAssign::create))  {
    1488     if (!window || !window->allowsAccessFrom(exec)) {
    1489       slot.setUndefined(this);
    1490       return true;
    1491     }
    1492   }
    1493 
    1494   return getStaticPropertySlot<Location, JSObject>(exec, &LocationTable, this, propertyName, slot);
    1495 }
    1496 
    1497 void Location::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
    1498 {
    1499   if (!m_frame)
    1500     return;
    1501 
    1502   DeprecatedString str = value->toString(exec);
    1503   KURL url = m_frame->loader()->url();
    1504   const Window* window = Window::retrieveWindow(m_frame);
    1505   bool sameDomainAccess = window && window->allowsAccessFrom(exec);
    1506 
    1507   const HashEntry* entry = Lookup::findEntry(&LocationTable, propertyName);
    1508 
    1509   if (entry) {
    1510       // cross-domain access to the location is allowed when assigning the whole location,
    1511       // but not when assigning the individual pieces, since that might inadvertently
    1512       // disclose other parts of the original location.
    1513       if (entry->value.intValue != Href && !sameDomainAccess)
    1514           return;
    1515 
    1516       switch (entry->value.intValue) {
    1517       case Href: {
    1518           Frame* frame = Window::retrieveActive(exec)->impl()->frame();
    1519           if (!frame)
    1520               return;
    1521           if (!frame->loader()->shouldAllowNavigation(m_frame))
    1522               return;
    1523           url = frame->loader()->completeURL(str);
    1524           break;
    1525       }
    1526       case Hash: {
    1527           if (str.startsWith("#"))
    1528               str = str.mid(1);
    1529           if (url.ref() == str)
    1530               return;
    1531           url.setRef(str);
    1532           break;
    1533       }
    1534       case Host: {
    1535           url.setHostAndPort(str);
    1536           break;
    1537       }
    1538       case Hostname:
    1539           url.setHost(str);
    1540           break;
    1541       case Pathname:
    1542           url.setPath(str);
    1543           break;
    1544       case Port:
    1545           url.setPort(str.toUInt());
    1546           break;
    1547       case Protocol:
    1548           url.setProtocol(str);
    1549           break;
    1550       case Search:
    1551           url.setQuery(str);
    1552           break;
    1553       default:
    1554           // Disallow changing other properties in LocationTable. e.g., "window.location.toString = ...".
    1555           // <http://bugs.webkit.org/show_bug.cgi?id=12720>
    1556           return;
    1557       }
    1558   } else {
    1559       if (sameDomainAccess)
    1560           JSObject::put(exec, propertyName, value, attr);
    1561       return;
    1562   }
    1563 
    1564   Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
    1565   if (!url.deprecatedString().startsWith("javascript:", false) || sameDomainAccess) {
    1566     bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
    1567     m_frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), false, userGesture);
    1568   }
    1569 }
    1570 
    1571 JSValue* LocationProtoFuncReplace::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1572 {
    1573     if (!thisObj->inherits(&Location::info))
    1574         return throwError(exec, TypeError);
    1575     Location* location = static_cast<Location*>(thisObj);
    1576     Frame* frame = location->frame();
    1577     if (!frame)
    1578         return jsUndefined();
    1579 
    1580     Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
    1581     if (activeFrame) {
    1582         if (!activeFrame->loader()->shouldAllowNavigation(frame))
    1583             return jsUndefined();
    1584         DeprecatedString str = args[0]->toString(exec);
    1585         const Window* window = Window::retrieveWindow(frame);
    1586         if (!str.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
    1587             bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
    1588             frame->loader()->scheduleLocationChange(activeFrame->loader()->completeURL(str).string(), activeFrame->loader()->outgoingReferrer(), true, userGesture);
    1589         }
    1590     }
    1591 
    1592     return jsUndefined();
    1593 }
    1594 
    1595 JSValue* LocationProtoFuncReload::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1596 {
    1597     if (!thisObj->inherits(&Location::info))
    1598         return throwError(exec, TypeError);
    1599     Location* location = static_cast<Location*>(thisObj);
    1600     Frame* frame = location->frame();
    1601     if (!frame)
    1602         return jsUndefined();
    1603 
    1604     Window* window = Window::retrieveWindow(frame);
    1605     if (!window->allowsAccessFrom(exec))
    1606         return jsUndefined();
    1607 
    1608     if (!frame->loader()->url().deprecatedString().startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
    1609         bool userGesture = Window::retrieveActive(exec)->impl()->frame()->scriptProxy()->processingUserGesture();
    1610         frame->loader()->scheduleRefresh(userGesture);
    1611     }
    1612     return jsUndefined();
    1613 }
    1614 
    1615 JSValue* LocationProtoFuncAssign::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1616 {
    1617     if (!thisObj->inherits(&Location::info))
    1618         return throwError(exec, TypeError);
    1619     Location* location = static_cast<Location*>(thisObj);
    1620     Frame* frame = location->frame();
    1621     if (!frame)
    1622         return jsUndefined();
    1623 
    1624     Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
    1625     if (activeFrame) {
    1626         if (!activeFrame->loader()->shouldAllowNavigation(frame))
    1627             return jsUndefined();
    1628         const Window* window = Window::retrieveWindow(frame);
    1629         String dstUrl = activeFrame->loader()->completeURL(args[0]->toString(exec)).string();
    1630         if (!dstUrl.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
    1631             bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
    1632             // We want a new history item if this JS was called via a user gesture
    1633             frame->loader()->scheduleLocationChange(dstUrl, activeFrame->loader()->outgoingReferrer(), false, userGesture);
    1634         }
    1635     }
    1636 
    1637     return jsUndefined();
    1638 }
    1639 
    1640 JSValue* LocationProtoFuncToString::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
    1641 {
    1642     if (!thisObj->inherits(&Location::info))
    1643         return throwError(exec, TypeError);
    1644     Location* location = static_cast<Location*>(thisObj);
    1645     Frame* frame = location->frame();
    1646     if (!frame)
    1647         return jsUndefined();
    1648 
    1649     const KURL& url = frame->loader()->url();
    1650     if (!url.hasPath())
    1651         return jsString(url.prettyURL() + "/");
    1652     return jsString(url.prettyURL());
    1653 }
    1654 
    1655 /////////////////////////////////////////////////////////////////////////////
    1656 
    1657 void DOMWindowTimer::fired()
    1658 {
    1659     timerNestingLevel = m_nestingLevel;
    1660     m_object->timerFired(this);
    1661     timerNestingLevel = 0;
    1662 }
    1663 
    1664 } // namespace KJS
    1665 
    1666 using namespace KJS;
    1667 
    1668 namespace WebCore {
    1669 
    1670 JSValue* toJS(ExecState*, DOMWindow* domWindow)
    1671 {
    1672     if (!domWindow)
    1673         return jsNull();
    1674     Frame* frame = domWindow->frame();
    1675     if (!frame)
    1676         return jsNull();
    1677     return Window::retrieve(frame);
    1678 }
    1679 
    1680102} // namespace WebCore
  • trunk/WebCore/bindings/js/ScheduledAction.h

    r28779 r28794  
    1818 */
    1919
    20 #ifndef kjs_window_h
    21 #define kjs_window_h
     20#ifndef ScheduledAction_h
     21#define ScheduledAction_h
    2222
    2323#include "PlatformString.h"
    24 #include "kjs_binding.h"
    2524#include <kjs/protect.h>
    26 #include <wtf/HashMap.h>
    27 #include <wtf/Noncopyable.h>
    28 #include <wtf/OwnPtr.h>
     25#include <wtf/Vector.h>
     26
     27namespace KJS {
     28    class Window;
     29    class JSValue;
     30    class List;
     31}
    2932
    3033namespace WebCore {
    31     class AtomicString;
    32     class DOMWindow;
    33     class Frame;
    34     class JSEventListener;
    35     class JSUnprotectedEventListener;
    36     class PausedTimeouts;
    37 }
    38 
    39 namespace KJS {
    40 
    41     class DOMWindowTimer;
    42     class Location;
    43     class ScheduledAction;
    44     class Window;
    45     class WindowFunc;
    46     class WindowPrivate;
    47 
    48   // This is the only WebCore JS binding which does not inherit from DOMObject
    49   class Window : public JSGlobalObject {
    50     friend class Location;
    51     friend class ScheduledAction;
    52   protected:
    53     Window(WebCore::DOMWindow*);
    54 
    55   public:
    56     virtual ~Window();
    57 
    58     WebCore::DOMWindow* impl() const { return m_impl.get(); }
    59 
    60     void disconnectFrame();
    61 
    62     // Returns and registers a window object. In case there's already a Window
    63     // for the specified frame p this will be returned in order to have unique
    64     // bindings.
    65     static JSValue* retrieve(WebCore::Frame*);
    66 
    67     // Returns the Window object for a given HTML frame
    68     static Window* retrieveWindow(WebCore::Frame*);
    69 
    70     // Returns a pointer to the Window object this javascript interpreting instance
    71     // was called from.
    72     static Window* retrieveActive(ExecState*);
    73 
    74     virtual void mark();
    75 
    76     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    77     JSValue* getValueProperty(ExecState*, int token) const;
    78     virtual void put(ExecState*, const Identifier& propertyName, JSValue*, int attr = None);
    79 
    80     int installTimeout(const UString& handler, int t, bool singleShot);
    81     int installTimeout(JSValue* function, const List& args, int t, bool singleShot);
    82     void clearTimeout(int timerId, bool delAction = true);
    83     WebCore::PausedTimeouts* pauseTimeouts();
    84     void resumeTimeouts(WebCore::PausedTimeouts*);
    85 
    86     void timerFired(DOMWindowTimer*);
    87 
    88     Location* location() const;
    89 
    90     // Finds a wrapper of a JS EventListener, returns 0 if no existing one.
    91     WebCore::JSEventListener* findJSEventListener(JSValue*, bool html = false);
    92 
    93     // Finds or creates a wrapper of a JS EventListener. JS EventListener object is GC-protected.
    94     WebCore::JSEventListener *findOrCreateJSEventListener(JSValue*, bool html = false);
    95 
    96     // Finds a wrapper of a GC-unprotected JS EventListener, returns 0 if no existing one.
    97     WebCore::JSUnprotectedEventListener* findJSUnprotectedEventListener(JSValue*, bool html = false);
    98 
    99     // Finds or creates a wrapper of a JS EventListener. JS EventListener object is *NOT* GC-protected.
    100     WebCore::JSUnprotectedEventListener *findOrCreateJSUnprotectedEventListener(JSValue*, bool html = false);
    101 
    102     void clear();
    103 
    104     void setCurrentEvent(WebCore::Event*);
    105     WebCore::Event* currentEvent();
    106 
    107     // Set a place to put a dialog return value when the window is cleared.
    108     void setReturnValueSlot(JSValue** slot);
    109 
    110     typedef HashMap<JSObject*, WebCore::JSEventListener*> ListenersMap;
    111     typedef HashMap<JSObject*, WebCore::JSUnprotectedEventListener*> UnprotectedListenersMap;
    112    
    113     ListenersMap& jsEventListeners();
    114     ListenersMap& jsHTMLEventListeners();
    115     UnprotectedListenersMap& jsUnprotectedEventListeners();
    116     UnprotectedListenersMap& jsUnprotectedHTMLEventListeners();
    117    
    118     virtual const ClassInfo* classInfo() const { return &info; }
    119     static const ClassInfo info;
    120 
    121     virtual ExecState* globalExec();
    122 
    123     virtual bool shouldInterruptScript() const;
    124 
    125     virtual bool allowsAccessFrom(const JSGlobalObject*) const;
    126     bool allowsAccessFrom(ExecState* exec) const { return allowsAccessFrom(exec->dynamicGlobalObject()); }
    127 
    128     enum {
    129         // Attributes
    130         Crypto, Event_, Location_, Navigator_,
    131         ClientInformation,
    132 
    133         // Event Listeners
    134         Onabort, Onblur, Onchange, Onclick,
    135         Ondblclick, Onerror, Onfocus, Onkeydown,
    136         Onkeypress, Onkeyup, Onload, Onmousedown,
    137         Onmousemove, Onmouseout, Onmouseover, Onmouseup,
    138         OnWindowMouseWheel, Onreset, Onresize, Onscroll,
    139         Onsearch, Onselect, Onsubmit, Onunload,
    140         Onbeforeunload,
    141 
    142         // Constructors
    143         DOMException, Audio, Image, Option, XMLHttpRequest,
    144         XSLTProcessor_
    145     };
    146 
    147   private:
    148     JSValue* getListener(ExecState*, const WebCore::AtomicString& eventType) const;
    149     void setListener(ExecState*, const WebCore::AtomicString& eventType, JSValue* func);
    150 
    151     static JSValue* childFrameGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
    152     static JSValue* namedFrameGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
    153     static JSValue* indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
    154     static JSValue* namedItemGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
    155 
    156     void clearHelperObjectProperties();
    157     void clearAllTimeouts();
    158     int installTimeout(ScheduledAction*, int interval, bool singleShot);
    159 
    160     RefPtr<WebCore::DOMWindow> m_impl;
    161     OwnPtr<WindowPrivate> d;
    162   };
    163 
    164 #define FOR_EACH_CLASS(macro) \
    165     macro(WindowProtoFuncAToB) \
    166     macro(WindowProtoFuncBToA) \
    167     macro(WindowProtoFuncOpen) \
    168     macro(WindowProtoFuncSetTimeout) \
    169     macro(WindowProtoFuncClearTimeout) \
    170     macro(WindowProtoFuncSetInterval) \
    171     macro(WindowProtoFuncAddEventListener) \
    172     macro(WindowProtoFuncRemoveEventListener) \
    173     macro(WindowProtoFuncShowModalDialog) \
    174     macro(WindowProtoFuncNotImplemented) \
    175 
    176 FOR_EACH_CLASS(KJS_IMPLEMENT_PROTOTYPE_FUNCTION_WITH_CREATE)
    177 #undef FOR_EACH_CLASS
    178 
    17934
    18035  /**
     
    18540    class ScheduledAction {
    18641    public:
    187         ScheduledAction(JSValue* func, const List& args);
    188         ScheduledAction(const WebCore::String& code)
     42        ScheduledAction(KJS::JSValue* func, const KJS::List& args);
     43        ScheduledAction(const String& code)
    18944            : m_code(code)
    19045        {
    19146        }
    19247
    193         void execute(Window *);
     48        void execute(KJS::Window*);
    19449
    19550    private:
    196         ProtectedPtr<JSValue> m_func;
    197         Vector<ProtectedPtr<JSValue> > m_args;
    198         WebCore::String m_code;
     51        KJS::ProtectedPtr<KJS::JSValue> m_func;
     52        Vector<KJS::ProtectedPtr<KJS::JSValue> > m_args;
     53        String m_code;
    19954    };
    20055
    201   class Location : public DOMObject {
    202     friend class Window;
    203   public:
    204     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    205     JSValue* getValueProperty(ExecState*, int token) const;
    206     virtual void put(ExecState*, const Identifier& propertyName, JSValue*, int attr = None);
    207 
    208     enum { Hash, Href, Hostname, Host, Pathname, Port, Protocol, Search,
    209            Replace, Reload, ToString, Assign };
    210 
    211     WebCore::Frame* frame() const { return m_frame; }
    212 
    213     virtual const ClassInfo* classInfo() const { return &info; }
    214     static const ClassInfo info;
    215 
    216   private:
    217     Location(WebCore::Frame*);
    218 
    219     WebCore::Frame* m_frame;
    220   };
    221 
    222 #define FOR_EACH_CLASS(macro) \
    223     macro(LocationProtoFuncAssign) \
    224     macro(LocationProtoFuncToString) \
    225     macro(LocationProtoFuncReplace) \
    226     macro(LocationProtoFuncReload) \
    227 
    228 FOR_EACH_CLASS(KJS_IMPLEMENT_PROTOTYPE_FUNCTION_WITH_CREATE)
    229 #undef FOR_EACH_CLASS
    230 
    231 } // namespace KJS
    232 
    233 namespace WebCore {
    234     KJS::JSValue* toJS(KJS::ExecState*, DOMWindow*);
    23556} // namespace WebCore
    23657
    237 #endif // kjs_window_h
     58#endif // ScheduledAction_h
  • trunk/WebCore/bindings/js/kjs_window.cpp

    r28779 r28794  
    5353#include "PlugInInfoStore.h"
    5454#include "RenderView.h"
     55#include "ScheduledAction.h"
    5556#include "SecurityOrigin.h"
    5657#include "Settings.h"
     
    100101class DOMWindowTimer : public TimerBase {
    101102public:
    102     DOMWindowTimer(int timeoutId, int nestingLevel, Window* object, ScheduledAction* action)
     103    DOMWindowTimer(int timeoutId, int nestingLevel, Window* object, WebCore::ScheduledAction* action)
    103104        : m_timeoutId(timeoutId)
    104105        , m_nestingLevel(nestingLevel)
     
    119120    void setNestingLevel(int n) { m_nestingLevel = n; }
    120121
    121     ScheduledAction* action() const { return m_action; }
    122     ScheduledAction* takeAction() { ScheduledAction* a = m_action; m_action = 0; return a; }
     122    WebCore::ScheduledAction* action() const { return m_action; }
     123    WebCore::ScheduledAction* takeAction() { WebCore::ScheduledAction* a = m_action; m_action = 0; return a; }
    123124
    124125private:
     
    128129    int m_nestingLevel;
    129130    Window* m_object;
    130     ScheduledAction* m_action;
     131    WebCore::ScheduledAction* m_action;
    131132};
    132133
     
    12031204}
    12041205
    1205 ////////////////////// ScheduledAction ////////////////////////
    1206 
    1207 void ScheduledAction::execute(Window* window)
    1208 {
    1209     RefPtr<Frame> frame = window->impl()->frame();
    1210     if (!frame)
    1211         return;
    1212 
    1213     KJSProxy* scriptProxy = frame->scriptProxy();
    1214     if (!scriptProxy)
    1215         return;
    1216 
    1217     Window* globalObject = scriptProxy->globalObject();
    1218 
    1219     scriptProxy->setProcessingTimerCallback(true);
    1220 
    1221     if (JSValue* func = m_func.get()) {
    1222         JSLock lock;
    1223         if (func->isObject() && static_cast<JSObject*>(func)->implementsCall()) {
    1224             ExecState* exec = window->globalExec();
    1225             ASSERT(window == globalObject);
    1226 
    1227             List args;
    1228             size_t size = m_args.size();
    1229             for (size_t i = 0; i < size; ++i) {
    1230                 args.append(m_args[i]);
    1231             }
    1232 
    1233             globalObject->startTimeoutCheck();
    1234             static_cast<JSObject*>(func)->call(exec, window, args);
    1235             globalObject->stopTimeoutCheck();
    1236             if (exec->hadException()) {
    1237                 JSObject* exception = exec->exception()->toObject(exec);
    1238                 exec->clearException();
    1239                 String message = exception->get(exec, exec->propertyNames().message)->toString(exec);
    1240                 int lineNumber = exception->get(exec, "line")->toInt32(exec);
    1241                 if (Interpreter::shouldPrintExceptions())
    1242                     printf("(timer):%s\n", message.utf8().data());
    1243                 if (Page* page = frame->page())
    1244                     page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, String());
    1245             }
    1246         }
    1247     } else
    1248         frame->loader()->executeScript(m_code);
    1249 
    1250     // Update our document's rendering following the execution of the timeout callback.
    1251     // FIXME: Why not use updateDocumentsRendering to update rendering of all documents?
    1252     // FIXME: Is this really the right point to do the update? We need a place that works
    1253     // for all possible entry points that might possibly execute script, but this seems
    1254     // to be a bit too low-level.
    1255     if (Document* doc = frame->document())
    1256         doc->updateRendering();
    1257 
    1258     scriptProxy->setProcessingTimerCallback(false);
    1259 }
    1260 
    12611206////////////////////// timeouts ////////////////////////
    12621207
     
    12671212}
    12681213
    1269 int Window::installTimeout(ScheduledAction* a, int t, bool singleShot)
     1214int Window::installTimeout(WebCore::ScheduledAction* a, int t, bool singleShot)
    12701215{
    12711216    int timeoutId = ++lastUsedTimeoutId;
     
    12921237}
    12931238
    1294 ScheduledAction::ScheduledAction(JSValue* func, const List& args)
    1295     : m_func(func)
    1296 {
    1297     List::const_iterator end = args.end();
    1298     for (List::const_iterator it = args.begin(); it != end; ++it)
    1299         m_args.append(*it);
    1300 }
    1301 
    13021239int Window::installTimeout(const UString& handler, int t, bool singleShot)
    13031240{
    1304     return installTimeout(new ScheduledAction(handler), t, singleShot);
     1241    return installTimeout(new WebCore::ScheduledAction(handler), t, singleShot);
    13051242}
    13061243
    13071244int Window::installTimeout(JSValue* func, const List& args, int t, bool singleShot)
    13081245{
    1309     return installTimeout(new ScheduledAction(func, args), t, singleShot);
     1246    return installTimeout(new WebCore::ScheduledAction(func, args), t, singleShot);
    13101247}
    13111248
     
    13791316
    13801317    // Delete timer before executing the action for one-shot timers.
    1381     ScheduledAction* action = timer->takeAction();
     1318    WebCore::ScheduledAction* action = timer->takeAction();
    13821319    d->m_timeouts.remove(timer->timeoutId());
    13831320    delete timer;
  • trunk/WebCore/bindings/js/kjs_window.h

    r28779 r28794  
    3535    class JSUnprotectedEventListener;
    3636    class PausedTimeouts;
     37    class ScheduledAction;
    3738}
    3839
     
    4142    class DOMWindowTimer;
    4243    class Location;
    43     class ScheduledAction;
    4444    class Window;
    4545    class WindowFunc;
     
    4949  class Window : public JSGlobalObject {
    5050    friend class Location;
    51     friend class ScheduledAction;
     51    friend class WebCore::ScheduledAction;
    5252  protected:
    5353    Window(WebCore::DOMWindow*);
     
    156156    void clearHelperObjectProperties();
    157157    void clearAllTimeouts();
    158     int installTimeout(ScheduledAction*, int interval, bool singleShot);
     158    int installTimeout(WebCore::ScheduledAction*, int interval, bool singleShot);
    159159
    160160    RefPtr<WebCore::DOMWindow> m_impl;
     
    178178
    179179
    180   /**
    181    * An action (either function or string) to be executed after a specified
    182    * time interval, either once or repeatedly. Used for window.setTimeout()
    183    * and window.setInterval()
    184    */
    185     class ScheduledAction {
    186     public:
    187         ScheduledAction(JSValue* func, const List& args);
    188         ScheduledAction(const WebCore::String& code)
    189             : m_code(code)
    190         {
    191         }
    192 
    193         void execute(Window *);
    194 
    195     private:
    196         ProtectedPtr<JSValue> m_func;
    197         Vector<ProtectedPtr<JSValue> > m_args;
    198         WebCore::String m_code;
    199     };
    200 
    201180  class Location : public DOMObject {
    202181    friend class Window;
Note: See TracChangeset for help on using the changeset viewer.