@gjsify/adwaita-web 0.64.2-next.252 → 0.64.2-next.255
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 +10 -80
- package/dist/adwaita-web.css +52 -3
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/accessible.d.ts +8 -0
- package/lib/types/compute-expand.d.ts +5 -0
- package/lib/types/compute-expand.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 +3 -2
- 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 +2 -1
- 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-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-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-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.d.ts +2 -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 +2 -1
- 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 +2 -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 +2 -1
- package/lib/types/gobject-elements.d.ts +7 -1
- 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 +1 -2
- 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/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/package.json +12 -12
- package/scss/_about_dialog.scss +46 -1
- package/scss/_checks.scss +5 -2
- package/scss/_icon.scss +3 -4
- package/scss/_labels.scss +2 -2
- package/scss/_overlay_split_view.scss +10 -0
- package/scss/_scrolled_window.scss +15 -0
- package/scss/_widget.scss +5 -1
- 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-button-content.spec.ts +1 -1
- package/src/adw-carousel.spec.ts +49 -1
- package/src/capabilities.mjs +1 -0
- package/src/checks.spec.ts +51 -1
- package/src/compute-expand.spec.ts +186 -0
- package/src/compute-expand.ts +134 -0
- package/src/construct-vectors.spec.ts +46 -1
- 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 +3 -2
- 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 +2 -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 +2 -1
- 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 +2 -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 +2 -1
- 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-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-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 +2 -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-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 +2 -1
- 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 +2 -1
- 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 +2 -1
- 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 +2 -1
- package/src/elements/gtk-paned.ts +2 -1
- package/src/elements/gtk-picture.ts +2 -1
- package/src/elements/gtk-popover-bin.ts +2 -1
- package/src/elements/gtk-popover-menu-bar.ts +2 -1
- package/src/elements/gtk-popover.ts +2 -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 +2 -1
- 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 +2 -1
- package/src/elements/gtk-stack-sidebar.ts +2 -1
- package/src/elements/gtk-stack-switcher.ts +2 -1
- package/src/elements/gtk-stack.ts +2 -1
- 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 +2 -1
- package/src/elements/gtk-video.ts +2 -1
- package/src/elements/gtk-viewport.ts +2 -1
- package/src/elements/gtk-window-controls.ts +2 -1
- package/src/elements/gtk-window-handle.ts +2 -1
- package/src/elements/gtk-window.ts +2 -1
- package/src/gio.spec.ts +13 -3
- package/src/glib.spec.ts +9 -0
- package/src/gobject-elements.ts +18 -4
- package/src/gtk-label.spec.ts +39 -0
- package/src/gtk-scrolled-window.spec.ts +6 -6
- 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 +3 -7
- package/src/namespace/gdk.ts +1 -0
- package/src/namespace/gio.ts +8 -0
- package/src/namespace/glib.ts +4 -0
- package/src/shared-tree-builder.ts +26 -3
- package/src/signals.ts +11 -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 +6 -2
- 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 +44 -0
- package/lib/types/icon-registry.d.ts +0 -37
- package/src/icon-registry.ts +0 -163
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
|
|
94
94
|
import type { DispatchedSignals } from '../signals.js';
|
|
95
95
|
import { STACK_PAGE_ATTRIBUTES, pageChildOf } from './gtk-stack-page.js';
|
|
96
|
+
import { WidgetElement } from '../widget-element.js';
|
|
96
97
|
|
|
97
98
|
/** `GtkStackTransitionType`, spelled as the GIR's enum nicks (gtkstack.c:95-121). */
|
|
98
99
|
export type StackTransitionType =
|
|
@@ -226,7 +227,7 @@ export interface GtkStackPageInfo {
|
|
|
226
227
|
/** The five `GtkStackPage` string/boolean properties this element reads off a child. */
|
|
227
228
|
const PAGE_ATTRIBUTES = ['name', 'title', 'icon-name', 'use-underline', 'needs-attention'];
|
|
228
229
|
|
|
229
|
-
export class GtkStack extends
|
|
230
|
+
export class GtkStack extends WidgetElement {
|
|
230
231
|
/** The GTK signals this element dispatches, each with the DOM event it arrives as (ADR 0093). */
|
|
231
232
|
static readonly signals: DispatchedSignals = {
|
|
232
233
|
'notify::visible-child': 'notify::visible-child',
|
|
@@ -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;
|
|
@@ -60,11 +60,12 @@ import {
|
|
|
60
60
|
|
|
61
61
|
import { createGtkImage } from './gtk-image.js';
|
|
62
62
|
import { bindSlottedChildren } from '../slotted-children.js';
|
|
63
|
+
import { WidgetElement } from '../widget-element.js';
|
|
63
64
|
|
|
64
65
|
/** `TIMEOUT_EXPAND` — how long a drag hovers before the row opens (gtktreeexpander.c:717). */
|
|
65
66
|
const TIMEOUT_EXPAND = 500;
|
|
66
67
|
|
|
67
|
-
export class GtkTreeExpander extends
|
|
68
|
+
export class GtkTreeExpander extends WidgetElement {
|
|
68
69
|
private _ornaments: HTMLElement[] = [];
|
|
69
70
|
private _expandTimer: ReturnType<typeof setTimeout> | null = null;
|
|
70
71
|
private _initialized = false;
|
|
@@ -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;
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
import { clampAdjustmentValue, normalizeAdjustment, type AdwAdjustment } from '@gjsify/adwaita-core';
|
|
67
67
|
|
|
68
68
|
import { bindSlottedChildren } from '../slotted-children.js';
|
|
69
|
+
import { WidgetElement } from '../widget-element.js';
|
|
69
70
|
|
|
70
71
|
/** `viewport_set_adjustment_values`'s two fractions of the visible size. */
|
|
71
72
|
const STEP_FRACTION = 0.1;
|
|
@@ -94,7 +95,7 @@ function axisAdjustment(clip: HTMLElement, axis: Axis): AdwAdjustment {
|
|
|
94
95
|
});
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
export class GtkViewport extends
|
|
98
|
+
export class GtkViewport extends WidgetElement {
|
|
98
99
|
private _observer: ResizeObserver | null = null;
|
|
99
100
|
private _watch: MutationObserver | null = null;
|
|
100
101
|
|
|
@@ -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`). */
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
// Modifications: Implemented as a Web Component for @gjsify/adwaita-web.
|
|
48
48
|
|
|
49
49
|
import { bindSlottedChildren } from '../slotted-children.js';
|
|
50
|
+
import { WidgetElement } from '../widget-element.js';
|
|
50
51
|
|
|
51
52
|
/** `GtkTitlebarGesture`'s three gestures, as `perform_titlebar_action` decides them. */
|
|
52
53
|
export type GtkTitlebarGesture = 'double-click' | 'middle-click' | 'right-click';
|
|
@@ -114,7 +115,7 @@ function gestureOf(button: number, presses: number): GtkTitlebarGesture | null {
|
|
|
114
115
|
*/
|
|
115
116
|
const DRAG_THRESHOLD = 1;
|
|
116
117
|
|
|
117
|
-
export class GtkWindowHandle extends
|
|
118
|
+
export class GtkWindowHandle extends WidgetElement {
|
|
118
119
|
/** The gesture in progress, as `priv->drag_start_x` / `_y` are in the C. */
|
|
119
120
|
private _drag: { pointerId: number; x: number; y: number } | null = null;
|
|
120
121
|
|
|
@@ -108,8 +108,9 @@ import { bindSlottedChildren, type AdwSlot } from '../slotted-children.js';
|
|
|
108
108
|
import './gtk-window-controls.js';
|
|
109
109
|
import { fillsContainingBlock } from './adw-window-features.js';
|
|
110
110
|
import type { WindowAction } from './gtk-window-controls.js';
|
|
111
|
+
import { WidgetElement } from '../widget-element.js';
|
|
111
112
|
|
|
112
|
-
export class GtkWindow extends
|
|
113
|
+
export class GtkWindow extends WidgetElement {
|
|
113
114
|
private _initialized = false;
|
|
114
115
|
/** The `titlebar` strip — `protected` so a subclass can place its own strips around it. */
|
|
115
116
|
protected _titlebar!: HTMLDivElement;
|
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 {
|
|
@@ -156,9 +162,17 @@ export function installSensitive(el: HTMLElement): void {
|
|
|
156
162
|
|
|
157
163
|
const VISIBLE_INSTALLED = new WeakSet<Element>();
|
|
158
164
|
|
|
159
|
-
/**
|
|
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
|
+
*/
|
|
160
172
|
export function hasInstalledVisible(el: Element): boolean {
|
|
161
|
-
|
|
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);
|
|
162
176
|
}
|
|
163
177
|
|
|
164
178
|
/**
|
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
|
});
|
|
@@ -20,8 +20,15 @@
|
|
|
20
20
|
import { describe, it, expect } from '@gjsify/unit';
|
|
21
21
|
|
|
22
22
|
import { GtkAdjustment, GtkStringList } from '@gjsify/adwaita-core';
|
|
23
|
+
import {
|
|
24
|
+
ROW_ACCESSOR_VECTORS,
|
|
25
|
+
driveRowAccessorVectors,
|
|
26
|
+
type ComboRowLike,
|
|
27
|
+
type SwitchRowLike,
|
|
28
|
+
} from '@gjsify/adwaita-core/conformance';
|
|
23
29
|
|
|
24
30
|
import type { AdwComboRow } from './elements/adw-combo-row.js';
|
|
31
|
+
import type { AdwSwitchRow } from './elements/adw-switch-row.js';
|
|
25
32
|
import type { AdwSpinRow } from './elements/adw-spin-row.js';
|
|
26
33
|
import type { GtkDropDown } from './elements/gtk-drop-down.js';
|
|
27
34
|
|
|
@@ -101,4 +108,16 @@ export const GtkValueDoorsTest = async () => {
|
|
|
101
108
|
expect(row.value).toBe(16);
|
|
102
109
|
});
|
|
103
110
|
});
|
|
111
|
+
|
|
112
|
+
await driveRowAccessorVectors(
|
|
113
|
+
{
|
|
114
|
+
name: 'adwaita-web',
|
|
115
|
+
isOracle: false,
|
|
116
|
+
makeComboRow: () => mount<AdwComboRow>('adw-combo-row') as unknown as ComboRowLike,
|
|
117
|
+
makeSwitchRow: () => mount<AdwSwitchRow>('adw-switch-row') as unknown as SwitchRowLike,
|
|
118
|
+
StringList: GtkStringList,
|
|
119
|
+
},
|
|
120
|
+
{ describe, it, expect },
|
|
121
|
+
ROW_ACCESSOR_VECTORS,
|
|
122
|
+
);
|
|
104
123
|
};
|
package/src/gtk-window.spec.ts
CHANGED
|
@@ -310,11 +310,11 @@ export const GtkWindowTest = async () => {
|
|
|
310
310
|
const { el, host } = mount();
|
|
311
311
|
let message = '';
|
|
312
312
|
try {
|
|
313
|
-
el.connect('
|
|
313
|
+
el.connect('toggled', () => {});
|
|
314
314
|
} catch (error) {
|
|
315
315
|
message = (error as Error).message;
|
|
316
316
|
}
|
|
317
|
-
expect(message.includes("'
|
|
317
|
+
expect(message.includes("'toggled'")).toBe(true);
|
|
318
318
|
host.remove();
|
|
319
319
|
});
|
|
320
320
|
|
|
@@ -20,6 +20,7 @@ import type { Buffer, Gutter } from '@gjsify/gtksource-core';
|
|
|
20
20
|
import { EditorSession, GutterSet, STOP_EMISSION, toBoolean, toNumber } from '@gjsify/gtksource-core';
|
|
21
21
|
|
|
22
22
|
import { WebEditorDriver } from './web-editor-driver.js';
|
|
23
|
+
import { WidgetElement } from '../widget-element.js';
|
|
23
24
|
|
|
24
25
|
const STYLE_ID = 'gjsify-gtk-source-view-style';
|
|
25
26
|
|
|
@@ -130,7 +131,7 @@ const OBSERVED_ATTRIBUTES = [
|
|
|
130
131
|
'bottom-margin',
|
|
131
132
|
];
|
|
132
133
|
|
|
133
|
-
export class GtkSourceView extends
|
|
134
|
+
export class GtkSourceView extends WidgetElement {
|
|
134
135
|
static get observedAttributes(): string[] {
|
|
135
136
|
return OBSERVED_ATTRIBUTES;
|
|
136
137
|
}
|
|
@@ -14,17 +14,12 @@
|
|
|
14
14
|
// that was never given draws nothing at all.
|
|
15
15
|
import { describe, expect, it } from '@gjsify/unit';
|
|
16
16
|
|
|
17
|
-
import { isIconAvailable
|
|
17
|
+
import { isIconAvailable } from './icon-theme.js';
|
|
18
18
|
import type { GtkImage } from './elements/gtk-image.js';
|
|
19
19
|
|
|
20
20
|
/** A name no compiled entry can collide with, for the "not shipped" arm. */
|
|
21
21
|
const ABSENT = 'gjsify-registry-probe';
|
|
22
22
|
|
|
23
|
-
/** An Adwaita symbolic SVG, small and distinctive — a filled 8px square in the 16px grid. */
|
|
24
|
-
const PROBE_SVG = `<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
|
25
|
-
<path d="m 4 4 h 8 v 8 h -8 z m 0 0" fill="currentColor"/>
|
|
26
|
-
</svg>`;
|
|
27
|
-
|
|
28
23
|
function mount(iconName: string | null): { el: GtkImage; host: HTMLElement } {
|
|
29
24
|
const host = document.createElement('div');
|
|
30
25
|
document.body.appendChild(host);
|
|
@@ -55,7 +50,7 @@ export function fallbackMask(): string {
|
|
|
55
50
|
return getComputedStyle(document.documentElement).getPropertyValue('--icon-image-missing').trim();
|
|
56
51
|
}
|
|
57
52
|
|
|
58
|
-
export const
|
|
53
|
+
export const AdwIconMasksTest = async () => {
|
|
59
54
|
await describe('<gtk-image> resolves a name to a real mask', async () => {
|
|
60
55
|
await it('a compiled name draws its OWN glyph, not the fallback', () => {
|
|
61
56
|
const { el, host } = mount('go-next');
|
|
@@ -136,8 +131,8 @@ export const AdwIconRegistryTest = async () => {
|
|
|
136
131
|
});
|
|
137
132
|
});
|
|
138
133
|
|
|
139
|
-
await describe('
|
|
140
|
-
await it('
|
|
134
|
+
await describe('isIconAvailable', async () => {
|
|
135
|
+
await it('answers for the compiled set and nothing else', () => {
|
|
141
136
|
expect(isIconAvailable(ABSENT)).toBe(false);
|
|
142
137
|
// …and a compiled one as available, so the check is not answering `false` to
|
|
143
138
|
// everything. `image-missing` is the case a fallback-comparison would get wrong.
|
|
@@ -145,96 +140,5 @@ export const AdwIconRegistryTest = async () => {
|
|
|
145
140
|
expect(isIconAvailable('image-missing')).toBe(true);
|
|
146
141
|
expect(isIconAvailable('')).toBe(false);
|
|
147
142
|
});
|
|
148
|
-
|
|
149
|
-
await it('makes the name resolve, on an element that is ALREADY mounted', () => {
|
|
150
|
-
const { el, host } = mount(ABSENT);
|
|
151
|
-
const before = maskOf(el);
|
|
152
|
-
expect(before).toBe(fallbackMask());
|
|
153
|
-
|
|
154
|
-
registerIcon(ABSENT, PROBE_SVG);
|
|
155
|
-
|
|
156
|
-
const after = maskOf(el);
|
|
157
|
-
expect(after).not.toBe(before);
|
|
158
|
-
expect(after).not.toBe(fallbackMask());
|
|
159
|
-
// The glyph really is the SVG that was handed over: `toDataUri` percent-encodes
|
|
160
|
-
// it, so the path data survives as `m%204%204`.
|
|
161
|
-
expect(after.includes('m%204%204')).toBe(true);
|
|
162
|
-
expect(isIconAvailable(ABSENT)).toBe(true);
|
|
163
|
-
host.remove();
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
await it('serves an element mounted AFTER the registration too', () => {
|
|
167
|
-
const { el, host } = mount(`${ABSENT}-symbolic`);
|
|
168
|
-
// The `-symbolic` suffix is stripped on both sides, so a consumer may spell the
|
|
169
|
-
// name either way at either end.
|
|
170
|
-
expect(el.resolvedIconName).toBe(ABSENT);
|
|
171
|
-
expect(maskOf(el).includes('m%204%204')).toBe(true);
|
|
172
|
-
host.remove();
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
await it('re-registering REPLACES the glyph without a second rule', () => {
|
|
176
|
-
const sheet = (document.getElementById('adwaita-web-icon-registry') as HTMLStyleElement).sheet;
|
|
177
|
-
const rulesBefore = (sheet as CSSStyleSheet).cssRules.length;
|
|
178
|
-
|
|
179
|
-
registerIcon(ABSENT, PROBE_SVG.replace('m 4 4 h 8 v 8 h -8 z', 'm 2 2 h 12 v 12 h -12 z'));
|
|
180
|
-
|
|
181
|
-
const { el, host } = mount(ABSENT);
|
|
182
|
-
expect(maskOf(el).includes('m%202%202')).toBe(true);
|
|
183
|
-
expect((sheet as CSSStyleSheet).cssRules.length).toBe(rulesBefore);
|
|
184
|
-
host.remove();
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
await it('throws on a name that could never be one CSS class', () => {
|
|
188
|
-
// Silently registering nothing is the exact failure this area exists to end, and
|
|
189
|
-
// unlike a render this is an explicit call with a wrong argument.
|
|
190
|
-
expect(() => registerIcon('org.gnome.Builder', PROBE_SVG)).toThrow();
|
|
191
|
-
expect(() => registerIcon('a b', PROBE_SVG)).toThrow();
|
|
192
|
-
expect(() => registerIcon('', PROBE_SVG)).toThrow();
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
await it('throws on a payload that is not SVG source, and registers nothing', () => {
|
|
196
|
-
// The NAME was checked from the start; the payload was not, and a wrong payload
|
|
197
|
-
// is worse than no registration at all: `toDataUri` percent-encodes anything, so
|
|
198
|
-
// the mask comes out well-formed and masks NOTHING, the registered class beats
|
|
199
|
-
// `:where(.adw-icon)` and switches this PR's fallback off, and `isIconAvailable`
|
|
200
|
-
// answers `true`. Measured in Firefox before the guard: `'not an svg at all'`
|
|
201
|
-
// gave `url("data:image/svg+xml,not%20an%20svg%20at%20all")` on a box painted 0 %,
|
|
202
|
-
// where the unregistered control painted the 30 % image-missing glyph.
|
|
203
|
-
const REJECTED = 'gjsify-registry-payload-probe';
|
|
204
|
-
expect(() => registerIcon(REJECTED, 'not an svg at all')).toThrow();
|
|
205
|
-
expect(() => registerIcon(REJECTED, '')).toThrow();
|
|
206
|
-
// The likeliest wrong argument of all: what the custom property HOLDS, handed
|
|
207
|
-
// over instead of what it was made from.
|
|
208
|
-
expect(() => registerIcon(REJECTED, 'url("data:image/svg+xml,%3Csvg%3E%3C/svg%3E")')).toThrow();
|
|
209
|
-
expect(isIconAvailable(REJECTED)).toBe(false);
|
|
210
|
-
|
|
211
|
-
const { el, host } = mount(REJECTED);
|
|
212
|
-
expect(maskOf(el)).toBe(fallbackMask());
|
|
213
|
-
host.remove();
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
await it('rebuilds its rules after the <style> element is taken away', () => {
|
|
217
|
-
// What an SPA head swap or an Astro view transition does. The record of inserted
|
|
218
|
-
// rules is module-level and outlives the element it describes, so the early
|
|
219
|
-
// return above used to skip the insert forever: the custom property was re-set
|
|
220
|
-
// and the rule that consumes it never came back.
|
|
221
|
-
const LOST = 'gjsify-registry-sheet-probe';
|
|
222
|
-
registerIcon(LOST, PROBE_SVG);
|
|
223
|
-
document.getElementById('adwaita-web-icon-registry')?.remove();
|
|
224
|
-
|
|
225
|
-
registerIcon(LOST, PROBE_SVG);
|
|
226
|
-
|
|
227
|
-
expect(document.getElementById('adwaita-web-icon-registry')).not.toBe(null);
|
|
228
|
-
const { el, host } = mount(LOST);
|
|
229
|
-
expect(maskOf(el).includes('m%204%204')).toBe(true);
|
|
230
|
-
host.remove();
|
|
231
|
-
|
|
232
|
-
// …and the names registered BEFORE the swap are on the rebuilt sheet too. Their
|
|
233
|
-
// custom properties survived on the document element, so re-issuing only the
|
|
234
|
-
// one name being registered would leave every earlier icon on the fallback.
|
|
235
|
-
const { el: earlier, host: earlierHost } = mount(ABSENT);
|
|
236
|
-
expect(maskOf(earlier)).not.toBe(fallbackMask());
|
|
237
|
-
earlierHost.remove();
|
|
238
|
-
});
|
|
239
143
|
});
|
|
240
144
|
};
|