diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-08-15 16:43:13 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-08-16 11:05:28 +0000 |
commit | b8e9ce6b4ecda30ad838c1d3465c428591071a66 (patch) | |
tree | 0d9ef453895e305aacd0c90eed89ba8bf0de7b04 /src/qml/jsapi/qjsengine.cpp | |
parent | 67c33f2230e899a230260879a5d90dfcd8e13d8d (diff) |
Add API to QJSEngine for importing ECMAScript modules
Now that the standard defines the concept of a module, it makes sense to
offer a function in QJSEngine that can read files and load them.
[ChangeLog][QtQml][QJSEngine] Added function to import ECMASCript
modules from the file system or the Qt resource system.
Change-Id: I72f8d49de948872221ac1b54fcfb066404bed9b9
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Diffstat (limited to 'src/qml/jsapi/qjsengine.cpp')
-rw-r--r-- | src/qml/jsapi/qjsengine.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 5fa81ccc2a..d20f7eb97c 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -52,6 +52,7 @@ #include <private/qqmldebugconnector_p.h> #include <private/qv4qobjectwrapper_p.h> #include <private/qv4stackframe_p.h> +#include <private/qv4module_p.h> #include <QtCore/qdatetime.h> #include <QtCore/qmetaobject.h> @@ -481,6 +482,54 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in return retval; } +static QUrl moduleUrlForFileName(const QString &fileName) +{ + QString absolutePath = QFileInfo(fileName).canonicalFilePath(); + if (!absolutePath.startsWith(QLatin1Char(':'))) + return QUrl::fromLocalFile(absolutePath); + + absolutePath.remove(0, 1); + QUrl url; + url.setPath(absolutePath); + url.setScheme(QLatin1String("qrc")); + return url; +} + +/*! + Imports the module located at \a fileName and returns a module namespace object that + contains all exported variables, constants and functions as properties. + + If this is the first time the module is imported in the engine, the file is loaded + from the specified location in either the local file system or the Qt resource system + and evaluated as an ECMAScript module. The file is expected to be encoded in UTF-8 text. + + Subsequent imports of the same module will return the previously imported instance. Modules + are singletons and remain around until the engine is destroyed. + + The specified \a fileName will internally be normalized using \a QFileInfo::canonicalFilePath(). + That means that multiple imports of the same file on disk using different relative paths will + load the file only once. + + \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()). + + \since 5.12 + */ +QJSValue QJSEngine::importModule(const QString &fileName) +{ + const QUrl url = moduleUrlForFileName(fileName); + auto moduleUnit = m_v4Engine->loadModule(url); + if (m_v4Engine->hasException) + return QJSValue(m_v4Engine, m_v4Engine->catchException()); + + QV4::Scope scope(m_v4Engine); + QV4::Scoped<QV4::Module> moduleNamespace(scope, moduleUnit->instantiate(m_v4Engine)); + if (m_v4Engine->hasException) + return QJSValue(m_v4Engine, m_v4Engine->catchException()); + moduleUnit->evaluate(); + return QJSValue(m_v4Engine, moduleNamespace->asReturnedValue()); +} + /*! Creates a JavaScript object of class Object. |