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/DecoderAdapter.cpp89
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h55
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp72
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingArea.h122
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in42
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp679
-rw-r--r--Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h143
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp89
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h62
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp148
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EventDispatcher.h90
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in30
-rw-r--r--Source/WebKit2/WebProcess/WebPage/FindController.cpp360
-rw-r--r--Source/WebKit2/WebProcess/WebPage/FindController.h84
-rw-r--r--Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp67
-rw-r--r--Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h115
-rw-r--r--Source/WebKit2/WebProcess/WebPage/LayerTreeHost.messages.in29
-rw-r--r--Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp175
-rw-r--r--Source/WebKit2/WebProcess/WebPage/PageOverlay.h105
-rw-r--r--Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.cpp144
-rw-r--r--Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.h99
-rw-r--r--Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp187
-rw-r--r--Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h90
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp224
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h69
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp97
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebContextMenu.h53
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebFrame.cpp738
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebFrame.h164
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspector.cpp207
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspector.h110
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in37
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp51
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h54
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPage.cpp2900
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPage.h748
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPage.messages.in248
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp48
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h60
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp42
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebUndoStep.h55
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp278
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h111
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h68
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm136
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp263
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h87
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp164
-rw-r--r--Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h74
-rw-r--r--Source/WebKit2/WebProcess/WebPage/efl/WebInspectorEfl.cpp44
-rw-r--r--Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp102
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/ChunkedUpdateDrawingAreaGtk.cpp56
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp45
-rw-r--r--Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp136
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h70
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm152
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.h47
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.mm194
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm52
-rw-r--r--Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm710
-rw-r--r--Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp467
-rw-r--r--Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.h129
-rw-r--r--Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp44
-rw-r--r--Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp418
-rw-r--r--Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp64
-rw-r--r--Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp44
-rw-r--r--Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp48
-rw-r--r--Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp468
68 files changed, 13452 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp
new file mode 100644
index 000000000..7c93dae7f
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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"
+
+namespace WebKit {
+
+DecoderAdapter::DecoderAdapter(const uint8_t* buffer, size_t bufferSize)
+ : m_decoder(buffer, bufferSize)
+{
+}
+
+bool DecoderAdapter::decodeBytes(Vector<uint8_t>& bytes)
+{
+ CoreIPC::DataReference dataReference;
+ if (!m_decoder.decodeVariableLengthByteArray(dataReference))
+ return false;
+
+ bytes = dataReference.vector();
+ return true;
+}
+
+bool DecoderAdapter::decodeBool(bool& value)
+{
+ return m_decoder.decodeBool(value);
+}
+
+bool DecoderAdapter::decodeUInt32(uint32_t& value)
+{
+ return m_decoder.decodeUInt32(value);
+}
+
+bool DecoderAdapter::decodeUInt64(uint64_t& value)
+{
+ return m_decoder.decodeUInt64(value);
+}
+
+bool DecoderAdapter::decodeInt32(int32_t& value)
+{
+ return m_decoder.decodeInt32(value);
+}
+
+bool DecoderAdapter::decodeInt64(int64_t& value)
+{
+ return m_decoder.decodeInt64(value);
+}
+
+bool DecoderAdapter::decodeFloat(float& value)
+{
+ return m_decoder.decodeFloat(value);
+}
+
+bool DecoderAdapter::decodeDouble(double& value)
+{
+ return m_decoder.decodeDouble(value);
+}
+
+bool DecoderAdapter::decodeString(String& value)
+{
+ return m_decoder.decode(value);
+}
+
+}
diff --git a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h
new file mode 100644
index 000000000..bd34ea8d3
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#ifndef DecoderAdapter_h
+#define DecoderAdapter_h
+
+#include "ArgumentDecoder.h"
+#include <wtf/Decoder.h>
+#include <wtf/Forward.h>
+
+namespace WebKit {
+
+class DecoderAdapter : public Decoder {
+public:
+ DecoderAdapter(const uint8_t* buffer, size_t bufferSize);
+
+private:
+ virtual bool decodeBytes(Vector<uint8_t>&);
+ virtual bool decodeBool(bool&);
+ 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&);
+
+ CoreIPC::ArgumentDecoder m_decoder;
+};
+
+} // namespace WebKit
+
+#endif // DecoderAdapter_h
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp
new file mode 100644
index 000000000..9d42ce4a5
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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 "DrawingArea.h"
+
+// Subclasses
+#include "DrawingAreaImpl.h"
+
+#if USE(TILED_BACKING_STORE)
+#include "TiledDrawingArea.h"
+#endif
+
+#if PLATFORM(MAC)
+#include "TiledCoreAnimationDrawingArea.h"
+#endif
+
+#include "WebPageCreationParameters.h"
+
+namespace WebKit {
+
+PassOwnPtr<DrawingArea> DrawingArea::create(WebPage* webPage, const WebPageCreationParameters& parameters)
+{
+ switch (parameters.drawingAreaType) {
+ case DrawingAreaTypeImpl:
+ return DrawingAreaImpl::create(webPage, parameters);
+#if USE(TILED_BACKING_STORE)
+ case DrawingAreaTypeTiled:
+ return adoptPtr(new TiledDrawingArea(webPage));
+#endif
+#if PLATFORM(MAC)
+ case DrawingAreaTypeTiledCoreAnimation:
+ return TiledCoreAnimationDrawingArea::create(webPage, parameters);
+#endif
+ }
+
+ return nullptr;
+}
+
+DrawingArea::DrawingArea(DrawingAreaType type, WebPage* webPage)
+ : m_type(type)
+ , m_webPage(webPage)
+{
+}
+
+DrawingArea::~DrawingArea()
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingArea.h b/Source/WebKit2/WebProcess/WebPage/DrawingArea.h
new file mode 100644
index 000000000..ffbbdbb57
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.h
@@ -0,0 +1,122 @@
+/*
+ * 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 DrawingArea_h
+#define DrawingArea_h
+
+#include "DrawingAreaInfo.h"
+#include <WebCore/FloatPoint.h>
+#include <WebCore/IntRect.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace CoreIPC {
+ class ArgumentDecoder;
+ class Connection;
+ class MessageID;
+}
+
+namespace WebCore {
+ class GraphicsLayer;
+}
+
+namespace WebKit {
+
+class WebPage;
+struct WebPageCreationParameters;
+
+#if PLATFORM(WIN)
+struct WindowGeometry;
+#endif
+
+class DrawingArea {
+ WTF_MAKE_NONCOPYABLE(DrawingArea);
+
+public:
+ static PassOwnPtr<DrawingArea> create(WebPage*, const WebPageCreationParameters&);
+ virtual ~DrawingArea();
+
+ void didReceiveDrawingAreaMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+
+ virtual void setNeedsDisplay(const WebCore::IntRect&) = 0;
+ virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) = 0;
+
+ // FIXME: These should be pure virtual.
+ virtual void pageBackgroundTransparencyChanged() { }
+ virtual void forceRepaint() { }
+ virtual void setLayerTreeStateIsFrozen(bool) { }
+ virtual bool layerTreeStateIsFrozen() const { return false; }
+
+ virtual void didInstallPageOverlay() { }
+ virtual void didUninstallPageOverlay() { }
+ virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&) { }
+ virtual void pageCustomRepresentationChanged() { }
+
+ virtual void setPaintingEnabled(bool) { }
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) = 0;
+ virtual void scheduleCompositingLayerSync() = 0;
+#if USE(TEXTURE_MAPPER)
+ virtual void didReceiveLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*) = 0;
+#endif
+#endif
+
+#if PLATFORM(WIN)
+ virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&) = 0;
+#endif
+
+protected:
+ DrawingArea(DrawingAreaType, WebPage*);
+
+ DrawingAreaType m_type;
+ WebPage* m_webPage;
+
+private:
+ // CoreIPC 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() { }
+ virtual void suspendPainting() { }
+ virtual void resumePainting() { }
+
+#if PLATFORM(MAC)
+ // Used by TiledCoreAnimationDrawingArea.
+ virtual void updateGeometry(const WebCore::IntSize& viewSize) { }
+#endif
+
+#if USE(TILED_BACKING_STORE)
+ virtual void setSize(const WebCore::IntSize& viewSize) { }
+ virtual void setVisibleContentRectAndScale(const WebCore::IntRect&, float) { }
+ virtual void setVisibleContentRectTrajectoryVector(const WebCore::FloatPoint&) { }
+ virtual void setContentsScale(float scale) { }
+ virtual void renderNextFrame() { }
+ virtual void takeSnapshot(const WebCore::IntSize& targetSize, const WebCore::IntRect& contentsRect) { }
+#endif
+};
+
+} // namespace WebKit
+
+#endif // DrawingArea_h
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in b/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in
new file mode 100644
index 000000000..48c3e1ae5
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in
@@ -0,0 +1,42 @@
+# Copyright (C) 2010, 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.
+
+messages -> DrawingArea {
+ UpdateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, float deviceScaleFactor, WebCore::IntSize size, WebCore::IntSize scrollOffset)
+ DidUpdate()
+ SuspendPainting()
+ ResumePainting()
+ PageCustomRepresentationChanged()
+
+#if PLATFORM(MAC)
+ // Used by TiledCoreAnimationDrawingArea.
+ UpdateGeometry(WebCore::IntSize viewSize)
+#endif
+
+#if USE(TILED_BACKING_STORE)
+ SetSize(WebCore::IntSize viewSize)
+ SetVisibleContentRectAndScale(WebCore::IntRect visibleContentRect, float scale)
+ SetVisibleContentRectTrajectoryVector(WebCore::FloatPoint trajectoryVector)
+ RenderNextFrame()
+ TakeSnapshot(WebCore::IntSize size, WebCore::IntRect contentsRect)
+#endif
+}
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp
new file mode 100644
index 000000000..e281d3652
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp
@@ -0,0 +1,679 @@
+/*
+ * 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 "DrawingAreaImpl.h"
+
+#include "DrawingAreaProxyMessages.h"
+#include "LayerTreeContext.h"
+#include "ShareableBitmap.h"
+#include "UpdateInfo.h"
+#include "WebPage.h"
+#include "WebPageCreationParameters.h"
+#include "WebProcess.h"
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/Page.h>
+#include <WebCore/Settings.h>
+
+using namespace WebCore;
+using namespace std;
+
+namespace WebKit {
+
+PassOwnPtr<DrawingAreaImpl> DrawingAreaImpl::create(WebPage* webPage, const WebPageCreationParameters& parameters)
+{
+ return adoptPtr(new DrawingAreaImpl(webPage, parameters));
+}
+
+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.isVisible)
+ , m_alwaysUseCompositing(false)
+ , m_displayTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::displayTimerFired)
+ , m_exitCompositingTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::exitAcceleratedCompositingMode)
+{
+ if (webPage->corePage()->settings()->acceleratedDrawingEnabled())
+ m_alwaysUseCompositing = true;
+
+ if (m_alwaysUseCompositing)
+ enterAcceleratedCompositingMode(0);
+}
+
+void DrawingAreaImpl::setNeedsDisplay(const IntRect& rect)
+{
+ if (!m_isPaintingEnabled)
+ return;
+
+ IntRect dirtyRect = rect;
+ dirtyRect.intersect(m_webPage->bounds());
+
+ if (dirtyRect.isEmpty())
+ return;
+
+ if (m_layerTreeHost) {
+ ASSERT(m_dirtyRegion.isEmpty());
+
+ m_layerTreeHost->setNonCompositedContentsNeedDisplay(dirtyRect);
+ return;
+ }
+
+ if (m_webPage->mainFrameHasCustomRepresentation())
+ return;
+
+ m_dirtyRegion.unite(dirtyRect);
+ scheduleDisplay();
+}
+
+void DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
+{
+ if (!m_isPaintingEnabled)
+ return;
+
+ if (m_layerTreeHost) {
+ ASSERT(m_scrollRect.isEmpty());
+ ASSERT(m_scrollOffset.isEmpty());
+ ASSERT(m_dirtyRegion.isEmpty());
+
+ m_layerTreeHost->scrollNonCompositedContents(scrollRect, scrollOffset);
+ return;
+ }
+
+ if (m_webPage->mainFrameHasCustomRepresentation())
+ return;
+
+ if (!m_scrollRect.isEmpty() && scrollRect != m_scrollRect) {
+ unsigned scrollArea = scrollRect.width() * scrollRect.height();
+ unsigned currentScrollArea = m_scrollRect.width() * m_scrollRect.height();
+
+ if (currentScrollArea >= scrollArea) {
+ // The rect being scrolled is at least as large as the rect we'd like to scroll.
+ // Go ahead and just invalidate the scroll rect.
+ setNeedsDisplay(scrollRect);
+ return;
+ }
+
+ // Just repaint the entire current scroll rect, we'll scroll the new rect instead.
+ setNeedsDisplay(m_scrollRect);
+ m_scrollRect = IntRect();
+ m_scrollOffset = IntSize();
+ }
+
+ // Get the part of the dirty region that is in the scroll rect.
+ Region dirtyRegionInScrollRect = intersect(scrollRect, m_dirtyRegion);
+ if (!dirtyRegionInScrollRect.isEmpty()) {
+ // There are parts of the dirty region that are inside the scroll rect.
+ // We need to subtract them from the region, move them and re-add them.
+ m_dirtyRegion.subtract(scrollRect);
+
+ // Move the dirty parts.
+ Region movedDirtyRegionInScrollRect = intersect(translate(dirtyRegionInScrollRect, scrollOffset), scrollRect);
+
+ // And add them back.
+ m_dirtyRegion.unite(movedDirtyRegionInScrollRect);
+ }
+
+ // Compute the scroll repaint region.
+ Region scrollRepaintRegion = subtract(scrollRect, translate(scrollRect, scrollOffset));
+
+ m_dirtyRegion.unite(scrollRepaintRegion);
+ scheduleDisplay();
+
+ m_scrollRect = scrollRect;
+ m_scrollOffset += scrollOffset;
+}
+
+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->bounds());
+
+ 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();
+ }
+ return;
+ }
+
+ m_isWaitingForDidUpdate = false;
+ display();
+}
+
+void DrawingAreaImpl::didInstallPageOverlay()
+{
+ if (m_layerTreeHost)
+ m_layerTreeHost->didInstallPageOverlay();
+}
+
+void DrawingAreaImpl::didUninstallPageOverlay()
+{
+ if (m_layerTreeHost)
+ m_layerTreeHost->didUninstallPageOverlay();
+
+ setNeedsDisplay(m_webPage->bounds());
+}
+
+void DrawingAreaImpl::setPageOverlayNeedsDisplay(const IntRect& rect)
+{
+ if (m_layerTreeHost) {
+ m_layerTreeHost->setPageOverlayNeedsDisplay(rect);
+ return;
+ }
+
+ setNeedsDisplay(rect);
+}
+
+void DrawingAreaImpl::pageCustomRepresentationChanged()
+{
+ if (!m_alwaysUseCompositing)
+ return;
+
+ if (m_webPage->mainFrameHasCustomRepresentation()) {
+ if (m_layerTreeHost)
+ exitAcceleratedCompositingMode();
+ } else if (!m_layerTreeHost)
+ enterAcceleratedCompositingMode(0);
+}
+
+void DrawingAreaImpl::setPaintingEnabled(bool paintingEnabled)
+{
+ m_isPaintingEnabled = paintingEnabled;
+}
+
+void DrawingAreaImpl::layerHostDidFlushLayers()
+{
+ ASSERT(m_layerTreeHost);
+
+ m_layerTreeHost->forceRepaint();
+
+ if (m_shouldSendDidUpdateBackingStoreState && !exitAcceleratedCompositingModePending()) {
+ sendDidUpdateBackingStoreState();
+ return;
+ }
+
+ if (!m_layerTreeHost)
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ ASSERT(!m_compositingAccordingToProxyMessages);
+ if (!exitAcceleratedCompositingModePending()) {
+ m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(m_backingStoreStateID, m_layerTreeHost->layerTreeContext()));
+ m_compositingAccordingToProxyMessages = true;
+ }
+#endif
+}
+
+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();
+ }
+ }
+ }
+}
+
+void DrawingAreaImpl::scheduleCompositingLayerSync()
+{
+ if (!m_layerTreeHost)
+ return;
+ m_layerTreeHost->scheduleLayerFlush();
+}
+
+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->deviceScaleFactorDidChange();
+ m_layerTreeHost->sizeDidChange(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;
+ }
+ }
+
+ // 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()
+{
+ ASSERT(!m_isWaitingForDidUpdate);
+ ASSERT(m_shouldSendDidUpdateBackingStoreState);
+
+ m_shouldSendDidUpdateBackingStoreState = false;
+
+ UpdateInfo updateInfo;
+
+ if (!m_isPaintingSuspended && !m_layerTreeHost)
+ display(updateInfo);
+
+ 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();
+ }
+ }
+
+ m_webPage->send(Messages::DrawingAreaProxy::DidUpdateBackingStoreState(m_backingStoreStateID, updateInfo, layerTreeContext));
+ m_compositingAccordingToProxyMessages = !layerTreeContext.isEmpty();
+}
+
+void DrawingAreaImpl::didUpdate()
+{
+ // We might get didUpdate messages from the UI process even after we've
+ // entered accelerated compositing mode. Ignore them.
+ if (m_layerTreeHost)
+ return;
+
+ m_isWaitingForDidUpdate = false;
+
+ // Display if needed. We call displayTimerFired here since it will throttle updates to 60fps.
+ displayTimerFired();
+}
+
+void DrawingAreaImpl::suspendPainting()
+{
+ ASSERT(!m_isPaintingSuspended);
+
+ if (m_layerTreeHost)
+ m_layerTreeHost->pauseRendering();
+
+ m_isPaintingSuspended = true;
+ m_displayTimer.stop();
+
+ m_webPage->corePage()->suspendScriptedAnimations();
+}
+
+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(m_webPage->bounds());
+
+ m_webPage->corePage()->resumeScriptedAnimations();
+}
+
+void DrawingAreaImpl::enterAcceleratedCompositingMode(GraphicsLayer* graphicsLayer)
+{
+ m_exitCompositingTimer.stop();
+ m_wantsToExitAcceleratedCompositingMode = false;
+
+ 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();
+ m_scrollOffset = IntSize();
+ m_displayTimer.stop();
+ m_isWaitingForDidUpdate = false;
+}
+
+void DrawingAreaImpl::exitAcceleratedCompositingMode()
+{
+ if (m_alwaysUseCompositing && !m_webPage->mainFrameHasCustomRepresentation())
+ return;
+
+ ASSERT(!m_layerTreeStateIsFrozen);
+
+ m_exitCompositingTimer.stop();
+ m_wantsToExitAcceleratedCompositingMode = false;
+
+ ASSERT(m_layerTreeHost);
+
+ m_layerTreeHost->invalidate();
+ m_layerTreeHost = nullptr;
+ m_dirtyRegion = m_webPage->bounds();
+
+ if (m_inUpdateBackingStoreState)
+ return;
+
+ if (m_shouldSendDidUpdateBackingStoreState) {
+ sendDidUpdateBackingStoreState();
+ return;
+ }
+
+ UpdateInfo updateInfo;
+ if (m_isPaintingSuspended) {
+ 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_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;
+ }
+
+ if (exitAcceleratedCompositingModePending())
+ return;
+
+ m_exitCompositingTimer.startOneShot(0);
+}
+
+void DrawingAreaImpl::scheduleDisplay()
+{
+ ASSERT(!m_layerTreeHost);
+
+ if (m_isWaitingForDidUpdate)
+ return;
+
+ if (m_isPaintingSuspended)
+ return;
+
+ if (m_dirtyRegion.isEmpty())
+ return;
+
+ if (m_displayTimer.isActive())
+ return;
+
+ m_displayTimer.startOneShot(0);
+}
+
+void DrawingAreaImpl::displayTimerFired()
+{
+ display();
+}
+
+void DrawingAreaImpl::display()
+{
+ ASSERT(!m_layerTreeHost);
+ ASSERT(!m_isWaitingForDidUpdate);
+ ASSERT(!m_inUpdateBackingStoreState);
+
+ if (m_isPaintingSuspended)
+ return;
+
+ if (m_dirtyRegion.isEmpty())
+ return;
+
+ if (m_shouldSendDidUpdateBackingStoreState) {
+ sendDidUpdateBackingStoreState();
+ return;
+ }
+
+ UpdateInfo updateInfo;
+ display(updateInfo);
+
+ if (m_layerTreeHost) {
+ // The call to update caused layout which turned on accelerated compositing.
+ // Don't send an Update message in this case.
+ return;
+ }
+
+ m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
+ m_isWaitingForDidUpdate = true;
+}
+
+static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>& rects)
+{
+ const size_t rectThreshold = 10;
+ const double wastedSpaceThreshold = 0.75;
+
+ if (rects.size() <= 1 || rects.size() > rectThreshold)
+ return true;
+
+ // Attempt to guess whether or not we should use the region bounds rect or the individual rects.
+ // We do this by computing the percentage of "wasted space" in the bounds. If that wasted space
+ // is too large, then we will do individual rect painting instead.
+ unsigned boundsArea = bounds.width() * bounds.height();
+ unsigned rectsArea = 0;
+ for (size_t i = 0; i < rects.size(); ++i)
+ rectsArea += rects[i].width() * rects[i].height();
+
+ double wastedSpace = 1 - (static_cast<double>(rectsArea) / boundsArea);
+
+ return wastedSpace <= wastedSpaceThreshold;
+}
+
+#if !PLATFORM(WIN)
+PassOwnPtr<GraphicsContext> DrawingAreaImpl::createGraphicsContext(ShareableBitmap* bitmap)
+{
+ return bitmap->createGraphicsContext();
+}
+#endif
+
+void DrawingAreaImpl::display(UpdateInfo& updateInfo)
+{
+ ASSERT(!m_isPaintingSuspended);
+ ASSERT(!m_layerTreeHost);
+ ASSERT(!m_webPage->size().isEmpty());
+
+ // FIXME: It would be better if we could avoid painting altogether when there is a custom representation.
+ if (m_webPage->mainFrameHasCustomRepresentation()) {
+ // ASSUMPTION: the custom representation will be painting the dirty region for us.
+ m_dirtyRegion = Region();
+ return;
+ }
+
+ 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();
+
+ IntRect bounds = m_dirtyRegion.bounds();
+ ASSERT(m_webPage->bounds().contains(bounds));
+
+ IntSize bitmapSize = bounds.size();
+ float deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor();
+ bitmapSize.scale(deviceScaleFactor);
+ RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bitmapSize, ShareableBitmap::SupportsAlpha);
+ if (!bitmap)
+ return;
+
+ if (!bitmap->createHandle(updateInfo.bitmapHandle))
+ return;
+
+ Vector<IntRect> rects = m_dirtyRegion.rects();
+
+ if (shouldPaintBoundsRect(bounds, rects)) {
+ rects.clear();
+ rects.append(bounds);
+ }
+
+ updateInfo.scrollRect = m_scrollRect;
+ updateInfo.scrollOffset = m_scrollOffset;
+
+ m_dirtyRegion = Region();
+ m_scrollRect = IntRect();
+ m_scrollOffset = IntSize();
+
+ OwnPtr<GraphicsContext> graphicsContext = createGraphicsContext(bitmap.get());
+ graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
+
+ updateInfo.updateRectBounds = bounds;
+
+ 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())
+ m_webPage->drawPageOverlay(*graphicsContext, rects[i]);
+ updateInfo.updateRects.append(rects[i]);
+ }
+
+ // Layout can trigger more calls to setNeedsDisplay and we don't want to process them
+ // until the UI process has painted the update, so we stop the timer here.
+ m_displayTimer.stop();
+}
+
+#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
+void DrawingAreaImpl::didReceiveLayerTreeHostMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
+{
+ if (m_layerTreeHost)
+ m_layerTreeHost->didReceiveLayerTreeHostMessage(connection, messageID, arguments);
+}
+#endif
+
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h
new file mode 100644
index 000000000..0dabf603a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+#ifndef DrawingAreaImpl_h
+#define DrawingAreaImpl_h
+
+#include "DrawingArea.h"
+#include "LayerTreeHost.h"
+#include "RunLoop.h"
+#include <WebCore/Region.h>
+
+namespace WebCore {
+ class GraphicsContext;
+}
+
+namespace WebKit {
+
+class ShareableBitmap;
+class UpdateInfo;
+
+class DrawingAreaImpl : public DrawingArea {
+public:
+ static PassOwnPtr<DrawingAreaImpl> create(WebPage*, const WebPageCreationParameters&);
+ virtual ~DrawingAreaImpl();
+
+ void layerHostDidFlushLayers();
+
+private:
+ DrawingAreaImpl(WebPage*, const WebPageCreationParameters&);
+
+ // DrawingArea
+ virtual void setNeedsDisplay(const WebCore::IntRect&);
+ virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset);
+ virtual void setLayerTreeStateIsFrozen(bool);
+ virtual bool layerTreeStateIsFrozen() const { return m_layerTreeStateIsFrozen; }
+ virtual void forceRepaint();
+
+ virtual void didInstallPageOverlay();
+ virtual void didUninstallPageOverlay();
+ virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&);
+
+ virtual void setPaintingEnabled(bool);
+
+ virtual void setRootCompositingLayer(WebCore::GraphicsLayer*);
+ virtual void scheduleCompositingLayerSync();
+
+#if PLATFORM(WIN)
+ virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&);
+#endif
+
+#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
+ virtual void didReceiveLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+#endif
+
+ // CoreIPC 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();
+
+ virtual void pageCustomRepresentationChanged();
+
+ void sendDidUpdateBackingStoreState();
+
+ void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*);
+ void exitAcceleratedCompositingModeSoon();
+ bool exitAcceleratedCompositingModePending() const { return m_exitCompositingTimer.isActive(); }
+ void exitAcceleratedCompositingMode();
+
+ void scheduleDisplay();
+ void displayTimerFired();
+ void display();
+ void display(UpdateInfo&);
+ PassOwnPtr<WebCore::GraphicsContext> createGraphicsContext(ShareableBitmap*);
+
+ 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;
+
+ // 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;
+
+ 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
new file mode 100644
index 000000000..547b68d73
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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"
+
+namespace WebKit {
+
+EncoderAdapter::EncoderAdapter()
+ : m_encoder(CoreIPC::ArgumentEncoder::create(0))
+{
+}
+
+CoreIPC::DataReference EncoderAdapter::dataReference() const
+{
+ return CoreIPC::DataReference(m_encoder->buffer(), m_encoder->bufferSize());
+}
+
+void EncoderAdapter::encodeBytes(const uint8_t* bytes, size_t size)
+{
+ m_encoder->encodeVariableLengthByteArray(CoreIPC::DataReference(bytes, size));
+}
+
+void EncoderAdapter::encodeBool(bool value)
+{
+ m_encoder->encodeBool(value);
+}
+
+void EncoderAdapter::encodeUInt32(uint32_t value)
+{
+ m_encoder->encodeUInt32(value);
+}
+
+void EncoderAdapter::encodeUInt64(uint64_t value)
+{
+ m_encoder->encodeUInt64(value);
+}
+
+void EncoderAdapter::encodeInt32(int32_t value)
+{
+ m_encoder->encodeInt32(value);
+}
+
+void EncoderAdapter::encodeInt64(int64_t value)
+{
+ m_encoder->encodeInt64(value);
+}
+
+void EncoderAdapter::encodeFloat(float value)
+{
+ m_encoder->encodeFloat(value);
+}
+
+void EncoderAdapter::encodeDouble(double value)
+{
+ m_encoder->encodeDouble(value);
+}
+
+void EncoderAdapter::encodeString(const String& value)
+{
+ m_encoder->encode(value);
+}
+
+}
diff --git a/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h
new file mode 100644
index 000000000..47de7afd5
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef EncoderAdapter_h
+#define EncoderAdapter_h
+
+#include <wtf/Encoder.h>
+#include <wtf/Forward.h>
+#include <wtf/OwnPtr.h>
+
+namespace CoreIPC {
+ class ArgumentEncoder;
+ class DataReference;
+}
+
+namespace WebKit {
+
+class EncoderAdapter : public Encoder {
+public:
+ EncoderAdapter();
+
+ CoreIPC::DataReference dataReference() const;
+
+private:
+ virtual void encodeBytes(const uint8_t*, size_t);
+ virtual void encodeBool(bool);
+ 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&);
+
+ OwnPtr<CoreIPC::ArgumentEncoder> m_encoder;
+};
+
+} // namespace WebKit
+
+#endif // EncoderAdapter_h
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
new file mode 100644
index 000000000..6486587d0
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
@@ -0,0 +1,148 @@
+/*
+ * 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 "EventDispatcher.h"
+
+#include "RunLoop.h"
+#include "WebEvent.h"
+#include "WebEventConversion.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
+#include <WebCore/Page.h>
+#include <wtf/MainThread.h>
+
+#if ENABLE(THREADED_SCROLLING)
+#include <WebCore/ScrollingCoordinator.h>
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+EventDispatcher::EventDispatcher()
+{
+}
+
+EventDispatcher::~EventDispatcher()
+{
+}
+
+#if ENABLE(THREADED_SCROLLING)
+void EventDispatcher::addScrollingCoordinatorForPage(WebPage* webPage)
+{
+ MutexLocker locker(m_scrollingCoordinatorsMutex);
+
+ ASSERT(webPage->corePage()->scrollingCoordinator());
+ ASSERT(!m_scrollingCoordinators.contains(webPage->pageID()));
+ m_scrollingCoordinators.set(webPage->pageID(), webPage->corePage()->scrollingCoordinator());
+}
+
+void EventDispatcher::removeScrollingCoordinatorForPage(WebPage* webPage)
+{
+ MutexLocker locker(m_scrollingCoordinatorsMutex);
+ ASSERT(m_scrollingCoordinators.contains(webPage->pageID()));
+
+ m_scrollingCoordinators.remove(webPage->pageID());
+}
+#endif
+
+void EventDispatcher::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage)
+{
+ if (messageID.is<CoreIPC::MessageClassEventDispatcher>()) {
+ didReceiveEventDispatcherMessageOnConnectionWorkQueue(connection, messageID, arguments, didHandleMessage);
+ return;
+ }
+}
+
+void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent)
+{
+#if ENABLE(THREADED_SCROLLING)
+ MutexLocker locker(m_scrollingCoordinatorsMutex);
+ if (ScrollingCoordinator* scrollingCoordinator = m_scrollingCoordinators.get(pageID).get()) {
+ PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
+
+ if (scrollingCoordinator->handleWheelEvent(platformWheelEvent)) {
+ sendDidHandleEvent(pageID, wheelEvent);
+ return;
+ }
+ }
+#endif
+
+ RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchWheelEvent, this, pageID, wheelEvent));
+}
+
+#if ENABLE(GESTURE_EVENTS)
+void EventDispatcher::gestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent)
+{
+#if ENABLE(THREADED_SCROLLING)
+ MutexLocker locker(m_scrollingCoordinatorsMutex);
+ if (ScrollingCoordinator* scrollingCoordinator = m_scrollingCoordinators.get(pageID).get()) {
+ PlatformGestureEvent platformGestureEvent = platform(gestureEvent);
+
+ if (scrollingCoordinator->handleGestureEvent(platformGestureEvent)) {
+ sendDidHandleEvent(pageID, gestureEvent);
+ return;
+ }
+ }
+#endif
+
+ RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchGestureEvent, this, pageID, gestureEvent));
+}
+#endif
+
+void EventDispatcher::dispatchWheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent)
+{
+ ASSERT(isMainThread());
+
+ WebPage* webPage = WebProcess::shared().webPage(pageID);
+ if (!webPage)
+ return;
+
+ webPage->wheelEvent(wheelEvent);
+}
+
+#if ENABLE(GESTURE_EVENTS)
+void EventDispatcher::dispatchGestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent)
+{
+ ASSERT(isMainThread());
+
+ WebPage* webPage = WebProcess::shared().webPage(pageID);
+ if (!webPage)
+ return;
+
+ webPage->gestureEvent(gestureEvent);
+}
+#endif
+
+#if ENABLE(THREADED_SCROLLING)
+void EventDispatcher::sendDidHandleEvent(uint64_t pageID, const WebEvent& event)
+{
+ WebProcess::shared().connection()->send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(event.type()), true), pageID);
+}
+#endif
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h
new file mode 100644
index 000000000..7cd2f9550
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+#ifndef EventDispatcher_h
+#define EventDispatcher_h
+
+#include "Connection.h"
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
+#include <wtf/ThreadingPrimitives.h>
+
+namespace WebCore {
+ class ScrollingCoordinator;
+}
+
+namespace WebKit {
+
+class WebEvent;
+class WebPage;
+class WebWheelEvent;
+
+#if ENABLE(GESTURE_EVENTS)
+class WebGestureEvent;
+#endif
+
+class EventDispatcher : public CoreIPC::Connection::QueueClient {
+ WTF_MAKE_NONCOPYABLE(EventDispatcher);
+
+public:
+ EventDispatcher();
+ ~EventDispatcher();
+
+#if ENABLE(THREADED_SCROLLING)
+ void addScrollingCoordinatorForPage(WebPage*);
+ void removeScrollingCoordinatorForPage(WebPage*);
+#endif
+
+private:
+ // CoreIPC::Connection::QueueClient
+ virtual void didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, bool& didHandleMessage) OVERRIDE;
+
+ // Implemented in generated EventDispatcherMessageReceiver.cpp
+ void didReceiveEventDispatcherMessageOnConnectionWorkQueue(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage);
+
+ // Message handlers
+ void wheelEvent(uint64_t pageID, const WebWheelEvent&);
+#if ENABLE(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(GESTURE_EVENTS)
+ void dispatchGestureEvent(uint64_t pageID, const WebGestureEvent&);
+#endif
+
+#if ENABLE(THREADED_SCROLLING)
+ void sendDidHandleEvent(uint64_t pageID, const WebEvent&);
+
+ Mutex m_scrollingCoordinatorsMutex;
+ HashMap<uint64_t, RefPtr<WebCore::ScrollingCoordinator> > m_scrollingCoordinators;
+#endif
+};
+
+} // namespace WebKit
+
+#endif // EventDispatcher_h
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in
new file mode 100644
index 000000000..a15571be5
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in
@@ -0,0 +1,30 @@
+# 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.
+
+messages -> EventDispatcher {
+ WheelEvent(uint64_t pageID, WebKit::WebWheelEvent event) DispatchOnConnectionQueue
+
+#if ENABLE(GESTURE_EVENTS)
+ GestureEvent(uint64_t pageID, WebKit::WebGestureEvent event) DispatchOnConnectionQueue
+#endif
+
+}
diff --git a/Source/WebKit2/WebProcess/WebPage/FindController.cpp b/Source/WebKit2/WebProcess/WebPage/FindController.cpp
new file mode 100644
index 000000000..9bdd80bb9
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/FindController.cpp
@@ -0,0 +1,360 @@
+/*
+ * 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 "FindController.h"
+
+#include "ShareableBitmap.h"
+#include "WKPage.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
+#include <WebCore/DocumentMarkerController.h>
+#include <WebCore/FocusController.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/Page.h>
+
+using namespace std;
+using namespace WebCore;
+
+namespace WebKit {
+
+static WebCore::FindOptions core(FindOptions options)
+{
+ return (options & FindOptionsCaseInsensitive ? CaseInsensitive : 0)
+ | (options & FindOptionsAtWordStarts ? AtWordStarts : 0)
+ | (options & FindOptionsTreatMedialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0)
+ | (options & FindOptionsBackwards ? Backwards : 0)
+ | (options & FindOptionsWrapAround ? WrapAround : 0);
+}
+
+FindController::FindController(WebPage* webPage)
+ : m_webPage(webPage)
+ , m_findPageOverlay(0)
+ , m_isShowingFindIndicator(false)
+{
+}
+
+FindController::~FindController()
+{
+}
+
+void FindController::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
+{
+ if (maxMatchCount == numeric_limits<unsigned>::max())
+ --maxMatchCount;
+
+ unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1);
+ m_webPage->corePage()->unmarkAllTextMatches();
+
+ // Check if we have more matches than allowed.
+ if (matchCount > maxMatchCount)
+ matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount);
+
+ m_webPage->send(Messages::WebPageProxy::DidCountStringMatches(string, matchCount));
+}
+
+static Frame* frameWithSelection(Page* page)
+{
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->selection()->isRange())
+ return frame;
+ }
+
+ return 0;
+}
+
+void FindController::findString(const String& string, FindOptions options, unsigned maxMatchCount)
+{
+ m_webPage->corePage()->unmarkAllTextMatches();
+
+ bool found = m_webPage->corePage()->findString(string, core(options));
+
+ Frame* selectedFrame = frameWithSelection(m_webPage->corePage());
+
+ bool shouldShowOverlay = false;
+
+ if (!found) {
+ // Clear the selection.
+ if (selectedFrame)
+ selectedFrame->selection()->clear();
+
+ hideFindIndicator();
+
+ m_webPage->send(Messages::WebPageProxy::DidFailToFindString(string));
+ } else {
+ shouldShowOverlay = options & FindOptionsShowOverlay;
+
+ if (shouldShowOverlay) {
+ if (maxMatchCount == numeric_limits<unsigned>::max())
+ --maxMatchCount;
+
+ unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1);
+
+ // Check if we have more matches than allowed.
+ if (matchCount > maxMatchCount) {
+ shouldShowOverlay = false;
+ matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount);
+ }
+
+ m_webPage->send(Messages::WebPageProxy::DidFindString(string, matchCount));
+ }
+
+ if (!(options & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay)) {
+ // Either we shouldn't show the find indicator, or we couldn't update it.
+ hideFindIndicator();
+ }
+ }
+
+ if (!shouldShowOverlay) {
+ if (m_findPageOverlay) {
+ // Get rid of the overlay.
+ m_webPage->uninstallPageOverlay(m_findPageOverlay, false);
+ }
+
+ ASSERT(!m_findPageOverlay);
+ return;
+ }
+
+ if (!m_findPageOverlay) {
+ RefPtr<PageOverlay> findPageOverlay = PageOverlay::create(this);
+ m_findPageOverlay = findPageOverlay.get();
+ m_webPage->installPageOverlay(findPageOverlay.release());
+ } else {
+ // The page overlay needs to be repainted.
+ m_findPageOverlay->setNeedsDisplay();
+ }
+}
+
+void FindController::hideFindUI()
+{
+ if (m_findPageOverlay)
+ m_webPage->uninstallPageOverlay(m_findPageOverlay, false);
+
+ hideFindIndicator();
+}
+
+bool FindController::updateFindIndicator(Frame* selectedFrame, bool isShowingOverlay, bool shouldAnimate)
+{
+ if (!selectedFrame)
+ return false;
+
+ IntRect selectionRect = enclosingIntRect(selectedFrame->selection()->bounds());
+
+ // Selection rect can be empty for matches that are currently obscured from view.
+ if (selectionRect.isEmpty())
+ return false;
+
+ // We want the selection rect in window coordinates.
+ IntRect selectionRectInWindowCoordinates = selectedFrame->view()->contentsToWindow(selectionRect);
+
+ Vector<FloatRect> textRects;
+ selectedFrame->selection()->getClippedVisibleTextRectangles(textRects);
+
+ 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;
+
+ OwnPtr<GraphicsContext> graphicsContext = findIndicatorTextBackingStore->createGraphicsContext();
+ graphicsContext->scale(FloatSize(m_webPage->corePage()->deviceScaleFactor(), m_webPage->corePage()->deviceScaleFactor()));
+
+ IntRect paintRect = selectionRect;
+ paintRect.move(selectedFrame->view()->frameRect().x(), selectedFrame->view()->frameRect().y());
+ paintRect.move(-selectedFrame->view()->scrollOffset());
+
+ graphicsContext->translate(-paintRect.x(), -paintRect.y());
+ selectedFrame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorForceBlackText | PaintBehaviorFlattenCompositingLayers);
+ selectedFrame->document()->updateLayout();
+
+ selectedFrame->view()->paint(graphicsContext.get(), paintRect);
+ selectedFrame->view()->setPaintBehavior(PaintBehaviorNormal);
+
+ ShareableBitmap::Handle handle;
+ if (!findIndicatorTextBackingStore->createHandle(handle))
+ return false;
+
+ // 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_isShowingFindIndicator = true;
+
+ return true;
+}
+
+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_isShowingFindIndicator = false;
+}
+
+void FindController::showFindIndicatorInSelection()
+{
+ Frame* selectedFrame = m_webPage->corePage()->focusController()->focusedOrMainFrame();
+ if (!selectedFrame)
+ return;
+
+ updateFindIndicator(selectedFrame, false);
+}
+
+void FindController::deviceScaleFactorDidChange()
+{
+ ASSERT(isShowingOverlay());
+
+ Frame* selectedFrame = frameWithSelection(m_webPage->corePage());
+ if (!selectedFrame)
+ return;
+
+ updateFindIndicator(selectedFrame, true, false);
+}
+
+Vector<IntRect> FindController::rectsForTextMatches()
+{
+ Vector<IntRect> rects;
+
+ 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()->scrollOffset().width(), -frame->view()->scrollOffset().height());
+ frameOffset = frame->view()->convertToContainingWindow(frameOffset);
+
+ 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);
+ }
+ }
+
+ return rects;
+}
+
+void FindController::pageOverlayDestroyed(PageOverlay*)
+{
+}
+
+void FindController::willMoveToWebPage(PageOverlay*, WebPage* webPage)
+{
+ if (webPage)
+ return;
+
+ // The page overlay is moving away from the web page, reset it.
+ ASSERT(m_findPageOverlay);
+ m_findPageOverlay = 0;
+}
+
+void FindController::didMoveToWebPage(PageOverlay*, WebPage*)
+{
+}
+
+static const float shadowOffsetX = 0.0;
+static const float shadowOffsetY = 1.0;
+static const float shadowBlurRadius = 2.0;
+static const float whiteFrameThickness = 1.0;
+
+static const float overlayBackgroundRed = 0.1;
+static const float overlayBackgroundGreen = 0.1;
+static const float overlayBackgroundBlue = 0.1;
+static const float overlayBackgroundAlpha = 0.25;
+
+static Color overlayBackgroundColor(float fractionFadedIn)
+{
+ return Color(overlayBackgroundRed, overlayBackgroundGreen, overlayBackgroundBlue, overlayBackgroundAlpha * fractionFadedIn);
+}
+
+static Color holeShadowColor(float fractionFadedIn)
+{
+ return Color(0.0f, 0.0f, 0.0f, fractionFadedIn);
+}
+
+static Color holeFillColor(float fractionFadedIn)
+{
+ return Color(1.0f, 1.0f, 1.0f, fractionFadedIn);
+}
+
+void FindController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
+{
+ float fractionFadedIn = pageOverlay->fractionFadedIn();
+
+ Vector<IntRect> rects = rectsForTextMatches();
+
+ // Draw the background.
+ graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(fractionFadedIn), ColorSpaceSRGB);
+
+ {
+ GraphicsContextStateSaver stateSaver(graphicsContext);
+
+ graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, holeShadowColor(fractionFadedIn), ColorSpaceSRGB);
+ graphicsContext.setFillColor(holeFillColor(fractionFadedIn), ColorSpaceSRGB);
+
+ // Draw white frames around the holes.
+ for (size_t i = 0; i < rects.size(); ++i) {
+ IntRect whiteFrameRect = rects[i];
+ whiteFrameRect.inflate(1);
+
+ 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]);
+}
+
+bool FindController::mouseEvent(PageOverlay* pageOverlay, const WebMouseEvent& mouseEvent)
+{
+ // If we get a mouse down event inside the page overlay we should hide the find UI.
+ if (mouseEvent.type() == WebEvent::MouseDown) {
+ // Dismiss the overlay.
+ hideFindUI();
+ }
+
+ return false;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/FindController.h b/Source/WebKit2/WebProcess/WebPage/FindController.h
new file mode 100644
index 000000000..da03b79a7
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/FindController.h
@@ -0,0 +1,84 @@
+/*
+ * 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 FindController_h
+#define FindController_h
+
+#include "PageOverlay.h"
+#include "WebFindOptions.h"
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+ class Frame;
+ class IntRect;
+}
+
+namespace WebKit {
+
+class WebPage;
+
+class FindController : private PageOverlay::Client {
+ WTF_MAKE_NONCOPYABLE(FindController);
+
+public:
+ explicit FindController(WebPage*);
+ virtual ~FindController();
+
+ void findString(const String&, FindOptions, unsigned maxMatchCount);
+ void hideFindUI();
+ void countStringMatches(const String&, FindOptions, unsigned maxMatchCount);
+
+ void hideFindIndicator();
+ void showFindIndicatorInSelection();
+
+ bool isShowingOverlay() const { return m_isShowingFindIndicator && m_findPageOverlay; }
+
+ void deviceScaleFactorDidChange();
+
+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);
+
+ Vector<WebCore::IntRect> rectsForTextMatches();
+ bool updateFindIndicator(WebCore::Frame* selectedFrame, bool isShowingOverlay, bool shouldAnimate = true);
+
+private:
+ WebPage* m_webPage;
+ 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;
+};
+
+} // namespace WebKit
+
+#endif // FindController_h
diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp
new file mode 100644
index 000000000..031c3fa6a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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 "LayerTreeHost.h"
+
+#if USE(CA)
+#if PLATFORM(MAC)
+#include "LayerTreeHostCAMac.h"
+#elif PLATFORM(WIN)
+#include "LayerTreeHostCAWin.h"
+#endif
+#endif
+
+#if PLATFORM(QT) && USE(TEXTURE_MAPPER)
+#include "qt/LayerTreeHostQt.h"
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+PassRefPtr<LayerTreeHost> LayerTreeHost::create(WebPage* webPage)
+{
+#if PLATFORM(MAC)
+ return LayerTreeHostCAMac::create(webPage);
+#elif PLATFORM(WIN) && HAVE(WKQCA)
+ return LayerTreeHostCAWin::create(webPage);
+#elif PLATFORM(QT) && USE(TEXTURE_MAPPER)
+ return LayerTreeHostQt::create(webPage);
+#else
+ return 0;
+#endif
+}
+
+LayerTreeHost::LayerTreeHost(WebPage* webPage)
+ : m_webPage(webPage)
+{
+}
+
+LayerTreeHost::~LayerTreeHost()
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h
new file mode 100644
index 000000000..61fbe2fc3
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+#ifndef LayerTreeHost_h
+#define LayerTreeHost_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace CoreIPC {
+class ArgumentDecoder;
+class Connection;
+class MessageID;
+}
+
+namespace WebCore {
+class FloatPoint;
+class IntRect;
+class IntSize;
+class GraphicsLayer;
+}
+
+namespace WebKit {
+
+class LayerTreeContext;
+class UpdateInfo;
+class WebPage;
+
+#if PLATFORM(WIN)
+struct WindowGeometry;
+#endif
+
+class LayerTreeHost : public RefCounted<LayerTreeHost> {
+public:
+ static PassRefPtr<LayerTreeHost> create(WebPage*);
+ virtual ~LayerTreeHost();
+
+ static bool supportsAcceleratedCompositing();
+
+ virtual const LayerTreeContext& layerTreeContext() = 0;
+ virtual void scheduleLayerFlush() = 0;
+ virtual void setLayerFlushSchedulingEnabled(bool) = 0;
+ virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool) = 0;
+ virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) = 0;
+ virtual void invalidate() = 0;
+
+ virtual void setNonCompositedContentsNeedDisplay(const WebCore::IntRect&) = 0;
+ virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) = 0;
+ virtual void forceRepaint() = 0;
+ virtual void sizeDidChange(const WebCore::IntSize& newSize) = 0;
+ virtual void deviceScaleFactorDidChange() = 0;
+
+ virtual void didInstallPageOverlay() = 0;
+ virtual void didUninstallPageOverlay() = 0;
+ virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&) = 0;
+
+ virtual void pauseRendering() { }
+ virtual void resumeRendering() { }
+
+#if USE(TILED_BACKING_STORE)
+ virtual void setVisibleContentRectAndScale(const WebCore::IntRect&, float scale) { }
+ virtual void setVisibleContentRectTrajectoryVector(const WebCore::FloatPoint&) { }
+ virtual void setVisibleContentRectForLayer(int layerID, const WebCore::IntRect&) { }
+ virtual void renderNextFrame() { }
+ virtual void purgeBackingStores() { }
+ virtual void didReceiveLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+#endif
+
+#if PLATFORM(WIN)
+ virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&) = 0;
+#endif
+
+protected:
+ explicit LayerTreeHost(WebPage*);
+
+ WebPage* m_webPage;
+
+
+#if USE(TILED_BACKING_STORE)
+ bool m_waitingForUIProcess;
+#endif
+};
+
+#if !PLATFORM(WIN) && !PLATFORM(QT)
+inline bool LayerTreeHost::supportsAcceleratedCompositing()
+{
+ return true;
+}
+#endif
+
+} // namespace WebKit
+
+#endif // LayerTreeHost_h
diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.messages.in b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.messages.in
new file mode 100644
index 000000000..d2e9c384e
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.messages.in
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2011 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 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(TILED_BACKING_STORE)
+messages -> LayerTreeHost {
+ SetVisibleContentRectForLayer(int layerID, WebCore::IntRect visibleContentRect)
+ SetVisibleContentRectTrajectoryVector(WebCore::FloatPoint trajectoryVectory)
+ SetVisibleContentRectAndScale(WebCore::IntRect contentRect, float scale)
+ RenderNextFrame()
+ PurgeBackingStores()
+}
+#endif
diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp
new file mode 100644
index 000000000..aa32b6a09
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp
@@ -0,0 +1,175 @@
+/*
+ * 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/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/Page.h>
+#include <WebCore/ScrollbarTheme.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(WebProcess::shared().runLoop(), 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()->setPageOverlayNeedsDisplay(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);
+}
+
+void PageOverlay::startFadeInAnimation()
+{
+ m_fractionFadedIn = 0.0;
+ m_fadeAnimationType = FadeInAnimation;
+
+ startFadeAnimation();
+}
+
+void PageOverlay::startFadeOutAnimation()
+{
+ m_fractionFadedIn = 1.0;
+ m_fadeAnimationType = FadeOutAnimation;
+
+ startFadeAnimation();
+}
+
+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;
+ setNeedsDisplay();
+
+ 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);
+ }
+ }
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.h b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h
new file mode 100644
index 000000000..1f61cebe9
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h
@@ -0,0 +1,105 @@
+/*
+ * 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 "RunLoop.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+ class GraphicsContext;
+ class IntRect;
+}
+
+namespace WebKit {
+
+class WebMouseEvent;
+class WebPage;
+
+class PageOverlay : public APIObject {
+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;
+ };
+
+ static const Type APIType = TypeBundlePageOverlay;
+
+ 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&);
+
+ void startFadeInAnimation();
+ void startFadeOutAnimation();
+
+ float fractionFadedIn() const { return m_fractionFadedIn; }
+
+protected:
+ explicit PageOverlay(Client*);
+
+private:
+ // APIObject
+ virtual Type type() const { return APIType; }
+
+ 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/TiledBackingStoreRemoteTile.cpp b/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.cpp
new file mode 100644
index 000000000..4140e7279
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 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 "TiledBackingStoreRemoteTile.h"
+
+#if USE(TILED_BACKING_STORE)
+
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "TiledBackingStoreClient.h"
+#include "UpdateInfo.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+TiledBackingStoreRemoteTile::TiledBackingStoreRemoteTile(TiledBackingStoreRemoteTileClient* client, TiledBackingStore* tiledBackingStore, const Coordinate& tileCoordinate)
+ : m_client(client)
+ , m_tiledBackingStore(tiledBackingStore)
+ , m_coordinate(tileCoordinate)
+ , m_rect(tiledBackingStore->tileRectForCoordinate(tileCoordinate))
+ , m_ID(0)
+ , m_dirtyRect(m_rect)
+{
+}
+
+TiledBackingStoreRemoteTile::~TiledBackingStoreRemoteTile()
+{
+ if (m_ID)
+ m_client->removeTile(m_ID);
+}
+
+bool TiledBackingStoreRemoteTile::isDirty() const
+{
+ return !m_dirtyRect.isEmpty();
+}
+
+void TiledBackingStoreRemoteTile::invalidate(const IntRect& dirtyRect)
+{
+ IntRect tileDirtyRect = intersection(dirtyRect, m_rect);
+ if (tileDirtyRect.isEmpty())
+ return;
+
+ m_dirtyRect.unite(tileDirtyRect);
+}
+
+Vector<IntRect> TiledBackingStoreRemoteTile::updateBackBuffer()
+{
+ if (!isDirty())
+ return Vector<IntRect>();
+
+ // FIXME: Only use a local buffer when we know the tile is animated (after the first invalidate)
+ // and destroy it after a few seconds of inactivity. We can render directly to shared
+ // memory in other cases.
+ if (!m_localBuffer || m_localBuffer->size() != m_rect.size()) {
+ m_localBuffer = ImageBuffer::create(m_rect.size());
+ m_localBuffer->context()->translate(-m_rect.x(), -m_rect.y());
+ m_localBuffer->context()->scale(FloatSize(m_tiledBackingStore->contentsScale(), m_tiledBackingStore->contentsScale()));
+ }
+ // This assumes that the GraphicsContext on the ImageBuffer acts synchronously
+ // for us to be able to draw this buffer on the ShareableBitmap right after.
+ m_tiledBackingStore->client()->tiledBackingStorePaint(m_localBuffer->context(), m_tiledBackingStore->mapToContents(m_dirtyRect));
+
+ RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(m_rect.size(), ShareableBitmap::SupportsAlpha);
+ OwnPtr<GraphicsContext> graphicsContext(bitmap->createGraphicsContext());
+ graphicsContext->drawImageBuffer(m_localBuffer.get(), ColorSpaceDeviceRGB, IntPoint(0, 0));
+
+ UpdateInfo updateInfo;
+ updateInfo.updateRectBounds = m_rect;
+ updateInfo.updateScaleFactor = m_tiledBackingStore->contentsScale();
+ bitmap->createHandle(updateInfo.bitmapHandle);
+
+ static int id = 0;
+ if (!m_ID) {
+ m_ID = ++id;
+ m_client->createTile(m_ID, updateInfo);
+ } else
+ m_client->updateTile(m_ID, updateInfo);
+
+ m_dirtyRect = IntRect();
+ return Vector<IntRect>();
+}
+
+void TiledBackingStoreRemoteTile::swapBackBufferToFront()
+{
+ // Handled by tiledBackingStorePaintEnd.
+}
+
+bool TiledBackingStoreRemoteTile::isReadyToPaint() const
+{
+ return !!m_ID;
+}
+
+void TiledBackingStoreRemoteTile::paint(GraphicsContext* context, const IntRect& rect)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void TiledBackingStoreRemoteTile::resize(const IntSize& newSize)
+{
+ m_rect = IntRect(m_rect.location(), newSize);
+ m_dirtyRect = m_rect;
+}
+
+TiledBackingStoreRemoteTileBackend::TiledBackingStoreRemoteTileBackend(TiledBackingStoreRemoteTileClient* client)
+ : m_client(client)
+{
+}
+
+PassRefPtr<WebCore::Tile> TiledBackingStoreRemoteTileBackend::createTile(WebCore::TiledBackingStore* tiledBackingStore, const WebCore::Tile::Coordinate& tileCoordinate)
+{
+ return TiledBackingStoreRemoteTile::create(m_client, tiledBackingStore, tileCoordinate);
+}
+
+void TiledBackingStoreRemoteTileBackend::paintCheckerPattern(WebCore::GraphicsContext*, const WebCore::FloatRect&)
+{
+}
+
+} // namespace WebKit
+
+#endif // USE(TILED_BACKING_STORE)
diff --git a/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.h b/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.h
new file mode 100644
index 000000000..12b2e0602
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef TiledBackingStoreRemoteTile_h
+#define TiledBackingStoreRemoteTile_h
+
+#if USE(TILED_BACKING_STORE)
+
+#include "Tile.h"
+#include "TiledBackingStore.h"
+#include "WebCore/IntRect.h"
+
+namespace WebCore {
+class ImageBuffer;
+class TiledBackingStore;
+}
+
+namespace WebKit {
+
+class TiledBackingStoreRemoteTileClient;
+class UpdateInfo;
+
+class TiledBackingStoreRemoteTile : public WebCore::Tile {
+public:
+ static PassRefPtr<Tile> create(TiledBackingStoreRemoteTileClient* client, WebCore::TiledBackingStore* tiledBackingStore, const Coordinate& tileCoordinate) { return adoptRef(new TiledBackingStoreRemoteTile(client, tiledBackingStore, tileCoordinate)); }
+ ~TiledBackingStoreRemoteTile();
+
+ bool isDirty() const;
+ void invalidate(const WebCore::IntRect&);
+ Vector<WebCore::IntRect> updateBackBuffer();
+ void swapBackBufferToFront();
+ bool isReadyToPaint() const;
+ void paint(WebCore::GraphicsContext*, const WebCore::IntRect&);
+
+ const Coordinate& coordinate() const { return m_coordinate; }
+ const WebCore::IntRect& rect() const { return m_rect; }
+ void resize(const WebCore::IntSize&);
+
+private:
+ TiledBackingStoreRemoteTile(TiledBackingStoreRemoteTileClient*, WebCore::TiledBackingStore*, const Coordinate&);
+
+ TiledBackingStoreRemoteTileClient* m_client;
+ WebCore::TiledBackingStore* m_tiledBackingStore;
+ Coordinate m_coordinate;
+ WebCore::IntRect m_rect;
+
+ int m_ID;
+ WebCore::IntRect m_dirtyRect;
+
+ OwnPtr<WebCore::ImageBuffer> m_localBuffer;
+};
+
+class TiledBackingStoreRemoteTileClient {
+public:
+ virtual ~TiledBackingStoreRemoteTileClient() { }
+ virtual void createTile(int tileID, const UpdateInfo&) = 0;
+ virtual void updateTile(int tileID, const UpdateInfo&) = 0;
+ virtual void removeTile(int tileID) = 0;
+};
+
+class TiledBackingStoreRemoteTileBackend : public WebCore::TiledBackingStoreBackend {
+public:
+ static PassOwnPtr<WebCore::TiledBackingStoreBackend> create(TiledBackingStoreRemoteTileClient* client) { return adoptPtr(new TiledBackingStoreRemoteTileBackend(client)); }
+ PassRefPtr<WebCore::Tile> createTile(WebCore::TiledBackingStore*, const WebCore::Tile::Coordinate&);
+ void paintCheckerPattern(WebCore::GraphicsContext*, const WebCore::FloatRect&);
+
+private:
+ TiledBackingStoreRemoteTileBackend(TiledBackingStoreRemoteTileClient*);
+ TiledBackingStoreRemoteTileClient* m_client;
+};
+
+
+} // namespace WebKit
+
+#endif // USE(TILED_BACKING_STORE)
+
+#endif // TiledBackingStoreRemoteTile
diff --git a/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp
new file mode 100644
index 000000000..c482e664b
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2010, 2011 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 "TiledDrawingArea.h"
+
+#if USE(TILED_BACKING_STORE)
+
+#include "DrawingAreaProxyMessages.h"
+#include "MessageID.h"
+#include "UpdateInfo.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+TiledDrawingArea::TiledDrawingArea(WebPage* webPage)
+ : DrawingArea(DrawingAreaTypeTiled, webPage)
+ , m_suspended(false)
+ , m_isWaitingForUIProcess(false)
+ , m_didSendTileUpdate(false)
+ , m_mainBackingStore(adoptPtr(new TiledBackingStore(this, TiledBackingStoreRemoteTileBackend::create(this))))
+{
+}
+
+TiledDrawingArea::~TiledDrawingArea()
+{
+}
+
+void TiledDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta)
+{
+ // FIXME: Do something much smarter.
+ setNeedsDisplay(scrollRect);
+}
+
+void TiledDrawingArea::setNeedsDisplay(const IntRect& rect)
+{
+ m_mainBackingStore->invalidate(rect);
+}
+
+void TiledDrawingArea::setSize(const IntSize& viewSize)
+{
+ ASSERT(!m_suspended);
+ ASSERT_ARG(viewSize, !viewSize.isEmpty());
+
+ m_webPage->setSize(viewSize);
+}
+
+void TiledDrawingArea::setVisibleContentRectAndScale(const WebCore::IntRect& visibleContentsRect, float scale)
+{
+ m_visibleContentRect = visibleContentsRect;
+
+ if (scale != m_mainBackingStore->contentsScale()) {
+ // Keep the tiles for the previous scale until enough content is available to be shown on the screen for the new scale.
+ // If we already have a previous set of tiles it means that two scale changed happened successively.
+ // In that case, make sure that our current main tiles have more content to show than the "previous previous"
+ // within the visible rect before replacing it.
+ if (!m_previousBackingStore || m_mainBackingStore->coverageRatio(m_visibleContentRect) > m_previousBackingStore->coverageRatio(m_visibleContentRect))
+ m_previousBackingStore = m_mainBackingStore.release();
+
+ m_mainBackingStore = adoptPtr(new TiledBackingStore(this, TiledBackingStoreRemoteTileBackend::create(this)));
+ m_mainBackingStore->setContentsScale(scale);
+ } else
+ m_mainBackingStore->adjustVisibleRect();
+}
+
+void TiledDrawingArea::setVisibleContentRectTrajectoryVector(const WebCore::FloatPoint& trajectoryVector)
+{
+ m_mainBackingStore->setVisibleRectTrajectoryVector(trajectoryVector);
+}
+
+void TiledDrawingArea::renderNextFrame()
+{
+ m_isWaitingForUIProcess = false;
+ m_mainBackingStore->updateTileBuffers();
+}
+
+void TiledDrawingArea::suspendPainting()
+{
+ ASSERT(!m_suspended);
+
+ m_suspended = true;
+}
+
+void TiledDrawingArea::resumePainting()
+{
+ ASSERT(m_suspended);
+
+ m_suspended = false;
+ m_mainBackingStore->updateTileBuffers();
+}
+
+void TiledDrawingArea::tiledBackingStorePaintBegin()
+{
+ m_webPage->layoutIfNeeded();
+}
+
+void TiledDrawingArea::tiledBackingStorePaint(GraphicsContext* graphicsContext, const IntRect& contentRect)
+{
+ m_webPage->drawRect(*graphicsContext, contentRect);
+}
+
+void TiledDrawingArea::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea)
+{
+ if (m_didSendTileUpdate) {
+ // Since we know that all tile updates following a page invalidate will all be rendered
+ // in one paint pass for all the tiles, we can send the swap tile message here.
+ m_webPage->send(Messages::DrawingAreaProxy::DidRenderFrame());
+ m_isWaitingForUIProcess = true;
+ m_didSendTileUpdate = false;
+
+ // Make sure that we destroy the previous backing store and remove its tiles only after DidRenderFrame
+ // was sent to swap recently created tiles' buffer. Else a frame could be rendered after the previous
+ // tiles were removed and before the new tile have their first back buffer swapped.
+ if (m_previousBackingStore && m_mainBackingStore->coverageRatio(m_visibleContentRect) >= 1.0f)
+ m_previousBackingStore.clear();
+ }
+}
+
+bool TiledDrawingArea::tiledBackingStoreUpdatesAllowed() const
+{
+ return !m_suspended && !m_isWaitingForUIProcess;
+}
+
+IntRect TiledDrawingArea::tiledBackingStoreContentsRect()
+{
+ return IntRect(IntPoint::zero(), m_webPage->size());
+}
+
+IntRect TiledDrawingArea::tiledBackingStoreVisibleRect()
+{
+ return m_visibleContentRect;
+}
+
+Color TiledDrawingArea::tiledBackingStoreBackgroundColor() const
+{
+ return Color::transparent;
+}
+
+void TiledDrawingArea::createTile(int tileID, const UpdateInfo& updateInfo)
+{
+ m_webPage->send(Messages::DrawingAreaProxy::CreateTile(tileID, updateInfo));
+ m_didSendTileUpdate = true;
+}
+void TiledDrawingArea::updateTile(int tileID, const UpdateInfo& updateInfo)
+{
+ m_webPage->send(Messages::DrawingAreaProxy::UpdateTile(tileID, updateInfo));
+ m_didSendTileUpdate = true;
+}
+void TiledDrawingArea::removeTile(int tileID)
+{
+ m_webPage->send(Messages::DrawingAreaProxy::RemoveTile(tileID));
+}
+
+#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
+void TiledDrawingArea::didReceiveLayerTreeHostMessage(CoreIPC::Connection* connection, CoreIPC::MessageID, CoreIPC::ArgumentDecoder* arguments)
+{
+}
+#endif
+} // namespace WebKit
+
+#endif // USE(TILED_BACKING_STORE)
diff --git a/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h
new file mode 100644
index 000000000..cbcbd3090
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 TiledDrawingArea_h
+#define TiledDrawingArea_h
+
+#if USE(TILED_BACKING_STORE)
+
+#include "DrawingArea.h"
+#include "TiledBackingStoreClient.h"
+#include "TiledBackingStoreRemoteTile.h"
+#include <WebCore/IntRect.h>
+
+namespace WebKit {
+
+class TiledDrawingArea : public DrawingArea, public WebCore::TiledBackingStoreClient, public TiledBackingStoreRemoteTileClient {
+public:
+ explicit TiledDrawingArea(WebPage*);
+ virtual ~TiledDrawingArea();
+
+ virtual void setNeedsDisplay(const WebCore::IntRect&);
+ virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta);
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual void attachCompositingContext() { }
+ virtual void detachCompositingContext() { }
+ virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) { }
+ virtual void scheduleCompositingLayerSync() { }
+ virtual void didReceiveLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+#endif
+
+private:
+ // CoreIPC message handlers.
+ virtual void setSize(const WebCore::IntSize& viewSize);
+ virtual void setVisibleContentRectAndScale(const WebCore::IntRect&, float);
+ virtual void setVisibleContentRectTrajectoryVector(const WebCore::FloatPoint&);
+ virtual void renderNextFrame();
+ virtual void suspendPainting();
+ virtual void resumePainting();
+
+ // TiledBackingStoreClient
+ virtual void tiledBackingStorePaintBegin();
+ virtual void tiledBackingStorePaint(WebCore::GraphicsContext*, const WebCore::IntRect& contentRect);
+ virtual void tiledBackingStorePaintEnd(const Vector<WebCore::IntRect>& paintedArea);
+ virtual bool tiledBackingStoreUpdatesAllowed() const;
+ virtual WebCore::IntRect tiledBackingStoreContentsRect();
+ virtual WebCore::IntRect tiledBackingStoreVisibleRect();
+ virtual WebCore::Color tiledBackingStoreBackgroundColor() const;
+
+ // TiledBackingStoreRemoteTileClient
+ virtual void createTile(int tileID, const UpdateInfo&);
+ virtual void updateTile(int tileID, const UpdateInfo&);
+ virtual void removeTile(int tileID);
+
+ bool m_suspended;
+ bool m_isWaitingForUIProcess;
+ bool m_didSendTileUpdate;
+ WebCore::IntRect m_visibleContentRect;
+
+ OwnPtr<WebCore::TiledBackingStore> m_mainBackingStore;
+ OwnPtr<WebCore::TiledBackingStore> m_previousBackingStore;
+};
+
+} // namespace WebKit
+
+#endif // USE(TILED_BACKING_STORE)
+
+#endif // TiledDrawingArea_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp
new file mode 100644
index 000000000..7a6045eb6
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2010, 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 "WebBackForwardListProxy.h"
+
+#include "DataReference.h"
+#include "EncoderAdapter.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
+#include "WebProcessProxyMessages.h"
+#include <WebCore/HistoryItem.h>
+#include <wtf/HashMap.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static const unsigned DefaultCapacity = 100;
+static const unsigned NoCurrentItemIndex = UINT_MAX;
+
+// 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;
+
+static IDToHistoryItemMap& idToHistoryItemMap()
+{
+ DEFINE_STATIC_LOCAL(IDToHistoryItemMap, map, ());
+ return map;
+}
+
+static HistoryItemToIDMap& historyItemToIDMap()
+{
+ DEFINE_STATIC_LOCAL(HistoryItemToIDMap, map, ());
+ return map;
+}
+
+static uint64_t uniqueHistoryItemID = 1;
+
+static uint64_t generateHistoryItemID()
+{
+ // These IDs exist in the WebProcess for items created by the WebProcess.
+ // The IDs generated here need to never collide with the IDs created in WebBackForwardList in the UIProcess.
+ // We accomplish this by starting from 3, and only ever using odd ids.
+ uniqueHistoryItemID += 2;
+ return uniqueHistoryItemID;
+}
+
+void WebBackForwardListProxy::setHighestItemIDFromUIProcess(uint64_t itemID)
+{
+ if (itemID <= uniqueHistoryItemID)
+ return;
+
+ if (itemID % 2)
+ uniqueHistoryItemID = itemID;
+ else
+ uniqueHistoryItemID = itemID + 1;
+}
+
+static void updateBackForwardItem(uint64_t itemID, HistoryItem* item)
+{
+ EncoderAdapter encoder;
+ item->encodeBackForwardTree(encoder);
+
+ WebProcess::shared().connection()->send(Messages::WebProcessProxy::AddBackForwardItem(itemID, item->originalURLString(), item->urlString(), item->title(), encoder.dataReference()), 0);
+}
+
+void WebBackForwardListProxy::addItemFromUIProcess(uint64_t itemID, PassRefPtr<WebCore::HistoryItem> prpItem)
+{
+ RefPtr<HistoryItem> item = prpItem;
+
+ // This item/itemID pair should not already exist in our maps.
+ ASSERT(!historyItemToIDMap().contains(item.get()));
+ ASSERT(!idToHistoryItemMap().contains(itemID));
+
+ historyItemToIDMap().set(item, itemID);
+ idToHistoryItemMap().set(itemID, item);
+}
+
+static void WK2NotifyHistoryItemChanged(HistoryItem* item)
+{
+ uint64_t itemID = historyItemToIDMap().get(item);
+ if (!itemID)
+ return;
+
+ updateBackForwardItem(itemID, item);
+}
+
+HistoryItem* WebBackForwardListProxy::itemForID(uint64_t itemID)
+{
+ return idToHistoryItemMap().get(itemID).get();
+}
+
+uint64_t WebBackForwardListProxy::idForItem(HistoryItem* item)
+{
+ ASSERT(item);
+ return historyItemToIDMap().get(item);
+}
+
+void WebBackForwardListProxy::removeItem(uint64_t itemID)
+{
+ IDToHistoryItemMap::iterator it = idToHistoryItemMap().find(itemID);
+ if (it == idToHistoryItemMap().end())
+ return;
+ historyItemToIDMap().remove(it->second);
+ idToHistoryItemMap().remove(it);
+}
+
+WebBackForwardListProxy::WebBackForwardListProxy(WebPage* page)
+ : m_page(page)
+{
+ WebCore::notifyHistoryItemChanged = WK2NotifyHistoryItemChanged;
+}
+
+void WebBackForwardListProxy::addItem(PassRefPtr<HistoryItem> prpItem)
+{
+ RefPtr<HistoryItem> item = prpItem;
+
+ ASSERT(!historyItemToIDMap().contains(item));
+
+ if (!m_page)
+ return;
+
+ uint64_t itemID = generateHistoryItemID();
+
+ ASSERT(!idToHistoryItemMap().contains(itemID));
+
+ historyItemToIDMap().set(item, itemID);
+ idToHistoryItemMap().set(itemID, item);
+
+ updateBackForwardItem(itemID, item.get());
+ m_page->send(Messages::WebPageProxy::BackForwardAddItem(itemID));
+}
+
+void WebBackForwardListProxy::goToItem(HistoryItem* item)
+{
+ if (!m_page)
+ return;
+
+ m_page->send(Messages::WebPageProxy::BackForwardGoToItem(historyItemToIDMap().get(item)));
+}
+
+HistoryItem* WebBackForwardListProxy::itemAtIndex(int itemIndex)
+{
+ if (!m_page)
+ return 0;
+
+ uint64_t itemID = 0;
+ if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::BackForwardItemAtIndex(itemIndex), Messages::WebPageProxy::BackForwardItemAtIndex::Reply(itemID), m_page->pageID()))
+ return 0;
+
+ if (!itemID)
+ return 0;
+
+ return idToHistoryItemMap().get(itemID).get();
+}
+
+int WebBackForwardListProxy::backListCount()
+{
+ if (!m_page)
+ return 0;
+
+ int backListCount = 0;
+ if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::BackForwardBackListCount(), Messages::WebPageProxy::BackForwardBackListCount::Reply(backListCount), m_page->pageID()))
+ return 0;
+
+ return backListCount;
+}
+
+int WebBackForwardListProxy::forwardListCount()
+{
+ if (!m_page)
+ return 0;
+
+ int forwardListCount = 0;
+ if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::BackForwardForwardListCount(), Messages::WebPageProxy::BackForwardForwardListCount::Reply(forwardListCount), m_page->pageID()))
+ return 0;
+
+ return forwardListCount;
+}
+
+void WebBackForwardListProxy::close()
+{
+ m_page = 0;
+}
+
+bool WebBackForwardListProxy::isActive()
+{
+ // FIXME: Should check the the list is enabled and has non-zero capacity.
+ return true;
+}
+
+void WebBackForwardListProxy::clear()
+{
+ m_page->send(Messages::WebPageProxy::BackForwardClear());
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h
new file mode 100644
index 000000000..b69eb123d
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010, 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.
+ */
+
+#ifndef WebBackForwardListProxy_h
+#define WebBackForwardListProxy_h
+
+#include <WebCore/BackForwardList.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebKit {
+
+class WebPage;
+
+class WebBackForwardListProxy : public WebCore::BackForwardList {
+public:
+ static PassRefPtr<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>);
+ static void setHighestItemIDFromUIProcess(uint64_t itemID);
+
+ void clear();
+
+private:
+ WebBackForwardListProxy(WebPage*);
+
+ virtual void addItem(PassRefPtr<WebCore::HistoryItem>);
+
+ virtual void goToItem(WebCore::HistoryItem*);
+
+ virtual WebCore::HistoryItem* itemAtIndex(int);
+ virtual int backListCount();
+ virtual int forwardListCount();
+
+ virtual bool isActive();
+
+ virtual void close();
+
+ WebPage* m_page;
+};
+
+} // namespace WebKit
+
+#endif // WebBackForwardListProxy_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp
new file mode 100644
index 000000000..e7e2e745f
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2010 Apple Inc. 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.
+ *
+ */
+
+#include "config.h"
+#include "WebContextMenu.h"
+
+#include "ContextMenuState.h"
+#include "InjectedBundleHitTestResult.h"
+#include "InjectedBundleUserMessageCoders.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
+#include <WebCore/ContextMenu.h>
+#include <WebCore/ContextMenuController.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/Page.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebContextMenu::WebContextMenu(WebPage* page)
+ : m_page(page)
+{
+}
+
+WebContextMenu::~WebContextMenu()
+{
+}
+
+void WebContextMenu::show()
+{
+ ContextMenuController* controller = m_page->corePage()->contextMenuController();
+ if (!controller)
+ return;
+ ContextMenu* menu = controller->contextMenu();
+ if (!menu)
+ return;
+ Node* node = controller->hitTestResult().innerNonSharedNode();
+ if (!node)
+ return;
+ Frame* frame = node->document()->frame();
+ if (!frame)
+ return;
+ FrameView* view = frame->view();
+ if (!view)
+ 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<APIObject> userData;
+ RefPtr<InjectedBundleHitTestResult> hitTestResult = InjectedBundleHitTestResult::create(controller->hitTestResult());
+ if (m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(m_page, hitTestResult.get(), proposedMenu, newMenu, userData))
+ proposedMenu = newMenu;
+
+ ContextMenuState contextMenuState;
+ contextMenuState.absoluteImageURLString = controller->hitTestResult().absoluteImageURL().string();
+ contextMenuState.absoluteLinkURLString = controller->hitTestResult().absoluteLinkURL().string();
+
+ // 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().point()), contextMenuState, proposedMenu, InjectedBundleUserMessageEncoder(userData.get())));
+}
+
+void WebContextMenu::itemSelected(const WebContextMenuItemData& item)
+{
+ ContextMenuItem coreItem(ActionType, static_cast<ContextMenuAction>(item.action()), item.title());
+ m_page->corePage()->contextMenuController()->contextMenuItemSelected(&coreItem);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h
new file mode 100644
index 000000000..3d9291aa3
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Apple Inc. 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.
+ *
+ */
+
+#ifndef WebContextMenu_h
+#define WebContextMenu_h
+
+#include "WebContextMenuItemData.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebKit {
+
+class WebPage;
+
+class WebContextMenu : public RefCounted<WebContextMenu> {
+public:
+ static PassRefPtr<WebContextMenu> create(WebPage* page)
+ {
+ return adoptRef(new WebContextMenu(page));
+ }
+
+ ~WebContextMenu();
+
+ void show();
+ void itemSelected(const WebContextMenuItemData&);
+
+private:
+ WebContextMenu(WebPage*);
+
+ WebPage* m_page;
+};
+
+} // namespace WebKit
+
+#endif // WebPopupMenu_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp
new file mode 100644
index 000000000..b32543eee
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp
@@ -0,0 +1,738 @@
+/*
+ * 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 "WebFrame.h"
+
+#include "DownloadManager.h"
+#include "InjectedBundleNodeHandle.h"
+#include "InjectedBundleRangeHandle.h"
+#include "InjectedBundleScriptWorld.h"
+#include "WebChromeClient.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
+#include <JavaScriptCore/APICast.h>
+#include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSLock.h>
+#include <JavaScriptCore/JSValueRef.h>
+#include <WebCore/AnimationController.h>
+#include <WebCore/ArchiveResource.h>
+#include <WebCore/CSSComputedStyleDeclaration.h>
+#include <WebCore/Chrome.h>
+#include <WebCore/DocumentLoader.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/HTMLFrameOwnerElement.h>
+#include <WebCore/HTMLNames.h>
+#include <WebCore/JSCSSStyleDeclaration.h>
+#include <WebCore/JSElement.h>
+#include <WebCore/JSRange.h>
+#include <WebCore/Page.h>
+#include <WebCore/RenderTreeAsText.h>
+#include <WebCore/SecurityOrigin.h>
+#include <WebCore/TextIterator.h>
+#include <WebCore/TextResourceDecoder.h>
+#include <wtf/text/StringBuilder.h>
+
+#if PLATFORM(MAC) || PLATFORM(WIN)
+#include <WebCore/LegacyWebArchive.h>
+#endif
+
+#ifndef NDEBUG
+#include <wtf/RefCountedLeakCounter.h>
+#endif
+
+using namespace JSC;
+using namespace WebCore;
+
+namespace WebKit {
+
+DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webFrameCounter, ("WebFrame"));
+
+static uint64_t generateFrameID()
+{
+ static uint64_t uniqueFrameID = 1;
+ return uniqueFrameID++;
+}
+
+static uint64_t generateListenerID()
+{
+ static uint64_t uniqueListenerID = 1;
+ return uniqueListenerID++;
+}
+
+PassRefPtr<WebFrame> WebFrame::createMainFrame(WebPage* page)
+{
+ RefPtr<WebFrame> frame = create();
+
+ page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()));
+
+ frame->init(page, String(), 0);
+
+ return frame.release();
+}
+
+PassRefPtr<WebFrame> WebFrame::createSubframe(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
+{
+ RefPtr<WebFrame> frame = create();
+
+ WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(ownerElement->document()->frame()->loader()->client())->webFrame();
+ page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID(), parentFrame->frameID()));
+
+ frame->init(page, frameName, ownerElement);
+
+ return frame.release();
+}
+
+PassRefPtr<WebFrame> WebFrame::create()
+{
+ RefPtr<WebFrame> frame = adoptRef(new WebFrame);
+
+ // Add explict ref() that will be balanced in WebFrameLoaderClient::frameLoaderDestroyed().
+ frame->ref();
+
+ return frame.release();
+}
+
+WebFrame::WebFrame()
+ : m_coreFrame(0)
+ , m_policyListenerID(0)
+ , m_policyFunction(0)
+ , m_policyDownloadID(0)
+ , m_frameLoaderClient(this)
+ , m_loadListener(0)
+ , m_frameID(generateFrameID())
+{
+ WebProcess::shared().addWebFrame(m_frameID, this);
+
+#ifndef NDEBUG
+ webFrameCounter.increment();
+#endif
+}
+
+WebFrame::~WebFrame()
+{
+ ASSERT(!m_coreFrame);
+
+#ifndef NDEBUG
+ webFrameCounter.decrement();
+#endif
+}
+
+void WebFrame::init(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
+{
+ RefPtr<Frame> frame = Frame::create(page->corePage(), ownerElement, &m_frameLoaderClient);
+ m_coreFrame = frame.get();
+
+ frame->tree()->setName(frameName);
+
+ if (ownerElement) {
+ ASSERT(ownerElement->document()->frame());
+ ownerElement->document()->frame()->tree()->appendChild(frame);
+ }
+
+ frame->init();
+}
+
+WebPage* WebFrame::page() const
+{
+ if (!m_coreFrame)
+ return 0;
+
+ if (WebCore::Page* page = m_coreFrame->page())
+ return static_cast<WebChromeClient*>(page->chrome()->client())->page();
+
+ return 0;
+}
+
+void WebFrame::invalidate()
+{
+ WebProcess::shared().removeWebFrame(m_frameID);
+ m_coreFrame = 0;
+}
+
+uint64_t WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction policyFunction)
+{
+ // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
+
+ invalidatePolicyListener();
+
+ m_policyListenerID = generateListenerID();
+ m_policyFunction = policyFunction;
+ return m_policyListenerID;
+}
+
+void WebFrame::invalidatePolicyListener()
+{
+ if (!m_policyListenerID)
+ return;
+
+ m_policyDownloadID = 0;
+ m_policyListenerID = 0;
+ m_policyFunction = 0;
+}
+
+void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t downloadID)
+{
+ if (!m_coreFrame)
+ return;
+
+ if (!m_policyListenerID)
+ return;
+
+ if (listenerID != m_policyListenerID)
+ return;
+
+ ASSERT(m_policyFunction);
+
+ FramePolicyFunction function = m_policyFunction;
+
+ invalidatePolicyListener();
+
+ m_policyDownloadID = downloadID;
+
+ (m_coreFrame->loader()->policyChecker()->*function)(action);
+}
+
+void WebFrame::startDownload(const WebCore::ResourceRequest& request)
+{
+ ASSERT(m_policyDownloadID);
+
+ DownloadManager::shared().startDownload(m_policyDownloadID, page(), request);
+
+ m_policyDownloadID = 0;
+}
+
+void WebFrame::convertHandleToDownload(ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& response)
+{
+ ASSERT(m_policyDownloadID);
+
+ DownloadManager::shared().convertHandleToDownload(m_policyDownloadID, page(), handle, request, response);
+ m_policyDownloadID = 0;
+}
+
+String WebFrame::source() const
+{
+ if (!m_coreFrame)
+ return String();
+ Document* document = m_coreFrame->document();
+ if (!document)
+ return String();
+ TextResourceDecoder* decoder = document->decoder();
+ if (!decoder)
+ return String();
+ DocumentLoader* documentLoader = m_coreFrame->loader()->activeDocumentLoader();
+ if (!documentLoader)
+ return String();
+ RefPtr<SharedBuffer> mainResourceData = documentLoader->mainResourceData();
+ if (!mainResourceData)
+ return String();
+ return decoder->encoding().decode(mainResourceData->data(), mainResourceData->size());
+}
+
+String WebFrame::contentsAsString() const
+{
+ if (!m_coreFrame)
+ return String();
+
+ if (isFrameSet()) {
+ StringBuilder builder;
+ for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
+ if (!builder.isEmpty())
+ builder.append(' ');
+ builder.append(static_cast<WebFrameLoaderClient*>(child->loader()->client())->webFrame()->contentsAsString());
+ }
+ // FIXME: It may make sense to use toStringPreserveCapacity() here.
+ return builder.toString();
+ }
+
+ Document* document = m_coreFrame->document();
+ if (!document)
+ return String();
+
+ RefPtr<Element> documentElement = document->documentElement();
+ if (!documentElement)
+ return String();
+
+ RefPtr<Range> range = document->createRange();
+
+ ExceptionCode ec = 0;
+ range->selectNode(documentElement.get(), ec);
+ if (ec)
+ return String();
+
+ return plainText(range.get());
+}
+
+String WebFrame::selectionAsString() const
+{
+ if (!m_coreFrame)
+ return String();
+
+ return m_coreFrame->displayStringModifiedByEncoding(m_coreFrame->editor()->selectedText());
+}
+
+IntSize WebFrame::size() const
+{
+ if (!m_coreFrame)
+ return IntSize();
+
+ FrameView* frameView = m_coreFrame->view();
+ if (!frameView)
+ return IntSize();
+
+ return frameView->contentsSize();
+}
+
+bool WebFrame::isFrameSet() const
+{
+ if (!m_coreFrame)
+ return false;
+
+ Document* document = m_coreFrame->document();
+ if (!document)
+ return false;
+ return document->isFrameSet();
+}
+
+bool WebFrame::isMainFrame() const
+{
+ if (WebPage* p = page())
+ return p->mainWebFrame() == this;
+
+ return false;
+}
+
+String WebFrame::name() const
+{
+ if (!m_coreFrame)
+ return String();
+
+ return m_coreFrame->tree()->uniqueName();
+}
+
+String WebFrame::url() const
+{
+ if (!m_coreFrame)
+ return String();
+
+ DocumentLoader* documentLoader = m_coreFrame->loader()->documentLoader();
+ if (!documentLoader)
+ return String();
+
+ return documentLoader->url().string();
+}
+
+String WebFrame::innerText() const
+{
+ if (!m_coreFrame)
+ return String();
+
+ if (!m_coreFrame->document()->documentElement())
+ return String();
+
+ return m_coreFrame->document()->documentElement()->innerText();
+}
+
+PassRefPtr<ImmutableArray> WebFrame::childFrames()
+{
+ if (!m_coreFrame)
+ return ImmutableArray::create();
+
+ size_t size = m_coreFrame->tree()->childCount();
+ if (!size)
+ return ImmutableArray::create();
+
+ Vector<RefPtr<APIObject> > vector;
+ vector.reserveInitialCapacity(size);
+
+ for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
+ WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(child->loader()->client())->webFrame();
+ vector.uncheckedAppend(webFrame);
+ }
+
+ return ImmutableArray::adopt(vector);
+}
+
+unsigned WebFrame::numberOfActiveAnimations() const
+{
+ if (!m_coreFrame)
+ return 0;
+
+ AnimationController* controller = m_coreFrame->animation();
+ if (!controller)
+ return 0;
+
+ return controller->numberOfActiveAnimations(m_coreFrame->document());
+}
+
+bool WebFrame::pauseAnimationOnElementWithId(const String& animationName, const String& elementID, double time)
+{
+ if (!m_coreFrame)
+ return false;
+
+ AnimationController* controller = m_coreFrame->animation();
+ if (!controller)
+ return false;
+
+ if (!m_coreFrame->document())
+ return false;
+
+ Node* coreNode = m_coreFrame->document()->getElementById(elementID);
+ if (!coreNode || !coreNode->renderer())
+ return false;
+
+ return controller->pauseAnimationAtTime(coreNode->renderer(), animationName, time);
+}
+
+bool WebFrame::pauseTransitionOnElementWithId(const String& propertyName, const String& elementID, double time)
+{
+ if (!m_coreFrame)
+ return false;
+
+ AnimationController* controller = m_coreFrame->animation();
+ if (!controller)
+ return false;
+
+ if (!m_coreFrame->document())
+ return false;
+
+ Node* coreNode = m_coreFrame->document()->getElementById(elementID);
+ if (!coreNode || !coreNode->renderer())
+ return false;
+
+ return controller->pauseTransitionAtTime(coreNode->renderer(), propertyName, time);
+}
+
+void WebFrame::suspendAnimations()
+{
+ if (!m_coreFrame)
+ return;
+
+ AnimationController* controller = m_coreFrame->animation();
+ if (!controller)
+ return;
+
+ controller->suspendAnimations();
+}
+
+void WebFrame::resumeAnimations()
+{
+ if (!m_coreFrame)
+ return;
+
+ AnimationController* controller = m_coreFrame->animation();
+ if (!controller)
+ return;
+
+ controller->resumeAnimations();
+}
+
+String WebFrame::layerTreeAsText() const
+{
+ if (!m_coreFrame)
+ return "";
+
+ return m_coreFrame->layerTreeAsText();
+}
+
+unsigned WebFrame::pendingUnloadCount() const
+{
+ if (!m_coreFrame)
+ return 0;
+
+ return m_coreFrame->domWindow()->pendingUnloadEventListeners();
+}
+
+bool WebFrame::allowsFollowingLink(const WebCore::KURL& url) const
+{
+ if (!m_coreFrame)
+ return true;
+
+ return m_coreFrame->document()->securityOrigin()->canDisplay(url);
+}
+
+JSGlobalContextRef WebFrame::jsContext()
+{
+ return toGlobalRef(m_coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
+}
+
+JSGlobalContextRef WebFrame::jsContextForWorld(InjectedBundleScriptWorld* world)
+{
+ return toGlobalRef(m_coreFrame->script()->globalObject(world->coreWorld())->globalExec());
+}
+
+IntRect WebFrame::contentBounds() const
+{
+ if (!m_coreFrame)
+ return IntRect();
+
+ FrameView* view = m_coreFrame->view();
+ if (!view)
+ return IntRect();
+
+ return IntRect(0, 0, view->contentsWidth(), view->contentsHeight());
+}
+
+IntRect WebFrame::visibleContentBounds() const
+{
+ if (!m_coreFrame)
+ return IntRect();
+
+ FrameView* view = m_coreFrame->view();
+ if (!view)
+ return IntRect();
+
+ IntRect contentRect = view->visibleContentRect(true);
+ return IntRect(0, 0, contentRect.width(), contentRect.height());
+}
+
+IntRect WebFrame::visibleContentBoundsExcludingScrollbars() const
+{
+ if (!m_coreFrame)
+ return IntRect();
+
+ FrameView* view = m_coreFrame->view();
+ if (!view)
+ return IntRect();
+
+ IntRect contentRect = view->visibleContentRect(false);
+ return IntRect(0, 0, contentRect.width(), contentRect.height());
+}
+
+IntSize WebFrame::scrollOffset() const
+{
+ if (!m_coreFrame)
+ return IntSize();
+
+ FrameView* view = m_coreFrame->view();
+ if (!view)
+ return IntSize();
+
+ return view->scrollOffset();
+}
+
+bool WebFrame::hasHorizontalScrollbar() const
+{
+ if (!m_coreFrame)
+ return false;
+
+ FrameView* view = m_coreFrame->view();
+ if (!view)
+ return false;
+
+ return view->horizontalScrollbar();
+}
+
+bool WebFrame::hasVerticalScrollbar() const
+{
+ if (!m_coreFrame)
+ return false;
+
+ FrameView* view = m_coreFrame->view();
+ if (!view)
+ return false;
+
+ return view->verticalScrollbar();
+}
+
+bool WebFrame::getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha)
+{
+ if (!m_coreFrame)
+ return false;
+
+ FrameView* view = m_coreFrame->view();
+ if (!view)
+ return false;
+
+ Color bgColor = view->documentBackgroundColor();
+ if (!bgColor.isValid())
+ return false;
+
+ bgColor.getRGBA(*red, *green, *blue, *alpha);
+ return true;
+}
+
+bool WebFrame::containsAnyFormElements() const
+{
+ if (!m_coreFrame)
+ return false;
+
+ Document* document = m_coreFrame->document();
+ if (!document)
+ return false;
+
+ for (Node* node = document->documentElement(); node; node = node->traverseNextNode()) {
+ if (!node->isElementNode())
+ continue;
+ if (static_cast<Element*>(node)->hasTagName(HTMLNames::formTag))
+ return true;
+ }
+ return false;
+}
+
+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();
+ return static_cast<WebFrameLoaderClient*>(coreFrame->loader()->client())->webFrame();
+}
+
+JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, InjectedBundleScriptWorld* world)
+{
+ if (!m_coreFrame)
+ return 0;
+
+ JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld());
+ ExecState* exec = globalObject->globalExec();
+
+ JSLock lock(SilenceAssertionsOnly);
+ return toRef(exec, toJS(exec, globalObject, nodeHandle->coreNode()));
+}
+
+JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleRangeHandle* rangeHandle, InjectedBundleScriptWorld* world)
+{
+ if (!m_coreFrame)
+ return 0;
+
+ JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld());
+ ExecState* exec = globalObject->globalExec();
+
+ JSLock lock(SilenceAssertionsOnly);
+ return toRef(exec, toJS(exec, globalObject, rangeHandle->coreRange()));
+}
+
+JSValueRef WebFrame::computedStyleIncludingVisitedInfo(JSObjectRef element)
+{
+ if (!m_coreFrame)
+ return 0;
+
+ JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(mainThreadNormalWorld());
+ ExecState* exec = globalObject->globalExec();
+
+ if (!toJS(element)->inherits(&JSElement::s_info))
+ return JSValueMakeUndefined(toRef(exec));
+
+ RefPtr<CSSComputedStyleDeclaration> style = computedStyle(static_cast<JSElement*>(toJS(element))->impl(), true);
+
+ JSLock lock(SilenceAssertionsOnly);
+ return toRef(exec, toJS(exec, globalObject, style.get()));
+}
+
+String WebFrame::counterValue(JSObjectRef element)
+{
+ if (!toJS(element)->inherits(&JSElement::s_info))
+ return String();
+
+ return counterValueForElement(static_cast<JSElement*>(toJS(element))->impl());
+}
+
+String WebFrame::markerText(JSObjectRef element)
+{
+ if (!toJS(element)->inherits(&JSElement::s_info))
+ return String();
+
+ return markerTextForListItem(static_cast<JSElement*>(toJS(element))->impl());
+}
+
+String WebFrame::provisionalURL() const
+{
+ if (!m_coreFrame)
+ return String();
+
+ return m_coreFrame->loader()->provisionalDocumentLoader()->url().string();
+}
+
+String WebFrame::suggestedFilenameForResourceWithURL(const KURL& url) const
+{
+ if (!m_coreFrame)
+ return String();
+
+ DocumentLoader* loader = m_coreFrame->loader()->documentLoader();
+ if (!loader)
+ return String();
+
+ // First, try the main resource.
+ if (loader->url() == url)
+ return loader->response().suggestedFilename();
+
+ // Next, try subresources.
+ RefPtr<ArchiveResource> resource = loader->subresource(url);
+ if (resource)
+ return resource->response().suggestedFilename();
+
+ return page()->cachedSuggestedFilenameForURL(url);
+}
+
+String WebFrame::mimeTypeForResourceWithURL(const KURL& url) const
+{
+ if (!m_coreFrame)
+ return String();
+
+ DocumentLoader* loader = m_coreFrame->loader()->documentLoader();
+ if (!loader)
+ return String();
+
+ // First, try the main resource.
+ if (loader->url() == url)
+ return loader->response().mimeType();
+
+ // Next, try subresources.
+ RefPtr<ArchiveResource> resource = loader->subresource(url);
+ if (resource)
+ return resource->mimeType();
+
+ return page()->cachedResponseMIMETypeForURL(url);
+}
+
+void WebFrame::setTextDirection(const String& direction)
+{
+ if (!m_coreFrame || !m_coreFrame->editor())
+ return;
+
+ if (direction == "auto")
+ m_coreFrame->editor()->setBaseWritingDirection(NaturalWritingDirection);
+ else if (direction == "ltr")
+ m_coreFrame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
+ else if (direction == "rtl")
+ m_coreFrame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
+}
+
+#if PLATFORM(MAC) || PLATFORM(WIN)
+RetainPtr<CFDataRef> WebFrame::webArchiveData() const
+{
+ if (RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(coreFrame()->document()))
+ return archive->rawDataRepresentation();
+
+ return 0;
+}
+#endif
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.h b/Source/WebKit2/WebProcess/WebPage/WebFrame.h
new file mode 100644
index 000000000..29ced42de
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.h
@@ -0,0 +1,164 @@
+/*
+ * 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 WebFrame_h
+#define WebFrame_h
+
+#include "APIObject.h"
+#include "ImmutableArray.h"
+#include "WebFrameLoaderClient.h"
+#include <JavaScriptCore/JSBase.h>
+#include <WebCore/FrameLoaderClient.h>
+#include <WebCore/FrameLoaderTypes.h>
+#include <WebCore/PolicyChecker.h>
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/RetainPtr.h>
+
+namespace WebCore {
+ class Frame;
+ class HTMLFrameOwnerElement;
+ class KURL;
+}
+
+namespace WebKit {
+
+class InjectedBundleNodeHandle;
+class InjectedBundleRangeHandle;
+class InjectedBundleScriptWorld;
+class WebPage;
+
+class WebFrame : public APIObject {
+public:
+ static const Type APIType = TypeBundleFrame;
+
+ static PassRefPtr<WebFrame> createMainFrame(WebPage*);
+ static PassRefPtr<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;
+ WebCore::Frame* coreFrame() const { return m_coreFrame; }
+
+ 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 startDownload(const WebCore::ResourceRequest&);
+ void convertHandleToDownload(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+
+ String source() const;
+ String contentsAsString() const;
+ String selectionAsString() const;
+
+ WebCore::IntSize size() const;
+
+ // WKBundleFrame API and SPI functions
+ bool isMainFrame() const;
+ String name() const;
+ String url() const;
+ String innerText() const;
+ bool isFrameSet() const;
+ PassRefPtr<ImmutableArray> childFrames();
+ JSValueRef computedStyleIncludingVisitedInfo(JSObjectRef element);
+ JSGlobalContextRef jsContext();
+ JSGlobalContextRef jsContextForWorld(InjectedBundleScriptWorld*);
+ WebCore::IntRect contentBounds() const;
+ WebCore::IntRect visibleContentBounds() const;
+ WebCore::IntRect visibleContentBoundsExcludingScrollbars() const;
+ WebCore::IntSize scrollOffset() const;
+ bool hasHorizontalScrollbar() const;
+ bool hasVerticalScrollbar() const;
+ bool getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha);
+ bool containsAnyFormElements() const;
+
+ static WebFrame* frameForContext(JSContextRef);
+
+ JSValueRef jsWrapperForWorld(InjectedBundleNodeHandle*, InjectedBundleScriptWorld*);
+ JSValueRef jsWrapperForWorld(InjectedBundleRangeHandle*, InjectedBundleScriptWorld*);
+
+ static String counterValue(JSObjectRef element);
+ static String markerText(JSObjectRef element);
+
+ unsigned numberOfActiveAnimations() const;
+ bool pauseAnimationOnElementWithId(const String& animationName, const String& elementID, double time);
+ bool pauseTransitionOnElementWithId(const String& propertyName, const String& elementID, double time);
+ void suspendAnimations();
+ void resumeAnimations();
+ String layerTreeAsText() const;
+
+ unsigned pendingUnloadCount() const;
+
+ bool allowsFollowingLink(const WebCore::KURL&) const;
+
+ String provisionalURL() const;
+ String suggestedFilenameForResourceWithURL(const WebCore::KURL&) const;
+ String mimeTypeForResourceWithURL(const WebCore::KURL&) const;
+
+ void setTextDirection(const String&);
+
+ // Simple listener class used by plug-ins to know when frames finish or fail loading.
+ class LoadListener {
+ public:
+ virtual ~LoadListener() { }
+
+ virtual void didFinishLoad(WebFrame*) = 0;
+ virtual void didFailLoad(WebFrame*, bool wasCancelled) = 0;
+ };
+ void setLoadListener(LoadListener* loadListener) { m_loadListener = loadListener; }
+ LoadListener* loadListener() const { return m_loadListener; }
+
+#if PLATFORM(MAC) || PLATFORM(WIN)
+ RetainPtr<CFDataRef> webArchiveData() const;
+#endif
+
+private:
+ static PassRefPtr<WebFrame> create();
+ WebFrame();
+
+ void init(WebPage*, const String& frameName, WebCore::HTMLFrameOwnerElement*);
+
+ virtual Type type() const { return APIType; }
+
+ WebCore::Frame* m_coreFrame;
+
+ uint64_t m_policyListenerID;
+ WebCore::FramePolicyFunction m_policyFunction;
+ uint64_t m_policyDownloadID;
+
+ WebFrameLoaderClient m_frameLoaderClient;
+ LoadListener* m_loadListener;
+
+ uint64_t m_frameID;
+};
+
+} // namespace WebKit
+
+#endif // WebFrame_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp
new file mode 100644
index 000000000..e1383c832
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp
@@ -0,0 +1,207 @@
+/*
+ * 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 "WebInspector.h"
+
+#if ENABLE(INSPECTOR)
+
+#include "WebInspectorFrontendClient.h"
+#include "WebInspectorProxyMessages.h"
+#include "WebPage.h"
+#include "WebPageCreationParameters.h"
+#include "WebProcess.h"
+#include <WebCore/InspectorController.h>
+#include <WebCore/Page.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+PassRefPtr<WebInspector> WebInspector::create(WebPage* page)
+{
+ return adoptRef(new WebInspector(page));
+}
+
+WebInspector::WebInspector(WebPage* page)
+ : m_page(page)
+ , m_inspectorPage(0)
+ , m_frontendClient(0)
+{
+}
+
+// Called from WebInspectorClient
+WebPage* WebInspector::createInspectorPage()
+{
+ if (!m_page)
+ return 0;
+
+ uint64_t inspectorPageID = 0;
+ WebPageCreationParameters parameters;
+
+ if (!WebProcess::shared().connection()->sendSync(Messages::WebInspectorProxy::CreateInspectorPage(),
+ Messages::WebInspectorProxy::CreateInspectorPage::Reply(inspectorPageID, parameters),
+ m_page->pageID(), CoreIPC::Connection::NoTimeout)) {
+ return 0;
+ }
+
+ if (!inspectorPageID)
+ return 0;
+
+ WebProcess::shared().createWebPage(inspectorPageID, parameters);
+ m_inspectorPage = WebProcess::shared().webPage(inspectorPageID);
+ ASSERT(m_inspectorPage);
+
+ OwnPtr<WebInspectorFrontendClient> frontendClient = adoptPtr(new WebInspectorFrontendClient(m_page, m_inspectorPage));
+ m_frontendClient = frontendClient.get();
+ m_inspectorPage->corePage()->inspectorController()->setInspectorFrontendClient(frontendClient.release());
+ return m_inspectorPage;
+}
+
+// Called from WebInspectorFrontendClient
+void WebInspector::didLoadInspectorPage()
+{
+ WebProcess::shared().connection()->send(Messages::WebInspectorProxy::DidLoadInspectorPage(), m_page->pageID());
+}
+
+void WebInspector::didClose()
+{
+ WebProcess::shared().connection()->send(Messages::WebInspectorProxy::DidClose(), m_page->pageID());
+}
+
+void WebInspector::bringToFront()
+{
+ WebProcess::shared().connection()->send(Messages::WebInspectorProxy::BringToFront(), m_page->pageID());
+}
+
+void WebInspector::inspectedURLChanged(const String& urlString)
+{
+ WebProcess::shared().connection()->send(Messages::WebInspectorProxy::InspectedURLChanged(urlString), m_page->pageID());
+}
+
+void WebInspector::attach()
+{
+ WebProcess::shared().connection()->send(Messages::WebInspectorProxy::Attach(), m_page->pageID());
+}
+
+void WebInspector::detach()
+{
+ WebProcess::shared().connection()->send(Messages::WebInspectorProxy::Detach(), m_page->pageID());
+}
+
+void WebInspector::setAttachedWindowHeight(unsigned height)
+{
+ WebProcess::shared().connection()->send(Messages::WebInspectorProxy::SetAttachedWindowHeight(height), m_page->pageID());
+}
+
+// Called by WebInspector messages
+void WebInspector::show()
+{
+ m_page->corePage()->inspectorController()->show();
+}
+
+void WebInspector::close()
+{
+ m_page->corePage()->inspectorController()->close();
+}
+
+void WebInspector::evaluateScriptForTest(long callID, const String& script)
+{
+ m_page->corePage()->inspectorController()->evaluateForTestInFrontend(callID, script);
+}
+
+void WebInspector::showConsole()
+{
+ m_page->corePage()->inspectorController()->show();
+ if (m_frontendClient)
+ m_frontendClient->showConsole();
+}
+
+void WebInspector::startJavaScriptDebugging()
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ m_page->corePage()->inspectorController()->show();
+ if (m_frontendClient)
+ m_frontendClient->setDebuggingEnabled(true);
+#endif
+}
+
+void WebInspector::stopJavaScriptDebugging()
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ m_page->corePage()->inspectorController()->show();
+ if (m_frontendClient)
+ m_frontendClient->setDebuggingEnabled(false);
+#endif
+}
+
+void WebInspector::setJavaScriptProfilingEnabled(bool enabled)
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ m_page->corePage()->inspectorController()->show();
+ if (!m_frontendClient)
+ return;
+ if (enabled)
+ m_page->corePage()->inspectorController()->enableProfiler();
+ else
+ m_page->corePage()->inspectorController()->disableProfiler();
+#endif
+}
+
+void WebInspector::startJavaScriptProfiling()
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ m_page->corePage()->inspectorController()->show();
+ if (m_frontendClient)
+ m_frontendClient->startProfilingJavaScript();
+#endif
+}
+
+void WebInspector::stopJavaScriptProfiling()
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ m_page->corePage()->inspectorController()->show();
+ if (m_frontendClient)
+ m_frontendClient->stopProfilingJavaScript();
+#endif
+}
+
+void WebInspector::startPageProfiling()
+{
+ m_page->corePage()->inspectorController()->show();
+ if (m_frontendClient)
+ m_frontendClient->setTimelineProfilingEnabled(true);
+}
+
+void WebInspector::stopPageProfiling()
+{
+ m_page->corePage()->inspectorController()->show();
+ if (m_frontendClient)
+ m_frontendClient->setTimelineProfilingEnabled(false);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.h b/Source/WebKit2/WebProcess/WebPage/WebInspector.h
new file mode 100644
index 000000000..79ff8074a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.h
@@ -0,0 +1,110 @@
+/*
+ * 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 WebInspector_h
+#define WebInspector_h
+
+#if ENABLE(INSPECTOR)
+
+#include "APIObject.h"
+#include "Connection.h"
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebKit {
+
+class WebInspectorFrontendClient;
+class WebPage;
+struct WebPageCreationParameters;
+
+class WebInspector : public APIObject {
+public:
+ static const Type APIType = TypeBundleInspector;
+
+ static PassRefPtr<WebInspector> create(WebPage*);
+
+ WebPage* page() const { return m_page; }
+ WebPage* inspectorPage() const { return m_inspectorPage; }
+
+ // Implemented in generated WebInspectorMessageReceiver.cpp
+ void didReceiveWebInspectorMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+
+ // Called by WebInspector messages
+ void show();
+ void close();
+
+ void evaluateScriptForTest(long callID, const String& script);
+
+ void setJavaScriptProfilingEnabled(bool);
+ void startPageProfiling();
+ void stopPageProfiling();
+
+#if PLATFORM(MAC)
+ static void setLocalizedStringsPath(const String&);
+#endif
+
+private:
+ friend class WebInspectorClient;
+ friend class WebInspectorFrontendClient;
+
+ explicit WebInspector(WebPage*);
+
+ virtual Type type() const { return APIType; }
+
+ // Called from WebInspectorClient
+ WebPage* createInspectorPage();
+
+ // Called from WebInspectorFrontendClient
+ void didLoadInspectorPage();
+ void didClose();
+ void bringToFront();
+ void inspectedURLChanged(const String&);
+
+ void attach();
+ void detach();
+
+ void setAttachedWindowHeight(unsigned);
+
+ // Implemented in platform WebInspector file
+ String localizedStringsURL() const;
+
+ void showConsole();
+
+ void startJavaScriptDebugging();
+ void stopJavaScriptDebugging();
+
+ void startJavaScriptProfiling();
+ void stopJavaScriptProfiling();
+
+ WebPage* m_page;
+ WebPage* m_inspectorPage;
+ WebInspectorFrontendClient* m_frontendClient;
+};
+
+} // 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
new file mode 100644
index 000000000..dc184b68a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in
@@ -0,0 +1,37 @@
+# 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.
+
+#if ENABLE(INSPECTOR)
+
+messages -> WebInspector {
+ Show()
+ Close()
+ ShowConsole()
+ StartJavaScriptDebugging()
+ StopJavaScriptDebugging()
+ StartJavaScriptProfiling()
+ StopJavaScriptProfiling()
+ StartPageProfiling()
+ StopPageProfiling()
+}
+
+#endif
diff --git a/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp
new file mode 100644
index 000000000..bcf3e8024
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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 "WebOpenPanelResultListener.h"
+
+namespace WebKit {
+
+PassRefPtr<WebOpenPanelResultListener> WebOpenPanelResultListener::create(WebPage* page, PassRefPtr<WebCore::FileChooser> fileChooser)
+{
+ return adoptRef(new WebOpenPanelResultListener(page, fileChooser));
+}
+
+WebOpenPanelResultListener::WebOpenPanelResultListener(WebPage* page, PassRefPtr<WebCore::FileChooser> fileChooser)
+ : m_page(page)
+ , m_fileChooser(fileChooser)
+{
+}
+
+WebOpenPanelResultListener::~WebOpenPanelResultListener()
+{
+}
+
+void WebOpenPanelResultListener::didChooseFiles(const Vector<String>& files)
+{
+ m_fileChooser->chooseFiles(files);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h
new file mode 100644
index 000000000..073d66adb
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h
@@ -0,0 +1,54 @@
+/*
+ * 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 WebOpenPanelResultListener_h
+#define WebOpenPanelResultListener_h
+
+#include <wtf/RefCounted.h>
+#include <WebCore/FileChooser.h>
+
+namespace WebKit {
+
+class WebPage;
+
+class WebOpenPanelResultListener : public RefCounted<WebOpenPanelResultListener> {
+public:
+ static PassRefPtr<WebOpenPanelResultListener> create(WebPage*, PassRefPtr<WebCore::FileChooser>);
+ ~WebOpenPanelResultListener();
+
+ void disconnectFromPage() { m_page = 0; }
+ void didChooseFiles(const Vector<String>&);
+
+private:
+ WebOpenPanelResultListener(WebPage*, PassRefPtr<WebCore::FileChooser>);
+
+ WebPage* m_page;
+ RefPtr<WebCore::FileChooser> m_fileChooser;
+};
+
+} // namespace WebKit
+
+
+#endif // WebOpenPanelResultListener_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
new file mode 100644
index 000000000..660f6f99c
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -0,0 +1,2900 @@
+/*
+ * Copyright (C) 2010, 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 "WebPage.h"
+
+#include "Arguments.h"
+#include "DataReference.h"
+#include "DecoderAdapter.h"
+#include "DrawingArea.h"
+#include "InjectedBundle.h"
+#include "InjectedBundleBackForwardList.h"
+#include "LayerTreeHost.h"
+#include "MessageID.h"
+#include "NetscapePlugin.h"
+#include "NotificationPermissionRequestManager.h"
+#include "PageOverlay.h"
+#include "PluginProxy.h"
+#include "PluginView.h"
+#include "PrintInfo.h"
+#include "RunLoop.h"
+#include "SessionState.h"
+#include "ShareableBitmap.h"
+#include "WebBackForwardList.h"
+#include "WebBackForwardListItem.h"
+#include "WebBackForwardListProxy.h"
+#include "WebChromeClient.h"
+#include "WebContextMenu.h"
+#include "WebContextMenuClient.h"
+#include "WebContextMessages.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebDragClient.h"
+#include "WebEditorClient.h"
+#include "WebEvent.h"
+#include "WebEventConversion.h"
+#include "WebFrame.h"
+#include "WebFullScreenManager.h"
+#include "WebGeolocationClient.h"
+#include "WebGeometry.h"
+#include "WebImage.h"
+#include "WebInspector.h"
+#include "WebInspectorClient.h"
+#include "WebNotificationClient.h"
+#include "WebOpenPanelResultListener.h"
+#include "WebPageCreationParameters.h"
+#include "WebPageGroupProxy.h"
+#include "WebPageProxyMessages.h"
+#include "WebPopupMenu.h"
+#include "WebPreferencesStore.h"
+#include "WebProcess.h"
+#include "WebProcessProxyMessages.h"
+#include <JavaScriptCore/APICast.h>
+#include <WebCore/AbstractDatabase.h>
+#include <WebCore/ArchiveResource.h>
+#include <WebCore/Chrome.h>
+#include <WebCore/ContextMenuController.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/EventHandler.h>
+#include <WebCore/FocusController.h>
+#include <WebCore/FormState.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameLoadRequest.h>
+#include <WebCore/FrameLoaderTypes.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/HTMLFormElement.h>
+#include <WebCore/HistoryItem.h>
+#include <WebCore/KeyboardEvent.h>
+#include <WebCore/MouseEvent.h>
+#include <WebCore/Page.h>
+#include <WebCore/PlatformKeyboardEvent.h>
+#include <WebCore/PluginDocument.h>
+#include <WebCore/PrintContext.h>
+#include <WebCore/RenderArena.h>
+#include <WebCore/RenderLayer.h>
+#include <WebCore/RenderTreeAsText.h>
+#include <WebCore/RenderView.h>
+#include <WebCore/ReplaceSelectionCommand.h>
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/SchemeRegistry.h>
+#include <WebCore/ScriptValue.h>
+#include <WebCore/SerializedScriptValue.h>
+#include <WebCore/Settings.h>
+#include <WebCore/SharedBuffer.h>
+#include <WebCore/SubstituteData.h>
+#include <WebCore/TextIterator.h>
+#include <WebCore/markup.h>
+#include <runtime/JSLock.h>
+#include <runtime/JSValue.h>
+
+#include <WebCore/Range.h>
+#include <WebCore/VisiblePosition.h>
+
+#if ENABLE(PLUGIN_PROCESS)
+#if PLATFORM(MAC)
+#include "MachPort.h"
+#endif
+#endif
+
+#if PLATFORM(MAC)
+#include "BuiltInPDFView.h"
+#endif
+
+#if PLATFORM(QT)
+#include "HitTestResult.h"
+#include <QMimeData>
+#endif
+
+#if PLATFORM(GTK)
+#include "DataObjectGtk.h"
+#endif
+
+#ifndef NDEBUG
+#include <wtf/RefCountedLeakCounter.h>
+#endif
+
+using namespace JSC;
+using namespace WebCore;
+using namespace std;
+
+namespace WebKit {
+
+class SendStopResponsivenessTimer {
+public:
+ SendStopResponsivenessTimer(WebPage* page)
+ : m_page(page)
+ {
+ }
+
+ ~SendStopResponsivenessTimer()
+ {
+ m_page->send(Messages::WebPageProxy::StopResponsivenessTimer());
+ }
+
+private:
+ WebPage* m_page;
+};
+
+DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage"));
+
+PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters)
+{
+ RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters));
+
+ if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
+ WebProcess::shared().injectedBundle()->didCreatePage(page.get());
+
+ return page.release();
+}
+
+WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
+ : m_viewSize(parameters.viewSize)
+ , m_useFixedLayout(false)
+ , m_drawsBackground(true)
+ , m_drawsTransparentBackground(false)
+ , m_isInRedo(false)
+ , m_isClosed(false)
+ , m_tabToLinks(false)
+#if PLATFORM(MAC)
+ , m_windowIsVisible(false)
+ , m_isSmartInsertDeleteEnabled(parameters.isSmartInsertDeleteEnabled)
+ , m_keyboardEventBeingInterpreted(0)
+#elif PLATFORM(WIN)
+ , m_nativeWindow(parameters.nativeWindow)
+#endif
+ , m_setCanStartMediaTimer(WebProcess::shared().runLoop(), this, &WebPage::setCanStartMediaTimerFired)
+ , m_findController(this)
+ , m_geolocationPermissionRequestManager(this)
+ , m_pageID(pageID)
+ , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
+ , m_canRunModal(parameters.canRunModal)
+ , m_isRunningModal(false)
+ , m_cachedMainFrameIsPinnedToLeftSide(false)
+ , m_cachedMainFrameIsPinnedToRightSide(false)
+ , m_cachedPageCount(0)
+ , m_isShowingContextMenu(false)
+#if PLATFORM(WIN)
+ , m_gestureReachedScrollingLimit(false)
+#endif
+{
+ 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);
+ pageClients.contextMenuClient = new WebContextMenuClient(this);
+ pageClients.editorClient = new WebEditorClient(this);
+ pageClients.dragClient = new WebDragClient(this);
+ pageClients.backForwardClient = WebBackForwardListProxy::create(this);
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ pageClients.geolocationClient = new WebGeolocationClient(this);
+#endif
+#if ENABLE(INSPECTOR)
+ pageClients.inspectorClient = new WebInspectorClient(this);
+#endif
+#if ENABLE(NOTIFICATIONS)
+ pageClients.notificationClient = new WebNotificationClient(this);
+#endif
+
+ m_page = adoptPtr(new Page(pageClients));
+
+ // Qt does not yet call setIsInWindow. Until it does, just leave
+ // this line out so plug-ins and video will work. Eventually all platforms
+ // should call setIsInWindow and this comment and #if should be removed,
+ // leaving behind the setCanStartMedia call.
+#if !PLATFORM(QT)
+ m_page->setCanStartMedia(false);
+#endif
+
+ updatePreferences(parameters.store);
+
+ m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);
+ m_page->setGroupName(m_pageGroup->identifier());
+
+ platformInitialize();
+
+ m_drawingArea = DrawingArea::create(this, parameters);
+ m_drawingArea->setPaintingEnabled(false);
+
+ m_mainFrame = WebFrame::createMainFrame(this);
+
+ setUseFixedLayout(parameters.useFixedLayout);
+
+ setDrawsBackground(parameters.drawsBackground);
+ setDrawsTransparentBackground(parameters.drawsTransparentBackground);
+
+ setPaginationMode(parameters.paginationMode);
+ setPageLength(parameters.pageLength);
+ setGapBetweenPages(parameters.gapBetweenPages);
+
+ setMemoryCacheMessagesEnabled(parameters.areMemoryCacheClientCallsEnabled);
+
+ setActive(parameters.isActive);
+ setFocused(parameters.isFocused);
+ setIsInWindow(parameters.isInWindow);
+
+ m_userAgent = parameters.userAgent;
+
+ WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID);
+
+ if (!parameters.sessionState.isEmpty())
+ restoreSession(parameters.sessionState);
+
+ m_drawingArea->setPaintingEnabled(true);
+
+#ifndef NDEBUG
+ webPageCounter.increment();
+#endif
+}
+
+WebPage::~WebPage()
+{
+ if (m_backForwardList)
+ m_backForwardList->detach();
+
+ ASSERT(!m_page);
+
+ m_sandboxExtensionTracker.invalidate();
+
+#if PLATFORM(MAC)
+ ASSERT(m_pluginViews.isEmpty());
+#endif
+
+#ifndef NDEBUG
+ webPageCounter.decrement();
+#endif
+}
+
+void WebPage::dummy(bool&)
+{
+}
+
+CoreIPC::Connection* WebPage::connection() const
+{
+ return WebProcess::shared().connection();
+}
+
+void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client)
+{
+ m_contextMenuClient.initialize(client);
+}
+
+void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client)
+{
+ m_editorClient.initialize(client);
+}
+
+void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client)
+{
+ m_formClient.initialize(client);
+}
+
+void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client)
+{
+ m_loaderClient.initialize(client);
+}
+
+void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient* client)
+{
+ m_policyClient.initialize(client);
+}
+
+void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient* client)
+{
+ m_resourceLoadClient.initialize(client);
+}
+
+void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client)
+{
+ m_uiClient.initialize(client);
+}
+
+#if ENABLE(FULLSCREEN_API)
+void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient* client)
+{
+ m_fullScreenClient.initialize(client);
+}
+#endif
+
+PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, const Plugin::Parameters& parameters)
+{
+ String pluginPath;
+
+ if (!WebProcess::shared().connection()->sendSync(
+ Messages::WebContext::GetPluginPath(parameters.mimeType, parameters.url.string()),
+ Messages::WebContext::GetPluginPath::Reply(pluginPath), 0)) {
+ return 0;
+ }
+
+ if (pluginPath.isNull()) {
+#if PLATFORM(MAC)
+ if (parameters.mimeType == "application/pdf"
+ || (parameters.mimeType.isEmpty() && parameters.url.path().lower().endsWith(".pdf")))
+ return BuiltInPDFView::create(frame);
+#else
+ UNUSED_PARAM(frame);
+#endif
+ return 0;
+ }
+
+#if ENABLE(PLUGIN_PROCESS)
+ return PluginProxy::create(pluginPath);
+#else
+ NetscapePlugin::setSetExceptionFunction(NPRuntimeObjectMap::setGlobalException);
+ return NetscapePlugin::create(NetscapePluginModule::getOrCreate(pluginPath));
+#endif
+}
+
+EditorState WebPage::editorState() const
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ ASSERT(frame);
+
+ EditorState result;
+ 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();
+ result.hasComposition = frame->editor()->hasComposition();
+ result.shouldIgnoreCompositionSelectionChange = frame->editor()->ignoreCompositionSelectionChange();
+
+#if PLATFORM(QT)
+ size_t location = 0;
+ size_t length = 0;
+
+ Element* selectionRoot = frame->selection()->rootEditableElement();
+ Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
+
+ if (!scope)
+ return result;
+
+ RefPtr<Range> range;
+ if (result.hasComposition && (range = frame->editor()->compositionRange())) {
+ frame->editor()->getCompositionSelection(result.anchorPosition, result.cursorPosition);
+
+ result.compositionRect = frame->view()->contentsToWindow(range->boundingBox());
+ }
+
+ if (!result.hasComposition && !result.selectionIsNone && (range = frame->selection()->selection().firstRange())) {
+ TextIterator::getLocationAndLengthFromRange(scope, range.get(), location, length);
+ bool baseIsFirst = frame->selection()->selection().isBaseFirst();
+
+ result.cursorPosition = (baseIsFirst) ? location + length : location;
+ result.anchorPosition = (baseIsFirst) ? location : location + length;
+ result.selectedText = range->text();
+ }
+
+ if (range)
+ result.microFocus = frame->view()->contentsToWindow(frame->editor()->firstRectForRange(range.get()));
+
+ // FIXME: We should only transfer innerText when it changes and do this on the UI side.
+ if (result.isContentEditable && !result.isInPasswordField) {
+ result.surroundingText = scope->innerText();
+ if (result.hasComposition) {
+ // The anchor is always the left position when they represent a composition.
+ result.surroundingText.remove(result.anchorPosition, result.cursorPosition - result.anchorPosition);
+ }
+ }
+#endif
+
+ return result;
+}
+
+String WebPage::renderTreeExternalRepresentation() const
+{
+ return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal);
+}
+
+uint64_t WebPage::renderTreeSize() const
+{
+ if (!m_page)
+ return 0;
+
+ Frame* mainFrame = m_page->mainFrame();
+ if (!mainFrame)
+ return 0;
+
+ uint64_t size = 0;
+ for (Frame* coreFrame = mainFrame; coreFrame; coreFrame = coreFrame->tree()->traverseNext())
+ size += coreFrame->document()->renderArena()->totalRenderArenaSize();
+
+ return size;
+}
+
+void WebPage::setTracksRepaints(bool trackRepaints)
+{
+ if (FrameView* view = mainFrameView())
+ view->setTracksRepaints(trackRepaints);
+}
+
+bool WebPage::isTrackingRepaints() const
+{
+ if (FrameView* view = mainFrameView())
+ return view->isTrackingRepaints();
+
+ return false;
+}
+
+void WebPage::resetTrackedRepaints()
+{
+ if (FrameView* view = mainFrameView())
+ view->resetTrackedRepaints();
+}
+
+PassRefPtr<ImmutableArray> WebPage::trackedRepaintRects()
+{
+ FrameView* view = mainFrameView();
+ if (!view)
+ return ImmutableArray::create();
+
+ const Vector<IntRect>& rects = view->trackedRepaintRects();
+ size_t size = rects.size();
+ if (!size)
+ return ImmutableArray::create();
+
+ Vector<RefPtr<APIObject> > vector;
+ vector.reserveInitialCapacity(size);
+
+ for (size_t i = 0; i < size; ++i)
+ vector.uncheckedAppend(WebRect::create(toAPI(rects[i])));
+
+ return ImmutableArray::adopt(vector);
+}
+
+void WebPage::executeEditingCommand(const String& commandName, const String& argument)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+ frame->editor()->command(commandName).execute(argument);
+}
+
+bool WebPage::isEditingCommandEnabled(const String& commandName)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return false;
+
+ Editor::Command command = frame->editor()->command(commandName);
+ return command.isSupported() && command.isEnabled();
+}
+
+void WebPage::clearMainFrameName()
+{
+ if (Frame* frame = mainFrame())
+ frame->tree()->clearName();
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
+{
+ m_drawingArea->setRootCompositingLayer(layer);
+}
+
+void WebPage::exitAcceleratedCompositingMode()
+{
+ m_drawingArea->setRootCompositingLayer(0);
+}
+#endif
+
+void WebPage::close()
+{
+ if (m_isClosed)
+ return;
+
+ m_isClosed = true;
+
+ if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
+ WebProcess::shared().injectedBundle()->willDestroyPage(this);
+
+#if ENABLE(INSPECTOR)
+ m_inspector = 0;
+#endif
+#if ENABLE(FULLSCREEN_API)
+ m_fullScreenManager = 0;
+#endif
+
+ if (m_activePopupMenu) {
+ m_activePopupMenu->disconnectFromPage();
+ m_activePopupMenu = 0;
+ }
+
+ if (m_activeOpenPanelResultListener) {
+ m_activeOpenPanelResultListener->disconnectFromPage();
+ m_activeOpenPanelResultListener = 0;
+ }
+
+ m_sandboxExtensionTracker.invalidate();
+
+ m_underlayPage = nullptr;
+ m_printContext = nullptr;
+ m_mainFrame->coreFrame()->loader()->detachFromParent();
+ m_page = nullptr;
+ m_drawingArea = nullptr;
+
+ bool isRunningModal = m_isRunningModal;
+ m_isRunningModal = false;
+
+ // The WebPage can be destroyed by this call.
+ WebProcess::shared().removeWebPage(m_pageID);
+
+ if (isRunningModal)
+ WebProcess::shared().runLoop()->stop();
+}
+
+void WebPage::tryClose()
+{
+ SendStopResponsivenessTimer stopper(this);
+
+ if (!m_mainFrame->coreFrame()->loader()->shouldClose()) {
+ send(Messages::WebPageProxy::StopResponsivenessTimer());
+ return;
+ }
+
+ send(Messages::WebPageProxy::ClosePage(true));
+}
+
+void WebPage::sendClose()
+{
+ send(Messages::WebPageProxy::ClosePage(false));
+}
+
+void WebPage::loadURL(const String& url, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+ loadURLRequest(ResourceRequest(KURL(KURL(), url)), sandboxExtensionHandle);
+}
+
+void WebPage::loadURLRequest(const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+ SendStopResponsivenessTimer stopper(this);
+
+ m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
+ m_mainFrame->coreFrame()->loader()->load(request, false);
+}
+
+void WebPage::loadData(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const KURL& baseURL, const KURL& unreachableURL)
+{
+ SendStopResponsivenessTimer stopper(this);
+
+ ResourceRequest request(baseURL);
+ SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL);
+ m_mainFrame->coreFrame()->loader()->load(request, substituteData, false);
+}
+
+void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString)
+{
+ RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
+ KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
+ loadData(sharedBuffer, "text/html", "utf-16", baseURL, KURL());
+}
+
+void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString)
+{
+ RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
+ KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
+ KURL unreachableURL = unreachableURLString.isEmpty() ? KURL() : KURL(KURL(), unreachableURLString);
+ loadData(sharedBuffer, "text/html", "utf-16", baseURL, unreachableURL);
+}
+
+void WebPage::loadPlainTextString(const String& string)
+{
+ RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(string.characters()), string.length() * sizeof(UChar));
+ loadData(sharedBuffer, "text/plain", "utf-16", blankURL(), KURL());
+}
+
+void WebPage::linkClicked(const String& url, const WebMouseEvent& event)
+{
+ Frame* frame = m_page->mainFrame();
+ if (!frame)
+ return;
+
+ RefPtr<Event> coreEvent;
+ if (event.type() != WebEvent::NoType)
+ coreEvent = MouseEvent::create(eventNames().clickEvent, frame->document()->defaultView(), platform(event), 0, 0);
+
+ frame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(url)),
+ false, false, coreEvent.get(), 0, MaybeSendReferrer);
+}
+
+void WebPage::stopLoadingFrame(uint64_t frameID)
+{
+ WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ if (!frame)
+ return;
+
+ frame->coreFrame()->loader()->stopForUserCancel();
+}
+
+void WebPage::stopLoading()
+{
+ SendStopResponsivenessTimer stopper(this);
+
+ m_mainFrame->coreFrame()->loader()->stopForUserCancel();
+}
+
+void WebPage::setDefersLoading(bool defersLoading)
+{
+ m_page->setDefersLoading(defersLoading);
+}
+
+void WebPage::reload(bool reloadFromOrigin)
+{
+ SendStopResponsivenessTimer stopper(this);
+
+ m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin);
+}
+
+void WebPage::goForward(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+ SendStopResponsivenessTimer stopper(this);
+
+ HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
+ ASSERT(item);
+ if (!item)
+ return;
+
+ m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
+ m_page->goToItem(item, FrameLoadTypeForward);
+}
+
+void WebPage::goBack(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+ SendStopResponsivenessTimer stopper(this);
+
+ HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
+ ASSERT(item);
+ if (!item)
+ return;
+
+ m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
+ m_page->goToItem(item, FrameLoadTypeBack);
+}
+
+void WebPage::goToBackForwardItem(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+ SendStopResponsivenessTimer stopper(this);
+
+ HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
+ ASSERT(item);
+ if (!item)
+ return;
+
+ m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
+ m_page->goToItem(item, FrameLoadTypeIndexedBackForward);
+}
+
+void WebPage::tryRestoreScrollPosition()
+{
+ m_page->mainFrame()->loader()->history()->restoreScrollPositionAndViewState();
+}
+
+void WebPage::layoutIfNeeded()
+{
+ if (m_mainFrame->coreFrame()->view())
+ m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive();
+
+ if (m_underlayPage) {
+ if (FrameView *frameView = m_underlayPage->mainFrameView())
+ frameView->updateLayoutAndStyleIfNeededRecursive();
+ }
+}
+
+void WebPage::setSize(const WebCore::IntSize& viewSize)
+{
+ FrameView* view = m_page->mainFrame()->view();
+
+#if USE(TILED_BACKING_STORE)
+ // If we are resizing to content ignore external attempts.
+ if (view->useFixedLayout())
+ return;
+#endif
+
+ if (m_viewSize == viewSize)
+ return;
+
+ view->resize(viewSize);
+ view->setNeedsLayout();
+ m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), viewSize));
+
+ m_viewSize = viewSize;
+}
+
+#if USE(TILED_BACKING_STORE)
+void WebPage::setFixedVisibleContentRect(const IntRect& rect)
+{
+ ASSERT(m_useFixedLayout);
+
+ Frame* frame = m_page->mainFrame();
+
+ frame->view()->setFixedVisibleContentRect(rect);
+}
+
+void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSize)
+{
+ ASSERT(m_useFixedLayout);
+ ASSERT(!targetLayoutSize.isEmpty());
+
+ FrameView* view = m_page->mainFrame()->view();
+
+ view->setDelegatesScrolling(true);
+ view->setUseFixedLayout(true);
+ view->setPaintsEntireContents(true);
+
+ if (view->fixedLayoutSize() == targetLayoutSize)
+ return;
+
+ // Always reset even when empty.
+ view->setFixedLayoutSize(targetLayoutSize);
+
+ // Schedule a layout to use the new target size.
+ if (!view->layoutPending()) {
+ view->setNeedsLayout();
+ view->scheduleRelayout();
+ }
+}
+
+void WebPage::resizeToContentsIfNeeded()
+{
+ ASSERT(m_useFixedLayout);
+
+ FrameView* view = m_page->mainFrame()->view();
+
+ if (!view->useFixedLayout())
+ return;
+
+ IntSize contentSize = view->contentsSize();
+ if (contentSize == m_viewSize)
+ return;
+
+ m_viewSize = contentSize;
+ view->resize(m_viewSize);
+ view->setNeedsLayout();
+}
+
+void WebPage::setViewportSize(const IntSize& size)
+{
+ ASSERT(m_useFixedLayout);
+
+ if (m_viewportSize == size)
+ return;
+
+ m_viewportSize = size;
+
+ // Recalculate the recommended layout size, when the available size (device pixel) changes.
+ Settings* settings = m_page->settings();
+
+ int minimumLayoutFallbackWidth = std::max(settings->layoutFallbackWidth(), size.width());
+
+ IntSize targetLayoutSize = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, settings->deviceWidth(), settings->deviceHeight(), settings->deviceDPI(), size).layoutSize;
+ setResizesToContentsUsingLayoutSize(targetLayoutSize);
+}
+
+#endif
+
+void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
+{
+ Frame* frame = m_page->mainFrame();
+
+ IntPoint scrollPosition = frame->view()->scrollPosition();
+ IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition();
+
+ // If the current scroll position in a direction is the max scroll position
+ // we don't want to scroll at all.
+ IntSize newScrollOffset;
+ if (scrollPosition.x() < maximumScrollPosition.x())
+ newScrollOffset.setWidth(scrollOffset.width());
+ if (scrollPosition.y() < maximumScrollPosition.y())
+ newScrollOffset.setHeight(scrollOffset.height());
+
+ if (newScrollOffset.isZero())
+ return;
+
+ frame->view()->setScrollPosition(frame->view()->scrollPosition() + newScrollOffset);
+}
+
+void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
+{
+ GraphicsContextStateSaver stateSaver(graphicsContext);
+ graphicsContext.clip(rect);
+
+ if (m_underlayPage) {
+ m_underlayPage->drawRect(graphicsContext, rect);
+
+ graphicsContext.beginTransparencyLayer(1);
+ m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
+ graphicsContext.endTransparencyLayer();
+ return;
+ }
+
+ m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
+}
+
+void WebPage::drawPageOverlay(GraphicsContext& graphicsContext, const IntRect& rect)
+{
+ ASSERT(m_pageOverlay);
+
+ GraphicsContextStateSaver stateSaver(graphicsContext);
+ graphicsContext.clip(rect);
+ m_pageOverlay->drawRect(graphicsContext, rect);
+}
+
+double WebPage::textZoomFactor() const
+{
+ Frame* frame = m_mainFrame->coreFrame();
+ if (!frame)
+ return 1;
+ return frame->textZoomFactor();
+}
+
+void WebPage::setTextZoomFactor(double zoomFactor)
+{
+ Frame* frame = m_mainFrame->coreFrame();
+ if (!frame)
+ return;
+ frame->setTextZoomFactor(static_cast<float>(zoomFactor));
+}
+
+double WebPage::pageZoomFactor() const
+{
+ Frame* frame = m_mainFrame->coreFrame();
+ if (!frame)
+ return 1;
+ return frame->pageZoomFactor();
+}
+
+void WebPage::setPageZoomFactor(double zoomFactor)
+{
+ Frame* frame = m_mainFrame->coreFrame();
+ if (!frame)
+ return;
+ frame->setPageZoomFactor(static_cast<float>(zoomFactor));
+}
+
+void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
+{
+ Frame* frame = m_mainFrame->coreFrame();
+ if (!frame)
+ return;
+ return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
+}
+
+void WebPage::windowScreenDidChange(uint64_t displayID)
+{
+ m_page->windowScreenDidChange(static_cast<PlatformDisplayID>(displayID));
+}
+
+void WebPage::scalePage(double scale, const IntPoint& origin)
+{
+ m_page->setPageScaleFactor(scale, origin);
+
+ send(Messages::WebPageProxy::PageScaleFactorDidChange(scale));
+}
+
+double WebPage::pageScaleFactor() const
+{
+ return m_page->pageScaleFactor();
+}
+
+void WebPage::setDeviceScaleFactor(float scaleFactor)
+{
+ if (scaleFactor == m_page->deviceScaleFactor())
+ return;
+
+ m_page->setDeviceScaleFactor(scaleFactor);
+
+ // Tell all our plug-in views that the device scale factor changed.
+#if PLATFORM(MAC)
+ for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
+ (*it)->setDeviceScaleFactor(scaleFactor);
+#endif
+
+ if (m_findController.isShowingOverlay()) {
+ // We must have updated layout to get the selection rects right.
+ layoutIfNeeded();
+ m_findController.deviceScaleFactorDidChange();
+ }
+}
+
+float WebPage::deviceScaleFactor() const
+{
+ return m_page->deviceScaleFactor();
+}
+
+void WebPage::setUseFixedLayout(bool fixed)
+{
+ m_useFixedLayout = fixed;
+
+ FrameView* view = mainFrameView();
+ if (!view)
+ return;
+
+ view->setUseFixedLayout(fixed);
+ if (!fixed)
+ view->setFixedLayoutSize(IntSize());
+}
+
+void WebPage::setFixedLayoutSize(const IntSize& size)
+{
+ FrameView* view = mainFrameView();
+ if (!view)
+ return;
+
+ view->setFixedLayoutSize(size);
+ view->forceLayout();
+}
+
+void WebPage::setPaginationMode(uint32_t mode)
+{
+ Page::Pagination pagination = m_page->pagination();
+ pagination.mode = static_cast<Page::Pagination::Mode>(mode);
+ m_page->setPagination(pagination);
+}
+
+void WebPage::setPageLength(double pageLength)
+{
+ Page::Pagination pagination = m_page->pagination();
+ pagination.pageLength = pageLength;
+ m_page->setPagination(pagination);
+}
+
+void WebPage::setGapBetweenPages(double gap)
+{
+ Page::Pagination pagination = m_page->pagination();
+ pagination.gap = gap;
+ m_page->setPagination(pagination);
+}
+
+void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay)
+{
+ bool shouldFadeIn = true;
+
+ if (m_pageOverlay) {
+ m_pageOverlay->setPage(0);
+
+ if (pageOverlay) {
+ // We're installing a page overlay when a page overlay is already active.
+ // In this case we don't want to fade in the new overlay.
+ shouldFadeIn = false;
+ }
+ }
+
+ m_pageOverlay = pageOverlay;
+ m_pageOverlay->setPage(this);
+
+ if (shouldFadeIn)
+ m_pageOverlay->startFadeInAnimation();
+
+ m_drawingArea->didInstallPageOverlay();
+#if PLATFORM(WIN)
+ send(Messages::WebPageProxy::DidInstallOrUninstallPageOverlay(true));
+#endif
+
+ m_pageOverlay->setNeedsDisplay();
+}
+
+void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool fadeOut)
+{
+ if (pageOverlay != m_pageOverlay)
+ return;
+
+ if (fadeOut) {
+ m_pageOverlay->startFadeOutAnimation();
+ return;
+ }
+
+ m_pageOverlay->setPage(0);
+ m_pageOverlay = nullptr;
+
+ m_drawingArea->didUninstallPageOverlay();
+#if PLATFORM(WIN)
+ send(Messages::WebPageProxy::DidInstallOrUninstallPageOverlay(false));
+#endif
+}
+
+PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options)
+{
+ FrameView* frameView = m_mainFrame->coreFrame()->view();
+ if (!frameView)
+ return 0;
+
+ IntSize bitmapSize = rect.size();
+ float deviceScaleFactor = corePage()->deviceScaleFactor();
+ bitmapSize.scale(deviceScaleFactor);
+
+ RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, options);
+ if (!snapshot->bitmap())
+ return 0;
+
+ OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
+ graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
+ graphicsContext->translate(-rect.x(), -rect.y());
+
+ frameView->updateLayoutAndStyleIfNeededRecursive();
+
+ PaintBehavior oldBehavior = frameView->paintBehavior();
+ frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
+ frameView->paint(graphicsContext.get(), rect);
+ frameView->setPaintBehavior(oldBehavior);
+
+ return snapshot.release();
+}
+
+PassRefPtr<WebImage> WebPage::scaledSnapshotInDocumentCoordinates(const IntRect& rect, double scaleFactor, ImageOptions options)
+{
+ FrameView* frameView = m_mainFrame->coreFrame()->view();
+ if (!frameView)
+ return 0;
+
+ float combinedScaleFactor = scaleFactor * corePage()->deviceScaleFactor();
+ IntSize size(ceil(rect.width() * combinedScaleFactor), ceil(rect.height() * combinedScaleFactor));
+ RefPtr<WebImage> snapshot = WebImage::create(size, options);
+ if (!snapshot->bitmap())
+ return 0;
+
+ OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
+ graphicsContext->applyDeviceScaleFactor(combinedScaleFactor);
+ graphicsContext->translate(-rect.x(), -rect.y());
+
+ frameView->updateLayoutAndStyleIfNeededRecursive();
+
+ PaintBehavior oldBehavior = frameView->paintBehavior();
+ frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
+ frameView->paintContents(graphicsContext.get(), rect);
+ frameView->setPaintBehavior(oldBehavior);
+
+ return snapshot.release();
+}
+
+PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options)
+{
+ return scaledSnapshotInDocumentCoordinates(rect, 1, options);
+}
+
+void WebPage::pageDidScroll()
+{
+ // Hide the find indicator.
+ m_findController.hideFindIndicator();
+
+ m_uiClient.pageDidScroll(this);
+
+ send(Messages::WebPageProxy::PageDidScroll());
+}
+
+#if USE(TILED_BACKING_STORE)
+void WebPage::pageDidRequestScroll(const IntPoint& point)
+{
+ send(Messages::WebPageProxy::PageDidRequestScroll(point));
+}
+#endif
+
+WebContextMenu* WebPage::contextMenu()
+{
+ if (!m_contextMenu)
+ m_contextMenu = WebContextMenu::create(this);
+ return m_contextMenu.get();
+}
+
+// Events
+
+static const WebEvent* g_currentEvent = 0;
+
+// FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
+// WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
+// platform events passed to the event handler code.
+const WebEvent* WebPage::currentEvent()
+{
+ return g_currentEvent;
+}
+
+class CurrentEvent {
+public:
+ explicit CurrentEvent(const WebEvent& event)
+ : m_previousCurrentEvent(g_currentEvent)
+ {
+ g_currentEvent = &event;
+ }
+
+ ~CurrentEvent()
+ {
+ g_currentEvent = m_previousCurrentEvent;
+ }
+
+private:
+ const WebEvent* m_previousCurrentEvent;
+};
+
+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;
+#endif
+
+ return false;
+}
+
+static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, Page* page)
+{
+ IntPoint point = page->mainFrame()->view()->windowToContents(platformMouseEvent.position());
+ HitTestResult result = page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, false);
+
+ Frame* frame = page->mainFrame();
+ if (result.innerNonSharedNode())
+ frame = result.innerNonSharedNode()->document()->frame();
+
+ bool handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent);
+ if (handled)
+ page->chrome()->showContextMenu();
+
+ return handled;
+}
+
+static bool handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page, bool onlyUpdateScrollbars)
+{
+ Frame* frame = page->mainFrame();
+ if (!frame->view())
+ return false;
+
+ PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
+
+ switch (platformMouseEvent.type()) {
+ case PlatformEvent::MousePressed: {
+ if (isContextClick(platformMouseEvent))
+ page->contextMenuController()->clearContextMenu();
+
+ bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent);
+ if (isContextClick(platformMouseEvent))
+ handled = handleContextMenuEvent(platformMouseEvent, page);
+
+ return handled;
+ }
+ case PlatformEvent::MouseReleased:
+ return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent);
+ case PlatformEvent::MouseMoved:
+ return frame->eventHandler()->mouseMoved(platformMouseEvent, onlyUpdateScrollbars);
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+}
+
+void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
+{
+ // Don't try to handle any pending mouse events if a context menu is showing.
+ if (m_isShowingContextMenu) {
+ send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
+ return;
+ }
+
+ bool handled = false;
+
+ if (m_pageOverlay) {
+ // Let the page overlay handle the event.
+ handled = m_pageOverlay->mouseEvent(mouseEvent);
+ }
+
+ 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, m_page.get(), onlyUpdateScrollbars);
+ }
+
+ send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
+}
+
+void WebPage::mouseEventSyncForTesting(const WebMouseEvent& mouseEvent, bool& handled)
+{
+ // Don't try to handle any pending mouse events if a context menu is showing.
+ if (m_isShowingContextMenu) {
+ handled = true;
+ return;
+ }
+
+ handled = m_pageOverlay && m_pageOverlay->mouseEvent(mouseEvent);
+
+ 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, m_page.get(), onlyUpdateScrollbars);
+ }
+}
+
+static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
+{
+ Frame* frame = page->mainFrame();
+ if (!frame->view())
+ return false;
+
+ PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
+ return frame->eventHandler()->handleWheelEvent(platformWheelEvent);
+}
+
+void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
+{
+ CurrentEvent currentEvent(wheelEvent);
+
+ bool 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());
+}
+
+static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
+{
+ if (!page->mainFrame()->view())
+ 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));
+}
+
+void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
+{
+ CurrentEvent currentEvent(keyboardEvent);
+
+ 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);
+
+ send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
+}
+
+void WebPage::keyEventSyncForTesting(const WebKeyboardEvent& keyboardEvent, bool& handled)
+{
+ CurrentEvent currentEvent(keyboardEvent);
+
+ handled = handleKeyEvent(keyboardEvent, m_page.get());
+ if (!handled)
+ handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
+}
+
+#if ENABLE(GESTURE_EVENTS)
+static bool handleGestureEvent(const WebGestureEvent& gestureEvent, Page* page)
+{
+ Frame* frame = page->mainFrame();
+ if (!frame->view())
+ return false;
+
+ PlatformGestureEvent platformGestureEvent = platform(gestureEvent);
+ return frame->eventHandler()->handleGestureEvent(platformGestureEvent);
+}
+
+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
+
+void WebPage::validateCommand(const String& commandName, uint64_t callbackID)
+{
+ bool isEnabled = false;
+ int32_t state = 0;
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (frame) {
+ Editor::Command command = frame->editor()->command(commandName);
+ state = command.state();
+ isEnabled = command.isSupported() && command.isEnabled();
+ }
+
+ send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
+}
+
+void WebPage::executeEditCommand(const String& commandName)
+{
+ executeEditingCommand(commandName, String());
+}
+
+uint64_t WebPage::restoreSession(const SessionState& sessionState)
+{
+ 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;
+}
+
+void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState, const SandboxExtension::Handle& sandboxExtensionHandle)
+{
+ if (uint64_t currentItemID = restoreSession(sessionState))
+ goToBackForwardItem(currentItemID, sandboxExtensionHandle);
+}
+
+#if ENABLE(TOUCH_EVENTS)
+static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
+{
+ Frame* frame = page->mainFrame();
+ if (!frame->view())
+ return false;
+
+ return frame->eventHandler()->handleTouchEvent(platform(touchEvent));
+}
+
+void WebPage::touchEvent(const WebTouchEvent& touchEvent)
+{
+ CurrentEvent currentEvent(touchEvent);
+
+ bool handled = handleTouchEvent(touchEvent, m_page.get());
+
+ send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
+}
+
+void WebPage::touchEventSyncForTesting(const WebTouchEvent& touchEvent, bool& handled)
+{
+ CurrentEvent currentEvent(touchEvent);
+ handled = handleTouchEvent(touchEvent, m_page.get());
+}
+#endif
+
+void WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
+{
+ page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
+}
+
+void WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
+{
+ page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity);
+}
+
+void WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
+{
+ scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity));
+}
+
+void WebPage::centerSelectionInVisibleArea()
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+
+ frame->selection()->revealSelection(ScrollAlignment::alignCenterAlways);
+ m_findController.showFindIndicatorInSelection();
+}
+
+void WebPage::setActive(bool isActive)
+{
+ m_page->focusController()->setActive(isActive);
+
+#if PLATFORM(MAC)
+ // Tell all our plug-in views that the window focus changed.
+ for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
+ (*it)->setWindowIsFocused(isActive);
+#endif
+}
+
+void WebPage::setDrawsBackground(bool drawsBackground)
+{
+ if (m_drawsBackground == drawsBackground)
+ return;
+
+ m_drawsBackground = drawsBackground;
+
+ for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
+ if (FrameView* view = coreFrame->view())
+ view->setTransparent(!drawsBackground);
+ }
+
+ m_drawingArea->pageBackgroundTransparencyChanged();
+ m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
+}
+
+void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground)
+{
+ if (m_drawsTransparentBackground == drawsTransparentBackground)
+ return;
+
+ m_drawsTransparentBackground = drawsTransparentBackground;
+
+ 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);
+ }
+
+ m_drawingArea->pageBackgroundTransparencyChanged();
+ m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
+}
+
+void WebPage::viewWillStartLiveResize()
+{
+ if (!m_page)
+ return;
+
+ // FIXME: This should propagate to all ScrollableAreas.
+ if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
+ if (FrameView* view = frame->view())
+ view->willStartLiveResize();
+ }
+}
+
+void WebPage::viewWillEndLiveResize()
+{
+ if (!m_page)
+ return;
+
+ // FIXME: This should propagate to all ScrollableAreas.
+ if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
+ if (FrameView* view = frame->view())
+ view->willEndLiveResize();
+ }
+}
+
+void WebPage::setFocused(bool isFocused)
+{
+ m_page->focusController()->setFocused(isFocused);
+}
+
+void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
+{
+ if (!m_page || !m_page->focusController())
+ return;
+
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ frame->document()->setFocusedNode(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);
+}
+
+void WebPage::setWindowResizerSize(const IntSize& windowResizerSize)
+{
+ if (m_windowResizerSize == windowResizerSize)
+ return;
+
+ m_windowResizerSize = windowResizerSize;
+
+ for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
+ FrameView* view = coreFrame->view();
+ if (view)
+ view->windowResizerRectChanged();
+ }
+}
+
+void WebPage::setCanStartMediaTimerFired()
+{
+ if (m_page)
+ m_page->setCanStartMedia(true);
+}
+
+void WebPage::setIsInWindow(bool isInWindow)
+{
+ if (!isInWindow) {
+ m_setCanStartMediaTimer.stop();
+ m_page->setCanStartMedia(false);
+ m_page->willMoveOffscreen();
+ } else {
+ // Defer the call to Page::setCanStartMedia() since it ends up sending a syncrhonous messages 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
+ // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>.
+ m_setCanStartMediaTimer.startOneShot(0);
+ m_page->didMoveOnscreen();
+ }
+}
+
+void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
+{
+ WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ if (!frame)
+ return;
+ frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
+}
+
+void WebPage::show()
+{
+ send(Messages::WebPageProxy::ShowPage());
+}
+
+void WebPage::setUserAgent(const String& userAgent)
+{
+ m_userAgent = userAgent;
+}
+
+IntPoint WebPage::screenToWindow(const IntPoint& point)
+{
+ IntPoint windowPoint;
+ sendSync(Messages::WebPageProxy::ScreenToWindow(point), Messages::WebPageProxy::ScreenToWindow::Reply(windowPoint));
+ return windowPoint;
+}
+
+IntRect WebPage::windowToScreen(const IntRect& rect)
+{
+ IntRect screenRect;
+ sendSync(Messages::WebPageProxy::WindowToScreen(rect), Messages::WebPageProxy::WindowToScreen::Reply(screenRect));
+ return screenRect;
+}
+
+IntRect WebPage::windowResizerRect() const
+{
+ if (m_windowResizerSize.isEmpty())
+ return IntRect();
+
+ IntSize frameViewSize;
+ if (Frame* coreFrame = m_mainFrame->coreFrame()) {
+ if (FrameView* view = coreFrame->view())
+ frameViewSize = view->size();
+ }
+
+ return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(),
+ m_windowResizerSize.width(), m_windowResizerSize.height());
+}
+
+KeyboardUIMode WebPage::keyboardUIMode()
+{
+ bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled();
+ return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
+}
+
+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;
+ CoreIPC::DataReference dataReference;
+
+ JSLock lock(SilenceAssertionsOnly);
+ 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();
+ }
+
+ send(Messages::WebPageProxy::ScriptValueCallback(dataReference, callbackID));
+}
+
+void WebPage::getContentsAsString(uint64_t callbackID)
+{
+ String resultString = m_mainFrame->contentsAsString();
+ send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
+}
+
+void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID)
+{
+ String resultString = renderTreeExternalRepresentation();
+ send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
+}
+
+void WebPage::getSelectionOrContentsAsString(uint64_t callbackID)
+{
+ String resultString = m_mainFrame->selectionAsString();
+ if (resultString.isEmpty())
+ resultString = m_mainFrame->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))
+ resultString = frame->source();
+
+ send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
+}
+
+void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
+{
+ CoreIPC::DataReference dataReference;
+
+ RefPtr<SharedBuffer> buffer;
+ if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
+ if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) {
+ if ((buffer = loader->mainResourceData()))
+ dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
+ }
+ }
+
+ send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
+}
+
+static PassRefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const KURL& resourceURL)
+{
+ DocumentLoader* loader = frame->loader()->documentLoader();
+ if (!loader)
+ return 0;
+
+ RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL);
+ if (!subresource)
+ return 0;
+
+ return subresource->data();
+}
+
+void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURLString, uint64_t callbackID)
+{
+ CoreIPC::DataReference dataReference;
+ KURL resourceURL(KURL(), resourceURLString);
+
+ RefPtr<SharedBuffer> buffer;
+ if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
+ buffer = resourceDataForFrame(frame->coreFrame(), resourceURL);
+ if (!buffer) {
+ // Try to get the resource data from the cache.
+ buffer = cachedResponseDataForURL(resourceURL);
+ }
+
+ if (buffer)
+ dataReference = CoreIPC::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)
+{
+ CoreIPC::DataReference dataReference;
+
+#if PLATFORM(MAC) || PLATFORM(WIN)
+ RetainPtr<CFDataRef> data;
+ if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
+ if ((data = frame->webArchiveData()))
+ dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
+ }
+#endif
+
+ send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
+}
+
+void WebPage::forceRepaintWithoutCallback()
+{
+ m_drawingArea->forceRepaint();
+}
+
+void WebPage::forceRepaint(uint64_t callbackID)
+{
+ forceRepaintWithoutCallback();
+ send(Messages::WebPageProxy::VoidCallback(callbackID));
+}
+
+void WebPage::preferencesDidChange(const WebPreferencesStore& store)
+{
+ WebPreferencesStore::removeTestRunnerOverrides();
+ updatePreferences(store);
+}
+
+void WebPage::updatePreferences(const WebPreferencesStore& store)
+{
+ Settings* settings = m_page->settings();
+
+ m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
+
+ // FIXME: This should be generated from macro expansion for all preferences,
+ // 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()));
+
+ FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS)
+
+#undef INITIALIZE_SETTINGS
+
+ settings->setScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey()));
+ settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey()));
+ settings->setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey()));
+ settings->setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey()));
+ settings->setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey()));
+ settings->setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey()));
+ settings->setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
+ settings->setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
+ settings->setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()));
+ settings->setPrivateBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()));
+ settings->setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey()));
+ 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()));
+#if ENABLE(WEB_ARCHIVE)
+ settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
+#endif
+ settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey()));
+ settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey()));
+ settings->setPageCacheSupportsPlugins(store.getBoolValueForKey(WebPreferencesKey::pageCacheSupportsPluginsKey()));
+ settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey()));
+ settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey()));
+ settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey()));
+ settings->setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey()));
+ settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey()));
+ settings->setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey()));
+ settings->setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey()));
+ settings->setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey()));
+
+ 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->setLayoutFallbackWidth(store.getUInt32ValueForKey(WebPreferencesKey::layoutFallbackWidthKey()));
+ settings->setDeviceDPI(store.getUInt32ValueForKey(WebPreferencesKey::deviceDPIKey()));
+ settings->setDeviceWidth(store.getUInt32ValueForKey(WebPreferencesKey::deviceWidthKey()));
+ settings->setDeviceHeight(store.getUInt32ValueForKey(WebPreferencesKey::deviceHeightKey()));
+ settings->setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey())));
+ settings->setShowsToolTipOverTruncatedText(store.getBoolValueForKey(WebPreferencesKey::showsToolTipOverTruncatedTextKey()));
+
+ 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->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
+ settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
+ settings->setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey()));
+ settings->setMediaPlaybackRequiresUserGesture(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackRequiresUserGestureKey()));
+ settings->setMediaPlaybackAllowsInline(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackAllowsInlineKey()));
+ settings->setMockScrollbarsEnabled(store.getBoolValueForKey(WebPreferencesKey::mockScrollbarsEnabledKey()));
+
+#if ENABLE(SQL_DATABASE)
+ AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
+#endif
+
+#if ENABLE(FULLSCREEN_API)
+ settings->setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey()));
+#endif
+
+ settings->setLocalStorageDatabasePath(WebProcess::shared().localStorageDirectory());
+
+#if USE(AVFOUNDATION)
+ settings->setAVFoundationEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationEnabledKey()));
+#endif
+
+#if ENABLE(WEB_SOCKETS)
+ settings->setUseHixie76WebSocketProtocol(store.getBoolValueForKey(WebPreferencesKey::hixie76WebSocketProtocolEnabledKey()));
+#endif
+
+#if ENABLE(WEB_AUDIO)
+ settings->setWebAudioEnabled(store.getBoolValueForKey(WebPreferencesKey::webAudioEnabledKey()));
+#endif
+
+ settings->setApplicationChromeMode(store.getBoolValueForKey(WebPreferencesKey::applicationChromeModeKey()));
+ settings->setSuppressIncrementalRendering(store.getBoolValueForKey(WebPreferencesKey::suppressIncrementalRenderingKey()));
+ settings->setBackspaceKeyNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::backspaceKeyNavigationEnabledKey()));
+ settings->setCaretBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::caretBrowsingEnabledKey()));
+
+#if ENABLE(VIDEO_TRACK)
+ settings->setShouldDisplaySubtitles(store.getBoolValueForKey(WebPreferencesKey::shouldDisplaySubtitlesKey()));
+ settings->setShouldDisplayCaptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayCaptionsKey()));
+ settings->setShouldDisplayTextDescriptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayTextDescriptionsKey()));
+#endif
+
+ platformPreferencesDidChange(store);
+}
+
+#if ENABLE(INSPECTOR)
+WebInspector* WebPage::inspector()
+{
+ if (m_isClosed)
+ return 0;
+ if (!m_inspector)
+ m_inspector = WebInspector::create(this);
+ return m_inspector.get();
+}
+#endif
+
+#if ENABLE(FULLSCREEN_API)
+WebFullScreenManager* WebPage::fullScreenManager()
+{
+ if (!m_fullScreenManager)
+ m_fullScreenManager = WebFullScreenManager::create(this);
+ return m_fullScreenManager.get();
+}
+#endif
+
+NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager()
+{
+ if (m_notificationPermissionRequestManager)
+ return m_notificationPermissionRequestManager.get();
+
+ m_notificationPermissionRequestManager = NotificationPermissionRequestManager::create(this);
+ return m_notificationPermissionRequestManager.get();
+}
+
+#if !PLATFORM(GTK) && !PLATFORM(MAC)
+bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
+{
+ Node* node = evt->target()->toNode();
+ ASSERT(node);
+ Frame* frame = node->document()->frame();
+ ASSERT(frame);
+
+ const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
+ if (!keyEvent)
+ return false;
+
+ Editor::Command command = frame->editor()->command(interpretKeyEvent(evt));
+
+ if (keyEvent->type() == PlatformEvent::RawKeyDown) {
+ // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
+ // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
+ // (e.g. Tab that inserts a Tab character, or Enter).
+ return !command.isTextInsertion() && command.execute(evt);
+ }
+
+ if (command.execute(evt))
+ return true;
+
+ // Don't insert null or control characters as they can result in unexpected behaviour
+ if (evt->charCode() < ' ')
+ return false;
+
+ return frame->editor()->insertText(evt->keyEvent()->text(), evt);
+}
+#endif
+
+#if PLATFORM(WIN)
+void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap& dataMap, uint32_t flags)
+{
+ if (!m_page) {
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession()));
+ return;
+ }
+
+ DragData dragData(dataMap, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
+ switch (action) {
+ case DragControllerActionEntered:
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
+ break;
+
+ case DragControllerActionUpdated:
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
+ break;
+
+ case DragControllerActionExited:
+ m_page->dragController()->dragExited(&dragData);
+ break;
+
+ case DragControllerActionPerformDrag:
+ m_page->dragController()->performDrag(&dragData);
+ break;
+
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+#elif PLATFORM(QT) || PLATFORM(GTK)
+void WebPage::performDragControllerAction(uint64_t action, WebCore::DragData dragData)
+{
+ if (!m_page) {
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession()));
+#if PLATFORM(QT)
+ QMimeData* data = const_cast<QMimeData*>(dragData.platformData());
+#elif PLATFORM(GTK)
+ DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
+#endif
+ delete data;
+ return;
+ }
+
+ switch (action) {
+ case DragControllerActionEntered:
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
+ break;
+
+ case DragControllerActionUpdated:
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
+ break;
+
+ case DragControllerActionExited:
+ m_page->dragController()->dragExited(&dragData);
+ break;
+
+ case DragControllerActionPerformDrag: {
+ m_page->dragController()->performDrag(&dragData);
+ break;
+ }
+
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ // DragData does not delete its platformData so we need to do that here.
+#if PLATFORM(QT)
+ QMimeData* data = const_cast<QMimeData*>(dragData.platformData());
+#elif PLATFORM(GTK)
+ DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
+#endif
+ delete data;
+}
+
+#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)
+{
+ if (!m_page) {
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession()));
+ 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)));
+ break;
+
+ case DragControllerActionUpdated:
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
+ break;
+
+ case DragControllerActionExited:
+ m_page->dragController()->dragExited(&dragData);
+ break;
+
+ case DragControllerActionPerformDrag: {
+ ASSERT(!m_pendingDropSandboxExtension);
+
+ m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
+
+ m_page->dragController()->performDrag(&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 invalidate it.
+ if (m_pendingDropSandboxExtension) {
+ m_pendingDropSandboxExtension->invalidate();
+ m_pendingDropSandboxExtension = nullptr;
+ }
+
+ break;
+ }
+
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+#endif
+
+void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
+{
+ IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController()->dragOffset().x(), clientPosition.y() + m_page->dragController()->dragOffset().y());
+ IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController()->dragOffset().x(), globalPosition.y() + m_page->dragController()->dragOffset().y());
+
+ m_page->dragController()->dragEnded();
+ FrameView* view = m_page->mainFrame()->view();
+ 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());
+ m_page->mainFrame()->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation);
+}
+
+void WebPage::willPerformLoadDragDestinationAction()
+{
+ m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release());
+}
+
+WebUndoStep* WebPage::webUndoStep(uint64_t stepID)
+{
+ return m_undoStepMap.get(stepID).get();
+}
+
+void WebPage::addWebUndoStep(uint64_t stepID, WebUndoStep* entry)
+{
+ m_undoStepMap.set(stepID, entry);
+}
+
+void WebPage::removeWebEditCommand(uint64_t stepID)
+{
+ m_undoStepMap.remove(stepID);
+}
+
+void WebPage::unapplyEditCommand(uint64_t stepID)
+{
+ WebUndoStep* step = webUndoStep(stepID);
+ if (!step)
+ return;
+
+ step->step()->unapply();
+}
+
+void WebPage::reapplyEditCommand(uint64_t stepID)
+{
+ WebUndoStep* step = webUndoStep(stepID);
+ if (!step)
+ return;
+
+ m_isInRedo = true;
+ step->step()->reapply();
+ m_isInRedo = false;
+}
+
+void WebPage::didRemoveEditCommand(uint64_t commandID)
+{
+ removeWebEditCommand(commandID);
+}
+
+void WebPage::setActivePopupMenu(WebPopupMenu* menu)
+{
+ m_activePopupMenu = menu;
+}
+
+void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener)
+{
+ m_activeOpenPanelResultListener = openPanelResultListener;
+}
+
+bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options)
+{
+ return m_page->findString(target, options);
+}
+
+void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount)
+{
+ m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount);
+}
+
+void WebPage::hideFindUI()
+{
+ m_findController.hideFindUI();
+}
+
+void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
+{
+ m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
+}
+
+void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
+{
+ if (!m_activePopupMenu)
+ return;
+
+ m_activePopupMenu->didChangeSelectedIndex(newIndex);
+ m_activePopupMenu = 0;
+}
+
+void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
+{
+ if (!m_activeOpenPanelResultListener)
+ return;
+
+ m_activeOpenPanelResultListener->didChooseFiles(files);
+ m_activeOpenPanelResultListener = 0;
+}
+
+void WebPage::didCancelForOpenPanel()
+{
+ m_activeOpenPanelResultListener = 0;
+}
+
+#if ENABLE(WEB_PROCESS_SANDBOX)
+void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle)
+{
+ SandboxExtension::create(handle)->consumePermanently();
+}
+#endif
+
+void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
+{
+ m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed);
+}
+
+void WebPage::didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)
+{
+ notificationPermissionRequestManager()->didReceiveNotificationPermissionDecision(notificationID, allowed);
+}
+
+void WebPage::advanceToNextMisspelling(bool startBeforeSelection)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ frame->editor()->advanceToNextMisspelling(startBeforeSelection);
+}
+
+void WebPage::changeSpellingToWord(const String& word)
+{
+ replaceSelectionWithText(m_page->focusController()->focusedOrMainFrame(), word);
+}
+
+void WebPage::unmarkAllMisspellings()
+{
+ for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (Document* document = frame->document())
+ document->markers()->removeMarkers(DocumentMarker::Spelling);
+ }
+}
+
+void WebPage::unmarkAllBadGrammar()
+{
+ for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (Document* document = frame->document())
+ document->markers()->removeMarkers(DocumentMarker::Grammar);
+ }
+}
+
+#if PLATFORM(MAC)
+void WebPage::uppercaseWord()
+{
+ m_page->focusController()->focusedOrMainFrame()->editor()->uppercaseWord();
+}
+
+void WebPage::lowercaseWord()
+{
+ m_page->focusController()->focusedOrMainFrame()->editor()->lowercaseWord();
+}
+
+void WebPage::capitalizeWord()
+{
+ m_page->focusController()->focusedOrMainFrame()->editor()->capitalizeWord();
+}
+#endif
+
+void WebPage::setTextForActivePopupMenu(int32_t index)
+{
+ if (!m_activePopupMenu)
+ return;
+
+ m_activePopupMenu->setTextForIndex(index);
+}
+
+#if PLATFORM(GTK)
+void WebPage::failedToShowPopupMenu()
+{
+ if (!m_activePopupMenu)
+ return;
+
+ m_activePopupMenu->client()->popupDidHide();
+}
+#endif
+
+void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item)
+{
+ if (!m_contextMenu)
+ return;
+
+ m_contextMenu->itemSelected(item);
+ m_contextMenu = 0;
+}
+
+void WebPage::replaceSelectionWithText(Frame* frame, const String& text)
+{
+ bool selectReplacement = true;
+ bool smartReplace = false;
+ return frame->editor()->replaceSelectionWithText(text, selectReplacement, smartReplace);
+}
+
+void WebPage::clearSelection()
+{
+ m_page->focusController()->focusedOrMainFrame()->selection()->clear();
+}
+
+bool WebPage::mainFrameHasCustomRepresentation() const
+{
+ if (Frame* frame = mainFrame())
+ return static_cast<WebFrameLoaderClient*>(frame->loader()->client())->frameHasCustomRepresentation();
+
+ return false;
+}
+
+void WebPage::didChangeScrollOffsetForMainFrame()
+{
+ Frame* frame = m_page->mainFrame();
+ IntPoint scrollPosition = frame->view()->scrollPosition();
+ IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition();
+ IntPoint minimumScrollPosition = frame->view()->minimumScrollPosition();
+
+ bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x());
+ bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x());
+
+ if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide) {
+ send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide));
+
+ m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide;
+ m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide;
+ }
+}
+
+void WebPage::mainFrameDidLayout()
+{
+ unsigned pageCount = m_page->pageCount();
+ if (pageCount != m_cachedPageCount) {
+ send(Messages::WebPageProxy::DidChangePageCount(pageCount));
+ m_cachedPageCount = pageCount;
+ }
+}
+
+#if PLATFORM(MAC)
+
+void WebPage::addPluginView(PluginView* pluginView)
+{
+ ASSERT(!m_pluginViews.contains(pluginView));
+
+ m_pluginViews.add(pluginView);
+}
+
+void WebPage::removePluginView(PluginView* pluginView)
+{
+ ASSERT(m_pluginViews.contains(pluginView));
+
+ m_pluginViews.remove(pluginView);
+}
+
+void WebPage::setWindowIsVisible(bool windowIsVisible)
+{
+ m_windowIsVisible = windowIsVisible;
+
+ // Tell all our plug-in views that the window visibility changed.
+ for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
+ (*it)->setWindowIsVisible(windowIsVisible);
+}
+
+void WebPage::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates, const WebCore::IntPoint& accessibilityViewCoordinates)
+{
+ m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
+ m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates;
+ m_accessibilityPosition = accessibilityViewCoordinates;
+
+ // Tell all our plug-in views that the window and view frames have changed.
+ for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
+ (*it)->windowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates);
+}
+
+#endif
+
+bool WebPage::windowIsFocused() const
+{
+#if PLATFORM(MAC)
+ if (!m_windowIsVisible)
+ return false;
+#endif
+ return m_page->focusController()->isFocused() && m_page->focusController()->isActive();
+}
+
+void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
+{
+ if (messageID.is<CoreIPC::MessageClassDrawingArea>()) {
+ if (m_drawingArea)
+ m_drawingArea->didReceiveDrawingAreaMessage(connection, messageID, arguments);
+ return;
+ }
+
+#if USE(TILED_BACKING_STORE) && USE(ACCELERATED_COMPOSITING)
+ if (messageID.is<CoreIPC::MessageClassLayerTreeHost>()) {
+ if (m_drawingArea)
+ m_drawingArea->didReceiveLayerTreeHostMessage(connection, messageID, arguments);
+ return;
+ }
+#endif
+
+#if ENABLE(INSPECTOR)
+ if (messageID.is<CoreIPC::MessageClassWebInspector>()) {
+ if (WebInspector* inspector = this->inspector())
+ inspector->didReceiveWebInspectorMessage(connection, messageID, arguments);
+ return;
+ }
+#endif
+
+#if ENABLE(FULLSCREEN_API)
+ if (messageID.is<CoreIPC::MessageClassWebFullScreenManager>()) {
+ fullScreenManager()->didReceiveMessage(connection, messageID, arguments);
+ return;
+ }
+#endif
+
+ didReceiveWebPageMessage(connection, messageID, arguments);
+}
+
+void WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply)
+{
+ didReceiveSyncWebPageMessage(connection, messageID, arguments, reply);
+}
+
+InjectedBundleBackForwardList* WebPage::backForwardList()
+{
+ if (!m_backForwardList)
+ m_backForwardList = InjectedBundleBackForwardList::create(this);
+ return m_backForwardList.get();
+}
+
+#if PLATFORM(QT)
+void WebPage::findZoomableAreaForPoint(const WebCore::IntPoint& point)
+{
+ Frame* mainframe = m_mainFrame->coreFrame();
+ HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true);
+
+ Node* node = result.innerNode();
+
+ if (!node)
+ return;
+
+ IntRect zoomableArea = node->getRect();
+
+ while (true) {
+ bool found = !node->isTextNode() && !node->isShadowRoot();
+
+ // No candidate found, bail out.
+ if (!found && !node->parentNode())
+ return;
+
+ // Candidate found, and it is a better candidate than its parent.
+ // NB: A parent is considered a better candidate iff the node is
+ // contained by it and it is the only child.
+ if (found && (!node->parentNode() || node->parentNode()->childNodeCount() != 1))
+ break;
+
+ node = node->parentNode();
+ zoomableArea.unite(node->getRect());
+ }
+
+ if (node->document() && node->document()->frame() && node->document()->frame()->view()) {
+ const ScrollView* view = node->document()->frame()->view();
+ zoomableArea = view->contentsToWindow(zoomableArea);
+ }
+
+ send(Messages::WebPageProxy::DidFindZoomableArea(point, zoomableArea));
+}
+#endif
+
+WebPage::SandboxExtensionTracker::~SandboxExtensionTracker()
+{
+ invalidate();
+}
+
+void WebPage::SandboxExtensionTracker::invalidate()
+{
+ if (m_pendingProvisionalSandboxExtension) {
+ m_pendingProvisionalSandboxExtension->invalidate();
+ m_pendingProvisionalSandboxExtension = 0;
+ }
+
+ if (m_provisionalSandboxExtension) {
+ m_provisionalSandboxExtension->invalidate();
+ m_provisionalSandboxExtension = 0;
+ }
+
+ if (m_committedSandboxExtension) {
+ m_committedSandboxExtension->invalidate();
+ m_committedSandboxExtension = 0;
+ }
+}
+
+void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension)
+{
+ setPendingProvisionalSandboxExtension(pendingDropSandboxExtension);
+}
+
+void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle)
+{
+ ASSERT(frame->isMainFrame());
+
+ setPendingProvisionalSandboxExtension(SandboxExtension::create(handle));
+}
+
+void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension)
+{
+ // If we get two beginLoad calls in succession, without a provisional load starting, then
+ // m_pendingProvisionalSandboxExtension will be non-null. Invalidate and null out the extension if that is the case.
+ if (m_pendingProvisionalSandboxExtension) {
+ m_pendingProvisionalSandboxExtension->invalidate();
+ m_pendingProvisionalSandboxExtension = nullptr;
+ }
+
+ m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension;
+}
+
+static bool shouldReuseCommittedSandboxExtension(WebFrame* frame)
+{
+ ASSERT(frame->isMainFrame());
+
+ FrameLoader* frameLoader = frame->coreFrame()->loader();
+ FrameLoadType frameLoadType = frameLoader->loadType();
+
+ // If the page is being reloaded, it should reuse whatever extension is committed.
+ if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin)
+ return true;
+
+ DocumentLoader* documentLoader = frameLoader->documentLoader();
+ DocumentLoader* provisionalDocumentLoader = frameLoader->provisionalDocumentLoader();
+ if (!documentLoader || !provisionalDocumentLoader)
+ return false;
+
+ if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile())
+ return true;
+
+ return false;
+}
+
+void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
+{
+ if (!frame->isMainFrame())
+ return;
+
+ // We should only reuse the commited sandbox extension if it is not null. It can be
+ // null if the last load was for an error page.
+ if (m_committedSandboxExtension && shouldReuseCommittedSandboxExtension(frame)) {
+ m_pendingProvisionalSandboxExtension = m_committedSandboxExtension.release();
+ ASSERT(!m_committedSandboxExtension);
+ }
+
+ ASSERT(!m_provisionalSandboxExtension);
+
+ m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
+ if (!m_provisionalSandboxExtension)
+ return;
+
+ m_provisionalSandboxExtension->consume();
+}
+
+void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame)
+{
+ if (!frame->isMainFrame())
+ return;
+
+ ASSERT(!m_pendingProvisionalSandboxExtension);
+
+ // The provisional load has been committed. Invalidate the currently committed sandbox
+ // extension and make the provisional sandbox extension the committed sandbox extension.
+ if (m_committedSandboxExtension)
+ m_committedSandboxExtension->invalidate();
+
+ m_committedSandboxExtension = m_provisionalSandboxExtension.release();
+}
+
+void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame)
+{
+ if (!frame->isMainFrame())
+ return;
+
+ if (!m_provisionalSandboxExtension)
+ return;
+
+ m_provisionalSandboxExtension->invalidate();
+ m_provisionalSandboxExtension = nullptr;
+}
+
+bool WebPage::hasLocalDataForURL(const KURL& url)
+{
+ if (url.isLocalFile())
+ return true;
+
+ FrameLoader* frameLoader = m_page->mainFrame()->loader();
+ DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0;
+ if (documentLoader && documentLoader->subresource(url))
+ return true;
+
+ return platformHasLocalDataForURL(url);
+}
+
+void WebPage::setCustomTextEncodingName(const String& encoding)
+{
+ m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding);
+}
+
+void WebPage::didRemoveBackForwardItem(uint64_t itemID)
+{
+ WebBackForwardListProxy::removeItem(itemID);
+}
+
+#if PLATFORM(MAC)
+
+bool WebPage::isSpeaking()
+{
+ bool result;
+ return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result;
+}
+
+void WebPage::speak(const String& string)
+{
+ send(Messages::WebPageProxy::Speak(string));
+}
+
+void WebPage::stopSpeaking()
+{
+ send(Messages::WebPageProxy::StopSpeaking());
+}
+
+#endif
+
+#if USE(CG)
+static RetainPtr<CGPDFDocumentRef> pdfDocumentForPrintingFrame(Frame* coreFrame)
+{
+ Document* document = coreFrame->document();
+ if (!document)
+ return 0;
+
+ if (!document->isPluginDocument())
+ return 0;
+
+ PluginView* pluginView = static_cast<PluginView*>(toPluginDocument(document)->pluginWidget());
+ if (!pluginView)
+ return 0;
+
+ return pluginView->pdfDocumentForPrinting();
+}
+#endif // USE(CG)
+
+void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
+{
+ WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ if (!frame)
+ return;
+
+ Frame* coreFrame = frame->coreFrame();
+ if (!coreFrame)
+ return;
+
+#if USE(CG)
+ if (pdfDocumentForPrintingFrame(coreFrame))
+ return;
+#endif // USE(CG)
+
+ if (!m_printContext)
+ m_printContext = adoptPtr(new PrintContext(coreFrame));
+
+ m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight);
+
+ float fullPageHeight;
+ m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true);
+}
+
+void WebPage::endPrinting()
+{
+ m_printContext = nullptr;
+}
+
+void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
+{
+ Vector<IntRect> resultPageRects;
+ double resultTotalScaleFactorForPrinting = 1;
+
+ beginPrinting(frameID, printInfo);
+
+ if (m_printContext) {
+ resultPageRects = m_printContext->pageRects();
+ resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor;
+ }
+#if USE(CG)
+ else {
+ WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ Frame* coreFrame = frame ? frame->coreFrame() : 0;
+ RetainPtr<CGPDFDocumentRef> pdfDocument = coreFrame ? pdfDocumentForPrintingFrame(coreFrame) : 0;
+ if (pdfDocument && CGPDFDocumentAllowsPrinting(pdfDocument.get())) {
+ CFIndex pageCount = CGPDFDocumentGetNumberOfPages(pdfDocument.get());
+ IntRect pageRect(0, 0, ceilf(printInfo.availablePaperWidth), ceilf(printInfo.availablePaperHeight));
+ for (CFIndex i = 1; i <= pageCount; ++i) {
+ resultPageRects.append(pageRect);
+ pageRect.move(0, pageRect.height());
+ }
+ }
+ }
+#endif // USE(CG)
+
+ // 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 USE(CG)
+static inline CGFloat roundCGFloat(CGFloat f)
+{
+ if (sizeof(CGFloat) == sizeof(float))
+ return roundf(static_cast<float>(f));
+ return static_cast<CGFloat>(round(f));
+}
+
+static void drawPDFPage(CGPDFDocumentRef pdfDocument, CFIndex pageIndex, CGContextRef context, CGFloat pageSetupScaleFactor, CGSize paperSize)
+{
+ CGContextSaveGState(context);
+
+ CGContextScaleCTM(context, pageSetupScaleFactor, pageSetupScaleFactor);
+
+ CGPDFPageRef page = CGPDFDocumentGetPage(pdfDocument, pageIndex + 1);
+ CGRect cropBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
+ if (CGRectIsEmpty(cropBox))
+ cropBox = CGRectIntersection(cropBox, CGPDFPageGetBoxRect(page, kCGPDFMediaBox));
+ else
+ cropBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
+
+ bool shouldRotate = (paperSize.width < paperSize.height) != (cropBox.size.width < cropBox.size.height);
+ if (shouldRotate)
+ swap(cropBox.size.width, cropBox.size.height);
+
+ // Center.
+ CGFloat widthDifference = paperSize.width / pageSetupScaleFactor - cropBox.size.width;
+ CGFloat heightDifference = paperSize.height / pageSetupScaleFactor - cropBox.size.height;
+ if (widthDifference || heightDifference)
+ CGContextTranslateCTM(context, roundCGFloat(widthDifference / 2), roundCGFloat(heightDifference / 2));
+
+ if (shouldRotate) {
+ CGContextRotateCTM(context, static_cast<CGFloat>(piOverTwoDouble));
+ CGContextTranslateCTM(context, 0, -cropBox.size.width);
+ }
+
+ CGContextDrawPDFPage(context, page);
+
+ CGContextRestoreGState(context);
+}
+#endif // USE(CG)
+
+#if PLATFORM(MAC) || PLATFORM(WIN)
+void WebPage::drawRectToPDF(uint64_t frameID, const PrintInfo& printInfo, const WebCore::IntRect& rect, uint64_t callbackID)
+{
+ WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ Frame* coreFrame = frame ? frame->coreFrame() : 0;
+
+ RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
+
+ if (coreFrame) {
+#if !USE(CG)
+ UNUSED_PARAM(printInfo);
+
+ ASSERT(coreFrame->document()->printing());
+#else
+ ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
+
+ // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
+ RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
+
+ CGRect mediaBox = CGRectMake(0, 0, rect.width(), rect.height());
+ RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
+ RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ CGPDFContextBeginPage(context.get(), pageInfo.get());
+
+ if (RetainPtr<CGPDFDocumentRef> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) {
+ CFIndex pageCount = CGPDFDocumentGetNumberOfPages(pdfDocument.get());
+ IntSize paperSize(ceilf(printInfo.availablePaperWidth), ceilf(printInfo.availablePaperHeight));
+ IntRect pageRect(IntPoint(), paperSize);
+ for (CFIndex i = 0; i < pageCount; ++i) {
+ if (pageRect.intersects(rect)) {
+ CGContextSaveGState(context.get());
+
+ CGContextTranslateCTM(context.get(), pageRect.x() - rect.x(), pageRect.y() - rect.y());
+ drawPDFPage(pdfDocument.get(), i, context.get(), printInfo.pageSetupScaleFactor, paperSize);
+
+ CGContextRestoreGState(context.get());
+ }
+ pageRect.move(0, pageRect.height());
+ }
+ } else {
+ GraphicsContext ctx(context.get());
+ ctx.scale(FloatSize(1, -1));
+ ctx.translate(0, -rect.height());
+ m_printContext->spoolRect(ctx, rect);
+ }
+
+ CGPDFContextEndPage(context.get());
+ CGPDFContextClose(context.get());
+#endif
+ }
+
+ send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), 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);
+ Frame* coreFrame = frame ? frame->coreFrame() : 0;
+
+ RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
+
+ if (coreFrame) {
+
+#if !USE(CG)
+ ASSERT(coreFrame->document()->printing());
+#else
+ ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
+
+ RetainPtr<CGPDFDocumentRef> pdfDocument = pdfDocumentForPrintingFrame(coreFrame);
+
+ // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
+ RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
+
+ 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));
+ size_t pageCount = m_printContext ? m_printContext->pageCount() : CGPDFDocumentGetNumberOfPages(pdfDocument.get());
+ for (uint32_t page = first; page < first + count; ++page) {
+ if (page >= pageCount)
+ break;
+
+ RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ CGPDFContextBeginPage(context.get(), pageInfo.get());
+
+ if (pdfDocument)
+ drawPDFPage(pdfDocument.get(), page, context.get(), printInfo.pageSetupScaleFactor, CGSizeMake(printInfo.availablePaperWidth, printInfo.availablePaperHeight));
+ else {
+ GraphicsContext ctx(context.get());
+ ctx.scale(FloatSize(1, -1));
+ ctx.translate(0, -m_printContext->pageRect(page).height());
+ m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width());
+ }
+
+ CGPDFContextEndPage(context.get());
+ }
+ CGPDFContextClose(context.get());
+#endif
+ }
+
+ send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
+}
+#endif
+
+void WebPage::runModal()
+{
+ if (m_isClosed)
+ return;
+ if (m_isRunningModal)
+ return;
+
+ m_isRunningModal = true;
+ send(Messages::WebPageProxy::RunModal());
+ 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()))
+ return true;
+ return platformCanHandleRequest(request);
+}
+
+#if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
+void WebPage::handleCorrectionPanelResult(const String& result)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+ frame->editor()->handleCorrectionPanelResult(result);
+}
+#endif
+
+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));
+}
+
+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));
+}
+
+void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time)
+{
+ mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time));
+}
+
+String WebPage::viewportConfigurationAsText(int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight)
+{
+ ViewportArguments arguments = mainFrame()->document()->viewportArguments();
+ ViewportAttributes attrs = WebCore::computeViewportAttributes(arguments, /* default layout width for non-mobile pages */ 980, deviceWidth, deviceHeight, deviceDPI, IntSize(availableWidth, availableHeight));
+ WebCore::restrictMinimumScaleFactorToViewportSize(attrs, IntSize(availableWidth, availableHeight));
+ WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attrs);
+ return String::format("viewport size %dx%d scale %f with limits [%f, %f] and userScalable %f\n", attrs.layoutSize.width(), attrs.layoutSize.height(), attrs.initialScale, attrs.minimumScale, attrs.maximumScale, attrs.userScalable);
+}
+
+void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame || !frame->editor()->canEdit())
+ return;
+
+ Vector<CompositionUnderline> underlines;
+ underlines.append(CompositionUnderline(0, compositionString.length(), Color(Color::black), false));
+ frame->editor()->setComposition(compositionString, underlines, from, from + length);
+}
+
+bool WebPage::hasCompositionForTesting()
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ return frame && frame->editor()->hasComposition();
+}
+
+void WebPage::confirmCompositionForTesting(const String& compositionString)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame || !frame->editor()->canEdit())
+ return;
+
+ if (compositionString.isNull())
+ frame->editor()->confirmComposition();
+ frame->editor()->confirmComposition(compositionString);
+}
+
+Frame* WebPage::mainFrame() const
+{
+ return m_page ? m_page->mainFrame() : 0;
+}
+
+FrameView* WebPage::mainFrameView() const
+{
+ if (Frame* frame = mainFrame())
+ return frame->view();
+
+ return 0;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h
new file mode 100644
index 000000000..40072cfbf
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h
@@ -0,0 +1,748 @@
+/*
+ * Copyright (C) 2010, 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.
+ */
+
+#ifndef WebPage_h
+#define WebPage_h
+
+#include "APIObject.h"
+#include "DrawingArea.h"
+#include "FindController.h"
+#include "GeolocationPermissionRequestManager.h"
+#include "ImageOptions.h"
+#include "ImmutableArray.h"
+#include "InjectedBundlePageContextMenuClient.h"
+#include "InjectedBundlePageEditorClient.h"
+#include "InjectedBundlePageFormClient.h"
+#include "InjectedBundlePageFullScreenClient.h"
+#include "InjectedBundlePageLoaderClient.h"
+#include "InjectedBundlePagePolicyClient.h"
+#include "InjectedBundlePageResourceLoadClient.h"
+#include "InjectedBundlePageUIClient.h"
+#include "MessageSender.h"
+#include "Plugin.h"
+#include "SandboxExtension.h"
+#include "ShareableBitmap.h"
+#include "WebUndoStep.h"
+#include <WebCore/DragData.h>
+#include <WebCore/Editor.h>
+#include <WebCore/FrameLoaderTypes.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/PlatformScreen.h>
+#include <WebCore/ScrollTypes.h>
+#include <WebCore/WebCoreKeyboardUIMode.h>
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(QT)
+#include "ArgumentCodersQt.h"
+#include "QtNetworkAccessManager.h"
+#include "QtNetworkReply.h"
+#include "QtNetworkReplyData.h"
+#include "QtNetworkRequestData.h"
+#include <QNetworkReply>
+#include <QNetworkRequest>
+#endif
+
+#if PLATFORM(GTK)
+#include "ArgumentCodersGtk.h"
+#endif
+
+#if ENABLE(TOUCH_EVENTS)
+#include <WebCore/PlatformTouchEvent.h>
+#endif
+
+#if PLATFORM(MAC)
+#include "DictionaryPopupInfo.h"
+#include <wtf/RetainPtr.h>
+OBJC_CLASS NSDictionary;
+OBJC_CLASS NSObject;
+OBJC_CLASS WKAccessibilityWebPageObject;
+#endif
+
+namespace CoreIPC {
+ class ArgumentDecoder;
+ class Connection;
+ class MessageID;
+}
+
+namespace WebCore {
+ class GraphicsContext;
+ class Frame;
+ class FrameView;
+ class KeyboardEvent;
+ class Page;
+ class PrintContext;
+ class Range;
+ class ResourceRequest;
+ class SharedBuffer;
+ class VisibleSelection;
+ struct KeypressCommand;
+}
+
+namespace WebKit {
+
+class DrawingArea;
+class InjectedBundleBackForwardList;
+class NotificationPermissionRequestManager;
+class PageOverlay;
+class PluginView;
+class SessionState;
+class WebContextMenu;
+class WebContextMenuItemData;
+class WebEvent;
+class WebFrame;
+class WebFullScreenManager;
+class WebImage;
+class WebInspector;
+class WebKeyboardEvent;
+class WebMouseEvent;
+class WebNotificationClient;
+class WebOpenPanelResultListener;
+class WebPageGroupProxy;
+class WebPopupMenu;
+class WebWheelEvent;
+struct AttributedString;
+struct EditorState;
+struct PrintInfo;
+struct WebPageCreationParameters;
+struct WebPreferencesStore;
+
+#if ENABLE(GESTURE_EVENTS)
+class WebGestureEvent;
+#endif
+
+#if ENABLE(TOUCH_EVENTS)
+class WebTouchEvent;
+#endif
+
+class WebPage : public APIObject, public CoreIPC::MessageSender<WebPage> {
+public:
+ static const Type APIType = TypeBundlePage;
+
+ static PassRefPtr<WebPage> create(uint64_t pageID, const WebPageCreationParameters&);
+ virtual ~WebPage();
+
+ // Used by MessageSender.
+ CoreIPC::Connection* connection() const;
+ uint64_t destinationID() const { return pageID(); }
+
+ void close();
+
+ WebCore::Page* corePage() const { return m_page.get(); }
+ uint64_t pageID() const { return m_pageID; }
+
+ void setSize(const WebCore::IntSize&);
+ const WebCore::IntSize& size() const { return m_viewSize; }
+ WebCore::IntRect bounds() const { return WebCore::IntRect(WebCore::IntPoint(), size()); }
+
+ InjectedBundleBackForwardList* backForwardList();
+ DrawingArea* drawingArea() const { return m_drawingArea.get(); }
+
+ WebPageGroupProxy* pageGroup() const { return m_pageGroup.get(); }
+
+ void scrollMainFrameIfNotAtMaxScrollPosition(const WebCore::IntSize& scrollOffset);
+
+ void scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity);
+
+ void centerSelectionInVisibleArea();
+
+#if ENABLE(INSPECTOR)
+ WebInspector* inspector();
+#endif
+
+#if ENABLE(FULLSCREEN_API)
+ WebFullScreenManager* fullScreenManager();
+#endif
+
+ // -- 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(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 show();
+ String userAgent() const { return m_userAgent; }
+ WebCore::IntRect windowResizerRect() const;
+ WebCore::KeyboardUIMode keyboardUIMode();
+
+ WebUndoStep* webUndoStep(uint64_t);
+ void addWebUndoStep(uint64_t, WebUndoStep*);
+ void removeWebEditCommand(uint64_t);
+ bool isInRedo() const { return m_isInRedo; }
+
+ void setActivePopupMenu(WebPopupMenu*);
+
+ WebOpenPanelResultListener* activeOpenPanelResultListener() const { return m_activeOpenPanelResultListener.get(); }
+ void setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener>);
+
+ // -- Called from WebProcess.
+ void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+ void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&);
+
+ // -- InjectedBundle methods
+ void initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient*);
+ void initializeInjectedBundleEditorClient(WKBundlePageEditorClient*);
+ void initializeInjectedBundleFormClient(WKBundlePageFormClient*);
+ void initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient*);
+ void initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient*);
+ void initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient*);
+ void initializeInjectedBundleUIClient(WKBundlePageUIClient*);
+#if ENABLE(FULLSCREEN_API)
+ void initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient*);
+#endif
+
+ InjectedBundlePageContextMenuClient& injectedBundleContextMenuClient() { return m_contextMenuClient; }
+ InjectedBundlePageEditorClient& injectedBundleEditorClient() { return m_editorClient; }
+ InjectedBundlePageFormClient& injectedBundleFormClient() { return m_formClient; }
+ InjectedBundlePageLoaderClient& injectedBundleLoaderClient() { return m_loaderClient; }
+ InjectedBundlePagePolicyClient& injectedBundlePolicyClient() { return m_policyClient; }
+ InjectedBundlePageResourceLoadClient& injectedBundleResourceLoadClient() { return m_resourceLoadClient; }
+ InjectedBundlePageUIClient& injectedBundleUIClient() { return m_uiClient; }
+#if ENABLE(FULLSCREEN_API)
+ InjectedBundlePageFullScreenClient& injectedBundleFullScreenClient() { return m_fullScreenClient; }
+#endif
+
+ void setUnderlayPage(PassRefPtr<WebPage> underlayPage) { m_underlayPage = underlayPage; }
+
+ bool findStringFromInjectedBundle(const String&, FindOptions);
+
+ WebFrame* mainWebFrame() const { return m_mainFrame.get(); }
+
+ WebCore::Frame* mainFrame() const; // May return 0.
+ WebCore::FrameView* mainFrameView() const; // May return 0.
+
+ PassRefPtr<Plugin> createPlugin(WebFrame*, const Plugin::Parameters&);
+
+ EditorState editorState() const;
+
+ String renderTreeExternalRepresentation() const;
+ uint64_t renderTreeSize() const;
+
+ void setTracksRepaints(bool);
+ bool isTrackingRepaints() const;
+ void resetTrackedRepaints();
+ PassRefPtr<ImmutableArray> trackedRepaintRects();
+
+ void executeEditingCommand(const String& commandName, const String& argument);
+ bool isEditingCommandEnabled(const String& commandName);
+ void clearMainFrameName();
+ void sendClose();
+
+ double textZoomFactor() const;
+ void setTextZoomFactor(double);
+ double pageZoomFactor() const;
+ void setPageZoomFactor(double);
+ void setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor);
+ void windowScreenDidChange(uint64_t);
+
+ void scalePage(double scale, const WebCore::IntPoint& origin);
+ double pageScaleFactor() const;
+
+ void setUseFixedLayout(bool);
+ bool useFixedLayout() const { return m_useFixedLayout; }
+ void setFixedLayoutSize(const WebCore::IntSize&);
+
+ void setPaginationMode(uint32_t /* WebCore::Page::Pagination::Mode */);
+ void setPageLength(double);
+ void setGapBetweenPages(double);
+
+ bool drawsBackground() const { return m_drawsBackground; }
+ bool drawsTransparentBackground() const { return m_drawsTransparentBackground; }
+
+ void stopLoading();
+ void stopLoadingFrame(uint64_t frameID);
+ void setDefersLoading(bool deferLoading);
+
+#if USE(ACCELERATED_COMPOSITING)
+ void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*);
+ void exitAcceleratedCompositingMode();
+#endif
+
+#if PLATFORM(MAC)
+ void addPluginView(PluginView*);
+ void removePluginView(PluginView*);
+
+ bool windowIsVisible() const { return m_windowIsVisible; }
+ const WebCore::IntRect& windowFrameInScreenCoordinates() const { return m_windowFrameInScreenCoordinates; }
+ const WebCore::IntRect& viewFrameInWindowCoordinates() const { return m_viewFrameInWindowCoordinates; }
+#elif PLATFORM(WIN)
+ HWND nativeWindow() const { return m_nativeWindow; }
+#endif
+
+ bool windowIsFocused() const;
+ void installPageOverlay(PassRefPtr<PageOverlay>);
+ void uninstallPageOverlay(PageOverlay*, bool fadeOut);
+ bool hasPageOverlay() const { return m_pageOverlay; }
+ WebCore::IntPoint screenToWindow(const WebCore::IntPoint&);
+ WebCore::IntRect windowToScreen(const WebCore::IntRect&);
+
+ PassRefPtr<WebImage> snapshotInViewCoordinates(const WebCore::IntRect&, ImageOptions);
+ PassRefPtr<WebImage> snapshotInDocumentCoordinates(const WebCore::IntRect&, ImageOptions);
+ PassRefPtr<WebImage> scaledSnapshotInDocumentCoordinates(const WebCore::IntRect&, double scaleFactor, ImageOptions);
+
+ static const WebEvent* currentEvent();
+
+ FindController& findController() { return m_findController; }
+ GeolocationPermissionRequestManager& geolocationPermissionRequestManager() { return m_geolocationPermissionRequestManager; }
+ NotificationPermissionRequestManager* notificationPermissionRequestManager();
+
+ void pageDidScroll();
+#if USE(TILED_BACKING_STORE)
+ void pageDidRequestScroll(const WebCore::IntPoint&);
+ void setFixedVisibleContentRect(const WebCore::IntRect&);
+ void setResizesToContentsUsingLayoutSize(const WebCore::IntSize&);
+ void resizeToContentsIfNeeded();
+ void setViewportSize(const WebCore::IntSize&);
+ WebCore::IntSize viewportSize() const { return m_viewportSize; }
+#endif
+
+ WebContextMenu* contextMenu();
+
+ bool hasLocalDataForURL(const WebCore::KURL&);
+ String cachedResponseMIMETypeForURL(const WebCore::KURL&);
+ String cachedSuggestedFilenameForURL(const WebCore::KURL&);
+ PassRefPtr<WebCore::SharedBuffer> cachedResponseDataForURL(const WebCore::KURL&);
+
+ static bool canHandleRequest(const WebCore::ResourceRequest&);
+
+ class SandboxExtensionTracker {
+ public:
+ ~SandboxExtensionTracker();
+
+ void invalidate();
+
+ void beginLoad(WebFrame*, const SandboxExtension::Handle& handle);
+ void willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension);
+ void didStartProvisionalLoad(WebFrame*);
+ void didCommitProvisionalLoad(WebFrame*);
+ void didFailProvisionalLoad(WebFrame*);
+
+ private:
+ void setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension>);
+
+ RefPtr<SandboxExtension> m_pendingProvisionalSandboxExtension;
+ RefPtr<SandboxExtension> m_provisionalSandboxExtension;
+ RefPtr<SandboxExtension> m_committedSandboxExtension;
+ };
+
+ SandboxExtensionTracker& sandboxExtensionTracker() { return m_sandboxExtensionTracker; }
+
+#if PLATFORM(QT)
+ void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd);
+ void confirmComposition(const String& text, int64_t selectionStart, int64_t selectionLength);
+ void cancelComposition();
+#endif
+
+#if PLATFORM(MAC)
+ void registerUIProcessAccessibilityTokens(const CoreIPC::DataReference& elemenToken, const CoreIPC::DataReference& windowToken);
+ WKAccessibilityWebPageObject* accessibilityRemoteObject();
+ WebCore::IntPoint accessibilityPosition() const { return m_accessibilityPosition; }
+
+ void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput);
+
+ 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);
+ void cancelComposition(EditorState& newState);
+ void insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, bool& handled, EditorState& newState);
+ 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 writeSelectionToPasteboard(const WTF::String& pasteboardName, const WTF::Vector<WTF::String>& pasteboardTypes, bool& result);
+ void readSelectionFromPasteboard(const WTF::String& pasteboardName, bool& result);
+ void shouldDelayWindowOrderingEvent(const WebKit::WebMouseEvent&, bool& result);
+ void acceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent&, bool& result);
+ bool performNonEditingBehaviorForSelector(const String&);
+
+#elif PLATFORM(WIN)
+ void confirmComposition(const String& compositionString);
+ void setComposition(const WTF::String& compositionString, const WTF::Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition);
+ void firstRectForCharacterInSelectedRange(const uint64_t characterPosition, WebCore::IntRect& resultRect);
+ void getSelectedText(WTF::String&);
+
+ void gestureWillBegin(const WebCore::IntPoint&, bool& canBeginPanning);
+ void gestureDidScroll(const WebCore::IntSize&);
+ void gestureDidEnd();
+#endif
+
+ void setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length);
+ bool hasCompositionForTesting();
+ void confirmCompositionForTesting(const String& compositionString);
+
+ // 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.
+ void dummy(bool&);
+
+#if PLATFORM(MAC)
+ void performDictionaryLookupForSelection(DictionaryPopupInfo::Type, WebCore::Frame*, const WebCore::VisibleSelection&);
+
+ bool isSpeaking();
+ void speak(const String&);
+ void stopSpeaking();
+
+ bool isSmartInsertDeleteEnabled() const { return m_isSmartInsertDeleteEnabled; }
+#endif
+
+ void replaceSelectionWithText(WebCore::Frame*, const String&);
+ void clearSelection();
+#if PLATFORM(WIN)
+ void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap&, uint32_t flags);
+#elif PLATFORM(QT) || PLATFORM(GTK)
+ void performDragControllerAction(uint64_t action, WebCore::DragData);
+#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&);
+#endif
+ void dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation);
+
+ void willPerformLoadDragDestinationAction();
+
+ void beginPrinting(uint64_t frameID, const PrintInfo&);
+ void endPrinting();
+ void computePagesForPrinting(uint64_t frameID, const PrintInfo&, uint64_t callbackID);
+#if PLATFORM(MAC) || PLATFORM(WIN)
+ void drawRectToPDF(uint64_t frameID, const PrintInfo&, const WebCore::IntRect&, uint64_t callbackID);
+ void drawPagesToPDF(uint64_t frameID, const PrintInfo&, uint32_t first, uint32_t count, uint64_t callbackID);
+#endif
+
+ bool mainFrameHasCustomRepresentation() const;
+
+ void didChangeScrollOffsetForMainFrame();
+
+ void mainFrameDidLayout();
+
+ bool canRunBeforeUnloadConfirmPanel() const { return m_canRunBeforeUnloadConfirmPanel; }
+ void setCanRunBeforeUnloadConfirmPanel(bool canRunBeforeUnloadConfirmPanel) { m_canRunBeforeUnloadConfirmPanel = canRunBeforeUnloadConfirmPanel; }
+
+ bool canRunModal() const { return m_canRunModal; }
+ void setCanRunModal(bool canRunModal) { m_canRunModal = canRunModal; }
+
+ void runModal();
+
+ void setDeviceScaleFactor(float);
+ float deviceScaleFactor() const;
+
+ void setMemoryCacheMessagesEnabled(bool);
+
+ void forceRepaintWithoutCallback();
+
+ void unmarkAllMisspellings();
+ void unmarkAllBadGrammar();
+
+#if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
+ void handleCorrectionPanelResult(const String&);
+#endif
+
+ // For testing purpose.
+ void simulateMouseDown(int button, WebCore::IntPoint, int clickCount, WKEventModifiers, double time);
+ void simulateMouseUp(int button, WebCore::IntPoint, int clickCount, WKEventModifiers, double time);
+ void simulateMouseMotion(WebCore::IntPoint, double time);
+ String viewportConfigurationAsText(int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight);
+
+ void contextMenuShowing() { m_isShowingContextMenu = true; }
+
+#if PLATFORM(QT)
+ void registerApplicationScheme(const String& scheme);
+ void applicationSchemeReply(const QtNetworkReplyData&);
+ void receivedApplicationSchemeRequest(const QNetworkRequest&, QtNetworkReply*);
+#endif
+ void wheelEvent(const WebWheelEvent&);
+#if ENABLE(GESTURE_EVENTS)
+ void gestureEvent(const WebGestureEvent&);
+#endif
+
+private:
+ WebPage(uint64_t pageID, const WebPageCreationParameters&);
+
+ virtual Type type() const { return APIType; }
+
+ void platformInitialize();
+
+ void didReceiveWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+ void didReceiveSyncWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&);
+
+#if !PLATFORM(MAC)
+ static const char* interpretKeyEvent(const WebCore::KeyboardEvent*);
+#endif
+ bool performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&);
+
+#if PLATFORM(MAC)
+ bool executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>&, WebCore::KeyboardEvent*);
+#endif
+
+ String sourceForFrame(WebFrame*);
+
+ void loadData(PassRefPtr<WebCore::SharedBuffer>, const String& MIMEType, const String& encodingName, const WebCore::KURL& baseURL, const WebCore::KURL& failingURL);
+
+ bool platformHasLocalDataForURL(const WebCore::KURL&);
+
+ // Actions
+ void tryClose();
+ void loadURL(const String&, const SandboxExtension::Handle&);
+ void loadURLRequest(const WebCore::ResourceRequest&, const SandboxExtension::Handle&);
+ void loadHTMLString(const String& htmlString, const String& baseURL);
+ void loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL);
+ void loadPlainTextString(const String&);
+ void linkClicked(const String& url, const WebMouseEvent&);
+ void reload(bool reloadFromOrigin);
+ void goForward(uint64_t, const SandboxExtension::Handle&);
+ void goBack(uint64_t, const SandboxExtension::Handle&);
+ void goToBackForwardItem(uint64_t, const SandboxExtension::Handle&);
+ void tryRestoreScrollPosition();
+ void setActive(bool);
+ void setFocused(bool);
+ void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&);
+ void setWindowResizerSize(const WebCore::IntSize&);
+ void setIsInWindow(bool);
+ void validateCommand(const String&, uint64_t);
+ void executeEditCommand(const String&);
+
+ 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)
+ void touchEvent(const WebTouchEvent&);
+ void touchEventSyncForTesting(const WebTouchEvent&, bool& handled);
+#endif
+ void contextMenuHidden() { m_isShowingContextMenu = false; }
+
+ static void scroll(WebCore::Page*, WebCore::ScrollDirection, WebCore::ScrollGranularity);
+ static void logicalScroll(WebCore::Page*, WebCore::ScrollLogicalDirection, WebCore::ScrollGranularity);
+
+ uint64_t restoreSession(const SessionState&);
+ void restoreSessionAndNavigateToCurrentItem(const SessionState&, const SandboxExtension::Handle&);
+
+ void didRemoveBackForwardItem(uint64_t);
+
+ void setDrawsBackground(bool);
+ void setDrawsTransparentBackground(bool);
+
+ void viewWillStartLiveResize();
+ void viewWillEndLiveResize();
+
+ void getContentsAsString(uint64_t callbackID);
+ void getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID);
+ void getResourceDataFromFrame(uint64_t frameID, const String& resourceURL, uint64_t callbackID);
+ void getRenderTreeExternalRepresentation(uint64_t callbackID);
+ void getSelectionOrContentsAsString(uint64_t callbackID);
+ void getSourceForFrame(uint64_t frameID, uint64_t callbackID);
+ void getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID);
+ void runJavaScriptInMainFrame(const String&, uint64_t callbackID);
+ void forceRepaint(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 setUserAgent(const String&);
+ void setCustomTextEncodingName(const String&);
+
+#if PLATFORM(MAC)
+ void performDictionaryLookupAtLocation(const WebCore::FloatPoint&);
+ void performDictionaryLookupForRange(DictionaryPopupInfo::Type, WebCore::Frame*, WebCore::Range*, NSDictionary *options);
+
+ void setWindowIsVisible(bool windowIsVisible);
+ void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates, const WebCore::IntPoint& accessibilityViewCoordinates);
+#endif
+
+ void unapplyEditCommand(uint64_t commandID);
+ void reapplyEditCommand(uint64_t commandID);
+ void didRemoveEditCommand(uint64_t commandID);
+
+ void findString(const String&, uint32_t findOptions, uint32_t maxMatchCount);
+ void hideFindUI();
+ void countStringMatches(const String&, uint32_t findOptions, uint32_t maxMatchCount);
+
+#if PLATFORM(QT)
+ void findZoomableAreaForPoint(const WebCore::IntPoint&);
+#endif
+
+ void didChangeSelectedIndexForActivePopupMenu(int32_t newIndex);
+ void setTextForActivePopupMenu(int32_t index);
+
+#if PLATFORM(GTK)
+ void failedToShowPopupMenu();
+#endif
+
+ void didChooseFilesForOpenPanel(const Vector<String>&);
+ void didCancelForOpenPanel();
+#if ENABLE(WEB_PROCESS_SANDBOX)
+ void extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle&);
+#endif
+
+ void didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed);
+ void didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed);
+
+ void advanceToNextMisspelling(bool startBeforeSelection);
+ void changeSpellingToWord(const String& word);
+#if PLATFORM(MAC)
+ void uppercaseWord();
+ void lowercaseWord();
+ void capitalizeWord();
+
+ void setSmartInsertDeleteEnabled(bool isSmartInsertDeleteEnabled) { m_isSmartInsertDeleteEnabled = isSmartInsertDeleteEnabled; }
+#endif
+
+#if ENABLE(CONTEXT_MENUS)
+ void didSelectItemFromActiveContextMenu(const WebContextMenuItemData&);
+#endif
+
+ void setCanStartMediaTimerFired();
+
+ static bool platformCanHandleRequest(const WebCore::ResourceRequest&);
+
+ OwnPtr<WebCore::Page> m_page;
+ RefPtr<WebFrame> m_mainFrame;
+ RefPtr<InjectedBundleBackForwardList> m_backForwardList;
+
+ RefPtr<WebPageGroupProxy> m_pageGroup;
+
+ String m_userAgent;
+
+ WebCore::IntSize m_viewSize;
+ OwnPtr<DrawingArea> m_drawingArea;
+ bool m_useFixedLayout;
+
+ bool m_drawsBackground;
+ bool m_drawsTransparentBackground;
+
+ bool m_isInRedo;
+ bool m_isClosed;
+
+ bool m_tabToLinks;
+
+#if PLATFORM(MAC)
+ // Whether the containing window is visible or not.
+ bool m_windowIsVisible;
+
+ // Whether smart insert/delete is enabled or not.
+ bool m_isSmartInsertDeleteEnabled;
+
+ // The frame of the containing window in screen coordinates.
+ WebCore::IntRect m_windowFrameInScreenCoordinates;
+
+ // The frame of the view in window coordinates.
+ WebCore::IntRect m_viewFrameInWindowCoordinates;
+
+ // The accessibility position of the view.
+ WebCore::IntPoint m_accessibilityPosition;
+
+ // All plug-in views on this web page.
+ HashSet<PluginView*> m_pluginViews;
+
+ RetainPtr<WKAccessibilityWebPageObject> m_mockAccessibilityElement;
+
+ WebCore::KeyboardEvent* m_keyboardEventBeingInterpreted;
+
+#elif PLATFORM(WIN)
+ // Our view's window (in the UI process).
+ HWND m_nativeWindow;
+
+ RefPtr<WebCore::Node> m_gestureTargetNode;
+#endif
+
+ RunLoop::Timer<WebPage> m_setCanStartMediaTimer;
+
+ HashMap<uint64_t, RefPtr<WebUndoStep> > m_undoStepMap;
+
+ WebCore::IntSize m_windowResizerSize;
+
+ InjectedBundlePageContextMenuClient m_contextMenuClient;
+ InjectedBundlePageEditorClient m_editorClient;
+ InjectedBundlePageFormClient m_formClient;
+ InjectedBundlePageLoaderClient m_loaderClient;
+ InjectedBundlePagePolicyClient m_policyClient;
+ InjectedBundlePageResourceLoadClient m_resourceLoadClient;
+ InjectedBundlePageUIClient m_uiClient;
+#if ENABLE(FULLSCREEN_API)
+ InjectedBundlePageFullScreenClient m_fullScreenClient;
+#endif
+
+#if USE(TILED_BACKING_STORE)
+ WebCore::IntSize m_resizesToContentsLayoutSize;
+ WebCore::IntSize m_viewportSize;
+#endif
+
+ FindController m_findController;
+ RefPtr<PageOverlay> m_pageOverlay;
+
+ RefPtr<WebPage> m_underlayPage;
+
+#if ENABLE(INSPECTOR)
+ RefPtr<WebInspector> m_inspector;
+#endif
+#if ENABLE(FULLSCREEN_API)
+ RefPtr<WebFullScreenManager> m_fullScreenManager;
+#endif
+ RefPtr<WebPopupMenu> m_activePopupMenu;
+ RefPtr<WebContextMenu> m_contextMenu;
+ RefPtr<WebOpenPanelResultListener> m_activeOpenPanelResultListener;
+ GeolocationPermissionRequestManager m_geolocationPermissionRequestManager;
+ RefPtr<NotificationPermissionRequestManager> m_notificationPermissionRequestManager;
+
+ OwnPtr<WebCore::PrintContext> m_printContext;
+
+ SandboxExtensionTracker m_sandboxExtensionTracker;
+ uint64_t m_pageID;
+
+ RefPtr<SandboxExtension> m_pendingDropSandboxExtension;
+
+ bool m_canRunBeforeUnloadConfirmPanel;
+
+ bool m_canRunModal;
+ bool m_isRunningModal;
+
+ bool m_cachedMainFrameIsPinnedToLeftSide;
+ bool m_cachedMainFrameIsPinnedToRightSide;
+
+ unsigned m_cachedPageCount;
+
+ bool m_isShowingContextMenu;
+
+#if PLATFORM(WIN)
+ bool m_gestureReachedScrollingLimit;
+#endif
+#if PLATFORM(QT)
+ HashMap<String, QtNetworkReply*> m_applicationSchemeReplies;
+#endif
+};
+
+} // namespace WebKit
+
+#endif // WebPage_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
new file mode 100644
index 000000000..5a3bb450e
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
@@ -0,0 +1,248 @@
+# Copyright (C) 2010, 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.
+
+messages -> WebPage {
+ SetActive(bool active)
+ SetFocused(bool focused)
+ SetInitialFocus(bool forward, bool isKeyboardEventValid, WebKit::WebKeyboardEvent event)
+ SetIsInWindow(bool isInWindow)
+
+ SetDrawsBackground(bool drawsBackground)
+ SetDrawsTransparentBackground(bool drawsTransparentBackground)
+
+ ViewWillStartLiveResize()
+ 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 ENABLE(TOUCH_EVENTS)
+ TouchEvent(WebKit::WebTouchEvent event)
+ TouchEventSyncForTesting(WebKit::WebTouchEvent event) -> (bool handled)
+#endif
+
+ ContextMenuHidden()
+
+ ScrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
+ CenterSelectionInVisibleArea()
+
+ GoBack(uint64_t backForwardItemID, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+ GoForward(uint64_t backForwardItemID, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+ GoToBackForwardItem(uint64_t backForwardItemID, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+ TryRestoreScrollPosition()
+ LoadHTMLString(WTF::String htmlString, WTF::String baseURL)
+ LoadAlternateHTMLString(WTF::String htmlString, WTF::String baseURL, WTF::String unreachableURL);
+ LoadPlainTextString(WTF::String string)
+ LoadURL(WTF::String url, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+ LoadURLRequest(WebCore::ResourceRequest request, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+ LinkClicked(WTF::String url, WebKit::WebMouseEvent event)
+ Reload(bool reloadFromOrigin)
+ StopLoading()
+
+#if PLATFORM(QT)
+ ApplicationSchemeReply(WebKit::QtNetworkReplyData reply)
+ RegisterApplicationScheme(WTF::String scheme)
+#endif
+
+ StopLoadingFrame(uint64_t frameID)
+
+ RestoreSession(WebKit::SessionState state)
+ RestoreSessionAndNavigateToCurrentItem(WebKit::SessionState state, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+
+ DidRemoveBackForwardItem(uint64_t backForwardItemID)
+
+ DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
+
+ ClearSelection()
+
+ # Callbacks.
+ GetContentsAsString(uint64_t callbackID)
+ GetMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
+ GetResourceDataFromFrame(uint64_t frameID, WTF::String resourceURL, uint64_t callbackID)
+ GetRenderTreeExternalRepresentation(uint64_t callbackID)
+ GetSelectionOrContentsAsString(uint64_t callbackID)
+ GetSourceForFrame(uint64_t frameID, uint64_t callbackID)
+ GetWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID)
+ RunJavaScriptInMainFrame(WTF::String script, uint64_t callbackID)
+ ForceRepaint(uint64_t callbackID)
+
+#if PLATFORM(MAC)
+ # Dictionary support.
+ PerformDictionaryLookupAtLocation(WebCore::FloatPoint point)
+#endif
+
+ PreferencesDidChange(WebKit::WebPreferencesStore store)
+
+ SetUserAgent(WTF::String userAgent)
+ SetCustomTextEncodingName(WTF::String encodingName)
+
+#if USE(TILED_BACKING_STORE)
+ SetFixedVisibleContentRect(WebCore::IntRect rect)
+ SetViewportSize(WebCore::IntSize size)
+#endif
+
+ Close()
+ TryClose()
+
+ ValidateCommand(WTF::String name, uint64_t callbackID)
+ ExecuteEditCommand(WTF::String name)
+
+ DidRemoveEditCommand(uint64_t commandID)
+ ReapplyEditCommand(uint64_t commandID)
+ UnapplyEditCommand(uint64_t commandID)
+
+ SetPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
+ SetPageZoomFactor(double zoomFactor)
+ SetTextZoomFactor(double zoomFactor)
+ WindowScreenDidChange(uint64_t displayID)
+
+ ScalePage(double scale, WebCore::IntPoint origin)
+
+ SetUseFixedLayout(bool fixed)
+ SetFixedLayoutSize(WebCore::IntSize size)
+
+ SetPaginationMode(uint32_t mode);
+ SetPageLength(double pageLength);
+ SetGapBetweenPages(double gap);
+
+ # Find.
+ FindString(WTF::String string, uint32_t findOptions, unsigned maxMatchCount)
+ HideFindUI()
+ CountStringMatches(WTF::String string, uint32_t findOptions, unsigned maxMatchCount)
+
+ # Drag and drop.
+#if PLATFORM(WIN)
+ PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, HashMap<UINT,Vector<String>> dataMap, uint32_t flags)
+#endif
+#if PLATFORM(QT) || PLATFORM(GTK)
+ PerformDragControllerAction(uint64_t action, WebCore::DragData dragData)
+#endif
+#if !PLATFORM(WIN) && !PLATFORM(QT) && !PLATFORM(GTK)
+ PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, WTF::String dragStorageName, uint32_t flags, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+#endif
+ DragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
+
+ # Popup menu.
+ DidChangeSelectedIndexForActivePopupMenu(int32_t newIndex);
+ SetTextForActivePopupMenu(int32_t index);
+#if PLATFORM(GTK)
+ FailedToShowPopupMenu();
+#endif
+
+ # Context menu.
+ DidSelectItemFromActiveContextMenu(WebKit::WebContextMenuItemData menuItem);
+
+ # Open panel.
+ DidChooseFilesForOpenPanel(Vector<WTF::String> fileURLs)
+ DidCancelForOpenPanel()
+#if ENABLE(WEB_PROCESS_SANDBOX)
+ ExtendSandboxForFileFromOpenPanel(WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+#endif
+
+ # Spelling and grammar.
+ AdvanceToNextMisspelling(bool startBeforeSelection)
+ ChangeSpellingToWord(WTF::String word)
+#if PLATFORM(MAC)
+ UppercaseWord();
+ LowercaseWord();
+ CapitalizeWord();
+
+ SetSmartInsertDeleteEnabled(bool isSmartInsertDeleteEnabled);
+#endif
+
+ # Geolocation
+ DidReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
+
+ # Notification
+ DidReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)
+
+ SetWindowResizerSize(WebCore::IntSize intersectsView)
+
+ # Printing.
+ BeginPrinting(uint64_t frameID, WebKit::PrintInfo printInfo)
+ EndPrinting();
+ ComputePagesForPrinting(uint64_t frameID, WebKit::PrintInfo printInfo, uint64_t callbackID)
+#if PLATFORM(MAC) || PLATFORM(WIN)
+ DrawRectToPDF(uint64_t frameID, WebKit::PrintInfo printInfo, WebCore::IntRect rect, uint64_t callbackID)
+ DrawPagesToPDF(uint64_t frameID, WebKit::PrintInfo printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
+#endif
+
+ SetMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled)
+
+ // 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.
+ Dummy() -> (bool dummyReturn)
+
+ SetCanRunBeforeUnloadConfirmPanel(bool canRunBeforeUnloadConfirmPanel)
+ SetCanRunModal(bool canRunModal)
+
+#if PLATFORM(QT)
+ SetComposition(WTF::String text, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd)
+ ConfirmComposition(WTF::String text, int64_t selectionStart, int64_t selectionLength)
+ CancelComposition()
+#endif
+
+#if PLATFORM(MAC)
+ # Complex text input support for plug-ins.
+ SendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, String textInput)
+
+ SetWindowIsVisible(bool windowIsVisible)
+ WindowAndViewFramesChanged(WebCore::IntRect windowFrameInScreenCoordinates, WebCore::IntRect viewFrameInWindowCoordinates, WebCore::IntPoint accessibilityViewCoordinates)
+ RegisterUIProcessAccessibilityTokens(CoreIPC::DataReference elemenToken, CoreIPC::DataReference windowToken)
+ WriteSelectionToPasteboard(WTF::String pasteboardName, WTF::Vector<WTF::String> pasteboardTypes) -> (bool result)
+ ReadSelectionFromPasteboard(WTF::String pasteboardName) -> (bool result)
+
+ # Text input.
+ SetComposition(WTF::String text, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) -> (WebKit::EditorState newState)
+ ConfirmComposition() -> (WebKit::EditorState newState)
+ CancelComposition() -> (WebKit::EditorState newState)
+ InsertText(WTF::String text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) -> (bool handled, 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)
+ ShouldDelayWindowOrderingEvent(WebKit::WebMouseEvent event) -> (bool result)
+ AcceptsFirstMouse(int eventNumber, WebKit::WebMouseEvent event) -> (bool result)
+#endif
+#if PLATFORM(WIN)
+ // FIXME: Unify with Mac counterparts.
+ ConfirmComposition(WTF::String compositionString)
+ SetComposition(WTF::String compositionString, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t cursorPosition)
+ FirstRectForCharacterInSelectedRange(uint64_t characterPosition) -> (WebCore::IntRect resultRect)
+ GetSelectedText() -> (WTF::String text)
+
+ GestureWillBegin(WebCore::IntPoint point) -> (bool canBeginPanning)
+ GestureDidScroll(WebCore::IntSize size)
+ GestureDidEnd()
+#endif
+#if PLATFORM(QT)
+ FindZoomableAreaForPoint(WebCore::IntPoint point)
+#endif
+
+#if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
+ HandleCorrectionPanelResult(String result)
+#endif
+}
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp
new file mode 100644
index 000000000..3bd20c8a6
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "WebPageGroupProxy.h"
+
+#include "WebProcess.h"
+#include "InjectedBundle.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());
+
+ return pageGroup.release();
+}
+
+WebPageGroupProxy::~WebPageGroupProxy()
+{
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h
new file mode 100644
index 000000000..91e6c5cfd
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h
@@ -0,0 +1,60 @@
+/*
+ * 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 WebPageGroupProxy_h
+#define WebPageGroupProxy_h
+
+#include "APIObject.h"
+#include "WebPageGroupData.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebKit {
+
+class WebPageGroupProxy : public APIObject {
+public:
+ static const Type APIType = TypeBundlePageGroup;
+
+ static PassRefPtr<WebPageGroupProxy> create(const WebPageGroupData&);
+ virtual ~WebPageGroupProxy();
+
+ const String& identifier() const { return m_data.identifer; }
+ uint64_t pageGroupID() const { return m_data.pageGroupID; }
+ bool isVisibleToInjectedBundle() const { return m_data.visibleToInjectedBundle; }
+ bool isVisibleToHistoryClient() const { return m_data.visibleToHistoryClient; }
+
+private:
+ WebPageGroupProxy(const WebPageGroupData& data)
+ : m_data(data)
+ {
+ }
+
+ virtual Type type() const { return APIType; }
+
+ WebPageGroupData m_data;
+};
+
+} // namespace WebKit
+
+#endif // WebPageGroupProxy_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp
new file mode 100644
index 000000000..7b41c5aa6
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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 "WebUndoStep.h"
+
+namespace WebKit {
+
+static uint64_t generateUndoStep()
+{
+ static uint64_t uniqueEntryID = 1;
+ return uniqueEntryID++;
+}
+
+PassRefPtr<WebUndoStep> WebUndoStep::create(PassRefPtr<WebCore::UndoStep> step)
+{
+ return adoptRef(new WebUndoStep(step, generateUndoStep()));
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/WebUndoStep.h b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.h
new file mode 100644
index 000000000..745377a3c
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.h
@@ -0,0 +1,55 @@
+/*
+ * 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 WebUndoStep_h
+#define WebUndoStep_h
+
+#include <WebCore/UndoStep.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebKit {
+
+class WebUndoStep : public RefCounted<WebUndoStep> {
+public:
+ static PassRefPtr<WebUndoStep> create(PassRefPtr<WebCore::UndoStep>);
+
+ WebCore::UndoStep* step() const { return m_step.get(); }
+ uint64_t stepID() const { return m_stepID; }
+
+private:
+ WebUndoStep(PassRefPtr<WebCore::UndoStep> step, uint64_t stepID)
+ : m_step(step)
+ , m_stepID(stepID)
+ {
+ }
+
+ RefPtr<WebCore::UndoStep> m_step;
+ uint64_t m_stepID;
+};
+
+} // namespace WebKit
+
+#endif // WebEditCommand_h
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp
new file mode 100644
index 000000000..8b135fd06
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp
@@ -0,0 +1,278 @@
+/*
+ * 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 "LayerTreeHostCA.h"
+
+#include "DrawingAreaImpl.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/GraphicsLayerCA.h>
+#include <WebCore/Page.h>
+#include <WebCore/PlatformCALayer.h>
+#include <WebCore/Settings.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage)
+ : LayerTreeHost(webPage)
+ , m_layerFlushSchedulingEnabled(true)
+ , m_isValid(true)
+ , m_notifyAfterScheduledLayerFlush(false)
+{
+}
+
+void LayerTreeHostCA::initialize()
+{
+ // Create a root layer.
+ m_rootLayer = GraphicsLayer::create(this);
+#ifndef NDEBUG
+ m_rootLayer->setName("LayerTreeHost root layer");
+#endif
+ m_rootLayer->setDrawsContent(false);
+ m_rootLayer->setSize(m_webPage->size());
+ static_cast<GraphicsLayerCA*>(m_rootLayer.get())->platformCALayer()->setGeometryFlipped(true);
+
+ m_nonCompositedContentLayer = GraphicsLayer::create(this);
+ static_cast<GraphicsLayerCA*>(m_nonCompositedContentLayer.get())->setAllowTiledLayer(false);
+#ifndef NDEBUG
+ m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content");
+#endif
+ 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->setAcceleratesDrawing(true);
+
+ m_rootLayer->addChild(m_nonCompositedContentLayer.get());
+
+ if (m_webPage->hasPageOverlay())
+ createPageOverlayLayer();
+
+ platformInitialize(m_layerTreeContext);
+
+ setLayerFlushSchedulingEnabled(!m_webPage->drawingArea() || !m_webPage->drawingArea()->layerTreeStateIsFrozen());
+ scheduleLayerFlush();
+}
+
+LayerTreeHostCA::~LayerTreeHostCA()
+{
+ ASSERT(!m_isValid);
+ ASSERT(!m_rootLayer);
+}
+
+const LayerTreeContext& LayerTreeHostCA::layerTreeContext()
+{
+ return m_layerTreeContext;
+}
+
+void LayerTreeHostCA::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
+{
+ m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
+}
+
+void LayerTreeHostCA::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
+{
+ m_nonCompositedContentLayer->removeAllChildren();
+
+ // Add the accelerated layer tree hierarchy.
+ if (graphicsLayer)
+ m_nonCompositedContentLayer->addChild(graphicsLayer);
+}
+
+void LayerTreeHostCA::invalidate()
+{
+ ASSERT(m_isValid);
+ m_rootLayer = nullptr;
+ m_isValid = false;
+}
+
+void LayerTreeHostCA::setNonCompositedContentsNeedDisplay(const IntRect& rect)
+{
+ m_nonCompositedContentLayer->setNeedsDisplayInRect(rect);
+ if (m_pageOverlayLayer)
+ m_pageOverlayLayer->setNeedsDisplayInRect(rect);
+
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostCA::scrollNonCompositedContents(const IntRect& scrollRect, const IntSize& scrollOffset)
+{
+ setNonCompositedContentsNeedDisplay(scrollRect);
+}
+
+void LayerTreeHostCA::sizeDidChange(const IntSize& newSize)
+{
+ m_rootLayer->setSize(newSize);
+
+ // If the newSize exposes new areas of the non-composited content a setNeedsDisplay is needed
+ // for those newly exposed areas.
+ FloatSize oldSize = m_nonCompositedContentLayer->size();
+ m_nonCompositedContentLayer->setSize(newSize);
+
+ if (newSize.width() > oldSize.width()) {
+ float height = std::min(static_cast<float>(newSize.height()), oldSize.height());
+ m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(oldSize.width(), 0, newSize.width() - oldSize.width(), height));
+ }
+
+ if (newSize.height() > oldSize.height())
+ m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(0, oldSize.height(), newSize.width(), newSize.height() - oldSize.height()));
+
+ if (m_pageOverlayLayer)
+ m_pageOverlayLayer->setSize(newSize);
+
+ scheduleLayerFlush();
+ flushPendingLayerChanges();
+}
+
+void LayerTreeHostCA::deviceScaleFactorDidChange()
+{
+ // Other layers learn of the scale factor change via WebPage::setDeviceScaleFactor.
+ m_nonCompositedContentLayer->deviceOrPageScaleFactorChanged();
+}
+
+void LayerTreeHostCA::forceRepaint()
+{
+ scheduleLayerFlush();
+ flushPendingLayerChanges();
+}
+
+void LayerTreeHostCA::didInstallPageOverlay()
+{
+ createPageOverlayLayer();
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostCA::didUninstallPageOverlay()
+{
+ destroyPageOverlayLayer();
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostCA::setPageOverlayNeedsDisplay(const IntRect& rect)
+{
+ ASSERT(m_pageOverlayLayer);
+ m_pageOverlayLayer->setNeedsDisplayInRect(rect);
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostCA::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
+{
+}
+
+void LayerTreeHostCA::notifySyncRequired(const WebCore::GraphicsLayer*)
+{
+}
+
+void LayerTreeHostCA::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& clipRect)
+{
+ if (graphicsLayer == m_nonCompositedContentLayer) {
+ m_webPage->drawRect(graphicsContext, clipRect);
+ return;
+ }
+
+ if (graphicsLayer == m_pageOverlayLayer) {
+ m_webPage->drawPageOverlay(graphicsContext, clipRect);
+ return;
+ }
+}
+
+bool LayerTreeHostCA::showDebugBorders() const
+{
+ return m_webPage->corePage()->settings()->showDebugBorders();
+}
+
+bool LayerTreeHostCA::showRepaintCounter() const
+{
+ return m_webPage->corePage()->settings()->showRepaintCounter();
+}
+
+float LayerTreeHostCA::deviceScaleFactor() const
+{
+ return m_webPage->corePage()->deviceScaleFactor();
+}
+
+void LayerTreeHostCA::performScheduledLayerFlush()
+{
+ {
+ RefPtr<LayerTreeHostCA> protect(this);
+ m_webPage->layoutIfNeeded();
+
+ if (!m_isValid)
+ return;
+ }
+
+ if (!flushPendingLayerChanges())
+ return;
+
+ didPerformScheduledLayerFlush();
+}
+
+void LayerTreeHostCA::didPerformScheduledLayerFlush()
+{
+ 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_notifyAfterScheduledLayerFlush = false;
+ }
+}
+
+bool LayerTreeHostCA::flushPendingLayerChanges()
+{
+ m_rootLayer->syncCompositingStateForThisLayerOnly();
+ m_nonCompositedContentLayer->syncCompositingStateForThisLayerOnly();
+ if (m_pageOverlayLayer)
+ m_pageOverlayLayer->syncCompositingStateForThisLayerOnly();
+
+ return m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes();
+}
+
+void LayerTreeHostCA::createPageOverlayLayer()
+{
+ ASSERT(!m_pageOverlayLayer);
+
+ m_pageOverlayLayer = GraphicsLayer::create(this);
+#ifndef NDEBUG
+ m_pageOverlayLayer->setName("LayerTreeHost page overlay content");
+#endif
+
+ m_pageOverlayLayer->setDrawsContent(true);
+ m_pageOverlayLayer->setSize(m_webPage->size());
+
+ m_rootLayer->addChild(m_pageOverlayLayer.get());
+}
+
+void LayerTreeHostCA::destroyPageOverlayLayer()
+{
+ ASSERT(m_pageOverlayLayer);
+ m_pageOverlayLayer->removeFromParent();
+ m_pageOverlayLayer = nullptr;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h
new file mode 100644
index 000000000..0566e9733
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+#ifndef LayerTreeHostCA_h
+#define LayerTreeHostCA_h
+
+#include "LayerTreeContext.h"
+#include "LayerTreeHost.h"
+#include <WebCore/GraphicsLayerClient.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebKit {
+
+class LayerTreeHostCA : public LayerTreeHost, WebCore::GraphicsLayerClient {
+public:
+ virtual ~LayerTreeHostCA();
+
+protected:
+ explicit LayerTreeHostCA(WebPage*);
+
+ WebCore::GraphicsLayer* rootLayer() const { return m_rootLayer.get(); }
+
+ void initialize();
+ void performScheduledLayerFlush();
+
+ // LayerTreeHost.
+ virtual void invalidate();
+ virtual void sizeDidChange(const WebCore::IntSize& newSize);
+ virtual void deviceScaleFactorDidChange();
+ virtual void forceRepaint();
+ virtual void setRootCompositingLayer(WebCore::GraphicsLayer*);
+
+ // LayerTreeHostCA
+ virtual void didPerformScheduledLayerFlush();
+
+ bool m_layerFlushSchedulingEnabled;
+
+private:
+ // LayerTreeHost.
+ virtual const LayerTreeContext& layerTreeContext();
+ virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool);
+
+ virtual void setNonCompositedContentsNeedDisplay(const WebCore::IntRect&);
+ virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset);
+
+ virtual void didInstallPageOverlay();
+ virtual void didUninstallPageOverlay();
+ virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&);
+
+ // GraphicsLayerClient
+ virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double time);
+ virtual void notifySyncRequired(const WebCore::GraphicsLayer*);
+ virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect);
+ virtual bool showDebugBorders() const;
+ virtual bool showRepaintCounter() const;
+ virtual float deviceScaleFactor() const;
+ virtual void didCommitChangesForLayer(const WebCore::GraphicsLayer*) const { }
+
+ // LayerTreeHostCA
+ virtual void platformInitialize(LayerTreeContext&) = 0;
+
+ bool flushPendingLayerChanges();
+
+ void createPageOverlayLayer();
+ void destroyPageOverlayLayer();
+
+ // The context for this layer tree.
+ LayerTreeContext m_layerTreeContext;
+
+ // Whether the layer tree host is valid or not.
+ bool m_isValid;
+
+ // Whether we should let the drawing area know the next time we've flushed
+ // layer tree changes.
+ bool m_notifyAfterScheduledLayerFlush;
+
+ // The root layer.
+ OwnPtr<WebCore::GraphicsLayer> m_rootLayer;
+
+ // The layer which contains all non-composited content.
+ OwnPtr<WebCore::GraphicsLayer> m_nonCompositedContentLayer;
+
+ // The page overlay layer. Will be null if there's no page overlay.
+ OwnPtr<WebCore::GraphicsLayer> m_pageOverlayLayer;
+};
+
+} // namespace WebKit
+
+#endif // LayerTreeHostCA_h
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h
new file mode 100644
index 000000000..06759e25d
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#ifndef LayerTreeHostCAMac_h
+#define LayerTreeHostCAMac_h
+
+#include "LayerTreeHostCA.h"
+#include <WebCore/LayerFlushScheduler.h>
+#include <WebCore/LayerFlushSchedulerClient.h>
+#include <wtf/RetainPtr.h>
+
+typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef;
+
+namespace WebKit {
+
+class LayerTreeHostCAMac : public LayerTreeHostCA, public WebCore::LayerFlushSchedulerClient {
+public:
+ static PassRefPtr<LayerTreeHostCAMac> create(WebPage*);
+ virtual ~LayerTreeHostCAMac();
+
+private:
+ explicit LayerTreeHostCAMac(WebPage*);
+
+ // LayerTreeHost.
+ virtual void scheduleLayerFlush();
+ virtual void setLayerFlushSchedulingEnabled(bool);
+ virtual void invalidate();
+ virtual void sizeDidChange(const WebCore::IntSize& newSize);
+ virtual void forceRepaint();
+ virtual void pauseRendering();
+ virtual void resumeRendering();
+
+ // LayerTreeHostCA
+ virtual void platformInitialize(LayerTreeContext&);
+ virtual void didPerformScheduledLayerFlush();
+
+ // LayerFlushSchedulerClient
+ virtual bool flushLayers();
+
+ RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient;
+ WebCore::LayerFlushScheduler m_layerFlushScheduler;
+};
+
+} // namespace WebKit
+
+#endif // LayerTreeHostCAMac_h
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm
new file mode 100644
index 000000000..5ff8ad13b
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+#import "config.h"
+#import "LayerTreeHostCAMac.h"
+
+#import "WebProcess.h"
+#import <QuartzCore/CATransaction.h>
+#import <WebCore/GraphicsLayer.h>
+#import <WebKitSystemInterface.h>
+
+using namespace WebCore;
+
+@interface CATransaction (Details)
++ (void)synchronize;
+@end
+
+namespace WebKit {
+
+PassRefPtr<LayerTreeHostCAMac> LayerTreeHostCAMac::create(WebPage* webPage)
+{
+ RefPtr<LayerTreeHostCAMac> host = adoptRef(new LayerTreeHostCAMac(webPage));
+ host->initialize();
+ return host.release();
+}
+
+LayerTreeHostCAMac::LayerTreeHostCAMac(WebPage* webPage)
+ : LayerTreeHostCA(webPage)
+ , m_layerFlushScheduler(this)
+{
+}
+
+LayerTreeHostCAMac::~LayerTreeHostCAMac()
+{
+ ASSERT(!m_remoteLayerClient);
+}
+
+void LayerTreeHostCAMac::platformInitialize(LayerTreeContext& layerTreeContext)
+{
+ mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort();
+ m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort);
+
+ WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), rootLayer()->platformLayer());
+
+ layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get());
+}
+
+void LayerTreeHostCAMac::scheduleLayerFlush()
+{
+ m_layerFlushScheduler.schedule();
+}
+
+void LayerTreeHostCAMac::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
+{
+ if (layerFlushingEnabled)
+ m_layerFlushScheduler.resume();
+ else
+ m_layerFlushScheduler.suspend();
+}
+
+void LayerTreeHostCAMac::invalidate()
+{
+ m_layerFlushScheduler.invalidate();
+
+ WKCARemoteLayerClientInvalidate(m_remoteLayerClient.get());
+ m_remoteLayerClient = nullptr;
+
+ LayerTreeHostCA::invalidate();
+}
+
+void LayerTreeHostCAMac::sizeDidChange(const IntSize& newSize)
+{
+ LayerTreeHostCA::sizeDidChange(newSize);
+ [CATransaction flush];
+ [CATransaction synchronize];
+}
+
+void LayerTreeHostCAMac::forceRepaint()
+{
+ LayerTreeHostCA::forceRepaint();
+ [CATransaction flush];
+ [CATransaction synchronize];
+}
+
+void LayerTreeHostCAMac::pauseRendering()
+{
+ CALayer* root = rootLayer()->platformLayer();
+ [root setValue:(id)kCFBooleanTrue forKey:@"NSCAViewRenderPaused"];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidPauseNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:root forKey:@"layer"]];
+}
+
+void LayerTreeHostCAMac::resumeRendering()
+{
+ CALayer* root = rootLayer()->platformLayer();
+ [root setValue:(id)kCFBooleanFalse forKey:@"NSCAViewRenderPaused"];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidResumeNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:root forKey:@"layer"]];
+}
+
+bool LayerTreeHostCAMac::flushLayers()
+{
+ // This gets called outside of the normal event loop so wrap in an autorelease pool
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ performScheduledLayerFlush();
+ [pool drain];
+
+ return true;
+}
+
+void LayerTreeHostCAMac::didPerformScheduledLayerFlush()
+{
+ LayerTreeHostCA::didPerformScheduledLayerFlush();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp
new file mode 100644
index 000000000..ef3c16a11
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp
@@ -0,0 +1,263 @@
+/*
+ * 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 "LayerTreeHostCAWin.h"
+
+#if HAVE(WKQCA)
+
+#include "DrawingAreaImpl.h"
+#include "ShareableBitmap.h"
+#include "UpdateInfo.h"
+#include "WKCACFViewWindow.h"
+#include "WebPage.h"
+#include <WebCore/GraphicsLayerCA.h>
+#include <WebCore/LayerChangesFlusher.h>
+#include <WebCore/PlatformCALayer.h>
+#include <WebCore/WebCoreInstanceHandle.h>
+#include <WebKitQuartzCoreAdditions/WKCACFImage.h>
+#include <WebKitQuartzCoreAdditions/WKCACFView.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/MainThread.h>
+
+#ifdef DEBUG_ALL
+#pragma comment(lib, "WebKitQuartzCoreAdditions_debug")
+#else
+#pragma comment(lib, "WebKitQuartzCoreAdditions")
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+bool LayerTreeHostCAWin::supportsAcceleratedCompositing()
+{
+ static bool initialized;
+ static bool supportsAcceleratedCompositing;
+ if (initialized)
+ return supportsAcceleratedCompositing;
+ initialized = true;
+
+ RetainPtr<WKCACFViewRef> view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow));
+ WKCACFViewWindow dummyWindow(view.get(), 0, 0);
+ CGRect fakeBounds = CGRectMake(0, 0, 10, 10);
+ WKCACFViewUpdate(view.get(), dummyWindow.window(), &fakeBounds);
+
+ supportsAcceleratedCompositing = WKCACFViewCanDraw(view.get());
+
+ WKCACFViewUpdate(view.get(), 0, 0);
+
+ return supportsAcceleratedCompositing;
+}
+
+PassRefPtr<LayerTreeHostCAWin> LayerTreeHostCAWin::create(WebPage* webPage)
+{
+ RefPtr<LayerTreeHostCAWin> host = adoptRef(new LayerTreeHostCAWin(webPage));
+ host->initialize();
+ return host.release();
+}
+
+LayerTreeHostCAWin::LayerTreeHostCAWin(WebPage* webPage)
+ : LayerTreeHostCA(webPage)
+ , m_isFlushingLayerChanges(false)
+{
+}
+
+LayerTreeHostCAWin::~LayerTreeHostCAWin()
+{
+}
+
+void LayerTreeHostCAWin::platformInitialize(LayerTreeContext& context)
+{
+ m_view.adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow));
+ WKCACFViewSetContextUserData(m_view.get(), static_cast<AbstractCACFLayerTreeHost*>(this));
+ WKCACFViewSetLayer(m_view.get(), rootLayer()->platformLayer());
+ WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this);
+
+ // Passing WS_DISABLED makes the window invisible to mouse events, which lets WKView's normal
+ // event handling mechanism work even when this window is obscuring the entire WKView HWND.
+ // Note that m_webPage->nativeWindow() is owned by the UI process, so this creates a cross-
+ // process window hierarchy (and thus implicitly attaches the input queues of the UI and web
+ // processes' main threads).
+ m_window = adoptPtr(new WKCACFViewWindow(m_view.get(), m_webPage->nativeWindow(), WS_DISABLED));
+
+ CGRect bounds = m_webPage->bounds();
+ WKCACFViewUpdate(m_view.get(), m_window->window(), &bounds);
+
+ context.window = m_window->window();
+}
+
+void LayerTreeHostCAWin::invalidate()
+{
+ LayerChangesFlusher::shared().cancelPendingFlush(this);
+
+ WKCACFViewSetContextUserData(m_view.get(), 0);
+ WKCACFViewSetLayer(m_view.get(), 0);
+ WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0);
+
+ // The UI process will destroy m_window's HWND when it gets the message to switch out of
+ // accelerated compositing mode. We don't want to destroy the HWND before then or we will get a
+ // flash of white before the UI process has a chance to display the non-composited content.
+ // Since the HWND needs to outlive us, we leak m_window here and tell it to clean itself up
+ // when its HWND is destroyed.
+ WKCACFViewWindow* window = m_window.leakPtr();
+ window->setDeletesSelfWhenWindowDestroyed(true);
+
+ LayerTreeHostCA::invalidate();
+}
+
+void LayerTreeHostCAWin::scheduleLayerFlush()
+{
+ if (!m_layerFlushSchedulingEnabled)
+ return;
+
+ LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this);
+}
+
+void LayerTreeHostCAWin::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
+{
+ if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
+ return;
+
+ m_layerFlushSchedulingEnabled = layerFlushingEnabled;
+
+ if (m_layerFlushSchedulingEnabled) {
+ scheduleLayerFlush();
+ return;
+ }
+
+ LayerChangesFlusher::shared().cancelPendingFlush(this);
+}
+
+void LayerTreeHostCAWin::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry)
+{
+ m_geometriesUpdater.addPendingUpdate(geometry);
+}
+
+void LayerTreeHostCAWin::sizeDidChange(const IntSize& newSize)
+{
+ LayerTreeHostCA::sizeDidChange(newSize);
+ CGRect bounds = CGRectMake(0, 0, newSize.width(), newSize.height());
+ WKCACFViewUpdate(m_view.get(), m_window->window(), &bounds);
+ WKCACFViewFlushContext(m_view.get());
+}
+
+void LayerTreeHostCAWin::forceRepaint()
+{
+ LayerTreeHostCA::forceRepaint();
+ WKCACFViewFlushContext(m_view.get());
+}
+
+void LayerTreeHostCAWin::contextDidChangeCallback(WKCACFViewRef view, void* info)
+{
+ // This should only be called on a background thread when no changes have actually
+ // been committed to the context, eg. when a video frame has been added to an image
+ // queue, so return without triggering animations etc.
+ if (!isMainThread())
+ return;
+
+ LayerTreeHostCAWin* host = static_cast<LayerTreeHostCAWin*>(info);
+ ASSERT_ARG(view, view == host->m_view);
+ host->contextDidChange();
+}
+
+void LayerTreeHostCAWin::contextDidChange()
+{
+ // Send currentTime to the pending animations. This function is called by CACF in a callback
+ // which occurs after the drawInContext calls. So currentTime is very close to the time
+ // the animations actually start
+ double currentTime = WTF::currentTime();
+
+ HashSet<RefPtr<PlatformCALayer> >::iterator end = m_pendingAnimatedLayers.end();
+ for (HashSet<RefPtr<PlatformCALayer> >::iterator it = m_pendingAnimatedLayers.begin(); it != end; ++it)
+ (*it)->animationStarted(currentTime);
+
+ m_pendingAnimatedLayers.clear();
+
+ // Update child window geometries now so that they stay mostly in sync with the accelerated content.
+ // FIXME: We should really be doing this when the changes we just flushed appear on screen. <http://webkit.org/b/61867>
+ // We also bring the child windows (i.e., plugins) to the top of the z-order to ensure they are above m_window.
+ // FIXME: We could do this just once per window when it is first shown. Maybe that would be more efficient?
+ m_geometriesUpdater.updateGeometries(BringToTop);
+}
+
+PlatformCALayer* LayerTreeHostCAWin::rootLayer() const
+{
+ return static_cast<GraphicsLayerCA*>(LayerTreeHostCA::rootLayer())->platformCALayer();
+}
+
+void LayerTreeHostCAWin::addPendingAnimatedLayer(PassRefPtr<PlatformCALayer> layer)
+{
+ m_pendingAnimatedLayers.add(layer);
+}
+
+void LayerTreeHostCAWin::layerTreeDidChange()
+{
+ if (m_isFlushingLayerChanges) {
+ // The layer tree is changing as a result of flushing GraphicsLayer changes to their
+ // underlying PlatformCALayers. We'll flush those changes to the context as part of that
+ // process, so there's no need to schedule another flush here.
+ return;
+ }
+
+ // The layer tree is changing as a result of someone modifying a PlatformCALayer that doesn't
+ // have a corresponding GraphicsLayer. Schedule a flush since we won't schedule one through the
+ // normal GraphicsLayer mechanisms.
+ LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this);
+}
+
+void LayerTreeHostCAWin::flushPendingLayerChangesNow()
+{
+ RefPtr<LayerTreeHostCA> protector(this);
+
+ m_isFlushingLayerChanges = true;
+
+ // Flush changes stored up in GraphicsLayers to their underlying PlatformCALayers, if
+ // requested.
+ performScheduledLayerFlush();
+
+ // Flush changes stored up in PlatformCALayers to the context so they will be rendered.
+ WKCACFViewFlushContext(m_view.get());
+
+ m_isFlushingLayerChanges = false;
+}
+
+void LayerTreeHostCAWin::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
+{
+ // Don't flush any changes when we don't have a root layer. This will prevent flashes of white
+ // when switching out of compositing mode.
+ setLayerFlushSchedulingEnabled(graphicsLayer);
+
+ // Resubmit all existing animations. CACF does not remember running animations
+ // When the layer tree is removed and then added back to the hierarchy
+ if (graphicsLayer)
+ static_cast<GraphicsLayerCA*>(graphicsLayer)->platformCALayer()->ensureAnimationsSubmitted();
+
+ LayerTreeHostCA::setRootCompositingLayer(graphicsLayer);
+}
+
+} // namespace WebKit
+
+#endif // HAVE(WKQCA)
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h
new file mode 100644
index 000000000..d9d59678a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef LayerTreeHostCAWin_h
+#define LayerTreeHostCAWin_h
+
+#include "HeaderDetection.h"
+
+#if HAVE(WKQCA)
+
+#include "CoalescedWindowGeometriesUpdater.h"
+#include "LayerTreeHostCA.h"
+#include <WebCore/AbstractCACFLayerTreeHost.h>
+#include <wtf/HashSet.h>
+#include <wtf/RetainPtr.h>
+
+typedef struct _WKCACFView* WKCACFViewRef;
+
+namespace WebKit {
+
+class WKCACFViewWindow;
+
+class LayerTreeHostCAWin : public LayerTreeHostCA, private WebCore::AbstractCACFLayerTreeHost {
+public:
+ static bool supportsAcceleratedCompositing();
+
+ static PassRefPtr<LayerTreeHostCAWin> create(WebPage*);
+ virtual ~LayerTreeHostCAWin();
+
+private:
+ explicit LayerTreeHostCAWin(WebPage*);
+
+ static void contextDidChangeCallback(WKCACFViewRef, void* info);
+ void contextDidChange();
+
+ // LayerTreeHost
+ virtual void invalidate();
+ virtual void forceRepaint();
+ virtual void sizeDidChange(const WebCore::IntSize& newSize);
+ virtual void scheduleLayerFlush();
+ virtual void setLayerFlushSchedulingEnabled(bool);
+ virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&);
+
+ // LayerTreeHostCA
+ virtual void platformInitialize(LayerTreeContext&);
+ virtual void setRootCompositingLayer(WebCore::GraphicsLayer*);
+
+ // AbstractCACFLayerTreeHost
+ virtual WebCore::PlatformCALayer* rootLayer() const;
+ virtual void addPendingAnimatedLayer(PassRefPtr<WebCore::PlatformCALayer>);
+ virtual void layerTreeDidChange();
+ virtual void flushPendingLayerChangesNow();
+
+ OwnPtr<WKCACFViewWindow> m_window;
+ RetainPtr<WKCACFViewRef> m_view;
+ HashSet<RefPtr<WebCore::PlatformCALayer> > m_pendingAnimatedLayers;
+ bool m_isFlushingLayerChanges;
+ CoalescedWindowGeometriesUpdater m_geometriesUpdater;
+};
+
+} // namespace WebKit
+
+#endif // HAVE(WKQCA)
+
+#endif // LayerTreeHostCAWin_h
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp b/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp
new file mode 100644
index 000000000..0ce37c449
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp
@@ -0,0 +1,164 @@
+/*
+ * 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 "WKCACFViewWindow.h"
+
+#if HAVE(WKQCA)
+
+#include <WebCore/WebCoreInstanceHandle.h>
+#include <WebKitQuartzCoreAdditions/WKCACFView.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static LPCWSTR windowClassName = L"WKCACFViewWindowClass";
+
+WKCACFViewWindow::WKCACFViewWindow(WKCACFViewRef view, HWND parentWindow, DWORD additionalStyles)
+ : m_window(0)
+ , m_view(view)
+ , m_deletesSelfWhenWindowDestroyed(false)
+{
+ ASSERT_ARG(view, view);
+
+ registerClass();
+
+ UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | additionalStyles;
+ if (parentWindow)
+ style |= WS_CHILD;
+ else
+ style |= WS_POPUP;
+
+ m_window = ::CreateWindowExW(0, windowClassName, L"WKCACFViewWindow", style, 0, 0, 0, 0, parentWindow, 0, instanceHandle(), this);
+ ASSERT_WITH_MESSAGE(m_window, "::CreateWindowExW failed with error %lu", ::GetLastError());
+}
+
+WKCACFViewWindow::~WKCACFViewWindow()
+{
+ if (!m_window)
+ return;
+
+ ASSERT(!m_deletesSelfWhenWindowDestroyed);
+ ::DestroyWindow(m_window);
+}
+
+LRESULT WKCACFViewWindow::onCustomDestroy(WPARAM, LPARAM)
+{
+ ::DestroyWindow(m_window);
+ return 0;
+}
+
+LRESULT WKCACFViewWindow::onDestroy(WPARAM, LPARAM)
+{
+ WKCACFViewUpdate(m_view.get(), 0, 0);
+ return 0;
+}
+
+LRESULT WKCACFViewWindow::onEraseBackground(WPARAM, LPARAM)
+{
+ // Tell Windows not to erase us.
+ return 1;
+}
+
+LRESULT WKCACFViewWindow::onNCDestroy(WPARAM, LPARAM)
+{
+ m_window = 0;
+
+ if (!m_deletesSelfWhenWindowDestroyed)
+ return 0;
+
+ delete this;
+ return 0;
+}
+
+LRESULT WKCACFViewWindow::onPaint(WPARAM, LPARAM)
+{
+ WKCACFViewDraw(m_view.get());
+ ::ValidateRect(m_window, 0);
+ return 0;
+}
+
+LRESULT WKCACFViewWindow::onPrintClient(WPARAM wParam, LPARAM lParam)
+{
+ if (!(lParam & PRF_CLIENT))
+ return 0;
+
+ WKCACFViewDrawIntoDC(m_view.get(), reinterpret_cast<HDC>(wParam));
+ return 0;
+}
+
+void WKCACFViewWindow::registerClass()
+{
+ static bool didRegister;
+ if (didRegister)
+ return;
+ didRegister = true;
+
+ WNDCLASSW wndClass = {0};
+ wndClass.lpfnWndProc = staticWndProc;
+ wndClass.hInstance = instanceHandle();
+ wndClass.lpszClassName = windowClassName;
+
+ ::RegisterClassW(&wndClass);
+}
+
+LRESULT WKCACFViewWindow::staticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ WKCACFViewWindow* window = reinterpret_cast<WKCACFViewWindow*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
+ if (!window) {
+ if (message != WM_CREATE)
+ return ::DefWindowProcW(hWnd, message, wParam, lParam);
+ CREATESTRUCT* createStruct = reinterpret_cast<CREATESTRUCT*>(lParam);
+ window = static_cast<WKCACFViewWindow*>(createStruct->lpCreateParams);
+ ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(window));
+ }
+
+ return window->wndProc(message, wParam, lParam);
+}
+
+LRESULT WKCACFViewWindow::wndProc(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message) {
+ case customDestroyMessage:
+ return onCustomDestroy(wParam, lParam);
+ case WM_DESTROY:
+ return onDestroy(wParam, lParam);
+ case WM_ERASEBKGND:
+ return onEraseBackground(wParam, lParam);
+ case WM_NCDESTROY:
+ return onNCDestroy(wParam, lParam);
+ case WM_PAINT:
+ return onPaint(wParam, lParam);
+ case WM_PRINTCLIENT:
+ return onPrintClient(wParam, lParam);
+ default:
+ return ::DefWindowProcW(m_window, message, wParam, lParam);
+ }
+}
+
+} // namespace WebKit
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h b/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h
new file mode 100644
index 000000000..391146a4c
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef WKCACFViewWindow_h
+#define WKCACFViewWindow_h
+
+#include "HeaderDetection.h"
+
+#if HAVE(WKQCA)
+
+#include <wtf/Noncopyable.h>
+#include <wtf/RetainPtr.h>
+
+typedef struct _WKCACFView* WKCACFViewRef;
+
+namespace WebKit {
+
+// FIXME: Move this class down to WebCore. (Maybe it can even replace some of WKCACFViewLayerTreeHost.)
+class WKCACFViewWindow {
+ WTF_MAKE_NONCOPYABLE(WKCACFViewWindow);
+public:
+ // WKCACFViewWindow will destroy its HWND when this message is received.
+ static const UINT customDestroyMessage = WM_USER + 1;
+
+ WKCACFViewWindow(WKCACFViewRef, HWND parentWindow, DWORD additionalStyles);
+ ~WKCACFViewWindow();
+
+ void setDeletesSelfWhenWindowDestroyed(bool deletes) { m_deletesSelfWhenWindowDestroyed = deletes; }
+
+ HWND window() const { return m_window; }
+
+private:
+ LRESULT onCustomDestroy(WPARAM, LPARAM);
+ LRESULT onDestroy(WPARAM, LPARAM);
+ LRESULT onEraseBackground(WPARAM, LPARAM);
+ LRESULT onNCDestroy(WPARAM, LPARAM);
+ LRESULT onPaint(WPARAM, LPARAM);
+ LRESULT onPrintClient(WPARAM, LPARAM);
+ static void registerClass();
+ static LRESULT CALLBACK staticWndProc(HWND, UINT, WPARAM, LPARAM);
+ LRESULT wndProc(UINT, WPARAM, LPARAM);
+
+ HWND m_window;
+ RetainPtr<WKCACFViewRef> m_view;
+ bool m_deletesSelfWhenWindowDestroyed;
+};
+
+} // namespace WebKit
+
+#endif // HAVE(WKQCA)
+
+#endif // WKCACFViewWindow_h
diff --git a/Source/WebKit2/WebProcess/WebPage/efl/WebInspectorEfl.cpp b/Source/WebKit2/WebProcess/WebPage/efl/WebInspectorEfl.cpp
new file mode 100644
index 000000000..755b4268c
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/efl/WebInspectorEfl.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * 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 "WebInspector.h"
+
+#if ENABLE(INSPECTOR)
+
+#include <WebCore/NotImplemented.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+String WebInspector::localizedStringsURL() const
+{
+ notImplemented();
+ return String();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp
new file mode 100644
index 000000000..669442014
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
+ * Copyright (C) 2011 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"
+
+#include "NotImplemented.h"
+#include "WebEvent.h"
+#include "WindowsKeyboardCodes.h"
+#include <WebCore/FocusController.h>
+#include <WebCore/Frame.h>
+#include <WebCore/KeyboardEvent.h>
+#include <WebCore/Page.h>
+#include <WebCore/PlatformKeyboardEvent.h>
+#include <WebCore/Settings.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void WebPage::platformInitialize()
+{
+ notImplemented();
+}
+
+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)
+{
+ notImplemented();
+ return false;
+}
+
+bool WebPage::platformHasLocalDataForURL(const KURL&)
+{
+ notImplemented();
+ return false;
+}
+
+String WebPage::cachedResponseMIMETypeForURL(const KURL&)
+{
+ notImplemented();
+ return String();
+}
+
+bool WebPage::platformCanHandleRequest(const ResourceRequest&)
+{
+ notImplemented();
+ return true;
+}
+
+String WebPage::cachedSuggestedFilenameForURL(const KURL&)
+{
+ notImplemented();
+ return String();
+}
+
+PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
+{
+ notImplemented();
+ return 0;
+}
+
+const char* WebPage::interpretKeyEvent(const KeyboardEvent* evt)
+{
+ notImplemented();
+ return 0;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/ChunkedUpdateDrawingAreaGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/ChunkedUpdateDrawingAreaGtk.cpp
new file mode 100644
index 000000000..313ad3fe7
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/ChunkedUpdateDrawingAreaGtk.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
+ * Copyright (C) 2011 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 "ChunkedUpdateDrawingArea.h"
+
+#include "RefPtrCairo.h"
+#include "UpdateChunk.h"
+#include "WebPage.h"
+
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/IntRect.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void ChunkedUpdateDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk)
+{
+ ASSERT(!updateChunk->isEmpty());
+
+ RefPtr<cairo_surface_t> image = updateChunk->createImage();
+ RefPtr<cairo_t> cr = cairo_create(image.get());
+ GraphicsContext gc(cr.get());
+ gc.save();
+ IntRect rect = updateChunk->rect();
+ gc.translate(-rect.x(), -rect.y());
+ m_webPage->drawRect(gc, updateChunk->rect());
+ gc.restore();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp
new file mode 100644
index 000000000..e00e437bd
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Portions Copyright (c) 2010 Motorola Mobility, 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 "WebInspector.h"
+
+#if ENABLE(INSPECTOR)
+
+#include <WebCore/NotImplemented.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+String WebInspector::localizedStringsURL() const
+{
+ notImplemented();
+ return String();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp
new file mode 100644
index 000000000..a25e1f7b3
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
+ * Copyright (C) 2011 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"
+
+#include "NotImplemented.h"
+#include "WebEvent.h"
+#include "WindowsKeyboardCodes.h"
+#include <WebCore/FocusController.h>
+#include <WebCore/Frame.h>
+#include <WebCore/KeyboardEvent.h>
+#include <WebCore/Page.h>
+#include <WebCore/PlatformKeyboardEvent.h>
+#include <WebCore/Settings.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void WebPage::platformInitialize()
+{
+ notImplemented();
+}
+
+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->goForward();
+ else
+ m_page->goBack();
+ break;
+ case VK_SPACE:
+ scroll(m_page.get(), keyboardEvent.shiftKey() ? ScrollUp : ScrollDown, ScrollByPage);
+ break;
+ case VK_LEFT:
+ scroll(m_page.get(), ScrollLeft, ScrollByLine);
+ break;
+ case VK_RIGHT:
+ scroll(m_page.get(), ScrollRight, ScrollByLine);
+ break;
+ case VK_UP:
+ scroll(m_page.get(), ScrollUp, ScrollByLine);
+ break;
+ case VK_DOWN:
+ scroll(m_page.get(), ScrollDown, ScrollByLine);
+ break;
+ case VK_HOME:
+ scroll(m_page.get(), ScrollUp, ScrollByDocument);
+ break;
+ case VK_END:
+ scroll(m_page.get(), ScrollDown, ScrollByDocument);
+ break;
+ case VK_PRIOR:
+ scroll(m_page.get(), ScrollUp, ScrollByPage);
+ break;
+ case VK_NEXT:
+ scroll(m_page.get(), ScrollDown, ScrollByPage);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool WebPage::platformHasLocalDataForURL(const KURL&)
+{
+ notImplemented();
+ return false;
+}
+
+String WebPage::cachedResponseMIMETypeForURL(const KURL&)
+{
+ notImplemented();
+ return String();
+}
+
+bool WebPage::platformCanHandleRequest(const ResourceRequest&)
+{
+ notImplemented();
+ return true;
+}
+
+String WebPage::cachedSuggestedFilenameForURL(const KURL&)
+{
+ notImplemented();
+ return String();
+}
+
+PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
+{
+ notImplemented();
+ return 0;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h
new file mode 100644
index 000000000..92620bec2
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#ifndef TiledCoreAnimationDrawingArea_h
+#define TiledCoreAnimationDrawingArea_h
+
+#include "DrawingArea.h"
+#include <WebCore/LayerFlushScheduler.h>
+#include <WebCore/LayerFlushSchedulerClient.h>
+#include <wtf/RetainPtr.h>
+
+OBJC_CLASS CALayer;
+OBJC_CLASS WKContentLayer;
+
+typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef;
+
+namespace WebKit {
+
+class TiledCoreAnimationDrawingArea : public DrawingArea, private WebCore::LayerFlushSchedulerClient {
+public:
+ static PassOwnPtr<TiledCoreAnimationDrawingArea> create(WebPage*, const WebPageCreationParameters&);
+ virtual ~TiledCoreAnimationDrawingArea();
+
+private:
+ TiledCoreAnimationDrawingArea(WebPage*, const WebPageCreationParameters&);
+
+ // DrawingArea
+ virtual void setNeedsDisplay(const WebCore::IntRect&) OVERRIDE;
+ virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) OVERRIDE;
+
+ virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) OVERRIDE;
+ virtual void scheduleCompositingLayerSync() OVERRIDE;
+
+ // WebCore::LayerFlushSchedulerClient
+ virtual bool flushLayers() OVERRIDE;
+
+ // Message handlers.
+ virtual void updateGeometry(const WebCore::IntSize& viewSize) OVERRIDE;
+
+ WebCore::LayerFlushScheduler m_layerFlushScheduler;
+ RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient;
+
+ RetainPtr<CALayer> m_rootLayer;
+};
+
+} // namespace WebKit
+
+#endif // TiledCoreAnimationDrawingArea_h
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm b/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm
new file mode 100644
index 000000000..a1da6bde5
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+#import "config.h"
+#import "TiledCoreAnimationDrawingArea.h"
+
+#import "DrawingAreaProxyMessages.h"
+#import "EventDispatcher.h"
+#import "LayerTreeContext.h"
+#import "WebPage.h"
+#import "WebProcess.h"
+#import <QuartzCore/QuartzCore.h>
+#import <WebCore/Frame.h>
+#import <WebCore/FrameView.h>
+#import <WebCore/GraphicsContext.h>
+#import <WebCore/Page.h>
+#import <WebCore/ScrollingCoordinator.h>
+#import <WebCore/Settings.h>
+#import <WebKitSystemInterface.h>
+
+@interface CATransaction (Details)
++ (void)synchronize;
+@end
+
+using namespace WebCore;
+
+namespace WebKit {
+
+PassOwnPtr<TiledCoreAnimationDrawingArea> TiledCoreAnimationDrawingArea::create(WebPage* webPage, const WebPageCreationParameters& parameters)
+{
+ return adoptPtr(new TiledCoreAnimationDrawingArea(webPage, parameters));
+}
+
+TiledCoreAnimationDrawingArea::TiledCoreAnimationDrawingArea(WebPage* webPage, const WebPageCreationParameters& parameters)
+ : DrawingArea(DrawingAreaTypeTiledCoreAnimation, webPage)
+ , m_layerFlushScheduler(this)
+{
+ Page* page = webPage->corePage();
+
+ // FIXME: It's weird that we're mucking around with the settings here.
+ page->settings()->setForceCompositingMode(true);
+
+#if ENABLE(THREADED_SCROLLING)
+ page->settings()->setScrollingCoordinatorEnabled(true);
+
+ WebProcess::shared().eventDispatcher().addScrollingCoordinatorForPage(webPage);
+#endif
+
+ m_rootLayer = [CALayer layer];
+
+ CGRect rootLayerFrame = m_webPage->bounds();
+ m_rootLayer.get().frame = rootLayerFrame;
+ m_rootLayer.get().opaque = YES;
+ m_rootLayer.get().geometryFlipped = YES;
+
+ mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort();
+ m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort);
+ WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), m_rootLayer.get());
+
+ LayerTreeContext layerTreeContext;
+ layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get());
+ m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(0, layerTreeContext));
+}
+
+TiledCoreAnimationDrawingArea::~TiledCoreAnimationDrawingArea()
+{
+#if ENABLE(THREADED_SCROLLING)
+ WebProcess::shared().eventDispatcher().removeScrollingCoordinatorForPage(m_webPage);
+#endif
+
+ m_layerFlushScheduler.invalidate();
+}
+
+void TiledCoreAnimationDrawingArea::setNeedsDisplay(const IntRect& rect)
+{
+}
+
+void TiledCoreAnimationDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
+{
+}
+
+void TiledCoreAnimationDrawingArea::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
+{
+ if (!graphicsLayer) {
+ m_rootLayer.get().sublayers = nil;
+ return;
+ }
+
+ m_rootLayer.get().sublayers = [NSArray arrayWithObject:graphicsLayer->platformLayer()];
+}
+
+void TiledCoreAnimationDrawingArea::scheduleCompositingLayerSync()
+{
+ m_layerFlushScheduler.schedule();
+ // FIXME: Implement
+}
+
+bool TiledCoreAnimationDrawingArea::flushLayers()
+{
+ // This gets called outside of the normal event loop so wrap in an autorelease pool
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ m_webPage->layoutIfNeeded();
+
+ bool returnValue = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes();
+
+ [pool drain];
+ return returnValue;
+}
+
+
+void TiledCoreAnimationDrawingArea::updateGeometry(const IntSize& viewSize)
+{
+ m_webPage->setSize(viewSize);
+ m_webPage->layoutIfNeeded();
+
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+
+ m_rootLayer.get().frame = CGRectMake(0, 0, viewSize.width(), viewSize.height());
+
+ [CATransaction commit];
+
+ [CATransaction flush];
+ [CATransaction synchronize];
+
+ m_webPage->send(Messages::DrawingAreaProxy::DidUpdateGeometry());
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.h b/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.h
new file mode 100644
index 000000000..2772ad0e1
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef WKAccessibilityWebPageObject_h
+#define WKAccessibilityWebPageObject_h
+
+namespace WebKit {
+class WebPage;
+}
+
+@interface WKAccessibilityWebPageObject : NSObject {
+ WebKit::WebPage* m_page;
+
+ id m_parent;
+ NSArray* m_attributeNames;
+ NSMutableArray* m_accessibilityChildren;
+}
+
+- (void)setWebPage:(WebKit::WebPage*)page;
+
+- (void)setRemoteParent:(id)parent;
+
+@end
+
+#endif // WKAccessibilityWebPageObject_h
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.mm b/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.mm
new file mode 100644
index 000000000..6ed37ea10
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.mm
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+#import "config.h"
+#import "WKAccessibilityWebPageObject.h"
+
+#import "WebFrame.h"
+#import "WebPage.h"
+#import <WebCore/AXObjectCache.h>
+#import <WebCore/Frame.h>
+#import <WebCore/FrameView.h>
+#import <WebCore/Page.h>
+#import <WebCore/ScrollView.h>
+#import <WebCore/Scrollbar.h>
+#import <WebKitSystemInterface.h>
+
+using namespace WebCore;
+using namespace WebKit;
+
+@implementation WKAccessibilityWebPageObject
+
+- (id)accessibilityRootObjectWrapper
+{
+ WebCore::Page* page = m_page->corePage();
+ if (!page)
+ return nil;
+
+ WebCore::Frame* core = page->mainFrame();
+ if (!core || !core->document())
+ return nil;
+
+ AccessibilityObject* root = core->document()->axObjectCache()->rootObject();
+ if (!root)
+ return nil;
+
+ return root->wrapper();
+}
+
+- (void)setWebPage:(WebPage*)page
+{
+ m_page = page;
+}
+
+- (void)setRemoteParent:(id)parent
+{
+ if (parent != m_parent) {
+ [m_parent release];
+ m_parent = [parent retain];
+ }
+}
+
+- (void)dealloc
+{
+ WKUnregisterUniqueIdForElement(self);
+ [m_accessibilityChildren release];
+ [m_attributeNames release];
+ [m_parent release];
+ [super dealloc];
+}
+
+- (BOOL)accessibilityIsIgnored
+{
+ return NO;
+}
+
+- (NSArray *)accessibilityAttributeNames
+{
+ if (!m_attributeNames)
+ m_attributeNames = [[NSArray alloc] initWithObjects:
+ NSAccessibilityRoleAttribute, NSAccessibilityRoleDescriptionAttribute, NSAccessibilityFocusedAttribute,
+ NSAccessibilityParentAttribute, NSAccessibilityWindowAttribute, NSAccessibilityTopLevelUIElementAttribute,
+ NSAccessibilityPositionAttribute, NSAccessibilitySizeAttribute, NSAccessibilityChildrenAttribute, nil];
+
+ return m_attributeNames;
+}
+
+- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute
+{
+ return NO;
+}
+
+- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
+{
+ return;
+}
+
+- (NSArray *)accessibilityActionNames
+{
+ return [NSArray array];
+}
+
+- (NSArray *)accessibilityChildren
+{
+ id wrapper = [self accessibilityRootObjectWrapper];
+ if (!wrapper)
+ return [NSArray array];
+
+ return [NSArray arrayWithObject:wrapper];
+}
+
+- (id)accessibilityAttributeValue:(NSString *)attribute
+{
+ if (!WebCore::AXObjectCache::accessibilityEnabled())
+ WebCore::AXObjectCache::enableAccessibility();
+
+ if ([attribute isEqualToString:NSAccessibilityParentAttribute])
+ return m_parent;
+ if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
+ return [m_parent accessibilityAttributeValue:NSAccessibilityWindowAttribute];
+ if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
+ return [m_parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
+ if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
+ return NSAccessibilityGroupRole;
+ if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute])
+ return NSAccessibilityRoleDescription(NSAccessibilityGroupRole, nil);
+ if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
+ return [NSNumber numberWithBool:NO];
+
+ if (!m_page)
+ return nil;
+
+ if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
+ WebCore::IntPoint point = m_page->accessibilityPosition();
+ return [NSValue valueWithPoint:NSMakePoint(point.x(), point.y())];
+ }
+ if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) {
+ const IntSize& s = m_page->size();
+ return [NSValue valueWithSize:NSMakeSize(s.width(), s.height())];
+ }
+ if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
+ return [self accessibilityChildren];
+
+ return nil;
+}
+
+- (BOOL)accessibilityShouldUseUniqueId
+{
+ return YES;
+}
+
+- (id)accessibilityHitTest:(NSPoint)point
+{
+ // Hit-test point comes in as bottom-screen coordinates. Needs to be normalized to the frame of the web page.
+ NSPoint remotePosition = [[self accessibilityAttributeValue:NSAccessibilityPositionAttribute] pointValue];
+ NSSize remoteSize = [[self accessibilityAttributeValue:NSAccessibilitySizeAttribute] sizeValue];
+
+ // Get the y position of the WKView (we have to screen-flip and go from bottom left to top left).
+ CGFloat screenHeight = [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height;
+ remotePosition.y = (screenHeight - remotePosition.y) - remoteSize.height;
+
+ point.y = screenHeight - point.y;
+
+ // Re-center point into the web page's frame.
+ point.y -= remotePosition.y;
+ point.x -= remotePosition.x;
+
+ WebCore::FrameView* frameView = m_page ? m_page->mainFrameView() : 0;
+ if (frameView) {
+ point.y += frameView->scrollPosition().y();
+ point.x += frameView->scrollPosition().x();
+ }
+
+ return [[self accessibilityRootObjectWrapper] accessibilityHitTest:point];
+}
+
+- (id)accessibilityFocusedUIElement
+{
+ return [[self accessibilityRootObjectWrapper] accessibilityFocusedUIElement];
+}
+
+
+@end
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm
new file mode 100644
index 000000000..d64bf9cf5
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#import "config.h"
+#import "WebInspector.h"
+
+#import <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+static String& globalInspectorLocalizedStringsURL()
+{
+ DEFINE_STATIC_LOCAL(String, inspectorLocalizedStringsURL, ());
+ return inspectorLocalizedStringsURL;
+}
+
+void WebInspector::setLocalizedStringsPath(const String& path)
+{
+ if (!path.isEmpty())
+ globalInspectorLocalizedStringsURL() = [[NSURL fileURLWithPath:path] absoluteString];
+ else
+ globalInspectorLocalizedStringsURL() = String();
+}
+
+String WebInspector::localizedStringsURL() const
+{
+ return globalInspectorLocalizedStringsURL();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm
new file mode 100644
index 000000000..bfee90207
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm
@@ -0,0 +1,710 @@
+/*
+ * Copyright (C) 2010, 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.
+ */
+
+#import "config.h"
+#import "WebPage.h"
+
+#import "AttributedString.h"
+#import "DataReference.h"
+#import "EditorState.h"
+#import "PluginView.h"
+#import "WKAccessibilityWebPageObject.h"
+#import "WebCoreArgumentCoders.h"
+#import "WebEvent.h"
+#import "WebEventConversion.h"
+#import "WebFrame.h"
+#import "WebPageProxyMessages.h"
+#import "WebProcess.h"
+#import <WebCore/AXObjectCache.h>
+#import <WebCore/FocusController.h>
+#import <WebCore/Frame.h>
+#import <WebCore/FrameView.h>
+#import <WebCore/HitTestResult.h>
+#import <WebCore/HTMLConverter.h>
+#import <WebCore/KeyboardEvent.h>
+#import <WebCore/Page.h>
+#import <WebCore/PlatformKeyboardEvent.h>
+#import <WebCore/ResourceHandle.h>
+#import <WebCore/RenderObject.h>
+#import <WebCore/RenderStyle.h>
+#import <WebCore/ScrollView.h>
+#import <WebCore/TextIterator.h>
+#import <WebCore/WindowsKeyboardCodes.h>
+#import <WebCore/visible_units.h>
+#import <WebKitSystemInterface.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static PassRefPtr<Range> convertToRange(Frame*, NSRange);
+
+void WebPage::platformInitialize()
+{
+#if USE(CFNETWORK)
+ m_page->addSchedulePair(SchedulePair::create([[NSRunLoop currentRunLoop] getCFRunLoop], kCFRunLoopCommonModes));
+#else
+ m_page->addSchedulePair(SchedulePair::create([NSRunLoop currentRunLoop], kCFRunLoopCommonModes));
+#endif
+
+ WKAccessibilityWebPageObject* mockAccessibilityElement = [[[WKAccessibilityWebPageObject alloc] init] autorelease];
+
+ // Get the pid for the starting process.
+ pid_t pid = WebProcess::shared().presenterApplicationPid();
+ WKAXInitializeElementWithPresenterPid(mockAccessibilityElement, pid);
+ [mockAccessibilityElement setWebPage:this];
+
+ // send data back over
+ NSData* remoteToken = (NSData *)WKAXRemoteTokenForElement(mockAccessibilityElement);
+ CoreIPC::DataReference dataToken = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>([remoteToken bytes]), [remoteToken length]);
+ send(Messages::WebPageProxy::RegisterWebProcessAccessibilityToken(dataToken));
+ m_mockAccessibilityElement = mockAccessibilityElement;
+}
+
+void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
+{
+}
+
+typedef HashMap<String, String> SelectorNameMap;
+
+// Map selectors into Editor command names.
+// This is not needed for any selectors that have the same name as the Editor command.
+static const SelectorNameMap* createSelectorExceptionMap()
+{
+ SelectorNameMap* map = new HashMap<String, String>;
+
+ map->add("insertNewlineIgnoringFieldEditor:", "InsertNewline");
+ map->add("insertParagraphSeparator:", "InsertNewline");
+ map->add("insertTabIgnoringFieldEditor:", "InsertTab");
+ map->add("pageDown:", "MovePageDown");
+ map->add("pageDownAndModifySelection:", "MovePageDownAndModifySelection");
+ map->add("pageUp:", "MovePageUp");
+ map->add("pageUpAndModifySelection:", "MovePageUpAndModifySelection");
+
+ return map;
+}
+
+static String commandNameForSelectorName(const String& selectorName)
+{
+ // Check the exception map first.
+ static const SelectorNameMap* exceptionMap = createSelectorExceptionMap();
+ SelectorNameMap::const_iterator it = exceptionMap->find(selectorName);
+ if (it != exceptionMap->end())
+ return it->second;
+
+ // Remove the trailing colon.
+ // No need to capitalize the command name since Editor command names are not case sensitive.
+ size_t selectorNameLength = selectorName.length();
+ if (selectorNameLength < 2 || selectorName[selectorNameLength - 1] != ':')
+ return String();
+ return selectorName.left(selectorNameLength - 1);
+}
+
+static Frame* frameForEvent(KeyboardEvent* event)
+{
+ Node* node = event->target()->toNode();
+ ASSERT(node);
+ Frame* frame = node->document()->frame();
+ ASSERT(frame);
+ return frame;
+}
+
+bool WebPage::executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>& commands, KeyboardEvent* event)
+{
+ Frame* frame = frameForEvent(event);
+ ASSERT(frame->page() == corePage());
+
+ bool eventWasHandled = false;
+ for (size_t i = 0; i < commands.size(); ++i) {
+ if (commands[i].commandName == "insertText:") {
+ ASSERT(!frame->editor()->hasComposition());
+
+ if (!frame->editor()->canEdit())
+ continue;
+
+ // 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.
+ eventWasHandled |= frame->editor()->insertText(commands[i].text, event);
+ } else {
+ Editor::Command command = frame->editor()->command(commandNameForSelectorName(commands[i].commandName));
+ if (command.isSupported()) {
+ bool commandExecutedByEditor = command.execute(event);
+ eventWasHandled |= commandExecutedByEditor;
+ if (!commandExecutedByEditor) {
+ bool performedNonEditingBehavior = event->keyEvent()->type() == PlatformEvent::RawKeyDown && performNonEditingBehaviorForSelector(commands[i].commandName);
+ eventWasHandled |= performedNonEditingBehavior;
+ }
+ } else {
+ bool commandWasHandledByUIProcess = false;
+ WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::ExecuteSavedCommandBySelector(commands[i].commandName),
+ Messages::WebPageProxy::ExecuteSavedCommandBySelector::Reply(commandWasHandledByUIProcess), m_pageID);
+ eventWasHandled |= commandWasHandledByUIProcess;
+ }
+ }
+ }
+ return eventWasHandled;
+}
+
+bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* event, bool saveCommands)
+{
+ ASSERT(!saveCommands || event->keypressCommands().isEmpty()); // Save commands once for each event.
+
+ Frame* frame = frameForEvent(event);
+
+ const PlatformKeyboardEvent* platformEvent = event->keyEvent();
+ if (!platformEvent)
+ return false;
+ Vector<KeypressCommand>& commands = event->keypressCommands();
+
+ if ([platformEvent->macEvent() type] == NSFlagsChanged)
+ return false;
+
+ bool eventWasHandled = false;
+
+ if (saveCommands) {
+ KeyboardEvent* oldEvent = m_keyboardEventBeingInterpreted;
+ m_keyboardEventBeingInterpreted = event;
+ bool sendResult = WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::InterpretQueuedKeyEvent(editorState()),
+ Messages::WebPageProxy::InterpretQueuedKeyEvent::Reply(eventWasHandled, commands), m_pageID);
+ m_keyboardEventBeingInterpreted = oldEvent;
+ if (!sendResult)
+ return false;
+
+ // An input method may make several actions per keypress. For example, pressing Return with Korean IM both confirms it and sends a newline.
+ // IM-like actions are handled immediately (so the return value from UI process is true), but there are saved commands that
+ // should be handled like normal text input after DOM event dispatch.
+ if (!event->keypressCommands().isEmpty())
+ return false;
+ } else {
+ // Are there commands that could just cause text insertion if executed via Editor?
+ // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore
+ // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
+ // (e.g. Tab that inserts a Tab character, or Enter).
+ bool haveTextInsertionCommands = false;
+ for (size_t i = 0; i < commands.size(); ++i) {
+ if (frame->editor()->command(commandNameForSelectorName(commands[i].commandName)).isTextInsertion())
+ haveTextInsertionCommands = true;
+ }
+ // If there are no text insertion commands, default keydown handler is the right time to execute the commands.
+ // Keypress (Char event) handler is the latest opportunity to execute.
+ if (!haveTextInsertionCommands || platformEvent->type() == PlatformEvent::Char) {
+ eventWasHandled = executeKeypressCommandsInternal(event->keypressCommands(), event);
+ event->keypressCommands().clear();
+ }
+ }
+ return eventWasHandled;
+}
+
+void WebPage::sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput)
+{
+ for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) {
+ if ((*it)->sendComplexTextInput(pluginComplexTextInputIdentifier, textInput))
+ break;
+ }
+}
+
+void WebPage::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, EditorState& newState)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+
+ if (frame->selection()->isContentEditable()) {
+ RefPtr<Range> replacementRange;
+ if (replacementRangeStart != NSNotFound) {
+ replacementRange = convertToRange(frame, NSMakeRange(replacementRangeStart, replacementRangeEnd - replacementRangeStart));
+ frame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
+ }
+
+ frame->editor()->setComposition(text, underlines, selectionStart, selectionEnd);
+ }
+
+ newState = editorState();
+}
+
+void WebPage::confirmComposition(EditorState& newState)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+
+ frame->editor()->confirmComposition();
+
+ newState = editorState();
+}
+
+void WebPage::cancelComposition(EditorState& newState)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+
+ frame->editor()->cancelComposition();
+
+ newState = editorState();
+}
+
+void WebPage::insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, bool& handled, EditorState& newState)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+
+ RefPtr<Range> replacementRange;
+ if (replacementRangeStart != NSNotFound) {
+ replacementRange = convertToRange(frame, NSMakeRange(replacementRangeStart, replacementRangeEnd - replacementRangeStart));
+ frame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
+ }
+
+ 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.
+ handled = frame->editor()->insertText(text, m_keyboardEventBeingInterpreted);
+ } else {
+ handled = true;
+ frame->editor()->confirmComposition(text);
+ }
+
+ newState = editorState();
+}
+
+void WebPage::getMarkedRange(uint64_t& location, uint64_t& length)
+{
+ location = NSNotFound;
+ length = 0;
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+
+ RefPtr<Range> range = frame->editor()->compositionRange();
+ size_t locationSize;
+ size_t lengthSize;
+ if (range && TextIterator::getLocationAndLengthFromRange(frame->selection()->rootEditableElementOrDocumentElement(), range.get(), locationSize, lengthSize)) {
+ location = static_cast<uint64_t>(locationSize);
+ length = static_cast<uint64_t>(lengthSize);
+ }
+}
+
+void WebPage::getSelectedRange(uint64_t& location, uint64_t& length)
+{
+ location = NSNotFound;
+ length = 0;
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+
+ size_t locationSize;
+ size_t lengthSize;
+ RefPtr<Range> range = frame->selection()->toNormalizedRange();
+ if (range && TextIterator::getLocationAndLengthFromRange(frame->selection()->rootEditableElementOrDocumentElement(), range.get(), locationSize, lengthSize)) {
+ location = static_cast<uint64_t>(locationSize);
+ length = static_cast<uint64_t>(lengthSize);
+ }
+}
+
+void WebPage::getAttributedSubstringFromRange(uint64_t location, uint64_t length, AttributedString& result)
+{
+ NSRange nsRange = NSMakeRange(location, length - location);
+
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+
+ if (frame->selection()->isNone() || !frame->selection()->isContentEditable() || frame->selection()->isInPasswordField())
+ return;
+
+ RefPtr<Range> range = convertToRange(frame, nsRange);
+ if (!range)
+ return;
+
+ result.string = [WebHTMLConverter editingAttributedStringFromRange:range.get()];
+ NSAttributedString* attributedString = result.string.get();
+
+ // [WebHTMLConverter editingAttributedStringFromRange:] insists on inserting a trailing
+ // whitespace at the end of the string which breaks the ATOK input method. <rdar://problem/5400551>
+ // To work around this we truncate the resultant string to the correct length.
+ if ([attributedString length] > nsRange.length) {
+ ASSERT([attributedString length] == nsRange.length + 1);
+ ASSERT([[attributedString string] characterAtIndex:nsRange.length] == '\n' || [[attributedString string] characterAtIndex:nsRange.length] == ' ');
+ result.string = [attributedString attributedSubstringFromRange:NSMakeRange(0, nsRange.length)];
+ }
+}
+
+void WebPage::characterIndexForPoint(IntPoint point, uint64_t& index)
+{
+ index = NSNotFound;
+ Frame* frame = m_page->mainFrame();
+ if (!frame)
+ return;
+
+ HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(point, false);
+ frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : m_page->focusController()->focusedOrMainFrame();
+
+ RefPtr<Range> range = frame->rangeForPoint(result.point());
+ if (!range)
+ return;
+
+ size_t location;
+ size_t length;
+ if (TextIterator::getLocationAndLengthFromRange(frame->selection()->rootEditableElementOrDocumentElement(), range.get(), location, length))
+ index = static_cast<uint64_t>(location);
+}
+
+PassRefPtr<Range> convertToRange(Frame* frame, NSRange nsrange)
+{
+ if (nsrange.location > INT_MAX)
+ return 0;
+ if (nsrange.length > INT_MAX || nsrange.location + nsrange.length > INT_MAX)
+ nsrange.length = INT_MAX - nsrange.location;
+
+ // our critical assumption is that we are only 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(), nsrange.location, nsrange.length);
+}
+
+void WebPage::firstRectForCharacterRange(uint64_t location, uint64_t length, WebCore::IntRect& resultRect)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ resultRect.setLocation(IntPoint(0, 0));
+ resultRect.setSize(IntSize(0, 0));
+
+ RefPtr<Range> range = convertToRange(frame, NSMakeRange(location, length));
+ if (!range)
+ return;
+
+ ASSERT(range->startContainer());
+ ASSERT(range->endContainer());
+
+ IntRect rect = frame->editor()->firstRectForRange(range.get());
+ resultRect = frame->view()->contentsToWindow(rect);
+}
+
+void WebPage::executeKeypressCommands(const Vector<WebCore::KeypressCommand>& commands, bool& handled, EditorState& newState)
+{
+ handled = executeKeypressCommandsInternal(commands, m_keyboardEventBeingInterpreted);
+ newState = editorState();
+}
+
+static bool isPositionInRange(const VisiblePosition& position, Range* range)
+{
+ RefPtr<Range> positionRange = makeRange(position, position);
+
+ ExceptionCode ec = 0;
+ range->compareBoundaryPoints(Range::START_TO_START, positionRange.get(), ec);
+ if (ec)
+ return false;
+
+ if (!range->isPointInRange(positionRange->startContainer(), positionRange->startOffset(), ec))
+ return false;
+ if (ec)
+ return false;
+
+ return true;
+}
+
+static bool shouldUseSelection(const VisiblePosition& position, const VisibleSelection& selection)
+{
+ if (!selection.isRange())
+ return false;
+
+ RefPtr<Range> selectedRange = selection.toNormalizedRange();
+ if (!selectedRange)
+ return false;
+
+ return isPositionInRange(position, selectedRange.get());
+}
+
+void WebPage::performDictionaryLookupAtLocation(const FloatPoint& floatPoint)
+{
+ Frame* frame = m_page->mainFrame();
+ if (!frame)
+ return;
+
+ // Find the frame the point is over.
+ IntPoint point = roundedIntPoint(floatPoint);
+ HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(point, false);
+ frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : m_page->focusController()->focusedOrMainFrame();
+
+ IntPoint translatedPoint = frame->view()->windowToContents(point);
+
+ // Don't do anything if there is no character at the point.
+ if (!frame->rangeForPoint(translatedPoint))
+ return;
+
+ VisiblePosition position = frame->visiblePositionForPoint(translatedPoint);
+ VisibleSelection selection = m_page->focusController()->focusedOrMainFrame()->selection()->selection();
+ if (shouldUseSelection(position, selection)) {
+ performDictionaryLookupForSelection(DictionaryPopupInfo::HotKey, frame, selection);
+ return;
+ }
+
+ NSDictionary *options = nil;
+
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ // As context, we are going to use the surrounding paragraph of text.
+ VisiblePosition paragraphStart = startOfParagraph(position);
+ VisiblePosition paragraphEnd = endOfParagraph(position);
+
+ NSRange rangeToPass = NSMakeRange(TextIterator::rangeLength(makeRange(paragraphStart, position).get()), 0);
+
+ RefPtr<Range> fullCharacterRange = makeRange(paragraphStart, paragraphEnd);
+ String fullPlainTextString = plainText(fullCharacterRange.get());
+
+ NSRange extractedRange = WKExtractWordDefinitionTokenRangeFromContextualString(fullPlainTextString, rangeToPass, &options);
+
+ RefPtr<Range> finalRange = TextIterator::subrange(fullCharacterRange.get(), extractedRange.location, extractedRange.length);
+ if (!finalRange)
+ return;
+#else
+ RefPtr<Range> finalRange = makeRange(startOfWord(position), endOfWord(position));
+ if (!finalRange)
+ return;
+#endif
+
+ performDictionaryLookupForRange(DictionaryPopupInfo::HotKey, frame, finalRange.get(), options);
+}
+
+void WebPage::performDictionaryLookupForSelection(DictionaryPopupInfo::Type type, Frame* frame, const VisibleSelection& selection)
+{
+ RefPtr<Range> selectedRange = selection.toNormalizedRange();
+ if (!selectedRange)
+ return;
+
+ NSDictionary *options = nil;
+
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ VisiblePosition selectionStart = selection.visibleStart();
+ VisiblePosition selectionEnd = selection.visibleEnd();
+
+ // As context, we are going to use the surrounding paragraphs of text.
+ VisiblePosition paragraphStart = startOfParagraph(selectionStart);
+ VisiblePosition paragraphEnd = endOfParagraph(selectionEnd);
+
+ int lengthToSelectionStart = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get());
+ int lengthToSelectionEnd = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get());
+ NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, lengthToSelectionEnd - lengthToSelectionStart);
+
+ String fullPlainTextString = plainText(makeRange(paragraphStart, paragraphEnd).get());
+
+ // Since we already have the range we want, we just need to grab the returned options.
+ WKExtractWordDefinitionTokenRangeFromContextualString(fullPlainTextString, rangeToPass, &options);
+#endif
+
+ performDictionaryLookupForRange(type, frame, selectedRange.get(), options);
+}
+
+void WebPage::performDictionaryLookupForRange(DictionaryPopupInfo::Type type, Frame* frame, Range* range, NSDictionary *options)
+{
+ String rangeText = range->text();
+ if (rangeText.stripWhiteSpace().isEmpty())
+ return;
+
+ RenderObject* renderer = range->startContainer()->renderer();
+ RenderStyle* style = renderer->style();
+ NSFont *font = style->font().primaryFont()->getNSFont();
+
+ // We won't be able to get an NSFont in the case that a Web Font is being used, so use
+ // the default system font at the same size instead.
+ if (!font)
+ font = [NSFont systemFontOfSize:style->font().primaryFont()->platformData().size()];
+
+ CFDictionaryRef fontDescriptorAttributes = (CFDictionaryRef)[[font fontDescriptor] fontAttributes];
+ if (!fontDescriptorAttributes)
+ return;
+
+ Vector<FloatQuad> quads;
+ range->textQuads(quads);
+ if (quads.isEmpty())
+ return;
+
+ IntRect rangeRect = frame->view()->contentsToWindow(quads[0].enclosingBoundingBox());
+
+ DictionaryPopupInfo dictionaryPopupInfo;
+ dictionaryPopupInfo.type = type;
+ dictionaryPopupInfo.origin = FloatPoint(rangeRect.x(), rangeRect.y() + style->fontMetrics().ascent());
+ dictionaryPopupInfo.fontInfo.fontAttributeDictionary = fontDescriptorAttributes;
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ dictionaryPopupInfo.options = (CFDictionaryRef)options;
+#endif
+
+ send(Messages::WebPageProxy::DidPerformDictionaryLookup(rangeText, dictionaryPopupInfo));
+}
+
+bool WebPage::performNonEditingBehaviorForSelector(const String& selector)
+{
+ // FIXME: All these selectors have corresponding Editor commands, but the commands only work in editable content.
+ // Should such non-editing behaviors be implemented in Editor or EventHandler::defaultArrowEventHandler() perhaps?
+ if (selector == "moveUp:")
+ scroll(m_page.get(), ScrollUp, ScrollByLine);
+ else if (selector == "moveToBeginningOfParagraph:")
+ scroll(m_page.get(), ScrollUp, ScrollByPage);
+ else if (selector == "moveToBeginningOfDocument:") {
+ scroll(m_page.get(), ScrollUp, ScrollByDocument);
+ scroll(m_page.get(), ScrollLeft, ScrollByDocument);
+ } else if (selector == "moveDown:")
+ scroll(m_page.get(), ScrollDown, ScrollByLine);
+ else if (selector == "moveToEndOfParagraph:")
+ scroll(m_page.get(), ScrollDown, ScrollByPage);
+ else if (selector == "moveToEndOfDocument:") {
+ scroll(m_page.get(), ScrollDown, ScrollByDocument);
+ scroll(m_page.get(), ScrollLeft, ScrollByDocument);
+ } else if (selector == "moveLeft:")
+ scroll(m_page.get(), ScrollLeft, ScrollByLine);
+ else if (selector == "moveWordLeft:")
+ scroll(m_page.get(), ScrollLeft, ScrollByPage);
+ else if (selector == "moveToLeftEndOfLine:")
+ m_page->goBack();
+ else if (selector == "moveRight:")
+ scroll(m_page.get(), ScrollRight, ScrollByLine);
+ else if (selector == "moveWordRight:")
+ scroll(m_page.get(), ScrollRight, ScrollByPage);
+ else if (selector == "moveToRightEndOfLine:")
+ m_page->goForward();
+ else
+ return false;
+
+ return true;
+}
+
+bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&)
+{
+ return false;
+}
+
+void WebPage::registerUIProcessAccessibilityTokens(const CoreIPC::DataReference& elementToken, const CoreIPC::DataReference& windowToken)
+{
+ NSData* elementTokenData = [NSData dataWithBytes:elementToken.data() length:elementToken.size()];
+ NSData* windowTokenData = [NSData dataWithBytes:windowToken.data() length:windowToken.size()];
+ id remoteElement = WKAXRemoteElementForToken(elementTokenData);
+ id remoteWindow = WKAXRemoteElementForToken(windowTokenData);
+ WKAXSetWindowForRemoteElement(remoteWindow, remoteElement);
+
+ [accessibilityRemoteObject() setRemoteParent:remoteElement];
+}
+
+void WebPage::writeSelectionToPasteboard(const String& pasteboardName, const Vector<String>& pasteboardTypes, bool& result)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame || frame->selection()->isNone()) {
+ result = false;
+ return;
+ }
+ frame->editor()->writeSelectionToPasteboard(pasteboardName, pasteboardTypes);
+ result = true;
+}
+
+void WebPage::readSelectionFromPasteboard(const String& pasteboardName, bool& result)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame || frame->selection()->isNone()) {
+ result = false;
+ return;
+ }
+ frame->editor()->readSelectionFromPasteboard(pasteboardName);
+ result = true;
+}
+
+WKAccessibilityWebPageObject* WebPage::accessibilityRemoteObject()
+{
+ return m_mockAccessibilityElement.get();
+}
+
+bool WebPage::platformHasLocalDataForURL(const WebCore::KURL& url)
+{
+ NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
+ [request setValue:(NSString*)userAgent() forHTTPHeaderField:@"User-Agent"];
+ NSCachedURLResponse *cachedResponse;
+#if USE(CFURLSTORAGESESSIONS)
+ if (CFURLStorageSessionRef storageSession = ResourceHandle::currentStorageSession())
+ cachedResponse = WKCachedResponseForRequest(storageSession, request);
+ else
+#endif
+ cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
+ [request release];
+
+ return cachedResponse;
+}
+
+static NSCachedURLResponse *cachedResponseForURL(WebPage* webPage, const KURL& url)
+{
+ RetainPtr<NSMutableURLRequest> request(AdoptNS, [[NSMutableURLRequest alloc] initWithURL:url]);
+ [request.get() setValue:(NSString *)webPage->userAgent() forHTTPHeaderField:@"User-Agent"];
+
+#if USE(CFURLSTORAGESESSIONS)
+ if (CFURLStorageSessionRef storageSession = ResourceHandle::currentStorageSession())
+ return WKCachedResponseForRequest(storageSession, request.get());
+#endif
+
+ return [[NSURLCache sharedURLCache] cachedResponseForRequest:request.get()];
+}
+
+String WebPage::cachedSuggestedFilenameForURL(const KURL& url)
+{
+ return [[cachedResponseForURL(this, url) response] suggestedFilename];
+}
+
+String WebPage::cachedResponseMIMETypeForURL(const KURL& url)
+{
+ return [[cachedResponseForURL(this, url) response] MIMEType];
+}
+
+PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL& url)
+{
+ return SharedBuffer::wrapNSData([cachedResponseForURL(this, url) data]);
+}
+
+bool WebPage::platformCanHandleRequest(const WebCore::ResourceRequest& request)
+{
+ if ([NSURLConnection canHandleRequest:request.nsURLRequest()])
+ return true;
+
+ // FIXME: Return true if this scheme is any one WebKit2 knows how to handle.
+ return request.url().protocolIs("applewebdata");
+}
+
+void WebPage::shouldDelayWindowOrderingEvent(const WebKit::WebMouseEvent& event, bool& result)
+{
+ result = false;
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+
+ HitTestResult hitResult = frame->eventHandler()->hitTestResultAtPoint(event.position(), true);
+ if (hitResult.isSelected())
+ result = frame->eventHandler()->eventMayStartDrag(platform(event));
+}
+
+void WebPage::acceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent& event, bool& result)
+{
+ result = false;
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+
+ HitTestResult hitResult = frame->eventHandler()->hitTestResultAtPoint(event.position(), true);
+ frame->eventHandler()->setActivationEventNumber(eventNumber);
+ if (hitResult.isSelected())
+ result = frame->eventHandler()->eventMayStartDrag(platform(event));
+ else
+ result = !!hitResult.scrollbar();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp
new file mode 100644
index 000000000..266a3a95d
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 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"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerTreeHostQt.h"
+
+#include "DrawingAreaImpl.h"
+#include "GraphicsContext.h"
+#include "LayerTreeHostProxyMessages.h"
+#include "MessageID.h"
+#include "WebGraphicsLayer.h"
+#include "WebPage.h"
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/Page.h>
+#include <WebCore/Settings.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+PassRefPtr<LayerTreeHostQt> LayerTreeHostQt::create(WebPage* webPage)
+{
+ return adoptRef(new LayerTreeHostQt(webPage));
+}
+
+LayerTreeHostQt::~LayerTreeHostQt()
+{
+}
+
+LayerTreeHostQt::LayerTreeHostQt(WebPage* webPage)
+ : LayerTreeHost(webPage)
+ , m_notifyAfterScheduledLayerFlush(false)
+ , m_isValid(true)
+#if USE(TILED_BACKING_STORE)
+ , m_waitingForUIProcess(false)
+ , m_isSuspended(false)
+#endif
+ , m_shouldSyncFrame(false)
+ , m_shouldSyncRootLayer(true)
+ , m_layerFlushTimer(this, &LayerTreeHostQt::layerFlushTimerFired)
+ , m_layerFlushSchedulingEnabled(true)
+ , m_shouldRecreateBackingStore(false)
+{
+ // Create a root layer.
+ m_rootLayer = GraphicsLayer::create(this);
+ WebGraphicsLayer* webRootLayer = toWebGraphicsLayer(m_rootLayer.get());
+ webRootLayer->setRootLayer(true);
+#ifndef NDEBUG
+ m_rootLayer->setName("LayerTreeHostQt root layer");
+#endif
+ m_rootLayer->setDrawsContent(false);
+ m_rootLayer->setSize(m_webPage->size());
+ m_layerTreeContext.webLayerID = toWebGraphicsLayer(webRootLayer)->id();
+
+ m_nonCompositedContentLayer = GraphicsLayer::create(this);
+#if USE(TILED_BACKING_STORE)
+ toWebGraphicsLayer(m_rootLayer.get())->setLayerTreeTileClient(this);
+#endif
+#ifndef NDEBUG
+ m_nonCompositedContentLayer->setName("LayerTreeHostQt non-composited content");
+#endif
+ m_nonCompositedContentLayer->setDrawsContent(true);
+ m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground());
+ m_nonCompositedContentLayer->setSize(m_webPage->size());
+
+ m_rootLayer->addChild(m_nonCompositedContentLayer.get());
+
+ if (m_webPage->hasPageOverlay())
+ createPageOverlayLayer();
+
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostQt::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled)
+{
+ if (m_layerFlushSchedulingEnabled == layerFlushingEnabled)
+ return;
+
+ m_layerFlushSchedulingEnabled = layerFlushingEnabled;
+
+ if (m_layerFlushSchedulingEnabled) {
+ scheduleLayerFlush();
+ return;
+ }
+
+ cancelPendingLayerFlush();
+}
+
+void LayerTreeHostQt::scheduleLayerFlush()
+{
+ if (!m_layerFlushSchedulingEnabled)
+ return;
+
+ if (!m_layerFlushTimer.isActive())
+ m_layerFlushTimer.startOneShot(0);
+}
+
+void LayerTreeHostQt::cancelPendingLayerFlush()
+{
+ m_layerFlushTimer.stop();
+}
+
+void LayerTreeHostQt::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
+{
+ m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
+}
+
+void LayerTreeHostQt::setRootCompositingLayer(WebCore::GraphicsLayer* graphicsLayer)
+{
+ m_nonCompositedContentLayer->removeAllChildren();
+
+ // Add the accelerated layer tree hierarchy.
+ if (graphicsLayer)
+ m_nonCompositedContentLayer->addChild(graphicsLayer);
+}
+
+void LayerTreeHostQt::invalidate()
+{
+ cancelPendingLayerFlush();
+
+ ASSERT(m_isValid);
+ m_rootLayer = nullptr;
+ m_isValid = false;
+}
+
+void LayerTreeHostQt::setNonCompositedContentsNeedDisplay(const WebCore::IntRect& rect)
+{
+ m_nonCompositedContentLayer->setNeedsDisplayInRect(rect);
+ if (m_pageOverlayLayer)
+ m_pageOverlayLayer->setNeedsDisplayInRect(rect);
+
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostQt::scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset)
+{
+ setNonCompositedContentsNeedDisplay(scrollRect);
+}
+
+void LayerTreeHostQt::forceRepaint()
+{
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostQt::sizeDidChange(const WebCore::IntSize& newSize)
+{
+ m_rootLayer->setSize(newSize);
+
+ // If the newSize exposes new areas of the non-composited content a setNeedsDisplay is needed
+ // for those newly exposed areas.
+ FloatSize oldSize = m_nonCompositedContentLayer->size();
+ m_nonCompositedContentLayer->setSize(newSize);
+
+ if (newSize.width() > oldSize.width()) {
+ float height = std::min(static_cast<float>(newSize.height()), oldSize.height());
+ m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(oldSize.width(), 0, newSize.width() - oldSize.width(), height));
+ }
+
+ if (newSize.height() > oldSize.height())
+ m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(0, oldSize.height(), newSize.width(), newSize.height() - oldSize.height()));
+
+ if (m_pageOverlayLayer)
+ m_pageOverlayLayer->setSize(newSize);
+
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostQt::didInstallPageOverlay()
+{
+ createPageOverlayLayer();
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostQt::didUninstallPageOverlay()
+{
+ destroyPageOverlayLayer();
+ scheduleLayerFlush();
+}
+
+void LayerTreeHostQt::setPageOverlayNeedsDisplay(const WebCore::IntRect& rect)
+{
+ ASSERT(m_pageOverlayLayer);
+ m_pageOverlayLayer->setNeedsDisplayInRect(rect);
+ scheduleLayerFlush();
+}
+
+bool LayerTreeHostQt::flushPendingLayerChanges()
+{
+ recreateBackingStoreIfNeeded();
+
+ bool didSync = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes();
+ m_nonCompositedContentLayer->syncCompositingStateForThisLayerOnly();
+ if (m_pageOverlayLayer)
+ m_pageOverlayLayer->syncCompositingStateForThisLayerOnly();
+
+ m_rootLayer->syncCompositingStateForThisLayerOnly();
+ return didSync;
+}
+
+void LayerTreeHostQt::didSyncCompositingStateForLayer(const WebLayerInfo& info)
+{
+ m_shouldSyncFrame = true;
+ m_webPage->send(Messages::LayerTreeHostProxy::SyncCompositingLayerState(info));
+}
+
+void LayerTreeHostQt::didDeleteLayer(WebLayerID id)
+{
+ m_shouldSyncFrame = true;
+ m_webPage->send(Messages::LayerTreeHostProxy::DeleteCompositingLayer(id));
+}
+
+void LayerTreeHostQt::performScheduledLayerFlush()
+{
+ m_webPage->layoutIfNeeded();
+
+ if (!m_isValid)
+ return;
+
+#if USE(TILED_BACKING_STORE)
+ if (m_isSuspended || m_waitingForUIProcess)
+ return;
+#endif
+
+ m_shouldSyncFrame = false;
+ flushPendingLayerChanges();
+ if (!m_shouldSyncFrame)
+ return;
+
+ if (m_shouldSyncRootLayer) {
+ m_webPage->send(Messages::LayerTreeHostProxy::SetRootCompositingLayer(toWebGraphicsLayer(m_rootLayer.get())->id()));
+ m_shouldSyncRootLayer = false;
+ }
+
+ m_webPage->send(Messages::LayerTreeHostProxy::DidRenderFrame());
+
+ if (!m_notifyAfterScheduledLayerFlush)
+ return;
+
+ // Let the drawing area know that we've done a flush of the layer changes.
+ static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
+ m_notifyAfterScheduledLayerFlush = false;
+}
+
+void LayerTreeHostQt::layerFlushTimerFired(Timer<LayerTreeHostQt>*)
+{
+ performScheduledLayerFlush();
+}
+
+void LayerTreeHostQt::createPageOverlayLayer()
+{
+ ASSERT(!m_pageOverlayLayer);
+
+ m_pageOverlayLayer = GraphicsLayer::create(this);
+#ifndef NDEBUG
+ m_pageOverlayLayer->setName("LayerTreeHostQt page overlay content");
+#endif
+
+ m_pageOverlayLayer->setDrawsContent(true);
+ m_pageOverlayLayer->setSize(m_webPage->size());
+
+ m_rootLayer->addChild(m_pageOverlayLayer.get());
+}
+
+void LayerTreeHostQt::destroyPageOverlayLayer()
+{
+ ASSERT(m_pageOverlayLayer);
+ m_pageOverlayLayer->removeFromParent();
+ m_pageOverlayLayer = nullptr;
+}
+
+int64_t LayerTreeHostQt::adoptImageBackingStore(Image* image)
+{
+ if (!image)
+ return InvalidWebLayerID;
+ QPixmap* pixmap = image->nativeImageForCurrentFrame();
+
+ if (!pixmap)
+ return InvalidWebLayerID;
+
+ int64_t key = pixmap->cacheKey();
+ HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key);
+
+ if (it != m_directlyCompositedImageRefCounts.end()) {
+ ++(it->second);
+ return key;
+ }
+
+ RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(image->size(), image->currentFrameHasAlpha() ? ShareableBitmap::SupportsAlpha : 0);
+ {
+ OwnPtr<WebCore::GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
+ graphicsContext->drawImage(image, ColorSpaceDeviceRGB, IntPoint::zero());
+ }
+
+ ShareableBitmap::Handle handle;
+ bitmap->createHandle(handle);
+ m_webPage->send(Messages::LayerTreeHostProxy::CreateDirectlyCompositedImage(key, handle));
+ m_directlyCompositedImageRefCounts.add(key, 1);
+ return key;
+}
+
+void LayerTreeHostQt::releaseImageBackingStore(int64_t key)
+{
+ if (!key)
+ return;
+ HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key);
+ if (it == m_directlyCompositedImageRefCounts.end())
+ return;
+
+ it->second--;
+
+ if (it->second)
+ return;
+
+ m_directlyCompositedImageRefCounts.remove(it);
+ m_webPage->send(Messages::LayerTreeHostProxy::DestroyDirectlyCompositedImage(key));
+}
+
+
+void LayerTreeHostQt::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
+{
+}
+
+void LayerTreeHostQt::notifySyncRequired(const WebCore::GraphicsLayer*)
+{
+}
+
+void LayerTreeHostQt::paintContents(const WebCore::GraphicsLayer* graphicsLayer, WebCore::GraphicsContext& graphicsContext, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect)
+{
+ if (graphicsLayer == m_nonCompositedContentLayer) {
+ m_webPage->drawRect(graphicsContext, clipRect);
+ return;
+ }
+
+ if (graphicsLayer == m_pageOverlayLayer) {
+ // Overlays contain transparent contents and won't clear the context as part of their rendering, so we do it here.
+ graphicsContext.clearRect(clipRect);
+ m_webPage->drawPageOverlay(graphicsContext, clipRect);
+ return;
+ }
+}
+
+bool LayerTreeHostQt::showDebugBorders() const
+{
+ return m_webPage->corePage()->settings()->showDebugBorders();
+}
+
+bool LayerTreeHostQt::showRepaintCounter() const
+{
+ return m_webPage->corePage()->settings()->showRepaintCounter();
+}
+
+bool LayerTreeHost::supportsAcceleratedCompositing()
+{
+ return true;
+}
+
+#if USE(TILED_BACKING_STORE)
+void LayerTreeHostQt::createTile(WebLayerID layerID, int tileID, const UpdateInfo& updateInfo)
+{
+ m_webPage->send(Messages::LayerTreeHostProxy::CreateTileForLayer(layerID, tileID, updateInfo));
+}
+
+void LayerTreeHostQt::updateTile(WebLayerID layerID, int tileID, const UpdateInfo& updateInfo)
+{
+ m_webPage->send(Messages::LayerTreeHostProxy::UpdateTileForLayer(layerID, tileID, updateInfo));
+}
+void LayerTreeHostQt::removeTile(WebLayerID layerID, int tileID)
+{
+ m_webPage->send(Messages::LayerTreeHostProxy::RemoveTileForLayer(layerID, tileID));
+}
+
+void LayerTreeHostQt::setVisibleContentRectForLayer(int layerID, const WebCore::IntRect& rect)
+{
+ WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(layerID);
+ if (!layer)
+ return;
+ FloatRect visibleRect(rect);
+ layer->setVisibleContentRect(rect);
+}
+
+void LayerTreeHostQt::setVisibleContentRectAndScale(const IntRect& rect, float scale)
+{
+ WebGraphicsLayer* layer = toWebGraphicsLayer(m_rootLayer.get());
+ if (!layer)
+ return;
+ layer->setContentsScale(scale);
+ toWebGraphicsLayer(m_nonCompositedContentLayer.get())->setVisibleContentRect(rect);
+}
+
+void LayerTreeHostQt::setVisibleContentRectTrajectoryVector(const FloatPoint& trajectoryVector)
+{
+ toWebGraphicsLayer(m_nonCompositedContentLayer.get())->setVisibleContentRectTrajectoryVector(trajectoryVector);
+}
+
+void LayerTreeHostQt::renderNextFrame()
+{
+ m_waitingForUIProcess = false;
+ scheduleLayerFlush();
+}
+
+bool LayerTreeHostQt::layerTreeTileUpdatesAllowed() const
+{
+ return !m_isSuspended && !m_waitingForUIProcess;
+}
+
+void LayerTreeHostQt::purgeBackingStores()
+{
+ m_shouldRecreateBackingStore = true;
+ WebGraphicsLayer* webRootLayer = toWebGraphicsLayer(m_rootLayer.get());
+ webRootLayer->purgeBackingStores();
+
+ ASSERT(!m_directlyCompositedImageRefCounts.size());
+}
+
+void LayerTreeHostQt::recreateBackingStoreIfNeeded()
+{
+ if (!m_shouldRecreateBackingStore)
+ return;
+
+ m_shouldRecreateBackingStore = false;
+ WebGraphicsLayer* webRootLayer = toWebGraphicsLayer(m_rootLayer.get());
+ webRootLayer->recreateBackingStoreIfNeeded();
+}
+#endif
+
+} // namespace WebKit
+#else
+#include "LayerTreeHost.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+bool LayerTreeHost::supportsAcceleratedCompositing()
+{
+ return false;
+}
+
+} // namespace WebKit
+#endif
diff --git a/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.h b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.h
new file mode 100644
index 000000000..8527c528b
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.h
@@ -0,0 +1,129 @@
+/*
+ Copyright (C) 2011 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 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 LayerTreeHostQt_h
+#define LayerTreeHostQt_h
+
+#include "LayerTreeContext.h"
+#include "LayerTreeHost.h"
+#include "Timer.h"
+#include "WebGraphicsLayer.h"
+#include <WebCore/GraphicsLayerClient.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebKit {
+
+class UpdateInfo;
+class WebPage;
+
+class LayerTreeHostQt : public LayerTreeHost, WebCore::GraphicsLayerClient
+#if USE(TILED_BACKING_STORE)
+ , public WebLayerTreeTileClient
+#endif
+{
+public:
+ static PassRefPtr<LayerTreeHostQt> create(WebPage*);
+ virtual ~LayerTreeHostQt();
+
+ static bool supportsAcceleratedCompositing();
+
+ virtual const LayerTreeContext& layerTreeContext() { return m_layerTreeContext; }
+ virtual void setLayerFlushSchedulingEnabled(bool);
+ virtual void scheduleLayerFlush();
+ virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool);
+ virtual void setRootCompositingLayer(WebCore::GraphicsLayer*);
+ virtual void invalidate();
+
+ virtual void setNonCompositedContentsNeedDisplay(const WebCore::IntRect&);
+ virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset);
+ virtual void forceRepaint();
+ virtual void sizeDidChange(const WebCore::IntSize& newSize);
+
+ virtual void didInstallPageOverlay();
+ virtual void didUninstallPageOverlay();
+ virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&);
+
+ virtual void pauseRendering() { m_isSuspended = true; }
+ virtual void resumeRendering() { m_isSuspended = false; scheduleLayerFlush(); }
+ virtual void deviceScaleFactorDidChange() { }
+ virtual int64_t adoptImageBackingStore(Image*);
+ virtual void releaseImageBackingStore(int64_t);
+
+#if USE(TILED_BACKING_STORE)
+ virtual void createTile(WebLayerID, int tileID, const UpdateInfo&);
+ virtual void updateTile(WebLayerID, int tileID, const UpdateInfo&);
+ virtual void removeTile(WebLayerID, int tileID);
+ virtual void setVisibleContentRectForLayer(int layerID, const WebCore::IntRect&);
+ virtual void renderNextFrame();
+ virtual void purgeBackingStores();
+ virtual bool layerTreeTileUpdatesAllowed() const;
+ virtual void setVisibleContentRectAndScale(const IntRect&, float scale);
+ virtual void setVisibleContentRectTrajectoryVector(const FloatPoint&);
+ virtual void didSyncCompositingStateForLayer(const WebLayerInfo&);
+ virtual void didDeleteLayer(WebLayerID);
+#endif
+
+protected:
+ explicit LayerTreeHostQt(WebPage*);
+
+private:
+ // GraphicsLayerClient
+ virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double time);
+ virtual void notifySyncRequired(const WebCore::GraphicsLayer*);
+ virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect);
+ virtual bool showDebugBorders() const;
+ virtual bool showRepaintCounter() const;
+
+ // LayerTreeHostQt
+ void createPageOverlayLayer();
+ void destroyPageOverlayLayer();
+ bool flushPendingLayerChanges();
+ void cancelPendingLayerFlush();
+ void performScheduledLayerFlush();
+ void sendLayersToUI();
+ void recreateBackingStoreIfNeeded();
+
+ OwnPtr<WebCore::GraphicsLayer> m_rootLayer;
+
+ // The layer which contains all non-composited content.
+ OwnPtr<WebCore::GraphicsLayer> m_nonCompositedContentLayer;
+
+ // The page overlay layer. Will be null if there's no page overlay.
+ OwnPtr<WebCore::GraphicsLayer> m_pageOverlayLayer;
+
+ HashMap<int64_t, int> m_directlyCompositedImageRefCounts;
+
+ bool m_notifyAfterScheduledLayerFlush;
+ bool m_isValid;
+#if USE(TILED_BACKING_STORE)
+ bool m_waitingForUIProcess;
+ bool m_isSuspended;
+#endif
+ LayerTreeContext m_layerTreeContext;
+ bool m_shouldSyncFrame;
+ bool m_shouldSyncRootLayer;
+ void layerFlushTimerFired(WebCore::Timer<LayerTreeHostQt>*);
+ WebCore::Timer<LayerTreeHostQt> m_layerFlushTimer;
+ bool m_layerFlushSchedulingEnabled;
+ bool m_shouldRecreateBackingStore;
+};
+
+}
+
+#endif // LayerTreeHostQt_h
diff --git a/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp
new file mode 100644
index 000000000..1a3b598a3
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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 "WebInspector.h"
+
+#if ENABLE(INSPECTOR)
+
+#include <WebCore/NotImplemented.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+String WebInspector::localizedStringsURL() const
+{
+ notImplemented();
+ return String();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp
new file mode 100644
index 000000000..55080d03c
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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"
+
+#include "NotImplemented.h"
+#include "WebEditorClient.h"
+#include "WebEvent.h"
+#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
+#include <WebCore/FocusController.h>
+#include <WebCore/Frame.h>
+#include <WebCore/KeyboardEvent.h>
+#include <WebCore/Page.h>
+#include <WebCore/PlatformKeyboardEvent.h>
+#include <WebCore/Range.h>
+#include <WebCore/Settings.h>
+#include <WebCore/Text.h>
+#include <WebCore/TextIterator.h>
+
+#ifndef VK_UNKNOWN
+#define VK_UNKNOWN 0
+#define VK_BACK 0x08
+#define VK_TAB 0x09
+#define VK_CLEAR 0x0C
+#define VK_RETURN 0x0D
+#define VK_SHIFT 0x10
+#define VK_CONTROL 0x11 // CTRL key
+#define VK_MENU 0x12 // ALT key
+#define VK_PAUSE 0x13 // PAUSE key
+#define VK_CAPITAL 0x14 // CAPS LOCK key
+#define VK_KANA 0x15 // Input Method Editor (IME) Kana mode
+#define VK_HANGUL 0x15 // IME Hangul mode
+#define VK_JUNJA 0x17 // IME Junja mode
+#define VK_FINAL 0x18 // IME final mode
+#define VK_HANJA 0x19 // IME Hanja mode
+#define VK_KANJI 0x19 // IME Kanji mode
+#define VK_ESCAPE 0x1B // ESC key
+#define VK_CONVERT 0x1C // IME convert
+#define VK_NONCONVERT 0x1D // IME nonconvert
+#define VK_ACCEPT 0x1E // IME accept
+#define VK_MODECHANGE 0x1F // IME mode change request
+#define VK_SPACE 0x20 // SPACE key
+#define VK_PRIOR 0x21 // PAGE UP key
+#define VK_NEXT 0x22 // PAGE DOWN key
+#define VK_END 0x23 // END key
+#define VK_HOME 0x24 // HOME key
+#define VK_LEFT 0x25 // LEFT ARROW key
+#define VK_UP 0x26 // UP ARROW key
+#define VK_RIGHT 0x27 // RIGHT ARROW key
+#define VK_DOWN 0x28 // DOWN ARROW key
+#define VK_SELECT 0x29 // SELECT key
+#define VK_PRINT 0x2A // PRINT key
+#define VK_EXECUTE 0x2B // EXECUTE key
+#define VK_SNAPSHOT 0x2C // PRINT SCREEN key
+#define VK_INSERT 0x2D // INS key
+#define VK_DELETE 0x2E // DEL key
+#define VK_HELP 0x2F // HELP key
+// Windows 2000/XP: For any country/region, the '.' key
+#define VK_OEM_PERIOD 0xBE
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void WebPage::platformInitialize()
+{
+ Settings* settings = m_page->settings();
+
+ // If accelerated compositing is enabled, we want to be in force-compositing mode, so that we don't switch between composited/non-composited state.
+ settings->setForceCompositingMode(true);
+}
+
+void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
+{
+}
+
+static const unsigned CtrlKey = 1 << 0;
+static const unsigned AltKey = 1 << 1;
+static const unsigned ShiftKey = 1 << 2;
+
+struct KeyDownEntry {
+ unsigned virtualKey;
+ unsigned modifiers;
+ const char* name;
+};
+
+struct KeyPressEntry {
+ unsigned charCode;
+ unsigned modifiers;
+ const char* name;
+};
+
+static const KeyDownEntry keyDownEntries[] = {
+ { VK_LEFT, 0, "MoveLeft" },
+ { VK_LEFT, ShiftKey, "MoveLeftAndModifySelection" },
+ { VK_LEFT, CtrlKey, "MoveWordLeft" },
+ { VK_LEFT, CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection" },
+ { VK_RIGHT, 0, "MoveRight" },
+ { VK_RIGHT, ShiftKey, "MoveRightAndModifySelection" },
+ { VK_RIGHT, CtrlKey, "MoveWordRight" },
+ { VK_RIGHT, CtrlKey | ShiftKey, "MoveWordRightAndModifySelection" },
+ { VK_UP, 0, "MoveUp" },
+ { VK_UP, ShiftKey, "MoveUpAndModifySelection" },
+ { VK_PRIOR, ShiftKey, "MovePageUpAndModifySelection" },
+ { VK_DOWN, 0, "MoveDown" },
+ { VK_DOWN, ShiftKey, "MoveDownAndModifySelection" },
+ { VK_NEXT, ShiftKey, "MovePageDownAndModifySelection" },
+ { VK_PRIOR, 0, "MovePageUp" },
+ { VK_NEXT, 0, "MovePageDown" },
+ { VK_HOME, 0, "MoveToBeginningOfLine" },
+ { VK_HOME, ShiftKey, "MoveToBeginningOfLineAndModifySelection" },
+ { VK_HOME, CtrlKey, "MoveToBeginningOfDocument" },
+ { VK_HOME, CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" },
+
+ { VK_END, 0, "MoveToEndOfLine" },
+ { VK_END, ShiftKey, "MoveToEndOfLineAndModifySelection" },
+ { VK_END, CtrlKey, "MoveToEndOfDocument" },
+ { VK_END, CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection" },
+
+ { VK_BACK, 0, "DeleteBackward" },
+ { VK_BACK, ShiftKey, "DeleteBackward" },
+ { VK_DELETE, 0, "DeleteForward" },
+ { VK_BACK, CtrlKey, "DeleteWordBackward" },
+ { VK_DELETE, CtrlKey, "DeleteWordForward" },
+
+ { 'B', CtrlKey, "ToggleBold" },
+ { 'I', CtrlKey, "ToggleItalic" },
+
+ { VK_ESCAPE, 0, "Cancel" },
+ { VK_OEM_PERIOD, CtrlKey, "Cancel" },
+ { VK_TAB, 0, "InsertTab" },
+ { VK_TAB, ShiftKey, "InsertBacktab" },
+ { VK_RETURN, 0, "InsertNewline" },
+ { VK_RETURN, CtrlKey, "InsertNewline" },
+ { VK_RETURN, AltKey, "InsertNewline" },
+ { VK_RETURN, ShiftKey, "InsertNewline" },
+ { VK_RETURN, AltKey | ShiftKey, "InsertNewline" },
+
+ // It's not quite clear whether clipboard shortcuts and Undo/Redo should be handled
+ // in the application or in WebKit. We chose WebKit.
+ { 'C', CtrlKey, "Copy" },
+ { 'V', CtrlKey, "Paste" },
+ { 'X', CtrlKey, "Cut" },
+ { 'A', CtrlKey, "SelectAll" },
+ { VK_INSERT, CtrlKey, "Copy" },
+ { VK_DELETE, ShiftKey, "Cut" },
+ { VK_INSERT, ShiftKey, "Paste" },
+ { 'Z', CtrlKey, "Undo" },
+ { 'Z', CtrlKey | ShiftKey, "Redo" },
+};
+
+static const KeyPressEntry keyPressEntries[] = {
+ { '\t', 0, "InsertTab" },
+ { '\t', ShiftKey, "InsertBacktab" },
+ { '\r', 0, "InsertNewline" },
+ { '\r', CtrlKey, "InsertNewline" },
+ { '\r', AltKey, "InsertNewline" },
+ { '\r', ShiftKey, "InsertNewline" },
+ { '\r', AltKey | ShiftKey, "InsertNewline" },
+};
+
+const char* WebPage::interpretKeyEvent(const KeyboardEvent* evt)
+{
+ ASSERT(evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
+
+ static HashMap<int, const char*>* keyDownCommandsMap = 0;
+ static HashMap<int, const char*>* keyPressCommandsMap = 0;
+
+ if (!keyDownCommandsMap) {
+ keyDownCommandsMap = new HashMap<int, const char*>;
+ keyPressCommandsMap = new HashMap<int, const char*>;
+
+ for (unsigned i = 0; i < (sizeof(keyDownEntries) / sizeof(keyDownEntries[0])); i++)
+ keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
+
+ for (unsigned i = 0; i < (sizeof(keyPressEntries) / sizeof(keyPressEntries[0])); i++)
+ keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
+ }
+
+ unsigned modifiers = 0;
+ if (evt->shiftKey())
+ modifiers |= ShiftKey;
+ if (evt->altKey())
+ modifiers |= AltKey;
+ if (evt->ctrlKey())
+ modifiers |= CtrlKey;
+
+ if (evt->type() == eventNames().keydownEvent) {
+ int mapKey = modifiers << 16 | evt->keyEvent()->windowsVirtualKeyCode();
+ return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
+ }
+
+ int mapKey = modifiers << 16 | evt->charCode();
+ return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
+}
+
+static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
+{
+ page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
+}
+
+static inline void logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
+{
+ page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(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->goForward();
+ else
+ m_page->goBack();
+ break;
+ case VK_SPACE:
+ logicalScroll(m_page.get(), keyboardEvent.shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward, ScrollByPage);
+ break;
+ case VK_LEFT:
+ scroll(m_page.get(), ScrollLeft, ScrollByLine);
+ break;
+ case VK_RIGHT:
+ scroll(m_page.get(), ScrollRight, ScrollByLine);
+ break;
+ case VK_UP:
+ scroll(m_page.get(), ScrollUp, ScrollByLine);
+ break;
+ case VK_DOWN:
+ scroll(m_page.get(), ScrollDown, ScrollByLine);
+ break;
+ case VK_HOME:
+ logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument);
+ break;
+ case VK_END:
+ logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument);
+ break;
+ case VK_PRIOR:
+ logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage);
+ break;
+ case VK_NEXT:
+ logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool WebPage::platformHasLocalDataForURL(const KURL&)
+{
+ notImplemented();
+ return false;
+}
+
+String WebPage::cachedResponseMIMETypeForURL(const KURL&)
+{
+ notImplemented();
+ return String();
+}
+
+bool WebPage::platformCanHandleRequest(const ResourceRequest&)
+{
+ notImplemented();
+ return true;
+}
+
+String WebPage::cachedSuggestedFilenameForURL(const KURL&)
+{
+ notImplemented();
+ return String();
+}
+
+PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
+{
+ notImplemented();
+ return 0;
+}
+
+static Frame* targetFrameForEditing(WebPage* page)
+{
+ Frame* targetFrame = page->corePage()->focusController()->focusedOrMainFrame();
+
+ if (!targetFrame || !targetFrame->editor())
+ return 0;
+
+ Editor* editor = targetFrame->editor();
+ if (!editor->canEdit())
+ return 0;
+
+ 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;
+ }
+ }
+ return targetFrame;
+}
+
+void WebPage::confirmComposition(const String& compositionString, int64_t selectionStart, int64_t selectionLength)
+{
+ Frame* targetFrame = targetFrameForEditing(this);
+ if (!targetFrame)
+ return;
+
+ Editor* editor = targetFrame->editor();
+ editor->confirmComposition(compositionString);
+
+ RefPtr<Range> selectionRange;
+ if (selectionStart != -1) {
+ Element* scope = targetFrame->selection()->rootEditableElement();
+ 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);
+ targetFrame->selection()->setSelection(selection);
+ }
+
+ // FIXME: static_cast<WebEditorClient*>(editor->client())->sendSelectionChangedMessage();
+}
+
+void WebPage::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementStart, uint64_t replacementLength)
+{
+ Frame* targetFrame = targetFrameForEditing(this);
+ if (!targetFrame)
+ return;
+
+ Element* scope = targetFrame->selection()->rootEditableElement();
+
+ if (targetFrame->selection()->isContentEditable()) {
+ if (replacementLength > 0) {
+ // The layout needs to be uptodate before setting a selection
+ targetFrame->document()->updateLayout();
+
+ RefPtr<Range> replacementRange = TextIterator::rangeFromLocationAndLength(scope, replacementStart, replacementLength);
+
+ targetFrame->editor()->setIgnoreCompositionSelectionChange(true);
+ targetFrame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
+ targetFrame->editor()->setIgnoreCompositionSelectionChange(false);
+ }
+
+ targetFrame->editor()->setComposition(text, underlines, selectionStart, selectionEnd);
+
+ // FIXME: static_cast<WebEditorClient*>(targetFrame->editor()->client())->sendSelectionChangedMessage();
+ }
+}
+
+void WebPage::cancelComposition()
+{
+ Frame* frame = targetFrameForEditing(this);
+
+ frame->editor()->cancelComposition();
+
+ // FIXME: static_cast<WebEditorClient*>(targetFrame->editor()->client())->sendSelectionChangedMessage();
+}
+
+void WebPage::registerApplicationScheme(const String& scheme)
+{
+ QtNetworkAccessManager* qnam = qobject_cast<QtNetworkAccessManager*>(WebProcess::shared().networkAccessManager());
+ if (!qnam)
+ return;
+ qnam->registerApplicationScheme(this, QString(scheme));
+}
+
+void WebPage::receivedApplicationSchemeRequest(const QNetworkRequest& request, QtNetworkReply* reply)
+{
+ QtNetworkRequestData requestData(request, reply);
+ m_applicationSchemeReplies.add(requestData.m_replyUuid, reply);
+ send(Messages::WebPageProxy::ResolveApplicationSchemeRequest(requestData));
+}
+
+void WebPage::applicationSchemeReply(const QtNetworkReplyData& replyData)
+{
+ if (!m_applicationSchemeReplies.contains(replyData.m_replyUuid))
+ return;
+
+ QtNetworkReply* networkReply = m_applicationSchemeReplies.take(replyData.m_replyUuid);
+ networkReply->setReplyData(replyData);
+ networkReply->finalize();
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp
new file mode 100644
index 000000000..4feb001fa
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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 "DrawingAreaImpl.h"
+
+#include "ShareableBitmap.h"
+#include "UpdateInfo.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include "WindowGeometry.h"
+#include <WebCore/GraphicsContext.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void DrawingAreaImpl::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_layerTreeHost) {
+ m_layerTreeHost->scheduleChildWindowGeometryUpdate(geometry);
+ return;
+ }
+#endif
+
+ // FIXME: This should be a Messages::DrawingAreaProxy, and DrawingAreaProxy should pass the
+ // data off to the WebPageProxy.
+ m_webPage->send(Messages::WebPageProxy::ScheduleChildWindowGeometryUpdate(geometry));
+}
+
+PassOwnPtr<GraphicsContext> DrawingAreaImpl::createGraphicsContext(ShareableBitmap* bitmap)
+{
+ HDC bitmapDC = bitmap->windowsContext();
+ // FIXME: We should really be checking m_webPage->draws[Transparent]Background() to determine
+ // whether to have an alpha channel or not. But currently we always render into a non-layered
+ // window, so the alpha channel doesn't matter anyway.
+ return adoptPtr(new GraphicsContext(bitmapDC, false));
+}
+
+} // namespace WebKit
+
diff --git a/Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp
new file mode 100644
index 000000000..57c04bbf0
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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 "LayerTreeHost.h"
+
+#if USE(CA)
+#include "LayerTreeHostCAWin.h"
+#endif
+
+namespace WebKit {
+
+bool LayerTreeHost::supportsAcceleratedCompositing()
+{
+#if USE(CA) && HAVE(WKQCA)
+ return LayerTreeHostCAWin::supportsAcceleratedCompositing();
+#else
+ return false;
+#endif
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp
new file mode 100644
index 000000000..5ada45d41
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "WebInspector.h"
+
+#if ENABLE(INSPECTOR)
+
+#include "WebKitBundle.h"
+#include <wtf/RetainPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+String WebInspector::localizedStringsURL() const
+{
+ RetainPtr<CFURLRef> localizedStringsURLRef(AdoptCF, CFBundleCopyResourceURL(webKitBundle(), CFSTR("localizedStrings"), CFSTR("js"), 0));
+ if (!localizedStringsURLRef)
+ return String();
+
+ return String(CFURLGetString(localizedStringsURLRef.get()));
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp
new file mode 100644
index 000000000..19f760f6a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp
@@ -0,0 +1,468 @@
+/*
+ * 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 "WebPage.h"
+
+#include "FontSmoothingLevel.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebEvent.h"
+#include "WebPageProxyMessages.h"
+#include "WebPreferencesStore.h"
+#include "WebProcess.h"
+#include <WebCore/FocusController.h>
+#include <WebCore/FontRenderingMode.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/HitTestRequest.h>
+#include <WebCore/HitTestResult.h>
+#include <WebCore/KeyboardEvent.h>
+#include <WebCore/Page.h>
+#include <WebCore/PlatformKeyboardEvent.h>
+#include <WebCore/RenderLayer.h>
+#include <WebCore/RenderView.h>
+#include <WebCore/ResourceHandle.h>
+#include <WebCore/Settings.h>
+#if USE(CG)
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+#endif
+#include <WinUser.h>
+
+#if USE(CFNETWORK)
+#include <CFNetwork/CFURLCachePriv.h>
+#include <CFNetwork/CFURLProtocolPriv.h>
+#include <CFNetwork/CFURLRequestPriv.h>
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void WebPage::platformInitialize()
+{
+}
+
+void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store)
+{
+ FontSmoothingLevel fontSmoothingLevel = static_cast<FontSmoothingLevel>(store.getUInt32ValueForKey(WebPreferencesKey::fontSmoothingLevelKey()));
+
+#if USE(CG)
+ FontSmoothingLevel adjustedLevel = fontSmoothingLevel;
+ if (adjustedLevel == FontSmoothingLevelWindows)
+ adjustedLevel = FontSmoothingLevelMedium;
+ wkSetFontSmoothingLevel(adjustedLevel);
+#endif
+
+ m_page->settings()->setFontRenderingMode(fontSmoothingLevel == FontSmoothingLevelWindows ? AlternateRenderingMode : NormalRenderingMode);
+}
+
+static const unsigned CtrlKey = 1 << 0;
+static const unsigned AltKey = 1 << 1;
+static const unsigned ShiftKey = 1 << 2;
+
+struct KeyDownEntry {
+ unsigned virtualKey;
+ unsigned modifiers;
+ const char* name;
+};
+
+struct KeyPressEntry {
+ unsigned charCode;
+ unsigned modifiers;
+ const char* name;
+};
+
+static const KeyDownEntry keyDownEntries[] = {
+ { VK_LEFT, 0, "MoveLeft" },
+ { VK_LEFT, ShiftKey, "MoveLeftAndModifySelection" },
+ { VK_LEFT, CtrlKey, "MoveWordLeft" },
+ { VK_LEFT, CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection" },
+ { VK_RIGHT, 0, "MoveRight" },
+ { VK_RIGHT, ShiftKey, "MoveRightAndModifySelection" },
+ { VK_RIGHT, CtrlKey, "MoveWordRight" },
+ { VK_RIGHT, CtrlKey | ShiftKey, "MoveWordRightAndModifySelection" },
+ { VK_UP, 0, "MoveUp" },
+ { VK_UP, ShiftKey, "MoveUpAndModifySelection" },
+ { VK_PRIOR, ShiftKey, "MovePageUpAndModifySelection" },
+ { VK_DOWN, 0, "MoveDown" },
+ { VK_DOWN, ShiftKey, "MoveDownAndModifySelection" },
+ { VK_NEXT, ShiftKey, "MovePageDownAndModifySelection" },
+ { VK_PRIOR, 0, "MovePageUp" },
+ { VK_NEXT, 0, "MovePageDown" },
+ { VK_HOME, 0, "MoveToBeginningOfLine" },
+ { VK_HOME, ShiftKey, "MoveToBeginningOfLineAndModifySelection" },
+ { VK_HOME, CtrlKey, "MoveToBeginningOfDocument" },
+ { VK_HOME, CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" },
+
+ { VK_END, 0, "MoveToEndOfLine" },
+ { VK_END, ShiftKey, "MoveToEndOfLineAndModifySelection" },
+ { VK_END, CtrlKey, "MoveToEndOfDocument" },
+ { VK_END, CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection" },
+
+ { VK_BACK, 0, "DeleteBackward" },
+ { VK_BACK, ShiftKey, "DeleteBackward" },
+ { VK_DELETE, 0, "DeleteForward" },
+ { VK_BACK, CtrlKey, "DeleteWordBackward" },
+ { VK_DELETE, CtrlKey, "DeleteWordForward" },
+
+ { 'B', CtrlKey, "ToggleBold" },
+ { 'I', CtrlKey, "ToggleItalic" },
+
+ { VK_ESCAPE, 0, "Cancel" },
+ { VK_OEM_PERIOD, CtrlKey, "Cancel" },
+ { VK_TAB, 0, "InsertTab" },
+ { VK_TAB, ShiftKey, "InsertBacktab" },
+ { VK_RETURN, 0, "InsertNewline" },
+ { VK_RETURN, CtrlKey, "InsertNewline" },
+ { VK_RETURN, AltKey, "InsertNewline" },
+ { VK_RETURN, ShiftKey, "InsertNewline" },
+ { VK_RETURN, AltKey | ShiftKey, "InsertNewline" },
+
+ // It's not quite clear whether clipboard shortcuts and Undo/Redo should be handled
+ // in the application or in WebKit. We chose WebKit.
+ { 'C', CtrlKey, "Copy" },
+ { 'V', CtrlKey, "Paste" },
+ { 'X', CtrlKey, "Cut" },
+ { 'A', CtrlKey, "SelectAll" },
+ { VK_INSERT, CtrlKey, "Copy" },
+ { VK_DELETE, ShiftKey, "Cut" },
+ { VK_INSERT, ShiftKey, "Paste" },
+ { 'Z', CtrlKey, "Undo" },
+ { 'Z', CtrlKey | ShiftKey, "Redo" },
+};
+
+static const KeyPressEntry keyPressEntries[] = {
+ { '\t', 0, "InsertTab" },
+ { '\t', ShiftKey, "InsertBacktab" },
+ { '\r', 0, "InsertNewline" },
+ { '\r', CtrlKey, "InsertNewline" },
+ { '\r', AltKey, "InsertNewline" },
+ { '\r', ShiftKey, "InsertNewline" },
+ { '\r', AltKey | ShiftKey, "InsertNewline" },
+};
+
+const char* WebPage::interpretKeyEvent(const KeyboardEvent* evt)
+{
+ ASSERT(evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
+
+ static HashMap<int, const char*>* keyDownCommandsMap = 0;
+ static HashMap<int, const char*>* keyPressCommandsMap = 0;
+
+ if (!keyDownCommandsMap) {
+ keyDownCommandsMap = new HashMap<int, const char*>;
+ keyPressCommandsMap = new HashMap<int, const char*>;
+
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyDownEntries); ++i)
+ keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
+
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyPressEntries); ++i)
+ keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
+ }
+
+ unsigned modifiers = 0;
+ if (evt->shiftKey())
+ modifiers |= ShiftKey;
+ if (evt->altKey())
+ modifiers |= AltKey;
+ if (evt->ctrlKey())
+ modifiers |= CtrlKey;
+
+ if (evt->type() == eventNames().keydownEvent) {
+ int mapKey = modifiers << 16 | evt->keyCode();
+ return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
+ }
+
+ int mapKey = modifiers << 16 | evt->charCode();
+ return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
+}
+
+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.isSystemKey())
+ return false;
+ if (keyboardEvent.shiftKey())
+ m_page->goForward();
+ else
+ m_page->goBack();
+ break;
+ case VK_LEFT:
+ if (keyboardEvent.isSystemKey())
+ m_page->goBack();
+ else
+ scroll(m_page.get(), ScrollLeft, ScrollByLine);
+ break;
+ case VK_RIGHT:
+ if (keyboardEvent.isSystemKey())
+ m_page->goForward();
+ else
+ scroll(m_page.get(), ScrollRight, ScrollByLine);
+ break;
+ case VK_UP:
+ if (keyboardEvent.isSystemKey())
+ return false;
+ scroll(m_page.get(), ScrollUp, ScrollByLine);
+ break;
+ case VK_DOWN:
+ if (keyboardEvent.isSystemKey())
+ return false;
+ scroll(m_page.get(), ScrollDown, ScrollByLine);
+ break;
+ case VK_HOME:
+ if (keyboardEvent.isSystemKey())
+ return false;
+ logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument);
+ break;
+ case VK_END:
+ if (keyboardEvent.isSystemKey())
+ return false;
+ logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument);
+ break;
+ case VK_PRIOR:
+ if (keyboardEvent.isSystemKey())
+ return false;
+ logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage);
+ break;
+ case VK_NEXT:
+ if (keyboardEvent.isSystemKey())
+ return false;
+ logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+#if USE(CFNETWORK)
+static RetainPtr<CFCachedURLResponseRef> cachedResponseForURL(WebPage* webPage, const KURL& url)
+{
+ RetainPtr<CFURLRef> cfURL(AdoptCF, url.createCFURL());
+ RetainPtr<CFMutableURLRequestRef> request(AdoptCF, CFURLRequestCreateMutable(0, cfURL.get(), kCFURLRequestCachePolicyReloadIgnoringCache, 60, 0));
+#if USE(CFURLSTORAGESESSIONS)
+ wkSetRequestStorageSession(ResourceHandle::currentStorageSession(), request.get());
+#endif
+
+ RetainPtr<CFStringRef> userAgent(AdoptCF, webPage->userAgent().createCFString());
+ CFURLRequestSetHTTPHeaderFieldValue(request.get(), CFSTR("User-Agent"), userAgent.get());
+
+ RetainPtr<CFURLCacheRef> cache;
+#if USE(CFURLSTORAGESESSIONS)
+ if (CFURLStorageSessionRef currentStorageSession = ResourceHandle::currentStorageSession())
+ cache.adoptCF(wkCopyURLCache(currentStorageSession));
+ else
+#endif
+ cache.adoptCF(CFURLCacheCopySharedURLCache());
+
+ RetainPtr<CFCachedURLResponseRef> response(AdoptCF, CFURLCacheCopyResponseForRequest(cache.get(), request.get()));
+ return response;
+}
+#endif
+
+bool WebPage::platformHasLocalDataForURL(const KURL& url)
+{
+#if USE(CFNETWORK)
+ return cachedResponseForURL(this, url);
+#else
+ return false;
+#endif
+}
+
+String WebPage::cachedResponseMIMETypeForURL(const KURL& url)
+{
+#if USE(CFNETWORK)
+ RetainPtr<CFCachedURLResponseRef> cachedResponse = cachedResponseForURL(this, url);
+ CFURLResponseRef response = CFCachedURLResponseGetWrappedResponse(cachedResponse.get());
+ return response ? CFURLResponseGetMIMEType(response) : String();
+#else
+ return String();
+#endif
+}
+
+String WebPage::cachedSuggestedFilenameForURL(const KURL& url)
+{
+#if USE(CFNETWORK)
+ RetainPtr<CFCachedURLResponseRef> cachedResponse = cachedResponseForURL(this, url);
+ CFURLResponseRef response = CFCachedURLResponseGetWrappedResponse(cachedResponse.get());
+ if (!response)
+ return String();
+ RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(response));
+
+ return suggestedFilename.get();
+#else
+ return String();
+#endif
+}
+
+PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL& url)
+{
+#if USE(CFNETWORK)
+ RetainPtr<CFCachedURLResponseRef> cachedResponse = cachedResponseForURL(this, url);
+ CFDataRef data = CFCachedURLResponseGetReceiverData(cachedResponse.get());
+ if (!data)
+ return 0;
+
+ return SharedBuffer::wrapCFData(data);
+#else
+ return 0;
+#endif
+}
+
+bool WebPage::platformCanHandleRequest(const WebCore::ResourceRequest& request)
+{
+#if USE(CFNETWORK)
+ return CFURLProtocolCanHandleRequest(request.cfURLRequest());
+#else
+ return true;
+#endif
+}
+
+void WebPage::confirmComposition(const String& compositionString)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame || !frame->editor()->canEdit())
+ return;
+ frame->editor()->confirmComposition(compositionString);
+}
+
+void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame || !frame->editor()->canEdit())
+ return;
+ frame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
+}
+
+void WebPage::firstRectForCharacterInSelectedRange(const uint64_t characterPosition, WebCore::IntRect& resultRect)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ IntRect rect;
+ if (RefPtr<Range> range = frame->editor()->hasComposition() ? frame->editor()->compositionRange() : frame->selection()->selection().toNormalizedRange()) {
+ ExceptionCode ec = 0;
+ RefPtr<Range> tempRange = range->cloneRange(ec);
+ tempRange->setStart(tempRange->startContainer(ec), tempRange->startOffset(ec) + characterPosition, ec);
+ rect = frame->editor()->firstRectForRange(tempRange.get());
+ }
+ resultRect = frame->view()->contentsToWindow(rect);
+}
+
+void WebPage::getSelectedText(String& text)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
+ text = selectedRange->text();
+}
+
+void WebPage::gestureWillBegin(const WebCore::IntPoint& point, bool& canBeginPanning)
+{
+ m_gestureReachedScrollingLimit = false;
+
+ bool hitScrollbar = false;
+
+ HitTestRequest request(HitTestRequest::ReadOnly);
+ for (Frame* childFrame = m_page->mainFrame(); childFrame; childFrame = EventHandler::subframeForTargetNode(m_gestureTargetNode.get())) {
+ ScrollView* scollView = childFrame->view();
+ if (!scollView)
+ break;
+
+ RenderView* renderView = childFrame->document()->renderView();
+ if (!renderView)
+ break;
+
+ RenderLayer* layer = renderView->layer();
+ if (!layer)
+ break;
+
+ HitTestResult result = scollView->windowToContents(point);
+ layer->hitTest(request, result);
+ m_gestureTargetNode = result.innerNode();
+
+ if (!hitScrollbar)
+ hitScrollbar = result.scrollbar();
+ }
+
+ if (hitScrollbar) {
+ canBeginPanning = false;
+ return;
+ }
+
+ if (!m_gestureTargetNode) {
+ canBeginPanning = false;
+ return;
+ }
+
+ for (RenderObject* renderer = m_gestureTargetNode->renderer(); renderer; renderer = renderer->parent()) {
+ if (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) {
+ canBeginPanning = true;
+ return;
+ }
+ }
+
+ canBeginPanning = false;
+}
+
+static bool scrollbarAtTopOrBottomOfDocument(Scrollbar* scrollbar)
+{
+ ASSERT_ARG(scrollbar, scrollbar);
+ return !scrollbar->currentPos() || scrollbar->currentPos() >= scrollbar->maximum();
+}
+
+void WebPage::gestureDidScroll(const IntSize& size)
+{
+ ASSERT_ARG(size, !size.isZero());
+
+ if (!m_gestureTargetNode || !m_gestureTargetNode->renderer() || !m_gestureTargetNode->renderer()->enclosingLayer())
+ return;
+
+ Scrollbar* verticalScrollbar = 0;
+ if (Frame* frame = m_page->mainFrame()) {
+ if (ScrollView* view = frame->view())
+ verticalScrollbar = view->verticalScrollbar();
+ }
+
+ m_gestureTargetNode->renderer()->enclosingLayer()->scrollByRecursively(size.width(), size.height());
+ bool gestureReachedScrollingLimit = verticalScrollbar && scrollbarAtTopOrBottomOfDocument(verticalScrollbar);
+
+ // FIXME: We really only want to update this state if the state was updated via scrolling the main frame,
+ // not scrolling something in a main frame when the main frame had already reached its scrolling limit.
+
+ if (gestureReachedScrollingLimit == m_gestureReachedScrollingLimit)
+ return;
+
+ send(Messages::WebPageProxy::SetGestureReachedScrollingLimit(gestureReachedScrollingLimit));
+ m_gestureReachedScrollingLimit = gestureReachedScrollingLimit;
+}
+
+void WebPage::gestureDidEnd()
+{
+ m_gestureTargetNode = nullptr;
+}
+
+} // namespace WebKit