@react-x11/components 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +81 -0
- package/dist/internal/heights.d.ts.map +1 -0
- package/dist/internal/heights.js +193 -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/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 +844 -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 +716 -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 +211 -0
- package/src/internal/hx.ts +53 -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 +1219 -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 +1087 -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,1068 @@
|
|
|
1
|
+
// `<vtterm>` — the registered element the vt backend draws into.
|
|
2
|
+
//
|
|
3
|
+
// The division of labour with `./index.ts` mirrors `../../code-editor/`: the
|
|
4
|
+
// component owns process things (resolve the optional dependencies, create
|
|
5
|
+
// the emulator and the pty, wire them together, flow control, the imperative
|
|
6
|
+
// handle), and this node owns pixels and input (cell metrics, layout, the
|
|
7
|
+
// renderer and the mirror, cursor blink, selection, key and mouse encoding
|
|
8
|
+
// through core's default-action seam, clipboard).
|
|
9
|
+
//
|
|
10
|
+
// The consequence worth having: the node is drivable with a fake `term` and
|
|
11
|
+
// no pty at all, which is what makes the whole renderer testable in CI.
|
|
12
|
+
import { CARET_BLINK_MS, Node } from 'react-x11/node';
|
|
13
|
+
import { Surface } from 'react-x11/ntk';
|
|
14
|
+
import { XK_ESCAPE, XK_INSERT, XK_TAB, ctrlChordLetter, } from 'react-x11/keysyms';
|
|
15
|
+
import { buildPalette } from './colors.js';
|
|
16
|
+
import { DECO_OVERLINE, DECO_STRIKE, DECO_UNDERLINE, VARIANT_BOLD, VARIANT_ITALIC, } from './colors.js';
|
|
17
|
+
import { Mirror, createSnapshot, orderSelection, readViewport, } from './diff.js';
|
|
18
|
+
import { FontSet, variantOf } from './fonts.js';
|
|
19
|
+
import { encodeKey, encodePaste } from './keys.js';
|
|
20
|
+
import { ENCODING_MODES, encodeAlternateScroll, encodeMouse } from './mouse.js';
|
|
21
|
+
import { createRenderer } from './renderer.js';
|
|
22
|
+
import { microtask, startInterval, stopInterval } from './timers.js';
|
|
23
|
+
/** The element name — the registration key, `kind`, and the JSX tag. */
|
|
24
|
+
export const ELEMENT = 'vtterm';
|
|
25
|
+
const DEFAULT_FAMILY = 'monospace';
|
|
26
|
+
const DEFAULT_SIZE = 13;
|
|
27
|
+
/** What a bare `<Terminal>` measures to, in cells. */
|
|
28
|
+
const PREFERRED_COLS = 80;
|
|
29
|
+
const PREFERRED_ROWS = 24;
|
|
30
|
+
/** Wheel notches to lines, the way every terminal counts them. */
|
|
31
|
+
const WHEEL_LINES = 3;
|
|
32
|
+
/** OSC 52 payloads bigger than this are a program misbehaving, not a copy. */
|
|
33
|
+
const MAX_OSC52 = 1_000_000;
|
|
34
|
+
/** What counts as part of a word for double-click selection. */
|
|
35
|
+
const WORD_CHAR = /[\p{L}\p{N}_\-./~+@:]/u;
|
|
36
|
+
export class VtTermNode extends Node {
|
|
37
|
+
_term = null;
|
|
38
|
+
_disposables = [];
|
|
39
|
+
_fonts = null;
|
|
40
|
+
_fontKey = '';
|
|
41
|
+
_palette;
|
|
42
|
+
_paletteKey = '';
|
|
43
|
+
_renderer = null;
|
|
44
|
+
_mirror = new Mirror();
|
|
45
|
+
_snapshot = null;
|
|
46
|
+
_workCell = null;
|
|
47
|
+
_cols = 0;
|
|
48
|
+
_rows = 0;
|
|
49
|
+
_reportedCols = 0;
|
|
50
|
+
_reportedRows = 0;
|
|
51
|
+
_focused = false;
|
|
52
|
+
_cursorOn = true;
|
|
53
|
+
_blink = null;
|
|
54
|
+
/** Selection anchor and head, in buffer-absolute coordinates. */
|
|
55
|
+
_anchor = null;
|
|
56
|
+
_head = null;
|
|
57
|
+
_selection = null;
|
|
58
|
+
_dragMode = null;
|
|
59
|
+
/** Escape armed one pass-through Tab — the way out of the keyboard trap. */
|
|
60
|
+
_tabEscapes = false;
|
|
61
|
+
/** Not in `modes`: tracked from DECSET/DECRST (see `_watchModes`). */
|
|
62
|
+
_mouseEncoding = 'default';
|
|
63
|
+
_alternateScroll = true;
|
|
64
|
+
constructor(props, app) {
|
|
65
|
+
super(ELEMENT, props, app);
|
|
66
|
+
// Without this nothing ever focuses the terminal and no key reaches it.
|
|
67
|
+
// An app's `focusable`/`tabIndex` prop still overrides either way.
|
|
68
|
+
this.focusableByDefault = true;
|
|
69
|
+
this.defaultCursor = 'text';
|
|
70
|
+
// A terminal drags out a selection of its own, over a cell grid nothing
|
|
71
|
+
// outside it can index (react-x11#291). Saying so keeps a `selectable`
|
|
72
|
+
// document around it from walking in, and keeps the two from both
|
|
73
|
+
// claiming to be showing the application's selection — the same
|
|
74
|
+
// declaration `<textinput>` and `<codeeditor>` make.
|
|
75
|
+
this.hasOwnSelection = true;
|
|
76
|
+
this._palette = buildPalette(paletteColors(this._props()));
|
|
77
|
+
this._paletteKey = paletteKey(this._props());
|
|
78
|
+
this._attach(this._props().term ?? null);
|
|
79
|
+
}
|
|
80
|
+
_props() {
|
|
81
|
+
return this.props;
|
|
82
|
+
}
|
|
83
|
+
// --- props ---------------------------------------------------------------
|
|
84
|
+
applyProps(next, prev) {
|
|
85
|
+
super.applyProps(next, prev);
|
|
86
|
+
const props = this._props();
|
|
87
|
+
if (props.term !== prev.term) {
|
|
88
|
+
this._attach(props.term ?? null);
|
|
89
|
+
}
|
|
90
|
+
const key = paletteKey(props);
|
|
91
|
+
if (key !== this._paletteKey) {
|
|
92
|
+
this._paletteKey = key;
|
|
93
|
+
this._palette = buildPalette(paletteColors(props));
|
|
94
|
+
// The palette generation is a signature input, so the ordinary diff
|
|
95
|
+
// repaints every cell whose colours actually moved. Nothing else here
|
|
96
|
+
// needs to know a theme changed.
|
|
97
|
+
this._repaint();
|
|
98
|
+
}
|
|
99
|
+
const { family, size } = this._fontStyle();
|
|
100
|
+
if (`${family}|${size}` !== this._fontKey) {
|
|
101
|
+
this._fonts = null;
|
|
102
|
+
this._mirror.invalidate();
|
|
103
|
+
this.invalidateMeasure('measure');
|
|
104
|
+
this._repaint();
|
|
105
|
+
}
|
|
106
|
+
if (props.cursorBlink !== prev.cursorBlink) {
|
|
107
|
+
this._syncBlink();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
destroySubtree() {
|
|
111
|
+
this._detach();
|
|
112
|
+
stopInterval(this._blink);
|
|
113
|
+
this._blink = null;
|
|
114
|
+
this._renderer?.destroy();
|
|
115
|
+
this._renderer = null;
|
|
116
|
+
super.destroySubtree();
|
|
117
|
+
}
|
|
118
|
+
// --- the emulator --------------------------------------------------------
|
|
119
|
+
/**
|
|
120
|
+
* Subscribe to everything that means "the screen may look different".
|
|
121
|
+
*
|
|
122
|
+
* Only render-relevant events: the component keeps `onData`, `onTitleChange`
|
|
123
|
+
* and `onBell`, which are about the process rather than about pixels.
|
|
124
|
+
*/
|
|
125
|
+
_attach(term) {
|
|
126
|
+
this._detach();
|
|
127
|
+
this._term = term;
|
|
128
|
+
this._mirror.invalidate();
|
|
129
|
+
if (!term)
|
|
130
|
+
return;
|
|
131
|
+
const dirty = () => this._repaint();
|
|
132
|
+
this._disposables.push(term.onWriteParsed(dirty), term.onScroll(dirty), term.onCursorMove(dirty), term.onResize(() => {
|
|
133
|
+
this._mirror.invalidate();
|
|
134
|
+
this._repaint();
|
|
135
|
+
}), term.buffer.onBufferChange(() => {
|
|
136
|
+
// The alternate screen is a different buffer with a different
|
|
137
|
+
// coordinate origin; nothing on the surface survives the switch.
|
|
138
|
+
this._mirror.invalidate();
|
|
139
|
+
this.clearSelection();
|
|
140
|
+
this._repaint();
|
|
141
|
+
}));
|
|
142
|
+
this._watchModes(term);
|
|
143
|
+
this._workCell = term.buffer.active.getNullCell();
|
|
144
|
+
this._repaint();
|
|
145
|
+
}
|
|
146
|
+
_detach() {
|
|
147
|
+
for (const d of this._disposables) {
|
|
148
|
+
try {
|
|
149
|
+
d.dispose();
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// a terminal already disposed
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
this._disposables.length = 0;
|
|
156
|
+
this._term = null;
|
|
157
|
+
this._workCell = null;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The two things `modes` does not carry.
|
|
161
|
+
*
|
|
162
|
+
* Mouse *encoding* (SGR 1006, urxvt 1015, UTF-8 1005) and alternate-scroll
|
|
163
|
+
* (1007) are set by DECSET/DECRST and read back nowhere, so a passive CSI
|
|
164
|
+
* observer records them and **returns false** — xterm still processes the
|
|
165
|
+
* sequence itself, and this handler is a listener rather than an
|
|
166
|
+
* implementation. Filed upstream as a request to expose `mouseEncoding`
|
|
167
|
+
* alongside `mouseTrackingMode`.
|
|
168
|
+
*/
|
|
169
|
+
_watchModes(term) {
|
|
170
|
+
const observe = (set) => (params) => {
|
|
171
|
+
for (const param of params) {
|
|
172
|
+
const value = Array.isArray(param) ? param[0] : param;
|
|
173
|
+
const encoding = ENCODING_MODES[value];
|
|
174
|
+
if (encoding)
|
|
175
|
+
this._mouseEncoding = set ? encoding : 'default';
|
|
176
|
+
if (value === 1007)
|
|
177
|
+
this._alternateScroll = set;
|
|
178
|
+
}
|
|
179
|
+
return false;
|
|
180
|
+
};
|
|
181
|
+
try {
|
|
182
|
+
this._disposables.push(term.parser.registerCsiHandler({ prefix: '?', final: 'h' }, observe(true)), term.parser.registerCsiHandler({ prefix: '?', final: 'l' }, observe(false)), term.parser.registerOscHandler(52, (data) => this._onOsc52(data)));
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// a fake terminal in a test that implements only what it needs
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// --- metrics and layout --------------------------------------------------
|
|
189
|
+
/**
|
|
190
|
+
* The font, off the **style** rather than off a prop of its own.
|
|
191
|
+
*
|
|
192
|
+
* `fontFamily` and `fontSize` are style properties, and core throws in
|
|
193
|
+
* development on an element that takes one as a flat prop — for good
|
|
194
|
+
* reason: a terminal inheriting the font from the tree above it is what
|
|
195
|
+
* makes `<box style={{ fontSize: 15 }}>` mean what it says. `<Terminal>`'s
|
|
196
|
+
* `fontFamily`/`fontSize` props are folded into this element's style.
|
|
197
|
+
*/
|
|
198
|
+
_fontStyle() {
|
|
199
|
+
const style = this.style;
|
|
200
|
+
return {
|
|
201
|
+
family: style.fontFamily ?? DEFAULT_FAMILY,
|
|
202
|
+
size: Number(style.fontSize ?? DEFAULT_SIZE),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
_fontSet() {
|
|
206
|
+
const { family, size } = this._fontStyle();
|
|
207
|
+
const key = `${family}|${size}`;
|
|
208
|
+
if (this._fonts && key === this._fontKey)
|
|
209
|
+
return this._fonts;
|
|
210
|
+
const fonts = this.app?.fonts;
|
|
211
|
+
if (!fonts)
|
|
212
|
+
return null;
|
|
213
|
+
this._fontKey = key;
|
|
214
|
+
this._fonts = new FontSet(fonts, family, size);
|
|
215
|
+
this._mirror.invalidate();
|
|
216
|
+
return this._fonts;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* 80×24, or as much of it as is on offer.
|
|
220
|
+
*
|
|
221
|
+
* A terminal in a dialog with nothing else to size it should be a terminal
|
|
222
|
+
* rather than a sliver; flex owns everything past that.
|
|
223
|
+
*/
|
|
224
|
+
measureContent({ width, height }) {
|
|
225
|
+
const fonts = this._fontSet();
|
|
226
|
+
const cellWidth = fonts?.metrics.cellWidth ?? DEFAULT_SIZE * 0.6;
|
|
227
|
+
const cellHeight = fonts?.metrics.cellHeight ?? DEFAULT_SIZE * 1.2;
|
|
228
|
+
return {
|
|
229
|
+
width: Math.min(PREFERRED_COLS * cellWidth, width),
|
|
230
|
+
height: Math.min(PREFERRED_ROWS * cellHeight, height),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/** Cells that fit the content box right now. */
|
|
234
|
+
gridSize() {
|
|
235
|
+
const fonts = this._fontSet();
|
|
236
|
+
const box = this.contentBox();
|
|
237
|
+
if (!fonts)
|
|
238
|
+
return { cols: PREFERRED_COLS, rows: PREFERRED_ROWS };
|
|
239
|
+
return {
|
|
240
|
+
cols: Math.max(1, Math.floor(box.width / fonts.metrics.cellWidth)),
|
|
241
|
+
rows: Math.max(1, Math.floor(box.height / fonts.metrics.cellHeight)),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Tell the component the grid changed, off the paint stack.
|
|
246
|
+
*
|
|
247
|
+
* `onGridResize` ends in `term.resize` and `pty.resize`, and both of those
|
|
248
|
+
* can synchronously produce output — running them inside paint would have
|
|
249
|
+
* the emulator writing to a buffer the renderer is halfway through reading.
|
|
250
|
+
*/
|
|
251
|
+
resizeToFit() {
|
|
252
|
+
const { cols, rows } = this.gridSize();
|
|
253
|
+
if (cols === this._reportedCols && rows === this._reportedRows)
|
|
254
|
+
return;
|
|
255
|
+
this._reportedCols = cols;
|
|
256
|
+
this._reportedRows = rows;
|
|
257
|
+
const notify = this._props().onGridResize;
|
|
258
|
+
if (notify)
|
|
259
|
+
microtask(() => !this.destroyed && notify(cols, rows));
|
|
260
|
+
}
|
|
261
|
+
get cols() {
|
|
262
|
+
return this._cols;
|
|
263
|
+
}
|
|
264
|
+
get rows() {
|
|
265
|
+
return this._rows;
|
|
266
|
+
}
|
|
267
|
+
// --- painting ------------------------------------------------------------
|
|
268
|
+
_repaint() {
|
|
269
|
+
if (this.destroyed)
|
|
270
|
+
return;
|
|
271
|
+
// The grid rect, not a tighter one: which cells are dirty is not known
|
|
272
|
+
// until the diff runs inside paint. Damage is a clip and a cull bound
|
|
273
|
+
// rather than a promise to redraw everything, and the diff still decides
|
|
274
|
+
// what is *rendered* — which is where the cost is.
|
|
275
|
+
this.invalidate(false, this, 'text');
|
|
276
|
+
}
|
|
277
|
+
paint(ctx) {
|
|
278
|
+
// background, border, and the clip to this node's rect
|
|
279
|
+
super.paint(ctx);
|
|
280
|
+
const fonts = this._fontSet();
|
|
281
|
+
if (!fonts)
|
|
282
|
+
return;
|
|
283
|
+
// Before the `term` check on purpose: the component sizes the emulator it
|
|
284
|
+
// is still building from what this reports, so the first layout has to
|
|
285
|
+
// reach it even though there is nothing to draw yet.
|
|
286
|
+
this.resizeToFit();
|
|
287
|
+
const term = this._term;
|
|
288
|
+
if (!term)
|
|
289
|
+
return;
|
|
290
|
+
const cell = ctx;
|
|
291
|
+
const renderer = this._ensureRenderer(cell);
|
|
292
|
+
if (!renderer)
|
|
293
|
+
return; // mock backend: no pixel API, so nothing to draw
|
|
294
|
+
const box = this.contentBox();
|
|
295
|
+
const { cellWidth, cellHeight } = fonts.metrics;
|
|
296
|
+
const fitCols = Math.max(1, Math.floor(box.width / cellWidth));
|
|
297
|
+
const fitRows = Math.max(1, Math.floor(box.height / cellHeight));
|
|
298
|
+
// The emulator resizes a beat later (through the component, off this
|
|
299
|
+
// stack), so draw the intersection until it catches up.
|
|
300
|
+
const cols = Math.max(1, Math.min(fitCols, term.cols));
|
|
301
|
+
const rows = Math.max(1, Math.min(fitRows, term.rows));
|
|
302
|
+
this._cols = cols;
|
|
303
|
+
this._rows = rows;
|
|
304
|
+
if (!renderer.ensure(cols, rows, fonts.metrics))
|
|
305
|
+
this._mirror.invalidate();
|
|
306
|
+
if (!this._snapshot ||
|
|
307
|
+
this._snapshot.cols !== cols ||
|
|
308
|
+
this._snapshot.rows !== rows) {
|
|
309
|
+
this._snapshot = createSnapshot(cols, rows);
|
|
310
|
+
this._mirror.invalidate();
|
|
311
|
+
}
|
|
312
|
+
const snapshot = readViewport(term, this._snapshot, {
|
|
313
|
+
palette: this._palette,
|
|
314
|
+
selection: this._selection,
|
|
315
|
+
cursor: this._cursorState(term, rows),
|
|
316
|
+
brightBold: term.options.drawBoldTextInBrightColors !== false,
|
|
317
|
+
}, this._workCell ?? undefined);
|
|
318
|
+
const result = this._mirror.diff(snapshot);
|
|
319
|
+
renderer.begin(cell, {
|
|
320
|
+
originX: box.x,
|
|
321
|
+
originY: box.y,
|
|
322
|
+
cols,
|
|
323
|
+
rows,
|
|
324
|
+
metrics: fonts.metrics,
|
|
325
|
+
});
|
|
326
|
+
if (result.copy) {
|
|
327
|
+
const { srcRow, dstRow, count } = result.copy;
|
|
328
|
+
if (!renderer.copyRows(srcRow, dstRow, count)) {
|
|
329
|
+
// No buffer to move pixels inside: the mirror already moved, so drop
|
|
330
|
+
// it and take a full repaint on the next frame rather than believing
|
|
331
|
+
// a copy that did not happen.
|
|
332
|
+
this._mirror.invalidate();
|
|
333
|
+
this._repaint();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
for (const span of result.spans) {
|
|
337
|
+
this._drawSpan(renderer, snapshot, span, fonts);
|
|
338
|
+
}
|
|
339
|
+
renderer.end();
|
|
340
|
+
}
|
|
341
|
+
_ensureRenderer(ctx) {
|
|
342
|
+
if (this._renderer)
|
|
343
|
+
return this._renderer;
|
|
344
|
+
// `react-x11/ntk` types its re-exports loosely on purpose — ntk ships no
|
|
345
|
+
// types of its own — so the shape this element needs is the structural
|
|
346
|
+
// one in `./renderer.ts`, and this is the one cast that says so.
|
|
347
|
+
this._renderer = createRenderer(this.app, ctx, (Surface ?? null));
|
|
348
|
+
if (this._renderer?.kind === 'direct') {
|
|
349
|
+
// Nothing is retained between frames: `Node.paint` fills this node's
|
|
350
|
+
// background before we draw, so every frame starts from an empty box.
|
|
351
|
+
this._mirror.invalidate();
|
|
352
|
+
}
|
|
353
|
+
return this._renderer;
|
|
354
|
+
}
|
|
355
|
+
_cursorState(term, rows) {
|
|
356
|
+
const buffer = term.buffer.active;
|
|
357
|
+
const row = buffer.baseY + buffer.cursorY - buffer.viewportY;
|
|
358
|
+
const props = this._props();
|
|
359
|
+
let shape = props.cursorStyle ?? term.options.cursorStyle ?? 'block';
|
|
360
|
+
if (!this._focused)
|
|
361
|
+
shape = 'hollow';
|
|
362
|
+
else if (!this._cursorOn)
|
|
363
|
+
shape = 'none';
|
|
364
|
+
if (row < 0 || row >= rows || buffer.cursorX >= term.cols) {
|
|
365
|
+
shape = 'none';
|
|
366
|
+
}
|
|
367
|
+
return { col: buffer.cursorX, row, shape };
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* One dirty span, as three passes over the same cells: backgrounds merged
|
|
371
|
+
* into runs of one colour, one glyph run per non-blank cell, then the
|
|
372
|
+
* decorations. The renderer batches each pass into a single request per
|
|
373
|
+
* colour, so a span of 80 cells is a handful of requests however many
|
|
374
|
+
* colours it carries.
|
|
375
|
+
*/
|
|
376
|
+
_drawSpan(renderer, snapshot, span, fonts) {
|
|
377
|
+
const { row, col, count } = span;
|
|
378
|
+
const base = row * snapshot.cols;
|
|
379
|
+
const end = col + count;
|
|
380
|
+
let start = col;
|
|
381
|
+
let bg = snapshot.bg[base + col];
|
|
382
|
+
for (let i = col + 1; i < end; i++) {
|
|
383
|
+
const next = snapshot.bg[base + i];
|
|
384
|
+
if (next !== bg) {
|
|
385
|
+
renderer.fillCells(row, start, i - start, bg);
|
|
386
|
+
start = i;
|
|
387
|
+
bg = next;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
renderer.fillCells(row, start, end - start, bg);
|
|
391
|
+
for (let i = col; i < end; i++) {
|
|
392
|
+
const index = base + i;
|
|
393
|
+
// Width 0 is the second half of a wide glyph: its background is part of
|
|
394
|
+
// the run above, and its glyph was drawn at the cell before it.
|
|
395
|
+
if (snapshot.width[index] === 0)
|
|
396
|
+
continue;
|
|
397
|
+
const chars = snapshot.chars[index];
|
|
398
|
+
if (!chars || chars === ' ')
|
|
399
|
+
continue;
|
|
400
|
+
const flags = snapshot.flags[index];
|
|
401
|
+
const run = fonts.run(chars, variantOf((flags & VARIANT_BOLD) !== 0, (flags & VARIANT_ITALIC) !== 0));
|
|
402
|
+
if (run)
|
|
403
|
+
renderer.drawRun(row, i, run, snapshot.fg[index]);
|
|
404
|
+
}
|
|
405
|
+
this._decorateSpan(renderer, snapshot, row, col, end);
|
|
406
|
+
this._drawCursor(renderer, row, col, end);
|
|
407
|
+
}
|
|
408
|
+
_decorateSpan(renderer, snapshot, row, col, end) {
|
|
409
|
+
const base = row * snapshot.cols;
|
|
410
|
+
const DECO = DECO_UNDERLINE | DECO_STRIKE | DECO_OVERLINE;
|
|
411
|
+
let runStart = -1;
|
|
412
|
+
let runDeco = 0;
|
|
413
|
+
let runFg = 0;
|
|
414
|
+
const flush = (until) => {
|
|
415
|
+
if (runStart < 0 || !runDeco)
|
|
416
|
+
return;
|
|
417
|
+
const count = until - runStart;
|
|
418
|
+
if (runDeco & DECO_UNDERLINE) {
|
|
419
|
+
renderer.decorate(row, runStart, count, 'underline', runFg);
|
|
420
|
+
}
|
|
421
|
+
if (runDeco & DECO_STRIKE) {
|
|
422
|
+
renderer.decorate(row, runStart, count, 'strike', runFg);
|
|
423
|
+
}
|
|
424
|
+
if (runDeco & DECO_OVERLINE) {
|
|
425
|
+
renderer.decorate(row, runStart, count, 'overline', runFg);
|
|
426
|
+
}
|
|
427
|
+
runStart = -1;
|
|
428
|
+
};
|
|
429
|
+
for (let i = col; i < end; i++) {
|
|
430
|
+
const deco = snapshot.flags[base + i] & DECO;
|
|
431
|
+
const fg = snapshot.fg[base + i];
|
|
432
|
+
if (deco !== runDeco || fg !== runFg) {
|
|
433
|
+
flush(i);
|
|
434
|
+
runDeco = deco;
|
|
435
|
+
runFg = fg;
|
|
436
|
+
runStart = deco ? i : -1;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
flush(end);
|
|
440
|
+
}
|
|
441
|
+
/** The shapes a colour swap cannot express: bar, underline, and the hollow
|
|
442
|
+
* box an unfocused terminal draws. */
|
|
443
|
+
_drawCursor(renderer, row, col, end) {
|
|
444
|
+
const term = this._term;
|
|
445
|
+
if (!term)
|
|
446
|
+
return;
|
|
447
|
+
const state = this._cursorState(term, this._rows);
|
|
448
|
+
if (state.row !== row || state.col < col || state.col >= end)
|
|
449
|
+
return;
|
|
450
|
+
switch (state.shape) {
|
|
451
|
+
case 'bar':
|
|
452
|
+
renderer.decorate(row, state.col, 1, 'bar', this._palette.cursor);
|
|
453
|
+
break;
|
|
454
|
+
case 'underline':
|
|
455
|
+
renderer.decorate(row, state.col, 1, 'cursorUnderline', this._palette.cursor);
|
|
456
|
+
break;
|
|
457
|
+
case 'hollow':
|
|
458
|
+
renderer.decorate(row, state.col, 1, 'box', this._palette.cursor);
|
|
459
|
+
break;
|
|
460
|
+
default:
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
// --- focus and the cursor blink ------------------------------------------
|
|
465
|
+
defaultFocus() {
|
|
466
|
+
this._focused = true;
|
|
467
|
+
this._cursorOn = true;
|
|
468
|
+
this._syncBlink();
|
|
469
|
+
this._reportFocus(true);
|
|
470
|
+
this._repaint();
|
|
471
|
+
}
|
|
472
|
+
defaultBlur() {
|
|
473
|
+
this._focused = false;
|
|
474
|
+
this._cursorOn = true;
|
|
475
|
+
this._syncBlink();
|
|
476
|
+
this._reportFocus(false);
|
|
477
|
+
this._repaint();
|
|
478
|
+
}
|
|
479
|
+
_reportFocus(focused) {
|
|
480
|
+
if (this._term?.modes.sendFocusMode) {
|
|
481
|
+
this._send(focused ? '\x1b[I' : '\x1b[O');
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
_syncBlink() {
|
|
485
|
+
stopInterval(this._blink);
|
|
486
|
+
this._blink = null;
|
|
487
|
+
const blink = this._props().cursorBlink !== false;
|
|
488
|
+
if (!this._focused || !blink) {
|
|
489
|
+
this._cursorOn = true;
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
// Core's own interval, so two carets on one screen are in step.
|
|
493
|
+
this._blink = startInterval(() => {
|
|
494
|
+
this._cursorOn = !this._cursorOn;
|
|
495
|
+
this._repaint();
|
|
496
|
+
}, CARET_BLINK_MS);
|
|
497
|
+
}
|
|
498
|
+
// --- input: keyboard -----------------------------------------------------
|
|
499
|
+
/**
|
|
500
|
+
* The terminal's own key behaviour, run after the application's `onKeyDown`
|
|
501
|
+
* handlers and not at all if one of them called `preventDefault()` — so an
|
|
502
|
+
* app-level chord still beats the terminal, the same bargain the XEmbed
|
|
503
|
+
* path documents.
|
|
504
|
+
*
|
|
505
|
+
* **Tab and the way out.** Core cycles focus on Tab before default actions,
|
|
506
|
+
* and a terminal that consumes Tab owes the keyboard user an exit. The
|
|
507
|
+
* convention `docs/extending.md` asks for is "Escape arms one pass-through
|
|
508
|
+
* Tab", with one terminal-specific twist: Escape is *also* still sent to the
|
|
509
|
+
* program (arming is a side effect, not a swallow), and arming is off while
|
|
510
|
+
* the alternate screen is up — a full-screen vim owns Esc-then-Tab as real
|
|
511
|
+
* input, and a focus-trapped full-screen application is the expected shape.
|
|
512
|
+
* The pointer always leaves.
|
|
513
|
+
*/
|
|
514
|
+
defaultKeyDown(ev) {
|
|
515
|
+
const term = this._term;
|
|
516
|
+
if (!term)
|
|
517
|
+
return;
|
|
518
|
+
if (this._clipboardChord(ev)) {
|
|
519
|
+
ev.preventDefault();
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
if (ev.keysym === XK_TAB && this._tabEscapes) {
|
|
523
|
+
this._tabEscapes = false;
|
|
524
|
+
return; // this one belongs to the focus cycle
|
|
525
|
+
}
|
|
526
|
+
this._tabEscapes =
|
|
527
|
+
ev.keysym === XK_ESCAPE && term.buffer.active.type !== 'alternate';
|
|
528
|
+
const bytes = encodeKey(ev, term.modes);
|
|
529
|
+
if (bytes === null)
|
|
530
|
+
return;
|
|
531
|
+
this._typed();
|
|
532
|
+
this._send(bytes);
|
|
533
|
+
ev.preventDefault();
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* The clipboard chords, and why a terminal's are not everyone else's.
|
|
537
|
+
*
|
|
538
|
+
* **Ctrl+C and Ctrl+V are not available.** Ctrl+C is SIGINT — the single
|
|
539
|
+
* most-pressed key in a terminal — and Ctrl+V is readline's literal-next.
|
|
540
|
+
* Both have to reach the program, so every terminal since xterm spells the
|
|
541
|
+
* clipboard with Shift: **Ctrl+Shift+C / Ctrl+Shift+V**, which is what
|
|
542
|
+
* gnome-terminal, konsole, kitty and alacritty all use.
|
|
543
|
+
*
|
|
544
|
+
* Three more are accepted because they cost the program nothing:
|
|
545
|
+
*
|
|
546
|
+
* - **Super+C / Super+V** (Command on a Mac keyboard under XQuartz).
|
|
547
|
+
* `keys.ts` never forwards a Super chord — those belong to the desktop —
|
|
548
|
+
* so nothing is taken from the program by answering them here, and it is
|
|
549
|
+
* the chord a Mac user's fingers already know.
|
|
550
|
+
* - **Shift+Insert** pastes PRIMARY and **Ctrl+Insert** copies to
|
|
551
|
+
* CLIPBOARD: the X convention that predates all of the above and still
|
|
552
|
+
* works everywhere.
|
|
553
|
+
* - **Ctrl+Shift+A** selects the screen. (Not Ctrl+A: that is
|
|
554
|
+
* beginning-of-line, and readline wants it.)
|
|
555
|
+
*
|
|
556
|
+
* The letter comes from core's `ctrlChordLetter`, which is public for
|
|
557
|
+
* exactly this and gets the subtlety right — ntk derives `codepoint` from
|
|
558
|
+
* the *shifted* keysym, so Ctrl+Shift+V arrives as `V` and Ctrl+V as `v`,
|
|
559
|
+
* while the keysym does not shift.
|
|
560
|
+
*/
|
|
561
|
+
_clipboardChord(ev) {
|
|
562
|
+
if (ev.keysym === XK_INSERT && (ev.shiftKey || ev.ctrlKey)) {
|
|
563
|
+
if (ev.shiftKey)
|
|
564
|
+
this.paste('PRIMARY');
|
|
565
|
+
else
|
|
566
|
+
this.copySelection();
|
|
567
|
+
return true;
|
|
568
|
+
}
|
|
569
|
+
const clipboardModifier = (ev.ctrlKey && ev.shiftKey) || ev.metaKey;
|
|
570
|
+
if (!clipboardModifier)
|
|
571
|
+
return false;
|
|
572
|
+
switch (ctrlChordLetter(ev)) {
|
|
573
|
+
case 0x63: // c
|
|
574
|
+
this.copySelection();
|
|
575
|
+
return true;
|
|
576
|
+
case 0x76: // v
|
|
577
|
+
this.paste('CLIPBOARD');
|
|
578
|
+
return true;
|
|
579
|
+
case 0x61: // a
|
|
580
|
+
this.selectAll();
|
|
581
|
+
return true;
|
|
582
|
+
default:
|
|
583
|
+
return false;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* A dead key or a Compose sequence finishing.
|
|
588
|
+
*
|
|
589
|
+
* Composition stays **on** for this element — unlike `<foreign>`, which
|
|
590
|
+
* turns it off because the embedded client has an input method of its own.
|
|
591
|
+
* Here there is no other side: the keys a composition takes never reach
|
|
592
|
+
* `defaultKeyDown`, so without this the text a Compose sequence produced
|
|
593
|
+
* would be typed into nothing. Only the commit is sent; the preedit is not
|
|
594
|
+
* drawn, which is the honest state of IME support in this component (see
|
|
595
|
+
* the PRD's non-goals).
|
|
596
|
+
*/
|
|
597
|
+
defaultComposition(ev) {
|
|
598
|
+
if (ev.type !== 'compositionEnd' || !ev.data)
|
|
599
|
+
return;
|
|
600
|
+
this._typed();
|
|
601
|
+
this._send(ev.data);
|
|
602
|
+
}
|
|
603
|
+
/** Input scrolls back to the prompt and drops the selection, like every
|
|
604
|
+
* other terminal. */
|
|
605
|
+
_typed() {
|
|
606
|
+
const term = this._term;
|
|
607
|
+
if (!term)
|
|
608
|
+
return;
|
|
609
|
+
if (term.buffer.active.viewportY !== term.buffer.active.baseY) {
|
|
610
|
+
term.scrollToBottom();
|
|
611
|
+
}
|
|
612
|
+
if (this._selection)
|
|
613
|
+
this.clearSelection();
|
|
614
|
+
}
|
|
615
|
+
_send(data) {
|
|
616
|
+
if (!data)
|
|
617
|
+
return;
|
|
618
|
+
this._props().onInput?.(data);
|
|
619
|
+
}
|
|
620
|
+
// --- input: pointer ------------------------------------------------------
|
|
621
|
+
_cellAt(ev) {
|
|
622
|
+
const fonts = this._fontSet();
|
|
623
|
+
const box = this.contentBox();
|
|
624
|
+
const cellWidth = fonts?.metrics.cellWidth ?? 1;
|
|
625
|
+
const cellHeight = fonts?.metrics.cellHeight ?? 1;
|
|
626
|
+
const col = Math.floor((ev.x - box.x) / cellWidth);
|
|
627
|
+
const row = Math.floor((ev.y - box.y) / cellHeight);
|
|
628
|
+
return {
|
|
629
|
+
col: Math.max(0, Math.min(this._cols - 1, col)),
|
|
630
|
+
row: Math.max(0, Math.min(this._rows - 1, row)),
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
_absLine(row) {
|
|
634
|
+
return (this._term?.buffer.active.viewportY ?? 0) + row;
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Whether this gesture belongs to the program rather than to the user.
|
|
638
|
+
*
|
|
639
|
+
* Shift is the universal override: an application that grabbed the mouse
|
|
640
|
+
* still has to let the user select text, and Shift is how every terminal
|
|
641
|
+
* spells that.
|
|
642
|
+
*/
|
|
643
|
+
_reporting(ev) {
|
|
644
|
+
const tracking = this._term?.modes.mouseTrackingMode ?? 'none';
|
|
645
|
+
return tracking !== 'none' && !ev.shiftKey;
|
|
646
|
+
}
|
|
647
|
+
defaultMouseDown(ev) {
|
|
648
|
+
const term = this._term;
|
|
649
|
+
if (!term)
|
|
650
|
+
return;
|
|
651
|
+
this.focus();
|
|
652
|
+
const { col, row } = this._cellAt(ev);
|
|
653
|
+
if (ev.button === 2 && !this._reporting(ev)) {
|
|
654
|
+
// The X convention: middle-click pastes PRIMARY, as `<textinput>` and
|
|
655
|
+
// `<codeeditor>` do.
|
|
656
|
+
this.paste('PRIMARY');
|
|
657
|
+
ev.preventDefault();
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
if (this._reporting(ev)) {
|
|
661
|
+
this._send(encodeMouse({
|
|
662
|
+
kind: 'down',
|
|
663
|
+
button: ev.button,
|
|
664
|
+
col,
|
|
665
|
+
row,
|
|
666
|
+
shiftKey: ev.shiftKey,
|
|
667
|
+
altKey: ev.altKey,
|
|
668
|
+
ctrlKey: ev.ctrlKey,
|
|
669
|
+
pressed: true,
|
|
670
|
+
}, {
|
|
671
|
+
tracking: term.modes.mouseTrackingMode,
|
|
672
|
+
encoding: this._mouseEncoding,
|
|
673
|
+
}) ?? '');
|
|
674
|
+
// A program in `drag` or `any` tracking wants the motion that follows,
|
|
675
|
+
// including the part of it that leaves this element — which is what
|
|
676
|
+
// capturing the pointer is for.
|
|
677
|
+
ev.capturePointer();
|
|
678
|
+
ev.preventDefault();
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
if (ev.button !== 1)
|
|
682
|
+
return;
|
|
683
|
+
const line = this._absLine(row);
|
|
684
|
+
this._dragMode =
|
|
685
|
+
ev.detail >= 3 ? 'line' : ev.detail === 2 ? 'word' : 'char';
|
|
686
|
+
if (ev.shiftKey && this._anchor) {
|
|
687
|
+
this._head = { line, col };
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
this._anchor = { line, col };
|
|
691
|
+
this._head = { line, col };
|
|
692
|
+
}
|
|
693
|
+
this._updateSelection();
|
|
694
|
+
ev.capturePointer();
|
|
695
|
+
ev.preventDefault();
|
|
696
|
+
}
|
|
697
|
+
defaultMouseDrag(ev) {
|
|
698
|
+
const term = this._term;
|
|
699
|
+
if (!term)
|
|
700
|
+
return;
|
|
701
|
+
const { col, row } = this._cellAt(ev);
|
|
702
|
+
if (this._dragMode === null) {
|
|
703
|
+
if (this._reporting(ev)) {
|
|
704
|
+
this._send(encodeMouse({
|
|
705
|
+
kind: 'move',
|
|
706
|
+
button: ev.button,
|
|
707
|
+
col,
|
|
708
|
+
row,
|
|
709
|
+
shiftKey: ev.shiftKey,
|
|
710
|
+
altKey: ev.altKey,
|
|
711
|
+
ctrlKey: ev.ctrlKey,
|
|
712
|
+
pressed: true,
|
|
713
|
+
}, {
|
|
714
|
+
tracking: term.modes.mouseTrackingMode,
|
|
715
|
+
encoding: this._mouseEncoding,
|
|
716
|
+
}) ?? '');
|
|
717
|
+
}
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
// Dragging past an edge scrolls the scrollback under the pointer.
|
|
721
|
+
const box = this.contentBox();
|
|
722
|
+
if (ev.y < box.y)
|
|
723
|
+
term.scrollLines(-1);
|
|
724
|
+
else if (ev.y > box.y + box.height)
|
|
725
|
+
term.scrollLines(1);
|
|
726
|
+
this._head = { line: this._absLine(row), col };
|
|
727
|
+
this._updateSelection();
|
|
728
|
+
}
|
|
729
|
+
defaultMouseUp(ev) {
|
|
730
|
+
const term = this._term;
|
|
731
|
+
if (term && this._dragMode === null && this._reporting(ev)) {
|
|
732
|
+
const { col, row } = this._cellAt(ev);
|
|
733
|
+
this._send(encodeMouse({
|
|
734
|
+
kind: 'up',
|
|
735
|
+
button: ev.button,
|
|
736
|
+
col,
|
|
737
|
+
row,
|
|
738
|
+
shiftKey: ev.shiftKey,
|
|
739
|
+
altKey: ev.altKey,
|
|
740
|
+
ctrlKey: ev.ctrlKey,
|
|
741
|
+
pressed: false,
|
|
742
|
+
}, {
|
|
743
|
+
tracking: term.modes.mouseTrackingMode,
|
|
744
|
+
encoding: this._mouseEncoding,
|
|
745
|
+
}) ?? '');
|
|
746
|
+
ev.releasePointer();
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
if (this._dragMode === null)
|
|
750
|
+
return;
|
|
751
|
+
this._dragMode = null;
|
|
752
|
+
ev.releasePointer?.();
|
|
753
|
+
const text = this.selectionText();
|
|
754
|
+
if (text) {
|
|
755
|
+
// PRIMARY on selection end, which is what the middle button pastes.
|
|
756
|
+
this._clipboard()
|
|
757
|
+
?.write(text, { selection: 'PRIMARY' })
|
|
758
|
+
.catch(() => { });
|
|
759
|
+
this._props().onSelectionChange?.(text);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* The wheel. No default-action seam exists for it, so the component wires
|
|
764
|
+
* `onWheel` to this — the same shape `<CodeEditor>` uses.
|
|
765
|
+
*/
|
|
766
|
+
handleWheel(ev) {
|
|
767
|
+
const term = this._term;
|
|
768
|
+
if (!term)
|
|
769
|
+
return false;
|
|
770
|
+
const notches = Math.round(ev.deltaY / 48) || (ev.deltaY > 0 ? 1 : -1);
|
|
771
|
+
const lines = notches * WHEEL_LINES;
|
|
772
|
+
if (this._reporting(ev)) {
|
|
773
|
+
const { col, row } = this._cellAt(ev);
|
|
774
|
+
this._send(encodeMouse({
|
|
775
|
+
kind: 'wheel',
|
|
776
|
+
button: 0,
|
|
777
|
+
deltaY: ev.deltaY,
|
|
778
|
+
col,
|
|
779
|
+
row,
|
|
780
|
+
shiftKey: ev.shiftKey,
|
|
781
|
+
altKey: ev.altKey,
|
|
782
|
+
ctrlKey: ev.ctrlKey,
|
|
783
|
+
pressed: false,
|
|
784
|
+
}, {
|
|
785
|
+
tracking: term.modes.mouseTrackingMode,
|
|
786
|
+
encoding: this._mouseEncoding,
|
|
787
|
+
}) ?? '');
|
|
788
|
+
return true;
|
|
789
|
+
}
|
|
790
|
+
if (term.buffer.active.type === 'alternate') {
|
|
791
|
+
// An alternate-screen application has no scrollback of its own, so the
|
|
792
|
+
// wheel becomes arrow keys — which is what makes `less` and `man`
|
|
793
|
+
// scroll (DECSET 1007).
|
|
794
|
+
if (!this._alternateScroll)
|
|
795
|
+
return false;
|
|
796
|
+
this._send(encodeAlternateScroll(Math.abs(lines), lines < 0, term.modes.applicationCursorKeysMode));
|
|
797
|
+
return true;
|
|
798
|
+
}
|
|
799
|
+
term.scrollLines(lines);
|
|
800
|
+
this._repaint();
|
|
801
|
+
return true;
|
|
802
|
+
}
|
|
803
|
+
// --- selection -----------------------------------------------------------
|
|
804
|
+
_updateSelection() {
|
|
805
|
+
const term = this._term;
|
|
806
|
+
if (!term || !this._anchor || !this._head)
|
|
807
|
+
return;
|
|
808
|
+
let { line: aLine, col: aCol } = this._anchor;
|
|
809
|
+
let { line: hLine, col: hCol } = this._head;
|
|
810
|
+
if (this._dragMode === 'line') {
|
|
811
|
+
aCol = 0;
|
|
812
|
+
hCol = term.cols;
|
|
813
|
+
}
|
|
814
|
+
else if (this._dragMode === 'word') {
|
|
815
|
+
const a = this._wordRange(aLine, aCol);
|
|
816
|
+
const h = this._wordRange(hLine, hCol);
|
|
817
|
+
const forward = hLine > aLine || (hLine === aLine && hCol >= aCol);
|
|
818
|
+
aCol = forward ? a.from : a.to;
|
|
819
|
+
hCol = forward ? h.to : h.from;
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
// A drag selects up to *and including* the cell the pointer is over
|
|
823
|
+
// when it moved forwards, which is what makes selecting one character
|
|
824
|
+
// possible at all.
|
|
825
|
+
const forward = hLine > aLine || (hLine === aLine && hCol >= aCol);
|
|
826
|
+
if (forward)
|
|
827
|
+
hCol += 1;
|
|
828
|
+
}
|
|
829
|
+
this._selection = orderSelection(aLine, aCol, hLine, hCol);
|
|
830
|
+
this._repaint();
|
|
831
|
+
}
|
|
832
|
+
_wordRange(line, col) {
|
|
833
|
+
const text = this._term?.buffer.active.getLine(line)?.translateToString();
|
|
834
|
+
if (!text)
|
|
835
|
+
return { from: col, to: col + 1 };
|
|
836
|
+
let from = col;
|
|
837
|
+
let to = col + 1;
|
|
838
|
+
if (!WORD_CHAR.test(text.charAt(col) || ' '))
|
|
839
|
+
return { from, to };
|
|
840
|
+
while (from > 0 && WORD_CHAR.test(text.charAt(from - 1)))
|
|
841
|
+
from--;
|
|
842
|
+
while (to < text.length && WORD_CHAR.test(text.charAt(to)))
|
|
843
|
+
to++;
|
|
844
|
+
return { from, to };
|
|
845
|
+
}
|
|
846
|
+
/** The selected text, reflow-true: a wrapped line joins with no newline. */
|
|
847
|
+
selectionText() {
|
|
848
|
+
const term = this._term;
|
|
849
|
+
const selection = this._selection;
|
|
850
|
+
if (!term || !selection)
|
|
851
|
+
return null;
|
|
852
|
+
const buffer = term.buffer.active;
|
|
853
|
+
let out = '';
|
|
854
|
+
for (let line = selection.startLine; line <= selection.endLine; line++) {
|
|
855
|
+
const buffered = buffer.getLine(line);
|
|
856
|
+
if (!buffered)
|
|
857
|
+
continue;
|
|
858
|
+
const from = line === selection.startLine ? selection.startCol : 0;
|
|
859
|
+
const to = line === selection.endLine ? selection.endCol : term.cols;
|
|
860
|
+
const next = buffer.getLine(line + 1);
|
|
861
|
+
const wrapped = line < selection.endLine && next?.isWrapped === true;
|
|
862
|
+
out += buffered.translateToString(!wrapped, from, to);
|
|
863
|
+
if (line < selection.endLine && !wrapped)
|
|
864
|
+
out += '\n';
|
|
865
|
+
}
|
|
866
|
+
return out.length ? out : null;
|
|
867
|
+
}
|
|
868
|
+
// `: this`, matching the base declarations core grew in #294 — a subclass
|
|
869
|
+
// narrowing them to void stops being structurally a DrawnNode.
|
|
870
|
+
clearSelection() {
|
|
871
|
+
if (!this._selection && !this._anchor)
|
|
872
|
+
return this;
|
|
873
|
+
this._selection = null;
|
|
874
|
+
this._anchor = null;
|
|
875
|
+
this._head = null;
|
|
876
|
+
this._dragMode = null;
|
|
877
|
+
this._repaint();
|
|
878
|
+
return this;
|
|
879
|
+
}
|
|
880
|
+
selectAll() {
|
|
881
|
+
const term = this._term;
|
|
882
|
+
if (!term)
|
|
883
|
+
return this;
|
|
884
|
+
this._selection = {
|
|
885
|
+
startLine: 0,
|
|
886
|
+
startCol: 0,
|
|
887
|
+
endLine: term.buffer.active.length - 1,
|
|
888
|
+
endCol: term.cols,
|
|
889
|
+
};
|
|
890
|
+
this._repaint();
|
|
891
|
+
return this;
|
|
892
|
+
}
|
|
893
|
+
// --- clipboard -----------------------------------------------------------
|
|
894
|
+
_clipboard() {
|
|
895
|
+
return (this.app
|
|
896
|
+
?.clipboard ?? null);
|
|
897
|
+
}
|
|
898
|
+
copySelection(selection = 'CLIPBOARD') {
|
|
899
|
+
const text = this.selectionText();
|
|
900
|
+
if (!text)
|
|
901
|
+
return;
|
|
902
|
+
this._clipboard()
|
|
903
|
+
?.write(text, { selection })
|
|
904
|
+
.catch(() => { });
|
|
905
|
+
}
|
|
906
|
+
paste(selection = 'CLIPBOARD') {
|
|
907
|
+
const term = this._term;
|
|
908
|
+
if (!term)
|
|
909
|
+
return;
|
|
910
|
+
this._clipboard()
|
|
911
|
+
?.read({ selection })
|
|
912
|
+
.then((text) => {
|
|
913
|
+
if (this.destroyed || typeof text !== 'string' || !text)
|
|
914
|
+
return;
|
|
915
|
+
this._typed();
|
|
916
|
+
this._send(encodePaste(text, term.modes.bracketedPasteMode));
|
|
917
|
+
})
|
|
918
|
+
.catch(() => { });
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* OSC 52 — the program asking for the clipboard.
|
|
922
|
+
*
|
|
923
|
+
* **Writes** are honoured (that is how `tmux`, `vim` and `nvim` copy out of
|
|
924
|
+
* an ssh session, and it is the whole point of the sequence), capped, and
|
|
925
|
+
* CLIPBOARD only. **Reads are answered with nothing, always**: replying
|
|
926
|
+
* would hand whatever the user last copied — a password, a token — to a
|
|
927
|
+
* program that merely printed eight bytes, so the answer is the same one
|
|
928
|
+
* kitty and iTerm ship by default.
|
|
929
|
+
*/
|
|
930
|
+
_onOsc52(data) {
|
|
931
|
+
if (this._props().allowClipboardWrite === false)
|
|
932
|
+
return true;
|
|
933
|
+
const semi = data.indexOf(';');
|
|
934
|
+
if (semi < 0)
|
|
935
|
+
return true;
|
|
936
|
+
const payload = data.slice(semi + 1);
|
|
937
|
+
if (payload === '?' || payload.length > MAX_OSC52)
|
|
938
|
+
return true;
|
|
939
|
+
const text = decodeBase64(payload);
|
|
940
|
+
if (text === null)
|
|
941
|
+
return true;
|
|
942
|
+
this._clipboard()
|
|
943
|
+
?.write(text, { selection: 'CLIPBOARD' })
|
|
944
|
+
.catch(() => { });
|
|
945
|
+
return true;
|
|
946
|
+
}
|
|
947
|
+
// --- the handle's half ---------------------------------------------------
|
|
948
|
+
scrollLines(amount) {
|
|
949
|
+
this._term?.scrollLines(amount);
|
|
950
|
+
this._repaint();
|
|
951
|
+
}
|
|
952
|
+
scrollToBottom() {
|
|
953
|
+
this._term?.scrollToBottom();
|
|
954
|
+
this._repaint();
|
|
955
|
+
}
|
|
956
|
+
/** The visible screen as text — "copy all", and what the tests read. */
|
|
957
|
+
serialize() {
|
|
958
|
+
const term = this._term;
|
|
959
|
+
if (!term)
|
|
960
|
+
return null;
|
|
961
|
+
const buffer = term.buffer.active;
|
|
962
|
+
const lines = [];
|
|
963
|
+
for (let row = 0; row < term.rows; row++) {
|
|
964
|
+
lines.push(buffer.getLine(buffer.viewportY + row)?.translateToString(true) ?? '');
|
|
965
|
+
}
|
|
966
|
+
// Trailing blank lines are the empty part of the screen, not content.
|
|
967
|
+
while (lines.length && lines[lines.length - 1] === '')
|
|
968
|
+
lines.pop();
|
|
969
|
+
return lines.join('\n');
|
|
970
|
+
}
|
|
971
|
+
/** The renderer in use, and what the last frame cost — the draw-op budget
|
|
972
|
+
* assertions read this. */
|
|
973
|
+
get rendererStats() {
|
|
974
|
+
const empty = {
|
|
975
|
+
fillRequests: 0,
|
|
976
|
+
glyphRequests: 0,
|
|
977
|
+
copies: 0,
|
|
978
|
+
blits: 0,
|
|
979
|
+
cellsFilled: 0,
|
|
980
|
+
glyphsDrawn: 0,
|
|
981
|
+
};
|
|
982
|
+
const renderer = this._renderer;
|
|
983
|
+
return {
|
|
984
|
+
kind: renderer?.kind ?? 'none',
|
|
985
|
+
stats: renderer?.stats ?? empty,
|
|
986
|
+
totals: renderer?.totals ?? { ...empty },
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* The visual bell as a palette, rather than as a second drawing path: the
|
|
992
|
+
* flash is background and foreground swapped, which every cell picks up
|
|
993
|
+
* through the ordinary resolve-and-diff and nothing else has to know about.
|
|
994
|
+
*/
|
|
995
|
+
function paletteColors(props) {
|
|
996
|
+
const colors = props.colors;
|
|
997
|
+
if (!props.inverted)
|
|
998
|
+
return colors;
|
|
999
|
+
return {
|
|
1000
|
+
...colors,
|
|
1001
|
+
background: colors?.foreground ?? '#e6e6e6',
|
|
1002
|
+
foreground: colors?.background ?? '#101014',
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
/** Everything about the palette that could change what a cell looks like. */
|
|
1006
|
+
function paletteKey(props) {
|
|
1007
|
+
const colors = props.colors;
|
|
1008
|
+
return [
|
|
1009
|
+
props.inverted ? 'inverted' : '',
|
|
1010
|
+
colors?.background ?? '',
|
|
1011
|
+
colors?.foreground ?? '',
|
|
1012
|
+
colors?.cursor ?? '',
|
|
1013
|
+
(colors?.palette ?? []).join(','),
|
|
1014
|
+
].join('|');
|
|
1015
|
+
}
|
|
1016
|
+
const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
1017
|
+
/**
|
|
1018
|
+
* Base64 to UTF-8, by hand.
|
|
1019
|
+
*
|
|
1020
|
+
* `atob` and `Buffer` are both globals the build may not name (`types: []`),
|
|
1021
|
+
* and reaching for one through `globalThis` for twenty lines of table lookup
|
|
1022
|
+
* is more machinery than the table.
|
|
1023
|
+
*/
|
|
1024
|
+
function decodeBase64(input) {
|
|
1025
|
+
const clean = input.replace(/[^A-Za-z0-9+/=]/g, '');
|
|
1026
|
+
const bytes = [];
|
|
1027
|
+
let buffer = 0;
|
|
1028
|
+
let bits = 0;
|
|
1029
|
+
for (const char of clean) {
|
|
1030
|
+
if (char === '=')
|
|
1031
|
+
break;
|
|
1032
|
+
const value = B64.indexOf(char);
|
|
1033
|
+
if (value < 0)
|
|
1034
|
+
return null;
|
|
1035
|
+
buffer = (buffer << 6) | value;
|
|
1036
|
+
bits += 6;
|
|
1037
|
+
if (bits >= 8) {
|
|
1038
|
+
bits -= 8;
|
|
1039
|
+
bytes.push((buffer >> bits) & 0xff);
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
// UTF-8 by hand too, for the same reason `TextDecoder` is not named here.
|
|
1043
|
+
let out = '';
|
|
1044
|
+
for (let i = 0; i < bytes.length;) {
|
|
1045
|
+
const b = bytes[i];
|
|
1046
|
+
let cp = b;
|
|
1047
|
+
let extra = 0;
|
|
1048
|
+
if (b >= 0xf0) {
|
|
1049
|
+
cp = b & 0x07;
|
|
1050
|
+
extra = 3;
|
|
1051
|
+
}
|
|
1052
|
+
else if (b >= 0xe0) {
|
|
1053
|
+
cp = b & 0x0f;
|
|
1054
|
+
extra = 2;
|
|
1055
|
+
}
|
|
1056
|
+
else if (b >= 0xc0) {
|
|
1057
|
+
cp = b & 0x1f;
|
|
1058
|
+
extra = 1;
|
|
1059
|
+
}
|
|
1060
|
+
i++;
|
|
1061
|
+
for (let k = 0; k < extra && i < bytes.length; k++, i++) {
|
|
1062
|
+
cp = (cp << 6) | (bytes[i] & 0x3f);
|
|
1063
|
+
}
|
|
1064
|
+
out += String.fromCodePoint(cp);
|
|
1065
|
+
}
|
|
1066
|
+
return out;
|
|
1067
|
+
}
|
|
1068
|
+
//# sourceMappingURL=node.js.map
|