diff --git a/lib/BaseViewer.js b/lib/BaseViewer.js index 3bf0107205..1311490cc6 100644 --- a/lib/BaseViewer.js +++ b/lib/BaseViewer.js @@ -31,6 +31,9 @@ import { importBpmnDiagram } from './import/Importer'; +import { + wrapForCompatibility +} from './util/CompatibilityUtil'; /** * A base viewer for BPMN 2.0 diagrams. @@ -88,7 +91,7 @@ inherits(BaseViewer, Diagram); * @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=[]) */ -BaseViewer.prototype.importXML = function(xml, bpmnDiagram, done) { +BaseViewer.prototype.importXML = wrapForCompatibility(function importXML(xml, bpmnDiagram, done) { if (isFunction(bpmnDiagram)) { done = bpmnDiagram; @@ -143,7 +146,7 @@ BaseViewer.prototype.importXML = function(xml, bpmnDiagram, done) { return done(err, err.warnings); }); -}; +}); /** * Import parsed definitions and render a BPMN 2.0 diagram. @@ -164,7 +167,7 @@ BaseViewer.prototype.importXML = function(xml, bpmnDiagram, done) { * @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=[]) */ -BaseViewer.prototype.importDefinitions = function(definitions, bpmnDiagram, done) { +BaseViewer.prototype.importDefinitions = wrapForCompatibility(function importDefinitions(definitions, bpmnDiagram, done) { if (isFunction(bpmnDiagram)) { done = bpmnDiagram; @@ -177,7 +180,7 @@ BaseViewer.prototype.importDefinitions = function(definitions, bpmnDiagram, done this._setDefinitions(definitions); return this.open(bpmnDiagram, done); -}; +}); /** * Open diagram of previously imported XML. @@ -197,7 +200,7 @@ BaseViewer.prototype.importDefinitions = function(definitions, bpmnDiagram, done * @param {string|ModdleElement} [bpmnDiagramOrId] id or the diagram to open * @param {Function} [done] invoked with (err, warnings=[]) */ -BaseViewer.prototype.open = function(bpmnDiagramOrId, done) { +BaseViewer.prototype.open = wrapForCompatibility(function open(bpmnDiagramOrId, done) { if (isFunction(bpmnDiagramOrId)) { done = bpmnDiagramOrId; @@ -232,7 +235,7 @@ BaseViewer.prototype.open = function(bpmnDiagramOrId, done) { // perform graphical import return importBpmnDiagram(this, definitions, bpmnDiagram, done); -}; +}); /** * Export the currently displayed BPMN 2.0 diagram as @@ -254,7 +257,7 @@ BaseViewer.prototype.open = function(bpmnDiagramOrId, done) { * * @param {Function} done invoked with (err, xml) */ -BaseViewer.prototype.saveXML = function(options, done) { +BaseViewer.prototype.saveXML = wrapForCompatibility(function saveXML(options, done) { if (!done) { done = options; @@ -296,7 +299,7 @@ BaseViewer.prototype.saveXML = function(options, done) { }).catch(function(err) { done(err); }); -}; +}); /** * Export the currently displayed BPMN 2.0 diagram as @@ -314,7 +317,7 @@ BaseViewer.prototype.saveXML = function(options, done) { * @param {Object} [options] * @param {Function} done invoked with (err, svgStr) */ -BaseViewer.prototype.saveSVG = function(options, done) { +BaseViewer.prototype.saveSVG = wrapForCompatibility(function saveSVG(options, done) { if (!done) { done = options; @@ -355,7 +358,7 @@ BaseViewer.prototype.saveSVG = function(options, done) { }); done(err, svg); -}; +}); /** * Get a named diagram service. @@ -569,7 +572,6 @@ BaseViewer.prototype._createModdle = function(options) { BaseViewer.prototype._modules = []; - // helpers /////////////// function checkValidationError(err) { diff --git a/lib/util/CompatibilityUtil.js b/lib/util/CompatibilityUtil.js new file mode 100644 index 0000000000..1f60716a9a --- /dev/null +++ b/lib/util/CompatibilityUtil.js @@ -0,0 +1,53 @@ +import { isFunction } from 'min-dash'; + +// TODO(nikku): remove with future bpmn-js version + +/** + * Wraps APIs to check: + * + * 1) If a callback is passed -> Warn users about callback deprecation. + * 2) If Promise class is implemented in current environment. + * + * @private + */ +export function wrapForCompatibility(api) { + + return function() { + + if (!window.Promise) { + throw new Error('Promises is not supported in this environment. Consider polyfilling.'); + } + + var argLen = arguments.length; + if (argLen >= 1 && isFunction(arguments[argLen - 1])) { + + var callback = arguments[argLen - 1]; + + console.warn(new Error( + 'Passing callbacks to ' + api.name + ' is deprecated and will be removed in a future major release.' + + 'Please switch to promises, cf. https://bpmn.io/l/moving-to-promises.html' + )); + + var argsWithoutCallback = Array.prototype.slice.call(arguments, 0, -1); + + api.apply(this, argsWithoutCallback).then(function(result) { + + var firstKey = Object.keys(result)[0]; + + // The APIs we are wrapping all resolve a single item depending on the API. + // For instance, importXML resolves { warnings } and saveXML returns { xml }. + // That's why we can call the callback with the first item of result. + return callback(null, result[firstKey]); + + // Passing a second paramter instead of catch because we don't want to + // catch errors thrown by callback(). + }, function(err) { + + return callback(err, err.warnings); + }); + } else { + + return api.apply(this, arguments); + } + }; +}