
bower_components.bpmn-js.dist.bpmn-modeler.js Maven / Gradle / Ivy
Show all versions of camunda-bpm-process-test-coverage Show documentation
/*!
* bpmn-js - bpmn-modeler v0.14.1
* Copyright 2014, 2015 camunda Services GmbH and other contributors
*
* Released under the bpmn.io license
* http://bpmn.io/license
*
* Source Code: https://github.com/bpmn-io/bpmn-js
*
* Date: 2016-03-23
*/
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.BpmnJS = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o' +
'' +
' ' +
' ' +
'' +
'' +
'' +
' ' +
' ' +
' ' +
' ' +
'';
/**
* A modeler for BPMN 2.0 diagrams.
*
*
* ## Extending the Modeler
*
* In order to extend the viewer pass extension modules to bootstrap via the
* `additionalModules` option. An extension module is an object that exposes
* named services.
*
* The following example depicts the integration of a simple
* logging component that integrates with interaction events:
*
*
* ```javascript
*
* // logging component
* function InteractionLogger(eventBus) {
* eventBus.on('element.hover', function(event) {
* console.log()
* })
* }
*
* InteractionLogger.$inject = [ 'eventBus' ]; // minification save
*
* // extension module
* var extensionModule = {
* __init__: [ 'interactionLogger' ],
* interactionLogger: [ 'type', InteractionLogger ]
* };
*
* // extend the viewer
* var bpmnModeler = new Modeler({ additionalModules: [ extensionModule ] });
* bpmnModeler.importXML(...);
* ```
*
*
* ## Customizing / Replacing Components
*
* You can replace individual diagram components by redefining them in override modules.
* This works for all components, including those defined in the core.
*
* Pass in override modules via the `options.additionalModules` flag like this:
*
* ```javascript
* function CustomContextPadProvider(contextPad) {
*
* contextPad.registerProvider(this);
*
* this.getContextPadEntries = function(element) {
* // no entries, effectively disable the context pad
* return {};
* };
* }
*
* CustomContextPadProvider.$inject = [ 'contextPad' ];
*
* var overrideModule = {
* contextPadProvider: [ 'type', CustomContextPadProvider ]
* };
*
* var bpmnModeler = new Modeler({ additionalModules: [ overrideModule ]});
* ```
*
* @param {Object} [options] configuration options to pass to the viewer
* @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
* @param {String|Number} [options.width] the width of the viewer
* @param {String|Number} [options.height] the height of the viewer
* @param {Object} [options.moddleExtensions] extension packages to provide
* @param {Array} [options.modules] a list of modules to override the default modules
* @param {Array} [options.additionalModules] a list of modules to use with the default modules
*/
function Modeler(options) {
Viewer.call(this, options);
// hook ID collection into the modeler
this.on('import.parse.complete', function(event) {
if (!event.error) {
this._collectIds(event.definitions, event.context);
}
}, this);
this.on('diagram.destroy', function() {
this.moddle.ids.clear();
}, this);
}
inherits(Modeler, Viewer);
module.exports = Modeler;
/**
* Create a new diagram to start modeling.
*
* @param {Function} [done]
*/
Modeler.prototype.createDiagram = function(done) {
return this.importXML(initialDiagram, done);
};
/**
* Create a moddle instance, attaching ids to it.
*
* @param {Object} options
*/
Modeler.prototype._createModdle = function(options) {
var moddle = Viewer.prototype._createModdle.call(this, options);
// attach ids to moddle to be able to track
// and validated ids in the BPMN 2.0 XML document
// tree
moddle.ids = new Ids([ 32, 36, 1 ]);
return moddle;
};
/**
* Collect ids processed during parsing of the
* definitions object.
*
* @param {ModdleElement} definitions
* @param {Context} context
*/
Modeler.prototype._collectIds = function(definitions, context) {
var moddle = definitions.$model,
ids = moddle.ids,
id;
// remove references from previous import
ids.clear();
for (id in context.elementsById) {
ids.claim(id, context.elementsById[id]);
}
};
Modeler.prototype._interactionModules = [
// non-modeling components
_dereq_(16),
_dereq_(8),
_dereq_(216),
_dereq_(212),
_dereq_(213)
];
Modeler.prototype._modelingModules = [
// modeling components
_dereq_(166),
_dereq_(118),
_dereq_(182),
_dereq_(196),
_dereq_(141),
_dereq_(133),
_dereq_(12),
_dereq_(62),
_dereq_(43),
_dereq_(10),
_dereq_(49),
_dereq_(54)
];
// modules the modeler is composed of
//
// - viewer modules
// - interaction modules
// - modeling modules
Modeler.prototype._modules = [].concat(
Modeler.prototype._modules,
Modeler.prototype._interactionModules,
Modeler.prototype._modelingModules);
},{"10":10,"118":118,"12":12,"133":133,"141":141,"16":16,"166":166,"182":182,"196":196,"2":2,"212":212,"213":213,"216":216,"241":241,"243":243,"43":43,"49":49,"54":54,"62":62,"8":8}],2:[function(_dereq_,module,exports){
/**
* The code in the area
* must not be changed.
*
* @see http://bpmn.io/license for more information.
*/
'use strict';
var assign = _dereq_(377),
omit = _dereq_(381),
isString = _dereq_(374),
isNumber = _dereq_(371);
var domify = _dereq_(394),
domQuery = _dereq_(397),
domRemove = _dereq_(398);
var Diagram = _dereq_(96),
BpmnModdle = _dereq_(72);
var inherits = _dereq_(243);
var Importer = _dereq_(65);
function checkValidationError(err) {
// check if we can help the user by indicating wrong BPMN 2.0 xml
// (in case he or the exporting tool did not get that right)
var pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/;
var match = pattern.exec(err.message);
if (match) {
err.message =
'unparsable content <' + match[1] + '> detected; ' +
'this may indicate an invalid BPMN 2.0 diagram file' + match[2];
}
return err;
}
var DEFAULT_OPTIONS = {
width: '100%',
height: '100%',
position: 'relative',
container: 'body'
};
/**
* Ensure the passed argument is a proper unit (defaulting to px)
*/
function ensureUnit(val) {
return val + (isNumber(val) ? 'px' : '');
}
/**
* A viewer for BPMN 2.0 diagrams.
*
* Have a look at {@link NavigatedViewer} or {@link Modeler} for bundles that include
* additional features.
*
*
* ## Extending the Viewer
*
* In order to extend the viewer pass extension modules to bootstrap via the
* `additionalModules` option. An extension module is an object that exposes
* named services.
*
* The following example depicts the integration of a simple
* logging component that integrates with interaction events:
*
*
* ```javascript
*
* // logging component
* function InteractionLogger(eventBus) {
* eventBus.on('element.hover', function(event) {
* console.log()
* })
* }
*
* InteractionLogger.$inject = [ 'eventBus' ]; // minification save
*
* // extension module
* var extensionModule = {
* __init__: [ 'interactionLogger' ],
* interactionLogger: [ 'type', InteractionLogger ]
* };
*
* // extend the viewer
* var bpmnViewer = new Viewer({ additionalModules: [ extensionModule ] });
* bpmnViewer.importXML(...);
* ```
*
* @param {Object} [options] configuration options to pass to the viewer
* @param {DOMElement} [options.container] the container to render the viewer in, defaults to body.
* @param {String|Number} [options.width] the width of the viewer
* @param {String|Number} [options.height] the height of the viewer
* @param {Object} [options.moddleExtensions] extension packages to provide
* @param {Array} [options.modules] a list of modules to override the default modules
* @param {Array} [options.additionalModules] a list of modules to use with the default modules
*/
function Viewer(options) {
options = assign({}, DEFAULT_OPTIONS, options);
this.moddle = this._createModdle(options);
this.container = this._createContainer(options);
/* */
addProjectLogo(this.container);
/* */
this._init(this.container, this.moddle, options);
}
inherits(Viewer, Diagram);
module.exports = Viewer;
/**
* Parse and render a BPMN 2.0 diagram.
*
* Once finished the viewer reports back the result to the
* provided callback function with (err, warnings).
*
* ## Life-Cycle Events
*
* During import the viewer will fire life-cycle events:
*
* * import.parse.start (about to read model from xml)
* * import.parse.complete (model read; may have worked or not)
* * import.render.start (graphical import start)
* * import.render.complete (graphical import finished)
* * import.done (everything done)
*
* You can use these events to hook into the life-cycle.
*
* @param {String} xml the BPMN 2.0 xml
* @param {Function} [done] invoked with (err, warnings=[])
*/
Viewer.prototype.importXML = function(xml, done) {
// done is optional
done = done || function() {};
var self = this;
// hook in pre-parse listeners +
// allow xml manipulation
xml = this._emit('import.parse.start', { xml: xml }) || xml;
this.moddle.fromXML(xml, 'bpmn:Definitions', function(err, definitions, context) {
// hook in post parse listeners +
// allow definitions manipulation
definitions = self._emit('import.parse.complete', {
error: err,
definitions: definitions,
context: context
}) || definitions;
if (err) {
err = checkValidationError(err);
self._emit('import.done', { error: err });
return done(err);
}
var parseWarnings = context.warnings;
self.importDefinitions(definitions, function(err, importWarnings) {
var allWarnings = [].concat(parseWarnings, importWarnings || []);
self._emit('import.done', { error: err, warnings: allWarnings });
done(err, allWarnings);
});
});
};
/**
* Export the currently displayed BPMN 2.0 diagram as
* a BPMN 2.0 XML document.
*
* @param {Object} [options] export options
* @param {Boolean} [options.format=false] output formated XML
* @param {Boolean} [options.preamble=true] output preamble
*
* @param {Function} done invoked with (err, xml)
*/
Viewer.prototype.saveXML = function(options, done) {
if (!done) {
done = options;
options = {};
}
var definitions = this.definitions;
if (!definitions) {
return done(new Error('no definitions loaded'));
}
this.moddle.toXML(definitions, options, done);
};
/**
* Export the currently displayed BPMN 2.0 diagram as
* an SVG image.
*
* @param {Object} [options]
* @param {Function} done invoked with (err, svgStr)
*/
Viewer.prototype.saveSVG = function(options, done) {
if (!done) {
done = options;
options = {};
}
var canvas = this.get('canvas');
var contentNode = canvas.getDefaultLayer(),
defsNode = canvas._svg.select('defs');
var contents = contentNode.innerSVG(),
defs = (defsNode && defsNode.outerSVG()) || '';
var bbox = contentNode.getBBox();
var svg =
'\n' +
'\n' +
'\n' +
'';
done(null, svg);
};
/**
* Get a named diagram service.
*
* @example
*
* var elementRegistry = viewer.get('elementRegistry');
* var startEventShape = elementRegistry.get('StartEvent_1');
*
* @param {String} name
*
* @return {Object} diagram service instance
*
* @method Viewer#get
*/
/**
* Invoke a function in the context of this viewer.
*
* @example
*
* viewer.invoke(function(elementRegistry) {
* var startEventShape = elementRegistry.get('StartEvent_1');
* });
*
* @param {Function} fn to be invoked
*
* @return {Object} the functions return value
*
* @method Viewer#invoke
*/
/**
* Remove all drawn elements from the viewer.
*
* After calling this method the viewer can still
* be reused for opening another diagram.
*
* @method Viewer#clear
*/
Viewer.prototype.importDefinitions = function(definitions, done) {
// use try/catch to not swallow synchronous exceptions
// that may be raised during model parsing
try {
if (this.definitions) {
// clear existing rendered diagram
this.clear();
}
// update definitions
this.definitions = definitions;
// perform graphical import
Importer.importBpmnDiagram(this, definitions, done);
} catch (e) {
// handle synchronous errors
done(e);
}
};
Viewer.prototype.getModules = function() {
return this._modules;
};
/**
* Destroy the viewer instance and remove all its
* remainders from the document tree.
*/
Viewer.prototype.destroy = function() {
// diagram destroy
Diagram.prototype.destroy.call(this);
// dom detach
domRemove(this.container);
};
/**
* Register an event listener
*
* Remove a previously added listener via {@link #off(event, callback)}.
*
* @param {String} event
* @param {Number} [priority]
* @param {Function} callback
* @param {Object} [that]
*/
Viewer.prototype.on = function(event, priority, callback, target) {
return this.get('eventBus').on(event, priority, callback, target);
};
/**
* De-register an event listener
*
* @param {String} event
* @param {Function} callback
*/
Viewer.prototype.off = function(event, callback) {
this.get('eventBus').off(event, callback);
};
Viewer.prototype._init = function(container, moddle, options) {
var baseModules = options.modules || this.getModules(),
additionalModules = options.additionalModules || [],
staticModules = [
{
bpmnjs: [ 'value', this ],
moddle: [ 'value', moddle ]
}
];
var diagramModules = [].concat(staticModules, baseModules, additionalModules);
var diagramOptions = assign(omit(options, 'additionalModules'), {
canvas: assign({}, options.canvas, { container: container }),
modules: diagramModules
});
// invoke diagram constructor
Diagram.call(this, diagramOptions);
};
/**
* Emit an event on the underlying {@link EventBus}
*
* @param {String} type
* @param {Object} event
*
* @return {Object} event processing result (if any)
*/
Viewer.prototype._emit = function(type, event) {
return this.get('eventBus').fire(type, event);
};
Viewer.prototype._createContainer = function(options) {
var parent = options.container,
container;
// support jquery element
// unwrap it if passed
if (parent.get) {
parent = parent.get(0);
}
// support selector
if (isString(parent)) {
parent = domQuery(parent);
}
container = domify('');
assign(container.style, {
width: ensureUnit(options.width),
height: ensureUnit(options.height),
position: options.position
});
parent.appendChild(container);
return container;
};
Viewer.prototype._createModdle = function(options) {
var moddleOptions = assign({}, this._moddleExtensions, options.moddleExtensions);
return new BpmnModdle(moddleOptions);
};
// modules the viewer is composed of
Viewer.prototype._modules = [
_dereq_(3),
_dereq_(204),
_dereq_(189),
_dereq_(171)
];
// default moddle extensions the viewer is composed of
Viewer.prototype._moddleExtensions = {};
/* */
var PoweredBy = _dereq_(71),
domEvent = _dereq_(395);
/**
* Adds the project logo to the diagram container as
* required by the bpmn.io license.
*
* @see http://bpmn.io/license
*
* @param {Element} container
*/
function addProjectLogo(container) {
var logoData = PoweredBy.BPMNIO_LOGO;
var linkMarkup =
'' +
'
' +
'';
var linkElement = domify(linkMarkup);
container.appendChild(linkElement);
domEvent.bind(linkElement, 'click', function(event) {
PoweredBy.open();
event.preventDefault();
});
}
/* */
},{"171":171,"189":189,"204":204,"243":243,"3":3,"371":371,"374":374,"377":377,"381":381,"394":394,"395":395,"397":397,"398":398,"65":65,"71":71,"72":72,"96":96}],3:[function(_dereq_,module,exports){
module.exports = {
__depends__: [
_dereq_(6),
_dereq_(67)
]
};
},{"6":6,"67":67}],4:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243),
isObject = _dereq_(372),
assign = _dereq_(377),
forEach = _dereq_(255),
every = _dereq_(252),
includes = _dereq_(257),
some = _dereq_(261);
var BaseRenderer = _dereq_(107),
TextUtil = _dereq_(232),
DiUtil = _dereq_(68);
var is = _dereq_(70).is;
var RenderUtil = _dereq_(231);
var componentsToPath = RenderUtil.componentsToPath,
createLine = RenderUtil.createLine;
var TASK_BORDER_RADIUS = 10;
var INNER_OUTER_DIST = 3;
var LABEL_STYLE = {
fontFamily: 'Arial, sans-serif',
fontSize: '12px'
};
function BpmnRenderer(eventBus, styles, pathMap, priority) {
BaseRenderer.call(this, eventBus, priority);
var textUtil = new TextUtil({
style: LABEL_STYLE,
size: { width: 100 }
});
var markers = {};
var computeStyle = styles.computeStyle;
function addMarker(id, element) {
markers[id] = element;
}
function marker(id) {
return markers[id];
}
function initMarkers(svg) {
function createMarker(id, options) {
var attrs = assign({
fill: 'black',
strokeWidth: 1,
strokeLinecap: 'round',
strokeDasharray: 'none'
}, options.attrs);
var ref = options.ref || { x: 0, y: 0 };
var scale = options.scale || 1;
// fix for safari / chrome / firefox bug not correctly
// resetting stroke dash array
if (attrs.strokeDasharray === 'none') {
attrs.strokeDasharray = [10000, 1];
}
var marker = options.element
.attr(attrs)
.marker(0, 0, 20, 20, ref.x, ref.y)
.attr({
markerWidth: 20 * scale,
markerHeight: 20 * scale
});
return addMarker(id, marker);
}
createMarker('sequenceflow-end', {
element: svg.path('M 1 5 L 11 10 L 1 15 Z'),
ref: { x: 11, y: 10 },
scale: 0.5
});
createMarker('messageflow-start', {
element: svg.circle(6, 6, 3.5),
attrs: {
fill: 'white',
stroke: 'black'
},
ref: { x: 6, y: 6 }
});
createMarker('messageflow-end', {
element: svg.path('m 1 5 l 0 -3 l 7 3 l -7 3 z'),
attrs: {
fill: 'white',
stroke: 'black',
strokeLinecap: 'butt'
},
ref: { x: 8.5, y: 5 }
});
createMarker('association-start', {
element: svg.path('M 11 5 L 1 10 L 11 15'),
attrs: {
fill: 'none',
stroke: 'black',
strokeWidth: 1.5
},
ref: { x: 1, y: 10 },
scale: 0.5
});
createMarker('association-end', {
element: svg.path('M 1 5 L 11 10 L 1 15'),
attrs: {
fill: 'none',
stroke: 'black',
strokeWidth: 1.5
},
ref: { x: 12, y: 10 },
scale: 0.5
});
createMarker('conditional-flow-marker', {
element: svg.path('M 0 10 L 8 6 L 16 10 L 8 14 Z'),
attrs: {
fill: 'white',
stroke: 'black'
},
ref: { x: -1, y: 10 },
scale: 0.5
});
createMarker('conditional-default-flow-marker', {
element: svg.path('M 1 4 L 5 16'),
attrs: {
stroke: 'black'
},
ref: { x: -5, y: 10 },
scale: 0.5
});
}
function drawCircle(p, width, height, offset, attrs) {
if (isObject(offset)) {
attrs = offset;
offset = 0;
}
offset = offset || 0;
attrs = computeStyle(attrs, {
stroke: 'black',
strokeWidth: 2,
fill: 'white'
});
var cx = width / 2,
cy = height / 2;
return p.circle(cx, cy, Math.round((width + height) / 4 - offset)).attr(attrs);
}
function drawRect(p, width, height, r, offset, attrs) {
if (isObject(offset)) {
attrs = offset;
offset = 0;
}
offset = offset || 0;
attrs = computeStyle(attrs, {
stroke: 'black',
strokeWidth: 2,
fill: 'white'
});
return p.rect(offset, offset, width - offset * 2, height - offset * 2, r).attr(attrs);
}
function drawDiamond(p, width, height, attrs) {
var x_2 = width / 2;
var y_2 = height / 2;
var points = [x_2, 0, width, y_2, x_2, height, 0, y_2 ];
attrs = computeStyle(attrs, {
stroke: 'black',
strokeWidth: 2,
fill: 'white'
});
return p.polygon(points).attr(attrs);
}
function drawLine(p, waypoints, attrs) {
attrs = computeStyle(attrs, [ 'no-fill' ], {
stroke: 'black',
strokeWidth: 2,
fill: 'none'
});
return createLine(waypoints, attrs).appendTo(p);
}
function drawPath(p, d, attrs) {
attrs = computeStyle(attrs, [ 'no-fill' ], {
strokeWidth: 2,
stroke: 'black'
});
return p.path(d).attr(attrs);
}
function drawMarker(type, p, path, attrs) {
return drawPath(p, path, assign({ 'data-marker': type }, attrs));
}
function as(type) {
return function(p, element) {
return handlers[type](p, element);
};
}
function renderer(type) {
return handlers[type];
}
function renderEventContent(element, p) {
var event = getSemantic(element);
var isThrowing = isThrowEvent(event);
if (isTypedEvent(event, 'bpmn:MessageEventDefinition')) {
return renderer('bpmn:MessageEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:TimerEventDefinition')) {
return renderer('bpmn:TimerEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:ConditionalEventDefinition')) {
return renderer('bpmn:ConditionalEventDefinition')(p, element);
}
if (isTypedEvent(event, 'bpmn:SignalEventDefinition')) {
return renderer('bpmn:SignalEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:CancelEventDefinition') &&
isTypedEvent(event, 'bpmn:TerminateEventDefinition', { parallelMultiple: false })) {
return renderer('bpmn:MultipleEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:CancelEventDefinition') &&
isTypedEvent(event, 'bpmn:TerminateEventDefinition', { parallelMultiple: true })) {
return renderer('bpmn:ParallelMultipleEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:EscalationEventDefinition')) {
return renderer('bpmn:EscalationEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:LinkEventDefinition')) {
return renderer('bpmn:LinkEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:ErrorEventDefinition')) {
return renderer('bpmn:ErrorEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:CancelEventDefinition')) {
return renderer('bpmn:CancelEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:CompensateEventDefinition')) {
return renderer('bpmn:CompensateEventDefinition')(p, element, isThrowing);
}
if (isTypedEvent(event, 'bpmn:TerminateEventDefinition')) {
return renderer('bpmn:TerminateEventDefinition')(p, element, isThrowing);
}
return null;
}
function renderLabel(p, label, options) {
return textUtil.createText(p, label || '', options).addClass('djs-label');
}
function renderEmbeddedLabel(p, element, align) {
var semantic = getSemantic(element);
return renderLabel(p, semantic.name, { box: element, align: align, padding: 5 });
}
function renderExternalLabel(p, element, align) {
var semantic = getSemantic(element);
return renderLabel(p, semantic.name, { box: element, align: align, style: { fontSize: '11px' } });
}
function renderLaneLabel(p, text, element) {
var textBox = renderLabel(p, text, {
box: { height: 30, width: element.height },
align: 'center-middle'
});
var top = -1 * element.height;
textBox.transform(
'rotate(270) ' +
'translate(' + top + ',' + 0 + ')'
);
}
function createPathFromConnection(connection) {
var waypoints = connection.waypoints;
var pathData = 'm ' + waypoints[0].x + ',' + waypoints[0].y;
for (var i = 1; i < waypoints.length; i++) {
pathData += 'L' + waypoints[i].x + ',' + waypoints[i].y + ' ';
}
return pathData;
}
var handlers = this.handlers = {
'bpmn:Event': function(p, element, attrs) {
return drawCircle(p, element.width, element.height, attrs);
},
'bpmn:StartEvent': function(p, element) {
var attrs = {};
var semantic = getSemantic(element);
if (!semantic.isInterrupting) {
attrs = {
strokeDasharray: '6',
strokeLinecap: 'round'
};
}
var circle = renderer('bpmn:Event')(p, element, attrs);
renderEventContent(element, p);
return circle;
},
'bpmn:MessageEventDefinition': function(p, element, isThrowing) {
var pathData = pathMap.getScaledPath('EVENT_MESSAGE', {
xScaleFactor: 0.9,
yScaleFactor: 0.9,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.235,
my: 0.315
}
});
var fill = isThrowing ? 'black' : 'white';
var stroke = isThrowing ? 'white' : 'black';
var messagePath = drawPath(p, pathData, {
strokeWidth: 1,
fill: fill,
stroke: stroke
});
return messagePath;
},
'bpmn:TimerEventDefinition': function(p, element) {
var circle = drawCircle(p, element.width, element.height, 0.2 * element.height, {
strokeWidth: 2
});
var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', {
xScaleFactor: 0.75,
yScaleFactor: 0.75,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.5,
my: 0.5
}
});
drawPath(p, pathData, {
strokeWidth: 2,
strokeLinecap: 'square'
});
for(var i = 0;i < 12;i++) {
var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', {
xScaleFactor: 0.75,
yScaleFactor: 0.75,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.5,
my: 0.5
}
});
var width = element.width / 2;
var height = element.height / 2;
drawPath(p, linePathData, {
strokeWidth: 1,
strokeLinecap: 'square',
transform: 'rotate(' + (i * 30) + ',' + height + ',' + width + ')'
});
}
return circle;
},
'bpmn:EscalationEventDefinition': function(p, event, isThrowing) {
var pathData = pathMap.getScaledPath('EVENT_ESCALATION', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: event.width,
containerHeight: event.height,
position: {
mx: 0.5,
my: 0.555
}
});
var fill = isThrowing ? 'black' : 'none';
return drawPath(p, pathData, {
strokeWidth: 1,
fill: fill
});
},
'bpmn:ConditionalEventDefinition': function(p, event) {
var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: event.width,
containerHeight: event.height,
position: {
mx: 0.5,
my: 0.222
}
});
return drawPath(p, pathData, {
strokeWidth: 1
});
},
'bpmn:LinkEventDefinition': function(p, event, isThrowing) {
var pathData = pathMap.getScaledPath('EVENT_LINK', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: event.width,
containerHeight: event.height,
position: {
mx: 0.57,
my: 0.263
}
});
var fill = isThrowing ? 'black' : 'none';
return drawPath(p, pathData, {
strokeWidth: 1,
fill: fill
});
},
'bpmn:ErrorEventDefinition': function(p, event, isThrowing) {
var pathData = pathMap.getScaledPath('EVENT_ERROR', {
xScaleFactor: 1.1,
yScaleFactor: 1.1,
containerWidth: event.width,
containerHeight: event.height,
position: {
mx: 0.2,
my: 0.722
}
});
var fill = isThrowing ? 'black' : 'none';
return drawPath(p, pathData, {
strokeWidth: 1,
fill: fill
});
},
'bpmn:CancelEventDefinition': function(p, event, isThrowing) {
var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', {
xScaleFactor: 1.0,
yScaleFactor: 1.0,
containerWidth: event.width,
containerHeight: event.height,
position: {
mx: 0.638,
my: -0.055
}
});
var fill = isThrowing ? 'black' : 'none';
return drawPath(p, pathData, {
strokeWidth: 1,
fill: fill
}).transform('rotate(45)');
},
'bpmn:CompensateEventDefinition': function(p, event, isThrowing) {
var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: event.width,
containerHeight: event.height,
position: {
mx: 0.22,
my: 0.5
}
});
var fill = isThrowing ? 'black' : 'none';
return drawPath(p, pathData, {
strokeWidth: 1,
fill: fill
});
},
'bpmn:SignalEventDefinition': function(p, event, isThrowing) {
var pathData = pathMap.getScaledPath('EVENT_SIGNAL', {
xScaleFactor: 0.9,
yScaleFactor: 0.9,
containerWidth: event.width,
containerHeight: event.height,
position: {
mx: 0.5,
my: 0.2
}
});
var fill = isThrowing ? 'black' : 'none';
return drawPath(p, pathData, {
strokeWidth: 1,
fill: fill
});
},
'bpmn:MultipleEventDefinition': function(p, event, isThrowing) {
var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', {
xScaleFactor: 1.1,
yScaleFactor: 1.1,
containerWidth: event.width,
containerHeight: event.height,
position: {
mx: 0.222,
my: 0.36
}
});
var fill = isThrowing ? 'black' : 'none';
return drawPath(p, pathData, {
strokeWidth: 1,
fill: fill
});
},
'bpmn:ParallelMultipleEventDefinition': function(p, event) {
var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', {
xScaleFactor: 1.2,
yScaleFactor: 1.2,
containerWidth: event.width,
containerHeight: event.height,
position: {
mx: 0.458,
my: 0.194
}
});
return drawPath(p, pathData, {
strokeWidth: 1
});
},
'bpmn:EndEvent': function(p, element) {
var circle = renderer('bpmn:Event')(p, element, {
strokeWidth: 4
});
renderEventContent(element, p, true);
return circle;
},
'bpmn:TerminateEventDefinition': function(p, element) {
var circle = drawCircle(p, element.width, element.height, 8, {
strokeWidth: 4,
fill: 'black'
});
return circle;
},
'bpmn:IntermediateEvent': function(p, element) {
var outer = renderer('bpmn:Event')(p, element, { strokeWidth: 1 });
/* inner */ drawCircle(p, element.width, element.height, INNER_OUTER_DIST, { strokeWidth: 1, fill: 'none' });
renderEventContent(element, p);
return outer;
},
'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'),
'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'),
'bpmn:Activity': function(p, element, attrs) {
return drawRect(p, element.width, element.height, TASK_BORDER_RADIUS, attrs);
},
'bpmn:Task': function(p, element, attrs) {
var rect = renderer('bpmn:Activity')(p, element, attrs);
renderEmbeddedLabel(p, element, 'center-middle');
attachTaskMarkers(p, element);
return rect;
},
'bpmn:ServiceTask': function(p, element) {
var task = renderer('bpmn:Task')(p, element);
var pathDataBG = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
abspos: {
x: 12,
y: 18
}
});
/* service bg */ drawPath(p, pathDataBG, {
strokeWidth: 1,
fill: 'none'
});
var fillPathData = pathMap.getScaledPath('TASK_TYPE_SERVICE_FILL', {
abspos: {
x: 17.2,
y: 18
}
});
/* service fill */ drawPath(p, fillPathData, {
strokeWidth: 0,
stroke: 'none',
fill: 'white'
});
var pathData = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
abspos: {
x: 17,
y: 22
}
});
/* service */ drawPath(p, pathData, {
strokeWidth: 1,
fill: 'white'
});
return task;
},
'bpmn:UserTask': function(p, element) {
var task = renderer('bpmn:Task')(p, element);
var x = 15;
var y = 12;
var pathData = pathMap.getScaledPath('TASK_TYPE_USER_1', {
abspos: {
x: x,
y: y
}
});
/* user path */ drawPath(p, pathData, {
strokeWidth: 0.5,
fill: 'none'
});
var pathData2 = pathMap.getScaledPath('TASK_TYPE_USER_2', {
abspos: {
x: x,
y: y
}
});
/* user2 path */ drawPath(p, pathData2, {
strokeWidth: 0.5,
fill: 'none'
});
var pathData3 = pathMap.getScaledPath('TASK_TYPE_USER_3', {
abspos: {
x: x,
y: y
}
});
/* user3 path */ drawPath(p, pathData3, {
strokeWidth: 0.5,
fill: 'black'
});
return task;
},
'bpmn:ManualTask': function(p, element) {
var task = renderer('bpmn:Task')(p, element);
var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', {
abspos: {
x: 17,
y: 15
}
});
/* manual path */ drawPath(p, pathData, {
strokeWidth: 0.25,
fill: 'white',
stroke: 'black'
});
return task;
},
'bpmn:SendTask': function(p, element) {
var task = renderer('bpmn:Task')(p, element);
var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: 21,
containerHeight: 14,
position: {
mx: 0.285,
my: 0.357
}
});
/* send path */ drawPath(p, pathData, {
strokeWidth: 1,
fill: 'black',
stroke: 'white'
});
return task;
},
'bpmn:ReceiveTask' : function(p, element) {
var semantic = getSemantic(element);
var task = renderer('bpmn:Task')(p, element);
var pathData;
if (semantic.instantiate) {
drawCircle(p, 28, 28, 20 * 0.22, { strokeWidth: 1 });
pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', {
abspos: {
x: 7.77,
y: 9.52
}
});
} else {
pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
xScaleFactor: 0.9,
yScaleFactor: 0.9,
containerWidth: 21,
containerHeight: 14,
position: {
mx: 0.3,
my: 0.4
}
});
}
/* receive path */ drawPath(p, pathData, {
strokeWidth: 1
});
return task;
},
'bpmn:ScriptTask': function(p, element) {
var task = renderer('bpmn:Task')(p, element);
var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', {
abspos: {
x: 15,
y: 20
}
});
/* script path */ drawPath(p, pathData, {
strokeWidth: 1
});
return task;
},
'bpmn:BusinessRuleTask': function(p, element) {
var task = renderer('bpmn:Task')(p, element);
var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', {
abspos: {
x: 8,
y: 8
}
});
var businessHeaderPath = drawPath(p, headerPathData);
businessHeaderPath.attr({
strokeWidth: 1,
fill: 'AAA'
});
var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', {
abspos: {
x: 8,
y: 8
}
});
var businessPath = drawPath(p, headerData);
businessPath.attr({
strokeWidth: 1
});
return task;
},
'bpmn:SubProcess': function(p, element, attrs) {
attrs = assign({ fillOpacity: 0.95 }, attrs);
var rect = renderer('bpmn:Activity')(p, element, attrs);
var expanded = DiUtil.isExpanded(element);
var isEventSubProcess = DiUtil.isEventSubProcess(element);
if (isEventSubProcess) {
rect.attr({
strokeDasharray: '1,2'
});
}
renderEmbeddedLabel(p, element, expanded ? 'center-top' : 'center-middle');
if (expanded) {
attachTaskMarkers(p, element);
} else {
attachTaskMarkers(p, element, ['SubProcessMarker']);
}
return rect;
},
'bpmn:AdHocSubProcess': function(p, element) {
return renderer('bpmn:SubProcess')(p, element);
},
'bpmn:Transaction': function(p, element) {
var outer = renderer('bpmn:SubProcess')(p, element);
var innerAttrs = styles.style([ 'no-fill', 'no-events' ]);
/* inner path */ drawRect(p, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs);
return outer;
},
'bpmn:CallActivity': function(p, element) {
return renderer('bpmn:SubProcess')(p, element, {
strokeWidth: 5
});
},
'bpmn:Participant': function(p, element) {
var lane = renderer('bpmn:Lane')(p, element, {
fillOpacity: 0.95,
fill: 'White'
});
var expandedPool = DiUtil.isExpanded(element);
if (expandedPool) {
drawLine(p, [
{ x: 30, y: 0 },
{ x: 30, y: element.height }
]);
var text = getSemantic(element).name;
renderLaneLabel(p, text, element);
} else {
// Collapsed pool draw text inline
var text2 = getSemantic(element).name;
renderLabel(p, text2, { box: element, align: 'center-middle' });
}
var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
if (participantMultiplicity) {
renderer('ParticipantMultiplicityMarker')(p, element);
}
return lane;
},
'bpmn:Lane': function(p, element, attrs) {
var rect = drawRect(p, element.width, element.height, 0, attrs || {
fill: 'none'
});
var semantic = getSemantic(element);
if (semantic.$type === 'bpmn:Lane') {
var text = semantic.name;
renderLaneLabel(p, text, element);
}
return rect;
},
'bpmn:InclusiveGateway': function(p, element) {
var diamond = drawDiamond(p, element.width, element.height);
/* circle path */
drawCircle(p, element.width, element.height, element.height * 0.24, {
strokeWidth: 2.5,
fill: 'none'
});
return diamond;
},
'bpmn:ExclusiveGateway': function(p, element) {
var diamond = drawDiamond(p, element.width, element.height);
var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', {
xScaleFactor: 0.4,
yScaleFactor: 0.4,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.32,
my: 0.3
}
});
if (!!(getDi(element).isMarkerVisible)) {
drawPath(p, pathData, {
strokeWidth: 1,
fill: 'black'
});
}
return diamond;
},
'bpmn:ComplexGateway': function(p, element) {
var diamond = drawDiamond(p, element.width, element.height);
var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', {
xScaleFactor: 0.5,
yScaleFactor:0.5,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.46,
my: 0.26
}
});
/* complex path */ drawPath(p, pathData, {
strokeWidth: 1,
fill: 'black'
});
return diamond;
},
'bpmn:ParallelGateway': function(p, element) {
var diamond = drawDiamond(p, element.width, element.height);
var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
xScaleFactor: 0.6,
yScaleFactor:0.6,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.46,
my: 0.2
}
});
/* parallel path */ drawPath(p, pathData, {
strokeWidth: 1,
fill: 'black'
});
return diamond;
},
'bpmn:EventBasedGateway': function(p, element) {
var semantic = getSemantic(element);
var diamond = drawDiamond(p, element.width, element.height);
/* outer circle path */ drawCircle(p, element.width, element.height, element.height * 0.20, {
strokeWidth: 1,
fill: 'none'
});
var type = semantic.eventGatewayType;
var instantiate = !!semantic.instantiate;
function drawEvent() {
var pathData = pathMap.getScaledPath('GATEWAY_EVENT_BASED', {
xScaleFactor: 0.18,
yScaleFactor: 0.18,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.36,
my: 0.44
}
});
/* event path */ drawPath(p, pathData, {
strokeWidth: 2,
fill: 'none'
});
}
if (type === 'Parallel') {
var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
xScaleFactor: 0.4,
yScaleFactor:0.4,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.474,
my: 0.296
}
});
var parallelPath = drawPath(p, pathData);
parallelPath.attr({
strokeWidth: 1,
fill: 'none'
});
} else if (type === 'Exclusive') {
if (!instantiate) {
var innerCircle = drawCircle(p, element.width, element.height, element.height * 0.26);
innerCircle.attr({
strokeWidth: 1,
fill: 'none'
});
}
drawEvent();
}
return diamond;
},
'bpmn:Gateway': function(p, element) {
return drawDiamond(p, element.width, element.height);
},
'bpmn:SequenceFlow': function(p, element) {
var pathData = createPathFromConnection(element);
var path = drawPath(p, pathData, {
strokeLinejoin: 'round',
markerEnd: marker('sequenceflow-end')
});
var sequenceFlow = getSemantic(element);
var source = element.source.businessObject;
// conditional flow marker
if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Activity')) {
path.attr({
markerStart: marker('conditional-flow-marker')
});
}
// default marker
if (source.default && (source.$instanceOf('bpmn:Gateway') || source.$instanceOf('bpmn:Activity')) &&
source.default === sequenceFlow) {
path.attr({
markerStart: marker('conditional-default-flow-marker')
});
}
return path;
},
'bpmn:Association': function(p, element, attrs) {
var semantic = getSemantic(element);
attrs = assign({
strokeDasharray: '0.5, 5',
strokeLinecap: 'round',
strokeLinejoin: 'round'
}, attrs || {});
if (semantic.associationDirection === 'One' ||
semantic.associationDirection === 'Both') {
attrs.markerEnd = marker('association-end');
}
if (semantic.associationDirection === 'Both') {
attrs.markerStart = marker('association-start');
}
return drawLine(p, element.waypoints, attrs);
},
'bpmn:DataInputAssociation': function(p, element) {
return renderer('bpmn:Association')(p, element, {
markerEnd: marker('association-end')
});
},
'bpmn:DataOutputAssociation': function(p, element) {
return renderer('bpmn:Association')(p, element, {
markerEnd: marker('association-end')
});
},
'bpmn:MessageFlow': function(p, element) {
var semantic = getSemantic(element),
di = getDi(element);
var pathData = createPathFromConnection(element);
var path = drawPath(p, pathData, {
markerEnd: marker('messageflow-end'),
markerStart: marker('messageflow-start'),
strokeDasharray: '10, 12',
strokeLinecap: 'round',
strokeLinejoin: 'round',
strokeWidth: '1.5px'
});
if (semantic.messageRef) {
var midPoint = path.getPointAtLength(path.getTotalLength() / 2);
var markerPathData = pathMap.getScaledPath('MESSAGE_FLOW_MARKER', {
abspos: {
x: midPoint.x,
y: midPoint.y
}
});
var messageAttrs = { strokeWidth: 1 };
if (di.messageVisibleKind === 'initiating') {
messageAttrs.fill = 'white';
messageAttrs.stroke = 'black';
} else {
messageAttrs.fill = '#888';
messageAttrs.stroke = 'white';
}
drawPath(p, markerPathData, messageAttrs);
}
return path;
},
'bpmn:DataObject': function(p, element) {
var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.474,
my: 0.296
}
});
var elementObject = drawPath(p, pathData, { fill: 'white' });
var semantic = getSemantic(element);
if (isCollection(semantic)) {
renderDataItemCollection(p, element);
}
return elementObject;
},
'bpmn:DataObjectReference': as('bpmn:DataObject'),
'bpmn:DataInput': function(p, element) {
var arrowPathData = pathMap.getRawPath('DATA_ARROW');
// page
var elementObject = renderer('bpmn:DataObject')(p, element);
/* input arrow path */ drawPath(p, arrowPathData, { strokeWidth: 1 });
return elementObject;
},
'bpmn:DataOutput': function(p, element) {
var arrowPathData = pathMap.getRawPath('DATA_ARROW');
// page
var elementObject = renderer('bpmn:DataObject')(p, element);
/* output arrow path */ drawPath(p, arrowPathData, {
strokeWidth: 1,
fill: 'black'
});
return elementObject;
},
'bpmn:DataStoreReference': function(p, element) {
var DATA_STORE_PATH = pathMap.getScaledPath('DATA_STORE', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0,
my: 0.133
}
});
var elementStore = drawPath(p, DATA_STORE_PATH, {
strokeWidth: 2,
fill: 'white'
});
return elementStore;
},
'bpmn:BoundaryEvent': function(p, element) {
var semantic = getSemantic(element),
cancel = semantic.cancelActivity;
var attrs = {
strokeWidth: 1
};
if (!cancel) {
attrs.strokeDasharray = '6';
attrs.strokeLinecap = 'round';
}
var outer = renderer('bpmn:Event')(p, element, attrs);
/* inner path */ drawCircle(p, element.width, element.height, INNER_OUTER_DIST, assign(attrs, { fill: 'none' }));
renderEventContent(element, p);
return outer;
},
'bpmn:Group': function(p, element) {
return drawRect(p, element.width, element.height, TASK_BORDER_RADIUS, {
strokeWidth: 1,
strokeDasharray: '8,3,1,3',
fill: 'none',
pointerEvents: 'none'
});
},
'label': function(p, element) {
return renderExternalLabel(p, element, '');
},
'bpmn:TextAnnotation': function(p, element) {
var style = {
'fill': 'none',
'stroke': 'none'
};
var textElement = drawRect(p, element.width, element.height, 0, 0, style);
var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.0,
my: 0.0
}
});
drawPath(p, textPathData);
var text = getSemantic(element).text || '';
renderLabel(p, text, { box: element, align: 'left-middle', padding: 5 });
return textElement;
},
'ParticipantMultiplicityMarker': function(p, element) {
var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: ((element.width / 2) / element.width),
my: (element.height - 15) / element.height
}
});
drawMarker('participant-multiplicity', p, markerPath);
},
'SubProcessMarker': function(p, element) {
var markerRect = drawRect(p, 14, 14, 0, {
strokeWidth: 1
});
// Process marker is placed in the middle of the box
// therefore fixed values can be used here
markerRect.transform('translate(' + (element.width / 2 - 7.5) + ',' + (element.height - 20) + ')');
var markerPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', {
xScaleFactor: 1.5,
yScaleFactor: 1.5,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: (element.width / 2 - 7.5) / element.width,
my: (element.height - 20) / element.height
}
});
drawMarker('sub-process', p, markerPath);
},
'ParallelMarker': function(p, element, position) {
var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: ((element.width / 2 + position.parallel) / element.width),
my: (element.height - 20) / element.height
}
});
drawMarker('parallel', p, markerPath);
},
'SequentialMarker': function(p, element, position) {
var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: ((element.width / 2 + position.seq) / element.width),
my: (element.height - 19) / element.height
}
});
drawMarker('sequential', p, markerPath);
},
'CompensationMarker': function(p, element, position) {
var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: ((element.width / 2 + position.compensation) / element.width),
my: (element.height - 13) / element.height
}
});
drawMarker('compensation', p, markerMath, { strokeWidth: 1 });
},
'LoopMarker': function(p, element, position) {
var markerPath = pathMap.getScaledPath('MARKER_LOOP', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: ((element.width / 2 + position.loop) / element.width),
my: (element.height - 7) / element.height
}
});
drawMarker('loop', p, markerPath, {
strokeWidth: 1,
fill: 'none',
strokeLinecap: 'round',
strokeMiterlimit: 0.5
});
},
'AdhocMarker': function(p, element, position) {
var markerPath = pathMap.getScaledPath('MARKER_ADHOC', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: ((element.width / 2 + position.adhoc) / element.width),
my: (element.height - 15) / element.height
}
});
drawMarker('adhoc', p, markerPath, {
strokeWidth: 1,
fill: 'black'
});
}
};
function attachTaskMarkers(p, element, taskMarkers) {
var obj = getSemantic(element);
var subprocess = includes(taskMarkers, 'SubProcessMarker');
var position;
if (subprocess) {
position = {
seq: -21,
parallel: -22,
compensation: -42,
loop: -18,
adhoc: 10
};
} else {
position = {
seq: -3,
parallel: -6,
compensation: -27,
loop: 0,
adhoc: 10
};
}
forEach(taskMarkers, function(marker) {
renderer(marker)(p, element, position);
});
if (obj.isForCompensation) {
renderer('CompensationMarker')(p, element, position);
}
if (obj.$type === 'bpmn:AdHocSubProcess') {
renderer('AdhocMarker')(p, element, position);
}
var loopCharacteristics = obj.loopCharacteristics,
isSequential = loopCharacteristics && loopCharacteristics.isSequential;
if (loopCharacteristics) {
if (isSequential === undefined) {
renderer('LoopMarker')(p, element, position);
}
if (isSequential === false) {
renderer('ParallelMarker')(p, element, position);
}
if (isSequential === true) {
renderer('SequentialMarker')(p, element, position);
}
}
}
function renderDataItemCollection(p, element) {
var yPosition = (element.height - 16) / element.height;
var pathData = pathMap.getScaledPath('DATA_OBJECT_COLLECTION_PATH', {
xScaleFactor: 1,
yScaleFactor: 1,
containerWidth: element.width,
containerHeight: element.height,
position: {
mx: 0.451,
my: yPosition
}
});
/* collection path */ drawPath(p, pathData, {
strokeWidth: 2
});
}
// hook onto canvas init event to initialize
// connection start/end markers on svg
eventBus.on('canvas.init', function(event) {
initMarkers(event.svg);
});
}
inherits(BpmnRenderer, BaseRenderer);
BpmnRenderer.$inject = [ 'eventBus', 'styles', 'pathMap' ];
module.exports = BpmnRenderer;
BpmnRenderer.prototype.canRender = function(element) {
return is(element, 'bpmn:BaseElement');
};
BpmnRenderer.prototype.drawShape = function(visuals, element) {
var type = element.type;
var h = this.handlers[type];
/* jshint -W040 */
return h(visuals, element);
};
BpmnRenderer.prototype.drawConnection = function(visuals, element) {
var type = element.type;
var h = this.handlers[type];
/* jshint -W040 */
return h(visuals, element);
};
BpmnRenderer.prototype.getShapePath = function(element) {
if (is(element, 'bpmn:Event')) {
return getCirclePath(element);
}
if (is(element, 'bpmn:Activity')) {
return getRoundRectPath(element, TASK_BORDER_RADIUS);
}
if (is(element, 'bpmn:Gateway')) {
return getDiamondPath(element);
}
return getRectPath(element);
};
///////// helper functions /////////////////////////////
/**
* Checks if eventDefinition of the given element matches with semantic type.
*
* @return {boolean} true if element is of the given semantic type
*/
function isTypedEvent(event, eventDefinitionType, filter) {
function matches(definition, filter) {
return every(filter, function(val, key) {
// we want a == conversion here, to be able to catch
// undefined == false and friends
/* jshint -W116 */
return definition[key] == val;
});
}
return some(event.eventDefinitions, function(definition) {
return definition.$type === eventDefinitionType && matches(event, filter);
});
}
function isThrowEvent(event) {
return (event.$type === 'bpmn:IntermediateThrowEvent') || (event.$type === 'bpmn:EndEvent');
}
function isCollection(element) {
return element.isCollection ||
(element.elementObjectRef && element.elementObjectRef.isCollection);
}
function getDi(element) {
return element.businessObject.di;
}
function getSemantic(element) {
return element.businessObject;
}
/////// cropping path customizations /////////////////////////
function getCirclePath(shape) {
var cx = shape.x + shape.width / 2,
cy = shape.y + shape.height / 2,
radius = shape.width / 2;
var circlePath = [
['M', cx, cy],
['m', 0, -radius],
['a', radius, radius, 0, 1, 1, 0, 2 * radius],
['a', radius, radius, 0, 1, 1, 0, -2 * radius],
['z']
];
return componentsToPath(circlePath);
}
function getRoundRectPath(shape, borderRadius) {
var x = shape.x,
y = shape.y,
width = shape.width,
height = shape.height;
var roundRectPath = [
['M', x + borderRadius, y],
['l', width - borderRadius * 2, 0],
['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, borderRadius],
['l', 0, height - borderRadius * 2],
['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, borderRadius],
['l', borderRadius * 2 - width, 0],
['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, -borderRadius],
['l', 0, borderRadius * 2 - height],
['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, -borderRadius],
['z']
];
return componentsToPath(roundRectPath);
}
function getDiamondPath(shape) {
var width = shape.width,
height = shape.height,
x = shape.x,
y = shape.y,
halfWidth = width / 2,
halfHeight = height / 2;
var diamondPath = [
['M', x + halfWidth, y],
['l', halfWidth, halfHeight],
['l', -halfWidth, halfHeight],
['l', -halfWidth, -halfHeight],
['z']
];
return componentsToPath(diamondPath);
}
function getRectPath(shape) {
var x = shape.x,
y = shape.y,
width = shape.width,
height = shape.height;
var rectPath = [
['M', x, y],
['l', width, 0],
['l', 0, height],
['l', -width, 0],
['z']
];
return componentsToPath(rectPath);
}
},{"107":107,"231":231,"232":232,"243":243,"252":252,"255":255,"257":257,"261":261,"372":372,"377":377,"68":68,"70":70}],5:[function(_dereq_,module,exports){
'use strict';
var Snap = _dereq_(240);
/**
* Map containing SVG paths needed by BpmnRenderer.
*/
function PathMap() {
/**
* Contains a map of path elements
*
* Path definition
* A parameterized path is defined like this:
*
* 'GATEWAY_PARALLEL': {
* d: 'm {mx},{my} {e.x0},0 0,{e.x1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
'-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
* height: 17.5,
* width: 17.5,
* heightElements: [2.5, 7.5],
* widthElements: [2.5, 7.5]
* }
*
* It's important to specify a correct height and width for the path as the scaling
* is based on the ratio between the specified height and width in this object and the
* height and width that is set as scale target (Note x,y coordinates will be scaled with
* individual ratios).
* The 'heightElements' and 'widthElements' array must contain the values that will be scaled.
* The scaling is based on the computed ratios.
* Coordinates on the y axis should be in the heightElement's array, they will be scaled using
* the computed ratio coefficient.
* In the parameterized path the scaled values can be accessed through the 'e' object in {} brackets.
*
* - The values for the y axis can be accessed in the path string using {e.y0}, {e.y1}, ....
* - The values for the x axis can be accessed in the path string using {e.x0}, {e.x1}, ....
*
* The numbers x0, x1 respectively y0, y1, ... map to the corresponding array index.
*
*/
this.pathMap = {
'EVENT_MESSAGE': {
d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
height: 36,
width: 36,
heightElements: [6, 14],
widthElements: [10.5, 21]
},
'EVENT_SIGNAL': {
d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x1},0 Z',
height: 36,
width: 36,
heightElements: [18],
widthElements: [10, 20]
},
'EVENT_ESCALATION': {
d: 'm {mx},{my} c -{e.x1},{e.y0} -{e.x3},{e.y1} -{e.x5},{e.y4} {e.x1},-{e.y3} {e.x3},-{e.y5} {e.x5},-{e.y6} ' +
'{e.x0},{e.y3} {e.x2},{e.y5} {e.x4},{e.y6} -{e.x0},-{e.y0} -{e.x2},-{e.y1} -{e.x4},-{e.y4} z',
height: 36,
width: 36,
heightElements: [2.382, 4.764, 4.926, 6.589333, 7.146, 13.178667, 19.768],
widthElements: [2.463, 2.808, 4.926, 5.616, 7.389, 8.424]
},
'EVENT_CONDITIONAL': {
d: 'M {e.x0},{e.y0} l {e.x1},0 l 0,{e.y2} l -{e.x1},0 Z ' +
'M {e.x2},{e.y3} l {e.x0},0 ' +
'M {e.x2},{e.y4} l {e.x0},0 ' +
'M {e.x2},{e.y5} l {e.x0},0 ' +
'M {e.x2},{e.y6} l {e.x0},0 ' +
'M {e.x2},{e.y7} l {e.x0},0 ' +
'M {e.x2},{e.y8} l {e.x0},0 ',
height: 36,
width: 36,
heightElements: [8.5, 14.5, 18, 11.5, 14.5, 17.5, 20.5, 23.5, 26.5],
widthElements: [10.5, 14.5, 12.5]
},
'EVENT_LINK': {
d: 'm {mx},{my} 0,{e.y0} -{e.x1},0 0,{e.y1} {e.x1},0 0,{e.y0} {e.x0},-{e.y2} -{e.x0},-{e.y2} z',
height: 36,
width: 36,
heightElements: [4.4375, 6.75, 7.8125],
widthElements: [9.84375, 13.5]
},
'EVENT_ERROR': {
d: 'm {mx},{my} {e.x0},-{e.y0} {e.x1},-{e.y1} {e.x2},{e.y2} {e.x3},-{e.y3} -{e.x4},{e.y4} -{e.x5},-{e.y5} z',
height: 36,
width: 36,
heightElements: [0.023, 8.737, 8.151, 16.564, 10.591, 8.714],
widthElements: [0.085, 6.672, 6.97, 4.273, 5.337, 6.636]
},
'EVENT_CANCEL_45': {
d: 'm {mx},{my} -{e.x1},0 0,{e.x0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
'0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
height: 36,
width: 36,
heightElements: [4.75, 8.5],
widthElements: [4.75, 8.5]
},
'EVENT_COMPENSATION': {
d: 'm {mx},{my} {e.x0},-{e.y0} 0,{e.y1} z m {e.x1},-{e.y2} {e.x2},-{e.y3} 0,{e.y1} -{e.x2},-{e.y3} z',
height: 36,
width: 36,
heightElements: [6.5, 13, 0.4, 6.1],
widthElements: [9, 9.3, 8.7]
},
'EVENT_TIMER_WH': {
d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ',
height: 36,
width: 36,
heightElements: [10, 2],
widthElements: [3, 7]
},
'EVENT_TIMER_LINE': {
d: 'M {mx},{my} ' +
'm {e.x0},{e.y0} l -{e.x1},{e.y1} ',
height: 36,
width: 36,
heightElements: [10, 3],
widthElements: [0, 0]
},
'EVENT_MULTIPLE': {
d:'m {mx},{my} {e.x1},-{e.y0} {e.x1},{e.y0} -{e.x0},{e.y1} -{e.x2},0 z',
height: 36,
width: 36,
heightElements: [6.28099, 12.56199],
widthElements: [3.1405, 9.42149, 12.56198]
},
'EVENT_PARALLEL_MULTIPLE': {
d:'m {mx},{my} {e.x0},0 0,{e.y1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
'-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
height: 36,
width: 36,
heightElements: [2.56228, 7.68683],
widthElements: [2.56228, 7.68683]
},
'GATEWAY_EXCLUSIVE': {
d:'m {mx},{my} {e.x0},{e.y0} {e.x1},{e.y0} {e.x2},0 {e.x4},{e.y2} ' +
'{e.x4},{e.y1} {e.x2},0 {e.x1},{e.y3} {e.x0},{e.y3} ' +
'{e.x3},0 {e.x5},{e.y1} {e.x5},{e.y2} {e.x3},0 z',
height: 17.5,
width: 17.5,
heightElements: [8.5, 6.5312, -6.5312, -8.5],
widthElements: [6.5, -6.5, 3, -3, 5, -5]
},
'GATEWAY_PARALLEL': {
d:'m {mx},{my} 0,{e.y1} -{e.x1},0 0,{e.y0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
'0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
height: 30,
width: 30,
heightElements: [5, 12.5],
widthElements: [5, 12.5]
},
'GATEWAY_EVENT_BASED': {
d:'m {mx},{my} {e.x0},{e.y0} {e.x0},{e.y1} {e.x1},{e.y2} {e.x2},0 z',
height: 11,
width: 11,
heightElements: [-6, 6, 12, -12],
widthElements: [9, -3, -12]
},
'GATEWAY_COMPLEX': {
d:'m {mx},{my} 0,{e.y0} -{e.x0},-{e.y1} -{e.x1},{e.y2} {e.x0},{e.y1} -{e.x2},0 0,{e.y3} ' +
'{e.x2},0 -{e.x0},{e.y1} l {e.x1},{e.y2} {e.x0},-{e.y1} 0,{e.y0} {e.x3},0 0,-{e.y0} {e.x0},{e.y1} ' +
'{e.x1},-{e.y2} -{e.x0},-{e.y1} {e.x2},0 0,-{e.y3} -{e.x2},0 {e.x0},-{e.y1} -{e.x1},-{e.y2} ' +
'-{e.x0},{e.y1} 0,-{e.y0} -{e.x3},0 z',
height: 17.125,
width: 17.125,
heightElements: [4.875, 3.4375, 2.125, 3],
widthElements: [3.4375, 2.125, 4.875, 3]
},
'DATA_OBJECT_PATH': {
d:'m 0,0 {e.x1},0 {e.x0},{e.y0} 0,{e.y1} -{e.x2},0 0,-{e.y2} {e.x1},0 0,{e.y0} {e.x0},0',
height: 61,
width: 51,
heightElements: [10, 50, 60],
widthElements: [10, 40, 50, 60]
},
'DATA_OBJECT_COLLECTION_PATH': {
d:'m {mx}, {my} ' +
'm 0 15 l 0 -15 ' +
'm 4 15 l 0 -15 ' +
'm 4 15 l 0 -15 ',
height: 61,
width: 51,
heightElements: [12],
widthElements: [1, 6, 12, 15]
},
'DATA_ARROW': {
d:'m 5,9 9,0 0,-3 5,5 -5,5 0,-3 -9,0 z',
height: 61,
width: 51,
heightElements: [],
widthElements: []
},
'DATA_STORE': {
d:'m {mx},{my} ' +
'l 0,{e.y2} ' +
'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' +
'l 0,-{e.y2} ' +
'c -{e.x0},-{e.y1} -{e.x1},-{e.y1} -{e.x2},0' +
'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' +
'm -{e.x2},{e.y0}' +
'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0' +
'm -{e.x2},{e.y0}' +
'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0',
height: 61,
width: 61,
heightElements: [7, 10, 45],
widthElements: [2, 58, 60]
},
'TEXT_ANNOTATION': {
d: 'm {mx}, {my} m 10,0 l -10,0 l 0,{e.y0} l 10,0',
height: 30,
width: 10,
heightElements: [30],
widthElements: [10]
},
'MARKER_SUB_PROCESS': {
d: 'm{mx},{my} m 7,2 l 0,10 m -5,-5 l 10,0',
height: 10,
width: 10,
heightElements: [],
widthElements: []
},
'MARKER_PARALLEL': {
d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10',
height: 10,
width: 10,
heightElements: [],
widthElements: []
},
'MARKER_SEQUENTIAL': {
d: 'm{mx},{my} m 0,3 l 10,0 m -10,3 l 10,0 m -10,3 l 10,0',
height: 10,
width: 10,
heightElements: [],
widthElements: []
},
'MARKER_COMPENSATION': {
d: 'm {mx},{my} 7,-5 0,10 z m 7.1,-0.3 6.9,-4.7 0,10 -6.9,-4.7 z',
height: 10,
width: 21,
heightElements: [],
widthElements: []
},
'MARKER_LOOP': {
d: 'm {mx},{my} c 3.526979,0 6.386161,-2.829858 6.386161,-6.320661 0,-3.490806 -2.859182,-6.320661 ' +
'-6.386161,-6.320661 -3.526978,0 -6.38616,2.829855 -6.38616,6.320661 0,1.745402 ' +
'0.714797,3.325567 1.870463,4.469381 0.577834,0.571908 1.265885,1.034728 2.029916,1.35457 ' +
'l -0.718163,-3.909793 m 0.718163,3.909793 -3.885211,0.802902',
height: 13.9,
width: 13.7,
heightElements: [],
widthElements: []
},
'MARKER_ADHOC': {
d: 'm {mx},{my} m 0.84461,2.64411 c 1.05533,-1.23780996 2.64337,-2.07882 4.29653,-1.97997996 2.05163,0.0805 ' +
'3.85579,1.15803 5.76082,1.79107 1.06385,0.34139996 2.24454,0.1438 3.18759,-0.43767 0.61743,-0.33642 ' +
'1.2775,-0.64078 1.7542,-1.17511 0,0.56023 0,1.12046 0,1.6807 -0.98706,0.96237996 -2.29792,1.62393996 ' +
'-3.6918,1.66181996 -1.24459,0.0927 -2.46671,-0.2491 -3.59505,-0.74812 -1.35789,-0.55965 ' +
'-2.75133,-1.33436996 -4.27027,-1.18121996 -1.37741,0.14601 -2.41842,1.13685996 -3.44288,1.96782996 z',
height: 4,
width: 15,
heightElements: [],
widthElements: []
},
'TASK_TYPE_SEND': {
d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
height: 14,
width: 21,
heightElements: [6, 14],
widthElements: [10.5, 21]
},
'TASK_TYPE_SCRIPT': {
d: 'm {mx},{my} c 9.966553,-6.27276 -8.000926,-7.91932 2.968968,-14.938 l -8.802728,0 ' +
'c -10.969894,7.01868 6.997585,8.66524 -2.968967,14.938 z ' +
'm -7,-12 l 5,0 ' +
'm -4.5,3 l 4.5,0 ' +
'm -3,3 l 5,0' +
'm -4,3 l 5,0',
height: 15,
width: 12.6,
heightElements: [6, 14],
widthElements: [10.5, 21]
},
'TASK_TYPE_USER_1': {
d: 'm {mx},{my} c 0.909,-0.845 1.594,-2.049 1.594,-3.385 0,-2.554 -1.805,-4.62199999 ' +
'-4.357,-4.62199999 -2.55199998,0 -4.28799998,2.06799999 -4.28799998,4.62199999 0,1.348 ' +
'0.974,2.562 1.89599998,3.405 -0.52899998,0.187 -5.669,2.097 -5.794,4.7560005 v 6.718 ' +
'h 17 v -6.718 c 0,-2.2980005 -5.5279996,-4.5950005 -6.0509996,-4.7760005 z' +
'm -8,6 l 0,5.5 m 11,0 l 0,-5'
},
'TASK_TYPE_USER_2': {
d: 'm {mx},{my} m 2.162,1.009 c 0,2.4470005 -2.158,4.4310005 -4.821,4.4310005 ' +
'-2.66499998,0 -4.822,-1.981 -4.822,-4.4310005 '
},
'TASK_TYPE_USER_3': {
d: 'm {mx},{my} m -6.9,-3.80 c 0,0 2.25099998,-2.358 4.27399998,-1.177 2.024,1.181 4.221,1.537 ' +
'4.124,0.965 -0.098,-0.57 -0.117,-3.79099999 -4.191,-4.13599999 -3.57499998,0.001 ' +
'-4.20799998,3.36699999 -4.20699998,4.34799999 z'
},
'TASK_TYPE_MANUAL': {
d: 'm {mx},{my} c 0.234,-0.01 5.604,0.008 8.029,0.004 0.808,0 1.271,-0.172 1.417,-0.752 0.227,-0.898 ' +
'-0.334,-1.314 -1.338,-1.316 -2.467,-0.01 -7.886,-0.004 -8.108,-0.004 -0.014,-0.079 0.016,-0.533 0,-0.61 ' +
'0.195,-0.042 8.507,0.006 9.616,0.002 0.877,-0.007 1.35,-0.438 1.353,-1.208 0.003,-0.768 -0.479,-1.09 ' +
'-1.35,-1.091 -2.968,-0.002 -9.619,-0.013 -9.619,-0.013 v -0.591 c 0,0 5.052,-0.016 7.225,-0.016 ' +
'0.888,-0.002 1.354,-0.416 1.351,-1.193 -0.006,-0.761 -0.492,-1.196 -1.361,-1.196 -3.473,-0.005 ' +
'-10.86,-0.003 -11.0829995,-0.003 -0.022,-0.047 -0.045,-0.094 -0.069,-0.139 0.3939995,-0.319 ' +
'2.0409995,-1.626 2.4149995,-2.017 0.469,-0.4870005 0.519,-1.1650005 0.162,-1.6040005 -0.414,-0.511 ' +
'-0.973,-0.5 -1.48,-0.236 -1.4609995,0.764 -6.5999995,3.6430005 -7.7329995,4.2710005 -0.9,0.499 ' +
'-1.516,1.253 -1.882,2.19 -0.37000002,0.95 -0.17,2.01 -0.166,2.979 0.004,0.718 -0.27300002,1.345 ' +
'-0.055,2.063 0.629,2.087 2.425,3.312 4.859,3.318 4.6179995,0.014 9.2379995,-0.139 13.8569995,-0.158 ' +
'0.755,-0.004 1.171,-0.301 1.182,-1.033 0.012,-0.754 -0.423,-0.969 -1.183,-0.973 -1.778,-0.01 ' +
'-5.824,-0.004 -6.04,-0.004 10e-4,-0.084 0.003,-0.586 10e-4,-0.67 z'
},
'TASK_TYPE_INSTANTIATING_SEND': {
d: 'm {mx},{my} l 0,8.4 l 12.6,0 l 0,-8.4 z l 6.3,3.6 l 6.3,-3.6'
},
'TASK_TYPE_SERVICE': {
d: 'm {mx},{my} v -1.71335 c 0.352326,-0.0705 0.703932,-0.17838 1.047628,-0.32133 ' +
'0.344416,-0.14465 0.665822,-0.32133 0.966377,-0.52145 l 1.19431,1.18005 1.567487,-1.57688 ' +
'-1.195028,-1.18014 c 0.403376,-0.61394 0.683079,-1.29908 0.825447,-2.01824 l 1.622133,-0.01 ' +
'v -2.2196 l -1.636514,0.01 c -0.07333,-0.35153 -0.178319,-0.70024 -0.323564,-1.04372 ' +
'-0.145244,-0.34406 -0.321407,-0.6644 -0.522735,-0.96217 l 1.131035,-1.13631 -1.583305,-1.56293 ' +
'-1.129598,1.13589 c -0.614052,-0.40108 -1.302883,-0.68093 -2.022633,-0.82247 l 0.0093,-1.61852 ' +
'h -2.241173 l 0.0042,1.63124 c -0.353763,0.0736 -0.705369,0.17977 -1.049785,0.32371 -0.344415,0.14437 ' +
'-0.665102,0.32092 -0.9635006,0.52046 l -1.1698628,-1.15823 -1.5667691,1.5792 1.1684265,1.15669 ' +
'c -0.4026573,0.61283 -0.68308,1.29797 -0.8247287,2.01713 l -1.6588041,0.003 v 2.22174 ' +
'l 1.6724648,-0.006 c 0.073327,0.35077 0.1797598,0.70243 0.3242851,1.04472 0.1452428,0.34448 ' +
'0.3214064,0.6644 0.5227339,0.96066 l -1.1993431,1.19723 1.5840256,1.56011 1.1964668,-1.19348 ' +
'c 0.6140517,0.40346 1.3028827,0.68232 2.0233517,0.82331 l 7.19e-4,1.69892 h 2.226848 z ' +
'm 0.221462,-3.9957 c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
'0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
'0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
},
'TASK_TYPE_SERVICE_FILL': {
d: 'm {mx},{my} c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
'0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
'0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
},
'TASK_TYPE_BUSINESS_RULE_HEADER': {
d: 'm {mx},{my} 0,4 20,0 0,-4 z'
},
'TASK_TYPE_BUSINESS_RULE_MAIN': {
d: 'm {mx},{my} 0,12 20,0 0,-12 z' +
'm 0,8 l 20,0 ' +
'm -13,-4 l 0,8'
},
'MESSAGE_FLOW_MARKER': {
d: 'm {mx},{my} m -10.5 ,-7 l 0,14 l 21,0 l 0,-14 z l 10.5,6 l 10.5,-6'
}
};
this.getRawPath = function getRawPath(pathId) {
return this.pathMap[pathId].d;
};
/**
* Scales the path to the given height and width.
* Use case
* Use case is to scale the content of elements (event, gateways) based
* on the element bounding box's size.
*
* Why not transform
* Scaling a path with transform() will also scale the stroke and IE does not support
* the option 'non-scaling-stroke' to prevent this.
* Also there are use cases where only some parts of a path should be
* scaled.
*
* @param {String} pathId The ID of the path.
* @param {Object} param
* Example param object scales the path to 60% size of the container (data.width, data.height).
*
* {
* xScaleFactor: 0.6,
* yScaleFactor:0.6,
* containerWidth: data.width,
* containerHeight: data.height,
* position: {
* mx: 0.46,
* my: 0.2,
* }
* }
*
*
* - targetpathwidth = xScaleFactor * containerWidth
* - targetpathheight = yScaleFactor * containerHeight
* - Position is used to set the starting coordinate of the path. M is computed:
*
* - position.x * containerWidth
* - position.y * containerHeight
*
* Center of the container position: {
* mx: 0.5,
* my: 0.5,
* }
* Upper left corner of the container
* position: {
* mx: 0.0,
* my: 0.0,
* }
*
*
*
*
*/
this.getScaledPath = function getScaledPath(pathId, param) {
var rawPath = this.pathMap[pathId];
// positioning
// compute the start point of the path
var mx, my;
if(!!param.abspos) {
mx = param.abspos.x;
my = param.abspos.y;
} else {
mx = param.containerWidth * param.position.mx;
my = param.containerHeight * param.position.my;
}
var coordinates = {}; //map for the scaled coordinates
if(param.position) {
// path
var heightRatio = (param.containerHeight / rawPath.height) * param.yScaleFactor;
var widthRatio = (param.containerWidth / rawPath.width) * param.xScaleFactor;
//Apply height ratio
for (var heightIndex = 0; heightIndex < rawPath.heightElements.length; heightIndex++) {
coordinates['y' + heightIndex] = rawPath.heightElements[heightIndex] * heightRatio;
}
//Apply width ratio
for (var widthIndex = 0; widthIndex < rawPath.widthElements.length; widthIndex++) {
coordinates['x' + widthIndex] = rawPath.widthElements[widthIndex] * widthRatio;
}
}
//Apply value to raw path
var path = Snap.format(
rawPath.d, {
mx: mx,
my: my,
e: coordinates
}
);
return path;
};
}
module.exports = PathMap;
},{"240":240}],6:[function(_dereq_,module,exports){
module.exports = {
__init__: [ 'bpmnRenderer' ],
bpmnRenderer: [ 'type', _dereq_(4) ],
pathMap: [ 'type', _dereq_(5) ]
};
},{"4":4,"5":5}],7:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var is = _dereq_(70).is,
getBoundingBox = _dereq_(221).getBBox;
var pick = _dereq_(383),
assign = _dereq_(377),
forEach = _dereq_(255),
values = _dereq_(385),
flatten = _dereq_(245),
groupBy = _dereq_(256);
var CommandInterceptor = _dereq_(98);
var OFFSET = { top: 60, bottom: 60, left: 100, right: 100 };
var PADDING = { top: 2, bottom: 2, left: 15, right: 15 };
/**
* An auto resize component that takes care of expanding parent participants
* and lanes if elements are modeled close to an edge of the parent element.
*/
function AutoResize(eventBus, canvas, modeling, elementRegistry){
CommandInterceptor.call(this, eventBus);
this.postExecuted([ 'shape.create' ], function(event) {
var context = event.context,
shape = context.shape,
parent = context.parent || context.newParent;
expand([ shape ], parent);
});
this.postExecuted([ 'elements.move' ], function(event) {
var context = event.context,
elements = flatten(values(context.closure.topLevel));
var expandings = groupBy(elements, function(element){
return element.parent.id;
});
forEach(expandings, function(elements, parentId) {
expand(elements, parentId);
});
});
/**
* Returns an object which indicates near which bounding edge(s)
* of a target a bounding box is located.
*
* @param {Object} bbox bounding box object with x, y, width and height properties
* @param {Shape} target
* @param {Number} padding
*
* @return {Object} {top, bottom, left, right}
*
* @example
*
* // If the bounding box is near the bottom left corner of a target the return object is:
* { top: false, bottom: true, left: true, right: false }
*
*/
function isInbounds(bbox, target, padding) {
return {
top: bbox.y < target.y + padding.top,
bottom: bbox.y + bbox.height > target.y + target.height - padding.bottom,
left: bbox.x < target.x + padding.left,
right: bbox.x + bbox.width > target.x + target.width - padding.right,
};
}
/**
* Expand the target shape if the bounding box of the moved elements is near or on an edge,
* considering the position of the bounding box in relation to the parent's edge plus padding.
* The amount to expand can be defined for each edge in the OFFSET object.
*
* @param {Array} elements
* @param {Shape|String} target|targetId
*/
function expand(elements, target) {
if (typeof target === 'string') {
target = elementRegistry.get(target);
}
var bbox = getBoundingBox(elements),
canExpand = true;
if (!is(target, 'bpmn:Participant') && !is(target, 'bpmn:Lane') && !(is(target, 'bpmn:SubProcess'))) {
return;
}
forEach(elements, function(element) {
if (is(element, 'bpmn:Lane') || element.labelTarget) {
canExpand = false;
return;
}
});
if (!canExpand) {
return;
}
var inbounds = isInbounds(bbox, target, PADDING);
var newBounds = pick(target, [ 'x', 'y', 'width', 'height' ]);
if (inbounds.top) {
var topPosition = bbox.y - OFFSET.top;
assign(newBounds, { y: topPosition, height: newBounds.height + newBounds.y - topPosition });
}
if (inbounds.bottom) {
assign(newBounds, { height: bbox.y + bbox.height + OFFSET.bottom - newBounds.y });
}
if (inbounds.left) {
var leftPosition = bbox.x - OFFSET.left;
assign(newBounds, { x: leftPosition, width: newBounds.width + newBounds.x - leftPosition });
}
if (inbounds.right) {
assign(newBounds, { width: bbox.x + bbox.width + OFFSET.right - newBounds.x });
}
if (is(target, 'bpmn:Participant')) {
modeling.resizeLane(target, newBounds);
} else {
modeling.resizeShape(target, newBounds);
}
var parent = target.parent;
// recursively expand parent elements
if (parent) {
expand([ target ], parent);
}
}
}
AutoResize.$inject = [ 'eventBus', 'canvas', 'modeling', 'elementRegistry' ];
inherits(AutoResize, CommandInterceptor);
module.exports = AutoResize;
},{"221":221,"243":243,"245":245,"255":255,"256":256,"377":377,"383":383,"385":385,"70":70,"98":98}],8:[function(_dereq_,module,exports){
module.exports = {
__init__: [ 'autoResize' ],
autoResize: [ 'type', _dereq_(7) ]
};
},{"7":7}],9:[function(_dereq_,module,exports){
'use strict';
var assign = _dereq_(377),
forEach = _dereq_(255),
isArray = _dereq_(368),
is = _dereq_(70).is,
isExpanded = _dereq_(68).isExpanded,
isAny = _dereq_(45).isAny,
getChildLanes = _dereq_(44).getChildLanes,
isEventSubProcess = _dereq_(68).isEventSubProcess;
/**
* A provider for BPMN 2.0 elements context pad
*/
function ContextPadProvider(contextPad, modeling, elementFactory,
connect, create, popupMenu,
canvas, rules, translate) {
contextPad.registerProvider(this);
this._contextPad = contextPad;
this._modeling = modeling;
this._elementFactory = elementFactory;
this._connect = connect;
this._create = create;
this._popupMenu = popupMenu;
this._canvas = canvas;
this._rules = rules;
this._translate = translate;
}
ContextPadProvider.$inject = [
'contextPad',
'modeling',
'elementFactory',
'connect',
'create',
'popupMenu',
'canvas',
'rules',
'translate'
];
module.exports = ContextPadProvider;
ContextPadProvider.prototype.getContextPadEntries = function(element) {
var contextPad = this._contextPad,
modeling = this._modeling,
elementFactory = this._elementFactory,
connect = this._connect,
create = this._create,
popupMenu = this._popupMenu,
canvas = this._canvas,
rules = this._rules,
translate = this._translate;
var actions = {};
if (element.type === 'label') {
return actions;
}
var businessObject = element.businessObject;
function startConnect(event, element, autoActivate) {
connect.start(event, element, autoActivate);
}
function removeElement(e) {
modeling.removeElements([ element ]);
}
function getReplaceMenuPosition(element) {
var Y_OFFSET = 5;
var diagramContainer = canvas.getContainer(),
pad = contextPad.getPad(element).html;
var diagramRect = diagramContainer.getBoundingClientRect(),
padRect = pad.getBoundingClientRect();
var top = padRect.top - diagramRect.top;
var left = padRect.left - diagramRect.left;
var pos = {
x: left,
y: top + padRect.height + Y_OFFSET
};
return pos;
}
/**
* Create an append action
*
* @param {String} type
* @param {String} className
* @param {String} [title]
* @param {Object} [options]
*
* @return {Object} descriptor
*/
function appendAction(type, className, title, options) {
if (typeof title !== 'string') {
options = title;
title = translate('Append {type}', { type: type.replace(/^bpmn\:/, '') });
}
function appendListener(event, element) {
var shape = elementFactory.createShape(assign({ type: type }, options));
create.start(event, shape, element);
}
return {
group: 'model',
className: className,
title: title,
action: {
dragstart: appendListener,
click: appendListener
}
};
}
function splitLaneHandler(count) {
return function(event, element) {
// actual split
modeling.splitLane(element, count);
// refresh context pad after split to
// get rid of split icons
contextPad.open(element, true);
};
}
if (isAny(businessObject, [ 'bpmn:Lane', 'bpmn:Participant' ]) && isExpanded(businessObject)) {
var childLanes = getChildLanes(element);
assign(actions, {
'lane-insert-above': {
group: 'lane-insert-above',
className: 'bpmn-icon-lane-insert-above',
title: translate('Add Lane above'),
action: {
click: function(event, element) {
modeling.addLane(element, 'top');
}
}
}
});
if (childLanes.length < 2) {
if (element.height >= 120) {
assign(actions, {
'lane-divide-two': {
group: 'lane-divide',
className: 'bpmn-icon-lane-divide-two',
title: translate('Divide into two Lanes'),
action: {
click: splitLaneHandler(2)
}
}
});
}
if (element.height >= 180) {
assign(actions, {
'lane-divide-three': {
group: 'lane-divide',
className: 'bpmn-icon-lane-divide-three',
title: translate('Divide into three Lanes'),
action: {
click: splitLaneHandler(3)
}
}
});
}
}
assign(actions, {
'lane-insert-below': {
group: 'lane-insert-below',
className: 'bpmn-icon-lane-insert-below',
title: translate('Add Lane below'),
action: {
click: function(event, element) {
modeling.addLane(element, 'bottom');
}
}
}
});
}
if (is(businessObject, 'bpmn:FlowNode')) {
if (is(businessObject, 'bpmn:EventBasedGateway')) {
assign(actions, {
'append.receive-task': appendAction('bpmn:ReceiveTask', 'bpmn-icon-receive-task'),
'append.message-intermediate-event': appendAction('bpmn:IntermediateCatchEvent',
'bpmn-icon-intermediate-event-catch-message',
{ eventDefinitionType: 'bpmn:MessageEventDefinition'}),
'append.timer-intermediate-event': appendAction('bpmn:IntermediateCatchEvent',
'bpmn-icon-intermediate-event-catch-timer',
{ eventDefinitionType: 'bpmn:TimerEventDefinition'}),
'append.condtion-intermediate-event': appendAction('bpmn:IntermediateCatchEvent',
'bpmn-icon-intermediate-event-catch-condition',
{ eventDefinitionType: 'bpmn:ConditionalEventDefinition'}),
'append.signal-intermediate-event': appendAction('bpmn:IntermediateCatchEvent',
'bpmn-icon-intermediate-event-catch-signal',
{ eventDefinitionType: 'bpmn:SignalEventDefinition'})
});
} else
if (isEventType(businessObject, 'bpmn:BoundaryEvent', 'bpmn:CompensateEventDefinition')) {
assign(actions, {
'append.compensation-activity':
appendAction('bpmn:Task', 'bpmn-icon-task', translate('Append compensation activity'), {
isForCompensation: true
})
});
} else
if (!is(businessObject, 'bpmn:EndEvent') &&
!businessObject.isForCompensation &&
!isEventType(businessObject, 'bpmn:IntermediateThrowEvent', 'bpmn:LinkEventDefinition') &&
!isEventSubProcess(businessObject)) {
assign(actions, {
'append.end-event': appendAction('bpmn:EndEvent', 'bpmn-icon-end-event-none'),
'append.gateway': appendAction('bpmn:ExclusiveGateway', 'bpmn-icon-gateway-xor'),
'append.append-task': appendAction('bpmn:Task', 'bpmn-icon-task'),
'append.intermediate-event': appendAction('bpmn:IntermediateThrowEvent',
'bpmn-icon-intermediate-event-none')
});
}
}
var replaceMenu;
if (popupMenu._providers['bpmn-replace']) {
replaceMenu = popupMenu.create('bpmn-replace', element);
}
if (replaceMenu && !replaceMenu.isEmpty()) {
// Replace menu entry
assign(actions, {
'replace': {
group: 'edit',
className: 'bpmn-icon-screw-wrench',
title: translate('Change type'),
action: {
click: function(event, element) {
replaceMenu.open(assign(getReplaceMenuPosition(element), {
cursor: { x: event.x, y: event.y }
}), element);
}
}
}
});
}
if (isAny(businessObject, [ 'bpmn:FlowNode', 'bpmn:InteractionNode' ]) ) {
assign(actions, {
'append.text-annotation': appendAction('bpmn:TextAnnotation', 'bpmn-icon-text-annotation'),
'connect': {
group: 'connect',
className: 'bpmn-icon-connection-multi',
title: translate('Connect using ' +
(businessObject.isForCompensation ? '' : 'Sequence/MessageFlow or ') +
'Association'),
action: {
click: startConnect,
dragstart: startConnect
}
}
});
}
if (isAny(businessObject, [ 'bpmn:DataObjectReference', 'bpmn:DataStoreReference' ])) {
assign(actions, {
'connect': {
group: 'connect',
className: 'bpmn-icon-connection-multi',
title: translate('Connect using DataInputAssociation'),
action: {
click: startConnect,
dragstart: startConnect
}
}
});
}
// delete element entry, only show if allowed by rules
var deleteAllowed = rules.allowed('elements.delete', { elements: [ element ]});
if (isArray(deleteAllowed)) {
// was the element returned as a deletion candidate?
deleteAllowed = deleteAllowed[0] === element;
}
if (deleteAllowed) {
assign(actions, {
'delete': {
group: 'edit',
className: 'bpmn-icon-trash',
title: translate('Remove'),
action: {
click: removeElement,
dragstart: removeElement
}
}
});
}
return actions;
};
function isEventType(eventBo, type, definition) {
var isType = eventBo.$instanceOf(type);
var isDefinition = false;
var definitions = eventBo.eventDefinitions || [];
forEach(definitions, function(def) {
if (def.$type === definition) {
isDefinition = true;
}
});
return isType && isDefinition;
}
},{"255":255,"368":368,"377":377,"44":44,"45":45,"68":68,"70":70}],10:[function(_dereq_,module,exports){
module.exports = {
__depends__: [
_dereq_(93),
_dereq_(124),
_dereq_(189),
_dereq_(122),
_dereq_(126),
_dereq_(51)
],
__init__: [ 'contextPadProvider' ],
contextPadProvider: [ 'type', _dereq_(9) ]
};
},{"122":122,"124":124,"126":126,"189":189,"51":51,"9":9,"93":93}],11:[function(_dereq_,module,exports){
'use strict';
function BpmnKeyBindings(keyboard, spaceTool, lassoTool, handTool, directEditing,
selection, canvas, elementRegistry, editorActions) {
var actions = {
selectElements: function() {
// select all elements except for the invisible
// root element
var rootElement = canvas.getRootElement();
var elements = elementRegistry.filter(function(element) {
return element != rootElement;
});
selection.select(elements);
},
spaceTool: function() {
spaceTool.toggle();
},
lassoTool: function() {
lassoTool.toggle();
},
handTool: function() {
handTool.toggle();
},
directEditing: function() {
var currentSelection = selection.get();
if (currentSelection.length) {
directEditing.activate(currentSelection[0]);
}
}
};
editorActions.register(actions);
keyboard.addListener(function(key, modifiers) {
// ctrl + a -> select all elements
if (key === 65 && keyboard.isCmd(modifiers)) {
editorActions.trigger('selectElements');
return true;
}
if (keyboard.hasModifier(modifiers)) {
return;
}
// s -> activate space tool
if (key === 83) {
editorActions.trigger('spaceTool');
return true;
}
// l -> activate lasso tool
if (key === 76) {
editorActions.trigger('lassoTool');
return true;
}
// h -> activate hand tool
if (key === 72) {
editorActions.trigger('handTool');
return true;
}
// e -> activate direct editing
if (key === 69) {
editorActions.trigger('directEditing');
return true;
}
});
}
BpmnKeyBindings.$inject = [
'keyboard',
'spaceTool',
'lassoTool',
'handTool',
'directEditing',
'selection',
'canvas',
'elementRegistry',
'editorActions'
];
module.exports = BpmnKeyBindings;
},{}],12:[function(_dereq_,module,exports){
module.exports = {
__depends__: [
_dereq_(137)
],
__init__: [ 'bpmnKeyBindings' ],
bpmnKeyBindings: [ 'type', _dereq_(11) ]
};
},{"11":11,"137":137}],13:[function(_dereq_,module,exports){
'use strict';
var UpdateLabelHandler = _dereq_(15);
var LabelUtil = _dereq_(14);
var is = _dereq_(70).is,
isExpanded = _dereq_(68).isExpanded;
var MIN_BOUNDS = {
width: 150,
height: 50
};
function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
directEditing.registerProvider(this);
commandStack.registerHandler('element.updateLabel', UpdateLabelHandler);
// listen to dblclick on non-root elements
eventBus.on('element.dblclick', function(event) {
directEditing.activate(event.element);
});
// complete on followup canvas operation
eventBus.on([ 'element.mousedown', 'drag.init', 'canvas.viewbox.changed' ], function(event) {
directEditing.complete();
});
// cancel on command stack changes
eventBus.on([ 'commandStack.changed' ], function() {
directEditing.cancel();
});
// activate direct editing for activities and text annotations
if ('ontouchstart' in document.documentElement) {
// we deactivate automatic label editing on mobile devices
// as it breaks the user interaction workflow
// TODO(nre): we should temporarily focus the edited element here
// and release the focused viewport after the direct edit operation is finished
} else {
eventBus.on('create.end', 500, function(e) {
var element = e.shape,
canExecute = e.context.canExecute;
if (!canExecute) {
return;
}
if (is(element, 'bpmn:Task') || is(element, 'bpmn:TextAnnotation') ||
(is(element, 'bpmn:SubProcess') && !isExpanded(element))) {
directEditing.activate(element);
}
});
}
this._canvas = canvas;
this._commandStack = commandStack;
}
LabelEditingProvider.$inject = [ 'eventBus', 'canvas', 'directEditing', 'commandStack' ];
module.exports = LabelEditingProvider;
LabelEditingProvider.prototype.activate = function(element) {
var text = LabelUtil.getLabel(element);
if (text === undefined) {
return;
}
var bbox = this.getEditingBBox(element);
// adjust for expanded pools AND lanes
if ((is(element, 'bpmn:Participant') && isExpanded(element)) || is(element, 'bpmn:Lane')) {
bbox.width = MIN_BOUNDS.width;
bbox.height = MIN_BOUNDS.height;
bbox.x = bbox.x + 10 - bbox.width / 2;
bbox.y = bbox.mid.y - bbox.height / 2;
}
// ajust minumum size for task and activities
if ((is(element, 'bpmn:Task') || is(element, 'bpmn:Activity') )) {
if (bbox.width < 100) {
bbox.width = 100;
bbox.x = bbox.mid.x - bbox.width / 2;
}
if (bbox.height < 80) {
bbox.height = 80;
bbox.y = bbox.mid.y - bbox.height / 2;
}
}
// adjust for expanded sub processes and collapsed pools
if ((is(element, 'bpmn:SubProcess') && isExpanded(element)) ||
(is(element, 'bpmn:Participant') && !isExpanded(element))) {
bbox.width = element.width;
bbox.height = MIN_BOUNDS.height;
bbox.x = bbox.mid.x - element.width / 2;
}
return { bounds: bbox, text: text };
};
LabelEditingProvider.prototype.getEditingBBox = function(element, maxBounds) {
var target = element.label || element;
var bbox = this._canvas.getAbsoluteBBox(target);
var mid = {
x: bbox.x + bbox.width / 2,
y: bbox.y + bbox.height / 2
};
// external label
if (target.labelTarget) {
bbox.width = Math.max(bbox.width, MIN_BOUNDS.width);
bbox.height = Math.max(bbox.height, MIN_BOUNDS.height);
bbox.x = mid.x - bbox.width / 2;
}
bbox.mid = mid;
return bbox;
};
LabelEditingProvider.prototype.update = function(element, newLabel) {
this._commandStack.execute('element.updateLabel', {
element: element,
newLabel: newLabel
});
};
},{"14":14,"15":15,"68":68,"70":70}],14:[function(_dereq_,module,exports){
'use strict';
var is = _dereq_(70).is;
function getLabelAttr(semantic) {
if (is(semantic, 'bpmn:FlowElement') ||
is(semantic, 'bpmn:Participant') ||
is(semantic, 'bpmn:Lane') ||
is(semantic, 'bpmn:SequenceFlow') ||
is(semantic, 'bpmn:MessageFlow')) {
return 'name';
}
if (is(semantic, 'bpmn:TextAnnotation')) {
return 'text';
}
}
module.exports.getLabel = function(element) {
var semantic = element.businessObject,
attr = getLabelAttr(semantic);
if (attr) {
return semantic[attr] || '';
}
};
module.exports.setLabel = function(element, text, isExternal) {
var semantic = element.businessObject,
attr = getLabelAttr(semantic);
if (attr) {
semantic[attr] = text;
}
// show external label if not empty
if (isExternal) {
element.hidden = !text;
}
return element;
};
},{"70":70}],15:[function(_dereq_,module,exports){
'use strict';
var LabelUtil = _dereq_(14);
/**
* A handler that updates the text of a BPMN element.
*/
function UpdateLabelHandler() {
/**
* 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;
LabelUtil.setLabel(label, text, labelTarget !== label);
return [ label, labelTarget ];
}
function execute(ctx) {
ctx.oldLabel = LabelUtil.getLabel(ctx.element);
return setText(ctx.element, ctx.newLabel);
}
function revert(ctx) {
return setText(ctx.element, ctx.oldLabel);
}
// API
this.execute = execute;
this.revert = revert;
}
module.exports = UpdateLabelHandler;
},{"14":14}],16:[function(_dereq_,module,exports){
module.exports = {
__depends__: [
_dereq_(100),
_dereq_(120),
_dereq_(93)
],
__init__: [ 'labelEditingProvider' ],
labelEditingProvider: [ 'type', _dereq_(13) ]
};
},{"100":100,"120":120,"13":13,"93":93}],17:[function(_dereq_,module,exports){
'use strict';
var map = _dereq_(258),
assign = _dereq_(377),
pick = _dereq_(383);
function BpmnFactory(moddle) {
this._model = moddle;
}
BpmnFactory.$inject = [ 'moddle' ];
BpmnFactory.prototype._needsId = function(element) {
return element.$instanceOf('bpmn:RootElement') ||
element.$instanceOf('bpmn:FlowElement') ||
element.$instanceOf('bpmn:MessageFlow') ||
element.$instanceOf('bpmn:DataAssociation') ||
element.$instanceOf('bpmn:Artifact') ||
element.$instanceOf('bpmn:Participant') ||
element.$instanceOf('bpmn:Lane') ||
element.$instanceOf('bpmn:Process') ||
element.$instanceOf('bpmn:Collaboration') ||
element.$instanceOf('bpmndi:BPMNShape') ||
element.$instanceOf('bpmndi:BPMNEdge') ||
element.$instanceOf('bpmndi:BPMNDiagram') ||
element.$instanceOf('bpmndi:BPMNPlane') ||
element.$instanceOf('bpmn:Property');
};
BpmnFactory.prototype._ensureId = function(element) {
// generate semantic ids for elements
// bpmn:SequenceFlow -> SequenceFlow_ID
var prefix = (element.$type || '').replace(/^[^:]*:/g, '') + '_';
if (!element.id && this._needsId(element)) {
element.id = this._model.ids.nextPrefixed(prefix, element);
}
};
BpmnFactory.prototype.create = function(type, attrs) {
var element = this._model.create(type, attrs || {});
this._ensureId(element);
return element;
};
BpmnFactory.prototype.createDiLabel = function() {
return this.create('bpmndi:BPMNLabel', {
bounds: this.createDiBounds()
});
};
BpmnFactory.prototype.createDiShape = function(semantic, bounds, attrs) {
return this.create('bpmndi:BPMNShape', assign({
bpmnElement: semantic,
bounds: this.createDiBounds(bounds)
}, attrs));
};
BpmnFactory.prototype.createDiBounds = function(bounds) {
return this.create('dc:Bounds', bounds);
};
BpmnFactory.prototype.createDiWaypoints = function(waypoints) {
return map(waypoints, function(pos) {
return this.createDiWaypoint(pos);
}, this);
};
BpmnFactory.prototype.createDiWaypoint = function(point) {
return this.create('dc:Point', pick(point, [ 'x', 'y' ]));
};
BpmnFactory.prototype.createDiEdge = function(semantic, waypoints, attrs) {
return this.create('bpmndi:BPMNEdge', assign({
bpmnElement: semantic
}, attrs));
};
BpmnFactory.prototype.createDiPlane = function(semantic) {
return this.create('bpmndi:BPMNPlane', {
bpmnElement: semantic
});
};
module.exports = BpmnFactory;
},{"258":258,"377":377,"383":383}],18:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var assign = _dereq_(377);
var BaseLayouter = _dereq_(206),
ManhattanLayout = _dereq_(209);
var LayoutUtil = _dereq_(208);
var getMid = LayoutUtil.getMid,
getOrientation = LayoutUtil.getOrientation;
var is = _dereq_(70).is;
function BpmnLayouter() {}
inherits(BpmnLayouter, BaseLayouter);
module.exports = BpmnLayouter;
BpmnLayouter.prototype.layoutConnection = function(connection, layoutHints) {
var source = connection.source,
target = connection.target,
waypoints = connection.waypoints,
start,
end;
var manhattanOptions,
updatedWaypoints;
start = getConnectionDocking(waypoints, 0, source);
end = getConnectionDocking(waypoints, waypoints && waypoints.length - 1, target);
// TODO (nre): support vertical modeling
// and invert preferredLayouts accordingly
if (is(connection, 'bpmn:Association') ||
is(connection, 'bpmn:DataAssociation')) {
if (waypoints && !isCompensationAssociation(connection)) {
return waypoints;
}
}
// manhattan layout sequence / message flows
if (is(connection, 'bpmn:MessageFlow')) {
manhattanOptions = {
preferredLayouts: [ 'straight', 'v:v' ]
};
if (is(target, 'bpmn:Event')) {
manhattanOptions = {
preferredLayouts: [ 'v:v' ]
};
}
} else
// layout all connection between flow elements h:h,
//
// except for
//
// (1) outgoing of BoundaryEvents -> layout h:v or v:h based on attach orientation
// (2) incoming / outgoing of Gateway -> v:h (outgoing), h:v (incoming)
//
if (is(connection, 'bpmn:SequenceFlow') ||
isCompensationAssociation(connection)) {
// make sure boundary event connections do
// not look ugly =:>
if (is(source, 'bpmn:BoundaryEvent')) {
var orientation = getAttachOrientation(source);
if (/left|right/.test(orientation)) {
manhattanOptions = {
preferredLayouts: [ 'h:v' ]
};
} else
if (/top|bottom/.test(orientation)) {
manhattanOptions = {
preferredLayouts: [ 'v:h' ]
};
}
} else
if (is(source, 'bpmn:Gateway')) {
manhattanOptions = {
preferredLayouts: [ 'v:h' ]
};
} else
if (is(target, 'bpmn:Gateway')) {
manhattanOptions = {
preferredLayouts: [ 'h:v' ]
};
}
// apply horizontal love <3
else {
manhattanOptions = {
preferredLayouts: [ 'h:h' ]
};
}
}
if (manhattanOptions) {
manhattanOptions = assign(manhattanOptions, layoutHints);
updatedWaypoints =
ManhattanLayout.repairConnection(
source, target,
start, end,
waypoints,
manhattanOptions);
}
return updatedWaypoints || [ start, end ];
};
function getAttachOrientation(attachedElement) {
var hostElement = attachedElement.host,
padding = -10;
return getOrientation(getMid(attachedElement), hostElement, padding);
}
function getConnectionDocking(waypoints, idx, shape) {
var point = waypoints && waypoints[idx];
return point ? (point.original || point) : getMid(shape);
}
function isCompensationAssociation(connection) {
var source = connection.source,
target = connection.target;
return is(target, 'bpmn:Activity') &&
is(source, 'bpmn:BoundaryEvent') &&
target.businessObject.isForCompensation;
}
},{"206":206,"208":208,"209":209,"243":243,"377":377,"70":70}],19:[function(_dereq_,module,exports){
'use strict';
var assign = _dereq_(377),
forEach = _dereq_(255),
inherits = _dereq_(243);
var Collections = _dereq_(219),
Model = _dereq_(210);
var getBusinessObject = _dereq_(70).getBusinessObject,
is = _dereq_(70).is;
var CommandInterceptor = _dereq_(98);
/**
* A handler responsible for updating the underlying BPMN 2.0 XML + DI
* once changes on the diagram happen
*/
function BpmnUpdater(eventBus, bpmnFactory, connectionDocking, translate) {
CommandInterceptor.call(this, eventBus);
this._bpmnFactory = bpmnFactory;
this._translate = translate;
var self = this;
////// connection cropping /////////////////////////
// crop connection ends during create/update
function cropConnection(e) {
var context = e.context,
connection;
if (!context.cropped) {
connection = context.connection;
connection.waypoints = connectionDocking.getCroppedWaypoints(connection);
context.cropped = true;
}
}
this.executed([
'connection.layout',
'connection.create',
'connection.reconnectEnd',
'connection.reconnectStart'
], cropConnection);
this.reverted([ 'connection.layout' ], function(e) {
delete e.context.cropped;
});
////// BPMN + DI update /////////////////////////
// update parent
function updateParent(e) {
var context = e.context;
self.updateParent(context.shape || context.connection, context.oldParent);
}
function reverseUpdateParent(e) {
var context = e.context;
var element = context.shape || context.connection,
// oldParent is the (old) new parent, because we are undoing
oldParent = context.parent || context.newParent;
self.updateParent(element, oldParent);
}
this.executed([ 'shape.move',
'shape.create',
'shape.delete',
'connection.create',
'connection.move',
'connection.delete' ], ifBpmn(updateParent));
this.reverted([ 'shape.move',
'shape.create',
'shape.delete',
'connection.create',
'connection.move',
'connection.delete' ], ifBpmn(reverseUpdateParent));
/*
* ## Updating Parent
*
* When morphing a Process into a Collaboration or vice-versa,
* make sure that both the *semantic* and *di* parent of each element
* is updated.
*
*/
function updateRoot(event) {
var context = event.context,
oldRoot = context.oldRoot,
children = oldRoot.children;
forEach(children, function(child) {
self.updateParent(child);
});
}
this.executed([ 'canvas.updateRoot' ], updateRoot);
this.reverted([ 'canvas.updateRoot' ], updateRoot);
// update bounds
function updateBounds(e) {
var shape = e.context.shape;
if (!is(shape, 'bpmn:BaseElement')) {
return;
}
self.updateBounds(shape);
}
this.executed([ 'shape.move', 'shape.create', 'shape.resize' ], ifBpmn(updateBounds));
this.reverted([ 'shape.move', 'shape.create', 'shape.resize' ], ifBpmn(updateBounds));
// attach / detach connection
function updateConnection(e) {
self.updateConnection(e.context);
}
this.executed([
'connection.create',
'connection.move',
'connection.delete',
'connection.reconnectEnd',
'connection.reconnectStart'
], ifBpmn(updateConnection));
this.reverted([
'connection.create',
'connection.move',
'connection.delete',
'connection.reconnectEnd',
'connection.reconnectStart'
], ifBpmn(updateConnection));
// update waypoints
function updateConnectionWaypoints(e) {
self.updateConnectionWaypoints(e.context.connection);
}
this.executed([
'connection.layout',
'connection.move',
'connection.updateWaypoints',
'connection.reconnectEnd',
'connection.reconnectStart'
], ifBpmn(updateConnectionWaypoints));
this.reverted([
'connection.layout',
'connection.move',
'connection.updateWaypoints',
'connection.reconnectEnd',
'connection.reconnectStart'
], ifBpmn(updateConnectionWaypoints));
// update Default & Conditional flows
this.executed([
'connection.reconnectEnd',
'connection.reconnectStart'
], ifBpmn(function(e) {
var context = e.context,
connection = context.connection,
businessObject = getBusinessObject(connection),
oldSource = getBusinessObject(context.oldSource),
oldTarget = getBusinessObject(context.oldTarget),
newSource = getBusinessObject(connection.source),
newTarget = getBusinessObject(connection.target);
if (oldSource === newSource || oldTarget === newTarget) {
return;
}
// on reconnectStart -> default flow
if (oldSource && oldSource.default) {
context.default = oldSource.default;
oldSource.default = undefined;
}
// on reconnectEnd -> default flow
if ((businessObject.sourceRef && businessObject.sourceRef.default) && !is(newTarget, 'bpmn:Activity')) {
context.default = businessObject.sourceRef.default;
businessObject.sourceRef.default = undefined;
}
// on reconnectStart -> condtional flow
if ((businessObject.conditionExpression) && is(oldSource, 'bpmn:Activity')) {
context.conditionExpression = businessObject.conditionExpression;
businessObject.conditionExpression = undefined;
}
// on reconnectEnd -> condtional flow
if ((businessObject.conditionExpression) && !is(newTarget, 'bpmn:Activity')) {
context.conditionExpression = businessObject.conditionExpression;
businessObject.conditionExpression = undefined;
}
}));
this.reverted([
'connection.reconnectEnd',
'connection.reconnectStart'
], ifBpmn(function(e) {
var context = e.context,
connection = context.connection,
businessObject = getBusinessObject(connection),
newSource = getBusinessObject(connection.source);
// default flow
if (context.default) {
if (is(newSource, 'bpmn:ExclusiveGateway') || is(newSource, 'bpmn:InclusiveGateway') ||
is(newSource, 'bpmn:Activity')) {
newSource.default = context.default;
}
}
// conditional flow
if (context.conditionExpression && is(newSource, 'bpmn:Activity')) {
businessObject.conditionExpression = context.conditionExpression;
}
}));
// update attachments
function updateAttachment(e) {
self.updateAttachment(e.context);
}
this.executed([ 'element.updateAttachment' ], ifBpmn(updateAttachment));
this.reverted([ 'element.updateAttachment' ], ifBpmn(updateAttachment));
}
inherits(BpmnUpdater, CommandInterceptor);
module.exports = BpmnUpdater;
BpmnUpdater.$inject = [ 'eventBus', 'bpmnFactory', 'connectionDocking', 'translate' ];
/////// implementation //////////////////////////////////
BpmnUpdater.prototype.updateAttachment = function(context) {
var shape = context.shape,
businessObject = shape.businessObject,
host = shape.host;
businessObject.attachedToRef = host && host.businessObject;
};
BpmnUpdater.prototype.updateParent = function(element, oldParent) {
// do not update BPMN 2.0 label parent
if (element instanceof Model.Label) {
return;
}
var parentShape = element.parent;
var businessObject = element.businessObject,
parentBusinessObject = parentShape && parentShape.businessObject,
parentDi = parentBusinessObject && parentBusinessObject.di;
if (is(element, 'bpmn:FlowNode')) {
this.updateFlowNodeRefs(businessObject, parentBusinessObject, oldParent && oldParent.businessObject);
}
if (is(element, 'bpmn:DataOutputAssociation')) {
if (element.source) {
parentBusinessObject = element.source.businessObject;
} else {
parentBusinessObject = null;
}
}
if (is(element, 'bpmn:DataInputAssociation')) {
if (element.target) {
parentBusinessObject = element.target.businessObject;
} else {
parentBusinessObject = null;
}
}
this.updateSemanticParent(businessObject, parentBusinessObject);
if (is(element, 'bpmn:DataObjectReference') && businessObject.dataObjectRef) {
this.updateSemanticParent(businessObject.dataObjectRef, parentBusinessObject);
}
this.updateDiParent(businessObject.di, parentDi);
};
BpmnUpdater.prototype.updateBounds = function(shape) {
var di = shape.businessObject.di;
var bounds = (shape instanceof Model.Label) ? this._getLabel(di).bounds : di.bounds;
assign(bounds, {
x: shape.x,
y: shape.y,
width: shape.width,
height: shape.height
});
};
BpmnUpdater.prototype.updateFlowNodeRefs = function(businessObject, newContainment, oldContainment) {
if (oldContainment === newContainment) {
return;
}
var oldRefs, newRefs;
if (is (oldContainment, 'bpmn:Lane')) {
oldRefs = oldContainment.get('flowNodeRef');
Collections.remove(oldRefs, businessObject);
}
if (is(newContainment, 'bpmn:Lane')) {
newRefs = newContainment.get('flowNodeRef');
Collections.add(newRefs, businessObject);
}
};
BpmnUpdater.prototype.updateDiParent = function(di, parentDi) {
if (parentDi && !is(parentDi, 'bpmndi:BPMNPlane')) {
parentDi = parentDi.$parent;
}
if (di.$parent === parentDi) {
return;
}
var planeElements = (parentDi || di.$parent).get('planeElement');
if (parentDi) {
planeElements.push(di);
di.$parent = parentDi;
} else {
Collections.remove(planeElements, di);
di.$parent = null;
}
};
function getDefinitions(element) {
while (element && !is(element, 'bpmn:Definitions')) {
element = element.$parent;
}
return element;
}
BpmnUpdater.prototype.getLaneSet = function(container) {
var laneSet, laneSets;
// bpmn:Lane
if (is(container, 'bpmn:Lane')) {
laneSet = container.childLaneSet;
if (!laneSet) {
laneSet = this._bpmnFactory.create('bpmn:LaneSet');
container.childLaneSet = laneSet;
laneSet.$parent = container;
}
return laneSet;
}
// bpmn:Participant
if (is(container, 'bpmn:Participant')) {
container = container.processRef;
}
// bpmn:FlowElementsContainer
laneSets = container.get('laneSets');
laneSet = laneSets[0];
if (!laneSet) {
laneSet = this._bpmnFactory.create('bpmn:LaneSet');
laneSet.$parent = container;
laneSets.push(laneSet);
}
return laneSet;
};
BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent) {
var containment,
translate = this._translate;
if (businessObject.$parent === newParent) {
return;
}
if (is(businessObject, 'bpmn:Lane')) {
if (newParent) {
newParent = this.getLaneSet(newParent);
}
containment = 'lanes';
} else
if (is(businessObject, 'bpmn:FlowElement')) {
if (newParent) {
if (is(newParent, 'bpmn:Participant')) {
newParent = newParent.processRef;
} else
if (is(newParent, 'bpmn:Lane')) {
do {
// unwrap Lane -> LaneSet -> (Lane | FlowElementsContainer)
newParent = newParent.$parent.$parent;
} while(is(newParent, 'bpmn:Lane'));
}
}
containment = 'flowElements';
} else
if (is(businessObject, 'bpmn:Artifact')) {
while (newParent &&
!is(newParent, 'bpmn:Process') &&
!is(newParent, 'bpmn:SubProcess') &&
!is(newParent, 'bpmn:Collaboration')) {
if (is(newParent, 'bpmn:Participant')) {
newParent = newParent.processRef;
break;
} else {
newParent = newParent.$parent;
}
}
containment = 'artifacts';
} else
if (is(businessObject, 'bpmn:MessageFlow')) {
containment = 'messageFlows';
} else
if (is(businessObject, 'bpmn:Participant')) {
containment = 'participants';
// make sure the participants process is properly attached / detached
// from the XML document
var process = businessObject.processRef,
definitions;
if (process) {
definitions = getDefinitions(businessObject.$parent || newParent);
if (businessObject.$parent) {
Collections.remove(definitions.get('rootElements'), process);
process.$parent = null;
}
if (newParent) {
Collections.add(definitions.get('rootElements'), process);
process.$parent = definitions;
}
}
} else
if (is(businessObject, 'bpmn:DataOutputAssociation')) {
containment = 'dataOutputAssociations';
} else
if (is(businessObject, 'bpmn:DataInputAssociation')) {
containment = 'dataInputAssociations';
}
if (!containment) {
throw new Error(translate(
'no parent for {element} in {parent}',
{
element: businessObject.id,
parent: newParent.id
}
));
}
var children;
if (businessObject.$parent) {
// remove from old parent
children = businessObject.$parent.get(containment);
Collections.remove(children, businessObject);
}
if (!newParent) {
businessObject.$parent = null;
} else {
// add to new parent
children = newParent.get(containment);
children.push(businessObject);
businessObject.$parent = newParent;
}
};
BpmnUpdater.prototype.updateConnectionWaypoints = function(connection) {
connection.businessObject.di.set('waypoint', this._bpmnFactory.createDiWaypoints(connection.waypoints));
};
BpmnUpdater.prototype.updateConnection = function(context) {
var connection = context.connection,
businessObject = getBusinessObject(connection),
newSource = getBusinessObject(connection.source),
newTarget = getBusinessObject(connection.target);
if (!is(businessObject, 'bpmn:DataAssociation')) {
var inverseSet = is(businessObject, 'bpmn:SequenceFlow');
if (businessObject.sourceRef !== newSource) {
if (inverseSet) {
Collections.remove(businessObject.sourceRef && businessObject.sourceRef.get('outgoing'), businessObject);
if (newSource && newSource.get('outgoing')) {
newSource.get('outgoing').push(businessObject);
}
}
businessObject.sourceRef = newSource;
}
if (businessObject.targetRef !== newTarget) {
if (inverseSet) {
Collections.remove(businessObject.targetRef && businessObject.targetRef.get('incoming'), businessObject);
if (newTarget && newTarget.get('incoming')) {
newTarget.get('incoming').push(businessObject);
}
}
businessObject.targetRef = newTarget;
}
} else
if (is(businessObject, 'bpmn:DataInputAssociation')) {
// handle obnoxious isMany sourceRef
businessObject.get('sourceRef')[0] = newSource;
// targetRef = new parent
this.updateSemanticParent(businessObject, newTarget);
} else
if (is(businessObject, 'bpmn:DataOutputAssociation')) {
// sourceRef = new parent
this.updateSemanticParent(businessObject, newSource);
// targetRef = new target
businessObject.targetRef = newTarget;
}
this.updateConnectionWaypoints(connection);
};
/////// helpers /////////////////////////////////////////
BpmnUpdater.prototype._getLabel = function(di) {
if (!di.label) {
di.label = this._bpmnFactory.createDiLabel();
}
return di.label;
};
/**
* Make sure the event listener is only called
* if the touched element is a BPMN element.
*
* @param {Function} fn
* @return {Function} guarded function
*/
function ifBpmn(fn) {
return function(event) {
var context = event.context,
element = context.shape || context.connection;
if (is(element, 'bpmn:BaseElement')) {
fn(event);
}
};
}
},{"210":210,"219":219,"243":243,"255":255,"377":377,"70":70,"98":98}],20:[function(_dereq_,module,exports){
'use strict';
var assign = _dereq_(377),
inherits = _dereq_(243);
var is = _dereq_(70).is;
var isExpanded = _dereq_(68).isExpanded;
var BaseElementFactory = _dereq_(102),
LabelUtil = _dereq_(69);
/**
* A bpmn-aware factory for diagram-js shapes
*/
function ElementFactory(bpmnFactory, moddle, translate) {
BaseElementFactory.call(this);
this._bpmnFactory = bpmnFactory;
this._moddle = moddle;
this._translate = translate;
}
inherits(ElementFactory, BaseElementFactory);
ElementFactory.$inject = [ 'bpmnFactory', 'moddle', 'translate' ];
module.exports = ElementFactory;
ElementFactory.prototype.baseCreate = BaseElementFactory.prototype.create;
ElementFactory.prototype.create = function(elementType, attrs) {
// no special magic for labels,
// we assume their businessObjects have already been created
// and wired via attrs
if (elementType === 'label') {
return this.baseCreate(elementType, assign({ type: 'label' }, LabelUtil.DEFAULT_LABEL_SIZE, attrs));
}
return this.createBpmnElement(elementType, attrs);
};
ElementFactory.prototype.createBpmnElement = function(elementType, attrs) {
var size,
translate = this._translate;
attrs = attrs || {};
var businessObject = attrs.businessObject;
if (!businessObject) {
if (!attrs.type) {
throw new Error(translate('no shape type specified'));
}
businessObject = this._bpmnFactory.create(attrs.type);
}
if (!businessObject.di) {
if (elementType === 'root') {
businessObject.di = this._bpmnFactory.createDiPlane(businessObject, [], {
id: businessObject.id + '_di'
});
} else
if (elementType === 'connection') {
businessObject.di = this._bpmnFactory.createDiEdge(businessObject, [], {
id: businessObject.id + '_di'
});
} else {
businessObject.di = this._bpmnFactory.createDiShape(businessObject, {}, {
id: businessObject.id + '_di'
});
}
}
if (attrs.processRef) {
businessObject.processRef = attrs.processRef;
}
if (attrs.isExpanded) {
businessObject.di.isExpanded = attrs.isExpanded;
}
if (is(businessObject, 'bpmn:ExclusiveGateway')) {
businessObject.di.isMarkerVisible = true;
}
if (attrs.isInterrupting === false) {
businessObject.isInterrupting = false;
}
if (attrs.associationDirection) {
businessObject.associationDirection = attrs.associationDirection;
}
var eventDefinitions,
newEventDefinition;
if (attrs.eventDefinitionType) {
eventDefinitions = businessObject.get('eventDefinitions') || [];
newEventDefinition = this._moddle.create(attrs.eventDefinitionType);
eventDefinitions.push(newEventDefinition);
newEventDefinition.$parent = businessObject;
businessObject.eventDefinitions = eventDefinitions;
}
if (attrs.isForCompensation) {
businessObject.isForCompensation = true;
}
size = this._getDefaultSize(businessObject);
attrs = assign({
businessObject: businessObject,
id: businessObject.id
}, size, attrs);
return this.baseCreate(elementType, attrs);
};
ElementFactory.prototype._getDefaultSize = function(semantic) {
if (is(semantic, 'bpmn:SubProcess')) {
if (isExpanded(semantic)) {
return { width: 350, height: 200 };
} else {
return { width: 100, height: 80 };
}
}
if (is(semantic, 'bpmn:Task')) {
return { width: 100, height: 80 };
}
if (is(semantic, 'bpmn:Gateway')) {
return { width: 50, height: 50 };
}
if (is(semantic, 'bpmn:Event')) {
return { width: 36, height: 36 };
}
if (is(semantic, 'bpmn:Participant')) {
if (!isExpanded(semantic)) {
return { width: 400, height: 100 };
} else {
return { width: 600, height: 250 };
}
}
if (is(semantic, 'bpmn:Lane')) {
return { width: 400, height: 100 };
}
if (is(semantic, 'bpmn:DataObjectReference')) {
return { width: 36, height: 50 };
}
if (is(semantic, 'bpmn:DataStoreReference')) {
return { width: 50, height: 50 };
}
if (is(semantic, 'bpmn:TextAnnotation')) {
return { width: 100, height: 30 };
}
return { width: 100, height: 80 };
};
ElementFactory.prototype.createParticipantShape = function(collapsed) {
var attrs = { type: 'bpmn:Participant' };
if (!collapsed) {
attrs.processRef = this._bpmnFactory.create('bpmn:Process');
}
return this.createShape(attrs);
};
},{"102":102,"243":243,"377":377,"68":68,"69":69,"70":70}],21:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var BaseModeling = _dereq_(142);
var UpdatePropertiesHandler = _dereq_(42),
UpdateCanvasRootHandler = _dereq_(40),
AddLaneHandler = _dereq_(37),
SplitLaneHandler = _dereq_(39),
ResizeLaneHandler = _dereq_(38),
UpdateFlowNodeRefsHandler = _dereq_(41);
/**
* BPMN 2.0 modeling features activator
*
* @param {EventBus} eventBus
* @param {ElementFactory} elementFactory
* @param {CommandStack} commandStack
* @param {BpmnRules} bpmnRules
*/
function Modeling(eventBus, elementFactory, commandStack, bpmnRules) {
BaseModeling.call(this, eventBus, elementFactory, commandStack);
this._bpmnRules = bpmnRules;
}
inherits(Modeling, BaseModeling);
Modeling.$inject = [ 'eventBus', 'elementFactory', 'commandStack', 'bpmnRules' ];
module.exports = Modeling;
Modeling.prototype.getHandlers = function() {
var handlers = BaseModeling.prototype.getHandlers.call(this);
handlers['element.updateProperties'] = UpdatePropertiesHandler;
handlers['canvas.updateRoot'] = UpdateCanvasRootHandler;
handlers['lane.add'] = AddLaneHandler;
handlers['lane.resize'] = ResizeLaneHandler;
handlers['lane.split'] = SplitLaneHandler;
handlers['lane.updateRefs'] = UpdateFlowNodeRefsHandler;
return handlers;
};
Modeling.prototype.updateLabel = function(element, newLabel) {
this._commandStack.execute('element.updateLabel', {
element: element,
newLabel: newLabel
});
};
Modeling.prototype.connect = function(source, target, attrs) {
var bpmnRules = this._bpmnRules;
if (!attrs) {
attrs = bpmnRules.canConnect(source, target) || { type: 'bpmn:Association' };
}
return this.createConnection(source, target, attrs, source.parent);
};
Modeling.prototype.updateProperties = function(element, properties) {
this._commandStack.execute('element.updateProperties', {
element: element,
properties: properties
});
};
Modeling.prototype.resizeLane = function(laneShape, newBounds, balanced) {
this._commandStack.execute('lane.resize', {
shape: laneShape,
newBounds: newBounds,
balanced: balanced
});
};
Modeling.prototype.addLane = function(targetLaneShape, location) {
var context = {
shape: targetLaneShape,
location: location
};
this._commandStack.execute('lane.add', context);
return context.newLane;
};
Modeling.prototype.splitLane = function(targetLane, count) {
this._commandStack.execute('lane.split', {
shape: targetLane,
count: count
});
};
/**
* Transform the current diagram into a collaboration.
*
* @return {djs.model.Root} the new root element
*/
Modeling.prototype.makeCollaboration = function() {
var collaborationElement = this._create('root', {
type: 'bpmn:Collaboration'
});
var context = {
newRoot: collaborationElement
};
this._commandStack.execute('canvas.updateRoot', context);
return collaborationElement;
};
Modeling.prototype.updateLaneRefs = function(flowNodeShapes, laneShapes) {
this._commandStack.execute('lane.updateRefs', {
flowNodeShapes: flowNodeShapes,
laneShapes: laneShapes
});
};
/**
* Transform the current diagram into a process.
*
* @return {djs.model.Root} the new root element
*/
Modeling.prototype.makeProcess = function() {
var processElement = this._create('root', {
type: 'bpmn:Process'
});
var context = {
newRoot: processElement
};
this._commandStack.execute('canvas.updateRoot', context);
};
},{"142":142,"243":243,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42}],22:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var is = _dereq_(70).is;
var CommandInterceptor = _dereq_(98);
function AppendBehavior(eventBus, elementFactory, bpmnRules) {
CommandInterceptor.call(this, eventBus);
// assign correct shape position unless already set
this.preExecute('shape.append', function(context) {
var source = context.source,
shape = context.shape;
if (!context.position) {
if (is(shape, 'bpmn:TextAnnotation')) {
context.position = {
x: source.x + source.width / 2 + 75,
y: source.y - (50) - shape.height / 2
};
} else {
context.position = {
x: source.x + source.width + 80 + shape.width / 2,
y: source.y + source.height / 2
};
}
}
}, true);
}
AppendBehavior.$inject = [ 'eventBus', 'elementFactory', 'bpmnRules' ];
inherits(AppendBehavior, CommandInterceptor);
module.exports = AppendBehavior;
},{"243":243,"70":70,"98":98}],23:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var CommandInterceptor = _dereq_(98);
var is = _dereq_(70).is;
/**
* BPMN specific create boundary event behavior
*/
function CreateBoundaryEventBehavior(eventBus, modeling, elementFactory, bpmnFactory) {
CommandInterceptor.call(this, eventBus);
/**
* replace intermediate event with boundary event when
* attaching it to a shape
*/
this.preExecute('shape.create', function(context) {
var shape = context.shape,
host = context.host,
businessObject,
boundaryEvent;
var attrs = {
cancelActivity: true
};
if (host && is(shape, 'bpmn:IntermediateThrowEvent')) {
attrs.attachedToRef = host.businessObject;
businessObject = bpmnFactory.create('bpmn:BoundaryEvent', attrs);
boundaryEvent = {
type: 'bpmn:BoundaryEvent',
businessObject: businessObject
};
context.shape = elementFactory.createShape(boundaryEvent);
}
}, true);
}
CreateBoundaryEventBehavior.$inject = [ 'eventBus', 'modeling', 'elementFactory', 'bpmnFactory' ];
inherits(CreateBoundaryEventBehavior, CommandInterceptor);
module.exports = CreateBoundaryEventBehavior;
},{"243":243,"70":70,"98":98}],24:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var CommandInterceptor = _dereq_(98);
var is = _dereq_(70).is;
/**
* BPMN specific create data object behavior
*/
function CreateDataObjectBehavior(eventBus, bpmnFactory, moddle) {
CommandInterceptor.call(this, eventBus);
this.preExecute('shape.create', function(event) {
var context = event.context,
shape = context.shape;
if (is(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') {
// create a DataObject every time a DataObjectReference is created
var dataObject = bpmnFactory.create('bpmn:DataObject');
// set the reference to the DataObject
shape.businessObject.dataObjectRef = dataObject;
}
});
}
CreateDataObjectBehavior.$inject = [ 'eventBus', 'bpmnFactory', 'moddle' ];
inherits(CreateDataObjectBehavior, CommandInterceptor);
module.exports = CreateDataObjectBehavior;
},{"243":243,"70":70,"98":98}],25:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var assign = _dereq_(377);
var CommandInterceptor = _dereq_(98);
var getApproxIntersection = _dereq_(226).getApproxIntersection;
function copy(obj) {
return assign({}, obj);
}
function CreateOnFlowBehavior(eventBus, bpmnRules, modeling) {
CommandInterceptor.call(this, eventBus);
/**
* Reconnect start / end of a connection after
* dropping an element on a flow.
*/
this.preExecute('shape.create', function(context) {
var parent = context.parent,
shape = context.shape;
if (bpmnRules.canInsert(shape, parent)) {
context.targetFlow = parent;
context.parent = parent.parent;
}
}, true);
this.postExecute('shape.create', function(context) {
var shape = context.shape,
targetFlow = context.targetFlow,
position = context.position,
source,
target,
reconnected,
intersection,
waypoints,
waypointsBefore,
waypointsAfter,
dockingPoint;
if (targetFlow) {
waypoints = targetFlow.waypoints;
intersection = getApproxIntersection(waypoints, position);
if (intersection) {
waypointsBefore = waypoints.slice(0, intersection.index);
waypointsAfter = waypoints.slice(intersection.index + (intersection.bendpoint ? 1 : 0));
dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : position;
waypointsBefore.push(copy(dockingPoint));
waypointsAfter.unshift(copy(dockingPoint));
}
source = targetFlow.source;
target = targetFlow.target;
if (bpmnRules.canConnect(source, shape, targetFlow)) {
// reconnect source -> inserted shape
modeling.reconnectEnd(targetFlow, shape, waypointsBefore || copy(position));
reconnected = true;
}
if (bpmnRules.canConnect(shape, target, targetFlow)) {
if (!reconnected) {
// reconnect inserted shape -> end
modeling.reconnectStart(targetFlow, shape, waypointsAfter || copy(position));
} else {
modeling.connect(shape, target, { type: targetFlow.type, waypoints: waypointsAfter });
}
}
}
}, true);
}
inherits(CreateOnFlowBehavior, CommandInterceptor);
CreateOnFlowBehavior.$inject = [ 'eventBus', 'bpmnRules', 'modeling' ];
module.exports = CreateOnFlowBehavior;
},{"226":226,"243":243,"377":377,"98":98}],26:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var CommandInterceptor = _dereq_(98);
var is = _dereq_(70).is;
/**
* BPMN specific create participant behavior
*/
function CreateParticipantBehavior(eventBus, modeling, elementFactory, bpmnFactory) {
CommandInterceptor.call(this, eventBus);
/**
* morph process into collaboration before adding
* participant onto collaboration
*/
this.preExecute('shape.create', function(context) {
var parent = context.parent,
shape = context.shape,
position = context.position;
if (is(parent, 'bpmn:Process') && is(shape, 'bpmn:Participant')) {
// this is going to detach the process root
// and set the returned collaboration element
// as the new root element
var collaborationElement = modeling.makeCollaboration();
// monkey patch the create context
// so that the participant is being dropped
// onto the new collaboration root instead
context.position = position;
context.parent = collaborationElement;
context.processRoot = parent;
}
}, true);
this.execute('shape.create', function(context) {
var processRoot = context.processRoot,
shape = context.shape;
if (processRoot) {
context.oldProcessRef = shape.businessObject.processRef;
// assign the participant processRef
shape.businessObject.processRef = processRoot.businessObject;
}
}, true);
this.revert('shape.create', function(context) {
var processRoot = context.processRoot,
shape = context.shape;
if (processRoot) {
// assign the participant processRef
shape.businessObject.processRef = context.oldProcessRef;
}
}, true);
this.postExecute('shape.create', function(context) {
var processRoot = context.processRoot,
shape = context.shape;
if (processRoot) {
// process root is already detached at this point
var processChildren = processRoot.children.slice();
modeling.moveElements(processChildren, { x: 0, y: 0 }, shape);
}
}, true);
}
CreateParticipantBehavior.$inject = [ 'eventBus', 'modeling', 'elementFactory', 'bpmnFactory' ];
inherits(CreateParticipantBehavior, CommandInterceptor);
module.exports = CreateParticipantBehavior;
},{"243":243,"70":70,"98":98}],27:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var CommandInterceptor = _dereq_(98);
var Collections = _dereq_(219);
var find = _dereq_(254);
var is = _dereq_(70).is;
var TARGET_REF_PLACEHOLDER_NAME = '__targetRef_placeholder';
/**
* This behavior makes sure we always set a fake
* DataInputAssociation#targetRef as demanded by the BPMN 2.0
* XSD schema.
*
* The reference is set to a bpmn:Property{ name: '__targetRef_placeholder' }
* which is created on the fly and cleaned up afterwards if not needed
* anymore.
*
* @param {EventBus} eventBus
* @param {BpmnFactory} bpmnFactory
*/
function DataInputAssociationBehavior(eventBus, bpmnFactory) {
CommandInterceptor.call(this, eventBus);
this.executed([
'connection.create',
'connection.delete',
'connection.move',
'connection.reconnectEnd'
], ifDataInputAssociation(fixTargetRef));
this.reverted([
'connection.create',
'connection.delete',
'connection.move',
'connection.reconnectEnd'
], ifDataInputAssociation(fixTargetRef));
function usesTargetRef(element, targetRef, removedConnection) {
var inputAssociations = element.get('dataInputAssociations');
return find(inputAssociations, function(association) {
return association !== removedConnection &&
association.targetRef === targetRef;
});
}
function getTargetRef(element, create) {
var properties = element.get('properties');
var targetRefProp = find(properties, function(p) {
return p.name === TARGET_REF_PLACEHOLDER_NAME;
});
if (!targetRefProp && create) {
targetRefProp = bpmnFactory.create('bpmn:Property', {
name: TARGET_REF_PLACEHOLDER_NAME
});
Collections.add(properties, targetRefProp);
}
return targetRefProp;
}
function cleanupTargetRef(element, connection) {
var targetRefProp = getTargetRef(element);
if (!targetRefProp) {
return;
}
if (!usesTargetRef(element, targetRefProp, connection)) {
Collections.remove(element.get('properties'), targetRefProp);
}
}
/**
* Make sure targetRef is set to a valid property or
* `null` if the connection is detached.
*
* @param {Event} event
*/
function fixTargetRef(event) {
var context = event.context,
connection = context.connection,
connectionBo = connection.businessObject,
target = connection.target,
targetBo = target && target.businessObject,
newTarget = context.newTarget,
newTargetBo = newTarget && newTarget.businessObject,
oldTarget = context.oldTarget || context.target,
oldTargetBo = oldTarget && oldTarget.businessObject;
var dataAssociation = connection.businessObject,
targetRefProp;
if (oldTargetBo && oldTargetBo !== targetBo) {
cleanupTargetRef(oldTargetBo, connectionBo);
}
if (newTargetBo && newTargetBo !== targetBo) {
cleanupTargetRef(newTargetBo, connectionBo);
}
if (targetBo) {
targetRefProp = getTargetRef(targetBo, true);
dataAssociation.targetRef = targetRefProp;
} else {
dataAssociation.targetRef = null;
}
}
}
DataInputAssociationBehavior.$inject = [ 'eventBus', 'bpmnFactory' ];
inherits(DataInputAssociationBehavior, CommandInterceptor);
module.exports = DataInputAssociationBehavior;
/**
* Only call the given function when the event
* touches a bpmn:DataInputAssociation.
*
* @param {Function} fn
* @return {Function}
*/
function ifDataInputAssociation(fn) {
return function(event) {
var context = event.context,
connection = context.connection;
if (is(connection, 'bpmn:DataInputAssociation')) {
return fn(event);
}
};
}
},{"219":219,"243":243,"254":254,"70":70,"98":98}],28:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var CommandInterceptor = _dereq_(98);
var is = _dereq_(70).is;
var getChildLanes = _dereq_(44).getChildLanes;
var eachElement = _dereq_(221).eachElement;
var LOW_PRIORITY = 500;
/**
* BPMN specific delete lane behavior
*/
function DeleteLaneBehavior(eventBus, modeling, spaceTool) {
CommandInterceptor.call(this, eventBus);
function compensateLaneDelete(shape, oldParent) {
var siblings = getChildLanes(oldParent);
var topAffected = [];
var bottomAffected = [];
eachElement(siblings, function(element) {
if (element.y > shape.y) {
bottomAffected.push(element);
} else {
topAffected.push(element);
}
return element.children;
});
if (!siblings.length) {
return;
}
var offset;
if (bottomAffected.length && topAffected.length) {
offset = shape.height / 2;
} else {
offset = shape.height;
}
var topAdjustments,
bottomAdjustments;
if (topAffected.length) {
topAdjustments = spaceTool.calculateAdjustments(
topAffected, 'y', offset, shape.y - 10);
spaceTool.makeSpace(
topAdjustments.movingShapes,
topAdjustments.resizingShapes,
{ x: 0, y: offset }, 's');
}
if (bottomAffected.length) {
bottomAdjustments = spaceTool.calculateAdjustments(
bottomAffected, 'y', -offset, shape.y + shape.height + 10);
spaceTool.makeSpace(
bottomAdjustments.movingShapes,
bottomAdjustments.resizingShapes,
{ x: 0, y: -offset }, 'n');
}
}
/**
* Adjust sizes of other lanes after lane deletion
*/
this.postExecuted('shape.delete', LOW_PRIORITY, function(event) {
var context = event.context,
hints = context.hints,
shape = context.shape,
oldParent = context.oldParent;
// only compensate lane deletes
if (!is(shape, 'bpmn:Lane')) {
return;
}
// compensate root deletes only
if (hints && hints.nested) {
return;
}
compensateLaneDelete(shape, oldParent);
});
}
DeleteLaneBehavior.$inject = [ 'eventBus', 'modeling', 'spaceTool' ];
inherits(DeleteLaneBehavior, CommandInterceptor);
module.exports = DeleteLaneBehavior;
},{"221":221,"243":243,"44":44,"70":70,"98":98}],29:[function(_dereq_,module,exports){
'use strict';
var assign = _dereq_(377),
inherits = _dereq_(243);
var LabelUtil = _dereq_(69),
is = _dereq_(70).is;
var hasExternalLabel = LabelUtil.hasExternalLabel,
getExternalLabelMid = LabelUtil.getExternalLabelMid;
var CommandInterceptor = _dereq_(98);
/**
* A component that makes sure that external labels are added
* together with respective elements and properly updated (DI wise)
* during move.
*
* @param {EventBus} eventBus
* @param {Modeling} modeling
* @param {BpmnFactory} bpmnFactory
*/
function LabelSupport(eventBus, modeling, bpmnFactory) {
CommandInterceptor.call(this, eventBus);
// create external labels on shape creation
this.postExecute([ 'shape.create', 'connection.create' ], function(e) {
var context = e.context;
var element = context.shape || context.connection,
businessObject = element.businessObject;
var position;
if (hasExternalLabel(businessObject)) {
position = getExternalLabelMid(element);
modeling.createLabel(element, position, {
id: businessObject.id + '_label',
hidden: !businessObject.name,
businessObject: businessObject
});
}
});
// update di information on label creation
this.executed([ 'label.create' ], function(e) {
var element = e.context.shape,
businessObject,
di;
// we want to trigger on real labels only
if (!element.labelTarget) {
return;
}
// we want to trigger on BPMN elements only
if (!is(element.labelTarget || element, 'bpmn:BaseElement')) {
return;
}
businessObject = element.businessObject,
di = businessObject.di;
if (!di.label) {
di.label = bpmnFactory.create('bpmndi:BPMNLabel', {
bounds: bpmnFactory.create('dc:Bounds')
});
}
assign(di.label.bounds, {
x: element.x,
y: element.y,
width: element.width,
height: element.height
});
});
}
inherits(LabelSupport, CommandInterceptor);
LabelSupport.$inject = [ 'eventBus', 'modeling', 'bpmnFactory' ];
module.exports = LabelSupport;
},{"243":243,"377":377,"69":69,"70":70,"98":98}],30:[function(_dereq_,module,exports){
'use strict';
var is = _dereq_(70).is;
function ModelingFeedback(eventBus, tooltips, translate) {
function showError(position, message) {
tooltips.add({
position: {
x: position.x + 5,
y: position.y + 5
},
type: 'error',
timeout: 2000,
html: '' + message + ''
});
}
eventBus.on([ 'shape.move.rejected', 'create.rejected' ], function(event) {
var context = event.context,
shape = context.shape,
target = context.target;
if (is(target, 'bpmn:Collaboration') && is(shape, 'bpmn:FlowNode')) {
showError(event, translate('flow elements must be children of pools/participants'));
}
});
}
ModelingFeedback.$inject = [ 'eventBus', 'tooltips', 'translate' ];
module.exports = ModelingFeedback;
},{"70":70}],31:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var CommandInterceptor = _dereq_(98);
var is = _dereq_(70).is;
/**
* BPMN specific remove behavior
*/
function RemoveParticipantBehavior(eventBus, modeling) {
CommandInterceptor.call(this, eventBus);
/**
* morph collaboration diagram into process diagram
* after the last participant has been removed
*/
this.preExecute('shape.delete', function(context) {
var shape = context.shape,
parent = shape.parent;
// activate the behavior if the shape to be removed
// is a participant
if (is(shape, 'bpmn:Participant')) {
context.collaborationRoot = parent;
}
}, true);
this.postExecute('shape.delete', function(context) {
var collaborationRoot = context.collaborationRoot;
if (collaborationRoot && !collaborationRoot.businessObject.participants.length) {
// replace empty collaboration with process diagram
modeling.makeProcess();
}
}, true);
}
RemoveParticipantBehavior.$inject = [ 'eventBus', 'modeling' ];
inherits(RemoveParticipantBehavior, CommandInterceptor);
module.exports = RemoveParticipantBehavior;
},{"243":243,"70":70,"98":98}],32:[function(_dereq_,module,exports){
'use strict';
var forEach = _dereq_(255),
find = _dereq_(254),
inherits = _dereq_(243);
var CommandInterceptor = _dereq_(98);
var is = _dereq_(70).is;
function ReplaceConnectionBehavior(eventBus, modeling, bpmnRules) {
CommandInterceptor.call(this, eventBus);
function fixConnection(connection) {
var source = connection.source,
target = connection.target,
parent = connection.parent;
// do not do anything if connection
// is already deleted (may happen due to other
// behaviors plugged-in before)
if (!parent) {
return;
}
var replacementType,
remove;
/**
* Check if incoming or outgoing connections
* can stay or could be substituted with an
* appropriate replacement.
*
* This holds true for SequenceFlow <> MessageFlow.
*/
if (is(connection, 'bpmn:SequenceFlow')) {
if (!bpmnRules.canConnectSequenceFlow(source, target)) {
remove = true;
}
if (bpmnRules.canConnectMessageFlow(source, target)) {
replacementType = 'bpmn:MessageFlow';
}
}
// transform message flows into sequence flows, if possible
if (is(connection, 'bpmn:MessageFlow')) {
if (!bpmnRules.canConnectMessageFlow(source, target)) {
remove = true;
}
if (bpmnRules.canConnectSequenceFlow(source, target)) {
replacementType = 'bpmn:SequenceFlow';
}
}
if (is(connection, 'bpmn:Association') && !bpmnRules.canConnectAssociation(source, target)) {
remove = true;
}
// remove invalid connection,
// unless it has been removed already
if (remove) {
modeling.removeConnection(connection);
}
// replace SequenceFlow <> MessageFlow
if (replacementType) {
modeling.connect(source, target, {
type: replacementType,
waypoints: connection.waypoints.slice()
});
}
}
this.postExecuted('elements.move', function(context) {
var closure = context.closure,
allConnections = closure.allConnections;
forEach(allConnections, fixConnection);
}, true);
this.postExecuted([
'connection.reconnectStart',
'connection.reconnectEnd'
], function(event){
var connection = event.context.connection;
fixConnection(connection);
});
this.postExecuted('element.updateProperties', function(event) {
var context = event.context,
properties = context.properties,
element = context.element,
businessObject = element.businessObject,
connection;
// remove condition expression when morphing to default flow
if (properties.default) {
connection = find(element.outgoing, { id: element.businessObject.default.id });
if (connection) {
modeling.updateProperties(connection, { conditionExpression: undefined });
}
}
// remove default property from source when morphing to conditional flow
if (properties.conditionExpression && businessObject.sourceRef.default === businessObject) {
modeling.updateProperties(element.source, { default: undefined });
}
});
}
inherits(ReplaceConnectionBehavior, CommandInterceptor);
ReplaceConnectionBehavior.$inject = [ 'eventBus', 'modeling', 'bpmnRules' ];
module.exports = ReplaceConnectionBehavior;
},{"243":243,"254":254,"255":255,"70":70,"98":98}],33:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var CommandInterceptor = _dereq_(98);
var forEach = _dereq_(255);
var isEventSubProcess = _dereq_(68).isEventSubProcess;
var is = _dereq_(70).is;
/**
* Defines the behaviour of what happens to the elements inside a container
* that morphs into another BPMN element
*/
function ReplaceElementBehaviour(eventBus, bpmnReplace, bpmnRules, elementRegistry, selection, modeling) {
CommandInterceptor.call(this, eventBus);
this._bpmnReplace = bpmnReplace;
this._elementRegistry = elementRegistry;
this._selection = selection;
this._modeling = modeling;
this.postExecuted([ 'elements.move' ], 500, function(event) {
var context = event.context,
target = context.newParent,
newHost = context.newHost,
elements = [];
forEach(context.closure.topLevel, function(topLevelElements) {
if (isEventSubProcess(topLevelElements)) {
elements = elements.concat(topLevelElements.children);
} else {
elements = elements.concat(topLevelElements);
}
});
// Change target to host when the moving element is a `bpmn:BoundaryEvent`
if (elements.length === 1 && newHost) {
target = newHost;
}
var canReplace = bpmnRules.canReplace(elements, target);
if (canReplace) {
this.replaceElements(elements, canReplace.replacements, newHost);
}
}, this);
// update attachments if the host is replaced
this.postExecute([ 'shape.replace' ], 1500, function(e) {
var context = e.context,
oldShape = context.oldShape,
newShape = context.newShape,
attachers = oldShape.attachers,
canReplace;
if (attachers && attachers.length) {
canReplace = bpmnRules.canReplace(attachers, newShape);
this.replaceElements(attachers, canReplace.replacements);
}
}, this);
}
inherits(ReplaceElementBehaviour, CommandInterceptor);
ReplaceElementBehaviour.prototype.replaceElements = function(elements, newElements, newHost) {
var elementRegistry = this._elementRegistry,
bpmnReplace = this._bpmnReplace,
selection = this._selection,
modeling = this._modeling;
forEach(newElements, function(replacement) {
var newElement = {
type: replacement.newElementType
};
var oldElement = elementRegistry.get(replacement.oldElementId);
if (newHost && is(oldElement, 'bpmn:BoundaryEvent')) {
modeling.updateAttachment(oldElement, null);
}
var idx = elements.indexOf(oldElement);
elements[idx] = bpmnReplace.replaceElement(oldElement, newElement, { select: false });
if (newHost && is(elements[idx], 'bpmn:BoundaryEvent')) {
modeling.updateAttachment(elements[idx], newHost);
}
});
if (newElements) {
selection.select(elements);
}
};
ReplaceElementBehaviour.$inject = [ 'eventBus', 'bpmnReplace', 'bpmnRules', 'elementRegistry',
'selection', 'modeling' ];
module.exports = ReplaceElementBehaviour;
},{"243":243,"255":255,"68":68,"70":70,"98":98}],34:[function(_dereq_,module,exports){
'use strict';
var is = _dereq_(70).is;
var roundBounds = _dereq_(208).roundBounds;
var hasPrimaryModifier = _dereq_(228).hasPrimaryModifier;
var SLIGHTLY_HIGHER_PRIORITY = 1001;
/**
* Invoke {@link Modeling#resizeLane} instead of
* {@link Modeling#resizeShape} when resizing a Lane
* or Participant shape.
*/
function ResizeLaneBehavior(eventBus, modeling) {
eventBus.on('resize.start', SLIGHTLY_HIGHER_PRIORITY + 500, function(event) {
var context = event.context,
shape = context.shape;
if (is(shape, 'bpmn:Lane') || is(shape, 'bpmn:Participant')) {
// should we resize the opposite lane(s) in
// order to compensate for the resize operation?
context.balanced = !hasPrimaryModifier(event);
}
});
/**
* Intercept resize end and call resize lane function instead.
*/
eventBus.on('resize.end', SLIGHTLY_HIGHER_PRIORITY, function(event) {
var context = event.context,
shape = context.shape,
canExecute = context.canExecute,
newBounds = context.newBounds;
if (is(shape, 'bpmn:Lane') || is(shape, 'bpmn:Participant')) {
if (canExecute) {
// ensure we have actual pixel values for new bounds
// (important when zoom level was > 1 during move)
newBounds = roundBounds(newBounds);
// perform the actual resize
modeling.resizeLane(shape, newBounds, context.balanced);
}
// stop propagation
return false;
}
});
}
ResizeLaneBehavior.$inject = [ 'eventBus', 'modeling' ];
module.exports = ResizeLaneBehavior;
},{"208":208,"228":228,"70":70}],35:[function(_dereq_,module,exports){
'use strict';
var inherits = _dereq_(243);
var CommandInterceptor = _dereq_(98);
var is = _dereq_(70).is;
var LOW_PRIORITY = 500,
HIGH_PRIORITY = 5000;
/**
* BPMN specific delete lane behavior
*/
function UpdateFlowNodeRefsBehavior(eventBus, modeling, translate) {
CommandInterceptor.call(this, eventBus);
/**
* Ok, this is it:
*
* We have to update the Lane#flowNodeRefs _and_
* FlowNode#lanes with every FlowNode move/resize and
* Lane move/resize.
*
* We want to group that stuff to recompute containments
* as efficient as possible.
*
* Yea!
*/
// the update context
var context;
function initContext() {
context = context || new UpdateContext();
context.enter();
return context;
}
function getContext() {
if (!context) {
throw new Error(translate('out of bounds release'));
}
return context;
}
function releaseContext() {
if (!context) {
throw new Error(translate('out of bounds release'));
}
var triggerUpdate = context.leave();
if (triggerUpdate) {
modeling.updateLaneRefs(context.flowNodes, context.lanes);
context = null;
}
return triggerUpdate;
}
var laneRefUpdateEvents = [
'spaceTool',
'lane.add',
'lane.resize',
'lane.split',
'elements.move',
'elements.delete',
'shape.create',
'shape.delete',
'shape.move',
'shape.resize'
];
// listen to a lot of stuff to group lane updates
this.preExecute(laneRefUpdateEvents, HIGH_PRIORITY, function(event) {
initContext();
});
this.postExecuted(laneRefUpdateEvents, LOW_PRIORITY, function(event) {
releaseContext();
});
// Mark flow nodes + lanes that need an update
this.preExecute([
'shape.create',
'shape.move',
'shape.delete',
'shape.resize'
], function(event) {
var context = event.context,
shape = context.shape;
var updateContext = getContext();
// no need to update labels
if (shape.labelTarget) {
return;
}
if (is(shape, 'bpmn:Lane')) {
updateContext.addLane(shape);
}
if (is(shape, 'bpmn:FlowNode')) {
updateContext.addFlowNode(shape);
}
});
}
UpdateFlowNodeRefsBehavior.$inject = [ 'eventBus', 'modeling' , 'translate'];
inherits(UpdateFlowNodeRefsBehavior, CommandInterceptor);
module.exports = UpdateFlowNodeRefsBehavior;
function UpdateContext() {
this.flowNodes = [];
this.lanes = [];
this.counter = 0;
this.addLane = function(lane) {
this.lanes.push(lane);
};
this.addFlowNode = function(flowNode) {
this.flowNodes.push(flowNode);
};
this.enter = function() {
this.counter++;
};
this.leave = function() {
this.counter--;
return !this.counter;
};
}
},{"243":243,"70":70,"98":98}],36:[function(_dereq_,module,exports){
module.exports = {
__init__: [
'appendBehavior',
'createBoundaryEventBehavior',
'createDataObjectBehavior',
'createOnFlowBehavior',
'createParticipantBehavior',
'dataInputAssociationBehavior',
'deleteLaneBehavior',
'labelBehavior',
'modelingFeedback',
'removeParticipantBehavior',
'replaceConnectionBehavior',
'replaceElementBehaviour',
'resizeLaneBehavior',
'updateFlowNodeRefsBehavior'
],
appendBehavior: [ 'type', _dereq_(22) ],
createBoundaryEventBehavior: [ 'type', _dereq_(23) ],
createDataObjectBehavior: [ 'type', _dereq_(24) ],
createOnFlowBehavior: [ 'type', _dereq_(25) ],
createParticipantBehavior: [ 'type', _dereq_(26) ],
dataInputAssociationBehavior: [ 'type', _dereq_(27) ],
deleteLaneBehavior: [ 'type', _dereq_(28) ],
labelBehavior: [ 'type', _dereq_(29) ],
modelingFeedback: [ 'type', _dereq_(30) ],
removeParticipantBehavior: [ 'type', _dereq_(31) ],
replaceConnectionBehavior: [ 'type', _dereq_(32) ],
replaceElementBehaviour: [ 'type', _dereq_(33) ],
resizeLaneBehavior: [ 'type', _dereq_(34) ],
updateFlowNodeRefsBehavior: [ 'type', _dereq_(35) ]
};
},{"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35}],37:[function(_dereq_,module,exports){
'use strict';
var filter = _dereq_(253);
var Elements = _dereq_(221);
var getLanesRoot = _dereq_(44).getLanesRoot,
getChildLanes = _dereq_(44).getChildLanes,
LANE_INDENTATION = _dereq_(44).LANE_INDENTATION;
/**
* A handler that allows us to add a new lane
* above or below an existing one.
*
* @param {Modeling} modeling
*/
function AddLaneHandler(modeling, spaceTool) {
this._modeling = modeling;
this._spaceTool = spaceTool;
}
AddLaneHandler.$inject = [ 'modeling', 'spaceTool' ];
module.exports = AddLaneHandler;
AddLaneHandler.prototype.preExecute = function(context) {
var spaceTool = this._spaceTool,
modeling = this._modeling;
var shape = context.shape,
location = context.location;
var lanesRoot = getLanesRoot(shape);
var isRoot = lanesRoot === shape,
laneParent = isRoot ? shape : shape.parent;
var existingChildLanes = getChildLanes(laneParent);
// (0) add a lane if we currently got none and are adding to root
if (!existingChildLanes.length) {
modeling.createShape({ type: 'bpmn:Lane' }, {
x: shape.x + LANE_INDENTATION,
y: shape.y,
width: shape.width - LANE_INDENTATION,
height: shape.height
}, laneParent);
}
// (1) collect affected elements to create necessary space
var allAffected = [];
Elements.eachElement(lanesRoot, function(element) {
allAffected.push(element);
if (element === shape) {
return [];
}
return filter(element.children, function(c) {
return c !== shape;
});
});
var offset = location === 'top' ? -120 : 120,
lanePosition = location === 'top' ? shape.y : shape.y + shape.height,
spacePos = lanePosition + (location === 'top' ? 10 : -10),
direction = location === 'top' ? 'n' : 's';
var adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos);
spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: 0, y: offset }, direction);
// (2) create new lane at open space
context.newLane = modeling.createShape({ type: 'bpmn:Lane' }, {
x: shape.x + (isRoot ? LANE_INDENTATION : 0),
y: lanePosition - (location === 'top' ? 120 : 0),
width: shape.width - (isRoot ? LANE_INDENTATION : 0),
height: 120
}, laneParent);
};
},{"221":221,"253":253,"44":44}],38:[function(_dereq_,module,exports){
'use strict';
var is = _dereq_(70).is;
var getLanesRoot = _dereq_(44).getLanesRoot,
computeLanesResize = _dereq_(44).computeLanesResize;
var eachElement = _dereq_(221).eachElement;
var asTRBL = _dereq_(208).asTRBL,
substractTRBL = _dereq_(180).substractTRBL;
/**
* A handler that resizes a lane.
*
* @param {Modeling} modeling
*/
function ResizeLaneHandler(modeling, spaceTool) {
this._modeling = modeling;
this._spaceTool = spaceTool;
}
ResizeLaneHandler.$inject = [ 'modeling', 'spaceTool' ];
module.exports = ResizeLaneHandler;
ResizeLaneHandler.prototype.preExecute = function(context) {
var shape = context.shape,
newBounds = context.newBounds,
balanced = context.balanced;
if (balanced !== false) {
this.resizeBalanced(shape, newBounds);
} else {
this.resizeSpace(shape, newBounds);
}
};
/**
* Resize balanced, adjusting next / previous lane sizes.
*
* @param {djs.model.Shape} shape
* @param {Bounds} newBounds
*/
ResizeLaneHandler.prototype.resizeBalanced = function(shape, newBounds) {
var modeling = this._modeling;
var resizeNeeded = computeLanesResize(shape, newBounds);
// resize the lane
modeling.resizeShape(shape, newBounds);
// resize other lanes as needed
resizeNeeded.forEach(function(r) {
modeling.resizeShape(r.shape, r.newBounds);
});
};
/**
* Resize, making actual space and moving below / above elements.
*
* @param {djs.model.Shape} shape
* @param {Bounds} newBounds
*/
ResizeLaneHandler.prototype.resizeSpace = function(shape, newBounds) {
var spaceTool = this._spaceTool;
var shapeTrbl = asTRBL(shape),
newTrbl = asTRBL(newBounds);
var trblDiff = substractTRBL(newTrbl, shapeTrbl);
var lanesRoot = getLanesRoot(shape);
var allAffected = [],
allLanes = [];
eachElement(lanesRoot, function(element) {
allAffected.push(element);
if (is(element, 'bpmn:Lane') || is(element, 'bpmn:Participant')) {
allLanes.push(element);
}
return element.children;
});
var change,
spacePos,
direction,
offset,
adjustments;
if (trblDiff.bottom || trblDiff.top) {
change = trblDiff.bottom || trblDiff.top;
spacePos = shape.y + (trblDiff.bottom ? shape.height : 0) + (trblDiff.bottom ? -10 : 10);
direction = trblDiff.bottom ? 's' : 'n';
offset = trblDiff.top > 0 || trblDiff.bottom < 0 ? -change : change;
adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos);
spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: 0, y: change }, direction);
}
if (trblDiff.left || trblDiff.right) {
change = trblDiff.right || trblDiff.left;
spacePos = shape.x + (trblDiff.right ? shape.width : 0) + (trblDiff.right ? -10 : 100);
direction = trblDiff.right ? 'e' : 'w';
offset = trblDiff.left > 0 || trblDiff.right < 0 ? -change : change;
adjustments = spaceTool.calculateAdjustments(allLanes, 'x', offset, spacePos);
spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: change, y: 0 }, direction);
}
};
},{"180":180,"208":208,"221":221,"44":44,"70":70}],39:[function(_dereq_,module,exports){
'use strict';
var getChildLanes = _dereq_(44).getChildLanes;
var LANE_INDENTATION = _dereq_(44).LANE_INDENTATION;
/**
* A handler that splits a lane into a number of sub-lanes,
* creating new sub lanes, if neccessary.
*
* @param {Modeling} modeling
*/
function SplitLaneHandler(modeling, translate) {
this._modeling = modeling;
this._translate = translate;
}
SplitLaneHandler.$inject = [ 'modeling', 'translate'];
module.exports = SplitLaneHandler;
SplitLaneHandler.prototype.preExecute = function(context) {
var modeling = this._modeling,
translate = this._translate;
var shape = context.shape,
newLanesCount = context.count;
var childLanes = getChildLanes(shape),
existingLanesCount = childLanes.length;
if (existingLanesCount > newLanesCount) {
throw new Error(translate('more than {count} child lanes', { count: newLanesCount }));
}
var newLanesHeight = Math.round(shape.height / newLanesCount);
// Iterate from top to bottom in child lane order,
// resizing existing lanes and creating new ones
// so that they split the parent proportionally.
//
// Due to rounding related errors, the bottom lane
// needs to take up all the remaining space.
var laneY,
laneHeight,
laneBounds,
newLaneAttrs,
idx;
for (idx = 0; idx < newLanesCount; idx++) {
laneY = shape.y + idx * newLanesHeight;
// if bottom lane
if (idx === newLanesCount - 1) {
laneHeight = shape.height - (newLanesHeight * idx);
} else {
laneHeight = newLanesHeight;
}
laneBounds = {
x: shape.x + LANE_INDENTATION,
y: laneY,
width: shape.width - LANE_INDENTATION,
height: laneHeight
};
if (idx < existingLanesCount) {
// resize existing lane
modeling.resizeShape(childLanes[idx], laneBounds);
} else {
// create a new lane at position
newLaneAttrs = {
type: 'bpmn:Lane'
};
modeling.createShape(newLaneAttrs, laneBounds, shape);
}
}
};
},{"44":44}],40:[function(_dereq_,module,exports){
'use strict';
var Collections = _dereq_(219);
function UpdateCanvasRootHandler(canvas, modeling) {
this._canvas = canvas;
this._modeling = modeling;
}
UpdateCanvasRootHandler.$inject = [ 'canvas', 'modeling' ];
module.exports = UpdateCanvasRootHandler;
UpdateCanvasRootHandler.prototype.execute = function(context) {
var canvas = this._canvas;
var newRoot = context.newRoot,
newRootBusinessObject = newRoot.businessObject,
oldRoot = canvas.getRootElement(),
oldRootBusinessObject = oldRoot.businessObject,
bpmnDefinitions = oldRootBusinessObject.$parent,
diPlane = oldRootBusinessObject.di;
// (1) replace process old <> new root
canvas.setRootElement(newRoot, true);
// (2) update root elements
Collections.add(bpmnDefinitions.rootElements, newRootBusinessObject);
newRootBusinessObject.$parent = bpmnDefinitions;
Collections.remove(bpmnDefinitions.rootElements, oldRootBusinessObject);
oldRootBusinessObject.$parent = null;
// (3) wire di
oldRootBusinessObject.di = null;
diPlane.bpmnElement = newRootBusinessObject;
newRootBusinessObject.di = diPlane;
context.oldRoot = oldRoot;
// TODO(nikku): return changed elements?
// return [ newRoot, oldRoot ];
};
UpdateCanvasRootHandler.prototype.revert = function(context) {
var canvas = this._canvas;
var newRoot = context.newRoot,
newRootBusinessObject = newRoot.businessObject,
oldRoot = context.oldRoot,
oldRootBusinessObject = oldRoot.businessObject,
bpmnDefinitions = newRootBusinessObject.$parent,
diPlane = newRootBusinessObject.di;
// (1) replace process old <> new root
canvas.setRootElement(oldRoot, true);
// (2) update root elements
Collections.remove(bpmnDefinitions.rootElements, newRootBusinessObject);
newRootBusinessObject.$parent = null;
Collections.add(bpmnDefinitions.rootElements, oldRootBusinessObject);
oldRootBusinessObject.$parent = bpmnDefinitions;
// (3) wire di
newRootBusinessObject.di = null;
diPlane.bpmnElement = oldRootBusinessObject;
oldRootBusinessObject.di = diPlane;
// TODO(nikku): return changed elements?
// return [ newRoot, oldRoot ];
};
},{"219":219}],41:[function(_dereq_,module,exports){
'use strict';
var collectLanes = _dereq_(44).collectLanes;
var getLanesRoot = _dereq_(44).getLanesRoot;
var is = _dereq_(70).is;
var Collections = _dereq_(219);
var asTRBL = _dereq_(208).asTRBL;
var FLOW_NODE_REFS_ATTR = 'flowNodeRef',
LANES_ATTR = 'lanes';
/**
* A handler that updates lane refs on changed elements
*/
function UpdateFlowNodeRefsHandler(elementRegistry) {
this._elementRegistry = elementRegistry;
}
UpdateFlowNodeRefsHandler.$inject = [ 'elementRegistry' ];
module.exports = UpdateFlowNodeRefsHandler;
UpdateFlowNodeRefsHandler.prototype.computeUpdates = function(flowNodeShapes, laneShapes) {
var handledNodes = {};
var updates = [];
var participantCache = {};
var allFlowNodeShapes = [];
function isInLaneShape(element, laneShape) {
var laneTrbl = asTRBL(laneShape);
var elementMid = {
x: element.x + element.width / 2,
y: element.y + element.height / 2
};
return elementMid.x > laneTrbl.left &&
elementMid.x < laneTrbl.right &&
elementMid.y > laneTrbl.top &&
elementMid.y < laneTrbl.bottom;
}
function addFlowNodeShape(flowNodeShape) {
if (!handledNodes[flowNodeShape.id]) {
allFlowNodeShapes.push(flowNodeShape);
handledNodes[flowNodeShape.id] = flowNodeShape;
}
}
function getAllLaneShapes(flowNodeShape) {
var root = getLanesRoot(flowNodeShape);
if (!participantCache[root.id]) {
participantCache[root.id] = collectLanes(root);
}
return participantCache[root.id];
}
function getNewLanes(flowNodeShape) {
if (!flowNodeShape.parent) {
return [];
}
var allLaneShapes = getAllLaneShapes(flowNodeShape);
return allLaneShapes.filter(function(l) {
return isInLaneShape(flowNodeShape, l);
}).map(function(shape) {
return shape.businessObject;
});
}
laneShapes.forEach(function(laneShape) {
var root = getLanesRoot(laneShape);
if (!root || handledNodes[root.id]) {
return;
}
var children = root.children.filter(function(c) {
return is(c, 'bpmn:FlowNode');
});
children.forEach(addFlowNodeShape);
handledNodes[root.id] = root;
});
flowNodeShapes.forEach(addFlowNodeShape);
allFlowNodeShapes.forEach(function(flowNodeShape) {
var flowNode = flowNodeShape.businessObject;
var lanes = flowNode.get(LANES_ATTR),
remove = lanes.slice(),
add = getNewLanes(flowNodeShape);
updates.push({ flowNode: flowNode, remove: remove, add: add });
});
laneShapes.forEach(function(laneShape) {
var lane = laneShape.businessObject;
// lane got removed XX-)
if (!laneShape.parent) {
lane.get(FLOW_NODE_REFS_ATTR).forEach(function(flowNode) {
updates.push({ flowNode: flowNode, remove: [ lane ], add: [] });
});
}
});
return updates;
};
UpdateFlowNodeRefsHandler.prototype.execute = function(context) {
var updates = context.updates;
if (!updates) {
updates = context.updates = this.computeUpdates(context.flowNodeShapes, context.laneShapes);
}
updates.forEach(function(update) {
var flowNode = update.flowNode,
lanes = flowNode.get(LANES_ATTR);
// unwire old
update.remove.forEach(function(oldLane) {
Collections.remove(lanes, oldLane);
Collections.remove(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode);
});
// wire new
update.add.forEach(function(newLane) {
Collections.add(lanes, newLane);
Collections.add(newLane.get(FLOW_NODE_REFS_ATTR), flowNode);
});
});
// TODO(nikku): return changed elements
// return [ ... ];
};
UpdateFlowNodeRefsHandler.prototype.revert = function(context) {
var updates = context.updates;
updates.forEach(function(update) {
var flowNode = update.flowNode,
lanes = flowNode.get(LANES_ATTR);
// unwire new
update.add.forEach(function(newLane) {
Collections.remove(lanes, newLane);
Collections.remove(newLane.get(FLOW_NODE_REFS_ATTR), flowNode);
});
// wire old
update.remove.forEach(function(oldLane) {
Collections.add(lanes, oldLane);
Collections.add(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode);
});
});
// TODO(nikku): return changed elements
// return [ ... ];
};
},{"208":208,"219":219,"44":44,"70":70}],42:[function(_dereq_,module,exports){
'use strict';
var reduce = _dereq_(384),
keys = _dereq_(378),
forEach = _dereq_(255),
assign = _dereq_(377);
var getBusinessObject = _dereq_(70).getBusinessObject;
var DEFAULT_FLOW = 'default',
NAME = 'name',
ID = 'id';
/**
* A handler that implements a BPMN 2.0 property update.
*
* This should be used to set simple properties on elements with
* an underlying BPMN business object.
*
* Use respective diagram-js provided handlers if you would
* like to perform automated modeling.
*/
function UpdatePropertiesHandler(elementRegistry, moddle, translate) {
this._elementRegistry = elementRegistry;
this._moddle = moddle;
this._translate = translate;
}
UpdatePropertiesHandler.$inject = [ 'elementRegistry', 'moddle', 'translate' ];
module.exports = UpdatePropertiesHandler;
////// api /////////////////////////////////////////////
/**
* Updates a BPMN element with a list of new properties
*
* @param {Object} context
* @param {djs.model.Base} context.element the element to update
* @param {Object} context.properties a list of properties to set on the element's
* businessObject (the BPMN model element)
*
* @return {Array} the updated element
*/
UpdatePropertiesHandler.prototype.execute = function(context) {
var element = context.element,
changed = [ element],
translate = this._translate;
if (!element) {
throw new Error(translate('element required'));
}
var elementRegistry = this._elementRegistry,
ids = this._moddle.ids;
var businessObject = element.businessObject,
properties = unwrapBusinessObjects(context.properties),
oldProperties = context.oldProperties || getProperties(businessObject, keys(properties));
if (isIdChange(properties, businessObject)) {
ids.unclaim(businessObject[ID]);
elementRegistry.updateId(element, properties[ID]);
}
// correctly indicate visual changes on default flow updates
if (DEFAULT_FLOW in properties) {
if (properties[DEFAULT_FLOW]) {
changed.push(elementRegistry.get(properties[DEFAULT_FLOW].id));
}
if (businessObject[DEFAULT_FLOW]) {
changed.push(elementRegistry.get(businessObject[DEFAULT_FLOW].id));
}
}
if (NAME in properties && element.label) {
changed.push(element.label);
// show the label
element.label.hidden = !properties[NAME];
}
// update properties
setProperties(businessObject, properties);
// store old values
context.oldProperties = oldProperties;
context.changed = changed;
// indicate changed on objects affected by the update
return changed;
};
/**
* Reverts the update on a BPMN elements properties.
*
* @param {Object} context
*
* @return {djs.mode.Base} the updated element
*/
UpdatePropertiesHandler.prototype.revert = function(context) {
var element = context.element,
properties = context.properties,
oldProperties = context.oldProperties,
businessObject = element.businessObject,
elementRegistry = this._elementRegistry,
ids = this._moddle.ids;
// update properties
setProperties(businessObject, oldProperties);
if (isIdChange(properties, businessObject)) {
ids.unclaim(properties[ID]);
elementRegistry.updateId(element, oldProperties[ID]);
}
return context.changed;
};
function isIdChange(properties, businessObject) {
return ID in properties && properties[ID] !== businessObject[ID];
}
function getProperties(businessObject, propertyNames) {
return reduce(propertyNames, function(result, key) {
result[key] = businessObject.get(key);
return result;
}, {});
}
function setProperties(businessObject, properties) {
forEach(properties, function(value, key) {
businessObject.set(key, value);
});
}
var referencePropertyNames = [ 'default' ];
/**
* Make sure we unwrap the actual business object
* behind diagram element that may have been
* passed as arguments.
*
* @param {Object} properties
*
* @return {Object} unwrappedProps
*/
function unwrapBusinessObjects(properties) {
var unwrappedProps = assign({}, properties);
referencePropertyNames.forEach(function(name) {
if (name in properties) {
unwrappedProps[name] = getBusinessObject(unwrappedProps[name]);
}
});
return unwrappedProps;
}
},{"255":255,"377":377,"378":378,"384":384,"70":70}],43:[function(_dereq_,module,exports){
module.exports = {
__init__: [ 'modeling', 'bpmnUpdater' ],
__depends__: [
_dereq_(36),
_dereq_(16),
_dereq_(59),
_dereq_(47),
_dereq_(57),
_dereq_(100),
_dereq_(200),
_dereq_(139),
_dereq_(112),
_dereq_(189),
_dereq_(120),
_dereq_(196)
],
bpmnFactory: [ 'type', _dereq_(17) ],
bpmnUpdater: [ 'type', _dereq_(19) ],
elementFactory: [ 'type', _dereq_(20) ],
modeling: [ 'type', _dereq_(21) ],
layouter: [ 'type', _dereq_(18) ],
connectionDocking: [ 'type', _dereq_(207) ]
};
},{"100":100,"112":112,"120":120,"139":139,"16":16,"17":17,"18":18,"189":189,"19":19,"196":196,"20":20,"200":200,"207":207,"21":21,"36":36,"47":47,"57":57,"59":59}],44:[function(_dereq_,module,exports){
'use strict';
var is = _dereq_(70).is;
var getParent = _dereq_(45).getParent;
var asTRBL = _dereq_(208).asTRBL,
substractTRBL = _dereq_(180).substractTRBL,
resizeTRBL = _dereq_(180).resizeTRBL;
var abs = Math.abs;
function getTRBLResize(oldBounds, newBounds) {
return substractTRBL(asTRBL(newBounds), asTRBL(oldBounds));
}
var LANE_PARENTS = [
'bpmn:Participant',
'bpmn:Process',
'bpmn:SubProcess'
];
var LANE_INDENTATION = 30;
module.exports.LANE_INDENTATION = LANE_INDENTATION;
/**
* Collect all lane shapes in the given paren
*
* @param {djs.model.Shape} shape
* @param {Array} [collectedShapes]
*
* @return {Array}
*/
function collectLanes(shape, collectedShapes) {
collectedShapes = collectedShapes || [];
shape.children.filter(function(s) {
if (is(s, 'bpmn:Lane')) {
collectLanes(s, collectedShapes);
collectedShapes.push(s);
}
});
return collectedShapes;
}
module.exports.collectLanes = collectLanes;
/**
* Return the lane children of the given element.
*
* @param {djs.model.Shape} shape
*
* @return {Array}
*/
function getChildLanes(shape) {
return shape.children.filter(function(c) {
return is(c, 'bpmn:Lane');
});
}
module.exports.getChildLanes = getChildLanes;
/**
* Return the root element containing the given lane shape
*
* @param {djs.model.Shape} shape
*
* @return {djs.model.Shape}
*/
function getLanesRoot(shape) {
return getParent(shape, LANE_PARENTS) || shape;
}
module.exports.getLanesRoot = getLanesRoot;
/**
* Compute the required resize operations for lanes
* adjacent to the given shape, assuming it will be
* resized to the given new bounds.
*
* @param {djs.model.Shape} shape
* @param {Bounds} newBounds
*
* @return {Array