all files / bpmn-js/lib/features/label-editing/cmd/ UpdateLabelHandler.js

100% Statements 40/40
90.63% Branches 29/32
100% Functions 7/7
100% Lines 40/40
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142                                                                          136×   136×   136×   136×       119× 119× 119×   119×           13×   13×   13×         13×               124× 124×       12×       119× 119× 119× 119× 119×   119×             113× 12×     101×     101× 52×       49× 47×         49× 49×           1189× 1189× 1189× 1189×                     117×  
import {
  setLabel,
  getLabel
} from '../LabelUtil';
 
import {
  getExternalLabelMid,
  isLabelExternal,
  hasExternalLabel,
  isLabel
} from '../../../util/LabelUtil';
 
import {
  is
} from '../../../util/ModelUtil';
 
var NULL_DIMENSIONS = {
  width: 0,
  height: 0
};
 
 
/**
 * A handler that updates the text of a BPMN element.
 */
export default function UpdateLabelHandler(modeling, textRenderer) {
 
  /**
   * Set the label and return the changed elements.
   *
   * Element parameter can be label itself or connection (i.e. sequence flow).
   *
   * @param {djs.model.Base} element
   * @param {String} text
   */
  function setText(element, text) {
 
    // external label if present
    var label = element.label || element;
 
    var labelTarget = element.labelTarget || element;
 
    setLabel(label, text, labelTarget !== label);
 
    return [ label, labelTarget ];
  }
 
  function preExecute(ctx) {
    var element = ctx.element,
        businessObject = element.businessObject,
        newLabel = ctx.newLabel;
 
    if (!isLabel(element)
        && isLabelExternal(element)
        && !hasExternalLabel(element)
        && !isEmptyText(newLabel)) {
 
      // create label
      var paddingTop = 7;
 
      var labelCenter = getExternalLabelMid(element);
 
      labelCenter = {
        x: labelCenter.x,
        y: labelCenter.y + paddingTop
      };
 
      modeling.createLabel(element, labelCenter, {
        id: businessObject.id + '_label',
        businessObject: businessObject
      });
    }
  }
 
  function execute(ctx) {
    ctx.oldLabel = getLabel(ctx.element);
    return setText(ctx.element, ctx.newLabel);
  }
 
  function revert(ctx) {
    return setText(ctx.element, ctx.oldLabel);
  }
 
  function postExecute(ctx) {
    var element = ctx.element,
        label = element.label || element,
        newLabel = ctx.newLabel,
        newBounds = ctx.newBounds,
        hints = ctx.hints || {};
 
    if (isLabel(label) && isEmptyText(newLabel)) {
 
      Eif (hints.removeShape !== false) {
        modeling.removeShape(label, { unsetLabel: false });
      }
 
      return;
    }
 
    // ignore internal labels for elements except text annotations
    if (!isLabelExternal(element) && !is(element, 'bpmn:TextAnnotation')) {
      return;
    }
 
    var text = getLabel(label);
 
    // don't resize without text
    if (!text) {
      return;
    }
 
    // resize element based on label _or_ pre-defined bounds
    if (typeof newBounds === 'undefined') {
      newBounds = textRenderer.getExternalLabelBounds(label, text);
    }
 
    // setting newBounds to false or _null_ will
    // disable the postExecute resize operation
    Eif (newBounds) {
      modeling.resizeShape(label, newBounds, NULL_DIMENSIONS);
    }
  }
 
  // API
 
  this.preExecute = preExecute;
  this.execute = execute;
  this.revert = revert;
  this.postExecute = postExecute;
}
 
UpdateLabelHandler.$inject = [
  'modeling',
  'textRenderer'
];
 
 
// helpers ///////////////////////
 
function isEmptyText(label) {
  return !label || !label.trim();
}