@gjsify/adwaita-web 0.64.1 → 0.64.2-next.254
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.
- package/README.md +22 -88
- package/dist/adwaita-web.css +91 -12
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/accessible.d.ts +8 -0
- package/lib/types/application.d.ts +1 -1
- package/lib/types/child-slot.spec.d.ts +1 -0
- package/lib/types/compute-expand.d.ts +5 -0
- package/lib/types/compute-expand.spec.d.ts +1 -0
- package/lib/types/container-fill.spec.d.ts +1 -0
- package/lib/types/elements/adw-about-dialog.d.ts +28 -1
- package/lib/types/elements/adw-action-row.d.ts +2 -1
- package/lib/types/elements/adw-alert-dialog.d.ts +80 -19
- package/lib/types/elements/adw-avatar.d.ts +2 -1
- package/lib/types/elements/adw-banner.d.ts +2 -1
- package/lib/types/elements/adw-bin.d.ts +2 -1
- package/lib/types/elements/adw-bottom-sheet.d.ts +5 -4
- package/lib/types/elements/adw-breakpoint-bin.d.ts +2 -1
- package/lib/types/elements/adw-button-content.d.ts +2 -1
- package/lib/types/elements/adw-button-row.d.ts +2 -1
- package/lib/types/elements/adw-card.d.ts +2 -1
- package/lib/types/elements/adw-carousel.d.ts +20 -3
- package/lib/types/elements/adw-clamp-scrollable.d.ts +2 -1
- package/lib/types/elements/adw-clamp.d.ts +2 -1
- package/lib/types/elements/adw-combo-row.d.ts +6 -1
- package/lib/types/elements/adw-data-grid.d.ts +2 -1
- package/lib/types/elements/adw-dialog.d.ts +2 -1
- package/lib/types/elements/adw-entry-row.d.ts +2 -1
- package/lib/types/elements/adw-expander-row.d.ts +2 -1
- package/lib/types/elements/adw-header-bar.d.ts +2 -1
- package/lib/types/elements/adw-inline-view-switcher.d.ts +3 -2
- package/lib/types/elements/adw-layout-slot.d.ts +2 -1
- package/lib/types/elements/adw-multi-layout-view.d.ts +2 -1
- package/lib/types/elements/adw-navigation-split-view.d.ts +2 -1
- package/lib/types/elements/adw-navigation-view.d.ts +3 -2
- package/lib/types/elements/adw-overlay-split-view.d.ts +2 -1
- package/lib/types/elements/adw-preferences-dialog.d.ts +5 -4
- package/lib/types/elements/adw-preferences-group.d.ts +2 -1
- package/lib/types/elements/adw-preferences-row.d.ts +2 -1
- package/lib/types/elements/adw-shortcut-label.d.ts +2 -1
- package/lib/types/elements/adw-shortcuts-item.d.ts +2 -1
- package/lib/types/elements/adw-shortcuts-section.d.ts +2 -1
- package/lib/types/elements/adw-sidebar.d.ts +4 -3
- package/lib/types/elements/adw-spin-row.d.ts +2 -1
- package/lib/types/elements/adw-spinner.d.ts +2 -1
- package/lib/types/elements/adw-split-button.d.ts +2 -1
- package/lib/types/elements/adw-status-page.d.ts +2 -1
- package/lib/types/elements/adw-switch-row.d.ts +4 -1
- package/lib/types/elements/adw-tab-bar.d.ts +2 -1
- package/lib/types/elements/adw-tab-button.d.ts +2 -1
- package/lib/types/elements/adw-tab-overview.d.ts +2 -1
- package/lib/types/elements/adw-tab-view.d.ts +3 -2
- package/lib/types/elements/adw-toast-overlay.d.ts +10 -30
- package/lib/types/elements/adw-toggle-group.d.ts +3 -2
- package/lib/types/elements/adw-toolbar-view.d.ts +2 -1
- package/lib/types/elements/adw-view-stack.d.ts +3 -1
- package/lib/types/elements/adw-view-switcher-bar.d.ts +2 -1
- package/lib/types/elements/adw-view-switcher-sidebar.d.ts +2 -1
- package/lib/types/elements/adw-view-switcher.d.ts +3 -2
- package/lib/types/elements/adw-window-features.d.ts +8 -0
- package/lib/types/elements/adw-window-title.d.ts +2 -1
- package/lib/types/elements/adw-wrap-box.d.ts +2 -1
- package/lib/types/elements/checks.d.ts +16 -1
- package/lib/types/elements/gtk-action-bar.d.ts +2 -1
- package/lib/types/elements/gtk-application-window.d.ts +1 -4
- package/lib/types/elements/gtk-aspect-frame.d.ts +2 -1
- package/lib/types/elements/gtk-box.d.ts +5 -1
- package/lib/types/elements/gtk-button.d.ts +5 -7
- package/lib/types/elements/gtk-calendar.d.ts +2 -1
- package/lib/types/elements/gtk-center-box.d.ts +2 -1
- package/lib/types/elements/gtk-color-dialog-button.d.ts +2 -1
- package/lib/types/elements/gtk-drag-icon.d.ts +2 -1
- package/lib/types/elements/gtk-drawing-area.d.ts +2 -1
- package/lib/types/elements/gtk-drop-down.d.ts +2 -1
- package/lib/types/elements/gtk-editable-label.d.ts +2 -1
- package/lib/types/elements/gtk-emoji-chooser.d.ts +2 -0
- package/lib/types/elements/gtk-entry.d.ts +2 -1
- package/lib/types/elements/gtk-expander.d.ts +2 -1
- package/lib/types/elements/gtk-fixed.d.ts +2 -1
- package/lib/types/elements/gtk-flow-box-child.d.ts +2 -1
- package/lib/types/elements/gtk-flow-box.d.ts +2 -1
- package/lib/types/elements/gtk-font-dialog-button.d.ts +2 -1
- package/lib/types/elements/gtk-frame.d.ts +2 -1
- package/lib/types/elements/gtk-gl-area.d.ts +2 -1
- package/lib/types/elements/gtk-graphics-offload.d.ts +2 -1
- package/lib/types/elements/gtk-grid.d.ts +2 -1
- package/lib/types/elements/gtk-header-bar.d.ts +2 -1
- package/lib/types/elements/gtk-image.d.ts +5 -6
- package/lib/types/elements/gtk-inscription.d.ts +2 -1
- package/lib/types/elements/gtk-label.d.ts +10 -3
- package/lib/types/elements/gtk-level-bar.d.ts +2 -1
- package/lib/types/elements/gtk-list-box-row.d.ts +2 -1
- package/lib/types/elements/gtk-list-box.d.ts +2 -1
- package/lib/types/elements/gtk-list-view.d.ts +2 -1
- package/lib/types/elements/gtk-media-controls.d.ts +2 -1
- package/lib/types/elements/gtk-menu-button.d.ts +2 -1
- package/lib/types/elements/gtk-notebook.d.ts +2 -1
- package/lib/types/elements/gtk-overlay.d.ts +2 -1
- package/lib/types/elements/gtk-paned.d.ts +2 -1
- package/lib/types/elements/gtk-picture.d.ts +2 -1
- package/lib/types/elements/gtk-popover-bin.d.ts +2 -1
- package/lib/types/elements/gtk-popover-menu-bar.d.ts +2 -1
- package/lib/types/elements/gtk-popover-menu.d.ts +2 -0
- package/lib/types/elements/gtk-popover.d.ts +7 -1
- package/lib/types/elements/gtk-progress-bar.d.ts +2 -1
- package/lib/types/elements/gtk-revealer.d.ts +2 -1
- package/lib/types/elements/gtk-scale-button.d.ts +2 -1
- package/lib/types/elements/gtk-scale.d.ts +2 -1
- package/lib/types/elements/gtk-scrollbar.d.ts +2 -1
- package/lib/types/elements/gtk-scrolled-window.d.ts +2 -1
- package/lib/types/elements/gtk-search-bar.d.ts +2 -1
- package/lib/types/elements/gtk-separator.d.ts +2 -1
- package/lib/types/elements/gtk-spin-button.d.ts +2 -1
- package/lib/types/elements/gtk-spinner.d.ts +2 -1
- package/lib/types/elements/gtk-stack-page.d.ts +29 -0
- package/lib/types/elements/gtk-stack-sidebar.d.ts +2 -1
- package/lib/types/elements/gtk-stack-switcher.d.ts +2 -1
- package/lib/types/elements/gtk-stack.d.ts +13 -1
- package/lib/types/elements/gtk-switch.d.ts +2 -1
- package/lib/types/elements/gtk-text-view.d.ts +2 -1
- package/lib/types/elements/gtk-text.d.ts +2 -1
- package/lib/types/elements/gtk-tree-expander.d.ts +2 -1
- package/lib/types/elements/gtk-video.d.ts +2 -1
- package/lib/types/elements/gtk-viewport.d.ts +2 -1
- package/lib/types/elements/gtk-window-controls.d.ts +2 -1
- package/lib/types/elements/gtk-window-handle.d.ts +2 -1
- package/lib/types/elements/gtk-window.d.ts +18 -2
- package/lib/types/gobject-elements.d.ts +15 -0
- package/lib/types/gtksource/gtk-source-view.d.ts +2 -1
- package/lib/types/{icon-registry.spec.d.ts → icon-masks.spec.d.ts} +1 -1
- package/lib/types/icon-theme.d.ts +15 -35
- package/lib/types/index.d.ts +3 -4
- package/lib/types/learn6502-window.spec.d.ts +1 -0
- package/lib/types/namespace/adw.d.ts +1 -1
- package/lib/types/namespace/gdk.d.ts +1 -0
- package/lib/types/namespace/gio.d.ts +1 -0
- package/lib/types/namespace/glib.d.ts +2 -1
- package/lib/types/namespace/gtk.d.ts +2 -0
- package/lib/types/shared-tree-builder.d.ts +31 -0
- package/lib/types/signals.d.ts +5 -1
- package/lib/types/source-view/adw-source-view.d.ts +2 -1
- package/lib/types/styles.generated.d.ts +1 -1
- package/lib/types/widget-element.d.ts +25 -0
- package/lib/types/widget-map.spec.d.ts +1 -0
- package/lib/types/widget-mapping.d.ts +7 -0
- package/lib/types/widget-visible.spec.d.ts +1 -0
- package/lib/types/window-maximize.spec.d.ts +1 -0
- package/package.json +13 -12
- package/scss/_about_dialog.scss +46 -1
- package/scss/_bin.scss +6 -3
- package/scss/_checks.scss +5 -2
- package/scss/_icon.scss +3 -4
- package/scss/_labels.scss +2 -2
- package/scss/_overlay.scss +11 -1
- package/scss/_overlay_split_view.scss +10 -0
- package/scss/_reset.scss +1 -1
- package/scss/_scrolled_window.scss +15 -0
- package/scss/_stack.scss +8 -2
- package/scss/_toast.scss +13 -3
- package/scss/_widget.scss +5 -1
- package/scss/_window.scss +16 -0
- package/src/accessible.ts +29 -0
- package/src/adw-about-dialog.spec.ts +81 -12
- package/src/adw-action-rows.spec.ts +2 -2
- package/src/adw-alert-dialog.spec.ts +71 -5
- package/src/adw-bin.spec.ts +4 -3
- package/src/adw-button-content.spec.ts +1 -1
- package/src/adw-carousel.spec.ts +49 -1
- package/src/adw-header-bar.spec.ts +18 -0
- package/src/adw-toast-overlay.spec.ts +68 -24
- package/src/application.spec.ts +44 -0
- package/src/application.ts +13 -18
- package/src/capabilities.mjs +2 -3
- package/src/checks.spec.ts +51 -1
- package/src/child-slot.spec.ts +71 -0
- package/src/compute-expand.spec.ts +186 -0
- package/src/compute-expand.ts +134 -0
- package/src/construct-vectors.spec.ts +97 -7
- package/src/container-fill.spec.ts +70 -0
- package/src/elements/adw-about-dialog.ts +152 -9
- package/src/elements/adw-action-row.ts +2 -1
- package/src/elements/adw-alert-dialog.ts +177 -46
- package/src/elements/adw-application-window.ts +0 -3
- package/src/elements/adw-avatar.ts +2 -1
- package/src/elements/adw-banner.ts +2 -1
- package/src/elements/adw-bin.ts +2 -1
- package/src/elements/adw-bottom-sheet.ts +5 -4
- package/src/elements/adw-breakpoint-bin.ts +5 -1
- package/src/elements/adw-button-content.ts +2 -1
- package/src/elements/adw-button-row.ts +2 -1
- package/src/elements/adw-card.ts +2 -1
- package/src/elements/adw-carousel.ts +62 -3
- package/src/elements/adw-clamp-scrollable.ts +2 -1
- package/src/elements/adw-clamp.ts +2 -1
- package/src/elements/adw-combo-row.ts +15 -1
- package/src/elements/adw-data-grid.ts +2 -1
- package/src/elements/adw-dialog.ts +5 -2
- package/src/elements/adw-entry-row.ts +2 -1
- package/src/elements/adw-expander-row.ts +2 -1
- package/src/elements/adw-header-bar.ts +6 -1
- package/src/elements/adw-inline-view-switcher.ts +3 -2
- package/src/elements/adw-layout-slot.ts +2 -1
- package/src/elements/adw-multi-layout-view.ts +2 -1
- package/src/elements/adw-navigation-split-view.ts +2 -1
- package/src/elements/adw-navigation-view.ts +3 -2
- package/src/elements/adw-overlay-split-view.ts +2 -1
- package/src/elements/adw-preferences-dialog.ts +6 -4
- package/src/elements/adw-preferences-group.ts +2 -1
- package/src/elements/adw-preferences-row.ts +2 -1
- package/src/elements/adw-shortcut-label.ts +2 -1
- package/src/elements/adw-shortcuts-item.ts +2 -1
- package/src/elements/adw-shortcuts-section.ts +2 -1
- package/src/elements/adw-sidebar.ts +4 -3
- package/src/elements/adw-spin-row.ts +2 -1
- package/src/elements/adw-spinner.ts +2 -1
- package/src/elements/adw-split-button.ts +2 -1
- package/src/elements/adw-status-page.ts +2 -1
- package/src/elements/adw-switch-row.ts +10 -1
- package/src/elements/adw-tab-bar.ts +2 -1
- package/src/elements/adw-tab-button.ts +2 -1
- package/src/elements/adw-tab-overview.ts +2 -1
- package/src/elements/adw-tab-view.ts +3 -2
- package/src/elements/adw-toast-overlay.ts +37 -70
- package/src/elements/adw-toggle-group.ts +3 -2
- package/src/elements/adw-toolbar-view.ts +2 -1
- package/src/elements/adw-view-stack.ts +39 -1
- package/src/elements/adw-view-switcher-bar.ts +2 -1
- package/src/elements/adw-view-switcher-sidebar.ts +2 -1
- package/src/elements/adw-view-switcher.ts +3 -2
- package/src/elements/adw-window-features.ts +14 -2
- package/src/elements/adw-window-title.ts +2 -1
- package/src/elements/adw-wrap-box.ts +2 -1
- package/src/elements/checks.ts +85 -6
- package/src/elements/gtk-action-bar.ts +2 -1
- package/src/elements/gtk-application-window.ts +3 -8
- package/src/elements/gtk-aspect-frame.ts +2 -1
- package/src/elements/gtk-box.ts +56 -1
- package/src/elements/gtk-button.ts +10 -22
- package/src/elements/gtk-calendar.ts +2 -1
- package/src/elements/gtk-center-box.ts +2 -1
- package/src/elements/gtk-color-dialog-button.ts +2 -1
- package/src/elements/gtk-drag-icon.ts +6 -1
- package/src/elements/gtk-drawing-area.ts +2 -1
- package/src/elements/gtk-drop-down.ts +2 -1
- package/src/elements/gtk-editable-label.ts +2 -1
- package/src/elements/gtk-emoji-chooser.ts +5 -0
- package/src/elements/gtk-entry.ts +2 -1
- package/src/elements/gtk-expander.ts +2 -1
- package/src/elements/gtk-fixed.ts +2 -1
- package/src/elements/gtk-flow-box-child.ts +5 -2
- package/src/elements/gtk-flow-box.ts +2 -1
- package/src/elements/gtk-font-dialog-button.ts +2 -1
- package/src/elements/gtk-frame.ts +2 -1
- package/src/elements/gtk-gl-area.ts +2 -1
- package/src/elements/gtk-graphics-offload.ts +5 -2
- package/src/elements/gtk-grid.ts +2 -1
- package/src/elements/gtk-header-bar.ts +2 -1
- package/src/elements/gtk-image.ts +14 -15
- package/src/elements/gtk-inscription.ts +2 -1
- package/src/elements/gtk-label.ts +12 -5
- package/src/elements/gtk-level-bar.ts +2 -1
- package/src/elements/gtk-list-box-row.ts +5 -2
- package/src/elements/gtk-list-box.ts +2 -1
- package/src/elements/gtk-list-view.ts +2 -1
- package/src/elements/gtk-media-controls.ts +2 -1
- package/src/elements/gtk-menu-button.ts +2 -1
- package/src/elements/gtk-notebook.ts +2 -1
- package/src/elements/gtk-overlay.ts +7 -5
- package/src/elements/gtk-paned.ts +9 -2
- package/src/elements/gtk-picture.ts +2 -1
- package/src/elements/gtk-popover-bin.ts +5 -1
- package/src/elements/gtk-popover-menu-bar.ts +2 -1
- package/src/elements/gtk-popover-menu.ts +5 -0
- package/src/elements/gtk-popover.ts +14 -1
- package/src/elements/gtk-progress-bar.ts +2 -1
- package/src/elements/gtk-revealer.ts +2 -1
- package/src/elements/gtk-scale-button.ts +2 -1
- package/src/elements/gtk-scale.ts +2 -1
- package/src/elements/gtk-scrollbar.ts +2 -1
- package/src/elements/gtk-scrolled-window.ts +8 -5
- package/src/elements/gtk-search-bar.ts +7 -6
- package/src/elements/gtk-separator.ts +2 -1
- package/src/elements/gtk-spin-button.ts +2 -1
- package/src/elements/gtk-spinner.ts +2 -1
- package/src/elements/gtk-stack-page.ts +112 -0
- package/src/elements/gtk-stack-sidebar.ts +2 -1
- package/src/elements/gtk-stack-switcher.ts +2 -1
- package/src/elements/gtk-stack.ts +52 -6
- package/src/elements/gtk-switch.ts +2 -1
- package/src/elements/gtk-text-view.ts +2 -1
- package/src/elements/gtk-text.ts +2 -1
- package/src/elements/gtk-tree-expander.ts +5 -1
- package/src/elements/gtk-video.ts +2 -1
- package/src/elements/gtk-viewport.ts +6 -1
- package/src/elements/gtk-window-controls.ts +2 -1
- package/src/elements/gtk-window-handle.ts +6 -1
- package/src/elements/gtk-window.ts +57 -7
- package/src/gio.spec.ts +13 -3
- package/src/glib.spec.ts +9 -0
- package/src/gobject-elements.ts +44 -2
- package/src/gtk-label.spec.ts +39 -0
- package/src/gtk-scrolled-window.spec.ts +6 -6
- package/src/gtk-stack.spec.ts +170 -0
- package/src/gtk-value-doors.spec.ts +19 -0
- package/src/gtk-window.spec.ts +2 -2
- package/src/gtksource/gtk-source-view.ts +2 -1
- package/src/{icon-registry.spec.ts → icon-masks.spec.ts} +4 -100
- package/src/icon-theme.spec.ts +69 -124
- package/src/icon-theme.ts +29 -119
- package/src/index.ts +5 -9
- package/src/keyboard-operable.spec.ts +3 -3
- package/src/learn6502-window.spec.ts +113 -0
- package/src/namespace/adw.ts +1 -1
- package/src/namespace/gdk.ts +1 -0
- package/src/namespace/gio.ts +8 -0
- package/src/namespace/glib.ts +4 -0
- package/src/namespace/gtk.ts +2 -0
- package/src/shared-tree-builder.ts +131 -13
- package/src/shared-trees.spec.ts +15 -1
- package/src/signals.ts +11 -2
- package/src/slotted-children.spec.ts +24 -0
- package/src/slotted-children.ts +18 -2
- package/src/source-view/adw-source-view.ts +2 -1
- package/src/split-button.spec.ts +1 -1
- package/src/style-manager.spec.ts +13 -0
- package/src/style-manager.ts +6 -0
- package/src/styles.generated.ts +1 -1
- package/src/test.browser.mts +16 -2
- package/src/value-lists.spec.ts +3 -3
- package/src/widget-element.ts +75 -0
- package/src/widget-map.spec.ts +116 -0
- package/src/widget-mapping.ts +100 -0
- package/src/widget-visible.spec.ts +148 -0
- package/src/window-maximize.spec.ts +93 -0
- package/lib/types/icon-registry.d.ts +0 -37
- package/src/icon-registry.ts +0 -163
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
// into a host `<div>` it was never given.
|
|
29
29
|
//
|
|
30
30
|
// Placed flat under `src/`, at parity with this package's other single-purpose modules
|
|
31
|
-
// (`accent.ts`, `breakpoints.ts`, `icon-
|
|
31
|
+
// (`accent.ts`, `breakpoints.ts`, `icon-theme.ts`) rather than a new `conformance/` or
|
|
32
32
|
// `builder/` directory for one file: unlike `gtk-host`, this package has no existing
|
|
33
33
|
// `conformance/` home to add to. Exported through the existing barrel, `src/index.ts` — the
|
|
34
34
|
// package's `exports` map ships only `.`, and a new subpath would buy nothing for a module
|
|
@@ -55,7 +55,14 @@ import {
|
|
|
55
55
|
|
|
56
56
|
import { observeAdaptiveSize } from './breakpoints.js';
|
|
57
57
|
import { capabilities } from './capabilities.mjs';
|
|
58
|
-
import {
|
|
58
|
+
import {
|
|
59
|
+
endpointOf,
|
|
60
|
+
hasElementApi,
|
|
61
|
+
hasInstalledVisible,
|
|
62
|
+
installElementApi,
|
|
63
|
+
installSensitive,
|
|
64
|
+
installVisible,
|
|
65
|
+
} from './gobject-elements.js';
|
|
59
66
|
import { dispatchedSignalsOf } from './signals.js';
|
|
60
67
|
import { slottedChildrenOf } from './slotted-children.js';
|
|
61
68
|
import { isTemplateTag, templateTagFor } from './template-classes.js';
|
|
@@ -154,14 +161,93 @@ function isWritable(el: object, member: string): boolean {
|
|
|
154
161
|
* upgraded has declared no slots yet, so the refusal below belongs to the mount.
|
|
155
162
|
*/
|
|
156
163
|
export function buildSharedTree(node: SharedTreeNode, record: BuildRecord = newRecord()): HTMLElement {
|
|
164
|
+
refuseSiblings(node, 'buildSharedTree');
|
|
165
|
+
return buildTree(node, record).root;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** What {@link buildWithSiblings} hands back: the root element and the objects built beside it. */
|
|
169
|
+
export interface BuiltTree {
|
|
170
|
+
/** The element the tree roots at, as {@link buildSharedTree} returns it. */
|
|
171
|
+
root: HTMLElement;
|
|
172
|
+
/**
|
|
173
|
+
* The sibling objects by id — `Adw.AlertDialog unsavedChangesDialog { }` or `$Learn learn { }`
|
|
174
|
+
* written after the template. A sibling is built in the root's id scope (a setter or a bind
|
|
175
|
+
* may name it) but is no child of the root: the code beside the file decides where, or
|
|
176
|
+
* whether, it is placed.
|
|
177
|
+
*/
|
|
178
|
+
siblings: ReadonlyMap<string, HTMLElement>;
|
|
179
|
+
/** Every element the tree names by id, siblings included: what `GtkBuilder.get_object` answers for. */
|
|
180
|
+
objects: ReadonlyMap<string, HTMLElement>;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** What {@link buildWithSiblings} takes beside the tree. */
|
|
184
|
+
export interface BuildOptions {
|
|
185
|
+
/** The object a handler NAME is looked up on (ADR 0093 § 3). */
|
|
186
|
+
scope?: Readonly<Record<string, unknown>>;
|
|
187
|
+
/** The size source a `breakpoints` node is driven from. */
|
|
188
|
+
observeSize?: SizeSource;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* A tree with sibling roots (ADR 0093): the root element, and each sibling by id, all DETACHED
|
|
193
|
+
* like {@link buildSharedTree}'s result.
|
|
194
|
+
*
|
|
195
|
+
* {@link buildSharedTree}, {@link mountSharedTree} and {@link buildTemplateTree} refuse such a
|
|
196
|
+
* tree by name, because they return one element and the siblings would be built and then thrown
|
|
197
|
+
* away. A sibling with no id is refused too: nothing could ever ask for it, which is how a
|
|
198
|
+
* dropped object looks finished.
|
|
199
|
+
*/
|
|
200
|
+
export function buildWithSiblings(node: SharedTreeNode, options: BuildOptions = {}): BuiltTree {
|
|
201
|
+
const record = newRecord(options.scope, options.observeSize);
|
|
202
|
+
const built = buildTree(node, record);
|
|
203
|
+
// An element declares its slots when it is connected, so a detached tree cannot be checked
|
|
204
|
+
// as it stands. It is connected for the length of the check and handed back detached, as
|
|
205
|
+
// documented: a placement the renderer could not honour is refused here, like
|
|
206
|
+
// `mountSharedTree` refuses it, instead of surfacing as a widget missing from the page.
|
|
207
|
+
const probe = document.createElement('div');
|
|
208
|
+
probe.hidden = true;
|
|
209
|
+
probe.append(built.root, ...built.siblings.values());
|
|
210
|
+
document.body.append(probe);
|
|
211
|
+
try {
|
|
212
|
+
refuseUnknownSlots(record.placed);
|
|
213
|
+
refuseUnheldExtensions(record.extended);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
for (const dispose of record.disposers) dispose();
|
|
216
|
+
throw error;
|
|
217
|
+
} finally {
|
|
218
|
+
probe.remove();
|
|
219
|
+
for (const el of [built.root, ...built.siblings.values()]) el.remove();
|
|
220
|
+
}
|
|
221
|
+
return built;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function refuseSiblings(node: SharedTreeNode, door: string): void {
|
|
225
|
+
if ((node.siblings?.length ?? 0) === 0) return;
|
|
226
|
+
throw new Error(
|
|
227
|
+
`\`${node.tag}\` carries ${node.siblings!.length} sibling object(s), and \`${door}\` returns one object ` +
|
|
228
|
+
'so they would be built and lost. Use `buildWithSiblings`, which hands them back by id.',
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Every node, its siblings in the same id scope, then the binds and breakpoints that name them. */
|
|
233
|
+
function buildTree(node: SharedTreeNode, record: BuildRecord): BuiltTree {
|
|
157
234
|
// ADR 0093 § 2: the whole tree is checked against the capability table before an element is
|
|
158
235
|
// created. A refused `layout` is named with its node and the reason the table gives.
|
|
159
|
-
assertTreeConstructs('adwaita-web', capabilities, node);
|
|
236
|
+
assertTreeConstructs('adwaita-web', capabilities, node, Object.keys(ARIA_OF));
|
|
160
237
|
if (node.menus !== undefined) record.menus = node.menus;
|
|
161
238
|
const root = buildNode(node, record);
|
|
239
|
+
const siblings = new Map<string, HTMLElement>();
|
|
240
|
+
for (const sibling of node.siblings ?? []) {
|
|
241
|
+
if (sibling.id === undefined) {
|
|
242
|
+
throw new Error(
|
|
243
|
+
`the sibling \`${sibling.tag}\` has no id, so nothing could ever ask for it: give it one in the .blp.`,
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
siblings.set(sibling.id, buildNode(sibling, record));
|
|
247
|
+
}
|
|
162
248
|
for (const bind of record.binds) bindProperty(bind, record);
|
|
163
249
|
for (const host of record.breakpointHosts) bindBreakpoints(host.el, host.node, record);
|
|
164
|
-
return root;
|
|
250
|
+
return { root, siblings, objects: new Map(record.ids) };
|
|
165
251
|
}
|
|
166
252
|
|
|
167
253
|
/** A fresh record, with the scope when the caller has one. */
|
|
@@ -344,7 +430,9 @@ export function writeProp(el: HTMLElement, prop: string, value: string | number
|
|
|
344
430
|
const member = propertyOf(prop);
|
|
345
431
|
const expand = GTK_WIDGET_EXPAND.find((name) => name === attr);
|
|
346
432
|
if (expand !== undefined && typeof value === 'boolean') el.setAttribute(expand, value ? '' : 'false');
|
|
347
|
-
else if (
|
|
433
|
+
else if (attr === 'visible' && typeof value === 'boolean' && hasInstalledVisible(el)) {
|
|
434
|
+
(el as unknown as Record<string, unknown>)[member] = value;
|
|
435
|
+
} else if (isTemplateTag(el.localName) && member in el) {
|
|
348
436
|
// An application class has no attributeChangedCallback: its properties are GObject properties,
|
|
349
437
|
// set the way `Gtk.Builder` sets them, after the constructor.
|
|
350
438
|
(el as unknown as Record<string, unknown>)[member] = value;
|
|
@@ -372,9 +460,14 @@ function buildNode(node: SharedTreeNode, record: BuildRecord): HTMLElement {
|
|
|
372
460
|
const el = document.createElement(node.extern === true ? templateTagFor(node.tag) : hostTagOf(node.tag));
|
|
373
461
|
// A template's children talk GObject to the template: `connect`, `emit`, `notify` (ADR 0096).
|
|
374
462
|
if (record.template !== undefined) installElementApi(el);
|
|
463
|
+
// `Gtk.Widget:visible`, which no element spells: a setter's target and an authored `false` need it.
|
|
464
|
+
installVisible(el);
|
|
375
465
|
// The id is how the TypeScript beside a `.blp` reaches this element
|
|
376
466
|
// (`root.querySelector('#…')`), the counterpart of `InternalChildren` on GTK.
|
|
377
467
|
if (node.id !== undefined) {
|
|
468
|
+
if (record.ids.has(node.id)) {
|
|
469
|
+
throw new Error(`Two nodes of this tree carry the id '${node.id}'; GtkBuilder refuses a duplicate id.`);
|
|
470
|
+
}
|
|
378
471
|
el.id = node.id;
|
|
379
472
|
record.ids.set(node.id, el);
|
|
380
473
|
}
|
|
@@ -419,6 +512,29 @@ function writeLook(el: HTMLElement, node: SharedTreeNode, menus?: SharedTreeNode
|
|
|
419
512
|
// `.blp`'s `styles ["title-1"]` reached the tree and never the page.
|
|
420
513
|
if (node.styleClasses !== undefined && node.styleClasses.length > 0) el.classList.add(...node.styleClasses);
|
|
421
514
|
writeExtensions(el, node);
|
|
515
|
+
writeAccessibility(el, node);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* The `accessibility { }` names this renderer has a door for, and the ARIA attribute each is.
|
|
520
|
+
* The rest (states, relations, `row-index`, …) are refused by name before the build, in
|
|
521
|
+
* {@link assertTreeConstructs}: no element here reads them, so they would be dropped.
|
|
522
|
+
*/
|
|
523
|
+
const ARIA_OF: Readonly<Record<string, string>> = {
|
|
524
|
+
label: 'aria-label',
|
|
525
|
+
description: 'aria-description',
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* `accessibility { label; description; }` as the host's `aria-label` / `aria-description`.
|
|
530
|
+
* Written after the props, so an element that derives a name from its tooltip sees the
|
|
531
|
+
* authored one first; an element whose role lives on an inner control forwards both
|
|
532
|
+
* (`accessible.ts`). A translatable value is written as its source text, as a prop's is.
|
|
533
|
+
*/
|
|
534
|
+
function writeAccessibility(el: HTMLElement, node: SharedTreeNode): void {
|
|
535
|
+
for (const [name, entry] of Object.entries(node.accessibility ?? {})) {
|
|
536
|
+
el.setAttribute(ARIA_OF[name], String(entry.value));
|
|
537
|
+
}
|
|
422
538
|
}
|
|
423
539
|
|
|
424
540
|
/** The `GtkGridLayoutChild` properties `layout { }` may carry, and the CSS Grid line each one is. */
|
|
@@ -492,7 +608,8 @@ export interface BuiltTemplateTree {
|
|
|
492
608
|
* belong to the first `connectedCallback`.
|
|
493
609
|
*/
|
|
494
610
|
export function buildTemplateTree(tree: SharedTreeNode, scope: TemplateScope, host: HTMLElement): BuiltTemplateTree {
|
|
495
|
-
|
|
611
|
+
refuseSiblings(tree, 'buildTemplateTree');
|
|
612
|
+
assertTreeConstructs('adwaita-web', capabilities, tree, Object.keys(ARIA_OF));
|
|
496
613
|
const record = newRecord(undefined, undefined, scope);
|
|
497
614
|
record.menus = tree.menus;
|
|
498
615
|
if (tree.id !== undefined) record.ids.set(tree.id, host);
|
|
@@ -591,9 +708,9 @@ function writeExtensions(el: HTMLElement, node: SharedTreeNode): void {
|
|
|
591
708
|
|
|
592
709
|
/** The response API an element answers to — `<adw-alert-dialog>`'s, named after libadwaita's. */
|
|
593
710
|
interface ResponseReader {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
711
|
+
get_response_label(id: string): string | null;
|
|
712
|
+
get_response_appearance(id: string): string | null;
|
|
713
|
+
get_response_enabled(id: string): boolean;
|
|
597
714
|
}
|
|
598
715
|
|
|
599
716
|
/**
|
|
@@ -617,10 +734,10 @@ function refuseUnheldExtensions(extended: readonly ExtendedNode[]): void {
|
|
|
617
734
|
const reader = el as unknown as Partial<ResponseReader>;
|
|
618
735
|
for (const response of node.extensions?.responses ?? []) {
|
|
619
736
|
const held =
|
|
620
|
-
typeof reader.
|
|
621
|
-
reader.
|
|
622
|
-
reader.
|
|
623
|
-
reader.
|
|
737
|
+
typeof reader.get_response_label === 'function' &&
|
|
738
|
+
reader.get_response_label(response.id) === response.label &&
|
|
739
|
+
reader.get_response_appearance?.(response.id) === (response.appearance ?? 'default') &&
|
|
740
|
+
reader.get_response_enabled?.(response.id) === (response.enabled ?? true);
|
|
624
741
|
if (!held) {
|
|
625
742
|
throw new Error(
|
|
626
743
|
`<${el.localName}> did not register the response "${response.id}" as authored, so the ` +
|
|
@@ -696,6 +813,7 @@ export interface MountOptions {
|
|
|
696
813
|
* `buildSharedTree` is for a caller that already has somewhere of its own to attach it.
|
|
697
814
|
*/
|
|
698
815
|
export function mountSharedTree(node: SharedTreeNode, options: MountOptions = {}): MountedSharedTree {
|
|
816
|
+
refuseSiblings(node, 'mountSharedTree');
|
|
699
817
|
const { into } = options;
|
|
700
818
|
const host = into ?? document.createElement('div');
|
|
701
819
|
const record = newRecord(options.scope, options.observeSize);
|
package/src/shared-trees.spec.ts
CHANGED
|
@@ -54,7 +54,7 @@ import { ADWAITA_GALLERY_SHARED_TREES } from '../../../../scripts/adwaita-galler
|
|
|
54
54
|
|
|
55
55
|
import '@gjsify/adwaita-web';
|
|
56
56
|
|
|
57
|
-
import { mountSharedTree } from './shared-tree-builder.js';
|
|
57
|
+
import { buildWithSiblings, mountSharedTree } from './shared-tree-builder.js';
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* Connect the authored root — these elements build on connect — run, and take it down again.
|
|
@@ -364,6 +364,20 @@ export const AdwSharedTreesTest = async () => {
|
|
|
364
364
|
).toThrow('has no slot "middle"');
|
|
365
365
|
});
|
|
366
366
|
|
|
367
|
+
// The detached door refuses it too: a root built and handed back is mounted by the
|
|
368
|
+
// caller, after the builder could still say anything.
|
|
369
|
+
await it('`buildWithSiblings` refuses the same placement, and hands a good tree back detached', () => {
|
|
370
|
+
const bad = { tag: 'AdwToolbarView', children: [{ tag: 'AdwBanner', slot: 'middle' }] };
|
|
371
|
+
expect(() => buildWithSiblings(bad)).toThrow('has no slot "middle"');
|
|
372
|
+
const { root, siblings } = buildWithSiblings({
|
|
373
|
+
tag: 'AdwToolbarView',
|
|
374
|
+
children: [{ tag: 'AdwBanner', slot: 'top' }],
|
|
375
|
+
siblings: [{ tag: 'GtkLabel', id: 'beside' }],
|
|
376
|
+
});
|
|
377
|
+
expect(root.isConnected || siblings.get('beside')!.isConnected).toBe(false);
|
|
378
|
+
expect(root.querySelector('adw-banner') !== null).toBe(true);
|
|
379
|
+
});
|
|
380
|
+
|
|
367
381
|
// ADR 0092's `layout { }`: a grid child's cell. GTK counts from 0, CSS Grid from 1.
|
|
368
382
|
await it('`layout { }` places a grid child in its cell, spans defaulting to one', () => {
|
|
369
383
|
mounted(
|
package/src/signals.ts
CHANGED
|
@@ -9,7 +9,16 @@
|
|
|
9
9
|
/** GTK signal name → the DOM event type the element dispatches it as. */
|
|
10
10
|
export type DispatchedSignals = Readonly<Record<string, string>>;
|
|
11
11
|
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* The signals `el`'s class and every class above it declare, or none. A class inherits its
|
|
14
|
+
* base's signals as a GObject class does (`map` / `unmap` are declared once, on
|
|
15
|
+
* `WidgetElement`); where two declare the same name, the more derived class wins.
|
|
16
|
+
*/
|
|
13
17
|
export function dispatchedSignalsOf(el: Element): DispatchedSignals {
|
|
14
|
-
|
|
18
|
+
const chain: DispatchedSignals[] = [];
|
|
19
|
+
for (let klass: unknown = el.constructor; typeof klass === 'function'; klass = Object.getPrototypeOf(klass)) {
|
|
20
|
+
const own = Object.getOwnPropertyDescriptor(klass, 'signals')?.value as DispatchedSignals | undefined;
|
|
21
|
+
if (own !== undefined) chain.unshift(own);
|
|
22
|
+
}
|
|
23
|
+
return Object.assign({}, ...chain) as DispatchedSignals;
|
|
15
24
|
}
|
|
@@ -113,6 +113,30 @@ export const AdwSlottedChildrenTest = async () => {
|
|
|
113
113
|
expect(report).toBe('[1]');
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
+
// The DECLARED twin of the case above. `install()` replaces the host's children with
|
|
117
|
+
// its structure, and a child no slot took used to go with them — gone without a word.
|
|
118
|
+
await it('keeps a declared child no slot takes, and warns that it was not placed', () => {
|
|
119
|
+
const host = document.createElement('div');
|
|
120
|
+
const typo = probe('sied', 'a');
|
|
121
|
+
host.append(document.createTextNode('\n '), typo);
|
|
122
|
+
mounted(host);
|
|
123
|
+
const side = document.createElement('div');
|
|
124
|
+
side.className = 'side';
|
|
125
|
+
|
|
126
|
+
const warned: string[] = [];
|
|
127
|
+
const warn = console.warn;
|
|
128
|
+
console.warn = (...args: unknown[]) => void warned.push(args.join(' '));
|
|
129
|
+
try {
|
|
130
|
+
bindSlottedChildren(host, [{ name: 'side', into: side }]).install(side);
|
|
131
|
+
} finally {
|
|
132
|
+
console.warn = warn;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const report = `${placement(host, typo)} | ${warned.join()}`;
|
|
136
|
+
host.remove();
|
|
137
|
+
expect(report).toBe("[1] | 'sied' is not a valid child type of 'div'");
|
|
138
|
+
});
|
|
139
|
+
|
|
116
140
|
await it('re-adopts a child that was appended, removed and appended again', async () => {
|
|
117
141
|
const host = mounted(document.createElement('div'));
|
|
118
142
|
const side = document.createElement('div');
|
package/src/slotted-children.ts
CHANGED
|
@@ -113,6 +113,12 @@ export interface AdwSlottedChildren {
|
|
|
113
113
|
/** Where a bound host's slots can be read back from — see {@link slottedChildrenOf}. */
|
|
114
114
|
const BOUND = new WeakMap<Element, AdwSlottedChildren>();
|
|
115
115
|
|
|
116
|
+
/** An element or a text node with something in it — markup's indentation and comments are not. */
|
|
117
|
+
function isContent(node: Node): boolean {
|
|
118
|
+
if (node instanceof Element) return true;
|
|
119
|
+
return node.nodeType === Node.TEXT_NODE && (node.textContent ?? '').trim() !== '';
|
|
120
|
+
}
|
|
121
|
+
|
|
116
122
|
/**
|
|
117
123
|
* The slot binding `host` installed, if it has one.
|
|
118
124
|
*
|
|
@@ -184,9 +190,19 @@ export function bindSlottedChildren(
|
|
|
184
190
|
slots,
|
|
185
191
|
slotFor,
|
|
186
192
|
install(...nodes: readonly Node[]) {
|
|
187
|
-
|
|
193
|
+
const unplaced: Node[] = [];
|
|
194
|
+
for (const node of Array.from(host.childNodes)) {
|
|
195
|
+
if (route(node) !== null || node.parentNode !== host || !isContent(node)) continue;
|
|
196
|
+
// `replaceChildren` below would delete it, and a child the author wrote that
|
|
197
|
+
// vanishes without a word is the silent drop this used to be. It stays beside
|
|
198
|
+
// the structure, as a late child with the same slot does, and says so the
|
|
199
|
+
// way GtkBuilder does (GTK_BUILDER_WARN_INVALID_CHILD_TYPE).
|
|
200
|
+
unplaced.push(node);
|
|
201
|
+
const type = node instanceof Element ? (node.getAttribute('slot') ?? '') : '';
|
|
202
|
+
console.warn(`'${type}' is not a valid child type of '${host.localName}'`);
|
|
203
|
+
}
|
|
188
204
|
structure = new Set(nodes);
|
|
189
|
-
host.replaceChildren(...nodes);
|
|
205
|
+
host.replaceChildren(...nodes, ...unplaced);
|
|
190
206
|
// Armed AFTER `replaceChildren`, so its own records are never delivered: an
|
|
191
207
|
// observer armed first would see the whole of `structure` as added nodes and
|
|
192
208
|
// spend a microtask rejecting them.
|
|
@@ -36,13 +36,14 @@ import { adwaitaEditorTheme, adwaitaHighlightStyle, ensureSourceViewStyleInjecte
|
|
|
36
36
|
import { formatHexAddress, formatLineNumber, stripSourceWhitespace } from '@gjsify/adwaita-core';
|
|
37
37
|
import { createGtkImage } from '../elements/gtk-image.js';
|
|
38
38
|
import { createCopyGlyph } from './copy-glyph.js';
|
|
39
|
+
import { WidgetElement } from '../widget-element.js';
|
|
39
40
|
|
|
40
41
|
/** Parse a boolean attribute: present (any value but "false") ⇒ true. */
|
|
41
42
|
function boolAttr(value: string | null): boolean {
|
|
42
43
|
return value !== null && value !== 'false';
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
export class AdwSourceView extends
|
|
46
|
+
export class AdwSourceView extends WidgetElement {
|
|
46
47
|
private _view?: EditorView;
|
|
47
48
|
private _editorHost!: HTMLDivElement;
|
|
48
49
|
private _copyButton!: HTMLButtonElement;
|
package/src/split-button.spec.ts
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
import { ADW_MENU_SURFACE_WEB, flattenMenu, menuRefusals } from '@gjsify/adwaita-core';
|
|
21
21
|
import type { SplitButtonProperty } from '@gjsify/adwaita-core';
|
|
22
22
|
import type { AdwSplitButton } from './elements/adw-split-button.js';
|
|
23
|
-
import { fallbackMask, maskOf } from './icon-
|
|
23
|
+
import { fallbackMask, maskOf } from './icon-masks.spec.js';
|
|
24
24
|
|
|
25
25
|
/** The GObject properties the element re-emits as `notify::*` CustomEvents. */
|
|
26
26
|
const NOTIFY_PROPERTIES: readonly SplitButtonProperty[] = [
|
|
@@ -6,6 +6,7 @@ import { STYLE_MANAGER_VECTORS, driveStyleManagerVectors, type AdwStyleLike } fr
|
|
|
6
6
|
import { describe, expect, it } from '@gjsify/unit';
|
|
7
7
|
|
|
8
8
|
import * as Adw from './namespace/adw.js';
|
|
9
|
+
import { webStyleSource } from './style-manager.js';
|
|
9
10
|
|
|
10
11
|
export const StyleManagerTest = async () => {
|
|
11
12
|
const root = document.documentElement;
|
|
@@ -26,6 +27,18 @@ export const StyleManagerTest = async () => {
|
|
|
26
27
|
{ describe, it, expect },
|
|
27
28
|
);
|
|
28
29
|
await describe('adwaita-web: Adw.StyleManager door', async () => {
|
|
30
|
+
await it('system_supports_color_schemes is true where prefers-color-scheme is known', () => {
|
|
31
|
+
expect(Adw.StyleManager.get_default().system_supports_color_schemes).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
await it('a browser that matches neither scheme does not support them', () => {
|
|
34
|
+
const real = globalThis.matchMedia;
|
|
35
|
+
globalThis.matchMedia = ((query: string) => ({ matches: false, media: query })) as never;
|
|
36
|
+
try {
|
|
37
|
+
expect(webStyleSource.supportsColorSchemes?.()).toBe(false);
|
|
38
|
+
} finally {
|
|
39
|
+
globalThis.matchMedia = real;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
29
42
|
await it('has a vector row for every vector', () => {
|
|
30
43
|
expect(STYLE_MANAGER_VECTORS.length > 0).toBe(true);
|
|
31
44
|
});
|
package/src/style-manager.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// on the root outranks `prefers-color-scheme` (ADR 0078, `isAdwaitaDark`). The behaviour is the
|
|
3
3
|
// core's (`style-manager.ts`); this file is the SOURCE: the root's `class` attribute and the media
|
|
4
4
|
// query are the two things that can flip it. Without a `document` (SSR) it is light and never changes.
|
|
5
|
+
// The system supports color schemes when the browser knows `prefers-color-scheme`: then one of its
|
|
6
|
+
// two values matches; a browser without the feature matches neither.
|
|
5
7
|
|
|
6
8
|
import { ColorScheme, StyleManagerBase, type StyleSource } from '@gjsify/adwaita-core';
|
|
7
9
|
|
|
@@ -20,6 +22,10 @@ export const webStyleSource: StyleSource = {
|
|
|
20
22
|
observer.disconnect();
|
|
21
23
|
};
|
|
22
24
|
},
|
|
25
|
+
supportsColorSchemes() {
|
|
26
|
+
const matches = (query: string) => globalThis.matchMedia?.(query).matches === true;
|
|
27
|
+
return matches('(prefers-color-scheme: dark)') || matches('(prefers-color-scheme: light)');
|
|
28
|
+
},
|
|
23
29
|
};
|
|
24
30
|
|
|
25
31
|
// FORCE_DARK / FORCE_LIGHT write the same root class an app writes by hand; DEFAULT takes it away.
|