From 8c619064693a1f6352d0c6b75f19c50a135ec960 Mon Sep 17 00:00:00 2001 From: Nico Rehwaldt Date: Thu, 12 Feb 2015 15:50:23 +0100 Subject: [PATCH] feat(bpmn-js): allow custom model extensions to be passed Related to bpmn-io/bpmn-moddle#15 --- lib/Modeler.js | 5 +- lib/Viewer.js | 6 +- test/fixtures/bpmn/extension/camunda.bpmn | 53 +++++ test/fixtures/json/model/camunda.json | 224 ++++++++++++++++++++++ test/spec/ViewerSpec.js | 49 ++++- 5 files changed, 328 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/bpmn/extension/camunda.bpmn create mode 100644 test/fixtures/json/model/camunda.json diff --git a/lib/Modeler.js b/lib/Modeler.js index 0644a58e..c5aecf9a 100644 --- a/lib/Modeler.js +++ b/lib/Modeler.js @@ -1,7 +1,6 @@ 'use strict'; -var BpmnModdle = require('bpmn-moddle'), - IdSupport = require('bpmn-moddle/lib/id-support'), +var IdSupport = require('bpmn-moddle/lib/id-support'), Ids = require('ids'); var Viewer = require('./Viewer'); @@ -44,7 +43,7 @@ Modeler.prototype.createDiagram = function(done) { }; Modeler.prototype.createModdle = function() { - var moddle = new BpmnModdle(); + var moddle = Viewer.prototype.createModdle.call(this); IdSupport.extend(moddle, new Ids([ 32, 36, 1 ])); diff --git a/lib/Viewer.js b/lib/Viewer.js index 6c55ead7..7ec20c07 100644 --- a/lib/Viewer.js +++ b/lib/Viewer.js @@ -67,6 +67,7 @@ function ensureUnit(val) { * @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 */ @@ -128,7 +129,7 @@ Viewer.prototype.importXML = function(xml, done) { var self = this; - this.moddle = this.createModdle(); + this.moddle = this.moddle || this.createModdle(); this.moddle.fromXML(xml, 'bpmn:Definitions', function(err, definitions) { @@ -158,7 +159,8 @@ Viewer.prototype.saveXML = function(options, done) { }; Viewer.prototype.createModdle = function() { - return new BpmnModdle(); + var options = this.options; + return options.moddle || new BpmnModdle(options.moddleExtensions); }; Viewer.prototype.saveSVG = function(options, done) { diff --git a/test/fixtures/bpmn/extension/camunda.bpmn b/test/fixtures/bpmn/extension/camunda.bpmn new file mode 100644 index 00000000..5aea651a --- /dev/null +++ b/test/fixtures/bpmn/extension/camunda.bpmn @@ -0,0 +1,53 @@ + + + + + SequenceFlow_1 + + + + + + + + + stringInListNestedInMap + ${ 'b' } + + + + + stringConstantValue + + + SequenceFlow_1 + SequenceFlow_2 + + + + SequenceFlow_2 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/fixtures/json/model/camunda.json b/test/fixtures/json/model/camunda.json new file mode 100644 index 00000000..7f47530e --- /dev/null +++ b/test/fixtures/json/model/camunda.json @@ -0,0 +1,224 @@ +{ + "name": "Camunda", + "uri": "http://activiti.org/bpmn", + "prefix": "camunda", + "xml": { + "tagAlias": "lowerCase" + }, + "associations": [], + "types": [ + { + "name": "AsyncCapable", + "isAbstract": true, + "extends": [ + "bpmn:Activity", + "bpmn:Gateway", + "bpmn:Event" + ], + "properties": [ + { + "name": "asyncBefore", + "isAttr": true, + "type": "Boolean", + "default": false + }, + { + "name": "asyncAfter", + "isAttr": true, + "type": "Boolean", + "default": false + } + ] + }, + { + "name": "Assignable", + "extends": [ "bpmn:UserTask" ], + "properties": [ + { + "name": "assignee", + "isAttr": true, + "type": "String" + } + ] + }, + { + "name": "Calling", + "extends": [ "bpmn:CallActivity" ], + "properties": [ + { + "name": "calledElementBinding", + "isAttr": true, + "type": "String" + }, + { + "name": "calledElementVersion", + "isAttr": true, + "type": "Integer" + } + ] + }, + { + "name": "ServiceTaskLike", + "extends": [ + "bpmn:ServiceTask", + "bpmn:BusinessRuleTask", + "bpmn:SendTask", + "bpmn:MessageEventDefinition" + ], + "properties": [ + { + "name": "expression", + "isAttr": true, + "type": "String" + }, + { + "name": "javaDelegate", + "isAttr": true, + "type": "String" + }, + { + "name": "delegateExpression", + "isAttr": true, + "type": "String" + } + ] + }, + { + "name": "Connector", + "superClass": [ + "Element" + ], + "properties": [ + { + "name": "inputOutput", + "type": "InputOutput" + }, + { + "name": "connectorId", + "type": "String" + } + ] + }, + { + "name": "InputOutput", + "superClass": [ + "Element" + ], + "properties": [ + { + "name": "inputOutput", + "type": "InputOutput" + }, + { + "name": "connectorId", + "type": "String" + }, + { + "name": "inputParameters", + "isMany": true, + "type": "InputParameter" + }, + { + "name": "outputParameters", + "isMany": true, + "type": "OutputParameter" + } + ] + }, + { + "name": "InputOutputParameter", + "properties": [ + { + "name": "name", + "isAttr": true, + "type": "String" + }, + { + "name": "value", + "isBody": true, + "type": "String" + }, + { + "name": "definition", + "type": "InputOutputParameterDefinition" + } + ] + }, + { + "name": "InputOutputParameterDefinition", + "isAbstract": true + }, + { + "name": "List", + "superClass": [ "InputOutputParameterDefinition" ], + "properties": [ + { + "name": "items", + "isMany": true, + "type": "InputOutputParameterDefinition" + } + ] + }, + { + "name": "Map", + "superClass": [ "InputOutputParameterDefinition" ], + "properties": [ + { + "name": "entries", + "isMany": true, + "type": "Entry" + } + ] + }, + { + "name": "Entry", + "properties": [ + { + "name": "key", + "isAttr": true, + "type": "String" + }, + { + "name": "value", + "type": "InputOutputParameterDefinition" + } + ] + }, + { + "name": "Value", + "superClass": [ "InputOutputParameterDefinition" ], + "properties": [ + { + "name": "value", + "isBody": true, + "type": "String" + } + ] + }, + { + "name": "Script", + "superClass": [ "InputOutputParameterDefinition" ], + "properties": [ + { + "name": "scriptLanguage", + "isAttr": true, + "type": "String" + }, + { + "name": "source", + "isBody": true, + "type": "String" + } + ] + }, + { + "name": "InputParameter", + "superClass": [ "InputOutputParameter" ] + }, + { + "name": "OutputParameter", + "superClass": [ "InputOutputParameter" ] + } + ], + "emumerations": [ ] +} \ No newline at end of file diff --git a/test/spec/ViewerSpec.js b/test/spec/ViewerSpec.js index 5f69b0d0..578fee25 100644 --- a/test/spec/ViewerSpec.js +++ b/test/spec/ViewerSpec.js @@ -1,6 +1,7 @@ 'use strict'; -var TestHelper = require('../TestHelper'); +require('../TestHelper'); + var fs = require('fs'); @@ -96,9 +97,6 @@ describe('Viewer', function() { expect(overlays).toBeDefined(); expect(elementRegistry).toBeDefined(); - // given - var subProcessShape = elementRegistry.get('SubProcess_1'); - // when overlays.add('SubProcess_1', { position: { @@ -270,6 +268,7 @@ describe('Viewer', function() { }); }); + it('should remove outer-makers on export', function(done) { // given @@ -387,6 +386,48 @@ describe('Viewer', function() { expect(viewer.container.style.height).toBe('100px'); }); + + var camundaPackage = require('../fixtures/json/model/camunda'); + + it('should provide custom moddle extensions', function(done) { + + var xml = fs.readFileSync('test/fixtures/bpmn/extension/camunda.bpmn', 'utf8'); + + // given + viewer = new Viewer({ + container: container, + moddleExtensions: { + camunda: camundaPackage + } + }); + + // when + viewer.importXML(xml, function(err, warnings) { + + var elementRegistry = viewer.get('elementRegistry'); + + var taskShape = elementRegistry.get('send'), + sendTask = taskShape.businessObject; + + // then + expect(sendTask).toBeDefined(); + + var extensionElements = sendTask.extensionElements; + + // receive task should be moddle extended + expect(sendTask.$instanceOf('camunda:ServiceTaskLike')).toBeTruthy(); + + // extension elements should provide typed element + expect(extensionElements).toBeTruthy(); + + expect(extensionElements.values.length).toBe(1); + expect(extensionElements.values[0].$instanceOf('camunda:InputOutput')).toBeTruthy(); + + done(err); + }); + + }); + });