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

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

Issue 869813003: Implement elementsFromPoint (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Cleanup, add a better test for tables Created 5 years, 10 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
« no previous file with comments | « Source/core/layout/HitTestResult.h ('k') | Source/core/layout/Layer.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 : m_hitTestLocation(other.m_hitTestLocation) 76 : m_hitTestLocation(other.m_hitTestLocation)
77 , m_innerNode(other.innerNode()) 77 , m_innerNode(other.innerNode())
78 , m_innerPossiblyPseudoNode(other.m_innerPossiblyPseudoNode) 78 , m_innerPossiblyPseudoNode(other.m_innerPossiblyPseudoNode)
79 , m_innerNonSharedNode(other.innerNonSharedNode()) 79 , m_innerNonSharedNode(other.innerNonSharedNode())
80 , m_pointInInnerNodeFrame(other.m_pointInInnerNodeFrame) 80 , m_pointInInnerNodeFrame(other.m_pointInInnerNodeFrame)
81 , m_localPoint(other.localPoint()) 81 , m_localPoint(other.localPoint())
82 , m_innerURLElement(other.URLElement()) 82 , m_innerURLElement(other.URLElement())
83 , m_scrollbar(other.scrollbar()) 83 , m_scrollbar(other.scrollbar())
84 , m_isOverWidget(other.isOverWidget()) 84 , m_isOverWidget(other.isOverWidget())
85 { 85 {
86 // Only copy the NodeSet in case of rect hit test. 86 // Only copy the NodeSet in case of list hit test.
87 m_rectBasedTestResult = adoptPtrWillBeNoop(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0); 87 m_listBasedTestResult = adoptPtrWillBeNoop(other.m_listBasedTestResult ? new NodeSet(*other.m_listBasedTestResult) : 0);
88 } 88 }
89 89
90 HitTestResult::~HitTestResult() 90 HitTestResult::~HitTestResult()
91 { 91 {
92 } 92 }
93 93
94 HitTestResult& HitTestResult::operator=(const HitTestResult& other) 94 HitTestResult& HitTestResult::operator=(const HitTestResult& other)
95 { 95 {
96 m_hitTestLocation = other.m_hitTestLocation; 96 m_hitTestLocation = other.m_hitTestLocation;
97 m_innerNode = other.innerNode(); 97 m_innerNode = other.innerNode();
98 m_innerPossiblyPseudoNode = other.innerPossiblyPseudoNode(); 98 m_innerPossiblyPseudoNode = other.innerPossiblyPseudoNode();
99 m_innerNonSharedNode = other.innerNonSharedNode(); 99 m_innerNonSharedNode = other.innerNonSharedNode();
100 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame; 100 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame;
101 m_localPoint = other.localPoint(); 101 m_localPoint = other.localPoint();
102 m_innerURLElement = other.URLElement(); 102 m_innerURLElement = other.URLElement();
103 m_scrollbar = other.scrollbar(); 103 m_scrollbar = other.scrollbar();
104 m_isOverWidget = other.isOverWidget(); 104 m_isOverWidget = other.isOverWidget();
105 105
106 // Only copy the NodeSet in case of rect hit test. 106 // Only copy the NodeSet in case of list hit test.
107 m_rectBasedTestResult = adoptPtrWillBeNoop(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0); 107 m_listBasedTestResult = adoptPtrWillBeNoop(other.m_listBasedTestResult ? new NodeSet(*other.m_listBasedTestResult) : 0);
108 108
109 return *this; 109 return *this;
110 } 110 }
111 111
112 DEFINE_TRACE(HitTestResult) 112 DEFINE_TRACE(HitTestResult)
113 { 113 {
114 visitor->trace(m_innerNode); 114 visitor->trace(m_innerNode);
115 visitor->trace(m_innerPossiblyPseudoNode); 115 visitor->trace(m_innerPossiblyPseudoNode);
116 visitor->trace(m_innerNonSharedNode); 116 visitor->trace(m_innerNonSharedNode);
117 visitor->trace(m_innerURLElement); 117 visitor->trace(m_innerURLElement);
118 visitor->trace(m_scrollbar); 118 visitor->trace(m_scrollbar);
119 #if ENABLE(OILPAN) 119 #if ENABLE(OILPAN)
120 visitor->trace(m_rectBasedTestResult); 120 visitor->trace(m_listBasedTestResult);
121 #endif 121 #endif
122 } 122 }
123 123
124 PositionWithAffinity HitTestResult::position() const 124 PositionWithAffinity HitTestResult::position() const
125 { 125 {
126 if (!m_innerPossiblyPseudoNode) 126 if (!m_innerPossiblyPseudoNode)
127 return PositionWithAffinity(); 127 return PositionWithAffinity();
128 LayoutObject* renderer = this->renderer(); 128 LayoutObject* renderer = this->renderer();
129 if (!renderer) 129 if (!renderer)
130 return PositionWithAffinity(); 130 return PositionWithAffinity();
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 return !toHTMLTextAreaElement(*m_innerNonSharedNode).isDisabledOrReadOnl y(); 365 return !toHTMLTextAreaElement(*m_innerNonSharedNode).isDisabledOrReadOnl y();
366 366
367 if (isHTMLInputElement(*m_innerNonSharedNode)) { 367 if (isHTMLInputElement(*m_innerNonSharedNode)) {
368 HTMLInputElement& inputElement = toHTMLInputElement(*m_innerNonSharedNod e); 368 HTMLInputElement& inputElement = toHTMLInputElement(*m_innerNonSharedNod e);
369 return !inputElement.isDisabledOrReadOnly() && inputElement.isTextField( ); 369 return !inputElement.isDisabledOrReadOnly() && inputElement.isTextField( );
370 } 370 }
371 371
372 return m_innerNonSharedNode->hasEditableStyle(); 372 return m_innerNonSharedNode->hasEditableStyle();
373 } 373 }
374 374
375 bool HitTestResult::addNodeToRectBasedTestResult(Node* node, const HitTestReques t& request, const HitTestLocation& locationInContainer, const LayoutRect& rect) 375 bool HitTestResult::addNodeToListBasedTestResult(Node* node, const HitTestReques t& request, const HitTestLocation& locationInContainer, const LayoutRect& rect)
376 { 376 {
377 // If it is not a rect-based hit test, this method has to be no-op. 377 // If not a list-based test, this function should be a no-op.
378 // Return false, so the hit test stops. 378 if (!request.listBased()) {
379 if (!isRectBasedTest()) 379 ASSERT(!isRectBasedTest());
380 return false; 380 return false;
381 }
381 382
382 // If node is null, return true so the hit test can continue. 383 // If node is null, return true so the hit test can continue.
383 if (!node) 384 if (!node)
384 return true; 385 return true;
385 386
386 mutableRectBasedTestResult().add(node); 387 mutableListBasedTestResult().add(node);
388
389 if (request.penetratingList())
390 return true;
387 391
388 bool regionFilled = rect.contains(locationInContainer.boundingBox()); 392 bool regionFilled = rect.contains(locationInContainer.boundingBox());
389 return !regionFilled; 393 return !regionFilled;
390 } 394 }
391 395
392 bool HitTestResult::addNodeToRectBasedTestResult(Node* node, const HitTestReques t& request, const HitTestLocation& locationInContainer, const FloatRect& rect) 396 bool HitTestResult::addNodeToListBasedTestResult(Node* node, const HitTestReques t& request, const HitTestLocation& locationInContainer, const FloatRect& rect)
393 { 397 {
394 // If it is not a rect-based hit test, this method has to be no-op. 398 // If not a list-based test, this function should be a no-op.
395 // Return false, so the hit test stops. 399 if (!request.listBased()) {
396 if (!isRectBasedTest()) 400 ASSERT(!isRectBasedTest());
397 return false; 401 return false;
402 }
398 403
399 // If node is null, return true so the hit test can continue. 404 // If node is null, return true so the hit test can continue.
400 if (!node) 405 if (!node)
401 return true; 406 return true;
402 407
403 mutableRectBasedTestResult().add(node); 408 mutableListBasedTestResult().add(node);
409
410 if (request.penetratingList())
411 return true;
404 412
405 bool regionFilled = rect.contains(locationInContainer.boundingBox()); 413 bool regionFilled = rect.contains(locationInContainer.boundingBox());
406 return !regionFilled; 414 return !regionFilled;
407 } 415 }
408 416
409 void HitTestResult::append(const HitTestResult& other) 417 void HitTestResult::append(const HitTestResult& other, const HitTestRequest& req uest)
410 { 418 {
411 ASSERT(isRectBasedTest() && other.isRectBasedTest()); 419 ASSERT(request.listBased());
412 420
413 if (!m_scrollbar && other.scrollbar()) { 421 if (!m_scrollbar && other.scrollbar()) {
414 setScrollbar(other.scrollbar()); 422 setScrollbar(other.scrollbar());
415 } 423 }
416 424
417 if (!m_innerNode && other.innerNode()) { 425 if (!m_innerNode && other.innerNode()) {
418 m_innerNode = other.innerNode(); 426 m_innerNode = other.innerNode();
419 m_innerPossiblyPseudoNode = other.innerPossiblyPseudoNode(); 427 m_innerPossiblyPseudoNode = other.innerPossiblyPseudoNode();
420 m_innerNonSharedNode = other.innerNonSharedNode(); 428 m_innerNonSharedNode = other.innerNonSharedNode();
421 m_localPoint = other.localPoint(); 429 m_localPoint = other.localPoint();
422 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame; 430 m_pointInInnerNodeFrame = other.m_pointInInnerNodeFrame;
423 m_innerURLElement = other.URLElement(); 431 m_innerURLElement = other.URLElement();
424 m_isOverWidget = other.isOverWidget(); 432 m_isOverWidget = other.isOverWidget();
425 } 433 }
426 434
427 if (other.m_rectBasedTestResult) { 435 if (other.m_listBasedTestResult) {
428 NodeSet& set = mutableRectBasedTestResult(); 436 NodeSet& set = mutableListBasedTestResult();
429 for (NodeSet::const_iterator it = other.m_rectBasedTestResult->begin(), last = other.m_rectBasedTestResult->end(); it != last; ++it) 437 for (NodeSet::const_iterator it = other.m_listBasedTestResult->begin(), last = other.m_listBasedTestResult->end(); it != last; ++it)
430 set.add(it->get()); 438 set.add(it->get());
431 } 439 }
432 } 440 }
433 441
434 const HitTestResult::NodeSet& HitTestResult::rectBasedTestResult() const 442 const HitTestResult::NodeSet& HitTestResult::listBasedTestResult() const
435 { 443 {
436 if (!m_rectBasedTestResult) 444 if (!m_listBasedTestResult)
437 m_rectBasedTestResult = adoptPtrWillBeNoop(new NodeSet); 445 m_listBasedTestResult = adoptPtrWillBeNoop(new NodeSet);
438 return *m_rectBasedTestResult; 446 return *m_listBasedTestResult;
439 } 447 }
440 448
441 HitTestResult::NodeSet& HitTestResult::mutableRectBasedTestResult() 449 HitTestResult::NodeSet& HitTestResult::mutableListBasedTestResult()
442 { 450 {
443 if (!m_rectBasedTestResult) 451 if (!m_listBasedTestResult)
444 m_rectBasedTestResult = adoptPtrWillBeNoop(new NodeSet); 452 m_listBasedTestResult = adoptPtrWillBeNoop(new NodeSet);
445 return *m_rectBasedTestResult; 453 return *m_listBasedTestResult;
446 } 454 }
447 455
448 void HitTestResult::resolveRectBasedTest(Node* resolvedInnerNode, const LayoutPo int& resolvedPointInMainFrame) 456 void HitTestResult::resolveRectBasedTest(Node* resolvedInnerNode, const LayoutPo int& resolvedPointInMainFrame)
449 { 457 {
450 ASSERT(isRectBasedTest()); 458 ASSERT(isRectBasedTest());
451 ASSERT(m_hitTestLocation.containsPoint(FloatPoint(resolvedPointInMainFrame)) ); 459 ASSERT(m_hitTestLocation.containsPoint(FloatPoint(resolvedPointInMainFrame)) );
452 m_hitTestLocation = HitTestLocation(resolvedPointInMainFrame); 460 m_hitTestLocation = HitTestLocation(resolvedPointInMainFrame);
453 m_pointInInnerNodeFrame = resolvedPointInMainFrame; 461 m_pointInInnerNodeFrame = resolvedPointInMainFrame;
454 m_innerNode = nullptr; 462 m_innerNode = nullptr;
455 m_innerNonSharedNode = nullptr; 463 m_innerNonSharedNode = nullptr;
456 m_innerPossiblyPseudoNode = nullptr; 464 m_innerPossiblyPseudoNode = nullptr;
457 m_rectBasedTestResult = nullptr; 465 m_listBasedTestResult = nullptr;
458 466
459 // Update the HitTestResult as if the supplied node had been hit in normal p oint-based hit-test. 467 // Update the HitTestResult as if the supplied node had been hit in normal p oint-based hit-test.
460 // Note that we don't know the local point after a rect-based hit-test, but we never use 468 // Note that we don't know the local point after a rect-based hit-test, but we never use
461 // it so shouldn't bother with the cost of computing it. 469 // it so shouldn't bother with the cost of computing it.
462 resolvedInnerNode->renderer()->updateHitTestResult(*this, LayoutPoint()); 470 resolvedInnerNode->renderer()->updateHitTestResult(*this, LayoutPoint());
463 ASSERT(!isRectBasedTest()); 471 ASSERT(!isRectBasedTest());
464 } 472 }
465 473
466 Element* HitTestResult::innerElement() const 474 Element* HitTestResult::innerElement() const
467 { 475 {
468 for (Node* node = m_innerNode.get(); node; node = NodeRenderingTraversal::pa rent(*node)) { 476 for (Node* node = m_innerNode.get(); node; node = NodeRenderingTraversal::pa rent(*node)) {
469 if (node->isElementNode()) 477 if (node->isElementNode())
470 return toElement(node); 478 return toElement(node);
471 } 479 }
472 480
473 return 0; 481 return 0;
474 } 482 }
475 483
476 } // namespace blink 484 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/layout/HitTestResult.h ('k') | Source/core/layout/Layer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698