diff --git a/src/common/labelEditNoScroll.ts b/src/common/labelEditNoScroll.ts new file mode 100644 index 0000000..2b4c81d --- /dev/null +++ b/src/common/labelEditNoScroll.ts @@ -0,0 +1,42 @@ +import { ContainerModule } from "inversify"; +import { + EditLabelAction, + EditLabelActionHandler, + EditLabelUI, + SModelRootImpl, + TYPES, + configureActionHandler, +} from "sprotty"; + +// For our use-case the sprotty container is at (0, 0) and fills the whole screen. +// Scrolling is disabled using CSS which disallows scrolling from the user. +// However the page might still be scrolled due to focus events. +// This is the case for the default sprotty EditLabelUI. +// When editing a label at a position where the edit control +// of the UI would be outside the viewport (at the right or bottom) +// the page would scroll to the right/bottom due to the focus event. +// To circumvent this we inherit from the default EditLabelUI and change it to +// scroll the page back to the page origin at (0, 0) if it has been moved due to the +// focus event. + +class NoScrollEditLabelUI extends EditLabelUI { + protected override onBeforeShow( + containerElement: HTMLElement, + root: Readonly, + ...contextElementIds: string[] + ): void { + super.onBeforeShow(containerElement, root, ...contextElementIds); + + // Scroll page to 0,0 if not already there + if (window.scrollX !== 0 || window.scrollY !== 0) { + window.scrollTo(0, 0); + } + } +} + +export const noScrollLabelEditUiModule = new ContainerModule((bind, _unbind, isBound) => { + const context = { bind, isBound }; + configureActionHandler(context, EditLabelAction.KIND, EditLabelActionHandler); + bind(NoScrollEditLabelUI).toSelf().inSingletonScope(); + bind(TYPES.IUIExtension).toService(NoScrollEditLabelUI); +}); diff --git a/src/index.ts b/src/index.ts index 096e821..e8d2ebf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,7 +15,6 @@ import { exportModule, hoverModule, labelEditModule, - labelEditUiModule, modelSourceModule, moveModule, routingModule, @@ -28,6 +27,7 @@ import { import { elkLayoutModule } from "sprotty-elk"; import { dfdAutoLayoutModule } from "./features/autoLayout/di.config"; import { dfdCommonModule } from "./common/di.config"; +import { noScrollLabelEditUiModule } from "./common/labelEditNoScroll"; import { dfdLabelModule } from "./features/labels/di.config"; import { toolPaletteModule } from "./features/toolPalette/di.config"; import { serializeModule } from "./features/serialize/di.config"; @@ -68,7 +68,6 @@ container.load( zorderModule, undoRedoModule, labelEditModule, - labelEditUiModule, edgeEditModule, exportModule, edgeLayoutModule, @@ -78,6 +77,8 @@ container.load( // Custom modules dfdCommonModule, + noScrollLabelEditUiModule, + dfdAutoLayoutModule, dfdElementsModule, serializeModule,