first commit
This commit is contained in:
96
docs/foundation/data/clipboard/src/manager/helpers.md
Normal file
96
docs/foundation/data/clipboard/src/manager/helpers.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# `manager/helpers.ts`
|
||||
|
||||
## Purpose
|
||||
|
||||
Pure helpers shared between `manager.ts` and `operations.ts`. Keeps both
|
||||
files under the line budget by housing the navigator / window resolution,
|
||||
the structured failure builder, the focus-error detector, and the
|
||||
`ClipboardItem` build + read pipelines in a single, side-effect-free
|
||||
module that tests can exercise directly.
|
||||
|
||||
## Features
|
||||
|
||||
- `resolveNavigator(nav?)` — caller, global, or empty shim.
|
||||
- `resolveWindow(win?)` — caller, global, or `undefined`.
|
||||
- `failure(code, message, method)` — typed `ClipboardResult` failure.
|
||||
- `isFocusError(cause)` — detects the canonical focus-required rejection.
|
||||
- `buildClipboardItems(data)` — MIME → `Blob` map for `ClipboardItem`.
|
||||
- `readClipboardItems(items, sanitizer?)` — pulls text / html / image /
|
||||
blobs out of a list of `ClipboardItem` instances.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { failure, CLIPBOARD_CODES } from "@suaveplan/clipboard";
|
||||
|
||||
const r = failure(CLIPBOARD_CODES.NO_CONTENT, "empty", "api");
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import {
|
||||
buildClipboardItems,
|
||||
readClipboardItems,
|
||||
} from "@suaveplan/clipboard";
|
||||
|
||||
const items = buildClipboardItems({
|
||||
text: "hello",
|
||||
html: "<b>hi</b>",
|
||||
image: pngBlob,
|
||||
blobs: { "application/json": jsonBlob },
|
||||
});
|
||||
|
||||
const clipboardItem = new ClipboardItem(items);
|
||||
await navigator.clipboard.write([clipboardItem]);
|
||||
|
||||
// Round-trip back:
|
||||
const read = await navigator.clipboard.read();
|
||||
const data = await readClipboardItems(read, (html) => html.trim());
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `resolveNavigator(nav?: ClipboardNavigator): ClipboardNavigator`
|
||||
|
||||
Returns `nav` when defined, otherwise the global `navigator`, otherwise
|
||||
the empty object `{}`.
|
||||
|
||||
### `resolveWindow(win?: ClipboardWindowLike): ClipboardWindowLike | undefined`
|
||||
|
||||
Returns `win` when defined, otherwise the global `window`, otherwise
|
||||
`undefined`.
|
||||
|
||||
### `failure<T>(code, message, method): ClipboardResult<T>`
|
||||
|
||||
Returns `{ success: false, error: message, code, method }`. Generic over
|
||||
`T` so call sites compose with their own result types.
|
||||
|
||||
### `isFocusError(cause: unknown): boolean`
|
||||
|
||||
Returns `true` when `cause` is an `Error` whose `name === "NotAllowedError"`
|
||||
and whose `message` (case-insensitively) contains `"focus"`. The browser
|
||||
signals "Clipboard needs page focus" with this exact shape.
|
||||
|
||||
### `buildClipboardItems(data: ClipboardData): Record<string, Blob>`
|
||||
|
||||
Builds a MIME → Blob map for `new ClipboardItem(...)`. Skips empty
|
||||
`text` and `html`. Defaults a typeless image blob to `image/png`.
|
||||
|
||||
### `readClipboardItems(items, sanitizer?): Promise<ClipboardData>`
|
||||
|
||||
Iterates every entry of every `ClipboardItem`, populating `text`,
|
||||
`html`, `image`, and `blobs`. The first image-typed entry wins. The
|
||||
`sanitizer` (when supplied) is applied to the raw `text/html` payload
|
||||
before returning.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The helpers are intentionally side-effect-free and free of telemetry
|
||||
calls so the same code runs from `runCopyText`, `runCopyRich`, etc.,
|
||||
without double-recording counters. `buildClipboardItems` and
|
||||
`readClipboardItems` are mirror images of each other — every MIME slot
|
||||
that `buildClipboardItems` writes is read back by `readClipboardItems`
|
||||
into the same `ClipboardData` shape. The focus-error detector matches
|
||||
both Chromium ("Document is not focused.") and WebKit ("Document not
|
||||
focused.") wording.
|
||||
Reference in New Issue
Block a user