refactoring van de cmap structuren bijna compleet
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
# Racket Wiki CMap component
|
||||
|
||||
This directory contains the complete browser-side CMap component.
|
||||
|
||||
`cmap.js` is the ES-module entry point of the diagram engine. Its public
|
||||
`DiagramEngine`, `DiagramNode` and `DiagramLink` classes expose only the API
|
||||
used by the wiki editor: creating nodes and links, changing their presentation,
|
||||
connecting endpoints, zooming and receiving render, selection, activation and
|
||||
move events. The engine does not install a `window.Cmap` global.
|
||||
|
||||
The modules under `engine/` separate that API from the renderer internals.
|
||||
`diagram-engine.js` owns the surface and component lifetime;
|
||||
`diagram-node.js`, `diagram-link.js` and `diagram-component.js` define the
|
||||
public handles. The `drawing-*` modules contain DOM rendering, geometry,
|
||||
relations, hit testing and pointer interaction. That rendering core is based on
|
||||
the MIT-licensed ionstage/cmap 0.1.3 source and is maintained as part of
|
||||
racket-wiki. Activation is recognized inside the same hit-test and drag
|
||||
lifecycle as selection, so it does not depend on a DOM `dblclick` event that
|
||||
may be suppressed by dragging.
|
||||
|
||||
`diagram-group.js` adds the generic view-level `DiagramGroup` abstraction. A
|
||||
group contains nodes or nested groups, calculates a frame from their geometry,
|
||||
and can be expanded or collapsed. It deliberately knows nothing about CMaps,
|
||||
wiki pages or aspects. `DiagramEngine.setFilter` accepts an application policy
|
||||
for component visibility; the engine combines that policy with each component's
|
||||
own visibility and hides links whose endpoints are hidden. A wiki adapter can
|
||||
therefore translate submap membership or aspect matching into groups and
|
||||
filters without putting domain rules into the drawing engine. Proxy endpoints
|
||||
and boundary navigation remain application concerns until a generic endpoint
|
||||
projection API is introduced.
|
||||
|
||||
`model/concept-repository.js` owns shared concepts, semantic concept relations
|
||||
and concept ownership. `model/concept-map.js` owns one map's concept
|
||||
placements, linking phrases, connectors, metadata and presentation values.
|
||||
`model/cmap-repository.js` owns the server boundary: it decodes stored CMaps,
|
||||
normalizes legacy concept identities and converts backend documents to and
|
||||
from `CmapModel`. It is the only browser-side CMap model module that knows the
|
||||
`/api/cmaps` routes. `model/appearance.js` owns the shared named styles, colour
|
||||
palette, validation and style matching. `model/appearance-repository.js`
|
||||
serializes that model through the appearance API. `model/settings-repository.js`
|
||||
owns the wiki start CMap and the authenticated user's A4-guide and
|
||||
per-CMap-context zoom settings. `model/people-repository.js` is the server
|
||||
boundary for the people referenced by concept tags.
|
||||
The repository objects keep only an in-memory session copy; the backend remains
|
||||
authoritative. None of these model modules contains DOM or drawing-engine
|
||||
objects, and CMap state is not persisted in browser storage.
|
||||
|
||||
`cmap-view.js` owns the canvas and its concrete `DiagramEngine` instance.
|
||||
`view/appearance-editor.js` presents the appearance model in the concept dialog
|
||||
and coordinates explicit style and palette changes with its repository.
|
||||
The concrete dialog controllers live in `../wiki/cmap/dialogs/`. They own
|
||||
their fields, validation and browser events. The workspace supplies the active
|
||||
CMap and performs editor transitions, while the controllers use repository
|
||||
APIs for stored CMaps and people instead of calling backend routes directly.
|
||||
`cmap-racket-wiki.js` contains the wiki-specific editor controller, selection
|
||||
state, content-based initial sizing, resize and relation controls. Its view
|
||||
records connect pure model ids to drawing nodes without making those nodes part
|
||||
of the model. Automatic sizing remains active while text is edited and is
|
||||
disabled when the user resizes a concept manually.
|
||||
|
||||
Selected concepts expose an edit handle. The host opens a modal editor for
|
||||
their shared name, aspects, people, description page, synopsis, image, external
|
||||
web address and linked wiki/CMap target, plus placement-specific background
|
||||
colour and typography. The editor has one compact tab for content, links and
|
||||
images, and a second tab for detailed colours, typography and submap
|
||||
presentation. Detailed settings can be saved as named, wiki-wide database
|
||||
styles; selected styles are applied immediately and non-default styles can be
|
||||
deleted. Its action bar remains visible while a tab scrolls.
|
||||
Structural kinds such as a sub-CMap head remain placement roles. Page concepts retain their linked `pageSlug`; double-click is
|
||||
reserved for opening that wiki page. Concepts may alternatively retain a
|
||||
`cmapSlug` for another stored CMap or a `parentCmapLink` for navigation back
|
||||
from a child map. An optional `externalUrl` accepts only HTTP(S), opens in a new
|
||||
browser tab and is shared by every placement of that concept. Images are data
|
||||
URLs inside the persisted CMap JSON document.
|
||||
Font families are selected from a practical list and font sizes are stored in
|
||||
typographic points. The host can change the linked page or CMap independently
|
||||
of the visible label and provides background and text-colour pickers.
|
||||
|
||||
Linking phrases are compact borderless nodes at the intentional bend between
|
||||
two connector segments. Their position is stored with the rest of the map.
|
||||
When an endpoint is deleted, a genuinely branching phrase is retained while it
|
||||
still has at least one incoming and one outgoing concept. Losing the final
|
||||
endpoint on either side removes the phrase and all its remaining segments.
|
||||
|
||||
Multiple selected items can be moved or deleted together. Grouping is a
|
||||
structural operation: the editor creates an expanded sub-CMap with a named main
|
||||
concept and adopts the selection as its contents. Ungrouping dissolves a
|
||||
selected inline sub-CMap or moves selected child items one level outward.
|
||||
**Make separate CMap** extracts the descendants into a complete stored CMap.
|
||||
The former sub-CMap head remains in the parent as an ordinary concept whose
|
||||
shared `cmapSlug` links to the new map. Ownership from that concept to the
|
||||
extracted concepts is removed; internal child connectors move with the child,
|
||||
while relations crossing the boundary terminate on the retained owner concept.
|
||||
The same action converts an older `derivedView` in place: its slug, title and
|
||||
metadata remain intact, but its document no longer depends on the parent CMap.
|
||||
|
||||
`toDocument` and `loadDocument` round-trip the complete editor model: items,
|
||||
formatting, positions, connectors, recursive submap membership and promoted
|
||||
map references. The public `currentModel`, `loadModel` and `replaceModel`
|
||||
methods let the workspace pass complete domain models to and from the editor.
|
||||
The CMap repository, rather than the workspace, persists those models.
|
||||
|
||||
## JSON interchange
|
||||
|
||||
`model/interchange.js` defines and validates the versioned
|
||||
`racket-wiki-cmap-bundle` format. `model/json-exporter.js` builds complete bundles
|
||||
through `CmapRepository` and the supplied page and attachment loaders.
|
||||
`model/json-importer.js` reads those bundles, stores CMaps through the same
|
||||
repository and performs the required page and attachment writes. The workspace
|
||||
decides only how conflicts are presented to the user.
|
||||
A bundle mirrors the normalized database model: `cmaps[]` contains the
|
||||
complete placement and presentation document, `concepts[]` contains shared
|
||||
content once per UUID, and `pages[]` contains the current Markdown, tags and
|
||||
referenced attachments of linked wiki and explanation pages. Attachments retain
|
||||
their MIME type and binary base64 content; import uploads them under the target
|
||||
page and rewrites the Markdown to the newly allocated URL. The root CMap and every included CMap retain
|
||||
their stable slug. Derived CMaps automatically include their source CMap.
|
||||
|
||||
Presentation includes coordinates, dimensions, colours, font settings,
|
||||
sub-CMap membership, linking phrases and connectors. Connector endpoints use
|
||||
local item ids; concept identity never depends on those local ids. The formal
|
||||
contract is
|
||||
[`racket-wiki-cmap-bundle-v1.schema.json`](../schemas/racket-wiki-cmap-bundle-v1.schema.json).
|
||||
|
||||
An external generator may use a temporary id such as `new:security-review` for
|
||||
a new concept. Every concept must also occur in at least one non-phrase
|
||||
`document.items[]` placement with coordinates. On import the server turns such
|
||||
a temporary identity into a UUID through the central Racket UUID helper. UUIDs
|
||||
already present in an export remain unchanged. Imported CMap slugs likewise
|
||||
remain unchanged.
|
||||
|
||||
`model/markdown-exporter.js` reads stored models through `CmapRepository` but
|
||||
produces a readable
|
||||
report instead of an importable bundle. It is independent of the JSON
|
||||
exporter because the report follows linked maps and optional wiki pages for a
|
||||
different purpose. Additional output formats can therefore be implemented as
|
||||
separate exporters without adding format-specific code to the workspace.
|
||||
|
||||
The editor keeps up to one hundred complete document states for Undo and Redo.
|
||||
One drag or resize gesture forms one history step. The public `undo`, `redo`,
|
||||
`canUndo`, `canRedo` and `resetHistory` methods are also used by the wiki host
|
||||
for keyboard shortcuts and context-menu state.
|
||||
|
||||
`cmap.css` contains all CMap presentation and interaction styles.
|
||||
|
||||
The source files deliberately remain separate but form one component and are
|
||||
loaded directly from `/js/cmap/`; there is no runtime download or vendor patch.
|
||||
Reference in New Issue
Block a user