diff --git a/services/web/frontend/js/features/source-editor/extensions/index.ts b/services/web/frontend/js/features/source-editor/extensions/index.ts index e3c0a28ccb..f7ab774d15 100644 --- a/services/web/frontend/js/features/source-editor/extensions/index.ts +++ b/services/web/frontend/js/features/source-editor/extensions/index.ts @@ -53,6 +53,7 @@ import { ranges } from './ranges' import { historyOT } from './history-ot' import { trackDetachedComments } from './track-detached-comments' import { reviewTooltip } from './review-tooltip' +import { tooltipsReposition } from './tooltips-reposition' const moduleExtensions: Array<(options: Record) => Extension> = importOverleafModules('sourceEditorExtensions').map( @@ -170,4 +171,5 @@ export const createExtensions = (options: Record): Extension[] => [ effectListeners(), geometryChangeEvent(), fileTreeItemDrop(), + tooltipsReposition(), ] diff --git a/services/web/frontend/js/features/source-editor/extensions/math-preview.ts b/services/web/frontend/js/features/source-editor/extensions/math-preview.ts index 3df55b2f28..1b9e051978 100644 --- a/services/web/frontend/js/features/source-editor/extensions/math-preview.ts +++ b/services/web/frontend/js/features/source-editor/extensions/math-preview.ts @@ -1,10 +1,4 @@ -import { - EditorView, - repositionTooltips, - showTooltip, - Tooltip, - ViewPlugin, -} from '@codemirror/view' +import { EditorView, showTooltip, Tooltip, ViewPlugin } from '@codemirror/view' import { Compartment, EditorState, @@ -24,8 +18,8 @@ import { documentCommands } from '../languages/latex/document-commands' import { debugConsole } from '@/utils/debugging' import { nodeHasError } from '../utils/tree-operations/common' import { documentEnvironments } from '../languages/latex/document-environments' +import { repositionAllTooltips } from './tooltips-reposition' -const REPOSITION_EVENT = 'editor:repositionMathTooltips' const HIDE_TOOLTIP_EVENT = 'editor:hideMathTooltip' export const mathPreview = (enabled: boolean): Extension => { @@ -81,19 +75,16 @@ export const mathPreviewStateField = StateField.define<{ showTooltip.compute([field], state => state.field(field).tooltip), ViewPlugin.define(view => { - const listener = () => repositionTooltips(view) const hideTooltip = () => { view.dispatch({ effects: hideTooltipEffect.of(null), }) } - window.addEventListener(REPOSITION_EVENT, listener) window.addEventListener(HIDE_TOOLTIP_EVENT, hideTooltip) return { destroy() { - window.removeEventListener(REPOSITION_EVENT, listener) window.removeEventListener(HIDE_TOOLTIP_EVENT, hideTooltip) }, } @@ -220,7 +211,7 @@ const buildTooltipContent = ( renderMath(math.content, math.displayMode, element, definitions) .then(() => { element.style.opacity = '1' - window.dispatchEvent(new Event(REPOSITION_EVENT)) + repositionAllTooltips() }) .catch(error => { debugConsole.error(error) diff --git a/services/web/frontend/js/features/source-editor/extensions/tooltips-reposition.ts b/services/web/frontend/js/features/source-editor/extensions/tooltips-reposition.ts new file mode 100644 index 0000000000..cb350b2e06 --- /dev/null +++ b/services/web/frontend/js/features/source-editor/extensions/tooltips-reposition.ts @@ -0,0 +1,20 @@ +import { repositionTooltips, ViewPlugin } from '@codemirror/view' + +const REPOSITION_EVENT = 'editor:repositionAllTooltips' + +export const tooltipsReposition = () => + ViewPlugin.define(view => { + const listener = () => repositionTooltips(view) + + window.addEventListener(REPOSITION_EVENT, listener) + + return { + destroy() { + window.removeEventListener(REPOSITION_EVENT, listener) + }, + } + }) + +export const repositionAllTooltips = () => { + window.dispatchEvent(new Event(REPOSITION_EVENT)) +} diff --git a/services/web/frontend/js/shared/context/layout-context.tsx b/services/web/frontend/js/shared/context/layout-context.tsx index 8dcc1fd8ff..6bc8c5b222 100644 --- a/services/web/frontend/js/shared/context/layout-context.tsx +++ b/services/web/frontend/js/shared/context/layout-context.tsx @@ -21,6 +21,7 @@ import { isMac } from '@/shared/utils/os' import { sendSearchEvent } from '@/features/event-tracking/search-events' import { useRailContext } from '@/features/ide-redesign/contexts/rail-context' import usePersistedState from '@/shared/hooks/use-persisted-state' +import { repositionAllTooltips } from '@/features/source-editor/extensions/tooltips-reposition' export type IdeLayout = 'sideBySide' | 'flat' export type IdeView = 'editor' | 'file' | 'pdf' | 'history' @@ -198,6 +199,15 @@ export const LayoutProvider: FC = ({ children }) => { [setPdfLayout, setView] ) + // Force codemirror to reposition all tooltips to prevent an issue + // where tooltips would sometimes show on top of the pdf preview + // https://github.com/overleaf/internal/issues/23840 + useEffect(() => { + if (view === 'pdf' && pdfLayout === 'flat') { + repositionAllTooltips() + } + }, [view, pdfLayout]) + const { reattach, detach,