import { getBBox } from '../../util/Elements'; var LOW_PRIORITY = 500; import { append as svgAppend, attr as svgAttr, create as svgCreate } from 'tiny-svg'; import { query as domQuery } from 'min-dom'; import { assign } from 'min-dash'; /** * @class * * A plugin that adds an outline to shapes and connections that may be activated and styled * via CSS classes. * * @param {EventBus} eventBus * @param {Styles} styles * @param {ElementRegistry} elementRegistry */ export default function Outline(eventBus, styles, elementRegistry) { this.offset = 6; var OUTLINE_STYLE = styles.cls('djs-outline', [ 'no-fill' ]); var self = this; function createOutline(gfx, bounds) { var outline = svgCreate('rect'); svgAttr(outline, assign({ x: 10, y: 10, width: 100, height: 100 }, OUTLINE_STYLE)); svgAppend(gfx, outline); return outline; } // A low priortity is necessary, because outlines of labels have to be updated // after the label bounds have been updated in the renderer. eventBus.on([ 'shape.added', 'shape.changed' ], LOW_PRIORITY, function(event) { var element = event.element, gfx = event.gfx; var outline = domQuery('.djs-outline', gfx); if (!outline) { outline = createOutline(gfx, element); } self.updateShapeOutline(outline, element); }); eventBus.on([ 'connection.added', 'connection.changed' ], function(event) { var element = event.element, gfx = event.gfx; var outline = domQuery('.djs-outline', gfx); if (!outline) { outline = createOutline(gfx, element); } self.updateConnectionOutline(outline, element); }); } /** * Updates the outline of a shape respecting the dimension of the * element and an outline offset. * * @param {SVGElement} outline * @param {djs.model.Base} element */ Outline.prototype.updateShapeOutline = function(outline, element) { svgAttr(outline, { x: -this.offset, y: -this.offset, width: element.width + this.offset * 2, height: element.height + this.offset * 2 }); }; /** * Updates the outline of a connection respecting the bounding box of * the connection and an outline offset. * * @param {SVGElement} outline * @param {djs.model.Base} element */ Outline.prototype.updateConnectionOutline = function(outline, connection) { var bbox = getBBox(connection); svgAttr(outline, { x: bbox.x - this.offset, y: bbox.y - this.offset, width: bbox.width + this.offset * 2, height: bbox.height + this.offset * 2 }); }; Outline.$inject = ['eventBus', 'styles', 'elementRegistry'];