@@ -1721,6 +1721,89 @@ void main() {
1721
1721
editable.hitTest (result, position: const Offset (5.0 , 15.0 ));
1722
1722
expect (result.path, hasLength (0 ));
1723
1723
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/61020
1724
+
1725
+ test ('hits correct WidgetSpan when scrolled' , () {
1726
+ final String text = '${"\n " * 10 }test' ;
1727
+ final TextSelectionDelegate delegate = _FakeEditableTextState ()
1728
+ ..textEditingValue = TextEditingValue (
1729
+ text: text,
1730
+ selection: const TextSelection .collapsed (offset: 13 ),
1731
+ );
1732
+ final List <RenderBox > renderBoxes = < RenderBox > [
1733
+ RenderParagraph (const TextSpan (text: 'a' ), textDirection: TextDirection .ltr),
1734
+ RenderParagraph (const TextSpan (text: 'b' ), textDirection: TextDirection .ltr),
1735
+ RenderParagraph (const TextSpan (text: 'c' ), textDirection: TextDirection .ltr),
1736
+ ];
1737
+ final RenderEditable editable = RenderEditable (
1738
+ maxLines: null ,
1739
+ text: TextSpan (
1740
+ style: const TextStyle (height: 1.0 , fontSize: 10.0 ),
1741
+ children: < InlineSpan > [
1742
+ TextSpan (text: text),
1743
+ const WidgetSpan (child: Text ('a' )),
1744
+ const TextSpan (children: < InlineSpan > [
1745
+ WidgetSpan (child: Text ('b' )),
1746
+ WidgetSpan (child: Text ('c' )),
1747
+ ],
1748
+ ),
1749
+ ],
1750
+ ),
1751
+ startHandleLayerLink: LayerLink (),
1752
+ endHandleLayerLink: LayerLink (),
1753
+ textDirection: TextDirection .ltr,
1754
+ offset: ViewportOffset .fixed (100.0 ), // equal to the height of the 10 empty lines
1755
+ textSelectionDelegate: delegate,
1756
+ selection: const TextSelection .collapsed (
1757
+ offset: 0 ,
1758
+ ),
1759
+ children: renderBoxes,
1760
+ );
1761
+ _applyParentData (renderBoxes, editable.text! );
1762
+ layout (editable, constraints: BoxConstraints .loose (const Size (500.0 , 500.0 )));
1763
+ // Prepare for painting after layout.
1764
+ pumpFrame (phase: EnginePhase .compositingBits);
1765
+ BoxHitTestResult result = BoxHitTestResult ();
1766
+ editable.hitTest (result, position: Offset .zero);
1767
+ // We expect two hit test entries in the path because the RenderEditable
1768
+ // will add itself as well.
1769
+ expect (result.path, hasLength (2 ));
1770
+ HitTestTarget target = result.path.first.target;
1771
+ expect (target, isA <TextSpan >());
1772
+ expect ((target as TextSpan ).text, text);
1773
+ // Only testing the RenderEditable entry here once, not anymore below.
1774
+ expect (result.path.last.target, isA <RenderEditable >());
1775
+ result = BoxHitTestResult ();
1776
+ editable.hitTest (result, position: const Offset (15.0 , 0.0 ));
1777
+ expect (result.path, hasLength (2 ));
1778
+ target = result.path.first.target;
1779
+ expect (target, isA <TextSpan >());
1780
+ expect ((target as TextSpan ).text, text);
1781
+
1782
+ result = BoxHitTestResult ();
1783
+ editable.hitTest (result, position: const Offset (41.0 , 0.0 ));
1784
+ expect (result.path, hasLength (3 ));
1785
+ target = result.path.first.target;
1786
+ expect (target, isA <TextSpan >());
1787
+ expect ((target as TextSpan ).text, 'a' );
1788
+
1789
+ result = BoxHitTestResult ();
1790
+ editable.hitTest (result, position: const Offset (55.0 , 0.0 ));
1791
+ expect (result.path, hasLength (3 ));
1792
+ target = result.path.first.target;
1793
+ expect (target, isA <TextSpan >());
1794
+ expect ((target as TextSpan ).text, 'b' );
1795
+
1796
+ result = BoxHitTestResult ();
1797
+ editable.hitTest (result, position: const Offset (69.0 , 5.0 ));
1798
+ expect (result.path, hasLength (3 ));
1799
+ target = result.path.first.target;
1800
+ expect (target, isA <TextSpan >());
1801
+ expect ((target as TextSpan ).text, 'c' );
1802
+
1803
+ result = BoxHitTestResult ();
1804
+ editable.hitTest (result, position: const Offset (5.0 , 15.0 ));
1805
+ expect (result.path, hasLength (2 ));
1806
+ }, skip: isBrowser); // https://github.com/flutter/flutter/issues/61020
1724
1807
});
1725
1808
1726
1809
test ('does not skip TextPainter.layout because of invalid cache' , () {
0 commit comments