97 lines
5.8 KiB
Markdown
97 lines
5.8 KiB
Markdown
# Racket Wiki CMap component
|
|
|
|
This directory contains the complete browser-side CMap component.
|
|
|
|
`cmap.js` is the drawing and hit-testing engine. It is based on the
|
|
MIT-licensed ionstage/cmap 0.1.3 source and is now maintained as part of
|
|
racket-wiki. Its public additions include `onSelection` on a map and
|
|
`onActivation` and `onRendered` callbacks. 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.
|
|
|
|
`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.
|
|
Neither model module contains DOM or drawing-engine objects.
|
|
|
|
`cmap-view.js` owns the canvas and the concrete `cmap.js` drawing instance.
|
|
`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 wiki host persists this JSON document through its CMap API.
|
|
|
|
## JSON interchange
|
|
|
|
`/js/wiki/cmap/interchange.js` implements the versioned `racket-wiki-cmap-bundle`
|
|
format. 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.
|
|
|
|
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 `/cmap/`; there is no runtime download or vendor patch.
|