# Browser integration

> Host the browser/WASM MVP and understand its platform limits.

## Try it, then make it yours

The [playground](https://siriusmarkdown.com/playground/) runs the SiriusMarkdown browser MVP on your device. Edit the source, stream an example, select and copy content, enlarge a diagram, or print the document. It uses the actual WebAssembly engine, with a worker for document parsing, preparation, layout, and math.

The browser MVP is a separate distribution from the native Swift SDK. It supports Markdown and GFM structure, sanitized rich HTML, vector equations and diagrams, highlighted code, tables, images, streaming, and source-backed selection. It does not provide complete native capability parity.

Diagram options include Unicode and ASCII text downloads. They use the same
parser as the vector diagram, preserve authored labels and values, and keep the
viewer position. The worker prepares text on demand. ASCII uses plain drawing
characters while keeping Unicode source labels. Unsupported or oversized text
exports offer source fallback. Pie labels retain multiline rows and expand tabs
before measuring terminal columns. XY text exports honor explicit data-label
suppression.

Browser 0.2.15 includes the shared engine from native SDK 0.7.23, including
composed inline highlights, task semantics, text colors and exact authored style ranges.
The released inline-equation line breaks and distinct HTML list source mappings remain supported.
The download manifest records `nativeSDKVersion` and `engineSourceSHA256`.
Keep that provenance with the complete runtime when upgrading.

Supported literal HTML text colors stay within their spans through mounted text,
rich clipboard and readable print. Links retain theme ink. Inline publications
include optional `textColor` sRGB bytes and exact `styleSources` opening/closing
byte and line ranges. A host must validate its current source revision before
using a range to edit the document; recovered HTML does not grant new delimiter
edit authority. Arbitrary CSS and CSS resource loading remain disabled.

Entities and escapes retain complete authored source ranges. Inline-code
boundaries include the parser's omitted padding while preserving the code run's
whole-token range. Shared `sourceTextMappings` keep partial selections and copy
exact across entities, escapes and code syntax, including wrapped spans and
retained content after source relocation.

Partial semantic Copy preserves selected words and spaces without adding an
unselected list marker or paragraph terminator. Selected authored line breaks
and joins between disjoint ranges remain. Whole-document and readable-print
serialization keep their paragraph structure.

## Download and host

Download [browser 0.2.15](https://github.com/mikhutchinson/siriusmarkdown-commercial/releases/tag/browser-0.2.15) from the public distribution repository. The release includes the browser ZIP, checksums, and the modified ElkSwift corresponding-source archive. The Swift XCFramework package remains a separate product in the same repository.

Extract the ZIP and serve its `site/` directory over HTTPS, or localhost during development. Keep `js/`, `assets/`, `dist/`, and `playground/` together. The included playground is a complete reference host; its `main.js` and `worker.js` show the session, font, resource, revision, and interaction wiring. `Browser-API.md` describes the integration contract.

Serve WASM as `application/wasm`, JavaScript as `text/javascript`, and fonts with their font MIME types. Keep workers, runtime imports, fonts, and modules on the same origin. A content security policy must permit the same-origin module worker and WebAssembly compilation using `wasm-unsafe-eval`; it should deny objects and active embedded content.

The main reactor is about 58 MiB and the separate diagram reactor about 57 MiB before HTTP compression. Load them on demand. A marketing page does not need either module. Use normal HTTP caching for a versioned runtime, and keep each version’s JavaScript, fonts, worker, and WASM together.

## Mount prepared content

The page mounts prepared publications from its worker. This is the presentation part of a host integration:

```javascript
import {
  applyTheme,
  mountMarkdownDocument,
} from "./js/render/index.js";

const root = document.querySelector("#preview");
applyTheme(document.documentElement, {
  preset: "document",
  appearance: "light",
});

const view = mountMarkdownDocument(root);
worker.addEventListener("message", ({ data }) => {
  // The host first rejects superseded epochs and source revisions.
  if (data.type === "publication") view.applyPublication(data);
  if (data.type === "relayout") view.applyRelayout(data);
});

// When removing the document:
// view.destroy();
// worker.terminate();
```

Here `worker` is the configured module worker owned by your host. Before sending source, install the supplied fonts, initialize the reactor, and configure the session with matching theme and font metrics. Follow the complete reference host for these steps rather than omitting configuration. The included browser API describes each message.

Use `documentEpoch` to distinguish documents and increasing source revisions to distinguish edits. A width change requests relayout of prepared content; it does not replace the source. On replacement or teardown, retire the previous document’s resource requests and selection state.

Supply `onFormat`, `onCodeCopy`, and `onCodeExport` when the host supports editing, clipboard writes, or downloads. Formatting ranges refer to the displayed source’s UTF-8 byte offsets. Validate the revision before applying an edit, and retain the editor’s Undo transaction.

## Diagram preparation

Interactive diagrams use a dedicated worker with batched document-font measurements. During continuous input, the renderer finishes a coherent prefix and coalesces newer appends. Unchanged accepted statements reuse preparation while source and pending-frontier metadata stay current. Replacement source, appearance changes and reset revoke obsolete work. Preparation and mounting have separate diagnostic timings.

## Readable PDF export

Choose **Publication tables** in the playground, then **Readable PDF** to preview wide tables for printing. Column groups repeat the identifying column, and later pages repeat the headings. Text retains its original size, merged cells keep their content, and connected row spans stay together. Closing the preview leaves the interactive reader in place.

Embedded readers can call `await view.createReadablePrint({ width: 720, height: 960 })`. Those dimensions fit Letter paper with half-inch margins. The result is an independent snapshot; keep its resource owner alive and call `dispose()` after printing. An unfit header or row group reports an error instead of clipping content. Publication column-region manifests and the native PDF export options remain separate capabilities.

## Optional resource gateway

The download includes a bounded Node host for pictures and icons whose origins do not allow browser CORS requests:

```sh
node site/js/host/server.mjs --root site --port 8843
```

Open `http://127.0.0.1:8843/playground/?resources=gateway`. Existing servers can mount the supplied handler behind their normal authentication and traffic controls. The browser adapter uses a same-origin endpoint. The gateway checks public DNS addresses and every redirect, preserves TLS hostname verification, uses anonymous requests, and bounds resource sizes, time, concurrency and caches. Failed requests retain the normal fallback.

Static hosting still uses direct browser requests and requires readable CORS responses. The public playground currently uses that direct mode. Self-hosting the gateway does not require changing the Markdown documents.

## Browser limits

Current Safari, Chrome, and Firefox are the intended desktop browsers. WebAssembly, JavaScript modules, module workers, and browser font APIs are required. Clipboard permissions and print dialogs vary by browser. Responsive layouts also work at phone widths; this does not imply an exhaustive mobile-device or assistive-technology certification.

Documents parse and render locally. External image and site-icon requests still use networking. Cross-origin images require readable CORS responses. Default resource fetchers deny redirects and local/private URL literals; browser networking cannot reproduce native per-hop DNS inspection. An unavailable image keeps a placeholder and a denied icon keeps its glyph.

Document-relative files require explicit host authorization. The playground authorizes its bundled Saturn photograph and files you select. Selecting one local file does not authorize access to other files on your device. Do not add an unrestricted proxy for arbitrary document URLs.

Supported HTML is sanitized into the document model. Scripts, active forms, arbitrary CSS, and embedded browsing contexts are not enabled. Standalone Markdown images support contextual alignment, width and caption edits, drag resizing and text wrapping. Inline Markdown and policy-authorized HTML images support width edits; HTML images also support alternative-text edits. The host owns source transactions and Undo. Wrap groups apply to standalone Markdown figures, including their captions; narrow columns place prose below the figure.

Ordinary Copy supplies readable text and HTML. **Copy Markdown** supplies the exact authored source as plain text for receiving applications. Browser clipboard custom formats differ from native pasteboard types; native RTF interoperability is not implied. Printing uses the browser’s print system and PDF pagination, rather than the native SDK’s PDF export APIs.

The runtime has a terminal trap fallback that preserves authored source. A host may explicitly opt into one bounded recovery attempt; it must not create an unlimited retry loop. The playground’s retry button retains the current source before reloading a failed renderer.

## License and notices

The browser distribution uses [Commercial SDK License 1.0](https://siriusmarkdown.com/license/). Previous MIT grants and third-party terms remain intact. Preserve the included runtime and font licenses, notices, and the separate EPL corresponding-source archive when redistributing the browser package. Keep that source archive outside the hosted runtime.
