UNPKG

bpmn-js

Version:

A bpmn 2.0 toolkit and web modeler

152 lines (120 loc) 3.51 kB
import { assign, forEach, isString, pick } from 'min-dash'; import { getDi, isAny } from '../../../util/ModelUtil'; import { isLabel } from '../../../util/LabelUtil'; var DEFAULT_COLORS = { fill: undefined, stroke: undefined }; export default function SetColorHandler(commandStack) { this._commandStack = commandStack; this._normalizeColor = function(color) { // Remove color for falsy values. if (!color) { return undefined; } if (isString(color)) { var hexColor = colorToHex(color); if (hexColor) { return hexColor; } } throw new Error('invalid color value: ' + color); }; } SetColorHandler.$inject = [ 'commandStack' ]; SetColorHandler.prototype.postExecute = function(context) { var elements = context.elements, colors = context.colors || DEFAULT_COLORS; var self = this; var di = {}; if ('fill' in colors) { assign(di, { 'background-color': this._normalizeColor(colors.fill) }); } if ('stroke' in colors) { assign(di, { 'border-color': this._normalizeColor(colors.stroke) }); } forEach(elements, function(element) { var assignedDi = isConnection(element) ? pick(di, [ 'border-color' ]) : di, elementDi = getDi(element); // TODO @barmac: remove once we drop bpmn.io properties ensureLegacySupport(assignedDi); if (isLabel(element)) { // set label colors as bpmndi:BPMNLabel#color self._commandStack.execute('element.updateModdleProperties', { element: element, moddleElement: elementDi.label, properties: { color: di['border-color'] } }); } else { // ignore non-compliant di if (!isAny(elementDi, [ 'bpmndi:BPMNEdge', 'bpmndi:BPMNShape' ])) { return; } // set colors bpmndi:BPMNEdge or bpmndi:BPMNShape self._commandStack.execute('element.updateProperties', { element: element, properties: { di: assignedDi } }); } }); }; /** * Convert color from rgb(a)/hsl to hex. Returns `null` for unknown color names and for colors * with alpha less than 1.0. This depends on `<canvas>` serialization of the `context.fillStyle`. * Cf. https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-fillstyle * * @example * ```js * var color = 'fuchsia'; * console.log(colorToHex(color)); * // "#ff00ff" * color = 'rgba(1,2,3,0.4)'; * console.log(colorToHex(color)); * // null * ``` * * @param {string} color * @returns {string|null} */ function colorToHex(color) { var context = document.createElement('canvas').getContext('2d'); // (0) Start with transparent to account for browser default values. context.fillStyle = 'transparent'; // (1) Assign color so that it's serialized. context.fillStyle = color; // (2) Return null for non-hex serialization result. return /^#[0-9a-fA-F]{6}$/.test(context.fillStyle) ? context.fillStyle : null; } function isConnection(element) { return !!element.waypoints; } /** * Add legacy properties if required. * @param {{ 'border-color': string?, 'background-color': string? }} di */ function ensureLegacySupport(di) { if ('border-color' in di) { di.stroke = di['border-color']; } if ('background-color' in di) { di.fill = di['background-color']; } }