Skip to content

Commit fb887b1

Browse files
committed
add documentation
1 parent 2047b87 commit fb887b1

File tree

2 files changed

+72
-15
lines changed

2 files changed

+72
-15
lines changed

frontend/webEditor/src/commandPalette/commandPaletteProvider.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { LayoutMethod } from "../layout/layoutMethod";
1010
import { LayoutModelAction } from "../layout/command";
1111
import { SaveJsonFileAction } from "../serialize/saveJsonFile";
1212
import { SaveDfdAndDdFileAction } from "../serialize/saveDfdAndDdFile";
13-
import { SaveImageAction } from "../serialize/export";
13+
import { ExportAction } from "../serialize/export";
1414

1515
/**
1616
* Provides possible actions for the command palette.
@@ -47,10 +47,10 @@ export class WebEditorCommandPaletteActionProvider implements ICommandPaletteAct
4747
new FolderAction(
4848
"Export",
4949
[
50-
new LabeledAction("Export diagram as SVG", [SaveImageAction.create("svg", false)], "file-media"),
51-
new LabeledAction("Export selection as SVG", [SaveImageAction.create("svg", true)], "file-media"),
52-
new LabeledAction("Export diagram as PDF", [SaveImageAction.create("pdf", false)], "file-pdf"),
53-
new LabeledAction("Export selection as PDF", [SaveImageAction.create("pdf", true)], "file-pdf"),
50+
new LabeledAction("Export diagram as SVG", [ExportAction.create("svg", false)], "file-media"),
51+
new LabeledAction("Export selection as SVG", [ExportAction.create("svg", true)], "file-media"),
52+
new LabeledAction("Export diagram as PDF", [ExportAction.create("pdf", false)], "file-pdf"),
53+
new LabeledAction("Export selection as PDF", [ExportAction.create("pdf", true)], "file-pdf"),
5454
],
5555
"export",
5656
),

frontend/webEditor/src/serialize/export.ts

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ const patch = init([
3131
eventListenersModule, // attaches event listeners
3232
]);
3333

34-
interface SaveImageAction extends Action {
34+
interface ExportAction extends Action {
3535
saveType: "svg" | "pdf";
3636
selectionOnly: boolean;
3737
}
3838

39-
export namespace SaveImageAction {
39+
export namespace ExportAction {
4040
export const KIND = "save-image";
4141

42-
export function create(saveType: "svg" | "pdf", selectionOnly: boolean): SaveImageAction {
42+
export function create(saveType: "svg" | "pdf", selectionOnly: boolean): ExportAction {
4343
return {
4444
kind: KIND,
4545
saveType,
@@ -54,12 +54,15 @@ interface SVGResult {
5454
height: number;
5555
}
5656

57-
export class SaveImageCommand extends Command {
58-
static readonly KIND = SaveImageAction.KIND;
57+
/**
58+
* Exports the diagram as either a svg or pdf
59+
*/
60+
export class ExportCommand extends Command {
61+
static readonly KIND = ExportAction.KIND;
5962
private static readonly PADDING = 5;
6063

6164
constructor(
62-
@inject(TYPES.Action) private readonly action: SaveImageAction,
65+
@inject(TYPES.Action) private readonly action: ExportAction,
6366
@inject(FileName) private readonly fileName: FileName,
6467
@inject(TYPES.ViewRegistry) private readonly viewRegistry: ViewRegistry,
6568
@multiInject(TYPES.IVNodePostprocessor) private readonly postProcessors: IVNodePostprocessor[],
@@ -98,6 +101,11 @@ export class SaveImageCommand extends Command {
98101
return context.root;
99102
}
100103

104+
/**
105+
* Generates saveable svg code
106+
* @param dom A dummy root element attached to the Dom
107+
* @returns The generated svg
108+
*/
101109
getSVG(context: CommandExecutionContext, dom: HTMLElement): SVGResult | undefined {
102110
// render diagram virtually
103111
if (this.action.selectionOnly) {
@@ -147,11 +155,11 @@ export class SaveImageCommand extends Command {
147155
if (!holderG.data) holderG.data = {};
148156
if (!holderG.data.attrs) holderG.data.attrs = {};
149157
holderG.data.attrs["transform"] =
150-
`translate(${-minTranslate.x + SaveImageCommand.PADDING},${-minTranslate.y + SaveImageCommand.PADDING})`;
158+
`translate(${-minTranslate.x + ExportCommand.PADDING},${-minTranslate.y + ExportCommand.PADDING})`;
151159
if (!svg.data) svg.data = {};
152160
if (!svg.data.attrs) svg.data.attrs = {};
153-
const width = maxSize.x - minTranslate.x + 2 * SaveImageCommand.PADDING;
154-
const height = maxSize.y - minTranslate.y + 2 * SaveImageCommand.PADDING;
161+
const width = maxSize.x - minTranslate.x + 2 * ExportCommand.PADDING;
162+
const height = maxSize.y - minTranslate.y + 2 * ExportCommand.PADDING;
155163
svg.data.attrs.width = width;
156164
svg.data.attrs.height = height;
157165
svg.data.attrs.viewBox = `0 0 ${width} ${height}`;
@@ -189,6 +197,11 @@ export class SaveImageCommand extends Command {
189197
link.click();
190198
}
191199

200+
/**
201+
* Recursively removes the selected class
202+
* Should be called before rendering
203+
* @param v Root VNode
204+
*/
192205
private removeSelectedClass(v: VNode) {
193206
if (v.data?.class?.selected) {
194207
v.data.class.selected = false;
@@ -201,6 +214,12 @@ export class SaveImageCommand extends Command {
201214
}
202215
}
203216

217+
/**
218+
* Recursively removes the routing handles of edges.
219+
* Needs to happen before removing classes
220+
* @param v
221+
* @returns
222+
*/
204223
private removeRoutingHandles(v: VNode) {
205224
if (!v.children) return;
206225
v.children = v.children?.filter((c) => {
@@ -213,6 +232,10 @@ export class SaveImageCommand extends Command {
213232
}
214233
}
215234

235+
/**
236+
* Recursively transforms the computed style of the html elements to properties on the VNode
237+
* @param v The current VNode
238+
*/
216239
private transformStyleToAttributes(v: VNode) {
217240
if (!v.elm) return;
218241

@@ -263,6 +286,10 @@ export class SaveImageCommand extends Command {
263286
}
264287
}
265288

289+
/**
290+
* Recursively removes html attributes the svg file does not need.
291+
* @param v The current VNode
292+
*/
266293
private removeUnusedAttributes(v: VNode) {
267294
if (!v.data) v.data = {};
268295
if (v.data.attrs) {
@@ -282,6 +309,13 @@ export class SaveImageCommand extends Command {
282309
}
283310
}
284311

312+
/**
313+
* Recursively iterates the VNodes an centers the text position manually.
314+
* This should happen after transforming the style to attributes
315+
* @param v Current VNode
316+
* @param maxSiblingSize biggest size of siblings
317+
* @param maxSiblingX biggest x of siblings
318+
*/
285319
private centerText(v: VNode, maxSiblingSize: number = 0, maxSiblingX: number = 0) {
286320
if (getVNodeSVGType(v) == "text") {
287321
if (!v.data) v.data = {};
@@ -341,7 +375,6 @@ function getMinTranslate(e: VNode, parentOffset: { x: number; y: number } = { x:
341375

342376
/**
343377
* Calculates the absolute translation of an element relative to the svg.
344-
* If the element has no translation, the offset of the parent is returned.
345378
* @param e the element to get the translation from
346379
* @param parentOffset Offset of the containing element
347380
* @returns Offset of the child relative to the svg
@@ -363,6 +396,13 @@ function getTranslate(
363396
return { x: newX, y: newY };
364397
}
365398

399+
/**
400+
* Gets the maximum size the canvas needs by adding its position and size and finding the maximum of this among children.
401+
* This is done by recursively.
402+
* @param e the root element for the sizing
403+
* @param parentOffset Offset of the containing element
404+
* @returns Required canvas size
405+
*/
366406
function getMaxRequiredCanvasSize(
367407
e: VNode,
368408
parentOffset: { x: number; y: number } = { x: 0, y: 0 },
@@ -380,6 +420,12 @@ function getMaxRequiredCanvasSize(
380420
return maxSize;
381421
}
382422

423+
/**
424+
* Calculates the size the canvas needs to be to accommodate the given element
425+
* @param e the element to calculate for
426+
* @param parentOffset Offset of the containing element
427+
* @returns The size required for the element
428+
*/
383429
function getRequiredCanvasSize(
384430
e: VNode,
385431
parentOffset: { x: number; y: number } = { x: 0, y: 0 },
@@ -397,6 +443,10 @@ function getVNodeSVGType(v: VNode): string | undefined {
397443
return v.sel?.split(/#|\./)[0];
398444
}
399445

446+
/**
447+
* @param v VNode to check
448+
* @returns The relevant style properties for the node type
449+
*/
400450
function getRelevantStyleProps(v: VNode): string[] {
401451
const type = getVNodeSVGType(v);
402452
switch (type) {
@@ -418,6 +468,10 @@ function getRelevantStyleProps(v: VNode): string[] {
418468
}
419469
}
420470

471+
/**
472+
* @param key CSS key
473+
* @returns The default value for a given CSS key
474+
*/
421475
function getDefaultPropertyValues(key: string) {
422476
switch (key) {
423477
case "stroke-dasharray":
@@ -433,6 +487,9 @@ function getDefaultPropertyValues(key: string) {
433487
}
434488
}
435489

490+
/**
491+
* VNodePostprocessor removing all non-selected elements
492+
*/
436493
class SelectionPostProcessor implements IVNodePostprocessor {
437494
decorate(v: VNode, element: SModelElementImpl): VNode {
438495
let shouldRender = this.isSelected(element);

0 commit comments

Comments
 (0)