Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: Source/core/rendering/HitTestResult.cpp

Issue 869813003: Implement elementsFromPoint (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix typeo Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2008, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2008, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 : m_hitTestLocation(other.m_hitTestLocation) 75 : m_hitTestLocation(other.m_hitTestLocation)
76 , m_innerNode(other.innerNode()) 76 , m_innerNode(other.innerNode())
77 , m_innerPossiblyPseudoNode(other.m_innerPossiblyPseudoNode) 77 , m_innerPossiblyPseudoNode(other.m_innerPossiblyPseudoNode)
78 , m_innerNonSharedNode(other.innerNonSharedNode()) 78 , m_innerNonSharedNode(other.innerNonSharedNode())
79 , m_pointInInnerNodeFrame(other.m_pointInInnerNodeFrame) 79 , m_pointInInnerNodeFrame(other.m_pointInInnerNodeFrame)
80 , m_localPoint(other.localPoint()) 80 , m_localPoint(other.localPoint())
81 , m_innerURLElement(other.URLElement()) 81 , m_innerURLElement(other.URLElement())
82 , m_scrollbar(other.scrollbar()) 82 , m_scrollbar(other.scrollbar())
83 , m_isOverWidget(other.isOverWidget()) 83 , m_isOverWidget(other.isOverWidget())
84 { 84 {
85 // Only copy the NodeSet in case of rect hit test. 85 // Only copy the NodeSet in case of list hit test.
86 m_rectBasedTestResult = adoptPtrWillBeNoop(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0); 86 m_listBasedTestResult = adoptPtrWillBeNoop(other.m_listBasedTestResult ? new NodeSet(*other.m_listBasedTestResult) : 0);
87 } 87 }
88 88
89 HitTestResult::~HitTestResult() 89 HitTestResult::~HitTestResult()
90 { 90 {
91 } 91 }
92 92
93 HitTestResult& HitTestResult::operator=(const HitTestResult& other) 93 HitTestResult& HitTestResult::operator=(const HitTestResult& other)
94 { 94 {
95 m_hitTestLocation = other.m_hitTestLocation; 95 m_hitTestLocation = other.m_hitTestLocation;
96 m_innerNode = other.innerNode(); 96 m_innerNode = other.innerNode();
97 m_innerPossiblyPseudoNode = other.innerPossiblyPseudoNode(); 97 m_innerPossiblyPseudoNode = other.innerPossiblyPseudoNode();
98 m_innerNonSharedNode = other.innerNonSharedNode(); 98 m_innerNonSharedNode = other.innerNonSharedNode();
99 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame; 99 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame;
100 m_localPoint = other.localPoint(); 100 m_localPoint = other.localPoint();
101 m_innerURLElement = other.URLElement(); 101 m_innerURLElement = other.URLElement();
102 m_scrollbar = other.scrollbar(); 102 m_scrollbar = other.scrollbar();
103 m_isOverWidget = other.isOverWidget(); 103 m_isOverWidget = other.isOverWidget();
104 104
105 // Only copy the NodeSet in case of rect hit test. 105 // Only copy the NodeSet in case of list hit test.
106 m_rectBasedTestResult = adoptPtrWillBeNoop(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0); 106 m_listBasedTestResult = adoptPtrWillBeNoop(other.m_listBasedTestResult ? new NodeSet(*other.m_listBasedTestResult) : 0);
107 107
108 return *this; 108 return *this;
109 } 109 }
110 110
111 void HitTestResult::trace(Visitor* visitor) 111 void HitTestResult::trace(Visitor* visitor)
112 { 112 {
113 visitor->trace(m_innerNode); 113 visitor->trace(m_innerNode);
114 visitor->trace(m_innerPossiblyPseudoNode); 114 visitor->trace(m_innerPossiblyPseudoNode);
115 visitor->trace(m_innerNonSharedNode); 115 visitor->trace(m_innerNonSharedNode);
116 visitor->trace(m_innerURLElement); 116 visitor->trace(m_innerURLElement);
117 visitor->trace(m_scrollbar); 117 visitor->trace(m_scrollbar);
118 #if ENABLE(OILPAN) 118 #if ENABLE(OILPAN)
119 visitor->trace(m_rectBasedTestResult); 119 visitor->trace(m_listBasedTestResult);
120 #endif 120 #endif
121 } 121 }
122 122
123 PositionWithAffinity HitTestResult::position() const 123 PositionWithAffinity HitTestResult::position() const
124 { 124 {
125 if (!m_innerPossiblyPseudoNode) 125 if (!m_innerPossiblyPseudoNode)
126 return PositionWithAffinity(); 126 return PositionWithAffinity();
127 RenderObject* renderer = this->renderer(); 127 RenderObject* renderer = this->renderer();
128 if (!renderer) 128 if (!renderer)
129 return PositionWithAffinity(); 129 return PositionWithAffinity();
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 return !toHTMLTextAreaElement(*m_innerNonSharedNode).isDisabledOrReadOnl y(); 364 return !toHTMLTextAreaElement(*m_innerNonSharedNode).isDisabledOrReadOnl y();
365 365
366 if (isHTMLInputElement(*m_innerNonSharedNode)) { 366 if (isHTMLInputElement(*m_innerNonSharedNode)) {
367 HTMLInputElement& inputElement = toHTMLInputElement(*m_innerNonSharedNod e); 367 HTMLInputElement& inputElement = toHTMLInputElement(*m_innerNonSharedNod e);
368 return !inputElement.isDisabledOrReadOnly() && inputElement.isTextField( ); 368 return !inputElement.isDisabledOrReadOnly() && inputElement.isTextField( );
369 } 369 }
370 370
371 return m_innerNonSharedNode->hasEditableStyle(); 371 return m_innerNonSharedNode->hasEditableStyle();
372 } 372 }
373 373
374 bool HitTestResult::addNodeToRectBasedTestResult(Node* node, const HitTestReques t& request, const HitTestLocation& locationInContainer, const LayoutRect& rect) 374 bool HitTestResult::addNodeToListBasedTestResult(Node* node, const HitTestReques t& request, const HitTestLocation& locationInContainer, const LayoutRect& rect)
375 { 375 {
376 // If it is not a rect-based hit test, this method has to be no-op. 376 // If not a list-based test, this function should be a no-op.
377 // Return false, so the hit test stops. 377 if (!request.listBased()) {
378 if (!isRectBasedTest()) 378 ASSERT(!isRectBasedTest());
379 return false; 379 return false;
380 }
380 381
381 // If node is null, return true so the hit test can continue. 382 // If node is null, return true so the hit test can continue.
382 if (!node) 383 if (!node)
383 return true; 384 return true;
384 385
385 mutableRectBasedTestResult().add(node); 386 mutableListBasedTestResult().add(node);
387
388 if (request.penetrating())
389 return true;
386 390
387 bool regionFilled = rect.contains(locationInContainer.boundingBox()); 391 bool regionFilled = rect.contains(locationInContainer.boundingBox());
388 return !regionFilled; 392 return !regionFilled;
389 } 393 }
390 394
391 bool HitTestResult::addNodeToRectBasedTestResult(Node* node, const HitTestReques t& request, const HitTestLocation& locationInContainer, const FloatRect& rect) 395 bool HitTestResult::addNodeToListBasedTestResult(Node* node, const HitTestReques t& request, const HitTestLocation& locationInContainer, const FloatRect& rect)
392 { 396 {
393 // If it is not a rect-based hit test, this method has to be no-op. 397 // If not a list-based test, this function should be a no-op.
394 // Return false, so the hit test stops. 398 if (!request.listBased()) {
395 if (!isRectBasedTest()) 399 ASSERT(!isRectBasedTest());
396 return false; 400 return false;
401 }
397 402
398 // If node is null, return true so the hit test can continue. 403 // If node is null, return true so the hit test can continue.
399 if (!node) 404 if (!node)
400 return true; 405 return true;
401 406
402 mutableRectBasedTestResult().add(node); 407 mutableListBasedTestResult().add(node);
408
409 if (request.penetrating())
410 return true;
403 411
404 bool regionFilled = rect.contains(locationInContainer.boundingBox()); 412 bool regionFilled = rect.contains(locationInContainer.boundingBox());
405 return !regionFilled; 413 return !regionFilled;
406 } 414 }
407 415
408 void HitTestResult::append(const HitTestResult& other) 416 void HitTestResult::append(const HitTestResult& other)
409 { 417 {
410 ASSERT(isRectBasedTest() && other.isRectBasedTest());
Rick Byers 2015/02/04 10:34:03 why don't you want to assert both are list-based h
pdr. 2015/02/17 04:10:14 I've added a const HitTestRequest& parameter to ap
Rick Byers 2015/02/20 20:02:23 Seems reasonable, thanks. I was naively thinking
411
412 if (!m_scrollbar && other.scrollbar()) { 418 if (!m_scrollbar && other.scrollbar()) {
413 setScrollbar(other.scrollbar()); 419 setScrollbar(other.scrollbar());
414 } 420 }
415 421
416 if (!m_innerNode && other.innerNode()) { 422 if (!m_innerNode && other.innerNode()) {
417 m_innerNode = other.innerNode(); 423 m_innerNode = other.innerNode();
418 m_innerPossiblyPseudoNode = other.innerPossiblyPseudoNode(); 424 m_innerPossiblyPseudoNode = other.innerPossiblyPseudoNode();
419 m_innerNonSharedNode = other.innerNonSharedNode(); 425 m_innerNonSharedNode = other.innerNonSharedNode();
420 m_localPoint = other.localPoint(); 426 m_localPoint = other.localPoint();
421 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame; 427 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame;
422 m_innerURLElement = other.URLElement(); 428 m_innerURLElement = other.URLElement();
423 m_isOverWidget = other.isOverWidget(); 429 m_isOverWidget = other.isOverWidget();
424 } 430 }
425 431
426 if (other.m_rectBasedTestResult) { 432 if (other.m_listBasedTestResult) {
427 NodeSet& set = mutableRectBasedTestResult(); 433 NodeSet& set = mutableListBasedTestResult();
428 for (NodeSet::const_iterator it = other.m_rectBasedTestResult->begin(), last = other.m_rectBasedTestResult->end(); it != last; ++it) 434 for (NodeSet::const_iterator it = other.m_listBasedTestResult->begin(), last = other.m_listBasedTestResult->end(); it != last; ++it)
429 set.add(it->get()); 435 set.add(it->get());
430 } 436 }
431 } 437 }
432 438
433 const HitTestResult::NodeSet& HitTestResult::rectBasedTestResult() const 439 const HitTestResult::NodeSet& HitTestResult::listBasedTestResult() const
434 { 440 {
435 if (!m_rectBasedTestResult) 441 if (!m_listBasedTestResult)
436 m_rectBasedTestResult = adoptPtrWillBeNoop(new NodeSet); 442 m_listBasedTestResult = adoptPtrWillBeNoop(new NodeSet);
437 return *m_rectBasedTestResult; 443 return *m_listBasedTestResult;
438 } 444 }
439 445
440 HitTestResult::NodeSet& HitTestResult::mutableRectBasedTestResult() 446 HitTestResult::NodeSet& HitTestResult::mutableListBasedTestResult()
441 { 447 {
442 if (!m_rectBasedTestResult) 448 if (!m_listBasedTestResult)
443 m_rectBasedTestResult = adoptPtrWillBeNoop(new NodeSet); 449 m_listBasedTestResult = adoptPtrWillBeNoop(new NodeSet);
444 return *m_rectBasedTestResult; 450 return *m_listBasedTestResult;
445 } 451 }
446 452
447 void HitTestResult::resolveRectBasedTest(Node* resolvedInnerNode, const LayoutPo int& resolvedPointInMainFrame) 453 void HitTestResult::resolveRectBasedTest(Node* resolvedInnerNode, const LayoutPo int& resolvedPointInMainFrame)
448 { 454 {
449 ASSERT(isRectBasedTest()); 455 ASSERT(isRectBasedTest());
450 ASSERT(m_hitTestLocation.containsPoint(FloatPoint(resolvedPointInMainFrame)) ); 456 ASSERT(m_hitTestLocation.containsPoint(FloatPoint(resolvedPointInMainFrame)) );
451 m_hitTestLocation = HitTestLocation(resolvedPointInMainFrame); 457 m_hitTestLocation = HitTestLocation(resolvedPointInMainFrame);
452 m_pointInInnerNodeFrame = resolvedPointInMainFrame; 458 m_pointInInnerNodeFrame = resolvedPointInMainFrame;
453 m_innerNode = nullptr; 459 m_innerNode = nullptr;
454 m_innerNonSharedNode = nullptr; 460 m_innerNonSharedNode = nullptr;
455 m_innerPossiblyPseudoNode = nullptr; 461 m_innerPossiblyPseudoNode = nullptr;
456 m_rectBasedTestResult = nullptr; 462 m_listBasedTestResult = nullptr;
457 463
458 // Update the HitTestResult as if the supplied node had been hit in normal p oint-based hit-test. 464 // Update the HitTestResult as if the supplied node had been hit in normal p oint-based hit-test.
459 // Note that we don't know the local point after a rect-based hit-test, but we never use 465 // Note that we don't know the local point after a rect-based hit-test, but we never use
460 // it so shouldn't bother with the cost of computing it. 466 // it so shouldn't bother with the cost of computing it.
461 resolvedInnerNode->renderer()->updateHitTestResult(*this, LayoutPoint()); 467 resolvedInnerNode->renderer()->updateHitTestResult(*this, LayoutPoint());
462 ASSERT(!isRectBasedTest()); 468 ASSERT(!isRectBasedTest());
463 } 469 }
464 470
465 Element* HitTestResult::innerElement() const 471 Element* HitTestResult::innerElement() const
466 { 472 {
467 for (Node* node = m_innerNode.get(); node; node = NodeRenderingTraversal::pa rent(*node)) { 473 for (Node* node = m_innerNode.get(); node; node = NodeRenderingTraversal::pa rent(*node)) {
468 if (node->isElementNode()) 474 if (node->isElementNode())
469 return toElement(node); 475 return toElement(node);
470 } 476 }
471 477
472 return 0; 478 return 0;
473 } 479 }
474 480
475 } // namespace blink 481 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698