1/*
2 * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef DOMWindow_h
28#define DOMWindow_h
29
30#include "ContextDestructionObserver.h"
31#include "EventTarget.h"
32#include "FrameDestructionObserver.h"
33#include "KURL.h"
34#include "Supplementable.h"
35
36namespace WebCore {
37
38    class BarProp;
39    class CSSRuleList;
40    class CSSStyleDeclaration;
41    class Console;
42    class Crypto;
43    class DOMApplicationCache;
44    class DOMSelection;
45    class DOMURL;
46    class DOMWindowProperty;
47    class Database;
48    class DatabaseCallback;
49    class Document;
50    class Element;
51    class EventListener;
52    class FloatRect;
53    class Frame;
54    class History;
55    class IDBFactory;
56    class Location;
57    class MediaQueryList;
58    class MessageEvent;
59    class Navigator;
60    class Node;
61    class Page;
62    class PageConsole;
63    class Performance;
64    class PostMessageTimer;
65    class ScheduledAction;
66    class Screen;
67    class ScriptCallStack;
68    class SecurityOrigin;
69    class SerializedScriptValue;
70    class Storage;
71    class StyleMedia;
72    class WebKitPoint;
73    class DOMWindowCSS;
74
75#if ENABLE(REQUEST_ANIMATION_FRAME)
76    class RequestAnimationFrameCallback;
77#endif
78
79    struct WindowFeatures;
80
81    typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
82
83    typedef int ExceptionCode;
84
85    enum SetLocationLocking { LockHistoryBasedOnGestureState, LockHistoryAndBackForwardList };
86
87    // FIXME: DOMWindow shouldn't subclass FrameDestructionObserver and instead should get to Frame via its Document.
88    class DOMWindow : public RefCounted<DOMWindow>
89                    , public EventTarget
90                    , public ContextDestructionObserver
91                    , public FrameDestructionObserver
92                    , public Supplementable<DOMWindow> {
93    public:
94        static PassRefPtr<DOMWindow> create(Document* document) { return adoptRef(new DOMWindow(document)); }
95        virtual ~DOMWindow();
96
97        // In some rare cases, we'll re-used a DOMWindow for a new Document. For example,
98        // when a script calls window.open("..."), the browser gives JavaScript a window
99        // synchronously but kicks off the load in the window asynchronously. Web sites
100        // expect that modifications that they make to the window object synchronously
101        // won't be blown away when the network load commits. To make that happen, we
102        // "securely transition" the existing DOMWindow to the Document that results from
103        // the network load. See also SecurityContext::isSecureTransitionTo.
104        void didSecureTransitionTo(Document*);
105
106        virtual const AtomicString& interfaceName() const;
107        virtual ScriptExecutionContext* scriptExecutionContext() const;
108
109        virtual DOMWindow* toDOMWindow();
110
111        void registerProperty(DOMWindowProperty*);
112        void unregisterProperty(DOMWindowProperty*);
113
114        void resetUnlessSuspendedForPageCache();
115        void suspendForPageCache();
116        void resumeFromPageCache();
117
118        PassRefPtr<MediaQueryList> matchMedia(const String&);
119
120        unsigned pendingUnloadEventListeners() const;
121
122        static bool dispatchAllPendingBeforeUnloadEvents();
123        static void dispatchAllPendingUnloadEvents();
124
125        static FloatRect adjustWindowRect(Page*, const FloatRect& pendingChanges);
126
127        bool allowPopUp(); // Call on first window, not target window.
128        static bool allowPopUp(Frame* firstFrame);
129        static bool canShowModalDialog(const Frame*);
130        static bool canShowModalDialogNow(const Frame*);
131
132        // DOM Level 0
133
134        Screen* screen() const;
135        History* history() const;
136        Crypto* crypto() const;
137        BarProp* locationbar() const;
138        BarProp* menubar() const;
139        BarProp* personalbar() const;
140        BarProp* scrollbars() const;
141        BarProp* statusbar() const;
142        BarProp* toolbar() const;
143        Navigator* navigator() const;
144        Navigator* clientInformation() const { return navigator(); }
145
146        Location* location() const;
147        void setLocation(const String& location, DOMWindow* activeWindow, DOMWindow* firstWindow,
148            SetLocationLocking = LockHistoryBasedOnGestureState);
149
150        DOMSelection* getSelection();
151
152        Element* frameElement() const;
153
154        void focus(ScriptExecutionContext* = 0);
155        void blur();
156        void close(ScriptExecutionContext* = 0);
157        void print();
158        void stop();
159
160        PassRefPtr<DOMWindow> open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
161            DOMWindow* activeWindow, DOMWindow* firstWindow);
162
163        typedef void (*PrepareDialogFunction)(DOMWindow*, void* context);
164        void showModalDialog(const String& urlString, const String& dialogFeaturesString,
165            DOMWindow* activeWindow, DOMWindow* firstWindow, PrepareDialogFunction, void* functionContext);
166
167        void alert(const String& message);
168        bool confirm(const String& message);
169        String prompt(const String& message, const String& defaultValue);
170        String btoa(const String& stringToEncode, ExceptionCode&);
171        String atob(const String& encodedString, ExceptionCode&);
172
173        bool find(const String&, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const;
174
175        bool offscreenBuffering() const;
176
177        int outerHeight() const;
178        int outerWidth() const;
179        int innerHeight() const;
180        int innerWidth() const;
181        int screenX() const;
182        int screenY() const;
183        int screenLeft() const { return screenX(); }
184        int screenTop() const { return screenY(); }
185        int scrollX() const;
186        int scrollY() const;
187        int pageXOffset() const { return scrollX(); }
188        int pageYOffset() const { return scrollY(); }
189
190        bool closed() const;
191
192        unsigned length() const;
193
194        String name() const;
195        void setName(const String&);
196
197        String status() const;
198        void setStatus(const String&);
199        String defaultStatus() const;
200        void setDefaultStatus(const String&);
201
202        // This attribute is an alias of defaultStatus and is necessary for legacy uses.
203        String defaultstatus() const { return defaultStatus(); }
204        void setDefaultstatus(const String& status) { setDefaultStatus(status); }
205
206        // Self-referential attributes
207
208        DOMWindow* self() const;
209        DOMWindow* window() const { return self(); }
210        DOMWindow* frames() const { return self(); }
211
212        DOMWindow* opener() const;
213        DOMWindow* parent() const;
214        DOMWindow* top() const;
215
216        // DOM Level 2 AbstractView Interface
217
218        Document* document() const;
219
220        // CSSOM View Module
221
222        PassRefPtr<StyleMedia> styleMedia() const;
223
224        // DOM Level 2 Style Interface
225
226        PassRefPtr<CSSStyleDeclaration> getComputedStyle(Element*, const String& pseudoElt) const;
227
228        // WebKit extensions
229
230        PassRefPtr<CSSRuleList> getMatchedCSSRules(Element*, const String& pseudoElt, bool authorOnly = true) const;
231        double devicePixelRatio() const;
232
233        PassRefPtr<WebKitPoint> webkitConvertPointFromPageToNode(Node*, const WebKitPoint*) const;
234        PassRefPtr<WebKitPoint> webkitConvertPointFromNodeToPage(Node*, const WebKitPoint*) const;
235
236        Console* console() const;
237        PageConsole* pageConsole() const;
238
239        void printErrorMessage(const String&);
240        String crossDomainAccessErrorMessage(DOMWindow* activeWindow);
241
242        void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
243        // Needed for Objective-C bindings (see bug 28774).
244        void postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
245        void postMessageTimerFired(PassOwnPtr<PostMessageTimer>);
246        void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, PassRefPtr<Event>, PassRefPtr<ScriptCallStack>);
247
248        void scrollBy(int x, int y) const;
249        void scrollTo(int x, int y) const;
250        void scroll(int x, int y) const { scrollTo(x, y); }
251
252        void moveBy(float x, float y) const;
253        void moveTo(float x, float y) const;
254
255        void resizeBy(float x, float y) const;
256        void resizeTo(float width, float height) const;
257
258        // Timers
259        int setTimeout(PassOwnPtr<ScheduledAction>, int timeout, ExceptionCode&);
260        void clearTimeout(int timeoutId);
261        int setInterval(PassOwnPtr<ScheduledAction>, int timeout, ExceptionCode&);
262        void clearInterval(int timeoutId);
263
264        // WebKit animation extensions
265#if ENABLE(REQUEST_ANIMATION_FRAME)
266        int requestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>);
267        int webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback>);
268        void cancelAnimationFrame(int id);
269#endif
270
271#if ENABLE(CSS3_CONDITIONAL_RULES)
272        DOMWindowCSS* css();
273#endif
274
275        // Events
276        // EventTarget API
277        virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
278        virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
279        virtual void removeAllEventListeners();
280
281        using EventTarget::dispatchEvent;
282        bool dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget);
283
284        void dispatchLoadEvent();
285
286        DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
287        DEFINE_ATTRIBUTE_EVENT_LISTENER(beforeunload);
288        DEFINE_ATTRIBUTE_EVENT_LISTENER(blur);
289        DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay);
290        DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough);
291        DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
292        DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
293        DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
294        DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
295        DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
296        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
297        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
298        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
299        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
300        DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
301        DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
302        DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange);
303        DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied);
304        DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
305        DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
306        DEFINE_ATTRIBUTE_EVENT_LISTENER(focus);
307        DEFINE_ATTRIBUTE_EVENT_LISTENER(hashchange);
308        DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
309        DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
310        DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
311        DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
312        DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
313        DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
314        DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata);
315        DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata);
316        DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
317        DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
318        DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
319        DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseenter);
320        DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseleave);
321        DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
322        DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
323        DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
324        DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
325        DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
326        DEFINE_ATTRIBUTE_EVENT_LISTENER(offline);
327        DEFINE_ATTRIBUTE_EVENT_LISTENER(online);
328        DEFINE_ATTRIBUTE_EVENT_LISTENER(pagehide);
329        DEFINE_ATTRIBUTE_EVENT_LISTENER(pageshow);
330        DEFINE_ATTRIBUTE_EVENT_LISTENER(pause);
331        DEFINE_ATTRIBUTE_EVENT_LISTENER(play);
332        DEFINE_ATTRIBUTE_EVENT_LISTENER(playing);
333        DEFINE_ATTRIBUTE_EVENT_LISTENER(popstate);
334        DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
335        DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange);
336        DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
337        DEFINE_ATTRIBUTE_EVENT_LISTENER(resize);
338        DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
339        DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
340        DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked);
341        DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking);
342        DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
343        DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled);
344        DEFINE_ATTRIBUTE_EVENT_LISTENER(storage);
345        DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
346        DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend);
347        DEFINE_ATTRIBUTE_EVENT_LISTENER(timeupdate);
348        DEFINE_ATTRIBUTE_EVENT_LISTENER(unload);
349        DEFINE_ATTRIBUTE_EVENT_LISTENER(volumechange);
350        DEFINE_ATTRIBUTE_EVENT_LISTENER(waiting);
351        DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitbeginfullscreen);
352        DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitendfullscreen);
353
354        DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, webkitAnimationStart);
355        DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration, webkitAnimationIteration);
356        DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd);
357        DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd);
358        DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(transitionend, transitionend);
359
360        void captureEvents();
361        void releaseEvents();
362
363        void finishedLoading();
364
365        using RefCounted<DOMWindow>::ref;
366        using RefCounted<DOMWindow>::deref;
367
368#if ENABLE(DEVICE_ORIENTATION)
369        DEFINE_ATTRIBUTE_EVENT_LISTENER(devicemotion);
370        DEFINE_ATTRIBUTE_EVENT_LISTENER(deviceorientation);
371#endif
372
373#if ENABLE(PROXIMITY_EVENTS)
374        DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitdeviceproximity);
375#endif
376
377        // HTML 5 key/value storage
378        Storage* sessionStorage(ExceptionCode&) const;
379        Storage* localStorage(ExceptionCode&) const;
380        Storage* optionalSessionStorage() const { return m_sessionStorage.get(); }
381        Storage* optionalLocalStorage() const { return m_localStorage.get(); }
382
383        DOMApplicationCache* applicationCache() const;
384        DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); }
385
386#if ENABLE(ORIENTATION_EVENTS)
387        // This is the interface orientation in degrees. Some examples are:
388        //  0 is straight up; -90 is when the device is rotated 90 clockwise;
389        //  90 is when rotated counter clockwise.
390        int orientation() const;
391
392        DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
393#endif
394
395#if ENABLE(TOUCH_EVENTS)
396        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
397        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
398        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
399        DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
400#endif
401
402#if ENABLE(WEB_TIMING)
403        Performance* performance() const;
404#endif
405
406        // FIXME: When this DOMWindow is no longer the active DOMWindow (i.e.,
407        // when its document is no longer the document that is displayed in its
408        // frame), we would like to zero out m_frame to avoid being confused
409        // by the document that is currently active in m_frame.
410        bool isCurrentlyDisplayedInFrame() const;
411
412        void willDetachDocumentFromFrame();
413        void willDestroyCachedFrame();
414
415        void enableSuddenTermination();
416        void disableSuddenTermination();
417
418    private:
419        explicit DOMWindow(Document*);
420
421        Page* page();
422        bool allowedToChangeWindowGeometry() const;
423
424        virtual void frameDestroyed() OVERRIDE;
425        virtual void willDetachPage() OVERRIDE;
426
427        virtual void refEventTarget() { ref(); }
428        virtual void derefEventTarget() { deref(); }
429        virtual EventTargetData* eventTargetData();
430        virtual EventTargetData* ensureEventTargetData();
431
432        static PassRefPtr<Frame> createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&,
433            DOMWindow* activeWindow, Frame* firstFrame, Frame* openerFrame,
434            PrepareDialogFunction = 0, void* functionContext = 0);
435        bool isInsecureScriptAccess(DOMWindow* activeWindow, const String& urlString);
436
437        void resetDOMWindowProperties();
438        void disconnectDOMWindowProperties();
439        void reconnectDOMWindowProperties();
440        void willDestroyDocumentInFrame();
441
442        bool m_shouldPrintWhenFinishedLoading;
443        bool m_suspendedForPageCache;
444
445        HashSet<DOMWindowProperty*> m_properties;
446
447        mutable RefPtr<Screen> m_screen;
448        mutable RefPtr<History> m_history;
449        mutable RefPtr<Crypto>  m_crypto;
450        mutable RefPtr<BarProp> m_locationbar;
451        mutable RefPtr<BarProp> m_menubar;
452        mutable RefPtr<BarProp> m_personalbar;
453        mutable RefPtr<BarProp> m_scrollbars;
454        mutable RefPtr<BarProp> m_statusbar;
455        mutable RefPtr<BarProp> m_toolbar;
456        mutable RefPtr<Console> m_console;
457        mutable RefPtr<Navigator> m_navigator;
458        mutable RefPtr<Location> m_location;
459        mutable RefPtr<StyleMedia> m_media;
460
461        EventTargetData m_eventTargetData;
462
463        String m_status;
464        String m_defaultStatus;
465
466        mutable RefPtr<Storage> m_sessionStorage;
467        mutable RefPtr<Storage> m_localStorage;
468        mutable RefPtr<DOMApplicationCache> m_applicationCache;
469
470#if ENABLE(WEB_TIMING)
471        mutable RefPtr<Performance> m_performance;
472#endif
473
474#if ENABLE(CSS3_CONDITIONAL_RULES)
475        mutable RefPtr<DOMWindowCSS> m_css;
476#endif
477    };
478
479    inline String DOMWindow::status() const
480    {
481        return m_status;
482    }
483
484    inline String DOMWindow::defaultStatus() const
485    {
486        return m_defaultStatus;
487    }
488
489} // namespace WebCore
490
491#endif // DOMWindow_h
492