Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4include.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qv4include_p.h"
5#include "qv4scopedvalue_p.h"
6#include "qv4jscall_p.h"
7
8#include <QtQml/qjsengine.h>
9#if QT_CONFIG(qml_network)
10#include <QtNetwork/qnetworkrequest.h>
11#include <QtNetwork/qnetworkreply.h>
12#endif
13#include <QtCore/qfile.h>
14#include <QtQml/qqmlfile.h>
15
16#include <private/qqmlengine_p.h>
17#include <private/qv4engine_p.h>
18#include <private/qv4functionobject_p.h>
19#include <private/qv4script_p.h>
20#include <private/qv4context_p.h>
21
23
24QV4Include::QV4Include(const QUrl &url, QV4::ExecutionEngine *engine,
25 QV4::QmlContext *qmlContext, const QV4::Value &callback)
26 : QObject(engine->jsEngine())
27 , v4(engine), m_url(url)
28#if QT_CONFIG(qml_network)
29 , m_network(nullptr) , m_reply(nullptr)
30#endif
31{
32 if (qmlContext)
33 m_qmlContext.set(v4, *qmlContext);
34 if (callback.as<QV4::FunctionObject>())
35 m_callbackFunction.set(v4, callback);
36
37 m_resultObject.set(v4, resultValue(v4));
38
39#if QT_CONFIG(qml_network)
40 if (QQmlEngine *qmlEngine = v4->qmlEngine()) {
41 m_network = qmlEngine->networkAccessManager();
42
45
46 m_reply = m_network->get(request);
47 QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(finished()));
48 } else {
49 finished();
50 }
51#else
52 finished();
53#endif
54}
55
56QV4Include::~QV4Include()
57{
58#if QT_CONFIG(qml_network)
59 delete m_reply;
60 m_reply = nullptr;
61#endif
62}
63
64QV4::ReturnedValue QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status,
65 const QString &statusText)
66{
67 QV4::Scope scope(v4);
68
69 // XXX It seems inefficient to create this object from scratch each time.
70 QV4::ScopedObject o(scope, v4->newObject());
71 QV4::ScopedString s(scope);
72 QV4::ScopedValue v(scope);
73 o->put((s = v4->newString(QStringLiteral("OK"))), (v = QV4::Value::fromInt32(Ok)));
74 o->put((s = v4->newString(QStringLiteral("LOADING"))), (v = QV4::Value::fromInt32(Loading)));
75 o->put((s = v4->newString(QStringLiteral("NETWORK_ERROR"))), (v = QV4::Value::fromInt32(NetworkError)));
76 o->put((s = v4->newString(QStringLiteral("EXCEPTION"))), (v = QV4::Value::fromInt32(Exception)));
77 o->put((s = v4->newString(QStringLiteral("status"))), (v = QV4::Value::fromInt32(status)));
78 if (!statusText.isEmpty())
79 o->put((s = v4->newString(QStringLiteral("statusText"))), (v = v4->newString(statusText)));
80
81 return o.asReturnedValue();
82}
83
84void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
85{
86 if (!callback.isObject())
87 return;
88 QV4::ExecutionEngine *v4 = callback.as<QV4::Object>()->engine();
89 QV4::Scope scope(v4);
90 QV4::ScopedFunctionObject f(scope, callback);
91 if (!f)
92 return;
93
94 QV4::JSCallArguments jsCallData(scope, 1);
95 *jsCallData.thisObject = v4->globalObject->asReturnedValue();
96 jsCallData.args[0] = status;
97 f->call(jsCallData);
98 if (scope.hasException())
99 scope.engine->catchException();
100}
101
102QV4::ReturnedValue QV4Include::result()
103{
104 return m_resultObject.value();
105}
106
107void QV4Include::finished()
108{
109#if QT_CONFIG(qml_network)
110 QV4::Scope scope(v4);
111 QV4::ScopedObject resultObj(scope, m_resultObject.value());
112 QV4::ScopedString status(scope, v4->newString(QStringLiteral("status")));
113 if (m_reply->error() == QNetworkReply::NoError) {
114 QByteArray data = m_reply->readAll();
115
117
118 QV4::Scoped<QV4::QmlContext> qml(scope, m_qmlContext.value());
119 QV4::Script script(v4, qml, /*parse as QML binding*/false, code, m_url.toString());
120
121 script.parse();
122 if (!scope.hasException())
123 script.run();
124 if (scope.hasException()) {
125 QV4::ScopedValue ex(scope, scope.engine->catchException());
126 resultObj->put(status, QV4::ScopedValue(scope, QV4::Value::fromInt32(Exception)));
127 QV4::ScopedString exception(scope, v4->newString(QStringLiteral("exception")));
128 resultObj->put(exception, ex);
129 } else {
130 resultObj->put(status, QV4::ScopedValue(scope, QV4::Value::fromInt32(Ok)));
131 }
132 } else {
133 resultObj->put(status, QV4::ScopedValue(scope, QV4::Value::fromInt32(NetworkError)));
134 }
135#else
136 QV4::Scope scope(v4);
137 QV4::ScopedObject resultObj(scope, m_resultObject.value());
138 QV4::ScopedString status(scope, v4->newString(QStringLiteral("status")));
139 resultObj->put(status, QV4::ScopedValue(scope, QV4::Value::fromInt32(NetworkError)));
140#endif // qml_network
141
142 QV4::ScopedValue cb(scope, m_callbackFunction.value());
143 callback(cb, resultObj);
144
145 disconnect();
146 deleteLater();
147}
148
149/*
150 Documented in qv4engine.cpp
151*/
153 const QJSValue &callbackFunction)
154{
155 QQmlRefPointer<QQmlContextData> context = engine->callingQmlContext();
156
157 if ((!context || !context->isJSContext()) && engine->qmlEngine()) {
161 "Qt.include(): Can only be called from JavaScript files")));
162 }
163
164
165 QV4::Scope scope(engine);
166 QV4::ScopedValue scopedCallbackFunction(scope, QV4::Value::undefinedValue());
167 if (auto function = QJSValuePrivate::asManagedType<QV4::FunctionObject>(&callbackFunction))
168 scopedCallbackFunction = *function;
169
170 const QQmlEngine *qmlEngine = engine->qmlEngine();
171 const QUrl intercepted = qmlEngine
173 : url;
174 QString localFile = QQmlFile::urlToLocalFileOrQrc(intercepted);
175
177 QV4::Scoped<QV4::QmlContext> qmlcontext(scope, scope.engine->qmlContext());
178
179 if (localFile.isEmpty()) {
180#if QT_CONFIG(qml_network)
181 QV4Include *i = new QV4Include(url, engine, qmlcontext, scopedCallbackFunction);
182 result = i->result();
183#else
184 result = resultValue(scope.engine, NetworkError);
185 callback(scopedCallbackFunction, result);
186#endif
187 } else {
188 QScopedPointer<QV4::Script> script;
190 script.reset(QV4::Script::createFromFileOrCache(scope.engine, qmlcontext, localFile, url, &error));
191
192 if (!script.isNull()) {
193 script->parse();
194 if (!scope.hasException())
195 script->run();
196 if (scope.hasException()) {
197 QV4::ScopedValue ex(scope, scope.engine->catchException());
198 result = resultValue(scope.engine, Exception);
199 QV4::ScopedString exception(scope, scope.engine->newString(QStringLiteral("exception")));
200 result->as<QV4::Object>()->put(exception, ex);
201 } else {
202 result = resultValue(scope.engine, Ok);
203 }
204 } else {
205 result = resultValue(scope.engine, NetworkError, error);
206 }
207
208 callback(scopedCallbackFunction, result);
209 }
210
211 return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
212}
213
215
216#include "moc_qv4include_p.cpp"
\inmodule QtCore
Definition qbytearray.h:57
void throwError(const QString &message)
Throws a run-time error (exception) with the given message.
static QJSValue fromReturnedValue(QV4::ReturnedValue d)
Definition qjsvalue_p.h:197
The QJSValue class acts as a container for Qt/JavaScript data types.
Definition qjsvalue.h:31
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
void setUrl(const QUrl &url)
Sets the URL this network request is referring to be url.
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
QQmlEngine * qmlEngine(const QObject *object)
Returns the QQmlEngine associated with object, if any.
Definition qqml.cpp:80
QUrl interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataType type) const
Run the current URL interceptors on the given url of the given type and return the result.
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to \l{QFile}.
Definition qqmlfile.cpp:742
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
\inmodule QtCore
Definition qurl.h:94
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2831
static QJSValue method_include(QV4::ExecutionEngine *engine, const QUrl &url, const QJSValue &callbackFunction)
ReturnedValue value() const
Combined button and popup list for selecting options.
Scoped< FunctionObject > ScopedFunctionObject
quint64 ReturnedValue
Scoped< String > ScopedString
static void * context
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLsizei const GLfloat * v
[13]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLdouble s
[6]
Definition qopenglext.h:235
GLuint64EXT * result
[6]
QQmlEngine * qmlEngine(const QObject *obj)
Definition qqml.cpp:80
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define QStringLiteral(str)
#define QT_CONFIG(feature)
if(qFloatDistance(a, b)<(1<< 7))
[0]
QUrl url("example.com")
[constructor-url-reference]
QObject::connect nullptr
myObject disconnect()
[26]
QNetworkRequest request(url)
manager put(request, myData, this, [this](QRestReply &reply) { if(reply.isSuccess()) })
[5]
QJSEngine engine
[0]
Heap::Object * newObject()
Heap::String * newString(char16_t c)
static Heap::ExecutionContext * qmlContext(Heap::ExecutionContext *ctx)
ReturnedValue catchException(StackTrace *trace=nullptr)
bool hasException() const
ExecutionEngine * engine
static Script * createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl, QString *error)
constexpr ReturnedValue asReturnedValue() const
static constexpr Value fromInt32(int i)
Definition qv4value_p.h:187
static constexpr Value undefinedValue()
Definition qv4value_p.h:191
const T * as() const
Definition qv4value_p.h:132
bool isObject() const
Definition qv4value_p.h:302