troll is an implementation of common JavaScript APIs for gjs and some helpers.
See this gjs issue for context.
This is not API stable and no release were made. Use at your own risk. Contributions welcome.
- WebSocket src
- fetch src
- request
- method/url
- headers
- text body
- response
- status/statusText/ok
- text() / json()
- request
- base64
timersbuiltin gjs 1.72consolebuiltin gjs 1.70TextDecoder/TextEncoderbuiltin gjs 1.70
- Provide a familiar environment for building GNOME applications
- Allow application developers to use third party libraries
- Encourage Shell extension developers to make flatpak apps instead
You can register all globals with
import "./troll/src/globals.js";
// fetch(...)
// new WebSocket(...)
// atob(...)
// btoa(...)
Arguments
Returns <string> the resolved uri
Similar to import.meta.resolve
or new URL(url, base)
.
import { resolve } from "./troll/src/main.js";
console.log(resolve(import.meta.url, "./xml.js"));
// resource:///some/path/xml.js
// or
// file:///some/path/xml.js
console.log(resolve("http://foo.example", "http://bar.example"));
// http://bar.example
Arguments
Returns <GLib.Uri> the resolved uri
Same as resolve
but returns a GLib.Uri
instead of a string
.
Arguments
target
<GObject.object>method
<string>finish
<string>...args
the list of arguments to pass tomethod
Returns <Promise> resolves or rejects with the result of the finish function
Run a Gio async operation and return a promise that resolve with the result of finish method or rejects.
See also Gio._promisify
Examples
import { promiseTask } from "./troll/src/main.js";
import Gio from "gi://Gio";
(async () => {
const file = Gio.File.new_for_path("/tmp/foobar");
// see https://developer.gnome.org/gio/stable/GFile.html#g-file-replace-readwrite-async
const stream = await promisetask(file, "readwrite_async", "readwrite_finish");
log(stream);
})().catch(logError);
Arguments
Returns <Object>
A helper function to easily load, build and bind a GTK XML interface. Here is an example
window.js
#!/usr/bin/env -S gjs -m
import Gtk from "gi://Gtk?version=4.0";
import { build, resolve } from "./troll/src/main.js";
const app = new Gtk.Application({
application_id: "hello.world",
});
app.connect("activate", () => {
const { window, button } = build(resolve(import.meta.url, "./window.xml"), {
onclicked,
app,
});
button.label = "World";
window.present();
});
app.runAsync(null);
function onclicked(button) {
console.log("Hello", button.label);
app.activeWindow?.close();
}
window.xml
<?xml version="1.0" encoding="UTF-8" ?>
<interface>
<requires lib="gtk" version="4.0" />
<object class="GtkApplicationWindow" id="window">
<property
name="title"
bind-source="app"
bind-property="application-id"
bind-flags="sync-create"
/>
<binding name="application">
<constant>app</constant>
</binding>
<property name="default-width">400</property>
<property name="default-height">400</property>
<child>
<object class="GtkButton" id="button">
<signal name="clicked" handler="onclicked" />
</object>
</child>
</object>
</interface>
window.blp
using Gtk 4.0;
ApplicationWindow window {
title: bind-property app.application-id;
application: bind app;
default-width: 400;
default-height: 400;
Button button {
clicked => $onclicked();
}
}
ℹ️ build
is for <interface/>
only, for <template/>
, use GObject.registerClass
gsx is a small function to write Gtk.
See gsx-demo for setup and instructions with Babel.
You can use it as a jsx pragma with babel, TypeScript, SWC or Rome like so:
import Gtk from "gi://Gtk?version=4.0";
import gsx from "./troll/src/main.js";
/** @jsx gsx.h */
/** @jsxFrag gsx.Fragment */
export default function MyButton() {
return (
<Gtk.Button connect-clicked={() => log("clicked")} halign={Gtk.Align.END}>
<Gtk.Image icon-name="folder-open-symbolic" pixel-size={48} />
</Gtk.Button>
);
}
GJS doesn't support source map yet. We recommend babel as it is the only option capable of retaining line numbers.
Equivalent without gsx
import Gtk from "gi://Gtk?version=4.0";
export default function MyButton() {
const image = new Gtk.Image({
"icon-name": "folder-open-synbolic",
"pixel-size": 48,
});
const button = new Gtk.Button({
halign: Gtk.Align.END,
});
button.connect("signal", () => {
log("clicked!");
});
button.add(image);
}
Usage without a compiler
import Gtk from "gi://Gtk?version=4.0";
import gsx from "./troll/src/main.js";
const { Button, Align, Image } = Gtk;
export default function MyButton() {
return gsx(
Button,
{
"connect-clicked": () => log("clicked"),
halign: Align.END,
},
gsx(Image, {
"icon-name": "folder-open-synbolic",
"pixel-size": 48,
}),
);
}