diff options
author | Sonny Piers <sonny@fastmail.net> | 2022-08-03 11:08:55 +0200 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2022-08-05 23:41:07 -0700 |
commit | 16bf215994923c50faa248b8866d33811fd62cae (patch) | |
tree | b1e2b02b8fd1c5a3384bdf646215766d9771c8b1 /examples | |
parent | dc3e044a12d4d1df23add5f7896e738e365c5ace (diff) | |
download | gjs-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.yml | 2 | ||||
-rw-r--r-- | examples/README | 4 | ||||
-rw-r--r-- | examples/calc.js | 18 | ||||
-rw-r--r-- | examples/dbus-client.js | 15 | ||||
-rw-r--r-- | examples/dbus-service.js | 7 | ||||
-rw-r--r-- | examples/gettext.js | 24 | ||||
-rw-r--r-- | examples/gio-cat.js | 12 | ||||
-rw-r--r-- | examples/glistmodel.js | 11 | ||||
-rw-r--r-- | examples/gtk-application.js | 26 | ||||
-rw-r--r-- | examples/gtk3-template.js | 7 | ||||
-rw-r--r-- | examples/gtk3.js (renamed from examples/gtk.js) | 7 | ||||
-rw-r--r-- | examples/gtk4-template.js | 7 | ||||
-rw-r--r-- | examples/gtk4.js | 62 | ||||
-rw-r--r-- | examples/http-client.js | 30 | ||||
-rw-r--r-- | examples/http-server.js | 32 | ||||
-rw-r--r-- | examples/timers.js | 12 | ||||
-rw-r--r-- | examples/webkit.js | 8 | ||||
-rw-r--r-- | examples/websocket-client.js | 16 |
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); }); |