diff options
Diffstat (limited to 'Source/WebKit2/WebProcess/WebPage')
52 files changed, 8324 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.cpp new file mode 100644 index 0000000..513621c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.cpp @@ -0,0 +1,221 @@ +/* + * 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 "ChunkedUpdateDrawingArea.h" + +#include "DrawingAreaMessageKinds.h" +#include "DrawingAreaProxyMessageKinds.h" +#include "MessageID.h" +#include "UpdateChunk.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebProcess.h" + +using namespace WebCore; + +namespace WebKit { + +ChunkedUpdateDrawingArea::ChunkedUpdateDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : DrawingArea(DrawingAreaInfo::ChunkedUpdate, identifier, webPage) + , m_isWaitingForUpdate(false) + , m_paintingIsSuspended(false) + , m_displayTimer(WebProcess::shared().runLoop(), this, &ChunkedUpdateDrawingArea::display) +{ +} + +ChunkedUpdateDrawingArea::~ChunkedUpdateDrawingArea() +{ +} + +void ChunkedUpdateDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + // FIXME: Do something much smarter. + setNeedsDisplay(scrollRect); +} + +void ChunkedUpdateDrawingArea::setNeedsDisplay(const IntRect& rect) +{ + // FIXME: Collect a set of rects/region instead of just the union + // of all rects. + m_dirtyRect.unite(rect); + scheduleDisplay(); +} + +void ChunkedUpdateDrawingArea::display() +{ + ASSERT(!m_isWaitingForUpdate); + + if (m_paintingIsSuspended) + return; + + if (m_dirtyRect.isEmpty()) + return; + + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<ChunkedUpdateDrawingArea> protect(this); + + // Layout if necessary. + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; + + IntRect dirtyRect = m_dirtyRect; + m_dirtyRect = IntRect(); + + // Create a new UpdateChunk and paint into it. + UpdateChunk updateChunk(dirtyRect); + paintIntoUpdateChunk(&updateChunk); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::Update, m_webPage->pageID(), CoreIPC::In(updateChunk)); + + m_isWaitingForUpdate = true; + m_displayTimer.stop(); +} + +void ChunkedUpdateDrawingArea::scheduleDisplay() +{ + if (m_paintingIsSuspended) + return; + + if (m_isWaitingForUpdate) + return; + + if (m_dirtyRect.isEmpty()) + return; + + if (m_displayTimer.isActive()) + return; + + m_displayTimer.startOneShot(0); +} + +void ChunkedUpdateDrawingArea::setSize(const IntSize& viewSize) +{ + ASSERT_ARG(viewSize, !viewSize.isEmpty()); + + // We don't want to wait for an update until we display. + m_isWaitingForUpdate = false; + + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<ChunkedUpdateDrawingArea> protect(this); + + m_webPage->setSize(viewSize); + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; + + if (m_paintingIsSuspended) { + ASSERT(!m_displayTimer.isActive()); + + // Painting is suspended, just send back an empty update chunk. + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(UpdateChunk())); + return; + } + + // Create a new UpdateChunk and paint into it. + UpdateChunk updateChunk(IntRect(0, 0, viewSize.width(), viewSize.height())); + paintIntoUpdateChunk(&updateChunk); + + m_displayTimer.stop(); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(updateChunk)); +} + +void ChunkedUpdateDrawingArea::suspendPainting() +{ + ASSERT(!m_paintingIsSuspended); + + m_paintingIsSuspended = true; + m_displayTimer.stop(); +} + +void ChunkedUpdateDrawingArea::resumePainting(bool forceRepaint) +{ + ASSERT(m_paintingIsSuspended); + + m_paintingIsSuspended = false; + + if (forceRepaint) { + // Just set the dirty rect to the entire page size. + m_dirtyRect = IntRect(IntPoint(0, 0), m_webPage->size()); + } + + // Schedule a display. + scheduleDisplay(); +} + +void ChunkedUpdateDrawingArea::didUpdate() +{ + m_isWaitingForUpdate = false; + + // Display if needed. + display(); +} + +void ChunkedUpdateDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + DrawingAreaInfo::Identifier targetIdentifier; + if (!arguments->decode(CoreIPC::Out(targetIdentifier))) + return; + + // We can switch drawing areas on the fly, so if this message was targetted at an obsolete drawing area, ignore it. + if (targetIdentifier != info().identifier) + return; + + switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) { + case DrawingAreaLegacyMessage::SetSize: { + IntSize size; + if (!arguments->decode(CoreIPC::Out(size))) + return; + + setSize(size); + break; + } + + case DrawingAreaLegacyMessage::SuspendPainting: + suspendPainting(); + break; + + case DrawingAreaLegacyMessage::ResumePainting: { + bool forceRepaint; + if (!arguments->decode(CoreIPC::Out(forceRepaint))) + return; + + resumePainting(forceRepaint); + break; + } + case DrawingAreaLegacyMessage::DidUpdate: + didUpdate(); + break; + + default: + ASSERT_NOT_REACHED(); + break; + } +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.h new file mode 100644 index 0000000..ac4b424 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.h @@ -0,0 +1,76 @@ +/* + * 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 ChunkedUpdateDrawingArea_h +#define ChunkedUpdateDrawingArea_h + +#include "DrawingArea.h" +#include "RunLoop.h" +#include <WebCore/IntPoint.h> + +namespace WebKit { + +class UpdateChunk; + +class ChunkedUpdateDrawingArea : public DrawingArea { +public: + ChunkedUpdateDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage*); + virtual ~ChunkedUpdateDrawingArea(); + + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta); + virtual void display(); + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachCompositingContext() { } + virtual void detachCompositingContext() { } + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) { } + virtual void scheduleCompositingLayerSync() { } + virtual void syncCompositingLayers() { } +#endif + + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + void scheduleDisplay(); + + // CoreIPC message handlers. + void setSize(const WebCore::IntSize& viewSize); + void suspendPainting(); + void resumePainting(bool forceRepaint); + void didUpdate(); + + // Platform overrides + void paintIntoUpdateChunk(UpdateChunk*); + + WebCore::IntRect m_dirtyRect; + bool m_isWaitingForUpdate; + bool m_paintingIsSuspended; + RunLoop::Timer<ChunkedUpdateDrawingArea> m_displayTimer; +}; + +} // namespace WebKit + +#endif // ChunkedUpdateDrawingArea_h diff --git a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp new file mode 100644 index 0000000..e5de52f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp @@ -0,0 +1,82 @@ +/* + * 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 "DecoderAdapter.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) +{ + return m_decoder.decodeBytes(bytes); +} + +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 0000000..bd34ea8 --- /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 0000000..3b76aaf --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp @@ -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. + */ + +#include "DrawingArea.h" + +// Subclasses +#include "ChunkedUpdateDrawingArea.h" + +#ifdef __APPLE__ +#include "DrawingAreaImpl.h" +#endif + +#if USE(ACCELERATED_COMPOSITING) +#include "LayerBackedDrawingArea.h" +#endif + +#if ENABLE(TILED_BACKING_STORE) +#include "TiledDrawingArea.h" +#endif + +namespace WebKit { + +PassRefPtr<DrawingArea> DrawingArea::create(DrawingAreaInfo::Type type, DrawingAreaInfo::Identifier identifier, WebPage* webPage) +{ + switch (type) { + case DrawingAreaInfo::None: + ASSERT_NOT_REACHED(); + break; + + case DrawingAreaInfo::Impl: +#ifdef __APPLE__ + return DrawingAreaImpl::create(identifier, webPage); +#else + return 0; +#endif + case DrawingAreaInfo::ChunkedUpdate: + return adoptRef(new ChunkedUpdateDrawingArea(identifier, webPage)); + +#if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC) + case DrawingAreaInfo::LayerBacked: + return adoptRef(new LayerBackedDrawingArea(identifier, webPage)); +#endif +#if ENABLE(TILED_BACKING_STORE) + case DrawingAreaInfo::Tiled: + return adoptRef(new TiledDrawingArea(identifier, webPage)); +#endif + } + + return 0; +} + +DrawingArea::DrawingArea(DrawingAreaInfo::Type type, DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : m_info(type, identifier) + , 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 0000000..75f0b00 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.h @@ -0,0 +1,88 @@ +/* + * 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/IntRect.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace WebCore { +#if USE(ACCELERATED_COMPOSITING) + class GraphicsLayer; +#endif +} + +namespace WebKit { + +class WebPage; + +class DrawingArea : public RefCounted<DrawingArea> { +public: + // FIXME: It might make sense to move this create function into a factory style class. + static PassRefPtr<DrawingArea> create(DrawingAreaInfo::Type, DrawingAreaInfo::Identifier, WebPage*); + virtual ~DrawingArea(); + +#ifdef __APPLE__ + void didReceiveDrawingAreaMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); +#endif + + virtual void setNeedsDisplay(const WebCore::IntRect&) = 0; + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta) = 0; + + virtual void pageBackgroundTransparencyChanged() { } + + virtual void onPageClose() { } + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachCompositingContext() = 0; + virtual void detachCompositingContext() = 0; + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) = 0; + virtual void scheduleCompositingLayerSync() = 0; + virtual void syncCompositingLayers() = 0; +#endif + + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*) = 0; + + const DrawingAreaInfo& info() const { return m_info; } + +protected: + DrawingArea(DrawingAreaInfo::Type, DrawingAreaInfo::Identifier, WebPage*); + + DrawingAreaInfo m_info; + WebPage* m_webPage; + +private: + // CoreIPC message handlers. + // FIXME: These should be pure virtual. + virtual void setSize(const WebCore::IntSize&) { } + virtual void didUpdate() { } +}; + +} // 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 0000000..6c628fb --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in @@ -0,0 +1,26 @@ +# 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 { + SetSize(WebCore::IntSize size) + DidUpdate() +} diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp new file mode 100644 index 0000000..ab4655a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp @@ -0,0 +1,247 @@ +/* + * 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 "DrawingAreaImpl.h" + +#include "DrawingAreaProxyMessages.h" +#include "ShareableBitmap.h" +#include "UpdateInfo.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/GraphicsContext.h> + +#ifndef __APPLE__ +#error "This drawing area is not ready for use by other ports yet." +#endif + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<DrawingAreaImpl> DrawingAreaImpl::create(DrawingAreaInfo::Identifier identifier, WebPage* webPage) +{ + return adoptRef(new DrawingAreaImpl(identifier, webPage)); +} + +DrawingAreaImpl::~DrawingAreaImpl() +{ +} + +DrawingAreaImpl::DrawingAreaImpl(DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : DrawingArea(DrawingAreaInfo::Impl, identifier, webPage) + , m_isWaitingForDidUpdate(false) + , m_displayTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::display) +{ +} + +void DrawingAreaImpl::setNeedsDisplay(const IntRect& rect) +{ + if (rect.isEmpty()) + return; + + m_dirtyRegion.unite(rect); + scheduleDisplay(); +} + +void DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + 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_scrollDelta = 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, scrollDelta), scrollRect); + + // And add them back. + m_dirtyRegion.unite(movedDirtyRegionInScrollRect); + } + + // Compute the scroll repaint region. + Region scrollRepaintRegion = subtract(scrollRect, translate(scrollRect, scrollDelta)); + + m_dirtyRegion.unite(scrollRepaintRegion); + + m_scrollRect = scrollRect; + m_scrollDelta += scrollDelta; +} + +void DrawingAreaImpl::attachCompositingContext() +{ +} + +void DrawingAreaImpl::detachCompositingContext() +{ +} + +void DrawingAreaImpl::setRootCompositingLayer(WebCore::GraphicsLayer*) +{ +} + +void DrawingAreaImpl::scheduleCompositingLayerSync() +{ +} + +void DrawingAreaImpl::syncCompositingLayers() +{ +} + +void DrawingAreaImpl::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*) +{ +} + +void DrawingAreaImpl::setSize(const IntSize& size) +{ + // Set this to false since we're about to call display(). + m_isWaitingForDidUpdate = false; + + m_webPage->setSize(size); + m_webPage->layoutIfNeeded(); + + // FIXME: Repaint. + + m_webPage->send(Messages::DrawingAreaProxy::DidSetSize()); +} + +void DrawingAreaImpl::didUpdate() +{ + m_isWaitingForDidUpdate = false; + + // Display if needed. + display(); +} + +void DrawingAreaImpl::scheduleDisplay() +{ + if (m_isWaitingForDidUpdate) + return; + + if (m_dirtyRegion.isEmpty()) + return; + + if (m_displayTimer.isActive()) + return; + + m_displayTimer.startOneShot(0); +} + +void DrawingAreaImpl::display() +{ + if (m_dirtyRegion.isEmpty()) + return; + + UpdateInfo updateInfo; + display(updateInfo); + + m_webPage->send(Messages::DrawingAreaProxy::Update(updateInfo)); + m_isWaitingForDidUpdate = true; +} + +static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>& rects) +{ + const size_t rectThreshold = 10; + const float wastedSpaceThreshold = 0.75f; + + 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(); + + float wastedSpace = 1 - (rectsArea / boundsArea); + + return wastedSpace <= wastedSpaceThreshold; +} + +void DrawingAreaImpl::display(UpdateInfo& updateInfo) +{ + // FIXME: It would be better if we could avoid painting altogether when there is a custom representation. + if (m_webPage->mainFrameHasCustomRepresentation()) + return; + + IntRect bounds = m_dirtyRegion.bounds(); + Vector<IntRect> rects = m_dirtyRegion.rects(); + + if (shouldPaintBoundsRect(bounds, rects)) { + rects.clear(); + rects.append(bounds); + } + + updateInfo.scrollRect = m_scrollRect; + updateInfo.scrollDelta = m_scrollDelta; + + m_dirtyRegion = Region(); + m_scrollRect = IntRect(); + m_scrollDelta = IntSize(); + + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bounds.size()); + if (!bitmap->createHandle(updateInfo.bitmapHandle)) + return; + + OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); + + m_webPage->layoutIfNeeded(); + + updateInfo.viewSize = m_webPage->size(); + updateInfo.updateRectBounds = bounds; + + graphicsContext->translate(-bounds.x(), -bounds.y()); + + for (size_t i = 0; i < rects.size(); ++i) { + m_webPage->drawRect(*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(); +} + + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h new file mode 100644 index 0000000..1f1b2e2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h @@ -0,0 +1,76 @@ +/* + * 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 "Region.h" +#include "RunLoop.h" + +namespace WebKit { + +struct UpdateInfo; + +class DrawingAreaImpl : public DrawingArea { +public: + static PassRefPtr<DrawingAreaImpl> create(DrawingAreaInfo::Identifier, WebPage*); + virtual ~DrawingAreaImpl(); + +private: + DrawingAreaImpl(DrawingAreaInfo::Identifier, WebPage*); + + // DrawingArea + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta); + virtual void attachCompositingContext(); + virtual void detachCompositingContext(); + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*); + virtual void scheduleCompositingLayerSync(); + virtual void syncCompositingLayers(); + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + // CoreIPC message handlers. + virtual void setSize(const WebCore::IntSize&); + virtual void didUpdate(); + + void scheduleDisplay(); + void display(); + void display(UpdateInfo&); + + Region m_dirtyRegion; + WebCore::IntRect m_scrollRect; + WebCore::IntSize m_scrollDelta; + + // 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; + + RunLoop::Timer<DrawingAreaImpl> m_displayTimer; +}; + +} // 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 0000000..00edcce --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp @@ -0,0 +1,88 @@ +/* + * 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 "EncoderAdapter.h" + +#include "DataReference.h" +#include "WebCoreArgumentCoders.h" + +namespace WebKit { + +EncoderAdapter::EncoderAdapter() + : m_encoder(CoreIPC::ArgumentEncoder::create(0)) +{ +} + +CoreIPC::DataReference EncoderAdapter::data() const +{ + return CoreIPC::DataReference(m_encoder->buffer(), m_encoder->bufferSize()); +} + +void EncoderAdapter::encodeBytes(const uint8_t* bytes, size_t size) +{ + m_encoder->encodeBytes(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 0000000..ae88a98 --- /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 data() 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/FindController.cpp b/Source/WebKit2/WebProcess/WebPage/FindController.cpp new file mode 100644 index 0000000..9b8669d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/FindController.cpp @@ -0,0 +1,300 @@ +/* + * 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 "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/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/Page.h> + +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) +{ + unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount); + m_webPage->corePage()->unmarkAllTextMatches(); + + 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) { + 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); + } + + 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); + + hideFindIndicator(); +} + +bool FindController::updateFindIndicator(Frame* selectedFrame, bool isShowingOverlay) +{ + if (!selectedFrame) + return false; + + // We want the selection rect in window coordinates. + IntRect selectionRectInWindowCoordinates = selectedFrame->view()->contentsToWindow(enclosingIntRect(selectedFrame->selection()->bounds())); + + Vector<FloatRect> textRects; + selectedFrame->selection()->getClippedVisibleTextRectangles(textRects); + + // Create a backing store and paint the find indicator text into it. + RefPtr<ShareableBitmap> findIndicatorTextBackingStore = ShareableBitmap::createShareable(selectionRectInWindowCoordinates.size()); + OwnPtr<GraphicsContext> graphicsContext = findIndicatorTextBackingStore->createGraphicsContext(); + + graphicsContext->translate(-selectionRectInWindowCoordinates.x(), -selectionRectInWindowCoordinates.y()); + selectedFrame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorForceBlackText | PaintBehaviorFlattenCompositingLayers); + selectedFrame->document()->updateLayout(); + + graphicsContext->clip(selectionRectInWindowCoordinates); + selectedFrame->view()->paint(graphicsContext.get(), selectionRectInWindowCoordinates); + selectedFrame->view()->setPaintBehavior(PaintBehaviorNormal); + + SharedMemory::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, handle, !isShowingOverlay)); + m_isShowingFindIndicator = true; + + return true; +} + +void FindController::hideFindIndicator() +{ + if (!m_isShowingFindIndicator) + return; + + SharedMemory::Handle handle; + m_webPage->send(Messages::WebPageProxy::SetFindIndicator(FloatRect(), Vector<FloatRect>(), handle, false)); + m_isShowingFindIndicator = 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 int overlayBackgroundRed = 25; +static const int overlayBackgroundGreen = 25; +static const int overlayBackgroundBlue = 25; +static const int overlayBackgroundAlpha = 63; + +static Color overlayBackgroundColor() +{ + return Color(overlayBackgroundRed, overlayBackgroundGreen, overlayBackgroundBlue, overlayBackgroundAlpha); +} + +void FindController::drawRect(PageOverlay*, GraphicsContext& graphicsContext, const IntRect& dirtyRect) +{ + Vector<IntRect> rects = rectsForTextMatches(); + ASSERT(!rects.isEmpty()); + + // Draw the background. + graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(), ColorSpaceSRGB); + + graphicsContext.save(); + graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color::black, ColorSpaceSRGB); + + graphicsContext.setFillColor(Color::white, 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.restore(); + + 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 0000000..110a7a4 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/FindController.h @@ -0,0 +1,79 @@ +/* + * 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(); + +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); + +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/LayerBackedDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.cpp new file mode 100644 index 0000000..8a81cca --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.cpp @@ -0,0 +1,230 @@ +/* + * 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 USE(ACCELERATED_COMPOSITING) + +#include "LayerBackedDrawingArea.h" + +#include "DrawingAreaMessageKinds.h" +#include "DrawingAreaProxyMessageKinds.h" +#include "MessageID.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/GraphicsLayer.h> + +using namespace WebCore; + +namespace WebKit { + +LayerBackedDrawingArea::LayerBackedDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : DrawingArea(DrawingAreaInfo::LayerBacked, identifier, webPage) + , m_syncTimer(WebProcess::shared().runLoop(), this, &LayerBackedDrawingArea::syncCompositingLayers) + , m_attached(false) + , m_shouldPaint(true) +{ + m_backingLayer = GraphicsLayer::create(this); + m_backingLayer->setDrawsContent(true); + m_backingLayer->setContentsOpaque(webPage->drawsBackground() && !webPage->drawsTransparentBackground()); + +#ifndef NDEBUG + m_backingLayer->setName("DrawingArea backing layer"); +#endif + m_backingLayer->setSize(webPage->size()); + platformInit(); +} + +LayerBackedDrawingArea::~LayerBackedDrawingArea() +{ + platformClear(); +} + +void LayerBackedDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + // FIXME: Do something much smarter. + setNeedsDisplay(scrollRect); +} + +void LayerBackedDrawingArea::setNeedsDisplay(const IntRect& rect) +{ + m_backingLayer->setNeedsDisplayInRect(rect); + scheduleCompositingLayerSync(); +} + +void LayerBackedDrawingArea::display() +{ + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<LayerBackedDrawingArea> protect(this); + + // Layout if necessary. + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; +} + +void LayerBackedDrawingArea::pageBackgroundTransparencyChanged() +{ + m_backingLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); +} + +void LayerBackedDrawingArea::scheduleDisplay() +{ +} + +void LayerBackedDrawingArea::setSize(const IntSize& viewSize) +{ + ASSERT(m_shouldPaint); + ASSERT_ARG(viewSize, !viewSize.isEmpty()); + + m_backingLayer->setSize(viewSize); + scheduleCompositingLayerSync(); + + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<LayerBackedDrawingArea> protect(this); + + m_webPage->setSize(viewSize); + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(viewSize)); +} + +void LayerBackedDrawingArea::suspendPainting() +{ + ASSERT(m_shouldPaint); + + m_shouldPaint = false; +} + +void LayerBackedDrawingArea::resumePainting() +{ + ASSERT(!m_shouldPaint); + + m_shouldPaint = true; + + // Display if needed. + display(); +} + +void LayerBackedDrawingArea::didUpdate() +{ + // Display if needed. + display(); +} + +void LayerBackedDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + DrawingAreaInfo::Identifier targetIdentifier; + if (!arguments->decode(CoreIPC::Out(targetIdentifier))) + return; + + // We can switch drawing areas on the fly, so if this message was targetted at an obsolete drawing area, ignore it. + if (targetIdentifier != info().identifier) + return; + + switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) { + case DrawingAreaLegacyMessage::SetSize: { + IntSize size; + if (!arguments->decode(CoreIPC::Out(size))) + return; + + setSize(size); + break; + } + + case DrawingAreaLegacyMessage::SuspendPainting: + suspendPainting(); + break; + + case DrawingAreaLegacyMessage::ResumePainting: + resumePainting(); + break; + + case DrawingAreaLegacyMessage::DidUpdate: + didUpdate(); + break; + + default: + ASSERT_NOT_REACHED(); + break; + } +} + +// GraphicsLayerClient methods +void LayerBackedDrawingArea::paintContents(const GraphicsLayer*, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& inClip) +{ + m_webPage->drawRect(graphicsContext, inClip); +} + +bool LayerBackedDrawingArea::showDebugBorders() const +{ + // FIXME: get from settings; + return false; +} + +bool LayerBackedDrawingArea::showRepaintCounter() const +{ + // FIXME: get from settings; + return false; +} + +#if !PLATFORM(MAC) && !PLATFORM(WIN) +void LayerBackedDrawingArea::attachCompositingContext(GraphicsLayer*) +{ +} + +void LayerBackedDrawingArea::detachCompositingContext() +{ +} + +#if !PLATFORM(MAC) +void LayerBackedDrawingArea::setRootCompositingLayer(WebCore::GraphicsLayer*) +{ +} +#endif + +void LayerBackedDrawingArea::scheduleCompositingLayerSync() +{ +} + +void LayerBackedDrawingArea::syncCompositingLayers() +{ +} + +void LayerBackedDrawingArea::platformInit() +{ +} + +void LayerBackedDrawingArea::platformClear() +{ +} +#endif + +} // namespace WebKit + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.h new file mode 100644 index 0000000..1b49de2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.h @@ -0,0 +1,125 @@ +/* + * 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 LayerBackedDrawingArea_h +#define LayerBackedDrawingArea_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "DrawingArea.h" +#include "RunLoop.h" +#include <WebCore/IntPoint.h> +#include <WebCore/GraphicsLayerClient.h> + +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> +#ifdef __OBJC__ +@class CALayer; +#else +class CALayer; +#endif +typedef struct __WKCARemoteLayerClientRef *WKCARemoteLayerClientRef; +#endif + +namespace WebCore { + class GraphicsContext; + class GraphicsLayer; +} + +namespace WebKit { + +class LayerBackedDrawingArea : public DrawingArea, private WebCore::GraphicsLayerClient { +public: + LayerBackedDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage*); + virtual ~LayerBackedDrawingArea(); + + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta); + virtual void display(); + + virtual void pageBackgroundTransparencyChanged(); + + virtual void attachCompositingContext(); + virtual void detachCompositingContext(); + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*); + virtual void scheduleCompositingLayerSync(); + virtual void syncCompositingLayers(); + + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + + // GraphicsLayerClient + virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double /*time*/) { } + virtual void notifySyncRequired(const WebCore::GraphicsLayer*) { } +public: + virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& inClip); +private: + virtual bool showDebugBorders() const; + virtual bool showRepaintCounter() const; + +#if PLATFORM(MAC) + virtual void onPageClose(); +#endif + + void scheduleDisplay(); + + // CoreIPC message handlers. + void setSize(const WebCore::IntSize& viewSize); + void suspendPainting(); + void resumePainting(); + void didUpdate(); + + void platformInit(); + void platformClear(); + +#if PLATFORM(MAC) + void setUpUpdateLayoutRunLoopObserver(); + void scheduleUpdateLayoutRunLoopObserver(); + void removeUpdateLayoutRunLoopObserver(); + + static void updateLayoutRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*); + void updateLayoutRunLoopObserverFired(); +#endif + + RunLoop::Timer<LayerBackedDrawingArea> m_syncTimer; + + OwnPtr<WebCore::GraphicsLayer> m_backingLayer; +#if PLATFORM(MAC) +#if HAVE(HOSTED_CORE_ANIMATION) + RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerRef; +#endif + RetainPtr<CFRunLoopObserverRef> m_updateLayoutRunLoopObserver; +#endif + + bool m_attached; + bool m_shouldPaint; +}; + +} // namespace WebKit + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif // LayerBackedDrawingArea_h diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp new file mode 100644 index 0000000..091f460 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp @@ -0,0 +1,111 @@ +/* + * 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 "PageOverlay.h" + +#include "WebPage.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/Page.h> + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<PageOverlay> PageOverlay::create(Client* client) +{ + return adoptRef(new PageOverlay(client)); +} + +PageOverlay::PageOverlay(Client* client) + : m_client(client) + , m_webPage(0) +{ +} + +PageOverlay::~PageOverlay() +{ +} + +IntRect PageOverlay::bounds() const +{ + FrameView* frameView = webPage()->corePage()->mainFrame()->view(); + + int width = frameView->width(); + if (frameView->verticalScrollbar()) + width -= frameView->verticalScrollbar()->width(); + int height = frameView->height(); + 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); +} + +void PageOverlay::setNeedsDisplay(const WebCore::IntRect& dirtyRect) +{ + if (m_webPage) + m_webPage->drawingArea()->setNeedsDisplay(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; + + graphicsContext.save(); + graphicsContext.beginTransparencyLayer(1); + graphicsContext.setCompositeOperation(CompositeCopy); + + m_client->drawRect(this, graphicsContext, paintRect); + + graphicsContext.endTransparencyLayer(); + graphicsContext.restore(); +} + +bool PageOverlay::mouseEvent(const WebMouseEvent& mouseEvent) +{ + // Ignore events outside the bounds. + if (!bounds().contains(mouseEvent.position())) + return false; + + return m_client->mouseEvent(this, mouseEvent); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.h b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h new file mode 100644 index 0000000..6f1f70f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h @@ -0,0 +1,86 @@ +/* + * 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 <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&); + +protected: + explicit PageOverlay(Client*); + + WebPage* webPage() const { return m_webPage; } + +private: + // APIObject + virtual Type type() const { return APIType; } + + WebCore::IntRect bounds() const; + + Client* m_client; + + WebPage* m_webPage; +}; + +} // namespace WebKit + +#endif // PageOverlay_h diff --git a/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp new file mode 100644 index 0000000..74aa4b2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp @@ -0,0 +1,235 @@ +/* + * 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. + */ + +#if ENABLE(TILED_BACKING_STORE) + +#include "TiledDrawingArea.h" + +#include "DrawingAreaMessageKinds.h" +#include "DrawingAreaProxyMessageKinds.h" +#include "MessageID.h" +#include "UpdateChunk.h" +#include "WebCore/Frame.h" +#include "WebCore/FrameView.h" +#include "WebCoreArgumentCoders.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebProcess.h" + +using namespace WebCore; + +namespace WebKit { + +TiledDrawingArea::TiledDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : DrawingArea(DrawingAreaInfo::Tiled, identifier, webPage) + , m_isWaitingForUpdate(false) + , m_shouldPaint(true) + , m_displayTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::display) + , m_tileUpdateTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::tileUpdateTimerFired) +{ +} + +TiledDrawingArea::~TiledDrawingArea() +{ +} + +void TiledDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + // FIXME: Do something much smarter. + setNeedsDisplay(scrollRect); +} + +void TiledDrawingArea::setNeedsDisplay(const IntRect& rect) +{ + // FIXME: Collect a set of rects/region instead of just the union of all rects. + m_dirtyRect.unite(rect); + scheduleDisplay(); +} + +void TiledDrawingArea::display() +{ + if (!m_shouldPaint) + return; + + if (m_dirtyRect.isEmpty()) + return; + + m_webPage->layoutIfNeeded(); + + IntRect dirtyRect = m_dirtyRect; + m_dirtyRect = IntRect(); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::Invalidate, m_webPage->pageID(), CoreIPC::In(dirtyRect)); + + m_displayTimer.stop(); +} + +void TiledDrawingArea::scheduleDisplay() +{ + if (!m_shouldPaint) + return; + + if (m_displayTimer.isActive()) + return; + + m_displayTimer.startOneShot(0); +} + +void TiledDrawingArea::setSize(const IntSize& viewSize) +{ + ASSERT(m_shouldPaint); + ASSERT_ARG(viewSize, !viewSize.isEmpty()); + + m_webPage->setSize(viewSize); + + scheduleDisplay(); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(viewSize)); +} + +void TiledDrawingArea::suspendPainting() +{ + ASSERT(m_shouldPaint); + + m_shouldPaint = false; + m_displayTimer.stop(); +} + +void TiledDrawingArea::resumePainting() +{ + ASSERT(!m_shouldPaint); + + m_shouldPaint = true; + + // Display if needed. + display(); +} + +void TiledDrawingArea::didUpdate() +{ + // Display if needed. + display(); +} + +void TiledDrawingArea::updateTile(int tileID, const IntRect& dirtyRect, float scale) +{ + m_webPage->layoutIfNeeded(); + + UpdateChunk updateChunk(dirtyRect); + paintIntoUpdateChunk(&updateChunk, scale); + + unsigned pendingUpdateCount = m_pendingUpdates.size(); + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::TileUpdated, m_webPage->pageID(), CoreIPC::In(tileID, updateChunk, scale, pendingUpdateCount)); +} + +void TiledDrawingArea::tileUpdateTimerFired() +{ + ASSERT(!m_pendingUpdates.isEmpty()); + + UpdateMap::iterator it = m_pendingUpdates.begin(); + TileUpdate update = it->second; + m_pendingUpdates.remove(it); + + updateTile(update.tileID, update.dirtyRect, update.scale); + + if (m_pendingUpdates.isEmpty()) + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In()); + else + m_tileUpdateTimer.startOneShot(0.001); +} + +void TiledDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) { + case DrawingAreaLegacyMessage::SetSize: { + IntSize size; + if (!arguments->decode(CoreIPC::Out(size))) + return; + + setSize(size); + break; + } + case DrawingAreaLegacyMessage::SuspendPainting: + suspendPainting(); + break; + case DrawingAreaLegacyMessage::ResumePainting: + resumePainting(); + break; + case DrawingAreaLegacyMessage::CancelTileUpdate: { + int tileID; + if (!arguments->decode(CoreIPC::Out(tileID))) + return; + UpdateMap::iterator it = m_pendingUpdates.find(tileID); + if (it != m_pendingUpdates.end()) { + m_pendingUpdates.remove(it); + if (m_pendingUpdates.isEmpty()) { + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In()); + m_tileUpdateTimer.stop(); + } + } + break; + } + case DrawingAreaLegacyMessage::RequestTileUpdate: { + TileUpdate update; + if (!arguments->decode(CoreIPC::Out(update.tileID, update.dirtyRect, update.scale))) + return; + UpdateMap::iterator it = m_pendingUpdates.find(update.tileID); + if (it != m_pendingUpdates.end()) + it->second.dirtyRect.unite(update.dirtyRect); + else { + m_pendingUpdates.add(update.tileID, update); + if (!m_tileUpdateTimer.isActive()) + m_tileUpdateTimer.startOneShot(0); + } + break; + } + case DrawingAreaLegacyMessage::TakeSnapshot: { + IntSize targetSize; + IntRect contentsRect; + + if (!arguments->decode(CoreIPC::Out(targetSize, contentsRect))) + return; + + m_webPage->layoutIfNeeded(); + + contentsRect.intersect(IntRect(IntPoint::zero(), m_webPage->mainFrame()->coreFrame()->view()->contentsSize())); + + float targetScale = float(targetSize.width()) / contentsRect.width(); + + UpdateChunk updateChunk(IntRect(IntPoint(contentsRect.x() * targetScale, contentsRect.y() * targetScale), targetSize)); + paintIntoUpdateChunk(&updateChunk, targetScale); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::SnapshotTaken, m_webPage->pageID(), CoreIPC::In(updateChunk)); + break; + } + default: + ASSERT_NOT_REACHED(); + break; + } +} + +} // namespace WebKit + +#endif // TILED_BACKING_STORE diff --git a/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h new file mode 100644 index 0000000..7b682ca --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h @@ -0,0 +1,94 @@ +/* + * 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 ENABLE(TILED_BACKING_STORE) + +#include "DrawingArea.h" +#include "RunLoop.h" +#include <WebCore/IntPoint.h> +#include <WebCore/IntRect.h> +#include <wtf/Vector.h> + +namespace WebKit { + +class UpdateChunk; + +class TiledDrawingArea : public DrawingArea { +public: + TiledDrawingArea(DrawingAreaInfo::Identifier, WebPage*); + virtual ~TiledDrawingArea(); + + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta); + virtual void display(); + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachCompositingContext() { } + virtual void detachCompositingContext() { } + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) { } + virtual void scheduleCompositingLayerSync() { } + virtual void syncCompositingLayers() { } +#endif + + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + void scheduleDisplay(); + + // CoreIPC message handlers. + void setSize(const WebCore::IntSize& viewSize); + void suspendPainting(); + void resumePainting(); + void didUpdate(); + void updateTile(int tileID, const WebCore::IntRect& dirtyRect, float scale); + + // Platform overrides + void paintIntoUpdateChunk(UpdateChunk*, float scale); + + void tileUpdateTimerFired(); + + WebCore::IntRect m_dirtyRect; + bool m_isWaitingForUpdate; + bool m_shouldPaint; + RunLoop::Timer<TiledDrawingArea> m_displayTimer; + + struct TileUpdate { + int tileID; + WebCore::IntRect dirtyRect; + float scale; + }; + typedef HashMap<int, TileUpdate> UpdateMap; + UpdateMap m_pendingUpdates; + RunLoop::Timer<TiledDrawingArea> m_tileUpdateTimer; +}; + +} // namespace WebKit + +#endif // 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 0000000..21f4fba --- /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 "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() +{ + static IDToHistoryItemMap map; + return map; +} + +static HistoryItemToIDMap& historyItemToIDMap() +{ + static 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.data()), 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(); +} + +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()); +} + +#if ENABLE(WML) +void WebBackForwardListProxy::clearWMLPageHistory() +{ +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h new file mode 100644 index 0000000..be28739 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h @@ -0,0 +1,72 @@ +/* + * 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 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(); + +#if ENABLE(WML) + void clearWMLPageHistory(); +#endif + + 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 0000000..b496128 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp @@ -0,0 +1,94 @@ +/* + * 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 "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/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(); + + // Notify the UIProcess. + 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 0000000..3d9291a --- /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/WebEditCommand.cpp b/Source/WebKit2/WebProcess/WebPage/WebEditCommand.cpp new file mode 100644 index 0000000..198cb6d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebEditCommand.cpp @@ -0,0 +1,41 @@ +/* + * 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 "WebEditCommand.h" + +namespace WebKit { + +static uint64_t generateCommandID() +{ + static uint64_t uniqueCommandID = 1; + return uniqueCommandID++; +} + +PassRefPtr<WebEditCommand> WebEditCommand::create(PassRefPtr<WebCore::EditCommand> command) +{ + return adoptRef(new WebEditCommand(command, generateCommandID())); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebEditCommand.h b/Source/WebKit2/WebProcess/WebPage/WebEditCommand.h new file mode 100644 index 0000000..b6844a2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebEditCommand.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 WebEditCommand_h +#define WebEditCommand_h + +#include <WebCore/EditCommand.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebKit { + +class WebEditCommand : public RefCounted<WebEditCommand> { +public: + static PassRefPtr<WebEditCommand> create(PassRefPtr<WebCore::EditCommand>); + + WebCore::EditCommand* command() const { return m_command.get(); } + uint64_t commandID() const { return m_commandID; } + +private: + WebEditCommand(PassRefPtr<WebCore::EditCommand> command, uint64_t commandID) + : m_command(command) + , m_commandID(commandID) + { + } + + RefPtr<WebCore::EditCommand> m_command; + uint64_t m_commandID; +}; + +} // namespace WebKit + +#endif // WebEditCommand_h diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp new file mode 100644 index 0000000..c5f117e --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp @@ -0,0 +1,517 @@ +/* + * 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 "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/JSLock.h> +#include <JavaScriptCore/JSValueRef.h> +#include <WebCore/AnimationController.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/JSCSSStyleDeclaration.h> +#include <WebCore/JSElement.h> +#include <WebCore/JSRange.h> +#include <WebCore/Page.h> +#include <WebCore/RenderTreeAsText.h> +#include <WebCore/TextIterator.h> +#include <WebCore/TextResourceDecoder.h> +#include <wtf/text/StringBuilder.h> + +#ifndef NDEBUG +#include <wtf/RefCountedLeakCounter.h> +#endif + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +#ifndef NDEBUG +static WTF::RefCountedLeakCounter webFrameCounter("WebFrame"); +#endif + +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 ResourceRequest& initialRequest, const ResourceResponse& response) +{ + ASSERT(m_policyDownloadID); + + DownloadManager::shared().convertHandleToDownload(m_policyDownloadID, page(), handle, request, initialRequest, 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->mainFrame() == 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(); + + return m_coreFrame->loader()->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(); +} + +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); +} + +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()); +} + +JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, InjectedBundleScriptWorld* world) +{ + 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) +{ + 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(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.h b/Source/WebKit2/WebProcess/WebPage/WebFrame.h new file mode 100644 index 0000000..3ded6f6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.h @@ -0,0 +1,144 @@ +/* + * 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> + +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::ResourceRequest& initialRequest, 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*); + + 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); + void suspendAnimations(); + void resumeAnimations(); + String layerTreeAsText() const; + + unsigned pendingUnloadCount() const; + + bool allowsFollowingLink(const WebCore::KURL&) const; + + String provisionalURL() const; + + // 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; } + +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 0000000..559b8b6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp @@ -0,0 +1,141 @@ +/* + * 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 "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#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 { + +WebInspector::WebInspector(WebPage* page) + : m_page(page) + , m_inspectorPage(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); + + 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()); +} + +// Called by WebInspector messages +void WebInspector::show() +{ + m_page->corePage()->inspectorController()->show(); +} + +void WebInspector::close() +{ + m_page->corePage()->inspectorController()->close(); +} + +void WebInspector::showConsole() +{ + m_page->corePage()->inspectorController()->showPanel(InspectorController::ConsolePanel); +} + +void WebInspector::startJavaScriptDebugging() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->showAndEnableDebugger(); +#endif +} + +void WebInspector::stopJavaScriptDebugging() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->disableDebugger(); +#endif +} + +void WebInspector::startJavaScriptProfiling() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->startUserInitiatedProfiling(); +#endif +} + +void WebInspector::stopJavaScriptProfiling() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->stopUserInitiatedProfiling(); + m_page->corePage()->inspectorController()->showPanel(InspectorController::ProfilesPanel); +#endif +} + +void WebInspector::startPageProfiling() +{ + m_page->corePage()->inspectorController()->startTimelineProfiler(); +} + +void WebInspector::stopPageProfiling() +{ + m_page->corePage()->inspectorController()->stopTimelineProfiler(); + // FIXME: show the Timeline panel. +} + +} // 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 0000000..21a7529 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.h @@ -0,0 +1,89 @@ +/* + * 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 "Connection.h" +#include <wtf/Forward.h> +#include <wtf/Noncopyable.h> + +namespace WebKit { + +class WebPage; +struct WebPageCreationParameters; + +class WebInspector { + WTF_MAKE_NONCOPYABLE(WebInspector); + +public: + explicit WebInspector(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*); + +private: + friend class WebInspectorClient; + friend class WebInspectorFrontendClient; + + // Called from WebInspectorClient + WebPage* createInspectorPage(); + + // Called from WebInspectorFrontendClient + void didLoadInspectorPage(); + void didClose(); + + // Implemented in platform WebInspector file + String localizedStringsURL() const; + + // Called by WebInspector messages + void show(); + void close(); + + void showConsole(); + + void startJavaScriptDebugging(); + void stopJavaScriptDebugging(); + + void startJavaScriptProfiling(); + void stopJavaScriptProfiling(); + + void startPageProfiling(); + void stopPageProfiling(); + + WebPage* m_page; + WebPage* m_inspectorPage; +}; + +} // 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 0000000..dc184b6 --- /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 0000000..d42e313 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp @@ -0,0 +1,50 @@ +/* + * 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 "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 0000000..073d66a --- /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 0000000..2259387 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp @@ -0,0 +1,1757 @@ +/* + * 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 "WebPage.h" + +#include "Arguments.h" +#include "DataReference.h" +#include "DecoderAdapter.h" +#include "DrawingArea.h" +#include "InjectedBundle.h" +#include "InjectedBundleBackForwardList.h" +#include "MessageID.h" +#include "NetscapePlugin.h" +#include "PageOverlay.h" +#include "PluginProxy.h" +#include "PluginView.h" +#include "PrintInfo.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 "WebGeolocationClient.h" +#include "WebImage.h" +#include "WebInspector.h" +#include "WebInspectorClient.h" +#include "WebOpenPanelResultListener.h" +#include "WebPageCreationParameters.h" +#include "WebPageGroupProxy.h" +#include "WebPageProxyMessages.h" +#include "WebPopupMenu.h" +#include "WebPreferencesStore.h" +#include "WebProcess.h" +#include "WebProcessProxyMessageKinds.h" +#include "WebProcessProxyMessages.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/EventHandler.h> +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameLoaderTypes.h> +#include <WebCore/FrameView.h> +#include <WebCore/HistoryItem.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/PrintContext.h> +#include <WebCore/RenderTreeAsText.h> +#include <WebCore/RenderLayer.h> +#include <WebCore/RenderView.h> +#include <WebCore/ReplaceSelectionCommand.h> +#include <WebCore/ResourceRequest.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> + +#if PLATFORM(MAC) || PLATFORM(WIN) +#include <WebCore/LegacyWebArchive.h> +#endif + +#if ENABLE(PLUGIN_PROCESS) +// FIXME: This is currently Mac-specific! +#include "MachPort.h" +#endif + +#if PLATFORM(QT) +#include "HitTestResult.h" +#endif + +#ifndef NDEBUG +#include <wtf/RefCountedLeakCounter.h> +#endif + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +#ifndef NDEBUG +static WTF::RefCountedLeakCounter webPageCounter("WebPage"); +#endif + +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_drawsBackground(true) + , m_drawsTransparentBackground(false) + , m_isInRedo(false) + , m_isClosed(false) + , m_tabToLinks(false) +#if PLATFORM(MAC) + , m_windowIsVisible(false) + , m_isSmartInsertDeleteEnabled(parameters.isSmartInsertDeleteEnabled) +#elif PLATFORM(WIN) + , m_nativeWindow(parameters.nativeWindow) +#endif + , m_findController(this) + , m_geolocationPermissionRequestManager(this) + , m_pageID(pageID) +{ + ASSERT(m_pageID); + + 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 + 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(); + Settings::setMinDOMTimerInterval(0.004); + + m_drawingArea = DrawingArea::create(parameters.drawingAreaInfo.type, parameters.drawingAreaInfo.identifier, this); + m_mainFrame = WebFrame::createMainFrame(this); + + setDrawsBackground(parameters.drawsBackground); + setDrawsTransparentBackground(parameters.drawsTransparentBackground); + + setActive(parameters.isActive); + setFocused(parameters.isFocused); + setIsInWindow(parameters.isInWindow); + + m_userAgent = parameters.userAgent; + + WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID); + + if (!parameters.sessionState.isEmpty()) + restoreSession(parameters.sessionState); + +#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::initializeInjectedBundleUIClient(WKBundlePageUIClient* client) +{ + m_uiClient.initialize(client); +} + +PassRefPtr<Plugin> WebPage::createPlugin(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()) + return 0; + +#if ENABLE(PLUGIN_PROCESS) + return PluginProxy::create(pluginPath); +#else + return NetscapePlugin::create(NetscapePluginModule::getOrCreate(pluginPath)); +#endif +} + +String WebPage::renderTreeExternalRepresentation() const +{ + return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal); +} + +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() +{ + mainFrame()->coreFrame()->tree()->clearName(); +} + +#if USE(ACCELERATED_COMPOSITING) +void WebPage::changeAcceleratedCompositingMode(WebCore::GraphicsLayer* layer) +{ + if (m_isClosed) + return; + + bool compositing = layer; + + // Tell the UI process that accelerated compositing changed. It may respond by changing + // drawing area types. + DrawingAreaInfo newDrawingAreaInfo; + + if (!sendSync(Messages::WebPageProxy::DidChangeAcceleratedCompositing(compositing), Messages::WebPageProxy::DidChangeAcceleratedCompositing::Reply(newDrawingAreaInfo))) + return; + + if (newDrawingAreaInfo.type != drawingArea()->info().type) { + m_drawingArea = 0; + if (newDrawingAreaInfo.type != DrawingAreaInfo::None) { + m_drawingArea = DrawingArea::create(newDrawingAreaInfo.type, newDrawingAreaInfo.identifier, this); + m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize)); + } + } +} + +void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer) +{ + changeAcceleratedCompositingMode(layer); + m_drawingArea->setRootCompositingLayer(layer); +} + +void WebPage::exitAcceleratedCompositingMode() +{ + changeAcceleratedCompositingMode(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 (m_activePopupMenu) { + m_activePopupMenu->disconnectFromPage(); + m_activePopupMenu = 0; + } + + if (m_activeOpenPanelResultListener) { + m_activeOpenPanelResultListener->disconnectFromPage(); + m_activeOpenPanelResultListener = 0; + } + + m_sandboxExtensionTracker.invalidate(); + + m_printContext = nullptr; + + m_mainFrame->coreFrame()->loader()->detachFromParent(); + m_page.clear(); + + m_drawingArea->onPageClose(); + m_drawingArea.clear(); + + WebProcess::shared().removeWebPage(m_pageID); +} + +void WebPage::tryClose() +{ + if (!m_mainFrame->coreFrame()->loader()->shouldClose()) + return; + + sendClose(); +} + +void WebPage::sendClose() +{ + send(Messages::WebPageProxy::ClosePage()); +} + +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) +{ + 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) +{ + 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::stopLoading() +{ + m_mainFrame->coreFrame()->loader()->stopForUserCancel(); +} + +void WebPage::setDefersLoading(bool defersLoading) +{ + m_page->setDefersLoading(defersLoading); +} + +void WebPage::reload(bool reloadFromOrigin) +{ + m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin); +} + +void WebPage::goForward(uint64_t backForwardItemID) +{ + HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); + m_page->goToItem(item, FrameLoadTypeForward); +} + +void WebPage::goBack(uint64_t backForwardItemID) +{ + HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); + m_page->goToItem(item, FrameLoadTypeBack); +} + +void WebPage::goToBackForwardItem(uint64_t backForwardItemID) +{ + HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); + m_page->goToItem(item, FrameLoadTypeIndexedBackForward); +} + +void WebPage::layoutIfNeeded() +{ + if (m_mainFrame->coreFrame()->view()) + m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive(); +} + +void WebPage::setSize(const WebCore::IntSize& viewSize) +{ +#if ENABLE(TILED_BACKING_STORE) + // If we are resizing to content ignore external attempts. + if (!m_resizesToContentsLayoutSize.isEmpty()) + return; +#endif + + if (m_viewSize == viewSize) + return; + + Frame* frame = m_page->mainFrame(); + + frame->view()->resize(viewSize); + frame->view()->setNeedsLayout(); + m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), viewSize)); + + m_viewSize = viewSize; +} + +#if ENABLE(TILED_BACKING_STORE) +void WebPage::setActualVisibleContentRect(const IntRect& rect) +{ + Frame* frame = m_page->mainFrame(); + + frame->view()->setActualVisibleContentRect(rect); +} + +void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSize) +{ + if (m_resizesToContentsLayoutSize == targetLayoutSize) + return; + + m_resizesToContentsLayoutSize = targetLayoutSize; + + Frame* frame = m_page->mainFrame(); + if (m_resizesToContentsLayoutSize.isEmpty()) { + frame->view()->setDelegatesScrolling(false); + frame->view()->setUseFixedLayout(false); + frame->view()->setPaintsEntireContents(false); + } else { + frame->view()->setDelegatesScrolling(true); + frame->view()->setUseFixedLayout(true); + frame->view()->setPaintsEntireContents(true); + frame->view()->setFixedLayoutSize(m_resizesToContentsLayoutSize); + } + frame->view()->forceLayout(); +} + +void WebPage::resizeToContentsIfNeeded() +{ + if (m_resizesToContentsLayoutSize.isEmpty()) + return; + + Frame* frame = m_page->mainFrame(); + + IntSize contentSize = frame->view()->contentsSize(); + if (contentSize == m_viewSize) + return; + + m_viewSize = contentSize; + frame->view()->resize(m_viewSize); + frame->view()->setNeedsLayout(); +} +#endif + +void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect) +{ + graphicsContext.save(); + graphicsContext.clip(rect); + m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect); + graphicsContext.restore(); + + if (m_pageOverlay) { + graphicsContext.save(); + graphicsContext.clip(rect); + m_pageOverlay->drawRect(graphicsContext, rect); + graphicsContext.restore(); + } +} + +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::scaleWebView(double scale, const IntPoint& origin) +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return; + frame->scalePage(scale, origin); +} + +double WebPage::viewScaleFactor() const +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return 1; + return frame->pageScaleFactor(); +} + +void WebPage::setUseFixedLayout(bool fixed) +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return; + + FrameView* view = frame->view(); + if (!view) + return; + + view->setUseFixedLayout(fixed); + if (!fixed) + view->setFixedLayoutSize(IntSize()); +} + +void WebPage::setFixedLayoutSize(const IntSize& size) +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return; + + FrameView* view = frame->view(); + if (!view) + return; + + view->setFixedLayoutSize(size); + view->forceLayout(); +} + +void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay) +{ + if (m_pageOverlay) + pageOverlay->setPage(0); + + m_pageOverlay = pageOverlay; + m_pageOverlay->setPage(this); + m_pageOverlay->setNeedsDisplay(); +} + +void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay) +{ + if (pageOverlay != m_pageOverlay) + return; + + m_pageOverlay->setPage(0); + m_pageOverlay = nullptr; + m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize)); +} + +PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options) +{ + FrameView* frameView = m_mainFrame->coreFrame()->view(); + if (!frameView) + return 0; + + frameView->updateLayoutAndStyleIfNeededRecursive(); + + PaintBehavior oldBehavior = frameView->paintBehavior(); + frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers); + + RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options); + OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext(); + + graphicsContext->save(); + graphicsContext->translate(-rect.x(), -rect.y()); + frameView->paint(graphicsContext.get(), rect); + graphicsContext->restore(); + + frameView->setPaintBehavior(oldBehavior); + + return snapshot.release(); +} + +PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options) +{ + FrameView* frameView = m_mainFrame->coreFrame()->view(); + if (!frameView) + return 0; + + frameView->updateLayoutAndStyleIfNeededRecursive(); + + PaintBehavior oldBehavior = frameView->paintBehavior(); + frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers); + + RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options); + OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext(); + + graphicsContext->save(); + graphicsContext->translate(-rect.x(), -rect.y()); + frameView->paintContents(graphicsContext.get(), rect); + graphicsContext->restore(); + + frameView->setPaintBehavior(oldBehavior); + + return snapshot.release(); +} + +void WebPage::pageDidScroll() +{ + // Hide the find indicator. + m_findController.hideFindIndicator(); + + m_uiClient.pageDidScroll(this); + + send(Messages::WebPageProxy::PageDidScroll()); +} + +#if ENABLE(TILED_BACKING_STORE) +void WebPage::pageDidRequestScroll(const IntSize& delta) +{ + send(Messages::WebPageProxy::PageDidRequestScroll(delta)); +} +#endif + +WebContextMenu* WebPage::contextMenu() +{ + if (!m_contextMenu) + m_contextMenu = WebContextMenu::create(this); + return m_contextMenu.get(); +} + +void WebPage::getLocationAndLengthFromRange(Range* range, uint64_t& location, uint64_t& length) +{ + location = notFound; + length = 0; + + if (!range || !range->startContainer()) + return; + + Element* selectionRoot = range->ownerDocument()->frame()->selection()->rootEditableElement(); + Element* scope = selectionRoot ? selectionRoot : range->ownerDocument()->documentElement(); + + // Mouse events may cause TSM to attempt to create an NSRange for a portion of the view + // that is not inside the current editable region. These checks ensure we don't produce + // potentially invalid data when responding to such requests. + if (range->startContainer() != scope && !range->startContainer()->isDescendantOf(scope)) + return; + if (range->endContainer() != scope && !range->endContainer()->isDescendantOf(scope)) + return; + + RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset()); + ASSERT(testRange->startContainer() == scope); + location = TextIterator::rangeLength(testRange.get()); + + ExceptionCode ec; + testRange->setEnd(range->endContainer(), range->endOffset(), ec); + ASSERT(testRange->startContainer() == scope); + length = TextIterator::rangeLength(testRange.get()) - location; +} + +// 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 handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page) +{ + Frame* frame = page->mainFrame(); + if (!frame->view()) + return false; + + PlatformMouseEvent platformMouseEvent = platform(mouseEvent); + + switch (platformMouseEvent.eventType()) { + case WebCore::MouseEventPressed: + { + if (isContextClick(platformMouseEvent)) + page->contextMenuController()->clearContextMenu(); + + bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent); + + if (isContextClick(platformMouseEvent)) { + handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent); + if (handled) + page->chrome()->showContextMenu(); + } + + return handled; + } + case WebCore::MouseEventReleased: + return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent); + case WebCore::MouseEventMoved: + return frame->eventHandler()->mouseMoved(platformMouseEvent); + + default: + ASSERT_NOT_REACHED(); + return false; + } +} + +void WebPage::mouseEvent(const WebMouseEvent& mouseEvent) +{ + bool handled = false; + + if (m_pageOverlay) { + // Let the page overlay handle the event. + handled = m_pageOverlay->mouseEvent(mouseEvent); + } + + if (!handled) { + CurrentEvent currentEvent(mouseEvent); + + handled = handleMouseEvent(mouseEvent, m_page.get()); + } + + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled)); +} + +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)); +} + +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()); + if (!handled) + handled = performDefaultBehaviorForKeyEvent(keyboardEvent); + + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled)); +} + +void WebPage::validateMenuItem(const String& commandName) +{ + 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::DidValidateMenuItem(commandName, isEnabled, state)); +} + +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) +{ + if (uint64_t currentItemID = restoreSession(sessionState)) + goToBackForwardItem(currentItemID); +} + +#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)); +} +#endif + +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::setFocused(bool isFocused) +{ + m_page->focusController()->setFocused(isFocused); +} + +void WebPage::setInitialFocus(bool forward) +{ + if (!m_page || !m_page->focusController()) + return; + + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + frame->document()->setFocusedNode(0); + 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::setIsInWindow(bool isInWindow) +{ + if (!isInWindow) { + m_page->setCanStartMedia(false); + m_page->willMoveOffscreen(); + } else { + m_page->setCanStartMedia(true); + 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; +} + +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()); +} + +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. + + JSLock lock(SilenceAssertionsOnly); + JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue(); + String resultString; + if (resultValue) + resultString = ustringToString(resultValue.toString(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec())); + + send(Messages::WebPageProxy::StringCallback(resultString, 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)); +} + +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 (RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(frame->coreFrame())) { + if ((data = archive->rawDataRepresentation())) + dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get())); + } + } +#endif + + send(Messages::WebPageProxy::DataCallback(dataReference, 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->setJavaScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey())); + settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey())); + 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())); + settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey())); + settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey())); + settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey())); + settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey())); + settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey())); + settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey())); + settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey())); + + settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey())); + settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey())); + settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey())); + settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey())); + +#if PLATFORM(WIN) + // Temporarily turn off accelerated compositing until we have a good solution for rendering it. + settings->setAcceleratedCompositingEnabled(false); +#else + settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey())); +#endif + settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey())); + settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey())); + +#if ENABLE(DATABASE) + AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey())); +#endif + + platformPreferencesDidChange(store); +} + +#if ENABLE(INSPECTOR) +WebInspector* WebPage::inspector() +{ + if (m_isClosed) + return 0; + if (!m_inspector) + m_inspector = adoptPtr(new WebInspector(this)); + return m_inspector.get(); +} +#endif + +#if !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() == PlatformKeyboardEvent::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 + +void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags) +{ + if (!m_page) { + send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone)); + 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: + m_page->dragController()->performDrag(&dragData); + break; + + default: + ASSERT_NOT_REACHED(); + } +} + +WebEditCommand* WebPage::webEditCommand(uint64_t commandID) +{ + return m_editCommandMap.get(commandID).get(); +} + +void WebPage::addWebEditCommand(uint64_t commandID, WebEditCommand* command) +{ + m_editCommandMap.set(commandID, command); +} + +void WebPage::removeWebEditCommand(uint64_t commandID) +{ + m_editCommandMap.remove(commandID); +} + +void WebPage::unapplyEditCommand(uint64_t commandID) +{ + WebEditCommand* command = webEditCommand(commandID); + if (!command) + return; + + command->command()->unapply(); +} + +void WebPage::reapplyEditCommand(uint64_t commandID) +{ + WebEditCommand* command = webEditCommand(commandID); + if (!command) + return; + + m_isInRedo = true; + command->command()->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; +} + +void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) +{ + m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, 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); +} + +void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item) +{ + ASSERT(m_contextMenu); + m_contextMenu->itemSelected(item); + m_contextMenu = 0; +} + +void WebPage::replaceSelectionWithText(Frame* frame, const String& text) +{ + if (frame->selection()->isNone()) + return; + + RefPtr<DocumentFragment> textFragment = createFragmentFromText(frame->selection()->toNormalizedRange().get(), text); + applyCommand(ReplaceSelectionCommand::create(frame->document(), textFragment.release(), true, false, true)); + frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); +} + +bool WebPage::mainFrameHasCustomRepresentation() const +{ + return static_cast<WebFrameLoaderClient*>(mainFrame()->coreFrame()->loader()->client())->frameHasCustomRepresentation(); +} + +#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); +} + +bool WebPage::windowIsFocused() const +{ + return m_page->focusController()->isActive(); +} + +#endif + +void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + if (messageID.is<CoreIPC::MessageClassDrawingAreaLegacy>()) { + if (m_drawingArea) + m_drawingArea->didReceiveMessage(connection, messageID, arguments); + return; + } + +#ifdef __APPLE__ + if (messageID.is<CoreIPC::MessageClassDrawingArea>()) { + if (m_drawingArea) + m_drawingArea->didReceiveDrawingAreaMessage(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 + + didReceiveWebPageMessage(connection, messageID, arguments); +} + +CoreIPC::SyncReplyMode WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply) +{ + return 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) +{ + const int minimumZoomTargetWidth = 100; + + Frame* mainframe = m_mainFrame->coreFrame(); + HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true); + + Node* node = result.innerNode(); + while (node && node->getRect().width() < minimumZoomTargetWidth) + node = node->parentNode(); + + IntRect zoomableArea; + if (node) + zoomableArea = node->getRect(); + send(Messages::WebPageProxy::DidFindZoomableArea(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::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle) +{ + ASSERT(frame->isMainFrame()); + + ASSERT(!m_pendingProvisionalSandboxExtension); + m_pendingProvisionalSandboxExtension = SandboxExtension::create(handle); +} + +void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame) +{ + if (!frame->isMainFrame()) + return; + + 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; + + ASSERT(!m_pendingProvisionalSandboxExtension); + if (!m_provisionalSandboxExtension) + return; + + m_provisionalSandboxExtension->invalidate(); + m_provisionalSandboxExtension = 0; +} + +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 + +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 (!m_printContext) + m_printContext = adoptPtr(new PrintContext(coreFrame)); + + m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight); +} + +void WebPage::endPrinting() +{ + m_printContext = nullptr; +} + +void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, Vector<IntRect>& resultPageRects, double& resultTotalScaleFactorForPrinting) +{ + beginPrinting(frameID, printInfo); + + WebFrame* frame = WebProcess::shared().webFrame(frameID); + if (!frame) + return; + + float fullPageHeight; + m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true); + + resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(printInfo.availablePaperWidth) * printInfo.pageSetupScaleFactor; + resultPageRects = m_printContext->pageRects(); + + // 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)); +} + +#if PLATFORM(MAC) +// FIXME: Find a better place for Mac specific code. +void WebPage::drawRectToPDF(uint64_t frameID, const WebCore::IntRect& rect, Vector<uint8_t>& pdfData) +{ + WebFrame* frame = WebProcess::shared().webFrame(frameID); + if (!frame) + return; + + Frame* coreFrame = frame->coreFrame(); + if (!coreFrame) + return; + + ASSERT(coreFrame->document()->printing()); + + RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0)); + + // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data. + RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get())); + + CGRect mediaBox = CGRectMake(0, 0, frame->size().width(), frame->size().height()); + RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0)); + CFDictionaryRef pageInfo = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CGPDFContextBeginPage(context.get(), pageInfo); + + GraphicsContext ctx(context.get()); + m_printContext->spoolRect(ctx, rect); + + CGPDFContextEndPage(context.get()); + CGPDFContextClose(context.get()); + + pdfData.resize(CFDataGetLength(pdfPageData.get())); + CFDataGetBytes(pdfPageData.get(), CFRangeMake(0, pdfData.size()), pdfData.data()); +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h new file mode 100644 index 0000000..7649ab6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h @@ -0,0 +1,499 @@ +/* + * 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 "InjectedBundlePageContextMenuClient.h" +#include "InjectedBundlePageEditorClient.h" +#include "InjectedBundlePageFormClient.h" +#include "InjectedBundlePageLoaderClient.h" +#include "InjectedBundlePageUIClient.h" +#include "MessageSender.h" +#include "Plugin.h" +#include "SandboxExtension.h" +#include "WebEditCommand.h" +#include <WebCore/Editor.h> +#include <WebCore/FrameLoaderTypes.h> +#include <WebCore/IntRect.h> +#include <wtf/HashMap.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> + +#if ENABLE(TOUCH_EVENTS) +#include <WebCore/PlatformTouchEvent.h> +#endif + +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> +#ifdef __OBJC__ +@class AccessibilityWebPageObject; +#else +class AccessibilityWebPageObject; +#endif +#endif + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebCore { + class GraphicsContext; + class KeyboardEvent; + class Page; + class PrintContext; + class ResourceRequest; + class SharedBuffer; +} + +namespace WebKit { + +class DrawingArea; +class InjectedBundleBackForwardList; +class PageOverlay; +class PluginView; +class SessionState; +class WebContextMenu; +class WebContextMenuItemData; +class WebEvent; +class WebFrame; +class WebImage; +class WebInspector; +class WebKeyboardEvent; +class WebMouseEvent; +class WebOpenPanelResultListener; +class WebPageGroupProxy; +class WebPopupMenu; +class WebWheelEvent; +struct PrintInfo; +struct WebPageCreationParameters; +struct WebPreferencesStore; + +#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; } + + InjectedBundleBackForwardList* backForwardList(); + DrawingArea* drawingArea() const { return m_drawingArea.get(); } + + WebPageGroupProxy* pageGroup() const { return m_pageGroup.get(); } + +#if ENABLE(INSPECTOR) + WebInspector* inspector(); +#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 layoutIfNeeded(); + + // -- Called from WebCore clients. +#if !PLATFORM(MAC) + bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*); +#endif + void show(); + String userAgent() const { return m_userAgent; } + WebCore::IntRect windowResizerRect() const; + bool tabsToLinks() const { return m_tabToLinks; } + + WebEditCommand* webEditCommand(uint64_t); + void addWebEditCommand(uint64_t, WebEditCommand*); + 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*); + CoreIPC::SyncReplyMode didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); + + // -- InjectedBundle methods + void initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient*); + void initializeInjectedBundleEditorClient(WKBundlePageEditorClient*); + void initializeInjectedBundleFormClient(WKBundlePageFormClient*); + void initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient*); + void initializeInjectedBundleUIClient(WKBundlePageUIClient*); + + InjectedBundlePageContextMenuClient& injectedBundleContextMenuClient() { return m_contextMenuClient; } + InjectedBundlePageEditorClient& injectedBundleEditorClient() { return m_editorClient; } + InjectedBundlePageFormClient& injectedBundleFormClient() { return m_formClient; } + InjectedBundlePageLoaderClient& injectedBundleLoaderClient() { return m_loaderClient; } + InjectedBundlePageUIClient& injectedBundleUIClient() { return m_uiClient; } + + bool findStringFromInjectedBundle(const String&, FindOptions); + + WebFrame* mainFrame() const { return m_mainFrame.get(); } + PassRefPtr<Plugin> createPlugin(const Plugin::Parameters&); + + String renderTreeExternalRepresentation() const; + 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 scaleWebView(double scale, const WebCore::IntPoint& origin); + double viewScaleFactor() const; + + void setUseFixedLayout(bool); + void setFixedLayoutSize(const WebCore::IntSize&); + + bool drawsBackground() const { return m_drawsBackground; } + bool drawsTransparentBackground() const { return m_drawsTransparentBackground; } + + void stopLoading(); + void setDefersLoading(bool deferLoading); + +#if USE(ACCELERATED_COMPOSITING) + void changeAcceleratedCompositingMode(WebCore::GraphicsLayer*); + 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; } + bool windowIsFocused() const; + bool interceptEditingKeyboardEvent(WebCore::KeyboardEvent*, bool); +#elif PLATFORM(WIN) + HWND nativeWindow() const { return m_nativeWindow; } +#endif + + void installPageOverlay(PassRefPtr<PageOverlay>); + void uninstallPageOverlay(PageOverlay*); + + PassRefPtr<WebImage> snapshotInViewCoordinates(const WebCore::IntRect&, ImageOptions); + PassRefPtr<WebImage> snapshotInDocumentCoordinates(const WebCore::IntRect&, ImageOptions); + + static const WebEvent* currentEvent(); + + FindController& findController() { return m_findController; } + GeolocationPermissionRequestManager& geolocationPermissionRequestManager() { return m_geolocationPermissionRequestManager; } + + void pageDidScroll(); +#if ENABLE(TILED_BACKING_STORE) + void pageDidRequestScroll(const WebCore::IntSize& delta); + void setActualVisibleContentRect(const WebCore::IntRect&); + + bool resizesToContentsEnabled() const { return !m_resizesToContentsLayoutSize.isEmpty(); } + WebCore::IntSize resizesToContentsLayoutSize() const { return m_resizesToContentsLayoutSize; } + void setResizesToContentsUsingLayoutSize(const WebCore::IntSize& targetLayoutSize); + void resizeToContentsIfNeeded(); +#endif + + WebContextMenu* contextMenu(); + + bool hasLocalDataForURL(const WebCore::KURL&); + + static bool canHandleRequest(const WebCore::ResourceRequest&); + + class SandboxExtensionTracker { + public: + ~SandboxExtensionTracker(); + + void invalidate(); + + void beginLoad(WebFrame*, const SandboxExtension::Handle& handle); + void didStartProvisionalLoad(WebFrame*); + void didCommitProvisionalLoad(WebFrame*); + void didFailProvisionalLoad(WebFrame*); + private: + RefPtr<SandboxExtension> m_pendingProvisionalSandboxExtension; + RefPtr<SandboxExtension> m_provisionalSandboxExtension; + RefPtr<SandboxExtension> m_committedSandboxExtension; + }; + + SandboxExtensionTracker& sandboxExtensionTracker() { return m_sandboxExtensionTracker; } + + static void getLocationAndLengthFromRange(WebCore::Range*, uint64_t& location, uint64_t& length); + +#if PLATFORM(MAC) + void sendAccessibilityPresenterToken(const CoreIPC::DataReference&); + AccessibilityWebPageObject* accessibilityRemoteObject(); + WebCore::IntPoint accessibilityPosition() const { return m_accessibilityPosition; } + + void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput); + + void getMarkedRange(uint64_t& location, uint64_t& length); + void characterIndexForPoint(const WebCore::IntPoint point, uint64_t& result); + void firstRectForCharacterRange(uint64_t location, uint64_t length, WebCore::IntRect& resultRect); +#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&); +#endif + + // FIXME: This a dummy message, to avoid breaking the build for platforms that don't require + // any synchronous messages, and should be removed when <rdar://problem/8775115> is fixed. + void dummy(bool&); + +#if PLATFORM(MAC) + bool isSpeaking(); + void speak(const String&); + void stopSpeaking(); + + bool isSmartInsertDeleteEnabled() const { return m_isSmartInsertDeleteEnabled; } +#endif + + void replaceSelectionWithText(WebCore::Frame*, const String&); + void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WTF::String& dragStorageName, uint32_t flags); + + void beginPrinting(uint64_t frameID, const PrintInfo&); + void endPrinting(); + void computePagesForPrinting(uint64_t frameID, const PrintInfo&, Vector<WebCore::IntRect>& resultPageRects, double& resultTotalScaleFactorForPrinting); +#if PLATFORM(MAC) + void drawRectToPDF(uint64_t frameID, const WebCore::IntRect&, Vector<uint8_t>& pdfData); +#endif + + bool mainFrameHasCustomRepresentation() const; + +private: + WebPage(uint64_t pageID, const WebPageCreationParameters&); + + virtual Type type() const { return APIType; } + + void platformInitialize(); + + void didReceiveWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + CoreIPC::SyncReplyMode didReceiveSyncWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); + + static const char* interpretKeyEvent(const WebCore::KeyboardEvent*); + bool performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&); + + 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& sandboxExtensionHandle); + void loadURLRequest(const WebCore::ResourceRequest&, const SandboxExtension::Handle& sandboxExtensionHandle); + void loadHTMLString(const String& htmlString, const String& baseURL); + void loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL); + void loadPlainTextString(const String&); + void reload(bool reloadFromOrigin); + void goForward(uint64_t); + void goBack(uint64_t); + void goToBackForwardItem(uint64_t); + void setActive(bool); + void setFocused(bool); + void setInitialFocus(bool); + void setWindowResizerSize(const WebCore::IntSize&); + void setIsInWindow(bool); + void mouseEvent(const WebMouseEvent&); + void wheelEvent(const WebWheelEvent&); + void keyEvent(const WebKeyboardEvent&); + void validateMenuItem(const String&); + void executeEditCommand(const String&); +#if ENABLE(TOUCH_EVENTS) + void touchEvent(const WebTouchEvent&); +#endif + + uint64_t restoreSession(const SessionState&); + void restoreSessionAndNavigateToCurrentItem(const SessionState&); + + void didRemoveBackForwardItem(uint64_t); + + void setDrawsBackground(bool); + void setDrawsTransparentBackground(bool); + + void getContentsAsString(uint64_t callbackID); + void getMainResourceDataOfFrame(uint64_t frameID, 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 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 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); + + void didChooseFilesForOpenPanel(const Vector<String>&); + void didCancelForOpenPanel(); + + void didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed); + + void advanceToNextMisspelling(bool startBeforeSelection); + void changeSpellingToWord(const String& word); + void unmarkAllMisspellings(); + void unmarkAllBadGrammar(); +#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 + + OwnPtr<WebCore::Page> m_page; + RefPtr<WebFrame> m_mainFrame; + RefPtr<InjectedBundleBackForwardList> m_backForwardList; + + RefPtr<WebPageGroupProxy> m_pageGroup; + + String m_userAgent; + + WebCore::IntSize m_viewSize; + RefPtr<DrawingArea> m_drawingArea; + + 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<AccessibilityWebPageObject> m_mockAccessibilityElement; +#elif PLATFORM(WIN) + // Our view's window (in the UI process). + HWND m_nativeWindow; +#endif + + HashMap<uint64_t, RefPtr<WebEditCommand> > m_editCommandMap; + + WebCore::IntSize m_windowResizerSize; + + InjectedBundlePageContextMenuClient m_contextMenuClient; + InjectedBundlePageEditorClient m_editorClient; + InjectedBundlePageFormClient m_formClient; + InjectedBundlePageLoaderClient m_loaderClient; + InjectedBundlePageUIClient m_uiClient; + +#if ENABLE(TILED_BACKING_STORE) + WebCore::IntSize m_resizesToContentsLayoutSize; +#endif + + FindController m_findController; + RefPtr<PageOverlay> m_pageOverlay; + +#if ENABLE(INSPECTOR) + OwnPtr<WebInspector> m_inspector; +#endif + RefPtr<WebPopupMenu> m_activePopupMenu; + RefPtr<WebContextMenu> m_contextMenu; + RefPtr<WebOpenPanelResultListener> m_activeOpenPanelResultListener; + GeolocationPermissionRequestManager m_geolocationPermissionRequestManager; + + OwnPtr<WebCore::PrintContext> m_printContext; + + SandboxExtensionTracker m_sandboxExtensionTracker; + uint64_t m_pageID; +}; + +} // 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 0000000..bd6bf1a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in @@ -0,0 +1,163 @@ +# 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. + +messages -> WebPage { + SetActive(bool active) + SetFocused(bool focused) + SetInitialFocus(bool forward) + SetIsInWindow(bool isInWindow) + + SetDrawsBackground(bool drawsBackground) + SetDrawsTransparentBackground(bool drawsTransparentBackground) + + KeyEvent(WebKit::WebKeyboardEvent event) + MouseEvent(WebKit::WebMouseEvent event) + WheelEvent(WebKit::WebWheelEvent event) +#if ENABLE(TOUCH_EVENTS) + TouchEvent(WebKit::WebTouchEvent event) +#endif + + GoBack(uint64_t backForwardItemID) + GoForward(uint64_t backForwardItemID) + GoToBackForwardItem(uint64_t backForwardItemID) + 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) + Reload(bool reloadFromOrigin) + StopLoading() + + RestoreSessionAndNavigateToCurrentItem(WebKit::SessionState state) + + DidRemoveBackForwardItem(uint64_t backForwardItemID) + + DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID) + + # Callbacks. + GetContentsAsString(uint64_t callbackID) + GetMainResourceDataOfFrame(uint64_t frameID, 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) + + PreferencesDidChange(WebKit::WebPreferencesStore store) + + SetUserAgent(WTF::String userAgent) + SetCustomTextEncodingName(WTF::String encodingName) + +#if ENABLE(TILED_BACKING_STORE) + SetActualVisibleContentRect(WebCore::IntRect rect) + SetResizesToContentsUsingLayoutSize(WebCore::IntSize size) +#endif + + Close() + TryClose() + + ValidateMenuItem(WTF::String name) + 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) + + ScaleWebView(double scale, WebCore::IntPoint origin) + + SetUseFixedLayout(bool fixed) + SetFixedLayoutSize(WebCore::IntSize size) + + # Find. + FindString(WTF::String string, uint32_t findOptions, unsigned maxMatchCount) + HideFindUI() + CountStringMatches(WTF::String string, uint32_t findOptions, unsigned maxMatchCount) + + # Drag and drop. + PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, WTF::String dragStorageName, uint32_t flags) + + # Popup menu. + DidChangeSelectedIndexForActivePopupMenu(int32_t newIndex); + SetTextForActivePopupMenu(int32_t index); + + # Context menu. + DidSelectItemFromActiveContextMenu(WebKit::WebContextMenuItemData menuItem); + + # Open panel. + DidChooseFilesForOpenPanel(Vector<WTF::String> fileURLs) + DidCancelForOpenPanel() + + # Spelling and grammar. + AdvanceToNextMisspelling(bool startBeforeSelection) + ChangeSpellingToWord(WTF::String word) + UnmarkAllMisspellings() + UnmarkAllBadGrammar() +#if PLATFORM(MAC) + UppercaseWord(); + LowercaseWord(); + CapitalizeWord(); + + SetSmartInsertDeleteEnabled(bool isSmartInsertDeleteEnabled); +#endif + + # Geolocation + DidReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) + + SetWindowResizerSize(WebCore::IntSize intersectsView) + + # Printing. + BeginPrinting(uint64_t frameID, WebKit::PrintInfo printInfo); + EndPrinting(); + ComputePagesForPrinting(uint64_t frameID, WebKit::PrintInfo printInfo) -> (Vector<WebCore::IntRect> pageRects, double totalScaleFactorForPrinting) +#if PLATFORM(MAC) + DrawRectToPDF(uint64_t frameID, WebCore::IntRect rect) -> (Vector<uint8_t> pdfData) +#endif + + // FIXME: This a dummy message, to avoid breaking the build for platforms that don't require + // any synchronous messages, and should be removed when <rdar://problem/8775115> is fixed. + Dummy() -> (bool dummyReturn) + +#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) + GetMarkedRange() -> (uint64_t location, uint64_t length) + CharacterIndexForPoint(WebCore::IntPoint point) -> (uint64_t result) + FirstRectForCharacterRange(uint64_t location, uint64_t length) -> (WebCore::IntRect resultRect) + SendAccessibilityPresenterToken(CoreIPC::DataReference token) +#endif +#if PLATFORM(WIN) + 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) +#endif +#if PLATFORM(QT) + FindZoomableAreaForPoint(WebCore::IntPoint point) +#endif +} diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp new file mode 100644 index 0000000..67109ec --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp @@ -0,0 +1,47 @@ +/* + * 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 "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 0000000..55cf629 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h @@ -0,0 +1,59 @@ +/* + * 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; } + +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/gtk/WebInspectorGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp new file mode 100644 index 0000000..4697f62 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp @@ -0,0 +1,46 @@ +/* + * 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 "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include <wtf/text/WTFString.h> + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + notImplemented(); + return String(); +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.h b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.h new file mode 100644 index 0000000..3b331b9 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.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 AccessibilityWebPageObject_h +#define AccessibilityWebPageObject_h + +namespace WebKit { +class WebPage; +} + +@interface AccessibilityWebPageObject : 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 // AccessibilityWebPageObject_h diff --git a/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm new file mode 100644 index 0000000..fa4aa1a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm @@ -0,0 +1,190 @@ +/* + * 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 "AccessibilityWebPageObject.h" + +#import "WebFrame.h" +#import "WebPage.h" +#import <WebCore/AXObjectCache.h> +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/ScrollView.h> +#import <WebCore/Scrollbar.h> + +using namespace WebCore; +using namespace WebKit; + +@implementation AccessibilityWebPageObject + +- (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 +{ + [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 [super accessibilityAttributeValue:attribute]; +} + +- (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 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* fv = m_page->mainFrame()->coreFrame()->view(); + if (fv) { + point.y += fv->scrollPosition().y(); + point.x += fv->scrollPosition().x(); + } + + return [[self accessibilityRootObjectWrapper] accessibilityHitTest:point]; +} + +- (id)accessibilityFocusedUIElement +{ + return NSAccessibilityUnignoredDescendant(self); +} + + +@end diff --git a/Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp b/Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp new file mode 100644 index 0000000..6bcecfd --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp @@ -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. + */ + +#include "ChunkedUpdateDrawingArea.h" + +#include "UpdateChunk.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebFrameLoaderClient.h" +#include <WebCore/Frame.h> +#include <WebCore/GraphicsContext.h> +#include <wtf/RetainPtr.h> + +using namespace WebCore; + +namespace WebKit { + +void ChunkedUpdateDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk) +{ + // FIXME: It would be better if we could avoid painting altogether when there is a custom representation. + if (m_webPage->mainFrameHasCustomRepresentation()) + return; + + RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); + RetainPtr<CGContextRef> bitmapContext(AdoptCF, CGBitmapContextCreate(updateChunk->data(), updateChunk->rect().width(), updateChunk->rect().height(), 8, updateChunk->rect().width() * 4, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + + // WebCore expects a flipped coordinate system. + CGContextTranslateCTM(bitmapContext.get(), 0.0, updateChunk->rect().height()); + CGContextScaleCTM(bitmapContext.get(), 1.0, -1.0); + + // Now paint into the backing store. + GraphicsContext graphicsContext(bitmapContext.get()); + graphicsContext.translate(-updateChunk->rect().x(), -updateChunk->rect().y()); + + m_webPage->drawRect(graphicsContext, updateChunk->rect()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm new file mode 100644 index 0000000..f8b7e71 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm @@ -0,0 +1,185 @@ +/* + * 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 USE(ACCELERATED_COMPOSITING) + +#include "LayerBackedDrawingArea.h" + +#include "DrawingAreaProxyMessageKinds.h" +#include "WebKitSystemInterface.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsLayer.h> +#include <WebCore/Page.h> + +using namespace WebCore; + +namespace WebKit { + +void LayerBackedDrawingArea::platformInit() +{ + setUpUpdateLayoutRunLoopObserver(); + + [m_backingLayer->platformLayer() setGeometryFlipped:YES]; +#if HAVE(HOSTED_CORE_ANIMATION) + attachCompositingContext(); +#endif + + scheduleCompositingLayerSync(); +} + +void LayerBackedDrawingArea::platformClear() +{ + if (!m_attached) + return; + + if (m_updateLayoutRunLoopObserver) { + CFRunLoopObserverInvalidate(m_updateLayoutRunLoopObserver.get()); + m_updateLayoutRunLoopObserver = 0; + } + +#if HAVE(HOSTED_CORE_ANIMATION) + WKCARemoteLayerClientInvalidate(m_remoteLayerRef.get()); + m_remoteLayerRef = nullptr; +#endif + + m_attached = false; +} + +void LayerBackedDrawingArea::attachCompositingContext() +{ + if (m_attached) + return; + + m_attached = true; + +#if HAVE(HOSTED_CORE_ANIMATION) + mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort(); + m_remoteLayerRef = WKCARemoteLayerClientMakeWithServerPort(serverPort); + WKCARemoteLayerClientSetLayer(m_remoteLayerRef.get(), m_backingLayer->platformLayer()); + + uint32_t contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerRef.get()); + WebProcess::shared().connection()->sendSync(DrawingAreaProxyLegacyMessage::AttachCompositingContext, m_webPage->pageID(), CoreIPC::In(contextID), CoreIPC::Out()); +#endif +} + +void LayerBackedDrawingArea::detachCompositingContext() +{ + m_backingLayer->removeAllChildren(); + + scheduleCompositingLayerSync(); +} + +void LayerBackedDrawingArea::setRootCompositingLayer(WebCore::GraphicsLayer* layer) +{ + m_backingLayer->removeAllChildren(); + if (layer) + m_backingLayer->addChild(layer); + + scheduleCompositingLayerSync(); +} + +void LayerBackedDrawingArea::scheduleCompositingLayerSync() +{ +// if (m_syncTimer.isActive()) +// return; +// +// m_syncTimer.startOneShot(0); + + scheduleUpdateLayoutRunLoopObserver(); +} + +void LayerBackedDrawingArea::syncCompositingLayers() +{ + m_backingLayer->syncCompositingStateForThisLayerOnly(); + + bool didSync = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateRecursive(); + if (!didSync) { + + } +} + +void LayerBackedDrawingArea::setUpUpdateLayoutRunLoopObserver() +{ + if (m_updateLayoutRunLoopObserver) + return; + + // Run before Core Animations commit observer, which has order 2000000. + const CFIndex runLoopOrder = 2000000 - 1; + CFRunLoopObserverContext context = { 0, this, 0, 0, 0 }; + m_updateLayoutRunLoopObserver.adoptCF(CFRunLoopObserverCreate(0, + kCFRunLoopBeforeWaiting | kCFRunLoopExit, true /* repeats */, + runLoopOrder, updateLayoutRunLoopObserverCallback, &context)); +} + +void LayerBackedDrawingArea::scheduleUpdateLayoutRunLoopObserver() +{ + CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent(); + CFRunLoopWakeUp(currentRunLoop); + + if (CFRunLoopContainsObserver(currentRunLoop, m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes)) + return; + + CFRunLoopAddObserver(currentRunLoop, m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes); +} + +void LayerBackedDrawingArea::removeUpdateLayoutRunLoopObserver() +{ + // FIXME: cache the run loop ref? + CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes); +} + +void LayerBackedDrawingArea::updateLayoutRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* info) +{ + // Keep the drawing area alive while running the callback, since that does layout, + // which might replace this drawing area with one of another type. + RefPtr<LayerBackedDrawingArea> drawingArea = reinterpret_cast<LayerBackedDrawingArea*>(info); + drawingArea->updateLayoutRunLoopObserverFired(); +} + +void LayerBackedDrawingArea::updateLayoutRunLoopObserverFired() +{ + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<LayerBackedDrawingArea> protect(this); + + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; + + if (m_attached) + syncCompositingLayers(); +} + +void LayerBackedDrawingArea::onPageClose() +{ + platformClear(); +} + +} // namespace WebKit + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm new file mode 100644 index 0000000..83909be --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm @@ -0,0 +1,40 @@ +/* + * 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 "WebInspector.h" + +#import <wtf/text/WTFString.h> + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + NSString *path = [[NSBundle bundleWithIdentifier:@"com.apple.WebCore"] pathForResource:@"localizedStrings" ofType:@"js"]; + if (path) + return [[NSURL fileURLWithPath:path] absoluteString]; + return String(); +} + +} // 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 0000000..f3211f2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm @@ -0,0 +1,369 @@ +/* + * 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 "WebPage.h" + +#include "AccessibilityWebPageObject.h" +#include "DataReference.h" +#include "PluginView.h" +#include "WebCoreArgumentCoders.h" +#include "WebEvent.h" +#include "WebFrame.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/AXObjectCache.h> +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/HitTestResult.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/ScrollView.h> +#include <WebCore/TextIterator.h> +#include <WebCore/WindowsKeyboardCodes.h> +#include <WebKitSystemInterface.h> + +using namespace WebCore; + +namespace WebKit { + +void WebPage::platformInitialize() +{ + m_page->addSchedulePair(SchedulePair::create([NSRunLoop currentRunLoop], kCFRunLoopCommonModes)); + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + AccessibilityWebPageObject* mockAccessibilityElement = [[[AccessibilityWebPageObject 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::DidReceiveAccessibilityPageToken(dataToken)); + m_mockAccessibilityElement = mockAccessibilityElement; +#endif +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore&) +{ +} + +// FIXME: need to add support for input methods + +bool WebPage::interceptEditingKeyboardEvent(KeyboardEvent* evt, bool shouldSaveCommand) +{ + Node* node = evt->target()->toNode(); + ASSERT(node); + Frame* frame = node->document()->frame(); + ASSERT(frame); + + const PlatformKeyboardEvent* keyEvent = evt->keyEvent(); + if (!keyEvent) + return false; + const Vector<KeypressCommand>& commands = evt->keypressCommands(); + bool hasKeypressCommand = !commands.isEmpty(); + + bool eventWasHandled = false; + + if (shouldSaveCommand || !hasKeypressCommand) { + Vector<KeypressCommand> commandsList; + Vector<CompositionUnderline> underlines; + unsigned start; + unsigned end; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::InterpretKeyEvent(keyEvent->type()), + Messages::WebPageProxy::InterpretKeyEvent::Reply(commandsList, start, end, underlines), + m_pageID, CoreIPC::Connection::NoTimeout)) + return false; + if (commandsList.isEmpty()) + return eventWasHandled; + + if (commandsList[0].commandName == "setMarkedText") { + frame->editor()->setComposition(commandsList[0].text, underlines, start, end); + eventWasHandled = true; + } else if (commandsList[0].commandName == "insertText" && frame->editor()->hasComposition()) { + frame->editor()->confirmComposition(commandsList[0].text); + eventWasHandled = true; + } else if (commandsList[0].commandName == "unmarkText") { + frame->editor()->confirmComposition(); + eventWasHandled = true; + } else { + for (size_t i = 0; i < commandsList.size(); i++) + evt->keypressCommands().append(commandsList[i]); + } + } else { + size_t size = commands.size(); + // Are there commands that would 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 < size; ++i) { + if (frame->editor()->command(commands[i].commandName).isTextInsertion()) + haveTextInsertionCommands = true; + } + if (!haveTextInsertionCommands || keyEvent->type() == PlatformKeyboardEvent::Char) { + for (size_t i = 0; i < size; ++i) { + if (commands[i].commandName == "insertText") { + // Don't insert null or control characters as they can result in unexpected behaviour + if (evt->charCode() < ' ') + return false; + eventWasHandled = frame->editor()->insertText(commands[i].text, evt); + } else + if (frame->editor()->command(commands[i].commandName).isSupported()) + eventWasHandled = frame->editor()->command(commands[i].commandName).execute(evt); + } + } + } + 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::getMarkedRange(uint64_t& location, uint64_t& length) +{ + location = NSNotFound; + length = 0; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + getLocationAndLengthFromRange(frame->editor()->compositionRange().get(), location, length); +} + +static Range *characterRangeAtPoint(Frame* frame, const IntPoint point) +{ + VisiblePosition position = frame->visiblePositionForPoint(point); + if (position.isNull()) + return NULL; + + VisiblePosition previous = position.previous(); + if (previous.isNotNull()) { + Range *previousCharacterRange = makeRange(previous, position).get(); + NSRect rect = frame->editor()->firstRectForRange(previousCharacterRange); + if (NSPointInRect(point, rect)) + return previousCharacterRange; + } + + VisiblePosition next = position.next(); + if (next.isNotNull()) { + Range *nextCharacterRange = makeRange(position, next).get(); + NSRect rect = frame->editor()->firstRectForRange(nextCharacterRange); + if (NSPointInRect(point, rect)) + return nextCharacterRange; + } + + return NULL; +} + +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(); + + Range *range = characterRangeAtPoint(frame, result.point()); + if (!range) + return; + + uint64_t length; + getLocationAndLengthFromRange(range, index, length); +} + +static 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. + Element* selectionRoot = frame->selection()->rootEditableElement(); + Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement(); + return TextIterator::rangeFromLocationAndLength(scope, 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) { + ASSERT(range->startContainer()); + ASSERT(range->endContainer()); + } + + IntRect rect = frame->editor()->firstRectForRange(range.get()); + resultRect = frame->view()->contentsToWindow(rect); +} + +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) + return false; + + // FIXME: This should be in WebCore. + + switch (keyboardEvent.windowsVirtualKeyCode()) { + case VK_BACK: + if (keyboardEvent.shiftKey()) + m_page->goForward(); + else + m_page->goBack(); + break; + case VK_SPACE: + if (keyboardEvent.shiftKey()) + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage); + else + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage); + break; + case VK_PRIOR: + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage); + break; + case VK_NEXT: + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage); + break; + case VK_HOME: + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument); + break; + case VK_END: + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument); + break; + case VK_UP: + if (keyboardEvent.shiftKey()) + return false; + if (keyboardEvent.metaKey()) { + scroll(m_page.get(), ScrollUp, ScrollByDocument); + scroll(m_page.get(), ScrollLeft, ScrollByDocument); + } else if (keyboardEvent.altKey() || keyboardEvent.controlKey()) + scroll(m_page.get(), ScrollUp, ScrollByPage); + else + scroll(m_page.get(), ScrollUp, ScrollByLine); + break; + case VK_DOWN: + if (keyboardEvent.shiftKey()) + return false; + if (keyboardEvent.metaKey()) { + scroll(m_page.get(), ScrollDown, ScrollByDocument); + scroll(m_page.get(), ScrollLeft, ScrollByDocument); + } else if (keyboardEvent.altKey() || keyboardEvent.controlKey()) + scroll(m_page.get(), ScrollDown, ScrollByPage); + else + scroll(m_page.get(), ScrollDown, ScrollByLine); + break; + case VK_LEFT: + if (keyboardEvent.shiftKey()) + return false; + if (keyboardEvent.metaKey()) + m_page->goBack(); + else { + if (keyboardEvent.altKey() | keyboardEvent.controlKey()) + scroll(m_page.get(), ScrollLeft, ScrollByPage); + else + scroll(m_page.get(), ScrollLeft, ScrollByLine); + } + break; + case VK_RIGHT: + if (keyboardEvent.shiftKey()) + return false; + if (keyboardEvent.metaKey()) + m_page->goForward(); + else { + if (keyboardEvent.altKey() || keyboardEvent.controlKey()) + scroll(m_page.get(), ScrollRight, ScrollByPage); + else + scroll(m_page.get(), ScrollRight, ScrollByLine); + } + break; + default: + return false; + } + + return true; +} + +void WebPage::sendAccessibilityPresenterToken(const CoreIPC::DataReference& data) +{ +#if !defined(BUILDING_ON_SNOW_LEOPARD) + NSData* tokenData = [NSData dataWithBytes:data.data() length:data.size()]; + [m_mockAccessibilityElement.get() setRemoteParent:WKAXRemoteElementForToken((CFDataRef)tokenData)]; +#endif +} + +AccessibilityWebPageObject* 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 = [[NSURLCache sharedURLCache] cachedResponseForRequest:request]; + [request release]; + + return cachedResponse; +} + +bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request) +{ + if ([NSURLConnection canHandleRequest:request.nsURLRequest()]) + return YES; + + // FIXME: Return true if this scheme is any one WebKit2 knows how to handle. + return request.url().protocolIs("applewebdata"); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/qt/ChunkedUpdateDrawingAreaQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/ChunkedUpdateDrawingAreaQt.cpp new file mode 100644 index 0000000..25ed3e7 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/ChunkedUpdateDrawingAreaQt.cpp @@ -0,0 +1,50 @@ +/* + * 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 "ChunkedUpdateDrawingArea.h" + +#include "UpdateChunk.h" +#include "WebPage.h" +#include <QImage> +#include <QPainter> +#include <WebCore/GraphicsContext.h> + +using namespace WebCore; + +namespace WebKit { + +void ChunkedUpdateDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk) +{ + QImage image(updateChunk->createImage()); + QPainter painter(&image); + // Now paint into the backing store. + GraphicsContext graphicsContext(&painter); + graphicsContext.translate(-updateChunk->rect().x(), -updateChunk->rect().y()); + + m_webPage->drawRect(graphicsContext, updateChunk->rect()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp new file mode 100644 index 0000000..b7ad782 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#if ENABLE(TILED_BACKING_STORE) + +#include "TiledDrawingArea.h" + +#include "UpdateChunk.h" +#include "WebPage.h" +#include <WebCore/GraphicsContext.h> + +#include <QImage> +#include <QPainter> + +using namespace WebCore; + +namespace WebKit { + +void TiledDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk, float scale) +{ + IntRect tileRect = updateChunk->rect(); + QImage image(updateChunk->createImage()); + QPainter painter(&image); + // Now paint into the backing store. + GraphicsContext graphicsContext(&painter); + graphicsContext.translate(-tileRect.x(), -tileRect.y()); + graphicsContext.scale(FloatSize(scale, scale)); + IntRect contentRect = enclosingIntRect(FloatRect(tileRect.x() / scale, + tileRect.y() / scale, + tileRect.width() / scale, + tileRect.height() / scale)); + m_webPage->drawRect(graphicsContext, contentRect); +} + +} // namespace WebKit + +#endif // TILED_BACKING_STORE diff --git a/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp new file mode 100644 index 0000000..99aa1eb --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp @@ -0,0 +1,45 @@ +/* + * 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 "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include <wtf/text/WTFString.h> + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.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 0000000..fe1a89c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp @@ -0,0 +1,279 @@ +/* + * 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 "WebPage.h" + +#include "WebEvent.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> + +#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() +{ +} + +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 WebCore::KURL&) +{ + // FIXME: Implement + return false; +} + +bool WebPage::canHandleRequest(const WebCore::ResourceRequest&) +{ + // FIXME: Implement + return true; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/win/ChunkedUpdateDrawingAreaWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/ChunkedUpdateDrawingAreaWin.cpp new file mode 100644 index 0000000..aa1f975 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/ChunkedUpdateDrawingAreaWin.cpp @@ -0,0 +1,63 @@ +/* + * 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 "ChunkedUpdateDrawingArea.h" + +#include "UpdateChunk.h" +#include "WebPage.h" +#include <WebCore/BitmapInfo.h> +#include <WebCore/GraphicsContext.h> + +using namespace WebCore; + +namespace WebKit { + +void ChunkedUpdateDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk) +{ + OwnPtr<HDC> hdc(::CreateCompatibleDC(0)); + + void* bits; + BitmapInfo bmp = BitmapInfo::createBottomUp(updateChunk->rect().size()); + OwnPtr<HBITMAP> hbmp(::CreateDIBSection(0, &bmp, DIB_RGB_COLORS, &bits, updateChunk->memory(), 0)); + + HBITMAP hbmpOld = static_cast<HBITMAP>(::SelectObject(hdc.get(), hbmp.get())); + + GraphicsContext gc(hdc.get()); + gc.save(); + + // FIXME: Is this white fill needed? + RECT rect = updateChunk->rect(); + ::FillRect(hdc.get(), &rect, (HBRUSH)::GetStockObject(WHITE_BRUSH)); + gc.translate(-updateChunk->rect().x(), -updateChunk->rect().y()); + + m_webPage->drawRect(gc, updateChunk->rect()); + + gc.restore(); + + // Re-select the old HBITMAP + ::SelectObject(hdc.get(), hbmpOld); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/win/LayerBackedDrawingAreaWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/LayerBackedDrawingAreaWin.cpp new file mode 100644 index 0000000..c07e1f5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/LayerBackedDrawingAreaWin.cpp @@ -0,0 +1,74 @@ +/* + * 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 USE(ACCELERATED_COMPOSITING) + +#include "LayerBackedDrawingArea.h" + +#include "DrawingAreaProxyMessageKinds.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsLayer.h> +#include <WebCore/Page.h> +#include <WebCore/WKCACFLayerRenderer.h> +#include <WebCore/WebCoreInstanceHandle.h> + +using namespace WebCore; + +namespace WebKit { + +void LayerBackedDrawingArea::platformInit() +{ +} + +void LayerBackedDrawingArea::platformClear() +{ +} + +void LayerBackedDrawingArea::attachCompositingContext() +{ +} + +void LayerBackedDrawingArea::detachCompositingContext() +{ +} + +void LayerBackedDrawingArea::setRootCompositingLayer(WebCore::GraphicsLayer* layer) +{ +} + +void LayerBackedDrawingArea::scheduleCompositingLayerSync() +{ +} + +void LayerBackedDrawingArea::syncCompositingLayers() +{ +} + +} // namespace WebKit + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp new file mode 100644 index 0000000..4c30b8b --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp @@ -0,0 +1,46 @@ +/* + * 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 "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include <wtf/RetainPtr.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + RetainPtr<CFURLRef> localizedStringsURLRef(AdoptCF, CFBundleCopyResourceURL(CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebKit")), 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 0000000..d41972c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp @@ -0,0 +1,310 @@ +/* + * 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 "WebPage.h" + +#include "FontSmoothingLevel.h" +#include "WebEvent.h" +#include "WebPreferencesStore.h" +#include <WebCore/FocusController.h> +#include <WebCore/FontRenderingMode.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/Settings.h> +#if PLATFORM(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() +{ + m_page->settings()->setFontRenderingMode(AlternateRenderingMode); +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store) +{ + FontSmoothingLevel fontSmoothingLevel = static_cast<FontSmoothingLevel>(store.getUInt32ValueForKey(WebPreferencesKey::fontSmoothingLevelKey())); + +#if PLATFORM(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; +} + +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_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 WebCore::KURL& url) +{ +#if USE(CFNETWORK) + RetainPtr<CFURLRef> cfURL(AdoptCF, url.createCFURL()); + RetainPtr<CFMutableURLRequestRef> request(AdoptCF, CFURLRequestCreateMutable(0, cfURL.get(), kCFURLRequestCachePolicyReloadIgnoringCache, 60, 0)); + + RetainPtr<CFStringRef> userAgent(AdoptCF, userAgent().createCFString()); + CFURLRequestSetHTTPHeaderFieldValue(request.get(), CFSTR("User-Agent"), userAgent.get()); + + RetainPtr<CFURLCacheRef> cache(AdoptCF, CFURLCacheCopySharedURLCache()); + + RetainPtr<CFCachedURLResponseRef> response(AdoptCF, CFURLCacheCopyResponseForRequest(cache.get(), request.get())); + return response; +#else + return false; +#endif +} + +bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request) +{ +#if USE(CFNETWORK) + // FIXME: Are there other requests we need to be able to handle? WebKit1's WebView.cpp has a FIXME here as well. + 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(); +} + +} // namespace WebKit |
