1/*
2 * Copyright (C) 2006-2017 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 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 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#pragma once
28
29#include "AbstractDOMWindow.h"
30#include "Base64Utilities.h"
31#include "ContextDestructionObserver.h"
32#include "ExceptionOr.h"
33#include "Frame.h"
34#include "FrameDestructionObserver.h"
35#include "ImageBitmap.h"
36#include "ScrollToOptions.h"
37#include "ScrollTypes.h"
38#include "Supplementable.h"
39#include <JavaScriptCore/HandleTypes.h>
40#include <wtf/Function.h>
41#include <wtf/HashSet.h>
42#include <wtf/WeakPtr.h>
43
44namespace JSC {
45class ExecState;
46class JSObject;
47class JSValue;
48template<typename> class Strong;
49}
50
51namespace WebCore {
52
53class BarProp;
54class CSSRuleList;
55class CSSStyleDeclaration;
56class Crypto;
57class CustomElementRegistry;
58class DOMApplicationCache;
59class DOMSelection;
60class DOMWindowProperty;
61class DOMWrapperWorld;
62class Document;
63class Element;
64class EventListener;
65class FloatRect;
66class History;
67class Location;
68class MediaQueryList;
69class Navigator;
70class Node;
71class NodeList;
72class Page;
73class PageConsoleClient;
74class Performance;
75class PostMessageTimer;
76class RequestAnimationFrameCallback;
77class ScheduledAction;
78class Screen;
79class Storage;
80class StyleMedia;
81class VisualViewport;
82class WebKitNamespace;
83class WebKitPoint;
84
85#if ENABLE(DEVICE_ORIENTATION)
86class DeviceMotionController;
87class DeviceOrientationController;
88#endif
89
90struct ImageBitmapOptions;
91struct WindowFeatures;
92
93enum SetLocationLocking { LockHistoryBasedOnGestureState, LockHistoryAndBackForwardList };
94enum class IncludeTargetOrigin { No, Yes };
95
96// FIXME: Rename DOMWindow to LocalWindow and AbstractDOMWindow to DOMWindow.
97class DOMWindow final
98 : public AbstractDOMWindow
99 , public CanMakeWeakPtr<DOMWindow>
100 , public ContextDestructionObserver
101 , public Base64Utilities
102 , public Supplementable<DOMWindow> {
103 WTF_MAKE_ISO_ALLOCATED(DOMWindow);
104public:
105
106 static Ref<DOMWindow> create(Document& document) { return adoptRef(*new DOMWindow(document)); }
107 WEBCORE_EXPORT virtual ~DOMWindow();
108
109 // In some rare cases, we'll reuse a DOMWindow for a new Document. For example,
110 // when a script calls window.open("..."), the browser gives JavaScript a window
111 // synchronously but kicks off the load in the window asynchronously. Web sites
112 // expect that modifications that they make to the window object synchronously
113 // won't be blown away when the network load commits. To make that happen, we
114 // "securely transition" the existing DOMWindow to the Document that results from
115 // the network load. See also SecurityContext::isSecureTransitionTo.
116 void didSecureTransitionTo(Document&);
117
118 class Observer {
119 public:
120 virtual ~Observer() { }
121
122 virtual void suspendForPageCache() { }
123 virtual void resumeFromPageCache() { }
124 virtual void willDestroyGlobalObjectInCachedFrame() { }
125 virtual void willDestroyGlobalObjectInFrame() { }
126 virtual void willDetachGlobalObjectFromFrame() { }
127 };
128
129 void registerObserver(Observer&);
130 void unregisterObserver(Observer&);
131
132 void resetUnlessSuspendedForDocumentSuspension();
133 void suspendForPageCache();
134 void resumeFromPageCache();
135
136 WEBCORE_EXPORT Frame* frame() const final;
137
138 RefPtr<MediaQueryList> matchMedia(const String&);
139
140 WEBCORE_EXPORT unsigned pendingUnloadEventListeners() const;
141
142 WEBCORE_EXPORT static bool dispatchAllPendingBeforeUnloadEvents();
143 WEBCORE_EXPORT static void dispatchAllPendingUnloadEvents();
144
145 static FloatRect adjustWindowRect(Page&, const FloatRect& pendingChanges);
146
147 bool allowPopUp(); // Call on first window, not target window.
148 static bool allowPopUp(Frame& firstFrame);
149 static bool canShowModalDialog(const Frame&);
150 WEBCORE_EXPORT void setCanShowModalDialogOverride(bool);
151
152 Screen& screen();
153 History& history();
154 Crypto& crypto() const;
155 BarProp& locationbar();
156 BarProp& menubar();
157 BarProp& personalbar();
158 BarProp& scrollbars();
159 BarProp& statusbar();
160 BarProp& toolbar();
161 WEBCORE_EXPORT Navigator& navigator();
162 Navigator* optionalNavigator() const { return m_navigator.get(); }
163 Navigator& clientInformation() { return navigator(); }
164
165 Location& location();
166 void setLocation(DOMWindow& activeWindow, const URL& completedURL, SetLocationLocking = LockHistoryBasedOnGestureState);
167
168 DOMSelection* getSelection();
169
170 Element* frameElement() const;
171
172 WEBCORE_EXPORT void focus(bool allowFocus = false);
173 void focus(DOMWindow& incumbentWindow);
174 void blur();
175 WEBCORE_EXPORT void close();
176 void close(Document&);
177 void print();
178 void stop();
179
180 WEBCORE_EXPORT ExceptionOr<RefPtr<WindowProxy>> open(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& urlString, const AtomString& frameName, const String& windowFeaturesString);
181
182 void showModalDialog(const String& urlString, const String& dialogFeaturesString, DOMWindow& activeWindow, DOMWindow& firstWindow, const WTF::Function<void(DOMWindow&)>& prepareDialogFunction);
183
184 void alert(const String& message = emptyString());
185 bool confirm(const String& message);
186 String prompt(const String& message, const String& defaultValue);
187
188 bool find(const String&, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const;
189
190 bool offscreenBuffering() const;
191
192 int outerHeight() const;
193 int outerWidth() const;
194 int innerHeight() const;
195 int innerWidth() const;
196 int screenX() const;
197 int screenY() const;
198 int screenLeft() const { return screenX(); }
199 int screenTop() const { return screenY(); }
200 int scrollX() const;
201 int scrollY() const;
202
203 bool closed() const;
204
205 unsigned length() const;
206
207 String name() const;
208 void setName(const String&);
209
210 String status() const;
211 void setStatus(const String&);
212 String defaultStatus() const;
213 void setDefaultStatus(const String&);
214
215 WindowProxy* opener() const;
216 void disownOpener();
217 WindowProxy* parent() const;
218 WindowProxy* top() const;
219
220 String origin() const;
221
222 // DOM Level 2 AbstractView Interface
223
224 WEBCORE_EXPORT Document* document() const;
225
226 // CSSOM View Module
227
228 StyleMedia& styleMedia();
229
230 // DOM Level 2 Style Interface
231
232 WEBCORE_EXPORT Ref<CSSStyleDeclaration> getComputedStyle(Element&, const String& pseudoElt) const;
233
234 // WebKit extensions
235
236 WEBCORE_EXPORT RefPtr<CSSRuleList> getMatchedCSSRules(Element*, const String& pseudoElt, bool authorOnly = true) const;
237 double devicePixelRatio() const;
238
239 RefPtr<WebKitPoint> webkitConvertPointFromPageToNode(Node*, const WebKitPoint*) const;
240 RefPtr<WebKitPoint> webkitConvertPointFromNodeToPage(Node*, const WebKitPoint*) const;
241
242 PageConsoleClient* console() const;
243
244 void printErrorMessage(const String&);
245
246 String crossDomainAccessErrorMessage(const DOMWindow& activeWindow, IncludeTargetOrigin);
247
248 ExceptionOr<void> postMessage(JSC::ExecState&, DOMWindow& incumbentWindow, JSC::JSValue message, const String& targetOrigin, Vector<JSC::Strong<JSC::JSObject>>&&);
249 void postMessageTimerFired(PostMessageTimer&);
250
251 void languagesChanged();
252
253 void scrollBy(const ScrollToOptions&) const;
254 void scrollBy(double x, double y) const;
255 void scrollTo(const ScrollToOptions&, ScrollClamping = ScrollClamping::Clamped) const;
256 void scrollTo(double x, double y, ScrollClamping = ScrollClamping::Clamped) const;
257
258 void moveBy(float x, float y) const;
259 void moveTo(float x, float y) const;
260
261 void resizeBy(float x, float y) const;
262 void resizeTo(float width, float height) const;
263
264 VisualViewport& visualViewport();
265
266 // Timers
267 ExceptionOr<int> setTimeout(JSC::ExecState&, std::unique_ptr<ScheduledAction>, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
268 void clearTimeout(int timeoutId);
269 ExceptionOr<int> setInterval(JSC::ExecState&, std::unique_ptr<ScheduledAction>, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
270 void clearInterval(int timeoutId);
271
272 int requestAnimationFrame(Ref<RequestAnimationFrameCallback>&&);
273 int webkitRequestAnimationFrame(Ref<RequestAnimationFrameCallback>&&);
274 void cancelAnimationFrame(int id);
275
276 // ImageBitmap
277 void createImageBitmap(ImageBitmap::Source&&, ImageBitmapOptions&&, ImageBitmap::Promise&&);
278 void createImageBitmap(ImageBitmap::Source&&, int sx, int sy, int sw, int sh, ImageBitmapOptions&&, ImageBitmap::Promise&&);
279
280 // Secure Contexts
281 bool isSecureContext() const;
282
283 // Events
284 // EventTarget API
285 bool addEventListener(const AtomString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) final;
286 bool removeEventListener(const AtomString& eventType, EventListener&, const ListenerOptions&) final;
287 void removeAllEventListeners() final;
288
289 using EventTarget::dispatchEvent;
290 void dispatchEvent(Event&, EventTarget*);
291
292 void dispatchLoadEvent();
293
294 void captureEvents();
295 void releaseEvents();
296
297 void finishedLoading();
298
299 // HTML 5 key/value storage
300 ExceptionOr<Storage*> sessionStorage();
301 ExceptionOr<Storage*> localStorage();
302 Storage* optionalSessionStorage() const { return m_sessionStorage.get(); }
303 Storage* optionalLocalStorage() const { return m_localStorage.get(); }
304
305 DOMApplicationCache& applicationCache();
306 DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); }
307
308 CustomElementRegistry* customElementRegistry() { return m_customElementRegistry.get(); }
309 CustomElementRegistry& ensureCustomElementRegistry();
310
311 ExceptionOr<Ref<NodeList>> collectMatchingElementsInFlatTree(Node&, const String& selectors);
312 ExceptionOr<RefPtr<Element>> matchingElementInFlatTree(Node&, const String& selectors);
313
314#if ENABLE(ORIENTATION_EVENTS)
315 // This is the interface orientation in degrees. Some examples are:
316 // 0 is straight up; -90 is when the device is rotated 90 clockwise;
317 // 90 is when rotated counter clockwise.
318 int orientation() const;
319#endif
320
321 Performance& performance() const;
322 WEBCORE_EXPORT double nowTimestamp() const;
323
324#if PLATFORM(IOS_FAMILY)
325 void incrementScrollEventListenersCount();
326 void decrementScrollEventListenersCount();
327 unsigned scrollEventListenerCount() const { return m_scrollEventListenerCount; }
328#endif
329
330#if ENABLE(DEVICE_ORIENTATION)
331 void startListeningForDeviceOrientationIfNecessary();
332 void stopListeningForDeviceOrientationIfNecessary();
333 void startListeningForDeviceMotionIfNecessary();
334 void stopListeningForDeviceMotionIfNecessary();
335
336 bool isAllowedToUseDeviceMotionOrientation(String& message) const;
337 bool isAllowedToAddDeviceMotionOrientationListener(String& message) const;
338
339 DeviceOrientationController* deviceOrientationController() const;
340 DeviceMotionController* deviceMotionController() const;
341#endif
342
343 void resetAllGeolocationPermission();
344
345#if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
346 bool hasTouchOrGestureEventListeners() const { return m_touchAndGestureEventListenerCount > 0; }
347#endif
348
349#if ENABLE(USER_MESSAGE_HANDLERS)
350 bool shouldHaveWebKitNamespaceForWorld(DOMWrapperWorld&);
351 WebKitNamespace* webkitNamespace();
352#endif
353
354 // FIXME: When this DOMWindow is no longer the active DOMWindow (i.e.,
355 // when its document is no longer the document that is displayed in its
356 // frame), we would like to zero out m_frame to avoid being confused
357 // by the document that is currently active in m_frame.
358 bool isCurrentlyDisplayedInFrame() const;
359
360 void willDetachDocumentFromFrame();
361 void willDestroyCachedFrame();
362
363 void enableSuddenTermination();
364 void disableSuddenTermination();
365
366 void willDestroyDocumentInFrame();
367 void frameDestroyed();
368
369private:
370 explicit DOMWindow(Document&);
371
372 ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
373
374 bool isLocalDOMWindow() const final { return true; }
375 bool isRemoteDOMWindow() const final { return false; }
376
377 Page* page();
378 bool allowedToChangeWindowGeometry() const;
379
380 static ExceptionOr<RefPtr<Frame>> createWindow(const String& urlString, const AtomString& frameName, const WindowFeatures&, DOMWindow& activeWindow, Frame& firstFrame, Frame& openerFrame, const WTF::Function<void(DOMWindow&)>& prepareDialogFunction = nullptr);
381 bool isInsecureScriptAccess(DOMWindow& activeWindow, const String& urlString);
382
383#if ENABLE(DEVICE_ORIENTATION)
384 void failedToRegisterDeviceMotionEventListener();
385#endif
386
387 bool isSameSecurityOriginAsMainFrame() const;
388
389#if ENABLE(GAMEPAD)
390 void incrementGamepadEventListenerCount();
391 void decrementGamepadEventListenerCount();
392#endif
393
394 bool m_shouldPrintWhenFinishedLoading { false };
395 bool m_suspendedForDocumentSuspension { false };
396 bool m_isSuspendingObservers { false };
397 Optional<bool> m_canShowModalDialogOverride;
398
399 HashSet<Observer*> m_observers;
400
401 mutable RefPtr<Crypto> m_crypto;
402 mutable RefPtr<History> m_history;
403 mutable RefPtr<BarProp> m_locationbar;
404 mutable RefPtr<StyleMedia> m_media;
405 mutable RefPtr<BarProp> m_menubar;
406 mutable RefPtr<Navigator> m_navigator;
407 mutable RefPtr<BarProp> m_personalbar;
408 mutable RefPtr<Screen> m_screen;
409 mutable RefPtr<BarProp> m_scrollbars;
410 mutable RefPtr<DOMSelection> m_selection;
411 mutable RefPtr<BarProp> m_statusbar;
412 mutable RefPtr<BarProp> m_toolbar;
413 mutable RefPtr<Location> m_location;
414 mutable RefPtr<VisualViewport> m_visualViewport;
415
416 String m_status;
417 String m_defaultStatus;
418
419 enum class PageStatus { None, Shown, Hidden };
420 PageStatus m_lastPageStatus { PageStatus::None };
421
422#if PLATFORM(IOS_FAMILY)
423 unsigned m_scrollEventListenerCount { 0 };
424#endif
425
426#if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
427 unsigned m_touchAndGestureEventListenerCount { 0 };
428#endif
429
430#if ENABLE(GAMEPAD)
431 unsigned m_gamepadEventListenerCount { 0 };
432#endif
433
434 mutable RefPtr<Storage> m_sessionStorage;
435 mutable RefPtr<Storage> m_localStorage;
436 mutable RefPtr<DOMApplicationCache> m_applicationCache;
437
438 RefPtr<CustomElementRegistry> m_customElementRegistry;
439
440 mutable RefPtr<Performance> m_performance;
441
442#if ENABLE(USER_MESSAGE_HANDLERS)
443 mutable RefPtr<WebKitNamespace> m_webkitNamespace;
444#endif
445};
446
447inline String DOMWindow::status() const
448{
449 return m_status;
450}
451
452inline String DOMWindow::defaultStatus() const
453{
454 return m_defaultStatus;
455}
456
457} // namespace WebCore
458
459SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DOMWindow)
460 static bool isType(const WebCore::AbstractDOMWindow& window) { return window.isLocalDOMWindow(); }
461 static bool isType(const WebCore::EventTarget& target) { return target.eventTargetInterface() == WebCore::DOMWindowEventTargetInterfaceType; }
462SPECIALIZE_TYPE_TRAITS_END()
463