Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: reduce code duplicated from mxGraph to override shape canvas #3138

Merged
merged 1 commit into from
Aug 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 21 additions & 47 deletions src/component/mxgraph/shape/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,32 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import type { mxShape } from 'mxgraph';
import type { mxShape, mxSvgCanvas2D } from 'mxgraph';

import { mxConstants, mxSvgCanvas2D } from '../initializer';
import { mxConstants } from '../initializer';
import { computeAllBpmnClassNamesOfCell } from '../renderer/style-utils';
import { BpmnStyleIdentifier } from '../style';

export const overrideCreateSvgCanvas = function (shape: mxShape): 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
shape.createSvgCanvas = function () {
// START bpmn-visualization CUSTOMIZATION
// use custom canvas implementation
const canvas = new SvgCanvas2D(this.node, false);
// END bpmn-visualization CUSTOMIZATION
canvas.strokeTolerance = this.pointerEvents ? this.svgStrokeTolerance : 0;
canvas.pointerEventsValue = this.svgPointerEvents;
const off = this.getSvgScreenOffset();

if (off == 0) {
this.node.removeAttribute('transform');
} else {
this.node.setAttribute('transform', 'translate(' + off + ',' + off + ')');
}

// START bpmn-visualization CUSTOMIZATION
// add attributes to be able to identify elements in DOM
const originalShapeCreateSvgCanvas = shape.createSvgCanvas;
shape.createSvgCanvas = function (): mxSvgCanvas2D {
const canvas = originalShapeCreateSvgCanvas.bind(this)();

// getTextCss is only used when creating foreignObject for label, so there is no impact on SVG text that we use for Overlays (Apply to mxgraph@4.2.2)
const originalCanvasGetTextCss = canvas.getTextCss;
canvas.getTextCss = function (): string {
const originalPointerEvents = this.pointerEvents;
// Fix for issue https://github.com/process-analytics/bpmn-visualization-js/issues/920
// This sets the "pointer-events" style property to "none" to avoid capturing the click.
// This cannot be generalized for all mxgraph use cases. For instance, in an editor mode, we should be able to edit the text by clicking on it.
this.pointerEvents = false;

const textCss = originalCanvasGetTextCss.bind(this)();
this.pointerEvents = originalPointerEvents;
return textCss;
};

// The following elements are required to add custom attributes to identify BPMN elements in the DOM
if (this.state?.cell) {
// '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
Expand All @@ -54,33 +54,7 @@ export const overrideCreateSvgCanvas = function (shape: mxShape): void {
this.node.setAttribute('class', allBpmnClassNames.join(' '));
this.node.dataset.bpmnId = this.state.cell.id;
}
// END bpmn-visualization CUSTOMIZATION
canvas.minStrokeWidth = this.minSvgStrokeWidth;

if (!this.antiAlias) {
// Rounds all numbers in the SVG output to integers
canvas.format = function (value: string) {
// eslint-disable-next-line unicorn/prefer-number-properties -- mxGraph code
return Math.round(parseFloat(value));
};
}

return canvas;
};
};

class SvgCanvas2D extends mxSvgCanvas2D {
// 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
override getTextCss(): string {
const originalPointerEvents = this.pointerEvents;
// Fix for issue https://github.com/process-analytics/bpmn-visualization-js/issues/920
// This sets the "pointer-events" style property to "none" to avoid capturing the click.
// This cannot be generalized for all mxgraph use cases. For instance, in an editor mode, we should be able to edit the text by clicking on it.
this.pointerEvents = false;

const textCss = super.getTextCss();
this.pointerEvents = originalPointerEvents;
return textCss;
}
}
Loading