| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) | 2 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 : m_node(node) | 51 : m_node(node) |
| 52 , m_quad(quad) | 52 , m_quad(quad) |
| 53 { } | 53 { } |
| 54 DEFINE_INLINE_TRACE() { visitor->trace(m_node); } | 54 DEFINE_INLINE_TRACE() { visitor->trace(m_node); } |
| 55 | 55 |
| 56 Node* node() const { return m_node; } | 56 Node* node() const { return m_node; } |
| 57 FloatQuad quad() const { return m_quad; } | 57 FloatQuad quad() const { return m_quad; } |
| 58 IntRect boundingBox() const { return m_quad.enclosingBoundingBox(); } | 58 IntRect boundingBox() const { return m_quad.enclosingBoundingBox(); } |
| 59 | 59 |
| 60 private: | 60 private: |
| 61 RawPtrWillBeMember<Node> m_node; | 61 Member<Node> m_node; |
| 62 FloatQuad m_quad; | 62 FloatQuad m_quad; |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 } // namespace TouchAdjustment | 65 } // namespace TouchAdjustment |
| 66 | 66 |
| 67 } // namespace blink | 67 } // namespace blink |
| 68 | 68 |
| 69 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::TouchAdjustment::Subta
rgetGeometry) | 69 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::TouchAdjustment::Subta
rgetGeometry) |
| 70 | 70 |
| 71 namespace blink { | 71 namespace blink { |
| 72 | 72 |
| 73 namespace TouchAdjustment { | 73 namespace TouchAdjustment { |
| 74 | 74 |
| 75 typedef WillBeHeapVector<SubtargetGeometry> SubtargetGeometryList; | 75 typedef HeapVector<SubtargetGeometry> SubtargetGeometryList; |
| 76 typedef bool (*NodeFilter)(Node*); | 76 typedef bool (*NodeFilter)(Node*); |
| 77 typedef void (*AppendSubtargetsForNode)(Node*, SubtargetGeometryList&); | 77 typedef void (*AppendSubtargetsForNode)(Node*, SubtargetGeometryList&); |
| 78 typedef float (*DistanceFunction)(const IntPoint&, const IntRect&, const Subtarg
etGeometry&); | 78 typedef float (*DistanceFunction)(const IntPoint&, const IntRect&, const Subtarg
etGeometry&); |
| 79 | 79 |
| 80 // Takes non-const Node* because isContentEditable is a non-const function. | 80 // Takes non-const Node* because isContentEditable is a non-const function. |
| 81 bool nodeRespondsToTapGesture(Node* node) | 81 bool nodeRespondsToTapGesture(Node* node) |
| 82 { | 82 { |
| 83 if (node->willRespondToMouseClickEvents() || node->willRespondToMouseMoveEve
nts()) | 83 if (node->willRespondToMouseClickEvents() || node->willRespondToMouseMoveEve
nts()) |
| 84 return true; | 84 return true; |
| 85 if (node->isElementNode()) { | 85 if (node->isElementNode()) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 static inline Node* parentShadowHostOrOwner(const Node* node) | 236 static inline Node* parentShadowHostOrOwner(const Node* node) |
| 237 { | 237 { |
| 238 if (Node* ancestor = node->parentOrShadowHostNode()) | 238 if (Node* ancestor = node->parentOrShadowHostNode()) |
| 239 return ancestor; | 239 return ancestor; |
| 240 if (node->isDocumentNode()) | 240 if (node->isDocumentNode()) |
| 241 return toDocument(node)->ownerElement(); | 241 return toDocument(node)->ownerElement(); |
| 242 return nullptr; | 242 return nullptr; |
| 243 } | 243 } |
| 244 | 244 |
| 245 // Compiles a list of subtargets of all the relevant target nodes. | 245 // Compiles a list of subtargets of all the relevant target nodes. |
| 246 void compileSubtargetList(const WillBeHeapVector<RefPtrWillBeMember<Node>>& inte
rsectedNodes, SubtargetGeometryList& subtargets, NodeFilter nodeFilter, AppendSu
btargetsForNode appendSubtargetsForNode) | 246 void compileSubtargetList(const HeapVector<Member<Node>>& intersectedNodes, Subt
argetGeometryList& subtargets, NodeFilter nodeFilter, AppendSubtargetsForNode ap
pendSubtargetsForNode) |
| 247 { | 247 { |
| 248 // Find candidates responding to tap gesture events in O(n) time. | 248 // Find candidates responding to tap gesture events in O(n) time. |
| 249 WillBeHeapHashMap<RawPtrWillBeMember<Node>, RawPtrWillBeMember<Node>> respon
derMap; | 249 HeapHashMap<Member<Node>, Member<Node>> responderMap; |
| 250 WillBeHeapHashSet<RawPtrWillBeMember<Node>> ancestorsToRespondersSet; | 250 HeapHashSet<Member<Node>> ancestorsToRespondersSet; |
| 251 WillBeHeapVector<RawPtrWillBeMember<Node>> candidates; | 251 HeapVector<Member<Node>> candidates; |
| 252 WillBeHeapHashSet<RawPtrWillBeMember<Node>> editableAncestors; | 252 HeapHashSet<Member<Node>> editableAncestors; |
| 253 | 253 |
| 254 // A node matching the NodeFilter is called a responder. Candidate nodes mus
t either be a | 254 // A node matching the NodeFilter is called a responder. Candidate nodes mus
t either be a |
| 255 // responder or have an ancestor that is a responder. | 255 // responder or have an ancestor that is a responder. |
| 256 // This iteration tests all ancestors at most once by caching earlier result
s. | 256 // This iteration tests all ancestors at most once by caching earlier result
s. |
| 257 for (unsigned i = 0; i < intersectedNodes.size(); ++i) { | 257 for (unsigned i = 0; i < intersectedNodes.size(); ++i) { |
| 258 Node* node = intersectedNodes[i].get(); | 258 Node* node = intersectedNodes[i].get(); |
| 259 WillBeHeapVector<RawPtrWillBeMember<Node>> visitedNodes; | 259 HeapVector<Member<Node>> visitedNodes; |
| 260 Node* respondingNode = nullptr; | 260 Node* respondingNode = nullptr; |
| 261 for (Node* visitedNode = node; visitedNode; visitedNode = visitedNode->p
arentOrShadowHostNode()) { | 261 for (Node* visitedNode = node; visitedNode; visitedNode = visitedNode->p
arentOrShadowHostNode()) { |
| 262 // Check if we already have a result for a common ancestor from anot
her candidate. | 262 // Check if we already have a result for a common ancestor from anot
her candidate. |
| 263 respondingNode = responderMap.get(visitedNode); | 263 respondingNode = responderMap.get(visitedNode); |
| 264 if (respondingNode) | 264 if (respondingNode) |
| 265 break; | 265 break; |
| 266 visitedNodes.append(visitedNode); | 266 visitedNodes.append(visitedNode); |
| 267 // Check if the node filter applies, which would mean we have found
a responding node. | 267 // Check if the node filter applies, which would mean we have found
a responding node. |
| 268 if (nodeFilter(visitedNode)) { | 268 if (nodeFilter(visitedNode)) { |
| 269 respondingNode = visitedNode; | 269 respondingNode = visitedNode; |
| 270 // Continue the iteration to collect the ancestors of the respon
der, which we will need later. | 270 // Continue the iteration to collect the ancestors of the respon
der, which we will need later. |
| 271 for (visitedNode = parentShadowHostOrOwner(visitedNode); visited
Node; visitedNode = parentShadowHostOrOwner(visitedNode)) { | 271 for (visitedNode = parentShadowHostOrOwner(visitedNode); visited
Node; visitedNode = parentShadowHostOrOwner(visitedNode)) { |
| 272 WillBeHeapHashSet<RawPtrWillBeMember<Node>>::AddResult addRe
sult = ancestorsToRespondersSet.add(visitedNode); | 272 HeapHashSet<Member<Node>>::AddResult addResult = ancestorsTo
RespondersSet.add(visitedNode); |
| 273 if (!addResult.isNewEntry) | 273 if (!addResult.isNewEntry) |
| 274 break; | 274 break; |
| 275 } | 275 } |
| 276 break; | 276 break; |
| 277 } | 277 } |
| 278 } | 278 } |
| 279 // Insert the detected responder for all the visited nodes. | 279 // Insert the detected responder for all the visited nodes. |
| 280 for (unsigned j = 0; j < visitedNodes.size(); j++) | 280 for (unsigned j = 0; j < visitedNodes.size(); j++) |
| 281 responderMap.add(visitedNodes[j], respondingNode); | 281 responderMap.add(visitedNodes[j], respondingNode); |
| 282 | 282 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 311 parent = parent->parentOrShadowHostNode(); | 311 parent = parent->parentOrShadowHostNode(); |
| 312 } | 312 } |
| 313 candidate = replacement; | 313 candidate = replacement; |
| 314 } | 314 } |
| 315 if (candidate) | 315 if (candidate) |
| 316 appendSubtargetsForNode(candidate, subtargets); | 316 appendSubtargetsForNode(candidate, subtargets); |
| 317 } | 317 } |
| 318 } | 318 } |
| 319 | 319 |
| 320 // Compiles a list of zoomable subtargets. | 320 // Compiles a list of zoomable subtargets. |
| 321 void compileZoomableSubtargets(const WillBeHeapVector<RefPtrWillBeMember<Node>>&
intersectedNodes, SubtargetGeometryList& subtargets) | 321 void compileZoomableSubtargets(const HeapVector<Member<Node>>& intersectedNodes,
SubtargetGeometryList& subtargets) |
| 322 { | 322 { |
| 323 for (unsigned i = 0; i < intersectedNodes.size(); ++i) { | 323 for (unsigned i = 0; i < intersectedNodes.size(); ++i) { |
| 324 Node* candidate = intersectedNodes[i].get(); | 324 Node* candidate = intersectedNodes[i].get(); |
| 325 if (nodeIsZoomTarget(candidate)) | 325 if (nodeIsZoomTarget(candidate)) |
| 326 appendZoomableSubtargets(candidate, subtargets); | 326 appendZoomableSubtargets(candidate, subtargets); |
| 327 } | 327 } |
| 328 } | 328 } |
| 329 | 329 |
| 330 // This returns quotient of the target area and its intersection with the touch
area. | 330 // This returns quotient of the target area and its intersection with the touch
area. |
| 331 // This will prioritize largest intersection and smallest area, while balancing
the two against each other. | 331 // This will prioritize largest intersection and smallest area, while balancing
the two against each other. |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 targetNode = targetNode->parentOrShadowHostNode(); | 472 targetNode = targetNode->parentOrShadowHostNode(); |
| 473 | 473 |
| 474 if (targetNode) | 474 if (targetNode) |
| 475 targetArea = targetNode->document().view()->contentsToRootFrame(targetAr
ea); | 475 targetArea = targetNode->document().view()->contentsToRootFrame(targetAr
ea); |
| 476 | 476 |
| 477 return (targetNode); | 477 return (targetNode); |
| 478 } | 478 } |
| 479 | 479 |
| 480 } // namespace TouchAdjustment | 480 } // namespace TouchAdjustment |
| 481 | 481 |
| 482 bool findBestClickableCandidate(Node*& targetNode, IntPoint& targetPoint, const
IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrW
illBeMember<Node>>& nodes) | 482 bool findBestClickableCandidate(Node*& targetNode, IntPoint& targetPoint, const
IntPoint& touchHotspot, const IntRect& touchArea, const HeapVector<Member<Node>>
& nodes) |
| 483 { | 483 { |
| 484 IntRect targetArea; | 484 IntRect targetArea; |
| 485 TouchAdjustment::SubtargetGeometryList subtargets; | 485 TouchAdjustment::SubtargetGeometryList subtargets; |
| 486 TouchAdjustment::compileSubtargetList(nodes, subtargets, TouchAdjustment::no
deRespondsToTapGesture, TouchAdjustment::appendBasicSubtargetsForNode); | 486 TouchAdjustment::compileSubtargetList(nodes, subtargets, TouchAdjustment::no
deRespondsToTapGesture, TouchAdjustment::appendBasicSubtargetsForNode); |
| 487 return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetP
oint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDi
stanceFunction); | 487 return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetP
oint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDi
stanceFunction); |
| 488 } | 488 } |
| 489 | 489 |
| 490 bool findBestContextMenuCandidate(Node*& targetNode, IntPoint& targetPoint, cons
t IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPt
rWillBeMember<Node>>& nodes) | 490 bool findBestContextMenuCandidate(Node*& targetNode, IntPoint& targetPoint, cons
t IntPoint& touchHotspot, const IntRect& touchArea, const HeapVector<Member<Node
>>& nodes) |
| 491 { | 491 { |
| 492 IntRect targetArea; | 492 IntRect targetArea; |
| 493 TouchAdjustment::SubtargetGeometryList subtargets; | 493 TouchAdjustment::SubtargetGeometryList subtargets; |
| 494 TouchAdjustment::compileSubtargetList(nodes, subtargets, TouchAdjustment::pr
ovidesContextMenuItems, TouchAdjustment::appendContextSubtargetsForNode); | 494 TouchAdjustment::compileSubtargetList(nodes, subtargets, TouchAdjustment::pr
ovidesContextMenuItems, TouchAdjustment::appendContextSubtargetsForNode); |
| 495 return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetP
oint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDi
stanceFunction); | 495 return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetP
oint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDi
stanceFunction); |
| 496 } | 496 } |
| 497 | 497 |
| 498 bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint
& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMem
ber<Node>>& nodes) | 498 bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint
& touchHotspot, const IntRect& touchArea, const HeapVector<Member<Node>>& nodes) |
| 499 { | 499 { |
| 500 IntPoint targetPoint; | 500 IntPoint targetPoint; |
| 501 TouchAdjustment::SubtargetGeometryList subtargets; | 501 TouchAdjustment::SubtargetGeometryList subtargets; |
| 502 TouchAdjustment::compileZoomableSubtargets(nodes, subtargets); | 502 TouchAdjustment::compileZoomableSubtargets(nodes, subtargets); |
| 503 return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetP
oint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::zoomable
IntersectionQuotient); | 503 return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetP
oint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::zoomable
IntersectionQuotient); |
| 504 } | 504 } |
| 505 | 505 |
| 506 } // namespace blink | 506 } // namespace blink |
| OLD | NEW |