Skip to content

Instantly share code, notes, and snippets.

@kenchris
Created January 23, 2012 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenchris/1663608 to your computer and use it in GitHub Desktop.
Save kenchris/1663608 to your computer and use it in GitHub Desktop.
commit e702addddefe6e3246db463a169d9007cce50f4f
Author: Kenneth Rohde Christiansen <kenneth@webkit.org>
Date: Mon Jan 23 16:06:02 2012 +0100
WIP: tap highlighting
diff --git a/Source/WebCore/Target.pri b/Source/WebCore/Target.pri
index 457db0c..45d9858 100644
--- a/Source/WebCore/Target.pri
+++ b/Source/WebCore/Target.pri
@@ -985,6 +985,7 @@ SOURCES += \
page/FrameView.cpp \
page/Geolocation.cpp \
page/GeolocationController.cpp \
+ page/GestureTapHighlighter.cpp \
page/GroupSettings.cpp \
page/History.cpp \
page/Location.cpp \
@@ -2044,6 +2045,7 @@ HEADERS += \
page/FrameView.h \
page/Geolocation.h \
page/Geoposition.h \
+ page/GestureTapHighlighter.h\
page/GroupSettings.h \
page/History.h \
page/Location.h \
diff --git a/Source/WebCore/page/GestureTapHighlighter.cpp b/Source/WebCore/page/GestureTapHighlighter.cpp
new file mode 100644
index 0000000..87193a1
--- /dev/null
+++ b/Source/WebCore/page/GestureTapHighlighter.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2012 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GestureTapHighlighter.h"
+
+#include "Element.h"
+#include "Frame.h"
+#include "FrameView.h"
+
+#include "GraphicsContext.h"
+#include "GraphicsTypes.h"
+#include "Node.h"
+#include "Page.h"
+#include "RenderBoxModelObject.h"
+#include "RenderInline.h"
+#include "RenderObject.h"
+#include "RenderLayer.h"
+
+namespace WebCore {
+
+namespace{
+
+inline LayoutSize frameToMainFrameOffset(Frame* frame)
+{
+ LayoutPoint mainFramePoint = frame->page()->mainFrame()->view()->rootViewToContents(frame->view()->contentsToRootView(LayoutPoint()));
+ return toLayoutSize(mainFramePoint);
+}
+
+} // anonymous namespace
+
+namespace GestureTapHighlighter {
+
+void drawHighlight(GraphicsContext* context, Node* node)
+{
+ RenderObject* renderer = node->renderer();
+ Frame* containingFrame = node->document()->frame();
+
+ if (!renderer || !containingFrame || !context)
+ return;
+
+ LayoutSize mainFrameOffset = frameToMainFrameOffset(containingFrame);
+
+ // Don't translate the context if the frame is rendered in page coordinates.
+ FrameView* view = containingFrame->page()->mainFrame()->view();
+ if (!view->delegatesScrolling()) {
+ FloatRect visibleRect = view->visibleContentRect();
+ context->translate(-visibleRect.x(), -visibleRect.y());
+ }
+
+ if (renderer->isBox() || renderer->isRenderInline()) {
+ LayoutRect contentBox;
+ LayoutRect paddingBox;
+ LayoutRect borderBox;
+
+ if (renderer->isBox()) {
+ RenderBox* renderBox = toRenderBox(renderer);
+ contentBox = renderBox->contentBoxRect();
+ paddingBox = LayoutRect(contentBox.x() - renderBox->paddingLeft(), contentBox.y() - renderBox->paddingTop(),
+ contentBox.width() + renderBox->paddingLeft() + renderBox->paddingRight(), contentBox.height() + renderBox->paddingTop() + renderBox->paddingBottom());
+ borderBox = LayoutRect(paddingBox.x() - renderBox->borderLeft(), paddingBox.y() - renderBox->borderTop(),
+ paddingBox.width() + renderBox->borderLeft() + renderBox->borderRight(), paddingBox.height() + renderBox->borderTop() + renderBox->borderBottom());
+ } else {
+ RenderInline* renderInline = toRenderInline(renderer);
+ // RenderInline's bounding box includes paddings and borders, excludes margins.
+ borderBox = renderInline->linesBoundingBox();
+ }
+
+ RoundedRect rect(borderBox);
+ rect.expandRadii(10);
+ rect.inflateWithRadii(5);
+
+
+ AffineTransform trans;
+
+
+ LayoutPoint referencePoint;
+ while (renderer) {
+ RenderObject* next = renderer->container();
+ if (!next)
+ break;
+
+ LayoutSize containerOffset = renderer->offsetFromContainer(next, referencePoint);
+ TransformationMatrix t;
+ renderer->getTransformFromContainer(next, containerOffset, t);
+
+ trans *= t.toAffineTransform();
+ referencePoint.move(containerOffset);
+ renderer = next;
+ }
+
+ rect.move(mainFrameOffset);
+
+ context->concatCTM(trans);
+ context->fillRoundedRect(rect, node->renderer()->style()->tapHighlightColor(), ColorSpaceDeviceRGB);
+ }
+}
+
+} // namespace GestureTapHighlighter
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/GestureTapHighlighter.h b/Source/WebCore/page/GestureTapHighlighter.h
new file mode 100644
index 0000000..e8092f3
--- /dev/null
+++ b/Source/WebCore/page/GestureTapHighlighter.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 GestureTapHighlighter_h
+#define GestureTapHighlighter_h
+
+namespace WebCore {
+
+class Color;
+class GraphicsContext;
+class Node;
+
+namespace GestureTapHighlighter {
+
+void drawHighlight(GraphicsContext*, Node*);
+
+} // namespace GestureTapHighlighter
+
+} // namespace WebCore
+
+#endif // DOMNodeHighlighter_h
diff --git a/Source/WebKit2/Target.pri b/Source/WebKit2/Target.pri
index 35983f0..7d6e7b0 100644
--- a/Source/WebKit2/Target.pri
+++ b/Source/WebKit2/Target.pri
@@ -348,6 +348,7 @@ HEADERS += \
WebProcess/WebPage/DrawingAreaImpl.h \
WebProcess/WebPage/EventDispatcher.h \
WebProcess/WebPage/FindController.h \
+ WebProcess/WebPage/TapHighlightController.h \
WebProcess/WebPage/PageOverlay.h \
WebProcess/WebPage/WebContextMenu.h \
WebProcess/WebPage/WebFrame.h \
@@ -701,6 +702,7 @@ SOURCES += \
WebProcess/WebPage/EncoderAdapter.cpp \
WebProcess/WebPage/EventDispatcher.cpp \
WebProcess/WebPage/FindController.cpp \
+ WebProcess/WebPage/TapHighlightController.cpp \
WebProcess/WebPage/LayerTreeHost.cpp \
WebProcess/WebPage/PageOverlay.cpp \
WebProcess/WebPage/TiledBackingStoreRemoteTile.cpp \
diff --git a/Source/WebKit2/WebProcess/WebPage/TapHighlightController.cpp b/Source/WebKit2/WebProcess/WebPage/TapHighlightController.cpp
new file mode 100644
index 0000000..3dfcb5a
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/TapHighlightController.cpp
@@ -0,0 +1,76 @@
+#include "config.h"
+#include "TapHighlightController.h"
+
+#include "ShareableBitmap.h"
+#include "WKPage.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include "WebProcess.h"
+#include <WebCore/FocusController.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/GraphicsContext.h>
+#include <WebCore/Page.h>
+#include <WebCore/GestureTapHighlighter.h>
+
+using namespace std;
+using namespace WebCore;
+
+namespace WebKit {
+
+TapHighlightController::TapHighlightController(WebPage* webPage)
+ : m_webPage(webPage)
+ , m_overlay(0)
+ , m_node(0)
+{
+}
+
+TapHighlightController::~TapHighlightController()
+{
+}
+
+void TapHighlightController::highlight(Node* node)
+{
+ m_node = node;
+
+ if (!m_overlay) {
+ RefPtr<PageOverlay> overlay = PageOverlay::create(this);
+ m_overlay = overlay.get();
+ m_webPage->installPageOverlay(overlay.release());
+ } else
+ m_overlay->setNeedsDisplay();
+}
+
+void TapHighlightController::pageOverlayDestroyed(PageOverlay*)
+{
+}
+
+void TapHighlightController::willMoveToWebPage(PageOverlay*, WebPage* webPage)
+{
+ if (webPage)
+ return;
+
+ // The page overlay is moving away from the web page, reset it.
+// ASSERT(m_overlay);
+ // m_overlay = 0;
+}
+
+void TapHighlightController::didMoveToWebPage(PageOverlay*, WebPage*)
+{
+}
+
+void TapHighlightController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
+{
+ if (!m_node)
+ return;
+
+ GestureTapHighlighter::drawHighlight(&graphicsContext, m_node);
+}
+
+bool TapHighlightController::mouseEvent(PageOverlay* pageOverlay, const WebMouseEvent& mouseEvent)
+{
+ return false;
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/TapHighlightController.h b/Source/WebKit2/WebProcess/WebPage/TapHighlightController.h
new file mode 100644
index 0000000..56577a6
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/TapHighlightController.h
@@ -0,0 +1,44 @@
+#ifndef TapHighlightController_h
+#define TapHighlightController_h
+
+#include "PageOverlay.h"
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+ class Frame;
+ class IntRect;
+ class Node;
+}
+
+namespace WebKit {
+
+class WebPage;
+
+class TapHighlightController : private PageOverlay::Client {
+ WTF_MAKE_NONCOPYABLE(TapHighlightController);
+
+public:
+ explicit TapHighlightController(WebPage*);
+ virtual ~TapHighlightController();
+
+ void highlight(WebCore::Node*);
+
+private:
+ // PageOverlay::Client.
+ virtual void pageOverlayDestroyed(PageOverlay*);
+ virtual void willMoveToWebPage(PageOverlay*, WebPage*);
+ virtual void didMoveToWebPage(PageOverlay*, WebPage*);
+ virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&);
+ virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect);
+
+private:
+ WebPage* m_webPage;
+ PageOverlay* m_overlay;
+ WebCore::Node* m_node;
+};
+
+} // namespace WebKit
+
+#endif // TapHighlightController_h
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
index 365d578..472e728 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -43,6 +43,7 @@
#include "RunLoop.h"
#include "SessionState.h"
#include "ShareableBitmap.h"
+#include "TapHighlightController.h"
#include "WebBackForwardList.h"
#include "WebBackForwardListItem.h"
#include "WebBackForwardListProxy.h"
@@ -175,6 +176,8 @@ PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParame
return page.release();
}
+static TapHighlightController* hack;
+
WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
: m_viewSize(parameters.viewSize)
, m_useFixedLayout(false)
@@ -228,6 +231,8 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
m_page = adoptPtr(new Page(pageClients));
+ hack = new TapHighlightController(this);
+
// 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,
@@ -1365,6 +1370,18 @@ void WebPage::gestureEvent(const WebGestureEvent& gestureEvent)
{
CurrentEvent currentEvent(gestureEvent);
+ Frame* mainframe = m_page->mainFrame();
+ HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(gestureEvent.position()), /*allowShadowContent*/ false, /*ignoreClipping*/ true);
+
+ Node* node = result.innerNode();
+ if (!node->isFocusable())
+ node = node->enclosingLinkEventParentOrSelf();
+
+ if (node) {
+ printf("Node %p\n", node);
+ hack->highlight(node);
+ }
+
bool handled = handleGestureEvent(gestureEvent, m_page.get());
send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled));
}
diff --git a/transformtest.html b/transformtest.html
new file mode 100644
index 0000000..39652c1
--- /dev/null
+++ b/transformtest.html
@@ -0,0 +1,10 @@
+<h1>
+<input style='position:absolute; left:10px; top:10px;' type='text'>
+<input style='position:absolute; left:0px; top:300px; -webkit-transform:skew(30deg) rotate(-40deg) scale(1.2);' type='text'>
+<input style='position:absolute; left:100px; top:100px; -webkit-transform: rotate(-20deg) scale(1.5);' type='button' value='hest#1'>
+<div style='position:absolute; left:400px; top:200px; -webkit-transform:rotate(10deg);'><a href='#'>hest#2</a></div>
+<div style='position:absolute; left:300px; top:100px; -webkit-transform:rotate(70deg);'><div style=' -webkit-transform:rotate(10deg);'><a href='#'>hest#3</a></div></div>
+<div style='-webkit-transform:rotate(70deg); width:200px'><div style='position:absolute; left:400px; top:-100px; -webkit-transform:rotate(10deg);'><a href='#'>hest#4</a></div></div>
+<a href='#' style='position:absolute;left:500px'>hest#5</a>
+<div style='position:absolute;left:640px'><a href='#'>hest#6</a>
+</h1>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment