@formicoidea/labre-framework-uml 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +384 -0
- package/dist/actions.d.ts +430 -0
- package/dist/actions.js +724 -0
- package/dist/background.d.ts +153 -0
- package/dist/background.js +557 -0
- package/dist/board-hit.d.ts +137 -0
- package/dist/board-hit.js +191 -0
- package/dist/commands-manifest.d.ts +19 -0
- package/dist/commands-manifest.js +571 -0
- package/dist/commands.d.ts +4 -0
- package/dist/commands.js +983 -0
- package/dist/component.d.ts +521 -0
- package/dist/component.js +708 -0
- package/dist/consts.d.ts +365 -0
- package/dist/consts.js +463 -0
- package/dist/descriptor.d.ts +12 -0
- package/dist/descriptor.js +10 -0
- package/dist/drawio-decode.d.ts +32 -0
- package/dist/drawio-decode.js +96 -0
- package/dist/drawio-import.d.ts +133 -0
- package/dist/drawio-import.js +885 -0
- package/dist/edge-morph.d.ts +154 -0
- package/dist/edge-morph.js +153 -0
- package/dist/edge-styles.d.ts +78 -0
- package/dist/edge-styles.js +210 -0
- package/dist/effects.d.ts +9 -0
- package/dist/effects.js +6 -0
- package/dist/element-renderer.d.ts +64 -0
- package/dist/element-renderer.js +114 -0
- package/dist/element-view.d.ts +234 -0
- package/dist/element-view.js +430 -0
- package/dist/export.d.ts +61 -0
- package/dist/export.js +41 -0
- package/dist/filename.d.ts +17 -0
- package/dist/filename.js +26 -0
- package/dist/frame-tag.d.ts +70 -0
- package/dist/frame-tag.js +78 -0
- package/dist/grammar.d.ts +695 -0
- package/dist/grammar.js +1436 -0
- package/dist/import.d.ts +306 -0
- package/dist/import.js +1270 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +67 -0
- package/dist/interchange.d.ts +125 -0
- package/dist/interchange.js +372 -0
- package/dist/keywords.d.ts +204 -0
- package/dist/keywords.js +361 -0
- package/dist/kinds.d.ts +73 -0
- package/dist/kinds.js +91 -0
- package/dist/legend.d.ts +30 -0
- package/dist/legend.js +255 -0
- package/dist/model.d.ts +862 -0
- package/dist/model.js +1316 -0
- package/dist/morph.d.ts +178 -0
- package/dist/morph.js +496 -0
- package/dist/node/act-glyphs.d.ts +30 -0
- package/dist/node/act-glyphs.js +142 -0
- package/dist/node/compartment-watcher.d.ts +107 -0
- package/dist/node/compartment-watcher.js +163 -0
- package/dist/node/fit.d.ts +85 -0
- package/dist/node/fit.js +129 -0
- package/dist/node/node-renderer.d.ts +49 -0
- package/dist/node/node-renderer.js +611 -0
- package/dist/node/node-view.d.ts +51 -0
- package/dist/node/node-view.js +89 -0
- package/dist/node/paint.d.ts +84 -0
- package/dist/node/paint.js +143 -0
- package/dist/node/sd-glyphs.d.ts +36 -0
- package/dist/node/sd-glyphs.js +79 -0
- package/dist/node/stm-glyphs.d.ts +22 -0
- package/dist/node/stm-glyphs.js +111 -0
- package/dist/node/tier-metrics.d.ts +38 -0
- package/dist/node/tier-metrics.js +45 -0
- package/dist/operators.d.ts +45 -0
- package/dist/operators.js +75 -0
- package/dist/plantuml-import.d.ts +113 -0
- package/dist/plantuml-import.js +1723 -0
- package/dist/plantuml.d.ts +94 -0
- package/dist/plantuml.js +985 -0
- package/dist/presets.d.ts +149 -0
- package/dist/presets.js +302 -0
- package/dist/profiles.d.ts +2 -0
- package/dist/profiles.js +358 -0
- package/dist/reading.d.ts +160 -0
- package/dist/reading.js +648 -0
- package/dist/roles.d.ts +257 -0
- package/dist/roles.js +997 -0
- package/dist/rules.d.ts +267 -0
- package/dist/rules.js +3090 -0
- package/dist/templates.d.ts +2 -0
- package/dist/templates.js +197 -0
- package/dist/toolbar/config.d.ts +228 -0
- package/dist/toolbar/config.js +833 -0
- package/dist/toolbar/icons.d.ts +440 -0
- package/dist/toolbar/icons.js +711 -0
- package/dist/toolbar/senior-tool.d.ts +11 -0
- package/dist/toolbar/senior-tool.js +21 -0
- package/dist/toolbar/uml-menu.d.ts +17 -0
- package/dist/toolbar/uml-menu.js +20 -0
- package/dist/toolbar/uml-senior-button.d.ts +18 -0
- package/dist/toolbar/uml-senior-button.js +22 -0
- package/dist/translations.d.ts +27 -0
- package/dist/translations.js +117 -0
- package/dist/view.d.ts +33 -0
- package/dist/view.js +236 -0
- package/dist/xmi-import.d.ts +174 -0
- package/dist/xmi-import.js +2268 -0
- package/dist/xmi.d.ts +61 -0
- package/dist/xmi.js +1860 -0
- package/dist/xml-reader.d.ts +157 -0
- package/dist/xml-reader.js +430 -0
- package/dist/xml.d.ts +72 -0
- package/dist/xml.js +96 -0
- package/package.json +38 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UML's seat on the edgeless senior row.
|
|
3
|
+
*
|
|
4
|
+
* No `order:` — like every other framework. The row IS the registration order
|
|
5
|
+
* of the flag-gated view extensions in `packages/affine/all/src/extensions/
|
|
6
|
+
* view.ts`, which follows `FRAMEWORK_DESCRIPTORS`; declaring an order here
|
|
7
|
+
* would make the stable sort start mattering and break that premise. Pinned by
|
|
8
|
+
* `all/src/__tests__/toolbar/senior-row-order.unit.spec.ts`, which reads this
|
|
9
|
+
* very file.
|
|
10
|
+
*/
|
|
11
|
+
export declare const umlSeniorTool: import("@formicoidea/labre-core/store").ExtensionType;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SeniorToolExtension } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* UML's seat on the edgeless senior row.
|
|
5
|
+
*
|
|
6
|
+
* No `order:` — like every other framework. The row IS the registration order
|
|
7
|
+
* of the flag-gated view extensions in `packages/affine/all/src/extensions/
|
|
8
|
+
* view.ts`, which follows `FRAMEWORK_DESCRIPTORS`; declaring an order here
|
|
9
|
+
* would make the stable sort start mattering and break that premise. Pinned by
|
|
10
|
+
* `all/src/__tests__/toolbar/senior-row-order.unit.spec.ts`, which reads this
|
|
11
|
+
* very file.
|
|
12
|
+
*/
|
|
13
|
+
export const umlSeniorTool = SeniorToolExtension('uml', ({ block }) => {
|
|
14
|
+
return {
|
|
15
|
+
name: 'UML',
|
|
16
|
+
labelKey: 'com.labre.framework.uml',
|
|
17
|
+
content: html `<edgeless-uml-senior-button
|
|
18
|
+
.edgeless=${block}
|
|
19
|
+
></edgeless-uml-senior-button>`,
|
|
20
|
+
};
|
|
21
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EmptyTool } from '@formicoidea/labre-core/gfx/pointer';
|
|
2
|
+
import { EdgelessCommandMenu } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
|
|
3
|
+
/**
|
|
4
|
+
* The popover above the toolbar for the UML toolbox. It declares nothing:
|
|
5
|
+
* {@link EdgelessCommandMenu} renders `umlCommands` for the `senior-menu`
|
|
6
|
+
* surface (`docs/adr/0008`).
|
|
7
|
+
*
|
|
8
|
+
* UML is past the fourteen-slot cap — twenty-one catalogue entries — so what
|
|
9
|
+
* this popover actually renders is the arbitrated thirteen plus the permanent
|
|
10
|
+
* "More artefacts…" button. That is the menu's own business, not this class's:
|
|
11
|
+
* `selectSeniorMenuCommands` does the ranking, and `commands.ts` documents the
|
|
12
|
+
* order it ranks from.
|
|
13
|
+
*/
|
|
14
|
+
export declare class EdgelessUmlMenu extends EdgelessCommandMenu {
|
|
15
|
+
protected owner: "uml";
|
|
16
|
+
type: typeof EmptyTool;
|
|
17
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EmptyTool } from '@formicoidea/labre-core/gfx/pointer';
|
|
2
|
+
import { EdgelessCommandMenu } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
|
|
3
|
+
/**
|
|
4
|
+
* The popover above the toolbar for the UML toolbox. It declares nothing:
|
|
5
|
+
* {@link EdgelessCommandMenu} renders `umlCommands` for the `senior-menu`
|
|
6
|
+
* surface (`docs/adr/0008`).
|
|
7
|
+
*
|
|
8
|
+
* UML is past the fourteen-slot cap — twenty-one catalogue entries — so what
|
|
9
|
+
* this popover actually renders is the arbitrated thirteen plus the permanent
|
|
10
|
+
* "More artefacts…" button. That is the menu's own business, not this class's:
|
|
11
|
+
* `selectSeniorMenuCommands` does the ranking, and `commands.ts` documents the
|
|
12
|
+
* order it ranks from.
|
|
13
|
+
*/
|
|
14
|
+
export class EdgelessUmlMenu extends EdgelessCommandMenu {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.owner = 'uml';
|
|
18
|
+
this.type = EmptyTool;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DddSeniorButtonBase } from '@formicoidea/labre-ddd-shared';
|
|
2
|
+
/**
|
|
3
|
+
* Main toolbar button (the class-box-and-ellipse tile) that opens the UML
|
|
4
|
+
* toolbox sub-menu above the toolbar.
|
|
5
|
+
*
|
|
6
|
+
* It reuses the shared senior-button base rather than restating the
|
|
7
|
+
* toggle/popper wiring a seventh time. The base lives in `ddd-shared` because
|
|
8
|
+
* the three DDD buttons were the first to need it and it was lifted out of them
|
|
9
|
+
* — the class itself knows nothing about DDD: it is a glyph, a tooltip key and
|
|
10
|
+
* a menu tag, which is the entirety of what a senior button is.
|
|
11
|
+
*/
|
|
12
|
+
export declare class EdgelessUmlSeniorButton extends DddSeniorButtonBase {
|
|
13
|
+
protected menuTag: "edgeless-uml-menu";
|
|
14
|
+
protected owner: "uml";
|
|
15
|
+
protected label: string;
|
|
16
|
+
protected labelKey: string;
|
|
17
|
+
protected icon: import("lit-html").TemplateResult<2>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DddSeniorButtonBase } from '@formicoidea/labre-ddd-shared';
|
|
2
|
+
import { umlToolbarIcon } from './icons.js';
|
|
3
|
+
/**
|
|
4
|
+
* Main toolbar button (the class-box-and-ellipse tile) that opens the UML
|
|
5
|
+
* toolbox sub-menu above the toolbar.
|
|
6
|
+
*
|
|
7
|
+
* It reuses the shared senior-button base rather than restating the
|
|
8
|
+
* toggle/popper wiring a seventh time. The base lives in `ddd-shared` because
|
|
9
|
+
* the three DDD buttons were the first to need it and it was lifted out of them
|
|
10
|
+
* — the class itself knows nothing about DDD: it is a glyph, a tooltip key and
|
|
11
|
+
* a menu tag, which is the entirety of what a senior button is.
|
|
12
|
+
*/
|
|
13
|
+
export class EdgelessUmlSeniorButton extends DddSeniorButtonBase {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(...arguments);
|
|
16
|
+
this.menuTag = 'edgeless-uml-menu';
|
|
17
|
+
this.owner = 'uml';
|
|
18
|
+
this.label = 'UML';
|
|
19
|
+
this.labelKey = 'com.labre.framework.uml';
|
|
20
|
+
this.icon = umlToolbarIcon;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type TranslationKeyManifestEntry } from '@formicoidea/labre-core/std';
|
|
2
|
+
/**
|
|
3
|
+
* THIS framework's contribution to the translation-key manifest — every
|
|
4
|
+
* `com.labre.*` key UML can hand to `TranslationProvider.t`, derived from the
|
|
5
|
+
* very declarations the editor registers (never restated).
|
|
6
|
+
*
|
|
7
|
+
* The contribution ships WITH the framework, exactly as C4's and BPMN's do: in
|
|
8
|
+
* the bundled distribution `@formicoidea/labre-framework-uml` carries it, and a
|
|
9
|
+
* host composes it into its catalogue the same way it already composes
|
|
10
|
+
* `umlCommands` into the command registry. See
|
|
11
|
+
* `packages/affine/all/src/translations.ts`.
|
|
12
|
+
*
|
|
13
|
+
* The two BACKGROUND declarations are walked even though neither carries a
|
|
14
|
+
* `labelKey` today: both frames write the user's own words (a diagram's
|
|
15
|
+
* heading, a subject's name) and have no vocabulary to fall back to. Walking
|
|
16
|
+
* them costs nothing and means the day one of them gains a declared label the
|
|
17
|
+
* manifest already names it — which is the whole reason these lists are derived
|
|
18
|
+
* rather than written.
|
|
19
|
+
*
|
|
20
|
+
* The RULES and the two PROFILES are walked after the roles and the backgrounds,
|
|
21
|
+
* and the order is load-bearing: a rule carries its framework's `roles` and, for
|
|
22
|
+
* `uml.actor-inside-subject`, the subject's own declaration, so walking the pack
|
|
23
|
+
* reaches keys those lists already named. `mergeTranslationEntries` keeps the
|
|
24
|
+
* FIRST occurrence, which is what makes each key report the source it actually
|
|
25
|
+
* comes from.
|
|
26
|
+
*/
|
|
27
|
+
export declare const umlTranslationEntries: TranslationKeyManifestEntry[];
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { collectTranslationKeys, commandCategoryTranslationEntries, commandTranslationEntries, mergeTranslationEntries, } from '@formicoidea/labre-core/std';
|
|
2
|
+
import { UML_DIAGRAM_FRAME, UML_SUBJECT_FRAME } from './background.js';
|
|
3
|
+
import { umlCommands } from './commands.js';
|
|
4
|
+
import { UML_DRAWIO_REMARKS } from './drawio-import.js';
|
|
5
|
+
import { UML_LAYOUT_REMARKS } from './import.js';
|
|
6
|
+
import { UML_ATTRIBUTES_SEED, UML_ATTRIBUTES_SEED_KEY, UML_NAME_SEED, UML_OPERATIONS_SEED, UML_OPERATIONS_SEED_KEY, UML_SLOTS_SEED, UML_SLOTS_SEED_KEY, umlSeedKey, } from './keywords.js';
|
|
7
|
+
import { UML_DIAGRAM_KIND_MENU } from './kinds.js';
|
|
8
|
+
import { UML_LEGEND_SECTION_WORDINGS } from './legend.js';
|
|
9
|
+
import { UML_FRAGMENT_OPERATOR_MENU } from './operators.js';
|
|
10
|
+
import { UML_PLANTUML_REMARKS } from './plantuml-import.js';
|
|
11
|
+
import { UML_PROFILES } from './profiles.js';
|
|
12
|
+
import { UML_READINGS } from './reading.js';
|
|
13
|
+
import { UML_ROLES } from './roles.js';
|
|
14
|
+
import { UML_RULES } from './rules.js';
|
|
15
|
+
import { UML_XMI_REMARKS } from './xmi-import.js';
|
|
16
|
+
/**
|
|
17
|
+
* The words a placed artefact is SEEDED with — its name compartment, and the
|
|
18
|
+
* three compartment lines a fresh classifier carries.
|
|
19
|
+
*
|
|
20
|
+
* Derived from {@link UML_NAME_SEED} itself, never restated: the fallback IS
|
|
21
|
+
* the very string the creation site used to write raw, mirroring BPMN's
|
|
22
|
+
* `seedEntries` exactly. The kinds the notation draws with no words
|
|
23
|
+
* (`UML_UNLABELLED_KINDS`, an empty seed) contribute no key — there is nothing
|
|
24
|
+
* to translate, and BPMN's own filter says the same thing one package over.
|
|
25
|
+
*
|
|
26
|
+
* `seed`, not `chrome`: unlike the section titles below, this text is WRITTEN
|
|
27
|
+
* INTO THE DOCUMENT and is the author's content from that moment on, so it is
|
|
28
|
+
* resolved once at placement (`actions.ts`) and never re-resolved.
|
|
29
|
+
*/
|
|
30
|
+
const seedEntries = () => [
|
|
31
|
+
...Object.entries(UML_NAME_SEED)
|
|
32
|
+
.filter(([, seed]) => seed !== '')
|
|
33
|
+
.map(([kind, seed]) => ({
|
|
34
|
+
key: umlSeedKey(kind),
|
|
35
|
+
fallback: seed,
|
|
36
|
+
source: 'seed',
|
|
37
|
+
})),
|
|
38
|
+
...[
|
|
39
|
+
[UML_ATTRIBUTES_SEED_KEY, UML_ATTRIBUTES_SEED],
|
|
40
|
+
[UML_OPERATIONS_SEED_KEY, UML_OPERATIONS_SEED],
|
|
41
|
+
[UML_SLOTS_SEED_KEY, UML_SLOTS_SEED],
|
|
42
|
+
].map(([key, fallback]) => ({ key, fallback, source: 'seed' })),
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* The auto-legend's own section titles ({@link UML_LEGEND_SECTION_WORDINGS})
|
|
46
|
+
* and the fixed-wording remarks the three readers and the materializer
|
|
47
|
+
* produce — chrome, not seeds: both are re-rendered every time the box is
|
|
48
|
+
* built or the report is drawn, never written into a document.
|
|
49
|
+
*
|
|
50
|
+
* Derived from the very tables the code reads (the fallback IS
|
|
51
|
+
* `UML_PLANTUML_REMARKS[…][1]`, never restated), so the wording a host is
|
|
52
|
+
* offered and the wording the library shows cannot drift. Mirrors BPMN's
|
|
53
|
+
* `importRemarkEntries` exactly, one table per reader instead of one.
|
|
54
|
+
*/
|
|
55
|
+
const chromeEntries = () => [
|
|
56
|
+
...UML_LEGEND_SECTION_WORDINGS,
|
|
57
|
+
...Object.values(UML_PLANTUML_REMARKS),
|
|
58
|
+
...Object.values(UML_XMI_REMARKS),
|
|
59
|
+
...Object.values(UML_DRAWIO_REMARKS),
|
|
60
|
+
...Object.values(UML_LAYOUT_REMARKS),
|
|
61
|
+
].map(([key, fallback]) => ({ key, fallback, source: 'chrome' }));
|
|
62
|
+
/**
|
|
63
|
+
* THIS framework's contribution to the translation-key manifest — every
|
|
64
|
+
* `com.labre.*` key UML can hand to `TranslationProvider.t`, derived from the
|
|
65
|
+
* very declarations the editor registers (never restated).
|
|
66
|
+
*
|
|
67
|
+
* The contribution ships WITH the framework, exactly as C4's and BPMN's do: in
|
|
68
|
+
* the bundled distribution `@formicoidea/labre-framework-uml` carries it, and a
|
|
69
|
+
* host composes it into its catalogue the same way it already composes
|
|
70
|
+
* `umlCommands` into the command registry. See
|
|
71
|
+
* `packages/affine/all/src/translations.ts`.
|
|
72
|
+
*
|
|
73
|
+
* The two BACKGROUND declarations are walked even though neither carries a
|
|
74
|
+
* `labelKey` today: both frames write the user's own words (a diagram's
|
|
75
|
+
* heading, a subject's name) and have no vocabulary to fall back to. Walking
|
|
76
|
+
* them costs nothing and means the day one of them gains a declared label the
|
|
77
|
+
* manifest already names it — which is the whole reason these lists are derived
|
|
78
|
+
* rather than written.
|
|
79
|
+
*
|
|
80
|
+
* The RULES and the two PROFILES are walked after the roles and the backgrounds,
|
|
81
|
+
* and the order is load-bearing: a rule carries its framework's `roles` and, for
|
|
82
|
+
* `uml.actor-inside-subject`, the subject's own declaration, so walking the pack
|
|
83
|
+
* reaches keys those lists already named. `mergeTranslationEntries` keeps the
|
|
84
|
+
* FIRST occurrence, which is what makes each key report the source it actually
|
|
85
|
+
* comes from.
|
|
86
|
+
*/
|
|
87
|
+
export const umlTranslationEntries = mergeTranslationEntries(commandTranslationEntries(umlCommands),
|
|
88
|
+
// The catalogue's own group headers, derived from the very categories these
|
|
89
|
+
// commands declare. They ship WITH the framework because core's registry
|
|
90
|
+
// names no framework category in the bundled distribution, so a host that
|
|
91
|
+
// composed core's manifest alone drew translated entries under English
|
|
92
|
+
// headers (#183).
|
|
93
|
+
commandCategoryTranslationEntries(umlCommands), collectTranslationKeys('role', UML_ROLES), collectTranslationKeys('background', [
|
|
94
|
+
UML_DIAGRAM_FRAME,
|
|
95
|
+
UML_SUBJECT_FRAME,
|
|
96
|
+
// Which of the four diagrams a frame declares it draws, and the words the
|
|
97
|
+
// picker offers them under. Filed under `background` with the two
|
|
98
|
+
// declarations above, and it is the honest bucket rather than a
|
|
99
|
+
// convenient one: `kind` is a prop of the diagram frame, these are the
|
|
100
|
+
// names of the values it can take, and the table is walked exactly as the
|
|
101
|
+
// two declarations beside it are.
|
|
102
|
+
UML_DIAGRAM_KIND_MENU,
|
|
103
|
+
// …and, since phase 3, which kind of COMBINED FRAGMENT a box declares it
|
|
104
|
+
// is (§17.6.4). Filed here with the diagram's own table and for the same
|
|
105
|
+
// reason: `operator` is a prop of a background element, these are the
|
|
106
|
+
// names of the values it can take, and the table is walked exactly as the
|
|
107
|
+
// three declarations beside it are.
|
|
108
|
+
UML_FRAGMENT_OPERATOR_MENU,
|
|
109
|
+
]), seedEntries(), chromeEntries(),
|
|
110
|
+
// AFTER the two groups above — see the header on why the order decides
|
|
111
|
+
// which source each key is reported under.
|
|
112
|
+
collectTranslationKeys('rule', UML_RULES), collectTranslationKeys('profile', UML_PROFILES),
|
|
113
|
+
// LAST, and the order is load-bearing: a reading profile carries the
|
|
114
|
+
// framework's own `roles`, so walking it reaches keys the list above
|
|
115
|
+
// already named. `mergeTranslationEntries` keeps the FIRST occurrence,
|
|
116
|
+
// which is what makes each key report the source it actually comes from.
|
|
117
|
+
collectTranslationKeys('reading', UML_READINGS));
|
package/dist/view.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ViewExtensionContext, ViewExtensionProvider } from '@formicoidea/labre-core/ext-loader';
|
|
2
|
+
/**
|
|
3
|
+
* UML rendering — ALWAYS registered, independent of any flag. Diagram frames,
|
|
4
|
+
* subjects and nodes already drawn must paint, stay selectable, stay editable
|
|
5
|
+
* and keep their resize gating whatever the tooling flag says. See
|
|
6
|
+
* `docs/adr/0009`.
|
|
7
|
+
*
|
|
8
|
+
* This is the RENDER half. The creation tooling — the senior button, its menu
|
|
9
|
+
* and its twenty-one commands — is {@link UmlViewExtension} below, exactly as
|
|
10
|
+
* `C4ViewExtension` is separate from `C4RenderViewExtension`. Nothing in this
|
|
11
|
+
* class may become flag-gated: a stored document needs every one of these
|
|
12
|
+
* registrations to load and paint.
|
|
13
|
+
*/
|
|
14
|
+
export declare class UmlRenderViewExtension extends ViewExtensionProvider {
|
|
15
|
+
name: string;
|
|
16
|
+
setup(context: ViewExtensionContext): void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* UML creation tooling — flag-gated (`uml`): the senior toolbar button, its
|
|
20
|
+
* sub-menu, the twenty-one commands behind them, its templates category, the
|
|
21
|
+
* frame's legend button and kind picker, the reading profiles and the two
|
|
22
|
+
* interchange capabilities.
|
|
23
|
+
*
|
|
24
|
+
* All of it is tooling in the sense `docs/adr/0009` means: a diagram drawn
|
|
25
|
+
* while the flag was on keeps painting, stays selectable and keeps its
|
|
26
|
+
* contextual toolbar when it goes off — only the ways to add new elements go
|
|
27
|
+
* away, the legend included since generating one CREATES elements.
|
|
28
|
+
*/
|
|
29
|
+
export declare class UmlViewExtension extends ViewExtensionProvider {
|
|
30
|
+
name: string;
|
|
31
|
+
effect(): void;
|
|
32
|
+
setup(context: ViewExtensionContext): void;
|
|
33
|
+
}
|
package/dist/view.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { FrameworkBackgroundInteractionExtension, InterchangeExtension, morphToolbarConfig, ReadingProfileExtension, ValidationProfileExtension, ValidationRuleExtension, } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
import { ViewExtensionProvider, } from '@formicoidea/labre-core/ext-loader';
|
|
3
|
+
import { TemplateCategoryExtension } from '@formicoidea/labre-core/gfx/template';
|
|
4
|
+
import { ToolbarModuleExtension, toolbarModuleKey, } from '@formicoidea/labre-core/shared/services';
|
|
5
|
+
import { BlockFlavourIdentifier, CommandExtension } from '@formicoidea/labre-core/std';
|
|
6
|
+
import { RoleVocabularyExtension } from '@formicoidea/labre-core/std/gfx';
|
|
7
|
+
import { UML_DIAGRAM_FRAME, UML_FRAGMENT_FRAME, UML_PARTITION_FRAME_V, UML_REGION_FRAME, UML_SUBJECT_FRAME, } from './background.js';
|
|
8
|
+
import { umlCommandIcons, umlCommands } from './commands.js';
|
|
9
|
+
import { UML_EDGE_MORPH_SPEC } from './edge-morph.js';
|
|
10
|
+
import { effects } from './effects.js';
|
|
11
|
+
import { UmlDiagramRendererExtension, UmlFragmentRendererExtension, UmlPartitionRendererExtension, UmlRegionRendererExtension, UmlSubjectRendererExtension, } from './element-renderer.js';
|
|
12
|
+
import { UmlDiagramView, UmlFragmentView, UmlPartitionView, UmlRegionView, UmlSubjectView, } from './element-view.js';
|
|
13
|
+
import { UML_INTERCHANGE } from './interchange.js';
|
|
14
|
+
import { UML_BARE_MORPH_SPEC, UML_MORPH_SPEC } from './morph.js';
|
|
15
|
+
import { UmlCompartmentWatcher } from './node/compartment-watcher.js';
|
|
16
|
+
import { UmlNodeRendererExtension } from './node/node-renderer.js';
|
|
17
|
+
import { UmlNodeView } from './node/node-view.js';
|
|
18
|
+
import { UML_PROFILES } from './profiles.js';
|
|
19
|
+
import { UML_READINGS } from './reading.js';
|
|
20
|
+
import { UML_ROLES } from './roles.js';
|
|
21
|
+
import { UML_RULES } from './rules.js';
|
|
22
|
+
import { umlTemplateCategory } from './templates.js';
|
|
23
|
+
import { umlDiagramToolbarExtension, umlDiagramToolingToolbarExtension, umlFragmentToolbarExtension, umlFragmentToolingToolbarExtension, umlPartitionToolbarExtension, umlRegionToolbarExtension, } from './toolbar/config.js';
|
|
24
|
+
import { umlSeniorTool } from './toolbar/senior-tool.js';
|
|
25
|
+
/**
|
|
26
|
+
* UML rendering — ALWAYS registered, independent of any flag. Diagram frames,
|
|
27
|
+
* subjects and nodes already drawn must paint, stay selectable, stay editable
|
|
28
|
+
* and keep their resize gating whatever the tooling flag says. See
|
|
29
|
+
* `docs/adr/0009`.
|
|
30
|
+
*
|
|
31
|
+
* This is the RENDER half. The creation tooling — the senior button, its menu
|
|
32
|
+
* and its twenty-one commands — is {@link UmlViewExtension} below, exactly as
|
|
33
|
+
* `C4ViewExtension` is separate from `C4RenderViewExtension`. Nothing in this
|
|
34
|
+
* class may become flag-gated: a stored document needs every one of these
|
|
35
|
+
* registrations to load and paint.
|
|
36
|
+
*/
|
|
37
|
+
export class UmlRenderViewExtension extends ViewExtensionProvider {
|
|
38
|
+
constructor() {
|
|
39
|
+
super(...arguments);
|
|
40
|
+
this.name = 'affine-uml-render-gfx';
|
|
41
|
+
}
|
|
42
|
+
setup(context) {
|
|
43
|
+
super.setup(context);
|
|
44
|
+
context.register(UmlDiagramView);
|
|
45
|
+
context.register(UmlDiagramRendererExtension);
|
|
46
|
+
context.register(UmlSubjectView);
|
|
47
|
+
context.register(UmlSubjectRendererExtension);
|
|
48
|
+
// The two BANDED frames of the behaviour diagrams (phase 2): the activity
|
|
49
|
+
// partition (§15.6.4) and the composite state's region (§14.2.4). Content
|
|
50
|
+
// to the letter — a swimlane holds its actions by GEOMETRY, so a document
|
|
51
|
+
// that loses the frame loses which partition every action was in.
|
|
52
|
+
context.register(UmlPartitionView);
|
|
53
|
+
context.register(UmlPartitionRendererExtension);
|
|
54
|
+
context.register(UmlRegionView);
|
|
55
|
+
context.register(UmlRegionRendererExtension);
|
|
56
|
+
// The COMBINED FRAGMENT of §17.6.4 (phase 3) — content to the letter, like
|
|
57
|
+
// the two frames above it: an `alt` holds its messages by GEOMETRY, so a
|
|
58
|
+
// document that loses the frame loses which branch every exchange was in.
|
|
59
|
+
context.register(UmlFragmentView);
|
|
60
|
+
context.register(UmlFragmentRendererExtension);
|
|
61
|
+
context.register(UmlNodeView);
|
|
62
|
+
context.register(UmlNodeRendererExtension);
|
|
63
|
+
// The role VOCABULARY, always on. A role is written in the document, not in
|
|
64
|
+
// the tooling: the direction reveal of a typed edge, the inversion command
|
|
65
|
+
// and the toolbar entry that must not lie about a generalization all read
|
|
66
|
+
// this, and they have to keep working on a diagram drawn while the flag was
|
|
67
|
+
// on and opened while it is off (`docs/adr/0009`, `docs/adr/0010`).
|
|
68
|
+
context.register(RoleVocabularyExtension(UML_ROLES));
|
|
69
|
+
if (this.isEdgeless(context.scope)) {
|
|
70
|
+
// Resize gating, driven by the declarations like every other framework
|
|
71
|
+
// background: the handles follow `resizeEnabled`, which both declarations
|
|
72
|
+
// seed to `true` — a diagram and a subject are both stretched to fit.
|
|
73
|
+
context.register(FrameworkBackgroundInteractionExtension(UML_DIAGRAM_FRAME));
|
|
74
|
+
context.register(FrameworkBackgroundInteractionExtension(UML_SUBJECT_FRAME));
|
|
75
|
+
// ONE registration for the partition, even though `background.ts`
|
|
76
|
+
// declares TWO of them — the column and the row (`UML_PARTITION_FRAME_V`
|
|
77
|
+
// / `_H`, picked per element by `umlPartitionFrame`). This extension is
|
|
78
|
+
// keyed on `def.type` alone, so registering the second would not gate the
|
|
79
|
+
// horizontal lane: it would refuse to mount, on every document, with
|
|
80
|
+
// `DuplicateServiceDefinitionError`.
|
|
81
|
+
//
|
|
82
|
+
// Passing the vertical one is not an arbitrary pick either. What the
|
|
83
|
+
// extension reads off a declaration is `geometry.resizable`, the FALLBACK
|
|
84
|
+
// for an element carrying no `resizeEnabled` — and the two declarations
|
|
85
|
+
// are one factory called twice, so they agree on it by construction. The
|
|
86
|
+
// orientation changes where the band is, never whether the handles are
|
|
87
|
+
// offered.
|
|
88
|
+
context.register(FrameworkBackgroundInteractionExtension(UML_PARTITION_FRAME_V));
|
|
89
|
+
context.register(FrameworkBackgroundInteractionExtension(UML_REGION_FRAME));
|
|
90
|
+
context.register(FrameworkBackgroundInteractionExtension(UML_FRAGMENT_FRAME));
|
|
91
|
+
// The selected frame's own row — the resize toggle and the two exports in
|
|
92
|
+
// its "⋮". Always-on for the reason `docs/adr/0009` gives: a stored
|
|
93
|
+
// diagram must keep its handles usable with the UML button switched off,
|
|
94
|
+
// and each "⋮" entry hides itself when its command is absent from the
|
|
95
|
+
// registry, so nothing on the row can be clicked into a no-op.
|
|
96
|
+
context.register(umlDiagramToolbarExtension);
|
|
97
|
+
// …and the two phase-2 frames' own rows, always-on for the same reason
|
|
98
|
+
// and with the same contents: the gestures you make on a frame that is
|
|
99
|
+
// ALREADY THERE. The partition's row carries one more — the orientation
|
|
100
|
+
// flip — and `toolbar/config.ts` argues at length why a toggle that
|
|
101
|
+
// writes a stored field still belongs on this side of `docs/adr/0009`:
|
|
102
|
+
// the flag takes away the ways to CREATE, not the ways to work with what
|
|
103
|
+
// a document already holds.
|
|
104
|
+
context.register(umlPartitionToolbarExtension);
|
|
105
|
+
context.register(umlRegionToolbarExtension);
|
|
106
|
+
// …and phase 3's, on the same terms: a stored combined fragment keeps its
|
|
107
|
+
// handles with the UML button off. The two gestures that CREATE — adding
|
|
108
|
+
// an operand, declaring which kind of fragment this is — are in the
|
|
109
|
+
// flag-gated module below.
|
|
110
|
+
context.register(umlFragmentToolbarExtension);
|
|
111
|
+
// Keeps a classifier's box big enough for the words an author types into
|
|
112
|
+
// it: when an edit into a compartment commits, the stack is re-measured,
|
|
113
|
+
// the node grows if it no longer fits and the tiers move to the boxes the
|
|
114
|
+
// new box yields. Always-on for the reason `docs/adr/0009` gives — it
|
|
115
|
+
// creates nothing and adds no field, it keeps words ALREADY in the
|
|
116
|
+
// document from being drawn over their own separator, and a diagram drawn
|
|
117
|
+
// while the UML button was on must stay editable when it goes off. The
|
|
118
|
+
// same place `C4TypeLineWatcher` is registered, for the same reason.
|
|
119
|
+
context.register(UmlCompartmentWatcher);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* UML creation tooling — flag-gated (`uml`): the senior toolbar button, its
|
|
125
|
+
* sub-menu, the twenty-one commands behind them, its templates category, the
|
|
126
|
+
* frame's legend button and kind picker, the reading profiles and the two
|
|
127
|
+
* interchange capabilities.
|
|
128
|
+
*
|
|
129
|
+
* All of it is tooling in the sense `docs/adr/0009` means: a diagram drawn
|
|
130
|
+
* while the flag was on keeps painting, stays selectable and keeps its
|
|
131
|
+
* contextual toolbar when it goes off — only the ways to add new elements go
|
|
132
|
+
* away, the legend included since generating one CREATES elements.
|
|
133
|
+
*/
|
|
134
|
+
export class UmlViewExtension extends ViewExtensionProvider {
|
|
135
|
+
constructor() {
|
|
136
|
+
super(...arguments);
|
|
137
|
+
this.name = 'affine-uml-gfx';
|
|
138
|
+
}
|
|
139
|
+
effect() {
|
|
140
|
+
super.effect();
|
|
141
|
+
// Defines the senior button and its menu — tooling-only custom elements.
|
|
142
|
+
effects();
|
|
143
|
+
}
|
|
144
|
+
setup(context) {
|
|
145
|
+
super.setup(context);
|
|
146
|
+
if (this.isEdgeless(context.scope)) {
|
|
147
|
+
// Writing PlantUML and XMI files, declared rather than assumed
|
|
148
|
+
// (`docs/adr/0012`). Tooling like the rest of this class: with the flag
|
|
149
|
+
// off there is nothing to export WITH, while a stored diagram keeps
|
|
150
|
+
// painting (`docs/adr/0009`).
|
|
151
|
+
context.register(InterchangeExtension(UML_INTERCHANGE));
|
|
152
|
+
// The reversed reading (MF3): what the diagram says about an element, on
|
|
153
|
+
// demand. One profile per node role, because a class, an actor and a use
|
|
154
|
+
// case are read as three different things. The CLICK that triggers it is
|
|
155
|
+
// registered once by the surface and gated by the presence of a profile.
|
|
156
|
+
for (const reading of UML_READINGS) {
|
|
157
|
+
context.register(ReadingProfileExtension(reading));
|
|
158
|
+
}
|
|
159
|
+
// The review checklist and its two levels of requirement — DATA, like the
|
|
160
|
+
// roles and the readings above (`rules.ts`, `profiles.ts`). Tooling in the
|
|
161
|
+
// sense `docs/adr/0009` means: with the flag off a stored diagram keeps
|
|
162
|
+
// painting and simply stops being checked, and a frame already set to the
|
|
163
|
+
// strict level keeps that id written, untouched.
|
|
164
|
+
context.register(ValidationRuleExtension(UML_RULES));
|
|
165
|
+
context.register(ValidationProfileExtension(UML_PROFILES));
|
|
166
|
+
context.register(umlSeniorTool);
|
|
167
|
+
// The Templates-panel category — tooling, so it goes with the flag (#244).
|
|
168
|
+
context.register(TemplateCategoryExtension(umlTemplateCategory));
|
|
169
|
+
context.register(CommandExtension(umlCommands, umlCommandIcons));
|
|
170
|
+
// The flag-gated half of the selected FRAME's row, through the `custom:`
|
|
171
|
+
// flavour slot — the shape wardley, bpmn and C4 all use to hang
|
|
172
|
+
// flag-gated entries off a row whose base is always-on. One module,
|
|
173
|
+
// carrying the legend button AND the diagram-kind picker, because both
|
|
174
|
+
// are gated by this one flag and there is no reason to spend a second
|
|
175
|
+
// registration on them.
|
|
176
|
+
context.register(umlDiagramToolingToolbarExtension);
|
|
177
|
+
// The COMBINED FRAGMENT's flag-gated row, through the same `custom:`
|
|
178
|
+
// slot: the add-operand button and the operator picker. Both create —
|
|
179
|
+
// one puts a band on the canvas, the other declares how the box is to be
|
|
180
|
+
// read — which is the line `docs/adr/0009` draws (`toolbar/config.ts`).
|
|
181
|
+
context.register(umlFragmentToolingToolbarExtension);
|
|
182
|
+
// The "Change type" dropdown on a selected CLASSIFIER's contextual
|
|
183
|
+
// toolbar — the generic module, parameterized by UML's own families.
|
|
184
|
+
//
|
|
185
|
+
// ## Why the key carries an owner
|
|
186
|
+
//
|
|
187
|
+
// A UML artefact is a native `group`, so the row the toolbar draws for it
|
|
188
|
+
// is the GROUP's row, merged from `affine:surface:group`,
|
|
189
|
+
// `custom:affine:surface:group` and the two surface wildcards. Both group
|
|
190
|
+
// keys were claimed long ago — the first by the native group operations
|
|
191
|
+
// (rename, ungroup), the second by Wardley's qualification dropdown — and
|
|
192
|
+
// C4's morph is already hanging off a third. `toolbarModuleKey` is what
|
|
193
|
+
// lifts the ceiling of two contributors per element: the module is
|
|
194
|
+
// registered under the distinct variant
|
|
195
|
+
// `custom:affine:surface:group#uml-morph` and the registry hands it to the
|
|
196
|
+
// same row (`toolbar-service/registry.ts`).
|
|
197
|
+
//
|
|
198
|
+
// ## Why here
|
|
199
|
+
//
|
|
200
|
+
// In the flag-gated half, because a morph is TOOLING: a classifier drawn
|
|
201
|
+
// while the flag was on keeps its kind, its role, its colours, its words
|
|
202
|
+
// and its place in every rule when the flag goes off — it just stops being
|
|
203
|
+
// something the toolbar offers to say differently (`docs/adr/0009`).
|
|
204
|
+
context.register(ToolbarModuleExtension({
|
|
205
|
+
id: BlockFlavourIdentifier(toolbarModuleKey('custom:affine:surface:group', 'uml-morph')),
|
|
206
|
+
config: morphToolbarConfig(UML_MORPH_SPEC),
|
|
207
|
+
}));
|
|
208
|
+
// The same dropdown on a BARE UML shape — the routing marks phase 2 added.
|
|
209
|
+
//
|
|
210
|
+
// §15.3.4 and §14.2.4 name none of them, so a bullseye, a bar, a diamond
|
|
211
|
+
// and a crossed circle are created as the shape alone (`actions.ts`) and
|
|
212
|
+
// a click selects a `umlNode` rather than a group. The widget derives a
|
|
213
|
+
// surface element's flavour from `model.type`, so their row is
|
|
214
|
+
// `affine:surface:umlNode`'s and not the group's — which is why this is a
|
|
215
|
+
// second registration under a second key rather than a widened
|
|
216
|
+
// `modelType` on the one above. The families, the props and the wording
|
|
217
|
+
// are shared by reference (`morph.ts`), so the two rows can never offer
|
|
218
|
+
// different menus.
|
|
219
|
+
context.register(ToolbarModuleExtension({
|
|
220
|
+
id: BlockFlavourIdentifier(toolbarModuleKey('custom:affine:surface:umlNode', 'uml-morph')),
|
|
221
|
+
config: morphToolbarConfig(UML_BARE_MORPH_SPEC),
|
|
222
|
+
}));
|
|
223
|
+
// The same dropdown on a selected RELATIONSHIP. A second registration
|
|
224
|
+
// rather than a second family inside the first, because the two speak
|
|
225
|
+
// about different element types: a classifier is a group, a relationship
|
|
226
|
+
// is a connector, and `modelType` is what each spec filters the selection
|
|
227
|
+
// with. The connector's own row is always-on (stroke, ends, routing) and
|
|
228
|
+
// this is an addition to it, so it takes the `custom:` twin under the same
|
|
229
|
+
// owner suffix.
|
|
230
|
+
context.register(ToolbarModuleExtension({
|
|
231
|
+
id: BlockFlavourIdentifier(toolbarModuleKey('custom:affine:surface:connector', 'uml-morph')),
|
|
232
|
+
config: morphToolbarConfig(UML_EDGE_MORPH_SPEC),
|
|
233
|
+
}));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|