Skip to content

Commit 6acfc2f

Browse files
committed
refactor: use editor.coordsAtPos() instead of manual DOM traversal
Replace getViewportCoordsFromPainterHost with editor.coordsAtPos() which delegates to PresentationEditor.coordsAtPos() in presentation mode. This handles all node types, zoom, and scroll via the layout engine instead of fragile CSS class-based DOM scraping.
1 parent 12b25bd commit 6acfc2f

1 file changed

Lines changed: 6 additions & 72 deletions

File tree

packages/super-editor/src/extensions/popover-plugin/popover-plugin.js

Lines changed: 6 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -150,87 +150,21 @@ class Popover {
150150
}
151151

152152
showPopoverAtPosition(pos) {
153-
let left = 0;
154-
let top = 0;
155-
let source = 'fallback';
156-
157-
// In presentation mode, find position using DOM elements in painterHost
158-
const presentationEditor = this.editor.presentationEditor;
159-
if (presentationEditor) {
160-
const result = this.getViewportCoordsFromPainterHost(presentationEditor, pos);
161-
if (result) {
162-
left = result.left;
163-
top = result.bottom;
164-
source = 'painterHost DOM';
165-
}
166-
}
167-
168-
// Fallback to view.coordsAtPos for non-presentation mode
169-
if (source === 'fallback') {
170-
const coords = this.view.coordsAtPos(pos);
171-
left = coords.left;
172-
top = coords.bottom;
173-
}
153+
const coords = this.editor.coordsAtPos(pos);
154+
if (!coords) return;
174155

175156
this.popoverRect = {
176157
width: 0,
177158
height: 0,
178-
top: top,
179-
left: left,
180-
bottom: top,
181-
right: left,
159+
top: coords.bottom,
160+
left: coords.left,
161+
bottom: coords.bottom,
162+
right: coords.left,
182163
};
183164

184165
this.tippyInstance.show();
185166
}
186167

187-
/**
188-
* Get viewport coordinates by finding the DOM element in the painted content.
189-
* This works in presentation mode where the actual DOM is off-screen but
190-
* painted elements exist in the painterHost.
191-
*/
192-
getViewportCoordsFromPainterHost(presentationEditor, pos) {
193-
// Access painterHost through the DOM - it's a private field but we can find it by class
194-
const visibleHost = presentationEditor.element;
195-
if (!visibleHost) return null;
196-
197-
// painterHost has class 'presentation-editor__pages'
198-
const painterHost = visibleHost.querySelector('.presentation-editor__pages');
199-
if (!painterHost) return null;
200-
201-
// Find all page elements
202-
const pageEls = painterHost.querySelectorAll('.superdoc-page[data-page-index]');
203-
if (!pageEls.length) return null;
204-
205-
// Search through pages for a span containing this position
206-
for (const pageEl of pageEls) {
207-
const spanEls = pageEl.querySelectorAll('span[data-pm-start][data-pm-end]');
208-
for (const spanEl of spanEls) {
209-
const pmStart = Number(spanEl.dataset.pmStart);
210-
const pmEnd = Number(spanEl.dataset.pmEnd);
211-
212-
if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
213-
const textNode = spanEl.firstChild;
214-
const charIndex = Math.min(pos - pmStart, textNode.length);
215-
216-
const range = document.createRange();
217-
range.setStart(textNode, charIndex);
218-
range.setEnd(textNode, charIndex);
219-
220-
const rect = range.getBoundingClientRect();
221-
222-
return {
223-
left: rect.left,
224-
top: rect.top,
225-
bottom: rect.bottom,
226-
};
227-
}
228-
}
229-
}
230-
231-
return null;
232-
}
233-
234168
getMentionText(from) {
235169
const maxLookBehind = 20;
236170
const startPos = Math.max(0, from - maxLookBehind);

0 commit comments

Comments
 (0)