diff --git a/Gruntfile.js b/Gruntfile.js index 64338b25..3474e671 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -119,9 +119,11 @@ module.exports = function(grunt) { grunt.registerTask('test', [ 'karma:single' ]); + grunt.registerTask('lint', [ 'eslint:check' ]); + grunt.registerTask('auto-test', [ 'karma:unit' ]); grunt.registerTask('build', [ 'bundle', 'copy' ]); - grunt.registerTask('default', [ 'eslint:check', 'test', 'build' ]); -}; \ No newline at end of file + grunt.registerTask('default', [ 'lint', 'test', 'build' ]); +}; diff --git a/README.md b/README.md index e073d5cd..1dfa8e89 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,19 @@ viewer.importXML(xml, function(err) { }); ``` +### Dynamic Attach/Detach + +You may attach or detach the viewer dynamically to any element on the page, too: + +```javascript +var viewer = new BpmnViewer(); + +// attach it to some element +viewer.attachTo('#container'); + +// detach the panel +viewer.detach(); +``` ## Installation diff --git a/lib/Viewer.js b/lib/Viewer.js index 775d59eb..a3d916d9 100644 --- a/lib/Viewer.js +++ b/lib/Viewer.js @@ -8,7 +8,6 @@ var assign = require('lodash/object/assign'), omit = require('lodash/object/omit'), - isString = require('lodash/lang/isString'), isNumber = require('lodash/lang/isNumber'); var domify = require('min-dom/lib/domify'), @@ -46,8 +45,7 @@ function checkValidationError(err) { var DEFAULT_OPTIONS = { width: '100%', height: '100%', - position: 'relative', - container: 'body' + position: 'relative' }; @@ -356,9 +354,49 @@ Viewer.prototype.off = function(event, callback) { this.get('eventBus').off(event, callback); }; +Viewer.prototype.attachTo = function(parentNode) { + + if (!parentNode) { + throw new Error('parentNode required'); + } + + // ensure we detach from the + // previous, old parent + this.detach(); + + // unwrap jQuery if provided + if (parentNode.get) { + parentNode = parentNode.get(0); + } + + if (typeof parentNode === 'string') { + parentNode = domQuery(parentNode); + } + + var container = this._container; + + parentNode.appendChild(container); + + this._emit('attach', {}); +}; + +Viewer.prototype.detach = function() { + + var container = this._container, + parentNode = container.parentNode; + + if (!parentNode) { + return; + } + + this._emit('detach', {}); + + parentNode.removeChild(container); +}; Viewer.prototype._init = function(container, moddle, options) { + this._container = container; var baseModules = options.modules || this.getModules(), additionalModules = options.additionalModules || [], staticModules = [ @@ -377,6 +415,10 @@ Viewer.prototype._init = function(container, moddle, options) { // invoke diagram constructor Diagram.call(this, diagramOptions); + + if (options && options.container) { + this.attachTo(options.container); + } }; /** @@ -393,21 +435,7 @@ Viewer.prototype._emit = function(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('
'); + var container = domify(''); assign(container.style, { width: ensureUnit(options.width), @@ -415,8 +443,6 @@ Viewer.prototype._createContainer = function(options) { position: options.position }); - parent.appendChild(container); - return container; }; diff --git a/package.json b/package.json index ac8303ca..16d559c6 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "all": "grunt", "dev": "grunt auto-test", "distro": "grunt build", - "test": "grunt test" + "test": "grunt test", + "lint": "grunt lint" }, "repository": { "type": "git", diff --git a/test/spec/ModelerSpec.js b/test/spec/ModelerSpec.js index 00966938..94c3682f 100644 --- a/test/spec/ModelerSpec.js +++ b/test/spec/ModelerSpec.js @@ -94,25 +94,6 @@ describe('Modeler', function() { }); - describe('defaults', function() { - - it('should use as default parent', function(done) { - - var xml = require('../fixtures/bpmn/simple.bpmn'); - - var modeler = new Modeler(); - - modeler.importXML(xml, function(err, warnings) { - - expect(modeler.container.parentNode).to.equal(document.body); - - done(err, warnings); - }); - }); - - }); - - describe('translate support', function() { var xml = require('../fixtures/bpmn/simple.bpmn'); diff --git a/test/spec/ViewerSpec.js b/test/spec/ViewerSpec.js index 0731dddb..52f11818 100644 --- a/test/spec/ViewerSpec.js +++ b/test/spec/ViewerSpec.js @@ -72,25 +72,6 @@ describe('Viewer', function() { }); - describe('defaults', function() { - - it('should use as default parent', function(done) { - - var xml = require('../fixtures/bpmn/simple.bpmn'); - - var viewer = new Viewer(); - - viewer.importXML(xml, function(err, warnings) { - - expect(viewer.container.parentNode).to.equal(document.body); - - done(err, warnings); - }); - }); - - }); - - describe('overlay support', function() { it('should allow to add overlays', function(done) { @@ -753,6 +734,33 @@ describe('Viewer', function() { }); + it('should attach the viewer to the given parent', function(done) { + + var xml = require('../fixtures/bpmn/simple.bpmn'); + + var viewer = new Viewer({ container: container }); + + viewer.importXML(xml, function(err, warnings) { + + expect(viewer.container.parentNode).to.equal(container); + + done(err, warnings); + }); + }); + + it('should not attach the viewer automatically if no parent was given', function(done) { + + var xml = require('../fixtures/bpmn/simple.bpmn'); + + var viewer = new Viewer(); + + viewer.importXML(xml, function(err, warnings) { + + expect(viewer.container.parentNode).to.equal(null); + + done(err, warnings); + }); + }); }); @@ -929,4 +937,41 @@ describe('Viewer', function() { }); + + describe('#attachTo', function() { + it('should attach the viewer', function(done) { + + var xml = require('../fixtures/bpmn/simple.bpmn'); + + var viewer = new Viewer(); + + viewer.importXML(xml, function(err, warnings) { + + expect(viewer.container.parentNode).to.equal(null); + viewer.attachTo(container); + expect(viewer.container.parentNode).to.equal(container); + + done(err, warnings); + }); + }); + }); + + + describe('#detach', function() { + it('should detach the viewer', function(done) { + + var xml = require('../fixtures/bpmn/simple.bpmn'); + + var viewer = new Viewer({ container: container }); + + viewer.importXML(xml, function(err, warnings) { + + expect(viewer.container.parentNode).to.equal(container); + viewer.detach(); + expect(viewer.container.parentNode).to.equal(null); + + done(err, warnings); + }); + }); + }); });