CopyPasteBehavior.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. 'use strict';
  2. var isFunction = require('min-dash').isFunction,
  3. isObject = require('min-dash').isObject,
  4. some = require('min-dash').some;
  5. var WILDCARD = '*';
  6. function CopyPasteBehavior(eventBus) {
  7. var self = this;
  8. eventBus.on('moddleCopy.canCopyProperty', function(context) {
  9. var property = context.property,
  10. parent = context.parent;
  11. return self.canCopyProperty(property, parent);
  12. });
  13. }
  14. CopyPasteBehavior.$inject = [ 'eventBus' ];
  15. /**
  16. * Check wether to disallow copying property.
  17. */
  18. CopyPasteBehavior.prototype.canCopyProperty = function(property, parent) {
  19. // (1) check wether property is allowed in parent
  20. if (isObject(property) && !isAllowedInParent(property, parent)) {
  21. return false;
  22. }
  23. // (2) check more complex scenarios
  24. if (is(property, 'camunda:InputOutput') && !this.canHostInputOutput(parent)) {
  25. return false;
  26. }
  27. if (isAny(property, [ 'camunda:Connector', 'camunda:Field' ]) && !this.canHostConnector(parent)) {
  28. return false;
  29. }
  30. if (is(property, 'camunda:In') && !this.canHostIn(parent)) {
  31. return false;
  32. }
  33. };
  34. CopyPasteBehavior.prototype.canHostInputOutput = function(parent) {
  35. // allowed in camunda:Connector
  36. var connector = getParent(parent, 'camunda:Connector');
  37. if (connector) {
  38. return true;
  39. }
  40. // special rules inside bpmn:FlowNode
  41. var flowNode = getParent(parent, 'bpmn:FlowNode');
  42. if (!flowNode) {
  43. return false;
  44. }
  45. if (isAny(flowNode, [ 'bpmn:StartEvent', 'bpmn:Gateway', 'bpmn:BoundaryEvent' ])) {
  46. return false;
  47. }
  48. if (is(flowNode, 'bpmn:SubProcess') && flowNode.get('triggeredByEvent')) {
  49. return false;
  50. }
  51. return true;
  52. };
  53. CopyPasteBehavior.prototype.canHostConnector = function(parent) {
  54. var serviceTaskLike = getParent(parent, 'camunda:ServiceTaskLike');
  55. if (is(serviceTaskLike, 'bpmn:MessageEventDefinition')) {
  56. // only allow on throw and end events
  57. return (
  58. getParent(parent, 'bpmn:IntermediateThrowEvent') ||
  59. getParent(parent, 'bpmn:EndEvent')
  60. );
  61. }
  62. return true;
  63. };
  64. CopyPasteBehavior.prototype.canHostIn = function(parent) {
  65. var callActivity = getParent(parent, 'bpmn:CallActivity');
  66. if (callActivity) {
  67. return true;
  68. }
  69. var signalEventDefinition = getParent(parent, 'bpmn:SignalEventDefinition');
  70. if (signalEventDefinition) {
  71. // only allow on throw and end events
  72. return (
  73. getParent(parent, 'bpmn:IntermediateThrowEvent') ||
  74. getParent(parent, 'bpmn:EndEvent')
  75. );
  76. }
  77. return true;
  78. };
  79. module.exports = CopyPasteBehavior;
  80. // helpers //////////
  81. function is(element, type) {
  82. return element && isFunction(element.$instanceOf) && element.$instanceOf(type);
  83. }
  84. function isAny(element, types) {
  85. return some(types, function(t) {
  86. return is(element, t);
  87. });
  88. }
  89. function getParent(element, type) {
  90. if (!type) {
  91. return element.$parent;
  92. }
  93. if (is(element, type)) {
  94. return element;
  95. }
  96. if (!element.$parent) {
  97. return;
  98. }
  99. return getParent(element.$parent, type);
  100. }
  101. function isAllowedInParent(property, parent) {
  102. // (1) find property descriptor
  103. var descriptor = property.$type && property.$model.getTypeDescriptor(property.$type);
  104. var allowedIn = descriptor && descriptor.meta && descriptor.meta.allowedIn;
  105. if (!allowedIn || isWildcard(allowedIn)) {
  106. return true;
  107. }
  108. // (2) check wether property has parent of allowed type
  109. return some(allowedIn, function(type) {
  110. return getParent(parent, type);
  111. });
  112. }
  113. function isWildcard(allowedIn) {
  114. return allowedIn.indexOf(WILDCARD) !== -1;
  115. }