# `util` reference

Internal utility helpers used throughout **dom-to-image-more**. They are exposed for
testing and advanced integration via:

```js
domtoimage.impl.util;
```

> ⚠️ These are **implementation details**, not part of the stable public API (`toSvg`,
> `toPng`, `toJpeg`, `toBlob`, `toCanvas`, `toPixelData`). They may change between
> releases. They are documented here because the test suite and some advanced callers
> depend on them.

The object is produced by `newUtil()` in
[`src/dom-to-image-more.js`](../src/dom-to-image-more.js) and attached to
`domtoimage.impl.util`. For the rest of the `impl` surface (`fontFaces`, `images`,
`inliner`, `urlCache`, `options`, `copyOptions`), see [IMPL.md](IMPL.md).

---

## Type guards

All of these return a `boolean` and are built on `isInstanceOf`, which checks the value
against the constructor from **both** its own window and the parent window (so they work
correctly across `<iframe>` boundaries).

| Function                                | Returns `true` when the value is…                                                                                       |
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `isElement(value)`                      | a DOM `Element`                                                                                                         |
| `isHTMLElement(value)`                  | an `HTMLElement`                                                                                                        |
| `isHTMLCanvasElement(value)`            | an `HTMLCanvasElement`                                                                                                  |
| `isHTMLImageElement(value)`             | an `HTMLImageElement`                                                                                                   |
| `isHTMLInputElement(value)`             | an `HTMLInputElement`                                                                                                   |
| `isHTMLLinkElement(value)`              | an `HTMLLinkElement`                                                                                                    |
| `isHTMLScriptElement(value)`            | an `HTMLScriptElement`                                                                                                  |
| `isHTMLStyleElement(value)`             | an `HTMLStyleElement`                                                                                                   |
| `isHTMLTextAreaElement(value)`          | an `HTMLTextAreaElement`                                                                                                |
| `isSVGElement(value)`                   | an `SVGElement`                                                                                                         |
| `isSVGImageElement(value)`              | an `SVGImageElement` (a nested SVG `<image>`, whose `href`/`xlink:href` is inlined)                                     |
| `isSVGSVGElement(value)`                | an `SVGSVGElement` (an `<svg>` root; non-root SVG elements take a different render path)                                |
| `isSVGRectElement(value)`               | an `SVGRectElement`                                                                                                     |
| `isSVGUseElement(value)`                | an `SVGUseElement` (a `<use>` referencing an element to inline)                                                         |
| `isShadowRoot(value)`                   | a `ShadowRoot`                                                                                                          |
| `isInShadowRoot(value)`                 | a node whose root (`getRootNode()`) is a `ShadowRoot`. Safe for `null`/`undefined` and for nodes without `getRootNode`. |
| `isElementHostForOpenShadowRoot(value)` | an `Element` that hosts an **open** shadow root (`value.shadowRoot !== null`)                                           |
| `isShadowSlotElement(value)`            | an `HTMLSlotElement` that lives inside a shadow root                                                                    |

### `isInstanceOf(value, typeName)`

`(value: any, typeName: string) => boolean`

Cross-realm `instanceof` check. Resolves the constructor named `typeName` from the value's
own window **and** `window.parent`, returning `true` if the value is an instance of
either. This is the primitive that all the guards above are built on, so type checks
survive elements that originate inside iframes.

### `isDataUrl(url)`

`(url: string) => boolean`

`true` if the string begins with `data:`.

### `isDimensionMissing(value)`

`(value: number) => boolean`

`true` when a measured dimension is unusable — i.e. `NaN`, `0`, or negative. Used to
decide when to fall back to default sizing (e.g. `width="100%"`).

---

## Geometry / dimensions

### `width(node)`

`(node: Element) => number`

Computed pixel width of `node`. Reads the CSS `width` via `getComputedStyle`; if that is
not a `px` value, falls back to `scrollWidth + border-left-width + border-right-width`.

### `height(node)`

`(node: Element) => number`

Computed pixel height of `node`. Same strategy as `width`, using
`scrollHeight + border-top-width + border-bottom-width` as the fallback.

> Note: both read live layout, so the value depends on the element's current rendered
> state (scrollbars, etc.).

---

## Window / document

### `getWindow(node)`

`(node?: Node) => Window`

Returns the `Window` that owns `node` (`node.ownerDocument.defaultView`), falling back to
`window`, then `global`, then `globalThis`. Each fallback is `typeof`-guarded so it does
not throw under SSR (Angular Universal, Next.js, plain Node) where `window`/`global` may
be absent. Tolerates a missing/`undefined` `node`. Underpins the cross-realm type guards.

---

## URLs & resources

### `resolveUrl(url, baseUrl)`

`(url: string, baseUrl: string) => string`

Resolves a possibly relative `url` against `baseUrl` and returns the absolute URL.
Implemented by letting the browser normalize an `<a href>` inside a throwaway document
that has a `<base>` set to `baseUrl`.

### `getAndEncode(url, type)`

`(url: string, type?: ResourceType) => Promise<string>`

Thin wrapper over the shared fetch core (see below) that resolves to a **data URL**
(base64) — used at the inline sites (images, fonts). `type` is the resource kind (a
`domtoimage.ResourceType` value: `IMAGE`, `CSS_IMAGE`, `FONT`, `STYLESHEET`) used by
`requestInterceptor` and to scope `imagePlaceholder`; it defaults to `undefined`. Resolves
to `''` when the resource is dropped.

### `getResourceText(url, type, allowNetwork)`

`(url: string, type?: ResourceType, allowNetwork?: boolean) => Promise<string | null>`

Sibling wrapper that resolves to the resource's **text** (via `readAsText`, no base64
round-trip) — used to load external stylesheets
([loadExternalStyleSheet](../README.md#loadexternalstylesheet)). `allowNetwork === false`
consults `requestInterceptor` but performs **no** network fetch (so a readable or
not-opted-in stylesheet can still be supplied by the interceptor without being
downloaded). Resolves to `null` when there's no resource.

#### Shared fetch core

Both wrappers share one fetch core that returns a Blob (network), a data URL string
(supplied by `requestInterceptor`/`imagePlaceholder`), or `null` (dropped); the wrappers
handle the encode/decode, so a resource is only base64-encoded where it's actually
inlined. Key behaviors:

- **Caches** by URL in `domtoimage.impl.urlCache`; concurrent/repeat requests for the same
  URL share one promise. Reset with [`resetUrlCache()`](IMPL.md#implurlcache).
- **`requestInterceptor`** is consulted first, before the fetch:
  `requestInterceptor(url, { type, status: undefined })` may return a data URL (or a
  promise of one) to short-circuit the network.
- Honors options: `cacheBust`, `httpTimeout`, `useCredentials` / `useCredentialsFilters`,
  and `corsImg` (proxy URL/method/headers/data with the `#{cors}` token substituted).
- Treats HTTP status `0` as success for `file://` URLs (Firefox local-file quirk).
- On any failure (network/timeout/non-2xx, **or** a response that isn't a usable Blob):
  consults `requestInterceptor(url, { type, status })` for a recovery value (takes
  precedence), then `imagePlaceholder` — **only for image types** (`IMAGE` / `CSS_IMAGE`;
  a `FONT`/`STYLESHEET`, or an untyped call, drops) — then drops. Never rejects; every
  failure is surfaced via `onImageError`.

### `makeImage(uri)`

`(uri: string) => Promise<HTMLImageElement | undefined>`

Loads `uri` into an `Image` (wrapped in an offscreen `<svg>` appended to `document.body`)
and resolves once it has loaded. Returns `undefined` for the empty data URL `data:,`.
Applies `crossOrigin = 'use-credentials'` when the `useCredentials` option is set. Removes
the temporary node on load/error; before resolving it awaits `image.decode()` (when
available) and then one `requestAnimationFrame`, so the bitmap is fully decoded before a
canvas reads it — guarding the Firefox/Safari blank-render timing race (issues #146,
#192).

### `canvasToBlob(canvas)`

`(canvas: HTMLCanvasElement) => Promise<Blob>`

Resolves to a PNG `Blob` of the canvas. Uses the native `canvas.toBlob` when available,
otherwise a manual `toDataURL` → `atob` → `Uint8Array` → `Blob` fallback.

---

## String helpers

### `escape(string)`

`(string: string) => string`

> Exposed as `util.escape` (implementation `escapeRegEx`).

Escapes characters that are special in a regular expression
(`. * + ? ^ $ { } ( ) | [ ] / \`) so the string can be used as a regex literal.

### `escapeXhtml(string)`

`(string: string) => string`

Escapes a string for safe embedding in the XHTML/`foreignObject` payload of the generated
SVG: replaces `%` → `%25`, `#` → `%23`, and newlines → `%0A`.

---

## Misc

### `asArray(arrayLike)`

`(arrayLike: ArrayLike<T>) => T[]`

Converts an array-like (e.g. a `NodeList` or `CSSStyleDeclaration`) into a real `Array` by
index copy.

### `uid()`

`() => string`

Returns a short unique id of the form `u<4-random-base36-chars><counter>` (e.g. `u3f9a0`).
The incrementing counter guarantees uniqueness within a session even if the random part
collides.

---

## Quick index

| Name                             | Category                  | Returns                                  |
| -------------------------------- | ------------------------- | ---------------------------------------- |
| `isElement`                      | type guard                | `boolean`                                |
| `isElementHostForOpenShadowRoot` | type guard                | `boolean`                                |
| `isShadowRoot`                   | type guard                | `boolean`                                |
| `isInShadowRoot`                 | type guard                | `boolean`                                |
| `isHTMLElement`                  | type guard                | `boolean`                                |
| `isHTMLCanvasElement`            | type guard                | `boolean`                                |
| `isHTMLInputElement`             | type guard                | `boolean`                                |
| `isHTMLImageElement`             | type guard                | `boolean`                                |
| `isHTMLLinkElement`              | type guard                | `boolean`                                |
| `isHTMLScriptElement`            | type guard                | `boolean`                                |
| `isHTMLStyleElement`             | type guard                | `boolean`                                |
| `isHTMLTextAreaElement`          | type guard                | `boolean`                                |
| `isShadowSlotElement`            | type guard                | `boolean`                                |
| `isSVGElement`                   | type guard                | `boolean`                                |
| `isSVGImageElement`              | type guard                | `boolean`                                |
| `isSVGSVGElement`                | type guard                | `boolean`                                |
| `isSVGRectElement`               | type guard                | `boolean`                                |
| `isSVGUseElement`                | type guard                | `boolean`                                |
| `isInstanceOf`                   | type guard                | `boolean`                                |
| `isDataUrl`                      | type guard                | `boolean`                                |
| `isDimensionMissing`             | dimensions                | `boolean`                                |
| `width`                          | dimensions                | `number`                                 |
| `height`                         | dimensions                | `number`                                 |
| `getWindow`                      | window                    | `Window`                                 |
| `resolveUrl`                     | url                       | `string`                                 |
| `getAndEncode`                   | url, type?                | `Promise<string>`                        |
| `getResourceText`                | url, type?, allowNetwork? | `Promise<string \| null>`                |
| `makeImage`                      | url                       | `Promise<HTMLImageElement \| undefined>` |
| `canvasToBlob`                   | url                       | `Promise<Blob>`                          |
| `escape`                         | string                    | `string`                                 |
| `escapeXhtml`                    | string                    | `string`                                 |
| `asArray`                        | misc                      | `Array`                                  |
| `uid`                            | misc                      | `string`                                 |
