aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsapi
diff options
context:
space:
mode:
authorAlex Shaw <alex.shaw.as@gmail.com>2021-04-25 17:57:37 -0400
committerAlex Shaw <alex.shaw.as@gmail.com>2021-05-01 17:26:00 -0400
commit3464655f5e2adaa1aed8925a9a54b8fb5f238f31 (patch)
treeebb7c46c7d4f1af6e4b1853a74d7502fee3c450f /src/qml/jsapi
parent689522817dc559056f7c55f811a189c4821b7787 (diff)
Add QJSEngine::registerModule
Some applications that use JavaScript as a scripting language may want to extend JS through C++ code. The current way to do that is with global objects. ES6 provides a better way of encapsulating code: modules. registerModule() allows an application to provide a QJSValue as a named module. Developers familiar with Node.js will find this very easy to use. Example: ```c++ QJSValue num(666); myEngine.registerModule("themarkofthebeast", num); ``` ```js import badnews from "themarkofthebeast"; ``` [ChangeLog][QtQml][QJSEngine] Adds the ability to register QJSValues in C++ as modules for importing in MJS files. Change-Id: I0c98dcb746aa2aa15aa2ab3082129d106413a23b Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/jsapi')
-rw-r--r--src/qml/jsapi/qjsengine.cpp73
-rw-r--r--src/qml/jsapi/qjsengine.h1
2 files changed, 74 insertions, 0 deletions
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index b27c6add75..7e8effda45 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -150,6 +150,46 @@ Q_DECLARE_METATYPE(QList<int>)
}
\endcode
+ Modules don't have to be files. They can be values registered with
+ QJSEngine::registerModule():
+
+ \code
+ import version from "version";
+
+ export function getVersion()
+ {
+ return version;
+ }
+ \endcode
+
+ \code
+ QJSValue version(610);
+ myEngine.registerModule("version", version);
+ QJSValue module = myEngine.importModule("./myprint.mjs");
+ QJSValue getVersion = module.property("getVersion");
+ QJSValue result = getVersion.call();
+ \endcode
+
+ Named exports are supported, but because they are treated as members of an
+ object, the default export must be an ECMAScript object. Most of the newXYZ
+ functions in QJSValue will return an object.
+
+ \code
+ QJSValue name("Qt6");
+ QJSValue obj = myEngine.newObject();
+ obj.setProperty("name", name);
+ myEngine.registerModule("info", obj);
+ \endcode
+
+ \code
+ import { name } from "info";
+
+ export function getName()
+ {
+ return name;
+ }
+ \endcode
+
\section1 Engine Configuration
The globalObject() function returns the \b {Global Object}
@@ -555,6 +595,8 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
\note If an exception is thrown during the loading of the module, the return value
will be the exception (typically an \c{Error} object; see QJSValue::isError()).
+ \sa registerModule()
+
\since 5.12
*/
QJSValue QJSEngine::importModule(const QString &fileName)
@@ -577,6 +619,37 @@ QJSValue QJSEngine::importModule(const QString &fileName)
}
/*!
+ Register a QJSValue to serve as a module. After this function is called,
+ all modules that import \a moduleName will import the value of \a value
+ instead of loading \a moduleName from the filesystem.
+
+ Any valid QJSValue can be registered, but named exports (i.e.
+ \c {import { name } from "info"} are treated as members of an object, so
+ the default export must be created with one of the newXYZ methods of
+ QJSEngine.
+
+ Because this allows modules that do not exist on the filesystem to be imported,
+ scripting applications can use this to provide built-in modules, similar to
+ Node.js
+
+ \note The QJSValue \a value is not called or read until it is used by another module.
+ This means that there is no code to evaluate, so no errors will be seen until
+ another module throws an exception while trying to load this module.
+
+ \warning Attempting to access a named export from a QJSValue that is not an
+ object will trigger a \l{Script Exception}{exception}.
+
+ \sa importModule()
+ */
+bool QJSEngine::registerModule(const QString &moduleName, const QJSValue &value)
+{
+ m_v4Engine->registerModule(moduleName, value);
+ if (m_v4Engine->hasException)
+ return false;
+ return true;
+}
+
+/*!
Creates a JavaScript object of class Object.
The prototype of the created object will be the Object
diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h
index ac79b30ebc..84730afe2b 100644
--- a/src/qml/jsapi/qjsengine.h
+++ b/src/qml/jsapi/qjsengine.h
@@ -71,6 +71,7 @@ public:
QJSValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1, QStringList *exceptionStackTrace = nullptr);
QJSValue importModule(const QString &fileName);
+ bool registerModule(const QString &moduleName, const QJSValue &value);
QJSValue newObject();
QJSValue newSymbol(const QString &name);