9#include <QtQml/qjsengine.h>
10#if QT_CONFIG(qml_network)
11#include <QtNetwork/qnetworkrequest.h>
12#include <QtNetwork/qnetworkreply.h>
14#include <QtCore/qfile.h>
15#include <QtQml/qqmlfile.h>
17#include <private/qqmlengine_p.h>
18#include <private/qqmlscriptblob_p.h>
19#include <private/qqmlscriptdata_p.h>
20#include <private/qv4context_p.h>
21#include <private/qv4engine_p.h>
22#include <private/qv4functionobject_p.h>
23#include <private/qv4script_p.h>
27QV4::ReturnedValue QV4Include::resultValue(QV4::ExecutionEngine *v4)
32 QV4::ScopedObject o(scope, v4->newObject());
33 QV4::ScopedString s(scope);
34 QV4::ScopedValue v(scope);
35 o->put((s = v4->newString(QStringLiteral(
"OK"))), (v = QV4::Value::fromInt32(Ok)));
36 o->put((s = v4->newString(QStringLiteral(
"LOADING"))), (v = QV4::Value::fromInt32(Loading)));
37 o->put((s = v4->newString(QStringLiteral(
"NETWORK_ERROR"))), (v = QV4::Value::fromInt32(NetworkError)));
38 o->put((s = v4->newString(QStringLiteral(
"EXCEPTION"))), (v = QV4::Value::fromInt32(Exception)));
39 return o.asReturnedValue();
42void QV4Include::populateResultValue(
QV4::Object *o, Status status,
const QString &statusText)
45 QV4::
ScopedString statusKey(scope, scope.engine->newString(QStringLiteral(
"status")));
46 QV4::
ScopedValue statusValue(scope, QV4::Value::fromInt32(status));
47 o->put(statusKey, statusValue);
48 if (statusText.isEmpty())
51 QV4::
ScopedString textKey(scope, scope.engine->newString(QStringLiteral(
"statusText")));
52 QV4::
ScopedValue textValue(scope, scope.engine->newString(statusText));
53 o->put(textKey, textValue);
56QV4Include::QV4Include(
57 QV4::Object *result,
QV4::FunctionObject *callbackFunction,
QV4::QmlContext *qmlContext)
60 QV4::ExecutionEngine *engine = result->engine();
61 m_resultObject.set(engine, result->asReturnedValue());
63 m_callbackFunction.set(engine, callbackFunction->asReturnedValue());
65 m_qmlContext.set(engine, qmlContext->asReturnedValue());
68void QV4Include::callback(
QV4::FunctionObject *callback,
QV4::Object *result)
73 QV4::
Scope scope(callback->engine());
75 *jsCallData
.thisObject = scope.engine->globalObject->asReturnedValue();
76 jsCallData.args[0] = result;
77 callback->call(jsCallData);
78 if (scope.hasException())
79 scope.engine->catchException();
83
84
85QJSValue QV4Include::method_include(
QV4::ExecutionEngine *engine,
const QUrl &url,
86 const QJSValue &callbackFunction)
88 QQmlRefPointer<QQmlContextData> context = engine->callingQmlContext();
90 if ((!context || !context->isJSContext()) && engine->qmlEngine()) {
91 return QJSValuePrivate::fromReturnedValue(
94 "Qt.include(): Can only be called from JavaScript files")));
100 QUrl includeUrl = url;
101 includeUrl.setFragment(QLatin1String(
"include"));
102 QQmlRefPointer<QQmlScriptBlob> scriptBlob = engine->typeLoader()->getScript(includeUrl);
107 scope, QJSValuePrivate::asReturnedValue(&callbackFunction));
108 QV4::
Scoped<
QV4::QmlContext> qmlContext(scope, scope.engine->qmlContext());
110 if (scriptBlob->isCompleteOrError()) {
111 processScriptBlob(scriptBlob.data(), result, callback, qmlContext);
112 return QJSValuePrivate::fromReturnedValue(result.asReturnedValue());
115 scriptBlob->registerCallback(
new QV4Include(result, callback, qmlContext));
116 populateResultValue(result, Loading);
117 return QJSValuePrivate::fromReturnedValue(result.asReturnedValue());
120void QV4Include::ready(QQmlNotifyingBlob *notifyingBlob)
122 Q_ASSERT(notifyingBlob);
123 Q_ASSERT(notifyingBlob->type() == QQmlDataBlob::JavaScriptFile);
126 static_cast<QQmlScriptBlob *>(notifyingBlob), m_resultObject.as<QV4::Object>(),
127 m_callbackFunction.as<QV4::FunctionObject>(), m_qmlContext.as<QV4::QmlContext>());
132void QV4Include::processScriptBlob(
133 QQmlScriptBlob *scriptBlob,
QV4::Object *result,
QV4::FunctionObject *callbackFunction,
134 QV4::QmlContext *qmlContext)
136 Q_ASSERT(scriptBlob);
141 if (scriptBlob->isError()) {
142 const QList<QQmlError> errors = scriptBlob->errors();
143 Q_ASSERT(!errors.isEmpty());
144 const QString errorString = QLatin1String(
"Error opening source file %1: %2")
145 .arg(scriptBlob->finalUrlString(), errors[0].toString());
146 populateResultValue(result, NetworkError, errorString);
147 callback(callbackFunction, result);
151 Q_ASSERT(scriptBlob->isComplete());
152 const auto cu = scope.engine->executableCompilationUnit(
153 scriptBlob->scriptData()->compilationUnit());
154 if (
QV4::Function *vmFunction = cu->rootFunction()) {
155 QScopedValueRollback<QV4::Function *> savedGlobal(scope.engine->globalCode, vmFunction);
156 vmFunction->call(
nullptr,
nullptr, 0, qmlContext ? qmlContext : scope.engine->rootContext());
159 if (scope.hasException()) {
161 populateResultValue(result, Exception);
162 QV4::
ScopedString exception(scope, scope.engine->newString(QStringLiteral(
"exception")));
163 result->put(exception, ex);
165 populateResultValue(result, Ok);
168 callback(callbackFunction, result);
Scoped< FunctionObject > ScopedFunctionObject
Scoped< Object > ScopedObject
Scoped< String > ScopedString
JSCallArguments(const Scope &scope, int argc=0)
Scope(ExecutionEngine *e)