@gjsify/adwaita-web 0.53.0 → 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. package/dist/adwaita-web.css +8070 -3037
  2. package/dist/adwaita-web.css.map +1 -1
  3. package/lib/types/adw-application-window.spec.d.ts +1 -0
  4. package/lib/types/adw-bin.spec.d.ts +1 -0
  5. package/lib/types/adw-breakpoint-bin.spec.d.ts +1 -0
  6. package/lib/types/adw-clamp-scrollable.spec.d.ts +1 -0
  7. package/lib/types/adw-multi-layout-view.spec.d.ts +1 -0
  8. package/lib/types/adw-preferences-row.spec.d.ts +1 -0
  9. package/lib/types/adw-shortcuts.spec.d.ts +1 -0
  10. package/lib/types/adw-tab-bar.spec.d.ts +1 -0
  11. package/lib/types/adw-tab-button.spec.d.ts +1 -0
  12. package/lib/types/adw-tab-overview.spec.d.ts +1 -0
  13. package/lib/types/adw-view-switcher-sidebar.spec.d.ts +1 -0
  14. package/lib/types/adw-window.spec.d.ts +1 -0
  15. package/lib/types/breakpoints.d.ts +14 -3
  16. package/lib/types/construct-vectors.spec.d.ts +1 -0
  17. package/lib/types/elements/adw-application-window.d.ts +27 -0
  18. package/lib/types/elements/adw-bin.d.ts +17 -0
  19. package/lib/types/elements/adw-breakpoint-bin.d.ts +67 -0
  20. package/lib/types/elements/adw-clamp-scrollable.d.ts +38 -0
  21. package/lib/types/elements/adw-dialog.d.ts +10 -0
  22. package/lib/types/elements/adw-layout-slot.d.ts +19 -0
  23. package/lib/types/elements/adw-multi-layout-view.d.ts +101 -0
  24. package/lib/types/elements/adw-preferences-row.d.ts +31 -0
  25. package/lib/types/elements/adw-shortcuts-dialog.d.ts +13 -0
  26. package/lib/types/elements/adw-shortcuts-item.d.ts +36 -0
  27. package/lib/types/elements/adw-shortcuts-section.d.ts +14 -0
  28. package/lib/types/elements/adw-sidebar.d.ts +5 -0
  29. package/lib/types/elements/adw-switch-row.d.ts +3 -0
  30. package/lib/types/elements/adw-tab-bar.d.ts +108 -0
  31. package/lib/types/elements/adw-tab-button.d.ts +32 -0
  32. package/lib/types/elements/adw-tab-overview.d.ts +199 -0
  33. package/lib/types/elements/adw-tab-view.d.ts +19 -23
  34. package/lib/types/elements/adw-view-switcher-sidebar.d.ts +84 -0
  35. package/lib/types/elements/adw-window.d.ts +40 -0
  36. package/lib/types/elements/gtk-about-dialog.d.ts +146 -0
  37. package/lib/types/elements/gtk-application-window.d.ts +34 -0
  38. package/lib/types/elements/gtk-aspect-frame.d.ts +27 -0
  39. package/lib/types/elements/gtk-button.d.ts +9 -0
  40. package/lib/types/elements/gtk-calendar.d.ts +159 -0
  41. package/lib/types/elements/gtk-center-box.d.ts +39 -0
  42. package/lib/types/elements/gtk-color-dialog-button.d.ts +69 -0
  43. package/lib/types/elements/gtk-column-view.d.ts +50 -0
  44. package/lib/types/elements/gtk-drag-icon.d.ts +78 -0
  45. package/lib/types/elements/gtk-drawing-area.d.ts +95 -0
  46. package/lib/types/elements/gtk-editable-label.d.ts +33 -0
  47. package/lib/types/elements/gtk-emoji-chooser.d.ts +84 -0
  48. package/lib/types/elements/gtk-entry.d.ts +20 -1
  49. package/lib/types/elements/gtk-expander.d.ts +49 -0
  50. package/lib/types/elements/gtk-fixed.d.ts +13 -0
  51. package/lib/types/elements/gtk-flow-box-child.d.ts +14 -0
  52. package/lib/types/elements/gtk-flow-box.d.ts +87 -0
  53. package/lib/types/elements/gtk-font-dialog-button.d.ts +83 -0
  54. package/lib/types/elements/gtk-frame.d.ts +24 -0
  55. package/lib/types/elements/gtk-gl-area.d.ts +136 -0
  56. package/lib/types/elements/gtk-graphics-offload.d.ts +24 -0
  57. package/lib/types/elements/gtk-grid-view.d.ts +39 -0
  58. package/lib/types/elements/gtk-grid.d.ts +27 -0
  59. package/lib/types/elements/gtk-header-bar.d.ts +60 -0
  60. package/lib/types/elements/gtk-inscription.d.ts +64 -0
  61. package/lib/types/elements/gtk-label.d.ts +3 -0
  62. package/lib/types/elements/gtk-level-bar.d.ts +59 -0
  63. package/lib/types/elements/gtk-link-button.d.ts +29 -0
  64. package/lib/types/elements/gtk-list-box-row.d.ts +54 -0
  65. package/lib/types/elements/gtk-list-box.d.ts +100 -0
  66. package/lib/types/elements/gtk-list-view.d.ts +73 -0
  67. package/lib/types/elements/gtk-media-controls.d.ts +142 -0
  68. package/lib/types/elements/gtk-notebook.d.ts +148 -0
  69. package/lib/types/elements/gtk-overlay.d.ts +22 -0
  70. package/lib/types/elements/gtk-page-setup-unix-dialog.d.ts +87 -0
  71. package/lib/types/elements/gtk-paned.d.ts +121 -0
  72. package/lib/types/elements/gtk-password-entry.d.ts +27 -0
  73. package/lib/types/elements/gtk-picture.d.ts +66 -0
  74. package/lib/types/elements/gtk-popover-bin.d.ts +82 -0
  75. package/lib/types/elements/gtk-popover-menu-bar.d.ts +66 -0
  76. package/lib/types/elements/gtk-popover-menu.d.ts +83 -0
  77. package/lib/types/elements/gtk-popover.d.ts +28 -3
  78. package/lib/types/elements/gtk-print-unix-dialog.d.ts +167 -0
  79. package/lib/types/elements/gtk-revealer.d.ts +55 -0
  80. package/lib/types/elements/gtk-scale-button.d.ts +59 -0
  81. package/lib/types/elements/gtk-scale.d.ts +98 -0
  82. package/lib/types/elements/gtk-scrollbar.d.ts +124 -0
  83. package/lib/types/elements/gtk-scrolled-window.d.ts +121 -0
  84. package/lib/types/elements/gtk-search-bar.d.ts +39 -0
  85. package/lib/types/elements/gtk-search-entry.d.ts +27 -0
  86. package/lib/types/elements/gtk-separator.d.ts +10 -0
  87. package/lib/types/elements/gtk-spin-button.d.ts +94 -0
  88. package/lib/types/elements/gtk-spinner.d.ts +14 -0
  89. package/lib/types/elements/gtk-stack-sidebar.d.ts +43 -0
  90. package/lib/types/elements/gtk-stack-switcher.d.ts +58 -0
  91. package/lib/types/elements/gtk-stack.d.ts +154 -0
  92. package/lib/types/elements/gtk-switch.d.ts +4 -1
  93. package/lib/types/elements/gtk-text-view.d.ts +62 -0
  94. package/lib/types/elements/gtk-text.d.ts +45 -0
  95. package/lib/types/elements/gtk-toggle-button.d.ts +45 -0
  96. package/lib/types/elements/gtk-tree-expander.d.ts +38 -0
  97. package/lib/types/elements/gtk-video.d.ts +97 -0
  98. package/lib/types/elements/gtk-viewport.d.ts +84 -0
  99. package/lib/types/elements/gtk-window-controls.d.ts +80 -0
  100. package/lib/types/elements/gtk-window-handle.d.ts +39 -0
  101. package/lib/types/elements/gtk-window.d.ts +97 -0
  102. package/lib/types/elements/justification.d.ts +2 -0
  103. package/lib/types/elements/popover-menu.d.ts +18 -0
  104. package/lib/types/elements/roving-focus.d.ts +29 -1
  105. package/lib/types/emoji-data.d.ts +38 -0
  106. package/lib/types/font-description.d.ts +96 -0
  107. package/lib/types/gtk-about-dialog.spec.d.ts +1 -0
  108. package/lib/types/gtk-action-bar.spec.d.ts +1 -0
  109. package/lib/types/gtk-application-window.spec.d.ts +1 -0
  110. package/lib/types/gtk-aspect-frame.spec.d.ts +1 -0
  111. package/lib/types/gtk-calendar.spec.d.ts +1 -0
  112. package/lib/types/gtk-center-box.spec.d.ts +1 -0
  113. package/lib/types/gtk-color-dialog-button.spec.d.ts +1 -0
  114. package/lib/types/gtk-column-view.spec.d.ts +1 -0
  115. package/lib/types/gtk-drag-icon.spec.d.ts +1 -0
  116. package/lib/types/gtk-drawing-area.spec.d.ts +1 -0
  117. package/lib/types/gtk-editable-label.spec.d.ts +1 -0
  118. package/lib/types/gtk-emoji-chooser.spec.d.ts +1 -0
  119. package/lib/types/gtk-expander.spec.d.ts +1 -0
  120. package/lib/types/gtk-fixed.spec.d.ts +1 -0
  121. package/lib/types/gtk-flow-box.spec.d.ts +1 -0
  122. package/lib/types/gtk-font-dialog-button.spec.d.ts +1 -0
  123. package/lib/types/gtk-frame.spec.d.ts +1 -0
  124. package/lib/types/gtk-gl-area.spec.d.ts +1 -0
  125. package/lib/types/gtk-graphics-offload.spec.d.ts +1 -0
  126. package/lib/types/gtk-grid-view.spec.d.ts +1 -0
  127. package/lib/types/gtk-grid.spec.d.ts +1 -0
  128. package/lib/types/gtk-header-bar.spec.d.ts +1 -0
  129. package/lib/types/gtk-inscription.spec.d.ts +1 -0
  130. package/lib/types/gtk-level-bar.spec.d.ts +1 -0
  131. package/lib/types/gtk-link-button.spec.d.ts +1 -0
  132. package/lib/types/gtk-list-box.spec.d.ts +1 -0
  133. package/lib/types/gtk-list-view.spec.d.ts +1 -0
  134. package/lib/types/gtk-media-controls.spec.d.ts +1 -0
  135. package/lib/types/gtk-notebook.spec.d.ts +1 -0
  136. package/lib/types/gtk-overlay.spec.d.ts +1 -0
  137. package/lib/types/gtk-paned.spec.d.ts +1 -0
  138. package/lib/types/gtk-password-entry.spec.d.ts +1 -0
  139. package/lib/types/gtk-picture.spec.d.ts +1 -0
  140. package/lib/types/gtk-popover-bin.spec.d.ts +1 -0
  141. package/lib/types/gtk-popover-menu-bar.spec.d.ts +1 -0
  142. package/lib/types/gtk-popover-menu.spec.d.ts +1 -0
  143. package/lib/types/gtk-popover-role.spec.d.ts +1 -0
  144. package/lib/types/gtk-popover.spec.d.ts +1 -0
  145. package/lib/types/gtk-print-dialogs.spec.d.ts +1 -0
  146. package/lib/types/gtk-revealer.spec.d.ts +1 -0
  147. package/lib/types/gtk-scale-button.spec.d.ts +1 -0
  148. package/lib/types/gtk-scale.spec.d.ts +1 -0
  149. package/lib/types/gtk-scrollbar.spec.d.ts +1 -0
  150. package/lib/types/gtk-scrolled-window.spec.d.ts +1 -0
  151. package/lib/types/gtk-search-bar.spec.d.ts +1 -0
  152. package/lib/types/gtk-search-entry.spec.d.ts +1 -0
  153. package/lib/types/gtk-separator.spec.d.ts +1 -0
  154. package/lib/types/gtk-spin-button.spec.d.ts +1 -0
  155. package/lib/types/gtk-spinner.spec.d.ts +1 -0
  156. package/lib/types/gtk-stack-sidebar.spec.d.ts +1 -0
  157. package/lib/types/gtk-stack-switcher.spec.d.ts +1 -0
  158. package/lib/types/gtk-stack.spec.d.ts +1 -0
  159. package/lib/types/gtk-text-view.spec.d.ts +1 -0
  160. package/lib/types/gtk-text.spec.d.ts +1 -0
  161. package/lib/types/gtk-toggle-button.spec.d.ts +1 -0
  162. package/lib/types/gtk-tree-expander.spec.d.ts +1 -0
  163. package/lib/types/gtk-video.spec.d.ts +1 -0
  164. package/lib/types/gtk-viewport.spec.d.ts +1 -0
  165. package/lib/types/gtk-window-controls.spec.d.ts +1 -0
  166. package/lib/types/gtk-window-handle.spec.d.ts +1 -0
  167. package/lib/types/gtk-window.spec.d.ts +1 -0
  168. package/lib/types/index.d.ts +4 -1
  169. package/lib/types/list-view-dom.d.ts +44 -0
  170. package/lib/types/namespace/adw.d.ts +12 -0
  171. package/lib/types/namespace/gtk.d.ts +61 -0
  172. package/lib/types/page-setup.d.ts +100 -0
  173. package/lib/types/scroll-shading.d.ts +15 -1
  174. package/lib/types/shared-tree-builder.d.ts +30 -2
  175. package/lib/types/signals.d.ts +4 -0
  176. package/lib/types/styles.generated.d.ts +1 -1
  177. package/lib/types/tab-chip.d.ts +73 -0
  178. package/lib/types/template-classes.d.ts +11 -0
  179. package/package.json +12 -8
  180. package/scss/_action_row.scss +2 -2
  181. package/scss/_application_window.scss +26 -0
  182. package/scss/_aspect_frame.scss +25 -0
  183. package/scss/_bin.scss +26 -0
  184. package/scss/_button.scss +45 -0
  185. package/scss/_calendar.scss +176 -0
  186. package/scss/_center_box.scss +25 -0
  187. package/scss/_checks.scss +6 -1
  188. package/scss/_clamp_scrollable.scss +28 -0
  189. package/scss/_color_button.scss +67 -0
  190. package/scss/_column_view.scss +126 -0
  191. package/scss/_drag_icon.scss +55 -0
  192. package/scss/_drawing.scss +85 -0
  193. package/scss/_emoji_chooser.scss +213 -0
  194. package/scss/_entry.scss +13 -5
  195. package/scss/_entry_row.scss +1 -1
  196. package/scss/_expander.scss +113 -0
  197. package/scss/_fixed.scss +29 -0
  198. package/scss/_flow_box.scss +94 -0
  199. package/scss/_font_button.scss +63 -0
  200. package/scss/_frame.scss +41 -0
  201. package/scss/_grid.scss +19 -0
  202. package/scss/_grid_view.scss +46 -0
  203. package/scss/_gtk_about_dialog.scss +186 -0
  204. package/scss/_headerbar.scss +132 -0
  205. package/scss/_icons.generated.scss +186 -0
  206. package/scss/_inscription.scss +125 -0
  207. package/scss/_level_bar.scss +190 -0
  208. package/scss/_link.scss +82 -0
  209. package/scss/_list_box.scss +88 -0
  210. package/scss/_list_view.scss +96 -0
  211. package/scss/_media_controls.scss +139 -0
  212. package/scss/_overlay.scss +68 -0
  213. package/scss/_paned.scss +130 -0
  214. package/scss/_password_entry.scss +83 -0
  215. package/scss/_picture.scss +80 -0
  216. package/scss/_popover_bin.scss +53 -0
  217. package/scss/_popover_menu_bar.scss +104 -0
  218. package/scss/_preferences_row.scss +51 -0
  219. package/scss/_print_dialogs.scss +328 -0
  220. package/scss/_reset.scss +21 -19
  221. package/scss/_revealer.scss +37 -0
  222. package/scss/_row.scss +20 -5
  223. package/scss/_scale.scss +298 -0
  224. package/scss/_scale_button.scss +167 -0
  225. package/scss/_scrollbar.scss +230 -0
  226. package/scss/_scrolled_window.scss +131 -0
  227. package/scss/_search_bar.scss +118 -0
  228. package/scss/_search_entry.scss +86 -0
  229. package/scss/_separator.scss +44 -0
  230. package/scss/_shortcuts_dialog.scss +100 -0
  231. package/scss/_spin_button.scss +172 -0
  232. package/scss/_spin_row.scss +56 -8
  233. package/scss/_spinner.scss +85 -4
  234. package/scss/_stack.scss +729 -0
  235. package/scss/_switch.scss +13 -5
  236. package/scss/_switch_row.scss +10 -0
  237. package/scss/_tab_bar.scss +317 -0
  238. package/scss/_tab_button.scss +98 -0
  239. package/scss/_tab_overview.scss +483 -0
  240. package/scss/_text.scss +182 -0
  241. package/scss/_theme.scss +1 -1
  242. package/scss/_tree_expander.scss +62 -0
  243. package/scss/_variables.scss +43 -21
  244. package/scss/_video.scss +146 -0
  245. package/scss/_view_switcher_sidebar.scss +112 -0
  246. package/scss/_viewport.scss +50 -0
  247. package/scss/_window.scss +118 -1
  248. package/scss/_window_handle.scss +20 -0
  249. package/scss/adwaita-skin.scss +109 -0
  250. package/src/adw-action-rows.spec.ts +76 -0
  251. package/src/adw-application-window.spec.ts +118 -0
  252. package/src/adw-bin.spec.ts +75 -0
  253. package/src/adw-breakpoint-bin.spec.ts +324 -0
  254. package/src/adw-clamp-scrollable.spec.ts +189 -0
  255. package/src/adw-multi-layout-view.spec.ts +243 -0
  256. package/src/adw-preferences-row.spec.ts +164 -0
  257. package/src/adw-row-state.spec.ts +142 -0
  258. package/src/adw-shortcuts.spec.ts +155 -0
  259. package/src/adw-tab-bar.spec.ts +287 -0
  260. package/src/adw-tab-button.spec.ts +101 -0
  261. package/src/adw-tab-overview.spec.ts +443 -0
  262. package/src/adw-view-switcher-sidebar.spec.ts +281 -0
  263. package/src/adw-window.spec.ts +129 -0
  264. package/src/breakpoints.ts +25 -8
  265. package/src/capabilities.d.mts +3 -0
  266. package/src/capabilities.mjs +18 -0
  267. package/src/connect-lifecycle.spec.ts +12 -0
  268. package/src/construct-vectors.spec.ts +175 -0
  269. package/src/elements/adw-application-window.ts +154 -0
  270. package/src/elements/adw-bin.ts +101 -0
  271. package/src/elements/adw-breakpoint-bin.ts +287 -0
  272. package/src/elements/adw-clamp-scrollable.ts +207 -0
  273. package/src/elements/adw-dialog.ts +19 -0
  274. package/src/elements/adw-layout-slot.ts +95 -0
  275. package/src/elements/adw-multi-layout-view.ts +326 -0
  276. package/src/elements/adw-preferences-row.ts +150 -0
  277. package/src/elements/adw-shortcuts-dialog.ts +52 -0
  278. package/src/elements/adw-shortcuts-item.ts +171 -0
  279. package/src/elements/adw-shortcuts-section.ts +86 -0
  280. package/src/elements/adw-sidebar.ts +42 -3
  281. package/src/elements/adw-switch-row.ts +28 -1
  282. package/src/elements/adw-tab-bar.ts +529 -0
  283. package/src/elements/adw-tab-button.ts +194 -0
  284. package/src/elements/adw-tab-overview.ts +1011 -0
  285. package/src/elements/adw-tab-view.ts +66 -145
  286. package/src/elements/adw-toggle-group.ts +20 -5
  287. package/src/elements/adw-view-stack.ts +18 -0
  288. package/src/elements/adw-view-switcher-sidebar.ts +332 -0
  289. package/src/elements/adw-window.ts +185 -11
  290. package/src/elements/checks.ts +35 -8
  291. package/src/elements/gtk-about-dialog.ts +811 -0
  292. package/src/elements/gtk-application-window.ts +108 -0
  293. package/src/elements/gtk-aspect-frame.ts +160 -0
  294. package/src/elements/gtk-button.ts +12 -0
  295. package/src/elements/gtk-calendar.ts +757 -0
  296. package/src/elements/gtk-center-box.ts +184 -0
  297. package/src/elements/gtk-color-dialog-button.ts +278 -0
  298. package/src/elements/gtk-column-view.ts +320 -0
  299. package/src/elements/gtk-drag-icon.ts +257 -0
  300. package/src/elements/gtk-drawing-area.ts +303 -0
  301. package/src/elements/gtk-editable-label.ts +204 -0
  302. package/src/elements/gtk-emoji-chooser.ts +542 -0
  303. package/src/elements/gtk-entry.ts +39 -5
  304. package/src/elements/gtk-expander.ts +301 -0
  305. package/src/elements/gtk-fixed.ts +99 -0
  306. package/src/elements/gtk-flow-box-child.ts +68 -0
  307. package/src/elements/gtk-flow-box.ts +480 -0
  308. package/src/elements/gtk-font-dialog-button.ts +432 -0
  309. package/src/elements/gtk-frame.ts +174 -0
  310. package/src/elements/gtk-gl-area.ts +476 -0
  311. package/src/elements/gtk-graphics-offload.ts +130 -0
  312. package/src/elements/gtk-grid-view.ts +168 -0
  313. package/src/elements/gtk-grid.ts +127 -0
  314. package/src/elements/gtk-header-bar.ts +273 -0
  315. package/src/elements/gtk-inscription.ts +387 -0
  316. package/src/elements/gtk-label.ts +19 -11
  317. package/src/elements/gtk-level-bar.ts +323 -0
  318. package/src/elements/gtk-link-button.ts +138 -0
  319. package/src/elements/gtk-list-box-row.ts +195 -0
  320. package/src/elements/gtk-list-box.ts +413 -0
  321. package/src/elements/gtk-list-view.ts +370 -0
  322. package/src/elements/gtk-media-controls.ts +509 -0
  323. package/src/elements/gtk-notebook.ts +664 -0
  324. package/src/elements/gtk-overlay.ts +149 -0
  325. package/src/elements/gtk-page-setup-unix-dialog.ts +420 -0
  326. package/src/elements/gtk-paned.ts +597 -0
  327. package/src/elements/gtk-password-entry.ts +170 -0
  328. package/src/elements/gtk-picture.ts +254 -0
  329. package/src/elements/gtk-popover-bin.ts +332 -0
  330. package/src/elements/gtk-popover-menu-bar.ts +355 -0
  331. package/src/elements/gtk-popover-menu.ts +339 -0
  332. package/src/elements/gtk-popover.ts +92 -10
  333. package/src/elements/gtk-print-unix-dialog.ts +989 -0
  334. package/src/elements/gtk-progress-bar.ts +24 -11
  335. package/src/elements/gtk-revealer.ts +406 -0
  336. package/src/elements/gtk-scale-button.ts +358 -0
  337. package/src/elements/gtk-scale.ts +492 -0
  338. package/src/elements/gtk-scrollbar.ts +528 -0
  339. package/src/elements/gtk-scrolled-window.ts +642 -0
  340. package/src/elements/gtk-search-bar.ts +200 -0
  341. package/src/elements/gtk-search-entry.ts +172 -0
  342. package/src/elements/gtk-separator.ts +52 -0
  343. package/src/elements/gtk-spin-button.ts +475 -0
  344. package/src/elements/gtk-spinner.ts +126 -0
  345. package/src/elements/gtk-stack-sidebar.ts +212 -0
  346. package/src/elements/gtk-stack-switcher.ts +279 -0
  347. package/src/elements/gtk-stack.ts +748 -0
  348. package/src/elements/gtk-switch.ts +52 -19
  349. package/src/elements/gtk-text-view.ts +290 -0
  350. package/src/elements/gtk-text.ts +219 -0
  351. package/src/elements/gtk-toggle-button.ts +239 -0
  352. package/src/elements/gtk-tree-expander.ts +243 -0
  353. package/src/elements/gtk-video.ts +423 -0
  354. package/src/elements/gtk-viewport.ts +277 -0
  355. package/src/elements/gtk-window-controls.ts +341 -0
  356. package/src/elements/gtk-window-handle.ts +221 -0
  357. package/src/elements/gtk-window.ts +366 -0
  358. package/src/elements/justification.ts +24 -0
  359. package/src/elements/popover-menu.ts +24 -0
  360. package/src/elements/roving-focus.ts +53 -21
  361. package/src/emoji-data.ts +577 -0
  362. package/src/entry-rows.spec.ts +31 -0
  363. package/src/font-description.ts +238 -0
  364. package/src/gtk-about-dialog.spec.ts +250 -0
  365. package/src/gtk-action-bar.spec.ts +89 -0
  366. package/src/gtk-application-window.spec.ts +107 -0
  367. package/src/gtk-aspect-frame.spec.ts +114 -0
  368. package/src/gtk-calendar.spec.ts +589 -0
  369. package/src/gtk-center-box.spec.ts +125 -0
  370. package/src/gtk-color-dialog-button.spec.ts +141 -0
  371. package/src/gtk-column-view.spec.ts +154 -0
  372. package/src/gtk-drag-icon.spec.ts +190 -0
  373. package/src/gtk-drawing-area.spec.ts +211 -0
  374. package/src/gtk-editable-label.spec.ts +190 -0
  375. package/src/gtk-emoji-chooser.spec.ts +173 -0
  376. package/src/gtk-entry.spec.ts +23 -0
  377. package/src/gtk-expander.spec.ts +170 -0
  378. package/src/gtk-fixed.spec.ts +97 -0
  379. package/src/gtk-flow-box.spec.ts +289 -0
  380. package/src/gtk-font-dialog-button.spec.ts +166 -0
  381. package/src/gtk-frame.spec.ts +119 -0
  382. package/src/gtk-gl-area.spec.ts +361 -0
  383. package/src/gtk-graphics-offload.spec.ts +119 -0
  384. package/src/gtk-grid-view.spec.ts +106 -0
  385. package/src/gtk-grid.spec.ts +122 -0
  386. package/src/gtk-header-bar.spec.ts +202 -0
  387. package/src/gtk-inscription.spec.ts +235 -0
  388. package/src/gtk-level-bar.spec.ts +199 -0
  389. package/src/gtk-link-button.spec.ts +117 -0
  390. package/src/gtk-list-box.spec.ts +422 -0
  391. package/src/gtk-list-view.spec.ts +203 -0
  392. package/src/gtk-media-controls.spec.ts +295 -0
  393. package/src/gtk-notebook.spec.ts +546 -0
  394. package/src/gtk-overlay.spec.ts +141 -0
  395. package/src/gtk-paned.spec.ts +267 -0
  396. package/src/gtk-password-entry.spec.ts +150 -0
  397. package/src/gtk-picture.spec.ts +172 -0
  398. package/src/gtk-popover-bin.spec.ts +229 -0
  399. package/src/gtk-popover-menu-bar.spec.ts +296 -0
  400. package/src/gtk-popover-menu.spec.ts +261 -0
  401. package/src/gtk-popover-role.spec.ts +138 -0
  402. package/src/gtk-popover.spec.ts +264 -0
  403. package/src/gtk-print-dialogs.spec.ts +251 -0
  404. package/src/gtk-revealer.spec.ts +164 -0
  405. package/src/gtk-scale-button.spec.ts +218 -0
  406. package/src/gtk-scale.spec.ts +213 -0
  407. package/src/gtk-scrollbar.spec.ts +244 -0
  408. package/src/gtk-scrolled-window.spec.ts +262 -0
  409. package/src/gtk-search-bar.spec.ts +179 -0
  410. package/src/gtk-search-entry.spec.ts +142 -0
  411. package/src/gtk-separator.spec.ts +74 -0
  412. package/src/gtk-spin-button.spec.ts +186 -0
  413. package/src/gtk-spinner.spec.ts +130 -0
  414. package/src/gtk-stack-sidebar.spec.ts +217 -0
  415. package/src/gtk-stack-switcher.spec.ts +249 -0
  416. package/src/gtk-stack.spec.ts +432 -0
  417. package/src/gtk-text-view.spec.ts +189 -0
  418. package/src/gtk-text.spec.ts +163 -0
  419. package/src/gtk-toggle-button.spec.ts +186 -0
  420. package/src/gtk-tree-expander.spec.ts +201 -0
  421. package/src/gtk-video.spec.ts +240 -0
  422. package/src/gtk-viewport.spec.ts +140 -0
  423. package/src/gtk-window-controls.spec.ts +232 -0
  424. package/src/gtk-window-handle.spec.ts +158 -0
  425. package/src/gtk-window.spec.ts +190 -0
  426. package/src/index.ts +9 -1
  427. package/src/keyboard-operable.spec.ts +33 -1
  428. package/src/list-view-dom.ts +121 -0
  429. package/src/namespace/adw.ts +12 -0
  430. package/src/namespace/gtk.ts +61 -0
  431. package/src/page-setup.ts +222 -0
  432. package/src/scroll-shading.ts +18 -1
  433. package/src/shared-tree-builder.ts +263 -21
  434. package/src/signals.ts +15 -0
  435. package/src/source-view/theme.ts +11 -5
  436. package/src/style-classes.spec.ts +9 -8
  437. package/src/styles.generated.ts +1 -1
  438. package/src/tab-chip.ts +200 -0
  439. package/src/template-classes.ts +45 -0
  440. package/src/test.browser.mts +152 -0
@@ -0,0 +1,432 @@
1
+ // DOM-level tests for <gtk-stack>. The widget is four separable things and each gets
2
+ // its own describe: WHICH CHILD is visible (the guards in `set_visible_child`, where
3
+ // most of the surprising behaviour lives), the PAGE DESCRIPTOR (a GtkStackPage is a
4
+ // GObject, so its properties are attributes on the child), the TRANSITION TYPE
5
+ // (reduced motion, RTL, and the two-way types resolving to one-directional ones) and
6
+ // the NOTIFICATION contract.
7
+ import { describe, expect, it } from '@gjsify/unit';
8
+
9
+ import type { GtkStack } from './elements/gtk-stack.js';
10
+
11
+ interface Page {
12
+ name: string;
13
+ title?: string;
14
+ icon?: string;
15
+ hidden?: boolean;
16
+ attention?: boolean;
17
+ underline?: boolean;
18
+ body?: string;
19
+ }
20
+
21
+ /** A stack with its pages, `<gtk-stack>` already upgraded and rendered. */
22
+ function mount(pages: Page[] = [], attrs: Record<string, string> = {}): { el: GtkStack; host: HTMLElement } {
23
+ const host = document.createElement('div');
24
+ document.body.appendChild(host);
25
+ const el = document.createElement('gtk-stack') as GtkStack;
26
+ for (const [name, value] of Object.entries(attrs)) el.setAttribute(name, value);
27
+ for (const page of pages) {
28
+ const child = document.createElement('div');
29
+ if (page.title !== undefined) child.setAttribute('title', page.title);
30
+ if (page.icon !== undefined) child.setAttribute('icon-name', page.icon);
31
+ if (page.attention) child.setAttribute('needs-attention', '');
32
+ if (page.underline) child.setAttribute('use-underline', '');
33
+ if (page.hidden) child.setAttribute('hidden', '');
34
+ child.textContent = page.body ?? page.name;
35
+ el.appendChild(child);
36
+ child.setAttribute('name', page.name);
37
+ }
38
+ host.appendChild(el);
39
+ return { el, host };
40
+ }
41
+
42
+ /**
43
+ * A turn of the event loop.
44
+ *
45
+ * A page's own change reaches the stack through a MutationObserver — `add_page` connects
46
+ * the stack to the page's `notify::visible` (gtkstack.c:1771), and the browser's equivalent
47
+ * of a `notify` on someone else's attribute is the observer, which delivers in a
48
+ * microtask. GObject's notify is synchronous; this await is the one place the two differ,
49
+ * and it is why the three page-mutation tests below wait where the C test would not.
50
+ */
51
+ function settle(): Promise<void> {
52
+ return new Promise((resolve) => setTimeout(resolve, 0));
53
+ }
54
+
55
+ /** The children in DOM order, with `visible-page` marked, as the render pass sees them. */
56
+ function marks(el: GtkStack): string[] {
57
+ return (Array.from(el.children) as HTMLElement[]).map(
58
+ (child) => `${child.getAttribute('name')}${child.classList.contains('visible-page') ? ':visible' : ''}`,
59
+ );
60
+ }
61
+
62
+ export const GtkStackTest = async () => {
63
+ await describe('<gtk-stack> defaults', async () => {
64
+ await it('shows the first visible page and hides every other one', () => {
65
+ // gtkstack.c:1773-1775 — the first page added while nothing is visible becomes
66
+ // the visible one, and `:2947` the role.
67
+ const { el, host } = mount([
68
+ { name: 'a', title: 'Alpha' },
69
+ { name: 'b', title: 'Beta' },
70
+ ]);
71
+ expect(marks(el)).toStrictEqual(['a:visible', 'b']);
72
+ expect(el.visibleChildName).toBe('a');
73
+ expect(el.getAttribute('role')).toBe('group');
74
+ expect(el.transitionDuration).toBe(200);
75
+ expect(el.transitionType).toBe('none');
76
+ host.remove();
77
+ });
78
+
79
+ await it('is homogeneous on both axes by default and anisotropic on request', () => {
80
+ // gtkstack.c:981-995 — both specs default TRUE.
81
+ const { el, host } = mount([{ name: 'a' }]);
82
+ expect(el.hhomogeneous).toBe(true);
83
+ expect(el.vhomogeneous).toBe(true);
84
+ el.hhomogeneous = false;
85
+ expect(el.hhomogeneous).toBe(false);
86
+ // An absent attribute is C's TRUE, so it has to read back as true after removal.
87
+ el.hhomogeneous = true;
88
+ expect(el.getAttribute('hhomogeneous')).toBe('');
89
+ expect(el.hhomogeneous).toBe(true);
90
+ host.remove();
91
+ });
92
+
93
+ await it('an unknown transition-type nick reads as none, the GIR default', () => {
94
+ // gtkstack.c:1038-1044 — the enum's default member is NONE.
95
+ const { el, host } = mount([{ name: 'a' }], { 'transition-type': 'cube' });
96
+ expect(el.transitionType).toBe('none');
97
+ host.remove();
98
+ });
99
+ });
100
+
101
+ await describe('<gtk-stack> which child is visible', async () => {
102
+ await it('setting the name of a visible page makes it visible', () => {
103
+ const { el, host } = mount([
104
+ { name: 'a', title: 'Alpha' },
105
+ { name: 'b', title: 'Beta' },
106
+ ]);
107
+ el.setVisibleChildName('b');
108
+ expect(marks(el)).toStrictEqual(['a', 'b:visible']);
109
+ expect(el.visibleChildName).toBe('b');
110
+ host.remove();
111
+ });
112
+
113
+ await it('an unknown name changes nothing', () => {
114
+ // gtkstack.c:2323-2327 — `g_warning`, then return.
115
+ const { el, host } = mount([
116
+ { name: 'a', title: 'Alpha' },
117
+ { name: 'b', title: 'Beta' },
118
+ ]);
119
+ expect(el.setVisibleChildName('nope')).toBe(false);
120
+ expect(el.visibleChildName).toBe('a');
121
+ host.remove();
122
+ });
123
+
124
+ await it('naming a page that is not visible is a no-op, not a blank stack', () => {
125
+ // gtkstack.c:1591-1594 / :2329-2332 — the widget must be visible itself.
126
+ const { el, host } = mount([
127
+ { name: 'a', title: 'Alpha' },
128
+ { name: 'b', title: 'Beta', hidden: true },
129
+ ]);
130
+ expect(el.setVisibleChildName('b')).toBe(false);
131
+ expect(el.visibleChildName).toBe('a');
132
+ host.remove();
133
+ });
134
+
135
+ await it('hiding the visible page falls back to the first visible one', async () => {
136
+ // `set_visible_child (stack, NULL)` — the first-visible scan, gtkstack.c:1437.
137
+ const { el, host } = mount([
138
+ { name: 'a', title: 'Alpha' },
139
+ { name: 'b', title: 'Beta' },
140
+ ]);
141
+ (el.children[0] as HTMLElement).setAttribute('hidden', '');
142
+ await settle();
143
+ expect(el.visibleChildName).toBe('b');
144
+ host.remove();
145
+ });
146
+
147
+ await it('re-selecting the visible page is not a change', () => {
148
+ // gtkstack.c:1452-1453 — no notify, no transition.
149
+ const { el, host } = mount([
150
+ { name: 'a', title: 'Alpha' },
151
+ { name: 'b', title: 'Beta' },
152
+ ]);
153
+ const events: string[] = [];
154
+ el.addEventListener('notify::visible-child', () => events.push('child'));
155
+ expect(el.setVisibleChildName('a')).toBe(false);
156
+ expect(events).toStrictEqual([]);
157
+ host.remove();
158
+ });
159
+
160
+ await it('a page with no name is never matched, and reads as a NULL name', () => {
161
+ // gtkstack.c:2314 — `info->name != NULL &&`, and get_visible_child_name
162
+ // returns NULL for an unnamed visible page (gtkstack.c:2220-2223).
163
+ const { el, host } = mount([{ name: '', title: 'Nameless' }]);
164
+ expect(el.visibleChildName).toBe(null);
165
+ expect(el.pages[0].name).toBe('');
166
+ expect(el.setVisibleChildName('')).toBe(false);
167
+ host.remove();
168
+ });
169
+
170
+ await it('setVisibleChild refuses a child that is not in the stack', () => {
171
+ // gtkstack.c:2258-2266 — `g_warning` for a child of the wrong type.
172
+ const { el, host } = mount([{ name: 'a', title: 'Alpha' }]);
173
+ const stranger = document.createElement('div');
174
+ expect(el.setVisibleChild(stranger)).toBe(false);
175
+ expect(el.visibleChildName).toBe('a');
176
+ host.remove();
177
+ });
178
+
179
+ await it('addTitled names and titles the child, and addChild appends a bare one', () => {
180
+ // gtkstack.c:1644-1663, :1665-1685.
181
+ const { el, host } = mount();
182
+ const child = el.addTitled(document.createElement('div'), 'later', 'Later');
183
+ expect(child.getAttribute('name')).toBe('later');
184
+ expect(child.getAttribute('title')).toBe('Later');
185
+ // The first visible page added to an empty stack becomes visible (:1773).
186
+ expect(el.visibleChildName).toBe('later');
187
+ host.remove();
188
+ });
189
+ });
190
+
191
+ await describe('<gtk-stack> the page descriptor', async () => {
192
+ await it('reads the six GtkStackPage properties off the child', () => {
193
+ // gtkstack.c:499-573 — the GObject's properties are the child's attributes.
194
+ const { el, host } = mount([
195
+ { name: 'a', title: 'Alpha', icon: 'go-next-symbolic', attention: true, underline: true },
196
+ ]);
197
+ expect(el.pages).toStrictEqual([
198
+ {
199
+ name: 'a',
200
+ title: 'Alpha',
201
+ iconName: 'go-next-symbolic',
202
+ needsAttention: true,
203
+ useUnderline: true,
204
+ visible: true,
205
+ child: el.children[0],
206
+ },
207
+ ]);
208
+ host.remove();
209
+ });
210
+
211
+ await it('an absent title is null, never a fallback to the name', () => {
212
+ // rebuild_child builds no label at all when title AND icon-name are NULL
213
+ // (gtkstackswitcher.c:158-176) — so "no title" has to stay expressible.
214
+ const { el, host } = mount([{ name: 'a' }]);
215
+ expect(el.pages[0].title).toBe(null);
216
+ expect(el.pages[0].iconName).toBe(null);
217
+ host.remove();
218
+ });
219
+
220
+ await it('hidden is the page flag: the descriptor follows it', () => {
221
+ const { el, host } = mount([
222
+ { name: 'a', title: 'Alpha' },
223
+ { name: 'b', title: 'Beta', hidden: true },
224
+ ]);
225
+ expect(el.pages[1].visible).toBe(false);
226
+ host.remove();
227
+ });
228
+
229
+ await it('getChildByName and getPage answer in child order, null when absent', () => {
230
+ const { el, host } = mount([
231
+ { name: 'a', title: 'Alpha' },
232
+ { name: 'b', title: 'Beta' },
233
+ ]);
234
+ expect(el.getChildByName('b')).toBe(el.children[1]);
235
+ expect(el.getChildByName('nope')).toBe(null);
236
+ expect(el.getPage(el.children[0] as HTMLElement)?.name).toBe('a');
237
+ expect(el.getPage(document.createElement('div'))).toBe(null);
238
+ expect(el.isSelected(el.children[0] as HTMLElement)).toBe(true);
239
+ host.remove();
240
+ });
241
+
242
+ await it('renaming the visible page moves visible-child-name with it', async () => {
243
+ // gtkstack.c:3169-3171 — set_name re-notifies visible-child-name when the
244
+ // renamed page IS the visible one, because the selection did not move but the
245
+ // name it is addressed by did.
246
+ const { el, host } = mount([
247
+ { name: 'a', title: 'Alpha' },
248
+ { name: 'b', title: 'Beta' },
249
+ ]);
250
+ (el.children[0] as HTMLElement).setAttribute('name', 'renamed');
251
+ await settle();
252
+ expect(el.visibleChildName).toBe('renamed');
253
+ host.remove();
254
+ });
255
+
256
+ await it('a title change fires page-updated for the switcher to hear', async () => {
257
+ // `on_page_updated` binds the page's own `notify` (gtkstackswitcher.c:311-321).
258
+ const { el, host } = mount([{ name: 'a', title: 'Alpha' }]);
259
+ const updated: unknown[] = [];
260
+ el.addEventListener('page-updated', (e) => updated.push((e as CustomEvent).detail));
261
+ (el.children[0] as HTMLElement).setAttribute('title', 'Changed');
262
+ await settle();
263
+ expect(updated).toStrictEqual([{ child: el.children[0] }]);
264
+ expect(el.pages[0].title).toBe('Changed');
265
+ host.remove();
266
+ });
267
+ });
268
+
269
+ await describe('<gtk-stack> transitions', async () => {
270
+ await it('runs the transition and clears it when the duration is up', async () => {
271
+ const { el, host } = mount(
272
+ [
273
+ { name: 'a', title: 'Alpha' },
274
+ { name: 'b', title: 'Beta' },
275
+ ],
276
+ { 'transition-type': 'crossfade', 'transition-duration': '10' },
277
+ );
278
+ const events: string[] = [];
279
+ el.addEventListener('transition-start', () => events.push('start'));
280
+ el.addEventListener('transition-end', () => events.push('end'));
281
+ el.setVisibleChildName('b');
282
+ expect(el.transitionRunning).toBe(true);
283
+ expect(el.dataset.transitionType).toBe('crossfade');
284
+ expect((el.children[0] as HTMLElement).classList.contains('transitioning-out')).toBe(true);
285
+ expect((el.children[1] as HTMLElement).classList.contains('transitioning-in')).toBe(true);
286
+ await new Promise((resolve) => setTimeout(resolve, 40));
287
+ expect(el.transitionRunning).toBe(false);
288
+ expect(el.dataset.transitionType).toBe(undefined);
289
+ expect(events).toStrictEqual(['start', 'end']);
290
+ host.remove();
291
+ });
292
+
293
+ await it('transition-type none starts no transition at all', () => {
294
+ // gtkstack.c:1400-1403 — an effective type of NONE skips the tracker.
295
+ const { el, host } = mount([
296
+ { name: 'a', title: 'Alpha' },
297
+ { name: 'b', title: 'Beta' },
298
+ ]);
299
+ el.setVisibleChildName('b');
300
+ expect(el.transitionRunning).toBe(false);
301
+ expect(el.dataset.transitionType).toBe(undefined);
302
+ host.remove();
303
+ });
304
+
305
+ await it('a zero duration starts no transition, though the type is set', () => {
306
+ // gtkstack.c:1402 — `transition_duration != 0` gates the whole branch.
307
+ const { el, host } = mount(
308
+ [
309
+ { name: 'a', title: 'Alpha' },
310
+ { name: 'b', title: 'Beta' },
311
+ ],
312
+ { 'transition-type': 'slide-left', 'transition-duration': '0' },
313
+ );
314
+ el.setVisibleChildName('b');
315
+ expect(el.transitionRunning).toBe(false);
316
+ host.remove();
317
+ });
318
+
319
+ await it('a two-way type resolves to a one-directional one, by page order', () => {
320
+ // get_simple_transition_type (gtkstack.c:1162-1200): slide-left-right becomes
321
+ // slide-left when the new page was added LATER (`i_first` false) and
322
+ // slide-right when it was added EARLIER (`i_first` true).
323
+ const forward = mount(
324
+ [
325
+ { name: 'a', title: 'Alpha' },
326
+ { name: 'b', title: 'Beta' },
327
+ ],
328
+ { 'transition-type': 'slide-left-right', 'transition-duration': '50' },
329
+ );
330
+ forward.el.setVisibleChildName('b');
331
+ expect(forward.el.dataset.transitionType).toBe('slide-left');
332
+ forward.host.remove();
333
+
334
+ const backward = mount(
335
+ [
336
+ { name: 'a', title: 'Alpha' },
337
+ { name: 'b', title: 'Beta' },
338
+ ],
339
+ { 'transition-type': 'slide-left-right', 'transition-duration': '50' },
340
+ );
341
+ // Go out to `b` first, so the switch BACK to `a` is the one under test and
342
+ // `a` — the earlier page — is the incoming one.
343
+ backward.el.setVisibleChildName('b');
344
+ backward.el.setVisibleChildName('a');
345
+ expect(backward.el.dataset.transitionType).toBe('slide-right');
346
+ backward.host.remove();
347
+ });
348
+
349
+ await it('a two-way type with nothing to slide away from collapses to none', () => {
350
+ // gtkstack.c:1541-1545 — `child_info == NULL || last_visible_child == NULL`.
351
+ const { el, host } = mount(
352
+ [
353
+ { name: 'a', title: 'Alpha', hidden: true },
354
+ { name: 'b', title: 'Beta', hidden: true },
355
+ { name: 'c', title: 'Gamma' },
356
+ ],
357
+ { 'transition-type': 'slide-left-right', 'transition-duration': '50' },
358
+ );
359
+ // Nothing was visible, so the first page shown has no outgoing sibling.
360
+ el.setVisibleChildName('c');
361
+ expect(el.visibleChildName).toBe('c');
362
+ expect(el.transitionRunning).toBe(false);
363
+ host.remove();
364
+ });
365
+
366
+ await it('interpolate-size is an attribute, and does not change the type', () => {
367
+ const { el, host } = mount([
368
+ { name: 'a', title: 'Alpha' },
369
+ { name: 'b', title: 'Beta' },
370
+ ]);
371
+ expect(el.interpolateSize).toBe(false);
372
+ el.interpolateSize = true;
373
+ expect(el.hasAttribute('interpolate-size')).toBe(true);
374
+ host.remove();
375
+ });
376
+ });
377
+
378
+ await describe('<gtk-stack> notification', async () => {
379
+ await it('notifies both child properties on a real change, child first', async () => {
380
+ // gtkstack.c:1568-1570 — the order is the two g_object_notify calls.
381
+ const { el, host } = mount(
382
+ [
383
+ { name: 'a', title: 'Alpha' },
384
+ { name: 'b', title: 'Beta' },
385
+ ],
386
+ { 'transition-duration': '5' },
387
+ );
388
+ const events: string[] = [];
389
+ el.addEventListener('notify::visible-child', () => events.push('child'));
390
+ el.addEventListener('notify::visible-child-name', () => events.push('name'));
391
+ el.setVisibleChildName('b');
392
+ expect(events).toStrictEqual(['child', 'name']);
393
+ await new Promise((resolve) => setTimeout(resolve, 20));
394
+ host.remove();
395
+ });
396
+
397
+ await it('reports the parsed property, not the raw attribute', () => {
398
+ const { el, host } = mount([{ name: 'a', title: 'Alpha' }]);
399
+ const details: unknown[] = [];
400
+ el.addEventListener('notify::transition-duration', (e) => details.push((e as CustomEvent).detail));
401
+ el.transitionDuration = 320;
402
+ expect(details).toStrictEqual([{ 'transition-duration': 320 }]);
403
+ host.remove();
404
+ });
405
+
406
+ await it('an added page reports items-changed, a removed one too', async () => {
407
+ const { el, host } = mount([
408
+ { name: 'a', title: 'Alpha' },
409
+ { name: 'b', title: 'Beta' },
410
+ ]);
411
+ const events: unknown[] = [];
412
+ el.addEventListener('items-changed', (e) => events.push((e as CustomEvent).detail));
413
+ const third = document.createElement('div');
414
+ third.setAttribute('name', 'c');
415
+ el.appendChild(third);
416
+ await new Promise((resolve) => setTimeout(resolve, 0));
417
+ expect(events).toStrictEqual([{ position: 2, removed: 0, added: 1 }]);
418
+ host.remove();
419
+ });
420
+
421
+ await it('the visible page carries no aria-hidden and the others do', async () => {
422
+ // gtkstack.c:1610-1613 — GTK_ACCESSIBLE_STATE_HIDDEN on the PAGE.
423
+ const { el, host } = mount([
424
+ { name: 'a', title: 'Alpha' },
425
+ { name: 'b', title: 'Beta' },
426
+ ]);
427
+ expect((el.children[0] as HTMLElement).hasAttribute('aria-hidden')).toBe(false);
428
+ expect((el.children[1] as HTMLElement).getAttribute('aria-hidden')).toBe('true');
429
+ host.remove();
430
+ });
431
+ });
432
+ };
@@ -0,0 +1,189 @@
1
+ // DOM-level tests for `<gtk-text-view>`: the buffer's text, the Pango properties that reach
2
+ // a CSS mechanism (`wrap-mode`, `justification`, `monospace`, the four margins,
3
+ // `cursor-visible`) and `accepts-tab`, whose GTK default is the OPPOSITE of a browser's.
4
+ //
5
+ // The paragraph sppacings are not here: they are Pango's paragraph model, which a textarea
6
+ // has no counterpart for, and they are declared in `check-adwaita-element-properties.mjs`.
7
+
8
+ import { describe, expect, it } from '@gjsify/unit';
9
+
10
+ import type { GtkTextView } from './elements/gtk-text-view.js';
11
+
12
+ function mount(text = ''): GtkTextView {
13
+ const el = document.createElement('gtk-text-view') as GtkTextView;
14
+ el.textContent = text;
15
+ document.body.appendChild(el);
16
+ return el;
17
+ }
18
+
19
+ function unmountAll(): void {
20
+ for (const el of Array.from(document.querySelectorAll('gtk-text-view'))) el.remove();
21
+ }
22
+
23
+ /**
24
+ * A Tab the element has to intercept: a synthetic keydown is all a test can produce. The
25
+ * caret is placed explicitly, because where a fresh control leaves it is the engine's
26
+ * choice and the row is about the INSERTION.
27
+ */
28
+ function pressTab(textarea: HTMLTextAreaElement, at = 0): KeyboardEvent {
29
+ textarea.setSelectionRange(at, at);
30
+ const event = new KeyboardEvent('keydown', { key: 'Tab', bubbles: true, cancelable: true });
31
+ textarea.dispatchEvent(event);
32
+ return event;
33
+ }
34
+
35
+ export const GtkTextViewTest = async () => {
36
+ await describe('<gtk-text-view> the buffer', async () => {
37
+ await it('takes its text from the light DOM, which is where a buffer goes', () => {
38
+ const el = mount('one\ntwo');
39
+ expect(el.text).toBe('one\ntwo');
40
+ expect(el.textarea.value).toBe('one\ntwo');
41
+ unmountAll();
42
+ });
43
+
44
+ await it('lets an explicit `text` attribute win over it', () => {
45
+ const el = mount('light dom');
46
+ el.setAttribute('text', 'from the attribute');
47
+ unmountAll();
48
+ const second = document.createElement('gtk-text-view') as GtkTextView;
49
+ second.textContent = 'light dom';
50
+ second.setAttribute('text', 'from the attribute');
51
+ document.body.appendChild(second);
52
+ expect(second.text).toBe('from the attribute');
53
+ second.remove();
54
+ });
55
+
56
+ await it("re-emits the buffer's `changed` on an edit", () => {
57
+ const el = mount('a');
58
+ const seen: unknown[] = [];
59
+ el.addEventListener('changed', (event) => seen.push((event as CustomEvent).detail));
60
+ el.textarea.value = 'ab';
61
+ el.textarea.dispatchEvent(new Event('input', { bubbles: true }));
62
+ expect(seen).toStrictEqual([{ text: 'ab' }]);
63
+ unmountAll();
64
+ });
65
+ });
66
+
67
+ await describe('<gtk-text-view> wrap mode', async () => {
68
+ await it("defaults to Pango's `none`, so lines do not wrap", () => {
69
+ const el = mount();
70
+ expect(el.wrapMode).toBe('none');
71
+ expect(getComputedStyle(el.textarea).whiteSpace).toBe('pre');
72
+ unmountAll();
73
+ });
74
+
75
+ await it('maps each Pango nick onto the CSS that breaks lines the same way', () => {
76
+ const el = mount();
77
+ el.wrapMode = 'word';
78
+ expect(getComputedStyle(el.textarea).whiteSpace).toBe('pre-wrap');
79
+ expect(getComputedStyle(el.textarea).wordBreak).toBe('normal');
80
+ el.wrapMode = 'char';
81
+ expect(getComputedStyle(el.textarea).wordBreak).toBe('break-all');
82
+ el.wrapMode = 'word-char';
83
+ expect(getComputedStyle(el.textarea).overflowWrap).toBe('anywhere');
84
+ unmountAll();
85
+ });
86
+
87
+ await it('reads an unknown nick as the pspec default, `none`', () => {
88
+ const el = mount();
89
+ el.setAttribute('wrap-mode', 'diagonal');
90
+ expect(el.wrapMode).toBe('none');
91
+ unmountAll();
92
+ });
93
+ });
94
+
95
+ await describe('<gtk-text-view> justification and margins', async () => {
96
+ await it("reads Pango's justification as `text-align`, `fill` included", () => {
97
+ const el = mount();
98
+ expect(el.justification).toBe('left');
99
+ expect(getComputedStyle(el.textarea).textAlign).toBe('start');
100
+ el.justification = 'fill';
101
+ expect(getComputedStyle(el.textarea).textAlign).toBe('justify');
102
+ el.justification = 'center';
103
+ expect(getComputedStyle(el.textarea).textAlign).toBe('center');
104
+ unmountAll();
105
+ });
106
+
107
+ await it('turns the four margins into padding the theme ADDS to, as GTK says', () => {
108
+ const el = mount();
109
+ expect(getComputedStyle(el.textarea).paddingTop).toBe('6px');
110
+ el.topMargin = 12;
111
+ el.rightMargin = 4;
112
+ el.bottomMargin = 2;
113
+ el.leftMargin = 8;
114
+ const style = getComputedStyle(el.textarea);
115
+ expect(style.paddingTop).toBe('18px');
116
+ expect(style.paddingRight).toBe('10px');
117
+ expect(style.paddingBottom).toBe('8px');
118
+ expect(style.paddingLeft).toBe('14px');
119
+ unmountAll();
120
+ });
121
+
122
+ await it("floors a margin at zero, like the pspec's own minimum", () => {
123
+ const el = mount();
124
+ el.topMargin = -20;
125
+ expect(el.topMargin).toBe(0);
126
+ unmountAll();
127
+ });
128
+ });
129
+
130
+ await describe('<gtk-text-view> monospace', async () => {
131
+ await it("is libadwaita's own `.monospace` class, reaching the inner control", () => {
132
+ const el = mount();
133
+ const plain = getComputedStyle(el.textarea).fontFamily;
134
+ el.monospace = true;
135
+ expect(el.classList.contains('monospace')).toBe(true);
136
+ expect(getComputedStyle(el.textarea).fontFamily).not.toBe(plain);
137
+ unmountAll();
138
+ });
139
+ });
140
+
141
+ await describe('<gtk-text-view> editable and the cursor', async () => {
142
+ await it('is editable with a visible cursor by default', () => {
143
+ const el = mount();
144
+ expect(el.editable).toBe(true);
145
+ expect(el.cursorVisible).toBe(true);
146
+ expect(el.textarea.readOnly).toBe(false);
147
+ expect(getComputedStyle(el.textarea).caretColor).not.toBe('transparent');
148
+ unmountAll();
149
+ });
150
+
151
+ await it('takes both from a VALUE, because both pspecs default TRUE', () => {
152
+ const el = mount();
153
+ el.setAttribute('editable', 'false');
154
+ el.setAttribute('cursor-visible', 'false');
155
+ expect(el.editable).toBe(false);
156
+ expect(el.cursorVisible).toBe(false);
157
+ expect(el.textarea.readOnly).toBe(true);
158
+ // `caret-color: transparent` computes to `rgba(0, 0, 0, 0)` on some engines and
159
+ // to the keyword on others, so the row compares against a probe carrying the same
160
+ // declaration rather than naming either spelling.
161
+ const probe = document.createElement('textarea');
162
+ probe.style.caretColor = 'transparent';
163
+ document.body.appendChild(probe);
164
+ expect(getComputedStyle(el.textarea).caretColor).toBe(getComputedStyle(probe).caretColor);
165
+ probe.remove();
166
+ unmountAll();
167
+ });
168
+ });
169
+
170
+ await describe('<gtk-text-view> accepts tab', async () => {
171
+ await it('defaults TRUE, so Tab inserts a tab character and focus stays', () => {
172
+ const el = mount('ab');
173
+ expect(el.acceptsTab).toBe(true);
174
+ const event = pressTab(el.textarea, 1);
175
+ expect(event.defaultPrevented).toBe(true);
176
+ expect(el.text).toBe('a\tb');
177
+ unmountAll();
178
+ });
179
+
180
+ await it('gives the browser its own Tab back when it is FALSE', () => {
181
+ const el = mount('ab');
182
+ el.acceptsTab = false;
183
+ const event = pressTab(el.textarea);
184
+ expect(event.defaultPrevented).toBe(false);
185
+ expect(el.text).toBe('ab');
186
+ unmountAll();
187
+ });
188
+ });
189
+ };