Files
racket-wiki/static/cmap

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.

cmap-racket-wiki.js contains the wiki-specific editor model, selection state, content-based initial sizing, resize and relation controls, page concepts and submap concepts. 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.

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/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.

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.