@elastic/isomer-sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/README.md +13 -2
  2. package/dist/author/authored_fields.d.ts +61 -11
  3. package/dist/author/authored_fields.d.ts.map +1 -1
  4. package/dist/author/authored_fields.js +73 -29
  5. package/dist/author/authored_fields.js.map +1 -1
  6. package/dist/author/authoring_input.d.ts +7 -0
  7. package/dist/author/authoring_input.d.ts.map +1 -0
  8. package/dist/author/authoring_input.js +60 -0
  9. package/dist/author/authoring_input.js.map +1 -0
  10. package/dist/author/authoring_model.d.ts +27 -0
  11. package/dist/author/authoring_model.d.ts.map +1 -0
  12. package/dist/author/authoring_model.js +98 -0
  13. package/dist/author/authoring_model.js.map +1 -0
  14. package/dist/author/declarations.d.ts +13 -0
  15. package/dist/author/declarations.d.ts.map +1 -0
  16. package/dist/author/declarations.js +277 -0
  17. package/dist/author/declarations.js.map +1 -0
  18. package/dist/author/index.d.ts +3 -1
  19. package/dist/author/index.d.ts.map +1 -1
  20. package/dist/author/index.js +3 -1
  21. package/dist/author/index.js.map +1 -1
  22. package/dist/author/jsx_shim.d.ts +6 -5
  23. package/dist/author/jsx_shim.d.ts.map +1 -1
  24. package/dist/author/jsx_shim.js +28 -111
  25. package/dist/author/jsx_shim.js.map +1 -1
  26. package/dist/author/schema_to_typescript.d.ts +37 -0
  27. package/dist/author/schema_to_typescript.d.ts.map +1 -0
  28. package/dist/author/schema_to_typescript.js +286 -0
  29. package/dist/author/schema_to_typescript.js.map +1 -0
  30. package/dist/cjs/author/authored_fields.js +77 -33
  31. package/dist/cjs/author/authored_fields.js.map +1 -1
  32. package/dist/cjs/author/authoring_input.js +64 -0
  33. package/dist/cjs/author/authoring_input.js.map +1 -0
  34. package/dist/cjs/author/authoring_model.js +104 -0
  35. package/dist/cjs/author/authoring_model.js.map +1 -0
  36. package/dist/cjs/author/declarations.js +281 -0
  37. package/dist/cjs/author/declarations.js.map +1 -0
  38. package/dist/cjs/author/index.js +6 -1
  39. package/dist/cjs/author/index.js.map +1 -1
  40. package/dist/cjs/author/jsx_shim.js +31 -114
  41. package/dist/cjs/author/jsx_shim.js.map +1 -1
  42. package/dist/cjs/author/schema_to_typescript.js +295 -0
  43. package/dist/cjs/author/schema_to_typescript.js.map +1 -0
  44. package/dist/cjs/composition/body_node_base.js +11 -4
  45. package/dist/cjs/composition/body_node_base.js.map +1 -1
  46. package/dist/cjs/composition/error.js +1 -0
  47. package/dist/cjs/composition/error.js.map +1 -1
  48. package/dist/cjs/composition/index.js +2 -1
  49. package/dist/cjs/composition/index.js.map +1 -1
  50. package/dist/cjs/define/frame.js +2 -3
  51. package/dist/cjs/define/frame.js.map +1 -1
  52. package/dist/cjs/define/index.js +7 -1
  53. package/dist/cjs/define/index.js.map +1 -1
  54. package/dist/cjs/define/primitive_example.js +26 -0
  55. package/dist/cjs/define/primitive_example.js.map +1 -0
  56. package/dist/cjs/define/primitive_icon.js +17 -0
  57. package/dist/cjs/define/primitive_icon.js.map +1 -0
  58. package/dist/cjs/define/primitive_module.js +14 -3
  59. package/dist/cjs/define/primitive_module.js.map +1 -1
  60. package/dist/cjs/define/slack_assets.js.map +1 -1
  61. package/dist/cjs/entries/index.js +7 -2
  62. package/dist/cjs/entries/index.js.map +1 -1
  63. package/dist/cjs/entries/slack.js +1 -2
  64. package/dist/cjs/entries/slack.js.map +1 -1
  65. package/dist/cjs/pack/capabilities.js +17 -11
  66. package/dist/cjs/pack/capabilities.js.map +1 -1
  67. package/dist/cjs/pack/compose.js +4 -1
  68. package/dist/cjs/pack/compose.js.map +1 -1
  69. package/dist/cjs/pack/index.js.map +1 -1
  70. package/dist/cjs/pack/primitive_pack.js +14 -2
  71. package/dist/cjs/pack/primitive_pack.js.map +1 -1
  72. package/dist/cjs/render/anchors.js +1 -1
  73. package/dist/cjs/render/anchors.js.map +1 -1
  74. package/dist/cjs/render/html/envelope.js.map +1 -1
  75. package/dist/cjs/render/layout_check.js.map +1 -1
  76. package/dist/cjs/render/markdown/builder.js +14 -8
  77. package/dist/cjs/render/markdown/builder.js.map +1 -1
  78. package/dist/cjs/render/markdown/format.js +30 -12
  79. package/dist/cjs/render/markdown/format.js.map +1 -1
  80. package/dist/cjs/render/primitive_dispatch.js +11 -25
  81. package/dist/cjs/render/primitive_dispatch.js.map +1 -1
  82. package/dist/cjs/render/slack/format.js +1 -601
  83. package/dist/cjs/render/slack/format.js.map +1 -1
  84. package/dist/cjs/render/slack/index.js +1 -2
  85. package/dist/cjs/render/slack/index.js.map +1 -1
  86. package/dist/cjs/render/slack/markdown_content.js +166 -115
  87. package/dist/cjs/render/slack/markdown_content.js.map +1 -1
  88. package/dist/cjs/testing/conformance.js +40 -24
  89. package/dist/cjs/testing/conformance.js.map +1 -1
  90. package/dist/cjs/testing/icon.js +248 -0
  91. package/dist/cjs/testing/icon.js.map +1 -0
  92. package/dist/cjs/testing/index.js +3 -1
  93. package/dist/cjs/testing/index.js.map +1 -1
  94. package/dist/cjs/testing/registration.js +5 -3
  95. package/dist/cjs/testing/registration.js.map +1 -1
  96. package/dist/cjs/validate/authoring_schema.js +17 -1
  97. package/dist/cjs/validate/authoring_schema.js.map +1 -1
  98. package/dist/cjs/validate/index.js +2 -1
  99. package/dist/cjs/validate/index.js.map +1 -1
  100. package/dist/cjs/validate/validation.js +2 -45
  101. package/dist/cjs/validate/validation.js.map +1 -1
  102. package/dist/composition/body_node_base.d.ts +7 -6
  103. package/dist/composition/body_node_base.d.ts.map +1 -1
  104. package/dist/composition/body_node_base.js +10 -3
  105. package/dist/composition/body_node_base.js.map +1 -1
  106. package/dist/composition/error.d.ts +1 -0
  107. package/dist/composition/error.d.ts.map +1 -1
  108. package/dist/composition/error.js +1 -0
  109. package/dist/composition/error.js.map +1 -1
  110. package/dist/composition/index.d.ts +1 -1
  111. package/dist/composition/index.d.ts.map +1 -1
  112. package/dist/composition/index.js +1 -1
  113. package/dist/composition/index.js.map +1 -1
  114. package/dist/define/frame.d.ts +9 -20
  115. package/dist/define/frame.d.ts.map +1 -1
  116. package/dist/define/frame.js +2 -3
  117. package/dist/define/frame.js.map +1 -1
  118. package/dist/define/index.d.ts +3 -1
  119. package/dist/define/index.d.ts.map +1 -1
  120. package/dist/define/index.js +3 -1
  121. package/dist/define/index.js.map +1 -1
  122. package/dist/define/primitive_example.d.ts +30 -0
  123. package/dist/define/primitive_example.d.ts.map +1 -0
  124. package/dist/define/primitive_example.js +21 -0
  125. package/dist/define/primitive_example.js.map +1 -0
  126. package/dist/define/primitive_icon.d.ts +11 -0
  127. package/dist/define/primitive_icon.d.ts.map +1 -0
  128. package/dist/define/primitive_icon.js +14 -0
  129. package/dist/define/primitive_icon.js.map +1 -0
  130. package/dist/define/primitive_module.d.ts +38 -24
  131. package/dist/define/primitive_module.d.ts.map +1 -1
  132. package/dist/define/primitive_module.js +14 -3
  133. package/dist/define/primitive_module.js.map +1 -1
  134. package/dist/define/slack_assets.d.ts +1 -1
  135. package/dist/define/slack_assets.d.ts.map +1 -1
  136. package/dist/define/slack_assets.js.map +1 -1
  137. package/dist/entries/index.d.ts +3 -3
  138. package/dist/entries/index.d.ts.map +1 -1
  139. package/dist/entries/index.js +2 -2
  140. package/dist/entries/index.js.map +1 -1
  141. package/dist/entries/slack.d.ts +1 -1
  142. package/dist/entries/slack.d.ts.map +1 -1
  143. package/dist/entries/slack.js +1 -1
  144. package/dist/entries/slack.js.map +1 -1
  145. package/dist/pack/capabilities.d.ts +24 -10
  146. package/dist/pack/capabilities.d.ts.map +1 -1
  147. package/dist/pack/capabilities.js +17 -11
  148. package/dist/pack/capabilities.js.map +1 -1
  149. package/dist/pack/compose.d.ts +4 -1
  150. package/dist/pack/compose.d.ts.map +1 -1
  151. package/dist/pack/compose.js +4 -1
  152. package/dist/pack/compose.js.map +1 -1
  153. package/dist/pack/index.d.ts +1 -1
  154. package/dist/pack/index.d.ts.map +1 -1
  155. package/dist/pack/index.js +1 -1
  156. package/dist/pack/index.js.map +1 -1
  157. package/dist/pack/primitive_pack.d.ts +11 -2
  158. package/dist/pack/primitive_pack.d.ts.map +1 -1
  159. package/dist/pack/primitive_pack.js +12 -1
  160. package/dist/pack/primitive_pack.js.map +1 -1
  161. package/dist/render/anchors.d.ts +2 -2
  162. package/dist/render/anchors.d.ts.map +1 -1
  163. package/dist/render/anchors.js +1 -1
  164. package/dist/render/anchors.js.map +1 -1
  165. package/dist/render/html/envelope.d.ts +3 -3
  166. package/dist/render/html/envelope.js.map +1 -1
  167. package/dist/render/layout_check.d.ts +1 -1
  168. package/dist/render/layout_check.d.ts.map +1 -1
  169. package/dist/render/layout_check.js.map +1 -1
  170. package/dist/render/markdown/builder.d.ts +2 -4
  171. package/dist/render/markdown/builder.d.ts.map +1 -1
  172. package/dist/render/markdown/builder.js +14 -7
  173. package/dist/render/markdown/builder.js.map +1 -1
  174. package/dist/render/markdown/format.d.ts +7 -0
  175. package/dist/render/markdown/format.d.ts.map +1 -1
  176. package/dist/render/markdown/format.js +27 -11
  177. package/dist/render/markdown/format.js.map +1 -1
  178. package/dist/render/primitive_dispatch.d.ts +6 -6
  179. package/dist/render/primitive_dispatch.d.ts.map +1 -1
  180. package/dist/render/primitive_dispatch.js +12 -26
  181. package/dist/render/primitive_dispatch.js.map +1 -1
  182. package/dist/render/slack/format.d.ts +0 -25
  183. package/dist/render/slack/format.d.ts.map +1 -1
  184. package/dist/render/slack/format.js +1 -599
  185. package/dist/render/slack/format.js.map +1 -1
  186. package/dist/render/slack/index.d.ts +1 -1
  187. package/dist/render/slack/index.d.ts.map +1 -1
  188. package/dist/render/slack/index.js +1 -1
  189. package/dist/render/slack/index.js.map +1 -1
  190. package/dist/render/slack/markdown_content.d.ts +10 -4
  191. package/dist/render/slack/markdown_content.d.ts.map +1 -1
  192. package/dist/render/slack/markdown_content.js +163 -113
  193. package/dist/render/slack/markdown_content.js.map +1 -1
  194. package/dist/testing/conformance.d.ts +19 -14
  195. package/dist/testing/conformance.d.ts.map +1 -1
  196. package/dist/testing/conformance.js +40 -24
  197. package/dist/testing/conformance.js.map +1 -1
  198. package/dist/testing/icon.d.ts +11 -0
  199. package/dist/testing/icon.d.ts.map +1 -0
  200. package/dist/testing/icon.js +244 -0
  201. package/dist/testing/icon.js.map +1 -0
  202. package/dist/testing/index.d.ts +2 -1
  203. package/dist/testing/index.d.ts.map +1 -1
  204. package/dist/testing/index.js +1 -0
  205. package/dist/testing/index.js.map +1 -1
  206. package/dist/testing/registration.d.ts +1 -1
  207. package/dist/testing/registration.d.ts.map +1 -1
  208. package/dist/testing/registration.js +6 -4
  209. package/dist/testing/registration.js.map +1 -1
  210. package/dist/validate/authoring_schema.d.ts +6 -0
  211. package/dist/validate/authoring_schema.d.ts.map +1 -1
  212. package/dist/validate/authoring_schema.js +15 -0
  213. package/dist/validate/authoring_schema.js.map +1 -1
  214. package/dist/validate/index.d.ts +1 -1
  215. package/dist/validate/index.d.ts.map +1 -1
  216. package/dist/validate/index.js +1 -1
  217. package/dist/validate/index.js.map +1 -1
  218. package/dist/validate/validation.d.ts +1 -11
  219. package/dist/validate/validation.d.ts.map +1 -1
  220. package/dist/validate/validation.js +3 -46
  221. package/dist/validate/validation.js.map +1 -1
  222. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../../src/render/html/envelope.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport { createElement, Fragment, type ReactNode } from 'react';\nimport { renderToStaticMarkup } from 'react-dom/server';\nimport {\n type Comment as JavaScriptComment,\n type Node as JavaScriptNode,\n parse,\n} from 'acorn';\n\nimport {\n type ChildNodeWalker,\n createChildNodeWalker,\n} from '../../composition/body_node_base';\nimport type { Composition } from '../../composition/composition';\nimport type { RenderTheme } from '../../composition/named_color';\nimport type { ValidationError } from '../../composition/validation_error';\nimport type {\n AnyPrimitiveDefinition,\n PrimitiveNode,\n PrimitiveStyleCollectionContext,\n PrimitiveStyleCollector,\n StyledRenderContext,\n StyleHandle,\n} from '../../define/primitive_module';\nimport {\n EMBEDDED_SCRIPT_ATTRIBUTE,\n resolveEnhancements,\n scopeScript,\n} from '../../pack/enhancements';\nimport {\n type CheckedValidationResult,\n compositionToRender,\n createCompositionValidator,\n enforceValidationMode,\n type ValidationErrorMode,\n} from '../../validate/validation';\nimport { withAnchors } from '../anchors';\nimport { contextWith } from '../context_view';\nimport { byteLength, type PayloadMeasurement } from '../payload';\nimport {\n type ReactContentDispatcher,\n renderCompositionContent,\n wrapCompositionContent,\n} from '../react/content';\n\nimport {\n embedScript,\n type EnhancementDefinition,\n enhancementScript,\n} from './enhancements';\n\n/** Knobs for the HTML surface. Every field defaults, so `{}` is valid. */\nexport interface HTMLRenderOptions {\n /** Overrides {@link Composition.theme}; `auto` when neither is set. */\n theme?: RenderTheme;\n /** Drops whitespace between tags that spans a line break, leaving `<pre>`, `<script>`, `<style>`, and `<textarea>` content intact. Defaults to `true`. */\n minify?: boolean;\n /** Adds the `fluid` wrapper class and reaches the pack as {@link PrimitiveStyleCollectionContext.fluid}; the adapter decides what it changes. */\n fluid?: boolean;\n /** Adds the `framed` wrapper class the adapter styles as a frame. Defaults to `true`. */\n framed?: boolean;\n /**\n * Renders the composition's title and subtitle. Defaults to `true`. Set\n * `false` when the embedding host already shows the title itself — the title\n * still backs the wrapper's `aria-label`.\n */\n heading?: boolean;\n /** Whether the collected CSS is inlined as a `<style>` element. Defaults to `'inline'`. */\n css?: 'inline' | 'separate';\n /**\n * Who runs the enhancement script. Defaults to `'embedded'`: `html` carries\n * a `<script>` that finds its own `.isomer` section when the page parses it.\n *\n * `'embedded'` never runs inside a shadow root, or anywhere the host inserts\n * `html` itself (`innerHTML`, a React tree). Use `'host'` there: `html`\n * carries no `<script>`, and the host calls `runEnhancementScript(js,\n * section)` after inserting it.\n */\n scripts?: 'embedded' | 'host';\n /** Defaults to collecting into {@link HTMLRenderResult.validationErrors}; `'throw'` raises instead. Input the budget refused raises in either mode. */\n onValidationError?: ValidationErrorMode;\n /** Opt-in by {@link EnhancementDefinition.id}. One whose content gate does not match the body is dropped. */\n enhancements?: readonly string[];\n /** `true` renders node anchors whether or not an enhancement asks for them, e.g. for tests. `false` cannot turn off anchors an enhancement needs. */\n anchors?: boolean;\n /**\n * Resolves `light-dark(…)` in the stylesheet to one scheme's value. A browser\n * resolves it itself; an image is one static frame, so the `svg` surface sets\n * it.\n */\n scheme?: 'light' | 'dark';\n}\n\n/**\n * One rendered HTML payload.\n *\n * `body` is the primitive markup alone; `html` adds the wrapper element, on\n * the default `css: 'inline'` a `<style>`, and on the default\n * `scripts: 'embedded'` a `<script>`. `css` and `js` are populated either way.\n * `validationErrors` are the messages that survived\n * {@link HTMLRenderOptions.onValidationError}.\n */\nexport interface HTMLRenderResult {\n html: string;\n css: string;\n /**\n * The enhancement script as a function body over `root`, or `''`. Under\n * `scripts: 'embedded'` the `<script>` in `html` wraps the same body; under\n * `'host'` the host runs it with `runEnhancementScript`. It is never a\n * complete script on its own.\n */\n js: string;\n body: string;\n measurement: PayloadMeasurement;\n validationErrors: ValidationError[];\n}\n\n/**\n * A pack's HTML entry point: the React renderer plus the style pass that runs\n * ahead of it.\n */\nexport interface HTMLRenderDispatcher<\n TNode extends PrimitiveNode,\n TCollector extends PrimitiveStyleCollector = PrimitiveStyleCollector,\n TContext = StyledRenderContext,\n> extends ReactContentDispatcher<TNode, TContext> {\n /** The whole composition's inventory: a child walker built from one pack's definitions cannot descend into another pack's container. */\n readonly definitions: readonly AnyPrimitiveDefinition[];\n /** One node's style pass, driven by {@link HTMLStyleAdapter.collectViewStyles} rather than called by the sdk. */\n collectStyles(\n node: TNode,\n collector: TCollector,\n context: PrimitiveStyleCollectionContext\n ): void;\n}\n\n/**\n * The composition's child walker and the enhancements every loaded pack\n * declared. Threaded into the style adapter so content-gating can see a\n * table nested inside a container from another package.\n */\nexport interface HTMLEnhancementScope {\n walk: ChildNodeWalker;\n definitions: readonly EnhancementDefinition[];\n}\n\n/**\n * How a pack turns its nodes into CSS. Optional overall — without an adapter\n * the render still produces markup, just with no class names and an empty\n * `TContext`.\n */\nexport interface HTMLStyleAdapter<\n TNode extends PrimitiveNode = PrimitiveNode,\n TCollector extends PrimitiveStyleCollector = PrimitiveStyleCollector,\n TContext = StyledRenderContext,\n> {\n /**\n * Names the collector shape {@link HTMLStyleAdapter.createCollector} returns, so a runtime can\n * reject a pack whose `collectStyles` hooks were written against a different one.\n */\n styleCollector?: string;\n /** One collector per render, shared by every other hook here and by both render passes. */\n createCollector(options: HTMLRenderOptions): TCollector;\n /**\n * Settles options that depend on the composition, before anything reads them.\n *\n * Needed by an adapter whose look is chosen per render: deciding `framed`\n * from the body has to happen before the wrapper class is written, not while\n * CSS is collected.\n */\n resolveOptions?(\n composition: Composition<TNode>,\n options: HTMLRenderOptions\n ): HTMLRenderOptions;\n /**\n * The `.isomer` / `.isomer.framed` / `.isomer.fluid` rules around a rendered composition.\n * Named for the wrapper rather than the frame, which the sdk reserves for a\n * pack's svg document surround.\n */\n collectWrapperStyles?(\n collector: TCollector,\n options: HTMLRenderOptions\n ): void;\n /** Walks the body into the collector, usually through {@link HTMLRenderDispatcher.collectStyles}. Runs before any markup exists. */\n collectViewStyles?(\n composition: Composition<TNode>,\n dispatcher: HTMLRenderDispatcher<TNode, TCollector, TContext>,\n collector: TCollector,\n context: PrimitiveStyleCollectionContext,\n options: HTMLRenderOptions,\n scope: HTMLEnhancementScope\n ): void;\n /** Runs once the collection pass has rendered the body, for styles only a renderer can discover. That markup is discarded. */\n collectAfterRender?(\n composition: Composition<TNode>,\n collector: TCollector,\n options: HTMLRenderOptions\n ): void;\n /**\n * Builds the render context handed to every `react` renderer. Called once\n * per pass, so an adapter that behaves differently while collecting returns\n * a different context then. Must be complete, because `TContext` is the\n * pack's own type. The sdk never writes to it: whether renderers anchor\n * is the surface's decision, whatever the context's `anchors` says.\n */\n createRenderContext(\n collector: TCollector,\n options: HTMLRenderOptions\n ): TContext;\n /** The collected CSS as text, with no `<style>` wrapper; the sdk adds one when `css` is `'inline'`. */\n renderStyles(collector: TCollector, options: HTMLRenderOptions): string;\n /**\n * Whether `handle` belongs to this adapter's stylesheet.\n *\n * Unused on a lone adapter. A runtime composing several packs' adapters\n * routes each handle to its owner, so CSS is neither duplicated nor\n * rendered against the wrong theme. An adapter that cannot answer this\n * cannot be combined with another.\n */\n ownsHandle?(handle: StyleHandle): boolean;\n /**\n * Appended after {@link HTMLDispatcherRenderOptions.scriptText} into the\n * render's one script. A function body with `root` in scope, under the same\n * rules as {@link EnhancementDefinition.script}.\n */\n getScriptText?(\n composition: Composition<TNode>,\n options: HTMLRenderOptions,\n scope: HTMLEnhancementScope\n ): string;\n}\n\n/** What {@link renderHTMLWithDispatcher} needs beyond the composition. */\nexport interface HTMLDispatcherRenderOptions<\n TNode extends PrimitiveNode,\n TCollector extends PrimitiveStyleCollector = PrimitiveStyleCollector,\n TContext = StyledRenderContext,\n> {\n dispatcher: HTMLRenderDispatcher<TNode, TCollector, TContext>;\n /** Runs once before rendering, which draws the composition it returns; {@link HTMLRenderOptions.onValidationError} decides what becomes of its errors. Defaults to `createCompositionValidator(dispatcher.definitions)`. */\n validate?: (\n composition: Composition<TNode>\n ) => CheckedValidationResult<TNode>;\n options?: HTMLRenderOptions;\n /** Used only when the composition has neither `meta.ariaLabel` nor a `title`. Defaults to `'View'`. */\n defaultAriaLabel?: string;\n styleAdapter?: HTMLStyleAdapter<TNode, TCollector, TContext>;\n /**\n * Emitted unescaped ahead of {@link HTMLStyleAdapter.getScriptText}. A\n * function body with `root` in scope, under the same rules as\n * {@link EnhancementDefinition.script}.\n */\n scriptText?: string;\n /**\n * Progressive enhancements declared by the packs this render was composed\n * from. The render resolves {@link HTMLRenderOptions.enhancements} against\n * them once, hands every renderer the set as `context.enhancements`, and\n * emits each resolved one's script.\n */\n enhancementDefinitions?: readonly EnhancementDefinition[];\n}\n\n/**\n * Renders a composition to standalone HTML: the wrapper element, the pack's\n * markup, and its CSS either inlined or returned separately.\n *\n * Runs the pack twice when a style adapter is present — once to collect\n * styles, once with the render context those styles produced — so a\n * `renderReact` implementation must be free of side effects.\n */\nexport const renderHTMLWithDispatcher = <\n TNode extends PrimitiveNode,\n TCollector extends PrimitiveStyleCollector = PrimitiveStyleCollector,\n TContext = StyledRenderContext,\n>(\n input: Composition<TNode>,\n {\n dispatcher,\n validate = createCompositionValidator<TNode>(dispatcher.definitions),\n options: rawOptions = {},\n defaultAriaLabel = 'View',\n styleAdapter,\n scriptText = '',\n enhancementDefinitions = [],\n }: HTMLDispatcherRenderOptions<TNode, TCollector, TContext>\n): HTMLRenderResult => {\n const validation = validate(input);\n const composition = compositionToRender(validation);\n // Resolved before the validation mode is read, so an adapter can derive\n // `onValidationError`.\n const options =\n styleAdapter?.resolveOptions?.(composition, rawOptions) ?? rawOptions;\n enforceValidationMode(validation, options.onValidationError);\n const framed = options.framed ?? true;\n const heading = options.heading ?? true;\n const theme = options.theme ?? composition.theme ?? 'auto';\n const cssMode = options.css ?? 'inline';\n const scriptsMode = options.scripts ?? 'embedded';\n const styleState = styleAdapter?.createCollector(options);\n const enhancementScope: HTMLEnhancementScope = {\n walk: createChildNodeWalker(dispatcher.definitions),\n definitions: enhancementDefinitions,\n };\n const applied = resolveEnhancements(\n composition.body,\n enhancementScope.walk,\n enhancementDefinitions,\n options.enhancements ?? []\n );\n const enhancements: ReadonlySet<string> = new Set(\n applied.map(({ id }) => id)\n );\n const anchors =\n options.anchors === true || applied.some(({ anchors }) => anchors);\n const enhanced = (context: TContext): TContext =>\n contextWith(context, 'enhancements', enhancements);\n\n if (styleState) {\n styleAdapter?.collectWrapperStyles?.(styleState, options);\n styleAdapter?.collectViewStyles?.(\n composition,\n dispatcher,\n styleState,\n { fluid: Boolean(options.fluid) },\n options,\n enhancementScope\n );\n const collectionContext = enhanced(\n styleAdapter?.createRenderContext(styleState, options) as TContext\n );\n withAnchors(anchors, () =>\n renderToStaticMarkup(\n createElement(() =>\n renderCompositionContent(composition, dispatcher, collectionContext, {\n heading,\n })\n )\n )\n );\n styleAdapter?.collectAfterRender?.(composition, styleState, options);\n }\n\n const renderContext = enhanced(\n styleState && styleAdapter\n ? styleAdapter.createRenderContext(styleState, options)\n : // No adapter means no class names and no css vars to resolve.\n ({} as TContext)\n );\n const cssText =\n styleState && styleAdapter\n ? styleAdapter.renderStyles(styleState, options)\n : '';\n const adapterScriptText =\n styleAdapter?.getScriptText?.(composition, options, enhancementScope) ?? '';\n const js = [\n ...[scriptText, adapterScriptText].filter(Boolean).map(scopeScript),\n enhancementScript(applied),\n ]\n .filter(Boolean)\n .join('\\n');\n const embeddedScript =\n js && scriptsMode === 'embedded' ? embedScript(js) : '';\n const body = withAnchors(anchors, () =>\n renderToStaticMarkup(\n createElement(() =>\n renderCompositionContent(composition, dispatcher, renderContext, {\n heading,\n })\n )\n )\n );\n const inlineCss = cssMode === 'inline' ? embedCss(cssText) : '';\n const inlineJs = embeddedScript ? embedJs(embeddedScript) : '';\n const raw = renderToStaticMarkup(\n createElement(RenderedHtmlView<TNode>, {\n composition,\n theme,\n fluid: Boolean(options.fluid),\n framed,\n styleText: inlineCss || undefined,\n scriptText: inlineJs || undefined,\n defaultAriaLabel,\n body,\n })\n );\n const html = options.minify === false ? raw : minifyHtml(raw);\n\n // Inline payloads are measured as emitted, escapes included.\n const inlineCssBytes = byteLength(inlineCss);\n const inlineJsBytes = byteLength(inlineJs);\n const separateCssBytes = cssMode === 'inline' ? 0 : byteLength(cssText);\n const separateJsBytes = embeddedScript ? 0 : byteLength(js);\n\n return {\n html,\n css: cssText,\n js,\n body,\n measurement: {\n html: byteLength(html) - inlineCssBytes - inlineJsBytes,\n css: inlineCssBytes + separateCssBytes,\n js: inlineJsBytes + separateJsBytes,\n total: byteLength(html) + separateCssBytes + separateJsBytes,\n },\n validationErrors: validation.errors,\n };\n};\n\ninterface RenderedHtmlViewProps<TNode extends PrimitiveNode> {\n composition: Composition<TNode>;\n theme: RenderTheme;\n fluid: boolean;\n framed: boolean;\n styleText?: string | undefined;\n scriptText?: string | undefined;\n defaultAriaLabel: string;\n body: string;\n}\n\n// Only `</style` ends a `<style>`. `\\/` is a CSS escape for `/`, so a string\n// holding it keeps its value.\nconst embedCss = (css: string): string => css.replace(/<\\/(?=style)/gi, '<\\\\/');\n\ninterface ScriptNode extends JavaScriptNode {\n tag: ScriptNode;\n quasi: ScriptNode;\n quasis: ScriptNode[];\n expressions: ScriptNode[];\n value: { raw: string; cooked: string | null };\n name?: string;\n}\n\n// Tagged templates observe raw spelling and reuse the same frozen object per site.\nconst embedJs = (js: string): string => {\n if (!/<\\/script|<!--/i.test(js)) return js;\n const comments: JavaScriptComment[] = [];\n const tree = parse(js, { ecmaVersion: 'latest', onComment: comments });\n const sites: ScriptNode[] = [];\n const identifiers = new Set<string>();\n const pending: JavaScriptNode[] = [tree];\n while (pending.length) {\n const node = pending.pop()! as ScriptNode;\n if (node.type === 'Identifier' && node.name) identifiers.add(node.name);\n if (\n node.type === 'TaggedTemplateExpression' &&\n node.quasi.quasis.some(({ value: { raw } }) =>\n /<\\/script|<!--/i.test(raw)\n )\n )\n sites.push(node);\n for (const value of Object.values(node)) {\n for (const child of Array.isArray(value) ? value : [value]) {\n if (\n child &&\n typeof child === 'object' &&\n 'type' in child &&\n 'start' in child\n ) {\n pending.push(child as JavaScriptNode);\n }\n }\n }\n }\n sites.sort((a, b) => a.start - b.start);\n let prefix = '__isomerTemplate';\n while ([...identifiers].some((name) => name.startsWith(prefix)))\n prefix += '_';\n const literal = (value: string | null): string =>\n value === null ? 'void 0' : JSON.stringify(value).replace(/</g, '\\\\u003c');\n const rewrite = (start: number, end: number): string => {\n let cursor = start;\n let result = '';\n const edits = [\n ...sites.map((site, index) => ({\n ...site,\n index,\n comment: undefined as string | undefined,\n })),\n ...comments\n .filter(({ start }) => /^(?:<!--|-->)/.test(js.slice(start, start + 4)))\n .map((comment) => ({ ...comment, index: -1, comment: comment.value })),\n ].sort((a, b) => a.start - b.start);\n for (const edit of edits) {\n if (edit.start < cursor || edit.end > end) continue;\n result += js.slice(cursor, edit.start);\n if (edit.comment !== undefined) {\n result += `//${edit.comment}`;\n } else {\n const site = sites[edit.index]!;\n const {\n tag,\n quasi: { quasis, expressions },\n } = site;\n const cooked = quasis\n .map(({ value }) => literal(value.cooked))\n .join(',');\n const raw = quasis.map(({ value }) => literal(value.raw)).join(',');\n const cache = `${prefix}${edit.index}`;\n const template = `${cache} ??= ${prefix}Freeze(${prefix}Define([${cooked}], 'raw', {value:${prefix}Freeze([${raw}])}))`;\n const args = expressions.map((expression) =>\n rewrite(expression.start, expression.end)\n );\n result += `(${rewrite(tag.start, tag.end)})(${template}${args.map((arg) => `,(${arg})`).join('')})`;\n }\n cursor = edit.end;\n }\n return result + js.slice(cursor, end);\n };\n const rewritten = rewrite(0, js.length);\n const scoped = sites.length\n ? `(function(){const ${prefix}Freeze=Object.freeze,${prefix}Define=Object.defineProperty;let ${sites.map((_site, index) => `${prefix}${index}`).join(',')};\\n${rewritten}\\n})();`\n : rewritten;\n return scoped\n .replace(/<\\/(?=script)/gi, '<\\\\/')\n .replace(/<!--/g, (_match, at: number, source: string) =>\n escapedBy(source, at) ? 'x3C!--' : '\\\\x3C!--'\n );\n};\n\nconst escapedBy = (source: string, at: number): boolean => {\n let slashes = 0;\n while (source[at - slashes - 1] === '\\\\') slashes += 1;\n return slashes % 2 === 1;\n};\n\nconst RenderedHtmlView = <TNode extends PrimitiveNode>({\n composition,\n theme,\n fluid,\n framed,\n styleText,\n scriptText,\n defaultAriaLabel,\n body,\n}: RenderedHtmlViewProps<TNode>): ReactNode =>\n wrapCompositionContent(\n createElement(\n Fragment,\n null,\n styleText\n ? createElement('style', {\n key: 'style',\n dangerouslySetInnerHTML: { __html: styleText },\n })\n : null,\n createElement('div', {\n key: 'body',\n dangerouslySetInnerHTML: { __html: body },\n }),\n scriptText\n ? createElement('script', {\n key: 'script',\n [EMBEDDED_SCRIPT_ATTRIBUTE]: '',\n dangerouslySetInnerHTML: { __html: scriptText },\n })\n : null\n ),\n composition,\n { framed, fluid, theme, defaultAriaLabel }\n );\n\n// Whitespace inside `pre`, `script`, `style`, and `textarea` is content, so\n// those elements match whole and pass through. Elsewhere only whitespace\n// spanning a line break is collapsed: a single space between inline elements\n// (`<b>a</b> <i>b</i>`) is authored content.\nconst MINIFY_RE =\n /<(pre|script|style|textarea)[\\s>][\\s\\S]*?(?:<\\/\\1\\s*>|$)|(?<=>)\\s+(?=<)/gi;\n\nconst minifyHtml = (value: string): string =>\n value\n .replace(MINIFY_RE, (match, element: string | undefined) =>\n element || !match.includes('\\n') ? match : ''\n )\n .trim();\n"]}
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../../src/render/html/envelope.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport { createElement, Fragment, type ReactNode } from 'react';\nimport { renderToStaticMarkup } from 'react-dom/server';\nimport {\n type Comment as JavaScriptComment,\n type Node as JavaScriptNode,\n parse,\n} from 'acorn';\n\nimport {\n type ChildNodeWalker,\n createChildNodeWalker,\n} from '../../composition/body_node_base';\nimport type { Composition } from '../../composition/composition';\nimport type { RenderTheme } from '../../composition/named_color';\nimport type { ValidationError } from '../../composition/validation_error';\nimport type {\n AnyPrimitiveDefinition,\n PrimitiveNode,\n PrimitiveStyleCollectionContext,\n PrimitiveStyleCollector,\n StyledRenderContext,\n StyleHandle,\n} from '../../define/primitive_module';\nimport {\n EMBEDDED_SCRIPT_ATTRIBUTE,\n resolveEnhancements,\n scopeScript,\n} from '../../pack/enhancements';\nimport {\n type CheckedValidationResult,\n compositionToRender,\n createCompositionValidator,\n enforceValidationMode,\n type ValidationErrorMode,\n} from '../../validate/validation';\nimport { withAnchors } from '../anchors';\nimport { contextWith } from '../context_view';\nimport { byteLength, type PayloadMeasurement } from '../payload';\nimport {\n type ReactContentDispatcher,\n renderCompositionContent,\n wrapCompositionContent,\n} from '../react/content';\n\nimport {\n embedScript,\n type EnhancementDefinition,\n enhancementScript,\n} from './enhancements';\n\n/** Knobs for the HTML surface. Every field defaults, so `{}` is valid. */\nexport interface HTMLRenderOptions {\n /** Overrides {@link Composition.theme}; `auto` when neither is set. */\n theme?: RenderTheme;\n /** Drops whitespace between tags that spans a line break, leaving `<pre>`, `<script>`, `<style>`, and `<textarea>` content intact. Defaults to `true`. */\n minify?: boolean;\n /** Adds the `fluid` wrapper class and reaches the pack as {@link PrimitiveStyleCollectionContext.fluid}; the adapter decides what it changes. */\n fluid?: boolean;\n /** Adds the `framed` wrapper class the adapter styles as a frame. Defaults to `true`. */\n framed?: boolean;\n /**\n * Renders the composition's title and subtitle. Defaults to `true`. Set\n * `false` when the embedding host already shows the title itself — the title\n * still backs the wrapper's `aria-label`.\n */\n heading?: boolean;\n /** Whether the collected CSS is inlined as a `<style>` element. Defaults to `'inline'`. */\n css?: 'inline' | 'separate';\n /**\n * Who runs the enhancement script. Defaults to `'embedded'`: `html` carries\n * a `<script>` that finds its own `.isomer` section when the page parses it.\n *\n * `'embedded'` never runs inside a shadow root, or anywhere the host inserts\n * `html` itself (`innerHTML`, a React tree). Use `'host'` there: `html`\n * carries no `<script>`, and the host calls `runEnhancementScript(js,\n * section)` after inserting it.\n */\n scripts?: 'embedded' | 'host';\n /** Defaults to collecting into {@link HTMLRenderResult.validationErrors}; `'throw'` raises instead. Input the budget refused raises in either mode. */\n onValidationError?: ValidationErrorMode;\n /** Opt-in by {@link EnhancementDefinition.id}. One whose content gate does not match the body is dropped. */\n enhancements?: readonly string[];\n /** `true` renders node anchors whether or not an enhancement asks for them, e.g. for tests. `false` cannot turn off anchors an enhancement needs. */\n anchors?: boolean;\n /**\n * Resolves `light-dark(…)` in the stylesheet to one scheme's value. A browser\n * resolves it itself; an image is one static frame, so the `snapshot` surface sets\n * it.\n */\n scheme?: 'light' | 'dark';\n}\n\n/**\n * One rendered HTML payload.\n *\n * `body` is the primitive markup alone; `html` adds the wrapper element, on\n * the default `css: 'inline'` a `<style>`, and on the default\n * `scripts: 'embedded'` a `<script>`. `css` and `js` are populated either way.\n * `validationErrors` are the messages that survived\n * {@link HTMLRenderOptions.onValidationError}.\n */\nexport interface HTMLRenderResult {\n html: string;\n css: string;\n /**\n * The enhancement script as a function body over `root`, or `''`. Under\n * `scripts: 'embedded'` the `<script>` in `html` wraps the same body; under\n * `'host'` the host runs it with `runEnhancementScript`. It is never a\n * complete script on its own.\n */\n js: string;\n body: string;\n measurement: PayloadMeasurement;\n validationErrors: ValidationError[];\n}\n\n/**\n * A pack's HTML entry point: the React renderer plus the style pass that runs\n * ahead of it.\n */\nexport interface HTMLRenderDispatcher<\n TNode extends PrimitiveNode,\n TCollector extends PrimitiveStyleCollector = PrimitiveStyleCollector,\n TContext = StyledRenderContext,\n> extends ReactContentDispatcher<TNode, TContext> {\n /** The whole composition's inventory: a child walker built from one pack's definitions cannot descend into another pack's container. */\n readonly definitions: readonly AnyPrimitiveDefinition[];\n /** One node's style pass, driven by {@link HTMLStyleAdapter.collectViewStyles} rather than called by the sdk. */\n collectStyles(\n node: TNode,\n collector: TCollector,\n context: PrimitiveStyleCollectionContext\n ): void;\n}\n\n/**\n * The composition's child walker and the enhancements every loaded pack\n * declared. Threaded into the style adapter so content-gating can see a\n * table nested inside a container from another package.\n */\nexport interface HTMLEnhancementScope {\n walk: ChildNodeWalker;\n definitions: readonly EnhancementDefinition[];\n}\n\n/**\n * How a pack turns its nodes into CSS. Optional overall — without an adapter\n * the render still produces markup, just with no class names and an empty\n * `TContext`.\n */\nexport interface HTMLStyleAdapter<\n TNode extends PrimitiveNode = PrimitiveNode,\n TCollector extends PrimitiveStyleCollector = PrimitiveStyleCollector,\n TContext = StyledRenderContext,\n> {\n /**\n * Names the collector shape {@link HTMLStyleAdapter.createCollector} returns, so a runtime can\n * reject a pack whose `collectStyles` hooks were written against a different one.\n */\n styleCollector?: string;\n /** One collector per render, shared by every other hook here and by both render passes. */\n createCollector(options: HTMLRenderOptions): TCollector;\n /**\n * Settles options that depend on the composition, before anything reads them.\n *\n * Needed by an adapter whose look is chosen per render: deciding `framed`\n * from the body has to happen before the wrapper class is written, not while\n * CSS is collected.\n */\n resolveOptions?(\n composition: Composition<TNode>,\n options: HTMLRenderOptions\n ): HTMLRenderOptions;\n /**\n * The `.isomer` / `.isomer.framed` / `.isomer.fluid` rules around a rendered composition.\n * Named for the wrapper rather than the frame, which the sdk reserves for the\n * document a snapshot is drawn inside.\n */\n collectWrapperStyles?(\n collector: TCollector,\n options: HTMLRenderOptions\n ): void;\n /** Walks the body into the collector, usually through {@link HTMLRenderDispatcher.collectStyles}. Runs before any markup exists. */\n collectViewStyles?(\n composition: Composition<TNode>,\n dispatcher: HTMLRenderDispatcher<TNode, TCollector, TContext>,\n collector: TCollector,\n context: PrimitiveStyleCollectionContext,\n options: HTMLRenderOptions,\n scope: HTMLEnhancementScope\n ): void;\n /** Runs once the collection pass has rendered the body, for styles only a renderer can discover. That markup is discarded. */\n collectAfterRender?(\n composition: Composition<TNode>,\n collector: TCollector,\n options: HTMLRenderOptions\n ): void;\n /**\n * Builds the render context handed to every `react` renderer. Called once\n * per pass, so an adapter that behaves differently while collecting returns\n * a different context then. Must be complete, because `TContext` is the\n * pack's own type. The sdk never writes to it: whether renderers anchor\n * is the surface's decision, whatever the context's `anchors` says.\n */\n createRenderContext(\n collector: TCollector,\n options: HTMLRenderOptions\n ): TContext;\n /** The collected CSS as text, with no `<style>` wrapper; the sdk adds one when `css` is `'inline'`. */\n renderStyles(collector: TCollector, options: HTMLRenderOptions): string;\n /**\n * Whether `handle` belongs to this adapter's stylesheet.\n *\n * Unused on a lone adapter. A runtime composing several packs' adapters\n * routes each handle to its owner, so CSS is neither duplicated nor\n * rendered against the wrong theme. An adapter that cannot answer this\n * cannot be combined with another.\n */\n ownsHandle?(handle: StyleHandle): boolean;\n /**\n * Appended after {@link HTMLDispatcherRenderOptions.scriptText} into the\n * render's one script. A function body with `root` in scope, under the same\n * rules as {@link EnhancementDefinition.script}.\n */\n getScriptText?(\n composition: Composition<TNode>,\n options: HTMLRenderOptions,\n scope: HTMLEnhancementScope\n ): string;\n}\n\n/** What {@link renderHTMLWithDispatcher} needs beyond the composition. */\nexport interface HTMLDispatcherRenderOptions<\n TNode extends PrimitiveNode,\n TCollector extends PrimitiveStyleCollector = PrimitiveStyleCollector,\n TContext = StyledRenderContext,\n> {\n dispatcher: HTMLRenderDispatcher<TNode, TCollector, TContext>;\n /** Runs once before rendering, which draws the composition it returns; {@link HTMLRenderOptions.onValidationError} decides what becomes of its errors. Defaults to `createCompositionValidator(dispatcher.definitions)`. */\n validate?: (\n composition: Composition<TNode>\n ) => CheckedValidationResult<TNode>;\n options?: HTMLRenderOptions;\n /** Used only when the composition has neither `meta.ariaLabel` nor a `title`. Defaults to `'View'`. */\n defaultAriaLabel?: string;\n styleAdapter?: HTMLStyleAdapter<TNode, TCollector, TContext>;\n /**\n * Emitted unescaped ahead of {@link HTMLStyleAdapter.getScriptText}. A\n * function body with `root` in scope, under the same rules as\n * {@link EnhancementDefinition.script}.\n */\n scriptText?: string;\n /**\n * Progressive enhancements declared by the packs this render was composed\n * from. The render resolves {@link HTMLRenderOptions.enhancements} against\n * them once, hands every renderer the set as `context.enhancements`, and\n * emits each resolved one's script.\n */\n enhancementDefinitions?: readonly EnhancementDefinition[];\n}\n\n/**\n * Renders a composition to standalone HTML: the wrapper element, the pack's\n * markup, and its CSS either inlined or returned separately.\n *\n * Runs the pack twice when a style adapter is present — once to collect\n * styles, once with the render context those styles produced — so a\n * `renderReact` implementation must be free of side effects.\n */\nexport const renderHTMLWithDispatcher = <\n TNode extends PrimitiveNode,\n TCollector extends PrimitiveStyleCollector = PrimitiveStyleCollector,\n TContext = StyledRenderContext,\n>(\n input: Composition<TNode>,\n {\n dispatcher,\n validate = createCompositionValidator<TNode>(dispatcher.definitions),\n options: rawOptions = {},\n defaultAriaLabel = 'View',\n styleAdapter,\n scriptText = '',\n enhancementDefinitions = [],\n }: HTMLDispatcherRenderOptions<TNode, TCollector, TContext>\n): HTMLRenderResult => {\n const validation = validate(input);\n const composition = compositionToRender(validation);\n // Resolved before the validation mode is read, so an adapter can derive\n // `onValidationError`.\n const options =\n styleAdapter?.resolveOptions?.(composition, rawOptions) ?? rawOptions;\n enforceValidationMode(validation, options.onValidationError);\n const framed = options.framed ?? true;\n const heading = options.heading ?? true;\n const theme = options.theme ?? composition.theme ?? 'auto';\n const cssMode = options.css ?? 'inline';\n const scriptsMode = options.scripts ?? 'embedded';\n const styleState = styleAdapter?.createCollector(options);\n const enhancementScope: HTMLEnhancementScope = {\n walk: createChildNodeWalker(dispatcher.definitions),\n definitions: enhancementDefinitions,\n };\n const applied = resolveEnhancements(\n composition.body,\n enhancementScope.walk,\n enhancementDefinitions,\n options.enhancements ?? []\n );\n const enhancements: ReadonlySet<string> = new Set(\n applied.map(({ id }) => id)\n );\n const anchors =\n options.anchors === true || applied.some(({ anchors }) => anchors);\n const enhanced = (context: TContext): TContext =>\n contextWith(context, 'enhancements', enhancements);\n\n if (styleState) {\n styleAdapter?.collectWrapperStyles?.(styleState, options);\n styleAdapter?.collectViewStyles?.(\n composition,\n dispatcher,\n styleState,\n { fluid: Boolean(options.fluid) },\n options,\n enhancementScope\n );\n const collectionContext = enhanced(\n styleAdapter?.createRenderContext(styleState, options) as TContext\n );\n withAnchors(anchors, () =>\n renderToStaticMarkup(\n createElement(() =>\n renderCompositionContent(composition, dispatcher, collectionContext, {\n heading,\n })\n )\n )\n );\n styleAdapter?.collectAfterRender?.(composition, styleState, options);\n }\n\n const renderContext = enhanced(\n styleState && styleAdapter\n ? styleAdapter.createRenderContext(styleState, options)\n : // No adapter means no class names and no css vars to resolve.\n ({} as TContext)\n );\n const cssText =\n styleState && styleAdapter\n ? styleAdapter.renderStyles(styleState, options)\n : '';\n const adapterScriptText =\n styleAdapter?.getScriptText?.(composition, options, enhancementScope) ?? '';\n const js = [\n ...[scriptText, adapterScriptText].filter(Boolean).map(scopeScript),\n enhancementScript(applied),\n ]\n .filter(Boolean)\n .join('\\n');\n const embeddedScript =\n js && scriptsMode === 'embedded' ? embedScript(js) : '';\n const body = withAnchors(anchors, () =>\n renderToStaticMarkup(\n createElement(() =>\n renderCompositionContent(composition, dispatcher, renderContext, {\n heading,\n })\n )\n )\n );\n const inlineCss = cssMode === 'inline' ? embedCss(cssText) : '';\n const inlineJs = embeddedScript ? embedJs(embeddedScript) : '';\n const raw = renderToStaticMarkup(\n createElement(RenderedHtmlView<TNode>, {\n composition,\n theme,\n fluid: Boolean(options.fluid),\n framed,\n styleText: inlineCss || undefined,\n scriptText: inlineJs || undefined,\n defaultAriaLabel,\n body,\n })\n );\n const html = options.minify === false ? raw : minifyHtml(raw);\n\n // Inline payloads are measured as emitted, escapes included.\n const inlineCssBytes = byteLength(inlineCss);\n const inlineJsBytes = byteLength(inlineJs);\n const separateCssBytes = cssMode === 'inline' ? 0 : byteLength(cssText);\n const separateJsBytes = embeddedScript ? 0 : byteLength(js);\n\n return {\n html,\n css: cssText,\n js,\n body,\n measurement: {\n html: byteLength(html) - inlineCssBytes - inlineJsBytes,\n css: inlineCssBytes + separateCssBytes,\n js: inlineJsBytes + separateJsBytes,\n total: byteLength(html) + separateCssBytes + separateJsBytes,\n },\n validationErrors: validation.errors,\n };\n};\n\ninterface RenderedHtmlViewProps<TNode extends PrimitiveNode> {\n composition: Composition<TNode>;\n theme: RenderTheme;\n fluid: boolean;\n framed: boolean;\n styleText?: string | undefined;\n scriptText?: string | undefined;\n defaultAriaLabel: string;\n body: string;\n}\n\n// Only `</style` ends a `<style>`. `\\/` is a CSS escape for `/`, so a string\n// holding it keeps its value.\nconst embedCss = (css: string): string => css.replace(/<\\/(?=style)/gi, '<\\\\/');\n\ninterface ScriptNode extends JavaScriptNode {\n tag: ScriptNode;\n quasi: ScriptNode;\n quasis: ScriptNode[];\n expressions: ScriptNode[];\n value: { raw: string; cooked: string | null };\n name?: string;\n}\n\n// Tagged templates observe raw spelling and reuse the same frozen object per site.\nconst embedJs = (js: string): string => {\n if (!/<\\/script|<!--/i.test(js)) return js;\n const comments: JavaScriptComment[] = [];\n const tree = parse(js, { ecmaVersion: 'latest', onComment: comments });\n const sites: ScriptNode[] = [];\n const identifiers = new Set<string>();\n const pending: JavaScriptNode[] = [tree];\n while (pending.length) {\n const node = pending.pop()! as ScriptNode;\n if (node.type === 'Identifier' && node.name) identifiers.add(node.name);\n if (\n node.type === 'TaggedTemplateExpression' &&\n node.quasi.quasis.some(({ value: { raw } }) =>\n /<\\/script|<!--/i.test(raw)\n )\n )\n sites.push(node);\n for (const value of Object.values(node)) {\n for (const child of Array.isArray(value) ? value : [value]) {\n if (\n child &&\n typeof child === 'object' &&\n 'type' in child &&\n 'start' in child\n ) {\n pending.push(child as JavaScriptNode);\n }\n }\n }\n }\n sites.sort((a, b) => a.start - b.start);\n let prefix = '__isomerTemplate';\n while ([...identifiers].some((name) => name.startsWith(prefix)))\n prefix += '_';\n const literal = (value: string | null): string =>\n value === null ? 'void 0' : JSON.stringify(value).replace(/</g, '\\\\u003c');\n const rewrite = (start: number, end: number): string => {\n let cursor = start;\n let result = '';\n const edits = [\n ...sites.map((site, index) => ({\n ...site,\n index,\n comment: undefined as string | undefined,\n })),\n ...comments\n .filter(({ start }) => /^(?:<!--|-->)/.test(js.slice(start, start + 4)))\n .map((comment) => ({ ...comment, index: -1, comment: comment.value })),\n ].sort((a, b) => a.start - b.start);\n for (const edit of edits) {\n if (edit.start < cursor || edit.end > end) continue;\n result += js.slice(cursor, edit.start);\n if (edit.comment !== undefined) {\n result += `//${edit.comment}`;\n } else {\n const site = sites[edit.index]!;\n const {\n tag,\n quasi: { quasis, expressions },\n } = site;\n const cooked = quasis\n .map(({ value }) => literal(value.cooked))\n .join(',');\n const raw = quasis.map(({ value }) => literal(value.raw)).join(',');\n const cache = `${prefix}${edit.index}`;\n const template = `${cache} ??= ${prefix}Freeze(${prefix}Define([${cooked}], 'raw', {value:${prefix}Freeze([${raw}])}))`;\n const args = expressions.map((expression) =>\n rewrite(expression.start, expression.end)\n );\n result += `(${rewrite(tag.start, tag.end)})(${template}${args.map((arg) => `,(${arg})`).join('')})`;\n }\n cursor = edit.end;\n }\n return result + js.slice(cursor, end);\n };\n const rewritten = rewrite(0, js.length);\n const scoped = sites.length\n ? `(function(){const ${prefix}Freeze=Object.freeze,${prefix}Define=Object.defineProperty;let ${sites.map((_site, index) => `${prefix}${index}`).join(',')};\\n${rewritten}\\n})();`\n : rewritten;\n return scoped\n .replace(/<\\/(?=script)/gi, '<\\\\/')\n .replace(/<!--/g, (_match, at: number, source: string) =>\n escapedBy(source, at) ? 'x3C!--' : '\\\\x3C!--'\n );\n};\n\nconst escapedBy = (source: string, at: number): boolean => {\n let slashes = 0;\n while (source[at - slashes - 1] === '\\\\') slashes += 1;\n return slashes % 2 === 1;\n};\n\nconst RenderedHtmlView = <TNode extends PrimitiveNode>({\n composition,\n theme,\n fluid,\n framed,\n styleText,\n scriptText,\n defaultAriaLabel,\n body,\n}: RenderedHtmlViewProps<TNode>): ReactNode =>\n wrapCompositionContent(\n createElement(\n Fragment,\n null,\n styleText\n ? createElement('style', {\n key: 'style',\n dangerouslySetInnerHTML: { __html: styleText },\n })\n : null,\n createElement('div', {\n key: 'body',\n dangerouslySetInnerHTML: { __html: body },\n }),\n scriptText\n ? createElement('script', {\n key: 'script',\n [EMBEDDED_SCRIPT_ATTRIBUTE]: '',\n dangerouslySetInnerHTML: { __html: scriptText },\n })\n : null\n ),\n composition,\n { framed, fluid, theme, defaultAriaLabel }\n );\n\n// Whitespace inside `pre`, `script`, `style`, and `textarea` is content, so\n// those elements match whole and pass through. Elsewhere only whitespace\n// spanning a line break is collapsed: a single space between inline elements\n// (`<b>a</b> <i>b</i>`) is authored content.\nconst MINIFY_RE =\n /<(pre|script|style|textarea)[\\s>][\\s\\S]*?(?:<\\/\\1\\s*>|$)|(?<=>)\\s+(?=<)/gi;\n\nconst minifyHtml = (value: string): string =>\n value\n .replace(MINIFY_RE, (match, element: string | undefined) =>\n element || !match.includes('\\n') ? match : ''\n )\n .trim();\n"]}
@@ -39,5 +39,5 @@ export interface LayoutFinding {
39
39
  * compared. Nothing inside a scaled box is checked. A finding is advice, not an error:
40
40
  * an overlap may be intended.
41
41
  */
42
- export declare const checkLayout: (layout: LayoutBox, body: readonly unknown[], walk: ChildNodeWalker, surface: "react" | "svg") => LayoutFinding[];
42
+ export declare const checkLayout: (layout: LayoutBox, body: readonly unknown[], walk: ChildNodeWalker, surface: "react" | "snapshot") => LayoutFinding[];
43
43
  //# sourceMappingURL=layout_check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout_check.d.ts","sourceRoot":"","sources":["../../src/render/layout_check.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAUrE,4CAA4C;AAC5C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,0FAA0F;AAC1F,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,6BAA6B;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;CACzC;AAED,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;CACZ;AAqFD;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,SAAS,EACjB,MAAM,SAAS,OAAO,EAAE,EACxB,MAAM,eAAe,EACrB,SAAS,OAAO,GAAG,KAAK,KACvB,aAAa,EAgFf,CAAC"}
1
+ {"version":3,"file":"layout_check.d.ts","sourceRoot":"","sources":["../../src/render/layout_check.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAUrE,4CAA4C;AAC5C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,0FAA0F;AAC1F,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,6BAA6B;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;CACzC;AAED,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;CACZ;AAqFD;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,SAAS,EACjB,MAAM,SAAS,OAAO,EAAE,EACxB,MAAM,eAAe,EACrB,SAAS,OAAO,GAAG,UAAU,KAC5B,aAAa,EAgFf,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"layout_check.js","sourceRoot":"","sources":["../../src/render/layout_check.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport type { ChildNodeWalker } from '../composition/body_node_base';\n\nimport {\n anchoredNodePaths,\n LAYOUT_ROOM_ATTRIBUTE,\n NODE_ANCHOR_ATTRIBUTE,\n nodeType,\n pairAnchors,\n} from './anchors';\n\n/** A rectangle on the canvas, in pixels. */\nexport interface LayoutRect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\n/** A laid-out element and the elements nested in it, as a layout engine measures them. */\nexport interface LayoutBox extends LayoutRect {\n /** Absent means unscaled. */\n readonly scale?: number;\n /** Text laid out in the box. */\n readonly runs?: readonly LayoutRect[];\n /** Where a {@link NODE_ANCHOR_ATTRIBUTE} is read from. */\n readonly attributes?: Readonly<Record<string, string>>;\n readonly children: readonly LayoutBox[];\n}\n\n/** A node drawn past the room its container gives it, or onto a sibling, by `by` pixels. */\nexport interface LayoutFinding {\n kind: 'overflow' | 'overlap';\n /** In validation's form, e.g. `body[1].items[0]`. */\n path: string;\n type: string;\n /** The sibling an `overlap` lands on. */\n with?: { path: string; type: string };\n by: number;\n}\n\ninterface PlacedNode {\n box: LayoutBox;\n path: string;\n type: string;\n}\n\n// Sub-pixel rounding reads as overflow without it.\nconst tolerance = 1;\n\nconst isScaled = ({ scale = 1 }: LayoutBox): boolean =>\n Math.abs(scale - 1) > 0.001;\n\nconst hasArea = ({ width, height }: LayoutRect): boolean =>\n width > 0 && height > 0;\n\n/** Every anchored box, pre-order, including those inside a scaled box, so a type's count matches its nodes. */\nconst anchoredBoxes = (box: LayoutBox): [string, LayoutBox][] => {\n const value = box.attributes?.[NODE_ANCHOR_ATTRIBUTE];\n return [\n ...(value === undefined ? [] : [[value, box] as [string, LayoutBox]]),\n ...box.children.flatMap(anchoredBoxes),\n ];\n};\n\nconst roomBoxes = (box: LayoutBox): LayoutBox[] => [\n ...(box.attributes?.[LAYOUT_ROOM_ATTRIBUTE] === undefined ? [] : [box]),\n ...box.children.flatMap(roomBoxes),\n];\n\n/**\n * The element boxes a node's own content fills: its box and those under it,\n * down to the nodes nested in it. Text runs are left out because glyphs\n * overhang a tight line height; a scaled box counts as itself alone.\n */\nconst ownBoxes = (\n box: LayoutBox,\n nested: ReadonlySet<LayoutBox>\n): LayoutBox[] => [\n box,\n ...(isScaled(box)\n ? []\n : box.children.flatMap((child) =>\n nested.has(child) ? [] : ownBoxes(child, nested)\n )),\n];\n\n/** What a box paints: its text, or itself when it holds nothing else, like a dot or a rule. */\nconst painted = (box: LayoutBox): LayoutRect[] => {\n if (isScaled(box)) {\n return [box];\n }\n const own =\n box.runs && box.runs.length > 0\n ? box.runs\n : box.children.length === 0\n ? [box]\n : [];\n return [...own.filter(hasArea), ...box.children.flatMap(painted)];\n};\n\nconst pastRoom = (room: LayoutRect, { x, y, width, height }: LayoutRect) =>\n Math.max(\n room.x - x,\n room.y - y,\n x + width - (room.x + room.width),\n y + height - (room.y + room.height)\n );\n\n/** How far `a` and `b` would have to move apart, along one axis, to clear each other. */\nconst overlapOf = (a: LayoutRect, b: LayoutRect): number => {\n const width = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const height = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n if (width <= tolerance || height <= tolerance) {\n return 0;\n }\n return Math.min(\n a.x + a.width - b.x,\n b.x + b.width - a.x,\n a.y + a.height - b.y,\n b.y + b.height - a.y\n );\n};\n\n/**\n * Where the nodes of `body` run past their room or onto each other in\n * `layout`, a measured render on `surface` with node anchors on. Empty when\n * nothing does.\n *\n * A node's room is the box of its nearest anchored or `layoutRoom` ancestor,\n * or `layout` at the top level, and only siblings under one room are\n * compared. Nothing inside a scaled box is checked. A finding is advice, not an error:\n * an overlap may be intended.\n */\nexport const checkLayout = (\n layout: LayoutBox,\n body: readonly unknown[],\n walk: ChildNodeWalker,\n surface: 'react' | 'svg'\n): LayoutFinding[] => {\n const nodes = anchoredNodePaths(body, walk, surface);\n const anchored = anchoredBoxes(layout);\n const boxes = pairAnchors(\n anchored,\n nodes.map(({ node }) => node)\n );\n const placed = new Map<LayoutBox, PlacedNode>();\n boxes.forEach((box, index) => {\n const { node, path } = nodes[index]!;\n const type = nodeType(node);\n if (box !== undefined && type !== undefined) {\n placed.set(box, { box, path, type });\n }\n });\n\n // Every anchored box bounds its ancestors' content, paired or not.\n const nested = new Set(anchored.map(([, box]) => box));\n const bounding = new Set([...nested, ...roomBoxes(layout)]);\n const rooms = new Map<PlacedNode, LayoutBox>();\n const siblings = new Map<LayoutBox | undefined, PlacedNode[]>();\n const visit = (box: LayoutBox, parent: LayoutBox | undefined): void => {\n const node = placed.get(box);\n if (node !== undefined) {\n rooms.set(node, parent ?? layout);\n siblings.set(parent, [...(siblings.get(parent) ?? []), node]);\n }\n if (!isScaled(box)) {\n box.children.forEach((child) =>\n visit(child, bounding.has(box) ? box : parent)\n );\n }\n };\n visit(layout, undefined);\n\n const overflows = [...rooms].flatMap(([node, room]): LayoutFinding[] => {\n const by = Math.max(\n 0,\n ...ownBoxes(node.box, nested)\n .filter(hasArea)\n .map((box) => pastRoom(room, box))\n );\n return by > tolerance\n ? [\n {\n kind: 'overflow',\n path: node.path,\n type: node.type,\n by: Math.round(by),\n },\n ]\n : [];\n });\n\n const overlaps = [...siblings.values()].flatMap((group) => {\n const paints = group.map(({ box }) => painted(box));\n return group.flatMap((first, i) =>\n group.slice(i + 1).flatMap((second, offset): LayoutFinding[] => {\n const by = Math.max(\n 0,\n ...paints[i]!.flatMap((a) =>\n paints[i + 1 + offset]!.map((b) => overlapOf(a, b))\n )\n );\n return by > 0\n ? [\n {\n kind: 'overlap',\n path: first.path,\n type: first.type,\n with: { path: second.path, type: second.type },\n by: Math.round(by),\n },\n ]\n : [];\n })\n );\n });\n\n return [...overflows, ...overlaps];\n};\n"]}
1
+ {"version":3,"file":"layout_check.js","sourceRoot":"","sources":["../../src/render/layout_check.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport type { ChildNodeWalker } from '../composition/body_node_base';\n\nimport {\n anchoredNodePaths,\n LAYOUT_ROOM_ATTRIBUTE,\n NODE_ANCHOR_ATTRIBUTE,\n nodeType,\n pairAnchors,\n} from './anchors';\n\n/** A rectangle on the canvas, in pixels. */\nexport interface LayoutRect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\n/** A laid-out element and the elements nested in it, as a layout engine measures them. */\nexport interface LayoutBox extends LayoutRect {\n /** Absent means unscaled. */\n readonly scale?: number;\n /** Text laid out in the box. */\n readonly runs?: readonly LayoutRect[];\n /** Where a {@link NODE_ANCHOR_ATTRIBUTE} is read from. */\n readonly attributes?: Readonly<Record<string, string>>;\n readonly children: readonly LayoutBox[];\n}\n\n/** A node drawn past the room its container gives it, or onto a sibling, by `by` pixels. */\nexport interface LayoutFinding {\n kind: 'overflow' | 'overlap';\n /** In validation's form, e.g. `body[1].items[0]`. */\n path: string;\n type: string;\n /** The sibling an `overlap` lands on. */\n with?: { path: string; type: string };\n by: number;\n}\n\ninterface PlacedNode {\n box: LayoutBox;\n path: string;\n type: string;\n}\n\n// Sub-pixel rounding reads as overflow without it.\nconst tolerance = 1;\n\nconst isScaled = ({ scale = 1 }: LayoutBox): boolean =>\n Math.abs(scale - 1) > 0.001;\n\nconst hasArea = ({ width, height }: LayoutRect): boolean =>\n width > 0 && height > 0;\n\n/** Every anchored box, pre-order, including those inside a scaled box, so a type's count matches its nodes. */\nconst anchoredBoxes = (box: LayoutBox): [string, LayoutBox][] => {\n const value = box.attributes?.[NODE_ANCHOR_ATTRIBUTE];\n return [\n ...(value === undefined ? [] : [[value, box] as [string, LayoutBox]]),\n ...box.children.flatMap(anchoredBoxes),\n ];\n};\n\nconst roomBoxes = (box: LayoutBox): LayoutBox[] => [\n ...(box.attributes?.[LAYOUT_ROOM_ATTRIBUTE] === undefined ? [] : [box]),\n ...box.children.flatMap(roomBoxes),\n];\n\n/**\n * The element boxes a node's own content fills: its box and those under it,\n * down to the nodes nested in it. Text runs are left out because glyphs\n * overhang a tight line height; a scaled box counts as itself alone.\n */\nconst ownBoxes = (\n box: LayoutBox,\n nested: ReadonlySet<LayoutBox>\n): LayoutBox[] => [\n box,\n ...(isScaled(box)\n ? []\n : box.children.flatMap((child) =>\n nested.has(child) ? [] : ownBoxes(child, nested)\n )),\n];\n\n/** What a box paints: its text, or itself when it holds nothing else, like a dot or a rule. */\nconst painted = (box: LayoutBox): LayoutRect[] => {\n if (isScaled(box)) {\n return [box];\n }\n const own =\n box.runs && box.runs.length > 0\n ? box.runs\n : box.children.length === 0\n ? [box]\n : [];\n return [...own.filter(hasArea), ...box.children.flatMap(painted)];\n};\n\nconst pastRoom = (room: LayoutRect, { x, y, width, height }: LayoutRect) =>\n Math.max(\n room.x - x,\n room.y - y,\n x + width - (room.x + room.width),\n y + height - (room.y + room.height)\n );\n\n/** How far `a` and `b` would have to move apart, along one axis, to clear each other. */\nconst overlapOf = (a: LayoutRect, b: LayoutRect): number => {\n const width = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const height = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n if (width <= tolerance || height <= tolerance) {\n return 0;\n }\n return Math.min(\n a.x + a.width - b.x,\n b.x + b.width - a.x,\n a.y + a.height - b.y,\n b.y + b.height - a.y\n );\n};\n\n/**\n * Where the nodes of `body` run past their room or onto each other in\n * `layout`, a measured render on `surface` with node anchors on. Empty when\n * nothing does.\n *\n * A node's room is the box of its nearest anchored or `layoutRoom` ancestor,\n * or `layout` at the top level, and only siblings under one room are\n * compared. Nothing inside a scaled box is checked. A finding is advice, not an error:\n * an overlap may be intended.\n */\nexport const checkLayout = (\n layout: LayoutBox,\n body: readonly unknown[],\n walk: ChildNodeWalker,\n surface: 'react' | 'snapshot'\n): LayoutFinding[] => {\n const nodes = anchoredNodePaths(body, walk, surface);\n const anchored = anchoredBoxes(layout);\n const boxes = pairAnchors(\n anchored,\n nodes.map(({ node }) => node)\n );\n const placed = new Map<LayoutBox, PlacedNode>();\n boxes.forEach((box, index) => {\n const { node, path } = nodes[index]!;\n const type = nodeType(node);\n if (box !== undefined && type !== undefined) {\n placed.set(box, { box, path, type });\n }\n });\n\n // Every anchored box bounds its ancestors' content, paired or not.\n const nested = new Set(anchored.map(([, box]) => box));\n const bounding = new Set([...nested, ...roomBoxes(layout)]);\n const rooms = new Map<PlacedNode, LayoutBox>();\n const siblings = new Map<LayoutBox | undefined, PlacedNode[]>();\n const visit = (box: LayoutBox, parent: LayoutBox | undefined): void => {\n const node = placed.get(box);\n if (node !== undefined) {\n rooms.set(node, parent ?? layout);\n siblings.set(parent, [...(siblings.get(parent) ?? []), node]);\n }\n if (!isScaled(box)) {\n box.children.forEach((child) =>\n visit(child, bounding.has(box) ? box : parent)\n );\n }\n };\n visit(layout, undefined);\n\n const overflows = [...rooms].flatMap(([node, room]): LayoutFinding[] => {\n const by = Math.max(\n 0,\n ...ownBoxes(node.box, nested)\n .filter(hasArea)\n .map((box) => pastRoom(room, box))\n );\n return by > tolerance\n ? [\n {\n kind: 'overflow',\n path: node.path,\n type: node.type,\n by: Math.round(by),\n },\n ]\n : [];\n });\n\n const overlaps = [...siblings.values()].flatMap((group) => {\n const paints = group.map(({ box }) => painted(box));\n return group.flatMap((first, i) =>\n group.slice(i + 1).flatMap((second, offset): LayoutFinding[] => {\n const by = Math.max(\n 0,\n ...paints[i]!.flatMap((a) =>\n paints[i + 1 + offset]!.map((b) => overlapOf(a, b))\n )\n );\n return by > 0\n ? [\n {\n kind: 'overlap',\n path: first.path,\n type: first.type,\n with: { path: second.path, type: second.type },\n by: Math.round(by),\n },\n ]\n : [];\n })\n );\n });\n\n return [...overflows, ...overlaps];\n};\n"]}
@@ -36,11 +36,9 @@ export declare const md: {
36
36
  table: (columns: readonly (MarkdownInlineInput | readonly MarkdownInlineInput[])[], rows: readonly (readonly (MarkdownInlineInput | readonly MarkdownInlineInput[])[])[]) => MarkdownBlock;
37
37
  /** An unsafe `language` is dropped. */
38
38
  codeBlock: (value: string, language?: string) => MarkdownBlock;
39
- /** Authored Markdown source, after {@link sanitizeMarkdownSource}. */
40
- authored: (source: string) => MarkdownBlock;
39
+ /** Authored Markdown source, after {@link sanitizeAuthoredSource}; whitespace-only source is dropped. */
40
+ authored: (source: string) => MarkdownContent;
41
41
  };
42
- /** A renderer's string output as content, printed as written. */
43
- export declare const markdownFromString: (markdown: string) => MarkdownContent;
44
42
  /** `content` as flat mdast blocks, typed `unknown` so no declaration names mdast. */
45
43
  export declare const markdownBlocks: (content: MarkdownContent) => readonly unknown[];
46
44
  /** `content` as GFM, without a trailing line break. */
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/render/markdown/builder.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EAEpB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACzB,MAAM,+BAA+B,CAAC;AAYvC,oDAAoD;AACpD,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAsG9C;;;;;;;;GAQG;AACH,eAAO,MAAM,EAAE;kBACC,MAAM,KAAG,cAAc;0BACf,mBAAmB,EAAE,KAAG,cAAc;4BAEpC,mBAAmB,EAAE,KAAG,cAAc;kBAEhD,MAAM,KAAG,cAAc;kBAK5B,mBAAmB,GAAG,SAAS,mBAAmB,EAAE,QACrD,MAAM,KACX,cAAc;iBAMJ,MAAM,OAAO,MAAM,KAAG,cAAc;IAMjD,4NAA4N;iBACjN,cAAc;6BACA,mBAAmB,EAAE,KAAG,aAAa;qBAGrD,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,eACf,mBAAmB,EAAE,KACjC,aAAa;IAEhB,mFAAmF;8BACzD,eAAe,EAAE,KAAG,eAAe;IAS7D;;;;OAIG;kBAEM,SAAS,CAAC,mBAAmB,GAAG,eAAe,CAAC,EAAE,uBAC7B;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAChE,aAAa;IAehB,+EAA+E;qBAEpE,SAAS,CAAC,mBAAmB,GAAG,SAAS,mBAAmB,EAAE,CAAC,EAAE,QACpE,SAAS,CAAC,SAAS,CACvB,mBAAmB,GAAG,SAAS,mBAAmB,EAAE,CACrD,EAAE,CAAC,EAAE,KACL,aAAa;IAWhB,uCAAuC;uBACpB,MAAM,aAAa,MAAM,KAAG,aAAa;IAS5D,sEAAsE;uBACnD,MAAM,KAAG,aAAa;CAE1C,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,KAAG,eACJ,CAAC;AA+CnD,qFAAqF;AACrF,eAAO,MAAM,cAAc,GAAI,SAAS,eAAe,KAAG,SAAS,OAAO,EACpD,CAAC;AAEvB,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,GAAI,SAAS,eAAe,KAAG,MAI1D,CAAC"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/render/markdown/builder.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EAEpB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACzB,MAAM,+BAA+B,CAAC;AAYvC,oDAAoD;AACpD,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAyG9C;;;;;;;;GAQG;AACH,eAAO,MAAM,EAAE;kBACC,MAAM,KAAG,cAAc;0BACf,mBAAmB,EAAE,KAAG,cAAc;4BAEpC,mBAAmB,EAAE,KAAG,cAAc;kBAEhD,MAAM,KAAG,cAAc;kBAK5B,mBAAmB,GAAG,SAAS,mBAAmB,EAAE,QACrD,MAAM,KACX,cAAc;iBAMJ,MAAM,OAAO,MAAM,KAAG,cAAc;IAMjD,4NAA4N;iBACjN,cAAc;6BACA,mBAAmB,EAAE,KAAG,aAAa;qBAGrD,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,eACf,mBAAmB,EAAE,KACjC,aAAa;IAEhB,mFAAmF;8BACzD,eAAe,EAAE,KAAG,eAAe;IAS7D;;;;OAIG;kBAEM,SAAS,CAAC,mBAAmB,GAAG,eAAe,CAAC,EAAE,uBAC7B;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAChE,aAAa;IAehB,+EAA+E;qBAEpE,SAAS,CAAC,mBAAmB,GAAG,SAAS,mBAAmB,EAAE,CAAC,EAAE,QACpE,SAAS,CAAC,SAAS,CACvB,mBAAmB,GAAG,SAAS,mBAAmB,EAAE,CACrD,EAAE,CAAC,EAAE,KACL,aAAa;IAWhB,uCAAuC;uBACpB,MAAM,aAAa,MAAM,KAAG,aAAa;IAS5D,yGAAyG;uBACtF,MAAM,KAAG,eAAe;CAO5C,CAAC;AA+CF,qFAAqF;AACrF,eAAO,MAAM,cAAc,GAAI,SAAS,eAAe,KAAG,SAAS,OAAO,EACpD,CAAC;AAEvB,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,GAAI,SAAS,eAAe,KAAG,MAI1D,CAAC"}
@@ -9,7 +9,7 @@ import { defaultHandlers, toMarkdown, } from 'mdast-util-to-markdown';
9
9
  import { oneLine } from '../../composition/one_line.js';
10
10
  import { markdownContent, } from '../../define/markdown_content.js';
11
11
  import { BLOCKED_HREF, sanitizeAssetUrl, sanitizeNavigationHref, } from '../../validate/url.js';
12
- import { sanitizeMarkdownSource } from './format.js';
12
+ import { sanitizeAuthoredSource } from './format.js';
13
13
  // A fence-info string only allows word-ish tokens; anything else would
14
14
  // terminate the fence early or inject markdown.
15
15
  const FENCE_INFO_RE = /^[\w+#.-]+$/;
@@ -55,10 +55,13 @@ const isListStart = (start, count) => start !== undefined &&
55
55
  start >= 0 &&
56
56
  start + Math.max(count - 1, 0) <= MAX_LIST_NUMBER;
57
57
  // Printed as written, for Markdown that is already safe. Trailing whitespace
58
- // would add blank lines between blocks.
59
- const verbatim = (markdown) => block({
58
+ // would add blank lines between blocks. `source` is the authored text when
59
+ // sanitizing degraded it to inert text, whose escapes only Markdown resolves;
60
+ // surfaces that print literal text read it instead.
61
+ const verbatim = (markdown, source) => block({
60
62
  type: VERBATIM_TYPE,
61
63
  value: markdown.trimEnd(),
64
+ ...(source === undefined ? {} : { source }),
62
65
  });
63
66
  // An empty wrapper prints its markers alone: `****` reads as a thematic break.
64
67
  const wrapper = (type, inputs) => {
@@ -144,11 +147,15 @@ export const md = {
144
147
  : null,
145
148
  value,
146
149
  }),
147
- /** Authored Markdown source, after {@link sanitizeMarkdownSource}. */
148
- authored: (source) => verbatim(sanitizeMarkdownSource(source)),
150
+ /** Authored Markdown source, after {@link sanitizeAuthoredSource}; whitespace-only source is dropped. */
151
+ authored: (source) => {
152
+ if (source.trim() === '') {
153
+ return [];
154
+ }
155
+ const { markdown, inert } = sanitizeAuthoredSource(source);
156
+ return verbatim(markdown, inert ? source : undefined);
157
+ },
149
158
  };
150
- /** A renderer's string output as content, printed as written. */
151
- export const markdownFromString = (markdown) => markdown.trim() === '' ? [] : verbatim(markdown);
152
159
  const asText = (node, ...rest) => defaultHandlers.text({ type: 'text', value: node.value ?? node.alt ?? '' }, ...rest);
153
160
  // The URL policy again at serialization, for content built outside `md`.
154
161
  const handlers = {
@@ -1 +1 @@
1
- {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/render/markdown/builder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,eAAe,EAGf,UAAU,GACX,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAGL,eAAe,GAGhB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAElD,uEAAuE;AACvE,gDAAgD;AAChD,MAAM,aAAa,GAAG,aAAa,CAAC;AACpC,oDAAoD;AACpD,MAAM,CAAC,MAAM,aAAa,GAAG,gBAAgB,CAAC;AAE9C,MAAM,MAAM,GAAG,CAAC,IAAqB,EAAkB,EAAE,CACvD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,QAAiB,EAAE,CAAC,CAAC;AAEhE,MAAM,KAAK,GAAG,CAAC,IAAiB,EAAiB,EAAE,CACjD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,OAAgB,EAAE,CAAC,CAAC;AAE/D,MAAM,aAAa,GAAG,CACpB,OAAyC,EACF,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnE,MAAM,YAAY,GAAG,CACnB,KAA2D,EAClB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEnE,MAAM,QAAQ,GAAG,CAAC,KAA0B,EAAmB,EAAE,CAC/D,OAAO,KAAK,KAAK,QAAQ;IACvB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;IACzC,CAAC,CAAE,KAAoC,CAAC;AAE5C,MAAM,SAAS,GAAG,GAAoB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;AAEvE,MAAM,WAAW,GAAG,CAAC,IAAqB,EAAW,EAAE,CACrD,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;AAE5C,mEAAmE;AACnE,MAAM,iBAAiB,GAAG,CACxB,MAAsC,EACnB,EAAE;IACrB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC1B,OAAO,KAAK,GAAG,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAE,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACxD,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,OAAO,GAAG,GAAG,KAAK,IAAI,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAE,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC1D,GAAG,IAAI,CAAC,CAAC;IACX,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF,2EAA2E;AAC3E,yCAAyC;AACzC,MAAM,cAAc,GAAG,CACrB,MAAsC,EACnB,EAAE,CACrB,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACrC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAC5D,CAAC;AAEJ,MAAM,WAAW,GAAG,CAAC,OAAwB,EAAiB,EAAE,CAC9D,aAAa,CAAC,OAAO,CAAC;IACpB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;IAC9B,CAAC,CAAC,CAAC,OAAiC,CAAC,CAAC;AAE1C,MAAM,aAAa,GAAG,CACpB,IAA2C,EACd,EAAE,CAC/B,OAAO,IAAI,KAAK,QAAQ;IACxB,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,CAAC;AAE/D,MAAM,WAAW,GAAG,CAClB,IAA2C,EACrB,EAAE,CACxB,aAAa,CAAC,IAAI,CAAC;IACjB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;IAC9D,CAAC,CAAE,WAAW,CAAC,IAAI,CAA0B,CAAC;AAElD,+EAA+E;AAC/E,MAAM,eAAe,GAAG,WAAW,CAAC;AAEpC,MAAM,WAAW,GAAG,CAClB,KAAyB,EACzB,KAAa,EACI,EAAE,CACnB,KAAK,KAAK,SAAS;IACnB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;IACvB,KAAK,IAAI,CAAC;IACV,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,eAAe,CAAC;AAEpD,6EAA6E;AAC7E,wCAAwC;AACxC,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAiB,EAAE,CACnD,KAAK,CAAC;IACJ,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE;CACA,CAAC,CAAC;AAE/B,+EAA+E;AAC/E,MAAM,OAAO,GAAG,CACd,IAA2B,EAC3B,MAA6B,EACb,EAAE;IAClB,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CACjB,IAA0D,EACvC,EAAE,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAE3E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,IAAI,EAAE,CAAC,KAAa,EAAkB,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChE,MAAM,EAAE,CAAC,GAAG,QAA+B,EAAkB,EAAE,CAC7D,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC7B,QAAQ,EAAE,CAAC,GAAG,QAA+B,EAAkB,EAAE,CAC/D,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC/B,IAAI,EAAE,CAAC,KAAa,EAAkB,EAAE,CACtC,MAAM,CACJ,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAC3E;IACH,IAAI,EAAE,CACJ,KAA2D,EAC3D,IAAY,EACI,EAAE,CAClB,MAAM,CAAC;QACL,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,sBAAsB,CAAC,IAAI,CAAC,IAAI,YAAY;QACjD,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC;KAC5B,CAAC;IACJ,KAAK,EAAE,CAAC,GAAW,EAAE,GAAW,EAAkB,EAAE;QAClD,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,GAAG,KAAK,IAAI;YACjB,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,4NAA4N;IAC5N,KAAK,EAAE,GAAmB,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACtD,SAAS,EAAE,CAAC,GAAG,QAA+B,EAAiB,EAAE,CAC/D,KAAK,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;IACrE,OAAO,EAAE,CACP,KAA4B,EAC5B,GAAG,QAA+B,EACnB,EAAE,CACjB,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;IACvE,mFAAmF;IACnF,UAAU,EAAE,CAAC,GAAG,QAA2B,EAAmB,EAAE;QAC9D,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACtC,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC;YACzB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,KAAK,CAAC;gBACJ,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,OAAiC;aAC5C,CAAC,CAAC;IACT,CAAC;IACD;;;;OAIG;IACH,IAAI,EAAE,CACJ,KAAyD,EACzD,EAAE,OAAO,GAAG,KAAK,EAAE,KAAK,KAA4C,EAAE,EACvD,EAAE;QACjB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAc,EAAE;YAClD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;YAClC,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC;gBACzB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;YACX,IAAI,EAAE,MAAM;YACZ,OAAO;YACP,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,MAAM,EAAE,KAAK;YACb,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IACD,+EAA+E;IAC/E,KAAK,EAAE,CACL,OAA0E,EAC1E,IAEM,EACS,EAAE,CACjB,KAAK,CAAC;QACJ,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAY,EAAE,CAAC,CAAC;YACrD,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC7B,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC;aAC3B,CAAC,CAAC;SACJ,CAAC,CAAC;KACJ,CAAC;IACJ,uCAAuC;IACvC,SAAS,EAAE,CAAC,KAAa,EAAE,QAAiB,EAAiB,EAAE,CAC7D,KAAK,CAAC;QACJ,IAAI,EAAE,MAAM;QACZ,IAAI,EACF,QAAQ,KAAK,SAAS,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;YACpD,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI;QACV,KAAK;KACN,CAAC;IACJ,sEAAsE;IACtE,QAAQ,EAAE,CAAC,MAAc,EAAiB,EAAE,CAC1C,QAAQ,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;CAC3C,CAAC;AAEF,iEAAiE;AACjE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAgB,EAAmB,EAAE,CACtE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAEnD,MAAM,MAAM,GAAW,CACrB,IAA6C,EAC7C,GAAG,IAAI,EACP,EAAE,CACF,eAAe,CAAC,IAAI,CAClB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,EAAE,EACrD,GAAG,IAAI,CACR,CAAC;AAEJ,yEAAyE;AACzE,MAAM,QAAQ,GAA2B;IACvC,IAAI,EAAE,CAAC,IAAU,EAAE,GAAG,IAAI,EAAE,EAAE,CAC5B,eAAe,CAAC,IAAI,CAClB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,YAAY,EAAE,EAClE,GAAG,IAAI,CACR;IACH,UAAU,EAAE,CAAC,IAAgB,EAAE,GAAG,IAAI,EAAE,EAAE,CACxC,eAAe,CAAC,UAAU,CACxB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,YAAY,EAAE,EAClE,GAAG,IAAI,CACR;IACH,KAAK,EAAE,CAAC,IAAW,EAAE,GAAG,IAAI,EAAE,EAAE;QAC9B,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvC,OAAO,GAAG,KAAK,IAAI;YACjB,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC;YACvB,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,EAAE,MAAM;IACZ,CAAC,aAAa,CAAC,EAAE,CAAC,IAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK;CACzD,CAAC;AAEF,MAAM,OAAO,GAAY;IACvB,MAAM,EAAE,GAAG;IACX,qEAAqE;IACrE,wEAAwE;IACxE,iBAAiB;IACjB,QAAQ,EAAE,GAAG;IACb,KAAK,EAAE,GAAG;IACV,cAAc,EAAE,KAAK;IACrB,IAAI,EAAE,GAAG;IACT,MAAM,EAAE,GAAG;IACX,UAAU,EAAE,CAAC,aAAa,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,QAAQ,EAAE,QAA+B;CAC1C,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAwB,EAAsB,EAAE,CAC7E,WAAW,CAAC,OAAO,CAAC,CAAC;AAEvB,uDAAuD;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAwB,EAAU,EAAE,CACpE,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,OAAO,CAC3E,KAAK,EACL,EAAE,CACH,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\n// Builder content is mdast under a brand. Every mdast type stays inside this\n// module, so no emitted declaration names one.\n\nimport type {\n Blockquote,\n Definition,\n Image,\n Link,\n ListItem,\n PhrasingContent,\n RootContent,\n TableRow,\n} from 'mdast';\nimport { gfmToMarkdown } from 'mdast-util-gfm';\nimport {\n defaultHandlers,\n type Handle,\n type Options,\n toMarkdown,\n} from 'mdast-util-to-markdown';\n\nimport { oneLine } from '../../composition/one_line';\nimport {\n type MarkdownBlock,\n type MarkdownContent,\n markdownContent,\n type MarkdownInline,\n type MarkdownInlineInput,\n} from '../../define/markdown_content';\nimport {\n BLOCKED_HREF,\n sanitizeAssetUrl,\n sanitizeNavigationHref,\n} from '../../validate/url';\n\nimport { sanitizeMarkdownSource } from './format';\n\n// A fence-info string only allows word-ish tokens; anything else would\n// terminate the fence early or inject markdown.\nconst FENCE_INFO_RE = /^[\\w+#.-]+$/;\n/** The node type of Markdown printed as written. */\nexport const VERBATIM_TYPE = 'isomerVerbatim';\n\nconst inline = (node: PhrasingContent): MarkdownInline =>\n Object.assign(node, { [markdownContent]: 'inline' as const });\n\nconst block = (node: RootContent): MarkdownBlock =>\n Object.assign(node, { [markdownContent]: 'block' as const });\n\nconst isContentList = (\n content: MarkdownInline | MarkdownContent\n): content is readonly MarkdownContent[] => Array.isArray(content);\n\nconst isInlineList = (\n label: MarkdownInlineInput | readonly MarkdownInlineInput[]\n): label is readonly MarkdownInlineInput[] => Array.isArray(label);\n\nconst phrasing = (input: MarkdownInlineInput): PhrasingContent =>\n typeof input === 'string'\n ? { type: 'text', value: oneLine(input) }\n : (input as unknown as PhrasingContent);\n\nconst emptyText = (): PhrasingContent => ({ type: 'text', value: '' });\n\nconst isEmptyText = (node: PhrasingContent): boolean =>\n node.type === 'text' && node.value === '';\n\n// A break at either edge prints as a literal `\\` or loose markers.\nconst withoutEdgeBreaks = (\n inputs: readonly MarkdownInlineInput[]\n): PhrasingContent[] => {\n const children = inputs.map(phrasing).filter((node) => !isEmptyText(node));\n let start = 0;\n let end = children.length;\n while (start < end && children[start]!.type === 'break') {\n start += 1;\n }\n while (end > start && children[end - 1]!.type === 'break') {\n end -= 1;\n }\n return children.slice(start, end);\n};\n\n// Only a paragraph breaks a line: a heading with one turns setext, and the\n// Slack fallback reads a line at a time.\nconst inlineChildren = (\n inputs: readonly MarkdownInlineInput[]\n): PhrasingContent[] =>\n withoutEdgeBreaks(inputs).map((node) =>\n node.type === 'break' ? { type: 'text', value: ' ' } : node\n );\n\nconst rootContent = (content: MarkdownContent): RootContent[] =>\n isContentList(content)\n ? content.flatMap(rootContent)\n : [content as unknown as RootContent];\n\nconst isInlineInput = (\n item: MarkdownInlineInput | MarkdownContent\n): item is MarkdownInlineInput =>\n typeof item === 'string' ||\n (!isContentList(item) && item[markdownContent] === 'inline');\n\nconst itemContent = (\n item: MarkdownInlineInput | MarkdownContent\n): ListItem['children'] =>\n isInlineInput(item)\n ? [{ type: 'paragraph', children: withoutEdgeBreaks([item]) }]\n : (rootContent(item) as ListItem['children']);\n\n// GFM reads a list number of at most nine digits, so the last item's must fit.\nconst MAX_LIST_NUMBER = 999_999_999;\n\nconst isListStart = (\n start: number | undefined,\n count: number\n): start is number =>\n start !== undefined &&\n Number.isInteger(start) &&\n start >= 0 &&\n start + Math.max(count - 1, 0) <= MAX_LIST_NUMBER;\n\n// Printed as written, for Markdown that is already safe. Trailing whitespace\n// would add blank lines between blocks.\nconst verbatim = (markdown: string): MarkdownBlock =>\n block({\n type: VERBATIM_TYPE,\n value: markdown.trimEnd(),\n } as unknown as RootContent);\n\n// An empty wrapper prints its markers alone: `****` reads as a thematic break.\nconst wrapper = (\n type: 'strong' | 'emphasis',\n inputs: MarkdownInlineInput[]\n): MarkdownInline => {\n const children = inlineChildren(inputs);\n return inline(children.length === 0 ? emptyText() : { type, children });\n};\n\nconst inlineRuns = (\n runs: MarkdownInlineInput | readonly MarkdownInlineInput[]\n): PhrasingContent[] => inlineChildren(isInlineList(runs) ? runs : [runs]);\n\n/**\n * Builds Markdown as content rather than strings, so escaping follows where\n * each value lands. Links and images apply the URL policy in\n * `src/validate/url.ts`: a blocked link keeps its label on\n * {@link BLOCKED_HREF}, and a blocked image degrades to its alt text.\n *\n * @example\n * md.list(rows.map((row) => md.paragraph(md.strong(row.label), ': ', row.value)))\n */\nexport const md = {\n text: (value: string): MarkdownInline => inline(phrasing(value)),\n strong: (...children: MarkdownInlineInput[]): MarkdownInline =>\n wrapper('strong', children),\n emphasis: (...children: MarkdownInlineInput[]): MarkdownInline =>\n wrapper('emphasis', children),\n code: (value: string): MarkdownInline =>\n inline(\n value === '' ? emptyText() : { type: 'inlineCode', value: oneLine(value) }\n ),\n link: (\n label: MarkdownInlineInput | readonly MarkdownInlineInput[],\n href: string\n ): MarkdownInline =>\n inline({\n type: 'link',\n url: sanitizeNavigationHref(href) ?? BLOCKED_HREF,\n children: inlineRuns(label),\n }),\n image: (alt: string, src: string): MarkdownInline => {\n const url = sanitizeAssetUrl(src);\n return url === null\n ? inline(phrasing(alt))\n : inline({ type: 'image', url, alt: oneLine(alt) });\n },\n /** A hard line break, printed as a backslash before the line ending. Inside a heading, strong, emphasis, link label, or table cell it is a space; at the start or end of any of these, or of a paragraph, it is dropped. */\n break: (): MarkdownInline => inline({ type: 'break' }),\n paragraph: (...children: MarkdownInlineInput[]): MarkdownBlock =>\n block({ type: 'paragraph', children: withoutEdgeBreaks(children) }),\n heading: (\n depth: 1 | 2 | 3 | 4 | 5 | 6,\n ...children: MarkdownInlineInput[]\n ): MarkdownBlock =>\n block({ type: 'heading', depth, children: inlineChildren(children) }),\n /** A quote with no blocks, such as one holding only a hidden child, is dropped. */\n blockquote: (...children: MarkdownContent[]): MarkdownContent => {\n const content = rootContent(children);\n return content.length === 0\n ? []\n : block({\n type: 'blockquote',\n children: content as Blockquote['children'],\n });\n },\n /**\n * An item that is inline input becomes one paragraph; one with no blocks,\n * such as a hidden child, is dropped. A `start` that would print a marker\n * GFM does not read as a list number is ignored.\n */\n list: (\n items: readonly (MarkdownInlineInput | MarkdownContent)[],\n { ordered = false, start }: { ordered?: boolean; start?: number } = {}\n ): MarkdownBlock => {\n const children = items.flatMap((item): ListItem[] => {\n const content = itemContent(item);\n return content.length === 0\n ? []\n : [{ type: 'listItem', spread: false, children: content }];\n });\n return block({\n type: 'list',\n ordered,\n ...(isListStart(start, children.length) ? { start } : {}),\n spread: false,\n children,\n });\n },\n /** A cell is one inline run or several. GFM trims a cell's edge whitespace. */\n table: (\n columns: readonly (MarkdownInlineInput | readonly MarkdownInlineInput[])[],\n rows: readonly (readonly (\n MarkdownInlineInput | readonly MarkdownInlineInput[]\n )[])[]\n ): MarkdownBlock =>\n block({\n type: 'table',\n children: [columns, ...rows].map((cells): TableRow => ({\n type: 'tableRow',\n children: cells.map((cell) => ({\n type: 'tableCell',\n children: inlineRuns(cell),\n })),\n })),\n }),\n /** An unsafe `language` is dropped. */\n codeBlock: (value: string, language?: string): MarkdownBlock =>\n block({\n type: 'code',\n lang:\n language !== undefined && FENCE_INFO_RE.test(language)\n ? language\n : null,\n value,\n }),\n /** Authored Markdown source, after {@link sanitizeMarkdownSource}. */\n authored: (source: string): MarkdownBlock =>\n verbatim(sanitizeMarkdownSource(source)),\n};\n\n/** A renderer's string output as content, printed as written. */\nexport const markdownFromString = (markdown: string): MarkdownContent =>\n markdown.trim() === '' ? [] : verbatim(markdown);\n\nconst asText: Handle = (\n node: { value?: string; alt?: string | null },\n ...rest\n) =>\n defaultHandlers.text(\n { type: 'text', value: node.value ?? node.alt ?? '' },\n ...rest\n );\n\n// The URL policy again at serialization, for content built outside `md`.\nconst handlers: Record<string, Handle> = {\n link: (node: Link, ...rest) =>\n defaultHandlers.link(\n { ...node, url: sanitizeNavigationHref(node.url) ?? BLOCKED_HREF },\n ...rest\n ),\n definition: (node: Definition, ...rest) =>\n defaultHandlers.definition(\n { ...node, url: sanitizeNavigationHref(node.url) ?? BLOCKED_HREF },\n ...rest\n ),\n image: (node: Image, ...rest) => {\n const url = sanitizeAssetUrl(node.url);\n return url === null\n ? asText(node, ...rest)\n : defaultHandlers.image({ ...node, url }, ...rest);\n },\n html: asText,\n [VERBATIM_TYPE]: (node: { value: string }) => node.value,\n};\n\nconst OPTIONS: Options = {\n bullet: '-',\n // With `*`, emphasis around strong prints `***x***`, which the Slack\n // fallback cannot split. `_` costs character references around emphasis\n // inside a word.\n emphasis: '_',\n fence: '`',\n listItemIndent: 'one',\n rule: '-',\n strong: '*',\n extensions: [gfmToMarkdown({ tablePipeAlign: false })],\n handlers: handlers as Options['handlers'],\n};\n\n/** `content` as flat mdast blocks, typed `unknown` so no declaration names mdast. */\nexport const markdownBlocks = (content: MarkdownContent): readonly unknown[] =>\n rootContent(content);\n\n/** `content` as GFM, without a trailing line break. */\nexport const serializeMarkdown = (content: MarkdownContent): string =>\n toMarkdown({ type: 'root', children: rootContent(content) }, OPTIONS).replace(\n /\\n$/,\n ''\n );\n"]}
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/render/markdown/builder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\n// Builder content is mdast under a brand. Every mdast type stays inside this\n// module, so no emitted declaration names one.\n\nimport type {\n Blockquote,\n Definition,\n Image,\n Link,\n ListItem,\n PhrasingContent,\n RootContent,\n TableRow,\n} from 'mdast';\nimport { gfmToMarkdown } from 'mdast-util-gfm';\nimport {\n defaultHandlers,\n type Handle,\n type Options,\n toMarkdown,\n} from 'mdast-util-to-markdown';\n\nimport { oneLine } from '../../composition/one_line';\nimport {\n type MarkdownBlock,\n type MarkdownContent,\n markdownContent,\n type MarkdownInline,\n type MarkdownInlineInput,\n} from '../../define/markdown_content';\nimport {\n BLOCKED_HREF,\n sanitizeAssetUrl,\n sanitizeNavigationHref,\n} from '../../validate/url';\n\nimport { sanitizeAuthoredSource } from './format';\n\n// A fence-info string only allows word-ish tokens; anything else would\n// terminate the fence early or inject markdown.\nconst FENCE_INFO_RE = /^[\\w+#.-]+$/;\n/** The node type of Markdown printed as written. */\nexport const VERBATIM_TYPE = 'isomerVerbatim';\n\nconst inline = (node: PhrasingContent): MarkdownInline =>\n Object.assign(node, { [markdownContent]: 'inline' as const });\n\nconst block = (node: RootContent): MarkdownBlock =>\n Object.assign(node, { [markdownContent]: 'block' as const });\n\nconst isContentList = (\n content: MarkdownInline | MarkdownContent\n): content is readonly MarkdownContent[] => Array.isArray(content);\n\nconst isInlineList = (\n label: MarkdownInlineInput | readonly MarkdownInlineInput[]\n): label is readonly MarkdownInlineInput[] => Array.isArray(label);\n\nconst phrasing = (input: MarkdownInlineInput): PhrasingContent =>\n typeof input === 'string'\n ? { type: 'text', value: oneLine(input) }\n : (input as unknown as PhrasingContent);\n\nconst emptyText = (): PhrasingContent => ({ type: 'text', value: '' });\n\nconst isEmptyText = (node: PhrasingContent): boolean =>\n node.type === 'text' && node.value === '';\n\n// A break at either edge prints as a literal `\\` or loose markers.\nconst withoutEdgeBreaks = (\n inputs: readonly MarkdownInlineInput[]\n): PhrasingContent[] => {\n const children = inputs.map(phrasing).filter((node) => !isEmptyText(node));\n let start = 0;\n let end = children.length;\n while (start < end && children[start]!.type === 'break') {\n start += 1;\n }\n while (end > start && children[end - 1]!.type === 'break') {\n end -= 1;\n }\n return children.slice(start, end);\n};\n\n// Only a paragraph breaks a line: a heading with one turns setext, and the\n// Slack fallback reads a line at a time.\nconst inlineChildren = (\n inputs: readonly MarkdownInlineInput[]\n): PhrasingContent[] =>\n withoutEdgeBreaks(inputs).map((node) =>\n node.type === 'break' ? { type: 'text', value: ' ' } : node\n );\n\nconst rootContent = (content: MarkdownContent): RootContent[] =>\n isContentList(content)\n ? content.flatMap(rootContent)\n : [content as unknown as RootContent];\n\nconst isInlineInput = (\n item: MarkdownInlineInput | MarkdownContent\n): item is MarkdownInlineInput =>\n typeof item === 'string' ||\n (!isContentList(item) && item[markdownContent] === 'inline');\n\nconst itemContent = (\n item: MarkdownInlineInput | MarkdownContent\n): ListItem['children'] =>\n isInlineInput(item)\n ? [{ type: 'paragraph', children: withoutEdgeBreaks([item]) }]\n : (rootContent(item) as ListItem['children']);\n\n// GFM reads a list number of at most nine digits, so the last item's must fit.\nconst MAX_LIST_NUMBER = 999_999_999;\n\nconst isListStart = (\n start: number | undefined,\n count: number\n): start is number =>\n start !== undefined &&\n Number.isInteger(start) &&\n start >= 0 &&\n start + Math.max(count - 1, 0) <= MAX_LIST_NUMBER;\n\n// Printed as written, for Markdown that is already safe. Trailing whitespace\n// would add blank lines between blocks. `source` is the authored text when\n// sanitizing degraded it to inert text, whose escapes only Markdown resolves;\n// surfaces that print literal text read it instead.\nconst verbatim = (markdown: string, source?: string): MarkdownBlock =>\n block({\n type: VERBATIM_TYPE,\n value: markdown.trimEnd(),\n ...(source === undefined ? {} : { source }),\n } as unknown as RootContent);\n\n// An empty wrapper prints its markers alone: `****` reads as a thematic break.\nconst wrapper = (\n type: 'strong' | 'emphasis',\n inputs: MarkdownInlineInput[]\n): MarkdownInline => {\n const children = inlineChildren(inputs);\n return inline(children.length === 0 ? emptyText() : { type, children });\n};\n\nconst inlineRuns = (\n runs: MarkdownInlineInput | readonly MarkdownInlineInput[]\n): PhrasingContent[] => inlineChildren(isInlineList(runs) ? runs : [runs]);\n\n/**\n * Builds Markdown as content rather than strings, so escaping follows where\n * each value lands. Links and images apply the URL policy in\n * `src/validate/url.ts`: a blocked link keeps its label on\n * {@link BLOCKED_HREF}, and a blocked image degrades to its alt text.\n *\n * @example\n * md.list(rows.map((row) => md.paragraph(md.strong(row.label), ': ', row.value)))\n */\nexport const md = {\n text: (value: string): MarkdownInline => inline(phrasing(value)),\n strong: (...children: MarkdownInlineInput[]): MarkdownInline =>\n wrapper('strong', children),\n emphasis: (...children: MarkdownInlineInput[]): MarkdownInline =>\n wrapper('emphasis', children),\n code: (value: string): MarkdownInline =>\n inline(\n value === '' ? emptyText() : { type: 'inlineCode', value: oneLine(value) }\n ),\n link: (\n label: MarkdownInlineInput | readonly MarkdownInlineInput[],\n href: string\n ): MarkdownInline =>\n inline({\n type: 'link',\n url: sanitizeNavigationHref(href) ?? BLOCKED_HREF,\n children: inlineRuns(label),\n }),\n image: (alt: string, src: string): MarkdownInline => {\n const url = sanitizeAssetUrl(src);\n return url === null\n ? inline(phrasing(alt))\n : inline({ type: 'image', url, alt: oneLine(alt) });\n },\n /** A hard line break, printed as a backslash before the line ending. Inside a heading, strong, emphasis, link label, or table cell it is a space; at the start or end of any of these, or of a paragraph, it is dropped. */\n break: (): MarkdownInline => inline({ type: 'break' }),\n paragraph: (...children: MarkdownInlineInput[]): MarkdownBlock =>\n block({ type: 'paragraph', children: withoutEdgeBreaks(children) }),\n heading: (\n depth: 1 | 2 | 3 | 4 | 5 | 6,\n ...children: MarkdownInlineInput[]\n ): MarkdownBlock =>\n block({ type: 'heading', depth, children: inlineChildren(children) }),\n /** A quote with no blocks, such as one holding only a hidden child, is dropped. */\n blockquote: (...children: MarkdownContent[]): MarkdownContent => {\n const content = rootContent(children);\n return content.length === 0\n ? []\n : block({\n type: 'blockquote',\n children: content as Blockquote['children'],\n });\n },\n /**\n * An item that is inline input becomes one paragraph; one with no blocks,\n * such as a hidden child, is dropped. A `start` that would print a marker\n * GFM does not read as a list number is ignored.\n */\n list: (\n items: readonly (MarkdownInlineInput | MarkdownContent)[],\n { ordered = false, start }: { ordered?: boolean; start?: number } = {}\n ): MarkdownBlock => {\n const children = items.flatMap((item): ListItem[] => {\n const content = itemContent(item);\n return content.length === 0\n ? []\n : [{ type: 'listItem', spread: false, children: content }];\n });\n return block({\n type: 'list',\n ordered,\n ...(isListStart(start, children.length) ? { start } : {}),\n spread: false,\n children,\n });\n },\n /** A cell is one inline run or several. GFM trims a cell's edge whitespace. */\n table: (\n columns: readonly (MarkdownInlineInput | readonly MarkdownInlineInput[])[],\n rows: readonly (readonly (\n MarkdownInlineInput | readonly MarkdownInlineInput[]\n )[])[]\n ): MarkdownBlock =>\n block({\n type: 'table',\n children: [columns, ...rows].map((cells): TableRow => ({\n type: 'tableRow',\n children: cells.map((cell) => ({\n type: 'tableCell',\n children: inlineRuns(cell),\n })),\n })),\n }),\n /** An unsafe `language` is dropped. */\n codeBlock: (value: string, language?: string): MarkdownBlock =>\n block({\n type: 'code',\n lang:\n language !== undefined && FENCE_INFO_RE.test(language)\n ? language\n : null,\n value,\n }),\n /** Authored Markdown source, after {@link sanitizeAuthoredSource}; whitespace-only source is dropped. */\n authored: (source: string): MarkdownContent => {\n if (source.trim() === '') {\n return [];\n }\n const { markdown, inert } = sanitizeAuthoredSource(source);\n return verbatim(markdown, inert ? source : undefined);\n },\n};\n\nconst asText: Handle = (\n node: { value?: string; alt?: string | null },\n ...rest\n) =>\n defaultHandlers.text(\n { type: 'text', value: node.value ?? node.alt ?? '' },\n ...rest\n );\n\n// The URL policy again at serialization, for content built outside `md`.\nconst handlers: Record<string, Handle> = {\n link: (node: Link, ...rest) =>\n defaultHandlers.link(\n { ...node, url: sanitizeNavigationHref(node.url) ?? BLOCKED_HREF },\n ...rest\n ),\n definition: (node: Definition, ...rest) =>\n defaultHandlers.definition(\n { ...node, url: sanitizeNavigationHref(node.url) ?? BLOCKED_HREF },\n ...rest\n ),\n image: (node: Image, ...rest) => {\n const url = sanitizeAssetUrl(node.url);\n return url === null\n ? asText(node, ...rest)\n : defaultHandlers.image({ ...node, url }, ...rest);\n },\n html: asText,\n [VERBATIM_TYPE]: (node: { value: string }) => node.value,\n};\n\nconst OPTIONS: Options = {\n bullet: '-',\n // With `*`, emphasis around strong prints `***x***`, which the Slack\n // fallback cannot split. `_` costs character references around emphasis\n // inside a word.\n emphasis: '_',\n fence: '`',\n listItemIndent: 'one',\n rule: '-',\n strong: '*',\n extensions: [gfmToMarkdown({ tablePipeAlign: false })],\n handlers: handlers as Options['handlers'],\n};\n\n/** `content` as flat mdast blocks, typed `unknown` so no declaration names mdast. */\nexport const markdownBlocks = (content: MarkdownContent): readonly unknown[] =>\n rootContent(content);\n\n/** `content` as GFM, without a trailing line break. */\nexport const serializeMarkdown = (content: MarkdownContent): string =>\n toMarkdown({ type: 'root', children: rootContent(content) }, OPTIONS).replace(\n /\\n$/,\n ''\n );\n"]}
@@ -1,3 +1,10 @@
1
+ /** `markdown` as flat GFM mdast blocks, typed `unknown` so no declaration names mdast; `null` past the parse budget or the parser's recursion depth. */
2
+ export declare const parseGfmBlocks: (markdown: string) => readonly unknown[] | null;
3
+ /** {@link sanitizeMarkdownSource}'s result, and whether it degraded to inert text. */
4
+ export declare const sanitizeAuthoredSource: (markdown: string) => {
5
+ markdown: string;
6
+ inert: boolean;
7
+ };
1
8
  /** Sanitizes GFM destinations and HTML; excessive syntax or length degrades to inert text. */
2
9
  export declare const sanitizeMarkdownSource: (markdown: string) => string;
3
10
  //# sourceMappingURL=format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/render/markdown/format.ts"],"names":[],"mappings":"AAuKA,8FAA8F;AAC9F,eAAO,MAAM,sBAAsB,GAAI,UAAU,MAAM,KAAG,MAezD,CAAC"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/render/markdown/format.ts"],"names":[],"mappings":"AAkDA,wJAAwJ;AACxJ,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,KAAG,SAAS,OAAO,EAAE,GAAG,IAQtE,CAAC;AA6HF,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,GACjC,UAAU,MAAM,KACf;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAiBpC,CAAC;AAEF,8FAA8F;AAC9F,eAAO,MAAM,sBAAsB,GAAI,UAAU,MAAM,KAAG,MACf,CAAC"}
@@ -23,6 +23,23 @@ const escapeLinkDestination = (href) => href.replace(/[()\s\\]/g, (char) => {
23
23
  });
24
24
  const escapeParsedDestination = (href) => escapeLinkDestination(href.replace(/&/g, '&amp;'));
25
25
  let parseOptions;
26
+ const parse = (source) => fromMarkdown(source, (parseOptions ??= {
27
+ extensions: [gfm()],
28
+ mdastExtensions: [gfmFromMarkdown()],
29
+ }));
30
+ /** `markdown` as flat GFM mdast blocks, typed `unknown` so no declaration names mdast; `null` past the parse budget or the parser's recursion depth. */
31
+ export const parseGfmBlocks = (markdown) => {
32
+ if (exceedsParseBudget(markdown))
33
+ return null;
34
+ try {
35
+ return parse(markdown).children;
36
+ }
37
+ catch (error) {
38
+ if (!(error instanceof RangeError))
39
+ throw error;
40
+ return null;
41
+ }
42
+ };
26
43
  // Each pass can expose a new sink (an escaped HTML block reveals the Markdown
27
44
  // inside it; a blocked link's label may close an outer `](`), so passes repeat
28
45
  // until the source is stable.
@@ -34,11 +51,7 @@ const offsets = (node) => {
34
51
  return start === undefined || end === undefined ? undefined : [start, end];
35
52
  };
36
53
  const sanitizePass = (source) => {
37
- parseOptions ??= {
38
- extensions: [gfm()],
39
- mdastExtensions: [gfmFromMarkdown()],
40
- };
41
- const root = fromMarkdown(source, parseOptions);
54
+ const root = parse(source);
42
55
  const definitions = new Map();
43
56
  const pending = [...root.children].reverse();
44
57
  while (pending.length) {
@@ -140,16 +153,17 @@ const sanitizePass = (source) => {
140
153
  };
141
154
  return emitChildren(0, source.length, root.children);
142
155
  };
143
- /** Sanitizes GFM destinations and HTML; excessive syntax or length degrades to inert text. */
144
- export const sanitizeMarkdownSource = (markdown) => {
145
- if (exceedsParseBudget(markdown))
146
- return inert(markdown);
156
+ /** {@link sanitizeMarkdownSource}'s result, and whether it degraded to inert text. */
157
+ export const sanitizeAuthoredSource = (markdown) => {
158
+ if (exceedsParseBudget(markdown)) {
159
+ return { markdown: inert(markdown), inert: true };
160
+ }
147
161
  let current = markdown;
148
162
  try {
149
163
  for (let pass = 0; pass < MAX_PASSES; pass++) {
150
164
  const next = sanitizePass(current);
151
165
  if (next === current)
152
- return current;
166
+ return { markdown: current, inert: false };
153
167
  current = next;
154
168
  }
155
169
  }
@@ -159,8 +173,10 @@ export const sanitizeMarkdownSource = (markdown) => {
159
173
  if (!(error instanceof RangeError))
160
174
  throw error;
161
175
  }
162
- return inert(current);
176
+ return { markdown: inert(current), inert: true };
163
177
  };
178
+ /** Sanitizes GFM destinations and HTML; excessive syntax or length degrades to inert text. */
179
+ export const sanitizeMarkdownSource = (markdown) => sanitizeAuthoredSource(markdown).markdown;
164
180
  // No link, image, definition, or tag can survive without `[` or `<`.
165
181
  const inert = (markdown) => markdown.replace(/[[\]\\]/g, '\\$&').replace(/</g, '&lt;');
166
182
  // GFM parsing is superlinear for some delimiter runs, even without nesting.
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/render/markdown/format.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\n// Authored Markdown source made safe to print, for `md.authored`.\n\nimport type { Definition, Nodes, Parents } from 'mdast';\nimport { fromMarkdown } from 'mdast-util-from-markdown';\nimport { gfmFromMarkdown } from 'mdast-util-gfm';\nimport { gfm } from 'micromark-extension-gfm';\n\nimport {\n BLOCKED_HREF,\n sanitizeParsedAssetUrl,\n sanitizeParsedNavigationHref,\n} from '../../validate/url';\n\n// Escapes label characters that could close a `[...]` early and smuggle in a\n// hostile destination of their own.\nconst escapeLinkLabel = (label: string): string =>\n label.replace(/[[\\]\\\\]/g, '\\\\$&');\n\n// Percent-encodes destination characters that would terminate the `(...)`\n// early or read as a link title. `encodeURIComponent` leaves `(` and `)`\n// unescaped by spec, so those two are mapped by hand.\nconst escapeLinkDestination = (href: string): string =>\n href.replace(/[()\\s\\\\]/g, (char) => {\n if (char === '(') return '%28';\n if (char === ')') return '%29';\n return encodeURIComponent(char);\n });\n\nconst escapeParsedDestination = (href: string): string =>\n escapeLinkDestination(href.replace(/&/g, '&amp;'));\n\nlet parseOptions: Parameters<typeof fromMarkdown>[1] | undefined;\n\n// Each pass can expose a new sink (an escaped HTML block reveals the Markdown\n// inside it; a blocked link's label may close an outer `](`), so passes repeat\n// until the source is stable.\nconst MAX_PASSES = 16;\n\nconst escapeTitle = (title: string): string =>\n `\"${title.replace(/[\"\\\\]/g, '\\\\$&')}\"`;\n\nconst offsets = (node: Nodes): [number, number] | undefined => {\n const start = node.position?.start.offset;\n const end = node.position?.end.offset;\n return start === undefined || end === undefined ? undefined : [start, end];\n};\n\nconst sanitizePass = (source: string): string => {\n parseOptions ??= {\n extensions: [gfm()],\n mdastExtensions: [gfmFromMarkdown()],\n };\n const root = fromMarkdown(source, parseOptions);\n const definitions = new Map<string, Definition>();\n const pending: Nodes[] = [...root.children].reverse();\n while (pending.length) {\n const node = pending.pop()!;\n if (node.type === 'definition' && !definitions.has(node.identifier)) {\n definitions.set(node.identifier, node);\n }\n if ('children' in node) pending.push(...[...node.children].reverse());\n }\n\n const slice = (node: Nodes): string => {\n const range = offsets(node);\n return range ? source.slice(...range) : '';\n };\n\n const emitChildren = (\n start: number,\n end: number,\n children: readonly Nodes[]\n ): string => {\n let out = '';\n let cursor = start;\n for (const child of children) {\n const range = offsets(child);\n if (!range) continue;\n out += source.slice(cursor, range[0]) + emit(child);\n cursor = range[1];\n }\n return out + source.slice(cursor, end);\n };\n\n const emitLabel = (node: Parents): string => {\n const first = node.children[0];\n const last = node.children[node.children.length - 1];\n const from = first && offsets(first);\n const to = last && offsets(last);\n return from && to ? emitChildren(from[0], to[1], node.children) : '';\n };\n\n const rewrite = (node: Nodes): string | undefined => {\n switch (node.type) {\n case 'html':\n return slice(node).replace(/</g, '&lt;');\n case 'definition': {\n const safe =\n sanitizeParsedNavigationHref(node.url) ??\n sanitizeParsedAssetUrl(node.url);\n if (safe === node.url) return undefined;\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `[${node.label ?? node.identifier}]: ${\n safe === null ? BLOCKED_HREF : escapeParsedDestination(safe)\n }${title}`;\n }\n case 'imageReference': {\n const definition = definitions.get(node.identifier);\n return definition && sanitizeParsedAssetUrl(definition.url) === null\n ? escapeLinkLabel(node.alt ?? '')\n : undefined;\n }\n case 'linkReference': {\n const definition = definitions.get(node.identifier);\n return definition &&\n sanitizeParsedNavigationHref(definition.url) === null &&\n sanitizeParsedAssetUrl(definition.url) !== null\n ? emitLabel(node)\n : undefined;\n }\n case 'image': {\n const safe = sanitizeParsedAssetUrl(node.url);\n if (safe === null) return escapeLinkLabel(node.alt ?? '');\n if (safe === node.url) return undefined;\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `![${escapeLinkLabel(node.alt ?? '')}](${escapeParsedDestination(\n safe\n )}${title})`;\n }\n case 'link': {\n const raw = slice(node);\n const safe = sanitizeParsedNavigationHref(node.url);\n if (raw.startsWith('<')) {\n return safe === null ? raw.slice(1, -1) : undefined;\n }\n // A GFM literal (`www.x.com`) is http(s) or mailto by construction.\n if (!raw.startsWith('[')) return undefined;\n if (safe === null) return emitLabel(node);\n if (safe === node.url) return undefined;\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `[${emitLabel(node)}](${escapeParsedDestination(safe)}${title})`;\n }\n default:\n return undefined;\n }\n };\n\n const emit = (node: Nodes): string => {\n const replaced = rewrite(node);\n if (replaced !== undefined) return replaced;\n const range = offsets(node);\n if (!range) return '';\n return 'children' in node\n ? emitChildren(range[0], range[1], node.children)\n : source.slice(...range);\n };\n\n return emitChildren(0, source.length, root.children);\n};\n\n/** Sanitizes GFM destinations and HTML; excessive syntax or length degrades to inert text. */\nexport const sanitizeMarkdownSource = (markdown: string): string => {\n if (exceedsParseBudget(markdown)) return inert(markdown);\n let current = markdown;\n try {\n for (let pass = 0; pass < MAX_PASSES; pass++) {\n const next = sanitizePass(current);\n if (next === current) return current;\n current = next;\n }\n } catch (error) {\n // The parser recurses per nesting level, so inline nesting deep enough\n // to exhaust the stack lands here.\n if (!(error instanceof RangeError)) throw error;\n }\n return inert(current);\n};\n\n// No link, image, definition, or tag can survive without `[` or `<`.\nconst inert = (markdown: string): string =>\n markdown.replace(/[[\\]\\\\]/g, '\\\\$&').replace(/</g, '&lt;');\n\n// GFM parsing is superlinear for some delimiter runs, even without nesting.\nconst LINE_PREFIX_RE = /^(?:[ \\t>]|[-*+](?=[ \\t])|\\d{1,9}[.)](?=[ \\t]))+/gm;\nconst MAX_LINE_PREFIX = 256;\nconst INLINE_DELIMITER_RE =\n /[[\\]*`~<>|\\\\]|(?<![\\p{L}\\p{N}])_|_(?![\\p{L}\\p{N}])/gu;\nconst MAX_INLINE_DELIMITERS = 2048;\n\nconst MAX_PARSE_LENGTH = 16_384;\n\nconst exceedsParseBudget = (markdown: string): boolean => {\n if (markdown.length > MAX_PARSE_LENGTH) return true;\n for (const [prefix] of markdown.matchAll(LINE_PREFIX_RE)) {\n if (prefix.length > MAX_LINE_PREFIX) return true;\n }\n let delimiters = 0;\n for (const _ of markdown.matchAll(INLINE_DELIMITER_RE)) {\n if (++delimiters > MAX_INLINE_DELIMITERS) return true;\n }\n return false;\n};\n"]}
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/render/markdown/format.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\n// Authored Markdown source made safe to print, for `md.authored`, and the GFM\n// parse it shares with the Slack fallback.\n\nimport type { Definition, Nodes, Parents, Root } from 'mdast';\nimport { fromMarkdown } from 'mdast-util-from-markdown';\nimport { gfmFromMarkdown } from 'mdast-util-gfm';\nimport { gfm } from 'micromark-extension-gfm';\n\nimport {\n BLOCKED_HREF,\n sanitizeParsedAssetUrl,\n sanitizeParsedNavigationHref,\n} from '../../validate/url';\n\n// Escapes label characters that could close a `[...]` early and smuggle in a\n// hostile destination of their own.\nconst escapeLinkLabel = (label: string): string =>\n label.replace(/[[\\]\\\\]/g, '\\\\$&');\n\n// Percent-encodes destination characters that would terminate the `(...)`\n// early or read as a link title. `encodeURIComponent` leaves `(` and `)`\n// unescaped by spec, so those two are mapped by hand.\nconst escapeLinkDestination = (href: string): string =>\n href.replace(/[()\\s\\\\]/g, (char) => {\n if (char === '(') return '%28';\n if (char === ')') return '%29';\n return encodeURIComponent(char);\n });\n\nconst escapeParsedDestination = (href: string): string =>\n escapeLinkDestination(href.replace(/&/g, '&amp;'));\n\nlet parseOptions: Parameters<typeof fromMarkdown>[1] | undefined;\n\nconst parse = (source: string): Root =>\n fromMarkdown(\n source,\n (parseOptions ??= {\n extensions: [gfm()],\n mdastExtensions: [gfmFromMarkdown()],\n })\n );\n\n/** `markdown` as flat GFM mdast blocks, typed `unknown` so no declaration names mdast; `null` past the parse budget or the parser's recursion depth. */\nexport const parseGfmBlocks = (markdown: string): readonly unknown[] | null => {\n if (exceedsParseBudget(markdown)) return null;\n try {\n return parse(markdown).children;\n } catch (error) {\n if (!(error instanceof RangeError)) throw error;\n return null;\n }\n};\n\n// Each pass can expose a new sink (an escaped HTML block reveals the Markdown\n// inside it; a blocked link's label may close an outer `](`), so passes repeat\n// until the source is stable.\nconst MAX_PASSES = 16;\n\nconst escapeTitle = (title: string): string =>\n `\"${title.replace(/[\"\\\\]/g, '\\\\$&')}\"`;\n\nconst offsets = (node: Nodes): [number, number] | undefined => {\n const start = node.position?.start.offset;\n const end = node.position?.end.offset;\n return start === undefined || end === undefined ? undefined : [start, end];\n};\n\nconst sanitizePass = (source: string): string => {\n const root = parse(source);\n const definitions = new Map<string, Definition>();\n const pending: Nodes[] = [...root.children].reverse();\n while (pending.length) {\n const node = pending.pop()!;\n if (node.type === 'definition' && !definitions.has(node.identifier)) {\n definitions.set(node.identifier, node);\n }\n if ('children' in node) pending.push(...[...node.children].reverse());\n }\n\n const slice = (node: Nodes): string => {\n const range = offsets(node);\n return range ? source.slice(...range) : '';\n };\n\n const emitChildren = (\n start: number,\n end: number,\n children: readonly Nodes[]\n ): string => {\n let out = '';\n let cursor = start;\n for (const child of children) {\n const range = offsets(child);\n if (!range) continue;\n out += source.slice(cursor, range[0]) + emit(child);\n cursor = range[1];\n }\n return out + source.slice(cursor, end);\n };\n\n const emitLabel = (node: Parents): string => {\n const first = node.children[0];\n const last = node.children[node.children.length - 1];\n const from = first && offsets(first);\n const to = last && offsets(last);\n return from && to ? emitChildren(from[0], to[1], node.children) : '';\n };\n\n const rewrite = (node: Nodes): string | undefined => {\n switch (node.type) {\n case 'html':\n return slice(node).replace(/</g, '&lt;');\n case 'definition': {\n const safe =\n sanitizeParsedNavigationHref(node.url) ??\n sanitizeParsedAssetUrl(node.url);\n if (safe === node.url) return undefined;\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `[${node.label ?? node.identifier}]: ${\n safe === null ? BLOCKED_HREF : escapeParsedDestination(safe)\n }${title}`;\n }\n case 'imageReference': {\n const definition = definitions.get(node.identifier);\n return definition && sanitizeParsedAssetUrl(definition.url) === null\n ? escapeLinkLabel(node.alt ?? '')\n : undefined;\n }\n case 'linkReference': {\n const definition = definitions.get(node.identifier);\n return definition &&\n sanitizeParsedNavigationHref(definition.url) === null &&\n sanitizeParsedAssetUrl(definition.url) !== null\n ? emitLabel(node)\n : undefined;\n }\n case 'image': {\n const safe = sanitizeParsedAssetUrl(node.url);\n if (safe === null) return escapeLinkLabel(node.alt ?? '');\n if (safe === node.url) return undefined;\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `![${escapeLinkLabel(node.alt ?? '')}](${escapeParsedDestination(\n safe\n )}${title})`;\n }\n case 'link': {\n const raw = slice(node);\n const safe = sanitizeParsedNavigationHref(node.url);\n if (raw.startsWith('<')) {\n return safe === null ? raw.slice(1, -1) : undefined;\n }\n // A GFM literal (`www.x.com`) is http(s) or mailto by construction.\n if (!raw.startsWith('[')) return undefined;\n if (safe === null) return emitLabel(node);\n if (safe === node.url) return undefined;\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `[${emitLabel(node)}](${escapeParsedDestination(safe)}${title})`;\n }\n default:\n return undefined;\n }\n };\n\n const emit = (node: Nodes): string => {\n const replaced = rewrite(node);\n if (replaced !== undefined) return replaced;\n const range = offsets(node);\n if (!range) return '';\n return 'children' in node\n ? emitChildren(range[0], range[1], node.children)\n : source.slice(...range);\n };\n\n return emitChildren(0, source.length, root.children);\n};\n\n/** {@link sanitizeMarkdownSource}'s result, and whether it degraded to inert text. */\nexport const sanitizeAuthoredSource = (\n markdown: string\n): { markdown: string; inert: boolean } => {\n if (exceedsParseBudget(markdown)) {\n return { markdown: inert(markdown), inert: true };\n }\n let current = markdown;\n try {\n for (let pass = 0; pass < MAX_PASSES; pass++) {\n const next = sanitizePass(current);\n if (next === current) return { markdown: current, inert: false };\n current = next;\n }\n } catch (error) {\n // The parser recurses per nesting level, so inline nesting deep enough\n // to exhaust the stack lands here.\n if (!(error instanceof RangeError)) throw error;\n }\n return { markdown: inert(current), inert: true };\n};\n\n/** Sanitizes GFM destinations and HTML; excessive syntax or length degrades to inert text. */\nexport const sanitizeMarkdownSource = (markdown: string): string =>\n sanitizeAuthoredSource(markdown).markdown;\n\n// No link, image, definition, or tag can survive without `[` or `<`.\nconst inert = (markdown: string): string =>\n markdown.replace(/[[\\]\\\\]/g, '\\\\$&').replace(/</g, '&lt;');\n\n// GFM parsing is superlinear for some delimiter runs, even without nesting.\nconst LINE_PREFIX_RE = /^(?:[ \\t>]|[-*+](?=[ \\t])|\\d{1,9}[.)](?=[ \\t]))+/gm;\nconst MAX_LINE_PREFIX = 256;\nconst INLINE_DELIMITER_RE =\n /[[\\]*`~<>|\\\\]|(?<![\\p{L}\\p{N}])_|_(?![\\p{L}\\p{N}])/gu;\nconst MAX_INLINE_DELIMITERS = 2048;\n\nconst MAX_PARSE_LENGTH = 16_384;\n\nconst exceedsParseBudget = (markdown: string): boolean => {\n if (markdown.length > MAX_PARSE_LENGTH) return true;\n for (const [prefix] of markdown.matchAll(LINE_PREFIX_RE)) {\n if (prefix.length > MAX_LINE_PREFIX) return true;\n }\n let delimiters = 0;\n for (const _ of markdown.matchAll(INLINE_DELIMITER_RE)) {\n if (++delimiters > MAX_INLINE_DELIMITERS) return true;\n }\n return false;\n};\n"]}