summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Welsh <contact@evanwelsh.com>2022-05-08 15:06:06 -0700
committerEvan Welsh <contact@evanwelsh.com>2022-05-08 15:06:06 -0700
commita06e890b8d06f019b49e5db29387df42547e8e6b (patch)
tree2d68c36342302a9bd4bfef535d5c00daf5f8da04
parent6ab6db38fe5a45979167d2b6f0cadd06a772798f (diff)
downloadgjs-ewlsh/replace-internal-imports.tar.gz
modules: Use ESM as the primary module systemewlsh/replace-internal-imports
-rw-r--r--.eslintrc.yml5
-rw-r--r--gi/repo.cpp124
-rw-r--r--gjs/context.cpp2
-rw-r--r--gjs/engine.cpp13
-rw-r--r--gjs/global.cpp5
-rw-r--r--gjs/importer.cpp1
-rw-r--r--gjs/module.cpp83
-rw-r--r--gjs/module.h2
-rw-r--r--installed-tests/js/testGObject.js2
-rw-r--r--js.gresource.xml35
-rw-r--r--modules/_bootstrap/.eslintrc.yml (renamed from modules/script/_bootstrap/.eslintrc.yml)0
-rw-r--r--modules/_bootstrap/coverage.js (renamed from modules/script/_bootstrap/coverage.js)0
-rw-r--r--modules/_bootstrap/debugger.js (renamed from modules/script/_bootstrap/debugger.js)0
-rw-r--r--modules/_bootstrap/default.js (renamed from modules/script/_bootstrap/default.js)0
-rw-r--r--modules/common/class.js (renamed from modules/core/_common.js)6
-rw-r--r--modules/core/_cairo.js128
-rw-r--r--modules/core/_gettext.js83
-rw-r--r--modules/deprecated/.eslintrc.yml (renamed from modules/core/.eslintrc.yml)6
-rw-r--r--modules/deprecated/_legacy.js (renamed from modules/script/_legacy.js)16
-rw-r--r--modules/deprecated/format.js (renamed from modules/core/_format.js)46
-rw-r--r--modules/deprecated/legacyImports.js38
-rw-r--r--modules/deprecated/signals.js (renamed from modules/core/_signals.js)12
-rw-r--r--modules/esm/_bootstrap/default.js9
-rw-r--r--modules/esm/_bootstrap/legacyImports.js9
-rw-r--r--modules/esm/cairo.js145
-rw-r--r--modules/esm/gettext.js101
-rw-r--r--modules/internal/.eslintrc.yml1
-rw-r--r--modules/internal/loader.js89
-rw-r--r--modules/overrides/.eslintrc.yml (renamed from modules/core/overrides/.eslintrc.yml)7
-rw-r--r--modules/overrides/GLib.js (renamed from modules/core/overrides/GLib.js)95
-rw-r--r--modules/overrides/GObject.js (renamed from modules/core/overrides/GObject.js)41
-rw-r--r--modules/overrides/Gio.js (renamed from modules/core/overrides/Gio.js)36
-rw-r--r--modules/overrides/Gtk.js (renamed from modules/core/overrides/Gtk.js)16
-rw-r--r--modules/overrides/cairo.js (renamed from modules/core/overrides/cairo.js)7
-rw-r--r--modules/print.cpp31
-rw-r--r--modules/script/cairo.js3
-rw-r--r--modules/script/format.js23
-rw-r--r--modules/script/gettext.js18
-rw-r--r--modules/script/lang.js5
-rw-r--r--modules/script/overrides/__init__.js1
-rw-r--r--modules/script/signals.js19
41 files changed, 747 insertions, 516 deletions
diff --git a/.eslintrc.yml b/.eslintrc.yml
index 97e728f9..3da99101 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -69,7 +69,10 @@ rules:
jsdoc/check-types: error
jsdoc/implements-on-classes: error
jsdoc/newline-after-description: error
- jsdoc/require-jsdoc: error
+ jsdoc/require-jsdoc:
+ - error
+ - publicOnly: true
+ enableFixer: false
jsdoc/require-param: error
jsdoc/require-param-description: error
jsdoc/require-param-name: error
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 9f5d4e1f..6059b720 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -50,6 +50,8 @@
#include "util/log.h"
GJS_JSAPI_RETURN_CONVENTION
+static bool load_override_module(JSContext*, const char* ns_name);
+GJS_JSAPI_RETURN_CONVENTION
static bool lookup_override_function(JSContext *, JS::HandleId,
JS::MutableHandleValue);
@@ -128,6 +130,9 @@ static bool resolve_namespace_object(JSContext* context,
GJS_MODULE_PROP_FLAGS))
return false;
+ if (!load_override_module(context, ns_name.get()))
+ return false;
+
JS::RootedValue override(context);
if (!lookup_override_function(context, ns_id, &override))
return false;
@@ -515,6 +520,125 @@ out:
return retval;
}
+static bool add_promise_reactions(JSContext* cx, JS::HandleValue promise,
+ JSNative resolve, JSNative reject,
+ const std::string& debug_tag) {
+ g_assert(promise.isObject() && "got weird value from JS::ModuleEvaluate");
+ JS::RootedObject promise_object(cx, &promise.toObject());
+
+ std::string resolved_tag = debug_tag + " async resolved";
+ std::string rejected_tag = debug_tag + " async rejected";
+
+ JS::RootedFunction on_rejected(
+ cx,
+ js::NewFunctionWithReserved(cx, reject, 1, 0, resolved_tag.c_str()));
+ if (!on_rejected)
+ return false;
+ JS::RootedFunction on_resolved(
+ cx,
+ js::NewFunctionWithReserved(cx, resolve, 1, 0, rejected_tag.c_str()));
+ if (!on_resolved)
+ return false;
+
+ JS::RootedObject resolved(cx, JS_GetFunctionObject(on_resolved));
+ JS::RootedObject rejected(cx, JS_GetFunctionObject(on_rejected));
+
+ return JS::AddPromiseReactions(cx, promise_object, resolved, rejected);
+}
+
+static bool on_context_module_resolved(JSContext* cx, unsigned argc,
+ JS::Value* vp) {
+ JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+ args.rval().setUndefined();
+
+ GjsContextPrivate::from_cx(cx)->main_loop_release();
+
+ return true;
+}
+
+static bool load_override_module_(JSContext* cx, const char* uri,
+ const char* debug_identifier) {
+ JS::RootedObject loader(cx, gjs_module_load(cx, uri, uri, true));
+
+ if (!loader) {
+ return false;
+ }
+
+ if (!JS::ModuleInstantiate(cx, loader)) {
+ gjs_log_exception(cx);
+ return false;
+ }
+
+ JS::RootedValue evaluation_promise(cx);
+ if (!JS::ModuleEvaluate(cx, loader, &evaluation_promise)) {
+ gjs_log_exception(cx);
+ return false;
+ }
+
+ GjsContextPrivate::from_cx(cx)->main_loop_hold();
+ bool ok = add_promise_reactions(
+ cx, evaluation_promise, on_context_module_resolved,
+ [](JSContext* cx, unsigned argc, JS::Value* vp) {
+ JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+ JS::HandleValue error = args.get(0);
+
+ GjsContextPrivate* gjs_cx = GjsContextPrivate::from_cx(cx);
+ gjs_cx->report_unhandled_exception();
+
+ gjs_log_exception_full(cx, error, nullptr, G_LOG_LEVEL_CRITICAL);
+
+ gjs_cx->main_loop_release();
+
+ args.rval().setUndefined();
+
+ return false;
+ },
+ "overrides");
+
+ if (!ok) {
+ gjs_log_exception(cx);
+ return false;
+ }
+
+ return true;
+}
+
+GJS_JSAPI_RETURN_CONVENTION
+static bool load_override_module(JSContext* cx, const char* ns_name) {
+ JS::AutoSaveExceptionState saved_exc(cx);
+
+ JS::RootedObject global(cx, gjs_get_import_global(cx));
+ JS::RootedValue importer(
+ cx, gjs_get_global_slot(global, GjsGlobalSlot::IMPORTS));
+ g_assert(importer.isObject());
+
+ JS::RootedObject overridespkg(cx), module(cx);
+ JS::RootedObject importer_obj(cx, &importer.toObject());
+ const GjsAtoms& atoms = GjsContextPrivate::atoms(cx);
+
+ GjsAutoChar uri = g_strdup_printf(
+ "resource:///org/gnome/gjs/modules/overrides/%s.js", ns_name);
+ if (!load_override_module_(cx, uri, ns_name)) {
+ JS::RootedValue exc(cx);
+ JS_GetPendingException(cx, &exc);
+
+ /* If the exception was an ImportError (i.e., module not found) then
+ * we simply didn't have an override, don't throw an exception */
+ if (error_has_name(cx, exc,
+ JS_AtomizeAndPinString(cx, "ImportError"))) {
+ saved_exc.restore();
+ return true;
+ }
+ goto fail;
+ }
+
+ return true;
+
+fail:
+ saved_exc.drop();
+ return false;
+}
+
GJS_JSAPI_RETURN_CONVENTION
static bool
lookup_override_function(JSContext *cx,
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 4e22825d..1a1a18ef 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -577,7 +577,7 @@ static bool add_promise_reactions(JSContext* cx, JS::HandleValue promise,
static void load_context_module(JSContext* cx, const char* uri,
const char* debug_identifier) {
- JS::RootedObject loader(cx, gjs_module_load(cx, uri, uri));
+ JS::RootedObject loader(cx, gjs_module_load(cx, uri, uri, true));
if (!loader) {
gjs_log_exception(cx);
diff --git a/gjs/engine.cpp b/gjs/engine.cpp
index 16d84cc1..fe3ea516 100644
--- a/gjs/engine.cpp
+++ b/gjs/engine.cpp
@@ -79,7 +79,7 @@ class GjsSourceHook : public js::SourceHook {
#ifdef G_OS_WIN32
HMODULE gjs_dll;
-static bool gjs_is_inited = false;
+static bool _gjs_is_inited = false;
BOOL WINAPI
DllMain (HINSTANCE hinstDLL,
@@ -90,7 +90,7 @@ LPVOID lpvReserved)
{
case DLL_PROCESS_ATTACH:
gjs_dll = hinstDLL;
- gjs_is_inited = JS_Init();
+ _gjs_is_inited = JS_Init();
break;
case DLL_THREAD_DETACH:
@@ -105,6 +105,7 @@ LPVOID lpvReserved)
return TRUE;
}
+static bool gjs_is_inited() { return _gjs_is_inited; }
#else
class GjsInit {
public:
@@ -120,11 +121,15 @@ public:
explicit operator bool() const { return true; }
};
-static GjsInit gjs_is_inited;
+static bool gjs_is_inited() {
+ static GjsInit gjs_is_inited;
+
+ return !!gjs_is_inited;
+}
#endif
JSContext* gjs_create_js_context(GjsContextPrivate* uninitialized_gjs) {
- g_assert(gjs_is_inited);
+ g_assert(gjs_is_inited());
JSContext *cx = JS_NewContext(32 * 1024 * 1024 /* max bytes */);
if (!cx)
return nullptr;
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 56fe8602..8f3f4cce 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -88,7 +88,7 @@ class GjsBaseGlobal {
static bool run_bootstrap(JSContext* cx, const char* bootstrap_script,
JS::HandleObject global) {
GjsAutoChar uri = g_strdup_printf(
- "resource:///org/gnome/gjs/modules/script/_bootstrap/%s.js",
+ "resource:///org/gnome/gjs/modules/_bootstrap/%s.js",
bootstrap_script);
JSAutoRealm ar(cx, global);
@@ -288,6 +288,7 @@ class GjsInternalGlobal : GjsBaseGlobal {
0),
JS_FN("setModulePrivate", gjs_internal_set_module_private, 2, 0),
JS_FN("uriExists", gjs_internal_uri_exists, 1, 0),
+ JS_FN("loadNative", &load_native_module, 1, 0),
JS_FS_END};
static constexpr JSClass klass = {
@@ -486,7 +487,7 @@ bool gjs_global_registry_get(JSContext* cx, JS::HandleObject registry,
* @global: a JS global object that has not yet been passed to this function
* @realm_name: (nullable): name of the realm, for debug output
* @bootstrap_script: (nullable): name of a bootstrap script (found at
- * resource://org/gnome/gjs/modules/script/_bootstrap/@bootstrap_script) or
+ * resource://org/gnome/gjs/modules/_bootstrap/@bootstrap_script) or
* %NULL for none
*
* Defines properties on the global object such as 'window' and 'imports', and
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index c8bc553e..c94d428e 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -798,7 +798,6 @@ JSFunctionSpec gjs_importer_proto_funcs[] = {
}
gjs_search_path.push_back("resource:///org/gnome/gjs/modules/script/");
- gjs_search_path.push_back("resource:///org/gnome/gjs/modules/core/");
/* $XDG_DATA_DIRS /gjs-1.0 */
system_data_dirs = g_get_system_data_dirs();
diff --git a/gjs/module.cpp b/gjs/module.cpp
index 3b54a3fc..502e8e47 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -4,7 +4,7 @@
#include <config.h>
-#include <stddef.h> // for size_t
+#include <stddef.h> // for size_t
#include <string.h>
#include <string> // for u16string
@@ -34,7 +34,7 @@
#include <js/Utility.h> // for UniqueChars
#include <js/Value.h>
#include <js/ValueArray.h>
-#include <jsapi.h> // for JS_DefinePropertyById, ...
+#include <jsapi.h> // for JS_DefinePropertyById, ...
#include <jsfriendapi.h> // for SetFunctionNativeReserved
#include <mozilla/Maybe.h>
@@ -54,7 +54,7 @@ union Utf8Unit;
}
class GjsScriptModule {
- char *m_name;
+ char* m_name;
GjsScriptModule(const char* name) {
m_name = g_strdup(name);
@@ -84,12 +84,8 @@ class GjsScriptModule {
/* Defines the empty module as a property on the importer */
GJS_JSAPI_RETURN_CONVENTION
- bool
- define_import(JSContext *cx,
- JS::HandleObject module,
- JS::HandleObject importer,
- JS::HandleId name) const
- {
+ bool define_import(JSContext* cx, JS::HandleObject module,
+ JS::HandleObject importer, JS::HandleId name) const {
if (!JS_DefinePropertyById(cx, importer, name, module,
GJS_MODULE_PROP_FLAGS & ~JSPROP_PERMANENT)) {
gjs_debug(GJS_DEBUG_IMPORTER, "Failed to define '%s' in importer",
@@ -141,12 +137,8 @@ class GjsScriptModule {
/* Loads JS code from a file and imports it */
GJS_JSAPI_RETURN_CONVENTION
- bool
- import_file(JSContext *cx,
- JS::HandleObject module,
- GFile *file)
- {
- GError *error = nullptr;
+ bool import_file(JSContext* cx, JS::HandleObject module, GFile* file) {
+ GError* error = nullptr;
GjsAutoChar script;
size_t script_len = 0;
@@ -163,16 +155,12 @@ class GjsScriptModule {
/* JSClass operations */
GJS_JSAPI_RETURN_CONVENTION
- bool
- resolve_impl(JSContext *cx,
- JS::HandleObject module,
- JS::HandleId id,
- bool *resolved)
- {
+ bool resolve_impl(JSContext* cx, JS::HandleObject module, JS::HandleId id,
+ bool* resolved) {
JS::RootedObject lexical(cx, JS_ExtensibleLexicalEnvironment(module));
if (!lexical) {
*resolved = false;
- return true; /* nothing imported yet */
+ return true; /* nothing imported yet */
}
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> maybe_desc(cx);
@@ -187,26 +175,23 @@ class GjsScriptModule {
* be supported according to ES6. For compatibility with earlier GJS,
* we treat it as if it were a real property, but warn about it. */
- g_warning("Some code accessed the property '%s' on the module '%s'. "
- "That property was defined with 'let' or 'const' inside the "
- "module. This was previously supported, but is not correct "
- "according to the ES6 standard. Any symbols to be exported "
- "from a module must be defined with 'var'. The property "
- "access will work as previously for the time being, but "
- "please fix your code anyway.",
- gjs_debug_id(id).c_str(), m_name);
+ g_warning(
+ "Some code accessed the property '%s' on the module '%s'. "
+ "That property was defined with 'let' or 'const' inside the "
+ "module. This was previously supported, but is not correct "
+ "according to the ES6 standard. Any symbols to be exported "
+ "from a module must be defined with 'var'. The property "
+ "access will work as previously for the time being, but "
+ "please fix your code anyway.",
+ gjs_debug_id(id).c_str(), m_name);
JS::Rooted<JS::PropertyDescriptor> desc(cx, maybe_desc.value());
return JS_DefinePropertyById(cx, module, id, desc);
}
GJS_JSAPI_RETURN_CONVENTION
- static bool
- resolve(JSContext *cx,
- JS::HandleObject module,
- JS::HandleId id,
- bool *resolved)
- {
+ static bool resolve(JSContext* cx, JS::HandleObject module, JS::HandleId id,
+ bool* resolved) {
return priv(module)->resolve_impl(cx, module, id, resolved);
}
@@ -248,16 +233,10 @@ class GjsScriptModule {
/* Carries out the import operation */
GJS_JSAPI_RETURN_CONVENTION
- static JSObject *
- import(JSContext *cx,
- JS::HandleObject importer,
- JS::HandleId id,
- const char *name,
- GFile *file)
- {
+ static JSObject* import(JSContext* cx, JS::HandleObject importer,
+ JS::HandleId id, const char* name, GFile* file) {
JS::RootedObject module(cx, GjsScriptModule::create(cx, name));
- if (!module ||
- !priv(module)->define_import(cx, module, importer, id) ||
+ if (!module || !priv(module)->define_import(cx, module, importer, id) ||
!priv(module)->import_file(cx, module, file))
return nullptr;
@@ -296,13 +275,8 @@ JSObject* gjs_script_module_build_private(JSContext* cx, const char* uri) {
*
* Returns: the JS module object, or nullptr on failure.
*/
-JSObject *
-gjs_module_import(JSContext *cx,
- JS::HandleObject importer,
- JS::HandleId id,
- const char *name,
- GFile *file)
-{
+JSObject* gjs_module_import(JSContext* cx, JS::HandleObject importer,
+ JS::HandleId id, const char* name, GFile* file) {
return GjsScriptModule::import(cx, importer, id, name, file);
}
@@ -357,7 +331,7 @@ JSObject* gjs_get_module_registry(JSObject* global) {
* @returns whether an error occurred while resolving the specifier.
*/
JSObject* gjs_module_load(JSContext* cx, const char* identifier,
- const char* file_uri) {
+ const char* file_uri, bool internal) {
g_assert((gjs_global_is_type(cx, GjsGlobalType::DEFAULT) ||
gjs_global_is_type(cx, GjsGlobalType::INTERNAL)) &&
"gjs_module_load can only be called from module-enabled "
@@ -378,9 +352,10 @@ JSObject* gjs_module_load(JSContext* cx, const char* identifier,
if (!uri)
return nullptr;
- JS::RootedValueArray<2> args(cx);
+ JS::RootedValueArray<3> args(cx);
args[0].setString(id);
args[1].setString(uri);
+ args[2].setBoolean(internal);
gjs_debug(GJS_DEBUG_IMPORTER,
"Module resolve hook for module '%s' (%s), global %p", identifier,
diff --git a/gjs/module.h b/gjs/module.h
index f6b3a353..5e2d477d 100644
--- a/gjs/module.h
+++ b/gjs/module.h
@@ -32,7 +32,7 @@ JSObject* gjs_get_module_registry(JSObject* global);
GJS_JSAPI_RETURN_CONVENTION
JSObject* gjs_module_load(JSContext* cx, const char* identifier,
- const char* uri);
+ const char* uri, bool internal = false);
GJS_JSAPI_RETURN_CONVENTION
JSObject* gjs_module_resolve(JSContext* cx,
diff --git a/installed-tests/js/testGObject.js b/installed-tests/js/testGObject.js
index 160f85ab..d8848723 100644
--- a/installed-tests/js/testGObject.js
+++ b/installed-tests/js/testGObject.js
@@ -2,7 +2,7 @@
// SPDX-FileCopyrightText: 2013 Giovanni Campagna <gcampagna@src.gnome.org>
// SPDX-FileCopyrightText: 2018 Red Hat, Inc.
-// This is where overrides in modules/core/overrides/GObject.js are tested,
+// This is where overrides in modules/overrides/GObject.js are tested,
// except for the class machinery, interface machinery, and GObject.ParamSpec,
// which are big enough to get their own files.
diff --git a/js.gresource.xml b/js.gresource.xml
index e12dea12..817818fa 100644
--- a/js.gresource.xml
+++ b/js.gresource.xml
@@ -3,10 +3,13 @@
<!-- SPDX-FileCopyrightText: 2014 Red Hat, Inc. -->
<gresources>
<gresource prefix="/org/gnome/gjs">
+ <file>modules/common/class.js</file>
+
<!-- Internal modules -->
<file>modules/internal/loader.js</file>
<!-- ESM-based modules -->
+ <file>modules/esm/_bootstrap/legacyImports.js</file>
<file>modules/esm/_bootstrap/default.js</file>
<file>modules/esm/_encoding/encoding.js</file>
@@ -22,19 +25,18 @@
<file>modules/esm/system.js</file>
<!-- Script-based Modules -->
- <file>modules/script/_bootstrap/debugger.js</file>
- <file>modules/script/_bootstrap/default.js</file>
- <file>modules/script/_bootstrap/coverage.js</file>
+ <file>modules/_bootstrap/debugger.js</file>
+ <file>modules/_bootstrap/default.js</file>
+ <file>modules/_bootstrap/coverage.js</file>
<file>modules/script/tweener/equations.js</file>
<file>modules/script/tweener/tweener.js</file>
<file>modules/script/tweener/tweenList.js</file>
-
+ <file>modules/script/overrides/__init__.js</file>
<file>modules/script/byteArray.js</file>
<file>modules/script/cairo.js</file>
<file>modules/script/gettext.js</file>
<file>modules/script/lang.js</file>
- <file>modules/script/_legacy.js</file>
<file>modules/script/mainloop.js</file>
<file>modules/script/jsUnit.js</file>
<file>modules/script/signals.js</file>
@@ -42,16 +44,15 @@
<file>modules/script/package.js</file>
<!-- Core Modules -->
- <file>modules/core/overrides/cairo.js</file>
- <file>modules/core/overrides/GLib.js</file>
- <file>modules/core/overrides/Gio.js</file>
- <file>modules/core/overrides/GObject.js</file>
- <file>modules/core/overrides/Gtk.js</file>
-
- <file>modules/core/_cairo.js</file>
- <file>modules/core/_common.js</file>
- <file>modules/core/_format.js</file>
- <file>modules/core/_gettext.js</file>
- <file>modules/core/_signals.js</file>
+ <file>modules/overrides/cairo.js</file>
+ <file>modules/overrides/GLib.js</file>
+ <file>modules/overrides/Gio.js</file>
+ <file>modules/overrides/GObject.js</file>
+ <file>modules/overrides/Gtk.js</file>
+
+ <file>modules/deprecated/legacyImports.js</file>
+ <file>modules/deprecated/_legacy.js</file>
+ <file>modules/deprecated/format.js</file>
+ <file>modules/deprecated/signals.js</file>
</gresource>
-</gresources>
+</gresources> \ No newline at end of file
diff --git a/modules/script/_bootstrap/.eslintrc.yml b/modules/_bootstrap/.eslintrc.yml
index fda87577..fda87577 100644
--- a/modules/script/_bootstrap/.eslintrc.yml
+++ b/modules/_bootstrap/.eslintrc.yml
diff --git a/modules/script/_bootstrap/coverage.js b/modules/_bootstrap/coverage.js
index 1af74c42..1af74c42 100644
--- a/modules/script/_bootstrap/coverage.js
+++ b/modules/_bootstrap/coverage.js
diff --git a/modules/script/_bootstrap/debugger.js b/modules/_bootstrap/debugger.js
index 6ae0d9c2..6ae0d9c2 100644
--- a/modules/script/_bootstrap/debugger.js
+++ b/modules/_bootstrap/debugger.js
diff --git a/modules/script/_bootstrap/default.js b/modules/_bootstrap/default.js
index 8c211a5a..8c211a5a 100644
--- a/modules/script/_bootstrap/default.js
+++ b/modules/_bootstrap/default.js
diff --git a/modules/core/_common.js b/modules/common/class.js
index 1a7fe772..7b514c84 100644
--- a/modules/core/_common.js
+++ b/modules/common/class.js
@@ -8,9 +8,9 @@
// This is a helper module in which to put code that is common between the
// legacy GObject.Class system and the new GObject.registerClass system.
-var _registerType = Symbol('GObject register type hook');
+export const _registerType = Symbol('GObject register type hook');
-function _generateAccessors(pspec, propdesc, GObject) {
+export function _generateAccessors(pspec, propdesc, GObject) {
const {name, flags} = pspec;
const readable = flags & GObject.ParamFlags.READABLE;
const writable = flags & GObject.ParamFlags.WRITABLE;
@@ -59,7 +59,7 @@ function _generateAccessors(pspec, propdesc, GObject) {
return propdesc;
}
-function _checkAccessors(proto, pspec, GObject) {
+export function _checkAccessors(proto, pspec, GObject) {
const {name, flags} = pspec;
if (flags & GObject.ParamFlags.CONSTRUCT_ONLY)
return;
diff --git a/modules/core/_cairo.js b/modules/core/_cairo.js
deleted file mode 100644
index 0bea8cad..00000000
--- a/modules/core/_cairo.js
+++ /dev/null
@@ -1,128 +0,0 @@
-// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
-// SPDX-FileCopyrightText: 2010 litl, LLC.
-
-/* exported Antialias, Content, Extend, FillRule, Filter, FontSlant, FontWeight,
-Format, LineCap, LineJoin, Operator, PatternType, SurfaceType */
-
-var Antialias = {
- DEFAULT: 0,
- NONE: 1,
- GRAY: 2,
- SUBPIXEL: 3,
-};
-
-var Content = {
- COLOR: 0x1000,
- ALPHA: 0x2000,
- COLOR_ALPHA: 0x3000,
-};
-
-var Extend = {
- NONE: 0,
- REPEAT: 1,
- REFLECT: 2,
- PAD: 3,
-};
-
-var FillRule = {
- WINDING: 0,
- EVEN_ODD: 1,
-};
-
-var Filter = {
- FAST: 0,
- GOOD: 1,
- BEST: 2,
- NEAREST: 3,
- BILINEAR: 4,
- GAUSSIAN: 5,
-};
-
-var FontSlant = {
- NORMAL: 0,
- ITALIC: 1,
- OBLIQUE: 2,
-};
-
-var FontWeight = {
- NORMAL: 0,
- BOLD: 1,
-};
-
-var Format = {
- ARGB32: 0,
- RGB24: 1,
- A8: 2,
- A1: 3,
- // The value of 4 is reserved by a deprecated enum value
- RGB16_565: 5,
-};
-
-var LineCap = {
- BUTT: 0,
- ROUND: 1,
- SQUASH: 2,
-};
-
-var LineJoin = {
- MITER: 0,
- ROUND: 1,
- BEVEL: 2,
-};
-
-var Operator = {
- CLEAR: 0,
- SOURCE: 1,
- OVER: 2,
- IN: 3,
- OUT: 4,
- ATOP: 5,
- DEST: 6,
- DEST_OVER: 7,
- DEST_IN: 8,
- DEST_OUT: 9,
- DEST_ATOP: 10,
- XOR: 11,
- ADD: 12,
- SATURATE: 13,
- MULTIPLY: 14,
- SCREEN: 15,
- OVERLAY: 16,
- DARKEN: 17,
- LIGHTEN: 18,
- COLOR_DODGE: 19,
- COLOR_BURN: 20,
- HARD_LIGHT: 21,
- SOFT_LIGHT: 22,
- DIFFERENCE: 23,
- EXCLUSION: 24,
- HSL_HUE: 25,
- HSL_SATURATION: 26,
- HSL_COLOR: 27,
- HSL_LUMINOSITY: 28,
-};
-
-var PatternType = {
- SOLID: 0,
- SURFACE: 1,
- LINEAR: 2,
- RADIAL: 3,
-};
-
-var SurfaceType = {
- IMAGE: 0,
- PDF: 1,
- PS: 2,
- XLIB: 3,
- XCB: 4,
- GLITZ: 5,
- QUARTZ: 6,
- WIN32: 7,
- BEOS: 8,
- DIRECTFB: 9,
- SVG: 10,
- OS2: 11,
- WIN32_PRINTING: 12,
- QUARTZ_IMAGE: 13,
-};
-
diff --git a/modules/core/_gettext.js b/modules/core/_gettext.js
deleted file mode 100644
index 376ad93f..00000000
--- a/modules/core/_gettext.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
-// SPDX-FileCopyrightText: 2009 Red Hat, Inc.
-
-/* exported bindtextdomain, dcgettext, dgettext, dngettext, domain, dpgettext,
-gettext, LocaleCategory, ngettext, pgettext, setlocale, textdomain */
-
-/**
- * This module provides a convenience layer for the "gettext" family of functions,
- * relying on GLib for the actual implementation.
- *
- * Usage:
- *
- * const Gettext = imports.gettext;
- *
- * Gettext.textdomain("myapp");
- * Gettext.bindtextdomain("myapp", "/usr/share/locale");
- *
- * let translated = Gettext.gettext("Hello world!");
- */
-
-const GLib = imports.gi.GLib;
-const GjsPrivate = imports.gi.GjsPrivate;
-
-var LocaleCategory = GjsPrivate.LocaleCategory;
-
-function setlocale(category, locale) {
- return GjsPrivate.setlocale(category, locale);
-}
-
-function textdomain(dom) {
- return GjsPrivate.textdomain(dom);
-}
-function bindtextdomain(dom, location) {
- return GjsPrivate.bindtextdomain(dom, location);
-}
-
-function gettext(msgid) {
- return GLib.dgettext(null, msgid);
-}
-function dgettext(dom, msgid) {
- return GLib.dgettext(dom, msgid);
-}
-function dcgettext(dom, msgid, category) {
- return GLib.dcgettext(dom, msgid, category);
-}
-
-function ngettext(msgid1, msgid2, n) {
- return GLib.dngettext(null, msgid1, msgid2, n);
-}
-function dngettext(dom, msgid1, msgid2, n) {
- return GLib.dngettext(dom, msgid1, msgid2, n);
-}
-// FIXME: missing dcngettext ?
-
-function pgettext(context, msgid) {
- return GLib.dpgettext2(null, context, msgid);
-}
-function dpgettext(dom, context, msgid) {
- return GLib.dpgettext2(dom, context, msgid);
-}
-
-/**
- * Create an object with bindings for gettext, ngettext,
- * and pgettext bound to a particular translation domain.
- *
- * @param {string} domainName Translation domain string
- * @returns {object} an object with gettext bindings
- */
-function domain(domainName) {
- return {
- gettext(msgid) {
- return GLib.dgettext(domainName, msgid);
- },
-
- ngettext(msgid1, msgid2, n) {
- return GLib.dngettext(domainName, msgid1, msgid2, n);
- },
-
- pgettext(context, msgid) {
- return GLib.dpgettext2(domainName, context, msgid);
- },
- };
-}
diff --git a/modules/core/.eslintrc.yml b/modules/deprecated/.eslintrc.yml
index 6c9c0253..84e48aef 100644
--- a/modules/core/.eslintrc.yml
+++ b/modules/deprecated/.eslintrc.yml
@@ -1,5 +1,7 @@
---
# SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
# SPDX-FileCopyrightText: 2020 Evan Welsh <contact@evanwelsh.com>
-rules:
- jsdoc/require-jsdoc: 'off'
+extends: '../../.eslintrc.yml'
+parserOptions:
+ sourceType: 'module'
+ ecmaVersion: 2022
diff --git a/modules/script/_legacy.js b/modules/deprecated/_legacy.js
index 135d2517..4500c5fa 100644
--- a/modules/script/_legacy.js
+++ b/modules/deprecated/_legacy.js
@@ -1,6 +1,5 @@
/* -*- mode: js; indent-tabs-mode: nil; -*- */
-/* exported Class, Interface, defineGObjectLegacyObjects,
-defineGtkLegacyObjects */
+/* eslint-disable jsdoc/require-jsdoc, no-invalid-this */
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2008 litl, LLC
// SPDX-FileCopyrightText: 2011 Jasper St. Pierre
@@ -9,6 +8,10 @@ defineGtkLegacyObjects */
// Adapted from MooTools
// https://github.com/mootools/mootools-core
+import {_checkAccessors} from '../common/class.js';
+
+const Gi = import.meta.importSync('_gi');
+
function _Base() {
throw new TypeError('Cannot instantiate abstract class _Base');
}
@@ -411,10 +414,7 @@ Interface.prototype._init = function (params) {
// GObject Lang.Class magic
-function defineGObjectLegacyObjects(GObject) {
- const Gi = imports._gi;
- const {_checkAccessors} = imports._common;
-
+export function defineGObjectLegacyObjects(GObject) {
// Some common functions between GObject.Class and GObject.Interface
function _createSignals(gtype, signals) {
@@ -646,7 +646,7 @@ function defineGObjectLegacyObjects(GObject) {
return {GObjectMeta, GObjectInterface};
}
-function defineGtkLegacyObjects(GObject, Gtk) {
+export function defineGtkLegacyObjects(GObject, Gtk) {
const GtkWidgetClass = new Class({
Name: 'GtkWidgetClass',
Extends: GObject.Class,
@@ -715,3 +715,5 @@ function defineGtkLegacyObjects(GObject, Gtk) {
return {GtkWidgetClass};
}
+
+export {Class, Interface, getMetaClass};
diff --git a/modules/core/_format.js b/modules/deprecated/format.js
index eb6f0319..55e652af 100644
--- a/modules/core/_format.js
+++ b/modules/deprecated/format.js
@@ -3,10 +3,12 @@
// SPDX-FileCopyrightText: 2012 Red Hat, Inc.
// SPDX-FileCopyrightText: 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
-/* exported vprintf */
-
-const GjsPrivate = imports.gi.GjsPrivate;
+import GjsPrivate from 'gi://GjsPrivate';
+/**
+ * @param string
+ * @param args
+ */
function vprintf(string, args) {
let i = 0;
let usePos = false;
@@ -29,11 +31,19 @@ function vprintf(string, args) {
let fillChar = widthGroup && widthGroup[0] === '0' ? '0' : ' ';
let width = parseInt(widthGroup, 10) || 0;
+ /**
+ * @param s
+ * @param c
+ * @param w
+ */
function fillWidth(s, c, w) {
let fill = c.repeat(w);
return fill.substr(s.length) + s;
}
+ /**
+ *
+ */
function getArg() {
return usePos ? args[pos - 1] : args[i++];
}
@@ -68,3 +78,33 @@ function vprintf(string, args) {
return fillWidth(s, fillChar, width);
});
}
+
+/**
+ * @param fmt
+ * @param {...any} args
+ */
+function printf(fmt, ...args) {
+ print(vprintf(fmt, args));
+}
+
+/**
+ * This function is intended to extend the String object and provide a
+ * String.format API for string formatting.
+ * It has to be set up using String.prototype.format = Format.format;
+ * Usage:
+ * "somestring %s %d".format('hello', 5);
+ * It supports %s, %d, %x and %f.
+ * For %f it also supports precisions like "%.2f".format(1.526).
+ * All specifiers can be prefixed with a minimum field width, e.g.
+ * "%5s".format("foo").
+ * Unless the width is prefixed with '0', the formatted string will be padded
+ * with spaces.
+ *
+ * @this {string}
+ * @param {...any} args
+ */
+function format(...args) {
+ return vprintf(this, args);
+}
+
+export {vprintf, printf, format};
diff --git a/modules/deprecated/legacyImports.js b/modules/deprecated/legacyImports.js
new file mode 100644
index 00000000..02c026d2
--- /dev/null
+++ b/modules/deprecated/legacyImports.js
@@ -0,0 +1,38 @@
+
+import {Class, Interface, getMetaClass} from './_legacy.js';
+import {
+ _connect,
+ _disconnect,
+ _emit,
+ _signalHandlerIsConnected,
+ _disconnectAll,
+ addSignalMethods
+} from './signals.js';
+import {format, vprintf, printf} from './format.js';
+
+if ('imports' in globalThis) {
+ // eslint-disable-next-line no-restricted-properties
+ Object.assign(imports.format, {format, vprintf, printf});
+ Object.assign(imports.lang, {Class, Interface, getMetaClass});
+ Object.assign(imports.signals, {
+ _connect,
+ _disconnect,
+ _emit,
+ _signalHandlerIsConnected,
+ _disconnectAll,
+ addSignalMethods,
+ });
+
+ const Lang = imports.lang;
+
+ const WithSignals = new Lang.Interface({
+ Name: 'WithSignals',
+ connect: _connect,
+ disconnect: _disconnect,
+ emit: _emit,
+ signalHandlerIsConnected: _signalHandlerIsConnected,
+ disconnectAll: _disconnectAll,
+ });
+
+ Object.assign(imports.signals, {WithSignals});
+}
diff --git a/modules/core/_signals.js b/modules/deprecated/signals.js
index 25dcfd47..7a9941fe 100644
--- a/modules/core/_signals.js
+++ b/modules/deprecated/signals.js
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2008 litl, LLC
-/* exported addSignalMethods */
-
// A couple principals of this simple signal system:
// 1) should look just like our GObject signal binding
// 2) memory and safety matter more than speed of connect/disconnect/emit
@@ -58,6 +56,9 @@ function _disconnect(id) {
throw new Error(`No signal connection ${id} found`);
}
+/**
+ * @param id
+ */
function _signalHandlerIsConnected(id) {
if (!('_signalConnections' in this))
return false;
@@ -141,3 +142,10 @@ function addSignalMethods(proto) {
// this one is not in GObject, but useful
_addSignalMethod(proto, 'disconnectAll', _disconnectAll);
}
+
+export {
+ // Private API, remains exported for backwards compatibility reasons
+ _connect, _disconnect, _emit, _signalHandlerIsConnected, _disconnectAll,
+ // Public API
+ addSignalMethods
+};
diff --git a/modules/esm/_bootstrap/default.js b/modules/esm/_bootstrap/default.js
index ff1f28bf..5a3972c5 100644
--- a/modules/esm/_bootstrap/default.js
+++ b/modules/esm/_bootstrap/default.js
@@ -9,3 +9,12 @@ import '_encoding/encoding';
import 'console';
// Bootstrap the Timers API
import '_timers';
+
+// Import remaining modules
+import 'gettext';
+
+// Bootstrap the gi module
+import 'gi';
+
+// globalThis.imports compatibility
+import './legacyImports.js';
diff --git a/modules/esm/_bootstrap/legacyImports.js b/modules/esm/_bootstrap/legacyImports.js
new file mode 100644
index 00000000..3b353ba1
--- /dev/null
+++ b/modules/esm/_bootstrap/legacyImports.js
@@ -0,0 +1,9 @@
+import gettext from 'gettext';
+import cairo from 'cairo';
+
+import '../../deprecated/legacyImports.js';
+
+if ('imports' in globalThis) {
+ Object.assign(imports.gettext, gettext);
+ Object.assign(imports.cairo, cairo);
+}
diff --git a/modules/esm/cairo.js b/modules/esm/cairo.js
index d6127ff1..1dc013ef 100644
--- a/modules/esm/cairo.js
+++ b/modules/esm/cairo.js
@@ -1,10 +1,145 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+// SPDX-FileCopyrightText: 2010 litl, LLC.
// SPDX-FileCopyrightText: 2020 Evan Welsh <contact@evanwelsh.com>
+const Antialias = {
+ DEFAULT: 0,
+ NONE: 1,
+ GRAY: 2,
+ SUBPIXEL: 3,
+};
+
+const Content = {
+ COLOR: 0x1000,
+ ALPHA: 0x2000,
+ COLOR_ALPHA: 0x3000,
+};
+
+const Extend = {
+ NONE: 0,
+ REPEAT: 1,
+ REFLECT: 2,
+ PAD: 3,
+};
+
+const FillRule = {
+ WINDING: 0,
+ EVEN_ODD: 1,
+};
+
+const Filter = {
+ FAST: 0,
+ GOOD: 1,
+ BEST: 2,
+ NEAREST: 3,
+ BILINEAR: 4,
+ GAUSSIAN: 5,
+};
+
+const FontSlant = {
+ NORMAL: 0,
+ ITALIC: 1,
+ OBLIQUE: 2,
+};
+
+const FontWeight = {
+ NORMAL: 0,
+ BOLD: 1,
+};
+
+const Format = {
+ ARGB32: 0,
+ RGB24: 1,
+ A8: 2,
+ A1: 3,
+ // The value of 4 is reserved by a deprecated enum value
+ RGB16_565: 5,
+};
+
+const LineCap = {
+ BUTT: 0,
+ ROUND: 1,
+ SQUASH: 2,
+};
+
+const LineJoin = {
+ MITER: 0,
+ ROUND: 1,
+ BEVEL: 2,
+};
+
+const Operator = {
+ CLEAR: 0,
+ SOURCE: 1,
+ OVER: 2,
+ IN: 3,
+ OUT: 4,
+ ATOP: 5,
+ DEST: 6,
+ DEST_OVER: 7,
+ DEST_IN: 8,
+ DEST_OUT: 9,
+ DEST_ATOP: 10,
+ XOR: 11,
+ ADD: 12,
+ SATURATE: 13,
+ MULTIPLY: 14,
+ SCREEN: 15,
+ OVERLAY: 16,
+ DARKEN: 17,
+ LIGHTEN: 18,
+ COLOR_DODGE: 19,
+ COLOR_BURN: 20,
+ HARD_LIGHT: 21,
+ SOFT_LIGHT: 22,
+ DIFFERENCE: 23,
+ EXCLUSION: 24,
+ HSL_HUE: 25,
+ HSL_SATURATION: 26,
+ HSL_COLOR: 27,
+ HSL_LUMINOSITY: 28,
+};
+
+const PatternType = {
+ SOLID: 0,
+ SURFACE: 1,
+ LINEAR: 2,
+ RADIAL: 3,
+};
+
+const SurfaceType = {
+ IMAGE: 0,
+ PDF: 1,
+ PS: 2,
+ XLIB: 3,
+ XCB: 4,
+ GLITZ: 5,
+ QUARTZ: 6,
+ WIN32: 7,
+ BEOS: 8,
+ DIRECTFB: 9,
+ SVG: 10,
+ OS2: 11,
+ WIN32_PRINTING: 12,
+ QUARTZ_IMAGE: 13,
+};
+
const cairo = import.meta.importSync('cairoNative');
-export default Object.assign(
- {},
- imports._cairo,
- cairo
-);
+const exports = Object.assign({}, {
+ Antialias,
+ Content,
+ Extend,
+ FillRule,
+ Filter,
+ FontSlant,
+ FontWeight,
+ Format,
+ LineCap,
+ LineJoin,
+ Operator,
+ PatternType,
+ SurfaceType,
+}, cairo);
+
+export default exports;
diff --git a/modules/esm/gettext.js b/modules/esm/gettext.js
index bcef3863..5c303a0c 100644
--- a/modules/esm/gettext.js
+++ b/modules/esm/gettext.js
@@ -1,20 +1,93 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+// SPDX-FileCopyrightText: 2009 Red Hat, Inc.
// SPDX-FileCopyrightText: 2020 Evan Welsh <contact@evanwelsh.com>
-export let {
- LocaleCategory,
- setlocale,
- textdomain,
- bindtextdomain,
- gettext,
- dgettext,
- dcgettext,
- ngettext,
- dngettext,
- pgettext,
- dpgettext,
- domain,
-} = imports._gettext;
+/* exported bindtextdomain, dcgettext, dgettext, dngettext, domain, dpgettext,
+gettext, LocaleCategory, ngettext, pgettext, setlocale, textdomain */
+
+/**
+ * This module provides a convenience layer for the "gettext" family of functions,
+ * relying on GLib for the actual implementation.
+ *
+ * Usage:
+ *
+ * const Gettext = imports.gettext;
+ *
+ * Gettext.textdomain("myapp");
+ * Gettext.bindtextdomain("myapp", "/usr/share/locale");
+ *
+ * let translated = Gettext.gettext("Hello world!");
+ */
+
+import GLib from 'gi://GLib';
+import GjsPrivate from 'gi://GjsPrivate';
+
+export let LocaleCategory = GjsPrivate.LocaleCategory;
+
+export function setlocale(category, locale) {
+ return GjsPrivate.setlocale(category, locale);
+}
+
+export function textdomain(dom) {
+ return GjsPrivate.textdomain(dom);
+}
+
+export function bindtextdomain(dom, location) {
+ return GjsPrivate.bindtextdomain(dom, location);
+}
+
+export function gettext(msgid) {
+ return GLib.dgettext(null, msgid);
+}
+
+export function dgettext(dom, msgid) {
+ return GLib.dgettext(dom, msgid);
+}
+
+export function dcgettext(dom, msgid, category) {
+ return GLib.dcgettext(dom, msgid, category);
+}
+
+export function ngettext(msgid1, msgid2, n) {
+ return GLib.dngettext(null, msgid1, msgid2, n);
+}
+
+export function dngettext(dom, msgid1, msgid2, n) {
+ return GLib.dngettext(dom, msgid1, msgid2, n);
+}
+
+// FIXME: missing dcngettext ?
+
+export function pgettext(context, msgid) {
+ return GLib.dpgettext2(null, context, msgid);
+}
+
+export function dpgettext(dom, context, msgid) {
+ return GLib.dpgettext2(dom, context, msgid);
+}
+
+/**
+ * Create an object with bindings for gettext, ngettext,
+ * and pgettext bound to a particular translation domain.
+ *
+ * @param {string} domainName Translation domain string
+ * @returns {object} an object with gettext bindings
+ */
+export function domain(domainName) {
+ return {
+ gettext(msgid) {
+ return GLib.dgettext(domainName, msgid);
+ },
+
+ ngettext(msgid1, msgid2, n) {
+ return GLib.dngettext(domainName, msgid1, msgid2, n);
+ },
+
+ pgettext(context, msgid) {
+ return GLib.dpgettext2(domainName, context, msgid);
+ },
+ };
+}
export default {
LocaleCategory,
diff --git a/modules/internal/.eslintrc.yml b/modules/internal/.eslintrc.yml
index 7c187793..269a2dfe 100644
--- a/modules/internal/.eslintrc.yml
+++ b/modules/internal/.eslintrc.yml
@@ -7,6 +7,7 @@ parserOptions:
ecmaVersion: 2022
globals:
ARGV: off
+ loadNative: readonly
Debugger: readonly
GIRepositoryGType: off
imports: off
diff --git a/modules/internal/loader.js b/modules/internal/loader.js
index 2f3f71d8..5ad6d83c 100644
--- a/modules/internal/loader.js
+++ b/modules/internal/loader.js
@@ -14,6 +14,8 @@
/** @typedef {{ [key: string]: string | undefined; }} Query */
/** @typedef {(uri: string, contents: string) => Module} CompileFunc */
+const {debug} = loadNative('_print');
+
/**
* Thrown when there is an error importing a module.
*/
@@ -32,6 +34,8 @@ class ImportError extends moduleGlobalThis.Error {
* ModulePrivate is the "private" object of every module.
*/
class ModulePrivate {
+ #override;
+
/**
*
* @param {string} id the module's identifier
@@ -42,6 +46,17 @@ class ModulePrivate {
this.id = id;
this.uri = uri;
this.internal = internal;
+
+ if (internal) {
+ Object.defineProperty(this, 'override', {
+ get: () => {
+ return this.#override;
+ },
+ set: override => {
+ this.#override = override;
+ },
+ });
+ }
}
}
@@ -108,8 +123,11 @@ class InternalModuleLoader {
}
if (isRelativePath(specifier)) {
- if (!parentURI)
- throw new ImportError('Cannot import relative path when module path is unknown.');
+ if (!parentURI) {
+ throw new ImportError(
+ 'Cannot import relative path when module path is unknown.'
+ );
+ }
return this.resolveRelativePath(specifier, parentURI);
}
@@ -131,7 +149,10 @@ class InternalModuleLoader {
parseURI(importingModuleURI);
// Handle relative imports from URI-based modules.
- const relativeURI = resolveRelativeResourceOrFile(importingModuleURI, relativePath);
+ const relativeURI = resolveRelativeResourceOrFile(
+ importingModuleURI,
+ relativePath
+ );
if (!relativeURI)
throw new ImportError('File does not have a valid parent!');
return parseURI(relativeURI);
@@ -154,12 +175,13 @@ class InternalModuleLoader {
/**
* @param {string} specifier the specifier (e.g. relative path, root package) to resolve
- * @param {string | null} importingModuleURI the URI of the module
- * triggering this resolve
+ * @param {ModulePrivate} importingModulePriv the private object of the module initiating
+ * the import triggering this resolve
*
* @returns {Module | null}
*/
- resolveModule(specifier, importingModuleURI) {
+ resolveModule(specifier, importingModulePriv) {
+ const importingModuleURI = importingModulePriv.uri;
const registry = getRegistry(this.global);
// Check if the module has already been loaded
@@ -180,9 +202,15 @@ class InternalModuleLoader {
if (!result)
return null;
- const [text, internal = false] = result;
+ const [text, internal] = result;
- const priv = new ModulePrivate(uri.uri, uri.uri, internal);
+ debug(`Importing ${specifier} ${internal ? '(internal)' : ''}`);
+
+ const priv = new ModulePrivate(
+ uri.uri,
+ uri.uri,
+ internal ?? importingModulePriv.internal
+ );
const compiled = this.compileModule(priv, text);
registry.set(uri.uri, compiled);
@@ -193,15 +221,18 @@ class InternalModuleLoader {
}
moduleResolveHook(importingModulePriv, specifier) {
- const resolved = this.resolveModule(specifier, importingModulePriv.uri ?? null);
+ const resolved = this.resolveModule(
+ specifier,
+ importingModulePriv ?? null
+ );
if (!resolved)
throw new ImportError(`Module not found: ${specifier}`);
return resolved;
}
- moduleLoadHook(id, uri) {
- const priv = new ModulePrivate(id, uri);
+ moduleLoadHook(id, uri, internal) {
+ const priv = new ModulePrivate(id, uri, internal);
const result = this.loadURI(parseURI(uri));
// result can only be null if `this` is InternalModuleLoader. If `this`
@@ -311,8 +342,11 @@ class ModuleLoader extends InternalModuleLoader {
throw new ImportError(`Unknown module: '${specifier}'`);
const parsed = parseURI(uri);
- if (parsed.scheme !== 'file' && parsed.scheme !== 'resource')
- throw new ImportError('Only file:// and resource:// URIs are currently supported.');
+ if (parsed.scheme !== 'file' && parsed.scheme !== 'resource') {
+ throw new ImportError(
+ 'Only file:// and resource:// URIs are currently supported.'
+ );
+ }
const text = loadResourceOrFile(parsed.uri);
const priv = new ModulePrivate(specifier, uri, true);
@@ -335,7 +369,7 @@ class ModuleLoader extends InternalModuleLoader {
* @returns {import("./internalLoader").Module}
*/
moduleResolveHook(importingModulePriv, specifier) {
- const module = this.resolveModule(specifier, importingModulePriv.uri);
+ const module = this.resolveModule(specifier, importingModulePriv);
if (module)
return module;
@@ -345,21 +379,26 @@ class ModuleLoader extends InternalModuleLoader {
moduleResolveAsyncHook(importingModulePriv, specifier) {
// importingModulePriv should never be missing. If it is then a JSScript
// is missing a private object
- if (!importingModulePriv || !importingModulePriv.uri)
- throw new ImportError('Cannot resolve relative imports from an unknown file.');
+ if (!importingModulePriv || !importingModulePriv.uri) {
+ throw new ImportError(
+ 'Cannot resolve relative imports from an unknown file.'
+ );
+ }
- return this.resolveModuleAsync(specifier, importingModulePriv.uri);
+ return this.resolveModuleAsync(specifier, importingModulePriv);
}
/**
* Resolves a module import with optional handling for relative imports asynchronously.
*
* @param {string} specifier the specifier (e.g. relative path, root package) to resolve
- * @param {string | null} importingModuleURI the URI of the module
+ * @param {ModulePrivate} importingModulePriv the private object of the module initiating
+ * the import triggering this resolve
* triggering this resolve
* @returns {import("../types").Module}
*/
- async resolveModuleAsync(specifier, importingModuleURI) {
+ async resolveModuleAsync(specifier, importingModulePriv) {
+ const importingModuleURI = importingModulePriv.uri;
const registry = getRegistry(this.global);
// Check if the module has already been loaded
@@ -385,9 +424,13 @@ class ModuleLoader extends InternalModuleLoader {
if (module)
return module;
- const [text, internal = false] = result;
+ const [text, internal] = result;
- const priv = new ModulePrivate(uri.uri, uri.uri, internal);
+ const priv = new ModulePrivate(
+ uri.uri,
+ uri.uri,
+ internal ?? importingModulePriv.internal
+ );
const compiled = this.compileModule(priv, text);
registry.set(uri.uri, compiled);
@@ -436,7 +479,9 @@ setGlobalModuleLoader(moduleGlobalThis, moduleLoader);
function generateGIModule(namespace, version) {
return `
import $$gi from 'gi';
- export default $$gi.require('${namespace}'${version !== undefined ? `, '${version}'` : ''});
+ export default $$gi.require('${namespace}'${
+ version !== undefined ? `, '${version}'` : ''
+});
`;
}
diff --git a/modules/core/overrides/.eslintrc.yml b/modules/overrides/.eslintrc.yml
index 8a5f8fd9..bd5a206c 100644
--- a/modules/core/overrides/.eslintrc.yml
+++ b/modules/overrides/.eslintrc.yml
@@ -2,6 +2,7 @@
# SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
# SPDX-FileCopyrightText: 2018 Philip Chimento <philip.chimento@gmail.com>
rules:
- no-unused-vars:
- - error
- - varsIgnorePattern: ^_init$
+ require-jsdoc: "off"
+parserOptions:
+ sourceType: 'module'
+ ecmaVersion: 2022 \ No newline at end of file
diff --git a/modules/core/overrides/GLib.js b/modules/overrides/GLib.js
index cb8f177e..312377a8 100644
--- a/modules/core/overrides/GLib.js
+++ b/modules/overrides/GLib.js
@@ -1,9 +1,7 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2011 Giovanni Campagna
-const ByteArray = imports.byteArray;
-
-let GLib;
+const {GLib} = import.meta.importSync('gi');
const SIMPLE_TYPES = ['b', 'y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd', 's', 'o', 'g'];
@@ -101,10 +99,11 @@ function _packVariant(signature, value) {
// special case for array of bytes
let bytes;
if (typeof value === 'string') {
- let byteArray = ByteArray.fromString(value);
+ let encoder = new TextEncoder();
+ let byteArray = encoder.encode(value);
if (byteArray[byteArray.length - 1] !== 0)
byteArray = Uint8Array.of(...byteArray, 0);
- bytes = ByteArray.toGBytes(byteArray);
+ bytes = new GLib.Bytes(byteArray);
} else {
bytes = new GLib.Bytes(value);
}
@@ -202,7 +201,7 @@ function _unpackVariant(variant, deep, recursive = false) {
case 'a':
if (variant.is_of_type(new GLib.VariantType('a{?*}'))) {
// special case containers
- let ret = { };
+ let ret = {};
let nElements = variant.n_children();
for (let i = 0; i < nElements; i++) {
// always unpack the dictionary entry, and always unpack
@@ -246,6 +245,10 @@ function _notIntrospectableError(funcName, replacement) {
return new Error(`${funcName} is not introspectable. Use ${replacement} instead.`);
}
+/**
+ * @param funcName
+ * @param replacement
+ */
function _warnNotIntrospectable(funcName, replacement) {
logError(_notIntrospectableError(funcName, replacement));
}
@@ -256,16 +259,12 @@ function _escapeCharacterSetChars(char) {
return char;
}
-function _init() {
- // this is imports.gi.GLib
-
- GLib = this;
-
+(function () {
// For convenience in property min or max values, since GLib.MAXINT64 and
// friends will log a warning when used
- this.MAXINT64_BIGINT = 0x7fff_ffff_ffff_ffffn;
- this.MININT64_BIGINT = -this.MAXINT64_BIGINT - 1n;
- this.MAXUINT64_BIGINT = 0xffff_ffff_ffff_ffffn;
+ GLib.MAXINT64_BIGINT = 0x7fff_ffff_ffff_ffffn;
+ GLib.MININT64_BIGINT = -GLib.MAXINT64_BIGINT - 1n;
+ GLib.MAXUINT64_BIGINT = 0xffff_ffff_ffff_ffffn;
// small HACK: we add a matches() method to standard Errors so that
// you can do "if (e.matches(Ns.FooError, Ns.FooError.SOME_CODE))"
@@ -276,15 +275,15 @@ function _init() {
// Guard against domains that aren't valid quarks and would lead
// to a crash
- const quarkToString = this.quark_to_string;
- const realNewLiteral = this.Error.new_literal;
- this.Error.new_literal = function (domain, code, message) {
+ const quarkToString = GLib.quark_to_string;
+ const realNewLiteral = GLib.Error.new_literal;
+ GLib.Error.new_literal = function (domain, code, message) {
if (quarkToString(domain) === null)
throw new TypeError(`Error.new_literal: ${domain} is not a valid domain`);
return realNewLiteral(domain, code, message);
};
- this.Variant._new_internal = function (sig, value) {
+ GLib.Variant._new_internal = function (sig, value) {
let signature = Array.prototype.slice.call(sig);
let variant = _packVariant(signature, value);
@@ -295,32 +294,32 @@ function _init() {
};
// Deprecate version of new GLib.Variant()
- this.Variant.new = function (sig, value) {
+ GLib.Variant.new = function (sig, value) {
return new GLib.Variant(sig, value);
};
- this.Variant.prototype.unpack = function () {
+ GLib.Variant.prototype.unpack = function () {
return _unpackVariant(this, false);
};
- this.Variant.prototype.deepUnpack = function () {
+ GLib.Variant.prototype.deepUnpack = function () {
return _unpackVariant(this, true);
};
// backwards compatibility alias
- this.Variant.prototype.deep_unpack = this.Variant.prototype.deepUnpack;
+ GLib.Variant.prototype.deep_unpack = GLib.Variant.prototype.deepUnpack;
// Note: discards type information, if the variant contains any 'v' types
- this.Variant.prototype.recursiveUnpack = function () {
+ GLib.Variant.prototype.recursiveUnpack = function () {
return _unpackVariant(this, true, true);
};
- this.Variant.prototype.toString = function () {
- return `[object variant of type "${this.get_type_string()}"]`;
+ GLib.Variant.prototype.toString = function () {
+ return `[object variant of type "${GLib.get_type_string()}"]`;
};
- this.Bytes.prototype.toArray = function () {
+ GLib.Bytes.prototype.toArray = function () {
return imports._byteArrayNative.fromGBytes(this);
};
- this.log_structured =
+ GLib.log_structured =
/**
* @param {string} logDomain
* @param {GLib.LogLevelFlags} logLevel
@@ -356,19 +355,19 @@ function _init() {
// GjsPrivate depends on GLib so we cannot import it
// before GLib is fully resolved.
- this.log_set_writer_func_variant = function (...args) {
- const {log_set_writer_func} = imports.gi.GjsPrivate;
+ GLib.log_set_writer_func_variant = function (...args) {
+ const {log_set_writer_func} = gi.GjsPrivate;
log_set_writer_func(...args);
};
- this.log_set_writer_default = function (...args) {
- const {log_set_writer_default} = imports.gi.GjsPrivate;
+ GLib.log_set_writer_default = function (...args) {
+ const {log_set_writer_default} = gi.GjsPrivate;
log_set_writer_default(...args);
};
- this.log_set_writer_func = function (writer_func) {
+ GLib.log_set_writer_func = function (writer_func) {
const {log_set_writer_func} = imports.gi.GjsPrivate;
if (typeof writer_func !== 'function') {
@@ -381,7 +380,7 @@ function _init() {
}
};
- this.VariantDict.prototype.lookup = function (key, variantType = null, deep = false) {
+ GLib.VariantDict.prototype.lookup = function (key, variantType = null, deep = false) {
if (typeof variantType === 'string')
variantType = new GLib.VariantType(variantType);
@@ -401,11 +400,11 @@ function _init() {
// is useless anyway and GLib.ascii_formatd() which is too complicated to
// implement here.
- this.stpcpy = function () {
+ GLib.stpcpy = function () {
throw _notIntrospectableError('GLib.stpcpy()', 'the + operator');
};
- this.strstr_len = function (haystack, len, needle) {
+ GLib.strstr_len = function (haystack, len, needle) {
_warnNotIntrospectable('GLib.strstr_len()', 'String.indexOf()');
let searchString = haystack;
if (len !== -1)
@@ -416,7 +415,7 @@ function _init() {
return haystack.slice(index);
};
- this.strrstr = function (haystack, needle) {
+ GLib.strrstr = function (haystack, needle) {
_warnNotIntrospectable('GLib.strrstr()', 'String.lastIndexOf()');
const index = haystack.lastIndexOf(needle);
if (index === -1)
@@ -424,7 +423,7 @@ function _init() {
return haystack.slice(index);
};
- this.strrstr_len = function (haystack, len, needle) {
+ GLib.strrstr_len = function (haystack, len, needle) {
_warnNotIntrospectable('GLib.strrstr_len()', 'String.lastIndexOf()');
let searchString = haystack;
if (len !== -1)
@@ -435,52 +434,52 @@ function _init() {
return haystack.slice(index);
};
- this.strup = function (string) {
+ GLib.strup = function (string) {
_warnNotIntrospectable('GLib.strup()',
'String.toUpperCase() or GLib.ascii_strup()');
return string.toUpperCase();
};
- this.strdown = function (string) {
+ GLib.strdown = function (string) {
_warnNotIntrospectable('GLib.strdown()',
'String.toLowerCase() or GLib.ascii_strdown()');
return string.toLowerCase();
};
- this.strreverse = function (string) {
+ GLib.strreverse = function (string) {
_warnNotIntrospectable('GLib.strreverse()',
'Array.reverse() and String.join()');
return [...string].reverse().join('');
};
- this.ascii_dtostr = function (unused, len, number) {
+ GLib.ascii_dtostr = function (unused, len, number) {
_warnNotIntrospectable('GLib.ascii_dtostr()', 'JS string conversion');
return `${number}`.slice(0, len);
};
- this.ascii_formatd = function () {
+ GLib.ascii_formatd = function () {
throw _notIntrospectableError('GLib.ascii_formatd()',
'Number.toExponential() and string interpolation');
};
- this.strchug = function (string) {
+ GLib.strchug = function (string) {
_warnNotIntrospectable('GLib.strchug()', 'String.trimStart()');
return string.trimStart();
};
- this.strchomp = function (string) {
+ GLib.strchomp = function (string) {
_warnNotIntrospectable('GLib.strchomp()', 'String.trimEnd()');
return string.trimEnd();
};
// g_strstrip() is a macro and therefore doesn't even appear in the GIR
// file, but we may as well include it here since it's trivial
- this.strstrip = function (string) {
+ GLib.strstrip = function (string) {
_warnNotIntrospectable('GLib.strstrip()', 'String.trim()');
return string.trim();
};
- this.strdelimit = function (string, delimiters, newDelimiter) {
+ GLib.strdelimit = function (string, delimiters, newDelimiter) {
_warnNotIntrospectable('GLib.strdelimit()', 'String.replace()');
if (delimiters === null)
@@ -494,7 +493,7 @@ function _init() {
return string.replace(delimiterRegex, newDelimiter);
};
- this.strcanon = function (string, validChars, substitutor) {
+ GLib.strcanon = function (string, validChars, substitutor) {
_warnNotIntrospectable('GLib.strcanon()', 'String.replace()');
if (typeof substitutor === 'number')
@@ -505,4 +504,4 @@ function _init() {
const invalidRegex = new RegExp(`[^${escapedValidArray.join('')}]`, 'g');
return string.replace(invalidRegex, substitutor);
};
-}
+})();
diff --git a/modules/core/overrides/GObject.js b/modules/overrides/GObject.js
index df6f9dc2..782f05b6 100644
--- a/modules/core/overrides/GObject.js
+++ b/modules/overrides/GObject.js
@@ -3,12 +3,12 @@
// SPDX-FileCopyrightText: 2011 Jasper St. Pierre
// SPDX-FileCopyrightText: 2017 Philip Chimento <philip.chimento@gmail.com>, <philip@endlessm.com>
-const Gi = imports._gi;
-const {GjsPrivate, GLib} = imports.gi;
-const {_checkAccessors, _registerType} = imports._common;
-const Legacy = imports._legacy;
+import * as Legacy from '../deprecated/_legacy.js';
+import {_checkAccessors, _registerType} from '../common/class.js';
-let GObject;
+const Gi = import.meta.importSync('_gi');
+
+const {GjsPrivate, GLib, GObject} = import.meta.importSync('gi');
var GTypeName = Symbol('GType name');
var GTypeFlags = Symbol('GType flags');
@@ -23,6 +23,9 @@ var _gtkCssName = Symbol('GTK widget CSS name');
var _gtkInternalChildren = Symbol('GTK widget template internal children');
var _gtkTemplate = Symbol('GTK widget template');
+/**
+ * @param {...any} args
+ */
function registerClass(...args) {
let klass = args[0];
if (args.length === 2) {
@@ -80,6 +83,7 @@ function registerClass(...args) {
return klass;
}
+
function _resolveLegacyClassFunction(klass, func) {
// Find the "least derived" class with a _classInit static function; there
// definitely is one, since this class must inherit from GObject
@@ -89,6 +93,7 @@ function _resolveLegacyClassFunction(klass, func) {
return initclass[func];
}
+
function _defineGType(klass, giPrototype, registeredType) {
const config = {
enumerable: false,
@@ -124,6 +129,7 @@ function _defineGType(klass, giPrototype, registeredType) {
// Some common functions between GObject.Class and GObject.Interface
+
function _createSignals(gtype, sigs) {
for (let signalName in sigs) {
let obj = sigs[signalName];
@@ -140,6 +146,7 @@ function _createSignals(gtype, sigs) {
}
}
+
function _getCallerBasename() {
const stackLines = new Error().stack.trim().split('\n');
const lineRegex = new RegExp(/@(.+:\/\/)?(.*\/)?(.+)\.js:\d+(:[\d]+)?$/);
@@ -281,9 +288,7 @@ function _checkProperties(klass) {
_checkAccessors(klass.prototype, pspec, GObject);
}
-function _init() {
- GObject = this;
-
+(function () {
function _makeDummyClass(obj, name, upperName, gtypeName, actual) {
let gtype = GObject.type_from_name(gtypeName);
obj[`TYPE_${upperName}`] = gtype;
@@ -295,7 +300,7 @@ function _init() {
GObject.gtypeNameBasedOnJSPath = false;
- _makeDummyClass(GObject, 'VoidType', 'NONE', 'void', function () {});
+ _makeDummyClass(GObject, 'VoidType', 'NONE', 'void', function () { });
_makeDummyClass(GObject, 'Char', 'CHAR', 'gchar', Number);
_makeDummyClass(GObject, 'UChar', 'UCHAR', 'guchar', Number);
_makeDummyClass(GObject, 'Unichar', 'UNICHAR', 'gint', String);
@@ -751,9 +756,9 @@ function _init() {
* a successful match.
*/
GObject.signal_handler_find = function (instance, match) {
- // For backwards compatibility
+ // For backwards compatibility
if (arguments.length === 7)
- // eslint-disable-next-line prefer-rest-params
+ // eslint-disable-next-line prefer-rest-params
return GObject._real_signal_handler_find(...arguments);
return instance[Gi.signal_find_symbol](match);
};
@@ -778,9 +783,9 @@ function _init() {
* @returns {number} The number of handlers that matched.
*/
GObject.signal_handlers_block_matched = function (instance, match) {
- // For backwards compatibility
+ // For backwards compatibility
if (arguments.length === 7)
- // eslint-disable-next-line prefer-rest-params
+ // eslint-disable-next-line prefer-rest-params
return GObject._real_signal_handlers_block_matched(...arguments);
return instance[Gi.signals_block_symbol](match);
};
@@ -808,9 +813,9 @@ function _init() {
* @returns {number} The number of handlers that matched.
*/
GObject.signal_handlers_unblock_matched = function (instance, match) {
- // For backwards compatibility
+ // For backwards compatibility
if (arguments.length === 7)
- // eslint-disable-next-line prefer-rest-params
+ // eslint-disable-next-line prefer-rest-params
return GObject._real_signal_handlers_unblock_matched(...arguments);
return instance[Gi.signals_unblock_symbol](match);
};
@@ -836,9 +841,9 @@ function _init() {
* @returns {number} The number of handlers that matched.
*/
GObject.signal_handlers_disconnect_matched = function (instance, match) {
- // For backwards compatibility
+ // For backwards compatibility
if (arguments.length === 7)
- // eslint-disable-next-line prefer-rest-params
+ // eslint-disable-next-line prefer-rest-params
return GObject._real_signal_handlers_disconnect_matched(...arguments);
return instance[Gi.signals_disconnect_symbol](match);
};
@@ -882,4 +887,4 @@ function _init() {
throw new Error('GObject.signal_handlers_disconnect_by_data() is not \
introspectable. Use GObject.signal_handlers_disconnect_by_func() instead.');
};
-}
+})();
diff --git a/modules/core/overrides/Gio.js b/modules/overrides/Gio.js
index 6cc29b17..d06eb0f8 100644
--- a/modules/core/overrides/Gio.js
+++ b/modules/overrides/Gio.js
@@ -1,10 +1,9 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2011 Giovanni Campagna
-var GLib = imports.gi.GLib;
-var GjsPrivate = imports.gi.GjsPrivate;
-var Signals = imports.signals;
-var Gio;
+import * as Signals from '../deprecated/signals.js';
+
+const {Gio, GjsPrivate, GLib} = import.meta.importSync('gi');
// Ensures that a Gio.UnixFDList being passed into or out of a DBus method with
// a parameter type that includes 'h' somewhere, actually has entries in it for
@@ -29,7 +28,7 @@ function _validateFDVariant(variant, fdList) {
const numFds = fdList.get_length();
if (val >= numFds) {
throw new Error(`handle ${val} is out of range of Gio.UnixFDList ` +
- `containing ${numFds} FDs`);
+ `containing ${numFds} FDs`);
}
return;
}
@@ -72,8 +71,7 @@ function _proxyInvoker(methodName, sync, inSignature, argArray) {
var maxNumberArgs = signatureLength + 4;
if (argArray.length < minNumberArgs) {
- throw new Error(`Not enough arguments passed for method: ${
- methodName}. Expected ${minNumberArgs}, got ${argArray.length}`);
+ throw new Error(`Not enough arguments passed for method: ${methodName}. Expected ${minNumberArgs}, got ${argArray.length}`);
} else if (argArray.length > maxNumberArgs) {
throw new Error(`Too many arguments passed for method ${methodName}. ` +
`Maximum is ${maxNumberArgs} including one callback, ` +
@@ -168,8 +166,7 @@ function _propertySetter(name, signature, value) {
try {
this.call_finish(result);
} catch (e) {
- log(`Could not set property ${name} on remote object ${
- this.g_object_path}: ${e.message}`);
+ log(`Could not set property ${name} on remote object ${this.g_object_path}: ${e.message}`);
}
});
}
@@ -453,9 +450,7 @@ function _promisify(proto, asyncFunc,
};
}
-function _init() {
- Gio = this;
-
+(function () {
Gio.DBus = {
get session() {
return Gio.bus_get_sync(Gio.BusType.SESSION, null);
@@ -497,6 +492,7 @@ function _init() {
_injectToStaticMethod(Gio.DBusProxy, 'new_finish', _addDBusConvenience);
_injectToStaticMethod(Gio.DBusProxy, 'new_for_bus_sync', _addDBusConvenience);
_injectToStaticMethod(Gio.DBusProxy, 'new_for_bus_finish', _addDBusConvenience);
+
Gio.DBusProxy.prototype.connectSignal = Signals._connect;
Gio.DBusProxy.prototype.disconnectSignal = Signals._disconnect;
@@ -551,14 +547,14 @@ function _init() {
Object.assign(Gio.Settings.prototype, {
_realInit: Gio.Settings.prototype._init, // add manually, not enumerable
_init(props = {}) {
- // 'schema' is a deprecated alias for schema_id
+ // 'schema' is a deprecated alias for schema_id
const schemaIdProp = ['schema', 'schema-id', 'schema_id',
'schemaId'].find(prop => prop in props);
const settingsSchemaProp = ['settings-schema', 'settings_schema',
'settingsSchema'].find(prop => prop in props);
if (!schemaIdProp && !settingsSchemaProp) {
throw new Error('One of property \'schema-id\' or ' +
- '\'settings-schema\' are required for Gio.Settings');
+ '\'settings-schema\' are required for Gio.Settings');
}
const source = Gio.SettingsSchemaSource.get_default();
@@ -572,21 +568,21 @@ function _init() {
const settingsSchemaPath = settingsSchema.get_path();
if (props['path'] === undefined && !settingsSchemaPath) {
throw new Error('Attempting to create schema ' +
- `'${settingsSchema.get_id()}' without a path`);
+ `'${settingsSchema.get_id()}' without a path`);
}
if (props['path'] !== undefined && settingsSchemaPath &&
- props['path'] !== settingsSchemaPath) {
+ props['path'] !== settingsSchemaPath) {
throw new Error(`GSettings created for path '${props['path']}'` +
- `, but schema specifies '${settingsSchemaPath}'`);
+ `, but schema specifies '${settingsSchemaPath}'`);
}
return this._realInit(props);
},
_checkKey(key) {
- // Avoid using has_key(); checking a JS array is faster than calling
- // through G-I.
+ // Avoid using has_key(); checking a JS array is faster than calling
+ // through G-I.
if (!this._keys)
this._keys = this.settings_schema.list_keys();
@@ -635,4 +631,4 @@ function _init() {
get_child: createCheckedMethod('get_child', '_checkChild'),
});
-}
+})();
diff --git a/modules/core/overrides/Gtk.js b/modules/overrides/Gtk.js
index ce63ba4e..dd27e169 100644
--- a/modules/core/overrides/Gtk.js
+++ b/modules/overrides/Gtk.js
@@ -2,16 +2,14 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2013 Giovanni Campagna
-const Legacy = imports._legacy;
-const {Gio, GjsPrivate, GObject} = imports.gi;
-const {_registerType} = imports._common;
+import * as Legacy from '../deprecated/_legacy.js';
+import {_registerType} from '../common/class.js';
-let Gtk;
let BuilderScope;
-function _init() {
- Gtk = this;
+const {Gtk, Gio, GjsPrivate, GObject} = import.meta.importSync('gi');
+(function () {
Gtk.children = GObject.__gtkChildren__;
Gtk.cssName = GObject.__gtkCssName__;
Gtk.internalChildren = GObject.__gtkInternalChildren__;
@@ -58,13 +56,13 @@ function _init() {
let children = wrapper.constructor[Gtk.children] || [];
for (let child of children) {
wrapper[child.replace(/-/g, '_')] =
- wrapper.get_template_child(wrapper.constructor, child);
+ wrapper.get_template_child(wrapper.constructor, child);
}
let internalChildren = wrapper.constructor[Gtk.internalChildren] || [];
for (let child of internalChildren) {
wrapper[`_${child.replace(/-/g, '_')}`] =
- wrapper.get_template_child(wrapper.constructor, child);
+ wrapper.get_template_child(wrapper.constructor, child);
}
}
@@ -149,7 +147,7 @@ function _init() {
}
});
}
-}
+})();
function _createClosure(builder, thisArg, handlerName, swapped, connectObject) {
connectObject = connectObject || thisArg;
diff --git a/modules/core/overrides/cairo.js b/modules/overrides/cairo.js
index 1d3ba0f9..3864df6e 100644
--- a/modules/core/overrides/cairo.js
+++ b/modules/overrides/cairo.js
@@ -3,7 +3,8 @@
// This override adds the builtin Cairo bindings to imports.gi.cairo.
// (It's confusing to have two incompatible ways to import Cairo.)
+import Cairo from 'cairo';
-function _init() {
- Object.assign(this, imports.cairo);
-}
+const {cairo} = import.meta.importSync('gi');
+
+Object.assign(cairo, Cairo);
diff --git a/modules/print.cpp b/modules/print.cpp
index 2b07a27b..e2dbc16b 100644
--- a/modules/print.cpp
+++ b/modules/print.cpp
@@ -162,12 +162,43 @@ static bool set_pretty_print_function(JSContext*, unsigned argc,
return true;
}
+GJS_JSAPI_RETURN_CONVENTION
+static bool gjs_debug_js(JSContext* cx, unsigned argc, JS::Value* vp) {
+ JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
+
+ if (argc != 1) {
+ gjs_throw(cx, "Must pass a single argument to log()");
+ return false;
+ }
+
+ /* JS::ToString might throw, in which case we will only log that the value
+ * could not be converted to string */
+ JS::AutoSaveExceptionState exc_state(cx);
+ JS::RootedString jstr(cx, JS::ToString(cx, argv[0]));
+ exc_state.restore();
+
+ if (!jstr) {
+ g_message("JS LOG: <cannot convert value to string>");
+ return true;
+ }
+
+ JS::UniqueChars s(JS_EncodeStringToUTF8(cx, jstr));
+ if (!s)
+ return false;
+
+ gjs_debug(GJS_DEBUG_IMPORTER, s.get());
+
+ argv.rval().setUndefined();
+ return true;
+}
+
// clang-format off
static constexpr JSFunctionSpec funcs[] = {
JS_FN("log", gjs_log, 1, GJS_MODULE_PROP_FLAGS),
JS_FN("logError", gjs_log_error, 2, GJS_MODULE_PROP_FLAGS),
JS_FN("print", gjs_print, 0, GJS_MODULE_PROP_FLAGS),
JS_FN("printerr", gjs_printerr, 0, GJS_MODULE_PROP_FLAGS),
+ JS_FN("debug", gjs_debug_js, 0, GJS_MODULE_PROP_FLAGS),
JS_FN("setPrettyPrintFunction", set_pretty_print_function, 1, GJS_MODULE_PROP_FLAGS),
JS_FS_END};
// clang-format on
diff --git a/modules/script/cairo.js b/modules/script/cairo.js
index 3401f3d6..288dc580 100644
--- a/modules/script/cairo.js
+++ b/modules/script/cairo.js
@@ -1,6 +1,3 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2010 litl, LLC.
-// Merge stuff defined in the shared imports._cairo and then in native code
-Object.assign(this, imports._cairo, imports.cairoNative);
-
diff --git a/modules/script/format.js b/modules/script/format.js
index 72b587c0..560d29d9 100644
--- a/modules/script/format.js
+++ b/modules/script/format.js
@@ -5,25 +5,4 @@
/* exported format, printf, vprintf */
-var {vprintf} = imports._format;
-
-function printf(fmt, ...args) {
- print(vprintf(fmt, args));
-}
-
-/*
- * This function is intended to extend the String object and provide a
- * String.format API for string formatting.
- * It has to be set up using String.prototype.format = Format.format;
- * Usage:
- * "somestring %s %d".format('hello', 5);
- * It supports %s, %d, %x and %f.
- * For %f it also supports precisions like "%.2f".format(1.526).
- * All specifiers can be prefixed with a minimum field width, e.g.
- * "%5s".format("foo").
- * Unless the width is prefixed with '0', the formatted string will be padded
- * with spaces.
- */
-function format(...args) {
- return vprintf(this, args);
-}
+// This file is a placeholder, imports.format is defined in deprecated/legacyImports.js
diff --git a/modules/script/gettext.js b/modules/script/gettext.js
index 9a3ef79d..ef3faa9e 100644
--- a/modules/script/gettext.js
+++ b/modules/script/gettext.js
@@ -1,20 +1,4 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2019 Evan Welsh
-/* exported LocaleCategory, bindtextdomain, dcgettext, dgettext, dngettext,
- domain, dpgettext, gettext, ngettext, pgettext, setlocale, textdomain */
-
-var {
- LocaleCategory,
- bindtextdomain,
- dcgettext,
- dgettext,
- dngettext,
- domain,
- dpgettext,
- gettext,
- ngettext,
- pgettext,
- setlocale,
- textdomain,
-} = imports._gettext;
+// This file is a placeholder, imports.gettext is defined in deprecated/legacyImports.js
diff --git a/modules/script/lang.js b/modules/script/lang.js
index 98082995..900d3db6 100644
--- a/modules/script/lang.js
+++ b/modules/script/lang.js
@@ -1,13 +1,10 @@
/* -*- mode: js; indent-tabs-mode: nil; -*- */
-/* exported bind, copyProperties, copyPublicProperties, countProperties, Class,
-getMetaClass, Interface */
+/* exported bind, copyProperties, copyPublicProperties, countProperties */
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2008 litl, LLC
// Utilities that are "meta-language" things like manipulating object props
-var {Class, Interface, getMetaClass} = imports._legacy;
-
function countProperties(obj) {
let count = 0;
for (let unusedProperty in obj)
diff --git a/modules/script/overrides/__init__.js b/modules/script/overrides/__init__.js
new file mode 100644
index 00000000..ddba652f
--- /dev/null
+++ b/modules/script/overrides/__init__.js
@@ -0,0 +1 @@
+// Placeholder for backwards compatibility (ensures imports.overrides resolves)
diff --git a/modules/script/signals.js b/modules/script/signals.js
index cd10605c..90956729 100644
--- a/modules/script/signals.js
+++ b/modules/script/signals.js
@@ -1,21 +1,4 @@
// SPDX-FileCopyrightText: 2008 litl, LLC
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
-/* exported addSignalMethods, WithSignals */
-
-const Lang = imports.lang;
-
-// Private API, remains exported for backwards compatibility reasons
-var {_connect, _disconnect, _emit, _signalHandlerIsConnected, _disconnectAll} = imports._signals;
-
-// Public API
-var {addSignalMethods} = imports._signals;
-
-var WithSignals = new Lang.Interface({
- Name: 'WithSignals',
- connect: _connect,
- disconnect: _disconnect,
- emit: _emit,
- signalHandlerIsConnected: _signalHandlerIsConnected,
- disconnectAll: _disconnectAll,
-});
+// This file is a placeholder, imports.signals is defined in deprecated/legacyImports.js