@gjsify/adwaita-web 0.64.12 → 0.64.13
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/dist/adwaita-web.css +31 -0
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/elements/adw-bin.d.ts +13 -0
- package/lib/types/elements/adw-expander-row.d.ts +3 -0
- package/lib/types/elements/gtk-label.d.ts +64 -0
- package/lib/types/label-markup.d.ts +30 -0
- package/lib/types/pango-markup.d.ts +17 -0
- package/lib/types/styles.generated.d.ts +1 -1
- package/lib/types/widget-element.d.ts +8 -2
- package/package.json +11 -11
- package/scss/_labels.scss +19 -0
- package/scss/_link.scss +73 -7
- package/src/adw-action-rows.spec.ts +19 -0
- package/src/adw-bin.spec.ts +20 -0
- package/src/adw-row-state.spec.ts +80 -0
- package/src/elements/adw-bin.ts +20 -1
- package/src/elements/adw-expander-row.ts +46 -16
- package/src/elements/gtk-label.ts +206 -16
- package/src/gtk-label.spec.ts +431 -11
- package/src/gtk-switch.spec.ts +8 -0
- package/src/label-markup.ts +193 -0
- package/src/pango-markup.spec.ts +11 -0
- package/src/pango-markup.ts +14 -5
- package/src/split-button.spec.ts +7 -4
- package/src/styles.generated.ts +1 -1
- package/src/widget-element.ts +28 -7
- package/src/widget-members.spec.ts +42 -3
package/src/widget-element.ts
CHANGED
|
@@ -16,10 +16,25 @@
|
|
|
16
16
|
// Reference: GTK gtk/gtkwidget.c (gtk_widget_set_visible, gtk_widget_set_tooltip_text)
|
|
17
17
|
// Copyright (c) GNOME contributors (GTK). LGPLv2.1+.
|
|
18
18
|
|
|
19
|
+
import { isWidgetNode } from '@gjsify/adwaita-core';
|
|
20
|
+
|
|
19
21
|
import { WIDGET_VISIBLE_GETTERS, installElementApi, markLazyElementApi, notifyElement } from './gobject-elements.js';
|
|
20
22
|
import { dispatchedSignalsOf, type DispatchedSignals } from './signals.js';
|
|
21
23
|
import { isMapped } from './widget-mapping.js';
|
|
22
24
|
|
|
25
|
+
/** Element links, walked until one lands on a widget: `isWidgetNode` says which those are. */
|
|
26
|
+
type ElementLink =
|
|
27
|
+
| 'firstElementChild'
|
|
28
|
+
| 'lastElementChild'
|
|
29
|
+
| 'nextElementSibling'
|
|
30
|
+
| 'previousElementSibling'
|
|
31
|
+
| 'parentElement';
|
|
32
|
+
|
|
33
|
+
function widgetChild(from: Element, first: ElementLink, next: ElementLink): Element | null {
|
|
34
|
+
for (let at = from[first]; at !== null; at = at[next]) if (isWidgetNode(at)) return at;
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
23
38
|
export class WidgetElement extends HTMLElement {
|
|
24
39
|
/** `Gtk.Widget::map` / `::unmap`, which every subclass inherits (`dispatchedSignalsOf`). */
|
|
25
40
|
static readonly signals: DispatchedSignals = { map: 'map', unmap: 'unmap' };
|
|
@@ -41,25 +56,31 @@ export class WidgetElement extends HTMLElement {
|
|
|
41
56
|
set_visible(visible: boolean): void {
|
|
42
57
|
this.visible = visible;
|
|
43
58
|
}
|
|
44
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* `gtk_widget_get_first_child`: the first child WIDGET, `null` for a leaf.
|
|
61
|
+
*
|
|
62
|
+
* The five walkers skip the elements a port builds for its own insides — `isWidgetNode`
|
|
63
|
+
* in `@gjsify/adwaita-core` carries the rule and the incident behind it, and the
|
|
64
|
+
* registered-class copy in `widgetTreeMembers()` answers from the same function.
|
|
65
|
+
*/
|
|
45
66
|
get_first_child(): Element | null {
|
|
46
|
-
return this
|
|
67
|
+
return widgetChild(this, 'firstElementChild', 'nextElementSibling');
|
|
47
68
|
}
|
|
48
69
|
/** `gtk_widget_get_last_child`. */
|
|
49
70
|
get_last_child(): Element | null {
|
|
50
|
-
return this
|
|
71
|
+
return widgetChild(this, 'lastElementChild', 'previousElementSibling');
|
|
51
72
|
}
|
|
52
73
|
/** `gtk_widget_get_next_sibling`. */
|
|
53
74
|
get_next_sibling(): Element | null {
|
|
54
|
-
return this
|
|
75
|
+
return widgetChild(this, 'nextElementSibling', 'nextElementSibling');
|
|
55
76
|
}
|
|
56
77
|
/** `gtk_widget_get_prev_sibling`. */
|
|
57
78
|
get_prev_sibling(): Element | null {
|
|
58
|
-
return this
|
|
79
|
+
return widgetChild(this, 'previousElementSibling', 'previousElementSibling');
|
|
59
80
|
}
|
|
60
|
-
/** `gtk_widget_get_parent
|
|
81
|
+
/** `gtk_widget_get_parent`: the nearest ancestor that is a widget, not a port's own wrapper. */
|
|
61
82
|
get_parent(): Element | null {
|
|
62
|
-
return this
|
|
83
|
+
return widgetChild(this, 'parentElement', 'parentElement');
|
|
63
84
|
}
|
|
64
85
|
/** `gtk_widget_get_width`: the layout box in CSS px; 0 until the widget is rendered. */
|
|
65
86
|
get_width(): number {
|
|
@@ -60,10 +60,10 @@ export const WidgetMembersTest = async () => {
|
|
|
60
60
|
expect(() => widget.set_direction(7)).toThrow();
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
await it('walks the
|
|
63
|
+
await it('walks the widget tree with the GTK link names', () => {
|
|
64
64
|
const parent = make('WidgetMembersParent');
|
|
65
|
-
const a =
|
|
66
|
-
const b =
|
|
65
|
+
const a = new Gtk.Label() as unknown as WidgetLike;
|
|
66
|
+
const b = new Gtk.Label() as unknown as WidgetLike;
|
|
67
67
|
parent.append(a, b);
|
|
68
68
|
expect(parent.get_first_child()).toBe(a);
|
|
69
69
|
expect(parent.get_last_child()).toBe(b);
|
|
@@ -73,6 +73,45 @@ export const WidgetMembersTest = async () => {
|
|
|
73
73
|
expect(parent.get_parent()).toBe(null);
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
await it("steps over the plain elements a port builds for a widget's insides", () => {
|
|
77
|
+
// `gtk_widget_get_first_child` hands back a GtkWidget, always. In a DOM port the
|
|
78
|
+
// same `children` list also holds what the port made for itself — the `<span>` a
|
|
79
|
+
// label's markup renderer writes, the `<div>` a row lays its slots out in — and a
|
|
80
|
+
// caller walking the tree would get one of those and find no `get_first_child` on
|
|
81
|
+
// it at all. The custom-element hyphen separates the two kinds (`isWidgetNode`).
|
|
82
|
+
const parent = make('WidgetMembersInsides');
|
|
83
|
+
const a = new Gtk.Label() as unknown as WidgetLike;
|
|
84
|
+
const b = new Gtk.Label() as unknown as WidgetLike;
|
|
85
|
+
parent.append(
|
|
86
|
+
document.createElement('span'),
|
|
87
|
+
a,
|
|
88
|
+
document.createElement('div'),
|
|
89
|
+
b,
|
|
90
|
+
document.createElement('span'),
|
|
91
|
+
);
|
|
92
|
+
expect(parent.get_first_child()).toBe(a);
|
|
93
|
+
expect(parent.get_last_child()).toBe(b);
|
|
94
|
+
expect(a.get_next_sibling()).toBe(b);
|
|
95
|
+
expect(b.get_prev_sibling()).toBe(a);
|
|
96
|
+
expect(b.get_next_sibling()).toBe(null);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
await it('a widget holding only its own markup is a LEAF', () => {
|
|
100
|
+
const label = make('WidgetMembersLeaf');
|
|
101
|
+
label.append(document.createElement('span'), document.createElement('span'));
|
|
102
|
+
expect(label.get_first_child()).toBe(null);
|
|
103
|
+
expect(label.get_last_child()).toBe(null);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
await it('get_parent reports the nearest ancestor that is a widget', () => {
|
|
107
|
+
const box = new Gtk.Box() as unknown as WidgetLike;
|
|
108
|
+
const wrapper = document.createElement('div');
|
|
109
|
+
const label = new Gtk.Label() as unknown as WidgetLike;
|
|
110
|
+
box.append(wrapper);
|
|
111
|
+
wrapper.append(label);
|
|
112
|
+
expect(label.get_parent()).toBe(box);
|
|
113
|
+
});
|
|
114
|
+
|
|
76
115
|
await it('walks the element tree of a built-in widget with the GTK link names', () => {
|
|
77
116
|
const box = new Gtk.Box() as unknown as WidgetLike;
|
|
78
117
|
const a = new Gtk.Label() as unknown as WidgetLike;
|