all files / lib/features/outline/ Outline.js

100% Statements 28/28
100% Branches 4/4
100% Functions 6/6
100% Lines 28/28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123                                                            616×   616×   616×     2227×   2227×             2227×   2227×         616× 2592× 2592×   2592×   2592× 1859×     2592×     616× 571× 571×   571×   571× 368×     571×                         2592×                                   571×   571×                  
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'];