-
Notifications
You must be signed in to change notification settings - Fork 9
Description
TL;DR;
When the content contains elements with the vertical-align
style - the mergeClientRects
can unexpectedly preserve selection only over it, ignoring everything before.
App:
selection_dismissed_bug.mp4
@recogito/text-annotator
sandbox:
selection_bug.mp4
Issue
I tracked down that the "dismissal" of the content before the "super" element happens in the mergeClientRects
function.
It establishes the block-is-contained
relation between the "super" element rect and the rects on the left:
Rects | Relation |
---|---|
![]() |
![]() |
} else if (a.top >= b.top && a.bottom <= b.bottom) { | |
if (a.left >= b.left && a.right <= b.right) { | |
return 'block-is-contained'; | |
} |
After, that the merging code picks the rect with the smaller width:
So the whole left part rect gets replaced with the "super" element rect!
text-annotator-js/packages/text-annotator/src/utils/mergeClientRects.ts
Lines 94 to 101 in 5b9abad
} else if (relation === 'block-contains' || relation === 'block-is-contained') { | |
// Block containment - keep the element with smaller width | |
if (rectA.width < rectB.width) { | |
next = next.map(r => r === rectB ? rectA : r); | |
} | |
wasMerged = true; | |
break; | |
} |
Reproduction
The issue can be reproduced in the @recogito/text-annotator
sandbox (Interactive playground):
<p>In 2020, the U.S. unemployment rate rose from a longtime record low of 3.5 percent in February to 14.7 percent in April. This represents a loss of 30 million jobs or about 18 percent of the labor force prior to the COVID-19
<span class="footnote-ref-tail">pandemic.
<a class="footnote-ref" name="footnote-ref-1" href="#footnote-1">1</a>
</span> To put this total in context
</p>
.footnote-ref-tail {
white-space: nowrap;
}
.footnote-ref {
display: inline-block;
min-width: 20px;
background-clip: content-box;
vertical-align: super;
color: #5f01df;
font-size: 14px;
font-style: normal;
font-weight: bold;
line-height: 17px;
text-align: center;
text-decoration: none;
cursor: pointer;
position: relative;
top: 5px;
}
.footnote-ref::before {
content: '[';
}
.footnote-ref::after {
content: ']';
}
Question
Should we consider using the wider rect instead of the smaller one as a replacement target? That way we'll pick the container rect instead of the one that's being contained. It sounds like a more sensible approach to me 🤔