| Index: Source/core/dom/TreeScope.cpp
|
| diff --git a/Source/core/dom/TreeScope.cpp b/Source/core/dom/TreeScope.cpp
|
| index 7e3410bd0dc2f54dcbce9b541e900ce5aaba2c28..7206a154cc5f2da1e54ecdc34e8f41e641b2d004 100644
|
| --- a/Source/core/dom/TreeScope.cpp
|
| +++ b/Source/core/dom/TreeScope.cpp
|
| @@ -241,24 +241,35 @@ HTMLMapElement* TreeScope::getImageMap(const String& url) const
|
| return toHTMLMapElement(m_imageMapsByName->getElementByMapName(AtomicString(name), this));
|
| }
|
|
|
| -HitTestResult hitTestInDocument(const Document* document, int x, int y)
|
| +static bool pointWithScrollAndZoomIfPossible(const Document& document, IntPoint& point)
|
| {
|
| - LocalFrame* frame = document->frame();
|
| -
|
| + LocalFrame* frame = document.frame();
|
| if (!frame)
|
| - return HitTestResult();
|
| + return false;
|
| FrameView* frameView = frame->view();
|
| if (!frameView)
|
| - return HitTestResult();
|
| + return false;
|
| +
|
| + FloatPoint pointInDocument(point);
|
| + pointInDocument.scale(frame->pageZoomFactor(), frame->pageZoomFactor());
|
| + pointInDocument.moveBy(frameView->scrollPosition());
|
| + IntPoint roundedPointInDocument = roundedIntPoint(pointInDocument);
|
|
|
| - float scaleFactor = frame->pageZoomFactor();
|
| - IntPoint point = roundedIntPoint(FloatPoint(x * scaleFactor + frameView->scrollX(), y * scaleFactor + frameView->scrollY()));
|
| + if (!frameView->visibleContentRect().contains(roundedPointInDocument))
|
| + return false;
|
|
|
| - if (!frameView->visibleContentRect().contains(point))
|
| + point = roundedPointInDocument;
|
| + return true;
|
| +}
|
| +
|
| +HitTestResult hitTestInDocument(const Document* document, int x, int y)
|
| +{
|
| + IntPoint hitPoint(x, y);
|
| + if (!pointWithScrollAndZoomIfPossible(*document, hitPoint))
|
| return HitTestResult();
|
|
|
| HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
|
| - HitTestResult result(point);
|
| + HitTestResult result(hitPoint);
|
| document->renderView()->hitTest(request, result);
|
| return result;
|
| }
|
| @@ -278,6 +289,48 @@ Element* TreeScope::elementFromPoint(int x, int y) const
|
| return toElement(node);
|
| }
|
|
|
| +Vector<Element*> TreeScope::elementsFromPoint(int x, int y) const
|
| +{
|
| + Vector<Element*> elements;
|
| +
|
| + Document& document = rootNode().document();
|
| + IntPoint hitPoint(x, y);
|
| + if (!pointWithScrollAndZoomIfPossible(document, hitPoint))
|
| + return elements;
|
| +
|
| + HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ListBased | HitTestRequest::PenetratingList);
|
| + HitTestResult result(hitPoint);
|
| + document.renderView()->hitTest(request, result);
|
| +
|
| + Node* lastNode = nullptr;
|
| + for (const auto rectBasedNode : result.listBasedTestResult()) {
|
| + Node* node = rectBasedNode.get();
|
| + if (!node || !node->isElementNode() || node->isDocumentNode())
|
| + continue;
|
| +
|
| + if (node->isPseudoElement() || node->isTextNode())
|
| + node = node->parentOrShadowHostNode();
|
| + node = ancestorInThisScope(node);
|
| +
|
| + // Prune duplicate entries. A pseduo ::before content above its parent
|
| + // node should only result in a single entry.
|
| + if (node == lastNode)
|
| + continue;
|
| +
|
| + if (node && node->isElementNode()) {
|
| + elements.append(toElement(node));
|
| + lastNode = node;
|
| + }
|
| + }
|
| +
|
| + if (m_document) {
|
| + if (elements.isEmpty() || elements.last() != m_document->documentElement())
|
| + elements.append(m_document->documentElement());
|
| + }
|
| +
|
| + return elements;
|
| +}
|
| +
|
| void TreeScope::addLabel(const AtomicString& forAttributeValue, HTMLLabelElement* element)
|
| {
|
| ASSERT(m_labelsByForAttribute);
|
|
|