Changeset 143727 in webkit
- Timestamp:
- Feb 22, 2013 6:46:35 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r143718 r143727 1 2013-02-22 Allan Sandfeld Jensen <allan.jensen@digia.com> 2 3 Allow child-frame content in hit-tests. 4 https://bugs.webkit.org/show_bug.cgi?id=95204 5 6 Reviewed by Julien Chaffraix. 7 8 A new tests for nodesFromRect that returns result from child frames. 9 10 * fast/dom/nodesFromRect/nodesFromRect-child-frame-content-expected.txt: Added. 11 * fast/dom/nodesFromRect/nodesFromRect-child-frame-content.html: Added. 12 * fast/dom/nodesFromRect/nodesFromRect-continuation-crash.html: 13 * fast/dom/nodesFromRect/resources/child-frame.html: Added. 14 * fast/dom/nodesFromRect/resources/nodesFromRect.js: 15 (check): 16 (checkShadowContent): 17 (nodesFromRectAsString): 18 1 19 2013-02-22 Zan Dobersek <zdobersek@igalia.com> 2 20 -
trunk/LayoutTests/fast/dom/nodesFromRect/nodesFromRect-continuation-crash.html
r133330 r143727 8 8 if (!window.internals) 9 9 alert("This test requires window.internals"); 10 var nodes = internals.nodesFromRect(document, 100, 100, 20, 20, 20, 20, false, false );10 var nodes = internals.nodesFromRect(document, 100, 100, 20, 20, 20, 20, false, false, false); 11 11 alert("PASS: This test did not trigger an ASSERT"); 12 12 }; -
trunk/LayoutTests/fast/dom/nodesFromRect/resources/nodesFromRect.js
r135841 r143727 2 2 * Contributors: 3 3 * * Antonio Gomes <tonikitoo@webkit.org> 4 **/ 4 * * Allan Sandfeld Jensen <allan.jensen@digia.com> 5 **/ 5 6 6 7 function check(x, y, topPadding, rightPadding, bottomPadding, leftPadding, list, doc) … … 12 13 doc = document; 13 14 14 var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, false /* allow shadow content */ );15 var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, false /* allow shadow content */, false /* allow child-frame content */); 15 16 if (!nodes) 16 17 return; … … 46 47 doc = document; 47 48 48 var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, true /* allowShadowContent */ );49 var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, true /* allowShadowContent */, false /* allow child-frame content */); 49 50 if (!nodes) 50 51 return; … … 97 98 { 98 99 var nodeString = ""; 99 var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, false /* allow shadow content */ );100 var nodes = internals.nodesFromRect(doc, x, y, topPadding, rightPadding, bottomPadding, leftPadding, true /* ignoreClipping */, false /* allow shadow content */, true /* allow child-frame content */); 100 101 if (!nodes) 101 102 return nodeString; … … 111 112 } else if (nodes[i].nodeType == 3) { 112 113 nodeString += "'" + nodes[i].data + "'"; 114 } else if (nodes[i].nodeType == 9) { 115 nodeString += "#document"; 113 116 } else { 114 117 continue; … … 120 123 return nodeString; 121 124 } 122 123 125 124 126 function getCenterFor(element) -
trunk/Source/WebCore/ChangeLog
r143726 r143727 1 2013-02-22 Allan Sandfeld Jensen <allan.jensen@digia.com> 2 3 Allow child-frame content in hit-tests. 4 https://bugs.webkit.org/show_bug.cgi?id=95204 5 6 Reviewed by Julien Chaffraix. 7 8 Refactors how EventHandler::hitTestResultAtPoint handles child-frame content, 9 it is now handled by the hit test itself controlled by the AllowChildFrameContent 10 flag in HitTestRequest. 11 12 This means that area-based hit-tests can now return elements from all the child frames 13 they intersect instead of just the one frame containing the center point. The improved 14 results from area-based hit-tests will among other things also improve touch adjustment 15 near frame boundaries. 16 17 Tests: fast/dom/nodesFromRect/nodesFromRect-child-frame-content.html 18 19 * page/EventHandler.cpp: 20 (WebCore::EventHandler::hitTestResultAtPoint): 21 Recursion into child-frames have been moved to RenderFrameBase::nodeAtPoint, so 22 now hitTestResultAtPoint just needs to set AllowChildFrameContent. 23 * page/TouchAdjustment.cpp: 24 (WebCore::TouchAdjustment::parentShadowHostOrOwner): 25 New function to iterate up across frame boundaries. 26 (WebCore::TouchAdjustment::compileSubtargetList): 27 We need to iterate up across frame boundaries to avoid iframes competing with their 28 own content for touch adjustment. 29 * rendering/HitTestRequest.h: 30 (WebCore::HitTestRequest::allowsChildFrameContent): 31 (WebCore::HitTestRequest::isChildFrameHitTest): 32 * rendering/HitTestResult.cpp: 33 (WebCore::HitTestResult::HitTestResult): 34 (WebCore::HitTestResult::operator=): 35 (WebCore::HitTestResult::append): 36 (WebCore::HitTestResult::dictationAlternatives): 37 * rendering/HitTestResult.h: 38 (WebCore::HitTestResult::pointInMainFrame): 39 (WebCore::HitTestResult::pointInInnerNodeFrame): 40 (HitTestResult): 41 m_hitTestLocation is now in main frame coordinates, which make m_pointInMainFrame 42 unnecessary, but requires the introduction of m_pointInInnerFrame, to remember 43 the coordinates of inner-node in its own frame. 44 * rendering/RenderFrameBase.cpp: 45 (WebCore::RenderFrameBase::nodeAtPoint): 46 The recursion into child-frames is now handled here instead of in hitTestResultAtPoint, this 47 allows us to recurse into multiple frames, instead of just one. 48 * rendering/RenderFrameBase.h: 49 (RenderFrameBase): 50 * rendering/RenderLayer.cpp: 51 (WebCore::RenderLayer::hitTest): 52 RenderLayer should not lie about being hit if the request is child-frame request. 53 * testing/Internals.cpp: 54 (WebCore::Internals::nodesFromRect): 55 * testing/Internals.h: 56 (Internals): 57 * testing/Internals.idl: 58 Extended so nodesFromRect with child-frame content can be tested. 59 1 60 2013-02-22 Andreas Kling <akling@apple.com> 2 61 -
trunk/Source/WebCore/page/EventHandler.cpp
r143560 r143727 1027 1027 return result; 1028 1028 1029 HitTestRequest request(hitType); 1029 // hitTestResultAtPoint is specifically used to hitTest into all frames, thus it always allows child frame content. 1030 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent); 1030 1031 m_frame->contentRenderer()->hitTest(request, result); 1031 1032 while (true) {1033 Node* n = result.innerNode();1034 if (!result.isOverWidget() || !n || !n->renderer() || !n->renderer()->isWidget())1035 break;1036 RenderWidget* renderWidget = toRenderWidget(n->renderer());1037 Widget* widget = renderWidget->widget();1038 if (!widget || !widget->isFrameView())1039 break;1040 Frame* frame = static_cast<HTMLFrameElementBase*>(n)->contentFrame();1041 if (!frame || !frame->contentRenderer())1042 break;1043 FrameView* view = static_cast<FrameView*>(widget);1044 LayoutPoint widgetPoint(result.localPoint().x() + view->scrollX() - renderWidget->borderLeft() - renderWidget->paddingLeft(),1045 result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop());1046 HitTestResult widgetHitTestResult(widgetPoint, padding.height(), padding.width(), padding.height(), padding.width());1047 widgetHitTestResult.setPointInMainFrame(result.pointInMainFrame());1048 frame->contentRenderer()->hitTest(request, widgetHitTestResult);1049 result = widgetHitTestResult;1050 1051 if (request.allowsFrameScrollbars()) {1052 Scrollbar* eventScrollbar = view->scrollbarAtPoint(roundedIntPoint(point));1053 if (eventScrollbar)1054 result.setScrollbar(eventScrollbar);1055 }1056 }1057 1032 1058 1033 if (!request.allowsShadowContent()) -
trunk/Source/WebCore/page/TouchAdjustment.cpp
r141524 r143727 26 26 #include "FloatQuad.h" 27 27 #include "FrameView.h" 28 #include "HTMLFrameOwnerElement.h" 28 29 #include "HTMLInputElement.h" 29 30 #include "HTMLLabelElement.h" … … 222 223 } 223 224 225 static inline Node* parentShadowHostOrOwner(const Node* node) 226 { 227 if (Node* ancestor = node->parentOrShadowHostNode()) 228 return ancestor; 229 if (node->isDocumentNode()) 230 return static_cast<const Document*>(node)->ownerElement(); 231 return 0; 232 } 233 224 234 // Compiles a list of subtargets of all the relevant target nodes. 225 235 void compileSubtargetList(const NodeList& intersectedNodes, SubtargetGeometryList& subtargets, NodeFilter nodeFilter, AppendSubtargetsForNode appendSubtargetsForNode) … … 249 259 respondingNode = visitedNode; 250 260 // Continue the iteration to collect the ancestors of the responder, which we will need later. 251 for (visitedNode = visitedNode->parentOrShadowHostNode(); visitedNode; visitedNode = visitedNode->parentOrShadowHostNode()) {261 for (visitedNode = parentShadowHostOrOwner(visitedNode); visitedNode; visitedNode = parentShadowHostOrOwner(visitedNode)) { 252 262 HashSet<Node*>::AddResult addResult = ancestorsToRespondersSet.add(visitedNode); 253 263 if (!addResult.isNewEntry) -
trunk/Source/WebCore/rendering/HitTestRequest.h
r142977 r143727 37 37 TouchEvent = 1 << 7, 38 38 AllowShadowContent = 1 << 8, 39 AllowFrameScrollbars = 1 << 9 39 AllowFrameScrollbars = 1 << 9, 40 AllowChildFrameContent = 1 << 10, 41 ChildFrameHitTest = 1 << 11 40 42 }; 41 43 … … 57 59 bool allowsShadowContent() const { return m_requestType & AllowShadowContent; } 58 60 bool allowsFrameScrollbars() const { return m_requestType & AllowFrameScrollbars; } 61 bool allowsChildFrameContent() const { return m_requestType & AllowChildFrameContent; } 62 bool isChildFrameHitTest() const { return m_requestType & ChildFrameHitTest; } 59 63 60 64 // Convenience functions -
trunk/Source/WebCore/rendering/HitTestResult.cpp
r141524 r143727 200 200 HitTestResult::HitTestResult(const LayoutPoint& point) 201 201 : m_hitTestLocation(point) 202 , m_pointIn MainFrame(point)202 , m_pointInInnerNodeFrame(point) 203 203 , m_isOverWidget(false) 204 204 { … … 207 207 HitTestResult::HitTestResult(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding) 208 208 : m_hitTestLocation(centerPoint, topPadding, rightPadding, bottomPadding, leftPadding) 209 , m_pointIn MainFrame(centerPoint)209 , m_pointInInnerNodeFrame(centerPoint) 210 210 , m_isOverWidget(false) 211 211 { … … 214 214 HitTestResult::HitTestResult(const HitTestLocation& other) 215 215 : m_hitTestLocation(other) 216 , m_pointIn MainFrame(m_hitTestLocation.point())216 , m_pointInInnerNodeFrame(m_hitTestLocation.point()) 217 217 , m_isOverWidget(false) 218 218 { … … 223 223 , m_innerNode(other.innerNode()) 224 224 , m_innerNonSharedNode(other.innerNonSharedNode()) 225 , m_pointIn MainFrame(other.m_pointInMainFrame)225 , m_pointInInnerNodeFrame(other.m_pointInInnerNodeFrame) 226 226 , m_localPoint(other.localPoint()) 227 227 , m_innerURLElement(other.URLElement()) … … 242 242 m_innerNode = other.innerNode(); 243 243 m_innerNonSharedNode = other.innerNonSharedNode(); 244 m_pointIn MainFrame = other.m_pointInMainFrame;244 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame; 245 245 m_localPoint = other.localPoint(); 246 246 m_innerURLElement = other.URLElement(); … … 736 736 m_innerNonSharedNode = other.innerNonSharedNode(); 737 737 m_localPoint = other.localPoint(); 738 m_pointIn MainFrame = other.m_pointInMainFrame;738 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame; 739 739 m_innerURLElement = other.URLElement(); 740 740 m_scrollbar = other.scrollbar(); … … 769 769 return Vector<String>(); 770 770 771 DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint( hitTestLocation().point(), DocumentMarker::DictationAlternatives);771 DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(pointInInnerNodeFrame(), DocumentMarker::DictationAlternatives); 772 772 if (!marker) 773 773 return Vector<String>(); -
trunk/Source/WebCore/rendering/HitTestResult.h
r139199 r143727 126 126 127 127 // The hit-tested point in the coordinates of the main frame. 128 const LayoutPoint& pointInMainFrame() const { return m_ pointInMainFrame; }128 const LayoutPoint& pointInMainFrame() const { return m_hitTestLocation.point(); } 129 129 IntPoint roundedPointInMainFrame() const { return roundedIntPoint(pointInMainFrame()); } 130 void setPointInMainFrame(const LayoutPoint& p) { m_pointInMainFrame = p; }131 130 132 131 // The hit-tested point in the coordinates of the innerNode frame, the frame containing innerNode. 133 const LayoutPoint& pointInInnerNodeFrame() const { return m_ hitTestLocation.point(); }132 const LayoutPoint& pointInInnerNodeFrame() const { return m_pointInInnerNodeFrame; } 134 133 IntPoint roundedPointInInnerNodeFrame() const { return roundedIntPoint(pointInInnerNodeFrame()); } 135 134 Frame* innerNodeFrame() const; … … 204 203 RefPtr<Node> m_innerNode; 205 204 RefPtr<Node> m_innerNonSharedNode; 206 LayoutPoint m_pointIn MainFrame; // The hit-tested point in main-frame coordinates.205 LayoutPoint m_pointInInnerNodeFrame; // The hit-tested point in innerNode frame coordinates. 207 206 LayoutPoint m_localPoint; // A point in the local coordinate space of m_innerNonSharedNode's renderer. Allows us to efficiently 208 207 // determine where inside the renderer we hit on subsequent operations. -
trunk/Source/WebCore/rendering/RenderFrameBase.cpp
r139749 r143727 30 30 #include "FrameView.h" 31 31 #include "HTMLFrameElementBase.h" 32 #include "HitTestResult.h" 33 #include "RenderLayer.h" 32 34 #include "RenderView.h" 33 35 … … 103 105 } 104 106 107 bool RenderFrameBase::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) 108 { 109 if (!request.allowsChildFrameContent()) 110 return RenderPart::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action); 111 112 ASSERT_WITH_SECURITY_IMPLICATION(!widget() || widget()->isFrameView()); 113 FrameView* childFrameView = static_cast<FrameView*>(widget()); 114 RenderView* childRoot = childFrameView ? childFrameView->renderView() : 0; 115 116 if (childRoot) { 117 LayoutPoint adjustedLocation = accumulatedOffset + location(); 118 LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - childFrameView->scrollOffset(); 119 HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); 120 HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildFrameHitTest); 121 HitTestResult childFrameResult(newHitTestLocation); 122 123 bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult); 124 result.append(childFrameResult); 125 if (isInsideChildFrame) 126 return true; 127 128 if (request.allowsFrameScrollbars()) { 129 // ScrollView scrollbars are not the same as RenderLayer scrollbars tested by RenderLayer::hitTestOverflowControls, 130 // so we need to test ScrollView scrollbars separately here. 131 // FIXME: Consider if this test could be done unconditionally. 132 Scrollbar* frameScrollbar = childFrameView->scrollbarAtPoint(newHitTestLocation.roundedPoint()); 133 if (frameScrollbar) 134 result.setScrollbar(frameScrollbar); 135 } 136 } 137 138 return RenderPart::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action); 105 139 } 140 141 } -
trunk/Source/WebCore/rendering/RenderFrameBase.h
r128677 r143727 37 37 38 38 public: 39 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE; 39 40 void layoutWithFlattening(bool fixedWidth, bool fixedHeight); 40 41 }; -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r143655 r143727 4014 4014 // return ourselves. We do this so mouse events continue getting delivered after a drag has 4015 4015 // exited the WebView, and so hit testing over a scrollbar hits the content document. 4016 if ( (request.active() || request.release()) && isRootLayer()) {4016 if (!request.isChildFrameHitTest() && (request.active() || request.release()) && isRootLayer()) { 4017 4017 renderer()->updateHitTestResult(result, toRenderView(renderer())->flipForWritingMode(hitTestLocation.point())); 4018 4018 insideLayer = this; -
trunk/Source/WebCore/testing/Internals.cpp
r143136 r143727 1399 1399 1400 1400 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int x, int y, unsigned topPadding, unsigned rightPadding, 1401 unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, ExceptionCode& ec) const1401 unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const 1402 1402 { 1403 1403 if (!document || !document->frame() || !document->frame()->view()) { … … 1411 1411 if (allowShadowContent) 1412 1412 hitType |= HitTestRequest::AllowShadowContent; 1413 if (allowChildFrameContent) 1414 hitType |= HitTestRequest::AllowChildFrameContent; 1413 1415 1414 1416 return document->nodesFromRect(x, y, topPadding, rightPadding, bottomPadding, leftPadding, hitType); -
trunk/Source/WebCore/testing/Internals.h
r143136 r143727 191 191 192 192 PassRefPtr<NodeList> nodesFromRect(Document*, int x, int y, unsigned topPadding, unsigned rightPadding, 193 unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, ExceptionCode&) const;193 unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode&) const; 194 194 195 195 void emitInspectorDidBeginFrame(); -
trunk/Source/WebCore/testing/Internals.idl
r143136 r143727 159 159 NodeList nodesFromRect(in Document document, in long x, in long y, 160 160 in unsigned long topPadding, in unsigned long rightPadding, in unsigned long bottomPadding, in unsigned long leftPadding, 161 in boolean ignoreClipping, in boolean allowShadowContent ) raises (DOMException);161 in boolean ignoreClipping, in boolean allowShadowContent, in boolean allowChildFrameContent) raises (DOMException); 162 162 163 163 void emitInspectorDidBeginFrame();
Note: See TracChangeset
for help on using the changeset viewer.