@gjsify/adwaita-web 0.64.13-next.283 → 0.64.14
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/lib/types/application.d.ts +3 -3
- package/lib/types/elements/adw-application-window.d.ts +4 -4
- package/lib/types/elements/adw-bin.d.ts +13 -0
- package/lib/types/elements/adw-split-button.d.ts +19 -28
- package/lib/types/elements/adw-tab-overview.d.ts +4 -4
- package/lib/types/elements/gtk-menu-button.d.ts +30 -42
- package/lib/types/elements/gtk-popover-bin.d.ts +18 -11
- package/lib/types/elements/gtk-popover-menu-bar.d.ts +15 -8
- package/lib/types/elements/gtk-popover-menu.d.ts +13 -15
- package/lib/types/elements/menu-slot.d.ts +49 -0
- package/lib/types/elements/popover-menu.d.ts +11 -7
- package/lib/types/index.d.ts +2 -1
- package/lib/types/namespace/gio.d.ts +1 -1
- package/lib/types/widget-element.d.ts +8 -2
- package/package.json +12 -13
- package/src/adw-application-window.spec.ts +5 -2
- package/src/adw-bin.spec.ts +20 -0
- package/src/application.ts +4 -4
- package/src/elements/adw-application-window.ts +17 -21
- package/src/elements/adw-bin.ts +20 -1
- package/src/elements/adw-split-button.ts +35 -59
- package/src/elements/adw-tab-overview.ts +18 -28
- package/src/elements/gtk-menu-button.ts +60 -82
- package/src/elements/gtk-popover-bin.ts +32 -38
- package/src/elements/gtk-popover-menu-bar.ts +41 -46
- package/src/elements/gtk-popover-menu.ts +35 -54
- package/src/elements/menu-slot.ts +139 -0
- package/src/elements/popover-menu.ts +26 -16
- package/src/gio-menu.spec.ts +173 -34
- package/src/gtk-image.spec.ts +3 -2
- package/src/gtk-menu-button.spec.ts +19 -16
- package/src/gtk-popover-bin.spec.ts +6 -5
- package/src/gtk-popover-menu-bar.spec.ts +11 -6
- package/src/gtk-popover-menu.spec.ts +22 -22
- package/src/index.ts +10 -2
- package/src/keyboard-operable.spec.ts +6 -5
- package/src/menu-actions.spec.ts +6 -1
- package/src/namespace/gio.ts +19 -2
- package/src/pango-markup.spec.ts +11 -0
- package/src/pango-markup.ts +5 -2
- package/src/shared-tree-builder.ts +6 -1
- package/src/split-button.spec.ts +25 -8
- package/src/widget-element.ts +28 -7
- package/src/widget-members.spec.ts +42 -3
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { GioApplicationBase, type AdwMenuItem, type AdwMenuActions, type
|
|
1
|
+
import { GioApplicationBase, type AdwMenuItem, type AdwMenuActions, type AdwMenuTree, type ApplicationHost } from '@gjsify/adwaita-core';
|
|
2
2
|
export declare const webHost: ApplicationHost;
|
|
3
3
|
/** An element's parent for action resolution; a popover is rooted at the widget that owns it. */
|
|
4
4
|
export declare function parentOfElement(node: object): object | null;
|
|
5
5
|
/** What a `Gtk.Actionable` does on activation: the action `prefix.name` found from `widget`. */
|
|
6
6
|
export declare function activateWidgetAction(widget: Element, fullName: string, parameter?: unknown): boolean;
|
|
7
|
-
/** What the items of `
|
|
8
|
-
export declare function menuActionsOfElement(el: Element,
|
|
7
|
+
/** What the items of `tree` read from the actions registered above `el` (ADR 0097 § 3). */
|
|
8
|
+
export declare function menuActionsOfElement(el: Element, tree: AdwMenuTree): AdwMenuActions;
|
|
9
9
|
/** What choosing `item` in a menu owned by `el` does: the action it names fires. */
|
|
10
10
|
export declare function activateElementMenuItem(el: Element, item: AdwMenuItem): boolean;
|
|
11
11
|
export declare class GioApplication extends GioApplicationBase {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AdwMenuModel } from '@gjsify/adwaita-core';
|
|
2
2
|
import type { AdwBreakpoint } from '@gjsify/adwaita-core';
|
|
3
3
|
import type { AdwSlot } from '../slotted-children.js';
|
|
4
4
|
import { GtkApplicationWindow } from './gtk-application-window.js';
|
|
5
5
|
export declare class AdwApplicationWindow extends GtkApplicationWindow {
|
|
6
6
|
private readonly _features;
|
|
7
|
-
private
|
|
7
|
+
private readonly _slot;
|
|
8
8
|
private _menubarEl;
|
|
9
9
|
static get observedAttributes(): string[];
|
|
10
10
|
/** The content area — the Adw.Window:content property. */
|
|
@@ -20,8 +20,8 @@ export declare class AdwApplicationWindow extends GtkApplicationWindow {
|
|
|
20
20
|
get showMenubar(): boolean;
|
|
21
21
|
set showMenubar(value: boolean);
|
|
22
22
|
/** The menubar's model — what a GtkApplication would own here. */
|
|
23
|
-
get menuModel(): AdwMenuModel;
|
|
24
|
-
set menuModel(value:
|
|
23
|
+
get menuModel(): AdwMenuModel | null;
|
|
24
|
+
set menuModel(value: AdwMenuModel | string | null);
|
|
25
25
|
/** The menubar strip, or null before the window is connected. */
|
|
26
26
|
get menubar(): HTMLDivElement | null;
|
|
27
27
|
connectedCallback(): void;
|
|
@@ -5,6 +5,19 @@ export declare class AdwBin extends WidgetElement {
|
|
|
5
5
|
get child(): Element | null;
|
|
6
6
|
/** `adw_bin_set_child`: replace the current child, unparenting it. */
|
|
7
7
|
set child(value: Element | null);
|
|
8
|
+
/**
|
|
9
|
+
* `adw_bin_get_child` / `adw_bin_set_child` — the METHOD spelling of {@link child}.
|
|
10
|
+
*
|
|
11
|
+
* The property alone is not the whole door. `Adw.Bin:child` is reached two ways and only
|
|
12
|
+
* one of them is a property: markup writes `child:`, but code built against GI calls
|
|
13
|
+
* `bin.get_child()` / `bin.set_child(w)`, which is the spelling a `.blp`-driven widget
|
|
14
|
+
* shared across renderers uses — GJS and the NativeScript bridge both answer it
|
|
15
|
+
* (`AdwSingleChildBase`), and here it was missing, so the shared code died with
|
|
16
|
+
* `get_child is not a function` on the web and nowhere else.
|
|
17
|
+
*/
|
|
18
|
+
get_child(): Element | null;
|
|
19
|
+
/** `adw_bin_set_child`. Refuses a child that already has a parent, as {@link setChild} does. */
|
|
20
|
+
set_child(child: Element | null): void;
|
|
8
21
|
connectedCallback(): void;
|
|
9
22
|
disconnectedCallback(): void;
|
|
10
23
|
/**
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import type { AdwMenuActions,
|
|
1
|
+
import type { AdwMenuActions, AdwMenuModel, SplitButtonDirection } from '@gjsify/adwaita-core';
|
|
2
2
|
import './gtk-popover.js';
|
|
3
3
|
import { WidgetElement } from '../widget-element.js';
|
|
4
4
|
export declare class AdwSplitButton extends WidgetElement {
|
|
5
5
|
private readonly _state;
|
|
6
|
+
/**
|
|
7
|
+
* The model's door, tree snapshot and `items-changed` subscription (ADR 0128). The
|
|
8
|
+
* STATE still owns the menu as a property — `dropdownEnabled` is derived from it and
|
|
9
|
+
* the notify order is libadwaita's — so every write here goes through the slot FIRST
|
|
10
|
+
* (which is what refuses it and snapshots it) and is then handed to the state.
|
|
11
|
+
*/
|
|
12
|
+
private readonly _slot;
|
|
6
13
|
private _actionEl;
|
|
7
14
|
private _dropdownEl;
|
|
8
15
|
private _arrowEl;
|
|
@@ -24,39 +31,23 @@ export declare class AdwSplitButton extends WidgetElement {
|
|
|
24
31
|
/** The symbolic icon name, or `null` when the action half shows a label or nothing. */
|
|
25
32
|
get iconName(): string | null;
|
|
26
33
|
set iconName(value: string);
|
|
27
|
-
/** The menu, normalised (ADR 0042). Empty when the dropdown has none. */
|
|
28
|
-
get menuModel(): AdwMenuModel;
|
|
29
34
|
/**
|
|
30
|
-
*
|
|
31
|
-
* descriptors, sections, submenus.
|
|
35
|
+
* The menu the dropdown pops up, by identity, or `null` when it has none (ADR 0128).
|
|
32
36
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
37
|
+
* `null` is the ONLY spelling of "no menu" now: an empty model is a menu, so an empty
|
|
38
|
+
* one leaves the dropdown enabled exactly as it does in GTK, where a non-null model
|
|
39
|
+
* still builds a popover (measured, `MENU_MODEL_DOOR_VECTORS`).
|
|
36
40
|
*/
|
|
37
|
-
|
|
41
|
+
get menuModel(): AdwMenuModel | null;
|
|
38
42
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* The property setter is not the only way a menu arrives: an attribute is, and the
|
|
42
|
-
* first cut refused only the setter, so a `custom` item written in markup drew
|
|
43
|
-
* exactly the row `assertMenuRenderable` exists to prevent — one that reads like a
|
|
44
|
-
* command and does nothing.
|
|
45
|
-
*
|
|
46
|
-
* THE TWO DOORS REFUSE DIFFERENTLY, and the difference is which side can hear it.
|
|
47
|
-
* A property assignment is a CALL, so it throws and the caller can catch. An
|
|
48
|
-
* attribute is MARKUP, parsed by the browser: a throw from `connectedCallback` is
|
|
49
|
-
* not delivered to whoever appended the element, it is reported as an uncaught
|
|
50
|
-
* page error — measured, it broke `adwaita-upgrade-order.spec.ts`, which counts
|
|
51
|
-
* exactly those. Nobody can handle it and everybody else pays for it. So the
|
|
52
|
-
* attribute path REFUSES THE MENU (no menu, and a menu-less dropdown is
|
|
53
|
-
* insensitive, which is visible) and says why on `console.error`.
|
|
43
|
+
* Take a real model, a JSON string in the portable spelling, or `null`.
|
|
54
44
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
45
|
+
* The REFUSAL is at the assignment rather than at render time: a `custom` item names
|
|
46
|
+
* an application widget this surface cannot host, and discovering that as a blank row
|
|
47
|
+
* three interactions later is what the refusal exists to prevent. {@link MenuSlot}
|
|
48
|
+
* owns the door; the state is handed only a menu this surface agreed to draw.
|
|
58
49
|
*/
|
|
59
|
-
|
|
50
|
+
set menuModel(value: AdwMenuModel | string | null);
|
|
60
51
|
/**
|
|
61
52
|
* What the action group publishes about the actions this menu names — the portable
|
|
62
53
|
* stand-in for a `GActionGroup`, and the ONLY place a menu's enabled/checked state
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AdwMenuModel } from '@gjsify/adwaita-core';
|
|
2
2
|
import type { AdwTabView } from './adw-tab-view.js';
|
|
3
3
|
import { WidgetElement } from '../widget-element.js';
|
|
4
4
|
export declare class AdwTabOverview extends WidgetElement {
|
|
@@ -20,7 +20,7 @@ export declare class AdwTabOverview extends WidgetElement {
|
|
|
20
20
|
private _newTabBtn;
|
|
21
21
|
private readonly _thumbs;
|
|
22
22
|
private _view;
|
|
23
|
-
private
|
|
23
|
+
private readonly _slot;
|
|
24
24
|
private _searchActive;
|
|
25
25
|
private _initialized;
|
|
26
26
|
/** The last visibility actually painted, so `notify::open` fires on a real change. */
|
|
@@ -66,8 +66,8 @@ export declare class AdwTabOverview extends WidgetElement {
|
|
|
66
66
|
get enableNewTab(): boolean;
|
|
67
67
|
set enableNewTab(value: boolean);
|
|
68
68
|
/** `Adw.TabOverview:secondary-menu` — the portal menu of extra actions. */
|
|
69
|
-
get secondaryMenu(): AdwMenuModel;
|
|
70
|
-
set secondaryMenu(value:
|
|
69
|
+
get secondaryMenu(): AdwMenuModel | null;
|
|
70
|
+
set secondaryMenu(value: AdwMenuModel | string | null);
|
|
71
71
|
/** `Adw.TabOverview:show-start-title-buttons`, TRUE upstream, so `="false"` turns it off. */
|
|
72
72
|
get showStartTitleButtons(): boolean;
|
|
73
73
|
set showStartTitleButtons(value: boolean);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { AdwMenuActions,
|
|
1
|
+
import type { AdwMenuActions, AdwMenuModel, SplitButtonDirection } from '@gjsify/adwaita-core';
|
|
2
2
|
import './gtk-popover.js';
|
|
3
3
|
import { WidgetElement } from '../widget-element.js';
|
|
4
4
|
export declare class GtkMenuButton extends WidgetElement {
|
|
5
5
|
private _buttonEl;
|
|
6
6
|
private _popoverEl;
|
|
7
|
-
|
|
7
|
+
/** The model, its tree snapshot and its `items-changed` subscription (ADR 0128). */
|
|
8
|
+
private readonly _slot;
|
|
8
9
|
private _actions;
|
|
9
10
|
private _menuTitle;
|
|
10
11
|
private _initialized;
|
|
@@ -12,41 +13,26 @@ export declare class GtkMenuButton extends WidgetElement {
|
|
|
12
13
|
static get observedAttributes(): string[];
|
|
13
14
|
/** Whether the popover menu is currently open. */
|
|
14
15
|
get active(): boolean;
|
|
15
|
-
/** The menu, normalised (ADR 0042). Setting rebuilds the popover. */
|
|
16
|
-
get menuModel(): AdwMenuModel;
|
|
17
16
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* The menu this button pops up, BY IDENTITY — the model itself, `null` when there is
|
|
18
|
+
* none, exactly as `gtk_menu_button_get_menu_model` answers (ADR 0128).
|
|
19
|
+
*
|
|
20
|
+
* It no longer answers an array, and `[]` is no longer how "no menu" is spelled: an
|
|
21
|
+
* EMPTY model is a menu that GTK still builds a popover for, and `null` is the one
|
|
22
|
+
* spelling of its absence (measured, `MENU_MODEL_DOOR_VECTORS`).
|
|
21
23
|
*/
|
|
22
|
-
|
|
23
|
-
/** `Gtk.MenuButton:menu-model` — the GIR spelling of {@link menuModel}. */
|
|
24
|
-
get menu_model(): AdwMenuModel;
|
|
25
|
-
set menu_model(value: AdwMenuInput);
|
|
26
|
-
get_menu_model(): AdwMenuModel;
|
|
27
|
-
set_menu_model(value: AdwMenuInput): void;
|
|
24
|
+
get menuModel(): AdwMenuModel | null;
|
|
28
25
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* first cut refused only the setter, so a `custom` item written in markup drew
|
|
33
|
-
* exactly the row `assertMenuRenderable` exists to prevent — one that reads like a
|
|
34
|
-
* command and does nothing.
|
|
35
|
-
*
|
|
36
|
-
* THE TWO DOORS REFUSE DIFFERENTLY, and the difference is which side can hear it.
|
|
37
|
-
* A property assignment is a CALL, so it throws and the caller can catch. An
|
|
38
|
-
* attribute is MARKUP, parsed by the browser: a throw from `connectedCallback` is
|
|
39
|
-
* not delivered to whoever appended the element, it is reported as an uncaught
|
|
40
|
-
* page error — measured, it broke `adwaita-upgrade-order.spec.ts`, which counts
|
|
41
|
-
* exactly those. Nobody can handle it and everybody else pays for it. So the
|
|
42
|
-
* attribute path REFUSES THE MENU (no menu, and a menu-less dropdown is
|
|
43
|
-
* insensitive, which is visible) and says why on `console.error`.
|
|
44
|
-
*
|
|
45
|
-
* A REFUSAL AND A TYPO ARE STILL DIFFERENT THINGS. `parseMenuModel` is total
|
|
46
|
-
* because malformed JSON is an author slip and must not stop the element
|
|
47
|
-
* upgrading; `custom` is well-formed, deliberate, and unhonourable here.
|
|
26
|
+
* Take a real model, a JSON string in the portable spelling, or `null`. Refused HERE,
|
|
27
|
+
* at the assignment, for a `custom` item this surface cannot host — {@link MenuSlot}
|
|
28
|
+
* owns both doors and the note on why they refuse differently.
|
|
48
29
|
*/
|
|
49
|
-
|
|
30
|
+
set menuModel(value: AdwMenuModel | string | null);
|
|
31
|
+
/** `Gtk.MenuButton:menu-model` — the GIR spelling of {@link menuModel}. */
|
|
32
|
+
get menu_model(): AdwMenuModel | null;
|
|
33
|
+
set menu_model(value: AdwMenuModel | string | null);
|
|
34
|
+
get_menu_model(): AdwMenuModel | null;
|
|
35
|
+
set_menu_model(value: AdwMenuModel | string | null): void;
|
|
50
36
|
/**
|
|
51
37
|
* What the action group publishes about the actions this menu names — the portable
|
|
52
38
|
* stand-in for a `GActionGroup`, and the only source of a menu's enabled/checked
|
|
@@ -62,18 +48,20 @@ export declare class GtkMenuButton extends WidgetElement {
|
|
|
62
48
|
set direction(value: SplitButtonDirection);
|
|
63
49
|
connectedCallback(): void;
|
|
64
50
|
attributeChangedCallback(name: string): void;
|
|
65
|
-
/**
|
|
66
|
-
* The `menu-model` attribute, through the core parser both elements share.
|
|
67
|
-
*
|
|
68
|
-
* The copy this replaces was weaker in a way markup can reach: it kept `id` and
|
|
69
|
-
* `icon` WHATEVER their runtime type, so `{"label":"Open","id":7}` produced an
|
|
70
|
-
* entry whose `id` is a number in a field typed `string` — and `id` is what the
|
|
71
|
-
* activation event reports. The core parser keeps only string-typed attributes.
|
|
72
|
-
*/
|
|
73
|
-
private _parseMenuAttr;
|
|
74
51
|
private _onPopoverToggled;
|
|
75
52
|
private _render;
|
|
76
53
|
/** The registry's answer, unless the application wrote `actions` itself (ADR 0097 § 2). */
|
|
77
54
|
private _refreshActions;
|
|
55
|
+
/**
|
|
56
|
+
* `gtk_menu_button_set_menu_model` notifies UNCONDITIONALLY — no identity guard, so the
|
|
57
|
+
* same model written twice notifies twice and `null` over `null` notifies as well
|
|
58
|
+
* (measured, `MENU_MODEL_NOTIFY_VECTORS`). Its `Adw.SplitButton` sibling guards on
|
|
59
|
+
* pointer equality, and the two disagree on purpose: a port with one rule for both is
|
|
60
|
+
* wrong about one of them.
|
|
61
|
+
*
|
|
62
|
+
* A MUTATION of the held model is not a write and notifies nothing — it arrives over
|
|
63
|
+
* `items-changed`, where it redraws the rows and stops.
|
|
64
|
+
*/
|
|
65
|
+
private _notifyModel;
|
|
78
66
|
private _renderMenu;
|
|
79
67
|
}
|
|
@@ -1,22 +1,29 @@
|
|
|
1
|
-
import type { AdwMenuActions,
|
|
1
|
+
import type { AdwMenuActions, AdwMenuModel } from '@gjsify/adwaita-core';
|
|
2
2
|
import './gtk-popover-menu.js';
|
|
3
3
|
import type { GtkPopoverMenu } from './gtk-popover-menu.js';
|
|
4
4
|
import { WidgetElement } from '../widget-element.js';
|
|
5
5
|
export declare class GtkPopoverBin extends WidgetElement {
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The model's door and `items-changed` subscription (ADR 0128), with NOTHING to do
|
|
8
|
+
* when the menu it holds mutates: this bin draws no rows. The `<gtk-popover-menu>` it
|
|
9
|
+
* built holds the SAME model and watches it through a slot of its own, so the rows
|
|
10
|
+
* follow one level down — and GTK sends no `notify::menu-model` for a mutation either
|
|
11
|
+
* (measured, `MENU_MODEL_NOTIFY_VECTORS`).
|
|
12
|
+
*/
|
|
13
|
+
private readonly _slot;
|
|
7
14
|
private _popover;
|
|
8
15
|
private _actions;
|
|
9
16
|
private _initialized;
|
|
10
17
|
private _longPressTimer;
|
|
11
18
|
static get observedAttributes(): string[];
|
|
12
|
-
/** The menu
|
|
13
|
-
get menuModel(): AdwMenuModel;
|
|
19
|
+
/** The menu this bin pops up, by identity, or `null` (ADR 0128). */
|
|
20
|
+
get menuModel(): AdwMenuModel | null;
|
|
14
21
|
/**
|
|
15
22
|
* The model the popover is built from — ONE slot with `popover`, because GTK's two
|
|
16
23
|
* setters clear each other (gtkpopoverbin.c:474-500, :543-551). A model REPLACES the
|
|
17
24
|
* popover; a popover DROPS the model, and both notify for both properties.
|
|
18
25
|
*/
|
|
19
|
-
set menuModel(value:
|
|
26
|
+
set menuModel(value: AdwMenuModel | string | null);
|
|
20
27
|
/**
|
|
21
28
|
* The popover this bin presents, or `null`.
|
|
22
29
|
*
|
|
@@ -61,6 +68,12 @@ export declare class GtkPopoverBin extends WidgetElement {
|
|
|
61
68
|
* un-modified key beside Shift is the whole binding here.
|
|
62
69
|
*/
|
|
63
70
|
private _onKeyDown;
|
|
71
|
+
/**
|
|
72
|
+
* The popover follows the PRESENCE of a model, not its length: an empty non-null
|
|
73
|
+
* `Gio.Menu` at `menu-model` still builds a `GtkPopoverMenu` in GTK and still
|
|
74
|
+
* dissociates an application-set popover (measured, `MENU_MODEL_DOOR_VECTORS`), and
|
|
75
|
+
* `null` is the one spelling of "no menu".
|
|
76
|
+
*/
|
|
64
77
|
private _buildPopover;
|
|
65
78
|
/**
|
|
66
79
|
* `set_popover` (gtkpopoverbin.c:543-587): hide and unparent the old one, parent the
|
|
@@ -74,10 +87,4 @@ export declare class GtkPopoverBin extends WidgetElement {
|
|
|
74
87
|
* of its own to report.
|
|
75
88
|
*/
|
|
76
89
|
private _notifyModel;
|
|
77
|
-
/**
|
|
78
|
-
* The `menu-model` ATTRIBUTE through the core parser, refusing a `custom` item the way
|
|
79
|
-
* every menu-bearing surface here does: markup is parsed by the browser, so a throw from
|
|
80
|
-
* `connectedCallback` would reach nobody and the menu would be silently empty.
|
|
81
|
-
*/
|
|
82
|
-
private _parseMenuAttr;
|
|
83
90
|
}
|
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
import type { AdwMenuActions,
|
|
1
|
+
import type { AdwMenuActions, AdwMenuModel } from '@gjsify/adwaita-core';
|
|
2
2
|
import './gtk-popover-menu.js';
|
|
3
3
|
import { WidgetElement } from '../widget-element.js';
|
|
4
4
|
export declare class GtkPopoverMenuBar extends WidgetElement {
|
|
5
|
-
|
|
5
|
+
/** The model, its tree snapshot and its `items-changed` subscription (ADR 0128). */
|
|
6
|
+
private readonly _slot;
|
|
6
7
|
private _actions;
|
|
7
8
|
private _items;
|
|
8
9
|
private _active;
|
|
9
10
|
private _initialized;
|
|
10
11
|
static get observedAttributes(): string[];
|
|
11
|
-
/** The menu
|
|
12
|
-
get menuModel(): AdwMenuModel;
|
|
13
|
-
set menuModel(value:
|
|
12
|
+
/** The menu this bar draws, by identity, or `null` (ADR 0128). */
|
|
13
|
+
get menuModel(): AdwMenuModel | null;
|
|
14
|
+
set menuModel(value: AdwMenuModel | string | null);
|
|
15
|
+
/**
|
|
16
|
+
* The one place a changed menu is answered — from either door AND from a mutation of
|
|
17
|
+
* the menu the bar is holding, which is why the `console.warn` below is here rather
|
|
18
|
+
* than beside the attribute parse it used to live in: a toplevel entry that is not a
|
|
19
|
+
* submenu can arrive by `append_item` just as easily as by markup.
|
|
20
|
+
*/
|
|
21
|
+
private _menuChanged;
|
|
14
22
|
/** What the action group publishes about the actions these menus name (ADR 0042). */
|
|
15
23
|
get actions(): AdwMenuActions | null;
|
|
16
24
|
set actions(value: AdwMenuActions | null);
|
|
@@ -51,8 +59,8 @@ export declare class GtkPopoverMenuBar extends WidgetElement {
|
|
|
51
59
|
/**
|
|
52
60
|
* One `menubar > item > popover` (the node tree in gtkpopovermenubar.c:38-46).
|
|
53
61
|
*
|
|
54
|
-
* A toplevel node that is not a submenu is
|
|
55
|
-
* wording rather than drawn: `tracker_insert` builds nothing for it
|
|
62
|
+
* A toplevel node that is not a submenu is WARNED about by {@link _menuChanged} with
|
|
63
|
+
* GTK's own wording rather than drawn: `tracker_insert` builds nothing for it
|
|
56
64
|
* (gtkpopovermenubar.c:466), and a row that opens nothing is the same lie in another
|
|
57
65
|
* shape.
|
|
58
66
|
*/
|
|
@@ -63,5 +71,4 @@ export declare class GtkPopoverMenuBar extends WidgetElement {
|
|
|
63
71
|
* row is not the row that opened a submenu (gtkpopovermenu.c:257-259).
|
|
64
72
|
*/
|
|
65
73
|
private _activate;
|
|
66
|
-
private _parseMenuAttr;
|
|
67
74
|
}
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import type { AdwMenuActions,
|
|
1
|
+
import type { AdwMenuActions, AdwMenuModel } from '@gjsify/adwaita-core';
|
|
2
2
|
import { GtkPopover } from './gtk-popover.js';
|
|
3
3
|
export declare class GtkPopoverMenu extends GtkPopover {
|
|
4
|
-
|
|
4
|
+
/** The model, its tree snapshot and its `items-changed` subscription (ADR 0128). */
|
|
5
|
+
private readonly _slot;
|
|
5
6
|
private _actions;
|
|
6
7
|
private _menuView;
|
|
7
8
|
/** Named apart from `GtkPopover`'s own: two `private` fields of one name are two fields. */
|
|
8
9
|
private _menuInitialized;
|
|
9
10
|
static get observedAttributes(): string[];
|
|
10
|
-
/** The menu,
|
|
11
|
-
get menuModel(): AdwMenuModel;
|
|
11
|
+
/** The menu this popover draws, by identity, or `null` (ADR 0128). */
|
|
12
|
+
get menuModel(): AdwMenuModel | null;
|
|
12
13
|
/**
|
|
13
|
-
*
|
|
14
|
-
* HERE — at the assignment, where it is a call the caller can catch.
|
|
15
|
-
* markup the browser parses, so
|
|
16
|
-
* says why on `console.error
|
|
14
|
+
* Take a real model, a JSON string in the portable spelling, or `null`, refusing a
|
|
15
|
+
* `custom` item HERE — at the assignment, where it is a call the caller can catch.
|
|
16
|
+
* An ATTRIBUTE is markup the browser parses, so that path refuses the whole menu and
|
|
17
|
+
* says why on `console.error`; {@link MenuSlot} owns both doors.
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* straight back. The one cast is where the core's parameter type (`AdwMenuInput`, whose
|
|
22
|
-
* entries are the AUTHORED shapes) is narrower than the behaviour it documents.
|
|
19
|
+
* A REAL MODEL IS WHAT A MENU BAR HANDS OVER for one of its submenus, and the model
|
|
20
|
+
* it hands over is `buildMenu(node.items)` — a menu of its own rather than this
|
|
21
|
+
* element's authored one, so the two cannot overwrite each other.
|
|
23
22
|
*/
|
|
24
|
-
set menuModel(value:
|
|
23
|
+
set menuModel(value: AdwMenuModel | string | null);
|
|
25
24
|
/** What the action group publishes about the actions this menu names (ADR 0042). */
|
|
26
25
|
get actions(): AdwMenuActions | null;
|
|
27
26
|
set actions(value: AdwMenuActions | null);
|
|
@@ -81,5 +80,4 @@ export declare class GtkPopoverMenu extends GtkPopover {
|
|
|
81
80
|
*/
|
|
82
81
|
private _activate;
|
|
83
82
|
private _renderMenu;
|
|
84
|
-
private _parseMenuAttr;
|
|
85
83
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AdwMenuTree, GioMenuModel } from '@gjsify/adwaita-core';
|
|
2
|
+
export declare class MenuSlot {
|
|
3
|
+
private readonly onItemsChanged;
|
|
4
|
+
/**
|
|
5
|
+
* The menu this element OWNS, so an edit to the same `menu-model="[…]"` attribute is a
|
|
6
|
+
* content change rather than a new menu — the popover already open follows it instead of
|
|
7
|
+
* being rebuilt (ADR 0128 § 5, the same rule `GjsifyOptionList` has for a list).
|
|
8
|
+
*/
|
|
9
|
+
private readonly _authored;
|
|
10
|
+
private _model;
|
|
11
|
+
private _tree;
|
|
12
|
+
private _unwatch;
|
|
13
|
+
/** @param onItemsChanged what to do when the HELD menu mutates under the element. */
|
|
14
|
+
constructor(onItemsChanged: () => void);
|
|
15
|
+
/** The model itself, by identity — what `menuModel` answers and what a child is handed. */
|
|
16
|
+
get model(): GioMenuModel | null;
|
|
17
|
+
/** The snapshot every walker reads. Re-taken on each `items-changed`, never aliased. */
|
|
18
|
+
get tree(): AdwMenuTree;
|
|
19
|
+
/**
|
|
20
|
+
* Whether there is anything to show — NOT whether there is a menu.
|
|
21
|
+
*
|
|
22
|
+
* `null` and an empty `Gio.Menu` are different menus and GTK treats them differently: an
|
|
23
|
+
* empty non-null model still builds a `GtkPopoverMenu` and still dissociates an
|
|
24
|
+
* application-set popover (measured, `MENU_MODEL_DOOR_VECTORS`). This answers the
|
|
25
|
+
* question the ROWS ask — "is there a row to draw" — and the elements ask
|
|
26
|
+
* `model === null` where GTK asks about the model.
|
|
27
|
+
*/
|
|
28
|
+
get isEmpty(): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* A PROPERTY write: a real model by identity, a JSON string into the authored menu,
|
|
31
|
+
* `null` for no menu — and a `TypeError` for an array, which this door no longer takes
|
|
32
|
+
* (`buildMenu` is how an array becomes a model now).
|
|
33
|
+
*
|
|
34
|
+
* A REFUSAL PUTS THE AUTHORED MENU BACK, because the door has already reconciled it by
|
|
35
|
+
* the time the tree can be refused: without the restore a refused string would leave the
|
|
36
|
+
* element holding a menu it threw over, and the next render would draw it.
|
|
37
|
+
*/
|
|
38
|
+
write(value: unknown): void;
|
|
39
|
+
/**
|
|
40
|
+
* The `menu-model` ATTRIBUTE, through the same door. A `null` attribute is no menu.
|
|
41
|
+
*
|
|
42
|
+
* A REFUSAL AND A TYPO ARE STILL DIFFERENT THINGS: `parseMenuModel` is total because
|
|
43
|
+
* malformed JSON is an author slip that must not stop the element upgrading, while a
|
|
44
|
+
* `custom` item is well-formed, deliberate, and unhonourable on this surface.
|
|
45
|
+
*/
|
|
46
|
+
writeMarkup(value: string | null): void;
|
|
47
|
+
/** Hold `next`, snapshot it, and listen to it — the three that always happen together. */
|
|
48
|
+
private _adopt;
|
|
49
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AdwMenuActions,
|
|
1
|
+
import type { AdwMenuActions, AdwMenuPath, AdwMenuTree } from '@gjsify/adwaita-core';
|
|
2
2
|
import type { GtkPopover } from './gtk-popover.js';
|
|
3
3
|
/**
|
|
4
4
|
* Called when the reader chooses an item, with the path that addresses it in the WHOLE
|
|
@@ -19,7 +19,7 @@ export declare class PopoverMenuView {
|
|
|
19
19
|
/** Class prefix for the element's own hooks — `adw-menu-button`, `adw-split-button-menu`. */
|
|
20
20
|
private readonly prefix;
|
|
21
21
|
private readonly onActivate;
|
|
22
|
-
private
|
|
22
|
+
private _tree;
|
|
23
23
|
private _actions;
|
|
24
24
|
private _title;
|
|
25
25
|
/** The submenu whose items are showing; `[]` is the root page. */
|
|
@@ -28,7 +28,7 @@ export declare class PopoverMenuView {
|
|
|
28
28
|
private _openers;
|
|
29
29
|
/** The row that LEAVES a page — what ArrowLeft acts on. */
|
|
30
30
|
private _backRow;
|
|
31
|
-
/** The canonical text of the
|
|
31
|
+
/** The canonical text of the tree showing, so an unchanged re-render keeps the page. */
|
|
32
32
|
private _key;
|
|
33
33
|
private _rows;
|
|
34
34
|
constructor(surface: GtkPopover,
|
|
@@ -90,13 +90,17 @@ export declare class PopoverMenuView {
|
|
|
90
90
|
*/
|
|
91
91
|
private focusPage;
|
|
92
92
|
/**
|
|
93
|
-
* Named for the value it takes,
|
|
93
|
+
* Named for the value it takes, which since ADR 0128 is a TREE and not a model: this
|
|
94
|
+
* view never holds a `Gio.MenuModel`, it walks the snapshot its element took, and a
|
|
95
|
+
* `setMenuModel` here would name a type it has no way to read. The element is the one
|
|
96
|
+
* place that owns the model.
|
|
97
|
+
*
|
|
98
|
+
* It was `setMenuModel` for the reason the rename keeps: the portable LIST model gave
|
|
94
99
|
* `ComboState` a `setModel` (ADR 0046), and two methods called `setModel` over two
|
|
95
100
|
* unrelated values on one surface is the collision the vocabulary work exists to
|
|
96
|
-
* remove.
|
|
97
|
-
* collection call by the setter's name.
|
|
101
|
+
* remove.
|
|
98
102
|
*/
|
|
99
|
-
|
|
103
|
+
setMenuTree(tree: AdwMenuTree): void;
|
|
100
104
|
setActions(actions: AdwMenuActions | null): void;
|
|
101
105
|
setTitle(title: string): void;
|
|
102
106
|
/** Return to the root page — called when the popover closes. */
|
package/lib/types/index.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export { AdwBottomSheetBottomBar, AdwBottomSheetContent, AdwBottomSheetSheet } f
|
|
|
32
32
|
export { AdwAlertResponse } from './elements/adw-alert-dialog.js';
|
|
33
33
|
export type { GtkPopoverAlign, GtkPopoverPosition, GtkPopoverRole } from './elements/gtk-popover.js';
|
|
34
34
|
export type { AdwViewStackPageInfo } from './elements/adw-view-stack.js';
|
|
35
|
-
export
|
|
35
|
+
export { buildMenu, menuTree, watchMenuModel } from '@gjsify/adwaita-core';
|
|
36
|
+
export type { AdwMenuActions, AdwMenuEntryInput, AdwMenuInput, AdwMenuItem, AdwMenuModel, AdwMenuNode, AdwMenuPath, AdwMenuSection, AdwMenuSubmenu, AdwMenuTree, } from '@gjsify/adwaita-core';
|
|
36
37
|
export type { GtkDropDownOption } from './elements/gtk-drop-down.js';
|
|
37
38
|
export type { AdwDialogPresentationMode } from './elements/adw-dialog.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '../file-chooser-host.js';
|
|
2
|
-
export { GioMenu as Menu, GioMenuItem as MenuItem } from '@gjsify/adwaita-core';
|
|
2
|
+
export { GioMenu as Menu, GioMenuItem as MenuItem, GioMenuModel as MenuModel, GioMenuAttributeIter as MenuAttributeIter, GioMenuLinkIter as MenuLinkIter, MENU_ATTRIBUTE_ACTION, MENU_ATTRIBUTE_ACTION_NAMESPACE, MENU_ATTRIBUTE_ICON, MENU_ATTRIBUTE_LABEL, MENU_ATTRIBUTE_TARGET, MENU_EXPORTER_MAX_SECTION_SIZE, MENU_LINK_SECTION, MENU_LINK_SUBMENU, } from '@gjsify/adwaita-core';
|
|
3
3
|
export { ListModel } from '@gjsify/adwaita-core';
|
|
4
4
|
export { GioFile as File, GioListStore as ListStore, GioOutputStream as OutputStream, GioFileOutputStream as FileOutputStream, FileCreateFlags, IOErrorEnum, promisify as _promisify, } from '@gjsify/adwaita-core';
|
|
5
5
|
export { SimpleAction, SimpleActionGroup, ApplicationFlags } from '@gjsify/adwaita-core';
|
|
@@ -9,7 +9,13 @@ export declare class WidgetElement extends HTMLElement {
|
|
|
9
9
|
get_visible(): boolean;
|
|
10
10
|
/** `gtk_widget_set_visible`. */
|
|
11
11
|
set_visible(visible: boolean): void;
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* `gtk_widget_get_first_child`: the first child WIDGET, `null` for a leaf.
|
|
14
|
+
*
|
|
15
|
+
* The five walkers skip the elements a port builds for its own insides — `isWidgetNode`
|
|
16
|
+
* in `@gjsify/adwaita-core` carries the rule and the incident behind it, and the
|
|
17
|
+
* registered-class copy in `widgetTreeMembers()` answers from the same function.
|
|
18
|
+
*/
|
|
13
19
|
get_first_child(): Element | null;
|
|
14
20
|
/** `gtk_widget_get_last_child`. */
|
|
15
21
|
get_last_child(): Element | null;
|
|
@@ -17,7 +23,7 @@ export declare class WidgetElement extends HTMLElement {
|
|
|
17
23
|
get_next_sibling(): Element | null;
|
|
18
24
|
/** `gtk_widget_get_prev_sibling`. */
|
|
19
25
|
get_prev_sibling(): Element | null;
|
|
20
|
-
/** `gtk_widget_get_parent
|
|
26
|
+
/** `gtk_widget_get_parent`: the nearest ancestor that is a widget, not a port's own wrapper. */
|
|
21
27
|
get_parent(): Element | null;
|
|
22
28
|
/** `gtk_widget_get_width`: the layout box in CSS px; 0 until the widget is rendered. */
|
|
23
29
|
get_width(): number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/adwaita-web",
|
|
3
|
-
"version": "0.64.
|
|
3
|
+
"version": "0.64.14",
|
|
4
4
|
"description": "Adwaita/Libadwaita web components for browser targets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
"@codemirror/language": "^6.12.4",
|
|
59
59
|
"@codemirror/state": "^6.7.0",
|
|
60
60
|
"@codemirror/view": "^6.43.4",
|
|
61
|
-
"@gjsify/adwaita-core": "0.64.
|
|
62
|
-
"@gjsify/adwaita-fonts": "0.64.
|
|
63
|
-
"@gjsify/adwaita-icons": "0.64.
|
|
64
|
-
"@gjsify/gtksource-core": "0.64.
|
|
61
|
+
"@gjsify/adwaita-core": "^0.64.14",
|
|
62
|
+
"@gjsify/adwaita-fonts": "^0.64.14",
|
|
63
|
+
"@gjsify/adwaita-icons": "^0.64.14",
|
|
64
|
+
"@gjsify/gtksource-core": "^0.64.14",
|
|
65
65
|
"@lezer/highlight": "^1.2.3"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
|
-
"@gjsify/app-settings": "0.64.
|
|
68
|
+
"@gjsify/app-settings": "^0.64.14"
|
|
69
69
|
},
|
|
70
70
|
"peerDependenciesMeta": {
|
|
71
71
|
"@gjsify/app-settings": {
|
|
@@ -73,11 +73,11 @@
|
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@gjsify/app-settings": "0.64.
|
|
77
|
-
"@gjsify/blueprint": "0.64.
|
|
78
|
-
"@gjsify/cli": "0.64.
|
|
79
|
-
"@gjsify/unit": "0.64.
|
|
80
|
-
"@gjsify/vite-plugin-blueprint": "0.64.
|
|
76
|
+
"@gjsify/app-settings": "^0.64.14",
|
|
77
|
+
"@gjsify/blueprint": "^0.64.14",
|
|
78
|
+
"@gjsify/cli": "^0.64.14",
|
|
79
|
+
"@gjsify/unit": "^0.64.14",
|
|
80
|
+
"@gjsify/vite-plugin-blueprint": "^0.64.14",
|
|
81
81
|
"sass": "^1.101.0",
|
|
82
82
|
"typescript": "^6.0.3"
|
|
83
83
|
},
|
|
@@ -114,6 +114,5 @@
|
|
|
114
114
|
"bugs": {
|
|
115
115
|
"url": "https://github.com/gjsify/gjsify/issues"
|
|
116
116
|
},
|
|
117
|
-
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/web/adwaita-web#readme"
|
|
118
|
-
"gitHead": "05fae97125a374e84bf57c2d2d086fb53523f205"
|
|
117
|
+
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/web/adwaita-web#readme"
|
|
119
118
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// <adw-window>'s spec and only the delta is asserted here.
|
|
9
9
|
import { describe, it, expect } from '@gjsify/unit';
|
|
10
10
|
import { driveWindowVectors, WINDOW_VECTORS } from '@gjsify/adwaita-core/conformance';
|
|
11
|
+
import { menuTree } from '@gjsify/adwaita-core';
|
|
11
12
|
|
|
12
13
|
import { webWindowSubject } from './gtk-window.spec.js';
|
|
13
14
|
|
|
@@ -114,12 +115,14 @@ export const AdwApplicationWindowTest = async () => {
|
|
|
114
115
|
|
|
115
116
|
await it('a broken model is dropped rather than thrown', async () => {
|
|
116
117
|
// `parseMenuModel` is total by construction: a typo in markup must not take
|
|
117
|
-
// the window down with it.
|
|
118
|
+
// the window down with it. Since ADR 0128 the window still HOLDS its authored
|
|
119
|
+
// menu — the typo empties it rather than removing it, and `null` is the only
|
|
120
|
+
// spelling of "no menu".
|
|
118
121
|
const win = document.createElement('adw-application-window') as AdwApplicationWindow;
|
|
119
122
|
win.setAttribute('menu-model', '{not json');
|
|
120
123
|
win.setAttribute('show-menubar', '');
|
|
121
124
|
document.body.appendChild(win);
|
|
122
|
-
expect(win.menuModel).toStrictEqual([]);
|
|
125
|
+
expect(menuTree(win.menuModel!)).toStrictEqual([]);
|
|
123
126
|
expect(win.menubar?.hidden).toBe(true);
|
|
124
127
|
win.remove();
|
|
125
128
|
});
|