UpdateLabelHandler.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import {
  2. setLabel,
  3. getLabel
  4. } from '../../../util/LabelUtil';
  5. import {
  6. getExternalLabelMid,
  7. isLabelExternal,
  8. hasExternalLabel,
  9. isLabel
  10. } from '../../../util/LabelUtil';
  11. import {
  12. is
  13. } from '../../../util/ModelUtil';
  14. var NULL_DIMENSIONS = {
  15. width: 0,
  16. height: 0
  17. };
  18. /**
  19. * @typedef {import('../../modeling/Modeling').default} Modeling
  20. * @typedef {import('../../../draw/TextRenderer').default} TextRenderer
  21. * @typedef {import('../../modeling/BpmnFactory').default} BpmnFactory
  22. *
  23. * @typedef {import('../../../model/Types').Element} Element
  24. */
  25. /**
  26. * A handler that updates the text of a BPMN element.
  27. *
  28. * @param {Modeling} modeling
  29. * @param {TextRenderer} textRenderer
  30. * @param {BpmnFactory} bpmnFactory
  31. */
  32. export default function UpdateLabelHandler(modeling, textRenderer, bpmnFactory) {
  33. /**
  34. * Set the label and return the changed elements.
  35. *
  36. * Element parameter can be label itself or connection (i.e. sequence flow).
  37. *
  38. * @param {Element} element
  39. * @param {string} text
  40. */
  41. function setText(element, text) {
  42. // external label if present
  43. var label = element.label || element;
  44. var labelTarget = element.labelTarget || element;
  45. setLabel(label, text, labelTarget !== label);
  46. return [ label, labelTarget ];
  47. }
  48. function preExecute(ctx) {
  49. var element = ctx.element,
  50. businessObject = element.businessObject,
  51. newLabel = ctx.newLabel;
  52. if (!isLabel(element)
  53. && isLabelExternal(element)
  54. && !hasExternalLabel(element)
  55. && !isEmptyText(newLabel)) {
  56. // create label
  57. var paddingTop = 7;
  58. var labelCenter = getExternalLabelMid(element);
  59. labelCenter = {
  60. x: labelCenter.x,
  61. y: labelCenter.y + paddingTop
  62. };
  63. modeling.createLabel(element, labelCenter, {
  64. id: businessObject.id + '_label',
  65. businessObject: businessObject,
  66. di: element.di
  67. });
  68. }
  69. }
  70. function execute(ctx) {
  71. ctx.oldLabel = getLabel(ctx.element);
  72. return setText(ctx.element, ctx.newLabel);
  73. }
  74. function revert(ctx) {
  75. return setText(ctx.element, ctx.oldLabel);
  76. }
  77. function postExecute(ctx) {
  78. var element = ctx.element,
  79. label = element.label || element,
  80. newLabel = ctx.newLabel,
  81. newBounds = ctx.newBounds,
  82. hints = ctx.hints || {};
  83. // ignore internal labels for elements except text annotations
  84. if (!isLabel(label) && !is(label, 'bpmn:TextAnnotation')) {
  85. return;
  86. }
  87. if (isLabel(label) && isEmptyText(newLabel)) {
  88. if (hints.removeShape !== false) {
  89. modeling.removeShape(label, { unsetLabel: false });
  90. }
  91. return;
  92. }
  93. var text = getLabel(element);
  94. // resize element based on label _or_ pre-defined bounds
  95. if (typeof newBounds === 'undefined') {
  96. newBounds = textRenderer.getExternalLabelBounds(label, text);
  97. }
  98. // setting newBounds to false or _null_ will
  99. // disable the postExecute resize operation
  100. if (newBounds) {
  101. modeling.resizeShape(label, newBounds, NULL_DIMENSIONS);
  102. }
  103. }
  104. // API
  105. this.preExecute = preExecute;
  106. this.execute = execute;
  107. this.revert = revert;
  108. this.postExecute = postExecute;
  109. }
  110. UpdateLabelHandler.$inject = [
  111. 'modeling',
  112. 'textRenderer',
  113. 'bpmnFactory'
  114. ];
  115. // helpers //////////
  116. function isEmptyText(label) {
  117. return !label || !label.trim();
  118. }