@react-x11/components 0.1.0 → 0.2.1
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.
- package/README.md +979 -21
- package/dist/ansi/cast.d.ts +48 -0
- package/dist/ansi/cast.d.ts.map +1 -0
- package/dist/ansi/cast.js +135 -0
- package/dist/ansi/cast.js.map +1 -0
- package/dist/ansi/index.d.ts +10 -0
- package/dist/ansi/index.d.ts.map +1 -0
- package/dist/ansi/index.js +27 -0
- package/dist/ansi/index.js.map +1 -0
- package/dist/ansi/palette.d.ts +79 -0
- package/dist/ansi/palette.d.ts.map +1 -0
- package/dist/ansi/palette.js +155 -0
- package/dist/ansi/palette.js.map +1 -0
- package/dist/ansi/parse.d.ts +114 -0
- package/dist/ansi/parse.d.ts.map +1 -0
- package/dist/ansi/parse.js +687 -0
- package/dist/ansi/parse.js.map +1 -0
- package/dist/ansi/sgr.d.ts +87 -0
- package/dist/ansi/sgr.d.ts.map +1 -0
- package/dist/ansi/sgr.js +302 -0
- package/dist/ansi/sgr.js.map +1 -0
- package/dist/ansi/utf8.d.ts +15 -0
- package/dist/ansi/utf8.d.ts.map +1 -0
- package/dist/ansi/utf8.js +82 -0
- package/dist/ansi/utf8.js.map +1 -0
- package/dist/calendar/Calendar.d.ts +136 -0
- package/dist/calendar/Calendar.d.ts.map +1 -0
- package/dist/calendar/Calendar.js +460 -0
- package/dist/calendar/Calendar.js.map +1 -0
- package/dist/calendar/DatePicker.d.ts +52 -0
- package/dist/calendar/DatePicker.d.ts.map +1 -0
- package/dist/calendar/DatePicker.js +257 -0
- package/dist/calendar/DatePicker.js.map +1 -0
- package/dist/calendar/dates.d.ts +90 -0
- package/dist/calendar/dates.d.ts.map +1 -0
- package/dist/calendar/dates.js +236 -0
- package/dist/calendar/dates.js.map +1 -0
- package/dist/calendar/index.d.ts +8 -0
- package/dist/calendar/index.d.ts.map +1 -0
- package/dist/calendar/index.js +15 -0
- package/dist/calendar/index.js.map +1 -0
- package/dist/charts/components.d.ts +141 -0
- package/dist/charts/components.d.ts.map +1 -0
- package/dist/charts/components.js +580 -0
- package/dist/charts/components.js.map +1 -0
- package/dist/charts/data.d.ts +198 -0
- package/dist/charts/data.d.ts.map +1 -0
- package/dist/charts/data.js +616 -0
- package/dist/charts/data.js.map +1 -0
- package/dist/charts/hx.d.ts +21 -0
- package/dist/charts/hx.d.ts.map +1 -0
- package/dist/charts/hx.js +15 -0
- package/dist/charts/hx.js.map +1 -0
- package/dist/charts/index.d.ts +27 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +38 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/node.d.ts +96 -0
- package/dist/charts/node.d.ts.map +1 -0
- package/dist/charts/node.js +720 -0
- package/dist/charts/node.js.map +1 -0
- package/dist/charts/render.d.ts +153 -0
- package/dist/charts/render.d.ts.map +1 -0
- package/dist/charts/render.js +762 -0
- package/dist/charts/render.js.map +1 -0
- package/dist/charts/scale.d.ts +42 -0
- package/dist/charts/scale.d.ts.map +1 -0
- package/dist/charts/scale.js +173 -0
- package/dist/charts/scale.js.map +1 -0
- package/dist/charts/spec.d.ts +91 -0
- package/dist/charts/spec.d.ts.map +1 -0
- package/dist/charts/spec.js +33 -0
- package/dist/charts/spec.js.map +1 -0
- package/dist/charts/timers.d.ts +6 -0
- package/dist/charts/timers.d.ts.map +1 -0
- package/dist/charts/timers.js +14 -0
- package/dist/charts/timers.js.map +1 -0
- package/dist/code/hx.d.ts +24 -0
- package/dist/code/hx.d.ts.map +1 -0
- package/dist/code/hx.js +25 -0
- package/dist/code/hx.js.map +1 -0
- package/dist/code/index.d.ts +45 -0
- package/dist/code/index.d.ts.map +1 -0
- package/dist/code/index.js +93 -0
- package/dist/code/index.js.map +1 -0
- package/dist/code-editor/completion.d.ts +26 -0
- package/dist/code-editor/completion.d.ts.map +1 -0
- package/dist/code-editor/completion.js +129 -0
- package/dist/code-editor/completion.js.map +1 -0
- package/dist/code-editor/doc.d.ts +35 -0
- package/dist/code-editor/doc.d.ts.map +1 -0
- package/dist/code-editor/doc.js +162 -0
- package/dist/code-editor/doc.js.map +1 -0
- package/dist/code-editor/hx.d.ts +13 -0
- package/dist/code-editor/hx.d.ts.map +1 -0
- package/dist/code-editor/hx.js +10 -0
- package/dist/code-editor/hx.js.map +1 -0
- package/dist/code-editor/index.d.ts +88 -0
- package/dist/code-editor/index.d.ts.map +1 -0
- package/dist/code-editor/index.js +401 -0
- package/dist/code-editor/index.js.map +1 -0
- package/dist/code-editor/node.d.ts +343 -0
- package/dist/code-editor/node.d.ts.map +1 -0
- package/dist/code-editor/node.js +1521 -0
- package/dist/code-editor/node.js.map +1 -0
- package/dist/code-language/hljs.d.ts +47 -0
- package/dist/code-language/hljs.d.ts.map +1 -0
- package/dist/code-language/hljs.js +211 -0
- package/dist/code-language/hljs.js.map +1 -0
- package/dist/code-language/index.d.ts +22 -0
- package/dist/code-language/index.d.ts.map +1 -0
- package/dist/code-language/index.js +20 -0
- package/dist/code-language/index.js.map +1 -0
- package/dist/code-language/languages/glsl.d.ts +4 -0
- package/dist/code-language/languages/glsl.d.ts.map +1 -0
- package/dist/code-language/languages/glsl.js +99 -0
- package/dist/code-language/languages/glsl.js.map +1 -0
- package/dist/code-language/languages/javascript.d.ts +10 -0
- package/dist/code-language/languages/javascript.d.ts.map +1 -0
- package/dist/code-language/languages/javascript.js +360 -0
- package/dist/code-language/languages/javascript.js.map +1 -0
- package/dist/code-language/languages/json.d.ts +4 -0
- package/dist/code-language/languages/json.d.ts.map +1 -0
- package/dist/code-language/languages/json.js +68 -0
- package/dist/code-language/languages/json.js.map +1 -0
- package/dist/code-language/languages/shell.d.ts +4 -0
- package/dist/code-language/languages/shell.d.ts.map +1 -0
- package/dist/code-language/languages/shell.js +189 -0
- package/dist/code-language/languages/shell.js.map +1 -0
- package/dist/code-language/languages/sql.d.ts +11 -0
- package/dist/code-language/languages/sql.d.ts.map +1 -0
- package/dist/code-language/languages/sql.js +133 -0
- package/dist/code-language/languages/sql.js.map +1 -0
- package/dist/code-language/lezer.d.ts +24 -0
- package/dist/code-language/lezer.d.ts.map +1 -0
- package/dist/code-language/lezer.js +148 -0
- package/dist/code-language/lezer.js.map +1 -0
- package/dist/code-language/registry.d.ts +19 -0
- package/dist/code-language/registry.d.ts.map +1 -0
- package/dist/code-language/registry.js +56 -0
- package/dist/code-language/registry.js.map +1 -0
- package/dist/code-language/runs.d.ts +35 -0
- package/dist/code-language/runs.d.ts.map +1 -0
- package/dist/code-language/runs.js +88 -0
- package/dist/code-language/runs.js.map +1 -0
- package/dist/code-language/stream.d.ts +70 -0
- package/dist/code-language/stream.d.ts.map +1 -0
- package/dist/code-language/stream.js +243 -0
- package/dist/code-language/stream.js.map +1 -0
- package/dist/code-language/textmate.d.ts +27 -0
- package/dist/code-language/textmate.d.ts.map +1 -0
- package/dist/code-language/textmate.js +86 -0
- package/dist/code-language/textmate.js.map +1 -0
- package/dist/code-language/theme.d.ts +26 -0
- package/dist/code-language/theme.d.ts.map +1 -0
- package/dist/code-language/theme.js +108 -0
- package/dist/code-language/theme.js.map +1 -0
- package/dist/code-language/timers.d.ts +7 -0
- package/dist/code-language/timers.d.ts.map +1 -0
- package/dist/code-language/timers.js +22 -0
- package/dist/code-language/timers.js.map +1 -0
- package/dist/code-language/types.d.ts +173 -0
- package/dist/code-language/types.d.ts.map +1 -0
- package/dist/code-language/types.js +41 -0
- package/dist/code-language/types.js.map +1 -0
- package/dist/codeblock/index.d.ts +69 -0
- package/dist/codeblock/index.d.ts.map +1 -0
- package/dist/codeblock/index.js +85 -0
- package/dist/codeblock/index.js.map +1 -0
- package/dist/color-picker/ColorField.d.ts +39 -0
- package/dist/color-picker/ColorField.d.ts.map +1 -0
- package/dist/color-picker/ColorField.js +239 -0
- package/dist/color-picker/ColorField.js.map +1 -0
- package/dist/color-picker/ColorPicker.d.ts +109 -0
- package/dist/color-picker/ColorPicker.d.ts.map +1 -0
- package/dist/color-picker/ColorPicker.js +757 -0
- package/dist/color-picker/ColorPicker.js.map +1 -0
- package/dist/color-picker/color.d.ts +105 -0
- package/dist/color-picker/color.d.ts.map +1 -0
- package/dist/color-picker/color.js +313 -0
- package/dist/color-picker/color.js.map +1 -0
- package/dist/color-picker/index.d.ts +8 -0
- package/dist/color-picker/index.d.ts.map +1 -0
- package/dist/color-picker/index.js +19 -0
- package/dist/color-picker/index.js.map +1 -0
- package/dist/desktop-calendar/eds.d.ts +102 -0
- package/dist/desktop-calendar/eds.d.ts.map +1 -0
- package/dist/desktop-calendar/eds.js +356 -0
- package/dist/desktop-calendar/eds.js.map +1 -0
- package/dist/desktop-calendar/ical.d.ts +63 -0
- package/dist/desktop-calendar/ical.d.ts.map +1 -0
- package/dist/desktop-calendar/ical.js +57 -0
- package/dist/desktop-calendar/ical.js.map +1 -0
- package/dist/desktop-calendar/index.d.ts +72 -0
- package/dist/desktop-calendar/index.d.ts.map +1 -0
- package/dist/desktop-calendar/index.js +213 -0
- package/dist/desktop-calendar/index.js.map +1 -0
- package/dist/embed/client.d.ts +121 -0
- package/dist/embed/client.d.ts.map +1 -0
- package/dist/embed/client.js +203 -0
- package/dist/embed/client.js.map +1 -0
- package/dist/embed/host.d.ts +96 -0
- package/dist/embed/host.d.ts.map +1 -0
- package/dist/embed/host.js +266 -0
- package/dist/embed/host.js.map +1 -0
- package/dist/embed/index.d.ts +5 -0
- package/dist/embed/index.d.ts.map +1 -0
- package/dist/embed/index.js +13 -0
- package/dist/embed/index.js.map +1 -0
- package/dist/embed/timers.d.ts +6 -0
- package/dist/embed/timers.d.ts.map +1 -0
- package/dist/embed/timers.js +16 -0
- package/dist/embed/timers.js.map +1 -0
- package/dist/flow/draw.d.ts +45 -0
- package/dist/flow/draw.d.ts.map +1 -0
- package/dist/flow/draw.js +295 -0
- package/dist/flow/draw.js.map +1 -0
- package/dist/flow/index.d.ts +64 -0
- package/dist/flow/index.d.ts.map +1 -0
- package/dist/flow/index.js +306 -0
- package/dist/flow/index.js.map +1 -0
- package/dist/flow/model.d.ts +158 -0
- package/dist/flow/model.d.ts.map +1 -0
- package/dist/flow/model.js +566 -0
- package/dist/flow/model.js.map +1 -0
- package/dist/flow/node.d.ts +429 -0
- package/dist/flow/node.d.ts.map +1 -0
- package/dist/flow/node.js +3025 -0
- package/dist/flow/node.js.map +1 -0
- package/dist/flow/paths.d.ts +43 -0
- package/dist/flow/paths.d.ts.map +1 -0
- package/dist/flow/paths.js +327 -0
- package/dist/flow/paths.js.map +1 -0
- package/dist/flow/types.d.ts +561 -0
- package/dist/flow/types.d.ts.map +1 -0
- package/dist/flow/types.js +2 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/formula/hx.d.ts +24 -0
- package/dist/formula/hx.d.ts.map +1 -0
- package/dist/formula/hx.js +25 -0
- package/dist/formula/hx.js.map +1 -0
- package/dist/formula/index.d.ts +74 -0
- package/dist/formula/index.d.ts.map +1 -0
- package/dist/formula/index.js +155 -0
- package/dist/formula/index.js.map +1 -0
- package/dist/formula/katex.d.ts +78 -0
- package/dist/formula/katex.d.ts.map +1 -0
- package/dist/formula/katex.js +130 -0
- package/dist/formula/katex.js.map +1 -0
- package/dist/formula/layout.d.ts +103 -0
- package/dist/formula/layout.d.ts.map +1 -0
- package/dist/formula/layout.js +716 -0
- package/dist/formula/layout.js.map +1 -0
- package/dist/formula/node.d.ts +50 -0
- package/dist/formula/node.d.ts.map +1 -0
- package/dist/formula/node.js +351 -0
- package/dist/formula/node.js.map +1 -0
- package/dist/html/controls.d.ts +48 -0
- package/dist/html/controls.d.ts.map +1 -0
- package/dist/html/controls.js +195 -0
- package/dist/html/controls.js.map +1 -0
- package/dist/html/css/cascade.d.ts +51 -0
- package/dist/html/css/cascade.d.ts.map +1 -0
- package/dist/html/css/cascade.js +552 -0
- package/dist/html/css/cascade.js.map +1 -0
- package/dist/html/css/parse.d.ts +74 -0
- package/dist/html/css/parse.d.ts.map +1 -0
- package/dist/html/css/parse.js +464 -0
- package/dist/html/css/parse.js.map +1 -0
- package/dist/html/css/style.d.ts +142 -0
- package/dist/html/css/style.d.ts.map +1 -0
- package/dist/html/css/style.js +1145 -0
- package/dist/html/css/style.js.map +1 -0
- package/dist/html/css/ua.d.ts +5 -0
- package/dist/html/css/ua.d.ts.map +1 -0
- package/dist/html/css/ua.js +171 -0
- package/dist/html/css/ua.js.map +1 -0
- package/dist/html/css/values.d.ts +78 -0
- package/dist/html/css/values.d.ts.map +1 -0
- package/dist/html/css/values.js +330 -0
- package/dist/html/css/values.js.map +1 -0
- package/dist/html/dom.d.ts +112 -0
- package/dist/html/dom.d.ts.map +1 -0
- package/dist/html/dom.js +374 -0
- package/dist/html/dom.js.map +1 -0
- package/dist/html/hx.d.ts +24 -0
- package/dist/html/hx.d.ts.map +1 -0
- package/dist/html/hx.js +29 -0
- package/dist/html/hx.js.map +1 -0
- package/dist/html/index.d.ts +137 -0
- package/dist/html/index.d.ts.map +1 -0
- package/dist/html/index.js +339 -0
- package/dist/html/index.js.map +1 -0
- package/dist/html/layout/block.d.ts +58 -0
- package/dist/html/layout/block.d.ts.map +1 -0
- package/dist/html/layout/block.js +724 -0
- package/dist/html/layout/block.js.map +1 -0
- package/dist/html/layout/boxes.d.ts +261 -0
- package/dist/html/layout/boxes.d.ts.map +1 -0
- package/dist/html/layout/boxes.js +725 -0
- package/dist/html/layout/boxes.js.map +1 -0
- package/dist/html/layout/flex.d.ts +16 -0
- package/dist/html/layout/flex.d.ts.map +1 -0
- package/dist/html/layout/flex.js +242 -0
- package/dist/html/layout/flex.js.map +1 -0
- package/dist/html/layout/floats.d.ts +50 -0
- package/dist/html/layout/floats.d.ts.map +1 -0
- package/dist/html/layout/floats.js +110 -0
- package/dist/html/layout/floats.js.map +1 -0
- package/dist/html/layout/inline.d.ts +44 -0
- package/dist/html/layout/inline.d.ts.map +1 -0
- package/dist/html/layout/inline.js +700 -0
- package/dist/html/layout/inline.js.map +1 -0
- package/dist/html/layout/table.d.ts +5 -0
- package/dist/html/layout/table.d.ts.map +1 -0
- package/dist/html/layout/table.js +340 -0
- package/dist/html/layout/table.js.map +1 -0
- package/dist/html/node.d.ts +149 -0
- package/dist/html/node.d.ts.map +1 -0
- package/dist/html/node.js +861 -0
- package/dist/html/node.js.map +1 -0
- package/dist/html/paint.d.ts +48 -0
- package/dist/html/paint.d.ts.map +1 -0
- package/dist/html/paint.js +495 -0
- package/dist/html/paint.js.map +1 -0
- package/dist/html/resources.d.ts +48 -0
- package/dist/html/resources.d.ts.map +1 -0
- package/dist/html/resources.js +156 -0
- package/dist/html/resources.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/heights.d.ts +88 -0
- package/dist/internal/heights.d.ts.map +1 -0
- package/dist/internal/heights.js +203 -0
- package/dist/internal/heights.js.map +1 -0
- package/dist/internal/hx.d.ts +24 -0
- package/dist/internal/hx.d.ts.map +1 -0
- package/dist/internal/hx.js +27 -0
- package/dist/internal/hx.js.map +1 -0
- package/dist/internal/scroll.d.ts +62 -0
- package/dist/internal/scroll.d.ts.map +1 -0
- package/dist/internal/scroll.js +224 -0
- package/dist/internal/scroll.js.map +1 -0
- package/dist/internal/text.d.ts +6 -0
- package/dist/internal/text.d.ts.map +1 -0
- package/dist/internal/text.js +44 -0
- package/dist/internal/text.js.map +1 -0
- package/dist/internal/timers.d.ts +8 -0
- package/dist/internal/timers.d.ts.map +1 -0
- package/dist/internal/timers.js +22 -0
- package/dist/internal/timers.js.map +1 -0
- package/dist/internal/widget.d.ts +40 -0
- package/dist/internal/widget.d.ts.map +1 -0
- package/dist/internal/widget.js +44 -0
- package/dist/internal/widget.js.map +1 -0
- package/dist/markdown/ast.d.ts +126 -0
- package/dist/markdown/ast.d.ts.map +1 -0
- package/dist/markdown/ast.js +8 -0
- package/dist/markdown/ast.js.map +1 -0
- package/dist/markdown/hx.d.ts +24 -0
- package/dist/markdown/hx.d.ts.map +1 -0
- package/dist/markdown/hx.js +25 -0
- package/dist/markdown/hx.js.map +1 -0
- package/dist/markdown/index.d.ts +90 -0
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +413 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/parse.d.ts +8 -0
- package/dist/markdown/parse.d.ts.map +1 -0
- package/dist/markdown/parse.js +911 -0
- package/dist/markdown/parse.js.map +1 -0
- package/dist/markdown/spans.d.ts +20 -0
- package/dist/markdown/spans.d.ts.map +1 -0
- package/dist/markdown/spans.js +96 -0
- package/dist/markdown/spans.js.map +1 -0
- package/dist/media-player/backends.d.ts +64 -0
- package/dist/media-player/backends.d.ts.map +1 -0
- package/dist/media-player/backends.js +110 -0
- package/dist/media-player/backends.js.map +1 -0
- package/dist/media-player/control.d.ts +40 -0
- package/dist/media-player/control.d.ts.map +1 -0
- package/dist/media-player/control.js +44 -0
- package/dist/media-player/control.js.map +1 -0
- package/dist/media-player/hx.d.ts +24 -0
- package/dist/media-player/hx.d.ts.map +1 -0
- package/dist/media-player/hx.js +25 -0
- package/dist/media-player/hx.js.map +1 -0
- package/dist/media-player/index.d.ts +107 -0
- package/dist/media-player/index.d.ts.map +1 -0
- package/dist/media-player/index.js +219 -0
- package/dist/media-player/index.js.map +1 -0
- package/dist/media-player/mpv.d.ts +4 -0
- package/dist/media-player/mpv.d.ts.map +1 -0
- package/dist/media-player/mpv.js +120 -0
- package/dist/media-player/mpv.js.map +1 -0
- package/dist/media-player/vlc.d.ts +8 -0
- package/dist/media-player/vlc.d.ts.map +1 -0
- package/dist/media-player/vlc.js +83 -0
- package/dist/media-player/vlc.js.map +1 -0
- package/dist/richtext/index.d.ts +19 -0
- package/dist/richtext/index.d.ts.map +1 -0
- package/dist/richtext/index.js +4 -0
- package/dist/richtext/index.js.map +1 -0
- package/dist/richtext/links.d.ts +12 -0
- package/dist/richtext/links.d.ts.map +1 -0
- package/dist/richtext/links.js +64 -0
- package/dist/richtext/links.js.map +1 -0
- package/dist/richtext/menu.d.ts +11 -0
- package/dist/richtext/menu.d.ts.map +1 -0
- package/dist/richtext/menu.js +43 -0
- package/dist/richtext/menu.js.map +1 -0
- package/dist/richtext/node.d.ts +151 -0
- package/dist/richtext/node.d.ts.map +1 -0
- package/dist/richtext/node.js +255 -0
- package/dist/richtext/node.js.map +1 -0
- package/dist/richtext/runs.d.ts +92 -0
- package/dist/richtext/runs.d.ts.map +1 -0
- package/dist/richtext/runs.js +158 -0
- package/dist/richtext/runs.js.map +1 -0
- package/dist/table/hx.d.ts +24 -0
- package/dist/table/hx.d.ts.map +1 -0
- package/dist/table/hx.js +25 -0
- package/dist/table/hx.js.map +1 -0
- package/dist/table/index.d.ts +169 -0
- package/dist/table/index.d.ts.map +1 -0
- package/dist/table/index.js +890 -0
- package/dist/table/index.js.map +1 -0
- package/dist/table/rows.d.ts +136 -0
- package/dist/table/rows.d.ts.map +1 -0
- package/dist/table/rows.js +146 -0
- package/dist/table/rows.js.map +1 -0
- package/dist/terminal/backends.d.ts +105 -0
- package/dist/terminal/backends.d.ts.map +1 -0
- package/dist/terminal/backends.js +185 -0
- package/dist/terminal/backends.js.map +1 -0
- package/dist/terminal/hx.d.ts +24 -0
- package/dist/terminal/hx.d.ts.map +1 -0
- package/dist/terminal/hx.js +25 -0
- package/dist/terminal/hx.js.map +1 -0
- package/dist/terminal/index.d.ts +160 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +344 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/title.d.ts +24 -0
- package/dist/terminal/title.d.ts.map +1 -0
- package/dist/terminal/title.js +129 -0
- package/dist/terminal/title.js.map +1 -0
- package/dist/terminal/vt/colors.d.ts +63 -0
- package/dist/terminal/vt/colors.d.ts.map +1 -0
- package/dist/terminal/vt/colors.js +203 -0
- package/dist/terminal/vt/colors.js.map +1 -0
- package/dist/terminal/vt/diff.d.ts +117 -0
- package/dist/terminal/vt/diff.d.ts.map +1 -0
- package/dist/terminal/vt/diff.js +358 -0
- package/dist/terminal/vt/diff.js.map +1 -0
- package/dist/terminal/vt/fonts.d.ts +92 -0
- package/dist/terminal/vt/fonts.d.ts.map +1 -0
- package/dist/terminal/vt/fonts.js +178 -0
- package/dist/terminal/vt/fonts.js.map +1 -0
- package/dist/terminal/vt/index.d.ts +78 -0
- package/dist/terminal/vt/index.d.ts.map +1 -0
- package/dist/terminal/vt/index.js +312 -0
- package/dist/terminal/vt/index.js.map +1 -0
- package/dist/terminal/vt/keys.d.ts +74 -0
- package/dist/terminal/vt/keys.d.ts.map +1 -0
- package/dist/terminal/vt/keys.js +309 -0
- package/dist/terminal/vt/keys.js.map +1 -0
- package/dist/terminal/vt/mouse.d.ts +44 -0
- package/dist/terminal/vt/mouse.d.ts.map +1 -0
- package/dist/terminal/vt/mouse.js +106 -0
- package/dist/terminal/vt/mouse.js.map +1 -0
- package/dist/terminal/vt/node.d.ts +246 -0
- package/dist/terminal/vt/node.d.ts.map +1 -0
- package/dist/terminal/vt/node.js +1068 -0
- package/dist/terminal/vt/node.js.map +1 -0
- package/dist/terminal/vt/pty.d.ts +81 -0
- package/dist/terminal/vt/pty.d.ts.map +1 -0
- package/dist/terminal/vt/pty.js +201 -0
- package/dist/terminal/vt/pty.js.map +1 -0
- package/dist/terminal/vt/renderer.d.ts +179 -0
- package/dist/terminal/vt/renderer.d.ts.map +1 -0
- package/dist/terminal/vt/renderer.js +357 -0
- package/dist/terminal/vt/renderer.js.map +1 -0
- package/dist/terminal/vt/timers.d.ts +6 -0
- package/dist/terminal/vt/timers.d.ts.map +1 -0
- package/dist/terminal/vt/timers.js +16 -0
- package/dist/terminal/vt/timers.js.map +1 -0
- package/dist/terminal/vt/xterm.d.ts +142 -0
- package/dist/terminal/vt/xterm.d.ts.map +1 -0
- package/dist/terminal/vt/xterm.js +32 -0
- package/dist/terminal/vt/xterm.js.map +1 -0
- package/dist/terminal-output/hx.d.ts +24 -0
- package/dist/terminal-output/hx.d.ts.map +1 -0
- package/dist/terminal-output/hx.js +25 -0
- package/dist/terminal-output/hx.js.map +1 -0
- package/dist/terminal-output/index.d.ts +92 -0
- package/dist/terminal-output/index.d.ts.map +1 -0
- package/dist/terminal-output/index.js +179 -0
- package/dist/terminal-output/index.js.map +1 -0
- package/dist/terminal-output/runs.d.ts +27 -0
- package/dist/terminal-output/runs.d.ts.map +1 -0
- package/dist/terminal-output/runs.js +66 -0
- package/dist/terminal-output/runs.js.map +1 -0
- package/dist/three/canvas.d.ts +46 -0
- package/dist/three/canvas.d.ts.map +1 -0
- package/dist/three/canvas.js +305 -0
- package/dist/three/canvas.js.map +1 -0
- package/dist/three/events.d.ts +64 -0
- package/dist/three/events.d.ts.map +1 -0
- package/dist/three/events.js +146 -0
- package/dist/three/events.js.map +1 -0
- package/dist/three/geometries.d.ts +89 -0
- package/dist/three/geometries.d.ts.map +1 -0
- package/dist/three/geometries.js +345 -0
- package/dist/three/geometries.js.map +1 -0
- package/dist/three/globals.d.ts +7 -0
- package/dist/three/globals.d.ts.map +1 -0
- package/dist/three/globals.js +20 -0
- package/dist/three/globals.js.map +1 -0
- package/dist/three/hx.d.ts +9 -0
- package/dist/three/hx.d.ts.map +1 -0
- package/dist/three/hx.js +10 -0
- package/dist/three/hx.js.map +1 -0
- package/dist/three/index.d.ts +22 -0
- package/dist/three/index.d.ts.map +1 -0
- package/dist/three/index.js +24 -0
- package/dist/three/index.js.map +1 -0
- package/dist/three/jsx-dev-runtime.d.ts +19 -0
- package/dist/three/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/three/jsx-dev-runtime.js +2 -0
- package/dist/three/jsx-dev-runtime.js.map +1 -0
- package/dist/three/jsx-runtime.d.ts +19 -0
- package/dist/three/jsx-runtime.d.ts.map +1 -0
- package/dist/three/jsx-runtime.js +2 -0
- package/dist/three/jsx-runtime.js.map +1 -0
- package/dist/three/jsx.d.ts +198 -0
- package/dist/three/jsx.d.ts.map +1 -0
- package/dist/three/jsx.js +2 -0
- package/dist/three/jsx.js.map +1 -0
- package/dist/three/materials.d.ts +125 -0
- package/dist/three/materials.d.ts.map +1 -0
- package/dist/three/materials.js +229 -0
- package/dist/three/materials.js.map +1 -0
- package/dist/three/math.d.ts +146 -0
- package/dist/three/math.d.ts.map +1 -0
- package/dist/three/math.js +464 -0
- package/dist/three/math.js.map +1 -0
- package/dist/three/objects.d.ts +185 -0
- package/dist/three/objects.d.ts.map +1 -0
- package/dist/three/objects.js +309 -0
- package/dist/three/objects.js.map +1 -0
- package/dist/three/passes.d.ts +54 -0
- package/dist/three/passes.d.ts.map +1 -0
- package/dist/three/passes.js +78 -0
- package/dist/three/passes.js.map +1 -0
- package/dist/three/postprocess.d.ts +85 -0
- package/dist/three/postprocess.d.ts.map +1 -0
- package/dist/three/postprocess.js +503 -0
- package/dist/three/postprocess.js.map +1 -0
- package/dist/three/raycast.d.ts +24 -0
- package/dist/three/raycast.d.ts.map +1 -0
- package/dist/three/raycast.js +138 -0
- package/dist/three/raycast.js.map +1 -0
- package/dist/three/reconciler.d.ts +48 -0
- package/dist/three/reconciler.d.ts.map +1 -0
- package/dist/three/reconciler.js +416 -0
- package/dist/three/reconciler.js.map +1 -0
- package/dist/three/renderer-direct.d.ts +102 -0
- package/dist/three/renderer-direct.d.ts.map +1 -0
- package/dist/three/renderer-direct.js +782 -0
- package/dist/three/renderer-direct.js.map +1 -0
- package/dist/three/renderer-indirect.d.ts +68 -0
- package/dist/three/renderer-indirect.d.ts.map +1 -0
- package/dist/three/renderer-indirect.js +438 -0
- package/dist/three/renderer-indirect.js.map +1 -0
- package/dist/three/store.d.ts +81 -0
- package/dist/three/store.d.ts.map +1 -0
- package/dist/three/store.js +110 -0
- package/dist/three/store.js.map +1 -0
- package/dist/timeline/hx.d.ts +18 -0
- package/dist/timeline/hx.d.ts.map +1 -0
- package/dist/timeline/hx.js +10 -0
- package/dist/timeline/hx.js.map +1 -0
- package/dist/timeline/index.d.ts +152 -0
- package/dist/timeline/index.d.ts.map +1 -0
- package/dist/timeline/index.js +383 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/tray-host/hx.d.ts +24 -0
- package/dist/tray-host/hx.d.ts.map +1 -0
- package/dist/tray-host/hx.js +25 -0
- package/dist/tray-host/hx.js.map +1 -0
- package/dist/tray-host/index.d.ts +110 -0
- package/dist/tray-host/index.d.ts.map +1 -0
- package/dist/tray-host/index.js +191 -0
- package/dist/tray-host/index.js.map +1 -0
- package/dist/tray-host/manager.d.ts +137 -0
- package/dist/tray-host/manager.d.ts.map +1 -0
- package/dist/tray-host/manager.js +462 -0
- package/dist/tray-host/manager.js.map +1 -0
- package/dist/tray-host/notify.d.ts +22 -0
- package/dist/tray-host/notify.d.ts.map +1 -0
- package/dist/tray-host/notify.js +74 -0
- package/dist/tray-host/notify.js.map +1 -0
- package/dist/tray-host/protocol.d.ts +106 -0
- package/dist/tray-host/protocol.d.ts.map +1 -0
- package/dist/tray-host/protocol.js +191 -0
- package/dist/tray-host/protocol.js.map +1 -0
- package/dist/tree/hx.d.ts +24 -0
- package/dist/tree/hx.d.ts.map +1 -0
- package/dist/tree/hx.js +25 -0
- package/dist/tree/hx.js.map +1 -0
- package/dist/tree/index.d.ts +221 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/dist/tree/index.js +751 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree/internal.d.ts +18 -0
- package/dist/tree/internal.d.ts.map +1 -0
- package/dist/tree/internal.js +66 -0
- package/dist/tree/internal.js.map +1 -0
- package/dist/tree/rows.d.ts +177 -0
- package/dist/tree/rows.d.ts.map +1 -0
- package/dist/tree/rows.js +179 -0
- package/dist/tree/rows.js.map +1 -0
- package/package.json +166 -12
- package/src/ansi/cast.ts +159 -0
- package/src/ansi/index.ts +53 -0
- package/src/ansi/palette.ts +226 -0
- package/src/ansi/parse.ts +780 -0
- package/src/ansi/sgr.ts +380 -0
- package/src/ansi/utf8.ts +84 -0
- package/src/calendar/Calendar.ts +744 -0
- package/src/calendar/DatePicker.ts +368 -0
- package/src/calendar/dates.ts +307 -0
- package/src/calendar/index.ts +51 -0
- package/src/charts/components.ts +864 -0
- package/src/charts/data.ts +776 -0
- package/src/charts/hx.ts +39 -0
- package/src/charts/index.ts +99 -0
- package/src/charts/node.ts +932 -0
- package/src/charts/render.ts +982 -0
- package/src/charts/scale.ts +214 -0
- package/src/charts/spec.ts +122 -0
- package/src/charts/timers.ts +24 -0
- package/src/code/hx.ts +51 -0
- package/src/code/index.ts +174 -0
- package/src/code-editor/completion.ts +161 -0
- package/src/code-editor/doc.ts +198 -0
- package/src/code-editor/hx.ts +26 -0
- package/src/code-editor/index.ts +615 -0
- package/src/code-editor/node.ts +1926 -0
- package/src/code-language/hljs.ts +302 -0
- package/src/code-language/index.ts +51 -0
- package/src/code-language/languages/glsl.ts +120 -0
- package/src/code-language/languages/javascript.ts +419 -0
- package/src/code-language/languages/json.ts +72 -0
- package/src/code-language/languages/shell.ts +221 -0
- package/src/code-language/languages/sql.ts +165 -0
- package/src/code-language/lezer.ts +190 -0
- package/src/code-language/registry.ts +66 -0
- package/src/code-language/runs.ts +128 -0
- package/src/code-language/stream.ts +306 -0
- package/src/code-language/textmate.ts +134 -0
- package/src/code-language/theme.ts +124 -0
- package/src/code-language/timers.ts +36 -0
- package/src/code-language/types.ts +252 -0
- package/src/codeblock/index.ts +146 -0
- package/src/color-picker/ColorField.ts +333 -0
- package/src/color-picker/ColorPicker.ts +1069 -0
- package/src/color-picker/color.ts +399 -0
- package/src/color-picker/index.ts +50 -0
- package/src/desktop-calendar/eds.ts +484 -0
- package/src/desktop-calendar/ical.ts +119 -0
- package/src/desktop-calendar/index.ts +287 -0
- package/src/embed/client.ts +311 -0
- package/src/embed/host.ts +432 -0
- package/src/embed/index.ts +33 -0
- package/src/embed/timers.ts +32 -0
- package/src/flow/draw.ts +418 -0
- package/src/flow/index.ts +473 -0
- package/src/flow/model.ts +687 -0
- package/src/flow/node.ts +3694 -0
- package/src/flow/paths.ts +403 -0
- package/src/flow/types.ts +634 -0
- package/src/formula/hx.ts +51 -0
- package/src/formula/index.ts +243 -0
- package/src/formula/katex.ts +209 -0
- package/src/formula/layout.ts +876 -0
- package/src/formula/node.ts +467 -0
- package/src/html/controls.ts +244 -0
- package/src/html/css/cascade.ts +606 -0
- package/src/html/css/parse.ts +500 -0
- package/src/html/css/style.ts +1371 -0
- package/src/html/css/ua.ts +174 -0
- package/src/html/css/values.ts +358 -0
- package/src/html/dom.ts +410 -0
- package/src/html/hx.ts +55 -0
- package/src/html/index.ts +545 -0
- package/src/html/layout/block.ts +876 -0
- package/src/html/layout/boxes.ts +981 -0
- package/src/html/layout/flex.ts +297 -0
- package/src/html/layout/floats.ts +125 -0
- package/src/html/layout/inline.ts +870 -0
- package/src/html/layout/table.ts +380 -0
- package/src/html/node.ts +967 -0
- package/src/html/paint.ts +605 -0
- package/src/html/resources.ts +214 -0
- package/src/index.ts +638 -0
- package/src/internal/heights.ts +222 -0
- package/src/internal/hx.ts +53 -0
- package/src/internal/scroll.ts +288 -0
- package/src/internal/text.ts +44 -0
- package/src/internal/timers.ts +44 -0
- package/src/internal/widget.ts +92 -0
- package/src/markdown/ast.ts +163 -0
- package/src/markdown/hx.ts +51 -0
- package/src/markdown/index.ts +686 -0
- package/src/markdown/parse.ts +1037 -0
- package/src/markdown/spans.ts +143 -0
- package/src/media-player/backends.ts +155 -0
- package/src/media-player/control.ts +70 -0
- package/src/media-player/hx.ts +51 -0
- package/src/media-player/index.ts +378 -0
- package/src/media-player/mpv.ts +146 -0
- package/src/media-player/vlc.ts +97 -0
- package/src/richtext/index.ts +42 -0
- package/src/richtext/links.ts +78 -0
- package/src/richtext/menu.ts +49 -0
- package/src/richtext/node.ts +406 -0
- package/src/richtext/runs.ts +253 -0
- package/src/table/hx.ts +51 -0
- package/src/table/index.ts +1270 -0
- package/src/table/rows.ts +275 -0
- package/src/terminal/backends.ts +242 -0
- package/src/terminal/hx.ts +51 -0
- package/src/terminal/index.ts +574 -0
- package/src/terminal/title.ts +172 -0
- package/src/terminal/vt/colors.ts +247 -0
- package/src/terminal/vt/diff.ts +467 -0
- package/src/terminal/vt/fonts.ts +233 -0
- package/src/terminal/vt/index.ts +443 -0
- package/src/terminal/vt/keys.ts +369 -0
- package/src/terminal/vt/mouse.ts +144 -0
- package/src/terminal/vt/node.ts +1242 -0
- package/src/terminal/vt/pty.ts +334 -0
- package/src/terminal/vt/renderer.ts +555 -0
- package/src/terminal/vt/timers.ts +31 -0
- package/src/terminal/vt/xterm.ts +193 -0
- package/src/terminal-output/hx.ts +51 -0
- package/src/terminal-output/index.ts +340 -0
- package/src/terminal-output/runs.ts +79 -0
- package/src/three/canvas.ts +451 -0
- package/src/three/events.ts +197 -0
- package/src/three/geometries.ts +429 -0
- package/src/three/globals.ts +34 -0
- package/src/three/hx.ts +22 -0
- package/src/three/index.ts +98 -0
- package/src/three/jsx-dev-runtime.ts +27 -0
- package/src/three/jsx-runtime.ts +38 -0
- package/src/three/jsx.ts +275 -0
- package/src/three/materials.ts +270 -0
- package/src/three/math.ts +585 -0
- package/src/three/objects.ts +397 -0
- package/src/three/passes.ts +90 -0
- package/src/three/postprocess.ts +677 -0
- package/src/three/raycast.ts +189 -0
- package/src/three/react-reconciler.d.ts +50 -0
- package/src/three/reconciler.ts +624 -0
- package/src/three/renderer-direct.ts +1055 -0
- package/src/three/renderer-indirect.ts +570 -0
- package/src/three/store.ts +207 -0
- package/src/timeline/hx.ts +31 -0
- package/src/timeline/index.ts +603 -0
- package/src/tray-host/hx.ts +51 -0
- package/src/tray-host/index.ts +331 -0
- package/src/tray-host/manager.ts +639 -0
- package/src/tray-host/notify.ts +102 -0
- package/src/tray-host/protocol.ts +235 -0
- package/src/tree/hx.ts +51 -0
- package/src/tree/index.ts +1127 -0
- package/src/tree/internal.ts +87 -0
- package/src/tree/rows.ts +334 -0
- package/src/index.d.ts +0 -2
- package/src/index.js +0 -9
- package/src/sparkline/index.d.ts +0 -29
- package/src/sparkline/index.js +0 -50
- package/src/sparkline/node.js +0 -72
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
// The retained node behind `<formula>` — one laid-out piece of mathematics.
|
|
2
|
+
//
|
|
3
|
+
// The split with `layout.ts`: the layout is pure geometry (KaTeX's tree in,
|
|
4
|
+
// positioned glyphs/rules/paths out), and this node is the ntk connection —
|
|
5
|
+
// it measures through the app's font manager, draws each glyph run through
|
|
6
|
+
// `fonts.layout`, fills rules and svg surds, and answers core's four text
|
|
7
|
+
// accessors so a `selectable` document (a `<Markdown>` with a math fence,
|
|
8
|
+
// or the component's own root) selects across the mathematics like any
|
|
9
|
+
// other text. Same seam `../richtext/node.ts` stands on; docs/extending.md
|
|
10
|
+
// calls it "answer from what you draw".
|
|
11
|
+
import { Node } from 'react-x11/node';
|
|
12
|
+
import type {
|
|
13
|
+
Context2D,
|
|
14
|
+
MeasureConstraints,
|
|
15
|
+
MeasuredSize,
|
|
16
|
+
} from 'react-x11/node';
|
|
17
|
+
import type { Rect } from 'react-x11';
|
|
18
|
+
|
|
19
|
+
import { faceOf } from './katex.js';
|
|
20
|
+
import type { KatexNode } from './katex.js';
|
|
21
|
+
import { layoutFormula } from './layout.js';
|
|
22
|
+
import type {
|
|
23
|
+
FormulaGlyph,
|
|
24
|
+
FormulaLayout,
|
|
25
|
+
FormulaPath,
|
|
26
|
+
FormulaShaper,
|
|
27
|
+
} from './layout.js';
|
|
28
|
+
|
|
29
|
+
/** The element name — registration key, `node.kind` and JSX tag alike. */
|
|
30
|
+
export const ELEMENT = 'formula';
|
|
31
|
+
|
|
32
|
+
/** The ntk connection a node is built against. Derived from `Node`'s own
|
|
33
|
+
* constructor rather than named, so it cannot drift from core's. */
|
|
34
|
+
export type NtkApp = ConstructorParameters<typeof Node>[2];
|
|
35
|
+
|
|
36
|
+
/** The props `<formula>` takes. The component builds them; apps use
|
|
37
|
+
* `<Formula>`, which also carries the fallback states. */
|
|
38
|
+
export interface FormulaElementProps {
|
|
39
|
+
/** KaTeX's virtual DOM for the expression. Stable identity per source —
|
|
40
|
+
* the layout cache keys off it. */
|
|
41
|
+
tree: KatexNode;
|
|
42
|
+
/** Pixels per em at the formula's base size. */
|
|
43
|
+
size: number;
|
|
44
|
+
/** Ink color for everything the expression does not color itself. */
|
|
45
|
+
color: string;
|
|
46
|
+
/** `KaTeX_Main-Regular.ttf` → bytes, registered into the app's font
|
|
47
|
+
* manager on first use. Absent means "shape through system fonts". */
|
|
48
|
+
fontData?: ReadonlyMap<string, Uint8Array> | null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// --- the slices of ntk this node speaks to ---------------------------------
|
|
52
|
+
// Typed structurally rather than imported: react-x11 keeps ntk deliberately
|
|
53
|
+
// loose, so an element says what it needs and nothing more.
|
|
54
|
+
|
|
55
|
+
interface MiniLine {
|
|
56
|
+
baseline: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface MiniLayout {
|
|
60
|
+
width: number;
|
|
61
|
+
lines: MiniLine[];
|
|
62
|
+
draw(ctx: unknown, x?: number, y?: number): void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface FontsLike {
|
|
66
|
+
layout(
|
|
67
|
+
content: Array<Record<string, unknown>>,
|
|
68
|
+
style: Record<string, unknown>,
|
|
69
|
+
options?: Record<string, unknown>,
|
|
70
|
+
): MiniLayout;
|
|
71
|
+
load(
|
|
72
|
+
source: Uint8Array,
|
|
73
|
+
opts?: { family?: string; weight?: number; style?: string },
|
|
74
|
+
): unknown;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface FillContext {
|
|
78
|
+
fillStyle: unknown;
|
|
79
|
+
save(): void;
|
|
80
|
+
restore(): void;
|
|
81
|
+
fillRect(x: number, y: number, w: number, h: number): void;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function canFill(ctx: Context2D): ctx is FillContext {
|
|
85
|
+
return typeof (ctx as Partial<FillContext> | null)?.fillRect === 'function';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
interface PathContext extends FillContext {
|
|
89
|
+
beginPath(): void;
|
|
90
|
+
moveTo(x: number, y: number): void;
|
|
91
|
+
lineTo(x: number, y: number): void;
|
|
92
|
+
bezierCurveTo(
|
|
93
|
+
x1: number,
|
|
94
|
+
y1: number,
|
|
95
|
+
x2: number,
|
|
96
|
+
y2: number,
|
|
97
|
+
x: number,
|
|
98
|
+
y: number,
|
|
99
|
+
): void;
|
|
100
|
+
quadraticCurveTo(x1: number, y1: number, x: number, y: number): void;
|
|
101
|
+
closePath(): void;
|
|
102
|
+
fill(): void;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function canPath(ctx: FillContext): ctx is PathContext {
|
|
106
|
+
const c = ctx as Partial<PathContext>;
|
|
107
|
+
return (
|
|
108
|
+
typeof c.beginPath === 'function' &&
|
|
109
|
+
typeof c.bezierCurveTo === 'function' &&
|
|
110
|
+
typeof c.fill === 'function'
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** The managers that already hold the KaTeX faces — `fonts.load` is
|
|
115
|
+
* registration, so doing it twice per manager would shadow itself. */
|
|
116
|
+
const fontsRegistered = new WeakSet<object>();
|
|
117
|
+
|
|
118
|
+
function registerKatexFonts(
|
|
119
|
+
fonts: FontsLike,
|
|
120
|
+
data: ReadonlyMap<string, Uint8Array>,
|
|
121
|
+
): void {
|
|
122
|
+
if (fontsRegistered.has(fonts)) return;
|
|
123
|
+
fontsRegistered.add(fonts);
|
|
124
|
+
for (const [file, bytes] of data) {
|
|
125
|
+
try {
|
|
126
|
+
fonts.load(bytes, faceOf(file));
|
|
127
|
+
} catch {
|
|
128
|
+
// one unreadable face degrades that face to system fallback, which
|
|
129
|
+
// is the ordinary state, not an error
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export class FormulaNode extends Node {
|
|
135
|
+
private _layout: FormulaLayout | null = null;
|
|
136
|
+
private _layoutOf: { tree: KatexNode; size: number; color: string } | null =
|
|
137
|
+
null;
|
|
138
|
+
private _widths = new Map<string, number>();
|
|
139
|
+
private _minis = new Map<string, MiniLayout | null>();
|
|
140
|
+
|
|
141
|
+
constructor(props: Record<string, unknown>, app: NtkApp) {
|
|
142
|
+
super(ELEMENT, props, app);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private _props(): Partial<FormulaElementProps> {
|
|
146
|
+
return this.props as unknown as Partial<FormulaElementProps>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private _fonts(): FontsLike | null {
|
|
150
|
+
const fonts = (this.app as { fonts?: FontsLike } | null)?.fonts;
|
|
151
|
+
if (!fonts || typeof fonts.layout !== 'function') return null;
|
|
152
|
+
const data = this._props().fontData;
|
|
153
|
+
if (data && typeof fonts.load === 'function') {
|
|
154
|
+
registerKatexFonts(fonts, data);
|
|
155
|
+
}
|
|
156
|
+
return fonts;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Measure one run in one face, memoized — the layout asks per glyph. */
|
|
160
|
+
private _shaper(fonts: FontsLike): FormulaShaper {
|
|
161
|
+
return {
|
|
162
|
+
width: (text, family, weight, style, size) => {
|
|
163
|
+
const key = `${family}|${weight}|${style}|${size}|${text}`;
|
|
164
|
+
const hit = this._widths.get(key);
|
|
165
|
+
if (hit !== undefined) return hit;
|
|
166
|
+
let width: number;
|
|
167
|
+
try {
|
|
168
|
+
width = fonts.layout([{ text, family, size, weight, style }], {
|
|
169
|
+
family,
|
|
170
|
+
size,
|
|
171
|
+
}).width;
|
|
172
|
+
} catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
if (this._widths.size > 2048) this._widths.clear();
|
|
176
|
+
this._widths.set(key, width);
|
|
177
|
+
return width;
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private _ensureLayout(): FormulaLayout | null {
|
|
183
|
+
const { tree, size = 14, color = 'black' } = this._props();
|
|
184
|
+
if (!tree) return null;
|
|
185
|
+
const prev = this._layoutOf;
|
|
186
|
+
if (
|
|
187
|
+
this._layout &&
|
|
188
|
+
prev &&
|
|
189
|
+
prev.tree === tree &&
|
|
190
|
+
prev.size === size &&
|
|
191
|
+
prev.color === color
|
|
192
|
+
) {
|
|
193
|
+
return this._layout;
|
|
194
|
+
}
|
|
195
|
+
const fonts = this._fonts();
|
|
196
|
+
this._layout = layoutFormula(tree, {
|
|
197
|
+
em: size,
|
|
198
|
+
color,
|
|
199
|
+
shaper: fonts ? this._shaper(fonts) : null,
|
|
200
|
+
});
|
|
201
|
+
this._layoutOf = { tree, size, color };
|
|
202
|
+
return this._layout;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** The natural size; mathematics does not wrap, so the offered width is
|
|
206
|
+
* not consulted and an over-wide formula overflows (scrollable inside
|
|
207
|
+
* its parent, like a code block). */
|
|
208
|
+
override measureContent(_constraints: MeasureConstraints): MeasuredSize {
|
|
209
|
+
const layout = this._ensureLayout();
|
|
210
|
+
if (!layout) return { width: 0, height: 0 };
|
|
211
|
+
return {
|
|
212
|
+
width: layout.width,
|
|
213
|
+
height: layout.ascent + layout.descent,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
override applyProps(
|
|
218
|
+
nextProps: Record<string, unknown>,
|
|
219
|
+
prevProps: Record<string, unknown>,
|
|
220
|
+
): void {
|
|
221
|
+
super.applyProps(nextProps, prevProps);
|
|
222
|
+
if (
|
|
223
|
+
nextProps.tree !== prevProps.tree ||
|
|
224
|
+
nextProps.size !== prevProps.size ||
|
|
225
|
+
nextProps.color !== prevProps.color ||
|
|
226
|
+
nextProps.fontData !== prevProps.fontData
|
|
227
|
+
) {
|
|
228
|
+
this._layout = null;
|
|
229
|
+
this._layoutOf = null;
|
|
230
|
+
this._minis.clear();
|
|
231
|
+
this.invalidateMeasure('content');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
override destroySubtree(): void {
|
|
236
|
+
this._widths.clear();
|
|
237
|
+
this._minis.clear();
|
|
238
|
+
super.destroySubtree();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// --- answering for our own text ------------------------------------------
|
|
242
|
+
//
|
|
243
|
+
// The four accessors from react-x11#291, over the glyphs in reading
|
|
244
|
+
// order. Indices are **code points** into `textContent()` and rectangles
|
|
245
|
+
// are in the owning window's coordinates — the space `abs` is in.
|
|
246
|
+
|
|
247
|
+
private _glyphs(): FormulaGlyph[] {
|
|
248
|
+
return this._ensureLayout()?.glyphs ?? [];
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
override textContent(): string {
|
|
252
|
+
return this._ensureLayout()?.text ?? '';
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
override textIndexAt(x: number, y: number): number {
|
|
256
|
+
const glyphs = this._glyphs();
|
|
257
|
+
if (!glyphs.length) return 0;
|
|
258
|
+
const lx = x - this.abs.x;
|
|
259
|
+
const ly = y - this.abs.y;
|
|
260
|
+
let best: FormulaGlyph | null = null;
|
|
261
|
+
let bestDist = Infinity;
|
|
262
|
+
for (const g of glyphs) {
|
|
263
|
+
const dx =
|
|
264
|
+
lx < g.x ? g.x - lx : lx > g.x + g.width ? lx - (g.x + g.width) : 0;
|
|
265
|
+
const dy = ly < g.top ? g.top - ly : ly > g.bottom ? ly - g.bottom : 0;
|
|
266
|
+
const dist = dx * dx + dy * dy;
|
|
267
|
+
if (dist < bestDist) {
|
|
268
|
+
bestDist = dist;
|
|
269
|
+
best = g;
|
|
270
|
+
if (dist === 0) break;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (!best) return 0;
|
|
274
|
+
const within = best.width
|
|
275
|
+
? Math.round(((lx - best.x) / best.width) * best.length)
|
|
276
|
+
: 0;
|
|
277
|
+
return best.index + Math.max(0, Math.min(best.length, within));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
override textCaretRect(index: number): Rect | null {
|
|
281
|
+
const glyphs = this._glyphs();
|
|
282
|
+
if (!glyphs.length) return null;
|
|
283
|
+
let g = glyphs[glyphs.length - 1];
|
|
284
|
+
for (const candidate of glyphs) {
|
|
285
|
+
if (
|
|
286
|
+
index >= candidate.index &&
|
|
287
|
+
index <= candidate.index + candidate.length
|
|
288
|
+
) {
|
|
289
|
+
g = candidate;
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const fraction = g.length
|
|
294
|
+
? Math.max(0, Math.min(1, (index - g.index) / g.length))
|
|
295
|
+
: 0;
|
|
296
|
+
return {
|
|
297
|
+
x: this.abs.x + g.x + fraction * g.width,
|
|
298
|
+
y: this.abs.y + g.top,
|
|
299
|
+
width: 0,
|
|
300
|
+
height: g.bottom - g.top,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
override textRangeRects(start: number, end: number): Rect[] {
|
|
305
|
+
if (end <= start) return [];
|
|
306
|
+
const bands: Rect[] = [];
|
|
307
|
+
for (const g of this._glyphs()) {
|
|
308
|
+
const a = Math.max(start, g.index);
|
|
309
|
+
const b = Math.min(end, g.index + g.length);
|
|
310
|
+
if (b <= a) continue;
|
|
311
|
+
const x1 = g.x + (g.length ? ((a - g.index) / g.length) * g.width : 0);
|
|
312
|
+
const x2 =
|
|
313
|
+
g.x + (g.length ? ((b - g.index) / g.length) * g.width : g.width);
|
|
314
|
+
const rect = {
|
|
315
|
+
x: this.abs.x + x1,
|
|
316
|
+
y: this.abs.y + g.top,
|
|
317
|
+
width: x2 - x1,
|
|
318
|
+
height: g.bottom - g.top,
|
|
319
|
+
};
|
|
320
|
+
// consecutive glyphs on the same band fuse into one rectangle, so an
|
|
321
|
+
// ordinary run selects as one strip rather than a picket fence
|
|
322
|
+
const last = bands[bands.length - 1];
|
|
323
|
+
if (
|
|
324
|
+
last &&
|
|
325
|
+
Math.abs(last.y - rect.y) < 0.5 &&
|
|
326
|
+
Math.abs(last.height - rect.height) < 0.5 &&
|
|
327
|
+
rect.x >= last.x - 0.5 &&
|
|
328
|
+
rect.x <= last.x + last.width + 1.5
|
|
329
|
+
) {
|
|
330
|
+
last.width = Math.max(last.width, rect.x + rect.width - last.x);
|
|
331
|
+
} else {
|
|
332
|
+
bands.push(rect);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return bands;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// --- paint ---------------------------------------------------------------
|
|
339
|
+
|
|
340
|
+
private _mini(g: FormulaGlyph): MiniLayout | null {
|
|
341
|
+
const fonts = this._fonts();
|
|
342
|
+
if (!fonts) return null;
|
|
343
|
+
const key = `${g.family}|${g.weight}|${g.style}|${g.size}|${g.color}|${g.text}`;
|
|
344
|
+
const hit = this._minis.get(key);
|
|
345
|
+
if (hit !== undefined) return hit;
|
|
346
|
+
let mini: MiniLayout | null = null;
|
|
347
|
+
try {
|
|
348
|
+
mini = fonts.layout(
|
|
349
|
+
[
|
|
350
|
+
{
|
|
351
|
+
text: g.text,
|
|
352
|
+
family: g.family,
|
|
353
|
+
size: g.size,
|
|
354
|
+
weight: g.weight,
|
|
355
|
+
style: g.style,
|
|
356
|
+
color: g.color,
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
{ family: g.family, size: g.size },
|
|
360
|
+
);
|
|
361
|
+
} catch {
|
|
362
|
+
mini = null;
|
|
363
|
+
}
|
|
364
|
+
if (this._minis.size > 1024) this._minis.clear();
|
|
365
|
+
this._minis.set(key, mini);
|
|
366
|
+
return mini;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private _fillPath(ctx: PathContext, p: FormulaPath): void {
|
|
370
|
+
// The transform, per katex.css: `slice` is "scale by height, clip the
|
|
371
|
+
// 400em tail at the box edge" — clamping x in path space renders the
|
|
372
|
+
// same shape as the clip because the tails are horizontal fills.
|
|
373
|
+
let sx: number;
|
|
374
|
+
let sy: number;
|
|
375
|
+
let clampX = Infinity;
|
|
376
|
+
if (p.mode === 'none') {
|
|
377
|
+
sx = p.width / p.viewWidth;
|
|
378
|
+
sy = p.height / p.viewHeight;
|
|
379
|
+
} else {
|
|
380
|
+
sy = p.height / p.viewHeight;
|
|
381
|
+
sx = sy;
|
|
382
|
+
if (p.mode === 'slice') clampX = p.width / (sx || 1);
|
|
383
|
+
else sx = sy = Math.min(sy, p.width / p.viewWidth || sy);
|
|
384
|
+
}
|
|
385
|
+
const ox = this.abs.x + p.x;
|
|
386
|
+
const oy = this.abs.y + p.y;
|
|
387
|
+
const X = (x: number): number => ox + Math.min(x, clampX) * sx;
|
|
388
|
+
const Y = (y: number): number => oy + y * sy;
|
|
389
|
+
ctx.beginPath();
|
|
390
|
+
for (const s of p.segs) {
|
|
391
|
+
switch (s.c) {
|
|
392
|
+
case 'M':
|
|
393
|
+
ctx.moveTo(X(s.x), Y(s.y));
|
|
394
|
+
break;
|
|
395
|
+
case 'L':
|
|
396
|
+
ctx.lineTo(X(s.x), Y(s.y));
|
|
397
|
+
break;
|
|
398
|
+
case 'C':
|
|
399
|
+
ctx.bezierCurveTo(X(s.x1), Y(s.y1), X(s.x2), Y(s.y2), X(s.x), Y(s.y));
|
|
400
|
+
break;
|
|
401
|
+
case 'Q':
|
|
402
|
+
ctx.quadraticCurveTo(X(s.x1), Y(s.y1), X(s.x), Y(s.y));
|
|
403
|
+
break;
|
|
404
|
+
case 'Z':
|
|
405
|
+
ctx.closePath();
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
ctx.fillStyle = p.color;
|
|
410
|
+
ctx.fill();
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
override paint(ctx: Context2D): void {
|
|
414
|
+
super.paint(ctx); // background, border, clip to `abs`
|
|
415
|
+
const layout = this._ensureLayout();
|
|
416
|
+
if (!layout || !canFill(ctx)) return;
|
|
417
|
+
const { x, y } = this.abs;
|
|
418
|
+
|
|
419
|
+
ctx.save();
|
|
420
|
+
|
|
421
|
+
// 1. the band the document selection has claimed of this formula
|
|
422
|
+
const range = this.selectionRange;
|
|
423
|
+
if (range && range.end > range.start) {
|
|
424
|
+
ctx.fillStyle = this.selectionColor;
|
|
425
|
+
for (const r of this.textRangeRects(range.start, range.end)) {
|
|
426
|
+
ctx.fillRect(
|
|
427
|
+
Math.round(r.x),
|
|
428
|
+
Math.round(r.y),
|
|
429
|
+
Math.ceil(r.width),
|
|
430
|
+
Math.ceil(r.height),
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// 2. rules — fraction bars, \rule, overlines
|
|
436
|
+
for (const r of layout.rules) {
|
|
437
|
+
if (r.color === 'transparent') continue;
|
|
438
|
+
ctx.fillStyle = r.color;
|
|
439
|
+
ctx.fillRect(
|
|
440
|
+
Math.round(x + r.x),
|
|
441
|
+
Math.round(y + r.y),
|
|
442
|
+
Math.max(1, Math.round(r.width)),
|
|
443
|
+
Math.max(1, Math.round(r.height)),
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// 3. svg geometry — surds, stretchy accents (needs a path API, which
|
|
448
|
+
// the mock backend does not have; skipping is the convention)
|
|
449
|
+
if (canPath(ctx)) {
|
|
450
|
+
for (const p of layout.paths) {
|
|
451
|
+
if (p.color === 'transparent' || !p.segs.length) continue;
|
|
452
|
+
if (p.width <= 0 || p.height <= 0) continue;
|
|
453
|
+
this._fillPath(ctx, p);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// 4. the ink
|
|
458
|
+
for (const g of layout.glyphs) {
|
|
459
|
+
if (g.color === 'transparent') continue;
|
|
460
|
+
const mini = this._mini(g);
|
|
461
|
+
if (!mini || !mini.lines.length) continue;
|
|
462
|
+
mini.draw(ctx, x + g.x, y + g.baseline - mini.lines[0].baseline);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
ctx.restore();
|
|
466
|
+
}
|
|
467
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// Form controls: where they go, and how big they are.
|
|
2
|
+
//
|
|
3
|
+
// A form control in a document is **not drawn here**. It is a real core
|
|
4
|
+
// widget — `<button>`, `<select>`, `<checkbox>`, `<radio>`, `<textinput>`,
|
|
5
|
+
// `<textarea>` — mounted beside the element at the rectangle layout gave it.
|
|
6
|
+
//
|
|
7
|
+
// That is the same escape hatch `<Flow>` opened for a node whose body is a
|
|
8
|
+
// form, and it exists for the same reason: a drawn control is a picture of a
|
|
9
|
+
// control. It does not take focus in the window's focus order, it does not
|
|
10
|
+
// speak to an assistive technology, it does not blink a caret or open a menu
|
|
11
|
+
// or agree with the platform's keyboard conventions, and every one of those
|
|
12
|
+
// would have to be rebuilt inside the paint pass. Mounting the real widget
|
|
13
|
+
// gets all of it, and gets it *consistent with the rest of the application* —
|
|
14
|
+
// a `<select>` in a rendered document drops the same menu as a `<Select>` in
|
|
15
|
+
// the surrounding window, because it is the same widget.
|
|
16
|
+
//
|
|
17
|
+
// What it costs is the reason this file exists rather than the component
|
|
18
|
+
// doing it inline: the box in the flow has to be the size the widget will
|
|
19
|
+
// actually be, before the widget exists. So the sizes here are measured from
|
|
20
|
+
// the same font metrics the widget will use, and `<Html>` mounts into
|
|
21
|
+
// exactly the rectangle layout reserved.
|
|
22
|
+
import type { Element } from 'domhandler';
|
|
23
|
+
|
|
24
|
+
import { attr, tagOf } from './dom.js';
|
|
25
|
+
import type { ComputedStyle } from './css/style.js';
|
|
26
|
+
import type { BoxTree, ReplacedKind } from './layout/boxes.js';
|
|
27
|
+
import type { FontsLike } from './layout/inline.js';
|
|
28
|
+
|
|
29
|
+
/** The palette numbers a control's box has to reserve room for. */
|
|
30
|
+
export interface ControlChrome {
|
|
31
|
+
controlPadY: number;
|
|
32
|
+
controlBorder: number;
|
|
33
|
+
controlRadius: number;
|
|
34
|
+
surface: string;
|
|
35
|
+
borderColor: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Where a control goes, in the element's own coordinate space. */
|
|
39
|
+
export interface ControlRect {
|
|
40
|
+
element: Element;
|
|
41
|
+
kind: ReplacedKind;
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
width: number;
|
|
45
|
+
height: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** The rectangles every control in a laid-out document landed on. */
|
|
49
|
+
export function controlRectsOf(tree: BoxTree): ControlRect[] {
|
|
50
|
+
const out: ControlRect[] = [];
|
|
51
|
+
for (const box of tree.controls) {
|
|
52
|
+
if (!box.el) continue;
|
|
53
|
+
if (box.width <= 0 || box.height <= 0) continue;
|
|
54
|
+
out.push({
|
|
55
|
+
element: box.el,
|
|
56
|
+
kind: box.replaced,
|
|
57
|
+
x: box.x,
|
|
58
|
+
y: box.y,
|
|
59
|
+
width: box.width,
|
|
60
|
+
height: box.height,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The size a control's box takes in the flow.
|
|
68
|
+
*
|
|
69
|
+
* An explicit `width`/`height` in the cascade wins — layout applies it after
|
|
70
|
+
* this — so what is computed here is the *intrinsic* size: what the widget
|
|
71
|
+
* would ask for. Text fields size from `size`/`cols`/`rows` the way HTML says
|
|
72
|
+
* and from the font's own metrics otherwise, because a field measured in
|
|
73
|
+
* pixels is the wrong size in every theme but the one it was measured in.
|
|
74
|
+
*/
|
|
75
|
+
export function measureControl(
|
|
76
|
+
el: Element,
|
|
77
|
+
kind: ReplacedKind,
|
|
78
|
+
style: ComputedStyle,
|
|
79
|
+
fonts: FontsLike | null,
|
|
80
|
+
look: ControlChrome,
|
|
81
|
+
): { width: number; height: number } {
|
|
82
|
+
const em = style.fontSize;
|
|
83
|
+
const ch = charWidth(style, fonts);
|
|
84
|
+
const lineHeight = Math.round(em * 1.35);
|
|
85
|
+
const padding = Math.round(em * 0.5);
|
|
86
|
+
// The widget's own vertical chrome, so the reserved box and the mounted
|
|
87
|
+
// widget agree rather than the widget overflowing the hole left for it.
|
|
88
|
+
const chrome = look.controlPadY * 2 + look.controlBorder * 2;
|
|
89
|
+
|
|
90
|
+
switch (kind) {
|
|
91
|
+
case 'checkbox':
|
|
92
|
+
case 'radio': {
|
|
93
|
+
const box = Math.round(em * 0.95);
|
|
94
|
+
return { width: box, height: box };
|
|
95
|
+
}
|
|
96
|
+
case 'button': {
|
|
97
|
+
const label = buttonLabel(el);
|
|
98
|
+
return {
|
|
99
|
+
width: Math.max(
|
|
100
|
+
Math.round(ch * label.length + padding * 2 + chrome),
|
|
101
|
+
Math.round(em * 3),
|
|
102
|
+
),
|
|
103
|
+
height: lineHeight + chrome,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
case 'select': {
|
|
107
|
+
const widest = optionWidths(el);
|
|
108
|
+
// The room for the chevron is the widget's, not the document's, but
|
|
109
|
+
// the document has to reserve it or the last letter of the widest
|
|
110
|
+
// option sits under it.
|
|
111
|
+
return {
|
|
112
|
+
width: Math.max(
|
|
113
|
+
Math.round(ch * widest + padding * 2 + em + chrome),
|
|
114
|
+
Math.round(em * 6),
|
|
115
|
+
),
|
|
116
|
+
height: lineHeight + chrome,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
case 'textarea': {
|
|
120
|
+
const cols = numberAttr(el, 'cols') ?? 30;
|
|
121
|
+
const rows = numberAttr(el, 'rows') ?? 3;
|
|
122
|
+
return {
|
|
123
|
+
width: Math.round(ch * cols + padding * 2 + chrome),
|
|
124
|
+
height: Math.round(lineHeight * rows + chrome),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
case 'input': {
|
|
128
|
+
const size = numberAttr(el, 'size') ?? 20;
|
|
129
|
+
return {
|
|
130
|
+
width: Math.round(ch * size + padding * 2 + chrome),
|
|
131
|
+
height: lineHeight + chrome,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
default:
|
|
135
|
+
return { width: 0, height: 0 };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** The label a `<button>` or an `<input type=submit>` shows. */
|
|
140
|
+
export function buttonLabel(el: Element): string {
|
|
141
|
+
if (tagOf(el) === 'button') {
|
|
142
|
+
let text = '';
|
|
143
|
+
for (const child of el.children) {
|
|
144
|
+
if (child.type === 'text') text += child.data;
|
|
145
|
+
}
|
|
146
|
+
const trimmed = text.trim();
|
|
147
|
+
if (trimmed) return trimmed;
|
|
148
|
+
}
|
|
149
|
+
const value = attr(el, 'value');
|
|
150
|
+
if (value) return value;
|
|
151
|
+
const type = (attr(el, 'type') ?? '').toLowerCase();
|
|
152
|
+
if (type === 'submit') return 'Submit';
|
|
153
|
+
if (type === 'reset') return 'Reset';
|
|
154
|
+
return attr(el, 'alt') ?? 'Button';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** A `<select>`'s options, as the widget's item list. */
|
|
158
|
+
export function optionsOf(el: Element): { value: string; label: string }[] {
|
|
159
|
+
const out: { value: string; label: string }[] = [];
|
|
160
|
+
const walk = (node: Element): void => {
|
|
161
|
+
for (const child of node.children) {
|
|
162
|
+
if (child.type !== 'tag') continue;
|
|
163
|
+
const tag = tagOf(child);
|
|
164
|
+
if (tag === 'option') {
|
|
165
|
+
let label = '';
|
|
166
|
+
for (const kid of child.children) {
|
|
167
|
+
if (kid.type === 'text') label += kid.data;
|
|
168
|
+
}
|
|
169
|
+
const trimmed = label.trim();
|
|
170
|
+
out.push({ value: attr(child, 'value') ?? trimmed, label: trimmed });
|
|
171
|
+
} else if (tag === 'optgroup') {
|
|
172
|
+
walk(child);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
walk(el);
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Which option a `<select>` starts on: `selected`, else the first. */
|
|
181
|
+
export function selectedOption(el: Element): string | null {
|
|
182
|
+
const options = optionsOf(el);
|
|
183
|
+
const walk = (node: Element): string | null => {
|
|
184
|
+
for (const child of node.children) {
|
|
185
|
+
if (child.type !== 'tag') continue;
|
|
186
|
+
if (tagOf(child) === 'option' && attr(child, 'selected') !== undefined) {
|
|
187
|
+
let label = '';
|
|
188
|
+
for (const kid of child.children) {
|
|
189
|
+
if (kid.type === 'text') label += kid.data;
|
|
190
|
+
}
|
|
191
|
+
return attr(child, 'value') ?? label.trim();
|
|
192
|
+
}
|
|
193
|
+
const nested = walk(child);
|
|
194
|
+
if (nested !== null) return nested;
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
};
|
|
198
|
+
return walk(el) ?? options[0]?.value ?? null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** A `<textarea>`'s initial text — its content, not an attribute. */
|
|
202
|
+
export function textareaValue(el: Element): string {
|
|
203
|
+
let text = '';
|
|
204
|
+
for (const child of el.children) {
|
|
205
|
+
if (child.type === 'text') text += child.data;
|
|
206
|
+
}
|
|
207
|
+
// HTML drops one leading newline after the open tag, which is why a
|
|
208
|
+
// pretty-printed `<textarea>` does not start with a blank line.
|
|
209
|
+
return text.replace(/^\r?\n/, '');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function numberAttr(el: Element, name: string): number | null {
|
|
213
|
+
const raw = attr(el, name);
|
|
214
|
+
if (!raw) return null;
|
|
215
|
+
const n = parseInt(raw, 10);
|
|
216
|
+
return Number.isFinite(n) && n > 0 ? n : null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function optionWidths(el: Element): number {
|
|
220
|
+
let widest = 4;
|
|
221
|
+
for (const option of optionsOf(el))
|
|
222
|
+
widest = Math.max(widest, option.label.length);
|
|
223
|
+
return widest;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** The average advance of a digit in this style — the `ch` unit, measured
|
|
227
|
+
* rather than guessed, because `size="20"` in a proportional face is a very
|
|
228
|
+
* different width from 20 monospace cells. */
|
|
229
|
+
function charWidth(style: ComputedStyle, fonts: FontsLike | null): number {
|
|
230
|
+
if (!fonts) return style.fontSize * 0.55;
|
|
231
|
+
try {
|
|
232
|
+
const font = fonts.match(style.fontFamily, {
|
|
233
|
+
size: style.fontSize,
|
|
234
|
+
weight: style.fontWeight,
|
|
235
|
+
style: style.fontStyle,
|
|
236
|
+
});
|
|
237
|
+
const metrics = font.metrics(style.fontSize);
|
|
238
|
+
// No advance in the metrics slice, so the em box's height is the proxy
|
|
239
|
+
// every UI toolkit uses for it.
|
|
240
|
+
return (metrics.ascent + metrics.descent) * 0.5;
|
|
241
|
+
} catch {
|
|
242
|
+
return style.fontSize * 0.55;
|
|
243
|
+
}
|
|
244
|
+
}
|