[gjs/esm/static-imports: 2/2] esm: Add additional builtin ES modules




commit e0e8c5458ef4d30c6c36237e49c259eae441d609
Author: Evan Welsh <contact evanwelsh com>
Date:   Wed Feb 3 17:02:35 2021 -0800

    esm: Add additional builtin ES modules
    
    Adds 'cairo', 'gettext', and 'system' modules, to match the builtin legacy
    modules that GJS already had.
    
    'gettext' and 'system' have named exports because it's expected that the
    functions might be used individually that way. That doesn't make as much
    sense for Cairo which is to be understood more as if it were a GI module.
    
    (changes from Philip folded in: Jasmine tests)

 doc/ESModules.md                      | 16 ++++++++++++++
 doc/Modules.md                        | 20 +++++++++--------
 installed-tests/js/.eslintrc.yml      |  1 +
 installed-tests/js/meson.build        | 41 ++++++++++++++++++++++-------------
 installed-tests/js/testCairoModule.js | 26 ++++++++++++++++++++++
 installed-tests/js/testESModules.js   | 23 ++++++++++++++++++++
 js.gresource.xml                      |  4 ++++
 modules/esm/cairo.js                  | 10 +++++++++
 modules/esm/gettext.js                | 30 +++++++++++++++++++++++++
 modules/esm/system.js                 | 26 ++++++++++++++++++++++
 10 files changed, 173 insertions(+), 24 deletions(-)
---
diff --git a/doc/ESModules.md b/doc/ESModules.md
index 80017a37..5c88ef98 100644
--- a/doc/ESModules.md
+++ b/doc/ESModules.md
@@ -154,6 +154,22 @@ import Gdk from 'gi://Gdk';
 import Hdy from 'gi://Hdy';
 ```
 
+## Built-in modules
+
+Built-in modules provide a default export with all their exported functions and properties. Most modules 
provide named exports too. `cairo` does not provide named exports of its API.
+
+Modifying the values of the default export _does not_ change the values of named exports.
+
+```js
+import system from 'system';
+system.exit(1);
+```
+
+```js
+import { ngettext as _ } from 'gettext';
+_('Hello!');
+```
+
 ## `import()` expressions
 
 Dynamic [`import()` statements][] are not currently supported in GJS.
diff --git a/doc/Modules.md b/doc/Modules.md
index 6400cbed..4b196b56 100644
--- a/doc/Modules.md
+++ b/doc/Modules.md
@@ -63,14 +63,13 @@ import Gtk from 'gi://Gtk?version=3.0';
 
 ## Cairo
 
-**Import with `const Cairo = imports.cairo;`**
+**Import with `import Cairo from 'cairo';`**
 
 Mostly API compatible with [cairo](https://www.cairographics.org/documentation/), but using camelCase 
function names. There is list of constants in [cairo.js][cairo-const] and functions for each object in its 
corresponding C++ file (eg. [cairo-context.cpp][cairo-func]). A simple example drawing a 32x32 red circle:
 
 ```js
-imports.gi.versions.Gtk = "3.0";
-const Gtk = imports.gi.Gtk;
-const Cairo = imports.cairo;
+import Gtk from 'gi://Gtk?version=3.0';
+import Cairo from 'cairo';
 
 let drawingArea = new Gtk.DrawingArea({
     height_request: 32,
@@ -125,12 +124,16 @@ Gettext.ngettext("I have %d apple", "I have %d apples", num).format(num);
 
 ## [Gettext](https://gitlab.gnome.org/GNOME/gjs/blob/master/modules/script/gettext.js)
 
-**Import with `const Gettext = imports.gettext;`**
+**Import with `import gettext from 'gettext';`**
 
 Helper functions for gettext. See also [examples/gettext.js][example-gettext] for usage.
 
 [example-gettext]: https://gitlab.gnome.org/GNOME/gjs/blob/master/examples/gettext.js
 
+### Legacy Imports (`imports.gettext`)
+
+Gettext is also exposed via `imports.gettext` on the global `imports` object.
+
 ## [jsUnit](https://gitlab.gnome.org/GNOME/gjs/blob/master/modules/script/jsUnit.js)
 
 **DEPRECATED**
@@ -218,7 +221,7 @@ obj.disconnectAll();
 
 ## [System](https://gitlab.gnome.org/GNOME/gjs/blob/master/modules/system.cpp)
 
-**Import with `const System = imports.system;`**
+**Import with `import system from 'system';`**
 
 The System module offers a number of useful functions and properties for debugging and shell interaction 
(eg. ARGV):
 
@@ -262,9 +265,8 @@ The System module offers a number of useful functions and properties for debuggi
  [examples/gtk-application.js][example-application]):
 
     ```js
-    imports.gi.versions.Gtk = "3.0";
-    const Gtk = imports.gi.Gtk;
-    const System = imports.system;
+    import Gtk from 'gi://Gtk?version=3.0';
+    import system from 'system';
 
     let myApp = new Gtk.Application();
     myApp.connect("activate", () => log("activated"));
diff --git a/installed-tests/js/.eslintrc.yml b/installed-tests/js/.eslintrc.yml
index 7f329a58..28ec04c6 100644
--- a/installed-tests/js/.eslintrc.yml
+++ b/installed-tests/js/.eslintrc.yml
@@ -31,6 +31,7 @@ globals:
   setTimeout: writable
 overrides:
   - files:
+      - testCairoModule.js
       - testESModules.js
       - modules/importmeta.js
       - modules/exports.js
diff --git a/installed-tests/js/meson.build b/installed-tests/js/meson.build
index 58385030..15b17d63 100644
--- a/installed-tests/js/meson.build
+++ b/installed-tests/js/meson.build
@@ -195,21 +195,32 @@ if get_option('installed_tests')
     install_data('testGDBus.js', install_dir: installed_js_tests_dir)
 endif
 
-# testESModules.js is also separate because it needs an extra minijasmine flag
+# tests using ES modules are also separate because they need an extra
+# minijasmine flag
 
-test('ESModules', minijasmine, args: [files('testESModules.js'), '-m'],
-    env: tests_environment, protocol: 'tap', suite: 'JS')
+modules_tests = ['ESModules']
+if build_cairo
+    modules_tests += 'CairoModule'
+endif
 
-esm_test_description_subst = {
-    'name': 'testESModules.js',
-    'installed_tests_execdir': installed_tests_execdir,
-}
-esm_test_description = configure_file(
-    configuration: esm_test_description_subst,
-    input: '../minijasmine-module.test.in', output: 'testESModules.test',
-    install: get_option('installed_tests'),
-    install_dir: installed_tests_metadir)
+foreach test : modules_tests
+    test_file = files('test@0@.js'.format(test))
 
-if get_option('installed_tests')
-    install_data('testESModules.js', install_dir: installed_js_tests_dir)
-endif
+    test(test, minijasmine, args: [test_file, '-m'], env: tests_environment,
+        protocol: 'tap', suite: 'JS')
+
+    esm_test_description_subst = {
+        'name': 'test@0@.js'.format(test),
+        'installed_tests_execdir': installed_tests_execdir,
+    }
+    esm_test_description = configure_file(
+        configuration: esm_test_description_subst,
+        input: '../minijasmine-module.test.in',
+        output: 'test@0@.test'.format(test),
+        install: get_option('installed_tests'),
+        install_dir: installed_tests_metadir)
+
+    if get_option('installed_tests')
+        install_data(test_file, install_dir: installed_js_tests_dir)
+    endif
+endforeach
diff --git a/installed-tests/js/testCairoModule.js b/installed-tests/js/testCairoModule.js
new file mode 100644
index 00000000..17c0b47c
--- /dev/null
+++ b/installed-tests/js/testCairoModule.js
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 Philip Chimento <philip chimento gmail com>
+
+import Cairo from 'cairo';
+import giCairo from 'gi://cairo';
+
+describe('Cairo imported as ES module', function () {
+    it('cairo default import', function () {
+        // one from cairoNative, one from cairo JS.
+        expect(typeof Cairo.Context).toBe('function');
+        expect(typeof Cairo.Format).toBe('object');
+    });
+
+    // cairo doesn't have named exports
+});
+
+describe('Cairo imported via GI', function () {
+    it('has the same functionality as imports.cairo', function () {
+        const surface = new giCairo.ImageSurface(Cairo.Format.ARGB32, 1, 1);
+        void new giCairo.Context(surface);
+    });
+
+    it('has boxed types from the GIR file', function () {
+        void new giCairo.RectangleInt();
+    });
+});
diff --git a/installed-tests/js/testESModules.js b/installed-tests/js/testESModules.js
index ea551485..d1b7210d 100644
--- a/installed-tests/js/testESModules.js
+++ b/installed-tests/js/testESModules.js
@@ -1,8 +1,12 @@
 // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
 // SPDX-FileCopyrightText: 2020 Evan Welsh <contact evanwelsh com>
 
+import gettext from 'gettext';
+import {ngettext as N_} from 'gettext';
 import gi from 'gi';
 import Gio from 'gi://Gio';
+import system from 'system';
+import {exit} from 'system';
 
 import $ from 'resource:///org/gjs/jsunit/modules/exports.js';
 import {NamedExport, data} from 'resource:///org/gjs/jsunit/modules/exports.js';
@@ -54,3 +58,22 @@ describe('ES module imports', function () {
         expect(metaProperties).toEqual(['url']);
     });
 });
+
+describe('Builtin ES modules', function () {
+    it('gettext default import', function () {
+        expect(typeof gettext.ngettext).toBe('function');
+    });
+
+    it('gettext named import', function () {
+        expect(typeof N_).toBe('function');
+    });
+
+    it('system default import', function () {
+        expect(typeof system.exit).toBe('function');
+    });
+
+    it('system named import', function () {
+        expect(typeof exit).toBe('function');
+        expect(exit).toBe(system.exit);
+    });
+});
diff --git a/js.gresource.xml b/js.gresource.xml
index 61193ab0..fc55e597 100644
--- a/js.gresource.xml
+++ b/js.gresource.xml
@@ -8,7 +8,11 @@
     <file>modules/internal/loader.js</file>
 
     <!-- ESM-based modules -->
+    <file>modules/esm/cairo.js</file>
+    <file>modules/esm/gettext.js</file>
     <file>modules/esm/gi.js</file>
+    <file>modules/esm/system.js</file>
+
     <!-- Script-based Modules -->
     <file>modules/script/_bootstrap/debugger.js</file>
     <file>modules/script/_bootstrap/default.js</file>
diff --git a/modules/esm/cairo.js b/modules/esm/cairo.js
new file mode 100644
index 00000000..d6127ff1
--- /dev/null
+++ b/modules/esm/cairo.js
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+// SPDX-FileCopyrightText: 2020 Evan Welsh <contact evanwelsh com>
+
+const cairo = import.meta.importSync('cairoNative');
+
+export default Object.assign(
+    {},
+    imports._cairo,
+    cairo
+);
diff --git a/modules/esm/gettext.js b/modules/esm/gettext.js
new file mode 100644
index 00000000..812d9305
--- /dev/null
+++ b/modules/esm/gettext.js
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+// SPDX-FileCopyrightText: 2020 Evan Welsh <contact evanwelsh com>
+
+export let {
+    setlocale,
+    textdomain,
+    bindtextdomain,
+    gettext,
+    dgettext,
+    dcgettext,
+    ngettext,
+    dngettext,
+    pgettext,
+    dpgettext,
+    domain,
+} = imports._gettext;
+
+export default {
+    setlocale,
+    textdomain,
+    bindtextdomain,
+    gettext,
+    dgettext,
+    dcgettext,
+    ngettext,
+    dngettext,
+    pgettext,
+    dpgettext,
+    domain,
+};
diff --git a/modules/esm/system.js b/modules/esm/system.js
new file mode 100644
index 00000000..07cf6c2c
--- /dev/null
+++ b/modules/esm/system.js
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+// SPDX-FileCopyrightText: 2020 Evan Welsh <contact evanwelsh com>
+
+const system = import.meta.importSync('system');
+
+export let {
+    addressOf,
+    refcount,
+    breakpoint,
+    gc,
+    exit,
+    version,
+    programInvocationName,
+    clearDateCaches,
+} = system;
+
+export default {
+    addressOf,
+    refcount,
+    breakpoint,
+    gc,
+    exit,
+    version,
+    programInvocationName,
+    clearDateCaches,
+};


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]