diff --git a/docs/features/html-import.md b/docs/features/html-import.md index 7cb7bf493..831914e82 100644 --- a/docs/features/html-import.md +++ b/docs/features/html-import.md @@ -98,8 +98,8 @@ Callers splice the fragment into the page tree via `insertImportedNodes(parentId | `instatic-outlet` | `base.outlet` | none (the CMS content outlet) | **No** | | `instatic-loop` | `base.loop` | `sourceId`, `filters.tableId`, `orderBy`, `direction`, `limit`, `offset`, `pagination`, `pageSize`, optional `tag` / `customTag` from `data-*` attrs | Yes | | `h1`–`h6`, `p`, `span`, `small`, `strong`, `em` | `base.text` | `text` = `el.textContent`, `tag` = tag name | No | -| `a` with class `btn` | `base.button`, or `base.link` when it wraps element children | `label` (`text` on `base.link`) = `el.textContent`, `href`, `target` | No for text-only; yes when it wraps elements | -| `a` (no `btn` class) | `base.link` | `text` = `el.textContent`, `href`, `target` | No for text-only; yes when it wraps elements | +| `a` with class `btn` | `base.button`, or `base.link` when it wraps element children | `label` (`text` on `base.link`) = `el.textContent`, `href`, `target` (normalised, see below) | No for text-only; yes when it wraps elements | +| `a` (no `btn` class) | `base.link` | `text` = `el.textContent`, `href`, `target` (normalised, see below) | No for text-only; yes when it wraps elements | | `img` | `base.image` | `src`, plus `loading` / `decoding` / `fetchPriority` when the attribute holds a value the module offers; `alt` is reported in `imageAlts` for the media record, not stored as a prop | No | | `form` | `base.form` | `mode`, `formId`, CMS data attrs, custom `action` / `method` | Yes | | `label` | `base.label` unless wrapping elements, then `base.container` | `text`, `targetMode`, `targetId` | No for plain labels; yes for wrapper labels | @@ -122,6 +122,7 @@ Callers splice the fragment into the page tree via `insertImportedNodes(parentId - **Direct text inside a recursing container is preserved.** The walker iterates `childNodes` (not just `children`): element children route through the rules, and each significant text node becomes a synthesized `base.text` child with `tag: 'none'` in document order. That no-wrapper text mode publishes back to bare text, so `
98%
` and `
  • Buy milk
  • ` import as containers holding their original text without adding selector-visible wrapper elements. Whitespace-only text (indentation between tags) is skipped; internal whitespace runs collapse to single spaces, and boundary spaces are kept when the text run sits between element siblings. - **`` metadata is preserved separately.** Classes, safe HTML attributes (`id`, ARIA, `data-*`, etc.), and harvested inline styles on `` are returned as `fragment.body` rather than inserted into `rootIds`. Full-site import applies them to `base.body`; paste-style HTML import can ignore them without changing the fragment structure. - `base.link` uses the prop `text` (not `label`). `base.button` uses `label` (not `text`). These match the module source. +- **`target` is normalised to the module vocabulary.** `base.link` and `base.button` persist only `_self`, `_blank` and `_parent` (`AnchorTargetSchema` in `@core/htmlAttributes`). Other authored values map to the one that navigates the same way outside a frameset: an empty `target=""`, a bare `target` and `_top` import as `_self`; a named browsing context (`target="sidebar"`, `_new`), which opens a new tab when no frame has that name, imports as `_blank`. Keywords match case-insensitively. Copying it verbatim would leave a prop the publisher's schema rejects, and the whole node would then render with module defaults instead of its authored `href` and text. - **Button-like elements keep what they wrap.** `base.button` is `canHaveChildren: false`, so an `a.btn` or a `