@react-x11/components 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -4
- package/dist/charts/node.d.ts +11 -1
- package/dist/charts/node.d.ts.map +1 -1
- package/dist/charts/node.js +44 -14
- package/dist/charts/node.js.map +1 -1
- package/dist/charts/render.d.ts +12 -3
- package/dist/charts/render.d.ts.map +1 -1
- package/dist/charts/render.js +94 -25
- package/dist/charts/render.js.map +1 -1
- package/dist/code/index.d.ts.map +1 -1
- package/dist/code/index.js +3 -1
- package/dist/code/index.js.map +1 -1
- package/dist/code-editor/completion.d.ts.map +1 -1
- package/dist/code-editor/completion.js +3 -2
- package/dist/code-editor/completion.js.map +1 -1
- package/dist/code-editor/index.d.ts.map +1 -1
- package/dist/code-editor/index.js +19 -0
- package/dist/code-editor/index.js.map +1 -1
- package/dist/code-editor/node.d.ts +177 -7
- package/dist/code-editor/node.d.ts.map +1 -1
- package/dist/code-editor/node.js +1329 -164
- package/dist/code-editor/node.js.map +1 -1
- package/dist/code-language/languages/glsl.d.ts.map +1 -1
- package/dist/code-language/languages/glsl.js +10 -2
- package/dist/code-language/languages/glsl.js.map +1 -1
- package/dist/code-language/languages/javascript.d.ts.map +1 -1
- package/dist/code-language/languages/javascript.js +18 -3
- package/dist/code-language/languages/javascript.js.map +1 -1
- package/dist/code-language/languages/json.d.ts.map +1 -1
- package/dist/code-language/languages/json.js +10 -2
- package/dist/code-language/languages/json.js.map +1 -1
- package/dist/code-language/languages/shell.d.ts.map +1 -1
- package/dist/code-language/languages/shell.js +10 -2
- package/dist/code-language/languages/shell.js.map +1 -1
- package/dist/code-language/languages/sql.d.ts.map +1 -1
- package/dist/code-language/languages/sql.js +20 -2
- package/dist/code-language/languages/sql.js.map +1 -1
- package/dist/code-language/stream.d.ts +22 -0
- package/dist/code-language/stream.d.ts.map +1 -1
- package/dist/code-language/stream.js +259 -9
- package/dist/code-language/stream.js.map +1 -1
- package/dist/code-language/types.d.ts +5 -4
- package/dist/code-language/types.d.ts.map +1 -1
- package/dist/codeblock/index.d.ts +13 -2
- package/dist/codeblock/index.d.ts.map +1 -1
- package/dist/codeblock/index.js +20 -3
- package/dist/codeblock/index.js.map +1 -1
- package/dist/flow/draw.d.ts +50 -0
- package/dist/flow/draw.d.ts.map +1 -1
- package/dist/flow/draw.js +132 -33
- package/dist/flow/draw.js.map +1 -1
- package/dist/flow/gl/color.d.ts +13 -0
- package/dist/flow/gl/color.d.ts.map +1 -0
- package/dist/flow/gl/color.js +82 -0
- package/dist/flow/gl/color.js.map +1 -0
- package/dist/flow/gl/index.d.ts +60 -0
- package/dist/flow/gl/index.d.ts.map +1 -0
- package/dist/flow/gl/index.js +283 -0
- package/dist/flow/gl/index.js.map +1 -0
- package/dist/flow/gl/pack.d.ts +133 -0
- package/dist/flow/gl/pack.d.ts.map +1 -0
- package/dist/flow/gl/pack.js +408 -0
- package/dist/flow/gl/pack.js.map +1 -0
- package/dist/flow/gl/renderer.d.ts +95 -0
- package/dist/flow/gl/renderer.d.ts.map +1 -0
- package/dist/flow/gl/renderer.js +459 -0
- package/dist/flow/gl/renderer.js.map +1 -0
- package/dist/flow/gl/shaders.d.ts +79 -0
- package/dist/flow/gl/shaders.d.ts.map +1 -0
- package/dist/flow/gl/shaders.js +346 -0
- package/dist/flow/gl/shaders.js.map +1 -0
- package/dist/flow/gl/text.d.ts +318 -0
- package/dist/flow/gl/text.d.ts.map +1 -0
- package/dist/flow/gl/text.js +1103 -0
- package/dist/flow/gl/text.js.map +1 -0
- package/dist/flow/index.d.ts +1 -1
- package/dist/flow/index.d.ts.map +1 -1
- package/dist/flow/index.js +619 -64
- package/dist/flow/index.js.map +1 -1
- package/dist/flow/node.d.ts +621 -72
- package/dist/flow/node.d.ts.map +1 -1
- package/dist/flow/node.js +2253 -1018
- package/dist/flow/node.js.map +1 -1
- package/dist/flow/paint.d.ts +35 -0
- package/dist/flow/paint.d.ts.map +1 -0
- package/dist/flow/paint.js +393 -0
- package/dist/flow/paint.js.map +1 -0
- package/dist/flow/paths.d.ts +14 -0
- package/dist/flow/paths.d.ts.map +1 -1
- package/dist/flow/paths.js +45 -19
- package/dist/flow/paths.js.map +1 -1
- package/dist/flow/scene.d.ts +584 -0
- package/dist/flow/scene.d.ts.map +1 -0
- package/dist/flow/scene.js +1453 -0
- package/dist/flow/scene.js.map +1 -0
- package/dist/flow/types.d.ts +111 -1
- package/dist/flow/types.d.ts.map +1 -1
- package/dist/html/controls.d.ts +28 -0
- package/dist/html/controls.d.ts.map +1 -1
- package/dist/html/controls.js +52 -2
- package/dist/html/controls.js.map +1 -1
- package/dist/html/css/calc.d.ts +14 -0
- package/dist/html/css/calc.d.ts.map +1 -0
- package/dist/html/css/calc.js +344 -0
- package/dist/html/css/calc.js.map +1 -0
- package/dist/html/css/cascade.d.ts +240 -6
- package/dist/html/css/cascade.d.ts.map +1 -1
- package/dist/html/css/cascade.js +1327 -66
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/color.d.ts +23 -0
- package/dist/html/css/color.d.ts.map +1 -0
- package/dist/html/css/color.js +740 -0
- package/dist/html/css/color.js.map +1 -0
- package/dist/html/css/content.d.ts +92 -0
- package/dist/html/css/content.d.ts.map +1 -0
- package/dist/html/css/content.js +388 -0
- package/dist/html/css/content.js.map +1 -0
- package/dist/html/css/counter-styles.d.ts +76 -0
- package/dist/html/css/counter-styles.d.ts.map +1 -0
- package/dist/html/css/counter-styles.js +893 -0
- package/dist/html/css/counter-styles.js.map +1 -0
- package/dist/html/css/decode.d.ts +12 -0
- package/dist/html/css/decode.d.ts.map +1 -0
- package/dist/html/css/decode.js +116 -0
- package/dist/html/css/decode.js.map +1 -0
- package/dist/html/css/parse.d.ts +110 -10
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +1473 -180
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/style.d.ts +498 -15
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +3698 -206
- package/dist/html/css/style.js.map +1 -1
- package/dist/html/css/ua.d.ts.map +1 -1
- package/dist/html/css/ua.js +57 -11
- package/dist/html/css/ua.js.map +1 -1
- package/dist/html/css/values.d.ts +37 -3
- package/dist/html/css/values.d.ts.map +1 -1
- package/dist/html/css/values.js +122 -48
- package/dist/html/css/values.js.map +1 -1
- package/dist/html/css/vars.d.ts +52 -0
- package/dist/html/css/vars.d.ts.map +1 -0
- package/dist/html/css/vars.js +358 -0
- package/dist/html/css/vars.js.map +1 -0
- package/dist/html/dom.d.ts +30 -4
- package/dist/html/dom.d.ts.map +1 -1
- package/dist/html/dom.js +278 -17
- package/dist/html/dom.js.map +1 -1
- package/dist/html/fonts.d.ts +106 -0
- package/dist/html/fonts.d.ts.map +1 -0
- package/dist/html/fonts.js +565 -0
- package/dist/html/fonts.js.map +1 -0
- package/dist/html/gif.d.ts +15 -0
- package/dist/html/gif.d.ts.map +1 -0
- package/dist/html/gif.js +229 -0
- package/dist/html/gif.js.map +1 -0
- package/dist/html/index.d.ts +50 -11
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +115 -9
- package/dist/html/index.js.map +1 -1
- package/dist/html/layout/block.d.ts +226 -3
- package/dist/html/layout/block.d.ts.map +1 -1
- package/dist/html/layout/block.js +2937 -197
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +340 -17
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +1714 -182
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/cache.d.ts +58 -0
- package/dist/html/layout/cache.d.ts.map +1 -0
- package/dist/html/layout/cache.js +224 -0
- package/dist/html/layout/cache.js.map +1 -0
- package/dist/html/layout/collapse.d.ts +45 -0
- package/dist/html/layout/collapse.d.ts.map +1 -0
- package/dist/html/layout/collapse.js +246 -0
- package/dist/html/layout/collapse.js.map +1 -0
- package/dist/html/layout/css-grid.d.ts +7 -0
- package/dist/html/layout/css-grid.d.ts.map +1 -0
- package/dist/html/layout/css-grid.js +900 -0
- package/dist/html/layout/css-grid.js.map +1 -0
- package/dist/html/layout/flex.d.ts.map +1 -1
- package/dist/html/layout/flex.js +1025 -89
- package/dist/html/layout/flex.js.map +1 -1
- package/dist/html/layout/floats.d.ts +45 -6
- package/dist/html/layout/floats.d.ts.map +1 -1
- package/dist/html/layout/floats.js +113 -14
- package/dist/html/layout/floats.js.map +1 -1
- package/dist/html/layout/grid-lines.d.ts +39 -0
- package/dist/html/layout/grid-lines.d.ts.map +1 -0
- package/dist/html/layout/grid-lines.js +119 -0
- package/dist/html/layout/grid-lines.js.map +1 -0
- package/dist/html/layout/grid.d.ts +53 -0
- package/dist/html/layout/grid.d.ts.map +1 -0
- package/dist/html/layout/grid.js +153 -0
- package/dist/html/layout/grid.js.map +1 -0
- package/dist/html/layout/inline.d.ts +151 -1
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +3375 -174
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/layout/shaping.d.ts +6 -0
- package/dist/html/layout/shaping.d.ts.map +1 -0
- package/dist/html/layout/shaping.js +100 -0
- package/dist/html/layout/shaping.js.map +1 -0
- package/dist/html/layout/table.d.ts +3 -0
- package/dist/html/layout/table.d.ts.map +1 -1
- package/dist/html/layout/table.js +681 -175
- package/dist/html/layout/table.js.map +1 -1
- package/dist/html/layout/tracks.d.ts +44 -0
- package/dist/html/layout/tracks.d.ts.map +1 -0
- package/dist/html/layout/tracks.js +349 -0
- package/dist/html/layout/tracks.js.map +1 -0
- package/dist/html/node.d.ts +169 -4
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +1331 -100
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts +92 -3
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +3503 -141
- package/dist/html/paint.js.map +1 -1
- package/dist/html/resources.d.ts +60 -14
- package/dist/html/resources.d.ts.map +1 -1
- package/dist/html/resources.js +122 -36
- package/dist/html/resources.js.map +1 -1
- package/dist/html/surfaces.d.ts +23 -0
- package/dist/html/surfaces.d.ts.map +1 -0
- package/dist/html/surfaces.js +68 -0
- package/dist/html/surfaces.js.map +1 -0
- package/dist/html/svg.d.ts +80 -0
- package/dist/html/svg.d.ts.map +1 -0
- package/dist/html/svg.js +435 -0
- package/dist/html/svg.js.map +1 -0
- package/dist/html/url.d.ts +23 -0
- package/dist/html/url.d.ts.map +1 -0
- package/dist/html/url.js +80 -0
- package/dist/html/url.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/collate.d.ts +3 -0
- package/dist/internal/collate.d.ts.map +1 -0
- package/dist/internal/collate.js +11 -0
- package/dist/internal/collate.js.map +1 -0
- package/dist/internal/markdown/ast.d.ts +11 -0
- package/dist/internal/markdown/ast.d.ts.map +1 -1
- package/dist/internal/markdown/parse.d.ts.map +1 -1
- package/dist/internal/markdown/parse.js +109 -8
- package/dist/internal/markdown/parse.js.map +1 -1
- package/dist/internal/prewarm.d.ts +18 -0
- package/dist/internal/prewarm.d.ts.map +1 -0
- package/dist/internal/prewarm.js +42 -0
- package/dist/internal/prewarm.js.map +1 -0
- package/dist/internal/sdf.d.ts +20 -0
- package/dist/internal/sdf.d.ts.map +1 -0
- package/dist/internal/sdf.js +216 -0
- package/dist/internal/sdf.js.map +1 -0
- package/dist/internal/splice.d.ts +12 -0
- package/dist/internal/splice.d.ts.map +1 -0
- package/dist/internal/splice.js +23 -0
- package/dist/internal/splice.js.map +1 -0
- package/dist/internal/window.d.ts +12 -0
- package/dist/internal/window.d.ts.map +1 -1
- package/dist/internal/window.js +23 -6
- package/dist/internal/window.js.map +1 -1
- package/dist/maps/anchors.d.ts +6 -1
- package/dist/maps/anchors.d.ts.map +1 -1
- package/dist/maps/anchors.js +260 -1
- package/dist/maps/anchors.js.map +1 -1
- package/dist/maps/controller.d.ts +57 -0
- package/dist/maps/controller.d.ts.map +1 -1
- package/dist/maps/controller.js +97 -18
- package/dist/maps/controller.js.map +1 -1
- package/dist/maps/gl/buckets.d.ts +5 -1
- package/dist/maps/gl/buckets.d.ts.map +1 -1
- package/dist/maps/gl/buckets.js +5 -2
- package/dist/maps/gl/buckets.js.map +1 -1
- package/dist/maps/gl/build-worker.d.ts +2 -0
- package/dist/maps/gl/build-worker.d.ts.map +1 -1
- package/dist/maps/gl/build-worker.js +1 -1
- package/dist/maps/gl/build-worker.js.map +1 -1
- package/dist/maps/gl/cover.d.ts +23 -4
- package/dist/maps/gl/cover.d.ts.map +1 -1
- package/dist/maps/gl/cover.js +61 -48
- package/dist/maps/gl/cover.js.map +1 -1
- package/dist/maps/gl/placement.d.ts +21 -8
- package/dist/maps/gl/placement.d.ts.map +1 -1
- package/dist/maps/gl/placement.js +133 -58
- package/dist/maps/gl/placement.js.map +1 -1
- package/dist/maps/gl/renderer.d.ts +36 -4
- package/dist/maps/gl/renderer.d.ts.map +1 -1
- package/dist/maps/gl/renderer.js +81 -24
- package/dist/maps/gl/renderer.js.map +1 -1
- package/dist/maps/gl/shaders.d.ts +18 -17
- package/dist/maps/gl/shaders.d.ts.map +1 -1
- package/dist/maps/gl/shaders.js +34 -32
- package/dist/maps/gl/shaders.js.map +1 -1
- package/dist/maps/gl/store.d.ts +10 -0
- package/dist/maps/gl/store.d.ts.map +1 -1
- package/dist/maps/gl/store.js +47 -4
- package/dist/maps/gl/store.js.map +1 -1
- package/dist/maps/gl/text.d.ts +153 -24
- package/dist/maps/gl/text.d.ts.map +1 -1
- package/dist/maps/gl/text.js +379 -63
- package/dist/maps/gl/text.js.map +1 -1
- package/dist/maps/gl/view.d.ts +293 -2
- package/dist/maps/gl/view.d.ts.map +1 -1
- package/dist/maps/gl/view.js +317 -82
- package/dist/maps/gl/view.js.map +1 -1
- package/dist/maps/icons.d.ts +32 -0
- package/dist/maps/icons.d.ts.map +1 -0
- package/dist/maps/icons.js +151 -0
- package/dist/maps/icons.js.map +1 -0
- package/dist/maps/index.d.ts +2 -0
- package/dist/maps/index.d.ts.map +1 -1
- package/dist/maps/index.js +2 -0
- package/dist/maps/index.js.map +1 -1
- package/dist/maps/labels.d.ts +56 -4
- package/dist/maps/labels.d.ts.map +1 -1
- package/dist/maps/labels.js +213 -46
- package/dist/maps/labels.js.map +1 -1
- package/dist/maps/node.d.ts +17 -0
- package/dist/maps/node.d.ts.map +1 -1
- package/dist/maps/node.js +64 -30
- package/dist/maps/node.js.map +1 -1
- package/dist/maps/proj.d.ts +48 -0
- package/dist/maps/proj.d.ts.map +1 -1
- package/dist/maps/proj.js +73 -0
- package/dist/maps/proj.js.map +1 -1
- package/dist/maps/sources.d.ts +5 -3
- package/dist/maps/sources.d.ts.map +1 -1
- package/dist/maps/sources.js +5 -3
- package/dist/maps/sources.js.map +1 -1
- package/dist/maps/style.d.ts +35 -0
- package/dist/maps/style.d.ts.map +1 -1
- package/dist/maps/style.js.map +1 -1
- package/dist/maps/styles.d.ts +12 -0
- package/dist/maps/styles.d.ts.map +1 -1
- package/dist/maps/styles.js +120 -6
- package/dist/maps/styles.js.map +1 -1
- package/dist/maps/tiles.d.ts +31 -11
- package/dist/maps/tiles.d.ts.map +1 -1
- package/dist/maps/tiles.js +61 -27
- package/dist/maps/tiles.js.map +1 -1
- package/dist/maps/types.d.ts +28 -4
- package/dist/maps/types.d.ts.map +1 -1
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +112 -43
- package/dist/markdown/index.js.map +1 -1
- package/dist/markdown/spans.d.ts.map +1 -1
- package/dist/markdown/spans.js +6 -0
- package/dist/markdown/spans.js.map +1 -1
- package/dist/qml/containers.d.ts.map +1 -1
- package/dist/qml/containers.js +6 -1
- package/dist/qml/containers.js.map +1 -1
- package/dist/qml/interaction.d.ts.map +1 -1
- package/dist/qml/interaction.js +38 -5
- package/dist/qml/interaction.js.map +1 -1
- package/dist/qml/layouts.d.ts.map +1 -1
- package/dist/qml/layouts.js +21 -6
- package/dist/qml/layouts.js.map +1 -1
- package/dist/qml/qtquick.d.ts.map +1 -1
- package/dist/qml/qtquick.js +9 -2
- package/dist/qml/qtquick.js.map +1 -1
- package/dist/qml/react.d.ts.map +1 -1
- package/dist/qml/react.js +9 -7
- package/dist/qml/react.js.map +1 -1
- package/dist/reorder/clock.d.ts +7 -0
- package/dist/reorder/clock.d.ts.map +1 -0
- package/dist/reorder/clock.js +26 -0
- package/dist/reorder/clock.js.map +1 -0
- package/dist/reorder/index.d.ts +25 -3
- package/dist/reorder/index.d.ts.map +1 -1
- package/dist/reorder/index.js +64 -19
- package/dist/reorder/index.js.map +1 -1
- package/dist/rich-text-editor/index.d.ts +0 -11
- package/dist/rich-text-editor/index.d.ts.map +1 -1
- package/dist/rich-text-editor/index.js +35 -1
- package/dist/rich-text-editor/index.js.map +1 -1
- package/dist/rich-text-editor/keymap.d.ts.map +1 -1
- package/dist/rich-text-editor/keymap.js +2 -1
- package/dist/rich-text-editor/keymap.js.map +1 -1
- package/dist/rich-text-editor/keys.d.ts +17 -6
- package/dist/rich-text-editor/keys.d.ts.map +1 -1
- package/dist/rich-text-editor/keys.js +135 -26
- package/dist/rich-text-editor/keys.js.map +1 -1
- package/dist/rich-text-editor/marks.d.ts +9 -0
- package/dist/rich-text-editor/marks.d.ts.map +1 -0
- package/dist/rich-text-editor/marks.js +83 -0
- package/dist/rich-text-editor/marks.js.map +1 -0
- package/dist/rich-text-editor/render.d.ts.map +1 -1
- package/dist/rich-text-editor/render.js +28 -10
- package/dist/rich-text-editor/render.js.map +1 -1
- package/dist/rich-text-editor/toolbar.d.ts.map +1 -1
- package/dist/rich-text-editor/toolbar.js +1 -1
- package/dist/rich-text-editor/toolbar.js.map +1 -1
- package/dist/rich-text-editor/virtual.d.ts.map +1 -1
- package/dist/rich-text-editor/virtual.js +17 -0
- package/dist/rich-text-editor/virtual.js.map +1 -1
- package/dist/richtext/node.d.ts +46 -2
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js +187 -4
- package/dist/richtext/node.js.map +1 -1
- package/dist/richtext/runs.d.ts +13 -8
- package/dist/richtext/runs.d.ts.map +1 -1
- package/dist/richtext/runs.js +18 -8
- package/dist/richtext/runs.js.map +1 -1
- package/dist/table/index.d.ts.map +1 -1
- package/dist/table/index.js +23 -0
- package/dist/table/index.js.map +1 -1
- package/dist/table/rows.d.ts +3 -2
- package/dist/table/rows.d.ts.map +1 -1
- package/dist/table/rows.js +20 -6
- package/dist/table/rows.js.map +1 -1
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +4 -0
- package/dist/terminal/index.js.map +1 -1
- package/dist/terminal/vt/pty.d.ts +13 -2
- package/dist/terminal/vt/pty.d.ts.map +1 -1
- package/dist/terminal/vt/pty.js +18 -3
- package/dist/terminal/vt/pty.js.map +1 -1
- package/dist/terminal-output/index.d.ts.map +1 -1
- package/dist/terminal-output/index.js +6 -1
- package/dist/terminal-output/index.js.map +1 -1
- package/dist/three/canvas.d.ts.map +1 -1
- package/dist/three/canvas.js +85 -7
- package/dist/three/canvas.js.map +1 -1
- package/dist/three/events.d.ts +22 -4
- package/dist/three/events.d.ts.map +1 -1
- package/dist/three/events.js +34 -4
- package/dist/three/events.js.map +1 -1
- package/dist/tree/index.d.ts.map +1 -1
- package/dist/tree/index.js +17 -0
- package/dist/tree/index.js.map +1 -1
- package/package.json +42 -33
- package/src/charts/node.ts +62 -26
- package/src/charts/render.ts +120 -30
- package/src/code/index.ts +3 -1
- package/src/code-editor/completion.ts +3 -2
- package/src/code-editor/index.ts +19 -0
- package/src/code-editor/node.ts +1574 -184
- package/src/code-language/languages/glsl.ts +12 -2
- package/src/code-language/languages/javascript.ts +21 -4
- package/src/code-language/languages/json.ts +12 -2
- package/src/code-language/languages/shell.ts +12 -2
- package/src/code-language/languages/sql.ts +22 -2
- package/src/code-language/stream.ts +257 -17
- package/src/code-language/types.ts +5 -4
- package/src/codeblock/index.ts +20 -3
- package/src/flow/draw.ts +167 -41
- package/src/flow/gl/color.ts +85 -0
- package/src/flow/gl/index.ts +342 -0
- package/src/flow/gl/pack.ts +585 -0
- package/src/flow/gl/renderer.ts +679 -0
- package/src/flow/gl/shaders.ts +371 -0
- package/src/flow/gl/text.ts +1295 -0
- package/src/flow/index.ts +794 -67
- package/src/flow/node.ts +2496 -1256
- package/src/flow/paint.ts +511 -0
- package/src/flow/paths.ts +80 -15
- package/src/flow/scene.ts +2199 -0
- package/src/flow/types.ts +113 -1
- package/src/html/controls.ts +73 -2
- package/src/html/css/calc.ts +385 -0
- package/src/html/css/cascade.ts +1403 -62
- package/src/html/css/color.ts +755 -0
- package/src/html/css/content.ts +417 -0
- package/src/html/css/counter-styles.ts +973 -0
- package/src/html/css/decode.ts +130 -0
- package/src/html/css/parse.ts +1514 -160
- package/src/html/css/style.ts +4102 -222
- package/src/html/css/ua.ts +58 -12
- package/src/html/css/values.ts +150 -50
- package/src/html/css/vars.ts +348 -0
- package/src/html/dom.ts +284 -17
- package/src/html/fonts.ts +641 -0
- package/src/html/gif.ts +233 -0
- package/src/html/index.ts +180 -20
- package/src/html/layout/block.ts +3456 -230
- package/src/html/layout/boxes.ts +2100 -190
- package/src/html/layout/cache.ts +289 -0
- package/src/html/layout/collapse.ts +317 -0
- package/src/html/layout/css-grid.ts +1063 -0
- package/src/html/layout/flex.ts +1115 -106
- package/src/html/layout/floats.ts +128 -14
- package/src/html/layout/grid-lines.ts +141 -0
- package/src/html/layout/grid.ts +181 -0
- package/src/html/layout/inline.ts +3943 -192
- package/src/html/layout/shaping.ts +140 -0
- package/src/html/layout/table.ts +696 -186
- package/src/html/layout/tracks.ts +437 -0
- package/src/html/node.ts +1481 -118
- package/src/html/paint.ts +4293 -169
- package/src/html/resources.ts +161 -50
- package/src/html/surfaces.ts +81 -0
- package/src/html/svg.ts +493 -0
- package/src/html/url.ts +86 -0
- package/src/index.ts +2 -0
- package/src/internal/collate.ts +12 -0
- package/src/internal/markdown/ast.ts +11 -0
- package/src/internal/markdown/parse.ts +154 -11
- package/src/internal/prewarm.ts +45 -0
- package/src/internal/sdf.ts +227 -0
- package/src/internal/splice.ts +25 -0
- package/src/internal/window.ts +36 -5
- package/src/maps/anchors.ts +307 -1
- package/src/maps/controller.ts +116 -31
- package/src/maps/gl/buckets.ts +5 -1
- package/src/maps/gl/build-worker.ts +13 -2
- package/src/maps/gl/cover.ts +79 -44
- package/src/maps/gl/placement.ts +221 -69
- package/src/maps/gl/renderer.ts +104 -20
- package/src/maps/gl/shaders.ts +35 -32
- package/src/maps/gl/store.ts +66 -17
- package/src/maps/gl/text.ts +444 -71
- package/src/maps/gl/view.ts +361 -96
- package/src/maps/icons.ts +183 -0
- package/src/maps/index.ts +4 -0
- package/src/maps/labels.ts +269 -49
- package/src/maps/node.ts +82 -49
- package/src/maps/proj.ts +87 -0
- package/src/maps/sources.ts +5 -3
- package/src/maps/style.ts +32 -0
- package/src/maps/styles.ts +215 -4
- package/src/maps/tiles.ts +64 -31
- package/src/maps/types.ts +28 -4
- package/src/markdown/index.ts +149 -67
- package/src/markdown/spans.ts +5 -0
- package/src/qml/containers.tsx +6 -1
- package/src/qml/interaction.tsx +42 -5
- package/src/qml/layouts.tsx +21 -6
- package/src/qml/qtquick.tsx +9 -2
- package/src/qml/react.tsx +7 -5
- package/src/reorder/clock.ts +27 -0
- package/src/reorder/index.ts +100 -27
- package/src/rich-text-editor/index.ts +34 -1
- package/src/rich-text-editor/keymap.ts +1 -1
- package/src/rich-text-editor/keys.ts +135 -26
- package/src/rich-text-editor/marks.ts +101 -0
- package/src/rich-text-editor/render.ts +49 -12
- package/src/rich-text-editor/toolbar.ts +1 -1
- package/src/rich-text-editor/virtual.ts +25 -0
- package/src/richtext/node.ts +235 -14
- package/src/richtext/runs.ts +23 -12
- package/src/table/index.ts +29 -0
- package/src/table/rows.ts +18 -8
- package/src/terminal/index.ts +4 -0
- package/src/terminal/vt/pty.ts +16 -2
- package/src/terminal-output/index.ts +6 -1
- package/src/three/canvas.ts +102 -8
- package/src/three/events.ts +49 -9
- package/src/tree/index.ts +19 -0
|
@@ -181,31 +181,168 @@ function indentOf(line: string): number {
|
|
|
181
181
|
|
|
182
182
|
export function parse(source: string, options: ParseOptions = {}): Document {
|
|
183
183
|
const partial = options.partial !== false;
|
|
184
|
+
const isComponent = options.isComponent ?? NO_COMPONENTS;
|
|
185
|
+
const expressions = options.expressions === true;
|
|
184
186
|
const normalized = source.replace(/\r\n?/g, '\n');
|
|
185
187
|
const lines = normalized.split('\n').map(expandLeadingTabs);
|
|
188
|
+
const previous = options.previous;
|
|
189
|
+
const was = previous ? resumable.get(previous) : undefined;
|
|
190
|
+
// Not with components: an open tag looks for its close to the end of the
|
|
191
|
+
// document (`componentCloseLine`), so a close added anywhere below can
|
|
192
|
+
// change what it is, and the block before an edit is no longer settled.
|
|
193
|
+
if (
|
|
194
|
+
previous &&
|
|
195
|
+
was &&
|
|
196
|
+
was.partial === partial &&
|
|
197
|
+
was.expressions === expressions &&
|
|
198
|
+
isComponent === NO_COMPONENTS &&
|
|
199
|
+
was.isComponent === NO_COMPONENTS
|
|
200
|
+
) {
|
|
201
|
+
return resume(previous, was, lines);
|
|
202
|
+
}
|
|
186
203
|
const blocks: BlockNode[] = [];
|
|
187
204
|
const ranges: Array<[number, number]> = [];
|
|
188
|
-
|
|
205
|
+
const blanks = new Uint8Array(lines.length);
|
|
206
|
+
parseBlocks(lines, partial, blocks, ranges, isComponent, expressions, {
|
|
207
|
+
from: 0,
|
|
208
|
+
blanks,
|
|
209
|
+
});
|
|
210
|
+
return remember(
|
|
211
|
+
{ blocks, raws: ranges.map(([a, b]) => lines.slice(a, b).join('\n')) },
|
|
212
|
+
{ lines, ranges, blanks, partial, isComponent, expressions },
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// --- resuming --------------------------------------------------------------
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* What a parse leaves for the next parse of the same document to start from
|
|
220
|
+
* (`ParseOptions.previous`).
|
|
221
|
+
*
|
|
222
|
+
* The block loop carries one thing from a block to the next, the paragraph
|
|
223
|
+
* it is gathering, and it looks only forwards: a block's extent is decided
|
|
224
|
+
* by the lines up to the first line of the block after it. So `blanks`
|
|
225
|
+
* marks the lines where the loop stood on a blank line at the top level with
|
|
226
|
+
* no paragraph open. Two parses standing on such a line, with the same lines
|
|
227
|
+
* from there to the end, produce the same blocks from there on. That is the
|
|
228
|
+
* point where an edit's re-parse can stop and take the rest from before.
|
|
229
|
+
*/
|
|
230
|
+
interface Resumable {
|
|
231
|
+
lines: string[];
|
|
232
|
+
/** each top-level block's [start, endExcl) line range */
|
|
233
|
+
ranges: Array<[number, number]>;
|
|
234
|
+
/** 1 on each line where the top-level loop stood blank with no paragraph */
|
|
235
|
+
blanks: Uint8Array;
|
|
236
|
+
partial: boolean;
|
|
237
|
+
isComponent: (name: string) => boolean;
|
|
238
|
+
expressions: boolean;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Kept beside the documents rather than in them, so a Document stays the
|
|
242
|
+
* plain data every caller and test compares. */
|
|
243
|
+
const resumable = new WeakMap<Document, Resumable>();
|
|
244
|
+
|
|
245
|
+
function remember(doc: Document, state: Resumable): Document {
|
|
246
|
+
resumable.set(doc, state);
|
|
247
|
+
return doc;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Parse `lines` as an edit of `previous`: from one block before the first
|
|
252
|
+
* line that changed, until the loop stands where the previous parse stood
|
|
253
|
+
* in the lines the edit left alone — or to the end, when it never does (an
|
|
254
|
+
* unclosed fence swallows the rest of a document either way).
|
|
255
|
+
*/
|
|
256
|
+
function resume(previous: Document, was: Resumable, lines: string[]): Document {
|
|
257
|
+
const old = was.lines;
|
|
258
|
+
const oldN = old.length;
|
|
259
|
+
const n = lines.length;
|
|
260
|
+
const shortest = Math.min(oldN, n);
|
|
261
|
+
let first = 0;
|
|
262
|
+
while (first < shortest && old[first] === lines[first]) first += 1;
|
|
263
|
+
if (first === oldN && first === n) return previous;
|
|
264
|
+
// lines at the end the edit did not touch, never counting the prefix twice
|
|
265
|
+
let same = 0;
|
|
266
|
+
while (
|
|
267
|
+
same < shortest - first &&
|
|
268
|
+
old[oldN - 1 - same] === lines[n - 1 - same]
|
|
269
|
+
) {
|
|
270
|
+
same += 1;
|
|
271
|
+
}
|
|
272
|
+
const shift = n - oldN;
|
|
273
|
+
const suffix = n - same;
|
|
274
|
+
|
|
275
|
+
// The first block that reaches the change, and the one before it: a
|
|
276
|
+
// block's extent is decided by the lines up to the next block's first —
|
|
277
|
+
// a list looks past blank lines to see whether it goes on — so the block
|
|
278
|
+
// before the first one touched cannot have depended on the change.
|
|
279
|
+
const { ranges } = was;
|
|
280
|
+
let lo = 0;
|
|
281
|
+
let hi = ranges.length;
|
|
282
|
+
while (lo < hi) {
|
|
283
|
+
const mid = (lo + hi) >> 1;
|
|
284
|
+
if (ranges[mid][1] <= first) lo = mid + 1;
|
|
285
|
+
else hi = mid;
|
|
286
|
+
}
|
|
287
|
+
const kept = Math.max(0, lo - 1);
|
|
288
|
+
const from = kept === 0 ? 0 : ranges[kept][0];
|
|
289
|
+
|
|
290
|
+
const blanks = new Uint8Array(n);
|
|
291
|
+
blanks.set(was.blanks.subarray(0, from));
|
|
292
|
+
const blocks: BlockNode[] = previous.blocks.slice(0, kept);
|
|
293
|
+
const raws = previous.raws.slice(0, kept);
|
|
294
|
+
const next: Array<[number, number]> = ranges.slice(0, kept);
|
|
295
|
+
const fresh: Array<[number, number]> = [];
|
|
296
|
+
const stop = parseBlocks(
|
|
189
297
|
lines,
|
|
190
|
-
partial,
|
|
298
|
+
was.partial,
|
|
191
299
|
blocks,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
300
|
+
fresh,
|
|
301
|
+
was.isComponent,
|
|
302
|
+
was.expressions,
|
|
303
|
+
{
|
|
304
|
+
from,
|
|
305
|
+
blanks,
|
|
306
|
+
resync: (i) => i >= suffix && was.blanks[i - shift] === 1,
|
|
307
|
+
},
|
|
195
308
|
);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
309
|
+
for (const [a, b] of fresh) {
|
|
310
|
+
raws.push(lines.slice(a, b).join('\n'));
|
|
311
|
+
next.push([a, b]);
|
|
312
|
+
}
|
|
313
|
+
if (stop < n) {
|
|
314
|
+
// the previous parse from the same place over the same lines: its
|
|
315
|
+
// blocks, where they now are
|
|
316
|
+
const at = stop - shift;
|
|
317
|
+
blanks.set(was.blanks.subarray(at), stop);
|
|
318
|
+
let j = ranges.length;
|
|
319
|
+
while (j > 0 && ranges[j - 1][0] >= at) j -= 1;
|
|
320
|
+
for (; j < ranges.length; j += 1) {
|
|
321
|
+
blocks.push(previous.blocks[j]);
|
|
322
|
+
raws.push(previous.raws[j]);
|
|
323
|
+
next.push([ranges[j][0] + shift, ranges[j][1] + shift]);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return remember({ blocks, raws }, { ...was, lines, ranges: next, blanks });
|
|
200
327
|
}
|
|
201
328
|
|
|
202
329
|
// --- block layer -----------------------------------------------------------
|
|
203
330
|
|
|
331
|
+
/** The top-level call's extra: where to start, where to record the blank
|
|
332
|
+
* lines it stands on, and when to stop (`resume`). */
|
|
333
|
+
interface TopLevel {
|
|
334
|
+
from: number;
|
|
335
|
+
blanks: Uint8Array;
|
|
336
|
+
resync?: (line: number) => boolean;
|
|
337
|
+
}
|
|
338
|
+
|
|
204
339
|
/**
|
|
205
340
|
* Parse a run of lines into blocks. `tailOpen` says the end of `lines` is
|
|
206
341
|
* the live end of a streaming document — the license for every "complete it
|
|
207
342
|
* anyway" rule. `ranges`, when given, receives each block's [start, endExcl)
|
|
208
343
|
* line range (only the top-level call wants them, for the streaming cache).
|
|
344
|
+
* Returns the line it stopped at: the end, or where `top.resync` said the
|
|
345
|
+
* rest would come out as it did before.
|
|
209
346
|
*/
|
|
210
347
|
function parseBlocks(
|
|
211
348
|
lines: string[],
|
|
@@ -214,8 +351,9 @@ function parseBlocks(
|
|
|
214
351
|
ranges?: Array<[number, number]>,
|
|
215
352
|
isComponent: (name: string) => boolean = NO_COMPONENTS,
|
|
216
353
|
expressions = false,
|
|
217
|
-
|
|
218
|
-
|
|
354
|
+
top?: TopLevel,
|
|
355
|
+
): number {
|
|
356
|
+
let i = top?.from ?? 0;
|
|
219
357
|
const n = lines.length;
|
|
220
358
|
|
|
221
359
|
let paraStart = -1;
|
|
@@ -245,6 +383,10 @@ function parseBlocks(
|
|
|
245
383
|
|
|
246
384
|
if (RE_BLANK.test(line)) {
|
|
247
385
|
flushPara(i);
|
|
386
|
+
if (top) {
|
|
387
|
+
if (top.resync?.(i)) return i;
|
|
388
|
+
top.blanks[i] = 1;
|
|
389
|
+
}
|
|
248
390
|
i += 1;
|
|
249
391
|
continue;
|
|
250
392
|
}
|
|
@@ -571,6 +713,7 @@ function parseBlocks(
|
|
|
571
713
|
}
|
|
572
714
|
|
|
573
715
|
flushPara(n);
|
|
716
|
+
return n;
|
|
574
717
|
}
|
|
575
718
|
|
|
576
719
|
// --- lists -----------------------------------------------------------------
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// A font family, warmed before the first layout sets text in it.
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { useApp } from 'react-x11';
|
|
4
|
+
|
|
5
|
+
/** The one method this needs of `app.fonts`, which ntk's FontManager has
|
|
6
|
+
* from the release that added it, and other font managers may not. */
|
|
7
|
+
interface PrewarmingFonts {
|
|
8
|
+
prewarm?: (family: string) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Start matching `family`'s faces now, off the event loop, so that the first
|
|
13
|
+
* layout setting text in it takes the answer instead of stalling on the
|
|
14
|
+
* system's font matcher — ntk's `FontManager#prewarm`. fontconfig answers in
|
|
15
|
+
* 20–40 ms on a Linux desktop and in 80–150 on XQuartz, and nothing warms a
|
|
16
|
+
* family but sans-serif until a layout asks for it.
|
|
17
|
+
*
|
|
18
|
+
* Called while rendering, as React's own resource hints are: a component
|
|
19
|
+
* renders ahead of the frame that lays it out, and a long document's render
|
|
20
|
+
* is hundreds of milliseconds of head start that an effect would give away.
|
|
21
|
+
* Once per family; nothing where the app's fonts have nothing to look up
|
|
22
|
+
* (fonts in memory, a native text engine) or predate the method.
|
|
23
|
+
*/
|
|
24
|
+
export function useFontPrewarm(family: string | null | undefined): void {
|
|
25
|
+
const fonts = (useApp() as { fonts?: PrewarmingFonts } | null)?.fonts;
|
|
26
|
+
useMemo(() => {
|
|
27
|
+
if (family) fonts?.prewarm?.(family);
|
|
28
|
+
}, [fonts, family]);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The font family a style names, read the way core flattens one — the last
|
|
32
|
+
* entry of an array that names it wins — or `fallback`. */
|
|
33
|
+
export function styleFamily(style: unknown, fallback: string): string {
|
|
34
|
+
let family = fallback;
|
|
35
|
+
const visit = (entry: unknown): void => {
|
|
36
|
+
if (Array.isArray(entry)) {
|
|
37
|
+
for (const e of entry) visit(e);
|
|
38
|
+
} else if (entry && typeof entry === 'object') {
|
|
39
|
+
const named = (entry as { fontFamily?: unknown }).fontFamily;
|
|
40
|
+
if (typeof named === 'string') family = named;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
visit(style);
|
|
44
|
+
return family;
|
|
45
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// A label's raster as a signed distance field: what lets one raster serve a
|
|
2
|
+
// name at every size a zoom passes through, and a halo of any width. Under
|
|
3
|
+
// the GL labels of both `<Map>` (`src/maps/gl/text.ts`) and `<Flow>`
|
|
4
|
+
// (`src/flow/gl/text.ts`), which is why it is here rather than in either.
|
|
5
|
+
//
|
|
6
|
+
// The text engine sets a string as coverage — alpha, antialiased — at one
|
|
7
|
+
// base size. Each texel here becomes its distance to the glyphs' edge,
|
|
8
|
+
// encoded in a byte so that `SDF_EDGE` is the edge itself, more is inside
|
|
9
|
+
// and less is outside:
|
|
10
|
+
//
|
|
11
|
+
// byte = 255 · (1 − d / radius − SDF_CUTOFF), d > 0 outside
|
|
12
|
+
//
|
|
13
|
+
// so a field reaches `radius · (1 − SDF_CUTOFF)` texels past the glyphs
|
|
14
|
+
// before it saturates at 0 — the room a halo has to grow into — and
|
|
15
|
+
// `radius · SDF_CUTOFF` into them.
|
|
16
|
+
//
|
|
17
|
+
// The distance is the exact Euclidean one, started at the edge by what the
|
|
18
|
+
// coverage says: an antialiased texel half covered sits on the edge, one a
|
|
19
|
+
// quarter covered a quarter of a texel outside it. That sub-texel start is
|
|
20
|
+
// what keeps a field set at 16 pixels from drawing a lumpy stroke at 40.
|
|
21
|
+
//
|
|
22
|
+
// **Only where it can change a byte.** A field is set the first time its
|
|
23
|
+
// string is drawn, so its cost is how late a label appears. Outside the
|
|
24
|
+
// glyphs the distance is Felzenszwalb and Huttenlocher's linear-time
|
|
25
|
+
// transform — but only over the window a field reaches round the ink, the
|
|
26
|
+
// rows that hold ink first and then the window's columns, since past the
|
|
27
|
+
// reach every byte is 0 and every source is inside it. Inside, a field
|
|
28
|
+
// saturates `radius · SDF_CUTOFF` texels in (1.5 at Flow's margin, 2.25 at
|
|
29
|
+
// a map's), so the nearest texel less than half covered is found by
|
|
30
|
+
// searching the few rings round each texel inside, not by a second
|
|
31
|
+
// transform over the whole raster. Byte for byte what the two whole
|
|
32
|
+
// transforms gave, at half the cost: measured over DirectWrite's coverage
|
|
33
|
+
// of 520 labels, 262 → 140 µs a field at Flow's margin and 626 → 311 at a
|
|
34
|
+
// map's.
|
|
35
|
+
|
|
36
|
+
/** The fraction of the byte range spent inside the glyphs. */
|
|
37
|
+
export const SDF_CUTOFF = 0.25;
|
|
38
|
+
|
|
39
|
+
/** The byte value of the glyphs' edge, as a fraction: `1 − SDF_CUTOFF`. */
|
|
40
|
+
export const SDF_EDGE = 1 - SDF_CUTOFF;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Device pixels outside a field's outline that its ink's edge is drawn. A
|
|
44
|
+
* text engine darkens stems at small sizes; a field thresholded at half
|
|
45
|
+
* coverage gives that back, and a string drawn from one looks a weight
|
|
46
|
+
* lighter than the same string set. Both GL label shaders draw it.
|
|
47
|
+
*/
|
|
48
|
+
export const SDF_INK_BIAS_PX = 0.15;
|
|
49
|
+
|
|
50
|
+
/** "No edge in reach": far past any raster's squared diagonal, and small
|
|
51
|
+
* enough that `FAR + q²` is still exact in a double, so two of them cross
|
|
52
|
+
* where two parabolas of one height do. */
|
|
53
|
+
const FAR = 1e10;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Each coverage byte's squared distance to the edge *inside* its own
|
|
57
|
+
* texel: (a − ½)² where more than half covered, 0 where not — a texel less
|
|
58
|
+
* than half covered is outside, where an inside distance ends — and FAR
|
|
59
|
+
* where whole.
|
|
60
|
+
*/
|
|
61
|
+
const INSIDE = new Float64Array(256);
|
|
62
|
+
for (let a8 = 1; a8 < 255; a8++) {
|
|
63
|
+
const d = 0.5 - a8 / 255;
|
|
64
|
+
INSIDE[a8] = d < 0 ? d * d : 0;
|
|
65
|
+
}
|
|
66
|
+
INSIDE[255] = FAR;
|
|
67
|
+
|
|
68
|
+
/** Scratch, grown to the largest raster seen and reused. */
|
|
69
|
+
let outer = new Float64Array(0);
|
|
70
|
+
let f = new Float64Array(0);
|
|
71
|
+
let g = new Float64Array(0);
|
|
72
|
+
let z = new Float64Array(0);
|
|
73
|
+
let v = new Int32Array(0);
|
|
74
|
+
|
|
75
|
+
function grow(texels: number, line: number): void {
|
|
76
|
+
if (outer.length < texels) outer = new Float64Array(texels);
|
|
77
|
+
if (f.length < line) {
|
|
78
|
+
f = new Float64Array(line);
|
|
79
|
+
g = new Float64Array(line);
|
|
80
|
+
z = new Float64Array(line + 1);
|
|
81
|
+
v = new Int32Array(line);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The squared distance transform of `length` values of `grid` from
|
|
87
|
+
* `offset`, `stride` apart, in place: each becomes the least
|
|
88
|
+
* `grid[r] + (q − r)²` — the lower envelope of parabolas rooted at every
|
|
89
|
+
* texel. `g` holds each parabola's `grid[r] + r²`, so where two cross is
|
|
90
|
+
* one division.
|
|
91
|
+
*/
|
|
92
|
+
function transform1d(
|
|
93
|
+
grid: Float64Array,
|
|
94
|
+
offset: number,
|
|
95
|
+
stride: number,
|
|
96
|
+
length: number,
|
|
97
|
+
): void {
|
|
98
|
+
let k = 0;
|
|
99
|
+
v[0] = 0;
|
|
100
|
+
z[0] = -Infinity;
|
|
101
|
+
z[1] = Infinity;
|
|
102
|
+
f[0] = grid[offset];
|
|
103
|
+
g[0] = f[0];
|
|
104
|
+
for (let q = 1, at = offset + stride; q < length; q++, at += stride) {
|
|
105
|
+
const fq = grid[at];
|
|
106
|
+
f[q] = fq;
|
|
107
|
+
const gq = fq + q * q;
|
|
108
|
+
g[q] = gq;
|
|
109
|
+
let s: number;
|
|
110
|
+
for (;;) {
|
|
111
|
+
const r = v[k];
|
|
112
|
+
s = (gq - g[r]) / (2 * (q - r));
|
|
113
|
+
if (s > z[k] || k === 0) break;
|
|
114
|
+
k--;
|
|
115
|
+
}
|
|
116
|
+
k++;
|
|
117
|
+
v[k] = q;
|
|
118
|
+
z[k] = s;
|
|
119
|
+
z[k + 1] = Infinity;
|
|
120
|
+
}
|
|
121
|
+
k = 0;
|
|
122
|
+
for (let q = 0, at = offset; q < length; q++, at += stride) {
|
|
123
|
+
while (z[k + 1] < q) k++;
|
|
124
|
+
const r = v[k];
|
|
125
|
+
const d = q - r;
|
|
126
|
+
grid[at] = f[r] + d * d;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The field of a `width` × `height` raster whose coverage is `alpha`
|
|
132
|
+
* (0-255), read every `step` bytes from `start` — so an RGBA readback is
|
|
133
|
+
* read in place, `step` 4 and `start` 3, and an engine's own coverage with
|
|
134
|
+
* `step` 1 and `start` 0. One byte a texel, see the top of this file for
|
|
135
|
+
* the encoding.
|
|
136
|
+
*/
|
|
137
|
+
export function distanceField(
|
|
138
|
+
alpha: Uint8Array,
|
|
139
|
+
width: number,
|
|
140
|
+
height: number,
|
|
141
|
+
radius: number,
|
|
142
|
+
step = 4,
|
|
143
|
+
start = 3,
|
|
144
|
+
): Uint8Array {
|
|
145
|
+
const texels = width * height;
|
|
146
|
+
grow(texels, Math.max(width, height));
|
|
147
|
+
// Zeroed: a byte nothing below writes is as far outside as a field sees.
|
|
148
|
+
const out = new Uint8Array(texels);
|
|
149
|
+
let minX = width;
|
|
150
|
+
let maxX = -1;
|
|
151
|
+
let minY = height;
|
|
152
|
+
let maxY = -1;
|
|
153
|
+
for (let y = 0, i = 0, a = start; y < height; y++) {
|
|
154
|
+
for (let x = 0; x < width; x++, i++, a += step) {
|
|
155
|
+
const a8 = alpha[a];
|
|
156
|
+
if (a8 === 0) {
|
|
157
|
+
outer[i] = FAR;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (x < minX) minX = x;
|
|
161
|
+
if (x > maxX) maxX = x;
|
|
162
|
+
if (y < minY) minY = y;
|
|
163
|
+
if (y > maxY) maxY = y;
|
|
164
|
+
if (a8 === 255) {
|
|
165
|
+
outer[i] = 0;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
// Partly covered: on the edge, off it by how far from half covered.
|
|
169
|
+
const d = 0.5 - a8 / 255;
|
|
170
|
+
outer[i] = d > 0 ? d * d : 0;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (maxX < 0) return out;
|
|
174
|
+
|
|
175
|
+
// Outside: the window the field reaches round the ink. Every source is
|
|
176
|
+
// in it, so what the transform computes there is exact, and past it every
|
|
177
|
+
// byte is 0. The rows with ink first — every source is on one — then
|
|
178
|
+
// every column of the window.
|
|
179
|
+
const reach = Math.ceil(radius * (1 - SDF_CUTOFF)) + 1;
|
|
180
|
+
const x0 = Math.max(0, minX - reach);
|
|
181
|
+
const x1 = Math.min(width - 1, maxX + reach);
|
|
182
|
+
const y0 = Math.max(0, minY - reach);
|
|
183
|
+
const y1 = Math.min(height - 1, maxY + reach);
|
|
184
|
+
for (let y = minY; y <= maxY; y++) {
|
|
185
|
+
transform1d(outer, y * width + x0, 1, x1 - x0 + 1);
|
|
186
|
+
}
|
|
187
|
+
for (let x = x0; x <= x1; x++) {
|
|
188
|
+
transform1d(outer, y0 * width + x, width, y1 - y0 + 1);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Inside, the field saturates this many rings in.
|
|
192
|
+
const deep = Math.ceil(radius * SDF_CUTOFF);
|
|
193
|
+
for (let y = y0; y <= y1; y++) {
|
|
194
|
+
for (let x = x0, i = y * width + x0; x <= x1; x++, i++) {
|
|
195
|
+
// Outside the ink, or in it: never both.
|
|
196
|
+
const o = outer[i];
|
|
197
|
+
let d: number;
|
|
198
|
+
if (o > 0) {
|
|
199
|
+
d = Math.sqrt(o);
|
|
200
|
+
} else {
|
|
201
|
+
// The least (a − ½)² + distance² over the texels round it, ring by
|
|
202
|
+
// ring, until no ring further out could be nearer — or the field
|
|
203
|
+
// has saturated, where the exact answer and this one are both 255.
|
|
204
|
+
let best = INSIDE[alpha[start + i * step]];
|
|
205
|
+
for (let k = 1; k <= deep && best > k * k; k++) {
|
|
206
|
+
for (let yy = y - k; yy <= y + k; yy++) {
|
|
207
|
+
if (yy < 0 || yy >= height) continue;
|
|
208
|
+
const dy2 = (yy - y) * (yy - y);
|
|
209
|
+
// a ring's top and bottom rows whole, its sides two texels
|
|
210
|
+
const across = yy === y - k || yy === y + k ? 1 : 2 * k;
|
|
211
|
+
for (let xx = x - k; xx <= x + k; xx += across) {
|
|
212
|
+
if (xx < 0 || xx >= width) continue;
|
|
213
|
+
const dx = xx - x;
|
|
214
|
+
const m =
|
|
215
|
+
INSIDE[alpha[start + (yy * width + xx) * step]] + dx * dx + dy2;
|
|
216
|
+
if (m < best) best = m;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
d = -Math.sqrt(best);
|
|
221
|
+
}
|
|
222
|
+
const value = Math.round(255 - 255 * (d / radius + SDF_CUTOFF));
|
|
223
|
+
out[i] = value < 0 ? 0 : value > 255 ? 255 : value;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return out;
|
|
227
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `target.splice(from, removed, ...items)`, for any number of items.
|
|
3
|
+
*
|
|
4
|
+
* A spread argument list lives on the stack, and somewhere past a hundred
|
|
5
|
+
* thousand items it throws `RangeError: Maximum call stack size exceeded` —
|
|
6
|
+
* a pasted log, or a file replaced whole, is that many lines. Past a few
|
|
7
|
+
* thousand the array is rebuilt in place instead: whoever holds `target`
|
|
8
|
+
* keeps holding it, which is the whole reason it is spliced rather than
|
|
9
|
+
* replaced.
|
|
10
|
+
*/
|
|
11
|
+
export function spliceAll<T>(
|
|
12
|
+
target: T[],
|
|
13
|
+
from: number,
|
|
14
|
+
removed: number,
|
|
15
|
+
items: readonly T[],
|
|
16
|
+
): void {
|
|
17
|
+
if (items.length <= 4096) {
|
|
18
|
+
target.splice(from, removed, ...items);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const tail = target.slice(from + removed);
|
|
22
|
+
target.length = from;
|
|
23
|
+
for (let i = 0; i < items.length; i++) target.push(items[i]);
|
|
24
|
+
for (let i = 0; i < tail.length; i++) target.push(tail[i]);
|
|
25
|
+
}
|
package/src/internal/window.ts
CHANGED
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
// forces them out, trailing side first — a direction reversal lands on
|
|
31
31
|
// rows still mounted instead of rebuilding them. The budget caps what a
|
|
32
32
|
// render can be asked to carry: the on-screen slice plus `prefetch` rows
|
|
33
|
-
// each side
|
|
33
|
+
// each side — at any speed, which is why a row is measured on its way
|
|
34
|
+
// out when nothing has measured it yet.
|
|
34
35
|
// - **Skeletons.** A scroll that outruns everything — a thumb dragged
|
|
35
36
|
// across the list, a flick past the band — floods the window with rows
|
|
36
37
|
// no single render can build in time. Those render as *skeletons*: the
|
|
@@ -164,6 +165,18 @@ export interface VirtualWindowInputs {
|
|
|
164
165
|
* settled. `BURST_BUDGET` / `SETTLE_BUDGET` are the defaults. */
|
|
165
166
|
burstBudget: number;
|
|
166
167
|
settleBudget: number;
|
|
168
|
+
/**
|
|
169
|
+
* Record the height the drawn row `id`, at `index`, is laid out at in the
|
|
170
|
+
* index, now; answer whether the index has a real height for it after.
|
|
171
|
+
* The trim asks before it drops a row the measure tick has not reached
|
|
172
|
+
* (see the budget below), during render — so no nudge and no re-render:
|
|
173
|
+
* the row is still laid out at exactly that height, and nothing on screen
|
|
174
|
+
* moves until the spacer takes its place. `false` for a row with no
|
|
175
|
+
* honest measurement to give, which keeps it mounted. `viewport` is the
|
|
176
|
+
* event-fresh one (`viewRef`), for a component whose rows are laid out
|
|
177
|
+
* against it.
|
|
178
|
+
*/
|
|
179
|
+
measure?: (id: RowKey, index: number, viewport: VirtualViewport) => boolean;
|
|
167
180
|
}
|
|
168
181
|
|
|
169
182
|
export interface VirtualWindow {
|
|
@@ -370,6 +383,7 @@ export function useVirtualWindow(inputs: VirtualWindowInputs): VirtualWindow {
|
|
|
370
383
|
threshold,
|
|
371
384
|
burstBudget,
|
|
372
385
|
settleBudget,
|
|
386
|
+
measure,
|
|
373
387
|
} = inputs;
|
|
374
388
|
const count = rows.length;
|
|
375
389
|
|
|
@@ -448,15 +462,32 @@ export function useVirtualWindow(inputs: VirtualWindowInputs): VirtualWindow {
|
|
|
448
462
|
// row laid out taller than the index believes contributes its real
|
|
449
463
|
// height while mounted and its guessed one once dropped, so cutting
|
|
450
464
|
// it silently shrinks the content above the viewport and the view
|
|
451
|
-
// yanks up by the difference with no debt left to put it right.
|
|
452
|
-
//
|
|
453
|
-
// it
|
|
465
|
+
// yanks up by the difference with no debt left to put it right.
|
|
466
|
+
//
|
|
467
|
+
// So a row the index has no number for is measured *here*, where it
|
|
468
|
+
// is still laid out (`measure`): once the index holds the height it
|
|
469
|
+
// is drawn at, the spacer that replaces it is exactly as tall, and it
|
|
470
|
+
// goes like any other. Waiting for the measure tick instead is only
|
|
471
|
+
// safe while the tick runs — and a flick defers every measurement to
|
|
472
|
+
// the settle, so a long one downward trimmed nothing at all and the
|
|
473
|
+
// window grew by every row it passed: 1,250 rows mounted four seconds
|
|
474
|
+
// into a trackpad fling, each frame laying all of them out. A row the
|
|
475
|
+
// last render did not build in full needs nothing: a skeleton is
|
|
476
|
+
// drawn at the index's height, and a row never drawn is not in the
|
|
477
|
+
// layout at all. What cannot be measured — a row not laid out yet, or
|
|
478
|
+
// laid out against a grid it is about to leave — is held a render or
|
|
479
|
+
// two longer, as before.
|
|
454
480
|
const budget = coreLast - coreFirst + 2 * prefetch;
|
|
455
481
|
let excess = last - first - budget;
|
|
456
482
|
if (excess > 0) {
|
|
483
|
+
const known = (i: number): boolean =>
|
|
484
|
+
exact ||
|
|
485
|
+
heights.isMeasured(i) ||
|
|
486
|
+
!real.current.has(rows[i].id) ||
|
|
487
|
+
measure?.(rows[i].id, i, viewRef.current) === true;
|
|
457
488
|
const cutAbove = (want: number): number => {
|
|
458
489
|
let k = 0;
|
|
459
|
-
while (k < want && (
|
|
490
|
+
while (k < want && known(first + k)) k++;
|
|
460
491
|
return k;
|
|
461
492
|
};
|
|
462
493
|
const aboveExtra = coreFirst - first;
|