feat(i18n): add localization

* Palette, ContextPad, Errors...

Closes #491
This commit is contained in:
davcs86 2016-02-25 10:40:56 -06:00 committed by Nico Rehwaldt
parent 85f50ff907
commit 49173abdad
21 changed files with 274 additions and 99 deletions

View File

@ -419,6 +419,7 @@ Viewer.prototype.off = function(event, callback) {
// modules the viewer is composed of
Viewer.prototype._modules = [
require('./core'),
require('diagram-js/lib/i18n/translate'),
require('diagram-js/lib/features/selection'),
require('diagram-js/lib/features/overlays')
];
@ -462,4 +463,4 @@ function addProjectLogo(container) {
});
}
/* </project-logo> */
/* </project-logo> */

View File

@ -15,7 +15,7 @@ var assign = require('lodash/object/assign'),
*/
function ContextPadProvider(contextPad, modeling, elementFactory,
connect, create, popupMenu,
canvas, rules) {
canvas, rules, translate) {
contextPad.registerProvider(this);
@ -29,6 +29,7 @@ function ContextPadProvider(contextPad, modeling, elementFactory,
this._popupMenu = popupMenu;
this._canvas = canvas;
this._rules = rules;
this._translate = translate;
}
ContextPadProvider.$inject = [
@ -39,7 +40,8 @@ ContextPadProvider.$inject = [
'create',
'popupMenu',
'canvas',
'rules'
'rules',
'translate'
];
module.exports = ContextPadProvider;
@ -55,7 +57,9 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
create = this._create,
popupMenu = this._popupMenu,
canvas = this._canvas,
rules = this._rules;
rules = this._rules,
translate = this._translate;
var actions = {};
@ -109,7 +113,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
if (typeof title !== 'string') {
options = title;
title = 'Append ' + type.replace(/^bpmn\:/, '');
title = translate('Append {type}', { type: type.replace(/^bpmn\:/, '') });
}
function appendListener(event, element) {
@ -149,7 +153,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
'lane-insert-above': {
group: 'lane-insert-above',
className: 'bpmn-icon-lane-insert-above',
title: 'Add Lane above',
title: translate('Add Lane above'),
action: {
click: function(event, element) {
modeling.addLane(element, 'top');
@ -165,7 +169,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
'lane-divide-two': {
group: 'lane-divide',
className: 'bpmn-icon-lane-divide-two',
title: 'Divide into two Lanes',
title: translate('Divide into two Lanes'),
action: {
click: splitLaneHandler(2)
}
@ -178,7 +182,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
'lane-divide-three': {
group: 'lane-divide',
className: 'bpmn-icon-lane-divide-three',
title: 'Divide into three Lanes',
title: translate('Divide into three Lanes'),
action: {
click: splitLaneHandler(3)
}
@ -191,7 +195,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
'lane-insert-below': {
group: 'lane-insert-below',
className: 'bpmn-icon-lane-insert-below',
title: 'Add Lane below',
title: translate('Add Lane below'),
action: {
click: function(event, element) {
modeling.addLane(element, 'bottom');
@ -227,7 +231,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
assign(actions, {
'append.compensation-activity':
appendAction('bpmn:Task', 'bpmn-icon-task', 'Append compensation activity', {
appendAction('bpmn:Task', 'bpmn-icon-task', translate('Append compensation activity'), {
isForCompensation: true
})
});
@ -261,7 +265,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
'replace': {
group: 'edit',
className: 'bpmn-icon-screw-wrench',
title: 'Change type',
title: translate('Change type'),
action: {
click: function(event, element) {
replaceMenu.open(assign(getReplaceMenuPosition(element), {
@ -281,9 +285,9 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
'connect': {
group: 'connect',
className: 'bpmn-icon-connection-multi',
title: 'Connect using ' +
title: translate('Connect using ' +
(businessObject.isForCompensation ? '' : 'Sequence/MessageFlow or ') +
'Association',
'Association'),
action: {
click: startConnect,
dragstart: startConnect
@ -297,7 +301,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
'connect': {
group: 'connect',
className: 'bpmn-icon-connection-multi',
title: 'Connect using DataInputAssociation',
title: translate('Connect using DataInputAssociation'),
action: {
click: startConnect,
dragstart: startConnect
@ -319,7 +323,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
'delete': {
group: 'edit',
className: 'bpmn-icon-trash',
title: 'Remove',
title: translate('Remove'),
action: {
click: removeElement,
dragstart: removeElement

View File

@ -17,11 +17,12 @@ var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
* A handler responsible for updating the underlying BPMN 2.0 XML + DI
* once changes on the diagram happen
*/
function BpmnUpdater(eventBus, bpmnFactory, connectionDocking) {
function BpmnUpdater(eventBus, bpmnFactory, connectionDocking, translate) {
CommandInterceptor.call(this, eventBus);
this._bpmnFactory = bpmnFactory;
this._translate = translate;
var self = this;
@ -247,7 +248,7 @@ inherits(BpmnUpdater, CommandInterceptor);
module.exports = BpmnUpdater;
BpmnUpdater.$inject = [ 'eventBus', 'bpmnFactory', 'connectionDocking' ];
BpmnUpdater.$inject = [ 'eventBus', 'bpmnFactory', 'connectionDocking', 'translate' ];
/////// implementation //////////////////////////////////
@ -402,7 +403,8 @@ BpmnUpdater.prototype.getLaneSet = function(container) {
BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent) {
var containment;
var containment,
translate = this._translate;
if (businessObject.$parent === newParent) {
return;
@ -494,7 +496,13 @@ BpmnUpdater.prototype.updateSemanticParent = function(businessObject, newParent)
}
if (!containment) {
throw new Error('no parent for ', businessObject, newParent);
throw new Error(translate(
'no parent for {element} in {parent}',
{
element: businessObject.id,
parent: newParent.id
}
));
}
var children;

View File

@ -12,17 +12,18 @@ var BaseElementFactory = require('diagram-js/lib/core/ElementFactory'),
/**
* A bpmn-aware factory for diagram-js shapes
*/
function ElementFactory(bpmnFactory, moddle) {
function ElementFactory(bpmnFactory, moddle, translate) {
BaseElementFactory.call(this);
this._bpmnFactory = bpmnFactory;
this._moddle = moddle;
this._translate = translate;
}
inherits(ElementFactory, BaseElementFactory);
ElementFactory.$inject = [ 'bpmnFactory', 'moddle' ];
ElementFactory.$inject = [ 'bpmnFactory', 'moddle', 'translate' ];
module.exports = ElementFactory;
@ -40,7 +41,8 @@ ElementFactory.prototype.create = function(elementType, attrs) {
};
ElementFactory.prototype.createBpmnElement = function(elementType, attrs) {
var size;
var size,
translate = this._translate;
attrs = attrs || {};
@ -48,7 +50,7 @@ ElementFactory.prototype.createBpmnElement = function(elementType, attrs) {
if (!businessObject) {
if (!attrs.type) {
throw new Error('no shape type specified');
throw new Error(translate('no shape type specified'));
}
businessObject = this._bpmnFactory.create(attrs.type);

View File

@ -3,7 +3,7 @@
var is = require('../../../util/ModelUtil').is;
function ModelingFeedback(eventBus, tooltips) {
function ModelingFeedback(eventBus, tooltips, translate) {
function showError(position, message) {
tooltips.add({
@ -24,13 +24,13 @@ function ModelingFeedback(eventBus, tooltips) {
target = context.target;
if (is(target, 'bpmn:Collaboration') && is(shape, 'bpmn:FlowNode')) {
showError(event, 'flow elements must be children of pools/participants');
showError(event, translate('flow elements must be children of pools/participants'));
}
});
}
ModelingFeedback.$inject = [ 'eventBus', 'tooltips' ];
ModelingFeedback.$inject = [ 'eventBus', 'tooltips', 'translate' ];
module.exports = ModelingFeedback;

View File

@ -14,7 +14,7 @@ var LOW_PRIORITY = 500,
/**
* BPMN specific delete lane behavior
*/
function UpdateFlowNodeRefsBehavior(eventBus, modeling) {
function UpdateFlowNodeRefsBehavior(eventBus, modeling, translate) {
CommandInterceptor.call(this, eventBus);
@ -44,7 +44,7 @@ function UpdateFlowNodeRefsBehavior(eventBus, modeling) {
function getContext() {
if (!context) {
throw new Error('out of bounds release');
throw new Error(translate('out of bounds release'));
}
return context;
@ -53,7 +53,7 @@ function UpdateFlowNodeRefsBehavior(eventBus, modeling) {
function releaseContext() {
if (!context) {
throw new Error('out of bounds release');
throw new Error(translate('out of bounds release'));
}
var triggerUpdate = context.leave();
@ -122,7 +122,7 @@ function UpdateFlowNodeRefsBehavior(eventBus, modeling) {
});
}
UpdateFlowNodeRefsBehavior.$inject = [ 'eventBus', 'modeling' ];
UpdateFlowNodeRefsBehavior.$inject = [ 'eventBus', 'modeling' , 'translate'];
inherits(UpdateFlowNodeRefsBehavior, CommandInterceptor);

View File

@ -10,18 +10,20 @@ var LANE_INDENTATION = require('../util/LaneUtil').LANE_INDENTATION;
*
* @param {Modeling} modeling
*/
function SplitLaneHandler(modeling) {
function SplitLaneHandler(modeling, translate) {
this._modeling = modeling;
this._translate = translate;
}
SplitLaneHandler.$inject = [ 'modeling' ];
SplitLaneHandler.$inject = [ 'modeling', 'translate'];
module.exports = SplitLaneHandler;
SplitLaneHandler.prototype.preExecute = function(context) {
var modeling = this._modeling;
var modeling = this._modeling,
translate = this._translate;
var shape = context.shape,
newLanesCount = context.count;
@ -30,7 +32,7 @@ SplitLaneHandler.prototype.preExecute = function(context) {
existingLanesCount = childLanes.length;
if (existingLanesCount > newLanesCount) {
throw new Error('more than ' + newLanesCount + ' child lanes');
throw new Error(translate('more than {count} child lanes', { count: newLanesCount }));
}
var newLanesHeight = Math.round(shape.height / newLanesCount);

View File

@ -21,12 +21,13 @@ var DEFAULT_FLOW = 'default',
* Use respective diagram-js provided handlers if you would
* like to perform automated modeling.
*/
function UpdatePropertiesHandler(elementRegistry, moddle) {
function UpdatePropertiesHandler(elementRegistry, moddle, translate) {
this._elementRegistry = elementRegistry;
this._moddle = moddle;
this._translate = translate;
}
UpdatePropertiesHandler.$inject = [ 'elementRegistry', 'moddle' ];
UpdatePropertiesHandler.$inject = [ 'elementRegistry', 'moddle', 'translate' ];
module.exports = UpdatePropertiesHandler;
@ -46,10 +47,11 @@ module.exports = UpdatePropertiesHandler;
UpdatePropertiesHandler.prototype.execute = function(context) {
var element = context.element,
changed = [ element ];
changed = [ element],
translate = this._translate;
if (!element) {
throw new Error('element required');
throw new Error(translate('element required'));
}
var elementRegistry = this._elementRegistry,

View File

@ -17,7 +17,7 @@ var find = require('lodash/collection/find');
* (1) elements are ordered by a {level} property
* (2) elements with {alwaysOnTop} are always added to the root
*/
function BpmnOrderingProvider(eventBus) {
function BpmnOrderingProvider(eventBus, translate) {
OrderingProvider.call(this, eventBus);
@ -84,7 +84,10 @@ function BpmnOrderingProvider(eventBus) {
}
if (!actualParent) {
throw new Error('no parent for ' + element.id + ' in ' + newParent.id);
throw new Error(translate('no parent for {element} in {parent}', {
element: element.id,
parent: newParent.id
}));
}
return actualParent;
@ -132,7 +135,7 @@ function BpmnOrderingProvider(eventBus) {
};
}
BpmnOrderingProvider.$inject = [ 'eventBus' ];
BpmnOrderingProvider.$inject = [ 'eventBus', 'translate' ];
inherits(BpmnOrderingProvider, OrderingProvider);

View File

@ -1,4 +1,7 @@
module.exports = {
__init__: [ 'bpmnOrderingProvider' ],
__depends__: [
require('diagram-js/lib/i18n/translate')
],
bpmnOrderingProvider: [ 'type', require('./BpmnOrderingProvider') ]
};

View File

@ -5,7 +5,7 @@ var assign = require('lodash/object/assign');
/**
* A palette provider for BPMN 2.0 elements.
*/
function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool, handTool) {
function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool, handTool, translate) {
this._palette = palette;
this._create = create;
@ -13,6 +13,7 @@ function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool,
this._spaceTool = spaceTool;
this._lassoTool = lassoTool;
this._handTool = handTool;
this._translate = translate;
palette.registerProvider(this);
}
@ -25,7 +26,9 @@ PaletteProvider.$inject = [
'elementFactory',
'spaceTool',
'lassoTool',
'handTool'
'handTool',
'translate',
'eventBus'
];
@ -36,7 +39,8 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
elementFactory = this._elementFactory,
spaceTool = this._spaceTool,
lassoTool = this._lassoTool,
handTool = this._handTool;
handTool = this._handTool,
translate = this._translate;
function createAction(type, group, className, title, options) {
@ -55,7 +59,7 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
return {
group: group,
className: className,
title: title || 'Create ' + shortType,
title: title || translate('Create {type}', { type: shortType }),
action: {
dragstart: createListener,
click: createListener
@ -71,7 +75,7 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
'hand-tool': {
group: 'tools',
className: 'bpmn-icon-hand-tool',
title: 'Activate the hand tool',
title: translate('Activate the hand tool'),
action: {
click: function(event) {
handTool.activateHand(event);
@ -81,7 +85,7 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
'lasso-tool': {
group: 'tools',
className: 'bpmn-icon-lasso-tool',
title: 'Activate the lasso tool',
title: translate('Activate the lasso tool'),
action: {
click: function(event) {
lassoTool.activateSelection(event);
@ -91,7 +95,7 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
'space-tool': {
group: 'tools',
className: 'bpmn-icon-space-tool',
title: 'Activate the create/remove space tool',
title: translate('Activate the create/remove space tool'),
action: {
click: function(event) {
spaceTool.activateSelection(event);
@ -124,13 +128,13 @@ PaletteProvider.prototype.getPaletteEntries = function(element) {
'bpmn:DataStoreReference', 'data-store', 'bpmn-icon-data-store'
),
'create.subprocess-expanded': createAction(
'bpmn:SubProcess', 'activity', 'bpmn-icon-subprocess-expanded', 'Create expanded SubProcess',
'bpmn:SubProcess', 'activity', 'bpmn-icon-subprocess-expanded', translate('Create expanded SubProcess'),
{ isExpanded: true }
),
'create.participant-expanded': {
group: 'collaboration',
className: 'bpmn-icon-participant',
title: 'Create Pool/Participant',
title: translate('Create Pool/Participant'),
action: {
dragstart: createParticipant,
click: createParticipant

View File

@ -4,7 +4,8 @@ module.exports = {
require('diagram-js/lib/features/create'),
require('diagram-js/lib/features/space-tool'),
require('diagram-js/lib/features/lasso-tool'),
require('diagram-js/lib/features/hand-tool')
require('diagram-js/lib/features/hand-tool'),
require('diagram-js/lib/i18n/translate')
],
__init__: [ 'paletteProvider' ],
paletteProvider: [ 'type', require('./PaletteProvider') ]

View File

@ -15,18 +15,19 @@ var replaceOptions = require ('../replace/ReplaceOptions');
/**
* This module is an element agnostic replace menu provider for the popup menu.
*/
function ReplaceMenuProvider(popupMenu, modeling, moddle, bpmnReplace, rules) {
function ReplaceMenuProvider(popupMenu, modeling, moddle, bpmnReplace, rules, translate) {
this._popupMenu = popupMenu;
this._modeling = modeling;
this._moddle = moddle;
this._bpmnReplace = bpmnReplace;
this._rules = rules;
this._translate = translate;
this.register();
}
ReplaceMenuProvider.$inject = [ 'popupMenu', 'modeling', 'moddle', 'bpmnReplace', 'rules' ];
ReplaceMenuProvider.$inject = [ 'popupMenu', 'modeling', 'moddle', 'bpmnReplace', 'rules', 'translate' ];
/**
@ -331,7 +332,7 @@ ReplaceMenuProvider.prototype._createSequenceFlowEntries = function (element, re
* @return {Object} menu entry item
*/
ReplaceMenuProvider.prototype._createMenuEntry = function(definition, element, action) {
var translate = this._translate;
var replaceElement = this._bpmnReplace.replaceElement;
var replaceAction = function() {
@ -341,7 +342,7 @@ ReplaceMenuProvider.prototype._createMenuEntry = function(definition, element, a
action = action || replaceAction;
var menuEntry = {
label: definition.label,
label: translate(definition.label),
className: definition.className,
id: definition.actionName,
action: action
@ -360,6 +361,7 @@ ReplaceMenuProvider.prototype._createMenuEntry = function(definition, element, a
ReplaceMenuProvider.prototype._getLoopEntries = function(element) {
var self = this;
var translate = this._translate;
function toggleLoopEntry(event, entry) {
var loopCharacteristics;
@ -394,7 +396,7 @@ ReplaceMenuProvider.prototype._getLoopEntries = function(element) {
{
id: 'toggle-parallel-mi',
className: 'bpmn-icon-parallel-mi-marker',
title: 'Parallel Multi Instance',
title: translate('Parallel Multi Instance'),
active: isParallel,
action: toggleLoopEntry,
options: {
@ -405,7 +407,7 @@ ReplaceMenuProvider.prototype._getLoopEntries = function(element) {
{
id: 'toggle-sequential-mi',
className: 'bpmn-icon-sequential-mi-marker',
title: 'Sequential Multi Instance',
title: translate('Sequential Multi Instance'),
active: isSequential,
action: toggleLoopEntry,
options: {
@ -416,7 +418,7 @@ ReplaceMenuProvider.prototype._getLoopEntries = function(element) {
{
id: 'toggle-loop',
className: 'bpmn-icon-loop-marker',
title: 'Loop',
title: translate('Loop'),
active: isLoop,
action: toggleLoopEntry,
options: {
@ -436,6 +438,7 @@ ReplaceMenuProvider.prototype._getLoopEntries = function(element) {
* @return {Object} a menu item
*/
ReplaceMenuProvider.prototype._getAdHocEntry = function(element) {
var translate = this._translate;
var businessObject = getBusinessObject(element);
var isAdHoc = is(businessObject, 'bpmn:AdHocSubProcess');
@ -445,7 +448,7 @@ ReplaceMenuProvider.prototype._getAdHocEntry = function(element) {
var adHocEntry = {
id: 'toggle-adhoc',
className: 'bpmn-icon-ad-hoc-marker',
title: 'Ad-hoc',
title: translate('Ad-hoc'),
active: isAdHoc,
action: function(event, entry) {
if (isAdHoc) {

View File

@ -27,10 +27,12 @@ function collectWaypoints(waypoints) {
});
}
function notYetDrawn(semantic, refSemantic, property) {
return new Error(
'element ' + elementToString(refSemantic) + ' referenced by ' +
elementToString(semantic) + '#' + property + ' not yet drawn');
function notYetDrawn(translate, semantic, refSemantic, property) {
return new Error(translate('element {element} referenced by {referenced}#{property} not yet drawn', {
element: elementToString(refSemantic),
referenced: elementToString(semantic),
property: property
}));
}
/**
@ -41,15 +43,16 @@ function notYetDrawn(semantic, refSemantic, property) {
* @param {ElementFactory} elementFactory
* @param {ElementRegistry} elementRegistry
*/
function BpmnImporter(eventBus, canvas, elementFactory, elementRegistry) {
function BpmnImporter(eventBus, canvas, elementFactory, elementRegistry, translate) {
this._eventBus = eventBus;
this._canvas = canvas;
this._elementFactory = elementFactory;
this._elementRegistry = elementRegistry;
this._translate = translate;
}
BpmnImporter.$inject = [ 'eventBus', 'canvas', 'elementFactory', 'elementRegistry' ];
BpmnImporter.$inject = [ 'eventBus', 'canvas', 'elementFactory', 'elementRegistry', 'translate' ];
module.exports = BpmnImporter;
@ -61,7 +64,8 @@ module.exports = BpmnImporter;
BpmnImporter.prototype.add = function(semantic, parentElement) {
var di = semantic.di,
element;
element,
translate = this._translate;
// ROOT ELEMENT
// handle the special case that we deal with a
@ -112,9 +116,11 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
this._canvas.addConnection(element, parentElement);
} else {
throw new Error('unknown di ' + elementToString(di) + ' for element ' + elementToString(semantic));
throw new Error(translate('unknown di {di} for element {semantic}', {
di: elementToString(di),
semantic: elementToString(semantic)
}));
}
// (optional) LABEL
if (hasExternalLabel(semantic)) {
this.addLabel(semantic, element);
@ -134,18 +140,20 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
* @param {djs.model.Base} boundaryElement
*/
BpmnImporter.prototype._attachBoundary = function(boundarySemantic, boundaryElement) {
var translate = this._translate;
var hostSemantic = boundarySemantic.attachedToRef;
if (!hostSemantic) {
throw new Error('missing ' + elementToString(boundarySemantic) + '#attachedToRef');
throw new Error(translate('missing {semantic}#attachedToRef', {
semantic: elementToString(boundarySemantic)
}));
}
var host = this._elementRegistry.get(hostSemantic.id),
attachers = host && host.attachers;
if (!host) {
throw notYetDrawn(boundarySemantic, hostSemantic, 'attachedToRef');
throw notYetDrawn(translate, boundarySemantic, hostSemantic, 'attachedToRef');
}
// wire element.host <> host.attachers
@ -190,7 +198,8 @@ BpmnImporter.prototype._getEnd = function(semantic, side) {
var element,
refSemantic,
type = semantic.$type;
type = semantic.$type,
translate = this._translate;
refSemantic = semantic[side + 'Ref'];
@ -213,9 +222,12 @@ BpmnImporter.prototype._getEnd = function(semantic, side) {
}
if (refSemantic) {
throw notYetDrawn(semantic, refSemantic, side + 'Ref');
throw notYetDrawn(translate, semantic, refSemantic, side + 'Ref');
} else {
throw new Error(elementToString(semantic) + '#' + side + 'Ref not specified');
throw new Error(translate('{semantic}#{side} Ref not specified', {
semantic: elementToString(semantic),
side: side
}));
}
};

View File

@ -34,7 +34,7 @@ function findDisplayCandidate(definitions) {
}
function BpmnTreeWalker(handler) {
function BpmnTreeWalker(handler, translate) {
// list of containers already walked
var handledElements = {};
@ -65,7 +65,9 @@ function BpmnTreeWalker(handler) {
// avoid multiple rendering of elements
if (gfx) {
throw new Error('already rendered ' + elementToString(element));
throw new Error(
translate('already rendered {element}', { element: elementToString(element) })
);
}
// call handler
@ -87,7 +89,7 @@ function BpmnTreeWalker(handler) {
} catch (e) {
logError(e.message, { element: element, error: e });
console.error('failed to import ' + elementToString(element));
console.error(translate('failed to import {element}', { element: elementToString(element) }));
console.error(e);
}
}
@ -103,13 +105,23 @@ function BpmnTreeWalker(handler) {
if (bpmnElement) {
if (bpmnElement.di) {
logError('multiple DI elements defined for ' + elementToString(bpmnElement), { element: bpmnElement });
logError(
translate('multiple DI elements defined for {element}', {
element: elementToString(bpmnElement)
}),
{ element: bpmnElement }
);
} else {
diRefs.bind(bpmnElement, 'di');
bpmnElement.di = di;
}
} else {
logError('no bpmnElement referenced in ' + elementToString(di), { element: di });
logError(
translate('no bpmnElement referenced in {element}', {
element: elementToString(di)
}),
{ element: di }
);
}
}
@ -144,7 +156,7 @@ function BpmnTreeWalker(handler) {
var diagrams = definitions.diagrams;
if (diagram && diagrams.indexOf(diagram) === -1) {
throw new Error('diagram not part of bpmn:Definitions');
throw new Error(translate('diagram not part of bpmn:Definitions'));
}
if (!diagram && diagrams && diagrams.length) {
@ -153,7 +165,7 @@ function BpmnTreeWalker(handler) {
// no diagram -> nothing to import
if (!diagram) {
throw new Error('no diagram to display');
throw new Error(translate('no diagram to display'));
}
// load DI from selected diagram only
@ -163,10 +175,12 @@ function BpmnTreeWalker(handler) {
var plane = diagram.plane;
if (!plane) {
throw new Error('no plane for ' + elementToString(diagram));
throw new Error(translate(
'no plane for {element}',
{ element: elementToString(diagram) }
));
}
var rootElement = plane.bpmnElement;
// ensure we default to a suitable display candidate (process or collaboration),
@ -175,10 +189,15 @@ function BpmnTreeWalker(handler) {
rootElement = findDisplayCandidate(definitions);
if (!rootElement) {
throw new Error('no process or collaboration to display');
throw new Error(translate('no process or collaboration to display'));
} else {
logError('correcting missing bpmnElement on ' + elementToString(plane) + ' to ' + elementToString(rootElement));
logError(
translate('correcting missing bpmnElement on {plane} to {rootElement}', {
plane: elementToString(plane),
rootElement: elementToString(rootElement)
})
);
// correct DI on the fly
plane.bpmnElement = rootElement;
@ -197,7 +216,12 @@ function BpmnTreeWalker(handler) {
// force drawing of everything not yet drawn that is part of the target DI
handleUnhandledProcesses(definitions.rootElements, ctx);
} else {
throw new Error('unsupported bpmnElement for ' + elementToString(plane) + ' : ' + elementToString(rootElement));
throw new Error(
translate('unsupported bpmnElement for {plane}: {rootElement}', {
plane: elementToString(plane),
rootElement: elementToString(rootElement)
})
);
}
// handle all deferred elements
@ -369,9 +393,12 @@ function BpmnTreeWalker(handler) {
handleDataElement(e, context);
} else {
logError(
'unrecognized flowElement ' + elementToString(e) + ' in context ' +
(context ? elementToString(context.businessObject) : null),
{ element: e, context: context });
translate('unrecognized flowElement {element} in context {context}', {
element: elementToString(e),
context: (context ? elementToString(context.businessObject) : 'null')
}),
{ element: e, context: context }
);
}
});
}

View File

@ -15,7 +15,8 @@ var BpmnTreeWalker = require('./BpmnTreeWalker');
function importBpmnDiagram(diagram, definitions, done) {
var importer = diagram.get('bpmnImporter'),
eventBus = diagram.get('eventBus');
eventBus = diagram.get('eventBus'),
translate = diagram.get('translate');
var error,
warnings = [];
@ -37,7 +38,7 @@ function importBpmnDiagram(diagram, definitions, done) {
}
};
var walker = new BpmnTreeWalker(visitor);
var walker = new BpmnTreeWalker(visitor, translate);
// import
walker.handleDefinitions(definitions);

View File

@ -1,3 +1,6 @@
module.exports = {
__depends__: [
require('diagram-js/lib/i18n/translate')
],
bpmnImporter: [ 'type', require('./BpmnImporter') ]
};

View File

@ -107,17 +107,45 @@ describe('Modeler', function() {
});
describe('translate support', function() {
var xml = require('../fixtures/bpmn/simple.bpmn');
it('should allow translation of multi-lingual strings', function(done) {
createModeler(xml, function(err, warnings, modeler) {
// given
var translate = modeler.get('translate');
// assume
expect(translate).to.exist;
// when
var interpolatedString = translate('HELLO {you}!', { you: 'WALT' });
// then
expect(interpolatedString).to.eql('HELLO WALT!');
done(err);
});
});
});
describe('overlay support', function() {
it('should allow to add overlays', function(done) {
var xml = require('../fixtures/bpmn/simple.bpmn');
createModeler(xml, function(err, warnings, viewer) {
createModeler(xml, function(err, warnings, modeler) {
// given
var overlays = viewer.get('overlays'),
elementRegistry = viewer.get('elementRegistry');
var overlays = modeler.get('overlays'),
elementRegistry = modeler.get('elementRegistry');
// assume
expect(overlays).to.exist;
@ -162,13 +190,13 @@ describe('Modeler', function() {
var xml = require('../fixtures/bpmn/simple.bpmn');
createModeler(xml, function(err, warnings, viewer) {
createModeler(xml, function(err, warnings, modeler) {
// given
var bendpointMove = viewer.get('bendpointMove'),
dragging = viewer.get('dragging'),
elementRegistry = viewer.get('elementRegistry'),
canvas = viewer.get('canvas');
var bendpointMove = modeler.get('bendpointMove'),
dragging = modeler.get('dragging'),
elementRegistry = modeler.get('elementRegistry'),
canvas = modeler.get('canvas');
// assume
expect(bendpointMove).to.exist;

View File

@ -0,0 +1,15 @@
'use strict';
var translate = require('diagram-js/lib/i18n/translate/translate');
module.exports = function customTranslate(template, replacements) {
if (template === 'Remove') {
template = 'Eliminar';
}
if (template === 'Activate the hand tool') {
template = 'Activar herramienta mano';
}
return translate(template, replacements);
};

View File

@ -0,0 +1,3 @@
module.exports = {
translate: [ 'value', require('./custom-translate') ]
};

View File

@ -0,0 +1,53 @@
'use strict';
require('test/TestHelper');
/* global bootstrapModeler, inject */
var coreModule = require('lib/core'),
translateModule = require('diagram-js/lib/i18n/translate'),
customTranslateModule = require('./custom-translate'),
modelingModule = require('lib/features/modeling'),
paletteModule = require('lib/features/palette'),
contextPadModule = require('lib/features/context-pad');
var diagramXML = require('test/fixtures/bpmn/simple.bpmn');
describe('i18n - translate', function() {
beforeEach(bootstrapModeler(diagramXML, {
modules: [
coreModule,
modelingModule,
paletteModule,
contextPadModule,
translateModule,
customTranslateModule
]
}));
it('should translate palette', inject(function(palette) {
// when
var handToolEntry = palette.getEntries()['hand-tool'];
// then
expect(handToolEntry.title).to.equal('Activar herramienta mano');
}));
it('should translate context pad', inject(function(contextPad) {
// given
contextPad.open('Task_1');
// when
var deleteEntry = contextPad._current.entries.delete;
// then
expect(deleteEntry.title).to.equal('Eliminar');
}));
});