@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,861 @@
|
|
|
1
|
+
// `<htmlview>` — the retained element behind `<Html>`.
|
|
2
|
+
//
|
|
3
|
+
// It owns the whole pipeline and, more importantly, owns **when each stage
|
|
4
|
+
// runs**. That is the component's reason to exist, so it is worth stating in
|
|
5
|
+
// one place:
|
|
6
|
+
//
|
|
7
|
+
// source changed → parse (incrementally), style, box, lay out, paint
|
|
8
|
+
// stylesheet arrived → style, box, lay out, paint
|
|
9
|
+
// DOM mutated → box, lay out, paint
|
|
10
|
+
// width changed → lay out, paint (no parse, no cascade)
|
|
11
|
+
// media band crossed → style, box, lay out, paint
|
|
12
|
+
// scrolled / exposed → paint, culled to the damage rect
|
|
13
|
+
//
|
|
14
|
+
// Each row is strictly cheaper than the one above it, and the two the
|
|
15
|
+
// component is measured on — first content painted, and what an expose or a
|
|
16
|
+
// resize costs — are the two cheapest. Nothing in a computed style depends on
|
|
17
|
+
// the width (see css/values.ts) and nothing in a box tree depends on the
|
|
18
|
+
// scroll, which is what makes the table true rather than aspirational.
|
|
19
|
+
//
|
|
20
|
+
// **Why one element rather than a tree of `<box>`es and `<richtext>`s**, the
|
|
21
|
+
// way `<Markdown>` is built. Two reasons, and the second is the load-bearing
|
|
22
|
+
// one:
|
|
23
|
+
//
|
|
24
|
+
// 1. A document of any size is thousands of elements. Reconciling them
|
|
25
|
+
// through React and laying them out through yoga, per keystroke of a
|
|
26
|
+
// streaming document, is the cost this is trying not to pay.
|
|
27
|
+
// 2. **CSS layout is not the host's layout.** react-x11 lays out with yoga,
|
|
28
|
+
// which is flexbox; block flow with margin collapsing, floats, an inline
|
|
29
|
+
// formatting context and table column sizing are not expressible in it.
|
|
30
|
+
// Composing would mean approximating the layout model, which is what
|
|
31
|
+
// ntk's `HtmlView` did and what makes it hard to trust. So the element
|
|
32
|
+
// draws — the same call `<Flow>` makes for a different reason — and the
|
|
33
|
+
// things that must be real widgets (form controls) are mounted beside it
|
|
34
|
+
// rather than inside it.
|
|
35
|
+
//
|
|
36
|
+
// What is reused from `<richtext>` is everything that was not about the
|
|
37
|
+
// element: the `TextRun` vocabulary, the per-run decoration painter, and the
|
|
38
|
+
// bidi-correct selection bands. See `src/richtext/runs.ts`.
|
|
39
|
+
import { registerElement, registeredElements } from 'react-x11/host';
|
|
40
|
+
import { Node } from 'react-x11/node';
|
|
41
|
+
import { codePointAtOffset, codeUnitOffsets } from '../internal/text.js';
|
|
42
|
+
import { attr, HtmlSource, isElement, tagOf } from './dom.js';
|
|
43
|
+
import { Cascade } from './css/cascade.js';
|
|
44
|
+
import { parseStylesheet } from './css/parse.js';
|
|
45
|
+
import { uaStylesheet } from './css/ua.js';
|
|
46
|
+
import { buildBoxes } from './layout/boxes.js';
|
|
47
|
+
import { layoutDocument } from './layout/block.js';
|
|
48
|
+
// Through the inline module rather than a second cache: the offsets table for
|
|
49
|
+
// a layout is built once, on the first selection that needs it.
|
|
50
|
+
import { layoutOffsets as layoutOffsetsOf } from './layout/inline.js';
|
|
51
|
+
import { lineBands as bandsFor } from '../richtext/runs.js';
|
|
52
|
+
import { paintDocument, queryChildIndex } from './paint.js';
|
|
53
|
+
import { controlRectsOf, measureControl } from './controls.js';
|
|
54
|
+
import { ResourceStore } from './resources.js';
|
|
55
|
+
/** The element name — registration key, `node.kind` and JSX tag alike. */
|
|
56
|
+
export const ELEMENT = 'htmlview';
|
|
57
|
+
export function registerHtmlView() {
|
|
58
|
+
if (registeredElements().includes(ELEMENT))
|
|
59
|
+
return;
|
|
60
|
+
registerElement(ELEMENT, {
|
|
61
|
+
create: (props, app) => new HtmlViewNode(props, app),
|
|
62
|
+
// `source` and `look` are this element's own vocabulary and neither is a
|
|
63
|
+
// style name today; declaring them keeps the DEV flat-style-prop
|
|
64
|
+
// assertion honest if core's vocabulary grows underneath us.
|
|
65
|
+
semanticNames: ['source', 'look', 'stylesheet', 'complete'],
|
|
66
|
+
childrenAllowed: false,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** What changed, and therefore how far back up the pipeline to go. */
|
|
70
|
+
var Stale;
|
|
71
|
+
(function (Stale) {
|
|
72
|
+
Stale[Stale["Nothing"] = 0] = "Nothing";
|
|
73
|
+
Stale[Stale["Layout"] = 1] = "Layout";
|
|
74
|
+
Stale[Stale["Boxes"] = 2] = "Boxes";
|
|
75
|
+
Stale[Stale["Style"] = 3] = "Style";
|
|
76
|
+
Stale[Stale["Everything"] = 4] = "Everything";
|
|
77
|
+
})(Stale || (Stale = {}));
|
|
78
|
+
export class HtmlViewNode extends Node {
|
|
79
|
+
_source = new HtmlSource();
|
|
80
|
+
_resources;
|
|
81
|
+
_cascade = null;
|
|
82
|
+
_tree = null;
|
|
83
|
+
_stale = Stale.Everything;
|
|
84
|
+
_laidOutAt = -1;
|
|
85
|
+
_mediaBand = -1;
|
|
86
|
+
_documentHeight = 0;
|
|
87
|
+
_documentWidth = 0;
|
|
88
|
+
_textPoints = null;
|
|
89
|
+
/** Whether code points and code units are the same index — true unless
|
|
90
|
+
* the text carries surrogate pairs. null until checked. */
|
|
91
|
+
_pointsAreUnits = null;
|
|
92
|
+
_hovered = [];
|
|
93
|
+
_scriptsSeen = new WeakSet();
|
|
94
|
+
_controls = [];
|
|
95
|
+
_reportedDomRevision = -1;
|
|
96
|
+
constructor(props, app) {
|
|
97
|
+
super(ELEMENT, props, app);
|
|
98
|
+
this._resources = new ResourceStore((request) => this._props().onResource?.(request) ?? null, () => {
|
|
99
|
+
// A late resource changes intrinsic sizes, so the box tree is what
|
|
100
|
+
// has to be rebuilt — not merely repainted. An image that arrives
|
|
101
|
+
// after first paint is the ordinary case, not an error path.
|
|
102
|
+
this._invalidate(Stale.Boxes);
|
|
103
|
+
});
|
|
104
|
+
this._read();
|
|
105
|
+
}
|
|
106
|
+
_props() {
|
|
107
|
+
return this.props;
|
|
108
|
+
}
|
|
109
|
+
// --- the pipeline ---------------------------------------------------------
|
|
110
|
+
_invalidate(stale) {
|
|
111
|
+
if (stale > this._stale)
|
|
112
|
+
this._stale = stale;
|
|
113
|
+
if (stale >= Stale.Layout)
|
|
114
|
+
this.invalidateMeasure('content');
|
|
115
|
+
this.invalidate(stale >= Stale.Layout, this, 'props');
|
|
116
|
+
}
|
|
117
|
+
/** Take the props' source into the parser. Cheap when nothing changed, and
|
|
118
|
+
* an append when the new source extends the old — see `HtmlSource`. */
|
|
119
|
+
_read() {
|
|
120
|
+
const props = this._props();
|
|
121
|
+
const changed = this._source.setSource(props.source ?? '', props.complete !== false);
|
|
122
|
+
if (changed) {
|
|
123
|
+
this._invalidate(Stale.Style);
|
|
124
|
+
props.onDocument?.(this._source.document);
|
|
125
|
+
this._reportedDomRevision = props.domRevision ?? 0;
|
|
126
|
+
}
|
|
127
|
+
this._sweep();
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Hand the document's own declarations to the host: every `<script>` once,
|
|
131
|
+
* and every resource that has not been asked for.
|
|
132
|
+
*
|
|
133
|
+
* Scripts are **never parsed and never run**. The seam is the whole of the
|
|
134
|
+
* feature: an application that wants scripting brings its own engine and
|
|
135
|
+
* its own policy, and one that does not gets a document that cannot
|
|
136
|
+
* surprise it. There is no configuration in between, because a renderer
|
|
137
|
+
* that half-runs a script is a renderer nobody can reason about.
|
|
138
|
+
*/
|
|
139
|
+
_sweep() {
|
|
140
|
+
const props = this._props();
|
|
141
|
+
const facts = this._source.facts();
|
|
142
|
+
if (props.onScript) {
|
|
143
|
+
for (const el of facts.scripts) {
|
|
144
|
+
if (this._scriptsSeen.has(el))
|
|
145
|
+
continue;
|
|
146
|
+
this._scriptsSeen.add(el);
|
|
147
|
+
props.onScript({
|
|
148
|
+
type: (attr(el, 'type') ?? 'text/javascript').toLowerCase(),
|
|
149
|
+
src: attr(el, 'src') ?? null,
|
|
150
|
+
text: textOf(el),
|
|
151
|
+
element: el,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const el of facts.resources) {
|
|
156
|
+
const tag = tagOf(el);
|
|
157
|
+
const url = tag === 'link' ? attr(el, 'href') : attr(el, 'src');
|
|
158
|
+
if (!url)
|
|
159
|
+
continue;
|
|
160
|
+
this._resources.request({
|
|
161
|
+
url,
|
|
162
|
+
kind: tag === 'link' ? 'stylesheet' : 'image',
|
|
163
|
+
element: el,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** Rebuild the cascade — the document's sheets plus the host's. */
|
|
168
|
+
_restyle(width) {
|
|
169
|
+
const props = this._props();
|
|
170
|
+
const sheets = [uaStylesheet(props.look)];
|
|
171
|
+
let order = 0;
|
|
172
|
+
for (const ref of this._source.facts().sheets) {
|
|
173
|
+
const text = ref.kind === 'inline'
|
|
174
|
+
? ref.text
|
|
175
|
+
: this._resources.stylesheetText(ref.href);
|
|
176
|
+
if (!text)
|
|
177
|
+
continue;
|
|
178
|
+
const sheet = parseStylesheet(text, order);
|
|
179
|
+
order += sheet.rules.length + 1;
|
|
180
|
+
// `@import` is a resource like any other, and its rules sit *before*
|
|
181
|
+
// the importing sheet's — so a fetched import is spliced in ahead.
|
|
182
|
+
for (const url of sheet.imports) {
|
|
183
|
+
this._resources.request({
|
|
184
|
+
url,
|
|
185
|
+
kind: 'stylesheet',
|
|
186
|
+
element: ref.element,
|
|
187
|
+
});
|
|
188
|
+
const imported = this._resources.stylesheetText(url);
|
|
189
|
+
if (imported) {
|
|
190
|
+
const parsed = parseStylesheet(imported, order);
|
|
191
|
+
order += parsed.rules.length + 1;
|
|
192
|
+
sheets.push(parsed);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
sheets.push(sheet);
|
|
196
|
+
}
|
|
197
|
+
const extra = props.stylesheet;
|
|
198
|
+
for (const text of Array.isArray(extra) ? extra : extra ? [extra] : []) {
|
|
199
|
+
const sheet = parseStylesheet(text, order);
|
|
200
|
+
order += sheet.rules.length + 1;
|
|
201
|
+
sheets.push(sheet);
|
|
202
|
+
}
|
|
203
|
+
this._cascade = new Cascade(sheets, props.look, width, this._viewportHeight());
|
|
204
|
+
this._cascade.setPointer({
|
|
205
|
+
hovered: new Set(this._hovered),
|
|
206
|
+
active: EMPTY_SET,
|
|
207
|
+
});
|
|
208
|
+
this._mediaBand = this._cascade.mediaBand(width);
|
|
209
|
+
}
|
|
210
|
+
_viewportHeight() {
|
|
211
|
+
// The viewport a `vh` resolves against is the window's, not the
|
|
212
|
+
// document's — a document taller than the window does not make `100vh`
|
|
213
|
+
// taller with it.
|
|
214
|
+
const root = this.root;
|
|
215
|
+
const height = root?.abs?.height;
|
|
216
|
+
return height && height > 0 ? height : 600;
|
|
217
|
+
}
|
|
218
|
+
_fonts() {
|
|
219
|
+
const fonts = this.app?.fonts;
|
|
220
|
+
return fonts ?? null;
|
|
221
|
+
}
|
|
222
|
+
/** Bring the pipeline up to date for a width. */
|
|
223
|
+
_prepare(width) {
|
|
224
|
+
const target = Math.max(1, Math.floor(width));
|
|
225
|
+
const props = this._props();
|
|
226
|
+
if ((props.domRevision ?? 0) !== this._reportedDomRevision) {
|
|
227
|
+
this._reportedDomRevision = props.domRevision ?? 0;
|
|
228
|
+
this._source.touch();
|
|
229
|
+
this._sweep();
|
|
230
|
+
if (this._stale < Stale.Style)
|
|
231
|
+
this._stale = Stale.Style;
|
|
232
|
+
}
|
|
233
|
+
if (this._stale === Stale.Nothing && this._laidOutAt === target)
|
|
234
|
+
return;
|
|
235
|
+
if (this._stale >= Stale.Style || !this._cascade) {
|
|
236
|
+
this._restyle(target);
|
|
237
|
+
this._stale = Math.max(this._stale, Stale.Boxes);
|
|
238
|
+
}
|
|
239
|
+
else if (this._cascade.mediaBand(target) !== this._mediaBand) {
|
|
240
|
+
// A resize that crossed a `@media` breakpoint is the one resize that
|
|
241
|
+
// does have to restyle. Knowing which resizes those are is why the
|
|
242
|
+
// breakpoints are collected at parse time.
|
|
243
|
+
this._restyle(target);
|
|
244
|
+
this._stale = Math.max(this._stale, Stale.Boxes);
|
|
245
|
+
}
|
|
246
|
+
const cascade = this._cascade;
|
|
247
|
+
if (!cascade)
|
|
248
|
+
return;
|
|
249
|
+
cascade.viewportWidth = target;
|
|
250
|
+
cascade.viewportHeight = this._viewportHeight();
|
|
251
|
+
if (this._stale >= Stale.Boxes || !this._tree) {
|
|
252
|
+
const props = this._props();
|
|
253
|
+
this._tree = buildBoxes(this._source.document, {
|
|
254
|
+
cascade,
|
|
255
|
+
imageSize: (el) => this._resources.imageSize(attr(el, 'src') ?? ''),
|
|
256
|
+
controlSize: (el, kind, style) => measureControl(el, kind, style, this._fonts(), props.look),
|
|
257
|
+
});
|
|
258
|
+
this._textPoints = null;
|
|
259
|
+
this._pointsAreUnits = null;
|
|
260
|
+
this._laidOutAt = -1;
|
|
261
|
+
}
|
|
262
|
+
if (this._tree &&
|
|
263
|
+
(this._laidOutAt !== target || this._stale >= Stale.Layout)) {
|
|
264
|
+
const result = layoutDocument(this._tree, this._fonts(), target, this._viewportHeight());
|
|
265
|
+
this._documentWidth = result.width;
|
|
266
|
+
this._documentHeight = result.height;
|
|
267
|
+
this._laidOutAt = target;
|
|
268
|
+
this._reportControls();
|
|
269
|
+
}
|
|
270
|
+
this._stale = Stale.Nothing;
|
|
271
|
+
}
|
|
272
|
+
_reportControls() {
|
|
273
|
+
const tree = this._tree;
|
|
274
|
+
const report = this._props().onControls;
|
|
275
|
+
if (!tree || !report)
|
|
276
|
+
return;
|
|
277
|
+
const rects = controlRectsOf(tree);
|
|
278
|
+
if (sameRects(rects, this._controls))
|
|
279
|
+
return;
|
|
280
|
+
this._controls = rects;
|
|
281
|
+
report(rects);
|
|
282
|
+
}
|
|
283
|
+
// --- core's questions -----------------------------------------------------
|
|
284
|
+
/**
|
|
285
|
+
* The size the document comes to at the offered width.
|
|
286
|
+
*
|
|
287
|
+
* The element sizes to its content and the application scrolls it — a
|
|
288
|
+
* `<box overflow="scroll">` around it, the same shape `<Markdown>` uses.
|
|
289
|
+
* That keeps the form controls mounted beside it scrolling with it for
|
|
290
|
+
* free, and core's scroller already blits. Virtualizing a document taller
|
|
291
|
+
* than X11's 16-bit coordinate space is the phase-2 work; see the PRD.
|
|
292
|
+
*/
|
|
293
|
+
measureContent({ width }) {
|
|
294
|
+
const offered = Number.isFinite(width) ? width : 800;
|
|
295
|
+
this._prepare(offered);
|
|
296
|
+
return {
|
|
297
|
+
width: Math.ceil(Math.min(this._documentWidth, offered)),
|
|
298
|
+
height: Math.ceil(this._documentHeight),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
applyProps(nextProps, prevProps) {
|
|
302
|
+
super.applyProps(nextProps, prevProps);
|
|
303
|
+
const next = nextProps;
|
|
304
|
+
const prev = prevProps;
|
|
305
|
+
if (next.look !== prev.look || next.stylesheet !== prev.stylesheet) {
|
|
306
|
+
this._invalidate(Stale.Style);
|
|
307
|
+
}
|
|
308
|
+
if (next.source !== prev.source || next.complete !== prev.complete) {
|
|
309
|
+
this._read();
|
|
310
|
+
}
|
|
311
|
+
else if ((next.domRevision ?? 0) !== (prev.domRevision ?? 0)) {
|
|
312
|
+
this._invalidate(Stale.Style);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
destroySubtree() {
|
|
316
|
+
this._resources.destroy();
|
|
317
|
+
this._source.destroy();
|
|
318
|
+
this._tree = null;
|
|
319
|
+
this._cascade = null;
|
|
320
|
+
super.destroySubtree();
|
|
321
|
+
}
|
|
322
|
+
// --- answering for our own text -------------------------------------------
|
|
323
|
+
//
|
|
324
|
+
// The four accessors from react-x11#291, over the whole document at once.
|
|
325
|
+
// A single element answering for every paragraph is what makes a drag from
|
|
326
|
+
// the first heading to the last table cell one contiguous selection with no
|
|
327
|
+
// per-block plumbing — and it is only possible because the box tree already
|
|
328
|
+
// gave every piece of text its slice of one index.
|
|
329
|
+
//
|
|
330
|
+
// Core counts in **code points**; the boxes count in code units, because
|
|
331
|
+
// that is what ntk's run geometry speaks. The conversion is here, once.
|
|
332
|
+
textContent() {
|
|
333
|
+
return this._tree?.text ?? '';
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Whether the document's code-point and code-unit indices coincide.
|
|
337
|
+
*
|
|
338
|
+
* They differ only where the text carries surrogate pairs (code points
|
|
339
|
+
* past U+FFFF — emoji, mostly), and the offsets table that converts
|
|
340
|
+
* between them costs O(text): tens of milliseconds and a table entry per
|
|
341
|
+
* character on a megabyte-scale document, rebuilt on every DOM change.
|
|
342
|
+
* A regex scan answers "are there any" in a fraction of that, with no
|
|
343
|
+
* allocation, so the common all-BMP document never builds the table.
|
|
344
|
+
*/
|
|
345
|
+
_identityIndex() {
|
|
346
|
+
if (this._pointsAreUnits === null) {
|
|
347
|
+
this._pointsAreUnits = !/[\uD800-\uDFFF]/.test(this.textContent());
|
|
348
|
+
}
|
|
349
|
+
return this._pointsAreUnits;
|
|
350
|
+
}
|
|
351
|
+
_points() {
|
|
352
|
+
if (!this._textPoints)
|
|
353
|
+
this._textPoints = codeUnitOffsets(this.textContent());
|
|
354
|
+
return this._textPoints;
|
|
355
|
+
}
|
|
356
|
+
_toUnits(codePoint) {
|
|
357
|
+
if (this._identityIndex()) {
|
|
358
|
+
return Math.max(0, Math.min(codePoint, this.textContent().length));
|
|
359
|
+
}
|
|
360
|
+
const offsets = this._points();
|
|
361
|
+
const at = Math.max(0, Math.min(codePoint, offsets.length - 1));
|
|
362
|
+
return offsets[at];
|
|
363
|
+
}
|
|
364
|
+
_toPoints(codeUnit) {
|
|
365
|
+
if (this._identityIndex()) {
|
|
366
|
+
return Math.max(0, Math.min(codeUnit, this.textContent().length));
|
|
367
|
+
}
|
|
368
|
+
return codePointAtOffset(this._points(), codeUnit);
|
|
369
|
+
}
|
|
370
|
+
textIndexAt(x, y) {
|
|
371
|
+
const tree = this._tree;
|
|
372
|
+
if (!tree)
|
|
373
|
+
return 0;
|
|
374
|
+
const local = this._toDocument(x, y);
|
|
375
|
+
const hit = nearestText(tree.root, local.x, local.y);
|
|
376
|
+
if (!hit)
|
|
377
|
+
return 0;
|
|
378
|
+
return this._toPoints(hit);
|
|
379
|
+
}
|
|
380
|
+
textCaretRect(index) {
|
|
381
|
+
const tree = this._tree;
|
|
382
|
+
if (!tree)
|
|
383
|
+
return null;
|
|
384
|
+
const units = this._toUnits(index);
|
|
385
|
+
const found = caretAt(tree.root, units);
|
|
386
|
+
if (!found)
|
|
387
|
+
return null;
|
|
388
|
+
return {
|
|
389
|
+
x: this.abs.x + found.x,
|
|
390
|
+
y: this.abs.y + found.y,
|
|
391
|
+
width: 0,
|
|
392
|
+
height: found.height,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
textRangeRects(start, end) {
|
|
396
|
+
const tree = this._tree;
|
|
397
|
+
if (!tree)
|
|
398
|
+
return [];
|
|
399
|
+
const from = this._toUnits(start);
|
|
400
|
+
const to = this._toUnits(end);
|
|
401
|
+
if (to <= from)
|
|
402
|
+
return [];
|
|
403
|
+
const out = [];
|
|
404
|
+
collectBands(tree.root, from, to, this.abs.x, this.abs.y, out);
|
|
405
|
+
return out;
|
|
406
|
+
}
|
|
407
|
+
// --- pointer --------------------------------------------------------------
|
|
408
|
+
/** The link under a point, if any. Not part of the selection seam: core
|
|
409
|
+
* deliberately left hover and `cursorAt` out of #291, so following a link
|
|
410
|
+
* stays this package's. */
|
|
411
|
+
hrefAtPoint(x, y) {
|
|
412
|
+
const el = this.elementAtPoint(x, y);
|
|
413
|
+
let node = el;
|
|
414
|
+
while (node) {
|
|
415
|
+
const href = attr(node, 'href');
|
|
416
|
+
if (href && (tagOf(node) === 'a' || tagOf(node) === 'area'))
|
|
417
|
+
return href;
|
|
418
|
+
node = isElement(node.parent) ? node.parent : null;
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
/** The deepest element whose box contains a window-space point. */
|
|
423
|
+
elementAtPoint(x, y) {
|
|
424
|
+
const tree = this._tree;
|
|
425
|
+
if (!tree)
|
|
426
|
+
return null;
|
|
427
|
+
const local = this._toDocument(x, y);
|
|
428
|
+
return deepestAt(tree.root, local.x, local.y);
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* The pointer moved. Returns true when the cascade's answer could have
|
|
432
|
+
* changed, so the caller knows whether to invalidate — which it only ever
|
|
433
|
+
* does for a document that actually contains a `:hover` rule.
|
|
434
|
+
*/
|
|
435
|
+
setHover(x, y) {
|
|
436
|
+
const cascade = this._cascade;
|
|
437
|
+
if (!cascade || !cascade.hoverSensitive)
|
|
438
|
+
return false;
|
|
439
|
+
const chain = [];
|
|
440
|
+
let node = this.elementAtPoint(x, y);
|
|
441
|
+
while (node) {
|
|
442
|
+
chain.push(node);
|
|
443
|
+
node = isElement(node.parent) ? node.parent : null;
|
|
444
|
+
}
|
|
445
|
+
if (sameChain(chain, this._hovered))
|
|
446
|
+
return false;
|
|
447
|
+
this._hovered = chain;
|
|
448
|
+
cascade.setPointer({ hovered: new Set(chain), active: EMPTY_SET });
|
|
449
|
+
this._invalidate(Stale.Boxes);
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
clearHover() {
|
|
453
|
+
if (!this._hovered.length)
|
|
454
|
+
return false;
|
|
455
|
+
this._hovered = [];
|
|
456
|
+
this._cascade?.setPointer({ hovered: new Set(), active: EMPTY_SET });
|
|
457
|
+
this._invalidate(Stale.Boxes);
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
/** The document, for an application that wants to read or change it. */
|
|
461
|
+
get document() {
|
|
462
|
+
return this._source.document;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* An application changed the DOM under us. Restyles, re-lays-out and
|
|
466
|
+
* repaints — everything but the parse, which nothing that happened to the
|
|
467
|
+
* tree can invalidate.
|
|
468
|
+
*
|
|
469
|
+
* Explicit rather than observed: see `HtmlHandle.refresh`.
|
|
470
|
+
*/
|
|
471
|
+
touchDocument() {
|
|
472
|
+
this._source.touch();
|
|
473
|
+
this._sweep();
|
|
474
|
+
this._invalidate(Stale.Style);
|
|
475
|
+
}
|
|
476
|
+
/** The document's `<title>`, when it had one. */
|
|
477
|
+
get title() {
|
|
478
|
+
return this._source.facts().title;
|
|
479
|
+
}
|
|
480
|
+
_toDocument(x, y) {
|
|
481
|
+
return { x: x - this.abs.x, y: y - this.abs.y };
|
|
482
|
+
}
|
|
483
|
+
// --- pointer defaults -----------------------------------------------------
|
|
484
|
+
//
|
|
485
|
+
// `:hover` is wired at the element rather than through React: the cascade
|
|
486
|
+
// already knows whether any rule in the document tests it, `setHover`
|
|
487
|
+
// returns without work when none does, and a document that does use it
|
|
488
|
+
// re-styles only when the hovered chain actually changed. The restyle is
|
|
489
|
+
// still document-wide — narrowing it to the affected subtree is the
|
|
490
|
+
// phase-2 item the PRD records.
|
|
491
|
+
defaultMouseMove(ev) {
|
|
492
|
+
super.defaultMouseMove?.(ev);
|
|
493
|
+
this.setHover(ev.x, ev.y);
|
|
494
|
+
}
|
|
495
|
+
defaultMouseLeave(ev) {
|
|
496
|
+
super.defaultMouseLeave?.(ev);
|
|
497
|
+
this.clearHover();
|
|
498
|
+
}
|
|
499
|
+
// --- paint ----------------------------------------------------------------
|
|
500
|
+
paint(ctx) {
|
|
501
|
+
super.paint(ctx); // background, border, clip to `abs`
|
|
502
|
+
this._prepare(this.abs.width || 1);
|
|
503
|
+
const tree = this._tree;
|
|
504
|
+
if (!tree)
|
|
505
|
+
return;
|
|
506
|
+
const range = this.selectionRange;
|
|
507
|
+
// Culling against the damage is what makes an expose of a strip cost the
|
|
508
|
+
// strip rather than the document. `paintDamage()` is null when the whole
|
|
509
|
+
// window is being repainted — but "the whole window" still bounds the
|
|
510
|
+
// paint, and the bound is load-bearing rather than an optimization: X
|
|
511
|
+
// carries glyph positions as Int16, so a document taller than ±32767
|
|
512
|
+
// *thrown to the server unculled* dies in the protocol encoder, not on
|
|
513
|
+
// the screen. The window node's rect is the tightest thing always known.
|
|
514
|
+
let damage = this.paintDamage();
|
|
515
|
+
if (!damage) {
|
|
516
|
+
const window = this.root?.abs;
|
|
517
|
+
if (window && window.height > 0) {
|
|
518
|
+
damage = { x: 0, y: 0, width: window.width, height: window.height };
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
paintDocument(ctx, tree, {
|
|
522
|
+
originX: this.abs.x,
|
|
523
|
+
originY: this.abs.y,
|
|
524
|
+
damage,
|
|
525
|
+
selection: range
|
|
526
|
+
? { start: this._toUnits(range.start), end: this._toUnits(range.end) }
|
|
527
|
+
: null,
|
|
528
|
+
selectionColor: this.selectionColor,
|
|
529
|
+
imageFor: (box) => box.el ? this._resources.image(attr(box.el, 'src') ?? '') : null,
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
const EMPTY_SET = new Set();
|
|
534
|
+
function textOf(el) {
|
|
535
|
+
let out = '';
|
|
536
|
+
for (const child of el.children) {
|
|
537
|
+
if (child.type === 'text')
|
|
538
|
+
out += child.data;
|
|
539
|
+
}
|
|
540
|
+
return out;
|
|
541
|
+
}
|
|
542
|
+
function sameChain(a, b) {
|
|
543
|
+
if (a.length !== b.length)
|
|
544
|
+
return false;
|
|
545
|
+
for (let i = 0; i < a.length; i += 1)
|
|
546
|
+
if (a[i] !== b[i])
|
|
547
|
+
return false;
|
|
548
|
+
return true;
|
|
549
|
+
}
|
|
550
|
+
function sameRects(a, b) {
|
|
551
|
+
if (a.length !== b.length)
|
|
552
|
+
return false;
|
|
553
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
554
|
+
const p = a[i];
|
|
555
|
+
const q = b[i];
|
|
556
|
+
if (p.element !== q.element ||
|
|
557
|
+
p.x !== q.x ||
|
|
558
|
+
p.y !== q.y ||
|
|
559
|
+
p.width !== q.width ||
|
|
560
|
+
p.height !== q.height) {
|
|
561
|
+
return false;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
// --- walks over the laid-out tree -------------------------------------------
|
|
567
|
+
/** Distance from a coordinate to an interval, zero inside it. */
|
|
568
|
+
function axisDistance(v, lo, span) {
|
|
569
|
+
return v < lo ? lo - v : v > lo + span ? v - (lo + span) : 0;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* The code-unit offset nearest a document-space point.
|
|
573
|
+
*
|
|
574
|
+
* Two prunes keep this the viewport's cost rather than the document's — it
|
|
575
|
+
* runs per pointer event during a selection drag, where an unpruned walk of
|
|
576
|
+
* a big document measured in the tens of milliseconds *per move*:
|
|
577
|
+
*
|
|
578
|
+
* - a subtree whose ink bounds cannot beat the best distance found so far
|
|
579
|
+
* is skipped whole (the metric `dy·4 + dx` is monotone in both axis
|
|
580
|
+
* distances, so the bounds give an exact lower bound);
|
|
581
|
+
* - within a box, lines are y-sorted, so the candidates are found by
|
|
582
|
+
* binary search and the scan stops the moment vertical distance alone
|
|
583
|
+
* rules a line out.
|
|
584
|
+
*/
|
|
585
|
+
function nearestText(box, x, y) {
|
|
586
|
+
let best = null;
|
|
587
|
+
let bestDistance = Infinity;
|
|
588
|
+
const tryLine = (line) => {
|
|
589
|
+
const dy = axisDistance(y, line.y, line.height);
|
|
590
|
+
for (const text of line.texts) {
|
|
591
|
+
const natural = text.layout.lines[text.layoutLine];
|
|
592
|
+
if (!natural)
|
|
593
|
+
continue;
|
|
594
|
+
const left = text.drawX + natural.x;
|
|
595
|
+
const dx = axisDistance(x, left, natural.width);
|
|
596
|
+
const distance = dy * 4 + dx;
|
|
597
|
+
if (distance >= bestDistance)
|
|
598
|
+
continue;
|
|
599
|
+
bestDistance = distance;
|
|
600
|
+
const local = text.layout.indexAt(x - text.drawX, y - text.drawY);
|
|
601
|
+
const offsets = layoutOffsetsOf(text.layout);
|
|
602
|
+
const units = offsets.length
|
|
603
|
+
? offsets[Math.max(0, Math.min(local, offsets.length - 1))]
|
|
604
|
+
: local;
|
|
605
|
+
best = text.textStart + Math.max(0, units - text.layoutStart);
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
const visit = (node) => {
|
|
609
|
+
const boundsDistance = axisDistance(y, node.boundsY, node.boundsHeight) * 4 +
|
|
610
|
+
axisDistance(x, node.boundsX, node.boundsWidth);
|
|
611
|
+
if (boundsDistance >= bestDistance)
|
|
612
|
+
return;
|
|
613
|
+
const lines = node.lines;
|
|
614
|
+
if (lines?.length) {
|
|
615
|
+
// The line nearest in y, by binary search; then outward both ways
|
|
616
|
+
// while vertical distance alone could still beat the best.
|
|
617
|
+
let lo = 0;
|
|
618
|
+
let hi = lines.length;
|
|
619
|
+
while (lo < hi) {
|
|
620
|
+
const mid = (lo + hi) >> 1;
|
|
621
|
+
if (lines[mid].y > y)
|
|
622
|
+
hi = mid;
|
|
623
|
+
else
|
|
624
|
+
lo = mid + 1;
|
|
625
|
+
}
|
|
626
|
+
for (let i = lo - 1; i >= 0; i -= 1) {
|
|
627
|
+
if (axisDistance(y, lines[i].y, lines[i].height) * 4 >= bestDistance)
|
|
628
|
+
break;
|
|
629
|
+
tryLine(lines[i]);
|
|
630
|
+
}
|
|
631
|
+
for (let i = lo; i < lines.length; i += 1) {
|
|
632
|
+
if (axisDistance(y, lines[i].y, lines[i].height) * 4 >= bestDistance)
|
|
633
|
+
break;
|
|
634
|
+
tryLine(lines[i]);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
// Atomics are ordinary children of the box, so the child walk below
|
|
638
|
+
// reaches them; a per-line atomics pass would visit each twice.
|
|
639
|
+
//
|
|
640
|
+
// A wide child list goes through the sorted index, outward from the
|
|
641
|
+
// pointer's y — the bounds prune alone still *visits* every child to
|
|
642
|
+
// reject it, and twenty thousand rejections per pointer move is the
|
|
643
|
+
// cost being avoided. The expansion stops the moment vertical distance
|
|
644
|
+
// alone cannot beat the best hit.
|
|
645
|
+
const index = node.paintIndex;
|
|
646
|
+
if (index) {
|
|
647
|
+
const sorted = index.boxes;
|
|
648
|
+
let lo = 0;
|
|
649
|
+
let hi = sorted.length;
|
|
650
|
+
while (lo < hi) {
|
|
651
|
+
const mid = (lo + hi) >> 1;
|
|
652
|
+
if (sorted[mid].boundsY > y)
|
|
653
|
+
hi = mid;
|
|
654
|
+
else
|
|
655
|
+
lo = mid + 1;
|
|
656
|
+
}
|
|
657
|
+
for (let i = lo - 1; i >= 0; i -= 1) {
|
|
658
|
+
const child = sorted[i];
|
|
659
|
+
if (axisDistance(y, child.boundsY, child.boundsHeight) * 4 >=
|
|
660
|
+
bestDistance)
|
|
661
|
+
break;
|
|
662
|
+
visit(child);
|
|
663
|
+
}
|
|
664
|
+
for (let i = lo; i < sorted.length; i += 1) {
|
|
665
|
+
const child = sorted[i];
|
|
666
|
+
if (axisDistance(y, child.boundsY, child.boundsHeight) * 4 >=
|
|
667
|
+
bestDistance)
|
|
668
|
+
break;
|
|
669
|
+
visit(child);
|
|
670
|
+
}
|
|
671
|
+
if (node.positionedPaint) {
|
|
672
|
+
for (const child of node.positionedPaint)
|
|
673
|
+
visit(child);
|
|
674
|
+
}
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
for (const child of node.children) {
|
|
678
|
+
if (child.kind === 'text' || child.kind === 'break')
|
|
679
|
+
continue;
|
|
680
|
+
visit(child);
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
visit(box);
|
|
684
|
+
return best;
|
|
685
|
+
}
|
|
686
|
+
/** Where a caret at a code-unit offset stands, in document coordinates.
|
|
687
|
+
* Subtrees whose text range cannot hold the offset are skipped whole, so
|
|
688
|
+
* the walk is the path to one paragraph, not the document. */
|
|
689
|
+
function caretAt(box, units) {
|
|
690
|
+
let found = null;
|
|
691
|
+
const visit = (node) => {
|
|
692
|
+
if (found)
|
|
693
|
+
return;
|
|
694
|
+
if (node.subtreeTextEnd <= node.subtreeTextStart)
|
|
695
|
+
return;
|
|
696
|
+
if (units < node.subtreeTextStart || units > node.subtreeTextEnd)
|
|
697
|
+
return;
|
|
698
|
+
const lines = node.lines;
|
|
699
|
+
if (lines?.length) {
|
|
700
|
+
// Lines are in document order, so their text starts are sorted:
|
|
701
|
+
// binary search the last line starting at or before the offset.
|
|
702
|
+
let lo = 0;
|
|
703
|
+
let hi = lines.length;
|
|
704
|
+
while (lo < hi) {
|
|
705
|
+
const mid = (lo + hi) >> 1;
|
|
706
|
+
if (lines[mid].textStart > units)
|
|
707
|
+
hi = mid;
|
|
708
|
+
else
|
|
709
|
+
lo = mid + 1;
|
|
710
|
+
}
|
|
711
|
+
for (let i = Math.max(0, lo - 1); i < lines.length; i += 1) {
|
|
712
|
+
const line = lines[i];
|
|
713
|
+
if (line.textStart > units)
|
|
714
|
+
break;
|
|
715
|
+
for (const text of line.texts) {
|
|
716
|
+
if (units < text.textStart || units > text.textEnd)
|
|
717
|
+
continue;
|
|
718
|
+
const offsets = layoutOffsetsOf(text.layout);
|
|
719
|
+
const layoutUnits = text.layoutStart + (units - text.textStart);
|
|
720
|
+
const caret = text.layout.caretPosition(codePointAtOffset(offsets, layoutUnits));
|
|
721
|
+
found = { x: text.drawX + caret.x, y: line.y, height: line.height };
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
for (const child of node.children) {
|
|
727
|
+
if (child.kind === 'text' || child.kind === 'break')
|
|
728
|
+
continue;
|
|
729
|
+
visit(child);
|
|
730
|
+
if (found)
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
visit(box);
|
|
735
|
+
return found;
|
|
736
|
+
}
|
|
737
|
+
/** Every band a document range covers, in window coordinates. The subtree
|
|
738
|
+
* text ranges prune the walk to the boxes the range actually crosses, so a
|
|
739
|
+
* drag's small range costs its own paragraphs; only Ctrl+A pays for all. */
|
|
740
|
+
function collectBands(box, from, to, dx, dy, out) {
|
|
741
|
+
if (box.subtreeTextEnd <= box.subtreeTextStart)
|
|
742
|
+
return;
|
|
743
|
+
if (box.subtreeTextEnd <= from || box.subtreeTextStart >= to)
|
|
744
|
+
return;
|
|
745
|
+
if (box.lines) {
|
|
746
|
+
const lines = box.lines;
|
|
747
|
+
// First line whose text can reach `from`, by binary search over the
|
|
748
|
+
// sorted text starts; stop at the first line past `to`.
|
|
749
|
+
let lo = 0;
|
|
750
|
+
let hi = lines.length;
|
|
751
|
+
while (lo < hi) {
|
|
752
|
+
const mid = (lo + hi) >> 1;
|
|
753
|
+
if (lines[mid].textEnd > from)
|
|
754
|
+
hi = mid;
|
|
755
|
+
else
|
|
756
|
+
lo = mid + 1;
|
|
757
|
+
}
|
|
758
|
+
for (let i = lo; i < lines.length; i += 1) {
|
|
759
|
+
const line = lines[i];
|
|
760
|
+
if (line.textStart >= to)
|
|
761
|
+
break;
|
|
762
|
+
if (line.textEnd > from && line.textStart < to) {
|
|
763
|
+
for (const text of line.texts) {
|
|
764
|
+
const natural = text.layout.lines[text.layoutLine];
|
|
765
|
+
if (!natural)
|
|
766
|
+
continue;
|
|
767
|
+
const a = Math.max(from, text.textStart);
|
|
768
|
+
const b = Math.min(to, text.textEnd);
|
|
769
|
+
if (b <= a)
|
|
770
|
+
continue;
|
|
771
|
+
const offsets = layoutOffsetsOf(text.layout);
|
|
772
|
+
for (const band of bandsFor(text.layout, natural, offsets, text.layoutStart + (a - text.textStart), text.layoutStart + (b - text.textStart))) {
|
|
773
|
+
out.push({
|
|
774
|
+
x: dx + band.x + text.drawX,
|
|
775
|
+
y: dy + line.y,
|
|
776
|
+
width: band.width,
|
|
777
|
+
height: line.height,
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
// Atomics are ordinary children, reached below.
|
|
785
|
+
for (const child of box.children) {
|
|
786
|
+
if (child.kind === 'text' || child.kind === 'break')
|
|
787
|
+
continue;
|
|
788
|
+
collectBands(child, from, to, dx, dy, out);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
/** The deepest element box containing a document-space point. */
|
|
792
|
+
function deepestAt(box, x, y) {
|
|
793
|
+
let found = box.el;
|
|
794
|
+
const visit = (node) => {
|
|
795
|
+
// The paint index answers a point query too — the wide level of a flat
|
|
796
|
+
// document is the root's child list, and a hit test that walked all of
|
|
797
|
+
// it would run per pointer move once hover is in the picture.
|
|
798
|
+
const candidates = node.paintIndex
|
|
799
|
+
? queryChildIndex(node.paintIndex, y, y + 1)
|
|
800
|
+
: node.children;
|
|
801
|
+
for (const child of candidates) {
|
|
802
|
+
if (child.kind === 'text' || child.kind === 'break')
|
|
803
|
+
continue;
|
|
804
|
+
if (x >= child.x &&
|
|
805
|
+
x < child.x + child.width &&
|
|
806
|
+
y >= child.y &&
|
|
807
|
+
y < child.y + child.height) {
|
|
808
|
+
if (child.el)
|
|
809
|
+
found = child.el;
|
|
810
|
+
visit(child);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
if (node.paintIndex && node.positionedPaint) {
|
|
814
|
+
for (const child of node.positionedPaint) {
|
|
815
|
+
if (x >= child.x &&
|
|
816
|
+
x < child.x + child.width &&
|
|
817
|
+
y >= child.y &&
|
|
818
|
+
y < child.y + child.height) {
|
|
819
|
+
if (child.el)
|
|
820
|
+
found = child.el;
|
|
821
|
+
visit(child);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
if (node.lines) {
|
|
826
|
+
for (const line of node.lines) {
|
|
827
|
+
for (const placed of line.atomics) {
|
|
828
|
+
if (x >= placed.box.x &&
|
|
829
|
+
x < placed.box.x + placed.box.width &&
|
|
830
|
+
y >= placed.box.y &&
|
|
831
|
+
y < placed.box.y + placed.box.height) {
|
|
832
|
+
if (placed.box.el)
|
|
833
|
+
found = placed.box.el;
|
|
834
|
+
visit(placed.box);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
// An inline box has no box of its own — its extent is the runs on
|
|
838
|
+
// this line — so the element under a point inside a paragraph is
|
|
839
|
+
// found from the run rather than from a rectangle.
|
|
840
|
+
if (y >= line.y && y < line.y + line.height) {
|
|
841
|
+
for (const text of line.texts) {
|
|
842
|
+
const natural = text.layout.lines[text.layoutLine];
|
|
843
|
+
if (!natural)
|
|
844
|
+
continue;
|
|
845
|
+
for (const run of natural.runs) {
|
|
846
|
+
const left = text.drawX + natural.x + run.x;
|
|
847
|
+
if (x >= left && x < left + run.width) {
|
|
848
|
+
const owner = run.span.element;
|
|
849
|
+
if (owner)
|
|
850
|
+
found = owner;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
visit(box);
|
|
859
|
+
return found;
|
|
860
|
+
}
|
|
861
|
+
//# sourceMappingURL=node.js.map
|