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.
Files changed (481) hide show
  1. package/AGENTS.md +11 -2
  2. package/README.md +47 -16
  3. package/README.zh-CN.md +21 -2
  4. package/dist/scripts/support-matrix.d.ts +18 -0
  5. package/dist/scripts/support-matrix.js +141 -0
  6. package/dist/scripts/support-matrix.js.map +1 -0
  7. package/dist/src/ast/common.d.ts +2 -2
  8. package/dist/src/ast/declarations.d.ts +7 -1
  9. package/dist/src/ast/expressions.d.ts +5 -0
  10. package/dist/src/ast/kinds.d.ts +2 -0
  11. package/dist/src/ast/kinds.js +2 -0
  12. package/dist/src/ast/kinds.js.map +1 -1
  13. package/dist/src/binder/binder.d.ts +2 -1
  14. package/dist/src/binder/binder.js +2 -0
  15. package/dist/src/binder/binder.js.map +1 -1
  16. package/dist/src/binder/declarations.d.ts +9 -0
  17. package/dist/src/binder/declarations.js +64 -0
  18. package/dist/src/binder/declarations.js.map +1 -1
  19. package/dist/src/binder/references.js +99 -4
  20. package/dist/src/binder/references.js.map +1 -1
  21. package/dist/src/binder/types.d.ts +32 -0
  22. package/dist/src/binder/types.js.map +1 -1
  23. package/dist/src/canonical.d.ts +29 -0
  24. package/dist/src/canonical.js +35 -0
  25. package/dist/src/canonical.js.map +1 -0
  26. package/dist/src/checker/assignability.d.ts +13 -0
  27. package/dist/src/checker/assignability.js +146 -0
  28. package/dist/src/checker/assignability.js.map +1 -0
  29. package/dist/src/checker/calls.d.ts +13 -0
  30. package/dist/src/checker/calls.js +127 -0
  31. package/dist/src/checker/calls.js.map +1 -0
  32. package/dist/src/checker/checker.d.ts +26 -0
  33. package/dist/src/checker/checker.js +31 -0
  34. package/dist/src/checker/checker.js.map +1 -0
  35. package/dist/src/checker/declarations.d.ts +9 -0
  36. package/dist/src/checker/declarations.js +15 -0
  37. package/dist/src/checker/declarations.js.map +1 -0
  38. package/dist/src/checker/flow.d.ts +21 -0
  39. package/dist/src/checker/flow.js +241 -0
  40. package/dist/src/checker/flow.js.map +1 -0
  41. package/dist/src/checker/globals.d.ts +9 -0
  42. package/dist/src/checker/globals.js +29 -0
  43. package/dist/src/checker/globals.js.map +1 -0
  44. package/dist/src/checker/source.d.ts +38 -0
  45. package/dist/src/checker/source.js +48 -0
  46. package/dist/src/checker/source.js.map +1 -0
  47. package/dist/src/checker/type-infer.d.ts +18 -0
  48. package/dist/src/checker/type-infer.js +173 -0
  49. package/dist/src/checker/type-infer.js.map +1 -0
  50. package/dist/src/checker/type-model.d.ts +73 -0
  51. package/dist/src/checker/type-model.js +151 -0
  52. package/dist/src/checker/type-model.js.map +1 -0
  53. package/dist/src/checker/type-system.d.ts +58 -0
  54. package/dist/src/checker/type-system.js +569 -0
  55. package/dist/src/checker/type-system.js.map +1 -0
  56. package/dist/src/checker/typecheck-types.d.ts +22 -0
  57. package/dist/src/checker/typecheck-types.js +109 -0
  58. package/dist/src/checker/typecheck-types.js.map +1 -0
  59. package/dist/src/checker/typecheck.d.ts +62 -0
  60. package/dist/src/checker/typecheck.js +574 -0
  61. package/dist/src/checker/typecheck.js.map +1 -0
  62. package/dist/src/checker/undefined.d.ts +14 -0
  63. package/dist/src/checker/undefined.js +32 -0
  64. package/dist/src/checker/undefined.js.map +1 -0
  65. package/dist/src/checker/walk.d.ts +10 -0
  66. package/dist/src/checker/walk.js +15 -0
  67. package/dist/src/checker/walk.js.map +1 -0
  68. package/dist/src/cli/help.d.ts +7 -0
  69. package/dist/src/cli/help.js +64 -0
  70. package/dist/src/cli/help.js.map +1 -0
  71. package/dist/src/cli/hints.js +2 -1
  72. package/dist/src/cli/hints.js.map +1 -1
  73. package/dist/src/cli/main.js +12 -48
  74. package/dist/src/cli/main.js.map +1 -1
  75. package/dist/src/codegen/generator/calls/access.js +8 -8
  76. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  77. package/dist/src/codegen/generator/calls/invocation.js +9 -4
  78. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  79. package/dist/src/codegen/generator/calls/super.d.ts +9 -1
  80. package/dist/src/codegen/generator/calls/super.js +56 -5
  81. package/dist/src/codegen/generator/calls/super.js.map +1 -1
  82. package/dist/src/codegen/generator/context.d.ts +13 -2
  83. package/dist/src/codegen/generator/context.js +25 -19
  84. package/dist/src/codegen/generator/context.js.map +1 -1
  85. package/dist/src/codegen/generator/debug.js +2 -1
  86. package/dist/src/codegen/generator/debug.js.map +1 -1
  87. package/dist/src/codegen/generator/expressions/primary.d.ts +4 -1
  88. package/dist/src/codegen/generator/expressions/primary.js +68 -8
  89. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  90. package/dist/src/codegen/generator/generator.js +11 -1
  91. package/dist/src/codegen/generator/generator.js.map +1 -1
  92. package/dist/src/codegen/generator/module.d.ts +3 -0
  93. package/dist/src/codegen/generator/module.js +116 -26
  94. package/dist/src/codegen/generator/module.js.map +1 -1
  95. package/dist/src/codegen/generator/state.d.ts +11 -1
  96. package/dist/src/codegen/generator/state.js.map +1 -1
  97. package/dist/src/codegen/generator/statements/variables.js +26 -7
  98. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  99. package/dist/src/codegen/generator/tables.d.ts +2 -0
  100. package/dist/src/codegen/generator/tables.js +4 -0
  101. package/dist/src/codegen/generator/tables.js.map +1 -1
  102. package/dist/src/driver/build-key.d.ts +2 -0
  103. package/dist/src/driver/build-key.js +1 -0
  104. package/dist/src/driver/build-key.js.map +1 -1
  105. package/dist/src/driver/bundler/graph.js +5 -1
  106. package/dist/src/driver/bundler/graph.js.map +1 -1
  107. package/dist/src/driver/bundler/merge.js +16 -1
  108. package/dist/src/driver/bundler/merge.js.map +1 -1
  109. package/dist/src/driver/bundler/types.d.ts +12 -0
  110. package/dist/src/driver/compiler.d.ts +1 -1
  111. package/dist/src/driver/compiler.js +3 -0
  112. package/dist/src/driver/compiler.js.map +1 -1
  113. package/dist/src/driver/fingerprint.js +2 -1
  114. package/dist/src/driver/fingerprint.js.map +1 -1
  115. package/dist/src/driver/frontend.d.ts +8 -6
  116. package/dist/src/driver/frontend.js +4 -0
  117. package/dist/src/driver/frontend.js.map +1 -1
  118. package/dist/src/driver/options.d.ts +6 -0
  119. package/dist/src/driver/version.d.ts +1 -1
  120. package/dist/src/driver/version.js +1 -1
  121. package/dist/src/extensions/gui/css.d.ts +26 -0
  122. package/dist/src/extensions/gui/css.js +100 -0
  123. package/dist/src/extensions/gui/css.js.map +1 -0
  124. package/dist/src/extensions/gui/html.js +28 -7
  125. package/dist/src/extensions/gui/html.js.map +1 -1
  126. package/dist/src/extensions/gui/index.js +79 -2
  127. package/dist/src/extensions/gui/index.js.map +1 -1
  128. package/dist/src/extensions/gui/three.d.ts +16 -0
  129. package/dist/src/extensions/gui/three.js +22 -0
  130. package/dist/src/extensions/gui/three.js.map +1 -0
  131. package/dist/src/extensions/media/index.d.ts +6 -5
  132. package/dist/src/extensions/media/index.js +12 -14
  133. package/dist/src/extensions/media/index.js.map +1 -1
  134. package/dist/src/extensions/registry.d.ts +38 -0
  135. package/dist/src/extensions/registry.js +10 -0
  136. package/dist/src/extensions/registry.js.map +1 -1
  137. package/dist/src/index.d.ts +1 -0
  138. package/dist/src/index.js +1 -0
  139. package/dist/src/index.js.map +1 -1
  140. package/dist/src/parser/declarations/classes.js +7 -0
  141. package/dist/src/parser/declarations/classes.js.map +1 -1
  142. package/dist/src/parser/expressions.js +14 -1
  143. package/dist/src/parser/expressions.js.map +1 -1
  144. package/dist/src/parser/literals.js +6 -2
  145. package/dist/src/parser/literals.js.map +1 -1
  146. package/dist/tests/binder/binder.test.js +29 -0
  147. package/dist/tests/binder/binder.test.js.map +1 -1
  148. package/dist/tests/canonical.test.d.ts +1 -0
  149. package/dist/tests/canonical.test.js +19 -0
  150. package/dist/tests/canonical.test.js.map +1 -0
  151. package/dist/tests/checker/checker.test.d.ts +1 -0
  152. package/dist/tests/checker/checker.test.js +245 -0
  153. package/dist/tests/checker/checker.test.js.map +1 -0
  154. package/dist/tests/cli/check.test.js +20 -0
  155. package/dist/tests/cli/check.test.js.map +1 -1
  156. package/dist/tests/conformance/matrix.test.d.ts +6 -0
  157. package/dist/tests/conformance/matrix.test.js +23 -0
  158. package/dist/tests/conformance/matrix.test.js.map +1 -0
  159. package/dist/tests/conformance/test262/manifest.d.ts +115 -0
  160. package/dist/tests/conformance/test262/manifest.js +257 -0
  161. package/dist/tests/conformance/test262/manifest.js.map +1 -0
  162. package/dist/tests/conformance/test262.test.d.ts +11 -0
  163. package/dist/tests/conformance/test262.test.js +74 -0
  164. package/dist/tests/conformance/test262.test.js.map +1 -0
  165. package/dist/tests/docs/structure.test.js +9 -11
  166. package/dist/tests/docs/structure.test.js.map +1 -1
  167. package/dist/tests/e2e/child-process.test.js +3 -2
  168. package/dist/tests/e2e/child-process.test.js.map +1 -1
  169. package/dist/tests/e2e/compile-builtins.test.js +45 -0
  170. package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
  171. package/dist/tests/e2e/compile-objects-classes.test.js +77 -0
  172. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  173. package/dist/tests/e2e/differential-syntax.test.d.ts +5 -0
  174. package/dist/tests/e2e/differential-syntax.test.js +95 -0
  175. package/dist/tests/e2e/differential-syntax.test.js.map +1 -0
  176. package/dist/tests/e2e/differential-values.test.js +15 -0
  177. package/dist/tests/e2e/differential-values.test.js.map +1 -1
  178. package/dist/tests/e2e/gui-browser.test.d.ts +13 -0
  179. package/dist/tests/e2e/gui-browser.test.js +163 -0
  180. package/dist/tests/e2e/gui-browser.test.js.map +1 -0
  181. package/dist/tests/e2e/gui-effects.test.d.ts +6 -0
  182. package/dist/tests/e2e/gui-effects.test.js +262 -0
  183. package/dist/tests/e2e/gui-effects.test.js.map +1 -0
  184. package/dist/tests/e2e/gui-example-browser.test.js +2 -2
  185. package/dist/tests/e2e/gui-example-browser.test.js.map +1 -1
  186. package/dist/tests/e2e/gui-example-canvas.test.js +5 -4
  187. package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -1
  188. package/dist/tests/e2e/gui-example-svg.test.js +4 -3
  189. package/dist/tests/e2e/gui-example-svg.test.js.map +1 -1
  190. package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
  191. package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
  192. package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
  193. package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
  194. package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
  195. package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
  196. package/dist/tests/e2e/gui-example.test.js +4 -3
  197. package/dist/tests/e2e/gui-example.test.js.map +1 -1
  198. package/dist/tests/e2e/gui-helpers.js +4 -3
  199. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  200. package/dist/tests/e2e/gui-layout.test.js +48 -0
  201. package/dist/tests/e2e/gui-layout.test.js.map +1 -1
  202. package/dist/tests/e2e/gui-media.test.js +10 -8
  203. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  204. package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
  205. package/dist/tests/e2e/gui-webgl.test.js +179 -0
  206. package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
  207. package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
  208. package/dist/tests/e2e/gui-webgl2.test.js +238 -0
  209. package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
  210. package/dist/tests/e2e/harness.d.ts +9 -0
  211. package/dist/tests/e2e/harness.js +14 -2
  212. package/dist/tests/e2e/harness.js.map +1 -1
  213. package/dist/tests/e2e/native-extensions.test.js +2 -1
  214. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  215. package/dist/tests/e2e/property-descriptors.test.js +20 -0
  216. package/dist/tests/e2e/property-descriptors.test.js.map +1 -1
  217. package/dist/tests/e2e/unicode-output.test.js +5 -3
  218. package/dist/tests/e2e/unicode-output.test.js.map +1 -1
  219. package/dist/tests/e2e/weak-collections.test.js +16 -2
  220. package/dist/tests/e2e/weak-collections.test.js.map +1 -1
  221. package/dist/tests/extensions/gui.test.js +41 -0
  222. package/dist/tests/extensions/gui.test.js.map +1 -1
  223. package/dist/tests/extensions/media.test.js +7 -3
  224. package/dist/tests/extensions/media.test.js.map +1 -1
  225. package/dist/tests/helpers.d.ts +1 -0
  226. package/dist/tests/helpers.js +1 -0
  227. package/dist/tests/helpers.js.map +1 -1
  228. package/dist/tests/parser/declarations.test.js +20 -0
  229. package/dist/tests/parser/declarations.test.js.map +1 -1
  230. package/dist/tests/parser/expressions.test.js +36 -0
  231. package/dist/tests/parser/expressions.test.js.map +1 -1
  232. package/dist/tests/platform.d.ts +32 -0
  233. package/dist/tests/platform.js +40 -0
  234. package/dist/tests/platform.js.map +1 -0
  235. package/dist/tests/platform.test.d.ts +12 -0
  236. package/dist/tests/platform.test.js +51 -0
  237. package/dist/tests/platform.test.js.map +1 -0
  238. package/dist/tests/version.test.js +4 -4
  239. package/dist/tests/version.test.js.map +1 -1
  240. package/doc/ai/README.md +10 -4
  241. package/doc/ai/build-recipe.md +1 -0
  242. package/doc/ai/cli.md +17 -5
  243. package/doc/ai/contributing.md +59 -2
  244. package/doc/ai/extensions.md +38 -7
  245. package/doc/ai/language-support.md +25 -16
  246. package/doc/ai/troubleshooting.md +12 -8
  247. package/doc/ai/zh-CN/README.md +9 -4
  248. package/doc/ai/zh-CN/build-recipe.md +1 -0
  249. package/doc/ai/zh-CN/cli.md +13 -3
  250. package/doc/ai/zh-CN/contributing.md +49 -3
  251. package/doc/ai/zh-CN/extensions.md +33 -6
  252. package/doc/ai/zh-CN/language-support.md +23 -14
  253. package/doc/ai/zh-CN/troubleshooting.md +10 -6
  254. package/doc/gui/api.md +47 -1
  255. package/doc/gui/build.md +72 -16
  256. package/doc/gui/canvas.md +11 -3
  257. package/doc/gui/dom.md +33 -18
  258. package/doc/gui/known-issues.md +58 -15
  259. package/doc/gui/layout.md +18 -0
  260. package/doc/gui/media.md +17 -13
  261. package/doc/gui/rendering.md +50 -3
  262. package/doc/gui/runtime.md +18 -0
  263. package/doc/gui/webgl.md +256 -0
  264. package/doc/gui-scripts.md +7 -0
  265. package/doc/gui.md +108 -17
  266. package/doc/implemented/binder.md +2 -0
  267. package/doc/implemented/checker.md +117 -0
  268. package/doc/implemented/cli.md +13 -1
  269. package/doc/implemented/codegen.md +3 -2
  270. package/doc/implemented/driver.md +2 -2
  271. package/doc/implemented/operators.md +2 -1
  272. package/doc/implemented/parser.md +3 -2
  273. package/doc/implemented/pipeline.md +8 -1
  274. package/doc/implemented/stdlib.md +2 -1
  275. package/doc/implemented/tests.md +3 -1
  276. package/doc/implemented.md +2 -0
  277. package/doc/npm-package.md +419 -0
  278. package/doc/requirements.md +22 -10
  279. package/doc/support-matrix.md +83 -0
  280. package/doc/unimplemented/classes.md +3 -0
  281. package/doc/unimplemented/deviations.md +3 -2
  282. package/doc/unimplemented/toolchain.md +1 -1
  283. package/doc/unimplemented/types.md +24 -8
  284. package/doc/unimplemented.md +1 -1
  285. package/doc/zh-CN/gui/api.md +43 -1
  286. package/doc/zh-CN/gui/build.md +64 -15
  287. package/doc/zh-CN/gui/canvas.md +9 -2
  288. package/doc/zh-CN/gui/dom.md +20 -7
  289. package/doc/zh-CN/gui/known-issues.md +46 -13
  290. package/doc/zh-CN/gui/layout.md +14 -0
  291. package/doc/zh-CN/gui/media.md +15 -11
  292. package/doc/zh-CN/gui/rendering.md +41 -4
  293. package/doc/zh-CN/gui/runtime.md +16 -0
  294. package/doc/zh-CN/gui/webgl.md +115 -0
  295. package/doc/zh-CN/gui-scripts.md +5 -0
  296. package/doc/zh-CN/gui.md +89 -14
  297. package/doc/zh-CN/implemented/binder.md +2 -0
  298. package/doc/zh-CN/implemented/checker.md +99 -0
  299. package/doc/zh-CN/implemented/cli.md +12 -1
  300. package/doc/zh-CN/implemented/codegen.md +3 -2
  301. package/doc/zh-CN/implemented/driver.md +2 -2
  302. package/doc/zh-CN/implemented/operators.md +1 -1
  303. package/doc/zh-CN/implemented/parser.md +3 -2
  304. package/doc/zh-CN/implemented/pipeline.md +3 -1
  305. package/doc/zh-CN/implemented/stdlib.md +2 -1
  306. package/doc/zh-CN/implemented/tests.md +3 -1
  307. package/doc/zh-CN/implemented.md +2 -0
  308. package/doc/zh-CN/npm-package.md +394 -0
  309. package/doc/zh-CN/post/announce.md +47 -47
  310. package/doc/zh-CN/requirements.md +16 -7
  311. package/doc/zh-CN/support-matrix.md +82 -0
  312. package/doc/zh-CN/unimplemented/classes.md +3 -0
  313. package/doc/zh-CN/unimplemented/deviations.md +3 -2
  314. package/doc/zh-CN/unimplemented/toolchain.md +1 -1
  315. package/doc/zh-CN/unimplemented/types.md +16 -6
  316. package/doc/zh-CN/unimplemented.md +1 -1
  317. package/llms.txt +6 -1
  318. package/package.json +2 -1
  319. package/runtime/ext_gui/audio.cpp +316 -0
  320. package/runtime/ext_gui/browser.cpp +573 -0
  321. package/runtime/ext_gui/browser_escape.cpp +85 -0
  322. package/runtime/ext_gui/browser_loop.cpp +83 -0
  323. package/runtime/ext_gui/canvas.cpp +12 -21
  324. package/runtime/ext_gui/canvas_internal.h +10 -0
  325. package/runtime/ext_gui/canvas_raster.cpp +79 -1
  326. package/runtime/ext_gui/clip_values.cpp +246 -0
  327. package/runtime/ext_gui/css.cpp +94 -0
  328. package/runtime/ext_gui/css.h +22 -1
  329. package/runtime/ext_gui/css_match.cpp +3 -0
  330. package/runtime/ext_gui/css_selector.cpp +9 -0
  331. package/runtime/ext_gui/css_sheet.cpp +89 -45
  332. package/runtime/ext_gui/document.cpp +4 -1
  333. package/runtime/ext_gui/document.h +2 -0
  334. package/runtime/ext_gui/dom.h +16 -0
  335. package/runtime/ext_gui/dom_api.cpp +37 -0
  336. package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
  337. package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
  338. package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
  339. package/runtime/ext_gui/dom_api_document.cpp +96 -5
  340. package/runtime/ext_gui/dom_api_events.cpp +20 -0
  341. package/runtime/ext_gui/dom_api_internal.h +278 -0
  342. package/runtime/ext_gui/dom_api_proto.cpp +6 -0
  343. package/runtime/ext_gui/dom_api_webgl.cpp +376 -0
  344. package/runtime/ext_gui/dom_api_webgl2.cpp +434 -0
  345. package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
  346. package/runtime/ext_gui/dom_api_webgl_buffer.cpp +212 -0
  347. package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
  348. package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
  349. package/runtime/ext_gui/dom_api_webgl_state.cpp +444 -0
  350. package/runtime/ext_gui/dom_api_webgl_texture.cpp +445 -0
  351. package/runtime/ext_gui/effect_values.cpp +312 -0
  352. package/runtime/ext_gui/gradient_values.cpp +476 -0
  353. package/runtime/ext_gui/grid_values.cpp +230 -0
  354. package/runtime/ext_gui/gui.cpp +90 -23
  355. package/runtime/ext_gui/gui_canvas.cpp +50 -2
  356. package/runtime/ext_gui/gui_engine.h +71 -0
  357. package/runtime/ext_gui/gui_events.cpp +4 -1
  358. package/runtime/ext_gui/gui_media.cpp +1 -1
  359. package/runtime/ext_gui/gui_webgl.cpp +83 -0
  360. package/runtime/ext_gui/layout.cpp +21 -0
  361. package/runtime/ext_gui/layout_flow.cpp +81 -4
  362. package/runtime/ext_gui/layout_flow_internal.h +31 -0
  363. package/runtime/ext_gui/layout_grid.cpp +374 -0
  364. package/runtime/ext_gui/media.h +1 -1
  365. package/runtime/ext_gui/media_api.h +2 -2
  366. package/runtime/ext_gui/media_query.cpp +211 -0
  367. package/runtime/ext_gui/paint.cpp +111 -77
  368. package/runtime/ext_gui/paint.h +33 -3
  369. package/runtime/ext_gui/paint_background.cpp +229 -0
  370. package/runtime/ext_gui/paint_clip.cpp +268 -0
  371. package/runtime/ext_gui/paint_effects.cpp +324 -0
  372. package/runtime/ext_gui/paint_internal.h +85 -0
  373. package/runtime/ext_gui/renderer.cpp +8 -31
  374. package/runtime/ext_gui/renderer_clip.cpp +196 -0
  375. package/runtime/ext_gui/renderer_image.cpp +13 -8
  376. package/runtime/ext_gui/renderer_internal.h +15 -8
  377. package/runtime/ext_gui/renderer_text.cpp +6 -31
  378. package/runtime/ext_gui/style.cpp +343 -20
  379. package/runtime/ext_gui/style.h +144 -3
  380. package/runtime/ext_gui/style_print.cpp +134 -1
  381. package/runtime/ext_gui/style_values.cpp +152 -126
  382. package/runtime/ext_gui/style_values_internal.h +35 -0
  383. package/runtime/ext_gui/webgl.h +466 -0
  384. package/runtime/ext_gui/webgl2_constants.h +274 -0
  385. package/runtime/ext_gui/webgl_buffer.cpp +565 -0
  386. package/runtime/ext_gui/webgl_constants.h +317 -0
  387. package/runtime/ext_gui/webgl_context.cpp +466 -0
  388. package/runtime/ext_gui/webgl_draw.cpp +495 -0
  389. package/runtime/ext_gui/webgl_glsl.h +125 -0
  390. package/runtime/ext_gui/webgl_glsl_compile.cpp +431 -0
  391. package/runtime/ext_gui/webgl_glsl_rewrite.cpp +349 -0
  392. package/runtime/ext_gui/webgl_glsl_scan.cpp +581 -0
  393. package/runtime/ext_gui/webgl_msl.cpp +62 -0
  394. package/runtime/ext_gui/webgl_msl.h +33 -0
  395. package/runtime/ext_gui/webgl_pipeline.cpp +274 -0
  396. package/runtime/ext_gui/webgl_program_internal.h +18 -0
  397. package/runtime/ext_gui/webgl_shader.cpp +582 -0
  398. package/runtime/ext_gui/webgl_texture.cpp +293 -0
  399. package/runtime/ext_gui/webgl_uniform.cpp +167 -0
  400. package/runtime/ext_gui/webgl_webgl2.cpp +224 -0
  401. package/runtime/ext_gui/window.cpp +9 -0
  402. package/runtime/ext_media/media.cpp +1 -1
  403. package/runtime/ext_media/media_bridge.c +9 -3
  404. package/runtime/ext_node/path/path.c +7 -7
  405. package/runtime/ext_node/url/url.c +4 -2
  406. package/runtime/rt.h +15 -0
  407. package/runtime/rt_internal.h +1 -0
  408. package/runtime/xt_constructors.c +2 -1
  409. package/runtime/xt_containers/access.inc +8 -0
  410. package/runtime/xt_containers/objects.inc +22 -2
  411. package/runtime/xt_io/exception.inc +4 -2
  412. package/runtime/xt_regex/api.inc +2 -0
  413. package/runtime/xt_regex/matcher.inc +16 -3
  414. package/runtime/xt_regex/parser.inc +8 -2
  415. package/runtime/xt_regex/types.inc +3 -0
  416. package/runtime/xt_stdlib/math.inc +62 -0
  417. package/runtime/xt_stdlib2/date.inc +7 -1
  418. package/runtime/xt_stdlib2/objects.inc +14 -0
  419. package/runtime/xt_stdlib2/regexp-match.inc +60 -21
  420. package/runtime/xt_stdlib2/regexp.inc +1 -0
  421. package/runtime/xt_typed_array.c +1 -1
  422. package/scripts/build-gui.ts +90 -3
  423. package/scripts/build-media.ts +323 -58
  424. package/scripts/setup-vs-toolchain.ps1 +152 -0
  425. package/scripts/support-matrix.ts +167 -0
  426. package/src/ast/common.ts +2 -0
  427. package/src/ast/declarations.ts +12 -1
  428. package/src/ast/expressions.ts +6 -0
  429. package/src/ast/kinds.ts +2 -0
  430. package/src/binder/binder.ts +3 -0
  431. package/src/binder/declarations.ts +70 -0
  432. package/src/binder/references.ts +97 -4
  433. package/src/binder/types.ts +30 -0
  434. package/src/canonical.ts +37 -0
  435. package/src/checker/assignability.ts +134 -0
  436. package/src/checker/calls.ts +135 -0
  437. package/src/checker/checker.ts +47 -0
  438. package/src/checker/declarations.ts +26 -0
  439. package/src/checker/flow.ts +236 -0
  440. package/src/checker/globals.ts +40 -0
  441. package/src/checker/source.ts +53 -0
  442. package/src/checker/type-infer.ts +185 -0
  443. package/src/checker/type-model.ts +212 -0
  444. package/src/checker/type-system.ts +578 -0
  445. package/src/checker/typecheck-types.ts +112 -0
  446. package/src/checker/typecheck.ts +586 -0
  447. package/src/checker/undefined.ts +43 -0
  448. package/src/checker/walk.ts +16 -0
  449. package/src/cli/help.ts +65 -0
  450. package/src/cli/hints.ts +2 -1
  451. package/src/cli/main.ts +12 -49
  452. package/src/codegen/generator/calls/access.ts +8 -8
  453. package/src/codegen/generator/calls/invocation.ts +8 -5
  454. package/src/codegen/generator/calls/super.ts +67 -5
  455. package/src/codegen/generator/context.ts +31 -19
  456. package/src/codegen/generator/debug.ts +2 -1
  457. package/src/codegen/generator/expressions/primary.ts +84 -13
  458. package/src/codegen/generator/generator.ts +11 -1
  459. package/src/codegen/generator/module.ts +115 -24
  460. package/src/codegen/generator/state.ts +11 -1
  461. package/src/codegen/generator/statements/variables.ts +26 -6
  462. package/src/codegen/generator/tables.ts +5 -0
  463. package/src/driver/build-key.ts +3 -0
  464. package/src/driver/bundler/graph.ts +6 -2
  465. package/src/driver/bundler/merge.ts +14 -1
  466. package/src/driver/bundler/types.ts +13 -0
  467. package/src/driver/compiler.ts +4 -1
  468. package/src/driver/fingerprint.ts +2 -1
  469. package/src/driver/frontend.ts +13 -2
  470. package/src/driver/options.ts +6 -0
  471. package/src/driver/version.ts +1 -1
  472. package/src/extensions/gui/css.ts +113 -0
  473. package/src/extensions/gui/html.ts +31 -11
  474. package/src/extensions/gui/index.ts +81 -2
  475. package/src/extensions/gui/three.ts +25 -0
  476. package/src/extensions/media/index.ts +13 -16
  477. package/src/extensions/registry.ts +48 -0
  478. package/src/index.ts +1 -0
  479. package/src/parser/declarations/classes.ts +7 -0
  480. package/src/parser/expressions.ts +13 -1
  481. package/src/parser/literals.ts +6 -2
@@ -38,6 +38,18 @@ static std::string formatLength(const Length &length) {
38
38
  return formatNumber(length.value) + "vw";
39
39
  case Unit::Vh:
40
40
  return formatNumber(length.value) + "vh";
41
+ case Unit::Clamp:
42
+ case Unit::Min:
43
+ case Unit::Max: {
44
+ const char *name = length.unit == Unit::Clamp ? "clamp" : (length.unit == Unit::Min ? "min" : "max");
45
+ std::string text = std::string(name) + "(";
46
+ for (size_t i = 0; i < length.args.size(); i++) {
47
+ if (i > 0) text += ", ";
48
+ text += xt_style_length_to_string(length.args[i]);
49
+ }
50
+ text += ")";
51
+ return text;
52
+ }
41
53
  default:
42
54
  return "";
43
55
  }
@@ -56,9 +68,116 @@ static std::string formatColor(const Color &color) {
56
68
  return buffer;
57
69
  }
58
70
 
71
+ static std::string quoteText(const std::string &text) {
72
+ std::string out = "\"";
73
+ for (char c : text) {
74
+ if (c == '"' || c == '\\') out.push_back('\\');
75
+ out.push_back(c);
76
+ }
77
+ out.push_back('"');
78
+ return out;
79
+ }
80
+
81
+ static std::string formatFilterList(const std::vector<FilterOp> &filters) {
82
+ if (filters.empty()) return "none";
83
+ std::string out;
84
+ for (const FilterOp &filter : filters) {
85
+ if (!out.empty()) out += " ";
86
+ switch (filter.kind) {
87
+ case FilterKind::Blur:
88
+ out += "blur(" + formatLength(filter.blur) + ")";
89
+ break;
90
+ case FilterKind::Brightness:
91
+ out += "brightness(" + formatNumber(filter.amount) + ")";
92
+ break;
93
+ case FilterKind::Contrast:
94
+ out += "contrast(" + formatNumber(filter.amount) + ")";
95
+ break;
96
+ case FilterKind::Grayscale:
97
+ out += "grayscale(" + formatNumber(filter.amount) + ")";
98
+ break;
99
+ case FilterKind::Sepia:
100
+ out += "sepia(" + formatNumber(filter.amount) + ")";
101
+ break;
102
+ case FilterKind::Invert:
103
+ out += "invert(" + formatNumber(filter.amount) + ")";
104
+ break;
105
+ case FilterKind::Saturate:
106
+ out += "saturate(" + formatNumber(filter.amount) + ")";
107
+ break;
108
+ case FilterKind::HueRotate:
109
+ out += "hue-rotate(" + formatNumber(filter.amount) + "deg)";
110
+ break;
111
+ case FilterKind::Opacity:
112
+ out += "opacity(" + formatNumber(filter.amount) + ")";
113
+ break;
114
+ case FilterKind::DropShadow:
115
+ out += "drop-shadow(" + formatLength(filter.dx) + " " + formatLength(filter.dy);
116
+ if (filter.blur.unit != Unit::Px || filter.blur.value != 0.0f)
117
+ out += " " + formatLength(filter.blur);
118
+ if (filter.has_color) out += " " + formatColor(filter.color);
119
+ out += ")";
120
+ break;
121
+ }
122
+ }
123
+ return out;
124
+ }
125
+
126
+ static std::string formatTextShadows(const std::vector<TextShadow> &shadows) {
127
+ if (shadows.empty()) return "none";
128
+ std::string out;
129
+ for (const TextShadow &shadow : shadows) {
130
+ if (!out.empty()) out += ", ";
131
+ out += formatLength(shadow.dx) + " " + formatLength(shadow.dy);
132
+ if (shadow.blur.unit != Unit::Px || shadow.blur.value != 0.0f)
133
+ out += " " + formatLength(shadow.blur);
134
+ if (shadow.has_color) out += " " + formatColor(shadow.color);
135
+ }
136
+ return out;
137
+ }
138
+
139
+ static std::string formatClipPath(const ClipPathSpec &clip) {
140
+ switch (clip.type) {
141
+ case ClipPathSpec::Type::None:
142
+ return "none";
143
+ case ClipPathSpec::Type::Inset: {
144
+ std::string out = "inset(" + formatLength(clip.inset_top) + " " +
145
+ formatLength(clip.inset_right) + " " + formatLength(clip.inset_bottom) +
146
+ " " + formatLength(clip.inset_left);
147
+ if (clip.inset_radius.unit != Unit::Px || clip.inset_radius.value != 0.0f)
148
+ out += " round " + formatLength(clip.inset_radius);
149
+ return out + ")";
150
+ }
151
+ case ClipPathSpec::Type::Circle:
152
+ case ClipPathSpec::Type::Ellipse: {
153
+ bool circle = clip.type == ClipPathSpec::Type::Circle;
154
+ std::string out = std::string(circle ? "circle(" : "ellipse(");
155
+ if (clip.radius_explicit) {
156
+ if (circle) out += formatLength(clip.radius_x);
157
+ else out += formatLength(clip.radius_x) + " " + formatLength(clip.radius_y);
158
+ out += " at ";
159
+ } else {
160
+ out += "at ";
161
+ }
162
+ out += formatLength(clip.center_x) + " " + formatLength(clip.center_y) + ")";
163
+ return out;
164
+ }
165
+ case ClipPathSpec::Type::Polygon: {
166
+ std::string out = "polygon(";
167
+ for (size_t i = 0; i + 1 < clip.polygon.size(); i += 2) {
168
+ if (i > 0) out += ", ";
169
+ out += formatLength(clip.polygon[i]) + " " + formatLength(clip.polygon[i + 1]);
170
+ }
171
+ return out + ")";
172
+ }
173
+ }
174
+ return "none";
175
+ }
176
+
59
177
  std::string xt_style_property_to_string(const XtStyle &style, const std::string &rawProperty) {
60
178
  std::string property = xt_css_lower(xt_css_trim(rawProperty));
61
- static const char *const displayNames[] = {"none", "block", "inline", "inline-block", "flex", "list-item"};
179
+ static const char *const displayNames[] = {"none", "block", "inline", "inline-block", "flex",
180
+ "grid", "list-item"};
62
181
  static const char *const positionNames[] = {"static", "relative", "absolute", "fixed"};
63
182
  static const char *const flexNames[] = {"row", "row-reverse", "column", "column-reverse"};
64
183
  static const char *const wrapNames[] = {"nowrap", "wrap", "wrap-reverse"};
@@ -118,6 +237,20 @@ std::string xt_style_property_to_string(const XtStyle &style, const std::string
118
237
  if (property == "border-radius") return formatNumber(style.border_radius) + "px";
119
238
  if (property == "opacity") return formatNumber(style.opacity);
120
239
  if (property == "z-index") return style.has_z_index ? formatNumber((float)style.z_index) : "auto";
240
+ if (property == "content") return style.has_content ? quoteText(style.content) : "none";
241
+ if (property == "clip-path") return formatClipPath(style.clip_path);
242
+ if (property == "filter") return formatFilterList(style.filters);
243
+ if (property == "backdrop-filter") return formatFilterList(style.backdrop_filters);
244
+ if (property == "text-shadow") return formatTextShadows(style.text_shadow);
245
+ if (property == "background-image") {
246
+ if (style.background_layers.empty()) return "none";
247
+ std::string out;
248
+ for (const BackgroundLayer &layer : style.background_layers) {
249
+ if (!out.empty()) out += ", ";
250
+ out += layer.kind == BackgroundKind::Linear ? "linear-gradient()" : "radial-gradient()";
251
+ }
252
+ return out;
253
+ }
121
254
  if (property == "transform") return xt_transform_to_string(style.transform);
122
255
  if (property == "transform-origin") {
123
256
  return formatLength(style.transform_origin_x) + " " + formatLength(style.transform_origin_y);
@@ -4,8 +4,10 @@
4
4
  */
5
5
 
6
6
  #include "style_internal.h"
7
+ #include "style_values_internal.h"
7
8
 
8
9
  #include <cstdlib>
10
+ #include <cstring>
9
11
  #include <vector>
10
12
 
11
13
  namespace xtgui {
@@ -19,8 +21,30 @@ static void setEdge(Edges *edges, const std::string &side, Length value) {
19
21
  else if (side == "left") edges->left = value;
20
22
  }
21
23
 
24
+ /* Split on whitespace outside function parentheses, so
25
+ * `clamp(26px, 5.4vw, 84px)` is one edge value rather than three tokens. */
26
+ static std::vector<std::string> splitEdgeTokens(const std::string &text) {
27
+ std::vector<std::string> parts;
28
+ std::string current;
29
+ int depth = 0;
30
+ for (char c : text) {
31
+ if (c == '(') depth++;
32
+ if (c == ')') depth--;
33
+ if ((c == ' ' || c == '\t' || c == '\n' || c == '\r') && depth == 0) {
34
+ if (!current.empty()) {
35
+ parts.push_back(current);
36
+ current.clear();
37
+ }
38
+ } else {
39
+ current.push_back(c);
40
+ }
41
+ }
42
+ if (!current.empty()) parts.push_back(current);
43
+ return parts;
44
+ }
45
+
22
46
  static bool parseEdgeLengths(const std::string &value, Edges *edges) {
23
- std::vector<std::string> parts = xt_css_split_whitespace(value);
47
+ std::vector<std::string> parts = splitEdgeTokens(value);
24
48
  if (parts.empty() || parts.size() > 4) return false;
25
49
  Length values[4];
26
50
  for (size_t i = 0; i < parts.size(); i++) {
@@ -57,6 +81,41 @@ static bool parseEdgeLengths(const std::string &value, Edges *edges) {
57
81
  return true;
58
82
  }
59
83
 
84
+
85
+ /** `inset: <top> <right> <bottom> <left>` (1-4 values, like margin). */
86
+ static bool parseInsetLengths(const std::string &value, Length *top, Length *right, Length *bottom,
87
+ Length *left) {
88
+ std::vector<std::string> parts = splitEdgeTokens(value);
89
+ if (parts.empty() || parts.size() > 4) return false;
90
+ Length values[4];
91
+ for (size_t i = 0; i < parts.size(); i++) {
92
+ Length length = xt_css_parse_length(parts[i]);
93
+ if (length.unit == Unit::Invalid) return false;
94
+ values[i] = length;
95
+ }
96
+ switch (parts.size()) {
97
+ case 1:
98
+ *top = *right = *bottom = *left = values[0];
99
+ break;
100
+ case 2:
101
+ *top = *bottom = values[0];
102
+ *right = *left = values[1];
103
+ break;
104
+ case 3:
105
+ *top = values[0];
106
+ *right = *left = values[1];
107
+ *bottom = values[2];
108
+ break;
109
+ default:
110
+ *top = values[0];
111
+ *right = values[1];
112
+ *bottom = values[2];
113
+ *left = values[3];
114
+ break;
115
+ }
116
+ return true;
117
+ }
118
+
60
119
  static bool assignLength(Length *target, const std::string &value) {
61
120
  Length length = xt_css_parse_length(value);
62
121
  if (length.unit == Unit::Invalid) return false;
@@ -64,17 +123,37 @@ static bool assignLength(Length *target, const std::string &value) {
64
123
  return true;
65
124
  }
66
125
 
67
- static bool assignColor(Color *target, bool *has, const std::string &value) {
68
- Color color = xt_css_parse_color(value);
69
- if (!color.valid) return false;
70
- *target = color;
71
- *has = true;
72
- return true;
73
- }
74
126
 
75
127
  float xt_style_resolve_absolute(const Length &length, float base, float em, float root, float vw,
76
128
  float vh) {
77
129
  switch (length.unit) {
130
+ case Unit::Clamp: {
131
+ if (length.args.size() < 3) return 0.0f;
132
+ float low = xt_style_resolve_absolute(length.args[0], base, em, root, vw, vh);
133
+ float value = xt_style_resolve_absolute(length.args[1], base, em, root, vw, vh);
134
+ float high = xt_style_resolve_absolute(length.args[2], base, em, root, vw, vh);
135
+ return value < low ? low : (value > high ? high : value);
136
+ }
137
+ case Unit::Min: {
138
+ float best = 0.0f;
139
+ bool first = true;
140
+ for (const Length &arg : length.args) {
141
+ float value = xt_style_resolve_absolute(arg, base, em, root, vw, vh);
142
+ if (first || value < best) best = value;
143
+ first = false;
144
+ }
145
+ return best;
146
+ }
147
+ case Unit::Max: {
148
+ float best = 0.0f;
149
+ bool first = true;
150
+ for (const Length &arg : length.args) {
151
+ float value = xt_style_resolve_absolute(arg, base, em, root, vw, vh);
152
+ if (first || value > best) best = value;
153
+ first = false;
154
+ }
155
+ return best;
156
+ }
78
157
  case Unit::Px:
79
158
  case Unit::Number:
80
159
  return length.value;
@@ -104,84 +183,14 @@ static bool parseEnum(const std::string &value, const char *const *names, int co
104
183
  return false;
105
184
  }
106
185
 
107
- /* -- transitions ---------------------------------------------------------- */
108
-
109
- static bool parseTimeSeconds(const std::string &text, float *out) {
110
- std::string token = xt_css_trim(text);
111
- if (token.empty()) return false;
112
- const char *begin = token.c_str();
113
- char *end = nullptr;
114
- double value = std::strtod(begin, &end);
115
- if (end == begin) return false;
116
- std::string unit = xt_css_lower(xt_css_trim(std::string(end)));
117
- if (unit == "ms") {
118
- *out = (float)(value / 1000.0);
119
- } else if (unit.empty() || unit == "s") {
120
- *out = (float)value;
121
- } else {
122
- return false;
123
- }
124
- return true;
125
- }
126
-
127
- static bool parseTimingFunction(const std::string &text, TimingFunction *out) {
128
- std::string token = xt_css_lower(xt_css_trim(text));
129
- if (token == "linear") {
130
- *out = TimingFunction::Linear;
131
- } else if (token == "ease") {
132
- *out = TimingFunction::Ease;
133
- } else if (token == "ease-in") {
134
- *out = TimingFunction::EaseIn;
135
- } else if (token == "ease-out") {
136
- *out = TimingFunction::EaseOut;
137
- } else if (token == "ease-in-out") {
138
- *out = TimingFunction::EaseInOut;
139
- } else {
140
- return false;
141
- }
186
+ static bool assignColor(Color *target, bool *has, const std::string &value) {
187
+ Color color = xt_css_parse_color(value);
188
+ if (!color.valid) return false;
189
+ *target = color;
190
+ *has = true;
142
191
  return true;
143
192
  }
144
193
 
145
- static std::vector<std::string> splitCommas(const std::string &text) {
146
- std::vector<std::string> parts;
147
- size_t start = 0;
148
- for (size_t i = 0; i <= text.size(); i++) {
149
- if (i == text.size() || text[i] == ',') {
150
- std::string part = xt_css_trim(text.substr(start, i - start));
151
- if (!part.empty()) parts.push_back(part);
152
- start = i + 1;
153
- }
154
- }
155
- return parts;
156
- }
157
-
158
- static void parseTransitionShorthand(const std::string &value, std::vector<TransitionSpec> *out) {
159
- out->clear();
160
- for (const std::string &group : splitCommas(value)) {
161
- std::vector<std::string> tokens = xt_css_split_whitespace(group);
162
- if (tokens.empty()) continue;
163
- TransitionSpec spec;
164
- int time_seen = 0;
165
- for (const std::string &token : tokens) {
166
- float seconds = 0;
167
- TimingFunction timing = TimingFunction::Ease;
168
- if (parseTimeSeconds(token, &seconds)) {
169
- if (time_seen == 0) {
170
- spec.duration = seconds;
171
- } else {
172
- spec.delay = seconds;
173
- }
174
- time_seen++;
175
- } else if (parseTimingFunction(token, &timing)) {
176
- spec.timing = timing;
177
- } else {
178
- spec.property = xt_css_lower(token);
179
- }
180
- }
181
- out->push_back(spec);
182
- }
183
- }
184
-
185
194
  /* -- declaration application ---------------------------------------------- */
186
195
 
187
196
  void xt_style_apply_declaration(XtStyle *style, const std::string &property,
@@ -189,9 +198,30 @@ void xt_style_apply_declaration(XtStyle *style, const std::string &property,
189
198
  std::string value = xt_css_trim(rawValue);
190
199
 
191
200
  if (property == "display") {
192
- static const char *const names[] = {"none", "block", "inline", "inline-block", "flex", "list-item"};
201
+ static const char *const names[] = {"none", "block", "inline", "inline-block", "flex", "grid",
202
+ "list-item"};
193
203
  int index = 0;
194
- if (parseEnum(value, names, 6, &index)) style->display = (Display)index;
204
+ if (parseEnum(value, names, 7, &index)) style->display = (Display)index;
205
+ return;
206
+ }
207
+ if (property == "visibility") {
208
+ std::string text = xt_css_lower(xt_css_trim(value));
209
+ if (text == "hidden" || text == "collapse") style->visible = false;
210
+ else if (text == "visible") style->visible = true;
211
+ return;
212
+ }
213
+ if (property == "pointer-events") {
214
+ std::string text = xt_css_lower(xt_css_trim(value));
215
+ if (text == "none") style->pointer_events = false;
216
+ else if (text == "auto" || text == "all" || text == "visiblepainted" ||
217
+ text == "visiblefill" || text == "visiblestroke")
218
+ style->pointer_events = true;
219
+ return;
220
+ }
221
+ if (property == "box-sizing") {
222
+ std::string text = xt_css_lower(xt_css_trim(value));
223
+ if (text == "border-box") style->box_sizing = BoxSizing::BorderBox;
224
+ else if (text == "content-box") style->box_sizing = BoxSizing::ContentBox;
195
225
  return;
196
226
  }
197
227
  if (property == "position") {
@@ -210,6 +240,10 @@ void xt_style_apply_declaration(XtStyle *style, const std::string &property,
210
240
  if (property == "right") { assignLength(&style->right, value); return; }
211
241
  if (property == "bottom") { assignLength(&style->bottom, value); return; }
212
242
  if (property == "left") { assignLength(&style->left, value); return; }
243
+ if (property == "inset") {
244
+ parseInsetLengths(value, &style->top, &style->right, &style->bottom, &style->left);
245
+ return;
246
+ }
213
247
 
214
248
  if (property == "margin") { parseEdgeLengths(value, &style->margin); return; }
215
249
  if (property == "padding") { parseEdgeLengths(value, &style->padding); return; }
@@ -274,14 +308,19 @@ void xt_style_apply_declaration(XtStyle *style, const std::string &property,
274
308
  return;
275
309
  }
276
310
  if (property == "background-color") { assignColor(&style->background, &style->has_background, value); return; }
311
+ if (property == "background-image") {
312
+ xt_style_apply_background_image(style, value);
313
+ return;
314
+ }
277
315
  if (property == "background") {
278
- Color color = xt_css_parse_color(value);
279
- if (color.valid) {
280
- style->background = color;
281
- style->has_background = true;
282
- }
316
+ xt_style_apply_background(style, value);
317
+ return;
318
+ }
319
+ if (property == "clip-path") {
320
+ xt_style_apply_clip_path(style, property, value);
283
321
  return;
284
322
  }
323
+ if (xt_style_apply_effect(style, property, value)) return;
285
324
 
286
325
  if (property == "font-size") {
287
326
  Length length = xt_css_parse_length(value);
@@ -319,6 +358,25 @@ void xt_style_apply_declaration(XtStyle *style, const std::string &property,
319
358
  style->line_height = {};
320
359
  return;
321
360
  }
361
+ /* A unitless `line-height` is a multiplier, not a length in pixels. The
362
+ * generic length parser maps a bare number to `px`, which collapsed
363
+ * `line-height: 0.76` / `1.9` to sub-pixel leading and made consecutive
364
+ * lines overlap. */
365
+ bool hasUnit = false;
366
+ for (const char *suffix : {"px", "%", "em", "rem", "vw", "vh", "pt", "pc", "in", "cm", "mm", "q"}) {
367
+ size_t length = std::strlen(suffix);
368
+ if (text.size() >= length && text.compare(text.size() - length, length, suffix) == 0) {
369
+ hasUnit = true;
370
+ break;
371
+ }
372
+ }
373
+ if (!hasUnit) {
374
+ float number = 0;
375
+ if (xt_css_parse_number(text, &number)) {
376
+ style->line_height = {number, Unit::Number};
377
+ return;
378
+ }
379
+ }
322
380
  Length length = xt_css_parse_length(text);
323
381
  if (length.unit == Unit::Invalid) return;
324
382
  /* Relative units are resolved in `finalizeStyle`, once the element's own
@@ -341,6 +399,8 @@ void xt_style_apply_declaration(XtStyle *style, const std::string &property,
341
399
  return;
342
400
  }
343
401
 
402
+ if (xt_style_apply_grid_property(style, property, value)) return;
403
+
344
404
  if (property == "flex-direction") {
345
405
  static const char *const names[] = {"row", "row-reverse", "column", "column-reverse"};
346
406
  int index = 0;
@@ -371,12 +431,6 @@ void xt_style_apply_declaration(XtStyle *style, const std::string &property,
371
431
  if (parseEnum(value, names, 6, &index)) style->justify_content = (JustifyContent)index;
372
432
  return;
373
433
  }
374
- if (property == "align-items") {
375
- static const char *const names[] = {"stretch", "flex-start", "flex-end", "center", "baseline"};
376
- int index = 0;
377
- if (parseEnum(value, names, 5, &index)) style->align_items = (AlignItems)index;
378
- return;
379
- }
380
434
  if (property == "align-content") {
381
435
  static const char *const names[] = {"stretch", "flex-start", "flex-end", "center",
382
436
  "space-between", "space-around"};
@@ -515,36 +569,8 @@ void xt_style_apply_declaration(XtStyle *style, const std::string &property,
515
569
  if (parseEnum(value, names, 4, &index)) style->clear = (Clear)index;
516
570
  return;
517
571
  }
518
- if (property == "transition") {
519
- parseTransitionShorthand(value, &style->transitions);
520
- return;
521
- }
522
- if (property == "transition-property") {
523
- std::vector<std::string> parts = splitCommas(value);
524
- style->transitions.resize(parts.size());
525
- for (size_t i = 0; i < parts.size(); i++) style->transitions[i].property = xt_css_lower(parts[i]);
526
- return;
527
- }
528
- if (property == "transition-duration" || property == "transition-delay") {
529
- std::vector<std::string> parts = splitCommas(value);
530
- style->transitions.resize(parts.size());
531
- for (size_t i = 0; i < parts.size(); i++) {
532
- float seconds = 0;
533
- if (!parseTimeSeconds(parts[i], &seconds)) continue;
534
- if (property == "transition-duration") style->transitions[i].duration = seconds;
535
- else style->transitions[i].delay = seconds;
536
- }
537
- return;
538
- }
539
- if (property == "transition-timing-function") {
540
- std::vector<std::string> parts = splitCommas(value);
541
- style->transitions.resize(parts.size());
542
- for (size_t i = 0; i < parts.size(); i++) {
543
- TimingFunction timing = TimingFunction::Ease;
544
- if (parseTimingFunction(parts[i], &timing)) style->transitions[i].timing = timing;
545
- }
546
- return;
547
- }
572
+ if (xt_style_apply_transition(style, property, value)) return;
573
+
548
574
  }
549
575
 
550
576
  } // namespace xtgui
@@ -0,0 +1,35 @@
1
+ #ifndef XT_GUI_STYLE_VALUES_INTERNAL_H
2
+ #define XT_GUI_STYLE_VALUES_INTERNAL_H
3
+
4
+ #include <string>
5
+
6
+ struct XtStyle;
7
+
8
+ namespace xtgui {
9
+
10
+ /** Apply `background-image` (a comma-separated layer list). */
11
+ void xt_style_apply_background_image(XtStyle *style, const std::string &value);
12
+
13
+ /** Apply the `background` shorthand (layers plus an optional final colour). */
14
+ void xt_style_apply_background(XtStyle *style, const std::string &value);
15
+
16
+ /** Apply `filter` / `backdrop-filter` / `text-shadow` / `content`; returns false
17
+ * for unrelated properties. */
18
+ bool xt_style_apply_effect(XtStyle *style, const std::string &property,
19
+ const std::string &value);
20
+
21
+ /** Apply `clip-path`; returns false for an unrelated property. */
22
+ bool xt_style_apply_clip_path(XtStyle *style, const std::string &property,
23
+ const std::string &value);
24
+
25
+ /** Apply a grid/alignment declaration; returns false for unrelated properties. */
26
+ bool xt_style_apply_grid_property(XtStyle *style, const std::string &property,
27
+ const std::string &value);
28
+
29
+ /** Apply a transition declaration; returns false for unrelated properties. */
30
+ bool xt_style_apply_transition(XtStyle *style, const std::string &property,
31
+ const std::string &value);
32
+
33
+ } // namespace xtgui
34
+
35
+ #endif /* XT_GUI_STYLE_VALUES_INTERNAL_H */