@gtkx/react 1.0.0-rc.1 → 1.0.0-rc.2

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 (381) hide show
  1. package/dist/adw/config.d.ts +2 -0
  2. package/dist/adw/config.d.ts.map +1 -0
  3. package/dist/adw/config.js +2 -0
  4. package/dist/adw/config.js.map +1 -0
  5. package/dist/{libraries/adw → adw}/dialog.d.ts +2 -2
  6. package/dist/adw/dialog.d.ts.map +1 -0
  7. package/dist/adw/dialog.js +25 -0
  8. package/dist/adw/dialog.js.map +1 -0
  9. package/dist/adw/element-behaviors.d.ts +2 -0
  10. package/dist/adw/element-behaviors.d.ts.map +1 -0
  11. package/dist/adw/element-behaviors.js +299 -0
  12. package/dist/adw/element-behaviors.js.map +1 -0
  13. package/dist/adw/element-config.d.ts +9 -0
  14. package/dist/adw/element-config.d.ts.map +1 -0
  15. package/dist/adw/element-config.js +137 -0
  16. package/dist/adw/element-config.js.map +1 -0
  17. package/dist/adw/index.d.ts +4 -0
  18. package/dist/adw/index.d.ts.map +1 -0
  19. package/dist/adw/index.js +3 -0
  20. package/dist/adw/index.js.map +1 -0
  21. package/dist/adw/prop-types.d.ts +29 -0
  22. package/dist/adw/prop-types.d.ts.map +1 -0
  23. package/dist/adw/prop-types.js +2 -0
  24. package/dist/adw/prop-types.js.map +1 -0
  25. package/dist/bootstrap.d.ts +2 -0
  26. package/dist/bootstrap.d.ts.map +1 -0
  27. package/dist/bootstrap.js +5 -0
  28. package/dist/bootstrap.js.map +1 -0
  29. package/dist/components/application.d.ts +2 -2
  30. package/dist/components/application.d.ts.map +1 -1
  31. package/dist/components/application.js +31 -18
  32. package/dist/components/application.js.map +1 -1
  33. package/dist/components/element.d.ts +6 -0
  34. package/dist/components/element.d.ts.map +1 -0
  35. package/dist/components/element.js +29 -0
  36. package/dist/components/element.js.map +1 -0
  37. package/dist/components/window.d.ts +2 -2
  38. package/dist/components/window.d.ts.map +1 -1
  39. package/dist/components/window.js +10 -11
  40. package/dist/components/window.js.map +1 -1
  41. package/dist/config.d.ts +4 -0
  42. package/dist/config.d.ts.map +1 -0
  43. package/dist/config.js +3 -0
  44. package/dist/config.js.map +1 -0
  45. package/dist/element-behaviors.d.ts +2 -0
  46. package/dist/element-behaviors.d.ts.map +1 -0
  47. package/dist/element-behaviors.js +348 -0
  48. package/dist/element-behaviors.js.map +1 -0
  49. package/dist/element-config.d.ts +10 -0
  50. package/dist/element-config.d.ts.map +1 -0
  51. package/dist/element-config.js +146 -0
  52. package/dist/element-config.js.map +1 -0
  53. package/dist/hooks/use-application.d.ts +4 -3
  54. package/dist/hooks/use-application.d.ts.map +1 -1
  55. package/dist/hooks/use-application.js +5 -4
  56. package/dist/hooks/use-application.js.map +1 -1
  57. package/dist/hooks/use-bind-setting.d.ts +21 -4
  58. package/dist/hooks/use-bind-setting.d.ts.map +1 -1
  59. package/dist/hooks/use-bind-setting.js +27 -16
  60. package/dist/hooks/use-bind-setting.js.map +1 -1
  61. package/dist/hooks/use-merged-refs.d.ts +8 -0
  62. package/dist/hooks/use-merged-refs.d.ts.map +1 -0
  63. package/dist/hooks/use-merged-refs.js +48 -0
  64. package/dist/hooks/use-merged-refs.js.map +1 -0
  65. package/dist/hooks/use-object-value.d.ts +3 -2
  66. package/dist/hooks/use-object-value.d.ts.map +1 -1
  67. package/dist/hooks/use-object-value.js +18 -21
  68. package/dist/hooks/use-object-value.js.map +1 -1
  69. package/dist/hooks/use-parent-window.d.ts +3 -2
  70. package/dist/hooks/use-parent-window.d.ts.map +1 -1
  71. package/dist/hooks/use-parent-window.js +3 -2
  72. package/dist/hooks/use-parent-window.js.map +1 -1
  73. package/dist/hooks/use-property.d.ts +5 -5
  74. package/dist/hooks/use-property.d.ts.map +1 -1
  75. package/dist/hooks/use-property.js +4 -3
  76. package/dist/hooks/use-property.js.map +1 -1
  77. package/dist/hooks/use-setting.d.ts +5 -16
  78. package/dist/hooks/use-setting.d.ts.map +1 -1
  79. package/dist/hooks/use-setting.js +16 -11
  80. package/dist/hooks/use-setting.js.map +1 -1
  81. package/dist/hooks/use-signal.d.ts +10 -7
  82. package/dist/hooks/use-signal.d.ts.map +1 -1
  83. package/dist/hooks/use-signal.js +29 -18
  84. package/dist/hooks/use-signal.js.map +1 -1
  85. package/dist/index.d.ts +7 -8
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2 -3
  88. package/dist/index.js.map +1 -1
  89. package/dist/internal.d.ts +6 -7
  90. package/dist/internal.d.ts.map +1 -1
  91. package/dist/internal.js +5 -7
  92. package/dist/internal.js.map +1 -1
  93. package/dist/prop-types.d.ts +110 -0
  94. package/dist/prop-types.d.ts.map +1 -0
  95. package/dist/prop-types.js +2 -0
  96. package/dist/prop-types.js.map +1 -0
  97. package/dist/reconciler/apply-props.d.ts +10 -7
  98. package/dist/reconciler/apply-props.d.ts.map +1 -1
  99. package/dist/reconciler/apply-props.js +182 -84
  100. package/dist/reconciler/apply-props.js.map +1 -1
  101. package/dist/reconciler/behaviors.d.ts +59 -0
  102. package/dist/reconciler/behaviors.d.ts.map +1 -0
  103. package/dist/reconciler/behaviors.js +172 -0
  104. package/dist/reconciler/behaviors.js.map +1 -0
  105. package/dist/reconciler/child-routing.d.ts +5 -0
  106. package/dist/reconciler/child-routing.d.ts.map +1 -0
  107. package/dist/reconciler/child-routing.js +156 -0
  108. package/dist/reconciler/child-routing.js.map +1 -0
  109. package/dist/reconciler/host-config.d.ts +8 -12
  110. package/dist/reconciler/host-config.d.ts.map +1 -1
  111. package/dist/reconciler/host-config.js +175 -270
  112. package/dist/reconciler/host-config.js.map +1 -1
  113. package/dist/reconciler/instance.d.ts +4 -5
  114. package/dist/reconciler/instance.d.ts.map +1 -1
  115. package/dist/reconciler/instance.js +44 -22
  116. package/dist/reconciler/instance.js.map +1 -1
  117. package/dist/reconciler/metadata.d.ts +17 -0
  118. package/dist/reconciler/metadata.d.ts.map +1 -0
  119. package/dist/reconciler/metadata.js +82 -0
  120. package/dist/reconciler/metadata.js.map +1 -0
  121. package/dist/reconciler/node.d.ts +76 -0
  122. package/dist/reconciler/node.d.ts.map +1 -0
  123. package/dist/reconciler/node.js +53 -0
  124. package/dist/reconciler/node.js.map +1 -0
  125. package/dist/reconciler/placement.d.ts +5 -0
  126. package/dist/reconciler/placement.d.ts.map +1 -0
  127. package/dist/reconciler/placement.js +175 -0
  128. package/dist/reconciler/placement.js.map +1 -0
  129. package/dist/reconciler/registry.d.ts +92 -0
  130. package/dist/reconciler/registry.d.ts.map +1 -0
  131. package/dist/reconciler/registry.js +64 -0
  132. package/dist/reconciler/registry.js.map +1 -0
  133. package/dist/reconciler/root-element.d.ts +9 -12
  134. package/dist/reconciler/root-element.d.ts.map +1 -1
  135. package/dist/reconciler/root-element.js +6 -6
  136. package/dist/reconciler/root-element.js.map +1 -1
  137. package/dist/reconciler/root.d.ts +56 -0
  138. package/dist/reconciler/root.d.ts.map +1 -0
  139. package/dist/reconciler/root.js +109 -0
  140. package/dist/reconciler/root.js.map +1 -0
  141. package/dist/reconciler/signals.d.ts +10 -0
  142. package/dist/reconciler/signals.d.ts.map +1 -0
  143. package/dist/reconciler/signals.js +70 -0
  144. package/dist/reconciler/signals.js.map +1 -0
  145. package/dist/reconciler/text.d.ts +19 -0
  146. package/dist/reconciler/text.d.ts.map +1 -0
  147. package/dist/reconciler/text.js +276 -0
  148. package/dist/reconciler/text.js.map +1 -0
  149. package/dist/utils/accessible-metadata.d.ts +11 -4
  150. package/dist/utils/accessible-metadata.d.ts.map +1 -1
  151. package/dist/utils/accessible-metadata.js +20 -17
  152. package/dist/utils/accessible-metadata.js.map +1 -1
  153. package/dist/{reconciler/accessible.d.ts → utils/accessible-props.d.ts} +7 -6
  154. package/dist/utils/accessible-props.d.ts.map +1 -0
  155. package/dist/utils/accessible-props.js +181 -0
  156. package/dist/utils/accessible-props.js.map +1 -0
  157. package/dist/utils/ref-prop.d.ts +15 -0
  158. package/dist/utils/ref-prop.d.ts.map +1 -0
  159. package/dist/utils/ref-prop.js +18 -0
  160. package/dist/utils/ref-prop.js.map +1 -0
  161. package/dist/utils/settings.d.ts +17 -0
  162. package/dist/utils/settings.d.ts.map +1 -0
  163. package/dist/utils/settings.js +37 -0
  164. package/dist/utils/settings.js.map +1 -0
  165. package/dist/utils/variant.d.ts +57 -0
  166. package/dist/utils/variant.d.ts.map +1 -0
  167. package/dist/utils/variant.js +197 -0
  168. package/dist/utils/variant.js.map +1 -0
  169. package/env.d.ts +9 -0
  170. package/package.json +36 -11
  171. package/src/adw/config.ts +1 -0
  172. package/src/adw/dialog.tsx +35 -0
  173. package/src/adw/element-behaviors.ts +379 -0
  174. package/src/adw/element-config.ts +140 -0
  175. package/src/adw/index.ts +4 -0
  176. package/src/adw/prop-types.ts +42 -0
  177. package/src/bootstrap.ts +5 -0
  178. package/src/components/application.tsx +42 -23
  179. package/src/components/element.tsx +47 -0
  180. package/src/components/window.tsx +12 -13
  181. package/src/config.ts +3 -0
  182. package/src/element-behaviors.ts +424 -0
  183. package/src/element-config.ts +148 -0
  184. package/src/env.d.ts +1 -0
  185. package/src/hooks/use-application.ts +6 -4
  186. package/src/hooks/use-bind-setting.ts +47 -31
  187. package/src/hooks/use-merged-refs.ts +64 -0
  188. package/src/hooks/use-object-value.ts +27 -23
  189. package/src/hooks/use-parent-window.ts +4 -2
  190. package/src/hooks/use-property.ts +11 -10
  191. package/src/hooks/use-setting.ts +20 -33
  192. package/src/hooks/use-signal.ts +37 -48
  193. package/src/index.ts +7 -8
  194. package/src/internal.ts +7 -18
  195. package/src/prop-types.ts +142 -0
  196. package/src/reconciler/apply-props.ts +233 -85
  197. package/src/reconciler/behaviors.ts +324 -0
  198. package/src/reconciler/child-routing.ts +202 -0
  199. package/src/reconciler/host-config.ts +239 -366
  200. package/src/reconciler/instance.ts +76 -24
  201. package/src/reconciler/metadata.ts +119 -0
  202. package/src/reconciler/node.ts +161 -0
  203. package/src/reconciler/placement.ts +255 -0
  204. package/src/reconciler/registry.ts +161 -0
  205. package/src/reconciler/root-element.ts +9 -11
  206. package/src/reconciler/root.ts +175 -0
  207. package/src/reconciler/signals.ts +113 -0
  208. package/src/reconciler/text.ts +407 -0
  209. package/src/utils/accessible-metadata.ts +23 -18
  210. package/src/utils/accessible-props.ts +279 -0
  211. package/src/utils/ref-prop.ts +30 -0
  212. package/src/utils/settings.ts +69 -0
  213. package/src/utils/variant.ts +368 -0
  214. package/dist/hooks/use-merge-refs.d.ts +0 -3
  215. package/dist/hooks/use-merge-refs.d.ts.map +0 -1
  216. package/dist/hooks/use-merge-refs.js +0 -48
  217. package/dist/hooks/use-merge-refs.js.map +0 -1
  218. package/dist/hooks/use-object-attachment.d.ts +0 -10
  219. package/dist/hooks/use-object-attachment.d.ts.map +0 -1
  220. package/dist/hooks/use-object-attachment.js +0 -24
  221. package/dist/hooks/use-object-attachment.js.map +0 -1
  222. package/dist/libraries/adw/dialog.d.ts.map +0 -1
  223. package/dist/libraries/adw/dialog.js +0 -25
  224. package/dist/libraries/adw/dialog.js.map +0 -1
  225. package/dist/libraries/adw/index.d.ts +0 -2
  226. package/dist/libraries/adw/index.d.ts.map +0 -1
  227. package/dist/libraries/adw/index.js +0 -2
  228. package/dist/libraries/adw/index.js.map +0 -1
  229. package/dist/reconciler/accessible.d.ts.map +0 -1
  230. package/dist/reconciler/accessible.js +0 -143
  231. package/dist/reconciler/accessible.js.map +0 -1
  232. package/dist/reconciler/commit-flush.d.ts +0 -3
  233. package/dist/reconciler/commit-flush.d.ts.map +0 -1
  234. package/dist/reconciler/commit-flush.js +0 -13
  235. package/dist/reconciler/commit-flush.js.map +0 -1
  236. package/dist/reconciler/container-attach.d.ts +0 -10
  237. package/dist/reconciler/container-attach.d.ts.map +0 -1
  238. package/dist/reconciler/container-attach.js +0 -216
  239. package/dist/reconciler/container-attach.js.map +0 -1
  240. package/dist/reconciler/content-rebuild.d.ts +0 -3
  241. package/dist/reconciler/content-rebuild.d.ts.map +0 -1
  242. package/dist/reconciler/content-rebuild.js +0 -15
  243. package/dist/reconciler/content-rebuild.js.map +0 -1
  244. package/dist/reconciler/dispatch.d.ts +0 -6
  245. package/dist/reconciler/dispatch.d.ts.map +0 -1
  246. package/dist/reconciler/dispatch.js +0 -61
  247. package/dist/reconciler/dispatch.js.map +0 -1
  248. package/dist/reconciler/element-prop-appliers.d.ts +0 -5
  249. package/dist/reconciler/element-prop-appliers.d.ts.map +0 -1
  250. package/dist/reconciler/element-prop-appliers.js +0 -104
  251. package/dist/reconciler/element-prop-appliers.js.map +0 -1
  252. package/dist/reconciler/element-props.d.ts +0 -25
  253. package/dist/reconciler/element-props.d.ts.map +0 -1
  254. package/dist/reconciler/element-props.js +0 -157
  255. package/dist/reconciler/element-props.js.map +0 -1
  256. package/dist/reconciler/label-text-rebuild.d.ts +0 -3
  257. package/dist/reconciler/label-text-rebuild.d.ts.map +0 -1
  258. package/dist/reconciler/label-text-rebuild.js +0 -22
  259. package/dist/reconciler/label-text-rebuild.js.map +0 -1
  260. package/dist/reconciler/portal.d.ts +0 -11
  261. package/dist/reconciler/portal.d.ts.map +0 -1
  262. package/dist/reconciler/portal.js +0 -20
  263. package/dist/reconciler/portal.js.map +0 -1
  264. package/dist/reconciler/reconciler-error-handler.d.ts +0 -7
  265. package/dist/reconciler/reconciler-error-handler.d.ts.map +0 -1
  266. package/dist/reconciler/reconciler-error-handler.js +0 -24
  267. package/dist/reconciler/reconciler-error-handler.js.map +0 -1
  268. package/dist/reconciler/reconciler-root.d.ts +0 -19
  269. package/dist/reconciler/reconciler-root.d.ts.map +0 -1
  270. package/dist/reconciler/reconciler-root.js +0 -24
  271. package/dist/reconciler/reconciler-root.js.map +0 -1
  272. package/dist/reconciler/reconciler.d.ts +0 -3
  273. package/dist/reconciler/reconciler.d.ts.map +0 -1
  274. package/dist/reconciler/reconciler.js +0 -12
  275. package/dist/reconciler/reconciler.js.map +0 -1
  276. package/dist/reconciler/render.d.ts +0 -23
  277. package/dist/reconciler/render.d.ts.map +0 -1
  278. package/dist/reconciler/render.js +0 -46
  279. package/dist/reconciler/render.js.map +0 -1
  280. package/dist/reconciler/signal-store.d.ts +0 -22
  281. package/dist/reconciler/signal-store.d.ts.map +0 -1
  282. package/dist/reconciler/signal-store.js +0 -84
  283. package/dist/reconciler/signal-store.js.map +0 -1
  284. package/dist/reconciler/state.d.ts +0 -36
  285. package/dist/reconciler/state.d.ts.map +0 -1
  286. package/dist/reconciler/state.js +0 -38
  287. package/dist/reconciler/state.js.map +0 -1
  288. package/dist/reconciler/text-buffer-controller.d.ts +0 -17
  289. package/dist/reconciler/text-buffer-controller.d.ts.map +0 -1
  290. package/dist/reconciler/text-buffer-controller.js +0 -102
  291. package/dist/reconciler/text-buffer-controller.js.map +0 -1
  292. package/dist/reconciler/text-buffer-rebuild.d.ts +0 -3
  293. package/dist/reconciler/text-buffer-rebuild.d.ts.map +0 -1
  294. package/dist/reconciler/text-buffer-rebuild.js +0 -7
  295. package/dist/reconciler/text-buffer-rebuild.js.map +0 -1
  296. package/dist/reconciler/text-node.d.ts +0 -7
  297. package/dist/reconciler/text-node.d.ts.map +0 -1
  298. package/dist/reconciler/text-node.js +0 -8
  299. package/dist/reconciler/text-node.js.map +0 -1
  300. package/dist/reconciler/types.d.ts +0 -5
  301. package/dist/reconciler/types.d.ts.map +0 -1
  302. package/dist/reconciler/types.js +0 -2
  303. package/dist/reconciler/types.js.map +0 -1
  304. package/dist/reconciler/visibility.d.ts +0 -6
  305. package/dist/reconciler/visibility.d.ts.map +0 -1
  306. package/dist/reconciler/visibility.js +0 -57
  307. package/dist/reconciler/visibility.js.map +0 -1
  308. package/dist/reconciler/wrapper-apply.d.ts +0 -6
  309. package/dist/reconciler/wrapper-apply.d.ts.map +0 -1
  310. package/dist/reconciler/wrapper-apply.js +0 -287
  311. package/dist/reconciler/wrapper-apply.js.map +0 -1
  312. package/dist/reconciler/wrapper-content.d.ts +0 -8
  313. package/dist/reconciler/wrapper-content.d.ts.map +0 -1
  314. package/dist/reconciler/wrapper-content.js +0 -19
  315. package/dist/reconciler/wrapper-content.js.map +0 -1
  316. package/dist/reconciler/wrapper-node.d.ts +0 -8
  317. package/dist/reconciler/wrapper-node.d.ts.map +0 -1
  318. package/dist/reconciler/wrapper-node.js +0 -4
  319. package/dist/reconciler/wrapper-node.js.map +0 -1
  320. package/dist/reconciler/wrapper-protocol.d.ts +0 -13
  321. package/dist/reconciler/wrapper-protocol.d.ts.map +0 -1
  322. package/dist/reconciler/wrapper-protocol.js +0 -20
  323. package/dist/reconciler/wrapper-protocol.js.map +0 -1
  324. package/dist/utils/create-element-component.d.ts +0 -4
  325. package/dist/utils/create-element-component.d.ts.map +0 -1
  326. package/dist/utils/create-element-component.js +0 -54
  327. package/dist/utils/create-element-component.js.map +0 -1
  328. package/dist/utils/gtype.d.ts +0 -16
  329. package/dist/utils/gtype.d.ts.map +0 -1
  330. package/dist/utils/gtype.js +0 -127
  331. package/dist/utils/gtype.js.map +0 -1
  332. package/dist/utils/notify-name.d.ts +0 -5
  333. package/dist/utils/notify-name.d.ts.map +0 -1
  334. package/dist/utils/notify-name.js +0 -6
  335. package/dist/utils/notify-name.js.map +0 -1
  336. package/dist/utils/object-prop.d.ts +0 -8
  337. package/dist/utils/object-prop.d.ts.map +0 -1
  338. package/dist/utils/object-prop.js +0 -9
  339. package/dist/utils/object-prop.js.map +0 -1
  340. package/dist/utils/settings-accessor.d.ts +0 -8
  341. package/dist/utils/settings-accessor.d.ts.map +0 -1
  342. package/dist/utils/settings-accessor.js +0 -69
  343. package/dist/utils/settings-accessor.js.map +0 -1
  344. package/dist/utils/wrapper-node-jsx.d.ts +0 -32
  345. package/dist/utils/wrapper-node-jsx.d.ts.map +0 -1
  346. package/dist/utils/wrapper-node-jsx.js +0 -2
  347. package/dist/utils/wrapper-node-jsx.js.map +0 -1
  348. package/src/hooks/use-merge-refs.ts +0 -53
  349. package/src/hooks/use-object-attachment.ts +0 -35
  350. package/src/libraries/adw/dialog.tsx +0 -34
  351. package/src/libraries/adw/index.ts +0 -1
  352. package/src/reconciler/accessible.ts +0 -232
  353. package/src/reconciler/commit-flush.ts +0 -13
  354. package/src/reconciler/container-attach.ts +0 -219
  355. package/src/reconciler/content-rebuild.ts +0 -19
  356. package/src/reconciler/dispatch.ts +0 -58
  357. package/src/reconciler/element-prop-appliers.ts +0 -110
  358. package/src/reconciler/element-props.ts +0 -192
  359. package/src/reconciler/label-text-rebuild.ts +0 -26
  360. package/src/reconciler/portal.ts +0 -28
  361. package/src/reconciler/reconciler-error-handler.ts +0 -29
  362. package/src/reconciler/reconciler-root.ts +0 -57
  363. package/src/reconciler/reconciler.ts +0 -13
  364. package/src/reconciler/render.ts +0 -61
  365. package/src/reconciler/signal-store.ts +0 -103
  366. package/src/reconciler/state.ts +0 -72
  367. package/src/reconciler/text-buffer-controller.ts +0 -107
  368. package/src/reconciler/text-buffer-rebuild.ts +0 -12
  369. package/src/reconciler/text-node.ts +0 -13
  370. package/src/reconciler/types.ts +0 -6
  371. package/src/reconciler/visibility.ts +0 -52
  372. package/src/reconciler/wrapper-apply.ts +0 -308
  373. package/src/reconciler/wrapper-content.ts +0 -24
  374. package/src/reconciler/wrapper-node.ts +0 -8
  375. package/src/reconciler/wrapper-protocol.ts +0 -32
  376. package/src/utils/create-element-component.ts +0 -77
  377. package/src/utils/gtype.ts +0 -166
  378. package/src/utils/notify-name.ts +0 -10
  379. package/src/utils/object-prop.ts +0 -13
  380. package/src/utils/settings-accessor.ts +0 -89
  381. package/src/utils/wrapper-node-jsx.ts +0 -34
@@ -0,0 +1,407 @@
1
+ import type * as GObject from "@gtkx/gi/gobject";
2
+ import * as Gdk from "@gtkx/gi/gdk";
3
+ import * as Gtk from "@gtkx/gi/gtk";
4
+ import { drain, indexBeforeOrEnd } from "@gtkx/utils";
5
+ import type { ContentChild, ContentKind, ElementNode, ParentNode, TextNode } from "./node.js";
6
+ import type { Props } from "./registry.js";
7
+ import { ELEMENT_KIND, TEXT_KIND } from "./node.js";
8
+
9
+ type OffsetResult = { found: boolean; offset: number };
10
+
11
+ type BufferBuild = {
12
+ buffer: Gtk.TextBuffer;
13
+ view: Gtk.TextView | null;
14
+ marks: { node: ElementNode; offset: number }[];
15
+ };
16
+
17
+ const dirtyHosts: Set<ElementNode> = new Set();
18
+ const tagTables: WeakMap<object, Gtk.TextTagTable> = new WeakMap();
19
+ const TEXT_CONTENT_KINDS: Set<string> = new Set(["label", "buffer", "tag"]);
20
+ const PAINTABLE_PROP = "paintable";
21
+ const TEXT_PROP = "text";
22
+
23
+ const CONTENT_MIX_RULES: { kind: ContentKind; prop: string; message: string }[] = [
24
+ {
25
+ kind: "label",
26
+ prop: "label",
27
+ message: "<GtkLabel> cannot mix a `label` prop with text children; use one or the other",
28
+ },
29
+ {
30
+ kind: "buffer",
31
+ prop: "text",
32
+ message: "<GtkTextBuffer> cannot mix a `text` prop with content children; use one or the other",
33
+ },
34
+ {
35
+ kind: "anchor",
36
+ prop: PAINTABLE_PROP,
37
+ message: "<GtkTextChildAnchor> cannot mix a `paintable` prop with a child widget; use one or the other",
38
+ },
39
+ ];
40
+
41
+ const charLength = (text: string): number => text[Symbol.iterator]().toArray().length;
42
+
43
+ const bufferText = (buffer: Gtk.TextBuffer): string =>
44
+ buffer.getText(buffer.getStartIter(), buffer.getEndIter(), false);
45
+
46
+ const currentText = (object: GObject.Object): string | null => {
47
+ if (object instanceof Gtk.TextBuffer) {
48
+ return bufferText(object);
49
+ }
50
+
51
+ if (object instanceof Gtk.Editable || object instanceof Gtk.EntryBuffer) {
52
+ return object.getText();
53
+ }
54
+
55
+ return null;
56
+ };
57
+
58
+ const hasSameText = (object: GObject.Object, prop: string, value: unknown): boolean =>
59
+ prop === TEXT_PROP && typeof value === "string" && currentText(object) === value;
60
+
61
+ const contentTextLength = (node: ContentChild): number => {
62
+ if (node.kind === TEXT_KIND) {
63
+ return charLength(node.text);
64
+ }
65
+
66
+ if (node.contentKind === "tag") {
67
+ return node.content.reduce((sum, child) => sum + contentTextLength(child), 0);
68
+ }
69
+
70
+ return node.contentKind === "anchor" ? 1 : 0;
71
+ };
72
+
73
+ const isTagElement = (node: ContentChild): node is ElementNode =>
74
+ node.kind === ELEMENT_KIND && node.contentKind === "tag";
75
+
76
+ const stepOffset = (node: ContentChild, target: TextNode, offset: number): OffsetResult => {
77
+ if (node === target) {
78
+ return { found: true, offset };
79
+ }
80
+
81
+ if (isTagElement(node)) {
82
+ return getOffset(node.content, target, offset);
83
+ }
84
+
85
+ return { found: false, offset: offset + contentTextLength(node) };
86
+ };
87
+
88
+ const getOffset = (nodes: ContentChild[], target: TextNode, start: number): OffsetResult => {
89
+ let offset = start;
90
+
91
+ for (const node of nodes) {
92
+ const step = stepOffset(node, target, offset);
93
+
94
+ if (step.found) {
95
+ return step;
96
+ }
97
+
98
+ offset = step.offset;
99
+ }
100
+
101
+ return { found: false, offset };
102
+ };
103
+
104
+ const enclosingTagNodes = (node: TextNode): ElementNode[] => {
105
+ const nodes: ElementNode[] = [];
106
+ let current: ParentNode | null = node.parent;
107
+
108
+ while (current !== null && current.kind === ELEMENT_KIND) {
109
+ if (current.contentKind === "tag") {
110
+ nodes.push(current);
111
+ }
112
+
113
+ current = current.parent;
114
+ }
115
+
116
+ return nodes;
117
+ };
118
+
119
+ const textRestrictionError = (text: string): Error =>
120
+ new Error(
121
+ "Text strings must be rendered within a <GtkLabel> or <GtkTextBuffer> element; " +
122
+ `received ${JSON.stringify(text)}`,
123
+ );
124
+
125
+ const canAcceptText = (host: ElementNode): boolean =>
126
+ host.contentKind !== null && TEXT_CONTENT_KINDS.has(host.contentKind);
127
+
128
+ const isRootHost = (node: ElementNode): boolean => node.contentKind === "label" || node.contentKind === "buffer";
129
+
130
+ const mapElementParent = <T>(parent: ParentNode | null, map: (element: ElementNode) => T): T | null =>
131
+ parent !== null && parent.kind === ELEMENT_KIND ? map(parent) : null;
132
+
133
+ const parentElement = (node: ElementNode): ElementNode | null => mapElementParent(node.parent, (parent) => parent);
134
+
135
+ const getRootHost = (node: ElementNode): ElementNode | null => {
136
+ let current: ElementNode | null = node;
137
+
138
+ while (current !== null) {
139
+ if (isRootHost(current)) {
140
+ return current;
141
+ }
142
+
143
+ current = parentElement(current);
144
+ }
145
+
146
+ return null;
147
+ };
148
+
149
+ const markTextDirty = (host: ElementNode): void => {
150
+ const root = getRootHost(host);
151
+
152
+ if (root !== null) {
153
+ dirtyHosts.add(root);
154
+ }
155
+ };
156
+
157
+ const enclosingHost = (node: TextNode): ElementNode | null => mapElementParent(node.parent, getRootHost);
158
+
159
+ const addContent = (host: ElementNode, child: ContentChild, before: ContentChild | null): void => {
160
+ const content = host.content;
161
+ const existing = content.indexOf(child);
162
+
163
+ if (existing !== -1) {
164
+ content.splice(existing, 1);
165
+ }
166
+
167
+ content.splice(
168
+ indexBeforeOrEnd(content, before, (item, target) => item === target),
169
+ 0,
170
+ child,
171
+ );
172
+
173
+ child.parent = host;
174
+ markTextDirty(host);
175
+ };
176
+
177
+ const removeContent = (host: ElementNode, child: ContentChild): void => {
178
+ const index = host.content.indexOf(child);
179
+
180
+ if (index !== -1) {
181
+ host.content.splice(index, 1);
182
+ }
183
+
184
+ markTextDirty(host);
185
+ };
186
+
187
+ const validateContentMix = (node: ElementNode, props: Props): void => {
188
+ if (node.content.length === 0) {
189
+ return;
190
+ }
191
+
192
+ const violated = CONTENT_MIX_RULES.find(
193
+ (rule) => rule.kind === node.contentKind && props[rule.prop] !== undefined,
194
+ );
195
+
196
+ if (violated !== undefined) {
197
+ throw new Error(violated.message);
198
+ }
199
+ };
200
+
201
+ const detachTag = (tag: Gtk.TextTag, table: Gtk.TextTagTable, name: string | null): void => {
202
+ const previous = tagTables.get(tag);
203
+
204
+ if (previous !== undefined && previous !== table) {
205
+ previous.remove(tag);
206
+ }
207
+
208
+ if (name === null) {
209
+ return;
210
+ }
211
+
212
+ const existing = table.lookup(name);
213
+
214
+ if (existing !== null && existing !== tag) {
215
+ table.remove(existing);
216
+ }
217
+ };
218
+
219
+ const ensureTag = (table: Gtk.TextTagTable, node: ElementNode): void => {
220
+ const tag = node.object;
221
+
222
+ if (!(tag instanceof Gtk.TextTag) || tagTables.get(tag) === table) {
223
+ return;
224
+ }
225
+
226
+ const name = typeof node.props.name === "string" ? node.props.name : null;
227
+ detachTag(tag, table, name);
228
+
229
+ if (name === null || table.lookup(name) !== tag) {
230
+ table.add(tag);
231
+ }
232
+
233
+ tagTables.set(tag, table);
234
+ };
235
+
236
+ const insertTag = (build: BufferBuild, node: ElementNode): void => {
237
+ const start = build.buffer.getCharCount();
238
+ insertContent(build, node.content);
239
+ const tag = node.object;
240
+
241
+ if (tag instanceof Gtk.TextTag) {
242
+ ensureTag(build.buffer.getTagTable(), node);
243
+ build.buffer.applyTag(tag, build.buffer.getIterAtOffset(start), build.buffer.getEndIter());
244
+ }
245
+ };
246
+
247
+ const contentPaintable = (node: ElementNode): Gdk.Paintable | null => {
248
+ const value = node.props[PAINTABLE_PROP];
249
+
250
+ return value instanceof Gdk.Paintable ? value : null;
251
+ };
252
+
253
+ const isContentPaintableProp = (node: ElementNode, name: string): boolean =>
254
+ name === PAINTABLE_PROP && node.contentKind === "anchor";
255
+
256
+ const insertAnchor = (build: BufferBuild, node: ElementNode): void => {
257
+ const paintable = contentPaintable(node);
258
+
259
+ if (paintable !== null) {
260
+ build.buffer.insertPaintable(build.buffer.getEndIter(), paintable);
261
+
262
+ return;
263
+ }
264
+
265
+ const anchor = node.object;
266
+
267
+ if (!(anchor instanceof Gtk.TextChildAnchor)) {
268
+ return;
269
+ }
270
+
271
+ build.buffer.insertChildAnchor(build.buffer.getEndIter(), anchor);
272
+ const child = node.content[0];
273
+
274
+ if (build.view !== null && child?.kind === ELEMENT_KIND && child.object instanceof Gtk.Widget) {
275
+ build.view.addChildAtAnchor(child.object, anchor);
276
+ }
277
+ };
278
+
279
+ const insertElement = (build: BufferBuild, node: ElementNode): void => {
280
+ if (node.contentKind === "tag") {
281
+ insertTag(build, node);
282
+ } else if (node.contentKind === "anchor") {
283
+ insertAnchor(build, node);
284
+ } else {
285
+ build.marks.push({ node, offset: build.buffer.getCharCount() });
286
+ }
287
+ };
288
+
289
+ const insertContent = (build: BufferBuild, nodes: ContentChild[]): void => {
290
+ for (const child of nodes) {
291
+ if (child.kind === TEXT_KIND) {
292
+ build.buffer.insert(build.buffer.getEndIter(), child.text, -1);
293
+ } else {
294
+ insertElement(build, child);
295
+ }
296
+ }
297
+ };
298
+
299
+ const placeMark = (buffer: Gtk.TextBuffer, node: ElementNode, offset: number): void => {
300
+ const mark = node.object;
301
+
302
+ if (!(mark instanceof Gtk.TextMark)) {
303
+ return;
304
+ }
305
+
306
+ const iter = buffer.getIterAtOffset(offset);
307
+
308
+ if (mark.getBuffer() === null) {
309
+ buffer.addMark(mark, iter);
310
+ } else {
311
+ buffer.moveMark(mark, iter);
312
+ }
313
+ };
314
+
315
+ const rebuildBuffer = (node: ElementNode): void => {
316
+ const buffer = node.object;
317
+
318
+ if (node.props.text !== undefined || !(buffer instanceof Gtk.TextBuffer)) {
319
+ return;
320
+ }
321
+
322
+ buffer.setText("", -1);
323
+ const build: BufferBuild = { buffer, view: node.bufferView, marks: [] };
324
+ insertContent(build, node.content);
325
+
326
+ for (const mark of build.marks) {
327
+ placeMark(buffer, mark.node, mark.offset);
328
+ }
329
+ };
330
+
331
+ const rebuildLabel = (node: ElementNode): void => {
332
+ if (node.props.label !== undefined) {
333
+ return;
334
+ }
335
+
336
+ const label = node.object;
337
+
338
+ if (!(label instanceof Gtk.Label)) {
339
+ return;
340
+ }
341
+
342
+ label.setLabel(node.content.map((child) => (child.kind === TEXT_KIND ? child.text : "")).join(""));
343
+ };
344
+
345
+ const flushTextHosts = (): void => {
346
+ drain(dirtyHosts, (host) => {
347
+ if (host.contentKind === "label") {
348
+ rebuildLabel(host);
349
+ } else if (host.contentKind === "buffer") {
350
+ rebuildBuffer(host);
351
+ }
352
+ });
353
+ };
354
+
355
+ const applyEnclosingTags = (
356
+ buffer: Gtk.TextBuffer,
357
+ node: TextNode,
358
+ startIter: Gtk.TextIter,
359
+ endIter: Gtk.TextIter,
360
+ ): void => {
361
+ for (const tagNode of enclosingTagNodes(node)) {
362
+ ensureTag(buffer.getTagTable(), tagNode);
363
+
364
+ if (tagNode.object instanceof Gtk.TextTag) {
365
+ buffer.applyTag(tagNode.object, startIter, endIter);
366
+ }
367
+ }
368
+ };
369
+
370
+ const didUpdateTextSurgically = (host: ElementNode, node: TextNode, oldText: string, newText: string): boolean => {
371
+ const buffer = host.object;
372
+
373
+ if (host.contentKind !== "buffer" || !(buffer instanceof Gtk.TextBuffer)) {
374
+ return false;
375
+ }
376
+
377
+ const located = getOffset(host.content, node, 0);
378
+
379
+ if (!located.found) {
380
+ return false;
381
+ }
382
+
383
+ const start = located.offset;
384
+ buffer.delete(buffer.getIterAtOffset(start), buffer.getIterAtOffset(start + charLength(oldText)));
385
+ buffer.insert(buffer.getIterAtOffset(start), newText, -1);
386
+ const startIter = buffer.getIterAtOffset(start);
387
+ const endIter = buffer.getIterAtOffset(start + charLength(newText));
388
+ applyEnclosingTags(buffer, node, startIter, endIter);
389
+
390
+ return true;
391
+ };
392
+
393
+ export {
394
+ TEXT_PROP,
395
+ textRestrictionError,
396
+ bufferText,
397
+ hasSameText,
398
+ canAcceptText,
399
+ isContentPaintableProp,
400
+ markTextDirty,
401
+ enclosingHost,
402
+ addContent,
403
+ removeContent,
404
+ validateContentMix,
405
+ flushTextHosts,
406
+ didUpdateTextSurgically,
407
+ };
@@ -1,26 +1,31 @@
1
- import type * as Gtk from "@gtkx/gi/gtk";
1
+ const metadataStore: WeakMap<object, Map<string, unknown>> = new WeakMap();
2
2
 
3
- type AccessibleMetadata = Map<string, unknown>;
3
+ const setAccessibleMetadata = (widget: object, name: string, value: unknown): void => {
4
+ let entries = metadataStore.get(widget);
4
5
 
5
- const accessibleMetadata = new WeakMap<Gtk.Accessible, AccessibleMetadata>();
6
-
7
- export const setAccessibleMetadata = (accessible: Gtk.Accessible, propName: string, value: unknown): void => {
8
- let entry = accessibleMetadata.get(accessible);
9
- if (!entry) {
10
- entry = new Map();
11
- accessibleMetadata.set(accessible, entry);
6
+ if (entries === undefined) {
7
+ entries = new Map();
8
+ metadataStore.set(widget, entries);
12
9
  }
13
- entry.set(propName, value);
10
+
11
+ entries.set(name, value);
14
12
  };
15
13
 
16
- export const deleteAccessibleMetadata = (accessible: Gtk.Accessible, propName: string): void => {
17
- const entry = accessibleMetadata.get(accessible);
18
- if (entry) entry.delete(propName);
14
+ const deleteAccessibleMetadata = (widget: object, name: string): void => {
15
+ metadataStore.get(widget)?.delete(name);
19
16
  };
20
17
 
21
- export const getAccessibleMetadata = <T = unknown>(accessible: Gtk.Accessible, propName: string): T | null => {
22
- const entry = accessibleMetadata.get(accessible);
23
- if (!entry) return null;
24
- const value = entry.get(propName);
25
- return (value as T) ?? null;
18
+ /**
19
+ * Returns the last value applied for an accessible prop on a widget, or null when none was applied.
20
+ *
21
+ * @param widget The widget to read from.
22
+ * @param name The accessible prop name.
23
+ * @returns The last applied value, or null.
24
+ */
25
+ const getAccessibleMetadata = (widget: object, name: string): unknown => {
26
+ const value = metadataStore.get(widget)?.get(name);
27
+
28
+ return value === undefined ? null : value;
26
29
  };
30
+
31
+ export { setAccessibleMetadata, deleteAccessibleMetadata, getAccessibleMetadata };