summaryrefslogtreecommitdiff
path: root/Source/WebKit2/WebProcess/WebPage
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/WebProcess/WebPage')
-rw-r--r--Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.cpp452
-rw-r--r--Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.h133
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/AreaAllocator.cpp328
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/AreaAllocator.h115
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp443
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.h170
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp239
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h92
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.messages.in28
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp252
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h125
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/UpdateAtlas.cpp116
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/UpdateAtlas.h83
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp136
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp36
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingArea.h113
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in21
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp438
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h105
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp114
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp142
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EventDispatcher.h44
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in6
-rw-r--r--Source/WebKit2/WebProcess/WebPage/FindController.cpp323
-rw-r--r--Source/WebKit2/WebProcess/WebPage/FindController.h43
-rw-r--r--Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp56
-rw-r--r--Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h80
-rw-r--r--Source/WebKit2/WebProcess/WebPage/PageBanner.cpp2
-rw-r--r--Source/WebKit2/WebProcess/WebPage/PageBanner.h13
-rw-r--r--Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp199
-rw-r--r--Source/WebKit2/WebProcess/WebPage/PageOverlay.h111
-rw-r--r--Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.cpp152
-rw-r--r--Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.h89
-rw-r--r--Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.messages.in (renamed from Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.messages.in)15
-rw-r--r--Source/WebKit2/WebProcess/WebPage/TapHighlightController.cpp119
-rw-r--r--Source/WebKit2/WebProcess/WebPage/TapHighlightController.h73
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.cpp147
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.h75
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.messages.in12
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.cpp92
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.h66
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.messages.in25
-rw-r--r--Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.cpp120
-rw-r--r--Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.h62
-rw-r--r--Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.messages.in28
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WKAccessibilityWebPageObjectIOS.h (renamed from Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h)42
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp87
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h26
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp33
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebContextMenu.h11
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.cpp12
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.h6
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebFrame.cpp304
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebFrame.h58
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspector.cpp350
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspector.h116
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in33
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspectorFrontendAPIDispatcher.cpp118
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspectorFrontendAPIDispatcher.h (renamed from Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h)48
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspectorUI.cpp308
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspectorUI.h136
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspectorUI.messages.in49
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp13
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h9
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPage.cpp3549
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPage.h1034
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPage.messages.in319
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp45
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h18
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPageOverlay.cpp149
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPageOverlay.h107
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp8
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebUndoStep.h3
-rw-r--r--Source/WebKit2/WebProcess/WebPage/atk/WebPageAccessibilityObjectAtk.cpp7
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp59
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurface.cpp75
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurface.h53
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceWayland.cpp117
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceWayland.h57
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp154
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.h65
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp372
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.h101
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.cpp23
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.h11
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorUIGtk.cpp (renamed from Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp)16
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp99
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp30
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.h2
89 files changed, 10129 insertions, 3736 deletions
diff --git a/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.cpp
new file mode 100644
index 000000000..a249fed5f
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.cpp
@@ -0,0 +1,452 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "AcceleratedDrawingArea.h"
+
+#include "DrawingAreaProxyMessages.h"
+#include "LayerTreeHost.h"
+#include "UpdateInfo.h"
+#include "WebPage.h"
+#include "WebPageCreationParameters.h"
+#include "WebPreferencesKeys.h"
+#include <WebCore/MainFrame.h>
+#include <WebCore/Page.h>
+#include <WebCore/PageOverlayController.h>
+#include <WebCore/Settings.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+AcceleratedDrawingArea::~AcceleratedDrawingArea()
+{
+ discardPreviousLayerTreeHost();
+ if (m_layerTreeHost)
+ m_layerTreeHost->invalidate();
+}
+
+AcceleratedDrawingArea::AcceleratedDrawingArea(WebPage& webPage, const WebPageCreationParameters& parameters)
+ : DrawingArea(DrawingAreaTypeImpl, webPage)
+ , m_exitCompositingTimer(RunLoop::main(), this, &AcceleratedDrawingArea::exitAcceleratedCompositingMode)
+ , m_discardPreviousLayerTreeHostTimer(RunLoop::main(), this, &AcceleratedDrawingArea::discardPreviousLayerTreeHost)
+{
+ if (!m_webPage.isVisible())
+ suspendPainting();
+}
+
+void AcceleratedDrawingArea::setNeedsDisplay()
+{
+ if (!m_isPaintingEnabled)
+ return;
+
+ if (m_layerTreeHost)
+ m_layerTreeHost->setNonCompositedContentsNeedDisplay();
+}
+
+void AcceleratedDrawingArea::setNeedsDisplayInRect(const IntRect& rect)
+{
+ if (!m_isPaintingEnabled)
+ return;
+
+ if (m_layerTreeHost)
+ m_layerTreeHost->setNonCompositedContentsNeedDisplayInRect(rect);
+}
+
+void AcceleratedDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta)
+{
+ if (!m_isPaintingEnabled)
+ return;
+
+ if (m_layerTreeHost)
+ m_layerTreeHost->scrollNonCompositedContents(scrollRect);
+}
+
+void AcceleratedDrawingArea::pageBackgroundTransparencyChanged()
+{
+ if (m_layerTreeHost)
+ m_layerTreeHost->pageBackgroundTransparencyChanged();
+ else if (m_previousLayerTreeHost)
+ m_previousLayerTreeHost->pageBackgroundTransparencyChanged();
+}
+
+void AcceleratedDrawingArea::setLayerTreeStateIsFrozen(bool isFrozen)
+{
+ if (m_layerTreeStateIsFrozen == isFrozen)
+ return;
+
+ m_layerTreeStateIsFrozen = isFrozen;
+
+ if (m_layerTreeHost)
+ m_layerTreeHost->setLayerFlushSchedulingEnabled(!isFrozen);
+
+ if (isFrozen)
+ m_exitCompositingTimer.stop();
+ else if (m_wantsToExitAcceleratedCompositingMode)
+ exitAcceleratedCompositingModeSoon();
+}
+
+void AcceleratedDrawingArea::forceRepaint()
+{
+ setNeedsDisplay();
+
+ m_webPage.layoutIfNeeded();
+
+ if (!m_layerTreeHost)
+ return;
+
+ // FIXME: We need to do the same work as the layerHostDidFlushLayers function here,
+ // but clearly it doesn't make sense to call the function with that name.
+ // Consider refactoring and renaming it.
+ if (m_compositingAccordingToProxyMessages)
+ m_layerTreeHost->forceRepaint();
+ else {
+ // Call setShouldNotifyAfterNextScheduledLayerFlush(false) here to
+ // prevent layerHostDidFlushLayers() from being called a second time.
+ m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false);
+ layerHostDidFlushLayers();
+ }
+}
+
+bool AcceleratedDrawingArea::forceRepaintAsync(uint64_t callbackID)
+{
+ return m_layerTreeHost && m_layerTreeHost->forceRepaintAsync(callbackID);
+}
+
+void AcceleratedDrawingArea::setPaintingEnabled(bool paintingEnabled)
+{
+ m_isPaintingEnabled = paintingEnabled;
+}
+
+void AcceleratedDrawingArea::updatePreferences(const WebPreferencesStore& store)
+{
+ m_webPage.corePage()->settings().setForceCompositingMode(store.getBoolValueForKey(WebPreferencesKey::forceCompositingModeKey()));
+ if (!m_layerTreeHost)
+ enterAcceleratedCompositingMode(nullptr);
+}
+
+void AcceleratedDrawingArea::mainFrameContentSizeChanged(const IntSize& size)
+{
+ if (m_webPage.useFixedLayout()) {
+ if (m_layerTreeHost)
+ m_layerTreeHost->sizeDidChange(size);
+ else if (m_previousLayerTreeHost)
+ m_previousLayerTreeHost->sizeDidChange(size);
+ }
+ m_webPage.mainFrame()->pageOverlayController().didChangeDocumentSize();
+}
+
+void AcceleratedDrawingArea::layerHostDidFlushLayers()
+{
+ ASSERT(m_layerTreeHost);
+ m_layerTreeHost->forceRepaint();
+
+ if (m_shouldSendDidUpdateBackingStoreState && !exitAcceleratedCompositingModePending()) {
+ sendDidUpdateBackingStoreState();
+ return;
+ }
+
+ ASSERT(!m_compositingAccordingToProxyMessages);
+ if (!exitAcceleratedCompositingModePending()) {
+ m_webPage.send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(m_backingStoreStateID, m_layerTreeHost->layerTreeContext()));
+ m_compositingAccordingToProxyMessages = true;
+ }
+}
+
+GraphicsLayerFactory* AcceleratedDrawingArea::graphicsLayerFactory()
+{
+ if (!m_layerTreeHost)
+ enterAcceleratedCompositingMode(nullptr);
+ return m_layerTreeHost ? m_layerTreeHost->graphicsLayerFactory() : nullptr;
+}
+
+void AcceleratedDrawingArea::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
+{
+ ASSERT(m_layerTreeHost);
+
+ // FIXME: Instead of using nested if statements, we should keep a compositing state
+ // enum in the AcceleratedDrawingArea object and have a changeAcceleratedCompositingState function
+ // that takes the new state.
+
+ if (graphicsLayer) {
+ // We're already in accelerated compositing mode, but the root compositing layer changed.
+
+ m_exitCompositingTimer.stop();
+ m_wantsToExitAcceleratedCompositingMode = false;
+
+ // If we haven't sent the EnterAcceleratedCompositingMode message, make sure that the
+ // layer tree host calls us back after the next layer flush so we can send it then.
+ if (!m_compositingAccordingToProxyMessages)
+ m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true);
+ }
+ m_layerTreeHost->setRootCompositingLayer(graphicsLayer);
+}
+
+void AcceleratedDrawingArea::scheduleCompositingLayerFlush()
+{
+ if (m_layerTreeHost)
+ m_layerTreeHost->scheduleLayerFlush();
+}
+
+void AcceleratedDrawingArea::scheduleCompositingLayerFlushImmediately()
+{
+ scheduleCompositingLayerFlush();
+}
+
+void AcceleratedDrawingArea::updateBackingStoreState(uint64_t stateID, bool respondImmediately, float deviceScaleFactor, const IntSize& size, const IntSize& scrollOffset)
+{
+ ASSERT(!m_inUpdateBackingStoreState);
+ m_inUpdateBackingStoreState = true;
+
+ ASSERT_ARG(stateID, stateID >= m_backingStoreStateID);
+ if (stateID != m_backingStoreStateID) {
+ m_backingStoreStateID = stateID;
+ m_shouldSendDidUpdateBackingStoreState = true;
+
+ m_webPage.setDeviceScaleFactor(deviceScaleFactor);
+ m_webPage.setSize(size);
+ m_webPage.layoutIfNeeded();
+ m_webPage.scrollMainFrameIfNotAtMaxScrollPosition(scrollOffset);
+
+ if (m_layerTreeHost)
+ m_layerTreeHost->sizeDidChange(m_webPage.size());
+ else if (m_previousLayerTreeHost)
+ m_previousLayerTreeHost->sizeDidChange(m_webPage.size());
+ } else {
+ ASSERT(size == m_webPage.size());
+ if (!m_shouldSendDidUpdateBackingStoreState) {
+ // We've already sent a DidUpdateBackingStoreState message for this state. We have nothing more to do.
+ m_inUpdateBackingStoreState = false;
+ return;
+ }
+ }
+
+ didUpdateBackingStoreState();
+
+ if (respondImmediately) {
+ // Make sure to resume painting if we're supposed to respond immediately, otherwise we'll just
+ // send back an empty UpdateInfo struct.
+ if (m_isPaintingSuspended)
+ resumePainting();
+
+ sendDidUpdateBackingStoreState();
+ }
+
+ m_inUpdateBackingStoreState = false;
+}
+
+void AcceleratedDrawingArea::sendDidUpdateBackingStoreState()
+{
+ ASSERT(m_shouldSendDidUpdateBackingStoreState);
+
+ m_shouldSendDidUpdateBackingStoreState = false;
+
+ UpdateInfo updateInfo;
+ updateInfo.viewSize = m_webPage.size();
+ updateInfo.deviceScaleFactor = m_webPage.corePage()->deviceScaleFactor();
+
+ LayerTreeContext layerTreeContext;
+ if (m_layerTreeHost) {
+ layerTreeContext = m_layerTreeHost->layerTreeContext();
+
+ // We don't want the layer tree host to notify after the next scheduled
+ // layer flush because that might end up sending an EnterAcceleratedCompositingMode
+ // message back to the UI process, but the updated layer tree context
+ // will be sent back in the DidUpdateBackingStoreState message.
+ m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false);
+ m_layerTreeHost->forceRepaint();
+ }
+
+ m_webPage.send(Messages::DrawingAreaProxy::DidUpdateBackingStoreState(m_backingStoreStateID, updateInfo, layerTreeContext));
+ m_compositingAccordingToProxyMessages = !layerTreeContext.isEmpty();
+}
+
+void AcceleratedDrawingArea::suspendPainting()
+{
+ ASSERT(!m_isPaintingSuspended);
+
+ if (m_layerTreeHost)
+ m_layerTreeHost->pauseRendering();
+
+ m_isPaintingSuspended = true;
+
+ m_webPage.corePage()->suspendScriptedAnimations();
+}
+
+void AcceleratedDrawingArea::resumePainting()
+{
+ if (!m_isPaintingSuspended) {
+ // FIXME: We can get a call to resumePainting when painting is not suspended.
+ // This happens when sending a synchronous message to create a new page. See <rdar://problem/8976531>.
+ return;
+ }
+
+ if (m_layerTreeHost)
+ m_layerTreeHost->resumeRendering();
+
+ m_isPaintingSuspended = false;
+
+ // FIXME: We shouldn't always repaint everything here.
+ setNeedsDisplay();
+
+ m_webPage.corePage()->resumeScriptedAnimations();
+}
+
+void AcceleratedDrawingArea::enterAcceleratedCompositingMode(GraphicsLayer* graphicsLayer)
+{
+ m_discardPreviousLayerTreeHostTimer.stop();
+
+ m_exitCompositingTimer.stop();
+ m_wantsToExitAcceleratedCompositingMode = false;
+
+ ASSERT(!m_layerTreeHost);
+ if (m_previousLayerTreeHost) {
+#if USE(COORDINATED_GRAPHICS)
+ m_layerTreeHost = WTFMove(m_previousLayerTreeHost);
+ m_layerTreeHost->setIsDiscardable(false);
+ if (!m_isPaintingSuspended)
+ m_layerTreeHost->resumeRendering();
+ if (!m_layerTreeStateIsFrozen)
+ m_layerTreeHost->setLayerFlushSchedulingEnabled(true);
+#else
+ ASSERT_NOT_REACHED();
+#endif
+ } else {
+ m_layerTreeHost = LayerTreeHost::create(m_webPage);
+
+ if (m_isPaintingSuspended)
+ m_layerTreeHost->pauseRendering();
+ }
+
+#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+ if (m_nativeSurfaceHandleForCompositing)
+ m_layerTreeHost->setNativeSurfaceHandleForCompositing(m_nativeSurfaceHandleForCompositing);
+#endif
+ if (!m_inUpdateBackingStoreState)
+ m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true);
+
+ m_layerTreeHost->setRootCompositingLayer(graphicsLayer);
+}
+
+void AcceleratedDrawingArea::exitAcceleratedCompositingModeSoon()
+{
+ if (m_layerTreeStateIsFrozen) {
+ m_wantsToExitAcceleratedCompositingMode = true;
+ return;
+ }
+
+ if (exitAcceleratedCompositingModePending())
+ return;
+
+ m_exitCompositingTimer.startOneShot(0);
+}
+
+void AcceleratedDrawingArea::exitAcceleratedCompositingModeNow()
+{
+ ASSERT(!m_layerTreeStateIsFrozen);
+
+ m_exitCompositingTimer.stop();
+ m_wantsToExitAcceleratedCompositingMode = false;
+
+#if USE(COORDINATED_GRAPHICS)
+ ASSERT(m_layerTreeHost);
+ m_previousLayerTreeHost = WTFMove(m_layerTreeHost);
+ m_previousLayerTreeHost->setIsDiscardable(true);
+ m_previousLayerTreeHost->pauseRendering();
+ m_previousLayerTreeHost->setLayerFlushSchedulingEnabled(false);
+ m_discardPreviousLayerTreeHostTimer.startOneShot(5);
+#else
+ m_layerTreeHost = nullptr;
+#endif
+}
+
+void AcceleratedDrawingArea::discardPreviousLayerTreeHost()
+{
+ m_discardPreviousLayerTreeHostTimer.stop();
+ if (!m_previousLayerTreeHost)
+ return;
+
+ m_previousLayerTreeHost->invalidate();
+ m_previousLayerTreeHost = nullptr;
+}
+
+#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+void AcceleratedDrawingArea::setNativeSurfaceHandleForCompositing(uint64_t handle)
+{
+ m_nativeSurfaceHandleForCompositing = handle;
+ if (m_layerTreeHost) {
+ m_webPage.corePage()->settings().setAcceleratedCompositingEnabled(true);
+ m_layerTreeHost->setNativeSurfaceHandleForCompositing(handle);
+ }
+}
+
+void AcceleratedDrawingArea::destroyNativeSurfaceHandleForCompositing(bool& handled)
+{
+ handled = true;
+ setNativeSurfaceHandleForCompositing(0);
+}
+#endif
+
+#if USE(COORDINATED_GRAPHICS_THREADED)
+void AcceleratedDrawingArea::didChangeViewportAttributes(ViewportAttributes&& attrs)
+{
+ if (m_layerTreeHost)
+ m_layerTreeHost->didChangeViewportAttributes(WTFMove(attrs));
+ else if (m_previousLayerTreeHost)
+ m_previousLayerTreeHost->didChangeViewportAttributes(WTFMove(attrs));
+}
+#endif
+
+#if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
+void AcceleratedDrawingArea::deviceOrPageScaleFactorChanged()
+{
+ if (m_layerTreeHost)
+ m_layerTreeHost->deviceOrPageScaleFactorChanged();
+ else if (m_previousLayerTreeHost)
+ m_previousLayerTreeHost->deviceOrPageScaleFactorChanged();
+}
+#endif
+
+void AcceleratedDrawingArea::activityStateDidChange(ActivityState::Flags changed, bool, const Vector<uint64_t>&)
+{
+ if (changed & ActivityState::IsVisible) {
+ if (m_webPage.isVisible())
+ resumePainting();
+ else
+ suspendPainting();
+ }
+}
+
+void AcceleratedDrawingArea::attachViewOverlayGraphicsLayer(Frame* frame, GraphicsLayer* viewOverlayRootLayer)
+{
+ if (!frame->isMainFrame())
+ return;
+
+ if (m_layerTreeHost)
+ m_layerTreeHost->setViewOverlayRootLayer(viewOverlayRootLayer);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.h
new file mode 100644
index 000000000..ead32ab6d
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/AcceleratedDrawingArea.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 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. AND ITS CONTRIBUTORS ``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 ITS 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 "DrawingArea.h"
+#include <wtf/RunLoop.h>
+
+namespace WebKit {
+
+class LayerTreeHost;
+
+class AcceleratedDrawingArea : public DrawingArea {
+public:
+ AcceleratedDrawingArea(WebPage&, const WebPageCreationParameters&);
+ virtual ~AcceleratedDrawingArea();
+
+protected:
+ // DrawingArea
+ void setNeedsDisplay() override;
+ void setNeedsDisplayInRect(const WebCore::IntRect&) override;
+ void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta) override;
+ void pageBackgroundTransparencyChanged() override;
+ void setLayerTreeStateIsFrozen(bool) override;
+ bool layerTreeStateIsFrozen() const override { return m_layerTreeStateIsFrozen; }
+ LayerTreeHost* layerTreeHost() const override { return m_layerTreeHost.get(); }
+ void forceRepaint() override;
+ bool forceRepaintAsync(uint64_t callbackID) override;
+
+ void setPaintingEnabled(bool) override;
+ void updatePreferences(const WebPreferencesStore&) override;
+ void mainFrameContentSizeChanged(const WebCore::IntSize&) override;
+
+ WebCore::GraphicsLayerFactory* graphicsLayerFactory() override;
+ void setRootCompositingLayer(WebCore::GraphicsLayer*) override;
+ void scheduleCompositingLayerFlush() override;
+ void scheduleCompositingLayerFlushImmediately() override;
+
+#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+ void setNativeSurfaceHandleForCompositing(uint64_t) override;
+ void destroyNativeSurfaceHandleForCompositing(bool&) override;
+#endif
+
+ void activityStateDidChange(WebCore::ActivityState::Flags, bool /* wantsDidUpdateActivityState */, const Vector<uint64_t>& /* callbackIDs */) override;
+ void attachViewOverlayGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*) override;
+
+ void layerHostDidFlushLayers() override;
+
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ void didChangeViewportAttributes(WebCore::ViewportAttributes&&) override;
+#endif
+
+#if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
+ void deviceOrPageScaleFactorChanged() override;
+#endif
+
+ // IPC message handlers.
+ void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, float deviceScaleFactor, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset) override;
+
+ void exitAcceleratedCompositingModeSoon();
+ bool exitAcceleratedCompositingModePending() const { return m_exitCompositingTimer.isActive(); }
+ void exitAcceleratedCompositingModeNow();
+ void discardPreviousLayerTreeHost();
+
+ virtual void suspendPainting();
+ virtual void resumePainting();
+
+ virtual void sendDidUpdateBackingStoreState();
+ virtual void didUpdateBackingStoreState() { }
+
+ virtual void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*);
+ virtual void exitAcceleratedCompositingMode() { }
+
+ uint64_t m_backingStoreStateID { 0 };
+
+ // Whether painting is enabled. If painting is disabled, any calls to setNeedsDisplay and scroll are ignored.
+ bool m_isPaintingEnabled { true };
+
+ // Whether we're currently processing an UpdateBackingStoreState message.
+ bool m_inUpdateBackingStoreState { false };
+
+ // When true, we should send an UpdateBackingStoreState message instead of any other messages
+ // we normally send to the UI process.
+ bool m_shouldSendDidUpdateBackingStoreState { false };
+
+ // True between sending the 'enter compositing' messages, and the 'exit compositing' message.
+ bool m_compositingAccordingToProxyMessages { false };
+
+ // When true, we maintain the layer tree in its current state by not leaving accelerated compositing mode
+ // and not scheduling layer flushes.
+ bool m_layerTreeStateIsFrozen { false };
+
+ // True when we were asked to exit accelerated compositing mode but couldn't because layer tree
+ // state was frozen.
+ bool m_wantsToExitAcceleratedCompositingMode { false };
+
+ // Whether painting is suspended. We'll still keep track of the dirty region but we
+ // won't paint until painting has resumed again.
+ bool m_isPaintingSuspended { false };
+
+ RunLoop::Timer<AcceleratedDrawingArea> m_exitCompositingTimer;
+
+ // The layer tree host that handles accelerated compositing.
+ RefPtr<LayerTreeHost> m_layerTreeHost;
+
+ RefPtr<LayerTreeHost> m_previousLayerTreeHost;
+ RunLoop::Timer<AcceleratedDrawingArea> m_discardPreviousLayerTreeHostTimer;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/AreaAllocator.cpp b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/AreaAllocator.cpp
new file mode 100644
index 000000000..a9ece1290
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/AreaAllocator.cpp
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "AreaAllocator.h"
+
+#if USE(COORDINATED_GRAPHICS)
+
+using namespace WebCore;
+
+namespace WebKit {
+
+AreaAllocator::AreaAllocator(const IntSize& size)
+ : m_size(size)
+ , m_minAlloc(1, 1)
+ , m_margin(0, 0)
+{
+}
+
+AreaAllocator::~AreaAllocator()
+{
+}
+
+void AreaAllocator::expand(const IntSize& size)
+{
+ m_size = m_size.expandedTo(size);
+}
+
+void AreaAllocator::expandBy(const IntSize& size)
+{
+ m_size += size;
+}
+
+void AreaAllocator::release(const IntRect&)
+{
+}
+
+int AreaAllocator::overhead() const
+{
+ return 0;
+}
+
+IntSize AreaAllocator::roundAllocation(const IntSize& size) const
+{
+ int width = size.width() + m_margin.width();
+ int height = size.height() + m_margin.height();
+ int extra = width % m_minAlloc.width();
+ if (extra)
+ width += m_minAlloc.width() - extra;
+ extra = height % m_minAlloc.height();
+ if (extra)
+ height += m_minAlloc.height() - extra;
+
+ return IntSize(width, height);
+}
+
+GeneralAreaAllocator::GeneralAreaAllocator(const IntSize& size)
+ : AreaAllocator(nextPowerOfTwo(size))
+{
+ m_root = new Node();
+ m_root->rect = IntRect(0, 0, m_size.width(), m_size.height());
+ m_root->largestFree = m_size;
+ m_nodeCount = 1;
+ setMinimumAllocation(IntSize(8, 8));
+}
+
+GeneralAreaAllocator::~GeneralAreaAllocator()
+{
+ freeNode(m_root);
+}
+
+void GeneralAreaAllocator::freeNode(Node* node)
+{
+ if (node) {
+ freeNode(node->left);
+ freeNode(node->right);
+ }
+ delete node;
+}
+
+void GeneralAreaAllocator::expand(const IntSize& size)
+{
+ AreaAllocator::expand(nextPowerOfTwo(size));
+
+ if (m_root->rect.size() == m_size)
+ return; // No change.
+
+ if (!m_root->left && m_root->largestFree.width() > 0) {
+ // No allocations have occurred, so just adjust the root size.
+ m_root->rect = IntRect(0, 0, m_size.width(), m_size.height());
+ m_root->largestFree = m_size;
+ return;
+ }
+
+ // Add extra nodes above the current root to expand the tree.
+ Node* oldRoot = m_root;
+ Split split;
+ if (m_size.width() >= m_size.height())
+ split = SplitOnX;
+ else
+ split = SplitOnY;
+
+ while (m_root->rect.size() != m_size) {
+ if (m_root->rect.width() == m_size.width())
+ split = SplitOnY;
+ else if (m_root->rect.height() == m_size.height())
+ split = SplitOnX;
+ Node* parent = new Node();
+ Node* right = new Node();
+ m_nodeCount += 2;
+ m_root->parent = parent;
+ parent->parent = nullptr;
+ parent->left = m_root;
+ parent->right = right;
+ parent->largestFree = m_root->rect.size();
+ right->parent = parent;
+ right->left = nullptr;
+ right->right = nullptr;
+ right->largestFree = m_root->rect.size();
+ if (split == SplitOnX) {
+ parent->rect = IntRect(m_root->rect.x(), m_root->rect.y(),
+ m_root->rect.width() * 2, m_root->rect.height());
+ right->rect = IntRect(m_root->rect.x() + m_root->rect.width(), m_root->rect.y(),
+ m_root->rect.width(), m_root->rect.height());
+ } else {
+ parent->rect = IntRect(m_root->rect.x(), m_root->rect.y(),
+ m_root->rect.width(), m_root->rect.height() * 2);
+ right->rect = IntRect(m_root->rect.x(), m_root->rect.y() + m_root->rect.width(),
+ m_root->rect.width(), m_root->rect.height());
+ }
+ split = (split == SplitOnX ? SplitOnY : SplitOnX);
+ m_root = parent;
+ }
+ updateLargestFree(oldRoot);
+}
+
+static inline bool fitsWithin(const IntSize& size1, const IntSize& size2)
+{
+ return size1.width() <= size2.width() && size1.height() <= size2.height();
+}
+
+IntRect GeneralAreaAllocator::allocate(const IntSize& size)
+{
+ IntSize rounded = roundAllocation(size);
+ rounded = nextPowerOfTwo(rounded);
+ if (rounded.width() <= 0 || rounded.width() > m_size.width()
+ || rounded.height() <= 0 || rounded.height() > m_size.height())
+ return IntRect();
+
+ IntPoint point = allocateFromNode(rounded, m_root);
+ if (point.x() >= 0)
+ return IntRect(point, size);
+ return IntRect();
+}
+
+IntPoint GeneralAreaAllocator::allocateFromNode(const IntSize& size, Node* node)
+{
+ // Find the best node to insert into, which should be
+ // a node with the least amount of unused space that is
+ // big enough to contain the requested size.
+ while (node) {
+ // Go down a level and determine if the left or right
+ // sub-tree contains the best chance of allocation.
+ Node* left = node->left;
+ Node* right = node->right;
+ if (left && fitsWithin(size, left->largestFree)) {
+ if (right && fitsWithin(size, right->largestFree)) {
+ if (left->largestFree.width() < right->largestFree.width()
+ || left->largestFree.height() < right->largestFree.height()) {
+ // The largestFree values may be a little oversized,
+ // so try the left sub-tree and then the right sub-tree.
+ IntPoint point = allocateFromNode(size, left);
+ if (point.x() >= 0)
+ return point;
+ return allocateFromNode(size, right);
+ }
+ node = right;
+ } else
+ node = left;
+ } else if (right && fitsWithin(size, right->largestFree))
+ node = right;
+ else if (left || right) {
+ // Neither sub-node has enough space to allocate from.
+ return IntPoint(-1, -1);
+ } else if (fitsWithin(size, node->largestFree)) {
+ // Do we need to split this node into smaller pieces?
+ Split split;
+ if (fitsWithin(IntSize(size.width() * 2, size.height() * 2), node->largestFree)) {
+ // Split in either direction: choose the inverse of
+ // the parent node's split direction to try to balance
+ // out the wasted space as further subdivisions happen.
+ if (node->parent
+ && node->parent->left->rect.x() == node->parent->right->rect.x())
+ split = SplitOnX;
+ else if (node->parent)
+ split = SplitOnY;
+ else if (node->rect.width() >= node->rect.height())
+ split = SplitOnX;
+ else
+ split = SplitOnY;
+ } else if (fitsWithin(IntSize(size.width() * 2, size.height()), node->largestFree)) {
+ // Split along the X direction.
+ split = SplitOnX;
+ } else if (fitsWithin(IntSize(size.width(), size.height() * 2), node->largestFree)) {
+ // Split along the Y direction.
+ split = SplitOnY;
+ } else {
+ // Cannot split further - allocate this node.
+ node->largestFree = IntSize(0, 0);
+ updateLargestFree(node);
+ return node->rect.location();
+ }
+
+ // Split the node, then go around again using the left sub-tree.
+ node = splitNode(node, split);
+ } else {
+ // Cannot possibly fit into this node.
+ break;
+ }
+ }
+ return IntPoint(-1, -1);
+}
+
+GeneralAreaAllocator::Node* GeneralAreaAllocator::splitNode(Node* node, Split split)
+{
+ Node* left = new Node();
+ left->parent = node;
+ Node* right = new Node();
+ right->parent = node;
+ node->left = left;
+ node->right = right;
+ m_nodeCount += 2;
+
+ if (split == SplitOnX) {
+ left->rect = IntRect(node->rect.x(), node->rect.y(),
+ node->rect.width() / 2, node->rect.height());
+ right->rect = IntRect(left->rect.maxX(), node->rect.y(),
+ node->rect.width() / 2, node->rect.height());
+ } else {
+ left->rect = IntRect(node->rect.x(), node->rect.y(),
+ node->rect.width(), node->rect.height() / 2);
+ right->rect = IntRect(node->rect.x(), left->rect.maxY(),
+ node->rect.width(), node->rect.height() / 2);
+ }
+
+ left->largestFree = left->rect.size();
+ right->largestFree = right->rect.size();
+ node->largestFree = right->largestFree;
+ return left;
+}
+
+void GeneralAreaAllocator::updateLargestFree(Node* node)
+{
+ while ((node = node->parent)) {
+ node->largestFree = IntSize(
+ std::max(node->left->largestFree.width(), node->right->largestFree.width()),
+ std::max(node->left->largestFree.height(), node->right->largestFree.height())
+ );
+ }
+}
+
+void GeneralAreaAllocator::release(const IntRect& rect)
+{
+ // Locate the node that contains the allocated region.
+ Node* node = m_root;
+ IntPoint point = rect.location();
+ while (node) {
+ if (node->left && node->left->rect.contains(point))
+ node = node->left;
+ else if (node->right && node->right->rect.contains(point))
+ node = node->right;
+ else if (node->rect.contains(point))
+ break;
+ else
+ return; // Point is completely outside the tree.
+ }
+ if (!node)
+ return;
+
+ // Mark the node as free and then work upwards through the tree
+ // recombining and deleting nodes until we reach a sibling
+ // that is still allocated.
+ node->largestFree = node->rect.size();
+ while (node->parent) {
+ if (node->parent->left == node) {
+ if (node->parent->right->largestFree != node->parent->right->rect.size())
+ break;
+ } else {
+ if (node->parent->left->largestFree != node->parent->left->rect.size())
+ break;
+ }
+ node = node->parent;
+ freeNode(node->left);
+ freeNode(node->right);
+ m_nodeCount -= 2;
+ node->left = nullptr;
+ node->right = nullptr;
+ node->largestFree = node->rect.size();
+ }
+
+ // Make the rest of our ancestors have the correct "largest free size".
+ updateLargestFree(node);
+}
+
+int GeneralAreaAllocator::overhead() const
+{
+ return m_nodeCount * sizeof(Node);
+}
+
+} // namespace WebKit
+
+#endif // USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/AreaAllocator.h b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/AreaAllocator.h
new file mode 100644
index 000000000..20cadd613
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/AreaAllocator.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef AreaAllocator_h
+#define AreaAllocator_h
+
+#if USE(COORDINATED_GRAPHICS)
+
+#include <WebCore/IntPoint.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/IntSize.h>
+
+namespace WebKit {
+
+inline int nextPowerOfTwo(int number)
+{
+ // This is a fast trick to get nextPowerOfTwo for an integer.
+ --number;
+ number |= number >> 1;
+ number |= number >> 2;
+ number |= number >> 4;
+ number |= number >> 8;
+ number |= number >> 16;
+ number++;
+ return number;
+}
+
+inline WebCore::IntSize nextPowerOfTwo(const WebCore::IntSize& size)
+{
+ return WebCore::IntSize(nextPowerOfTwo(size.width()), nextPowerOfTwo(size.height()));
+}
+
+class AreaAllocator {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit AreaAllocator(const WebCore::IntSize&);
+ virtual ~AreaAllocator();
+
+ WebCore::IntSize size() const { return m_size; }
+
+ WebCore::IntSize minimumAllocation() const { return m_minAlloc; }
+ void setMinimumAllocation(const WebCore::IntSize& size) { m_minAlloc = size; }
+
+ WebCore::IntSize margin() const { return m_margin; }
+ void setMargin(const WebCore::IntSize &margin) { m_margin = margin; }
+
+ virtual void expand(const WebCore::IntSize&);
+ void expandBy(const WebCore::IntSize&);
+
+ virtual WebCore::IntRect allocate(const WebCore::IntSize&) = 0;
+ virtual void release(const WebCore::IntRect&);
+
+ virtual int overhead() const;
+
+protected:
+ WebCore::IntSize m_size;
+ WebCore::IntSize m_minAlloc;
+ WebCore::IntSize m_margin;
+
+ WebCore::IntSize roundAllocation(const WebCore::IntSize&) const;
+};
+
+class GeneralAreaAllocator final : public AreaAllocator {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit GeneralAreaAllocator(const WebCore::IntSize&);
+ virtual ~GeneralAreaAllocator();
+
+ void expand(const WebCore::IntSize&) override;
+ WebCore::IntRect allocate(const WebCore::IntSize&) override;
+ void release(const WebCore::IntRect&) override;
+ int overhead() const override;
+
+private:
+ enum Split { SplitOnX, SplitOnY };
+
+ struct Node {
+ WTF_MAKE_FAST_ALLOCATED;
+ public:
+ WebCore::IntRect rect;
+ WebCore::IntSize largestFree;
+ Node* parent { nullptr };
+ Node* left { nullptr };
+ Node* right { nullptr };
+ };
+
+ Node* m_root;
+ int m_nodeCount;
+
+ static void freeNode(Node*);
+ WebCore::IntPoint allocateFromNode(const WebCore::IntSize&, Node*);
+ Node* splitNode(Node*, Split);
+ static void updateLargestFree(Node*);
+};
+
+} // namespace WebKit
+
+#endif // USE(COORDINATED_GRAPHICS)
+#endif // AreaAllocator_h
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp
new file mode 100644
index 000000000..19fed7ece
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2013 Company 100, Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "CompositingCoordinator.h"
+
+#if USE(COORDINATED_GRAPHICS)
+
+#include <WebCore/DOMWindow.h>
+#include <WebCore/Document.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/InspectorController.h>
+#include <WebCore/MainFrame.h>
+#include <WebCore/MemoryPressureHandler.h>
+#include <WebCore/Page.h>
+#include <wtf/SetForScope.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+CompositingCoordinator::CompositingCoordinator(Page* page, CompositingCoordinator::Client& client)
+ : m_page(page)
+ , m_client(client)
+ , m_releaseInactiveAtlasesTimer(*this, &CompositingCoordinator::releaseInactiveAtlasesTimerFired)
+{
+}
+
+CompositingCoordinator::~CompositingCoordinator()
+{
+ m_isDestructing = true;
+
+ purgeBackingStores();
+
+ for (auto& registeredLayer : m_registeredLayers.values())
+ registeredLayer->setCoordinator(nullptr);
+}
+
+void CompositingCoordinator::invalidate()
+{
+ m_rootLayer = nullptr;
+ purgeBackingStores();
+}
+
+void CompositingCoordinator::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
+{
+ if (m_rootCompositingLayer == graphicsLayer)
+ return;
+
+ if (m_rootCompositingLayer)
+ m_rootCompositingLayer->removeFromParent();
+
+ m_rootCompositingLayer = graphicsLayer;
+ if (m_rootCompositingLayer)
+ m_rootLayer->addChildAtIndex(m_rootCompositingLayer, 0);
+}
+
+void CompositingCoordinator::setViewOverlayRootLayer(GraphicsLayer* graphicsLayer)
+{
+ if (m_overlayCompositingLayer == graphicsLayer)
+ return;
+
+ if (m_overlayCompositingLayer)
+ m_overlayCompositingLayer->removeFromParent();
+
+ m_overlayCompositingLayer = graphicsLayer;
+ if (m_overlayCompositingLayer)
+ m_rootLayer->addChild(m_overlayCompositingLayer);
+}
+
+void CompositingCoordinator::sizeDidChange(const IntSize& newSize)
+{
+ m_rootLayer->setSize(newSize);
+ notifyFlushRequired(m_rootLayer.get());
+}
+
+bool CompositingCoordinator::flushPendingLayerChanges()
+{
+ SetForScope<bool> protector(m_isFlushingLayerChanges, true);
+
+ initializeRootCompositingLayerIfNeeded();
+
+ m_rootLayer->flushCompositingStateForThisLayerOnly();
+ m_client.didFlushRootLayer(m_visibleContentsRect);
+
+ if (m_overlayCompositingLayer)
+ m_overlayCompositingLayer->flushCompositingState(FloatRect(FloatPoint(), m_rootLayer->size()));
+
+ bool didSync = m_page->mainFrame().view()->flushCompositingStateIncludingSubframes();
+
+ auto& coordinatedLayer = downcast<CoordinatedGraphicsLayer>(*m_rootLayer);
+ coordinatedLayer.updateContentBuffersIncludingSubLayers();
+ coordinatedLayer.syncPendingStateChangesIncludingSubLayers();
+
+ flushPendingImageBackingChanges();
+
+ if (m_shouldSyncFrame) {
+ didSync = true;
+
+ if (m_rootCompositingLayer) {
+ m_state.contentsSize = roundedIntSize(m_rootCompositingLayer->size());
+ if (CoordinatedGraphicsLayer* contentsLayer = mainContentsLayer())
+ m_state.coveredRect = contentsLayer->coverRect();
+ }
+ m_state.scrollPosition = m_visibleContentsRect.location();
+
+ m_client.commitSceneState(m_state);
+
+ clearPendingStateChanges();
+ m_shouldSyncFrame = false;
+ }
+
+ return didSync;
+}
+
+double CompositingCoordinator::timestamp() const
+{
+ auto* document = m_page->mainFrame().document();
+ if (!document)
+ return 0;
+ return document->domWindow() ? document->domWindow()->nowTimestamp() : document->monotonicTimestamp();
+}
+
+void CompositingCoordinator::syncDisplayState()
+{
+#if !USE(REQUEST_ANIMATION_FRAME_TIMER) && !USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
+ // Make sure that any previously registered animation callbacks are being executed before we flush the layers.
+ m_lastAnimationServiceTime = timestamp();
+ m_page->mainFrame().view()->serviceScriptedAnimations();
+#endif
+ m_page->mainFrame().view()->updateLayoutAndStyleIfNeededRecursive();
+}
+
+double CompositingCoordinator::nextAnimationServiceTime() const
+{
+ // According to the requestAnimationFrame spec, rAF callbacks should not be faster than 60FPS.
+ static const double MinimalTimeoutForAnimations = 1. / 60.;
+ return std::max<double>(0., MinimalTimeoutForAnimations - timestamp() + m_lastAnimationServiceTime);
+}
+
+void CompositingCoordinator::clearPendingStateChanges()
+{
+ m_state.layersToCreate.clear();
+ m_state.layersToUpdate.clear();
+ m_state.layersToRemove.clear();
+
+ m_state.imagesToCreate.clear();
+ m_state.imagesToRemove.clear();
+ m_state.imagesToUpdate.clear();
+ m_state.imagesToClear.clear();
+
+ m_state.updateAtlasesToCreate.clear();
+ m_state.updateAtlasesToRemove.clear();
+}
+
+void CompositingCoordinator::initializeRootCompositingLayerIfNeeded()
+{
+ if (m_didInitializeRootCompositingLayer)
+ return;
+
+ m_state.rootCompositingLayer = downcast<CoordinatedGraphicsLayer>(*m_rootLayer).id();
+ m_didInitializeRootCompositingLayer = true;
+ m_shouldSyncFrame = true;
+}
+
+void CompositingCoordinator::createRootLayer(const IntSize& size)
+{
+ ASSERT(!m_rootLayer);
+ // Create a root layer.
+ m_rootLayer = GraphicsLayer::create(this, *this);
+#ifndef NDEBUG
+ m_rootLayer->setName("CompositingCoordinator root layer");
+#endif
+ m_rootLayer->setDrawsContent(false);
+ m_rootLayer->setSize(size);
+}
+
+void CompositingCoordinator::syncLayerState(CoordinatedLayerID id, CoordinatedGraphicsLayerState& state)
+{
+ m_shouldSyncFrame = true;
+ m_state.layersToUpdate.append(std::make_pair(id, state));
+}
+
+Ref<CoordinatedImageBacking> CompositingCoordinator::createImageBackingIfNeeded(Image* image)
+{
+ CoordinatedImageBackingID imageID = CoordinatedImageBacking::getCoordinatedImageBackingID(image);
+ auto addResult = m_imageBackings.ensure(imageID, [this, image] {
+ return CoordinatedImageBacking::create(this, image);
+ });
+ return *addResult.iterator->value;
+}
+
+void CompositingCoordinator::createImageBacking(CoordinatedImageBackingID imageID)
+{
+ m_state.imagesToCreate.append(imageID);
+}
+
+void CompositingCoordinator::updateImageBacking(CoordinatedImageBackingID imageID, RefPtr<CoordinatedSurface>&& coordinatedSurface)
+{
+ m_shouldSyncFrame = true;
+ m_state.imagesToUpdate.append(std::make_pair(imageID, WTFMove(coordinatedSurface)));
+}
+
+void CompositingCoordinator::clearImageBackingContents(CoordinatedImageBackingID imageID)
+{
+ m_shouldSyncFrame = true;
+ m_state.imagesToClear.append(imageID);
+}
+
+void CompositingCoordinator::removeImageBacking(CoordinatedImageBackingID imageID)
+{
+ if (m_isPurging)
+ return;
+
+ ASSERT(m_imageBackings.contains(imageID));
+ m_imageBackings.remove(imageID);
+
+ m_state.imagesToRemove.append(imageID);
+
+ size_t imageIDPosition = m_state.imagesToClear.find(imageID);
+ if (imageIDPosition != notFound)
+ m_state.imagesToClear.remove(imageIDPosition);
+}
+
+void CompositingCoordinator::flushPendingImageBackingChanges()
+{
+ for (auto& imageBacking : m_imageBackings.values())
+ imageBacking->update();
+}
+
+void CompositingCoordinator::notifyAnimationStarted(const GraphicsLayer*, const String&, double /* time */)
+{
+}
+
+void CompositingCoordinator::notifyFlushRequired(const GraphicsLayer*)
+{
+ if (!m_isDestructing && !isFlushingLayerChanges())
+ m_client.notifyFlushRequired();
+}
+
+void CompositingCoordinator::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const FloatRect& clipRect)
+{
+ m_client.paintLayerContents(graphicsLayer, graphicsContext, enclosingIntRect(clipRect));
+}
+
+std::unique_ptr<GraphicsLayer> CompositingCoordinator::createGraphicsLayer(GraphicsLayer::Type layerType, GraphicsLayerClient& client)
+{
+ CoordinatedGraphicsLayer* layer = new CoordinatedGraphicsLayer(layerType, client);
+ layer->setCoordinator(this);
+ m_registeredLayers.add(layer->id(), layer);
+ m_state.layersToCreate.append(layer->id());
+ layer->setNeedsVisibleRectAdjustment();
+ notifyFlushRequired(layer);
+ return std::unique_ptr<GraphicsLayer>(layer);
+}
+
+float CompositingCoordinator::deviceScaleFactor() const
+{
+ return m_page->deviceScaleFactor();
+}
+
+float CompositingCoordinator::pageScaleFactor() const
+{
+ return m_page->pageScaleFactor();
+}
+
+void CompositingCoordinator::createUpdateAtlas(uint32_t atlasID, RefPtr<CoordinatedSurface>&& coordinatedSurface)
+{
+ m_state.updateAtlasesToCreate.append(std::make_pair(atlasID, WTFMove(coordinatedSurface)));
+}
+
+void CompositingCoordinator::removeUpdateAtlas(uint32_t atlasID)
+{
+ if (m_isPurging)
+ return;
+ m_state.updateAtlasesToRemove.append(atlasID);
+}
+
+FloatRect CompositingCoordinator::visibleContentsRect() const
+{
+ return m_visibleContentsRect;
+}
+
+CoordinatedGraphicsLayer* CompositingCoordinator::mainContentsLayer()
+{
+ if (!is<CoordinatedGraphicsLayer>(m_rootCompositingLayer))
+ return nullptr;
+
+ return downcast<CoordinatedGraphicsLayer>(*m_rootCompositingLayer).findFirstDescendantWithContentsRecursively();
+}
+
+void CompositingCoordinator::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector)
+{
+ // A zero trajectoryVector indicates that tiles all around the viewport are requested.
+ if (CoordinatedGraphicsLayer* contentsLayer = mainContentsLayer())
+ contentsLayer->setVisibleContentRectTrajectoryVector(trajectoryVector);
+
+ bool contentsRectDidChange = rect != m_visibleContentsRect;
+ if (contentsRectDidChange) {
+ m_visibleContentsRect = rect;
+
+ for (auto& registeredLayer : m_registeredLayers.values())
+ registeredLayer->setNeedsVisibleRectAdjustment();
+ }
+
+ FrameView* view = m_page->mainFrame().view();
+ if (view->useFixedLayout() && contentsRectDidChange) {
+ // Round the rect instead of enclosing it to make sure that its size stays
+ // the same while panning. This can have nasty effects on layout.
+ view->setFixedVisibleContentRect(roundedIntRect(rect));
+ }
+}
+
+void CompositingCoordinator::deviceOrPageScaleFactorChanged()
+{
+ m_rootLayer->deviceOrPageScaleFactorChanged();
+}
+
+void CompositingCoordinator::detachLayer(CoordinatedGraphicsLayer* layer)
+{
+ if (m_isPurging)
+ return;
+
+ m_registeredLayers.remove(layer->id());
+
+ size_t index = m_state.layersToCreate.find(layer->id());
+ if (index != notFound) {
+ m_state.layersToCreate.remove(index);
+ return;
+ }
+
+ m_state.layersToRemove.append(layer->id());
+ notifyFlushRequired(layer);
+}
+
+void CompositingCoordinator::commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset)
+{
+ if (auto* layer = m_registeredLayers.get(layerID))
+ layer->commitScrollOffset(offset);
+}
+
+void CompositingCoordinator::renderNextFrame()
+{
+ for (auto& atlas : m_updateAtlases)
+ atlas->didSwapBuffers();
+}
+
+void CompositingCoordinator::purgeBackingStores()
+{
+ SetForScope<bool> purgingToggle(m_isPurging, true);
+
+ for (auto& registeredLayer : m_registeredLayers.values())
+ registeredLayer->purgeBackingStores();
+
+ m_imageBackings.clear();
+ m_updateAtlases.clear();
+}
+
+bool CompositingCoordinator::paintToSurface(const IntSize& size, CoordinatedSurface::Flags flags, uint32_t& atlasID, IntPoint& offset, CoordinatedSurface::Client& client)
+{
+ for (auto& updateAtlas : m_updateAtlases) {
+ UpdateAtlas* atlas = updateAtlas.get();
+ if (atlas->supportsAlpha() == (flags & CoordinatedSurface::SupportsAlpha)) {
+ // This will be false if there is no available buffer space.
+ if (atlas->paintOnAvailableBuffer(size, atlasID, offset, client))
+ return true;
+ }
+ }
+
+ static const int ScratchBufferDimension = 1024; // Should be a power of two.
+ m_updateAtlases.append(std::make_unique<UpdateAtlas>(*this, ScratchBufferDimension, flags));
+ scheduleReleaseInactiveAtlases();
+ return m_updateAtlases.last()->paintOnAvailableBuffer(size, atlasID, offset, client);
+}
+
+const double ReleaseInactiveAtlasesTimerInterval = 0.5;
+
+void CompositingCoordinator::scheduleReleaseInactiveAtlases()
+{
+ if (!m_releaseInactiveAtlasesTimer.isActive())
+ m_releaseInactiveAtlasesTimer.startRepeating(ReleaseInactiveAtlasesTimerInterval);
+}
+
+void CompositingCoordinator::releaseInactiveAtlasesTimerFired()
+{
+ releaseAtlases(MemoryPressureHandler::singleton().isUnderMemoryPressure() ? ReleaseUnused : ReleaseInactive);
+}
+
+void CompositingCoordinator::releaseAtlases(ReleaseAtlasPolicy policy)
+{
+ // We always want to keep one atlas for root contents layer.
+ std::unique_ptr<UpdateAtlas> atlasToKeepAnyway;
+ bool foundActiveAtlasForRootContentsLayer = false;
+ for (int i = m_updateAtlases.size() - 1; i >= 0; --i) {
+ UpdateAtlas* atlas = m_updateAtlases[i].get();
+ bool inUse = atlas->isInUse();
+ if (!inUse)
+ atlas->addTimeInactive(ReleaseInactiveAtlasesTimerInterval);
+ bool usableForRootContentsLayer = !atlas->supportsAlpha();
+ if (atlas->isInactive() || (!inUse && policy == ReleaseUnused)) {
+ if (!foundActiveAtlasForRootContentsLayer && !atlasToKeepAnyway && usableForRootContentsLayer)
+ atlasToKeepAnyway = WTFMove(m_updateAtlases[i]);
+ m_updateAtlases.remove(i);
+ } else if (usableForRootContentsLayer)
+ foundActiveAtlasForRootContentsLayer = true;
+ }
+
+ if (!foundActiveAtlasForRootContentsLayer && atlasToKeepAnyway)
+ m_updateAtlases.append(atlasToKeepAnyway.release());
+
+ m_updateAtlases.shrinkToFit();
+
+ if (m_updateAtlases.size() <= 1)
+ m_releaseInactiveAtlasesTimer.stop();
+}
+
+} // namespace WebKit
+
+#endif // USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.h b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.h
new file mode 100644
index 000000000..eb214cf65
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Company 100, Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#ifndef CompositingCoordinator_h
+#define CompositingCoordinator_h
+
+#if USE(COORDINATED_GRAPHICS)
+
+#include "UpdateAtlas.h"
+#include <WebCore/CoordinatedGraphicsLayer.h>
+#include <WebCore/CoordinatedGraphicsState.h>
+#include <WebCore/CoordinatedImageBacking.h>
+#include <WebCore/FloatPoint.h>
+#include <WebCore/GraphicsLayerClient.h>
+#include <WebCore/GraphicsLayerFactory.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/Timer.h>
+
+namespace WebCore {
+class Page;
+class GraphicsContext;
+class GraphicsLayer;
+class CoordinatedSurface;
+}
+
+namespace WebKit {
+
+class CompositingCoordinator final : public WebCore::GraphicsLayerClient
+ , public WebCore::CoordinatedGraphicsLayerClient
+ , public WebCore::CoordinatedImageBacking::Client
+ , public UpdateAtlas::Client
+ , public WebCore::GraphicsLayerFactory {
+ WTF_MAKE_NONCOPYABLE(CompositingCoordinator);
+public:
+ class Client {
+ public:
+ virtual void didFlushRootLayer(const WebCore::FloatRect& visibleContentRect) = 0;
+ virtual void notifyFlushRequired() = 0;
+ virtual void commitSceneState(const WebCore::CoordinatedGraphicsState&) = 0;
+ virtual void paintLayerContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, const WebCore::IntRect& clipRect) = 0;
+ };
+
+ CompositingCoordinator(WebCore::Page*, CompositingCoordinator::Client&);
+ virtual ~CompositingCoordinator();
+
+ void invalidate();
+
+ void setRootCompositingLayer(WebCore::GraphicsLayer*);
+ void setViewOverlayRootLayer(WebCore::GraphicsLayer*);
+ void sizeDidChange(const WebCore::IntSize&);
+ void deviceOrPageScaleFactorChanged();
+
+ void setVisibleContentsRect(const WebCore::FloatRect&, const WebCore::FloatPoint&);
+ void renderNextFrame();
+ void commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset);
+
+ void createRootLayer(const WebCore::IntSize&);
+ WebCore::GraphicsLayer* rootLayer() const { return m_rootLayer.get(); }
+ WebCore::GraphicsLayer* rootCompositingLayer() const { return m_rootCompositingLayer; }
+ WebCore::CoordinatedGraphicsLayer* mainContentsLayer();
+
+ bool flushPendingLayerChanges();
+ WebCore::CoordinatedGraphicsState& state() { return m_state; }
+
+ void syncDisplayState();
+
+ double nextAnimationServiceTime() const;
+
+private:
+ enum ReleaseAtlasPolicy {
+ ReleaseInactive,
+ ReleaseUnused
+ };
+
+ // GraphicsLayerClient
+ void notifyAnimationStarted(const WebCore::GraphicsLayer*, const String&, double time) override;
+ void notifyFlushRequired(const WebCore::GraphicsLayer*) override;
+ void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::FloatRect& clipRect) override;
+ float deviceScaleFactor() const override;
+ float pageScaleFactor() const override;
+
+ // CoordinatedImageBacking::Client
+ void createImageBacking(WebCore::CoordinatedImageBackingID) override;
+ void updateImageBacking(WebCore::CoordinatedImageBackingID, RefPtr<WebCore::CoordinatedSurface>&&) override;
+ void clearImageBackingContents(WebCore::CoordinatedImageBackingID) override;
+ void removeImageBacking(WebCore::CoordinatedImageBackingID) override;
+
+ // CoordinatedGraphicsLayerClient
+ bool isFlushingLayerChanges() const override { return m_isFlushingLayerChanges; }
+ WebCore::FloatRect visibleContentsRect() const override;
+ Ref<WebCore::CoordinatedImageBacking> createImageBackingIfNeeded(WebCore::Image*) override;
+ void detachLayer(WebCore::CoordinatedGraphicsLayer*) override;
+ bool paintToSurface(const WebCore::IntSize&, WebCore::CoordinatedSurface::Flags, uint32_t& /* atlasID */, WebCore::IntPoint&, WebCore::CoordinatedSurface::Client&) override;
+ void syncLayerState(WebCore::CoordinatedLayerID, WebCore::CoordinatedGraphicsLayerState&) override;
+
+ // UpdateAtlas::Client
+ void createUpdateAtlas(uint32_t atlasID, RefPtr<WebCore::CoordinatedSurface>&&) override;
+ void removeUpdateAtlas(uint32_t atlasID) override;
+
+ // GraphicsLayerFactory
+ std::unique_ptr<WebCore::GraphicsLayer> createGraphicsLayer(WebCore::GraphicsLayer::Type, WebCore::GraphicsLayerClient&) override;
+
+ void initializeRootCompositingLayerIfNeeded();
+ void flushPendingImageBackingChanges();
+ void clearPendingStateChanges();
+
+ void purgeBackingStores();
+
+ void scheduleReleaseInactiveAtlases();
+ void releaseInactiveAtlasesTimerFired();
+ void releaseAtlases(ReleaseAtlasPolicy);
+
+ double timestamp() const;
+
+ WebCore::Page* m_page;
+ CompositingCoordinator::Client& m_client;
+
+ std::unique_ptr<WebCore::GraphicsLayer> m_rootLayer;
+ WebCore::GraphicsLayer* m_rootCompositingLayer { nullptr };
+ WebCore::GraphicsLayer* m_overlayCompositingLayer { nullptr };
+
+ WebCore::CoordinatedGraphicsState m_state;
+
+ typedef HashMap<WebCore::CoordinatedLayerID, WebCore::CoordinatedGraphicsLayer*> LayerMap;
+ LayerMap m_registeredLayers;
+ typedef HashMap<WebCore::CoordinatedImageBackingID, RefPtr<WebCore::CoordinatedImageBacking> > ImageBackingMap;
+ ImageBackingMap m_imageBackings;
+ Vector<std::unique_ptr<UpdateAtlas>> m_updateAtlases;
+
+ // We don't send the messages related to releasing resources to renderer during purging, because renderer already had removed all resources.
+ bool m_isDestructing { false };
+ bool m_isPurging { false };
+ bool m_isFlushingLayerChanges { false };
+ bool m_shouldSyncFrame { false };
+ bool m_didInitializeRootCompositingLayer { false };
+
+ WebCore::FloatRect m_visibleContentsRect;
+ WebCore::Timer m_releaseInactiveAtlasesTimer;
+
+ double m_lastAnimationServiceTime { 0 };
+};
+
+}
+
+#endif // namespace WebKit
+
+#endif // CompositingCoordinator_h
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp
new file mode 100644
index 000000000..b74070519
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2012 Company 100, Inc.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+
+#if USE(COORDINATED_GRAPHICS)
+#include "CoordinatedLayerTreeHost.h"
+
+#include "DrawingArea.h"
+#include "WebCoordinatedSurface.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include <WebCore/FrameView.h>
+#include <WebCore/MainFrame.h>
+#include <WebCore/PageOverlayController.h>
+
+#if USE(COORDINATED_GRAPHICS_THREADED)
+#include "ThreadSafeCoordinatedSurface.h"
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+Ref<CoordinatedLayerTreeHost> CoordinatedLayerTreeHost::create(WebPage& webPage)
+{
+ return adoptRef(*new CoordinatedLayerTreeHost(webPage));
+}
+
+CoordinatedLayerTreeHost::~CoordinatedLayerTreeHost()
+{
+}
+
+CoordinatedLayerTreeHost::CoordinatedLayerTreeHost(WebPage& webPage)
+ : LayerTreeHost(webPage)
+ , m_coordinator(webPage.corePage(), *this)
+ , m_layerFlushTimer(RunLoop::main(), this, &CoordinatedLayerTreeHost::layerFlushTimerFired)
+{
+ m_coordinator.createRootLayer(m_webPage.size());
+
+ CoordinatedSurface::setFactory(createCoordinatedSurface);
+ scheduleLayerFlush();
+}
+
+void CoordinatedLayerTreeHost::scheduleLayerFlush()
+{
+ if (!m_layerFlushSchedulingEnabled)
+ return;
+
+ if (m_isWaitingForRenderer) {
+ m_scheduledWhileWaitingForRenderer = true;
+ return;
+ }
+
+ if (!m_layerFlushTimer.isActive())
+ m_layerFlushTimer.startOneShot(0);
+}
+
+void CoordinatedLayerTreeHost::cancelPendingLayerFlush()
+{
+ m_layerFlushTimer.stop();
+}
+
+void CoordinatedLayerTreeHost::setViewOverlayRootLayer(GraphicsLayer* viewOverlayRootLayer)
+{
+ LayerTreeHost::setViewOverlayRootLayer(viewOverlayRootLayer);
+ m_coordinator.setViewOverlayRootLayer(viewOverlayRootLayer);
+}
+
+void CoordinatedLayerTreeHost::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
+{
+ m_coordinator.setRootCompositingLayer(graphicsLayer);
+}
+
+void CoordinatedLayerTreeHost::invalidate()
+{
+ cancelPendingLayerFlush();
+
+ m_coordinator.invalidate();
+ LayerTreeHost::invalidate();
+}
+
+void CoordinatedLayerTreeHost::forceRepaint()
+{
+ // This is necessary for running layout tests. Since in this case we are not waiting for a UIProcess to reply nicely.
+ // Instead we are just triggering forceRepaint. But we still want to have the scripted animation callbacks being executed.
+ m_coordinator.syncDisplayState();
+
+ // We need to schedule another flush, otherwise the forced paint might cancel a later expected flush.
+ // This is aligned with LayerTreeHostCA.
+ scheduleLayerFlush();
+
+ if (m_isWaitingForRenderer)
+ return;
+
+ m_coordinator.flushPendingLayerChanges();
+}
+
+bool CoordinatedLayerTreeHost::forceRepaintAsync(uint64_t callbackID)
+{
+ // We expect the UI process to not require a new repaint until the previous one has finished.
+ ASSERT(!m_forceRepaintAsyncCallbackID);
+ m_forceRepaintAsyncCallbackID = callbackID;
+ scheduleLayerFlush();
+ return true;
+}
+
+void CoordinatedLayerTreeHost::sizeDidChange(const IntSize& newSize)
+{
+ m_coordinator.sizeDidChange(newSize);
+ scheduleLayerFlush();
+}
+
+void CoordinatedLayerTreeHost::setVisibleContentsRect(const FloatRect& rect, const FloatPoint& trajectoryVector)
+{
+ m_coordinator.setVisibleContentsRect(rect, trajectoryVector);
+ scheduleLayerFlush();
+}
+
+void CoordinatedLayerTreeHost::renderNextFrame()
+{
+ m_isWaitingForRenderer = false;
+ bool scheduledWhileWaitingForRenderer = std::exchange(m_scheduledWhileWaitingForRenderer, false);
+ m_coordinator.renderNextFrame();
+
+ if (scheduledWhileWaitingForRenderer || m_layerFlushTimer.isActive()) {
+ m_layerFlushTimer.stop();
+ layerFlushTimerFired();
+ }
+}
+
+void CoordinatedLayerTreeHost::didFlushRootLayer(const FloatRect& visibleContentRect)
+{
+ // Because our view-relative overlay root layer is not attached to the FrameView's GraphicsLayer tree, we need to flush it manually.
+ if (m_viewOverlayRootLayer)
+ m_viewOverlayRootLayer->flushCompositingState(visibleContentRect);
+}
+
+void CoordinatedLayerTreeHost::layerFlushTimerFired()
+{
+ if (m_isSuspended || m_isWaitingForRenderer)
+ return;
+
+ m_coordinator.syncDisplayState();
+
+ if (!m_isValid || !m_coordinator.rootCompositingLayer())
+ return;
+
+ bool didSync = m_coordinator.flushPendingLayerChanges();
+
+ if (m_forceRepaintAsyncCallbackID) {
+ m_webPage.send(Messages::WebPageProxy::VoidCallback(m_forceRepaintAsyncCallbackID));
+ m_forceRepaintAsyncCallbackID = 0;
+ }
+
+ if (m_notifyAfterScheduledLayerFlush && didSync) {
+ m_webPage.drawingArea()->layerHostDidFlushLayers();
+ m_notifyAfterScheduledLayerFlush = false;
+ }
+}
+
+void CoordinatedLayerTreeHost::paintLayerContents(const GraphicsLayer*, GraphicsContext&, const IntRect&)
+{
+}
+
+void CoordinatedLayerTreeHost::commitSceneState(const CoordinatedGraphicsState& state)
+{
+ m_isWaitingForRenderer = true;
+}
+
+RefPtr<CoordinatedSurface> CoordinatedLayerTreeHost::createCoordinatedSurface(const IntSize& size, CoordinatedSurface::Flags flags)
+{
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ return ThreadSafeCoordinatedSurface::create(size, flags);
+#else
+ UNUSED_PARAM(size);
+ UNUSED_PARAM(flags);
+ return nullptr;
+#endif
+}
+
+void CoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged()
+{
+ m_coordinator.deviceOrPageScaleFactorChanged();
+ m_webPage.mainFrame()->pageOverlayController().didChangeDeviceScaleFactor();
+}
+
+void CoordinatedLayerTreeHost::pageBackgroundTransparencyChanged()
+{
+}
+
+GraphicsLayerFactory* CoordinatedLayerTreeHost::graphicsLayerFactory()
+{
+ return &m_coordinator;
+}
+
+void CoordinatedLayerTreeHost::scheduleAnimation()
+{
+ if (m_isWaitingForRenderer)
+ return;
+
+ if (m_layerFlushTimer.isActive())
+ return;
+
+ scheduleLayerFlush();
+ m_layerFlushTimer.startOneShot(m_coordinator.nextAnimationServiceTime());
+}
+
+void CoordinatedLayerTreeHost::commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset)
+{
+ m_coordinator.commitScrollOffset(layerID, offset);
+}
+
+} // namespace WebKit
+#endif // USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h
new file mode 100644
index 000000000..7b3aa5d35
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.h
@@ -0,0 +1,92 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2013 Company 100, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef CoordinatedLayerTreeHost_h
+#define CoordinatedLayerTreeHost_h
+
+#if USE(COORDINATED_GRAPHICS)
+
+#include "CompositingCoordinator.h"
+#include "LayerTreeHost.h"
+#include <wtf/RunLoop.h>
+
+namespace WebCore {
+class CoordinatedSurface;
+class GraphicsLayerFactory;
+}
+
+namespace WebKit {
+
+class WebPage;
+
+class CoordinatedLayerTreeHost : public LayerTreeHost, public CompositingCoordinator::Client
+{
+public:
+ static Ref<CoordinatedLayerTreeHost> create(WebPage&);
+ virtual ~CoordinatedLayerTreeHost();
+
+protected:
+ explicit CoordinatedLayerTreeHost(WebPage&);
+
+ void scheduleLayerFlush() override;
+ void cancelPendingLayerFlush() override;
+ void setRootCompositingLayer(WebCore::GraphicsLayer*) override;
+ void invalidate() override;
+
+ void forceRepaint() override;
+ bool forceRepaintAsync(uint64_t callbackID) override;
+ void sizeDidChange(const WebCore::IntSize& newSize) override;
+
+ void deviceOrPageScaleFactorChanged() override;
+ void pageBackgroundTransparencyChanged() override;
+
+ void setVisibleContentsRect(const WebCore::FloatRect&, const WebCore::FloatPoint&);
+ void renderNextFrame();
+ void commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset);
+
+ WebCore::GraphicsLayerFactory* graphicsLayerFactory() override;
+
+ void scheduleAnimation() override;
+
+ void setViewOverlayRootLayer(WebCore::GraphicsLayer*) override;
+
+ // CompositingCoordinator::Client
+ void didFlushRootLayer(const WebCore::FloatRect& visibleContentRect) override;
+ void notifyFlushRequired() override { scheduleLayerFlush(); };
+ void commitSceneState(const WebCore::CoordinatedGraphicsState&) override;
+ void paintLayerContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, const WebCore::IntRect& clipRect) override;
+
+private:
+ void layerFlushTimerFired();
+
+ static RefPtr<WebCore::CoordinatedSurface> createCoordinatedSurface(const WebCore::IntSize&, WebCore::CoordinatedSurface::Flags);
+
+ CompositingCoordinator m_coordinator;
+ bool m_isWaitingForRenderer { true };
+ bool m_scheduledWhileWaitingForRenderer { false };
+ uint64_t m_forceRepaintAsyncCallbackID { 0 };
+ RunLoop::Timer<CoordinatedLayerTreeHost> m_layerFlushTimer;
+};
+
+} // namespace WebKit
+
+#endif // USE(COORDINATED_GRAPHICS)
+
+#endif // CoordinatedLayerTreeHost_h
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.messages.in b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.messages.in
new file mode 100644
index 000000000..73f953d0b
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedLayerTreeHost.messages.in
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+# Copyright (C) 2012 Intel Corporation. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+
+
+#if USE(COORDINATED_GRAPHICS)
+messages -> CoordinatedLayerTreeHost LegacyReceiver {
+ SetVisibleContentsRect(WebCore::FloatRect visibleContentsRect, WebCore::FloatPoint trajectoryVectory)
+ RenderNextFrame()
+ CommitScrollOffset(uint32_t layerID, WebCore::IntSize offset)
+}
+#endif
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp
new file mode 100644
index 000000000..281353b8a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2012 Company 100, Inc.
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "ThreadedCoordinatedLayerTreeHost.h"
+
+#if USE(COORDINATED_GRAPHICS_THREADED)
+
+#include "AcceleratedSurface.h"
+#include "WebPage.h"
+#include <WebCore/FrameView.h>
+#include <WebCore/MainFrame.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+Ref<ThreadedCoordinatedLayerTreeHost> ThreadedCoordinatedLayerTreeHost::create(WebPage& webPage)
+{
+ return adoptRef(*new ThreadedCoordinatedLayerTreeHost(webPage));
+}
+
+ThreadedCoordinatedLayerTreeHost::~ThreadedCoordinatedLayerTreeHost()
+{
+}
+
+ThreadedCoordinatedLayerTreeHost::ThreadedCoordinatedLayerTreeHost(WebPage& webPage)
+ : CoordinatedLayerTreeHost(webPage)
+ , m_compositorClient(*this)
+ , m_surface(AcceleratedSurface::create(webPage))
+ , m_viewportController(webPage.size())
+{
+ if (FrameView* frameView = m_webPage.mainFrameView()) {
+ auto contentsSize = frameView->contentsSize();
+ if (!contentsSize.isEmpty())
+ m_viewportController.didChangeContentsSize(contentsSize);
+ }
+
+ IntSize scaledSize(m_webPage.size());
+ scaledSize.scale(m_webPage.deviceScaleFactor());
+ float scaleFactor = m_webPage.deviceScaleFactor() * m_viewportController.pageScaleFactor();
+
+ if (m_surface) {
+ TextureMapper::PaintFlags paintFlags = 0;
+
+ if (m_surface->shouldPaintMirrored())
+ paintFlags |= TextureMapper::PaintingMirrored;
+
+ // Do not do frame sync when rendering offscreen in the web process to ensure that SwapBuffers never blocks.
+ // Rendering to the actual screen will happen later anyway since the UI process schedules a redraw for every update,
+ // the compositor will take care of syncing to vblank.
+ m_compositor = ThreadedCompositor::create(m_compositorClient, scaledSize, scaleFactor, m_surface->window(), ThreadedCompositor::ShouldDoFrameSync::No, paintFlags);
+ m_layerTreeContext.contextID = m_surface->surfaceID();
+ } else
+ m_compositor = ThreadedCompositor::create(m_compositorClient, scaledSize, scaleFactor);
+
+ didChangeViewport();
+}
+
+void ThreadedCoordinatedLayerTreeHost::invalidate()
+{
+ m_compositor->invalidate();
+ CoordinatedLayerTreeHost::invalidate();
+ m_surface = nullptr;
+}
+
+void ThreadedCoordinatedLayerTreeHost::forceRepaint()
+{
+ CoordinatedLayerTreeHost::forceRepaint();
+ m_compositor->forceRepaint();
+}
+
+void ThreadedCoordinatedLayerTreeHost::scrollNonCompositedContents(const IntRect& rect)
+{
+ FrameView* frameView = m_webPage.mainFrameView();
+ if (!frameView || !frameView->delegatesScrolling())
+ return;
+
+ m_viewportController.didScroll(rect.location());
+ if (m_isDiscardable)
+ m_discardableSyncActions |= DiscardableSyncActions::UpdateViewport;
+ else
+ didChangeViewport();
+}
+
+void ThreadedCoordinatedLayerTreeHost::contentsSizeChanged(const IntSize& newSize)
+{
+ m_viewportController.didChangeContentsSize(newSize);
+ if (m_isDiscardable)
+ m_discardableSyncActions |= DiscardableSyncActions::UpdateViewport;
+ else
+ didChangeViewport();
+}
+
+void ThreadedCoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged()
+{
+ if (m_isDiscardable) {
+ m_discardableSyncActions |= DiscardableSyncActions::UpdateScale;
+ return;
+ }
+
+ if (m_surface && m_surface->resize(m_webPage.size()))
+ m_layerTreeContext.contextID = m_surface->surfaceID();
+
+ CoordinatedLayerTreeHost::deviceOrPageScaleFactorChanged();
+ m_compositor->setScaleFactor(m_webPage.deviceScaleFactor() * m_viewportController.pageScaleFactor());
+}
+
+void ThreadedCoordinatedLayerTreeHost::pageBackgroundTransparencyChanged()
+{
+ if (m_isDiscardable) {
+ m_discardableSyncActions |= DiscardableSyncActions::UpdateBackground;
+ return;
+ }
+
+ CoordinatedLayerTreeHost::pageBackgroundTransparencyChanged();
+ m_compositor->setDrawsBackground(m_webPage.drawsBackground());
+}
+
+void ThreadedCoordinatedLayerTreeHost::sizeDidChange(const IntSize& size)
+{
+ if (m_isDiscardable) {
+ m_discardableSyncActions |= DiscardableSyncActions::UpdateSize;
+ m_viewportController.didChangeViewportSize(size);
+ return;
+ }
+
+ if (m_surface && m_surface->resize(size))
+ m_layerTreeContext.contextID = m_surface->surfaceID();
+
+ CoordinatedLayerTreeHost::sizeDidChange(size);
+ m_viewportController.didChangeViewportSize(size);
+ IntSize scaledSize(size);
+ scaledSize.scale(m_webPage.deviceScaleFactor());
+ m_compositor->setViewportSize(scaledSize, m_webPage.deviceScaleFactor() * m_viewportController.pageScaleFactor());
+ didChangeViewport();
+}
+
+void ThreadedCoordinatedLayerTreeHost::didChangeViewportAttributes(ViewportAttributes&& attr)
+{
+ m_viewportController.didChangeViewportAttributes(WTFMove(attr));
+ if (m_isDiscardable)
+ m_discardableSyncActions |= DiscardableSyncActions::UpdateViewport;
+ else
+ didChangeViewport();
+}
+
+#if PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+void ThreadedCoordinatedLayerTreeHost::setNativeSurfaceHandleForCompositing(uint64_t handle)
+{
+ m_layerTreeContext.contextID = handle;
+ m_compositor->setNativeSurfaceHandleForCompositing(handle);
+ scheduleLayerFlush();
+}
+#endif
+
+void ThreadedCoordinatedLayerTreeHost::didChangeViewport()
+{
+ FloatRect visibleRect(m_viewportController.visibleContentsRect());
+ if (visibleRect.isEmpty())
+ return;
+
+ // When using non overlay scrollbars, the contents size doesn't include the scrollbars, but we need to include them
+ // in the visible area used by the compositor to ensure that the scrollbar layers are also updated.
+ // See https://bugs.webkit.org/show_bug.cgi?id=160450.
+ FrameView* view = m_webPage.corePage()->mainFrame().view();
+ Scrollbar* scrollbar = view->verticalScrollbar();
+ if (scrollbar && !scrollbar->isOverlayScrollbar())
+ visibleRect.expand(scrollbar->width(), 0);
+ scrollbar = view->horizontalScrollbar();
+ if (scrollbar && !scrollbar->isOverlayScrollbar())
+ visibleRect.expand(0, scrollbar->height());
+
+ CoordinatedLayerTreeHost::setVisibleContentsRect(visibleRect, FloatPoint::zero());
+
+ float pageScale = m_viewportController.pageScaleFactor();
+ IntPoint scrollPosition = roundedIntPoint(visibleRect.location());
+ if (m_lastScrollPosition != scrollPosition) {
+ m_lastScrollPosition = scrollPosition;
+ m_compositor->setScrollPosition(m_lastScrollPosition, m_webPage.deviceScaleFactor() * pageScale);
+
+ if (!view->useFixedLayout())
+ view->notifyScrollPositionChanged(m_lastScrollPosition);
+ }
+
+ if (m_lastPageScaleFactor != pageScale) {
+ m_lastPageScaleFactor = pageScale;
+ m_webPage.scalePage(pageScale, m_lastScrollPosition);
+ }
+}
+
+void ThreadedCoordinatedLayerTreeHost::commitSceneState(const CoordinatedGraphicsState& state)
+{
+ CoordinatedLayerTreeHost::commitSceneState(state);
+ m_compositor->updateSceneState(state);
+}
+
+void ThreadedCoordinatedLayerTreeHost::setIsDiscardable(bool discardable)
+{
+ m_isDiscardable = discardable;
+ if (m_isDiscardable) {
+ m_discardableSyncActions = OptionSet<DiscardableSyncActions>();
+ return;
+ }
+
+ if (m_discardableSyncActions.isEmpty())
+ return;
+
+ if (m_discardableSyncActions.contains(DiscardableSyncActions::UpdateBackground))
+ pageBackgroundTransparencyChanged();
+
+ if (m_discardableSyncActions.contains(DiscardableSyncActions::UpdateSize)) {
+ // Size changes already sets the scale factor and updates the viewport.
+ sizeDidChange(m_webPage.size());
+ return;
+ }
+
+ if (m_discardableSyncActions.contains(DiscardableSyncActions::UpdateScale))
+ deviceOrPageScaleFactorChanged();
+
+ if (m_discardableSyncActions.contains(DiscardableSyncActions::UpdateViewport))
+ didChangeViewport();
+}
+
+} // namespace WebKit
+
+#endif // USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h
new file mode 100644
index 000000000..ca8aeac63
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Company 100, Inc.
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#ifndef ThreadedCoordinatedLayerTreeHost_h
+#define ThreadedCoordinatedLayerTreeHost_h
+
+#if USE(COORDINATED_GRAPHICS_THREADED)
+
+#include "CoordinatedLayerTreeHost.h"
+#include "SimpleViewportController.h"
+#include "ThreadedCompositor.h"
+#include <wtf/OptionSet.h>
+
+namespace WebCore {
+class GraphicsContext;
+class GraphicsLayer;
+struct CoordinatedGraphicsState;
+}
+
+namespace WebKit {
+
+class AcceleratedSurface;
+class WebPage;
+
+class ThreadedCoordinatedLayerTreeHost final : public CoordinatedLayerTreeHost {
+public:
+ static Ref<ThreadedCoordinatedLayerTreeHost> create(WebPage&);
+ virtual ~ThreadedCoordinatedLayerTreeHost();
+
+private:
+ explicit ThreadedCoordinatedLayerTreeHost(WebPage&);
+
+ void scrollNonCompositedContents(const WebCore::IntRect& scrollRect) override;
+ void sizeDidChange(const WebCore::IntSize&) override;
+ void deviceOrPageScaleFactorChanged() override;
+ void pageBackgroundTransparencyChanged() override;
+
+ void contentsSizeChanged(const WebCore::IntSize&) override;
+ void didChangeViewportAttributes(WebCore::ViewportAttributes&&) override;
+
+ void invalidate() override;
+
+ void forceRepaint() override;
+ bool forceRepaintAsync(uint64_t callbackID) override { return false; }
+
+ void setIsDiscardable(bool) override;
+
+#if PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+ void setNativeSurfaceHandleForCompositing(uint64_t) override;
+#endif
+
+ class CompositorClient final : public ThreadedCompositor::Client {
+ WTF_MAKE_NONCOPYABLE(CompositorClient);
+ public:
+ CompositorClient(ThreadedCoordinatedLayerTreeHost& layerTreeHost)
+ : m_layerTreeHost(layerTreeHost)
+ {
+ }
+
+ private:
+ void renderNextFrame() override
+ {
+ m_layerTreeHost.renderNextFrame();
+ }
+
+ void commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset) override
+ {
+ m_layerTreeHost.commitScrollOffset(layerID, offset);
+ }
+
+ ThreadedCoordinatedLayerTreeHost& m_layerTreeHost;
+ };
+
+ void didChangeViewport();
+
+ // CompositingCoordinator::Client
+ void didFlushRootLayer(const WebCore::FloatRect&) override { }
+ void commitSceneState(const WebCore::CoordinatedGraphicsState&) override;
+
+ enum class DiscardableSyncActions {
+ UpdateSize = 1 << 1,
+ UpdateViewport = 1 << 2,
+ UpdateScale = 1 << 3,
+ UpdateBackground = 1 << 4
+ };
+
+ CompositorClient m_compositorClient;
+ std::unique_ptr<AcceleratedSurface> m_surface;
+ RefPtr<ThreadedCompositor> m_compositor;
+ SimpleViewportController m_viewportController;
+ float m_lastPageScaleFactor { 1 };
+ WebCore::IntPoint m_lastScrollPosition;
+ bool m_isDiscardable { false };
+ OptionSet<DiscardableSyncActions> m_discardableSyncActions;
+};
+
+} // namespace WebKit
+
+#endif // USE(COORDINATED_GRAPHICS_THREADED)
+
+#endif // ThreadedCoordinatedLayerTreeHost_h
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/UpdateAtlas.cpp b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/UpdateAtlas.cpp
new file mode 100644
index 000000000..e2c4ffeee
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/UpdateAtlas.cpp
@@ -0,0 +1,116 @@
+/*
+ Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2012 Company 100, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "UpdateAtlas.h"
+
+#if USE(COORDINATED_GRAPHICS)
+
+#include <WebCore/CoordinatedGraphicsState.h>
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/IntRect.h>
+#include <wtf/MathExtras.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+class UpdateAtlasSurfaceClient final : public CoordinatedSurface::Client {
+public:
+ UpdateAtlasSurfaceClient(CoordinatedSurface::Client& client, const IntSize& size, bool supportsAlpha)
+ : m_client(client)
+ , m_size(size)
+ , m_supportsAlpha(supportsAlpha)
+ {
+ }
+
+ void paintToSurfaceContext(GraphicsContext& context) override
+ {
+ if (m_supportsAlpha) {
+ context.setCompositeOperation(CompositeCopy);
+ context.fillRect(IntRect(IntPoint::zero(), m_size), Color::transparent);
+ context.setCompositeOperation(CompositeSourceOver);
+ }
+
+ m_client.paintToSurfaceContext(context);
+ }
+
+private:
+ CoordinatedSurface::Client& m_client;
+ IntSize m_size;
+ bool m_supportsAlpha;
+};
+
+UpdateAtlas::UpdateAtlas(Client& client, int dimension, CoordinatedSurface::Flags flags)
+ : m_client(client)
+{
+ static uint32_t nextID = 0;
+ m_ID = ++nextID;
+ IntSize size = nextPowerOfTwo(IntSize(dimension, dimension));
+ m_surface = CoordinatedSurface::create(size, flags);
+
+ m_client.createUpdateAtlas(m_ID, m_surface.copyRef());
+}
+
+UpdateAtlas::~UpdateAtlas()
+{
+ if (m_surface)
+ m_client.removeUpdateAtlas(m_ID);
+}
+
+void UpdateAtlas::buildLayoutIfNeeded()
+{
+ if (m_areaAllocator)
+ return;
+ m_areaAllocator = std::make_unique<GeneralAreaAllocator>(size());
+ m_areaAllocator->setMinimumAllocation(IntSize(32, 32));
+}
+
+void UpdateAtlas::didSwapBuffers()
+{
+ m_areaAllocator = nullptr;
+}
+
+bool UpdateAtlas::paintOnAvailableBuffer(const IntSize& size, uint32_t& atlasID, IntPoint& offset, CoordinatedSurface::Client& client)
+{
+ m_inactivityInSeconds = 0;
+ buildLayoutIfNeeded();
+ IntRect rect = m_areaAllocator->allocate(size);
+
+ // No available buffer was found.
+ if (rect.isEmpty())
+ return false;
+
+ if (!m_surface)
+ return false;
+
+ atlasID = m_ID;
+
+ // FIXME: Use tri-state buffers, to allow faster updates.
+ offset = rect.location();
+
+ UpdateAtlasSurfaceClient surfaceClient(client, size, supportsAlpha());
+ m_surface->paintToSurface(rect, surfaceClient);
+
+ return true;
+}
+
+} // namespace WebCore
+#endif // USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/UpdateAtlas.h b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/UpdateAtlas.h
new file mode 100644
index 000000000..63f76be95
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/UpdateAtlas.h
@@ -0,0 +1,83 @@
+/*
+ Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2012 Company 100, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#ifndef UpdateAtlas_h
+#define UpdateAtlas_h
+
+#include "AreaAllocator.h"
+#include <WebCore/CoordinatedSurface.h>
+#include <WebCore/IntSize.h>
+#include <wtf/RefPtr.h>
+
+#if USE(COORDINATED_GRAPHICS)
+
+namespace WebCore {
+class GraphicsContext;
+class IntPoint;
+}
+
+namespace WebKit {
+
+class UpdateAtlas {
+ WTF_MAKE_NONCOPYABLE(UpdateAtlas);
+public:
+ class Client {
+ public:
+ virtual void createUpdateAtlas(uint32_t /* id */, RefPtr<WebCore::CoordinatedSurface>&&) = 0;
+ virtual void removeUpdateAtlas(uint32_t /* id */) = 0;
+ };
+
+ UpdateAtlas(Client&, int dimension, WebCore::CoordinatedSurface::Flags);
+ ~UpdateAtlas();
+
+ inline WebCore::IntSize size() const { return m_surface->size(); }
+
+ // Returns false if there is no available buffer.
+ bool paintOnAvailableBuffer(const WebCore::IntSize&, uint32_t& atlasID, WebCore::IntPoint& offset, WebCore::CoordinatedSurface::Client&);
+ void didSwapBuffers();
+ bool supportsAlpha() const { return m_surface->supportsAlpha(); }
+
+ void addTimeInactive(double seconds)
+ {
+ ASSERT(!isInUse());
+ m_inactivityInSeconds += seconds;
+ }
+ bool isInactive() const
+ {
+ const double inactiveSecondsTolerance = 3;
+ return m_inactivityInSeconds > inactiveSecondsTolerance;
+ }
+ bool isInUse() const { return !!m_areaAllocator; }
+
+private:
+ void buildLayoutIfNeeded();
+
+private:
+ Client& m_client;
+ std::unique_ptr<GeneralAreaAllocator> m_areaAllocator;
+ RefPtr<WebCore::CoordinatedSurface> m_surface;
+ double m_inactivityInSeconds { 0 };
+ uint32_t m_ID { 0 };
+};
+
+} // namespace WebKit
+
+#endif // USE(COORDINATED_GRAPHICS)
+#endif // UpdateAtlas_h
diff --git a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp
deleted file mode 100644
index 9cdcb2b45..000000000
--- a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
- */
-
-#include "config.h"
-#include "DecoderAdapter.h"
-
-#include "DataReference.h"
-#include "WebCoreArgumentCoders.h"
-#include <wtf/text/WTFString.h>
-
-namespace WebKit {
-
-DecoderAdapter::DecoderAdapter(const uint8_t* buffer, size_t bufferSize)
- : m_decoder(buffer, bufferSize)
-{
- // Keep format compatibility by decoding an unused uint64_t value
- // that used to be encoded by the argument encoder.
- uint64_t value;
- m_decoder.decode(value);
- ASSERT(!value);
-}
-
-bool DecoderAdapter::decodeBytes(Vector<uint8_t>& bytes)
-{
- IPC::DataReference dataReference;
- if (!m_decoder.decode(dataReference))
- return false;
-
- bytes = dataReference.vector();
- return true;
-}
-
-bool DecoderAdapter::decodeBool(bool& value)
-{
- return m_decoder.decode(value);
-}
-
-bool DecoderAdapter::decodeUInt16(uint16_t& value)
-{
- return m_decoder.decode(value);
-}
-
-bool DecoderAdapter::decodeUInt32(uint32_t& value)
-{
- return m_decoder.decode(value);
-}
-
-bool DecoderAdapter::decodeUInt64(uint64_t& value)
-{
- return m_decoder.decode(value);
-}
-
-bool DecoderAdapter::decodeInt32(int32_t& value)
-{
- return m_decoder.decode(value);
-}
-
-bool DecoderAdapter::decodeInt64(int64_t& value)
-{
- return m_decoder.decode(value);
-}
-
-bool DecoderAdapter::decodeFloat(float& value)
-{
- return m_decoder.decode(value);
-}
-
-bool DecoderAdapter::decodeDouble(double& value)
-{
- return m_decoder.decode(value);
-}
-
-bool DecoderAdapter::decodeString(String& value)
-{
- // This mimics the IPC binary encoding of Strings prior to r88886.
- // Whenever the IPC binary encoding changes, we'll have to "undo" the changes here.
- // FIXME: We shouldn't use the IPC binary encoding format for history,
- // and we should come up with a migration strategy so we can actually bump the version number
- // without breaking encoding/decoding of the history tree.
-
- uint32_t length;
- if (!m_decoder.decode(length))
- return false;
-
- if (length == std::numeric_limits<uint32_t>::max()) {
- // This is the null string.
- value = String();
- return true;
- }
-
- uint64_t lengthInBytes;
- if (!m_decoder.decode(lengthInBytes))
- return false;
-
- if (lengthInBytes % sizeof(UChar) || lengthInBytes / sizeof(UChar) != length) {
- m_decoder.markInvalid();
- return false;
- }
-
- if (!m_decoder.bufferIsLargeEnoughToContain<UChar>(length)) {
- m_decoder.markInvalid();
- return false;
- }
-
- UChar* buffer;
- String string = String::createUninitialized(length, buffer);
- if (!m_decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(buffer), length * sizeof(UChar), alignof(UChar)))
- return false;
-
- value = string;
- return true;
-}
-
-} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp
index e4750e6c2..2e780d91b 100644
--- a/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp
@@ -25,28 +25,30 @@
#include "config.h"
#include "DrawingArea.h"
-#include <wtf/Functional.h>
+
+#include "DrawingAreaMessages.h"
+#include "WebPage.h"
+#include "WebPageCreationParameters.h"
+#include "WebProcess.h"
+#include <WebCore/DisplayRefreshMonitor.h>
+#include <WebCore/TransformationMatrix.h>
// Subclasses
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#include "RemoteLayerTreeDrawingArea.h"
#include "TiledCoreAnimationDrawingArea.h"
#else
-#if USE(COORDINATED_GRAPHICS)
-#include "CoordinatedDrawingArea.h"
-#else
#include "DrawingAreaImpl.h"
#endif
-#endif
-#include "WebPageCreationParameters.h"
+using namespace WebCore;
namespace WebKit {
-std::unique_ptr<DrawingArea> DrawingArea::create(WebPage* webPage, const WebPageCreationParameters& parameters)
+std::unique_ptr<DrawingArea> DrawingArea::create(WebPage& webPage, const WebPageCreationParameters& parameters)
{
switch (parameters.drawingAreaType) {
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#if !PLATFORM(IOS)
case DrawingAreaTypeTiledCoreAnimation:
return std::make_unique<TiledCoreAnimationDrawingArea>(webPage, parameters);
@@ -54,27 +56,24 @@ std::unique_ptr<DrawingArea> DrawingArea::create(WebPage* webPage, const WebPage
case DrawingAreaTypeRemoteLayerTree:
return std::make_unique<RemoteLayerTreeDrawingArea>(webPage, parameters);
#else
-#if USE(COORDINATED_GRAPHICS)
- case DrawingAreaTypeCoordinated:
- return std::make_unique<CoordinatedDrawingArea>(webPage, parameters);
-#else
case DrawingAreaTypeImpl:
return std::make_unique<DrawingAreaImpl>(webPage, parameters);
#endif
-#endif
}
return nullptr;
}
-DrawingArea::DrawingArea(DrawingAreaType type, WebPage* webPage)
+DrawingArea::DrawingArea(DrawingAreaType type, WebPage& webPage)
: m_type(type)
, m_webPage(webPage)
{
+ WebProcess::singleton().addMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_webPage.pageID(), *this);
}
DrawingArea::~DrawingArea()
{
+ WebProcess::singleton().removeMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_webPage.pageID());
}
void DrawingArea::dispatchAfterEnsuringUpdatedScrollPosition(std::function<void ()> function)
@@ -83,4 +82,11 @@ void DrawingArea::dispatchAfterEnsuringUpdatedScrollPosition(std::function<void
function();
}
+#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
+RefPtr<WebCore::DisplayRefreshMonitor> DrawingArea::createDisplayRefreshMonitor(PlatformDisplayID)
+{
+ return nullptr;
+}
+#endif
+
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingArea.h b/Source/WebKit2/WebProcess/WebPage/DrawingArea.h
index adf7c5cc8..c3d682711 100644
--- a/Source/WebKit2/WebProcess/WebPage/DrawingArea.h
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.h
@@ -23,48 +23,54 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DrawingArea_h
-#define DrawingArea_h
+#pragma once
#include "DrawingAreaInfo.h"
#include "LayerTreeContext.h"
+#include "MessageReceiver.h"
+#include <WebCore/ActivityState.h>
#include <WebCore/FloatRect.h>
#include <WebCore/IntRect.h>
-#include <WebCore/ViewState.h>
+#include <WebCore/LayerFlushThrottleState.h>
+#include <WebCore/LayoutMilestones.h>
+#include <WebCore/PlatformScreen.h>
#include <functional>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
+#include <wtf/TypeCasts.h>
+#include <wtf/Vector.h>
namespace IPC {
class Connection;
-class MessageDecoder;
+class Decoder;
}
namespace WebCore {
+class DisplayRefreshMonitor;
+class Frame;
class FrameView;
class GraphicsLayer;
class GraphicsLayerFactory;
+class MachSendRight;
+struct ViewportAttributes;
}
namespace WebKit {
struct ColorSpaceData;
class LayerTreeHost;
-class PageOverlay;
class WebPage;
struct WebPageCreationParameters;
struct WebPreferencesStore;
-class DrawingArea {
+class DrawingArea : public IPC::MessageReceiver {
WTF_MAKE_NONCOPYABLE(DrawingArea);
public:
- static std::unique_ptr<DrawingArea> create(WebPage*, const WebPageCreationParameters&);
+ static std::unique_ptr<DrawingArea> create(WebPage&, const WebPageCreationParameters&);
virtual ~DrawingArea();
DrawingAreaType type() const { return m_type; }
-
- void didReceiveDrawingAreaMessage(IPC::Connection*, IPC::MessageDecoder&);
virtual void setNeedsDisplay() = 0;
virtual void setNeedsDisplayInRect(const WebCore::IntRect&) = 0;
@@ -78,71 +84,108 @@ public:
virtual bool layerTreeStateIsFrozen() const { return false; }
virtual LayerTreeHost* layerTreeHost() const { return 0; }
- virtual void didInstallPageOverlay(PageOverlay*) { }
- virtual void didUninstallPageOverlay(PageOverlay*) { }
- virtual void setPageOverlayNeedsDisplay(PageOverlay*, const WebCore::IntRect&) { }
- virtual void setPageOverlayOpacity(PageOverlay*, float) { }
- virtual void clearPageOverlay(PageOverlay*) { }
-
virtual void setPaintingEnabled(bool) { }
virtual void updatePreferences(const WebPreferencesStore&) { }
virtual void mainFrameContentSizeChanged(const WebCore::IntSize&) { }
-#if PLATFORM(MAC)
- virtual void setExposedRect(const WebCore::FloatRect&) = 0;
- virtual WebCore::FloatRect exposedRect() const = 0;
- virtual void setCustomFixedPositionRect(const WebCore::FloatRect&) = 0;
+#if PLATFORM(COCOA)
+ virtual void setViewExposedRect(std::optional<WebCore::FloatRect>) = 0;
+ virtual std::optional<WebCore::FloatRect> viewExposedRect() const = 0;
+
+ virtual void acceleratedAnimationDidStart(uint64_t /*layerID*/, const String& /*key*/, double /*startTime*/) { }
+ virtual void acceleratedAnimationDidEnd(uint64_t /*layerID*/, const String& /*key*/) { }
+ virtual void addFence(const WebCore::MachSendRight&) { }
+#endif
+#if PLATFORM(IOS)
+ virtual WebCore::FloatRect exposedContentRect() const = 0;
+ virtual void setExposedContentRect(const WebCore::FloatRect&) = 0;
#endif
virtual void mainFrameScrollabilityChanged(bool) { }
virtual bool supportsAsyncScrolling() { return false; }
- virtual void didChangeScrollOffsetForAnyFrame() { }
-
virtual bool shouldUseTiledBackingForFrameView(const WebCore::FrameView*) { return false; }
-#if USE(ACCELERATED_COMPOSITING)
- virtual WebCore::GraphicsLayerFactory* graphicsLayerFactory() { return 0; }
+ virtual WebCore::GraphicsLayerFactory* graphicsLayerFactory() { return nullptr; }
virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) = 0;
virtual void scheduleCompositingLayerFlush() = 0;
-#endif
+ virtual void scheduleCompositingLayerFlushImmediately() = 0;
-#if USE(COORDINATED_GRAPHICS)
- virtual void didReceiveCoordinatedLayerTreeHostMessage(IPC::Connection*, IPC::MessageDecoder&) = 0;
+#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
+ virtual RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID);
#endif
virtual void dispatchAfterEnsuringUpdatedScrollPosition(std::function<void ()>);
- virtual void viewStateDidChange(WebCore::ViewState::Flags) { }
+ virtual void activityStateDidChange(WebCore::ActivityState::Flags, bool /* wantsDidUpdateActivityState */, const Vector<uint64_t>& /* callbackIDs */) { }
virtual void setLayerHostingMode(LayerHostingMode) { }
+ virtual bool markLayersVolatileImmediatelyIfPossible() { return true; }
+
+ virtual bool adjustLayerFlushThrottling(WebCore::LayerFlushThrottleState::Flags) { return false; }
+
+ virtual void attachViewOverlayGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*) { }
+
+ virtual void setShouldScaleViewToFitDocument(bool) { }
+
+ virtual bool dispatchDidReachLayoutMilestone(WebCore::LayoutMilestones) { return false; }
+
+#if PLATFORM(COCOA)
+ // Used by TiledCoreAnimationDrawingArea.
+ virtual void updateGeometry(const WebCore::IntSize& viewSize, const WebCore::IntSize& layerPosition, bool flushSynchronously, const WebCore::MachSendRight& fencePort) { }
+#endif
+
+ virtual void layerHostDidFlushLayers() { };
+
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ virtual void didChangeViewportAttributes(WebCore::ViewportAttributes&&) = 0;
+#endif
+
+#if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
+ virtual void deviceOrPageScaleFactorChanged() = 0;
+#endif
+
protected:
- DrawingArea(DrawingAreaType, WebPage*);
+ DrawingArea(DrawingAreaType, WebPage&);
DrawingAreaType m_type;
- WebPage* m_webPage;
+ WebPage& m_webPage;
+
+#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+ uint64_t m_nativeSurfaceHandleForCompositing { 0 };
+#endif
private:
+ // IPC::MessageReceiver.
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+ void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
+
// Message handlers.
// FIXME: These should be pure virtual.
virtual void updateBackingStoreState(uint64_t /*backingStoreStateID*/, bool /*respondImmediately*/, float /*deviceScaleFactor*/, const WebCore::IntSize& /*size*/,
const WebCore::IntSize& /*scrollOffset*/) { }
virtual void didUpdate() { }
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
// Used by TiledCoreAnimationDrawingArea.
- virtual void updateGeometry(const WebCore::IntSize& viewSize, const WebCore::IntSize& layerPosition) { }
virtual void setDeviceScaleFactor(float) { }
virtual void setColorSpace(const ColorSpaceData&) { }
virtual void adjustTransientZoom(double scale, WebCore::FloatPoint origin) { }
virtual void commitTransientZoom(double scale, WebCore::FloatPoint origin) { }
+
+ virtual void addTransactionCallbackID(uint64_t callbackID) { ASSERT_NOT_REACHED(); }
#endif
-};
-#define DRAWING_AREA_TYPE_CASTS(ToValueTypeName, predicate) \
- TYPE_CASTS_BASE(ToValueTypeName, DrawingArea, value, value->predicate, value.predicate)
+#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+ virtual void setNativeSurfaceHandleForCompositing(uint64_t) = 0;
+ virtual void destroyNativeSurfaceHandleForCompositing(bool&) = 0;
+#endif
+};
} // namespace WebKit
-#endif // DrawingArea_h
+#define SPECIALIZE_TYPE_TRAITS_DRAWING_AREA(ToValueTypeName, AreaType) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebKit::ToValueTypeName) \
+ static bool isType(const WebKit::DrawingArea& area) { return area.type() == WebKit::AreaType; } \
+SPECIALIZE_TYPE_TRAITS_END()
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in b/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in
index f4b8286a5..b076f34c1 100644
--- a/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in
@@ -20,19 +20,28 @@
# 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.
-messages -> DrawingArea LegacyReceiver {
+messages -> DrawingArea {
UpdateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, float deviceScaleFactor, WebCore::IntSize size, WebCore::IntSize scrollOffset)
DidUpdate()
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
// Used by TiledCoreAnimationDrawingArea.
- UpdateGeometry(WebCore::IntSize viewSize, WebCore::IntSize layerPosition)
+ UpdateGeometry(WebCore::IntSize viewSize, WebCore::IntSize layerPosition, bool flushSynchronously, WebCore::MachSendRight fencePort)
SetDeviceScaleFactor(float deviceScaleFactor)
- SetColorSpace(WebKit::ColorSpaceData colorSpace)
- SetExposedRect(WebCore::FloatRect exposedRect)
- SetCustomFixedPositionRect(WebCore::FloatRect fixedPositionRect)
+ SetColorSpace(struct WebKit::ColorSpaceData colorSpace)
+ SetViewExposedRect(std::optional<WebCore::FloatRect> viewExposedRect)
AdjustTransientZoom(double scale, WebCore::FloatPoint origin)
CommitTransientZoom(double scale, WebCore::FloatPoint origin)
+
+ AcceleratedAnimationDidStart(uint64_t layerID, String key, double startTime)
+ AcceleratedAnimationDidEnd(uint64_t layerID, String key)
+
+ AddTransactionCallbackID(uint64_t callbackID)
+#endif
+
+#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+ SetNativeSurfaceHandleForCompositing(uint64_t handle)
+ DestroyNativeSurfaceHandleForCompositing() -> (bool handled)
#endif
}
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp
index 0abead9b7..a2da574c4 100644
--- a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp
@@ -27,12 +27,12 @@
#include "DrawingAreaImpl.h"
#include "DrawingAreaProxyMessages.h"
-#include "LayerTreeContext.h"
+#include "LayerTreeHost.h"
#include "ShareableBitmap.h"
#include "UpdateInfo.h"
#include "WebPage.h"
#include "WebPageCreationParameters.h"
-#include "WebProcess.h"
+#include "WebPreferencesKeys.h"
#include <WebCore/GraphicsContext.h>
#include <WebCore/Page.h>
#include <WebCore/Settings.h>
@@ -43,60 +43,38 @@ namespace WebKit {
DrawingAreaImpl::~DrawingAreaImpl()
{
- if (m_layerTreeHost)
- m_layerTreeHost->invalidate();
}
-DrawingAreaImpl::DrawingAreaImpl(WebPage* webPage, const WebPageCreationParameters& parameters)
- : DrawingArea(DrawingAreaTypeImpl, webPage)
- , m_backingStoreStateID(0)
- , m_isPaintingEnabled(true)
- , m_inUpdateBackingStoreState(false)
- , m_shouldSendDidUpdateBackingStoreState(false)
- , m_isWaitingForDidUpdate(false)
- , m_compositingAccordingToProxyMessages(false)
- , m_layerTreeStateIsFrozen(false)
- , m_wantsToExitAcceleratedCompositingMode(false)
- , m_isPaintingSuspended(!(parameters.viewState & ViewState::IsVisible))
- , m_alwaysUseCompositing(false)
+DrawingAreaImpl::DrawingAreaImpl(WebPage& webPage, const WebPageCreationParameters& parameters)
+ : AcceleratedDrawingArea(webPage, parameters)
, m_displayTimer(RunLoop::main(), this, &DrawingAreaImpl::displayTimerFired)
- , m_exitCompositingTimer(RunLoop::main(), this, &DrawingAreaImpl::exitAcceleratedCompositingMode)
{
- if (webPage->corePage()->settings().acceleratedDrawingEnabled() || webPage->corePage()->settings().forceCompositingMode())
- m_alwaysUseCompositing = true;
-
- if (m_alwaysUseCompositing)
- enterAcceleratedCompositingMode(0);
}
void DrawingAreaImpl::setNeedsDisplay()
{
- if (!m_isPaintingEnabled)
- return;
-
if (m_layerTreeHost) {
ASSERT(m_dirtyRegion.isEmpty());
- m_layerTreeHost->setNonCompositedContentsNeedDisplay();
+ AcceleratedDrawingArea::setNeedsDisplay();
return;
}
- setNeedsDisplayInRect(m_webPage->bounds());
+ setNeedsDisplayInRect(m_webPage.bounds());
}
void DrawingAreaImpl::setNeedsDisplayInRect(const IntRect& rect)
{
- if (!m_isPaintingEnabled)
- return;
-
if (m_layerTreeHost) {
ASSERT(m_dirtyRegion.isEmpty());
- m_layerTreeHost->setNonCompositedContentsNeedDisplayInRect(rect);
+ AcceleratedDrawingArea::setNeedsDisplayInRect(rect);
return;
}
-
- IntRect dirtyRect = rect;
- dirtyRect.intersect(m_webPage->bounds());
+ if (!m_isPaintingEnabled)
+ return;
+
+ IntRect dirtyRect = rect;
+ dirtyRect.intersect(m_webPage.bounds());
if (dirtyRect.isEmpty())
return;
@@ -106,21 +84,23 @@ void DrawingAreaImpl::setNeedsDisplayInRect(const IntRect& rect)
void DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollDelta)
{
- if (!m_isPaintingEnabled)
- return;
-
if (m_layerTreeHost) {
ASSERT(m_scrollRect.isEmpty());
ASSERT(m_scrollOffset.isEmpty());
ASSERT(m_dirtyRegion.isEmpty());
-
- m_layerTreeHost->scrollNonCompositedContents(scrollRect);
+ AcceleratedDrawingArea::scroll(scrollRect, scrollDelta);
return;
}
+ if (!m_isPaintingEnabled)
+ return;
+
if (scrollRect.isEmpty())
return;
+ if (m_previousLayerTreeHost)
+ m_previousLayerTreeHost->scrollNonCompositedContents(scrollRect);
+
if (!m_scrollRect.isEmpty() && scrollRect != m_scrollRect) {
unsigned scrollArea = scrollRect.width() * scrollRect.height();
unsigned currentScrollArea = m_scrollRect.width() * m_scrollRect.height();
@@ -150,8 +130,8 @@ void DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollDel
// And add them back.
m_dirtyRegion.unite(movedDirtyRegionInScrollRect);
- }
-
+ }
+
// Compute the scroll repaint region.
Region scrollRepaintRegion = subtract(scrollRect, translate(scrollRect, scrollDelta));
@@ -162,223 +142,99 @@ void DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollDel
m_scrollOffset += scrollDelta;
}
-void DrawingAreaImpl::pageBackgroundTransparencyChanged()
-{
- if (m_layerTreeHost)
- m_layerTreeHost->pageBackgroundTransparencyChanged();
-}
-
-void DrawingAreaImpl::setLayerTreeStateIsFrozen(bool isFrozen)
-{
- if (m_layerTreeStateIsFrozen == isFrozen)
- return;
-
- m_layerTreeStateIsFrozen = isFrozen;
-
- if (m_layerTreeHost)
- m_layerTreeHost->setLayerFlushSchedulingEnabled(!isFrozen);
-
- if (isFrozen)
- m_exitCompositingTimer.stop();
- else if (m_wantsToExitAcceleratedCompositingMode)
- exitAcceleratedCompositingModeSoon();
-}
-
void DrawingAreaImpl::forceRepaint()
{
- setNeedsDisplay();
-
- m_webPage->layoutIfNeeded();
-
- if (m_layerTreeHost) {
- // FIXME: We need to do the same work as the layerHostDidFlushLayers function here,
- // but clearly it doesn't make sense to call the function with that name.
- // Consider refactoring and renaming it.
- if (m_compositingAccordingToProxyMessages)
- m_layerTreeHost->forceRepaint();
- else {
- // Call setShouldNotifyAfterNextScheduledLayerFlush(false) here to
- // prevent layerHostDidFlushLayers() from being called a second time.
- m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false);
- layerHostDidFlushLayers();
- }
+ if (m_inUpdateBackingStoreState) {
+ m_forceRepaintAfterBackingStoreStateUpdate = true;
return;
}
+ m_forceRepaintAfterBackingStoreStateUpdate = false;
- m_isWaitingForDidUpdate = false;
- display();
-}
-
-bool DrawingAreaImpl::forceRepaintAsync(uint64_t callbackID)
-{
- return m_layerTreeHost && m_layerTreeHost->forceRepaintAsync(callbackID);
-}
-
-void DrawingAreaImpl::didInstallPageOverlay(PageOverlay* pageOverlay)
-{
- if (m_layerTreeHost)
- m_layerTreeHost->didInstallPageOverlay(pageOverlay);
-}
-
-void DrawingAreaImpl::didUninstallPageOverlay(PageOverlay* pageOverlay)
-{
- if (m_layerTreeHost)
- m_layerTreeHost->didUninstallPageOverlay(pageOverlay);
-
- setNeedsDisplay();
-}
-
-void DrawingAreaImpl::setPageOverlayNeedsDisplay(PageOverlay* pageOverlay, const IntRect& rect)
-{
if (m_layerTreeHost) {
- m_layerTreeHost->setPageOverlayNeedsDisplay(pageOverlay, rect);
+ AcceleratedDrawingArea::forceRepaint();
return;
}
- setNeedsDisplayInRect(rect);
+ m_isWaitingForDidUpdate = false;
+ if (m_isPaintingEnabled) {
+ m_dirtyRegion = m_webPage.bounds();
+ display();
+ }
}
-void DrawingAreaImpl::setPageOverlayOpacity(PageOverlay* pageOverlay, float value)
+void DrawingAreaImpl::mainFrameContentSizeChanged(const WebCore::IntSize& newSize)
{
+#if USE(COORDINATED_GRAPHICS_THREADED)
if (m_layerTreeHost)
- m_layerTreeHost->setPageOverlayOpacity(pageOverlay, value);
-}
-
-void DrawingAreaImpl::setPaintingEnabled(bool paintingEnabled)
-{
- m_isPaintingEnabled = paintingEnabled;
+ m_layerTreeHost->contentsSizeChanged(newSize);
+ else if (m_previousLayerTreeHost)
+ m_previousLayerTreeHost->contentsSizeChanged(newSize);
+#else
+ UNUSED_PARAM(newSize);
+#endif
}
void DrawingAreaImpl::updatePreferences(const WebPreferencesStore& store)
{
- m_webPage->corePage()->settings().setForceCompositingMode(store.getBoolValueForKey(WebPreferencesKey::forceCompositingModeKey()) && LayerTreeHost::supportsAcceleratedCompositing());
-}
-
-void DrawingAreaImpl::layerHostDidFlushLayers()
-{
- ASSERT(m_layerTreeHost);
-
- m_layerTreeHost->forceRepaint();
-
- if (m_shouldSendDidUpdateBackingStoreState && !exitAcceleratedCompositingModePending()) {
- sendDidUpdateBackingStoreState();
- return;
- }
-
- if (!m_layerTreeHost)
- return;
+ Settings& settings = m_webPage.corePage()->settings();
+ settings.setForceCompositingMode(store.getBoolValueForKey(WebPreferencesKey::forceCompositingModeKey()));
-#if USE(ACCELERATED_COMPOSITING)
- ASSERT(!m_compositingAccordingToProxyMessages);
- if (!exitAcceleratedCompositingModePending()) {
- m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(m_backingStoreStateID, m_layerTreeHost->layerTreeContext()));
- m_compositingAccordingToProxyMessages = true;
- }
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ // Fixed position elements need to be composited and create stacking contexts
+ // in order to be scrolled by the ScrollingCoordinator.
+ settings.setAcceleratedCompositingForFixedPositionEnabled(settings.acceleratedCompositingEnabled());
+ settings.setFixedPositionCreatesStackingContext(settings.acceleratedCompositingEnabled());
#endif
-}
-
-#if USE(ACCELERATED_COMPOSITING)
-GraphicsLayerFactory* DrawingAreaImpl::graphicsLayerFactory()
-{
- if (m_layerTreeHost)
- return m_layerTreeHost->graphicsLayerFactory();
- return 0;
+ m_alwaysUseCompositing = settings.acceleratedCompositingEnabled() && settings.forceCompositingMode();
+ if (m_alwaysUseCompositing && !m_layerTreeHost)
+ enterAcceleratedCompositingMode(nullptr);
}
void DrawingAreaImpl::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
{
- // FIXME: Instead of using nested if statements, we should keep a compositing state
- // enum in the DrawingAreaImpl object and have a changeAcceleratedCompositingState function
- // that takes the new state.
-
- if (graphicsLayer) {
- if (!m_layerTreeHost) {
- // We're actually entering accelerated compositing mode.
- enterAcceleratedCompositingMode(graphicsLayer);
- } else {
- // We're already in accelerated compositing mode, but the root compositing layer changed.
-
- m_exitCompositingTimer.stop();
- m_wantsToExitAcceleratedCompositingMode = false;
-
- // If we haven't sent the EnterAcceleratedCompositingMode message, make sure that the
- // layer tree host calls us back after the next layer flush so we can send it then.
- if (!m_compositingAccordingToProxyMessages)
- m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true);
-
- m_layerTreeHost->setRootCompositingLayer(graphicsLayer);
- }
- } else {
- if (m_layerTreeHost) {
- m_layerTreeHost->setRootCompositingLayer(0);
- if (!m_alwaysUseCompositing) {
- // We'll exit accelerated compositing mode on a timer, to avoid re-entering
- // compositing code via display() and layout.
- // If we're leaving compositing mode because of a setSize, it is safe to
- // exit accelerated compositing mode right away.
- if (m_inUpdateBackingStoreState)
- exitAcceleratedCompositingMode();
- else
- exitAcceleratedCompositingModeSoon();
- }
+ if (m_layerTreeHost) {
+ AcceleratedDrawingArea::setRootCompositingLayer(graphicsLayer);
+
+ if (!graphicsLayer && !m_alwaysUseCompositing) {
+ // We'll exit accelerated compositing mode on a timer, to avoid re-entering
+ // compositing code via display() and layout.
+ // If we're leaving compositing mode because of a setSize, it is safe to
+ // exit accelerated compositing mode right away.
+ if (m_inUpdateBackingStoreState)
+ exitAcceleratedCompositingMode();
+ else
+ exitAcceleratedCompositingModeSoon();
}
+ return;
}
-}
-void DrawingAreaImpl::scheduleCompositingLayerFlush()
-{
- if (!m_layerTreeHost)
+ if (!graphicsLayer)
return;
- m_layerTreeHost->scheduleLayerFlush();
+
+ // We're actually entering accelerated compositing mode.
+ enterAcceleratedCompositingMode(graphicsLayer);
}
-#endif
void DrawingAreaImpl::updateBackingStoreState(uint64_t stateID, bool respondImmediately, float deviceScaleFactor, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset)
{
- ASSERT(!m_inUpdateBackingStoreState);
- m_inUpdateBackingStoreState = true;
-
- ASSERT_ARG(stateID, stateID >= m_backingStoreStateID);
- if (stateID != m_backingStoreStateID) {
- m_backingStoreStateID = stateID;
- m_shouldSendDidUpdateBackingStoreState = true;
-
- m_webPage->setDeviceScaleFactor(deviceScaleFactor);
- m_webPage->setSize(size);
- m_webPage->layoutIfNeeded();
- m_webPage->scrollMainFrameIfNotAtMaxScrollPosition(scrollOffset);
-
- if (m_layerTreeHost) {
- m_layerTreeHost->sizeDidChange(m_webPage->size());
- } else
- m_dirtyRegion = m_webPage->bounds();
- } else {
- ASSERT(size == m_webPage->size());
- if (!m_shouldSendDidUpdateBackingStoreState) {
- // We've already sent a DidUpdateBackingStoreState message for this state. We have nothing more to do.
- m_inUpdateBackingStoreState = false;
- return;
- }
- }
+ if (stateID != m_backingStoreStateID && !m_layerTreeHost)
+ m_dirtyRegion = IntRect(IntPoint(), size);
+
+ AcceleratedDrawingArea::updateBackingStoreState(stateID, respondImmediately, deviceScaleFactor, size, scrollOffset);
+ if (m_forceRepaintAfterBackingStoreStateUpdate)
+ forceRepaint();
+}
+
+void DrawingAreaImpl::didUpdateBackingStoreState()
+{
// The UI process has updated to a new backing store state. Any Update messages we sent before
// this point will be ignored. We wait to set this to false until after updating the page's
// size so that any displays triggered by the relayout will be ignored. If we're supposed to
// respond to the UpdateBackingStoreState message immediately, we'll do a display anyway in
// sendDidUpdateBackingStoreState; otherwise we shouldn't do one right now.
m_isWaitingForDidUpdate = false;
-
- if (respondImmediately) {
- // Make sure to resume painting if we're supposed to respond immediately, otherwise we'll just
- // send back an empty UpdateInfo struct.
- if (m_isPaintingSuspended)
- resumePainting();
-
- sendDidUpdateBackingStoreState();
- }
-
- m_inUpdateBackingStoreState = false;
}
void DrawingAreaImpl::sendDidUpdateBackingStoreState()
@@ -386,33 +242,20 @@ void DrawingAreaImpl::sendDidUpdateBackingStoreState()
ASSERT(!m_isWaitingForDidUpdate);
ASSERT(m_shouldSendDidUpdateBackingStoreState);
- m_shouldSendDidUpdateBackingStoreState = false;
-
- UpdateInfo updateInfo;
-
- if (!m_isPaintingSuspended && !m_layerTreeHost)
+ if (!m_isPaintingSuspended && !m_layerTreeHost) {
+ UpdateInfo updateInfo;
display(updateInfo);
+ if (!m_layerTreeHost) {
+ m_shouldSendDidUpdateBackingStoreState = false;
- LayerTreeContext layerTreeContext;
-
- if (m_isPaintingSuspended || m_layerTreeHost) {
- updateInfo.viewSize = m_webPage->size();
- updateInfo.deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor();
-
- if (m_layerTreeHost) {
- layerTreeContext = m_layerTreeHost->layerTreeContext();
-
- // We don't want the layer tree host to notify after the next scheduled
- // layer flush because that might end up sending an EnterAcceleratedCompositingMode
- // message back to the UI process, but the updated layer tree context
- // will be sent back in the DidUpdateBackingStoreState message.
- m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false);
- m_layerTreeHost->forceRepaint();
+ LayerTreeContext layerTreeContext;
+ m_webPage.send(Messages::DrawingAreaProxy::DidUpdateBackingStoreState(m_backingStoreStateID, updateInfo, layerTreeContext));
+ m_compositingAccordingToProxyMessages = false;
+ return;
}
}
- m_webPage->send(Messages::DrawingAreaProxy::DidUpdateBackingStoreState(m_backingStoreStateID, updateInfo, layerTreeContext));
- m_compositingAccordingToProxyMessages = !layerTreeContext.isEmpty();
+ AcceleratedDrawingArea::sendDidUpdateBackingStoreState();
}
void DrawingAreaImpl::didUpdate()
@@ -430,45 +273,14 @@ void DrawingAreaImpl::didUpdate()
void DrawingAreaImpl::suspendPainting()
{
- ASSERT(!m_isPaintingSuspended);
-
- if (m_layerTreeHost)
- m_layerTreeHost->pauseRendering();
-
- m_isPaintingSuspended = true;
+ AcceleratedDrawingArea::suspendPainting();
m_displayTimer.stop();
}
-void DrawingAreaImpl::resumePainting()
-{
- if (!m_isPaintingSuspended) {
- // FIXME: We can get a call to resumePainting when painting is not suspended.
- // This happens when sending a synchronous message to create a new page. See <rdar://problem/8976531>.
- return;
- }
-
- if (m_layerTreeHost)
- m_layerTreeHost->resumeRendering();
-
- m_isPaintingSuspended = false;
-
- // FIXME: We shouldn't always repaint everything here.
- setNeedsDisplay();
-}
-
void DrawingAreaImpl::enterAcceleratedCompositingMode(GraphicsLayer* graphicsLayer)
{
- m_exitCompositingTimer.stop();
- m_wantsToExitAcceleratedCompositingMode = false;
+ AcceleratedDrawingArea::enterAcceleratedCompositingMode(graphicsLayer);
- ASSERT(!m_layerTreeHost);
-
- m_layerTreeHost = LayerTreeHost::create(m_webPage);
- if (!m_inUpdateBackingStoreState)
- m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true);
-
- m_layerTreeHost->setRootCompositingLayer(graphicsLayer);
-
// Non-composited content will now be handled exclusively by the layer tree host.
m_dirtyRegion = Region();
m_scrollRect = IntRect();
@@ -482,16 +294,8 @@ void DrawingAreaImpl::exitAcceleratedCompositingMode()
if (m_alwaysUseCompositing)
return;
- ASSERT(!m_layerTreeStateIsFrozen);
-
- m_exitCompositingTimer.stop();
- m_wantsToExitAcceleratedCompositingMode = false;
-
- ASSERT(m_layerTreeHost);
-
- m_layerTreeHost->invalidate();
- m_layerTreeHost = nullptr;
- m_dirtyRegion = m_webPage->bounds();
+ AcceleratedDrawingArea::exitAcceleratedCompositingModeNow();
+ m_dirtyRegion = m_webPage.bounds();
if (m_inUpdateBackingStoreState)
return;
@@ -503,36 +307,21 @@ void DrawingAreaImpl::exitAcceleratedCompositingMode()
UpdateInfo updateInfo;
if (m_isPaintingSuspended) {
- updateInfo.viewSize = m_webPage->size();
- updateInfo.deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor();
+ updateInfo.viewSize = m_webPage.size();
+ updateInfo.deviceScaleFactor = m_webPage.corePage()->deviceScaleFactor();
} else
display(updateInfo);
-#if USE(ACCELERATED_COMPOSITING)
// Send along a complete update of the page so we can paint the contents right after we exit the
// accelerated compositing mode, eliminiating flicker.
if (m_compositingAccordingToProxyMessages) {
- m_webPage->send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode(m_backingStoreStateID, updateInfo));
+ m_webPage.send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode(m_backingStoreStateID, updateInfo));
m_compositingAccordingToProxyMessages = false;
} else {
// If we left accelerated compositing mode before we sent an EnterAcceleratedCompositingMode message to the
// UI process, we still need to let it know about the new contents, so send an Update message.
- m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
- }
-#endif
-}
-
-void DrawingAreaImpl::exitAcceleratedCompositingModeSoon()
-{
- if (m_layerTreeStateIsFrozen) {
- m_wantsToExitAcceleratedCompositingMode = true;
- return;
+ m_webPage.send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
}
-
- if (exitAcceleratedCompositingModePending())
- return;
-
- m_exitCompositingTimer.startOneShot(0);
}
void DrawingAreaImpl::scheduleDisplay()
@@ -585,7 +374,7 @@ void DrawingAreaImpl::display()
return;
}
- m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
+ m_webPage.send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
m_isWaitingForDidUpdate = true;
}
@@ -614,23 +403,24 @@ void DrawingAreaImpl::display(UpdateInfo& updateInfo)
{
ASSERT(!m_isPaintingSuspended);
ASSERT(!m_layerTreeHost);
- ASSERT(!m_webPage->size().isEmpty());
+ ASSERT(!m_webPage.size().isEmpty());
- m_webPage->layoutIfNeeded();
+ m_webPage.layoutIfNeeded();
// The layout may have put the page into accelerated compositing mode. If the LayerTreeHost is
// in charge of displaying, we have nothing more to do.
if (m_layerTreeHost)
return;
- updateInfo.viewSize = m_webPage->size();
- updateInfo.deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor();
+ updateInfo.viewSize = m_webPage.size();
+ updateInfo.deviceScaleFactor = m_webPage.corePage()->deviceScaleFactor();
- IntRect bounds = m_dirtyRegion.bounds();
- ASSERT(m_webPage->bounds().contains(bounds));
+ // Always render the whole page when we don't render the background.
+ IntRect bounds = m_webPage.drawsBackground() ? m_dirtyRegion.bounds() : m_webPage.bounds();
+ ASSERT(m_webPage.bounds().contains(bounds));
IntSize bitmapSize = bounds.size();
- float deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor();
+ float deviceScaleFactor = m_webPage.corePage()->deviceScaleFactor();
bitmapSize.scale(deviceScaleFactor);
RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bitmapSize, ShareableBitmap::SupportsAlpha);
if (!bitmap)
@@ -639,12 +429,16 @@ void DrawingAreaImpl::display(UpdateInfo& updateInfo)
if (!bitmap->createHandle(updateInfo.bitmapHandle))
return;
- Vector<IntRect> rects = m_dirtyRegion.rects();
+ Vector<IntRect> rects;
+ if (m_webPage.drawsBackground()) {
+ rects = m_dirtyRegion.rects();
- if (shouldPaintBoundsRect(bounds, rects)) {
- rects.clear();
+ if (shouldPaintBoundsRect(bounds, rects)) {
+ rects.clear();
+ rects.append(bounds);
+ }
+ } else
rects.append(bounds);
- }
updateInfo.scrollRect = m_scrollRect;
updateInfo.scrollOffset = m_scrollOffset;
@@ -660,17 +454,9 @@ void DrawingAreaImpl::display(UpdateInfo& updateInfo)
graphicsContext->translate(-bounds.x(), -bounds.y());
- for (size_t i = 0; i < rects.size(); ++i) {
- m_webPage->drawRect(*graphicsContext, rects[i]);
-
- if (m_webPage->hasPageOverlay()) {
- PageOverlayList& pageOverlays = m_webPage->pageOverlays();
- PageOverlayList::iterator end = pageOverlays.end();
- for (PageOverlayList::iterator it = pageOverlays.begin(); it != end; ++it)
- m_webPage->drawPageOverlay(it->get(), *graphicsContext, rects[i]);
- }
-
- updateInfo.updateRects.append(rects[i]);
+ for (const auto& rect : rects) {
+ m_webPage.drawRect(*graphicsContext, rect);
+ updateInfo.updateRects.append(rect);
}
// Layout can trigger more calls to setNeedsDisplay and we don't want to process them
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h
index f327e2074..3fce0a7a7 100644
--- a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h
@@ -23,16 +23,13 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DrawingAreaImpl_h
-#define DrawingAreaImpl_h
+#pragma once
-#include "DrawingArea.h"
-#include "LayerTreeHost.h"
+#include "AcceleratedDrawingArea.h"
#include <WebCore/Region.h>
-#include <wtf/RunLoop.h>
namespace WebCore {
- class GraphicsContext;
+class GraphicsContext;
}
namespace WebKit {
@@ -40,100 +37,52 @@ namespace WebKit {
class ShareableBitmap;
class UpdateInfo;
-class DrawingAreaImpl : public DrawingArea {
+class DrawingAreaImpl final : public AcceleratedDrawingArea {
public:
- DrawingAreaImpl(WebPage*, const WebPageCreationParameters&);
+ DrawingAreaImpl(WebPage&, const WebPageCreationParameters&);
virtual ~DrawingAreaImpl();
- void layerHostDidFlushLayers();
-
private:
// DrawingArea
- virtual void setNeedsDisplay() override;
- virtual void setNeedsDisplayInRect(const WebCore::IntRect&) override;
- virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta);
- virtual void pageBackgroundTransparencyChanged() override;
- virtual void setLayerTreeStateIsFrozen(bool);
- virtual bool layerTreeStateIsFrozen() const { return m_layerTreeStateIsFrozen; }
- virtual LayerTreeHost* layerTreeHost() const { return m_layerTreeHost.get(); }
- virtual void forceRepaint();
- virtual bool forceRepaintAsync(uint64_t callbackID);
-
- virtual void didInstallPageOverlay(PageOverlay*);
- virtual void didUninstallPageOverlay(PageOverlay*);
- virtual void setPageOverlayNeedsDisplay(PageOverlay*, const WebCore::IntRect&);
- virtual void setPageOverlayOpacity(PageOverlay*, float);
-
- virtual void setPaintingEnabled(bool);
- virtual void updatePreferences(const WebPreferencesStore&) override;
-
-#if USE(ACCELERATED_COMPOSITING)
- virtual WebCore::GraphicsLayerFactory* graphicsLayerFactory() override;
- virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) override;
- virtual void scheduleCompositingLayerFlush() override;
-#endif
+ void setNeedsDisplay() override;
+ void setNeedsDisplayInRect(const WebCore::IntRect&) override;
+ void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta) override;
+ void forceRepaint() override;
+
+ void mainFrameContentSizeChanged(const WebCore::IntSize&) override;
+ void updatePreferences(const WebPreferencesStore&) override;
+
+ void setRootCompositingLayer(WebCore::GraphicsLayer*) override;
// IPC message handlers.
- virtual void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, float deviceScaleFactor, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset);
- virtual void didUpdate();
- virtual void suspendPainting();
- virtual void resumePainting();
-
- void sendDidUpdateBackingStoreState();
-
- void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*);
- void exitAcceleratedCompositingModeSoon();
- bool exitAcceleratedCompositingModePending() const { return m_exitCompositingTimer.isActive(); }
- void exitAcceleratedCompositingMode();
+ void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, float deviceScaleFactor, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset) override;
+ void didUpdate() override;
+
+ // AcceleratedDrawingArea
+ void suspendPainting() override;
+ void sendDidUpdateBackingStoreState() override;
+ void didUpdateBackingStoreState() override;
+
+ void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*) override;
+ void exitAcceleratedCompositingMode() override;
void scheduleDisplay();
void displayTimerFired();
void display();
void display(UpdateInfo&);
- uint64_t m_backingStoreStateID;
-
WebCore::Region m_dirtyRegion;
WebCore::IntRect m_scrollRect;
WebCore::IntSize m_scrollOffset;
- // Whether painting is enabled. If painting is disabled, any calls to setNeedsDisplay and scroll are ignored.
- bool m_isPaintingEnabled;
-
- // Whether we're currently processing an UpdateBackingStoreState message.
- bool m_inUpdateBackingStoreState;
-
- // When true, we should send an UpdateBackingStoreState message instead of any other messages
- // we normally send to the UI process.
- bool m_shouldSendDidUpdateBackingStoreState;
-
// Whether we're waiting for a DidUpdate message. Used for throttling paints so that the
// web process won't paint more frequent than the UI process can handle.
- bool m_isWaitingForDidUpdate;
-
- // True between sending the 'enter compositing' messages, and the 'exit compositing' message.
- bool m_compositingAccordingToProxyMessages;
-
- // When true, we maintain the layer tree in its current state by not leaving accelerated compositing mode
- // and not scheduling layer flushes.
- bool m_layerTreeStateIsFrozen;
+ bool m_isWaitingForDidUpdate { false };
- // True when we were asked to exit accelerated compositing mode but couldn't because layer tree
- // state was frozen.
- bool m_wantsToExitAcceleratedCompositingMode;
-
- // Whether painting is suspended. We'll still keep track of the dirty region but we
- // won't paint until painting has resumed again.
- bool m_isPaintingSuspended;
- bool m_alwaysUseCompositing;
+ bool m_alwaysUseCompositing {false };
+ bool m_forceRepaintAfterBackingStoreStateUpdate { false };
RunLoop::Timer<DrawingAreaImpl> m_displayTimer;
- RunLoop::Timer<DrawingAreaImpl> m_exitCompositingTimer;
-
- // The layer tree host that handles accelerated compositing.
- RefPtr<LayerTreeHost> m_layerTreeHost;
};
} // namespace WebKit
-
-#endif // DrawingAreaImpl_h
diff --git a/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp
deleted file mode 100644
index 38ec1dc81..000000000
--- a/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
- */
-
-#include "config.h"
-#include "EncoderAdapter.h"
-
-#include "DataReference.h"
-#include "WebCoreArgumentCoders.h"
-#include <wtf/text/WTFString.h>
-
-namespace WebKit {
-
-EncoderAdapter::EncoderAdapter()
-{
- // Keep format compatibility by decoding an unused uint64_t value
- // that used to be encoded by the argument encoder.
- m_encoder << static_cast<uint64_t>(0);
-}
-
-IPC::DataReference EncoderAdapter::dataReference() const
-{
- return IPC::DataReference(m_encoder.buffer(), m_encoder.bufferSize());
-}
-
-void EncoderAdapter::encodeBytes(const uint8_t* bytes, size_t size)
-{
- m_encoder << IPC::DataReference(bytes, size);
-}
-
-void EncoderAdapter::encodeBool(bool value)
-{
- m_encoder << value;
-}
-
-void EncoderAdapter::encodeUInt16(uint16_t value)
-{
- m_encoder << value;
-}
-
-void EncoderAdapter::encodeUInt32(uint32_t value)
-{
- m_encoder << value;
-}
-
-void EncoderAdapter::encodeUInt64(uint64_t value)
-{
- m_encoder << value;
-}
-
-void EncoderAdapter::encodeInt32(int32_t value)
-{
- m_encoder << value;
-}
-
-void EncoderAdapter::encodeInt64(int64_t value)
-{
- m_encoder << value;
-}
-
-void EncoderAdapter::encodeFloat(float value)
-{
- m_encoder << value;
-}
-
-void EncoderAdapter::encodeDouble(double value)
-{
- m_encoder << value;
-}
-
-void EncoderAdapter::encodeString(const String& value)
-{
- // This mimics the IPC binary encoding of Strings prior to r88886.
- // Whenever the IPC binary encoding changes, we'll have to "undo" the changes here.
- // FIXME: We shouldn't use the IPC binary encoding format for history,
- // and we should come up with a migration strategy so we can actually bump the version number
- // without breaking encoding/decoding of the history tree.
-
- // Special case the null string.
- if (value.isNull()) {
- m_encoder << std::numeric_limits<uint32_t>::max();
- return;
- }
-
- uint32_t length = value.length();
- m_encoder << length;
-
- uint64_t lengthInBytes = length * sizeof(UChar);
- m_encoder << lengthInBytes;
- m_encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(value.deprecatedCharacters()), length * sizeof(UChar), alignof(UChar));
-}
-
-}
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
index 2dc475856..1f222658c 100644
--- a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2014-2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@
#include "WebPageProxyMessages.h"
#include "WebProcess.h"
#include <WebCore/Page.h>
+#include <WebCore/WheelEventTestTrigger.h>
#include <wtf/MainThread.h>
#include <wtf/RunLoop.h>
@@ -46,13 +47,14 @@ using namespace WebCore;
namespace WebKit {
-PassRefPtr<EventDispatcher> EventDispatcher::create()
+Ref<EventDispatcher> EventDispatcher::create()
{
- return adoptRef(new EventDispatcher);
+ return adoptRef(*new EventDispatcher);
}
EventDispatcher::EventDispatcher()
- : m_queue(WorkQueue::create("com.apple.WebKit.EventDispatcher"))
+ : m_queue(WorkQueue::create("com.apple.WebKit.EventDispatcher", WorkQueue::Type::Serial, WorkQueue::QOS::UserInteractive))
+ , m_recentWheelEventDeltaFilter(WheelEventDeltaFilter::create())
{
}
@@ -63,18 +65,18 @@ EventDispatcher::~EventDispatcher()
#if ENABLE(ASYNC_SCROLLING)
void EventDispatcher::addScrollingTreeForPage(WebPage* webPage)
{
- MutexLocker locker(m_scrollingTreesMutex);
+ LockHolder locker(m_scrollingTreesMutex);
ASSERT(webPage->corePage()->scrollingCoordinator());
ASSERT(!m_scrollingTrees.contains(webPage->pageID()));
- AsyncScrollingCoordinator* scrollingCoordinator = toAsyncScrollingCoordinator(webPage->corePage()->scrollingCoordinator());
- m_scrollingTrees.set(webPage->pageID(), toThreadedScrollingTree(scrollingCoordinator->scrollingTree()));
+ AsyncScrollingCoordinator& scrollingCoordinator = downcast<AsyncScrollingCoordinator>(*webPage->corePage()->scrollingCoordinator());
+ m_scrollingTrees.set(webPage->pageID(), downcast<ThreadedScrollingTree>(scrollingCoordinator.scrollingTree()));
}
void EventDispatcher::removeScrollingTreeForPage(WebPage* webPage)
{
- MutexLocker locker(m_scrollingTreesMutex);
+ LockHolder locker(m_scrollingTreesMutex);
ASSERT(m_scrollingTrees.contains(webPage->pageID()));
m_scrollingTrees.remove(webPage->pageID());
@@ -88,19 +90,42 @@ void EventDispatcher::initializeConnection(IPC::Connection* connection)
void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent, bool canRubberBandAtLeft, bool canRubberBandAtRight, bool canRubberBandAtTop, bool canRubberBandAtBottom)
{
-#if ENABLE(ASYNC_SCROLLING)
- MutexLocker locker(m_scrollingTreesMutex);
- if (ThreadedScrollingTree* scrollingTree = m_scrollingTrees.get(pageID)) {
- PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
+ PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
+
+#if PLATFORM(COCOA)
+ switch (wheelEvent.phase()) {
+ case PlatformWheelEventPhaseBegan:
+ m_recentWheelEventDeltaFilter->beginFilteringDeltas();
+ break;
+ case PlatformWheelEventPhaseEnded:
+ m_recentWheelEventDeltaFilter->endFilteringDeltas();
+ break;
+ default:
+ break;
+ }
+
+ if (m_recentWheelEventDeltaFilter->isFilteringDeltas()) {
+ m_recentWheelEventDeltaFilter->updateFromDelta(FloatSize(platformWheelEvent.deltaX(), platformWheelEvent.deltaY()));
+ FloatSize filteredDelta = m_recentWheelEventDeltaFilter->filteredDelta();
+ platformWheelEvent = platformWheelEvent.copyWithDeltasAndVelocity(filteredDelta.width(), filteredDelta.height(), m_recentWheelEventDeltaFilter->filteredVelocity());
+ }
+#endif
+#if ENABLE(ASYNC_SCROLLING)
+ LockHolder locker(m_scrollingTreesMutex);
+ if (RefPtr<ThreadedScrollingTree> scrollingTree = m_scrollingTrees.get(pageID)) {
// FIXME: It's pretty horrible that we're updating the back/forward state here.
// WebCore should always know the current state and know when it changes so the
// scrolling tree can be notified.
// We only need to do this at the beginning of the gesture.
- if (platformWheelEvent.phase() == PlatformWheelEventPhaseBegan)
- ScrollingThread::dispatch(bind(&ThreadedScrollingTree::setCanRubberBandState, scrollingTree, canRubberBandAtLeft, canRubberBandAtRight, canRubberBandAtTop, canRubberBandAtBottom));
+ if (platformWheelEvent.phase() == PlatformWheelEventPhaseBegan) {
+ ScrollingThread::dispatch([scrollingTree, canRubberBandAtLeft, canRubberBandAtRight, canRubberBandAtTop, canRubberBandAtBottom] {
+ scrollingTree->setCanRubberBandState(canRubberBandAtLeft, canRubberBandAtRight, canRubberBandAtTop, canRubberBandAtBottom);
+ });
+ }
ScrollingTree::EventResult result = scrollingTree->tryToHandleWheelEvent(platformWheelEvent);
+
if (result == ScrollingTree::DidHandleEvent || result == ScrollingTree::DidNotHandleEvent) {
sendDidReceiveEvent(pageID, wheelEvent, result == ScrollingTree::DidHandleEvent);
return;
@@ -113,24 +138,105 @@ void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEven
UNUSED_PARAM(canRubberBandAtBottom);
#endif
- RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchWheelEvent, this, pageID, wheelEvent));
+ RunLoop::main().dispatch([protectedThis = makeRef(*this), pageID, wheelEvent]() mutable {
+ protectedThis->dispatchWheelEvent(pageID, wheelEvent);
+ });
+}
+
+#if ENABLE(MAC_GESTURE_EVENTS)
+void EventDispatcher::gestureEvent(uint64_t pageID, const WebKit::WebGestureEvent& gestureEvent)
+{
+ RunLoop::main().dispatch([protectedThis = makeRef(*this), pageID, gestureEvent]() mutable {
+ protectedThis->dispatchGestureEvent(pageID, gestureEvent);
+ });
+}
+#endif
+
+#if ENABLE(IOS_TOUCH_EVENTS)
+void EventDispatcher::clearQueuedTouchEventsForPage(const WebPage& webPage)
+{
+ LockHolder locker(&m_touchEventsLock);
+ m_touchEvents.remove(webPage.pageID());
+}
+
+void EventDispatcher::getQueuedTouchEventsForPage(const WebPage& webPage, TouchEventQueue& destinationQueue)
+{
+ LockHolder locker(&m_touchEventsLock);
+ destinationQueue = m_touchEvents.take(webPage.pageID());
+}
+
+void EventDispatcher::touchEvent(uint64_t pageID, const WebKit::WebTouchEvent& touchEvent)
+{
+ bool updateListWasEmpty;
+ {
+ LockHolder locker(&m_touchEventsLock);
+ updateListWasEmpty = m_touchEvents.isEmpty();
+ auto addResult = m_touchEvents.add(pageID, TouchEventQueue());
+ if (addResult.isNewEntry)
+ addResult.iterator->value.append(touchEvent);
+ else {
+ TouchEventQueue& queuedEvents = addResult.iterator->value;
+ ASSERT(!queuedEvents.isEmpty());
+ const WebTouchEvent& lastTouchEvent = queuedEvents.last();
+
+ // Coalesce touch move events.
+ if (touchEvent.type() == WebEvent::TouchMove && lastTouchEvent.type() == WebEvent::TouchMove)
+ queuedEvents.last() = touchEvent;
+ else
+ queuedEvents.append(touchEvent);
+ }
+ }
+
+ if (updateListWasEmpty) {
+ RunLoop::main().dispatch([protectedThis = makeRef(*this)]() mutable {
+ protectedThis->dispatchTouchEvents();
+ });
+ }
+}
+
+void EventDispatcher::dispatchTouchEvents()
+{
+ HashMap<uint64_t, TouchEventQueue> localCopy;
+ {
+ LockHolder locker(&m_touchEventsLock);
+ localCopy.swap(m_touchEvents);
+ }
+
+ for (auto& slot : localCopy) {
+ if (WebPage* webPage = WebProcess::singleton().webPage(slot.key))
+ webPage->dispatchAsynchronousTouchEvents(slot.value);
+ }
}
+#endif
void EventDispatcher::dispatchWheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent)
{
- ASSERT(isMainThread());
+ ASSERT(RunLoop::isMain());
- WebPage* webPage = WebProcess::shared().webPage(pageID);
+ WebPage* webPage = WebProcess::singleton().webPage(pageID);
if (!webPage)
return;
webPage->wheelEvent(wheelEvent);
}
+#if ENABLE(MAC_GESTURE_EVENTS)
+void EventDispatcher::dispatchGestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent)
+{
+ ASSERT(RunLoop::isMain());
+
+ WebPage* webPage = WebProcess::singleton().webPage(pageID);
+ if (!webPage)
+ return;
+
+ webPage->gestureEvent(gestureEvent);
+}
+#endif
+
#if ENABLE(ASYNC_SCROLLING)
void EventDispatcher::sendDidReceiveEvent(uint64_t pageID, const WebEvent& event, bool didHandleEvent)
{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(event.type()), didHandleEvent), pageID);
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(event.type()), didHandleEvent), pageID);
}
#endif
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h
index b9998f17e..1d477877e 100644
--- a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h
+++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,11 +27,20 @@
#define EventDispatcher_h
#include "Connection.h"
+
+#include "WebEvent.h"
+#include <WebCore/WheelEventDeltaFilter.h>
+#include <memory>
#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
#include <wtf/ThreadingPrimitives.h>
+#if ENABLE(MAC_GESTURE_EVENTS)
+#include "WebGestureEvent.h"
+#endif
+
namespace WebCore {
class ThreadedScrollingTree;
}
@@ -44,7 +53,7 @@ class WebWheelEvent;
class EventDispatcher : public IPC::Connection::WorkQueueMessageReceiver {
public:
- static PassRefPtr<EventDispatcher> create();
+ static Ref<EventDispatcher> create();
~EventDispatcher();
#if ENABLE(ASYNC_SCROLLING)
@@ -52,30 +61,55 @@ public:
void removeScrollingTreeForPage(WebPage*);
#endif
+#if ENABLE(IOS_TOUCH_EVENTS)
+ typedef Vector<WebTouchEvent, 1> TouchEventQueue;
+
+ void clearQueuedTouchEventsForPage(const WebPage&);
+ void getQueuedTouchEventsForPage(const WebPage&, TouchEventQueue&);
+#endif
+
void initializeConnection(IPC::Connection*);
private:
EventDispatcher();
// IPC::Connection::WorkQueueMessageReceiver.
- virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override;
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
// Message handlers
void wheelEvent(uint64_t pageID, const WebWheelEvent&, bool canRubberBandAtLeft, bool canRubberBandAtRight, bool canRubberBandAtTop, bool canRubberBandAtBottom);
+#if ENABLE(IOS_TOUCH_EVENTS)
+ void touchEvent(uint64_t pageID, const WebTouchEvent&);
+#endif
+#if ENABLE(MAC_GESTURE_EVENTS)
+ void gestureEvent(uint64_t pageID, const WebGestureEvent&);
+#endif
+
// This is called on the main thread.
void dispatchWheelEvent(uint64_t pageID, const WebWheelEvent&);
+#if ENABLE(IOS_TOUCH_EVENTS)
+ void dispatchTouchEvents();
+#endif
+#if ENABLE(MAC_GESTURE_EVENTS)
+ void dispatchGestureEvent(uint64_t pageID, const WebGestureEvent&);
+#endif
#if ENABLE(ASYNC_SCROLLING)
void sendDidReceiveEvent(uint64_t pageID, const WebEvent&, bool didHandleEvent);
#endif
- RefPtr<WorkQueue> m_queue;
+ Ref<WorkQueue> m_queue;
#if ENABLE(ASYNC_SCROLLING)
- Mutex m_scrollingTreesMutex;
+ Lock m_scrollingTreesMutex;
HashMap<uint64_t, RefPtr<WebCore::ThreadedScrollingTree>> m_scrollingTrees;
#endif
+ std::unique_ptr<WebCore::WheelEventDeltaFilter> m_recentWheelEventDeltaFilter;
+#if ENABLE(IOS_TOUCH_EVENTS)
+ Lock m_touchEventsLock;
+ HashMap<uint64_t, TouchEventQueue> m_touchEvents;
+#endif
};
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in
index dbcf4bd5c..5e1543c98 100644
--- a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in
+++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in
@@ -22,4 +22,10 @@
messages -> EventDispatcher {
WheelEvent(uint64_t pageID, WebKit::WebWheelEvent event, bool canRubberBandAtLeft, bool canRubberBandAtRight, bool canRubberBandAtTop, bool canRubberBandAtBottom)
+#if ENABLE(IOS_TOUCH_EVENTS)
+ TouchEvent(uint64_t pageID, WebKit::WebTouchEvent event)
+#endif
+#if ENABLE(MAC_GESTURE_EVENTS)
+ GestureEvent(uint64_t pageID, WebKit::WebGestureEvent event)
+#endif
}
diff --git a/Source/WebKit2/WebProcess/WebPage/FindController.cpp b/Source/WebKit2/WebProcess/WebPage/FindController.cpp
index ccd03cc92..33032c172 100644
--- a/Source/WebKit2/WebProcess/WebPage/FindController.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/FindController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
#include "config.h"
#include "FindController.h"
+#include "DrawingArea.h"
#include "PluginView.h"
#include "ShareableBitmap.h"
#include "WKPage.h"
@@ -39,8 +40,14 @@
#include <WebCore/GraphicsContext.h>
#include <WebCore/MainFrame.h>
#include <WebCore/Page.h>
+#include <WebCore/PageOverlayController.h>
+#include <WebCore/PlatformMouseEvent.h>
#include <WebCore/PluginDocument.h>
+#if PLATFORM(COCOA)
+#include <WebCore/TextIndicatorWindow.h>
+#endif
+
using namespace WebCore;
namespace WebKit {
@@ -56,8 +63,9 @@ static WebCore::FindOptions core(FindOptions options)
FindController::FindController(WebPage* webPage)
: m_webPage(webPage)
- , m_findPageOverlay(0)
+ , m_findPageOverlay(nullptr)
, m_isShowingFindIndicator(false)
+ , m_foundStringMatchIndex(-1)
{
}
@@ -122,19 +130,29 @@ void FindController::updateFindUIAfterPageScroll(bool found, const String& strin
selectedFrame->selection().clear();
hideFindIndicator();
+ didFailToFindString();
m_webPage->send(Messages::WebPageProxy::DidFailToFindString(string));
} else {
shouldShowOverlay = options & FindOptionsShowOverlay;
bool shouldShowHighlight = options & FindOptionsShowHighlight;
+ bool shouldDetermineMatchIndex = options & FindOptionsDetermineMatchIndex;
unsigned matchCount = 1;
+ if (shouldDetermineMatchIndex) {
+ if (pluginView)
+ matchCount = pluginView->countFindMatches(string, core(options), maxMatchCount + 1);
+ else
+ matchCount = m_webPage->corePage()->countFindMatches(string, core(options), maxMatchCount + 1);
+ }
+
if (shouldShowOverlay || shouldShowHighlight) {
if (maxMatchCount == std::numeric_limits<unsigned>::max())
--maxMatchCount;
if (pluginView) {
- matchCount = pluginView->countFindMatches(string, core(options), maxMatchCount + 1);
+ if (!shouldDetermineMatchIndex)
+ matchCount = pluginView->countFindMatches(string, core(options), maxMatchCount + 1);
shouldShowOverlay = false;
} else {
m_webPage->corePage()->unmarkAllTextMatches();
@@ -147,39 +165,93 @@ void FindController::updateFindUIAfterPageScroll(bool found, const String& strin
matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount);
}
}
+ if (matchCount == static_cast<unsigned>(kWKMoreThanMaximumMatchCount))
+ m_foundStringMatchIndex = -1;
+ else {
+ if (m_foundStringMatchIndex < 0)
+ m_foundStringMatchIndex += matchCount;
+ if (m_foundStringMatchIndex >= (int) matchCount)
+ m_foundStringMatchIndex -= matchCount;
+ }
- m_webPage->send(Messages::WebPageProxy::DidFindString(string, matchCount));
+ m_findMatches.clear();
+ Vector<IntRect> matchRects;
+ if (auto range = m_webPage->corePage()->selection().firstRange()) {
+ range->absoluteTextRects(matchRects);
+ m_findMatches.append(range);
+ }
+
+ m_webPage->send(Messages::WebPageProxy::DidFindString(string, matchRects, matchCount, m_foundStringMatchIndex));
- if (!(options & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay))
+ if (!(options & FindOptionsShowFindIndicator) || !selectedFrame || !updateFindIndicator(*selectedFrame, shouldShowOverlay))
hideFindIndicator();
}
if (!shouldShowOverlay) {
if (m_findPageOverlay)
- m_webPage->uninstallPageOverlay(m_findPageOverlay, true);
+ m_webPage->mainFrame()->pageOverlayController().uninstallPageOverlay(*m_findPageOverlay, PageOverlay::FadeMode::Fade);
} else {
if (!m_findPageOverlay) {
- RefPtr<PageOverlay> findPageOverlay = PageOverlay::create(this);
- m_findPageOverlay = findPageOverlay.get();
- m_webPage->installPageOverlay(findPageOverlay.release(), true);
- m_findPageOverlay->setNeedsDisplay();
- } else
- m_findPageOverlay->setNeedsDisplay();
+ auto findPageOverlay = PageOverlay::create(*this, PageOverlay::OverlayType::Document);
+ m_findPageOverlay = findPageOverlay.ptr();
+ m_webPage->mainFrame()->pageOverlayController().installPageOverlay(WTFMove(findPageOverlay), PageOverlay::FadeMode::Fade);
+ }
+ m_findPageOverlay->setNeedsDisplay();
}
}
void FindController::findString(const String& string, FindOptions options, unsigned maxMatchCount)
{
PluginView* pluginView = pluginViewForFrame(m_webPage->mainFrame());
-
+
+ WebCore::FindOptions coreOptions = core(options);
+
+ // iOS will reveal the selection through a different mechanism, and
+ // we need to avoid sending the non-painted selection change to the UI process
+ // so that it does not clear the selection out from under us.
+#if PLATFORM(IOS)
+ coreOptions = static_cast<FindOptions>(coreOptions | DoNotRevealSelection);
+#endif
+
+ willFindString();
+
+ bool foundStringStartsAfterSelection = false;
+ if (!pluginView) {
+ if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) {
+ FrameSelection& fs = selectedFrame->selection();
+ if (fs.selectionBounds().isEmpty()) {
+ m_findMatches.clear();
+ int indexForSelection;
+ m_webPage->corePage()->findStringMatchingRanges(string, coreOptions, maxMatchCount, m_findMatches, indexForSelection);
+ m_foundStringMatchIndex = indexForSelection;
+ foundStringStartsAfterSelection = true;
+ }
+ }
+ }
+
+ m_findMatches.clear();
+
bool found;
-
if (pluginView)
- found = pluginView->findString(string, core(options), maxMatchCount);
+ found = pluginView->findString(string, coreOptions, maxMatchCount);
else
- found = m_webPage->corePage()->findString(string, core(options));
+ found = m_webPage->corePage()->findString(string, coreOptions);
- m_webPage->drawingArea()->dispatchAfterEnsuringUpdatedScrollPosition(WTF::bind(&FindController::updateFindUIAfterPageScroll, this, found, string, options, maxMatchCount));
+ if (found) {
+ didFindString();
+
+ if (!foundStringStartsAfterSelection) {
+ if (options & FindOptionsBackwards)
+ m_foundStringMatchIndex--;
+ else
+ m_foundStringMatchIndex++;
+ }
+ }
+
+ RefPtr<WebPage> protectedWebPage = m_webPage;
+ m_webPage->drawingArea()->dispatchAfterEnsuringUpdatedScrollPosition([protectedWebPage, found, string, options, maxMatchCount] () {
+ protectedWebPage->findController().updateFindUIAfterPageScroll(found, string, options, maxMatchCount);
+ });
}
void FindController::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
@@ -187,70 +259,39 @@ void FindController::findStringMatches(const String& string, FindOptions options
m_findMatches.clear();
int indexForSelection;
- m_webPage->corePage()->findStringMatchingRanges(string, core(options), maxMatchCount, &m_findMatches, indexForSelection);
+ m_webPage->corePage()->findStringMatchingRanges(string, core(options), maxMatchCount, m_findMatches, indexForSelection);
Vector<Vector<IntRect>> matchRects;
for (size_t i = 0; i < m_findMatches.size(); ++i) {
Vector<IntRect> rects;
- m_findMatches[i]->textRects(rects);
- matchRects.append(rects);
+ m_findMatches[i]->absoluteTextRects(rects);
+ matchRects.append(WTFMove(rects));
}
m_webPage->send(Messages::WebPageProxy::DidFindStringMatches(string, matchRects, indexForSelection));
}
-bool FindController::getFindIndicatorBitmapAndRect(Frame* frame, ShareableBitmap::Handle& handle, IntRect& selectionRect)
-{
- selectionRect = enclosingIntRect(frame->selection().bounds());
-
- // Selection rect can be empty for matches that are currently obscured from view.
- if (selectionRect.isEmpty())
- return false;
-
- IntSize backingStoreSize = selectionRect.size();
- backingStoreSize.scale(m_webPage->corePage()->deviceScaleFactor());
-
- // Create a backing store and paint the find indicator text into it.
- RefPtr<ShareableBitmap> findIndicatorTextBackingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha);
- if (!findIndicatorTextBackingStore)
- return false;
-
- auto graphicsContext = findIndicatorTextBackingStore->createGraphicsContext();
- graphicsContext->scale(FloatSize(m_webPage->corePage()->deviceScaleFactor(), m_webPage->corePage()->deviceScaleFactor()));
-
- IntRect paintRect = selectionRect;
- paintRect.move(frame->view()->frameRect().x(), frame->view()->frameRect().y());
- paintRect.move(-frame->view()->scrollOffset());
-
- graphicsContext->translate(-paintRect.x(), -paintRect.y());
- frame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorForceBlackText | PaintBehaviorFlattenCompositingLayers);
- frame->document()->updateLayout();
-
- frame->view()->paint(graphicsContext.get(), paintRect);
- frame->view()->setPaintBehavior(PaintBehaviorNormal);
-
- if (!findIndicatorTextBackingStore->createHandle(handle))
- return false;
- return true;
-}
-
void FindController::getImageForFindMatch(uint32_t matchIndex)
{
if (matchIndex >= m_findMatches.size())
return;
- Frame* frame = m_findMatches[matchIndex]->startContainer()->document().frame();
+ Frame* frame = m_findMatches[matchIndex]->startContainer().document().frame();
if (!frame)
return;
VisibleSelection oldSelection = frame->selection().selection();
- frame->selection().setSelection(VisibleSelection(m_findMatches[matchIndex].get()));
+ frame->selection().setSelection(VisibleSelection(*m_findMatches[matchIndex]));
- IntRect selectionRect;
- ShareableBitmap::Handle handle;
- getFindIndicatorBitmapAndRect(frame, handle, selectionRect);
+ RefPtr<ShareableBitmap> selectionSnapshot = WebFrame::fromCoreFrame(*frame)->createSelectionSnapshot();
frame->selection().setSelection(oldSelection);
+ if (!selectionSnapshot)
+ return;
+
+ ShareableBitmap::Handle handle;
+ selectionSnapshot->createHandle(handle);
+
if (handle.isNull())
return;
@@ -261,17 +302,17 @@ void FindController::selectFindMatch(uint32_t matchIndex)
{
if (matchIndex >= m_findMatches.size())
return;
- Frame* frame = m_findMatches[matchIndex]->startContainer()->document().frame();
+ Frame* frame = m_findMatches[matchIndex]->startContainer().document().frame();
if (!frame)
return;
- frame->selection().setSelection(VisibleSelection(m_findMatches[matchIndex].get()));
+ frame->selection().setSelection(VisibleSelection(*m_findMatches[matchIndex]));
}
void FindController::hideFindUI()
{
m_findMatches.clear();
if (m_findPageOverlay)
- m_webPage->uninstallPageOverlay(m_findPageOverlay, true);
+ m_webPage->mainFrame()->pageOverlayController().uninstallPageOverlay(*m_findPageOverlay, PageOverlay::FadeMode::Fade);
PluginView* pluginView = pluginViewForFrame(m_webPage->mainFrame());
@@ -283,34 +324,18 @@ void FindController::hideFindUI()
hideFindIndicator();
}
-bool FindController::updateFindIndicator(Frame* selectedFrame, bool isShowingOverlay, bool shouldAnimate)
-{
- if (!selectedFrame)
- return false;
+#if !PLATFORM(IOS)
- IntRect selectionRect;
- ShareableBitmap::Handle handle;
- if (!getFindIndicatorBitmapAndRect(selectedFrame, handle, selectionRect))
+bool FindController::updateFindIndicator(Frame& selectedFrame, bool isShowingOverlay, bool shouldAnimate)
+{
+ RefPtr<TextIndicator> indicator = TextIndicator::createWithSelectionInFrame(selectedFrame, TextIndicatorOptionIncludeMarginIfRangeMatchesSelection, shouldAnimate ? TextIndicatorPresentationTransition::Bounce : TextIndicatorPresentationTransition::None);
+ if (!indicator)
return false;
- // We want the selection rect in window coordinates.
- IntRect selectionRectInWindowCoordinates = selectedFrame->view()->contentsToWindow(selectionRect);
-
- Vector<FloatRect> textRects;
- selectedFrame->selection().getClippedVisibleTextRectangles(textRects);
-
- // We want the text rects in selection rect coordinates.
- Vector<FloatRect> textRectsInSelectionRectCoordinates;
-
- for (size_t i = 0; i < textRects.size(); ++i) {
- IntRect textRectInSelectionRectCoordinates = selectedFrame->view()->contentsToWindow(enclosingIntRect(textRects[i]));
- textRectInSelectionRectCoordinates.move(-selectionRectInWindowCoordinates.x(), -selectionRectInWindowCoordinates.y());
-
- textRectsInSelectionRectCoordinates.append(textRectInSelectionRectCoordinates);
- }
-
- m_webPage->send(Messages::WebPageProxy::SetFindIndicator(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, m_webPage->corePage()->deviceScaleFactor(), handle, !isShowingOverlay, shouldAnimate));
- m_findIndicatorRect = selectionRectInWindowCoordinates;
+ m_findIndicatorRect = enclosingIntRect(indicator->selectionRectInRootViewCoordinates());
+#if PLATFORM(COCOA)
+ m_webPage->send(Messages::WebPageProxy::SetTextIndicator(indicator->data(), static_cast<uint64_t>(isShowingOverlay ? TextIndicatorWindowLifetime::Permanent : TextIndicatorWindowLifetime::Temporary)));
+#endif
m_isShowingFindIndicator = true;
return true;
@@ -321,15 +346,34 @@ void FindController::hideFindIndicator()
if (!m_isShowingFindIndicator)
return;
- ShareableBitmap::Handle handle;
- m_webPage->send(Messages::WebPageProxy::SetFindIndicator(FloatRect(), Vector<FloatRect>(), m_webPage->corePage()->deviceScaleFactor(), handle, false, true));
+ m_webPage->send(Messages::WebPageProxy::ClearTextIndicator());
m_isShowingFindIndicator = false;
+ m_foundStringMatchIndex = -1;
+ didHideFindIndicator();
+}
+
+void FindController::willFindString()
+{
}
+void FindController::didFindString()
+{
+}
+
+void FindController::didFailToFindString()
+{
+}
+
+void FindController::didHideFindIndicator()
+{
+}
+
+#endif
+
void FindController::showFindIndicatorInSelection()
{
Frame& selectedFrame = m_webPage->corePage()->focusController().focusedOrMainFrame();
- updateFindIndicator(&selectedFrame, false);
+ updateFindIndicator(selectedFrame, false);
}
void FindController::deviceScaleFactorDidChange()
@@ -340,106 +384,119 @@ void FindController::deviceScaleFactorDidChange()
if (!selectedFrame)
return;
- updateFindIndicator(selectedFrame, true, false);
+ updateFindIndicator(*selectedFrame, true, false);
+}
+
+void FindController::redraw()
+{
+ if (!m_isShowingFindIndicator)
+ return;
+
+ Frame* selectedFrame = frameWithSelection(m_webPage->corePage());
+ if (!selectedFrame)
+ return;
+
+ updateFindIndicator(*selectedFrame, isShowingOverlay(), false);
}
-Vector<IntRect> FindController::rectsForTextMatches()
+Vector<IntRect> FindController::rectsForTextMatchesInRect(IntRect clipRect)
{
Vector<IntRect> rects;
+ FrameView* mainFrameView = m_webPage->corePage()->mainFrame().view();
+
for (Frame* frame = &m_webPage->corePage()->mainFrame(); frame; frame = frame->tree().traverseNext()) {
Document* document = frame->document();
if (!document)
continue;
- IntRect visibleRect = frame->view()->visibleContentRect();
- Vector<IntRect> frameRects = document->markers().renderedRectsForMarkers(DocumentMarker::TextMatch);
- IntPoint frameOffset(-frame->view()->scrollOffsetRelativeToDocument().width(), -frame->view()->scrollOffsetRelativeToDocument().height());
- frameOffset = frame->view()->convertToContainingWindow(frameOffset);
+ for (FloatRect rect : document->markers().renderedRectsForMarkers(DocumentMarker::TextMatch)) {
+ if (!frame->isMainFrame())
+ rect = mainFrameView->windowToContents(frame->view()->contentsToWindow(enclosingIntRect(rect)));
+ rect.intersect(clipRect);
+
+ if (rect.isEmpty())
+ continue;
- for (Vector<IntRect>::iterator it = frameRects.begin(), end = frameRects.end(); it != end; ++it) {
- it->intersect(visibleRect);
- it->move(frameOffset.x(), frameOffset.y());
- rects.append(*it);
+ rects.append(rect);
}
}
return rects;
}
-void FindController::pageOverlayDestroyed(PageOverlay*)
+void FindController::willMoveToPage(PageOverlay&, Page* page)
{
-}
-
-void FindController::willMoveToWebPage(PageOverlay*, WebPage* webPage)
-{
- if (webPage)
+ if (page)
return;
ASSERT(m_findPageOverlay);
m_findPageOverlay = 0;
}
-void FindController::didMoveToWebPage(PageOverlay*, WebPage*)
+void FindController::didMoveToPage(PageOverlay&, Page*)
{
}
-static const float shadowOffsetX = 0.0;
-static const float shadowOffsetY = 1.0;
-static const float shadowBlurRadius = 2.0;
+const float shadowOffsetX = 0;
+const float shadowOffsetY = 0;
+const float shadowBlurRadius = 1;
+const float shadowColorAlpha = 0.5;
-static const float overlayBackgroundRed = 0.1;
-static const float overlayBackgroundGreen = 0.1;
-static const float overlayBackgroundBlue = 0.1;
-static const float overlayBackgroundAlpha = 0.25;
-
-void FindController::drawRect(PageOverlay* /*pageOverlay*/, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
+void FindController::drawRect(PageOverlay&, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
{
- Color overlayBackgroundColor(overlayBackgroundRed, overlayBackgroundGreen, overlayBackgroundBlue, overlayBackgroundAlpha);
+ const int borderWidth = 1;
+
+ Color overlayBackgroundColor(0.1f, 0.1f, 0.1f, 0.25f);
- Vector<IntRect> rects = rectsForTextMatches();
+ IntRect borderInflatedDirtyRect = dirtyRect;
+ borderInflatedDirtyRect.inflate(borderWidth);
+ Vector<IntRect> rects = rectsForTextMatchesInRect(borderInflatedDirtyRect);
// Draw the background.
- graphicsContext.fillRect(dirtyRect, overlayBackgroundColor, ColorSpaceSRGB);
+ graphicsContext.fillRect(dirtyRect, overlayBackgroundColor);
{
GraphicsContextStateSaver stateSaver(graphicsContext);
- graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color::black, ColorSpaceSRGB);
- graphicsContext.setFillColor(Color::white, ColorSpaceSRGB);
+ graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color(0.0f, 0.0f, 0.0f, shadowColorAlpha));
+ graphicsContext.setFillColor(Color::white);
// Draw white frames around the holes.
- for (size_t i = 0; i < rects.size(); ++i) {
- IntRect whiteFrameRect = rects[i];
- whiteFrameRect.inflate(1);
-
+ for (auto& rect : rects) {
+ IntRect whiteFrameRect = rect;
+ whiteFrameRect.inflate(borderWidth);
graphicsContext.fillRect(whiteFrameRect);
}
}
- graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB);
-
// Clear out the holes.
- for (size_t i = 0; i < rects.size(); ++i)
- graphicsContext.fillRect(rects[i]);
+ for (auto& rect : rects)
+ graphicsContext.clearRect(rect);
if (!m_isShowingFindIndicator)
return;
if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) {
- IntRect findIndicatorRect = selectedFrame->view()->contentsToWindow(enclosingIntRect(selectedFrame->selection().bounds()));
+ IntRect findIndicatorRect = selectedFrame->view()->contentsToRootView(enclosingIntRect(selectedFrame->selection().selectionBounds()));
if (findIndicatorRect != m_findIndicatorRect)
hideFindIndicator();
}
}
-bool FindController::mouseEvent(PageOverlay*, const WebMouseEvent& mouseEvent)
+bool FindController::mouseEvent(PageOverlay&, const PlatformMouseEvent& mouseEvent)
{
- if (mouseEvent.type() == WebEvent::MouseDown)
+ if (mouseEvent.type() == PlatformEvent::MousePressed)
hideFindUI();
return false;
}
+void FindController::didInvalidateDocumentMarkerRects()
+{
+ if (m_findPageOverlay)
+ m_findPageOverlay->setNeedsDisplay();
+}
+
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/FindController.h b/Source/WebKit2/WebProcess/WebPage/FindController.h
index af0c0a1c4..7ec0d5af8 100644
--- a/Source/WebKit2/WebProcess/WebPage/FindController.h
+++ b/Source/WebKit2/WebProcess/WebPage/FindController.h
@@ -26,24 +26,28 @@
#ifndef FindController_h
#define FindController_h
-#include "PageOverlay.h"
#include "ShareableBitmap.h"
#include "WebFindOptions.h"
#include <WebCore/IntRect.h>
+#include <WebCore/PageOverlay.h>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>
+#if PLATFORM(IOS)
+#include "FindIndicatorOverlayClientIOS.h"
+#endif
+
namespace WebCore {
- class Frame;
- class Range;
+class Frame;
+class Range;
}
namespace WebKit {
class WebPage;
-class FindController : private PageOverlay::Client {
+class FindController : private WebCore::PageOverlay::Client {
WTF_MAKE_NONCOPYABLE(FindController);
public:
@@ -63,29 +67,42 @@ public:
bool isShowingOverlay() const { return m_isShowingFindIndicator && m_findPageOverlay; }
void deviceScaleFactorDidChange();
+ void didInvalidateDocumentMarkerRects();
+
+ void redraw();
private:
// PageOverlay::Client.
- virtual void pageOverlayDestroyed(PageOverlay*);
- virtual void willMoveToWebPage(PageOverlay*, WebPage*);
- virtual void didMoveToWebPage(PageOverlay*, WebPage*);
- virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&);
- virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect);
+ void willMoveToPage(WebCore::PageOverlay&, WebCore::Page*) override;
+ void didMoveToPage(WebCore::PageOverlay&, WebCore::Page*) override;
+ bool mouseEvent(WebCore::PageOverlay&, const WebCore::PlatformMouseEvent&) override;
+ void drawRect(WebCore::PageOverlay&, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override;
- Vector<WebCore::IntRect> rectsForTextMatches();
- bool getFindIndicatorBitmapAndRect(WebCore::Frame*, ShareableBitmap::Handle&, WebCore::IntRect& selectionRect);
- bool updateFindIndicator(WebCore::Frame* selectedFrame, bool isShowingOverlay, bool shouldAnimate = true);
+ Vector<WebCore::IntRect> rectsForTextMatchesInRect(WebCore::IntRect clipRect);
+ bool updateFindIndicator(WebCore::Frame& selectedFrame, bool isShowingOverlay, bool shouldAnimate = true);
void updateFindUIAfterPageScroll(bool found, const String&, FindOptions, unsigned maxMatchCount);
+ void willFindString();
+ void didFindString();
+ void didFailToFindString();
+ void didHideFindIndicator();
+
WebPage* m_webPage;
- PageOverlay* m_findPageOverlay;
+ WebCore::PageOverlay* m_findPageOverlay;
// Whether the UI process is showing the find indicator. Note that this can be true even if
// the find indicator isn't showing, but it will never be false when it is showing.
bool m_isShowingFindIndicator;
WebCore::IntRect m_findIndicatorRect;
Vector<RefPtr<WebCore::Range>> m_findMatches;
+ // Index value is -1 if not found or if number of matches exceeds provided maximum.
+ int m_foundStringMatchIndex;
+
+#if PLATFORM(IOS)
+ RefPtr<WebCore::PageOverlay> m_findIndicatorOverlay;
+ std::unique_ptr<FindIndicatorOverlayClientIOS> m_findIndicatorOverlayClient;
+#endif
};
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp
index 593a1ca45..dd6e129fd 100644
--- a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp
@@ -24,13 +24,14 @@
*/
#include "config.h"
-#include "LayerTreeHost.h"
-#if USE(COORDINATED_GRAPHICS)
-#include "CoordinatedLayerTreeHost.h"
-#endif
+#if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
+
+#include "LayerTreeHost.h"
-#if PLATFORM(GTK) && USE(TEXTURE_MAPPER_GL)
+#if USE(COORDINATED_GRAPHICS_THREADED)
+#include "ThreadedCoordinatedLayerTreeHost.h"
+#elif PLATFORM(GTK) && USE(TEXTURE_MAPPER_GL)
#include "LayerTreeHostGtk.h"
#endif
@@ -38,25 +39,60 @@ using namespace WebCore;
namespace WebKit {
-PassRefPtr<LayerTreeHost> LayerTreeHost::create(WebPage* webPage)
+RefPtr<LayerTreeHost> LayerTreeHost::create(WebPage& webPage)
{
-#if USE(COORDINATED_GRAPHICS)
- return CoordinatedLayerTreeHost::create(webPage);
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ return ThreadedCoordinatedLayerTreeHost::create(webPage);
#elif PLATFORM(GTK) && USE(TEXTURE_MAPPER_GL)
return LayerTreeHostGtk::create(webPage);
#else
UNUSED_PARAM(webPage);
- return 0;
+ return nullptr;
#endif
}
-LayerTreeHost::LayerTreeHost(WebPage* webPage)
+LayerTreeHost::LayerTreeHost(WebPage& webPage)
: m_webPage(webPage)
{
}
LayerTreeHost::~LayerTreeHost()
{
+ ASSERT(!m_isValid);
+}
+
+void LayerTreeHost::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
+{
+ if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
+ return;
+
+ m_layerFlushSchedulingEnabled = layerFlushingEnabled;
+
+ if (m_layerFlushSchedulingEnabled) {
+ scheduleLayerFlush();
+ return;
+ }
+
+ cancelPendingLayerFlush();
+}
+
+void LayerTreeHost::pauseRendering()
+{
+ m_isSuspended = true;
+}
+
+void LayerTreeHost::resumeRendering()
+{
+ m_isSuspended = false;
+ scheduleLayerFlush();
+}
+
+void LayerTreeHost::invalidate()
+{
+ ASSERT(m_isValid);
+ m_isValid = false;
}
} // namespace WebKit
+
+#endif // USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h
index c059c4534..51af581c6 100644
--- a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h
+++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h
@@ -26,88 +26,92 @@
#ifndef LayerTreeHost_h
#define LayerTreeHost_h
+#if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
+
#include "LayerTreeContext.h"
-#include <WebCore/Color.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
namespace IPC {
class Connection;
-class MessageDecoder;
}
namespace WebCore {
-class FloatPoint;
-class FloatRect;
class IntRect;
class IntSize;
class GraphicsLayer;
class GraphicsLayerFactory;
+#if USE(COORDINATED_GRAPHICS_THREADED)
+struct ViewportAttributes;
+#endif
}
namespace WebKit {
-class PageOverlay;
-class UpdateInfo;
class WebPage;
class LayerTreeHost : public RefCounted<LayerTreeHost> {
public:
- static PassRefPtr<LayerTreeHost> create(WebPage*);
+ static RefPtr<LayerTreeHost> create(WebPage&);
virtual ~LayerTreeHost();
- static bool supportsAcceleratedCompositing();
+ const LayerTreeContext& layerTreeContext() const { return m_layerTreeContext; }
+ void setLayerFlushSchedulingEnabled(bool);
+ void setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush) { m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush; }
- virtual const LayerTreeContext& layerTreeContext() = 0;
virtual void scheduleLayerFlush() = 0;
- virtual void setLayerFlushSchedulingEnabled(bool) = 0;
- virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool) = 0;
+ virtual void cancelPendingLayerFlush() = 0;
virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) = 0;
- virtual void invalidate() = 0;
+ virtual void invalidate();
- virtual void setNonCompositedContentsNeedDisplay() = 0;
- virtual void setNonCompositedContentsNeedDisplayInRect(const WebCore::IntRect&) = 0;
- virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect) = 0;
+ virtual void setNonCompositedContentsNeedDisplay() { };
+ virtual void setNonCompositedContentsNeedDisplayInRect(const WebCore::IntRect&) { };
+ virtual void scrollNonCompositedContents(const WebCore::IntRect&) { };
virtual void forceRepaint() = 0;
virtual bool forceRepaintAsync(uint64_t /*callbackID*/) { return false; }
virtual void sizeDidChange(const WebCore::IntSize& newSize) = 0;
- virtual void deviceOrPageScaleFactorChanged() = 0;
virtual void pageBackgroundTransparencyChanged() = 0;
- virtual void didInstallPageOverlay(PageOverlay*) = 0;
- virtual void didUninstallPageOverlay(PageOverlay*) = 0;
- virtual void setPageOverlayNeedsDisplay(PageOverlay*, const WebCore::IntRect&) = 0;
- virtual void setPageOverlayOpacity(PageOverlay*, float) { }
+ virtual void pauseRendering();
+ virtual void resumeRendering();
- virtual void pauseRendering() { }
- virtual void resumeRendering() { }
+ virtual WebCore::GraphicsLayerFactory* graphicsLayerFactory() { return nullptr; }
- virtual WebCore::GraphicsLayerFactory* graphicsLayerFactory() { return 0; }
- virtual void setBackgroundColor(const WebCore::Color&) { }
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ virtual void contentsSizeChanged(const WebCore::IntSize&) { };
+ virtual void didChangeViewportAttributes(WebCore::ViewportAttributes&&) { };
+#endif
#if USE(COORDINATED_GRAPHICS)
- virtual void didReceiveCoordinatedLayerTreeHostMessage(IPC::Connection*, IPC::MessageDecoder&) = 0;
+ virtual void scheduleAnimation() = 0;
+ virtual void setIsDiscardable(bool) { };
#endif
-#if PLATFORM(MAC)
- virtual void setLayerHostingMode(LayerHostingMode) { }
+#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK)
+ virtual void setNativeSurfaceHandleForCompositing(uint64_t) { };
#endif
-#if USE(COORDINATED_GRAPHICS) && ENABLE(REQUEST_ANIMATION_FRAME)
- virtual void scheduleAnimation() = 0;
+#if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
+ virtual void deviceOrPageScaleFactorChanged() = 0;
#endif
-protected:
- explicit LayerTreeHost(WebPage*);
+ virtual void setViewOverlayRootLayer(WebCore::GraphicsLayer* viewOverlayRootLayer) { m_viewOverlayRootLayer = viewOverlayRootLayer; }
- WebPage* m_webPage;
+protected:
+ explicit LayerTreeHost(WebPage&);
+
+ WebPage& m_webPage;
+ LayerTreeContext m_layerTreeContext;
+ bool m_layerFlushSchedulingEnabled { true };
+ bool m_notifyAfterScheduledLayerFlush { false };
+ bool m_isSuspended { false };
+ bool m_isValid { true };
+ WebCore::GraphicsLayer* m_viewOverlayRootLayer { nullptr };
};
-inline bool LayerTreeHost::supportsAcceleratedCompositing()
-{
- return true;
-}
-
} // namespace WebKit
+#endif // USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
+
#endif // LayerTreeHost_h
diff --git a/Source/WebKit2/WebProcess/WebPage/PageBanner.cpp b/Source/WebKit2/WebProcess/WebPage/PageBanner.cpp
index 8dc53b745..6b2fecac7 100644
--- a/Source/WebKit2/WebProcess/WebPage/PageBanner.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/PageBanner.cpp
@@ -33,7 +33,9 @@ namespace WebKit {
PageBanner::~PageBanner()
{
+#if PLATFORM(MAC)
ASSERT(!m_webPage);
+#endif
m_client->pageBannerDestroyed(this);
}
diff --git a/Source/WebKit2/WebProcess/WebPage/PageBanner.h b/Source/WebKit2/WebProcess/WebPage/PageBanner.h
index 8d9181493..84802109d 100644
--- a/Source/WebKit2/WebProcess/WebPage/PageBanner.h
+++ b/Source/WebKit2/WebProcess/WebPage/PageBanner.h
@@ -28,7 +28,6 @@
#include "APIObject.h"
#include "WebEvent.h"
-#include <wtf/PassRefPtr.h>
#if PLATFORM(MAC)
OBJC_CLASS CALayer;
@@ -61,7 +60,7 @@ public:
};
#if PLATFORM(MAC)
- static PassRefPtr<PageBanner> create(CALayer *, int height, Client*);
+ static Ref<PageBanner> create(CALayer *, int height, Client*);
CALayer *layer();
#endif
@@ -83,14 +82,14 @@ private:
explicit PageBanner(CALayer *, int height, Client*);
#endif
- Type m_type;
Client* m_client;
- WebPage* m_webPage;
-
- bool m_mouseDownInBanner;
- bool m_isHidden;
#if PLATFORM(MAC)
+ Type m_type = NotSet;
+ WebPage* m_webPage = 0;
+ bool m_mouseDownInBanner = false;
+ bool m_isHidden = false;
+
RetainPtr<CALayer> m_layer;
int m_height;
#endif
diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp
deleted file mode 100644
index 35b982543..000000000
--- a/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
- */
-
-#include "config.h"
-#include "PageOverlay.h"
-
-#include "WebPage.h"
-#include "WebProcess.h"
-#include <WebCore/FrameView.h>
-#include <WebCore/GraphicsContext.h>
-#include <WebCore/MainFrame.h>
-#include <WebCore/Page.h>
-#include <WebCore/ScrollbarTheme.h>
-#include <wtf/CurrentTime.h>
-
-using namespace WebCore;
-
-namespace WebKit {
-
-static const double fadeAnimationDuration = 0.2;
-static const double fadeAnimationFrameRate = 30;
-
-PassRefPtr<PageOverlay> PageOverlay::create(Client* client)
-{
- return adoptRef(new PageOverlay(client));
-}
-
-PageOverlay::PageOverlay(Client* client)
- : m_client(client)
- , m_webPage(0)
- , m_fadeAnimationTimer(RunLoop::main(), this, &PageOverlay::fadeAnimationTimerFired)
- , m_fadeAnimationStartTime(0.0)
- , m_fadeAnimationDuration(fadeAnimationDuration)
- , m_fadeAnimationType(NoAnimation)
- , m_fractionFadedIn(1.0)
-{
-}
-
-PageOverlay::~PageOverlay()
-{
-}
-
-IntRect PageOverlay::bounds() const
-{
- FrameView* frameView = m_webPage->corePage()->mainFrame().view();
-
- int width = frameView->width();
- int height = frameView->height();
-
- if (!ScrollbarTheme::theme()->usesOverlayScrollbars()) {
- if (frameView->verticalScrollbar())
- width -= frameView->verticalScrollbar()->width();
- if (frameView->horizontalScrollbar())
- height -= frameView->horizontalScrollbar()->height();
- }
- return IntRect(0, 0, width, height);
-}
-
-void PageOverlay::setPage(WebPage* webPage)
-{
- m_client->willMoveToWebPage(this, webPage);
- m_webPage = webPage;
- m_client->didMoveToWebPage(this, webPage);
-
- m_fadeAnimationTimer.stop();
-}
-
-void PageOverlay::setNeedsDisplay(const IntRect& dirtyRect)
-{
- if (m_webPage) {
- m_webPage->drawingArea()->setPageOverlayOpacity(this, m_fractionFadedIn);
- m_webPage->drawingArea()->setPageOverlayNeedsDisplay(this, dirtyRect);
- }
-}
-
-void PageOverlay::setNeedsDisplay()
-{
- setNeedsDisplay(bounds());
-}
-
-void PageOverlay::drawRect(GraphicsContext& graphicsContext, const IntRect& dirtyRect)
-{
- // If the dirty rect is outside the bounds, ignore it.
- IntRect paintRect = intersection(dirtyRect, bounds());
- if (paintRect.isEmpty())
- return;
-
- GraphicsContextStateSaver stateSaver(graphicsContext);
- graphicsContext.beginTransparencyLayer(1);
- graphicsContext.setCompositeOperation(CompositeCopy);
-
- m_client->drawRect(this, graphicsContext, paintRect);
-
- graphicsContext.endTransparencyLayer();
-}
-
-bool PageOverlay::mouseEvent(const WebMouseEvent& mouseEvent)
-{
- // Ignore events outside the bounds.
- if (!bounds().contains(mouseEvent.position()))
- return false;
-
- return m_client->mouseEvent(this, mouseEvent);
-}
-
-WKTypeRef PageOverlay::copyAccessibilityAttributeValue(WKStringRef attribute, WKTypeRef parameter)
-{
- return m_client->copyAccessibilityAttributeValue(this, attribute, parameter);
-}
-
-WKArrayRef PageOverlay::copyAccessibilityAttributeNames(bool parameterizedNames)
-{
- return m_client->copyAccessibilityAttributeNames(this, parameterizedNames);
-}
-
-void PageOverlay::startFadeInAnimation()
-{
- m_fractionFadedIn = 0.0;
- m_fadeAnimationType = FadeInAnimation;
-
- startFadeAnimation();
-}
-
-void PageOverlay::startFadeOutAnimation()
-{
- m_fractionFadedIn = 1.0;
- m_fadeAnimationType = FadeOutAnimation;
-
- startFadeAnimation();
-}
-
-void PageOverlay::stopFadeOutAnimation()
-{
- m_fractionFadedIn = 1.0;
- m_fadeAnimationTimer.stop();
-}
-
-void PageOverlay::startFadeAnimation()
-{
- m_fadeAnimationStartTime = currentTime();
-
- // Start the timer
- m_fadeAnimationTimer.startRepeating(1 / fadeAnimationFrameRate);
-}
-
-void PageOverlay::fadeAnimationTimerFired()
-{
- float animationProgress = (currentTime() - m_fadeAnimationStartTime) / m_fadeAnimationDuration;
-
- if (animationProgress >= 1.0)
- animationProgress = 1.0;
-
- double sine = sin(piOverTwoFloat * animationProgress);
- float fadeAnimationValue = sine * sine;
-
- m_fractionFadedIn = (m_fadeAnimationType == FadeInAnimation) ? fadeAnimationValue : 1 - fadeAnimationValue;
- m_webPage->drawingArea()->setPageOverlayOpacity(this, m_fractionFadedIn);
-
- if (animationProgress == 1.0) {
- m_fadeAnimationTimer.stop();
-
- bool wasFadingOut = m_fadeAnimationType == FadeOutAnimation;
- m_fadeAnimationType = NoAnimation;
-
- if (wasFadingOut) {
- // If this was a fade out, go ahead and uninstall the page overlay.
- m_webPage->uninstallPageOverlay(this, false);
- }
- }
-}
-
-void PageOverlay::clear()
-{
- m_webPage->drawingArea()->clearPageOverlay(this);
-}
-
-} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.h b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h
deleted file mode 100644
index 295f1e816..000000000
--- a/Source/WebKit2/WebProcess/WebPage/PageOverlay.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
- */
-
-#ifndef PageOverlay_h
-#define PageOverlay_h
-
-#include "APIObject.h"
-#include "WKBase.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RunLoop.h>
-
-namespace WebCore {
- class GraphicsContext;
- class IntPoint;
- class IntRect;
-}
-
-namespace WebKit {
-
-class WebMouseEvent;
-class WebPage;
-
-class PageOverlay : public API::ObjectImpl<API::Object::Type::BundlePageOverlay> {
-public:
- class Client {
- protected:
- virtual ~Client() { }
-
- public:
- virtual void pageOverlayDestroyed(PageOverlay*) = 0;
- virtual void willMoveToWebPage(PageOverlay*, WebPage*) = 0;
- virtual void didMoveToWebPage(PageOverlay*, WebPage*) = 0;
- virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) = 0;
- virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&) = 0;
-
- virtual WKTypeRef copyAccessibilityAttributeValue(PageOverlay*, WKStringRef /* attribute */, WKTypeRef /* parameter */) { return 0; }
- virtual WKArrayRef copyAccessibilityAttributeNames(PageOverlay*, bool /* parameterizedNames */) { return 0; }
- };
-
- static PassRefPtr<PageOverlay> create(Client*);
- virtual ~PageOverlay();
-
- void setPage(WebPage*);
- void setNeedsDisplay(const WebCore::IntRect& dirtyRect);
- void setNeedsDisplay();
-
- void drawRect(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect);
- bool mouseEvent(const WebMouseEvent&);
-
- WKTypeRef copyAccessibilityAttributeValue(WKStringRef attribute, WKTypeRef parameter);
- WKArrayRef copyAccessibilityAttributeNames(bool parameterizedNames);
-
- void startFadeInAnimation();
- void startFadeOutAnimation();
- void stopFadeOutAnimation();
-
- void clear();
-
- Client* client() const { return m_client; }
-
-protected:
- explicit PageOverlay(Client*);
-
-private:
- WebCore::IntRect bounds() const;
-
- void startFadeAnimation();
- void fadeAnimationTimerFired();
-
- Client* m_client;
- WebPage* m_webPage;
-
- RunLoop::Timer<PageOverlay> m_fadeAnimationTimer;
- double m_fadeAnimationStartTime;
- double m_fadeAnimationDuration;
-
- enum FadeAnimationType {
- NoAnimation,
- FadeInAnimation,
- FadeOutAnimation,
- };
-
- FadeAnimationType m_fadeAnimationType;
- float m_fractionFadedIn;
-};
-
-} // namespace WebKit
-
-#endif // PageOverlay_h
diff --git a/Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.cpp b/Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.cpp
new file mode 100644
index 000000000..35e0450ac
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "RemoteWebInspectorUI.h"
+
+#include "RemoteWebInspectorProxyMessages.h"
+#include "RemoteWebInspectorUIMessages.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+#include <WebCore/Chrome.h>
+#include <WebCore/DOMWrapperWorld.h>
+#include <WebCore/InspectorController.h>
+#include <WebCore/ScriptGlobalObject.h>
+#include <WebCore/ScriptState.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+Ref<RemoteWebInspectorUI> RemoteWebInspectorUI::create(WebPage& page)
+{
+ return adoptRef(*new RemoteWebInspectorUI(page));
+}
+
+RemoteWebInspectorUI::RemoteWebInspectorUI(WebPage& page)
+ : m_page(page)
+ , m_frontendAPIDispatcher(page)
+{
+}
+
+void RemoteWebInspectorUI::initialize(const String& debuggableType, const String& backendCommandsURL)
+{
+ m_debuggableType = debuggableType;
+ m_backendCommandsURL = backendCommandsURL;
+
+ m_page.corePage()->inspectorController().setInspectorFrontendClient(this);
+
+ m_frontendAPIDispatcher.reset();
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setDockingUnavailable"), true);
+}
+
+void RemoteWebInspectorUI::didSave(const String& url)
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("savedURL"), url);
+}
+
+void RemoteWebInspectorUI::didAppend(const String& url)
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("appendedToURL"), url);
+}
+
+void RemoteWebInspectorUI::sendMessageToFrontend(const String& message)
+{
+ m_frontendAPIDispatcher.dispatchMessageAsync(message);
+}
+
+void RemoteWebInspectorUI::sendMessageToBackend(const String& message)
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::RemoteWebInspectorProxy::SendMessageToBackend(message), m_page.pageID());
+}
+
+void RemoteWebInspectorUI::windowObjectCleared()
+{
+ if (m_frontendHost)
+ m_frontendHost->disconnectClient();
+
+ m_frontendHost = InspectorFrontendHost::create(this, m_page.corePage());
+ ScriptGlobalObject::set(*execStateFromPage(mainThreadNormalWorld(), m_page.corePage()), ASCIILiteral("InspectorFrontendHost"), *m_frontendHost);
+}
+
+void RemoteWebInspectorUI::frontendLoaded()
+{
+ m_frontendAPIDispatcher.frontendLoaded();
+
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setIsVisible"), true);
+
+ bringToFront();
+}
+
+void RemoteWebInspectorUI::startWindowDrag()
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::RemoteWebInspectorProxy::StartWindowDrag(), m_page.pageID());
+}
+
+void RemoteWebInspectorUI::moveWindowBy(float x, float y)
+{
+ FloatRect frameRect = m_page.corePage()->chrome().windowRect();
+ frameRect.move(x, y);
+ m_page.corePage()->chrome().setWindowRect(frameRect);
+}
+
+WebCore::UserInterfaceLayoutDirection RemoteWebInspectorUI::userInterfaceLayoutDirection() const
+{
+ return m_page.corePage()->userInterfaceLayoutDirection();
+}
+
+void RemoteWebInspectorUI::bringToFront()
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::RemoteWebInspectorProxy::BringToFront(), m_page.pageID());
+}
+
+void RemoteWebInspectorUI::closeWindow()
+{
+ m_page.corePage()->inspectorController().setInspectorFrontendClient(nullptr);
+
+ WebProcess::singleton().parentProcessConnection()->send(Messages::RemoteWebInspectorProxy::FrontendDidClose(), m_page.pageID());
+}
+
+void RemoteWebInspectorUI::openInNewTab(const String& url)
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::RemoteWebInspectorProxy::OpenInNewTab(url), m_page.pageID());
+}
+
+void RemoteWebInspectorUI::save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs)
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::RemoteWebInspectorProxy::Save(filename, content, base64Encoded, forceSaveAs), m_page.pageID());
+}
+
+void RemoteWebInspectorUI::append(const String& filename, const String& content)
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::RemoteWebInspectorProxy::Append(filename, content), m_page.pageID());
+}
+
+void RemoteWebInspectorUI::inspectedURLChanged(const String& urlString)
+{
+ // Do nothing. The remote side can know if the main resource changed.
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.h b/Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.h
new file mode 100644
index 000000000..33f43bec0
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "MessageReceiver.h"
+#include "WebInspectorFrontendAPIDispatcher.h"
+#include <WebCore/InspectorFrontendClient.h>
+#include <WebCore/InspectorFrontendHost.h>
+#include <wtf/Deque.h>
+
+namespace WebKit {
+
+class WebPage;
+
+class RemoteWebInspectorUI final : public RefCounted<RemoteWebInspectorUI>, public IPC::MessageReceiver, public WebCore::InspectorFrontendClient {
+public:
+ static Ref<RemoteWebInspectorUI> create(WebPage&);
+
+ // Implemented in generated RemoteWebInspectorUIMessageReceiver.cpp
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+
+ // Called by RemoteWebInspectorUI messages
+ void initialize(const String& debuggableType, const String& backendCommandsURL);
+ void didSave(const String& url);
+ void didAppend(const String& url);
+ void sendMessageToFrontend(const String&);
+
+ // WebCore::InspectorFrontendClient
+ void windowObjectCleared() override;
+ void frontendLoaded() override;
+ void startWindowDrag() override;
+ void moveWindowBy(float x, float y) override;
+
+ String localizedStringsURL() override;
+ String backendCommandsURL() override { return m_backendCommandsURL; }
+ String debuggableType() override { return m_debuggableType; }
+
+ WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() const override;
+
+ void bringToFront() override;
+ void closeWindow() override;
+
+ void openInNewTab(const String& url) override;
+ void save(const String& url, const String& content, bool base64Encoded, bool forceSaveAs) override;
+ void append(const String& url, const String& content) override;
+ void inspectedURLChanged(const String&) override;
+ void sendMessageToBackend(const String&) override;
+
+ bool canSave() override { return true; }
+ bool isUnderTest() override { return false; }
+ unsigned inspectionLevel() const override { return 1; }
+ void requestSetDockSide(DockSide) override { }
+ void changeAttachedWindowHeight(unsigned) override { }
+ void changeAttachedWindowWidth(unsigned) override { }
+
+private:
+ explicit RemoteWebInspectorUI(WebPage&);
+
+ WebPage& m_page;
+ WebInspectorFrontendAPIDispatcher m_frontendAPIDispatcher;
+ RefPtr<WebCore::InspectorFrontendHost> m_frontendHost;
+ String m_debuggableType;
+ String m_backendCommandsURL;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.messages.in b/Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.messages.in
index 8ba527a3d..5b5cab2c9 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.messages.in
+++ b/Source/WebKit2/WebProcess/WebPage/RemoteWebInspectorUI.messages.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2012 Apple Inc. All rights reserved.
+# Copyright (C) 2016 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -20,10 +20,11 @@
# 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.
-messages -> WebPageGroupProxy {
- AddUserStyleSheet(WebCore::UserStyleSheet userStyleSheet);
- AddUserScript(WebCore::UserScript userScript);
- RemoveAllUserStyleSheets();
- RemoveAllUserScripts();
- RemoveAllUserContent();
+messages -> RemoteWebInspectorUI {
+ Initialize(String debuggableType, String backendCommandsURL)
+
+ DidSave(String url)
+ DidAppend(String url)
+
+ SendMessageToFrontend(String message)
}
diff --git a/Source/WebKit2/WebProcess/WebPage/TapHighlightController.cpp b/Source/WebKit2/WebProcess/WebPage/TapHighlightController.cpp
deleted file mode 100644
index df9ab32f4..000000000
--- a/Source/WebKit2/WebProcess/WebPage/TapHighlightController.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this program; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "TapHighlightController.h"
-
-#if ENABLE(TOUCH_EVENTS)
-
-#include "ShareableBitmap.h"
-#include "WKPage.h"
-#include "WebCoreArgumentCoders.h"
-#include "WebPage.h"
-#include "WebPageProxyMessages.h"
-#include "WebProcess.h"
-#include <WebCore/FocusController.h>
-#include <WebCore/Frame.h>
-#include <WebCore/FrameView.h>
-#include <WebCore/GestureTapHighlighter.h>
-#include <WebCore/GraphicsContext.h>
-#include <WebCore/Page.h>
-
-#include <WebCore/RenderObject.h>
-
-using namespace std;
-using namespace WebCore;
-
-namespace WebKit {
-
-TapHighlightController::TapHighlightController(WebPage* webPage)
- : m_webPage(webPage)
- , m_overlay(0)
-{
-}
-
-TapHighlightController::~TapHighlightController()
-{
-}
-
-void TapHighlightController::highlight(Node* node)
-{
- ASSERT(node);
-
- m_path = GestureTapHighlighter::pathForNodeHighlight(node);
- m_color = node->renderer()->style().tapHighlightColor();
-
- if (!m_overlay) {
- RefPtr<PageOverlay> overlay = PageOverlay::create(this);
- m_overlay = overlay.get();
- m_webPage->installPageOverlay(overlay.release());
- } else
- m_overlay->setNeedsDisplay();
-}
-
-void TapHighlightController::hideHighlight()
-{
- if (m_overlay)
- m_webPage->uninstallPageOverlay(m_overlay, /* fadeout */ true);
-}
-
-void TapHighlightController::pageOverlayDestroyed(PageOverlay*)
-{
-}
-
-void TapHighlightController::willMoveToWebPage(PageOverlay*, WebPage* webPage)
-{
- if (webPage)
- return;
-
- // The page overlay is moving away from the web page, reset it.
- ASSERT(m_overlay);
- m_overlay = 0;
-}
-
-void TapHighlightController::didMoveToWebPage(PageOverlay*, WebPage*)
-{
-}
-
-static Color highlightColor(Color baseColor, float fractionFadedIn)
-{
- return Color(baseColor.red(), baseColor.green(), baseColor.blue(), int(baseColor.alpha() * fractionFadedIn));
-}
-
-void TapHighlightController::drawRect(PageOverlay* /*pageOverlay*/, GraphicsContext& context, const IntRect& /*dirtyRect*/)
-{
- if (m_path.isEmpty())
- return;
-
- {
- GraphicsContextStateSaver stateSaver(context);
- context.setFillColor(highlightColor(m_color, 0.5f), ColorSpaceSRGB);
- context.fillPath(m_path);
- }
-}
-
-bool TapHighlightController::mouseEvent(PageOverlay*, const WebMouseEvent&)
-{
- return false;
-}
-
-} // namespace WebKit
-
-#endif // ENABLE(TOUCH_EVENTS)
diff --git a/Source/WebKit2/WebProcess/WebPage/TapHighlightController.h b/Source/WebKit2/WebProcess/WebPage/TapHighlightController.h
deleted file mode 100644
index cb20858c6..000000000
--- a/Source/WebKit2/WebProcess/WebPage/TapHighlightController.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this program; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef TapHighlightController_h
-#define TapHighlightController_h
-
-#if ENABLE(TOUCH_EVENTS)
-
-#include "PageOverlay.h"
-#include <WebCore/Color.h>
-#include <WebCore/Path.h>
-#include <wtf/Forward.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-class Frame;
-class IntRect;
-class Node;
-}
-
-namespace WebKit {
-
-class WebPage;
-
-class TapHighlightController : private PageOverlay::Client {
- WTF_MAKE_NONCOPYABLE(TapHighlightController);
-
-public:
- explicit TapHighlightController(WebPage*);
- virtual ~TapHighlightController();
-
- void highlight(WebCore::Node*);
- void hideHighlight();
-
-private:
- // PageOverlay::Client.
- virtual void pageOverlayDestroyed(PageOverlay*);
- virtual void willMoveToWebPage(PageOverlay*, WebPage*);
- virtual void didMoveToWebPage(PageOverlay*, WebPage*);
- virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&);
- virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect);
-
-private:
- WebPage* m_webPage;
- PageOverlay* m_overlay;
-
- WebCore::Path m_path;
- WebCore::Color m_color;
-};
-
-} // namespace WebKit
-
-#endif // ENABLE(TOUCH_EVENTS)
-
-#endif // TapHighlightController_h
diff --git a/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.cpp b/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.cpp
new file mode 100644
index 000000000..3a4a6a1a7
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "ViewGestureGeometryCollector.h"
+
+#include "ViewGestureGeometryCollectorMessages.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebFrame.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/HTMLImageElement.h>
+#include <WebCore/HitTestResult.h>
+#include <WebCore/ImageDocument.h>
+#include <WebCore/RenderView.h>
+
+#if PLATFORM(IOS)
+#include "SmartMagnificationControllerMessages.h"
+#endif
+
+#if PLATFORM(MAC)
+#include "ViewGestureControllerMessages.h"
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+ViewGestureGeometryCollector::ViewGestureGeometryCollector(WebPage& webPage)
+ : m_webPage(webPage)
+#if PLATFORM(MAC)
+ , m_renderTreeSizeNotificationThreshold(0)
+#endif
+{
+ WebProcess::singleton().addMessageReceiver(Messages::ViewGestureGeometryCollector::messageReceiverName(), m_webPage.pageID(), *this);
+}
+
+ViewGestureGeometryCollector::~ViewGestureGeometryCollector()
+{
+ WebProcess::singleton().removeMessageReceiver(Messages::ViewGestureGeometryCollector::messageReceiverName(), m_webPage.pageID());
+}
+
+void ViewGestureGeometryCollector::dispatchDidCollectGeometryForSmartMagnificationGesture(FloatPoint origin, FloatRect targetRect, FloatRect visibleContentRect, bool isReplacedElement, double viewportMinimumScale, double viewportMaximumScale)
+{
+#if PLATFORM(MAC)
+ m_webPage.send(Messages::ViewGestureController::DidCollectGeometryForSmartMagnificationGesture(origin, targetRect, visibleContentRect, isReplacedElement, viewportMinimumScale, viewportMaximumScale));
+#endif
+#if PLATFORM(IOS)
+ m_webPage.send(Messages::SmartMagnificationController::DidCollectGeometryForSmartMagnificationGesture(origin, targetRect, visibleContentRect, isReplacedElement, viewportMinimumScale, viewportMaximumScale));
+#endif
+}
+
+void ViewGestureGeometryCollector::collectGeometryForSmartMagnificationGesture(FloatPoint origin)
+{
+ FloatRect visibleContentRect = m_webPage.mainFrameView()->unobscuredContentRectIncludingScrollbars();
+
+ if (m_webPage.mainWebFrame()->handlesPageScaleGesture())
+ return;
+
+ IntPoint originInContentsSpace = m_webPage.mainFrameView()->windowToContents(roundedIntPoint(origin));
+ HitTestResult hitTestResult = HitTestResult(originInContentsSpace);
+
+ m_webPage.mainFrameView()->renderView()->hitTest(HitTestRequest(), hitTestResult);
+ Node* node = hitTestResult.innerNode();
+ if (!node) {
+ dispatchDidCollectGeometryForSmartMagnificationGesture(FloatPoint(), FloatRect(), FloatRect(), false, 0, 0);
+ return;
+ }
+
+ bool isReplaced;
+ FloatRect renderRect;
+ double viewportMinimumScale;
+ double viewportMaximumScale;
+
+ computeZoomInformationForNode(*node, origin, renderRect, isReplaced, viewportMinimumScale, viewportMaximumScale);
+ dispatchDidCollectGeometryForSmartMagnificationGesture(origin, renderRect, visibleContentRect, isReplaced, viewportMinimumScale, viewportMaximumScale);
+}
+
+void ViewGestureGeometryCollector::computeZoomInformationForNode(Node& node, FloatPoint& origin, FloatRect& renderRect, bool& isReplaced, double& viewportMinimumScale, double& viewportMaximumScale)
+{
+ renderRect = node.renderRect(&isReplaced);
+ if (node.document().isImageDocument()) {
+ if (HTMLImageElement* imageElement = static_cast<ImageDocument&>(node.document()).imageElement()) {
+ if (&node != imageElement) {
+ renderRect = imageElement->renderRect(&isReplaced);
+ FloatPoint newOrigin = origin;
+ if (origin.x() < renderRect.x() || origin.x() > renderRect.maxX())
+ newOrigin.setX(renderRect.x() + renderRect.width() / 2);
+ if (origin.y() < renderRect.y() || origin.y() > renderRect.maxY())
+ newOrigin.setY(renderRect.y() + renderRect.height() / 2);
+ origin = newOrigin;
+ }
+ isReplaced = true;
+ }
+ }
+#if PLATFORM(MAC)
+ viewportMinimumScale = 0;
+ viewportMaximumScale = std::numeric_limits<double>::max();
+#else
+ viewportMinimumScale = m_webPage.minimumPageScaleFactor();
+ viewportMaximumScale = m_webPage.maximumPageScaleFactor();
+#endif
+}
+
+#if PLATFORM(MAC)
+void ViewGestureGeometryCollector::collectGeometryForMagnificationGesture()
+{
+ FloatRect visibleContentRect = m_webPage.mainFrameView()->unobscuredContentRectIncludingScrollbars();
+ bool frameHandlesMagnificationGesture = m_webPage.mainWebFrame()->handlesPageScaleGesture();
+ m_webPage.send(Messages::ViewGestureController::DidCollectGeometryForMagnificationGesture(visibleContentRect, frameHandlesMagnificationGesture));
+}
+
+void ViewGestureGeometryCollector::mainFrameDidLayout()
+{
+ if (m_renderTreeSizeNotificationThreshold && m_webPage.renderTreeSize() >= m_renderTreeSizeNotificationThreshold) {
+ m_webPage.send(Messages::ViewGestureController::DidHitRenderTreeSizeThreshold());
+ m_renderTreeSizeNotificationThreshold = 0;
+ }
+}
+#endif
+
+} // namespace WebKit
+
diff --git a/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.h b/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.h
new file mode 100644
index 000000000..6fff6520f
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#ifndef ViewGestureGeometryCollector_h
+#define ViewGestureGeometryCollector_h
+
+#include "MessageReceiver.h"
+#include <wtf/RunLoop.h>
+
+namespace WebCore {
+class FloatPoint;
+class FloatRect;
+class Node;
+}
+
+namespace WebKit {
+
+class WebPage;
+
+class ViewGestureGeometryCollector : private IPC::MessageReceiver {
+public:
+ ViewGestureGeometryCollector(WebPage&);
+ ~ViewGestureGeometryCollector();
+
+ void mainFrameDidLayout();
+
+private:
+ // IPC::MessageReceiver.
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+
+ // Message handlers.
+ void collectGeometryForSmartMagnificationGesture(WebCore::FloatPoint origin);
+
+#if PLATFORM(MAC)
+ void collectGeometryForMagnificationGesture();
+ void setRenderTreeSizeNotificationThreshold(uint64_t size) { m_renderTreeSizeNotificationThreshold = size; }
+
+ void renderTreeSizeNotificationTimerFired();
+#endif
+
+ void dispatchDidCollectGeometryForSmartMagnificationGesture(WebCore::FloatPoint origin, WebCore::FloatRect targetRect, WebCore::FloatRect visibleContentRect, bool isReplacedElement, double viewportMinimumScale, double viewportMaximumScale);
+ void computeZoomInformationForNode(WebCore::Node&, WebCore::FloatPoint& origin, WebCore::FloatRect& renderRect, bool& isReplaced, double& viewportMinimumScale, double& viewportMaximumScale);
+
+ WebPage& m_webPage;
+
+#if PLATFORM(MAC)
+ uint64_t m_renderTreeSizeNotificationThreshold;
+#endif
+};
+
+} // namespace WebKit
+
+#endif // ViewGestureGeometryCollector
diff --git a/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.messages.in b/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.messages.in
index efd051f80..047209abe 100644
--- a/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.messages.in
+++ b/Source/WebKit2/WebProcess/WebPage/ViewGestureGeometryCollector.messages.in
@@ -20,14 +20,12 @@
# 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.
-#if !PLATFORM(IOS)
-
messages -> ViewGestureGeometryCollector {
+ CollectGeometryForSmartMagnificationGesture(WebCore::FloatPoint origin)
-CollectGeometryForMagnificationGesture()
-CollectGeometryForSmartMagnificationGesture(WebCore::FloatPoint origin)
-
-SetRenderTreeSizeNotificationThreshold(uint64_t size)
-}
+#if !PLATFORM(IOS)
+ CollectGeometryForMagnificationGesture()
+ SetRenderTreeSizeNotificationThreshold(uint64_t size)
#endif
+}
diff --git a/Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.cpp b/Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.cpp
new file mode 100644
index 000000000..c8e363861
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "ViewUpdateDispatcher.h"
+
+#if PLATFORM(IOS)
+
+#include "ViewUpdateDispatcherMessages.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+#include <wtf/RunLoop.h>
+
+namespace WebKit {
+
+Ref<ViewUpdateDispatcher> ViewUpdateDispatcher::create()
+{
+ return adoptRef(*new ViewUpdateDispatcher);
+}
+
+ViewUpdateDispatcher::ViewUpdateDispatcher()
+ : m_queue(WorkQueue::create("com.apple.WebKit.ViewUpdateDispatcher"))
+{
+}
+
+ViewUpdateDispatcher::~ViewUpdateDispatcher()
+{
+}
+
+void ViewUpdateDispatcher::initializeConnection(IPC::Connection* connection)
+{
+ connection->addWorkQueueMessageReceiver(Messages::ViewUpdateDispatcher::messageReceiverName(), m_queue.get(), this);
+}
+
+void ViewUpdateDispatcher::visibleContentRectUpdate(uint64_t pageID, const VisibleContentRectUpdateInfo& visibleContentRectUpdateInfo)
+{
+ bool updateListWasEmpty;
+ {
+ LockHolder locker(&m_dataMutex);
+ updateListWasEmpty = m_latestUpdate.isEmpty();
+ auto iterator = m_latestUpdate.find(pageID);
+ if (iterator == m_latestUpdate.end())
+ m_latestUpdate.set<UpdateData>(pageID, { visibleContentRectUpdateInfo, visibleContentRectUpdateInfo.timestamp() });
+ else
+ iterator->value.visibleContentRectUpdateInfo = visibleContentRectUpdateInfo;
+ }
+ if (updateListWasEmpty) {
+ RunLoop::main().dispatch([protectedThis = makeRef(*this)]() mutable {
+ protectedThis->dispatchVisibleContentRectUpdate();
+ });
+ }
+}
+
+void ViewUpdateDispatcher::dispatchVisibleContentRectUpdate()
+{
+ HashMap<uint64_t, UpdateData> update;
+ {
+ LockHolder locker(&m_dataMutex);
+ update = WTFMove(m_latestUpdate);
+ }
+
+ for (auto& slot : update) {
+ if (WebPage* webPage = WebProcess::singleton().webPage(slot.key))
+ webPage->updateVisibleContentRects(slot.value.visibleContentRectUpdateInfo, slot.value.oldestTimestamp);
+ }
+}
+
+} // namespace WebKit
+
+#endif // PLATFORM(IOS)
diff --git a/Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.h b/Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.h
new file mode 100644
index 000000000..e47dc4e1d
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#ifndef ViewUpdateDispatcher_h
+#define ViewUpdateDispatcher_h
+
+#include "Connection.h"
+
+#include "VisibleContentRectUpdateInfo.h"
+#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
+#include <wtf/Ref.h>
+
+namespace WebKit {
+
+class ViewUpdateDispatcher : public IPC::Connection::WorkQueueMessageReceiver {
+public:
+ static Ref<ViewUpdateDispatcher> create();
+ ~ViewUpdateDispatcher();
+
+ void initializeConnection(IPC::Connection*);
+
+private:
+ ViewUpdateDispatcher();
+ // IPC::Connection::WorkQueueMessageReceiver.
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+
+ void visibleContentRectUpdate(uint64_t pageID, const VisibleContentRectUpdateInfo&);
+
+ void dispatchVisibleContentRectUpdate();
+
+ struct UpdateData {
+ VisibleContentRectUpdateInfo visibleContentRectUpdateInfo;
+ MonotonicTime oldestTimestamp;
+ };
+
+ Ref<WorkQueue> m_queue;
+ Lock m_dataMutex;
+ HashMap<uint64_t, UpdateData> m_latestUpdate;
+};
+
+} // namespace WebKit
+
+#endif // ViewportUpdateDispatcher_h
diff --git a/Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.messages.in b/Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.messages.in
new file mode 100644
index 000000000..17e2c8dd1
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ViewUpdateDispatcher.messages.in
@@ -0,0 +1,25 @@
+# Copyright (C) 2014 Apple Inc. All rights reserved.
+#
+# 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+
+messages -> ViewUpdateDispatcher {
+ VisibleContentRectUpdate(uint64_t pageID, WebKit::VisibleContentRectUpdateInfo visibleContentRectUpdateInfo)
+}
diff --git a/Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.cpp b/Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.cpp
new file mode 100644
index 000000000..0e676f966
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "VisitedLinkTableController.h"
+
+#include "VisitedLinkStoreMessages.h"
+#include "VisitedLinkTableControllerMessages.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+#include <WebCore/PageCache.h>
+#include <wtf/NeverDestroyed.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static HashMap<uint64_t, VisitedLinkTableController*>& visitedLinkTableControllers()
+{
+ static NeverDestroyed<HashMap<uint64_t, VisitedLinkTableController*>> visitedLinkTableControllers;
+
+ return visitedLinkTableControllers;
+}
+
+PassRefPtr<VisitedLinkTableController> VisitedLinkTableController::getOrCreate(uint64_t identifier)
+{
+ auto& visitedLinkTableControllerPtr = visitedLinkTableControllers().add(identifier, nullptr).iterator->value;
+ if (visitedLinkTableControllerPtr)
+ return visitedLinkTableControllerPtr;
+
+ auto visitedLinkTableController = adoptRef(*new VisitedLinkTableController(identifier));
+ visitedLinkTableControllerPtr = visitedLinkTableController.ptr();
+
+ return WTFMove(visitedLinkTableController);
+}
+
+VisitedLinkTableController::VisitedLinkTableController(uint64_t identifier)
+ : m_identifier(identifier)
+{
+ WebProcess::singleton().addMessageReceiver(Messages::VisitedLinkTableController::messageReceiverName(), m_identifier, *this);
+}
+
+VisitedLinkTableController::~VisitedLinkTableController()
+{
+ ASSERT(visitedLinkTableControllers().contains(m_identifier));
+
+ WebProcess::singleton().removeMessageReceiver(Messages::VisitedLinkTableController::messageReceiverName(), m_identifier);
+
+ visitedLinkTableControllers().remove(m_identifier);
+}
+
+bool VisitedLinkTableController::isLinkVisited(Page&, LinkHash linkHash, const URL&, const AtomicString&)
+{
+ return m_visitedLinkTable.isLinkVisited(linkHash);
+}
+
+void VisitedLinkTableController::addVisitedLink(Page& page, LinkHash linkHash)
+{
+ if (m_visitedLinkTable.isLinkVisited(linkHash))
+ return;
+
+ WebPage* webPage = WebPage::fromCorePage(&page);
+ if (!webPage)
+ return;
+
+ WebProcess::singleton().parentProcessConnection()->send(Messages::VisitedLinkStore::AddVisitedLinkHashFromPage(webPage->pageID(), linkHash), m_identifier);
+}
+
+void VisitedLinkTableController::setVisitedLinkTable(const SharedMemory::Handle& handle)
+{
+ auto sharedMemory = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly);
+ if (!sharedMemory)
+ return;
+
+ m_visitedLinkTable.setSharedMemory(WTFMove(sharedMemory));
+
+ invalidateStylesForAllLinks();
+}
+
+void VisitedLinkTableController::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes)
+{
+ for (auto linkHash : linkHashes)
+ invalidateStylesForLink(linkHash);
+}
+
+void VisitedLinkTableController::allVisitedLinkStateChanged()
+{
+ invalidateStylesForAllLinks();
+}
+
+void VisitedLinkTableController::removeAllVisitedLinks()
+{
+ m_visitedLinkTable.clear();
+
+ invalidateStylesForAllLinks();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.h b/Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.h
new file mode 100644
index 000000000..e1330884b
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#ifndef VisitedLinkTableController_h
+#define VisitedLinkTableController_h
+
+#include "MessageReceiver.h"
+#include "SharedMemory.h"
+#include "VisitedLinkTable.h"
+#include <WebCore/VisitedLinkStore.h>
+
+namespace WebKit {
+
+class VisitedLinkTableController final : public WebCore::VisitedLinkStore , private IPC::MessageReceiver {
+public:
+ static PassRefPtr<VisitedLinkTableController> getOrCreate(uint64_t identifier);
+ virtual ~VisitedLinkTableController();
+
+private:
+ explicit VisitedLinkTableController(uint64_t identifier);
+
+ // WebCore::VisitedLinkStore.
+ bool isLinkVisited(WebCore::Page&, WebCore::LinkHash, const WebCore::URL& baseURL, const AtomicString& attributeURL) override;
+ void addVisitedLink(WebCore::Page&, WebCore::LinkHash) override;
+
+ // IPC::MessageReceiver.
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+
+ void setVisitedLinkTable(const SharedMemory::Handle&);
+ void visitedLinkStateChanged(const Vector<WebCore::LinkHash>&);
+ void allVisitedLinkStateChanged();
+ void removeAllVisitedLinks();
+
+ uint64_t m_identifier;
+ VisitedLinkTable m_visitedLinkTable;
+};
+
+} // namespace WebKit
+
+#endif // VisitedLinkTableController_h
diff --git a/Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.messages.in b/Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.messages.in
new file mode 100644
index 000000000..039dd3022
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/VisitedLinkTableController.messages.in
@@ -0,0 +1,28 @@
+# Copyright (C) 2014 Apple Inc. All rights reserved.
+#
+# 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+
+messages -> VisitedLinkTableController {
+ SetVisitedLinkTable(WebKit::SharedMemory::Handle handle)
+ VisitedLinkStateChanged(Vector<WebCore::LinkHash> linkHashes)
+ AllVisitedLinkStateChanged()
+ RemoveAllVisitedLinks()
+}
diff --git a/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h b/Source/WebKit2/WebProcess/WebPage/WKAccessibilityWebPageObjectIOS.h
index ccddaaaf7..da2c6be92 100644
--- a/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h
+++ b/Source/WebKit2/WebProcess/WebPage/WKAccessibilityWebPageObjectIOS.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,41 +23,19 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef EncoderAdapter_h
-#define EncoderAdapter_h
+#ifndef WKAccessibilityWebPageObjectIOS_h
+#define WKAccessibilityWebPageObjectIOS_h
-#include "ArgumentEncoder.h"
-#include <wtf/Encoder.h>
-#include <wtf/Forward.h>
+#if PLATFORM(IOS)
-namespace IPC {
- class ArgumentEncoder;
- class DataReference;
-}
+#include "WKAccessibilityWebPageObjectBase.h"
-namespace WebKit {
+@interface WKAccessibilityWebPageObject : WKAccessibilityWebPageObjectBase
-class EncoderAdapter : public Encoder {
-public:
- EncoderAdapter();
+@property(nonatomic, retain) NSData *remoteTokenData;
- IPC::DataReference dataReference() const;
+@end
-private:
- virtual void encodeBytes(const uint8_t*, size_t);
- virtual void encodeBool(bool);
- virtual void encodeUInt16(uint16_t value);
- virtual void encodeUInt32(uint32_t);
- virtual void encodeUInt64(uint64_t);
- virtual void encodeInt32(int32_t);
- virtual void encodeInt64(int64_t);
- virtual void encodeFloat(float);
- virtual void encodeDouble(double);
- virtual void encodeString(const String&);
+#endif // PLATFORM(IOS)
- IPC::ArgumentEncoder m_encoder;
-};
-
-} // namespace WebKit
-
-#endif // EncoderAdapter_h
+#endif // WKAccessibilityWebPageObjectIOS_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp
index 11bb1a18f..f2e8ecd60 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp
@@ -26,14 +26,16 @@
#include "config.h"
#include "WebBackForwardListProxy.h"
-#include "DataReference.h"
-#include "EncoderAdapter.h"
+#include "SessionState.h"
+#include "SessionStateConversion.h"
#include "WebCoreArgumentCoders.h"
#include "WebPage.h"
#include "WebPageProxyMessages.h"
#include "WebProcess.h"
#include "WebProcessProxyMessages.h"
+#include <WebCore/HistoryController.h>
#include <WebCore/HistoryItem.h>
+#include <WebCore/MainFrame.h>
#include <WebCore/PageCache.h>
#include <wtf/HashMap.h>
#include <wtf/NeverDestroyed.h>
@@ -45,20 +47,25 @@ namespace WebKit {
// FIXME <rdar://problem/8819268>: This leaks all HistoryItems that go into these maps.
// We need to clear up the life time of these objects.
-typedef HashMap<uint64_t, RefPtr<HistoryItem>> IDToHistoryItemMap;
-typedef HashMap<RefPtr<HistoryItem>, uint64_t> HistoryItemToIDMap;
+typedef HashMap<uint64_t, RefPtr<HistoryItem>> IDToHistoryItemMap; // "ID" here is the item ID.
+
+struct ItemAndPageID {
+ uint64_t itemID;
+ uint64_t pageID;
+};
+typedef HashMap<RefPtr<HistoryItem>, ItemAndPageID> HistoryItemToIDMap;
static IDToHistoryItemMap& idToHistoryItemMap()
{
- static NeverDestroyed<IDToHistoryItemMap> map;;
+ static NeverDestroyed<IDToHistoryItemMap> map;
return map;
-}
+}
static HistoryItemToIDMap& historyItemToIDMap()
{
static NeverDestroyed<HistoryItemToIDMap> map;
return map;
-}
+}
static uint64_t uniqueHistoryItemID = 1;
@@ -82,33 +89,28 @@ void WebBackForwardListProxy::setHighestItemIDFromUIProcess(uint64_t itemID)
uniqueHistoryItemID = itemID + 1;
}
-static void updateBackForwardItem(uint64_t itemID, HistoryItem* item)
+static void updateBackForwardItem(uint64_t itemID, uint64_t pageID, HistoryItem* item)
{
- EncoderAdapter encoder;
- item->encodeBackForwardTree(encoder);
-
- WebProcess::shared().parentProcessConnection()->send(Messages::WebProcessProxy::AddBackForwardItem(itemID, item->originalURLString(), item->urlString(), item->title(), encoder.dataReference()), 0);
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::AddBackForwardItem(itemID, pageID, toPageState(*item)), 0);
}
-void WebBackForwardListProxy::addItemFromUIProcess(uint64_t itemID, PassRefPtr<WebCore::HistoryItem> prpItem)
+void WebBackForwardListProxy::addItemFromUIProcess(uint64_t itemID, Ref<HistoryItem>&& item, uint64_t pageID)
{
- RefPtr<HistoryItem> item = prpItem;
-
// This item/itemID pair should not already exist in our maps.
- ASSERT(!historyItemToIDMap().contains(item.get()));
+ ASSERT(!historyItemToIDMap().contains(item.ptr()));
ASSERT(!idToHistoryItemMap().contains(itemID));
-
- historyItemToIDMap().set(item, itemID);
- idToHistoryItemMap().set(itemID, item);
+
+ historyItemToIDMap().set<ItemAndPageID>(item.ptr(), { .itemID = itemID, .pageID = pageID });
+ idToHistoryItemMap().set(itemID, item.ptr());
}
static void WK2NotifyHistoryItemChanged(HistoryItem* item)
{
- uint64_t itemID = historyItemToIDMap().get(item);
- if (!itemID)
+ ItemAndPageID ids = historyItemToIDMap().get(item);
+ if (!ids.itemID)
return;
- updateBackForwardItem(itemID, item);
+ updateBackForwardItem(ids.itemID, ids.pageID, item);
}
HistoryItem* WebBackForwardListProxy::itemForID(uint64_t itemID)
@@ -119,7 +121,7 @@ HistoryItem* WebBackForwardListProxy::itemForID(uint64_t itemID)
uint64_t WebBackForwardListProxy::idForItem(HistoryItem* item)
{
ASSERT(item);
- return historyItemToIDMap().get(item);
+ return historyItemToIDMap().get(item).itemID;
}
void WebBackForwardListProxy::removeItem(uint64_t itemID)
@@ -128,7 +130,8 @@ void WebBackForwardListProxy::removeItem(uint64_t itemID)
if (!item)
return;
- pageCache()->remove(item.get());
+ PageCache::singleton().remove(*item);
+ WebCore::Page::clearPreviousItemFromAllPages(item.get());
historyItemToIDMap().remove(item);
}
@@ -138,11 +141,9 @@ WebBackForwardListProxy::WebBackForwardListProxy(WebPage* page)
WebCore::notifyHistoryItemChanged = WK2NotifyHistoryItemChanged;
}
-void WebBackForwardListProxy::addItem(PassRefPtr<HistoryItem> prpItem)
+void WebBackForwardListProxy::addItem(Ref<HistoryItem>&& item)
{
- RefPtr<HistoryItem> item = prpItem;
-
- ASSERT(!historyItemToIDMap().contains(item));
+ ASSERT(!historyItemToIDMap().contains(item.ptr()));
if (!m_page)
return;
@@ -151,12 +152,10 @@ void WebBackForwardListProxy::addItem(PassRefPtr<HistoryItem> prpItem)
ASSERT(!idToHistoryItemMap().contains(itemID));
- m_associatedItemIDs.add(itemID);
-
- historyItemToIDMap().set(item, itemID);
- idToHistoryItemMap().set(itemID, item);
+ historyItemToIDMap().set<ItemAndPageID>(item.ptr(), { .itemID = itemID, .pageID = m_page->pageID() });
+ idToHistoryItemMap().set(itemID, item.ptr());
- updateBackForwardItem(itemID, item.get());
+ updateBackForwardItem(itemID, m_page->pageID(), item.ptr());
m_page->send(Messages::WebPageProxy::BackForwardAddItem(itemID));
}
@@ -166,7 +165,7 @@ void WebBackForwardListProxy::goToItem(HistoryItem* item)
return;
SandboxExtension::Handle sandboxExtensionHandle;
- m_page->sendSync(Messages::WebPageProxy::BackForwardGoToItem(historyItemToIDMap().get(item)), Messages::WebPageProxy::BackForwardGoToItem::Reply(sandboxExtensionHandle));
+ m_page->sendSync(Messages::WebPageProxy::BackForwardGoToItem(historyItemToIDMap().get(item).itemID), Messages::WebPageProxy::BackForwardGoToItem::Reply(sandboxExtensionHandle));
m_page->sandboxExtensionTracker().beginLoad(m_page->mainWebFrame(), sandboxExtensionHandle);
}
@@ -176,7 +175,7 @@ HistoryItem* WebBackForwardListProxy::itemAtIndex(int itemIndex)
return 0;
uint64_t itemID = 0;
- if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::BackForwardItemAtIndex(itemIndex), Messages::WebPageProxy::BackForwardItemAtIndex::Reply(itemID), m_page->pageID()))
+ if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::BackForwardItemAtIndex(itemIndex), Messages::WebPageProxy::BackForwardItemAtIndex::Reply(itemID), m_page->pageID()))
return 0;
if (!itemID)
@@ -191,7 +190,7 @@ int WebBackForwardListProxy::backListCount()
return 0;
int backListCount = 0;
- if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::BackForwardBackListCount(), Messages::WebPageProxy::BackForwardBackListCount::Reply(backListCount), m_page->pageID()))
+ if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::BackForwardBackListCount(), Messages::WebPageProxy::BackForwardBackListCount::Reply(backListCount), m_page->pageID()))
return 0;
return backListCount;
@@ -203,7 +202,7 @@ int WebBackForwardListProxy::forwardListCount()
return 0;
int forwardListCount = 0;
- if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::BackForwardForwardListCount(), Messages::WebPageProxy::BackForwardForwardListCount::Reply(forwardListCount), m_page->pageID()))
+ if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::BackForwardForwardListCount(), Messages::WebPageProxy::BackForwardForwardListCount::Reply(forwardListCount), m_page->pageID()))
return 0;
return forwardListCount;
@@ -211,19 +210,7 @@ int WebBackForwardListProxy::forwardListCount()
void WebBackForwardListProxy::close()
{
- HashSet<uint64_t>::iterator end = m_associatedItemIDs.end();
- for (HashSet<uint64_t>::iterator i = m_associatedItemIDs.begin(); i != end; ++i)
- WebCore::pageCache()->remove(itemForID(*i));
-
- m_associatedItemIDs.clear();
-
- m_page = 0;
-}
-
-bool WebBackForwardListProxy::isActive()
-{
- // FIXME: Should check the the list is enabled and has non-zero capacity.
- return true;
+ m_page = nullptr;
}
void WebBackForwardListProxy::clear()
diff --git a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h
index e47eed74f..d43f948ca 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h
@@ -28,7 +28,6 @@
#include <WebCore/BackForwardClient.h>
#include <wtf/HashSet.h>
-#include <wtf/PassRefPtr.h>
namespace WebKit {
@@ -36,13 +35,13 @@ class WebPage;
class WebBackForwardListProxy : public WebCore::BackForwardClient {
public:
- static PassRefPtr<WebBackForwardListProxy> create(WebPage* page) { return adoptRef(new WebBackForwardListProxy(page)); }
+ static Ref<WebBackForwardListProxy> create(WebPage* page) { return adoptRef(*new WebBackForwardListProxy(page)); }
static WebCore::HistoryItem* itemForID(uint64_t);
static uint64_t idForItem(WebCore::HistoryItem*);
static void removeItem(uint64_t itemID);
- static void addItemFromUIProcess(uint64_t itemID, PassRefPtr<WebCore::HistoryItem>);
+ void addItemFromUIProcess(uint64_t itemID, Ref<WebCore::HistoryItem>&&, uint64_t pageID);
static void setHighestItemIDFromUIProcess(uint64_t itemID);
void clear();
@@ -50,26 +49,17 @@ public:
private:
WebBackForwardListProxy(WebPage*);
- virtual void addItem(PassRefPtr<WebCore::HistoryItem>);
+ void addItem(Ref<WebCore::HistoryItem>&&) override;
- virtual void goToItem(WebCore::HistoryItem*);
+ void goToItem(WebCore::HistoryItem*) override;
- virtual WebCore::HistoryItem* itemAtIndex(int);
- virtual int backListCount();
- virtual int forwardListCount();
+ WebCore::HistoryItem* itemAtIndex(int) override;
+ int backListCount() override;
+ int forwardListCount() override;
- virtual bool isActive();
-
- virtual void close();
-
-#if PLATFORM(IOS)
- virtual unsigned current() override;
- virtual void setCurrent(unsigned newCurrent) override;
- virtual bool clearAllPageCaches() override;
-#endif
+ void close() override;
WebPage* m_page;
- HashSet<uint64_t> m_associatedItemIDs;
};
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp
index f6c940e7a..4a663d295 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp
@@ -25,12 +25,12 @@
#include "WebContextMenu.h"
-#include "InjectedBundleHitTestResult.h"
-#include "InjectedBundleUserMessageCoders.h"
+#include "ContextMenuContextData.h"
+#include "UserData.h"
#include "WebCoreArgumentCoders.h"
-#include "WebHitTestResult.h"
#include "WebPage.h"
#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
#include <WebCore/ContextMenu.h>
#include <WebCore/ContextMenuController.h>
#include <WebCore/Frame.h>
@@ -53,9 +53,6 @@ WebContextMenu::~WebContextMenu()
void WebContextMenu::show()
{
ContextMenuController& controller = m_page->corePage()->contextMenuController();
- ContextMenu* menu = controller.contextMenu();
- if (!menu)
- return;
Frame* frame = controller.hitTestResult().innerNodeFrame();
if (!frame)
return;
@@ -66,17 +63,19 @@ void WebContextMenu::show()
Vector<WebContextMenuItemData> menuItems;
RefPtr<API::Object> userData;
menuItemsWithUserData(menuItems, userData);
- WebHitTestResult::Data webHitTestResultData(controller.hitTestResult());
+
+ auto menuLocation = view->contentsToRootView(controller.hitTestResult().roundedPointInInnerNodeFrame());
+
+ ContextMenuContextData contextMenuContextData(menuLocation, menuItems, controller.context());
// Mark the WebPage has having a shown context menu then notify the UIProcess.
m_page->contextMenuShowing();
- m_page->send(Messages::WebPageProxy::ShowContextMenu(view->contentsToWindow(controller.hitTestResult().roundedPointInInnerNodeFrame()), webHitTestResultData, menuItems, InjectedBundleUserMessageEncoder(userData.get())));
+ m_page->send(Messages::WebPageProxy::ShowContextMenu(contextMenuContextData, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
}
void WebContextMenu::itemSelected(const WebContextMenuItemData& item)
{
- ContextMenuItem coreItem(ActionType, static_cast<ContextMenuAction>(item.action()), item.title());
- m_page->corePage()->contextMenuController().contextMenuItemSelected(&coreItem);
+ m_page->corePage()->contextMenuController().contextMenuItemSelected(static_cast<ContextMenuAction>(item.action()), item.title());
}
void WebContextMenu::menuItemsWithUserData(Vector<WebContextMenuItemData> &menuItems, RefPtr<API::Object>& userData) const
@@ -88,17 +87,11 @@ void WebContextMenu::menuItemsWithUserData(Vector<WebContextMenuItemData> &menuI
return;
// Give the bundle client a chance to process the menu.
-#if USE(CROSS_PLATFORM_CONTEXT_MENUS)
const Vector<ContextMenuItem>& coreItems = menu->items();
-#else
- Vector<ContextMenuItem> coreItems = contextMenuItemVector(menu->platformDescription());
-#endif
- Vector<WebContextMenuItemData> proposedMenu = kitItems(coreItems, menu);
- Vector<WebContextMenuItemData> newMenu;
- RefPtr<InjectedBundleHitTestResult> hitTestResult = InjectedBundleHitTestResult::create(controller.hitTestResult());
- if (m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(m_page, hitTestResult.get(), proposedMenu, newMenu, userData))
- proposedMenu = newMenu;
- menuItems = proposedMenu;
+
+ if (m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(*m_page, controller.hitTestResult(), coreItems, menuItems, userData))
+ return;
+ menuItems = kitItems(coreItems);
}
Vector<WebContextMenuItemData> WebContextMenu::items() const
diff --git a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h
index 75ed7e69a..aded5a67b 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h
@@ -25,18 +25,23 @@
#include "WebContextMenuItemData.h"
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+class Image;
+}
namespace WebKit {
+class ShareableBitmap;
class WebPage;
class WebContextMenu : public RefCounted<WebContextMenu> {
public:
- static PassRefPtr<WebContextMenu> create(WebPage* page)
+ static Ref<WebContextMenu> create(WebPage* page)
{
- return adoptRef(new WebContextMenu(page));
+ return adoptRef(*new WebContextMenu(page));
}
~WebContextMenu();
diff --git a/Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.cpp b/Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.cpp
index 4b6a1633c..56fea2208 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "WebDocumentLoader.h"
+#include "WebFrame.h"
+
using namespace WebCore;
namespace WebKit {
@@ -36,6 +38,16 @@ WebDocumentLoader::WebDocumentLoader(const ResourceRequest& request, const Subst
{
}
+void WebDocumentLoader::detachFromFrame()
+{
+ if (m_navigationID)
+ WebFrame::fromCoreFrame(*frame())->documentLoaderDetached(m_navigationID);
+
+ m_navigationID = 0;
+
+ DocumentLoader::detachFromFrame();
+}
+
void WebDocumentLoader::setNavigationID(uint64_t navigationID)
{
ASSERT(navigationID);
diff --git a/Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.h b/Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.h
index 90476107a..f127d64d0 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebDocumentLoader.h
@@ -32,9 +32,9 @@ namespace WebKit {
class WebDocumentLoader : public WebCore::DocumentLoader {
public:
- static PassRefPtr<WebDocumentLoader> create(const WebCore::ResourceRequest& request, const WebCore::SubstituteData& data)
+ static Ref<WebDocumentLoader> create(const WebCore::ResourceRequest& request, const WebCore::SubstituteData& data)
{
- return adoptRef(new WebDocumentLoader(request, data));
+ return adoptRef(*new WebDocumentLoader(request, data));
}
uint64_t navigationID() const { return m_navigationID; }
@@ -43,6 +43,8 @@ public:
private:
WebDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&);
+ void detachFromFrame() override;
+
uint64_t m_navigationID;
};
diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp
index 4b9845d86..30203c647 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,14 +28,20 @@
#include "APIArray.h"
#include "DownloadManager.h"
+#include "FrameInfoData.h"
+#include "InjectedBundleFileHandle.h"
#include "InjectedBundleHitTestResult.h"
#include "InjectedBundleNodeHandle.h"
#include "InjectedBundleRangeHandle.h"
#include "InjectedBundleScriptWorld.h"
+#include "NetworkConnectionToWebProcessMessages.h"
+#include "NetworkProcessConnection.h"
#include "PluginView.h"
#include "WKAPICast.h"
#include "WKBundleAPICast.h"
#include "WebChromeClient.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebDocumentLoader.h"
#include "WebPage.h"
#include "WebPageProxyMessages.h"
#include "WebProcess.h"
@@ -44,18 +50,24 @@
#include <JavaScriptCore/JSLock.h>
#include <JavaScriptCore/JSValueRef.h>
#include <WebCore/ArchiveResource.h>
+#include <WebCore/CertificateInfo.h>
#include <WebCore/Chrome.h>
#include <WebCore/DocumentLoader.h>
#include <WebCore/EventHandler.h>
+#include <WebCore/File.h>
#include <WebCore/Frame.h>
+#include <WebCore/FrameSnapshotting.h>
#include <WebCore/FrameView.h>
#include <WebCore/HTMLFormElement.h>
#include <WebCore/HTMLFrameOwnerElement.h>
#include <WebCore/HTMLInputElement.h>
#include <WebCore/HTMLNames.h>
+#include <WebCore/HTMLSelectElement.h>
#include <WebCore/HTMLTextAreaElement.h>
+#include <WebCore/ImageBuffer.h>
#include <WebCore/JSCSSStyleDeclaration.h>
#include <WebCore/JSElement.h>
+#include <WebCore/JSFile.h>
#include <WebCore/JSRange.h>
#include <WebCore/MainFrame.h>
#include <WebCore/NetworkingContext.h>
@@ -63,24 +75,17 @@
#include <WebCore/Page.h>
#include <WebCore/PluginDocument.h>
#include <WebCore/RenderTreeAsText.h>
-#include <WebCore/ResourceBuffer.h>
-#include <WebCore/ResourceLoader.h>
#include <WebCore/ScriptController.h>
#include <WebCore/SecurityOrigin.h>
+#include <WebCore/SubresourceLoader.h>
#include <WebCore/TextIterator.h>
#include <WebCore/TextResourceDecoder.h>
#include <wtf/text/StringBuilder.h>
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#include <WebCore/LegacyWebArchive.h>
#endif
-#if ENABLE(NETWORK_PROCESS)
-#include "NetworkConnectionToWebProcessMessages.h"
-#include "NetworkProcessConnection.h"
-#include "WebCoreArgumentCoders.h"
-#endif
-
#ifndef NDEBUG
#include <wtf/RefCountedLeakCounter.h>
#endif
@@ -104,54 +109,51 @@ static uint64_t generateListenerID()
return uniqueListenerID++;
}
-PassRefPtr<WebFrame> WebFrame::createWithCoreMainFrame(WebPage* page, WebCore::Frame* coreFrame)
+Ref<WebFrame> WebFrame::createWithCoreMainFrame(WebPage* page, WebCore::Frame* coreFrame)
{
- RefPtr<WebFrame> frame = create(std::unique_ptr<WebFrameLoaderClient>(static_cast<WebFrameLoaderClient*>(&coreFrame->loader().client())));
- page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()));
+ auto frame = create(std::unique_ptr<WebFrameLoaderClient>(static_cast<WebFrameLoaderClient*>(&coreFrame->loader().client())));
+ page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()), page->pageID(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
frame->m_coreFrame = coreFrame;
frame->m_coreFrame->tree().setName(String());
frame->m_coreFrame->init();
- return frame.release();
+ return frame;
}
-PassRefPtr<WebFrame> WebFrame::createSubframe(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
+Ref<WebFrame> WebFrame::createSubframe(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
{
- RefPtr<WebFrame> frame = create(std::make_unique<WebFrameLoaderClient>());
- page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID()));
+ auto frame = create(std::make_unique<WebFrameLoaderClient>());
+ page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID()), page->pageID(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+
+ auto coreFrame = Frame::create(page->corePage(), ownerElement, frame->m_frameLoaderClient.get());
+ frame->m_coreFrame = coreFrame.ptr();
- RefPtr<Frame> coreFrame = Frame::create(page->corePage(), ownerElement, frame->m_frameLoaderClient.get());
- frame->m_coreFrame = coreFrame.get();
- frame->m_coreFrame->tree().setName(frameName);
+ coreFrame->tree().setName(frameName);
if (ownerElement) {
ASSERT(ownerElement->document().frame());
- ownerElement->document().frame()->tree().appendChild(coreFrame.release());
+ ownerElement->document().frame()->tree().appendChild(coreFrame.get());
}
- frame->m_coreFrame->init();
- return frame.release();
+ coreFrame->init();
+
+ return frame;
}
-PassRefPtr<WebFrame> WebFrame::create(std::unique_ptr<WebFrameLoaderClient> frameLoaderClient)
+Ref<WebFrame> WebFrame::create(std::unique_ptr<WebFrameLoaderClient> frameLoaderClient)
{
- RefPtr<WebFrame> frame = adoptRef(new WebFrame(std::move(frameLoaderClient)));
+ auto frame = adoptRef(*new WebFrame(WTFMove(frameLoaderClient)));
// Add explict ref() that will be balanced in WebFrameLoaderClient::frameLoaderDestroyed().
frame->ref();
- return frame.release();
+ return frame;
}
WebFrame::WebFrame(std::unique_ptr<WebFrameLoaderClient> frameLoaderClient)
- : m_coreFrame(0)
- , m_policyListenerID(0)
- , m_policyFunction(0)
- , m_policyDownloadID(0)
- , m_frameLoaderClient(std::move(frameLoaderClient))
- , m_loadListener(0)
+ : m_frameLoaderClient(WTFMove(frameLoaderClient))
, m_frameID(generateFrameID())
{
m_frameLoaderClient->setWebFrame(this);
- WebProcess::shared().addWebFrame(m_frameID, this);
+ WebProcess::singleton().addWebFrame(m_frameID, this);
#ifndef NDEBUG
webFrameCounter.increment();
@@ -178,9 +180,31 @@ WebPage* WebFrame::page() const
return 0;
}
+WebFrame* WebFrame::fromCoreFrame(Frame& frame)
+{
+ auto* webFrameLoaderClient = toWebFrameLoaderClient(frame.loader().client());
+ if (!webFrameLoaderClient)
+ return nullptr;
+
+ return webFrameLoaderClient->webFrame();
+}
+
+FrameInfoData WebFrame::info() const
+{
+ FrameInfoData info;
+
+ info.isMainFrame = isMainFrame();
+ // FIXME: This should use the full request.
+ info.request = ResourceRequest(URL(URL(), url()));
+ info.securityOrigin = SecurityOriginData::fromFrame(m_coreFrame);
+ info.frameID = m_frameID;
+
+ return info;
+}
+
void WebFrame::invalidate()
{
- WebProcess::shared().removeWebFrame(m_frameID);
+ WebProcess::singleton().removeWebFrame(m_frameID);
m_coreFrame = 0;
}
@@ -200,12 +224,12 @@ void WebFrame::invalidatePolicyListener()
if (!m_policyListenerID)
return;
- m_policyDownloadID = 0;
+ m_policyDownloadID = { };
m_policyListenerID = 0;
m_policyFunction = 0;
}
-void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t downloadID)
+void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t navigationID, DownloadID downloadID)
{
if (!m_coreFrame)
return;
@@ -218,65 +242,54 @@ void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action
ASSERT(m_policyFunction);
- FramePolicyFunction function = std::move(m_policyFunction);
+ FramePolicyFunction function = WTFMove(m_policyFunction);
invalidatePolicyListener();
m_policyDownloadID = downloadID;
+ if (navigationID) {
+ if (WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(m_coreFrame->loader().policyDocumentLoader()))
+ documentLoader->setNavigationID(navigationID);
+ }
+
function(action);
}
-void WebFrame::startDownload(const WebCore::ResourceRequest& request)
+void WebFrame::startDownload(const WebCore::ResourceRequest& request, const String& suggestedName)
{
- ASSERT(m_policyDownloadID);
-
- uint64_t policyDownloadID = m_policyDownloadID;
- m_policyDownloadID = 0;
+ ASSERT(m_policyDownloadID.downloadID());
-#if ENABLE(NETWORK_PROCESS)
- if (WebProcess::shared().usesNetworkProcess()) {
- WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::StartDownload(page()->sessionID(), policyDownloadID, request), 0);
- return;
- }
-#endif
+ auto policyDownloadID = m_policyDownloadID;
+ m_policyDownloadID = { };
- WebProcess::shared().downloadManager().startDownload(policyDownloadID, request);
+ auto& webProcess = WebProcess::singleton();
+ SessionID sessionID = page() ? page()->sessionID() : SessionID::defaultSessionID();
+ webProcess.networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::StartDownload(sessionID, policyDownloadID, request, suggestedName), 0);
}
-void WebFrame::convertMainResourceLoadToDownload(DocumentLoader* documentLoader, const ResourceRequest& request, const ResourceResponse& response)
+void WebFrame::convertMainResourceLoadToDownload(DocumentLoader* documentLoader, SessionID sessionID, const ResourceRequest& request, const ResourceResponse& response)
{
- ASSERT(m_policyDownloadID);
-
- uint64_t policyDownloadID = m_policyDownloadID;
- m_policyDownloadID = 0;
+ ASSERT(m_policyDownloadID.downloadID());
- ResourceLoader* mainResourceLoader = documentLoader->mainResourceLoader();
+ auto policyDownloadID = m_policyDownloadID;
+ m_policyDownloadID = { };
-#if ENABLE(NETWORK_PROCESS)
- if (WebProcess::shared().usesNetworkProcess()) {
- // Use 0 to indicate that there is no main resource loader.
- // This can happen if the main resource is in the WebCore memory cache.
- uint64_t mainResourceLoadIdentifier;
- if (mainResourceLoader)
- mainResourceLoadIdentifier = mainResourceLoader->identifier();
- else
- mainResourceLoadIdentifier = 0;
+ SubresourceLoader* mainResourceLoader = documentLoader->mainResourceLoader();
- WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::ConvertMainResourceLoadToDownload(mainResourceLoadIdentifier, policyDownloadID, request, response), 0);
- return;
- }
-#endif
-
- if (!mainResourceLoader) {
- // The main resource has already been loaded. Start a new download instead.
- WebProcess::shared().downloadManager().startDownload(policyDownloadID, request);
- return;
- }
+ auto& webProcess = WebProcess::singleton();
+ // Use 0 to indicate that the resource load can't be converted and a new download must be started.
+ // This can happen if there is no loader because the main resource is in the WebCore memory cache,
+ // or because the conversion was attempted when not calling SubresourceLoader::didReceiveResponse().
+ uint64_t mainResourceLoadIdentifier;
+ if (mainResourceLoader)
+ mainResourceLoadIdentifier = mainResourceLoader->identifier();
+ else
+ mainResourceLoadIdentifier = 0;
- WebProcess::shared().downloadManager().convertHandleToDownload(policyDownloadID, documentLoader->mainResourceLoader()->handle(), request, response);
+ webProcess.networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::ConvertMainResourceLoadToDownload(sessionID, mainResourceLoadIdentifier, policyDownloadID, request, response), 0);
}
-String WebFrame::source() const
+String WebFrame::source() const
{
if (!m_coreFrame)
return String();
@@ -289,7 +302,7 @@ String WebFrame::source() const
DocumentLoader* documentLoader = m_coreFrame->loader().activeDocumentLoader();
if (!documentLoader)
return String();
- RefPtr<ResourceBuffer> mainResourceData = documentLoader->mainResourceData();
+ RefPtr<SharedBuffer> mainResourceData = documentLoader->mainResourceData();
if (!mainResourceData)
return String();
return decoder->encoding().decode(mainResourceData->data(), mainResourceData->size());
@@ -306,8 +319,7 @@ String WebFrame::contentsAsString() const
if (!builder.isEmpty())
builder.append(' ');
- WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(child->loader().client());
- WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
+ WebFrame* webFrame = WebFrame::fromCoreFrame(*child);
ASSERT(webFrame);
builder.append(webFrame->contentsAsString());
@@ -326,9 +338,7 @@ String WebFrame::contentsAsString() const
RefPtr<Range> range = document->createRange();
- ExceptionCode ec = 0;
- range->selectNode(documentElement.get(), ec);
- if (ec)
+ if (range->selectNode(*documentElement).hasException())
return String();
return plainText(range.get());
@@ -393,6 +403,18 @@ String WebFrame::url() const
return documentLoader->url().string();
}
+CertificateInfo WebFrame::certificateInfo() const
+{
+ if (!m_coreFrame)
+ return { };
+
+ DocumentLoader* documentLoader = m_coreFrame->loader().documentLoader();
+ if (!documentLoader)
+ return { };
+
+ return valueOrCompute(documentLoader->response().certificateInfo(), [] { return CertificateInfo(); });
+}
+
String WebFrame::innerText() const
{
if (!m_coreFrame)
@@ -409,11 +431,10 @@ WebFrame* WebFrame::parentFrame() const
if (!m_coreFrame || !m_coreFrame->ownerElement())
return 0;
- WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(m_coreFrame->ownerElement()->document().frame()->loader().client());
- return webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
+ return WebFrame::fromCoreFrame(*m_coreFrame->ownerElement()->document().frame());
}
-PassRefPtr<API::Array> WebFrame::childFrames()
+Ref<API::Array> WebFrame::childFrames()
{
if (!m_coreFrame)
return API::Array::create();
@@ -426,13 +447,12 @@ PassRefPtr<API::Array> WebFrame::childFrames()
vector.reserveInitialCapacity(size);
for (Frame* child = m_coreFrame->tree().firstChild(); child; child = child->tree().nextSibling()) {
- WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(child->loader().client());
- WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
+ WebFrame* webFrame = WebFrame::fromCoreFrame(*child);
ASSERT(webFrame);
vector.uncheckedAppend(webFrame);
}
- return API::Array::create(std::move(vector));
+ return API::Array::create(WTFMove(vector));
}
String WebFrame::layerTreeAsText() const
@@ -456,7 +476,7 @@ bool WebFrame::allowsFollowingLink(const WebCore::URL& url) const
if (!m_coreFrame)
return true;
- return m_coreFrame->document()->securityOrigin()->canDisplay(url);
+ return m_coreFrame->document()->securityOrigin().canDisplay(url);
}
JSGlobalContextRef WebFrame::jsContext()
@@ -479,6 +499,35 @@ bool WebFrame::handlesPageScaleGesture() const
return pluginView && pluginView->handlesPageScaleFactor();
}
+bool WebFrame::requiresUnifiedScaleFactor() const
+{
+ if (!m_coreFrame->document()->isPluginDocument())
+ return 0;
+
+ PluginDocument* pluginDocument = static_cast<PluginDocument*>(m_coreFrame->document());
+ PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
+ return pluginView && pluginView->requiresUnifiedScaleFactor();
+}
+
+void WebFrame::setAccessibleName(const String& accessibleName)
+{
+ if (!AXObjectCache::accessibilityEnabled())
+ return;
+
+ if (!m_coreFrame)
+ return;
+
+ auto* document = m_coreFrame->document();
+ if (!document)
+ return;
+
+ auto* rootObject = document->axObjectCache()->rootObject();
+ if (!rootObject)
+ return;
+
+ rootObject->setAccessibleName(accessibleName);
+}
+
IntRect WebFrame::contentBounds() const
{
if (!m_coreFrame)
@@ -526,7 +575,7 @@ IntSize WebFrame::scrollOffset() const
if (!view)
return IntSize();
- return view->scrollOffset();
+ return toIntSize(view->scrollPosition());
}
bool WebFrame::hasHorizontalScrollbar() const
@@ -558,7 +607,7 @@ PassRefPtr<InjectedBundleHitTestResult> WebFrame::hitTest(const IntPoint point)
if (!m_coreFrame)
return 0;
- return InjectedBundleHitTestResult::create(m_coreFrame->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent));
+ return InjectedBundleHitTestResult::create(m_coreFrame->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent));
}
bool WebFrame::getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha)
@@ -587,10 +636,10 @@ bool WebFrame::containsAnyFormElements() const
if (!document)
return false;
- for (Node* node = document->documentElement(); node; node = NodeTraversal::next(node)) {
- if (!node->isElementNode())
+ for (Node* node = document->documentElement(); node; node = NodeTraversal::next(*node)) {
+ if (!is<Element>(*node))
continue;
- if (isHTMLFormElement(node))
+ if (is<HTMLFormElement>(*node))
return true;
}
return false;
@@ -605,10 +654,10 @@ bool WebFrame::containsAnyFormControls() const
if (!document)
return false;
- for (Node* node = document->documentElement(); node; node = NodeTraversal::next(node)) {
- if (!node->isElementNode())
+ for (Node* node = document->documentElement(); node; node = NodeTraversal::next(*node)) {
+ if (!is<Element>(*node))
continue;
- if (isHTMLInputElement(node) || isHTMLSelectElement(node) || isHTMLTextAreaElement(node))
+ if (is<HTMLInputElement>(*node) || is<HTMLSelectElement>(*node) || is<HTMLTextAreaElement>(*node))
return true;
}
return false;
@@ -624,15 +673,12 @@ void WebFrame::stopLoading()
WebFrame* WebFrame::frameForContext(JSContextRef context)
{
- JSObjectRef globalObjectRef = JSContextGetGlobalObject(context);
- JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
- if (strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell") != 0)
- return 0;
- Frame* coreFrame = static_cast<JSDOMWindowShell*>(globalObjectObj)->window()->impl().frame();
-
- WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(coreFrame->loader().client());
- return webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
+ JSC::JSGlobalObject* globalObjectObj = toJS(context)->lexicalGlobalObject();
+ JSDOMWindow* window = jsDynamicDowncast<JSDOMWindow*>(globalObjectObj->vm(), globalObjectObj);
+ if (!window)
+ return nullptr;
+ return WebFrame::fromCoreFrame(*(window->wrapped().frame()));
}
JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, InjectedBundleScriptWorld* world)
@@ -659,12 +705,24 @@ JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleRangeHandle* rangeHandle, I
return toRef(exec, toJS(exec, globalObject, rangeHandle->coreRange()));
}
+JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleFileHandle* fileHandle, InjectedBundleScriptWorld* world)
+{
+ if (!m_coreFrame)
+ return nullptr;
+
+ JSDOMWindow* globalObject = m_coreFrame->script().globalObject(world->coreWorld());
+ ExecState* exec = globalObject->globalExec();
+
+ JSLockHolder lock(exec);
+ return toRef(exec, toJS(exec, globalObject, fileHandle->coreFile()));
+}
+
String WebFrame::counterValue(JSObjectRef element)
{
- if (!toJS(element)->inherits(JSElement::info()))
+ if (!toJS(element)->inherits(*toJS(element)->vm(), JSElement::info()))
return String();
- return counterValueForElement(&jsCast<JSElement*>(toJS(element))->impl());
+ return counterValueForElement(&jsCast<JSElement*>(toJS(element))->wrapped());
}
String WebFrame::provisionalURL() const
@@ -734,15 +792,19 @@ void WebFrame::setTextDirection(const String& direction)
m_coreFrame->editor().setBaseWritingDirection(RightToLeftWritingDirection);
}
-#if PLATFORM(MAC)
+void WebFrame::documentLoaderDetached(uint64_t navigationID)
+{
+ page()->send(Messages::WebPageProxy::DidDestroyNavigation(navigationID));
+}
+
+#if PLATFORM(COCOA)
RetainPtr<CFDataRef> WebFrame::webArchiveData(FrameFilterFunction callback, void* context)
{
- RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(coreFrame()->document(), [this, callback, context](Frame& frame) -> bool {
+ RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(*coreFrame()->document(), [this, callback, context](Frame& frame) -> bool {
if (!callback)
return true;
- WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame.loader().client());
- WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
+ WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
ASSERT(webFrame);
return callback(toAPI(this), toAPI(webFrame), context);
@@ -754,5 +816,25 @@ RetainPtr<CFDataRef> WebFrame::webArchiveData(FrameFilterFunction callback, void
return archive->rawDataRepresentation();
}
#endif
+
+PassRefPtr<ShareableBitmap> WebFrame::createSelectionSnapshot() const
+{
+ std::unique_ptr<ImageBuffer> snapshot = snapshotSelection(*coreFrame(), WebCore::SnapshotOptionsForceBlackText);
+ if (!snapshot)
+ return nullptr;
+
+ auto sharedSnapshot = ShareableBitmap::createShareable(snapshot->internalSize(), ShareableBitmap::SupportsAlpha);
+ if (!sharedSnapshot)
+ return nullptr;
+
+ // FIXME: We should consider providing a way to use subpixel antialiasing for the snapshot
+ // if we're compositing this image onto a solid color (e.g. the modern find indicator style).
+ auto graphicsContext = sharedSnapshot->createGraphicsContext();
+ float deviceScaleFactor = coreFrame()->page()->deviceScaleFactor();
+ graphicsContext->scale(deviceScaleFactor);
+ graphicsContext->drawConsumingImageBuffer(WTFMove(snapshot), FloatPoint());
+
+ return WTFMove(sharedSnapshot);
+}
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.h b/Source/WebKit2/WebProcess/WebPage/WebFrame.h
index e337f1e92..5142a3704 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebFrame.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +27,8 @@
#define WebFrame_h
#include "APIObject.h"
+#include "DownloadID.h"
+#include "ShareableBitmap.h"
#include "WKBase.h"
#include "WebFrameLoaderClient.h"
#include <JavaScriptCore/JSBase.h>
@@ -43,41 +45,48 @@ class Array;
}
namespace WebCore {
+class CertificateInfo;
class Frame;
class HTMLFrameOwnerElement;
class IntPoint;
class IntRect;
+class SessionID;
class URL;
}
namespace WebKit {
+class InjectedBundleFileHandle;
class InjectedBundleHitTestResult;
class InjectedBundleNodeHandle;
class InjectedBundleRangeHandle;
class InjectedBundleScriptWorld;
class WebPage;
+struct FrameInfoData;
class WebFrame : public API::ObjectImpl<API::Object::Type::BundleFrame> {
public:
- static PassRefPtr<WebFrame> createWithCoreMainFrame(WebPage*, WebCore::Frame*);
- static PassRefPtr<WebFrame> createSubframe(WebPage*, const String& frameName, WebCore::HTMLFrameOwnerElement*);
+ static Ref<WebFrame> createWithCoreMainFrame(WebPage*, WebCore::Frame*);
+ static Ref<WebFrame> createSubframe(WebPage*, const String& frameName, WebCore::HTMLFrameOwnerElement*);
~WebFrame();
// Called when the FrameLoaderClient (and therefore the WebCore::Frame) is being torn down.
void invalidate();
WebPage* page() const;
+
+ static WebFrame* fromCoreFrame(WebCore::Frame&);
WebCore::Frame* coreFrame() const { return m_coreFrame; }
+ FrameInfoData info() const;
uint64_t frameID() const { return m_frameID; }
uint64_t setUpPolicyListener(WebCore::FramePolicyFunction);
void invalidatePolicyListener();
- void didReceivePolicyDecision(uint64_t listenerID, WebCore::PolicyAction, uint64_t downloadID);
+ void didReceivePolicyDecision(uint64_t listenerID, WebCore::PolicyAction, uint64_t navigationID, DownloadID);
- void startDownload(const WebCore::ResourceRequest&);
- void convertMainResourceLoadToDownload(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+ void startDownload(const WebCore::ResourceRequest&, const String& suggestedName = { });
+ void convertMainResourceLoadToDownload(WebCore::DocumentLoader*, WebCore::SessionID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
String source() const;
String contentsAsString() const;
@@ -89,10 +98,11 @@ public:
bool isMainFrame() const;
String name() const;
String url() const;
+ WebCore::CertificateInfo certificateInfo() const;
String innerText() const;
bool isFrameSet() const;
WebFrame* parentFrame() const;
- PassRefPtr<API::Array> childFrames();
+ Ref<API::Array> childFrames();
JSGlobalContextRef jsContext();
JSGlobalContextRef jsContextForWorld(InjectedBundleScriptWorld*);
WebCore::IntRect contentBounds() const;
@@ -107,11 +117,14 @@ public:
bool containsAnyFormControls() const;
void stopLoading();
bool handlesPageScaleGesture() const;
+ bool requiresUnifiedScaleFactor() const;
+ void setAccessibleName(const String&);
static WebFrame* frameForContext(JSContextRef);
JSValueRef jsWrapperForWorld(InjectedBundleNodeHandle*, InjectedBundleScriptWorld*);
JSValueRef jsWrapperForWorld(InjectedBundleRangeHandle*, InjectedBundleScriptWorld*);
+ JSValueRef jsWrapperForWorld(InjectedBundleFileHandle*, InjectedBundleScriptWorld*);
static String counterValue(JSObjectRef element);
@@ -127,6 +140,8 @@ public:
void setTextDirection(const String&);
+ void documentLoaderDetached(uint64_t navigationID);
+
// Simple listener class used by plug-ins to know when frames finish or fail loading.
class LoadListener {
public:
@@ -138,25 +153,36 @@ public:
void setLoadListener(LoadListener* loadListener) { m_loadListener = loadListener; }
LoadListener* loadListener() const { return m_loadListener; }
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
typedef bool (*FrameFilterFunction)(WKBundleFrameRef, WKBundleFrameRef subframe, void* context);
RetainPtr<CFDataRef> webArchiveData(FrameFilterFunction, void* context);
#endif
+ PassRefPtr<ShareableBitmap> createSelectionSnapshot() const;
+
+#if PLATFORM(IOS)
+ uint64_t firstLayerTreeTransactionIDAfterDidCommitLoad() const { return m_firstLayerTreeTransactionIDAfterDidCommitLoad; }
+ void setFirstLayerTreeTransactionIDAfterDidCommitLoad(uint64_t transactionID) { m_firstLayerTreeTransactionIDAfterDidCommitLoad = transactionID; }
+#endif
+
private:
- static PassRefPtr<WebFrame> create(std::unique_ptr<WebFrameLoaderClient>);
- WebFrame(std::unique_ptr<WebFrameLoaderClient>);
+ static Ref<WebFrame> create(std::unique_ptr<WebFrameLoaderClient>);
+ explicit WebFrame(std::unique_ptr<WebFrameLoaderClient>);
- WebCore::Frame* m_coreFrame;
+ WebCore::Frame* m_coreFrame { nullptr };
- uint64_t m_policyListenerID;
- WebCore::FramePolicyFunction m_policyFunction;
- uint64_t m_policyDownloadID;
+ uint64_t m_policyListenerID { 0 };
+ WebCore::FramePolicyFunction m_policyFunction { nullptr };
+ DownloadID m_policyDownloadID { 0 };
std::unique_ptr<WebFrameLoaderClient> m_frameLoaderClient;
- LoadListener* m_loadListener;
+ LoadListener* m_loadListener { nullptr };
- uint64_t m_frameID;
+ uint64_t m_frameID { 0 };
+
+#if PLATFORM(IOS)
+ uint64_t m_firstLayerTreeTransactionIDAfterDidCommitLoad { 0 };
+#endif
};
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp
index 91c13455b..5f59706ff 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2014-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,302 +26,290 @@
#include "config.h"
#include "WebInspector.h"
-#if ENABLE(INSPECTOR)
#include "WebFrame.h"
-#include "WebInspectorFrontendClient.h"
+#include "WebInspectorMessages.h"
#include "WebInspectorProxyMessages.h"
+#include "WebInspectorUIMessages.h"
#include "WebPage.h"
-#include "WebPageCreationParameters.h"
#include "WebProcess.h"
+#include <WebCore/Chrome.h>
+#include <WebCore/Document.h>
+#include <WebCore/FrameLoadRequest.h>
+#include <WebCore/FrameView.h>
#include <WebCore/InspectorController.h>
#include <WebCore/InspectorFrontendClient.h>
+#include <WebCore/InspectorPageAgent.h>
#include <WebCore/MainFrame.h>
+#include <WebCore/NotImplemented.h>
#include <WebCore/Page.h>
#include <WebCore/ScriptController.h>
-#include <inspector/InspectorAgentBase.h>
-#include <bindings/ScriptValue.h>
-#include <wtf/text/StringConcatenate.h>
+#include <WebCore/WindowFeatures.h>
using namespace WebCore;
+static const float minimumAttachedHeight = 250;
+static const float maximumAttachedHeightRatio = 0.75;
+static const float minimumAttachedWidth = 500;
+
namespace WebKit {
-PassRefPtr<WebInspector> WebInspector::create(WebPage* page, InspectorFrontendChannel* frontendChannel)
+Ref<WebInspector> WebInspector::create(WebPage* page)
{
- return adoptRef(new WebInspector(page, frontendChannel));
+ return adoptRef(*new WebInspector(page));
}
-WebInspector::WebInspector(WebPage* page, InspectorFrontendChannel* frontendChannel)
+WebInspector::WebInspector(WebPage* page)
: m_page(page)
- , m_inspectorPage(0)
- , m_frontendClient(0)
- , m_frontendChannel(frontendChannel)
-#if PLATFORM(MAC)
- , m_hasLocalizedStringsURL(false)
-#endif
-#if ENABLE(INSPECTOR_SERVER)
- , m_remoteFrontendConnected(false)
-#endif
-{
-}
-
-// Called from WebInspectorClient
-WebPage* WebInspector::createInspectorPage()
-{
- if (!m_page)
- return 0;
-
- ASSERT(!m_inspectorPage);
- ASSERT(!m_frontendClient);
-
- uint64_t inspectorPageID = 0;
- WebPageCreationParameters parameters;
-
- if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebInspectorProxy::CreateInspectorPage(),
- Messages::WebInspectorProxy::CreateInspectorPage::Reply(inspectorPageID, parameters),
- m_page->pageID(), std::chrono::milliseconds::max())) {
- return 0;
- }
-
- if (!inspectorPageID)
- return 0;
-
- WebProcess::shared().createWebPage(inspectorPageID, parameters);
- m_inspectorPage = WebProcess::shared().webPage(inspectorPageID);
- ASSERT(m_inspectorPage);
-
- auto frontendClient = std::make_unique<WebInspectorFrontendClient>(m_page, m_inspectorPage);
- m_frontendClient = frontendClient.get();
- m_inspectorPage->corePage()->inspectorController().setInspectorFrontendClient(std::move(frontendClient));
- return m_inspectorPage;
-}
-
-void WebInspector::destroyInspectorPage()
{
- m_inspectorPage = 0;
- m_frontendClient = 0;
- m_frontendChannel = 0;
}
-// Called from WebInspectorFrontendClient
-void WebInspector::didClose()
+WebInspector::~WebInspector()
{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::DidClose(), m_page->pageID());
- destroyInspectorPage();
+ if (m_frontendConnection)
+ m_frontendConnection->invalidate();
}
-void WebInspector::bringToFront()
-{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::BringToFront(), m_page->pageID());
-}
-
-void WebInspector::inspectedURLChanged(const String& urlString)
-{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::InspectedURLChanged(urlString), m_page->pageID());
-}
-
-void WebInspector::save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs)
-{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::Save(filename, content, base64Encoded, forceSaveAs), m_page->pageID());
-}
+// Called from WebInspectorClient
+void WebInspector::openFrontendConnection(bool underTest)
+{
+#if USE(UNIX_DOMAIN_SOCKETS)
+ IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
+ IPC::Connection::Identifier connectionIdentifier(socketPair.server);
+ IPC::Attachment connectionClientPort(socketPair.client);
+#elif OS(DARWIN)
+ mach_port_t listeningPort;
+ if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort) != KERN_SUCCESS)
+ CRASH();
+
+ if (mach_port_insert_right(mach_task_self(), listeningPort, listeningPort, MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS)
+ CRASH();
+
+ IPC::Connection::Identifier connectionIdentifier(listeningPort);
+ IPC::Attachment connectionClientPort(listeningPort, MACH_MSG_TYPE_MOVE_SEND);
+
+#else
+ notImplemented();
+ return;
+#endif
-void WebInspector::append(const String& filename, const String& content)
-{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::Append(filename, content), m_page->pageID());
-}
+ m_frontendConnection = IPC::Connection::createServerConnection(connectionIdentifier, *this);
+ m_frontendConnection->open();
-void WebInspector::attachBottom()
-{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachBottom(), m_page->pageID());
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::CreateInspectorPage(connectionClientPort, canAttachWindow(), underTest), m_page->pageID());
}
-void WebInspector::attachRight()
+void WebInspector::closeFrontendConnection()
{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachRight(), m_page->pageID());
-}
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::DidClose(), m_page->pageID());
-void WebInspector::detach()
-{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::Detach(), m_page->pageID());
-}
+ // If we tried to close the frontend before it was created, then no connection exists yet.
+ if (m_frontendConnection) {
+ m_frontendConnection->invalidate();
+ m_frontendConnection = nullptr;
+ }
-void WebInspector::setAttachedWindowHeight(unsigned height)
-{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowHeight(height), m_page->pageID());
+ m_attached = false;
+ m_previousCanAttach = false;
}
-void WebInspector::setAttachedWindowWidth(unsigned width)
-{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowWidth(width), m_page->pageID());
-}
-
-void WebInspector::setToolbarHeight(unsigned height)
+void WebInspector::bringToFront()
{
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SetToolbarHeight(height), m_page->pageID());
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::BringToFront(), m_page->pageID());
}
// Called by WebInspector messages
void WebInspector::show()
{
+ if (!m_page->corePage())
+ return;
+
m_page->corePage()->inspectorController().show();
}
void WebInspector::close()
{
- m_page->corePage()->inspectorController().close();
-}
+ if (!m_page->corePage())
+ return;
-void WebInspector::didSave(const String& url)
-{
- ASSERT(m_inspectorPage);
- m_inspectorPage->corePage()->mainFrame().script().executeScript(makeString("InspectorFrontendAPI.savedURL(\"", url, "\")"));
-}
+ // Close could be called multiple times during teardown.
+ if (!m_frontendConnection)
+ return;
-void WebInspector::didAppend(const String& url)
-{
- ASSERT(m_inspectorPage);
- m_inspectorPage->corePage()->mainFrame().script().executeScript(makeString("InspectorFrontendAPI.appendedToURL(\"", url, "\")"));
+ m_page->corePage()->inspectorController().disconnectFrontend(this);
+ closeFrontendConnection();
}
-void WebInspector::attachedBottom()
+void WebInspector::openInNewTab(const String& urlString)
{
- if (m_frontendClient)
- m_frontendClient->setAttachedWindow(InspectorFrontendClient::DOCKED_TO_BOTTOM);
-}
+ Page* inspectedPage = m_page->corePage();
+ if (!inspectedPage)
+ return;
-void WebInspector::attachedRight()
-{
- if (m_frontendClient)
- m_frontendClient->setAttachedWindow(InspectorFrontendClient::DOCKED_TO_RIGHT);
-}
+ Frame& inspectedMainFrame = inspectedPage->mainFrame();
+ FrameLoadRequest request(inspectedMainFrame.document()->securityOrigin(), ResourceRequest(urlString), "_blank", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
-void WebInspector::detached()
-{
- if (m_frontendClient)
- m_frontendClient->setAttachedWindow(InspectorFrontendClient::UNDOCKED);
+ Page* newPage = inspectedPage->chrome().createWindow(inspectedMainFrame, request, WindowFeatures(), NavigationAction(request.resourceRequest(), NavigationType::LinkClicked));
+ if (!newPage)
+ return;
+
+ newPage->mainFrame().loader().load(request);
}
-void WebInspector::evaluateScriptForTest(long callID, const String& script)
+void WebInspector::evaluateScriptForTest(const String& script)
{
- m_page->corePage()->inspectorController().evaluateForTestInFrontend(callID, script);
+ if (!m_page->corePage())
+ return;
+
+ m_page->corePage()->inspectorController().evaluateForTestInFrontend(script);
}
void WebInspector::showConsole()
{
+ if (!m_page->corePage())
+ return;
+
m_page->corePage()->inspectorController().show();
- if (m_frontendClient)
- m_frontendClient->showConsole();
+ m_frontendConnection->send(Messages::WebInspectorUI::ShowConsole(), 0);
}
void WebInspector::showResources()
{
+ if (!m_page->corePage())
+ return;
+
m_page->corePage()->inspectorController().show();
- if (m_frontendClient)
- m_frontendClient->showResources();
+ m_frontendConnection->send(Messages::WebInspectorUI::ShowResources(), 0);
}
-void WebInspector::showMainResourceForFrame(uint64_t frameID)
+void WebInspector::showTimelines()
{
- WebFrame* frame = WebProcess::shared().webFrame(frameID);
- if (!frame)
+ if (!m_page->corePage())
return;
m_page->corePage()->inspectorController().show();
- if (m_frontendClient)
- m_frontendClient->showMainResourceForFrame(frame->coreFrame());
+ m_frontendConnection->send(Messages::WebInspectorUI::ShowTimelines(), 0);
}
-void WebInspector::startJavaScriptDebugging()
+void WebInspector::showMainResourceForFrame(uint64_t frameIdentifier)
{
+ WebFrame* frame = WebProcess::singleton().webFrame(frameIdentifier);
+ if (!frame)
+ return;
+
+ if (!m_page->corePage())
+ return;
+
m_page->corePage()->inspectorController().show();
- if (m_frontendClient)
- m_frontendClient->setDebuggingEnabled(true);
+
+ String inspectorFrameIdentifier = m_page->corePage()->inspectorController().pageAgent()->frameId(frame->coreFrame());
+ m_frontendConnection->send(Messages::WebInspectorUI::ShowMainResourceForFrame(inspectorFrameIdentifier), 0);
}
-void WebInspector::stopJavaScriptDebugging()
+void WebInspector::startPageProfiling()
{
- m_page->corePage()->inspectorController().show();
- if (m_frontendClient)
- m_frontendClient->setDebuggingEnabled(false);
+ if (!m_page->corePage())
+ return;
+
+ m_frontendConnection->send(Messages::WebInspectorUI::StartPageProfiling(), 0);
}
-void WebInspector::setJavaScriptProfilingEnabled(bool enabled)
+void WebInspector::stopPageProfiling()
{
- m_page->corePage()->inspectorController().show();
- if (!m_frontendClient)
+ if (!m_page->corePage())
return;
- m_page->corePage()->inspectorController().setProfilerEnabled(enabled);
+ m_frontendConnection->send(Messages::WebInspectorUI::StopPageProfiling(), 0);
}
-void WebInspector::startJavaScriptProfiling()
+void WebInspector::startElementSelection()
{
- m_page->corePage()->inspectorController().show();
- if (m_frontendClient)
- m_frontendClient->startProfilingJavaScript();
+ if (!m_page->corePage())
+ return;
+
+ m_frontendConnection->send(Messages::WebInspectorUI::StartElementSelection(), 0);
}
-void WebInspector::stopJavaScriptProfiling()
+void WebInspector::stopElementSelection()
{
- m_page->corePage()->inspectorController().show();
- if (m_frontendClient)
- m_frontendClient->stopProfilingJavaScript();
+ if (!m_page->corePage())
+ return;
+
+ m_frontendConnection->send(Messages::WebInspectorUI::StopElementSelection(), 0);
}
-void WebInspector::startPageProfiling()
+void WebInspector::elementSelectionChanged(bool active)
{
- m_page->corePage()->inspectorController().show();
- if (m_frontendClient)
- m_frontendClient->setTimelineProfilingEnabled(true);
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::ElementSelectionChanged(active), m_page->pageID());
}
-void WebInspector::stopPageProfiling()
+bool WebInspector::canAttachWindow()
{
- m_page->corePage()->inspectorController().show();
- if (m_frontendClient)
- m_frontendClient->setTimelineProfilingEnabled(false);
+ if (!m_page->corePage())
+ return false;
+
+ // Don't allow attaching to another inspector -- two inspectors in one window is too much!
+ if (m_page->isInspectorPage())
+ return false;
+
+ // If we are already attached, allow attaching again to allow switching sides.
+ if (m_attached)
+ return true;
+
+ // Don't allow the attach if the window would be too small to accommodate the minimum inspector size.
+ unsigned inspectedPageHeight = m_page->corePage()->mainFrame().view()->visibleHeight();
+ unsigned inspectedPageWidth = m_page->corePage()->mainFrame().view()->visibleWidth();
+ unsigned maximumAttachedHeight = inspectedPageHeight * maximumAttachedHeightRatio;
+ return minimumAttachedHeight <= maximumAttachedHeight && minimumAttachedWidth <= inspectedPageWidth;
}
void WebInspector::updateDockingAvailability()
{
- if (!m_frontendClient)
+ if (m_attached)
+ return;
+
+ bool canAttachWindow = this->canAttachWindow();
+ if (m_previousCanAttach == canAttachWindow)
return;
- bool canAttachWindow = m_frontendClient->canAttachWindow();
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachAvailabilityChanged(canAttachWindow), m_page->pageID());
- m_frontendClient->setDockingUnavailable(!canAttachWindow);
+ m_previousCanAttach = canAttachWindow;
+
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachAvailabilityChanged(canAttachWindow), m_page->pageID());
}
-#if ENABLE(INSPECTOR_SERVER)
-void WebInspector::sendMessageToRemoteFrontend(const String& message)
+void WebInspector::sendMessageToBackend(const String& message)
{
- ASSERT(m_remoteFrontendConnected);
- WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SendMessageToRemoteFrontend(message), m_page->pageID());
+ if (!m_page->corePage())
+ return;
+
+ m_page->corePage()->inspectorController().dispatchMessageFromFrontend(message);
}
-void WebInspector::dispatchMessageFromRemoteFrontend(const String& message)
+void WebInspector::sendMessageToFrontend(const String& message)
{
- m_page->corePage()->inspectorController().dispatchMessageFromFrontend(message);
+#if ENABLE(INSPECTOR_SERVER)
+ if (m_remoteFrontendConnected)
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::SendMessageToRemoteFrontend(message), m_page->pageID());
+ else
+#endif
+ m_frontendConnection->send(Messages::WebInspectorUI::SendMessageToFrontend(message), 0);
}
+#if ENABLE(INSPECTOR_SERVER)
void WebInspector::remoteFrontendConnected()
{
- ASSERT(!m_remoteFrontendConnected);
- // Switching between in-process and remote inspectors isn't supported yet.
- ASSERT(!m_inspectorPage);
-
- m_page->corePage()->inspectorController().connectFrontend(m_frontendChannel);
- m_remoteFrontendConnected = true;
+ if (m_page->corePage()) {
+ m_remoteFrontendConnected = true;
+ m_page->corePage()->inspectorController().connectFrontend(this);
+ }
}
void WebInspector::remoteFrontendDisconnected()
{
- ASSERT(m_remoteFrontendConnected);
- m_page->corePage()->inspectorController().disconnectFrontend(Inspector::InspectorDisconnectReason::InspectorDestroyed);
m_remoteFrontendConnected = false;
+
+ if (m_page->corePage())
+ m_page->corePage()->inspectorController().disconnectFrontend(this);
}
#endif
} // namespace WebKit
-
-#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.h b/Source/WebKit2/WebProcess/WebPage/WebInspector.h
index 14f5a3ba6..c1a67a779 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebInspector.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2014, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,116 +23,96 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebInspector_h
-#define WebInspector_h
-
-#if ENABLE(INSPECTOR)
+#pragma once
#include "APIObject.h"
#include "Connection.h"
-#include <WebCore/InspectorForwarding.h>
+#include "MessageReceiver.h"
+#include <inspector/InspectorFrontendChannel.h>
#include <wtf/Noncopyable.h>
#include <wtf/text/WTFString.h>
namespace WebKit {
-class WebInspectorFrontendClient;
class WebPage;
-class WebInspector : public API::ObjectImpl<API::Object::Type::BundleInspector> {
+class WebInspector : public API::ObjectImpl<API::Object::Type::BundleInspector>, public IPC::Connection::Client, public Inspector::FrontendChannel {
public:
- static PassRefPtr<WebInspector> create(WebPage*, WebCore::InspectorFrontendChannel*);
+ static Ref<WebInspector> create(WebPage*);
WebPage* page() const { return m_page; }
- WebPage* inspectorPage() const { return m_inspectorPage; }
+
+ void updateDockingAvailability();
+
+ void sendMessageToFrontend(const String& message) override;
+ ConnectionType connectionType() const override { return ConnectionType::Local; }
// Implemented in generated WebInspectorMessageReceiver.cpp
- void didReceiveWebInspectorMessage(IPC::Connection*, IPC::MessageDecoder&);
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+
+ // IPC::Connection::Client
+ void didClose(IPC::Connection&) override { close(); }
+ void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) override { close(); }
// Called by WebInspector messages
+ void connectionEstablished();
+
void show();
void close();
- void didSave(const String& url);
- void didAppend(const String& url);
+ void openInNewTab(const String& urlString);
+
+ void canAttachWindow(bool& result);
+
+ void showConsole();
+ void showResources();
+ void showTimelines();
- void attachedBottom();
- void attachedRight();
- void detached();
+ void showMainResourceForFrame(uint64_t frameIdentifier);
- void evaluateScriptForTest(long callID, const String& script);
+ void setAttached(bool attached) { m_attached = attached; }
+
+ void evaluateScriptForTest(const String& script);
- void setJavaScriptProfilingEnabled(bool);
void startPageProfiling();
void stopPageProfiling();
+ void startElementSelection();
+ void stopElementSelection();
+ void elementSelectionChanged(bool);
+
+ void sendMessageToBackend(const String&);
+
#if ENABLE(INSPECTOR_SERVER)
- bool hasRemoteFrontendConnected() const { return m_remoteFrontendConnected; }
- void sendMessageToRemoteFrontend(const String& message);
- void dispatchMessageFromRemoteFrontend(const String& message);
void remoteFrontendConnected();
void remoteFrontendDisconnected();
#endif
+ void disconnectFromPage() { close(); }
+
private:
friend class WebInspectorClient;
- friend class WebInspectorFrontendClient;
- explicit WebInspector(WebPage*, WebCore::InspectorFrontendChannel*);
+ explicit WebInspector(WebPage*);
+ virtual ~WebInspector();
+
+ bool canAttachWindow();
// Called from WebInspectorClient
- WebPage* createInspectorPage();
- void destroyInspectorPage();
+ void openFrontendConnection(bool underTest);
+ void closeFrontendConnection();
- // Called from WebInspectorFrontendClient
- void didClose();
void bringToFront();
- void inspectedURLChanged(const String&);
-
- bool canSave() const;
- void save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs);
- void append(const String& filename, const String& content);
- void attachBottom();
- void attachRight();
- void detach();
-
- void setAttachedWindowHeight(unsigned);
- void setAttachedWindowWidth(unsigned);
- void setToolbarHeight(unsigned);
-
- // Implemented in platform WebInspector file
- String localizedStringsURL() const;
-
- void showConsole();
-
- void showResources();
-
- void showMainResourceForFrame(uint64_t frameID);
-
- void startJavaScriptDebugging();
- void stopJavaScriptDebugging();
-
- void startJavaScriptProfiling();
- void stopJavaScriptProfiling();
+ WebPage* m_page;
- void updateDockingAvailability();
+ RefPtr<IPC::Connection> m_frontendConnection;
- WebPage* m_page;
- WebPage* m_inspectorPage;
- WebInspectorFrontendClient* m_frontendClient;
- WebCore::InspectorFrontendChannel* m_frontendChannel;
-#if PLATFORM(MAC)
- mutable String m_localizedStringsURL;
- mutable bool m_hasLocalizedStringsURL;
-#endif
+ bool m_attached { false };
+ bool m_previousCanAttach { false };
#if ENABLE(INSPECTOR_SERVER)
- bool m_remoteFrontendConnected;
+ bool m_remoteFrontendConnected { false };
#endif
};
} // namespace WebKit
-
-#endif // ENABLE(INSPECTOR)
-
-#endif // WebInspector_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in b/Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in
index c23b86f21..45eccd822 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Apple Inc. All rights reserved.
+# Copyright (C) 2010, 2014 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -20,31 +20,30 @@
# 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.
-#if ENABLE(INSPECTOR)
-
-messages -> WebInspector LegacyReceiver {
+messages -> WebInspector {
Show()
Close()
- AttachedBottom()
- AttachedRight()
- Detached()
- DidSave(String url)
- DidAppend(String url)
+
+ SetAttached(bool attached)
+
ShowConsole()
ShowResources()
- ShowMainResourceForFrame(uint64_t frameID)
- StartJavaScriptDebugging()
- StopJavaScriptDebugging()
- StartJavaScriptProfiling()
- StopJavaScriptProfiling()
+ ShowTimelines()
+
+ ShowMainResourceForFrame(uint64_t frameIdentifier)
+
+ OpenInNewTab(String url)
+
StartPageProfiling()
StopPageProfiling()
+ StartElementSelection()
+ StopElementSelection()
+
+ SendMessageToBackend(String message)
+
#if ENABLE(INSPECTOR_SERVER)
- DispatchMessageFromRemoteFrontend(String message)
RemoteFrontendConnected()
RemoteFrontendDisconnected()
#endif
}
-
-#endif
diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspectorFrontendAPIDispatcher.cpp b/Source/WebKit2/WebProcess/WebPage/WebInspectorFrontendAPIDispatcher.cpp
new file mode 100644
index 000000000..5257731ea
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspectorFrontendAPIDispatcher.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "WebInspectorFrontendAPIDispatcher.h"
+
+#include "WebPage.h"
+#include <WebCore/MainFrame.h>
+#include <WebCore/ScriptController.h>
+#include <WebCore/ScriptState.h>
+
+namespace WebKit {
+
+WebInspectorFrontendAPIDispatcher::WebInspectorFrontendAPIDispatcher(WebPage& page)
+ : m_page(page)
+{
+}
+
+void WebInspectorFrontendAPIDispatcher::reset()
+{
+ m_frontendLoaded = false;
+ m_suspended = false;
+ m_queue.clear();
+}
+
+void WebInspectorFrontendAPIDispatcher::frontendLoaded()
+{
+ m_frontendLoaded = true;
+
+ evaluateQueuedExpressions();
+}
+
+void WebInspectorFrontendAPIDispatcher::suspend()
+{
+ ASSERT(m_frontendLoaded);
+ ASSERT(!m_suspended);
+ ASSERT(m_queue.isEmpty());
+
+ m_suspended = true;
+}
+
+void WebInspectorFrontendAPIDispatcher::unsuspend()
+{
+ ASSERT(m_suspended);
+
+ m_suspended = false;
+
+ evaluateQueuedExpressions();
+}
+
+void WebInspectorFrontendAPIDispatcher::dispatchCommand(const String& command)
+{
+ evaluateOrQueueExpression(makeString("InspectorFrontendAPI.dispatch([\"", command, "\"])"));
+}
+
+void WebInspectorFrontendAPIDispatcher::dispatchCommand(const String& command, const String& argument)
+{
+ evaluateOrQueueExpression(makeString("InspectorFrontendAPI.dispatch([\"", command, "\", \"", argument, "\"])"));
+}
+
+void WebInspectorFrontendAPIDispatcher::dispatchCommand(const String& command, bool argument)
+{
+ evaluateOrQueueExpression(makeString("InspectorFrontendAPI.dispatch([\"", command, "\", ", argument ? "true" : "false", "])"));
+}
+
+void WebInspectorFrontendAPIDispatcher::dispatchMessageAsync(const String& message)
+{
+ evaluateOrQueueExpression(makeString("InspectorFrontendAPI.dispatchMessageAsync(", message, ")"));
+}
+
+void WebInspectorFrontendAPIDispatcher::evaluateOrQueueExpression(const String& expression)
+{
+ if (!m_frontendLoaded || m_suspended) {
+ m_queue.append(expression);
+ return;
+ }
+
+ ASSERT(m_queue.isEmpty());
+ ASSERT(!m_page.corePage()->mainFrame().script().isPaused());
+ m_page.corePage()->mainFrame().script().executeScript(expression);
+}
+
+void WebInspectorFrontendAPIDispatcher::evaluateQueuedExpressions()
+{
+ if (m_queue.isEmpty())
+ return;
+
+ for (const String& expression : m_queue) {
+ ASSERT(!m_page.corePage()->mainFrame().script().isPaused());
+ m_page.corePage()->mainFrame().script().executeScript(expression);
+ }
+
+ m_queue.clear();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h b/Source/WebKit2/WebProcess/WebPage/WebInspectorFrontendAPIDispatcher.h
index a0e4c40b9..f5c424e2d 100644
--- a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspectorFrontendAPIDispatcher.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,34 +23,38 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DecoderAdapter_h
-#define DecoderAdapter_h
+#pragma once
-#include "ArgumentDecoder.h"
-#include <wtf/Decoder.h>
-#include <wtf/Forward.h>
+#include <wtf/Deque.h>
+#include <wtf/text/WTFString.h>
namespace WebKit {
-class DecoderAdapter : public Decoder {
+class WebPage;
+
+class WebInspectorFrontendAPIDispatcher {
public:
- DecoderAdapter(const uint8_t* buffer, size_t bufferSize);
+ WebInspectorFrontendAPIDispatcher(WebPage&);
+
+ void reset();
+ void frontendLoaded();
+
+ void suspend();
+ void unsuspend();
+
+ void dispatchCommand(const String& command);
+ void dispatchCommand(const String& command, const String& argument);
+ void dispatchCommand(const String& command, bool argument);
+ void dispatchMessageAsync(const String& message);
private:
- virtual bool decodeBytes(Vector<uint8_t>&);
- virtual bool decodeBool(bool&);
- virtual bool decodeUInt16(uint16_t&);
- virtual bool decodeUInt32(uint32_t&);
- virtual bool decodeUInt64(uint64_t&);
- virtual bool decodeInt32(int32_t&);
- virtual bool decodeInt64(int64_t&);
- virtual bool decodeFloat(float&);
- virtual bool decodeDouble(double&);
- virtual bool decodeString(String&);
-
- IPC::ArgumentDecoder m_decoder;
+ void evaluateOrQueueExpression(const String&);
+ void evaluateQueuedExpressions();
+
+ WebPage& m_page;
+ Deque<String> m_queue;
+ bool m_frontendLoaded { false };
+ bool m_suspended { false };
};
} // namespace WebKit
-
-#endif // DecoderAdapter_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.cpp b/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.cpp
new file mode 100644
index 000000000..a01edb370
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "WebInspectorUI.h"
+
+#include "WebInspectorMessages.h"
+#include "WebInspectorProxyMessages.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+#include <WebCore/Chrome.h>
+#include <WebCore/DOMWrapperWorld.h>
+#include <WebCore/InspectorController.h>
+#include <WebCore/NotImplemented.h>
+#include <WebCore/ScriptGlobalObject.h>
+#include <WebCore/ScriptState.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+Ref<WebInspectorUI> WebInspectorUI::create(WebPage& page)
+{
+ return adoptRef(*new WebInspectorUI(page));
+}
+
+WebInspectorUI::WebInspectorUI(WebPage& page)
+ : m_page(page)
+ , m_frontendAPIDispatcher(page)
+{
+}
+
+void WebInspectorUI::establishConnection(IPC::Attachment encodedConnectionIdentifier, uint64_t inspectedPageIdentifier, bool underTest, unsigned inspectionLevel)
+{
+#if USE(UNIX_DOMAIN_SOCKETS)
+ IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.releaseFileDescriptor());
+#elif OS(DARWIN)
+ IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port());
+#else
+ notImplemented();
+ return;
+#endif
+
+ if (IPC::Connection::identifierIsNull(connectionIdentifier))
+ return;
+
+ m_inspectedPageIdentifier = inspectedPageIdentifier;
+ m_frontendAPIDispatcher.reset();
+ m_underTest = underTest;
+ m_inspectionLevel = inspectionLevel;
+
+ m_frontendController = &m_page.corePage()->inspectorController();
+ m_frontendController->setInspectorFrontendClient(this);
+
+ m_backendConnection = IPC::Connection::createClientConnection(connectionIdentifier, *this);
+ m_backendConnection->open();
+}
+
+void WebInspectorUI::windowObjectCleared()
+{
+ if (m_frontendHost)
+ m_frontendHost->disconnectClient();
+
+ m_frontendHost = InspectorFrontendHost::create(this, m_page.corePage());
+ ScriptGlobalObject::set(*execStateFromPage(mainThreadNormalWorld(), m_page.corePage()), ASCIILiteral("InspectorFrontendHost"), *m_frontendHost);
+}
+
+void WebInspectorUI::frontendLoaded()
+{
+ m_frontendAPIDispatcher.frontendLoaded();
+
+ // Tell the new frontend about the current dock state. If the window object
+ // cleared due to a reload, the dock state won't be resent from UIProcess.
+ setDockingUnavailable(m_dockingUnavailable);
+ setDockSide(m_dockSide);
+ setIsVisible(m_isVisible);
+
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::FrontendLoaded(), m_inspectedPageIdentifier);
+
+ bringToFront();
+}
+
+void WebInspectorUI::startWindowDrag()
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::StartWindowDrag(), m_inspectedPageIdentifier);
+}
+
+void WebInspectorUI::moveWindowBy(float x, float y)
+{
+ FloatRect frameRect = m_page.corePage()->chrome().windowRect();
+ frameRect.move(x, y);
+ m_page.corePage()->chrome().setWindowRect(frameRect);
+}
+
+void WebInspectorUI::bringToFront()
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::BringToFront(), m_inspectedPageIdentifier);
+}
+
+void WebInspectorUI::closeWindow()
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::DidClose(), m_inspectedPageIdentifier);
+
+ if (m_backendConnection)
+ m_backendConnection->invalidate();
+ m_backendConnection = nullptr;
+
+ if (m_frontendController)
+ m_frontendController->setInspectorFrontendClient(nullptr);
+ m_frontendController = nullptr;
+
+ if (m_frontendHost)
+ m_frontendHost->disconnectClient();
+
+ m_inspectedPageIdentifier = 0;
+ m_underTest = false;
+}
+
+WebCore::UserInterfaceLayoutDirection WebInspectorUI::userInterfaceLayoutDirection() const
+{
+ return m_page.corePage()->userInterfaceLayoutDirection();
+}
+
+void WebInspectorUI::requestSetDockSide(DockSide side)
+{
+ auto& webProcess = WebProcess::singleton();
+ switch (side) {
+ case DockSide::Undocked:
+ webProcess.parentProcessConnection()->send(Messages::WebInspectorProxy::Detach(), m_inspectedPageIdentifier);
+ break;
+ case DockSide::Right:
+ webProcess.parentProcessConnection()->send(Messages::WebInspectorProxy::AttachRight(), m_inspectedPageIdentifier);
+ break;
+ case DockSide::Left:
+ webProcess.parentProcessConnection()->send(Messages::WebInspectorProxy::AttachLeft(), m_inspectedPageIdentifier);
+ break;
+ case DockSide::Bottom:
+ webProcess.parentProcessConnection()->send(Messages::WebInspectorProxy::AttachBottom(), m_inspectedPageIdentifier);
+ break;
+ }
+}
+
+void WebInspectorUI::setDockSide(DockSide side)
+{
+ const char* sideString;
+
+ switch (side) {
+ case DockSide::Undocked:
+ sideString = "undocked";
+ break;
+
+ case DockSide::Right:
+ sideString = "right";
+ break;
+
+ case DockSide::Left:
+ sideString = "left";
+ break;
+
+ case DockSide::Bottom:
+ sideString = "bottom";
+ break;
+ }
+
+ m_dockSide = side;
+
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setDockSide"), String(ASCIILiteral(sideString)));
+}
+
+void WebInspectorUI::setDockingUnavailable(bool unavailable)
+{
+ m_dockingUnavailable = unavailable;
+
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setDockingUnavailable"), unavailable);
+}
+
+void WebInspectorUI::setIsVisible(bool visible)
+{
+ m_isVisible = visible;
+
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setIsVisible"), visible);
+}
+
+void WebInspectorUI::changeAttachedWindowHeight(unsigned height)
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowHeight(height), m_inspectedPageIdentifier);
+}
+
+void WebInspectorUI::changeAttachedWindowWidth(unsigned width)
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowWidth(width), m_inspectedPageIdentifier);
+}
+
+void WebInspectorUI::openInNewTab(const String& url)
+{
+ if (m_backendConnection)
+ m_backendConnection->send(Messages::WebInspector::OpenInNewTab(url), 0);
+}
+
+void WebInspectorUI::save(const WTF::String& filename, const WTF::String& content, bool base64Encoded, bool forceSaveAs)
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::Save(filename, content, base64Encoded, forceSaveAs), m_inspectedPageIdentifier);
+}
+
+void WebInspectorUI::append(const WTF::String& filename, const WTF::String& content)
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::Append(filename, content), m_inspectedPageIdentifier);
+}
+
+void WebInspectorUI::inspectedURLChanged(const String& urlString)
+{
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::InspectedURLChanged(urlString), m_inspectedPageIdentifier);
+}
+
+void WebInspectorUI::showConsole()
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showConsole"));
+}
+
+void WebInspectorUI::showResources()
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showResources"));
+}
+
+void WebInspectorUI::showTimelines()
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showTimelines"));
+}
+
+void WebInspectorUI::showMainResourceForFrame(const String& frameIdentifier)
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("showMainResourceForFrame"), frameIdentifier);
+}
+
+void WebInspectorUI::startPageProfiling()
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setTimelineProfilingEnabled"), true);
+}
+
+void WebInspectorUI::stopPageProfiling()
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setTimelineProfilingEnabled"), false);
+}
+
+void WebInspectorUI::startElementSelection()
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setElementSelectionEnabled"), true);
+}
+
+void WebInspectorUI::stopElementSelection()
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("setElementSelectionEnabled"), false);
+}
+
+void WebInspectorUI::didSave(const String& url)
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("savedURL"), url);
+}
+
+void WebInspectorUI::didAppend(const String& url)
+{
+ m_frontendAPIDispatcher.dispatchCommand(ASCIILiteral("appendedToURL"), url);
+}
+
+void WebInspectorUI::sendMessageToFrontend(const String& message)
+{
+ m_frontendAPIDispatcher.dispatchMessageAsync(message);
+}
+
+void WebInspectorUI::pagePaused()
+{
+ m_frontendAPIDispatcher.suspend();
+}
+
+void WebInspectorUI::pageUnpaused()
+{
+ m_frontendAPIDispatcher.unsuspend();
+}
+
+void WebInspectorUI::sendMessageToBackend(const String& message)
+{
+ if (m_backendConnection)
+ m_backendConnection->send(Messages::WebInspector::SendMessageToBackend(message), 0);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.h b/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.h
new file mode 100644
index 000000000..446185b12
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "Connection.h"
+#include "WebInspectorFrontendAPIDispatcher.h"
+#include <WebCore/InspectorFrontendClient.h>
+#include <WebCore/InspectorFrontendHost.h>
+
+namespace WebCore {
+class InspectorController;
+}
+
+namespace WebKit {
+
+class WebPage;
+
+class WebInspectorUI : public RefCounted<WebInspectorUI>, public IPC::Connection::Client, public WebCore::InspectorFrontendClient {
+public:
+ static Ref<WebInspectorUI> create(WebPage&);
+
+ // Implemented in generated WebInspectorUIMessageReceiver.cpp
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+
+ // IPC::Connection::Client
+ void didClose(IPC::Connection&) override { closeWindow(); }
+ void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) override { closeWindow(); }
+
+ // Called by WebInspectorUI messages
+ void establishConnection(IPC::Attachment connectionIdentifier, uint64_t inspectedPageIdentifier, bool underTest, unsigned inspectionLevel);
+
+ void showConsole();
+ void showResources();
+ void showTimelines();
+
+ void showMainResourceForFrame(const String& frameIdentifier);
+
+ void startPageProfiling();
+ void stopPageProfiling();
+
+ void startElementSelection();
+ void stopElementSelection();
+
+ void attachedBottom() { setDockSide(DockSide::Bottom); }
+ void attachedRight() { setDockSide(DockSide::Right); }
+ void attachedLeft() { setDockSide(DockSide::Left); }
+ void detached() { setDockSide(DockSide::Undocked); }
+
+ void setDockSide(DockSide);
+ void setDockingUnavailable(bool);
+
+ void setIsVisible(bool);
+
+ void didSave(const String& url);
+ void didAppend(const String& url);
+
+ void sendMessageToFrontend(const String&);
+
+ // WebCore::InspectorFrontendClient
+ void windowObjectCleared() override;
+ void frontendLoaded() override;
+
+ void startWindowDrag() override;
+ void moveWindowBy(float x, float y) override;
+
+ String localizedStringsURL() override;
+
+ void bringToFront() override;
+ void closeWindow() override;
+
+ WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() const override;
+
+ void requestSetDockSide(DockSide) override;
+ void changeAttachedWindowHeight(unsigned) override;
+ void changeAttachedWindowWidth(unsigned) override;
+
+ void openInNewTab(const String& url) override;
+
+ bool canSave() override;
+ void save(const WTF::String& url, const WTF::String& content, bool base64Encoded, bool forceSaveAs) override;
+ void append(const WTF::String& url, const WTF::String& content) override;
+
+ void inspectedURLChanged(const String&) override;
+
+ void sendMessageToBackend(const String&) override;
+
+ void pagePaused() override;
+ void pageUnpaused() override;
+
+ bool isUnderTest() override { return m_underTest; }
+ unsigned inspectionLevel() const override { return m_inspectionLevel; }
+
+private:
+ explicit WebInspectorUI(WebPage&);
+
+ WebPage& m_page;
+ WebInspectorFrontendAPIDispatcher m_frontendAPIDispatcher;
+ RefPtr<WebCore::InspectorFrontendHost> m_frontendHost;
+ RefPtr<IPC::Connection> m_backendConnection;
+
+ // Keep a pointer to the frontend's inspector controller rather than going through
+ // corePage(), since we may need it after the frontend's page has started destruction.
+ WebCore::InspectorController* m_frontendController { nullptr };
+
+ uint64_t m_inspectedPageIdentifier { 0 };
+ bool m_underTest { false };
+ bool m_dockingUnavailable { false };
+ bool m_isVisible { false };
+ DockSide m_dockSide { DockSide::Undocked };
+ unsigned m_inspectionLevel { 1 };
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.messages.in b/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.messages.in
new file mode 100644
index 000000000..372ed3cea
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspectorUI.messages.in
@@ -0,0 +1,49 @@
+# Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
+#
+# 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+
+messages -> WebInspectorUI {
+ EstablishConnection(IPC::Attachment connectionIdentifier, uint64_t inspectedPageIdentifier, bool underTest, unsigned inspectionLevel)
+
+ AttachedBottom()
+ AttachedRight()
+ AttachedLeft()
+ Detached()
+ SetDockingUnavailable(bool unavailable)
+ SetIsVisible(bool visible)
+
+ ShowConsole()
+ ShowResources()
+ ShowTimelines()
+
+ ShowMainResourceForFrame(String frameIdentifier)
+
+ StartPageProfiling()
+ StopPageProfiling()
+
+ StartElementSelection()
+ StopElementSelection()
+
+ DidSave(String url)
+ DidAppend(String url)
+
+ SendMessageToFrontend(String message)
+}
diff --git a/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp
index bcf3e8024..6866c7984 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp
@@ -26,11 +26,13 @@
#include "config.h"
#include "WebOpenPanelResultListener.h"
+#include <WebCore/Icon.h>
+
namespace WebKit {
-PassRefPtr<WebOpenPanelResultListener> WebOpenPanelResultListener::create(WebPage* page, PassRefPtr<WebCore::FileChooser> fileChooser)
+Ref<WebOpenPanelResultListener> WebOpenPanelResultListener::create(WebPage* page, PassRefPtr<WebCore::FileChooser> fileChooser)
{
- return adoptRef(new WebOpenPanelResultListener(page, fileChooser));
+ return adoptRef(*new WebOpenPanelResultListener(page, fileChooser));
}
WebOpenPanelResultListener::WebOpenPanelResultListener(WebPage* page, PassRefPtr<WebCore::FileChooser> fileChooser)
@@ -48,4 +50,11 @@ void WebOpenPanelResultListener::didChooseFiles(const Vector<String>& files)
m_fileChooser->chooseFiles(files);
}
+#if PLATFORM(IOS)
+void WebOpenPanelResultListener::didChooseFilesWithDisplayStringAndIcon(const Vector<String>& files, const String& displayString, WebCore::Icon* displayIcon)
+{
+ m_fileChooser->chooseMediaFiles(files, displayString, displayIcon);
+}
+#endif
+
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h
index 073d66adb..69330d237 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h
@@ -29,17 +29,24 @@
#include <wtf/RefCounted.h>
#include <WebCore/FileChooser.h>
+namespace WebCore {
+class Icon;
+}
+
namespace WebKit {
class WebPage;
class WebOpenPanelResultListener : public RefCounted<WebOpenPanelResultListener> {
public:
- static PassRefPtr<WebOpenPanelResultListener> create(WebPage*, PassRefPtr<WebCore::FileChooser>);
+ static Ref<WebOpenPanelResultListener> create(WebPage*, PassRefPtr<WebCore::FileChooser>);
~WebOpenPanelResultListener();
void disconnectFromPage() { m_page = 0; }
void didChooseFiles(const Vector<String>&);
+#if PLATFORM(IOS)
+ void didChooseFilesWithDisplayStringAndIcon(const Vector<String>&, const String& displayString, WebCore::Icon*);
+#endif
private:
WebOpenPanelResultListener(WebPage*, PassRefPtr<WebCore::FileChooser>);
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
index c7da0d9d2..f5024de4b 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
* Copyright (C) 2012 Intel Corporation. All rights reserved.
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
*
@@ -28,9 +28,10 @@
#include "config.h"
#include "WebPage.h"
-#include "Arguments.h"
+#include "APIArray.h"
+#include "APIGeometry.h"
+#include "AssistedNodeInformation.h"
#include "DataReference.h"
-#include "DecoderAdapter.h"
#include "DragControllerAction.h"
#include "DrawingArea.h"
#include "DrawingAreaMessages.h"
@@ -38,19 +39,26 @@
#include "EventDispatcher.h"
#include "InjectedBundle.h"
#include "InjectedBundleBackForwardList.h"
-#include "InjectedBundleUserMessageCoders.h"
-#include "LayerTreeHost.h"
+#include "InjectedBundleScriptWorld.h"
+#include "LibWebRTCProvider.h"
+#include "LoadParameters.h"
#include "Logging.h"
#include "NetscapePlugin.h"
#include "NotificationPermissionRequestManager.h"
#include "PageBanner.h"
-#include "PageOverlay.h"
#include "PluginProcessAttributes.h"
#include "PluginProxy.h"
#include "PluginView.h"
#include "PrintInfo.h"
+#include "RemoteWebInspectorUI.h"
+#include "RemoteWebInspectorUIMessages.h"
#include "SessionState.h"
+#include "SessionStateConversion.h"
+#include "SessionTracker.h"
#include "ShareableBitmap.h"
+#include "VisitedLinkTableController.h"
+#include "WKBundleAPICast.h"
+#include "WKRetainPtr.h"
#include "WKSharedAPICast.h"
#include "WebAlternativeTextClient.h"
#include "WebBackForwardListItem.h"
@@ -59,64 +67,93 @@
#include "WebColorChooser.h"
#include "WebContextMenu.h"
#include "WebContextMenuClient.h"
-#include "WebContextMessages.h"
#include "WebCoreArgumentCoders.h"
+#include "WebDatabaseProvider.h"
+#include "WebDiagnosticLoggingClient.h"
#include "WebDocumentLoader.h"
#include "WebDragClient.h"
#include "WebEditorClient.h"
#include "WebEvent.h"
#include "WebEventConversion.h"
+#include "WebEventFactory.h"
#include "WebFrame.h"
#include "WebFrameLoaderClient.h"
#include "WebFullScreenManager.h"
#include "WebFullScreenManagerMessages.h"
+#include "WebGamepadProvider.h"
#include "WebGeolocationClient.h"
#include "WebImage.h"
#include "WebInspector.h"
#include "WebInspectorClient.h"
#include "WebInspectorMessages.h"
+#include "WebInspectorUI.h"
+#include "WebInspectorUIMessages.h"
+#include "WebMediaKeyStorageManager.h"
#include "WebNotificationClient.h"
#include "WebOpenPanelResultListener.h"
#include "WebPageCreationParameters.h"
#include "WebPageGroupProxy.h"
#include "WebPageMessages.h"
+#include "WebPageOverlay.h"
#include "WebPageProxyMessages.h"
+#include "WebPaymentCoordinator.h"
#include "WebPlugInClient.h"
+#include "WebPluginInfoProvider.h"
#include "WebPopupMenu.h"
+#include "WebPreferencesDefinitions.h"
+#include "WebPreferencesKeys.h"
#include "WebPreferencesStore.h"
#include "WebProcess.h"
+#include "WebProcessPoolMessages.h"
#include "WebProcessProxyMessages.h"
#include "WebProgressTrackerClient.h"
+#include "WebSocketProvider.h"
+#include "WebStorageNamespaceProvider.h"
+#include "WebUndoStep.h"
+#include "WebUserContentController.h"
+#include "WebUserMediaClient.h"
+#include "WebValidationMessageClient.h"
#include <JavaScriptCore/APICast.h>
+#include <WebCore/ApplicationCacheStorage.h>
#include <WebCore/ArchiveResource.h>
+#include <WebCore/BackForwardController.h>
#include <WebCore/Chrome.h>
+#include <WebCore/CommonVM.h>
#include <WebCore/ContextMenuController.h>
+#include <WebCore/DataTransfer.h>
#include <WebCore/DatabaseManager.h>
#include <WebCore/DocumentFragment.h>
#include <WebCore/DocumentLoader.h>
#include <WebCore/DocumentMarkerController.h>
#include <WebCore/DragController.h>
#include <WebCore/DragData.h>
-#include <WebCore/DragSession.h>
+#include <WebCore/ElementIterator.h>
#include <WebCore/EventHandler.h>
+#include <WebCore/EventNames.h>
#include <WebCore/FocusController.h>
#include <WebCore/FormState.h>
#include <WebCore/FrameLoadRequest.h>
#include <WebCore/FrameLoaderTypes.h>
#include <WebCore/FrameView.h>
#include <WebCore/HTMLFormElement.h>
+#include <WebCore/HTMLImageElement.h>
#include <WebCore/HTMLInputElement.h>
+#include <WebCore/HTMLOListElement.h>
#include <WebCore/HTMLPlugInElement.h>
#include <WebCore/HTMLPlugInImageElement.h>
+#include <WebCore/HTMLUListElement.h>
#include <WebCore/HistoryController.h>
#include <WebCore/HistoryItem.h>
#include <WebCore/HitTestResult.h>
+#include <WebCore/InspectorController.h>
+#include <WebCore/JSDOMExceptionHandling.h>
#include <WebCore/JSDOMWindow.h>
#include <WebCore/KeyboardEvent.h>
#include <WebCore/MIMETypeRegistry.h>
#include <WebCore/MainFrame.h>
#include <WebCore/MouseEvent.h>
#include <WebCore/Page.h>
+#include <WebCore/PageConfiguration.h>
#include <WebCore/PlatformKeyboardEvent.h>
#include <WebCore/PluginDocument.h>
#include <WebCore/PrintContext.h>
@@ -124,69 +161,89 @@
#include <WebCore/RenderLayer.h>
#include <WebCore/RenderTreeAsText.h>
#include <WebCore/RenderView.h>
-#include <WebCore/ResourceBuffer.h>
#include <WebCore/ResourceRequest.h>
#include <WebCore/ResourceResponse.h>
#include <WebCore/RuntimeEnabledFeatures.h>
#include <WebCore/SchemeRegistry.h>
#include <WebCore/ScriptController.h>
#include <WebCore/SerializedScriptValue.h>
+#include <WebCore/SessionID.h>
#include <WebCore/Settings.h>
#include <WebCore/ShadowRoot.h>
#include <WebCore/SharedBuffer.h>
+#include <WebCore/StyleProperties.h>
#include <WebCore/SubframeLoader.h>
#include <WebCore/SubstituteData.h>
#include <WebCore/TextIterator.h>
+#include <WebCore/UserInputBridge.h>
+#include <WebCore/UserScript.h>
+#include <WebCore/UserStyleSheet.h>
#include <WebCore/VisiblePosition.h>
#include <WebCore/VisibleUnits.h>
+#include <WebCore/WebGLStateTracker.h>
+#include <WebCore/htmlediting.h>
#include <WebCore/markup.h>
#include <bindings/ScriptValue.h>
+#include <profiler/ProfilerDatabase.h>
+#include <runtime/JSCInlines.h>
#include <runtime/JSCJSValue.h>
#include <runtime/JSLock.h>
-#include <runtime/Operations.h>
+#include <runtime/SamplingProfiler.h>
#include <wtf/RunLoop.h>
+#include <wtf/SetForScope.h>
-#if ENABLE(MHTML)
-#include <WebCore/MHTMLArchive.h>
-#endif
-
-#if PLATFORM(MAC)
-#include "MachPort.h"
+#if ENABLE(DATA_DETECTION)
+#include "DataDetectionResult.h"
#endif
-#if ENABLE(BATTERY_STATUS)
-#include "WebBatteryClient.h"
-#endif
-
-#if ENABLE(NETWORK_INFO)
-#include "WebNetworkInfoClient.h"
+#if ENABLE(MHTML)
+#include <WebCore/MHTMLArchive.h>
#endif
#if ENABLE(VIBRATION)
#include "WebVibrationClient.h"
#endif
+#if ENABLE(POINTER_LOCK)
+#include <WebCore/PointerLockController.h>
+#endif
+
#if ENABLE(PROXIMITY_EVENTS)
#include "WebDeviceProximityClient.h"
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
#include "PDFPlugin.h"
+#include "RemoteLayerTreeTransaction.h"
+#include "WKStringCF.h"
+#include "WebPlaybackSessionManager.h"
+#include "WebVideoFullscreenManager.h"
#include <WebCore/LegacyWebArchive.h>
#endif
#if PLATFORM(GTK)
-#include <gtk/gtk.h>
-#include "DataObjectGtk.h"
#include "WebPrintOperationGtk.h"
+#include "WebSelectionData.h"
+#include <gtk/gtk.h>
+#endif
+
+#if PLATFORM(IOS)
+#include "RemoteLayerTreeDrawingArea.h"
+#include <CoreGraphics/CoreGraphics.h>
+#include <WebCore/CoreTextSPI.h>
+#include <WebCore/Icon.h>
#endif
#ifndef NDEBUG
#include <wtf/RefCountedLeakCounter.h>
#endif
-#if USE(COORDINATED_GRAPHICS)
-#include "CoordinatedLayerTreeHostMessages.h"
+#if ENABLE(DATA_DETECTION)
+#include <WebCore/DataDetection.h>
+#endif
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+#include <WebCore/MediaPlayerRequestInstallMissingPluginsCallback.h>
#endif
using namespace JSC;
@@ -194,6 +251,13 @@ using namespace WebCore;
namespace WebKit {
+static const double pageScrollHysteresisSeconds = 0.3;
+static const std::chrono::milliseconds initialLayerVolatilityTimerInterval { 20 };
+static const std::chrono::seconds maximumLayerVolatilityTimerInterval { 2 };
+
+#define RELEASE_LOG_IF_ALLOWED(...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), Layers, __VA_ARGS__)
+#define RELEASE_LOG_ERROR_IF_ALLOWED(...) RELEASE_LOG_ERROR_IF(isAlwaysOnLoggingAllowed(), Layers, __VA_ARGS__)
+
class SendStopResponsivenessTimer {
public:
SendStopResponsivenessTimer(WebPage* page)
@@ -210,115 +274,147 @@ private:
WebPage* m_page;
};
+class DeferredPageDestructor {
+public:
+ static void createDeferredPageDestructor(std::unique_ptr<Page> page, WebPage* webPage)
+ {
+ new DeferredPageDestructor(WTFMove(page), webPage);
+ }
+
+private:
+ DeferredPageDestructor(std::unique_ptr<Page> page, WebPage* webPage)
+ : m_page(WTFMove(page))
+ , m_webPage(webPage)
+ {
+ tryDestruction();
+ }
+
+ void tryDestruction()
+ {
+ if (m_page->insideNestedRunLoop()) {
+ m_page->whenUnnested([this] { tryDestruction(); });
+ return;
+ }
+
+ m_page = nullptr;
+ m_webPage = nullptr;
+ delete this;
+ }
+
+ std::unique_ptr<Page> m_page;
+ RefPtr<WebPage> m_webPage;
+};
+
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage"));
-PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters)
+Ref<WebPage> WebPage::create(uint64_t pageID, WebPageCreationParameters&& parameters)
{
- RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters));
+ Ref<WebPage> page = adoptRef(*new WebPage(pageID, WTFMove(parameters)));
- if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
- WebProcess::shared().injectedBundle()->didCreatePage(page.get());
+ if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::singleton().injectedBundle())
+ WebProcess::singleton().injectedBundle()->didCreatePage(page.ptr());
- return page.release();
+ return page;
}
-WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
+WebPage::WebPage(uint64_t pageID, WebPageCreationParameters&& parameters)
: m_pageID(pageID)
- , m_sessionID(0)
, m_viewSize(parameters.viewSize)
- , m_hasSeenPlugin(false)
- , m_useFixedLayout(false)
- , m_drawsBackground(true)
- , m_drawsTransparentBackground(false)
- , m_isInRedo(false)
- , m_isClosed(false)
- , m_tabToLinks(false)
- , m_asynchronousPluginInitializationEnabled(false)
- , m_asynchronousPluginInitializationEnabledForAllPlugins(false)
- , m_artificialPluginInitializationDelayEnabled(false)
- , m_scrollingPerformanceLoggingEnabled(false)
- , m_mainFrameIsScrollable(true)
#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
- , m_readyToFindPrimarySnapshottedPlugin(false)
- , m_didFindPrimarySnapshottedPlugin(false)
- , m_numberOfPrimarySnapshotDetectionAttempts(0)
, m_determinePrimarySnapshottedPlugInTimer(RunLoop::main(), this, &WebPage::determinePrimarySnapshottedPlugInTimerFired)
#endif
, m_layerHostingMode(parameters.layerHostingMode)
-#if PLATFORM(MAC)
- , m_pdfPluginEnabled(false)
- , m_hasCachedWindowFrame(false)
- , m_keyboardEventBeingInterpreted(0)
-#if !PLATFORM(IOS)
+#if PLATFORM(COCOA)
, m_viewGestureGeometryCollector(*this)
-#endif
-#elif PLATFORM(GTK) && HAVE(ACCESSIBILITY)
- , m_accessibilityObject(0)
+#elif HAVE(ACCESSIBILITY) && PLATFORM(GTK)
+ , m_accessibilityObject(nullptr)
#endif
, m_setCanStartMediaTimer(RunLoop::main(), this, &WebPage::setCanStartMediaTimerFired)
- , m_sendDidUpdateViewStateTimer(RunLoop::main(), this, &WebPage::didUpdateViewStateTimerFired)
- , m_findController(this)
-#if ENABLE(INPUT_TYPE_COLOR)
- , m_activeColorChooser(0)
+#if ENABLE(CONTEXT_MENUS)
+ , m_contextMenuClient(std::make_unique<API::InjectedBundle::PageContextMenuClient>())
#endif
+ , m_editorClient { std::make_unique<API::InjectedBundle::EditorClient>() }
+ , m_formClient(std::make_unique<API::InjectedBundle::FormClient>())
+ , m_uiClient(std::make_unique<API::InjectedBundle::PageUIClient>())
+ , m_findController(this)
+ , m_userContentController(WebUserContentController::getOrCreate(parameters.userContentControllerID))
#if ENABLE(GEOLOCATION)
, m_geolocationPermissionRequestManager(this)
#endif
+#if ENABLE(MEDIA_STREAM)
+ , m_userMediaPermissionRequestManager(*this)
+#endif
+ , m_pageScrolledHysteresis([this](HysteresisState state) { if (state == HysteresisState::Stopped) pageStoppedScrolling(); }, pageScrollHysteresisSeconds)
, m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
, m_canRunModal(parameters.canRunModal)
- , m_isRunningModal(false)
- , m_cachedMainFrameIsPinnedToLeftSide(false)
- , m_cachedMainFrameIsPinnedToRightSide(false)
- , m_cachedMainFrameIsPinnedToTopSide(false)
- , m_cachedMainFrameIsPinnedToBottomSide(false)
- , m_canShortCircuitHorizontalWheelEvents(false)
- , m_numWheelEventHandlers(0)
- , m_cachedPageCount(0)
- , m_autoSizingShouldExpandToViewHeight(false)
-#if ENABLE(CONTEXT_MENUS)
- , m_isShowingContextMenu(false)
-#endif
#if PLATFORM(IOS)
- , m_shouldReturnWordAtSelection(false)
-#endif
- , m_inspectorClient(0)
- , m_backgroundColor(Color::white)
- , m_maximumRenderingSuppressionToken(0)
- , m_scrollPinningBehavior(DoNotPin)
- , m_useAsyncScrolling(false)
- , m_viewState(parameters.viewState)
- , m_processSuppressionDisabledByWebPreference("Process suppression is disabled.")
+ , m_forceAlwaysUserScalable(parameters.ignoresViewportScaleLimits)
+ , m_screenSize(parameters.screenSize)
+ , m_availableScreenSize(parameters.availableScreenSize)
+#endif
+ , m_layerVolatilityTimer(*this, &WebPage::layerVolatilityTimerFired)
+ , m_activityState(parameters.activityState)
+ , m_processSuppressionEnabled(true)
+ , m_userActivity("Process suppression disabled for page.")
+ , m_userActivityHysteresis([this](HysteresisState) { updateUserActivity(); })
+ , m_userInterfaceLayoutDirection(parameters.userInterfaceLayoutDirection)
+ , m_overrideContentSecurityPolicy { parameters.overrideContentSecurityPolicy }
{
ASSERT(m_pageID);
- // FIXME: This is a non-ideal location for this Setting and
- // 4ms should be adopted project-wide now, https://bugs.webkit.org/show_bug.cgi?id=61214
- Settings::setDefaultMinDOMTimerInterval(0.004);
- Page::PageClients pageClients;
- pageClients.chromeClient = new WebChromeClient(this);
+ m_pageGroup = WebProcess::singleton().webPageGroup(parameters.pageGroupData);
+
+#if PLATFORM(IOS)
+ Settings::setShouldManageAudioSessionCategory(true);
+#endif
+
+ PageConfiguration pageConfiguration(
+ makeUniqueRef<WebEditorClient>(this),
+ WebSocketProvider::create(),
+ makeUniqueRef<WebKit::LibWebRTCProvider>()
+ );
+ pageConfiguration.chromeClient = new WebChromeClient(*this);
#if ENABLE(CONTEXT_MENUS)
- pageClients.contextMenuClient = new WebContextMenuClient(this);
+ pageConfiguration.contextMenuClient = new WebContextMenuClient(this);
#endif
- pageClients.editorClient = new WebEditorClient(this);
#if ENABLE(DRAG_SUPPORT)
- pageClients.dragClient = new WebDragClient(this);
-#endif
- pageClients.backForwardClient = WebBackForwardListProxy::create(this);
-#if ENABLE(INSPECTOR)
- m_inspectorClient = new WebInspectorClient(this);
- pageClients.inspectorClient = m_inspectorClient;
+ pageConfiguration.dragClient = new WebDragClient(this);
#endif
+ pageConfiguration.backForwardClient = WebBackForwardListProxy::create(this);
+ pageConfiguration.inspectorClient = new WebInspectorClient(this);
#if USE(AUTOCORRECTION_PANEL)
- pageClients.alternativeTextClient = new WebAlternativeTextClient(this);
+ pageConfiguration.alternativeTextClient = new WebAlternativeTextClient(this);
#endif
- pageClients.plugInClient = new WebPlugInClient(this);
- pageClients.loaderClientForMainFrame = new WebFrameLoaderClient;
- pageClients.progressTrackerClient = new WebProgressTrackerClient(*this);
- m_page = adoptPtr(new Page(pageClients));
+ pageConfiguration.plugInClient = new WebPlugInClient(*this);
+ pageConfiguration.loaderClientForMainFrame = new WebFrameLoaderClient;
+ pageConfiguration.progressTrackerClient = new WebProgressTrackerClient(*this);
+ pageConfiguration.diagnosticLoggingClient = std::make_unique<WebDiagnosticLoggingClient>(*this);
+ pageConfiguration.webGLStateTracker = std::make_unique<WebGLStateTracker>([this](bool isUsingHighPerformanceWebGL) {
+ send(Messages::WebPageProxy::SetIsUsingHighPerformanceWebGL(isUsingHighPerformanceWebGL));
+ });
+
+#if PLATFORM(COCOA)
+ pageConfiguration.validationMessageClient = std::make_unique<WebValidationMessageClient>(*this);
+#endif
+
+ pageConfiguration.applicationCacheStorage = &WebProcess::singleton().applicationCacheStorage();
+ pageConfiguration.databaseProvider = WebDatabaseProvider::getOrCreate(m_pageGroup->pageGroupID());
+ pageConfiguration.pluginInfoProvider = &WebPluginInfoProvider::singleton();
+ pageConfiguration.storageNamespaceProvider = WebStorageNamespaceProvider::getOrCreate(m_pageGroup->pageGroupID());
+ pageConfiguration.userContentProvider = m_userContentController.ptr();
+ pageConfiguration.visitedLinkStore = VisitedLinkTableController::getOrCreate(parameters.visitedLinkTableID);
+
+#if ENABLE(APPLE_PAY)
+ pageConfiguration.paymentCoordinatorClient = new WebPaymentCoordinator(*this);
+#endif
- m_drawingArea = DrawingArea::create(this, parameters);
+ m_page = std::make_unique<Page>(WTFMove(pageConfiguration));
+ updatePreferences(parameters.store);
+
+ m_drawingArea = DrawingArea::create(*this, parameters);
m_drawingArea->setPaintingEnabled(false);
+ m_drawingArea->setShouldScaleViewToFitDocument(parameters.shouldScaleViewToFitDocument);
#if ENABLE(ASYNC_SCROLLING)
m_useAsyncScrolling = parameters.store.getBoolValueForKey(WebPreferencesKey::threadedScrollingEnabledKey());
@@ -328,16 +424,11 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
#endif
m_mainFrame = WebFrame::createWithCoreMainFrame(this, &m_page->mainFrame());
+ m_drawingArea->updatePreferences(parameters.store);
-#if ENABLE(BATTERY_STATUS)
- WebCore::provideBatteryTo(m_page.get(), new WebBatteryClient(this));
-#endif
#if ENABLE(GEOLOCATION)
WebCore::provideGeolocationTo(m_page.get(), new WebGeolocationClient(this));
#endif
-#if ENABLE(NETWORK_INFO)
- WebCore::provideNetworkInfoTo(m_page.get(), new WebNetworkInfoClient(this));
-#endif
#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
WebCore::provideNotification(m_page.get(), new WebNotificationClient(this));
#endif
@@ -347,25 +438,32 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
#if ENABLE(PROXIMITY_EVENTS)
WebCore::provideDeviceProximityTo(m_page.get(), new WebDeviceProximityClient(this));
#endif
+#if ENABLE(MEDIA_STREAM)
+ WebCore::provideUserMediaTo(m_page.get(), new WebUserMediaClient(*this));
+#endif
+
+ m_page->setControlledByAutomation(parameters.controlledByAutomation);
#if ENABLE(REMOTE_INSPECTOR)
- m_page->setRemoteInspectionAllowed(true);
+ m_page->setRemoteInspectionAllowed(parameters.allowsRemoteInspection);
+ m_page->setRemoteInspectionNameOverride(parameters.remoteInspectionNameOverride);
#endif
m_page->setCanStartMedia(false);
m_mayStartMediaWhenInWindow = parameters.mayStartMediaWhenInWindow;
- m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);
m_page->setGroupName(m_pageGroup->identifier());
m_page->setDeviceScaleFactor(parameters.deviceScaleFactor);
+ m_page->setUserInterfaceLayoutDirection(m_userInterfaceLayoutDirection);
+#if PLATFORM(IOS)
+ m_page->setTextAutosizingWidth(parameters.textAutosizingWidth);
+#endif
- updatePreferences(parameters.store);
platformInitialize();
setUseFixedLayout(parameters.useFixedLayout);
setDrawsBackground(parameters.drawsBackground);
- setDrawsTransparentBackground(parameters.drawsTransparentBackground);
setUnderlayColor(parameters.underlayColor);
@@ -373,53 +471,56 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
setPaginationBehavesLikeColumns(parameters.paginationBehavesLikeColumns);
setPageLength(parameters.pageLength);
setGapBetweenPages(parameters.gapBetweenPages);
+ setPaginationLineGridEnabled(parameters.paginationLineGridEnabled);
+
+ // If the page is created off-screen, its visibilityState should be prerender.
+ m_page->setActivityState(m_activityState);
+ if (!isVisible())
+ m_page->setIsPrerender();
- setMemoryCacheMessagesEnabled(parameters.areMemoryCacheClientCallsEnabled);
-
- setActive(parameters.viewState & ViewState::WindowIsActive);
- setFocused(parameters.viewState & ViewState::IsFocused);
-
- // Page defaults to in-window, but setIsInWindow depends on it being a valid indicator of actually having been put into a window.
- bool isInWindow = parameters.viewState & ViewState::IsInWindow;
- if (!isInWindow)
- m_page->setIsInWindow(false);
- else
- WebProcess::shared().pageDidEnterWindow(m_pageID);
-
- setIsInWindow(isInWindow);
+ updateIsInWindow(true);
setMinimumLayoutSize(parameters.minimumLayoutSize);
setAutoSizingShouldExpandToViewHeight(parameters.autoSizingShouldExpandToViewHeight);
setScrollPinningBehavior(parameters.scrollPinningBehavior);
+ if (parameters.scrollbarOverlayStyle)
+ m_scrollbarOverlayStyle = static_cast<ScrollbarOverlayStyle>(parameters.scrollbarOverlayStyle.value());
+ else
+ m_scrollbarOverlayStyle = std::optional<ScrollbarOverlayStyle>();
+
setBackgroundExtendsBeyondPage(parameters.backgroundExtendsBeyondPage);
+ setTopContentInset(parameters.topContentInset);
+
m_userAgent = parameters.userAgent;
WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID);
- if (!parameters.sessionState.isEmpty())
- restoreSession(parameters.sessionState);
+ if (!parameters.itemStates.isEmpty())
+ restoreSessionInternal(parameters.itemStates, WasRestoredByAPIRequest::No);
+
+ if (parameters.sessionID.isValid())
+ setSessionID(parameters.sessionID);
m_drawingArea->setPaintingEnabled(true);
setMediaVolume(parameters.mediaVolume);
- // We use the DidFirstLayout milestone to determine when to unfreeze the layer tree.
- m_page->addLayoutMilestones(DidFirstLayout);
+ setMuted(parameters.muted);
+
+ // We use the DidFirstVisuallyNonEmptyLayout milestone to determine when to unfreeze the layer tree.
+ m_page->addLayoutMilestones(DidFirstLayout | DidFirstVisuallyNonEmptyLayout);
- WebProcess::shared().addMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID, *this);
+ auto& webProcess = WebProcess::singleton();
+ webProcess.addMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID, *this);
// FIXME: This should be done in the object constructors, and the objects themselves should be message receivers.
- WebProcess::shared().addMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID, *this);
-#if USE(COORDINATED_GRAPHICS)
- WebProcess::shared().addMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID, *this);
-#endif
-#if ENABLE(INSPECTOR)
- WebProcess::shared().addMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID, *this);
-#endif
+ webProcess.addMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID, *this);
+ webProcess.addMessageReceiver(Messages::WebInspectorUI::messageReceiverName(), m_pageID, *this);
+ webProcess.addMessageReceiver(Messages::RemoteWebInspectorUI::messageReceiverName(), m_pageID, *this);
#if ENABLE(FULLSCREEN_API)
- WebProcess::shared().addMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID, *this);
+ webProcess.addMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID, *this);
#endif
#ifndef NDEBUG
@@ -428,21 +529,61 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
#if ENABLE(ASYNC_SCROLLING)
if (m_useAsyncScrolling)
- WebProcess::shared().eventDispatcher().addScrollingTreeForPage(this);
+ webProcess.eventDispatcher().addScrollingTreeForPage(this);
+#endif
+
+ for (auto& mimeType : parameters.mimeTypesWithCustomContentProviders)
+ m_mimeTypesWithCustomContentProviders.add(mimeType);
+
+
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+ if (WebMediaKeyStorageManager* manager = webProcess.supplement<WebMediaKeyStorageManager>())
+ m_page->settings().setMediaKeysStorageDirectory(manager->mediaKeyStorageDirectory());
#endif
+ m_page->settings().setAppleMailPaginationQuirkEnabled(parameters.appleMailPaginationQuirkEnabled);
- m_page->setIsVisible(m_viewState & ViewState::IsVisible, true);
- setIsVisuallyIdle(m_viewState & ViewState::IsVisuallyIdle);
+ if (parameters.viewScaleFactor != 1)
+ scaleView(parameters.viewScaleFactor);
+
+ m_page->addLayoutMilestones(parameters.observedLayoutMilestones);
+
+#if PLATFORM(COCOA)
+ m_page->settings().setContentDispositionAttachmentSandboxEnabled(true);
+ setSmartInsertDeleteEnabled(parameters.smartInsertDeleteEnabled);
+#endif
}
-void WebPage::reinitializeWebPage(const WebPageCreationParameters& parameters)
+void WebPage::reinitializeWebPage(WebPageCreationParameters&& parameters)
{
- if (m_viewState != parameters.viewState)
- setViewStateInternal(parameters.viewState, true);
+ if (m_activityState != parameters.activityState)
+ setActivityState(parameters.activityState, false, Vector<uint64_t>());
if (m_layerHostingMode != parameters.layerHostingMode)
setLayerHostingMode(parameters.layerHostingMode);
}
+void WebPage::updateThrottleState()
+{
+ // We should suppress if the page is not active, is visually idle, and supression is enabled.
+ bool isLoading = m_activityState & ActivityState::IsLoading;
+ bool isPlayingAudio = m_activityState & ActivityState::IsAudible;
+ bool pageSuppressed = !isLoading && !isPlayingAudio && m_processSuppressionEnabled && (m_activityState & ActivityState::IsVisuallyIdle);
+
+ // The UserActivity keeps the processes runnable. So if the page should be suppressed, stop the activity.
+ // If the page should not be supressed, start it.
+ if (pageSuppressed)
+ m_userActivityHysteresis.stop();
+ else
+ m_userActivityHysteresis.start();
+}
+
+void WebPage::updateUserActivity()
+{
+ if (m_userActivityHysteresis.state() == HysteresisState::Started)
+ m_userActivity.start();
+ else
+ m_userActivity.stop();
+}
+
WebPage::~WebPage()
{
if (m_backForwardList)
@@ -450,11 +591,14 @@ WebPage::~WebPage()
ASSERT(!m_page);
+ auto& webProcess = WebProcess::singleton();
#if ENABLE(ASYNC_SCROLLING)
if (m_useAsyncScrolling)
- WebProcess::shared().eventDispatcher().removeScrollingTreeForPage(this);
+ webProcess.eventDispatcher().removeScrollingTreeForPage(this);
#endif
+ platformDetach();
+
m_sandboxExtensionTracker.invalidate();
for (auto* pluginView : m_pluginViews)
@@ -467,18 +611,14 @@ WebPage::~WebPage()
m_footerBanner->detachFromPage();
#endif // !PLATFORM(IOS)
- WebProcess::shared().removeMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID);
+ webProcess.removeMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID);
// FIXME: This should be done in the object destructors, and the objects themselves should be message receivers.
- WebProcess::shared().removeMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID);
-#if USE(COORDINATED_GRAPHICS)
- WebProcess::shared().removeMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID);
-#endif
-#if ENABLE(INSPECTOR)
- WebProcess::shared().removeMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID);
-#endif
+ webProcess.removeMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID);
+ webProcess.removeMessageReceiver(Messages::WebInspectorUI::messageReceiverName(), m_pageID);
+ webProcess.removeMessageReceiver(Messages::RemoteWebInspectorUI::messageReceiverName(), m_pageID);
#if ENABLE(FULLSCREEN_API)
- WebProcess::shared().removeMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID);
+ webProcess.removeMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID);
#endif
#ifndef NDEBUG
@@ -492,7 +632,7 @@ void WebPage::dummy(bool&)
IPC::Connection* WebPage::messageSenderConnection()
{
- return WebProcess::shared().parentProcessConnection();
+ return WebProcess::singleton().parentProcessConnection();
}
uint64_t WebPage::messageSenderDestinationID()
@@ -501,20 +641,35 @@ uint64_t WebPage::messageSenderDestinationID()
}
#if ENABLE(CONTEXT_MENUS)
-void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClientBase* client)
+void WebPage::setInjectedBundleContextMenuClient(std::unique_ptr<API::InjectedBundle::PageContextMenuClient> contextMenuClient)
{
- m_contextMenuClient.initialize(client);
+ if (!contextMenuClient) {
+ m_contextMenuClient = std::make_unique<API::InjectedBundle::PageContextMenuClient>();
+ return;
+ }
+
+ m_contextMenuClient = WTFMove(contextMenuClient);
}
#endif
-void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClientBase* client)
+void WebPage::setInjectedBundleEditorClient(std::unique_ptr<API::InjectedBundle::EditorClient> editorClient)
{
- m_editorClient.initialize(client);
+ if (!editorClient) {
+ m_editorClient = std::make_unique<API::InjectedBundle::EditorClient>();
+ return;
+ }
+
+ m_editorClient = WTFMove(editorClient);
}
-void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClientBase* client)
+void WebPage::setInjectedBundleFormClient(std::unique_ptr<API::InjectedBundle::FormClient> formClient)
{
- m_formClient.initialize(client);
+ if (!formClient) {
+ m_formClient = std::make_unique<API::InjectedBundle::FormClient>();
+ return;
+ }
+
+ m_formClient = WTFMove(formClient);
}
void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClientBase* client)
@@ -546,9 +701,14 @@ void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoa
m_resourceLoadClient.initialize(client);
}
-void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClientBase* client)
+void WebPage::setInjectedBundleUIClient(std::unique_ptr<API::InjectedBundle::PageUIClient> uiClient)
{
- m_uiClient.initialize(client);
+ if (!uiClient) {
+ m_uiClient = std::make_unique<API::InjectedBundle::PageUIClient>();
+ return;
+ }
+
+ m_uiClient = WTFMove(uiClient);
}
#if ENABLE(FULLSCREEN_API)
@@ -558,19 +718,22 @@ void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenCli
}
#endif
-void WebPage::initializeInjectedBundleDiagnosticLoggingClient(WKBundlePageDiagnosticLoggingClientBase* client)
-{
- m_logDiagnosticMessageClient.initialize(client);
-}
-
#if ENABLE(NETSCAPE_PLUGIN_API)
-PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* pluginElement, const Plugin::Parameters& parameters, String& newMIMEType)
+
+RefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* pluginElement, const Plugin::Parameters& parameters, String& newMIMEType)
{
String frameURLString = frame->coreFrame()->loader().documentLoader()->responseURL().string();
String pageURLString = m_page->mainFrame().loader().documentLoader()->responseURL().string();
+
+#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
+ HTMLPlugInImageElement& pluginImageElement = downcast<HTMLPlugInImageElement>(*pluginElement);
+ unsigned pluginArea = 0;
+ PluginProcessType processType = pluginElement->displayState() == HTMLPlugInElement::WaitingForSnapshot && !(plugInIsPrimarySize(pluginImageElement, pluginArea) && !plugInIntersectsSearchRect(pluginImageElement)) ? PluginProcessTypeSnapshot : PluginProcessTypeNormal;
+#else
PluginProcessType processType = pluginElement->displayState() == HTMLPlugInElement::WaitingForSnapshot ? PluginProcessTypeSnapshot : PluginProcessTypeNormal;
+#endif
- bool allowOnlyApplicationPlugins = !frame->coreFrame()->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin);
+ bool allowOnlyApplicationPlugins = !frame->coreFrame()->loader().subframeLoader().allowPlugins();
uint64_t pluginProcessToken;
uint32_t pluginLoadPolicy;
@@ -578,14 +741,15 @@ PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* plu
if (!sendSync(Messages::WebPageProxy::FindPlugin(parameters.mimeType, static_cast<uint32_t>(processType), parameters.url.string(), frameURLString, pageURLString, allowOnlyApplicationPlugins), Messages::WebPageProxy::FindPlugin::Reply(pluginProcessToken, newMIMEType, pluginLoadPolicy, unavailabilityDescription)))
return nullptr;
- bool isBlockedPlugin = static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy) == PluginModuleBlocked;
+ PluginModuleLoadPolicy loadPolicy = static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy);
+ bool isBlockedPlugin = (loadPolicy == PluginModuleBlockedForSecurity) || (loadPolicy == PluginModuleBlockedForCompatibility);
if (isBlockedPlugin || !pluginProcessToken) {
#if ENABLE(PDFKIT_PLUGIN)
String path = parameters.url.path();
if (shouldUsePDFPlugin() && (MIMETypeRegistry::isPDFOrPostScriptMIMEType(parameters.mimeType) || (parameters.mimeType.isEmpty() && (path.endsWith(".pdf", false) || path.endsWith(".ps", false))))) {
- RefPtr<PDFPlugin> pdfPlugin = PDFPlugin::create(frame);
- return pdfPlugin.release();
+ auto pdfPlugin = PDFPlugin::create(frame);
+ return WTFMove(pdfPlugin);
}
#else
UNUSED_PARAM(frame);
@@ -594,11 +758,12 @@ PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* plu
if (isBlockedPlugin) {
bool replacementObscured = false;
- if (pluginElement->renderer()->isEmbeddedObject()) {
- RenderEmbeddedObject* renderObject = toRenderEmbeddedObject(pluginElement->renderer());
- renderObject->setPluginUnavailabilityReasonWithDescription(RenderEmbeddedObject::InsecurePluginVersion, unavailabilityDescription);
- replacementObscured = renderObject->isReplacementObscured();
- renderObject->setUnavailablePluginIndicatorIsHidden(replacementObscured);
+ auto* renderer = pluginElement->renderer();
+ if (is<RenderEmbeddedObject>(renderer)) {
+ auto& renderObject = downcast<RenderEmbeddedObject>(*renderer);
+ renderObject.setPluginUnavailabilityReasonWithDescription(RenderEmbeddedObject::InsecurePluginVersion, unavailabilityDescription);
+ replacementObscured = renderObject.isReplacementObscured();
+ renderObject.setUnavailablePluginIndicatorIsHidden(replacementObscured);
}
send(Messages::WebPageProxy::DidBlockInsecurePluginVersion(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString, replacementObscured));
@@ -614,19 +779,19 @@ PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* plu
#endif // ENABLE(NETSCAPE_PLUGIN_API)
-#if ENABLE(WEBGL)
-WebCore::WebGLLoadPolicy WebPage::webGLPolicyForURL(WebFrame* frame, const String& url)
+#if ENABLE(WEBGL) && !PLATFORM(COCOA)
+WebCore::WebGLLoadPolicy WebPage::webGLPolicyForURL(WebFrame*, const String& /* url */)
{
- uint32_t policyResult = 0;
-
- if (sendSync(Messages::WebPageProxy::WebGLPolicyForURL(url), Messages::WebPageProxy::WebGLPolicyForURL::Reply(policyResult)))
- return static_cast<WebGLLoadPolicy>(policyResult);
+ return WebGLAllowCreation;
+}
- return WebGLAllow;
+WebCore::WebGLLoadPolicy WebPage::resolveWebGLPolicyForURL(WebFrame*, const String& /* url */)
+{
+ return WebGLAllowCreation;
}
-#endif // ENABLE(WEBGL)
+#endif
-EditorState WebPage::editorState() const
+EditorState WebPage::editorState(IncludePostLayoutDataHint shouldIncludePostLayoutData) const
{
Frame& frame = m_page->focusController().focusedOrMainFrame();
@@ -641,49 +806,102 @@ EditorState WebPage::editorState() const
}
}
- result.selectionIsNone = frame.selection().isNone();
- result.selectionIsRange = frame.selection().isRange();
- result.isContentEditable = frame.selection().isContentEditable();
- result.isContentRichlyEditable = frame.selection().isContentRichlyEditable();
- result.isInPasswordField = frame.selection().isInPasswordField();
+ const VisibleSelection& selection = frame.selection().selection();
+
+ result.selectionIsNone = selection.isNone();
+ result.selectionIsRange = selection.isRange();
+ result.isContentEditable = selection.isContentEditable();
+ result.isContentRichlyEditable = selection.isContentRichlyEditable();
+ result.isInPasswordField = selection.isInPasswordField();
result.hasComposition = frame.editor().hasComposition();
result.shouldIgnoreCompositionSelectionChange = frame.editor().ignoreCompositionSelectionChange();
-#if PLATFORM(IOS)
- FrameSelection& selection = frame.selection();
- if (frame.editor().hasComposition()) {
- RefPtr<Range> compositionRange = frame.editor().compositionRange();
- Vector<WebCore::SelectionRect> compositionRects;
- compositionRange->collectSelectionRects(compositionRects);
- if (compositionRects.size())
- result.firstMarkedRect = compositionRects[0].rect();
- if (compositionRects.size() > 1)
- result.lastMarkedRect = compositionRects.last().rect();
- else
- result.lastMarkedRect = result.firstMarkedRect;
- result.markedText = plainText(compositionRange.get());
- }
- if (selection.isCaret()) {
- result.caretRectAtStart = selection.absoluteCaretBounds();
- result.caretRectAtEnd = result.caretRectAtStart;
- if (m_shouldReturnWordAtSelection)
- result.wordAtSelection = plainText(wordRangeFromPosition(selection.start()).get());
- } else if (selection.isRange()) {
- result.caretRectAtStart = VisiblePosition(selection.start()).absoluteCaretBounds();
- result.caretRectAtEnd = VisiblePosition(selection.end()).absoluteCaretBounds();
- RefPtr<Range> selectedRange = selection.toNormalizedRange();
- selectedRange->collectSelectionRects(result.selectionRects);
- result.selectedTextLength = plainText(selectedRange.get(), TextIteratorDefaultBehavior, true).length();
+#if PLATFORM(COCOA)
+ if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::Yes && result.isContentEditable) {
+ auto& postLayoutData = result.postLayoutData();
+ if (!selection.isNone()) {
+ Node* nodeToRemove;
+ if (auto* style = Editor::styleForSelectionStart(&frame, nodeToRemove)) {
+ if (style->fontCascade().weight() >= FontWeightBold)
+ postLayoutData.typingAttributes |= AttributeBold;
+ if (style->fontCascade().italic() == FontItalicOn)
+ postLayoutData.typingAttributes |= AttributeItalics;
+
+ RefPtr<EditingStyle> typingStyle = frame.selection().typingStyle();
+ if (typingStyle && typingStyle->style()) {
+ String value = typingStyle->style()->getPropertyValue(CSSPropertyWebkitTextDecorationsInEffect);
+ if (value.contains("underline"))
+ postLayoutData.typingAttributes |= AttributeUnderline;
+ } else {
+ if (style->textDecorationsInEffect() & TextDecorationUnderline)
+ postLayoutData.typingAttributes |= AttributeUnderline;
+ }
+
+ if (style->visitedDependentColor(CSSPropertyColor).isValid())
+ postLayoutData.textColor = style->visitedDependentColor(CSSPropertyColor);
+
+ switch (style->textAlign()) {
+ case RIGHT:
+ case WEBKIT_RIGHT:
+ postLayoutData.textAlignment = RightAlignment;
+ break;
+ case LEFT:
+ case WEBKIT_LEFT:
+ postLayoutData.textAlignment = LeftAlignment;
+ break;
+ case CENTER:
+ case WEBKIT_CENTER:
+ postLayoutData.textAlignment = CenterAlignment;
+ break;
+ case JUSTIFY:
+ postLayoutData.textAlignment = JustifiedAlignment;
+ break;
+ case TASTART:
+ postLayoutData.textAlignment = style->isLeftToRightDirection() ? LeftAlignment : RightAlignment;
+ break;
+ case TAEND:
+ postLayoutData.textAlignment = style->isLeftToRightDirection() ? RightAlignment : LeftAlignment;
+ break;
+ }
+
+ HTMLElement* enclosingListElement = enclosingList(selection.start().deprecatedNode());
+ if (enclosingListElement) {
+ if (is<HTMLUListElement>(*enclosingListElement))
+ postLayoutData.enclosingListType = UnorderedList;
+ else if (is<HTMLOListElement>(*enclosingListElement))
+ postLayoutData.enclosingListType = OrderedList;
+ else
+ ASSERT_NOT_REACHED();
+ } else
+ postLayoutData.enclosingListType = NoList;
+
+ if (nodeToRemove)
+ nodeToRemove->remove();
+ }
+ }
}
#endif
-#if PLATFORM(GTK)
- result.cursorRect = frame.selection().absoluteCaretBounds();
-#endif
+ platformEditorState(frame, result, shouldIncludePostLayoutData);
+
+ m_lastEditorStateWasContentEditable = result.isContentEditable ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
return result;
}
+void WebPage::updateEditorStateAfterLayoutIfEditabilityChanged()
+{
+ // FIXME: We should update EditorStateIsContentEditable to track whether the state is richly
+ // editable or plainttext-only.
+ if (m_lastEditorStateWasContentEditable == EditorStateIsContentEditable::Unset)
+ return;
+
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+ EditorStateIsContentEditable editorStateIsContentEditable = frame.selection().selection().isContentEditable() ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
+ if (m_lastEditorStateWasContentEditable != editorStateIsContentEditable)
+ send(Messages::WebPageProxy::EditorStateChanged(editorState()));
+}
+
String WebPage::renderTreeExternalRepresentation() const
{
return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal);
@@ -721,7 +939,7 @@ void WebPage::resetTrackedRepaints()
view->resetTrackedRepaints();
}
-PassRefPtr<API::Array> WebPage::trackedRepaintRects()
+Ref<API::Array> WebPage::trackedRepaintRects()
{
FrameView* view = mainFrameView();
if (!view)
@@ -733,7 +951,7 @@ PassRefPtr<API::Array> WebPage::trackedRepaintRects()
for (const auto& repaintRect : view->trackedRepaintRects())
repaintRects.uncheckedAppend(API::Rect::create(toAPI(repaintRect)));
- return API::Array::create(std::move(repaintRects));
+ return API::Array::create(WTFMove(repaintRects));
}
PluginView* WebPage::focusedPluginViewForFrame(Frame& frame)
@@ -772,6 +990,19 @@ void WebPage::executeEditingCommand(const String& commandName, const String& arg
frame.editor().command(commandName).execute(argument);
}
+void WebPage::setEditable(bool editable)
+{
+ m_page->setEditable(editable);
+ m_page->setTabKeyCyclesThroughElements(!editable);
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+ if (editable) {
+ frame.editor().applyEditingStyleToBodyElement();
+ // If the page is made editable and the selection is empty, set it to something.
+ if (frame.selection().isNone())
+ frame.selection().setSelectionFromNone();
+ }
+}
+
bool WebPage::isEditingCommandEnabled(const String& commandName)
{
Frame& frame = m_page->focusController().focusedOrMainFrame();
@@ -789,7 +1020,6 @@ void WebPage::clearMainFrameName()
frame->tree().clearName();
}
-#if USE(ACCELERATED_COMPOSITING)
void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
{
m_drawingArea->setRootCompositingLayer(layer);
@@ -799,7 +1029,6 @@ void WebPage::exitAcceleratedCompositingMode()
{
m_drawingArea->setRootCompositingLayer(0);
}
-#endif
void WebPage::close()
{
@@ -812,30 +1041,34 @@ void WebPage::close()
if (!mainWebFrame()->url().isEmpty())
reportUsedFeatures();
- if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
- WebProcess::shared().injectedBundle()->willDestroyPage(this);
+ if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::singleton().injectedBundle())
+ WebProcess::singleton().injectedBundle()->willDestroyPage(this);
+
+ if (m_inspector) {
+ m_inspector->disconnectFromPage();
+ m_inspector = nullptr;
+ }
+
+ m_page->inspectorController().disconnectAllFrontends();
-#if ENABLE(INSPECTOR)
- m_inspector = 0;
-#endif
#if ENABLE(FULLSCREEN_API)
- m_fullScreenManager = 0;
+ m_fullScreenManager = nullptr;
#endif
if (m_activePopupMenu) {
m_activePopupMenu->disconnectFromPage();
- m_activePopupMenu = 0;
+ m_activePopupMenu = nullptr;
}
if (m_activeOpenPanelResultListener) {
m_activeOpenPanelResultListener->disconnectFromPage();
- m_activeOpenPanelResultListener = 0;
+ m_activeOpenPanelResultListener = nullptr;
}
#if ENABLE(INPUT_TYPE_COLOR)
if (m_activeColorChooser) {
m_activeColorChooser->disconnectFromPage();
- m_activeColorChooser = 0;
+ m_activeColorChooser = nullptr;
}
#endif
@@ -846,6 +1079,13 @@ void WebPage::close()
}
#endif
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+ if (m_installMediaPluginsCallback) {
+ m_installMediaPluginsCallback->invalidate();
+ m_installMediaPluginsCallback = nullptr;
+ }
+#endif
+
m_sandboxExtensionTracker.invalidate();
#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
@@ -853,39 +1093,41 @@ void WebPage::close()
#endif
#if ENABLE(CONTEXT_MENUS)
- m_contextMenuClient.initialize(0);
+ m_contextMenuClient = std::make_unique<API::InjectedBundle::PageContextMenuClient>();
#endif
- m_editorClient.initialize(0);
- m_formClient.initialize(0);
+ m_editorClient = std::make_unique<API::InjectedBundle::EditorClient>();
+ m_formClient = std::make_unique<API::InjectedBundle::FormClient>();
m_loaderClient.initialize(0);
m_policyClient.initialize(0);
m_resourceLoadClient.initialize(0);
- m_uiClient.initialize(0);
+ m_uiClient = std::make_unique<API::InjectedBundle::PageUIClient>();
#if ENABLE(FULLSCREEN_API)
m_fullScreenClient.initialize(0);
#endif
- m_logDiagnosticMessageClient.initialize(0);
m_printContext = nullptr;
m_mainFrame->coreFrame()->loader().detachFromParent();
- m_page = nullptr;
m_drawingArea = nullptr;
+ DeferredPageDestructor::createDeferredPageDestructor(WTFMove(m_page), this);
+
bool isRunningModal = m_isRunningModal;
m_isRunningModal = false;
// The WebPage can be destroyed by this call.
- WebProcess::shared().removeWebPage(m_pageID);
+ WebProcess::singleton().removeWebPage(m_pageID);
+
+ WebProcess::singleton().updateActivePages();
if (isRunningModal)
- RunLoop::main()->stop();
+ RunLoop::main().stop();
}
void WebPage::tryClose()
{
SendStopResponsivenessTimer stopper(this);
- if (!m_mainFrame->coreFrame()->loader().shouldClose()) {
+ if (!corePage()->userInputBridge().tryClosePage()) {
send(Messages::WebPageProxy::StopResponsivenessTimer());
return;
}
@@ -900,108 +1142,137 @@ void WebPage::sendClose()
void WebPage::loadURLInFrame(const String& url, uint64_t frameID)
{
- WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
if (!frame)
return;
- frame->coreFrame()->loader().load(FrameLoadRequest(frame->coreFrame(), ResourceRequest(URL(URL(), url))));
+ frame->coreFrame()->loader().load(FrameLoadRequest(frame->coreFrame(), ResourceRequest(URL(URL(), url)), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
+}
+
+#if !PLATFORM(COCOA)
+void WebPage::platformDidReceiveLoadParameters(const LoadParameters& loadParameters)
+{
}
+#endif
-void WebPage::loadRequest(const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle, IPC::MessageDecoder& decoder)
+void WebPage::loadRequest(const LoadParameters& loadParameters)
{
SendStopResponsivenessTimer stopper(this);
- RefPtr<API::Object> userData;
- InjectedBundleUserMessageDecoder userMessageDecoder(userData);
- if (!decoder.decode(userMessageDecoder))
- return;
+ m_pendingNavigationID = loadParameters.navigationID;
- m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
+ m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), loadParameters.sandboxExtensionHandle);
// Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
// to all the client to set up any needed state.
- m_loaderClient.willLoadURLRequest(this, request, userData.get());
+ m_loaderClient.willLoadURLRequest(this, loadParameters.request, WebProcess::singleton().transformHandlesToObjects(loadParameters.userData.object()).get());
+
+ platformDidReceiveLoadParameters(loadParameters);
// Initate the load in WebCore.
- m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(m_mainFrame->coreFrame(), request));
+ FrameLoadRequest frameLoadRequest(m_mainFrame->coreFrame(), loadParameters.request, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+ ShouldOpenExternalURLsPolicy externalURLsPolicy = static_cast<ShouldOpenExternalURLsPolicy>(loadParameters.shouldOpenExternalURLsPolicy);
+ frameLoadRequest.setShouldOpenExternalURLsPolicy(externalURLsPolicy);
+
+ corePage()->userInputBridge().loadRequest(frameLoadRequest);
+
+ ASSERT(!m_pendingNavigationID);
}
-void WebPage::loadDataImpl(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, IPC::MessageDecoder& decoder)
+void WebPage::loadDataImpl(uint64_t navigationID, PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, const UserData& userData)
{
SendStopResponsivenessTimer stopper(this);
- RefPtr<API::Object> userData;
- InjectedBundleUserMessageDecoder userMessageDecoder(userData);
- if (!decoder.decode(userMessageDecoder))
- return;
+ m_pendingNavigationID = navigationID;
ResourceRequest request(baseURL);
- SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL);
+ ResourceResponse response(URL(), MIMEType, sharedBuffer->size(), encodingName);
+ SubstituteData substituteData(sharedBuffer, unreachableURL, response, SubstituteData::SessionHistoryVisibility::Hidden);
// Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
// to all the client to set up any needed state.
- m_loaderClient.willLoadDataRequest(this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), userData.get());
+ m_loaderClient.willLoadDataRequest(this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), WebProcess::singleton().transformHandlesToObjects(userData.object()).get());
// Initate the load in WebCore.
- m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(m_mainFrame->coreFrame(), request, substituteData));
+ m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(m_mainFrame->coreFrame(), request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
}
-void WebPage::loadString(const String& htmlString, const String& MIMEType, const URL& baseURL, const URL& unreachableURL, IPC::MessageDecoder& decoder)
+void WebPage::loadStringImpl(uint64_t navigationID, const String& htmlString, const String& MIMEType, const URL& baseURL, const URL& unreachableURL, const UserData& userData)
{
if (!htmlString.isNull() && htmlString.is8Bit()) {
RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters8()), htmlString.length() * sizeof(LChar));
- loadDataImpl(sharedBuffer, MIMEType, ASCIILiteral("latin1"), baseURL, unreachableURL, decoder);
+ loadDataImpl(navigationID, sharedBuffer, MIMEType, ASCIILiteral("latin1"), baseURL, unreachableURL, userData);
} else {
RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters16()), htmlString.length() * sizeof(UChar));
- loadDataImpl(sharedBuffer, MIMEType, ASCIILiteral("utf-16"), baseURL, unreachableURL, decoder);
+ loadDataImpl(navigationID, sharedBuffer, MIMEType, ASCIILiteral("utf-16"), baseURL, unreachableURL, userData);
}
}
-void WebPage::loadData(const IPC::DataReference& data, const String& MIMEType, const String& encodingName, const String& baseURLString, IPC::MessageDecoder& decoder)
+void WebPage::loadData(const LoadParameters& loadParameters)
{
- RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(data.data()), data.size());
- URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
- loadDataImpl(sharedBuffer, MIMEType, encodingName, baseURL, URL(), decoder);
-}
+ platformDidReceiveLoadParameters(loadParameters);
-void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString, IPC::MessageDecoder& decoder)
-{
- URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
- loadString(htmlString, ASCIILiteral("text/html"), baseURL, URL(), decoder);
+ RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
+ URL baseURL = loadParameters.baseURLString.isEmpty() ? blankURL() : URL(URL(), loadParameters.baseURLString);
+ loadDataImpl(loadParameters.navigationID, sharedBuffer, loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData);
}
-void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString, IPC::MessageDecoder& decoder)
+void WebPage::loadString(const LoadParameters& loadParameters)
{
- URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
- URL unreachableURL = unreachableURLString.isEmpty() ? URL() : URL(URL(), unreachableURLString);
- loadString(htmlString, ASCIILiteral("text/html"), baseURL, unreachableURL, decoder);
+ platformDidReceiveLoadParameters(loadParameters);
+
+ URL baseURL = loadParameters.baseURLString.isEmpty() ? blankURL() : URL(URL(), loadParameters.baseURLString);
+ loadStringImpl(loadParameters.navigationID, loadParameters.string, loadParameters.MIMEType, baseURL, URL(), loadParameters.userData);
}
-void WebPage::loadPlainTextString(const String& string, IPC::MessageDecoder& decoder)
+void WebPage::loadAlternateHTMLString(const LoadParameters& loadParameters)
{
- loadString(string, ASCIILiteral("text/plain"), blankURL(), URL(), decoder);
+ platformDidReceiveLoadParameters(loadParameters);
+
+ URL baseURL = loadParameters.baseURLString.isEmpty() ? blankURL() : URL(URL(), loadParameters.baseURLString);
+ URL unreachableURL = loadParameters.unreachableURLString.isEmpty() ? URL() : URL(URL(), loadParameters.unreachableURLString);
+ URL provisionalLoadErrorURL = loadParameters.provisionalLoadErrorURLString.isEmpty() ? URL() : URL(URL(), loadParameters.provisionalLoadErrorURLString);
+ m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL(provisionalLoadErrorURL);
+ loadStringImpl(0, loadParameters.string, ASCIILiteral("text/html"), baseURL, unreachableURL, loadParameters.userData);
+ m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL({ });
}
-void WebPage::loadWebArchiveData(const IPC::DataReference& webArchiveData, IPC::MessageDecoder& decoder)
+void WebPage::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
{
- RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(webArchiveData.data()), webArchiveData.size() * sizeof(uint8_t));
- loadDataImpl(sharedBuffer, ASCIILiteral("application/x-webarchive"), ASCIILiteral("utf-16"), blankURL(), URL(), decoder);
+ Frame* mainFrame = m_mainFrame->coreFrame();
+ Document* mainFrameDocument = mainFrame->document();
+ if (!mainFrameDocument)
+ return;
+
+ const int singleClick = 1;
+ RefPtr<MouseEvent> mouseEvent = MouseEvent::create(eventNames().clickEvent, true, true, currentTime(), nullptr, singleClick, screenPoint.x(), screenPoint.y(), documentPoint.x(), documentPoint.y(),
+#if ENABLE(POINTER_LOCK)
+ 0, 0,
+#endif
+ false, false, false, false, 0, nullptr, 0, WebCore::NoTap, nullptr);
+
+ mainFrame->loader().urlSelected(mainFrameDocument->completeURL(url), emptyString(), mouseEvent.get(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
}
void WebPage::stopLoadingFrame(uint64_t frameID)
{
- WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
if (!frame)
return;
- frame->coreFrame()->loader().stopForUserCancel();
+ corePage()->userInputBridge().stopLoadingFrame(frame->coreFrame());
}
void WebPage::stopLoading()
{
SendStopResponsivenessTimer stopper(this);
- m_mainFrame->coreFrame()->loader().stopForUserCancel();
+ corePage()->userInputBridge().stopLoadingFrame(m_mainFrame->coreFrame());
+}
+
+bool WebPage::defersLoading() const
+{
+ return m_page->defersLoading();
}
void WebPage::setDefersLoading(bool defersLoading)
@@ -1009,15 +1280,18 @@ void WebPage::setDefersLoading(bool defersLoading)
m_page->setDefersLoading(defersLoading);
}
-void WebPage::reload(bool reloadFromOrigin, const SandboxExtension::Handle& sandboxExtensionHandle)
+void WebPage::reload(uint64_t navigationID, bool reloadFromOrigin, bool contentBlockersEnabled, const SandboxExtension::Handle& sandboxExtensionHandle)
{
SendStopResponsivenessTimer stopper(this);
+ ASSERT(!m_mainFrame->coreFrame()->loader().frameHasLoaded() || !m_pendingNavigationID);
+ m_pendingNavigationID = navigationID;
+
m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
- m_mainFrame->coreFrame()->loader().reload(reloadFromOrigin);
+ corePage()->userInputBridge().reloadFrame(m_mainFrame->coreFrame(), reloadFromOrigin, contentBlockersEnabled);
}
-void WebPage::goForward(uint64_t backForwardItemID)
+void WebPage::goForward(uint64_t navigationID, uint64_t backForwardItemID)
{
SendStopResponsivenessTimer stopper(this);
@@ -1026,10 +1300,13 @@ void WebPage::goForward(uint64_t backForwardItemID)
if (!item)
return;
- m_page->goToItem(item, FrameLoadTypeForward);
+ ASSERT(!m_pendingNavigationID);
+ m_pendingNavigationID = navigationID;
+
+ m_page->goToItem(*item, FrameLoadType::Forward);
}
-void WebPage::goBack(uint64_t backForwardItemID)
+void WebPage::goBack(uint64_t navigationID, uint64_t backForwardItemID)
{
SendStopResponsivenessTimer stopper(this);
@@ -1038,10 +1315,13 @@ void WebPage::goBack(uint64_t backForwardItemID)
if (!item)
return;
- m_page->goToItem(item, FrameLoadTypeBack);
+ ASSERT(!m_pendingNavigationID);
+ m_pendingNavigationID = navigationID;
+
+ m_page->goToItem(*item, FrameLoadType::Back);
}
-void WebPage::goToBackForwardItem(uint64_t backForwardItemID)
+void WebPage::goToBackForwardItem(uint64_t navigationID, uint64_t backForwardItemID)
{
SendStopResponsivenessTimer stopper(this);
@@ -1050,7 +1330,10 @@ void WebPage::goToBackForwardItem(uint64_t backForwardItemID)
if (!item)
return;
- m_page->goToItem(item, FrameLoadTypeIndexedBackForward);
+ ASSERT(!m_pendingNavigationID);
+ m_pendingNavigationID = navigationID;
+
+ m_page->goToItem(*item, FrameLoadType::IndexedBackForward);
}
void WebPage::tryRestoreScrollPosition()
@@ -1066,7 +1349,7 @@ void WebPage::layoutIfNeeded()
WebPage* WebPage::fromCorePage(Page* page)
{
- return static_cast<WebChromeClient&>(page->chrome().client()).page();
+ return &static_cast<WebChromeClient&>(page->chrome().client()).page();
}
void WebPage::setSize(const WebCore::IntSize& viewSize)
@@ -1074,29 +1357,22 @@ void WebPage::setSize(const WebCore::IntSize& viewSize)
if (m_viewSize == viewSize)
return;
+ m_viewSize = viewSize;
FrameView* view = m_page->mainFrame().view();
view->resize(viewSize);
m_drawingArea->setNeedsDisplay();
-
- m_viewSize = viewSize;
-#if USE(TILED_BACKING_STORE)
+#if USE(COORDINATED_GRAPHICS)
if (view->useFixedLayout())
- sendViewportAttributesChanged();
+ sendViewportAttributesChanged(m_page->viewportArguments());
#endif
}
-#if USE(TILED_BACKING_STORE)
-void WebPage::setFixedVisibleContentRect(const IntRect& rect)
-{
- ASSERT(m_useFixedLayout);
-
- m_page->mainFrame().view()->setFixedVisibleContentRect(rect);
-}
-
-void WebPage::sendViewportAttributesChanged()
+#if USE(COORDINATED_GRAPHICS)
+void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArguments)
{
- ASSERT(m_useFixedLayout);
+ FrameView* view = m_page->mainFrame().view();
+ ASSERT(view && view->useFixedLayout());
// Viewport properties have no impact on zero sized fixed viewports.
if (m_viewSize.isEmpty())
@@ -1111,9 +1387,7 @@ void WebPage::sendViewportAttributesChanged()
int deviceWidth = (settings.deviceWidth() > 0) ? settings.deviceWidth() : m_viewSize.width();
int deviceHeight = (settings.deviceHeight() > 0) ? settings.deviceHeight() : m_viewSize.height();
- ViewportAttributes attr = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
-
- FrameView* view = m_page->mainFrame().view();
+ ViewportAttributes attr = computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
// If no layout was done yet set contentFixedOrigin to (0,0).
IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint();
@@ -1129,14 +1403,18 @@ void WebPage::sendViewportAttributesChanged()
#endif
contentFixedSize.scale(1 / attr.initialScale);
- setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
+ view->setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
// This also takes care of the relayout.
setFixedLayoutSize(roundedIntSize(attr.layoutSize));
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ m_drawingArea->didChangeViewportAttributes(WTFMove(attr));
+#else
send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
+#endif
}
#endif
@@ -1144,8 +1422,8 @@ void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffse
{
FrameView* frameView = m_page->mainFrame().view();
- IntPoint scrollPosition = frameView->scrollPosition();
- IntPoint maximumScrollPosition = frameView->maximumScrollPosition();
+ ScrollPosition scrollPosition = frameView->scrollPosition();
+ ScrollPosition maximumScrollPosition = frameView->maximumScrollPosition();
// If the current scroll position in a direction is the max scroll position
// we don't want to scroll at all.
@@ -1166,20 +1444,18 @@ void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
GraphicsContextStateSaver stateSaver(graphicsContext);
graphicsContext.clip(rect);
- m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
-}
-
-void WebPage::drawPageOverlay(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& rect)
-{
- ASSERT(pageOverlay);
-
- GraphicsContextStateSaver stateSaver(graphicsContext);
- graphicsContext.clip(rect);
- pageOverlay->drawRect(graphicsContext, rect);
+ m_mainFrame->coreFrame()->view()->paint(graphicsContext, rect);
}
double WebPage::textZoomFactor() const
{
+ PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
+ if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
+ if (pluginView->handlesPageScaleFactor())
+ return pluginView->pageScaleFactor();
+ return pageScaleFactor();
+ }
+
Frame* frame = m_mainFrame->coreFrame();
if (!frame)
return 1;
@@ -1189,8 +1465,13 @@ double WebPage::textZoomFactor() const
void WebPage::setTextZoomFactor(double zoomFactor)
{
PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
- if (pluginView && pluginView->handlesPageScaleFactor())
+ if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
+ if (pluginView->handlesPageScaleFactor())
+ pluginView->setPageScaleFactor(zoomFactor, IntPoint());
+ else
+ scalePage(zoomFactor, IntPoint());
return;
+ }
Frame* frame = m_mainFrame->coreFrame();
if (!frame)
@@ -1201,8 +1482,11 @@ void WebPage::setTextZoomFactor(double zoomFactor)
double WebPage::pageZoomFactor() const
{
PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
- if (pluginView && pluginView->handlesPageScaleFactor())
- return pluginView->pageScaleFactor();
+ if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
+ if (pluginView->handlesPageScaleFactor())
+ return pluginView->pageScaleFactor();
+ return pageScaleFactor();
+ }
Frame* frame = m_mainFrame->coreFrame();
if (!frame)
@@ -1213,8 +1497,11 @@ double WebPage::pageZoomFactor() const
void WebPage::setPageZoomFactor(double zoomFactor)
{
PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
- if (pluginView && pluginView->handlesPageScaleFactor()) {
- pluginView->setPageScaleFactor(zoomFactor, IntPoint());
+ if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
+ if (pluginView->handlesPageScaleFactor())
+ pluginView->setPageScaleFactor(zoomFactor, IntPoint());
+ else
+ scalePage(zoomFactor, IntPoint());
return;
}
@@ -1227,8 +1514,11 @@ void WebPage::setPageZoomFactor(double zoomFactor)
void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
{
PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
- if (pluginView && pluginView->handlesPageScaleFactor()) {
- pluginView->setPageScaleFactor(pageZoomFactor, IntPoint());
+ if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
+ if (pluginView->handlesPageScaleFactor())
+ pluginView->setPageScaleFactor(pageZoomFactor, IntPoint());
+ else
+ scalePage(pageZoomFactor, IntPoint());
return;
}
@@ -1238,39 +1528,102 @@ void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFa
return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
}
-void WebPage::windowScreenDidChange(uint64_t displayID)
+void WebPage::windowScreenDidChange(uint32_t displayID)
{
m_page->chrome().windowScreenDidChange(static_cast<PlatformDisplayID>(displayID));
}
void WebPage::scalePage(double scale, const IntPoint& origin)
{
+ double totalScale = scale * viewScaleFactor();
+ bool willChangeScaleFactor = totalScale != totalScaleFactor();
+
+#if PLATFORM(IOS)
+ if (willChangeScaleFactor) {
+ if (!m_inDynamicSizeUpdate)
+ m_dynamicSizeUpdateHistory.clear();
+ m_scaleWasSetByUIProcess = false;
+ }
+#endif
PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
if (pluginView && pluginView->handlesPageScaleFactor()) {
- pluginView->setPageScaleFactor(scale, origin);
+ // If the main-frame plugin wants to handle the page scale factor, make sure to reset WebCore's page scale.
+ // Otherwise, we can end up with an immutable but non-1 page scale applied by WebCore on top of whatever the plugin does.
+ if (m_page->pageScaleFactor() != 1) {
+ m_page->setPageScaleFactor(1, origin);
+ for (auto* pluginView : m_pluginViews)
+ pluginView->pageScaleFactorDidChange();
+ }
+
+ pluginView->setPageScaleFactor(totalScale, origin);
return;
}
- m_page->setPageScaleFactor(scale, origin);
+ m_page->setPageScaleFactor(totalScale, origin);
+
+ // We can't early return before setPageScaleFactor because the origin might be different.
+ if (!willChangeScaleFactor)
+ return;
for (auto* pluginView : m_pluginViews)
pluginView->pageScaleFactorDidChange();
- if (m_drawingArea->layerTreeHost())
- m_drawingArea->layerTreeHost()->deviceOrPageScaleFactorChanged();
+#if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
+ m_drawingArea->deviceOrPageScaleFactorChanged();
+#endif
send(Messages::WebPageProxy::PageScaleFactorDidChange(scale));
}
-double WebPage::pageScaleFactor() const
+void WebPage::scalePageInViewCoordinates(double scale, IntPoint centerInViewCoordinates)
+{
+ double totalScale = scale * viewScaleFactor();
+ if (totalScale == totalScaleFactor())
+ return;
+
+ IntPoint scrollPositionAtNewScale = mainFrameView()->rootViewToContents(-centerInViewCoordinates);
+ double scaleRatio = scale / pageScaleFactor();
+ scrollPositionAtNewScale.scale(scaleRatio);
+ scalePage(scale, scrollPositionAtNewScale);
+}
+
+double WebPage::totalScaleFactor() const
{
PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
if (pluginView && pluginView->handlesPageScaleFactor())
return pluginView->pageScaleFactor();
-
+
return m_page->pageScaleFactor();
}
+double WebPage::pageScaleFactor() const
+{
+ return totalScaleFactor() / viewScaleFactor();
+}
+
+double WebPage::viewScaleFactor() const
+{
+ return m_page->viewScaleFactor();
+}
+
+void WebPage::scaleView(double scale)
+{
+ if (viewScaleFactor() == scale)
+ return;
+
+ float pageScale = pageScaleFactor();
+
+ IntPoint scrollPositionAtNewScale;
+ if (FrameView* mainFrameView = m_page->mainFrame().view()) {
+ double scaleRatio = scale / viewScaleFactor();
+ scrollPositionAtNewScale = mainFrameView->scrollPosition();
+ scrollPositionAtNewScale.scale(scaleRatio);
+ }
+
+ m_page->setViewScaleFactor(scale);
+ scalePage(pageScale, scrollPositionAtNewScale);
+}
+
void WebPage::setDeviceScaleFactor(float scaleFactor)
{
if (scaleFactor == m_page->deviceScaleFactor())
@@ -1279,7 +1632,7 @@ void WebPage::setDeviceScaleFactor(float scaleFactor)
m_page->setDeviceScaleFactor(scaleFactor);
// Tell all our plug-in views that the device scale factor changed.
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
for (auto* pluginView : m_pluginViews)
pluginView->setDeviceScaleFactor(scaleFactor);
@@ -1292,8 +1645,9 @@ void WebPage::setDeviceScaleFactor(float scaleFactor)
m_findController.deviceScaleFactorDidChange();
}
- if (m_drawingArea->layerTreeHost())
- m_drawingArea->layerTreeHost()->deviceOrPageScaleFactorChanged();
+#if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
+ m_drawingArea->deviceOrPageScaleFactorChanged();
+#endif
}
float WebPage::deviceScaleFactor() const
@@ -1301,6 +1655,11 @@ float WebPage::deviceScaleFactor() const
return m_page->deviceScaleFactor();
}
+void WebPage::accessibilitySettingsDidChange()
+{
+ m_page->accessibilitySettingsDidChange();
+}
+
void WebPage::setUseFixedLayout(bool fixed)
{
// Do not overwrite current settings if initially setting it to false.
@@ -1308,7 +1667,9 @@ void WebPage::setUseFixedLayout(bool fixed)
return;
m_useFixedLayout = fixed;
+#if !PLATFORM(IOS)
m_page->settings().setFixedElementsLayoutRelativeToFrame(fixed);
+#endif
#if USE(COORDINATED_GRAPHICS)
m_page->settings().setAcceleratedCompositingForFixedPositionEnabled(fixed);
m_page->settings().setFixedPositionCreatesStackingContext(fixed);
@@ -1316,7 +1677,7 @@ void WebPage::setUseFixedLayout(bool fixed)
m_page->settings().setScrollingCoordinatorEnabled(fixed);
#endif
-#if USE(TILED_BACKING_STORE) && ENABLE(SMOOTH_SCROLLING)
+#if USE(COORDINATED_GRAPHICS) && ENABLE(SMOOTH_SCROLLING)
// Delegated scrolling will be enabled when the FrameView is created if fixed layout is enabled.
// Ensure we don't do animated scrolling in the WebProcess in that case.
m_page->settings().setScrollAnimatorEnabled(!fixed);
@@ -1326,25 +1687,57 @@ void WebPage::setUseFixedLayout(bool fixed)
if (!view)
return;
-#if USE(TILED_BACKING_STORE)
+#if USE(COORDINATED_GRAPHICS)
view->setDelegatesScrolling(fixed);
view->setPaintsEntireContents(fixed);
#endif
view->setUseFixedLayout(fixed);
if (!fixed)
setFixedLayoutSize(IntSize());
+
+ send(Messages::WebPageProxy::UseFixedLayoutDidChange(fixed));
}
-void WebPage::setFixedLayoutSize(const IntSize& size)
+bool WebPage::setFixedLayoutSize(const IntSize& size)
{
FrameView* view = mainFrameView();
if (!view || view->fixedLayoutSize() == size)
- return;
+ return false;
view->setFixedLayoutSize(size);
- // Do not force it until the first layout, this would then become our first layout prematurely.
- if (view->didFirstLayout())
- view->forceLayout();
+
+ send(Messages::WebPageProxy::FixedLayoutSizeDidChange(size));
+ return true;
+}
+
+IntSize WebPage::fixedLayoutSize() const
+{
+ FrameView* view = mainFrameView();
+ if (!view)
+ return IntSize();
+ return view->fixedLayoutSize();
+}
+
+void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArguments)
+{
+#if PLATFORM(IOS)
+ if (m_viewportConfiguration.setViewportArguments(viewportArguments))
+ viewportConfigurationChanged();
+#endif
+
+#if USE(COORDINATED_GRAPHICS)
+ FrameView* view = m_page->mainFrame().view();
+ if (view && view->useFixedLayout())
+ sendViewportAttributesChanged(viewportArguments);
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ else
+ m_drawingArea->didChangeViewportAttributes(ViewportAttributes());
+#endif
+#endif
+
+#if !PLATFORM(IOS) && !USE(COORDINATED_GRAPHICS)
+ UNUSED_PARAM(viewportArguments);
+#endif
}
void WebPage::listenForLayoutMilestones(uint32_t milestones)
@@ -1358,6 +1751,16 @@ void WebPage::setSuppressScrollbarAnimations(bool suppressAnimations)
{
m_page->setShouldSuppressScrollbarAnimations(suppressAnimations);
}
+
+void WebPage::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
+{
+ m_page->setVerticalScrollElasticity(enableVerticalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
+}
+
+void WebPage::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
+{
+ m_page->setHorizontalScrollElasticity(enableHorizontalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
+}
void WebPage::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
{
@@ -1393,55 +1796,24 @@ void WebPage::setGapBetweenPages(double gap)
m_page->setPagination(pagination);
}
-void WebPage::postInjectedBundleMessage(const String& messageName, IPC::MessageDecoder& decoder)
+void WebPage::setPaginationLineGridEnabled(bool lineGridEnabled)
{
- InjectedBundle* injectedBundle = WebProcess::shared().injectedBundle();
- if (!injectedBundle)
- return;
-
- RefPtr<API::Object> messageBody;
- InjectedBundleUserMessageDecoder messageBodyDecoder(messageBody);
- if (!decoder.decode(messageBodyDecoder))
- return;
-
- injectedBundle->didReceiveMessageToPage(this, messageName, messageBody.get());
+ m_page->setPaginationLineGridEnabled(lineGridEnabled);
}
-void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay, bool shouldFadeIn)
+void WebPage::postInjectedBundleMessage(const String& messageName, const UserData& userData)
{
- RefPtr<PageOverlay> overlay = pageOverlay;
-
- if (m_pageOverlays.contains(overlay.get()))
- return;
-
- m_pageOverlays.append(overlay);
- overlay->setPage(this);
-
- if (shouldFadeIn)
- overlay->startFadeInAnimation();
-
- m_drawingArea->didInstallPageOverlay(overlay.get());
-}
-
-void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool shouldFadeOut)
-{
- size_t existingOverlayIndex = m_pageOverlays.find(pageOverlay);
- if (existingOverlayIndex == notFound)
- return;
-
- if (shouldFadeOut) {
- pageOverlay->startFadeOutAnimation();
+ auto& webProcess = WebProcess::singleton();
+ InjectedBundle* injectedBundle = webProcess.injectedBundle();
+ if (!injectedBundle)
return;
- }
- pageOverlay->setPage(0);
- m_pageOverlays.remove(existingOverlayIndex);
-
- m_drawingArea->didUninstallPageOverlay(pageOverlay);
+ injectedBundle->didReceiveMessageToPage(this, messageName, webProcess.transformHandlesToObjects(userData.object()).get());
}
#if !PLATFORM(IOS)
-void WebPage::setHeaderPageBanner(PassRefPtr<PageBanner> pageBanner)
+
+void WebPage::setHeaderPageBanner(PageBanner* pageBanner)
{
if (m_headerBanner)
m_headerBanner->detachFromPage();
@@ -1457,7 +1829,7 @@ PageBanner* WebPage::headerPageBanner()
return m_headerBanner.get();
}
-void WebPage::setFooterPageBanner(PassRefPtr<PageBanner> pageBanner)
+void WebPage::setFooterPageBanner(PageBanner* pageBanner)
{
if (m_footerBanner)
m_footerBanner->detachFromPage();
@@ -1488,32 +1860,93 @@ void WebPage::showPageBanners()
if (m_footerBanner)
m_footerBanner->showIfHidden();
}
+
+void WebPage::setHeaderBannerHeightForTesting(int height)
+{
+#if ENABLE(RUBBER_BANDING)
+ corePage()->addHeaderWithHeight(height);
+#endif
+}
+
+void WebPage::setFooterBannerHeightForTesting(int height)
+{
+#if ENABLE(RUBBER_BANDING)
+ corePage()->addFooterWithHeight(height);
+#endif
+}
+
#endif // !PLATFORM(IOS)
-PassRefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double scaleFactor, SnapshotOptions options)
+void WebPage::takeSnapshot(IntRect snapshotRect, IntSize bitmapSize, uint32_t options, uint64_t callbackID)
+{
+ SnapshotOptions snapshotOptions = static_cast<SnapshotOptions>(options);
+ snapshotOptions |= SnapshotOptionsShareable;
+
+ RefPtr<WebImage> image = snapshotAtSize(snapshotRect, bitmapSize, snapshotOptions);
+
+ ShareableBitmap::Handle handle;
+ if (image)
+ image->bitmap().createHandle(handle, SharedMemory::Protection::ReadOnly);
+
+ send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
+}
+
+PassRefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double additionalScaleFactor, SnapshotOptions options)
+{
+ IntRect snapshotRect = rect;
+ IntSize bitmapSize = snapshotRect.size();
+ if (options & SnapshotOptionsPrinting) {
+ ASSERT(additionalScaleFactor == 1);
+ Frame* coreFrame = m_mainFrame->coreFrame();
+ if (!coreFrame)
+ return nullptr;
+ bitmapSize.setHeight(PrintContext::numberOfPages(*coreFrame, bitmapSize) * (bitmapSize.height() + 1) - 1);
+ } else {
+ double scaleFactor = additionalScaleFactor;
+ if (!(options & SnapshotOptionsExcludeDeviceScaleFactor))
+ scaleFactor *= corePage()->deviceScaleFactor();
+ bitmapSize.scale(scaleFactor);
+ }
+
+ return snapshotAtSize(rect, bitmapSize, options);
+}
+
+PassRefPtr<WebImage> WebPage::snapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
{
Frame* coreFrame = m_mainFrame->coreFrame();
if (!coreFrame)
- return 0;
+ return nullptr;
FrameView* frameView = coreFrame->view();
if (!frameView)
- return 0;
+ return nullptr;
- IntSize bitmapSize = rect.size();
- float combinedScaleFactor = scaleFactor * corePage()->deviceScaleFactor();
- bitmapSize.scale(combinedScaleFactor);
+ IntRect snapshotRect = rect;
+ float horizontalScaleFactor = static_cast<float>(bitmapSize.width()) / rect.width();
+ float verticalScaleFactor = static_cast<float>(bitmapSize.height()) / rect.height();
+ float scaleFactor = std::max(horizontalScaleFactor, verticalScaleFactor);
- RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
- if (!snapshot->bitmap())
- return 0;
+ auto snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
+
+ auto graphicsContext = snapshot->bitmap().createGraphicsContext();
+
+ if (options & SnapshotOptionsPrinting) {
+ PrintContext::spoolAllPagesWithBoundaries(*coreFrame, *graphicsContext, snapshotRect.size());
+ return snapshot;
+ }
- auto graphicsContext = snapshot->bitmap()->createGraphicsContext();
+ Color documentBackgroundColor = frameView->documentBackgroundColor();
+ Color backgroundColor = (coreFrame->settings().backgroundShouldExtendBeyondPage() && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView->baseBackgroundColor();
+ graphicsContext->fillRect(IntRect(IntPoint(), bitmapSize), backgroundColor);
- graphicsContext->clearRect(IntRect(IntPoint(), bitmapSize));
+ if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
+ double deviceScaleFactor = corePage()->deviceScaleFactor();
+ graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
+ scaleFactor /= deviceScaleFactor;
+ }
- graphicsContext->applyDeviceScaleFactor(combinedScaleFactor);
- graphicsContext->translate(-rect.x(), -rect.y());
+ graphicsContext->scale(scaleFactor);
+ graphicsContext->translate(-snapshotRect.x(), -snapshotRect.y());
FrameView::SelectionInSnapshot shouldPaintSelection = FrameView::IncludeSelection;
if (options & SnapshotOptionsExcludeSelectionHighlighting)
@@ -1523,28 +1956,94 @@ PassRefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, dou
if (options & SnapshotOptionsInViewCoordinates)
coordinateSpace = FrameView::ViewCoordinates;
- frameView->paintContentsForSnapshot(graphicsContext.get(), rect, shouldPaintSelection, coordinateSpace);
+ frameView->paintContentsForSnapshot(*graphicsContext, snapshotRect, shouldPaintSelection, coordinateSpace);
if (options & SnapshotOptionsPaintSelectionRectangle) {
- FloatRect selectionRectangle = m_mainFrame->coreFrame()->selection().bounds();
- graphicsContext->setStrokeColor(Color(0xFF, 0, 0), ColorSpaceDeviceRGB);
+ FloatRect selectionRectangle = m_mainFrame->coreFrame()->selection().selectionBounds();
+ graphicsContext->setStrokeColor(Color(0xFF, 0, 0));
graphicsContext->strokeRect(selectionRectangle, 1);
}
+
+ return snapshot;
+}
+
+PassRefPtr<WebImage> WebPage::snapshotNode(WebCore::Node& node, SnapshotOptions options, unsigned maximumPixelCount)
+{
+ Frame* coreFrame = m_mainFrame->coreFrame();
+ if (!coreFrame)
+ return nullptr;
- return snapshot.release();
+ FrameView* frameView = coreFrame->view();
+ if (!frameView)
+ return nullptr;
+
+ if (!node.renderer())
+ return nullptr;
+
+ LayoutRect topLevelRect;
+ IntRect snapshotRect = snappedIntRect(node.renderer()->paintingRootRect(topLevelRect));
+ if (snapshotRect.isEmpty())
+ return nullptr;
+
+ double scaleFactor = 1;
+ IntSize snapshotSize = snapshotRect.size();
+ unsigned maximumHeight = maximumPixelCount / snapshotSize.width();
+ if (maximumHeight < static_cast<unsigned>(snapshotSize.height())) {
+ scaleFactor = static_cast<double>(maximumHeight) / snapshotSize.height();
+ snapshotSize = IntSize(snapshotSize.width() * scaleFactor, maximumHeight);
+ }
+
+ auto snapshot = WebImage::create(snapshotSize, snapshotOptionsToImageOptions(options));
+
+ auto graphicsContext = snapshot->bitmap().createGraphicsContext();
+
+ if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
+ double deviceScaleFactor = corePage()->deviceScaleFactor();
+ graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
+ scaleFactor /= deviceScaleFactor;
+ }
+
+ graphicsContext->scale(scaleFactor);
+ graphicsContext->translate(-snapshotRect.x(), -snapshotRect.y());
+
+ Color savedBackgroundColor = frameView->baseBackgroundColor();
+ frameView->setBaseBackgroundColor(Color::transparent);
+ frameView->setNodeToDraw(&node);
+
+ frameView->paintContentsForSnapshot(*graphicsContext, snapshotRect, FrameView::ExcludeSelection, FrameView::DocumentCoordinates);
+
+ frameView->setBaseBackgroundColor(savedBackgroundColor);
+ frameView->setNodeToDraw(nullptr);
+
+ return snapshot;
}
void WebPage::pageDidScroll()
{
- m_uiClient.pageDidScroll(this);
+#if PLATFORM(IOS)
+ if (!m_inDynamicSizeUpdate)
+ m_dynamicSizeUpdateHistory.clear();
+#endif
+ m_uiClient->pageDidScroll(this);
+
+ m_pageScrolledHysteresis.impulse();
send(Messages::WebPageProxy::PageDidScroll());
}
-#if USE(TILED_BACKING_STORE)
+void WebPage::pageStoppedScrolling()
+{
+ // Maintain the current history item's scroll position up-to-date.
+ if (Frame* frame = m_mainFrame->coreFrame())
+ frame->loader().history().saveScrollPositionAndViewStateToItem(frame->loader().history().currentItem());
+}
+
+#if USE(COORDINATED_GRAPHICS)
void WebPage::pageDidRequestScroll(const IntPoint& point)
{
- send(Messages::WebPageProxy::PageDidRequestScroll(point));
+#if USE(COORDINATED_GRAPHICS_THREADED)
+ drawingArea()->scroll(IntRect(point, IntSize()), IntSize());
+#endif
}
#endif
@@ -1559,14 +2058,16 @@ WebContextMenu* WebPage::contextMenu()
WebContextMenu* WebPage::contextMenuAtPointInWindow(const IntPoint& point)
{
corePage()->contextMenuController().clearContextMenu();
-
+
// Simulate a mouse click to generate the correct menu.
- PlatformMouseEvent mouseEvent(point, point, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime());
- bool handled = corePage()->mainFrame().eventHandler().sendContextMenuEvent(mouseEvent);
- if (!handled)
- return 0;
+ PlatformMouseEvent mousePressEvent(point, point, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime(), WebCore::ForceAtClick, WebCore::NoTap);
+ corePage()->userInputBridge().handleMousePressEvent(mousePressEvent);
+ bool handled = corePage()->userInputBridge().handleContextMenuEvent(mousePressEvent, &corePage()->mainFrame());
+ auto* menu = handled ? contextMenu() : nullptr;
+ PlatformMouseEvent mouseReleaseEvent(point, point, RightButton, PlatformEvent::MouseReleased, 1, false, false, false, false, currentTime(), WebCore::ForceAtClick, WebCore::NoTap);
+ corePage()->userInputBridge().handleMouseReleaseEvent(mouseReleaseEvent);
- return contextMenu();
+ return menu;
}
#endif
@@ -1582,6 +2083,75 @@ const WebEvent* WebPage::currentEvent()
return g_currentEvent;
}
+void WebPage::setLayerTreeStateIsFrozen(bool frozen)
+{
+ auto* drawingArea = this->drawingArea();
+ if (!drawingArea)
+ return;
+
+ drawingArea->setLayerTreeStateIsFrozen(frozen);
+}
+
+void WebPage::callVolatilityCompletionHandlers()
+{
+ auto completionHandlers = WTFMove(m_markLayersAsVolatileCompletionHandlers);
+ for (auto& completionHandler : completionHandlers)
+ completionHandler();
+}
+
+void WebPage::layerVolatilityTimerFired()
+{
+ auto newInterval = 2 * m_layerVolatilityTimer.repeatIntervalMS();
+ bool didSucceed = markLayersVolatileImmediatelyIfPossible();
+ if (didSucceed || newInterval > maximumLayerVolatilityTimerInterval) {
+ m_layerVolatilityTimer.stop();
+ RELEASE_LOG_IF_ALLOWED("%p - WebPage - Attempted to mark layers as volatile, success? %d", this, didSucceed);
+ callVolatilityCompletionHandlers();
+ return;
+ }
+
+ RELEASE_LOG_ERROR_IF_ALLOWED("%p - WebPage - Failed to mark all layers as volatile, will retry in %lld ms", this, static_cast<long long>(newInterval.count()));
+ m_layerVolatilityTimer.startRepeating(newInterval);
+}
+
+bool WebPage::markLayersVolatileImmediatelyIfPossible()
+{
+ return !drawingArea() || drawingArea()->markLayersVolatileImmediatelyIfPossible();
+}
+
+void WebPage::markLayersVolatile(std::function<void ()> completionHandler)
+{
+ RELEASE_LOG_IF_ALLOWED("%p - WebPage::markLayersVolatile()", this);
+
+ if (m_layerVolatilityTimer.isActive())
+ m_layerVolatilityTimer.stop();
+
+ if (completionHandler)
+ m_markLayersAsVolatileCompletionHandlers.append(WTFMove(completionHandler));
+
+ bool didSucceed = markLayersVolatileImmediatelyIfPossible();
+ if (didSucceed || m_isSuspendedUnderLock) {
+ if (didSucceed)
+ RELEASE_LOG_IF_ALLOWED("%p - WebPage - Successfully marked layers as volatile", this);
+ else {
+ // If we get suspended when locking the screen, it is expected that some IOSurfaces cannot be marked as purgeable so we do not keep retrying.
+ RELEASE_LOG_IF_ALLOWED("%p - WebPage - Did what we could to mark IOSurfaces as purgeable after locking the screen", this);
+ }
+ callVolatilityCompletionHandlers();
+ return;
+ }
+
+ RELEASE_LOG_IF_ALLOWED("%p - Failed to mark all layers as volatile, will retry in %lld ms", this, initialLayerVolatilityTimerInterval.count());
+ m_layerVolatilityTimer.startRepeating(initialLayerVolatilityTimerInterval);
+}
+
+void WebPage::cancelMarkLayersVolatile()
+{
+ RELEASE_LOG_IF_ALLOWED("%p - WebPage::cancelMarkLayersVolatile()", this);
+ m_layerVolatilityTimer.stop();
+ m_markLayersAsVolatileCompletionHandlers.clear();
+}
+
class CurrentEvent {
public:
explicit CurrentEvent(const WebEvent& event)
@@ -1602,16 +2172,11 @@ private:
#if ENABLE(CONTEXT_MENUS)
static bool isContextClick(const PlatformMouseEvent& event)
{
- if (event.button() == WebCore::RightButton)
- return true;
-
-#if PLATFORM(MAC)
- // FIXME: this really should be about OSX-style UI, not about the Mac port
- if (event.button() == WebCore::LeftButton && event.ctrlKey())
- return true;
+#if PLATFORM(COCOA)
+ return WebEventFactory::shouldBeHandledAsContextClick(event);
+#else
+ return event.button() == WebCore::RightButton;
#endif
-
- return false;
}
static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, WebPage* page)
@@ -1622,13 +2187,23 @@ static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent,
Frame* frame = &page->corePage()->mainFrame();
if (result.innerNonSharedNode())
frame = result.innerNonSharedNode()->document().frame();
-
- bool handled = frame->eventHandler().sendContextMenuEvent(platformMouseEvent);
+
+ bool handled = page->corePage()->userInputBridge().handleContextMenuEvent(platformMouseEvent, frame);
if (handled)
page->contextMenu()->show();
return handled;
}
+
+void WebPage::contextMenuForKeyEvent()
+{
+ corePage()->contextMenuController().clearContextMenu();
+
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+ bool handled = frame.eventHandler().sendContextMenuEventForKey();
+ if (handled)
+ contextMenu()->show();
+}
#endif
static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page, bool onlyUpdateScrollbars)
@@ -1646,7 +2221,7 @@ static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page, boo
page->corePage()->contextMenuController().clearContextMenu();
#endif
- bool handled = frame.eventHandler().handleMousePressEvent(platformMouseEvent);
+ bool handled = page->corePage()->userInputBridge().handleMousePressEvent(platformMouseEvent);
#if ENABLE(CONTEXT_MENUS)
if (isContextClick(platformMouseEvent))
handled = handleContextMenuEvent(platformMouseEvent, page);
@@ -1654,12 +2229,18 @@ static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page, boo
return handled;
}
case PlatformEvent::MouseReleased:
- return frame.eventHandler().handleMouseReleaseEvent(platformMouseEvent);
+ return page->corePage()->userInputBridge().handleMouseReleaseEvent(platformMouseEvent);
case PlatformEvent::MouseMoved:
if (onlyUpdateScrollbars)
- return frame.eventHandler().passMouseMovedEventToScrollbars(platformMouseEvent);
- return frame.eventHandler().mouseMoved(platformMouseEvent);
+ return page->corePage()->userInputBridge().handleMouseMoveOnScrollbarEvent(platformMouseEvent);
+ return page->corePage()->userInputBridge().handleMouseMoveEvent(platformMouseEvent);
+
+ case PlatformEvent::MouseForceChanged:
+ case PlatformEvent::MouseForceDown:
+ case PlatformEvent::MouseForceUp:
+ return page->corePage()->userInputBridge().handleMouseForceEvent(platformMouseEvent);
+
default:
ASSERT_NOT_REACHED();
return false;
@@ -1668,21 +2249,28 @@ static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page, boo
void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
{
+ SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
+
+ m_userActivityHysteresis.impulse();
+
+ bool shouldHandleEvent = true;
+
#if ENABLE(CONTEXT_MENUS)
// Don't try to handle any pending mouse events if a context menu is showing.
- if (m_isShowingContextMenu) {
+ if (m_isShowingContextMenu)
+ shouldHandleEvent = false;
+#endif
+#if ENABLE(DRAG_SUPPORT)
+ if (m_isStartingDrag)
+ shouldHandleEvent = false;
+#endif
+
+ if (!shouldHandleEvent) {
send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
return;
}
-#endif
+
bool handled = false;
- if (m_pageOverlays.size()) {
- // Let the page overlay handle the event.
- PageOverlayList::reverse_iterator end = m_pageOverlays.rend();
- for (PageOverlayList::reverse_iterator it = m_pageOverlays.rbegin(); it != end; ++it)
- if ((handled = (*it)->mouseEvent(mouseEvent)))
- break;
- }
#if !PLATFORM(IOS)
if (!handled && m_headerBanner)
@@ -1691,7 +2279,7 @@ void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
handled = m_footerBanner->mouseEvent(mouseEvent);
#endif // !PLATFORM(IOS)
- if (!handled && canHandleUserEvents()) {
+ if (!handled) {
CurrentEvent currentEvent(mouseEvent);
// We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
@@ -1706,36 +2294,6 @@ void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
}
-void WebPage::mouseEventSyncForTesting(const WebMouseEvent& mouseEvent, bool& handled)
-{
- handled = false;
-
- if (m_pageOverlays.size()) {
- PageOverlayList::reverse_iterator end = m_pageOverlays.rend();
- for (PageOverlayList::reverse_iterator it = m_pageOverlays.rbegin(); it != end; ++it)
- if ((handled = (*it)->mouseEvent(mouseEvent)))
- break;
- }
-#if !PLATFORM(IOS)
- if (!handled && m_headerBanner)
- handled = m_headerBanner->mouseEvent(mouseEvent);
- if (!handled && m_footerBanner)
- handled = m_footerBanner->mouseEvent(mouseEvent);
-#endif // !PLATFORM(IOS)
-
- if (!handled) {
- CurrentEvent currentEvent(mouseEvent);
-
- // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
- // button is currently pressed. It is possible that neither of those things will be true since on
- // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one
- // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
- // efficient scrollbars-only version of the event.
- bool onlyUpdateScrollbars = !(m_page->focusController().isActive() || (mouseEvent.button() != WebMouseEvent::NoButton));
- handled = handleMouseEvent(mouseEvent, this, onlyUpdateScrollbars);
- }
-}
-
static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
{
Frame& frame = page->mainFrame();
@@ -1743,26 +2301,18 @@ static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
return false;
PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
- return frame.eventHandler().handleWheelEvent(platformWheelEvent);
+ return page->userInputBridge().handleWheelEvent(platformWheelEvent);
}
void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
{
- bool handled = false;
+ m_userActivityHysteresis.impulse();
- if (canHandleUserEvents()) {
- CurrentEvent currentEvent(wheelEvent);
-
- handled = handleWheelEvent(wheelEvent, m_page.get());
- }
- send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
-}
-
-void WebPage::wheelEventSyncForTesting(const WebWheelEvent& wheelEvent, bool& handled)
-{
CurrentEvent currentEvent(wheelEvent);
- handled = handleWheelEvent(wheelEvent, m_page.get());
+ bool handled = handleWheelEvent(wheelEvent, m_page.get());
+
+ send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
}
static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
@@ -1771,61 +2321,24 @@ static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
return false;
if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
- return page->focusController().focusedOrMainFrame().eventHandler().handleAccessKey(platform(keyboardEvent));
- return page->focusController().focusedOrMainFrame().eventHandler().keyEvent(platform(keyboardEvent));
+ return page->userInputBridge().handleAccessKeyEvent(platform(keyboardEvent));
+ return page->userInputBridge().handleKeyEvent(platform(keyboardEvent));
}
void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
{
- bool handled = false;
+ SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
- if (canHandleUserEvents()) {
- CurrentEvent currentEvent(keyboardEvent);
+ m_userActivityHysteresis.impulse();
- handled = handleKeyEvent(keyboardEvent, m_page.get());
- // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
- if (!handled)
- handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
- }
- send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
-}
-
-void WebPage::keyEventSyncForTesting(const WebKeyboardEvent& keyboardEvent, bool& handled)
-{
CurrentEvent currentEvent(keyboardEvent);
- Frame& frame = m_page->focusController().focusedOrMainFrame();
- frame.document()->updateStyleIfNeeded();
-
- handled = handleKeyEvent(keyboardEvent, m_page.get());
+ bool handled = handleKeyEvent(keyboardEvent, m_page.get());
+ // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
if (!handled)
handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
-}
-
-WKTypeRef WebPage::pageOverlayCopyAccessibilityAttributeValue(WKStringRef attribute, WKTypeRef parameter)
-{
- if (!m_pageOverlays.size())
- return 0;
- PageOverlayList::reverse_iterator end = m_pageOverlays.rend();
- for (PageOverlayList::reverse_iterator it = m_pageOverlays.rbegin(); it != end; ++it) {
- WKTypeRef value = (*it)->copyAccessibilityAttributeValue(attribute, parameter);
- if (value)
- return value;
- }
- return 0;
-}
-WKArrayRef WebPage::pageOverlayCopyAccessibilityAttributesNames(bool parameterizedNames)
-{
- if (!m_pageOverlays.size())
- return 0;
- PageOverlayList::reverse_iterator end = m_pageOverlays.rend();
- for (PageOverlayList::reverse_iterator it = m_pageOverlays.rbegin(); it != end; ++it) {
- WKArrayRef value = (*it)->copyAccessibilityAttributeNames(parameterizedNames);
- if (value)
- return value;
- }
- return 0;
+ send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
}
void WebPage::validateCommand(const String& commandName, uint64_t callbackID)
@@ -1844,39 +2357,23 @@ void WebPage::validateCommand(const String& commandName, uint64_t callbackID)
send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
}
-void WebPage::executeEditCommand(const String& commandName)
+void WebPage::executeEditCommand(const String& commandName, const String& argument)
{
- executeEditingCommand(commandName, String());
+ executeEditingCommand(commandName, argument);
}
-uint64_t WebPage::restoreSession(const SessionState& sessionState)
+void WebPage::restoreSessionInternal(const Vector<BackForwardListItemState>& itemStates, WasRestoredByAPIRequest restoredByAPIRequest)
{
- const BackForwardListItemVector& list = sessionState.list();
- size_t size = list.size();
- uint64_t currentItemID = 0;
- for (size_t i = 0; i < size; ++i) {
- WebBackForwardListItem* webItem = list[i].get();
- DecoderAdapter decoder(webItem->backForwardData().data(), webItem->backForwardData().size());
-
- RefPtr<HistoryItem> item = HistoryItem::decodeBackForwardTree(webItem->url(), webItem->title(), webItem->originalURL(), decoder);
- if (!item) {
- LOG_ERROR("Failed to decode a HistoryItem from session state data.");
- return 0;
- }
-
- if (i == sessionState.currentIndex())
- currentItemID = webItem->itemID();
-
- WebBackForwardListProxy::addItemFromUIProcess(list[i]->itemID(), item.release());
- }
- ASSERT(currentItemID);
- return currentItemID;
+ for (const auto& itemState : itemStates) {
+ auto historyItem = toHistoryItem(itemState.pageState);
+ historyItem->setWasRestoredFromSession(restoredByAPIRequest == WasRestoredByAPIRequest::Yes);
+ static_cast<WebBackForwardListProxy*>(corePage()->backForward().client())->addItemFromUIProcess(itemState.identifier, WTFMove(historyItem), m_pageID);
+ }
}
-void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState)
+void WebPage::restoreSession(const Vector<BackForwardListItemState>& itemStates)
{
- if (uint64_t currentItemID = restoreSession(sessionState))
- goToBackForwardItem(currentItemID);
+ restoreSessionInternal(itemStates, WasRestoredByAPIRequest::Yes);
}
#if ENABLE(TOUCH_EVENTS)
@@ -1887,34 +2384,62 @@ static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
return page->mainFrame().eventHandler().handleTouchEvent(platform(touchEvent));
}
+#endif
+
+#if ENABLE(IOS_TOUCH_EVENTS)
+void WebPage::dispatchTouchEvent(const WebTouchEvent& touchEvent, bool& handled)
+{
+ SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
+
+ m_lastInteractionLocation = touchEvent.position();
+ CurrentEvent currentEvent(touchEvent);
+ handled = handleTouchEvent(touchEvent, m_page.get());
+}
+
+void WebPage::touchEventSync(const WebTouchEvent& touchEvent, bool& handled)
+{
+ EventDispatcher::TouchEventQueue queuedEvents;
+ WebProcess::singleton().eventDispatcher().getQueuedTouchEventsForPage(*this, queuedEvents);
+ dispatchAsynchronousTouchEvents(queuedEvents);
+ dispatchTouchEvent(touchEvent, handled);
+}
+#elif ENABLE(TOUCH_EVENTS)
void WebPage::touchEvent(const WebTouchEvent& touchEvent)
{
- bool handled = false;
+ CurrentEvent currentEvent(touchEvent);
- if (canHandleUserEvents()) {
- CurrentEvent currentEvent(touchEvent);
+ bool handled = handleTouchEvent(touchEvent, m_page.get());
- handled = handleTouchEvent(touchEvent, m_page.get());
- }
send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
}
+#endif
-void WebPage::touchEventSyncForTesting(const WebTouchEvent& touchEvent, bool& handled)
+#if ENABLE(MAC_GESTURE_EVENTS)
+static bool handleGestureEvent(const WebGestureEvent& event, Page* page)
{
- CurrentEvent currentEvent(touchEvent);
- handled = handleTouchEvent(touchEvent, m_page.get());
+ if (!page->mainFrame().view())
+ return false;
+
+ return page->mainFrame().eventHandler().handleGestureEvent(platform(event));
+}
+
+void WebPage::gestureEvent(const WebGestureEvent& gestureEvent)
+{
+ CurrentEvent currentEvent(gestureEvent);
+ bool handled = handleGestureEvent(gestureEvent, m_page.get());
+ send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled));
}
#endif
bool WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
{
- return page->focusController().focusedOrMainFrame().eventHandler().scrollRecursively(direction, granularity);
+ return page->userInputBridge().scrollRecursively(direction, granularity);
}
bool WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
{
- return page->focusController().focusedOrMainFrame().eventHandler().logicalScrollRecursively(direction, granularity);
+ return page->userInputBridge().logicalScrollRecursively(direction, granularity);
}
bool WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
@@ -1925,21 +2450,39 @@ bool WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
void WebPage::centerSelectionInVisibleArea()
{
Frame& frame = m_page->focusController().focusedOrMainFrame();
- frame.selection().revealSelection(ScrollAlignment::alignCenterAlways);
+ frame.selection().revealSelection(SelectionRevealMode::Reveal, ScrollAlignment::alignCenterAlways);
m_findController.showFindIndicatorInSelection();
}
-void WebPage::setActive(bool isActive)
+bool WebPage::isControlledByAutomation() const
+{
+ return m_page->isControlledByAutomation();
+}
+
+void WebPage::setControlledByAutomation(bool controlled)
+{
+ m_page->setControlledByAutomation(controlled);
+}
+
+void WebPage::insertNewlineInQuotedContent()
{
- m_page->focusController().setActive(isActive);
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+ if (frame.selection().isNone())
+ return;
+ frame.editor().insertParagraphSeparatorInQuotedContent();
}
-void WebPage::setViewIsVisible(bool isVisible)
+#if ENABLE(REMOTE_INSPECTOR)
+void WebPage::setAllowsRemoteInspection(bool allow)
{
- corePage()->focusController().setContentIsVisible(isVisible);
+ m_page->setRemoteInspectionAllowed(allow);
+}
- m_page->setIsVisible(m_viewState & ViewState::IsVisible, false);
+void WebPage::setRemoteInspectionNameOverride(const String& name)
+{
+ m_page->setRemoteInspectionNameOverride(name);
}
+#endif
void WebPage::setDrawsBackground(bool drawsBackground)
{
@@ -1957,21 +2500,26 @@ void WebPage::setDrawsBackground(bool drawsBackground)
m_drawingArea->setNeedsDisplay();
}
-void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground)
+#if HAVE(COREANIMATION_FENCES)
+void WebPage::setTopContentInsetFenced(float contentInset, IPC::Attachment fencePort)
{
- if (m_drawsTransparentBackground == drawsTransparentBackground)
- return;
+ m_drawingArea->addFence(MachSendRight::create(fencePort.port()));
- m_drawsTransparentBackground = drawsTransparentBackground;
+ setTopContentInset(contentInset);
- Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white;
- for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree().traverseNext()) {
- if (FrameView* view = coreFrame->view())
- view->setBaseBackgroundColor(backgroundColor);
- }
+ mach_port_deallocate(mach_task_self(), fencePort.port());
+}
+#endif
- m_drawingArea->pageBackgroundTransparencyChanged();
- m_drawingArea->setNeedsDisplay();
+void WebPage::setTopContentInset(float contentInset)
+{
+ if (contentInset == m_page->topContentInset())
+ return;
+
+ m_page->setTopContentInset(contentInset);
+
+ for (auto* pluginView : m_pluginViews)
+ pluginView->topContentInsetDidChange();
}
void WebPage::viewWillStartLiveResize()
@@ -1996,41 +2544,27 @@ void WebPage::viewWillEndLiveResize()
view->willEndLiveResize();
}
-void WebPage::setFocused(bool isFocused)
-{
- m_page->focusController().setFocused(isFocused);
-}
-
-void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
+void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event, uint64_t callbackID)
{
if (!m_page)
return;
+ SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
+
Frame& frame = m_page->focusController().focusedOrMainFrame();
frame.document()->setFocusedElement(0);
if (isKeyboardEventValid && event.type() == WebEvent::KeyDown) {
PlatformKeyboardEvent platformEvent(platform(event));
platformEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown);
- m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, KeyboardEvent::create(platformEvent, frame.document()->defaultView()).get());
- return;
- }
-
- m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0);
-}
+ m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, &KeyboardEvent::create(platformEvent, frame.document()->defaultView()).get());
-void WebPage::setWindowResizerSize(const IntSize& windowResizerSize)
-{
- if (m_windowResizerSize == windowResizerSize)
+ send(Messages::WebPageProxy::VoidCallback(callbackID));
return;
-
- m_windowResizerSize = windowResizerSize;
-
- for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree().traverseNext()) {
- FrameView* view = coreFrame->view();
- if (view)
- view->windowResizerRectChanged();
}
+
+ m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, nullptr);
+ send(Messages::WebPageProxy::VoidCallback(callbackID));
}
void WebPage::setCanStartMediaTimerFired()
@@ -2039,32 +2573,17 @@ void WebPage::setCanStartMediaTimerFired()
m_page->setCanStartMedia(true);
}
-#if !PLATFORM(MAC) || PLATFORM(IOS)
-void WebPage::didUpdateViewStateTimerFired()
-{
- send(Messages::WebPageProxy::DidUpdateViewState());
-}
-#endif
-
-inline bool WebPage::canHandleUserEvents() const
+void WebPage::updateIsInWindow(bool isInitialState)
{
-#if USE(TILED_BACKING_STORE)
- // Should apply only if the area was frozen by didStartPageTransition().
- return !m_drawingArea->layerTreeStateIsFrozen();
-#endif
- return true;
-}
+ bool isInWindow = m_activityState & WebCore::ActivityState::IsInWindow;
-void WebPage::setIsInWindow(bool isInWindow)
-{
- bool pageWasInWindow = m_page->isInWindow();
-
if (!isInWindow) {
m_setCanStartMediaTimer.stop();
m_page->setCanStartMedia(false);
- if (pageWasInWindow)
- WebProcess::shared().pageWillLeaveWindow(m_pageID);
+ // The WebProcess does not yet know about this page; no need to tell it we're leaving the window.
+ if (!isInitialState)
+ WebProcess::singleton().pageWillLeaveWindow(m_pageID);
} else {
// Defer the call to Page::setCanStartMedia() since it ends up sending a synchronous message to the UI process
// in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing
@@ -2072,53 +2591,34 @@ void WebPage::setIsInWindow(bool isInWindow)
if (m_mayStartMediaWhenInWindow)
m_setCanStartMediaTimer.startOneShot(0);
- if (!pageWasInWindow)
- WebProcess::shared().pageDidEnterWindow(m_pageID);
+ WebProcess::singleton().pageDidEnterWindow(m_pageID);
}
- m_page->setIsInWindow(isInWindow);
-
if (isInWindow)
layoutIfNeeded();
}
-void WebPage::setViewState(ViewState::Flags viewState, bool wantsDidUpdateViewState)
+void WebPage::setActivityState(ActivityState::Flags activityState, bool wantsDidUpdateActivityState, const Vector<uint64_t>& callbackIDs)
{
- setViewStateInternal(viewState, false);
+ ActivityState::Flags changed = m_activityState ^ activityState;
+ m_activityState = activityState;
- if (wantsDidUpdateViewState)
- m_sendDidUpdateViewStateTimer.startOneShot(0);
-}
+ if (changed)
+ updateThrottleState();
-void WebPage::setViewStateInternal(ViewState::Flags viewState, bool isInitialState)
-{
- ViewState::Flags changed = m_viewState ^ viewState;
- m_viewState = viewState;
-
- m_drawingArea->viewStateDidChange(changed);
+ m_page->setActivityState(activityState);
+ for (auto* pluginView : m_pluginViews)
+ pluginView->activityStateDidChange(changed);
- // We want to make sure to update the active state while hidden, so if the view is hidden then update the active state
- // early (in case it becomes visible), and if the view was visible then update active state later (in case it hides).
- if (changed & ViewState::IsFocused)
- setFocused(viewState & ViewState::IsFocused);
- if (changed & ViewState::WindowIsActive && !(m_viewState & ViewState::IsVisible))
- setActive(viewState & ViewState::WindowIsActive);
- if (changed & ViewState::IsVisible)
- setViewIsVisible(viewState & ViewState::IsVisible);
- if (changed & ViewState::WindowIsActive && m_viewState & ViewState::IsVisible)
- setActive(viewState & ViewState::WindowIsActive);
- if (changed & ViewState::IsInWindow)
- setIsInWindow(viewState & ViewState::IsInWindow);
- if (changed & ViewState::IsVisuallyIdle)
- setIsVisuallyIdle(viewState & ViewState::IsVisuallyIdle);
+ m_drawingArea->activityStateDidChange(changed, wantsDidUpdateActivityState, callbackIDs);
- for (auto* pluginView : m_pluginViews)
- pluginView->viewStateDidChange(changed);
+ if (changed & ActivityState::IsInWindow)
+ updateIsInWindow();
}
-void WebPage::setLayerHostingMode(unsigned layerHostingMode)
+void WebPage::setLayerHostingMode(LayerHostingMode layerHostingMode)
{
- m_layerHostingMode = static_cast<LayerHostingMode>(layerHostingMode);
+ m_layerHostingMode = layerHostingMode;
m_drawingArea->setLayerHostingMode(m_layerHostingMode);
@@ -2126,36 +2626,47 @@ void WebPage::setLayerHostingMode(unsigned layerHostingMode)
pluginView->setLayerHostingMode(m_layerHostingMode);
}
-uint64_t WebPage::sessionID() const
+void WebPage::setSessionID(SessionID sessionID)
{
- if (m_sessionID)
- return m_sessionID;
-
- return m_page->settings().privateBrowsingEnabled() ? SessionTracker::legacyPrivateSessionID : SessionTracker::defaultSessionID;
+ if (sessionID.isEphemeral())
+ WebProcess::singleton().ensurePrivateBrowsingSession(sessionID);
+ m_page->setSessionID(sessionID);
}
-void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
+void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, DownloadID downloadID)
{
- WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
if (!frame)
return;
- frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
+ frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), navigationID, downloadID);
}
void WebPage::didStartPageTransition()
{
m_drawingArea->setLayerTreeStateIsFrozen(true);
+
+#if PLATFORM(MAC)
+ bool hasPreviouslyFocusedDueToUserInteraction = m_hasEverFocusedElementDueToUserInteractionSincePageTransition;
+#endif
+ m_hasEverFocusedElementDueToUserInteractionSincePageTransition = false;
+ m_isAssistingNodeDueToUserInteraction = false;
+ m_lastEditorStateWasContentEditable = EditorStateIsContentEditable::Unset;
+#if PLATFORM(MAC)
+ if (hasPreviouslyFocusedDueToUserInteraction)
+ send(Messages::WebPageProxy::SetHasHadSelectionChangesFromUserInteraction(m_hasEverFocusedElementDueToUserInteractionSincePageTransition));
+ if (m_needsHiddenContentEditableQuirk) {
+ m_needsHiddenContentEditableQuirk = false;
+ send(Messages::WebPageProxy::SetNeedsHiddenContentEditableQuirk(m_needsHiddenContentEditableQuirk));
+ }
+ if (m_needsPlainTextQuirk) {
+ m_needsPlainTextQuirk = false;
+ send(Messages::WebPageProxy::SetNeedsPlainTextQuirk(m_needsPlainTextQuirk));
+ }
+#endif
}
void WebPage::didCompletePageTransition()
{
-#if USE(TILED_BACKING_STORE)
- if (m_mainFrame->coreFrame()->view()->delegatesScrolling())
- // Wait until the UI process sent us the visible rect it wants rendered.
- send(Messages::WebPageProxy::PageTransitionViewportReady());
- else
-#endif
-
m_drawingArea->setLayerTreeStateIsFrozen(false);
}
@@ -2164,19 +2675,29 @@ void WebPage::show()
send(Messages::WebPageProxy::ShowPage());
}
-void WebPage::setUserAgent(const String& userAgent)
+String WebPage::userAgent(const URL& webCoreURL) const
{
- m_userAgent = userAgent;
+ return userAgent(nullptr, webCoreURL);
}
-String WebPage::userAgent(const URL& url) const
+String WebPage::userAgent(WebFrame* frame, const URL& webcoreURL) const
{
- String userAgent = platformUserAgent(url);
+ if (frame && m_loaderClient.client().userAgentForURL) {
+ API::String* apiString = m_loaderClient.userAgentForURL(frame, API::URL::create(webcoreURL).ptr());
+ if (apiString)
+ return apiString->string();
+ }
+
+ String userAgent = platformUserAgent(webcoreURL);
if (!userAgent.isEmpty())
return userAgent;
-
return m_userAgent;
}
+
+void WebPage::setUserAgent(const String& userAgent)
+{
+ m_userAgent = userAgent;
+}
void WebPage::suspendActiveDOMObjectsAndAnimations()
{
@@ -2188,38 +2709,39 @@ void WebPage::resumeActiveDOMObjectsAndAnimations()
m_page->resumeActiveDOMObjectsAndAnimations();
}
-IntPoint WebPage::screenToWindow(const IntPoint& point)
+IntPoint WebPage::screenToRootView(const IntPoint& point)
{
IntPoint windowPoint;
- sendSync(Messages::WebPageProxy::ScreenToWindow(point), Messages::WebPageProxy::ScreenToWindow::Reply(windowPoint));
+ sendSync(Messages::WebPageProxy::ScreenToRootView(point), Messages::WebPageProxy::ScreenToRootView::Reply(windowPoint));
return windowPoint;
}
-IntRect WebPage::windowToScreen(const IntRect& rect)
+IntRect WebPage::rootViewToScreen(const IntRect& rect)
{
IntRect screenRect;
- sendSync(Messages::WebPageProxy::WindowToScreen(rect), Messages::WebPageProxy::WindowToScreen::Reply(screenRect));
+ sendSync(Messages::WebPageProxy::RootViewToScreen(rect), Messages::WebPageProxy::RootViewToScreen::Reply(screenRect));
return screenRect;
}
-
-IntRect WebPage::windowResizerRect() const
+
+#if PLATFORM(IOS)
+IntPoint WebPage::accessibilityScreenToRootView(const IntPoint& point)
{
- if (m_windowResizerSize.isEmpty())
- return IntRect();
-
- IntSize frameViewSize;
- if (Frame* coreFrame = m_mainFrame->coreFrame()) {
- if (FrameView* view = coreFrame->view())
- frameViewSize = view->size();
- }
+ IntPoint windowPoint;
+ sendSync(Messages::WebPageProxy::AccessibilityScreenToRootView(point), Messages::WebPageProxy::AccessibilityScreenToRootView::Reply(windowPoint));
+ return windowPoint;
+}
- return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(),
- m_windowResizerSize.width(), m_windowResizerSize.height());
+IntRect WebPage::rootViewToAccessibilityScreen(const IntRect& rect)
+{
+ IntRect screenRect;
+ sendSync(Messages::WebPageProxy::RootViewToAccessibilityScreen(rect), Messages::WebPageProxy::RootViewToAccessibilityScreen::Reply(screenRect));
+ return screenRect;
}
+#endif
KeyboardUIMode WebPage::keyboardUIMode()
{
- bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled();
+ bool fullKeyboardAccessEnabled = WebProcess::singleton().fullKeyboardAccessEnabled();
return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
}
@@ -2228,18 +2750,20 @@ void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID
// NOTE: We need to be careful when running scripts that the objects we depend on don't
// disappear during script execution.
- // Retain the SerializedScriptValue at this level so it (and the internal data) lives
- // long enough for the DataReference to be encoded by the sent message.
RefPtr<SerializedScriptValue> serializedResultValue;
- IPC::DataReference dataReference;
-
- JSLockHolder lock(JSDOMWindow::commonVM());
- if (JSValue resultValue = m_mainFrame->coreFrame()->script().executeScript(script, true).jsValue()) {
- if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), toRef(m_mainFrame->coreFrame()->script().globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0)))
- dataReference = serializedResultValue->data();
+ JSLockHolder lock(commonVM());
+ bool hadException = true;
+ ExceptionDetails details;
+ if (JSValue resultValue = m_mainFrame->coreFrame()->script().executeScript(script, true, &details)) {
+ hadException = false;
+ serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(),
+ toRef(m_mainFrame->coreFrame()->script().globalObject(mainThreadNormalWorld())->globalExec(), resultValue), nullptr);
}
- send(Messages::WebPageProxy::ScriptValueCallback(dataReference, callbackID));
+ IPC::DataReference dataReference;
+ if (serializedResultValue)
+ dataReference = serializedResultValue->data();
+ send(Messages::WebPageProxy::ScriptValueCallback(dataReference, hadException, details, callbackID));
}
void WebPage::getContentsAsString(uint64_t callbackID)
@@ -2249,17 +2773,14 @@ void WebPage::getContentsAsString(uint64_t callbackID)
}
#if ENABLE(MHTML)
-void WebPage::getContentsAsMHTMLData(uint64_t callbackID, bool useBinaryEncoding)
+void WebPage::getContentsAsMHTMLData(uint64_t callbackID)
{
- IPC::DataReference dataReference;
-
- RefPtr<SharedBuffer> buffer = useBinaryEncoding
- ? MHTMLArchive::generateMHTMLDataUsingBinaryEncoding(m_page.get())
- : MHTMLArchive::generateMHTMLData(m_page.get());
+ RefPtr<SharedBuffer> buffer = MHTMLArchive::generateMHTMLData(m_page.get());
+ // FIXME: Use SharedBufferDataReference.
+ IPC::DataReference dataReference;
if (buffer)
dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
-
send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
}
#endif
@@ -2282,35 +2803,33 @@ static Frame* frameWithSelection(Page* page)
void WebPage::getSelectionAsWebArchiveData(uint64_t callbackID)
{
- IPC::DataReference dataReference;
-
-#if PLATFORM(MAC)
- RefPtr<LegacyWebArchive> archive;
+#if PLATFORM(COCOA)
RetainPtr<CFDataRef> data;
+ if (Frame* frame = frameWithSelection(m_page.get()))
+ data = LegacyWebArchive::createFromSelection(frame)->rawDataRepresentation();
+#endif
- Frame* frame = frameWithSelection(m_page.get());
- if (frame) {
- archive = LegacyWebArchive::createFromSelection(frame);
- data = archive->rawDataRepresentation();
+ IPC::DataReference dataReference;
+#if PLATFORM(COCOA)
+ if (data)
dataReference = IPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
- }
#endif
-
send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
}
void WebPage::getSelectionOrContentsAsString(uint64_t callbackID)
{
- String resultString = m_mainFrame->selectionAsString();
+ WebFrame* focusedOrMainFrame = WebFrame::fromCoreFrame(m_page->focusController().focusedOrMainFrame());
+ String resultString = focusedOrMainFrame->selectionAsString();
if (resultString.isEmpty())
- resultString = m_mainFrame->contentsAsString();
+ resultString = focusedOrMainFrame->contentsAsString();
send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
}
void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID)
{
String resultString;
- if (WebFrame* frame = WebProcess::shared().webFrame(frameID))
+ if (WebFrame* frame = WebProcess::singleton().webFrame(frameID))
resultString = frame->source();
send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
@@ -2318,74 +2837,70 @@ void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID)
void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
{
- IPC::DataReference dataReference;
-
- RefPtr<ResourceBuffer> buffer;
- RefPtr<SharedBuffer> pdfResource;
- if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
- if (PluginView* pluginView = pluginViewForFrame(frame->coreFrame())) {
- if ((pdfResource = pluginView->liveResourceData()))
- dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(pdfResource->data()), pdfResource->size());
- }
-
- if (dataReference.isEmpty()) {
- if (DocumentLoader* loader = frame->coreFrame()->loader().documentLoader()) {
- if ((buffer = loader->mainResourceData()))
- dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
- }
+ RefPtr<SharedBuffer> buffer;
+ if (WebFrame* frame = WebProcess::singleton().webFrame(frameID)) {
+ if (PluginView* pluginView = pluginViewForFrame(frame->coreFrame()))
+ buffer = pluginView->liveResourceData();
+ if (!buffer) {
+ if (DocumentLoader* loader = frame->coreFrame()->loader().documentLoader())
+ buffer = loader->mainResourceData();
}
}
+ // FIXME: Use SharedBufferDataReference.
+ IPC::DataReference dataReference;
+ if (buffer)
+ dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
}
-static PassRefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const URL& resourceURL)
+static RefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const URL& resourceURL)
{
DocumentLoader* loader = frame->loader().documentLoader();
if (!loader)
- return 0;
+ return nullptr;
RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL);
if (!subresource)
- return 0;
+ return nullptr;
- return subresource->data();
+ return &subresource->data();
}
void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURLString, uint64_t callbackID)
{
- IPC::DataReference dataReference;
- URL resourceURL(URL(), resourceURLString);
-
RefPtr<SharedBuffer> buffer;
- if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
+ if (WebFrame* frame = WebProcess::singleton().webFrame(frameID)) {
+ URL resourceURL(URL(), resourceURLString);
buffer = resourceDataForFrame(frame->coreFrame(), resourceURL);
if (!buffer) {
// Try to get the resource data from the cache.
buffer = cachedResponseDataForURL(resourceURL);
}
-
- if (buffer)
- dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
}
+ // FIXME: Use SharedBufferDataReference.
+ IPC::DataReference dataReference;
+ if (buffer)
+ dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
}
void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID)
{
- IPC::DataReference dataReference;
-
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
RetainPtr<CFDataRef> data;
- if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
- if ((data = frame->webArchiveData(0, 0)))
- dataReference = IPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
- }
+ if (WebFrame* frame = WebProcess::singleton().webFrame(frameID))
+ data = frame->webArchiveData(nullptr, nullptr);
#else
UNUSED_PARAM(frameID);
#endif
+ IPC::DataReference dataReference;
+#if PLATFORM(COCOA)
+ if (data)
+ dataReference = IPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
+#endif
send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
}
@@ -2420,7 +2935,7 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
m_scrollingPerformanceLoggingEnabled = store.getBoolValueForKey(WebPreferencesKey::scrollingPerformanceLoggingEnabledKey());
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
m_pdfPluginEnabled = store.getBoolValueForKey(WebPreferencesKey::pdfPluginEnabledKey());
#endif
@@ -2428,7 +2943,7 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
// but we currently don't match the naming of WebCore exactly so we are
// handrolling the boolean and integer preferences until that is fixed.
-#define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings.set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()));
+#define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) settings.set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()));
FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS)
@@ -2445,17 +2960,18 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
settings.setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
settings.setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
settings.setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()));
- if (m_sessionID)
- settings.setPrivateBrowsingEnabled(SessionTracker::isEphemeralID(m_sessionID));
- else
- settings.setPrivateBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()));
+ if (store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && !usesEphemeralSession())
+ setSessionID(SessionID::legacyPrivateSessionID());
+ else if (!store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && sessionID() == SessionID::legacyPrivateSessionID())
+ setSessionID(SessionID::defaultSessionID());
settings.setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey()));
- settings.setJavaScriptExperimentsEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptExperimentsEnabledKey()));
+ settings.setJavaScriptRuntimeFlags(RuntimeFlags(store.getUInt32ValueForKey(WebPreferencesKey::javaScriptRuntimeFlagsKey())));
settings.setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey()));
settings.setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey()));
settings.setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey()));
settings.setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey()));
settings.setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey()));
+ settings.setDOMTimersThrottlingEnabled(store.getBoolValueForKey(WebPreferencesKey::domTimersThrottlingEnabledKey()));
#if ENABLE(WEB_ARCHIVE)
settings.setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
#endif
@@ -2470,16 +2986,12 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
settings.setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey()));
settings.setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey()));
settings.setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey()));
+ settings.setNeedsStorageAccessFromFileURLsQuirk(store.getBoolValueForKey(WebPreferencesKey::needsStorageAccessFromFileURLsQuirkKey()));
- settings.setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey()));
- settings.setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey()));
- settings.setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey()));
- settings.setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey()));
- settings.setScreenFontSubstitutionEnabled(store.getBoolValueForKey(WebPreferencesKey::screenFontSubstitutionEnabledKey())
-#if PLATFORM(MAC)
- || WebProcess::shared().shouldForceScreenFontSubstitution()
-#endif
- );
+ settings.setMinimumFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumFontSizeKey()));
+ settings.setMinimumLogicalFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey()));
+ settings.setDefaultFontSize(store.getDoubleValueForKey(WebPreferencesKey::defaultFontSizeKey()));
+ settings.setDefaultFixedFontSize(store.getDoubleValueForKey(WebPreferencesKey::defaultFixedFontSizeKey()));
settings.setLayoutFallbackWidth(store.getUInt32ValueForKey(WebPreferencesKey::layoutFallbackWidthKey()));
settings.setDeviceWidth(store.getUInt32ValueForKey(WebPreferencesKey::deviceWidthKey()));
settings.setDeviceHeight(store.getUInt32ValueForKey(WebPreferencesKey::deviceHeightKey()));
@@ -2487,35 +2999,57 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
settings.setShowsToolTipOverTruncatedText(store.getBoolValueForKey(WebPreferencesKey::showsToolTipOverTruncatedTextKey()));
settings.setAcceleratedCompositingForOverflowScrollEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingForOverflowScrollEnabledKey()));
- settings.setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing());
- settings.setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing());
- settings.setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()) && LayerTreeHost::supportsAcceleratedCompositing());
+ settings.setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()));
+ settings.setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()));
+ settings.setDisplayListDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::displayListDrawingEnabledKey()));
+ settings.setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()));
settings.setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
settings.setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
settings.setShowTiledScrollingIndicator(store.getBoolValueForKey(WebPreferencesKey::tiledScrollingIndicatorVisibleKey()));
+ settings.setVisibleDebugOverlayRegions(store.getUInt32ValueForKey(WebPreferencesKey::visibleDebugOverlayRegionsKey()));
+ settings.setUseGiantTiles(store.getBoolValueForKey(WebPreferencesKey::useGiantTilesKey()));
+
settings.setAggressiveTileRetentionEnabled(store.getBoolValueForKey(WebPreferencesKey::aggressiveTileRetentionEnabledKey()));
- RuntimeEnabledFeatures::sharedFeatures().setCSSRegionsEnabled(store.getBoolValueForKey(WebPreferencesKey::cssRegionsEnabledKey()));
- RuntimeEnabledFeatures::sharedFeatures().setCSSCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::cssCompositingEnabledKey()));
- settings.setCSSGridLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::cssGridLayoutEnabledKey()));
- settings.setRegionBasedColumnsEnabled(store.getBoolValueForKey(WebPreferencesKey::regionBasedColumnsEnabledKey()));
+ settings.setTemporaryTileCohortRetentionEnabled(store.getBoolValueForKey(WebPreferencesKey::temporaryTileCohortRetentionEnabledKey()));
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ RuntimeEnabledFeatures::sharedFeatures().setAnimationTriggersEnabled(store.getBoolValueForKey(WebPreferencesKey::cssAnimationTriggersEnabledKey()));
+#endif
+#if ENABLE(WEB_ANIMATIONS)
+ RuntimeEnabledFeatures::sharedFeatures().setWebAnimationsEnabled(store.getBoolValueForKey(WebPreferencesKey::webAnimationsEnabledKey()));
+#endif
settings.setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey()));
- settings.setMultithreadedWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::multithreadedWebGLEnabledKey()));
settings.setForceSoftwareWebGLRendering(store.getBoolValueForKey(WebPreferencesKey::forceSoftwareWebGLRenderingKey()));
settings.setAccelerated2dCanvasEnabled(store.getBoolValueForKey(WebPreferencesKey::accelerated2dCanvasEnabledKey()));
- settings.setMediaPlaybackRequiresUserGesture(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackRequiresUserGestureKey()));
- settings.setMediaPlaybackAllowsInline(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackAllowsInlineKey()));
+ bool requiresUserGestureForMedia = store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForMediaPlaybackKey());
+ settings.setVideoPlaybackRequiresUserGesture(requiresUserGestureForMedia || store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForVideoPlaybackKey()));
+ settings.setAudioPlaybackRequiresUserGesture(requiresUserGestureForMedia || store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForAudioPlaybackKey()));
+ settings.setRequiresUserGestureToLoadVideo(store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureToLoadVideoKey()));
+ settings.setMainContentUserGestureOverrideEnabled(store.getBoolValueForKey(WebPreferencesKey::mainContentUserGestureOverrideEnabledKey()));
+ settings.setAllowsInlineMediaPlayback(store.getBoolValueForKey(WebPreferencesKey::allowsInlineMediaPlaybackKey()));
+ settings.setAllowsInlineMediaPlaybackAfterFullscreen(store.getBoolValueForKey(WebPreferencesKey::allowsInlineMediaPlaybackAfterFullscreenKey()));
+ settings.setInlineMediaPlaybackRequiresPlaysInlineAttribute(store.getBoolValueForKey(WebPreferencesKey::inlineMediaPlaybackRequiresPlaysInlineAttributeKey()));
+ settings.setInvisibleAutoplayNotPermitted(store.getBoolValueForKey(WebPreferencesKey::invisibleAutoplayNotPermittedKey()));
+ settings.setMediaDataLoadsAutomatically(store.getBoolValueForKey(WebPreferencesKey::mediaDataLoadsAutomaticallyKey()));
+#if ENABLE(ATTACHMENT_ELEMENT)
+ settings.setAttachmentElementEnabled(store.getBoolValueForKey(WebPreferencesKey::attachmentElementEnabledKey()));
+#endif
+ settings.setAllowsPictureInPictureMediaPlayback(store.getBoolValueForKey(WebPreferencesKey::allowsPictureInPictureMediaPlaybackKey()));
+ settings.setMediaControlsScaleWithPageZoom(store.getBoolValueForKey(WebPreferencesKey::mediaControlsScaleWithPageZoomKey()));
settings.setMockScrollbarsEnabled(store.getBoolValueForKey(WebPreferencesKey::mockScrollbarsEnabledKey()));
settings.setHyperlinkAuditingEnabled(store.getBoolValueForKey(WebPreferencesKey::hyperlinkAuditingEnabledKey()));
settings.setRequestAnimationFrameEnabled(store.getBoolValueForKey(WebPreferencesKey::requestAnimationFrameEnabledKey()));
#if ENABLE(SMOOTH_SCROLLING)
settings.setScrollAnimatorEnabled(store.getBoolValueForKey(WebPreferencesKey::scrollAnimatorEnabledKey()));
#endif
+ settings.setForceUpdateScrollbarsOnMainThreadForPerformanceTesting(store.getBoolValueForKey(WebPreferencesKey::forceUpdateScrollbarsOnMainThreadForPerformanceTestingKey()));
settings.setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
settings.setSpatialNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::spatialNavigationEnabledKey()));
-#if ENABLE(SQL_DATABASE)
- DatabaseManager::manager().setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
-#endif
+ settings.setHttpEquivEnabled(store.getBoolValueForKey(WebPreferencesKey::httpEquivEnabledKey()));
+
+ settings.setSelectionPaintingWithoutSelectionGapsEnabled(store.getBoolValueForKey(WebPreferencesKey::selectionPaintingWithoutSelectionGapsEnabledKey()));
+
+ DatabaseManager::singleton().setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
#if ENABLE(FULLSCREEN_API)
settings.setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey()));
@@ -2523,14 +3057,19 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
#if USE(AVFOUNDATION)
settings.setAVFoundationEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationEnabledKey()));
+ settings.setAVFoundationNSURLSessionEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationNSURLSessionEnabledKey()));
#endif
-#if PLATFORM(MAC)
+#if USE(GSTREAMER)
+ settings.setGStreamerEnabled(store.getBoolValueForKey(WebPreferencesKey::isGStreamerEnabledKey()));
+#endif
+
+#if PLATFORM(COCOA)
settings.setQTKitEnabled(store.getBoolValueForKey(WebPreferencesKey::isQTKitEnabledKey()));
#endif
-#if USE(PLUGIN_PROXY_FOR_VIDEO)
- settings->setVideoPluginProxyEnabled(store.getBoolValueForKey(WebPreferencesKey::isVideoPluginProxyEnabledKey()));
+#if PLATFORM(IOS) && HAVE(AVKIT)
+ settings.setAVKitEnabled(true);
#endif
#if ENABLE(WEB_AUDIO)
@@ -2538,10 +3077,25 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
#endif
#if ENABLE(MEDIA_STREAM)
- settings.setMediaStreamEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaStreamEnabledKey()));
+ RuntimeEnabledFeatures::sharedFeatures().setMediaStreamEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaStreamEnabledKey()));
+#endif
+
+#if ENABLE(WEB_RTC)
+ RuntimeEnabledFeatures::sharedFeatures().setPeerConnectionEnabled(store.getBoolValueForKey(WebPreferencesKey::peerConnectionEnabledKey()));
+#endif
+
+#if ENABLE(SERVICE_CONTROLS)
+ settings.setImageControlsEnabled(store.getBoolValueForKey(WebPreferencesKey::imageControlsEnabledKey()));
+#endif
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ settings.setAllowsAirPlayForMediaPlayback(store.getBoolValueForKey(WebPreferencesKey::allowsAirPlayForMediaPlaybackKey()));
+#endif
+
+#if ENABLE(RESOURCE_USAGE)
+ settings.setResourceUsageOverlayVisible(store.getBoolValueForKey(WebPreferencesKey::resourceUsageOverlayVisibleKey()));
#endif
- settings.setApplicationChromeMode(store.getBoolValueForKey(WebPreferencesKey::applicationChromeModeKey()));
settings.setSuppressesIncrementalRendering(store.getBoolValueForKey(WebPreferencesKey::suppressesIncrementalRenderingKey()));
settings.setIncrementalRenderingSuppressionTimeoutInSeconds(store.getDoubleValueForKey(WebPreferencesKey::incrementalRenderingSuppressionTimeoutKey()));
settings.setBackspaceKeyNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::backspaceKeyNavigationEnabledKey()));
@@ -2574,6 +3128,7 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
#if ENABLE(TEXT_AUTOSIZING)
settings.setTextAutosizingEnabled(store.getBoolValueForKey(WebPreferencesKey::textAutosizingEnabledKey()));
+ settings.setMinimumZoomFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumZoomFontSizeKey()));
#endif
settings.setLogsPageMessagesToSystemConsoleEnabled(store.getBoolValueForKey(WebPreferencesKey::logsPageMessagesToSystemConsoleEnabledKey()));
@@ -2583,16 +3138,18 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
settings.setSelectTrailingWhitespaceEnabled(store.getBoolValueForKey(WebPreferencesKey::selectTrailingWhitespaceEnabledKey()));
settings.setShowsURLsInToolTips(store.getBoolValueForKey(WebPreferencesKey::showsURLsInToolTipsEnabledKey()));
-#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
settings.setHiddenPageDOMTimerThrottlingEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageDOMTimerThrottlingEnabledKey()));
-#endif
-#if ENABLE(PAGE_VISIBILITY_API)
- settings.setHiddenPageCSSAnimationSuspensionEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageCSSAnimationSuspensionEnabledKey()));
-#endif
+ settings.setHiddenPageDOMTimerThrottlingAutoIncreases(store.getBoolValueForKey(WebPreferencesKey::hiddenPageDOMTimerThrottlingAutoIncreasesKey()));
+ settings.setHiddenPageCSSAnimationSuspensionEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageCSSAnimationSuspensionEnabledKey()));
settings.setLowPowerVideoAudioBufferSizeEnabled(store.getBoolValueForKey(WebPreferencesKey::lowPowerVideoAudioBufferSizeEnabledKey()));
settings.setSimpleLineLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::simpleLineLayoutEnabledKey()));
settings.setSimpleLineLayoutDebugBordersEnabled(store.getBoolValueForKey(WebPreferencesKey::simpleLineLayoutDebugBordersEnabledKey()));
+
+ settings.setNewBlockInsideInlineModelEnabled(store.getBoolValueForKey(WebPreferencesKey::newBlockInsideInlineModelEnabledKey()));
+ settings.setDeferredCSSParserEnabled(store.getBoolValueForKey(WebPreferencesKey::deferredCSSParserEnabledKey()));
+
+ settings.setSubpixelCSSOMElementMetricsEnabled(store.getBoolValueForKey(WebPreferencesKey::subpixelCSSOMElementMetricsEnabledKey()));
settings.setUseLegacyTextAlignPositionedElementBehavior(store.getBoolValueForKey(WebPreferencesKey::useLegacyTextAlignPositionedElementBehaviorKey()));
@@ -2600,29 +3157,229 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
settings.setMediaSourceEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaSourceEnabledKey()));
#endif
- if (store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey())) {
- if (m_processSuppressionDisabledByWebPreference.isActive())
- m_processSuppressionDisabledByWebPreference.endActivity();
- } else {
- if (!m_processSuppressionDisabledByWebPreference.isActive())
- m_processSuppressionDisabledByWebPreference.beginActivity();
+#if ENABLE(MEDIA_STREAM)
+ settings.setMockCaptureDevicesEnabled(store.getBoolValueForKey(WebPreferencesKey::mockCaptureDevicesEnabledKey()));
+ settings.setMediaCaptureRequiresSecureConnection(store.getBoolValueForKey(WebPreferencesKey::mediaCaptureRequiresSecureConnectionKey()));
+#endif
+
+ settings.setShouldConvertPositionStyleOnCopy(store.getBoolValueForKey(WebPreferencesKey::shouldConvertPositionStyleOnCopyKey()));
+
+ settings.setStandalone(store.getBoolValueForKey(WebPreferencesKey::standaloneKey()));
+ settings.setTelephoneNumberParsingEnabled(store.getBoolValueForKey(WebPreferencesKey::telephoneNumberParsingEnabledKey()));
+ settings.setAllowMultiElementImplicitSubmission(store.getBoolValueForKey(WebPreferencesKey::allowMultiElementImplicitSubmissionKey()));
+ settings.setAlwaysUseAcceleratedOverflowScroll(store.getBoolValueForKey(WebPreferencesKey::alwaysUseAcceleratedOverflowScrollKey()));
+
+ settings.setPasswordEchoEnabled(store.getBoolValueForKey(WebPreferencesKey::passwordEchoEnabledKey()));
+ settings.setPasswordEchoDurationInSeconds(store.getDoubleValueForKey(WebPreferencesKey::passwordEchoDurationKey()));
+
+ settings.setLayoutInterval(Seconds(store.getDoubleValueForKey(WebPreferencesKey::layoutIntervalKey())));
+ settings.setMaxParseDuration(store.getDoubleValueForKey(WebPreferencesKey::maxParseDurationKey()));
+
+ settings.setEnableInheritURIQueryComponent(store.getBoolValueForKey(WebPreferencesKey::enableInheritURIQueryComponentKey()));
+
+ settings.setShouldDispatchJavaScriptWindowOnErrorEvents(true);
+
+ auto userInterfaceDirectionPolicyCandidate = static_cast<WebCore::UserInterfaceDirectionPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::userInterfaceDirectionPolicyKey()));
+ if (userInterfaceDirectionPolicyCandidate == WebCore::UserInterfaceDirectionPolicy::Content || userInterfaceDirectionPolicyCandidate == WebCore::UserInterfaceDirectionPolicy::System)
+ settings.setUserInterfaceDirectionPolicy(userInterfaceDirectionPolicyCandidate);
+ TextDirection systemLayoutDirectionCandidate = static_cast<TextDirection>(store.getUInt32ValueForKey(WebPreferencesKey::systemLayoutDirectionKey()));
+ if (systemLayoutDirectionCandidate == WebCore::LTR || systemLayoutDirectionCandidate == WebCore::RTL)
+ settings.setSystemLayoutDirection(systemLayoutDirectionCandidate);
+
+#if ENABLE(APPLE_PAY)
+ settings.setApplePayEnabled(store.getBoolValueForKey(WebPreferencesKey::applePayEnabledKey()));
+ settings.setApplePayCapabilityDisclosureAllowed(store.getBoolValueForKey(WebPreferencesKey::applePayCapabilityDisclosureAllowedKey()));
+#endif
+
+#if PLATFORM(IOS)
+ settings.setUseImageDocumentForSubframePDF(true);
+#endif
+
+#if ENABLE(DATA_DETECTION)
+ settings.setDataDetectorTypes(static_cast<DataDetectorTypes>(store.getUInt32ValueForKey(WebPreferencesKey::dataDetectorTypesKey())));
+#endif
+#if ENABLE(GAMEPAD)
+ RuntimeEnabledFeatures::sharedFeatures().setGamepadsEnabled(store.getBoolValueForKey(WebPreferencesKey::gamepadsEnabledKey()));
+#endif
+
+#if ENABLE(SERVICE_CONTROLS)
+ settings.setServiceControlsEnabled(store.getBoolValueForKey(WebPreferencesKey::serviceControlsEnabledKey()));
+#endif
+
+#if ENABLE(FETCH_API)
+ RuntimeEnabledFeatures::sharedFeatures().setFetchAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::fetchAPIEnabledKey()));
+#endif
+
+#if ENABLE(DOWNLOAD_ATTRIBUTE)
+ RuntimeEnabledFeatures::sharedFeatures().setDownloadAttributeEnabled(store.getBoolValueForKey(WebPreferencesKey::downloadAttributeEnabledKey()));
+#endif
+
+ RuntimeEnabledFeatures::sharedFeatures().setShadowDOMEnabled(store.getBoolValueForKey(WebPreferencesKey::shadowDOMEnabledKey()));
+
+ RuntimeEnabledFeatures::sharedFeatures().setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
+
+ // Experimental Features.
+
+ RuntimeEnabledFeatures::sharedFeatures().setCSSGridLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::cssGridLayoutEnabledKey()));
+
+ RuntimeEnabledFeatures::sharedFeatures().setCustomElementsEnabled(store.getBoolValueForKey(WebPreferencesKey::customElementsEnabledKey()));
+
+#if ENABLE(WEBGL2)
+ RuntimeEnabledFeatures::sharedFeatures().setWebGL2Enabled(store.getBoolValueForKey(WebPreferencesKey::webGL2EnabledKey()));
+#endif
+
+ settings.setSpringTimingFunctionEnabled(store.getBoolValueForKey(WebPreferencesKey::springTimingFunctionEnabledKey()));
+
+ settings.setVisualViewportEnabled(store.getBoolValueForKey(WebPreferencesKey::visualViewportEnabledKey()));
+
+ settings.setInputEventsEnabled(store.getBoolValueForKey(WebPreferencesKey::inputEventsEnabledKey()));
+ RuntimeEnabledFeatures::sharedFeatures().setInputEventsEnabled(store.getBoolValueForKey(WebPreferencesKey::inputEventsEnabledKey()));
+
+ RuntimeEnabledFeatures::sharedFeatures().setModernMediaControlsEnabled(store.getBoolValueForKey(WebPreferencesKey::modernMediaControlsEnabledKey()));
+
+#if ENABLE(ENCRYPTED_MEDIA)
+ RuntimeEnabledFeatures::sharedFeatures().setEncryptedMediaAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::encryptedMediaAPIEnabledKey()));
+#endif
+
+#if ENABLE(INTERSECTION_OBSERVER)
+ RuntimeEnabledFeatures::sharedFeatures().setIntersectionObserverEnabled(store.getBoolValueForKey(WebPreferencesKey::intersectionObserverEnabledKey()));
+#endif
+
+ RuntimeEnabledFeatures::sharedFeatures().setUserTimingEnabled(store.getBoolValueForKey(WebPreferencesKey::userTimingEnabledKey()));
+ RuntimeEnabledFeatures::sharedFeatures().setResourceTimingEnabled(store.getBoolValueForKey(WebPreferencesKey::resourceTimingEnabledKey()));
+ RuntimeEnabledFeatures::sharedFeatures().setLinkPreloadEnabled(store.getBoolValueForKey(WebPreferencesKey::linkPreloadEnabledKey()));
+
+ bool processSuppressionEnabled = store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey());
+ if (m_processSuppressionEnabled != processSuppressionEnabled) {
+ m_processSuppressionEnabled = processSuppressionEnabled;
+ updateThrottleState();
}
+#if ENABLE(SUBTLE_CRYPTO)
+ RuntimeEnabledFeatures::sharedFeatures().setSubtleCryptoEnabled(store.getBoolValueForKey(WebPreferencesKey::subtleCryptoEnabledKey()));
+#endif
+
platformPreferencesDidChange(store);
if (m_drawingArea)
m_drawingArea->updatePreferences(store);
+
+#if PLATFORM(IOS)
+ m_ignoreViewportScalingConstraints = store.getBoolValueForKey(WebPreferencesKey::ignoreViewportScalingConstraintsKey());
+ m_viewportConfiguration.setCanIgnoreScalingConstraints(m_ignoreViewportScalingConstraints);
+ setForceAlwaysUserScalable(m_forceAlwaysUserScalable || store.getBoolValueForKey(WebPreferencesKey::forceAlwaysUserScalableKey()));
+#endif
+ settings.setLargeImageAsyncDecodingEnabled(store.getBoolValueForKey(WebPreferencesKey::largeImageAsyncDecodingEnabledKey()));
+ settings.setAnimatedImageAsyncDecodingEnabled(store.getBoolValueForKey(WebPreferencesKey::animatedImageAsyncDecodingEnabledKey()));
+ settings.setShouldSuppressKeyboardInputDuringProvisionalNavigation(store.getBoolValueForKey(WebPreferencesKey::shouldSuppressKeyboardInputDuringProvisionalNavigationKey()));
+}
+
+#if ENABLE(DATA_DETECTION)
+void WebPage::setDataDetectionResults(NSArray *detectionResults)
+{
+ DataDetectionResult dataDetectionResult;
+ dataDetectionResult.results = detectionResults;
+ send(Messages::WebPageProxy::SetDataDetectionResult(dataDetectionResult));
+}
+#endif
+
+#if PLATFORM(COCOA)
+void WebPage::willCommitLayerTree(RemoteLayerTreeTransaction& layerTransaction)
+{
+ FrameView* frameView = corePage()->mainFrame().view();
+ if (!frameView)
+ return;
+
+ layerTransaction.setContentsSize(frameView->contentsSize());
+ layerTransaction.setScrollOrigin(frameView->scrollOrigin());
+ layerTransaction.setPageScaleFactor(corePage()->pageScaleFactor());
+ layerTransaction.setRenderTreeSize(corePage()->renderTreeSize());
+ layerTransaction.setPageExtendedBackgroundColor(corePage()->pageExtendedBackgroundColor());
+
+ layerTransaction.setBaseLayoutViewportSize(frameView->baseLayoutViewportSize());
+ layerTransaction.setMinStableLayoutViewportOrigin(frameView->minStableLayoutViewportOrigin());
+ layerTransaction.setMaxStableLayoutViewportOrigin(frameView->maxStableLayoutViewportOrigin());
+
+#if PLATFORM(IOS)
+ layerTransaction.setScaleWasSetByUIProcess(scaleWasSetByUIProcess());
+ layerTransaction.setMinimumScaleFactor(m_viewportConfiguration.minimumScale());
+ layerTransaction.setMaximumScaleFactor(m_viewportConfiguration.maximumScale());
+ layerTransaction.setInitialScaleFactor(m_viewportConfiguration.initialScale());
+ layerTransaction.setViewportMetaTagWidth(m_viewportConfiguration.viewportArguments().width);
+ layerTransaction.setViewportMetaTagWidthWasExplicit(m_viewportConfiguration.viewportArguments().widthWasExplicit);
+ layerTransaction.setViewportMetaTagCameFromImageDocument(m_viewportConfiguration.viewportArguments().type == ViewportArguments::ImageDocument);
+ layerTransaction.setIsInStableState(m_isInStableState);
+ layerTransaction.setAllowsUserScaling(allowsUserScaling());
+#endif
+
+#if PLATFORM(MAC)
+ layerTransaction.setScrollPosition(frameView->scrollPosition());
+#endif
}
-#if ENABLE(INSPECTOR)
-WebInspector* WebPage::inspector()
+void WebPage::didFlushLayerTreeAtTime(MonotonicTime timestamp)
+{
+#if PLATFORM(IOS)
+ if (m_oldestNonStableUpdateVisibleContentRectsTimestamp != MonotonicTime()) {
+ Seconds elapsed = timestamp - m_oldestNonStableUpdateVisibleContentRectsTimestamp;
+ m_oldestNonStableUpdateVisibleContentRectsTimestamp = MonotonicTime();
+
+ m_estimatedLatency = m_estimatedLatency * 0.80 + elapsed * 0.20;
+ }
+#else
+ UNUSED_PARAM(timestamp);
+#endif
+}
+#endif
+
+WebInspector* WebPage::inspector(LazyCreationPolicy behavior)
{
if (m_isClosed)
- return 0;
- if (!m_inspector)
- m_inspector = WebInspector::create(this, m_inspectorClient);
+ return nullptr;
+ if (!m_inspector && behavior == LazyCreationPolicy::CreateIfNeeded)
+ m_inspector = WebInspector::create(this);
return m_inspector.get();
}
+
+WebInspectorUI* WebPage::inspectorUI()
+{
+ if (m_isClosed)
+ return nullptr;
+ if (!m_inspectorUI)
+ m_inspectorUI = WebInspectorUI::create(*this);
+ return m_inspectorUI.get();
+}
+
+RemoteWebInspectorUI* WebPage::remoteInspectorUI()
+{
+ if (m_isClosed)
+ return nullptr;
+ if (!m_remoteInspectorUI)
+ m_remoteInspectorUI = RemoteWebInspectorUI::create(*this);
+ return m_remoteInspectorUI.get();
+}
+
+#if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+WebPlaybackSessionManager& WebPage::playbackSessionManager()
+{
+ if (!m_playbackSessionManager)
+ m_playbackSessionManager = WebPlaybackSessionManager::create(*this);
+ return *m_playbackSessionManager;
+}
+
+WebVideoFullscreenManager& WebPage::videoFullscreenManager()
+{
+ if (!m_videoFullscreenManager)
+ m_videoFullscreenManager = WebVideoFullscreenManager::create(*this, playbackSessionManager());
+ return *m_videoFullscreenManager;
+}
+#endif
+
+#if PLATFORM(IOS)
+void WebPage::setAllowsMediaDocumentInlinePlayback(bool allows)
+{
+ m_page->setAllowsMediaDocumentInlinePlayback(allows);
+}
#endif
#if ENABLE(FULLSCREEN_API)
@@ -2643,7 +3400,7 @@ NotificationPermissionRequestManager* WebPage::notificationPermissionRequestMana
return m_notificationPermissionRequestManager.get();
}
-#if !PLATFORM(GTK) && !PLATFORM(MAC)
+#if !PLATFORM(GTK) && !PLATFORM(COCOA)
bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
{
Node* node = evt->target()->toNode();
@@ -2682,64 +3439,63 @@ bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
#if ENABLE(DRAG_SUPPORT)
#if PLATFORM(GTK)
-void WebPage::performDragControllerAction(uint64_t action, WebCore::DragData dragData)
+void WebPage::performDragControllerAction(uint64_t action, const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t draggingSourceOperationMask, WebSelectionData&& selection, uint32_t flags)
{
if (!m_page) {
- send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession()));
- DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
- data->deref();
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, false, 0));
return;
}
+ DragData dragData(selection.selectionData.ptr(), clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
switch (action) {
- case DragControllerActionEntered:
- send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController().dragEntered(dragData)));
+ case DragControllerActionEntered: {
+ DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
break;
-
- case DragControllerActionUpdated:
- send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController().dragUpdated(dragData)));
+ }
+ case DragControllerActionUpdated: {
+ DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
break;
-
+ }
case DragControllerActionExited:
m_page->dragController().dragExited(dragData);
break;
- case DragControllerActionPerformDrag: {
- m_page->dragController().performDrag(dragData);
+ case DragControllerActionPerformDragOperation: {
+ m_page->dragController().performDragOperation(dragData);
break;
}
default:
ASSERT_NOT_REACHED();
}
- // DragData does not delete its platformData so we need to do that here.
- DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
- data->deref();
}
-
#else
-void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsHandleArray)
+void WebPage::performDragControllerAction(uint64_t action, const WebCore::DragData& dragData, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsHandleArray)
{
if (!m_page) {
- send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession()));
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, false, 0));
return;
}
- DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
switch (action) {
- case DragControllerActionEntered:
- send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController().dragEntered(dragData)));
+ case DragControllerActionEntered: {
+ DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
break;
- case DragControllerActionUpdated:
- send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController().dragUpdated(dragData)));
+ }
+ case DragControllerActionUpdated: {
+ DragOperation resolvedDragOperation = m_page->dragController().dragUpdated(dragData);
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
break;
-
+ }
case DragControllerActionExited:
m_page->dragController().dragExited(dragData);
break;
- case DragControllerActionPerformDrag: {
+ case DragControllerActionPerformDragOperation: {
ASSERT(!m_pendingDropSandboxExtension);
m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
@@ -2748,13 +3504,16 @@ void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint cli
m_pendingDropExtensionsForFileUpload.append(extension);
}
- m_page->dragController().performDrag(dragData);
+ m_page->dragController().performDragOperation(dragData);
// If we started loading a local file, the sandbox extension tracker would have adopted this
// pending drop sandbox extension. If not, we'll play it safe and clear it.
m_pendingDropSandboxExtension = nullptr;
m_pendingDropExtensionsForFileUpload.clear();
+#if ENABLE(DATA_INTERACTION)
+ send(Messages::WebPageProxy::DidPerformDataInteractionControllerOperation());
+#endif
break;
}
@@ -2774,13 +3533,13 @@ void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint glob
if (!view)
return;
// FIXME: These are fake modifier keys here, but they should be real ones instead.
- PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime());
+ PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime(), 0, WebCore::NoTap);
m_page->mainFrame().eventHandler().dragSourceEndedAt(event, (DragOperation)operation);
}
void WebPage::willPerformLoadDragDestinationAction()
{
- m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release());
+ m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(WTFMove(m_pendingDropSandboxExtension));
}
void WebPage::mayPerformUploadDragDestinationAction()
@@ -2807,6 +3566,11 @@ void WebPage::removeWebEditCommand(uint64_t stepID)
m_undoStepMap.remove(stepID);
}
+bool WebPage::isAlwaysOnLoggingAllowed() const
+{
+ return corePage() && corePage()->isAlwaysOnLoggingAllowed();
+}
+
void WebPage::unapplyEditCommand(uint64_t stepID)
{
WebUndoStep* step = webUndoStep(stepID);
@@ -2838,6 +3602,7 @@ void WebPage::setActivePopupMenu(WebPopupMenu* menu)
}
#if ENABLE(INPUT_TYPE_COLOR)
+
void WebPage::setActiveColorChooser(WebColorChooser* colorChooser)
{
m_activeColorChooser = colorChooser;
@@ -2852,11 +3617,12 @@ void WebPage::didChooseColor(const WebCore::Color& color)
{
m_activeColorChooser->didChooseColor(color);
}
+
#endif
-void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener)
+void WebPage::setActiveOpenPanelResultListener(Ref<WebOpenPanelResultListener>&& openPanelResultListener)
{
- m_activeOpenPanelResultListener = openPanelResultListener;
+ m_activeOpenPanelResultListener = WTFMove(openPanelResultListener);
}
bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options)
@@ -2897,7 +3663,7 @@ void WebPage::countStringMatches(const String& string, uint32_t options, uint32_
void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
{
changeSelectedIndex(newIndex);
- m_activePopupMenu = 0;
+ m_activePopupMenu = nullptr;
}
void WebPage::changeSelectedIndex(int32_t index)
@@ -2908,24 +3674,47 @@ void WebPage::changeSelectedIndex(int32_t index)
m_activePopupMenu->didChangeSelectedIndex(index);
}
+#if PLATFORM(IOS)
+void WebPage::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& files, const String& displayString, const IPC::DataReference& iconData)
+{
+ if (!m_activeOpenPanelResultListener)
+ return;
+
+ RefPtr<Icon> icon;
+ if (!iconData.isEmpty()) {
+ RetainPtr<CFDataRef> dataRef = adoptCF(CFDataCreate(nullptr, iconData.data(), iconData.size()));
+ RetainPtr<CGDataProviderRef> imageProviderRef = adoptCF(CGDataProviderCreateWithCFData(dataRef.get()));
+ RetainPtr<CGImageRef> imageRef = adoptCF(CGImageCreateWithJPEGDataProvider(imageProviderRef.get(), nullptr, true, kCGRenderingIntentDefault));
+ icon = Icon::createIconForImage(imageRef.get());
+ }
+
+ m_activeOpenPanelResultListener->didChooseFilesWithDisplayStringAndIcon(files, displayString, icon.get());
+ m_activeOpenPanelResultListener = nullptr;
+}
+#endif
+
void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
{
if (!m_activeOpenPanelResultListener)
return;
m_activeOpenPanelResultListener->didChooseFiles(files);
- m_activeOpenPanelResultListener = 0;
+ m_activeOpenPanelResultListener = nullptr;
}
void WebPage::didCancelForOpenPanel()
{
- m_activeOpenPanelResultListener = 0;
+ m_activeOpenPanelResultListener = nullptr;
}
-#if ENABLE(WEB_PROCESS_SANDBOX)
+#if ENABLE(SANDBOX_EXTENSIONS)
void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle)
{
- SandboxExtension::create(handle)->consumePermanently();
+ bool result = SandboxExtension::consumePermanently(handle);
+ if (!result) {
+ // We have reports of cases where this fails for some unknown reason, <rdar://problem/10156710>.
+ WTFLogAlways("WebPage::extendSandboxForFileFromOpenPanel(): Could not consume a sandbox extension");
+ }
}
#endif
@@ -2941,6 +3730,34 @@ void WebPage::didReceiveNotificationPermissionDecision(uint64_t notificationID,
notificationPermissionRequestManager()->didReceiveNotificationPermissionDecision(notificationID, allowed);
}
+#if ENABLE(MEDIA_STREAM)
+void WebPage::userMediaAccessWasGranted(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID)
+{
+ m_userMediaPermissionRequestManager.userMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID);
+}
+
+void WebPage::userMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)
+{
+ m_userMediaPermissionRequestManager.userMediaAccessWasDenied(userMediaID, static_cast<UserMediaRequest::MediaAccessDenialReason>(reason), invalidConstraint);
+}
+
+void WebPage::didCompleteMediaDeviceEnumeration(uint64_t userMediaID, const Vector<CaptureDevice>& devices, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess)
+{
+ m_userMediaPermissionRequestManager.didCompleteMediaDeviceEnumeration(userMediaID, devices, deviceIdentifierHashSalt, originHasPersistentAccess);
+}
+#if ENABLE(SANDBOX_EXTENSIONS)
+void WebPage::grantUserMediaDeviceSandboxExtensions(const MediaDeviceSandboxExtensions& extensions)
+{
+ m_userMediaPermissionRequestManager.grantUserMediaDeviceSandboxExtensions(extensions);
+}
+
+void WebPage::revokeUserMediaDeviceSandboxExtensions(const Vector<String>& extensionIDs)
+{
+ m_userMediaPermissionRequestManager.revokeUserMediaDeviceSandboxExtensions(extensionIDs);
+}
+#endif
+#endif
+
#if !PLATFORM(IOS)
void WebPage::advanceToNextMisspelling(bool startBeforeSelection)
{
@@ -3012,7 +3829,7 @@ void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& i
return;
m_contextMenu->itemSelected(item);
- m_contextMenu = 0;
+ m_contextMenu = nullptr;
}
#endif
@@ -3023,17 +3840,47 @@ void WebPage::replaceSelectionWithText(Frame* frame, const String& text)
return frame->editor().replaceSelectionWithText(text, selectReplacement, smartReplace);
}
+#if !PLATFORM(IOS)
void WebPage::clearSelection()
{
m_page->focusController().focusedOrMainFrame().selection().clear();
}
+#endif
+
+void WebPage::restoreSelectionInFocusedEditableElement()
+{
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+ if (!frame.selection().isNone())
+ return;
+
+ if (auto document = frame.document()) {
+ if (auto element = document->focusedElement())
+ element->updateFocusAppearance(SelectionRestorationMode::Restore, SelectionRevealMode::DoNotReveal);
+ }
+}
+
+bool WebPage::mainFrameHasCustomContentProvider() const
+{
+ if (Frame* frame = mainFrame()) {
+ WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
+ ASSERT(webFrameLoaderClient);
+ return webFrameLoaderClient->frameHasCustomContentProvider();
+ }
+
+ return false;
+}
+
+void WebPage::addMIMETypeWithCustomContentProvider(const String& mimeType)
+{
+ m_mimeTypesWithCustomContentProviders.add(mimeType);
+}
void WebPage::updateMainFrameScrollOffsetPinning()
{
Frame& frame = m_page->mainFrame();
- IntPoint scrollPosition = frame.view()->scrollPosition();
- IntPoint maximumScrollPosition = frame.view()->maximumScrollPosition();
- IntPoint minimumScrollPosition = frame.view()->minimumScrollPosition();
+ ScrollPosition scrollPosition = frame.view()->scrollPosition();
+ ScrollPosition maximumScrollPosition = frame.view()->maximumScrollPosition();
+ ScrollPosition minimumScrollPosition = frame.view()->minimumScrollPosition();
bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x());
bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x());
@@ -3058,21 +3905,17 @@ void WebPage::mainFrameDidLayout()
m_cachedPageCount = pageCount;
}
-#if USE(TILED_BACKING_STORE) && USE(ACCELERATED_COMPOSITING)
- if (m_drawingArea && m_drawingArea->layerTreeHost()) {
- double red, green, blue, alpha;
- m_mainFrame->getDocumentBackgroundColor(&red, &green, &blue, &alpha);
- RGBA32 rgba = makeRGBA32FromFloats(red, green, blue, alpha);
- if (m_backgroundColor.rgb() != rgba) {
- m_backgroundColor.setRGB(rgba);
- m_drawingArea->layerTreeHost()->setBackgroundColor(m_backgroundColor);
- }
- }
-#endif
-
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
m_viewGestureGeometryCollector.mainFrameDidLayout();
#endif
+#if PLATFORM(IOS)
+ if (FrameView* frameView = mainFrameView()) {
+ IntSize newContentSize = frameView->contentsSize();
+ if (m_viewportConfiguration.setContentsSize(newContentSize))
+ viewportConfigurationChanged();
+ }
+ m_findController.redraw();
+#endif
}
void WebPage::addPluginView(PluginView* pluginView)
@@ -3099,13 +3942,13 @@ void WebPage::removePluginView(PluginView* pluginView)
void WebPage::sendSetWindowFrame(const FloatRect& windowFrame)
{
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
m_hasCachedWindowFrame = false;
#endif
send(Messages::WebPageProxy::SetWindowFrame(windowFrame));
}
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void WebPage::windowAndViewFramesChanged(const FloatRect& windowFrameInScreenCoordinates, const FloatRect& windowFrameInUnflippedScreenCoordinates, const FloatRect& viewFrameInWindowCoordinates, const FloatPoint& accessibilityViewCoordinates)
{
m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
@@ -3145,29 +3988,25 @@ bool WebPage::windowAndWebPageAreFocused() const
return m_page->focusController().isFocused() && m_page->focusController().isActive();
}
-void WebPage::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder)
+void WebPage::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
{
- if (decoder.messageReceiverName() == Messages::DrawingArea::messageReceiverName()) {
- if (m_drawingArea)
- m_drawingArea->didReceiveDrawingAreaMessage(connection, decoder);
+ if (decoder.messageReceiverName() == Messages::WebInspector::messageReceiverName()) {
+ if (WebInspector* inspector = this->inspector())
+ inspector->didReceiveMessage(connection, decoder);
return;
}
-#if USE(TILED_BACKING_STORE) && USE(ACCELERATED_COMPOSITING)
- if (decoder.messageReceiverName() == Messages::CoordinatedLayerTreeHost::messageReceiverName()) {
- if (m_drawingArea)
- m_drawingArea->didReceiveCoordinatedLayerTreeHostMessage(connection, decoder);
+ if (decoder.messageReceiverName() == Messages::WebInspectorUI::messageReceiverName()) {
+ if (WebInspectorUI* inspectorUI = this->inspectorUI())
+ inspectorUI->didReceiveMessage(connection, decoder);
return;
}
-#endif
-
-#if ENABLE(INSPECTOR)
- if (decoder.messageReceiverName() == Messages::WebInspector::messageReceiverName()) {
- if (WebInspector* inspector = this->inspector())
- inspector->didReceiveWebInspectorMessage(connection, decoder);
+
+ if (decoder.messageReceiverName() == Messages::RemoteWebInspectorUI::messageReceiverName()) {
+ if (RemoteWebInspectorUI* remoteInspectorUI = this->remoteInspectorUI())
+ remoteInspectorUI->didReceiveMessage(connection, decoder);
return;
}
-#endif
#if ENABLE(FULLSCREEN_API)
if (decoder.messageReceiverName() == Messages::WebFullScreenManager::messageReceiverName()) {
@@ -3179,7 +4018,7 @@ void WebPage::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder
didReceiveWebPageMessage(connection, decoder);
}
-void WebPage::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)
+void WebPage::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
{
didReceiveSyncWebPageMessage(connection, decoder, replyEncoder);
}
@@ -3243,7 +4082,7 @@ static bool shouldReuseCommittedSandboxExtension(WebFrame* frame)
FrameLoadType frameLoadType = frameLoader.loadType();
// If the page is being reloaded, it should reuse whatever extension is committed.
- if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin)
+ if (frameLoadType == FrameLoadType::Reload || frameLoadType == FrameLoadType::ReloadFromOrigin)
return true;
DocumentLoader* documentLoader = frameLoader.documentLoader();
@@ -3269,7 +4108,7 @@ void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
ASSERT(!m_provisionalSandboxExtension);
- m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
+ m_provisionalSandboxExtension = WTFMove(m_pendingProvisionalSandboxExtension);
if (!m_provisionalSandboxExtension)
return;
@@ -3286,7 +4125,7 @@ void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame)
if (m_committedSandboxExtension)
m_committedSandboxExtension->revoke();
- m_committedSandboxExtension = m_provisionalSandboxExtension.release();
+ m_committedSandboxExtension = WTFMove(m_provisionalSandboxExtension);
// We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started.
// This extension is not cleared, because it does not pertain to the failed load, and will be needed.
@@ -3330,7 +4169,7 @@ void WebPage::didRemoveBackForwardItem(uint64_t itemID)
WebBackForwardListProxy::removeItem(itemID);
}
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
bool WebPage::isSpeaking()
{
@@ -3350,19 +4189,16 @@ void WebPage::stopSpeaking()
#endif
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
RetainPtr<PDFDocument> WebPage::pdfDocumentForPrintingFrame(Frame* coreFrame)
{
Document* document = coreFrame->document();
- if (!document)
- return 0;
-
- if (!document->isPluginDocument())
- return 0;
+ if (!is<PluginDocument>(document))
+ return nullptr;
- PluginView* pluginView = static_cast<PluginView*>(toPluginDocument(document)->pluginWidget());
+ PluginView* pluginView = static_cast<PluginView*>(downcast<PluginDocument>(*document).pluginWidget());
if (!pluginView)
- return 0;
+ return nullptr;
return pluginView->pdfDocumentForPrinting();
}
@@ -3370,7 +4206,7 @@ RetainPtr<PDFDocument> WebPage::pdfDocumentForPrintingFrame(Frame* coreFrame)
void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
{
- WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
if (!frame)
return;
@@ -3378,13 +4214,13 @@ void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
if (!coreFrame)
return;
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
if (pdfDocumentForPrintingFrame(coreFrame))
return;
#endif // PLATFORM(MAC)
if (!m_printContext)
- m_printContext = adoptPtr(new PrintContext(coreFrame));
+ m_printContext = std::make_unique<PrintContext>(coreFrame);
drawingArea()->setLayerTreeStateIsFrozen(true);
m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight);
@@ -3408,6 +4244,13 @@ void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printIn
{
Vector<IntRect> resultPageRects;
double resultTotalScaleFactorForPrinting = 1;
+ computePagesForPrintingImpl(frameID, printInfo, resultPageRects, resultTotalScaleFactorForPrinting);
+ send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID));
+}
+
+void WebPage::computePagesForPrintingImpl(uint64_t frameID, const PrintInfo& printInfo, Vector<WebCore::IntRect>& resultPageRects, double& resultTotalScaleFactorForPrinting)
+{
+ ASSERT(resultPageRects.isEmpty());
beginPrinting(frameID, printInfo);
@@ -3415,41 +4258,43 @@ void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printIn
resultPageRects = m_printContext->pageRects();
resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor;
}
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
else
computePagesForPrintingPDFDocument(frameID, printInfo, resultPageRects);
-#endif // PLATFORM(MAC)
+#endif // PLATFORM(COCOA)
// If we're asked to print, we should actually print at least a blank page.
if (resultPageRects.isEmpty())
resultPageRects.append(IntRect(0, 0, 1, 1));
-
- send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID));
}
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void WebPage::drawRectToImage(uint64_t frameID, const PrintInfo& printInfo, const IntRect& rect, const WebCore::IntSize& imageSize, uint64_t callbackID)
{
- WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
Frame* coreFrame = frame ? frame->coreFrame() : 0;
RefPtr<WebImage> image;
#if USE(CG)
if (coreFrame) {
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
#else
ASSERT(coreFrame->document()->printing());
#endif
- RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(imageSize, ShareableBitmap::SupportsAlpha);
+ auto bitmap = ShareableBitmap::createShareable(imageSize, ShareableBitmap::SupportsAlpha);
+ if (!bitmap) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
auto graphicsContext = bitmap->createGraphicsContext();
float printingScale = static_cast<float>(imageSize.width()) / rect.width();
- graphicsContext->scale(FloatSize(printingScale, printingScale));
+ graphicsContext->scale(printingScale);
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) {
ASSERT(!m_printContext);
graphicsContext->scale(FloatSize(1, -1));
@@ -3461,29 +4306,36 @@ void WebPage::drawRectToImage(uint64_t frameID, const PrintInfo& printInfo, cons
m_printContext->spoolRect(*graphicsContext, rect);
}
- image = WebImage::create(bitmap.release());
+ image = WebImage::create(bitmap.releaseNonNull());
}
#endif
ShareableBitmap::Handle handle;
if (image)
- image->bitmap()->createHandle(handle, SharedMemory::ReadOnly);
+ image->bitmap().createHandle(handle, SharedMemory::Protection::ReadOnly);
send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
}
void WebPage::drawPagesToPDF(uint64_t frameID, const PrintInfo& printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
{
- WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ RetainPtr<CFMutableDataRef> pdfPageData;
+ drawPagesToPDFImpl(frameID, printInfo, first, count, pdfPageData);
+ send(Messages::WebPageProxy::DataCallback(IPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
+}
+
+void WebPage::drawPagesToPDFImpl(uint64_t frameID, const PrintInfo& printInfo, uint32_t first, uint32_t count, RetainPtr<CFMutableDataRef>& pdfPageData)
+{
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
Frame* coreFrame = frame ? frame->coreFrame() : 0;
- RetainPtr<CFMutableDataRef> pdfPageData = adoptCF(CFDataCreateMutable(0, 0));
+ pdfPageData = adoptCF(CFDataCreateMutable(0, 0));
#if USE(CG)
if (coreFrame) {
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
#else
ASSERT(coreFrame->document()->printing());
@@ -3495,7 +4347,7 @@ void WebPage::drawPagesToPDF(uint64_t frameID, const PrintInfo& printInfo, uint3
CGRect mediaBox = (m_printContext && m_printContext->pageCount()) ? m_printContext->pageRect(0) : CGRectMake(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight);
RetainPtr<CGContextRef> context = adoptCF(CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) {
ASSERT(!m_printContext);
drawPagesToPDFFromPDFDocument(context.get(), pdfDocument.get(), printInfo, first, count);
@@ -3521,8 +4373,6 @@ void WebPage::drawPagesToPDF(uint64_t frameID, const PrintInfo& printInfo, uint3
CGPDFContextClose(context.get());
}
#endif
-
- send(Messages::WebPageProxy::DataCallback(IPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
}
#elif PLATFORM(GTK)
@@ -3549,18 +4399,59 @@ void WebPage::savePDFToFileInDownloadsFolder(const String& suggestedFilename, co
send(Messages::WebPageProxy::SavePDFToFileInDownloadsFolder(suggestedFilename, originatingURLString, IPC::DataReference(data, size)));
}
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void WebPage::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size, const String& pdfUUID)
{
send(Messages::WebPageProxy::SavePDFToTemporaryFolderAndOpenWithNativeApplication(suggestedFilename, originatingURLString, IPC::DataReference(data, size), pdfUUID));
}
#endif
+void WebPage::addResourceRequest(unsigned long identifier, const WebCore::ResourceRequest& request)
+{
+ if (!request.url().protocolIsInHTTPFamily())
+ return;
+
+ if (m_mainFrameProgressCompleted && !ScriptController::processingUserGesture())
+ return;
+
+ ASSERT(!m_trackedNetworkResourceRequestIdentifiers.contains(identifier));
+ bool wasEmpty = m_trackedNetworkResourceRequestIdentifiers.isEmpty();
+ m_trackedNetworkResourceRequestIdentifiers.add(identifier);
+ if (wasEmpty)
+ send(Messages::WebPageProxy::SetNetworkRequestsInProgress(true));
+}
+
+void WebPage::removeResourceRequest(unsigned long identifier)
+{
+ if (!m_trackedNetworkResourceRequestIdentifiers.remove(identifier))
+ return;
+
+ if (m_trackedNetworkResourceRequestIdentifiers.isEmpty())
+ send(Messages::WebPageProxy::SetNetworkRequestsInProgress(false));
+}
+
void WebPage::setMediaVolume(float volume)
{
m_page->setMediaVolume(volume);
}
+void WebPage::setMuted(MediaProducer::MutedStateFlags state)
+{
+ m_page->setMuted(state);
+}
+
+#if ENABLE(MEDIA_SESSION)
+void WebPage::handleMediaEvent(uint32_t eventType)
+{
+ m_page->handleMediaEvent(static_cast<MediaEventType>(eventType));
+}
+
+void WebPage::setVolumeOfMediaElement(double volume, uint64_t elementID)
+{
+ m_page->setVolumeOfMediaElement(volume, elementID);
+}
+#endif
+
void WebPage::setMayStartMediaWhenInWindow(bool mayStartMedia)
{
if (mayStartMedia == m_mayStartMediaWhenInWindow)
@@ -3580,36 +4471,25 @@ void WebPage::runModal()
m_isRunningModal = true;
send(Messages::WebPageProxy::RunModal());
+#if !ASSERT_DISABLED
+ Ref<WebPage> protector(*this);
+#endif
RunLoop::run();
ASSERT(!m_isRunningModal);
}
-void WebPage::setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled)
-{
- m_page->setMemoryCacheClientCallsEnabled(memoryCacheMessagesEnabled);
-}
-
bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request)
{
- if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol()))
+ if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol().toStringWithoutCopying()))
return true;
-#if ENABLE(BLOB)
- if (request.url().protocolIs("blob"))
+ if (request.url().protocolIsBlob())
return true;
-#endif
return platformCanHandleRequest(request);
}
-#if USE(TILED_BACKING_STORE)
-void WebPage::commitPageTransitionViewport()
-{
- m_drawingArea->setLayerTreeStateIsFrozen(false);
-}
-#endif
-
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void WebPage::handleAlternativeTextUIResult(const String& result)
{
Frame& frame = m_page->focusController().focusedOrMainFrame();
@@ -3619,17 +4499,17 @@ void WebPage::handleAlternativeTextUIResult(const String& result)
void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
{
- mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
+ mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time, WebCore::ForceAtClick, WebMouseEvent::NoTap));
}
void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
{
- mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
+ mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time, WebCore::ForceAtClick, WebMouseEvent::NoTap));
}
void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time)
{
- mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time));
+ mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time, 0, WebMouseEvent::NoTap));
}
void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length)
@@ -3660,12 +4540,12 @@ void WebPage::confirmCompositionForTesting(const String& compositionString)
frame.editor().confirmComposition(compositionString);
}
-void WebPage::numWheelEventHandlersChanged(unsigned numWheelEventHandlers)
+void WebPage::wheelEventHandlersChanged(bool hasHandlers)
{
- if (m_numWheelEventHandlers == numWheelEventHandlers)
+ if (m_hasWheelEventHandlers == hasHandlers)
return;
- m_numWheelEventHandlers = numWheelEventHandlers;
+ m_hasWheelEventHandlers = hasHandlers;
recomputeShortCircuitHorizontalWheelEventsState();
}
@@ -3708,7 +4588,7 @@ static bool pageContainsAnyHorizontalScrollbars(Frame* mainFrame)
void WebPage::recomputeShortCircuitHorizontalWheelEventsState()
{
- bool canShortCircuitHorizontalWheelEvents = !m_numWheelEventHandlers;
+ bool canShortCircuitHorizontalWheelEvents = !m_hasWheelEventHandlers;
if (canShortCircuitHorizontalWheelEvents) {
// Check if we have any horizontal scroll bars on the page.
@@ -3723,9 +4603,9 @@ void WebPage::recomputeShortCircuitHorizontalWheelEventsState()
send(Messages::WebPageProxy::SetCanShortCircuitHorizontalWheelEvents(m_canShortCircuitHorizontalWheelEvents));
}
-Frame* WebPage::mainFrame() const
+MainFrame* WebPage::mainFrame() const
{
- return m_page ? &m_page->mainFrame() : 0;
+ return m_page ? &m_page->mainFrame() : nullptr;
}
FrameView* WebPage::mainFrameView() const
@@ -3733,18 +4613,7 @@ FrameView* WebPage::mainFrameView() const
if (Frame* frame = mainFrame())
return frame->view();
- return 0;
-}
-
-void WebPage::setVisibilityStatePrerender()
-{
- if (m_page)
- m_page->setIsPrerender();
-}
-
-void WebPage::setIsVisuallyIdle(bool isVisuallyIdle)
-{
- m_page->setIsVisuallyIdle(isVisuallyIdle);
+ return nullptr;
}
void WebPage::setScrollingPerformanceLoggingEnabled(bool enabled)
@@ -3762,7 +4631,7 @@ bool WebPage::canPluginHandleResponse(const ResourceResponse& response)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
uint32_t pluginLoadPolicy;
- bool allowOnlyApplicationPlugins = !m_mainFrame->coreFrame()->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin);
+ bool allowOnlyApplicationPlugins = !m_mainFrame->coreFrame()->loader().subframeLoader().allowPlugins();
uint64_t pluginProcessToken;
String newMIMEType;
@@ -3770,13 +4639,143 @@ bool WebPage::canPluginHandleResponse(const ResourceResponse& response)
if (!sendSync(Messages::WebPageProxy::FindPlugin(response.mimeType(), PluginProcessTypeNormal, response.url().string(), response.url().string(), response.url().string(), allowOnlyApplicationPlugins), Messages::WebPageProxy::FindPlugin::Reply(pluginProcessToken, newMIMEType, pluginLoadPolicy, unavailabilityDescription)))
return false;
- return pluginLoadPolicy != PluginModuleBlocked && pluginProcessToken;
+ bool isBlockedPlugin = (pluginLoadPolicy == PluginModuleBlockedForSecurity) || (pluginLoadPolicy == PluginModuleBlockedForCompatibility);
+ return !isBlockedPlugin && pluginProcessToken;
#else
UNUSED_PARAM(response);
return false;
#endif
}
+bool WebPage::shouldUseCustomContentProviderForResponse(const ResourceResponse& response)
+{
+ auto& mimeType = response.mimeType();
+ if (mimeType.isNull())
+ return false;
+
+ // If a plug-in exists that claims to support this response, it should take precedence over the custom content provider.
+ // canPluginHandleResponse() is called last because it performs synchronous IPC.
+ return m_mimeTypesWithCustomContentProviders.contains(mimeType) && !canPluginHandleResponse(response);
+}
+
+#if PLATFORM(COCOA)
+
+void WebPage::insertTextAsync(const String& text, const EditingRange& replacementEditingRange, bool registerUndoGroup, uint32_t editingRangeIsRelativeTo, bool suppressSelectionUpdate)
+{
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+
+ Ref<Frame> protector(frame);
+
+ bool replacesText = false;
+ if (replacementEditingRange.location != notFound) {
+ RefPtr<Range> replacementRange = rangeFromEditingRange(frame, replacementEditingRange, static_cast<EditingRangeIsRelativeTo>(editingRangeIsRelativeTo));
+ if (replacementRange) {
+ SetForScope<bool> isSelectingTextWhileInsertingAsynchronously(m_isSelectingTextWhileInsertingAsynchronously, suppressSelectionUpdate);
+ frame.selection().setSelection(VisibleSelection(*replacementRange, SEL_DEFAULT_AFFINITY));
+ replacesText = true;
+ }
+ }
+
+ if (registerUndoGroup)
+ send(Messages::WebPageProxy::RegisterInsertionUndoGrouping());
+
+ if (!frame.editor().hasComposition()) {
+ // An insertText: might be handled by other responders in the chain if we don't handle it.
+ // One example is space bar that results in scrolling down the page.
+ frame.editor().insertText(text, nullptr, replacesText ? TextEventInputAutocompletion : TextEventInputKeyboard);
+ } else
+ frame.editor().confirmComposition(text);
+}
+
+void WebPage::getMarkedRangeAsync(uint64_t callbackID)
+{
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+
+ RefPtr<Range> range = frame.editor().compositionRange();
+ size_t location;
+ size_t length;
+ if (!range || !TextIterator::getLocationAndLengthFromRange(frame.selection().rootEditableElementOrDocumentElement(), range.get(), location, length)) {
+ location = notFound;
+ length = 0;
+ }
+
+ send(Messages::WebPageProxy::EditingRangeCallback(EditingRange(location, length), callbackID));
+}
+
+void WebPage::getSelectedRangeAsync(uint64_t callbackID)
+{
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+
+ size_t location;
+ size_t length;
+ RefPtr<Range> range = frame.selection().toNormalizedRange();
+ if (!range || !TextIterator::getLocationAndLengthFromRange(frame.selection().rootEditableElementOrDocumentElement(), range.get(), location, length)) {
+ location = notFound;
+ length = 0;
+ }
+
+ send(Messages::WebPageProxy::EditingRangeCallback(EditingRange(location, length), callbackID));
+}
+
+void WebPage::characterIndexForPointAsync(const WebCore::IntPoint& point, uint64_t callbackID)
+{
+ uint64_t index = notFound;
+
+ HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(point);
+ Frame* frame = result.innerNonSharedNode() ? result.innerNodeFrame() : &m_page->focusController().focusedOrMainFrame();
+
+ RefPtr<Range> range = frame->rangeForPoint(result.roundedPointInInnerNodeFrame());
+ if (range) {
+ size_t location;
+ size_t length;
+ if (TextIterator::getLocationAndLengthFromRange(frame->selection().rootEditableElementOrDocumentElement(), range.get(), location, length))
+ index = static_cast<uint64_t>(location);
+ }
+
+ send(Messages::WebPageProxy::UnsignedCallback(index, callbackID));
+}
+
+void WebPage::firstRectForCharacterRangeAsync(const EditingRange& editingRange, uint64_t callbackID)
+{
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+ IntRect result(IntPoint(0, 0), IntSize(0, 0));
+
+ RefPtr<Range> range = rangeFromEditingRange(frame, editingRange);
+ if (!range) {
+ send(Messages::WebPageProxy::RectForCharacterRangeCallback(result, EditingRange(notFound, 0), callbackID));
+ return;
+ }
+
+ result = frame.view()->contentsToWindow(frame.editor().firstRectForRange(range.get()));
+
+ // FIXME: Update actualRange to match the range of first rect.
+ send(Messages::WebPageProxy::RectForCharacterRangeCallback(result, editingRange, callbackID));
+}
+
+void WebPage::setCompositionAsync(const String& text, Vector<CompositionUnderline> underlines, const EditingRange& selection, const EditingRange& replacementEditingRange)
+{
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+
+ if (frame.selection().selection().isContentEditable()) {
+ RefPtr<Range> replacementRange;
+ if (replacementEditingRange.location != notFound) {
+ replacementRange = rangeFromEditingRange(frame, replacementEditingRange);
+ if (replacementRange)
+ frame.selection().setSelection(VisibleSelection(*replacementRange, SEL_DEFAULT_AFFINITY));
+ }
+
+ frame.editor().setComposition(text, underlines, selection.location, selection.location + selection.length);
+ }
+}
+
+void WebPage::confirmCompositionAsync()
+{
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+ frame.editor().confirmComposition();
+}
+
+#endif // PLATFORM(COCOA)
+
#if PLATFORM(GTK)
static Frame* targetFrameForEditing(WebPage* page)
{
@@ -3784,17 +4783,16 @@ static Frame* targetFrameForEditing(WebPage* page)
Editor& editor = targetFrame.editor();
if (!editor.canEdit())
- return 0;
+ return nullptr;
if (editor.hasComposition()) {
// We should verify the parent node of this IME composition node are
// editable because JavaScript may delete a parent node of the composition
// node. In this case, WebKit crashes while deleting texts from the parent
// node, which doesn't exist any longer.
- if (PassRefPtr<Range> range = editor.compositionRange()) {
- Node* node = range->startContainer();
- if (!node || !node->isContentEditable())
- return 0;
+ if (auto range = editor.compositionRange()) {
+ if (!range->startContainer().isContentEditable())
+ return nullptr;
}
}
return &targetFrame;
@@ -3815,37 +4813,39 @@ void WebPage::confirmComposition(const String& compositionString, int64_t select
return;
}
- Element* scope = targetFrame->selection().rootEditableElement();
+ Element* scope = targetFrame->selection().selection().rootEditableElement();
RefPtr<Range> selectionRange = TextIterator::rangeFromLocationAndLength(scope, selectionStart, selectionLength);
ASSERT_WITH_MESSAGE(selectionRange, "Invalid selection: [%lld:%lld] in text of length %d", static_cast<long long>(selectionStart), static_cast<long long>(selectionLength), scope->innerText().length());
if (selectionRange) {
- VisibleSelection selection(selectionRange.get(), SEL_DEFAULT_AFFINITY);
+ VisibleSelection selection(*selectionRange, SEL_DEFAULT_AFFINITY);
targetFrame->selection().setSelection(selection);
}
send(Messages::WebPageProxy::EditorStateChanged(editorState()));
}
-void WebPage::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementStart, uint64_t replacementLength)
+void WebPage::setComposition(const String& text, const Vector<CompositionUnderline>& underlines, uint64_t selectionStart, uint64_t selectionLength, uint64_t replacementStart, uint64_t replacementLength)
{
Frame* targetFrame = targetFrameForEditing(this);
- if (!targetFrame || !targetFrame->selection().isContentEditable()) {
+ if (!targetFrame || !targetFrame->selection().selection().isContentEditable()) {
send(Messages::WebPageProxy::EditorStateChanged(editorState()));
return;
}
+ Ref<Frame> protector(*targetFrame);
+
if (replacementLength > 0) {
// The layout needs to be uptodate before setting a selection
targetFrame->document()->updateLayout();
- Element* scope = targetFrame->selection().rootEditableElement();
+ Element* scope = targetFrame->selection().selection().rootEditableElement();
RefPtr<Range> replacementRange = TextIterator::rangeFromLocationAndLength(scope, replacementStart, replacementLength);
targetFrame->editor().setIgnoreCompositionSelectionChange(true);
- targetFrame->selection().setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
+ targetFrame->selection().setSelection(VisibleSelection(*replacementRange, SEL_DEFAULT_AFFINITY));
targetFrame->editor().setIgnoreCompositionSelectionChange(false);
}
- targetFrame->editor().setComposition(text, underlines, selectionStart, selectionEnd);
+ targetFrame->editor().setComposition(text, underlines, selectionStart, selectionStart + selectionLength);
send(Messages::WebPageProxy::EditorStateChanged(editorState()));
}
@@ -3857,14 +4857,179 @@ void WebPage::cancelComposition()
}
#endif
+#if PLATFORM(MAC)
+static bool needsHiddenContentEditableQuirk(bool needsQuirks, const URL& url)
+{
+ if (!needsQuirks)
+ return false;
+
+ String host = url.host();
+ String path = url.path();
+ return equalLettersIgnoringASCIICase(host, "docs.google.com");
+}
+
+static bool needsPlainTextQuirk(bool needsQuirks, const URL& url)
+{
+ if (!needsQuirks)
+ return false;
+
+ String host = url.host();
+
+ if (equalLettersIgnoringASCIICase(host, "twitter.com"))
+ return true;
+
+ if (equalLettersIgnoringASCIICase(host, "onedrive.live.com"))
+ return true;
+
+ String path = url.path();
+ if (equalLettersIgnoringASCIICase(host, "www.icloud.com") && (path.contains("notes") || url.fragmentIdentifier().contains("notes")))
+ return true;
+
+ if (equalLettersIgnoringASCIICase(host, "trix-editor.org"))
+ return true;
+
+ return false;
+}
+#endif
+
void WebPage::didChangeSelection()
{
+ Frame& frame = m_page->focusController().focusedOrMainFrame();
+ // The act of getting Dictionary Popup info can make selection changes that we should not propagate to the UIProcess.
+ // Specifically, if there is a caret selection, it will change to a range selection of the word around the caret. And
+ // then it will change back.
+ if (frame.editor().isGettingDictionaryPopupInfo())
+ return;
+
+ // Similarly, we don't want to propagate changes to the web process when inserting text asynchronously, since we will
+ // end up with a range selection very briefly right before inserting the text.
+ if (m_isSelectingTextWhileInsertingAsynchronously)
+ return;
+
+ FrameView* view = frame.view();
+
+ // If there is a layout pending, we should avoid populating EditorState that require layout to be done or it will
+ // trigger a synchronous layout every time the selection changes. sendPostLayoutEditorStateIfNeeded() will be called
+ // to send the full editor state after layout is done if we send a partial editor state here.
+ auto editorState = this->editorState(view && view->needsLayout() ? IncludePostLayoutDataHint::No : IncludePostLayoutDataHint::Yes);
+ m_isEditorStateMissingPostLayoutData = editorState.isMissingPostLayoutData;
+
+#if PLATFORM(MAC)
+ bool hasPreviouslyFocusedDueToUserInteraction = m_hasEverFocusedElementDueToUserInteractionSincePageTransition;
+ m_hasEverFocusedElementDueToUserInteractionSincePageTransition |= m_userIsInteracting;
+
+ if (!hasPreviouslyFocusedDueToUserInteraction && m_hasEverFocusedElementDueToUserInteractionSincePageTransition) {
+ if (needsHiddenContentEditableQuirk(m_page->settings().needsSiteSpecificQuirks(), m_page->mainFrame().document()->url())) {
+ m_needsHiddenContentEditableQuirk = true;
+ send(Messages::WebPageProxy::SetNeedsHiddenContentEditableQuirk(m_needsHiddenContentEditableQuirk));
+ }
+
+ if (needsPlainTextQuirk(m_page->settings().needsSiteSpecificQuirks(), m_page->mainFrame().document()->url())) {
+ m_needsPlainTextQuirk = true;
+ send(Messages::WebPageProxy::SetNeedsPlainTextQuirk(m_needsPlainTextQuirk));
+ }
+
+ send(Messages::WebPageProxy::SetHasHadSelectionChangesFromUserInteraction(m_hasEverFocusedElementDueToUserInteractionSincePageTransition));
+ }
+
+ // Abandon the current inline input session if selection changed for any other reason but an input method direct action.
+ // FIXME: This logic should be in WebCore.
+ // FIXME: Many changes that affect composition node do not go through didChangeSelection(). We need to do something when DOM manipulation affects the composition, because otherwise input method's idea about it will be different from Editor's.
+ // FIXME: We can't cancel composition when selection changes to NoSelection, but we probably should.
+ if (frame.editor().hasComposition() && !frame.editor().ignoreCompositionSelectionChange() && !frame.selection().isNone()) {
+ frame.editor().cancelComposition();
+ discardedComposition();
+ } else
+ send(Messages::WebPageProxy::EditorStateChanged(editorState));
+#else
+ send(Messages::WebPageProxy::EditorStateChanged(editorState), pageID(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+#endif
+
+#if PLATFORM(IOS)
+ m_drawingArea->scheduleCompositingLayerFlush();
+#endif
+}
+
+void WebPage::resetAssistedNodeForFrame(WebFrame* frame)
+{
+ if (!m_assistedNode)
+ return;
+ if (frame->isMainFrame() || m_assistedNode->document().frame() == frame->coreFrame()) {
+#if PLATFORM(IOS)
+ send(Messages::WebPageProxy::StopAssistingNode());
+#elif PLATFORM(MAC)
+ send(Messages::WebPageProxy::SetEditableElementIsFocused(false));
+#endif
+ m_assistedNode = nullptr;
+ }
+}
+
+void WebPage::elementDidFocus(WebCore::Node* node)
+{
+ if (m_assistedNode == node && m_isAssistingNodeDueToUserInteraction)
+ return;
+
+ if (node->hasTagName(WebCore::HTMLNames::selectTag) || node->hasTagName(WebCore::HTMLNames::inputTag) || node->hasTagName(WebCore::HTMLNames::textareaTag) || node->hasEditableStyle()) {
+ m_assistedNode = node;
+ m_isAssistingNodeDueToUserInteraction |= m_userIsInteracting;
+
+#if PLATFORM(IOS)
+ AssistedNodeInformation information;
+ getAssistedNodeInformation(information);
+ RefPtr<API::Object> userData;
+
+ m_formClient->willBeginInputSession(this, downcast<Element>(node), WebFrame::fromCoreFrame(*node->document().frame()), userData, m_userIsInteracting);
+
+ send(Messages::WebPageProxy::StartAssistingNode(information, m_userIsInteracting, m_hasPendingBlurNotification, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
+#elif PLATFORM(MAC)
+ if (node->hasTagName(WebCore::HTMLNames::selectTag))
+ send(Messages::WebPageProxy::SetEditableElementIsFocused(false));
+ else
+ send(Messages::WebPageProxy::SetEditableElementIsFocused(true));
+#endif
+ m_hasPendingBlurNotification = false;
+ }
+}
+
+void WebPage::elementDidBlur(WebCore::Node* node)
+{
+ if (m_assistedNode == node) {
+ m_hasPendingBlurNotification = true;
+ RefPtr<WebPage> protectedThis(this);
+ callOnMainThread([protectedThis] {
+ if (protectedThis->m_hasPendingBlurNotification) {
+#if PLATFORM(IOS)
+ protectedThis->send(Messages::WebPageProxy::StopAssistingNode());
+#elif PLATFORM(MAC)
+ protectedThis->send(Messages::WebPageProxy::SetEditableElementIsFocused(false));
+#endif
+ }
+ protectedThis->m_hasPendingBlurNotification = false;
+ });
+
+ m_isAssistingNodeDueToUserInteraction = false;
+ m_assistedNode = nullptr;
+ }
+}
+
+void WebPage::sendPostLayoutEditorStateIfNeeded()
+{
+ if (!m_isEditorStateMissingPostLayoutData)
+ return;
+
+ send(Messages::WebPageProxy::EditorStateChanged(editorState(IncludePostLayoutDataHint::Yes)), pageID(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+ m_isEditorStateMissingPostLayoutData = false;
+}
+
+void WebPage::discardedComposition()
+{
+ send(Messages::WebPageProxy::CompositionWasCanceled());
send(Messages::WebPageProxy::EditorStateChanged(editorState()));
}
-void WebPage::setMainFrameInViewSourceMode(bool inViewSourceMode)
+void WebPage::canceledComposition()
{
- m_mainFrame->coreFrame()->setInViewSourceMode(inViewSourceMode);
+ send(Messages::WebPageProxy::CompositionWasCanceled());
}
void WebPage::setMinimumLayoutSize(const IntSize& minimumLayoutSize)
@@ -3927,12 +5092,15 @@ bool WebPage::canShowMIMEType(const String& MIMEType) const
if (MIMETypeRegistry::canShowMIMEType(MIMEType))
return true;
+ if (!MIMEType.isNull() && m_mimeTypesWithCustomContentProviders.contains(MIMEType))
+ return true;
+
const PluginData& pluginData = m_page->pluginData();
- if (pluginData.supportsMimeType(MIMEType, PluginData::AllPlugins) && corePage()->mainFrame().loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin))
+ if (pluginData.supportsWebVisibleMimeType(MIMEType, PluginData::AllPlugins) && corePage()->mainFrame().loader().subframeLoader().allowPlugins())
return true;
// We can use application plugins even if plugins aren't enabled.
- if (pluginData.supportsMimeType(MIMEType, PluginData::OnlyApplicationPlugins))
+ if (pluginData.supportsWebVisibleMimeType(MIMEType, PluginData::OnlyApplicationPlugins))
return true;
return false;
@@ -3961,8 +5129,36 @@ void WebPage::didCancelCheckingText(uint64_t requestID)
request->didCancel();
}
+void WebPage::willReplaceMultipartContent(const WebFrame& frame)
+{
+#if PLATFORM(IOS)
+ if (!frame.isMainFrame())
+ return;
+
+ m_previousExposedContentRect = m_drawingArea->exposedContentRect();
+#endif
+}
+
+void WebPage::didReplaceMultipartContent(const WebFrame& frame)
+{
+#if PLATFORM(IOS)
+ if (!frame.isMainFrame())
+ return;
+
+ // Restore the previous exposed content rect so that it remains fixed when replacing content
+ // from multipart/x-mixed-replace streams.
+ m_drawingArea->setExposedContentRect(m_previousExposedContentRect);
+#endif
+}
+
void WebPage::didCommitLoad(WebFrame* frame)
{
+#if PLATFORM(IOS)
+ frame->setFirstLayerTreeTransactionIDAfterDidCommitLoad(downcast<RemoteLayerTreeDrawingArea>(*m_drawingArea).nextTransactionID());
+ cancelPotentialTapInFrame(*frame);
+#endif
+ resetAssistedNodeForFrame(frame);
+
if (!frame->isMainFrame())
return;
@@ -3972,17 +5168,56 @@ void WebPage::didCommitLoad(WebFrame* frame)
reportUsedFeatures();
// Only restore the scale factor for standard frame loads (of the main frame).
- if (frame->coreFrame()->loader().loadType() == FrameLoadTypeStandard) {
+ if (frame->coreFrame()->loader().loadType() == FrameLoadType::Standard) {
Page* page = frame->coreFrame()->page();
+
+#if PLATFORM(MAC)
+ // As a very special case, we disable non-default layout modes in WKView for main-frame PluginDocuments.
+ // Ideally we would only worry about this in WKView or the WKViewLayoutStrategies, but if we allow
+ // a round-trip to the UI process, you'll see the wrong scale temporarily. So, we reset it here, and then
+ // again later from the UI process.
+ if (frame->coreFrame()->document()->isPluginDocument()) {
+ scaleView(1);
+ setUseFixedLayout(false);
+ }
+#endif
+
if (page && page->pageScaleFactor() != 1)
scalePage(1, IntPoint());
}
+#if PLATFORM(IOS)
+ m_hasReceivedVisibleContentRectsAfterDidCommitLoad = false;
+ m_scaleWasSetByUIProcess = false;
+ m_userHasChangedPageScaleFactor = false;
+ m_estimatedLatency = Seconds(1.0 / 60);
+
+#if ENABLE(IOS_TOUCH_EVENTS)
+ WebProcess::singleton().eventDispatcher().clearQueuedTouchEventsForPage(*this);
+#endif
+
+ resetViewportDefaultConfiguration(frame);
+ const Frame* coreFrame = frame->coreFrame();
+
+ bool viewportChanged = false;
+ if (m_viewportConfiguration.setContentsSize(coreFrame->view()->contentsSize()))
+ viewportChanged = true;
+
+ if (m_viewportConfiguration.setViewportArguments(coreFrame->document()->viewportArguments()))
+ viewportChanged = true;
+
+ if (viewportChanged)
+ viewportConfigurationChanged();
+#endif
#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
resetPrimarySnapshottedPlugIn();
#endif
- WebProcess::shared().updateActivePages();
+#if USE(OS_STATE)
+ m_loadCommitTime = std::chrono::system_clock::now();
+#endif
+
+ WebProcess::singleton().updateActivePages();
updateMainFrameScrollOffsetPinning();
}
@@ -4002,13 +5237,14 @@ void WebPage::didFinishLoad(WebFrame* frame)
}
#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
-static int primarySnapshottedPlugInSearchLimit = 3000;
-static int primarySnapshottedPlugInSearchGap = 200;
-static float primarySnapshottedPlugInSearchBucketSize = 1.1;
-static int primarySnapshottedPlugInMinimumWidth = 400;
-static int primarySnapshottedPlugInMinimumHeight = 300;
-static unsigned maxPrimarySnapshottedPlugInDetectionAttempts = 2;
-static int deferredPrimarySnapshottedPlugInDetectionDelay = 3;
+static const int primarySnapshottedPlugInSearchLimit = 3000;
+static const float primarySnapshottedPlugInSearchBucketSize = 1.1;
+static const int primarySnapshottedPlugInMinimumWidth = 400;
+static const int primarySnapshottedPlugInMinimumHeight = 300;
+static const unsigned maxPrimarySnapshottedPlugInDetectionAttempts = 2;
+static const int deferredPrimarySnapshottedPlugInDetectionDelay = 3;
+static const float overlappingImageBoundsScale = 1.1;
+static const float minimumOverlappingImageToPluginDimensionScale = .9;
#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
void WebPage::determinePrimarySnapshottedPlugInTimerFired()
@@ -4046,59 +5282,71 @@ void WebPage::determinePrimarySnapshottedPlugIn()
++m_numberOfPrimarySnapshotDetectionAttempts;
- RenderView* renderView = corePage()->mainFrame().view()->renderView();
+ layoutIfNeeded();
+
+ MainFrame& mainFrame = corePage()->mainFrame();
+ if (!mainFrame.view())
+ return;
+ if (!mainFrame.view()->renderView())
+ return;
+ RenderView& mainRenderView = *mainFrame.view()->renderView();
IntRect searchRect = IntRect(IntPoint(), corePage()->mainFrame().view()->contentsSize());
searchRect.intersect(IntRect(IntPoint(), IntSize(primarySnapshottedPlugInSearchLimit, primarySnapshottedPlugInSearchLimit)));
- HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent);
- HashSet<RenderObject*> seenRenderers;
- HTMLPlugInImageElement* candidatePlugIn = 0;
+ HTMLPlugInImageElement* candidatePlugIn = nullptr;
unsigned candidatePlugInArea = 0;
- for (int x = searchRect.x(); x <= searchRect.width(); x += primarySnapshottedPlugInSearchGap) {
- for (int y = searchRect.y(); y <= searchRect.height(); y += primarySnapshottedPlugInSearchGap) {
- HitTestResult hitTestResult = HitTestResult(LayoutPoint(x, y));
- renderView->hitTest(request, hitTestResult);
-
- Element* element = hitTestResult.innerElement();
- if (!element)
- continue;
-
- RenderObject* renderer = element->renderer();
- if (!renderer || !renderer->isBox())
- continue;
-
- RenderBox* renderBox = toRenderBox(renderer);
-
- if (!seenRenderers.add(renderer).isNewEntry)
+ for (Frame* frame = &mainFrame; frame; frame = frame->tree().traverseNextRendered()) {
+ if (!frame->loader().subframeLoader().containsPlugins())
+ continue;
+ if (!frame->document() || !frame->view())
+ continue;
+ for (auto& plugInImageElement : descendantsOfType<HTMLPlugInImageElement>(*frame->document())) {
+ if (plugInImageElement.displayState() == HTMLPlugInElement::Playing)
continue;
- if (!element->isPluginElement())
+ auto pluginRenderer = plugInImageElement.renderer();
+ if (!pluginRenderer || !pluginRenderer->isBox())
continue;
-
- HTMLPlugInElement* plugInElement = toHTMLPlugInElement(element);
- if (!plugInElement->isPlugInImageElement())
+ auto& pluginRenderBox = downcast<RenderBox>(*pluginRenderer);
+ if (!plugInIntersectsSearchRect(plugInImageElement))
continue;
- HTMLPlugInImageElement* plugInImageElement = toHTMLPlugInImageElement(plugInElement);
+ IntRect plugInRectRelativeToView = plugInImageElement.clientRect();
+ ScrollPosition scrollPosition = mainFrame.view()->documentScrollPositionRelativeToViewOrigin();
+ IntRect plugInRectRelativeToTopDocument(plugInRectRelativeToView.location() + scrollPosition, plugInRectRelativeToView.size());
+ HitTestResult hitTestResult(plugInRectRelativeToTopDocument.center());
+ mainRenderView.hitTest(request, hitTestResult);
- if (plugInElement->displayState() == HTMLPlugInElement::Playing)
- continue;
-
- if (renderBox->contentWidth() < primarySnapshottedPlugInMinimumWidth || renderBox->contentHeight() < primarySnapshottedPlugInMinimumHeight)
+ Element* element = hitTestResult.targetElement();
+ if (!element)
continue;
- LayoutUnit contentArea = renderBox->contentWidth() * renderBox->contentHeight();
-
- if (contentArea > candidatePlugInArea * primarySnapshottedPlugInSearchBucketSize) {
- candidatePlugIn = plugInImageElement;
- candidatePlugInArea = contentArea;
+ IntRect elementRectRelativeToView = element->clientRect();
+ IntRect elementRectRelativeToTopDocument(elementRectRelativeToView.location() + scrollPosition, elementRectRelativeToView.size());
+ LayoutRect inflatedPluginRect = plugInRectRelativeToTopDocument;
+ LayoutUnit xOffset = (inflatedPluginRect.width() * overlappingImageBoundsScale - inflatedPluginRect.width()) / 2;
+ LayoutUnit yOffset = (inflatedPluginRect.height() * overlappingImageBoundsScale - inflatedPluginRect.height()) / 2;
+ inflatedPluginRect.inflateX(xOffset);
+ inflatedPluginRect.inflateY(yOffset);
+
+ if (element != &plugInImageElement) {
+ if (!(is<HTMLImageElement>(*element)
+ && inflatedPluginRect.contains(elementRectRelativeToTopDocument)
+ && elementRectRelativeToTopDocument.width() > pluginRenderBox.width() * minimumOverlappingImageToPluginDimensionScale
+ && elementRectRelativeToTopDocument.height() > pluginRenderBox.height() * minimumOverlappingImageToPluginDimensionScale))
+ continue;
+ LOG(Plugins, "Primary Plug-In Detection: Plug-in is hidden by an image that is roughly aligned with it, autoplaying regardless of whether or not it's actually the primary plug-in.");
+ plugInImageElement.restartSnapshottedPlugIn();
}
+
+ if (plugInIsPrimarySize(plugInImageElement, candidatePlugInArea))
+ candidatePlugIn = &plugInImageElement;
}
}
-
if (!candidatePlugIn) {
LOG(Plugins, "Primary Plug-In Detection: fail - did not find a candidate plug-in.");
if (m_numberOfPrimarySnapshotDetectionAttempts < maxPrimarySnapshottedPlugInDetectionAttempts) {
@@ -4132,13 +5380,53 @@ bool WebPage::matchesPrimaryPlugIn(const String& pageOrigin, const String& plugi
return (pageOrigin == m_primaryPlugInPageOrigin && pluginOrigin == m_primaryPlugInOrigin && mimeType == m_primaryPlugInMimeType);
}
+
+bool WebPage::plugInIntersectsSearchRect(HTMLPlugInImageElement& plugInImageElement)
+{
+ MainFrame& mainFrame = corePage()->mainFrame();
+ if (!mainFrame.view())
+ return false;
+ if (!mainFrame.view()->renderView())
+ return false;
+
+ IntRect searchRect = IntRect(IntPoint(), corePage()->mainFrame().view()->contentsSize());
+ searchRect.intersect(IntRect(IntPoint(), IntSize(primarySnapshottedPlugInSearchLimit, primarySnapshottedPlugInSearchLimit)));
+
+ IntRect plugInRectRelativeToView = plugInImageElement.clientRect();
+ if (plugInRectRelativeToView.isEmpty())
+ return false;
+ ScrollPosition scrollPosition = mainFrame.view()->documentScrollPositionRelativeToViewOrigin();
+ IntRect plugInRectRelativeToTopDocument(plugInRectRelativeToView.location() + toIntSize(scrollPosition), plugInRectRelativeToView.size());
+
+ return plugInRectRelativeToTopDocument.intersects(searchRect);
+}
+
+bool WebPage::plugInIsPrimarySize(WebCore::HTMLPlugInImageElement& plugInImageElement, unsigned& candidatePlugInArea)
+{
+ auto* renderer = plugInImageElement.renderer();
+ if (!is<RenderBox>(renderer))
+ return false;
+
+ auto& box = downcast<RenderBox>(*renderer);
+ if (box.contentWidth() < primarySnapshottedPlugInMinimumWidth || box.contentHeight() < primarySnapshottedPlugInMinimumHeight)
+ return false;
+
+ LayoutUnit contentArea = box.contentWidth() * box.contentHeight();
+ if (contentArea > candidatePlugInArea * primarySnapshottedPlugInSearchBucketSize) {
+ candidatePlugInArea = contentArea.toUnsigned();
+ return true;
+ }
+
+ return false;
+}
+
#endif // ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
-PassRefPtr<Range> WebPage::currentSelectionAsRange()
+RefPtr<Range> WebPage::currentSelectionAsRange()
{
- Frame* frame = frameWithSelection(m_page.get());
+ auto* frame = frameWithSelection(m_page.get());
if (!frame)
- return 0;
+ return nullptr;
return frame->selection().toNormalizedRange();
}
@@ -4149,6 +5437,11 @@ void WebPage::reportUsedFeatures()
m_loaderClient.featuresUsedInPage(this, namedFeatures);
}
+void WebPage::updateWebsitePolicies(const WebsitePolicies&)
+{
+ // FIXME: Update the website policies in m_page.
+}
+
unsigned WebPage::extendIncrementalRenderingSuppression()
{
unsigned token = m_maximumRenderingSuppressionToken + 1;
@@ -4177,13 +5470,241 @@ void WebPage::setScrollPinningBehavior(uint32_t pinning)
m_page->mainFrame().view()->setScrollPinningBehavior(m_scrollPinningBehavior);
}
-PassRefPtr<DocumentLoader> WebPage::createDocumentLoader(Frame& frame, const ResourceRequest& request, const SubstituteData& substituteData)
+void WebPage::setScrollbarOverlayStyle(std::optional<uint32_t> scrollbarStyle)
{
- RefPtr<WebDocumentLoader> documentLoader = WebDocumentLoader::create(request, substituteData);
+ if (scrollbarStyle)
+ m_scrollbarOverlayStyle = static_cast<ScrollbarOverlayStyle>(scrollbarStyle.value());
+ else
+ m_scrollbarOverlayStyle = std::optional<ScrollbarOverlayStyle>();
+ m_page->mainFrame().view()->recalculateScrollbarOverlayStyle();
+}
+
+Ref<DocumentLoader> WebPage::createDocumentLoader(Frame& frame, const ResourceRequest& request, const SubstituteData& substituteData)
+{
+ Ref<WebDocumentLoader> documentLoader = WebDocumentLoader::create(request, substituteData);
+
+ if (frame.isMainFrame()) {
+ if (m_pendingNavigationID) {
+ documentLoader->setNavigationID(m_pendingNavigationID);
+ m_pendingNavigationID = 0;
+ }
+ }
+
+ return WTFMove(documentLoader);
+}
+
+void WebPage::updateCachedDocumentLoader(WebDocumentLoader& documentLoader, Frame& frame)
+{
+ if (m_pendingNavigationID && frame.isMainFrame()) {
+ documentLoader.setNavigationID(m_pendingNavigationID);
+ m_pendingNavigationID = 0;
+ }
+}
+
+void WebPage::getBytecodeProfile(uint64_t callbackID)
+{
+ if (!commonVM().m_perBytecodeProfiler) {
+ send(Messages::WebPageProxy::StringCallback(String(), callbackID));
+ return;
+ }
- // FIXME: Set the navigation ID if possible.
+ String result = commonVM().m_perBytecodeProfiler->toJSON();
+ ASSERT(result.length());
+ send(Messages::WebPageProxy::StringCallback(result, callbackID));
+}
- return documentLoader.release();
+void WebPage::getSamplingProfilerOutput(uint64_t callbackID)
+{
+#if ENABLE(SAMPLING_PROFILER)
+ SamplingProfiler* samplingProfiler = commonVM().samplingProfiler();
+ if (!samplingProfiler) {
+ send(Messages::WebPageProxy::InvalidateStringCallback(callbackID));
+ return;
+ }
+
+ StringPrintStream result;
+ samplingProfiler->reportTopFunctions(result);
+ samplingProfiler->reportTopBytecodes(result);
+ send(Messages::WebPageProxy::StringCallback(result.toString(), callbackID));
+#else
+ send(Messages::WebPageProxy::InvalidateStringCallback(callbackID));
+#endif
+}
+
+RefPtr<WebCore::Range> WebPage::rangeFromEditingRange(WebCore::Frame& frame, const EditingRange& range, EditingRangeIsRelativeTo editingRangeIsRelativeTo)
+{
+ ASSERT(range.location != notFound);
+
+ // Sanitize the input, because TextIterator::rangeFromLocationAndLength takes signed integers.
+ if (range.location > INT_MAX)
+ return 0;
+ int length;
+ if (range.length <= INT_MAX && range.location + range.length <= INT_MAX)
+ length = static_cast<int>(range.length);
+ else
+ length = INT_MAX - range.location;
+
+ if (editingRangeIsRelativeTo == EditingRangeIsRelativeTo::EditableRoot) {
+ // Our critical assumption is that this code path is called by input methods that
+ // concentrate on a given area containing the selection.
+ // We have to do this because of text fields and textareas. The DOM for those is not
+ // directly in the document DOM, so serialization is problematic. Our solution is
+ // to use the root editable element of the selection start as the positional base.
+ // That fits with AppKit's idea of an input context.
+ return TextIterator::rangeFromLocationAndLength(frame.selection().rootEditableElementOrDocumentElement(), static_cast<int>(range.location), length);
+ }
+
+ ASSERT(editingRangeIsRelativeTo == EditingRangeIsRelativeTo::Paragraph);
+
+ const VisibleSelection& selection = frame.selection().selection();
+ RefPtr<Range> selectedRange = selection.toNormalizedRange();
+ if (!selectedRange)
+ return 0;
+
+ RefPtr<Range> paragraphRange = makeRange(startOfParagraph(selection.visibleStart()), selection.visibleEnd());
+ if (!paragraphRange)
+ return 0;
+
+ ContainerNode& rootNode = paragraphRange.get()->startContainer().treeScope().rootNode();
+ int paragraphStartIndex = TextIterator::rangeLength(Range::create(rootNode.document(), &rootNode, 0, &paragraphRange->startContainer(), paragraphRange->startOffset()).ptr());
+ return TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + static_cast<int>(range.location), length);
+}
+
+void WebPage::didChangeScrollOffsetForFrame(Frame* frame)
+{
+ if (!frame->isMainFrame())
+ return;
+
+ // If this is called when tearing down a FrameView, the WebCore::Frame's
+ // current FrameView will be null.
+ if (!frame->view())
+ return;
+
+ updateMainFrameScrollOffsetPinning();
+}
+
+void WebPage::postMessage(const String& messageName, API::Object* messageBody)
+{
+ send(Messages::WebPageProxy::HandleMessage(messageName, UserData(WebProcess::singleton().transformObjectsToHandles(messageBody))));
+}
+
+void WebPage::postSynchronousMessageForTesting(const String& messageName, API::Object* messageBody, RefPtr<API::Object>& returnData)
+{
+ UserData returnUserData;
+
+ auto& webProcess = WebProcess::singleton();
+ if (!sendSync(Messages::WebPageProxy::HandleSynchronousMessage(messageName, UserData(webProcess.transformObjectsToHandles(messageBody))), Messages::WebPageProxy::HandleSynchronousMessage::Reply(returnUserData), Seconds::infinity(), IPC::SendSyncOption::UseFullySynchronousModeForTesting))
+ returnData = nullptr;
+ else
+ returnData = webProcess.transformHandlesToObjects(returnUserData.object());
+}
+
+void WebPage::clearWheelEventTestTrigger()
+{
+ if (!m_page)
+ return;
+
+ m_page->clearTrigger();
+}
+
+void WebPage::setShouldScaleViewToFitDocument(bool shouldScaleViewToFitDocument)
+{
+ if (!m_drawingArea)
+ return;
+
+ m_drawingArea->setShouldScaleViewToFitDocument(shouldScaleViewToFitDocument);
+}
+
+void WebPage::imageOrMediaDocumentSizeChanged(const IntSize& newSize)
+{
+ send(Messages::WebPageProxy::ImageOrMediaDocumentSizeChanged(newSize));
+}
+
+void WebPage::addUserScript(const String& source, WebCore::UserContentInjectedFrames injectedFrames, WebCore::UserScriptInjectionTime injectionTime)
+{
+ WebCore::UserScript userScript{ source, WebCore::blankURL(), Vector<String>(), Vector<String>(), injectionTime, injectedFrames };
+
+ m_userContentController->addUserScript(*InjectedBundleScriptWorld::normalWorld(), WTFMove(userScript));
+}
+
+void WebPage::addUserStyleSheet(const String& source, WebCore::UserContentInjectedFrames injectedFrames)
+{
+ WebCore::UserStyleSheet userStyleSheet{ source, WebCore::blankURL(), Vector<String>(), Vector<String>(), injectedFrames, UserStyleUserLevel };
+
+ m_userContentController->addUserStyleSheet(*InjectedBundleScriptWorld::normalWorld(), WTFMove(userStyleSheet));
+}
+
+void WebPage::removeAllUserContent()
+{
+ m_userContentController->removeAllUserContent();
+}
+
+void WebPage::dispatchDidReachLayoutMilestone(WebCore::LayoutMilestones milestones)
+{
+ RefPtr<API::Object> userData;
+ injectedBundleLoaderClient().didReachLayoutMilestone(this, milestones, userData);
+
+ // Clients should not set userData for this message, and it won't be passed through.
+ ASSERT(!userData);
+
+ // The drawing area might want to defer dispatch of didLayout to the UI process.
+ if (m_drawingArea && m_drawingArea->dispatchDidReachLayoutMilestone(milestones))
+ return;
+
+ send(Messages::WebPageProxy::DidReachLayoutMilestone(milestones));
+}
+
+void WebPage::didRestoreScrollPosition()
+{
+ send(Messages::WebPageProxy::DidRestoreScrollPosition());
+}
+
+void WebPage::setResourceCachingDisabled(bool disabled)
+{
+ m_page->setResourceCachingDisabled(disabled);
+}
+
+void WebPage::setUserInterfaceLayoutDirection(uint32_t direction)
+{
+ m_userInterfaceLayoutDirection = static_cast<WebCore::UserInterfaceLayoutDirection>(direction);
+ m_page->setUserInterfaceLayoutDirection(m_userInterfaceLayoutDirection);
+}
+
+#if ENABLE(GAMEPAD)
+
+void WebPage::gamepadActivity(const Vector<GamepadData>& gamepadDatas, bool shouldMakeGamepadsVisible)
+{
+ WebGamepadProvider::singleton().gamepadActivity(gamepadDatas, shouldMakeGamepadsVisible);
+}
+
+#endif
+
+#if ENABLE(POINTER_LOCK)
+void WebPage::didAcquirePointerLock()
+{
+ corePage()->pointerLockController().didAcquirePointerLock();
+}
+
+void WebPage::didNotAcquirePointerLock()
+{
+ corePage()->pointerLockController().didNotAcquirePointerLock();
+}
+
+void WebPage::didLosePointerLock()
+{
+ corePage()->pointerLockController().didLosePointerLock();
+}
+#endif
+
+void WebPage::didGetLoadDecisionForIcon(bool decision, uint64_t loadIdentifier, uint64_t newCallbackID)
+{
+ if (auto* documentLoader = corePage()->mainFrame().loader().documentLoader())
+ documentLoader->didGetLoadDecisionForIcon(decision, loadIdentifier, newCallbackID);
+}
+
+void WebPage::setUseIconLoadingClient(bool useIconLoadingClient)
+{
+ static_cast<WebFrameLoaderClient&>(corePage()->mainFrame().loader().client()).setUseIconLoadingClient(useIconLoadingClient);
}
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h
index 7f50290b6..346d32dc2 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,51 +23,64 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebPage_h
-#define WebPage_h
+#pragma once
+#include "APIInjectedBundleEditorClient.h"
+#include "APIInjectedBundleFormClient.h"
+#include "APIInjectedBundlePageContextMenuClient.h"
+#include "APIInjectedBundlePageUIClient.h"
#include "APIObject.h"
-#include "DrawingArea.h"
+#include "Download.h"
+#include "EditingRange.h"
#include "FindController.h"
#include "GeolocationPermissionRequestManager.h"
#include "ImageOptions.h"
-#include "InjectedBundlePageDiagnosticLoggingClient.h"
-#include "InjectedBundlePageEditorClient.h"
-#include "InjectedBundlePageFormClient.h"
#include "InjectedBundlePageFullScreenClient.h"
#include "InjectedBundlePageLoaderClient.h"
#include "InjectedBundlePagePolicyClient.h"
#include "InjectedBundlePageResourceLoadClient.h"
-#include "InjectedBundlePageUIClient.h"
+#include "LayerTreeContext.h"
#include "MessageReceiver.h"
#include "MessageSender.h"
-#include "TapHighlightController.h"
#include "Plugin.h"
#include "SandboxExtension.h"
#include "ShareableBitmap.h"
-#include "WebUndoStep.h"
+#include "UserData.h"
+#include "UserMediaPermissionRequestManager.h"
+#include <WebCore/ActivityState.h>
#include <WebCore/DictationAlternative.h>
+#include <WebCore/DictionaryPopupInfo.h>
#include <WebCore/DragData.h>
#include <WebCore/Editor.h>
#include <WebCore/FrameLoaderTypes.h>
+#include <WebCore/HitTestResult.h>
+#include <WebCore/HysteresisActivity.h>
#include <WebCore/IntRect.h>
+#include <WebCore/IntSizeHash.h>
#include <WebCore/Page.h>
+#include <WebCore/PageOverlay.h>
#include <WebCore/PageVisibilityState.h>
-#include <WebCore/PlatformScreen.h>
+#include <WebCore/PlatformMouseEvent.h>
#include <WebCore/ScrollTypes.h>
#include <WebCore/TextChecking.h>
+#include <WebCore/TextIndicator.h>
#include <WebCore/UserActivity.h>
-#include <WebCore/ViewState.h>
+#include <WebCore/UserContentTypes.h>
+#include <WebCore/UserInterfaceLayoutDirection.h>
+#include <WebCore/UserScriptTypes.h>
+#include <WebCore/ViewportConfiguration.h>
#include <WebCore/WebCoreKeyboardUIMode.h>
+#include <memory>
#include <wtf/HashMap.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/MonotonicTime.h>
#include <wtf/RefPtr.h>
+#include <wtf/RunLoop.h>
+#include <wtf/Seconds.h>
#include <wtf/text/WTFString.h>
-#if HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
+#if HAVE(ACCESSIBILITY) && PLATFORM(GTK)
#include "WebPageAccessibilityObject.h"
-#include <wtf/gobject/GRefPtr.h>
+#include <wtf/glib/GRefPtr.h>
#endif
#if PLATFORM(GTK)
@@ -75,29 +88,33 @@
#include "WebPrintOperationGtk.h"
#endif
-#if ENABLE(TOUCH_EVENTS)
#if PLATFORM(IOS)
+#include "GestureTypes.h"
+#import "WebPageMessages.h"
+#endif
+
+#if ENABLE(IOS_TOUCH_EVENTS)
#include <WebKitAdditions/PlatformTouchEventIOS.h>
-#else
+#elif ENABLE(TOUCH_EVENTS)
#include <WebCore/PlatformTouchEvent.h>
#endif
+
+#if ENABLE(MAC_GESTURE_EVENTS)
+#include <WebKitAdditions/PlatformGestureEventMac.h>
#endif
#if ENABLE(CONTEXT_MENUS)
#include "InjectedBundlePageContextMenuClient.h"
#endif
-#if PLATFORM(MAC)
-#include "DictionaryPopupInfo.h"
-#include "LayerHostingContext.h"
+#if PLATFORM(COCOA)
#include "ViewGestureGeometryCollector.h"
#include <wtf/RetainPtr.h>
OBJC_CLASS CALayer;
+OBJC_CLASS NSArray;
OBJC_CLASS NSDictionary;
OBJC_CLASS NSObject;
OBJC_CLASS WKAccessibilityWebPageObject;
-
-#define ENABLE_PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC 1
#endif
namespace API {
@@ -105,75 +122,101 @@ class Array;
}
namespace IPC {
- class ArgumentDecoder;
- class Connection;
+class Decoder;
+class Connection;
}
namespace WebCore {
- class GraphicsContext;
- class Frame;
- class FrameView;
- class HTMLPlugInElement;
- class IntPoint;
- class KeyboardEvent;
- class Page;
- class PrintContext;
- class Range;
- class ResourceResponse;
- class ResourceRequest;
- class SharedBuffer;
- class SubstituteData;
- class TextCheckingRequest;
- class URL;
- class VisibleSelection;
- struct KeypressCommand;
- struct TextCheckingResult;
+class DocumentLoader;
+class GraphicsContext;
+class Frame;
+class FrameView;
+class HTMLPlugInElement;
+class HTMLPlugInImageElement;
+class IntPoint;
+class KeyboardEvent;
+class MediaPlaybackTargetContext;
+class Page;
+class PrintContext;
+class Range;
+class ResourceResponse;
+class ResourceRequest;
+class SharedBuffer;
+class SubstituteData;
+class TextCheckingRequest;
+class URL;
+class VisibleSelection;
+struct Highlight;
+struct KeypressCommand;
+struct TextCheckingResult;
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+class MediaPlayerRequestInstallMissingPluginsCallback;
+#endif
}
namespace WebKit {
-
class DrawingArea;
class InjectedBundleBackForwardList;
class NotificationPermissionRequestManager;
+class PDFPlugin;
class PageBanner;
-class PageOverlay;
class PluginView;
-class SessionState;
+class RemoteWebInspectorUI;
+class VisibleContentRectUpdateInfo;
class WebColorChooser;
class WebContextMenu;
class WebContextMenuItemData;
+class WebDocumentLoader;
class WebEvent;
class WebFrame;
class WebFullScreenManager;
class WebImage;
class WebInspector;
class WebInspectorClient;
+class WebInspectorUI;
+class WebGestureEvent;
class WebKeyboardEvent;
class WebMouseEvent;
class WebNotificationClient;
class WebOpenPanelResultListener;
class WebPageGroupProxy;
+class WebPageOverlay;
+class WebPlaybackSessionManager;
class WebPopupMenu;
+class WebUndoStep;
+class WebUserContentController;
+class WebVideoFullscreenManager;
class WebWheelEvent;
+struct AssistedNodeInformation;
struct AttributedString;
+struct BackForwardListItemState;
+struct EditingRange;
struct EditorState;
+class GamepadData;
struct InteractionInformationAtPosition;
+struct InteractionInformationRequest;
+struct LoadParameters;
struct PrintInfo;
+struct WebsitePolicies;
struct WebPageCreationParameters;
struct WebPreferencesStore;
+struct WebSelectionData;
+
+#if PLATFORM(COCOA)
+class RemoteLayerTreeTransaction;
+#endif
#if ENABLE(TOUCH_EVENTS)
class WebTouchEvent;
#endif
-typedef Vector<RefPtr<PageOverlay>> PageOverlayList;
-
class WebPage : public API::ObjectImpl<API::Object::Type::BundlePage>, public IPC::MessageReceiver, public IPC::MessageSender {
public:
- static PassRefPtr<WebPage> create(uint64_t pageID, const WebPageCreationParameters&);
+ static Ref<WebPage> create(uint64_t pageID, WebPageCreationParameters&&);
virtual ~WebPage();
- void reinitializeWebPage(const WebPageCreationParameters&);
+ void reinitializeWebPage(WebPageCreationParameters&&);
void close();
@@ -181,8 +224,10 @@ public:
WebCore::Page* corePage() const { return m_page.get(); }
uint64_t pageID() const { return m_pageID; }
- uint64_t sessionID() const;
- void setSessionID(uint64_t sessionID) { m_sessionID = sessionID; }
+ WebCore::SessionID sessionID() const { return m_page->sessionID(); }
+ bool usesEphemeralSession() const { return m_page->usesEphemeralSession(); }
+
+ void setSessionID(WebCore::SessionID);
void setSize(const WebCore::IntSize&);
const WebCore::IntSize& size() const { return m_viewSize; }
@@ -202,8 +247,25 @@ public:
void centerSelectionInVisibleArea();
-#if ENABLE(INSPECTOR)
- WebInspector* inspector();
+#if PLATFORM(COCOA)
+ void willCommitLayerTree(RemoteLayerTreeTransaction&);
+ void didFlushLayerTreeAtTime(MonotonicTime);
+#endif
+
+ enum class LazyCreationPolicy { UseExistingOnly, CreateIfNeeded };
+
+ WebInspector* inspector(LazyCreationPolicy = LazyCreationPolicy::CreateIfNeeded);
+ WebInspectorUI* inspectorUI();
+ RemoteWebInspectorUI* remoteInspectorUI();
+ bool isInspectorPage() { return !!m_inspectorUI || !!m_remoteInspectorUI; }
+
+#if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+ WebPlaybackSessionManager& playbackSessionManager();
+ WebVideoFullscreenManager& videoFullscreenManager();
+#endif
+#if PLATFORM(IOS)
+ void setAllowsMediaDocumentInlinePlayback(bool);
+ bool allowsMediaDocumentInlinePlayback() const { return m_allowsMediaDocumentInlinePlayback; }
#endif
#if ENABLE(FULLSCREEN_API)
@@ -213,33 +275,38 @@ public:
// -- Called by the DrawingArea.
// FIXME: We could genericize these into a DrawingArea client interface. Would that be beneficial?
void drawRect(WebCore::GraphicsContext&, const WebCore::IntRect&);
- void drawPageOverlay(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect&);
void layoutIfNeeded();
// -- Called from WebCore clients.
-#if PLATFORM(MAC)
- bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*, bool saveCommands);
-#elif !PLATFORM(GTK)
bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*);
-#endif
void didStartPageTransition();
void didCompletePageTransition();
void didCommitLoad(WebFrame*);
+ void willReplaceMultipartContent(const WebFrame&);
+ void didReplaceMultipartContent(const WebFrame&);
void didFinishLoad(WebFrame*);
void show();
String userAgent(const WebCore::URL&) const;
+ String userAgent(WebFrame*, const WebCore::URL&) const;
String platformUserAgent(const WebCore::URL&) const;
- WebCore::IntRect windowResizerRect() const;
WebCore::KeyboardUIMode keyboardUIMode();
+ const String& overrideContentSecurityPolicy() const { return m_overrideContentSecurityPolicy; }
+
WebUndoStep* webUndoStep(uint64_t);
void addWebUndoStep(uint64_t, WebUndoStep*);
void removeWebEditCommand(uint64_t);
bool isInRedo() const { return m_isInRedo; }
+ bool isAlwaysOnLoggingAllowed() const;
void setActivePopupMenu(WebPopupMenu*);
+ void setHiddenPageTimerThrottlingIncreaseLimit(std::chrono::milliseconds limit)
+ {
+ m_page->setTimerAlignmentIntervalIncreaseLimit(limit);
+ }
+
#if ENABLE(INPUT_TYPE_COLOR)
WebColorChooser* activeColorChooser() const { return m_activeColorChooser; }
void setActiveColorChooser(WebColorChooser*);
@@ -248,36 +315,34 @@ public:
#endif
WebOpenPanelResultListener* activeOpenPanelResultListener() const { return m_activeOpenPanelResultListener.get(); }
- void setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener>);
+ void setActiveOpenPanelResultListener(Ref<WebOpenPanelResultListener>&&);
- void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override;
- void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
+ void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
// -- InjectedBundle methods
#if ENABLE(CONTEXT_MENUS)
- void initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClientBase*);
+ void setInjectedBundleContextMenuClient(std::unique_ptr<API::InjectedBundle::PageContextMenuClient>);
#endif
- void initializeInjectedBundleEditorClient(WKBundlePageEditorClientBase*);
- void initializeInjectedBundleFormClient(WKBundlePageFormClientBase*);
+ void setInjectedBundleEditorClient(std::unique_ptr<API::InjectedBundle::EditorClient>);
+ void setInjectedBundleFormClient(std::unique_ptr<API::InjectedBundle::FormClient>);
void initializeInjectedBundleLoaderClient(WKBundlePageLoaderClientBase*);
void initializeInjectedBundlePolicyClient(WKBundlePagePolicyClientBase*);
void initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClientBase*);
- void initializeInjectedBundleUIClient(WKBundlePageUIClientBase*);
+ void setInjectedBundleUIClient(std::unique_ptr<API::InjectedBundle::PageUIClient>);
#if ENABLE(FULLSCREEN_API)
void initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClientBase*);
#endif
- void initializeInjectedBundleDiagnosticLoggingClient(WKBundlePageDiagnosticLoggingClientBase*);
#if ENABLE(CONTEXT_MENUS)
- InjectedBundlePageContextMenuClient& injectedBundleContextMenuClient() { return m_contextMenuClient; }
+ API::InjectedBundle::PageContextMenuClient& injectedBundleContextMenuClient() { return *m_contextMenuClient.get(); }
#endif
- InjectedBundlePageEditorClient& injectedBundleEditorClient() { return m_editorClient; }
- InjectedBundlePageFormClient& injectedBundleFormClient() { return m_formClient; }
+ API::InjectedBundle::EditorClient& injectedBundleEditorClient() { return *m_editorClient.get(); }
+ API::InjectedBundle::FormClient& injectedBundleFormClient() { return *m_formClient.get(); }
InjectedBundlePageLoaderClient& injectedBundleLoaderClient() { return m_loaderClient; }
InjectedBundlePagePolicyClient& injectedBundlePolicyClient() { return m_policyClient; }
InjectedBundlePageResourceLoadClient& injectedBundleResourceLoadClient() { return m_resourceLoadClient; }
- InjectedBundlePageUIClient& injectedBundleUIClient() { return m_uiClient; }
- InjectedBundlePageDiagnosticLoggingClient& injectedBundleDiagnosticLoggingClient() { return m_logDiagnosticMessageClient; }
+ API::InjectedBundle::PageUIClient& injectedBundleUIClient() { return *m_uiClient.get(); }
#if ENABLE(FULLSCREEN_API)
InjectedBundlePageFullScreenClient& injectedBundleFullScreenClient() { return m_fullScreenClient; }
#endif
@@ -286,20 +351,24 @@ public:
WebFrame* mainWebFrame() const { return m_mainFrame.get(); }
- WebCore::Frame* mainFrame() const; // May return 0.
+ WebCore::MainFrame* mainFrame() const; // May return 0.
WebCore::FrameView* mainFrameView() const; // May return 0.
- PassRefPtr<WebCore::Range> currentSelectionAsRange();
+ RefPtr<WebCore::Range> currentSelectionAsRange();
#if ENABLE(NETSCAPE_PLUGIN_API)
- PassRefPtr<Plugin> createPlugin(WebFrame*, WebCore::HTMLPlugInElement*, const Plugin::Parameters&, String& newMIMEType);
+ RefPtr<Plugin> createPlugin(WebFrame*, WebCore::HTMLPlugInElement*, const Plugin::Parameters&, String& newMIMEType);
#endif
#if ENABLE(WEBGL)
WebCore::WebGLLoadPolicy webGLPolicyForURL(WebFrame*, const String&);
-#endif // ENABLE(WEBGL)
+ WebCore::WebGLLoadPolicy resolveWebGLPolicyForURL(WebFrame*, const String&);
+#endif
- EditorState editorState() const;
+ enum class IncludePostLayoutDataHint { No, Yes };
+ EditorState editorState(IncludePostLayoutDataHint = IncludePostLayoutDataHint::Yes) const;
+ void sendPostLayoutEditorStateIfNeeded();
+ void updateEditorStateAfterLayoutIfEditabilityChanged();
String renderTreeExternalRepresentation() const;
String renderTreeExternalRepresentationForPrinting() const;
@@ -308,7 +377,7 @@ public:
void setTracksRepaints(bool);
bool isTrackingRepaints() const;
void resetTrackedRepaints();
- PassRefPtr<API::Array> trackedRepaintRects();
+ Ref<API::Array> trackedRepaintRects();
void executeEditingCommand(const String& commandName, const String& argument);
bool isEditingCommandEnabled(const String& commandName);
@@ -322,52 +391,62 @@ public:
double pageZoomFactor() const;
void setPageZoomFactor(double);
void setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor);
- void windowScreenDidChange(uint64_t);
+ void windowScreenDidChange(uint32_t);
+
+ void accessibilitySettingsDidChange();
void scalePage(double scale, const WebCore::IntPoint& origin);
+ void scalePageInViewCoordinates(double scale, WebCore::IntPoint centerInViewCoordinates);
double pageScaleFactor() const;
+ double totalScaleFactor() const;
+ double viewScaleFactor() const;
+ void scaleView(double scale);
void setUseFixedLayout(bool);
bool useFixedLayout() const { return m_useFixedLayout; }
- void setFixedLayoutSize(const WebCore::IntSize&);
+ bool setFixedLayoutSize(const WebCore::IntSize&);
+ WebCore::IntSize fixedLayoutSize() const;
void listenForLayoutMilestones(uint32_t /* LayoutMilestones */);
void setSuppressScrollbarAnimations(bool);
-
+
+ void setEnableVerticalRubberBanding(bool);
+ void setEnableHorizontalRubberBanding(bool);
+
void setBackgroundExtendsBeyondPage(bool);
void setPaginationMode(uint32_t /* WebCore::Pagination::Mode */);
void setPaginationBehavesLikeColumns(bool);
void setPageLength(double);
void setGapBetweenPages(double);
-
- void postInjectedBundleMessage(const String& messageName, IPC::MessageDecoder&);
+ void setPaginationLineGridEnabled(bool);
+
+ void postInjectedBundleMessage(const String& messageName, const UserData&);
bool drawsBackground() const { return m_drawsBackground; }
- bool drawsTransparentBackground() const { return m_drawsTransparentBackground; }
void setUnderlayColor(const WebCore::Color& color) { m_underlayColor = color; }
WebCore::Color underlayColor() const { return m_underlayColor; }
void stopLoading();
void stopLoadingFrame(uint64_t frameID);
+ bool defersLoading() const;
void setDefersLoading(bool deferLoading);
-#if USE(ACCELERATED_COMPOSITING)
void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*);
void exitAcceleratedCompositingMode();
-#endif
void addPluginView(PluginView*);
void removePluginView(PluginView*);
- bool isVisible() const { return m_viewState & WebCore::ViewState::IsVisible; }
+ bool isVisible() const { return m_activityState & WebCore::ActivityState::IsVisible; }
+ bool isVisibleOrOccluded() const { return m_activityState & WebCore::ActivityState::IsVisibleOrOccluded; }
LayerHostingMode layerHostingMode() const { return m_layerHostingMode; }
- void setLayerHostingMode(unsigned);
+ void setLayerHostingMode(LayerHostingMode);
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void updatePluginsActiveAndFocusedState();
const WebCore::FloatRect& windowFrameInScreenCoordinates() const { return m_windowFrameInScreenCoordinates; }
const WebCore::FloatRect& windowFrameInUnflippedScreenCoordinates() const { return m_windowFrameInUnflippedScreenCoordinates; }
@@ -375,35 +454,41 @@ public:
bool hasCachedWindowFrame() const { return m_hasCachedWindowFrame; }
-#if !PLATFORM(IOS)
- void setTopOverhangImage(PassRefPtr<WebImage>);
- void setBottomOverhangImage(PassRefPtr<WebImage>);
-#endif // !PLATFORM(IOS)
-
void updateHeaderAndFooterLayersForDeviceScaleChange(float scaleFactor);
-#endif // PLATFORM(MAC)
+#endif
+
+#if PLATFORM(MAC)
+ void setTopOverhangImage(WebImage*);
+ void setBottomOverhangImage(WebImage*);
+#endif
bool windowIsFocused() const;
bool windowAndWebPageAreFocused() const;
- void installPageOverlay(PassRefPtr<PageOverlay>, bool shouldFadeIn = false);
- void uninstallPageOverlay(PageOverlay*, bool shouldFadeOut = false);
- bool hasPageOverlay() const { return m_pageOverlays.size(); }
- PageOverlayList& pageOverlays() { return m_pageOverlays; }
#if !PLATFORM(IOS)
- void setHeaderPageBanner(PassRefPtr<PageBanner>);
+ void setHeaderPageBanner(PageBanner*);
PageBanner* headerPageBanner();
- void setFooterPageBanner(PassRefPtr<PageBanner>);
+ void setFooterPageBanner(PageBanner*);
PageBanner* footerPageBanner();
void hidePageBanners();
void showPageBanners();
-#endif // !PLATFORM(IOS)
-
- WebCore::IntPoint screenToWindow(const WebCore::IntPoint&);
- WebCore::IntRect windowToScreen(const WebCore::IntRect&);
+
+ void setHeaderBannerHeightForTesting(int);
+ void setFooterBannerHeightForTesting(int);
+#endif
- PassRefPtr<WebImage> scaledSnapshotWithOptions(const WebCore::IntRect&, double scaleFactor, SnapshotOptions);
+ WebCore::IntPoint screenToRootView(const WebCore::IntPoint&);
+ WebCore::IntRect rootViewToScreen(const WebCore::IntRect&);
+
+#if PLATFORM(IOS)
+ WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&);
+ WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&);
+#endif
+
+ PassRefPtr<WebImage> scaledSnapshotWithOptions(const WebCore::IntRect&, double additionalScaleFactor, SnapshotOptions);
+ PassRefPtr<WebImage> snapshotAtSize(const WebCore::IntRect&, const WebCore::IntSize& bitmapSize, SnapshotOptions);
+ PassRefPtr<WebImage> snapshotNode(WebCore::Node&, SnapshotOptions, unsigned maximumPixelCount = std::numeric_limits<unsigned>::max());
static const WebEvent* currentEvent();
@@ -414,34 +499,115 @@ public:
#endif
#if PLATFORM(IOS)
- void handleTap(const WebCore::IntPoint&);
+ void savePageState(WebCore::HistoryItem&);
+ void restorePageState(const WebCore::HistoryItem&);
+#endif
+
+#if ENABLE(MEDIA_STREAM)
+ UserMediaPermissionRequestManager& userMediaPermissionRequestManager() { return m_userMediaPermissionRequestManager; }
+#endif
+
+ void elementDidFocus(WebCore::Node*);
+ void elementDidBlur(WebCore::Node*);
+ void resetAssistedNodeForFrame(WebFrame*);
+
+ void viewportPropertiesDidChange(const WebCore::ViewportArguments&);
+
+#if PLATFORM(IOS)
+ WebCore::FloatSize screenSize() const;
+ WebCore::FloatSize availableScreenSize() const;
+ int32_t deviceOrientation() const { return m_deviceOrientation; }
+ void didReceiveMobileDocType(bool);
+
+ void setUseTestingViewportConfiguration(bool useTestingViewport) { m_useTestingViewportConfiguration = useTestingViewport; }
+ bool isUsingTestingViewportConfiguration() const { return m_useTestingViewportConfiguration; }
+
+ double minimumPageScaleFactor() const;
+ double maximumPageScaleFactor() const;
+ double maximumPageScaleFactorIgnoringAlwaysScalable() const;
+ bool allowsUserScaling() const;
+ bool hasStablePageScaleFactor() const { return m_hasStablePageScaleFactor; }
+
+ void handleTap(const WebCore::IntPoint&, uint64_t lastLayerTreeTransactionId);
+ void potentialTapAtPosition(uint64_t requestID, const WebCore::FloatPoint&);
+ void commitPotentialTap(uint64_t lastLayerTreeTransactionId);
+ void commitPotentialTapFailed();
+ void cancelPotentialTap();
+ void cancelPotentialTapInFrame(WebFrame&);
void tapHighlightAtPosition(uint64_t requestID, const WebCore::FloatPoint&);
+ void inspectorNodeSearchMovedToPosition(const WebCore::FloatPoint&);
+ void inspectorNodeSearchEndedAtPosition(const WebCore::FloatPoint&);
+
void blurAssistedNode();
- void selectWithGesture(const WebCore::IntPoint&, uint32_t granularity, uint32_t gestureType, uint32_t gestureState, uint64_t callbackID);
+ void selectWithGesture(const WebCore::IntPoint&, uint32_t granularity, uint32_t gestureType, uint32_t gestureState, bool isInteractingWithAssistedNode, uint64_t callbackID);
void updateSelectionWithTouches(const WebCore::IntPoint& point, uint32_t touches, bool baseIsStart, uint64_t callbackID);
+ void updateBlockSelectionWithTouch(const WebCore::IntPoint&, uint32_t touch, uint32_t handlePosition);
void selectWithTwoTouches(const WebCore::IntPoint& from, const WebCore::IntPoint& to, uint32_t gestureType, uint32_t gestureState, uint64_t callbackID);
void extendSelection(uint32_t granularity);
- void elementDidFocus(WebCore::Node*);
- void elementDidBlur(WebCore::Node*);
+ void selectWordBackward();
+ void moveSelectionByOffset(int32_t offset, uint64_t callbackID);
+ void selectTextWithGranularityAtPoint(const WebCore::IntPoint&, uint32_t granularity, bool isInteractingWithAssistedNode, uint64_t callbackID);
+ void selectPositionAtBoundaryWithDirection(const WebCore::IntPoint&, uint32_t granularity, uint32_t direction, bool isInteractingWithAssistedNode, uint64_t callbackID);
+ void moveSelectionAtBoundaryWithDirection(uint32_t granularity, uint32_t direction, uint64_t callbackID);
+ void selectPositionAtPoint(const WebCore::IntPoint&, bool isInteractingWithAssistedNode, uint64_t callbackID);
+ void beginSelectionInDirection(uint32_t direction, uint64_t callbackID);
+ void updateSelectionWithExtentPoint(const WebCore::IntPoint&, bool isInteractingWithAssistedNode, uint64_t callbackID);
+ void updateSelectionWithExtentPointAndBoundary(const WebCore::IntPoint&, uint32_t granularity, bool isInteractingWithAssistedNode, uint64_t callbackID);
+
+ void requestDictationContext(uint64_t callbackID);
+ void replaceDictatedText(const String& oldText, const String& newText);
+ void replaceSelectedText(const String& oldText, const String& newText);
void requestAutocorrectionData(const String& textForAutocorrection, uint64_t callbackID);
void applyAutocorrection(const String& correction, const String& originalText, uint64_t callbackID);
+ void syncApplyAutocorrection(const String& correction, const String& originalText, bool& correctionApplied);
void requestAutocorrectionContext(uint64_t callbackID);
void getAutocorrectionContext(String& beforeText, String& markedText, String& selectedText, String& afterText, uint64_t& location, uint64_t& length);
- void insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd);
- void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd);
- void confirmComposition();
- void getPositionInformation(const WebCore::IntPoint&, InteractionInformationAtPosition&);
- void requestPositionInformation(const WebCore::IntPoint&);
+ void getPositionInformation(const InteractionInformationRequest&, InteractionInformationAtPosition&);
+ void requestPositionInformation(const InteractionInformationRequest&);
+ void startInteractionWithElementAtPosition(const WebCore::IntPoint&);
+ void stopInteraction();
+ void performActionOnElement(uint32_t action);
+ void focusNextAssistedNode(bool isForward, uint64_t callbackID);
+ void setAssistedNodeValue(const String&);
+ void setAssistedNodeValueAsNumber(double);
+ void setAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection);
+ WebCore::IntRect rectForElementAtInteractionLocation();
+ void updateSelectionAppearance();
+ void getSelectionContext(uint64_t callbackID);
+ void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
+ void getRectsForGranularityWithSelectionOffset(uint32_t, int32_t, uint64_t callbackID);
+ void getRectsAtSelectionOffsetWithText(int32_t, const String&, uint64_t callbackID);
+#if ENABLE(IOS_TOUCH_EVENTS)
+ void dispatchAsynchronousTouchEvents(const Vector<WebTouchEvent, 1>& queue);
+#endif
+
+ void contentSizeCategoryDidChange(const String&);
+ void executeEditCommandWithCallback(const String&, uint64_t callbackID);
+
+ Seconds eventThrottlingDelay() const;
+
+ void showInspectorHighlight(const WebCore::Highlight&);
+ void hideInspectorHighlight();
+
+ void showInspectorIndication();
+ void hideInspectorIndication();
+
+ void enableInspectorNodeSearch();
+ void disableInspectorNodeSearch();
+
+ void setForceAlwaysUserScalable(bool);
#endif
+ void setLayerTreeStateIsFrozen(bool);
+ void markLayersVolatile(std::function<void ()> completionHandler = { });
+ void cancelMarkLayersVolatile();
+
NotificationPermissionRequestManager* notificationPermissionRequestManager();
void pageDidScroll();
-#if USE(TILED_BACKING_STORE)
+#if USE(COORDINATED_GRAPHICS)
void pageDidRequestScroll(const WebCore::IntPoint&);
- void setFixedVisibleContentRect(const WebCore::IntRect&);
- void sendViewportAttributesChanged();
#endif
#if ENABLE(CONTEXT_MENUS)
@@ -452,7 +618,7 @@ public:
bool hasLocalDataForURL(const WebCore::URL&);
String cachedResponseMIMETypeForURL(const WebCore::URL&);
String cachedSuggestedFilenameForURL(const WebCore::URL&);
- PassRefPtr<WebCore::SharedBuffer> cachedResponseDataForURL(const WebCore::URL&);
+ RefPtr<WebCore::SharedBuffer> cachedResponseDataForURL(const WebCore::URL&);
static bool canHandleRequest(const WebCore::ResourceRequest&);
@@ -478,23 +644,24 @@ public:
SandboxExtensionTracker& sandboxExtensionTracker() { return m_sandboxExtensionTracker; }
-#if PLATFORM(EFL)
- void setThemePath(const String&);
-#endif
-
-#if USE(TILED_BACKING_STORE)
- void commitPageTransitionViewport();
-#endif
-
#if PLATFORM(GTK)
- void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd);
+ void setComposition(const String& text, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeLength);
void confirmComposition(const String& text, int64_t selectionStart, int64_t selectionLength);
void cancelComposition();
+
+ void collapseSelectionInFrame(uint64_t frameID);
+#endif
+
+#if PLATFORM (GTK) && HAVE(GTK_GESTURES)
+ void getCenterForZoomGesture(const WebCore::IntPoint& centerInViewCoordinates, WebCore::IntPoint& result);
#endif
+ void didApplyStyle();
void didChangeSelection();
+ void discardedComposition();
+ void canceledComposition();
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void registerUIProcessAccessibilityTokens(const IPC::DataReference& elemenToken, const IPC::DataReference& windowToken);
WKAccessibilityWebPageObject* accessibilityRemoteObject();
NSObject *accessibilityObjectForMainFramePlugin();
@@ -502,36 +669,33 @@ public:
void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput);
- void cancelComposition(EditorState& newState);
-#if !PLATFORM(IOS)
- void insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, bool& handled, EditorState& newState);
- void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, EditorState& newState);
- void confirmComposition(EditorState& newState);
-#endif
- void getMarkedRange(uint64_t& location, uint64_t& length);
- void getSelectedRange(uint64_t& location, uint64_t& length);
- void getAttributedSubstringFromRange(uint64_t location, uint64_t length, AttributedString&);
- void characterIndexForPoint(const WebCore::IntPoint point, uint64_t& result);
- void firstRectForCharacterRange(uint64_t location, uint64_t length, WebCore::IntRect& resultRect);
- void executeKeypressCommands(const Vector<WebCore::KeypressCommand>&, bool& handled, EditorState& newState);
+ void insertTextAsync(const String& text, const EditingRange& replacementRange, bool registerUndoGroup = false, uint32_t editingRangeIsRelativeTo = (uint32_t)EditingRangeIsRelativeTo::EditableRoot, bool suppressSelectionUpdate = false);
+ void getMarkedRangeAsync(uint64_t callbackID);
+ void getSelectedRangeAsync(uint64_t callbackID);
+ void characterIndexForPointAsync(const WebCore::IntPoint&, uint64_t callbackID);
+ void firstRectForCharacterRangeAsync(const EditingRange&, uint64_t callbackID);
+ void setCompositionAsync(const String& text, Vector<WebCore::CompositionUnderline> underlines, const EditingRange& selectionRange, const EditingRange& replacementRange);
+ void confirmCompositionAsync();
+
+#if PLATFORM(MAC)
+ void insertDictatedTextAsync(const String& text, const EditingRange& replacementRange, const Vector<WebCore::DictationAlternative>& dictationAlternativeLocations, bool registerUndoGroup = false);
+ void attributedSubstringForCharacterRangeAsync(const EditingRange&, uint64_t callbackID);
+ void fontAtSelection(uint64_t callbackID);
+#endif
+
void readSelectionFromPasteboard(const WTF::String& pasteboardName, bool& result);
void getStringSelectionForPasteboard(WTF::String& stringValue);
void getDataSelectionForPasteboard(const WTF::String pasteboardType, SharedMemory::Handle& handle, uint64_t& size);
void shouldDelayWindowOrderingEvent(const WebKit::WebMouseEvent&, bool& result);
void acceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent&, bool& result);
bool performNonEditingBehaviorForSelector(const String&, WebCore::KeyboardEvent*);
- void insertDictatedText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, const Vector<WebCore::DictationAlternative>& dictationAlternativeLocations, bool& handled, EditorState& newState);
-#elif PLATFORM(EFL)
- void confirmComposition(const String& compositionString);
- void setComposition(const WTF::String& compositionString, const WTF::Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition);
- void cancelComposition();
-#elif PLATFORM(GTK)
-#if USE(TEXTURE_MAPPER_GL)
- void setAcceleratedCompositingWindowId(int64_t nativeWindowHandle);
+
+#if ENABLE(SERVICE_CONTROLS)
+ void replaceSelectionWithPasteboardData(const Vector<String>& types, const IPC::DataReference&);
#endif
#endif
-#if HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
+#if HAVE(ACCESSIBILITY) && PLATFORM(GTK)
void updateAccessibilityTree();
#endif
@@ -543,13 +707,12 @@ public:
// any synchronous messages, and should be removed when <rdar://problem/8775115> is fixed.
void dummy(bool&);
-#if PLATFORM(MAC)
- void performDictionaryLookupForSelection(WebCore::Frame*, const WebCore::VisibleSelection&);
-
+#if PLATFORM(COCOA)
bool isSpeaking();
void speak(const String&);
void stopSpeaking();
+ void performDictionaryLookupForSelection(WebCore::Frame*, const WebCore::VisibleSelection&, WebCore::TextIndicatorPresentationTransition);
#endif
bool isSmartInsertDeleteEnabled();
@@ -560,35 +723,57 @@ public:
void replaceSelectionWithText(WebCore::Frame*, const String&);
void clearSelection();
+ void restoreSelectionInFocusedEditableElement();
#if ENABLE(DRAG_SUPPORT)
#if PLATFORM(GTK)
- void performDragControllerAction(uint64_t action, WebCore::DragData);
+ void performDragControllerAction(uint64_t action, const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t draggingSourceOperationMask, WebSelectionData&&, uint32_t flags);
#else
- void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WTF::String& dragStorageName, uint32_t flags, const SandboxExtension::Handle&, const SandboxExtension::HandleArray&);
+ void performDragControllerAction(uint64_t action, const WebCore::DragData&, const SandboxExtension::Handle&, const SandboxExtension::HandleArray&);
#endif
void dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation);
void willPerformLoadDragDestinationAction();
void mayPerformUploadDragDestinationAction();
+
+ void willStartDrag() { ASSERT(!m_isStartingDrag); m_isStartingDrag = true; }
+ void didStartDrag() { ASSERT(m_isStartingDrag); m_isStartingDrag = false; }
+ void dragCancelled() { m_isStartingDrag = false; }
#endif // ENABLE(DRAG_SUPPORT)
void beginPrinting(uint64_t frameID, const PrintInfo&);
void endPrinting();
void computePagesForPrinting(uint64_t frameID, const PrintInfo&, uint64_t callbackID);
-#if PLATFORM(MAC)
+ void computePagesForPrintingImpl(uint64_t frameID, const PrintInfo&, Vector<WebCore::IntRect>& pageRects, double& totalScaleFactor);
+#if PLATFORM(COCOA)
void drawRectToImage(uint64_t frameID, const PrintInfo&, const WebCore::IntRect&, const WebCore::IntSize&, uint64_t callbackID);
void drawPagesToPDF(uint64_t frameID, const PrintInfo&, uint32_t first, uint32_t count, uint64_t callbackID);
+ void drawPagesToPDFImpl(uint64_t frameID, const PrintInfo&, uint32_t first, uint32_t count, RetainPtr<CFMutableDataRef>& pdfPageData);
+#if PLATFORM(IOS)
+ void computePagesForPrintingAndDrawToPDF(uint64_t frameID, const PrintInfo&, uint64_t callbackID, PassRefPtr<Messages::WebPage::ComputePagesForPrintingAndDrawToPDF::DelayedReply>);
+#endif
#elif PLATFORM(GTK)
void drawPagesForPrinting(uint64_t frameID, const PrintInfo&, uint64_t callbackID);
void didFinishPrintOperation(const WebCore::ResourceError&, uint64_t callbackID);
#endif
+ void addResourceRequest(unsigned long, const WebCore::ResourceRequest&);
+ void removeResourceRequest(unsigned long);
+
void setMediaVolume(float);
+ void setMuted(WebCore::MediaProducer::MutedStateFlags);
void setMayStartMediaWhenInWindow(bool);
+#if ENABLE(MEDIA_SESSION)
+ void handleMediaEvent(uint32_t /* WebCore::MediaEventType */);
+ void setVolumeOfMediaElement(double, uint64_t);
+#endif
+
void updateMainFrameScrollOffsetPinning();
+ bool mainFrameHasCustomContentProvider() const;
+ void addMIMETypeWithCustomContentProvider(const String&);
+
void mainFrameDidLayout();
bool canRunBeforeUnloadConfirmPanel() const { return m_canRunBeforeUnloadConfirmPanel; }
@@ -602,13 +787,11 @@ public:
void setDeviceScaleFactor(float);
float deviceScaleFactor() const;
- void setMemoryCacheMessagesEnabled(bool);
-
void forceRepaintWithoutCallback();
void unmarkAllMisspellings();
void unmarkAllBadGrammar();
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void handleAlternativeTextUIResult(const String&);
#endif
@@ -623,22 +806,42 @@ public:
void wheelEvent(const WebWheelEvent&);
- void numWheelEventHandlersChanged(unsigned);
+ void wheelEventHandlersChanged(bool);
void recomputeShortCircuitHorizontalWheelEventsState();
- void setVisibilityStatePrerender();
+#if ENABLE(MAC_GESTURE_EVENTS)
+ void gestureEvent(const WebGestureEvent&);
+#endif
+
void updateVisibilityState(bool isInitialState = false);
#if PLATFORM(IOS)
- void didFinishScrolling(const WebCore::FloatPoint& contentOffset);
- void didFinishZooming(float);
+ void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&);
+ void setMaximumUnobscuredSize(const WebCore::FloatSize&);
+ void setDeviceOrientation(int32_t);
+ void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID);
+ void synchronizeDynamicViewportUpdate(double& newTargetScale, WebCore::FloatPoint& newScrollPosition, uint64_t& nextValidLayerTreeTransactionID);
+ void updateVisibleContentRects(const VisibleContentRectUpdateInfo&, MonotonicTime oldestTimestamp);
+ bool scaleWasSetByUIProcess() const { return m_scaleWasSetByUIProcess; }
+ void willStartUserTriggeredZooming();
+ void applicationWillResignActive();
+ void applicationDidEnterBackground(bool isSuspendedUnderLock);
+ void applicationDidFinishSnapshottingAfterEnteringBackground();
+ void applicationWillEnterForeground(bool isSuspendedUnderLock);
+ void applicationDidBecomeActive();
+ void zoomToRect(WebCore::FloatRect, double minimumScale, double maximumScale);
+ void completePendingSyntheticClickForContentChangeObserver();
+#endif
+
+#if ENABLE(IOS_TOUCH_EVENTS)
+ void dispatchTouchEvent(const WebTouchEvent&, bool& handled);
#endif
#if PLATFORM(GTK) && USE(TEXTURE_MAPPER_GL)
uint64_t nativeWindowHandle() { return m_nativeWindowHandle; }
#endif
- bool canPluginHandleResponse(const WebCore::ResourceResponse& response);
+ bool shouldUseCustomContentProviderForResponse(const WebCore::ResourceResponse&);
bool asynchronousPluginInitializationEnabled() const { return m_asynchronousPluginInitializationEnabled; }
void setAsynchronousPluginInitializationEnabled(bool enabled) { m_asynchronousPluginInitializationEnabled = enabled; }
@@ -652,14 +855,16 @@ public:
bool scrollingPerformanceLoggingEnabled() const { return m_scrollingPerformanceLoggingEnabled; }
void setScrollingPerformanceLoggingEnabled(bool);
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
bool shouldUsePDFPlugin() const;
bool pdfPluginEnabled() const { return m_pdfPluginEnabled; }
void setPDFPluginEnabled(bool enabled) { m_pdfPluginEnabled = enabled; }
+
+ NSDictionary *dataDetectionContext() const { return m_dataDetectionContext.get(); }
#endif
void savePDFToFileInDownloadsFolder(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size);
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size, const String& pdfUUID);
#endif
@@ -682,6 +887,12 @@ public:
void determinePrimarySnapshottedPlugInTimerFired();
void resetPrimarySnapshottedPlugIn();
bool matchesPrimaryPlugIn(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) const;
+ bool plugInIntersectsSearchRect(WebCore::HTMLPlugInImageElement& pluginImageElement);
+ bool plugInIsPrimarySize(WebCore::HTMLPlugInImageElement& pluginImageElement, unsigned &pluginArea);
+#endif
+
+#if ENABLE(DATA_DETECTION)
+ void setDataDetectionResults(NSArray *);
#endif
unsigned extendIncrementalRenderingSuppression();
@@ -691,75 +902,164 @@ public:
WebCore::ScrollPinningBehavior scrollPinningBehavior() { return m_scrollPinningBehavior; }
void setScrollPinningBehavior(uint32_t /* WebCore::ScrollPinningBehavior */ pinning);
- WKTypeRef pageOverlayCopyAccessibilityAttributeValue(WKStringRef attribute, WKTypeRef parameter);
- WKArrayRef pageOverlayCopyAccessibilityAttributesNames(bool parameterizedNames);
+ std::optional<WebCore::ScrollbarOverlayStyle> scrollbarOverlayStyle() { return m_scrollbarOverlayStyle; }
+ void setScrollbarOverlayStyle(std::optional<uint32_t /* WebCore::ScrollbarOverlayStyle */> scrollbarStyle);
- PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(WebCore::Frame&, const WebCore::ResourceRequest&, const WebCore::SubstituteData&);
+ Ref<WebCore::DocumentLoader> createDocumentLoader(WebCore::Frame&, const WebCore::ResourceRequest&, const WebCore::SubstituteData&);
+ void updateCachedDocumentLoader(WebDocumentLoader&, WebCore::Frame&);
+
+ void getBytecodeProfile(uint64_t callbackID);
+ void getSamplingProfilerOutput(uint64_t callbackID);
+
+#if ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)
+ void handleTelephoneNumberClick(const String& number, const WebCore::IntPoint&);
+ void handleSelectionServiceClick(WebCore::FrameSelection&, const Vector<String>& telephoneNumbers, const WebCore::IntPoint&);
+#endif
+
+ void didChangeScrollOffsetForFrame(WebCore::Frame*);
+
+ void setMainFrameProgressCompleted(bool completed) { m_mainFrameProgressCompleted = completed; }
+ bool shouldDispatchFakeMouseMoveEvents() const { return m_shouldDispatchFakeMouseMoveEvents; }
+
+ void postMessage(const String& messageName, API::Object* messageBody);
+ void postSynchronousMessageForTesting(const String& messageName, API::Object* messageBody, RefPtr<API::Object>& returnData);
+
+#if PLATFORM(GTK)
+ void setInputMethodState(bool);
+#endif
+
+ void imageOrMediaDocumentSizeChanged(const WebCore::IntSize&);
+#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
+ void requestInstallMissingMediaPlugins(const String& details, const String& description, WebCore::MediaPlayerRequestInstallMissingPluginsCallback&);
+#endif
+#endif
+
+ void addUserScript(const String& source, WebCore::UserContentInjectedFrames, WebCore::UserScriptInjectionTime);
+ void addUserStyleSheet(const String& source, WebCore::UserContentInjectedFrames);
+ void removeAllUserContent();
+
+ void dispatchDidReachLayoutMilestone(WebCore::LayoutMilestones);
+
+ void didRestoreScrollPosition();
+
+ bool isControlledByAutomation() const;
+ void setControlledByAutomation(bool);
+
+ void insertNewlineInQuotedContent();
+
+#if USE(OS_STATE)
+ std::chrono::system_clock::time_point loadCommitTime() const { return m_loadCommitTime; }
+#endif
+
+#if ENABLE(GAMEPAD)
+ void gamepadActivity(const Vector<GamepadData>&, bool shouldMakeGamepadsVisible);
+#endif
+
+#if ENABLE(POINTER_LOCK)
+ void didAcquirePointerLock();
+ void didNotAcquirePointerLock();
+ void didLosePointerLock();
+#endif
+
+ void didGetLoadDecisionForIcon(bool decision, uint64_t loadIdentifier, uint64_t newCallbackID);
+ void setUseIconLoadingClient(bool);
private:
- WebPage(uint64_t pageID, const WebPageCreationParameters&);
+ WebPage(uint64_t pageID, WebPageCreationParameters&&);
+
+ void updateThrottleState();
+ void updateUserActivity();
// IPC::MessageSender
- virtual IPC::Connection* messageSenderConnection() override;
- virtual uint64_t messageSenderDestinationID() override;
+ IPC::Connection* messageSenderConnection() override;
+ uint64_t messageSenderDestinationID() override;
void platformInitialize();
+ void platformDetach();
+ void platformEditorState(WebCore::Frame&, EditorState& result, IncludePostLayoutDataHint) const;
- void didReceiveWebPageMessage(IPC::Connection*, IPC::MessageDecoder&);
- void didReceiveSyncWebPageMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&);
+ void didReceiveWebPageMessage(IPC::Connection&, IPC::Decoder&);
+ void didReceiveSyncWebPageMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
-#if !PLATFORM(MAC)
+#if PLATFORM(IOS)
+ void resetViewportDefaultConfiguration(WebFrame* mainFrame);
+ void viewportConfigurationChanged();
+ void updateViewportSizeForCSSViewportUnits();
+
+ static void convertSelectionRectsToRootView(WebCore::FrameView*, Vector<WebCore::SelectionRect>&);
+ PassRefPtr<WebCore::Range> rangeForWebSelectionAtPosition(const WebCore::IntPoint&, const WebCore::VisiblePosition&, SelectionFlags&);
+ PassRefPtr<WebCore::Range> rangeForBlockAtPoint(const WebCore::IntPoint&);
+ void computeExpandAndShrinkThresholdsForHandle(const WebCore::IntPoint&, SelectionHandlePosition, float& growThreshold, float& shrinkThreshold);
+ PassRefPtr<WebCore::Range> changeBlockSelection(const WebCore::IntPoint&, SelectionHandlePosition, float& growThreshold, float& shrinkThreshold, SelectionFlags&);
+ PassRefPtr<WebCore::Range> expandedRangeFromHandle(WebCore::Range*, SelectionHandlePosition);
+ PassRefPtr<WebCore::Range> contractedRangeFromHandle(WebCore::Range* currentRange, SelectionHandlePosition, SelectionFlags&);
+ void getAssistedNodeInformation(AssistedNodeInformation&);
+ void platformInitializeAccessibility();
+ void handleSyntheticClick(WebCore::Node* nodeRespondingToClick, const WebCore::FloatPoint& location);
+ void completeSyntheticClick(WebCore::Node* nodeRespondingToClick, const WebCore::FloatPoint& location, WebCore::SyntheticClickType);
+ void sendTapHighlightForNodeIfNecessary(uint64_t requestID, WebCore::Node*);
+ void resetTextAutosizing();
+ WebCore::VisiblePosition visiblePositionInFocusedNodeForPoint(const WebCore::Frame&, const WebCore::IntPoint&, bool isInteractingWithAssistedNode);
+ PassRefPtr<WebCore::Range> rangeForGranularityAtPoint(const WebCore::Frame&, const WebCore::IntPoint&, uint32_t granularity, bool isInteractingWithAssistedNode);
+ bool shouldSwitchToBlockModeForHandle(const WebCore::IntPoint& handlePoint, SelectionHandlePosition);
+ RefPtr<WebCore::Range> switchToBlockSelectionAtPoint(const WebCore::IntPoint&, SelectionHandlePosition);
+#if ENABLE(DATA_INTERACTION)
+ void requestStartDataInteraction(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
+#endif
+#endif
+
+#if !PLATFORM(COCOA)
static const char* interpretKeyEvent(const WebCore::KeyboardEvent*);
#endif
+
bool performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&);
#if PLATFORM(MAC)
bool executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>&, WebCore::KeyboardEvent*);
#endif
+ bool markLayersVolatileImmediatelyIfPossible();
+ void layerVolatilityTimerFired();
+ void callVolatilityCompletionHandlers();
+
String sourceForFrame(WebFrame*);
- void loadDataImpl(PassRefPtr<WebCore::SharedBuffer>, const String& MIMEType, const String& encodingName, const WebCore::URL& baseURL, const WebCore::URL& failingURL, IPC::MessageDecoder&);
- void loadString(const String&, const String& MIMEType, const WebCore::URL& baseURL, const WebCore::URL& failingURL, IPC::MessageDecoder&);
+ void loadDataImpl(uint64_t navigationID, PassRefPtr<WebCore::SharedBuffer>, const String& MIMEType, const String& encodingName, const WebCore::URL& baseURL, const WebCore::URL& failingURL, const UserData&);
+ void loadStringImpl(uint64_t navigationID, const String&, const String& MIMEType, const WebCore::URL& baseURL, const WebCore::URL& failingURL, const UserData&);
bool platformHasLocalDataForURL(const WebCore::URL&);
// Actions
void tryClose();
- void loadRequest(const WebCore::ResourceRequest&, const SandboxExtension::Handle&, IPC::MessageDecoder&);
- void loadData(const IPC::DataReference&, const String& MIMEType, const String& encodingName, const String& baseURL, IPC::MessageDecoder&);
- void loadHTMLString(const String& htmlString, const String& baseURL, IPC::MessageDecoder&);
- void loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, IPC::MessageDecoder&);
- void loadPlainTextString(const String&, IPC::MessageDecoder&);
- void loadWebArchiveData(const IPC::DataReference&, IPC::MessageDecoder&);
- void reload(bool reloadFromOrigin, const SandboxExtension::Handle&);
- void goForward(uint64_t);
- void goBack(uint64_t);
- void goToBackForwardItem(uint64_t);
+ void platformDidReceiveLoadParameters(const LoadParameters&);
+ void loadRequest(const LoadParameters&);
+ void loadData(const LoadParameters&);
+ void loadString(const LoadParameters&);
+ void loadAlternateHTMLString(const LoadParameters&);
+ void navigateToPDFLinkWithSimulatedClick(const String& url, WebCore::IntPoint documentPoint, WebCore::IntPoint screenPoint);
+ void reload(uint64_t navigationID, bool reloadFromOrigin, bool contentBlockersEnabled, const SandboxExtension::Handle&);
+ void goForward(uint64_t navigationID, uint64_t);
+ void goBack(uint64_t navigationID, uint64_t);
+ void goToBackForwardItem(uint64_t navigationID, uint64_t);
void tryRestoreScrollPosition();
- void setActive(bool);
- void setFocused(bool);
- void setViewIsVisible(bool);
- void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&);
- void setWindowResizerSize(const WebCore::IntSize&);
- void setIsInWindow(bool);
- void setIsVisuallyIdle(bool);
- void setViewState(WebCore::ViewState::Flags, bool wantsDidUpdateViewState);
- void setViewStateInternal(WebCore::ViewState::Flags, bool isInitialState);
+ void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&, uint64_t callbackID);
+ void updateIsInWindow(bool isInitialState = false);
+ void setActivityState(WebCore::ActivityState::Flags, bool wantsDidUpdateActivityState, const Vector<uint64_t>& callbackIDs);
void validateCommand(const String&, uint64_t);
- void executeEditCommand(const String&);
+ void executeEditCommand(const String&, const String&);
+ void setEditable(bool);
void mouseEvent(const WebMouseEvent&);
- void mouseEventSyncForTesting(const WebMouseEvent&, bool&);
- void wheelEventSyncForTesting(const WebWheelEvent&, bool&);
void keyEvent(const WebKeyboardEvent&);
- void keyEventSyncForTesting(const WebKeyboardEvent&, bool&);
-#if ENABLE(TOUCH_EVENTS)
+#if ENABLE(IOS_TOUCH_EVENTS)
+ void touchEventSync(const WebTouchEvent&, bool& handled);
+#elif ENABLE(TOUCH_EVENTS)
void touchEvent(const WebTouchEvent&);
- void touchEventSyncForTesting(const WebTouchEvent&, bool& handled);
#endif
#if ENABLE(CONTEXT_MENUS)
void contextMenuHidden() { m_isShowingContextMenu = false; }
+ void contextMenuForKeyEvent();
#endif
static bool scroll(WebCore::Page*, WebCore::ScrollDirection, WebCore::ScrollGranularity);
@@ -767,20 +1067,29 @@ private:
void loadURLInFrame(const String&, uint64_t frameID);
- uint64_t restoreSession(const SessionState&);
- void restoreSessionAndNavigateToCurrentItem(const SessionState&);
-
+ enum class WasRestoredByAPIRequest { No, Yes };
+ void restoreSessionInternal(const Vector<BackForwardListItemState>&, WasRestoredByAPIRequest);
+ void restoreSession(const Vector<BackForwardListItemState>&);
void didRemoveBackForwardItem(uint64_t);
+#if ENABLE(REMOTE_INSPECTOR)
+ void setAllowsRemoteInspection(bool);
+ void setRemoteInspectionNameOverride(const String&);
+#endif
+
void setDrawsBackground(bool);
- void setDrawsTransparentBackground(bool);
+
+#if HAVE(COREANIMATION_FENCES)
+ void setTopContentInsetFenced(float, IPC::Attachment);
+#endif
+ void setTopContentInset(float);
void viewWillStartLiveResize();
void viewWillEndLiveResize();
void getContentsAsString(uint64_t callbackID);
#if ENABLE(MHTML)
- void getContentsAsMHTMLData(uint64_t callbackID, bool useBinaryEncoding);
+ void getContentsAsMHTMLData(uint64_t callbackID);
#endif
void getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID);
void getResourceDataFromFrame(uint64_t frameID, const String& resourceURL, uint64_t callbackID);
@@ -791,20 +1100,26 @@ private:
void getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID);
void runJavaScriptInMainFrame(const String&, uint64_t callbackID);
void forceRepaint(uint64_t callbackID);
+ void takeSnapshot(WebCore::IntRect snapshotRect, WebCore::IntSize bitmapSize, uint32_t options, uint64_t callbackID);
void preferencesDidChange(const WebPreferencesStore&);
void platformPreferencesDidChange(const WebPreferencesStore&);
void updatePreferences(const WebPreferencesStore&);
- void didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID);
+ void didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, DownloadID);
void setUserAgent(const String&);
void setCustomTextEncodingName(const String&);
void suspendActiveDOMObjectsAndAnimations();
void resumeActiveDOMObjectsAndAnimations();
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
void performDictionaryLookupAtLocation(const WebCore::FloatPoint&);
- void performDictionaryLookupForRange(WebCore::Frame*, WebCore::Range*, NSDictionary *options);
+ void performDictionaryLookupOfCurrentSelection();
+ void performDictionaryLookupForRange(WebCore::Frame*, WebCore::Range&, NSDictionary *options, WebCore::TextIndicatorPresentationTransition);
+ WebCore::DictionaryPopupInfo dictionaryPopupInfoForRange(WebCore::Frame*, WebCore::Range&, NSDictionary **options, WebCore::TextIndicatorPresentationTransition);
+#if ENABLE(PDFKIT_PLUGIN)
+ WebCore::DictionaryPopupInfo dictionaryPopupInfoForSelectionInPDFPlugin(PDFSelection *, PDFPlugin&, NSDictionary **options, WebCore::TextIndicatorPresentationTransition);
+#endif
void windowAndViewFramesChanged(const WebCore::FloatRect& windowFrameInScreenCoordinates, const WebCore::FloatRect& windowFrameInUnflippedScreenCoordinates, const WebCore::FloatRect& viewFrameInWindowCoordinates, const WebCore::FloatPoint& accessibilityViewCoordinates);
@@ -828,7 +1143,7 @@ private:
void countStringMatches(const String&, uint32_t findOptions, uint32_t maxMatchCount);
#if USE(COORDINATED_GRAPHICS)
- void findZoomableAreaForPoint(const WebCore::IntPoint&, const WebCore::IntSize& area);
+ void sendViewportAttributesChanged(const WebCore::ViewportArguments&);
#endif
void didChangeSelectedIndexForActivePopupMenu(int32_t newIndex);
@@ -838,9 +1153,12 @@ private:
void failedToShowPopupMenu();
#endif
+#if PLATFORM(IOS)
+ void didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>&, const String& displayString, const IPC::DataReference& iconData);
+#endif
void didChooseFilesForOpenPanel(const Vector<String>&);
void didCancelForOpenPanel();
-#if ENABLE(WEB_PROCESS_SANDBOX)
+#if ENABLE(SANDBOX_EXTENSIONS)
void extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle&);
#endif
@@ -848,6 +1166,17 @@ private:
void didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed);
+#if ENABLE(MEDIA_STREAM)
+ void userMediaAccessWasGranted(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID);
+ void userMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint);
+
+ void didCompleteMediaDeviceEnumeration(uint64_t userMediaID, const Vector<WebCore::CaptureDevice>& devices, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess);
+#if ENABLE(SANDBOX_EXTENSIONS)
+ void grantUserMediaDeviceSandboxExtensions(const MediaDeviceSandboxExtensions&);
+ void revokeUserMediaDeviceSandboxExtensions(const Vector<String>&);
+#endif
+#endif
+
void advanceToNextMisspelling(bool startBeforeSelection);
void changeSpellingToWord(const String& word);
#if USE(APPKIT)
@@ -862,23 +1191,67 @@ private:
void changeSelectedIndex(int32_t index);
void setCanStartMediaTimerFired();
- void didUpdateViewStateTimerFired();
-
- bool canHandleUserEvents() const;
-
- void setMainFrameInViewSourceMode(bool);
static bool platformCanHandleRequest(const WebCore::ResourceRequest&);
static PluginView* focusedPluginViewForFrame(WebCore::Frame&);
static PluginView* pluginViewForFrame(WebCore::Frame*);
+ static RefPtr<WebCore::Range> rangeFromEditingRange(WebCore::Frame&, const EditingRange&, EditingRangeIsRelativeTo = EditingRangeIsRelativeTo::EditableRoot);
+
void reportUsedFeatures();
+ void updateWebsitePolicies(const WebsitePolicies&);
+
+#if PLATFORM(MAC)
+ void performImmediateActionHitTestAtLocation(WebCore::FloatPoint);
+ RefPtr<WebCore::Range> lookupTextAtLocation(WebCore::FloatPoint, NSDictionary **options);
+ void immediateActionDidUpdate();
+ void immediateActionDidCancel();
+ void immediateActionDidComplete();
+ void setFont(const String& fontFamily, double fontSize, uint64_t fontTraits);
+
+ void dataDetectorsDidPresentUI(WebCore::PageOverlay::PageOverlayID);
+ void dataDetectorsDidChangeUI(WebCore::PageOverlay::PageOverlayID);
+ void dataDetectorsDidHideUI(WebCore::PageOverlay::PageOverlayID);
+
+ void handleAcceptedCandidate(WebCore::TextCheckingResult);
+#endif
+
+#if PLATFORM(COCOA)
+ void requestActiveNowPlayingSessionInfo();
+#endif
+
+ void setShouldDispatchFakeMouseMoveEvents(bool dispatch) { m_shouldDispatchFakeMouseMoveEvents = dispatch; }
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+ void playbackTargetSelected(uint64_t, const WebCore::MediaPlaybackTargetContext& outputDevice) const;
+ void playbackTargetAvailabilityDidChange(uint64_t, bool);
+ void setShouldPlayToPlaybackTarget(uint64_t, bool);
+#endif
+
+ void clearWheelEventTestTrigger();
+
+ void setShouldScaleViewToFitDocument(bool);
+
+ void pageStoppedScrolling();
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+ void didEndRequestInstallMissingMediaPlugins(uint32_t result);
+#endif
+
+ void setResourceCachingDisabled(bool);
+ void setUserInterfaceLayoutDirection(uint32_t);
+
+ bool canPluginHandleResponse(const WebCore::ResourceResponse&);
+
+#if USE(QUICK_LOOK)
+ void didReceivePasswordForQuickLookDocument(const String&);
+#endif
+
uint64_t m_pageID;
- uint64_t m_sessionID;
- OwnPtr<WebCore::Page> m_page;
+ std::unique_ptr<WebCore::Page> m_page;
RefPtr<WebFrame> m_mainFrame;
RefPtr<InjectedBundleBackForwardList> m_backForwardList;
@@ -890,34 +1263,33 @@ private:
std::unique_ptr<DrawingArea> m_drawingArea;
HashSet<PluginView*> m_pluginViews;
- bool m_hasSeenPlugin;
+ bool m_hasSeenPlugin { false };
HashMap<uint64_t, RefPtr<WebCore::TextCheckingRequest>> m_pendingTextCheckingRequestMap;
- bool m_useFixedLayout;
-
- bool m_drawsBackground;
- bool m_drawsTransparentBackground;
+ bool m_useFixedLayout { false };
+ bool m_drawsBackground { true };
WebCore::Color m_underlayColor;
- bool m_isInRedo;
- bool m_isClosed;
-
- bool m_tabToLinks;
+ bool m_isInRedo { false };
+ bool m_isClosed { false };
+ bool m_tabToLinks { false };
- bool m_asynchronousPluginInitializationEnabled;
- bool m_asynchronousPluginInitializationEnabledForAllPlugins;
- bool m_artificialPluginInitializationDelayEnabled;
-
- bool m_scrollingPerformanceLoggingEnabled;
+ bool m_asynchronousPluginInitializationEnabled { false };
+ bool m_asynchronousPluginInitializationEnabledForAllPlugins { false };
+ bool m_artificialPluginInitializationDelayEnabled { false };
+ bool m_scrollingPerformanceLoggingEnabled { false };
+ bool m_mainFrameIsScrollable { true };
- bool m_mainFrameIsScrollable;
+#if PLATFORM(IOS)
+ bool m_ignoreViewportScalingConstraints { false };
+#endif
#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
- bool m_readyToFindPrimarySnapshottedPlugin;
- bool m_didFindPrimarySnapshottedPlugin;
- unsigned m_numberOfPrimarySnapshotDetectionAttempts;
+ bool m_readyToFindPrimarySnapshottedPlugin { false };
+ bool m_didFindPrimarySnapshottedPlugin { false };
+ unsigned m_numberOfPrimarySnapshotDetectionAttempts { 0 };
String m_primaryPlugInPageOrigin;
String m_primaryPlugInOrigin;
String m_primaryPlugInMimeType;
@@ -927,10 +1299,9 @@ private:
// The layer hosting mode.
LayerHostingMode m_layerHostingMode;
-#if PLATFORM(MAC)
- bool m_pdfPluginEnabled;
-
- bool m_hasCachedWindowFrame;
+#if PLATFORM(COCOA)
+ bool m_pdfPluginEnabled { false };
+ bool m_hasCachedWindowFrame { false };
// The frame of the containing window in screen coordinates.
WebCore::FloatRect m_windowFrameInScreenCoordinates;
@@ -946,19 +1317,17 @@ private:
RetainPtr<WKAccessibilityWebPageObject> m_mockAccessibilityElement;
- WebCore::KeyboardEvent* m_keyboardEventBeingInterpreted;
-
-#if !PLATFORM(IOS)
ViewGestureGeometryCollector m_viewGestureGeometryCollector;
-#endif
-#elif HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
+ RetainPtr<NSDictionary> m_dataDetectionContext;
+
+#elif HAVE(ACCESSIBILITY) && PLATFORM(GTK)
GRefPtr<WebPageAccessibilityObject> m_accessibilityObject;
#endif
#if PLATFORM(GTK) && USE(TEXTURE_MAPPER_GL)
// Our view's window in the UI process.
- uint64_t m_nativeWindowHandle;
+ uint64_t m_nativeWindowHandle { 0 };
#endif
#if !PLATFORM(IOS)
@@ -967,32 +1336,35 @@ private:
#endif // !PLATFORM(IOS)
RunLoop::Timer<WebPage> m_setCanStartMediaTimer;
- RunLoop::Timer<WebPage> m_sendDidUpdateViewStateTimer;
- bool m_mayStartMediaWhenInWindow;
+ bool m_mayStartMediaWhenInWindow { false };
HashMap<uint64_t, RefPtr<WebUndoStep>> m_undoStepMap;
- WebCore::IntSize m_windowResizerSize;
-
#if ENABLE(CONTEXT_MENUS)
- InjectedBundlePageContextMenuClient m_contextMenuClient;
+ std::unique_ptr<API::InjectedBundle::PageContextMenuClient> m_contextMenuClient;
#endif
- InjectedBundlePageEditorClient m_editorClient;
- InjectedBundlePageFormClient m_formClient;
+ std::unique_ptr<API::InjectedBundle::EditorClient> m_editorClient;
+ std::unique_ptr<API::InjectedBundle::FormClient> m_formClient;
InjectedBundlePageLoaderClient m_loaderClient;
InjectedBundlePagePolicyClient m_policyClient;
InjectedBundlePageResourceLoadClient m_resourceLoadClient;
- InjectedBundlePageUIClient m_uiClient;
+ std::unique_ptr<API::InjectedBundle::PageUIClient> m_uiClient;
#if ENABLE(FULLSCREEN_API)
InjectedBundlePageFullScreenClient m_fullScreenClient;
#endif
- InjectedBundlePageDiagnosticLoggingClient m_logDiagnosticMessageClient;
FindController m_findController;
- PageOverlayList m_pageOverlays;
-#if ENABLE(INSPECTOR)
RefPtr<WebInspector> m_inspector;
+ RefPtr<WebInspectorUI> m_inspectorUI;
+ RefPtr<RemoteWebInspectorUI> m_remoteInspectorUI;
+
+#if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+ RefPtr<WebPlaybackSessionManager> m_playbackSessionManager;
+ RefPtr<WebVideoFullscreenManager> m_videoFullscreenManager;
+#endif
+#if PLATFORM(IOS)
+ bool m_allowsMediaDocumentInlinePlayback { false };
#endif
#if ENABLE(FULLSCREEN_API)
RefPtr<WebFullScreenManager> m_fullScreenManager;
@@ -1002,16 +1374,22 @@ private:
RefPtr<WebContextMenu> m_contextMenu;
#endif
#if ENABLE(INPUT_TYPE_COLOR)
- WebColorChooser* m_activeColorChooser;
+ WebColorChooser* m_activeColorChooser { nullptr };
#endif
RefPtr<WebOpenPanelResultListener> m_activeOpenPanelResultListener;
RefPtr<NotificationPermissionRequestManager> m_notificationPermissionRequestManager;
+ Ref<WebUserContentController> m_userContentController;
+
#if ENABLE(GEOLOCATION)
GeolocationPermissionRequestManager m_geolocationPermissionRequestManager;
#endif
- OwnPtr<WebCore::PrintContext> m_printContext;
+#if ENABLE(MEDIA_STREAM)
+ UserMediaPermissionRequestManager m_userMediaPermissionRequestManager;
+#endif
+
+ std::unique_ptr<WebCore::PrintContext> m_printContext;
#if PLATFORM(GTK)
RefPtr<WebPrintOperationGtk> m_printOperation;
#endif
@@ -1021,49 +1399,135 @@ private:
RefPtr<SandboxExtension> m_pendingDropSandboxExtension;
Vector<RefPtr<SandboxExtension>> m_pendingDropExtensionsForFileUpload;
- bool m_canRunBeforeUnloadConfirmPanel;
+ WebCore::HysteresisActivity m_pageScrolledHysteresis;
- bool m_canRunModal;
- bool m_isRunningModal;
+ bool m_canRunBeforeUnloadConfirmPanel { false };
- bool m_cachedMainFrameIsPinnedToLeftSide;
- bool m_cachedMainFrameIsPinnedToRightSide;
- bool m_cachedMainFrameIsPinnedToTopSide;
- bool m_cachedMainFrameIsPinnedToBottomSide;
- bool m_canShortCircuitHorizontalWheelEvents;
- unsigned m_numWheelEventHandlers;
+ bool m_canRunModal { false };
+ bool m_isRunningModal { false };
- unsigned m_cachedPageCount;
+#if ENABLE(DRAG_SUPPORT)
+ bool m_isStartingDrag { false };
+#endif
+
+ bool m_cachedMainFrameIsPinnedToLeftSide { true };
+ bool m_cachedMainFrameIsPinnedToRightSide { true };
+ bool m_cachedMainFrameIsPinnedToTopSide { true };
+ bool m_cachedMainFrameIsPinnedToBottomSide { true };
+ bool m_canShortCircuitHorizontalWheelEvents { false };
+ bool m_hasWheelEventHandlers { false };
+
+ unsigned m_cachedPageCount { 0 };
+
+ HashSet<unsigned long> m_trackedNetworkResourceRequestIdentifiers;
WebCore::IntSize m_minimumLayoutSize;
- bool m_autoSizingShouldExpandToViewHeight;
+ bool m_autoSizingShouldExpandToViewHeight { false };
+
+ bool m_userIsInteracting { false };
+ bool m_isAssistingNodeDueToUserInteraction { false };
+ bool m_hasEverFocusedElementDueToUserInteractionSincePageTransition { false };
+ bool m_needsHiddenContentEditableQuirk { false };
+ bool m_needsPlainTextQuirk { false };
#if ENABLE(CONTEXT_MENUS)
- bool m_isShowingContextMenu;
+ bool m_isShowingContextMenu { false };
#endif
+
+ RefPtr<WebCore::Node> m_assistedNode;
+ bool m_hasPendingBlurNotification { false };
#if PLATFORM(IOS)
- RefPtr<WebCore::Node> m_assistedNode;
RefPtr<WebCore::Range> m_currentWordRange;
- bool m_shouldReturnWordAtSelection;
+ RefPtr<WebCore::Node> m_interactionNode;
+ WebCore::IntPoint m_lastInteractionLocation;
+
+ enum SelectionAnchor {
+ Start,
+ End
+ };
+ SelectionAnchor m_selectionAnchor { Start };
+
+ RefPtr<WebCore::Node> m_potentialTapNode;
+ WebCore::FloatPoint m_potentialTapLocation;
+
+ WebCore::ViewportConfiguration m_viewportConfiguration;
+ bool m_hasReceivedVisibleContentRectsAfterDidCommitLoad { false };
+ bool m_scaleWasSetByUIProcess { false };
+ bool m_userHasChangedPageScaleFactor { false };
+ bool m_hasStablePageScaleFactor { true };
+ bool m_useTestingViewportConfiguration { false };
+ bool m_isInStableState { true };
+ bool m_forceAlwaysUserScalable { false };
+ MonotonicTime m_oldestNonStableUpdateVisibleContentRectsTimestamp;
+ Seconds m_estimatedLatency { 0 };
+ WebCore::FloatSize m_screenSize;
+ WebCore::FloatSize m_availableScreenSize;
+ RefPtr<WebCore::Range> m_currentBlockSelection;
+ WebCore::IntRect m_blockRectForTextSelection;
+
+ RefPtr<WebCore::Range> m_initialSelection;
+ WebCore::IntSize m_blockSelectionDesiredSize;
+ WebCore::FloatSize m_maximumUnobscuredSize;
+ int32_t m_deviceOrientation { 0 };
+ bool m_inDynamicSizeUpdate { false };
+ HashMap<std::pair<WebCore::IntSize, double>, WebCore::IntPoint> m_dynamicSizeUpdateHistory;
+ RefPtr<WebCore::Node> m_pendingSyntheticClickNode;
+ WebCore::FloatPoint m_pendingSyntheticClickLocation;
+ WebCore::FloatRect m_previousExposedContentRect;
+#endif
+
+ WebCore::Timer m_layerVolatilityTimer;
+ Vector<std::function<void ()>> m_markLayersAsVolatileCompletionHandlers;
+ bool m_isSuspendedUnderLock { false };
+
+ HashSet<String, ASCIICaseInsensitiveHash> m_mimeTypesWithCustomContentProviders;
+ WebCore::Color m_backgroundColor { WebCore::Color::white };
+
+ HashSet<unsigned> m_activeRenderingSuppressionTokens;
+ unsigned m_maximumRenderingSuppressionToken { 0 };
+
+ WebCore::ScrollPinningBehavior m_scrollPinningBehavior { WebCore::DoNotPin };
+ std::optional<WebCore::ScrollbarOverlayStyle> m_scrollbarOverlayStyle;
+
+ bool m_useAsyncScrolling { false };
+
+ WebCore::ActivityState::Flags m_activityState;
+
+ bool m_processSuppressionEnabled;
+ UserActivity m_userActivity;
+ WebCore::HysteresisActivity m_userActivityHysteresis;
+
+ uint64_t m_pendingNavigationID { 0 };
+
+#if ENABLE(WEBGL)
+ WebCore::WebGLLoadPolicy m_systemWebGLPolicy { WebCore::WebGLAllowCreation };
#endif
- WebInspectorClient* m_inspectorClient;
+ bool m_mainFrameProgressCompleted { false };
+ bool m_shouldDispatchFakeMouseMoveEvents { true };
+ bool m_isEditorStateMissingPostLayoutData { false };
+ bool m_isSelectingTextWhileInsertingAsynchronously { false };
- WebCore::Color m_backgroundColor;
+ enum class EditorStateIsContentEditable { No, Yes, Unset };
+ mutable EditorStateIsContentEditable m_lastEditorStateWasContentEditable { EditorStateIsContentEditable::Unset };
- HashSet<unsigned> m_activeRenderingSuppressionTokens;
- unsigned m_maximumRenderingSuppressionToken;
-
- WebCore::ScrollPinningBehavior m_scrollPinningBehavior;
+#if PLATFORM(GTK)
+ bool m_inputMethodEnabled { false };
+#endif
- bool m_useAsyncScrolling;
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+ RefPtr<WebCore::MediaPlayerRequestInstallMissingPluginsCallback> m_installMediaPluginsCallback;
+#endif
+
+#if USE(OS_STATE)
+ std::chrono::system_clock::time_point m_loadCommitTime;
+#endif
- WebCore::ViewState::Flags m_viewState;
+ WebCore::UserInterfaceLayoutDirection m_userInterfaceLayoutDirection { WebCore::UserInterfaceLayoutDirection::LTR };
- UserActivity m_processSuppressionDisabledByWebPreference;
+ const String m_overrideContentSecurityPolicy;
};
} // namespace WebKit
-#endif // WebPage_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
index fdeb9c6c4..8459458ae 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+# Copyright (C) 2010-2016 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -21,14 +21,16 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
messages -> WebPage LegacyReceiver {
- SetInitialFocus(bool forward, bool isKeyboardEventValid, WebKit::WebKeyboardEvent event)
- SetViewState(unsigned viewState, bool wantsDidUpdateViewState)
- SetLayerHostingMode(unsigned layerHostingMode)
-
- SetSessionID(uint64_t sessionID)
+ SetInitialFocus(bool forward, bool isKeyboardEventValid, WebKit::WebKeyboardEvent event, uint64_t callbackID)
+ SetActivityState(unsigned activityState, bool wantsDidUpdateActivityState, Vector<uint64_t> callbackIDs)
+ SetLayerHostingMode(enum WebKit::LayerHostingMode layerHostingMode)
SetDrawsBackground(bool drawsBackground)
- SetDrawsTransparentBackground(bool drawsTransparentBackground)
+
+#if HAVE(COREANIMATION_FENCES)
+ SetTopContentInsetFenced(float contentInset, IPC::Attachment fencePort)
+#endif
+ SetTopContentInset(float contentInset)
SetUnderlayColor(WebCore::Color color)
@@ -36,32 +38,80 @@ messages -> WebPage LegacyReceiver {
ViewWillEndLiveResize()
KeyEvent(WebKit::WebKeyboardEvent event)
- KeyEventSyncForTesting(WebKit::WebKeyboardEvent event) -> (bool handled)
MouseEvent(WebKit::WebMouseEvent event)
- MouseEventSyncForTesting(WebKit::WebMouseEvent event) -> (bool handled)
- WheelEventSyncForTesting(WebKit::WebWheelEvent event) -> (bool handled)
#if PLATFORM(IOS)
- HandleTap(WebCore::IntPoint point)
+ SetViewportConfigurationMinimumLayoutSize(WebCore::FloatSize size)
+ SetMaximumUnobscuredSize(WebCore::FloatSize size)
+ SetDeviceOrientation(int32_t deviceOrientation)
+ DynamicViewportSizeUpdate(WebCore::FloatSize minimumLayoutSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
+ SynchronizeDynamicViewportUpdate() -> (double newTargetScale, WebCore::FloatPoint newScrollPosition, uint64_t nextValidLayerTreeTransactionID)
+
+ HandleTap(WebCore::IntPoint point, uint64_t lastLayerTreeTransactionId)
+ PotentialTapAtPosition(uint64_t requestID, WebCore::FloatPoint point)
+ CommitPotentialTap(uint64_t lastLayerTreeTransactionId)
+ CancelPotentialTap()
TapHighlightAtPosition(uint64_t requestID, WebCore::FloatPoint point)
+ InspectorNodeSearchMovedToPosition(WebCore::FloatPoint point)
+ InspectorNodeSearchEndedAtPosition(WebCore::FloatPoint point)
BlurAssistedNode()
- SelectWithGesture(WebCore::IntPoint point, uint32_t granularity, uint32_t gestureType, uint32_t gestureState, uint64_t callbackID)
+ SelectWithGesture(WebCore::IntPoint point, uint32_t granularity, uint32_t gestureType, uint32_t gestureState, bool isInteractingWithAssistedNode, uint64_t callbackID)
UpdateSelectionWithTouches(WebCore::IntPoint point, uint32_t touches, bool baseIsStart, uint64_t callbackID)
+ UpdateBlockSelectionWithTouch(WebCore::IntPoint point, uint32_t touch, uint32_t handlePosition)
SelectWithTwoTouches(WebCore::IntPoint from, WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, uint64_t callbackID)
ExtendSelection(uint32_t granularity)
+ SelectWordBackward()
+ MoveSelectionByOffset(int32_t offset, uint64_t callbackID)
+ SelectTextWithGranularityAtPoint(WebCore::IntPoint point, uint32_t granularity, bool isInteractingWithAssistedNode, uint64_t callbackID)
+ SelectPositionAtBoundaryWithDirection(WebCore::IntPoint point, uint32_t granularity, uint32_t direction, bool isInteractingWithAssistedNode, uint64_t callbackID)
+ MoveSelectionAtBoundaryWithDirection(uint32_t granularity, uint32_t direction, uint64_t callbackID)
+ SelectPositionAtPoint(WebCore::IntPoint point, bool isInteractingWithAssistedNode, uint64_t callbackID)
+ BeginSelectionInDirection(uint32_t direction, uint64_t callbackID)
+ UpdateSelectionWithExtentPoint(WebCore::IntPoint point, bool isInteractingWithAssistedNode, uint64_t callbackID)
+ UpdateSelectionWithExtentPointAndBoundary(WebCore::IntPoint point, uint32_t granularity, bool isInteractingWithAssistedNode, uint64_t callbackID)
+ RequestDictationContext(uint64_t callbackID)
+ ReplaceDictatedText(String oldText, String newText)
+ ReplaceSelectedText(String oldText, String newText)
RequestAutocorrectionData(String textForAutocorrection, uint64_t callbackID)
ApplyAutocorrection(String correction, String originalText, uint64_t callbackID)
+ SyncApplyAutocorrection(String correction, String originalText) -> (bool autocorrectionApplied)
RequestAutocorrectionContext(uint64_t callbackID)
GetAutocorrectionContext() -> (String beforeContext, String markedText, String selectedText, String afterContext, uint64_t location, uint64_t length)
- InsertText(String text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd)
- SetComposition(String text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd)
- ConfirmComposition()
- GetPositionInformation(WebCore::IntPoint point) -> (WebKit::InteractionInformationAtPosition information)
- RequestPositionInformation(WebCore::IntPoint point)
+ GetPositionInformation(struct WebKit::InteractionInformationRequest request) -> (struct WebKit::InteractionInformationAtPosition information)
+ RequestPositionInformation(struct WebKit::InteractionInformationRequest request)
+ StartInteractionWithElementAtPosition(WebCore::IntPoint point)
+ StopInteraction()
+ PerformActionOnElement(uint32_t action)
+ FocusNextAssistedNode(bool isForward, uint64_t callbackID)
+ SetAssistedNodeValue(String value)
+ SetAssistedNodeValueAsNumber(double value)
+ SetAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection)
+ ApplicationWillResignActive()
+ ApplicationDidEnterBackground(bool isSuspendedUnderLock)
+ ApplicationDidFinishSnapshottingAfterEnteringBackground()
+ ApplicationWillEnterForeground(bool isSuspendedUnderLock)
+ ApplicationDidBecomeActive()
+ ContentSizeCategoryDidChange(String contentSizeCategory)
+ ExecuteEditCommandWithCallback(String name, uint64_t callbackID)
+ GetSelectionContext(uint64_t callbackID)
+ SetAllowsMediaDocumentInlinePlayback(bool allows)
+ HandleTwoFingerTapAtPoint(WebCore::IntPoint point, uint64_t requestID)
+ SetForceAlwaysUserScalable(bool userScalable)
+ GetRectsForGranularityWithSelectionOffset(uint32_t granularity, int32_t offset, uint64_t callbackID);
+ GetRectsAtSelectionOffsetWithText(int32_t offset, String text, uint64_t callbackID);
#endif
-#if ENABLE(TOUCH_EVENTS)
+ SetControlledByAutomation(bool controlled)
+
+#if ENABLE(REMOTE_INSPECTOR)
+ SetAllowsRemoteInspection(bool allow)
+ SetRemoteInspectionNameOverride(String name)
+#endif
+
+#if ENABLE(IOS_TOUCH_EVENTS)
+ TouchEventSync(WebKit::WebTouchEvent event) -> (bool handled)
+#endif
+#if !ENABLE(IOS_TOUCH_EVENTS) && ENABLE(TOUCH_EVENTS)
TouchEvent(WebKit::WebTouchEvent event)
- TouchEventSyncForTesting(WebKit::WebTouchEvent event) -> (bool handled)
#endif
#if ENABLE(INPUT_TYPE_COLOR)
@@ -71,42 +121,44 @@ messages -> WebPage LegacyReceiver {
#if ENABLE(CONTEXT_MENUS)
ContextMenuHidden()
+ ContextMenuForKeyEvent()
#endif
ScrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
CenterSelectionInVisibleArea()
- GoBack(uint64_t backForwardItemID)
- GoForward(uint64_t backForwardItemID)
- GoToBackForwardItem(uint64_t backForwardItemID)
+ GoBack(uint64_t navigationID, uint64_t backForwardItemID)
+ GoForward(uint64_t navigationID, uint64_t backForwardItemID)
+ GoToBackForwardItem(uint64_t navigationID, uint64_t backForwardItemID)
TryRestoreScrollPosition()
LoadURLInFrame(String url, uint64_t frameID)
- LoadRequest(WebCore::ResourceRequest request, WebKit::SandboxExtension::Handle sandboxExtensionHandle, WebKit::WebContextUserMessageEncoder userData) Variadic
- LoadData(IPC::DataReference data, String MIMEType, String encoding, String baseURL, WebKit::WebContextUserMessageEncoder userData) Variadic
- LoadHTMLString(String htmlString, String baseURL, WebKit::WebContextUserMessageEncoder userData) Variadic
- LoadAlternateHTMLString(String htmlString, String baseURL, String unreachableURL, WebKit::WebContextUserMessageEncoder userData) Variadic
- LoadPlainTextString(String string, WebKit::WebContextUserMessageEncoder userData) Variadic
- LoadWebArchiveData(IPC::DataReference webArchiveData, WebKit::WebContextUserMessageEncoder userData) Variadic
-
- Reload(bool reloadFromOrigin, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+ LoadRequest(struct WebKit::LoadParameters loadParameters)
+ LoadData(struct WebKit::LoadParameters loadParameters)
+ LoadString(struct WebKit::LoadParameters loadParameters)
+ LoadAlternateHTMLString(struct WebKit::LoadParameters loadParameters)
+
+ NavigateToPDFLinkWithSimulatedClick(String url, WebCore::IntPoint documentPoint, WebCore::IntPoint screenPoint)
+
+ Reload(uint64_t navigationID, bool reloadFromOrigin, bool contentBlockersEnabled, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
StopLoading()
StopLoadingFrame(uint64_t frameID)
- RestoreSession(WebKit::SessionState state)
- RestoreSessionAndNavigateToCurrentItem(WebKit::SessionState state)
+ RestoreSession(Vector<WebKit::BackForwardListItemState> itemStates)
DidRemoveBackForwardItem(uint64_t backForwardItemID)
- DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
+ UpdateWebsitePolicies(struct WebKit::WebsitePolicies websitePolicies)
+ DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, WebKit::DownloadID downloadID)
ClearSelection()
+ RestoreSelectionInFocusedEditableElement()
# Callbacks.
GetContentsAsString(uint64_t callbackID)
#if ENABLE(MHTML)
- GetContentsAsMHTMLData(uint64_t callbackID, bool useBinaryEncoding)
+ GetContentsAsMHTMLData(uint64_t callbackID)
#endif
GetMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
GetResourceDataFromFrame(uint64_t frameID, String resourceURL, uint64_t callbackID)
@@ -118,12 +170,17 @@ messages -> WebPage LegacyReceiver {
RunJavaScriptInMainFrame(String script, uint64_t callbackID)
ForceRepaint(uint64_t callbackID)
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
# Dictionary support.
PerformDictionaryLookupAtLocation(WebCore::FloatPoint point)
#endif
- PreferencesDidChange(WebKit::WebPreferencesStore store)
+#if PLATFORM(MAC)
+ PerformDictionaryLookupOfCurrentSelection()
+ SetFont(String fontFamily, double fontSize, uint64_t fontTraits)
+#endif
+
+ PreferencesDidChange(struct WebKit::WebPreferencesStore store)
SetUserAgent(String userAgent)
SetCustomTextEncodingName(String encodingName)
@@ -134,8 +191,9 @@ messages -> WebPage LegacyReceiver {
Close()
TryClose()
+ SetEditable(bool editable)
ValidateCommand(String name, uint64_t callbackID)
- ExecuteEditCommand(String name)
+ ExecuteEditCommand(String name, String argument)
DidRemoveEditCommand(uint64_t commandID)
ReapplyEditCommand(uint64_t commandID)
@@ -144,23 +202,31 @@ messages -> WebPage LegacyReceiver {
SetPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
SetPageZoomFactor(double zoomFactor)
SetTextZoomFactor(double zoomFactor)
- WindowScreenDidChange(uint64_t displayID)
+ WindowScreenDidChange(uint32_t displayID)
+
+ AccessibilitySettingsDidChange()
ScalePage(double scale, WebCore::IntPoint origin)
+ ScalePageInViewCoordinates(double scale, WebCore::IntPoint centerInViewCoordinates)
+ ScaleView(double scale)
SetUseFixedLayout(bool fixed)
SetFixedLayoutSize(WebCore::IntSize size)
ListenForLayoutMilestones(uint32_t milestones)
SetSuppressScrollbarAnimations(bool suppressAnimations)
+ SetEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
+ SetEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
+
SetBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
SetPaginationMode(uint32_t mode)
SetPaginationBehavesLikeColumns(bool behavesLikeColumns)
SetPageLength(double pageLength)
SetGapBetweenPages(double gap)
+ SetPaginationLineGridEnabled(bool lineGridEnabled)
- PostInjectedBundleMessage(String messageName, WebKit::WebContextUserMessageEncoder messageBody) Variadic
+ PostInjectedBundleMessage(String messageName, WebKit::UserData messageBody)
# Find.
FindString(String string, uint32_t findOptions, unsigned maxMatchCount)
@@ -169,16 +235,24 @@ messages -> WebPage LegacyReceiver {
SelectFindMatch(uint32_t matchIndex)
HideFindUI()
CountStringMatches(String string, uint32_t findOptions, unsigned maxMatchCount)
+
+ AddMIMETypeWithCustomContentProvider(String mimeType)
# Drag and drop.
#if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
- PerformDragControllerAction(uint64_t action, WebCore::DragData dragData)
+ PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, struct WebKit::WebSelectionData selection, uint32_t flags)
#endif
#if !PLATFORM(GTK) && ENABLE(DRAG_SUPPORT)
- PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, String dragStorageName, uint32_t flags, WebKit::SandboxExtension::Handle sandboxExtensionHandle, WebKit::SandboxExtension::HandleArray sandboxExtensionsForUpload)
+ PerformDragControllerAction(uint64_t action, WebCore::DragData dragData, WebKit::SandboxExtension::Handle sandboxExtensionHandle, WebKit::SandboxExtension::HandleArray sandboxExtensionsForUpload)
#endif
#if ENABLE(DRAG_SUPPORT)
+ DidStartDrag()
DragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
+ DragCancelled()
+#endif
+
+#if ENABLE(DATA_INTERACTION)
+ RequestStartDataInteraction(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition)
#endif
# Popup menu.
@@ -194,9 +268,12 @@ messages -> WebPage LegacyReceiver {
#endif
# Open panel.
+#if PLATFORM(IOS)
+ DidChooseFilesForOpenPanelWithDisplayStringAndIcon(Vector<String> fileURLs, String displayString, IPC::DataReference iconData)
+#endif
DidChooseFilesForOpenPanel(Vector<String> fileURLs)
DidCancelForOpenPanel()
-#if ENABLE(WEB_PROCESS_SANDBOX)
+#if ENABLE(SANDBOX_EXTENSIONS)
ExtendSandboxForFileFromOpenPanel(WebKit::SandboxExtension::Handle sandboxExtensionHandle)
#endif
@@ -210,7 +287,7 @@ messages -> WebPage LegacyReceiver {
LowercaseWord()
CapitalizeWord()
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
SetSmartInsertDeleteEnabled(bool isSmartInsertDeleteEnabled)
#endif
@@ -219,28 +296,44 @@ messages -> WebPage LegacyReceiver {
DidReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
#endif
+#if ENABLE(MEDIA_STREAM)
+ # MediaSteam
+ UserMediaAccessWasGranted(uint64_t userMediaID, String audioDeviceUID, String videoDeviceUID)
+ UserMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String invalidConstraint)
+ DidCompleteMediaDeviceEnumeration(uint64_t userMediaID, Vector<WebCore::CaptureDevice> devices, String mediaDeviceIdentifierHashSalt, bool hasPersistentAccess)
+#if ENABLE(SANDBOX_EXTENSIONS)
+ GrantUserMediaDeviceSandboxExtensions(WebKit::MediaDeviceSandboxExtensions sandboxExtensions)
+ RevokeUserMediaDeviceSandboxExtensions(Vector<String> sandboxExtensionIDs)
+#endif
+#endif
+
# Notification
DidReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)
- SetWindowResizerSize(WebCore::IntSize intersectsView)
-
# Printing.
- BeginPrinting(uint64_t frameID, WebKit::PrintInfo printInfo)
+ BeginPrinting(uint64_t frameID, struct WebKit::PrintInfo printInfo)
EndPrinting()
- ComputePagesForPrinting(uint64_t frameID, WebKit::PrintInfo printInfo, uint64_t callbackID)
-#if PLATFORM(MAC)
- DrawRectToImage(uint64_t frameID, WebKit::PrintInfo printInfo, WebCore::IntRect rect, WebCore::IntSize imageSize, uint64_t callbackID)
- DrawPagesToPDF(uint64_t frameID, WebKit::PrintInfo printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
+ ComputePagesForPrinting(uint64_t frameID, struct WebKit::PrintInfo printInfo, uint64_t callbackID)
+#if PLATFORM(COCOA)
+ DrawRectToImage(uint64_t frameID, struct WebKit::PrintInfo printInfo, WebCore::IntRect rect, WebCore::IntSize imageSize, uint64_t callbackID)
+ DrawPagesToPDF(uint64_t frameID, struct WebKit::PrintInfo printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
+#if PLATFORM(IOS)
+ ComputePagesForPrintingAndDrawToPDF(uint64_t frameID, struct WebKit::PrintInfo printInfo, uint64_t callbackID) -> (uint32_t pageCount) Delayed
+#endif
#endif
#if PLATFORM(GTK)
- DrawPagesForPrinting(uint64_t frameID, WebKit::PrintInfo printInfo, uint64_t callbackID)
+ DrawPagesForPrinting(uint64_t frameID, struct WebKit::PrintInfo printInfo, uint64_t callbackID)
#endif
# Media
SetMediaVolume(float volume)
+ SetMuted(WebCore::MediaProducer::MutedStateFlags muted)
SetMayStartMediaWhenInWindow(bool mayStartMedia)
- SetMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled)
+#if ENABLE(MEDIA_SESSION)
+ HandleMediaEvent(uint32_t eventType)
+ SetVolumeOfMediaElement(double volume, uint64_t elementID)
+#endif
// FIXME: This a dummy message, to avoid breaking the build for platforms that don't require
// any synchronous messages, and should be removed when <rdar://problem/8775115> is fixed.
@@ -249,21 +342,19 @@ messages -> WebPage LegacyReceiver {
SetCanRunBeforeUnloadConfirmPanel(bool canRunBeforeUnloadConfirmPanel)
SetCanRunModal(bool canRunModal)
-#if PLATFORM(EFL)
- SetThemePath(String themePath)
-#endif
-
-#if USE(TILED_BACKING_STORE)
- CommitPageTransitionViewport()
-#endif
-
#if PLATFORM(GTK)
SetComposition(String text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd)
ConfirmComposition(String text, int64_t selectionStart, int64_t selectionLength)
CancelComposition()
+
+ CollapseSelectionInFrame(uint64_t frameID)
#endif
-#if PLATFORM(MAC)
+#if PLATFORM (GTK) && HAVE(GTK_GESTURES)
+ GetCenterForZoomGesture(WebCore::IntPoint centerInViewCoordinates) -> (WebCore::IntPoint center)
+#endif
+
+#if PLATFORM(COCOA)
# Complex text input support for plug-ins.
SendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, String textInput)
@@ -274,51 +365,99 @@ messages -> WebPage LegacyReceiver {
GetDataSelectionForPasteboard(String pasteboardType) -> (WebKit::SharedMemory::Handle handle, uint64_t size)
ReadSelectionFromPasteboard(String pasteboardName) -> (bool result)
- # Text input.
- CancelComposition() -> (WebKit::EditorState newState)
- GetMarkedRange() -> (uint64_t location, uint64_t length)
- GetSelectedRange() -> (uint64_t location, uint64_t length)
- GetAttributedSubstringFromRange(uint64_t location, uint64_t length) -> (WebKit::AttributedString result)
- CharacterIndexForPoint(WebCore::IntPoint point) -> (uint64_t result)
- FirstRectForCharacterRange(uint64_t location, uint64_t length) -> (WebCore::IntRect resultRect)
- ExecuteKeypressCommands(Vector<WebCore::KeypressCommand> savedCommands) -> (bool handled, WebKit::EditorState newState)
+#if ENABLE(SERVICE_CONTROLS)
+ ReplaceSelectionWithPasteboardData(Vector<String> types, IPC::DataReference data)
+#endif
+
ShouldDelayWindowOrderingEvent(WebKit::WebMouseEvent event) -> (bool result)
AcceptsFirstMouse(int eventNumber, WebKit::WebMouseEvent event) -> (bool result)
- InsertDictatedText(String text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, Vector<WebCore::DictationAlternative> dictationAlternatives) -> (bool handled, WebKit::EditorState newState)
+
+ InsertTextAsync(String text, struct WebKit::EditingRange replacementRange, bool registerUndoGroup, uint32_t editingRangeIsRelativeTo, bool suppressSelectionUpdate)
+ GetMarkedRangeAsync(uint64_t callbackID)
+ GetSelectedRangeAsync(uint64_t callbackID)
+ CharacterIndexForPointAsync(WebCore::IntPoint point, uint64_t callbackID);
+ FirstRectForCharacterRangeAsync(struct WebKit::EditingRange range, uint64_t callbackID);
+ SetCompositionAsync(String text, Vector<WebCore::CompositionUnderline> underlines, struct WebKit::EditingRange selectionRange, struct WebKit::EditingRange replacementRange)
+ ConfirmCompositionAsync()
#endif
-#if PLATFORM(MAC) && !PLATFORM(IOS)
- InsertText(String text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) -> (bool handled, WebKit::EditorState newState)
- SetComposition(String text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) -> (WebKit::EditorState newState)
- ConfirmComposition() -> (WebKit::EditorState newState)
+#if PLATFORM(MAC)
+ InsertDictatedTextAsync(String text, struct WebKit::EditingRange replacementRange, Vector<WebCore::DictationAlternative> dictationAlternatives, bool registerUndoGroup)
+ AttributedSubstringForCharacterRangeAsync(struct WebKit::EditingRange range, uint64_t callbackID);
+ FontAtSelection(uint64_t callbackID);
#endif
+
SetMinimumLayoutSize(WebCore::IntSize minimumLayoutSize)
SetAutoSizingShouldExpandToViewHeight(bool shouldExpand)
-#if PLATFORM(EFL)
- ConfirmComposition(String compositionString)
- SetComposition(String compositionString, Vector<WebCore::CompositionUnderline> underlines, uint64_t cursorPosition)
- CancelComposition()
+#if PLATFORM(COCOA)
+ HandleAlternativeTextUIResult(String result)
#endif
-#if USE(COORDINATED_GRAPHICS)
- FindZoomableAreaForPoint(WebCore::IntPoint point, WebCore::IntSize area)
+
+#if PLATFORM(IOS)
+ WillStartUserTriggeredZooming();
#endif
+ SetScrollPinningBehavior(uint32_t pinning)
+ SetScrollbarOverlayStyle(std::optional<uint32_t> scrollbarStyle)
+
+ GetBytecodeProfile(uint64_t callbackID)
+
+ GetSamplingProfilerOutput(uint64_t callbackID)
+
+ TakeSnapshot(WebCore::IntRect snapshotRect, WebCore::IntSize bitmapSize, uint32_t options, uint64_t callbackID)
#if PLATFORM(MAC)
- HandleAlternativeTextUIResult(String result)
+ PerformImmediateActionHitTestAtLocation(WebCore::FloatPoint location)
+ ImmediateActionDidUpdate()
+ ImmediateActionDidCancel()
+ ImmediateActionDidComplete()
+
+ DataDetectorsDidPresentUI(WebCore::PageOverlay::PageOverlayID pageOverlay)
+ DataDetectorsDidChangeUI(WebCore::PageOverlay::PageOverlayID pageOverlay)
+ DataDetectorsDidHideUI(WebCore::PageOverlay::PageOverlayID pageOverlay)
+
+ HandleAcceptedCandidate(struct WebCore::TextCheckingResult acceptedCandidate)
+
+ SetHeaderBannerHeightForTesting(int height);
+ SetFooterBannerHeightForTesting(int height);
#endif
- SetVisibilityStatePrerender()
+#if PLATFORM(COCOA)
+ RequestActiveNowPlayingSessionInfo()
+#endif
-#if PLATFORM(IOS)
- DidFinishScrolling(WebCore::FloatPoint contentOffset);
- DidFinishZooming(float scale);
+ SetShouldDispatchFakeMouseMoveEvents(bool shouldDispatchFakeMouseMoveEvents)
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+ PlaybackTargetSelected(uint64_t contextId, WebCore::MediaPlaybackTargetContext target)
+ PlaybackTargetAvailabilityDidChange(uint64_t contextId, bool available)
+ SetShouldPlayToPlaybackTarget(uint64_t contextId, bool shouldPlay)
#endif
-#if PLATFORM(GTK) && USE(TEXTURE_MAPPER_GL)
- SetAcceleratedCompositingWindowId(int64_t id)
+#if ENABLE(POINTER_LOCK)
+ DidAcquirePointerLock()
+ DidNotAcquirePointerLock()
+ DidLosePointerLock()
#endif
- SetMainFrameInViewSourceMode(bool inViewSourceMode)
-
- SetScrollPinningBehavior(uint32_t pinning)
+ ClearWheelEventTestTrigger()
+ SetShouldScaleViewToFitDocument(bool shouldScaleViewToFitDocument)
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+ DidEndRequestInstallMissingMediaPlugins(uint32_t result)
+#endif
+
+ SetResourceCachingDisabled(bool disabled)
+
+ SetUserInterfaceLayoutDirection(uint32_t direction)
+
+ DidGetLoadDecisionForIcon(bool decision, uint64_t loadIdentifier, uint64_t newCallbackID)
+ SetUseIconLoadingClient(bool useIconLoadingClient)
+
+#if ENABLE(GAMEPAD)
+ GamepadActivity(Vector<WebKit::GamepadData> gamepadDatas, bool shouldMakeGamepadsVisible)
+#endif
+
+#if USE(QUICK_LOOK)
+ DidReceivePasswordForQuickLookDocument(String password)
+#endif
}
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp
index 9164f480e..c6fb72196 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp
@@ -26,60 +26,39 @@
#include "config.h"
#include "WebPageGroupProxy.h"
-#include "WebProcess.h"
#include "InjectedBundle.h"
+#include "WebProcess.h"
+#include "WebUserContentController.h"
#include <WebCore/DOMWrapperWorld.h>
#include <WebCore/PageGroup.h>
+#include <WebCore/UserContentController.h>
namespace WebKit {
PassRefPtr<WebPageGroupProxy> WebPageGroupProxy::create(const WebPageGroupData& data)
{
- RefPtr<WebPageGroupProxy> pageGroup = adoptRef(new WebPageGroupProxy(data));
-
- if (pageGroup->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
- WebProcess::shared().injectedBundle()->didInitializePageGroup(pageGroup.get());
+ auto pageGroup = adoptRef(*new WebPageGroupProxy(data));
- return pageGroup.release();
-}
+ if (pageGroup->isVisibleToInjectedBundle() && WebProcess::singleton().injectedBundle())
+ WebProcess::singleton().injectedBundle()->didInitializePageGroup(pageGroup.ptr());
-WebPageGroupProxy::~WebPageGroupProxy()
-{
+ return WTFMove(pageGroup);
}
WebPageGroupProxy::WebPageGroupProxy(const WebPageGroupData& data)
: m_data(data)
- , m_pageGroup(WebCore::PageGroup::pageGroup(m_data.identifer))
-{
- for (size_t i = 0; i < data.userStyleSheets.size(); ++i)
- addUserStyleSheet(data.userStyleSheets[i]);
- for (size_t i = 0; i < data.userScripts.size(); ++i)
- addUserScript(data.userScripts[i]);
-}
-
-void WebPageGroupProxy::addUserStyleSheet(const WebCore::UserStyleSheet& userStyleSheet)
+ , m_pageGroup(WebCore::PageGroup::pageGroup(m_data.identifier))
+ , m_userContentController(WebUserContentController::getOrCreate(m_data.userContentControllerIdentifier))
{
- m_pageGroup->addUserStyleSheetToWorld(WebCore::mainThreadNormalWorld(), userStyleSheet.source(), userStyleSheet.url(), userStyleSheet.whitelist(), userStyleSheet.blacklist(), userStyleSheet.injectedFrames(), userStyleSheet.level());
}
-void WebPageGroupProxy::addUserScript(const WebCore::UserScript& userScript)
-{
- m_pageGroup->addUserScriptToWorld(WebCore::mainThreadNormalWorld(), userScript.source(), userScript.url(), userScript.whitelist(), userScript.blacklist(), userScript.injectionTime(), userScript.injectedFrames());
-}
-
-void WebPageGroupProxy::removeAllUserStyleSheets()
-{
- m_pageGroup->removeUserStyleSheetsFromWorld(WebCore::mainThreadNormalWorld());
-}
-
-void WebPageGroupProxy::removeAllUserScripts()
+WebPageGroupProxy::~WebPageGroupProxy()
{
- m_pageGroup->removeUserScriptsFromWorld(WebCore::mainThreadNormalWorld());
}
-void WebPageGroupProxy::removeAllUserContent()
+WebUserContentController& WebPageGroupProxy::userContentController()
{
- m_pageGroup->removeAllUserContent();
+ return m_userContentController;
}
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h
index 5e7d50b85..c98b8ae3d 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h
@@ -30,41 +30,33 @@
#include "WebPageGroupData.h"
#include <wtf/PassRefPtr.h>
-namespace IPC {
-class Connection;
-class MessageDecoder;
-}
-
namespace WebCore {
class PageGroup;
}
namespace WebKit {
+class WebUserContentController;
+
class WebPageGroupProxy : public API::ObjectImpl<API::Object::Type::BundlePageGroup> {
public:
static PassRefPtr<WebPageGroupProxy> create(const WebPageGroupData&);
virtual ~WebPageGroupProxy();
- const String& identifier() const { return m_data.identifer; }
+ const String& identifier() const { return m_data.identifier; }
uint64_t pageGroupID() const { return m_data.pageGroupID; }
bool isVisibleToInjectedBundle() const { return m_data.visibleToInjectedBundle; }
bool isVisibleToHistoryClient() const { return m_data.visibleToHistoryClient; }
WebCore::PageGroup* corePageGroup() const { return m_pageGroup; }
- void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&);
+ WebUserContentController& userContentController();
private:
WebPageGroupProxy(const WebPageGroupData&);
- void addUserStyleSheet(const WebCore::UserStyleSheet&);
- void addUserScript(const WebCore::UserScript&);
- void removeAllUserStyleSheets();
- void removeAllUserScripts();
- void removeAllUserContent();
-
WebPageGroupData m_data;
WebCore::PageGroup* m_pageGroup;
+ Ref<WebUserContentController> m_userContentController;
};
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageOverlay.cpp b/Source/WebKit2/WebProcess/WebPage/WebPageOverlay.cpp
new file mode 100644
index 000000000..2f42a0750
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebPageOverlay.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "WebPageOverlay.h"
+
+#include "WebFrame.h"
+#include "WebPage.h"
+#include <WebCore/GraphicsLayer.h>
+#include <WebCore/PageOverlay.h>
+#include <wtf/NeverDestroyed.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static HashMap<PageOverlay*, WebPageOverlay*>& overlayMap()
+{
+ static NeverDestroyed<HashMap<PageOverlay*, WebPageOverlay*>> map;
+ return map;
+}
+
+Ref<WebPageOverlay> WebPageOverlay::create(std::unique_ptr<WebPageOverlay::Client> client, PageOverlay::OverlayType overlayType)
+{
+ return adoptRef(*new WebPageOverlay(WTFMove(client), overlayType));
+}
+
+WebPageOverlay::WebPageOverlay(std::unique_ptr<WebPageOverlay::Client> client, PageOverlay::OverlayType overlayType)
+ : m_overlay(PageOverlay::create(*this, overlayType))
+ , m_client(WTFMove(client))
+{
+ ASSERT(m_client);
+ overlayMap().add(m_overlay.get(), this);
+}
+
+WebPageOverlay::~WebPageOverlay()
+{
+ if (!m_overlay)
+ return;
+
+ overlayMap().remove(m_overlay.get());
+ m_overlay = nullptr;
+}
+
+WebPageOverlay* WebPageOverlay::fromCoreOverlay(PageOverlay& overlay)
+{
+ return overlayMap().get(&overlay);
+}
+
+void WebPageOverlay::setNeedsDisplay(const IntRect& dirtyRect)
+{
+ m_overlay->setNeedsDisplay(dirtyRect);
+}
+
+void WebPageOverlay::setNeedsDisplay()
+{
+ m_overlay->setNeedsDisplay();
+}
+
+void WebPageOverlay::clear()
+{
+ m_overlay->clear();
+}
+
+void WebPageOverlay::willMoveToPage(PageOverlay&, Page* page)
+{
+ m_client->willMoveToPage(*this, page ? WebPage::fromCorePage(page) : nullptr);
+}
+
+void WebPageOverlay::didMoveToPage(PageOverlay&, Page* page)
+{
+ m_client->didMoveToPage(*this, page ? WebPage::fromCorePage(page) : nullptr);
+}
+
+void WebPageOverlay::drawRect(PageOverlay&, GraphicsContext& context, const IntRect& dirtyRect)
+{
+ m_client->drawRect(*this, context, dirtyRect);
+}
+
+bool WebPageOverlay::mouseEvent(PageOverlay&, const PlatformMouseEvent& event)
+{
+ return m_client->mouseEvent(*this, event);
+}
+
+void WebPageOverlay::didScrollFrame(PageOverlay&, Frame& frame)
+{
+ m_client->didScrollFrame(*this, WebFrame::fromCoreFrame(frame));
+}
+
+#if PLATFORM(MAC)
+DDActionContext *WebPageOverlay::actionContextForResultAtPoint(FloatPoint location, RefPtr<WebCore::Range>& rangeHandle)
+{
+ return m_client->actionContextForResultAtPoint(*this, location, rangeHandle);
+}
+
+void WebPageOverlay::dataDetectorsDidPresentUI()
+{
+ m_client->dataDetectorsDidPresentUI(*this);
+}
+
+void WebPageOverlay::dataDetectorsDidChangeUI()
+{
+ m_client->dataDetectorsDidChangeUI(*this);
+}
+
+void WebPageOverlay::dataDetectorsDidHideUI()
+{
+ m_client->dataDetectorsDidHideUI(*this);
+}
+#endif // PLATFORM(MAC)
+
+bool WebPageOverlay::copyAccessibilityAttributeStringValueForPoint(PageOverlay&, String attribute, FloatPoint parameter, String& value)
+{
+ return m_client->copyAccessibilityAttributeStringValueForPoint(*this, attribute, parameter, value);
+}
+
+bool WebPageOverlay::copyAccessibilityAttributeBoolValueForPoint(PageOverlay&, String attribute, FloatPoint parameter, bool& value)
+{
+ return m_client->copyAccessibilityAttributeBoolValueForPoint(*this, attribute, parameter, value);
+}
+
+Vector<String> WebPageOverlay::copyAccessibilityAttributeNames(PageOverlay&, bool parameterizedNames)
+{
+ return m_client->copyAccessibilityAttributeNames(*this, parameterizedNames);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageOverlay.h b/Source/WebKit2/WebProcess/WebPage/WebPageOverlay.h
new file mode 100644
index 000000000..f07b0f818
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebPageOverlay.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#ifndef WebPageOverlay_h
+#define WebPageOverlay_h
+
+#include "APIObject.h"
+#include <WebCore/FloatPoint.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/PageOverlay.h>
+#include <WebCore/Range.h>
+#include <wtf/RetainPtr.h>
+
+OBJC_CLASS DDActionContext;
+
+namespace WebKit {
+
+class WebFrame;
+class WebPage;
+
+class WebPageOverlay : public API::ObjectImpl<API::Object::Type::BundlePageOverlay>, private WebCore::PageOverlay::Client {
+public:
+ class Client {
+ public:
+ virtual ~Client() { }
+
+ virtual void willMoveToPage(WebPageOverlay&, WebPage*) = 0;
+ virtual void didMoveToPage(WebPageOverlay&, WebPage*) = 0;
+ virtual void drawRect(WebPageOverlay&, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) = 0;
+ virtual bool mouseEvent(WebPageOverlay&, const WebCore::PlatformMouseEvent&) = 0;
+ virtual void didScrollFrame(WebPageOverlay&, WebFrame*) { }
+
+#if PLATFORM(MAC)
+ virtual DDActionContext *actionContextForResultAtPoint(WebPageOverlay&, WebCore::FloatPoint location, RefPtr<WebCore::Range>& rangeHandle) { return nullptr; }
+ virtual void dataDetectorsDidPresentUI(WebPageOverlay&) { }
+ virtual void dataDetectorsDidChangeUI(WebPageOverlay&) { }
+ virtual void dataDetectorsDidHideUI(WebPageOverlay&) { }
+#endif
+
+ virtual bool copyAccessibilityAttributeStringValueForPoint(WebPageOverlay&, String /* attribute */, WebCore::FloatPoint /* parameter */, String& /* value */) { return false; }
+ virtual bool copyAccessibilityAttributeBoolValueForPoint(WebPageOverlay&, String /* attribute */, WebCore::FloatPoint /* parameter */, bool& /* value */) { return false; }
+ virtual Vector<String> copyAccessibilityAttributeNames(WebPageOverlay&, bool /* parameterizedNames */) { return Vector<String>(); }
+ };
+
+ static Ref<WebPageOverlay> create(std::unique_ptr<Client>, WebCore::PageOverlay::OverlayType = WebCore::PageOverlay::OverlayType::View);
+ static WebPageOverlay* fromCoreOverlay(WebCore::PageOverlay&);
+ virtual ~WebPageOverlay();
+
+ void setNeedsDisplay(const WebCore::IntRect& dirtyRect);
+ void setNeedsDisplay();
+
+ void clear();
+
+ WebCore::PageOverlay* coreOverlay() const { return m_overlay.get(); }
+ Client& client() const { return *m_client; }
+
+#if PLATFORM(MAC)
+ DDActionContext *actionContextForResultAtPoint(WebCore::FloatPoint, RefPtr<WebCore::Range>&);
+ void dataDetectorsDidPresentUI();
+ void dataDetectorsDidChangeUI();
+ void dataDetectorsDidHideUI();
+#endif
+
+private:
+ WebPageOverlay(std::unique_ptr<Client>, WebCore::PageOverlay::OverlayType);
+
+ // WebCore::PageOverlay::Client
+ void willMoveToPage(WebCore::PageOverlay&, WebCore::Page*) override;
+ void didMoveToPage(WebCore::PageOverlay&, WebCore::Page*) override;
+ void drawRect(WebCore::PageOverlay&, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override;
+ bool mouseEvent(WebCore::PageOverlay&, const WebCore::PlatformMouseEvent&) override;
+ void didScrollFrame(WebCore::PageOverlay&, WebCore::Frame&) override;
+
+ bool copyAccessibilityAttributeStringValueForPoint(WebCore::PageOverlay&, String /* attribute */, WebCore::FloatPoint /* parameter */, String& value) override;
+ bool copyAccessibilityAttributeBoolValueForPoint(WebCore::PageOverlay&, String /* attribute */, WebCore::FloatPoint /* parameter */, bool& value) override;
+ Vector<String> copyAccessibilityAttributeNames(WebCore::PageOverlay&, bool /* parameterizedNames */) override;
+
+
+ RefPtr<WebCore::PageOverlay> m_overlay;
+ std::unique_ptr<Client> m_client;
+};
+
+} // namespace WebKit
+
+#endif // WebPageOverlay_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp
index 7b41c5aa6..2caa8d0d4 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp
@@ -34,9 +34,13 @@ static uint64_t generateUndoStep()
return uniqueEntryID++;
}
-PassRefPtr<WebUndoStep> WebUndoStep::create(PassRefPtr<WebCore::UndoStep> step)
+Ref<WebUndoStep> WebUndoStep::create(PassRefPtr<WebCore::UndoStep> step)
+{
+ return adoptRef(*new WebUndoStep(step, generateUndoStep()));
+}
+
+WebUndoStep::~WebUndoStep()
{
- return adoptRef(new WebUndoStep(step, generateUndoStep()));
}
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebUndoStep.h b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.h
index 745377a3c..11871e91f 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebUndoStep.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.h
@@ -34,7 +34,8 @@ namespace WebKit {
class WebUndoStep : public RefCounted<WebUndoStep> {
public:
- static PassRefPtr<WebUndoStep> create(PassRefPtr<WebCore::UndoStep>);
+ static Ref<WebUndoStep> create(PassRefPtr<WebCore::UndoStep>);
+ ~WebUndoStep();
WebCore::UndoStep* step() const { return m_step.get(); }
uint64_t stepID() const { return m_stepID; }
diff --git a/Source/WebKit2/WebProcess/WebPage/atk/WebPageAccessibilityObjectAtk.cpp b/Source/WebKit2/WebProcess/WebPage/atk/WebPageAccessibilityObjectAtk.cpp
index 577a9671c..421fb8ddd 100644
--- a/Source/WebKit2/WebProcess/WebPage/atk/WebPageAccessibilityObjectAtk.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/atk/WebPageAccessibilityObjectAtk.cpp
@@ -30,6 +30,7 @@
#include "WebPage.h"
#include <WebCore/AXObjectCache.h>
+#include <WebCore/Document.h>
#include <WebCore/MainFrame.h>
#include <WebCore/Page.h>
@@ -55,7 +56,11 @@ static AtkObject* accessibilityRootObjectWrapper(AtkObject* atkObject)
if (!coreFrame.document())
return 0;
- AccessibilityObject* coreRootObject = coreFrame.document()->axObjectCache()->rootObject();
+ AXObjectCache* cache = coreFrame.document()->axObjectCache();
+ if (!cache)
+ return nullptr;
+
+ AccessibilityObject* coreRootObject = cache->rootObject();
if (!coreRootObject)
return 0;
diff --git a/Source/WebKit2/WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp b/Source/WebKit2/WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp
new file mode 100644
index 000000000..50545b30f
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gstreamer/WebPageGStreamer.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 Igalia S.L.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "WebPage.h"
+
+#if ENABLE(VIDEO) && USE(GSTREAMER)
+
+#include "WebPageProxyMessages.h"
+#include <WebCore/MediaPlayerRequestInstallMissingPluginsCallback.h>
+#include <gst/pbutils/install-plugins.h>
+
+namespace WebKit {
+
+void WebPage::requestInstallMissingMediaPlugins(const String& details, const String& description, WebCore::MediaPlayerRequestInstallMissingPluginsCallback& callback)
+{
+ if (m_installMediaPluginsCallback) {
+ callback.complete(GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS);
+ return;
+ }
+
+ m_installMediaPluginsCallback = &callback;
+ send(Messages::WebPageProxy::RequestInstallMissingMediaPlugins(details, description));
+}
+
+void WebPage::didEndRequestInstallMissingMediaPlugins(uint32_t result)
+{
+ if (!m_installMediaPluginsCallback)
+ return;
+
+ m_installMediaPluginsCallback->complete(result);
+ m_installMediaPluginsCallback = nullptr;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(VIDEO) && USE(GSTREAMER)
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurface.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurface.cpp
new file mode 100644
index 000000000..6b20cd85d
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurface.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 Igalia S.L.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "AcceleratedSurface.h"
+
+#include "WebPage.h"
+#include <WebCore/PlatformDisplay.h>
+
+#if PLATFORM(WAYLAND)
+#include "AcceleratedSurfaceWayland.h"
+#endif
+
+#if USE(REDIRECTED_XCOMPOSITE_WINDOW)
+#include "AcceleratedSurfaceX11.h"
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+std::unique_ptr<AcceleratedSurface> AcceleratedSurface::create(WebPage& webPage)
+{
+#if PLATFORM(WAYLAND)
+ if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland)
+ return AcceleratedSurfaceWayland::create(webPage);
+#endif
+#if USE(REDIRECTED_XCOMPOSITE_WINDOW)
+ if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11)
+ return AcceleratedSurfaceX11::create(webPage);
+#endif
+ return nullptr;
+}
+
+AcceleratedSurface::AcceleratedSurface(WebPage& webPage)
+ : m_webPage(webPage)
+ , m_size(webPage.size())
+{
+ m_size.scale(m_webPage.deviceScaleFactor());
+}
+
+bool AcceleratedSurface::resize(const IntSize& size)
+{
+ IntSize scaledSize(size);
+ scaledSize.scale(m_webPage.deviceScaleFactor());
+ if (scaledSize == m_size)
+ return false;
+
+ m_size = scaledSize;
+ return true;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurface.h b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurface.h
new file mode 100644
index 000000000..26b4c8a53
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurface.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Igalia S.L.
+ *
+ * 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 <WebCore/IntSize.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebKit {
+
+class WebPage;
+
+class AcceleratedSurface {
+ WTF_MAKE_NONCOPYABLE(AcceleratedSurface); WTF_MAKE_FAST_ALLOCATED;
+public:
+ static std::unique_ptr<AcceleratedSurface> create(WebPage&);
+ virtual ~AcceleratedSurface() = default;
+
+ virtual uint64_t window() const { ASSERT_NOT_REACHED(); return 0; }
+ virtual uint64_t surfaceID() const { ASSERT_NOT_REACHED(); return 0; };
+ virtual bool resize(const WebCore::IntSize&);
+ virtual bool shouldPaintMirrored() const { return false; }
+
+protected:
+ AcceleratedSurface(WebPage&);
+
+ WebPage& m_webPage;
+ WebCore::IntSize m_size;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceWayland.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceWayland.cpp
new file mode 100644
index 000000000..b6f0b87f7
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceWayland.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 Igalia S.L.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "AcceleratedSurfaceWayland.h"
+
+#if PLATFORM(WAYLAND)
+
+#include "WebKit2WaylandClientProtocol.h"
+#include "WebProcess.h"
+#include <WebCore/PlatformDisplayWayland.h>
+#include <cstring>
+#include <wayland-egl.h>
+#include <wtf/NeverDestroyed.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+class WaylandCompositorDisplay final : public PlatformDisplayWayland {
+ WTF_MAKE_NONCOPYABLE(WaylandCompositorDisplay);
+public:
+ static std::unique_ptr<WaylandCompositorDisplay> create()
+ {
+ struct wl_display* display = wl_display_connect(WebProcess::singleton().waylandCompositorDisplayName().utf8().data());
+ if (!display) {
+ WTFLogAlways("PlatformDisplayWayland initialization: failed to connect to the Wayland display: %s", WebProcess::singleton().waylandCompositorDisplayName().utf8().data());
+ return nullptr;
+ }
+
+ return std::unique_ptr<WaylandCompositorDisplay>(new WaylandCompositorDisplay(display));
+ }
+
+ void bindSurfaceToPage(struct wl_surface* surface, WebPage& page)
+ {
+ if (!m_webkitgtk)
+ return;
+
+ wl_webkitgtk_bind_surface_to_page(reinterpret_cast<struct wl_webkitgtk*>(m_webkitgtk.get()), surface, page.pageID());
+ wl_display_roundtrip(m_display);
+ }
+
+private:
+ WaylandCompositorDisplay(struct wl_display* display)
+ {
+ initialize(display);
+ PlatformDisplay::setSharedDisplayForCompositing(*this);
+ }
+
+ void registryGlobal(const char* interface, uint32_t name) override
+ {
+ PlatformDisplayWayland::registryGlobal(interface, name);
+ if (!std::strcmp(interface, "wl_webkitgtk"))
+ m_webkitgtk.reset(static_cast<struct wl_proxy*>(wl_registry_bind(m_registry.get(), name, &wl_webkitgtk_interface, 1)));
+ }
+
+ WlUniquePtr<struct wl_proxy> m_webkitgtk;
+};
+
+static std::unique_ptr<WaylandCompositorDisplay>& waylandCompositorDisplay()
+{
+ static NeverDestroyed<std::unique_ptr<WaylandCompositorDisplay>> waylandDisplay(WaylandCompositorDisplay::create());
+ return waylandDisplay;
+}
+
+std::unique_ptr<AcceleratedSurfaceWayland> AcceleratedSurfaceWayland::create(WebPage& webPage)
+{
+ return waylandCompositorDisplay() ? std::unique_ptr<AcceleratedSurfaceWayland>(new AcceleratedSurfaceWayland(webPage)) : nullptr;
+}
+
+AcceleratedSurfaceWayland::AcceleratedSurfaceWayland(WebPage& webPage)
+ : AcceleratedSurface(webPage)
+ , m_surface(waylandCompositorDisplay()->createSurface())
+ , m_window(wl_egl_window_create(m_surface.get(), std::max(1, m_size.width()), std::max(1, m_size.height())))
+{
+ waylandCompositorDisplay()->bindSurfaceToPage(m_surface.get(), m_webPage);
+}
+
+AcceleratedSurfaceWayland::~AcceleratedSurfaceWayland()
+{
+ wl_egl_window_destroy(m_window);
+}
+
+bool AcceleratedSurfaceWayland::resize(const IntSize& size)
+{
+ if (!AcceleratedSurface::resize(size))
+ return false;
+
+ wl_egl_window_resize(m_window, m_size.width(), m_size.height(), 0, 0);
+ return true;
+}
+
+} // namespace WebKit
+
+#endif // PLATFORM(WAYLAND)
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceWayland.h b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceWayland.h
new file mode 100644
index 000000000..38a2fbcd0
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceWayland.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 Igalia S.L.
+ *
+ * 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
+
+#if PLATFORM(WAYLAND)
+
+#include "AcceleratedSurface.h"
+#include "WebPage.h"
+#include <WebCore/WlUniquePtr.h>
+#include <wayland-egl.h>
+
+namespace WebKit {
+
+class AcceleratedSurfaceWayland final : public AcceleratedSurface {
+ WTF_MAKE_NONCOPYABLE(AcceleratedSurfaceWayland); WTF_MAKE_FAST_ALLOCATED;
+public:
+ static std::unique_ptr<AcceleratedSurfaceWayland> create(WebPage&);
+ ~AcceleratedSurfaceWayland();
+
+ uint64_t window() const override { return reinterpret_cast<uint64_t>(m_window); }
+ uint64_t surfaceID() const override { return m_webPage.pageID(); }
+ bool resize(const WebCore::IntSize&) override;
+ bool shouldPaintMirrored() const override { return true; }
+
+private:
+ AcceleratedSurfaceWayland(WebPage&);
+
+ WebCore::WlUniquePtr<struct wl_surface> m_surface;
+ struct wl_egl_window* m_window { nullptr };
+};
+
+} // namespace WebKit
+
+#endif // PLATFORM(WAYLAND)
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp
new file mode 100644
index 000000000..665e25789
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2012-2016 Igalia S.L.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "AcceleratedSurfaceX11.h"
+
+#if USE(REDIRECTED_XCOMPOSITE_WINDOW)
+
+#include "WebPage.h"
+#include <WebCore/PlatformDisplayX11.h>
+#include <WebCore/RefPtrCairo.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
+#include <cairo-xlib.h>
+#include <gdk/gdkx.h>
+#include <wtf/RunLoop.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+std::unique_ptr<AcceleratedSurfaceX11> AcceleratedSurfaceX11::create(WebPage& webPage)
+{
+ if (!downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).supportsXComposite())
+ return nullptr;
+ return std::unique_ptr<AcceleratedSurfaceX11>(new AcceleratedSurfaceX11(webPage));
+}
+
+static GdkVisual* defaultVisual()
+{
+ if (GdkVisual* visual = gdk_screen_get_rgba_visual(gdk_screen_get_default()))
+ return visual;
+ return gdk_screen_get_system_visual(gdk_screen_get_default());
+}
+
+AcceleratedSurfaceX11::AcceleratedSurfaceX11(WebPage& webPage)
+ : AcceleratedSurface(webPage)
+ , m_display(downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native())
+{
+ Screen* screen = DefaultScreenOfDisplay(m_display);
+
+ ASSERT(downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native() == m_display);
+
+ GdkVisual* visual = defaultVisual();
+ XUniqueColormap colormap(XCreateColormap(m_display, RootWindowOfScreen(screen), GDK_VISUAL_XVISUAL(visual), AllocNone));
+
+ XSetWindowAttributes windowAttributes;
+ windowAttributes.override_redirect = True;
+ windowAttributes.colormap = colormap.get();
+
+ // CWBorderPixel must be present when the depth doesn't match the parent's one.
+ // See http://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c?id=xorg-server-1.16.0#n703.
+ windowAttributes.border_pixel = 0;
+
+ m_parentWindow = XCreateWindow(m_display,
+ RootWindowOfScreen(screen),
+ -1, -1, 1, 1,
+ 0,
+ gdk_visual_get_depth(visual),
+ InputOutput,
+ GDK_VISUAL_XVISUAL(visual),
+ CWOverrideRedirect | CWColormap | CWBorderPixel,
+ &windowAttributes);
+ XMapWindow(m_display, m_parentWindow.get());
+
+ windowAttributes.event_mask = StructureNotifyMask;
+ windowAttributes.override_redirect = False;
+
+ // Create the window of at last 1x1 since X doesn't allow to create empty windows.
+ m_window = XCreateWindow(m_display,
+ m_parentWindow.get(),
+ 0, 0,
+ std::max(1, m_size.width()),
+ std::max(1, m_size.height()),
+ 0,
+ CopyFromParent,
+ InputOutput,
+ CopyFromParent,
+ CWEventMask,
+ &windowAttributes);
+ XMapWindow(m_display, m_window.get());
+
+ while (1) {
+ XEvent event;
+ XWindowEvent(m_display, m_window.get(), StructureNotifyMask, &event);
+ if (event.type == MapNotify && event.xmap.window == m_window.get())
+ break;
+ }
+ XSelectInput(m_display, m_window.get(), NoEventMask);
+ XCompositeRedirectWindow(m_display, m_window.get(), CompositeRedirectManual);
+ createPixmap();
+}
+
+AcceleratedSurfaceX11::~AcceleratedSurfaceX11()
+{
+ ASSERT(m_display);
+ ASSERT(m_window);
+ ASSERT(m_parentWindow);
+
+ // Explicitly reset these because we need to ensure it happens in this order.
+ m_window.reset();
+ m_parentWindow.reset();
+}
+
+void AcceleratedSurfaceX11::createPixmap()
+{
+ m_pixmap = XCompositeNameWindowPixmap(m_display, m_window.get());
+ RefPtr<cairo_surface_t> surface = adoptRef(cairo_xlib_surface_create(m_display, m_pixmap.get(), GDK_VISUAL_XVISUAL(defaultVisual()), m_size.width(), m_size.height()));
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
+ cairo_set_operator(cr.get(), CAIRO_OPERATOR_CLEAR);
+ cairo_paint(cr.get());
+ XSync(m_display, False);
+}
+
+bool AcceleratedSurfaceX11::resize(const IntSize& size)
+{
+ if (!AcceleratedSurface::resize(size))
+ return false;
+
+ // Resize the window to at last 1x1 since X doesn't allow to create empty windows.
+ XResizeWindow(m_display, m_window.get(), std::max(1, m_size.width()), std::max(1, m_size.height()));
+ XFlush(m_display);
+
+ // Release the previous pixmap later to give some time to the UI process to update.
+ RunLoop::main().dispatchAfter(std::chrono::seconds(5), [pixmap = WTFMove(m_pixmap)] { });
+ createPixmap();
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // USE(REDIRECTED_XCOMPOSITE_WINDOW)
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.h b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.h
new file mode 100644
index 000000000..740f58978
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/AcceleratedSurfaceX11.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012-2016 Igalia S.L.
+ *
+ * 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
+
+#if USE(REDIRECTED_XCOMPOSITE_WINDOW)
+
+#include "AcceleratedSurface.h"
+#include <WebCore/XUniqueResource.h>
+
+typedef struct _XDisplay Display;
+typedef unsigned long Pixmap;
+typedef unsigned long Window;
+
+namespace WebKit {
+
+class WebPage;
+
+class AcceleratedSurfaceX11 final : public AcceleratedSurface {
+ WTF_MAKE_NONCOPYABLE(AcceleratedSurfaceX11); WTF_MAKE_FAST_ALLOCATED;
+public:
+ static std::unique_ptr<AcceleratedSurfaceX11> create(WebPage&);
+ ~AcceleratedSurfaceX11();
+
+ uint64_t window() const override { return m_window.get(); }
+ uint64_t surfaceID() const override { return m_pixmap.get(); }
+ bool resize(const WebCore::IntSize&) override;
+ bool shouldPaintMirrored() const override { return false; }
+
+private:
+ AcceleratedSurfaceX11(WebPage&);
+
+ void createPixmap();
+
+ Display* m_display { nullptr };
+ WebCore::XUniqueWindow m_window;
+ WebCore::XUniqueWindow m_parentWindow;
+ WebCore::XUniquePixmap m_pixmap;
+};
+
+} // namespace WebKit
+
+#endif // USE(REDIRECTED_XCOMPOSITE_WINDOW)
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp
index 70f6c8365..40bb07d9f 100644
--- a/Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp
@@ -29,6 +29,7 @@
#if USE(TEXTURE_MAPPER_GL)
+#include "AcceleratedSurface.h"
#include "DrawingAreaImpl.h"
#include "TextureMapperGL.h"
#include "WebPage.h"
@@ -46,63 +47,103 @@
#include <WebCore/MainFrame.h>
#include <WebCore/Page.h>
#include <WebCore/Settings.h>
-#include <wtf/CurrentTime.h>
-
#include <gdk/gdk.h>
-#if defined(GDK_WINDOWING_X11)
-#define Region XRegion
-#define Font XFont
-#define Cursor XCursor
-#define Screen XScreen
-#include <gdk/gdkx.h>
-#endif
+#include <wtf/CurrentTime.h>
using namespace WebCore;
namespace WebKit {
-PassRefPtr<LayerTreeHostGtk> LayerTreeHostGtk::create(WebPage* webPage)
+LayerTreeHostGtk::RenderFrameScheduler::RenderFrameScheduler(std::function<bool()> renderer)
+ : m_renderer(WTFMove(renderer))
+ , m_timer(RunLoop::main(), this, &LayerTreeHostGtk::RenderFrameScheduler::renderFrame)
{
- RefPtr<LayerTreeHostGtk> host = adoptRef(new LayerTreeHostGtk(webPage));
- host->initialize();
- return host.release();
+ // We use a RunLoop timer because otherwise GTK+ event handling during dragging can starve WebCore timers, which have a lower priority.
+ // Use a higher priority than WebCore timers.
+ m_timer.setPriority(GDK_PRIORITY_REDRAW - 1);
}
-LayerTreeHostGtk::LayerTreeHostGtk(WebPage* webPage)
- : LayerTreeHost(webPage)
- , m_isValid(true)
- , m_notifyAfterScheduledLayerFlush(false)
- , m_lastFlushTime(0)
- , m_layerFlushSchedulingEnabled(true)
- , m_layerFlushTimerCallbackId(0)
+LayerTreeHostGtk::RenderFrameScheduler::~RenderFrameScheduler()
{
}
-GLContext* LayerTreeHostGtk::glContext()
+void LayerTreeHostGtk::RenderFrameScheduler::start()
{
- if (m_context)
- return m_context.get();
+ if (m_timer.isActive())
+ return;
+ m_fireTime = 0;
+ nextFrame();
+}
+
+void LayerTreeHostGtk::RenderFrameScheduler::stop()
+{
+ m_timer.stop();
+}
+
+static inline bool shouldSkipNextFrameBecauseOfContinousImmediateFlushes(double current, double lastImmediateFlushTime)
+{
+ // 100ms is about a perceptable delay in UI, so when scheduling layer flushes immediately for more than 100ms,
+ // we skip the next frame to ensure pending timers have a change to be fired.
+ static const double maxDurationOfImmediateFlushes = 0.100;
+ if (!lastImmediateFlushTime)
+ return false;
+ return lastImmediateFlushTime + maxDurationOfImmediateFlushes < current;
+}
- uint64_t windowHandle = m_webPage->nativeWindowHandle();
- if (!windowHandle)
- return 0;
+void LayerTreeHostGtk::RenderFrameScheduler::nextFrame()
+{
+ static const double targetFramerate = 1 / 60.0;
+ // When rendering layers takes more time than the target delay (0.016), we end up scheduling layer flushes
+ // immediately. Since the layer flush timer has a higher priority than WebCore timers, these are never
+ // fired while we keep scheduling layer flushes immediately.
+ double current = monotonicallyIncreasingTime();
+ double timeToNextFlush = std::max(targetFramerate - (current - m_fireTime), 0.0);
+ if (timeToNextFlush)
+ m_lastImmediateFlushTime = 0;
+ else if (!m_lastImmediateFlushTime)
+ m_lastImmediateFlushTime = current;
+
+ if (shouldSkipNextFrameBecauseOfContinousImmediateFlushes(current, m_lastImmediateFlushTime)) {
+ timeToNextFlush = targetFramerate;
+ m_lastImmediateFlushTime = 0;
+ }
+
+ m_timer.startOneShot(timeToNextFlush);
+}
+
+void LayerTreeHostGtk::RenderFrameScheduler::renderFrame()
+{
+ m_fireTime = monotonicallyIncreasingTime();
+ if (!m_renderer() || m_timer.isActive())
+ return;
+ nextFrame();
+}
- m_context = GLContext::createContextForWindow(windowHandle, GLContext::sharingContext());
- return m_context.get();
+Ref<LayerTreeHostGtk> LayerTreeHostGtk::create(WebPage& webPage)
+{
+ return adoptRef(*new LayerTreeHostGtk(webPage));
}
-void LayerTreeHostGtk::initialize()
+LayerTreeHostGtk::LayerTreeHostGtk(WebPage& webPage)
+ : LayerTreeHost(webPage)
+ , m_surface(AcceleratedSurface::create(webPage))
+ , m_renderFrameScheduler(std::bind(&LayerTreeHostGtk::renderFrame, this))
{
- m_rootLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
+ m_rootLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
m_rootLayer->setDrawsContent(false);
- m_rootLayer->setSize(m_webPage->size());
+ m_rootLayer->setSize(m_webPage.size());
+
+ m_scaleMatrix.makeIdentity();
+ m_scaleMatrix.scale(m_webPage.deviceScaleFactor() * m_webPage.pageScaleFactor());
+ downcast<GraphicsLayerTextureMapper>(*m_rootLayer).layer().setAnchorPoint(FloatPoint3D());
+ downcast<GraphicsLayerTextureMapper>(*m_rootLayer).layer().setTransform(m_scaleMatrix);
// The non-composited contents are a child of the root layer.
- m_nonCompositedContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
+ m_nonCompositedContentLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
m_nonCompositedContentLayer->setDrawsContent(true);
- m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground());
- m_nonCompositedContentLayer->setSize(m_webPage->size());
- if (m_webPage->corePage()->settings().acceleratedDrawingEnabled())
+ m_nonCompositedContentLayer->setContentsOpaque(m_webPage.drawsBackground());
+ m_nonCompositedContentLayer->setSize(m_webPage.size());
+ if (m_webPage.corePage()->settings().acceleratedDrawingEnabled())
m_nonCompositedContentLayer->setAcceleratesDrawing(true);
#ifndef NDEBUG
@@ -113,46 +154,45 @@ void LayerTreeHostGtk::initialize()
m_rootLayer->addChild(m_nonCompositedContentLayer.get());
m_nonCompositedContentLayer->setNeedsDisplay();
- m_layerTreeContext.windowHandle = m_webPage->nativeWindowHandle();
+ if (m_surface) {
+ createTextureMapper();
+ m_layerTreeContext.contextID = m_surface->surfaceID();
+ }
+}
+
+bool LayerTreeHostGtk::makeContextCurrent()
+{
+ uint64_t nativeHandle = m_surface ? m_surface->window() : m_layerTreeContext.contextID;
+ if (!nativeHandle) {
+ m_context = nullptr;
+ return false;
+ }
- GLContext* context = glContext();
- if (!context)
- return;
+ if (m_context)
+ return m_context->makeContextCurrent();
- // The creation of the TextureMapper needs an active OpenGL context.
- context->makeContextCurrent();
+ m_context = GLContext::createContextForWindow(reinterpret_cast<GLNativeWindowType>(nativeHandle), &PlatformDisplay::sharedDisplayForCompositing());
+ if (!m_context)
+ return false;
- m_textureMapper = TextureMapperGL::create();
- static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
- toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get());
+ if (!m_context->makeContextCurrent())
+ return false;
- if (m_webPage->hasPageOverlay()) {
- PageOverlayList& pageOverlays = m_webPage->pageOverlays();
- PageOverlayList::iterator end = pageOverlays.end();
- for (PageOverlayList::iterator it = pageOverlays.begin(); it != end; ++it)
- createPageOverlayLayer(it->get());
- }
+ // Do not do frame sync when rendering offscreen in the web process to ensure that SwapBuffers never blocks.
+ // Rendering to the actual screen will happen later anyway since the UI process schedules a redraw for every update,
+ // the compositor will take care of syncing to vblank.
+ if (m_surface)
+ m_context->swapInterval(0);
- scheduleLayerFlush();
+ return true;
}
LayerTreeHostGtk::~LayerTreeHostGtk()
{
- ASSERT(!m_isValid);
ASSERT(!m_rootLayer);
cancelPendingLayerFlush();
}
-const LayerTreeContext& LayerTreeHostGtk::layerTreeContext()
-{
- return m_layerTreeContext;
-}
-
-void LayerTreeHostGtk::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
-{
- m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
-}
-
void LayerTreeHostGtk::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
{
m_nonCompositedContentLayer->removeAllChildren();
@@ -166,7 +206,10 @@ void LayerTreeHostGtk::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
void LayerTreeHostGtk::invalidate()
{
- ASSERT(m_isValid);
+ // This can trigger destruction of GL objects so let's make sure that
+ // we have the right active context
+ if (m_context)
+ m_context->makeContextCurrent();
cancelPendingLayerFlush();
m_rootLayer = nullptr;
@@ -174,28 +217,20 @@ void LayerTreeHostGtk::invalidate()
m_textureMapper = nullptr;
m_context = nullptr;
- m_isValid = false;
+ LayerTreeHost::invalidate();
+
+ m_surface = nullptr;
}
void LayerTreeHostGtk::setNonCompositedContentsNeedDisplay()
{
m_nonCompositedContentLayer->setNeedsDisplay();
-
- PageOverlayLayerMap::iterator end = m_pageOverlayLayers.end();
- for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(); it != end; ++it)
- it->value->setNeedsDisplay();
-
scheduleLayerFlush();
}
void LayerTreeHostGtk::setNonCompositedContentsNeedDisplayInRect(const IntRect& rect)
{
m_nonCompositedContentLayer->setNeedsDisplayInRect(rect);
-
- PageOverlayLayerMap::iterator end = m_pageOverlayLayers.end();
- for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(); it != end; ++it)
- it->value->setNeedsDisplayInRect(rect);
-
scheduleLayerFlush();
}
@@ -224,88 +259,50 @@ void LayerTreeHostGtk::sizeDidChange(const IntSize& newSize)
m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(0, oldSize.height(), newSize.width(), newSize.height() - oldSize.height()));
m_nonCompositedContentLayer->setNeedsDisplay();
- PageOverlayLayerMap::iterator end = m_pageOverlayLayers.end();
- for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(); it != end; ++it)
- it->value->setSize(newSize);
+ if (m_surface && m_surface->resize(newSize))
+ m_layerTreeContext.contextID = m_surface->surfaceID();
compositeLayersToContext(ForResize);
}
void LayerTreeHostGtk::deviceOrPageScaleFactorChanged()
{
+ if (m_surface && m_surface->resize(m_webPage.size()))
+ m_layerTreeContext.contextID = m_surface->surfaceID();
+
// Other layers learn of the scale factor change via WebPage::setDeviceScaleFactor.
m_nonCompositedContentLayer->deviceOrPageScaleFactorChanged();
-}
-void LayerTreeHostGtk::forceRepaint()
-{
- scheduleLayerFlush();
+ m_scaleMatrix.makeIdentity();
+ m_scaleMatrix.scale(m_webPage.deviceScaleFactor() * m_webPage.pageScaleFactor());
+ downcast<GraphicsLayerTextureMapper>(*m_rootLayer).layer().setTransform(m_scaleMatrix);
}
-void LayerTreeHostGtk::didInstallPageOverlay(PageOverlay* pageOverlay)
-{
- createPageOverlayLayer(pageOverlay);
- scheduleLayerFlush();
-}
-
-void LayerTreeHostGtk::didUninstallPageOverlay(PageOverlay* pageOverlay)
-{
- destroyPageOverlayLayer(pageOverlay);
- scheduleLayerFlush();
-}
-
-void LayerTreeHostGtk::setPageOverlayNeedsDisplay(PageOverlay* pageOverlay, const IntRect& rect)
+void LayerTreeHostGtk::forceRepaint()
{
- GraphicsLayer* layer = m_pageOverlayLayers.get(pageOverlay);
- if (!layer)
- return;
-
- layer->setNeedsDisplayInRect(rect);
scheduleLayerFlush();
}
-void LayerTreeHostGtk::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
+void LayerTreeHostGtk::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const FloatRect& clipRect)
{
+ if (graphicsLayer == m_nonCompositedContentLayer.get())
+ m_webPage.drawRect(graphicsContext, enclosingIntRect(clipRect));
}
-void LayerTreeHostGtk::notifyFlushRequired(const WebCore::GraphicsLayer*)
+float LayerTreeHostGtk::deviceScaleFactor() const
{
+ return m_webPage.deviceScaleFactor();
}
-void LayerTreeHostGtk::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& clipRect)
-{
- if (graphicsLayer == m_nonCompositedContentLayer.get()) {
- m_webPage->drawRect(graphicsContext, clipRect);
- return;
- }
-
- for (auto& pageOverlayLayer : m_pageOverlayLayers) {
- if (pageOverlayLayer.value.get() == graphicsLayer) {
- m_webPage->drawPageOverlay(pageOverlayLayer.key, graphicsContext, clipRect);
- break;
- }
- }
-}
-
-gboolean LayerTreeHostGtk::layerFlushTimerFiredCallback(LayerTreeHostGtk* layerTreeHost)
+float LayerTreeHostGtk::pageScaleFactor() const
{
- layerTreeHost->layerFlushTimerFired();
- return FALSE;
+ return m_webPage.pageScaleFactor();
}
-void LayerTreeHostGtk::layerFlushTimerFired()
+bool LayerTreeHostGtk::renderFrame()
{
- ASSERT(m_layerFlushTimerCallbackId);
- m_layerFlushTimerCallbackId = 0;
-
flushAndRenderLayers();
-
- if (toTextureMapperLayer(m_rootLayer.get())->descendantsOrSelfHaveRunningAnimations() && !m_layerFlushTimerCallbackId) {
- const double targetFPS = 60;
- double nextFlush = std::max((1 / targetFPS) - (currentTime() - m_lastFlushTime), 0.0);
- m_layerFlushTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, nextFlush * 1000.0, reinterpret_cast<GSourceFunc>(layerFlushTimerFiredCallback), this, 0);
- g_source_set_name_by_id(m_layerFlushTimerCallbackId, "[WebKit] layerFlushTimerFiredCallback");
- }
+ return downcast<GraphicsLayerTextureMapper>(*m_rootLayer).layer().descendantsOrSelfHaveRunningAnimations();
}
bool LayerTreeHostGtk::flushPendingLayerChanges()
@@ -313,17 +310,19 @@ bool LayerTreeHostGtk::flushPendingLayerChanges()
m_rootLayer->flushCompositingStateForThisLayerOnly();
m_nonCompositedContentLayer->flushCompositingStateForThisLayerOnly();
- PageOverlayLayerMap::iterator end = m_pageOverlayLayers.end();
- for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(); it != end; ++it)
- it->value->flushCompositingStateForThisLayerOnly();
+ if (!m_webPage.corePage()->mainFrame().view()->flushCompositingStateIncludingSubframes())
+ return false;
+
+ if (m_viewOverlayRootLayer)
+ m_viewOverlayRootLayer->flushCompositingState(FloatRect(FloatPoint(), m_rootLayer->size()));
- return m_webPage->corePage()->mainFrame().view()->flushCompositingStateIncludingSubframes();
+ downcast<GraphicsLayerTextureMapper>(*m_rootLayer).updateBackingStoreIncludingSubLayers();
+ return true;
}
void LayerTreeHostGtk::compositeLayersToContext(CompositePurpose purpose)
{
- GLContext* context = glContext();
- if (!context || !context->makeContextCurrent())
+ if (!makeContextCurrent())
return;
// The window size may be out of sync with the page size at this point, and getting
@@ -331,34 +330,38 @@ void LayerTreeHostGtk::compositeLayersToContext(CompositePurpose purpose)
// we set the viewport parameters directly from the window size.
IntSize contextSize = m_context->defaultFrameBufferSize();
glViewport(0, 0, contextSize.width(), contextSize.height());
-
- if (purpose == ForResize) {
- glClearColor(1, 1, 1, 0);
+ if (purpose == ForResize || !m_webPage.drawsBackground()) {
+ glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
}
- m_textureMapper->beginPainting();
- toTextureMapperLayer(m_rootLayer.get())->paint();
+ ASSERT(m_textureMapper);
+
+ TextureMapper::PaintFlags paintFlags = 0;
+
+ if (m_surface && m_surface->shouldPaintMirrored())
+ paintFlags |= TextureMapper::PaintingMirrored;
+
+ m_textureMapper->beginPainting(paintFlags);
+ downcast<GraphicsLayerTextureMapper>(*m_rootLayer).layer().paint();
m_textureMapper->endPainting();
- context->swapBuffers();
+ m_context->swapBuffers();
}
void LayerTreeHostGtk::flushAndRenderLayers()
{
{
RefPtr<LayerTreeHostGtk> protect(this);
- m_webPage->layoutIfNeeded();
+ m_webPage.layoutIfNeeded();
if (!m_isValid)
return;
}
- GLContext* context = glContext();
- if (!context || !context->makeContextCurrent())
+ if (!makeContextCurrent())
return;
- m_lastFlushTime = currentTime();
if (!flushPendingLayerChanges())
return;
@@ -367,76 +370,59 @@ void LayerTreeHostGtk::flushAndRenderLayers()
if (m_notifyAfterScheduledLayerFlush) {
// Let the drawing area know that we've done a flush of the layer changes.
- static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
+ m_webPage.drawingArea()->layerHostDidFlushLayers();
m_notifyAfterScheduledLayerFlush = false;
}
}
-void LayerTreeHostGtk::createPageOverlayLayer(PageOverlay* pageOverlay)
+void LayerTreeHostGtk::scheduleLayerFlush()
{
- std::unique_ptr<GraphicsLayer> layer = GraphicsLayer::create(graphicsLayerFactory(), this);
-#ifndef NDEBUG
- layer->setName("LayerTreeHost page overlay content");
-#endif
-
- layer->setAcceleratesDrawing(m_webPage->corePage()->settings().acceleratedDrawingEnabled());
- layer->setDrawsContent(true);
- layer->setSize(m_webPage->size());
- layer->setShowDebugBorder(m_webPage->corePage()->settings().showDebugBorders());
- layer->setShowRepaintCounter(m_webPage->corePage()->settings().showRepaintCounter());
+ if (!m_layerFlushSchedulingEnabled || !m_textureMapper)
+ return;
- m_rootLayer->addChild(layer.get());
- m_pageOverlayLayers.add(pageOverlay, std::move(layer));
+ m_renderFrameScheduler.start();
}
-void LayerTreeHostGtk::destroyPageOverlayLayer(PageOverlay* pageOverlay)
+void LayerTreeHostGtk::pageBackgroundTransparencyChanged()
{
- std::unique_ptr<GraphicsLayer> layer = m_pageOverlayLayers.take(pageOverlay);
- ASSERT(layer);
-
- layer->removeFromParent();
+ m_nonCompositedContentLayer->setContentsOpaque(m_webPage.drawsBackground());
}
-void LayerTreeHostGtk::scheduleLayerFlush()
+void LayerTreeHostGtk::cancelPendingLayerFlush()
{
- if (!m_layerFlushSchedulingEnabled)
- return;
-
- // We use a GLib timer because otherwise GTK+ event handling during dragging can starve WebCore timers, which have a lower priority.
- if (!m_layerFlushTimerCallbackId) {
- m_layerFlushTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, 0, reinterpret_cast<GSourceFunc>(layerFlushTimerFiredCallback), this, 0);
- g_source_set_name_by_id(m_layerFlushTimerCallbackId, "[WebKit] layerFlushTimerFiredCallback");
- }
+ m_renderFrameScheduler.stop();
}
-void LayerTreeHostGtk::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
+void LayerTreeHostGtk::setViewOverlayRootLayer(GraphicsLayer* viewOverlayRootLayer)
{
- if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
- return;
-
- m_layerFlushSchedulingEnabled = layerFlushingEnabled;
-
- if (m_layerFlushSchedulingEnabled) {
- scheduleLayerFlush();
- return;
- }
-
- cancelPendingLayerFlush();
+ LayerTreeHost::setViewOverlayRootLayer(viewOverlayRootLayer);
+ if (m_viewOverlayRootLayer)
+ m_rootLayer->addChild(m_viewOverlayRootLayer);
}
-void LayerTreeHostGtk::pageBackgroundTransparencyChanged()
+void LayerTreeHostGtk::createTextureMapper()
{
- m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground());
+ // The creation of the TextureMapper needs an active OpenGL context.
+ if (!makeContextCurrent())
+ return;
+
+ ASSERT(m_isValid);
+ ASSERT(!m_textureMapper);
+ m_textureMapper = TextureMapper::create();
+ static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
+ downcast<GraphicsLayerTextureMapper>(*m_rootLayer).layer().setTextureMapper(m_textureMapper.get());
}
-void LayerTreeHostGtk::cancelPendingLayerFlush()
+#if PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+void LayerTreeHostGtk::setNativeSurfaceHandleForCompositing(uint64_t handle)
{
- if (!m_layerFlushTimerCallbackId)
- return;
+ cancelPendingLayerFlush();
+ m_layerTreeContext.contextID = handle;
- g_source_remove(m_layerFlushTimerCallbackId);
- m_layerFlushTimerCallbackId = 0;
+ createTextureMapper();
+ scheduleLayerFlush();
}
+#endif
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.h b/Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.h
index bb30b0990..e356a3683 100644
--- a/Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.h
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/LayerTreeHostGtk.h
@@ -34,80 +34,83 @@
#include "TextureMapperLayer.h"
#include <WebCore/GLContext.h>
#include <WebCore/GraphicsLayerClient.h>
-#include <wtf/HashMap.h>
-#include <wtf/OwnPtr.h>
+#include <WebCore/TransformationMatrix.h>
+#include <wtf/RunLoop.h>
namespace WebKit {
-class LayerTreeHostGtk : public LayerTreeHost, WebCore::GraphicsLayerClient {
+class AcceleratedSurface;
+
+class LayerTreeHostGtk final : public LayerTreeHost, WebCore::GraphicsLayerClient {
public:
- static PassRefPtr<LayerTreeHostGtk> create(WebPage*);
+ static Ref<LayerTreeHostGtk> create(WebPage&);
virtual ~LayerTreeHostGtk();
-protected:
- explicit LayerTreeHostGtk(WebPage*);
+private:
+ explicit LayerTreeHostGtk(WebPage&);
WebCore::GraphicsLayer* rootLayer() const { return m_rootLayer.get(); }
- void initialize();
+ // LayerTreeHost
+ void scheduleLayerFlush() override;
+ void cancelPendingLayerFlush() override;
+ void setRootCompositingLayer(WebCore::GraphicsLayer*) override;
+ void invalidate() override;
- // LayerTreeHost.
- virtual void invalidate();
- virtual void sizeDidChange(const WebCore::IntSize& newSize);
- virtual void deviceOrPageScaleFactorChanged();
- virtual void forceRepaint();
- virtual void setRootCompositingLayer(WebCore::GraphicsLayer*);
- virtual void scheduleLayerFlush();
- virtual void setLayerFlushSchedulingEnabled(bool layerFlushingEnabled);
- virtual void pageBackgroundTransparencyChanged() override;
+ void forceRepaint() override;
+ void sizeDidChange(const WebCore::IntSize& newSize) override;
+ void deviceOrPageScaleFactorChanged() override;
+ void pageBackgroundTransparencyChanged() override;
-private:
- // LayerTreeHost.
- virtual const LayerTreeContext& layerTreeContext();
- virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool);
+ void setNonCompositedContentsNeedDisplay() override;
+ void setNonCompositedContentsNeedDisplayInRect(const WebCore::IntRect&) override;
+ void scrollNonCompositedContents(const WebCore::IntRect& scrollRect) override;
+ void setViewOverlayRootLayer(WebCore::GraphicsLayer*) override;
+
+#if PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW)
+ void setNativeSurfaceHandleForCompositing(uint64_t) override;
+#endif
+
+ class RenderFrameScheduler {
+ public:
+ RenderFrameScheduler(std::function<bool()>);
+ ~RenderFrameScheduler();
- virtual void setNonCompositedContentsNeedDisplay() override;
- virtual void setNonCompositedContentsNeedDisplayInRect(const WebCore::IntRect&) override;
- virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect);
+ void start();
+ void stop();
- virtual void didInstallPageOverlay(PageOverlay*) override;
- virtual void didUninstallPageOverlay(PageOverlay*) override;
- virtual void setPageOverlayNeedsDisplay(PageOverlay*, const WebCore::IntRect&) override;
+ private:
+ void renderFrame();
+ void nextFrame();
- virtual bool flushPendingLayerChanges();
+ std::function<bool()> m_renderer;
+ RunLoop::Timer<RenderFrameScheduler> m_timer;
+ double m_fireTime { 0 };
+ double m_lastImmediateFlushTime { 0 };
+ };
// GraphicsLayerClient
- virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double time);
- virtual void notifyFlushRequired(const WebCore::GraphicsLayer*);
- virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect);
- virtual void didCommitChangesForLayer(const WebCore::GraphicsLayer*) const { }
+ void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::FloatRect& clipRect) override;
+ float deviceScaleFactor() const override;
+ float pageScaleFactor() const override;
- void createPageOverlayLayer(PageOverlay*);
- void destroyPageOverlayLayer(PageOverlay*);
+ bool flushPendingLayerChanges();
enum CompositePurpose { ForResize, NotForResize };
void compositeLayersToContext(CompositePurpose = NotForResize);
void flushAndRenderLayers();
- void cancelPendingLayerFlush();
-
- void layerFlushTimerFired();
- static gboolean layerFlushTimerFiredCallback(LayerTreeHostGtk*);
-
- WebCore::GLContext* glContext();
+ bool renderFrame();
+ bool makeContextCurrent();
+ void createTextureMapper();
- LayerTreeContext m_layerTreeContext;
- bool m_isValid;
- bool m_notifyAfterScheduledLayerFlush;
std::unique_ptr<WebCore::GraphicsLayer> m_rootLayer;
std::unique_ptr<WebCore::GraphicsLayer> m_nonCompositedContentLayer;
- typedef HashMap<PageOverlay*, std::unique_ptr<WebCore::GraphicsLayer>> PageOverlayLayerMap;
- PageOverlayLayerMap m_pageOverlayLayers;
- OwnPtr<WebCore::TextureMapper> m_textureMapper;
- OwnPtr<WebCore::GLContext> m_context;
- double m_lastFlushTime;
- bool m_layerFlushSchedulingEnabled;
- unsigned m_layerFlushTimerCallbackId;
+ std::unique_ptr<WebCore::TextureMapper> m_textureMapper;
+ std::unique_ptr<WebCore::GLContext> m_context;
+ WebCore::TransformationMatrix m_scaleMatrix;
+ std::unique_ptr<AcceleratedSurface> m_surface;
+ RenderFrameScheduler m_renderFrameScheduler;
};
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.cpp
index 2d54bcc6c..8ddc912f6 100644
--- a/Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "PrinterListGtk.h"
-#ifdef HAVE_GTK_UNIX_PRINTING
+#if HAVE(GTK_UNIX_PRINTING)
#include <gtk/gtkunixprint.h>
@@ -34,27 +34,26 @@ namespace WebKit {
PrinterListGtk* PrinterListGtk::s_sharedPrinterList = nullptr;
-RefPtr<PrinterListGtk> PrinterListGtk::shared()
+RefPtr<PrinterListGtk> PrinterListGtk::getOrCreate()
{
if (s_sharedPrinterList)
- return s_sharedPrinterList;
+ return s_sharedPrinterList->isEnumeratingPrinters() ? nullptr : s_sharedPrinterList;
return adoptRef(new PrinterListGtk);
}
-gboolean PrinterListGtk::enumeratePrintersFunction(GtkPrinter* printer)
-{
- ASSERT(s_sharedPrinterList);
- s_sharedPrinterList->addPrinter(printer);
- return FALSE;
-}
-
PrinterListGtk::PrinterListGtk()
: m_defaultPrinter(nullptr)
+ , m_enumeratingPrinters(true)
{
ASSERT(!s_sharedPrinterList);
s_sharedPrinterList = this;
- gtk_enumerate_printers(reinterpret_cast<GtkPrinterFunc>(&enumeratePrintersFunction), nullptr, nullptr, TRUE);
+ gtk_enumerate_printers([](GtkPrinter* printer, gpointer) -> gboolean {
+ ASSERT(s_sharedPrinterList);
+ s_sharedPrinterList->addPrinter(printer);
+ return FALSE;
+ }, nullptr, nullptr, TRUE);
+ m_enumeratingPrinters = false;
}
PrinterListGtk::~PrinterListGtk()
@@ -81,4 +80,4 @@ GtkPrinter* PrinterListGtk::findPrinter(const char* printerName) const
} // namespace WebKit
-#endif // HAVE_GTK_UNIX_PRINTING
+#endif // HAVE(GTK_UNIX_PRINTING)
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.h b/Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.h
index 8d8a952b4..e13cb2995 100644
--- a/Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.h
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.h
@@ -26,11 +26,11 @@
#ifndef PrinterListGtk_h
#define PrinterListGtk_h
-#ifdef HAVE_GTK_UNIX_PRINTING
+#if HAVE(GTK_UNIX_PRINTING)
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
-#include <wtf/gobject/GRefPtr.h>
+#include <wtf/glib/GRefPtr.h>
typedef struct _GtkPrinter GtkPrinter;
@@ -38,7 +38,7 @@ namespace WebKit {
class PrinterListGtk: public RefCounted<PrinterListGtk> {
public:
- static RefPtr<PrinterListGtk> shared();
+ static RefPtr<PrinterListGtk> getOrCreate();
~PrinterListGtk();
GtkPrinter* findPrinter(const char*) const;
@@ -47,16 +47,17 @@ public:
private:
PrinterListGtk();
- static gboolean enumeratePrintersFunction(GtkPrinter*);
void addPrinter(GtkPrinter*);
+ bool isEnumeratingPrinters() const { return m_enumeratingPrinters; }
Vector<GRefPtr<GtkPrinter>, 4> m_printerList;
GtkPrinter* m_defaultPrinter;
+ bool m_enumeratingPrinters;
static PrinterListGtk* s_sharedPrinterList;
};
} // namespace WebKit
-#endif // HAVE_GTK_UNIX_PRINTING
+#endif // HAVE(GTK_UNIX_PRINTING)
#endif // WebPrintOperationGtk_h
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorUIGtk.cpp
index 5a0ef9e32..a0f1d4852 100644
--- a/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorUIGtk.cpp
@@ -25,9 +25,8 @@
*/
#include "config.h"
-#include "WebInspector.h"
-
-#if ENABLE(INSPECTOR)
+#include "WebInspectorUI.h"
+#include "RemoteWebInspectorUI.h"
#include <WebCore/FileSystem.h>
#include <glib.h>
@@ -35,16 +34,19 @@
namespace WebKit {
-bool WebInspector::canSave() const
+bool WebInspectorUI::canSave()
{
return false;
}
-String WebInspector::localizedStringsURL() const
+String WebInspectorUI::localizedStringsURL()
{
return String("resource:///org/webkitgtk/inspector/Localizations/en.lproj/localizedStrings.js");
}
-} // namespace WebKit
+String RemoteWebInspectorUI::localizedStringsURL()
+{
+ return String("resource:///org/webkitgtk/inspector/Localizations/en.lproj/localizedStrings.js");
+}
-#endif // ENABLE(INSPECTOR)
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp
index 338cf565b..f0e34efdc 100644
--- a/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp
@@ -28,22 +28,26 @@
#include "config.h"
#include "WebPage.h"
+#include "EditorState.h"
#include "NotImplemented.h"
#include "WebEvent.h"
+#include "WebFrame.h"
#include "WebPageAccessibilityObject.h"
#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
#include "WindowsKeyboardCodes.h"
#include <WebCore/BackForwardController.h>
#include <WebCore/EventHandler.h>
#include <WebCore/FocusController.h>
#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
#include <WebCore/KeyboardEvent.h>
#include <WebCore/Page.h>
#include <WebCore/PasteboardHelper.h>
#include <WebCore/PlatformKeyboardEvent.h>
#include <WebCore/Settings.h>
-#include <WebCore/UserAgentGtk.h>
-#include <wtf/gobject/GUniquePtr.h>
+#include <WebCore/UserAgent.h>
+#include <wtf/glib/GUniquePtr.h>
using namespace WebCore;
@@ -60,10 +64,46 @@ void WebPage::platformInitialize()
GUniquePtr<gchar> plugID(atk_plug_get_id(ATK_PLUG(m_accessibilityObject.get())));
send(Messages::WebPageProxy::BindAccessibilityTree(String(plugID.get())));
#endif
+}
-#if USE(TEXTURE_MAPPER_GL)
- m_nativeWindowHandle = 0;
-#endif
+void WebPage::platformDetach()
+{
+}
+
+void WebPage::platformEditorState(Frame& frame, EditorState& result, IncludePostLayoutDataHint shouldIncludePostLayoutData) const
+{
+ if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::No) {
+ result.isMissingPostLayoutData = true;
+ return;
+ }
+
+ auto& postLayoutData = result.postLayoutData();
+ postLayoutData.caretRectAtStart = frame.selection().absoluteCaretBounds();
+
+ const VisibleSelection& selection = frame.selection().selection();
+ if (selection.isNone())
+ return;
+
+ const Editor& editor = frame.editor();
+ if (selection.isRange()) {
+ if (editor.selectionHasStyle(CSSPropertyFontWeight, "bold") == TrueTriState)
+ postLayoutData.typingAttributes |= AttributeBold;
+ if (editor.selectionHasStyle(CSSPropertyFontStyle, "italic") == TrueTriState)
+ postLayoutData.typingAttributes |= AttributeItalics;
+ if (editor.selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline") == TrueTriState)
+ postLayoutData.typingAttributes |= AttributeUnderline;
+ if (editor.selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "line-through") == TrueTriState)
+ postLayoutData.typingAttributes |= AttributeStrikeThrough;
+ } else if (selection.isCaret()) {
+ if (editor.selectionStartHasStyle(CSSPropertyFontWeight, "bold"))
+ postLayoutData.typingAttributes |= AttributeBold;
+ if (editor.selectionStartHasStyle(CSSPropertyFontStyle, "italic"))
+ postLayoutData.typingAttributes |= AttributeItalics;
+ if (editor.selectionStartHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline"))
+ postLayoutData.typingAttributes |= AttributeUnderline;
+ if (editor.selectionStartHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "line-through"))
+ postLayoutData.typingAttributes |= AttributeStrikeThrough;
+ }
}
#if HAVE(ACCESSIBILITY)
@@ -81,23 +121,12 @@ void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
notImplemented();
}
-static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
-{
- page->focusController().focusedOrMainFrame().eventHandler().scrollRecursively(direction, granularity);
-}
-
bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
{
if (keyboardEvent.type() != WebEvent::KeyDown && keyboardEvent.type() != WebEvent::RawKeyDown)
return false;
switch (keyboardEvent.windowsVirtualKeyCode()) {
- case VK_BACK:
- if (keyboardEvent.shiftKey())
- m_page->backForward().goForward();
- else
- m_page->backForward().goBack();
- break;
case VK_SPACE:
scroll(m_page.get(), keyboardEvent.shiftKey() ? ScrollUp : ScrollDown, ScrollByPage);
break;
@@ -156,19 +185,12 @@ String WebPage::cachedSuggestedFilenameForURL(const URL&)
return String();
}
-PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const URL&)
+RefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const URL&)
{
notImplemented();
return 0;
}
-#if USE(TEXTURE_MAPPER_GL)
-void WebPage::setAcceleratedCompositingWindowId(int64_t nativeWindowHandle)
-{
- m_nativeWindowHandle = nativeWindowHandle;
-}
-#endif
-
String WebPage::platformUserAgent(const URL& url) const
{
if (url.isNull() || !m_page->settings().needsSiteSpecificQuirks())
@@ -177,4 +199,33 @@ String WebPage::platformUserAgent(const URL& url) const
return WebCore::standardUserAgentForURL(url);
}
+#if HAVE(GTK_GESTURES)
+void WebPage::getCenterForZoomGesture(const IntPoint& centerInViewCoordinates, IntPoint& result)
+{
+ result = mainFrameView()->rootViewToContents(centerInViewCoordinates);
+ double scale = m_page->pageScaleFactor();
+ result.scale(1 / scale, 1 / scale);
+}
+#endif
+
+void WebPage::setInputMethodState(bool enabled)
+{
+ if (m_inputMethodEnabled == enabled)
+ return;
+
+ m_inputMethodEnabled = enabled;
+ send(Messages::WebPageProxy::SetInputMethodState(enabled));
+}
+
+void WebPage::collapseSelectionInFrame(uint64_t frameID)
+{
+ WebFrame* frame = WebProcess::singleton().webFrame(frameID);
+ if (!frame || !frame->coreFrame())
+ return;
+
+ // Collapse the selection without clearing it.
+ const VisibleSelection& selection = frame->coreFrame()->selection().selection();
+ frame->coreFrame()->selection().setBase(selection.extent(), selection.affinity());
+}
+
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp
index e79cc75c2..fdd419394 100644
--- a/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp
@@ -40,10 +40,11 @@
#include <WebCore/ResourceError.h>
#include <WebCore/URL.h>
#include <gtk/gtk.h>
+#include <memory>
#include <wtf/Vector.h>
-#include <wtf/gobject/GUniquePtr.h>
+#include <wtf/glib/GUniquePtr.h>
-#ifdef HAVE_GTK_UNIX_PRINTING
+#if HAVE(GTK_UNIX_PRINTING)
#include "PrinterListGtk.h"
#include <cairo-pdf.h>
#include <cairo-ps.h>
@@ -52,7 +53,7 @@
namespace WebKit {
-#ifdef HAVE_GTK_UNIX_PRINTING
+#if HAVE(GTK_UNIX_PRINTING)
class WebPrintOperationGtkUnix final: public WebPrintOperationGtk {
public:
WebPrintOperationGtkUnix(WebPage* page, const PrintInfo& printInfo)
@@ -66,7 +67,8 @@ public:
m_printContext = printContext;
m_callbackID = callbackID;
- RefPtr<PrinterListGtk> printerList = PrinterListGtk::shared();
+ RefPtr<PrinterListGtk> printerList = PrinterListGtk::getOrCreate();
+ ASSERT(printerList);
const char* printerName = gtk_print_settings_get_printer(m_printSettings.get());
GtkPrinter* printer = printerName ? printerList->findPrinter(printerName) : printerList->defaultPrinter();
if (!printer) {
@@ -104,7 +106,7 @@ public:
print(surface, 72, 72);
}
- void startPage(cairo_t* cr) override
+ void startPage(cairo_t*) override
{
if (!currentPageIsFirstPageOfSheet())
return;
@@ -139,7 +141,7 @@ public:
cairo_show_page(cr);
}
- static void printJobComplete(GtkPrintJob* printJob, WebPrintOperationGtkUnix* printOperation, const GError* error)
+ static void printJobComplete(GtkPrintJob*, WebPrintOperationGtkUnix* printOperation, const GError* error)
{
printOperation->printDone(error ? printError(printOperation->frameURL(), error->message) : WebCore::ResourceError());
printOperation->m_printJob = 0;
@@ -148,13 +150,13 @@ public:
static void printJobFinished(WebPrintOperationGtkUnix* printOperation)
{
printOperation->deref();
- WebProcess::shared().enableTermination();
+ WebProcess::singleton().enableTermination();
}
void endPrint() override
{
// Disable web process termination until the print job finishes.
- WebProcess::shared().disableTermination();
+ WebProcess::singleton().disableTermination();
cairo_surface_finish(gtk_print_job_get_surface(m_printJob.get(), 0));
// Make sure the operation is alive until the job is sent.
@@ -208,6 +210,7 @@ struct PrintPagesData {
, firstSheetNumber(0)
, numberOfSheets(0)
, firstPagePosition(0)
+ , lastPagePosition(0)
, collated(0)
, uncollated(0)
, isDone(false)
@@ -360,7 +363,6 @@ struct PrintPagesData {
GRefPtr<GMainLoop> mainLoop;
int totalPrinted;
- size_t totalToPrint;
int pageNumber;
Vector<size_t> pages;
size_t sheetNumber;
@@ -379,11 +381,13 @@ struct PrintPagesData {
PassRefPtr<WebPrintOperationGtk> WebPrintOperationGtk::create(WebPage* page, const PrintInfo& printInfo)
{
-#ifdef HAVE_GTK_UNIX_PRINTING
+#if HAVE(GTK_UNIX_PRINTING)
return adoptRef(new WebPrintOperationGtkUnix(page, printInfo));
#elif defined(G_OS_WIN32)
return adoptRef(new WebPrintOperationGtkWin32(page, printInfo));
#else
+ UNUSED_PARAM(page);
+ UNUSED_PARAM(printInfo);
return 0;
#endif
}
@@ -695,7 +699,7 @@ void WebPrintOperationGtk::printPagesDone()
{
m_printPagesIdleId = 0;
endPrint();
- m_cairoContext = 0;
+ m_cairoContext = nullptr;
}
void WebPrintOperationGtk::printDone(const WebCore::ResourceError& error)
@@ -713,7 +717,7 @@ void WebPrintOperationGtk::print(cairo_surface_t* surface, double xDPI, double y
{
ASSERT(m_printContext);
- OwnPtr<PrintPagesData> data = adoptPtr(new PrintPagesData(this));
+ auto data = std::make_unique<PrintPagesData>(this);
if (!data->isValid) {
cairo_surface_finish(surface);
printDone(invalidPageRangeToPrint(frameURL()));
@@ -729,7 +733,7 @@ void WebPrintOperationGtk::print(cairo_surface_t* surface, double xDPI, double y
// operation has finished. See https://bugs.webkit.org/show_bug.cgi?id=122801.
unsigned idlePriority = m_printMode == PrintInfo::PrintModeSync ? G_PRIORITY_DEFAULT - 10 : G_PRIORITY_DEFAULT_IDLE + 10;
GMainLoop* mainLoop = data->mainLoop.get();
- m_printPagesIdleId = gdk_threads_add_idle_full(idlePriority, printPagesIdle, data.leakPtr(), printPagesIdleDone);
+ m_printPagesIdleId = gdk_threads_add_idle_full(idlePriority, printPagesIdle, data.release(), printPagesIdleDone);
if (m_printMode == PrintInfo::PrintModeSync) {
ASSERT(mainLoop);
g_main_loop_run(mainLoop);
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.h b/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.h
index c201a2ef9..f5fec106c 100644
--- a/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.h
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.h
@@ -30,7 +30,7 @@
#include <WebCore/RefPtrCairo.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/gobject/GRefPtr.h>
+#include <wtf/glib/GRefPtr.h>
typedef struct _GtkPrintSettings GtkPrintSettings;
typedef struct _GtkPageSetup GtkPageSetup;