BPMN

@tiptap-pro/extension-diagrams/bpmn draws diagrams stored as BPMN 2.0 XML with bpmn-js, and connects the bpmn-js modeler for changing them. It draws no charts.
Pro ExtensionAlphaPilot program
New tab

Quick start

import { Diagrams } from '@tiptap-pro/extension-diagrams'
import { bpmnDiagramRenderer } from '@tiptap-pro/extension-diagrams/bpmn'
import rendererUrl from '@tiptap-pro/extension-diagrams/bpmn-renderer?url&no-inline'
import viewerUrl from 'bpmn-js/dist/bpmn-viewer.production.min.js?url&no-inline'

Diagrams.configure({
  diagramRenderers: [bpmnDiagramRenderer({ viewerUrl, rendererUrl })],
})

editor.commands.insertFlowDiagram({ source: bpmnXml, format: 'bpmn', title: 'Payment check' })
  • bpmn-js is not a dependency of the package.
  • Install it yourself and serve its bundles as files.
  • Its licence is yours to accept.

Options

OptionTypeDescription
viewerUrlstringRequired. A bpmn-js bundle: bpmn-js/dist/bpmn-viewer.production.min.js. The modeler bundle works too
rendererUrlstringRequired. @tiptap-pro/extension-diagrams/bpmn-renderer, served as a file. With Vite, ?url&no-inline
scriptNoncestring | nullFor pages with a nonce-based Content Security Policy
idstringDefault 'bpmn'
labelstringDefault 'BPMN'

How it draws

  • bpmn-js runs in one iframe per page, with sandbox="allow-scripts" and a policy that allows no network request.
  • The iframe is laid out off screen, because bpmn-js measures labels while it draws.
  • It loads the first time a BPMN diagram is drawn.
  • A drawing is cached by source.
  • Layout: the XML must carry its layout (BPMN DI), as a modeler saves it. A process without one does not draw.
  • Colors: a diagram is drawn black on white, on a page of its own. The --tt-flow-diagram-* properties do not reach it.
  • In a PNG, WebP, JPEG or Word export labels are SVG text, so the file looks like the picture in the editor.
  • On a server a BPMN diagram cannot be exported. bpmn-js lays out text in a browser.

The bpmn.io attribution

  • The Renderer's rules ask for the bpmn.io attribution: a "Powered by bpmn.io" link with the bpmn.io logo.
  • It is shown below the picture in the editor and drawn into every exported file.
  • An integration can add to the rules with rendererRules, but not remove the attribution.

What a BPMN source is

  • The root is definitions in the namespace http://www.omg.org/spec/BPMN/20100524/MODEL, under any prefix.
  • The file is closed.
  • It is stored as written, layout included. Only a byte-order mark and the white space around it are removed.
  • Empty source is allowed, for a process still to be modeled.
  • Pasting BPMN XML as text gives a BPMN diagram.
  • detectDiagramInput returns { kind: 'bpmn' } for it.

insertFlowDiagram and updateFlowDiagram return false for anything else, and for source longer than 1,000,000 characters.

Editing in the modeler

connectBpmnEditor runs the bpmn-js modeler in an iframe you created and opens a diagram in it. You build the dialog, the iframe and the buttons; the package fills the iframe, sandboxes it with scripts only, and hands back the XML when you ask for it.

import { connectBpmnEditor } from '@tiptap-pro/extension-diagrams/bpmn'
import rendererUrl from '@tiptap-pro/extension-diagrams/bpmn-renderer?url&no-inline'
import fontUrl from 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css?url&no-inline'
import bpmnStyleUrl from 'bpmn-js/dist/assets/bpmn-js.css?url&no-inline'
import diagramStyleUrl from 'bpmn-js/dist/assets/diagram-js.css?url&no-inline'
import modelerUrl from 'bpmn-js/dist/bpmn-modeler.production.min.js?url&no-inline'

const frame = document.createElement('iframe')
dialog.append(frame)

const connection = connectBpmnEditor(frame, {
  modelerUrl,
  rendererUrl,
  styleUrls: [diagramStyleUrl, bpmnStyleUrl, fontUrl],
  source: diagram.source,
  onReady: () => (saveButton.disabled = false),
})

saveButton.onclick = async () => {
  const source = await connection.save()
  editor.commands.updateFlowDiagram({ pos, source, format: 'bpmn' })
  connection.destroy()
  dialog.close()
}

connectBpmnEditor(frame, options)

OptionTypeDescription
modelerUrlstringRequired. The bpmn-js modeler bundle, bpmn-js/dist/bpmn-modeler.production.min.js
rendererUrlstringRequired. @tiptap-pro/extension-diagrams/bpmn-renderer, the same file the Renderer uses
styleUrlsreadonly string[]Required. The modeler's stylesheets: diagram-js.css, bpmn-js.css and bpmn-font/css/bpmn-embedded.css
scriptNoncestring | nullFor pages with a nonce-based Content Security Policy
sourcestringThe BPMN XML to open. Empty opens a new process with a start event
onReady()() => voidThe diagram is open and can be edited
onChange()() => voidCalled after every change in the modeler
onError(message)(message) => voidThe modeler did not load, or could not open the source

It returns { save, destroy }:

FunctionReturns
save()A Promise of the diagram as it is now, as BPMN XML. It rejects when the modeler sends something that is not BPMN
destroy()Nothing. Stops listening and empties the iframe; the iframe stays yours
  • Fonts of the modeler must come from data: or from the origin of a stylesheet, so use the embedded font stylesheet.
  • The modeler works on a copy: changes others make to the same diagram while it is open are replaced by the next save.