Title: [137603] branches/chromium/1359

Diff

Copied: branches/chromium/1359/LayoutTests/platform/chromium/fast/events/touch/compositor-touch-hit-rects-expected.txt (from rev 137570, trunk/LayoutTests/platform/chromium/fast/events/touch/compositor-touch-hit-rects-expected.txt) (0 => 137603)


--- branches/chromium/1359/LayoutTests/platform/chromium/fast/events/touch/compositor-touch-hit-rects-expected.txt	                        (rev 0)
+++ branches/chromium/1359/LayoutTests/platform/chromium/fast/events/touch/compositor-touch-hit-rects-expected.txt	2012-12-13 17:18:19 UTC (rev 137603)
@@ -0,0 +1,46 @@
+This tests verifies the hit test regions given to the compositor. It can only be run in DumpRenderTree. The outputted rects should cover the hit test regions of all the listed elements.
+
+normalFlow[0]: (8, 72, 784, 10)
+normalFlow[1]: (8, 72, 784, 10)
+normalFlow[2]: (128, 72, 30, 10)
+normalFlow[3]: (8, 72, 784, 10)
+absoluteChildContainer[0]: (8, 162, 784, 10)
+absoluteChildContainer[1]: (8, 162, 784, 10)
+absoluteChildContainer[2]: (8, 162, 784, 10)
+absoluteChildContainer[3]: (118, 300, 140, 10)
+absoluteChildContainer[4]: (118, 300, 140, 10)
+relativeChildContainer[0]: (8, 272, 784, 10)
+relativeChildContainer[1]: (8, 272, 784, 10)
+relativeChildContainer[2]: (8, 272, 784, 10)
+relativeChildContainer[3]: (128, 472, 140, 10)
+overhangingContainer[0]: (8, 362, 784, 10)
+overhangingContainer[1]: (8, 362, 110, 80)
+overhangingContainer[2]: (8, 362, 110, 80)
+transformedChildContainer[0]: (62, 421, 661, 32)
+transformedChildContainer[1]: (62, 421, 661, 32)
+transformedChildContainer[2]: (8, 432, 769, 10)
+continuation[0]: (108, 502, 100, 10)
+
+This tests verifies the hit test regions given to the compositor. It can only be run in DumpRenderTree. The outputted rects should cover the hit test regions of all the listed elements.
+
+normalFlow[0]: (8, 72, 784, 10)
+normalFlow[1]: (8, 72, 784, 10)
+normalFlow[2]: (128, 72, 30, 10)
+normalFlow[3]: (8, 72, 784, 10)
+absoluteChildContainer[0]: (8, 162, 784, 10)
+absoluteChildContainer[1]: (8, 162, 784, 10)
+absoluteChildContainer[2]: (8, 162, 784, 10)
+absoluteChildContainer[3]: (118, 300, 140, 10)
+absoluteChildContainer[4]: (118, 300, 140, 10)
+relativeChildContainer[0]: (8, 272, 784, 10)
+relativeChildContainer[1]: (8, 272, 784, 10)
+relativeChildContainer[2]: (8, 272, 784, 10)
+relativeChildContainer[3]: (128, 472, 140, 10)
+overhangingContainer[0]: (8, 362, 784, 10)
+overhangingContainer[1]: (8, 362, 110, 80)
+overhangingContainer[2]: (8, 362, 110, 80)
+transformedChildContainer[0]: (62, 421, 661, 32)
+transformedChildContainer[1]: (62, 421, 661, 32)
+transformedChildContainer[2]: (8, 432, 769, 10)
+continuation[0]: (108, 502, 100, 10)
+

Copied: branches/chromium/1359/LayoutTests/platform/chromium/fast/events/touch/compositor-touch-hit-rects.html (from rev 137570, trunk/LayoutTests/platform/chromium/fast/events/touch/compositor-touch-hit-rects.html) (0 => 137603)


--- branches/chromium/1359/LayoutTests/platform/chromium/fast/events/touch/compositor-touch-hit-rects.html	                        (rev 0)
+++ branches/chromium/1359/LayoutTests/platform/chromium/fast/events/touch/compositor-touch-hit-rects.html	2012-12-13 17:18:19 UTC (rev 137603)
@@ -0,0 +1,200 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#transformedChild {
+	-webkit-transform: rotate3d(0.2, 1, 0, 35grad);
+}
+#absoluteChild {
+	position: absolute;
+	top: 300px;
+}
+#relativeChild {
+	position: relative;
+	top: 200px;
+}
+#overhangingContainer {
+	height: 10px;
+}
+#overhangingFloatingChild {
+	width: 100px;
+	float: left;
+}
+#tests {
+	font: 10px Ahem;
+}
+</style>
+</head>
+<body>
+<p id="description">This tests verifies the hit test regions given to the compositor. It can only be run in DumpRenderTree.
+The outputted rects should cover the hit test regions of all the listed elements.</p>
+<div id="console"></div>
+
+<div id="tests">
+	<div id="normalFlow">
+		Lorem ipsum
+		<span>sum</span>.
+	</div>
+	<div id="absoluteChildContainer">
+		Lorem ipsum
+		<span id="absoluteChild">Absolute child</span>
+	</div>
+	<div id="relativeChildContainer">
+		Lorem ipsum
+		<span id="relativeChild">Relative child</span>
+	</div>
+	<div id="overhangingContainer">
+		<div id="overhangingFloatingChild">Overhanging float overhanging float overhanging float overhanging float</div>
+	</div>
+	<div id="transformedChildContainer">
+		<div id="transformedChild">Transformed</div>
+	</div>
+	<div>
+		<b id="continuation">This b tag
+		<div>causes a</div>
+		continuation</b>
+	</div>
+</div>
+<script>
+if (!window.testRunner)
+	return;
+
+window.testRunner.dumpAsText();
+
+function listener() { }
+
+function log(msg) {
+	var span = document.createElement("span");
+	document.getElementById("console").appendChild(span);
+    span.innerHTML = msg + '<br />';
+}
+
+function sortRects(a, b) {
+	return a.top - b.top;
+}
+
+function logRects(id) {
+	element = document.getElementById(id);
+	element.addEventListener('touchstart', listener, false);
+	rects = window.internals.touchEventTargetClientRects(document);
+	var sortedRects = new Array();
+	for (var i = 0; i < rects.length; ++i)
+		sortedRects[i] = rects[i];
+	sortedRects.sort(sortRects);
+	for (var i = 0; i < rects.length; ++i)
+		log(id + "[" + i + "]: (" + sortedRects[i].left + ", " + sortedRects[i].top + ", " + sortedRects[i].width + ", " + sortedRects[i].height + ")");
+	element.removeEventListener('touchstart', listener, false);
+}
+
+logRects("normalFlow");
+logRects("absoluteChildContainer");
+logRects("relativeChildContainer");
+logRects("overhangingContainer");
+logRects("transformedChildContainer");
+logRects("continuation");
+
+var testContainer = document.getElementById("tests");
+testContainer.parentNode.removeChild(testContainer);
+
+</script>
+</body>
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#transformedChild {
+	-webkit-transform: rotate3d(0.2, 1, 0, 35grad);
+}
+#absoluteChild {
+	position: absolute;
+	top: 300px;
+}
+#relativeChild {
+	position: relative;
+	top: 200px;
+}
+#overhangingContainer {
+	height: 10px;
+}
+#overhangingFloatingChild {
+	width: 100px;
+	float: left;
+}
+#tests {
+	font: 10px Ahem;
+}
+</style>
+</head>
+<body>
+<p id="description">This tests verifies the hit test regions given to the compositor. It can only be run in DumpRenderTree.
+The outputted rects should cover the hit test regions of all the listed elements.</p>
+<div id="console"></div>
+
+<div id="tests">
+	<div id="normalFlow">
+		Lorem ipsum
+		<span>sum</span>.
+	</div>
+	<div id="absoluteChildContainer">
+		Lorem ipsum
+		<span id="absoluteChild">Absolute child</span>
+	</div>
+	<div id="relativeChildContainer">
+		Lorem ipsum
+		<span id="relativeChild">Relative child</span>
+	</div>
+	<div id="overhangingContainer">
+		<div id="overhangingFloatingChild">Overhanging float overhanging float overhanging float overhanging float</div>
+	</div>
+	<div id="transformedChildContainer">
+		<div id="transformedChild">Transformed</div>
+	</div>
+	<div>
+		<b id="continuation">This b tag
+		<div>causes a</div>
+		continuation</b>
+	</div>
+</div>
+<script>
+if (!window.testRunner)
+	return;
+
+window.testRunner.dumpAsText();
+
+function listener() { }
+
+function log(msg) {
+	var span = document.createElement("span");
+	document.getElementById("console").appendChild(span);
+    span.innerHTML = msg + '<br />';
+}
+
+function sortRects(a, b) {
+	return a.top - b.top;
+}
+
+function logRects(id) {
+	element = document.getElementById(id);
+	element.addEventListener('touchstart', listener, false);
+	rects = window.internals.touchEventTargetClientRects(document);
+	var sortedRects = new Array();
+	for (var i = 0; i < rects.length; ++i)
+		sortedRects[i] = rects[i];
+	sortedRects.sort(sortRects);
+	for (var i = 0; i < rects.length; ++i)
+		log(id + "[" + i + "]: (" + sortedRects[i].left + ", " + sortedRects[i].top + ", " + sortedRects[i].width + ", " + sortedRects[i].height + ")");
+	element.removeEventListener('touchstart', listener, false);
+}
+
+logRects("normalFlow");
+logRects("absoluteChildContainer");
+logRects("relativeChildContainer");
+logRects("overhangingContainer");
+logRects("transformedChildContainer");
+logRects("continuation");
+
+var testContainer = document.getElementById("tests");
+testContainer.parentNode.removeChild(testContainer);
+
+</script>
+</body>

Modified: branches/chromium/1359/Source/WebCore/dom/Document.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/dom/Document.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/dom/Document.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -498,9 +498,6 @@
     , m_writeRecursionIsTooDeep(false)
     , m_writeRecursionDepth(0)
     , m_wheelEventHandlerCount(0)
-#if ENABLE(TOUCH_EVENTS)
-    , m_touchEventHandlerCount(0)
-#endif
     , m_pendingTasksTimer(this, &Document::pendingTasksTimerFired)
     , m_scheduledTasksAreSuspended(false)
     , m_visualUpdatesAllowed(true)
@@ -5599,33 +5596,57 @@
     wheelEventHandlerCountChanged(this);
 }
 
-void Document::didAddTouchEventHandler()
+void Document::didAddTouchEventHandler(Node* handler)
 {
 #if ENABLE(TOUCH_EVENTS)
-    ++m_touchEventHandlerCount;
-    if (m_touchEventHandlerCount > 1)
+    if (!m_touchEventTargets.get())
+        m_touchEventTargets = adoptPtr(new TouchEventTargetSet);
+    m_touchEventTargets->add(handler);
+    if (Document* parent = parentDocument()) {
+        parent->didAddTouchEventHandler(this);
         return;
-    if (Page* page = this->page())
-        page->chrome()->client()->needTouchEvents(true);
+    }
+    if (Page* page = this->page()) {
+#if ENABLE(TOUCH_EVENT_TRACKING)
+        if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+            scrollingCoordinator->touchEventTargetRectsDidChange(this);
 #endif
+        if (m_touchEventTargets->size() == 1)
+            page->chrome()->client()->needTouchEvents(true);
+    }
+#else
+    UNUSED_PARAM(handler);
+#endif
 }
 
-void Document::didRemoveTouchEventHandler()
+void Document::didRemoveTouchEventHandler(Node* handler)
 {
 #if ENABLE(TOUCH_EVENTS)
-    ASSERT(m_touchEventHandlerCount);
-    --m_touchEventHandlerCount;
-    if (m_touchEventHandlerCount)
+    if (!m_touchEventTargets.get())
         return;
+    ASSERT(m_touchEventTargets->contains(handler));
+    m_touchEventTargets->remove(handler);
+    if (Document* parent = parentDocument()) {
+        parent->didRemoveTouchEventHandler(this);
+        return;
+    }
 
     Page* page = this->page();
     if (!page)
         return;
+#if ENABLE(TOUCH_EVENT_TRACKING)
+    if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+        scrollingCoordinator->touchEventTargetRectsDidChange(this);
+#endif
+    if (m_touchEventTargets->size())
+        return;
     for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
-        if (frame->document() && frame->document()->touchEventHandlerCount())
+        if (frame->document() && frame->document()->hasTouchEventHandlers())
             return;
     }
     page->chrome()->client()->needTouchEvents(false);
+#else
+    UNUSED_PARAM(handler);
 #endif
 }
 

Modified: branches/chromium/1359/Source/WebCore/dom/Document.h (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/dom/Document.h	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/dom/Document.h	2012-12-13 17:18:19 UTC (rev 137603)
@@ -207,6 +207,8 @@
 };
 const int numNodeListInvalidationTypes = InvalidateOnAnyAttrChange + 1;
 
+typedef HashCountedSet<Node*> TouchEventTargetSet;
+
 class Document : public ContainerNode, public TreeScope, public ScriptExecutionContext {
 public:
     static PassRefPtr<Document> create(Frame* frame, const KURL& url)
@@ -1118,14 +1120,20 @@
     void didRemoveWheelEventHandler();
 
 #if ENABLE(TOUCH_EVENTS)
-    unsigned touchEventHandlerCount() const { return m_touchEventHandlerCount; }
+    bool hasTouchEventHandlers() const { return (m_touchEventTargets.get()) ? m_touchEventTargets->size() : false; }
 #else
-    unsigned touchEventHandlerCount() const { return 0; }
+    bool hasTouchEventHandlers() const { return false; }
 #endif
 
-    void didAddTouchEventHandler();
-    void didRemoveTouchEventHandler();
+    void didAddTouchEventHandler(Node*);
+    void didRemoveTouchEventHandler(Node*);
 
+#if ENABLE(TOUCH_EVENTS)
+    const TouchEventTargetSet* touchEventTargets() const { return m_touchEventTargets.get(); }
+#else
+    const TouchEventTargetSet* touchEventTargets() const { return 0; }
+#endif
+
     bool visualUpdatesAllowed() const { return m_visualUpdatesAllowed; }
 
 #if ENABLE(MICRODATA)
@@ -1503,7 +1511,7 @@
     
     unsigned m_wheelEventHandlerCount;
 #if ENABLE(TOUCH_EVENTS)
-    unsigned m_touchEventHandlerCount;
+    OwnPtr<TouchEventTargetSet> m_touchEventTargets;
 #endif
 
 #if ENABLE(REQUEST_ANIMATION_FRAME)

Modified: branches/chromium/1359/Source/WebCore/dom/Node.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/dom/Node.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/dom/Node.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -2122,8 +2122,8 @@
     for (size_t i = 0; i < touchEventNames.size(); ++i) {
         const EventListenerVector& listeners = getEventListeners(touchEventNames[i]);
         for (size_t j = 0; j < listeners.size(); ++j) {
-            oldDocument->didRemoveTouchEventHandler();
-            document()->didAddTouchEventHandler();
+            oldDocument->didRemoveTouchEventHandler(this);
+            document()->didAddTouchEventHandler(this);
         }
     }
 
@@ -2152,7 +2152,7 @@
         if (eventType == eventNames().mousewheelEvent)
             document->didAddWheelEventHandler();
         else if (eventNames().isTouchEventType(eventType))
-            document->didAddTouchEventHandler();
+            document->didAddTouchEventHandler(targetNode);
     }
 
     return true;
@@ -2174,7 +2174,7 @@
         if (eventType == eventNames().mousewheelEvent)
             document->didRemoveWheelEventHandler();
         else if (eventNames().isTouchEventType(eventType))
-            document->didRemoveTouchEventHandler();
+            document->didRemoveTouchEventHandler(targetNode);
     }
 
     return true;

Modified: branches/chromium/1359/Source/WebCore/history/CachedFrame.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/history/CachedFrame.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/history/CachedFrame.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -134,7 +134,7 @@
     m_document->enqueuePopstateEvent(historyItem && historyItem->stateObject() ? historyItem->stateObject() : SerializedScriptValue::nullValue());
     
 #if ENABLE(TOUCH_EVENTS)
-    if (m_document->touchEventHandlerCount())
+    if (m_document->hasTouchEventHandlers())
         m_document->page()->chrome()->client()->needTouchEvents(true);
 #endif
 

Modified: branches/chromium/1359/Source/WebCore/html/HTMLInputElement.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/html/HTMLInputElement.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/html/HTMLInputElement.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -163,7 +163,7 @@
         document()->formController()->checkedRadioButtons().removeButton(this);
 #if ENABLE(TOUCH_EVENTS)
     if (m_hasTouchEventHandler)
-        document()->didRemoveTouchEventHandler();
+        document()->didRemoveTouchEventHandler(this);
 #endif
 }
 
@@ -489,9 +489,9 @@
     bool hasTouchEventHandler = m_inputType->hasTouchEventHandler();
     if (hasTouchEventHandler != m_hasTouchEventHandler) {
       if (hasTouchEventHandler)
-        document()->didAddTouchEventHandler();
+        document()->didAddTouchEventHandler(this);
       else
-        document()->didRemoveTouchEventHandler();
+        document()->didRemoveTouchEventHandler(this);
       m_hasTouchEventHandler = hasTouchEventHandler;
     }
 #endif

Modified: branches/chromium/1359/Source/WebCore/page/DOMWindow.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/page/DOMWindow.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/page/DOMWindow.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -1584,7 +1584,7 @@
         if (eventType == eventNames().mousewheelEvent)
             document->didAddWheelEventHandler();
         else if (eventNames().isTouchEventType(eventType))
-            document->didAddTouchEventHandler();
+            document->didAddTouchEventHandler(document);
         else if (eventType == eventNames().storageEvent)
             didAddStorageEventListener(this);
     }
@@ -1615,7 +1615,7 @@
         if (eventType == eventNames().mousewheelEvent)
             document->didRemoveWheelEventHandler();
         else if (eventNames().isTouchEventType(eventType))
-            document->didRemoveTouchEventHandler();
+            document->didRemoveTouchEventHandler(document);
     }
 
     if (eventType == eventNames().unloadEvent)

Modified: branches/chromium/1359/Source/WebCore/page/EventHandler.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/page/EventHandler.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/page/EventHandler.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -3939,7 +3939,7 @@
             }
             if (!doc)
                 continue;
-            if (!doc->touchEventHandlerCount())
+            if (!doc->hasTouchEventHandlers())
                 continue;
             m_originatingTouchPointTargets.set(touchPointTargetKey, node);
             touchTarget = node;
@@ -3964,7 +3964,7 @@
         Document* doc = touchTarget->toNode()->document();
         if (!doc)
             continue;
-        if (!doc->touchEventHandlerCount())
+        if (!doc->hasTouchEventHandlers())
             continue;
         Frame* targetFrame = doc->frame();
         if (!targetFrame)

Modified: branches/chromium/1359/Source/WebCore/page/Frame.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/page/Frame.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/page/Frame.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -309,7 +309,7 @@
     if (m_page && m_page->mainFrame() == this) {
         notifyChromeClientWheelEventHandlerCountChanged();
 #if ENABLE(TOUCH_EVENTS)
-        if (m_doc && m_doc->touchEventHandlerCount())
+        if (m_doc && m_doc->hasTouchEventHandlers())
             m_page->chrome()->client()->needTouchEvents(true);
 #endif
     }

Modified: branches/chromium/1359/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -27,6 +27,7 @@
 
 #include "ScrollingCoordinator.h"
 
+#include "Document.h"
 #include "Frame.h"
 #include "FrameView.h"
 #include "IntRect.h"
@@ -176,6 +177,54 @@
     return nonFastScrollableRegion;
 }
 
+#if ENABLE(TOUCH_EVENT_TRACKING)
+static void accumulateRendererTouchEventTargetRects(Vector<IntRect>& rects, const RenderObject* renderer)
+{
+    // FIXME: This method is O(N^2) as it walks the tree to the root for every renderer. RenderGeometryMap would fix this.
+    rects.append(enclosingIntRect(renderer->clippedOverflowRectForRepaint(0)));
+    if (renderer->isRenderBlock()) {
+        const RenderBlock* block = toRenderBlock(renderer);
+        for (RenderObject* child = block->firstChild(); child; child = child->nextSibling())
+            accumulateRendererTouchEventTargetRects(rects, child);
+    }
+}
+
+static void accumulateDocumentEventTargetRects(Vector<IntRect>& rects, const Document* document)
+{
+    ASSERT(document);
+    if (!document->touchEventTargets())
+        return;
+
+    const TouchEventTargetSet* targets = document->touchEventTargets();
+    for (TouchEventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) {
+        const Node* touchTarget = iter->key;
+        if (touchTarget == document) {
+            if (RenderView* view = document->renderView())
+                rects.append(enclosingIntRect(view->clippedOverflowRectForRepaint(0)));
+            return;
+        }
+
+        if (touchTarget->isDocumentNode() && touchTarget != document) {
+            accumulateDocumentEventTargetRects(rects, static_cast<const Document*>(touchTarget));
+            continue;
+        }
+
+        if (RenderObject* renderer = touchTarget->renderer())
+            accumulateRendererTouchEventTargetRects(rects, renderer);
+    }
+}
+
+void ScrollingCoordinator::computeAbsoluteTouchEventTargetRects(const Document* document, Vector<IntRect>& rects)
+{
+    ASSERT(document);
+    if (!document->view())
+        return;
+
+    // FIXME: These rects won't be properly updated if the renderers are in a sub-tree that scrolls.
+    accumulateDocumentEventTargetRects(rects, document);
+}
+#endif
+
 unsigned ScrollingCoordinator::computeCurrentWheelEventHandlerCount()
 {
     unsigned wheelEventHandlerCount = 0;

Modified: branches/chromium/1359/Source/WebCore/page/scrolling/ScrollingCoordinator.h (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2012-12-13 17:18:19 UTC (rev 137603)
@@ -29,6 +29,7 @@
 #include "IntRect.h"
 #include "LayoutRect.h"
 #include "PlatformWheelEvent.h"
+#include "RenderObject.h"
 #include "ScrollTypes.h"
 #include "Timer.h"
 #include <wtf/Forward.h>
@@ -50,6 +51,7 @@
 
 enum ScrollingNodeType { ScrollingNode, FixedNode };
 
+class Document;
 class Frame;
 class FrameView;
 class GraphicsLayer;
@@ -149,7 +151,12 @@
     virtual void scrollableAreaScrollLayerDidChange(ScrollableArea*, GraphicsLayer*) { }
     virtual void setLayerIsContainerForFixedPositionLayers(GraphicsLayer*, bool) { }
     virtual void setLayerIsFixedToContainerLayer(GraphicsLayer*, bool) { }
+    virtual void touchEventTargetRectsDidChange(const Document*) { }
 
+#if ENABLE(TOUCH_EVENT_TRACKING)
+    void computeAbsoluteTouchEventTargetRects(const Document*, Vector<IntRect>&);
+#endif
+
     static String mainThreadScrollingReasonsAsText(MainThreadScrollingReasons);
     String mainThreadScrollingReasonsAsText() const;
 

Modified: branches/chromium/1359/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -115,8 +115,32 @@
     // frame view whose layout was updated is not the main frame.
     Region nonFastScrollableRegion = computeNonFastScrollableRegion(m_page->mainFrame(), IntPoint());
     setNonFastScrollableRegion(nonFastScrollableRegion);
+#if ENABLE(TOUCH_EVENT_TRACKING)
+    Vector<IntRect> touchEventTargetRects;
+    computeAbsoluteTouchEventTargetRects(m_page->mainFrame()->document(), touchEventTargetRects);
+    setTouchEventTargetRects(touchEventTargetRects);
+#endif
 }
 
+void ScrollingCoordinatorChromium::touchEventTargetRectsDidChange(const Document* document)
+{
+#if ENABLE(TOUCH_EVENT_TRACKING)
+    // Wait until after layout to update.
+    if (m_page->mainFrame()->view()->needsLayout())
+        return;
+
+    // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves.
+    setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view()));
+    if (m_private->scrollLayer()) {
+        Vector<IntRect> touchEventTargetRects;
+        computeAbsoluteTouchEventTargetRects(document, touchEventTargetRects);
+        setTouchEventTargetRects(touchEventTargetRects);
+    }
+#else
+    UNUSED_PARAM(document);
+#endif
+}
+
 void ScrollingCoordinatorChromium::frameViewRootLayerDidChange(FrameView* frameView)
 {
     ScrollingCoordinator::frameViewRootLayerDidChange(frameView);
@@ -209,6 +233,18 @@
     }
 }
 
+void ScrollingCoordinatorChromium::setTouchEventTargetRects(const Vector<IntRect>& absoluteHitTestRects)
+{
+    // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves.
+    setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view()));
+    if (m_private->scrollLayer()) {
+        WebVector<WebRect> webRects(absoluteHitTestRects.size());
+        for (size_t i = 0; i < absoluteHitTestRects.size(); ++i)
+            webRects[i] = absoluteHitTestRects[i];
+        m_private->scrollLayer()->setTouchEventHandlerRegion(webRects);
+    }
+}
+
 void ScrollingCoordinatorChromium::setWheelEventHandlerCount(unsigned wheelEventHandlerCount)
 {
     // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves.

Modified: branches/chromium/1359/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.h (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.h	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/page/scrolling/chromium/ScrollingCoordinatorChromium.h	2012-12-13 17:18:19 UTC (rev 137603)
@@ -68,12 +68,16 @@
     // Should be called whenever the scrollable layer for the given scroll area changes.
     virtual void scrollableAreaScrollLayerDidChange(ScrollableArea*, GraphicsLayer*);
 
+    // Should be called whenever touch handlers are registered, removed, or moved.
+    virtual void touchEventTargetRectsDidChange(const Document*) OVERRIDE;
+
 private:
     virtual void recomputeWheelEventHandlerCountForFrameView(FrameView*);
     virtual void setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons);
 
     void setScrollLayer(GraphicsLayer*);
     void setNonFastScrollableRegion(const Region&);
+    void setTouchEventTargetRects(const Vector<IntRect>&);
     void setWheelEventHandlerCount(unsigned);
     PassOwnPtr<WebKit::WebScrollbarLayer> createScrollbarLayer(Scrollbar*, WebKit::WebLayer* scrollLayer, GraphicsLayer* scrollbarGraphicsLayer, FrameView*);
 

Modified: branches/chromium/1359/Source/WebCore/testing/Internals.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/testing/Internals.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/testing/Internals.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -73,6 +73,7 @@
 #include "RenderTreeAsText.h"
 #include "RuntimeEnabledFeatures.h"
 #include "SchemeRegistry.h"
+#include "ScrollingCoordinator.h"
 #include "SelectRuleFeatureSet.h"
 #include "SerializedScriptValue.h"
 #include "Settings.h"
@@ -1200,9 +1201,39 @@
         return 0;
     }
 
-    return document->touchEventHandlerCount();
+    const TouchEventTargetSet* touchHandlers = document->touchEventTargets();
+    if (!touchHandlers)
+        return 0;
+
+    unsigned count = 0;
+    for (TouchEventTargetSet::const_iterator iter = touchHandlers->begin(); iter != touchHandlers->end(); ++iter)
+        count += iter->value;
+    return count;
 }
 
+#if ENABLE(TOUCH_EVENT_TRACKING)
+PassRefPtr<ClientRectList> Internals::touchEventTargetClientRects(Document* document, ExceptionCode& ec)
+{
+    if (!document || !document->view() || !document->page()) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+    if (!document->page()->scrollingCoordinator())
+        return ClientRectList::create();
+
+    document->updateLayoutIgnorePendingStylesheets();
+
+    Vector<IntRect> absoluteRects;
+    document->page()->scrollingCoordinator()->computeAbsoluteTouchEventTargetRects(document, absoluteRects);
+    Vector<FloatQuad> absoluteQuads(absoluteRects.size());
+
+    for (size_t i = 0; i < absoluteRects.size(); ++i)
+        absoluteQuads[i] = FloatQuad(absoluteRects[i]);
+
+    return ClientRectList::create(absoluteQuads);
+}
+#endif
+
 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int x, int y, unsigned topPadding, unsigned rightPadding,
     unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, ExceptionCode& ec) const
 {

Modified: branches/chromium/1359/Source/WebCore/testing/Internals.h (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/testing/Internals.h	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/testing/Internals.h	2012-12-13 17:18:19 UTC (rev 137603)
@@ -171,6 +171,9 @@
 
     unsigned wheelEventHandlerCount(Document*, ExceptionCode&);
     unsigned touchEventHandlerCount(Document*, ExceptionCode&);
+#if ENABLE(TOUCH_EVENT_TRACKING)
+    PassRefPtr<ClientRectList> touchEventTargetClientRects(Document*, ExceptionCode&);
+#endif
 
     PassRefPtr<NodeList> nodesFromRect(Document*, int x, int y, unsigned topPadding, unsigned rightPadding,
         unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, ExceptionCode&) const;

Modified: branches/chromium/1359/Source/WebCore/testing/Internals.idl (137602 => 137603)


--- branches/chromium/1359/Source/WebCore/testing/Internals.idl	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebCore/testing/Internals.idl	2012-12-13 17:18:19 UTC (rev 137603)
@@ -139,6 +139,9 @@
 
     unsigned long wheelEventHandlerCount(in Document document) raises (DOMException);
     unsigned long touchEventHandlerCount(in Document document) raises (DOMException);
+#if defined(ENABLE_TOUCH_EVENT_TRACKING) && ENABLE_TOUCH_EVENT_TRACKING
+    ClientRectList touchEventTargetClientRects(in Document document) raises (DOMException);
+#endif
 
     NodeList nodesFromRect(in Document document, in long x, in long y,
         in unsigned long topPadding, in unsigned long rightPadding, in unsigned long bottomPadding, in unsigned long leftPadding,

Modified: branches/chromium/1359/Source/WebKit/chromium/features.gypi (137602 => 137603)


--- branches/chromium/1359/Source/WebKit/chromium/features.gypi	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebKit/chromium/features.gypi	2012-12-13 17:18:19 UTC (rev 137603)
@@ -116,6 +116,7 @@
       'ENABLE_TOUCH_ADJUSTMENT=1',
       'ENABLE_TOUCH_EVENTS=<(enable_touch_events)',
       'ENABLE_TOUCH_ICON_LOADING=<(enable_touch_icon_loading)',
+      'ENABLE_TOUCH_EVENT_TRACKING=<(enable_touch_events)',
       'ENABLE_TOUCH_SLIDER=1',
       'ENABLE_USER_TIMING=1',
       'ENABLE_V8_SCRIPT_DEBUG_SERVER=1',

Modified: branches/chromium/1359/Source/WebKit/chromium/src/WebPluginContainerImpl.cpp (137602 => 137603)


--- branches/chromium/1359/Source/WebKit/chromium/src/WebPluginContainerImpl.cpp	2012-12-13 17:13:59 UTC (rev 137602)
+++ branches/chromium/1359/Source/WebKit/chromium/src/WebPluginContainerImpl.cpp	2012-12-13 17:18:19 UTC (rev 137603)
@@ -530,9 +530,9 @@
         return;
     m_touchEventRequestType = requestType;
     if (m_touchEventRequestType != TouchEventRequestTypeNone)
-        m_element->document()->didAddTouchEventHandler();
+        m_element->document()->didAddTouchEventHandler(m_element);
     else
-        m_element->document()->didRemoveTouchEventHandler();
+        m_element->document()->didRemoveTouchEventHandler(m_element);
 }
 
 void WebPluginContainerImpl::setWantsWheelEvents(bool wantsWheelEvents)
@@ -685,7 +685,7 @@
 #endif
 
     if (m_touchEventRequestType != TouchEventRequestTypeNone)
-        m_element->document()->didRemoveTouchEventHandler();
+        m_element->document()->didRemoveTouchEventHandler(m_element);
 
     for (size_t i = 0; i < m_pluginLoadObservers.size(); ++i)
         m_pluginLoadObservers[i]->clearPluginContainer();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to