/* * Copyright (C) 2006-2017 Apple Inc. All rights reserved. * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include "Base64Utilities.h" #include "ContextDestructionObserver.h" #include "EventTarget.h" #include "ExceptionOr.h" #include "FrameDestructionObserver.h" #include "ScrollToOptions.h" #include "Supplementable.h" #include #include namespace JSC { class ExecState; class JSObject; class JSValue; template class Strong; } namespace WebCore { class BarProp; class CSSRuleList; class CSSStyleDeclaration; class Crypto; class CustomElementRegistry; class DOMApplicationCache; class DOMSelection; class DOMWindowProperty; class DOMWrapperWorld; class Document; class Element; class EventListener; class FloatRect; class History; class Location; class MediaQueryList; class Navigator; class Node; class NodeList; class Page; class PageConsoleClient; class Performance; class PostMessageTimer; class RequestAnimationFrameCallback; class ScheduledAction; class Screen; class Storage; class StyleMedia; class WebKitNamespace; class WebKitPoint; struct WindowFeatures; enum SetLocationLocking { LockHistoryBasedOnGestureState, LockHistoryAndBackForwardList }; // FIXME: DOMWindow shouldn't subclass FrameDestructionObserver and instead should get to Frame via its Document. class DOMWindow final : public RefCounted , public EventTargetWithInlineData , public ContextDestructionObserver , public FrameDestructionObserver , public Base64Utilities , public Supplementable { public: static Ref create(Document& document) { return adoptRef(*new DOMWindow(document)); } WEBCORE_EXPORT virtual ~DOMWindow(); // In some rare cases, we'll reuse a DOMWindow for a new Document. For example, // when a script calls window.open("..."), the browser gives JavaScript a window // synchronously but kicks off the load in the window asynchronously. Web sites // expect that modifications that they make to the window object synchronously // won't be blown away when the network load commits. To make that happen, we // "securely transition" the existing DOMWindow to the Document that results from // the network load. See also SecurityContext::isSecureTransitionTo. void didSecureTransitionTo(Document&); void registerProperty(DOMWindowProperty&); void unregisterProperty(DOMWindowProperty&); void resetUnlessSuspendedForDocumentSuspension(); void suspendForDocumentSuspension(); void resumeFromDocumentSuspension(); RefPtr matchMedia(const String&); WEBCORE_EXPORT unsigned pendingUnloadEventListeners() const; WEBCORE_EXPORT static bool dispatchAllPendingBeforeUnloadEvents(); WEBCORE_EXPORT static void dispatchAllPendingUnloadEvents(); static FloatRect adjustWindowRect(Page&, const FloatRect& pendingChanges); bool allowPopUp(); // Call on first window, not target window. static bool allowPopUp(Frame& firstFrame); static bool canShowModalDialog(const Frame&); WEBCORE_EXPORT void setCanShowModalDialogOverride(bool); Screen* screen() const; History* history() const; Crypto* crypto() const; BarProp* locationbar() const; BarProp* menubar() const; BarProp* personalbar() const; BarProp* scrollbars() const; BarProp* statusbar() const; BarProp* toolbar() const; Navigator* navigator() const; Navigator* clientInformation() const { return navigator(); } Location* location() const; void setLocation(DOMWindow& activeWindow, DOMWindow& firstWindow, const String& location, SetLocationLocking = LockHistoryBasedOnGestureState); DOMSelection* getSelection(); Element* frameElement() const; WEBCORE_EXPORT void focus(bool allowFocus = false); void focus(DOMWindow& callerWindow); void blur(); WEBCORE_EXPORT void close(); void close(Document&); void print(); void stop(); WEBCORE_EXPORT RefPtr open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString, DOMWindow& activeWindow, DOMWindow& firstWindow); void showModalDialog(const String& urlString, const String& dialogFeaturesString, DOMWindow& activeWindow, DOMWindow& firstWindow, std::function prepareDialogFunction); void alert(const String& message = emptyString()); bool confirm(const String& message); String prompt(const String& message, const String& defaultValue); bool find(const String&, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const; bool offscreenBuffering() const; int outerHeight() const; int outerWidth() const; int innerHeight() const; int innerWidth() const; int screenX() const; int screenY() const; int screenLeft() const { return screenX(); } int screenTop() const { return screenY(); } int scrollX() const; int scrollY() const; bool closed() const; unsigned length() const; String name() const; void setName(const String&); String status() const; void setStatus(const String&); String defaultStatus() const; void setDefaultStatus(const String&); // Self-referential attributes DOMWindow* self() const; DOMWindow* window() const { return self(); } DOMWindow* frames() const { return self(); } DOMWindow* opener() const; DOMWindow* parent() const; DOMWindow* top() const; // DOM Level 2 AbstractView Interface WEBCORE_EXPORT Document* document() const; // CSSOM View Module RefPtr styleMedia() const; // DOM Level 2 Style Interface WEBCORE_EXPORT Ref getComputedStyle(Element&, const String& pseudoElt) const; // WebKit extensions WEBCORE_EXPORT RefPtr getMatchedCSSRules(Element*, const String& pseudoElt, bool authorOnly = true) const; double devicePixelRatio() const; RefPtr webkitConvertPointFromPageToNode(Node*, const WebKitPoint*) const; RefPtr webkitConvertPointFromNodeToPage(Node*, const WebKitPoint*) const; PageConsoleClient* console() const; void printErrorMessage(const String&); String crossDomainAccessErrorMessage(const DOMWindow& activeWindow); ExceptionOr postMessage(JSC::ExecState&, DOMWindow& callerWindow, JSC::JSValue message, const String& targetOrigin, Vector>&&); void postMessageTimerFired(PostMessageTimer&); void languagesChanged(); void scrollBy(const ScrollToOptions&) const; void scrollBy(double x, double y) const; void scrollTo(const ScrollToOptions&) const; void scrollTo(double x, double y) const; void moveBy(float x, float y) const; void moveTo(float x, float y) const; void resizeBy(float x, float y) const; void resizeTo(float width, float height) const; // Timers ExceptionOr setTimeout(std::unique_ptr, int timeout); void clearTimeout(int timeoutId); ExceptionOr setInterval(std::unique_ptr, int timeout); void clearInterval(int timeoutId); int requestAnimationFrame(Ref&&); int webkitRequestAnimationFrame(Ref&&); void cancelAnimationFrame(int id); // Events // EventTarget API bool addEventListener(const AtomicString& eventType, Ref&&, const AddEventListenerOptions&) final; bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) final; void removeAllEventListeners() final; using EventTarget::dispatchEvent; bool dispatchEvent(Event&, EventTarget*); void dispatchLoadEvent(); void captureEvents(); void releaseEvents(); void finishedLoading(); using RefCounted::ref; using RefCounted::deref; // HTML 5 key/value storage ExceptionOr sessionStorage() const; ExceptionOr localStorage() const; Storage* optionalSessionStorage() const { return m_sessionStorage.get(); } Storage* optionalLocalStorage() const { return m_localStorage.get(); } DOMApplicationCache* applicationCache() const; DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); } CustomElementRegistry* customElementRegistry() { return m_customElementRegistry.get(); } CustomElementRegistry& ensureCustomElementRegistry(); ExceptionOr> collectMatchingElementsInFlatTree(Node&, const String& selectors); ExceptionOr> matchingElementInFlatTree(Node&, const String& selectors); #if ENABLE(ORIENTATION_EVENTS) // This is the interface orientation in degrees. Some examples are: // 0 is straight up; -90 is when the device is rotated 90 clockwise; // 90 is when rotated counter clockwise. int orientation() const; #endif #if ENABLE(WEB_TIMING) Performance* performance() const; #endif double nowTimestamp() const; #if PLATFORM(IOS) void incrementScrollEventListenersCount(); void decrementScrollEventListenersCount(); unsigned scrollEventListenerCount() const { return m_scrollEventListenerCount; } #endif void resetAllGeolocationPermission(); #if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS) bool hasTouchEventListeners() const { return m_touchEventListenerCount > 0; } #endif #if ENABLE(USER_MESSAGE_HANDLERS) bool shouldHaveWebKitNamespaceForWorld(DOMWrapperWorld&); WebKitNamespace* webkitNamespace() const; #endif // FIXME: When this DOMWindow is no longer the active DOMWindow (i.e., // when its document is no longer the document that is displayed in its // frame), we would like to zero out m_frame to avoid being confused // by the document that is currently active in m_frame. bool isCurrentlyDisplayedInFrame() const; void willDetachDocumentFromFrame(); void willDestroyCachedFrame(); void enableSuddenTermination(); void disableSuddenTermination(); WeakPtr createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); } private: explicit DOMWindow(Document&); EventTargetInterface eventTargetInterface() const final { return DOMWindowEventTargetInterfaceType; } ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); } DOMWindow* toDOMWindow() final; Page* page(); bool allowedToChangeWindowGeometry() const; void frameDestroyed() final; void willDetachPage() final; void refEventTarget() final { ref(); } void derefEventTarget() final { deref(); } static RefPtr createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&, DOMWindow& activeWindow, Frame& firstFrame, Frame& openerFrame, std::function prepareDialogFunction = nullptr); bool isInsecureScriptAccess(DOMWindow& activeWindow, const String& urlString); void resetDOMWindowProperties(); void disconnectDOMWindowProperties(); void reconnectDOMWindowProperties(); void willDestroyDocumentInFrame(); bool isSameSecurityOriginAsMainFrame() const; #if ENABLE(GAMEPAD) void incrementGamepadEventListenerCount(); void decrementGamepadEventListenerCount(); #endif bool m_shouldPrintWhenFinishedLoading { false }; bool m_suspendedForDocumentSuspension { false }; std::optional m_canShowModalDialogOverride; HashSet m_properties; mutable RefPtr m_crypto; mutable RefPtr m_history; mutable RefPtr m_locationbar; mutable RefPtr m_media; mutable RefPtr m_menubar; mutable RefPtr m_navigator; mutable RefPtr m_personalbar; mutable RefPtr m_screen; mutable RefPtr m_scrollbars; mutable RefPtr m_selection; mutable RefPtr m_statusbar; mutable RefPtr m_toolbar; mutable RefPtr m_location; String m_status; String m_defaultStatus; enum class PageStatus { None, Shown, Hidden }; PageStatus m_lastPageStatus { PageStatus::None }; WeakPtrFactory m_weakPtrFactory; #if PLATFORM(IOS) unsigned m_scrollEventListenerCount { 0 }; #endif #if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS) unsigned m_touchEventListenerCount { 0 }; #endif #if ENABLE(GAMEPAD) unsigned m_gamepadEventListenerCount { 0 }; #endif mutable RefPtr m_sessionStorage; mutable RefPtr m_localStorage; mutable RefPtr m_applicationCache; RefPtr m_customElementRegistry; #if ENABLE(WEB_TIMING) mutable RefPtr m_performance; #endif #if ENABLE(USER_MESSAGE_HANDLERS) mutable RefPtr m_webkitNamespace; #endif }; inline String DOMWindow::status() const { return m_status; } inline String DOMWindow::defaultStatus() const { return m_defaultStatus; } } // namespace WebCore