-
-
Save adbre/2353693cb40e0af0404613e52f87d05b to your computer and use it in GitHub Desktop.
'use strict'; | |
var forEach = require('lodash/collection/forEach'); | |
var HIGH_PRIORITY = 10001; | |
function ReadOnly( | |
eventBus, | |
contextPad, | |
dragging, | |
directEditing, | |
editorActions, | |
modeling, | |
palette, | |
paletteProvider) { | |
this._readOnly = false; | |
this._eventBus = eventBus; | |
var self = this; | |
eventBus.on('readOnly.changed', HIGH_PRIORITY, function (e) { | |
self._readOnly = e.readOnly; | |
if (e.readOnly) { | |
directEditing.cancel(); | |
contextPad.close(); | |
dragging.cancel(); | |
} | |
palette._update(); | |
}); | |
function intercept(obj, fnName, cb) { | |
var fn = obj[fnName]; | |
obj[fnName] = function () { | |
return cb.call(this, fn, arguments); | |
}; | |
} | |
function ignoreWhenReadOnly(obj, fnName) { | |
intercept(obj, fnName, function (fn, args) { | |
if (self._readOnly) { | |
return; | |
} | |
return fn.apply(this, args); | |
}); | |
} | |
function throwIfReadOnly(obj, fnName) { | |
intercept(obj, fnName, function (fn, args) { | |
if (self._readOnly) { | |
throw new Error('model is read-only'); | |
} | |
return fn.apply(this, args); | |
}); | |
} | |
ignoreWhenReadOnly(contextPad, 'open'); | |
ignoreWhenReadOnly(dragging, 'init'); | |
ignoreWhenReadOnly(directEditing, 'activate'); | |
ignoreWhenReadOnly(editorActions._actions, 'undo'); | |
ignoreWhenReadOnly(editorActions._actions, 'redo'); | |
ignoreWhenReadOnly(editorActions._actions, 'copy'); | |
ignoreWhenReadOnly(editorActions._actions, 'paste'); | |
ignoreWhenReadOnly(editorActions._actions, 'removeSelection'); | |
// BpmnEditorActions | |
ignoreWhenReadOnly(editorActions._actions, 'spaceTool'); | |
ignoreWhenReadOnly(editorActions._actions, 'lassoTool'); | |
ignoreWhenReadOnly(editorActions._actions, 'globalConnectTool'); | |
ignoreWhenReadOnly(editorActions._actions, 'distributeElements'); | |
ignoreWhenReadOnly(editorActions._actions, 'alignElements'); | |
ignoreWhenReadOnly(editorActions._actions, 'directEditing'); | |
throwIfReadOnly(modeling, 'moveShape'); | |
throwIfReadOnly(modeling, 'updateAttachment'); | |
throwIfReadOnly(modeling, 'moveElements'); | |
throwIfReadOnly(modeling, 'moveConnection'); | |
throwIfReadOnly(modeling, 'layoutConnection'); | |
throwIfReadOnly(modeling, 'createConnection'); | |
throwIfReadOnly(modeling, 'createShape'); | |
throwIfReadOnly(modeling, 'createLabel'); | |
throwIfReadOnly(modeling, 'appendShape'); | |
throwIfReadOnly(modeling, 'removeElements'); | |
throwIfReadOnly(modeling, 'distributeElements'); | |
throwIfReadOnly(modeling, 'removeShape'); | |
throwIfReadOnly(modeling, 'removeConnection'); | |
throwIfReadOnly(modeling, 'replaceShape'); | |
throwIfReadOnly(modeling, 'pasteElements'); | |
throwIfReadOnly(modeling, 'alignElements'); | |
throwIfReadOnly(modeling, 'resizeShape'); | |
throwIfReadOnly(modeling, 'createSpace'); | |
throwIfReadOnly(modeling, 'updateWaypoints'); | |
throwIfReadOnly(modeling, 'reconnectStart'); | |
throwIfReadOnly(modeling, 'reconnectEnd'); | |
intercept(paletteProvider, 'getPaletteEntries', function (fn, args) { | |
var entries = fn.apply(this, args); | |
if (self._readOnly) { | |
var allowedEntries = [ | |
'hand-tool' | |
]; | |
forEach(entries, function (value, key) { | |
if (allowedEntries.indexOf(key) === -1) { | |
delete entries[key]; | |
} | |
}); | |
} | |
return entries; | |
}); | |
} | |
ReadOnly.$inject = [ | |
'eventBus', | |
'contextPad', | |
'dragging', | |
'directEditing', | |
'editorActions', | |
'modeling', | |
'palette', | |
'paletteProvider', | |
]; | |
module.exports = ReadOnly; | |
ReadOnly.prototype.readOnly = function (readOnly) { | |
var newValue = !!readOnly, | |
oldValue = !!this._readOnly; | |
if (readOnly === undefined || newValue === oldValue) { | |
return oldValue; | |
} | |
this._readOnly = newValue; | |
this._eventBus.fire('readOnly.changed', { readOnly: newValue }); | |
return newValue; | |
}; |
To add it in the bpmn-js-example build chain you need to include the ReadOnly.js file and add it to the BpmnModeler class (see how other modules are included).
To activate/disable readOnly state
modeler.get('readOnly').readOnly(true|false);
See also https://forum.bpmn.io/t/changing-from-modeler-to-viewer-and-back-again/900/12 for more info
Hi Adam,
Unfortunately, this method does not work anymore, can you please give me a hint how I can get to work.
Thanks and regards,
@Tricinty what exavtly does not work anymore?
The lines
ignoreWhenReadOnly(editorActions._actions, 'undo');
ignoreWhenReadOnly(editorActions._actions, 'redo');
ignoreWhenReadOnly(editorActions._actions, 'copy');
ignoreWhenReadOnly(editorActions._actions, 'paste');
ignoreWhenReadOnly(editorActions._actions, 'removeSelection');
// BpmnEditorActions
ignoreWhenReadOnly(editorActions._actions, 'spaceTool');
ignoreWhenReadOnly(editorActions._actions, 'lassoTool');
ignoreWhenReadOnly(editorActions._actions, 'globalConnectTool');
ignoreWhenReadOnly(editorActions._actions, 'distributeElements');
ignoreWhenReadOnly(editorActions._actions, 'alignElements');
ignoreWhenReadOnly(editorActions._actions, 'directEditing');
Cause the editor actions module to crash later on, since the actions are now registered when the diagram is loaded. One could defer patching the actions with this code instead:
eventBus.on('editorActions.init', function() {
ignoreWhenReadOnly(editorActions._actions, 'undo');
ignoreWhenReadOnly(editorActions._actions, 'redo');
ignoreWhenReadOnly(editorActions._actions, 'copy');
ignoreWhenReadOnly(editorActions._actions, 'paste');
ignoreWhenReadOnly(editorActions._actions, 'removeSelection');
// BpmnEditorActions
ignoreWhenReadOnly(editorActions._actions, 'spaceTool');
ignoreWhenReadOnly(editorActions._actions, 'lassoTool');
ignoreWhenReadOnly(editorActions._actions, 'globalConnectTool');
ignoreWhenReadOnly(editorActions._actions, 'distributeElements');
ignoreWhenReadOnly(editorActions._actions, 'alignElements');
ignoreWhenReadOnly(editorActions._actions, 'directEditing');
});
Additionally, dynamically loading the read-only module must now use code like this (the parameter has changed to additionalModules
instead of modules
in the original post):
var readOnlyModule = {
__init__: ['readOnly'],
readOnly: ['type', ReadOnly]
};
var viewer = new BpmnJS({
container : ... ,
additionalModules: [readOnlyModule]
});
viewer.get('readOnly').readOnly(true);
However, using this module produces a disabled modeler that is unable to scroll the diagram with the mouse within its viewport (when clicking within the diagram), which is unusable for non-trivial diagrams. The problem is that
ignoreWhenReadOnly(dragging, 'init');
breaks the hand-tool that allows scrolling the diagram. Without the line, one can start dragging individual shapes but not drop them again.
The alternative to the "ReadOnly"-Module is using either a modler or a viewer - the constructor function for the viewer is also available in the modeler - I searched for this quite a long time:
var Modeler = editMode ? BpmnJS : BpmnJS.NavigatedViewer;
var viewer = new Modeler({
container : ...
});
This has the drawback that when switching from viewer to modeler, one has to re-draw the diagram (loosing potential scroll positions) but is way better than having a "Viewer" that is much less convienent that the "original" viewer.
Hello Adam ,
Could you please, give me some code hints, in order to use this implementation,
Where I can integrate and call the readOnly.js for example in this bpmn-js-examples .
Thanks and regards,