xbintsc 0.5.23 → 0.5.32
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/AGENTS.md +11 -2
- package/README.md +47 -16
- package/README.zh-CN.md +21 -2
- package/dist/scripts/support-matrix.d.ts +18 -0
- package/dist/scripts/support-matrix.js +141 -0
- package/dist/scripts/support-matrix.js.map +1 -0
- package/dist/src/ast/common.d.ts +2 -2
- package/dist/src/ast/declarations.d.ts +7 -1
- package/dist/src/ast/expressions.d.ts +5 -0
- package/dist/src/ast/kinds.d.ts +2 -0
- package/dist/src/ast/kinds.js +2 -0
- package/dist/src/ast/kinds.js.map +1 -1
- package/dist/src/binder/binder.d.ts +2 -1
- package/dist/src/binder/binder.js +2 -0
- package/dist/src/binder/binder.js.map +1 -1
- package/dist/src/binder/declarations.d.ts +9 -0
- package/dist/src/binder/declarations.js +64 -0
- package/dist/src/binder/declarations.js.map +1 -1
- package/dist/src/binder/references.js +99 -4
- package/dist/src/binder/references.js.map +1 -1
- package/dist/src/binder/types.d.ts +32 -0
- package/dist/src/binder/types.js.map +1 -1
- package/dist/src/canonical.d.ts +29 -0
- package/dist/src/canonical.js +35 -0
- package/dist/src/canonical.js.map +1 -0
- package/dist/src/checker/assignability.d.ts +13 -0
- package/dist/src/checker/assignability.js +146 -0
- package/dist/src/checker/assignability.js.map +1 -0
- package/dist/src/checker/calls.d.ts +13 -0
- package/dist/src/checker/calls.js +127 -0
- package/dist/src/checker/calls.js.map +1 -0
- package/dist/src/checker/checker.d.ts +26 -0
- package/dist/src/checker/checker.js +31 -0
- package/dist/src/checker/checker.js.map +1 -0
- package/dist/src/checker/declarations.d.ts +9 -0
- package/dist/src/checker/declarations.js +15 -0
- package/dist/src/checker/declarations.js.map +1 -0
- package/dist/src/checker/flow.d.ts +21 -0
- package/dist/src/checker/flow.js +241 -0
- package/dist/src/checker/flow.js.map +1 -0
- package/dist/src/checker/globals.d.ts +9 -0
- package/dist/src/checker/globals.js +29 -0
- package/dist/src/checker/globals.js.map +1 -0
- package/dist/src/checker/source.d.ts +38 -0
- package/dist/src/checker/source.js +48 -0
- package/dist/src/checker/source.js.map +1 -0
- package/dist/src/checker/type-infer.d.ts +18 -0
- package/dist/src/checker/type-infer.js +173 -0
- package/dist/src/checker/type-infer.js.map +1 -0
- package/dist/src/checker/type-model.d.ts +73 -0
- package/dist/src/checker/type-model.js +151 -0
- package/dist/src/checker/type-model.js.map +1 -0
- package/dist/src/checker/type-system.d.ts +58 -0
- package/dist/src/checker/type-system.js +569 -0
- package/dist/src/checker/type-system.js.map +1 -0
- package/dist/src/checker/typecheck-types.d.ts +22 -0
- package/dist/src/checker/typecheck-types.js +109 -0
- package/dist/src/checker/typecheck-types.js.map +1 -0
- package/dist/src/checker/typecheck.d.ts +62 -0
- package/dist/src/checker/typecheck.js +574 -0
- package/dist/src/checker/typecheck.js.map +1 -0
- package/dist/src/checker/undefined.d.ts +14 -0
- package/dist/src/checker/undefined.js +32 -0
- package/dist/src/checker/undefined.js.map +1 -0
- package/dist/src/checker/walk.d.ts +10 -0
- package/dist/src/checker/walk.js +15 -0
- package/dist/src/checker/walk.js.map +1 -0
- package/dist/src/cli/help.d.ts +7 -0
- package/dist/src/cli/help.js +64 -0
- package/dist/src/cli/help.js.map +1 -0
- package/dist/src/cli/hints.js +2 -1
- package/dist/src/cli/hints.js.map +1 -1
- package/dist/src/cli/main.js +12 -48
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/calls/access.js +8 -8
- package/dist/src/codegen/generator/calls/access.js.map +1 -1
- package/dist/src/codegen/generator/calls/invocation.js +9 -4
- package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
- package/dist/src/codegen/generator/calls/super.d.ts +9 -1
- package/dist/src/codegen/generator/calls/super.js +56 -5
- package/dist/src/codegen/generator/calls/super.js.map +1 -1
- package/dist/src/codegen/generator/context.d.ts +13 -2
- package/dist/src/codegen/generator/context.js +25 -19
- package/dist/src/codegen/generator/context.js.map +1 -1
- package/dist/src/codegen/generator/debug.js +2 -1
- package/dist/src/codegen/generator/debug.js.map +1 -1
- package/dist/src/codegen/generator/expressions/primary.d.ts +4 -1
- package/dist/src/codegen/generator/expressions/primary.js +68 -8
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
- package/dist/src/codegen/generator/generator.js +11 -1
- package/dist/src/codegen/generator/generator.js.map +1 -1
- package/dist/src/codegen/generator/module.d.ts +3 -0
- package/dist/src/codegen/generator/module.js +116 -26
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/state.d.ts +11 -1
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/variables.js +26 -7
- package/dist/src/codegen/generator/statements/variables.js.map +1 -1
- package/dist/src/codegen/generator/tables.d.ts +2 -0
- package/dist/src/codegen/generator/tables.js +4 -0
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/driver/build-key.d.ts +2 -0
- package/dist/src/driver/build-key.js +1 -0
- package/dist/src/driver/build-key.js.map +1 -1
- package/dist/src/driver/bundler/graph.js +5 -1
- package/dist/src/driver/bundler/graph.js.map +1 -1
- package/dist/src/driver/bundler/merge.js +16 -1
- package/dist/src/driver/bundler/merge.js.map +1 -1
- package/dist/src/driver/bundler/types.d.ts +12 -0
- package/dist/src/driver/compiler.d.ts +1 -1
- package/dist/src/driver/compiler.js +3 -0
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/fingerprint.js +2 -1
- package/dist/src/driver/fingerprint.js.map +1 -1
- package/dist/src/driver/frontend.d.ts +8 -6
- package/dist/src/driver/frontend.js +4 -0
- package/dist/src/driver/frontend.js.map +1 -1
- package/dist/src/driver/options.d.ts +6 -0
- package/dist/src/driver/version.d.ts +1 -1
- package/dist/src/driver/version.js +1 -1
- package/dist/src/extensions/gui/css.d.ts +26 -0
- package/dist/src/extensions/gui/css.js +100 -0
- package/dist/src/extensions/gui/css.js.map +1 -0
- package/dist/src/extensions/gui/html.js +28 -7
- package/dist/src/extensions/gui/html.js.map +1 -1
- package/dist/src/extensions/gui/index.js +79 -2
- package/dist/src/extensions/gui/index.js.map +1 -1
- package/dist/src/extensions/gui/three.d.ts +16 -0
- package/dist/src/extensions/gui/three.js +22 -0
- package/dist/src/extensions/gui/three.js.map +1 -0
- package/dist/src/extensions/media/index.d.ts +6 -5
- package/dist/src/extensions/media/index.js +12 -14
- package/dist/src/extensions/media/index.js.map +1 -1
- package/dist/src/extensions/registry.d.ts +38 -0
- package/dist/src/extensions/registry.js +10 -0
- package/dist/src/extensions/registry.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/parser/declarations/classes.js +7 -0
- package/dist/src/parser/declarations/classes.js.map +1 -1
- package/dist/src/parser/expressions.js +14 -1
- package/dist/src/parser/expressions.js.map +1 -1
- package/dist/src/parser/literals.js +6 -2
- package/dist/src/parser/literals.js.map +1 -1
- package/dist/tests/binder/binder.test.js +29 -0
- package/dist/tests/binder/binder.test.js.map +1 -1
- package/dist/tests/canonical.test.d.ts +1 -0
- package/dist/tests/canonical.test.js +19 -0
- package/dist/tests/canonical.test.js.map +1 -0
- package/dist/tests/checker/checker.test.d.ts +1 -0
- package/dist/tests/checker/checker.test.js +245 -0
- package/dist/tests/checker/checker.test.js.map +1 -0
- package/dist/tests/cli/check.test.js +20 -0
- package/dist/tests/cli/check.test.js.map +1 -1
- package/dist/tests/conformance/matrix.test.d.ts +6 -0
- package/dist/tests/conformance/matrix.test.js +23 -0
- package/dist/tests/conformance/matrix.test.js.map +1 -0
- package/dist/tests/conformance/test262/manifest.d.ts +115 -0
- package/dist/tests/conformance/test262/manifest.js +257 -0
- package/dist/tests/conformance/test262/manifest.js.map +1 -0
- package/dist/tests/conformance/test262.test.d.ts +11 -0
- package/dist/tests/conformance/test262.test.js +74 -0
- package/dist/tests/conformance/test262.test.js.map +1 -0
- package/dist/tests/docs/structure.test.js +9 -11
- package/dist/tests/docs/structure.test.js.map +1 -1
- package/dist/tests/e2e/child-process.test.js +3 -2
- package/dist/tests/e2e/child-process.test.js.map +1 -1
- package/dist/tests/e2e/compile-builtins.test.js +45 -0
- package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
- package/dist/tests/e2e/compile-objects-classes.test.js +77 -0
- package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
- package/dist/tests/e2e/differential-syntax.test.d.ts +5 -0
- package/dist/tests/e2e/differential-syntax.test.js +95 -0
- package/dist/tests/e2e/differential-syntax.test.js.map +1 -0
- package/dist/tests/e2e/differential-values.test.js +15 -0
- package/dist/tests/e2e/differential-values.test.js.map +1 -1
- package/dist/tests/e2e/gui-browser.test.d.ts +13 -0
- package/dist/tests/e2e/gui-browser.test.js +163 -0
- package/dist/tests/e2e/gui-browser.test.js.map +1 -0
- package/dist/tests/e2e/gui-effects.test.d.ts +6 -0
- package/dist/tests/e2e/gui-effects.test.js +262 -0
- package/dist/tests/e2e/gui-effects.test.js.map +1 -0
- package/dist/tests/e2e/gui-example-browser.test.js +2 -2
- package/dist/tests/e2e/gui-example-browser.test.js.map +1 -1
- package/dist/tests/e2e/gui-example-canvas.test.js +5 -4
- package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -1
- package/dist/tests/e2e/gui-example-svg.test.js +4 -3
- package/dist/tests/e2e/gui-example-svg.test.js.map +1 -1
- package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
- package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
- package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
- package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
- package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
- package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
- package/dist/tests/e2e/gui-example.test.js +4 -3
- package/dist/tests/e2e/gui-example.test.js.map +1 -1
- package/dist/tests/e2e/gui-helpers.js +4 -3
- package/dist/tests/e2e/gui-helpers.js.map +1 -1
- package/dist/tests/e2e/gui-layout.test.js +48 -0
- package/dist/tests/e2e/gui-layout.test.js.map +1 -1
- package/dist/tests/e2e/gui-media.test.js +10 -8
- package/dist/tests/e2e/gui-media.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
- package/dist/tests/e2e/gui-webgl.test.js +179 -0
- package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
- package/dist/tests/e2e/gui-webgl2.test.js +238 -0
- package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
- package/dist/tests/e2e/harness.d.ts +9 -0
- package/dist/tests/e2e/harness.js +14 -2
- package/dist/tests/e2e/harness.js.map +1 -1
- package/dist/tests/e2e/native-extensions.test.js +2 -1
- package/dist/tests/e2e/native-extensions.test.js.map +1 -1
- package/dist/tests/e2e/property-descriptors.test.js +20 -0
- package/dist/tests/e2e/property-descriptors.test.js.map +1 -1
- package/dist/tests/e2e/unicode-output.test.js +5 -3
- package/dist/tests/e2e/unicode-output.test.js.map +1 -1
- package/dist/tests/e2e/weak-collections.test.js +16 -2
- package/dist/tests/e2e/weak-collections.test.js.map +1 -1
- package/dist/tests/extensions/gui.test.js +41 -0
- package/dist/tests/extensions/gui.test.js.map +1 -1
- package/dist/tests/extensions/media.test.js +7 -3
- package/dist/tests/extensions/media.test.js.map +1 -1
- package/dist/tests/helpers.d.ts +1 -0
- package/dist/tests/helpers.js +1 -0
- package/dist/tests/helpers.js.map +1 -1
- package/dist/tests/parser/declarations.test.js +20 -0
- package/dist/tests/parser/declarations.test.js.map +1 -1
- package/dist/tests/parser/expressions.test.js +36 -0
- package/dist/tests/parser/expressions.test.js.map +1 -1
- package/dist/tests/platform.d.ts +32 -0
- package/dist/tests/platform.js +40 -0
- package/dist/tests/platform.js.map +1 -0
- package/dist/tests/platform.test.d.ts +12 -0
- package/dist/tests/platform.test.js +51 -0
- package/dist/tests/platform.test.js.map +1 -0
- package/dist/tests/version.test.js +4 -4
- package/dist/tests/version.test.js.map +1 -1
- package/doc/ai/README.md +10 -4
- package/doc/ai/build-recipe.md +1 -0
- package/doc/ai/cli.md +17 -5
- package/doc/ai/contributing.md +59 -2
- package/doc/ai/extensions.md +38 -7
- package/doc/ai/language-support.md +25 -16
- package/doc/ai/troubleshooting.md +12 -8
- package/doc/ai/zh-CN/README.md +9 -4
- package/doc/ai/zh-CN/build-recipe.md +1 -0
- package/doc/ai/zh-CN/cli.md +13 -3
- package/doc/ai/zh-CN/contributing.md +49 -3
- package/doc/ai/zh-CN/extensions.md +33 -6
- package/doc/ai/zh-CN/language-support.md +23 -14
- package/doc/ai/zh-CN/troubleshooting.md +10 -6
- package/doc/gui/api.md +47 -1
- package/doc/gui/build.md +72 -16
- package/doc/gui/canvas.md +11 -3
- package/doc/gui/dom.md +33 -18
- package/doc/gui/known-issues.md +58 -15
- package/doc/gui/layout.md +18 -0
- package/doc/gui/media.md +17 -13
- package/doc/gui/rendering.md +50 -3
- package/doc/gui/runtime.md +18 -0
- package/doc/gui/webgl.md +256 -0
- package/doc/gui-scripts.md +7 -0
- package/doc/gui.md +108 -17
- package/doc/implemented/binder.md +2 -0
- package/doc/implemented/checker.md +117 -0
- package/doc/implemented/cli.md +13 -1
- package/doc/implemented/codegen.md +3 -2
- package/doc/implemented/driver.md +2 -2
- package/doc/implemented/operators.md +2 -1
- package/doc/implemented/parser.md +3 -2
- package/doc/implemented/pipeline.md +8 -1
- package/doc/implemented/stdlib.md +2 -1
- package/doc/implemented/tests.md +3 -1
- package/doc/implemented.md +2 -0
- package/doc/npm-package.md +419 -0
- package/doc/requirements.md +22 -10
- package/doc/support-matrix.md +83 -0
- package/doc/unimplemented/classes.md +3 -0
- package/doc/unimplemented/deviations.md +3 -2
- package/doc/unimplemented/toolchain.md +1 -1
- package/doc/unimplemented/types.md +24 -8
- package/doc/unimplemented.md +1 -1
- package/doc/zh-CN/gui/api.md +43 -1
- package/doc/zh-CN/gui/build.md +64 -15
- package/doc/zh-CN/gui/canvas.md +9 -2
- package/doc/zh-CN/gui/dom.md +20 -7
- package/doc/zh-CN/gui/known-issues.md +46 -13
- package/doc/zh-CN/gui/layout.md +14 -0
- package/doc/zh-CN/gui/media.md +15 -11
- package/doc/zh-CN/gui/rendering.md +41 -4
- package/doc/zh-CN/gui/runtime.md +16 -0
- package/doc/zh-CN/gui/webgl.md +115 -0
- package/doc/zh-CN/gui-scripts.md +5 -0
- package/doc/zh-CN/gui.md +89 -14
- package/doc/zh-CN/implemented/binder.md +2 -0
- package/doc/zh-CN/implemented/checker.md +99 -0
- package/doc/zh-CN/implemented/cli.md +12 -1
- package/doc/zh-CN/implemented/codegen.md +3 -2
- package/doc/zh-CN/implemented/driver.md +2 -2
- package/doc/zh-CN/implemented/operators.md +1 -1
- package/doc/zh-CN/implemented/parser.md +3 -2
- package/doc/zh-CN/implemented/pipeline.md +3 -1
- package/doc/zh-CN/implemented/stdlib.md +2 -1
- package/doc/zh-CN/implemented/tests.md +3 -1
- package/doc/zh-CN/implemented.md +2 -0
- package/doc/zh-CN/npm-package.md +394 -0
- package/doc/zh-CN/post/announce.md +47 -47
- package/doc/zh-CN/requirements.md +16 -7
- package/doc/zh-CN/support-matrix.md +82 -0
- package/doc/zh-CN/unimplemented/classes.md +3 -0
- package/doc/zh-CN/unimplemented/deviations.md +3 -2
- package/doc/zh-CN/unimplemented/toolchain.md +1 -1
- package/doc/zh-CN/unimplemented/types.md +16 -6
- package/doc/zh-CN/unimplemented.md +1 -1
- package/llms.txt +6 -1
- package/package.json +2 -1
- package/runtime/ext_gui/audio.cpp +316 -0
- package/runtime/ext_gui/browser.cpp +573 -0
- package/runtime/ext_gui/browser_escape.cpp +85 -0
- package/runtime/ext_gui/browser_loop.cpp +83 -0
- package/runtime/ext_gui/canvas.cpp +12 -21
- package/runtime/ext_gui/canvas_internal.h +10 -0
- package/runtime/ext_gui/canvas_raster.cpp +79 -1
- package/runtime/ext_gui/clip_values.cpp +246 -0
- package/runtime/ext_gui/css.cpp +94 -0
- package/runtime/ext_gui/css.h +22 -1
- package/runtime/ext_gui/css_match.cpp +3 -0
- package/runtime/ext_gui/css_selector.cpp +9 -0
- package/runtime/ext_gui/css_sheet.cpp +89 -45
- package/runtime/ext_gui/document.cpp +4 -1
- package/runtime/ext_gui/document.h +2 -0
- package/runtime/ext_gui/dom.h +16 -0
- package/runtime/ext_gui/dom_api.cpp +37 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
- package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
- package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
- package/runtime/ext_gui/dom_api_document.cpp +96 -5
- package/runtime/ext_gui/dom_api_events.cpp +20 -0
- package/runtime/ext_gui/dom_api_internal.h +278 -0
- package/runtime/ext_gui/dom_api_proto.cpp +6 -0
- package/runtime/ext_gui/dom_api_webgl.cpp +376 -0
- package/runtime/ext_gui/dom_api_webgl2.cpp +434 -0
- package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
- package/runtime/ext_gui/dom_api_webgl_buffer.cpp +212 -0
- package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
- package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
- package/runtime/ext_gui/dom_api_webgl_state.cpp +444 -0
- package/runtime/ext_gui/dom_api_webgl_texture.cpp +445 -0
- package/runtime/ext_gui/effect_values.cpp +312 -0
- package/runtime/ext_gui/gradient_values.cpp +476 -0
- package/runtime/ext_gui/grid_values.cpp +230 -0
- package/runtime/ext_gui/gui.cpp +90 -23
- package/runtime/ext_gui/gui_canvas.cpp +50 -2
- package/runtime/ext_gui/gui_engine.h +71 -0
- package/runtime/ext_gui/gui_events.cpp +4 -1
- package/runtime/ext_gui/gui_media.cpp +1 -1
- package/runtime/ext_gui/gui_webgl.cpp +83 -0
- package/runtime/ext_gui/layout.cpp +21 -0
- package/runtime/ext_gui/layout_flow.cpp +81 -4
- package/runtime/ext_gui/layout_flow_internal.h +31 -0
- package/runtime/ext_gui/layout_grid.cpp +374 -0
- package/runtime/ext_gui/media.h +1 -1
- package/runtime/ext_gui/media_api.h +2 -2
- package/runtime/ext_gui/media_query.cpp +211 -0
- package/runtime/ext_gui/paint.cpp +111 -77
- package/runtime/ext_gui/paint.h +33 -3
- package/runtime/ext_gui/paint_background.cpp +229 -0
- package/runtime/ext_gui/paint_clip.cpp +268 -0
- package/runtime/ext_gui/paint_effects.cpp +324 -0
- package/runtime/ext_gui/paint_internal.h +85 -0
- package/runtime/ext_gui/renderer.cpp +8 -31
- package/runtime/ext_gui/renderer_clip.cpp +196 -0
- package/runtime/ext_gui/renderer_image.cpp +13 -8
- package/runtime/ext_gui/renderer_internal.h +15 -8
- package/runtime/ext_gui/renderer_text.cpp +6 -31
- package/runtime/ext_gui/style.cpp +343 -20
- package/runtime/ext_gui/style.h +144 -3
- package/runtime/ext_gui/style_print.cpp +134 -1
- package/runtime/ext_gui/style_values.cpp +152 -126
- package/runtime/ext_gui/style_values_internal.h +35 -0
- package/runtime/ext_gui/webgl.h +466 -0
- package/runtime/ext_gui/webgl2_constants.h +274 -0
- package/runtime/ext_gui/webgl_buffer.cpp +565 -0
- package/runtime/ext_gui/webgl_constants.h +317 -0
- package/runtime/ext_gui/webgl_context.cpp +466 -0
- package/runtime/ext_gui/webgl_draw.cpp +495 -0
- package/runtime/ext_gui/webgl_glsl.h +125 -0
- package/runtime/ext_gui/webgl_glsl_compile.cpp +431 -0
- package/runtime/ext_gui/webgl_glsl_rewrite.cpp +349 -0
- package/runtime/ext_gui/webgl_glsl_scan.cpp +581 -0
- package/runtime/ext_gui/webgl_msl.cpp +62 -0
- package/runtime/ext_gui/webgl_msl.h +33 -0
- package/runtime/ext_gui/webgl_pipeline.cpp +274 -0
- package/runtime/ext_gui/webgl_program_internal.h +18 -0
- package/runtime/ext_gui/webgl_shader.cpp +582 -0
- package/runtime/ext_gui/webgl_texture.cpp +293 -0
- package/runtime/ext_gui/webgl_uniform.cpp +167 -0
- package/runtime/ext_gui/webgl_webgl2.cpp +224 -0
- package/runtime/ext_gui/window.cpp +9 -0
- package/runtime/ext_media/media.cpp +1 -1
- package/runtime/ext_media/media_bridge.c +9 -3
- package/runtime/ext_node/path/path.c +7 -7
- package/runtime/ext_node/url/url.c +4 -2
- package/runtime/rt.h +15 -0
- package/runtime/rt_internal.h +1 -0
- package/runtime/xt_constructors.c +2 -1
- package/runtime/xt_containers/access.inc +8 -0
- package/runtime/xt_containers/objects.inc +22 -2
- package/runtime/xt_io/exception.inc +4 -2
- package/runtime/xt_regex/api.inc +2 -0
- package/runtime/xt_regex/matcher.inc +16 -3
- package/runtime/xt_regex/parser.inc +8 -2
- package/runtime/xt_regex/types.inc +3 -0
- package/runtime/xt_stdlib/math.inc +62 -0
- package/runtime/xt_stdlib2/date.inc +7 -1
- package/runtime/xt_stdlib2/objects.inc +14 -0
- package/runtime/xt_stdlib2/regexp-match.inc +60 -21
- package/runtime/xt_stdlib2/regexp.inc +1 -0
- package/runtime/xt_typed_array.c +1 -1
- package/scripts/build-gui.ts +90 -3
- package/scripts/build-media.ts +323 -58
- package/scripts/setup-vs-toolchain.ps1 +152 -0
- package/scripts/support-matrix.ts +167 -0
- package/src/ast/common.ts +2 -0
- package/src/ast/declarations.ts +12 -1
- package/src/ast/expressions.ts +6 -0
- package/src/ast/kinds.ts +2 -0
- package/src/binder/binder.ts +3 -0
- package/src/binder/declarations.ts +70 -0
- package/src/binder/references.ts +97 -4
- package/src/binder/types.ts +30 -0
- package/src/canonical.ts +37 -0
- package/src/checker/assignability.ts +134 -0
- package/src/checker/calls.ts +135 -0
- package/src/checker/checker.ts +47 -0
- package/src/checker/declarations.ts +26 -0
- package/src/checker/flow.ts +236 -0
- package/src/checker/globals.ts +40 -0
- package/src/checker/source.ts +53 -0
- package/src/checker/type-infer.ts +185 -0
- package/src/checker/type-model.ts +212 -0
- package/src/checker/type-system.ts +578 -0
- package/src/checker/typecheck-types.ts +112 -0
- package/src/checker/typecheck.ts +586 -0
- package/src/checker/undefined.ts +43 -0
- package/src/checker/walk.ts +16 -0
- package/src/cli/help.ts +65 -0
- package/src/cli/hints.ts +2 -1
- package/src/cli/main.ts +12 -49
- package/src/codegen/generator/calls/access.ts +8 -8
- package/src/codegen/generator/calls/invocation.ts +8 -5
- package/src/codegen/generator/calls/super.ts +67 -5
- package/src/codegen/generator/context.ts +31 -19
- package/src/codegen/generator/debug.ts +2 -1
- package/src/codegen/generator/expressions/primary.ts +84 -13
- package/src/codegen/generator/generator.ts +11 -1
- package/src/codegen/generator/module.ts +115 -24
- package/src/codegen/generator/state.ts +11 -1
- package/src/codegen/generator/statements/variables.ts +26 -6
- package/src/codegen/generator/tables.ts +5 -0
- package/src/driver/build-key.ts +3 -0
- package/src/driver/bundler/graph.ts +6 -2
- package/src/driver/bundler/merge.ts +14 -1
- package/src/driver/bundler/types.ts +13 -0
- package/src/driver/compiler.ts +4 -1
- package/src/driver/fingerprint.ts +2 -1
- package/src/driver/frontend.ts +13 -2
- package/src/driver/options.ts +6 -0
- package/src/driver/version.ts +1 -1
- package/src/extensions/gui/css.ts +113 -0
- package/src/extensions/gui/html.ts +31 -11
- package/src/extensions/gui/index.ts +81 -2
- package/src/extensions/gui/three.ts +25 -0
- package/src/extensions/media/index.ts +13 -16
- package/src/extensions/registry.ts +48 -0
- package/src/index.ts +1 -0
- package/src/parser/declarations/classes.ts +7 -0
- package/src/parser/expressions.ts +13 -1
- package/src/parser/literals.ts +6 -2
|
@@ -72,6 +72,13 @@ class SelectorParser {
|
|
|
72
72
|
}
|
|
73
73
|
std::string name = xt_css_lower(readIdent(text, index));
|
|
74
74
|
if (name.empty()) return false;
|
|
75
|
+
/* `::before`/`::after` are generated-content elements, not states. The
|
|
76
|
+
* single-colon spellings (`:before`) are the legacy equivalent. */
|
|
77
|
+
if (pseudoElement || name == "before" || name == "after") {
|
|
78
|
+
compound->pseudo_element = name;
|
|
79
|
+
any = true;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
75
82
|
if (!pseudoElement && *index < text.size() && text[*index] == '(') {
|
|
76
83
|
int depth = 0;
|
|
77
84
|
size_t start = *index;
|
|
@@ -192,6 +199,8 @@ class SelectorParser {
|
|
|
192
199
|
if (!compound.id.empty()) ids++;
|
|
193
200
|
classes += computeCompoundSpecificity(compound);
|
|
194
201
|
if (!compound.tag.empty()) types++;
|
|
202
|
+
/* A pseudo-element counts like a type selector (CSS specificity). */
|
|
203
|
+
if (!compound.pseudo_element.empty()) types++;
|
|
195
204
|
}
|
|
196
205
|
return (ids << 20) | (classes << 10) | types;
|
|
197
206
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* xbintsc GUI engine — CSS declaration and stylesheet parsing.
|
|
3
|
+
*
|
|
4
|
+
* At-rules are no longer all skipped: `@media` blocks are parsed recursively
|
|
5
|
+
* and each rule keeps its (possibly nested) query, which the cascade evaluates
|
|
6
|
+
* against the viewport. Every other at-rule is ignored with its block.
|
|
3
7
|
*/
|
|
4
8
|
|
|
5
9
|
#include "css_internal.h"
|
|
@@ -41,6 +45,42 @@ size_t findTopLevel(const std::string &text, char needle, size_t from) {
|
|
|
41
45
|
return std::string::npos;
|
|
42
46
|
}
|
|
43
47
|
|
|
48
|
+
/** The `}` matching the `{` at `open`, respecting strings and nested blocks. */
|
|
49
|
+
size_t findBlockEnd(const std::string &text, size_t open) {
|
|
50
|
+
int depth = 0;
|
|
51
|
+
char quote = 0;
|
|
52
|
+
for (size_t i = open; i < text.size(); i++) {
|
|
53
|
+
char c = text[i];
|
|
54
|
+
if (quote != 0) {
|
|
55
|
+
if (c == quote) quote = 0;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (c == '"' || c == '\'') quote = c;
|
|
59
|
+
else if (c == '{') depth++;
|
|
60
|
+
else if (c == '}') {
|
|
61
|
+
depth--;
|
|
62
|
+
if (depth == 0) return i;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return std::string::npos;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Join a nested `@media` prelude: distribute `inner` over an outer comma list. */
|
|
69
|
+
std::string combineMedia(const std::string &outer, const std::string &inner) {
|
|
70
|
+
if (outer.empty()) return inner;
|
|
71
|
+
if (inner.empty()) return outer;
|
|
72
|
+
std::vector<std::string> outerParts = xt_css_split_commas(outer);
|
|
73
|
+
std::vector<std::string> innerParts = xt_css_split_commas(inner);
|
|
74
|
+
std::string combined;
|
|
75
|
+
for (const std::string &o : outerParts) {
|
|
76
|
+
for (const std::string &i : innerParts) {
|
|
77
|
+
if (!combined.empty()) combined += ", ";
|
|
78
|
+
combined += o + " and " + i;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return combined;
|
|
82
|
+
}
|
|
83
|
+
|
|
44
84
|
std::string stripImportant(std::string value, bool *important) {
|
|
45
85
|
size_t pos = value.rfind('!');
|
|
46
86
|
if (pos == std::string::npos) return value;
|
|
@@ -52,6 +92,54 @@ std::string stripImportant(std::string value, bool *important) {
|
|
|
52
92
|
return value;
|
|
53
93
|
}
|
|
54
94
|
|
|
95
|
+
/** Parse one rule list, carrying the enclosing `@media` prelude. */
|
|
96
|
+
void parseRules(const std::string &text, const std::string &media, int *order,
|
|
97
|
+
StyleSheet *sheet) {
|
|
98
|
+
size_t index = 0;
|
|
99
|
+
while (index < text.size()) {
|
|
100
|
+
while (index < text.size() && xt_is_css_space(text[index])) index++;
|
|
101
|
+
if (index >= text.size()) break;
|
|
102
|
+
|
|
103
|
+
if (text[index] == '@') {
|
|
104
|
+
size_t nameStart = index + 1;
|
|
105
|
+
size_t nameEnd = nameStart;
|
|
106
|
+
while (nameEnd < text.size() &&
|
|
107
|
+
(std::isalnum((unsigned char)text[nameEnd]) || text[nameEnd] == '-'))
|
|
108
|
+
nameEnd++;
|
|
109
|
+
std::string name = xt_css_lower(text.substr(nameStart, nameEnd - nameStart));
|
|
110
|
+
size_t brace = text.find('{', nameEnd);
|
|
111
|
+
size_t semi = text.find(';', nameEnd);
|
|
112
|
+
if (brace != std::string::npos && (semi == std::string::npos || brace < semi)) {
|
|
113
|
+
size_t close = findBlockEnd(text, brace);
|
|
114
|
+
if (close == std::string::npos) break;
|
|
115
|
+
if (name == "media") {
|
|
116
|
+
std::string query = xt_css_trim(text.substr(nameEnd, brace - nameEnd));
|
|
117
|
+
std::string nested = combineMedia(media, query);
|
|
118
|
+
parseRules(text.substr(brace + 1, close - brace - 1), nested, order, sheet);
|
|
119
|
+
}
|
|
120
|
+
/* Other block at-rules (`@supports`, `@keyframes`, `@font-face`, …) are
|
|
121
|
+
* not part of the engine's subset: ignore the whole block. */
|
|
122
|
+
index = close + 1;
|
|
123
|
+
} else {
|
|
124
|
+
index = (semi == std::string::npos) ? text.size() : semi + 1;
|
|
125
|
+
}
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
size_t brace = text.find('{', index);
|
|
130
|
+
if (brace == std::string::npos) break;
|
|
131
|
+
size_t close = findBlockEnd(text, brace);
|
|
132
|
+
if (close == std::string::npos) break;
|
|
133
|
+
Rule rule;
|
|
134
|
+
rule.selectors = xt_css_parse_selector_list(text.substr(index, brace - index));
|
|
135
|
+
rule.declarations = xt_css_parse_declarations(text.substr(brace + 1, close - brace - 1));
|
|
136
|
+
rule.order = (*order)++;
|
|
137
|
+
rule.media = media;
|
|
138
|
+
if (!rule.selectors.empty() && !rule.declarations.empty()) sheet->rules.push_back(std::move(rule));
|
|
139
|
+
index = close + 1;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
55
143
|
} // namespace
|
|
56
144
|
|
|
57
145
|
std::vector<Declaration> xt_css_parse_declarations(const std::string &text) {
|
|
@@ -77,52 +165,8 @@ std::vector<Declaration> xt_css_parse_declarations(const std::string &text) {
|
|
|
77
165
|
StyleSheet xt_css_parse_stylesheet(const std::string &text) {
|
|
78
166
|
StyleSheet sheet;
|
|
79
167
|
std::string clean = stripComments(text);
|
|
80
|
-
size_t index = 0;
|
|
81
168
|
int order = 0;
|
|
82
|
-
|
|
83
|
-
while (index < clean.size() && xt_is_css_space(clean[index])) index++;
|
|
84
|
-
if (index >= clean.size()) break;
|
|
85
|
-
if (clean[index] == '@') {
|
|
86
|
-
size_t brace = clean.find('{', index);
|
|
87
|
-
size_t semi = clean.find(';', index);
|
|
88
|
-
if (brace != std::string::npos && (semi == std::string::npos || brace < semi)) {
|
|
89
|
-
int depth = 0;
|
|
90
|
-
size_t i = brace;
|
|
91
|
-
for (; i < clean.size(); i++) {
|
|
92
|
-
if (clean[i] == '{') depth++;
|
|
93
|
-
else if (clean[i] == '}') {
|
|
94
|
-
depth--;
|
|
95
|
-
if (depth == 0) break;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
index = (i < clean.size()) ? i + 1 : clean.size();
|
|
99
|
-
} else {
|
|
100
|
-
index = (semi == std::string::npos) ? clean.size() : semi + 1;
|
|
101
|
-
}
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
size_t brace = clean.find('{', index);
|
|
105
|
-
if (brace == std::string::npos) break;
|
|
106
|
-
int depth = 0;
|
|
107
|
-
size_t close = std::string::npos;
|
|
108
|
-
for (size_t i = brace; i < clean.size(); i++) {
|
|
109
|
-
if (clean[i] == '{') depth++;
|
|
110
|
-
else if (clean[i] == '}') {
|
|
111
|
-
depth--;
|
|
112
|
-
if (depth == 0) {
|
|
113
|
-
close = i;
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
if (close == std::string::npos) break;
|
|
119
|
-
Rule rule;
|
|
120
|
-
rule.selectors = xt_css_parse_selector_list(clean.substr(index, brace - index));
|
|
121
|
-
rule.declarations = xt_css_parse_declarations(clean.substr(brace + 1, close - brace - 1));
|
|
122
|
-
rule.order = order++;
|
|
123
|
-
if (!rule.selectors.empty() && !rule.declarations.empty()) sheet.rules.push_back(std::move(rule));
|
|
124
|
-
index = close + 1;
|
|
125
|
-
}
|
|
169
|
+
parseRules(clean, "", &order, &sheet);
|
|
126
170
|
return sheet;
|
|
127
171
|
}
|
|
128
172
|
|
|
@@ -47,7 +47,7 @@ void XtDocument::restyle(float viewportWidth, float viewportHeight) {
|
|
|
47
47
|
MatchState state;
|
|
48
48
|
state.hover = hover_;
|
|
49
49
|
state.focus = focus_;
|
|
50
|
-
xt_style_compute(root_.get(), sheet_, styles_, viewportWidth, viewportHeight, state);
|
|
50
|
+
xt_style_compute(root_.get(), sheet_, styles_, viewportWidth, viewportHeight, state, &pseudos_);
|
|
51
51
|
startTransitions();
|
|
52
52
|
updateDisplay();
|
|
53
53
|
}
|
|
@@ -124,6 +124,9 @@ void XtDocument::startTransitions() {
|
|
|
124
124
|
for (auto &entry : styles_) {
|
|
125
125
|
const Node *node = entry.first;
|
|
126
126
|
const XtStyle &target = entry.second;
|
|
127
|
+
/* Generated boxes are rebuilt on every restyle; a transition keyed by one
|
|
128
|
+
* would address a node that no longer exists. */
|
|
129
|
+
if (node->is_pseudo) continue;
|
|
127
130
|
if (target.transitions.empty()) continue;
|
|
128
131
|
auto prev_it = display_.find(node);
|
|
129
132
|
if (prev_it == display_.end()) continue;
|
|
@@ -118,6 +118,8 @@ class XtDocument {
|
|
|
118
118
|
std::unique_ptr<Node> root_;
|
|
119
119
|
/** Detached nodes (created or removed) stay alive here so handles remain valid. */
|
|
120
120
|
std::unordered_map<const Node *, std::unique_ptr<Node>> detached_;
|
|
121
|
+
/** Synthetic `::before`/`::after` nodes for the current style generation. */
|
|
122
|
+
PseudoNodeSet pseudos_;
|
|
121
123
|
bool dirty_ = false;
|
|
122
124
|
StyleSheet sheet_;
|
|
123
125
|
std::unordered_map<const Node *, XtStyle> styles_; // target (cascade)
|
package/runtime/ext_gui/dom.h
CHANGED
|
@@ -18,6 +18,9 @@ namespace xtgui {
|
|
|
18
18
|
|
|
19
19
|
enum class NodeType { Document, Element, Text };
|
|
20
20
|
|
|
21
|
+
/** Which generated-content box a synthetic pseudo-element node represents. */
|
|
22
|
+
enum class PseudoElement { None, Before, After };
|
|
23
|
+
|
|
21
24
|
struct Attr {
|
|
22
25
|
std::string name;
|
|
23
26
|
std::string value;
|
|
@@ -32,6 +35,19 @@ struct Node {
|
|
|
32
35
|
Node *parent = nullptr;
|
|
33
36
|
std::vector<std::unique_ptr<Node>> children;
|
|
34
37
|
|
|
38
|
+
/* -- generated content (`::before` / `::after`) -------------------------
|
|
39
|
+
* A pseudo-element is a synthetic node owned by the document's per-restyle
|
|
40
|
+
* arena, not by the DOM tree: it is never in `children`, so traversal,
|
|
41
|
+
* queries, serialization and `elementIndex()` do not see it. `pseudo_origin`
|
|
42
|
+
* is the element the selector matched and whose computed style it inherits.
|
|
43
|
+
* `pseudo_before`/`pseudo_after` are transient pointers set by the cascade
|
|
44
|
+
* for the layout pass (the arena is rebuilt on every restyle). */
|
|
45
|
+
bool is_pseudo = false;
|
|
46
|
+
PseudoElement pseudo = PseudoElement::None;
|
|
47
|
+
const Node *pseudo_origin = nullptr;
|
|
48
|
+
Node *pseudo_before = nullptr;
|
|
49
|
+
Node *pseudo_after = nullptr;
|
|
50
|
+
|
|
35
51
|
Node() = default;
|
|
36
52
|
explicit Node(NodeType nodeType) : type(nodeType) {}
|
|
37
53
|
|
|
@@ -52,11 +52,39 @@ XtGuiWindow *resolve_window(xt_value self) {
|
|
|
52
52
|
return xt_gui_window_from_this(xt_object_get_cstr(self, "__xt_gui_win"));
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/** Bind a pending handle to the node its key now finds: copy the slot
|
|
56
|
+
* bookkeeping of the canonical handle, then drop the pending marker so later
|
|
57
|
+
* resolutions take the normal path. */
|
|
58
|
+
static xtgui::Node *bind_pending(XtGuiWindow *win, xt_value self, xtgui::Node *node) {
|
|
59
|
+
xt_value canonical = xt_gui_node_handle(win, node);
|
|
60
|
+
if (!XT_IS_OBJECT(canonical)) return nullptr;
|
|
61
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_node"),
|
|
62
|
+
xt_object_get_cstr(canonical, "__xt_gui_node"));
|
|
63
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_slot_gen"),
|
|
64
|
+
xt_object_get_cstr(canonical, "__xt_gui_slot_gen"));
|
|
65
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_gen"),
|
|
66
|
+
xt_object_get_cstr(canonical, "__xt_gui_gen"));
|
|
67
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_pending"), XT_UNDEFINED);
|
|
68
|
+
xt_gui_canvas_bind_pending(win, node, self);
|
|
69
|
+
return node;
|
|
70
|
+
}
|
|
71
|
+
|
|
55
72
|
/** Resolve a node handle to its node, or NULL when it is stale/foreign. */
|
|
56
73
|
xtgui::Node *resolve_node(xt_value self, XtGuiWindow **winOut) {
|
|
57
74
|
XtGuiWindow *win = resolve_window(self);
|
|
58
75
|
if (winOut != nullptr) *winOut = win;
|
|
59
76
|
if (win == nullptr || win->document == nullptr) return nullptr;
|
|
77
|
+
/* A pending handle names its node indirectly so that a module which queried
|
|
78
|
+
* `#id` before `loadHTML` ran still works: look the key up now and bind. */
|
|
79
|
+
xt_value pending = xt_object_get_cstr(self, "__xt_gui_pending");
|
|
80
|
+
if (XT_IS_NUMBER(pending)) {
|
|
81
|
+
std::string key = to_string_value(xt_object_get_cstr(self, "__xt_gui_pending_key"));
|
|
82
|
+
xtgui::Node *node = (int)xt_to_number(pending) == domapi::pending_by_id
|
|
83
|
+
? domapi::document_find_by_id(win, key)
|
|
84
|
+
: domapi::document_query_selector(win, key);
|
|
85
|
+
if (node == nullptr) return nullptr;
|
|
86
|
+
return bind_pending(win, self, node);
|
|
87
|
+
}
|
|
60
88
|
xt_value gen = xt_object_get_cstr(self, "__xt_gui_gen");
|
|
61
89
|
if (!XT_IS_NUMBER(gen) || xt_to_number(gen) != win->doc_generation) return nullptr;
|
|
62
90
|
if (value_truthy(xt_object_get_cstr(self, "__xt_gui_doc"))) {
|
|
@@ -121,6 +149,15 @@ void set_class_name(XtGuiWindow *win, xtgui::Node *node, const std::string &valu
|
|
|
121
149
|
}
|
|
122
150
|
}
|
|
123
151
|
|
|
152
|
+
xt_value pending_handle(XtGuiWindow *win, int kind, const std::string &key) {
|
|
153
|
+
xt_value handle = xt_object_new_with_proto(node_proto());
|
|
154
|
+
if (win != nullptr) xt_object_set(handle, xt_string_from_cstr("__xt_gui_win"), win->object);
|
|
155
|
+
xt_object_set(handle, xt_string_from_cstr("__xt_gui_pending"), xt_number((double)kind));
|
|
156
|
+
xt_object_set(handle, xt_string_from_cstr("__xt_gui_pending_key"),
|
|
157
|
+
xt_string_from_cstr(key.c_str()));
|
|
158
|
+
return handle;
|
|
159
|
+
}
|
|
160
|
+
|
|
124
161
|
} // namespace domapi
|
|
125
162
|
|
|
126
163
|
xt_value xt_gui_node_handle(XtGuiWindow *win, const xtgui::Node *node) {
|
|
@@ -58,8 +58,23 @@ METHOD(node_get_context) {
|
|
|
58
58
|
std::string mode = string_arg(argc, argv, 0);
|
|
59
59
|
XtGuiWindow *win = nullptr;
|
|
60
60
|
xtgui::Node *node = resolve_node(self, &win);
|
|
61
|
-
if (
|
|
61
|
+
if (mode == "webgl" || mode == "experimental-webgl" || mode == "webgl2") {
|
|
62
|
+
const bool webgl2 = mode == "webgl2";
|
|
63
|
+
if (node == nullptr) return XT_NULL;
|
|
64
|
+
if (!node->isElement() || !node->isTag("canvas")) return XT_NULL;
|
|
65
|
+
if (xt_gui_canvas_find(win, node) != nullptr) return XT_NULL; // already a 2D canvas
|
|
66
|
+
xt_value cached = xt_object_get_cstr(self, "__xt_gui_gl");
|
|
67
|
+
if (XT_IS_OBJECT(cached)) {
|
|
68
|
+
const bool cached_webgl2 = value_truthy(xt_object_get_cstr(cached, "__xt_gl_webgl2"));
|
|
69
|
+
return cached_webgl2 == webgl2 ? cached : XT_NULL;
|
|
70
|
+
}
|
|
71
|
+
xtgui::WebGLContext *context = xt_gui_webgl_get(win, node, webgl2);
|
|
72
|
+
return webgl_context_handle(self, context);
|
|
73
|
+
}
|
|
62
74
|
if (mode != "2d") return XT_NULL;
|
|
75
|
+
if (node == nullptr) return xt_canvas_pending_context(self, win);
|
|
76
|
+
if (!node->isElement() || !node->isTag("canvas")) return XT_NULL;
|
|
77
|
+
if (xt_gui_webgl_find(win, node) != nullptr) return XT_NULL; // already a WebGL canvas
|
|
63
78
|
xtgui::Canvas2D *canvas = xt_gui_canvas_get(win, node);
|
|
64
79
|
if (canvas == nullptr) return XT_NULL;
|
|
65
80
|
xt_value cached = xt_object_get_cstr(self, "__xt_gui_ctx");
|
|
@@ -72,84 +87,6 @@ METHOD(node_get_context) {
|
|
|
72
87
|
return ctx;
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
METHOD(node_width_get) {
|
|
76
|
-
(void)env;
|
|
77
|
-
(void)argc;
|
|
78
|
-
(void)argv;
|
|
79
|
-
XtGuiWindow *win = nullptr;
|
|
80
|
-
xtgui::Node *node = resolve_node(self, &win);
|
|
81
|
-
if (node == nullptr || !node->isElement()) return xt_number(0);
|
|
82
|
-
if (node->isTag("canvas")) {
|
|
83
|
-
xtgui::Canvas2D *canvas = xt_gui_canvas_find(win, node);
|
|
84
|
-
if (canvas != nullptr) return xt_number(canvas->width());
|
|
85
|
-
}
|
|
86
|
-
const std::string *attr = node->attr("width");
|
|
87
|
-
float value = 0.0f;
|
|
88
|
-
if (attr != nullptr && xtgui::xt_css_parse_number(*attr, &value)) return xt_number(value);
|
|
89
|
-
return xt_number(0);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
METHOD(node_width_set) {
|
|
93
|
-
(void)env;
|
|
94
|
-
XtGuiWindow *win = nullptr;
|
|
95
|
-
xtgui::Node *node = resolve_node(self, &win);
|
|
96
|
-
if (node == nullptr || !node->isElement()) return XT_UNDEFINED;
|
|
97
|
-
double value = number_arg(argc, argv, 0, 0.0);
|
|
98
|
-
if (node->isTag("canvas")) {
|
|
99
|
-
xtgui::Canvas2D *canvas = xt_gui_canvas_get(win, node);
|
|
100
|
-
if (canvas != nullptr) {
|
|
101
|
-
canvas->resize((int)value, canvas->height());
|
|
102
|
-
if (win != nullptr && win->document != nullptr) {
|
|
103
|
-
win->document->setCanvasInfo(node, (float)canvas->width(), (float)canvas->height(),
|
|
104
|
-
canvas->id());
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return XT_UNDEFINED;
|
|
108
|
-
}
|
|
109
|
-
set_attribute(win, node, "width", std::to_string((long long)value));
|
|
110
|
-
return XT_UNDEFINED;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
METHOD(node_height_get) {
|
|
114
|
-
(void)env;
|
|
115
|
-
(void)argc;
|
|
116
|
-
(void)argv;
|
|
117
|
-
XtGuiWindow *win = nullptr;
|
|
118
|
-
xtgui::Node *node = resolve_node(self, &win);
|
|
119
|
-
if (node == nullptr || !node->isElement()) return xt_number(0);
|
|
120
|
-
if (node->isTag("canvas")) {
|
|
121
|
-
xtgui::Canvas2D *canvas = xt_gui_canvas_find(win, node);
|
|
122
|
-
if (canvas != nullptr) return xt_number(canvas->height());
|
|
123
|
-
}
|
|
124
|
-
const std::string *attr = node->attr("height");
|
|
125
|
-
float value = 0.0f;
|
|
126
|
-
if (attr != nullptr && xtgui::xt_css_parse_number(*attr, &value)) return xt_number(value);
|
|
127
|
-
return xt_number(0);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
METHOD(node_height_set) {
|
|
131
|
-
(void)env;
|
|
132
|
-
XtGuiWindow *win = nullptr;
|
|
133
|
-
xtgui::Node *node = resolve_node(self, &win);
|
|
134
|
-
if (node == nullptr || !node->isElement()) return XT_UNDEFINED;
|
|
135
|
-
double value = number_arg(argc, argv, 0, 0.0);
|
|
136
|
-
if (node->isTag("canvas")) {
|
|
137
|
-
xtgui::Canvas2D *canvas = xt_gui_canvas_get(win, node);
|
|
138
|
-
if (canvas != nullptr) {
|
|
139
|
-
canvas->resize(canvas->width(), (int)value);
|
|
140
|
-
if (win != nullptr && win->document != nullptr) {
|
|
141
|
-
win->document->setCanvasInfo(node, (float)canvas->width(), (float)canvas->height(),
|
|
142
|
-
canvas->id());
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return XT_UNDEFINED;
|
|
146
|
-
}
|
|
147
|
-
set_attribute(win, node, "height", std::to_string((long long)value));
|
|
148
|
-
return XT_UNDEFINED;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/* -- state / style getters and setters ------------------------------------ */
|
|
152
|
-
|
|
153
90
|
METHOD(canvas_get_canvas) {
|
|
154
91
|
(void)env;
|
|
155
92
|
(void)argc;
|
|
@@ -579,4 +516,4 @@ METHOD(canvas_get_image_data) {
|
|
|
579
516
|
|
|
580
517
|
} // namespace domapi
|
|
581
518
|
|
|
582
|
-
#undef METHOD
|
|
519
|
+
#undef METHOD
|
|
@@ -227,6 +227,135 @@ METHOD(canvas_get_transform) {
|
|
|
227
227
|
return result;
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
METHOD(node_width_get) {
|
|
231
|
+
(void)env;
|
|
232
|
+
(void)argc;
|
|
233
|
+
(void)argv;
|
|
234
|
+
XtGuiWindow *win = nullptr;
|
|
235
|
+
xtgui::Node *node = resolve_node(self, &win);
|
|
236
|
+
if (node == nullptr || !node->isElement()) return xt_number(0);
|
|
237
|
+
if (node->isTag("canvas")) {
|
|
238
|
+
if (xtgui::WebGLContext *webgl = xt_gui_webgl_find(win, node)) {
|
|
239
|
+
return xt_number(webgl->width());
|
|
240
|
+
}
|
|
241
|
+
xtgui::Canvas2D *canvas = xt_gui_canvas_find(win, node);
|
|
242
|
+
if (canvas != nullptr) return xt_number(canvas->width());
|
|
243
|
+
}
|
|
244
|
+
const std::string *attr = node->attr("width");
|
|
245
|
+
float value = 0.0f;
|
|
246
|
+
if (attr != nullptr && xtgui::xt_css_parse_number(*attr, &value)) return xt_number(value);
|
|
247
|
+
/* A canvas with no context still reports the CSS default bitmap size. */
|
|
248
|
+
return xt_number(node->isTag("canvas") ? 300 : 0);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
METHOD(node_width_set) {
|
|
252
|
+
(void)env;
|
|
253
|
+
XtGuiWindow *win = nullptr;
|
|
254
|
+
xtgui::Node *node = resolve_node(self, &win);
|
|
255
|
+
if (node == nullptr || !node->isElement()) return XT_UNDEFINED;
|
|
256
|
+
double value = canvas_number_arg(argc, argv, 0, 0.0);
|
|
257
|
+
if (node->isTag("canvas")) {
|
|
258
|
+
if (xtgui::WebGLContext *webgl = xt_gui_webgl_find(win, node)) {
|
|
259
|
+
webgl->resize((int)value, webgl->height());
|
|
260
|
+
/* A resize replaces the colour texture; the page has to re-upload the
|
|
261
|
+
* image op even when the box size did not change. */
|
|
262
|
+
mark_dirty(win);
|
|
263
|
+
if (win != nullptr && win->document != nullptr) {
|
|
264
|
+
win->document->setCanvasInfo(node, (float)webgl->width(), (float)webgl->height(),
|
|
265
|
+
webgl->id());
|
|
266
|
+
}
|
|
267
|
+
return XT_UNDEFINED;
|
|
268
|
+
}
|
|
269
|
+
xtgui::Canvas2D *canvas = xt_gui_canvas_find(win, node);
|
|
270
|
+
if (canvas != nullptr) {
|
|
271
|
+
canvas->resize((int)value, canvas->height());
|
|
272
|
+
if (win != nullptr && win->document != nullptr) {
|
|
273
|
+
win->document->setCanvasInfo(node, (float)canvas->width(), (float)canvas->height(),
|
|
274
|
+
canvas->id());
|
|
275
|
+
}
|
|
276
|
+
return XT_UNDEFINED;
|
|
277
|
+
}
|
|
278
|
+
/* No context yet: update the attribute so a later getContext uses it. */
|
|
279
|
+
int height = 150;
|
|
280
|
+
const std::string *height_attr = node->attr("height");
|
|
281
|
+
float parsed = 0.0f;
|
|
282
|
+
if (height_attr != nullptr && xtgui::xt_css_parse_number(*height_attr, &parsed)) {
|
|
283
|
+
height = (int)(parsed + 0.5f);
|
|
284
|
+
}
|
|
285
|
+
set_attribute(win, node, "width", std::to_string((long long)value));
|
|
286
|
+
if (win != nullptr && win->document != nullptr) {
|
|
287
|
+
win->document->setCanvasInfo(node, (float)value, (float)height, 0);
|
|
288
|
+
}
|
|
289
|
+
return XT_UNDEFINED;
|
|
290
|
+
}
|
|
291
|
+
set_attribute(win, node, "width", std::to_string((long long)value));
|
|
292
|
+
return XT_UNDEFINED;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
METHOD(node_height_get) {
|
|
296
|
+
(void)env;
|
|
297
|
+
(void)argc;
|
|
298
|
+
(void)argv;
|
|
299
|
+
XtGuiWindow *win = nullptr;
|
|
300
|
+
xtgui::Node *node = resolve_node(self, &win);
|
|
301
|
+
if (node == nullptr || !node->isElement()) return xt_number(0);
|
|
302
|
+
if (node->isTag("canvas")) {
|
|
303
|
+
if (xtgui::WebGLContext *webgl = xt_gui_webgl_find(win, node)) {
|
|
304
|
+
return xt_number(webgl->height());
|
|
305
|
+
}
|
|
306
|
+
xtgui::Canvas2D *canvas = xt_gui_canvas_find(win, node);
|
|
307
|
+
if (canvas != nullptr) return xt_number(canvas->height());
|
|
308
|
+
}
|
|
309
|
+
const std::string *attr = node->attr("height");
|
|
310
|
+
float value = 0.0f;
|
|
311
|
+
if (attr != nullptr && xtgui::xt_css_parse_number(*attr, &value)) return xt_number(value);
|
|
312
|
+
return xt_number(node->isTag("canvas") ? 150 : 0);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
METHOD(node_height_set) {
|
|
316
|
+
(void)env;
|
|
317
|
+
XtGuiWindow *win = nullptr;
|
|
318
|
+
xtgui::Node *node = resolve_node(self, &win);
|
|
319
|
+
if (node == nullptr || !node->isElement()) return XT_UNDEFINED;
|
|
320
|
+
double value = canvas_number_arg(argc, argv, 0, 0.0);
|
|
321
|
+
if (node->isTag("canvas")) {
|
|
322
|
+
if (xtgui::WebGLContext *webgl = xt_gui_webgl_find(win, node)) {
|
|
323
|
+
webgl->resize(webgl->width(), (int)value);
|
|
324
|
+
mark_dirty(win);
|
|
325
|
+
if (win != nullptr && win->document != nullptr) {
|
|
326
|
+
win->document->setCanvasInfo(node, (float)webgl->width(), (float)webgl->height(),
|
|
327
|
+
webgl->id());
|
|
328
|
+
}
|
|
329
|
+
return XT_UNDEFINED;
|
|
330
|
+
}
|
|
331
|
+
xtgui::Canvas2D *canvas = xt_gui_canvas_find(win, node);
|
|
332
|
+
if (canvas != nullptr) {
|
|
333
|
+
canvas->resize(canvas->width(), (int)value);
|
|
334
|
+
if (win != nullptr && win->document != nullptr) {
|
|
335
|
+
win->document->setCanvasInfo(node, (float)canvas->width(), (float)canvas->height(),
|
|
336
|
+
canvas->id());
|
|
337
|
+
}
|
|
338
|
+
return XT_UNDEFINED;
|
|
339
|
+
}
|
|
340
|
+
int width = 300;
|
|
341
|
+
const std::string *width_attr = node->attr("width");
|
|
342
|
+
float parsed = 0.0f;
|
|
343
|
+
if (width_attr != nullptr && xtgui::xt_css_parse_number(*width_attr, &parsed)) {
|
|
344
|
+
width = (int)(parsed + 0.5f);
|
|
345
|
+
}
|
|
346
|
+
set_attribute(win, node, "height", std::to_string((long long)value));
|
|
347
|
+
if (win != nullptr && win->document != nullptr) {
|
|
348
|
+
win->document->setCanvasInfo(node, (float)width, (float)value, 0);
|
|
349
|
+
}
|
|
350
|
+
return XT_UNDEFINED;
|
|
351
|
+
}
|
|
352
|
+
set_attribute(win, node, "height", std::to_string((long long)value));
|
|
353
|
+
return XT_UNDEFINED;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/* -- state / style getters and setters ------------------------------------ */
|
|
357
|
+
|
|
358
|
+
|
|
230
359
|
} // namespace domapi
|
|
231
360
|
|
|
232
|
-
#undef METHOD
|
|
361
|
+
#undef METHOD
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc GUI engine — 2D contexts for pending canvas handles.
|
|
3
|
+
*
|
|
4
|
+
* The gui extension hands out element handles before `loadHTML`; a module may
|
|
5
|
+
* call `getContext("2d")` in that window. Keep the bridge here so
|
|
6
|
+
* `dom_api_canvas.cpp` stays focused (and under the per-file line budget).
|
|
7
|
+
*/
|
|
8
|
+
#include <memory>
|
|
9
|
+
#include <string>
|
|
10
|
+
|
|
11
|
+
#include "canvas.h"
|
|
12
|
+
#include "dom_api_internal.h"
|
|
13
|
+
#include "gui_engine.h"
|
|
14
|
+
|
|
15
|
+
namespace {
|
|
16
|
+
|
|
17
|
+
bool is_pending_canvas(xt_value self) {
|
|
18
|
+
xt_value pending = xt_object_get_cstr(self, "__xt_gui_pending");
|
|
19
|
+
return XT_IS_NUMBER(pending);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
} // namespace
|
|
23
|
+
|
|
24
|
+
namespace domapi {
|
|
25
|
+
|
|
26
|
+
xt_value xt_canvas_pending_context(xt_value self, XtGuiWindow *win) {
|
|
27
|
+
if (!is_pending_canvas(self) || win == nullptr) return XT_NULL;
|
|
28
|
+
xt_value cached = xt_object_get_cstr(self, "__xt_gui_ctx");
|
|
29
|
+
if (XT_IS_OBJECT(cached)) return cached;
|
|
30
|
+
auto created = std::make_unique<xtgui::Canvas2D>(300, 150);
|
|
31
|
+
xtgui::Canvas2D *raw = created.get();
|
|
32
|
+
win->pending_canvases[raw->id()] = std::move(created);
|
|
33
|
+
xt_value ctx = xt_object_new_with_proto(canvas_proto());
|
|
34
|
+
xt_object_set(ctx, xt_string_from_cstr("__xt_gui_canvas"), xt_number((double)raw->id()));
|
|
35
|
+
xt_object_set(ctx, xt_string_from_cstr("__xt_gui_node"), self);
|
|
36
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_ctx"), ctx);
|
|
37
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_pending_canvas"), xt_number((double)raw->id()));
|
|
38
|
+
return ctx;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
} // namespace domapi
|