xbintsc 0.5.31 → 0.5.36

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 (286) hide show
  1. package/README.md +25 -16
  2. package/README.zh-CN.md +10 -8
  3. package/dist/scripts/check-version.d.ts +27 -0
  4. package/dist/scripts/check-version.js +71 -0
  5. package/dist/scripts/check-version.js.map +1 -0
  6. package/dist/scripts/package-platform.d.ts +58 -0
  7. package/dist/scripts/package-platform.js +142 -0
  8. package/dist/scripts/package-platform.js.map +1 -0
  9. package/dist/scripts/verify-platform-package.d.ts +34 -0
  10. package/dist/scripts/verify-platform-package.js +161 -0
  11. package/dist/scripts/verify-platform-package.js.map +1 -0
  12. package/dist/src/binder/references.js +14 -1
  13. package/dist/src/binder/references.js.map +1 -1
  14. package/dist/src/cli/help.d.ts +1 -1
  15. package/dist/src/cli/main.js +3 -1
  16. package/dist/src/cli/main.js.map +1 -1
  17. package/dist/src/codegen/generator/module.d.ts +1 -0
  18. package/dist/src/codegen/generator/module.js +54 -0
  19. package/dist/src/codegen/generator/module.js.map +1 -1
  20. package/dist/src/codegen/generator/statements/variables.js +6 -4
  21. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  22. package/dist/src/driver/runtime-lib.d.ts +29 -4
  23. package/dist/src/driver/runtime-lib.js +68 -10
  24. package/dist/src/driver/runtime-lib.js.map +1 -1
  25. package/dist/src/driver/version.d.ts +1 -1
  26. package/dist/src/driver/version.js +1 -1
  27. package/dist/src/extensions/gui/css.d.ts +26 -0
  28. package/dist/src/extensions/gui/css.js +100 -0
  29. package/dist/src/extensions/gui/css.js.map +1 -0
  30. package/dist/src/extensions/gui/html.js +9 -2
  31. package/dist/src/extensions/gui/html.js.map +1 -1
  32. package/dist/src/extensions/gui/index.js +22 -7
  33. package/dist/src/extensions/gui/index.js.map +1 -1
  34. package/dist/src/extensions/gui/three.d.ts +16 -0
  35. package/dist/src/extensions/gui/three.js +22 -0
  36. package/dist/src/extensions/gui/three.js.map +1 -0
  37. package/dist/src/extensions/media/index.d.ts +6 -5
  38. package/dist/src/extensions/media/index.js +15 -16
  39. package/dist/src/extensions/media/index.js.map +1 -1
  40. package/dist/src/parser/context.d.ts +41 -0
  41. package/dist/src/parser/context.js +89 -4
  42. package/dist/src/parser/context.js.map +1 -1
  43. package/dist/src/parser/literals.js +6 -12
  44. package/dist/src/parser/literals.js.map +1 -1
  45. package/dist/tests/driver/platform-package.test.d.ts +1 -0
  46. package/dist/tests/driver/platform-package.test.js +49 -0
  47. package/dist/tests/driver/platform-package.test.js.map +1 -0
  48. package/dist/tests/driver/runtime-lib.test.js +51 -4
  49. package/dist/tests/driver/runtime-lib.test.js.map +1 -1
  50. package/dist/tests/e2e/compile-builtins.test.js +24 -0
  51. package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
  52. package/dist/tests/e2e/compile-objects-classes.test.js +23 -0
  53. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  54. package/dist/tests/e2e/gui-audio.test.d.ts +14 -0
  55. package/dist/tests/e2e/gui-audio.test.js +287 -0
  56. package/dist/tests/e2e/gui-audio.test.js.map +1 -0
  57. package/dist/tests/e2e/gui-browser.test.js +1 -1
  58. package/dist/tests/e2e/gui-browser.test.js.map +1 -1
  59. package/dist/tests/e2e/gui-effects.test.d.ts +6 -0
  60. package/dist/tests/e2e/gui-effects.test.js +262 -0
  61. package/dist/tests/e2e/gui-effects.test.js.map +1 -0
  62. package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
  63. package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
  64. package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
  65. package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
  66. package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
  67. package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
  68. package/dist/tests/e2e/gui-helpers.d.ts +7 -0
  69. package/dist/tests/e2e/gui-helpers.js +1 -0
  70. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  71. package/dist/tests/e2e/gui-layout.test.js +48 -0
  72. package/dist/tests/e2e/gui-layout.test.js.map +1 -1
  73. package/dist/tests/e2e/gui-media.test.js +83 -4
  74. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  75. package/dist/tests/e2e/gui-style.test.js +55 -0
  76. package/dist/tests/e2e/gui-style.test.js.map +1 -1
  77. package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
  78. package/dist/tests/e2e/gui-webgl.test.js +437 -0
  79. package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
  80. package/dist/tests/e2e/gui-webgl2-3d.test.d.ts +4 -0
  81. package/dist/tests/e2e/gui-webgl2-3d.test.js +264 -0
  82. package/dist/tests/e2e/gui-webgl2-3d.test.js.map +1 -0
  83. package/dist/tests/e2e/gui-webgl2-blit.test.d.ts +10 -0
  84. package/dist/tests/e2e/gui-webgl2-blit.test.js +262 -0
  85. package/dist/tests/e2e/gui-webgl2-blit.test.js.map +1 -0
  86. package/dist/tests/e2e/gui-webgl2-formats.test.d.ts +6 -0
  87. package/dist/tests/e2e/gui-webgl2-formats.test.js +395 -0
  88. package/dist/tests/e2e/gui-webgl2-formats.test.js.map +1 -0
  89. package/dist/tests/e2e/gui-webgl2-mrt.test.d.ts +4 -0
  90. package/dist/tests/e2e/gui-webgl2-mrt.test.js +105 -0
  91. package/dist/tests/e2e/gui-webgl2-mrt.test.js.map +1 -0
  92. package/dist/tests/e2e/gui-webgl2-ubo.test.d.ts +8 -0
  93. package/dist/tests/e2e/gui-webgl2-ubo.test.js +112 -0
  94. package/dist/tests/e2e/gui-webgl2-ubo.test.js.map +1 -0
  95. package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
  96. package/dist/tests/e2e/gui-webgl2.test.js +282 -0
  97. package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
  98. package/dist/tests/extensions/gui-index.test.js +1 -0
  99. package/dist/tests/extensions/gui-index.test.js.map +1 -1
  100. package/dist/tests/extensions/gui.test.js +41 -0
  101. package/dist/tests/extensions/gui.test.js.map +1 -1
  102. package/dist/tests/extensions/media.test.js +8 -3
  103. package/dist/tests/extensions/media.test.js.map +1 -1
  104. package/dist/tests/parser/expressions.test.js +30 -0
  105. package/dist/tests/parser/expressions.test.js.map +1 -1
  106. package/dist/tests/platform-tarball.test.d.ts +1 -0
  107. package/dist/tests/platform-tarball.test.js +111 -0
  108. package/dist/tests/platform-tarball.test.js.map +1 -0
  109. package/dist/tests/version.test.js +6 -0
  110. package/dist/tests/version.test.js.map +1 -1
  111. package/doc/ai/contributing.md +11 -0
  112. package/doc/ai/extensions.md +35 -12
  113. package/doc/ai/troubleshooting.md +17 -11
  114. package/doc/ai/zh-CN/contributing.md +9 -0
  115. package/doc/ai/zh-CN/extensions.md +30 -10
  116. package/doc/ai/zh-CN/troubleshooting.md +14 -8
  117. package/doc/gui/api.md +63 -14
  118. package/doc/gui/build.md +79 -16
  119. package/doc/gui/canvas.md +11 -3
  120. package/doc/gui/dom.md +35 -17
  121. package/doc/gui/known-issues.md +57 -24
  122. package/doc/gui/layout.md +18 -0
  123. package/doc/gui/media.md +21 -13
  124. package/doc/gui/rendering.md +50 -3
  125. package/doc/gui/webgl.md +315 -0
  126. package/doc/gui.md +113 -18
  127. package/doc/npm-package.md +59 -29
  128. package/doc/requirements.md +24 -11
  129. package/doc/zh-CN/gui/api.md +53 -11
  130. package/doc/zh-CN/gui/build.md +70 -16
  131. package/doc/zh-CN/gui/canvas.md +9 -2
  132. package/doc/zh-CN/gui/dom.md +22 -7
  133. package/doc/zh-CN/gui/known-issues.md +45 -19
  134. package/doc/zh-CN/gui/layout.md +14 -0
  135. package/doc/zh-CN/gui/media.md +18 -11
  136. package/doc/zh-CN/gui/rendering.md +41 -4
  137. package/doc/zh-CN/gui/webgl.md +121 -0
  138. package/doc/zh-CN/gui.md +91 -15
  139. package/doc/zh-CN/npm-package.md +48 -24
  140. package/doc/zh-CN/requirements.md +16 -7
  141. package/llms.txt +2 -0
  142. package/package.json +17 -1
  143. package/runtime/ext_gui/audio.cpp +365 -153
  144. package/runtime/ext_gui/audio_buffer.cpp +166 -0
  145. package/runtime/ext_gui/audio_buffer.h +37 -0
  146. package/runtime/ext_gui/audio_decode.cpp +219 -0
  147. package/runtime/ext_gui/audio_decode.h +39 -0
  148. package/runtime/ext_gui/audio_device.cpp +87 -0
  149. package/runtime/ext_gui/audio_effects.cpp +163 -0
  150. package/runtime/ext_gui/audio_effects.h +25 -0
  151. package/runtime/ext_gui/audio_internal.h +30 -0
  152. package/runtime/ext_gui/audio_mixer.cpp +494 -0
  153. package/runtime/ext_gui/audio_mixer.h +238 -0
  154. package/runtime/ext_gui/audio_param.cpp +104 -0
  155. package/runtime/ext_gui/audio_param_object.cpp +155 -0
  156. package/runtime/ext_gui/browser.cpp +50 -14
  157. package/runtime/ext_gui/canvas.cpp +3 -18
  158. package/runtime/ext_gui/canvas_internal.h +10 -0
  159. package/runtime/ext_gui/canvas_raster.cpp +60 -0
  160. package/runtime/ext_gui/clip_values.cpp +246 -0
  161. package/runtime/ext_gui/css.cpp +94 -0
  162. package/runtime/ext_gui/css.h +22 -1
  163. package/runtime/ext_gui/css_match.cpp +3 -0
  164. package/runtime/ext_gui/css_selector.cpp +30 -3
  165. package/runtime/ext_gui/css_sheet.cpp +89 -45
  166. package/runtime/ext_gui/document.cpp +4 -1
  167. package/runtime/ext_gui/document.h +2 -0
  168. package/runtime/ext_gui/dom.h +16 -0
  169. package/runtime/ext_gui/dom_api.cpp +1 -0
  170. package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
  171. package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
  172. package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
  173. package/runtime/ext_gui/dom_api_internal.h +275 -0
  174. package/runtime/ext_gui/dom_api_webgl.cpp +383 -0
  175. package/runtime/ext_gui/dom_api_webgl2.cpp +549 -0
  176. package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
  177. package/runtime/ext_gui/dom_api_webgl_buffer.cpp +216 -0
  178. package/runtime/ext_gui/dom_api_webgl_compressed.cpp +167 -0
  179. package/runtime/ext_gui/dom_api_webgl_framebuffer.cpp +160 -0
  180. package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
  181. package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
  182. package/runtime/ext_gui/dom_api_webgl_source.cpp +161 -0
  183. package/runtime/ext_gui/dom_api_webgl_state.cpp +590 -0
  184. package/runtime/ext_gui/dom_api_webgl_texture.cpp +485 -0
  185. package/runtime/ext_gui/dom_api_webgl_ubo.cpp +81 -0
  186. package/runtime/ext_gui/effect_values.cpp +312 -0
  187. package/runtime/ext_gui/gradient_values.cpp +476 -0
  188. package/runtime/ext_gui/grid_values.cpp +230 -0
  189. package/runtime/ext_gui/gui.cpp +44 -9
  190. package/runtime/ext_gui/gui_canvas.cpp +50 -2
  191. package/runtime/ext_gui/gui_engine.h +36 -4
  192. package/runtime/ext_gui/gui_events.cpp +4 -1
  193. package/runtime/ext_gui/gui_media.cpp +1 -1
  194. package/runtime/ext_gui/gui_webgl.cpp +83 -0
  195. package/runtime/ext_gui/image_bitmap.cpp +28 -0
  196. package/runtime/ext_gui/image_bitmap.h +26 -0
  197. package/runtime/ext_gui/image_bitmap_browser.cpp +136 -0
  198. package/runtime/ext_gui/layout.cpp +21 -0
  199. package/runtime/ext_gui/layout_flow.cpp +81 -4
  200. package/runtime/ext_gui/layout_flow_internal.h +31 -0
  201. package/runtime/ext_gui/layout_grid.cpp +374 -0
  202. package/runtime/ext_gui/media.cpp +32 -0
  203. package/runtime/ext_gui/media.h +14 -1
  204. package/runtime/ext_gui/media_api.h +25 -2
  205. package/runtime/ext_gui/media_query.cpp +211 -0
  206. package/runtime/ext_gui/paint.cpp +111 -77
  207. package/runtime/ext_gui/paint.h +33 -3
  208. package/runtime/ext_gui/paint_background.cpp +229 -0
  209. package/runtime/ext_gui/paint_clip.cpp +268 -0
  210. package/runtime/ext_gui/paint_effects.cpp +324 -0
  211. package/runtime/ext_gui/paint_internal.h +85 -0
  212. package/runtime/ext_gui/renderer.cpp +8 -31
  213. package/runtime/ext_gui/renderer_clip.cpp +196 -0
  214. package/runtime/ext_gui/renderer_image.cpp +13 -8
  215. package/runtime/ext_gui/renderer_internal.h +15 -8
  216. package/runtime/ext_gui/renderer_text.cpp +6 -31
  217. package/runtime/ext_gui/style.cpp +343 -20
  218. package/runtime/ext_gui/style.h +144 -3
  219. package/runtime/ext_gui/style_print.cpp +134 -1
  220. package/runtime/ext_gui/style_values.cpp +152 -126
  221. package/runtime/ext_gui/style_values_internal.h +35 -0
  222. package/runtime/ext_gui/webgl.h +600 -0
  223. package/runtime/ext_gui/webgl2_constants.h +274 -0
  224. package/runtime/ext_gui/webgl_blit.cpp +95 -0
  225. package/runtime/ext_gui/webgl_buffer.cpp +480 -0
  226. package/runtime/ext_gui/webgl_buffer_objects.cpp +270 -0
  227. package/runtime/ext_gui/webgl_clear.cpp +142 -0
  228. package/runtime/ext_gui/webgl_compressed.cpp +180 -0
  229. package/runtime/ext_gui/webgl_constants.h +317 -0
  230. package/runtime/ext_gui/webgl_context.cpp +551 -0
  231. package/runtime/ext_gui/webgl_draw.cpp +560 -0
  232. package/runtime/ext_gui/webgl_draw_buffers.cpp +75 -0
  233. package/runtime/ext_gui/webgl_glsl.h +165 -0
  234. package/runtime/ext_gui/webgl_glsl_compile.cpp +437 -0
  235. package/runtime/ext_gui/webgl_glsl_rewrite.cpp +367 -0
  236. package/runtime/ext_gui/webgl_glsl_scan.cpp +590 -0
  237. package/runtime/ext_gui/webgl_glsl_scan_block.cpp +126 -0
  238. package/runtime/ext_gui/webgl_glsl_tokens.h +28 -0
  239. package/runtime/ext_gui/webgl_msl.cpp +62 -0
  240. package/runtime/ext_gui/webgl_msl.h +33 -0
  241. package/runtime/ext_gui/webgl_pipeline.cpp +326 -0
  242. package/runtime/ext_gui/webgl_program_blocks.cpp +58 -0
  243. package/runtime/ext_gui/webgl_program_internal.h +24 -0
  244. package/runtime/ext_gui/webgl_shader.cpp +594 -0
  245. package/runtime/ext_gui/webgl_state.cpp +228 -0
  246. package/runtime/ext_gui/webgl_texture.cpp +420 -0
  247. package/runtime/ext_gui/webgl_texture_3d.cpp +215 -0
  248. package/runtime/ext_gui/webgl_uniform.cpp +167 -0
  249. package/runtime/ext_gui/webgl_uniform_block.h +31 -0
  250. package/runtime/ext_gui/webgl_webgl2.cpp +277 -0
  251. package/runtime/ext_media/decode_audio.cpp +308 -0
  252. package/runtime/ext_media/media.cpp +1 -1
  253. package/runtime/ext_media/media_bridge.c +11 -3
  254. package/runtime/rt.h +17 -0
  255. package/runtime/rt_internal.h +1 -0
  256. package/runtime/xt_array_buffer.c +30 -0
  257. package/runtime/xt_containers/access.inc +8 -0
  258. package/runtime/xt_regex/api.inc +2 -0
  259. package/runtime/xt_regex/matcher.inc +16 -3
  260. package/runtime/xt_regex/parser.inc +8 -2
  261. package/runtime/xt_regex/types.inc +3 -0
  262. package/runtime/xt_stdlib2/regexp-match.inc +60 -21
  263. package/runtime/xt_stdlib2/regexp.inc +1 -0
  264. package/runtime/xt_typed_array/elements.inc +13 -0
  265. package/runtime/xt_typed_array.c +1 -1
  266. package/scripts/build-gui.ts +90 -3
  267. package/scripts/build-media.ts +335 -62
  268. package/scripts/build-runtime.ts +21 -16
  269. package/scripts/check-version.ts +39 -9
  270. package/scripts/package-platform.ts +183 -0
  271. package/scripts/set-platform-version.ts +62 -0
  272. package/scripts/setup-vs-toolchain.ps1 +152 -0
  273. package/scripts/verify-platform-package.ts +182 -0
  274. package/src/binder/references.ts +13 -1
  275. package/src/cli/main.ts +5 -1
  276. package/src/codegen/generator/module.ts +50 -0
  277. package/src/codegen/generator/statements/variables.ts +6 -3
  278. package/src/driver/runtime-lib.ts +73 -9
  279. package/src/driver/version.ts +1 -1
  280. package/src/extensions/gui/css.ts +113 -0
  281. package/src/extensions/gui/html.ts +9 -2
  282. package/src/extensions/gui/index.ts +22 -7
  283. package/src/extensions/gui/three.ts +25 -0
  284. package/src/extensions/media/index.ts +16 -18
  285. package/src/parser/context.ts +99 -4
  286. package/src/parser/literals.ts +6 -12
@@ -10,6 +10,7 @@
10
10
  #ifndef XT_GUI_STYLE_H
11
11
  #define XT_GUI_STYLE_H
12
12
 
13
+ #include <memory>
13
14
  #include <string>
14
15
  #include <unordered_map>
15
16
  #include <vector>
@@ -20,7 +21,8 @@
20
21
 
21
22
  namespace xtgui {
22
23
 
23
- enum class Display { None, Block, Inline, InlineBlock, Flex, ListItem };
24
+ enum class Display { None, Block, Inline, InlineBlock, Flex, Grid, ListItem };
25
+ enum class BoxSizing { ContentBox, BorderBox };
24
26
  enum class Position { Static, Relative, Absolute, Fixed };
25
27
  enum class FlexDirection { Row, RowReverse, Column, ColumnReverse };
26
28
  enum class FlexWrap { NoWrap, Wrap, WrapReverse };
@@ -44,6 +46,93 @@ struct TransitionSpec {
44
46
  TimingFunction timing = TimingFunction::Ease;
45
47
  };
46
48
 
49
+ /** One track of a `grid-template-columns` / `grid-template-rows` list.
50
+ * `min`/`max` keep their CSS unit (`auto` for an intrinsic bound); `fr` is the
51
+ * flex fraction of a `minmax(..., <n>fr)` or `<n>fr` track. */
52
+ struct GridTrack {
53
+ Length min{0.0f, Unit::Auto};
54
+ Length max{0.0f, Unit::Auto};
55
+ float fr = 0.0f;
56
+ };
57
+
58
+ struct BackgroundGradientStop {
59
+ float offset = 0.0f;
60
+ Color color;
61
+ };
62
+
63
+ enum class BackgroundKind { Linear, Radial };
64
+
65
+ /** How a radial layer's radii are chosen when it has no explicit lengths. */
66
+ enum class RadialSize { ClosestSide, FarthestSide, ClosestCorner, FarthestCorner, Explicit };
67
+
68
+ /** One `background-image` layer. Layers are painted bottom-up: the first one in
69
+ * the declaration is the topmost, as in CSS. A gradient is approximated with
70
+ * solid bands through the rectangle pipeline (there is no gradient shader). */
71
+ struct BackgroundLayer {
72
+ BackgroundKind kind = BackgroundKind::Linear;
73
+ /* linear */
74
+ float angle = 180.0f; // CSS degrees: 0 = to top, 90 = to right, 180 = to bottom
75
+ /* radial */
76
+ bool circle = false;
77
+ bool has_shape = false;
78
+ RadialSize size = RadialSize::FarthestCorner;
79
+ Length center_x{50.0f, Unit::Percent};
80
+ Length center_y{50.0f, Unit::Percent};
81
+ Length radius_x{0.0f, Unit::Auto}; // Explicit radii only
82
+ Length radius_y{0.0f, Unit::Auto};
83
+ std::vector<BackgroundGradientStop> stops;
84
+ };
85
+
86
+ /** `clip-path` shapes. Lengths stay unresolved until paint knows the box. */
87
+ struct ClipPathSpec {
88
+ enum class Type { None, Inset, Circle, Ellipse, Polygon } type = Type::None;
89
+ Length inset_top;
90
+ Length inset_right;
91
+ Length inset_bottom;
92
+ Length inset_left;
93
+ Length inset_radius{0.0f, Unit::Px};
94
+ Length center_x{50.0f, Unit::Percent};
95
+ Length center_y{50.0f, Unit::Percent};
96
+ Length radius_x{50.0f, Unit::Percent};
97
+ Length radius_y{50.0f, Unit::Percent};
98
+ bool radius_explicit = false;
99
+ /** Flat `x0, y0, x1, y1, …` list, resolved against the border box. */
100
+ std::vector<Length> polygon;
101
+ };
102
+
103
+ enum class FilterKind {
104
+ Blur,
105
+ Brightness,
106
+ Contrast,
107
+ Grayscale,
108
+ Sepia,
109
+ Invert,
110
+ Saturate,
111
+ HueRotate,
112
+ Opacity,
113
+ DropShadow
114
+ };
115
+
116
+ /** One `filter` / `backdrop-filter` function. */
117
+ struct FilterOp {
118
+ FilterKind kind = FilterKind::Brightness;
119
+ float amount = 1.0f;
120
+ Length dx;
121
+ Length dy;
122
+ Length blur;
123
+ Color color;
124
+ bool has_color = false;
125
+ };
126
+
127
+ /** One `text-shadow` entry. */
128
+ struct TextShadow {
129
+ Length dx;
130
+ Length dy;
131
+ Length blur;
132
+ Color color; // `has_color == false` means currentColor
133
+ bool has_color = false;
134
+ };
135
+
47
136
  struct Edges {
48
137
  Length top;
49
138
  Length right;
@@ -55,6 +144,10 @@ struct Edges {
55
144
 
56
145
  struct XtStyle {
57
146
  Display display = Display::Inline;
147
+ BoxSizing box_sizing = BoxSizing::ContentBox;
148
+ /* CSS custom properties (`--name`) are inherited and substituted into the
149
+ * values of the other declarations during the cascade. */
150
+ std::unordered_map<std::string, std::string> variables;
58
151
  Position position = Position::Static;
59
152
  Edges margin;
60
153
  Edges padding;
@@ -75,9 +168,25 @@ struct XtStyle {
75
168
  Length bottom;
76
169
  Length left;
77
170
 
171
+ bool visible = true; // inherited `visibility`
172
+ bool pointer_events = true; // inherited `pointer-events`
78
173
  Color color; // inherited; defaults to black
79
174
  Color background; // transparent by default
80
175
  bool has_background = false;
176
+ /** `background-image` layers, in declaration order (first = topmost). */
177
+ std::vector<BackgroundLayer> background_layers;
178
+ /** `clip-path`; `Type::None` leaves the box unclipped. */
179
+ ClipPathSpec clip_path;
180
+ /** `filter` / `backdrop-filter` function lists (not inherited). */
181
+ std::vector<FilterOp> filters;
182
+ std::vector<FilterOp> backdrop_filters;
183
+ /** `text-shadow` entries (inherited, as in CSS). */
184
+ std::vector<TextShadow> text_shadow;
185
+ /** Generated `content` of a `::before`/`::after` box. The cascade resolves
186
+ * `attr()` and string escapes before layout; `has_content` distinguishes
187
+ * `content: ""` from no generated box. */
188
+ std::string content;
189
+ bool has_content = false;
81
190
 
82
191
  float font_size = 16.0f; // inherited
83
192
  int font_weight = 400; // inherited
@@ -93,6 +202,19 @@ struct XtStyle {
93
202
  JustifyContent justify_content = JustifyContent::FlexStart;
94
203
  AlignItems align_items = AlignItems::Stretch;
95
204
  AlignContent align_content = AlignContent::Stretch;
205
+ /* Grid (a focused subset: explicit/implicit rows and columns, gap, item
206
+ * alignment and simple line placement). */
207
+ std::vector<GridTrack> grid_columns;
208
+ std::vector<GridTrack> grid_rows;
209
+ AlignItems justify_items = AlignItems::Stretch;
210
+ bool has_justify_self = false;
211
+ AlignItems justify_self = AlignItems::Stretch;
212
+ bool has_align_self = false;
213
+ AlignItems align_self = AlignItems::Stretch;
214
+ int grid_column_start = 0;
215
+ int grid_column_end = 0;
216
+ int grid_row_start = 0;
217
+ int grid_row_end = 0;
96
218
  Length gap;
97
219
  Length row_gap;
98
220
  Length column_gap;
@@ -121,11 +243,30 @@ struct XtStyle {
121
243
  /** Initial (non-inherited) style; inherited fields are overridden from the parent. */
122
244
  XtStyle xt_style_initial();
123
245
 
246
+ /** Owns the synthetic `::before`/`::after` nodes of one style computation. The
247
+ * arena is rebuilt on every restyle, so generated content always reflects the
248
+ * latest DOM and CSS. */
249
+ class PseudoNodeSet {
250
+ public:
251
+ /** Release the previous generation (the caller must already have cleared the
252
+ * element → pseudo pointers it handed out). */
253
+ void clear();
254
+ Node *create(Node *origin, PseudoElement side);
255
+ size_t size() const { return nodes_.size(); }
256
+
257
+ private:
258
+ std::vector<std::unique_ptr<Node>> nodes_;
259
+ };
260
+
124
261
  /** Cascade UA + author + inline declarations into `out` for the document root.
125
- * `state` supplies `:hover`/`:focus` for dynamic selector matching. */
262
+ * `state` supplies `:hover`/`:focus` for dynamic selector matching. When
263
+ * `pseudos` is non-null, `::before`/`::after` styles are computed too and each
264
+ * element's transient `pseudo_before`/`pseudo_after` pointers are published for
265
+ * layout. */
126
266
  void xt_style_compute(const Node *root, const StyleSheet &sheet,
127
267
  std::unordered_map<const Node *, XtStyle> &out, float viewportWidth,
128
- float viewportHeight, const MatchState &state = MatchState());
268
+ float viewportHeight, const MatchState &state = MatchState(),
269
+ PseudoNodeSet *pseudos = nullptr);
129
270
 
130
271
  /** Format a computed property for diagnostics/tests (`computedStyle(sel, prop)`). */
131
272
  std::string xt_style_property_to_string(const XtStyle &style, const std::string &property);
@@ -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);