@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
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
import { normalizeBoxOrientation, type BoxOrientation } from '@gjsify/adwaita-core';
|
|
48
48
|
|
|
49
49
|
import type { GtkStack } from './gtk-stack.js';
|
|
50
|
+
import { WidgetElement } from '../widget-element.js';
|
|
50
51
|
|
|
51
52
|
/** The `GtkStackPageInfo` half this element reads — it never looks inside `child`. */
|
|
52
53
|
interface SwitcherPage {
|
|
@@ -65,7 +66,7 @@ interface SwitcherButton {
|
|
|
65
66
|
icon: HTMLElement;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
export class GtkStackSwitcher extends
|
|
69
|
+
export class GtkStackSwitcher extends WidgetElement {
|
|
69
70
|
private _stack: GtkStack | null = null;
|
|
70
71
|
private _initialized = false;
|
|
71
72
|
private _nodes: SwitcherButton[] = [];
|
|
@@ -92,6 +92,8 @@
|
|
|
92
92
|
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
93
93
|
|
|
94
94
|
import type { DispatchedSignals } from '../signals.js';
|
|
95
|
+
import { STACK_PAGE_ATTRIBUTES, pageChildOf } from './gtk-stack-page.js';
|
|
96
|
+
import { WidgetElement } from '../widget-element.js';
|
|
95
97
|
|
|
96
98
|
/** `GtkStackTransitionType`, spelled as the GIR's enum nicks (gtkstack.c:95-121). */
|
|
97
99
|
export type StackTransitionType =
|
|
@@ -225,7 +227,7 @@ export interface GtkStackPageInfo {
|
|
|
225
227
|
/** The five `GtkStackPage` string/boolean properties this element reads off a child. */
|
|
226
228
|
const PAGE_ATTRIBUTES = ['name', 'title', 'icon-name', 'use-underline', 'needs-attention'];
|
|
227
229
|
|
|
228
|
-
export class GtkStack extends
|
|
230
|
+
export class GtkStack extends WidgetElement {
|
|
229
231
|
/** The GTK signals this element dispatches, each with the DOM event it arrives as (ADR 0093). */
|
|
230
232
|
static readonly signals: DispatchedSignals = {
|
|
231
233
|
'notify::visible-child': 'notify::visible-child',
|
|
@@ -416,7 +418,7 @@ export class GtkStack extends HTMLElement {
|
|
|
416
418
|
}
|
|
417
419
|
this._initialized = true;
|
|
418
420
|
this.setAttribute('role', 'group');
|
|
419
|
-
for (const child of this._children()) this._initChild(child);
|
|
421
|
+
for (const child of this._children()) this._initChild(this._adopt(child));
|
|
420
422
|
// `add_page` connects the stack to each page's `notify::visible`
|
|
421
423
|
// (gtkstack.c:1771), which is the browser's mutation observer.
|
|
422
424
|
this._observer = new MutationObserver((records) => this._onChildMutations(records));
|
|
@@ -531,12 +533,44 @@ export class GtkStack extends HTMLElement {
|
|
|
531
533
|
return this._children().find((child) => this._page(child).visible) ?? null;
|
|
532
534
|
}
|
|
533
535
|
|
|
536
|
+
/**
|
|
537
|
+
* A `<gtk-stack-page>` record, adopted: its child takes the record's place and its properties
|
|
538
|
+
* as the attributes this element reads, the way `<adw-view-stack>` adopts a declared page.
|
|
539
|
+
* Any other child is already the page and is handed back as it is.
|
|
540
|
+
*/
|
|
541
|
+
private _adopt(child: HTMLElement): HTMLElement {
|
|
542
|
+
if (child.localName !== 'gtk-stack-page') return child;
|
|
543
|
+
const content = pageChildOf(child);
|
|
544
|
+
if (content === null) {
|
|
545
|
+
throw new Error(
|
|
546
|
+
`<gtk-stack-page name="${child.getAttribute('name') ?? ''}"> has no child, so the stack would ` +
|
|
547
|
+
'hold a page with nothing to show.',
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
for (const name of STACK_PAGE_ATTRIBUTES) {
|
|
551
|
+
const value = child.getAttribute(name);
|
|
552
|
+
if (value !== null) content.setAttribute(name, value);
|
|
553
|
+
}
|
|
554
|
+
if (child.hasAttribute('hidden')) content.setAttribute('hidden', '');
|
|
555
|
+
content.removeAttribute('slot');
|
|
556
|
+
this.replaceChild(content, child);
|
|
557
|
+
return content;
|
|
558
|
+
}
|
|
559
|
+
|
|
534
560
|
private _initChild(child: HTMLElement): void {
|
|
535
561
|
if (this._initializedChildren.has(child)) return;
|
|
536
562
|
this._initializedChildren.add(child);
|
|
537
563
|
child.classList.add('adw-stack-page');
|
|
538
564
|
}
|
|
539
565
|
|
|
566
|
+
/**
|
|
567
|
+
* The observer watches the subtree, so an attribute record can come from anything below a
|
|
568
|
+
* page; only a direct child is a page of THIS stack (a nested stack's pages are its own).
|
|
569
|
+
*/
|
|
570
|
+
private _isPage(node: Node): boolean {
|
|
571
|
+
return node.parentNode === this;
|
|
572
|
+
}
|
|
573
|
+
|
|
540
574
|
private _onChildMutations(records: MutationRecord[]): void {
|
|
541
575
|
let added = 0;
|
|
542
576
|
let removed = 0;
|
|
@@ -544,13 +578,24 @@ export class GtkStack extends HTMLElement {
|
|
|
544
578
|
let pageUpdated = false;
|
|
545
579
|
for (const record of records) {
|
|
546
580
|
if (record.type === 'childList') {
|
|
581
|
+
// The observer watches the subtree for page attributes; a child list changing
|
|
582
|
+
// below a page (an adopted record handing over its child) is not a page change.
|
|
583
|
+
if (record.target !== this) continue;
|
|
547
584
|
for (const node of Array.from(record.removedNodes)) {
|
|
585
|
+
// A record leaving as its child takes its place was never a page here.
|
|
586
|
+
if (node instanceof HTMLElement && node.localName === 'gtk-stack-page') continue;
|
|
548
587
|
if (node === this._visible) this._visible = null;
|
|
549
588
|
if (node === this._lastVisible) this._lastVisible = null;
|
|
550
589
|
removed += 1;
|
|
551
590
|
}
|
|
552
591
|
for (const node of Array.from(record.addedNodes)) {
|
|
553
592
|
if (!(node instanceof HTMLElement)) continue;
|
|
593
|
+
// An adopted record is replaced by its child, and that replacement is the
|
|
594
|
+
// childList record the page is counted in.
|
|
595
|
+
if (node.localName === 'gtk-stack-page') {
|
|
596
|
+
if (node.parentElement === this) this._adopt(node);
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
554
599
|
this._initChild(node);
|
|
555
600
|
added += 1;
|
|
556
601
|
if (position === -1) position = this._children().indexOf(node);
|
|
@@ -558,13 +603,14 @@ export class GtkStack extends HTMLElement {
|
|
|
558
603
|
continue;
|
|
559
604
|
}
|
|
560
605
|
const name = record.attributeName;
|
|
561
|
-
if (!name) continue;
|
|
606
|
+
if (!name || !this._isPage(record.target)) continue;
|
|
562
607
|
if (name === 'hidden') {
|
|
563
608
|
// `stack_child_visibility_notify_cb` (gtkstack.c:1617-1633) re-runs
|
|
564
609
|
// `update_child_visible`: hiding the visible page falls back to the first
|
|
565
610
|
// visible one (which is what the NULL means, :1437-1450), and showing one
|
|
566
|
-
// while none is visible picks it up (:3147-3149).
|
|
567
|
-
|
|
611
|
+
// while none is visible picks it up (:3147-3149). Any other change leaves
|
|
612
|
+
// the selection where it is.
|
|
613
|
+
if (!this._visible || !this._page(this._visible).visible) this._show(this._firstVisible());
|
|
568
614
|
continue;
|
|
569
615
|
}
|
|
570
616
|
if (PAGE_ATTRIBUTES.includes(name)) pageUpdated = true;
|
|
@@ -579,7 +625,7 @@ export class GtkStack extends HTMLElement {
|
|
|
579
625
|
}
|
|
580
626
|
if (pageUpdated) {
|
|
581
627
|
for (const record of records) {
|
|
582
|
-
if (record.type !== 'attributes') continue;
|
|
628
|
+
if (record.type !== 'attributes' || !this._isPage(record.target)) continue;
|
|
583
629
|
const target = record.target as HTMLElement;
|
|
584
630
|
this.dispatchEvent(new CustomEvent('page-updated', { bubbles: true, detail: { child: target } }));
|
|
585
631
|
// `gtk_stack_page_set_name` re-notifies `visible-child-name` when the
|
|
@@ -40,8 +40,9 @@
|
|
|
40
40
|
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
41
41
|
|
|
42
42
|
import type { DispatchedSignals } from '../signals.js';
|
|
43
|
+
import { WidgetElement } from '../widget-element.js';
|
|
43
44
|
|
|
44
|
-
export class GtkSwitch extends
|
|
45
|
+
export class GtkSwitch extends WidgetElement {
|
|
45
46
|
/** The GTK signals this element dispatches, each with the DOM event it arrives as (ADR 0093). */
|
|
46
47
|
static readonly signals: DispatchedSignals = {
|
|
47
48
|
'notify::active': 'notify::active',
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
import { normalizeLabelJustify, type LabelJustification } from '@gjsify/adwaita-core';
|
|
51
51
|
|
|
52
52
|
import { JUSTIFY_TEXT_ALIGN } from './justification.js';
|
|
53
|
+
import { WidgetElement } from '../widget-element.js';
|
|
53
54
|
|
|
54
55
|
/** `Gtk.WrapMode`'s four nicks, in enum order — Pango's enum, and the DEFAULT is `none`. */
|
|
55
56
|
const WRAP_MODES = ['none', 'char', 'word', 'word-char'] as const;
|
|
@@ -83,7 +84,7 @@ export interface GtkTextBufferSubset {
|
|
|
83
84
|
get_text(): string;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
export class GtkTextView extends
|
|
87
|
+
export class GtkTextView extends WidgetElement {
|
|
87
88
|
private _area!: HTMLTextAreaElement;
|
|
88
89
|
private _initialized = false;
|
|
89
90
|
|
package/src/elements/gtk-text.ts
CHANGED
|
@@ -43,8 +43,9 @@
|
|
|
43
43
|
// arithmetic composed from @gjsify/adwaita-core.
|
|
44
44
|
|
|
45
45
|
import { ENTRY_ROW_MAX_LENGTH_LIMIT, clampEntryText, entryTextLength } from '@gjsify/adwaita-core';
|
|
46
|
+
import { WidgetElement } from '../widget-element.js';
|
|
46
47
|
|
|
47
|
-
export class GtkText extends
|
|
48
|
+
export class GtkText extends WidgetElement {
|
|
48
49
|
private _input!: HTMLInputElement;
|
|
49
50
|
private _initialized = false;
|
|
50
51
|
private _maxLength = 0;
|
|
@@ -59,11 +59,13 @@ import {
|
|
|
59
59
|
} from '@gjsify/adwaita-core';
|
|
60
60
|
|
|
61
61
|
import { createGtkImage } from './gtk-image.js';
|
|
62
|
+
import { bindSlottedChildren } from '../slotted-children.js';
|
|
63
|
+
import { WidgetElement } from '../widget-element.js';
|
|
62
64
|
|
|
63
65
|
/** `TIMEOUT_EXPAND` — how long a drag hovers before the row opens (gtktreeexpander.c:717). */
|
|
64
66
|
const TIMEOUT_EXPAND = 500;
|
|
65
67
|
|
|
66
|
-
export class GtkTreeExpander extends
|
|
68
|
+
export class GtkTreeExpander extends WidgetElement {
|
|
67
69
|
private _ornaments: HTMLElement[] = [];
|
|
68
70
|
private _expandTimer: ReturnType<typeof setTimeout> | null = null;
|
|
69
71
|
private _initialized = false;
|
|
@@ -142,6 +144,8 @@ export class GtkTreeExpander extends HTMLElement {
|
|
|
142
144
|
if (!this.hasAttribute('tabindex')) this.tabIndex = 0;
|
|
143
145
|
this._wire();
|
|
144
146
|
}
|
|
147
|
+
// The NAME only, for the reason `adw-bin.ts` gives: the child already IS the content.
|
|
148
|
+
bindSlottedChildren(this, [{ name: 'child', into: this }]);
|
|
145
149
|
this.setAttribute('role', 'button');
|
|
146
150
|
this._render();
|
|
147
151
|
}
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
// Reference: refs/libadwaita/src/stylesheet/widgets/_misc.scss:74-81 (the 64/32 osd icon)
|
|
66
66
|
// Copyright (c) The GTK Team. LGPLv2.1+.
|
|
67
67
|
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
68
|
+
import { WidgetElement } from '../widget-element.js';
|
|
68
69
|
|
|
69
70
|
/** The four overlay glyphs, in the order `update_overlay_icon` tests them (gtkvideo.c:626-646). */
|
|
70
71
|
export type VideoOverlayIcon =
|
|
@@ -99,7 +100,7 @@ export const READY_ICON = 'media-playback-start-symbolic';
|
|
|
99
100
|
/** `gtk_video_reveal_controls`' timeout: 3 s (gtkvideo.c:130). */
|
|
100
101
|
export const CONTROLS_HIDE_MS = 3000;
|
|
101
102
|
|
|
102
|
-
export class GtkVideo extends
|
|
103
|
+
export class GtkVideo extends WidgetElement {
|
|
103
104
|
private _initialized = false;
|
|
104
105
|
private _overlayIcon!: HTMLButtonElement;
|
|
105
106
|
private _controlsRevealer!: HTMLDivElement;
|
|
@@ -65,6 +65,9 @@
|
|
|
65
65
|
|
|
66
66
|
import { clampAdjustmentValue, normalizeAdjustment, type AdwAdjustment } from '@gjsify/adwaita-core';
|
|
67
67
|
|
|
68
|
+
import { bindSlottedChildren } from '../slotted-children.js';
|
|
69
|
+
import { WidgetElement } from '../widget-element.js';
|
|
70
|
+
|
|
68
71
|
/** `viewport_set_adjustment_values`'s two fractions of the visible size. */
|
|
69
72
|
const STEP_FRACTION = 0.1;
|
|
70
73
|
const PAGE_FRACTION = 0.9;
|
|
@@ -92,7 +95,7 @@ function axisAdjustment(clip: HTMLElement, axis: Axis): AdwAdjustment {
|
|
|
92
95
|
});
|
|
93
96
|
}
|
|
94
97
|
|
|
95
|
-
export class GtkViewport extends
|
|
98
|
+
export class GtkViewport extends WidgetElement {
|
|
96
99
|
private _observer: ResizeObserver | null = null;
|
|
97
100
|
private _watch: MutationObserver | null = null;
|
|
98
101
|
|
|
@@ -130,6 +133,8 @@ export class GtkViewport extends HTMLElement {
|
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
connectedCallback() {
|
|
136
|
+
// The NAME only, for the reason `adw-bin.ts` gives: the child already IS the content.
|
|
137
|
+
bindSlottedChildren(this, [{ name: 'child', into: this }]);
|
|
133
138
|
this.setAttribute('role', 'generic');
|
|
134
139
|
// `scroll` does not bubble, so the platform's own is heard here, on the node that
|
|
135
140
|
// raised it, and re-announced as GTK's `GtkAdjustment::value-changed`.
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
67
67
|
|
|
68
68
|
import { createGtkImage } from './gtk-image.js';
|
|
69
|
+
import { WidgetElement } from '../widget-element.js';
|
|
69
70
|
|
|
70
71
|
/** `Gtk.PackType`, spelled as the GIR's enum nicks (gtkwindowcontrols.c:68). */
|
|
71
72
|
type PackSide = 'start' | 'end';
|
|
@@ -120,7 +121,7 @@ const WINDOW_ATTRIBUTES = [
|
|
|
120
121
|
/** `closest` over both window spellings — `Adw.Window` is a `GtkWindow` subclass. */
|
|
121
122
|
const WINDOW_SELECTOR = 'gtk-window, adw-window';
|
|
122
123
|
|
|
123
|
-
export class GtkWindowControls extends
|
|
124
|
+
export class GtkWindowControls extends WidgetElement {
|
|
124
125
|
private _initialized = false;
|
|
125
126
|
private _empty = true;
|
|
126
127
|
/** The frame this controls answers to, or `null` outside one (`:257-263`). */
|
|
@@ -46,6 +46,9 @@
|
|
|
46
46
|
// Copyright (c) The GTK Team. LGPLv2.1+.
|
|
47
47
|
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
48
48
|
|
|
49
|
+
import { bindSlottedChildren } from '../slotted-children.js';
|
|
50
|
+
import { WidgetElement } from '../widget-element.js';
|
|
51
|
+
|
|
49
52
|
/** `GtkTitlebarGesture`'s three gestures, as `perform_titlebar_action` decides them. */
|
|
50
53
|
export type GtkTitlebarGesture = 'double-click' | 'middle-click' | 'right-click';
|
|
51
54
|
|
|
@@ -112,7 +115,7 @@ function gestureOf(button: number, presses: number): GtkTitlebarGesture | null {
|
|
|
112
115
|
*/
|
|
113
116
|
const DRAG_THRESHOLD = 1;
|
|
114
117
|
|
|
115
|
-
export class GtkWindowHandle extends
|
|
118
|
+
export class GtkWindowHandle extends WidgetElement {
|
|
116
119
|
/** The gesture in progress, as `priv->drag_start_x` / `_y` are in the C. */
|
|
117
120
|
private _drag: { pointerId: number; x: number; y: number } | null = null;
|
|
118
121
|
|
|
@@ -146,6 +149,8 @@ export class GtkWindowHandle extends HTMLElement {
|
|
|
146
149
|
}
|
|
147
150
|
|
|
148
151
|
connectedCallback() {
|
|
152
|
+
// The NAME only, for the reason `adw-bin.ts` gives: the child already IS the content.
|
|
153
|
+
bindSlottedChildren(this, [{ name: 'child', into: this }]);
|
|
149
154
|
this.setAttribute('role', 'generic');
|
|
150
155
|
this.addEventListener('click', this._onClick);
|
|
151
156
|
this.addEventListener('pointerdown', this._onPointerDown);
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
// difference a reader of the DOM can see.
|
|
48
48
|
//
|
|
49
49
|
// NOT PORTED, and why — these are the KNOWN_GAPS of this element:
|
|
50
|
-
// `
|
|
50
|
+
// `child`, `default-widget`, `display` — WIDGET- or
|
|
51
51
|
// DISPLAY-typed, so a slot or an id here rather than an attribute; `child` and
|
|
52
52
|
// `titlebar` ARE slots and `transient-for` only has to be PRESENT.
|
|
53
53
|
// `destroy-with-parent` — a DOM node has no destroy, and a page has no parent to destroy.
|
|
@@ -69,8 +69,14 @@
|
|
|
69
69
|
// `set_focus(el)` calls `el.focus()` and refuses an element outside the frame;
|
|
70
70
|
// `set_focus(null)` blurs. `focusin`/`focusout` notify; focus that merely
|
|
71
71
|
// leaves with the window (blur) keeps its widget, as GTK keeps it.
|
|
72
|
-
// `maximized` — the FRAME's state
|
|
73
|
-
//
|
|
72
|
+
// `maximized` — the FRAME's state, not the browser window's: a page cannot maximize its
|
|
73
|
+
// browser window. Square corners, and — as in GTK, where a maximized or
|
|
74
|
+
// fullscreen window ignores its default size and fills the work area — the frame
|
|
75
|
+
// fills its CONTAINING BLOCK (the viewport for a frame in a full-height body)
|
|
76
|
+
// until it is unmaximized, which restores `default-width`/`default-height`.
|
|
77
|
+
// `fullscreened` does the same. `maximize()`, `unmaximize()`, `fullscreen()`,
|
|
78
|
+
// `unfullscreen()` and `toggle-maximized` all write the attribute. `is_maximized()`
|
|
79
|
+
// reads it.
|
|
74
80
|
// `present()` — un-hides the frame; a page cannot raise or focus a window it does not own.
|
|
75
81
|
//
|
|
76
82
|
// THE GOBJECT DOOR (ADR 0096 § 3, ADR 0098 Amendment 3): `connect` / `disconnect` / `emit` /
|
|
@@ -92,6 +98,7 @@
|
|
|
92
98
|
|
|
93
99
|
import { CloseRequestState, WindowMemberState, type WindowMemberProperty } from '@gjsify/adwaita-core';
|
|
94
100
|
|
|
101
|
+
import { defineWindowApplication, type GtkApplication } from '../application.js';
|
|
95
102
|
import { installElementApi } from '../gobject-elements.js';
|
|
96
103
|
import type { DispatchedSignals } from '../signals.js';
|
|
97
104
|
import { bindSlottedChildren, type AdwSlot } from '../slotted-children.js';
|
|
@@ -99,9 +106,11 @@ import { bindSlottedChildren, type AdwSlot } from '../slotted-children.js';
|
|
|
99
106
|
// Registers <gtk-window-controls>: a frame with no titlebar of its own draws the two of them
|
|
100
107
|
// a server-side decoration would have, so importing the window alone must define them.
|
|
101
108
|
import './gtk-window-controls.js';
|
|
109
|
+
import { fillsContainingBlock } from './adw-window-features.js';
|
|
102
110
|
import type { WindowAction } from './gtk-window-controls.js';
|
|
111
|
+
import { WidgetElement } from '../widget-element.js';
|
|
103
112
|
|
|
104
|
-
export class GtkWindow extends
|
|
113
|
+
export class GtkWindow extends WidgetElement {
|
|
105
114
|
private _initialized = false;
|
|
106
115
|
/** The `titlebar` strip — `protected` so a subclass can place its own strips around it. */
|
|
107
116
|
protected _titlebar!: HTMLDivElement;
|
|
@@ -138,6 +147,7 @@ export class GtkWindow extends HTMLElement {
|
|
|
138
147
|
'close-request': 'close-request',
|
|
139
148
|
...Object.fromEntries(
|
|
140
149
|
[
|
|
150
|
+
'application',
|
|
141
151
|
'decorated',
|
|
142
152
|
'default-height',
|
|
143
153
|
'default-width',
|
|
@@ -156,6 +166,11 @@ export class GtkWindow extends HTMLElement {
|
|
|
156
166
|
),
|
|
157
167
|
};
|
|
158
168
|
|
|
169
|
+
/** `Gtk.Window:application`: setting it is `add_window` (ADR 0098), set by `defineWindowApplication`. */
|
|
170
|
+
declare application: GtkApplication | null;
|
|
171
|
+
declare get_application: () => GtkApplication | null;
|
|
172
|
+
declare set_application: (application: GtkApplication | null) => void;
|
|
173
|
+
|
|
159
174
|
/** `GObject.Object.connect`: installed per instance by `installElementApi`; refuses an undeclared signal. */
|
|
160
175
|
declare connect: (signal: string, handler: (emitter: this, ...args: any[]) => unknown) => number;
|
|
161
176
|
/** `GObject.Object.disconnect`: throws for an id that is not connected. */
|
|
@@ -239,6 +254,15 @@ export class GtkWindow extends HTMLElement {
|
|
|
239
254
|
this._write('maximized', String(value));
|
|
240
255
|
}
|
|
241
256
|
|
|
257
|
+
/** `Gtk.Window:fullscreened` — square corners, and the frame fills its containing block. */
|
|
258
|
+
get fullscreened(): boolean {
|
|
259
|
+
return this._offByDefault('fullscreened');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
set fullscreened(value: boolean) {
|
|
263
|
+
this._write('fullscreened', String(value));
|
|
264
|
+
}
|
|
265
|
+
|
|
242
266
|
/** `Gtk.Window:resizable` — whether the maximize button may appear. */
|
|
243
267
|
get resizable(): boolean {
|
|
244
268
|
return this._onByDefault('resizable');
|
|
@@ -300,7 +324,14 @@ export class GtkWindow extends HTMLElement {
|
|
|
300
324
|
this._content.className = 'adw-gtk-window-content';
|
|
301
325
|
|
|
302
326
|
bindSlottedChildren(this, [
|
|
303
|
-
|
|
327
|
+
// `child` only beside a titlebar: AdwWindow and AdwApplicationWindow inherit
|
|
328
|
+
// `Gtk.Window:child` and abort on it (adw-window.c:180), `content` is theirs.
|
|
329
|
+
...(this.hasTitlebar()
|
|
330
|
+
? [
|
|
331
|
+
{ name: 'titlebar', into: this._titlebar },
|
|
332
|
+
{ name: 'child', into: this._content },
|
|
333
|
+
]
|
|
334
|
+
: []),
|
|
304
335
|
...this.extraSlots(),
|
|
305
336
|
{ into: this._content },
|
|
306
337
|
]).install(...this.strips());
|
|
@@ -431,16 +462,18 @@ export class GtkWindow extends HTMLElement {
|
|
|
431
462
|
|
|
432
463
|
/**
|
|
433
464
|
* The frame's box from `default-width` / `default-height`; an absent one clears it. A subclass
|
|
434
|
-
* with a size request of its own (`Adw.Window`'s 360×200) replaces this.
|
|
465
|
+
* with a size request of its own (`Adw.Window`'s 360×200) replaces this. A maximized or
|
|
466
|
+
* fullscreened frame carries no inline size: the skin fills its containing block.
|
|
435
467
|
*/
|
|
436
468
|
protected renderFrameSize(): void {
|
|
469
|
+
const fills = fillsContainingBlock(this);
|
|
437
470
|
const width = Number.parseFloat(this.getAttribute('default-width') ?? '');
|
|
438
471
|
const height = Number.parseFloat(this.getAttribute('default-height') ?? '');
|
|
439
472
|
for (const [axis, value] of [
|
|
440
473
|
['width', width],
|
|
441
474
|
['height', height],
|
|
442
475
|
] as const) {
|
|
443
|
-
if (Number.isFinite(value) && value > 0) this.style.setProperty(axis, `${value}px`);
|
|
476
|
+
if (!fills && Number.isFinite(value) && value > 0) this.style.setProperty(axis, `${value}px`);
|
|
444
477
|
else this.style.removeProperty(axis);
|
|
445
478
|
}
|
|
446
479
|
}
|
|
@@ -598,6 +631,23 @@ export class GtkWindow extends HTMLElement {
|
|
|
598
631
|
unmaximize(): void {
|
|
599
632
|
this._write('maximized', 'false');
|
|
600
633
|
}
|
|
634
|
+
|
|
635
|
+
/** `gtk_window_is_fullscreen`: the FRAME's state, like {@link is_maximized}. */
|
|
636
|
+
is_fullscreen(): boolean {
|
|
637
|
+
return this.fullscreened;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/** `gtk_window_fullscreen`; asynchronous in GTK, so the property is written directly. */
|
|
641
|
+
fullscreen(): void {
|
|
642
|
+
this._write('fullscreened', 'true');
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/** `gtk_window_unfullscreen`, with the same caveat as {@link fullscreen}. */
|
|
646
|
+
unfullscreen(): void {
|
|
647
|
+
this._write('fullscreened', 'false');
|
|
648
|
+
}
|
|
601
649
|
}
|
|
602
650
|
|
|
603
651
|
customElements.define('gtk-window', GtkWindow);
|
|
652
|
+
|
|
653
|
+
defineWindowApplication(GtkWindow.prototype);
|
package/src/gio.spec.ts
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
|
-
// The `Gio.SimpleActionGroup` door of adwaita-web, held to the shared vectors (real GJS
|
|
2
|
-
// oracle, in adwaita-core's `simple-action-group.gjs.spec.ts`). The door is the namespace module itself.
|
|
1
|
+
// The `Gio.SimpleActionGroup` and `Gio.AppInfo` door of adwaita-web, held to the shared vectors (real GJS
|
|
2
|
+
// is their oracle, in adwaita-core's `simple-action-group.gjs.spec.ts` / `gio-app-info.gjs.spec.ts`). The door is the namespace module itself.
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
+
GIO_APP_INFO_VECTORS,
|
|
5
6
|
SIMPLE_ACTION_GROUP_VECTORS,
|
|
7
|
+
driveGioAppInfoVectors,
|
|
6
8
|
driveSimpleActionGroupVectors,
|
|
7
9
|
type GioActionsLike,
|
|
10
|
+
type GioAppInfoSubject,
|
|
8
11
|
} from '@gjsify/adwaita-core/conformance';
|
|
9
12
|
import { describe, expect, it } from '@gjsify/unit';
|
|
10
13
|
|
|
14
|
+
import * as Gdk from './namespace/gdk.js';
|
|
11
15
|
import * as Gio from './namespace/gio.js';
|
|
16
|
+
import * as GLib from './namespace/glib.js';
|
|
12
17
|
|
|
13
18
|
export const GioActionsTest = async () => {
|
|
14
19
|
await driveSimpleActionGroupVectors(
|
|
15
20
|
{ name: 'adwaita-web', isOracle: false, Gio: Gio as unknown as GioActionsLike },
|
|
16
21
|
{ describe, it, expect },
|
|
17
22
|
);
|
|
23
|
+
await driveGioAppInfoVectors(
|
|
24
|
+
{ name: 'adwaita-web', isOracle: false, display: true, Gio, GLib, Gdk } as unknown as GioAppInfoSubject,
|
|
25
|
+
{ describe, it, expect },
|
|
26
|
+
GIO_APP_INFO_VECTORS,
|
|
27
|
+
);
|
|
18
28
|
await describe('adwaita-web: Gio door', async () => {
|
|
19
29
|
await it('has a vector row for every vector', () => {
|
|
20
|
-
expect(SIMPLE_ACTION_GROUP_VECTORS.length > 0).toBe(true);
|
|
30
|
+
expect(SIMPLE_ACTION_GROUP_VECTORS.length > 0 && GIO_APP_INFO_VECTORS.length > 0).toBe(true);
|
|
21
31
|
});
|
|
22
32
|
});
|
|
23
33
|
};
|
package/src/glib.spec.ts
CHANGED
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
import {
|
|
6
6
|
GLIB_PATH_VECTORS,
|
|
7
7
|
GLIB_TIMER_VECTORS,
|
|
8
|
+
GLIB_URI_VECTORS,
|
|
8
9
|
driveGLibPathVectors,
|
|
9
10
|
driveGLibTimerVectors,
|
|
11
|
+
driveGLibUriVectors,
|
|
10
12
|
type GLibPathsLike,
|
|
11
13
|
type GLibTimersLike,
|
|
14
|
+
type GLibUriLike,
|
|
12
15
|
} from '@gjsify/adwaita-core/conformance';
|
|
13
16
|
import { describe, expect, it } from '@gjsify/unit';
|
|
14
17
|
|
|
@@ -36,6 +39,12 @@ export const GLibTest = async () => {
|
|
|
36
39
|
await driveGLibPathVectors(
|
|
37
40
|
{ name: 'adwaita-web', isOracle: false, GLib: GLib as unknown as GLibPathsLike },
|
|
38
41
|
{ describe, it, expect },
|
|
42
|
+
GLIB_PATH_VECTORS,
|
|
43
|
+
);
|
|
44
|
+
await driveGLibUriVectors(
|
|
45
|
+
{ name: 'adwaita-web', isOracle: false, GLib: GLib as unknown as GLibUriLike },
|
|
46
|
+
{ describe, it, expect },
|
|
47
|
+
GLIB_URI_VECTORS,
|
|
39
48
|
);
|
|
40
49
|
await describe('adwaita-web: GLib door', async () => {
|
|
41
50
|
await it('answers the host-bound path questions with the root and no data dirs', () => {
|
package/src/gobject-elements.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { attributeOf, propertyOf } from '@gjsify/adwaita-core/tags';
|
|
18
18
|
|
|
19
19
|
import { dispatchedSignalsOf } from './signals.js';
|
|
20
|
+
import { watchMapping } from './widget-mapping.js';
|
|
20
21
|
|
|
21
22
|
type Handler = (emitter: HTMLElement, ...args: unknown[]) => unknown;
|
|
22
23
|
|
|
@@ -60,7 +61,7 @@ function inheritedDescriptor(el: object, member: string): PropertyDescriptor | u
|
|
|
60
61
|
return undefined;
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
function notifyElement(el: HTMLElement, name: string): void {
|
|
64
|
+
export function notifyElement(el: HTMLElement, name: string): void {
|
|
64
65
|
const member = propertyOf(name);
|
|
65
66
|
el.dispatchEvent(
|
|
66
67
|
new CustomEvent(eventOf(el, `notify::${name}`), {
|
|
@@ -122,7 +123,12 @@ export function listenElement(el: HTMLElement, signal: string, handler: Handler)
|
|
|
122
123
|
}
|
|
123
124
|
};
|
|
124
125
|
el.addEventListener(event, listener);
|
|
125
|
-
|
|
126
|
+
// `map` / `unmap` have no DOM event behind them: the element is watched while one is connected.
|
|
127
|
+
const unwatch = signal === 'map' || signal === 'unmap' ? watchMapping(el) : undefined;
|
|
128
|
+
return () => {
|
|
129
|
+
el.removeEventListener(event, listener);
|
|
130
|
+
unwatch?.();
|
|
131
|
+
};
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
export function dispatchElement(el: HTMLElement, signal: string, args: readonly unknown[]): void {
|
|
@@ -154,6 +160,42 @@ export function installSensitive(el: HTMLElement): void {
|
|
|
154
160
|
});
|
|
155
161
|
}
|
|
156
162
|
|
|
163
|
+
const VISIBLE_INSTALLED = new WeakSet<Element>();
|
|
164
|
+
|
|
165
|
+
/** The `visible` getters `WidgetElement` puts on its prototype, so a class's own accessor tells apart. */
|
|
166
|
+
export const WIDGET_VISIBLE_GETTERS = new WeakSet<() => boolean>();
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Whether `el` has the port's `visible` — from `installVisible` or from `WidgetElement`. An
|
|
170
|
+
* element with its own `visible` (`<gtk-stack-page>`) keeps its own and answers false.
|
|
171
|
+
*/
|
|
172
|
+
export function hasInstalledVisible(el: Element): boolean {
|
|
173
|
+
if (VISIBLE_INSTALLED.has(el)) return true;
|
|
174
|
+
const getter = inheritedDescriptor(el, 'visible')?.get;
|
|
175
|
+
return getter !== undefined && WIDGET_VISIBLE_GETTERS.has(getter as () => boolean);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* `Gtk.Widget:visible` for an element that has no member of that name: `gtk_widget_get_visible`
|
|
180
|
+
* and `gtk_widget_set_visible` over the DOM's `hidden` attribute, TRUE until hidden as GtkWidget's
|
|
181
|
+
* default is. It notifies only where the element declares `notify::visible`. An element that already declares `visible` (`<gtk-stack-page>`, `<adw-sidebar>`)
|
|
182
|
+
* keeps its own, and so does a registered class whose prototype has the port's members.
|
|
183
|
+
*/
|
|
184
|
+
export function installVisible(el: HTMLElement): void {
|
|
185
|
+
if ('visible' in el) return;
|
|
186
|
+
VISIBLE_INSTALLED.add(el);
|
|
187
|
+
const define = (name: string, descriptor: PropertyDescriptor) =>
|
|
188
|
+
Object.defineProperty(el, name, { configurable: true, enumerable: false, ...descriptor });
|
|
189
|
+
const set = (value: unknown): void => {
|
|
190
|
+
const before = !el.hidden;
|
|
191
|
+
el.toggleAttribute('hidden', !value);
|
|
192
|
+
if (!el.hidden !== before && 'notify::visible' in dispatchedSignalsOf(el)) notifyElement(el, 'visible');
|
|
193
|
+
};
|
|
194
|
+
define('visible', { get: () => !el.hidden, set });
|
|
195
|
+
if (!('get_visible' in el)) define('get_visible', { value: () => !el.hidden, writable: true });
|
|
196
|
+
if (!('set_visible' in el)) define('set_visible', { value: set, writable: true });
|
|
197
|
+
}
|
|
198
|
+
|
|
157
199
|
/** Gives `el` the instance API of a registered class, over the events it declares. */
|
|
158
200
|
export function installElementApi(el: HTMLElement): void {
|
|
159
201
|
// A registered class already has the core's four methods on its prototype.
|
package/src/gtk-label.spec.ts
CHANGED
|
@@ -325,6 +325,45 @@ export const GtkLabelTest = async () => {
|
|
|
325
325
|
host.remove();
|
|
326
326
|
});
|
|
327
327
|
|
|
328
|
+
// GtkLabel's wrapping MINIMUM is its longest word, not the width it first wrapped
|
|
329
|
+
// at. A pinned `width` made the measured block the label's min-content, so a card
|
|
330
|
+
// around it in a narrower pane (Learn6502's preferences: 343px) grew past the pane.
|
|
331
|
+
await it('lets a wrapped label shrink below the width it first wrapped at', () => {
|
|
332
|
+
const long = 'word '.repeat(60).trim();
|
|
333
|
+
const { el, host } = mount(long);
|
|
334
|
+
host.style.display = 'flex';
|
|
335
|
+
const card = document.createElement('div');
|
|
336
|
+
host.appendChild(card);
|
|
337
|
+
card.appendChild(el);
|
|
338
|
+
el.wrap = true;
|
|
339
|
+
const first = el.querySelector('.adw-label-text')!.getBoundingClientRect().width;
|
|
340
|
+
expect(first > 300).toBe(true);
|
|
341
|
+
host.style.width = '200px';
|
|
342
|
+
expect(card.getBoundingClientRect().width <= 200).toBe(true);
|
|
343
|
+
expect(el.getBoundingClientRect().width <= 200).toBe(true);
|
|
344
|
+
host.remove();
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// gtk_label_measure: a wrapping label's minimum is its widest word, its natural
|
|
348
|
+
// width the text on one line (capped only by `max-width-chars`).
|
|
349
|
+
await it('gives a wrapped label its widest word as minimum, one line as natural', () => {
|
|
350
|
+
const long = 'word '.repeat(60).trim();
|
|
351
|
+
const { el, host } = mount(long);
|
|
352
|
+
el.wrap = true;
|
|
353
|
+
const word = mount('word');
|
|
354
|
+
const wordWidth = textRect(word.el).width;
|
|
355
|
+
word.host.remove();
|
|
356
|
+
const line = mount(long);
|
|
357
|
+
line.host.style.width = 'max-content';
|
|
358
|
+
const lineWidth = textRect(line.el).width;
|
|
359
|
+
line.host.remove();
|
|
360
|
+
host.style.width = 'min-content';
|
|
361
|
+
expect(el.getBoundingClientRect().width <= Math.ceil(wordWidth) + 1).toBe(true);
|
|
362
|
+
host.style.width = 'max-content';
|
|
363
|
+
expect(Math.abs(el.getBoundingClientRect().width - lineWidth) <= 1).toBe(true);
|
|
364
|
+
host.remove();
|
|
365
|
+
});
|
|
366
|
+
|
|
328
367
|
await it('is not selectable unless asked, as GtkLabel', () => {
|
|
329
368
|
const { el, host } = mount('Hi');
|
|
330
369
|
expect(getComputedStyle(el).userSelect).toBe('none');
|
|
@@ -216,24 +216,24 @@ export const GtkScrolledWindowTest = async () => {
|
|
|
216
216
|
await fill(el, 10);
|
|
217
217
|
// No request is made until one of the two asks for it: GTK only measures the
|
|
218
218
|
// child when `propagate-natural-*` or a NEVER policy does (gtkscrolledwindow.c:1841-1844).
|
|
219
|
-
expect(el.viewport.style.
|
|
219
|
+
expect(el.viewport.style.height).toBe('');
|
|
220
220
|
// The NATURAL request is the child's `max-content` size, propagated up.
|
|
221
221
|
el.setAttribute('propagate-natural-height', '');
|
|
222
222
|
expect(el.propagateNaturalHeight).toBe(true);
|
|
223
|
-
expect(el.viewport.style.
|
|
223
|
+
expect(el.viewport.style.height).toBe('max-content');
|
|
224
224
|
// A NEVER policy adds the child's MINIMUM request instead — and the natural one
|
|
225
225
|
// is the larger of the two, so it wins when both are asked for. Both are FALSE in
|
|
226
226
|
// the pspec, so their ATTRIBUTE is their presence, as `has-frame` is.
|
|
227
227
|
el.removeAttribute('propagate-natural-height');
|
|
228
228
|
el.setAttribute('vscrollbar-policy', 'never');
|
|
229
|
-
expect(el.viewport.style.
|
|
229
|
+
expect(el.viewport.style.height).toBe('min-content');
|
|
230
230
|
// With both asked for on ONE axis the natural wins, and the other axis keeps
|
|
231
231
|
// its own answer.
|
|
232
232
|
el.setAttribute('propagate-natural-width', '');
|
|
233
|
-
expect(el.viewport.style.
|
|
234
|
-
expect(el.viewport.style.
|
|
233
|
+
expect(el.viewport.style.width).toBe('max-content');
|
|
234
|
+
expect(el.viewport.style.height).toBe('min-content');
|
|
235
235
|
el.setAttribute('propagate-natural-height', '');
|
|
236
|
-
expect(el.viewport.style.
|
|
236
|
+
expect(el.viewport.style.height).toBe('max-content');
|
|
237
237
|
host.remove();
|
|
238
238
|
});
|
|
239
239
|
});
|