diff --git a/lib/Viewer.js b/lib/Viewer.js index cd630a78..541d2d15 100644 --- a/lib/Viewer.js +++ b/lib/Viewer.js @@ -212,9 +212,7 @@ Viewer.prototype.importXML = function(xml, bpmnDiagram, done) { return done(err, parseWarnings); } - self._setDefinitions(definitions); - - self.open(bpmnDiagram, function(err, importWarnings) { + self.importDefinitions(definitions, bpmnDiagram, function(err, importWarnings) { var allWarnings = [].concat(parseWarnings, importWarnings || []); self._emit('import.done', { error: err, warnings: allWarnings }); @@ -224,6 +222,40 @@ Viewer.prototype.importXML = function(xml, bpmnDiagram, done) { }); }; +/** + * Import parsed definitions 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.render.start (graphical import start) + * * import.render.complete (graphical import finished) + * + * You can use these events to hook into the life-cycle. + * + * @param {ModdleElement} definitions parsed BPMN 2.0 definitions + * @param {ModdleElement|String} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered) + * @param {Function} [done] invoked with (err, warnings=[]) + */ +Viewer.prototype.importDefinitions = function(definitions, bpmnDiagram, done) { + + if (isFunction(bpmnDiagram)) { + done = bpmnDiagram; + bpmnDiagram = null; + } + + // done is optional + done = done || function() {}; + + this._setDefinitions(definitions); + + return this.open(bpmnDiagram, done); +}; + /** * Open diagram of previously imported XML. * diff --git a/test/spec/ViewerSpec.js b/test/spec/ViewerSpec.js index bb645c50..560102f5 100644 --- a/test/spec/ViewerSpec.js +++ b/test/spec/ViewerSpec.js @@ -769,6 +769,187 @@ describe('Viewer', function() { }); + describe('#importDefinitions', function() { + + describe('single diagram', function() { + + var xml = require('../fixtures/bpmn/simple.bpmn'), + viewer, + definitions; + + beforeEach(function(done) { + createViewer(xml, null, function(error, _, tmpViewer) { + if (error) { + return done(error); + } + + definitions = tmpViewer.getDefinitions(); + + tmpViewer.destroy(); + + done(); + }); + }); + + beforeEach(function() { + viewer = new Viewer({ container: container }); + }); + + afterEach(function() { + viewer.destroy(); + }); + + + it('should emit events', function(done) { + + // given + var events = []; + + viewer.on([ + 'import.parse.start', + 'import.parse.complete', + 'import.render.start', + 'import.render.complete', + 'import.done' + ], function(e) { + // log event type + event arguments + events.push([ + e.type, + Object.keys(e).filter(function(key) { + return key !== 'type'; + }) + ]); + }); + + // when + viewer.importDefinitions(definitions, function(err) { + + // then + expect(events).to.eql([ + [ 'import.render.start', [ 'definitions' ] ], + [ 'import.render.complete', [ 'error', 'warnings' ] ] + ]); + + done(err); + }); + }); + + + it('should work without callback', function(done) { + + // given + viewer.on('import.render.complete', function(context) { + // then + done(context.error); + }); + + // when + viewer.importDefinitions(definitions); + }); + + }); + + + describe('multiple BPMNDiagram elements', function() { + + var multipleXML = require('../fixtures/bpmn/multiple-diagrams.bpmn'), + viewer, + definitions; + + beforeEach(function(done) { + createViewer(multipleXML, null, function(error, _, tmpViewer) { + if (error) { + return done(error); + } + + definitions = tmpViewer.getDefinitions(); + + tmpViewer.destroy(); + + done(); + }); + }); + + beforeEach(function() { + viewer = new Viewer({ container: container }); + }); + + afterEach(function() { + viewer.destroy(); + }); + + + it('should import default without bpmnDiagram specified', function(done) { + + // when + viewer.importDefinitions(definitions, function(err) { + + // then + done(err); + }); + }); + + + it('should import bpmnDiagram specified by id', function(done) { + + // when + viewer.importDefinitions(definitions, 'BpmnDiagram_2', function(err) { + + // then + done(err); + }); + }); + + + it('should handle diagram not found', function(done) { + + // when + viewer.importDefinitions(definitions, 'Diagram_IDontExist', function(err) { + + // then + expect(err).to.exist; + expect(err.message).to.eql('BPMNDiagram not found'); + + done(); + }); + }); + + + describe('without callback', function() { + + it('should open default', function(done) { + + // given + viewer.on('import.render.complete', function(event) { + + // then + done(event.error); + }); + + // when + viewer.importDefinitions(definitions); + }); + + + it('should open specified BPMNDiagram', function(done) { + + // given + viewer.on('import.render.complete', function(event) { + + // then + done(event.error); + }); + + // when + viewer.importDefinitions(definitions, 'BpmnDiagram_2'); + }); + + }); + + }); + }); + + describe('#open', function() { var multipleXMLSimple = require('../fixtures/bpmn/multiple-diagrams.bpmn'),