From db0ce65aa403a53979733d5773bfa01fb0d00d68 Mon Sep 17 00:00:00 2001 From: Philipp Fromme Date: Wed, 14 Sep 2016 08:18:56 +0200 Subject: [PATCH] feat(graphics): remove snapsvg Related to bpmn-io/diagram-js#50 --- lib/Viewer.js | 10 +- lib/draw/BpmnRenderer.js | 580 ++++++++++-------- lib/draw/PathMap.js | 32 +- .../replace-preview/BpmnReplacePreview.js | 12 +- package.json | 5 +- .../custom-elements/CustomRenderer.js | 42 +- test/spec/ModelerSpec.js | 2 +- test/spec/draw/BpmnRendererSpec.js | 6 +- .../spec/features/modeling/LabelBoundsSpec.js | 5 +- .../behavior/ReplaceElementBehaviourSpec.js | 4 +- .../replace-preview/BpmnReplacePreviewSpec.js | 32 +- test/spec/import/elements/LabelSpec.js | 6 +- 12 files changed, 452 insertions(+), 284 deletions(-) diff --git a/lib/Viewer.js b/lib/Viewer.js index 521abdc3..775d59eb 100644 --- a/lib/Viewer.js +++ b/lib/Viewer.js @@ -15,6 +15,8 @@ var domify = require('min-dom/lib/domify'), domQuery = require('min-dom/lib/query'), domRemove = require('min-dom/lib/remove'); +var innerSVG = require('tiny-svg/lib/innerSVG'); + var Diagram = require('diagram-js'), BpmnModdle = require('bpmn-moddle'); @@ -230,10 +232,10 @@ Viewer.prototype.saveSVG = function(options, done) { var canvas = this.get('canvas'); var contentNode = canvas.getDefaultLayer(), - defsNode = canvas._svg.select('defs'); + defsNode = domQuery('defs', canvas._svg); - var contents = contentNode.innerSVG(), - defs = (defsNode && defsNode.outerSVG()) || ''; + var contents = innerSVG(contentNode), + defs = (defsNode && defsNode.outerHTML) || ''; var bbox = contentNode.getBBox(); @@ -472,4 +474,4 @@ function addProjectLogo(container) { }); } -/* */ \ No newline at end of file +/* */ diff --git a/lib/draw/BpmnRenderer.js b/lib/draw/BpmnRenderer.js index de761d43..6fda3ed2 100644 --- a/lib/draw/BpmnRenderer.js +++ b/lib/draw/BpmnRenderer.js @@ -19,13 +19,23 @@ var RenderUtil = require('diagram-js/lib/util/RenderUtil'); var componentsToPath = RenderUtil.componentsToPath, createLine = RenderUtil.createLine; +var domClasses = require('min-dom/lib/classes'), + domQuery = require('min-dom/lib/query'); + +var svgAppend = require('tiny-svg/lib/append'), + svgAttr = require('tiny-svg/lib/attr'), + svgCreate = require('tiny-svg/lib/create'); + +var rotate = require('diagram-js/lib/util/SvgTransformUtil').rotate, + transform = require('diagram-js/lib/util/SvgTransformUtil').transform, + translate = require('diagram-js/lib/util/SvgTransformUtil').translate; var TASK_BORDER_RADIUS = 10; var INNER_OUTER_DIST = 3; var LABEL_STYLE = { fontFamily: 'Arial, sans-serif', - fontSize: '12px' + fontSize: 12 }; @@ -47,7 +57,9 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } function marker(id) { - return markers[id]; + var marker = markers[id]; + + return 'url(#' + marker.id + ')'; } function initMarkers(svg) { @@ -70,26 +82,49 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { attrs.strokeDasharray = [10000, 1]; } - var marker = options.element - .attr(attrs) - .marker(0, 0, 20, 20, ref.x, ref.y) - .attr({ - markerWidth: 20 * scale, - markerHeight: 20 * scale - }); + var marker = svgCreate('marker'); + + svgAttr(options.element, attrs); + + svgAppend(marker, options.element); + + svgAttr(marker, { + id: id, + viewBox: '0 0 20 20', + refX: ref.x, + refY: ref.y, + markerWidth: 20 * scale, + markerHeight: 20 * scale, + orient: 'auto' + }); + + var defs = domQuery('defs', svg); + + if (!defs) { + defs = svgCreate('defs'); + + svgAppend(svg, defs); + } + + svgAppend(defs, marker); return addMarker(id, marker); } + var sequenceflowEnd = svgCreate('path'); + svgAttr(sequenceflowEnd, { d: 'M 1 5 L 11 10 L 1 15 Z' }); createMarker('sequenceflow-end', { - element: svg.path('M 1 5 L 11 10 L 1 15 Z'), + element: sequenceflowEnd, ref: { x: 11, y: 10 }, scale: 0.5 }); + var messageflowStart = svgCreate('circle'); + svgAttr(messageflowStart, { cx: 6, cy: 6, r: 3.5 }); + createMarker('messageflow-start', { - element: svg.circle(6, 6, 3.5), + element: messageflowStart, attrs: { fill: 'white', stroke: 'black' @@ -97,8 +132,11 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { ref: { x: 6, y: 6 } }); + var messageflowEnd = svgCreate('path'); + svgAttr(messageflowEnd, { d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z' }); + createMarker('messageflow-end', { - element: svg.path('m 1 5 l 0 -3 l 7 3 l -7 3 z'), + element: messageflowEnd, attrs: { fill: 'white', stroke: 'black', @@ -107,8 +145,11 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { ref: { x: 8.5, y: 5 } }); + var associationStart = svgCreate('path'); + svgAttr(associationStart, { d: 'M 11 5 L 1 10 L 11 15' }); + createMarker('association-start', { - element: svg.path('M 11 5 L 1 10 L 11 15'), + element: associationStart, attrs: { fill: 'none', stroke: 'black', @@ -118,8 +159,11 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { scale: 0.5 }); + var associationEnd = svgCreate('path'); + svgAttr(associationEnd, { d: 'M 1 5 L 11 10 L 1 15' }); + createMarker('association-end', { - element: svg.path('M 1 5 L 11 10 L 1 15'), + element: associationEnd, attrs: { fill: 'none', stroke: 'black', @@ -129,8 +173,11 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { scale: 0.5 }); + var conditionalflowMarker = svgCreate('path'); + svgAttr(conditionalflowMarker, { d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z' }); + createMarker('conditional-flow-marker', { - element: svg.path('M 0 10 L 8 6 L 16 10 L 8 14 Z'), + element: conditionalflowMarker, attrs: { fill: 'white', stroke: 'black' @@ -139,8 +186,11 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { scale: 0.5 }); + var conditionaldefaultflowMarker = svgCreate('path'); + svgAttr(conditionaldefaultflowMarker, { d: 'M 1 4 L 5 16' }); + createMarker('conditional-default-flow-marker', { - element: svg.path('M 1 4 L 5 16'), + element: conditionaldefaultflowMarker, attrs: { stroke: 'black' }, @@ -149,7 +199,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { }); } - function drawCircle(p, width, height, offset, attrs) { + function drawCircle(parentGfx, width, height, offset, attrs) { if (isObject(offset)) { attrs = offset; @@ -167,10 +217,20 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var cx = width / 2, cy = height / 2; - return p.circle(cx, cy, Math.round((width + height) / 4 - offset)).attr(attrs); + var circle = svgCreate('circle'); + svgAttr(circle, { + cx: cx, + cy: cy, + r: Math.round((width + height) / 4 - offset) + }); + svgAttr(circle, attrs); + + svgAppend(parentGfx, circle); + + return circle; } - function drawRect(p, width, height, r, offset, attrs) { + function drawRect(parentGfx, width, height, r, offset, attrs) { if (isObject(offset)) { attrs = offset; @@ -185,15 +245,32 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { fill: 'white' }); - return p.rect(offset, offset, width - offset * 2, height - offset * 2, r).attr(attrs); + var rect = svgCreate('rect'); + svgAttr(rect, { + x: offset, + y: offset, + width: width - offset * 2, + height: height - offset * 2, + rx: r, + ry: r + }); + svgAttr(rect, attrs); + + svgAppend(parentGfx, rect); + + return rect; } - function drawDiamond(p, width, height, attrs) { + function drawDiamond(parentGfx, width, height, attrs) { var x_2 = width / 2; var y_2 = height / 2; - var points = [x_2, 0, width, y_2, x_2, height, 0, y_2 ]; + var points = [{ x: x_2, y: 0 }, { x: width, y: y_2 }, { x: x_2, y: height }, { x: 0, y: y_2 }]; + + var pointsString = points.map(function(point) { + return point.x + ',' + point.y; + }).join(' '); attrs = computeStyle(attrs, { stroke: 'black', @@ -201,36 +278,54 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { fill: 'white' }); - return p.polygon(points).attr(attrs); + var polygon = svgCreate('polygon'); + svgAttr(polygon, { + points: pointsString + }); + svgAttr(polygon, attrs); + + svgAppend(parentGfx, polygon); + + return polygon; } - function drawLine(p, waypoints, attrs) { + function drawLine(parentGfx, waypoints, attrs) { attrs = computeStyle(attrs, [ 'no-fill' ], { stroke: 'black', strokeWidth: 2, fill: 'none' }); - return createLine(waypoints, attrs).appendTo(p); + var line = createLine(waypoints, attrs); + + svgAppend(parentGfx, line); + + return line; } - function drawPath(p, d, attrs) { + function drawPath(parentGfx, d, attrs) { attrs = computeStyle(attrs, [ 'no-fill' ], { strokeWidth: 2, stroke: 'black' }); - return p.path(d).attr(attrs); + var path = svgCreate('path'); + svgAttr(path, { d: d }); + svgAttr(path, attrs); + + svgAppend(parentGfx, path); + + return path; } - function drawMarker(type, p, path, attrs) { - return drawPath(p, path, assign({ 'data-marker': type }, attrs)); + function drawMarker(type, parentGfx, path, attrs) { + return drawPath(parentGfx, path, assign({ 'data-marker': type }, attrs)); } function as(type) { - return function(p, element) { - return handlers[type](p, element); + return function(parentGfx, element) { + return handlers[type](parentGfx, element); }; } @@ -238,74 +333,77 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { return handlers[type]; } - function renderEventContent(element, p) { + function renderEventContent(element, parentGfx) { var event = getSemantic(element); var isThrowing = isThrowEvent(event); if (isTypedEvent(event, 'bpmn:MessageEventDefinition')) { - return renderer('bpmn:MessageEventDefinition')(p, element, isThrowing); + return renderer('bpmn:MessageEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:TimerEventDefinition')) { - return renderer('bpmn:TimerEventDefinition')(p, element, isThrowing); + return renderer('bpmn:TimerEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:ConditionalEventDefinition')) { - return renderer('bpmn:ConditionalEventDefinition')(p, element); + return renderer('bpmn:ConditionalEventDefinition')(parentGfx, element); } if (isTypedEvent(event, 'bpmn:SignalEventDefinition')) { - return renderer('bpmn:SignalEventDefinition')(p, element, isThrowing); + return renderer('bpmn:SignalEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:CancelEventDefinition') && isTypedEvent(event, 'bpmn:TerminateEventDefinition', { parallelMultiple: false })) { - return renderer('bpmn:MultipleEventDefinition')(p, element, isThrowing); + return renderer('bpmn:MultipleEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:CancelEventDefinition') && isTypedEvent(event, 'bpmn:TerminateEventDefinition', { parallelMultiple: true })) { - return renderer('bpmn:ParallelMultipleEventDefinition')(p, element, isThrowing); + return renderer('bpmn:ParallelMultipleEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:EscalationEventDefinition')) { - return renderer('bpmn:EscalationEventDefinition')(p, element, isThrowing); + return renderer('bpmn:EscalationEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:LinkEventDefinition')) { - return renderer('bpmn:LinkEventDefinition')(p, element, isThrowing); + return renderer('bpmn:LinkEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:ErrorEventDefinition')) { - return renderer('bpmn:ErrorEventDefinition')(p, element, isThrowing); + return renderer('bpmn:ErrorEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:CancelEventDefinition')) { - return renderer('bpmn:CancelEventDefinition')(p, element, isThrowing); + return renderer('bpmn:CancelEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:CompensateEventDefinition')) { - return renderer('bpmn:CompensateEventDefinition')(p, element, isThrowing); + return renderer('bpmn:CompensateEventDefinition')(parentGfx, element, isThrowing); } if (isTypedEvent(event, 'bpmn:TerminateEventDefinition')) { - return renderer('bpmn:TerminateEventDefinition')(p, element, isThrowing); + return renderer('bpmn:TerminateEventDefinition')(parentGfx, element, isThrowing); } return null; } - function renderLabel(p, label, options) { - return textUtil.createText(p, label || '', options).addClass('djs-label'); + function renderLabel(parentGfx, label, options) { + var text = textUtil.createText(parentGfx, label || '', options); + domClasses(text).add('djs-label'); + + return text; } - function renderEmbeddedLabel(p, element, align) { + function renderEmbeddedLabel(parentGfx, element, align) { var semantic = getSemantic(element); - return renderLabel(p, semantic.name, { box: element, align: align, padding: 5 }); + return renderLabel(parentGfx, semantic.name, { box: element, align: align, padding: 5 }); } - function renderExternalLabel(p, element) { + function renderExternalLabel(parentGfx, element) { var semantic = getSemantic(element); var box = { width: 90, @@ -314,20 +412,18 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { y: element.height / 2 + element.y }; - return renderLabel(p, semantic.name, { box: box, style: { fontSize: '11px' } }); + return renderLabel(parentGfx, semantic.name, { box: box, style: { fontSize: '11px' } }); } - function renderLaneLabel(p, text, element) { - var textBox = renderLabel(p, text, { + function renderLaneLabel(parentGfx, text, element) { + var textBox = renderLabel(parentGfx, text, { box: { height: 30, width: element.height }, align: 'center-middle' }); var top = -1 * element.height; - textBox.transform( - 'rotate(270) ' + - 'translate(' + top + ',' + 0 + ')' - ); + + transform(textBox, 0, -top, 270); } function createPathFromConnection(connection) { @@ -341,10 +437,10 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } var handlers = this.handlers = { - 'bpmn:Event': function(p, element, attrs) { - return drawCircle(p, element.width, element.height, attrs); + 'bpmn:Event': function(parentGfx, element, attrs) { + return drawCircle(parentGfx, element.width, element.height, attrs); }, - 'bpmn:StartEvent': function(p, element) { + 'bpmn:StartEvent': function(parentGfx, element) { var attrs = {}; var semantic = getSemantic(element); @@ -355,13 +451,13 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { }; } - var circle = renderer('bpmn:Event')(p, element, attrs); + var circle = renderer('bpmn:Event')(parentGfx, element, attrs); - renderEventContent(element, p); + renderEventContent(element, parentGfx); return circle; }, - 'bpmn:MessageEventDefinition': function(p, element, isThrowing) { + 'bpmn:MessageEventDefinition': function(parentGfx, element, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_MESSAGE', { xScaleFactor: 0.9, yScaleFactor: 0.9, @@ -376,7 +472,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var fill = isThrowing ? 'black' : 'white'; var stroke = isThrowing ? 'white' : 'black'; - var messagePath = drawPath(p, pathData, { + var messagePath = drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: stroke @@ -384,9 +480,9 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { return messagePath; }, - 'bpmn:TimerEventDefinition': function(p, element) { + 'bpmn:TimerEventDefinition': function(parentGfx, element) { - var circle = drawCircle(p, element.width, element.height, 0.2 * element.height, { + var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, { strokeWidth: 2 }); @@ -401,7 +497,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - drawPath(p, pathData, { + drawPath(parentGfx, pathData, { strokeWidth: 2, strokeLinecap: 'square' }); @@ -422,7 +518,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var width = element.width / 2; var height = element.height / 2; - drawPath(p, linePathData, { + drawPath(parentGfx, linePathData, { strokeWidth: 1, strokeLinecap: 'square', transform: 'rotate(' + (i * 30) + ',' + height + ',' + width + ')' @@ -431,7 +527,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { return circle; }, - 'bpmn:EscalationEventDefinition': function(p, event, isThrowing) { + 'bpmn:EscalationEventDefinition': function(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_ESCALATION', { xScaleFactor: 1, yScaleFactor: 1, @@ -445,12 +541,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var fill = isThrowing ? 'black' : 'none'; - return drawPath(p, pathData, { + return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill }); }, - 'bpmn:ConditionalEventDefinition': function(p, event) { + 'bpmn:ConditionalEventDefinition': function(parentGfx, event) { var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', { xScaleFactor: 1, yScaleFactor: 1, @@ -462,11 +558,11 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - return drawPath(p, pathData, { + return drawPath(parentGfx, pathData, { strokeWidth: 1 }); }, - 'bpmn:LinkEventDefinition': function(p, event, isThrowing) { + 'bpmn:LinkEventDefinition': function(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_LINK', { xScaleFactor: 1, yScaleFactor: 1, @@ -480,12 +576,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var fill = isThrowing ? 'black' : 'none'; - return drawPath(p, pathData, { + return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill }); }, - 'bpmn:ErrorEventDefinition': function(p, event, isThrowing) { + 'bpmn:ErrorEventDefinition': function(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_ERROR', { xScaleFactor: 1.1, yScaleFactor: 1.1, @@ -499,12 +595,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var fill = isThrowing ? 'black' : 'none'; - return drawPath(p, pathData, { + return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill }); }, - 'bpmn:CancelEventDefinition': function(p, event, isThrowing) { + 'bpmn:CancelEventDefinition': function(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', { xScaleFactor: 1.0, yScaleFactor: 1.0, @@ -518,12 +614,16 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var fill = isThrowing ? 'black' : 'none'; - return drawPath(p, pathData, { + var path = drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill - }).transform('rotate(45)'); + }); + + rotate(path, 45); + + return path; }, - 'bpmn:CompensateEventDefinition': function(p, event, isThrowing) { + 'bpmn:CompensateEventDefinition': function(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', { xScaleFactor: 1, yScaleFactor: 1, @@ -537,12 +637,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var fill = isThrowing ? 'black' : 'none'; - return drawPath(p, pathData, { + return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill }); }, - 'bpmn:SignalEventDefinition': function(p, event, isThrowing) { + 'bpmn:SignalEventDefinition': function(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_SIGNAL', { xScaleFactor: 0.9, yScaleFactor: 0.9, @@ -556,12 +656,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var fill = isThrowing ? 'black' : 'none'; - return drawPath(p, pathData, { + return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill }); }, - 'bpmn:MultipleEventDefinition': function(p, event, isThrowing) { + 'bpmn:MultipleEventDefinition': function(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', { xScaleFactor: 1.1, yScaleFactor: 1.1, @@ -575,12 +675,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var fill = isThrowing ? 'black' : 'none'; - return drawPath(p, pathData, { + return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill }); }, - 'bpmn:ParallelMultipleEventDefinition': function(p, event) { + 'bpmn:ParallelMultipleEventDefinition': function(parentGfx, event) { var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', { xScaleFactor: 1.2, yScaleFactor: 1.2, @@ -592,50 +692,50 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - return drawPath(p, pathData, { + return drawPath(parentGfx, pathData, { strokeWidth: 1 }); }, - 'bpmn:EndEvent': function(p, element) { - var circle = renderer('bpmn:Event')(p, element, { + 'bpmn:EndEvent': function(parentGfx, element) { + var circle = renderer('bpmn:Event')(parentGfx, element, { strokeWidth: 4 }); - renderEventContent(element, p, true); + renderEventContent(element, parentGfx, true); return circle; }, - 'bpmn:TerminateEventDefinition': function(p, element) { - var circle = drawCircle(p, element.width, element.height, 8, { + 'bpmn:TerminateEventDefinition': function(parentGfx, element) { + var circle = drawCircle(parentGfx, element.width, element.height, 8, { strokeWidth: 4, fill: 'black' }); return circle; }, - 'bpmn:IntermediateEvent': function(p, element) { - var outer = renderer('bpmn:Event')(p, element, { strokeWidth: 1 }); - /* inner */ drawCircle(p, element.width, element.height, INNER_OUTER_DIST, { strokeWidth: 1, fill: 'none' }); + 'bpmn:IntermediateEvent': function(parentGfx, element) { + var outer = renderer('bpmn:Event')(parentGfx, element, { strokeWidth: 1 }); + /* inner */ drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, { strokeWidth: 1, fill: 'none' }); - renderEventContent(element, p); + renderEventContent(element, parentGfx); return outer; }, 'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'), 'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'), - 'bpmn:Activity': function(p, element, attrs) { - return drawRect(p, element.width, element.height, TASK_BORDER_RADIUS, attrs); + 'bpmn:Activity': function(parentGfx, element, attrs) { + return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, attrs); }, - 'bpmn:Task': function(p, element, attrs) { - var rect = renderer('bpmn:Activity')(p, element, attrs); - renderEmbeddedLabel(p, element, 'center-middle'); - attachTaskMarkers(p, element); + 'bpmn:Task': function(parentGfx, element, attrs) { + var rect = renderer('bpmn:Activity')(parentGfx, element, attrs); + renderEmbeddedLabel(parentGfx, element, 'center-middle'); + attachTaskMarkers(parentGfx, element); return rect; }, - 'bpmn:ServiceTask': function(p, element) { - var task = renderer('bpmn:Task')(p, element); + 'bpmn:ServiceTask': function(parentGfx, element) { + var task = renderer('bpmn:Task')(parentGfx, element); var pathDataBG = pathMap.getScaledPath('TASK_TYPE_SERVICE', { abspos: { @@ -644,7 +744,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* service bg */ drawPath(p, pathDataBG, { + /* service bg */ drawPath(parentGfx, pathDataBG, { strokeWidth: 1, fill: 'none' }); @@ -656,7 +756,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* service fill */ drawPath(p, fillPathData, { + /* service fill */ drawPath(parentGfx, fillPathData, { strokeWidth: 0, stroke: 'none', fill: 'white' @@ -669,15 +769,15 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* service */ drawPath(p, pathData, { + /* service */ drawPath(parentGfx, pathData, { strokeWidth: 1, fill: 'white' }); return task; }, - 'bpmn:UserTask': function(p, element) { - var task = renderer('bpmn:Task')(p, element); + 'bpmn:UserTask': function(parentGfx, element) { + var task = renderer('bpmn:Task')(parentGfx, element); var x = 15; var y = 12; @@ -689,7 +789,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* user path */ drawPath(p, pathData, { + /* user path */ drawPath(parentGfx, pathData, { strokeWidth: 0.5, fill: 'none' }); @@ -701,7 +801,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* user2 path */ drawPath(p, pathData2, { + /* user2 path */ drawPath(parentGfx, pathData2, { strokeWidth: 0.5, fill: 'none' }); @@ -713,15 +813,15 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* user3 path */ drawPath(p, pathData3, { + /* user3 path */ drawPath(parentGfx, pathData3, { strokeWidth: 0.5, fill: 'black' }); return task; }, - 'bpmn:ManualTask': function(p, element) { - var task = renderer('bpmn:Task')(p, element); + 'bpmn:ManualTask': function(parentGfx, element) { + var task = renderer('bpmn:Task')(parentGfx, element); var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', { abspos: { @@ -730,7 +830,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* manual path */ drawPath(p, pathData, { + /* manual path */ drawPath(parentGfx, pathData, { strokeWidth: 0.25, fill: 'white', stroke: 'black' @@ -738,8 +838,8 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { return task; }, - 'bpmn:SendTask': function(p, element) { - var task = renderer('bpmn:Task')(p, element); + 'bpmn:SendTask': function(parentGfx, element) { + var task = renderer('bpmn:Task')(parentGfx, element); var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', { xScaleFactor: 1, @@ -752,7 +852,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* send path */ drawPath(p, pathData, { + /* send path */ drawPath(parentGfx, pathData, { strokeWidth: 1, fill: 'black', stroke: 'white' @@ -760,14 +860,14 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { return task; }, - 'bpmn:ReceiveTask' : function(p, element) { + 'bpmn:ReceiveTask' : function(parentGfx, element) { var semantic = getSemantic(element); - var task = renderer('bpmn:Task')(p, element); + var task = renderer('bpmn:Task')(parentGfx, element); var pathData; if (semantic.instantiate) { - drawCircle(p, 28, 28, 20 * 0.22, { strokeWidth: 1 }); + drawCircle(28, 28, 20 * 0.22, { strokeWidth: 1 }); pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', { abspos: { @@ -789,14 +889,14 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { }); } - /* receive path */ drawPath(p, pathData, { + /* receive path */ drawPath(parentGfx, pathData, { strokeWidth: 1 }); return task; }, - 'bpmn:ScriptTask': function(p, element) { - var task = renderer('bpmn:Task')(p, element); + 'bpmn:ScriptTask': function(parentGfx, element) { + var task = renderer('bpmn:Task')(parentGfx, element); var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', { abspos: { @@ -805,14 +905,14 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* script path */ drawPath(p, pathData, { + /* script path */ drawPath(parentGfx, pathData, { strokeWidth: 1 }); return task; }, - 'bpmn:BusinessRuleTask': function(p, element) { - var task = renderer('bpmn:Task')(p, element); + 'bpmn:BusinessRuleTask': function(parentGfx, element) { + var task = renderer('bpmn:Task')(parentGfx, element); var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', { abspos: { @@ -821,8 +921,8 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - var businessHeaderPath = drawPath(p, headerPathData); - businessHeaderPath.attr({ + var businessHeaderPath = drawPath(parentGfx, headerPathData); + svgAttr(businessHeaderPath, { strokeWidth: 1, fill: 'AAA' }); @@ -834,59 +934,59 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - var businessPath = drawPath(p, headerData); - businessPath.attr({ + var businessPath = drawPath(parentGfx, headerData); + svgAttr(businessPath, { strokeWidth: 1 }); return task; }, - 'bpmn:SubProcess': function(p, element, attrs) { + 'bpmn:SubProcess': function(parentGfx, element, attrs) { attrs = assign({ fillOpacity: 0.95 }, attrs); - var rect = renderer('bpmn:Activity')(p, element, attrs); + var rect = renderer('bpmn:Activity')(parentGfx, element, attrs); var expanded = DiUtil.isExpanded(element); var isEventSubProcess = DiUtil.isEventSubProcess(element); if (isEventSubProcess) { - rect.attr({ + svgAttr(rect, { strokeDasharray: '1,2' }); } - renderEmbeddedLabel(p, element, expanded ? 'center-top' : 'center-middle'); + renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle'); if (expanded) { - attachTaskMarkers(p, element); + attachTaskMarkers(parentGfx, element); } else { - attachTaskMarkers(p, element, ['SubProcessMarker']); + attachTaskMarkers(parentGfx, element, ['SubProcessMarker']); } return rect; }, - 'bpmn:AdHocSubProcess': function(p, element) { - return renderer('bpmn:SubProcess')(p, element); + 'bpmn:AdHocSubProcess': function(parentGfx, element) { + return renderer('bpmn:SubProcess')(parentGfx, element); }, - 'bpmn:Transaction': function(p, element) { - var outer = renderer('bpmn:SubProcess')(p, element); + 'bpmn:Transaction': function(parentGfx, element) { + var outer = renderer('bpmn:SubProcess')(parentGfx, element); var innerAttrs = styles.style([ 'no-fill', 'no-events' ]); - /* inner path */ drawRect(p, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs); + /* inner path */ drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs); return outer; }, - 'bpmn:CallActivity': function(p, element) { - return renderer('bpmn:SubProcess')(p, element, { + 'bpmn:CallActivity': function(parentGfx, element) { + return renderer('bpmn:SubProcess')(parentGfx, element, { strokeWidth: 5 }); }, - 'bpmn:Participant': function(p, element) { + 'bpmn:Participant': function(parentGfx, element) { - var lane = renderer('bpmn:Lane')(p, element, { + var lane = renderer('bpmn:Lane')(parentGfx, element, { fillOpacity: 0.95, fill: 'White' }); @@ -894,28 +994,28 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { var expandedPool = DiUtil.isExpanded(element); if (expandedPool) { - drawLine(p, [ + drawLine(parentGfx, [ { x: 30, y: 0 }, { x: 30, y: element.height } ]); var text = getSemantic(element).name; - renderLaneLabel(p, text, element); + renderLaneLabel(parentGfx, text, element); } else { // Collapsed pool draw text inline var text2 = getSemantic(element).name; - renderLabel(p, text2, { box: element, align: 'center-middle' }); + renderLabel(parentGfx, text2, { box: element, align: 'center-middle' }); } var participantMultiplicity = !!(getSemantic(element).participantMultiplicity); if (participantMultiplicity) { - renderer('ParticipantMultiplicityMarker')(p, element); + renderer('ParticipantMultiplicityMarker')(parentGfx, element); } return lane; }, - 'bpmn:Lane': function(p, element, attrs) { - var rect = drawRect(p, element.width, element.height, 0, attrs || { + 'bpmn:Lane': function(parentGfx, element, attrs) { + var rect = drawRect(parentGfx, element.width, element.height, 0, attrs || { fill: 'none' }); @@ -923,24 +1023,24 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { if (semantic.$type === 'bpmn:Lane') { var text = semantic.name; - renderLaneLabel(p, text, element); + renderLaneLabel(parentGfx, text, element); } return rect; }, - 'bpmn:InclusiveGateway': function(p, element) { - var diamond = drawDiamond(p, element.width, element.height); + 'bpmn:InclusiveGateway': function(parentGfx, element) { + var diamond = drawDiamond(parentGfx, element.width, element.height); /* circle path */ - drawCircle(p, element.width, element.height, element.height * 0.24, { + drawCircle(parentGfx, element.width, element.height, element.height * 0.24, { strokeWidth: 2.5, fill: 'none' }); return diamond; }, - 'bpmn:ExclusiveGateway': function(p, element) { - var diamond = drawDiamond(p, element.width, element.height); + 'bpmn:ExclusiveGateway': function(parentGfx, element) { + var diamond = drawDiamond(parentGfx, element.width, element.height); var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', { xScaleFactor: 0.4, @@ -954,7 +1054,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { }); if ((getDi(element).isMarkerVisible)) { - drawPath(p, pathData, { + drawPath(parentGfx, pathData, { strokeWidth: 1, fill: 'black' }); @@ -962,8 +1062,8 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { return diamond; }, - 'bpmn:ComplexGateway': function(p, element) { - var diamond = drawDiamond(p, element.width, element.height); + 'bpmn:ComplexGateway': function(parentGfx, element) { + var diamond = drawDiamond(parentGfx, element.width, element.height); var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', { xScaleFactor: 0.5, @@ -976,15 +1076,15 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* complex path */ drawPath(p, pathData, { + /* complex path */ drawPath(parentGfx, pathData, { strokeWidth: 1, fill: 'black' }); return diamond; }, - 'bpmn:ParallelGateway': function(p, element) { - var diamond = drawDiamond(p, element.width, element.height); + 'bpmn:ParallelGateway': function(parentGfx, element) { + var diamond = drawDiamond(parentGfx, element.width, element.height); var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', { xScaleFactor: 0.6, @@ -997,20 +1097,20 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* parallel path */ drawPath(p, pathData, { + /* parallel path */ drawPath(parentGfx, pathData, { strokeWidth: 1, fill: 'black' }); return diamond; }, - 'bpmn:EventBasedGateway': function(p, element) { + 'bpmn:EventBasedGateway': function(parentGfx, element) { var semantic = getSemantic(element); - var diamond = drawDiamond(p, element.width, element.height); + var diamond = drawDiamond(parentGfx, element.width, element.height); - /* outer circle path */ drawCircle(p, element.width, element.height, element.height * 0.20, { + /* outer circle path */ drawCircle(parentGfx, element.width, element.height, element.height * 0.20, { strokeWidth: 1, fill: 'none' }); @@ -1031,7 +1131,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* event path */ drawPath(p, pathData, { + /* event path */ drawPath(parentGfx, pathData, { strokeWidth: 2, fill: 'none' }); @@ -1050,16 +1150,16 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - var parallelPath = drawPath(p, pathData); - parallelPath.attr({ + var parallelPath = drawPath(parentGfx, pathData); + svgAttr(parallelPath, { strokeWidth: 1, fill: 'none' }); } else if (type === 'Exclusive') { if (!instantiate) { - var innerCircle = drawCircle(p, element.width, element.height, element.height * 0.26); - innerCircle.attr({ + var innerCircle = drawCircle(parentGfx, element.width, element.height, element.height * 0.26); + svgAttr(innerCircle, { strokeWidth: 1, fill: 'none' }); @@ -1071,12 +1171,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { return diamond; }, - 'bpmn:Gateway': function(p, element) { - return drawDiamond(p, element.width, element.height); + 'bpmn:Gateway': function(parentGfx, element) { + return drawDiamond(parentGfx, element.width, element.height); }, - 'bpmn:SequenceFlow': function(p, element) { + 'bpmn:SequenceFlow': function(parentGfx, element) { var pathData = createPathFromConnection(element); - var path = drawPath(p, pathData, { + var path = drawPath(parentGfx, pathData, { strokeLinejoin: 'round', markerEnd: marker('sequenceflow-end') }); @@ -1086,7 +1186,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { // conditional flow marker if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Activity')) { - path.attr({ + svgAttr(path, { markerStart: marker('conditional-flow-marker') }); } @@ -1094,14 +1194,14 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { // default marker if (source.default && (source.$instanceOf('bpmn:Gateway') || source.$instanceOf('bpmn:Activity')) && source.default === sequenceFlow) { - path.attr({ + svgAttr(path, { markerStart: marker('conditional-default-flow-marker') }); } return path; }, - 'bpmn:Association': function(p, element, attrs) { + 'bpmn:Association': function(parentGfx, element, attrs) { var semantic = getSemantic(element); @@ -1120,25 +1220,25 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { attrs.markerStart = marker('association-start'); } - return drawLine(p, element.waypoints, attrs); + return drawLine(parentGfx, element.waypoints, attrs); }, - 'bpmn:DataInputAssociation': function(p, element) { - return renderer('bpmn:Association')(p, element, { + 'bpmn:DataInputAssociation': function(parentGfx, element) { + return renderer('bpmn:Association')(parentGfx, element, { markerEnd: marker('association-end') }); }, - 'bpmn:DataOutputAssociation': function(p, element) { - return renderer('bpmn:Association')(p, element, { + 'bpmn:DataOutputAssociation': function(parentGfx, element) { + return renderer('bpmn:Association')(parentGfx, element, { markerEnd: marker('association-end') }); }, - 'bpmn:MessageFlow': function(p, element) { + 'bpmn:MessageFlow': function(parentGfx, element) { var semantic = getSemantic(element), di = getDi(element); var pathData = createPathFromConnection(element); - var path = drawPath(p, pathData, { + var path = drawPath(parentGfx, pathData, { markerEnd: marker('messageflow-end'), markerStart: marker('messageflow-start'), strokeDasharray: '10, 12', @@ -1167,12 +1267,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { messageAttrs.stroke = 'white'; } - drawPath(p, markerPathData, messageAttrs); + drawPath(parentGfx, markerPathData, messageAttrs); } return path; }, - 'bpmn:DataObject': function(p, element) { + 'bpmn:DataObject': function(parentGfx, element) { var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', { xScaleFactor: 1, yScaleFactor: 1, @@ -1184,42 +1284,42 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - var elementObject = drawPath(p, pathData, { fill: 'white' }); + var elementObject = drawPath(parentGfx, pathData, { fill: 'white' }); var semantic = getSemantic(element); if (isCollection(semantic)) { - renderDataItemCollection(p, element); + renderDataItemCollection(parentGfx, element); } return elementObject; }, 'bpmn:DataObjectReference': as('bpmn:DataObject'), - 'bpmn:DataInput': function(p, element) { + 'bpmn:DataInput': function(parentGfx, element) { var arrowPathData = pathMap.getRawPath('DATA_ARROW'); // page - var elementObject = renderer('bpmn:DataObject')(p, element); + var elementObject = renderer('bpmn:DataObject')(parentGfx, element); - /* input arrow path */ drawPath(p, arrowPathData, { strokeWidth: 1 }); + /* input arrow path */ drawPath(parentGfx, arrowPathData, { strokeWidth: 1 }); return elementObject; }, - 'bpmn:DataOutput': function(p, element) { + 'bpmn:DataOutput': function(parentGfx, element) { var arrowPathData = pathMap.getRawPath('DATA_ARROW'); // page - var elementObject = renderer('bpmn:DataObject')(p, element); + var elementObject = renderer('bpmn:DataObject')(parentGfx, element); - /* output arrow path */ drawPath(p, arrowPathData, { + /* output arrow path */ drawPath(parentGfx, arrowPathData, { strokeWidth: 1, fill: 'black' }); return elementObject; }, - 'bpmn:DataStoreReference': function(p, element) { + 'bpmn:DataStoreReference': function(parentGfx, element) { var DATA_STORE_PATH = pathMap.getScaledPath('DATA_STORE', { xScaleFactor: 1, yScaleFactor: 1, @@ -1231,14 +1331,14 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - var elementStore = drawPath(p, DATA_STORE_PATH, { + var elementStore = drawPath(parentGfx, DATA_STORE_PATH, { strokeWidth: 2, fill: 'white' }); return elementStore; }, - 'bpmn:BoundaryEvent': function(p, element) { + 'bpmn:BoundaryEvent': function(parentGfx, element) { var semantic = getSemantic(element), cancel = semantic.cancelActivity; @@ -1252,26 +1352,26 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { attrs.strokeLinecap = 'round'; } - var outer = renderer('bpmn:Event')(p, element, attrs); - /* inner path */ drawCircle(p, element.width, element.height, INNER_OUTER_DIST, assign(attrs, { fill: 'none' })); + var outer = renderer('bpmn:Event')(parentGfx, element, attrs); + /* inner path */ drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, assign(attrs, { fill: 'none' })); - renderEventContent(element, p); + renderEventContent(element, parentGfx); return outer; }, - 'bpmn:Group': function(p, element) { - return drawRect(p, element.width, element.height, TASK_BORDER_RADIUS, { + 'bpmn:Group': function(parentGfx, element) { + return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, { strokeWidth: 1, strokeDasharray: '8,3,1,3', fill: 'none', pointerEvents: 'none' }); }, - 'label': function(p, element) { + 'label': function(parentGfx, element) { // Update external label size and bounds during rendering when // we have the actual rendered bounds anyway. - var textElement = renderExternalLabel(p, element); + var textElement = renderExternalLabel(parentGfx, element); var textBBox = textElement.getBBox(); @@ -1284,18 +1384,18 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { element.height = Math.ceil(textBBox.height); // compensate bounding box x - textElement.attr({ + svgAttr(textElement, { transform: 'translate(' + (-1 * textBBox.x) + ',0)' }); return textElement; }, - 'bpmn:TextAnnotation': function(p, element) { + 'bpmn:TextAnnotation': function(parentGfx, element) { var style = { 'fill': 'none', 'stroke': 'none' }; - var textElement = drawRect(p, element.width, element.height, 0, 0, style); + var textElement = drawRect(parentGfx, element.width, element.height, 0, 0, style); var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', { xScaleFactor: 1, yScaleFactor: 1, @@ -1306,14 +1406,14 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { my: 0.0 } }); - drawPath(p, textPathData); + drawPath(parentGfx, textPathData); var text = getSemantic(element).text || ''; - renderLabel(p, text, { box: element, align: 'left-middle', padding: 5 }); + renderLabel(parentGfx, text, { box: element, align: 'left-middle', padding: 5 }); return textElement; }, - 'ParticipantMultiplicityMarker': function(p, element) { + 'ParticipantMultiplicityMarker': function(parentGfx, element) { var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', { xScaleFactor: 1, yScaleFactor: 1, @@ -1325,16 +1425,16 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - drawMarker('participant-multiplicity', p, markerPath); + drawMarker('participant-multiplicity', parentGfx, markerPath); }, - 'SubProcessMarker': function(p, element) { - var markerRect = drawRect(p, 14, 14, 0, { + 'SubProcessMarker': function(parentGfx, element) { + var markerRect = drawRect(parentGfx, 14, 14, 0, { strokeWidth: 1 }); // Process marker is placed in the middle of the box // therefore fixed values can be used here - markerRect.transform('translate(' + (element.width / 2 - 7.5) + ',' + (element.height - 20) + ')'); + translate(markerRect, element.width / 2 - 7.5, element.height - 20); var markerPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', { xScaleFactor: 1.5, @@ -1347,9 +1447,9 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - drawMarker('sub-process', p, markerPath); + drawMarker('sub-process', parentGfx, markerPath); }, - 'ParallelMarker': function(p, element, position) { + 'ParallelMarker': function(parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', { xScaleFactor: 1, yScaleFactor: 1, @@ -1361,9 +1461,9 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - drawMarker('parallel', p, markerPath); + drawMarker('parallel', parentGfx, markerPath); }, - 'SequentialMarker': function(p, element, position) { + 'SequentialMarker': function(parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', { xScaleFactor: 1, yScaleFactor: 1, @@ -1375,9 +1475,9 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - drawMarker('sequential', p, markerPath); + drawMarker('sequential', parentGfx, markerPath); }, - 'CompensationMarker': function(p, element, position) { + 'CompensationMarker': function(parentGfx, element, position) { var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', { xScaleFactor: 1, yScaleFactor: 1, @@ -1389,9 +1489,9 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - drawMarker('compensation', p, markerMath, { strokeWidth: 1 }); + drawMarker('compensation', parentGfx, markerMath, { strokeWidth: 1 }); }, - 'LoopMarker': function(p, element, position) { + 'LoopMarker': function(parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_LOOP', { xScaleFactor: 1, yScaleFactor: 1, @@ -1403,14 +1503,14 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - drawMarker('loop', p, markerPath, { + drawMarker('loop', parentGfx, markerPath, { strokeWidth: 1, fill: 'none', strokeLinecap: 'round', strokeMiterlimit: 0.5 }); }, - 'AdhocMarker': function(p, element, position) { + 'AdhocMarker': function(parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_ADHOC', { xScaleFactor: 1, yScaleFactor: 1, @@ -1422,14 +1522,14 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - drawMarker('adhoc', p, markerPath, { + drawMarker('adhoc', parentGfx, markerPath, { strokeWidth: 1, fill: 'black' }); } }; - function attachTaskMarkers(p, element, taskMarkers) { + function attachTaskMarkers(parentGfx, element, taskMarkers) { var obj = getSemantic(element); var subprocess = includes(taskMarkers, 'SubProcessMarker'); @@ -1454,15 +1554,15 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } forEach(taskMarkers, function(marker) { - renderer(marker)(p, element, position); + renderer(marker)(parentGfx, element, position); }); if (obj.isForCompensation) { - renderer('CompensationMarker')(p, element, position); + renderer('CompensationMarker')(parentGfx, element, position); } if (obj.$type === 'bpmn:AdHocSubProcess') { - renderer('AdhocMarker')(p, element, position); + renderer('AdhocMarker')(parentGfx, element, position); } var loopCharacteristics = obj.loopCharacteristics, @@ -1471,20 +1571,20 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { if (loopCharacteristics) { if (isSequential === undefined) { - renderer('LoopMarker')(p, element, position); + renderer('LoopMarker')(parentGfx, element, position); } if (isSequential === false) { - renderer('ParallelMarker')(p, element, position); + renderer('ParallelMarker')(parentGfx, element, position); } if (isSequential === true) { - renderer('SequentialMarker')(p, element, position); + renderer('SequentialMarker')(parentGfx, element, position); } } } - function renderDataItemCollection(p, element) { + function renderDataItemCollection(parentGfx, element) { var yPosition = (element.height - 16) / element.height; @@ -1499,7 +1599,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) { } }); - /* collection path */ drawPath(p, pathData, { + /* collection path */ drawPath(parentGfx, pathData, { strokeWidth: 2 }); } @@ -1523,20 +1623,20 @@ BpmnRenderer.prototype.canRender = function(element) { return is(element, 'bpmn:BaseElement'); }; -BpmnRenderer.prototype.drawShape = function(visuals, element) { +BpmnRenderer.prototype.drawShape = function(parentGfx, element) { var type = element.type; var h = this.handlers[type]; /* jshint -W040 */ - return h(visuals, element); + return h(parentGfx, element); }; -BpmnRenderer.prototype.drawConnection = function(visuals, element) { +BpmnRenderer.prototype.drawConnection = function(parentGfx, element) { var type = element.type; var h = this.handlers[type]; /* jshint -W040 */ - return h(visuals, element); + return h(parentGfx, element); }; BpmnRenderer.prototype.getShapePath = function(element) { diff --git a/lib/draw/PathMap.js b/lib/draw/PathMap.js index fc816d81..88eb2db0 100644 --- a/lib/draw/PathMap.js +++ b/lib/draw/PathMap.js @@ -1,7 +1,5 @@ 'use strict'; -var Snap = require('diagram-js/vendor/snapsvg'); - /** * Map containing SVG paths needed by BpmnRenderer. */ @@ -438,7 +436,7 @@ function PathMap() { } //Apply value to raw path - var path = Snap.format( + var path = format( rawPath.d, { mx: mx, my: my, @@ -450,3 +448,31 @@ function PathMap() { } module.exports = PathMap; + +////////// helpers ////////// + +// copied from https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js +var tokenRegex = /\{([^\}]+)\}/g, + objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g; // matches .xxxxx or ["xxxxx"] to run over object properties + +function replacer(all, key, obj) { + var res = obj; + key.replace(objNotationRegex, function(all, name, quote, quotedName, isFunc) { + name = name || quotedName; + if (res) { + if (name in res) { + res = res[name]; + } + typeof res == 'function' && isFunc && (res = res()); + } + }); + res = (res == null || res == obj ? all : res) + ''; + + return res; +} + +function format(str, obj) { + return String(str).replace(tokenRegex, function(all, key) { + return replacer(all, key, obj); + }); +} diff --git a/lib/features/replace-preview/BpmnReplacePreview.js b/lib/features/replace-preview/BpmnReplacePreview.js index 8e9ec00c..a0cf5fe8 100644 --- a/lib/features/replace-preview/BpmnReplacePreview.js +++ b/lib/features/replace-preview/BpmnReplacePreview.js @@ -7,6 +7,10 @@ var inherits = require('inherits'); var assign = require('lodash/object/assign'), forEach = require('lodash/collection/forEach'); +var domQuery = require('min-dom/lib/query'); + +var svgAttr = require('tiny-svg/lib/attr'); + var LOW_PRIORITY = 250; function BpmnReplacePreview(eventBus, elementRegistry, elementFactory, canvas, previewSupport) { @@ -45,10 +49,10 @@ function BpmnReplacePreview(eventBus, elementRegistry, elementFactory, canvas, p canvas.addShape(tempShape, element.parent); // select the original SVG element related to the element and hide it - var gfx = context.dragGroup.select('[data-element-id=' + element.id + ']'); + var gfx = domQuery('[data-element-id=' + element.id + ']', context.dragGroup); if (gfx) { - gfx.attr({ display: 'none' }); + svgAttr(gfx, { display: 'none' }); } // clone the gfx of the temporary shape and add it to the drag group @@ -71,10 +75,10 @@ function BpmnReplacePreview(eventBus, elementRegistry, elementFactory, canvas, p forEach(visualReplacements, function(dragger, id) { - var originalGfx = context.dragGroup.select('[data-element-id=' + id + ']'); + var originalGfx = domQuery('[data-element-id=' + id + ']', context.dragGroup); if (originalGfx) { - originalGfx.attr({ display: 'inline' }); + svgAttr(originalGfx, { display: 'inline' }); } dragger.remove(); diff --git a/package.json b/package.json index 9034670a..fac4eb2f 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "load-grunt-tasks": "^0.3.0", "mocha": "^2.2.5", "mocha-test-container-support": "0.2.0", - "phantomjs": "^1.9.19", + "phantomjs": "^2.1.7", "sinon": "~1.14.1", "sinon-chai": "~2.7.0", "source-map-concat": "^1.0.0", @@ -79,6 +79,7 @@ "inherits": "^2.0.1", "lodash": "^3.0.1", "min-dom": "^0.2.0", - "object-refs": "^0.1.1" + "object-refs": "^0.1.1", + "tiny-svg": "0.0.1" } } diff --git a/test/integration/custom-elements/CustomRenderer.js b/test/integration/custom-elements/CustomRenderer.js index f0186b38..14c01545 100644 --- a/test/integration/custom-elements/CustomRenderer.js +++ b/test/integration/custom-elements/CustomRenderer.js @@ -6,6 +6,10 @@ var BaseRenderer = require('diagram-js/lib/draw/BaseRenderer'); var componentsToPath = require('diagram-js/lib/util/RenderUtil').componentsToPath; +var svgAppend = require('tiny-svg/lib/append'), + svgAttr = require('tiny-svg/lib/attr'), + svgCreate = require('tiny-svg/lib/create'); + function CustomRenderer(eventBus, styles) { @@ -18,19 +22,23 @@ function CustomRenderer(eventBus, styles) { var computeStyle = styles.computeStyle; this.handlers = { - 'custom:triangle': function(p, element) { - return self.drawTriangle(p, element.width); + 'custom:triangle': function(parentGfx, element) { + return self.drawTriangle(parentGfx, element.width); }, - 'custom:circle': function(p, element, attrs) { - return self.drawCircle(p, element.width, element.height, attrs); + 'custom:circle': function(parentGfx, element, attrs) { + return self.drawCircle(parentGfx, element.width, element.height, attrs); } }; - this.drawTriangle = function(p, side, attrs) { + this.drawTriangle = function(parentGfx, side, attrs) { var halfSide = side / 2, points; - points = [ halfSide, 0, side, side, 0, side ]; + points = [{ x: halfSide, y: 0 }, { x: side, y: side }, { x: 0, y: side }]; + + var pointsString = points.map(function(point) { + return point.x + ',' + point.y; + }).join(' '); attrs = computeStyle(attrs, { stroke: '#3CAA82', @@ -38,7 +46,13 @@ function CustomRenderer(eventBus, styles) { fill: '#3CAA82' }); - return p.polygon(points).attr(attrs); + var polygon = svgCreate('polygon'); + svgAttr(polygon, { points: pointsString }); + svgAttr(polygon, attrs); + + svgAppend(parentGfx, polygon); + + return polygon; }; this.getTrianglePath = function(element) { @@ -57,7 +71,7 @@ function CustomRenderer(eventBus, styles) { return componentsToPath(trianglePath); }; - this.drawCircle = function(p, width, height, attrs) { + this.drawCircle = function(parentGfx, width, height, attrs) { var cx = width / 2, cy = height / 2; @@ -67,7 +81,17 @@ function CustomRenderer(eventBus, styles) { fill: 'white' }); - return p.circle(cx, cy, Math.round((width + height) / 4)).attr(attrs); + var circle = svgCreate('circle'); + svgAttr(circle, { + cx: cx, + cy: cy, + r: Math.round((width + height) / 4) + }); + svgAttr(circle, attrs); + + svgAppend(parentGfx, circle); + + return circle; }; this.getCirclePath = function(shape) { diff --git a/test/spec/ModelerSpec.js b/test/spec/ModelerSpec.js index 00966938..fba17547 100644 --- a/test/spec/ModelerSpec.js +++ b/test/spec/ModelerSpec.js @@ -40,7 +40,7 @@ describe('Modeler', function() { }); - it.skip('should import complex', function(done) { + it.only('should import complex', function(done) { var xml = require('../fixtures/bpmn/complex.bpmn'); createModeler(xml, done); }); diff --git a/test/spec/draw/BpmnRendererSpec.js b/test/spec/draw/BpmnRendererSpec.js index aa9cbaf0..2aa9fa9d 100644 --- a/test/spec/draw/BpmnRendererSpec.js +++ b/test/spec/draw/BpmnRendererSpec.js @@ -5,6 +5,8 @@ require('../../TestHelper'); var coreModule = require('../../../lib/core'), rendererModule = require('../../../lib/draw'); +var domQuery = require('min-dom/lib/query'); + /* global bootstrapViewer, bootstrapModeler, inject */ @@ -174,7 +176,7 @@ describe('draw - bpmn renderer', function() { var callActivityGfx = elementRegistry.getGraphics('CallActivity'); // make sure the + marker is shown - expect(callActivityGfx.select('[data-marker=sub-process]')).to.exist; + expect(domQuery('[data-marker=sub-process]', callActivityGfx)).to.exist; done(); })(); @@ -197,7 +199,7 @@ describe('draw - bpmn renderer', function() { var callActivityGfx = elementRegistry.getGraphics('AdHocSubProcess'); // make sure the + marker is shown - expect(callActivityGfx.select('[data-marker=adhoc]')).to.exist; + expect(domQuery('[data-marker=adhoc]', callActivityGfx)).to.exist; done(); })(); diff --git a/test/spec/features/modeling/LabelBoundsSpec.js b/test/spec/features/modeling/LabelBoundsSpec.js index 621f5260..36143e54 100644 --- a/test/spec/features/modeling/LabelBoundsSpec.js +++ b/test/spec/features/modeling/LabelBoundsSpec.js @@ -6,6 +6,9 @@ var Modeler = require('../../../../lib/Modeler'); var TestContainer = require('mocha-test-container-support'); +var domQuery = require('min-dom/lib/query'); + + describe('label bounds', function() { function createModeler(xml, done) { @@ -198,7 +201,7 @@ describe('label bounds', function() { // given var shape = elementRegistry.get('StartEvent_1'), gfx = elementRegistry.getGraphics('StartEvent_1_label'), - hit = gfx.select('.djs-hit'); + hit = domQuery('.djs-hit', gfx); var interactionEventSpy = sinon.spy(hit, 'attr'), rendererSpy = sinon.spy(bpmnRenderer, 'drawShape'); diff --git a/test/spec/features/modeling/behavior/ReplaceElementBehaviourSpec.js b/test/spec/features/modeling/behavior/ReplaceElementBehaviourSpec.js index 2ccdd2a1..b95054ad 100644 --- a/test/spec/features/modeling/behavior/ReplaceElementBehaviourSpec.js +++ b/test/spec/features/modeling/behavior/ReplaceElementBehaviourSpec.js @@ -12,6 +12,8 @@ var replacePreviewModule = require('../../../../../lib/features/replace-preview' var is = require('../../../../../lib/util/ModelUtil').is, canvasEvent = require('../../../../util/MockEvents').createCanvasEvent; +var domQuery = require('min-dom/lib/query'); + describe('features/modeling - move start event behavior', function() { @@ -437,7 +439,7 @@ describe('features/modeling - move start event behavior', function() { // then var gfx = elementRegistry.getGraphics(subProcess); - var outline = gfx.select('.djs-outline'); + var outline = domQuery('.djs-outline', gfx); expect(outline.getBBox().width).to.equal(gfx.getBBox().width); expect(outline.getBBox().height).to.equal(gfx.getBBox().height); diff --git a/test/spec/features/replace-preview/BpmnReplacePreviewSpec.js b/test/spec/features/replace-preview/BpmnReplacePreviewSpec.js index 02feddcf..35de0783 100644 --- a/test/spec/features/replace-preview/BpmnReplacePreviewSpec.js +++ b/test/spec/features/replace-preview/BpmnReplacePreviewSpec.js @@ -12,6 +12,10 @@ var canvasEvent = require('../../../util/MockEvents').createCanvasEvent; var assign = require('lodash/object/assign'); +var svgAttr = require('tiny-svg/lib/attr'), + svgClone = require('tiny-svg/lib/clone'), + innerSVG = require('tiny-svg/lib/innerSVG'); + describe('features/replace-preview', function() { @@ -46,7 +50,7 @@ describe('features/replace-preview', function() { canvas.addShape(tempShape, rootElement); - var gfx = elementRegistry.getGraphics(tempShape).clone(); + var gfx = svgClone(elementRegistry.getGraphics(tempShape)); canvas.removeShape(tempShape); @@ -77,9 +81,9 @@ describe('features/replace-preview', function() { // then var dragGroup = dragging.context().data.context.dragGroup; - dragGroup[0].attr('display', 'inline'); + svgAttr(dragGroup.childNodes[0], 'display', 'inline'); - expect(dragGroup[0].getBBox()).to.eql(dragGroup[1].getBBox()); + expect(dragGroup.childNodes[0].getBBox()).to.eql(dragGroup.childNodes[1].getBBox()); })); @@ -124,7 +128,7 @@ describe('features/replace-preview', function() { // then var dragGroup = dragging.context().data.context.dragGroup; - expect(dragGroup[0].attr('display')).to.equal('none'); + expect(svgAttr(dragGroup.childNodes[0], 'display')).to.equal('none'); })); @@ -147,7 +151,7 @@ describe('features/replace-preview', function() { eventDefinitionType: 'bpmn:MessageEventDefinition' }); - expect(context.dragGroup[0].innerSVG()).to.equal(startEventGfx.innerSVG()); + expect(innerSVG(context.dragGroup.childNodes[0])).to.equal(innerSVG(startEventGfx)); }) ); @@ -164,7 +168,7 @@ describe('features/replace-preview', function() { // check if the visual replacement is a blank interrupting start event var startEventGfx = getGfx({ type: 'bpmn:StartEvent' }); - expect(context.dragGroup[1].innerSVG()).to.equal(startEventGfx.innerSVG()); + expect(innerSVG(context.dragGroup.childNodes[1])).to.equal(innerSVG(startEventGfx)); }) ); @@ -188,7 +192,7 @@ describe('features/replace-preview', function() { eventDefinitionType: 'bpmn:MessageEventDefinition' }); - expect(context.dragGroup[0].innerSVG()).to.equal(startEventGfx.innerSVG()); + expect(innerSVG(context.dragGroup.childNodes[0])).to.equal(innerSVG(startEventGfx)); }) ); @@ -208,7 +212,7 @@ describe('features/replace-preview', function() { // check if the visual representation remains a non interrupting message start event var startEventGfx = getGfx({ type: 'bpmn:StartEvent' }); - expect(context.dragGroup[1].innerSVG()).to.equal(startEventGfx.innerSVG()); + expect(innerSVG(context.dragGroup.childNodes[1])).to.equal(innerSVG(startEventGfx)); }) ); @@ -231,9 +235,9 @@ describe('features/replace-preview', function() { // check if the visual replacements are blank interrupting start events var startEventGfx = getGfx({ type: 'bpmn:StartEvent' }); - expect(context.dragGroup[1].innerSVG()).to.equal(startEventGfx.innerSVG()); - expect(context.dragGroup[3].innerSVG()).to.equal(startEventGfx.innerSVG()); - expect(context.dragGroup[4].innerSVG()).to.equal(startEventGfx.innerSVG()); + expect(innerSVG(context.dragGroup.childNodes[1])).to.equal(innerSVG(startEventGfx)); + expect(innerSVG(context.dragGroup.childNodes[3])).to.equal(innerSVG(startEventGfx)); + expect(innerSVG(context.dragGroup.childNodes[4])).to.equal(innerSVG(startEventGfx)); }) ); @@ -268,9 +272,9 @@ describe('features/replace-preview', function() { var context = dragging.context().data.context; // then - expect(context.dragGroup[0].innerSVG()).to.equal(messageStartEventGfx.innerSVG()); - expect(context.dragGroup[1].innerSVG()).to.equal(startEventGfx.innerSVG()); - expect(context.dragGroup[2].innerSVG()).to.equal(timerStartEventGfx.innerSVG()); + expect(innerSVG(context.dragGroup.childNodes[0])).to.equal(innerSVG(messageStartEventGfx)); + expect(innerSVG(context.dragGroup.childNodes[1])).to.equal(innerSVG(startEventGfx)); + expect(innerSVG(context.dragGroup.childNodes[2])).to.equal(innerSVG(timerStartEventGfx)); }) ); diff --git a/test/spec/import/elements/LabelSpec.js b/test/spec/import/elements/LabelSpec.js index 99ad4095..c24f5cb1 100644 --- a/test/spec/import/elements/LabelSpec.js +++ b/test/spec/import/elements/LabelSpec.js @@ -50,13 +50,13 @@ describe('import - labels', function() { // then expect(endEvent.label.x).to.be.within(236, 237); expect(endEvent.label.y).to.be.within(256, 256); - expect(endEvent.label.width).to.be.within(68, 69); + expect(endEvent.label.width).to.be.within(67, 69); expect(endEvent.label.height).to.be.within(23, 30); expect(sequenceFlow.label.x).to.be.within(441, 442); expect(sequenceFlow.label.y).to.be.within(316, 317); expect(sequenceFlow.label.width).to.be.within(79, 82); - expect(sequenceFlow.label.height).to.be.within(11, 15); + expect(sequenceFlow.label.height).to.be.within(12, 15); done(); })(); @@ -72,4 +72,4 @@ describe('import - labels', function() { }); -}); \ No newline at end of file +});