diff options
Diffstat (limited to 'Source/WebCore/page/Chrome.cpp')
-rw-r--r-- | Source/WebCore/page/Chrome.cpp | 255 |
1 files changed, 89 insertions, 166 deletions
diff --git a/Source/WebCore/page/Chrome.cpp b/Source/WebCore/page/Chrome.cpp index 85cfd4d65..a5b00ae0b 100644 --- a/Source/WebCore/page/Chrome.cpp +++ b/Source/WebCore/page/Chrome.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2009, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2006-2017 Apple Inc. All rights reserved. * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2012, Samsung Electronics. All rights reserved. * @@ -23,14 +23,13 @@ #include "Chrome.h" #include "ChromeClient.h" -#include "DNS.h" -#include "DateTimeChooser.h" #include "Document.h" #include "DocumentType.h" #include "FileIconLoader.h" #include "FileChooser.h" #include "FileList.h" #include "FloatRect.h" +#include "FrameLoaderClient.h" #include "FrameTree.h" #include "Geolocation.h" #include "HTMLFormElement.h" @@ -45,14 +44,12 @@ #include "PopupOpeningObserver.h" #include "RenderObject.h" #include "ResourceHandle.h" -#include "SecurityOrigin.h" #include "Settings.h" #include "StorageNamespace.h" #include "WindowFeatures.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> +#include <runtime/VM.h> +#include <wtf/SetForScope.h> #include <wtf/Vector.h> -#include <wtf/text/StringBuilder.h> #if ENABLE(INPUT_TYPE_COLOR) #include "ColorChooser.h" @@ -65,10 +62,6 @@ using namespace HTMLNames; Chrome::Chrome(Page& page, ChromeClient& client) : m_page(page) , m_client(client) - , m_displayID(0) -#if PLATFORM(IOS) - , m_isDispatchViewportDataDidChangeSuppressed(false) -#endif { } @@ -77,28 +70,28 @@ Chrome::~Chrome() m_client.chromeDestroyed(); } -void Chrome::invalidateRootView(const IntRect& updateRect, bool immediate) +void Chrome::invalidateRootView(const IntRect& updateRect) { - m_client.invalidateRootView(updateRect, immediate); + m_client.invalidateRootView(updateRect); } -void Chrome::invalidateContentsAndRootView(const IntRect& updateRect, bool immediate) +void Chrome::invalidateContentsAndRootView(const IntRect& updateRect) { - m_client.invalidateContentsAndRootView(updateRect, immediate); + m_client.invalidateContentsAndRootView(updateRect); } -void Chrome::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) +void Chrome::invalidateContentsForSlowScroll(const IntRect& updateRect) { - m_client.invalidateContentsForSlowScroll(updateRect, immediate); + m_client.invalidateContentsForSlowScroll(updateRect); } void Chrome::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) { m_client.scroll(scrollDelta, rectToScroll, clipRect); - InspectorInstrumentation::didScroll(&m_page); + InspectorInstrumentation::didScroll(m_page); } -#if USE(TILED_BACKING_STORE) +#if USE(COORDINATED_GRAPHICS) void Chrome::delegatedScrollRequested(const IntPoint& scrollPoint) { m_client.delegatedScrollRequested(scrollPoint); @@ -114,20 +107,29 @@ IntRect Chrome::rootViewToScreen(const IntRect& rect) const { return m_client.rootViewToScreen(rect); } + +#if PLATFORM(IOS) -PlatformPageClient Chrome::platformPageClient() const +IntPoint Chrome::accessibilityScreenToRootView(const IntPoint& point) const { - return m_client.platformPageClient(); + return m_client.accessibilityScreenToRootView(point); } -void Chrome::contentsSizeChanged(Frame* frame, const IntSize& size) const +IntRect Chrome::rootViewToAccessibilityScreen(const IntRect& rect) const { - m_client.contentsSizeChanged(frame, size); + return m_client.rootViewToAccessibilityScreen(rect); +} + +#endif + +PlatformPageClient Chrome::platformPageClient() const +{ + return m_client.platformPageClient(); } -void Chrome::layoutUpdated(Frame* frame) const +void Chrome::contentsSizeChanged(Frame& frame, const IntSize& size) const { - m_client.layoutUpdated(frame); + m_client.contentsSizeChanged(frame, size); } void Chrome::scrollRectIntoView(const IntRect& rect) const @@ -185,14 +187,16 @@ void Chrome::focusedFrameChanged(Frame* frame) const m_client.focusedFrameChanged(frame); } -Page* Chrome::createWindow(Frame* frame, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction& action) const +Page* Chrome::createWindow(Frame& frame, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction& action) const { Page* newPage = m_client.createWindow(frame, request, features, action); if (!newPage) - return 0; + return nullptr; - if (StorageNamespace* oldSessionStorage = m_page.sessionStorage(false)) + if (auto* oldSessionStorage = m_page.sessionStorage(false)) newPage->setSessionStorage(oldSessionStorage->copy(newPage)); + if (auto* oldEphemeralLocalStorage = m_page.ephemeralLocalStorage(false)) + newPage->setEphemeralLocalStorage(oldEphemeralLocalStorage->copy(newPage)); return newPage; } @@ -207,30 +211,16 @@ bool Chrome::canRunModal() const return m_client.canRunModal(); } -static bool canRunModalIfDuringPageDismissal(Page& page, ChromeClient::DialogType dialog, const String& message) -{ - for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) { - FrameLoader::PageDismissalType dismissal = frame->loader().pageDismissalEventBeingDispatched(); - if (dismissal != FrameLoader::NoDismissal) - return page.chrome().client().shouldRunModalDialogDuringPageDismissal(dialog, message, dismissal); - } - return true; -} - -bool Chrome::canRunModalNow() const -{ - // If loads are blocked, we can't run modal because the contents - // of the modal dialog will never show up! - return canRunModal() && !ResourceHandle::loadsBlocked() - && canRunModalIfDuringPageDismissal(m_page, ChromeClient::HTMLDialog, String()); -} - void Chrome::runModal() const { // Defer callbacks in all the other pages in this group, so we don't try to run JavaScript // in a way that could interact with this view. PageGroupLoadDeferrer deferrer(m_page, false); + // JavaScript that runs within the nested event loop must not be run in the context of the + // script that called showModalDialog. Null out entryScope to break the connection. + SetForScope<JSC::VMEntryScope*> entryScopeNullifier { m_page.mainFrame().document()->vm().entryScope, nullptr }; + TimerBase::fireTimersInNestedEventLoop(); m_client.runModal(); } @@ -285,16 +275,13 @@ bool Chrome::canRunBeforeUnloadConfirmPanel() return m_client.canRunBeforeUnloadConfirmPanel(); } -bool Chrome::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) +bool Chrome::runBeforeUnloadConfirmPanel(const String& message, Frame& frame) { // Defer loads in case the client method runs a new event loop that would // otherwise cause the load to continue while we're in the middle of executing JavaScript. PageGroupLoadDeferrer deferrer(m_page, true); - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, message); - bool ok = m_client.runBeforeUnloadConfirmPanel(message, frame); - InspectorInstrumentation::didRunJavaScriptDialog(cookie); - return ok; + return m_client.runBeforeUnloadConfirmPanel(message, frame); } void Chrome::closeWindowSoon() @@ -302,93 +289,56 @@ void Chrome::closeWindowSoon() m_client.closeWindowSoon(); } -void Chrome::runJavaScriptAlert(Frame* frame, const String& message) +void Chrome::runJavaScriptAlert(Frame& frame, const String& message) { - if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::AlertDialog, message)) - return; - // Defer loads in case the client method runs a new event loop that would // otherwise cause the load to continue while we're in the middle of executing JavaScript. PageGroupLoadDeferrer deferrer(m_page, true); - ASSERT(frame); notifyPopupOpeningObservers(); - String displayMessage = frame->displayStringModifiedByEncoding(message); + String displayMessage = frame.displayStringModifiedByEncoding(message); - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, displayMessage); m_client.runJavaScriptAlert(frame, displayMessage); - InspectorInstrumentation::didRunJavaScriptDialog(cookie); } -bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message) +bool Chrome::runJavaScriptConfirm(Frame& frame, const String& message) { - if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::ConfirmDialog, message)) - return false; - // Defer loads in case the client method runs a new event loop that would // otherwise cause the load to continue while we're in the middle of executing JavaScript. PageGroupLoadDeferrer deferrer(m_page, true); - ASSERT(frame); notifyPopupOpeningObservers(); - String displayMessage = frame->displayStringModifiedByEncoding(message); - - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, displayMessage); - bool ok = m_client.runJavaScriptConfirm(frame, displayMessage); - InspectorInstrumentation::didRunJavaScriptDialog(cookie); - return ok; + return m_client.runJavaScriptConfirm(frame, frame.displayStringModifiedByEncoding(message)); } -bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultValue, String& result) +bool Chrome::runJavaScriptPrompt(Frame& frame, const String& prompt, const String& defaultValue, String& result) { - if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::PromptDialog, prompt)) - return false; - // Defer loads in case the client method runs a new event loop that would // otherwise cause the load to continue while we're in the middle of executing JavaScript. PageGroupLoadDeferrer deferrer(m_page, true); - ASSERT(frame); notifyPopupOpeningObservers(); - String displayPrompt = frame->displayStringModifiedByEncoding(prompt); - - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, displayPrompt); - bool ok = m_client.runJavaScriptPrompt(frame, displayPrompt, frame->displayStringModifiedByEncoding(defaultValue), result); - InspectorInstrumentation::didRunJavaScriptDialog(cookie); + String displayPrompt = frame.displayStringModifiedByEncoding(prompt); + bool ok = m_client.runJavaScriptPrompt(frame, displayPrompt, frame.displayStringModifiedByEncoding(defaultValue), result); if (ok) - result = frame->displayStringModifiedByEncoding(result); + result = frame.displayStringModifiedByEncoding(result); return ok; } -void Chrome::setStatusbarText(Frame* frame, const String& status) -{ - ASSERT(frame); - m_client.setStatusbarText(frame->displayStringModifiedByEncoding(status)); -} - -bool Chrome::shouldInterruptJavaScript() -{ - // Defer loads in case the client method runs a new event loop that would - // otherwise cause the load to continue while we're in the middle of executing JavaScript. - PageGroupLoadDeferrer deferrer(m_page, true); - - return m_client.shouldInterruptJavaScript(); -} - -IntRect Chrome::windowResizerRect() const +void Chrome::setStatusbarText(Frame& frame, const String& status) { - return m_client.windowResizerRect(); + m_client.setStatusbarText(frame.displayStringModifiedByEncoding(status)); } void Chrome::mouseDidMoveOverElement(const HitTestResult& result, unsigned modifierFlags) { if (result.innerNode() && result.innerNode()->document().isDNSPrefetchEnabled()) - prefetchDNS(result.absoluteLinkURL().host()); + m_page.mainFrame().loader().client().prefetchDNS(result.absoluteLinkURL().host()); m_client.mouseDidMoveOverElement(result, modifierFlags); - InspectorInstrumentation::mouseDidMoveOverElement(&m_page, result, modifierFlags); + InspectorInstrumentation::mouseDidMoveOverElement(m_page, result, modifierFlags); } void Chrome::setToolTip(const HitTestResult& result) @@ -401,10 +351,10 @@ void Chrome::setToolTip(const HitTestResult& result) if (toolTip.isEmpty() && m_page.settings().showsURLsInToolTips()) { if (Element* element = result.innerNonSharedElement()) { // Get tooltip representing form action, if relevant - if (isHTMLInputElement(element)) { - HTMLInputElement* input = toHTMLInputElement(element); - if (input->isSubmitButton()) { - if (HTMLFormElement* form = input->form()) { + if (is<HTMLInputElement>(*element)) { + HTMLInputElement& input = downcast<HTMLInputElement>(*element); + if (input.isSubmitButton()) { + if (HTMLFormElement* form = input.form()) { toolTip = form->action(); if (form->renderer()) toolTipDirection = form->renderer()->style().direction(); @@ -434,8 +384,8 @@ void Chrome::setToolTip(const HitTestResult& result) // Lastly, for <input type="file"> that allow multiple files, we'll consider a tooltip for the selected filenames if (toolTip.isEmpty()) { if (Element* element = result.innerNonSharedElement()) { - if (isHTMLInputElement(element)) { - toolTip = toHTMLInputElement(element)->defaultToolTip(); + if (is<HTMLInputElement>(*element)) { + toolTip = downcast<HTMLInputElement>(*element).defaultToolTip(); // FIXME: We should obtain text direction of tooltip from // ChromeClient or platform. As of October 2011, all client @@ -450,9 +400,9 @@ void Chrome::setToolTip(const HitTestResult& result) m_client.setToolTip(toolTip, toolTipDirection); } -void Chrome::print(Frame* frame) +void Chrome::print(Frame& frame) { - // FIXME: This should have PageGroupLoadDeferrer, like runModal() or runJavaScriptAlert(), becasue it's no different from those. + // FIXME: This should have PageGroupLoadDeferrer, like runModal() or runJavaScriptAlert(), because it's no different from those. m_client.print(frame); } @@ -466,40 +416,37 @@ void Chrome::disableSuddenTermination() m_client.disableSuddenTermination(); } -#if ENABLE(DIRECTORY_UPLOAD) -void Chrome::enumerateChosenDirectory(FileChooser* fileChooser) -{ - m_client.enumerateChosenDirectory(fileChooser); -} -#endif - #if ENABLE(INPUT_TYPE_COLOR) -PassOwnPtr<ColorChooser> Chrome::createColorChooser(ColorChooserClient* client, const Color& initialColor) + +std::unique_ptr<ColorChooser> Chrome::createColorChooser(ColorChooserClient& client, const Color& initialColor) { notifyPopupOpeningObservers(); return m_client.createColorChooser(client, initialColor); } -#endif -#if ENABLE(DATE_AND_TIME_INPUT_TYPES) && !PLATFORM(IOS) -PassRefPtr<DateTimeChooser> Chrome::openDateTimeChooser(DateTimeChooserClient* client, const DateTimeChooserParameters& parameters) -{ - notifyPopupOpeningObservers(); - return m_client.openDateTimeChooser(client, parameters); -} #endif -void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser) +void Chrome::runOpenPanel(Frame& frame, FileChooser& fileChooser) { notifyPopupOpeningObservers(); m_client.runOpenPanel(frame, fileChooser); } -void Chrome::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* loader) +void Chrome::loadIconForFiles(const Vector<String>& filenames, FileIconLoader& loader) { m_client.loadIconForFiles(filenames, loader); } +FloatSize Chrome::screenSize() const +{ + return m_client.screenSize(); +} + +FloatSize Chrome::availableScreenSize() const +{ + return m_client.availableScreenSize(); +} + void Chrome::dispatchViewportPropertiesDidChange(const ViewportArguments& arguments) const { #if PLATFORM(IOS) @@ -527,14 +474,12 @@ void Chrome::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves) #endif } -#if ENABLE(REQUEST_ANIMATION_FRAME) void Chrome::scheduleAnimation() { #if !USE(REQUEST_ANIMATION_FRAME_TIMER) m_client.scheduleAnimation(); #endif } -#endif PlatformDisplayID Chrome::displayID() const { @@ -562,19 +507,6 @@ void ChromeClient::annotatedRegionsChanged() } #endif -void ChromeClient::populateVisitedLinks() -{ -} - -FloatRect ChromeClient::customHighlightRect(Node*, const AtomicString&, const FloatRect&) -{ - return FloatRect(); -} - -void ChromeClient::paintCustomHighlight(Node*, const AtomicString&, const FloatRect&, const FloatRect&, bool, bool) -{ -} - bool ChromeClient::shouldReplaceWithGeneratedFileForUpload(const String&, String&) { return false; @@ -601,13 +533,13 @@ bool Chrome::hasOpenedPopup() const return m_client.hasOpenedPopup(); } -PassRefPtr<PopupMenu> Chrome::createPopupMenu(PopupMenuClient* client) const +RefPtr<PopupMenu> Chrome::createPopupMenu(PopupMenuClient& client) const { notifyPopupOpeningObservers(); return m_client.createPopupMenu(client); } -PassRefPtr<SearchPopupMenu> Chrome::createSearchPopupMenu(PopupMenuClient* client) const +RefPtr<SearchPopupMenu> Chrome::createSearchPopupMenu(PopupMenuClient& client) const { notifyPopupOpeningObservers(); return m_client.createSearchPopupMenu(client); @@ -618,44 +550,35 @@ bool Chrome::requiresFullscreenForVideoPlayback() return m_client.requiresFullscreenForVideoPlayback(); } -#if PLATFORM(IOS) -// FIXME: Make argument, frame, a reference. -void Chrome::didReceiveDocType(Frame* frame) +void Chrome::didReceiveDocType(Frame& frame) { - ASSERT(frame); - if (!frame->isMainFrame()) - return; - - DocumentType* documentType = frame->document()->doctype(); - if (!documentType) { - // FIXME: We should notify the client when <!DOCTYPE> is removed so that - // it can adjust the viewport accordingly. See <rdar://problem/15417894>. +#if !PLATFORM(IOS) + UNUSED_PARAM(frame); +#else + if (!frame.isMainFrame()) return; - } - if (documentType->publicId().contains("xhtml mobile", false)) - m_client.didReceiveMobileDocType(); -} + auto* doctype = frame.document()->doctype(); + m_client.didReceiveMobileDocType(doctype && doctype->publicId().containsIgnoringASCIICase("xhtml mobile")); #endif +} -void Chrome::registerPopupOpeningObserver(PopupOpeningObserver* observer) +void Chrome::registerPopupOpeningObserver(PopupOpeningObserver& observer) { - ASSERT(observer); - m_popupOpeningObservers.append(observer); + m_popupOpeningObservers.append(&observer); } -void Chrome::unregisterPopupOpeningObserver(PopupOpeningObserver* observer) +void Chrome::unregisterPopupOpeningObserver(PopupOpeningObserver& observer) { - size_t index = m_popupOpeningObservers.find(observer); - ASSERT(index != notFound); - m_popupOpeningObservers.remove(index); + bool removed = m_popupOpeningObservers.removeFirst(&observer); + ASSERT_UNUSED(removed, removed); } void Chrome::notifyPopupOpeningObservers() const { const Vector<PopupOpeningObserver*> observers(m_popupOpeningObservers); - for (size_t i = 0; i < observers.size(); ++i) - observers[i]->willOpenPopup(); + for (auto& observer : observers) + observer->willOpenPopup(); } } // namespace WebCore |