diff --git a/packages/sprotty/src/features/edge-junction/di.config.ts b/packages/sprotty/src/features/edge-junction/di.config.ts index 370ff64..bb14a3e 100644 --- a/packages/sprotty/src/features/edge-junction/di.config.ts +++ b/packages/sprotty/src/features/edge-junction/di.config.ts @@ -24,6 +24,7 @@ const edgeJunctionModule = new ContainerModule(bind => { bind(TYPES.IEdgeRoutePostprocessor).toService(JunctionFinder); bind(JunctionPostProcessor).toSelf().inSingletonScope(); bind(TYPES.IVNodePostprocessor).toService(JunctionPostProcessor); + bind(TYPES.HiddenVNodePostprocessor).toService(JunctionPostProcessor); }); export default edgeJunctionModule; diff --git a/packages/sprotty/src/features/edge-junction/junction-postprocessor.ts b/packages/sprotty/src/features/edge-junction/junction-postprocessor.ts index a15b2ae..b2ca306 100644 --- a/packages/sprotty/src/features/edge-junction/junction-postprocessor.ts +++ b/packages/sprotty/src/features/edge-junction/junction-postprocessor.ts @@ -14,13 +14,14 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { injectable, inject } from "inversify"; -import { IVNodePostprocessor } from "../../base/views/vnode-postprocessor"; +import { inject, injectable } from "inversify"; import { VNode } from "snabbdom"; -import { Action } from "sprotty-protocol"; +import { Action, RequestBoundsAction, SModelRoot } from "sprotty-protocol"; import { SModelElementImpl } from "../../base/model/smodel"; import { TYPES } from "../../base/types"; import { ViewerOptions } from "../../base/views/viewer-options"; +import { IVNodePostprocessor } from "../../base/views/vnode-postprocessor"; +import { ModelSource } from "../../model-source/model-source"; /** * Finds all junction points in the first SVG group element (diagram root level) and moves them to the end of the SVG. @@ -28,22 +29,57 @@ import { ViewerOptions } from "../../base/views/viewer-options"; */ @injectable() export class JunctionPostProcessor implements IVNodePostprocessor { + currentModel: SModelRoot; + isFirstRender = true; + @inject(TYPES.ViewerOptions) private viewerOptions: ViewerOptions; + @inject(TYPES.ModelSource) private modelSource: ModelSource; decorate(vnode: VNode, element: SModelElementImpl): VNode { return vnode; } postUpdate(cause?: Action | undefined): void { - const baseDiv = this.viewerOptions.baseDiv; - const svg = document.querySelector(`#${baseDiv} > svg > g`); - if (svg) { - const junctionGroups = Array.from(document.querySelectorAll('g.sprotty-junction')); + // if the model has changed, we need to remove the junction points from the previous model + if (this.currentModel !== this.modelSource.model) { + this.isFirstRender = true; + } + + // if the cause of the update is a RequestBoundsAction (from the hidden model) + // and we are rendering the diagram for the first time (not from an update or setting the same model again) + // we need to remove the junction points from the previous model + if (cause?.kind === RequestBoundsAction.KIND && this.isFirstRender) { + const junctionPointsInHiddenDiv = document.querySelectorAll(`#${this.viewerOptions.hiddenDiv} > svg > g > g.sprotty-junction`); + junctionPointsInHiddenDiv.forEach(e => e.remove()); + + const junctionPointsInBaseDiv = document.querySelectorAll(`#${this.viewerOptions.baseDiv} > svg > g > g.sprotty-junction`); + junctionPointsInBaseDiv.forEach(e => e.remove()); + } + + const hiddenSvg = document.querySelector(`#${this.viewerOptions.hiddenDiv} > svg > g`); + const baseSvg = document.querySelector(`#${this.viewerOptions.baseDiv} > svg > g`); + + // move junction points to the end of the SVG in the hidden div + if (hiddenSvg) { + const junctionGroups = Array.from(document.querySelectorAll(`#${this.viewerOptions.hiddenDiv} > svg > g > g > g.sprotty-junction`)); junctionGroups.forEach(junctionGroup => { junctionGroup.remove(); }); + hiddenSvg.append(...junctionGroups); + } - svg.append(...junctionGroups); + // move junction points to the end of the SVG in the base div + if (baseSvg) { + const junctionGroups = Array.from(document.querySelectorAll(`#${this.viewerOptions.baseDiv} > svg > g > g > g.sprotty-junction`)); + junctionGroups.forEach(junctionGroup => { + junctionGroup.remove(); + }); + baseSvg.append(...junctionGroups); } + + // update the current model + this.currentModel = this.modelSource.model; + // after the first render, we don't need to remove the junction points anymore + this.isFirstRender = false; } } diff --git a/packages/sprotty/src/index.ts b/packages/sprotty/src/index.ts index 675a89c..89ac96e 100644 --- a/packages/sprotty/src/index.ts +++ b/packages/sprotty/src/index.ts @@ -113,6 +113,7 @@ export * from './features/edge-intersection/intersection-finder'; export * from './features/edge-intersection/sweepline'; export * from './features/edge-junction/junction-finder'; +export * from './features/edge-junction/junction-postprocessor'; export * from './features/move/model'; export * from './features/move/move';