summaryrefslogtreecommitdiff
path: root/gjs
diff options
context:
space:
mode:
authorAylur <[email protected]>2024-06-07 20:38:02 +0200
committerAylur <[email protected]>2024-06-07 20:38:02 +0200
commit15285a17bf447c5185dfbb92d9a4bd2670a4e44e (patch)
treea087e6a79232abd9938f771da844efb0de618888 /gjs
parentc3c294c2c08aaf35a25684b5dbc0d332b13ead44 (diff)
fix: jsx edge cases
Diffstat (limited to 'gjs')
-rw-r--r--gjs/src/astalify.ts63
-rw-r--r--gjs/src/binding.ts8
-rw-r--r--gjs/src/jsx/jsx-runtime.ts19
-rw-r--r--gjs/src/overrides.ts23
4 files changed, 53 insertions, 60 deletions
diff --git a/gjs/src/astalify.ts b/gjs/src/astalify.ts
index 2817606..f986716 100644
--- a/gjs/src/astalify.ts
+++ b/gjs/src/astalify.ts
@@ -1,7 +1,11 @@
-import Binding, { kebabify, type Connectable, type Subscribable } from "./binding.js"
+import Binding, { kebabify, snakeify, type Connectable, type Subscribable } from "./binding.js"
import { Astal, Gtk } from "./imports.js"
import { execAsync } from "./process.js"
-import { setChild } from "./overrides.js"
+
+Object.defineProperty(Astal.Box.prototype, "children", {
+ get() { return this.get_children() },
+ set(v) { this.set_children(v) },
+})
export type Widget<C extends { new(...args: any): Gtk.Widget }> = InstanceType<C> & {
className: string
@@ -44,21 +48,15 @@ function hook(
}
function ctor(self: any, config: any = {}, ...children: Gtk.Widget[]) {
- const { setup, child, ...props } = config
+ const { setup, ...props } = config
props.visible ??= true
- const pchildren = props.children
- delete props.children
-
const bindings = Object.keys(props).reduce((acc: any, prop) => {
if (props[prop] instanceof Binding) {
- const bind = [prop, props[prop]]
- prop === "child"
- ? setChild(self, props[prop].get())
- : self[`set_${kebabify(prop)}`](props[prop].get())
-
+ const binding = props[prop]
+ self[`set_${snakeify(prop)}`](binding.get())
delete props[prop]
- return [...acc, bind]
+ return [...acc, [prop, binding]]
}
return acc
}, [])
@@ -66,13 +64,16 @@ function ctor(self: any, config: any = {}, ...children: Gtk.Widget[]) {
const onHandlers = Object.keys(props).reduce((acc: any, key) => {
if (key.startsWith("on")) {
const sig = kebabify(key).split("-").slice(1).join("-")
- const handler = [sig, props[key]]
+ const handler = props[key]
delete props[key]
- return [...acc, handler]
+ return [...acc, [sig, handler]]
}
return acc
}, [])
+ const pchildren = props.children
+ delete props.children
+
Object.assign(self, props)
Object.assign(self, {
hook(obj: any, sig: any, callback: any) {
@@ -80,15 +81,6 @@ function ctor(self: any, config: any = {}, ...children: Gtk.Widget[]) {
},
})
- if (child instanceof Binding) {
- setChild(self, child.get())
- self.connect("destroy", child.subscribe(v => {
- setChild(self, v)
- }))
- } else if (self instanceof Gtk.Container && child instanceof Gtk.Widget) {
- self.add(child)
- }
-
for (const [signal, callback] of onHandlers) {
if (typeof callback === "function") {
self.connect(signal, callback)
@@ -100,19 +92,19 @@ function ctor(self: any, config: any = {}, ...children: Gtk.Widget[]) {
}
if (self instanceof Gtk.Container) {
- if (pchildren) {
- for (const child of pchildren)
- self.add(child)
- }
if (children) {
for (const child of children)
self.add(child)
}
+ if (pchildren && Array.isArray(pchildren)) {
+ for (const child of pchildren)
+ self.add(child)
+ }
}
for (const [prop, bind] of bindings) {
self.connect("destroy", bind.subscribe((v: any) => {
- self[`set_${kebabify(prop)}`](v)
+ self[`set_${snakeify(prop)}`](v)
}))
}
@@ -138,6 +130,21 @@ function proxify<
set(v) { Astal.widget_set_cursor(this, v) },
})
+ klass.prototype.set_child = function(widget: Gtk.Widget) {
+ if (this instanceof Gtk.Bin) {
+ const rm = this.get_child()
+ if (rm)
+ this.remove(rm)
+ }
+ if (this instanceof Gtk.Container)
+ this.add(widget)
+ }
+
+ Object.defineProperty(klass.prototype, "child", {
+ get() { return this.get_child?.() },
+ set(v) { this.set_child(v) },
+ })
+
const proxy = new Proxy(klass, {
construct(_, [conf, ...children]) {
const self = new klass
diff --git a/gjs/src/binding.ts b/gjs/src/binding.ts
index a8b6d55..50d941d 100644
--- a/gjs/src/binding.ts
+++ b/gjs/src/binding.ts
@@ -1,8 +1,10 @@
-export const kebabify = (str: string) => str
- .replace(/([a-z])([A-Z])/g, "$1-$2")
- .replaceAll("_", "-")
+export const snakeify = (str: string) => str
+ .replace(/([a-z])([A-Z])/g, "$1_$2")
.toLowerCase()
+export const kebabify = (str: string) => snakeify(str)
+ .replaceAll("_", "-")
+
export interface Subscribable<T = unknown> {
subscribe(callback: () => void): () => void
get(): T
diff --git a/gjs/src/jsx/jsx-runtime.ts b/gjs/src/jsx/jsx-runtime.ts
index 41aa447..5e7f23b 100644
--- a/gjs/src/jsx/jsx-runtime.ts
+++ b/gjs/src/jsx/jsx-runtime.ts
@@ -3,10 +3,9 @@ import * as Widget from "../widgets.js"
import Binding from "../binding.js"
function w(e: any) {
- if (e instanceof Gtk.Widget || e instanceof Binding)
- return e
-
- return Widget.Label({ label: String(e) })
+ return e instanceof Gtk.Widget || e instanceof Binding
+ ? e
+ : Widget.Label({ label: String(e) })
}
export function jsx(
@@ -20,7 +19,15 @@ export function jsx(
else
children = children.flat()
- if (ctor === "centerbox") {
+ // <box children={Binding} /> and <box>{Binding}</box>
+ if (ctor === "box" && children.length === 1 && children[0] instanceof Binding) {
+ props.children = children[0]
+ }
+
+ // TODO: handle array of Binding
+ // is there a usecase?
+
+ else if (ctor === "centerbox") {
if (children[0])
props.startWidget = w(children[0])
if (children[1])
@@ -29,7 +36,7 @@ export function jsx(
props.endWidget = w(children[2])
}
- else if (ctor == "overlay") {
+ else if (ctor === "overlay") {
const [child, ...overlays] = children
if (child)
props.child = child
diff --git a/gjs/src/overrides.ts b/gjs/src/overrides.ts
deleted file mode 100644
index e3d3df5..0000000
--- a/gjs/src/overrides.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Gtk, Astal } from "./imports.js"
-
-export function setChild(parent: Gtk.Widget, child: Gtk.Widget) {
- if (parent instanceof Gtk.Bin) {
- const rm = parent.get_child()
- if (rm)
- parent.remove(rm)
- }
- if (parent instanceof Gtk.Container)
- parent.add(child)
-}
-
-// gjs fails to map List types?
-Object.defineProperty(Astal.Box.prototype, "children", {
- get() { return this.get_children() },
- set(v) { this.set_children(v) },
-})
-
-// gjs deprecated the child setter
-Object.defineProperty(Gtk.Container.prototype, "child", {
- get() { return this.get_child?.() },
- set(v) { setChild(this, v) },
-})