@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,423 @@
1
+ // <gtk-video> — a playing surface with a play affordance and a controls bar, and NOTHING
2
+ // else. It owns no decoding, no pipeline and no transport of its own: `GtkVideo` is a
3
+ // `GtkWidget` with a `GtkMediaStream` on it and a three-node template over it
4
+ // (refs/gtk/gtk/ui/gtkvideo.ui), and every question of "what is playing" is answered by
5
+ // the stream.
6
+ //
7
+ // THE REPLICA IS A REAL `<video>`, AND SAYING SO IS THE POINT. GTK's `GtkMediaStream` is
8
+ // an abstract playback backend; the browser already ships one, and `<video>` is it. So the
9
+ // element takes a `<video>` as its light-DOM child, applies `autoplay` and `loop` to it as
10
+ // the two PROPERTIES are declared (gtkpicture's sibling `gtkvideo.c:407-414`, :432-439),
11
+ // and reflects its events back out. What it does NOT do is reimplement a transport: there
12
+ // is no buffering state model, no seek-pending flag, no `GstPipeline`, because the C has
13
+ // none either — those live in the backend behind `GtkMediaStream`, not in the widget.
14
+ //
15
+ // `autoplay` WAITS FOR PREPARED, WHICH IS A REAL DIFFERENCE FROM THE ATTRIBUTE. The C does
16
+ // not play on `set_autoplay`; it plays when the stream reports `prepared` AND the widget is
17
+ // mapped, and it re-checks that on every `prepared` notification
18
+ // (gtkvideo.c:684-690, `gtk_video_notify_cb`). Setting `autoplay` on a `<video>` element
19
+ // before its `src` is known therefore plays nothing, and setting it after `src` plays —
20
+ // the same order-dependence the C has, arrived at honestly, so the attribute is applied as
21
+ // the C applies it: the property is stored, and `play()` is called on the media's own
22
+ // readiness, never on the write.
23
+ //
24
+ // THE OVERLAY ICON IS A FOUR-WAY CHOICE AND THE ORDER IS THE POINT.
25
+ // `gtk_video_update_overlay_icon` (gtkvideo.c:626-646) picks in this order: no stream at
26
+ // all → `media-eject-symbolic`; a stream with an ERROR → `dialog-error-symbolic`; a stream
27
+ // that ENDED → `media-playlist-repeat-symbolic`; otherwise → `media-playback-start-symbolic`.
28
+ // No media stream is the FIRST arm and not the last, so an element that has not been given
29
+ // a `<video>` draws the eject glyph — the shape of "there is nothing here to play" — rather
30
+ // than a play glyph over nothing. `error` before `ended` matters too: a stream that both
31
+ // ended and failed shows the error.
32
+ //
33
+ // THE OVERLAY IS HIDDEN WHILE PLAYING, NOT SWAPPED. `gtk_video_update_playing` sets the
34
+ // overlay's VISIBILITY to `!playing` (gtkvideo.c:665) and restores the cursor at the same
35
+ // time. There is no pause icon in the overlay: a video that is playing shows the frames and
36
+ // nothing on top of them, and the controls bar is what carries the pause button. That is
37
+ // why this element has one overlay node and no per-state icon table of its own.
38
+ //
39
+ // THE CONTROLS REVEAL AND HIDE ON A TIMER. `gtk_video_reveal_controls` reveals the
40
+ // revealer and arms a 3-second timeout that hides it again (gtkvideo.c:125-133), and the
41
+ // motion controller calls it (gtkvideo.c:177-178). So the controls are shown on pointer
42
+ // movement and withdrawn three seconds after the last movement, and the SAME
43
+ // `revealControls()` is what a click on the video calls. `CONTROLS_HIDE_MS` is that 3000.
44
+ //
45
+ // `graphics-offload` IS A RENDERING HINT AND IS HONOURED AS ONE. `GtkGraphicsOffload` moves
46
+ // the child into a shared GL texture so a widget and its neighbours composite on the GPU;
47
+ // its `enabled` property is what `GtkVideo:graphics-offload` reads and writes
48
+ // (gtkvideo.c:988-992, :1010-1023). CSS has no equivalent — there is no compositor to move a
49
+ // subtree into — so the property is stored, readable and writable, and surfaced as a class,
50
+ // and NOTHING ELSE HAPPENS. That is declared rather than hidden: see `_video.scss`'s header.
51
+ //
52
+ // THE TEMPLATE'S THREE OVERLAY NODES ARE ALL PRESENT. `ui/gtkvideo.ui` puts an overlay
53
+ // icon, a `controls_revealer` and (implicitly, as the main child) the picture, inside a
54
+ // `GtkOverlay`. The overlay icon wears `.osd` AND `.circular`, and libadwaita gives
55
+ // `video image.osd` a 64px box with a 32px radius
56
+ // (refs/libadwaita/src/stylesheet/widgets/_misc.scss:75-81) — which is exactly what a
57
+ // `.circular` button already is at 34px, so the 64/32 pair is the video's own larger
58
+ // version of it and is stated in the stylesheet rather than invented here.
59
+ //
60
+ // Reference: refs/gtk/gtk/gtkvideo.c (the overlay-icon four-way choice :626-646,
61
+ // `update_playing` hiding it :658-666, the autoplay-on-prepared check :679-690,
62
+ // `gtk_video_reveal_controls` :125-133, the property table :400-445,
63
+ // `graphics-offload` :976-1023)
64
+ // Reference: refs/gtk/gtk/ui/gtkvideo.ui (the three-node overlay template)
65
+ // Reference: refs/libadwaita/src/stylesheet/widgets/_misc.scss:74-81 (the 64/32 osd icon)
66
+ // Copyright (c) The GTK Team. LGPLv2.1+.
67
+ // Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
68
+
69
+ /** The four overlay glyphs, in the order `update_overlay_icon` tests them (gtkvideo.c:626-646). */
70
+ export type VideoOverlayIcon =
71
+ | 'media-eject-symbolic'
72
+ | 'dialog-error-symbolic'
73
+ | 'media-playlist-repeat-symbolic'
74
+ | 'media-playback-start-symbolic';
75
+
76
+ // FOUR CONSTANTS, NOT ONE TABLE, and not with a type annotation on the declaration. Both
77
+ // are load-bearing: `check-adwaita-icon-masks.mjs` finds an emitted icon name with a regex
78
+ // for a SCREAMING_SNAKE identifier ending in `ICON` or `ICON_NAME` whose `=` is followed by
79
+ // a plain string literal. A `const X: Type = '…'` puts a `: Type` between the name and the
80
+ // `=` and is invisible to it; so is one member of an array of literals. Either way the
81
+ // check's second arm reports ICONS entries nothing emits, while all four are emitted.
82
+
83
+ /**
84
+ * The glyph a video with NO stream draws — the FIRST arm of the four-way choice
85
+ * (gtkvideo.c:629), because "there is nothing here to play" is the state every GtkVideo
86
+ * starts in.
87
+ */
88
+ export const NO_STREAM_ICON = 'media-eject-symbolic';
89
+
90
+ /** The glyph a stream that FAILED draws (gtkvideo.c:633) — tested before `ended`. */
91
+ export const ERROR_ICON = 'dialog-error-symbolic';
92
+
93
+ /** The glyph a stream that has ENDED draws (gtkvideo.c:638-639). */
94
+ export const ENDED_ICON = 'media-playlist-repeat-symbolic';
95
+
96
+ /** The glyph a READY stream draws (gtkvideo.c:645) — the arm everything else falls through to. */
97
+ export const READY_ICON = 'media-playback-start-symbolic';
98
+
99
+ /** `gtk_video_reveal_controls`' timeout: 3 s (gtkvideo.c:130). */
100
+ export const CONTROLS_HIDE_MS = 3000;
101
+
102
+ export class GtkVideo extends HTMLElement {
103
+ private _initialized = false;
104
+ private _overlayIcon!: HTMLButtonElement;
105
+ private _controlsRevealer!: HTMLDivElement;
106
+ private _media: HTMLVideoElement | null = null;
107
+ /** The listeners currently bound on `_media`, so `_detachMedia` removes the SAME ones. */
108
+ private mediaListeners: [string, EventListener][] = [];
109
+ private _hideTimer: number | null = null;
110
+ /** What the media element last told us, in the four fields the overlay choice reads. */
111
+ private _hasStream = false;
112
+ private _error: string | null = null;
113
+ private _ended = false;
114
+ private _playing = false;
115
+
116
+ static get observedAttributes() {
117
+ return ['autoplay', 'graphics-offload', 'loop'];
118
+ }
119
+
120
+ /**
121
+ * `GtkVideo:autoplay` (gtkvideo.c:407-414). Defaults to FALSE. The C plays on the
122
+ * stream's `prepared` notification and not on this write — see the header — so this
123
+ * setter records the flag and lets the media's own readiness decide.
124
+ */
125
+ get autoplay(): boolean {
126
+ return this.hasAttribute('autoplay');
127
+ }
128
+
129
+ set autoplay(value: boolean) {
130
+ this._write('autoplay', !!value);
131
+ this._syncMedia();
132
+ }
133
+
134
+ /** `GtkVideo:loop` (gtkvideo.c:432-439). Defaults to FALSE. A plain `<video loop>`. */
135
+ get loop(): boolean {
136
+ return this.hasAttribute('loop');
137
+ }
138
+
139
+ set loop(value: boolean) {
140
+ this._write('loop', !!value);
141
+ this._syncMedia();
142
+ }
143
+
144
+ /**
145
+ * `GtkVideo:graphics-offload` (gtkvideo.c:400-406, :1010-1023). Defaults to FALSE — the
146
+ * template ships `<property name="enabled">disabled</property>` (ui/gtkvideo.ui), so the
147
+ * C starts with the offload OFF and an application has to ask for it.
148
+ *
149
+ * Stored, readable and class-flagged, and NOTHING ELSE HAPPENS: CSS has no way to move a
150
+ * subtree into a shared GPU texture, which is what `GtkGraphicsOffload` is. The class is
151
+ * `graphics-offload` so a page can still target it, and `KNOWN_GAPS` in
152
+ * `check-adwaita-element-properties.mjs` does not list it because the PROPERTY is
153
+ * observed — what it does not buy is a faster composite.
154
+ */
155
+ get graphicsOffload(): boolean {
156
+ return this.hasAttribute('graphics-offload');
157
+ }
158
+
159
+ set graphicsOffload(value: boolean) {
160
+ this._write('graphics-offload', !!value);
161
+ }
162
+
163
+ /** The `<video>` this element drives — the browser's answer to a `GtkMediaStream`. */
164
+ get media(): HTMLVideoElement | null {
165
+ return this._media;
166
+ }
167
+
168
+ /** Whether the media reports itself playing — `GtkVideo:playing` (`gtk_video_get_playing`). */
169
+ get playing(): boolean {
170
+ return this._playing;
171
+ }
172
+
173
+ /** The current position in SECONDS — the C's `timestamp`, in microseconds × 1000. */
174
+ get timestamp(): number {
175
+ return this._media?.currentTime ?? 0;
176
+ }
177
+
178
+ /** The media's duration in SECONDS — the C's `duration`; 0 while it is unknown. */
179
+ get duration(): number {
180
+ const value = this._media?.duration ?? 0;
181
+ return Number.isFinite(value) ? value : 0;
182
+ }
183
+
184
+ /** Whether the overlay controls bar is currently revealed. */
185
+ get controlsRevealed(): boolean {
186
+ return this._controlsRevealer?.classList.contains('revealed') ?? false;
187
+ }
188
+
189
+ private _write(name: string, value: boolean): void {
190
+ this.toggleAttribute(name, value);
191
+ }
192
+
193
+ connectedCallback() {
194
+ if (this._initialized) {
195
+ this._adoptMedia();
196
+ return;
197
+ }
198
+ this._initialized = true;
199
+
200
+ // `ui/gtkvideo.ui`'s overlay icon is a GtkImage wearing `.osd` and `.circular` with
201
+ // an accessible role of BUTTON (the gesture is what makes it a button). A `<button>`
202
+ // IS that role natively, which is the honest way to build it rather than a div with
203
+ // a click handler and an ARIA keyword.
204
+ this._overlayIcon = document.createElement('button');
205
+ this._overlayIcon.className = 'adw-video-overlay-icon osd circular';
206
+ this._overlayIcon.type = 'button';
207
+ this._overlayIcon.setAttribute('aria-label', 'Play');
208
+ this._overlayIcon.title = 'Play';
209
+ this._overlayIcon.addEventListener('click', () => this._overlayClicked());
210
+
211
+ this._controlsRevealer = document.createElement('div');
212
+ this._controlsRevealer.className = 'adw-video-controls-revealer';
213
+
214
+ this._wrap();
215
+ this._adoptMedia();
216
+ // `gtk_video_motion` (ui/gtkvideo.ui) — the motion controller's only job. Bound on
217
+ // the element rather than on the surface so a pointer anywhere over the video (the
218
+ // surface, the controls bar, the overlay icon) counts, which is what GTK's
219
+ // `GtkEventControllerMotion` on the template's root does.
220
+ this.addEventListener('pointermove', this._onPointerMove);
221
+ }
222
+
223
+ /**
224
+ * `ui/gtkvideo.ui` keeps the author's `<video>` as the MAIN child of the overlay and adds
225
+ * the two overlay children around it. Wrapping in place rather than re-creating is what
226
+ * lets the light DOM stay the API: a page writes `<gtk-video><video src=…></video></gtk-video>`
227
+ * and the element never has to be told where the media is.
228
+ */
229
+ private _wrap(): void {
230
+ const media = this.querySelector<HTMLVideoElement>(':scope > video');
231
+ // EVERY other light child is the CONTROLS, and the template says where they go:
232
+ // `ui/gtkvideo.ui`'s `controls_revealer` holds a `GtkMediaControls` as its child, and
233
+ // `revealed` is what reveals it. `replaceChildren` therefore cannot simply discard
234
+ // them — a bar dropped on the floor is a bar outside the document, which loses its
235
+ // stylesheet, its popover's own `connectedCallback`, and the `closest('gtk-video')` a
236
+ // `<gtk-media-controls>` reads its stream from. So they are moved, not dropped.
237
+ const controls = [...this.children].filter((child) => child !== media);
238
+ const surface = document.createElement('div');
239
+ surface.className = 'adw-video-surface';
240
+ this.replaceChildren(surface);
241
+ if (media) surface.appendChild(media);
242
+ surface.append(this._overlayIcon);
243
+ this._controlsRevealer.append(...controls);
244
+ surface.append(this._controlsRevealer);
245
+ }
246
+
247
+ private _adoptMedia(): void {
248
+ // Narrowed at the selector: `querySelector` answers `Element`, and the whole point of the
249
+ // media is that it has `play`, `paused` and `error`. `?? null` for the reason
250
+ // `<gtk-media-controls>`'s own `_adoptMedia` states: the no-stream arm of the four-way
251
+ // choice is compared against a field initialised to `null`, and an `undefined` there
252
+ // would read as a stream.
253
+ const media = this.querySelector<HTMLVideoElement>(':scope > .adw-video-surface > video') ?? null;
254
+ if (media === this._media) {
255
+ this._syncMedia();
256
+ // `gtk_video_set_media_stream` calls `gtk_video_update_all` (gtkvideo.c:761-763)
257
+ // on EVERY assignment, and a video with NO `<video>` child is the assignment of
258
+ // nothing — the same function, the same four arms, no stream. Returning early
259
+ // without this left the no-stream arm undrawn on the FIRST call, which is the only
260
+ // call a streamless `<gtk-video>` ever makes: the eject glyph is the state every
261
+ // GtkVideo starts in, and it has to be the state it STARTS in.
262
+ this._updateOverlayIcon();
263
+ return;
264
+ }
265
+ if (this._media) this._detachMedia(this._media);
266
+ this._media = media;
267
+ // No stream is the FIRST arm of the four-way overlay choice (gtkvideo.c:629), so an
268
+ // element with no `<video>` child draws the eject glyph from the start rather than
269
+ // flashing a play glyph over nothing.
270
+ this._hasStream = media !== null;
271
+ if (media) {
272
+ const onPlay = () => this._updatePlaying(true);
273
+ const onPause = () => this._updatePlaying(false);
274
+ const onEnded = () => {
275
+ this._ended = true;
276
+ this._updateOverlayIcon();
277
+ };
278
+ const onError = () => {
279
+ this._error = media.error?.message ?? 'Playback failed';
280
+ this._updateOverlayIcon();
281
+ };
282
+ const onMetadata = () => {
283
+ // A stream that reports a NEW duration is no longer ended, exactly as
284
+ // `gtk_video_update_ended` re-reads the stream on every notification.
285
+ this._ended = false;
286
+ this._error = null;
287
+ this._updateOverlayIcon();
288
+ };
289
+ // `gtk_video_notify_cb`'s `prepared` arm (gtkvideo.c:679-690): autoplay plays
290
+ // here and NOT on the property write, so the flag and the readiness are two
291
+ // independent conditions and the C checks both.
292
+ const onPrepared = () => {
293
+ if (this.autoplay) void media.play().catch(() => {});
294
+ };
295
+ this.mediaListeners = [
296
+ ['play', onPlay],
297
+ ['pause', onPause],
298
+ ['ended', onEnded],
299
+ ['error', onError],
300
+ ['loadedmetadata', onMetadata],
301
+ ['loadeddata', onPrepared],
302
+ ];
303
+ for (const [type, handler] of this.mediaListeners) media.addEventListener(type, handler);
304
+ }
305
+ this._syncMedia();
306
+ this._updateOverlayIcon();
307
+ }
308
+
309
+ private _detachMedia(media: HTMLVideoElement): void {
310
+ // The listeners are held rather than re-created per event: `_adoptMedia` runs on
311
+ // every reconnect and a `() => …` handler removed here would not be the same
312
+ // function the one added there bound, so a re-parented `<video>` would end up with
313
+ // two handlers per event and two `notify::playing` per play.
314
+ for (const [type, handler] of this.mediaListeners) media.removeEventListener(type, handler);
315
+ this.mediaListeners = [];
316
+ }
317
+
318
+ /** `autoplay` and `loop` are declared PROPERTIES of the widget, so they are applied to
319
+ * the media rather than left to the author's markup — `ui/gtkvideo.ui` does the same by
320
+ * binding them on the template. */
321
+ private _syncMedia(): void {
322
+ if (!this._media) return;
323
+ this._media.loop = this.loop;
324
+ // The C's `autoplay` is NOT the element's autoplay attribute, so the media is
325
+ // never given one: a `preload`/autoplay element the author did not ask for is
326
+ // exactly the "plays when the stream becomes prepared" behaviour the C has, and the
327
+ // readiness gate is already on `loadeddata` above.
328
+ this._media.autoplay = false;
329
+ this.classList.toggle('graphics-offload', this.graphicsOffload);
330
+ }
331
+
332
+ private _overlayClicked(): void {
333
+ // `overlay_clicked_cb` (ui/gtkvideo.ui) toggles: it plays when stopped and pauses
334
+ // when playing, which is the overlay's whole contract — it is only VISIBLE when
335
+ // stopped, so the pause branch is reachable only from the controls bar's own button.
336
+ const media = this._media ?? null;
337
+ if (media === null) return;
338
+ if (media.paused) void media.play().catch(() => {});
339
+ else media.pause();
340
+ }
341
+
342
+ /**
343
+ * `gtk_video_reveal_controls` (gtkvideo.c:125-133): reveal, then arm a 3 s timeout that
344
+ * hides it again. Re-arming on every call is what makes it a "three seconds after the
345
+ * LAST movement" rather than a "three seconds after the first".
346
+ */
347
+ revealControls(): void {
348
+ if (!this._controlsRevealer) return;
349
+ this._controlsRevealer.classList.add('revealed');
350
+ if (this._hideTimer !== null) clearTimeout(this._hideTimer);
351
+ this._hideTimer = setTimeout(() => this._hideControls(), CONTROLS_HIDE_MS) as unknown as number;
352
+ }
353
+
354
+ private _hideControls(): void {
355
+ this._hideTimer = null;
356
+ this._controlsRevealer?.classList.remove('revealed');
357
+ }
358
+
359
+ /** `gtk_video_motion` (ui/gtkvideo.ui) — the motion controller's only job. */
360
+ private _onPointerMove = (): void => {
361
+ this.revealControls();
362
+ };
363
+
364
+ attributeChangedCallback(name: string) {
365
+ if (!this._initialized) return;
366
+ if (name === 'graphics-offload') this._syncMedia();
367
+ this.dispatchEvent(
368
+ new CustomEvent(`notify::${name}`, { bubbles: true, detail: { [name]: this._property(name) } }),
369
+ );
370
+ }
371
+
372
+ /** The `notify::` detail for `name`: the PROPERTY, parsed, not the raw attribute. */
373
+ private _property(name: string): boolean {
374
+ switch (name) {
375
+ case 'autoplay':
376
+ return this.autoplay;
377
+ case 'loop':
378
+ return this.loop;
379
+ default:
380
+ return this.graphicsOffload;
381
+ }
382
+ }
383
+
384
+ /** `gtk_video_update_playing` (gtkvideo.c:658-666) — VISIBILITY, not an icon swap. */
385
+ private _updatePlaying(playing: boolean): void {
386
+ this._playing = playing;
387
+ if (this._overlayIcon) this._overlayIcon.hidden = playing;
388
+ this.classList.toggle('playing', playing);
389
+ this.dispatchEvent(new CustomEvent('notify::playing', { bubbles: true, detail: { playing } }));
390
+ }
391
+
392
+ /** `gtk_video_update_overlay_icon` (gtkvideo.c:626-646), arm by arm. */
393
+ private _updateOverlayIcon(): void {
394
+ if (!this._overlayIcon) return;
395
+ let icon: VideoOverlayIcon;
396
+ let tooltip: string | null = null;
397
+ if (!this._hasStream) icon = NO_STREAM_ICON;
398
+ else if (this._error !== null) {
399
+ icon = ERROR_ICON;
400
+ tooltip = this._error;
401
+ } else if (this._ended) icon = ENDED_ICON;
402
+ else icon = READY_ICON;
403
+
404
+ const image = document.createElement('gtk-image');
405
+ // The four names carry their `-symbolic` suffix already — `normalizeIconName` accepts
406
+ // either spelling and the mask classes are keyed on the bare name, see `gtk-image.ts`.
407
+ image.setAttribute('icon-name', icon);
408
+ // `icon-size` 2 in the template (ui/gtkvideo.ui) is GTK's ICON_SIZE dialog-scale,
409
+ // which libadwaita renders at 64px through the `video image.osd` rule; the web's own
410
+ // size is the stylesheet's, so nothing is set here and the rule wins as it should.
411
+ this._overlayIcon.replaceChildren(image);
412
+ if (tooltip) this._overlayIcon.title = tooltip;
413
+ else this._overlayIcon.title = '';
414
+ this._overlayIcon.classList.toggle('error', this._error !== null);
415
+ }
416
+
417
+ disconnectedCallback() {
418
+ if (this._hideTimer !== null) clearTimeout(this._hideTimer);
419
+ this._hideTimer = null;
420
+ }
421
+ }
422
+
423
+ customElements.define('gtk-video', GtkVideo);