Skip to content

Commit 7bfe334

Browse files
committed
Dragging a selection into a pseudo element results in incorrect selection of the host element.
https://bugs.webkit.org/show_bug.cgi?id=304434 rdar://142905243 Reviewed by Tim Nguyen. We do not support selection in pseudo elements. So when we drag a selection across a pseudo element, and we set the inner node for the hit test, if it is a pseudo element, we set the node to the host element instead. However, when we do this, we did nothing to set the localPoint in that element to something that made sense. In the following illustration, 'Pseudo' is a pseudo element, 'Element' is the host element that is a regular div otherwise. Pseudo Element ^ ^ | | When the cursor is at 'e' in Pseudo, and the element is reset, the cursor is then effectively at the second 'e' in Element. If you started your selection after the first 'E' and dragged backwards, once you reached the 'e' in Pseudo, you selection would be 'le', not just the first 'E' as you would expect. To avoid this issue, when setting the local point we check to see if the pseudo element identifier has been set, and if so, we zero out the point instead of using the offset that is not longer applicable. Progressed imported/w3c/web-platform-tests/css/css-pseudo/text-selection.html * Source/WebCore/rendering/HitTestResult.cpp: (WebCore::HitTestResult::setLocalPoint): * Source/WebCore/rendering/HitTestResult.h: (WebCore::HitTestResult::setLocalPoint): Deleted. * Source/WebCore/rendering/RenderObject.cpp: (WebCore::RenderObject::updateHitTestResult const): Canonical link: https://commits.webkit.org/304719@main
1 parent 3f5f349 commit 7bfe334

File tree

4 files changed

+9
-4
lines changed

4 files changed

+9
-4
lines changed

LayoutTests/imported/w3c/web-platform-tests/css/css-pseudo/text-selection-expected.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ helloworld
22
helloworld
33
helloworld
44

5-
FAIL Selection ending in ::before assert_equals: toString expected "hello" but got "o"
6-
FAIL Selection contained in ::before assert_equals: toString expected "" but got "llo"
5+
PASS Selection ending in ::before
6+
PASS Selection contained in ::before
77
PASS Selection ending in ::marker
88
PASS Selection contained in ::marker
99
FAIL Selection ending in ::before-marker assert_equals: toString expected "hello" but got "o"

Source/WebCore/rendering/HitTestResult.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,11 @@ LocalFrame* HitTestResult::innerNodeFrame() const
206206
return 0;
207207
}
208208

209+
void HitTestResult::setLocalPoint(const LayoutPoint& p)
210+
{
211+
m_localPoint = m_pseudoElementIdentifier ? LayoutPoint() : p;
212+
}
213+
209214
std::optional<Style::PseudoElementIdentifier> HitTestResult::pseudoElementIdentifier() const
210215
{
211216
return m_pseudoElementIdentifier;

Source/WebCore/rendering/HitTestResult.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class HitTestResult {
9999

100100
// The hit-tested point in the coordinates of the inner node.
101101
const LayoutPoint& localPoint() const { return m_localPoint; }
102-
void setLocalPoint(const LayoutPoint& p) { m_localPoint = p; }
102+
void setLocalPoint(const LayoutPoint&);
103103

104104
WEBCORE_EXPORT void setToNonUserAgentShadowAncestor();
105105

Source/WebCore/rendering/RenderObject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1887,8 +1887,8 @@ void RenderObject::updateHitTestResult(HitTestResult& result, const LayoutPoint&
18871887
result.setInnerNode(node.get());
18881888
if (!result.innerNonSharedNode())
18891889
result.setInnerNonSharedNode(node.get());
1890-
result.setLocalPoint(point);
18911890
result.setPseudoElementIdentifier(style().pseudoElementIdentifier());
1891+
result.setLocalPoint(point);
18921892
}
18931893
}
18941894

0 commit comments

Comments
 (0)