From 9083c7d95c379037f196ced3db4f4d49283c5929 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 4 Jul 2023 06:53:21 +0200 Subject: [PATCH 01/90] POC maxGraph 0.1.0 v1 --- dev/ts/component/SvgExporter.ts | 70 ++-- dev/ts/component/ThemedBpmnVisualization.ts | 49 ++- dev/ts/main.ts | 2 +- package.json | 3 +- src/bpmn-visualization.ts | 6 - src/component/mxgraph/BpmnGraph.ts | 92 ++++- src/component/mxgraph/BpmnRenderer.ts | 40 +- src/component/mxgraph/GraphCellUpdater.ts | 14 +- src/component/mxgraph/GraphConfigurator.ts | 17 +- .../mxgraph/config/MarkerConfigurator.ts | 14 +- .../mxgraph/config/ShapeConfigurator.ts | 114 +++--- .../mxgraph/config/StyleConfigurator.ts | 263 +++++++----- src/component/mxgraph/initializer.ts | 77 ---- .../mxgraph/overlay/custom-overlay.ts | 42 +- src/component/mxgraph/overlay/shapes.ts | 10 +- .../mxgraph/renderer/CoordinatesTranslator.ts | 23 +- .../mxgraph/renderer/StyleComputer.ts | 175 +++++--- src/component/mxgraph/renderer/style-utils.ts | 63 ++- .../mxgraph/shape/activity-shapes.ts | 29 +- src/component/mxgraph/shape/edges.ts | 28 +- src/component/mxgraph/shape/event-shapes.ts | 23 +- src/component/mxgraph/shape/flow-shapes.ts | 25 +- src/component/mxgraph/shape/gateway-shapes.ts | 17 +- .../mxgraph/shape/render/BpmnCanvas.ts | 8 +- .../mxgraph/shape/render/icon-painter.ts | 91 +++-- .../mxgraph/shape/text-annotation-shapes.ts | 10 +- src/component/mxgraph/style/identifiers.ts | 16 +- src/component/mxgraph/style/utils.ts | 17 +- src/component/version.ts | 4 +- test/integration/BpmnVisualization.test.ts | 4 +- test/integration/config/mxgraph-config.ts | 4 +- test/integration/helpers/model-expect.ts | 36 +- test/integration/matchers/matcher-utils.ts | 44 +- test/integration/matchers/toBeCell/index.ts | 4 +- test/integration/matchers/toBeEdge/index.ts | 55 ++- test/integration/matchers/toBeShape/index.ts | 92 ++++- .../mxGraph.model.bpmn.elements.test.ts | 101 +++-- .../mxgraph/renderer/StyleComputer.test.ts | 382 +++++++++++++++--- .../mxgraph/renderer/style-utils.test.ts | 69 ++-- vite.config.js | 7 +- 40 files changed, 1327 insertions(+), 813 deletions(-) delete mode 100644 src/component/mxgraph/initializer.ts diff --git a/dev/ts/component/SvgExporter.ts b/dev/ts/component/SvgExporter.ts index b6602c5e07..7c7ba7cfa3 100644 --- a/dev/ts/component/SvgExporter.ts +++ b/dev/ts/component/SvgExporter.ts @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { mxgraph, mxClient, mxConstants, mxSvgCanvas2D, mxUtils } from '../../../src/component/mxgraph/initializer'; -import type { mxGraph, mxSvgCanvas2D as mxSvgCanvas2DType } from 'mxgraph'; +import type { Graph, AlignValue, VAlignValue, OverflowValue, TextDirectionValue } from '@maxgraph/core'; +import { Client, SvgCanvas2D, ImageExport, constants, xmlUtils, domUtils, stringUtils } from '@maxgraph/core'; interface SvgExportOptions { scale: number; @@ -30,7 +30,7 @@ interface SvgExportOptions { // https://github.com/jgraph/drawio/blob/v14.7.7/src/main/webapp/js/diagramly/Editor.js#L5932 // https://github.com/jgraph/drawio/blob/v14.8.0/src/main/webapp/js/grapheditor/Graph.js#L9007 export class SvgExporter { - constructor(private graph: mxGraph) {} + constructor(private graph: Graph) {} exportSvg(): string { return this.doSvgExport(true); @@ -40,13 +40,16 @@ export class SvgExporter { // chrome and webkit: tainted canvas when svg contains foreignObject // also on brave --> probably fail on chromium based browsers // so disable foreign objects for such browsers - const isFirefox = mxClient.IS_FF; + const isFirefox = Client.IS_FF; return this.doSvgExport(isFirefox); } private doSvgExport(enableForeignObjectForLabel: boolean): string { const svgDocument = this.computeSvg({ scale: 1, border: 25, enableForeignObjectForLabel: enableForeignObjectForLabel }); - const svgAsString = mxUtils.getXml(svgDocument); + // TODO maxgraph@0.1.0 migration - fix type + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const svgAsString = xmlUtils.getXml(svgDocument); return ` ${svgAsString} @@ -63,8 +66,8 @@ ${svgAsString} const viewScale = this.graph.view.scale; // Prepares SVG document that holds the output - const svgDoc = mxUtils.createXmlDocument(); - const root = svgDoc.createElementNS(mxConstants.NS_SVG, 'svg'); + const svgDoc = xmlUtils.createXmlDocument(); + const root = svgDoc.createElementNS(constants.NS_SVG, 'svg'); const s = scale / viewScale; const w = Math.max(1, Math.ceil(bounds.width * s) + 2 * border); @@ -76,7 +79,7 @@ ${svgAsString} root.setAttribute('viewBox', (crisp ? '-0.5 -0.5' : '0 0') + ' ' + w + ' ' + h); svgDoc.appendChild(root); - const group = svgDoc.createElementNS(mxConstants.NS_SVG, 'g'); + const group = svgDoc.createElementNS(constants.NS_SVG, 'g'); root.appendChild(group); const svgCanvas = this.createSvgCanvas(group); @@ -91,7 +94,7 @@ ${svgAsString} svgCanvas.scale(s); - const imgExport = new mxgraph.mxImageExport(); + const imgExport = new ImageExport(); // FIXME only the first overlay is placed at the right position // overlays put on element of subprocess/call-activity are not placed correctly in svg export imgExport.includeOverlays = true; @@ -100,41 +103,37 @@ ${svgAsString} return svgDoc; } - createSvgCanvas(node: Element): mxSvgCanvas2DType { - const canvas = new CanvasForExport(node); + createSvgCanvas(node: SVGElement): SvgCanvas2D { + const canvas = new CanvasForExport(node, true); // from the draw.io code, may not be needed here canvas.pointerEvents = true; return canvas; } } -class CanvasForExport extends mxSvgCanvas2D { +class CanvasForExport extends SvgCanvas2D { // Convert HTML entities private htmlConverter = document.createElement('div'); - constructor(node: Element) { - super(node); - } - override getAlternateText( - fo: Element, + fo: SVGForeignObjectElement, x: number, y: number, w: number, h: number, - str: string, + str: Element | string, // eslint-disable-next-line @typescript-eslint/no-unused-vars - align: string, + align: AlignValue, // eslint-disable-next-line @typescript-eslint/no-unused-vars - valign: string, + valign: VAlignValue, // eslint-disable-next-line @typescript-eslint/no-unused-vars - wrap: string, + wrap: boolean, // eslint-disable-next-line @typescript-eslint/no-unused-vars format: string, // eslint-disable-next-line @typescript-eslint/no-unused-vars - overflow: string, + overflow: OverflowValue, // eslint-disable-next-line @typescript-eslint/no-unused-vars - clip: string, + clip: boolean, // eslint-disable-next-line @typescript-eslint/no-unused-vars rotation: number, ): string { @@ -147,27 +146,34 @@ class CanvasForExport extends mxSvgCanvas2D { w: number, h: number, str: string, - align: string, - valign: string, - wrap: string, - overflow: string, - clip: string, + align: AlignValue, + valign: VAlignValue, + wrap: boolean, + overflow: OverflowValue, + clip: boolean, rotation: number, - dir: string, + dir: TextDirectionValue, ): void { str = this.computeTruncatedText(str, w); super.plainText(x, y, w, h, str, align, valign, wrap, overflow, clip, rotation, dir); } - private computeTruncatedText(str: string, w: number): string { + private computeTruncatedText(str: Element | string, w: number): string { // Assumes a max character width of 0.5em if (str == null || this.state.fontSize <= 0) { return ''; } + // TODO maxgraph@0.1.0 migration - manage str when it is an Element (see maxGraph code) + if (str instanceof Element) { + str = str.innerHTML; + } try { this.htmlConverter.innerHTML = str; - str = mxUtils.extractTextWithWhitespace(this.htmlConverter.childNodes); + // TODO maxgraph@0.1.0 migration - fix type + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + str = domUtils.extractTextWithWhitespace(this.htmlConverter.childNodes); // Workaround for substring breaking double byte UTF const exp = Math.ceil((2 * w) / this.state.fontSize); @@ -192,7 +198,7 @@ class CanvasForExport extends mxSvgCanvas2D { // Uses result and adds ellipsis if more than 1 char remains if (result.length < str.length && str.length - result.length > 1) { - str = mxUtils.trim(result.join('')) + '...'; + str = stringUtils.trim(result.join('')) + '...'; } } catch (e) { console.warn('Error while computing txt label', e); diff --git a/dev/ts/component/ThemedBpmnVisualization.ts b/dev/ts/component/ThemedBpmnVisualization.ts index be2fbb743a..63135ef3f3 100644 --- a/dev/ts/component/ThemedBpmnVisualization.ts +++ b/dev/ts/component/ThemedBpmnVisualization.ts @@ -16,7 +16,6 @@ limitations under the License. import { BpmnVisualization, FlowKind, ShapeBpmnElementKind, ShapeUtil, StyleConfigurator, StyleDefault } from '../../../src/bpmn-visualization'; import { logStartup } from '../utils/internal-helpers'; -import { mxConstants } from '../../../src/component/mxgraph/initializer'; interface Theme { defaultFillColor: string; @@ -139,44 +138,44 @@ export class ThemedBpmnVisualization extends BpmnVisualization { strokeColor = theme.defaultStrokeColor; break; } - const style = styleSheet.styles[kind]; - style['fillColor'] = fillColor; - style['strokeColor'] = strokeColor; + const style = styleSheet.styles.get(kind); + style.fillColor = fillColor; + style.strokeColor = strokeColor; }); // TASK ShapeUtil.taskKinds().forEach(kind => { - const style = styleSheet.styles[kind]; - style['fillColor'] = theme.taskAndCallActivityFillColor; + const style = styleSheet.styles.get(kind); + style.fillColor = theme.taskAndCallActivityFillColor; }); // CALL ACTIVITY - const callActivityStyle = styleSheet.styles[ShapeBpmnElementKind.CALL_ACTIVITY]; - callActivityStyle['fillColor'] = theme.taskAndCallActivityFillColor; + const callActivityStyle = styleSheet.styles.get(ShapeBpmnElementKind.CALL_ACTIVITY); + callActivityStyle.fillColor = theme.taskAndCallActivityFillColor; // TEXT ANNOTATION - const textAnnotationStyle = styleSheet.styles[ShapeBpmnElementKind.TEXT_ANNOTATION]; - textAnnotationStyle['fillColor'] = theme.textAnnotationFillColor ?? StyleDefault.TEXT_ANNOTATION_FILL_COLOR; + const textAnnotationStyle = styleSheet.styles.get(ShapeBpmnElementKind.TEXT_ANNOTATION); + textAnnotationStyle.fillColor = theme.textAnnotationFillColor ?? StyleDefault.TEXT_ANNOTATION_FILL_COLOR; // POOL - const poolStyle = styleSheet.styles[ShapeBpmnElementKind.POOL]; - poolStyle['fillColor'] = theme.poolFillColor; - poolStyle['swimlaneFillColor'] = theme.defaultFillColor; + const poolStyle = styleSheet.styles.get(ShapeBpmnElementKind.POOL); + poolStyle.fillColor = theme.poolFillColor; + poolStyle.swimlaneFillColor = theme.defaultFillColor; // LANE - const laneStyle = styleSheet.styles[ShapeBpmnElementKind.LANE]; - laneStyle['fillColor'] = theme.laneFillColor; + const laneStyle = styleSheet.styles.get(ShapeBpmnElementKind.LANE); + laneStyle.fillColor = theme.laneFillColor; // DEFAULTS const defaultVertexStyle = styleSheet.getDefaultVertexStyle(); - defaultVertexStyle['fontColor'] = theme.defaultFontColor; - defaultVertexStyle['fillColor'] = theme.defaultFillColor; - defaultVertexStyle['strokeColor'] = theme.defaultStrokeColor; + defaultVertexStyle.fontColor = theme.defaultFontColor; + defaultVertexStyle.fillColor = theme.defaultFillColor; + defaultVertexStyle.strokeColor = theme.defaultStrokeColor; const defaultEdgeStyle = styleSheet.getDefaultEdgeStyle(); - defaultEdgeStyle['fontColor'] = theme.defaultFontColor; - defaultEdgeStyle['fillColor'] = theme.defaultFillColor; - defaultEdgeStyle['strokeColor'] = theme.flowColor ?? theme.defaultStrokeColor; + defaultEdgeStyle.fontColor = theme.defaultFontColor; + defaultEdgeStyle.fillColor = theme.defaultFillColor; + defaultEdgeStyle.strokeColor = theme.flowColor ?? theme.defaultStrokeColor; // theme configuration completed return true; @@ -187,10 +186,10 @@ export class ThemedBpmnVisualization extends BpmnVisualization { const stylesheet = this.graph.getStylesheet(); - // directly access the 'styles' map to update values. Using stylesheet.getCellStyle returns a copy of the style - const seqFlowStyle = stylesheet.styles[FlowKind.SEQUENCE_FLOW]; - seqFlowStyle[mxConstants.STYLE_STROKECOLOR] = color; - seqFlowStyle[mxConstants.STYLE_FILLCOLOR] = color; + // directly access the 'styles' map to update values. Using stylesheet.getBPMNCellStyle returns a copy of the style + const seqFlowStyle = stylesheet.styles.get(FlowKind.SEQUENCE_FLOW); + seqFlowStyle.strokeColor = color; + seqFlowStyle.fillColor = color; logStartup('Sequence flows style updated'); } diff --git a/dev/ts/main.ts b/dev/ts/main.ts index 5f8bbb9d67..4277abf00b 100644 --- a/dev/ts/main.ts +++ b/dev/ts/main.ts @@ -128,7 +128,7 @@ function collapseBpmnElement(bpmnElementId: string): void { return; } log('Updating model, bpmnElement to collapse:', bpmnElementId); - const model = bpmnVisualization.graph.getModel(); + const model = bpmnVisualization.graph.model; const cell = model.getCell(bpmnElementId); if (!cell) { log('Element not found in the model, do nothing'); diff --git a/package.json b/package.json index f61d570fc8..780e640fde 100644 --- a/package.json +++ b/package.json @@ -93,10 +93,9 @@ "utils:test:model": "node ./scripts/utils/dist/utils.mjs test/fixtures/bpmn/simple-start-task-end.bpmn --output model" }, "dependencies": { - "@typed-mxgraph/typed-mxgraph": "~1.0.8", + "@maxgraph/core": "0.1.0", "fast-xml-parser": "4.2.5", "lodash-es": "~4.17.21", - "mxgraph": "4.2.2", "strnum": "1.0.5" }, "devDependencies": { diff --git a/src/bpmn-visualization.ts b/src/bpmn-visualization.ts index e33c24abdc..8ca11a0a47 100644 --- a/src/bpmn-visualization.ts +++ b/src/bpmn-visualization.ts @@ -14,9 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Use mxgraph types -/// - // Public API export * from './component/options'; export { BpmnVisualization } from './component/BpmnVisualization'; @@ -30,6 +27,3 @@ export { IconPainter } from './component/mxgraph/shape/render/icon-painter'; export { StyleConfigurator } from './component/mxgraph/config/StyleConfigurator'; export * from './component/mxgraph/style'; export * from './component/mxgraph/shape/render'; - -// the mxGraph context -export { mxgraph } from './component/mxgraph/initializer'; diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index 52d0b443a8..f003a359e7 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -18,13 +18,13 @@ import type { FitOptions, ZoomConfiguration } from '../options'; import { FitType } from '../options'; import { ensurePositiveValue, ensureValidZoomConfiguration } from '../helpers/validators'; import { debounce, throttle } from 'lodash-es'; -import { mxgraph, mxEvent } from './initializer'; -import type { mxCellState, mxGraphView, mxPoint } from 'mxgraph'; +import type { CellState, CellStateStyle, CellStyle, Point } from '@maxgraph/core'; +import { eventUtils, Graph, GraphView, InternalEvent, Stylesheet } from '@maxgraph/core'; const zoomFactorIn = 1.25; const zoomFactorOut = 1 / zoomFactorIn; -export class BpmnGraph extends mxgraph.mxGraph { +export class BpmnGraph extends Graph { private currentZoomLevel = 1; /** @@ -42,7 +42,7 @@ export class BpmnGraph extends mxgraph.mxGraph { /** * @internal */ - override createGraphView(): mxGraphView { + override createGraphView(): GraphView { return new BpmnGraphView(this); } @@ -83,28 +83,28 @@ export class BpmnGraph extends mxgraph.mxGraph { * Overridden to manage `currentZoomLevel` * @internal */ - override zoomActual(): void { + override zoomActual = (): void => { super.zoomActual(); this.setCurrentZoomLevel(); - } + }; /** * Overridden to manage `currentZoomLevel` * @internal */ - override zoomIn(): void { + override zoomIn = (): void => { super.zoomIn(); this.setCurrentZoomLevel(); - } + }; /** * Overridden to manage `currentZoomLevel` * @internal */ - override zoomOut(): void { + override zoomOut = (): void => { super.zoomOut(); this.setCurrentZoomLevel(); - } + }; /** * @internal @@ -142,24 +142,31 @@ export class BpmnGraph extends mxgraph.mxGraph { const clientHeight = this.container.clientHeight - margin; const width = bounds.width / this.view.scale; const height = bounds.height / this.view.scale; - const scale = Math.min(maxScale, Math.min(clientWidth / width, clientHeight / height)); + let scale = Math.min(maxScale, Math.min(clientWidth / width, clientHeight / height)); this.setCurrentZoomLevel(scale); + // TODO magraph@0.1.0 improve implementation (the following is to make integration tests pass) + scale == 0 && (scale = 1); this.view.scaleAndTranslate( scale, - (margin + clientWidth - width * scale) / (2 * scale) - bounds.x / this.view.scale, - (margin + clientHeight - height * scale) / (2 * scale) - bounds.y / this.view.scale, + this.NaNToZero((margin + clientWidth - width * scale) / (2 * scale) - bounds.x / this.view.scale), + this.NaNToZero((margin + clientHeight - height * scale) / (2 * scale) - bounds.y / this.view.scale), ); } } + // TODO magraph@0.1.0 move somewhere else + find a better name + should be a util function + private NaNToZero(value: number): number { + return Number.isNaN(value) ? 0 : value; + } + /** * @internal */ registerMouseWheelZoomListeners(config: ZoomConfiguration): void { config = ensureValidZoomConfiguration(config); - mxEvent.addMouseWheelListener(debounce(this.createMouseWheelZoomListener(true), config.debounceDelay), this.container); - mxEvent.addMouseWheelListener(throttle(this.createMouseWheelZoomListener(false), config.throttleDelay), this.container); + InternalEvent.addMouseWheelListener(debounce(this.createMouseWheelZoomListener(true), config.debounceDelay), this.container); + InternalEvent.addMouseWheelListener(throttle(this.createMouseWheelZoomListener(false), config.throttleDelay), this.container); } // Update the currentZoomLevel when performScaling is false, use the currentZoomLevel to set the scale otherwise @@ -171,20 +178,20 @@ export class BpmnGraph extends mxgraph.mxGraph { const [offsetX, offsetY] = this.getEventRelativeCoordinates(evt); const [newScale, dx, dy] = this.getScaleAndTranslationDeltas(offsetX, offsetY); this.view.scaleAndTranslate(newScale, this.view.translate.x + dx, this.view.translate.y + dy); - mxEvent.consume(evt); + InternalEvent.consume(evt); } } private createMouseWheelZoomListener(performScaling: boolean) { return (event: Event, up: boolean) => { - if (mxEvent.isConsumed(event)) { + if (!(event instanceof MouseEvent) || eventUtils.isConsumed(event)) { return; } - const evt = event as MouseEvent; + // only the ctrl key - const isZoomWheelEvent = evt.ctrlKey && !evt.altKey && !evt.shiftKey && !evt.metaKey; + const isZoomWheelEvent = event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey; if (isZoomWheelEvent) { - this.manageMouseWheelZoomEvent(up, evt, performScaling); + this.manageMouseWheelZoomEvent(up, event, performScaling); } }; } @@ -222,10 +229,15 @@ export class BpmnGraph extends mxgraph.mxGraph { const factor = scale / this.view.scale; return [factor, scale]; } + + // TODO magraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) + override createStylesheet(): Stylesheet { + return new BpmnStylesheet(); + } } -class BpmnGraphView extends mxgraph.mxGraphView { - override getFloatingTerminalPoint(edge: mxCellState, start: mxCellState, end: mxCellState, source: boolean): mxPoint { +class BpmnGraphView extends GraphView { + override getFloatingTerminalPoint(edge: CellState, start: CellState, end: CellState, source: boolean): Point { // some values may be null: the first and the last values are null prior computing floating terminal points const edgePoints = edge.absolutePoints.filter(Boolean); // when there is no BPMN waypoint, all values are null @@ -237,3 +249,39 @@ class BpmnGraphView extends mxgraph.mxGraphView { return source ? pts[1] : pts[pts.length - 2]; } } + +// TODO magraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) +class BpmnStylesheet extends Stylesheet { + override getCellStyle(cellStyle: CellStyle, defaultStyle: CellStateStyle): CellStateStyle { + let style: CellStateStyle; + + if (cellStyle.baseStyleNames && cellStyle.baseStyleNames.length > 0) { + // creates style with the given baseStyleNames. (merges from left to right) + style = cellStyle.baseStyleNames.reduce( + (acc, styleName) => { + return (acc = { + ...acc, + ...this.styles.get(styleName), + }); + }, + // here is the change + // {}, + { ...defaultStyle }, + // END of here is the change + ); + } else if (cellStyle.baseStyleNames && cellStyle.baseStyleNames.length === 0) { + // baseStyleNames is explicitly an empty array, so don't use any default styles. + style = {}; + } else { + style = { ...defaultStyle }; + } + + // Merges cellStyle into style + style = { + ...style, + ...cellStyle, + }; + + return style; + } +} diff --git a/src/component/mxgraph/BpmnRenderer.ts b/src/component/mxgraph/BpmnRenderer.ts index 76f1dfbe4a..bcfb2af69d 100644 --- a/src/component/mxgraph/BpmnRenderer.ts +++ b/src/component/mxgraph/BpmnRenderer.ts @@ -13,6 +13,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +import type { Cell } from '@maxgraph/core'; +import { Point } from '@maxgraph/core'; import type { Edge, Waypoint } from '../../model/bpmn/internal/edge/edge'; import { MessageFlow } from '../../model/bpmn/internal/edge/flows'; @@ -21,12 +23,11 @@ import type ShapeBpmnElement from '../../model/bpmn/internal/shape/ShapeBpmnElem import type Bounds from '../../model/bpmn/internal/Bounds'; import { MessageVisibleKind, ShapeUtil } from '../../model/bpmn/internal'; import CoordinatesTranslator from './renderer/CoordinatesTranslator'; +import type { BPMNCellStyle } from './renderer/StyleComputer'; import StyleComputer from './renderer/StyleComputer'; import type { BpmnGraph } from './BpmnGraph'; import type { FitOptions, RendererOptions } from '../options'; import type { RenderedModel } from '../registry/bpmn-model-registry'; -import { mxPoint } from './initializer'; -import type { mxCell } from 'mxgraph'; /** * @internal @@ -40,8 +41,11 @@ export class BpmnRenderer { } private insertShapesAndEdges({ pools, lanes, subprocesses, otherFlowNodes, boundaryEvents, edges }: RenderedModel): void { - this.graph.batchUpdate(() => { - this.graph.getModel().clear(); // ensure to remove manual changes or already loaded graphs + // TODO rebase use this.graph.batchUpdate + const model = this.graph.model; + model.clear(); // ensure to remove manual changes or already loaded graphs + model.beginUpdate(); + try { this.insertShapes(pools); this.insertShapes(lanes); this.insertShapes(subprocesses); @@ -50,14 +54,16 @@ export class BpmnRenderer { this.insertShapes(boundaryEvents); // at last as edge source and target must be present in the model prior insertion, otherwise they are not rendered this.insertEdges(edges); - }); + } finally { + model.endUpdate(); + } } private insertShapes(shapes: Shape[]): void { shapes.forEach(shape => this.insertShape(shape)); } - private getParent(bpmnElement: ShapeBpmnElement): mxCell { + private getParent(bpmnElement: ShapeBpmnElement): Cell { const bpmnElementParent = this.getCell(bpmnElement.parentId); return bpmnElementParent ?? this.graph.getDefaultParent(); } @@ -93,10 +99,10 @@ export class BpmnRenderer { if (edgeCenterCoordinate) { mxEdge.geometry.relative = false; - const labelBoundsRelativeCoordinateFromParent = this.coordinatesTranslator.computeRelativeCoordinates(mxEdge.parent, new mxPoint(labelBounds.x, labelBounds.y)); + const labelBoundsRelativeCoordinateFromParent = this.coordinatesTranslator.computeRelativeCoordinates(mxEdge.parent, new Point(labelBounds.x, labelBounds.y)); const relativeLabelX = labelBoundsRelativeCoordinateFromParent.x + labelBounds.width / 2 - edgeCenterCoordinate.x; const relativeLabelY = labelBoundsRelativeCoordinateFromParent.y - edgeCenterCoordinate.y; - mxEdge.geometry.offset = new mxPoint(relativeLabelX, relativeLabelY); + mxEdge.geometry.offset = new Point(relativeLabelX, relativeLabelY); } } @@ -104,33 +110,33 @@ export class BpmnRenderer { }); } - private insertMessageFlowIconIfNeeded(edge: Edge, mxEdge: mxCell): void { + private insertMessageFlowIconIfNeeded(edge: Edge, mxEdge: Cell): void { if (edge.bpmnElement instanceof MessageFlow && edge.messageVisibleKind !== MessageVisibleKind.NONE) { const cell = this.graph.insertVertex(mxEdge, messageFlowIconId(mxEdge.id), undefined, 0, 0, 20, 14, this.styleComputer.computeMessageFlowIconStyle(edge)); cell.geometry.relative = true; - cell.geometry.offset = new mxPoint(-10, -7); + cell.geometry.offset = new Point(-10, -7); } } - private insertWaypoints(waypoints: Waypoint[], mxEdge: mxCell): void { + private insertWaypoints(waypoints: Waypoint[], mxEdge: Cell): void { if (waypoints) { - mxEdge.geometry.points = waypoints.map(waypoint => this.coordinatesTranslator.computeRelativeCoordinates(mxEdge.parent, new mxPoint(waypoint.x, waypoint.y))); + mxEdge.geometry.points = waypoints.map(waypoint => this.coordinatesTranslator.computeRelativeCoordinates(mxEdge.parent, new Point(waypoint.x, waypoint.y))); } } - private getCell(id: string): mxCell { - return this.graph.getModel().getCell(id); + private getCell(id: string): Cell { + return this.graph.model.getCell(id); } - private insertVertex(parent: mxCell, id: string | null, value: string, bounds: Bounds, labelBounds: Bounds, style?: string): mxCell { - const vertexCoordinates = this.coordinatesTranslator.computeRelativeCoordinates(parent, new mxPoint(bounds.x, bounds.y)); + private insertVertex(parent: Cell, id: string | null, value: string, bounds: Bounds, labelBounds: Bounds, style?: BPMNCellStyle): Cell { + const vertexCoordinates = this.coordinatesTranslator.computeRelativeCoordinates(parent, new Point(bounds.x, bounds.y)); const cell = this.graph.insertVertex(parent, id, value, vertexCoordinates.x, vertexCoordinates.y, bounds.width, bounds.height, style); if (labelBounds) { // label coordinates are relative in the cell referential coordinates const relativeLabelX = labelBounds.x - bounds.x; const relativeLabelY = labelBounds.y - bounds.y; - cell.geometry.offset = new mxPoint(relativeLabelX, relativeLabelY); + cell.geometry.offset = new Point(relativeLabelX, relativeLabelY); } return cell; } diff --git a/src/component/mxgraph/GraphCellUpdater.ts b/src/component/mxgraph/GraphCellUpdater.ts index 77e9e4e3d9..1d125547cc 100644 --- a/src/component/mxgraph/GraphCellUpdater.ts +++ b/src/component/mxgraph/GraphCellUpdater.ts @@ -18,8 +18,6 @@ import { isShapeStyleUpdate, setStyle, updateFill, updateFont, updateStroke } fr import { StyleManager } from './style/StyleManager'; import type { BpmnGraph } from './BpmnGraph'; -import { mxConstants } from './initializer'; -import { BpmnStyleIdentifier } from './style'; import type { Overlay, StyleUpdate } from '../registry'; import type { CssRegistry } from '../registry/css-registry'; import { MxGraphCustomOverlay } from './overlay/custom-overlay'; @@ -27,6 +25,7 @@ import { ensureIsArray } from '../helpers/array-utils'; import { OverlayConverter } from './overlay/OverlayConverter'; import { messageFlowIconId } from './BpmnRenderer'; import { ensureOpacityValue } from '../helpers/validators'; +import type { BPMNCellStyle } from './renderer/StyleComputer'; /** * @internal @@ -52,7 +51,7 @@ export default class GraphCellUpdater { } private updateAndRefreshCssClassesOfElement(elementId: string, cssClasses: string[]): void { - const model = this.graph.getModel(); + const model = this.graph.model; const cell = model.getCell(elementId); if (!cell) { return; @@ -61,12 +60,17 @@ export default class GraphCellUpdater { this.styleManager.ensureStyleIsStored(cell); let cellStyle = cell.getStyle(); + // TODO rebase adapt code for maxgraph cellStyle = setStyle(cellStyle, BpmnStyleIdentifier.EXTRA_CSS_CLASSES, cssClasses.join(',')); model.setStyle(cell, cellStyle); + // TODO magraph@0.1.0 improve logic + // const style = state.style as BPMNCellStyle; + // !style.bpmn.extra && (style.bpmn.extra = { css: { classes: undefined } }); + // style.bpmn.extra.css.classes = cssClasses; } addOverlays(bpmnElementId: string, overlays: Overlay | Overlay[]): void { - const cell = this.graph.getModel().getCell(bpmnElementId); + const cell = this.graph.model.getCell(bpmnElementId); if (!cell) { return; } @@ -77,7 +81,7 @@ export default class GraphCellUpdater { } removeAllOverlays(bpmnElementId: string): void { - const cell = this.graph.getModel().getCell(bpmnElementId); + const cell = this.graph.model.getCell(bpmnElementId); if (!cell) { return; } diff --git a/src/component/mxgraph/GraphConfigurator.ts b/src/component/mxgraph/GraphConfigurator.ts index 7f50f19f08..cdaa3d3e99 100644 --- a/src/component/mxgraph/GraphConfigurator.ts +++ b/src/component/mxgraph/GraphConfigurator.ts @@ -19,8 +19,8 @@ import ShapeConfigurator from './config/ShapeConfigurator'; import MarkerConfigurator from './config/MarkerConfigurator'; import type { GlobalOptions } from '../options'; import { BpmnGraph } from './BpmnGraph'; -import { mxEvent } from './initializer'; -import type { mxMouseEvent } from 'mxgraph'; +import type { InternalMouseEvent, PanningHandler } from '@maxgraph/core'; +import { eventUtils, InternalEvent } from '@maxgraph/core'; /** * Configure the BpmnMxGraph graph that can be used by the lib @@ -63,16 +63,19 @@ export default class GraphConfigurator { } private configureNavigationSupport(options: GlobalOptions): void { - const panningHandler = this.graph.panningHandler; + // TODO magraph@0.1.0 decide if we hide this maxGraph implementation details in BpmnGraph + // In theory, the panningHandler may not be available if its plugin is not registered. The maxGraph code sometimes check for availability. For now, the check is not needed as we know that we load it + const panningHandler = this.graph.getPlugin('PanningHandler'); + if (options?.navigation?.enabled) { // Pan configuration - panningHandler.addListener(mxEvent.PAN_START, this.getPanningHandler('grab')); - panningHandler.addListener(mxEvent.PAN_END, this.getPanningHandler('default')); + panningHandler.addListener(InternalEvent.PAN_START, this.getPanningHandler('grab')); + panningHandler.addListener(InternalEvent.PAN_END, this.getPanningHandler('default')); panningHandler.usePopupTrigger = false; // only use the left button to trigger panning // Reimplement the function as we also want to trigger 'panning on cells' (ignoreCell to true) and only on left-click // The mxGraph standard implementation doesn't ignore right click in this case, so do it by ourselves - panningHandler.isForcePanningEvent = (me): boolean => mxEvent.isLeftMouseButton(me.getEvent()) || mxEvent.isMultiTouchEvent(me.getEvent()); + panningHandler.isForcePanningEvent = (me: InternalMouseEvent): boolean => eventUtils.isLeftMouseButton(me.getEvent()) || eventUtils.isMultiTouchEvent(me.getEvent()); this.graph.setPanning(true); // Zoom configuration @@ -83,7 +86,7 @@ export default class GraphConfigurator { panningHandler.setPinchEnabled(false); // Disable panning on touch device // eslint-disable-next-line @typescript-eslint/no-unused-vars -- prefix parameter name - common practice to acknowledge the fact that some parameter is unused (e.g. in TypeScript compiler) - panningHandler.isForcePanningEvent = (_me: mxMouseEvent): boolean => false; + panningHandler.isForcePanningEvent = (_me: InternalMouseEvent): boolean => false; } } diff --git a/src/component/mxgraph/config/MarkerConfigurator.ts b/src/component/mxgraph/config/MarkerConfigurator.ts index 5b7b50ac14..ddbe6a0de1 100644 --- a/src/component/mxgraph/config/MarkerConfigurator.ts +++ b/src/component/mxgraph/config/MarkerConfigurator.ts @@ -15,8 +15,8 @@ limitations under the License. */ import { MarkerIdentifier } from '../style'; -import { mxgraph } from '../initializer'; -import type { mxAbstractCanvas2D, mxCell, mxPoint, mxShape } from 'mxgraph'; +import type { Cell, Point, Shape, AbstractCanvas2D } from '@maxgraph/core'; +import { MarkerShape } from '@maxgraph/core'; /** * @internal @@ -32,14 +32,14 @@ export default class MarkerConfigurator { // prefix parameter name - common practice to acknowledge the fact that some parameter is unused (e.g. in TypeScript compiler) const createMarker = ( - c: mxAbstractCanvas2D, - _shape: mxShape, + c: AbstractCanvas2D, + _shape: Shape, _type: string, - pe: mxPoint, + pe: Point, unitX: number, unitY: number, size: number, - _source: mxCell, + _source: Cell, strokewidth: number, ): (() => void) => { const nx = unitX * (size + strokewidth + 4); @@ -52,6 +52,6 @@ export default class MarkerConfigurator { c.stroke(); }; }; - mxgraph.mxMarker.addMarker(MarkerIdentifier.ARROW_DASH, createMarker); + MarkerShape.addMarker(MarkerIdentifier.ARROW_DASH, createMarker); } } diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index fe481ddcef..ee3c5a83cf 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -14,8 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { mxgraph, mxCellRenderer, mxConstants, mxRectangle, mxSvgCanvas2D } from '../initializer'; -import type { mxCellState, mxImageShape, mxShape } from 'mxgraph'; +import type { CellState, CellOverlay } from '@maxgraph/core'; +import { CellRenderer, Shape, Rectangle, ImageShape, Dictionary, SvgCanvas2D, constants } from '@maxgraph/core'; + import { ShapeBpmnElementKind } from '../../../model/bpmn/internal'; import { EndEventShape, EventShape, IntermediateEventShape, ThrowIntermediateEventShape } from '../shape/event-shapes'; import { ComplexGatewayShape, EventBasedGatewayShape, ExclusiveGatewayShape, InclusiveGatewayShape, ParallelGatewayShape } from '../shape/gateway-shapes'; @@ -33,11 +34,12 @@ import { } from '../shape/activity-shapes'; import { TextAnnotationShape } from '../shape/text-annotation-shapes'; import { MessageFlowIconShape } from '../shape/flow-shapes'; -import { BpmnStyleIdentifier } from '../style'; +import { BpmnStyleIdentifier, FONT } from '../style'; import { computeAllBpmnClassNamesOfCell } from '../renderer/style-utils'; import { MxGraphCustomOverlay } from '../overlay/custom-overlay'; import { OverlayBadgeShape } from '../overlay/shapes'; import { BpmnConnector } from '../shape/edges'; +import type { BPMNCellStyle } from '../renderer/StyleComputer'; /** * @internal @@ -52,43 +54,59 @@ export default class ShapeConfigurator { private registerShapes(): void { // events - mxCellRenderer.registerShape(ShapeBpmnElementKind.EVENT_END, EndEventShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.EVENT_START, EventShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW, ThrowIntermediateEventShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, IntermediateEventShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.EVENT_BOUNDARY, IntermediateEventShape); + CellRenderer.registerShape(ShapeBpmnElementKind.EVENT_END, EndEventShape); + CellRenderer.registerShape(ShapeBpmnElementKind.EVENT_START, EventShape); + CellRenderer.registerShape(ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW, ThrowIntermediateEventShape); + CellRenderer.registerShape(ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, IntermediateEventShape); + CellRenderer.registerShape(ShapeBpmnElementKind.EVENT_BOUNDARY, IntermediateEventShape); // gateways - mxCellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_COMPLEX, ComplexGatewayShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_EVENT_BASED, EventBasedGatewayShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_EXCLUSIVE, ExclusiveGatewayShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_INCLUSIVE, InclusiveGatewayShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_PARALLEL, ParallelGatewayShape); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // @ts-ignore + CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_COMPLEX, ComplexGatewayShape); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // @ts-ignore + CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_EVENT_BASED, EventBasedGatewayShape); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // @ts-ignore + CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_EXCLUSIVE, ExclusiveGatewayShape); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // @ts-ignore + CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_INCLUSIVE, InclusiveGatewayShape); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // @ts-ignore + CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_PARALLEL, ParallelGatewayShape); // activities - mxCellRenderer.registerShape(ShapeBpmnElementKind.SUB_PROCESS, SubProcessShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.CALL_ACTIVITY, CallActivityShape); + CellRenderer.registerShape(ShapeBpmnElementKind.SUB_PROCESS, SubProcessShape); + CellRenderer.registerShape(ShapeBpmnElementKind.CALL_ACTIVITY, CallActivityShape); // tasks - mxCellRenderer.registerShape(ShapeBpmnElementKind.TASK, TaskShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.TASK_SERVICE, ServiceTaskShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.TASK_USER, UserTaskShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.TASK_RECEIVE, ReceiveTaskShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.TASK_SEND, SendTaskShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.TASK_MANUAL, ManualTaskShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.TASK_SCRIPT, ScriptTaskShape); - mxCellRenderer.registerShape(ShapeBpmnElementKind.TASK_BUSINESS_RULE, BusinessRuleTaskShape); + CellRenderer.registerShape(ShapeBpmnElementKind.TASK, TaskShape); + CellRenderer.registerShape(ShapeBpmnElementKind.TASK_SERVICE, ServiceTaskShape); + CellRenderer.registerShape(ShapeBpmnElementKind.TASK_USER, UserTaskShape); + CellRenderer.registerShape(ShapeBpmnElementKind.TASK_RECEIVE, ReceiveTaskShape); + CellRenderer.registerShape(ShapeBpmnElementKind.TASK_SEND, SendTaskShape); + CellRenderer.registerShape(ShapeBpmnElementKind.TASK_MANUAL, ManualTaskShape); + CellRenderer.registerShape(ShapeBpmnElementKind.TASK_SCRIPT, ScriptTaskShape); + CellRenderer.registerShape(ShapeBpmnElementKind.TASK_BUSINESS_RULE, BusinessRuleTaskShape); // artifacts - mxCellRenderer.registerShape(ShapeBpmnElementKind.TEXT_ANNOTATION, TextAnnotationShape); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // @ts-ignore + CellRenderer.registerShape(ShapeBpmnElementKind.TEXT_ANNOTATION, TextAnnotationShape); // shapes for flows - mxCellRenderer.registerShape(BpmnStyleIdentifier.EDGE, BpmnConnector); - mxCellRenderer.registerShape(BpmnStyleIdentifier.MESSAGE_FLOW_ICON, MessageFlowIconShape); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // @ts-ignore + CellRenderer.registerShape(BpmnStyleIdentifier.EDGE, BpmnConnector); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // @ts-ignore + CellRenderer.registerShape(BpmnStyleIdentifier.MESSAGE_FLOW_ICON, MessageFlowIconShape); } private initMxSvgCanvasPrototype(): void { // getTextCss is only used when creating foreignObject for label, so there is no impact on svg text that we use for Overlays. // Analysis done for mxgraph@4.1.1, still apply to mxgraph@4.2.2 - mxSvgCanvas2D.prototype.getTextCss = function () { + SvgCanvas2D.prototype.getTextCss = function () { const s = this.state; - const lh = mxConstants.ABSOLUTE_LINE_HEIGHT ? s.fontSize * mxConstants.LINE_HEIGHT + 'px' : mxConstants.LINE_HEIGHT * this.lineHeightCorrection; + const lh = constants.ABSOLUTE_LINE_HEIGHT ? s.fontSize * constants.LINE_HEIGHT + 'px' : constants.LINE_HEIGHT * this.lineHeightCorrection; let css = 'display: inline-block; font-size: ' + s.fontSize + @@ -107,18 +125,18 @@ export default class ShapeConfigurator { // END OF Fix for issue #920 '; '; - if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD) { + if ((s.fontStyle & FONT.BOLD) == FONT.BOLD) { css += 'font-weight: bold; '; } - if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC) { + if ((s.fontStyle & FONT.ITALIC) == FONT.ITALIC) { css += 'font-style: italic; '; } const deco = []; - if ((s.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE) { + if ((s.fontStyle & FONT.UNDERLINE) == FONT.UNDERLINE) { deco.push('underline'); } - if ((s.fontStyle & mxConstants.FONT_STRIKETHROUGH) == mxConstants.FONT_STRIKETHROUGH) { + if ((s.fontStyle & FONT.STRIKETHROUGH) == FONT.STRIKETHROUGH) { deco.push('line-through'); } if (deco.length > 0) { @@ -132,8 +150,8 @@ export default class ShapeConfigurator { private initMxShapePrototype(): void { // The following is copied from the mxgraph mxShape implementation then converted to TypeScript and enriched for bpmn-visualization // It is needed for adding the custom attributes that permits identification of the BPMN elements in the DOM - mxgraph.mxShape.prototype.createSvgCanvas = function () { - const canvas = new mxSvgCanvas2D(this.node, false); + Shape.prototype.createSvgCanvas = function () { + const canvas = new SvgCanvas2D(this.node, false); canvas.strokeTolerance = this.pointerEvents ? this.svgStrokeTolerance : 0; canvas.pointerEventsValue = this.svgPointerEvents; const off = this.getSvgScreenOffset(); @@ -150,9 +168,11 @@ export default class ShapeConfigurator { // 'this.state.style' = the style definition associated with the cell // 'this.state.cell.style' = the style applied to the cell: 1st element: style name = bpmn shape name const cell = this.state.cell; - // dialect = strictHtml is set means that current node holds an HTML label - let allBpmnClassNames = computeAllBpmnClassNamesOfCell(cell, this.dialect === mxConstants.DIALECT_STRICTHTML); - const extraCssClasses = this.state.style[BpmnStyleIdentifier.EXTRA_CSS_CLASSES]; + // dialect = strictHtml is set means that current node holds an html label + // TODO magraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided."constants.DIALECT.STRICTHTML + let allBpmnClassNames = computeAllBpmnClassNamesOfCell(cell, this.dialect === 'strictHtml'); + const extraCssClasses = (this.state.style as BPMNCellStyle).bpmn?.extra?.css?.classes; + // TODO rebase verify the cssClasses property type in BPMNCellStyle if (typeof extraCssClasses == 'string') { allBpmnClassNames = allBpmnClassNames.concat(extraCssClasses.split(',')); } @@ -165,8 +185,8 @@ export default class ShapeConfigurator { if (!this.antiAlias) { // Rounds all numbers in the SVG output to integers - canvas.format = function (value: string) { - return Math.round(parseFloat(value)); + canvas.format = (value: number): number => { + return Math.round(value); }; } @@ -175,13 +195,13 @@ export default class ShapeConfigurator { } initMxCellRendererCreateCellOverlays(): void { - mxCellRenderer.prototype.createCellOverlays = function (state: mxCellState) { + CellRenderer.prototype.createCellOverlays = function (state: CellState) { const graph = state.view.graph; const overlays = graph.getCellOverlays(state.cell); let dict = null; if (overlays != null) { - dict = new mxgraph.mxDictionary(); + dict = new Dictionary(); for (const currentOverlay of overlays) { const shape = state.overlays != null ? state.overlays.remove(currentOverlay) : null; @@ -190,14 +210,14 @@ export default class ShapeConfigurator { continue; } - let overlayShape: mxShape; + let overlayShape: Shape; // START bpmn-visualization CUSTOMIZATION if (currentOverlay instanceof MxGraphCustomOverlay) { - overlayShape = new OverlayBadgeShape(currentOverlay.label, new mxRectangle(0, 0, 0, 0), currentOverlay.style); + overlayShape = new OverlayBadgeShape(currentOverlay.label, new Rectangle(0, 0, 0, 0), currentOverlay.style); } else { - overlayShape = new mxgraph.mxImageShape(new mxRectangle(0, 0, 0, 0), currentOverlay.image.src); - (overlayShape).preserveImageAspect = false; + overlayShape = new ImageShape(new Rectangle(0, 0, 0, 0), currentOverlay.image.src); + (overlayShape).preserveImageAspect = false; } // END bpmn-visualization CUSTOMIZATION @@ -205,7 +225,7 @@ export default class ShapeConfigurator { overlayShape.overlay = currentOverlay; // The 'initializeOverlay' signature forces us to hardly cast the overlayShape - this.initializeOverlay(state, overlayShape); + this.initializeOverlay(state, overlayShape); this.installCellOverlayListeners(state, currentOverlay, overlayShape); if (currentOverlay.cursor != null) { @@ -226,7 +246,7 @@ export default class ShapeConfigurator { // Removes unused if (state.overlays != null) { // prefix parameter name - common practice to acknowledge the fact that some parameter is unused (e.g. in TypeScript compiler) - state.overlays.visit(function (_id: string, shape: mxShape) { + state.overlays.visit(function (_id: string, shape: Shape) { shape.destroy(); }); } diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 61f84aeb84..8e7d8a7a92 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -14,11 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ +import type { ArrowType, ShapeValue, Stylesheet } from '@maxgraph/core'; +import { constants, Perimeter } from '@maxgraph/core'; + import { AssociationDirectionKind, FlowKind, SequenceFlowKind, ShapeBpmnElementKind, ShapeUtil } from '../../../model/bpmn/internal'; import { BpmnStyleIdentifier, MarkerIdentifier, StyleDefault } from '../style'; import type { BpmnGraph } from '../BpmnGraph'; -import { mxConstants, mxPerimeter } from '../initializer'; -import type { mxStylesheet, StyleMap } from 'mxgraph'; +import type { BPMNCellStyle } from '../renderer/StyleComputer'; const arrowDefaultSize = 12; @@ -31,59 +33,77 @@ const arrowDefaultSize = 12; * @experimental */ export class StyleConfigurator { + // TODO magraph@0.1.0 in StyleConfigurator, we don't need to use BPMNCellStyle, CellStyle is enough + private specificFlowStyles = new MapWithDefault([ [ FlowKind.SEQUENCE_FLOW, - (style: StyleMap) => { - style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_BLOCK_THIN; + (style: BPMNCellStyle) => { + style.endArrow = 'blockThin'; }, ], [ FlowKind.MESSAGE_FLOW, - (style: StyleMap) => { - style[mxConstants.STYLE_DASHED] = true; - style[mxConstants.STYLE_DASH_PATTERN] = '8 5'; - style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_OVAL; - style[mxConstants.STYLE_STARTSIZE] = 8; - style[mxConstants.STYLE_STARTFILL] = true; - style[BpmnStyleIdentifier.EDGE_START_FILL_COLOR] = StyleDefault.MESSAGE_FLOW_MARKER_START_FILL_COLOR; - style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_BLOCK_THIN; - style[mxConstants.STYLE_ENDFILL] = true; - style[BpmnStyleIdentifier.EDGE_END_FILL_COLOR] = StyleDefault.MESSAGE_FLOW_MARKER_END_FILL_COLOR; + (style: BPMNCellStyle) => { + style.dashed = true; + style.dashPattern = '8 5'; + style.startArrow = 'oval'; + style.startSize = 8; + style.startFill = true; + style.bpmn.edge.startFillColor = StyleDefault.MESSAGE_FLOW_MARKER_START_FILL_COLOR; + style.endArrow = 'blockThin'; + style.endFill = true; + style.bpmn.edge.endFillColor = StyleDefault.MESSAGE_FLOW_MARKER_END_FILL_COLOR; }, ], [ FlowKind.ASSOCIATION_FLOW, - (style: StyleMap) => { - style[mxConstants.STYLE_DASHED] = true; - style[mxConstants.STYLE_DASH_PATTERN] = '1 2'; - // STYLE_ENDARROW and STYLE_STARTARROW are defined in specific AssociationDirectionKind styles when needed - style[mxConstants.STYLE_STARTSIZE] = arrowDefaultSize; + (style: BPMNCellStyle) => { + style.dashed = true; + style.dashPattern = '1 2'; + // TODO maxgraph@0.1.0 migration - update comment // STYLE_ENDARROW and STYLE_STARTARROW are defined in specific AssociationDirectionKind styles when needed + // style.endArrow = 'openThin'; + // style.startArrow = 'openThin'; + style.startSize = 12; }, ], ]); private specificSequenceFlowStyles = new MapWithDefault([ [ SequenceFlowKind.DEFAULT, - (style: StyleMap) => { - style[mxConstants.STYLE_STARTARROW] = MarkerIdentifier.ARROW_DASH; + (style: BPMNCellStyle) => { + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + style.startArrow = MarkerIdentifier.ARROW_DASH; }, ], [ SequenceFlowKind.CONDITIONAL_FROM_ACTIVITY, - (style: StyleMap) => { - style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_DIAMOND_THIN; - style[mxConstants.STYLE_STARTSIZE] = 18; - style[mxConstants.STYLE_STARTFILL] = true; - style[BpmnStyleIdentifier.EDGE_START_FILL_COLOR] = StyleDefault.SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR; + (style: BPMNCellStyle) => { + style.startArrow = 'diamondThin'; + style.startSize = 18; + style.startFill = true; + style.bpmn.edge.startFillColor = StyleDefault.SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR; }, ], ]); private specificAssociationFlowStyles = new MapWithDefault([ [ AssociationDirectionKind.NONE, + (style: BPMNCellStyle) => { + style.startArrow = undefined; + style.endArrow = undefined; + }, + ], + [ + AssociationDirectionKind.ONE, + (style: BPMNCellStyle) => { + style.startArrow = undefined; + }, + ], + [ + AssociationDirectionKind.BOTH, // eslint-disable-next-line @typescript-eslint/no-unused-vars -- prefix parameter name - common practice to acknowledge the fact that some parameter is unused (e.g. in TypeScript compiler) - (_style: StyleMap) => { + (_style: BPMNCellStyle) => { // the style is fully managed by the FlowKind.ASSOCIATION_FLOW style }, ], @@ -121,130 +141,172 @@ export class StyleConfigurator { this.configureFlowStyles(); } - private getStylesheet(): mxStylesheet { + private getStylesheet(): Stylesheet { return this.graph.getStylesheet(); } - private putCellStyle(name: ShapeBpmnElementKind, style: StyleMap): void { + private putCellStyle(name: ShapeBpmnElementKind, style: BPMNCellStyle): void { this.getStylesheet().putCellStyle(name, style); } private configureDefaultVertexStyle(): void { - const style = this.getStylesheet().getDefaultVertexStyle(); - configureCommonDefaultStyle(style); - - style[mxConstants.STYLE_ABSOLUTE_ARCSIZE] = true; - style[mxConstants.STYLE_ARCSIZE] = StyleDefault.SHAPE_ARC_SIZE; + StyleConfigurator.configureCommonDefaultStyle(this.getStylesheet().getDefaultVertexStyle() as BPMNCellStyle); } private configurePoolStyle(): void { - const style: StyleMap = {}; - style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_SWIMLANE; - - // label style - style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE; - style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER; - style[mxConstants.STYLE_STARTSIZE] = StyleDefault.POOL_LABEL_SIZE; - style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.POOL_LABEL_FILL_COLOR; + const style: BPMNCellStyle = { + // TODO magraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE + shape: 'swimlane', + // label style + verticalAlign: 'middle', + align: 'center', + // TODO magraph@0.1.0 find a way to not force cast + startSize: StyleDefault.POOL_LABEL_SIZE, + // TODO magraph@0.1.0 find a way to not force cast + fillColor: StyleDefault.POOL_LABEL_FILL_COLOR, + }; this.graph.getStylesheet().putCellStyle(ShapeBpmnElementKind.POOL, style); } private configureLaneStyle(): void { - const style: StyleMap = {}; - style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_SWIMLANE; - - // label style - style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE; - style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER; - style[mxConstants.STYLE_SWIMLANE_LINE] = 0; // hide the line between the title region and the content area - style[mxConstants.STYLE_STARTSIZE] = StyleDefault.LANE_LABEL_SIZE; - style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.LANE_LABEL_FILL_COLOR; + const style: BPMNCellStyle = { + // TODO magraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE + shape: 'swimlane', + // label style + verticalAlign: 'middle', + align: 'center', + swimlaneLine: false, // hide the line between the title region and the content area + // TODO magraph@0.1.0 find a way to not force cast + startSize: StyleDefault.LANE_LABEL_SIZE, + // TODO magraph@0.1.0 find a way to not force cast + fillColor: StyleDefault.LANE_LABEL_FILL_COLOR, + }; this.graph.getStylesheet().putCellStyle(ShapeBpmnElementKind.LANE, style); } private configureEventStyles(): void { ShapeUtil.eventKinds().forEach(kind => { - const style: StyleMap = {}; - style[mxConstants.STYLE_SHAPE] = kind; - style[mxConstants.STYLE_PERIMETER] = mxPerimeter.EllipsePerimeter; - style[mxConstants.STYLE_STROKEWIDTH] = kind == ShapeBpmnElementKind.EVENT_END ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN; - style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = mxConstants.ALIGN_BOTTOM; + const style: BPMNCellStyle = { + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + shape: (kind), + perimeter: Perimeter.EllipsePerimeter, + // TODO magraph@0.1.0 find a way to not force cast + strokeWidth: (kind == ShapeBpmnElementKind.EVENT_END ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN), + verticalLabelPosition: 'bottom', + }; this.putCellStyle(kind, style); }); } private configureTextAnnotationStyle(): void { - const style: StyleMap = {}; - style[mxConstants.STYLE_SHAPE] = ShapeBpmnElementKind.TEXT_ANNOTATION; - style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE; - style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_LEFT; - style[mxConstants.STYLE_SPACING_LEFT] = 5; - style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.TEXT_ANNOTATION_FILL_COLOR; - style[mxConstants.STYLE_STROKEWIDTH] = StyleDefault.STROKE_WIDTH_THIN; + const style: BPMNCellStyle = { + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + shape: (ShapeBpmnElementKind.TEXT_ANNOTATION), + // label style + verticalAlign: 'middle', + align: 'left', + spacingLeft: 5, + // TODO magraph@0.1.0 find a way to not force cast + fillColor: StyleDefault.TEXT_ANNOTATION_FILL_COLOR, + // TODO magraph@0.1.0 find a way to not force cast + strokeWidth: StyleDefault.STROKE_WIDTH_THIN, + }; this.putCellStyle(ShapeBpmnElementKind.TEXT_ANNOTATION, style); } private configureGroupStyle(): void { - const style: StyleMap = {}; - style[mxConstants.STYLE_ROUNDED] = true; - style[mxConstants.STYLE_DASHED] = true; - style[mxConstants.STYLE_DASH_PATTERN] = '7 4 1 4'; - style[mxConstants.STYLE_STROKEWIDTH] = StyleDefault.STROKE_WIDTH_THIN; - style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.GROUP_FILL_COLOR; - // Default label positioning - style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER; - style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_TOP; + const style: BPMNCellStyle = { + rounded: true, + absoluteArcSize: 1, + // TODO magraph@0.1.0 find a way to not force cast + arcSize: StyleDefault.SHAPE_ARC_SIZE, + dashed: true, + dashPattern: '7 4 1 4', + // TODO magraph@0.1.0 find a way to not force cast + strokeWidth: StyleDefault.STROKE_WIDTH_THIN, + // TODO magraph@0.1.0 find a way to not force cast + fillColor: StyleDefault.GROUP_FILL_COLOR, + // Default label positioning + align: 'center', + verticalAlign: 'top', + }; this.putCellStyle(ShapeBpmnElementKind.GROUP, style); } private configureActivityStyles(): void { ShapeUtil.activityKinds().forEach(kind => { - const style: StyleMap = {}; - style[mxConstants.STYLE_SHAPE] = kind; - style[mxConstants.STYLE_ROUNDED] = true; // required by the BPMN specification - style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE; - style[mxConstants.STYLE_STROKEWIDTH] = kind == ShapeBpmnElementKind.CALL_ACTIVITY ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN; + const style: BPMNCellStyle = { + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + shape: (kind), + rounded: true, // required by the BPMN specification + + // TODO rebase arcSize seems to have been moved in another configuration + //absoluteArcSize: 1, + // TODO magraph@0.1.0 find a way to not force cast + //arcSize: StyleDefault.SHAPE_ARC_SIZE, + + // label style + verticalAlign: 'middle', + // TODO magraph@0.1.0 find a way to not force cast + strokeWidth: (kind == ShapeBpmnElementKind.CALL_ACTIVITY ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN), + }; this.putCellStyle(kind, style); }); } private configureGatewayStyles(): void { ShapeUtil.gatewayKinds().forEach(kind => { - const style: StyleMap = {}; - style[mxConstants.STYLE_SHAPE] = kind; - style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RhombusPerimeter; - style[mxConstants.STYLE_STROKEWIDTH] = StyleDefault.STROKE_WIDTH_THIN; - style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_TOP; - - // Default label positioning - style[mxConstants.STYLE_LABEL_POSITION] = mxConstants.ALIGN_LEFT; - style[mxConstants.STYLE_VERTICAL_LABEL_POSITION] = mxConstants.ALIGN_TOP; - + const style: BPMNCellStyle = { + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + shape: (kind), + perimeter: Perimeter.RhombusPerimeter, + verticalAlign: 'top', + // TODO magraph@0.1.0 find a way to not force cast + strokeWidth: StyleDefault.STROKE_WIDTH_THIN, + + // Default label positioning + labelPosition: 'left', + verticalLabelPosition: 'top', + }; this.putCellStyle(kind, style); }); } private configureDefaultEdgeStyle(): void { - const style = this.getStylesheet().getDefaultEdgeStyle(); + const style = this.getStylesheet().getDefaultEdgeStyle() as BPMNCellStyle; configureCommonDefaultStyle(style); - style[mxConstants.STYLE_SHAPE] = BpmnStyleIdentifier.EDGE; - style[mxConstants.STYLE_ENDSIZE] = arrowDefaultSize; - style[mxConstants.STYLE_STROKEWIDTH] = 1.5; - style[mxConstants.STYLE_ROUNDED] = true; - style[mxConstants.STYLE_ARCSIZE] = 5; - style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_BOTTOM; - + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + style.shape = BpmnStyleIdentifier.EDGE; + style.endSize = 12; + style.strokeWidth = 1.5; + style.rounded = true; + style.arcSize = 5; + style.verticalAlign = 'bottom'; // The end arrow must be redefined in specific style - delete style[mxConstants.STYLE_ENDARROW]; + style.endArrow = undefined; + } + + // TODO rebase move to a function out of the class + private static configureCommonDefaultStyle(style: BPMNCellStyle): void { + style.fontFamily = StyleDefault.DEFAULT_FONT_FAMILY; + style.fontSize = StyleDefault.DEFAULT_FONT_SIZE; + style.fontColor = StyleDefault.DEFAULT_FONT_COLOR; + style.fillColor = StyleDefault.DEFAULT_FILL_COLOR; + style.strokeColor = StyleDefault.DEFAULT_STROKE_COLOR; + style.labelBackgroundColor = constants.NONE; + + // only works with html labels (enabled by GraphConfigurator) + style.whiteSpace = 'wrap'; } - private configureEdgeStyles(styleKinds: T[], specificStyles: Map void>): void { + private configureEdgeStyles(styleKinds: T[], specificStyles: Map void>): void { styleKinds.forEach(kind => { - const style: StyleMap = {}; + // TODO magraph@0.1.0 review if we need to set bpmn.edge (this is not enough for edge.ts) + const style: BPMNCellStyle = { bpmn: { edge: {} } }; specificStyles.get(kind)(style); this.graph.getStylesheet().putCellStyle(kind.toString(), style); }); @@ -257,6 +319,7 @@ export class StyleConfigurator { } } +// TODO rebase fix function configureCommonDefaultStyle(style: StyleMap): void { style[mxConstants.STYLE_FONTFAMILY] = StyleDefault.DEFAULT_FONT_FAMILY; style[mxConstants.STYLE_FONTSIZE] = StyleDefault.DEFAULT_FONT_SIZE; @@ -269,8 +332,8 @@ function configureCommonDefaultStyle(style: StyleMap): void { style[mxConstants.STYLE_WHITE_SPACE] = 'wrap'; } -class MapWithDefault extends Map void> { - override get(key: T): (style: StyleMap) => void { +class MapWithDefault extends Map void> { + override get(key: T): (style: BPMNCellStyle) => void { return ( super.get(key) ?? (() => { diff --git a/src/component/mxgraph/initializer.ts b/src/component/mxgraph/initializer.ts deleted file mode 100644 index 4441dd0c3a..0000000000 --- a/src/component/mxgraph/initializer.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 2021 Bonitasoft S.A. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import factory, { type mxGraphExportObject } from 'mxgraph'; - -/** - * The `mxgraph` context that allows access to the mxGraph objects. - * - * **WARNING**: this is for advanced users. - * - * Here are some examples where calling the mxGraph API directly can be useful: - * ```javascript - * // Get the mxGraph version - * const mxGraphVersion = mxgraph.mxClient.VERSION; - * // Call mxUtils in custom BPMN Shapes - * c.setFillColor(mxgraph.mxUtils.getValue(this.style, BpmnStyleIdentifier.EDGE_START_FILL_COLOR, this.stroke)); - * ``` - * - * @since 0.30.0 - */ -export const mxgraph = initialize(); - -/** @internal */ -export const mxCellRenderer = mxgraph.mxCellRenderer; -/** @internal */ -export const mxClient = mxgraph.mxClient; -/** @internal */ -export const mxConstants = mxgraph.mxConstants; -/** @internal */ -export const mxEvent = mxgraph.mxEvent; -/** @internal */ -export const mxPerimeter = mxgraph.mxPerimeter; -/** @internal */ -export const mxPoint = mxgraph.mxPoint; -/** @internal */ -export const mxRectangle = mxgraph.mxRectangle; -/** @internal */ -export const mxRectangleShape = mxgraph.mxRectangleShape; -/** @internal */ -export const mxSvgCanvas2D = mxgraph.mxSvgCanvas2D; -/** @internal */ -export const mxUtils = mxgraph.mxUtils; - -/** @internal */ -declare global { - interface Window { - mxForceIncludes: boolean; - mxLoadResources: boolean; - mxLoadStylesheets: boolean; - mxResourceExtension: string; - } -} - -function initialize(): mxGraphExportObject { - // set options globally, as it is not working when passing options to the factory (https://github.com/jgraph/mxgraph/issues/479) - // Required otherwise 'Uncaught ReferenceError: assignment to undeclared variable mx...' - window.mxForceIncludes = false; - window.mxLoadResources = false; - // Required otherwise we got 'Uncaught ReferenceError: assignment to undeclared variable mx...' - window.mxLoadStylesheets = false; - window.mxResourceExtension = '.txt'; - - return factory({}); -} diff --git a/src/component/mxgraph/overlay/custom-overlay.ts b/src/component/mxgraph/overlay/custom-overlay.ts index 2bbda2413f..dac6de54b9 100644 --- a/src/component/mxgraph/overlay/custom-overlay.ts +++ b/src/component/mxgraph/overlay/custom-overlay.ts @@ -1,5 +1,5 @@ /* -Copyright 2021 Bonitasoft S.A. +Copyright 2023 Bonitasoft S.A. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { mxgraph, mxConstants, mxPoint, mxRectangle } from '../initializer'; -import type { mxCellState, mxPoint as mxPointType, mxRectangle as mxRectangleType } from 'mxgraph'; +import type { CellState } from '@maxgraph/core'; +import { CellOverlay, Point, Rectangle } from '@maxgraph/core'; + import type { OverlayStyle } from '../../registry'; export type VerticalAlignType = 'bottom' | 'middle' | 'top'; @@ -33,17 +34,22 @@ export interface MxGraphCustomOverlayPosition { export type MxGraphCustomOverlayStyle = Required; -export class MxGraphCustomOverlay extends mxgraph.mxCellOverlay { +export class MxGraphCustomOverlay extends CellOverlay { readonly style: MxGraphCustomOverlayStyle; constructor(public label: string, options: MxGraphCustomOverlayOptions) { - super(null, '', options.position.horizontalAlign, options.position.verticalAlign, null, 'default'); + super(null, '', options.position.horizontalAlign, options.position.verticalAlign, new Point(), 'default'); + // FIXME maxgraph@0.1.0 constructor doesn't set some properties + this.align = options.position.horizontalAlign; + this.verticalAlign = options.position.verticalAlign; + // end of fixme this.style = options.style; } - // Based on original method from mxCellOverlay (mxCellOverlay.prototype.getBounds) - override getBounds(state: mxCellState): mxRectangleType { - const isEdge = state.view.graph.getModel().isEdge(state.cell); + // TODO when doing the real maxGraph migration: update comment and check code migration + // Based on original method from mxCellOverlay (mxCellOverlay.prototype.getBounds) override getBounds(state: CellState): Rectangle { + override getBounds(state: CellState): Rectangle { + const isEdge = state.cell.isEdge(); const s = state.view.scale; let pt; @@ -56,43 +62,43 @@ export class MxGraphCustomOverlay extends mxgraph.mxCellOverlay { if (isEdge) { pt = this.computeEdgeBounds(state); } else { - pt = new mxPoint(); + pt = new Point(); - if (this.align == mxConstants.ALIGN_LEFT) { + if (this.align == 'left') { pt.x = state.x; - } else if (this.align == mxConstants.ALIGN_CENTER) { + } else if (this.align == 'center') { pt.x = state.x + state.width / 2; } else { pt.x = state.x + state.width; } - if (this.verticalAlign == mxConstants.ALIGN_TOP) { + if (this.verticalAlign == 'top') { pt.y = state.y; - } else if (this.verticalAlign == mxConstants.ALIGN_MIDDLE) { + } else if (this.verticalAlign == 'middle') { pt.y = state.y + state.height / 2; } else { pt.y = state.y + state.height; } } - return new mxRectangle(Math.round(pt.x - (w * this.defaultOverlap - this.offset.x) * s), Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * s); + return new Rectangle(Math.round(pt.x - (w * this.defaultOverlap - this.offset.x) * s), Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * s); } - private computeEdgeBounds(state: mxCellState): mxPointType { + private computeEdgeBounds(state: CellState): Point { const pts = state.absolutePoints; // 1st point for start position - if (this.align == mxConstants.ALIGN_LEFT) { + if (this.align == 'left') { return pts[0]; } // middle point for middle position - else if (this.align == mxConstants.ALIGN_CENTER) { + else if (this.align == 'center') { if (pts.length % 2 == 1) { return pts[Math.floor(pts.length / 2)]; } else { const idx = pts.length / 2; const p0 = pts[idx - 1]; const p1 = pts[idx]; - return new mxPoint(p0.x + (p1.x - p0.x) / 2, p0.y + (p1.y - p0.y) / 2); + return new Point(p0.x + (p1.x - p0.x) / 2, p0.y + (p1.y - p0.y) / 2); } } // last point for end position diff --git a/src/component/mxgraph/overlay/shapes.ts b/src/component/mxgraph/overlay/shapes.ts index 0cce8de3ae..59d4436d4e 100644 --- a/src/component/mxgraph/overlay/shapes.ts +++ b/src/component/mxgraph/overlay/shapes.ts @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { mxgraph } from '../initializer'; -import type { mxRectangle } from 'mxgraph'; +import type { Rectangle } from '@maxgraph/core'; +import { TextShape } from '@maxgraph/core'; import type { MxGraphCustomOverlayStyle } from './custom-overlay'; -export class OverlayBadgeShape extends mxgraph.mxText { - constructor(value: string, bounds: mxRectangle, style: MxGraphCustomOverlayStyle) { +export class OverlayBadgeShape extends TextShape { + constructor(value: string, bounds: Rectangle, style: MxGraphCustomOverlayStyle) { super( value, bounds, @@ -39,6 +39,6 @@ export class OverlayBadgeShape extends mxgraph.mxText { style.stroke.color, ); this.fillOpacity = style.fill.opacity; - this.strokewidth = style.stroke.width; + this.strokeWidth = style.stroke.width; } } diff --git a/src/component/mxgraph/renderer/CoordinatesTranslator.ts b/src/component/mxgraph/renderer/CoordinatesTranslator.ts index df5ed354a0..e47418282d 100644 --- a/src/component/mxgraph/renderer/CoordinatesTranslator.ts +++ b/src/component/mxgraph/renderer/CoordinatesTranslator.ts @@ -15,8 +15,8 @@ limitations under the License. */ import type { BpmnGraph } from '../BpmnGraph'; -import { mxPoint } from '../initializer'; -import type { mxCell, mxPoint as mxPointType } from 'mxgraph'; +import type { Cell } from '@maxgraph/core'; +import { Point } from '@maxgraph/core'; /** * @internal @@ -29,11 +29,11 @@ export default class CoordinatesTranslator { * @param parent the cell to use for the new coordinate referential * @param absoluteCoordinate */ - computeRelativeCoordinates(parent: mxCell, absoluteCoordinate: mxPointType): mxPointType { + computeRelativeCoordinates(parent: Cell, absoluteCoordinate: Point): Point { const translateForRoot = this.getTranslateForRoot(parent); const relativeX = absoluteCoordinate.x + translateForRoot.x; const relativeY = absoluteCoordinate.y + translateForRoot.y; - return new mxPoint(relativeX, relativeY); + return new Point(relativeX, relativeY); } // Returns the translation to be applied to a cell whose mxGeometry x and y values are expressed with absolute coordinates @@ -42,17 +42,16 @@ export default class CoordinatesTranslator { // // This implementation is taken from the example described in the documentation of mxgraph#getTranslateForRoot (4.1.1) // The translation is generally negative - private getTranslateForRoot(cell: mxCell): mxPointType { - const model = this.graph.getModel(); - const offset = new mxPoint(0, 0); + private getTranslateForRoot(cell: Cell): Point { + const offset = new Point(0, 0); while (cell != null) { - const geo = model.getGeometry(cell); + const geo = cell.getGeometry(); if (geo != null) { offset.x -= geo.x; offset.y -= geo.y; } - cell = model.getParent(cell); + cell = cell.getParent(); } return offset; @@ -64,8 +63,8 @@ export default class CoordinatesTranslator { * * The center coordinates are given in the same referential as the `mxCell`, so relative to its parent. */ - computeEdgeCenter(mxEdge: mxCell): mxPointType { - const points: mxPointType[] = mxEdge.geometry.points; + computeEdgeCenter(mxEdge: Cell): Point { + const points: Point[] = mxEdge.geometry.points; const p0 = points[0]; const pe = points[points.length - 1]; @@ -73,7 +72,7 @@ export default class CoordinatesTranslator { if (p0 != null && pe != null) { const dx = pe.x - p0.x; const dy = pe.y - p0.y; - return new mxPoint(p0.x + dx / 2, p0.y + dy / 2); + return new Point(p0.x + dx / 2, p0.y + dy / 2); } return undefined; diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index 7909d30d39..7c06f08ad5 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -14,7 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { mxConstants } from '../initializer'; +import type { CellStyle, ShapeValue } from '@maxgraph/core'; + import Shape from '../../../model/bpmn/internal/shape/Shape'; import type { Edge } from '../../../model/bpmn/internal/edge/edge'; import type Bounds from '../../../model/bpmn/internal/Bounds'; @@ -27,12 +28,54 @@ import { ShapeBpmnStartEvent, ShapeBpmnSubProcess, } from '../../../model/bpmn/internal/shape/ShapeBpmnElement'; -import { BpmnStyleIdentifier } from '../style'; +import { BpmnStyleIdentifier, FONT } from '../style'; +import type { + AssociationDirectionKind, + FlowKind, + GlobalTaskKind, + SequenceFlowKind, + ShapeBpmnEventBasedGatewayKind, + ShapeBpmnEventDefinitionKind, + ShapeBpmnSubProcessKind, +} from '../../../model/bpmn/internal'; import { MessageVisibleKind, ShapeBpmnCallActivityKind, ShapeBpmnElementKind, ShapeBpmnMarkerKind, ShapeUtil } from '../../../model/bpmn/internal'; import { AssociationFlow, SequenceFlow } from '../../../model/bpmn/internal/edge/flows'; import type { Font } from '../../../model/bpmn/internal/Label'; import type { RendererOptions } from '../../options'; +// TODO magraph@0.1.0 this type should probably be part of the API (so it should be exported) +export interface BPMNCellStyle extends CellStyle { + // TODO magraph@0.1.0 the shape property is defined as 'ShapeValue'. It should be 'ShapeValue | string' + // Omit { + // shape?: ShapeValue | string; + // TODO magraph@0.1.0 make bpmn mandatory? + bpmn?: { + // TODO magraph@0.1.0 sort properties in alphabetical order for clarity (and as done in maxGraph CellStyle) and provide documentation about each property + // TODO magraph@0.1.0 make kind mandatory? + kind?: ShapeBpmnElementKind | FlowKind; + isInstantiating?: boolean; + gatewayKind?: ShapeBpmnEventBasedGatewayKind; + eventDefinitionKind?: ShapeBpmnEventDefinitionKind; + isInterrupting?: boolean; + subProcessKind?: ShapeBpmnSubProcessKind; + globalTaskKind?: GlobalTaskKind; + markers?: ShapeBpmnMarkerKind[]; + sequenceFlowKind?: SequenceFlowKind; + associationDirectionKind?: AssociationDirectionKind; + // TODO magraph@0.1.0 isNonInitiating: previously we add a string, this introduces extra changes. If we want to keep this, do it in the master branch + isNonInitiating?: boolean; // TODO magraph@0.1.0 why not 'isInitiating' for consistency with other boolean value? Negate doesn't make things easier to understand + extra?: { + css: { + classes: string[]; + }; + }; + edge?: { + endFillColor?: string; + startFillColor?: string; + }; + }; +} + /** * @internal */ @@ -43,43 +86,47 @@ export default class StyleComputer { this.ignoreBpmnColors = options?.ignoreBpmnColors ?? true; } - computeStyle(bpmnCell: Shape | Edge, labelBounds: Bounds): string { - const styles: string[] = [bpmnCell.bpmnElement.kind as string]; + computeStyle(bpmnCell: Shape | Edge, labelBounds: Bounds): BPMNCellStyle { + const style: BPMNCellStyle = { + bpmn: { kind: bpmnCell.bpmnElement.kind }, + }; + + const baseStyleNames: string[] = [bpmnCell.bpmnElement.kind as string]; - let mainStyleValues; if (bpmnCell instanceof Shape) { - mainStyleValues = this.computeShapeStyleValues(bpmnCell); + // TODO magraph@0.1.0 find a better way for the merge + StyleComputer.enrichStyleWithShapeInfo(style, bpmnCell); } else { - styles.push(...StyleComputer.computeEdgeBaseStyles(bpmnCell)); - mainStyleValues = this.computeEdgeStyleValues(bpmnCell); + baseStyleNames.push(...StyleComputer.computeEdgeBaseStyleNames(bpmnCell)); } const fontStyleValues = this.computeFontStyleValues(bpmnCell); const labelStyleValues = StyleComputer.computeLabelStyleValues(bpmnCell, labelBounds); - return styles // - .concat(toArrayOfMxGraphStyleEntries([...mainStyleValues, ...fontStyleValues, ...labelStyleValues])) - .join(';'); + return { baseStyleNames: baseStyleNames, ...style, ...fontStyleValues, ...labelStyleValues }; } - private computeShapeStyleValues(shape: Shape): Map { - const styleValues = new Map(); + private static enrichStyleWithShapeInfo(style: BPMNCellStyle, shape: Shape): void { const bpmnElement = shape.bpmnElement; if (bpmnElement instanceof ShapeBpmnEvent) { - StyleComputer.computeEventShapeStyle(bpmnElement, styleValues); + StyleComputer.computeEventShapeStyle(bpmnElement, style); } else if (bpmnElement instanceof ShapeBpmnActivity) { - StyleComputer.computeActivityShapeStyle(bpmnElement, styleValues); + StyleComputer.computeActivityShapeStyle(bpmnElement, style); } else if (ShapeUtil.isPoolOrLane(bpmnElement.kind)) { + // 'style.horizontal' is for the label + // In BPMN, isHorizontal is for the Shape + // TODO rebase adapt comment // mxConstants.STYLE_HORIZONTAL is for the label // In BPMN, isHorizontal is for the Shape // So we invert the value when we switch from the BPMN value to the mxGraph value. - styleValues.set(mxConstants.STYLE_HORIZONTAL, shape.isHorizontal ? '0' : '1'); + style.horizontal = !(shape.isHorizontal ?? true); } else if (bpmnElement instanceof ShapeBpmnEventBasedGateway) { - styleValues.set(BpmnStyleIdentifier.IS_INSTANTIATING, String(bpmnElement.instantiate)); - styleValues.set(BpmnStyleIdentifier.EVENT_BASED_GATEWAY_KIND, String(bpmnElement.gatewayKind)); + style.bpmn.isInstantiating = bpmnElement.instantiate; + style.bpmn.gatewayKind = bpmnElement.gatewayKind; } + // TODO rebase adapt for maxGraph if (!this.ignoreBpmnColors) { const extensions = shape.extensions; const fillColor = extensions.fillColor; @@ -95,30 +142,29 @@ export default class StyleComputer { return styleValues; } - private static computeEventShapeStyle(bpmnElement: ShapeBpmnEvent, styleValues: Map): void { - styleValues.set(BpmnStyleIdentifier.EVENT_DEFINITION_KIND, bpmnElement.eventDefinitionKind); + private static computeEventShapeStyle(bpmnElement: ShapeBpmnEvent, style: BPMNCellStyle): void { + style.bpmn.eventDefinitionKind = bpmnElement.eventDefinitionKind; if (bpmnElement instanceof ShapeBpmnBoundaryEvent || (bpmnElement instanceof ShapeBpmnStartEvent && bpmnElement.isInterrupting !== undefined)) { - styleValues.set(BpmnStyleIdentifier.IS_INTERRUPTING, String(bpmnElement.isInterrupting)); + style.bpmn.isInterrupting = bpmnElement.isInterrupting; } } - private static computeActivityShapeStyle(bpmnElement: ShapeBpmnActivity, styleValues: Map): void { + private static computeActivityShapeStyle(bpmnElement: ShapeBpmnActivity, style: BPMNCellStyle): void { if (bpmnElement instanceof ShapeBpmnSubProcess) { - styleValues.set(BpmnStyleIdentifier.SUB_PROCESS_KIND, bpmnElement.subProcessKind); + style.bpmn.subProcessKind = bpmnElement.subProcessKind; } else if (bpmnElement.kind === ShapeBpmnElementKind.TASK_RECEIVE) { - styleValues.set(BpmnStyleIdentifier.IS_INSTANTIATING, String(bpmnElement.instantiate)); + style.bpmn.isInstantiating = bpmnElement.instantiate; } else if (bpmnElement instanceof ShapeBpmnCallActivity) { - styleValues.set(BpmnStyleIdentifier.GLOBAL_TASK_KIND, bpmnElement.globalTaskKind); + style.bpmn.globalTaskKind = bpmnElement.globalTaskKind; } - const markers: ShapeBpmnMarkerKind[] = bpmnElement.markers; - if (markers.length > 0) { - styleValues.set(BpmnStyleIdentifier.MARKERS, markers.join(',')); - } + style.bpmn.markers = bpmnElement.markers; } - private static computeEdgeBaseStyles(edge: Edge): string[] { + // TODO magraph@0.1.0 switch from static method to function (same in other places of this class) --> TODO in master branch + // This applies to the current implementation and to all static methods of this class + private static computeEdgeBaseStyleNames(edge: Edge): string[] { const styles: string[] = []; const bpmnElement = edge.bpmnElement; @@ -143,43 +189,49 @@ export default class StyleComputer { return styleValues; } - private computeFontStyleValues(bpmnCell: Shape | Edge): Map { - const styleValues = new Map(); + private computeFontStyleValues(bpmnCell: Shape | Edge): CellStyle { + const style: CellStyle = {}; const font = bpmnCell.label?.font; if (font) { - styleValues.set(mxConstants.STYLE_FONTFAMILY, font.name); - styleValues.set(mxConstants.STYLE_FONTSIZE, font.size); - styleValues.set(mxConstants.STYLE_FONTSTYLE, getFontStyleValue(font)); + font.name && (style.fontFamily = font.name); + font.size && (style.fontSize = font.size); + style.fontStyle = StyleComputer.getFontStyleValue(font); } + // TODO rebase adapt for maxGraph if (!this.ignoreBpmnColors) { const extensions = bpmnCell.label?.extensions; extensions?.color && styleValues.set(mxConstants.STYLE_FONTCOLOR, extensions.color); } - return styleValues; + return style; } - private static computeLabelStyleValues(bpmnCell: Shape | Edge, labelBounds: Bounds): Map { - const styleValues = new Map(); + private static computeLabelStyleValues(bpmnCell: Shape | Edge, labelBounds: Bounds): CellStyle { + const style: CellStyle = {}; const bpmnElement = bpmnCell.bpmnElement; if (labelBounds) { - styleValues.set(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP); + style.verticalAlign = 'top'; if (bpmnCell.bpmnElement.kind != ShapeBpmnElementKind.TEXT_ANNOTATION) { - styleValues.set(mxConstants.STYLE_ALIGN, mxConstants.ALIGN_CENTER); + style.align = 'center'; } if (bpmnCell instanceof Shape) { // arbitrarily increase width to relax too small bounds (for instance for reference diagrams from miwg-test-suite) - styleValues.set(mxConstants.STYLE_LABEL_WIDTH, labelBounds.width + 1); + style.labelWidth = labelBounds.width + 1; // align settings // According to the documentation, "label position" can only take values in left, center, right with default=center // However, there is undocumented behavior when the value is not one of these and this behavior is exactly what we want. // See https://github.com/jgraph/mxgraph/blob/v4.2.2/javascript/src/js/view/mxGraphView.js#L1183-L1252 - styleValues.set(mxConstants.STYLE_LABEL_POSITION, 'ignore'); - styleValues.set(mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE); + // FIXME magraph@0.1.0 values were inverted in the mxGraph implementation, this was probably wrong as they were set like this in StyleConfigurator (fixed in master branch) + // styleValues.set(mxConstants.STYLE_LABEL_POSITION, 'ignore'); + // styleValues.set(mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE); + // TODO rebase adapt label position for maxGraph + style.labelPosition = 'left'; + style.verticalLabelPosition = 'top'; + // end of fixme } } // when no label bounds, adjust the default style dynamically @@ -189,21 +241,24 @@ export default class StyleComputer { (bpmnElement instanceof ShapeBpmnCallActivity && bpmnElement.callActivityKind === ShapeBpmnCallActivityKind.CALLING_PROCESS)) && !bpmnElement.markers.includes(ShapeBpmnMarkerKind.EXPAND) ) { - styleValues.set(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP); + style.verticalAlign = 'top'; } - return styleValues; + return style; } - computeMessageFlowIconStyle(edge: Edge): string { - const styleValues: Array<[string, string]> = []; - styleValues.push(['shape', BpmnStyleIdentifier.MESSAGE_FLOW_ICON]); - styleValues.push([BpmnStyleIdentifier.IS_INITIATING, String(edge.messageVisibleKind === MessageVisibleKind.INITIATING)]); - if (!this.ignoreBpmnColors) { - edge.extensions.strokeColor && styleValues.push([mxConstants.STYLE_STROKECOLOR, edge.extensions.strokeColor]); - } - - return toArrayOfMxGraphStyleEntries(styleValues).join(';'); + computeMessageFlowIconStyle(edge: Edge): BPMNCellStyle { + return { + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + shape: BpmnStyleIdentifier.MESSAGE_FLOW_ICON, + // TODO rebase, isNonInitiating --> isInitiating + // styleValues.push([BpmnStyleIdentifier.IS_INITIATING, String(edge.messageVisibleKind === MessageVisibleKind.INITIATING)]); + bpmn: { isNonInitiating: edge.messageVisibleKind === MessageVisibleKind.NON_INITIATING }, + }; + // TODO rebase for maxGraph, handle bpmn in color + // if (!this.ignoreBpmnColors) { + // edge.extensions.strokeColor && styleValues.push([mxConstants.STYLE_STROKECOLOR, edge.extensions.strokeColor]); + // } } } @@ -214,20 +269,16 @@ export default class StyleComputer { export function getFontStyleValue(font: Font): number { let value = 0; if (font.isBold) { - value += mxConstants.FONT_BOLD; + value += FONT.BOLD; } if (font.isItalic) { - value += mxConstants.FONT_ITALIC; + value += FONT.ITALIC; } if (font.isStrikeThrough) { - value += mxConstants.FONT_STRIKETHROUGH; + value += FONT.STRIKETHROUGH; } if (font.isUnderline) { - value += mxConstants.FONT_UNDERLINE; + value += FONT.UNDERLINE; } return value; } - -function toArrayOfMxGraphStyleEntries(styleValues: Array<[string, string | number]>): string[] { - return styleValues.filter(([, v]) => v && v != 'undefined').map(([key, value]) => `${key}=${value}`); -} diff --git a/src/component/mxgraph/renderer/style-utils.ts b/src/component/mxgraph/renderer/style-utils.ts index 43ea496a38..82362a0814 100644 --- a/src/component/mxgraph/renderer/style-utils.ts +++ b/src/component/mxgraph/renderer/style-utils.ts @@ -14,9 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { mxCell } from 'mxgraph'; +import type { Cell } from '@maxgraph/core'; + import { FlowKind, ShapeUtil } from '../../../model/bpmn/internal'; -import { BpmnStyleIdentifier } from '../style/identifiers'; +import type { BPMNCellStyle } from './StyleComputer'; /** * Compute the all class names associated to a cell in a hyphen case form. @@ -25,8 +26,8 @@ import { BpmnStyleIdentifier } from '../style/identifiers'; * @param isLabel the boolean that indicates if class must be computed for label. * @internal */ -export function computeAllBpmnClassNamesOfCell(cell: mxCell, isLabel: boolean): string[] { - return computeAllBpmnClassNames(cell.style, isLabel); +export function computeAllBpmnClassNamesOfCell(cell: Cell, isLabel: boolean): string[] { + return computeAllBpmnClassNames(cell.style as BPMNCellStyle, isLabel); } /** @@ -36,13 +37,12 @@ export function computeAllBpmnClassNamesOfCell(cell: mxCell, isLabel: boolean): * @param isLabel the boolean that indicates if class must be computed for label. * @internal exported for testing purpose */ -export function computeAllBpmnClassNames(style: string, isLabel: boolean): string[] { +export function computeAllBpmnClassNames(style: BPMNCellStyle, isLabel: boolean): string[] { const classes: string[] = []; - const styleElements = style.split(';'); - const pseudoBpmnElementKind = styleElements[0]; - // shape=bpmn.message-flow-icon --> message-flow-icon - const bpmnElementKind = pseudoBpmnElementKind.replace(/shape=bpmn./g, ''); + // TODO magraph@0.1.0 style.bpmn.kind could be omit by considering the first element of style.baseStyleNames (this would restore the previous behavior) + // if kind is not set, check shape: bpmn.message-flow-icon --> message-flow-icon + const bpmnElementKind = style.bpmn?.kind ?? style.shape?.replace(/bpmn./g, ''); const typeClasses = new Map(); typeClasses.set('bpmn-type-activity', ShapeUtil.isActivity(bpmnElementKind)); @@ -55,31 +55,26 @@ export function computeAllBpmnClassNames(style: string, isLabel: boolean): strin classes.push(computeBpmnBaseClassName(bpmnElementKind)); - styleElements - .map(entry => { - const elements = entry.split('='); - return [elements[0], elements[1]]; - }) - .forEach(([key, value]) => { - switch (key) { - case BpmnStyleIdentifier.EVENT_DEFINITION_KIND: - classes.push(`bpmn-event-def-${value}`); - break; - case BpmnStyleIdentifier.EVENT_BASED_GATEWAY_KIND: - classes.push(`bpmn-gateway-kind-${value.toLowerCase()}`); - break; - case BpmnStyleIdentifier.IS_INITIATING: // message flow icon - classes.push(value == 'true' ? 'bpmn-icon-initiating' : 'bpmn-icon-non-initiating'); - break; - case BpmnStyleIdentifier.SUB_PROCESS_KIND: - classes.push(`bpmn-sub-process-${value.toLowerCase()}`); - break; - case BpmnStyleIdentifier.GLOBAL_TASK_KIND: - classes.push(computeBpmnBaseClassName(value)); - break; - } - }); - + if (style.bpmn?.eventDefinitionKind) { + classes.push(`bpmn-event-def-${style.bpmn.eventDefinitionKind}`); + } + if (style.bpmn?.gatewayKind) { + classes.push(`bpmn-gateway-kind-${style.bpmn.gatewayKind.toLowerCase()}`); + } + // TODO rebase use "initiating" and not "isNonInitiating" to restore the implementation of the master branch + // message flow icon + // case BpmnStyleIdentifier.IS_INITIATING: // message flow icon + // classes.push(value == 'true' ? 'bpmn-icon-initiating' : 'bpmn-icon-non-initiating'); + // break; + if (style.bpmn?.isNonInitiating !== undefined) { + classes.push(style.bpmn.isNonInitiating ? 'bpmn-icon-non-initiating' : 'bpmn-icon-initiating'); + } + if (style.bpmn?.subProcessKind) { + classes.push(`bpmn-sub-process-${style.bpmn.subProcessKind.toLowerCase()}`); + } + if (style.bpmn?.globalTaskKind) { + classes.push(computeBpmnBaseClassName(style.bpmn.globalTaskKind)); + } if (isLabel) { classes.push('bpmn-label'); } diff --git a/src/component/mxgraph/shape/activity-shapes.ts b/src/component/mxgraph/shape/activity-shapes.ts index 354fc2dbc8..0973245ba9 100644 --- a/src/component/mxgraph/shape/activity-shapes.ts +++ b/src/component/mxgraph/shape/activity-shapes.ts @@ -14,10 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { mxAbstractCanvas2D } from 'mxgraph'; -import { mxRectangleShape, mxUtils } from '../initializer'; -import { BpmnStyleIdentifier, StyleDefault } from '../style'; -import { getBpmnIsInstantiating } from '../style/utils'; +import type { AbstractCanvas2D } from '@maxgraph/core'; +import { RectangleShape } from '@maxgraph/core'; + +import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import { StyleDefault } from '../style'; import type { BpmnCanvas, PaintParameter, ShapeConfiguration } from './render'; import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; @@ -36,23 +37,23 @@ function paintEnvelopeIcon(paintParameter: PaintParameter, isFilled: boolean): v /** * @internal */ -export abstract class BaseActivityShape extends mxRectangleShape { +export abstract class BaseActivityShape extends RectangleShape { protected iconPainter = IconPainterProvider.get(); constructor() { super(undefined, undefined, undefined); // the configuration is passed with the styles at runtime } - override paintForeground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void { + override paintForeground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { super.paintForeground(c, x, y, w, h); // 0 is used for ratioParent as if we pass undefined to builder function the default 0.25 value will be used instead this.paintMarkerIcons(buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this, ratioFromParent: 0, iconStrokeWidth: 1.5 })); } protected paintMarkerIcons(paintParameter: PaintParameter): void { - const markers = mxUtils.getValue(this.style, BpmnStyleIdentifier.MARKERS, undefined); + const markers = (this.style as BPMNCellStyle).bpmn.markers; if (markers) { - orderActivityMarkers(markers.split(',')).forEach((marker, idx, allMarkers) => { + orderActivityMarkers(markers).forEach((marker, idx, allMarkers) => { paintParameter = { ...paintParameter, setIconOriginFunct: this.getMarkerIconOriginFunction(allMarkers.length, idx + 1), @@ -97,7 +98,7 @@ export abstract class BaseActivityShape extends mxRectangleShape { } abstract class BaseTaskShape extends BaseActivityShape { - override paintForeground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void { + override paintForeground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { super.paintForeground(c, x, y, w, h); this.paintTaskIcon(buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this })); } @@ -139,7 +140,7 @@ export class UserTaskShape extends BaseTaskShape { */ export class ReceiveTaskShape extends BaseTaskShape { protected paintTaskIcon(paintParameter: PaintParameter): void { - if (!getBpmnIsInstantiating(this.style)) { + if (!(this.style as BPMNCellStyle).bpmn.isInstantiating) { paintEnvelopeIcon(paintParameter, false); return; } @@ -206,12 +207,12 @@ export class ScriptTaskShape extends BaseTaskShape { * @internal */ export class CallActivityShape extends BaseActivityShape { - override paintForeground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void { + override paintForeground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { super.paintForeground(c, x, y, w, h); const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this }); - switch (mxUtils.getValue(this.style, BpmnStyleIdentifier.GLOBAL_TASK_KIND, undefined)) { + switch ((this.style as BPMNCellStyle).bpmn.globalTaskKind) { case ShapeBpmnElementKind.GLOBAL_TASK_MANUAL: this.iconPainter.paintHandIcon({ ...paintParameter, @@ -250,8 +251,8 @@ export class CallActivityShape extends BaseActivityShape { * @internal */ export class SubProcessShape extends BaseActivityShape { - override paintBackground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void { - const subProcessKind = mxUtils.getValue(this.style, BpmnStyleIdentifier.SUB_PROCESS_KIND, undefined); + override paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { + const subProcessKind = (this.style as BPMNCellStyle).bpmn.subProcessKind; c.save(); // ensure we can later restore the configuration if (subProcessKind === ShapeBpmnSubProcessKind.EVENT) { c.setDashed(true, false); diff --git a/src/component/mxgraph/shape/edges.ts b/src/component/mxgraph/shape/edges.ts index 58acf06350..947268343b 100644 --- a/src/component/mxgraph/shape/edges.ts +++ b/src/component/mxgraph/shape/edges.ts @@ -14,16 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { mxgraph, mxSvgCanvas2D, mxUtils } from '../initializer'; -import type { mxAbstractCanvas2D, mxPoint } from 'mxgraph'; -import { BpmnStyleIdentifier } from '../style'; +import type { Point, AbstractCanvas2D } from '@maxgraph/core'; +import { SvgCanvas2D, ConnectorShape } from '@maxgraph/core'; -export class BpmnConnector extends mxgraph.mxConnector { - constructor(points: mxPoint[], stroke: string, strokewidth?: number) { +import type { BPMNCellStyle } from '../renderer/StyleComputer'; + +// TODO magraph@0.1.0 remove to use the new support of endFillColor and starFillColor provided by https://github.com/maxGraph/maxGraph/issues/201 +export class BpmnConnector extends ConnectorShape { + constructor(points: Point[], stroke: string, strokewidth?: number) { super(points, stroke, strokewidth); } - override paintEdgeShape(c: mxAbstractCanvas2D, pts: mxPoint[]): void { + override paintEdgeShape(c: AbstractCanvas2D, pts: Point[]): void { // The indirection via functions for markers is needed in // order to apply the offsets before painting the line and // paint the markers after painting the line. @@ -37,19 +39,19 @@ export class BpmnConnector extends mxgraph.mxConnector { c.setDashed(false, false); if (sourceMarker != null) { - c.setFillColor(mxUtils.getValue(this.style, BpmnStyleIdentifier.EDGE_START_FILL_COLOR, this.stroke)); + c.setFillColor((this.style as BPMNCellStyle).bpmn?.edge?.startFillColor ?? this.stroke); sourceMarker(); } if (targetMarker != null) { - c.setFillColor(mxUtils.getValue(this.style, BpmnStyleIdentifier.EDGE_END_FILL_COLOR, this.stroke)); + c.setFillColor((this.style as BPMNCellStyle).bpmn?.edge?.endFillColor ?? this.stroke); targetMarker(); } } // taken from mxPolyline, required as we cannot call mxPolyline method here (parent of the parent) // we only support non STYLE_CURVED here (is possible with parent class) - private paintEdgeLine(c: mxAbstractCanvas2D, pts: mxPoint[]): void { + private paintEdgeLine(c: AbstractCanvas2D, pts: Point[]): void { const prev = getPointerEventsValue(c); setPointerEventsValue(c, 'stroke'); this.paintLine(c, pts, this.isRounded); @@ -57,12 +59,12 @@ export class BpmnConnector extends mxgraph.mxConnector { } } -function getPointerEventsValue(c: mxAbstractCanvas2D): string { - return c instanceof mxSvgCanvas2D ? c.pointerEventsValue : null; +function getPointerEventsValue(c: AbstractCanvas2D): string { + return c instanceof SvgCanvas2D ? c.pointerEventsValue : null; } -function setPointerEventsValue(c: mxAbstractCanvas2D, value: string): void { - if (c instanceof mxSvgCanvas2D) { +function setPointerEventsValue(c: AbstractCanvas2D, value: string): void { + if (c instanceof SvgCanvas2D) { c.pointerEventsValue = value; } } diff --git a/src/component/mxgraph/shape/event-shapes.ts b/src/component/mxgraph/shape/event-shapes.ts index e854b48f02..fce201acfe 100644 --- a/src/component/mxgraph/shape/event-shapes.ts +++ b/src/component/mxgraph/shape/event-shapes.ts @@ -14,18 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { mxAbstractCanvas2D } from 'mxgraph'; -import { mxgraph, mxUtils } from '../initializer'; -import { BpmnStyleIdentifier, StyleDefault } from '../style'; +import type { AbstractCanvas2D } from '@maxgraph/core'; +import { EllipseShape } from '@maxgraph/core'; + import { ShapeBpmnEventDefinitionKind } from '../../../model/bpmn/internal'; import type { BpmnCanvas, PaintParameter } from './render'; import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; +import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import { StyleDefault } from '../style'; /** * @internal */ -export class EventShape extends mxgraph.mxEllipse { +export class EventShape extends EllipseShape { protected iconPainter = IconPainterProvider.get(); // refactor: when all/more event types will be supported, we could move to a Record/MappedType @@ -85,10 +87,10 @@ export class EventShape extends mxgraph.mxEllipse { super(undefined, undefined, undefined); // the configuration is passed with the styles at runtime } - override paintVertexShape(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void { + override paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this, isFilled: this.withFilledIcon }); - EventShape.setDashedOuterShapePattern(paintParameter, mxUtils.getValue(this.style, BpmnStyleIdentifier.IS_INTERRUPTING, undefined)); + EventShape.setDashedOuterShapePattern(paintParameter, (this.style as BPMNCellStyle).bpmn.isInterrupting); this.paintOuterShape(paintParameter); EventShape.restoreOriginalOuterShapePattern(paintParameter); @@ -100,15 +102,14 @@ export class EventShape extends mxgraph.mxEllipse { } private paintInnerShape(paintParameter: PaintParameter): void { - const paintIcon = - this.iconPainters.get(mxUtils.getValue(this.style, BpmnStyleIdentifier.EVENT_DEFINITION_KIND, ShapeBpmnEventDefinitionKind.NONE)) ?? - (() => this.iconPainter.paintEmptyIcon()); + const paintIcon = this.iconPainters.get((this.style as BPMNCellStyle).bpmn.eventDefinitionKind) || (() => this.iconPainter.paintEmptyIcon()); paintIcon(paintParameter); } - private static setDashedOuterShapePattern(paintParameter: PaintParameter, isInterrupting: string): void { + private static setDashedOuterShapePattern(paintParameter: PaintParameter, isInterrupting: boolean): void { paintParameter.canvas.save(); // ensure we can later restore the configuration - if (isInterrupting === 'false') { + // TODO magraph@0.1.0 'isInterrupting' can be undefined in maxGraph whereas it wasn't with mxGraph + if (isInterrupting === false) { paintParameter.canvas.setDashed(true, false); paintParameter.canvas.setDashPattern('3 2'); } diff --git a/src/component/mxgraph/shape/flow-shapes.ts b/src/component/mxgraph/shape/flow-shapes.ts index 8cafc6ee80..5af884e6b0 100644 --- a/src/component/mxgraph/shape/flow-shapes.ts +++ b/src/component/mxgraph/shape/flow-shapes.ts @@ -14,33 +14,26 @@ See the License for the specific language governing permissions and limitations under the License. */ +import type { AbstractCanvas2D, Rectangle } from '@maxgraph/core'; +import { RectangleShape } from '@maxgraph/core'; + import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import { BpmnStyleIdentifier } from '../style'; -import { mxRectangleShape, mxUtils } from '../initializer'; -import type { mxAbstractCanvas2D, mxRectangle } from 'mxgraph'; +import type { BPMNCellStyle } from '../renderer/StyleComputer'; /** * @internal */ -export class MessageFlowIconShape extends mxRectangleShape { +export class MessageFlowIconShape extends RectangleShape { protected iconPainter = IconPainterProvider.get(); - constructor(bounds: mxRectangle, fill: string, stroke: string, strokewidth: number) { + constructor(bounds: Rectangle, fill: string, stroke: string, strokewidth: number) { super(bounds, fill, stroke, strokewidth); } - override paintVertexShape(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void { - const paintParameter = buildPaintParameter({ - canvas: c, - x, - y, - width: w, - height: h, - shape: this, - ratioFromParent: 1, - isFilled: mxUtils.getValue(this.style, BpmnStyleIdentifier.IS_INITIATING, 'true') == 'false', - }); + override paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { + const withFilledIcon = (this.style as BPMNCellStyle).bpmn.isNonInitiating; + const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this, ratioFromParent: 1, isFilled: withFilledIcon }); this.iconPainter.paintEnvelopeIcon(paintParameter); } diff --git a/src/component/mxgraph/shape/gateway-shapes.ts b/src/component/mxgraph/shape/gateway-shapes.ts index 45170806e3..66179e50b9 100644 --- a/src/component/mxgraph/shape/gateway-shapes.ts +++ b/src/component/mxgraph/shape/gateway-shapes.ts @@ -14,21 +14,22 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { mxAbstractCanvas2D } from 'mxgraph'; -import { mxgraph, mxUtils } from '../initializer'; -import { BpmnStyleIdentifier, StyleDefault } from '../style'; -import { getBpmnIsInstantiating } from '../style/utils'; +import type { AbstractCanvas2D } from '@maxgraph/core'; +import { RhombusShape } from '@maxgraph/core'; + import { ShapeBpmnEventBasedGatewayKind } from '../../../model/bpmn/internal'; +import { StyleDefault } from '../style'; import type { PaintParameter } from './render'; import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; +import type { BPMNCellStyle } from '../renderer/StyleComputer'; -abstract class GatewayShape extends mxgraph.mxRhombus { +abstract class GatewayShape extends RhombusShape { protected iconPainter = IconPainterProvider.get(); protected abstract paintInnerShape(paintParameter: PaintParameter): void; - override paintVertexShape(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void { + override paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this }); this.paintOuterShape(paintParameter); this.paintInnerShape(paintParameter); @@ -103,7 +104,7 @@ export class EventBasedGatewayShape extends GatewayShape { ...paintParameter, ratioFromParent: 0.55, }); - if (!getBpmnIsInstantiating(this.style)) { + if (!(this.style as BPMNCellStyle).bpmn.isInstantiating) { this.iconPainter.paintCircleIcon({ ...paintParameter, ratioFromParent: 0.45, @@ -115,7 +116,7 @@ export class EventBasedGatewayShape extends GatewayShape { ...paintParameter, ratioFromParent: 0.3, }; - if (mxUtils.getValue(this.style, BpmnStyleIdentifier.EVENT_BASED_GATEWAY_KIND, ShapeBpmnEventBasedGatewayKind.Exclusive) == ShapeBpmnEventBasedGatewayKind.Parallel) { + if ((this.style as BPMNCellStyle).bpmn.gatewayKind == ShapeBpmnEventBasedGatewayKind.Parallel) { this.iconPainter.paintPlusCrossIcon(innerIconPaintParameter); } else { this.iconPainter.paintPentagon(innerIconPaintParameter); diff --git a/src/component/mxgraph/shape/render/BpmnCanvas.ts b/src/component/mxgraph/shape/render/BpmnCanvas.ts index d8415ccb53..59c8a23915 100644 --- a/src/component/mxgraph/shape/render/BpmnCanvas.ts +++ b/src/component/mxgraph/shape/render/BpmnCanvas.ts @@ -16,7 +16,7 @@ limitations under the License. import { StyleDefault } from '../../style'; import type { IconConfiguration, IconStyleConfiguration, ShapeConfiguration, Size } from './render-types'; -import type { mxAbstractCanvas2D } from 'mxgraph'; +import type { AbstractCanvas2D } from '@maxgraph/core'; /** * **WARN**: You may use it to customize the BPMN Theme as suggested in the examples. But be aware that the way the default BPMN theme can be modified is subject to change. @@ -25,7 +25,7 @@ import type { mxAbstractCanvas2D } from 'mxgraph'; * @experimental */ export interface BpmnCanvasConfiguration { - canvas: mxAbstractCanvas2D; + canvas: AbstractCanvas2D; shapeConfig: ShapeConfiguration; iconConfig: IconConfiguration; } @@ -79,7 +79,7 @@ export function computeScaledIconSize(initialIconSize: Size, iconStyleConfigurat * @experimental */ export class BpmnCanvas { - private canvas: mxAbstractCanvas2D; + private canvas: AbstractCanvas2D; private readonly iconOriginalSize: Size; private readonly scaleX: number; @@ -192,7 +192,7 @@ export class BpmnCanvas { this.canvas.setStrokeWidth(strokeWidth); } - arcTo(rx: number, ry: number, angle: number, largeArcFlag: number, sweepFlag: number, x: number, y: number): void { + arcTo(rx: number, ry: number, angle: number, largeArcFlag: boolean, sweepFlag: boolean, x: number, y: number): void { this.canvas.arcTo(rx * this.scaleX, ry * this.scaleY, angle, largeArcFlag, sweepFlag, this.computeScaleFromOriginX(x), this.computeScaleFromOriginY(y)); } diff --git a/src/component/mxgraph/shape/render/icon-painter.ts b/src/component/mxgraph/shape/render/icon-painter.ts index ec23e37d63..f16bee76f1 100644 --- a/src/component/mxgraph/shape/render/icon-painter.ts +++ b/src/component/mxgraph/shape/render/icon-painter.ts @@ -14,11 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { mxAbstractCanvas2D, mxShape } from 'mxgraph'; -import { mxConstants, mxUtils } from '../../initializer'; -import { StyleDefault } from '../../style'; import { BpmnCanvas } from './BpmnCanvas'; +import { StyleDefault } from '../../style'; import type { IconStyleConfiguration, ShapeConfiguration, Size } from './render-types'; +import type { Shape, AbstractCanvas2D } from '@maxgraph/core'; /** * **WARN**: You may use it to customize the BPMN Theme as suggested in the examples. But be aware that the way the default BPMN theme can be modified is subject to change. @@ -27,7 +26,7 @@ import type { IconStyleConfiguration, ShapeConfiguration, Size } from './render- * @experimental */ export interface PaintParameter { - canvas: mxAbstractCanvas2D; + canvas: AbstractCanvas2D; shapeConfig: ShapeConfiguration; iconStyleConfig: IconStyleConfiguration; ratioFromParent?: number; @@ -48,20 +47,20 @@ export function buildPaintParameter({ isFilled, iconStrokeWidth, }: { - canvas: mxAbstractCanvas2D; + canvas: AbstractCanvas2D; x: number; y: number; width: number; height: number; - shape: mxShape; + shape: Shape; ratioFromParent?: number; isFilled?: boolean; iconStrokeWidth?: number; }): PaintParameter { - const shapeStrokeWidth = shape.strokewidth || mxUtils.getValue(shape.style, mxConstants.STYLE_STROKEWIDTH, StyleDefault.STROKE_WIDTH_THIN); - const fillColor = shape.fill || mxUtils.getValue(shape.style, mxConstants.STYLE_FILLCOLOR, StyleDefault.DEFAULT_FILL_COLOR); - const strokeColor = shape.stroke || mxUtils.getValue(shape.style, mxConstants.STYLE_STROKECOLOR, StyleDefault.DEFAULT_STROKE_COLOR); - const margin = mxUtils.getValue(shape.style, mxConstants.STYLE_MARGIN, StyleDefault.DEFAULT_MARGIN); + const shapeStrokeWidth = shape.strokeWidth || shape.style.strokeWidth || StyleDefault.STROKE_WIDTH_THIN; + const fillColor = shape.fill || shape.style.fillColor || StyleDefault.DEFAULT_FILL_COLOR; + const strokeColor = shape.stroke || shape.style.strokeColor || StyleDefault.DEFAULT_STROKE_COLOR; + const margin = shape.style.margin ?? StyleDefault.DEFAULT_MARGIN; ratioFromParent ??= 0.25; isFilled ??= false; iconStrokeWidth ??= 0; @@ -425,64 +424,64 @@ export class IconPainter { canvas.begin(); canvas.moveTo(124.31, 150.29); canvas.lineTo(99.66, 141.03); - canvas.arcTo(6.43, 6.43, 0, 0, 1, 95.51, 135.03); + canvas.arcTo(6.43, 6.43, 0, false, true, 95.51, 135.03); canvas.lineTo(95.51, 130.66); - canvas.arcTo(47.75, 47.75, 0, 0, 0, 119.51, 89.25); + canvas.arcTo(47.75, 47.75, 0, false, false, 119.51, 89.25); canvas.lineTo(119.51, 71.25); - canvas.arcTo(47.62, 47.62, 0, 0, 0, 101.18, 33.64); - canvas.arcTo(29.35, 29.35, 0, 0, 0, 101.52, 29.14); - canvas.arcTo(29.68, 29.68, 0, 0, 0, 42.17, 29.14); - canvas.arcTo(29.24, 29.24, 0, 0, 0, 42.53, 33.63); - canvas.arcTo(47.65, 47.65, 0, 0, 0, 24.14, 71.23); + canvas.arcTo(47.62, 47.62, 0, false, false, 101.18, 33.64); + canvas.arcTo(29.35, 29.35, 0, false, false, 101.52, 29.14); + canvas.arcTo(29.68, 29.68, 0, false, false, 42.17, 29.14); + canvas.arcTo(29.24, 29.24, 0, false, false, 42.53, 33.63); + canvas.arcTo(47.65, 47.65, 0, false, false, 24.14, 71.23); canvas.lineTo(24.14, 89.23); - canvas.arcTo(47.7, 47.7, 0, 0, 0, 48.19, 130.63); + canvas.arcTo(47.7, 47.7, 0, false, false, 48.19, 130.63); canvas.lineTo(48.19, 135.03); - canvas.arcTo(6.43, 6.43, 0, 0, 1, 44.03, 141.03); + canvas.arcTo(6.43, 6.43, 0, false, true, 44.03, 141.03); canvas.lineTo(19.31, 150.29); - canvas.arcTo(29.81, 29.81, 0, 0, 0, 0.09, 178.03); + canvas.arcTo(29.81, 29.81, 0, false, false, 0.09, 178.03); canvas.lineTo(0.09, 233.51); - canvas.arcTo(5.63, 5.63, 0, 1, 0, 11.34, 233.51); + canvas.arcTo(5.63, 5.63, 0, true, false, 11.34, 233.51); canvas.lineTo(11.34, 178.03); - canvas.arcTo(18.19, 18.19, 0, 0, 1, 11.57, 175.17); + canvas.arcTo(18.19, 18.19, 0, false, true, 11.57, 175.17); canvas.lineTo(20.5, 184.11); - canvas.arcTo(12.32, 12.32, 0, 0, 1, 24.14, 192.89); + canvas.arcTo(12.32, 12.32, 0, false, true, 24.14, 192.89); canvas.lineTo(24.14, 233.51); - canvas.arcTo(5.63, 5.63, 0, 1, 0, 35.39, 233.51); + canvas.arcTo(5.63, 5.63, 0, true, false, 35.39, 233.51); canvas.lineTo(35.39, 192.93); - canvas.arcTo(23.5, 23.5, 0, 0, 0, 28.46, 176.2); + canvas.arcTo(23.5, 23.5, 0, false, false, 28.46, 176.2); canvas.lineTo(17.04, 164.78); - canvas.arcTo(18.34, 18.34, 0, 0, 1, 23.29, 160.78); + canvas.arcTo(18.34, 18.34, 0, false, true, 23.29, 160.78); canvas.lineTo(43.65, 153.15); canvas.lineTo(66.22, 175.72); canvas.lineTo(66.22, 233.51); - canvas.arcTo(5.63, 5.63, 0, 1, 0, 77.47, 233.51); + canvas.arcTo(5.63, 5.63, 0, true, false, 77.47, 233.51); canvas.lineTo(77.47, 175.76); canvas.lineTo(100.04, 153.19); canvas.lineTo(120.4, 160.82); - canvas.arcTo(18.39, 18.39, 0, 0, 1, 126.65, 164.82); + canvas.arcTo(18.39, 18.39, 0, false, true, 126.65, 164.82); canvas.lineTo(115.24, 176.24); - canvas.arcTo(23.5, 23.5, 0, 0, 0, 108.31, 192.93); + canvas.arcTo(23.5, 23.5, 0, false, false, 108.31, 192.93); canvas.lineTo(108.31, 233.55); - canvas.arcTo(5.63, 5.63, 0, 1, 0, 119.56, 233.55); + canvas.arcTo(5.63, 5.63, 0, true, false, 119.56, 233.55); canvas.lineTo(119.56, 192.93); - canvas.arcTo(12.35, 12.35, 0, 0, 1, 123.19, 184.15); + canvas.arcTo(12.35, 12.35, 0, false, true, 123.19, 184.15); canvas.lineTo(132.13, 175.22); - canvas.arcTo(18, 18, 0, 0, 1, 132.36, 178.08); + canvas.arcTo(18, 18, 0, false, true, 132.36, 178.08); canvas.lineTo(132.36, 233.56); - canvas.arcTo(5.63, 5.63, 0, 0, 0, 143.61, 233.56); + canvas.arcTo(5.63, 5.63, 0, false, false, 143.61, 233.56); canvas.lineTo(143.61, 178.03); - canvas.arcTo(29.81, 29.81, 0, 0, 0, 124.31, 150.29); + canvas.arcTo(29.81, 29.81, 0, false, false, 124.31, 150.29); canvas.close(); canvas.moveTo(71.85, 10.72); - canvas.arcTo(18.46, 18.46, 0, 0, 1, 90.17, 27.18); - canvas.arcTo(47.68, 47.68, 0, 0, 0, 53.53, 27.18); - canvas.arcTo(18.44, 18.44, 0, 0, 1, 71.85, 10.72); + canvas.arcTo(18.46, 18.46, 0, false, true, 90.17, 27.18); + canvas.arcTo(47.68, 47.68, 0, false, false, 53.53, 27.18); + canvas.arcTo(18.44, 18.44, 0, false, true, 71.85, 10.72); canvas.close(); canvas.moveTo(35.39, 71.23); - canvas.arcTo(36.46, 36.46, 0, 0, 1, 108.31, 71.23); + canvas.arcTo(36.46, 36.46, 0, false, true, 108.31, 71.23); canvas.lineTo(108.31, 77.4); canvas.curveTo(82.12, 75.4, 56.97, 60.55, 56.71, 60.4); - canvas.arcTo(5.62, 5.62, 0, 0, 0, 48.78, 62.71); + canvas.arcTo(5.62, 5.62, 0, false, false, 48.78, 62.71); canvas.curveTo(46.24, 67.79, 40.45, 71.89, 35.39, 74.62); canvas.close(); canvas.moveTo(35.39, 89.23); @@ -490,13 +489,13 @@ export class IconPainter { canvas.curveTo(40.55, 84.85, 49.73, 80.08, 55.67, 72.66); canvas.curveTo(64.83, 77.46, 85.92, 87.21, 108.31, 88.66); canvas.lineTo(108.31, 89.24); - canvas.arcTo(36.46, 36.46, 0, 1, 1, 35.39, 89.24); + canvas.arcTo(36.46, 36.46, 0, true, true, 35.39, 89.24); canvas.close(); canvas.moveTo(71.85, 165.45); canvas.lineTo(54.06, 147.69); - canvas.arcTo(17.7, 17.7, 0, 0, 0, 59.43, 135.32); - canvas.arcTo(47.57, 47.57, 0, 0, 0, 84.27, 135.32); - canvas.arcTo(17.7, 17.7, 0, 0, 0, 89.64, 147.69); + canvas.arcTo(17.7, 17.7, 0, false, false, 59.43, 135.32); + canvas.arcTo(47.57, 47.57, 0, false, false, 84.27, 135.32); + canvas.arcTo(17.7, 17.7, 0, false, false, 89.64, 147.69); canvas.close(); canvas.fill(); } @@ -607,8 +606,8 @@ export class IconPainter { private static paintGearInnerCircle(canvas: BpmnCanvas, arcStartX: number, arcStartY: number): void { const arcRay = 13.5; canvas.moveTo(arcStartX, arcStartY); - canvas.arcTo(arcRay, arcRay, 0, 1, 1, arcStartX + 2 * arcRay, arcStartY); - canvas.arcTo(arcRay, arcRay, 0, 0, 1, arcStartX, arcStartY); + canvas.arcTo(arcRay, arcRay, 0, true, true, arcStartX + 2 * arcRay, arcStartY); + canvas.arcTo(arcRay, arcRay, 0, false, true, arcStartX, arcStartY); canvas.close(); canvas.fillAndStroke(); } @@ -651,7 +650,7 @@ export class IconPainter { // Loop canvas.begin(); canvas.moveTo(5.5, 19.08); - canvas.arcTo(8, 8, 0, 1, 1, 10.5, 21.08); + canvas.arcTo(8, 8, 0, true, true, 10.5, 21.08); canvas.stroke(); // Arrow diff --git a/src/component/mxgraph/shape/text-annotation-shapes.ts b/src/component/mxgraph/shape/text-annotation-shapes.ts index dc937e7104..5fa120932c 100644 --- a/src/component/mxgraph/shape/text-annotation-shapes.ts +++ b/src/component/mxgraph/shape/text-annotation-shapes.ts @@ -15,14 +15,14 @@ limitations under the License. */ import { StyleDefault } from '../style'; -import { mxRectangleShape } from '../initializer'; -import type { mxAbstractCanvas2D } from 'mxgraph'; +import type { AbstractCanvas2D } from '@maxgraph/core'; +import { RectangleShape } from '@maxgraph/core'; /** * @internal */ -export class TextAnnotationShape extends mxRectangleShape { - override paintForeground(c: mxAbstractCanvas2D, x: number, y: number, _w: number, h: number): void { +export class TextAnnotationShape extends RectangleShape { + override paintForeground(c: AbstractCanvas2D, x: number, y: number, _w: number, h: number): void { // paint sort of left square bracket shape - for text annotation c.begin(); c.moveTo(x + StyleDefault.TEXT_ANNOTATION_BORDER_LENGTH, y); @@ -32,7 +32,7 @@ export class TextAnnotationShape extends mxRectangleShape { c.stroke(); } - override paintBackground(c: mxAbstractCanvas2D, x: number, y: number, w: number, h: number): void { + override paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { c.save(); // ensure we can later restore the configuration c.setStrokeColor('none'); // we have a special stroke shape managed in 'paintForeground' super.paintBackground(c, x, y, w, h); diff --git a/src/component/mxgraph/style/identifiers.ts b/src/component/mxgraph/style/identifiers.ts index 64dd8bbe9c..79feb14ea5 100644 --- a/src/component/mxgraph/style/identifiers.ts +++ b/src/component/mxgraph/style/identifiers.ts @@ -22,26 +22,12 @@ limitations under the License. * @category BPMN Theme * @experimental */ +// TODO real maxGraph migration - may be renamed into BpmnShapeIdentifier after the maxGraph migration export const BpmnStyleIdentifier = { // edge EDGE: 'bpmn.edge', - EDGE_START_FILL_COLOR: 'bpmn.edge.startFillColor', - EDGE_END_FILL_COLOR: 'bpmn.edge.endFillColor', - - // kind - EVENT_BASED_GATEWAY_KIND: 'bpmn.gatewayKind', - EVENT_DEFINITION_KIND: 'bpmn.eventDefinitionKind', - GLOBAL_TASK_KIND: 'bpmn.globalTaskKind', - SUB_PROCESS_KIND: 'bpmn.subProcessKind', - - // state - IS_INITIATING: 'bpmn.isInitiating', - IS_INSTANTIATING: 'bpmn.isInstantiating', - IS_INTERRUPTING: 'bpmn.isInterrupting', // other identifiers - EXTRA_CSS_CLASSES: 'bpmn.extra.css.classes', - MARKERS: 'bpmn.markers', MESSAGE_FLOW_ICON: 'bpmn.messageFlowIcon', }; diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index 38f720a51c..082008db0d 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -17,7 +17,6 @@ limitations under the License. import { ensureOpacityValue, ensureStrokeWidthValue } from '../../helpers/validators'; import type { Fill, Font, ShapeStyleUpdate, Stroke, StyleUpdate } from '../../registry'; import { ShapeBpmnElementKind } from '../../../model/bpmn/internal'; -import { mxConstants, mxUtils } from '../initializer'; import { BpmnStyleIdentifier } from './identifiers'; /** @@ -68,16 +67,18 @@ export const StyleDefault = { MESSAGE_FLOW_MARKER_END_FILL_COLOR: 'White', }; -/** - * Get the BPMN 'instantiate' information from the style. - * @param style the mxGraph style - * @internal - * @private - */ -export const getBpmnIsInstantiating = (style: { [p: string]: unknown }): boolean => mxUtils.getValue(style, BpmnStyleIdentifier.IS_INSTANTIATING, 'false') == 'true'; +// TODO magraph@0.1.0 maxGraph "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.FONT +// TODO magraph@0.1.0 remove duplicated from maxGraph +export enum FONT { + BOLD = 1, + ITALIC = 2, + UNDERLINE = 4, + STRIKETHROUGH = 8, +} const convertDefaultValue = (value: string): string | undefined => (value == 'default' ? undefined : value); +// TODO rebase fix update style functions export const updateStroke = (cellStyle: string, stroke: Stroke): string => { if (stroke) { cellStyle = setStyle(cellStyle, mxConstants.STYLE_STROKECOLOR, stroke.color, convertDefaultValue); diff --git a/src/component/version.ts b/src/component/version.ts index f29b84527b..ed7709f611 100644 --- a/src/component/version.ts +++ b/src/component/version.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { mxClient } from './mxgraph/initializer'; +import { Client } from '@maxgraph/core'; // WARN: this constant is automatically updated at release time by the 'manage-version-in-files.mjs' script. // So, if you modify the name of this file or this constant, please update the script accordingly. @@ -24,7 +24,7 @@ const libVersion = '0.37.0-post'; * @internal */ export const version = (): Version => { - return { lib: libVersion, dependencies: new Map([['mxGraph', mxClient.VERSION]]) }; + return { lib: libVersion, dependencies: new Map([['maxGraph', Client.VERSION]]) }; }; /** diff --git a/test/integration/BpmnVisualization.test.ts b/test/integration/BpmnVisualization.test.ts index 3ebd379338..1e3780d9ac 100644 --- a/test/integration/BpmnVisualization.test.ts +++ b/test/integration/BpmnVisualization.test.ts @@ -67,8 +67,8 @@ describe('BpmnVisualization API', () => { it('lib version', () => { expect(bpmnVisualization.getVersion().lib).toBe(getLibVersionFromPackageJson()); }); - it('mxGraph version', () => { - expect(bpmnVisualization.getVersion().dependencies.get('mxGraph')).toBeDefined(); + it('maxGraph version', () => { + expect(bpmnVisualization.getVersion().dependencies.get('maxGraph')).toBeDefined(); }); it('not modifiable version', () => { const initialVersion = bpmnVisualization.getVersion(); diff --git a/test/integration/config/mxgraph-config.ts b/test/integration/config/mxgraph-config.ts index 994f551ddc..d5f96a79c6 100644 --- a/test/integration/config/mxgraph-config.ts +++ b/test/integration/config/mxgraph-config.ts @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { mxClient } from '@lib/component/mxgraph/initializer'; +import { Client } from '@maxgraph/core'; // Force usage of ForeignObject // By default, mxGraph detects no ForeignObject support when running tests in jsdom environment -mxClient.NO_FO = false; +Client.NO_FO = false; diff --git a/test/integration/helpers/model-expect.ts b/test/integration/helpers/model-expect.ts index 5f2b6b3e9b..816301ae34 100644 --- a/test/integration/helpers/model-expect.ts +++ b/test/integration/helpers/model-expect.ts @@ -15,6 +15,7 @@ limitations under the License. */ import type { + AssociationDirectionKind, Fill, FlowKind, GlobalTaskKind, @@ -58,9 +59,10 @@ import { toBeTextAnnotation, toBeUserTask, } from '../matchers'; -import type { mxCell, mxGeometry } from 'mxgraph'; +import type { AlignValue, ArrowType, Cell, FilterFunction, Geometry, ShapeValue, VAlignValue } from '@maxgraph/core'; import type { ExpectedOverlay } from '../matchers/matcher-utils'; import { getCell } from '../matchers/matcher-utils'; +import type { BPMNCellStyle } from '../../../src/component/mxgraph/renderer/StyleComputer'; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace @@ -137,7 +139,7 @@ expect.extend({ export interface ExpectedCellWithGeometry { parentId?: string; - geometry: mxGeometry; + geometry: Geometry; } export interface ExpectedFont { @@ -151,7 +153,9 @@ export interface ExpectedFont { opacity?: Opacity; } +// TODO rebase do we keep HorizontalAlign, we could use AlignValue instead export type HorizontalAlign = 'center' | 'left' | 'right'; +// TODO rebase do we keep VerticalAlign, we could use VAlignValue instead export type VerticalAlign = 'bottom' | 'middle' | 'top'; type ExpectedModelElement = { @@ -170,7 +174,7 @@ type ExpectedModelElement = { export interface ExpectedShapeModelElement extends ExpectedModelElement { kind?: ShapeBpmnElementKind; /** Generally needed when the BPMN shape doesn't exist yet (use an arbitrary shape until the final render is implemented) */ - styleShape?: string; + styleShape?: ShapeValue | string; markers?: ShapeBpmnMarkerKind[]; isInstantiating?: boolean; /** @@ -196,8 +200,8 @@ export interface ExpectedCallActivityModelElement extends ExpectedShapeModelElem export interface ExpectedEdgeModelElement extends ExpectedModelElement { kind?: FlowKind; - startArrow?: string; - endArrow?: string; + startArrow?: ArrowType; + endArrow?: ArrowType; messageVisibleKind?: MessageVisibleKind; } @@ -205,6 +209,10 @@ export interface ExpectedSequenceFlowModelElement extends ExpectedEdgeModelEleme sequenceFlowKind?: SequenceFlowKind; } +export interface ExpectedAssociationFlowModelElement extends ExpectedEdgeModelElement { + associationDirectionKind?: AssociationDirectionKind; +} + export interface ExpectedBoundaryEventModelElement extends ExpectedEventModelElement { isInterrupting?: boolean; } @@ -217,24 +225,24 @@ export interface ExpectedEventBasedGatewayModelElement extends ExpectedShapeMode } export const bpmnVisualization = new BpmnVisualization(null); -const defaultParent = bpmnVisualization.graph.getDefaultParent(); +const getDefaultParent = (): Cell => bpmnVisualization.graph.getDefaultParent(); -export const getDefaultParentId = (): string => defaultParent.id; +export const getDefaultParentId = (): string => getDefaultParent().id; -const expectElementsInModel = (parentId: string, elementsNumber: number, filter: (cell: mxCell) => boolean): void => { - const model = bpmnVisualization.graph.model; - const descendants = model.filterDescendants(filter, getCell(parentId)); +const expectElementsInModel = (parentId: string, elementsNumber: number, filter: FilterFunction): void => { + const parentCell = parentId ? getCell(parentId) : getDefaultParent(); + const descendants = parentCell.filterDescendants(filter); expect(descendants).toHaveLength(elementsNumber); }; export const expectPoolsInModel = (pools: number): void => { - expectElementsInModel(undefined, pools, (cell: mxCell): boolean => { - return cell.style?.startsWith(ShapeBpmnElementKind.POOL); + expectElementsInModel(undefined, pools, (cell: Cell): boolean => { + return cell != getDefaultParent() && (cell.style as BPMNCellStyle).bpmn.kind == ShapeBpmnElementKind.POOL; }); }; export const expectShapesInModel = (parentId: string, shapesNumber: number): void => { - expectElementsInModel(parentId, shapesNumber, (cell: mxCell): boolean => { + expectElementsInModel(parentId, shapesNumber, (cell: Cell): boolean => { return cell.getId() != parentId && cell.isVertex(); }); }; @@ -244,7 +252,7 @@ export const expectTotalShapesInModel = (shapesNumber: number): void => { }; export const expectEdgesInModel = (parentId: string, edgesNumber: number): void => { - expectElementsInModel(parentId, edgesNumber, (cell: mxCell): boolean => { + expectElementsInModel(parentId, edgesNumber, (cell: Cell): boolean => { return cell.isEdge(); }); }; diff --git a/test/integration/matchers/matcher-utils.ts b/test/integration/matchers/matcher-utils.ts index b86241c315..f76556aac9 100644 --- a/test/integration/matchers/matcher-utils.ts +++ b/test/integration/matchers/matcher-utils.ts @@ -14,18 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. */ +import type { Cell, Geometry } from '@maxgraph/core'; + +import MatcherContext = jest.MatcherContext; +import CustomMatcherResult = jest.CustomMatcherResult; + import type { ExpectedEdgeModelElement, ExpectedFont, ExpectedShapeModelElement, HorizontalAlign, VerticalAlign } from '../helpers/model-expect'; import { bpmnVisualization } from '../helpers/model-expect'; -import type { mxCell, mxGeometry, StyleMap } from 'mxgraph'; import type { Opacity } from '@lib/component/registry'; -import type { MxGraphCustomOverlay, MxGraphCustomOverlayStyle } from '@lib/component/mxgraph/overlay/custom-overlay'; +import type { MxGraphCustomOverlay, MxGraphCustomOverlayStyle } from '../../../src/component/mxgraph/overlay/custom-overlay'; import { getFontStyleValue as computeFontStyleValue } from '@lib/component/mxgraph/renderer/StyleComputer'; -import { BpmnStyleIdentifier } from '@lib/component/mxgraph/style'; import { Font } from '@lib/model/bpmn/internal/Label'; -import MatcherContext = jest.MatcherContext; -import CustomMatcherResult = jest.CustomMatcherResult; +import type { BPMNCellStyle } from '../../../src/component/mxgraph/renderer/StyleComputer'; + +// TODO magraph@0.1.0 remove this type +export type ExpectedStateStyle = BPMNCellStyle; -// Used for received view state, computed resolved style and expected style. +// TODO rebase make it work export interface BpmnCellStyle extends StyleMap { opacity: Opacity; verticalAlign?: VerticalAlign; @@ -53,9 +58,9 @@ export interface BpmnCellStyle extends StyleMap { export interface ExpectedCell { value?: string; - geometry?: mxGeometry; + geometry?: Geometry; /** the Cell style property or a jest expect using a regexp. */ - styleRawFromModelOrJestExpect?: string; + styleRawFromModelOrJestExpect?: BPMNCellStyle; /** * The style of the Cell in the model where all properties have been resolved by also applying properties coming from the referenced styles. * @@ -91,7 +96,7 @@ export function buildCellMatcher( expected: R, cellKind: string, buildExpectedCell: (received: string, expected: R) => ExpectedCell, - buildReceivedCell: (cell: mxCell) => ExpectedCell, + buildReceivedCell: (cell: Cell) => ExpectedCell, ): CustomMatcherResult { const options = { isNot: matcherContext.isNot, @@ -135,6 +140,7 @@ export function getFontStyleValue(expectedFont: ExpectedFont): number { export function buildExpectedCellStyleWithCommonAttributes(expectedModelElt: ExpectedEdgeModelElement | ExpectedShapeModelElement): BpmnCellStyle { const font = expectedModelElt.font; + // Here are the default values as defined in StyleDefault return { opacity: expectedModelElt.opacity, strokeColor: expectedModelElt.stroke?.color ?? 'Black', @@ -148,9 +154,13 @@ export function buildExpectedCellStyleWithCommonAttributes(expectedModelElt: Exp fontOpacity: expectedModelElt.font?.opacity, // custom bpmn-visualization extraCssClasses: expectedModelElt.extraCssClasses, + // TODO magraph@0.1.0 set basic information when removing the custom processing in buildReceivedStateStyle + // bpmn: { xxxx }, }; } +// TODO magraph@0.1.0 why building ExpectedStateStyle now maxGraph manage style in object. We should use 'stateStyle' directly (and remove this function) +// TODO magraph@0.1.0 rename into 'receivedStateStyle' (in master branch) /** * This function really gets style from the state of the cell in the graph view. * The functions that return BpmnCellStyle objects are in fact, returning a computed style by using the style properties from the model augmented with the properties resolved @@ -159,7 +169,7 @@ export function buildExpectedCellStyleWithCommonAttributes(expectedModelElt: Exp * @param cell The Cell to consider to get the style in the state view * @param bv The instance of BpmnVisualization under test */ -export function buildReceivedViewStateStyle(cell: mxCell, bv = bpmnVisualization): BpmnCellStyle { +export function buildReceivedViewStateStyle(cell: Cell, bv = bpmnVisualization): BpmnCellStyle { return toBpmnStyle(bv.graph.getView().getState(cell).style, cell.edge); } @@ -173,7 +183,7 @@ export function buildReceivedViewStateStyle(cell: mxCell, bv = bpmnVisualization * @param cell The Cell to consider for the computation of the resolved style. * @param bv The instance of BpmnVisualization under test */ -export function buildReceivedResolvedModelCellStyle(cell: mxCell, bv = bpmnVisualization): BpmnCellStyle { +export function buildReceivedResolvedModelCellStyle(cell: Cell, bv = bpmnVisualization): BpmnCellStyle { return toBpmnStyle(bv.graph.getCellStyle(cell), cell.edge); } @@ -205,6 +215,9 @@ function toBpmnStyle(rawStyle: StyleMap, isEdge: boolean): BpmnCellStyle { style.endSize = rawStyle.endSize; } else { style.shape = rawStyle.shape; + // TODO rebase horizontal check + // why is it needed in maxgraph , explain why + // stateStyle.horizontal && (expectedStateStyle.horizontal = stateStyle.horizontal); style.horizontal = rawStyle.horizontal; style.swimlaneFillColor = rawStyle.swimlaneFillColor; style.fillOpacity = rawStyle.fillOpacity; @@ -212,9 +225,11 @@ function toBpmnStyle(rawStyle: StyleMap, isEdge: boolean): BpmnCellStyle { return style; } -function buildBaseReceivedExpectedCell(cell: mxCell): ExpectedCell { +function buildBaseReceivedExpectedCell(cell: Cell): ExpectedCell { return { value: cell.value, + // TODO rebase make the style work + style: cell.style as BPMNCellStyle, styleRawFromModelOrJestExpect: cell.style, styleResolvedFromModel: buildReceivedResolvedModelCellStyle(cell), styleViewState: buildReceivedViewStateStyle(cell), @@ -228,8 +243,9 @@ function buildBaseReceivedExpectedCell(cell: mxCell): ExpectedCell { export function buildReceivedCellWithCommonAttributes(cell: mxCell): ExpectedCell { const receivedCell = buildBaseReceivedExpectedCell(cell); + // the maxGraph API returns an empty array when there is no overlays const cellOverlays = bpmnVisualization.graph.getCellOverlays(cell) as MxGraphCustomOverlay[]; - if (cellOverlays) { + if (cellOverlays.length > 0) { receivedCell.overlays = cellOverlays.map(cellOverlay => ({ label: cellOverlay.label, horizontalAlign: cellOverlay.align, @@ -251,6 +267,6 @@ export function buildReceivedCellWithCommonAttributes(cell: mxCell): ExpectedCel return receivedCell; } -export function getCell(received: string): mxCell { +export function getCell(received: string): Cell { return bpmnVisualization.graph.model.getCell(received); } diff --git a/test/integration/matchers/toBeCell/index.ts b/test/integration/matchers/toBeCell/index.ts index 7e7139b46b..f8ad95bc51 100644 --- a/test/integration/matchers/toBeCell/index.ts +++ b/test/integration/matchers/toBeCell/index.ts @@ -20,7 +20,7 @@ import MatcherContext = jest.MatcherContext; import CustomMatcherResult = jest.CustomMatcherResult; import type { ExpectedCellWithGeometry } from '../../helpers/model-expect'; import { getDefaultParentId } from '../../helpers/model-expect'; -import type { mxCell } from 'mxgraph'; +import type { Cell } from '@maxgraph/core'; export function toBeCell(this: MatcherContext, received: string): CustomMatcherResult { const pass = getCell(received) ? true : false; @@ -30,7 +30,7 @@ export function toBeCell(this: MatcherContext, received: string): CustomMatcherR }; } -function buildReceivedCell(cell: mxCell): ExpectedCell { +function buildReceivedCell(cell: Cell): ExpectedCell { return { id: cell.id, parent: { id: cell.parent.id }, diff --git a/test/integration/matchers/toBeEdge/index.ts b/test/integration/matchers/toBeEdge/index.ts index 9b63049aec..3854aaa80a 100644 --- a/test/integration/matchers/toBeEdge/index.ts +++ b/test/integration/matchers/toBeEdge/index.ts @@ -14,13 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { BpmnCellStyle, ExpectedCell } from '../matcher-utils'; -import { buildCellMatcher, buildExpectedCellStyleWithCommonAttributes, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; -import { FlowKind, MessageVisibleKind } from '@lib/model/bpmn/internal'; -import type { ExpectedEdgeModelElement, ExpectedSequenceFlowModelElement } from '../../helpers/model-expect'; +import type { ShapeValue } from '@maxgraph/core'; + +import type { ExpectedCell, ExpectedStateStyle } from '../matcher-utils'; +import { buildCellMatcher, buildCommonExpectedStateStyle, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; +import { AssociationDirectionKind, FlowKind, MessageVisibleKind, SequenceFlowKind } from '../../../../src/model/bpmn/internal'; +import type { ExpectedAssociationFlowModelElement, ExpectedEdgeModelElement, ExpectedSequenceFlowModelElement } from '../../helpers/model-expect'; import { getDefaultParentId } from '../../helpers/model-expect'; import { BpmnStyleIdentifier } from '@lib/component/mxgraph/style'; -import { mxConstants } from '@lib/component/mxgraph/initializer'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; import MatcherContext = jest.MatcherContext; import CustomMatcherResult = jest.CustomMatcherResult; @@ -44,25 +46,38 @@ function buildExpectedMsgFlowIconCellStyle(expectedModel: ExpectedEdgeModelEleme return style; } -function buildExpectedEdgeStylePropertyRegexp(expectedModel: ExpectedEdgeModelElement | ExpectedSequenceFlowModelElement): string { - let expectedStyle: string = expectedModel.kind; +function buildExpectedEdgeStylePropertyRegexp(expectedModel: ExpectedEdgeModelElement | ExpectedSequenceFlowModelElement | ExpectedAssociationFlowModelElement): BPMNCellStyle { + const style: BPMNCellStyle = { bpmn: {} }; + // TODO magraph@0.1.0 share with edge + style.baseStyleNames = [expectedModel.kind]; + style.bpmn.kind = expectedModel.kind; if ('sequenceFlowKind' in expectedModel) { - expectedStyle = expectedStyle + `;${(expectedModel as ExpectedSequenceFlowModelElement).sequenceFlowKind}`; + style.baseStyleNames.push((expectedModel as ExpectedSequenceFlowModelElement).sequenceFlowKind); + } + if ('associationDirectionKind' in expectedModel) { + style.baseStyleNames.push((expectedModel as ExpectedAssociationFlowModelElement).associationDirectionKind); } - return expectedStyle + '.*'; + + return style; } function buildExpectedCell(id: string, expectedModel: ExpectedEdgeModelElement | ExpectedSequenceFlowModelElement): ExpectedCell { + // TODO magraph@0.1.0 refactor, duplication with buildExpectedCell in shape matchers const parentId = expectedModel.parentId; const expectedCell: ExpectedCell = { id, - value: expectedModel.label, + value: expectedModel.label ?? null, // maxGraph now set to 'null', mxGraph set to 'undefined' + style: expect.objectContaining(buildExpectedStyle(expectedModel)), + // TODO rebase make style work styleRawFromModelOrJestExpect: expect.stringMatching(buildExpectedEdgeStylePropertyRegexp(expectedModel)), styleResolvedFromModel: buildExpectedEdgeCellStyle(expectedModel), styleViewState: buildExpectedEdgeCellStyle(expectedModel), edge: true, vertex: false, - parent: { id: parentId ? parentId : getDefaultParentId() }, + parent: { id: parentId ? parentId : getDefaultParentId() }, // TODO magraph@0.1.0 use ?? instead (in master branch) + state: { + style: buildExpectedStateStyle(expectedModel), + }, overlays: expectedModel.overlays, }; @@ -71,7 +86,14 @@ function buildExpectedCell(id: string, expectedModel: ExpectedEdgeModelElement | expectedCell.children = [ { id: `messageFlowIcon_of_${id}`, - value: undefined, + value: null, // maxGraph now set to 'null', mxGraph set to 'undefined' + // TODO rebase make the style check work + style: { + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + shape: BpmnStyleIdentifier.MESSAGE_FLOW_ICON, + // TODO magraph@0.1.0 duplicated logic to compute the 'isNonInitiating' property. Update the expectedModel to store a boolean instead of a string + bpmn: { isNonInitiating: expectedModel.messageVisibleKind === MessageVisibleKind.NON_INITIATING }, + }, styleRawFromModelOrJestExpect: expect.stringMatching( `shape=${BpmnStyleIdentifier.MESSAGE_FLOW_ICON};${BpmnStyleIdentifier.IS_INITIATING}=${expectedModel.messageVisibleKind == MessageVisibleKind.INITIATING}`, ), @@ -92,13 +114,18 @@ function buildEdgeMatcher(matcherName: string, matcherContext: MatcherContext, r } export function toBeSequenceFlow(this: MatcherContext, received: string, expected: ExpectedSequenceFlowModelElement): CustomMatcherResult { + // TODO maxgraph@0.1.0 migration - why is it needed? move to the master branch? + expected.sequenceFlowKind ??= SequenceFlowKind.NORMAL; return buildEdgeMatcher('toBeSequenceFlow', this, received, { ...expected, kind: FlowKind.SEQUENCE_FLOW, endArrow: 'blockThin' }); } export function toBeMessageFlow(this: MatcherContext, received: string, expected: ExpectedEdgeModelElement): CustomMatcherResult { - return buildEdgeMatcher('toBeMessageFlow', this, received, { ...expected, kind: FlowKind.MESSAGE_FLOW, startArrow: mxConstants.ARROW_OVAL, endArrow: 'blockThin' }); + // TODO maxgraph@0.1.0 migration - constant or type? + return buildEdgeMatcher('toBeMessageFlow', this, received, { ...expected, kind: FlowKind.MESSAGE_FLOW, startArrow: 'oval', endArrow: 'blockThin' }); } -export function toBeAssociationFlow(this: MatcherContext, received: string, expected: ExpectedEdgeModelElement): CustomMatcherResult { +export function toBeAssociationFlow(this: MatcherContext, received: string, expected: ExpectedAssociationFlowModelElement): CustomMatcherResult { + // TODO maxgraph@0.1.0 migration - why is it needed? move to the master branch? + expected.associationDirectionKind ??= AssociationDirectionKind.NONE; return buildEdgeMatcher('toBeAssociationFlow', this, received, { ...expected, kind: FlowKind.ASSOCIATION_FLOW }); } diff --git a/test/integration/matchers/toBeShape/index.ts b/test/integration/matchers/toBeShape/index.ts index 4e1cf5acf2..914c262f48 100644 --- a/test/integration/matchers/toBeShape/index.ts +++ b/test/integration/matchers/toBeShape/index.ts @@ -14,6 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ +import type { ShapeValue } from '@maxgraph/core'; + +import type { ExpectedCell, ExpectedStateStyle } from '../matcher-utils'; +import { buildCellMatcher, buildCommonExpectedStateStyle, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; + import type { BpmnCellStyle, ExpectedCell } from '../matcher-utils'; import { buildCellMatcher, buildExpectedCellStyleWithCommonAttributes, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; import type { @@ -26,10 +31,10 @@ import type { ExpectedSubProcessModelElement, } from '../../helpers/model-expect'; import { getDefaultParentId } from '../../helpers/model-expect'; -import { ShapeBpmnElementKind, ShapeBpmnMarkerKind, ShapeBpmnSubProcessKind } from '@lib/model/bpmn/internal'; -import { mxConstants } from '@lib/component/mxgraph/initializer'; +import { ShapeBpmnElementKind, ShapeBpmnEventBasedGatewayKind, ShapeBpmnMarkerKind, ShapeBpmnSubProcessKind } from '@lib/model/bpmn/internal'; import MatcherContext = jest.MatcherContext; import CustomMatcherResult = jest.CustomMatcherResult; +import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; function expectedStrokeWidth(kind: ShapeBpmnElementKind): number { return [ @@ -66,6 +71,14 @@ export function buildExpectedShapeCellStyle(expectedModel: ExpectedShapeModelEle style.align = expectedModel.align ?? 'center'; style.strokeWidth = style.strokeWidth ?? expectedStrokeWidth(expectedModel.kind); + // TODO rebase - adapt + const expectedStateStyle = buildCommonExpectedStateStyle(expectedModel); + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + expectedStateStyle.shape = ((!expectedModel.styleShape ? expectedModel.kind : expectedModel.styleShape)); + expectedStateStyle.verticalAlign = expectedModel.verticalAlign ? expectedModel.verticalAlign : 'middle'; + expectedStateStyle.align = expectedModel.align ? expectedModel.align : 'center'; + expectedStateStyle.strokeWidth = expectedStrokeWidth(expectedModel.kind); + style.fillColor = expectedModel.fill?.color ?? ([ShapeBpmnElementKind.LANE, ShapeBpmnElementKind.POOL, ShapeBpmnElementKind.TEXT_ANNOTATION, ShapeBpmnElementKind.GROUP].includes(expectedModel.kind) @@ -79,9 +92,15 @@ export function buildExpectedShapeCellStyle(expectedModel: ExpectedShapeModelEle // ignore marker order, which is only relevant when rendering the shape (it has its own order algorithm) 'markers' in expectedModel && (style.markers = expectedModel.markers.sort()); + // TODO rebase - adapt + // TODO magraph@0.1.0 explain why this is needed. Can we move this addition to the master branch + if ('isHorizontal' in expectedModel) { + expectedStateStyle.horizontal = expectedModel.isHorizontal; + } return style; } +// TODO magraph@0.1.0 Here we don't check all properties. Why? function buildExpectedShapeStylePropertyRegexp( expectedModel: | ExpectedShapeModelElement @@ -91,39 +110,51 @@ function buildExpectedShapeStylePropertyRegexp( | ExpectedBoundaryEventModelElement | ExpectedEventBasedGatewayModelElement | ExpectedCallActivityModelElement, -): string { - let expectedStyle: string = expectedModel.kind; +): BPMNCellStyle { + const style: BPMNCellStyle = { bpmn: {} }; + // TODO magraph@0.1.0 share with edge + style.baseStyleNames = [expectedModel.kind]; + style.bpmn.kind = expectedModel.kind; + if ('eventDefinitionKind' in expectedModel) { - expectedStyle = expectedStyle + `.*bpmn.eventDefinitionKind=${expectedModel.eventDefinitionKind}`; + style.bpmn.eventDefinitionKind = expectedModel.eventDefinitionKind; } if ('subProcessKind' in expectedModel) { - expectedStyle = expectedStyle + `.*bpmn.subProcessKind=${expectedModel.subProcessKind}`; + style.bpmn.subProcessKind = expectedModel.subProcessKind; } if ('globalTaskKind' in expectedModel) { - expectedStyle = expectedStyle + `.*bpmn.globalTaskKind=${expectedModel.globalTaskKind}`; + style.bpmn.globalTaskKind = expectedModel.globalTaskKind; } if (expectedModel.isInstantiating !== undefined) { - expectedStyle = expectedStyle + `.*bpmn.isInstantiating=${expectedModel.isInstantiating}`; + style.bpmn.isInstantiating = expectedModel.isInstantiating; } - if (expectedModel.markers?.length > 0) { - // There is no guaranteed order, so testing the list of markers with a string is not practical. Markers are therefore checked with BpmnStyle.markers. - // Here, we check only that the markers are placed in the style. - expectedStyle = expectedStyle + `.*bpmn.markers=*`; + // if (expectedModel.markers?.length > 0) { + // // There is no guaranteed order, so testing the list of markers with a string is not practical. Markers are therefore checked with BpmnStyle.markers. + // // Here, we check only that the markers are placed in the style. + // expectedStyle = expectedStyle + `.*bpmn.markers=*`; + // } + // TODO rebase ignore markers order + if (expectedModel.markers) { + style.bpmn.markers = expectedModel.markers; } if ('isInterrupting' in expectedModel) { - expectedStyle = expectedStyle + `.*bpmn.isInterrupting=${expectedModel.isInterrupting}`; + style.bpmn.isInterrupting = expectedModel.isInterrupting; } if ('gatewayKind' in expectedModel) { - expectedStyle = expectedStyle + `.*bpmn.gatewayKind=${expectedModel.gatewayKind}`; + style.bpmn.gatewayKind = expectedModel.gatewayKind; } - return expectedStyle + '.*'; + + return style; } function buildExpectedCell(id: string, expectedModel: ExpectedShapeModelElement): ExpectedCell { + // TODO magraph@0.1.0 refactor, duplication with buildExpectedCell in edge matchers const parentId = expectedModel.parentId; return { id, - value: expectedModel.label, + value: expectedModel.label ?? null, // maxGraph now set to 'null', mxGraph set to 'undefined' + style: expect.objectContaining(buildExpectedStyle(expectedModel)), + // TODO rebase make it work styleRawFromModelOrJestExpect: expect.stringMatching(buildExpectedShapeStylePropertyRegexp(expectedModel)), styleResolvedFromModel: buildExpectedShapeCellStyle(expectedModel), styleViewState: buildExpectedShapeCellStyle(expectedModel), @@ -146,6 +177,13 @@ function buildContainerMatcher(matcherName: string, matcherContext: MatcherConte }); } +function buildContainerMatcher(matcherName: string, matcherContext: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + 'isHorizontal' in expected && (expected.isHorizontal = expected.isHorizontal); + + // TODO magraph@0.1.0 maxGraph "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE + return buildShapeMatcher(matcherName, matcherContext, received, { ...expected, styleShape: 'swimlane' }); +} + export function toBePool(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { return buildContainerMatcher('toBePool', this, received, { ...expected, kind: ShapeBpmnElementKind.POOL }); } @@ -155,10 +193,15 @@ export function toBeLane(this: MatcherContext, received: string, expected: Expec } export function toBeCallActivity(this: MatcherContext, received: string, expected: ExpectedCallActivityModelElement): CustomMatcherResult { + // TODO magraph@0.1.0 introduce common code for activity kinds + expected.markers ??= []; return buildShapeMatcher('toBeCallActivity', this, received, { ...expected, kind: ShapeBpmnElementKind.CALL_ACTIVITY }); } export function toBeSubProcess(this: MatcherContext, received: string, expected: ExpectedSubProcessModelElement): CustomMatcherResult { + // TODO rebase review markers management + // TODO magraph@0.1.0 introduce common code for activity kinds + // expected.markers ??= []; if (expected.subProcessKind == ShapeBpmnSubProcessKind.AD_HOC) { expected.markers ??= []; expected.markers.push(ShapeBpmnMarkerKind.ADHOC); @@ -167,34 +210,50 @@ export function toBeSubProcess(this: MatcherContext, received: string, expected: } export function toBeTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + // TODO magraph@0.1.0 introduce common code for activity kinds + expected.markers ??= []; return buildShapeMatcher('toBeTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK }); } export function toBeServiceTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + // TODO magraph@0.1.0 introduce common code for activity kinds + expected.markers ??= []; return buildShapeMatcher('toBeServiceTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_SERVICE }); } export function toBeUserTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + // TODO magraph@0.1.0 introduce common code for activity kinds + expected.markers ??= []; return buildShapeMatcher('toBeUserTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_USER }); } export function toBeReceiveTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + // TODO magraph@0.1.0 introduce common code for activity kinds + expected.markers ??= []; return buildShapeMatcher('toBeReceiveTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_RECEIVE }); } export function toBeSendTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + // TODO magraph@0.1.0 introduce common code for activity kinds + expected.markers ??= []; return buildShapeMatcher('toBeSendTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_SEND }); } export function toBeManualTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + // TODO magraph@0.1.0 introduce common code for activity kinds + expected.markers ??= []; return buildShapeMatcher('toBeManualTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_MANUAL }); } export function toBeScriptTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + // TODO magraph@0.1.0 introduce common code for activity kinds + expected.markers ??= []; return buildShapeMatcher('toBeScriptTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_SCRIPT }); } export function toBeBusinessRuleTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + // TODO magraph@0.1.0 introduce common code for activity kinds + expected.markers ??= []; return buildShapeMatcher('toBeBusinessRuleTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_BUSINESS_RULE }); } @@ -227,6 +286,7 @@ function buildGatewayMatcher(matcherName: string, matcherContext: MatcherContext } export function toBeEventBasedGateway(this: MatcherContext, received: string, expected: ExpectedEventBasedGatewayModelElement): CustomMatcherResult { + expected.gatewayKind ??= ShapeBpmnEventBasedGatewayKind.None; return buildGatewayMatcher('toBeEventBasedGateway', this, received, { ...expected, kind: ShapeBpmnElementKind.GATEWAY_EVENT_BASED }); } diff --git a/test/integration/mxGraph.model.bpmn.elements.test.ts b/test/integration/mxGraph.model.bpmn.elements.test.ts index b7367b7185..b662adba7d 100644 --- a/test/integration/mxGraph.model.bpmn.elements.test.ts +++ b/test/integration/mxGraph.model.bpmn.elements.test.ts @@ -14,6 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ +import type { ArrowType } from '@maxgraph/core'; +import { Point, Geometry } from '@maxgraph/core'; + import { MarkerIdentifier, MessageVisibleKind, @@ -30,14 +33,11 @@ import { bpmnVisualization, expectEdgesInModel, expectPoolsInModel, - expectShapesInModel, expectTotalEdgesInModel, + expectShapesInModel, expectTotalShapesInModel, getDefaultParentId, } from './helpers/model-expect'; -import { mxgraph, mxConstants, mxPoint } from '@lib/component/mxgraph/initializer'; - -const mxGeometry = mxgraph.mxGeometry; describe('mxGraph model - BPMN elements', () => { describe('BPMN elements should be available in the mxGraph model', () => { @@ -56,6 +56,11 @@ describe('mxGraph model - BPMN elements', () => { describe('BPMN containers', () => { const baseShapeModelElement: ExpectedShapeModelElement = { isSwimLaneLabelHorizontal: false }; + // TODO rebase update test for maxGraph + // TODO magraph@0.1.0 change isHorizontal value for maxGraph, but the logic is probably wrong in 'master' (convert integer into boolean) + // const minimalPoolModelElement: ExpectedShapeModelElement = { + // parentId: getDefaultParentId(), + // }; it('pool', () => { expect('participant_1_id').toBePool({ ...baseShapeModelElement, label: 'Pool 1' }); expect('participant_2_id').toBePool(baseShapeModelElement); @@ -1046,6 +1051,7 @@ describe('mxGraph model - BPMN elements', () => { it('Collapsed', () => { expect('collapsed_call_activity_id').toBeCallActivity({ label: 'Collapsed Call Activity', + markers: [ShapeBpmnMarkerKind.EXPAND], parentId: 'participant_1_id', markers: [ShapeBpmnMarkerKind.EXPAND], verticalAlign: 'top', @@ -1471,7 +1477,8 @@ describe('mxGraph model - BPMN elements', () => { it('sequence flows', () => { expect('default_sequence_flow_id').toBeSequenceFlow({ sequenceFlowKind: SequenceFlowKind.DEFAULT, - startArrow: MarkerIdentifier.ARROW_DASH, + // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + startArrow: (MarkerIdentifier.ARROW_DASH), parentId: 'participant_1_id', font: expectedBoldFont, }); @@ -1482,7 +1489,7 @@ describe('mxGraph model - BPMN elements', () => { }); expect('conditional_sequence_flow_from_activity_id').toBeSequenceFlow({ sequenceFlowKind: SequenceFlowKind.CONDITIONAL_FROM_ACTIVITY, - startArrow: mxConstants.ARROW_DIAMOND_THIN, + startArrow: 'diamondThin', parentId: 'participant_1_id', verticalAlign: 'bottom', }); @@ -1563,12 +1570,12 @@ describe('mxGraph model - BPMN elements', () => { expect('Participant_1').toBeCellWithParentAndGeometry({ // unchanged as this is a pool, coordinates are the ones from the bpmn source - geometry: new mxGeometry(160, 80, 900, 180), + geometry: new Geometry(160, 80, 900, 180), }); expect('StartEvent_1').toBeCellWithParentAndGeometry({ parentId: 'Participant_1', - geometry: new mxGeometry( + geometry: new Geometry( 150, // absolute coordinates: parent 160, cell 310 80, // absolute coordinates: parent 80, cell 160 40, // unchanged as no transformation on size @@ -1576,20 +1583,20 @@ describe('mxGraph model - BPMN elements', () => { ), }); - const sequenceFlowGeometry = new mxGeometry(0, 0, 0, 0); - sequenceFlowGeometry.points = [ - new mxPoint(190, 100), // absolute coordinates: parent x="160" y="80", cell x="350" y="180" - new mxPoint(350, 100), // absolute coordinates: parent x="160" y="80", cell x="510" y="180" + const sequenceFlowMxGeometry = new Geometry(0, 0, 0, 0); + sequenceFlowMxGeometry.points = [ + new Point(190, 100), // absolute coordinates: parent x="160" y="80", cell x="350" y="180" + new Point(350, 100), // absolute coordinates: parent x="160" y="80", cell x="510" y="180" ]; expect('SequenceFlow_id').toBeCellWithParentAndGeometry({ parentId: 'Participant_1', geometry: sequenceFlowGeometry, }); - const messageFlowGeometry = new mxGeometry(0, 0, 0, 0); - messageFlowGeometry.points = [ - new mxPoint(334, 260), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="260" - new mxPoint(334, 342), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="342" + const messageFlowMxGeometry = new Geometry(0, 0, 0, 0); + messageFlowMxGeometry.points = [ + new Point(334, 260), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="260" + new Point(334, 342), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="342" ]; expect('MessageFlow_1').toBeCellWithParentAndGeometry({ geometry: messageFlowGeometry, @@ -1601,12 +1608,12 @@ describe('mxGraph model - BPMN elements', () => { expect('Participant_1').toBeCellWithParentAndGeometry({ // unchanged as this is a pool, coordinates are the ones from the bpmn source - geometry: new mxGeometry(160, 80, 900, 400), + geometry: new Geometry(160, 80, 900, 400), }); expect('Lane_1_1').toBeCellWithParentAndGeometry({ parentId: 'Participant_1', - geometry: new mxGeometry( + geometry: new Geometry( 30, // absolute coordinates: parent 160, cell 190 0, // absolute coordinates: parent 80, cell 80 870, // unchanged as no transformation on size @@ -1616,7 +1623,7 @@ describe('mxGraph model - BPMN elements', () => { expect('StartEvent_1').toBeCellWithParentAndGeometry({ parentId: 'Lane_1_1', - geometry: new mxGeometry( + geometry: new Geometry( 120, // absolute coordinates: parent 190, cell 310 80, // absolute coordinates: parent 80, cell 160 40, // unchanged as no transformation on size @@ -1626,7 +1633,7 @@ describe('mxGraph model - BPMN elements', () => { expect('Lane_1_847987').not.toBeCellWithParentAndGeometry({ parentId: 'Participant_1', - geometry: new mxGeometry( + geometry: new Geometry( 30, // absolute coordinates: parent 160, cell 190 200, // absolute coordinates: parent 80, cell 280 870, // unchanged as no transformation on size @@ -1634,20 +1641,20 @@ describe('mxGraph model - BPMN elements', () => { ), }); - const sequenceFlowMxGeometry = new mxGeometry(0, 0, 0, 0); + const sequenceFlowMxGeometry = new Geometry(0, 0, 0, 0); sequenceFlowMxGeometry.points = [ - new mxPoint(160, 100), // absolute coordinates: parent x="190" y="80", cell x="350" y="180" - new mxPoint(320, 100), // absolute coordinates: parent x="190" y="80", cell x="510" y="180" + new Point(160, 100), // absolute coordinates: parent x="190" y="80", cell x="350" y="180" + new Point(320, 100), // absolute coordinates: parent x="190" y="80", cell x="510" y="180" ]; expect('SequenceFlow_id').toBeCellWithParentAndGeometry({ parentId: 'Lane_1_1', geometry: sequenceFlowMxGeometry, }); - const messageFlowMxGeometry = new mxGeometry(0, 0, 0, 0); + const messageFlowMxGeometry = new Geometry(0, 0, 0, 0); messageFlowMxGeometry.points = [ - new mxPoint(334, 480), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="480" - new mxPoint(334, 632), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="632" + new Point(334, 480), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="480" + new Point(334, 632), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="632" ]; expect('MessageFlow_1').toBeCellWithParentAndGeometry({ geometry: messageFlowMxGeometry, @@ -1659,6 +1666,8 @@ describe('mxGraph model - BPMN elements', () => { // pool const baseShapeModelElement: ExpectedShapeModelElement = { isSwimLaneLabelHorizontal: true }; + // TODO rebase update test for maxGraph + // const minimalPoolModelElement: ExpectedShapeModelElement = { isHorizontal: true, parentId: getDefaultParentId() }; expect('Participant_Vertical_With_Lanes').toBePool({ ...baseShapeModelElement, label: 'Vertical Pool With Lanes' }); // lane @@ -1678,7 +1687,7 @@ describe('mxGraph model - BPMN elements', () => { expect('StartEvent_1').toBeCellWithParentAndGeometry({ parentId: defaultParentId, - geometry: new mxGeometry( + geometry: new Geometry( 156.10001, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -1690,11 +1699,11 @@ describe('mxGraph model - BPMN elements', () => { expect('Activity_1').toBeCellWithParentAndGeometry({ parentId: defaultParentId, - geometry: new mxGeometry(250, 59, 100, 80), + geometry: new Geometry(250, 59, 100, 80), }); - const geometry = new mxGeometry(412, 81, 36, 36); - geometry.offset = new mxPoint(4.16e25, 1.24000000003e29); + const geometry = new Geometry(412, 81, 36, 36); + geometry.offset = new Point(4.16e25, 1.24000000003e29); expect('EndEvent_1').toBeCellWithParentAndGeometry({ parentId: defaultParentId, geometry: geometry, @@ -1702,19 +1711,25 @@ describe('mxGraph model - BPMN elements', () => { }); it('Parse a diagram with numbers not parsable as number', () => { - bpmnVisualization.load(readFileSync('../fixtures/bpmn/xml-parsing/special/simple-start-task-end_numbers_not_parsable_as_number.bpmn')); - - expect('Activity_1').toBeCellWithParentAndGeometry({ - parentId: defaultParentId, - geometry: new mxGeometry( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore malformed source, conversion result - 'not_a_number0', // from 'not_a_number' - 'not a number too0', // from 'not a number too' - -100, - -80, - ), - }); + // TODO magraph@0.1.0 change in maxGraph, throw 'Error: Invalid x supplied'. bpmn-visualization should handle it + // capture the error and rethrow it with a convenient + // OR validate the values during parsing + + expect(() => bpmnVisualization.load(readFileSync('../fixtures/bpmn/xml-parsing/special/simple-start-task-end_numbers_not_parsable_as_number.bpmn'))).toThrow( + `Invalid x supplied.`, + ); + // bpmnVisualization.load(readFileSync('../fixtures/bpmn/xml-parsing/special/simple-start-task-end_numbers_not_parsable_as_number.bpmn')); + // expect('Activity_1').toBeCellWithParentAndGeometry({ + // parentId: defaultParentId, + // geometry: new Geometry( + // // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // // @ts-ignore malformed source, conversion result + // 'not_a_number0', // from 'not_a_number' + // 'not a number too0', // from 'not a number too' + // -100, + // -80, + // ), + // }); }); }); diff --git a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts index 599620705e..514784c6c5 100644 --- a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts +++ b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts @@ -17,6 +17,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import type { BPMNCellStyle } from '../../../../../src/component/mxgraph/renderer/StyleComputer'; import StyleComputer from '@lib/component/mxgraph/renderer/StyleComputer'; import Shape from '@lib/model/bpmn/internal/shape/Shape'; import ShapeBpmnElement, { @@ -31,6 +32,7 @@ import ShapeBpmnElement, { import type { BpmnEventKind, GlobalTaskKind } from '@lib/model/bpmn/internal'; import { AssociationDirectionKind, + FlowKind, MessageVisibleKind, SequenceFlowKind, ShapeBpmnCallActivityKind, @@ -125,25 +127,28 @@ function newAssociationFlow(kind: AssociationDirectionKind): AssociationFlow { return new AssociationFlow('id', 'name', undefined, undefined, kind); } +// TODO magraph@0.1.0 order properties alphabetically in expected style + describe('Style Computer', () => { // use a shared instance to check that there is no state stored in the implementation const styleComputer = new StyleComputer(); // shortcut as the current computeStyle implementation requires to pass the BPMN label bounds as extra argument - function computeStyle(bpmnCell: Shape | Edge): string { + function computeStyle(bpmnCell: Shape | Edge): BPMNCellStyle { return styleComputer.computeStyle(bpmnCell, bpmnCell.label?.bounds); } describe('compute style - shape label', () => { it('compute style of shape with no label', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.TASK_USER)); - expect(computeStyle(shape)).toBe('userTask'); + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['userTask'], bpmn: { kind: ShapeBpmnElementKind.TASK_USER } }); }); it('compute style of shape with a no font label', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.EVENT_END), undefined, new Label(undefined, undefined)); - expect(computeStyle(shape)).toBe('endEvent'); + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['endEvent'], bpmn: { kind: ShapeBpmnElementKind.EVENT_END } }); }); + it('compute style of shape with label including bold font', () => { const shape = new Shape( 'id', @@ -151,44 +156,95 @@ describe('Style Computer', () => { undefined, new Label(toFont({ name: 'Courier', size: 9, isBold: true }), undefined), ); - expect(computeStyle(shape)).toBe('exclusiveGateway;fontFamily=Courier;fontSize=9;fontStyle=1'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['exclusiveGateway'], + fontFamily: 'Courier', + fontSize: 9, + fontStyle: 1, + bpmn: { kind: ShapeBpmnElementKind.GATEWAY_EXCLUSIVE }, + }); }); it('compute style of shape with label including italic font', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH), undefined, new Label(toFont({ name: 'Arial', isItalic: true }), undefined)); - expect(computeStyle(shape)).toBe('intermediateCatchEvent;fontFamily=Arial;fontStyle=2'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['intermediateCatchEvent'], + fontFamily: 'Arial', + fontStyle: 2, + bpmn: { kind: ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH }, + }); }); it('compute style of shape with label including bold/italic font', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW), undefined, new Label(toFont({ isBold: true, isItalic: true }), undefined)); - expect(computeStyle(shape)).toBe('intermediateThrowEvent;fontStyle=3'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['intermediateThrowEvent'], + fontStyle: 3, + bpmn: { kind: ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW }, + }); + }); + + it('compute style of shape with label including font family only', () => { + const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.TASK_SCRIPT), undefined, new Label(toFont({ name: 'Roboto' }), undefined)); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['scriptTask'], + fontFamily: 'Roboto', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + bpmn: { kind: ShapeBpmnElementKind.TASK_SCRIPT }, + }); }); it('compute style of shape with label bounds', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.CALL_ACTIVITY), undefined, new Label(undefined, new Bounds(40, 200, 80, 140))); - expect(computeStyle(shape)).toBe('callActivity;verticalAlign=top;align=center;labelWidth=81;labelPosition=ignore;verticalLabelPosition=middle'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['callActivity'], + align: 'center', + verticalAlign: 'top', + labelWidth: 81, + // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator + // expect(computeStyle(shape)).toBe('callActivity;verticalAlign=top;align=center;labelWidth=81;labelPosition=ignore;verticalLabelPosition=middle'); + labelPosition: 'left', + verticalLabelPosition: 'top', + // end of fixme + bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY }, + }); }); }); describe('compute style - edge label', () => { it('compute style of edge with no label', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.CONDITIONAL_FROM_GATEWAY)); - expect(computeStyle(edge)).toBe('sequenceFlow;conditional_from_gateway'); + expect(computeStyle(edge)).toStrictEqual({ + baseStyleNames: ['sequenceFlow', 'conditional_from_gateway'], + bpmn: { kind: FlowKind.SEQUENCE_FLOW }, + }); }); it('compute style of edge with a no font label', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.NORMAL), undefined, new Label(undefined, undefined)); - expect(computeStyle(edge)).toBe('sequenceFlow;normal'); + expect(computeStyle(edge)).toStrictEqual({ + baseStyleNames: ['sequenceFlow', 'normal'], + bpmn: { kind: FlowKind.SEQUENCE_FLOW }, + }); }); it('compute style of edge with label including strike-through font', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.CONDITIONAL_FROM_ACTIVITY), undefined, new Label(toFont({ size: 14.2, isStrikeThrough: true }), undefined)); - expect(computeStyle(edge)).toBe('sequenceFlow;conditional_from_activity;fontSize=14.2;fontStyle=8'); + expect(computeStyle(edge)).toStrictEqual({ + baseStyleNames: ['sequenceFlow', 'conditional_from_activity'], + fontSize: 14.2, + fontStyle: 8, + bpmn: { kind: FlowKind.SEQUENCE_FLOW }, + }); }); it('compute style of edge with label including underline font', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.DEFAULT), undefined, new Label(toFont({ isUnderline: true }), undefined)); - expect(computeStyle(edge)).toBe('sequenceFlow;default;fontStyle=4'); + expect(computeStyle(edge)).toStrictEqual({ + baseStyleNames: ['sequenceFlow', 'default'], + fontStyle: 4, + bpmn: { kind: FlowKind.SEQUENCE_FLOW }, + }); }); it('compute style of edge with label including bold/italic/strike-through/underline font', () => { @@ -198,12 +254,23 @@ describe('Style Computer', () => { undefined, new Label(toFont({ isBold: true, isItalic: true, isStrikeThrough: true, isUnderline: true }), undefined), ); - expect(computeStyle(edge)).toBe('sequenceFlow;normal;fontStyle=15'); + expect(computeStyle(edge)).toStrictEqual({ + baseStyleNames: ['sequenceFlow', 'normal'], + fontStyle: 15, + bpmn: { kind: FlowKind.SEQUENCE_FLOW }, + }); }); it('compute style of edge with label bounds', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.NORMAL), undefined, new Label(toFont({ name: 'Helvetica' }), new Bounds(20, 20, 30, 120))); - expect(computeStyle(edge)).toBe('sequenceFlow;normal;fontFamily=Helvetica;verticalAlign=top;align=center'); + expect(computeStyle(edge)).toStrictEqual({ + baseStyleNames: ['sequenceFlow', 'normal'], + fontFamily: 'Helvetica', + align: 'center', + verticalAlign: 'top', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + bpmn: { kind: FlowKind.SEQUENCE_FLOW }, + }); }); }); @@ -214,7 +281,10 @@ describe('Style Computer', () => { [SequenceFlowKind.NORMAL, 'normal'], ])('compute style - sequence flows: %s', (kind: SequenceFlowKind, expected: string) => { const edge = new Edge('id', newSequenceFlow(kind)); - expect(computeStyle(edge)).toBe(`sequenceFlow;${expected}`); + expect(computeStyle(edge)).toStrictEqual({ + baseStyleNames: ['sequenceFlow', expected], + bpmn: { kind: FlowKind.SEQUENCE_FLOW }, + }); }); it.each([ @@ -223,7 +293,10 @@ describe('Style Computer', () => { [AssociationDirectionKind.BOTH, 'Both'], ])('compute style - association flows: %s', (kind: AssociationDirectionKind, expected: string) => { const edge = new Edge('id', newAssociationFlow(kind)); - expect(computeStyle(edge)).toBe(`association;${expected}`); + expect(computeStyle(edge)).toStrictEqual({ + baseStyleNames: ['association', expected], + bpmn: { kind: FlowKind.ASSOCIATION_FLOW }, + }); }); it.each([ @@ -231,51 +304,92 @@ describe('Style Computer', () => { [MessageVisibleKind.INITIATING, 'true'], ])('compute style - message flow icon: %s', (messageVisibleKind: MessageVisibleKind, expected: string) => { const edge = new Edge('id', newMessageFlow(), undefined, undefined, messageVisibleKind); - expect(styleComputer.computeMessageFlowIconStyle(edge)).toBe(`shape=bpmn.messageFlowIcon;bpmn.isInitiating=${expected}`); + // TODO magraph@0.1.0 cast to (waiting for "maxGraph fixes its types") + expect(styleComputer.computeMessageFlowIconStyle(edge)).toStrictEqual({ + shape: 'bpmn.messageFlowIcon', + // TODO rebase rename isNonInitiating --> isNonInitiating + bpmn: { isNonInitiating: expected }, + }); }); describe('compute style - events kind', () => { it('intermediate catch conditional', () => { const shape = newShape(newShapeBpmnEvent(ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, ShapeBpmnEventDefinitionKind.CONDITIONAL), newLabel({ name: 'Ubuntu' })); - expect(computeStyle(shape)).toBe('intermediateCatchEvent;bpmn.eventDefinitionKind=conditional;fontFamily=Ubuntu'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['intermediateCatchEvent'], + fontFamily: 'Ubuntu', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + bpmn: { kind: ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, eventDefinitionKind: ShapeBpmnEventDefinitionKind.CONDITIONAL }, + }); }); it('start signal', () => { const shape = newShape(newShapeBpmnEvent(ShapeBpmnElementKind.EVENT_START, ShapeBpmnEventDefinitionKind.SIGNAL), newLabel({ isBold: true })); - expect(computeStyle(shape)).toBe('startEvent;bpmn.eventDefinitionKind=signal;fontStyle=1'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['startEvent'], + fontStyle: 1, + bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.SIGNAL }, + }); }); }); + describe('compute style - boundary events', () => { it('interrupting message', () => { const shape = newShape(newShapeBpmnBoundaryEvent(ShapeBpmnEventDefinitionKind.MESSAGE, true), newLabel({ name: 'Arial' })); - expect(computeStyle(shape)).toBe('boundaryEvent;bpmn.eventDefinitionKind=message;bpmn.isInterrupting=true;fontFamily=Arial'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['boundaryEvent'], + fontFamily: 'Arial', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + bpmn: { kind: ShapeBpmnElementKind.EVENT_BOUNDARY, eventDefinitionKind: ShapeBpmnEventDefinitionKind.MESSAGE, isInterrupting: true }, + }); }); it('non interrupting timer', () => { const shape = newShape(newShapeBpmnBoundaryEvent(ShapeBpmnEventDefinitionKind.TIMER, false), newLabel({ isItalic: true })); - expect(computeStyle(shape)).toBe('boundaryEvent;bpmn.eventDefinitionKind=timer;bpmn.isInterrupting=false;fontStyle=2'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['boundaryEvent'], + fontStyle: 2, + bpmn: { kind: ShapeBpmnElementKind.EVENT_BOUNDARY, eventDefinitionKind: ShapeBpmnEventDefinitionKind.TIMER, isInterrupting: false }, + }); }); it('cancel with undefined interrupting value', () => { const shape = newShape(newShapeBpmnBoundaryEvent(ShapeBpmnEventDefinitionKind.CANCEL, undefined), newLabel({ isStrikeThrough: true })); - expect(computeStyle(shape)).toBe('boundaryEvent;bpmn.eventDefinitionKind=cancel;bpmn.isInterrupting=true;fontStyle=8'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['boundaryEvent'], + fontStyle: 8, + bpmn: { kind: ShapeBpmnElementKind.EVENT_BOUNDARY, eventDefinitionKind: ShapeBpmnEventDefinitionKind.CANCEL, isInterrupting: true }, + }); }); }); describe('compute style - event sub-process start event', () => { it('interrupting message', () => { const shape = newShape(newShapeBpmnStartEvent(ShapeBpmnEventDefinitionKind.MESSAGE, true), newLabel({ name: 'Arial' })); - expect(computeStyle(shape)).toBe('startEvent;bpmn.eventDefinitionKind=message;bpmn.isInterrupting=true;fontFamily=Arial'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['startEvent'], + fontFamily: 'Arial', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.MESSAGE, isInterrupting: true }, + }); }); it('non interrupting timer', () => { const shape = newShape(newShapeBpmnStartEvent(ShapeBpmnEventDefinitionKind.TIMER, false), newLabel({ isItalic: true })); - expect(computeStyle(shape)).toBe('startEvent;bpmn.eventDefinitionKind=timer;bpmn.isInterrupting=false;fontStyle=2'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['startEvent'], + fontStyle: 2, + bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.TIMER, isInterrupting: false }, + }); }); it('cancel with undefined interrupting value', () => { const shape = newShape(newShapeBpmnStartEvent(ShapeBpmnEventDefinitionKind.CANCEL, undefined), newLabel({ isStrikeThrough: true })); - expect(computeStyle(shape)).toBe('startEvent;bpmn.eventDefinitionKind=cancel;fontStyle=8'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['startEvent'], + fontStyle: 8, + bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.CANCEL }, + }); }); }); @@ -301,6 +415,33 @@ describe('Style Computer', () => { ); }); }); + // TODO rebase adapt test + // const expectedStyle = { + // baseStyleNames: ['subProcess'], + // bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.EMBEDDED, markers }, + // fontFamily: 'Arial', + // fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + // }; + // !markers.includes(ShapeBpmnMarkerKind.EXPAND) && (expectedStyle.verticalAlign = 'top'); + // expect(computeStyle(shape)).toStrictEqual(expectedStyle); + // }); + // + // it(`${expandKind} embedded sub-process with label bounds`, () => { + // const shape = newShape(newShapeBpmnSubProcess(ShapeBpmnSubProcessKind.EMBEDDED, markers), newLabel({ name: 'sans-serif' }, new Bounds(20, 20, 300, 200))); + // expect(computeStyle(shape)).toStrictEqual({ + // align: 'center', + // baseStyleNames: ['subProcess'], + // bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.EMBEDDED, markers }, + // fontFamily: 'sans-serif', + // fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + // labelWidth: 301, + // verticalAlign: 'top', + // // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator + // // `subProcess;bpmn.subProcessKind=embedded${additionalMarkerStyle};fontFamily=sans-serif;verticalAlign=top;align=center;labelWidth=301;labelPosition=top;verticalLabelPosition=left`, + // labelPosition: 'left', + // verticalLabelPosition: 'top', + // // end of fixme + // }); }); }); @@ -312,17 +453,40 @@ describe('Style Computer', () => { ])(`compute style - %s call activities`, (expandKind: string, markers: ShapeBpmnMarkerKind[]) => { it(`${expandKind} call activity without label bounds`, () => { const shape = newShape(newShapeBpmnCallActivityCallingProcess(markers), newLabel({ name: 'Arial' })); - const additionalMarkerStyle = markers.includes(ShapeBpmnMarkerKind.EXPAND) ? ';bpmn.markers=expand' : ''; - const additionalTerminalStyle = !markers.includes(ShapeBpmnMarkerKind.EXPAND) ? ';verticalAlign=top' : ''; - expect(computeStyle(shape)).toBe(`callActivity${additionalMarkerStyle};fontFamily=Arial${additionalTerminalStyle}`); + const expectedStyle = { + baseStyleNames: ['callActivity'], + bpmn: { + kind: ShapeBpmnElementKind.CALL_ACTIVITY, + globalTaskKind: undefined, // TODO magraph@0.1.0 decide if we set globalTaskKind to undefined or if we omit the property + markers, + }, + fontFamily: 'Arial', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + }; + !markers.includes(ShapeBpmnMarkerKind.EXPAND) && (expectedStyle.verticalAlign = 'top'); + expect(computeStyle(shape)).toStrictEqual(expectedStyle); }); it(`${expandKind} call activity with label bounds`, () => { const shape = newShape(newShapeBpmnCallActivityCallingProcess(markers), newLabel({ name: 'sans-serif' }, new Bounds(20, 20, 300, 200))); - const additionalMarkerStyle = markers.includes(ShapeBpmnMarkerKind.EXPAND) ? ';bpmn.markers=expand' : ''; - expect(computeStyle(shape)).toBe( - `callActivity${additionalMarkerStyle};fontFamily=sans-serif;verticalAlign=top;align=center;labelWidth=301;labelPosition=ignore;verticalLabelPosition=middle`, - ); + expect(computeStyle(shape)).toStrictEqual({ + align: 'center', + baseStyleNames: ['callActivity'], + bpmn: { + kind: ShapeBpmnElementKind.CALL_ACTIVITY, + globalTaskKind: undefined, // TODO magraph@0.1.0 decide if we set globalTaskKind to undefined or if we omit the property + markers, + }, + fontFamily: 'sans-serif', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + labelWidth: 301, + verticalAlign: 'top', + // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator + // `callActivity${additionalMarkerStyle};fontFamily=sans-serif;verticalAlign=top;align=center;labelWidth=301;labelPosition=ignore;verticalLabelPosition=middle`, + labelPosition: 'left', + verticalLabelPosition: 'top', + // end of fixme + }); }); }); }); @@ -337,14 +501,35 @@ describe('Style Computer', () => { ])(`compute style - call activities calling %s`, (globalTaskKind: GlobalTaskKind) => { it(`call activity calling ${globalTaskKind} without label bounds`, () => { const shape = newShape(newShapeBpmnCallActivityCallingGlobalTask(globalTaskKind), newLabel({ name: 'Arial' })); - expect(computeStyle(shape)).toBe(`callActivity;bpmn.globalTaskKind=${globalTaskKind};fontFamily=Arial`); + const expectedStyle = { + baseStyleNames: ['callActivity'], + bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, globalTaskKind: globalTaskKind, markers: [] }, + fontFamily: 'Arial', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + }; + expect(computeStyle(shape)).toStrictEqual(expectedStyle); }); it(`call activity calling ${globalTaskKind} with label bounds`, () => { const shape = newShape(newShapeBpmnCallActivityCallingGlobalTask(globalTaskKind), newLabel({ name: 'sans-serif' }, new Bounds(20, 20, 300, 200))); - expect(computeStyle(shape)).toBe( - `callActivity;bpmn.globalTaskKind=${globalTaskKind};fontFamily=sans-serif;verticalAlign=top;align=center;labelWidth=301;labelPosition=ignore;verticalLabelPosition=middle`, - ); + expect(computeStyle(shape)).toStrictEqual({ + align: 'center', + baseStyleNames: ['callActivity'], + bpmn: { + globalTaskKind: globalTaskKind, + kind: ShapeBpmnElementKind.CALL_ACTIVITY, + markers: [], + }, + fontFamily: 'sans-serif', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + labelWidth: 301, + verticalAlign: 'top', + // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator + // `callActivity;bpmn.globalTaskKind=${globalTaskKind};fontFamily=sans-serif;verticalAlign=top;align=center;labelWidth=301;labelPosition=ignore;verticalLabelPosition=middle`, + labelPosition: 'left', + verticalLabelPosition: 'top', + // end of fixme + }); }); }); }); @@ -356,49 +541,99 @@ describe('Style Computer', () => { ['instantiating', true], ])('%s receive task', (instantiatingKind: string, instantiate: boolean) => { const shape = newShape(newShapeBpmnActivity(ShapeBpmnElementKind.TASK_RECEIVE, undefined, instantiate), newLabel({ name: 'Arial' })); - expect(computeStyle(shape)).toBe(`receiveTask;bpmn.isInstantiating=${instantiate};fontFamily=Arial`); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['receiveTask'], + bpmn: { kind: ShapeBpmnElementKind.TASK_RECEIVE, isInstantiating: instantiate, markers: [] }, + fontFamily: 'Arial', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + }); }); }); describe('compute style - text annotation', () => { it('without label', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.TEXT_ANNOTATION)); - expect(computeStyle(shape)).toBe('textAnnotation'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['textAnnotation'], + bpmn: { kind: ShapeBpmnElementKind.TEXT_ANNOTATION }, + }); }); it('with label bounds', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.TEXT_ANNOTATION), newLabel({ name: 'Segoe UI' }, new Bounds(50, 50, 100, 100))); - expect(computeStyle(shape)).toBe('textAnnotation;fontFamily=Segoe UI;verticalAlign=top;labelWidth=101;labelPosition=ignore;verticalLabelPosition=middle'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['textAnnotation'], + bpmn: { + kind: ShapeBpmnElementKind.TEXT_ANNOTATION, + }, + fontFamily: 'Segoe UI', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + labelWidth: 101, + verticalAlign: 'top', + // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator + // 'textAnnotation;fontFamily=Segoe UI;verticalAlign=top;labelWidth=101;labelPosition=ignore;verticalLabelPosition=middle' + labelPosition: 'left', + verticalLabelPosition: 'top', + // end of fixme + }); }); }); describe('compute style - group', () => { it('without label', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.GROUP)); - expect(computeStyle(shape)).toBe('group'); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['group'], + bpmn: { kind: ShapeBpmnElementKind.GROUP }, + }); }); it('with label bounds', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.GROUP), newLabel({ name: 'Roboto' }, new Bounds(50, 50, 100, 100))); - expect(computeStyle(shape)).toBe('group;fontFamily=Roboto;verticalAlign=top;align=center;labelWidth=101;labelPosition=ignore;verticalLabelPosition=middle'); + expect(computeStyle(shape)).toStrictEqual({ + align: 'center', + baseStyleNames: ['group'], + bpmn: { + kind: ShapeBpmnElementKind.GROUP, + }, + fontFamily: 'Roboto', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + labelWidth: 101, + verticalAlign: 'top', + // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator + // 'group;fontFamily=Roboto;verticalAlign=top;align=center;labelWidth=101;labelPosition=ignore;verticalLabelPosition=middle' + labelPosition: 'left', + verticalLabelPosition: 'top', + // end of fixme + }); }); }); describe('compute style - pool references a Process', () => { it.each([ - ['vertical', false, '1'], - ['horizontal', true, '0'], - ])('%s pool references a Process', (title: string, isHorizontal: boolean, expected: string) => { + ['vertical', false, true], + ['horizontal', true, false], + ['undefined', undefined, false], + ])('%s pool references a Process', (title: string, isHorizontal: boolean, expectedStyleIsHorizontal: boolean) => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.POOL), undefined, isHorizontal); - expect(computeStyle(shape)).toBe(`pool;horizontal=${expected}`); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['pool'], + horizontal: expectedStyleIsHorizontal, + bpmn: { kind: ShapeBpmnElementKind.POOL }, + }); }); }); describe('compute style - lane', () => { it.each([ - ['vertical', false, '1'], - ['horizontal', true, '0'], - ])('%s lane', (title: string, isHorizontal: boolean, expected: string) => { + ['vertical', false, true], + ['horizontal', true, false], + ['undefined', undefined, false], + ])('%s lane', (title: string, isHorizontal: boolean, expectedStyleIsHorizontal: boolean) => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.LANE), undefined, isHorizontal); - expect(computeStyle(shape)).toBe(`lane;horizontal=${expected}`); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['lane'], + horizontal: expectedStyleIsHorizontal, + bpmn: { kind: ShapeBpmnElementKind.LANE }, + }); }); }); @@ -419,8 +654,14 @@ describe('Style Computer', () => { (markerKind: ShapeBpmnMarkerKind) => { it(`${bpmnKind} with ${markerKind} marker`, () => { const shape = newShape(newShapeBpmnActivity(bpmnKind, [markerKind]), newLabel({ name: 'Arial' })); - const additionalReceiveTaskStyle = bpmnKind === ShapeBpmnElementKind.TASK_RECEIVE ? ';bpmn.isInstantiating=false' : ''; - expect(computeStyle(shape)).toBe(`${bpmnKind}${additionalReceiveTaskStyle};bpmn.markers=${markerKind};fontFamily=Arial`); + const expectedStyle = { + baseStyleNames: [bpmnKind], + bpmn: { kind: bpmnKind, markers: [markerKind] }, + fontFamily: 'Arial', + fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + }; + bpmnKind === ShapeBpmnElementKind.TASK_RECEIVE && (expectedStyle.bpmn.isInstantiating = false); + expect(computeStyle(shape)).toStrictEqual(expectedStyle); }); if (bpmnKind == ShapeBpmnElementKind.SUB_PROCESS) { @@ -429,12 +670,27 @@ describe('Style Computer', () => { const shape = newShape(newShapeBpmnSubProcess(subProcessKind, markers)); expect(computeStyle(shape)).toBe(`subProcess;bpmn.subProcessKind=${subProcessKind};bpmn.markers=${getExpectedMarkers(markers, subProcessKind).join(',')}`); }); + // TODO rebase adapt test for maxgraph + // it(`${bpmnKind} with Loop & Expand (collapsed) markers`, () => { + // const shape = newShape(newShapeBpmnSubProcess(ShapeBpmnSubProcessKind.EMBEDDED, [markerKind, ShapeBpmnMarkerKind.EXPAND])); + // expect(computeStyle(shape)).toStrictEqual({ + // baseStyleNames: ['subProcess'], + // bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, markers: [markerKind, ShapeBpmnMarkerKind.EXPAND], subProcessKind: ShapeBpmnSubProcessKind.EMBEDDED }, + // }); + // }); } if (bpmnKind == ShapeBpmnElementKind.CALL_ACTIVITY) { it(`${bpmnKind} calling process with ${markerKind} & Expand (collapsed) markers`, () => { const shape = newShape(newShapeBpmnCallActivityCallingProcess([markerKind, ShapeBpmnMarkerKind.EXPAND])); - expect(computeStyle(shape)).toBe(`callActivity;bpmn.markers=${markerKind},expand`); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['callActivity'], + bpmn: { + kind: ShapeBpmnElementKind.CALL_ACTIVITY, + globalTaskKind: undefined, // TODO magraph@0.1.0 decide if we omit the globalTaskKind property when not set + markers: [markerKind, ShapeBpmnMarkerKind.EXPAND], + }, + }); }); it.each([ @@ -445,7 +701,14 @@ describe('Style Computer', () => { [ShapeBpmnElementKind.GLOBAL_TASK_BUSINESS_RULE as GlobalTaskKind], ])(`${bpmnKind} calling global task with ${markerKind} marker`, (globalTaskKind: GlobalTaskKind) => { const shape = newShape(newShapeBpmnCallActivityCallingGlobalTask(globalTaskKind, [markerKind])); - expect(computeStyle(shape)).toBe(`callActivity;bpmn.globalTaskKind=${globalTaskKind};bpmn.markers=${markerKind}`); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['callActivity'], + bpmn: { + kind: ShapeBpmnElementKind.CALL_ACTIVITY, + globalTaskKind, + markers: [markerKind], + }, + }); }); } }, @@ -468,8 +731,23 @@ describe('Style Computer', () => { expect(computeStyle(shape)).toBe(`eventBasedGateway;bpmn.isInstantiating=${!!instantiate};bpmn.gatewayKind=${gatewayKind};fontFamily=Arial`); }, ); + // TODO rebase adapt test for maxGraph + // `( + // 'event-based gateway when instantiate: $instantiate for gatewayKind: $gatewayKind', + // ({ instantiate, gatewayKind }: { instantiate: boolean; gatewayKind: ShapeBpmnEventBasedGatewayKind }) => { + // const shape = newShape(newShapeBpmnEventBasedGateway(instantiate, gatewayKind), newLabel({ name: 'Arial' })); + // gatewayKind ??= ShapeBpmnEventBasedGatewayKind.None; + // expect(computeStyle(shape)).toStrictEqual({ + // baseStyleNames: ['eventBasedGateway'], + // bpmn: { kind: ShapeBpmnElementKind.GATEWAY_EVENT_BASED, gatewayKind, isInstantiating: !!instantiate }, + // fontFamily: 'Arial', + // fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + // }); + // }, + // ); }); + // TODO rebase adapt tests for maxGraph describe('compute style - colors', () => { describe.each([[undefined], [false], [true]])(`Ignore BPMN colors: %s`, (ignoreBpmnColors: boolean) => { // 'undefined' RendererOptions tested in other tests in this file diff --git a/test/unit/component/mxgraph/renderer/style-utils.test.ts b/test/unit/component/mxgraph/renderer/style-utils.test.ts index 3032b21e0a..3d538cfb0b 100644 --- a/test/unit/component/mxgraph/renderer/style-utils.test.ts +++ b/test/unit/component/mxgraph/renderer/style-utils.test.ts @@ -14,7 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { FlowKind, ShapeBpmnElementKind } from '@lib/model/bpmn/internal'; +import type { BPMNCellStyle } from '../../../../../src/component/mxgraph/renderer/StyleComputer'; +import { FlowKind, ShapeBpmnElementKind, ShapeBpmnEventBasedGatewayKind, ShapeBpmnEventDefinitionKind, ShapeBpmnSubProcessKind } from '@lib/model/bpmn/internal'; import { computeBpmnBaseClassName, computeAllBpmnClassNames } from '@lib/component/mxgraph/renderer/style-utils'; describe('compute base css class names of BPMN elements', () => { @@ -43,34 +44,42 @@ describe('compute base css class names of BPMN elements', () => { }); describe('compute all css class names based on style input', () => { + // TODO rebase adapt test entries it.each` - style | isLabel | expectedClassNames - ${ShapeBpmnElementKind.LANE} | ${true} | ${['bpmn-type-container', 'bpmn-lane', 'bpmn-label']} - ${ShapeBpmnElementKind.POOL} | ${false} | ${['bpmn-type-container', 'bpmn-pool']} - ${ShapeBpmnElementKind.CALL_ACTIVITY} | ${false} | ${['bpmn-type-activity', 'bpmn-call-activity']} - ${'callActivity;bpmn.globalTaskKind=globalTask'} | ${false} | ${['bpmn-type-activity', 'bpmn-call-activity', 'bpmn-global-task']} - ${'callActivity;bpmn.globalTaskKind=globalManualTask'} | ${true} | ${['bpmn-type-activity', 'bpmn-call-activity', 'bpmn-global-manual-task', 'bpmn-label']} - ${ShapeBpmnElementKind.EVENT_BOUNDARY} | ${true} | ${['bpmn-type-event', 'bpmn-boundary-event', 'bpmn-label']} - ${'boundaryEvent;bpmn.eventDefinitionKind=cancel;bpmn.isInterrupting=true'} | ${true} | ${['bpmn-type-event', 'bpmn-boundary-event', 'bpmn-event-def-cancel', 'bpmn-label']} - ${ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW} | ${false} | ${['bpmn-type-event', 'bpmn-intermediate-throw-event']} - ${'startEvent;bpmn.eventDefinitionKind=timer;bpmn.isInterrupting=false;fontStyle=2'} | ${false} | ${['bpmn-type-event', 'bpmn-start-event', 'bpmn-event-def-timer']} - ${ShapeBpmnElementKind.GATEWAY_EVENT_BASED} | ${true} | ${['bpmn-type-gateway', 'bpmn-event-based-gateway', 'bpmn-label']} - ${'eventBasedGateway;bpmn.isInstantiating=true;bpmn.gatewayKind=Parallel'} | ${false} | ${['bpmn-type-gateway', 'bpmn-event-based-gateway', 'bpmn-gateway-kind-parallel']} - ${ShapeBpmnElementKind.GATEWAY_EXCLUSIVE} | ${true} | ${['bpmn-type-gateway', 'bpmn-exclusive-gateway', 'bpmn-label']} - ${ShapeBpmnElementKind.TASK} | ${true} | ${['bpmn-type-activity', 'bpmn-type-task', 'bpmn-task', 'bpmn-label']} - ${ShapeBpmnElementKind.TASK_BUSINESS_RULE} | ${false} | ${['bpmn-type-activity', 'bpmn-type-task', 'bpmn-business-rule-task']} - ${ShapeBpmnElementKind.SUB_PROCESS} | ${false} | ${['bpmn-type-activity', 'bpmn-sub-process']} - ${'subProcess;bpmn.subProcessKind=adHoc'} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-adhoc', 'bpmn-label']} - ${'subProcess;bpmn.subProcessKind=embedded'} | ${false} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-embedded']} - ${'subProcess;bpmn.subProcessKind=event'} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-event', 'bpmn-label']} - ${'subProcess;bpmn.subProcessKind=transaction'} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-transaction', 'bpmn-label']} - ${FlowKind.ASSOCIATION_FLOW} | ${true} | ${['bpmn-type-flow', 'bpmn-association', 'bpmn-label']} - ${FlowKind.MESSAGE_FLOW} | ${false} | ${['bpmn-type-flow', 'bpmn-message-flow']} - ${'sequenceFlow;default;fontStyle=4'} | ${false} | ${['bpmn-type-flow', 'bpmn-sequence-flow']} - ${'shape=bpmn.message-flow-icon'} | ${false} | ${['bpmn-message-flow-icon']} - ${'shape=bpmn.message-flow-icon;bpmn.isInitiating=false'} | ${false} | ${['bpmn-message-flow-icon', 'bpmn-icon-non-initiating']} - ${'shape=bpmn.message-flow-icon;bpmn.isInitiating=true'} | ${true} | ${['bpmn-message-flow-icon', 'bpmn-icon-initiating', 'bpmn-label']} - `('style="$style" / isLabel=$isLabel', ({ style, isLabel, expectedClassNames }: { style: string; isLabel: boolean; expectedClassNames: string[] }) => { - expect(computeAllBpmnClassNames(style, isLabel)).toEqual(expectedClassNames); - }); + style | isLabel | expectedClassNames + ${{ bpmn: { kind: ShapeBpmnElementKind.LANE } }} | ${true} | ${['bpmn-type-container', 'bpmn-lane', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.POOL } }} | ${false} | ${['bpmn-type-container', 'bpmn-pool']} + ${{ bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY } }} | ${false} | ${['bpmn-type-activity', 'bpmn-call-activity']} + ${{ bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, globalTaskKind: ShapeBpmnElementKind.GLOBAL_TASK } }} | ${false} | ${['bpmn-type-activity', 'bpmn-call-activity', 'bpmn-global-task']} + ${{ bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, globalTaskKind: ShapeBpmnElementKind.GLOBAL_TASK_MANUAL } }} | ${true} | ${['bpmn-type-activity', 'bpmn-call-activity', 'bpmn-global-manual-task', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.EVENT_BOUNDARY } }} | ${true} | ${['bpmn-type-event', 'bpmn-boundary-event', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.EVENT_BOUNDARY, eventDefinitionKind: ShapeBpmnEventDefinitionKind.CANCEL } }} | ${true} | ${['bpmn-type-event', 'bpmn-boundary-event', 'bpmn-event-def-cancel', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW } }} | ${false} | ${['bpmn-type-event', 'bpmn-intermediate-throw-event']} + ${{ bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.TIMER, isInterrupting: false }, fontStyle: 2 }} | ${false} | ${['bpmn-type-event', 'bpmn-start-event', 'bpmn-event-def-timer']} + ${{ bpmn: { kind: ShapeBpmnElementKind.GATEWAY_EVENT_BASED } }} | ${true} | ${['bpmn-type-gateway', 'bpmn-event-based-gateway', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.GATEWAY_EVENT_BASED, isInstantiating: true, gatewayKind: ShapeBpmnEventBasedGatewayKind.Parallel } }} | ${false} | ${['bpmn-type-gateway', 'bpmn-event-based-gateway', 'bpmn-gateway-kind-parallel']} + ${{ bpmn: { kind: ShapeBpmnElementKind.GATEWAY_EXCLUSIVE } }} | ${true} | ${['bpmn-type-gateway', 'bpmn-exclusive-gateway', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.TASK } }} | ${true} | ${['bpmn-type-activity', 'bpmn-type-task', 'bpmn-task', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.TASK_BUSINESS_RULE } }} | ${false} | ${['bpmn-type-activity', 'bpmn-type-task', 'bpmn-business-rule-task']} + ${{ bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS } }} | ${false} | ${['bpmn-type-activity', 'bpmn-sub-process']} + ${'subProcess;bpmn.subProcessKind=adHoc'} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-adhoc', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.EMBEDDED } }} | ${false} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-embedded']} + ${{ bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.EVENT } }} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-event', 'bpmn-label']} + ${'subProcess;bpmn.subProcessKind=transaction'} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-transaction', 'bpmn-label']} + ${{ bpmn: { kind: FlowKind.ASSOCIATION_FLOW } }} | ${true} | ${['bpmn-type-flow', 'bpmn-association', 'bpmn-label']} + ${{ bpmn: { kind: FlowKind.MESSAGE_FLOW } }} | ${false} | ${['bpmn-type-flow', 'bpmn-message-flow']} + ${'shape=bpmn.message-flow-icon'} | ${false} | ${['bpmn-message-flow-icon']} + ${'shape=bpmn.message-flow-icon;bpmn.isInitiating=false'} | ${false} | ${['bpmn-message-flow-icon', 'bpmn-icon-non-initiating']} + ${'shape=bpmn.message-flow-icon;bpmn.isInitiating=true'} | ${true} | ${['bpmn-message-flow-icon', 'bpmn-icon-initiating', 'bpmn-label']} + ${{ bpmn: { kind: FlowKind.SEQUENCE_FLOW } }} | ${false} | ${['bpmn-type-flow', 'bpmn-sequence-flow']} + ${{ shape: 'bpmn.message-flow-icon' }} | ${false} | ${['bpmn-message-flow-icon']} + ${{ bpmn: { isNonInitiating: true }, shape: 'bpmn.message-flow-icon' }} | ${false} | ${['bpmn-message-flow-icon', 'bpmn-icon-non-initiating']} + ${{ bpmn: { isNonInitiating: false }, shape: 'bpmn.message-flow-icon' }} | ${true} | ${['bpmn-message-flow-icon', 'bpmn-icon-initiating', 'bpmn-label']} + `( + // TODO magraph@0.1.0 find a way to correctly display the style object + 'style="$style" / isLabel=$isLabel', + ({ style, isLabel, expectedClassNames }: { style: BPMNCellStyle; isLabel: boolean; expectedClassNames: string[] }) => { + expect(computeAllBpmnClassNames(style, isLabel)).toEqual(expectedClassNames); + }, + ); }); diff --git a/vite.config.js b/vite.config.js index 100d8171e7..f4c9a74b99 100644 --- a/vite.config.js +++ b/vite.config.js @@ -42,13 +42,14 @@ export default defineConfig(({ mode }) => { entryFileNames: `dev/public/assets/[name].js`, chunkFileNames: `dev/public/assets/[name].js`, assetFileNames: `dev/public/assets/[name].[ext]`, + // TODO magraph@0.1.0 test the splitVendorChunkPlugin (see https://vitejs.dev/guide/build.html#chunking-strategy) manualChunks: { - // put mxgraph code in a dedicated file. As it is eol, it doesn't change from release to release, so it reduces the changes when uploading the demo to the examples repository - mxgraph: ['mxgraph'], + // put maxGraph code in a dedicated file. As it is eol, it doesn't change from release to release, so it reduces the changes when uploading the demo to the examples repository + maxGraph: ['@maxgraph/core'], }, }, }, - chunkSizeWarningLimit: 820, // mxgraph + chunkSizeWarningLimit: 555, // maxGraph }, preview: { port: 10002, From 290966970414bfbd4881ff6b92f62150dcc67fef Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 16 Jun 2023 08:29:55 +0200 Subject: [PATCH 02/90] TMP disable the GH workflow running the e2e tests (not passing) --- .github/workflows/test-e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index f34b2f0736..64bc94eca8 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -45,6 +45,7 @@ on: jobs: test_e2e: runs-on: ${{ matrix.os }} + if: github.event_name == 'NOT_SUPPORTED' # TEMP disable e2e until the code compile and the JS doesn't generate runtime errors that block the dev server strategy: # we want to run the full build on all os: don't cancel running jobs even if one fails fail-fast: false From 8f4ee05391b259ecfb14eab0f213b50cf0eee640 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 16 Jun 2023 12:34:37 +0200 Subject: [PATCH 03/90] POC maxGraph 0.1.0 v2 BpmnGraph: remove batchUpdate as it is already defined in the Graph class GraphCellUpdater.ts: WIP fix TSC errors StyleManager.ts: WIP fix TSC errors StyleComputer.ts: WIP fix TSC errors BpmnRenderer.ts: update TODO StyleConfigurator.ts: WIP fix TSC errors StyleConfigurator.ts: add TODO after rebase ShapeConfigurator.ts: WIP fix TSC errors fix rebase: fix FONT imports (no more exported in style/index - internal only) Add TODO in BPMNCellStyle style/utils.ts: WIP fix TSC errors StyleManager.ts: remove unused imports StyleComputer.test.ts: WIP fix TSC errors integration tests: WIP fix TSC errors mxGraph.model.bpmn.elements.test.ts: restore variable name after rebase (no mx in names) run fix CSS class undefined access - WIP CSS classes disapaer when doing navigation fix typo in TODO/FIXME about maxgraph StyleComputer.test.ts: fix msg flow icon tests after rebase StyleComputer.test.ts: fix sub-process tests after rebase StyleComputer.test.ts: clean comment in sub-process tests after rebase the comments was the test implementation in the previous poc. During rebase, as there were too many conflicts, the tests hadn't been migrated and the former poc implem put there to help the new test migration StyleComputer.test.ts: fix subprocess markers test StyleComputer.test.ts: fix event gateway test StyleComputer.test.ts: WIP fix bpmn in color StyleComputer.ts: fix msg icon flow extension computation StyleComputer.ts: improve comment StyleComputer.ts: fix edges extension computation style-utils.test.ts: fix subprocess tests (adhoc still KO) style-utils.test.ts: fix msg flow icon style-utils.test.ts: FIXME for adhoc ThemedBpmnVisualization.ts: fix wrongly migrated comment refactor: restore getDataModel method when getModel was called with mxGraph refactor: restore usage of getDataModel method in BpmnRenderer.ts refactor: restore usage of getDataModel method in GraphCellUpdater.ts GraphCellUpdater.ts add TODO for the master branch SvgExporter.ts: restore import order like with mxGraph imple ShapeConfigurator.ts: restore import order like with mxGraph implem ShapeConfigurator.ts: restore comment StyleConfigurator.ts: restore import order StyleConfigurator.ts: add todo for arc configuration custom-overlay.ts: restore import order toBeShape/index.ts: fix compilation errors toBeEdge/index.ts: fix compilation errors matcher-utils.ts: fix compilation errors mxGraph.model.bpmn.elements.test.ts: fix compilation errors integration tests: fix CSS api tests mxGraph.model.css.api.test.ts: check no extra css classes prior adding them IT: simplify check of extra css classes edge/shape WIP debug extra CSS classes not added to the dom style-utils.test.ts: fix test WIP restore style.isInitiating: make test pass WIP restore style.isInitiating integration test: BpmnCellStyle.horizontal is now a boolean (same type as in CellStyle) integration test: fix test in "bpmn in color" StyleComputer.ts remove TODO about "isInitiating" (already managed) mxGraph.model.bpmn.elements.test.ts: revert extra changes StyleComputer.ts remove TODO about "style.horizontal" (already managed) StyleComputer.ts fix label position (horizontal and vertical) style-utils.test.ts: remove TODO already managed StyleComputer.ts: simplify management of style.horizontal for lane and pool update TODO custom-overlay.ts: restore original license header model-expect.ts: remove extra imports model-expect.ts: simplify import WIP tmp fix to update the style WIP tmp fix to update the style and CSS classes (clone the style of the cell to cache and update) refactor: simply the storage of CSS classes in the BPMN style object integ test: refactor markers management integ test: restore the implem of the getFontStyleValue utils function (make 2 tests pass) CSS classes: only set in style when the array is not empty (fix 10 integration tests) TMP: more logs in the matcher error msg to better diagnose the problem WIP integ test: investigate lower fontStyle value WIP integ test: fix fontStyle value update TODO comments for consistency fix more integration tests: CSS class reset fix wrong assertion in IT: fontStyle updateStyle fontStyle: less side effect when setting flag of undefined value StyleComputer: do not set fontStyle value to 0 (restore mxGraph behaviour) + fix IT IT: remove extra check fix: updateStyle 'default' special value now correctly reset the value style utils.ts: improve TODO improve comments about workarounds for maxGraph issues Add TODO set plugins in Graph constructor mxGraph.model.style.api.test.ts remove extra FIXME mxGraph.model.style.api.test.ts add TODO StyleComputer.ts remove managed TODO style utils: update todo test: simplify todo remove managed TODO matcher-utils.ts: remove tmp solution to jest msg matcher-utils.ts remove managed TODO Manage "todo rebase" update todo fix style for rounded activity (was not correcly migrated) StyleConfigurator.ts: migrated code better fit the original code manage some "todo rebase" refactor: style function - no need to return the style object anymore refactor: rename style properties used to fill markers (prepare future feature available in maxGraph) Add todo about fixing "fill edge markers" --- dev/ts/component/SvgExporter.ts | 2 +- dev/ts/component/ThemedBpmnVisualization.ts | 2 +- dev/ts/main.ts | 2 +- src/component/mxgraph/BpmnGraph.ts | 29 +- src/component/mxgraph/BpmnRenderer.ts | 18 +- src/component/mxgraph/GraphCellUpdater.ts | 36 ++- src/component/mxgraph/GraphConfigurator.ts | 2 +- .../mxgraph/config/ShapeConfigurator.ts | 37 +-- .../mxgraph/config/StyleConfigurator.ts | 143 ++++------ .../mxgraph/overlay/custom-overlay.ts | 4 +- .../mxgraph/renderer/StyleComputer.ts | 100 +++---- src/component/mxgraph/renderer/style-utils.ts | 11 +- src/component/mxgraph/shape/edges.ts | 6 +- src/component/mxgraph/shape/event-shapes.ts | 2 +- src/component/mxgraph/shape/flow-shapes.ts | 17 +- src/component/mxgraph/style/StyleManager.ts | 23 +- src/component/mxgraph/style/identifiers.ts | 2 +- src/component/mxgraph/style/utils.ts | 110 +++++--- test/integration/helpers/model-expect.ts | 8 +- test/integration/matchers/matcher-utils.ts | 38 ++- test/integration/matchers/toBeCell/index.ts | 1 + test/integration/matchers/toBeEdge/index.ts | 39 ++- test/integration/matchers/toBeShape/index.ts | 100 ++----- .../mxGraph.model.bpmn.elements.test.ts | 41 ++- .../integration/mxGraph.model.css.api.test.ts | 10 + .../mxGraph.model.parsing.entities.test.ts | 2 +- .../mxGraph.model.style.api.test.ts | 27 +- .../mxgraph/renderer/StyleComputer.test.ts | 251 +++++++++--------- .../mxgraph/renderer/style-utils.test.ts | 15 +- 29 files changed, 510 insertions(+), 568 deletions(-) diff --git a/dev/ts/component/SvgExporter.ts b/dev/ts/component/SvgExporter.ts index 7c7ba7cfa3..6913cb76bb 100644 --- a/dev/ts/component/SvgExporter.ts +++ b/dev/ts/component/SvgExporter.ts @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { Graph, AlignValue, VAlignValue, OverflowValue, TextDirectionValue } from '@maxgraph/core'; import { Client, SvgCanvas2D, ImageExport, constants, xmlUtils, domUtils, stringUtils } from '@maxgraph/core'; +import type { Graph, AlignValue, VAlignValue, OverflowValue, TextDirectionValue } from '@maxgraph/core'; interface SvgExportOptions { scale: number; diff --git a/dev/ts/component/ThemedBpmnVisualization.ts b/dev/ts/component/ThemedBpmnVisualization.ts index 63135ef3f3..ad4ac1aa54 100644 --- a/dev/ts/component/ThemedBpmnVisualization.ts +++ b/dev/ts/component/ThemedBpmnVisualization.ts @@ -186,7 +186,7 @@ export class ThemedBpmnVisualization extends BpmnVisualization { const stylesheet = this.graph.getStylesheet(); - // directly access the 'styles' map to update values. Using stylesheet.getBPMNCellStyle returns a copy of the style + // directly access the 'styles' map to update values. Using stylesheet.getCellStyle returns a copy of the style const seqFlowStyle = stylesheet.styles.get(FlowKind.SEQUENCE_FLOW); seqFlowStyle.strokeColor = color; seqFlowStyle.fillColor = color; diff --git a/dev/ts/main.ts b/dev/ts/main.ts index 4277abf00b..70cb72adc3 100644 --- a/dev/ts/main.ts +++ b/dev/ts/main.ts @@ -128,7 +128,7 @@ function collapseBpmnElement(bpmnElementId: string): void { return; } log('Updating model, bpmnElement to collapse:', bpmnElementId); - const model = bpmnVisualization.graph.model; + const model = bpmnVisualization.graph.getDataModel(); const cell = model.getCell(bpmnElementId); if (!cell) { log('Element not found in the model, do nothing'); diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index f003a359e7..0af4c72ade 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -31,6 +31,8 @@ export class BpmnGraph extends Graph { * @internal */ constructor(container: HTMLElement) { + // TODO maxGraph@0.1.0 - only set the plugins we need + // require a version that doesn't generate errors when plugins are not found (is ok in v0.8.0) super(container); this.zoomFactor = zoomFactorIn; if (this.container) { @@ -46,25 +48,6 @@ export class BpmnGraph extends Graph { return new BpmnGraphView(this); } - /** - * Shortcut for an update of the model within a transaction. - * - * This method is inspired from {@link https://github.com/maxGraph/maxGraph/blob/v0.1.0/packages/core/src/view/Graph.ts#L487-L494 maxGraph}. - * - * @param fn the update to be made in the transaction. - * - * @experimental subject to change, may move to a subclass of `mxGraphModel` - * @alpha - */ - batchUpdate(fn: () => void): void { - this.model.beginUpdate(); - try { - fn(); - } finally { - this.model.endUpdate(); - } - } - /** * Overridden to manage `currentZoomLevel` * @internal @@ -145,7 +128,7 @@ export class BpmnGraph extends Graph { let scale = Math.min(maxScale, Math.min(clientWidth / width, clientHeight / height)); this.setCurrentZoomLevel(scale); - // TODO magraph@0.1.0 improve implementation (the following is to make integration tests pass) + // TODO maxgraph@0.1.0 improve implementation (the following is to make integration tests pass) scale == 0 && (scale = 1); this.view.scaleAndTranslate( scale, @@ -155,7 +138,7 @@ export class BpmnGraph extends Graph { } } - // TODO magraph@0.1.0 move somewhere else + find a better name + should be a util function + // TODO maxgraph@0.1.0 move somewhere else + find a better name + should be a util function private NaNToZero(value: number): number { return Number.isNaN(value) ? 0 : value; } @@ -230,7 +213,7 @@ export class BpmnGraph extends Graph { return [factor, scale]; } - // TODO magraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) + // TODO maxgraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) override createStylesheet(): Stylesheet { return new BpmnStylesheet(); } @@ -250,7 +233,7 @@ class BpmnGraphView extends GraphView { } } -// TODO magraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) +// TODO maxgraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) class BpmnStylesheet extends Stylesheet { override getCellStyle(cellStyle: CellStyle, defaultStyle: CellStateStyle): CellStateStyle { let style: CellStateStyle; diff --git a/src/component/mxgraph/BpmnRenderer.ts b/src/component/mxgraph/BpmnRenderer.ts index bcfb2af69d..50cb54fa34 100644 --- a/src/component/mxgraph/BpmnRenderer.ts +++ b/src/component/mxgraph/BpmnRenderer.ts @@ -13,8 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import type { Cell } from '@maxgraph/core'; -import { Point } from '@maxgraph/core'; import type { Edge, Waypoint } from '../../model/bpmn/internal/edge/edge'; import { MessageFlow } from '../../model/bpmn/internal/edge/flows'; @@ -28,6 +26,8 @@ import StyleComputer from './renderer/StyleComputer'; import type { BpmnGraph } from './BpmnGraph'; import type { FitOptions, RendererOptions } from '../options'; import type { RenderedModel } from '../registry/bpmn-model-registry'; +import type { Cell } from '@maxgraph/core'; +import { Point } from '@maxgraph/core'; /** * @internal @@ -41,11 +41,8 @@ export class BpmnRenderer { } private insertShapesAndEdges({ pools, lanes, subprocesses, otherFlowNodes, boundaryEvents, edges }: RenderedModel): void { - // TODO rebase use this.graph.batchUpdate - const model = this.graph.model; - model.clear(); // ensure to remove manual changes or already loaded graphs - model.beginUpdate(); - try { + this.graph.batchUpdate(() => { + this.graph.getDataModel().clear(); // ensure to remove manual changes or already loaded graphs this.insertShapes(pools); this.insertShapes(lanes); this.insertShapes(subprocesses); @@ -54,9 +51,7 @@ export class BpmnRenderer { this.insertShapes(boundaryEvents); // at last as edge source and target must be present in the model prior insertion, otherwise they are not rendered this.insertEdges(edges); - } finally { - model.endUpdate(); - } + }); } private insertShapes(shapes: Shape[]): void { @@ -125,11 +120,12 @@ export class BpmnRenderer { } private getCell(id: string): Cell { - return this.graph.model.getCell(id); + return this.graph.getDataModel().getCell(id); } private insertVertex(parent: Cell, id: string | null, value: string, bounds: Bounds, labelBounds: Bounds, style?: BPMNCellStyle): Cell { const vertexCoordinates = this.coordinatesTranslator.computeRelativeCoordinates(parent, new Point(bounds.x, bounds.y)); + // TODO maxGraph@0.1.0 check insertVertex with single parameter const cell = this.graph.insertVertex(parent, id, value, vertexCoordinates.x, vertexCoordinates.y, bounds.width, bounds.height, style); if (labelBounds) { diff --git a/src/component/mxgraph/GraphCellUpdater.ts b/src/component/mxgraph/GraphCellUpdater.ts index 1d125547cc..31f8ea87b9 100644 --- a/src/component/mxgraph/GraphCellUpdater.ts +++ b/src/component/mxgraph/GraphCellUpdater.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { isShapeStyleUpdate, setStyle, updateFill, updateFont, updateStroke } from './style/utils'; +import { getCellStyleClone, isShapeStyleUpdate, setCssClasses, setStyle, updateFill, updateFont, updateStroke } from './style/utils'; import { StyleManager } from './style/StyleManager'; import type { BpmnGraph } from './BpmnGraph'; @@ -26,12 +26,13 @@ import { OverlayConverter } from './overlay/OverlayConverter'; import { messageFlowIconId } from './BpmnRenderer'; import { ensureOpacityValue } from '../helpers/validators'; import type { BPMNCellStyle } from './renderer/StyleComputer'; +import { cloneUtils } from '@maxgraph/core'; /** * @internal */ export function newGraphCellUpdater(graph: BpmnGraph, cssRegistry: CssRegistry): GraphCellUpdater { - return new GraphCellUpdater(graph, new OverlayConverter(), new StyleManager(cssRegistry, graph.getModel())); + return new GraphCellUpdater(graph, new OverlayConverter(), new StyleManager(cssRegistry, graph.getDataModel())); } /** @@ -51,7 +52,7 @@ export default class GraphCellUpdater { } private updateAndRefreshCssClassesOfElement(elementId: string, cssClasses: string[]): void { - const model = this.graph.model; + const model = this.graph.getDataModel(); const cell = model.getCell(elementId); if (!cell) { return; @@ -59,18 +60,14 @@ export default class GraphCellUpdater { this.styleManager.ensureStyleIsStored(cell); - let cellStyle = cell.getStyle(); - // TODO rebase adapt code for maxgraph - cellStyle = setStyle(cellStyle, BpmnStyleIdentifier.EXTRA_CSS_CLASSES, cssClasses.join(',')); + const cellStyle: BPMNCellStyle = getCellStyleClone(cell); + setCssClasses(cellStyle, cssClasses); + model.setStyle(cell, cellStyle); - // TODO magraph@0.1.0 improve logic - // const style = state.style as BPMNCellStyle; - // !style.bpmn.extra && (style.bpmn.extra = { css: { classes: undefined } }); - // style.bpmn.extra.css.classes = cssClasses; } addOverlays(bpmnElementId: string, overlays: Overlay | Overlay[]): void { - const cell = this.graph.model.getCell(bpmnElementId); + const cell = this.graph.getDataModel().getCell(bpmnElementId); if (!cell) { return; } @@ -81,7 +78,7 @@ export default class GraphCellUpdater { } removeAllOverlays(bpmnElementId: string): void { - const cell = this.graph.model.getCell(bpmnElementId); + const cell = this.graph.getDataModel().getCell(bpmnElementId); if (!cell) { return; } @@ -95,7 +92,7 @@ export default class GraphCellUpdater { return; } - const model = this.graph.getModel(); + const model = this.graph.getDataModel(); const cells = withCellIdsOfMessageFlowIcons(bpmnElementIds) .map(id => model.getCell(id)) .filter(Boolean); @@ -108,16 +105,17 @@ export default class GraphCellUpdater { for (const cell of cells) { this.styleManager.ensureStyleIsStored(cell); - let cellStyle = cell.getStyle(); - cellStyle = setStyle(cellStyle, mxConstants.STYLE_OPACITY, styleUpdate.opacity, ensureOpacityValue); - cellStyle = updateStroke(cellStyle, styleUpdate.stroke); - cellStyle = updateFont(cellStyle, styleUpdate.font); + const cellStyle = getCellStyleClone(cell); + setStyle(cellStyle, 'opacity', styleUpdate.opacity, ensureOpacityValue); + updateStroke(cellStyle, styleUpdate.stroke); + updateFont(cellStyle, styleUpdate.font); if (isShapeStyleUpdate(styleUpdate)) { - cellStyle = updateFill(cellStyle, styleUpdate.fill); + updateFill(cellStyle, styleUpdate.fill); } - this.graph.model.setStyle(cell, cellStyle); + // TODO maxgraph@0.1.0 migration --> apply this to the master branch graph.model --> model + model.setStyle(cell, cellStyle); } }); } diff --git a/src/component/mxgraph/GraphConfigurator.ts b/src/component/mxgraph/GraphConfigurator.ts index cdaa3d3e99..9c7a7dca1b 100644 --- a/src/component/mxgraph/GraphConfigurator.ts +++ b/src/component/mxgraph/GraphConfigurator.ts @@ -63,7 +63,7 @@ export default class GraphConfigurator { } private configureNavigationSupport(options: GlobalOptions): void { - // TODO magraph@0.1.0 decide if we hide this maxGraph implementation details in BpmnGraph + // TODO maxgraph@0.1.0 decide if we hide this maxGraph implementation details in BpmnGraph // In theory, the panningHandler may not be available if its plugin is not registered. The maxGraph code sometimes check for availability. For now, the check is not needed as we know that we load it const panningHandler = this.graph.getPlugin('PanningHandler'); diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index ee3c5a83cf..5e82ca5116 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { CellState, CellOverlay } from '@maxgraph/core'; -import { CellRenderer, Shape, Rectangle, ImageShape, Dictionary, SvgCanvas2D, constants } from '@maxgraph/core'; +import { CellRenderer, constants, Dictionary, ImageShape, Rectangle, Shape, SvgCanvas2D } from '@maxgraph/core'; +import type { CellOverlay, CellState } from '@maxgraph/core'; import { ShapeBpmnElementKind } from '../../../model/bpmn/internal'; import { EndEventShape, EventShape, IntermediateEventShape, ThrowIntermediateEventShape } from '../shape/event-shapes'; @@ -34,12 +34,13 @@ import { } from '../shape/activity-shapes'; import { TextAnnotationShape } from '../shape/text-annotation-shapes'; import { MessageFlowIconShape } from '../shape/flow-shapes'; -import { BpmnStyleIdentifier, FONT } from '../style'; +import { BpmnStyleIdentifier } from '../style'; +import { FONT } from '../style/utils'; import { computeAllBpmnClassNamesOfCell } from '../renderer/style-utils'; +import type { BPMNCellStyle } from '../renderer/StyleComputer'; import { MxGraphCustomOverlay } from '../overlay/custom-overlay'; import { OverlayBadgeShape } from '../overlay/shapes'; import { BpmnConnector } from '../shape/edges'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; /** * @internal @@ -60,19 +61,19 @@ export default class ShapeConfigurator { CellRenderer.registerShape(ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, IntermediateEventShape); CellRenderer.registerShape(ShapeBpmnElementKind.EVENT_BOUNDARY, IntermediateEventShape); // gateways - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_COMPLEX, ComplexGatewayShape); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_EVENT_BASED, EventBasedGatewayShape); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_EXCLUSIVE, ExclusiveGatewayShape); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_INCLUSIVE, InclusiveGatewayShape); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_PARALLEL, ParallelGatewayShape); // activities @@ -88,15 +89,15 @@ export default class ShapeConfigurator { CellRenderer.registerShape(ShapeBpmnElementKind.TASK_SCRIPT, ScriptTaskShape); CellRenderer.registerShape(ShapeBpmnElementKind.TASK_BUSINESS_RULE, BusinessRuleTaskShape); // artifacts - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.TEXT_ANNOTATION, TextAnnotationShape); // shapes for flows - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call // @ts-ignore CellRenderer.registerShape(BpmnStyleIdentifier.EDGE, BpmnConnector); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO magraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call // @ts-ignore CellRenderer.registerShape(BpmnStyleIdentifier.MESSAGE_FLOW_ICON, MessageFlowIconShape); } @@ -168,13 +169,13 @@ export default class ShapeConfigurator { // 'this.state.style' = the style definition associated with the cell // 'this.state.cell.style' = the style applied to the cell: 1st element: style name = bpmn shape name const cell = this.state.cell; - // dialect = strictHtml is set means that current node holds an html label - // TODO magraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided."constants.DIALECT.STRICTHTML + // dialect = strictHtml is set means that current node holds an HTML label + // TODO maxgraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided."constants.DIALECT.STRICTHTML let allBpmnClassNames = computeAllBpmnClassNamesOfCell(cell, this.dialect === 'strictHtml'); - const extraCssClasses = (this.state.style as BPMNCellStyle).bpmn?.extra?.css?.classes; - // TODO rebase verify the cssClasses property type in BPMNCellStyle - if (typeof extraCssClasses == 'string') { - allBpmnClassNames = allBpmnClassNames.concat(extraCssClasses.split(',')); + // TODO maxgraph@0.1.0 - do we need to introduce a BpmnCellStateStyle type (to not have the baseStyleName property)? + const extraCssClasses = (this.state.style as BPMNCellStyle).bpmn?.extraCssClasses; + if (extraCssClasses) { + allBpmnClassNames = allBpmnClassNames.concat(extraCssClasses); } this.node.setAttribute('class', allBpmnClassNames.join(' ')); diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 8e7d8a7a92..e95098457b 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -14,13 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { ArrowType, ShapeValue, Stylesheet } from '@maxgraph/core'; -import { constants, Perimeter } from '@maxgraph/core'; - import { AssociationDirectionKind, FlowKind, SequenceFlowKind, ShapeBpmnElementKind, ShapeUtil } from '../../../model/bpmn/internal'; import { BpmnStyleIdentifier, MarkerIdentifier, StyleDefault } from '../style'; import type { BpmnGraph } from '../BpmnGraph'; import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import { constants, Perimeter } from '@maxgraph/core'; +import type { ArrowType, ShapeValue, Stylesheet } from '@maxgraph/core'; const arrowDefaultSize = 12; @@ -33,7 +32,7 @@ const arrowDefaultSize = 12; * @experimental */ export class StyleConfigurator { - // TODO magraph@0.1.0 in StyleConfigurator, we don't need to use BPMNCellStyle, CellStyle is enough + // TODO maxgraph@0.1.0 in StyleConfigurator, we don't need to use BPMNCellStyle, CellStyle is enough private specificFlowStyles = new MapWithDefault([ [ @@ -49,11 +48,11 @@ export class StyleConfigurator { style.dashPattern = '8 5'; style.startArrow = 'oval'; style.startSize = 8; - style.startFill = true; - style.bpmn.edge.startFillColor = StyleDefault.MESSAGE_FLOW_MARKER_START_FILL_COLOR; + style.startFill = true; // TODO maxgraph@0.1.0 could be removed when maxGraph fixes https://github.com/maxGraph/maxGraph/pull/157 + style.startFillColor = StyleDefault.MESSAGE_FLOW_MARKER_START_FILL_COLOR; style.endArrow = 'blockThin'; - style.endFill = true; - style.bpmn.edge.endFillColor = StyleDefault.MESSAGE_FLOW_MARKER_END_FILL_COLOR; + style.endFill = true; // TODO maxgraph@0.1.0 could be removed when maxGraph fixes https://github.com/maxGraph/maxGraph/pull/157 + style.endFillColor = StyleDefault.MESSAGE_FLOW_MARKER_END_FILL_COLOR; }, ], [ @@ -61,10 +60,8 @@ export class StyleConfigurator { (style: BPMNCellStyle) => { style.dashed = true; style.dashPattern = '1 2'; - // TODO maxgraph@0.1.0 migration - update comment // STYLE_ENDARROW and STYLE_STARTARROW are defined in specific AssociationDirectionKind styles when needed - // style.endArrow = 'openThin'; - // style.startArrow = 'openThin'; - style.startSize = 12; + // endArrow and startArrow are defined in specific AssociationDirectionKind styles when needed + style.startSize = arrowDefaultSize; }, ], ]); @@ -72,7 +69,7 @@ export class StyleConfigurator { [ SequenceFlowKind.DEFAULT, (style: BPMNCellStyle) => { - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types style.startArrow = MarkerIdentifier.ARROW_DASH; }, ], @@ -81,27 +78,14 @@ export class StyleConfigurator { (style: BPMNCellStyle) => { style.startArrow = 'diamondThin'; style.startSize = 18; - style.startFill = true; - style.bpmn.edge.startFillColor = StyleDefault.SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR; + style.startFill = true; // TODO maxgraph@0.1.0 could be removed when maxGraph fixes https://github.com/maxGraph/maxGraph/pull/157 + style.startFillColor = StyleDefault.SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR; }, ], ]); private specificAssociationFlowStyles = new MapWithDefault([ [ AssociationDirectionKind.NONE, - (style: BPMNCellStyle) => { - style.startArrow = undefined; - style.endArrow = undefined; - }, - ], - [ - AssociationDirectionKind.ONE, - (style: BPMNCellStyle) => { - style.startArrow = undefined; - }, - ], - [ - AssociationDirectionKind.BOTH, // eslint-disable-next-line @typescript-eslint/no-unused-vars -- prefix parameter name - common practice to acknowledge the fact that some parameter is unused (e.g. in TypeScript compiler) (_style: BPMNCellStyle) => { // the style is fully managed by the FlowKind.ASSOCIATION_FLOW style @@ -109,15 +93,15 @@ export class StyleConfigurator { ], [ AssociationDirectionKind.ONE, - (style: StyleMap) => { - style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_OPEN_THIN; + (style: BPMNCellStyle) => { + style.endArrow = 'openThin'; }, ], [ AssociationDirectionKind.BOTH, - (style: StyleMap) => { - style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_OPEN_THIN; - style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_OPEN_THIN; + (style: BPMNCellStyle) => { + style.endArrow = 'openThin'; + style.startArrow = 'openThin'; }, ], ]); @@ -150,19 +134,24 @@ export class StyleConfigurator { } private configureDefaultVertexStyle(): void { - StyleConfigurator.configureCommonDefaultStyle(this.getStylesheet().getDefaultVertexStyle() as BPMNCellStyle); + const style = this.getStylesheet().getDefaultVertexStyle(); + configureCommonDefaultStyle(style); + + // TODO maxgraph@0.1.0 arcSize should be a boolean (probably fixed in next versions of maxGraph) + style.absoluteArcSize = 1; + style.arcSize = StyleDefault.SHAPE_ARC_SIZE; } private configurePoolStyle(): void { const style: BPMNCellStyle = { - // TODO magraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE + // TODO maxgraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE shape: 'swimlane', // label style verticalAlign: 'middle', align: 'center', - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast startSize: StyleDefault.POOL_LABEL_SIZE, - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast fillColor: StyleDefault.POOL_LABEL_FILL_COLOR, }; @@ -171,15 +160,15 @@ export class StyleConfigurator { private configureLaneStyle(): void { const style: BPMNCellStyle = { - // TODO magraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE + // TODO maxgraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE shape: 'swimlane', // label style verticalAlign: 'middle', align: 'center', swimlaneLine: false, // hide the line between the title region and the content area - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast startSize: StyleDefault.LANE_LABEL_SIZE, - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast fillColor: StyleDefault.LANE_LABEL_FILL_COLOR, }; @@ -189,10 +178,10 @@ export class StyleConfigurator { private configureEventStyles(): void { ShapeUtil.eventKinds().forEach(kind => { const style: BPMNCellStyle = { - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types shape: (kind), perimeter: Perimeter.EllipsePerimeter, - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast strokeWidth: (kind == ShapeBpmnElementKind.EVENT_END ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN), verticalLabelPosition: 'bottom', }; @@ -202,15 +191,15 @@ export class StyleConfigurator { private configureTextAnnotationStyle(): void { const style: BPMNCellStyle = { - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types shape: (ShapeBpmnElementKind.TEXT_ANNOTATION), // label style verticalAlign: 'middle', align: 'left', spacingLeft: 5, - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast fillColor: StyleDefault.TEXT_ANNOTATION_FILL_COLOR, - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast strokeWidth: StyleDefault.STROKE_WIDTH_THIN, }; this.putCellStyle(ShapeBpmnElementKind.TEXT_ANNOTATION, style); @@ -219,16 +208,12 @@ export class StyleConfigurator { private configureGroupStyle(): void { const style: BPMNCellStyle = { rounded: true, - absoluteArcSize: 1, - // TODO magraph@0.1.0 find a way to not force cast - arcSize: StyleDefault.SHAPE_ARC_SIZE, dashed: true, dashPattern: '7 4 1 4', - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast strokeWidth: StyleDefault.STROKE_WIDTH_THIN, - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast fillColor: StyleDefault.GROUP_FILL_COLOR, - // Default label positioning align: 'center', verticalAlign: 'top', @@ -239,18 +224,11 @@ export class StyleConfigurator { private configureActivityStyles(): void { ShapeUtil.activityKinds().forEach(kind => { const style: BPMNCellStyle = { - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types shape: (kind), rounded: true, // required by the BPMN specification - - // TODO rebase arcSize seems to have been moved in another configuration - //absoluteArcSize: 1, - // TODO magraph@0.1.0 find a way to not force cast - //arcSize: StyleDefault.SHAPE_ARC_SIZE, - - // label style - verticalAlign: 'middle', - // TODO magraph@0.1.0 find a way to not force cast + verticalAlign: 'middle', // label style + // TODO maxgraph@0.1.0 find a way to not force cast strokeWidth: (kind == ShapeBpmnElementKind.CALL_ACTIVITY ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN), }; this.putCellStyle(kind, style); @@ -260,11 +238,11 @@ export class StyleConfigurator { private configureGatewayStyles(): void { ShapeUtil.gatewayKinds().forEach(kind => { const style: BPMNCellStyle = { - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types shape: (kind), perimeter: Perimeter.RhombusPerimeter, verticalAlign: 'top', - // TODO magraph@0.1.0 find a way to not force cast + // TODO maxgraph@0.1.0 find a way to not force cast strokeWidth: StyleDefault.STROKE_WIDTH_THIN, // Default label positioning @@ -279,34 +257,20 @@ export class StyleConfigurator { const style = this.getStylesheet().getDefaultEdgeStyle() as BPMNCellStyle; configureCommonDefaultStyle(style); - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types style.shape = BpmnStyleIdentifier.EDGE; - style.endSize = 12; + style.endSize = arrowDefaultSize; style.strokeWidth = 1.5; style.rounded = true; style.arcSize = 5; style.verticalAlign = 'bottom'; // The end arrow must be redefined in specific style - style.endArrow = undefined; - } - - // TODO rebase move to a function out of the class - private static configureCommonDefaultStyle(style: BPMNCellStyle): void { - style.fontFamily = StyleDefault.DEFAULT_FONT_FAMILY; - style.fontSize = StyleDefault.DEFAULT_FONT_SIZE; - style.fontColor = StyleDefault.DEFAULT_FONT_COLOR; - style.fillColor = StyleDefault.DEFAULT_FILL_COLOR; - style.strokeColor = StyleDefault.DEFAULT_STROKE_COLOR; - style.labelBackgroundColor = constants.NONE; - - // only works with html labels (enabled by GraphConfigurator) - style.whiteSpace = 'wrap'; + delete style.endArrow; } private configureEdgeStyles(styleKinds: T[], specificStyles: Map void>): void { styleKinds.forEach(kind => { - // TODO magraph@0.1.0 review if we need to set bpmn.edge (this is not enough for edge.ts) - const style: BPMNCellStyle = { bpmn: { edge: {} } }; + const style: BPMNCellStyle = {}; specificStyles.get(kind)(style); this.graph.getStylesheet().putCellStyle(kind.toString(), style); }); @@ -319,17 +283,16 @@ export class StyleConfigurator { } } -// TODO rebase fix -function configureCommonDefaultStyle(style: StyleMap): void { - style[mxConstants.STYLE_FONTFAMILY] = StyleDefault.DEFAULT_FONT_FAMILY; - style[mxConstants.STYLE_FONTSIZE] = StyleDefault.DEFAULT_FONT_SIZE; - style[mxConstants.STYLE_FONTCOLOR] = StyleDefault.DEFAULT_FONT_COLOR; - style[mxConstants.STYLE_FILLCOLOR] = StyleDefault.DEFAULT_FILL_COLOR; - style[mxConstants.STYLE_STROKECOLOR] = StyleDefault.DEFAULT_STROKE_COLOR; - style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR] = mxConstants.NONE; +function configureCommonDefaultStyle(style: BPMNCellStyle): void { + style.fontFamily = StyleDefault.DEFAULT_FONT_FAMILY; + style.fontSize = StyleDefault.DEFAULT_FONT_SIZE; + style.fontColor = StyleDefault.DEFAULT_FONT_COLOR; + style.fillColor = StyleDefault.DEFAULT_FILL_COLOR; + style.strokeColor = StyleDefault.DEFAULT_STROKE_COLOR; + style.labelBackgroundColor = constants.NONE; // only works with html labels (enabled by GraphConfigurator) - style[mxConstants.STYLE_WHITE_SPACE] = 'wrap'; + style.whiteSpace = 'wrap'; } class MapWithDefault extends Map void> { diff --git a/src/component/mxgraph/overlay/custom-overlay.ts b/src/component/mxgraph/overlay/custom-overlay.ts index dac6de54b9..7aaf754c01 100644 --- a/src/component/mxgraph/overlay/custom-overlay.ts +++ b/src/component/mxgraph/overlay/custom-overlay.ts @@ -1,5 +1,5 @@ /* -Copyright 2023 Bonitasoft S.A. +Copyright 2021 Bonitasoft S.A. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { CellState } from '@maxgraph/core'; import { CellOverlay, Point, Rectangle } from '@maxgraph/core'; +import type { CellState } from '@maxgraph/core'; import type { OverlayStyle } from '../../registry'; diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index 7c06f08ad5..b90cb21e99 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { CellStyle, ShapeValue } from '@maxgraph/core'; +import type { AlignValue, CellStyle, ShapeValue } from '@maxgraph/core'; import Shape from '../../../model/bpmn/internal/shape/Shape'; import type { Edge } from '../../../model/bpmn/internal/edge/edge'; @@ -28,7 +28,8 @@ import { ShapeBpmnStartEvent, ShapeBpmnSubProcess, } from '../../../model/bpmn/internal/shape/ShapeBpmnElement'; -import { BpmnStyleIdentifier, FONT } from '../style'; +import { BpmnStyleIdentifier } from '../style'; +import { FONT } from '../style/utils'; import type { AssociationDirectionKind, FlowKind, @@ -43,15 +44,22 @@ import { AssociationFlow, SequenceFlow } from '../../../model/bpmn/internal/edge import type { Font } from '../../../model/bpmn/internal/Label'; import type { RendererOptions } from '../../options'; -// TODO magraph@0.1.0 this type should probably be part of the API (so it should be exported) +// TODO maxgraph@0.1.0 this type should probably be part of the API (so it should be exported) +// TODO maxgraph@0.1.0 move somewhere else +// TODO maxgraph@0.1.0 rename for consistent naming BPMNCellStyle --> BpmnCellStyle (apply to other places) +// a BpmnCellStyle exists in tests. Try to use this one instead export interface BPMNCellStyle extends CellStyle { - // TODO magraph@0.1.0 the shape property is defined as 'ShapeValue'. It should be 'ShapeValue | string' + // TODO maxgraph@0.1.0 fill markers properties to remove when https://github.com/maxGraph/maxGraph/issues/201 is available + endFillColor?: string; + // TODO maxgraph@0.1.0 fill markers properties to remove when https://github.com/maxGraph/maxGraph/issues/201 is available + startFillColor?: string; + // TODO maxgraph@0.1.0 the shape property is defined as 'ShapeValue'. It should be 'ShapeValue | string' // Omit { // shape?: ShapeValue | string; - // TODO magraph@0.1.0 make bpmn mandatory? + // TODO maxgraph@0.1.0 make bpmn mandatory? bpmn?: { - // TODO magraph@0.1.0 sort properties in alphabetical order for clarity (and as done in maxGraph CellStyle) and provide documentation about each property - // TODO magraph@0.1.0 make kind mandatory? + // TODO maxgraph@0.1.0 sort properties in alphabetical order for clarity (and as done in maxGraph CellStyle) and provide documentation about each property + // TODO maxgraph@0.1.0 make kind mandatory? kind?: ShapeBpmnElementKind | FlowKind; isInstantiating?: boolean; gatewayKind?: ShapeBpmnEventBasedGatewayKind; @@ -62,17 +70,8 @@ export interface BPMNCellStyle extends CellStyle { markers?: ShapeBpmnMarkerKind[]; sequenceFlowKind?: SequenceFlowKind; associationDirectionKind?: AssociationDirectionKind; - // TODO magraph@0.1.0 isNonInitiating: previously we add a string, this introduces extra changes. If we want to keep this, do it in the master branch - isNonInitiating?: boolean; // TODO magraph@0.1.0 why not 'isInitiating' for consistency with other boolean value? Negate doesn't make things easier to understand - extra?: { - css: { - classes: string[]; - }; - }; - edge?: { - endFillColor?: string; - startFillColor?: string; - }; + isInitiating?: boolean; + extraCssClasses?: string[]; }; } @@ -94,19 +93,21 @@ export default class StyleComputer { const baseStyleNames: string[] = [bpmnCell.bpmnElement.kind as string]; if (bpmnCell instanceof Shape) { - // TODO magraph@0.1.0 find a better way for the merge - StyleComputer.enrichStyleWithShapeInfo(style, bpmnCell); + // TODO maxgraph@0.1.0 find a better way for the merge - computeShapeBaseStylesValues and returns a CellStyle for consistency with other methods + this.enrichStyleWithShapeInfo(style, bpmnCell); } else { baseStyleNames.push(...StyleComputer.computeEdgeBaseStyleNames(bpmnCell)); + // TODO maxgraph@0.1.0 find a better way for the merge - computeEdgeBaseStylesValues and returns a CellStyle for consistency with other methods + this.enrichStyleWithEdgeInfo(style, bpmnCell); } const fontStyleValues = this.computeFontStyleValues(bpmnCell); const labelStyleValues = StyleComputer.computeLabelStyleValues(bpmnCell, labelBounds); - return { baseStyleNames: baseStyleNames, ...style, ...fontStyleValues, ...labelStyleValues }; + return { baseStyleNames, ...style, ...fontStyleValues, ...labelStyleValues }; } - private static enrichStyleWithShapeInfo(style: BPMNCellStyle, shape: Shape): void { + private enrichStyleWithShapeInfo(style: BPMNCellStyle, shape: Shape): void { const bpmnElement = shape.bpmnElement; if (bpmnElement instanceof ShapeBpmnEvent) { @@ -116,30 +117,24 @@ export default class StyleComputer { } else if (ShapeUtil.isPoolOrLane(bpmnElement.kind)) { // 'style.horizontal' is for the label // In BPMN, isHorizontal is for the Shape - // TODO rebase adapt comment - // mxConstants.STYLE_HORIZONTAL is for the label - // In BPMN, isHorizontal is for the Shape // So we invert the value when we switch from the BPMN value to the mxGraph value. - style.horizontal = !(shape.isHorizontal ?? true); + style.horizontal = !shape.isHorizontal; } else if (bpmnElement instanceof ShapeBpmnEventBasedGateway) { style.bpmn.isInstantiating = bpmnElement.instantiate; style.bpmn.gatewayKind = bpmnElement.gatewayKind; } - // TODO rebase adapt for maxGraph if (!this.ignoreBpmnColors) { const extensions = shape.extensions; const fillColor = extensions.fillColor; if (fillColor) { - styleValues.set(mxConstants.STYLE_FILLCOLOR, fillColor); + style.fillColor = fillColor; if (ShapeUtil.isPoolOrLane(bpmnElement.kind)) { - styleValues.set(mxConstants.STYLE_SWIMLANE_FILLCOLOR, fillColor); + style.swimlaneFillColor = fillColor; } } - extensions.strokeColor && styleValues.set(mxConstants.STYLE_STROKECOLOR, extensions.strokeColor); + extensions.strokeColor && (style.strokeColor = extensions.strokeColor); } - - return styleValues; } private static computeEventShapeStyle(bpmnElement: ShapeBpmnEvent, style: BPMNCellStyle): void { @@ -162,7 +157,7 @@ export default class StyleComputer { style.bpmn.markers = bpmnElement.markers; } - // TODO magraph@0.1.0 switch from static method to function (same in other places of this class) --> TODO in master branch + // TODO maxgraph@0.1.0 switch from static method to function (same in other places of this class) --> TODO in master branch // This applies to the current implementation and to all static methods of this class private static computeEdgeBaseStyleNames(edge: Edge): string[] { const styles: string[] = []; @@ -178,15 +173,11 @@ export default class StyleComputer { return styles; } - private computeEdgeStyleValues(edge: Edge): Map { - const styleValues = new Map(); - + private enrichStyleWithEdgeInfo(style: BPMNCellStyle, edge: Edge): void { if (!this.ignoreBpmnColors) { const extensions = edge.extensions; - extensions.strokeColor && styleValues.set(mxConstants.STYLE_STROKECOLOR, extensions.strokeColor); + extensions.strokeColor && (style.strokeColor = extensions.strokeColor); } - - return styleValues; } private computeFontStyleValues(bpmnCell: Shape | Edge): CellStyle { @@ -196,13 +187,13 @@ export default class StyleComputer { if (font) { font.name && (style.fontFamily = font.name); font.size && (style.fontSize = font.size); - style.fontStyle = StyleComputer.getFontStyleValue(font); + const fontStyleValue = getFontStyleValue(font); + fontStyleValue && (style.fontStyle = fontStyleValue); } - // TODO rebase adapt for maxGraph if (!this.ignoreBpmnColors) { const extensions = bpmnCell.label?.extensions; - extensions?.color && styleValues.set(mxConstants.STYLE_FONTCOLOR, extensions.color); + extensions?.color && (style.fontColor = extensions.color); } return style; @@ -225,12 +216,9 @@ export default class StyleComputer { // According to the documentation, "label position" can only take values in left, center, right with default=center // However, there is undocumented behavior when the value is not one of these and this behavior is exactly what we want. // See https://github.com/jgraph/mxgraph/blob/v4.2.2/javascript/src/js/view/mxGraphView.js#L1183-L1252 - // FIXME magraph@0.1.0 values were inverted in the mxGraph implementation, this was probably wrong as they were set like this in StyleConfigurator (fixed in master branch) - // styleValues.set(mxConstants.STYLE_LABEL_POSITION, 'ignore'); - // styleValues.set(mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE); - // TODO rebase adapt label position for maxGraph - style.labelPosition = 'left'; - style.verticalLabelPosition = 'top'; + // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) + style.labelPosition = 'ignore'; + style.verticalLabelPosition = 'middle'; // end of fixme } } @@ -248,17 +236,15 @@ export default class StyleComputer { } computeMessageFlowIconStyle(edge: Edge): BPMNCellStyle { - return { - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + const style: BPMNCellStyle = { + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types shape: BpmnStyleIdentifier.MESSAGE_FLOW_ICON, - // TODO rebase, isNonInitiating --> isInitiating - // styleValues.push([BpmnStyleIdentifier.IS_INITIATING, String(edge.messageVisibleKind === MessageVisibleKind.INITIATING)]); - bpmn: { isNonInitiating: edge.messageVisibleKind === MessageVisibleKind.NON_INITIATING }, + bpmn: { isInitiating: edge.messageVisibleKind === MessageVisibleKind.INITIATING }, }; - // TODO rebase for maxGraph, handle bpmn in color - // if (!this.ignoreBpmnColors) { - // edge.extensions.strokeColor && styleValues.push([mxConstants.STYLE_STROKECOLOR, edge.extensions.strokeColor]); - // } + if (!this.ignoreBpmnColors) { + edge.extensions.strokeColor && (style.strokeColor = edge.extensions.strokeColor); + } + return style; } } diff --git a/src/component/mxgraph/renderer/style-utils.ts b/src/component/mxgraph/renderer/style-utils.ts index 82362a0814..fcede27270 100644 --- a/src/component/mxgraph/renderer/style-utils.ts +++ b/src/component/mxgraph/renderer/style-utils.ts @@ -40,7 +40,7 @@ export function computeAllBpmnClassNamesOfCell(cell: Cell, isLabel: boolean): st export function computeAllBpmnClassNames(style: BPMNCellStyle, isLabel: boolean): string[] { const classes: string[] = []; - // TODO magraph@0.1.0 style.bpmn.kind could be omit by considering the first element of style.baseStyleNames (this would restore the previous behavior) + // TODO maxgraph@0.1.0 style.bpmn.kind could be omit by considering the first element of style.baseStyleNames (this would restore the previous behavior) // if kind is not set, check shape: bpmn.message-flow-icon --> message-flow-icon const bpmnElementKind = style.bpmn?.kind ?? style.shape?.replace(/bpmn./g, ''); @@ -61,13 +61,8 @@ export function computeAllBpmnClassNames(style: BPMNCellStyle, isLabel: boolean) if (style.bpmn?.gatewayKind) { classes.push(`bpmn-gateway-kind-${style.bpmn.gatewayKind.toLowerCase()}`); } - // TODO rebase use "initiating" and not "isNonInitiating" to restore the implementation of the master branch - // message flow icon - // case BpmnStyleIdentifier.IS_INITIATING: // message flow icon - // classes.push(value == 'true' ? 'bpmn-icon-initiating' : 'bpmn-icon-non-initiating'); - // break; - if (style.bpmn?.isNonInitiating !== undefined) { - classes.push(style.bpmn.isNonInitiating ? 'bpmn-icon-non-initiating' : 'bpmn-icon-initiating'); + if (style.bpmn?.isInitiating !== undefined) { + classes.push(style.bpmn.isInitiating ? 'bpmn-icon-initiating' : 'bpmn-icon-non-initiating'); } if (style.bpmn?.subProcessKind) { classes.push(`bpmn-sub-process-${style.bpmn.subProcessKind.toLowerCase()}`); diff --git a/src/component/mxgraph/shape/edges.ts b/src/component/mxgraph/shape/edges.ts index 947268343b..a1b0974a92 100644 --- a/src/component/mxgraph/shape/edges.ts +++ b/src/component/mxgraph/shape/edges.ts @@ -19,7 +19,7 @@ import { SvgCanvas2D, ConnectorShape } from '@maxgraph/core'; import type { BPMNCellStyle } from '../renderer/StyleComputer'; -// TODO magraph@0.1.0 remove to use the new support of endFillColor and starFillColor provided by https://github.com/maxGraph/maxGraph/issues/201 +// TODO maxgraph@0.1.0 remove the BpmnConnector class to use the new support of endFillColor and starFillColor provided by https://github.com/maxGraph/maxGraph/issues/201 export class BpmnConnector extends ConnectorShape { constructor(points: Point[], stroke: string, strokewidth?: number) { super(points, stroke, strokewidth); @@ -39,12 +39,12 @@ export class BpmnConnector extends ConnectorShape { c.setDashed(false, false); if (sourceMarker != null) { - c.setFillColor((this.style as BPMNCellStyle).bpmn?.edge?.startFillColor ?? this.stroke); + c.setFillColor((this.style as BPMNCellStyle).startFillColor ?? this.stroke); sourceMarker(); } if (targetMarker != null) { - c.setFillColor((this.style as BPMNCellStyle).bpmn?.edge?.endFillColor ?? this.stroke); + c.setFillColor((this.style as BPMNCellStyle).endFillColor ?? this.stroke); targetMarker(); } } diff --git a/src/component/mxgraph/shape/event-shapes.ts b/src/component/mxgraph/shape/event-shapes.ts index fce201acfe..c4d91ff7b3 100644 --- a/src/component/mxgraph/shape/event-shapes.ts +++ b/src/component/mxgraph/shape/event-shapes.ts @@ -108,7 +108,7 @@ export class EventShape extends EllipseShape { private static setDashedOuterShapePattern(paintParameter: PaintParameter, isInterrupting: boolean): void { paintParameter.canvas.save(); // ensure we can later restore the configuration - // TODO magraph@0.1.0 'isInterrupting' can be undefined in maxGraph whereas it wasn't with mxGraph + // TODO maxgraph@0.1.0 'isInterrupting' can be undefined in maxGraph whereas it wasn't with mxGraph if (isInterrupting === false) { paintParameter.canvas.setDashed(true, false); paintParameter.canvas.setDashPattern('3 2'); diff --git a/src/component/mxgraph/shape/flow-shapes.ts b/src/component/mxgraph/shape/flow-shapes.ts index 5af884e6b0..78fe94616f 100644 --- a/src/component/mxgraph/shape/flow-shapes.ts +++ b/src/component/mxgraph/shape/flow-shapes.ts @@ -14,12 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { AbstractCanvas2D, Rectangle } from '@maxgraph/core'; -import { RectangleShape } from '@maxgraph/core'; - import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import { RectangleShape } from '@maxgraph/core'; +import type { AbstractCanvas2D, Rectangle } from '@maxgraph/core'; /** * @internal @@ -32,8 +31,16 @@ export class MessageFlowIconShape extends RectangleShape { } override paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { - const withFilledIcon = (this.style as BPMNCellStyle).bpmn.isNonInitiating; - const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this, ratioFromParent: 1, isFilled: withFilledIcon }); + const paintParameter = buildPaintParameter({ + canvas: c, + x, + y, + width: w, + height: h, + shape: this, + ratioFromParent: 1, + isFilled: !((this.style as BPMNCellStyle).bpmn.isInitiating ?? true), + }); this.iconPainter.paintEnvelopeIcon(paintParameter); } diff --git a/src/component/mxgraph/style/StyleManager.ts b/src/component/mxgraph/style/StyleManager.ts index 180eeb9398..ceeaf231b7 100644 --- a/src/component/mxgraph/style/StyleManager.ts +++ b/src/component/mxgraph/style/StyleManager.ts @@ -13,15 +13,15 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import type { mxCell, mxGraphModel } from 'mxgraph'; -import { BpmnStyleIdentifier } from '.'; -import { setStyle } from './utils'; +import type { Cell, CellStyle, GraphDataModel } from '@maxgraph/core'; +import { getCellStyleClone, setCssClasses } from './utils'; import type { CssRegistry } from '../../registry/css-registry'; +import type { BPMNCellStyle } from '../renderer/StyleComputer'; export class StyleManager { - private stylesCache: Map = new Map(); + private stylesCache: Map = new Map(); - constructor(readonly cssRegistry: CssRegistry, readonly model: mxGraphModel) {} + constructor(readonly cssRegistry: CssRegistry, readonly model: GraphDataModel) {} clear(): void { this.stylesCache.clear(); @@ -29,6 +29,7 @@ export class StyleManager { resetAllStyles(): void { for (const cellId of this.stylesCache.keys()) { + // TODO inline in master branch const style = this.stylesCache.get(cellId); this.resetStyle(cellId, style); } @@ -46,20 +47,22 @@ export class StyleManager { } } - private resetStyle(cellId: string, style: string): void { + private resetStyle(cellId: string, style: BPMNCellStyle): void { const cell = this.model.getCell(cellId); + // TODO maxGraph 0.1.0 - inline (can be done in the master branch as well) const cssClasses = this.cssRegistry.getClassNames(cellId); - const styleWithCssClasses = setStyle(style, BpmnStyleIdentifier.EXTRA_CSS_CLASSES, cssClasses.join(',')); - this.model.setStyle(cell, styleWithCssClasses); + // no need to copy the style, it is coming from the cache only and is later deleted from the cache + setCssClasses(style, cssClasses); + this.model.setStyle(cell, style); this.stylesCache.delete(cellId); } - ensureStyleIsStored(cell: mxCell): void { + ensureStyleIsStored(cell: Cell): void { const cellId = cell.getId(); if (!this.stylesCache.has(cellId)) { - this.stylesCache.set(cellId, cell.getStyle()); + this.stylesCache.set(cellId, getCellStyleClone(cell)); } } } diff --git a/src/component/mxgraph/style/identifiers.ts b/src/component/mxgraph/style/identifiers.ts index 79feb14ea5..5f6e975b64 100644 --- a/src/component/mxgraph/style/identifiers.ts +++ b/src/component/mxgraph/style/identifiers.ts @@ -22,7 +22,7 @@ limitations under the License. * @category BPMN Theme * @experimental */ -// TODO real maxGraph migration - may be renamed into BpmnShapeIdentifier after the maxGraph migration +// TODO maxGraph@0.1.0 - real migration - may be renamed into BpmnShapeIdentifier after the maxGraph migration export const BpmnStyleIdentifier = { // edge EDGE: 'bpmn.edge', diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index 082008db0d..c0cfa6eac5 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -14,10 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ +import type { Cell, CellStyle, NumericCellStateStyleKeys } from '@maxgraph/core'; +import { cloneUtils, styleUtils } from '@maxgraph/core'; + +import type { BPMNCellStyle } from '../renderer/StyleComputer'; import { ensureOpacityValue, ensureStrokeWidthValue } from '../../helpers/validators'; import type { Fill, Font, ShapeStyleUpdate, Stroke, StyleUpdate } from '../../registry'; -import { ShapeBpmnElementKind } from '../../../model/bpmn/internal'; -import { BpmnStyleIdentifier } from './identifiers'; +import { ShapeUtil } from '../../../model/bpmn/internal'; /** * Store all rendering defaults used by `bpmn-visualization`. @@ -67,8 +70,8 @@ export const StyleDefault = { MESSAGE_FLOW_MARKER_END_FILL_COLOR: 'White', }; -// TODO magraph@0.1.0 maxGraph "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.FONT -// TODO magraph@0.1.0 remove duplicated from maxGraph +// TODO maxgraph@0.1.0 maxGraph "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.FONT +// to remove when https://github.com/maxGraph/maxGraph/issues/205 is fixed export enum FONT { BOLD = 1, ITALIC = 2, @@ -78,53 +81,98 @@ export enum FONT { const convertDefaultValue = (value: string): string | undefined => (value == 'default' ? undefined : value); -// TODO rebase fix update style functions -export const updateStroke = (cellStyle: string, stroke: Stroke): string => { +export const updateStroke = (cellStyle: CellStyle, stroke: Stroke): void => { if (stroke) { - cellStyle = setStyle(cellStyle, mxConstants.STYLE_STROKECOLOR, stroke.color, convertDefaultValue); - cellStyle = setStyle(cellStyle, mxConstants.STYLE_STROKE_OPACITY, stroke.opacity, ensureOpacityValue); - cellStyle = setStyle(cellStyle, mxConstants.STYLE_STROKEWIDTH, stroke.width, ensureStrokeWidthValue); + setStyle(cellStyle, 'strokeColor', stroke.color, convertDefaultValue); + setStyle(cellStyle, 'strokeOpacity', stroke.opacity, ensureOpacityValue); + setStyle(cellStyle, 'strokeWidth', stroke.width, ensureStrokeWidthValue); } - return cellStyle; }; -export const setStyle = (cellStyle: string, key: string, value: T | undefined, converter: (value: T) => T | undefined = (value: T) => value): string => { - return value == undefined ? cellStyle : mxUtils.setStyle(cellStyle, key, converter(value)); +export const setStyle = ( + cellStyle: CellStyle, + key: keyof CellStyle, + value: T | undefined, + converter: (value: T) => T | undefined = (value: T) => value, +): void => { + if (value != undefined) { + const convertedValue = converter(value); + if (convertedValue == null) { + // TODO maxgraph@0.1.0 - this is required for the effective cell style computation with the fix temporary used in bpmn-visualization + // if the value is undefined/or null, the value from the default style is not used! + // remove the property to use the value from the "base styles" which provides the default value + delete cellStyle[key]; + } else { + // TODO maxgraph@0.1.0 - fix type - can we really ignore ts error? + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + cellStyle[key] = convertedValue; + } + } }; -export const setStyleFlag = (cellStyle: string, key: string, flag: number, value: boolean | undefined): string => - value == undefined ? cellStyle : mxUtils.setStyleFlag(cellStyle, key, flag, value); +export const setStyleFlag = (cellStyle: CellStyle, key: NumericCellStateStyleKeys, flag: number, value?: boolean): void => { + // TODO maxGraph@0.1.0 - move this comment to the master branch + // the mxGraph setStyleFlag function toggle the flag if the value if undefined is passed. In bpmn-visualization, we want to keep the value as it is instead in this case (there is no toggle feature) + if (value == undefined) return; + + // FIXME maxGraph@0.1.0 - bug in maxGraph setStyleFlag seems to fail when the fontStyle is undefined + // when the property is undefined, setting the flag set the value to 0. So initialize the value when undefined as a workaround. + // to remove when https://github.com/maxGraph/maxGraph/pull/377 is fixed + if (cellStyle[key] == undefined) { + cellStyle[key] = 0; + } + + styleUtils.setStyleFlag(cellStyle, key, flag, value); +}; -export const updateFont = (cellStyle: string, font: Font): string => { +export const updateFont = (cellStyle: CellStyle, font: Font): void => { if (font) { - cellStyle = setStyle(cellStyle, mxConstants.STYLE_FONTCOLOR, font.color, convertDefaultValue); - cellStyle = setStyle(cellStyle, mxConstants.STYLE_FONTSIZE, font.size); - cellStyle = setStyle(cellStyle, mxConstants.STYLE_FONTFAMILY, font.family); + setStyle(cellStyle, 'fontColor', font.color, convertDefaultValue); + setStyle(cellStyle, 'fontSize', font.size); + setStyle(cellStyle, 'fontFamily', font.family); - cellStyle = setStyleFlag(cellStyle, mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_BOLD, font.isBold); - cellStyle = setStyleFlag(cellStyle, mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_ITALIC, font.isItalic); - cellStyle = setStyleFlag(cellStyle, mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_UNDERLINE, font.isUnderline); - cellStyle = setStyleFlag(cellStyle, mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_STRIKETHROUGH, font.isStrikeThrough); + setStyleFlag(cellStyle, 'fontStyle', FONT.BOLD, font.isBold); + setStyleFlag(cellStyle, 'fontStyle', FONT.ITALIC, font.isItalic); + setStyleFlag(cellStyle, 'fontStyle', FONT.UNDERLINE, font.isUnderline); + setStyleFlag(cellStyle, 'fontStyle', FONT.STRIKETHROUGH, font.isStrikeThrough); - cellStyle = setStyle(cellStyle, mxConstants.STYLE_TEXT_OPACITY, font.opacity, ensureOpacityValue); + setStyle(cellStyle, 'textOpacity', font.opacity, ensureOpacityValue); } - return cellStyle; }; -export const updateFill = (cellStyle: string, fill: Fill): string => { +export const updateFill = (cellStyle: BPMNCellStyle, fill: Fill): void => { if (fill.color) { - cellStyle = setStyle(cellStyle, mxConstants.STYLE_FILLCOLOR, fill.color, convertDefaultValue); + setStyle(cellStyle, 'fillColor', fill.color, convertDefaultValue); - if (cellStyle.includes(ShapeBpmnElementKind.POOL) || cellStyle.includes(ShapeBpmnElementKind.LANE)) { - cellStyle = setStyle(cellStyle, mxConstants.STYLE_SWIMLANE_FILLCOLOR, fill.color, convertDefaultValue); + const kind = cellStyle.bpmn.kind; + if (ShapeUtil.isPoolOrLane(kind)) { + setStyle(cellStyle, 'swimlaneFillColor', fill.color, convertDefaultValue); } } - cellStyle = setStyle(cellStyle, mxConstants.STYLE_FILL_OPACITY, fill.opacity, ensureOpacityValue); - - return cellStyle; + setStyle(cellStyle, 'fillOpacity', fill.opacity, ensureOpacityValue); }; export const isShapeStyleUpdate = (style: StyleUpdate): style is ShapeStyleUpdate => { return style && typeof style === 'object' && 'fill' in style; }; + +export function setCssClasses(cellStyle: BPMNCellStyle, cssClasses: string[]): void { + // TODO maxgraph@0.1.0 do we need to check if the parameter is not undefined - test pass without checking undefined + if (cssClasses.length > 0) { + cellStyle.bpmn.extraCssClasses = cssClasses; + } else { + // TODO maxgraph@0.1.0 - this is needed to make the integration tests pass - do we really do to it for a real usage? + cellStyle.bpmn.extraCssClasses = undefined; + // delete cellStyle.bpmn.extraCssClasses; + } +} + +// FIXME maxGraph 0.1.0 - in model.setStyle, the processing is done only if the style parameter is not equal to the style of the cell +// If the style has been get from the cell, then modified, this is the same instance as in the cell, so the 2 objects are equal, so no processing is done +// in mxGraph, the style was a string, now it is an object. Modifying the returned style didn't modified the string of the style cell, so the 2 objects weren't equal and so processing was done. +// +// See https://github.com/maxGraph/maxGraph/issues/326 (the method modified the style of the cell, so the 2 objects are equal, no processing is done) +// https://github.com/maxGraph/maxGraph/pull/380 provides an dedicated method in Cell +export const getCellStyleClone = (cell: Cell): CellStyle => cloneUtils.clone(cell.getStyle()); diff --git a/test/integration/helpers/model-expect.ts b/test/integration/helpers/model-expect.ts index 816301ae34..e69863eaaa 100644 --- a/test/integration/helpers/model-expect.ts +++ b/test/integration/helpers/model-expect.ts @@ -59,10 +59,10 @@ import { toBeTextAnnotation, toBeUserTask, } from '../matchers'; -import type { AlignValue, ArrowType, Cell, FilterFunction, Geometry, ShapeValue, VAlignValue } from '@maxgraph/core'; +import type { ArrowType, Cell, FilterFunction, Geometry, ShapeValue } from '@maxgraph/core'; import type { ExpectedOverlay } from '../matchers/matcher-utils'; import { getCell } from '../matchers/matcher-utils'; -import type { BPMNCellStyle } from '../../../src/component/mxgraph/renderer/StyleComputer'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace @@ -153,9 +153,9 @@ export interface ExpectedFont { opacity?: Opacity; } -// TODO rebase do we keep HorizontalAlign, we could use AlignValue instead +// TODO maxGraph@0.1.0 do we keep HorizontalAlign, we could use AlignValue instead export type HorizontalAlign = 'center' | 'left' | 'right'; -// TODO rebase do we keep VerticalAlign, we could use VAlignValue instead +// TODO maxGraph@0.1.0 do we keep VerticalAlign, we could use VAlignValue instead export type VerticalAlign = 'bottom' | 'middle' | 'top'; type ExpectedModelElement = { diff --git a/test/integration/matchers/matcher-utils.ts b/test/integration/matchers/matcher-utils.ts index f76556aac9..a477a614a6 100644 --- a/test/integration/matchers/matcher-utils.ts +++ b/test/integration/matchers/matcher-utils.ts @@ -22,16 +22,14 @@ import CustomMatcherResult = jest.CustomMatcherResult; import type { ExpectedEdgeModelElement, ExpectedFont, ExpectedShapeModelElement, HorizontalAlign, VerticalAlign } from '../helpers/model-expect'; import { bpmnVisualization } from '../helpers/model-expect'; import type { Opacity } from '@lib/component/registry'; -import type { MxGraphCustomOverlay, MxGraphCustomOverlayStyle } from '../../../src/component/mxgraph/overlay/custom-overlay'; +import type { MxGraphCustomOverlay, MxGraphCustomOverlayStyle } from '@lib/component/mxgraph/overlay/custom-overlay'; import { getFontStyleValue as computeFontStyleValue } from '@lib/component/mxgraph/renderer/StyleComputer'; import { Font } from '@lib/model/bpmn/internal/Label'; -import type { BPMNCellStyle } from '../../../src/component/mxgraph/renderer/StyleComputer'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; -// TODO magraph@0.1.0 remove this type -export type ExpectedStateStyle = BPMNCellStyle; - -// TODO rebase make it work -export interface BpmnCellStyle extends StyleMap { +// TODO maxgraph@0.1.0 remove this type and use a single type shared with BPMNCellStyle +// No more need for a dedicated BpmnStyle in the integration tests. Use the one from the sources +export interface BpmnCellStyle { opacity: Opacity; verticalAlign?: VerticalAlign; align?: HorizontalAlign; @@ -50,9 +48,10 @@ export interface BpmnCellStyle extends StyleMap { endArrow?: string; endSize?: number; shape?: string; - horizontal?: number; + horizontal?: boolean; // custom bpmn-visualization extraCssClasses?: string[]; + isInitiating?: boolean; markers?: string[]; } @@ -154,13 +153,14 @@ export function buildExpectedCellStyleWithCommonAttributes(expectedModelElt: Exp fontOpacity: expectedModelElt.font?.opacity, // custom bpmn-visualization extraCssClasses: expectedModelElt.extraCssClasses, - // TODO magraph@0.1.0 set basic information when removing the custom processing in buildReceivedStateStyle + // TODO maxgraph@0.1.0 set basic information when removing the custom processing in buildReceivedStateStyle // bpmn: { xxxx }, }; } -// TODO magraph@0.1.0 why building ExpectedStateStyle now maxGraph manage style in object. We should use 'stateStyle' directly (and remove this function) -// TODO magraph@0.1.0 rename into 'receivedStateStyle' (in master branch) +// TODO maxgraph@0.1.0 why building ExpectedStateStyle now maxGraph manage style in object. We should use 'stateStyle' directly (and remove this function) +// investigate "check style properties from the model: keep a single check by merging the code previously used to check the style string and the StyleMap to check the CellStyle (with bpmn addons) +// TODO maxgraph@0.1.0 rename into 'receivedStateStyle' (in master branch) /** * This function really gets style from the state of the cell in the graph view. * The functions that return BpmnCellStyle objects are in fact, returning a computed style by using the style properties from the model augmented with the properties resolved @@ -187,7 +187,7 @@ export function buildReceivedResolvedModelCellStyle(cell: Cell, bv = bpmnVisuali return toBpmnStyle(bv.graph.getCellStyle(cell), cell.edge); } -function toBpmnStyle(rawStyle: StyleMap, isEdge: boolean): BpmnCellStyle { +function toBpmnStyle(rawStyle: BPMNCellStyle, isEdge: boolean): BpmnCellStyle { const style: BpmnCellStyle = { opacity: rawStyle.opacity, verticalAlign: rawStyle.verticalAlign, @@ -202,11 +202,12 @@ function toBpmnStyle(rawStyle: StyleMap, isEdge: boolean): BpmnCellStyle { fontStyle: rawStyle.fontStyle, fontOpacity: rawStyle.textOpacity, // custom bpmn-visualization - extraCssClasses: rawStyle[BpmnStyleIdentifier.EXTRA_CSS_CLASSES]?.split(','), + // extraCssClasses: rawStyle[BpmnStyleIdentifier.EXTRA_CSS_CLASSES]?.split(','), + extraCssClasses: rawStyle.bpmn?.extraCssClasses, // ignore marker order, which is only relevant when rendering the shape (it has its own order algorithm) - markers: rawStyle[BpmnStyleIdentifier.MARKERS]?.split(',').sort(), + markers: rawStyle.bpmn?.markers?.sort(), // for message flow icon (value in rawStyle are string) - 'bpmn.isInitiating': rawStyle[BpmnStyleIdentifier.IS_INITIATING] ? rawStyle[BpmnStyleIdentifier.IS_INITIATING] == 'true' : undefined, + isInitiating: rawStyle.bpmn.isInitiating, }; if (isEdge) { @@ -215,9 +216,6 @@ function toBpmnStyle(rawStyle: StyleMap, isEdge: boolean): BpmnCellStyle { style.endSize = rawStyle.endSize; } else { style.shape = rawStyle.shape; - // TODO rebase horizontal check - // why is it needed in maxgraph , explain why - // stateStyle.horizontal && (expectedStateStyle.horizontal = stateStyle.horizontal); style.horizontal = rawStyle.horizontal; style.swimlaneFillColor = rawStyle.swimlaneFillColor; style.fillOpacity = rawStyle.fillOpacity; @@ -228,8 +226,6 @@ function toBpmnStyle(rawStyle: StyleMap, isEdge: boolean): BpmnCellStyle { function buildBaseReceivedExpectedCell(cell: Cell): ExpectedCell { return { value: cell.value, - // TODO rebase make the style work - style: cell.style as BPMNCellStyle, styleRawFromModelOrJestExpect: cell.style, styleResolvedFromModel: buildReceivedResolvedModelCellStyle(cell), styleViewState: buildReceivedViewStateStyle(cell), @@ -240,7 +236,7 @@ function buildBaseReceivedExpectedCell(cell: Cell): ExpectedCell { }; } -export function buildReceivedCellWithCommonAttributes(cell: mxCell): ExpectedCell { +export function buildReceivedCellWithCommonAttributes(cell: Cell): ExpectedCell { const receivedCell = buildBaseReceivedExpectedCell(cell); // the maxGraph API returns an empty array when there is no overlays diff --git a/test/integration/matchers/toBeCell/index.ts b/test/integration/matchers/toBeCell/index.ts index f8ad95bc51..bd1d1ba52d 100644 --- a/test/integration/matchers/toBeCell/index.ts +++ b/test/integration/matchers/toBeCell/index.ts @@ -23,6 +23,7 @@ import { getDefaultParentId } from '../../helpers/model-expect'; import type { Cell } from '@maxgraph/core'; export function toBeCell(this: MatcherContext, received: string): CustomMatcherResult { + // TODO maxGraph@0.1.0 - simplify expression? const pass = getCell(received) ? true : false; return { message: () => this.utils.matcherHint(`.${pass ? 'not.' : ''}toBeCell`) + '\n\n' + `Expected cell with id '${received}' ${pass ? 'not ' : ''}to be found in the mxGraph model`, diff --git a/test/integration/matchers/toBeEdge/index.ts b/test/integration/matchers/toBeEdge/index.ts index 3854aaa80a..c1fc81b382 100644 --- a/test/integration/matchers/toBeEdge/index.ts +++ b/test/integration/matchers/toBeEdge/index.ts @@ -16,9 +16,9 @@ limitations under the License. import type { ShapeValue } from '@maxgraph/core'; -import type { ExpectedCell, ExpectedStateStyle } from '../matcher-utils'; -import { buildCellMatcher, buildCommonExpectedStateStyle, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; -import { AssociationDirectionKind, FlowKind, MessageVisibleKind, SequenceFlowKind } from '../../../../src/model/bpmn/internal'; +import type { BpmnCellStyle, ExpectedCell } from '../matcher-utils'; +import { buildCellMatcher, buildExpectedCellStyleWithCommonAttributes, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; +import { AssociationDirectionKind, FlowKind, MessageVisibleKind, SequenceFlowKind } from '@lib/model/bpmn/internal'; import type { ExpectedAssociationFlowModelElement, ExpectedEdgeModelElement, ExpectedSequenceFlowModelElement } from '../../helpers/model-expect'; import { getDefaultParentId } from '../../helpers/model-expect'; import { BpmnStyleIdentifier } from '@lib/component/mxgraph/style'; @@ -42,13 +42,13 @@ function buildExpectedMsgFlowIconCellStyle(expectedModel: ExpectedEdgeModelEleme style.align = 'center'; style.verticalAlign = 'middle'; style.shape = BpmnStyleIdentifier.MESSAGE_FLOW_ICON; - style[BpmnStyleIdentifier.IS_INITIATING] = expectedModel.messageVisibleKind == MessageVisibleKind.INITIATING; + style.isInitiating = expectedModel.messageVisibleKind == MessageVisibleKind.INITIATING; return style; } function buildExpectedEdgeStylePropertyRegexp(expectedModel: ExpectedEdgeModelElement | ExpectedSequenceFlowModelElement | ExpectedAssociationFlowModelElement): BPMNCellStyle { const style: BPMNCellStyle = { bpmn: {} }; - // TODO magraph@0.1.0 share with edge + // TODO maxgraph@0.1.0 share with shape or remove style.baseStyleNames = [expectedModel.kind]; style.bpmn.kind = expectedModel.kind; if ('sequenceFlowKind' in expectedModel) { @@ -57,27 +57,25 @@ function buildExpectedEdgeStylePropertyRegexp(expectedModel: ExpectedEdgeModelEl if ('associationDirectionKind' in expectedModel) { style.baseStyleNames.push((expectedModel as ExpectedAssociationFlowModelElement).associationDirectionKind); } + if ('extraCssClasses' in expectedModel) { + style.bpmn.extraCssClasses = expectedModel.extraCssClasses; + } return style; } function buildExpectedCell(id: string, expectedModel: ExpectedEdgeModelElement | ExpectedSequenceFlowModelElement): ExpectedCell { - // TODO magraph@0.1.0 refactor, duplication with buildExpectedCell in shape matchers + // TODO maxgraph@0.1.0 refactor, duplication with buildExpectedCell in shape matchers const parentId = expectedModel.parentId; const expectedCell: ExpectedCell = { id, value: expectedModel.label ?? null, // maxGraph now set to 'null', mxGraph set to 'undefined' - style: expect.objectContaining(buildExpectedStyle(expectedModel)), - // TODO rebase make style work - styleRawFromModelOrJestExpect: expect.stringMatching(buildExpectedEdgeStylePropertyRegexp(expectedModel)), + styleRawFromModelOrJestExpect: expect.objectContaining(buildExpectedEdgeStylePropertyRegexp(expectedModel)), styleResolvedFromModel: buildExpectedEdgeCellStyle(expectedModel), styleViewState: buildExpectedEdgeCellStyle(expectedModel), edge: true, vertex: false, - parent: { id: parentId ? parentId : getDefaultParentId() }, // TODO magraph@0.1.0 use ?? instead (in master branch) - state: { - style: buildExpectedStateStyle(expectedModel), - }, + parent: { id: parentId ? parentId : getDefaultParentId() }, // TODO maxgraph@0.1.0 use ?? instead (in master branch) overlays: expectedModel.overlays, }; @@ -87,16 +85,13 @@ function buildExpectedCell(id: string, expectedModel: ExpectedEdgeModelElement | { id: `messageFlowIcon_of_${id}`, value: null, // maxGraph now set to 'null', mxGraph set to 'undefined' - // TODO rebase make the style check work - style: { - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + styleRawFromModelOrJestExpect: expect.objectContaining({ + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types shape: BpmnStyleIdentifier.MESSAGE_FLOW_ICON, - // TODO magraph@0.1.0 duplicated logic to compute the 'isNonInitiating' property. Update the expectedModel to store a boolean instead of a string - bpmn: { isNonInitiating: expectedModel.messageVisibleKind === MessageVisibleKind.NON_INITIATING }, - }, - styleRawFromModelOrJestExpect: expect.stringMatching( - `shape=${BpmnStyleIdentifier.MESSAGE_FLOW_ICON};${BpmnStyleIdentifier.IS_INITIATING}=${expectedModel.messageVisibleKind == MessageVisibleKind.INITIATING}`, - ), + // TODO maxgraph@0.1.0 duplicated logic to compute the 'isInitiating' property. Update the expectedModel to store a boolean instead of a string + // duplication exists in the master branch (it is fixed in bpmn-visualization 0.43.0) + bpmn: { isInitiating: expectedModel.messageVisibleKind == MessageVisibleKind.INITIATING }, + }), styleResolvedFromModel: buildExpectedMsgFlowIconCellStyle(expectedModel), styleViewState: buildExpectedMsgFlowIconCellStyle(expectedModel), edge: false, diff --git a/test/integration/matchers/toBeShape/index.ts b/test/integration/matchers/toBeShape/index.ts index 914c262f48..4d9c129a55 100644 --- a/test/integration/matchers/toBeShape/index.ts +++ b/test/integration/matchers/toBeShape/index.ts @@ -14,12 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { ShapeValue } from '@maxgraph/core'; - -import type { ExpectedCell, ExpectedStateStyle } from '../matcher-utils'; -import { buildCellMatcher, buildCommonExpectedStateStyle, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; - -import type { BpmnCellStyle, ExpectedCell } from '../matcher-utils'; +import type { ExpectedCell, BpmnCellStyle } from '../matcher-utils'; import { buildCellMatcher, buildExpectedCellStyleWithCommonAttributes, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; import type { ExpectedBoundaryEventModelElement, @@ -66,19 +61,13 @@ function expectedStrokeWidth(kind: ShapeBpmnElementKind): number { export function buildExpectedShapeCellStyle(expectedModel: ExpectedShapeModelElement): BpmnCellStyle { const style = buildExpectedCellStyleWithCommonAttributes(expectedModel); + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types + // expectedStateStyle.shape = ((!expectedModel.styleShape ? expectedModel.kind : expectedModel.styleShape)); style.shape = expectedModel.styleShape ?? expectedModel.kind; style.verticalAlign = expectedModel.verticalAlign ?? 'middle'; style.align = expectedModel.align ?? 'center'; style.strokeWidth = style.strokeWidth ?? expectedStrokeWidth(expectedModel.kind); - // TODO rebase - adapt - const expectedStateStyle = buildCommonExpectedStateStyle(expectedModel); - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types - expectedStateStyle.shape = ((!expectedModel.styleShape ? expectedModel.kind : expectedModel.styleShape)); - expectedStateStyle.verticalAlign = expectedModel.verticalAlign ? expectedModel.verticalAlign : 'middle'; - expectedStateStyle.align = expectedModel.align ? expectedModel.align : 'center'; - expectedStateStyle.strokeWidth = expectedStrokeWidth(expectedModel.kind); - style.fillColor = expectedModel.fill?.color ?? ([ShapeBpmnElementKind.LANE, ShapeBpmnElementKind.POOL, ShapeBpmnElementKind.TEXT_ANNOTATION, ShapeBpmnElementKind.GROUP].includes(expectedModel.kind) @@ -87,20 +76,15 @@ export function buildExpectedShapeCellStyle(expectedModel: ExpectedShapeModelEle style.swimlaneFillColor = [ShapeBpmnElementKind.POOL, ShapeBpmnElementKind.LANE].includes(expectedModel.kind) && style.fillColor !== 'none' ? style.fillColor : undefined; style.fillOpacity = expectedModel.fill?.opacity; - 'isSwimLaneLabelHorizontal' in expectedModel && (style.horizontal = Number(expectedModel.isSwimLaneLabelHorizontal)); + 'isSwimLaneLabelHorizontal' in expectedModel && (style.horizontal = expectedModel.isSwimLaneLabelHorizontal); // ignore marker order, which is only relevant when rendering the shape (it has its own order algorithm) 'markers' in expectedModel && (style.markers = expectedModel.markers.sort()); - // TODO rebase - adapt - // TODO magraph@0.1.0 explain why this is needed. Can we move this addition to the master branch - if ('isHorizontal' in expectedModel) { - expectedStateStyle.horizontal = expectedModel.isHorizontal; - } return style; } -// TODO magraph@0.1.0 Here we don't check all properties. Why? +// TODO maxgraph@0.1.0 Here we don't check all properties. This duplicates the other style check functions function buildExpectedShapeStylePropertyRegexp( expectedModel: | ExpectedShapeModelElement @@ -112,7 +96,7 @@ function buildExpectedShapeStylePropertyRegexp( | ExpectedCallActivityModelElement, ): BPMNCellStyle { const style: BPMNCellStyle = { bpmn: {} }; - // TODO magraph@0.1.0 share with edge + // TODO maxgraph@0.1.0 share with edge style.baseStyleNames = [expectedModel.kind]; style.bpmn.kind = expectedModel.kind; @@ -128,12 +112,6 @@ function buildExpectedShapeStylePropertyRegexp( if (expectedModel.isInstantiating !== undefined) { style.bpmn.isInstantiating = expectedModel.isInstantiating; } - // if (expectedModel.markers?.length > 0) { - // // There is no guaranteed order, so testing the list of markers with a string is not practical. Markers are therefore checked with BpmnStyle.markers. - // // Here, we check only that the markers are placed in the style. - // expectedStyle = expectedStyle + `.*bpmn.markers=*`; - // } - // TODO rebase ignore markers order if (expectedModel.markers) { style.bpmn.markers = expectedModel.markers; } @@ -143,19 +121,20 @@ function buildExpectedShapeStylePropertyRegexp( if ('gatewayKind' in expectedModel) { style.bpmn.gatewayKind = expectedModel.gatewayKind; } + if ('extraCssClasses' in expectedModel) { + style.bpmn.extraCssClasses = expectedModel.extraCssClasses; + } return style; } function buildExpectedCell(id: string, expectedModel: ExpectedShapeModelElement): ExpectedCell { - // TODO magraph@0.1.0 refactor, duplication with buildExpectedCell in edge matchers + // TODO maxgraph@0.1.0 refactor, duplication with buildExpectedCell in edge matchers const parentId = expectedModel.parentId; return { id, value: expectedModel.label ?? null, // maxGraph now set to 'null', mxGraph set to 'undefined' - style: expect.objectContaining(buildExpectedStyle(expectedModel)), - // TODO rebase make it work - styleRawFromModelOrJestExpect: expect.stringMatching(buildExpectedShapeStylePropertyRegexp(expectedModel)), + styleRawFromModelOrJestExpect: expect.objectContaining(buildExpectedShapeStylePropertyRegexp(expectedModel)), styleResolvedFromModel: buildExpectedShapeCellStyle(expectedModel), styleViewState: buildExpectedShapeCellStyle(expectedModel), edge: false, @@ -172,18 +151,12 @@ function buildShapeMatcher(matcherName: string, matcherContext: MatcherContext, function buildContainerMatcher(matcherName: string, matcherContext: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { return buildShapeMatcher(matcherName, matcherContext, received, { ...expected, - styleShape: mxConstants.SHAPE_SWIMLANE, + // TODO maxgraph@0.1.0 maxGraph "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE + styleShape: 'swimlane', isSwimLaneLabelHorizontal: expected.isSwimLaneLabelHorizontal ?? false, }); } -function buildContainerMatcher(matcherName: string, matcherContext: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { - 'isHorizontal' in expected && (expected.isHorizontal = expected.isHorizontal); - - // TODO magraph@0.1.0 maxGraph "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE - return buildShapeMatcher(matcherName, matcherContext, received, { ...expected, styleShape: 'swimlane' }); -} - export function toBePool(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { return buildContainerMatcher('toBePool', this, received, { ...expected, kind: ShapeBpmnElementKind.POOL }); } @@ -192,69 +165,54 @@ export function toBeLane(this: MatcherContext, received: string, expected: Expec return buildContainerMatcher('toBeLane', this, received, { ...expected, kind: ShapeBpmnElementKind.LANE }); } -export function toBeCallActivity(this: MatcherContext, received: string, expected: ExpectedCallActivityModelElement): CustomMatcherResult { - // TODO magraph@0.1.0 introduce common code for activity kinds +function buildActivityMatcher(matcherName: string, matcherContext: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { + // TODO maxgraph@0.1.0 - review the markers management (sometimes it is undefined by default, sometimes it is an empty array) expected.markers ??= []; - return buildShapeMatcher('toBeCallActivity', this, received, { ...expected, kind: ShapeBpmnElementKind.CALL_ACTIVITY }); + return buildShapeMatcher(matcherName, matcherContext, received, expected); +} + +export function toBeCallActivity(this: MatcherContext, received: string, expected: ExpectedCallActivityModelElement): CustomMatcherResult { + return buildActivityMatcher('toBeCallActivity', this, received, { ...expected, kind: ShapeBpmnElementKind.CALL_ACTIVITY }); } export function toBeSubProcess(this: MatcherContext, received: string, expected: ExpectedSubProcessModelElement): CustomMatcherResult { - // TODO rebase review markers management - // TODO magraph@0.1.0 introduce common code for activity kinds - // expected.markers ??= []; if (expected.subProcessKind == ShapeBpmnSubProcessKind.AD_HOC) { expected.markers ??= []; expected.markers.push(ShapeBpmnMarkerKind.ADHOC); } - return buildShapeMatcher('toBeSubProcess', this, received, { ...expected, kind: ShapeBpmnElementKind.SUB_PROCESS }); + return buildActivityMatcher('toBeSubProcess', this, received, { ...expected, kind: ShapeBpmnElementKind.SUB_PROCESS }); } export function toBeTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { - // TODO magraph@0.1.0 introduce common code for activity kinds - expected.markers ??= []; - return buildShapeMatcher('toBeTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK }); + return buildActivityMatcher('toBeTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK }); } export function toBeServiceTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { - // TODO magraph@0.1.0 introduce common code for activity kinds - expected.markers ??= []; - return buildShapeMatcher('toBeServiceTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_SERVICE }); + return buildActivityMatcher('toBeServiceTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_SERVICE }); } export function toBeUserTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { - // TODO magraph@0.1.0 introduce common code for activity kinds - expected.markers ??= []; - return buildShapeMatcher('toBeUserTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_USER }); + return buildActivityMatcher('toBeUserTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_USER }); } export function toBeReceiveTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { - // TODO magraph@0.1.0 introduce common code for activity kinds - expected.markers ??= []; - return buildShapeMatcher('toBeReceiveTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_RECEIVE }); + return buildActivityMatcher('toBeReceiveTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_RECEIVE }); } export function toBeSendTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { - // TODO magraph@0.1.0 introduce common code for activity kinds - expected.markers ??= []; - return buildShapeMatcher('toBeSendTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_SEND }); + return buildActivityMatcher('toBeSendTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_SEND }); } export function toBeManualTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { - // TODO magraph@0.1.0 introduce common code for activity kinds - expected.markers ??= []; - return buildShapeMatcher('toBeManualTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_MANUAL }); + return buildActivityMatcher('toBeManualTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_MANUAL }); } export function toBeScriptTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { - // TODO magraph@0.1.0 introduce common code for activity kinds - expected.markers ??= []; - return buildShapeMatcher('toBeScriptTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_SCRIPT }); + return buildActivityMatcher('toBeScriptTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_SCRIPT }); } export function toBeBusinessRuleTask(this: MatcherContext, received: string, expected: ExpectedShapeModelElement): CustomMatcherResult { - // TODO magraph@0.1.0 introduce common code for activity kinds - expected.markers ??= []; - return buildShapeMatcher('toBeBusinessRuleTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_BUSINESS_RULE }); + return buildActivityMatcher('toBeBusinessRuleTask', this, received, { ...expected, kind: ShapeBpmnElementKind.TASK_BUSINESS_RULE }); } function buildEventMatcher(matcherName: string, matcherContext: MatcherContext, received: string, expected: ExpectedStartEventModelElement): CustomMatcherResult { diff --git a/test/integration/mxGraph.model.bpmn.elements.test.ts b/test/integration/mxGraph.model.bpmn.elements.test.ts index b662adba7d..7f09e26068 100644 --- a/test/integration/mxGraph.model.bpmn.elements.test.ts +++ b/test/integration/mxGraph.model.bpmn.elements.test.ts @@ -14,9 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { ArrowType } from '@maxgraph/core'; -import { Point, Geometry } from '@maxgraph/core'; - import { MarkerIdentifier, MessageVisibleKind, @@ -33,11 +30,13 @@ import { bpmnVisualization, expectEdgesInModel, expectPoolsInModel, - expectTotalEdgesInModel, expectShapesInModel, + expectTotalEdgesInModel, expectTotalShapesInModel, getDefaultParentId, } from './helpers/model-expect'; +import type { ArrowType } from '@maxgraph/core'; +import { Point, Geometry } from '@maxgraph/core'; describe('mxGraph model - BPMN elements', () => { describe('BPMN elements should be available in the mxGraph model', () => { @@ -56,11 +55,6 @@ describe('mxGraph model - BPMN elements', () => { describe('BPMN containers', () => { const baseShapeModelElement: ExpectedShapeModelElement = { isSwimLaneLabelHorizontal: false }; - // TODO rebase update test for maxGraph - // TODO magraph@0.1.0 change isHorizontal value for maxGraph, but the logic is probably wrong in 'master' (convert integer into boolean) - // const minimalPoolModelElement: ExpectedShapeModelElement = { - // parentId: getDefaultParentId(), - // }; it('pool', () => { expect('participant_1_id').toBePool({ ...baseShapeModelElement, label: 'Pool 1' }); expect('participant_2_id').toBePool(baseShapeModelElement); @@ -1051,7 +1045,6 @@ describe('mxGraph model - BPMN elements', () => { it('Collapsed', () => { expect('collapsed_call_activity_id').toBeCallActivity({ label: 'Collapsed Call Activity', - markers: [ShapeBpmnMarkerKind.EXPAND], parentId: 'participant_1_id', markers: [ShapeBpmnMarkerKind.EXPAND], verticalAlign: 'top', @@ -1477,7 +1470,7 @@ describe('mxGraph model - BPMN elements', () => { it('sequence flows', () => { expect('default_sequence_flow_id').toBeSequenceFlow({ sequenceFlowKind: SequenceFlowKind.DEFAULT, - // TODO magraph@0.1.0 remove forcing type when maxGraph fixes its types + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types startArrow: (MarkerIdentifier.ARROW_DASH), parentId: 'participant_1_id', font: expectedBoldFont, @@ -1583,8 +1576,8 @@ describe('mxGraph model - BPMN elements', () => { ), }); - const sequenceFlowMxGeometry = new Geometry(0, 0, 0, 0); - sequenceFlowMxGeometry.points = [ + const sequenceFlowGeometry = new Geometry(0, 0, 0, 0); + sequenceFlowGeometry.points = [ new Point(190, 100), // absolute coordinates: parent x="160" y="80", cell x="350" y="180" new Point(350, 100), // absolute coordinates: parent x="160" y="80", cell x="510" y="180" ]; @@ -1593,8 +1586,8 @@ describe('mxGraph model - BPMN elements', () => { geometry: sequenceFlowGeometry, }); - const messageFlowMxGeometry = new Geometry(0, 0, 0, 0); - messageFlowMxGeometry.points = [ + const messageFlowGeometry = new Geometry(0, 0, 0, 0); + messageFlowGeometry.points = [ new Point(334, 260), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="260" new Point(334, 342), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="342" ]; @@ -1641,23 +1634,23 @@ describe('mxGraph model - BPMN elements', () => { ), }); - const sequenceFlowMxGeometry = new Geometry(0, 0, 0, 0); - sequenceFlowMxGeometry.points = [ + const sequenceFlowGeometry = new Geometry(0, 0, 0, 0); + sequenceFlowGeometry.points = [ new Point(160, 100), // absolute coordinates: parent x="190" y="80", cell x="350" y="180" new Point(320, 100), // absolute coordinates: parent x="190" y="80", cell x="510" y="180" ]; expect('SequenceFlow_id').toBeCellWithParentAndGeometry({ parentId: 'Lane_1_1', - geometry: sequenceFlowMxGeometry, + geometry: sequenceFlowGeometry, }); - const messageFlowMxGeometry = new Geometry(0, 0, 0, 0); - messageFlowMxGeometry.points = [ + const messageFlowGeometry = new Geometry(0, 0, 0, 0); + messageFlowGeometry.points = [ new Point(334, 480), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="480" new Point(334, 632), // absolute coordinates: parent graph.getDefaultParent(), cell x="334" y="632" ]; expect('MessageFlow_1').toBeCellWithParentAndGeometry({ - geometry: messageFlowMxGeometry, + geometry: messageFlowGeometry, }); }); @@ -1666,8 +1659,6 @@ describe('mxGraph model - BPMN elements', () => { // pool const baseShapeModelElement: ExpectedShapeModelElement = { isSwimLaneLabelHorizontal: true }; - // TODO rebase update test for maxGraph - // const minimalPoolModelElement: ExpectedShapeModelElement = { isHorizontal: true, parentId: getDefaultParentId() }; expect('Participant_Vertical_With_Lanes').toBePool({ ...baseShapeModelElement, label: 'Vertical Pool With Lanes' }); // lane @@ -1711,8 +1702,8 @@ describe('mxGraph model - BPMN elements', () => { }); it('Parse a diagram with numbers not parsable as number', () => { - // TODO magraph@0.1.0 change in maxGraph, throw 'Error: Invalid x supplied'. bpmn-visualization should handle it - // capture the error and rethrow it with a convenient + // TODO maxgraph@0.1.0 change in maxGraph, throw 'Error: Invalid x supplied'. bpmn-visualization should handle it + // capture the error and rethrow it with a convenient // OR validate the values during parsing expect(() => bpmnVisualization.load(readFileSync('../fixtures/bpmn/xml-parsing/special/simple-start-task-end_numbers_not_parsable_as_number.bpmn'))).toThrow( diff --git a/test/integration/mxGraph.model.css.api.test.ts b/test/integration/mxGraph.model.css.api.test.ts index a040d5c274..154a47433f 100644 --- a/test/integration/mxGraph.model.css.api.test.ts +++ b/test/integration/mxGraph.model.css.api.test.ts @@ -25,6 +25,11 @@ describe('mxGraph model - CSS API', () => { }); test('Add CSS classes on Shape', () => { + expect('userTask_2_2').toBeUserTask({ + // not under test + parentId: 'lane_02', + label: 'User Task 2.2', + }); bpmnVisualization.bpmnElementsRegistry.addCssClasses('userTask_2_2', ['class#1', 'class#2']); expect('userTask_2_2').toBeUserTask({ extraCssClasses: ['class#1', 'class#2'], @@ -35,6 +40,11 @@ describe('mxGraph model - CSS API', () => { }); test('Add CSS classes on Edge', () => { + expect('sequenceFlow_lane_3_elt_3').toBeSequenceFlow({ + // not under test + parentId: 'lane_03', + verticalAlign: 'bottom', + }); bpmnVisualization.bpmnElementsRegistry.addCssClasses('sequenceFlow_lane_3_elt_3', ['class-1', 'class-2', 'class-3']); expect('sequenceFlow_lane_3_elt_3').toBeSequenceFlow({ extraCssClasses: ['class-1', 'class-2', 'class-3'], diff --git a/test/integration/mxGraph.model.parsing.entities.test.ts b/test/integration/mxGraph.model.parsing.entities.test.ts index 6ad23fbea0..f0cdfbb847 100644 --- a/test/integration/mxGraph.model.parsing.entities.test.ts +++ b/test/integration/mxGraph.model.parsing.entities.test.ts @@ -33,7 +33,7 @@ describe('From BPMN diagram with entities in attributes', () => { bpmnVisualization.load(readFileSync('../fixtures/bpmn/xml-parsing/special/start-tasks-end_entities_in_attributes.bpmn')); const expectElementLabel = (id: string): jest.JestMatchers => { - const model = bpmnVisualization.graph.getModel(); + const model = bpmnVisualization.graph.getDataModel(); const cell = model.getCell(id); expect(cell).toBeDefined(); // eslint-disable-next-line jest/valid-expect -- util function diff --git a/test/integration/mxGraph.model.style.api.test.ts b/test/integration/mxGraph.model.style.api.test.ts index debf3693b9..34a4d5fb24 100644 --- a/test/integration/mxGraph.model.style.api.test.ts +++ b/test/integration/mxGraph.model.style.api.test.ts @@ -23,15 +23,15 @@ import { buildExpectedShapeCellStyle } from './matchers/toBeShape'; import { readFileSync } from '@test/shared/file-helper'; import { MessageVisibleKind, ShapeBpmnElementKind, ShapeBpmnEventDefinitionKind } from '@lib/model/bpmn/internal'; import type { EdgeStyleUpdate, Fill, Font, Stroke, StyleUpdate } from '@lib/component/registry'; -import type { mxCell } from 'mxgraph'; +import type { Cell } from '@maxgraph/core'; // Create a dedicated instance with a DOM container as it is required by the CSS API. const bv = initializeBpmnVisualizationWithContainerId('bpmn-container-style-css-cross-tests'); const htmlElementLookup = new HtmlElementLookup(bv); -const getCell = (bpmnElementId: string): mxCell => { +const getCell = (bpmnElementId: string): Cell => { const graph = bv.graph; - const cell = graph.model.getCell(bpmnElementId); + const cell = graph.getDataModel().getCell(bpmnElementId); if (!cell) { throw new Error(`Unable to find cell in the model with id ${bpmnElementId}`); } @@ -131,13 +131,21 @@ describe('mxGraph model - update style', () => { }); it('Font style already set and no font style as api parameter', () => { - const font = { + const font: Font = { isBold: true, isItalic: true, isUnderline: true, isStrikeThrough: true, }; bpmnVisualization.bpmnElementsRegistry.updateStyle('userTask_2_2', { font }); + // TODO maxGraph@0.1.0 - add such additional check in the master branch and do it when several style update actions are done + expect('userTask_2_2').toBeUserTask({ + font, + // not under test + parentId: 'lane_02', + label: 'User Task 2.2', + }); + // this doesn't change the style as the font property is empty bpmnVisualization.bpmnElementsRegistry.updateStyle('userTask_2_2', { font: {} }); @@ -158,6 +166,17 @@ describe('mxGraph model - update style', () => { isStrikeThrough: true, }, }); + expect('userTask_2_2').toBeUserTask({ + font: { + isBold: true, + isItalic: true, + isUnderline: true, + isStrikeThrough: true, + }, + // not under test + parentId: 'lane_02', + label: 'User Task 2.2', + }); bpmnVisualization.bpmnElementsRegistry.updateStyle('userTask_2_2', { font: { isItalic: false, isUnderline: false } }); expect('userTask_2_2').toBeUserTask({ diff --git a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts index 514784c6c5..f19add0983 100644 --- a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts +++ b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts @@ -17,7 +17,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { BPMNCellStyle } from '../../../../../src/component/mxgraph/renderer/StyleComputer'; +import type { AlignValue, ShapeValue } from '@maxgraph/core'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; import StyleComputer from '@lib/component/mxgraph/renderer/StyleComputer'; import Shape from '@lib/model/bpmn/internal/shape/Shape'; import ShapeBpmnElement, { @@ -127,7 +128,7 @@ function newAssociationFlow(kind: AssociationDirectionKind): AssociationFlow { return new AssociationFlow('id', 'name', undefined, undefined, kind); } -// TODO magraph@0.1.0 order properties alphabetically in expected style +// TODO maxgraph@0.1.0 order properties alphabetically in expected style describe('Style Computer', () => { // use a shared instance to check that there is no state stored in the implementation @@ -189,7 +190,6 @@ describe('Style Computer', () => { expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['scriptTask'], fontFamily: 'Roboto', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it bpmn: { kind: ShapeBpmnElementKind.TASK_SCRIPT }, }); }); @@ -201,11 +201,9 @@ describe('Style Computer', () => { align: 'center', verticalAlign: 'top', labelWidth: 81, - // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator - // expect(computeStyle(shape)).toBe('callActivity;verticalAlign=top;align=center;labelWidth=81;labelPosition=ignore;verticalLabelPosition=middle'); - labelPosition: 'left', - verticalLabelPosition: 'top', - // end of fixme + // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) + labelPosition: 'ignore', + verticalLabelPosition: 'middle', bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY }, }); }); @@ -268,7 +266,6 @@ describe('Style Computer', () => { fontFamily: 'Helvetica', align: 'center', verticalAlign: 'top', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it bpmn: { kind: FlowKind.SEQUENCE_FLOW }, }); }); @@ -300,15 +297,14 @@ describe('Style Computer', () => { }); it.each([ - [MessageVisibleKind.NON_INITIATING, 'false'], - [MessageVisibleKind.INITIATING, 'true'], - ])('compute style - message flow icon: %s', (messageVisibleKind: MessageVisibleKind, expected: string) => { + [MessageVisibleKind.NON_INITIATING, false], + [MessageVisibleKind.INITIATING, true], + ])('compute style - message flow icon: %s', (messageVisibleKind: MessageVisibleKind, expected: boolean) => { const edge = new Edge('id', newMessageFlow(), undefined, undefined, messageVisibleKind); - // TODO magraph@0.1.0 cast to (waiting for "maxGraph fixes its types") - expect(styleComputer.computeMessageFlowIconStyle(edge)).toStrictEqual({ - shape: 'bpmn.messageFlowIcon', - // TODO rebase rename isNonInitiating --> isNonInitiating - bpmn: { isNonInitiating: expected }, + expect(styleComputer.computeMessageFlowIconStyle(edge)).toStrictEqual({ + bpmn: { isInitiating: expected }, + // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types + shape: 'bpmn.messageFlowIcon', }); }); @@ -318,7 +314,6 @@ describe('Style Computer', () => { expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['intermediateCatchEvent'], fontFamily: 'Ubuntu', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it bpmn: { kind: ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, eventDefinitionKind: ShapeBpmnEventDefinitionKind.CONDITIONAL }, }); }); @@ -339,7 +334,6 @@ describe('Style Computer', () => { expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['boundaryEvent'], fontFamily: 'Arial', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it bpmn: { kind: ShapeBpmnElementKind.EVENT_BOUNDARY, eventDefinitionKind: ShapeBpmnEventDefinitionKind.MESSAGE, isInterrupting: true }, }); }); @@ -369,7 +363,6 @@ describe('Style Computer', () => { expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['startEvent'], fontFamily: 'Arial', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.MESSAGE, isInterrupting: true }, }); }); @@ -400,48 +393,34 @@ describe('Style Computer', () => { ])(`%s`, (expandKind: string, markers: ShapeBpmnMarkerKind[]) => { describe.each(Object.values(ShapeBpmnSubProcessKind))(`%s`, (subProcessKind: ShapeBpmnSubProcessKind) => { markers = getExpectedMarkers(markers, subProcessKind); - const additionalMarkerStyle = markers.length > 0 ? `;bpmn.markers=${markers.join(',')}` : ''; it(`${subProcessKind} sub-process without label bounds`, () => { const shape = newShape(newShapeBpmnSubProcess(subProcessKind, markers), newLabel({ name: 'Arial' })); - const additionalTerminalStyle = !markers.includes(ShapeBpmnMarkerKind.EXPAND) ? ';verticalAlign=top' : ''; - expect(computeStyle(shape)).toBe(`subProcess;bpmn.subProcessKind=${subProcessKind}${additionalMarkerStyle};fontFamily=Arial${additionalTerminalStyle}`); + const expectedStyle = { + baseStyleNames: ['subProcess'], + bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind, markers }, + fontFamily: 'Arial', + }; + !markers.includes(ShapeBpmnMarkerKind.EXPAND) && (expectedStyle.verticalAlign = 'top'); + + expect(computeStyle(shape)).toStrictEqual(expectedStyle); }); it(`${subProcessKind} sub-process with label bounds`, () => { const shape = newShape(newShapeBpmnSubProcess(subProcessKind, markers), newLabel({ name: 'sans-serif' }, new Bounds(20, 20, 300, 200))); - expect(computeStyle(shape)).toBe( - `subProcess;bpmn.subProcessKind=${subProcessKind}${additionalMarkerStyle};fontFamily=sans-serif;verticalAlign=top;align=center;labelWidth=301;labelPosition=ignore;verticalLabelPosition=middle`, - ); + expect(computeStyle(shape)).toStrictEqual({ + align: 'center', + baseStyleNames: ['subProcess'], + bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind, markers }, + fontFamily: 'sans-serif', + labelWidth: 301, + verticalAlign: 'top', + // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) + labelPosition: 'ignore', + verticalLabelPosition: 'middle', + }); }); }); - // TODO rebase adapt test - // const expectedStyle = { - // baseStyleNames: ['subProcess'], - // bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.EMBEDDED, markers }, - // fontFamily: 'Arial', - // fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it - // }; - // !markers.includes(ShapeBpmnMarkerKind.EXPAND) && (expectedStyle.verticalAlign = 'top'); - // expect(computeStyle(shape)).toStrictEqual(expectedStyle); - // }); - // - // it(`${expandKind} embedded sub-process with label bounds`, () => { - // const shape = newShape(newShapeBpmnSubProcess(ShapeBpmnSubProcessKind.EMBEDDED, markers), newLabel({ name: 'sans-serif' }, new Bounds(20, 20, 300, 200))); - // expect(computeStyle(shape)).toStrictEqual({ - // align: 'center', - // baseStyleNames: ['subProcess'], - // bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.EMBEDDED, markers }, - // fontFamily: 'sans-serif', - // fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it - // labelWidth: 301, - // verticalAlign: 'top', - // // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator - // // `subProcess;bpmn.subProcessKind=embedded${additionalMarkerStyle};fontFamily=sans-serif;verticalAlign=top;align=center;labelWidth=301;labelPosition=top;verticalLabelPosition=left`, - // labelPosition: 'left', - // verticalLabelPosition: 'top', - // // end of fixme - // }); }); }); @@ -457,11 +436,10 @@ describe('Style Computer', () => { baseStyleNames: ['callActivity'], bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, - globalTaskKind: undefined, // TODO magraph@0.1.0 decide if we set globalTaskKind to undefined or if we omit the property + globalTaskKind: undefined, // TODO maxgraph@0.1.0 decide if we set globalTaskKind to undefined or if we omit the property markers, }, fontFamily: 'Arial', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it }; !markers.includes(ShapeBpmnMarkerKind.EXPAND) && (expectedStyle.verticalAlign = 'top'); expect(computeStyle(shape)).toStrictEqual(expectedStyle); @@ -474,18 +452,15 @@ describe('Style Computer', () => { baseStyleNames: ['callActivity'], bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, - globalTaskKind: undefined, // TODO magraph@0.1.0 decide if we set globalTaskKind to undefined or if we omit the property + globalTaskKind: undefined, // TODO maxgraph@0.1.0 decide if we set globalTaskKind to undefined or if we omit the property markers, }, fontFamily: 'sans-serif', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it labelWidth: 301, verticalAlign: 'top', - // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator - // `callActivity${additionalMarkerStyle};fontFamily=sans-serif;verticalAlign=top;align=center;labelWidth=301;labelPosition=ignore;verticalLabelPosition=middle`, - labelPosition: 'left', - verticalLabelPosition: 'top', - // end of fixme + // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) + labelPosition: 'ignore', + verticalLabelPosition: 'middle', }); }); }); @@ -505,7 +480,6 @@ describe('Style Computer', () => { baseStyleNames: ['callActivity'], bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, globalTaskKind: globalTaskKind, markers: [] }, fontFamily: 'Arial', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it }; expect(computeStyle(shape)).toStrictEqual(expectedStyle); }); @@ -521,14 +495,11 @@ describe('Style Computer', () => { markers: [], }, fontFamily: 'sans-serif', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it labelWidth: 301, verticalAlign: 'top', - // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator - // `callActivity;bpmn.globalTaskKind=${globalTaskKind};fontFamily=sans-serif;verticalAlign=top;align=center;labelWidth=301;labelPosition=ignore;verticalLabelPosition=middle`, - labelPosition: 'left', - verticalLabelPosition: 'top', - // end of fixme + // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) + labelPosition: 'ignore', + verticalLabelPosition: 'middle', }); }); }); @@ -545,7 +516,6 @@ describe('Style Computer', () => { baseStyleNames: ['receiveTask'], bpmn: { kind: ShapeBpmnElementKind.TASK_RECEIVE, isInstantiating: instantiate, markers: [] }, fontFamily: 'Arial', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it }); }); }); @@ -566,14 +536,11 @@ describe('Style Computer', () => { kind: ShapeBpmnElementKind.TEXT_ANNOTATION, }, fontFamily: 'Segoe UI', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it labelWidth: 101, verticalAlign: 'top', - // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator - // 'textAnnotation;fontFamily=Segoe UI;verticalAlign=top;labelWidth=101;labelPosition=ignore;verticalLabelPosition=middle' - labelPosition: 'left', - verticalLabelPosition: 'top', - // end of fixme + // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) + labelPosition: 'ignore', + verticalLabelPosition: 'middle', }); }); }); @@ -595,14 +562,11 @@ describe('Style Computer', () => { kind: ShapeBpmnElementKind.GROUP, }, fontFamily: 'Roboto', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it + // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) + labelPosition: 'ignore', labelWidth: 101, verticalAlign: 'top', - // FIXME magraph@0.1.0 values were inverted in the master branch implementation, this was probably wrong as they were set like this in StyleConfigurator - // 'group;fontFamily=Roboto;verticalAlign=top;align=center;labelWidth=101;labelPosition=ignore;verticalLabelPosition=middle' - labelPosition: 'left', - verticalLabelPosition: 'top', - // end of fixme + verticalLabelPosition: 'middle', }); }); }); @@ -611,7 +575,7 @@ describe('Style Computer', () => { it.each([ ['vertical', false, true], ['horizontal', true, false], - ['undefined', undefined, false], + ['undefined', undefined, true], // the parser set a default value in the shape, so this shouldn't be used ])('%s pool references a Process', (title: string, isHorizontal: boolean, expectedStyleIsHorizontal: boolean) => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.POOL), undefined, isHorizontal); expect(computeStyle(shape)).toStrictEqual({ @@ -626,7 +590,7 @@ describe('Style Computer', () => { it.each([ ['vertical', false, true], ['horizontal', true, false], - ['undefined', undefined, false], + ['undefined', undefined, true], // the parser set a default value in the shape, so this shouldn't be used ])('%s lane', (title: string, isHorizontal: boolean, expectedStyleIsHorizontal: boolean) => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.LANE), undefined, isHorizontal); expect(computeStyle(shape)).toStrictEqual({ @@ -658,7 +622,6 @@ describe('Style Computer', () => { baseStyleNames: [bpmnKind], bpmn: { kind: bpmnKind, markers: [markerKind] }, fontFamily: 'Arial', - fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it }; bpmnKind === ShapeBpmnElementKind.TASK_RECEIVE && (expectedStyle.bpmn.isInstantiating = false); expect(computeStyle(shape)).toStrictEqual(expectedStyle); @@ -668,16 +631,11 @@ describe('Style Computer', () => { it.each(Object.values(ShapeBpmnSubProcessKind))(`%s subProcess with Loop & Expand (collapsed) markers`, (subProcessKind: ShapeBpmnSubProcessKind) => { const markers = [markerKind, ShapeBpmnMarkerKind.EXPAND]; const shape = newShape(newShapeBpmnSubProcess(subProcessKind, markers)); - expect(computeStyle(shape)).toBe(`subProcess;bpmn.subProcessKind=${subProcessKind};bpmn.markers=${getExpectedMarkers(markers, subProcessKind).join(',')}`); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['subProcess'], + bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, markers: getExpectedMarkers(markers, subProcessKind), subProcessKind }, + }); }); - // TODO rebase adapt test for maxgraph - // it(`${bpmnKind} with Loop & Expand (collapsed) markers`, () => { - // const shape = newShape(newShapeBpmnSubProcess(ShapeBpmnSubProcessKind.EMBEDDED, [markerKind, ShapeBpmnMarkerKind.EXPAND])); - // expect(computeStyle(shape)).toStrictEqual({ - // baseStyleNames: ['subProcess'], - // bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, markers: [markerKind, ShapeBpmnMarkerKind.EXPAND], subProcessKind: ShapeBpmnSubProcessKind.EMBEDDED }, - // }); - // }); } if (bpmnKind == ShapeBpmnElementKind.CALL_ACTIVITY) { @@ -687,7 +645,7 @@ describe('Style Computer', () => { baseStyleNames: ['callActivity'], bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, - globalTaskKind: undefined, // TODO magraph@0.1.0 decide if we omit the globalTaskKind property when not set + globalTaskKind: undefined, // TODO maxgraph@0.1.0 decide if we omit the globalTaskKind property when not set markers: [markerKind, ShapeBpmnMarkerKind.EXPAND], }, }); @@ -728,37 +686,26 @@ describe('Style Computer', () => { ({ instantiate, gatewayKind }: { instantiate: boolean; gatewayKind: ShapeBpmnEventBasedGatewayKind }) => { const shape = newShape(newShapeBpmnEventBasedGateway(instantiate, gatewayKind), newLabel({ name: 'Arial' })); gatewayKind ??= ShapeBpmnEventBasedGatewayKind.None; - expect(computeStyle(shape)).toBe(`eventBasedGateway;bpmn.isInstantiating=${!!instantiate};bpmn.gatewayKind=${gatewayKind};fontFamily=Arial`); + expect(computeStyle(shape)).toStrictEqual({ + baseStyleNames: ['eventBasedGateway'], + bpmn: { kind: ShapeBpmnElementKind.GATEWAY_EVENT_BASED, gatewayKind, isInstantiating: !!instantiate }, + fontFamily: 'Arial', + }); }, ); - // TODO rebase adapt test for maxGraph - // `( - // 'event-based gateway when instantiate: $instantiate for gatewayKind: $gatewayKind', - // ({ instantiate, gatewayKind }: { instantiate: boolean; gatewayKind: ShapeBpmnEventBasedGatewayKind }) => { - // const shape = newShape(newShapeBpmnEventBasedGateway(instantiate, gatewayKind), newLabel({ name: 'Arial' })); - // gatewayKind ??= ShapeBpmnEventBasedGatewayKind.None; - // expect(computeStyle(shape)).toStrictEqual({ - // baseStyleNames: ['eventBasedGateway'], - // bpmn: { kind: ShapeBpmnElementKind.GATEWAY_EVENT_BASED, gatewayKind, isInstantiating: !!instantiate }, - // fontFamily: 'Arial', - // fontStyle: 0, // TODO magraph@0.1.0 decide if we set the fontStyle property to 0 or if we omit it - // }); - // }, - // ); }); - // TODO rebase adapt tests for maxGraph describe('compute style - colors', () => { describe.each([[undefined], [false], [true]])(`Ignore BPMN colors: %s`, (ignoreBpmnColors: boolean) => { // 'undefined' RendererOptions tested in other tests in this file const styleComputer = new StyleComputer(ignoreBpmnColors === undefined ? {} : { ignoreBpmnColors: ignoreBpmnColors }); const expectAdditionalColorsStyle = !(ignoreBpmnColors ?? true); - function computeStyleWithRendererOptions(element: Shape | Edge): string { + function computeStyleWithRendererOptions(element: Shape | Edge): BPMNCellStyle { return styleComputer.computeStyle(element, element.label?.bounds); } - function computeMessageFlowIconStyleWithRendererOptions(edge: Edge): string { + function computeMessageFlowIconStyleWithRendererOptions(edge: Edge): BPMNCellStyle { return styleComputer.computeMessageFlowIconStyle(edge); } @@ -767,19 +714,40 @@ describe('Style Computer', () => { const shape = newShape(newShapeBpmnElement(kind), newLabelExtension('#010101')); shape.extensions.fillColor = '#000003'; shape.extensions.strokeColor = '#FF0203'; - const additionalColorsStyle = expectAdditionalColorsStyle ? ';fillColor=#000003;strokeColor=#FF0203;fontColor=#010101' : ''; - expect(computeStyleWithRendererOptions(shape)).toBe(`${kind}${additionalColorsStyle}`); + const expectedStyle = { + baseStyleNames: [kind], + bpmn: { kind: kind }, + }; + if (expectAdditionalColorsStyle) { + expectedStyle.fillColor = '#000003'; + expectedStyle.fontColor = '#010101'; + expectedStyle.strokeColor = '#FF0203'; + } + expect(computeStyleWithRendererOptions(shape)).toStrictEqual(expectedStyle); }); it.each([ShapeBpmnElementKind.LANE, ShapeBpmnElementKind.POOL])('%s', (kind: ShapeBpmnElementKind) => { - const shape = newShape(newShapeBpmnElement(kind), newLabelExtension('#aa0101')); + const shape = newShape(newShapeBpmnElement(kind), newLabelExtension('#aa0101'), true); shape.extensions.fillColor = '#AA0003'; shape.extensions.strokeColor = '#FF02AA'; - const additionalColorsStyle = expectAdditionalColorsStyle ? ';fillColor=#AA0003;swimlaneFillColor=#AA0003;strokeColor=#FF02AA;fontColor=#aa0101' : ''; - expect(computeStyleWithRendererOptions(shape)).toBe(`${kind};horizontal=1${additionalColorsStyle}`); + const expectedStyle = { + baseStyleNames: [kind], + bpmn: { kind: kind }, + horizontal: false, + }; + if (expectAdditionalColorsStyle) { + expectedStyle.fillColor = '#AA0003'; + expectedStyle.fontColor = '#aa0101'; + expectedStyle.strokeColor = '#FF02AA'; + expectedStyle.swimlaneFillColor = '#AA0003'; + } + expect(computeStyleWithRendererOptions(shape)).toStrictEqual(expectedStyle); }); it('no extension', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.TASK)); - expect(computeStyleWithRendererOptions(shape)).toBe(`task`); + expect(computeStyleWithRendererOptions(shape)).toStrictEqual({ + baseStyleNames: ['task'], + bpmn: { kind: ShapeBpmnElementKind.TASK }, + }); }); }); @@ -787,26 +755,55 @@ describe('Style Computer', () => { it('sequence flow', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.DEFAULT), undefined, newLabelExtension('#aaaaaa')); edge.extensions.strokeColor = '#111111'; - const additionalColorsStyle = expectAdditionalColorsStyle ? ';strokeColor=#111111;fontColor=#aaaaaa' : ''; - expect(computeStyleWithRendererOptions(edge)).toBe(`sequenceFlow;default${additionalColorsStyle}`); + const expectedStyle = { + baseStyleNames: ['sequenceFlow', 'default'], + bpmn: { kind: FlowKind.SEQUENCE_FLOW }, + }; + if (expectAdditionalColorsStyle) { + expectedStyle.fontColor = '#aaaaaa'; + expectedStyle.strokeColor = '#111111'; + } + + expect(computeStyleWithRendererOptions(edge)).toStrictEqual(expectedStyle); }); it('message flow', () => { const edge = new Edge('id', newMessageFlow(), undefined, newLabelExtension('#aaaabb')); edge.extensions.strokeColor = '#1111bb'; - const additionalColorsStyle = expectAdditionalColorsStyle ? ';strokeColor=#1111bb;fontColor=#aaaabb' : ''; - expect(computeStyleWithRendererOptions(edge)).toBe(`messageFlow${additionalColorsStyle}`); + const expectedStyle = { + baseStyleNames: ['messageFlow'], + bpmn: { kind: FlowKind.MESSAGE_FLOW }, + }; + if (expectAdditionalColorsStyle) { + expectedStyle.fontColor = '#aaaabb'; + expectedStyle.strokeColor = '#1111bb'; + } + expect(computeStyleWithRendererOptions(edge)).toStrictEqual(expectedStyle); }); it('message flow icon', () => { const edge = new Edge('id', newMessageFlow()); edge.extensions.strokeColor = '#11aabb'; - const additionalColorsStyle = expectAdditionalColorsStyle ? ';strokeColor=#11aabb' : ''; - expect(computeMessageFlowIconStyleWithRendererOptions(edge)).toBe(`shape=bpmn.messageFlowIcon;bpmn.isInitiating=false${additionalColorsStyle}`); + const expectedStyle = { + bpmn: { isInitiating: false }, + // TODO maxGraph@0.1.0 force conversion to ShapeValue + decide if we use BpmnStyleIdentifier const instead + shape: 'bpmn.messageFlowIcon', + }; + if (expectAdditionalColorsStyle) { + expectedStyle.strokeColor = '#11aabb'; + } + expect(computeMessageFlowIconStyleWithRendererOptions(edge)).toStrictEqual(expectedStyle); }); it('association flow', () => { const edge = new Edge('id', newAssociationFlow(AssociationDirectionKind.ONE), undefined, newLabelExtension('#aaaacc')); edge.extensions.strokeColor = '#1111cc'; - const additionalColorsStyle = expectAdditionalColorsStyle ? ';strokeColor=#1111cc;fontColor=#aaaacc' : ''; - expect(computeStyleWithRendererOptions(edge)).toBe(`association;One${additionalColorsStyle}`); + const expectedStyle = { + baseStyleNames: ['association', 'One'], + bpmn: { kind: FlowKind.ASSOCIATION_FLOW }, + }; + if (expectAdditionalColorsStyle) { + expectedStyle.fontColor = '#aaaacc'; + expectedStyle.strokeColor = '#1111cc'; + } + expect(computeStyleWithRendererOptions(edge)).toStrictEqual(expectedStyle); }); }); }); diff --git a/test/unit/component/mxgraph/renderer/style-utils.test.ts b/test/unit/component/mxgraph/renderer/style-utils.test.ts index 3d538cfb0b..077a4f799e 100644 --- a/test/unit/component/mxgraph/renderer/style-utils.test.ts +++ b/test/unit/component/mxgraph/renderer/style-utils.test.ts @@ -44,7 +44,6 @@ describe('compute base css class names of BPMN elements', () => { }); describe('compute all css class names based on style input', () => { - // TODO rebase adapt test entries it.each` style | isLabel | expectedClassNames ${{ bpmn: { kind: ShapeBpmnElementKind.LANE } }} | ${true} | ${['bpmn-type-container', 'bpmn-lane', 'bpmn-label']} @@ -62,21 +61,17 @@ describe('compute all css class names based on style input', () => { ${{ bpmn: { kind: ShapeBpmnElementKind.TASK } }} | ${true} | ${['bpmn-type-activity', 'bpmn-type-task', 'bpmn-task', 'bpmn-label']} ${{ bpmn: { kind: ShapeBpmnElementKind.TASK_BUSINESS_RULE } }} | ${false} | ${['bpmn-type-activity', 'bpmn-type-task', 'bpmn-business-rule-task']} ${{ bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS } }} | ${false} | ${['bpmn-type-activity', 'bpmn-sub-process']} - ${'subProcess;bpmn.subProcessKind=adHoc'} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-adhoc', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.AD_HOC } }} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-ad_hoc', 'bpmn-label']} ${{ bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.EMBEDDED } }} | ${false} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-embedded']} ${{ bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.EVENT } }} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-event', 'bpmn-label']} - ${'subProcess;bpmn.subProcessKind=transaction'} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-transaction', 'bpmn-label']} + ${{ bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind: ShapeBpmnSubProcessKind.TRANSACTION } }} | ${true} | ${['bpmn-type-activity', 'bpmn-sub-process', 'bpmn-sub-process-transaction', 'bpmn-label']} ${{ bpmn: { kind: FlowKind.ASSOCIATION_FLOW } }} | ${true} | ${['bpmn-type-flow', 'bpmn-association', 'bpmn-label']} ${{ bpmn: { kind: FlowKind.MESSAGE_FLOW } }} | ${false} | ${['bpmn-type-flow', 'bpmn-message-flow']} - ${'shape=bpmn.message-flow-icon'} | ${false} | ${['bpmn-message-flow-icon']} - ${'shape=bpmn.message-flow-icon;bpmn.isInitiating=false'} | ${false} | ${['bpmn-message-flow-icon', 'bpmn-icon-non-initiating']} - ${'shape=bpmn.message-flow-icon;bpmn.isInitiating=true'} | ${true} | ${['bpmn-message-flow-icon', 'bpmn-icon-initiating', 'bpmn-label']} ${{ bpmn: { kind: FlowKind.SEQUENCE_FLOW } }} | ${false} | ${['bpmn-type-flow', 'bpmn-sequence-flow']} - ${{ shape: 'bpmn.message-flow-icon' }} | ${false} | ${['bpmn-message-flow-icon']} - ${{ bpmn: { isNonInitiating: true }, shape: 'bpmn.message-flow-icon' }} | ${false} | ${['bpmn-message-flow-icon', 'bpmn-icon-non-initiating']} - ${{ bpmn: { isNonInitiating: false }, shape: 'bpmn.message-flow-icon' }} | ${true} | ${['bpmn-message-flow-icon', 'bpmn-icon-initiating', 'bpmn-label']} + ${{ bpmn: { isInitiating: false }, shape: 'bpmn.message-flow-icon' }} | ${false} | ${['bpmn-message-flow-icon', 'bpmn-icon-non-initiating']} + ${{ bpmn: { isInitiating: true }, shape: 'bpmn.message-flow-icon' }} | ${true} | ${['bpmn-message-flow-icon', 'bpmn-icon-initiating', 'bpmn-label']} `( - // TODO magraph@0.1.0 find a way to correctly display the style object + // TODO maxgraph@0.1.0 find a way to correctly display the style object 'style="$style" / isLabel=$isLabel', ({ style, isLabel, expectedClassNames }: { style: BPMNCellStyle; isLabel: boolean; expectedClassNames: string[] }) => { expect(computeAllBpmnClassNames(style, isLabel)).toEqual(expectedClassNames); From f6681a1d5a1609a892a27417f373e6146d64bbda Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:53:59 +0200 Subject: [PATCH 04/90] bump maxGraph from 0.1.0 to 0.10.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 780e640fde..9407082fce 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "utils:test:model": "node ./scripts/utils/dist/utils.mjs test/fixtures/bpmn/simple-start-task-end.bpmn --output model" }, "dependencies": { - "@maxgraph/core": "0.1.0", + "@maxgraph/core": "0.10.0", "fast-xml-parser": "4.2.5", "lodash-es": "~4.17.21", "strnum": "1.0.5" From f3b1775681117fd7e55905745f9a0ea60ae57a1e Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:54:21 +0200 Subject: [PATCH 05/90] update package-lock.json --- package-lock.json | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23f8f20f32..0b81ed6724 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,9 @@ "version": "0.37.0-post", "license": "Apache-2.0", "dependencies": { - "@typed-mxgraph/typed-mxgraph": "~1.0.8", + "@maxgraph/core": "0.10.0", "fast-xml-parser": "4.2.5", "lodash-es": "~4.17.21", - "mxgraph": "4.2.2", "strnum": "1.0.5" }, "devDependencies": { @@ -2824,6 +2823,11 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@maxgraph/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.0.tgz", + "integrity": "sha512-odxP8pniRZpdxFJW8/HAy8aFEXV8xtwK/2fx82DlhapveohJzM348e+y49lMFvD8W1ZfulTISEDAeLFb5/LZ8g==" + }, "node_modules/@microsoft/api-extractor": { "version": "7.35.2", "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.35.2.tgz", @@ -3283,11 +3287,6 @@ "node": ">=10.13.0" } }, - "node_modules/@typed-mxgraph/typed-mxgraph": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@typed-mxgraph/typed-mxgraph/-/typed-mxgraph-1.0.8.tgz", - "integrity": "sha512-rzTbmD/XofRq0YZMY/BU9cjbCTw9q8rpIvWRhQO0DcgCx3+rpHTsVOk3pfuhcnUigUYNFkljmDkRuVjbl7zZoQ==" - }, "node_modules/@types/argparse": { "version": "1.0.38", "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", @@ -8899,12 +8898,6 @@ "dev": true, "license": "MIT" }, - "node_modules/mxgraph": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/mxgraph/-/mxgraph-4.2.2.tgz", - "integrity": "sha512-FrJc5AxzXSqiQNF+8CyJk6VxuKO4UVPgw32FZuFZ3X9W+JqOAQBTokZhh0ZkEqGpEOyp3z778ssmBTvdrTAdqw==", - "deprecated": "Package no longer supported. Use at your own risk" - }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -14569,6 +14562,11 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@maxgraph/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.0.tgz", + "integrity": "sha512-odxP8pniRZpdxFJW8/HAy8aFEXV8xtwK/2fx82DlhapveohJzM348e+y49lMFvD8W1ZfulTISEDAeLFb5/LZ8g==" + }, "@microsoft/api-extractor": { "version": "7.35.2", "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.35.2.tgz", @@ -14922,11 +14920,6 @@ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "dev": true }, - "@typed-mxgraph/typed-mxgraph": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@typed-mxgraph/typed-mxgraph/-/typed-mxgraph-1.0.8.tgz", - "integrity": "sha512-rzTbmD/XofRq0YZMY/BU9cjbCTw9q8rpIvWRhQO0DcgCx3+rpHTsVOk3pfuhcnUigUYNFkljmDkRuVjbl7zZoQ==" - }, "@types/argparse": { "version": "1.0.38", "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", @@ -18790,11 +18783,6 @@ "version": "2.1.2", "dev": true }, - "mxgraph": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/mxgraph/-/mxgraph-4.2.2.tgz", - "integrity": "sha512-FrJc5AxzXSqiQNF+8CyJk6VxuKO4UVPgw32FZuFZ3X9W+JqOAQBTokZhh0ZkEqGpEOyp3z778ssmBTvdrTAdqw==" - }, "mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", From db2a32a2ac5e976022a7d447ebc09fb1f7ee1c49 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:57:52 +0200 Subject: [PATCH 06/90] fix tsc error after bumping maxGraph --- src/component/mxgraph/config/StyleConfigurator.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index e95098457b..f37adcec23 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -19,7 +19,7 @@ import { BpmnStyleIdentifier, MarkerIdentifier, StyleDefault } from '../style'; import type { BpmnGraph } from '../BpmnGraph'; import type { BPMNCellStyle } from '../renderer/StyleComputer'; import { constants, Perimeter } from '@maxgraph/core'; -import type { ArrowType, ShapeValue, Stylesheet } from '@maxgraph/core'; +import type { ShapeValue, Stylesheet } from '@maxgraph/core'; const arrowDefaultSize = 12; @@ -69,8 +69,7 @@ export class StyleConfigurator { [ SequenceFlowKind.DEFAULT, (style: BPMNCellStyle) => { - // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types - style.startArrow = MarkerIdentifier.ARROW_DASH; + style.startArrow = MarkerIdentifier.ARROW_DASH; }, ], [ @@ -137,8 +136,7 @@ export class StyleConfigurator { const style = this.getStylesheet().getDefaultVertexStyle(); configureCommonDefaultStyle(style); - // TODO maxgraph@0.1.0 arcSize should be a boolean (probably fixed in next versions of maxGraph) - style.absoluteArcSize = 1; + style.absoluteArcSize = true; style.arcSize = StyleDefault.SHAPE_ARC_SIZE; } From b8df3cc486ce5b2284fd46f5d8a696cd42cfbfac Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:25:25 +0200 Subject: [PATCH 07/90] bump vite to not have "No matching export in" --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9407082fce..131805ce5e 100644 --- a/package.json +++ b/package.json @@ -150,7 +150,7 @@ "ts-jest": "~29.1.0", "typedoc": "~0.24.8", "typescript": "~5.1.3", - "vite": "~4.3.9" + "vite": "~4.4.12" }, "overrides": { "@types/node": "^16.18.0" From bb5b1408f70961ec3790825e748971ed634230f4 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:25:36 +0200 Subject: [PATCH 08/90] update package-lock.json --- package-lock.json | 484 +++++++++++++++++++++++++--------------------- 1 file changed, 259 insertions(+), 225 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0b81ed6724..afcb36124a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,7 +66,7 @@ "ts-jest": "~29.1.0", "typedoc": "~0.24.8", "typescript": "~5.1.3", - "vite": "~4.3.9" + "vite": "~4.4.12" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -1866,9 +1866,9 @@ "dev": true }, "node_modules/@esbuild/android-arm": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.14.tgz", - "integrity": "sha512-0CnlwnjDU8cks0yJLXfkaU/uoLyRf9VZJs4p1PskBr2AlAHeEsFEwJEo0of/Z3g+ilw5mpyDwThlxzNEIxOE4g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", "cpu": [ "arm" ], @@ -1882,9 +1882,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.14.tgz", - "integrity": "sha512-eLOpPO1RvtsP71afiFTvS7tVFShJBCT0txiv/xjFBo5a7R7Gjw7X0IgIaFoLKhqXYAXhahoXm7qAmRXhY4guJg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", "cpu": [ "arm64" ], @@ -1898,9 +1898,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.14.tgz", - "integrity": "sha512-nrfQYWBfLGfSGLvRVlt6xi63B5IbfHm3tZCdu/82zuFPQ7zez4XjmRtF/wIRYbJQ/DsZrxJdEvYFE67avYXyng==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", "cpu": [ "x64" ], @@ -1914,9 +1914,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.14.tgz", - "integrity": "sha512-eoSjEuDsU1ROwgBH/c+fZzuSyJUVXQTOIN9xuLs9dE/9HbV/A5IqdXHU1p2OfIMwBwOYJ9SFVGGldxeRCUJFyw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", "cpu": [ "arm64" ], @@ -1930,9 +1930,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.14.tgz", - "integrity": "sha512-zN0U8RWfrDttdFNkHqFYZtOH8hdi22z0pFm0aIJPsNC4QQZv7je8DWCX5iA4Zx6tRhS0CCc0XC2m7wKsbWEo5g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", "cpu": [ "x64" ], @@ -1946,9 +1946,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.14.tgz", - "integrity": "sha512-z0VcD4ibeZWVQCW1O7szaLxGsx54gcCnajEJMdYoYjLiq4g1jrP2lMq6pk71dbS5+7op/L2Aod+erw+EUr28/A==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", "cpu": [ "arm64" ], @@ -1962,9 +1962,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.14.tgz", - "integrity": "sha512-hd9mPcxfTgJlolrPlcXkQk9BMwNBvNBsVaUe5eNUqXut6weDQH8whcNaKNF2RO8NbpT6GY8rHOK2A9y++s+ehw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", "cpu": [ "x64" ], @@ -1978,9 +1978,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.14.tgz", - "integrity": "sha512-BNTl+wSJ1omsH8s3TkQmIIIQHwvwJrU9u1ggb9XU2KTVM4TmthRIVyxSp2qxROJHhZuW/r8fht46/QE8hU8Qvg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", "cpu": [ "arm" ], @@ -1994,9 +1994,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.14.tgz", - "integrity": "sha512-FhAMNYOq3Iblcj9i+K0l1Fp/MHt+zBeRu/Qkf0LtrcFu3T45jcwB6A1iMsemQ42vR3GBhjNZJZTaCe3VFPbn9g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", "cpu": [ "arm64" ], @@ -2010,9 +2010,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.14.tgz", - "integrity": "sha512-91OK/lQ5y2v7AsmnFT+0EyxdPTNhov3y2CWMdizyMfxSxRqHazXdzgBKtlmkU2KYIc+9ZK3Vwp2KyXogEATYxQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", "cpu": [ "ia32" ], @@ -2026,9 +2026,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.14.tgz", - "integrity": "sha512-vp15H+5NR6hubNgMluqqKza85HcGJgq7t6rMH7O3Y6ApiOWPkvW2AJfNojUQimfTp6OUrACUXfR4hmpcENXoMQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", "cpu": [ "loong64" ], @@ -2042,9 +2042,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.14.tgz", - "integrity": "sha512-90TOdFV7N+fgi6c2+GO9ochEkmm9kBAKnuD5e08GQMgMINOdOFHuYLPQ91RYVrnWwQ5683sJKuLi9l4SsbJ7Hg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", "cpu": [ "mips64el" ], @@ -2058,9 +2058,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.14.tgz", - "integrity": "sha512-NnBGeoqKkTugpBOBZZoktQQ1Yqb7aHKmHxsw43NddPB2YWLAlpb7THZIzsRsTr0Xw3nqiPxbA1H31ZMOG+VVPQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", "cpu": [ "ppc64" ], @@ -2074,9 +2074,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.14.tgz", - "integrity": "sha512-0qdlKScLXA8MGVy21JUKvMzCYWovctuP8KKqhtE5A6IVPq4onxXhSuhwDd2g5sRCzNDlDjitc5sX31BzDoL5Fw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", "cpu": [ "riscv64" ], @@ -2090,9 +2090,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.14.tgz", - "integrity": "sha512-Hdm2Jo1yaaOro4v3+6/zJk6ygCqIZuSDJHdHaf8nVH/tfOuoEX5Riv03Ka15LmQBYJObUTNS1UdyoMk0WUn9Ww==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", "cpu": [ "s390x" ], @@ -2106,9 +2106,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.14.tgz", - "integrity": "sha512-8KHF17OstlK4DuzeF/KmSgzrTWQrkWj5boluiiq7kvJCiQVzUrmSkaBvcLB2UgHpKENO2i6BthPkmUhNDaJsVw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", "cpu": [ "x64" ], @@ -2122,9 +2122,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.14.tgz", - "integrity": "sha512-nVwpqvb3yyXztxIT2+VsxJhB5GCgzPdk1n0HHSnchRAcxqKO6ghXwHhJnr0j/B+5FSyEqSxF4q03rbA2fKXtUQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", "cpu": [ "x64" ], @@ -2138,9 +2138,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.14.tgz", - "integrity": "sha512-1RZ7uQQ9zcy/GSAJL1xPdN7NDdOOtNEGiJalg/MOzeakZeTrgH/DoCkbq7TaPDiPhWqnDF+4bnydxRqQD7il6g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", "cpu": [ "x64" ], @@ -2154,9 +2154,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.14.tgz", - "integrity": "sha512-nqMjDsFwv7vp7msrwWRysnM38Sd44PKmW8EzV01YzDBTcTWUpczQg6mGao9VLicXSgW/iookNK6AxeogNVNDZA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", "cpu": [ "x64" ], @@ -2170,9 +2170,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.14.tgz", - "integrity": "sha512-xrD0mccTKRBBIotrITV7WVQAwNJ5+1va6L0H9zN92v2yEdjfAN7864cUaZwJS7JPEs53bDTzKFbfqVlG2HhyKQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", "cpu": [ "arm64" ], @@ -2186,9 +2186,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.14.tgz", - "integrity": "sha512-nXpkz9bbJrLLyUTYtRotSS3t5b+FOuljg8LgLdINWFs3FfqZMtbnBCZFUmBzQPyxqU87F8Av+3Nco/M3hEcu1w==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", "cpu": [ "ia32" ], @@ -2202,9 +2202,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.14.tgz", - "integrity": "sha512-gPQmsi2DKTaEgG14hc3CHXHp62k8g6qr0Pas+I4lUxRMugGSATh/Bi8Dgusoz9IQ0IfdrvLpco6kujEIBoaogA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", "cpu": [ "x64" ], @@ -4403,9 +4403,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001473", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001473.tgz", - "integrity": "sha512-ewDad7+D2vlyy+E4UJuVfiBsU69IL+8oVmTuZnH5Q6CIUbxNfI50uVpRHbUPDD6SUaN2o0Lh4DhTrvLG/Tn1yg==", + "version": "1.0.30001612", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", + "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", "dev": true, "funding": [ { @@ -5282,9 +5282,9 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.14.tgz", - "integrity": "sha512-vOO5XhmVj/1XQR9NQ1UPq6qvMYL7QFJU57J5fKBKBKxp17uDt5PgxFDb4A2nEiXhr1qQs4x0F5+66hVVw4ruNw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "dev": true, "hasInstallScript": true, "bin": { @@ -5294,28 +5294,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.14", - "@esbuild/android-arm64": "0.17.14", - "@esbuild/android-x64": "0.17.14", - "@esbuild/darwin-arm64": "0.17.14", - "@esbuild/darwin-x64": "0.17.14", - "@esbuild/freebsd-arm64": "0.17.14", - "@esbuild/freebsd-x64": "0.17.14", - "@esbuild/linux-arm": "0.17.14", - "@esbuild/linux-arm64": "0.17.14", - "@esbuild/linux-ia32": "0.17.14", - "@esbuild/linux-loong64": "0.17.14", - "@esbuild/linux-mips64el": "0.17.14", - "@esbuild/linux-ppc64": "0.17.14", - "@esbuild/linux-riscv64": "0.17.14", - "@esbuild/linux-s390x": "0.17.14", - "@esbuild/linux-x64": "0.17.14", - "@esbuild/netbsd-x64": "0.17.14", - "@esbuild/openbsd-x64": "0.17.14", - "@esbuild/sunos-x64": "0.17.14", - "@esbuild/win32-arm64": "0.17.14", - "@esbuild/win32-ia32": "0.17.14", - "@esbuild/win32-x64": "0.17.14" + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" } }, "node_modules/escalade": { @@ -8910,9 +8910,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -9730,9 +9730,9 @@ } }, "node_modules/postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -9749,9 +9749,9 @@ } ], "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -11278,9 +11278,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -12271,14 +12271,14 @@ } }, "node_modules/vite": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", - "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.12.tgz", + "integrity": "sha512-KtPlUbWfxzGVul8Nut8Gw2Qe8sBzWY+8QVc5SL8iRFnpnrcoCaNlzO40c1R6hPmcdTwIPEDkq0Y9+27a5tVbdQ==", "dev": true, "dependencies": { - "esbuild": "^0.17.5", - "postcss": "^8.4.23", - "rollup": "^3.21.0" + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" }, "bin": { "vite": "bin/vite.js" @@ -12286,12 +12286,16 @@ "engines": { "node": "^14.18.0 || >=16.0.0" }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@types/node": ">= 14", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", @@ -12304,6 +12308,9 @@ "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, @@ -12318,6 +12325,22 @@ } } }, + "node_modules/vite/node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", @@ -13945,156 +13968,156 @@ "dev": true }, "@esbuild/android-arm": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.14.tgz", - "integrity": "sha512-0CnlwnjDU8cks0yJLXfkaU/uoLyRf9VZJs4p1PskBr2AlAHeEsFEwJEo0of/Z3g+ilw5mpyDwThlxzNEIxOE4g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.14.tgz", - "integrity": "sha512-eLOpPO1RvtsP71afiFTvS7tVFShJBCT0txiv/xjFBo5a7R7Gjw7X0IgIaFoLKhqXYAXhahoXm7qAmRXhY4guJg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.14.tgz", - "integrity": "sha512-nrfQYWBfLGfSGLvRVlt6xi63B5IbfHm3tZCdu/82zuFPQ7zez4XjmRtF/wIRYbJQ/DsZrxJdEvYFE67avYXyng==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.14.tgz", - "integrity": "sha512-eoSjEuDsU1ROwgBH/c+fZzuSyJUVXQTOIN9xuLs9dE/9HbV/A5IqdXHU1p2OfIMwBwOYJ9SFVGGldxeRCUJFyw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.14.tgz", - "integrity": "sha512-zN0U8RWfrDttdFNkHqFYZtOH8hdi22z0pFm0aIJPsNC4QQZv7je8DWCX5iA4Zx6tRhS0CCc0XC2m7wKsbWEo5g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.14.tgz", - "integrity": "sha512-z0VcD4ibeZWVQCW1O7szaLxGsx54gcCnajEJMdYoYjLiq4g1jrP2lMq6pk71dbS5+7op/L2Aod+erw+EUr28/A==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.14.tgz", - "integrity": "sha512-hd9mPcxfTgJlolrPlcXkQk9BMwNBvNBsVaUe5eNUqXut6weDQH8whcNaKNF2RO8NbpT6GY8rHOK2A9y++s+ehw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.14.tgz", - "integrity": "sha512-BNTl+wSJ1omsH8s3TkQmIIIQHwvwJrU9u1ggb9XU2KTVM4TmthRIVyxSp2qxROJHhZuW/r8fht46/QE8hU8Qvg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.14.tgz", - "integrity": "sha512-FhAMNYOq3Iblcj9i+K0l1Fp/MHt+zBeRu/Qkf0LtrcFu3T45jcwB6A1iMsemQ42vR3GBhjNZJZTaCe3VFPbn9g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.14.tgz", - "integrity": "sha512-91OK/lQ5y2v7AsmnFT+0EyxdPTNhov3y2CWMdizyMfxSxRqHazXdzgBKtlmkU2KYIc+9ZK3Vwp2KyXogEATYxQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.14.tgz", - "integrity": "sha512-vp15H+5NR6hubNgMluqqKza85HcGJgq7t6rMH7O3Y6ApiOWPkvW2AJfNojUQimfTp6OUrACUXfR4hmpcENXoMQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.14.tgz", - "integrity": "sha512-90TOdFV7N+fgi6c2+GO9ochEkmm9kBAKnuD5e08GQMgMINOdOFHuYLPQ91RYVrnWwQ5683sJKuLi9l4SsbJ7Hg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.14.tgz", - "integrity": "sha512-NnBGeoqKkTugpBOBZZoktQQ1Yqb7aHKmHxsw43NddPB2YWLAlpb7THZIzsRsTr0Xw3nqiPxbA1H31ZMOG+VVPQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.14.tgz", - "integrity": "sha512-0qdlKScLXA8MGVy21JUKvMzCYWovctuP8KKqhtE5A6IVPq4onxXhSuhwDd2g5sRCzNDlDjitc5sX31BzDoL5Fw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.14.tgz", - "integrity": "sha512-Hdm2Jo1yaaOro4v3+6/zJk6ygCqIZuSDJHdHaf8nVH/tfOuoEX5Riv03Ka15LmQBYJObUTNS1UdyoMk0WUn9Ww==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.14.tgz", - "integrity": "sha512-8KHF17OstlK4DuzeF/KmSgzrTWQrkWj5boluiiq7kvJCiQVzUrmSkaBvcLB2UgHpKENO2i6BthPkmUhNDaJsVw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.14.tgz", - "integrity": "sha512-nVwpqvb3yyXztxIT2+VsxJhB5GCgzPdk1n0HHSnchRAcxqKO6ghXwHhJnr0j/B+5FSyEqSxF4q03rbA2fKXtUQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.14.tgz", - "integrity": "sha512-1RZ7uQQ9zcy/GSAJL1xPdN7NDdOOtNEGiJalg/MOzeakZeTrgH/DoCkbq7TaPDiPhWqnDF+4bnydxRqQD7il6g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.14.tgz", - "integrity": "sha512-nqMjDsFwv7vp7msrwWRysnM38Sd44PKmW8EzV01YzDBTcTWUpczQg6mGao9VLicXSgW/iookNK6AxeogNVNDZA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.14.tgz", - "integrity": "sha512-xrD0mccTKRBBIotrITV7WVQAwNJ5+1va6L0H9zN92v2yEdjfAN7864cUaZwJS7JPEs53bDTzKFbfqVlG2HhyKQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.14.tgz", - "integrity": "sha512-nXpkz9bbJrLLyUTYtRotSS3t5b+FOuljg8LgLdINWFs3FfqZMtbnBCZFUmBzQPyxqU87F8Av+3Nco/M3hEcu1w==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.14.tgz", - "integrity": "sha512-gPQmsi2DKTaEgG14hc3CHXHp62k8g6qr0Pas+I4lUxRMugGSATh/Bi8Dgusoz9IQ0IfdrvLpco6kujEIBoaogA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", "dev": true, "optional": true }, @@ -15703,9 +15726,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001473", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001473.tgz", - "integrity": "sha512-ewDad7+D2vlyy+E4UJuVfiBsU69IL+8oVmTuZnH5Q6CIUbxNfI50uVpRHbUPDD6SUaN2o0Lh4DhTrvLG/Tn1yg==", + "version": "1.0.30001612", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", + "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", "dev": true }, "chalk": { @@ -16301,33 +16324,33 @@ "dev": true }, "esbuild": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.14.tgz", - "integrity": "sha512-vOO5XhmVj/1XQR9NQ1UPq6qvMYL7QFJU57J5fKBKBKxp17uDt5PgxFDb4A2nEiXhr1qQs4x0F5+66hVVw4ruNw==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.17.14", - "@esbuild/android-arm64": "0.17.14", - "@esbuild/android-x64": "0.17.14", - "@esbuild/darwin-arm64": "0.17.14", - "@esbuild/darwin-x64": "0.17.14", - "@esbuild/freebsd-arm64": "0.17.14", - "@esbuild/freebsd-x64": "0.17.14", - "@esbuild/linux-arm": "0.17.14", - "@esbuild/linux-arm64": "0.17.14", - "@esbuild/linux-ia32": "0.17.14", - "@esbuild/linux-loong64": "0.17.14", - "@esbuild/linux-mips64el": "0.17.14", - "@esbuild/linux-ppc64": "0.17.14", - "@esbuild/linux-riscv64": "0.17.14", - "@esbuild/linux-s390x": "0.17.14", - "@esbuild/linux-x64": "0.17.14", - "@esbuild/netbsd-x64": "0.17.14", - "@esbuild/openbsd-x64": "0.17.14", - "@esbuild/sunos-x64": "0.17.14", - "@esbuild/win32-arm64": "0.17.14", - "@esbuild/win32-ia32": "0.17.14", - "@esbuild/win32-x64": "0.17.14" + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" } }, "escalade": { @@ -18795,9 +18818,9 @@ } }, "nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true }, "natural-compare": { @@ -19333,14 +19356,14 @@ "dev": true }, "postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "requires": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "postcss-calc": { @@ -20336,9 +20359,9 @@ "dev": true }, "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true }, "source-map-support": { @@ -21021,15 +21044,26 @@ "dev": true }, "vite": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", - "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.12.tgz", + "integrity": "sha512-KtPlUbWfxzGVul8Nut8Gw2Qe8sBzWY+8QVc5SL8iRFnpnrcoCaNlzO40c1R6hPmcdTwIPEDkq0Y9+27a5tVbdQ==", "dev": true, "requires": { - "esbuild": "^0.17.5", + "esbuild": "^0.18.10", "fsevents": "~2.3.2", - "postcss": "^8.4.23", - "rollup": "^3.21.0" + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "dependencies": { + "rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + } } }, "vscode-oniguruma": { From cdced0584a72266dca00d708e88fbe6b35187ddd Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:36:43 +0200 Subject: [PATCH 09/90] fix tsc error after bumping maxGraph --- test/integration/helpers/model-expect.ts | 6 +++--- test/integration/mxGraph.model.bpmn.elements.test.ts | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/test/integration/helpers/model-expect.ts b/test/integration/helpers/model-expect.ts index e69863eaaa..f12ba67aff 100644 --- a/test/integration/helpers/model-expect.ts +++ b/test/integration/helpers/model-expect.ts @@ -59,7 +59,7 @@ import { toBeTextAnnotation, toBeUserTask, } from '../matchers'; -import type { ArrowType, Cell, FilterFunction, Geometry, ShapeValue } from '@maxgraph/core'; +import type { StyleArrowValue, Cell, FilterFunction, Geometry, ShapeValue } from '@maxgraph/core'; import type { ExpectedOverlay } from '../matchers/matcher-utils'; import { getCell } from '../matchers/matcher-utils'; import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; @@ -200,8 +200,8 @@ export interface ExpectedCallActivityModelElement extends ExpectedShapeModelElem export interface ExpectedEdgeModelElement extends ExpectedModelElement { kind?: FlowKind; - startArrow?: ArrowType; - endArrow?: ArrowType; + startArrow?: StyleArrowValue; + endArrow?: StyleArrowValue; messageVisibleKind?: MessageVisibleKind; } diff --git a/test/integration/mxGraph.model.bpmn.elements.test.ts b/test/integration/mxGraph.model.bpmn.elements.test.ts index 7f09e26068..a9edde643c 100644 --- a/test/integration/mxGraph.model.bpmn.elements.test.ts +++ b/test/integration/mxGraph.model.bpmn.elements.test.ts @@ -35,7 +35,6 @@ import { expectTotalShapesInModel, getDefaultParentId, } from './helpers/model-expect'; -import type { ArrowType } from '@maxgraph/core'; import { Point, Geometry } from '@maxgraph/core'; describe('mxGraph model - BPMN elements', () => { @@ -1470,8 +1469,7 @@ describe('mxGraph model - BPMN elements', () => { it('sequence flows', () => { expect('default_sequence_flow_id').toBeSequenceFlow({ sequenceFlowKind: SequenceFlowKind.DEFAULT, - // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types - startArrow: (MarkerIdentifier.ARROW_DASH), + startArrow: MarkerIdentifier.ARROW_DASH, parentId: 'participant_1_id', font: expectedBoldFont, }); From 675857d51b445e8d73431dfa2e0d4f854cc5f6d2 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:34:52 +0200 Subject: [PATCH 10/90] StyleConfigurator.ts add missing TODO maxgraph 0.1.0 --- src/component/mxgraph/config/StyleConfigurator.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index f37adcec23..3c416d24ad 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -137,6 +137,7 @@ export class StyleConfigurator { configureCommonDefaultStyle(style); style.absoluteArcSize = true; + // TODO maxgraph@0.1.0 find a way to not force cast style.arcSize = StyleDefault.SHAPE_ARC_SIZE; } From fc6205404992bf6d91098e7d7ae0fafe692adb99 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 22 Apr 2024 18:21:36 +0200 Subject: [PATCH 11/90] EXTRA integration tests run in ESM (needed for maxgraph --> IN PROGRESS in master branch) WIP integration tests run in ESM (with commonJS configuration) Revert "EXTRA WIP run integration in ESM mode" This reverts commit 21c3691647630cd11f5572789d47cc5a22decfce. EXTRA WIP run integration in ESM mode EXTRA WIP run integration in ESM mode (vscode config) --- .vscode/launch.json | 3 +++ .vscode/settings.json | 2 +- package.json | 2 +- sonar-project.properties | 2 +- test/integration/jest.config.js | 13 +++++-------- test/shared/file-helper.ts | 7 +++++-- tsconfig.test.json | 1 + 7 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 83692dbd64..8fd30443a9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -33,6 +33,9 @@ "name": "test:integration", "request": "launch", "program": "${workspaceFolder}/node_modules/jest/bin/jest", + "env": { + "NODE_OPTIONS": "--experimental-vm-modules" + }, "args": [ "--runInBand", "--config=./test/integration/jest.config.js" ], diff --git a/.vscode/settings.json b/.vscode/settings.json index 3f23f89cb4..fa8e5593f0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, // Jest Extension (https://github.com/jest-community/vscode-jest) // The following is to run unit tests diff --git a/package.json b/package.json index 131805ce5e..4cebe3232c 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "test": "run-s test:unit test:integration test:e2e", "test:unit": "jest --runInBand --config=./test/unit/jest.config.js", "test:unit:coverage": "npm run test:unit -- --coverage", - "test:integration": "jest --runInBand --config=./test/integration/jest.config.js", + "test:integration": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --config=./test/integration/jest.config.js", "test:integration:coverage": "npm run test:integration -- --coverage", "test:unit:watch": "npm run test:unit:coverage -- --watchAll", "test:e2e": "cross-env JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 jest --runInBand --detectOpenHandles --config=./test/e2e/jest.config.js", diff --git a/sonar-project.properties b/sonar-project.properties index cb2d02967c..d9302d80cd 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -16,7 +16,7 @@ sonar.sourceEncoding=UTF-8 # Path to tests sonar.tests=test -sonar.test.exclusions=**/jest.config.js,**/*.png +sonar.test.exclusions=**/jest.config.js,**/jest.config.cjs,**/jest.config.mjs,**/*.png #sonar.test.inclusions= sonar.javascript.lcov.reportPaths=build/test-report/unit/lcov.info,build/test-report/integration/lcov.info,build/test-report/e2e/lcov.info diff --git a/test/integration/jest.config.js b/test/integration/jest.config.js index 64c317ece8..380de337e6 100644 --- a/test/integration/jest.config.js +++ b/test/integration/jest.config.js @@ -26,18 +26,15 @@ module.exports = { '^.+\\.ts?$': [ 'ts-jest', { + useESM: true, tsconfig: '/tsconfig.test.json', }, ], }, - moduleNameMapper: { - ...moduleNameMapper, - // Hack to use lodash instead of lodash-es in integration tests. - // This is only to resolve the import, otherwise Jest fails to parse the lodash-es files. - // For more details, see https://github.com/process-analytics/bpmn-visualization-js/pull/2678 - // The lodash code is not called in integration tests, so changing the lodash implementation in used in not an issue. - '^lodash-es$': 'lodash', - }, + moduleNameMapper, + extensionsToTreatAsEsm: ['.ts'], + // https://jestjs.io/docs/configuration#modulefileextensions-arraystring + moduleFileExtensions: ['ts', 'js', 'mjs', 'cjs', 'jsx', 'tsx', 'json', 'node'], collectCoverageFrom: ['src/**/*.{ts,js}'], coveragePathIgnorePatterns: ['/src/model/'], coverageReporters: ['lcov', 'text-summary'], diff --git a/test/shared/file-helper.ts b/test/shared/file-helper.ts index 88dfa0567d..e4c28b3bab 100644 --- a/test/shared/file-helper.ts +++ b/test/shared/file-helper.ts @@ -15,13 +15,16 @@ limitations under the License. */ import { readdirSync, readFileSync as fsReadFileSync } from 'node:fs'; -import { join } from 'node:path'; +import { join, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); export function readFileSync(relPathToSourceFile: string, encoding: BufferEncoding = 'utf-8', dirName = __dirname): string { return fsReadFileSync(join(dirName, relPathToSourceFile), { encoding }); } -/** Returns the files in the given directory. The function doesn't do any recursion in sub directories. */ +/** Returns the files in the given directory. The function doesn't do any recursion in subdirectories. */ export function findFiles(relPathToSourceDirectory: string): string[] { return readdirSync(join(__dirname, relPathToSourceDirectory)); } diff --git a/tsconfig.test.json b/tsconfig.test.json index 4704ae1ec1..fa30d82f12 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -1,6 +1,7 @@ { "extends": "./tsconfig", "compilerOptions": { + "module": "ES2020", "sourceMap": true, "baseUrl": ".", "paths": { From 1aa5ee246468c684b1d68859dd8de642bd618b73 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:05:22 +0200 Subject: [PATCH 12/90] EXTRA unit tests run in ESM (needed to run maxgraph) with commonJS configuration EXTRA WIP unit tests run in ESM (with commonJS configuration) WIP unit tests run in ESM (with commonJS configuration) WIP unit tests run in ESM (with commonJS configuration) test pass WIP unit tests run in ESM (with commonJS configuration) vscode config --- .vscode/launch.json | 3 +++ package.json | 2 +- test/unit/component/parser/parsing-messages.test.ts | 1 + test/unit/component/registry/bpmn-model-registry.test.ts | 1 + test/unit/jest.config.js | 4 ++++ 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 8fd30443a9..4734dece5a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,6 +9,9 @@ "name": "test:unit", "request": "launch", "program": "${workspaceFolder}/node_modules/jest/bin/jest", + "env": { + "NODE_OPTIONS": "--experimental-vm-modules" + }, "args": [ "--runInBand", "--config=./test/unit/jest.config.js" ], diff --git a/package.json b/package.json index 4cebe3232c..c52eb7dd57 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "lint": "eslint \"**/*.{js,mjs,ts}\" --max-warnings 0 --quiet --fix", "lint-check": "eslint \"**/*.{js,mjs,ts}\" --max-warnings 0", "test": "run-s test:unit test:integration test:e2e", - "test:unit": "jest --runInBand --config=./test/unit/jest.config.js", + "test:unit": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --config=./test/unit/jest.config.js", "test:unit:coverage": "npm run test:unit -- --coverage", "test:integration": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --config=./test/integration/jest.config.js", "test:integration:coverage": "npm run test:integration -- --coverage", diff --git a/test/unit/component/parser/parsing-messages.test.ts b/test/unit/component/parser/parsing-messages.test.ts index 9a66b5cce4..7a0fd4540f 100644 --- a/test/unit/component/parser/parsing-messages.test.ts +++ b/test/unit/component/parser/parsing-messages.test.ts @@ -24,6 +24,7 @@ import { ShapeUnknownBpmnElementWarning, BoundaryEventNotAttachedToActivityWarning, } from '@lib/component/parser/json/warnings'; +import { jest } from '@jest/globals'; describe('parsing message collector', () => { jest.spyOn(console, 'warn').mockImplementation(() => { diff --git a/test/unit/component/registry/bpmn-model-registry.test.ts b/test/unit/component/registry/bpmn-model-registry.test.ts index 20a11b7e05..ea1cd2d637 100644 --- a/test/unit/component/registry/bpmn-model-registry.test.ts +++ b/test/unit/component/registry/bpmn-model-registry.test.ts @@ -18,6 +18,7 @@ import type { EdgeBpmnSemantic, ShapeBpmnSemantic } from '@lib/component/registr import { BpmnModelRegistry } from '@lib/component/registry/bpmn-model-registry'; import { expectAssociationFlow, expectLane, expectMessageFlow, expectPool, expectSequenceFlow, expectStartEvent } from '@test/shared/model/bpmn-semantic-utils'; import { associationFlowInModel, laneInModel, messageFlowInModel, poolInModel, sequenceFlowInModel, startEventInModel } from '../../helpers/bpmn-model-utils'; +import { jest } from '@jest/globals'; const bpmnModelRegistry = new BpmnModelRegistry(); diff --git a/test/unit/jest.config.js b/test/unit/jest.config.js index 08472ac49d..a108c58a11 100644 --- a/test/unit/jest.config.js +++ b/test/unit/jest.config.js @@ -26,9 +26,13 @@ module.exports = { 'ts-jest', { tsconfig: '/tsconfig.test.json', + useESM: true, }, ], }, + extensionsToTreatAsEsm: ['.ts'], + // https://jestjs.io/docs/configuration#modulefileextensions-arraystring + moduleFileExtensions: ['ts', 'js', 'mjs', 'cjs', 'jsx', 'tsx', 'json', 'node'], moduleNameMapper, collectCoverageFrom: ['src/**/*.{ts,js}'], coveragePathIgnorePatterns: ['/src/model/'], From d6d2261762dd943d654161c01e542c0205083981 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:48:48 +0200 Subject: [PATCH 13/90] WIP e2e and perf tests run in ESM (with commonJS configuration) --- package.json | 4 ++-- test/e2e/jest.config.js | 4 ++++ test/performance/jest.config.js | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c52eb7dd57..b58a7c9eed 100644 --- a/package.json +++ b/package.json @@ -72,10 +72,10 @@ "test:integration": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --config=./test/integration/jest.config.js", "test:integration:coverage": "npm run test:integration -- --coverage", "test:unit:watch": "npm run test:unit:coverage -- --watchAll", - "test:e2e": "cross-env JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 jest --runInBand --detectOpenHandles --config=./test/e2e/jest.config.js", + "test:e2e": "cross-env NODE_OPTIONS=--experimental-vm-modules jest JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 jest --runInBand --detectOpenHandles --config=./test/e2e/jest.config.js", "test:e2e:verbose": "cross-env DEBUG=bv:test:*,pw:browser* npm run test:e2e", "test:e2e:coverage": "npm run test:e2e -- --coverage", - "test:perf": "jest --runInBand --detectOpenHandles --config=./test/performance/jest.config.js", + "test:perf": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --detectOpenHandles --config=./test/performance/jest.config.js", "test:perf:verbose": "cross-env DEBUG=bv:test:*,pw:browser* npm run test:perf", "test:perf:compile": "tsc -p test/performance/", "test:bundles": "jest --runInBand --detectOpenHandles --config=./test/bundles/jest.config.js", diff --git a/test/e2e/jest.config.js b/test/e2e/jest.config.js index a2a71ba7e6..7df703100b 100644 --- a/test/e2e/jest.config.js +++ b/test/e2e/jest.config.js @@ -31,9 +31,13 @@ module.exports = { 'ts-jest', { tsconfig: '/tsconfig.test.json', + useESM: true, }, ], }, + extensionsToTreatAsEsm: ['.ts'], + // https://jestjs.io/docs/configuration#modulefileextensions-arraystring + moduleFileExtensions: ['ts', 'js', 'mjs', 'cjs', 'jsx', 'tsx', 'json', 'node'], moduleNameMapper, collectCoverageFrom: ['src/**/*.{ts,js}'], coveragePathIgnorePatterns: ['/src/model'], diff --git a/test/performance/jest.config.js b/test/performance/jest.config.js index cca8f60b9f..1013b808bf 100644 --- a/test/performance/jest.config.js +++ b/test/performance/jest.config.js @@ -30,9 +30,13 @@ module.exports = { 'ts-jest', { tsconfig: '/tsconfig.test.json', + useESM: true, }, ], }, + extensionsToTreatAsEsm: ['.ts'], + // https://jestjs.io/docs/configuration#modulefileextensions-arraystring + moduleFileExtensions: ['ts', 'js', 'mjs', 'cjs', 'jsx', 'tsx', 'json', 'node'], moduleNameMapper, setupFiles: ['./test/config/jest.retries.ts'], setupFilesAfterEnv: ['jest-extended/all', 'expect-playwright'], From d6420fb4303bdccd9f366c8143d9aca097db696a Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:57:49 +0200 Subject: [PATCH 14/90] WIP e2e and perf tests run in ESM (with commonJS configuration) --- test/config/jest.retries.ts | 7 +++--- test/shared/environment-utils.ts | 34 +++++++++++++++++++++++++++++ test/shared/visu/bpmn-page-utils.ts | 4 +--- 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 test/shared/environment-utils.ts diff --git a/test/config/jest.retries.ts b/test/config/jest.retries.ts index de0ee376a1..bd6a894ba7 100644 --- a/test/config/jest.retries.ts +++ b/test/config/jest.retries.ts @@ -14,9 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore js file with commonjs export -import envUtils = require('@test/shared/environment-utils.js'); +import { jest } from '@jest/globals'; +import { isRunningOnCi } from '@test/shared/environment-utils'; -const onCi = envUtils.isRunningOnCi(); +const onCi = isRunningOnCi(); jest.retryTimes(onCi ? 3 : 0, { logErrorsBeforeRetry: true }); diff --git a/test/shared/environment-utils.ts b/test/shared/environment-utils.ts new file mode 100644 index 0000000000..b00d9a0ae0 --- /dev/null +++ b/test/shared/environment-utils.ts @@ -0,0 +1,34 @@ +/* +Copyright 2022 Bonitasoft S.A. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// TODO duplicated with environment-utils.js + +const isMacOS = (): boolean => { + return process.platform.startsWith('darwin'); +}; + +const isWindowsOS = (): boolean => { + return process.platform.startsWith('win'); +}; + +// running on GitHub Actions: https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables +export const isRunningOnCi = (): boolean => { + return process.env.CI === 'true'; +}; + +export const isRunningOnCISlowOS = (): boolean => { + return isRunningOnCi() && (isMacOS() || isWindowsOS()); +}; diff --git a/test/shared/visu/bpmn-page-utils.ts b/test/shared/visu/bpmn-page-utils.ts index 6b3da31077..5b46d4fa2c 100644 --- a/test/shared/visu/bpmn-page-utils.ts +++ b/test/shared/visu/bpmn-page-utils.ts @@ -27,9 +27,7 @@ import type { ShapeStyleUpdate } from '@lib/component/registry'; import type { StyleUpdate } from '@lib/component/registry'; import { BpmnQuerySelectorsForTests } from '@test/shared/query-selectors'; import { delay } from './test-utils'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore js file with commonjs export -import envUtils = require('../environment-utils.js'); +import * as envUtils from '../environment-utils'; const pageCheckLog = debugLogger('bv:test:page-check'); From e3af05659951e9cdda40b675f2f492f56eae0b27 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:13:58 +0200 Subject: [PATCH 15/90] EXTRA jest.image.ts fix async by using await The promises management was wrong, images were not correctly assigned to the right file --- test/config/jest.image.ts | 55 ++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/test/config/jest.image.ts b/test/config/jest.image.ts index 74d53a0cf1..75985d9a24 100644 --- a/test/config/jest.image.ts +++ b/test/config/jest.image.ts @@ -56,7 +56,7 @@ class RetriesCounter { const retriesCounter = new RetriesCounter(); -function saveAndRegisterImages(matcherContext: MatcherContext, received: Buffer, options: MatchImageSnapshotOptions): void { +async function saveAndRegisterImages(matcherContext: MatcherContext, received: Buffer, options: MatchImageSnapshotOptions): Promise { const snapshotIdentifier = options.customSnapshotIdentifier; // Manage expected and received images const baseImagePathWithName = `${options.customDiffDir}/${snapshotIdentifier}`; @@ -79,35 +79,32 @@ function saveAndRegisterImages(matcherContext: MatcherContext, received: Buffer, matchers: {}, // required by the jest-html-reporters getJestGlobalData function even if not used }; - addAttach({ - attach: computeRelativePathFromReportToSnapshots(`${baseImagePathWithName}-diff.png`), - description: 'diff', - bufferFormat: 'png', - context, - }) - .then(() => - addAttach({ - attach: computeRelativePathFromReportToSnapshots(expectedImagePath), - description: 'expected', - bufferFormat: 'png', - context, - }), - ) - .then(() => { - addAttach({ - attach: computeRelativePathFromReportToSnapshots(receivedImagePath), - description: 'received', - bufferFormat: 'png', - context, - }); - }) - .catch(e => - console.error( - `Error while attaching images to test ${snapshotIdentifier}.` + - `The 'jest-html-reporters' reporter is probably not in use. For instance, this occurs when running tests with the IntelliJ/Webstorm Jest runner.`, - e, - ), + try { + await addAttach({ + attach: computeRelativePathFromReportToSnapshots(`${baseImagePathWithName}-diff.png`), + description: 'diff', + bufferFormat: 'png', + context, + }); + await addAttach({ + attach: computeRelativePathFromReportToSnapshots(expectedImagePath), + description: 'expected', + bufferFormat: 'png', + context, + }); + await addAttach({ + attach: computeRelativePathFromReportToSnapshots(receivedImagePath), + description: 'received', + bufferFormat: 'png', + context, + }); + } catch (e) { + console.error( + `Error while attaching images to test ${snapshotIdentifier}.` + + `The 'jest-html-reporters' reporter is probably not in use. For instance, this occurs when running tests with the IntelliJ/Webstorm Jest runner.`, + e, ); + } } // Improve jest-image-snapshot outputs to facilitate debug From c9259664d7a8e245302c1594da9eb7fa8c692561 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:16:35 +0200 Subject: [PATCH 16/90] WIP e2e tests run in ESM - tmp jest.image configuration --- test/config/jest.image.tmp.ts | 24 ++++++++++++++++++++++++ test/e2e/jest.config.js | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 test/config/jest.image.tmp.ts diff --git a/test/config/jest.image.tmp.ts b/test/config/jest.image.tmp.ts new file mode 100644 index 0000000000..ad5e7f17ee --- /dev/null +++ b/test/config/jest.image.tmp.ts @@ -0,0 +1,24 @@ +/* +Copyright 2024 Bonitasoft S.A. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { expect } from '@jest/globals'; +import toMatchImageSnapshot from 'jest-image-snapshot'; + +// This is a temporary fix, waiting for the migration of jest.image.ts + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore not the right signature, but works at runtime +expect.extend(toMatchImageSnapshot); diff --git a/test/e2e/jest.config.js b/test/e2e/jest.config.js index 7df703100b..35f23722dc 100644 --- a/test/e2e/jest.config.js +++ b/test/e2e/jest.config.js @@ -48,7 +48,8 @@ module.exports = { 'expect-playwright', './test/config/jest.retries.ts', // jest-image-snapshot configuration doesn't work with setupFiles, fix with setupFilesAfterEnv: see https://github.com/testing-library/jest-dom/issues/122#issuecomment-650520461 - './test/config/jest.image.ts', + './test/config/jest.image.tmp.ts', + // './test/config/jest.image.ts', // need playwright globals to be available, so after environment './test/config/playwright.browser.logs.ts', ], From c95a9cb91fa70c78e86a37bc95b9d465189cef60 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:20:46 +0200 Subject: [PATCH 17/90] WIP e2e tests run in ESM - tmp jest.image configuration --- test/config/jest.image.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/config/jest.image.ts b/test/config/jest.image.ts index 75985d9a24..4fd3e3fe36 100644 --- a/test/config/jest.image.ts +++ b/test/config/jest.image.ts @@ -61,6 +61,7 @@ async function saveAndRegisterImages(matcherContext: MatcherContext, received: B // Manage expected and received images const baseImagePathWithName = `${options.customDiffDir}/${snapshotIdentifier}`; const expectedImagePath = `${baseImagePathWithName}-expected.png`; + // TODO could use async as the function is async copyFileSync(`${options.customSnapshotsDir}/${snapshotIdentifier}.png`, expectedImagePath); // this image is generated by jest-image-snapshot when activating `storeReceivedOnFailure` const receivedImagePath = `${baseImagePathWithName}-received.png`; @@ -111,7 +112,7 @@ async function saveAndRegisterImages(matcherContext: MatcherContext, received: B // The 'options' parameter is mandatory for us, and some properties must be set as well // All options properties used here are always set in bpmn-visualization tests // If the following implementation would be done directly in jest-image-snapshot, this won't be required as it set default values we cannot access here -function toMatchImageSnapshotCustom(this: MatcherContext, received: Buffer, options: MatchImageSnapshotOptions): CustomMatcherResult { +async function toMatchImageSnapshotCustom(this: MatcherContext, received: Buffer, options: MatchImageSnapshotOptions): Promise { const testId = this.currentTestName; retriesCounter.incrementExecutionCount(testId); jestLog("Test: '%s' (test file path: '%s')", this.currentTestName, this.testPath); @@ -123,7 +124,7 @@ function toMatchImageSnapshotCustom(this: MatcherContext, received: Buffer, opti if (!result.pass) { jestLog('Result: failure'); if (retriesCounter.hasReachMaxRetries(testId)) { - saveAndRegisterImages(this, received, options); + await saveAndRegisterImages(this, received, options); } // Add configured failure threshold in the error message From 54e811773bc54b3efe3862fe9414047441763cd5 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:23:24 +0200 Subject: [PATCH 18/90] WIP e2e tests run in ESM - tmp jest.image configuration --- test/e2e/jest.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/e2e/jest.config.js b/test/e2e/jest.config.js index 35f23722dc..23ab8eb0e8 100644 --- a/test/e2e/jest.config.js +++ b/test/e2e/jest.config.js @@ -48,6 +48,7 @@ module.exports = { 'expect-playwright', './test/config/jest.retries.ts', // jest-image-snapshot configuration doesn't work with setupFiles, fix with setupFilesAfterEnv: see https://github.com/testing-library/jest-dom/issues/122#issuecomment-650520461 + // TODO tmp implementation (no attachment in the report) './test/config/jest.image.tmp.ts', // './test/config/jest.image.ts', // need playwright globals to be available, so after environment From b002dcdc3ce2d3819f4b96135aee69d7e2feb1ce Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:46:04 +0200 Subject: [PATCH 19/90] WIP e2e tests run in ESM - fix package.json script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b58a7c9eed..cbac05ee80 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "test:integration": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --config=./test/integration/jest.config.js", "test:integration:coverage": "npm run test:integration -- --coverage", "test:unit:watch": "npm run test:unit:coverage -- --watchAll", - "test:e2e": "cross-env NODE_OPTIONS=--experimental-vm-modules jest JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 jest --runInBand --detectOpenHandles --config=./test/e2e/jest.config.js", + "test:e2e": "cross-env NODE_OPTIONS=--experimental-vm-modules JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 jest --runInBand --detectOpenHandles --config=./test/e2e/jest.config.js", "test:e2e:verbose": "cross-env DEBUG=bv:test:*,pw:browser* npm run test:e2e", "test:e2e:coverage": "npm run test:e2e -- --coverage", "test:perf": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --detectOpenHandles --config=./test/performance/jest.config.js", From 99901fa70d42dba4c307f15c98c453a11ad85b5b Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:23:58 +0200 Subject: [PATCH 20/90] bump maxGraph --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cbac05ee80..269163f4b2 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "utils:test:model": "node ./scripts/utils/dist/utils.mjs test/fixtures/bpmn/simple-start-task-end.bpmn --output model" }, "dependencies": { - "@maxgraph/core": "0.10.0", + "@maxgraph/core": "0.10.1", "fast-xml-parser": "4.2.5", "lodash-es": "~4.17.21", "strnum": "1.0.5" From ec2b544e6f744e76cca09cc36411fb33fd30a7a4 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:24:29 +0200 Subject: [PATCH 21/90] update package-lock.json after maxGraph bump --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index afcb36124a..c40c351dde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.37.0-post", "license": "Apache-2.0", "dependencies": { - "@maxgraph/core": "0.10.0", + "@maxgraph/core": "0.10.1", "fast-xml-parser": "4.2.5", "lodash-es": "~4.17.21", "strnum": "1.0.5" @@ -2824,9 +2824,9 @@ } }, "node_modules/@maxgraph/core": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.0.tgz", - "integrity": "sha512-odxP8pniRZpdxFJW8/HAy8aFEXV8xtwK/2fx82DlhapveohJzM348e+y49lMFvD8W1ZfulTISEDAeLFb5/LZ8g==" + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.1.tgz", + "integrity": "sha512-7u2MTO7Kvl2Q96duv4Dr75J63oobWiA1hx8ZEBl3e8GBIKs/sIc3KsV24W4llzXkF/G7kkbdmVVhe43e5xeEQg==" }, "node_modules/@microsoft/api-extractor": { "version": "7.35.2", @@ -14586,9 +14586,9 @@ } }, "@maxgraph/core": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.0.tgz", - "integrity": "sha512-odxP8pniRZpdxFJW8/HAy8aFEXV8xtwK/2fx82DlhapveohJzM348e+y49lMFvD8W1ZfulTISEDAeLFb5/LZ8g==" + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.1.tgz", + "integrity": "sha512-7u2MTO7Kvl2Q96duv4Dr75J63oobWiA1hx8ZEBl3e8GBIKs/sIc3KsV24W4llzXkF/G7kkbdmVVhe43e5xeEQg==" }, "@microsoft/api-extractor": { "version": "7.35.2", From 22862416690c337efc469add1930e587413d2574 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:26:26 +0200 Subject: [PATCH 22/90] vite: reduce the chunk limit to match maxGraph chunk size --- vite.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vite.config.js b/vite.config.js index f4c9a74b99..9a46706dc1 100644 --- a/vite.config.js +++ b/vite.config.js @@ -49,7 +49,7 @@ export default defineConfig(({ mode }) => { }, }, }, - chunkSizeWarningLimit: 555, // maxGraph + chunkSizeWarningLimit: 466, // maxGraph }, preview: { port: 10002, From a6b3f2abd7e2c99399918856082f308b7124f56c Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:15:12 +0200 Subject: [PATCH 23/90] EXTRA (todo on master) e2e: start fixing path to received file in fit tests --- test/e2e/diagram.navigation.fit.test.ts | 3 +++ test/e2e/diagram.navigation.zoom.pan.test.ts | 9 +++++++++ test/e2e/overlays.rendering.test.ts | 2 ++ 3 files changed, 14 insertions(+) diff --git a/test/e2e/diagram.navigation.fit.test.ts b/test/e2e/diagram.navigation.fit.test.ts index 403a76aa19..7b59a5853d 100644 --- a/test/e2e/diagram.navigation.fit.test.ts +++ b/test/e2e/diagram.navigation.fit.test.ts @@ -32,8 +32,11 @@ class FitImageSnapshotConfigurator extends ImageSnapshotConfigurator { margin?: number; }): MatchImageSnapshotOptions { const config = super.getConfig(param); + // TODO migration maxgraph 0.10.1 - to fix in the master branch - we may make a copy of the original configuration config.customSnapshotsDir = FitImageSnapshotConfigurator.buildSnapshotFitDir(config.customSnapshotsDir, param.fitType, true, param.margin ? param.margin : 0); config.customDiffDir = param.buildCustomDiffDir(config, param.fitType, param.margin); + // TODO migration maxgraph 0.10.1 - to fix in the master branch + config.customReceivedDir = config.customDiffDir; return config; } diff --git a/test/e2e/diagram.navigation.zoom.pan.test.ts b/test/e2e/diagram.navigation.zoom.pan.test.ts index 7dd5cf3da5..50ecb1c0fe 100644 --- a/test/e2e/diagram.navigation.zoom.pan.test.ts +++ b/test/e2e/diagram.navigation.zoom.pan.test.ts @@ -208,6 +208,15 @@ describe('diagram navigation - zoom with buttons and mouse', () => { await doZoomWithButton(secondZoom, xTimes); const image = await page.screenshot({ fullPage: true }); + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + // to be done in all function of this file + // create a copy of "config" then set the value + // const config = {...imageSnapshotConfigurator.getConfig(bpmnDiagramName)}; + // config.customSnapshotIdentifier = 'initial.zoom'; + // config.customDiffDir = join(config.customDiffDir, `zoom-mouse-then-button-${firstZoom}-then-${secondZoom}`); + // config.customReceivedDir = config.customDiffDir; + // then pass the config object + const config = imageSnapshotConfigurator.getConfig(bpmnDiagramName); expect(image).toMatchImageSnapshot({ ...config, diff --git a/test/e2e/overlays.rendering.test.ts b/test/e2e/overlays.rendering.test.ts index ee739b2da8..450076a9b4 100644 --- a/test/e2e/overlays.rendering.test.ts +++ b/test/e2e/overlays.rendering.test.ts @@ -190,6 +190,8 @@ describe('BPMN Shapes with overlays', () => { customSnapshotIdentifier: `add.overlay.on.position.${position}`, customSnapshotsDir: getShapeDir(config.customSnapshotsDir), customDiffDir: getShapeDir(config.customDiffDir), + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir (see other test files) + // customReceivedDir: getShapeDir(config.customReceivedDir), }); }); From 7ae90a5e6024e344d3844cbb290805cd2a200518 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 15:35:26 +0200 Subject: [PATCH 24/90] EXTRA (todo on master) e2e: start fixing path to received file in fit tests --- test/config/jest.image.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/config/jest.image.ts b/test/config/jest.image.ts index 4fd3e3fe36..4125c627d9 100644 --- a/test/config/jest.image.ts +++ b/test/config/jest.image.ts @@ -64,6 +64,7 @@ async function saveAndRegisterImages(matcherContext: MatcherContext, received: B // TODO could use async as the function is async copyFileSync(`${options.customSnapshotsDir}/${snapshotIdentifier}.png`, expectedImagePath); // this image is generated by jest-image-snapshot when activating `storeReceivedOnFailure` + // TODO here we should use options.customReceivedDir const receivedImagePath = `${baseImagePathWithName}-received.png`; // Attach the images to jest-html-reports From f340246b6c39e65d25c77991967e8096379ebb3f Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:02:18 +0200 Subject: [PATCH 25/90] EXTRA (todo on master) e2e: start fixing path to received file in fit tests --- test/e2e/diagram.navigation.fit.test.ts | 7 +- test/e2e/diagram.navigation.zoom.pan.test.ts | 62 ++++++++------- .../e2e/helpers/visu/image-snapshot-config.ts | 3 + test/e2e/overlays.rendering.test.ts | 78 +++++++++++-------- 4 files changed, 85 insertions(+), 65 deletions(-) diff --git a/test/e2e/diagram.navigation.fit.test.ts b/test/e2e/diagram.navigation.fit.test.ts index 7b59a5853d..0a1798f636 100644 --- a/test/e2e/diagram.navigation.fit.test.ts +++ b/test/e2e/diagram.navigation.fit.test.ts @@ -22,6 +22,7 @@ import { FitType } from '@lib/component/options'; import { getBpmnDiagramNames } from '@test/shared/visu/test-utils'; import { AvailableTestPages, PageTester } from '@test/shared/visu/bpmn-page-utils'; import type { ImageSnapshotThresholdConfig } from './helpers/visu/image-snapshot-config'; +import { withCustomReceivedDir } from './helpers/visu/image-snapshot-config'; import { ImageSnapshotConfigurator, MultiBrowserImageSnapshotThresholds } from './helpers/visu/image-snapshot-config'; class FitImageSnapshotConfigurator extends ImageSnapshotConfigurator { @@ -32,12 +33,10 @@ class FitImageSnapshotConfigurator extends ImageSnapshotConfigurator { margin?: number; }): MatchImageSnapshotOptions { const config = super.getConfig(param); - // TODO migration maxgraph 0.10.1 - to fix in the master branch - we may make a copy of the original configuration config.customSnapshotsDir = FitImageSnapshotConfigurator.buildSnapshotFitDir(config.customSnapshotsDir, param.fitType, true, param.margin ? param.margin : 0); config.customDiffDir = param.buildCustomDiffDir(config, param.fitType, param.margin); - // TODO migration maxgraph 0.10.1 - to fix in the master branch - config.customReceivedDir = config.customDiffDir; - return config; + // TODO migration maxgraph 0.10.1 - to fix in the master branch - we may make a copy of the original configuration + return withCustomReceivedDir(config); } private static buildSnapshotFitDir(parentDir: string, fitType: FitType, withMargin = false, margin?: number): string { diff --git a/test/e2e/diagram.navigation.zoom.pan.test.ts b/test/e2e/diagram.navigation.zoom.pan.test.ts index 50ecb1c0fe..83d6ef789a 100644 --- a/test/e2e/diagram.navigation.zoom.pan.test.ts +++ b/test/e2e/diagram.navigation.zoom.pan.test.ts @@ -21,6 +21,7 @@ import type { Page } from 'playwright'; import type { Point } from '@test/shared/visu/bpmn-page-utils'; import { AvailableTestPages, PageTester } from '@test/shared/visu/bpmn-page-utils'; import type { ImageSnapshotThresholdConfig } from './helpers/visu/image-snapshot-config'; +import { withCustomReceivedDir } from './helpers/visu/image-snapshot-config'; import { ImageSnapshotConfigurator, MultiBrowserImageSnapshotThresholds } from './helpers/visu/image-snapshot-config'; import { ZoomType } from '@lib/component/options'; @@ -106,11 +107,14 @@ describe('diagram navigation - zoom and pan with mouse', () => { const image = await page.screenshot({ fullPage: true }); const config = imageSnapshotConfigurator.getConfig(bpmnDiagramName); - expect(image).toMatchImageSnapshot({ - ...config, - customSnapshotIdentifier: 'initial.zoom', - customDiffDir: join(config.customDiffDir, `mouse-zoom-in-out-${xTimes}-times`), - }); + expect(image).toMatchImageSnapshot( + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + withCustomReceivedDir({ + ...config, + customSnapshotIdentifier: 'initial.zoom', + customDiffDir: join(config.customDiffDir, `mouse-zoom-in-out-${xTimes}-times`), + }), + ); }); }); @@ -150,11 +154,14 @@ describe('diagram navigation - zoom with buttons', () => { const image = await page.screenshot({ fullPage: true }); const config = imageSnapshotConfigurator.getConfig(bpmnDiagramName); - expect(image).toMatchImageSnapshot({ - ...config, - customSnapshotIdentifier: 'initial.zoom', - customDiffDir: join(config.customDiffDir, `button-zoom-in-out-${xTimes}-times`), - }); + expect(image).toMatchImageSnapshot( + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + withCustomReceivedDir({ + ...config, + customSnapshotIdentifier: 'initial.zoom', + customDiffDir: join(config.customDiffDir, `button-zoom-in-out-${xTimes}-times`), + }), + ); }); }); @@ -192,11 +199,14 @@ describe('diagram navigation - zoom with buttons and mouse', () => { const image = await page.screenshot({ fullPage: true }); const config = imageSnapshotConfigurator.getConfig(bpmnDiagramName); - expect(image).toMatchImageSnapshot({ - ...config, - customSnapshotIdentifier: 'initial.zoom', - customDiffDir: join(config.customDiffDir, `zoom-button-then-mouse-${firstZoom}-then-${secondZoom}`), - }); + expect(image).toMatchImageSnapshot( + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + withCustomReceivedDir({ + ...config, + customSnapshotIdentifier: 'initial.zoom', + customDiffDir: join(config.customDiffDir, `zoom-button-then-mouse-${firstZoom}-then-${secondZoom}`), + }), + ); }); it.each` @@ -208,20 +218,14 @@ describe('diagram navigation - zoom with buttons and mouse', () => { await doZoomWithButton(secondZoom, xTimes); const image = await page.screenshot({ fullPage: true }); - // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir - // to be done in all function of this file - // create a copy of "config" then set the value - // const config = {...imageSnapshotConfigurator.getConfig(bpmnDiagramName)}; - // config.customSnapshotIdentifier = 'initial.zoom'; - // config.customDiffDir = join(config.customDiffDir, `zoom-mouse-then-button-${firstZoom}-then-${secondZoom}`); - // config.customReceivedDir = config.customDiffDir; - // then pass the config object - const config = imageSnapshotConfigurator.getConfig(bpmnDiagramName); - expect(image).toMatchImageSnapshot({ - ...config, - customSnapshotIdentifier: 'initial.zoom', - customDiffDir: join(config.customDiffDir, `zoom-mouse-then-button-${firstZoom}-then-${secondZoom}`), - }); + expect(image).toMatchImageSnapshot( + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + withCustomReceivedDir({ + ...config, + customSnapshotIdentifier: 'initial.zoom', + customDiffDir: join(config.customDiffDir, `zoom-mouse-then-button-${firstZoom}-then-${secondZoom}`), + }), + ); }); }); diff --git a/test/e2e/helpers/visu/image-snapshot-config.ts b/test/e2e/helpers/visu/image-snapshot-config.ts index df999ab76a..452c857dc4 100644 --- a/test/e2e/helpers/visu/image-snapshot-config.ts +++ b/test/e2e/helpers/visu/image-snapshot-config.ts @@ -156,3 +156,6 @@ export class MultiBrowserImageSnapshotThresholds { } } } + +// TODO migration maxgraph 0.10.1 - to fix in the master branch - we may make a copy of the original configuration +export const withCustomReceivedDir = (options: MatchImageSnapshotOptions): MatchImageSnapshotOptions => ({ ...options, customReceivedDir: options.customDiffDir }); diff --git a/test/e2e/overlays.rendering.test.ts b/test/e2e/overlays.rendering.test.ts index 450076a9b4..0b029328a7 100644 --- a/test/e2e/overlays.rendering.test.ts +++ b/test/e2e/overlays.rendering.test.ts @@ -24,6 +24,7 @@ import { overlayEdgePositionValues, overlayShapePositionValues } from '@test/sha import type { Point } from '@test/shared/visu/bpmn-page-utils'; import { AvailableTestPages, PageTester } from '@test/shared/visu/bpmn-page-utils'; import type { ImageSnapshotThresholdConfig } from './helpers/visu/image-snapshot-config'; +import { withCustomReceivedDir } from './helpers/visu/image-snapshot-config'; import { ImageSnapshotConfigurator, MultiBrowserImageSnapshotThresholds } from './helpers/visu/image-snapshot-config'; import debugLogger from 'debug'; @@ -185,14 +186,15 @@ describe('BPMN Shapes with overlays', () => { const image = await page.screenshot({ fullPage: true }); const config = imageSnapshotConfigurator.getConfig(bpmnDiagramName); - expect(image).toMatchImageSnapshot({ - ...config, - customSnapshotIdentifier: `add.overlay.on.position.${position}`, - customSnapshotsDir: getShapeDir(config.customSnapshotsDir), - customDiffDir: getShapeDir(config.customDiffDir), - // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir (see other test files) - // customReceivedDir: getShapeDir(config.customReceivedDir), - }); + expect(image).toMatchImageSnapshot( + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + withCustomReceivedDir({ + ...config, + customSnapshotIdentifier: `add.overlay.on.position.${position}`, + customSnapshotsDir: getShapeDir(config.customSnapshotsDir), + customDiffDir: getShapeDir(config.customDiffDir), + }), + ); }); it(`remove all overlays of Shape`, async () => { @@ -203,12 +205,15 @@ describe('BPMN Shapes with overlays', () => { const image = await page.screenshot({ fullPage: true }); const config = imageSnapshotConfigurator.getConfig(bpmnDiagramName); - expect(image).toMatchImageSnapshot({ - ...config, - customSnapshotIdentifier: 'remove.all.overlays.of.shape', - customSnapshotsDir: getShapeDir(config.customSnapshotsDir), - customDiffDir: getShapeDir(config.customDiffDir), - }); + expect(image).toMatchImageSnapshot( + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + withCustomReceivedDir({ + ...config, + customSnapshotIdentifier: 'remove.all.overlays.of.shape', + customSnapshotsDir: getShapeDir(config.customSnapshotsDir), + customDiffDir: getShapeDir(config.customDiffDir), + }), + ); }); }); @@ -250,12 +255,15 @@ describe('BPMN Edges with overlays', () => { const image = await page.screenshot({ fullPage: true }); const config = imageSnapshotConfigurator.getConfig(bpmnDiagramName); - expect(image).toMatchImageSnapshot({ - ...config, - customSnapshotIdentifier: `add.overlay.on.${edgeKind}.flow`, - customSnapshotsDir: getEdgePositionDir(config.customSnapshotsDir, position), - customDiffDir: getEdgePositionDir(config.customDiffDir, position), - }); + expect(image).toMatchImageSnapshot( + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + withCustomReceivedDir({ + ...config, + customSnapshotIdentifier: `add.overlay.on.${edgeKind}.flow`, + customSnapshotsDir: getEdgePositionDir(config.customSnapshotsDir, position), + customDiffDir: getEdgePositionDir(config.customDiffDir, position), + }), + ); }); it(`remove all overlays of ${edgeKind} flow`, async () => { @@ -267,12 +275,15 @@ describe('BPMN Edges with overlays', () => { const image = await page.screenshot({ fullPage: true }); const config = imageSnapshotConfigurator.getConfig(bpmnDiagramName); - expect(image).toMatchImageSnapshot({ - ...config, - customSnapshotIdentifier: `remove.all.overlays.of.${edgeKind}.flow`, - customSnapshotsDir: getEdgeDir(config.customSnapshotsDir), - customDiffDir: getEdgeDir(config.customDiffDir), - }); + expect(image).toMatchImageSnapshot( + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + withCustomReceivedDir({ + ...config, + customSnapshotIdentifier: `remove.all.overlays.of.${edgeKind}.flow`, + customSnapshotsDir: getEdgeDir(config.customSnapshotsDir), + customDiffDir: getEdgeDir(config.customDiffDir), + }), + ); }); }); }); @@ -476,11 +487,14 @@ describe('Overlay style', () => { const image = await page.screenshot({ fullPage: true }); const config = imageSnapshotConfigurator.getConfig(style); - expect(image).toMatchImageSnapshot({ - ...config, - customSnapshotIdentifier: `add.overlay.with.custom.${style}`, - customSnapshotsDir: join(config.customSnapshotsDir, snapshotPath), - customDiffDir: join(config.customDiffDir, snapshotPath), - }); + expect(image).toMatchImageSnapshot( + // TODO migration maxgraph 0.10.1 - to fix in the master branch - set customReceivedDir + withCustomReceivedDir({ + ...config, + customSnapshotIdentifier: `add.overlay.with.custom.${style}`, + customSnapshotsDir: join(config.customSnapshotsDir, snapshotPath), + customDiffDir: join(config.customDiffDir, snapshotPath), + }), + ); }); }); From 6f2f0578080368eac2bfbcc10f5e48c9d4314846 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:19:23 +0200 Subject: [PATCH 26/90] EXTRA (todo on master) e2e: start fixing path to received file in fit tests --- test/e2e/helpers/visu/image-snapshot-config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/e2e/helpers/visu/image-snapshot-config.ts b/test/e2e/helpers/visu/image-snapshot-config.ts index 452c857dc4..d1c890fe5c 100644 --- a/test/e2e/helpers/visu/image-snapshot-config.ts +++ b/test/e2e/helpers/visu/image-snapshot-config.ts @@ -59,6 +59,7 @@ export class ImageSnapshotConfigurator { customSnapshotIdentifier: fileName, customSnapshotsDir: this.defaultCustomSnapshotsDir, customDiffDir: this.defaultCustomDiffDir, + // TODO migration maxgraph 0.10.1 - to fix in the master branch - we may remove this line and enforce the use of withCustomReceivedDir everywhere customReceivedDir: this.defaultCustomDiffDir, }; } @@ -158,4 +159,5 @@ export class MultiBrowserImageSnapshotThresholds { } // TODO migration maxgraph 0.10.1 - to fix in the master branch - we may make a copy of the original configuration +// TODO find a better name: consolidate configuration? export const withCustomReceivedDir = (options: MatchImageSnapshotOptions): MatchImageSnapshotOptions => ({ ...options, customReceivedDir: options.customDiffDir }); From 2c5726dac20f8862d1e8ccaac2a2285cc0c47f93 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:07:57 +0200 Subject: [PATCH 27/90] EXTRA (todo on master) e2e: start fixing path to received file in fit tests (add todo) --- test/config/jest.image.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/config/jest.image.ts b/test/config/jest.image.ts index 4125c627d9..99f0af3bb9 100644 --- a/test/config/jest.image.ts +++ b/test/config/jest.image.ts @@ -62,6 +62,7 @@ async function saveAndRegisterImages(matcherContext: MatcherContext, received: B const baseImagePathWithName = `${options.customDiffDir}/${snapshotIdentifier}`; const expectedImagePath = `${baseImagePathWithName}-expected.png`; // TODO could use async as the function is async + // TODO move this copy to the toMatchImageSnapshotCustom function (the image processing is done their, here we should only attach the images to the report) copyFileSync(`${options.customSnapshotsDir}/${snapshotIdentifier}.png`, expectedImagePath); // this image is generated by jest-image-snapshot when activating `storeReceivedOnFailure` // TODO here we should use options.customReceivedDir From d208c483e95f91614b7d080da81cbdf431832ab2 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:13:48 +0200 Subject: [PATCH 28/90] StyleConfigurator.ts: manage todo from maxgraph 0.1.0 --- .../mxgraph/config/StyleConfigurator.ts | 62 +++++++------------ 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 3c416d24ad..5dd1464704 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -19,7 +19,7 @@ import { BpmnStyleIdentifier, MarkerIdentifier, StyleDefault } from '../style'; import type { BpmnGraph } from '../BpmnGraph'; import type { BPMNCellStyle } from '../renderer/StyleComputer'; import { constants, Perimeter } from '@maxgraph/core'; -import type { ShapeValue, Stylesheet } from '@maxgraph/core'; +import type { Stylesheet } from '@maxgraph/core'; const arrowDefaultSize = 12; @@ -137,21 +137,17 @@ export class StyleConfigurator { configureCommonDefaultStyle(style); style.absoluteArcSize = true; - // TODO maxgraph@0.1.0 find a way to not force cast - style.arcSize = StyleDefault.SHAPE_ARC_SIZE; + style.arcSize = StyleDefault.SHAPE_ARC_SIZE; } private configurePoolStyle(): void { const style: BPMNCellStyle = { - // TODO maxgraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE - shape: 'swimlane', + shape: constants.SHAPE.SWIMLANE, // label style verticalAlign: 'middle', align: 'center', - // TODO maxgraph@0.1.0 find a way to not force cast - startSize: StyleDefault.POOL_LABEL_SIZE, - // TODO maxgraph@0.1.0 find a way to not force cast - fillColor: StyleDefault.POOL_LABEL_FILL_COLOR, + startSize: StyleDefault.POOL_LABEL_SIZE, + fillColor: StyleDefault.POOL_LABEL_FILL_COLOR, }; this.graph.getStylesheet().putCellStyle(ShapeBpmnElementKind.POOL, style); @@ -159,16 +155,13 @@ export class StyleConfigurator { private configureLaneStyle(): void { const style: BPMNCellStyle = { - // TODO maxgraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.SHAPE.SWIMLANE - shape: 'swimlane', + shape: constants.SHAPE.SWIMLANE, // label style verticalAlign: 'middle', align: 'center', swimlaneLine: false, // hide the line between the title region and the content area - // TODO maxgraph@0.1.0 find a way to not force cast - startSize: StyleDefault.LANE_LABEL_SIZE, - // TODO maxgraph@0.1.0 find a way to not force cast - fillColor: StyleDefault.LANE_LABEL_FILL_COLOR, + startSize: StyleDefault.LANE_LABEL_SIZE, + fillColor: StyleDefault.LANE_LABEL_FILL_COLOR, }; this.graph.getStylesheet().putCellStyle(ShapeBpmnElementKind.LANE, style); @@ -177,11 +170,10 @@ export class StyleConfigurator { private configureEventStyles(): void { ShapeUtil.eventKinds().forEach(kind => { const style: BPMNCellStyle = { - // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types - shape: (kind), + shape: kind, + // TODO maxgraph@0.10.1 decide if we use the function or the string to set the perimeter perimeter: Perimeter.EllipsePerimeter, - // TODO maxgraph@0.1.0 find a way to not force cast - strokeWidth: (kind == ShapeBpmnElementKind.EVENT_END ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN), + strokeWidth: kind == ShapeBpmnElementKind.EVENT_END ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN, verticalLabelPosition: 'bottom', }; this.putCellStyle(kind, style); @@ -190,16 +182,13 @@ export class StyleConfigurator { private configureTextAnnotationStyle(): void { const style: BPMNCellStyle = { - // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types - shape: (ShapeBpmnElementKind.TEXT_ANNOTATION), + shape: ShapeBpmnElementKind.TEXT_ANNOTATION, // label style verticalAlign: 'middle', align: 'left', spacingLeft: 5, - // TODO maxgraph@0.1.0 find a way to not force cast - fillColor: StyleDefault.TEXT_ANNOTATION_FILL_COLOR, - // TODO maxgraph@0.1.0 find a way to not force cast - strokeWidth: StyleDefault.STROKE_WIDTH_THIN, + fillColor: StyleDefault.TEXT_ANNOTATION_FILL_COLOR, + strokeWidth: StyleDefault.STROKE_WIDTH_THIN, }; this.putCellStyle(ShapeBpmnElementKind.TEXT_ANNOTATION, style); } @@ -209,10 +198,8 @@ export class StyleConfigurator { rounded: true, dashed: true, dashPattern: '7 4 1 4', - // TODO maxgraph@0.1.0 find a way to not force cast - strokeWidth: StyleDefault.STROKE_WIDTH_THIN, - // TODO maxgraph@0.1.0 find a way to not force cast - fillColor: StyleDefault.GROUP_FILL_COLOR, + strokeWidth: StyleDefault.STROKE_WIDTH_THIN, + fillColor: StyleDefault.GROUP_FILL_COLOR, // Default label positioning align: 'center', verticalAlign: 'top', @@ -223,12 +210,10 @@ export class StyleConfigurator { private configureActivityStyles(): void { ShapeUtil.activityKinds().forEach(kind => { const style: BPMNCellStyle = { - // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types - shape: (kind), + shape: kind, rounded: true, // required by the BPMN specification verticalAlign: 'middle', // label style - // TODO maxgraph@0.1.0 find a way to not force cast - strokeWidth: (kind == ShapeBpmnElementKind.CALL_ACTIVITY ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN), + strokeWidth: kind == ShapeBpmnElementKind.CALL_ACTIVITY ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN, }; this.putCellStyle(kind, style); }); @@ -237,12 +222,11 @@ export class StyleConfigurator { private configureGatewayStyles(): void { ShapeUtil.gatewayKinds().forEach(kind => { const style: BPMNCellStyle = { - // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types - shape: (kind), + shape: kind, + // TODO maxgraph@0.10.1 decide if we use the function or the string to set the perimeter perimeter: Perimeter.RhombusPerimeter, verticalAlign: 'top', - // TODO maxgraph@0.1.0 find a way to not force cast - strokeWidth: StyleDefault.STROKE_WIDTH_THIN, + strokeWidth: StyleDefault.STROKE_WIDTH_THIN, // Default label positioning labelPosition: 'left', @@ -256,11 +240,11 @@ export class StyleConfigurator { const style = this.getStylesheet().getDefaultEdgeStyle() as BPMNCellStyle; configureCommonDefaultStyle(style); - // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types - style.shape = BpmnStyleIdentifier.EDGE; + style.shape = BpmnStyleIdentifier.EDGE; style.endSize = arrowDefaultSize; style.strokeWidth = 1.5; style.rounded = true; + // TODO maxgraph@0.10.1 the rendered edge arcSize seems larger than with mxGraph (also seen with maxgrpah 0.1.0) style.arcSize = 5; style.verticalAlign = 'bottom'; // The end arrow must be redefined in specific style From 21f6694e0b48d66712ef60d75430085848d67ece Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:21:12 +0200 Subject: [PATCH 29/90] StyleManager update TODO --- src/component/mxgraph/style/StyleManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/style/StyleManager.ts b/src/component/mxgraph/style/StyleManager.ts index ceeaf231b7..c41136e2ed 100644 --- a/src/component/mxgraph/style/StyleManager.ts +++ b/src/component/mxgraph/style/StyleManager.ts @@ -29,7 +29,7 @@ export class StyleManager { resetAllStyles(): void { for (const cellId of this.stylesCache.keys()) { - // TODO inline in master branch + // TODO maxGraph 0.1.0 - inline in master branch const style = this.stylesCache.get(cellId); this.resetStyle(cellId, style); } From 82ce01195e70d52c751a2675b2511d5ddbb49d1f Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:36:15 +0200 Subject: [PATCH 30/90] Manage some TODO maxgraph 0.1.0 in StyleComputer.test.ts --- .../mxgraph/renderer/StyleComputer.ts | 8 +------- .../mxgraph/renderer/StyleComputer.test.ts | 20 +++++++------------ 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index b90cb21e99..8d2376e1e6 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -212,14 +212,8 @@ export default class StyleComputer { if (bpmnCell instanceof Shape) { // arbitrarily increase width to relax too small bounds (for instance for reference diagrams from miwg-test-suite) style.labelWidth = labelBounds.width + 1; - // align settings - // According to the documentation, "label position" can only take values in left, center, right with default=center - // However, there is undocumented behavior when the value is not one of these and this behavior is exactly what we want. - // See https://github.com/jgraph/mxgraph/blob/v4.2.2/javascript/src/js/view/mxGraphView.js#L1183-L1252 - // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) - style.labelPosition = 'ignore'; + style.labelPosition = 'ignore'; style.verticalLabelPosition = 'middle'; - // end of fixme } } // when no label bounds, adjust the default style dynamically diff --git a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts index f19add0983..aafdc1df35 100644 --- a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts +++ b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts @@ -17,7 +17,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { AlignValue, ShapeValue } from '@maxgraph/core'; +import type { ShapeValue } from '@maxgraph/core'; import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; import StyleComputer from '@lib/component/mxgraph/renderer/StyleComputer'; import Shape from '@lib/model/bpmn/internal/shape/Shape'; @@ -201,8 +201,7 @@ describe('Style Computer', () => { align: 'center', verticalAlign: 'top', labelWidth: 81, - // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) - labelPosition: 'ignore', + labelPosition: 'ignore', verticalLabelPosition: 'middle', bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY }, }); @@ -415,8 +414,7 @@ describe('Style Computer', () => { fontFamily: 'sans-serif', labelWidth: 301, verticalAlign: 'top', - // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) - labelPosition: 'ignore', + labelPosition: 'ignore', verticalLabelPosition: 'middle', }); }); @@ -458,8 +456,7 @@ describe('Style Computer', () => { fontFamily: 'sans-serif', labelWidth: 301, verticalAlign: 'top', - // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) - labelPosition: 'ignore', + labelPosition: 'ignore', verticalLabelPosition: 'middle', }); }); @@ -497,8 +494,7 @@ describe('Style Computer', () => { fontFamily: 'sans-serif', labelWidth: 301, verticalAlign: 'top', - // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) - labelPosition: 'ignore', + labelPosition: 'ignore', verticalLabelPosition: 'middle', }); }); @@ -538,8 +534,7 @@ describe('Style Computer', () => { fontFamily: 'Segoe UI', labelWidth: 101, verticalAlign: 'top', - // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) - labelPosition: 'ignore', + labelPosition: 'ignore', verticalLabelPosition: 'middle', }); }); @@ -562,8 +557,7 @@ describe('Style Computer', () => { kind: ShapeBpmnElementKind.GROUP, }, fontFamily: 'Roboto', - // TODO maxgraph@0.1.0 remove forcing type when bumping maxGraph (fixed in version 0.2.1) - labelPosition: 'ignore', + labelPosition: 'ignore', labelWidth: 101, verticalAlign: 'top', verticalLabelPosition: 'middle', From 8024887c4d315ceeaaa42205427f77d75bb19738 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:40:28 +0200 Subject: [PATCH 31/90] Manage some TODO maxgraph 0.1.0 in StyleComputer.test.ts --- .../component/mxgraph/renderer/StyleComputer.test.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts index aafdc1df35..9f82cea977 100644 --- a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts +++ b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts @@ -17,7 +17,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { ShapeValue } from '@maxgraph/core'; import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; import StyleComputer from '@lib/component/mxgraph/renderer/StyleComputer'; import Shape from '@lib/model/bpmn/internal/shape/Shape'; @@ -302,8 +301,8 @@ describe('Style Computer', () => { const edge = new Edge('id', newMessageFlow(), undefined, undefined, messageVisibleKind); expect(styleComputer.computeMessageFlowIconStyle(edge)).toStrictEqual({ bpmn: { isInitiating: expected }, - // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types - shape: 'bpmn.messageFlowIcon', + // TODO maxGraph@0.10.1 decide if we use BpmnStyleIdentifier const instead + shape: 'bpmn.messageFlowIcon', }); }); @@ -778,8 +777,8 @@ describe('Style Computer', () => { edge.extensions.strokeColor = '#11aabb'; const expectedStyle = { bpmn: { isInitiating: false }, - // TODO maxGraph@0.1.0 force conversion to ShapeValue + decide if we use BpmnStyleIdentifier const instead - shape: 'bpmn.messageFlowIcon', + // TODO maxGraph@0.10.1 decide if we use BpmnStyleIdentifier const instead + shape: 'bpmn.messageFlowIcon', }; if (expectAdditionalColorsStyle) { expectedStyle.strokeColor = '#11aabb'; From a6fc85b106bca2acd7ca719f764613688e3ce308 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:56:03 +0200 Subject: [PATCH 32/90] Fix typo in TODO of StyleConfigurator.ts --- src/component/mxgraph/config/StyleConfigurator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 5dd1464704..97c56f3abd 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -244,7 +244,7 @@ export class StyleConfigurator { style.endSize = arrowDefaultSize; style.strokeWidth = 1.5; style.rounded = true; - // TODO maxgraph@0.10.1 the rendered edge arcSize seems larger than with mxGraph (also seen with maxgrpah 0.1.0) + // TODO maxgraph@0.10.1 the rendered edge arcSize seems larger than with mxGraph (also seen with maxgraph 0.1.0) style.arcSize = 5; style.verticalAlign = 'bottom'; // The end arrow must be redefined in specific style From 221aac3e699bb8d4e704616af23db316d0509dbb Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:58:04 +0200 Subject: [PATCH 33/90] StyleComputer.ts BPMNCellStyle remove arrow fill properties available out of the box in maxGraph --- src/component/mxgraph/renderer/StyleComputer.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index 8d2376e1e6..7a7c4d90dc 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { AlignValue, CellStyle, ShapeValue } from '@maxgraph/core'; +import type { CellStyle, ShapeValue } from '@maxgraph/core'; import Shape from '../../../model/bpmn/internal/shape/Shape'; import type { Edge } from '../../../model/bpmn/internal/edge/edge'; @@ -49,13 +49,6 @@ import type { RendererOptions } from '../../options'; // TODO maxgraph@0.1.0 rename for consistent naming BPMNCellStyle --> BpmnCellStyle (apply to other places) // a BpmnCellStyle exists in tests. Try to use this one instead export interface BPMNCellStyle extends CellStyle { - // TODO maxgraph@0.1.0 fill markers properties to remove when https://github.com/maxGraph/maxGraph/issues/201 is available - endFillColor?: string; - // TODO maxgraph@0.1.0 fill markers properties to remove when https://github.com/maxGraph/maxGraph/issues/201 is available - startFillColor?: string; - // TODO maxgraph@0.1.0 the shape property is defined as 'ShapeValue'. It should be 'ShapeValue | string' - // Omit { - // shape?: ShapeValue | string; // TODO maxgraph@0.1.0 make bpmn mandatory? bpmn?: { // TODO maxgraph@0.1.0 sort properties in alphabetical order for clarity (and as done in maxGraph CellStyle) and provide documentation about each property From bcd1f7e75e6d6c0c1849fe70d2aeab862227cfda Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:40:23 +0200 Subject: [PATCH 34/90] Add TODO --- src/component/mxgraph/style/identifiers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/component/mxgraph/style/identifiers.ts b/src/component/mxgraph/style/identifiers.ts index 5f6e975b64..323f0d447e 100644 --- a/src/component/mxgraph/style/identifiers.ts +++ b/src/component/mxgraph/style/identifiers.ts @@ -27,6 +27,7 @@ export const BpmnStyleIdentifier = { // edge EDGE: 'bpmn.edge', + // TODO maxGraph@0.10.1 - real migration - renamed into SHAPE_MESSAGE_FLOW_ICON? // other identifiers MESSAGE_FLOW_ICON: 'bpmn.messageFlowIcon', }; From 3ea1a7ed73c7e673922c41ed8715ee3a284686c2 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:43:11 +0200 Subject: [PATCH 35/90] fix TODO --- src/component/mxgraph/BpmnGraph.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index 0af4c72ade..c0e1e1e62a 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -132,17 +132,12 @@ export class BpmnGraph extends Graph { scale == 0 && (scale = 1); this.view.scaleAndTranslate( scale, - this.NaNToZero((margin + clientWidth - width * scale) / (2 * scale) - bounds.x / this.view.scale), - this.NaNToZero((margin + clientHeight - height * scale) / (2 * scale) - bounds.y / this.view.scale), + convertNaNToZero((margin + clientWidth - width * scale) / (2 * scale) - bounds.x / this.view.scale), + convertNaNToZero((margin + clientHeight - height * scale) / (2 * scale) - bounds.y / this.view.scale), ); } } - // TODO maxgraph@0.1.0 move somewhere else + find a better name + should be a util function - private NaNToZero(value: number): number { - return Number.isNaN(value) ? 0 : value; - } - /** * @internal */ @@ -268,3 +263,7 @@ class BpmnStylesheet extends Stylesheet { return style; } } + +function convertNaNToZero(value: number): number { + return Number.isNaN(value) ? 0 : value; +} From 827f436eb02cfa3f3e4a00d67e069eed13e1d3d5 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:46:10 +0200 Subject: [PATCH 36/90] update TODO in BpmnGraph.ts --- src/component/mxgraph/BpmnGraph.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index c0e1e1e62a..679cd9bf7b 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -209,6 +209,7 @@ export class BpmnGraph extends Graph { } // TODO maxgraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) + // with maxgraph@0.10.1, using the maxGraph implementation impact the results of the integration tests (markers) override createStylesheet(): Stylesheet { return new BpmnStylesheet(); } From f91d847b2eabd99cae951272a653228a5e00db37 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:47:33 +0200 Subject: [PATCH 37/90] update TODO in BpmnRenderer.ts --- src/component/mxgraph/BpmnRenderer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/component/mxgraph/BpmnRenderer.ts b/src/component/mxgraph/BpmnRenderer.ts index 50cb54fa34..343dba8da4 100644 --- a/src/component/mxgraph/BpmnRenderer.ts +++ b/src/component/mxgraph/BpmnRenderer.ts @@ -83,6 +83,7 @@ export class BpmnRenderer { const target = this.getCell(bpmnElement.targetRefId); const labelBounds = edge.label?.bounds; const style = this.styleComputer.computeStyle(edge, labelBounds); + // TODO maxGraph@0.10.1 use insertEdge with single parameter const mxEdge = this.graph.insertEdge(parent, bpmnElement.id, bpmnElement.name, source, target, style); this.insertWaypoints(edge.waypoints, mxEdge); @@ -125,7 +126,7 @@ export class BpmnRenderer { private insertVertex(parent: Cell, id: string | null, value: string, bounds: Bounds, labelBounds: Bounds, style?: BPMNCellStyle): Cell { const vertexCoordinates = this.coordinatesTranslator.computeRelativeCoordinates(parent, new Point(bounds.x, bounds.y)); - // TODO maxGraph@0.1.0 check insertVertex with single parameter + // TODO maxGraph@0.10.1 use insertVertex with single parameter const cell = this.graph.insertVertex(parent, id, value, vertexCoordinates.x, vertexCoordinates.y, bounds.width, bounds.height, style); if (labelBounds) { From b6a14e1b16433e04d6b0daee27302475c6d30632 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:17:06 +0200 Subject: [PATCH 38/90] Use Graph.insertXXX methods with a single parameter --- src/component/mxgraph/BpmnRenderer.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/component/mxgraph/BpmnRenderer.ts b/src/component/mxgraph/BpmnRenderer.ts index 343dba8da4..18d2d2c6ae 100644 --- a/src/component/mxgraph/BpmnRenderer.ts +++ b/src/component/mxgraph/BpmnRenderer.ts @@ -83,8 +83,7 @@ export class BpmnRenderer { const target = this.getCell(bpmnElement.targetRefId); const labelBounds = edge.label?.bounds; const style = this.styleComputer.computeStyle(edge, labelBounds); - // TODO maxGraph@0.10.1 use insertEdge with single parameter - const mxEdge = this.graph.insertEdge(parent, bpmnElement.id, bpmnElement.name, source, target, style); + const mxEdge = this.graph.insertEdge({ parent, id: bpmnElement.id, value: bpmnElement.name, source, target, style }); this.insertWaypoints(edge.waypoints, mxEdge); if (labelBounds) { @@ -126,8 +125,7 @@ export class BpmnRenderer { private insertVertex(parent: Cell, id: string | null, value: string, bounds: Bounds, labelBounds: Bounds, style?: BPMNCellStyle): Cell { const vertexCoordinates = this.coordinatesTranslator.computeRelativeCoordinates(parent, new Point(bounds.x, bounds.y)); - // TODO maxGraph@0.10.1 use insertVertex with single parameter - const cell = this.graph.insertVertex(parent, id, value, vertexCoordinates.x, vertexCoordinates.y, bounds.width, bounds.height, style); + const cell = this.graph.insertVertex({ parent, id, value, position: [vertexCoordinates.x, vertexCoordinates.y], width: bounds.width, height: bounds.height, style }); if (labelBounds) { // label coordinates are relative in the cell referential coordinates From 14ab3755bd69af1b5aa53e97198dde098ffa3688 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:24:37 +0200 Subject: [PATCH 39/90] Remove FONT and use the constants.FONT from maxGraph --- .../mxgraph/config/ShapeConfigurator.ts | 9 ++++----- .../mxgraph/renderer/StyleComputer.ts | 10 +++++----- src/component/mxgraph/style/utils.ts | 18 +++++------------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index 5e82ca5116..5d1c7d192f 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -35,7 +35,6 @@ import { import { TextAnnotationShape } from '../shape/text-annotation-shapes'; import { MessageFlowIconShape } from '../shape/flow-shapes'; import { BpmnStyleIdentifier } from '../style'; -import { FONT } from '../style/utils'; import { computeAllBpmnClassNamesOfCell } from '../renderer/style-utils'; import type { BPMNCellStyle } from '../renderer/StyleComputer'; import { MxGraphCustomOverlay } from '../overlay/custom-overlay'; @@ -126,18 +125,18 @@ export default class ShapeConfigurator { // END OF Fix for issue #920 '; '; - if ((s.fontStyle & FONT.BOLD) == FONT.BOLD) { + if ((s.fontStyle & constants.FONT.BOLD) == constants.FONT.BOLD) { css += 'font-weight: bold; '; } - if ((s.fontStyle & FONT.ITALIC) == FONT.ITALIC) { + if ((s.fontStyle & constants.FONT.ITALIC) == constants.FONT.ITALIC) { css += 'font-style: italic; '; } const deco = []; - if ((s.fontStyle & FONT.UNDERLINE) == FONT.UNDERLINE) { + if ((s.fontStyle & constants.FONT.UNDERLINE) == constants.FONT.UNDERLINE) { deco.push('underline'); } - if ((s.fontStyle & FONT.STRIKETHROUGH) == FONT.STRIKETHROUGH) { + if ((s.fontStyle & constants.FONT.STRIKETHROUGH) == constants.FONT.STRIKETHROUGH) { deco.push('line-through'); } if (deco.length > 0) { diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index 7a7c4d90dc..7c906e215a 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -15,6 +15,7 @@ limitations under the License. */ import type { CellStyle, ShapeValue } from '@maxgraph/core'; +import { constants } from '@maxgraph/core'; import Shape from '../../../model/bpmn/internal/shape/Shape'; import type { Edge } from '../../../model/bpmn/internal/edge/edge'; @@ -29,7 +30,6 @@ import { ShapeBpmnSubProcess, } from '../../../model/bpmn/internal/shape/ShapeBpmnElement'; import { BpmnStyleIdentifier } from '../style'; -import { FONT } from '../style/utils'; import type { AssociationDirectionKind, FlowKind, @@ -242,16 +242,16 @@ export default class StyleComputer { export function getFontStyleValue(font: Font): number { let value = 0; if (font.isBold) { - value += FONT.BOLD; + value += constants.FONT.BOLD; } if (font.isItalic) { - value += FONT.ITALIC; + value += constants.FONT.ITALIC; } if (font.isStrikeThrough) { - value += FONT.STRIKETHROUGH; + value += constants.FONT.STRIKETHROUGH; } if (font.isUnderline) { - value += FONT.UNDERLINE; + value += constants.FONT.UNDERLINE; } return value; } diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index c0cfa6eac5..49bddf7782 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -15,6 +15,7 @@ limitations under the License. */ import type { Cell, CellStyle, NumericCellStateStyleKeys } from '@maxgraph/core'; +import { constants } from '@maxgraph/core'; import { cloneUtils, styleUtils } from '@maxgraph/core'; import type { BPMNCellStyle } from '../renderer/StyleComputer'; @@ -70,15 +71,6 @@ export const StyleDefault = { MESSAGE_FLOW_MARKER_END_FILL_COLOR: 'White', }; -// TODO maxgraph@0.1.0 maxGraph "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided." constants.FONT -// to remove when https://github.com/maxGraph/maxGraph/issues/205 is fixed -export enum FONT { - BOLD = 1, - ITALIC = 2, - UNDERLINE = 4, - STRIKETHROUGH = 8, -} - const convertDefaultValue = (value: string): string | undefined => (value == 'default' ? undefined : value); export const updateStroke = (cellStyle: CellStyle, stroke: Stroke): void => { @@ -132,10 +124,10 @@ export const updateFont = (cellStyle: CellStyle, font: Font): void => { setStyle(cellStyle, 'fontSize', font.size); setStyle(cellStyle, 'fontFamily', font.family); - setStyleFlag(cellStyle, 'fontStyle', FONT.BOLD, font.isBold); - setStyleFlag(cellStyle, 'fontStyle', FONT.ITALIC, font.isItalic); - setStyleFlag(cellStyle, 'fontStyle', FONT.UNDERLINE, font.isUnderline); - setStyleFlag(cellStyle, 'fontStyle', FONT.STRIKETHROUGH, font.isStrikeThrough); + setStyleFlag(cellStyle, 'fontStyle', constants.FONT.BOLD, font.isBold); + setStyleFlag(cellStyle, 'fontStyle', constants.FONT.ITALIC, font.isItalic); + setStyleFlag(cellStyle, 'fontStyle', constants.FONT.UNDERLINE, font.isUnderline); + setStyleFlag(cellStyle, 'fontStyle', constants.FONT.STRIKETHROUGH, font.isStrikeThrough); setStyle(cellStyle, 'textOpacity', font.opacity, ensureOpacityValue); } From cacc7f5c6928654dd27ec791e6d4c44f245f425f Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:26:58 +0200 Subject: [PATCH 40/90] setStyleFlag: remove workaround as there is now a fix in maxGraph --- src/component/mxgraph/style/utils.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index 49bddf7782..6a8082cd51 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -108,13 +108,6 @@ export const setStyleFlag = (cellStyle: CellStyle, key: NumericCellStateStyleKey // the mxGraph setStyleFlag function toggle the flag if the value if undefined is passed. In bpmn-visualization, we want to keep the value as it is instead in this case (there is no toggle feature) if (value == undefined) return; - // FIXME maxGraph@0.1.0 - bug in maxGraph setStyleFlag seems to fail when the fontStyle is undefined - // when the property is undefined, setting the flag set the value to 0. So initialize the value when undefined as a workaround. - // to remove when https://github.com/maxGraph/maxGraph/pull/377 is fixed - if (cellStyle[key] == undefined) { - cellStyle[key] = 0; - } - styleUtils.setStyleFlag(cellStyle, key, flag, value); }; From a4e6ffcb1430db1d35a0bfe8e1dcb30e52573222 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:30:50 +0200 Subject: [PATCH 41/90] Manage TODO in utils.ts getCellStyleClone --- src/component/mxgraph/style/utils.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index 6a8082cd51..7e35798fa7 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -154,10 +154,9 @@ export function setCssClasses(cellStyle: BPMNCellStyle, cssClasses: string[]): v } } -// FIXME maxGraph 0.1.0 - in model.setStyle, the processing is done only if the style parameter is not equal to the style of the cell +// In model.setStyle, the processing is done only if the style parameter is not equal to the style of the cell // If the style has been get from the cell, then modified, this is the same instance as in the cell, so the 2 objects are equal, so no processing is done -// in mxGraph, the style was a string, now it is an object. Modifying the returned style didn't modified the string of the style cell, so the 2 objects weren't equal and so processing was done. +// in mxGraph, the style was a string, now it is an object. Modifying the returned style didn't modify the string of the style cell, so the 2 objects weren't equal and so processing was done. // -// See https://github.com/maxGraph/maxGraph/issues/326 (the method modified the style of the cell, so the 2 objects are equal, no processing is done) -// https://github.com/maxGraph/maxGraph/pull/380 provides an dedicated method in Cell -export const getCellStyleClone = (cell: Cell): CellStyle => cloneUtils.clone(cell.getStyle()); +// See https://github.com/maxGraph/maxGraph/issues/326 +export const getCellStyleClone = (cell: Cell): CellStyle => cell.getClonedStyle(); From eff4a53d9cd36f06515c65ac2b8eda8e99e34615 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:33:31 +0200 Subject: [PATCH 42/90] Update TODO --- src/component/mxgraph/BpmnGraph.ts | 1 + src/component/mxgraph/style/utils.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index 679cd9bf7b..b77c78a5d9 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -230,6 +230,7 @@ class BpmnGraphView extends GraphView { } // TODO maxgraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) +// see also utils.ts setStyle which adds another workaround that should be possible to remove with maxGraph@0.10.1 class BpmnStylesheet extends Stylesheet { override getCellStyle(cellStyle: CellStyle, defaultStyle: CellStateStyle): CellStateStyle { let style: CellStateStyle; diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index 7e35798fa7..a67534b43b 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -90,7 +90,7 @@ export const setStyle = ( if (value != undefined) { const convertedValue = converter(value); if (convertedValue == null) { - // TODO maxgraph@0.1.0 - this is required for the effective cell style computation with the fix temporary used in bpmn-visualization + // TODO maxgraph@0.1.0 - this is required for the effective cell style computation with the fix temporary used in bpmn-visualization (BpmnStylesheet) // if the value is undefined/or null, the value from the default style is not used! // remove the property to use the value from the "base styles" which provides the default value delete cellStyle[key]; From 628a6d8c9e8b8b674e3cab4649a0c851090f6797 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 15:00:01 +0200 Subject: [PATCH 43/90] StyleComputer.ts update TODO --- src/component/mxgraph/renderer/StyleComputer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index 7c906e215a..bfbd28eb77 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -150,7 +150,7 @@ export default class StyleComputer { style.bpmn.markers = bpmnElement.markers; } - // TODO maxgraph@0.1.0 switch from static method to function (same in other places of this class) --> TODO in master branch + // TODO maxgraph@0.1.0 switch from static method to function (same in other places of this class) --> this has been done in master branch // This applies to the current implementation and to all static methods of this class private static computeEdgeBaseStyleNames(edge: Edge): string[] { const styles: string[] = []; From af351af94d03f09c43722e41dd6c4700d1132010 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 15:40:31 +0200 Subject: [PATCH 44/90] StyleComputer.ts: fix TODO --- src/component/mxgraph/renderer/StyleComputer.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index bfbd28eb77..fe268edc5b 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -49,10 +49,8 @@ import type { RendererOptions } from '../../options'; // TODO maxgraph@0.1.0 rename for consistent naming BPMNCellStyle --> BpmnCellStyle (apply to other places) // a BpmnCellStyle exists in tests. Try to use this one instead export interface BPMNCellStyle extends CellStyle { - // TODO maxgraph@0.1.0 make bpmn mandatory? + // TODO maxgraph@0.1.0 sort properties in alphabetical order for clarity (and as done in maxGraph CellStyle) and provide documentation about each property bpmn?: { - // TODO maxgraph@0.1.0 sort properties in alphabetical order for clarity (and as done in maxGraph CellStyle) and provide documentation about each property - // TODO maxgraph@0.1.0 make kind mandatory? kind?: ShapeBpmnElementKind | FlowKind; isInstantiating?: boolean; gatewayKind?: ShapeBpmnEventBasedGatewayKind; From 88a6524f345c5fc299f698fe43a855f0f5ba5a35 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:04:44 +0200 Subject: [PATCH 45/90] remove extra imports --- src/component/mxgraph/GraphCellUpdater.ts | 1 - src/component/mxgraph/style/utils.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/component/mxgraph/GraphCellUpdater.ts b/src/component/mxgraph/GraphCellUpdater.ts index 31f8ea87b9..c18432d2a8 100644 --- a/src/component/mxgraph/GraphCellUpdater.ts +++ b/src/component/mxgraph/GraphCellUpdater.ts @@ -26,7 +26,6 @@ import { OverlayConverter } from './overlay/OverlayConverter'; import { messageFlowIconId } from './BpmnRenderer'; import { ensureOpacityValue } from '../helpers/validators'; import type { BPMNCellStyle } from './renderer/StyleComputer'; -import { cloneUtils } from '@maxgraph/core'; /** * @internal diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index a67534b43b..c83e49ac0b 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -16,7 +16,7 @@ limitations under the License. import type { Cell, CellStyle, NumericCellStateStyleKeys } from '@maxgraph/core'; import { constants } from '@maxgraph/core'; -import { cloneUtils, styleUtils } from '@maxgraph/core'; +import { styleUtils } from '@maxgraph/core'; import type { BPMNCellStyle } from '../renderer/StyleComputer'; import { ensureOpacityValue, ensureStrokeWidthValue } from '../../helpers/validators'; From dc396e0a621933c43be0ac7918749b62192b72b7 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:27:28 +0200 Subject: [PATCH 46/90] Update edge.arcSize value to replicate the rendering we had with mxGraph --- src/component/mxgraph/config/StyleConfigurator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 97c56f3abd..f712ccb62a 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -245,7 +245,7 @@ export class StyleConfigurator { style.strokeWidth = 1.5; style.rounded = true; // TODO maxgraph@0.10.1 the rendered edge arcSize seems larger than with mxGraph (also seen with maxgraph 0.1.0) - style.arcSize = 5; + // style.arcSize = 2; // put 2 in maxgraph@0.10.1, in mxGraph@4.2.2 we used 5 style.verticalAlign = 'bottom'; // The end arrow must be redefined in specific style delete style.endArrow; From 927ce24fdfe32c2fe814b48983d7640a26e278a0 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:13:03 +0200 Subject: [PATCH 47/90] Move BPMNCellStyle to a dedicated file --- src/component/mxgraph/BpmnRenderer.ts | 2 +- src/component/mxgraph/GraphCellUpdater.ts | 2 +- .../mxgraph/config/ShapeConfigurator.ts | 2 +- .../mxgraph/config/StyleConfigurator.ts | 2 +- .../mxgraph/renderer/StyleComputer.ts | 32 +------------ src/component/mxgraph/renderer/style-utils.ts | 2 +- .../mxgraph/shape/activity-shapes.ts | 2 +- src/component/mxgraph/shape/edges.ts | 2 +- src/component/mxgraph/shape/event-shapes.ts | 2 +- src/component/mxgraph/shape/flow-shapes.ts | 2 +- src/component/mxgraph/shape/gateway-shapes.ts | 2 +- src/component/mxgraph/style/StyleManager.ts | 2 +- src/component/mxgraph/style/types.ts | 48 +++++++++++++++++++ src/component/mxgraph/style/utils.ts | 2 +- test/integration/helpers/model-expect.ts | 2 +- test/integration/matchers/matcher-utils.ts | 2 +- test/integration/matchers/toBeEdge/index.ts | 2 +- test/integration/matchers/toBeShape/index.ts | 2 +- .../mxgraph/renderer/StyleComputer.test.ts | 2 +- .../mxgraph/renderer/style-utils.test.ts | 2 +- 20 files changed, 67 insertions(+), 49 deletions(-) create mode 100644 src/component/mxgraph/style/types.ts diff --git a/src/component/mxgraph/BpmnRenderer.ts b/src/component/mxgraph/BpmnRenderer.ts index 18d2d2c6ae..c3e8d9cca2 100644 --- a/src/component/mxgraph/BpmnRenderer.ts +++ b/src/component/mxgraph/BpmnRenderer.ts @@ -21,7 +21,7 @@ import type ShapeBpmnElement from '../../model/bpmn/internal/shape/ShapeBpmnElem import type Bounds from '../../model/bpmn/internal/Bounds'; import { MessageVisibleKind, ShapeUtil } from '../../model/bpmn/internal'; import CoordinatesTranslator from './renderer/CoordinatesTranslator'; -import type { BPMNCellStyle } from './renderer/StyleComputer'; +import type { BPMNCellStyle } from './style/types'; import StyleComputer from './renderer/StyleComputer'; import type { BpmnGraph } from './BpmnGraph'; import type { FitOptions, RendererOptions } from '../options'; diff --git a/src/component/mxgraph/GraphCellUpdater.ts b/src/component/mxgraph/GraphCellUpdater.ts index c18432d2a8..d87b765d20 100644 --- a/src/component/mxgraph/GraphCellUpdater.ts +++ b/src/component/mxgraph/GraphCellUpdater.ts @@ -25,7 +25,7 @@ import { ensureIsArray } from '../helpers/array-utils'; import { OverlayConverter } from './overlay/OverlayConverter'; import { messageFlowIconId } from './BpmnRenderer'; import { ensureOpacityValue } from '../helpers/validators'; -import type { BPMNCellStyle } from './renderer/StyleComputer'; +import type { BPMNCellStyle } from './style/types'; /** * @internal diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index 5d1c7d192f..62ca59f0fe 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -36,7 +36,7 @@ import { TextAnnotationShape } from '../shape/text-annotation-shapes'; import { MessageFlowIconShape } from '../shape/flow-shapes'; import { BpmnStyleIdentifier } from '../style'; import { computeAllBpmnClassNamesOfCell } from '../renderer/style-utils'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import type { BPMNCellStyle } from '../style/types'; import { MxGraphCustomOverlay } from '../overlay/custom-overlay'; import { OverlayBadgeShape } from '../overlay/shapes'; import { BpmnConnector } from '../shape/edges'; diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index f712ccb62a..a5a7da2c02 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -17,7 +17,7 @@ limitations under the License. import { AssociationDirectionKind, FlowKind, SequenceFlowKind, ShapeBpmnElementKind, ShapeUtil } from '../../../model/bpmn/internal'; import { BpmnStyleIdentifier, MarkerIdentifier, StyleDefault } from '../style'; import type { BpmnGraph } from '../BpmnGraph'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import type { BPMNCellStyle } from '../style/types'; import { constants, Perimeter } from '@maxgraph/core'; import type { Stylesheet } from '@maxgraph/core'; diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index fe268edc5b..d05bb7f67e 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -30,41 +30,11 @@ import { ShapeBpmnSubProcess, } from '../../../model/bpmn/internal/shape/ShapeBpmnElement'; import { BpmnStyleIdentifier } from '../style'; -import type { - AssociationDirectionKind, - FlowKind, - GlobalTaskKind, - SequenceFlowKind, - ShapeBpmnEventBasedGatewayKind, - ShapeBpmnEventDefinitionKind, - ShapeBpmnSubProcessKind, -} from '../../../model/bpmn/internal'; import { MessageVisibleKind, ShapeBpmnCallActivityKind, ShapeBpmnElementKind, ShapeBpmnMarkerKind, ShapeUtil } from '../../../model/bpmn/internal'; import { AssociationFlow, SequenceFlow } from '../../../model/bpmn/internal/edge/flows'; import type { Font } from '../../../model/bpmn/internal/Label'; import type { RendererOptions } from '../../options'; - -// TODO maxgraph@0.1.0 this type should probably be part of the API (so it should be exported) -// TODO maxgraph@0.1.0 move somewhere else -// TODO maxgraph@0.1.0 rename for consistent naming BPMNCellStyle --> BpmnCellStyle (apply to other places) -// a BpmnCellStyle exists in tests. Try to use this one instead -export interface BPMNCellStyle extends CellStyle { - // TODO maxgraph@0.1.0 sort properties in alphabetical order for clarity (and as done in maxGraph CellStyle) and provide documentation about each property - bpmn?: { - kind?: ShapeBpmnElementKind | FlowKind; - isInstantiating?: boolean; - gatewayKind?: ShapeBpmnEventBasedGatewayKind; - eventDefinitionKind?: ShapeBpmnEventDefinitionKind; - isInterrupting?: boolean; - subProcessKind?: ShapeBpmnSubProcessKind; - globalTaskKind?: GlobalTaskKind; - markers?: ShapeBpmnMarkerKind[]; - sequenceFlowKind?: SequenceFlowKind; - associationDirectionKind?: AssociationDirectionKind; - isInitiating?: boolean; - extraCssClasses?: string[]; - }; -} +import type { BPMNCellStyle } from '../style/types'; /** * @internal diff --git a/src/component/mxgraph/renderer/style-utils.ts b/src/component/mxgraph/renderer/style-utils.ts index fcede27270..1474c447fc 100644 --- a/src/component/mxgraph/renderer/style-utils.ts +++ b/src/component/mxgraph/renderer/style-utils.ts @@ -17,7 +17,7 @@ limitations under the License. import type { Cell } from '@maxgraph/core'; import { FlowKind, ShapeUtil } from '../../../model/bpmn/internal'; -import type { BPMNCellStyle } from './StyleComputer'; +import type { BPMNCellStyle } from '../style/types'; /** * Compute the all class names associated to a cell in a hyphen case form. diff --git a/src/component/mxgraph/shape/activity-shapes.ts b/src/component/mxgraph/shape/activity-shapes.ts index 0973245ba9..411500117f 100644 --- a/src/component/mxgraph/shape/activity-shapes.ts +++ b/src/component/mxgraph/shape/activity-shapes.ts @@ -17,7 +17,7 @@ limitations under the License. import type { AbstractCanvas2D } from '@maxgraph/core'; import { RectangleShape } from '@maxgraph/core'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import type { BPMNCellStyle } from '../style/types'; import { StyleDefault } from '../style'; import type { BpmnCanvas, PaintParameter, ShapeConfiguration } from './render'; import { IconPainterProvider } from './render'; diff --git a/src/component/mxgraph/shape/edges.ts b/src/component/mxgraph/shape/edges.ts index a1b0974a92..dcea9036e8 100644 --- a/src/component/mxgraph/shape/edges.ts +++ b/src/component/mxgraph/shape/edges.ts @@ -17,7 +17,7 @@ limitations under the License. import type { Point, AbstractCanvas2D } from '@maxgraph/core'; import { SvgCanvas2D, ConnectorShape } from '@maxgraph/core'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import type { BPMNCellStyle } from '../style/types'; // TODO maxgraph@0.1.0 remove the BpmnConnector class to use the new support of endFillColor and starFillColor provided by https://github.com/maxGraph/maxGraph/issues/201 export class BpmnConnector extends ConnectorShape { diff --git a/src/component/mxgraph/shape/event-shapes.ts b/src/component/mxgraph/shape/event-shapes.ts index c4d91ff7b3..fa3654c5ef 100644 --- a/src/component/mxgraph/shape/event-shapes.ts +++ b/src/component/mxgraph/shape/event-shapes.ts @@ -21,7 +21,7 @@ import { ShapeBpmnEventDefinitionKind } from '../../../model/bpmn/internal'; import type { BpmnCanvas, PaintParameter } from './render'; import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import type { BPMNCellStyle } from '../style/types'; import { StyleDefault } from '../style'; /** diff --git a/src/component/mxgraph/shape/flow-shapes.ts b/src/component/mxgraph/shape/flow-shapes.ts index 78fe94616f..55186f3337 100644 --- a/src/component/mxgraph/shape/flow-shapes.ts +++ b/src/component/mxgraph/shape/flow-shapes.ts @@ -16,7 +16,7 @@ limitations under the License. import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import type { BPMNCellStyle } from '../style/types'; import { RectangleShape } from '@maxgraph/core'; import type { AbstractCanvas2D, Rectangle } from '@maxgraph/core'; diff --git a/src/component/mxgraph/shape/gateway-shapes.ts b/src/component/mxgraph/shape/gateway-shapes.ts index 66179e50b9..6546eac71b 100644 --- a/src/component/mxgraph/shape/gateway-shapes.ts +++ b/src/component/mxgraph/shape/gateway-shapes.ts @@ -22,7 +22,7 @@ import { StyleDefault } from '../style'; import type { PaintParameter } from './render'; import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import type { BPMNCellStyle } from '../style/types'; abstract class GatewayShape extends RhombusShape { protected iconPainter = IconPainterProvider.get(); diff --git a/src/component/mxgraph/style/StyleManager.ts b/src/component/mxgraph/style/StyleManager.ts index c41136e2ed..56cd5ff8bd 100644 --- a/src/component/mxgraph/style/StyleManager.ts +++ b/src/component/mxgraph/style/StyleManager.ts @@ -16,7 +16,7 @@ limitations under the License. import type { Cell, CellStyle, GraphDataModel } from '@maxgraph/core'; import { getCellStyleClone, setCssClasses } from './utils'; import type { CssRegistry } from '../../registry/css-registry'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import type { BPMNCellStyle } from '../style/types'; export class StyleManager { private stylesCache: Map = new Map(); diff --git a/src/component/mxgraph/style/types.ts b/src/component/mxgraph/style/types.ts new file mode 100644 index 0000000000..a449a7eb90 --- /dev/null +++ b/src/component/mxgraph/style/types.ts @@ -0,0 +1,48 @@ +/* +Copyright 2024 Bonitasoft S.A. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import type { CellStyle } from '@maxgraph/core'; +import type { + AssociationDirectionKind, + FlowKind, + GlobalTaskKind, + SequenceFlowKind, + ShapeBpmnElementKind, + ShapeBpmnEventBasedGatewayKind, + ShapeBpmnEventDefinitionKind, + ShapeBpmnMarkerKind, + ShapeBpmnSubProcessKind, +} from '../../../model/bpmn/internal'; + +// TODO maxgraph@0.1.0 rename for consistent naming BPMNCellStyle --> BpmnCellStyle (apply to other places) +// a BpmnCellStyle exists in tests. Try to use this one instead +// TODO maxgraph@0.1.0 sort properties in alphabetical order for clarity (and as done in maxGraph CellStyle) and provide documentation about each property +export interface BPMNCellStyle extends CellStyle { + bpmn?: { + associationDirectionKind?: AssociationDirectionKind; + eventDefinitionKind?: ShapeBpmnEventDefinitionKind; + extraCssClasses?: string[]; + gatewayKind?: ShapeBpmnEventBasedGatewayKind; + globalTaskKind?: GlobalTaskKind; + isInitiating?: boolean; + isInstantiating?: boolean; + isInterrupting?: boolean; + kind?: ShapeBpmnElementKind | FlowKind; + markers?: ShapeBpmnMarkerKind[]; + sequenceFlowKind?: SequenceFlowKind; + subProcessKind?: ShapeBpmnSubProcessKind; + }; +} diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index c83e49ac0b..21fd78fb68 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -18,7 +18,7 @@ import type { Cell, CellStyle, NumericCellStateStyleKeys } from '@maxgraph/core' import { constants } from '@maxgraph/core'; import { styleUtils } from '@maxgraph/core'; -import type { BPMNCellStyle } from '../renderer/StyleComputer'; +import type { BPMNCellStyle } from './types'; import { ensureOpacityValue, ensureStrokeWidthValue } from '../../helpers/validators'; import type { Fill, Font, ShapeStyleUpdate, Stroke, StyleUpdate } from '../../registry'; import { ShapeUtil } from '../../../model/bpmn/internal'; diff --git a/test/integration/helpers/model-expect.ts b/test/integration/helpers/model-expect.ts index f12ba67aff..90f02383c5 100644 --- a/test/integration/helpers/model-expect.ts +++ b/test/integration/helpers/model-expect.ts @@ -62,7 +62,7 @@ import { import type { StyleArrowValue, Cell, FilterFunction, Geometry, ShapeValue } from '@maxgraph/core'; import type { ExpectedOverlay } from '../matchers/matcher-utils'; import { getCell } from '../matchers/matcher-utils'; -import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace diff --git a/test/integration/matchers/matcher-utils.ts b/test/integration/matchers/matcher-utils.ts index a477a614a6..4422c751b2 100644 --- a/test/integration/matchers/matcher-utils.ts +++ b/test/integration/matchers/matcher-utils.ts @@ -25,7 +25,7 @@ import type { Opacity } from '@lib/component/registry'; import type { MxGraphCustomOverlay, MxGraphCustomOverlayStyle } from '@lib/component/mxgraph/overlay/custom-overlay'; import { getFontStyleValue as computeFontStyleValue } from '@lib/component/mxgraph/renderer/StyleComputer'; import { Font } from '@lib/model/bpmn/internal/Label'; -import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; // TODO maxgraph@0.1.0 remove this type and use a single type shared with BPMNCellStyle // No more need for a dedicated BpmnStyle in the integration tests. Use the one from the sources diff --git a/test/integration/matchers/toBeEdge/index.ts b/test/integration/matchers/toBeEdge/index.ts index c1fc81b382..47804b046a 100644 --- a/test/integration/matchers/toBeEdge/index.ts +++ b/test/integration/matchers/toBeEdge/index.ts @@ -22,7 +22,7 @@ import { AssociationDirectionKind, FlowKind, MessageVisibleKind, SequenceFlowKin import type { ExpectedAssociationFlowModelElement, ExpectedEdgeModelElement, ExpectedSequenceFlowModelElement } from '../../helpers/model-expect'; import { getDefaultParentId } from '../../helpers/model-expect'; import { BpmnStyleIdentifier } from '@lib/component/mxgraph/style'; -import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; import MatcherContext = jest.MatcherContext; import CustomMatcherResult = jest.CustomMatcherResult; diff --git a/test/integration/matchers/toBeShape/index.ts b/test/integration/matchers/toBeShape/index.ts index 4d9c129a55..5dc23a7e78 100644 --- a/test/integration/matchers/toBeShape/index.ts +++ b/test/integration/matchers/toBeShape/index.ts @@ -29,7 +29,7 @@ import { getDefaultParentId } from '../../helpers/model-expect'; import { ShapeBpmnElementKind, ShapeBpmnEventBasedGatewayKind, ShapeBpmnMarkerKind, ShapeBpmnSubProcessKind } from '@lib/model/bpmn/internal'; import MatcherContext = jest.MatcherContext; import CustomMatcherResult = jest.CustomMatcherResult; -import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; function expectedStrokeWidth(kind: ShapeBpmnElementKind): number { return [ diff --git a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts index 9f82cea977..19e41b4af5 100644 --- a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts +++ b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts @@ -17,7 +17,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { BPMNCellStyle } from '@lib/component/mxgraph/renderer/StyleComputer'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; import StyleComputer from '@lib/component/mxgraph/renderer/StyleComputer'; import Shape from '@lib/model/bpmn/internal/shape/Shape'; import ShapeBpmnElement, { diff --git a/test/unit/component/mxgraph/renderer/style-utils.test.ts b/test/unit/component/mxgraph/renderer/style-utils.test.ts index 077a4f799e..abcf419c88 100644 --- a/test/unit/component/mxgraph/renderer/style-utils.test.ts +++ b/test/unit/component/mxgraph/renderer/style-utils.test.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { BPMNCellStyle } from '../../../../../src/component/mxgraph/renderer/StyleComputer'; +import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; import { FlowKind, ShapeBpmnElementKind, ShapeBpmnEventBasedGatewayKind, ShapeBpmnEventDefinitionKind, ShapeBpmnSubProcessKind } from '@lib/model/bpmn/internal'; import { computeBpmnBaseClassName, computeAllBpmnClassNames } from '@lib/component/mxgraph/renderer/style-utils'; From 79ea060c21359792051bfc862b6c34fa5af87ea0 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:14:53 +0200 Subject: [PATCH 48/90] StyleComputer.ts manage TODO --- src/component/mxgraph/renderer/StyleComputer.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index d05bb7f67e..96e4b70571 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { CellStyle, ShapeValue } from '@maxgraph/core'; +import type { CellStyle } from '@maxgraph/core'; import { constants } from '@maxgraph/core'; import Shape from '../../../model/bpmn/internal/shape/Shape'; @@ -192,8 +192,7 @@ export default class StyleComputer { computeMessageFlowIconStyle(edge: Edge): BPMNCellStyle { const style: BPMNCellStyle = { - // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types - shape: BpmnStyleIdentifier.MESSAGE_FLOW_ICON, + shape: BpmnStyleIdentifier.MESSAGE_FLOW_ICON, bpmn: { isInitiating: edge.messageVisibleKind === MessageVisibleKind.INITIATING }, }; if (!this.ignoreBpmnColors) { From e37b321d09f6e300f340807282d3b47468cbbd74 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:16:21 +0200 Subject: [PATCH 49/90] style-utils.ts manage TODO --- src/component/mxgraph/renderer/style-utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/component/mxgraph/renderer/style-utils.ts b/src/component/mxgraph/renderer/style-utils.ts index 1474c447fc..893183e94e 100644 --- a/src/component/mxgraph/renderer/style-utils.ts +++ b/src/component/mxgraph/renderer/style-utils.ts @@ -40,7 +40,6 @@ export function computeAllBpmnClassNamesOfCell(cell: Cell, isLabel: boolean): st export function computeAllBpmnClassNames(style: BPMNCellStyle, isLabel: boolean): string[] { const classes: string[] = []; - // TODO maxgraph@0.1.0 style.bpmn.kind could be omit by considering the first element of style.baseStyleNames (this would restore the previous behavior) // if kind is not set, check shape: bpmn.message-flow-icon --> message-flow-icon const bpmnElementKind = style.bpmn?.kind ?? style.shape?.replace(/bpmn./g, ''); From 65c4935344d93c527cc93319c3c040a56d5a5ce4 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:24:52 +0200 Subject: [PATCH 50/90] Update todo of maxgraph 0.1.0: mark them to be done after a new rebase on master --- src/component/mxgraph/GraphCellUpdater.ts | 2 +- src/component/mxgraph/GraphConfigurator.ts | 3 ++- src/component/mxgraph/renderer/StyleComputer.ts | 2 +- src/component/mxgraph/style/StyleManager.ts | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/component/mxgraph/GraphCellUpdater.ts b/src/component/mxgraph/GraphCellUpdater.ts index d87b765d20..a30388ee91 100644 --- a/src/component/mxgraph/GraphCellUpdater.ts +++ b/src/component/mxgraph/GraphCellUpdater.ts @@ -113,7 +113,7 @@ export default class GraphCellUpdater { updateFill(cellStyle, styleUpdate.fill); } - // TODO maxgraph@0.1.0 migration --> apply this to the master branch graph.model --> model + // TODO maxgraph@0.10.1 migration --> change to apply this to the master branch: graph.model --> model (from maxgraph@0.1.0 migration) model.setStyle(cell, cellStyle); } }); diff --git a/src/component/mxgraph/GraphConfigurator.ts b/src/component/mxgraph/GraphConfigurator.ts index 9c7a7dca1b..d59f6c246c 100644 --- a/src/component/mxgraph/GraphConfigurator.ts +++ b/src/component/mxgraph/GraphConfigurator.ts @@ -63,7 +63,8 @@ export default class GraphConfigurator { } private configureNavigationSupport(options: GlobalOptions): void { - // TODO maxgraph@0.1.0 decide if we hide this maxGraph implementation details in BpmnGraph + // TODO maxgraph@0.1.0 decide if we do the check or not. + // If not, add a comment to explain why // In theory, the panningHandler may not be available if its plugin is not registered. The maxGraph code sometimes check for availability. For now, the check is not needed as we know that we load it const panningHandler = this.graph.getPlugin('PanningHandler'); diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index 96e4b70571..162d364dfc 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -118,7 +118,7 @@ export default class StyleComputer { style.bpmn.markers = bpmnElement.markers; } - // TODO maxgraph@0.1.0 switch from static method to function (same in other places of this class) --> this has been done in master branch + // TODO maxgraph@0.10.1 switch from static method to function (same in other places of this class) --> this has been done in master branch // This applies to the current implementation and to all static methods of this class private static computeEdgeBaseStyleNames(edge: Edge): string[] { const styles: string[] = []; diff --git a/src/component/mxgraph/style/StyleManager.ts b/src/component/mxgraph/style/StyleManager.ts index 56cd5ff8bd..a3ae8ef905 100644 --- a/src/component/mxgraph/style/StyleManager.ts +++ b/src/component/mxgraph/style/StyleManager.ts @@ -29,7 +29,7 @@ export class StyleManager { resetAllStyles(): void { for (const cellId of this.stylesCache.keys()) { - // TODO maxGraph 0.1.0 - inline in master branch + // TODO maxGraph 0.10.1 - inline in master branch (from maxgraph@0.1.0 migration) const style = this.stylesCache.get(cellId); this.resetStyle(cellId, style); } @@ -49,7 +49,7 @@ export class StyleManager { private resetStyle(cellId: string, style: BPMNCellStyle): void { const cell = this.model.getCell(cellId); - // TODO maxGraph 0.1.0 - inline (can be done in the master branch as well) + // TODO maxGraph 0.10.1 - inline in master branch (from maxgraph@0.1.0 migration) const cssClasses = this.cssRegistry.getClassNames(cellId); // no need to copy the style, it is coming from the cache only and is later deleted from the cache From a36015a438c4466099db9c4896b6c227d38d0805 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:28:50 +0200 Subject: [PATCH 51/90] manage TODO in utils.ts setCssClasses --- src/component/mxgraph/style/utils.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index 21fd78fb68..5391506e62 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -144,13 +144,10 @@ export const isShapeStyleUpdate = (style: StyleUpdate): style is ShapeStyleUpdat }; export function setCssClasses(cellStyle: BPMNCellStyle, cssClasses: string[]): void { - // TODO maxgraph@0.1.0 do we need to check if the parameter is not undefined - test pass without checking undefined if (cssClasses.length > 0) { cellStyle.bpmn.extraCssClasses = cssClasses; } else { - // TODO maxgraph@0.1.0 - this is needed to make the integration tests pass - do we really do to it for a real usage? - cellStyle.bpmn.extraCssClasses = undefined; - // delete cellStyle.bpmn.extraCssClasses; + delete cellStyle.bpmn.extraCssClasses; } } From 53197c309c6a89570a78af34b22ada9e1ed2f653 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:29:07 +0200 Subject: [PATCH 52/90] Update todo of maxgraph 0.1.0: mark them to be done after a new rebase on master --- src/component/mxgraph/style/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index 5391506e62..b6df55b71e 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -104,7 +104,7 @@ export const setStyle = ( }; export const setStyleFlag = (cellStyle: CellStyle, key: NumericCellStateStyleKeys, flag: number, value?: boolean): void => { - // TODO maxGraph@0.1.0 - move this comment to the master branch + // TODO maxGraph@0.10.1 - move this comment to the master branch (from maxgraph@0.1.0 migration) // the mxGraph setStyleFlag function toggle the flag if the value if undefined is passed. In bpmn-visualization, we want to keep the value as it is instead in this case (there is no toggle feature) if (value == undefined) return; From d72d568713b15037c418b286f683ff98ab0d5a23 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:41:06 +0200 Subject: [PATCH 53/90] Update todo of maxgraph 0.1.0: mark them to be done after a new rebase on master --- test/integration/mxGraph.model.bpmn.elements.test.ts | 2 +- test/unit/component/mxgraph/renderer/StyleComputer.test.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/test/integration/mxGraph.model.bpmn.elements.test.ts b/test/integration/mxGraph.model.bpmn.elements.test.ts index a9edde643c..bcae3b9116 100644 --- a/test/integration/mxGraph.model.bpmn.elements.test.ts +++ b/test/integration/mxGraph.model.bpmn.elements.test.ts @@ -1700,7 +1700,7 @@ describe('mxGraph model - BPMN elements', () => { }); it('Parse a diagram with numbers not parsable as number', () => { - // TODO maxgraph@0.1.0 change in maxGraph, throw 'Error: Invalid x supplied'. bpmn-visualization should handle it + // TODO maxgraph@0.10.1 change in maxGraph, throw 'Error: Invalid x supplied'. bpmn-visualization should handle it - wait for new rebase on master (the code changed in recent version) // capture the error and rethrow it with a convenient // OR validate the values during parsing diff --git a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts index 19e41b4af5..0c2136d02d 100644 --- a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts +++ b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts @@ -127,8 +127,6 @@ function newAssociationFlow(kind: AssociationDirectionKind): AssociationFlow { return new AssociationFlow('id', 'name', undefined, undefined, kind); } -// TODO maxgraph@0.1.0 order properties alphabetically in expected style - describe('Style Computer', () => { // use a shared instance to check that there is no state stored in the implementation const styleComputer = new StyleComputer(); From bdea858cce8aa1424da0d69f5add1cb39166ad14 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:47:48 +0200 Subject: [PATCH 54/90] Rename the "BpmnCellStyle" type used in tests --- test/integration/matchers/matcher-utils.ts | 21 ++++++++++---------- test/integration/matchers/toBeEdge/index.ts | 6 +++--- test/integration/matchers/toBeShape/index.ts | 4 ++-- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/test/integration/matchers/matcher-utils.ts b/test/integration/matchers/matcher-utils.ts index 4422c751b2..5b8ae31a99 100644 --- a/test/integration/matchers/matcher-utils.ts +++ b/test/integration/matchers/matcher-utils.ts @@ -27,9 +27,10 @@ import { getFontStyleValue as computeFontStyleValue } from '@lib/component/mxgra import { Font } from '@lib/model/bpmn/internal/Label'; import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; -// TODO maxgraph@0.1.0 remove this type and use a single type shared with BPMNCellStyle -// No more need for a dedicated BpmnStyle in the integration tests. Use the one from the sources -export interface BpmnCellStyle { +/** + * Used in test to compare the expected and received styles. + */ +export interface ComparedBpmnCellStyle { opacity: Opacity; verticalAlign?: VerticalAlign; align?: HorizontalAlign; @@ -65,11 +66,11 @@ export interface ExpectedCell { * * It involves the usage of `graph.getCellStyle`. */ - styleResolvedFromModel?: BpmnCellStyle; + styleResolvedFromModel?: ComparedBpmnCellStyle; /** * Relates to the current style in the state view of the cell which is typically retrieved by calling `view.getState(cell).style` where `view` is `graph.getView()`. */ - styleViewState?: BpmnCellStyle; + styleViewState?: ComparedBpmnCellStyle; id?: string; edge?: boolean; vertex?: boolean; @@ -136,7 +137,7 @@ export function getFontStyleValue(expectedFont: ExpectedFont): number { ); } -export function buildExpectedCellStyleWithCommonAttributes(expectedModelElt: ExpectedEdgeModelElement | ExpectedShapeModelElement): BpmnCellStyle { +export function buildExpectedCellStyleWithCommonAttributes(expectedModelElt: ExpectedEdgeModelElement | ExpectedShapeModelElement): ComparedBpmnCellStyle { const font = expectedModelElt.font; // Here are the default values as defined in StyleDefault @@ -169,7 +170,7 @@ export function buildExpectedCellStyleWithCommonAttributes(expectedModelElt: Exp * @param cell The Cell to consider to get the style in the state view * @param bv The instance of BpmnVisualization under test */ -export function buildReceivedViewStateStyle(cell: Cell, bv = bpmnVisualization): BpmnCellStyle { +export function buildReceivedViewStateStyle(cell: Cell, bv = bpmnVisualization): ComparedBpmnCellStyle { return toBpmnStyle(bv.graph.getView().getState(cell).style, cell.edge); } @@ -183,12 +184,12 @@ export function buildReceivedViewStateStyle(cell: Cell, bv = bpmnVisualization): * @param cell The Cell to consider for the computation of the resolved style. * @param bv The instance of BpmnVisualization under test */ -export function buildReceivedResolvedModelCellStyle(cell: Cell, bv = bpmnVisualization): BpmnCellStyle { +export function buildReceivedResolvedModelCellStyle(cell: Cell, bv = bpmnVisualization): ComparedBpmnCellStyle { return toBpmnStyle(bv.graph.getCellStyle(cell), cell.edge); } -function toBpmnStyle(rawStyle: BPMNCellStyle, isEdge: boolean): BpmnCellStyle { - const style: BpmnCellStyle = { +function toBpmnStyle(rawStyle: BPMNCellStyle, isEdge: boolean): ComparedBpmnCellStyle { + const style: ComparedBpmnCellStyle = { opacity: rawStyle.opacity, verticalAlign: rawStyle.verticalAlign, align: rawStyle.align, diff --git a/test/integration/matchers/toBeEdge/index.ts b/test/integration/matchers/toBeEdge/index.ts index 47804b046a..fc194fed0b 100644 --- a/test/integration/matchers/toBeEdge/index.ts +++ b/test/integration/matchers/toBeEdge/index.ts @@ -16,7 +16,7 @@ limitations under the License. import type { ShapeValue } from '@maxgraph/core'; -import type { BpmnCellStyle, ExpectedCell } from '../matcher-utils'; +import type { ComparedBpmnCellStyle, ExpectedCell } from '../matcher-utils'; import { buildCellMatcher, buildExpectedCellStyleWithCommonAttributes, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; import { AssociationDirectionKind, FlowKind, MessageVisibleKind, SequenceFlowKind } from '@lib/model/bpmn/internal'; import type { ExpectedAssociationFlowModelElement, ExpectedEdgeModelElement, ExpectedSequenceFlowModelElement } from '../../helpers/model-expect'; @@ -26,7 +26,7 @@ import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; import MatcherContext = jest.MatcherContext; import CustomMatcherResult = jest.CustomMatcherResult; -function buildExpectedEdgeCellStyle(expectedModel: ExpectedEdgeModelElement): BpmnCellStyle { +function buildExpectedEdgeCellStyle(expectedModel: ExpectedEdgeModelElement): ComparedBpmnCellStyle { const style = buildExpectedCellStyleWithCommonAttributes(expectedModel); style.verticalAlign = expectedModel.verticalAlign ?? 'top'; style.align = 'center'; @@ -37,7 +37,7 @@ function buildExpectedEdgeCellStyle(expectedModel: ExpectedEdgeModelElement): Bp return style; } -function buildExpectedMsgFlowIconCellStyle(expectedModel: ExpectedEdgeModelElement): BpmnCellStyle { +function buildExpectedMsgFlowIconCellStyle(expectedModel: ExpectedEdgeModelElement): ComparedBpmnCellStyle { const style = buildExpectedCellStyleWithCommonAttributes(expectedModel); style.align = 'center'; style.verticalAlign = 'middle'; diff --git a/test/integration/matchers/toBeShape/index.ts b/test/integration/matchers/toBeShape/index.ts index 5dc23a7e78..4731379122 100644 --- a/test/integration/matchers/toBeShape/index.ts +++ b/test/integration/matchers/toBeShape/index.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { ExpectedCell, BpmnCellStyle } from '../matcher-utils'; +import type { ExpectedCell, ComparedBpmnCellStyle } from '../matcher-utils'; import { buildCellMatcher, buildExpectedCellStyleWithCommonAttributes, buildReceivedCellWithCommonAttributes } from '../matcher-utils'; import type { ExpectedBoundaryEventModelElement, @@ -59,7 +59,7 @@ function expectedStrokeWidth(kind: ShapeBpmnElementKind): number { : undefined; } -export function buildExpectedShapeCellStyle(expectedModel: ExpectedShapeModelElement): BpmnCellStyle { +export function buildExpectedShapeCellStyle(expectedModel: ExpectedShapeModelElement): ComparedBpmnCellStyle { const style = buildExpectedCellStyleWithCommonAttributes(expectedModel); // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types // expectedStateStyle.shape = ((!expectedModel.styleShape ? expectedModel.kind : expectedModel.styleShape)); From 0ccbc649255e0f19334af3883888e752fd643f7f Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:50:04 +0200 Subject: [PATCH 55/90] Rename "BPMNCellStyle" into "BpmnCellStyle" type to use a consistent case --- src/component/mxgraph/BpmnRenderer.ts | 4 +- src/component/mxgraph/GraphCellUpdater.ts | 4 +- .../mxgraph/config/ShapeConfigurator.ts | 4 +- .../mxgraph/config/StyleConfigurator.ts | 46 ++++---- .../mxgraph/renderer/StyleComputer.ts | 18 +-- src/component/mxgraph/renderer/style-utils.ts | 6 +- .../mxgraph/shape/activity-shapes.ts | 10 +- src/component/mxgraph/shape/edges.ts | 6 +- src/component/mxgraph/shape/event-shapes.ts | 6 +- src/component/mxgraph/shape/flow-shapes.ts | 4 +- src/component/mxgraph/shape/gateway-shapes.ts | 6 +- src/component/mxgraph/style/StyleManager.ts | 4 +- src/component/mxgraph/style/types.ts | 5 +- src/component/mxgraph/style/utils.ts | 6 +- test/integration/helpers/model-expect.ts | 4 +- test/integration/matchers/matcher-utils.ts | 6 +- test/integration/matchers/toBeEdge/index.ts | 8 +- test/integration/matchers/toBeShape/index.ts | 6 +- .../mxgraph/renderer/StyleComputer.test.ts | 106 +++++++++--------- .../mxgraph/renderer/style-utils.test.ts | 4 +- 20 files changed, 130 insertions(+), 133 deletions(-) diff --git a/src/component/mxgraph/BpmnRenderer.ts b/src/component/mxgraph/BpmnRenderer.ts index c3e8d9cca2..25927e171c 100644 --- a/src/component/mxgraph/BpmnRenderer.ts +++ b/src/component/mxgraph/BpmnRenderer.ts @@ -21,7 +21,7 @@ import type ShapeBpmnElement from '../../model/bpmn/internal/shape/ShapeBpmnElem import type Bounds from '../../model/bpmn/internal/Bounds'; import { MessageVisibleKind, ShapeUtil } from '../../model/bpmn/internal'; import CoordinatesTranslator from './renderer/CoordinatesTranslator'; -import type { BPMNCellStyle } from './style/types'; +import type { BpmnCellStyle } from './style/types'; import StyleComputer from './renderer/StyleComputer'; import type { BpmnGraph } from './BpmnGraph'; import type { FitOptions, RendererOptions } from '../options'; @@ -123,7 +123,7 @@ export class BpmnRenderer { return this.graph.getDataModel().getCell(id); } - private insertVertex(parent: Cell, id: string | null, value: string, bounds: Bounds, labelBounds: Bounds, style?: BPMNCellStyle): Cell { + private insertVertex(parent: Cell, id: string | null, value: string, bounds: Bounds, labelBounds: Bounds, style?: BpmnCellStyle): Cell { const vertexCoordinates = this.coordinatesTranslator.computeRelativeCoordinates(parent, new Point(bounds.x, bounds.y)); const cell = this.graph.insertVertex({ parent, id, value, position: [vertexCoordinates.x, vertexCoordinates.y], width: bounds.width, height: bounds.height, style }); diff --git a/src/component/mxgraph/GraphCellUpdater.ts b/src/component/mxgraph/GraphCellUpdater.ts index a30388ee91..ad1ceb7a59 100644 --- a/src/component/mxgraph/GraphCellUpdater.ts +++ b/src/component/mxgraph/GraphCellUpdater.ts @@ -25,7 +25,7 @@ import { ensureIsArray } from '../helpers/array-utils'; import { OverlayConverter } from './overlay/OverlayConverter'; import { messageFlowIconId } from './BpmnRenderer'; import { ensureOpacityValue } from '../helpers/validators'; -import type { BPMNCellStyle } from './style/types'; +import type { BpmnCellStyle } from './style/types'; /** * @internal @@ -59,7 +59,7 @@ export default class GraphCellUpdater { this.styleManager.ensureStyleIsStored(cell); - const cellStyle: BPMNCellStyle = getCellStyleClone(cell); + const cellStyle: BpmnCellStyle = getCellStyleClone(cell); setCssClasses(cellStyle, cssClasses); model.setStyle(cell, cellStyle); diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index 62ca59f0fe..af4977ea01 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -36,7 +36,7 @@ import { TextAnnotationShape } from '../shape/text-annotation-shapes'; import { MessageFlowIconShape } from '../shape/flow-shapes'; import { BpmnStyleIdentifier } from '../style'; import { computeAllBpmnClassNamesOfCell } from '../renderer/style-utils'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; import { MxGraphCustomOverlay } from '../overlay/custom-overlay'; import { OverlayBadgeShape } from '../overlay/shapes'; import { BpmnConnector } from '../shape/edges'; @@ -172,7 +172,7 @@ export default class ShapeConfigurator { // TODO maxgraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided."constants.DIALECT.STRICTHTML let allBpmnClassNames = computeAllBpmnClassNamesOfCell(cell, this.dialect === 'strictHtml'); // TODO maxgraph@0.1.0 - do we need to introduce a BpmnCellStateStyle type (to not have the baseStyleName property)? - const extraCssClasses = (this.state.style as BPMNCellStyle).bpmn?.extraCssClasses; + const extraCssClasses = (this.state.style as BpmnCellStyle).bpmn?.extraCssClasses; if (extraCssClasses) { allBpmnClassNames = allBpmnClassNames.concat(extraCssClasses); } diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index a5a7da2c02..dd979ae917 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -17,7 +17,7 @@ limitations under the License. import { AssociationDirectionKind, FlowKind, SequenceFlowKind, ShapeBpmnElementKind, ShapeUtil } from '../../../model/bpmn/internal'; import { BpmnStyleIdentifier, MarkerIdentifier, StyleDefault } from '../style'; import type { BpmnGraph } from '../BpmnGraph'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; import { constants, Perimeter } from '@maxgraph/core'; import type { Stylesheet } from '@maxgraph/core'; @@ -37,13 +37,13 @@ export class StyleConfigurator { private specificFlowStyles = new MapWithDefault([ [ FlowKind.SEQUENCE_FLOW, - (style: BPMNCellStyle) => { + (style: BpmnCellStyle) => { style.endArrow = 'blockThin'; }, ], [ FlowKind.MESSAGE_FLOW, - (style: BPMNCellStyle) => { + (style: BpmnCellStyle) => { style.dashed = true; style.dashPattern = '8 5'; style.startArrow = 'oval'; @@ -57,7 +57,7 @@ export class StyleConfigurator { ], [ FlowKind.ASSOCIATION_FLOW, - (style: BPMNCellStyle) => { + (style: BpmnCellStyle) => { style.dashed = true; style.dashPattern = '1 2'; // endArrow and startArrow are defined in specific AssociationDirectionKind styles when needed @@ -68,13 +68,13 @@ export class StyleConfigurator { private specificSequenceFlowStyles = new MapWithDefault([ [ SequenceFlowKind.DEFAULT, - (style: BPMNCellStyle) => { + (style: BpmnCellStyle) => { style.startArrow = MarkerIdentifier.ARROW_DASH; }, ], [ SequenceFlowKind.CONDITIONAL_FROM_ACTIVITY, - (style: BPMNCellStyle) => { + (style: BpmnCellStyle) => { style.startArrow = 'diamondThin'; style.startSize = 18; style.startFill = true; // TODO maxgraph@0.1.0 could be removed when maxGraph fixes https://github.com/maxGraph/maxGraph/pull/157 @@ -86,19 +86,19 @@ export class StyleConfigurator { [ AssociationDirectionKind.NONE, // eslint-disable-next-line @typescript-eslint/no-unused-vars -- prefix parameter name - common practice to acknowledge the fact that some parameter is unused (e.g. in TypeScript compiler) - (_style: BPMNCellStyle) => { + (_style: BpmnCellStyle) => { // the style is fully managed by the FlowKind.ASSOCIATION_FLOW style }, ], [ AssociationDirectionKind.ONE, - (style: BPMNCellStyle) => { + (style: BpmnCellStyle) => { style.endArrow = 'openThin'; }, ], [ AssociationDirectionKind.BOTH, - (style: BPMNCellStyle) => { + (style: BpmnCellStyle) => { style.endArrow = 'openThin'; style.startArrow = 'openThin'; }, @@ -128,7 +128,7 @@ export class StyleConfigurator { return this.graph.getStylesheet(); } - private putCellStyle(name: ShapeBpmnElementKind, style: BPMNCellStyle): void { + private putCellStyle(name: ShapeBpmnElementKind, style: BpmnCellStyle): void { this.getStylesheet().putCellStyle(name, style); } @@ -141,7 +141,7 @@ export class StyleConfigurator { } private configurePoolStyle(): void { - const style: BPMNCellStyle = { + const style: BpmnCellStyle = { shape: constants.SHAPE.SWIMLANE, // label style verticalAlign: 'middle', @@ -154,7 +154,7 @@ export class StyleConfigurator { } private configureLaneStyle(): void { - const style: BPMNCellStyle = { + const style: BpmnCellStyle = { shape: constants.SHAPE.SWIMLANE, // label style verticalAlign: 'middle', @@ -169,7 +169,7 @@ export class StyleConfigurator { private configureEventStyles(): void { ShapeUtil.eventKinds().forEach(kind => { - const style: BPMNCellStyle = { + const style: BpmnCellStyle = { shape: kind, // TODO maxgraph@0.10.1 decide if we use the function or the string to set the perimeter perimeter: Perimeter.EllipsePerimeter, @@ -181,7 +181,7 @@ export class StyleConfigurator { } private configureTextAnnotationStyle(): void { - const style: BPMNCellStyle = { + const style: BpmnCellStyle = { shape: ShapeBpmnElementKind.TEXT_ANNOTATION, // label style verticalAlign: 'middle', @@ -194,7 +194,7 @@ export class StyleConfigurator { } private configureGroupStyle(): void { - const style: BPMNCellStyle = { + const style: BpmnCellStyle = { rounded: true, dashed: true, dashPattern: '7 4 1 4', @@ -209,7 +209,7 @@ export class StyleConfigurator { private configureActivityStyles(): void { ShapeUtil.activityKinds().forEach(kind => { - const style: BPMNCellStyle = { + const style: BpmnCellStyle = { shape: kind, rounded: true, // required by the BPMN specification verticalAlign: 'middle', // label style @@ -221,7 +221,7 @@ export class StyleConfigurator { private configureGatewayStyles(): void { ShapeUtil.gatewayKinds().forEach(kind => { - const style: BPMNCellStyle = { + const style: BpmnCellStyle = { shape: kind, // TODO maxgraph@0.10.1 decide if we use the function or the string to set the perimeter perimeter: Perimeter.RhombusPerimeter, @@ -237,7 +237,7 @@ export class StyleConfigurator { } private configureDefaultEdgeStyle(): void { - const style = this.getStylesheet().getDefaultEdgeStyle() as BPMNCellStyle; + const style = this.getStylesheet().getDefaultEdgeStyle() as BpmnCellStyle; configureCommonDefaultStyle(style); style.shape = BpmnStyleIdentifier.EDGE; @@ -251,9 +251,9 @@ export class StyleConfigurator { delete style.endArrow; } - private configureEdgeStyles(styleKinds: T[], specificStyles: Map void>): void { + private configureEdgeStyles(styleKinds: T[], specificStyles: Map void>): void { styleKinds.forEach(kind => { - const style: BPMNCellStyle = {}; + const style: BpmnCellStyle = {}; specificStyles.get(kind)(style); this.graph.getStylesheet().putCellStyle(kind.toString(), style); }); @@ -266,7 +266,7 @@ export class StyleConfigurator { } } -function configureCommonDefaultStyle(style: BPMNCellStyle): void { +function configureCommonDefaultStyle(style: BpmnCellStyle): void { style.fontFamily = StyleDefault.DEFAULT_FONT_FAMILY; style.fontSize = StyleDefault.DEFAULT_FONT_SIZE; style.fontColor = StyleDefault.DEFAULT_FONT_COLOR; @@ -278,8 +278,8 @@ function configureCommonDefaultStyle(style: BPMNCellStyle): void { style.whiteSpace = 'wrap'; } -class MapWithDefault extends Map void> { - override get(key: T): (style: BPMNCellStyle) => void { +class MapWithDefault extends Map void> { + override get(key: T): (style: BpmnCellStyle) => void { return ( super.get(key) ?? (() => { diff --git a/src/component/mxgraph/renderer/StyleComputer.ts b/src/component/mxgraph/renderer/StyleComputer.ts index 162d364dfc..06ce707bd0 100644 --- a/src/component/mxgraph/renderer/StyleComputer.ts +++ b/src/component/mxgraph/renderer/StyleComputer.ts @@ -34,7 +34,7 @@ import { MessageVisibleKind, ShapeBpmnCallActivityKind, ShapeBpmnElementKind, Sh import { AssociationFlow, SequenceFlow } from '../../../model/bpmn/internal/edge/flows'; import type { Font } from '../../../model/bpmn/internal/Label'; import type { RendererOptions } from '../../options'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; /** * @internal @@ -46,8 +46,8 @@ export default class StyleComputer { this.ignoreBpmnColors = options?.ignoreBpmnColors ?? true; } - computeStyle(bpmnCell: Shape | Edge, labelBounds: Bounds): BPMNCellStyle { - const style: BPMNCellStyle = { + computeStyle(bpmnCell: Shape | Edge, labelBounds: Bounds): BpmnCellStyle { + const style: BpmnCellStyle = { bpmn: { kind: bpmnCell.bpmnElement.kind }, }; @@ -68,7 +68,7 @@ export default class StyleComputer { return { baseStyleNames, ...style, ...fontStyleValues, ...labelStyleValues }; } - private enrichStyleWithShapeInfo(style: BPMNCellStyle, shape: Shape): void { + private enrichStyleWithShapeInfo(style: BpmnCellStyle, shape: Shape): void { const bpmnElement = shape.bpmnElement; if (bpmnElement instanceof ShapeBpmnEvent) { @@ -98,7 +98,7 @@ export default class StyleComputer { } } - private static computeEventShapeStyle(bpmnElement: ShapeBpmnEvent, style: BPMNCellStyle): void { + private static computeEventShapeStyle(bpmnElement: ShapeBpmnEvent, style: BpmnCellStyle): void { style.bpmn.eventDefinitionKind = bpmnElement.eventDefinitionKind; if (bpmnElement instanceof ShapeBpmnBoundaryEvent || (bpmnElement instanceof ShapeBpmnStartEvent && bpmnElement.isInterrupting !== undefined)) { @@ -106,7 +106,7 @@ export default class StyleComputer { } } - private static computeActivityShapeStyle(bpmnElement: ShapeBpmnActivity, style: BPMNCellStyle): void { + private static computeActivityShapeStyle(bpmnElement: ShapeBpmnActivity, style: BpmnCellStyle): void { if (bpmnElement instanceof ShapeBpmnSubProcess) { style.bpmn.subProcessKind = bpmnElement.subProcessKind; } else if (bpmnElement.kind === ShapeBpmnElementKind.TASK_RECEIVE) { @@ -134,7 +134,7 @@ export default class StyleComputer { return styles; } - private enrichStyleWithEdgeInfo(style: BPMNCellStyle, edge: Edge): void { + private enrichStyleWithEdgeInfo(style: BpmnCellStyle, edge: Edge): void { if (!this.ignoreBpmnColors) { const extensions = edge.extensions; extensions.strokeColor && (style.strokeColor = extensions.strokeColor); @@ -190,8 +190,8 @@ export default class StyleComputer { return style; } - computeMessageFlowIconStyle(edge: Edge): BPMNCellStyle { - const style: BPMNCellStyle = { + computeMessageFlowIconStyle(edge: Edge): BpmnCellStyle { + const style: BpmnCellStyle = { shape: BpmnStyleIdentifier.MESSAGE_FLOW_ICON, bpmn: { isInitiating: edge.messageVisibleKind === MessageVisibleKind.INITIATING }, }; diff --git a/src/component/mxgraph/renderer/style-utils.ts b/src/component/mxgraph/renderer/style-utils.ts index 893183e94e..73087bd056 100644 --- a/src/component/mxgraph/renderer/style-utils.ts +++ b/src/component/mxgraph/renderer/style-utils.ts @@ -17,7 +17,7 @@ limitations under the License. import type { Cell } from '@maxgraph/core'; import { FlowKind, ShapeUtil } from '../../../model/bpmn/internal'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; /** * Compute the all class names associated to a cell in a hyphen case form. @@ -27,7 +27,7 @@ import type { BPMNCellStyle } from '../style/types'; * @internal */ export function computeAllBpmnClassNamesOfCell(cell: Cell, isLabel: boolean): string[] { - return computeAllBpmnClassNames(cell.style as BPMNCellStyle, isLabel); + return computeAllBpmnClassNames(cell.style as BpmnCellStyle, isLabel); } /** @@ -37,7 +37,7 @@ export function computeAllBpmnClassNamesOfCell(cell: Cell, isLabel: boolean): st * @param isLabel the boolean that indicates if class must be computed for label. * @internal exported for testing purpose */ -export function computeAllBpmnClassNames(style: BPMNCellStyle, isLabel: boolean): string[] { +export function computeAllBpmnClassNames(style: BpmnCellStyle, isLabel: boolean): string[] { const classes: string[] = []; // if kind is not set, check shape: bpmn.message-flow-icon --> message-flow-icon diff --git a/src/component/mxgraph/shape/activity-shapes.ts b/src/component/mxgraph/shape/activity-shapes.ts index 411500117f..474d4b7f09 100644 --- a/src/component/mxgraph/shape/activity-shapes.ts +++ b/src/component/mxgraph/shape/activity-shapes.ts @@ -17,7 +17,7 @@ limitations under the License. import type { AbstractCanvas2D } from '@maxgraph/core'; import { RectangleShape } from '@maxgraph/core'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; import { StyleDefault } from '../style'; import type { BpmnCanvas, PaintParameter, ShapeConfiguration } from './render'; import { IconPainterProvider } from './render'; @@ -51,7 +51,7 @@ export abstract class BaseActivityShape extends RectangleShape { } protected paintMarkerIcons(paintParameter: PaintParameter): void { - const markers = (this.style as BPMNCellStyle).bpmn.markers; + const markers = (this.style as BpmnCellStyle).bpmn.markers; if (markers) { orderActivityMarkers(markers).forEach((marker, idx, allMarkers) => { paintParameter = { @@ -140,7 +140,7 @@ export class UserTaskShape extends BaseTaskShape { */ export class ReceiveTaskShape extends BaseTaskShape { protected paintTaskIcon(paintParameter: PaintParameter): void { - if (!(this.style as BPMNCellStyle).bpmn.isInstantiating) { + if (!(this.style as BpmnCellStyle).bpmn.isInstantiating) { paintEnvelopeIcon(paintParameter, false); return; } @@ -212,7 +212,7 @@ export class CallActivityShape extends BaseActivityShape { const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this }); - switch ((this.style as BPMNCellStyle).bpmn.globalTaskKind) { + switch ((this.style as BpmnCellStyle).bpmn.globalTaskKind) { case ShapeBpmnElementKind.GLOBAL_TASK_MANUAL: this.iconPainter.paintHandIcon({ ...paintParameter, @@ -252,7 +252,7 @@ export class CallActivityShape extends BaseActivityShape { */ export class SubProcessShape extends BaseActivityShape { override paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { - const subProcessKind = (this.style as BPMNCellStyle).bpmn.subProcessKind; + const subProcessKind = (this.style as BpmnCellStyle).bpmn.subProcessKind; c.save(); // ensure we can later restore the configuration if (subProcessKind === ShapeBpmnSubProcessKind.EVENT) { c.setDashed(true, false); diff --git a/src/component/mxgraph/shape/edges.ts b/src/component/mxgraph/shape/edges.ts index dcea9036e8..d425877d5a 100644 --- a/src/component/mxgraph/shape/edges.ts +++ b/src/component/mxgraph/shape/edges.ts @@ -17,7 +17,7 @@ limitations under the License. import type { Point, AbstractCanvas2D } from '@maxgraph/core'; import { SvgCanvas2D, ConnectorShape } from '@maxgraph/core'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; // TODO maxgraph@0.1.0 remove the BpmnConnector class to use the new support of endFillColor and starFillColor provided by https://github.com/maxGraph/maxGraph/issues/201 export class BpmnConnector extends ConnectorShape { @@ -39,12 +39,12 @@ export class BpmnConnector extends ConnectorShape { c.setDashed(false, false); if (sourceMarker != null) { - c.setFillColor((this.style as BPMNCellStyle).startFillColor ?? this.stroke); + c.setFillColor((this.style as BpmnCellStyle).startFillColor ?? this.stroke); sourceMarker(); } if (targetMarker != null) { - c.setFillColor((this.style as BPMNCellStyle).endFillColor ?? this.stroke); + c.setFillColor((this.style as BpmnCellStyle).endFillColor ?? this.stroke); targetMarker(); } } diff --git a/src/component/mxgraph/shape/event-shapes.ts b/src/component/mxgraph/shape/event-shapes.ts index fa3654c5ef..9c06b6fa7b 100644 --- a/src/component/mxgraph/shape/event-shapes.ts +++ b/src/component/mxgraph/shape/event-shapes.ts @@ -21,7 +21,7 @@ import { ShapeBpmnEventDefinitionKind } from '../../../model/bpmn/internal'; import type { BpmnCanvas, PaintParameter } from './render'; import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; import { StyleDefault } from '../style'; /** @@ -90,7 +90,7 @@ export class EventShape extends EllipseShape { override paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this, isFilled: this.withFilledIcon }); - EventShape.setDashedOuterShapePattern(paintParameter, (this.style as BPMNCellStyle).bpmn.isInterrupting); + EventShape.setDashedOuterShapePattern(paintParameter, (this.style as BpmnCellStyle).bpmn.isInterrupting); this.paintOuterShape(paintParameter); EventShape.restoreOriginalOuterShapePattern(paintParameter); @@ -102,7 +102,7 @@ export class EventShape extends EllipseShape { } private paintInnerShape(paintParameter: PaintParameter): void { - const paintIcon = this.iconPainters.get((this.style as BPMNCellStyle).bpmn.eventDefinitionKind) || (() => this.iconPainter.paintEmptyIcon()); + const paintIcon = this.iconPainters.get((this.style as BpmnCellStyle).bpmn.eventDefinitionKind) || (() => this.iconPainter.paintEmptyIcon()); paintIcon(paintParameter); } diff --git a/src/component/mxgraph/shape/flow-shapes.ts b/src/component/mxgraph/shape/flow-shapes.ts index 55186f3337..354cae311b 100644 --- a/src/component/mxgraph/shape/flow-shapes.ts +++ b/src/component/mxgraph/shape/flow-shapes.ts @@ -16,7 +16,7 @@ limitations under the License. import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; import { RectangleShape } from '@maxgraph/core'; import type { AbstractCanvas2D, Rectangle } from '@maxgraph/core'; @@ -39,7 +39,7 @@ export class MessageFlowIconShape extends RectangleShape { height: h, shape: this, ratioFromParent: 1, - isFilled: !((this.style as BPMNCellStyle).bpmn.isInitiating ?? true), + isFilled: !((this.style as BpmnCellStyle).bpmn.isInitiating ?? true), }); this.iconPainter.paintEnvelopeIcon(paintParameter); diff --git a/src/component/mxgraph/shape/gateway-shapes.ts b/src/component/mxgraph/shape/gateway-shapes.ts index 6546eac71b..a294065c18 100644 --- a/src/component/mxgraph/shape/gateway-shapes.ts +++ b/src/component/mxgraph/shape/gateway-shapes.ts @@ -22,7 +22,7 @@ import { StyleDefault } from '../style'; import type { PaintParameter } from './render'; import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; abstract class GatewayShape extends RhombusShape { protected iconPainter = IconPainterProvider.get(); @@ -104,7 +104,7 @@ export class EventBasedGatewayShape extends GatewayShape { ...paintParameter, ratioFromParent: 0.55, }); - if (!(this.style as BPMNCellStyle).bpmn.isInstantiating) { + if (!(this.style as BpmnCellStyle).bpmn.isInstantiating) { this.iconPainter.paintCircleIcon({ ...paintParameter, ratioFromParent: 0.45, @@ -116,7 +116,7 @@ export class EventBasedGatewayShape extends GatewayShape { ...paintParameter, ratioFromParent: 0.3, }; - if ((this.style as BPMNCellStyle).bpmn.gatewayKind == ShapeBpmnEventBasedGatewayKind.Parallel) { + if ((this.style as BpmnCellStyle).bpmn.gatewayKind == ShapeBpmnEventBasedGatewayKind.Parallel) { this.iconPainter.paintPlusCrossIcon(innerIconPaintParameter); } else { this.iconPainter.paintPentagon(innerIconPaintParameter); diff --git a/src/component/mxgraph/style/StyleManager.ts b/src/component/mxgraph/style/StyleManager.ts index a3ae8ef905..da1c0055a5 100644 --- a/src/component/mxgraph/style/StyleManager.ts +++ b/src/component/mxgraph/style/StyleManager.ts @@ -16,7 +16,7 @@ limitations under the License. import type { Cell, CellStyle, GraphDataModel } from '@maxgraph/core'; import { getCellStyleClone, setCssClasses } from './utils'; import type { CssRegistry } from '../../registry/css-registry'; -import type { BPMNCellStyle } from '../style/types'; +import type { BpmnCellStyle } from '../style/types'; export class StyleManager { private stylesCache: Map = new Map(); @@ -47,7 +47,7 @@ export class StyleManager { } } - private resetStyle(cellId: string, style: BPMNCellStyle): void { + private resetStyle(cellId: string, style: BpmnCellStyle): void { const cell = this.model.getCell(cellId); // TODO maxGraph 0.10.1 - inline in master branch (from maxgraph@0.1.0 migration) const cssClasses = this.cssRegistry.getClassNames(cellId); diff --git a/src/component/mxgraph/style/types.ts b/src/component/mxgraph/style/types.ts index a449a7eb90..20b244010c 100644 --- a/src/component/mxgraph/style/types.ts +++ b/src/component/mxgraph/style/types.ts @@ -27,10 +27,7 @@ import type { ShapeBpmnSubProcessKind, } from '../../../model/bpmn/internal'; -// TODO maxgraph@0.1.0 rename for consistent naming BPMNCellStyle --> BpmnCellStyle (apply to other places) -// a BpmnCellStyle exists in tests. Try to use this one instead -// TODO maxgraph@0.1.0 sort properties in alphabetical order for clarity (and as done in maxGraph CellStyle) and provide documentation about each property -export interface BPMNCellStyle extends CellStyle { +export interface BpmnCellStyle extends CellStyle { bpmn?: { associationDirectionKind?: AssociationDirectionKind; eventDefinitionKind?: ShapeBpmnEventDefinitionKind; diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index b6df55b71e..362baaa1b9 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -18,7 +18,7 @@ import type { Cell, CellStyle, NumericCellStateStyleKeys } from '@maxgraph/core' import { constants } from '@maxgraph/core'; import { styleUtils } from '@maxgraph/core'; -import type { BPMNCellStyle } from './types'; +import type { BpmnCellStyle } from './types'; import { ensureOpacityValue, ensureStrokeWidthValue } from '../../helpers/validators'; import type { Fill, Font, ShapeStyleUpdate, Stroke, StyleUpdate } from '../../registry'; import { ShapeUtil } from '../../../model/bpmn/internal'; @@ -126,7 +126,7 @@ export const updateFont = (cellStyle: CellStyle, font: Font): void => { } }; -export const updateFill = (cellStyle: BPMNCellStyle, fill: Fill): void => { +export const updateFill = (cellStyle: BpmnCellStyle, fill: Fill): void => { if (fill.color) { setStyle(cellStyle, 'fillColor', fill.color, convertDefaultValue); @@ -143,7 +143,7 @@ export const isShapeStyleUpdate = (style: StyleUpdate): style is ShapeStyleUpdat return style && typeof style === 'object' && 'fill' in style; }; -export function setCssClasses(cellStyle: BPMNCellStyle, cssClasses: string[]): void { +export function setCssClasses(cellStyle: BpmnCellStyle, cssClasses: string[]): void { if (cssClasses.length > 0) { cellStyle.bpmn.extraCssClasses = cssClasses; } else { diff --git a/test/integration/helpers/model-expect.ts b/test/integration/helpers/model-expect.ts index 90f02383c5..d0c9ce7c5c 100644 --- a/test/integration/helpers/model-expect.ts +++ b/test/integration/helpers/model-expect.ts @@ -62,7 +62,7 @@ import { import type { StyleArrowValue, Cell, FilterFunction, Geometry, ShapeValue } from '@maxgraph/core'; import type { ExpectedOverlay } from '../matchers/matcher-utils'; import { getCell } from '../matchers/matcher-utils'; -import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; +import type { BpmnCellStyle } from '@lib/component/mxgraph/style/types'; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace @@ -237,7 +237,7 @@ const expectElementsInModel = (parentId: string, elementsNumber: number, filter: export const expectPoolsInModel = (pools: number): void => { expectElementsInModel(undefined, pools, (cell: Cell): boolean => { - return cell != getDefaultParent() && (cell.style as BPMNCellStyle).bpmn.kind == ShapeBpmnElementKind.POOL; + return cell != getDefaultParent() && (cell.style as BpmnCellStyle).bpmn.kind == ShapeBpmnElementKind.POOL; }); }; diff --git a/test/integration/matchers/matcher-utils.ts b/test/integration/matchers/matcher-utils.ts index 5b8ae31a99..810ce0428e 100644 --- a/test/integration/matchers/matcher-utils.ts +++ b/test/integration/matchers/matcher-utils.ts @@ -25,7 +25,7 @@ import type { Opacity } from '@lib/component/registry'; import type { MxGraphCustomOverlay, MxGraphCustomOverlayStyle } from '@lib/component/mxgraph/overlay/custom-overlay'; import { getFontStyleValue as computeFontStyleValue } from '@lib/component/mxgraph/renderer/StyleComputer'; import { Font } from '@lib/model/bpmn/internal/Label'; -import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; +import type { BpmnCellStyle } from '@lib/component/mxgraph/style/types'; /** * Used in test to compare the expected and received styles. @@ -60,7 +60,7 @@ export interface ExpectedCell { value?: string; geometry?: Geometry; /** the Cell style property or a jest expect using a regexp. */ - styleRawFromModelOrJestExpect?: BPMNCellStyle; + styleRawFromModelOrJestExpect?: BpmnCellStyle; /** * The style of the Cell in the model where all properties have been resolved by also applying properties coming from the referenced styles. * @@ -188,7 +188,7 @@ export function buildReceivedResolvedModelCellStyle(cell: Cell, bv = bpmnVisuali return toBpmnStyle(bv.graph.getCellStyle(cell), cell.edge); } -function toBpmnStyle(rawStyle: BPMNCellStyle, isEdge: boolean): ComparedBpmnCellStyle { +function toBpmnStyle(rawStyle: BpmnCellStyle, isEdge: boolean): ComparedBpmnCellStyle { const style: ComparedBpmnCellStyle = { opacity: rawStyle.opacity, verticalAlign: rawStyle.verticalAlign, diff --git a/test/integration/matchers/toBeEdge/index.ts b/test/integration/matchers/toBeEdge/index.ts index fc194fed0b..a47d6a844e 100644 --- a/test/integration/matchers/toBeEdge/index.ts +++ b/test/integration/matchers/toBeEdge/index.ts @@ -22,7 +22,7 @@ import { AssociationDirectionKind, FlowKind, MessageVisibleKind, SequenceFlowKin import type { ExpectedAssociationFlowModelElement, ExpectedEdgeModelElement, ExpectedSequenceFlowModelElement } from '../../helpers/model-expect'; import { getDefaultParentId } from '../../helpers/model-expect'; import { BpmnStyleIdentifier } from '@lib/component/mxgraph/style'; -import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; +import type { BpmnCellStyle } from '@lib/component/mxgraph/style/types'; import MatcherContext = jest.MatcherContext; import CustomMatcherResult = jest.CustomMatcherResult; @@ -46,8 +46,8 @@ function buildExpectedMsgFlowIconCellStyle(expectedModel: ExpectedEdgeModelEleme return style; } -function buildExpectedEdgeStylePropertyRegexp(expectedModel: ExpectedEdgeModelElement | ExpectedSequenceFlowModelElement | ExpectedAssociationFlowModelElement): BPMNCellStyle { - const style: BPMNCellStyle = { bpmn: {} }; +function buildExpectedEdgeStylePropertyRegexp(expectedModel: ExpectedEdgeModelElement | ExpectedSequenceFlowModelElement | ExpectedAssociationFlowModelElement): BpmnCellStyle { + const style: BpmnCellStyle = { bpmn: {} }; // TODO maxgraph@0.1.0 share with shape or remove style.baseStyleNames = [expectedModel.kind]; style.bpmn.kind = expectedModel.kind; @@ -85,7 +85,7 @@ function buildExpectedCell(id: string, expectedModel: ExpectedEdgeModelElement | { id: `messageFlowIcon_of_${id}`, value: null, // maxGraph now set to 'null', mxGraph set to 'undefined' - styleRawFromModelOrJestExpect: expect.objectContaining({ + styleRawFromModelOrJestExpect: expect.objectContaining({ // TODO maxgraph@0.1.0 remove forcing type when maxGraph fixes its types shape: BpmnStyleIdentifier.MESSAGE_FLOW_ICON, // TODO maxgraph@0.1.0 duplicated logic to compute the 'isInitiating' property. Update the expectedModel to store a boolean instead of a string diff --git a/test/integration/matchers/toBeShape/index.ts b/test/integration/matchers/toBeShape/index.ts index 4731379122..36fe1e2c4b 100644 --- a/test/integration/matchers/toBeShape/index.ts +++ b/test/integration/matchers/toBeShape/index.ts @@ -29,7 +29,7 @@ import { getDefaultParentId } from '../../helpers/model-expect'; import { ShapeBpmnElementKind, ShapeBpmnEventBasedGatewayKind, ShapeBpmnMarkerKind, ShapeBpmnSubProcessKind } from '@lib/model/bpmn/internal'; import MatcherContext = jest.MatcherContext; import CustomMatcherResult = jest.CustomMatcherResult; -import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; +import type { BpmnCellStyle } from '@lib/component/mxgraph/style/types'; function expectedStrokeWidth(kind: ShapeBpmnElementKind): number { return [ @@ -94,8 +94,8 @@ function buildExpectedShapeStylePropertyRegexp( | ExpectedBoundaryEventModelElement | ExpectedEventBasedGatewayModelElement | ExpectedCallActivityModelElement, -): BPMNCellStyle { - const style: BPMNCellStyle = { bpmn: {} }; +): BpmnCellStyle { + const style: BpmnCellStyle = { bpmn: {} }; // TODO maxgraph@0.1.0 share with edge style.baseStyleNames = [expectedModel.kind]; style.bpmn.kind = expectedModel.kind; diff --git a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts index 0c2136d02d..435d132279 100644 --- a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts +++ b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts @@ -17,7 +17,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; +import type { BpmnCellStyle } from '@lib/component/mxgraph/style/types'; import StyleComputer from '@lib/component/mxgraph/renderer/StyleComputer'; import Shape from '@lib/model/bpmn/internal/shape/Shape'; import ShapeBpmnElement, { @@ -132,19 +132,19 @@ describe('Style Computer', () => { const styleComputer = new StyleComputer(); // shortcut as the current computeStyle implementation requires to pass the BPMN label bounds as extra argument - function computeStyle(bpmnCell: Shape | Edge): BPMNCellStyle { + function computeStyle(bpmnCell: Shape | Edge): BpmnCellStyle { return styleComputer.computeStyle(bpmnCell, bpmnCell.label?.bounds); } describe('compute style - shape label', () => { it('compute style of shape with no label', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.TASK_USER)); - expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['userTask'], bpmn: { kind: ShapeBpmnElementKind.TASK_USER } }); + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['userTask'], bpmn: { kind: ShapeBpmnElementKind.TASK_USER } }); }); it('compute style of shape with a no font label', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.EVENT_END), undefined, new Label(undefined, undefined)); - expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['endEvent'], bpmn: { kind: ShapeBpmnElementKind.EVENT_END } }); + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['endEvent'], bpmn: { kind: ShapeBpmnElementKind.EVENT_END } }); }); it('compute style of shape with label including bold font', () => { @@ -154,7 +154,7 @@ describe('Style Computer', () => { undefined, new Label(toFont({ name: 'Courier', size: 9, isBold: true }), undefined), ); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['exclusiveGateway'], fontFamily: 'Courier', fontSize: 9, @@ -165,7 +165,7 @@ describe('Style Computer', () => { it('compute style of shape with label including italic font', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH), undefined, new Label(toFont({ name: 'Arial', isItalic: true }), undefined)); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['intermediateCatchEvent'], fontFamily: 'Arial', fontStyle: 2, @@ -175,7 +175,7 @@ describe('Style Computer', () => { it('compute style of shape with label including bold/italic font', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW), undefined, new Label(toFont({ isBold: true, isItalic: true }), undefined)); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['intermediateThrowEvent'], fontStyle: 3, bpmn: { kind: ShapeBpmnElementKind.EVENT_INTERMEDIATE_THROW }, @@ -184,7 +184,7 @@ describe('Style Computer', () => { it('compute style of shape with label including font family only', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.TASK_SCRIPT), undefined, new Label(toFont({ name: 'Roboto' }), undefined)); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['scriptTask'], fontFamily: 'Roboto', bpmn: { kind: ShapeBpmnElementKind.TASK_SCRIPT }, @@ -193,7 +193,7 @@ describe('Style Computer', () => { it('compute style of shape with label bounds', () => { const shape = new Shape('id', newShapeBpmnElement(ShapeBpmnElementKind.CALL_ACTIVITY), undefined, new Label(undefined, new Bounds(40, 200, 80, 140))); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['callActivity'], align: 'center', verticalAlign: 'top', @@ -208,7 +208,7 @@ describe('Style Computer', () => { describe('compute style - edge label', () => { it('compute style of edge with no label', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.CONDITIONAL_FROM_GATEWAY)); - expect(computeStyle(edge)).toStrictEqual({ + expect(computeStyle(edge)).toStrictEqual({ baseStyleNames: ['sequenceFlow', 'conditional_from_gateway'], bpmn: { kind: FlowKind.SEQUENCE_FLOW }, }); @@ -216,7 +216,7 @@ describe('Style Computer', () => { it('compute style of edge with a no font label', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.NORMAL), undefined, new Label(undefined, undefined)); - expect(computeStyle(edge)).toStrictEqual({ + expect(computeStyle(edge)).toStrictEqual({ baseStyleNames: ['sequenceFlow', 'normal'], bpmn: { kind: FlowKind.SEQUENCE_FLOW }, }); @@ -224,7 +224,7 @@ describe('Style Computer', () => { it('compute style of edge with label including strike-through font', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.CONDITIONAL_FROM_ACTIVITY), undefined, new Label(toFont({ size: 14.2, isStrikeThrough: true }), undefined)); - expect(computeStyle(edge)).toStrictEqual({ + expect(computeStyle(edge)).toStrictEqual({ baseStyleNames: ['sequenceFlow', 'conditional_from_activity'], fontSize: 14.2, fontStyle: 8, @@ -234,7 +234,7 @@ describe('Style Computer', () => { it('compute style of edge with label including underline font', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.DEFAULT), undefined, new Label(toFont({ isUnderline: true }), undefined)); - expect(computeStyle(edge)).toStrictEqual({ + expect(computeStyle(edge)).toStrictEqual({ baseStyleNames: ['sequenceFlow', 'default'], fontStyle: 4, bpmn: { kind: FlowKind.SEQUENCE_FLOW }, @@ -248,7 +248,7 @@ describe('Style Computer', () => { undefined, new Label(toFont({ isBold: true, isItalic: true, isStrikeThrough: true, isUnderline: true }), undefined), ); - expect(computeStyle(edge)).toStrictEqual({ + expect(computeStyle(edge)).toStrictEqual({ baseStyleNames: ['sequenceFlow', 'normal'], fontStyle: 15, bpmn: { kind: FlowKind.SEQUENCE_FLOW }, @@ -257,7 +257,7 @@ describe('Style Computer', () => { it('compute style of edge with label bounds', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.NORMAL), undefined, new Label(toFont({ name: 'Helvetica' }), new Bounds(20, 20, 30, 120))); - expect(computeStyle(edge)).toStrictEqual({ + expect(computeStyle(edge)).toStrictEqual({ baseStyleNames: ['sequenceFlow', 'normal'], fontFamily: 'Helvetica', align: 'center', @@ -274,7 +274,7 @@ describe('Style Computer', () => { [SequenceFlowKind.NORMAL, 'normal'], ])('compute style - sequence flows: %s', (kind: SequenceFlowKind, expected: string) => { const edge = new Edge('id', newSequenceFlow(kind)); - expect(computeStyle(edge)).toStrictEqual({ + expect(computeStyle(edge)).toStrictEqual({ baseStyleNames: ['sequenceFlow', expected], bpmn: { kind: FlowKind.SEQUENCE_FLOW }, }); @@ -286,7 +286,7 @@ describe('Style Computer', () => { [AssociationDirectionKind.BOTH, 'Both'], ])('compute style - association flows: %s', (kind: AssociationDirectionKind, expected: string) => { const edge = new Edge('id', newAssociationFlow(kind)); - expect(computeStyle(edge)).toStrictEqual({ + expect(computeStyle(edge)).toStrictEqual({ baseStyleNames: ['association', expected], bpmn: { kind: FlowKind.ASSOCIATION_FLOW }, }); @@ -297,7 +297,7 @@ describe('Style Computer', () => { [MessageVisibleKind.INITIATING, true], ])('compute style - message flow icon: %s', (messageVisibleKind: MessageVisibleKind, expected: boolean) => { const edge = new Edge('id', newMessageFlow(), undefined, undefined, messageVisibleKind); - expect(styleComputer.computeMessageFlowIconStyle(edge)).toStrictEqual({ + expect(styleComputer.computeMessageFlowIconStyle(edge)).toStrictEqual({ bpmn: { isInitiating: expected }, // TODO maxGraph@0.10.1 decide if we use BpmnStyleIdentifier const instead shape: 'bpmn.messageFlowIcon', @@ -307,7 +307,7 @@ describe('Style Computer', () => { describe('compute style - events kind', () => { it('intermediate catch conditional', () => { const shape = newShape(newShapeBpmnEvent(ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, ShapeBpmnEventDefinitionKind.CONDITIONAL), newLabel({ name: 'Ubuntu' })); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['intermediateCatchEvent'], fontFamily: 'Ubuntu', bpmn: { kind: ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, eventDefinitionKind: ShapeBpmnEventDefinitionKind.CONDITIONAL }, @@ -316,7 +316,7 @@ describe('Style Computer', () => { it('start signal', () => { const shape = newShape(newShapeBpmnEvent(ShapeBpmnElementKind.EVENT_START, ShapeBpmnEventDefinitionKind.SIGNAL), newLabel({ isBold: true })); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['startEvent'], fontStyle: 1, bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.SIGNAL }, @@ -327,7 +327,7 @@ describe('Style Computer', () => { describe('compute style - boundary events', () => { it('interrupting message', () => { const shape = newShape(newShapeBpmnBoundaryEvent(ShapeBpmnEventDefinitionKind.MESSAGE, true), newLabel({ name: 'Arial' })); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['boundaryEvent'], fontFamily: 'Arial', bpmn: { kind: ShapeBpmnElementKind.EVENT_BOUNDARY, eventDefinitionKind: ShapeBpmnEventDefinitionKind.MESSAGE, isInterrupting: true }, @@ -336,7 +336,7 @@ describe('Style Computer', () => { it('non interrupting timer', () => { const shape = newShape(newShapeBpmnBoundaryEvent(ShapeBpmnEventDefinitionKind.TIMER, false), newLabel({ isItalic: true })); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['boundaryEvent'], fontStyle: 2, bpmn: { kind: ShapeBpmnElementKind.EVENT_BOUNDARY, eventDefinitionKind: ShapeBpmnEventDefinitionKind.TIMER, isInterrupting: false }, @@ -345,7 +345,7 @@ describe('Style Computer', () => { it('cancel with undefined interrupting value', () => { const shape = newShape(newShapeBpmnBoundaryEvent(ShapeBpmnEventDefinitionKind.CANCEL, undefined), newLabel({ isStrikeThrough: true })); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['boundaryEvent'], fontStyle: 8, bpmn: { kind: ShapeBpmnElementKind.EVENT_BOUNDARY, eventDefinitionKind: ShapeBpmnEventDefinitionKind.CANCEL, isInterrupting: true }, @@ -356,7 +356,7 @@ describe('Style Computer', () => { describe('compute style - event sub-process start event', () => { it('interrupting message', () => { const shape = newShape(newShapeBpmnStartEvent(ShapeBpmnEventDefinitionKind.MESSAGE, true), newLabel({ name: 'Arial' })); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['startEvent'], fontFamily: 'Arial', bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.MESSAGE, isInterrupting: true }, @@ -365,7 +365,7 @@ describe('Style Computer', () => { it('non interrupting timer', () => { const shape = newShape(newShapeBpmnStartEvent(ShapeBpmnEventDefinitionKind.TIMER, false), newLabel({ isItalic: true })); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['startEvent'], fontStyle: 2, bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.TIMER, isInterrupting: false }, @@ -374,7 +374,7 @@ describe('Style Computer', () => { it('cancel with undefined interrupting value', () => { const shape = newShape(newShapeBpmnStartEvent(ShapeBpmnEventDefinitionKind.CANCEL, undefined), newLabel({ isStrikeThrough: true })); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['startEvent'], fontStyle: 8, bpmn: { kind: ShapeBpmnElementKind.EVENT_START, eventDefinitionKind: ShapeBpmnEventDefinitionKind.CANCEL }, @@ -392,7 +392,7 @@ describe('Style Computer', () => { it(`${subProcessKind} sub-process without label bounds`, () => { const shape = newShape(newShapeBpmnSubProcess(subProcessKind, markers), newLabel({ name: 'Arial' })); - const expectedStyle = { + const expectedStyle = { baseStyleNames: ['subProcess'], bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind, markers }, fontFamily: 'Arial', @@ -404,7 +404,7 @@ describe('Style Computer', () => { it(`${subProcessKind} sub-process with label bounds`, () => { const shape = newShape(newShapeBpmnSubProcess(subProcessKind, markers), newLabel({ name: 'sans-serif' }, new Bounds(20, 20, 300, 200))); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ align: 'center', baseStyleNames: ['subProcess'], bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, subProcessKind, markers }, @@ -427,7 +427,7 @@ describe('Style Computer', () => { ])(`compute style - %s call activities`, (expandKind: string, markers: ShapeBpmnMarkerKind[]) => { it(`${expandKind} call activity without label bounds`, () => { const shape = newShape(newShapeBpmnCallActivityCallingProcess(markers), newLabel({ name: 'Arial' })); - const expectedStyle = { + const expectedStyle = { baseStyleNames: ['callActivity'], bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, @@ -442,7 +442,7 @@ describe('Style Computer', () => { it(`${expandKind} call activity with label bounds`, () => { const shape = newShape(newShapeBpmnCallActivityCallingProcess(markers), newLabel({ name: 'sans-serif' }, new Bounds(20, 20, 300, 200))); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ align: 'center', baseStyleNames: ['callActivity'], bpmn: { @@ -470,7 +470,7 @@ describe('Style Computer', () => { ])(`compute style - call activities calling %s`, (globalTaskKind: GlobalTaskKind) => { it(`call activity calling ${globalTaskKind} without label bounds`, () => { const shape = newShape(newShapeBpmnCallActivityCallingGlobalTask(globalTaskKind), newLabel({ name: 'Arial' })); - const expectedStyle = { + const expectedStyle = { baseStyleNames: ['callActivity'], bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, globalTaskKind: globalTaskKind, markers: [] }, fontFamily: 'Arial', @@ -480,7 +480,7 @@ describe('Style Computer', () => { it(`call activity calling ${globalTaskKind} with label bounds`, () => { const shape = newShape(newShapeBpmnCallActivityCallingGlobalTask(globalTaskKind), newLabel({ name: 'sans-serif' }, new Bounds(20, 20, 300, 200))); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ align: 'center', baseStyleNames: ['callActivity'], bpmn: { @@ -505,7 +505,7 @@ describe('Style Computer', () => { ['instantiating', true], ])('%s receive task', (instantiatingKind: string, instantiate: boolean) => { const shape = newShape(newShapeBpmnActivity(ShapeBpmnElementKind.TASK_RECEIVE, undefined, instantiate), newLabel({ name: 'Arial' })); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['receiveTask'], bpmn: { kind: ShapeBpmnElementKind.TASK_RECEIVE, isInstantiating: instantiate, markers: [] }, fontFamily: 'Arial', @@ -516,14 +516,14 @@ describe('Style Computer', () => { describe('compute style - text annotation', () => { it('without label', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.TEXT_ANNOTATION)); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['textAnnotation'], bpmn: { kind: ShapeBpmnElementKind.TEXT_ANNOTATION }, }); }); it('with label bounds', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.TEXT_ANNOTATION), newLabel({ name: 'Segoe UI' }, new Bounds(50, 50, 100, 100))); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['textAnnotation'], bpmn: { kind: ShapeBpmnElementKind.TEXT_ANNOTATION, @@ -540,14 +540,14 @@ describe('Style Computer', () => { describe('compute style - group', () => { it('without label', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.GROUP)); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['group'], bpmn: { kind: ShapeBpmnElementKind.GROUP }, }); }); it('with label bounds', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.GROUP), newLabel({ name: 'Roboto' }, new Bounds(50, 50, 100, 100))); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ align: 'center', baseStyleNames: ['group'], bpmn: { @@ -569,7 +569,7 @@ describe('Style Computer', () => { ['undefined', undefined, true], // the parser set a default value in the shape, so this shouldn't be used ])('%s pool references a Process', (title: string, isHorizontal: boolean, expectedStyleIsHorizontal: boolean) => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.POOL), undefined, isHorizontal); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['pool'], horizontal: expectedStyleIsHorizontal, bpmn: { kind: ShapeBpmnElementKind.POOL }, @@ -584,7 +584,7 @@ describe('Style Computer', () => { ['undefined', undefined, true], // the parser set a default value in the shape, so this shouldn't be used ])('%s lane', (title: string, isHorizontal: boolean, expectedStyleIsHorizontal: boolean) => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.LANE), undefined, isHorizontal); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['lane'], horizontal: expectedStyleIsHorizontal, bpmn: { kind: ShapeBpmnElementKind.LANE }, @@ -609,7 +609,7 @@ describe('Style Computer', () => { (markerKind: ShapeBpmnMarkerKind) => { it(`${bpmnKind} with ${markerKind} marker`, () => { const shape = newShape(newShapeBpmnActivity(bpmnKind, [markerKind]), newLabel({ name: 'Arial' })); - const expectedStyle = { + const expectedStyle = { baseStyleNames: [bpmnKind], bpmn: { kind: bpmnKind, markers: [markerKind] }, fontFamily: 'Arial', @@ -622,7 +622,7 @@ describe('Style Computer', () => { it.each(Object.values(ShapeBpmnSubProcessKind))(`%s subProcess with Loop & Expand (collapsed) markers`, (subProcessKind: ShapeBpmnSubProcessKind) => { const markers = [markerKind, ShapeBpmnMarkerKind.EXPAND]; const shape = newShape(newShapeBpmnSubProcess(subProcessKind, markers)); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['subProcess'], bpmn: { kind: ShapeBpmnElementKind.SUB_PROCESS, markers: getExpectedMarkers(markers, subProcessKind), subProcessKind }, }); @@ -632,7 +632,7 @@ describe('Style Computer', () => { if (bpmnKind == ShapeBpmnElementKind.CALL_ACTIVITY) { it(`${bpmnKind} calling process with ${markerKind} & Expand (collapsed) markers`, () => { const shape = newShape(newShapeBpmnCallActivityCallingProcess([markerKind, ShapeBpmnMarkerKind.EXPAND])); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['callActivity'], bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, @@ -650,7 +650,7 @@ describe('Style Computer', () => { [ShapeBpmnElementKind.GLOBAL_TASK_BUSINESS_RULE as GlobalTaskKind], ])(`${bpmnKind} calling global task with ${markerKind} marker`, (globalTaskKind: GlobalTaskKind) => { const shape = newShape(newShapeBpmnCallActivityCallingGlobalTask(globalTaskKind, [markerKind])); - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['callActivity'], bpmn: { kind: ShapeBpmnElementKind.CALL_ACTIVITY, @@ -677,7 +677,7 @@ describe('Style Computer', () => { ({ instantiate, gatewayKind }: { instantiate: boolean; gatewayKind: ShapeBpmnEventBasedGatewayKind }) => { const shape = newShape(newShapeBpmnEventBasedGateway(instantiate, gatewayKind), newLabel({ name: 'Arial' })); gatewayKind ??= ShapeBpmnEventBasedGatewayKind.None; - expect(computeStyle(shape)).toStrictEqual({ + expect(computeStyle(shape)).toStrictEqual({ baseStyleNames: ['eventBasedGateway'], bpmn: { kind: ShapeBpmnElementKind.GATEWAY_EVENT_BASED, gatewayKind, isInstantiating: !!instantiate }, fontFamily: 'Arial', @@ -692,11 +692,11 @@ describe('Style Computer', () => { const styleComputer = new StyleComputer(ignoreBpmnColors === undefined ? {} : { ignoreBpmnColors: ignoreBpmnColors }); const expectAdditionalColorsStyle = !(ignoreBpmnColors ?? true); - function computeStyleWithRendererOptions(element: Shape | Edge): BPMNCellStyle { + function computeStyleWithRendererOptions(element: Shape | Edge): BpmnCellStyle { return styleComputer.computeStyle(element, element.label?.bounds); } - function computeMessageFlowIconStyleWithRendererOptions(edge: Edge): BPMNCellStyle { + function computeMessageFlowIconStyleWithRendererOptions(edge: Edge): BpmnCellStyle { return styleComputer.computeMessageFlowIconStyle(edge); } @@ -705,7 +705,7 @@ describe('Style Computer', () => { const shape = newShape(newShapeBpmnElement(kind), newLabelExtension('#010101')); shape.extensions.fillColor = '#000003'; shape.extensions.strokeColor = '#FF0203'; - const expectedStyle = { + const expectedStyle = { baseStyleNames: [kind], bpmn: { kind: kind }, }; @@ -720,7 +720,7 @@ describe('Style Computer', () => { const shape = newShape(newShapeBpmnElement(kind), newLabelExtension('#aa0101'), true); shape.extensions.fillColor = '#AA0003'; shape.extensions.strokeColor = '#FF02AA'; - const expectedStyle = { + const expectedStyle = { baseStyleNames: [kind], bpmn: { kind: kind }, horizontal: false, @@ -735,7 +735,7 @@ describe('Style Computer', () => { }); it('no extension', () => { const shape = newShape(newShapeBpmnElement(ShapeBpmnElementKind.TASK)); - expect(computeStyleWithRendererOptions(shape)).toStrictEqual({ + expect(computeStyleWithRendererOptions(shape)).toStrictEqual({ baseStyleNames: ['task'], bpmn: { kind: ShapeBpmnElementKind.TASK }, }); @@ -746,7 +746,7 @@ describe('Style Computer', () => { it('sequence flow', () => { const edge = new Edge('id', newSequenceFlow(SequenceFlowKind.DEFAULT), undefined, newLabelExtension('#aaaaaa')); edge.extensions.strokeColor = '#111111'; - const expectedStyle = { + const expectedStyle = { baseStyleNames: ['sequenceFlow', 'default'], bpmn: { kind: FlowKind.SEQUENCE_FLOW }, }; @@ -760,7 +760,7 @@ describe('Style Computer', () => { it('message flow', () => { const edge = new Edge('id', newMessageFlow(), undefined, newLabelExtension('#aaaabb')); edge.extensions.strokeColor = '#1111bb'; - const expectedStyle = { + const expectedStyle = { baseStyleNames: ['messageFlow'], bpmn: { kind: FlowKind.MESSAGE_FLOW }, }; @@ -773,7 +773,7 @@ describe('Style Computer', () => { it('message flow icon', () => { const edge = new Edge('id', newMessageFlow()); edge.extensions.strokeColor = '#11aabb'; - const expectedStyle = { + const expectedStyle = { bpmn: { isInitiating: false }, // TODO maxGraph@0.10.1 decide if we use BpmnStyleIdentifier const instead shape: 'bpmn.messageFlowIcon', @@ -786,7 +786,7 @@ describe('Style Computer', () => { it('association flow', () => { const edge = new Edge('id', newAssociationFlow(AssociationDirectionKind.ONE), undefined, newLabelExtension('#aaaacc')); edge.extensions.strokeColor = '#1111cc'; - const expectedStyle = { + const expectedStyle = { baseStyleNames: ['association', 'One'], bpmn: { kind: FlowKind.ASSOCIATION_FLOW }, }; diff --git a/test/unit/component/mxgraph/renderer/style-utils.test.ts b/test/unit/component/mxgraph/renderer/style-utils.test.ts index abcf419c88..2e3b9e1714 100644 --- a/test/unit/component/mxgraph/renderer/style-utils.test.ts +++ b/test/unit/component/mxgraph/renderer/style-utils.test.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { BPMNCellStyle } from '@lib/component/mxgraph/style/types'; +import type { BpmnCellStyle } from '@lib/component/mxgraph/style/types'; import { FlowKind, ShapeBpmnElementKind, ShapeBpmnEventBasedGatewayKind, ShapeBpmnEventDefinitionKind, ShapeBpmnSubProcessKind } from '@lib/model/bpmn/internal'; import { computeBpmnBaseClassName, computeAllBpmnClassNames } from '@lib/component/mxgraph/renderer/style-utils'; @@ -73,7 +73,7 @@ describe('compute all css class names based on style input', () => { `( // TODO maxgraph@0.1.0 find a way to correctly display the style object 'style="$style" / isLabel=$isLabel', - ({ style, isLabel, expectedClassNames }: { style: BPMNCellStyle; isLabel: boolean; expectedClassNames: string[] }) => { + ({ style, isLabel, expectedClassNames }: { style: BpmnCellStyle; isLabel: boolean; expectedClassNames: string[] }) => { expect(computeAllBpmnClassNames(style, isLabel)).toEqual(expectedClassNames); }, ); From c7e5142050cf7f2f5bfda8604a8a9520caade17c Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 18:02:29 +0200 Subject: [PATCH 56/90] test: Remove "align" types and use maxGraph "align" type instead (they are used to define related maxGraph properties) --- test/integration/helpers/model-expect.ts | 11 +++-------- test/integration/matchers/matcher-utils.ts | 8 ++++---- test/integration/mxGraph.model.style.api.test.ts | 10 +++++----- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/test/integration/helpers/model-expect.ts b/test/integration/helpers/model-expect.ts index d0c9ce7c5c..a28d7bcc62 100644 --- a/test/integration/helpers/model-expect.ts +++ b/test/integration/helpers/model-expect.ts @@ -59,7 +59,7 @@ import { toBeTextAnnotation, toBeUserTask, } from '../matchers'; -import type { StyleArrowValue, Cell, FilterFunction, Geometry, ShapeValue } from '@maxgraph/core'; +import type { AlignValue, StyleArrowValue, Cell, FilterFunction, Geometry, ShapeValue, VAlignValue } from '@maxgraph/core'; import type { ExpectedOverlay } from '../matchers/matcher-utils'; import { getCell } from '../matchers/matcher-utils'; import type { BpmnCellStyle } from '@lib/component/mxgraph/style/types'; @@ -153,19 +153,14 @@ export interface ExpectedFont { opacity?: Opacity; } -// TODO maxGraph@0.1.0 do we keep HorizontalAlign, we could use AlignValue instead -export type HorizontalAlign = 'center' | 'left' | 'right'; -// TODO maxGraph@0.1.0 do we keep VerticalAlign, we could use VAlignValue instead -export type VerticalAlign = 'bottom' | 'middle' | 'top'; - type ExpectedModelElement = { - align?: HorizontalAlign; + align?: AlignValue; font?: ExpectedFont; label?: string; overlays?: ExpectedOverlay[]; parentId?: string; stroke?: Stroke; - verticalAlign?: VerticalAlign; + verticalAlign?: VAlignValue; opacity?: number; // custom bpmn-visualization extraCssClasses?: string[]; diff --git a/test/integration/matchers/matcher-utils.ts b/test/integration/matchers/matcher-utils.ts index 810ce0428e..824fc922d3 100644 --- a/test/integration/matchers/matcher-utils.ts +++ b/test/integration/matchers/matcher-utils.ts @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { Cell, Geometry } from '@maxgraph/core'; +import type { AlignValue, Cell, Geometry, VAlignValue } from '@maxgraph/core'; import MatcherContext = jest.MatcherContext; import CustomMatcherResult = jest.CustomMatcherResult; -import type { ExpectedEdgeModelElement, ExpectedFont, ExpectedShapeModelElement, HorizontalAlign, VerticalAlign } from '../helpers/model-expect'; +import type { ExpectedEdgeModelElement, ExpectedFont, ExpectedShapeModelElement } from '../helpers/model-expect'; import { bpmnVisualization } from '../helpers/model-expect'; import type { Opacity } from '@lib/component/registry'; import type { MxGraphCustomOverlay, MxGraphCustomOverlayStyle } from '@lib/component/mxgraph/overlay/custom-overlay'; @@ -32,8 +32,8 @@ import type { BpmnCellStyle } from '@lib/component/mxgraph/style/types'; */ export interface ComparedBpmnCellStyle { opacity: Opacity; - verticalAlign?: VerticalAlign; - align?: HorizontalAlign; + verticalAlign?: VAlignValue; + align?: AlignValue; strokeWidth?: 'default' | number; strokeColor: string; strokeOpacity: Opacity; diff --git a/test/integration/mxGraph.model.style.api.test.ts b/test/integration/mxGraph.model.style.api.test.ts index 34a4d5fb24..6e4971be6c 100644 --- a/test/integration/mxGraph.model.style.api.test.ts +++ b/test/integration/mxGraph.model.style.api.test.ts @@ -16,7 +16,7 @@ limitations under the License. import { initializeBpmnVisualizationWithContainerId } from './helpers/bpmn-visualization-initialization'; import { HtmlElementLookup } from './helpers/html-utils'; -import type { ExpectedShapeModelElement, VerticalAlign } from './helpers/model-expect'; +import type { ExpectedShapeModelElement } from './helpers/model-expect'; import { bpmnVisualization } from './helpers/model-expect'; import { buildReceivedResolvedModelCellStyle, buildReceivedViewStateStyle } from './matchers/matcher-utils'; import { buildExpectedShapeCellStyle } from './matchers/toBeShape'; @@ -769,11 +769,11 @@ describe('mxGraph model - update style', () => { bv.bpmnElementsRegistry.updateStyle(bpmnElementId, { stroke: { color: strokeColor } }); } - const expectedModel = { + const expectedModel: ExpectedShapeModelElement = { extraCssClasses: ['class-1', 'class-2'], kind: ShapeBpmnElementKind.EVENT_END, stroke: { color: strokeColor }, - verticalAlign: 'top', // when events have a label + verticalAlign: 'top', // when events have a label }; checkModelStyle(bpmnElementId, expectedModel); checkViewStateStyle(bpmnElementId, expectedModel); @@ -1087,10 +1087,10 @@ describe('mxGraph model - reset style', () => { } // Check that the style has been reset to default values for each element - const expectedModel = { + const expectedModel: ExpectedShapeModelElement = { extraCssClasses: ['class-1', 'class-2'], kind: ShapeBpmnElementKind.EVENT_END, - verticalAlign: 'top' as VerticalAlign, // when events have a label + verticalAlign: 'top', // when events have a label }; checkModelStyle(bpmnElementId, expectedModel); checkViewStateStyle(bpmnElementId, expectedModel); From e5b5fa292d14d92bd3c15e7a11eb4add5469417d Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 18:11:04 +0200 Subject: [PATCH 57/90] Update todo of maxgraph 0.1.0: mark them to be done after a new rebase on master --- test/integration/mxGraph.model.style.api.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/mxGraph.model.style.api.test.ts b/test/integration/mxGraph.model.style.api.test.ts index 6e4971be6c..d5d5516f6a 100644 --- a/test/integration/mxGraph.model.style.api.test.ts +++ b/test/integration/mxGraph.model.style.api.test.ts @@ -138,7 +138,7 @@ describe('mxGraph model - update style', () => { isStrikeThrough: true, }; bpmnVisualization.bpmnElementsRegistry.updateStyle('userTask_2_2', { font }); - // TODO maxGraph@0.1.0 - add such additional check in the master branch and do it when several style update actions are done + // TODO maxGraph@0.10.1 - add such additional check in the master branch and do it when several style update actions are done (from maxgraph@0.1.0 migration) expect('userTask_2_2').toBeUserTask({ font, // not under test From 643bf1a58631a5425f74ed840e169c00715341b9 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 18:11:50 +0200 Subject: [PATCH 58/90] StyleComputer.test.ts: manage TODO --- test/unit/component/mxgraph/renderer/StyleComputer.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts index 435d132279..87f2d940a7 100644 --- a/test/unit/component/mxgraph/renderer/StyleComputer.test.ts +++ b/test/unit/component/mxgraph/renderer/StyleComputer.test.ts @@ -299,7 +299,6 @@ describe('Style Computer', () => { const edge = new Edge('id', newMessageFlow(), undefined, undefined, messageVisibleKind); expect(styleComputer.computeMessageFlowIconStyle(edge)).toStrictEqual({ bpmn: { isInitiating: expected }, - // TODO maxGraph@0.10.1 decide if we use BpmnStyleIdentifier const instead shape: 'bpmn.messageFlowIcon', }); }); @@ -775,7 +774,6 @@ describe('Style Computer', () => { edge.extensions.strokeColor = '#11aabb'; const expectedStyle = { bpmn: { isInitiating: false }, - // TODO maxGraph@0.10.1 decide if we use BpmnStyleIdentifier const instead shape: 'bpmn.messageFlowIcon', }; if (expectAdditionalColorsStyle) { From 797c9f4e2f1cc1d8a2decb82ddecf6f544d8bbbe Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 26 Apr 2024 18:16:24 +0200 Subject: [PATCH 59/90] Update TODO in style-utils.test.ts --- test/unit/component/mxgraph/renderer/style-utils.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/unit/component/mxgraph/renderer/style-utils.test.ts b/test/unit/component/mxgraph/renderer/style-utils.test.ts index 2e3b9e1714..4d365987f8 100644 --- a/test/unit/component/mxgraph/renderer/style-utils.test.ts +++ b/test/unit/component/mxgraph/renderer/style-utils.test.ts @@ -72,6 +72,8 @@ describe('compute all css class names based on style input', () => { ${{ bpmn: { isInitiating: true }, shape: 'bpmn.message-flow-icon' }} | ${true} | ${['bpmn-message-flow-icon', 'bpmn-icon-initiating', 'bpmn-label']} `( // TODO maxgraph@0.1.0 find a way to correctly display the style object + // see also https://jestjs.io/docs/api#1-testeachtablename-fn-timeout + // partial solution: $style.bpmn.kind 'style="$style" / isLabel=$isLabel', ({ style, isLabel, expectedClassNames }: { style: BpmnCellStyle; isLabel: boolean; expectedClassNames: string[] }) => { expect(computeAllBpmnClassNames(style, isLabel)).toEqual(expectedClassNames); From 242fe00631c685ea5b3845597f218006cf0c3fd8 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Thu, 23 May 2024 18:16:15 +0200 Subject: [PATCH 60/90] StyleConfigurator.ts: update TODO about Perimeter configuration --- src/component/mxgraph/config/StyleConfigurator.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index dd979ae917..9e7591b8f2 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -172,6 +172,8 @@ export class StyleConfigurator { const style: BpmnCellStyle = { shape: kind, // TODO maxgraph@0.10.1 decide if we use the function or the string to set the perimeter + // this will reduce adherence to the maxGraph implementation and only use configuration string + // be also aware of https://github.com/process-analytics/bpmn-visualization-js/pull/2814#issuecomment-1692971602 perimeter: Perimeter.EllipsePerimeter, strokeWidth: kind == ShapeBpmnElementKind.EVENT_END ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN, verticalLabelPosition: 'bottom', From 5894e10bb860bff906fb988760cd01d07ec3e12e Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 24 May 2024 15:29:06 +0200 Subject: [PATCH 61/90] bump maxGraph to 0.10.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 269163f4b2..462dedf5e7 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "utils:test:model": "node ./scripts/utils/dist/utils.mjs test/fixtures/bpmn/simple-start-task-end.bpmn --output model" }, "dependencies": { - "@maxgraph/core": "0.10.1", + "@maxgraph/core": "0.10.2", "fast-xml-parser": "4.2.5", "lodash-es": "~4.17.21", "strnum": "1.0.5" From 284905afbf55c9371b793028ba4b990e621e7a3c Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 24 May 2024 15:29:28 +0200 Subject: [PATCH 62/90] package-lock.json - bump maxGraph to 0.10.2 --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index c40c351dde..063eec1cd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.37.0-post", "license": "Apache-2.0", "dependencies": { - "@maxgraph/core": "0.10.1", + "@maxgraph/core": "0.10.2", "fast-xml-parser": "4.2.5", "lodash-es": "~4.17.21", "strnum": "1.0.5" @@ -2824,9 +2824,9 @@ } }, "node_modules/@maxgraph/core": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.1.tgz", - "integrity": "sha512-7u2MTO7Kvl2Q96duv4Dr75J63oobWiA1hx8ZEBl3e8GBIKs/sIc3KsV24W4llzXkF/G7kkbdmVVhe43e5xeEQg==" + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.2.tgz", + "integrity": "sha512-7Ka/irQkb/TMs2ovEck1YW9SamMHHXUx48tlOBpBLd9lXmidDf/ToDj1bNuvU/j6U6xFwEnWNl7/aBuDHSTbzQ==" }, "node_modules/@microsoft/api-extractor": { "version": "7.35.2", @@ -14586,9 +14586,9 @@ } }, "@maxgraph/core": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.1.tgz", - "integrity": "sha512-7u2MTO7Kvl2Q96duv4Dr75J63oobWiA1hx8ZEBl3e8GBIKs/sIc3KsV24W4llzXkF/G7kkbdmVVhe43e5xeEQg==" + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.2.tgz", + "integrity": "sha512-7Ka/irQkb/TMs2ovEck1YW9SamMHHXUx48tlOBpBLd9lXmidDf/ToDj1bNuvU/j6U6xFwEnWNl7/aBuDHSTbzQ==" }, "@microsoft/api-extractor": { "version": "7.35.2", From c286c77a428b79e8b595519e1e95b55335f9411a Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 24 May 2024 16:48:47 +0200 Subject: [PATCH 63/90] SVGExporter: manage TODO --- dev/ts/component/SvgExporter.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/dev/ts/component/SvgExporter.ts b/dev/ts/component/SvgExporter.ts index 6913cb76bb..9d772e1a89 100644 --- a/dev/ts/component/SvgExporter.ts +++ b/dev/ts/component/SvgExporter.ts @@ -44,11 +44,10 @@ export class SvgExporter { return this.doSvgExport(isFirefox); } + // TODO maxgraph@0.10.2 migration - generate empty content private doSvgExport(enableForeignObjectForLabel: boolean): string { const svgDocument = this.computeSvg({ scale: 1, border: 25, enableForeignObjectForLabel: enableForeignObjectForLabel }); - // TODO maxgraph@0.1.0 migration - fix type - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + console.warn('svgDocument', svgDocument); const svgAsString = xmlUtils.getXml(svgDocument); return ` @@ -56,7 +55,7 @@ ${svgAsString} `; } - private computeSvg(svgExportOptions: SvgExportOptions): XMLDocument { + private computeSvg(svgExportOptions: SvgExportOptions): Element { const scale = svgExportOptions.scale ?? 1; const border = svgExportOptions.border ?? 0; const crisp = svgExportOptions.crisp ?? true; @@ -100,7 +99,7 @@ ${svgAsString} imgExport.includeOverlays = true; imgExport.drawState(this.graph.getView().getState(this.graph.model.root), svgCanvas); - return svgDoc; + return root; } createSvgCanvas(node: SVGElement): SvgCanvas2D { @@ -170,10 +169,7 @@ class CanvasForExport extends SvgCanvas2D { try { this.htmlConverter.innerHTML = str; - // TODO maxgraph@0.1.0 migration - fix type - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - str = domUtils.extractTextWithWhitespace(this.htmlConverter.childNodes); + str = domUtils.extractTextWithWhitespace(Array.from(this.htmlConverter.childNodes)); // Workaround for substring breaking double byte UTF const exp = Math.ceil((2 * w) / this.state.fontSize); From 7fc8e9dfd9a00e5b7ac37a058b395ba2225f07ac Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 24 May 2024 17:03:03 +0200 Subject: [PATCH 64/90] SVGExporter: try to debug empty content --- dev/ts/component/SvgExporter.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/dev/ts/component/SvgExporter.ts b/dev/ts/component/SvgExporter.ts index 9d772e1a89..807b0971b9 100644 --- a/dev/ts/component/SvgExporter.ts +++ b/dev/ts/component/SvgExporter.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Client, SvgCanvas2D, ImageExport, constants, xmlUtils, domUtils, stringUtils } from '@maxgraph/core'; +import { Client, SvgCanvas2D, ImageExport, constants, xmlUtils, domUtils, stringUtils, XmlCanvas2D } from '@maxgraph/core'; import type { Graph, AlignValue, VAlignValue, OverflowValue, TextDirectionValue } from '@maxgraph/core'; interface SvgExportOptions { @@ -47,8 +47,23 @@ export class SvgExporter { // TODO maxgraph@0.10.2 migration - generate empty content private doSvgExport(enableForeignObjectForLabel: boolean): string { const svgDocument = this.computeSvg({ scale: 1, border: 25, enableForeignObjectForLabel: enableForeignObjectForLabel }); - console.warn('svgDocument', svgDocument); + const svgAsString = xmlUtils.getXml(svgDocument); + // DEBUG - TODO magraph@0.10.2 - attempt to debug empty content + console.warn('svgDocument', svgDocument); + const xmlDoc = xmlUtils.createXmlDocument(); + const root = xmlDoc.createElement('data'); + xmlDoc.appendChild(root); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore -- TODO maxgraph@0.10.2 migration - wrong type in maxGraph XmlCanvas2D constructor, should be Element in constructor + const xmlCanvas = new XmlCanvas2D(root); + const imgExport = new ImageExport(); + imgExport.includeOverlays = true; + imgExport.drawState(this.graph.getView().getState(this.graph.model.root), xmlCanvas); + const xml = xmlUtils.getXml(root); + console.warn('xml', xml); + // end of DEBUG + return ` ${svgAsString} From a4bade6c925a4673bbfb98412d95e2183f6b5010 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 24 May 2024 17:07:12 +0200 Subject: [PATCH 65/90] ShapeConfigurator.ts: manage TODO --- src/component/mxgraph/config/ShapeConfigurator.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index af4977ea01..697b50428d 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -169,9 +169,8 @@ export default class ShapeConfigurator { // 'this.state.cell.style' = the style applied to the cell: 1st element: style name = bpmn shape name const cell = this.state.cell; // dialect = strictHtml is set means that current node holds an HTML label - // TODO maxgraph@0.1.0 "TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided."constants.DIALECT.STRICTHTML - let allBpmnClassNames = computeAllBpmnClassNamesOfCell(cell, this.dialect === 'strictHtml'); - // TODO maxgraph@0.1.0 - do we need to introduce a BpmnCellStateStyle type (to not have the baseStyleName property)? + let allBpmnClassNames = computeAllBpmnClassNamesOfCell(cell, this.dialect === constants.DIALECT.STRICTHTML); + // TODO maxgraph@0.10.2 - do we need to introduce a BpmnCellStateStyle type (to not have the baseStyleName property in the casted type)? const extraCssClasses = (this.state.style as BpmnCellStyle).bpmn?.extraCssClasses; if (extraCssClasses) { allBpmnClassNames = allBpmnClassNames.concat(extraCssClasses); From 087bf5c8910d645cc6ade26ad319ddd82262e700 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 24 May 2024 17:16:30 +0200 Subject: [PATCH 66/90] custom-overlay.ts: manage TODO --- src/component/mxgraph/overlay/custom-overlay.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/component/mxgraph/overlay/custom-overlay.ts b/src/component/mxgraph/overlay/custom-overlay.ts index 7aaf754c01..932ef1c504 100644 --- a/src/component/mxgraph/overlay/custom-overlay.ts +++ b/src/component/mxgraph/overlay/custom-overlay.ts @@ -39,10 +39,6 @@ export class MxGraphCustomOverlay extends CellOverlay { constructor(public label: string, options: MxGraphCustomOverlayOptions) { super(null, '', options.position.horizontalAlign, options.position.verticalAlign, new Point(), 'default'); - // FIXME maxgraph@0.1.0 constructor doesn't set some properties - this.align = options.position.horizontalAlign; - this.verticalAlign = options.position.verticalAlign; - // end of fixme this.style = options.style; } From e7b8f897d4fde0ff8516df256e6de61e092f9a5c Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 27 May 2024 13:55:17 +0200 Subject: [PATCH 67/90] SvgExporter.ts: update TODO - add link to maxGraph PR fixing issues --- dev/ts/component/SvgExporter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/ts/component/SvgExporter.ts b/dev/ts/component/SvgExporter.ts index 807b0971b9..8f007530b5 100644 --- a/dev/ts/component/SvgExporter.ts +++ b/dev/ts/component/SvgExporter.ts @@ -44,7 +44,7 @@ export class SvgExporter { return this.doSvgExport(isFirefox); } - // TODO maxgraph@0.10.2 migration - generate empty content + // TODO maxgraph@0.10.2 migration - generate empty content - should be fixed with https://github.com/maxGraph/maxGraph/pull/425 private doSvgExport(enableForeignObjectForLabel: boolean): string { const svgDocument = this.computeSvg({ scale: 1, border: 25, enableForeignObjectForLabel: enableForeignObjectForLabel }); @@ -55,7 +55,7 @@ export class SvgExporter { const root = xmlDoc.createElement('data'); xmlDoc.appendChild(root); // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore -- TODO maxgraph@0.10.2 migration - wrong type in maxGraph XmlCanvas2D constructor, should be Element in constructor + // @ts-ignore -- TODO maxgraph@0.10.2 migration - wrong type in maxGraph XmlCanvas2D constructor, should be Element in constructor - see https://github.com/maxGraph/maxGraph/pull/423 const xmlCanvas = new XmlCanvas2D(root); const imgExport = new ImageExport(); imgExport.includeOverlays = true; From 3ca3cd0c5b0177ee12d8b9b6168692e6c119e98d Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 27 May 2024 14:13:03 +0200 Subject: [PATCH 68/90] GraphConfigurator.ts add TODO about foldingEnabled configuration --- src/component/mxgraph/GraphConfigurator.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/component/mxgraph/GraphConfigurator.ts b/src/component/mxgraph/GraphConfigurator.ts index d59f6c246c..5744971804 100644 --- a/src/component/mxgraph/GraphConfigurator.ts +++ b/src/component/mxgraph/GraphConfigurator.ts @@ -57,8 +57,9 @@ export default class GraphConfigurator { this.graph.setConstrainChildren(false); this.graph.setExtendParents(false); - // Disable folding for container mxCell (pool, lane, sub process, call activity) because we don't need it. - // This also prevents requesting unavailable images (see #185) as we don't override BpmnMxGraph folding default images. + // Disable folding for container Cell (pool, lane, sub process, call activity) because we don't need it. + // This also prevents requesting unavailable images (see #185) as we don't override mxGraph folding default images. + // TODO migration maxgraph 0.10.2 - call this.graph.options.foldingEnabled, remove this.graph.foldingEnabled which is not used to manage folding. See https://github.com/maxGraph/maxGraph/pull/426 this.graph.foldingEnabled = false; } From 5930261f99b435454f3408f7cd159c063058a757 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:28:23 +0200 Subject: [PATCH 69/90] Introduce BpmnCellStateStyle --- .../mxgraph/config/ShapeConfigurator.ts | 5 +-- .../mxgraph/shape/activity-shapes.ts | 10 ++--- src/component/mxgraph/shape/edges.ts | 6 +-- src/component/mxgraph/shape/event-shapes.ts | 6 +-- src/component/mxgraph/shape/flow-shapes.ts | 4 +- src/component/mxgraph/shape/gateway-shapes.ts | 6 +-- src/component/mxgraph/style/types.ts | 37 +++++++++++-------- 7 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index 697b50428d..91b9070cda 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -36,7 +36,7 @@ import { TextAnnotationShape } from '../shape/text-annotation-shapes'; import { MessageFlowIconShape } from '../shape/flow-shapes'; import { BpmnStyleIdentifier } from '../style'; import { computeAllBpmnClassNamesOfCell } from '../renderer/style-utils'; -import type { BpmnCellStyle } from '../style/types'; +import type { BpmnCellStateStyle, BpmnCellStyle } from '../style/types'; import { MxGraphCustomOverlay } from '../overlay/custom-overlay'; import { OverlayBadgeShape } from '../overlay/shapes'; import { BpmnConnector } from '../shape/edges'; @@ -170,8 +170,7 @@ export default class ShapeConfigurator { const cell = this.state.cell; // dialect = strictHtml is set means that current node holds an HTML label let allBpmnClassNames = computeAllBpmnClassNamesOfCell(cell, this.dialect === constants.DIALECT.STRICTHTML); - // TODO maxgraph@0.10.2 - do we need to introduce a BpmnCellStateStyle type (to not have the baseStyleName property in the casted type)? - const extraCssClasses = (this.state.style as BpmnCellStyle).bpmn?.extraCssClasses; + const extraCssClasses = (this.state.style as BpmnCellStateStyle).bpmn?.extraCssClasses; if (extraCssClasses) { allBpmnClassNames = allBpmnClassNames.concat(extraCssClasses); } diff --git a/src/component/mxgraph/shape/activity-shapes.ts b/src/component/mxgraph/shape/activity-shapes.ts index 474d4b7f09..ef1d2de051 100644 --- a/src/component/mxgraph/shape/activity-shapes.ts +++ b/src/component/mxgraph/shape/activity-shapes.ts @@ -17,7 +17,7 @@ limitations under the License. import type { AbstractCanvas2D } from '@maxgraph/core'; import { RectangleShape } from '@maxgraph/core'; -import type { BpmnCellStyle } from '../style/types'; +import type { BpmnCellStateStyle } from '../style/types'; import { StyleDefault } from '../style'; import type { BpmnCanvas, PaintParameter, ShapeConfiguration } from './render'; import { IconPainterProvider } from './render'; @@ -51,7 +51,7 @@ export abstract class BaseActivityShape extends RectangleShape { } protected paintMarkerIcons(paintParameter: PaintParameter): void { - const markers = (this.style as BpmnCellStyle).bpmn.markers; + const markers = (this.style as BpmnCellStateStyle).bpmn.markers; if (markers) { orderActivityMarkers(markers).forEach((marker, idx, allMarkers) => { paintParameter = { @@ -140,7 +140,7 @@ export class UserTaskShape extends BaseTaskShape { */ export class ReceiveTaskShape extends BaseTaskShape { protected paintTaskIcon(paintParameter: PaintParameter): void { - if (!(this.style as BpmnCellStyle).bpmn.isInstantiating) { + if (!(this.style as BpmnCellStateStyle).bpmn.isInstantiating) { paintEnvelopeIcon(paintParameter, false); return; } @@ -212,7 +212,7 @@ export class CallActivityShape extends BaseActivityShape { const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this }); - switch ((this.style as BpmnCellStyle).bpmn.globalTaskKind) { + switch ((this.style as BpmnCellStateStyle).bpmn.globalTaskKind) { case ShapeBpmnElementKind.GLOBAL_TASK_MANUAL: this.iconPainter.paintHandIcon({ ...paintParameter, @@ -252,7 +252,7 @@ export class CallActivityShape extends BaseActivityShape { */ export class SubProcessShape extends BaseActivityShape { override paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { - const subProcessKind = (this.style as BpmnCellStyle).bpmn.subProcessKind; + const subProcessKind = (this.style as BpmnCellStateStyle).bpmn.subProcessKind; c.save(); // ensure we can later restore the configuration if (subProcessKind === ShapeBpmnSubProcessKind.EVENT) { c.setDashed(true, false); diff --git a/src/component/mxgraph/shape/edges.ts b/src/component/mxgraph/shape/edges.ts index d425877d5a..34f8963f6f 100644 --- a/src/component/mxgraph/shape/edges.ts +++ b/src/component/mxgraph/shape/edges.ts @@ -17,7 +17,7 @@ limitations under the License. import type { Point, AbstractCanvas2D } from '@maxgraph/core'; import { SvgCanvas2D, ConnectorShape } from '@maxgraph/core'; -import type { BpmnCellStyle } from '../style/types'; +import type { BpmnCellStateStyle } from '../style/types'; // TODO maxgraph@0.1.0 remove the BpmnConnector class to use the new support of endFillColor and starFillColor provided by https://github.com/maxGraph/maxGraph/issues/201 export class BpmnConnector extends ConnectorShape { @@ -39,12 +39,12 @@ export class BpmnConnector extends ConnectorShape { c.setDashed(false, false); if (sourceMarker != null) { - c.setFillColor((this.style as BpmnCellStyle).startFillColor ?? this.stroke); + c.setFillColor((this.style as BpmnCellStateStyle).startFillColor ?? this.stroke); sourceMarker(); } if (targetMarker != null) { - c.setFillColor((this.style as BpmnCellStyle).endFillColor ?? this.stroke); + c.setFillColor((this.style as BpmnCellStateStyle).endFillColor ?? this.stroke); targetMarker(); } } diff --git a/src/component/mxgraph/shape/event-shapes.ts b/src/component/mxgraph/shape/event-shapes.ts index 9c06b6fa7b..b2d75fa7a4 100644 --- a/src/component/mxgraph/shape/event-shapes.ts +++ b/src/component/mxgraph/shape/event-shapes.ts @@ -21,7 +21,7 @@ import { ShapeBpmnEventDefinitionKind } from '../../../model/bpmn/internal'; import type { BpmnCanvas, PaintParameter } from './render'; import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import type { BpmnCellStyle } from '../style/types'; +import type { BpmnCellStateStyle } from '../style/types'; import { StyleDefault } from '../style'; /** @@ -90,7 +90,7 @@ export class EventShape extends EllipseShape { override paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void { const paintParameter = buildPaintParameter({ canvas: c, x, y, width: w, height: h, shape: this, isFilled: this.withFilledIcon }); - EventShape.setDashedOuterShapePattern(paintParameter, (this.style as BpmnCellStyle).bpmn.isInterrupting); + EventShape.setDashedOuterShapePattern(paintParameter, (this.style as BpmnCellStateStyle).bpmn.isInterrupting); this.paintOuterShape(paintParameter); EventShape.restoreOriginalOuterShapePattern(paintParameter); @@ -102,7 +102,7 @@ export class EventShape extends EllipseShape { } private paintInnerShape(paintParameter: PaintParameter): void { - const paintIcon = this.iconPainters.get((this.style as BpmnCellStyle).bpmn.eventDefinitionKind) || (() => this.iconPainter.paintEmptyIcon()); + const paintIcon = this.iconPainters.get((this.style as BpmnCellStateStyle).bpmn.eventDefinitionKind) || (() => this.iconPainter.paintEmptyIcon()); paintIcon(paintParameter); } diff --git a/src/component/mxgraph/shape/flow-shapes.ts b/src/component/mxgraph/shape/flow-shapes.ts index 354cae311b..ae748fd0ec 100644 --- a/src/component/mxgraph/shape/flow-shapes.ts +++ b/src/component/mxgraph/shape/flow-shapes.ts @@ -16,7 +16,7 @@ limitations under the License. import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import type { BpmnCellStyle } from '../style/types'; +import type { BpmnCellStateStyle } from '../style/types'; import { RectangleShape } from '@maxgraph/core'; import type { AbstractCanvas2D, Rectangle } from '@maxgraph/core'; @@ -39,7 +39,7 @@ export class MessageFlowIconShape extends RectangleShape { height: h, shape: this, ratioFromParent: 1, - isFilled: !((this.style as BpmnCellStyle).bpmn.isInitiating ?? true), + isFilled: !((this.style as BpmnCellStateStyle).bpmn.isInitiating ?? true), }); this.iconPainter.paintEnvelopeIcon(paintParameter); diff --git a/src/component/mxgraph/shape/gateway-shapes.ts b/src/component/mxgraph/shape/gateway-shapes.ts index a294065c18..8823d5a053 100644 --- a/src/component/mxgraph/shape/gateway-shapes.ts +++ b/src/component/mxgraph/shape/gateway-shapes.ts @@ -22,7 +22,7 @@ import { StyleDefault } from '../style'; import type { PaintParameter } from './render'; import { IconPainterProvider } from './render'; import { buildPaintParameter } from './render/icon-painter'; -import type { BpmnCellStyle } from '../style/types'; +import type { BpmnCellStateStyle } from '../style/types'; abstract class GatewayShape extends RhombusShape { protected iconPainter = IconPainterProvider.get(); @@ -104,7 +104,7 @@ export class EventBasedGatewayShape extends GatewayShape { ...paintParameter, ratioFromParent: 0.55, }); - if (!(this.style as BpmnCellStyle).bpmn.isInstantiating) { + if (!(this.style as BpmnCellStateStyle).bpmn.isInstantiating) { this.iconPainter.paintCircleIcon({ ...paintParameter, ratioFromParent: 0.45, @@ -116,7 +116,7 @@ export class EventBasedGatewayShape extends GatewayShape { ...paintParameter, ratioFromParent: 0.3, }; - if ((this.style as BpmnCellStyle).bpmn.gatewayKind == ShapeBpmnEventBasedGatewayKind.Parallel) { + if ((this.style as BpmnCellStateStyle).bpmn.gatewayKind == ShapeBpmnEventBasedGatewayKind.Parallel) { this.iconPainter.paintPlusCrossIcon(innerIconPaintParameter); } else { this.iconPainter.paintPentagon(innerIconPaintParameter); diff --git a/src/component/mxgraph/style/types.ts b/src/component/mxgraph/style/types.ts index 20b244010c..3410b2e344 100644 --- a/src/component/mxgraph/style/types.ts +++ b/src/component/mxgraph/style/types.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import type { CellStyle } from '@maxgraph/core'; +import type { CellStateStyle, CellStyle } from '@maxgraph/core'; import type { AssociationDirectionKind, FlowKind, @@ -27,19 +27,26 @@ import type { ShapeBpmnSubProcessKind, } from '../../../model/bpmn/internal'; +export interface BpmnCellStyleExtension { + associationDirectionKind?: AssociationDirectionKind; + eventDefinitionKind?: ShapeBpmnEventDefinitionKind; + extraCssClasses?: string[]; + gatewayKind?: ShapeBpmnEventBasedGatewayKind; + globalTaskKind?: GlobalTaskKind; + isInitiating?: boolean; + isInstantiating?: boolean; + isInterrupting?: boolean; + kind?: ShapeBpmnElementKind | FlowKind; + markers?: ShapeBpmnMarkerKind[]; + sequenceFlowKind?: SequenceFlowKind; + subProcessKind?: ShapeBpmnSubProcessKind; +} + +// TODO check if we can use interface augmentation on CellStyle/CellStateStyle instead of extending the type. This would avoid to cast CellStyle/CellStateStyle everywhere in the code export interface BpmnCellStyle extends CellStyle { - bpmn?: { - associationDirectionKind?: AssociationDirectionKind; - eventDefinitionKind?: ShapeBpmnEventDefinitionKind; - extraCssClasses?: string[]; - gatewayKind?: ShapeBpmnEventBasedGatewayKind; - globalTaskKind?: GlobalTaskKind; - isInitiating?: boolean; - isInstantiating?: boolean; - isInterrupting?: boolean; - kind?: ShapeBpmnElementKind | FlowKind; - markers?: ShapeBpmnMarkerKind[]; - sequenceFlowKind?: SequenceFlowKind; - subProcessKind?: ShapeBpmnSubProcessKind; - }; + bpmn?: BpmnCellStyleExtension; +} + +export interface BpmnCellStateStyle extends CellStateStyle { + bpmn?: BpmnCellStyleExtension; } From 96728099c5e7969e428cb922ae189cee42f00830 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 19:41:26 +0200 Subject: [PATCH 70/90] Introduce BpmnCellStateStyle - ShapeConfigurator.ts: remove unused import --- src/component/mxgraph/config/ShapeConfigurator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index 91b9070cda..52f50fa1ca 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -36,7 +36,7 @@ import { TextAnnotationShape } from '../shape/text-annotation-shapes'; import { MessageFlowIconShape } from '../shape/flow-shapes'; import { BpmnStyleIdentifier } from '../style'; import { computeAllBpmnClassNamesOfCell } from '../renderer/style-utils'; -import type { BpmnCellStateStyle, BpmnCellStyle } from '../style/types'; +import type { BpmnCellStateStyle } from '../style/types'; import { MxGraphCustomOverlay } from '../overlay/custom-overlay'; import { OverlayBadgeShape } from '../overlay/shapes'; import { BpmnConnector } from '../shape/edges'; From 39d2e31c8628602101bcda989cc99abb82b7674d Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:23:32 +0200 Subject: [PATCH 71/90] GraphConfigurator.ts: update TODO about PanningHandler --- src/component/mxgraph/GraphConfigurator.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/component/mxgraph/GraphConfigurator.ts b/src/component/mxgraph/GraphConfigurator.ts index 5744971804..8440973b6d 100644 --- a/src/component/mxgraph/GraphConfigurator.ts +++ b/src/component/mxgraph/GraphConfigurator.ts @@ -64,9 +64,10 @@ export default class GraphConfigurator { } private configureNavigationSupport(options: GlobalOptions): void { - // TODO maxgraph@0.1.0 decide if we do the check or not. + // TODO maxgraph@0.1.0 decide if we check that panningHandler is registered // If not, add a comment to explain why // In theory, the panningHandler may not be available if its plugin is not registered. The maxGraph code sometimes check for availability. For now, the check is not needed as we know that we load it + // we know that the panningHandler is registered because it is done in the BpmnGraph constructor const panningHandler = this.graph.getPlugin('PanningHandler'); if (options?.navigation?.enabled) { From ff1e1cf2cd538d876ad4d5e42b5218397c22e04c Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:31:11 +0200 Subject: [PATCH 72/90] GraphCellUpdater: update TODO --- src/component/mxgraph/GraphCellUpdater.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/component/mxgraph/GraphCellUpdater.ts b/src/component/mxgraph/GraphCellUpdater.ts index ad1ceb7a59..54d4f96e82 100644 --- a/src/component/mxgraph/GraphCellUpdater.ts +++ b/src/component/mxgraph/GraphCellUpdater.ts @@ -114,6 +114,7 @@ export default class GraphCellUpdater { } // TODO maxgraph@0.10.1 migration --> change to apply this to the master branch: graph.model --> model (from maxgraph@0.1.0 migration) + // change applied to master in "refactor: split internal registries (#2818)" commit3dfc4967 model.setStyle(cell, cellStyle); } }); From 84f62b22923c2471db493a3ca961818d92265036 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:01:03 +0200 Subject: [PATCH 73/90] Graph constructor: only used maxGraph plugins we need --- src/component/mxgraph/BpmnGraph.ts | 7 +++---- src/component/mxgraph/GraphConfigurator.ts | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index b77c78a5d9..f6aa7e1938 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -19,7 +19,7 @@ import { FitType } from '../options'; import { ensurePositiveValue, ensureValidZoomConfiguration } from '../helpers/validators'; import { debounce, throttle } from 'lodash-es'; import type { CellState, CellStateStyle, CellStyle, Point } from '@maxgraph/core'; -import { eventUtils, Graph, GraphView, InternalEvent, Stylesheet } from '@maxgraph/core'; +import { eventUtils, Graph, GraphView, InternalEvent, Stylesheet, PanningHandler } from '@maxgraph/core'; const zoomFactorIn = 1.25; const zoomFactorOut = 1 / zoomFactorIn; @@ -31,9 +31,8 @@ export class BpmnGraph extends Graph { * @internal */ constructor(container: HTMLElement) { - // TODO maxGraph@0.1.0 - only set the plugins we need - // require a version that doesn't generate errors when plugins are not found (is ok in v0.8.0) - super(container); + // TODO maxGraph@0.10.2 - only set the plugins we need (validate the list) + super(container, undefined, [PanningHandler]); this.zoomFactor = zoomFactorIn; if (this.container) { // ensure we don't have a select text cursor on label hover, see #294 diff --git a/src/component/mxgraph/GraphConfigurator.ts b/src/component/mxgraph/GraphConfigurator.ts index 8440973b6d..9d38f67a14 100644 --- a/src/component/mxgraph/GraphConfigurator.ts +++ b/src/component/mxgraph/GraphConfigurator.ts @@ -64,10 +64,10 @@ export default class GraphConfigurator { } private configureNavigationSupport(options: GlobalOptions): void { - // TODO maxgraph@0.1.0 decide if we check that panningHandler is registered + // TODO maxgraph@0.10.2 decide if we check that panningHandler is registered // If not, add a comment to explain why // In theory, the panningHandler may not be available if its plugin is not registered. The maxGraph code sometimes check for availability. For now, the check is not needed as we know that we load it - // we know that the panningHandler is registered because it is done in the BpmnGraph constructor + // we know that the panningHandler is registered because it is done in the BpmnGraph constructor (not setting it makes the integration tests fail) const panningHandler = this.graph.getPlugin('PanningHandler'); if (options?.navigation?.enabled) { From ca48e96a7e4170ac7ad2780ddd97307a33075b56 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:08:07 +0200 Subject: [PATCH 74/90] WIP remove maxGraph workaround for v0.1.0 that are now fixed --- src/component/mxgraph/BpmnGraph.ts | 74 +++++++++++++++--------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index f6aa7e1938..7df9f1b833 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -209,9 +209,9 @@ export class BpmnGraph extends Graph { // TODO maxgraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) // with maxgraph@0.10.1, using the maxGraph implementation impact the results of the integration tests (markers) - override createStylesheet(): Stylesheet { - return new BpmnStylesheet(); - } + // override createStylesheet(): Stylesheet { + // return new BpmnStylesheet(); + // } } class BpmnGraphView extends GraphView { @@ -230,40 +230,40 @@ class BpmnGraphView extends GraphView { // TODO maxgraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) // see also utils.ts setStyle which adds another workaround that should be possible to remove with maxGraph@0.10.1 -class BpmnStylesheet extends Stylesheet { - override getCellStyle(cellStyle: CellStyle, defaultStyle: CellStateStyle): CellStateStyle { - let style: CellStateStyle; - - if (cellStyle.baseStyleNames && cellStyle.baseStyleNames.length > 0) { - // creates style with the given baseStyleNames. (merges from left to right) - style = cellStyle.baseStyleNames.reduce( - (acc, styleName) => { - return (acc = { - ...acc, - ...this.styles.get(styleName), - }); - }, - // here is the change - // {}, - { ...defaultStyle }, - // END of here is the change - ); - } else if (cellStyle.baseStyleNames && cellStyle.baseStyleNames.length === 0) { - // baseStyleNames is explicitly an empty array, so don't use any default styles. - style = {}; - } else { - style = { ...defaultStyle }; - } - - // Merges cellStyle into style - style = { - ...style, - ...cellStyle, - }; - - return style; - } -} +// class BpmnStylesheet extends Stylesheet { +// override getCellStyle(cellStyle: CellStyle, defaultStyle: CellStateStyle): CellStateStyle { +// let style: CellStateStyle; +// +// if (cellStyle.baseStyleNames && cellStyle.baseStyleNames.length > 0) { +// // creates style with the given baseStyleNames. (merges from left to right) +// style = cellStyle.baseStyleNames.reduce( +// (acc, styleName) => { +// return (acc = { +// ...acc, +// ...this.styles.get(styleName), +// }); +// }, +// // here is the change +// // {}, +// { ...defaultStyle }, +// // END of here is the change +// ); +// } else if (cellStyle.baseStyleNames && cellStyle.baseStyleNames.length === 0) { +// // baseStyleNames is explicitly an empty array, so don't use any default styles. +// style = {}; +// } else { +// style = { ...defaultStyle }; +// } +// +// // Merges cellStyle into style +// style = { +// ...style, +// ...cellStyle, +// }; +// +// return style; +// } +// } function convertNaNToZero(value: number): number { return Number.isNaN(value) ? 0 : value; From f265908ee2bedbac01ac02ee5f9a90d43f536799 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:15:46 +0200 Subject: [PATCH 75/90] WIP remove maxGraph workaround for v0.1.0 that are now fixed --- src/component/mxgraph/style/utils.ts | 34 ++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index 362baaa1b9..590a3d9850 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -87,20 +87,26 @@ export const setStyle = ( value: T | undefined, converter: (value: T) => T | undefined = (value: T) => value, ): void => { - if (value != undefined) { - const convertedValue = converter(value); - if (convertedValue == null) { - // TODO maxgraph@0.1.0 - this is required for the effective cell style computation with the fix temporary used in bpmn-visualization (BpmnStylesheet) - // if the value is undefined/or null, the value from the default style is not used! - // remove the property to use the value from the "base styles" which provides the default value - delete cellStyle[key]; - } else { - // TODO maxgraph@0.1.0 - fix type - can we really ignore ts error? - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - cellStyle[key] = convertedValue; - } - } + if (value == undefined) return; + // TODO maxgraph@0.10.2 - fix type - can we really ignore ts error? (from maxgraph@0.1.0) + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + cellStyle[key] = converter(value); + + // if (value != undefined) { + // const convertedValue = converter(value); + // if (convertedValue == null) { + // // TODO maxgraph@0.1.0 - this is required for the effective cell style computation with the fix temporary used in bpmn-visualization (BpmnStylesheet) + // // if the value is undefined/or null, the value from the default style is not used! + // // remove the property to use the value from the "base styles" which provides the default value + // delete cellStyle[key]; + // } else { + // // TODO maxgraph@0.1.0 - fix type - can we really ignore ts error? + // // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // // @ts-ignore + // cellStyle[key] = convertedValue; + // } + // } }; export const setStyleFlag = (cellStyle: CellStyle, key: NumericCellStateStyleKeys, flag: number, value?: boolean): void => { From 61bd589018232432c6c2a3ea8f085ecb96b7ab2e Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:16:34 +0200 Subject: [PATCH 76/90] WIP remove maxGraph workaround for v0.1.0 that are now fixed --- src/component/mxgraph/BpmnGraph.ts | 43 ---------------------------- src/component/mxgraph/style/utils.ts | 15 ---------- 2 files changed, 58 deletions(-) diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index 7df9f1b833..63f65749e4 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -206,12 +206,6 @@ export class BpmnGraph extends Graph { const factor = scale / this.view.scale; return [factor, scale]; } - - // TODO maxgraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) - // with maxgraph@0.10.1, using the maxGraph implementation impact the results of the integration tests (markers) - // override createStylesheet(): Stylesheet { - // return new BpmnStylesheet(); - // } } class BpmnGraphView extends GraphView { @@ -228,43 +222,6 @@ class BpmnGraphView extends GraphView { } } -// TODO maxgraph@0.1.0 temp to fix maxGraph style merge issue (should be fixed in maxGraph@0.2.0) -// see also utils.ts setStyle which adds another workaround that should be possible to remove with maxGraph@0.10.1 -// class BpmnStylesheet extends Stylesheet { -// override getCellStyle(cellStyle: CellStyle, defaultStyle: CellStateStyle): CellStateStyle { -// let style: CellStateStyle; -// -// if (cellStyle.baseStyleNames && cellStyle.baseStyleNames.length > 0) { -// // creates style with the given baseStyleNames. (merges from left to right) -// style = cellStyle.baseStyleNames.reduce( -// (acc, styleName) => { -// return (acc = { -// ...acc, -// ...this.styles.get(styleName), -// }); -// }, -// // here is the change -// // {}, -// { ...defaultStyle }, -// // END of here is the change -// ); -// } else if (cellStyle.baseStyleNames && cellStyle.baseStyleNames.length === 0) { -// // baseStyleNames is explicitly an empty array, so don't use any default styles. -// style = {}; -// } else { -// style = { ...defaultStyle }; -// } -// -// // Merges cellStyle into style -// style = { -// ...style, -// ...cellStyle, -// }; -// -// return style; -// } -// } - function convertNaNToZero(value: number): number { return Number.isNaN(value) ? 0 : value; } diff --git a/src/component/mxgraph/style/utils.ts b/src/component/mxgraph/style/utils.ts index 590a3d9850..c10eda2626 100644 --- a/src/component/mxgraph/style/utils.ts +++ b/src/component/mxgraph/style/utils.ts @@ -92,21 +92,6 @@ export const setStyle = ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore cellStyle[key] = converter(value); - - // if (value != undefined) { - // const convertedValue = converter(value); - // if (convertedValue == null) { - // // TODO maxgraph@0.1.0 - this is required for the effective cell style computation with the fix temporary used in bpmn-visualization (BpmnStylesheet) - // // if the value is undefined/or null, the value from the default style is not used! - // // remove the property to use the value from the "base styles" which provides the default value - // delete cellStyle[key]; - // } else { - // // TODO maxgraph@0.1.0 - fix type - can we really ignore ts error? - // // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // // @ts-ignore - // cellStyle[key] = convertedValue; - // } - // } }; export const setStyleFlag = (cellStyle: CellStyle, key: NumericCellStateStyleKeys, flag: number, value?: boolean): void => { From e2e6f76ec37582ea7b85d46bb448943d427991d0 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 19:40:47 +0200 Subject: [PATCH 77/90] WIP remove maxGraph workaround for v0.1.0 that are now fixed - BpmnGraph.ts: remove unused imports --- src/component/mxgraph/BpmnGraph.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index 63f65749e4..01e14c85cb 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -18,8 +18,8 @@ import type { FitOptions, ZoomConfiguration } from '../options'; import { FitType } from '../options'; import { ensurePositiveValue, ensureValidZoomConfiguration } from '../helpers/validators'; import { debounce, throttle } from 'lodash-es'; -import type { CellState, CellStateStyle, CellStyle, Point } from '@maxgraph/core'; -import { eventUtils, Graph, GraphView, InternalEvent, Stylesheet, PanningHandler } from '@maxgraph/core'; +import type { CellState, Point } from '@maxgraph/core'; +import { eventUtils, Graph, GraphView, InternalEvent, PanningHandler } from '@maxgraph/core'; const zoomFactorIn = 1.25; const zoomFactorOut = 1 / zoomFactorIn; From 3924d317fa74498bab04fd10f71e6f33731bed6c Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:21:33 +0200 Subject: [PATCH 78/90] GraphCellUpdater.ts update TODO --- src/component/mxgraph/GraphCellUpdater.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/GraphCellUpdater.ts b/src/component/mxgraph/GraphCellUpdater.ts index 54d4f96e82..0ba1eb546c 100644 --- a/src/component/mxgraph/GraphCellUpdater.ts +++ b/src/component/mxgraph/GraphCellUpdater.ts @@ -113,7 +113,7 @@ export default class GraphCellUpdater { updateFill(cellStyle, styleUpdate.fill); } - // TODO maxgraph@0.10.1 migration --> change to apply this to the master branch: graph.model --> model (from maxgraph@0.1.0 migration) + // TODO maxgraph@0.10.2 migration --> ensure that change to apply this to the master branch: graph.model --> model (from maxgraph@0.1.0 migration) // change applied to master in "refactor: split internal registries (#2818)" commit3dfc4967 model.setStyle(cell, cellStyle); } From 67a7b5bcfac4761d21e3a6e1ace84d1e126955dc Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:22:17 +0200 Subject: [PATCH 79/90] GraphConfigurator.ts update TODO --- src/component/mxgraph/GraphConfigurator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/GraphConfigurator.ts b/src/component/mxgraph/GraphConfigurator.ts index 9d38f67a14..4f72ca9a9e 100644 --- a/src/component/mxgraph/GraphConfigurator.ts +++ b/src/component/mxgraph/GraphConfigurator.ts @@ -59,7 +59,7 @@ export default class GraphConfigurator { // Disable folding for container Cell (pool, lane, sub process, call activity) because we don't need it. // This also prevents requesting unavailable images (see #185) as we don't override mxGraph folding default images. - // TODO migration maxgraph 0.10.2 - call this.graph.options.foldingEnabled, remove this.graph.foldingEnabled which is not used to manage folding. See https://github.com/maxGraph/maxGraph/pull/426 + // TODO migration maxgraph 0.10.2 (should be fixed in 0.10.3) - call this.graph.options.foldingEnabled, remove this.graph.foldingEnabled which is not used to manage folding. See https://github.com/maxGraph/maxGraph/pull/426 this.graph.foldingEnabled = false; } From 227c84973ce6ea9744a4f3e78255fe80bbb8bfeb Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:25:05 +0200 Subject: [PATCH 80/90] types.ts: update TODO --- src/component/mxgraph/style/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/style/types.ts b/src/component/mxgraph/style/types.ts index 3410b2e344..d1fc0ea67a 100644 --- a/src/component/mxgraph/style/types.ts +++ b/src/component/mxgraph/style/types.ts @@ -42,7 +42,7 @@ export interface BpmnCellStyleExtension { subProcessKind?: ShapeBpmnSubProcessKind; } -// TODO check if we can use interface augmentation on CellStyle/CellStateStyle instead of extending the type. This would avoid to cast CellStyle/CellStateStyle everywhere in the code +// TODO migration maxGraph@0.10.2 check if we can use interface augmentation on CellStyle/CellStateStyle instead of extending the type. This would avoid to cast CellStyle/CellStateStyle everywhere in the code export interface BpmnCellStyle extends CellStyle { bpmn?: BpmnCellStyleExtension; } From d99302976117497a55b45234f747a200ed03c491 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 19:38:36 +0200 Subject: [PATCH 81/90] BpmnGraph.ts update TODO --- src/component/mxgraph/BpmnGraph.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/BpmnGraph.ts b/src/component/mxgraph/BpmnGraph.ts index 01e14c85cb..ba17e4e58e 100644 --- a/src/component/mxgraph/BpmnGraph.ts +++ b/src/component/mxgraph/BpmnGraph.ts @@ -31,7 +31,7 @@ export class BpmnGraph extends Graph { * @internal */ constructor(container: HTMLElement) { - // TODO maxGraph@0.10.2 - only set the plugins we need (validate the list) + // TODO maxGraph@0.10.2 - validate the list of maxGraph plugins we need to use super(container, undefined, [PanningHandler]); this.zoomFactor = zoomFactorIn; if (this.container) { From 4e2bba32799d086af03a28ec370864395860241a Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 19:48:18 +0200 Subject: [PATCH 82/90] ShapeConfigurator.ts update TODO --- .../mxgraph/config/ShapeConfigurator.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index 52f50fa1ca..aaf0786aba 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -60,19 +60,19 @@ export default class ShapeConfigurator { CellRenderer.registerShape(ShapeBpmnElementKind.EVENT_INTERMEDIATE_CATCH, IntermediateEventShape); CellRenderer.registerShape(ShapeBpmnElementKind.EVENT_BOUNDARY, IntermediateEventShape); // gateways - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.10.2 fix CellRenderer.registerShape call (from maxgraph@0.1.0) // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_COMPLEX, ComplexGatewayShape); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.10.2 fix CellRenderer.registerShape call (from maxgraph@0.1.0) // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_EVENT_BASED, EventBasedGatewayShape); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.10.2 fix CellRenderer.registerShape call (from maxgraph@0.1.0) // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_EXCLUSIVE, ExclusiveGatewayShape); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.10.2 fix CellRenderer.registerShape call (from maxgraph@0.1.0) // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_INCLUSIVE, InclusiveGatewayShape); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.10.2 fix CellRenderer.registerShape call (from maxgraph@0.1.0) // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.GATEWAY_PARALLEL, ParallelGatewayShape); // activities @@ -88,15 +88,15 @@ export default class ShapeConfigurator { CellRenderer.registerShape(ShapeBpmnElementKind.TASK_SCRIPT, ScriptTaskShape); CellRenderer.registerShape(ShapeBpmnElementKind.TASK_BUSINESS_RULE, BusinessRuleTaskShape); // artifacts - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.10.2 fix CellRenderer.registerShape call (from maxgraph@0.1.0) // @ts-ignore CellRenderer.registerShape(ShapeBpmnElementKind.TEXT_ANNOTATION, TextAnnotationShape); // shapes for flows - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.10.2 fix CellRenderer.registerShape call (from maxgraph@0.1.0) // @ts-ignore CellRenderer.registerShape(BpmnStyleIdentifier.EDGE, BpmnConnector); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.1.0 fix CellRenderer.registerShape call + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TODO maxgraph@0.10.2 fix CellRenderer.registerShape call (from maxgraph@0.1.0) // @ts-ignore CellRenderer.registerShape(BpmnStyleIdentifier.MESSAGE_FLOW_ICON, MessageFlowIconShape); } From 8e18141fa40635abaac1c0bf6f0aeeeada1055b9 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 19:51:27 +0200 Subject: [PATCH 83/90] StyleConfigurator.ts simplify type --- .../mxgraph/config/StyleConfigurator.ts | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 9e7591b8f2..2e8252e4a0 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -17,9 +17,8 @@ limitations under the License. import { AssociationDirectionKind, FlowKind, SequenceFlowKind, ShapeBpmnElementKind, ShapeUtil } from '../../../model/bpmn/internal'; import { BpmnStyleIdentifier, MarkerIdentifier, StyleDefault } from '../style'; import type { BpmnGraph } from '../BpmnGraph'; -import type { BpmnCellStyle } from '../style/types'; import { constants, Perimeter } from '@maxgraph/core'; -import type { Stylesheet } from '@maxgraph/core'; +import type { CellStyle, Stylesheet } from '@maxgraph/core'; const arrowDefaultSize = 12; @@ -32,18 +31,16 @@ const arrowDefaultSize = 12; * @experimental */ export class StyleConfigurator { - // TODO maxgraph@0.1.0 in StyleConfigurator, we don't need to use BPMNCellStyle, CellStyle is enough - private specificFlowStyles = new MapWithDefault([ [ FlowKind.SEQUENCE_FLOW, - (style: BpmnCellStyle) => { + (style: CellStyle) => { style.endArrow = 'blockThin'; }, ], [ FlowKind.MESSAGE_FLOW, - (style: BpmnCellStyle) => { + (style: CellStyle) => { style.dashed = true; style.dashPattern = '8 5'; style.startArrow = 'oval'; @@ -57,7 +54,7 @@ export class StyleConfigurator { ], [ FlowKind.ASSOCIATION_FLOW, - (style: BpmnCellStyle) => { + (style: CellStyle) => { style.dashed = true; style.dashPattern = '1 2'; // endArrow and startArrow are defined in specific AssociationDirectionKind styles when needed @@ -68,13 +65,13 @@ export class StyleConfigurator { private specificSequenceFlowStyles = new MapWithDefault([ [ SequenceFlowKind.DEFAULT, - (style: BpmnCellStyle) => { + (style: CellStyle) => { style.startArrow = MarkerIdentifier.ARROW_DASH; }, ], [ SequenceFlowKind.CONDITIONAL_FROM_ACTIVITY, - (style: BpmnCellStyle) => { + (style: CellStyle) => { style.startArrow = 'diamondThin'; style.startSize = 18; style.startFill = true; // TODO maxgraph@0.1.0 could be removed when maxGraph fixes https://github.com/maxGraph/maxGraph/pull/157 @@ -86,19 +83,19 @@ export class StyleConfigurator { [ AssociationDirectionKind.NONE, // eslint-disable-next-line @typescript-eslint/no-unused-vars -- prefix parameter name - common practice to acknowledge the fact that some parameter is unused (e.g. in TypeScript compiler) - (_style: BpmnCellStyle) => { + (_style: CellStyle) => { // the style is fully managed by the FlowKind.ASSOCIATION_FLOW style }, ], [ AssociationDirectionKind.ONE, - (style: BpmnCellStyle) => { + (style: CellStyle) => { style.endArrow = 'openThin'; }, ], [ AssociationDirectionKind.BOTH, - (style: BpmnCellStyle) => { + (style: CellStyle) => { style.endArrow = 'openThin'; style.startArrow = 'openThin'; }, @@ -128,7 +125,7 @@ export class StyleConfigurator { return this.graph.getStylesheet(); } - private putCellStyle(name: ShapeBpmnElementKind, style: BpmnCellStyle): void { + private putCellStyle(name: ShapeBpmnElementKind, style: CellStyle): void { this.getStylesheet().putCellStyle(name, style); } @@ -141,7 +138,7 @@ export class StyleConfigurator { } private configurePoolStyle(): void { - const style: BpmnCellStyle = { + const style: CellStyle = { shape: constants.SHAPE.SWIMLANE, // label style verticalAlign: 'middle', @@ -154,7 +151,7 @@ export class StyleConfigurator { } private configureLaneStyle(): void { - const style: BpmnCellStyle = { + const style: CellStyle = { shape: constants.SHAPE.SWIMLANE, // label style verticalAlign: 'middle', @@ -169,7 +166,7 @@ export class StyleConfigurator { private configureEventStyles(): void { ShapeUtil.eventKinds().forEach(kind => { - const style: BpmnCellStyle = { + const style: CellStyle = { shape: kind, // TODO maxgraph@0.10.1 decide if we use the function or the string to set the perimeter // this will reduce adherence to the maxGraph implementation and only use configuration string @@ -183,7 +180,7 @@ export class StyleConfigurator { } private configureTextAnnotationStyle(): void { - const style: BpmnCellStyle = { + const style: CellStyle = { shape: ShapeBpmnElementKind.TEXT_ANNOTATION, // label style verticalAlign: 'middle', @@ -196,7 +193,7 @@ export class StyleConfigurator { } private configureGroupStyle(): void { - const style: BpmnCellStyle = { + const style: CellStyle = { rounded: true, dashed: true, dashPattern: '7 4 1 4', @@ -211,7 +208,7 @@ export class StyleConfigurator { private configureActivityStyles(): void { ShapeUtil.activityKinds().forEach(kind => { - const style: BpmnCellStyle = { + const style: CellStyle = { shape: kind, rounded: true, // required by the BPMN specification verticalAlign: 'middle', // label style @@ -223,7 +220,7 @@ export class StyleConfigurator { private configureGatewayStyles(): void { ShapeUtil.gatewayKinds().forEach(kind => { - const style: BpmnCellStyle = { + const style: CellStyle = { shape: kind, // TODO maxgraph@0.10.1 decide if we use the function or the string to set the perimeter perimeter: Perimeter.RhombusPerimeter, @@ -239,7 +236,7 @@ export class StyleConfigurator { } private configureDefaultEdgeStyle(): void { - const style = this.getStylesheet().getDefaultEdgeStyle() as BpmnCellStyle; + const style = this.getStylesheet().getDefaultEdgeStyle() as CellStyle; configureCommonDefaultStyle(style); style.shape = BpmnStyleIdentifier.EDGE; @@ -253,9 +250,9 @@ export class StyleConfigurator { delete style.endArrow; } - private configureEdgeStyles(styleKinds: T[], specificStyles: Map void>): void { + private configureEdgeStyles(styleKinds: T[], specificStyles: Map void>): void { styleKinds.forEach(kind => { - const style: BpmnCellStyle = {}; + const style: CellStyle = {}; specificStyles.get(kind)(style); this.graph.getStylesheet().putCellStyle(kind.toString(), style); }); @@ -268,7 +265,7 @@ export class StyleConfigurator { } } -function configureCommonDefaultStyle(style: BpmnCellStyle): void { +function configureCommonDefaultStyle(style: CellStyle): void { style.fontFamily = StyleDefault.DEFAULT_FONT_FAMILY; style.fontSize = StyleDefault.DEFAULT_FONT_SIZE; style.fontColor = StyleDefault.DEFAULT_FONT_COLOR; @@ -280,8 +277,8 @@ function configureCommonDefaultStyle(style: BpmnCellStyle): void { style.whiteSpace = 'wrap'; } -class MapWithDefault extends Map void> { - override get(key: T): (style: BpmnCellStyle) => void { +class MapWithDefault extends Map void> { + override get(key: T): (style: CellStyle) => void { return ( super.get(key) ?? (() => { From 34553daa993e0652b3f08f8512d5382e1527e723 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 22:40:32 +0200 Subject: [PATCH 84/90] StyleConfigurator.ts: update TODO --- src/component/mxgraph/config/StyleConfigurator.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 2e8252e4a0..58f1eb3254 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -168,8 +168,9 @@ export class StyleConfigurator { ShapeUtil.eventKinds().forEach(kind => { const style: CellStyle = { shape: kind, - // TODO maxgraph@0.10.1 decide if we use the function or the string to set the perimeter - // this will reduce adherence to the maxGraph implementation and only use configuration string + // TODO maxgraph@0.10.2 decide if we use the function or the string to set the perimeter (apply to all configuration in this file) + // using a string will reduce adherence to the maxGraph implementation + // in case maxGraph provide a way to not register its default style configuration, using a function would avoid to have to register the perimeter in the style registry // be also aware of https://github.com/process-analytics/bpmn-visualization-js/pull/2814#issuecomment-1692971602 perimeter: Perimeter.EllipsePerimeter, strokeWidth: kind == ShapeBpmnElementKind.EVENT_END ? StyleDefault.STROKE_WIDTH_THICK : StyleDefault.STROKE_WIDTH_THIN, @@ -222,7 +223,6 @@ export class StyleConfigurator { ShapeUtil.gatewayKinds().forEach(kind => { const style: CellStyle = { shape: kind, - // TODO maxgraph@0.10.1 decide if we use the function or the string to set the perimeter perimeter: Perimeter.RhombusPerimeter, verticalAlign: 'top', strokeWidth: StyleDefault.STROKE_WIDTH_THIN, From db7e4a2a31764fa43212b458de17ce7ae8bdc732 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Fri, 9 Aug 2024 23:48:52 +0200 Subject: [PATCH 85/90] StyleConfigurator.ts: update TODO --- src/component/mxgraph/config/StyleConfigurator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 58f1eb3254..61f6465b12 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -243,7 +243,7 @@ export class StyleConfigurator { style.endSize = arrowDefaultSize; style.strokeWidth = 1.5; style.rounded = true; - // TODO maxgraph@0.10.1 the rendered edge arcSize seems larger than with mxGraph (also seen with maxgraph 0.1.0) + // TODO maxgraph@0.10.2: possible maxGraph regresssion - the rendered edge arcSize seems larger than with mxGraph (also seen with maxgraph 0.1.0) // style.arcSize = 2; // put 2 in maxgraph@0.10.1, in mxGraph@4.2.2 we used 5 style.verticalAlign = 'bottom'; // The end arrow must be redefined in specific style From 2de8548031ed9af0ec6c57b8fa45906dd850a3c2 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Sat, 10 Aug 2024 00:06:59 +0200 Subject: [PATCH 86/90] StyleConfigurator.ts: TMP update edge arcSize to try to reproduce the mxGraph rendering --- src/component/mxgraph/config/StyleConfigurator.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 61f6465b12..845241b538 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -243,8 +243,8 @@ export class StyleConfigurator { style.endSize = arrowDefaultSize; style.strokeWidth = 1.5; style.rounded = true; - // TODO maxgraph@0.10.2: possible maxGraph regresssion - the rendered edge arcSize seems larger than with mxGraph (also seen with maxgraph 0.1.0) - // style.arcSize = 2; // put 2 in maxgraph@0.10.1, in mxGraph@4.2.2 we used 5 + // TODO maxgraph@0.10.2: possible maxGraph regression - the rendered edge arcSize seems larger than with mxGraph (also seen with maxgraph 0.1.0) + style.arcSize = 2; // put 2 in maxgraph@0.10.1, in mxGraph@4.2.2 we used 5 style.verticalAlign = 'bottom'; // The end arrow must be redefined in specific style delete style.endArrow; From 16768c2bfc8bf48d1b01103ee42abd21533301bf Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Sat, 10 Aug 2024 00:43:02 +0200 Subject: [PATCH 87/90] custom-overlay.ts: update TODO --- src/component/mxgraph/overlay/custom-overlay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/mxgraph/overlay/custom-overlay.ts b/src/component/mxgraph/overlay/custom-overlay.ts index 932ef1c504..25f3e09f54 100644 --- a/src/component/mxgraph/overlay/custom-overlay.ts +++ b/src/component/mxgraph/overlay/custom-overlay.ts @@ -42,7 +42,7 @@ export class MxGraphCustomOverlay extends CellOverlay { this.style = options.style; } - // TODO when doing the real maxGraph migration: update comment and check code migration + // TODO maxgraph@0.10.2: when doing the real maxGraph migration: update comment and check code migration (from maxgraph@0.1.0) // Based on original method from mxCellOverlay (mxCellOverlay.prototype.getBounds) override getBounds(state: CellState): Rectangle { override getBounds(state: CellState): Rectangle { const isEdge = state.cell.isEdge(); From e10cecd9206373532263aa731a4a13135d9db245 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Sun, 11 Aug 2024 18:22:06 +0200 Subject: [PATCH 88/90] StyleConfigurator.ts: TMP update edge arcSize to try to reproduce the mxGraph rendering --- src/component/mxgraph/config/StyleConfigurator.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 845241b538..0dab3f6603 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -244,7 +244,8 @@ export class StyleConfigurator { style.strokeWidth = 1.5; style.rounded = true; // TODO maxgraph@0.10.2: possible maxGraph regression - the rendered edge arcSize seems larger than with mxGraph (also seen with maxgraph 0.1.0) - style.arcSize = 2; // put 2 in maxgraph@0.10.1, in mxGraph@4.2.2 we used 5 + // a better value may be 2.5, this may be due to an extra division by 2 in maxGraph + style.arcSize = 2; // in mxGraph@4.2.2 we used 5 style.verticalAlign = 'bottom'; // The end arrow must be redefined in specific style delete style.endArrow; From da640898b75a21b11a968b7d9c58844c6f05bd43 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:17:59 +0200 Subject: [PATCH 89/90] bump maxgraph to 0.10.3 + fix enabledFolding option in GraphConfigurator.ts --- package.json | 2 +- src/component/mxgraph/GraphConfigurator.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 462dedf5e7..9a0346480b 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "utils:test:model": "node ./scripts/utils/dist/utils.mjs test/fixtures/bpmn/simple-start-task-end.bpmn --output model" }, "dependencies": { - "@maxgraph/core": "0.10.2", + "@maxgraph/core": "0.10.3", "fast-xml-parser": "4.2.5", "lodash-es": "~4.17.21", "strnum": "1.0.5" diff --git a/src/component/mxgraph/GraphConfigurator.ts b/src/component/mxgraph/GraphConfigurator.ts index 4f72ca9a9e..1cac4b7b11 100644 --- a/src/component/mxgraph/GraphConfigurator.ts +++ b/src/component/mxgraph/GraphConfigurator.ts @@ -59,8 +59,7 @@ export default class GraphConfigurator { // Disable folding for container Cell (pool, lane, sub process, call activity) because we don't need it. // This also prevents requesting unavailable images (see #185) as we don't override mxGraph folding default images. - // TODO migration maxgraph 0.10.2 (should be fixed in 0.10.3) - call this.graph.options.foldingEnabled, remove this.graph.foldingEnabled which is not used to manage folding. See https://github.com/maxGraph/maxGraph/pull/426 - this.graph.foldingEnabled = false; + this.graph.options.foldingEnabled = false; } private configureNavigationSupport(options: GlobalOptions): void { From f50b06ef6895be63c7ecc5ec65ec67226a27e738 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:18:15 +0200 Subject: [PATCH 90/90] update package-lock.json after bump maxgraph to 0.10.3 --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 063eec1cd7..f0801851d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.37.0-post", "license": "Apache-2.0", "dependencies": { - "@maxgraph/core": "0.10.2", + "@maxgraph/core": "0.10.3", "fast-xml-parser": "4.2.5", "lodash-es": "~4.17.21", "strnum": "1.0.5" @@ -2824,9 +2824,9 @@ } }, "node_modules/@maxgraph/core": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.2.tgz", - "integrity": "sha512-7Ka/irQkb/TMs2ovEck1YW9SamMHHXUx48tlOBpBLd9lXmidDf/ToDj1bNuvU/j6U6xFwEnWNl7/aBuDHSTbzQ==" + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.3.tgz", + "integrity": "sha512-VeVRaWLw3lqmPlYKj8fIqq/sI0L5TIy65V505GKR+XvGcOuQLYGxJUNurapzxHjAjCR4cxZeyJ1usfjW44yL4Q==" }, "node_modules/@microsoft/api-extractor": { "version": "7.35.2", @@ -14586,9 +14586,9 @@ } }, "@maxgraph/core": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.2.tgz", - "integrity": "sha512-7Ka/irQkb/TMs2ovEck1YW9SamMHHXUx48tlOBpBLd9lXmidDf/ToDj1bNuvU/j6U6xFwEnWNl7/aBuDHSTbzQ==" + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.10.3.tgz", + "integrity": "sha512-VeVRaWLw3lqmPlYKj8fIqq/sI0L5TIy65V505GKR+XvGcOuQLYGxJUNurapzxHjAjCR4cxZeyJ1usfjW44yL4Q==" }, "@microsoft/api-extractor": { "version": "7.35.2",