Skip to content

Allow line breaks in popover links and fix positioning of preview popovers#698

Open
SteffenAstheimer wants to merge 2 commits into
developfrom
697-internal-link-text-is-not-wrapping-leading-to-overflow
Open

Allow line breaks in popover links and fix positioning of preview popovers#698
SteffenAstheimer wants to merge 2 commits into
developfrom
697-internal-link-text-is-not-wrapping-leading-to-overflow

Conversation

@SteffenAstheimer

Copy link
Copy Markdown
Contributor

This should fix the problem of non wrapping link text, described in #697.

image image

@SteffenAstheimer SteffenAstheimer added this to the Release 4.15 milestone Jul 2, 2026
@SteffenAstheimer SteffenAstheimer self-assigned this Jul 2, 2026
@SteffenAstheimer SteffenAstheimer linked an issue Jul 2, 2026 that may be closed by this pull request
@SteffenAstheimer SteffenAstheimer changed the title overwrite nowrap property for .preview link text Allow line breaks in popover links and fix positioning of preview popovers Jul 8, 2026
@SteffenAstheimer

Copy link
Copy Markdown
Contributor Author

I added some javascript to solve the issue described in #142.

If the .preview element wraps over multiple lines, Popper positions the popover against the element's getBoundingClientRect(), which covers all visual line fragments at once and thus ends up in the middle of the line.

I introduced a helper function that creates an invisible span as popover anchor for the individual line fragment that was clicked, which is deduced by the position of the cursor.

const popoverTrigger = createPopoverAnchor(this, event);

function createPopoverAnchor(source, event) {
const rect = source.classList.contains('preview') ? getClickedClientRect(source, event) : undefined;
if(undefined === rect) { return source }
const anchor = document.createElement('span');
Array.from(source.attributes).forEach(function(attribute) {
if(attribute.name !== 'id') {
anchor.setAttribute(attribute.name, attribute.value);
}
});
anchor.classList.add('preview-popover-anchor');
anchor.style.position = 'absolute';
anchor.style.left = `${rect.left + window.pageXOffset}px`;
anchor.style.top = `${rect.top + window.pageYOffset}px`;
anchor.style.width = `${Math.max(rect.width, 1)}px`;
anchor.style.height = `${Math.max(rect.height, 1)}px`;
anchor.style.pointerEvents = 'none';
anchor.style.opacity = '0';
document.body.appendChild(anchor);
return anchor;
}

function getClickedClientRect(element, event) {
const originalEvent = event.originalEvent || event,
pointer = originalEvent.changedTouches ? originalEvent.changedTouches[0] : originalEvent,
clientX = pointer.clientX,
clientY = pointer.clientY,
rects = Array.from(element.getClientRects());
let closestRect,
closestDistance = Number.POSITIVE_INFINITY;
if(undefined === clientX || undefined === clientY || rects.length < 2) { return }
for(const rect of rects) {
if(clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom) {
return rect;
}
const distanceX = Math.max(rect.left - clientX, 0, clientX - rect.right),
distanceY = Math.max(rect.top - clientY, 0, clientY - rect.bottom),
distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY);
if(distance < closestDistance) {
closestRect = rect;
closestDistance = distance;
}
}
return closestRect;
}

The only real issue I could find, is that each line fragment is treated as its own element in such a way, that you can open multiple popovers for the same link. But I could live with that.

image

@SteffenAstheimer SteffenAstheimer requested review from peterstadler and removed request for peterstadler July 8, 2026 13:38
@SteffenAstheimer SteffenAstheimer force-pushed the 697-internal-link-text-is-not-wrapping-leading-to-overflow branch from 27adbc2 to 64510a4 Compare July 8, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

internal link text is not wrapping, leading to overflow

1 participant