UNPKG

bpmn-js

Version:

A bpmn 2.0 toolkit and web modeler

190 lines (149 loc) 4.33 kB
import { assign } from 'min-dash'; import { attr as svgAttr, create as svgCreate } from 'tiny-svg'; import { is, isAny } from '../../util/ModelUtil'; import { isLabel } from '../../util/LabelUtil'; import { DATA_OBJECT_REFERENCE_OUTLINE_PATH, DATA_STORE_REFERENCE_OUTLINE_PATH, DATA_OBJECT_REFERENCE_STANDARD_SIZE, DATA_STORE_REFERENCE_STANDARD_SIZE, createPath } from './OutlineUtil'; /** * @typedef { import('diagram-js/lib/features/outline/OutlineProvider').default } BaseOutlineProvider * * @typedef { import('diagram-js/lib/features/outline/OutlineProvider').Outline } Outline * * @typedef { import('diagram-js/lib/draw/Styles').default } Styles * * @typedef { import('diagram-js/lib/model/Types').Element } Element */ const DEFAULT_OFFSET = 5; /** * BPMN-specific outline provider. * * @implements {BaseOutlineProvider} * * @param {Outline} outline * @param {Styles} styles */ export default function OutlineProvider(outline, styles) { this._styles = styles; outline.registerProvider(this); } OutlineProvider.$inject = [ 'outline', 'styles' ]; /** * Returns outline for a given element. * * @param {Element} element * * @return {Outline} */ OutlineProvider.prototype.getOutline = function(element) { const OUTLINE_STYLE = this._styles.cls('djs-outline', [ 'no-fill' ]); var outline; if (isLabel(element)) { return; } if (is(element, 'bpmn:Gateway')) { outline = svgCreate('rect'); assign(outline.style, { 'transform-box': 'fill-box', 'transform': 'rotate(45deg)', 'transform-origin': 'center' }); svgAttr(outline, assign({ x: 2, y: 2, rx: 4, width: element.width - 4, height: element.height - 4, }, OUTLINE_STYLE)); } else if (isAny(element, [ 'bpmn:Task', 'bpmn:SubProcess', 'bpmn:Group', 'bpmn:CallActivity' ])) { outline = svgCreate('rect'); svgAttr(outline, assign({ x: -DEFAULT_OFFSET, y: -DEFAULT_OFFSET, rx: 14, width: element.width + DEFAULT_OFFSET * 2, height: element.height + DEFAULT_OFFSET * 2 }, OUTLINE_STYLE)); } else if (is(element, 'bpmn:EndEvent')) { outline = svgCreate('circle'); // Extra 1px offset needed due to increased stroke-width of end event // which makes it bigger than other events. svgAttr(outline, assign({ cx: element.width / 2, cy: element.height / 2, r: element.width / 2 + DEFAULT_OFFSET + 1 }, OUTLINE_STYLE)); } else if (is(element, 'bpmn:Event')) { outline = svgCreate('circle'); svgAttr(outline, assign({ cx: element.width / 2, cy: element.height / 2, r: element.width / 2 + DEFAULT_OFFSET }, OUTLINE_STYLE)); } else if (is(element, 'bpmn:DataObjectReference') && isStandardSize(element, 'bpmn:DataObjectReference')) { outline = createPath( DATA_OBJECT_REFERENCE_OUTLINE_PATH, { x: -6, y: -6 }, OUTLINE_STYLE ); } else if (is(element, 'bpmn:DataStoreReference') && isStandardSize(element, 'bpmn:DataStoreReference')) { outline = createPath( DATA_STORE_REFERENCE_OUTLINE_PATH, { x: -6, y: -6 }, OUTLINE_STYLE ); } return outline; }; /** * Updates the outline for a given element. * Returns true if the update for the given element was handled by this provider. * * @param {Element} element * @param {Outline} outline * @returns {boolean} */ OutlineProvider.prototype.updateOutline = function(element, outline) { if (isLabel(element)) { return; } if (isAny(element, [ 'bpmn:SubProcess', 'bpmn:Group' ])) { svgAttr(outline, { width: element.width + DEFAULT_OFFSET * 2, height: element.height + DEFAULT_OFFSET * 2 }); return true; } else if (isAny(element, [ 'bpmn:Event', 'bpmn:Gateway', 'bpmn:DataStoreReference', 'bpmn:DataObjectReference' ])) { return true; } return false; }; // helpers ////////// function isStandardSize(element, type) { var standardSize; if (type === 'bpmn:DataObjectReference') { standardSize = DATA_OBJECT_REFERENCE_STANDARD_SIZE; } else if (type === 'bpmn:DataStoreReference') { standardSize = DATA_STORE_REFERENCE_STANDARD_SIZE; } return element.width === standardSize.width && element.height === standardSize.height; }