123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- import {
- reduce,
- keys,
- forEach,
- assign
- } from 'min-dash';
- import {
- getBusinessObject
- } from '../../../util/ModelUtil';
- var DEFAULT_FLOW = 'default',
- ID = 'id',
- DI = 'di';
- var NULL_DIMENSIONS = {
- width: 0,
- height: 0
- };
- /**
- * 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.
- */
- export default function UpdatePropertiesHandler(
- elementRegistry, moddle, translate,
- modeling, textRenderer) {
- this._elementRegistry = elementRegistry;
- this._moddle = moddle;
- this._translate = translate;
- this._modeling = modeling;
- this._textRenderer = textRenderer;
- }
- UpdatePropertiesHandler.$inject = [
- 'elementRegistry',
- 'moddle',
- 'translate',
- 'modeling',
- 'textRenderer'
- ];
- // 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<djs.model.Base>} 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, properties);
- if (isIdChange(properties, businessObject)) {
- ids.unclaim(businessObject[ID]);
- elementRegistry.updateId(element, properties[ID]);
- ids.claim(properties[ID], businessObject);
- }
- // 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));
- }
- }
- // update properties
- setProperties(businessObject, properties);
- // store old values
- context.oldProperties = oldProperties;
- context.changed = changed;
- // indicate changed on objects affected by the update
- return changed;
- };
- UpdatePropertiesHandler.prototype.postExecute = function(context) {
- var element = context.element,
- label = element.label;
- var text = label && getBusinessObject(label).name;
- if (!text) {
- return;
- }
- // get layouted text bounds and resize external
- // external label accordingly
- var newLabelBounds = this._textRenderer.getExternalLabelBounds(label, text);
- this._modeling.resizeShape(label, newLabelBounds, NULL_DIMENSIONS);
- };
- /**
- * Reverts the update on a BPMN elements properties.
- *
- * @param {Object} context
- *
- * @return {djs.model.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]);
- ids.claim(oldProperties[ID], businessObject);
- }
- return context.changed;
- };
- function isIdChange(properties, businessObject) {
- return ID in properties && properties[ID] !== businessObject[ID];
- }
- function getProperties(businessObject, properties) {
- var propertyNames = keys(properties);
- return reduce(propertyNames, function(result, key) {
- // handle DI separately
- if (key !== DI) {
- result[key] = businessObject.get(key);
- } else {
- result[key] = getDiProperties(businessObject.di, keys(properties.di));
- }
- return result;
- }, {});
- }
- function getDiProperties(di, propertyNames) {
- return reduce(propertyNames, function(result, key) {
- result[key] = di.get(key);
- return result;
- }, {});
- }
- function setProperties(businessObject, properties) {
- forEach(properties, function(value, key) {
- if (key !== DI) {
- businessObject.set(key, value);
- } else {
- // only update, if businessObject.di exists
- if (businessObject.di) {
- setDiProperties(businessObject.di, value);
- }
- }
- });
- }
- function setDiProperties(di, properties) {
- forEach(properties, function(value, key) {
- di.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;
- }
|