summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorSonny Piers <sonny@fastmail.net>2022-08-03 11:08:55 +0200
committerPhilip Chimento <philip.chimento@gmail.com>2022-08-05 23:41:07 -0700
commit16bf215994923c50faa248b8866d33811fd62cae (patch)
treeb1e2b02b8fd1c5a3384bdf646215766d9771c8b1 /examples
parentdc3e044a12d4d1df23add5f7896e738e365c5ace (diff)
downloadgjs-16bf215994923c50faa248b8866d33811fd62cae.tar.gz
doc: Modernize examples
* Use ES modules * Use `console` * Port examples to GTK4 (except `calc.js` and `webkit.js`) * Port examples to libsoup 3.0 * Don't use `var` * Stop using `bytearray`
Diffstat (limited to 'examples')
-rw-r--r--examples/.eslintrc.yml2
-rw-r--r--examples/README4
-rw-r--r--examples/calc.js18
-rw-r--r--examples/dbus-client.js15
-rw-r--r--examples/dbus-service.js7
-rw-r--r--examples/gettext.js24
-rw-r--r--examples/gio-cat.js12
-rw-r--r--examples/glistmodel.js11
-rw-r--r--examples/gtk-application.js26
-rw-r--r--examples/gtk3-template.js7
-rw-r--r--examples/gtk3.js (renamed from examples/gtk.js)7
-rw-r--r--examples/gtk4-template.js7
-rw-r--r--examples/gtk4.js62
-rw-r--r--examples/http-client.js30
-rw-r--r--examples/http-server.js32
-rw-r--r--examples/timers.js12
-rw-r--r--examples/webkit.js8
-rw-r--r--examples/websocket-client.js16
18 files changed, 183 insertions, 117 deletions
diff --git a/examples/.eslintrc.yml b/examples/.eslintrc.yml
index 493d9fed..922f3cdc 100644
--- a/examples/.eslintrc.yml
+++ b/examples/.eslintrc.yml
@@ -1,4 +1,6 @@
---
+parserOptions:
+ sourceType: 'module'
# SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
# SPDX-FileCopyrightText: 2020 Evan Welsh <contact@evanwelsh.com>
rules:
diff --git a/examples/README b/examples/README
index 44143e67..0256676a 100644
--- a/examples/README
+++ b/examples/README
@@ -1,3 +1,5 @@
In order to run those example scripts, do:
- gjs-console script-filename.js
+```sh
+gjs -m script-filename.js
+```
diff --git a/examples/calc.js b/examples/calc.js
index 88b4358b..f976514b 100644
--- a/examples/calc.js
+++ b/examples/calc.js
@@ -1,13 +1,11 @@
-#!/usr/bin/env gjs
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2008 Robert Carr <carrr@rpi.edu>
-imports.gi.versions.Gtk = '3.0';
-const {Gtk} = imports.gi;
+import Gtk from 'gi://Gtk?version=3.0';
Gtk.init(null);
-var calcVal = '';
+let calcVal = '';
function updateDisplay() {
label.set_markup(`<span size='30000'>${calcVal}</span>`);
@@ -60,7 +58,7 @@ function randomNum() {
}
function packButtons(buttons, vbox) {
- var hbox = new Gtk.HBox();
+ let hbox = new Gtk.HBox();
hbox.homogeneous = true;
@@ -71,13 +69,13 @@ function packButtons(buttons, vbox) {
}
function createButton(str, func) {
- var btn = new Gtk.Button({label: str});
+ let btn = new Gtk.Button({label: str});
btn.connect('clicked', func);
return btn;
}
function createButtons() {
- var vbox = new Gtk.VBox({homogeneous: true});
+ let vbox = new Gtk.VBox({homogeneous: true});
packButtons([
createButton('(', pressedNumber),
@@ -122,7 +120,7 @@ function createButtons() {
return vbox;
}
-var win = new Gtk.Window({
+let win = new Gtk.Window({
title: 'Calculator',
resizable: false,
opacity: 0.6,
@@ -131,11 +129,11 @@ var win = new Gtk.Window({
win.resize(250, 250);
win.connect('destroy', () => Gtk.main_quit());
-var label = new Gtk.Label({label: ''});
+let label = new Gtk.Label({label: ''});
label.set_alignment(1, 0);
updateDisplay();
-var mainvbox = new Gtk.VBox();
+let mainvbox = new Gtk.VBox();
mainvbox.pack_start(label, false, true, 1);
mainvbox.pack_start(new Gtk.HSeparator(), false, true, 5);
mainvbox.pack_start(createButtons(), true, true, 2);
diff --git a/examples/dbus-client.js b/examples/dbus-client.js
index a59d1ff5..e9d1aeaf 100644
--- a/examples/dbus-client.js
+++ b/examples/dbus-client.js
@@ -1,11 +1,8 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2020 Andy Holmes <andrew.g.r.holmes@gmail.com>
-'use strict';
-
-const GLib = imports.gi.GLib;
-const Gio = imports.gi.Gio;
-
+import GLib from 'gi://GLib';
+import Gio from 'gi://Gio';
/*
* An XML DBus Interface
@@ -51,8 +48,8 @@ function onNameAppeared(connection, name, _owner) {
'org.gnome.gjs.Test',
'/org/gnome/gjs/Test'
);
- } catch (e) {
- logError(e);
+ } catch (err) {
+ logError(err);
return;
}
@@ -89,8 +86,8 @@ function onNameAppeared(connection, name, _owner) {
let value = proxy.SimpleMethodSync();
print(`SimpleMethod: ${value}`);
- } catch (e) {
- logError(`SimpleMethod: ${e.message}`);
+ } catch (err) {
+ logError(`SimpleMethod: ${err.message}`);
}
proxy.ComplexMethodRemote('input string', (value, error, fdList) => {
diff --git a/examples/dbus-service.js b/examples/dbus-service.js
index 74d6689b..b4af5c1a 100644
--- a/examples/dbus-service.js
+++ b/examples/dbus-service.js
@@ -1,11 +1,8 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2020 Andy Holmes <andrew.g.r.holmes@gmail.com>
-'use strict';
-
-const GLib = imports.gi.GLib;
-const Gio = imports.gi.Gio;
-
+import GLib from 'gi://GLib';
+import Gio from 'gi://Gio';
/*
* An XML DBus Interface
diff --git a/examples/gettext.js b/examples/gettext.js
index cbbb1d61..422d207c 100644
--- a/examples/gettext.js
+++ b/examples/gettext.js
@@ -3,21 +3,27 @@
/*
* Make sure you have a non english locale installed, for example fr_FR and run
- * LANGUAGE=fr_FR gjs gettext.js
+ * LANGUAGE=fr_FR gjs -m gettext.js
* the label should show a translation of 'Print help'
*/
-imports.gi.versions.Gtk = '3.0';
-const Gettext = imports.gettext;
-const Gtk = imports.gi.Gtk;
+import Gettext, {gettext as _} from 'gettext';
+import Gtk from 'gi://Gtk?version=4.0';
+import GLib from 'gi://GLib';
+
+Gtk.init();
+
+let loop = GLib.MainLoop.new(null, false);
Gettext.bindtextdomain('gnome-shell', '/usr/share/locale');
Gettext.textdomain('gnome-shell');
-Gtk.init(null);
+let window = new Gtk.Window({title: 'gettext'});
+window.set_child(new Gtk.Label({label: _('Print help')}));
+window.connect('close-request', () => {
+ loop.quit();
+});
-let w = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL});
-w.add(new Gtk.Label({label: Gettext.gettext('Print help')}));
-w.show_all();
+window.present();
-Gtk.main();
+loop.run();
diff --git a/examples/gio-cat.js b/examples/gio-cat.js
index 2d083c3c..72d9c2d8 100644
--- a/examples/gio-cat.js
+++ b/examples/gio-cat.js
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2010 litl, LLC
-const ByteArray = imports.byteArray;
-const GLib = imports.gi.GLib;
-const Gio = imports.gi.Gio;
+import GLib from 'gi://GLib';
+import Gio from 'gi://Gio';
let loop = GLib.MainLoop.new(null, false);
+const decoder = new TextDecoder();
function cat(filename) {
let f = Gio.file_new_for_path(filename);
@@ -13,12 +13,12 @@ function cat(filename) {
let contents;
try {
contents = obj.load_contents_finish(res)[1];
- } catch (e) {
- logError(e);
+ } catch (err) {
+ logError(err);
loop.quit();
return;
}
- print(ByteArray.toString(contents));
+ print(decoder.decode(contents));
loop.quit();
});
diff --git a/examples/glistmodel.js b/examples/glistmodel.js
index 890b2d30..938b2fba 100644
--- a/examples/glistmodel.js
+++ b/examples/glistmodel.js
@@ -1,19 +1,14 @@
-/* exported GjsListStore */
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2020 Andy Holmes <andrew.g.r.holmes@gmail.com>
-'use strict';
-
-const GObject = imports.gi.GObject;
-const Gio = imports.gi.Gio;
-
-
+import GObject from 'gi://GObject';
+import Gio from 'gi://Gio';
/**
* An example of implementing the GListModel interface in GJS. The only real
* requirement here is that the class be derived from some GObject.
*/
-var GjsListStore = GObject.registerClass({
+export let GjsListStore = GObject.registerClass({
GTypeName: 'GjsListStore',
Implements: [Gio.ListModel],
}, class MyList extends GObject.Object {
diff --git a/examples/gtk-application.js b/examples/gtk-application.js
index bc45f41b..4aa4f26d 100644
--- a/examples/gtk-application.js
+++ b/examples/gtk-application.js
@@ -2,21 +2,17 @@
// SPDX-FileCopyrightText: 2017 Andy Holmes <andrew.g.r.holmes@gmail.com>
// See the note about Application.run() at the bottom of the script
-const System = imports.system;
-
-// Include this in case both GTK3 and GTK4 installed, otherwise an exception
-// will be thrown
-imports.gi.versions.Gtk = '3.0';
-
-const Gio = imports.gi.Gio;
-const GLib = imports.gi.GLib;
-const GObject = imports.gi.GObject;
-const Gtk = imports.gi.Gtk;
-
+import System from 'system';
+import Gio from 'gi://Gio';
+import GLib from 'gi://GLib';
+import GObject from 'gi://GObject';
+// Include the version in case both GTK3 and GTK4 installed
+// otherwise an exception will be thrown
+import Gtk from 'gi://Gtk?version=4.0';
// An example GtkApplication with a few bells and whistles, see also:
// https://wiki.gnome.org/HowDoI/GtkApplication
-var ExampleApplication = GObject.registerClass({
+let ExampleApplication = GObject.registerClass({
Properties: {
'exampleprop': GObject.ParamSpec.string(
'exampleprop', // property name
@@ -73,13 +69,13 @@ var ExampleApplication = GObject.registerClass({
});
let label = new Gtk.Label({label: this.exampleprop});
- window.add(label);
+ window.set_child(label);
- window.connect('delete-event', () => {
+ window.connect('close-request', () => {
this.quit();
});
- window.show_all();
+ window.present();
// Example GNotification, see: https://developer.gnome.org/GNotification/
let notif = new Gio.Notification();
diff --git a/examples/gtk3-template.js b/examples/gtk3-template.js
index 3ec64cb5..b7b2dfda 100644
--- a/examples/gtk3-template.js
+++ b/examples/gtk3-template.js
@@ -1,13 +1,12 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2021 Andy Holmes <andyholmes@gnome.org>
-imports.gi.versions.Gtk = '3.0';
-const {GObject, Gio, Gtk} = imports.gi;
-
+import GObject from 'gi://GObject';
+import Gio from 'gi://Gio';
+import Gtk from 'gi://Gtk?version=3.0';
Gtk.init(null);
-
/* In this example the template contents are loaded from the file as a string.
*
* The `Template` property of the class definition will accept:
diff --git a/examples/gtk.js b/examples/gtk3.js
index 8aa8b4e3..00541f7c 100644
--- a/examples/gtk.js
+++ b/examples/gtk3.js
@@ -1,10 +1,9 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2008 litl, LLC
-// Include this in case both GTK3 and GTK4 installed, otherwise an exception
-// will be thrown
-imports.gi.versions.Gtk = '3.0';
-const Gtk = imports.gi.Gtk;
+// Include the version in case both GTK3 and GTK4 installed
+// otherwise an exception will be thrown
+import Gtk from 'gi://Gtk?version=3.0';
// Initialize Gtk before you start calling anything from the import
Gtk.init(null);
diff --git a/examples/gtk4-template.js b/examples/gtk4-template.js
index de34c588..890a8555 100644
--- a/examples/gtk4-template.js
+++ b/examples/gtk4-template.js
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2021 Andy Holmes <andyholmes@gnome.org>
-imports.gi.versions.Gtk = '4.0';
-const {GLib, GObject, Gio, Gtk} = imports.gi;
-
+import GLib from 'gi://GLib';
+import GObject from 'gi://GObject';
+import Gio from 'gi://Gio';
+import Gtk from 'gi://Gtk?version=4.0';
Gtk.init();
diff --git a/examples/gtk4.js b/examples/gtk4.js
new file mode 100644
index 00000000..b12274c8
--- /dev/null
+++ b/examples/gtk4.js
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+// SPDX-FileCopyrightText: 2008 litl, LLC
+
+// Include the version in case both GTK3 and GTK4 installed
+// otherwise an exception will be thrown
+import Gtk from 'gi://Gtk?version=4.0';
+import GLib from 'gi://GLib';
+
+// Initialize Gtk before you start calling anything from the import
+Gtk.init();
+
+// If you are not using GtkApplication which has its own mainloop
+// you must create it yourself, see gtk-application.js example
+let loop = GLib.MainLoop.new(null, false);
+
+// Construct a window
+let win = new Gtk.Window({
+ title: 'A default title',
+ default_width: 300,
+ default_height: 250,
+});
+
+// Object properties can also be set or changed after construction, unless they
+// are marked construct-only.
+win.title = 'Hello World!';
+
+// This is a callback function
+function onCloseRequest() {
+ log('close-request emitted');
+ loop.quit();
+}
+
+// When the window is given the "close-request" signal (this is given by the
+// window manager, usually by the "close" option, or on the titlebar), we ask
+// it to call the onCloseRequest() function as defined above.
+win.connect('close-request', onCloseRequest);
+
+// Create a button to close the window
+let button = new Gtk.Button({
+ label: 'Close the Window',
+ // An example of how constants are mapped:
+ // 'Gtk' and 'Align' are taken from the GtkAlign enum,
+ // 'CENTER' from the constant GTK_ALIGN_CENTER
+ valign: Gtk.Align.CENTER,
+ halign: Gtk.Align.CENTER,
+});
+
+// Connect to the 'clicked' signal, using another way to call an arrow function
+button.connect('clicked', () => win.close());
+
+// Add the button to the window
+win.set_child(button);
+
+// Show the window
+win.present();
+
+// Control will end here and wait for an event to occur
+// (like a key press or mouse event)
+// The main loop will run until loop.quit is called.
+loop.run();
+
+log('The main loop has completed.');
diff --git a/examples/http-client.js b/examples/http-client.js
index 29effb31..5f1d7d94 100644
--- a/examples/http-client.js
+++ b/examples/http-client.js
@@ -4,32 +4,32 @@
// This is a simple example of a HTTP client in Gjs using libsoup
// https://developer.gnome.org/libsoup/stable/libsoup-client-howto.html
-const Soup = imports.gi.Soup;
-const GLib = imports.gi.GLib;
-const byteArray = imports.byteArray;
+import Soup from 'gi://Soup?version=3.0';
+import GLib from 'gi://GLib';
const loop = GLib.MainLoop.new(null, false);
const session = new Soup.Session();
const message = new Soup.Message({
method: 'GET',
- uri: Soup.URI.new('http://localhost:1080/hello?myname=gjs'),
+ uri: GLib.Uri.parse('http://localhost:1080/hello?myname=gjs', GLib.UriFlags.NONE),
});
+const decoder = new TextDecoder();
-session.send_async(message, null, send_async_callback);
+session.send_async(message, null, null, send_async_callback);
function read_bytes_async_callback(inputStream, res) {
let data;
try {
data = inputStream.read_bytes_finish(res);
- } catch (e) {
- logError(e);
+ } catch (err) {
+ logError(err);
loop.quit();
return;
}
- log(`body:\n${byteArray.toString(byteArray.fromGBytes(data))}`);
+ console.log('body:', decoder.decode(data.toArray()));
loop.quit();
}
@@ -39,18 +39,20 @@ function send_async_callback(self, res) {
try {
inputStream = session.send_finish(res);
- } catch (e) {
- logError(e);
+ } catch (err) {
+ logError(err);
loop.quit();
return;
}
- log(`status: ${message.status_code} - ${message.reason_phrase}`);
- message.response_headers.foreach((name, value) => {
- log(`${name}: ${value}`);
+ console.log('status:', message.status_code, message.reason_phrase);
+
+ const response_headers = message.get_response_headers();
+ response_headers.foreach((name, value) => {
+ console.log(name, ':', value);
});
- inputStream.read_bytes_async(message.response_headers.get('content-length'), null, null, read_bytes_async_callback);
+ inputStream.read_bytes_async(response_headers.get_one('content-length'), null, null, read_bytes_async_callback);
}
loop.run();
diff --git a/examples/http-server.js b/examples/http-server.js
index 43ddf4c6..8f9e9172 100644
--- a/examples/http-server.js
+++ b/examples/http-server.js
@@ -1,17 +1,21 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2010 litl, LLC
-// This is a simple example of a HTTP server in Gjs using libsoup
+// This is a simple example of a HTTP server in GJS using libsoup
+// open http://localhost:1080 in your browser or use http-client.js
-const Soup = imports.gi.Soup;
+import Soup from 'gi://Soup?version=3.0';
+import GLib from 'gi://GLib';
-function handler(server, msg, path, query, client) {
- msg.status_code = 200;
- msg.response_headers.set_content_type('text/html', {});
- msg.response_body.append(`
+const loop = GLib.MainLoop.new(null, false);
+
+function handler(_server, msg, _path, _query) {
+ msg.set_status(200, null);
+ msg.get_response_headers().set_content_type('text/html', {charset: 'UTF-8'});
+ msg.get_response_body().append(`
<html>
<body>
- Greetings, visitor from ${client.get_host()}<br>
+ Greetings, visitor from ${msg.get_remote_host()}<br>
What is your name?
<form action="/hello">
<input name="myname">
@@ -21,15 +25,15 @@ function handler(server, msg, path, query, client) {
`);
}
-function helloHandler(server, msg, path, query) {
+function helloHandler(_server, msg, path, query) {
if (!query) {
msg.set_redirect(302, '/');
return;
}
- msg.status_code = 200;
- msg.response_headers.set_content_type('text/html', {charset: 'UTF-8'});
- msg.response_body.append(`
+ msg.set_status(200, null);
+ msg.get_response_headers().set_content_type('text/html', {charset: 'UTF-8'});
+ msg.get_response_body().append(`
<html>
<body>
Hello, ${query.myname}! ☺<br>
@@ -40,10 +44,12 @@ function helloHandler(server, msg, path, query) {
}
function main() {
- let server = new Soup.Server({port: 1080});
+ let server = new Soup.Server();
server.add_handler('/', handler);
server.add_handler('/hello', helloHandler);
- server.run();
+ server.listen_local(1080, Soup.ServerListenOptions.IPV4_ONLY);
}
main();
+
+loop.run();
diff --git a/examples/timers.js b/examples/timers.js
index fb23ba00..4b32f952 100644
--- a/examples/timers.js
+++ b/examples/timers.js
@@ -2,7 +2,11 @@
// SPDX-FileCopyrightText: 2021 Evan Welsh <contact@evanwelsh.com>
// This example demonstrates that Promises always execute prior
-// to timeouts. It should log "java" then "script".
+// to timeouts. It should log "hello" then "world".
+
+import GLib from 'gi://GLib';
+
+const loop = GLib.MainLoop.new(null, false);
const promise = new Promise(r => {
let i = 100;
@@ -13,9 +17,11 @@ const promise = new Promise(r => {
});
setTimeout(() => {
- promise.then(() => log('java'));
+ promise.then(() => log('hello'));
});
setTimeout(() => {
- log('script');
+ log('world');
});
+
+loop.run();
diff --git a/examples/webkit.js b/examples/webkit.js
index adf809f4..dd803efc 100644
--- a/examples/webkit.js
+++ b/examples/webkit.js
@@ -1,17 +1,15 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2008 litl, LLC
-imports.gi.versions.Gtk = '3.0';
-imports.gi.versions.WebKit2 = '4.0';
-const Gtk = imports.gi.Gtk;
-const WebKit = imports.gi.WebKit2;
+import Gtk from 'gi://Gtk?version=3.0';
+import WebKit from 'gi://WebKit2?version=4.0';
Gtk.init(null);
let win = new Gtk.Window();
let view = new WebKit.WebView();
-view.load_uri('http://www.google.com/');
+view.load_uri('https://www.gnome.org');
win.add(view);
win.connect('destroy', () => {
diff --git a/examples/websocket-client.js b/examples/websocket-client.js
index 7de93e1a..d258f52e 100644
--- a/examples/websocket-client.js
+++ b/examples/websocket-client.js
@@ -4,27 +4,27 @@
// This is an example of a WebSocket client in Gjs using libsoup
// https://developer.gnome.org/libsoup/stable/libsoup-2.4-WebSockets.html
-const Soup = imports.gi.Soup;
-const GLib = imports.gi.GLib;
-const byteArray = imports.byteArray;
+import Soup from 'gi://Soup?version=3.0';
+import GLib from 'gi://GLib';
const loop = GLib.MainLoop.new(null, false);
const session = new Soup.Session();
const message = new Soup.Message({
method: 'GET',
- uri: Soup.URI.new('wss://echo.websocket.org'),
+ uri: GLib.Uri.parse('wss://ws.postman-echo.com/raw', GLib.UriFlags.NONE),
});
+const decoder = new TextDecoder();
-session.websocket_connect_async(message, 'origin', [], null, websocket_connect_async_callback);
+session.websocket_connect_async(message, null, [], null, null, websocket_connect_async_callback);
function websocket_connect_async_callback(_session, res) {
let connection;
try {
connection = session.websocket_connect_finish(res);
- } catch (e) {
- logError(e);
+ } catch (err) {
+ logError(err);
loop.quit();
return;
}
@@ -43,7 +43,7 @@ function websocket_connect_async_callback(_session, res) {
if (type !== Soup.WebsocketDataType.TEXT)
return;
- const str = byteArray.toString(byteArray.fromGBytes(data));
+ const str = decoder.decode(data.toArray());
log(`message: ${str}`);
connection.close(Soup.WebsocketCloseCode.NORMAL, null);
});