aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4engine.cpp14
-rw-r--r--src/qml/jsruntime/qv4engine_p.h1
-rw-r--r--src/qml/jsruntime/qv4include.cpp50
-rw-r--r--src/qml/jsruntime/qv4include_p.h9
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp59
-rw-r--r--src/qml/qml/qqmldelayedcallqueue.cpp29
-rw-r--r--src/qml/qml/qqmldelayedcallqueue_p.h4
-rw-r--r--src/qml/qml/qqmlglobal.cpp7
-rw-r--r--src/qml/qml/qqmlglobal_p.h6
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp1050
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h208
-rw-r--r--src/quick/util/qquickglobal.cpp2
-rw-r--r--tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml1
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp34
-rw-r--r--tests/auto/qml/qqmlqt/data/qtObjectContents.qml10
-rw-r--r--tests/auto/qml/qqmlqt/data/resolvedUrl.qml2
-rw-r--r--tests/auto/qml/qqmlqt/tst_qqmlqt.cpp310
17 files changed, 835 insertions, 961 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 923d458feb..fe34207ddc 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -2048,10 +2048,7 @@ void ExecutionEngine::initQmlGlobalObject()
void ExecutionEngine::initializeGlobal()
{
- QV4::Scope scope(this);
-
- QV4::ScopedObject qt(scope, memoryManager->allocate<QV4::QtObject>(qmlEngine()));
- globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt);
+ createQtObject();
QV4::GlobalExtensions::init(globalObject, QJSEngine::AllExtensions);
@@ -2078,6 +2075,15 @@ void ExecutionEngine::initializeGlobal()
}
}
+void ExecutionEngine::createQtObject()
+{
+ QV4::Scope scope(this);
+ QtObject *qtObject = new QtObject(this);
+ QJSEngine::setObjectOwnership(qtObject, QJSEngine::JavaScriptOwnership);
+ QV4::ScopedObject qt(scope, QV4::QObjectWrapper::wrap(this, qtObject));
+ globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt);
+}
+
const QSet<QString> &ExecutionEngine::illegalNames() const
{
return m_illegalNames;
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 92bd3a0627..bf24663920 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -689,6 +689,7 @@ public:
QV4::ReturnedValue global();
void initQmlGlobalObject();
void initializeGlobal();
+ void createQtObject();
void freezeObject(const QV4::Value &value);
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 17512cf4ff..c185894ab3 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -59,20 +59,21 @@ QT_BEGIN_NAMESPACE
QV4Include::QV4Include(const QUrl &url, QV4::ExecutionEngine *engine,
QV4::QmlContext *qmlContext, const QV4::Value &callback)
- : v4(engine), m_url(url)
+ : QObject(engine->jsEngine())
+ , v4(engine), m_url(url)
#if QT_CONFIG(qml_network)
, m_redirectCount(0), m_network(nullptr) , m_reply(nullptr)
#endif
{
if (qmlContext)
- m_qmlContext.set(engine, *qmlContext);
+ m_qmlContext.set(v4, *qmlContext);
if (callback.as<QV4::FunctionObject>())
- m_callbackFunction.set(engine, callback);
+ m_callbackFunction.set(v4, callback);
m_resultObject.set(v4, resultValue(v4));
#if QT_CONFIG(qml_network)
- if (QQmlEngine *qmlEngine = engine->qmlEngine()) {
+ if (QQmlEngine *qmlEngine = v4->qmlEngine()) {
m_network = qmlEngine->networkAccessManager();
QNetworkRequest request;
@@ -202,37 +203,40 @@ void QV4Include::finished()
/*
Documented in qv4engine.cpp
*/
-QV4::ReturnedValue QV4Include::method_include(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
+QJSValue QV4Include::method_include(QV4::ExecutionEngine *engine, const QUrl &url,
+ const QJSValue &callbackFunction)
{
- QV4::Scope scope(b);
- if (!argc)
- RETURN_UNDEFINED();
+ QQmlRefPointer<QQmlContextData> context = engine->callingQmlContext();
- QQmlRefPointer<QQmlContextData> context = scope.engine->callingQmlContext();
-
- if ((!context || !context->isJSContext()) && scope.engine->qmlEngine())
- RETURN_RESULT(scope.engine->throwError(QString::fromUtf8("Qt.include(): Can only be called from JavaScript files")));
+ if ((!context || !context->isJSContext()) && engine->qmlEngine()) {
+ return QJSValuePrivate::fromReturnedValue(
+ engine->throwError(
+ QString::fromUtf8(
+ "Qt.include(): Can only be called from JavaScript files")));
+ }
- QV4::ScopedValue callbackFunction(scope, QV4::Value::undefinedValue());
- if (argc >= 2 && argv[1].as<QV4::FunctionObject>())
- callbackFunction = argv[1];
- QUrl url(scope.engine->resolvedUrl(argv[0].toQStringNoThrow()));
- if (const QQmlEngine *qmlEngine = scope.engine->qmlEngine())
- url = qmlEngine->interceptUrl(url, QQmlAbstractUrlInterceptor::JavaScriptFile);
+ QV4::Scope scope(engine);
+ QV4::ScopedValue scopedCallbackFunction(scope, QV4::Value::undefinedValue());
+ if (auto function = QJSValuePrivate::asManagedType<QV4::FunctionObject>(&callbackFunction))
+ scopedCallbackFunction = *function;
- QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
+ const QQmlEngine *qmlEngine = engine->qmlEngine();
+ const QUrl intercepted = qmlEngine
+ ? qmlEngine->interceptUrl(url, QQmlAbstractUrlInterceptor::JavaScriptFile)
+ : url;
+ QString localFile = QQmlFile::urlToLocalFileOrQrc(intercepted);
QV4::ScopedValue result(scope);
QV4::Scoped<QV4::QmlContext> qmlcontext(scope, scope.engine->qmlContext());
if (localFile.isEmpty()) {
#if QT_CONFIG(qml_network)
- QV4Include *i = new QV4Include(url, scope.engine, qmlcontext, callbackFunction);
+ QV4Include *i = new QV4Include(url, engine, qmlcontext, scopedCallbackFunction);
result = i->result();
#else
result = resultValue(scope.engine, NetworkError);
- callback(callbackFunction, result);
+ callback(scopedCallbackFunction, result);
#endif
} else {
QScopedPointer<QV4::Script> script;
@@ -255,10 +259,10 @@ QV4::ReturnedValue QV4Include::method_include(const QV4::FunctionObject *b, cons
result = resultValue(scope.engine, NetworkError, error);
}
- callback(callbackFunction, result);
+ callback(scopedCallbackFunction, result);
}
- return result->asReturnedValue();
+ return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index 9d0a17a5cc..d375abf20a 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -61,7 +61,8 @@
QT_BEGIN_NAMESPACE
-class QQmlEngine;
+class QJSEngine;
+class QJSValue;
#if QT_CONFIG(qml_network)
class QNetworkAccessManager;
#endif
@@ -77,13 +78,15 @@ public:
Exception = 3
};
- static QV4::ReturnedValue method_include(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QJSValue method_include(QV4::ExecutionEngine *engine, const QUrl &url,
+ const QJSValue &callbackFunction);
private Q_SLOTS:
void finished();
private:
- QV4Include(const QUrl &url, QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &callback);
+ QV4Include(const QUrl &url, QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext,
+ const QV4::Value &callback);
~QV4Include();
QV4::ReturnedValue result();
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index cabe48dbef..1bf3a01f03 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1554,6 +1554,16 @@ static const QQmlPropertyData * RelatedMethod(const QQmlObjectOrGadget &object,
}
}
+static int numDefinedArguments(QV4::CallData *callArgs)
+{
+ int numDefinedArguments = callArgs->argc();
+ while (numDefinedArguments > 0
+ && callArgs->args[numDefinedArguments - 1].type() == QV4::StaticValue::Undefined_Type) {
+ --numDefinedArguments;
+ }
+ return numDefinedArguments;
+}
+
static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQmlPropertyData &data,
QV4::ExecutionEngine *engine, QV4::CallData *callArgs,
QMetaObject::Call callType = QMetaObject::InvokeMetaMethod)
@@ -1567,6 +1577,35 @@ static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQ
+ QLatin1String(unknownTypeError));
}
+ auto handleTooManyArguments = [&](int expectedArguments) {
+ const QMetaObject *metaObject = object.metaObject();
+ const int indexOfClassInfo = metaObject->indexOfClassInfo("QML.StrictArguments");
+ if (indexOfClassInfo != -1
+ && QString::fromUtf8(metaObject->classInfo(indexOfClassInfo).value())
+ == QStringLiteral("true")) {
+ engine->throwError(QStringLiteral("Too many arguments"));
+ return false;
+ }
+
+ const auto stackTrace = engine->stackTrace();
+ if (stackTrace.isEmpty()) {
+ qWarning().nospace().noquote()
+ << "When matching arguments for "
+ << object.className() << "::" << data.name(object.metaObject()) << "():";
+ } else {
+ const StackFrame frame = engine->stackTrace().first();
+ qWarning().noquote() << frame.function + QLatin1Char('@') + frame.source
+ + (frame.line > 0 ? (QLatin1Char(':') + QString::number(frame.line))
+ : QString());
+ }
+
+ qWarning().noquote() << QStringLiteral("Too many arguments, ignoring %1")
+ .arg(callArgs->argc() - expectedArguments);
+ return true;
+ };
+
+ const int definedArgumentCount = numDefinedArguments(callArgs);
+
if (data.hasArguments()) {
int *args = nullptr;
@@ -1588,24 +1627,19 @@ static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQ
return engine->throwError(error);
}
- if (args[0] < callArgs->argc()) {
- Q_ASSERT(!engine->stackTrace().isEmpty());
+ if (args[0] < definedArgumentCount) {
+ if (!handleTooManyArguments(args[0]))
+ return Encode::undefined();
- const StackFrame frame = engine->stackTrace().first();
- qWarning().noquote() << frame.function + QLatin1Char('@') + frame.source
- + (frame.line > 0 ? (QLatin1Char(':') + QString::number(frame.line))
- : QString());
-
- qWarning().noquote() << QStringLiteral("Too many arguments, ignoring %1")
- .arg(callArgs->argc() - args[0]);
}
return CallMethod(object, data.coreIndex(), returnType, args[0], args + 1, engine, callArgs, callType);
} else {
+ if (definedArgumentCount > 0 && !handleTooManyArguments(0))
+ return Encode::undefined();
return CallMethod(object, data.coreIndex(), returnType, 0, nullptr, engine, callArgs, callType);
-
}
}
@@ -1626,7 +1660,8 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const
QV4::ExecutionEngine *engine, QV4::CallData *callArgs, const QQmlPropertyCache *propertyCache,
QMetaObject::Call callType = QMetaObject::InvokeMetaMethod)
{
- int argumentCount = callArgs->argc();
+ const int argumentCount = callArgs->argc();
+ const int definedArgumentCount = numDefinedArguments(callArgs);
QQmlPropertyData best;
int bestParameterScore = INT_MAX;
@@ -1654,7 +1689,7 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const
if (methodArgumentCount > argumentCount)
continue; // We don't have sufficient arguments to call this method
- int methodParameterScore = argumentCount - methodArgumentCount;
+ int methodParameterScore = definedArgumentCount - methodArgumentCount;
if (methodParameterScore > bestParameterScore)
continue; // We already have a better option
diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp
index 02fde97b3d..141c55c0ec 100644
--- a/src/qml/qml/qqmldelayedcallqueue.cpp
+++ b/src/qml/qml/qqmldelayedcallqueue.cpp
@@ -108,6 +108,9 @@ void QQmlDelayedCallQueue::init(QV4::ExecutionEngine* engine)
QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
+ QV4::ExecutionEngine *engine = b->engine();
+ QQmlDelayedCallQueue *self = engine->delayedCallQueue();
+
QV4::Scope scope(b);
if (argc == 0)
THROW_GENERIC_ERROR("Qt.callLater: no arguments given");
@@ -123,8 +126,8 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::F
QVector<DelayedFunctionCall>::Iterator iter;
if (functionData.second != -1) {
// This is a QObject function wrapper
- iter = m_delayedFunctionCalls.begin();
- while (iter != m_delayedFunctionCalls.end()) {
+ iter = self->m_delayedFunctionCalls.begin();
+ while (iter != self->m_delayedFunctionCalls.end()) {
DelayedFunctionCall& dfc = *iter;
QPair<QObject *, int> storedFunctionData = QV4::QObjectMethod::extractQtMethod(dfc.m_function.as<QV4::FunctionObject>());
if (storedFunctionData == functionData) {
@@ -134,8 +137,8 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::F
}
} else {
// This is a JavaScript function (dynamic slot on VMEMO)
- iter = m_delayedFunctionCalls.begin();
- while (iter != m_delayedFunctionCalls.end()) {
+ iter = self->m_delayedFunctionCalls.begin();
+ while (iter != self->m_delayedFunctionCalls.end()) {
DelayedFunctionCall& dfc = *iter;
if (arg0 == dfc.m_function.value()) {
break; // Already stored!
@@ -144,16 +147,16 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::F
}
}
- const bool functionAlreadyStored = (iter != m_delayedFunctionCalls.end());
+ const bool functionAlreadyStored = (iter != self->m_delayedFunctionCalls.end());
if (functionAlreadyStored) {
DelayedFunctionCall dfc = *iter;
- m_delayedFunctionCalls.erase(iter);
- m_delayedFunctionCalls.append(dfc);
+ self->m_delayedFunctionCalls.erase(iter);
+ self->m_delayedFunctionCalls.append(dfc);
} else {
- m_delayedFunctionCalls.append(QV4::PersistentValue(m_engine, arg0));
+ self->m_delayedFunctionCalls.append(QV4::PersistentValue(engine, arg0));
}
- DelayedFunctionCall& dfc = m_delayedFunctionCalls.last();
+ DelayedFunctionCall& dfc = self->m_delayedFunctionCalls.last();
if (dfc.m_objectGuard.isNull()) {
if (functionData.second != -1) {
// if it's a qobject function wrapper, guard against qobject deletion
@@ -166,11 +169,11 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::F
dfc.m_guarded = true;
}
}
- storeAnyArguments(dfc, argv, argc, 1, m_engine);
+ self->storeAnyArguments(dfc, argv, argc, 1, engine);
- if (!m_callbackOutstanding) {
- m_tickedMethod.invoke(this, Qt::QueuedConnection);
- m_callbackOutstanding = true;
+ if (!self->m_callbackOutstanding) {
+ self->m_tickedMethod.invoke(self, Qt::QueuedConnection);
+ self->m_callbackOutstanding = true;
}
return QV4::Encode::undefined();
}
diff --git a/src/qml/qml/qqmldelayedcallqueue_p.h b/src/qml/qml/qqmldelayedcallqueue_p.h
index 7962318561..48ee38bbb9 100644
--- a/src/qml/qml/qqmldelayedcallqueue_p.h
+++ b/src/qml/qml/qqmldelayedcallqueue_p.h
@@ -69,7 +69,9 @@ public:
void init(QV4::ExecutionEngine *);
- QV4::ReturnedValue addUniquelyAndExecuteLater(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue addUniquelyAndExecuteLater(
+ const QV4::FunctionObject *, const QV4::Value *thisObject,
+ const QV4::Value *argv, int argc);
public Q_SLOTS:
void ticked();
diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp
index e3a5df382e..d4473b7020 100644
--- a/src/qml/qml/qqmlglobal.cpp
+++ b/src/qml/qml/qqmlglobal.cpp
@@ -149,9 +149,12 @@ Q_AUTOTEST_EXPORT QQmlColorProvider *QQml_colorProvider(void)
QQmlGuiProvider::~QQmlGuiProvider() {}
-QObject *QQmlGuiProvider::application(QObject *) { return new QQmlApplication(); }
+QQmlApplication *QQmlGuiProvider::application(QObject *parent)
+{
+ return new QQmlApplication(parent);
+}
QStringList QQmlGuiProvider::fontFamilies() { return QStringList(); }
-bool QQmlGuiProvider::openUrlExternally(QUrl &) { return false; }
+bool QQmlGuiProvider::openUrlExternally(const QUrl &) { return false; }
QObject *QQmlGuiProvider::inputMethod()
{
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 5634ada7d1..d32641c10c 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -248,16 +248,16 @@ public:
Q_QML_PRIVATE_EXPORT QQmlColorProvider *QQml_setColorProvider(QQmlColorProvider *);
Q_QML_PRIVATE_EXPORT QQmlColorProvider *QQml_colorProvider();
-
+class QQmlApplication;
class Q_QML_PRIVATE_EXPORT QQmlGuiProvider
{
public:
virtual ~QQmlGuiProvider();
- virtual QObject *application(QObject *parent);
+ virtual QQmlApplication *application(QObject *parent);
virtual QObject *inputMethod();
virtual QObject *styleHints();
virtual QStringList fontFamilies();
- virtual bool openUrlExternally(QUrl &);
+ virtual bool openUrlExternally(const QUrl &);
virtual QString pluginName() const;
};
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 7061cf1c86..0610bf0ccc 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -84,145 +84,42 @@
QT_BEGIN_NAMESPACE
-using namespace QV4;
+Q_LOGGING_CATEGORY(lcRootProperties, "qml.rootObjectProperties");
-DEFINE_OBJECT_VTABLE(QtObject);
+using namespace QV4;
#define THROW_TYPE_ERROR_WITH_MESSAGE(msg) \
do { \
return scope.engine->throwTypeError(QString::fromUtf8(msg)); \
} while (false)
-void Heap::QtObject::init(QQmlEngine *qmlEngine)
+QtObject::QtObject(ExecutionEngine *engine)
+ : m_engine(engine)
{
- Heap::Object::init();
- enumeratorIterator = 0;
- keyIterator = 0;
- Scope scope(internalClass->engine);
- ScopedObject o(scope, this);
-
- {
- ScopedString str(scope);
- ScopedValue v(scope);
- o->put((str = scope.engine->newString(QStringLiteral("Asynchronous"))), (v = QV4::Value::fromInt32(0)));
- o->put((str = scope.engine->newString(QStringLiteral("Synchronous"))), (v = QV4::Value::fromInt32(1)));
- }
-
- o->defineDefaultProperty(QStringLiteral("include"), QV4Include::method_include);
- o->defineDefaultProperty(QStringLiteral("isQtObject"), QV4::QtObject::method_isQtObject);
- o->defineDefaultProperty(QStringLiteral("color"), QV4::QtObject::method_color);
- o->defineDefaultProperty(QStringLiteral("rgba"), QV4::QtObject::method_rgba);
- o->defineDefaultProperty(QStringLiteral("hsla"), QV4::QtObject::method_hsla);
- o->defineDefaultProperty(QStringLiteral("hsva"), QV4::QtObject::method_hsva);
- o->defineDefaultProperty(QStringLiteral("colorEqual"), QV4::QtObject::method_colorEqual);
- o->defineDefaultProperty(QStringLiteral("rect"), QV4::QtObject::method_rect);
- o->defineDefaultProperty(QStringLiteral("point"), QV4::QtObject::method_point);
- o->defineDefaultProperty(QStringLiteral("size"), QV4::QtObject::method_size);
- o->defineDefaultProperty(QStringLiteral("font"), QV4::QtObject::method_font);
-
- o->defineDefaultProperty(QStringLiteral("vector2d"), QV4::QtObject::method_vector2d);
- o->defineDefaultProperty(QStringLiteral("vector3d"), QV4::QtObject::method_vector3d);
- o->defineDefaultProperty(QStringLiteral("vector4d"), QV4::QtObject::method_vector4d);
- o->defineDefaultProperty(QStringLiteral("quaternion"), QV4::QtObject::method_quaternion);
- o->defineDefaultProperty(QStringLiteral("matrix4x4"), QV4::QtObject::method_matrix4x4);
-
- o->defineDefaultProperty(QStringLiteral("formatDate"), QV4::QtObject::method_formatDate);
- o->defineDefaultProperty(QStringLiteral("formatTime"), QV4::QtObject::method_formatTime);
- o->defineDefaultProperty(QStringLiteral("formatDateTime"), QV4::QtObject::method_formatDateTime);
-
- o->defineDefaultProperty(QStringLiteral("openUrlExternally"), QV4::QtObject::method_openUrlExternally);
- o->defineDefaultProperty(QStringLiteral("fontFamilies"), QV4::QtObject::method_fontFamilies);
- o->defineDefaultProperty(QStringLiteral("md5"), QV4::QtObject::method_md5);
- o->defineDefaultProperty(QStringLiteral("btoa"), QV4::QtObject::method_btoa);
- o->defineDefaultProperty(QStringLiteral("atob"), QV4::QtObject::method_atob);
- o->defineDefaultProperty(QStringLiteral("resolvedUrl"), QV4::QtObject::method_resolvedUrl);
-#if QT_CONFIG(qml_locale)
- o->defineDefaultProperty(QStringLiteral("locale"), QV4::QtObject::method_locale);
-#endif
- o->defineDefaultProperty(QStringLiteral("binding"), QV4::QtObject::method_binding);
-
- if (qmlEngine) {
- o->defineDefaultProperty(QStringLiteral("alpha"), QV4::QtObject::method_alpha);
- o->defineDefaultProperty(QStringLiteral("lighter"), QV4::QtObject::method_lighter);
- o->defineDefaultProperty(QStringLiteral("darker"), QV4::QtObject::method_darker);
- o->defineDefaultProperty(QStringLiteral("tint"), QV4::QtObject::method_tint);
- o->defineDefaultProperty(QStringLiteral("quit"), QV4::QtObject::method_quit);
- o->defineDefaultProperty(QStringLiteral("exit"), QV4::QtObject::method_exit);
- o->defineDefaultProperty(QStringLiteral("createQmlObject"), QV4::QtObject::method_createQmlObject);
- o->defineDefaultProperty(QStringLiteral("createComponent"), QV4::QtObject::method_createComponent);
- }
-
- o->defineAccessorProperty(QStringLiteral("platform"), QV4::QtObject::method_get_platform, nullptr);
- o->defineAccessorProperty(QStringLiteral("application"), QV4::QtObject::method_get_application, nullptr);
- o->defineAccessorProperty(QStringLiteral("inputMethod"), QV4::QtObject::method_get_inputMethod, nullptr);
- o->defineAccessorProperty(QStringLiteral("styleHints"), QV4::QtObject::method_get_styleHints, nullptr);
+ QV4::Scope scope(engine);
+ QV4::ScopedString callLaterName(scope, engine->newIdentifier(QStringLiteral("callLater")));
- o->defineDefaultProperty(QStringLiteral("callLater"), QV4::QtObject::method_callLater);
-}
+ QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createBuiltinFunction(
+ engine, callLaterName, QQmlDelayedCallQueue::addUniquelyAndExecuteLater, 1));
-void QtObject::addAll()
-{
- bool dummy = false;
- findAndAdd(nullptr, dummy);
+ m_callLater = QJSValuePrivate::fromReturnedValue(function.asReturnedValue());
}
-ReturnedValue QtObject::findAndAdd(const QString *name, bool &foundProperty) const
+QtObject *QtObject::create(QQmlEngine *, QJSEngine *jsEngine)
{
- Scope scope(engine());
- ScopedObject o(scope, this);
- ScopedString key(scope);
- ScopedValue value(scope);
-
- const QMetaObject *qtMetaObject = &Qt::staticMetaObject;
- for (int enumCount = qtMetaObject->enumeratorCount(); d()->enumeratorIterator < enumCount;
- ++d()->enumeratorIterator) {
- QMetaEnum enumerator = qtMetaObject->enumerator(d()->enumeratorIterator);
- for (int keyCount = enumerator.keyCount(); d()->keyIterator < keyCount; ++d()->keyIterator) {
- key = scope.engine->newString(QString::fromUtf8(enumerator.key(d()->keyIterator)));
- value = QV4::Value::fromInt32(enumerator.value(d()->keyIterator));
- o->put(key, value);
- if (name && key->toQString() == *name) {
- ++d()->keyIterator;
- foundProperty = true;
- return value->asReturnedValue();
- }
- }
- d()->keyIterator = 0;
- }
- d()->enumeratorIterator = Heap::QtObject::Finished;
- foundProperty = false;
- return Encode::undefined();
+ QV4::ExecutionEngine *v4 = jsEngine->handle();
+ QV4::Scope scope(v4);
+ ScopedObject globalObject(scope, v4->globalObject);
+ ScopedString qtName(scope, v4->newString(QStringLiteral("Qt")));
+ QV4::ScopedValue result(scope, globalObject->get(qtName->toPropertyKey()));
+ return qobject_cast<QtObject *>(result->as<QV4::QObjectWrapper>()->object());
}
-ReturnedValue QtObject::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
+QJSValue QtObject::include(const QString &url, const QJSValue &callback) const
{
- bool hasProp = false;
- if (hasProperty == nullptr) {
- hasProperty = &hasProp;
- }
-
- ReturnedValue ret = QV4::Object::virtualGet(m, id, receiver, hasProperty);
- if (*hasProperty) {
- return ret;
- }
-
- auto that = static_cast<const QtObject*>(m);
- if (!that->d()->isComplete()) {
- const QString key = id.toQString();
- ret = that->findAndAdd(&key, *hasProperty);
- }
-
- return ret;
+ return QV4Include::method_include(v4Engine(), v4Engine()->resolvedUrl(url), callback);
}
-OwnPropertyKeyIterator *QtObject::virtualOwnPropertyKeys(const Object *m, Value *target)
-{
- auto that = static_cast<const QtObject*>(m);
- if (!that->d()->isComplete())
- const_cast<QtObject *>(that)->addAll();
-
- return Object::virtualOwnPropertyKeys(m, target);
-}
/*!
\qmlmethod bool Qt::isQtObject(object)
@@ -230,12 +127,9 @@ OwnPropertyKeyIterator *QtObject::virtualOwnPropertyKeys(const Object *m, Value
Returns \c true if \a object is a valid reference to a Qt or QML object,
\c false otherwise.
*/
-ReturnedValue QtObject::method_isQtObject(const FunctionObject *, const Value *, const Value *argv, int argc)
+bool QtObject::isQtObject(const QJSValue &value) const
{
- if (argc == 0)
- RETURN_RESULT(QV4::Encode(false));
-
- return QV4::Encode(argv[0].as<QV4::QObjectWrapper>() != nullptr);
+ return qjsvalue_cast<QObject *>(value) != nullptr;
}
/*!
@@ -244,25 +138,15 @@ ReturnedValue QtObject::method_isQtObject(const FunctionObject *, const Value *,
Returns the color corresponding to the given \a name (i.e. red or #ff0000).
If there is no such color, \c null is returned.
*/
-ReturnedValue QtObject::method_color(const FunctionObject *f, const Value *, const Value *argv,
- int argc)
+QVariant QtObject::color(const QString &name) const
{
- QV4::Scope scope(f);
- if (argc != 1)
- THROW_GENERIC_ERROR("Qt.color(): Qt.color takes exactly one argument");
-
- QVariant v = scope.engine->toVariant(argv[0], -1);
- if (v.userType() == QMetaType::QString) {
- bool ok = false;
- v = QQmlStringConverters::colorFromString(v.toString(), &ok);
- if (!ok) {
- return QV4::Encode::null();
- }
- } else {
- THROW_GENERIC_ERROR("Qt.color(): Argument must be a string");
- }
+ bool ok = false;
+ const QVariant v = QQmlStringConverters::colorFromString(name, &ok);
+ if (ok)
+ return v;
- return scope.engine->fromVariant(v);
+ v4Engine()->throwError(QStringLiteral("\"%1\" is not a valid color name").arg(name));
+ return QVariant::fromValue(nullptr);
}
/*!
@@ -271,17 +155,8 @@ ReturnedValue QtObject::method_color(const FunctionObject *f, const Value *, con
Returns a color with the specified \a red, \a green, \a blue, and \a alpha
components. All components should be in the range 0-1 (inclusive).
*/
-ReturnedValue QtObject::method_rgba(const FunctionObject *f, const Value *, const Value *argv, int argc)
+QVariant QtObject::rgba(double r, double g, double b, double a) const
{
- QV4::Scope scope(f);
- if (argc < 3 || argc > 4)
- THROW_GENERIC_ERROR("Qt.rgba(): Invalid arguments");
-
- double r = argv[0].toNumber();
- double g = argv[1].toNumber();
- double b = argv[2].toNumber();
- double a = (argc == 4) ? argv[3].toNumber() : 1;
-
if (r < 0.0) r=0.0;
if (r > 1.0) r=1.0;
if (g < 0.0) g=0.0;
@@ -291,7 +166,7 @@ ReturnedValue QtObject::method_rgba(const FunctionObject *f, const Value *, cons
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return scope.engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
+ return QQml_colorProvider()->fromRgbF(r, g, b, a);
}
/*!
@@ -300,18 +175,8 @@ ReturnedValue QtObject::method_rgba(const FunctionObject *f, const Value *, cons
Returns a color with the specified \a hue, \a saturation, \a lightness, and \a alpha
components. All components should be in the range 0-1 (inclusive).
*/
-ReturnedValue QtObject::method_hsla(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::hsla(double h, double s, double l, double a) const
{
- QV4::Scope scope(b);
- int argCount = argc;
- if (argCount < 3 || argCount > 4)
- THROW_GENERIC_ERROR("Qt.hsla(): Invalid arguments");
-
- double h = argv[0].toNumber();
- double s = argv[1].toNumber();
- double l = argv[2].toNumber();
- double a = (argCount == 4) ? argv[3].toNumber() : 1;
-
if (h < 0.0) h=0.0;
if (h > 1.0) h=1.0;
if (s < 0.0) s=0.0;
@@ -321,7 +186,7 @@ ReturnedValue QtObject::method_hsla(const FunctionObject *b, const Value *, cons
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return scope.engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
+ return QQml_colorProvider()->fromHslF(h, s, l, a);
}
/*!
@@ -332,24 +197,14 @@ ReturnedValue QtObject::method_hsla(const FunctionObject *b, const Value *, cons
components. All components should be in the range 0-1 (inclusive).
*/
-ReturnedValue QtObject::method_hsva(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::hsva(double h, double s, double v, double a) const
{
- QV4::Scope scope(b);
- int argCount = argc;
- if (argCount < 3 || argCount > 4)
- THROW_GENERIC_ERROR("Qt.hsva(): Invalid arguments");
-
- double h = argv[0].toNumber();
- double s = argv[1].toNumber();
- double v = argv[2].toNumber();
- double a = (argCount == 4) ? argv[3].toNumber() : 1;
-
h = qBound(0.0, h, 1.0);
s = qBound(0.0, s, 1.0);
v = qBound(0.0, v, 1.0);
a = qBound(0.0, a, 1.0);
- return scope.engine->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a));
+ return QQml_colorProvider()->fromHsvF(h, s, v, a);
}
/*!
@@ -360,36 +215,35 @@ ReturnedValue QtObject::method_hsva(const FunctionObject *b, const Value *, cons
is supplied it must be convertible to a color, as described for the
\l{colorbasictypedocs}{color} basic type.
*/
-ReturnedValue QtObject::method_colorEqual(const FunctionObject *b, const Value *, const Value *argv, int argc)
+bool QtObject::colorEqual(const QVariant &lhs, const QVariant &rhs) const
{
- QV4::Scope scope(b);
- if (argc != 2)
- THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
-
bool ok = false;
- QVariant lhs = scope.engine->toVariant(argv[0], -1);
- if (lhs.userType() == QMetaType::QString) {
- lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok);
+ QVariant color1 = lhs;
+ if (color1.userType() == QMetaType::QString) {
+ color1 = QQmlStringConverters::colorFromString(color1.toString(), &ok);
if (!ok) {
- THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
+ v4Engine()->throwError(QStringLiteral("Qt.colorEqual(): Invalid color name"));
+ return false;
}
- } else if (lhs.userType() != QMetaType::QColor) {
- THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
+ } else if (color1.userType() != QMetaType::QColor) {
+ v4Engine()->throwError(QStringLiteral("Qt.colorEqual(): Invalid arguments"));
+ return false;
}
- QVariant rhs = scope.engine->toVariant(argv[1], -1);
- if (rhs.userType() == QMetaType::QString) {
- rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok);
+ QVariant color2 = rhs;
+ if (color2.userType() == QMetaType::QString) {
+ color2 = QQmlStringConverters::colorFromString(color2.toString(), &ok);
if (!ok) {
- THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
+ v4Engine()->throwError(QStringLiteral("Qt.colorEqual(): Invalid color name"));
+ return false;
}
- } else if (rhs.userType() != QMetaType::QColor) {
- THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
+ } else if (color2.userType() != QMetaType::QColor) {
+ v4Engine()->throwError(QStringLiteral("Qt.colorEqual(): Invalid arguments"));
+ return false;
}
- bool equal = (lhs == rhs);
- return QV4::Encode(equal);
+ return color1 == color2;
}
/*!
@@ -397,18 +251,9 @@ ReturnedValue QtObject::method_colorEqual(const FunctionObject *b, const Value *
Returns a rect with the top-left corner at \a x, \a y and the specified \a width and \a height.
*/
-ReturnedValue QtObject::method_rect(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QRectF QtObject::rect(double x, double y, double width, double height) const
{
- QV4::Scope scope(b);
- if (argc != 4)
- THROW_GENERIC_ERROR("Qt.rect(): Invalid arguments");
-
- double x = argv[0].toNumber();
- double y = argv[1].toNumber();
- double w = argv[2].toNumber();
- double h = argv[3].toNumber();
-
- return scope.engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
+ return QRectF(x, y, width, height);
}
/*!
@@ -416,16 +261,9 @@ ReturnedValue QtObject::method_rect(const FunctionObject *b, const Value *, cons
Returns a point with the specified \a x and \a y coordinates.
*/
-ReturnedValue QtObject::method_point(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QPointF QtObject::point(double x, double y) const
{
- QV4::Scope scope(b);
- if (argc != 2)
- THROW_GENERIC_ERROR("Qt.point(): Invalid arguments");
-
- double x = argv[0].toNumber();
- double y = argv[1].toNumber();
-
- return scope.engine->fromVariant(QVariant::fromValue(QPointF(x, y)));
+ return QPointF(x, y);
}
/*!
@@ -433,16 +271,9 @@ ReturnedValue QtObject::method_point(const FunctionObject *b, const Value *, con
Returns a size with the specified \a width and \a height.
*/
-ReturnedValue QtObject::method_size(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QSizeF QtObject::size(double w, double h) const
{
- QV4::Scope scope(b);
- if (argc != 2)
- THROW_GENERIC_ERROR("Qt.size(): Invalid arguments");
-
- double w = argv[0].toNumber();
- double h = argv[1].toNumber();
-
- return scope.engine->fromVariant(QVariant::fromValue(QSizeF(w, h)));
+ return QSizeF(w, h);
}
/*!
@@ -454,37 +285,53 @@ ReturnedValue QtObject::method_size(const FunctionObject *b, const Value *, cons
subproperty names, and the values are valid values for each subproperty.
Invalid keys will be ignored.
*/
-ReturnedValue QtObject::method_font(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::font(const QJSValue &fontSpecifier) const
{
- QV4::Scope scope(b);
- if (argc != 1 || !argv[0].isObject())
- THROW_GENERIC_ERROR("Qt.font(): Invalid arguments");
+ if (!fontSpecifier.isObject()) {
+ v4Engine()->throwError(QStringLiteral("Qt.font(): Invalid arguments"));
+ return QVariant();
+ }
- QVariant v;
- if (!QQml_valueTypeProvider()->createValueType(
- QMetaType::QFont, QJSValuePrivate::fromReturnedValue(argv[0].asReturnedValue()),
- v)) {
- THROW_GENERIC_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
+ {
+ QVariant v;
+ if (QQml_valueTypeProvider()->createValueType(QMetaType::QFont, fontSpecifier, v))
+ return v;
}
- return scope.engine->fromVariant(v);
+
+ v4Engine()->throwError(QStringLiteral("Qt.font(): Invalid argument: "
+ "no valid font subproperties specified"));
+ return QVariant();
}
-static ReturnedValue createValueType(const FunctionObject *b, const Value *argv, int argc,
- int parameters, QMetaType::Type type, const char *method)
+template<typename T>
+void addParameters(QJSEngine *e, QJSValue &result, int i, T parameter)
{
- QV4::Scope scope(b);
- if (argc != parameters) {
- return scope.engine->throwError(QString::fromUtf8("Qt.%1(): Invalid arguments")
- .arg(QString::fromUtf8(method)));
- }
+ result.setProperty(i, e->toScriptValue(parameter));
+}
- QJSValue params = scope.engine->jsEngine()->newArray(parameters);
- for (int i = 0; i < parameters; ++i)
- params.setProperty(i, QJSValuePrivate::fromReturnedValue(argv[i].asReturnedValue()));
+template<>
+void addParameters<double>(QJSEngine *, QJSValue &result, int i, double parameter)
+{
+ result.setProperty(i, QJSValue(parameter));
+}
+
+template<typename T, typename ...Others>
+void addParameters(QJSEngine *e, QJSValue &result, int i, T parameter, Others... others)
+{
+ addParameters<T>(e, result, i, parameter);
+ addParameters<Others...>(e, result, ++i, others...);
+}
+template<typename ...T>
+static QVariant createValueType(QJSEngine *e, QMetaType::Type type, T... parameters)
+{
+ if (!e)
+ return QVariant();
+ QJSValue params = e->newArray(sizeof...(parameters));
+ addParameters(e, params, 0, parameters...);
QVariant variant;
QQml_valueTypeProvider()->createValueType(type, params, variant);
- return scope.engine->fromVariant(variant);
+ return variant;
}
/*!
@@ -492,9 +339,9 @@ static ReturnedValue createValueType(const FunctionObject *b, const Value *argv,
Returns a vector2d with the specified \a x and \a y values.
*/
-ReturnedValue QtObject::method_vector2d(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::vector2d(double x, double y) const
{
- return createValueType(b, argv, argc, 2, QMetaType::QVector2D, "vector2d");
+ return createValueType(jsEngine(), QMetaType::QVector2D, x, y);
}
/*!
@@ -502,9 +349,9 @@ ReturnedValue QtObject::method_vector2d(const FunctionObject *b, const Value *,
Returns a vector3d with the specified \a x, \a y, and \a z values.
*/
-ReturnedValue QtObject::method_vector3d(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::vector3d(double x, double y, double z) const
{
- return createValueType(b, argv, argc, 3, QMetaType::QVector3D, "vector3d");
+ return createValueType(jsEngine(), QMetaType::QVector3D, x, y, z);
}
/*!
@@ -512,9 +359,9 @@ ReturnedValue QtObject::method_vector3d(const FunctionObject *b, const Value *,
Returns a vector4d with the specified \a x, \a y, \a z, and \a w values.
*/
-ReturnedValue QtObject::method_vector4d(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::vector4d(double x, double y, double z, double w) const
{
- return createValueType(b, argv, argc, 4, QMetaType::QVector4D, "vector4d");
+ return createValueType(jsEngine(), QMetaType::QVector4D, x, y, z, w);
}
/*!
@@ -522,9 +369,9 @@ ReturnedValue QtObject::method_vector4d(const FunctionObject *b, const Value *,
Returns a quaternion with the specified \a scalar, \a x, \a y, and \a z values.
*/
-ReturnedValue QtObject::method_quaternion(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::quaternion(double scalar, double x, double y, double z) const
{
- return createValueType(b, argv, argc, 4, QMetaType::QQuaternion, "quaternion");
+ return createValueType(jsEngine(), QMetaType::QQuaternion, scalar, x, y, z);
}
/*!
@@ -548,27 +395,53 @@ ReturnedValue QtObject::method_quaternion(const FunctionObject *b, const Value *
Finally, the function may be called with no arguments and the resulting
matrix will be the identity matrix.
*/
-ReturnedValue QtObject::method_matrix4x4(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::matrix4x4() const
{
- QV4::Scope scope(b);
+ QVariant variant;
+ QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, QJSValue(), variant);
+ return variant;
+}
- if (argc == 0) {
- QVariant variant;
- QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, QJSValue(), variant);
- return scope.engine->fromVariant(variant);
+QVariant QtObject::matrix4x4(const QJSValue &value) const
+{
+ if (value.isObject()) {
+ QVariant v;
+ if (QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, value, v))
+ return v;
}
- if (argc == 1 && argv[0].isObject()) {
- QVariant v;
- if (!QQml_valueTypeProvider()->createValueType(
- QMetaType::QMatrix4x4,
- QJSValuePrivate::fromReturnedValue(argv[0].asReturnedValue()), v)) {
- THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
+ v4Engine()->throwError(QStringLiteral("Qt.matrix4x4(): Invalid argument: "
+ "not a valid matrix4x4 values array"));
+ return QVariant();
+}
+
+QVariant QtObject::matrix4x4(double m11, double m12, double m13, double m14,
+ double m21, double m22, double m23, double m24,
+ double m31, double m32, double m33, double m34,
+ double m41, double m42, double m43, double m44) const
+{
+ return createValueType(jsEngine(), QMetaType::QMatrix4x4,
+ m11, m12, m13, m14, m21, m22, m23, m24,
+ m31, m32, m33, m34, m41, m42, m43, m44);
+}
+
+static QVariant colorVariantFromJSValue(const QJSValue &color, bool *ok)
+{
+ QVariant v;
+ if (color.isString()) {
+ v = QQmlStringConverters::colorFromString(color.toString(), ok);
+ if (!(*ok))
+ return QVariant::fromValue(nullptr);
+ } else {
+ v = color.toVariant();
+ if (v.userType() != QMetaType::QColor) {
+ *ok = false;
+ return QVariant::fromValue(nullptr);
}
- return scope.engine->fromVariant(v);
}
- return createValueType(b, argv, argc, 16, QMetaType::QMatrix4x4, "matrix4x4");
+ *ok = true;
+ return v;
}
/*!
@@ -586,28 +459,11 @@ ReturnedValue QtObject::method_matrix4x4(const FunctionObject *b, const Value *,
If \a factor is not supplied, returns a color that is 50% lighter than \a baseColor (factor 1.5).
*/
-ReturnedValue QtObject::method_lighter(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::lighter(const QJSValue &color, double factor) const
{
- QV4::Scope scope(b);
- if (argc != 1 && argc != 2)
- THROW_GENERIC_ERROR("Qt.lighter(): Invalid arguments");
-
- QVariant v = scope.engine->toVariant(argv[0], -1);
- if (v.userType() == QMetaType::QString) {
- bool ok = false;
- v = QQmlStringConverters::colorFromString(v.toString(), &ok);
- if (!ok) {
- return QV4::Encode::null();
- }
- } else if (v.userType() != QMetaType::QColor) {
- return QV4::Encode::null();
- }
-
- qreal factor = 1.5;
- if (argc == 2)
- factor = argv[1].toNumber();
-
- return scope.engine->fromVariant(QQml_colorProvider()->lighter(v, factor));
+ bool ok;
+ const QVariant v = colorVariantFromJSValue(color, &ok);
+ return ok ? QQml_colorProvider()->lighter(v, factor) : v;
}
/*!
@@ -626,28 +482,11 @@ ReturnedValue QtObject::method_lighter(const FunctionObject *b, const Value *, c
If \a factor is not supplied, returns a color that is 50% darker than \a baseColor (factor 2.0).
*/
-ReturnedValue QtObject::method_darker(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::darker(const QJSValue &color, double factor) const
{
- QV4::Scope scope(b);
- if (argc != 1 && argc != 2)
- THROW_GENERIC_ERROR("Qt.darker(): Invalid arguments");
-
- QVariant v = scope.engine->toVariant(argv[0], -1);
- if (v.userType() == QMetaType::QString) {
- bool ok = false;
- v = QQmlStringConverters::colorFromString(v.toString(), &ok);
- if (!ok) {
- return QV4::Encode::null();
- }
- } else if (v.userType() != QMetaType::QColor) {
- return QV4::Encode::null();
- }
-
- qreal factor = 2.0;
- if (argc == 2)
- factor = argv[1].toNumber();
-
- return scope.engine->fromVariant(QQml_colorProvider()->darker(v, factor));
+ bool ok;
+ const QVariant v = colorVariantFromJSValue(color, &ok);
+ return ok ? QQml_colorProvider()->darker(v, factor) : v;
}
/*!
@@ -657,26 +496,11 @@ ReturnedValue QtObject::method_darker(const FunctionObject *b, const Value *, co
\a value is a real ranging from 0 (completely transparent) to 1 (completely opaque).
*/
-ReturnedValue QtObject::method_alpha(const FunctionObject *b, const Value *, const Value *argv,
- int argc)
+QVariant QtObject::alpha(const QJSValue &baseColor, double value) const
{
- QV4::Scope scope(b);
- if (argc != 2)
- THROW_GENERIC_ERROR("Qt.alpha(): Wrong number of arguments provided");
-
- QVariant v = scope.engine->toVariant(argv[0], -1);
- if (v.userType() == QMetaType::QString) {
- bool ok = false;
- v = QQmlStringConverters::colorFromString(v.toString(), &ok);
- if (!ok)
- return QV4::Encode::null();
- } else if (v.userType() != QMetaType::QColor) {
- return QV4::Encode::null();
- }
-
- qreal value = argv[1].toNumber();
-
- return scope.engine->fromVariant(QQml_colorProvider()->alpha(v, value));
+ bool ok;
+ const QVariant v = colorVariantFromJSValue(baseColor, &ok);
+ return ok ? QQml_colorProvider()->alpha(v, value) : v;
}
/*!
@@ -705,37 +529,19 @@ ReturnedValue QtObject::method_alpha(const FunctionObject *b, const Value *, con
Tint is most useful when a subtle change is intended to be conveyed due to some event;
you can then use tinting to more effectively tune the visible color.
*/
-ReturnedValue QtObject::method_tint(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QVariant QtObject::tint(const QJSValue &baseColor, const QJSValue &tintColor) const
{
- QV4::Scope scope(b);
- if (argc != 2)
- THROW_GENERIC_ERROR("Qt.tint(): Invalid arguments");
+ bool ok;
// base color
- QVariant v1 = scope.engine->toVariant(argv[0], -1);
- if (v1.userType() == QMetaType::QString) {
- bool ok = false;
- v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
- if (!ok) {
- return QV4::Encode::null();
- }
- } else if (v1.userType() != QMetaType::QColor) {
- return QV4::Encode::null();
- }
+ const QVariant v1 = colorVariantFromJSValue(baseColor, &ok);
+ if (!ok)
+ return v1;
// tint color
- QVariant v2 = scope.engine->toVariant(argv[1], -1);
- if (v2.userType() == QMetaType::QString) {
- bool ok = false;
- v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
- if (!ok) {
- return QV4::Encode::null();
- }
- } else if (v2.userType() != QMetaType::QColor) {
- return QV4::Encode::null();
- }
+ const QVariant v2 = colorVariantFromJSValue(tintColor, &ok);
- return scope.engine->fromVariant(QQml_colorProvider()->tint(v1, v2));
+ return ok ? QQml_colorProvider()->tint(v1, v2) : v2;
}
namespace {
@@ -753,46 +559,6 @@ QString formatDateTimeObjectUsingDateFormat(T formatThis, Qt::DateFormat format)
// Q_UNREACHABLE(); // ### Qt 6: restore once the default is gone
return QString();
}
-
-template <typename T>
-ReturnedValue formatDateTimeObject(const T &formatThis, const QV4::Scope &scope, const QString &functionName, int argc, const Value *argv) {
-
- QString formatted;
- if (argc >= 2) {
- QV4::ScopedString s(scope, argv[1]);
- if (s) {
- if (argc == 3)
- scope.engine->throwError(QLatin1String("%1(): Stay argument, third argument can only be used if second argument is a locale").arg(functionName));
- QString format = s->toQString();
- formatted = formatThis.toString(format);
- } else if (argv[1].isNumber()) {
- if (argc == 3)
- scope.engine->throwError(QLatin1String("%1(): Stay argument, third argument can only be used if second argument is a locale").arg(functionName));
- quint32 intFormat = argv[1].asDouble();
- Qt::DateFormat format = Qt::DateFormat(intFormat);
- formatted = formatDateTimeObjectUsingDateFormat(formatThis, format);
- } else {
- QLocale::FormatType formatOptions = QLocale::ShortFormat;
- if (argc == 3) {
- if (argv[2].isNumber())
- formatOptions = QLocale::FormatType(quint32(argv[2].asDouble()));
- else
- scope.engine->throwError(QLatin1String("%1(): Third argument must be a Locale format option").arg(functionName));
- }
- auto enginePriv = QQmlEnginePrivate::get(scope.engine->qmlEngine());
- auto localeMetaTypeId = qMetaTypeId<QLocale>();
- QVariant locale = enginePriv->v4engine()->toVariant(argv[1], localeMetaTypeId);
- if (!locale.canConvert(QMetaType(localeMetaTypeId)))
- scope.engine->throwError(QLatin1String("%1(): Bad second argument (must be either string, number or locale)").arg(functionName));
- formatted = locale.value<QLocale>().toString(formatThis, formatOptions);
- }
- } else {
- formatted = QLocale().toString(formatThis, QLocale::ShortFormat);
- }
-
- return Encode(scope.engine->newString(formatted));
-}
-
}
/*!
@@ -811,17 +577,23 @@ default locale.
\sa Locale
*/
-ReturnedValue QtObject::method_formatDate(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QString QtObject::formatDate(const QDate &date, const QString &format) const
{
- QV4::Scope scope(b);
- if (argc < 1)
- THROW_GENERIC_ERROR("Qt.formatDate(): Missing argument");
- if (argc > 3)
- THROW_GENERIC_ERROR("Qt.formatDate(): Stray arguments; formatDate takes at most 3 arguments.");
+ return date.toString(format);
+}
- QDate date = scope.engine->toVariant(argv[0], -1).toDateTime().date();
- return formatDateTimeObject(date, scope, QLatin1String("Qt.formatDate"), argc, argv);
+QString QtObject::formatDate(const QDate &date, Qt::DateFormat format) const
+{
+ return formatDateTimeObjectUsingDateFormat(date, format);
+}
+
+#if QT_CONFIG(qml_locale)
+QString QtObject::formatDate(const QDate &date, const QLocale &locale,
+ QLocale::FormatType formatType) const
+{
+ return locale.toString(date, formatType);
}
+#endif
/*!
\qmlmethod string Qt::formatTime(datetime time, variant format, variant localeFormatOption)
@@ -839,23 +611,73 @@ If \a format is not specified, \a time is formatted using
\sa Locale
*/
-ReturnedValue QtObject::method_formatTime(const FunctionObject *b, const Value *, const Value *argv, int argc)
+static std::optional<QTime> timeFromString(const QString &string, QV4::ExecutionEngine *engine)
{
- QV4::Scope scope(b);
- if (argc < 1)
- THROW_GENERIC_ERROR("Qt.formatTime(): Missing argument");
- if (argc > 3)
- THROW_GENERIC_ERROR("Qt.formatTime(): Stray arguments; formatTime takes at most 3 arguments.");
+ {
+ const QTime time = QTime::fromString(string, Qt::ISODate);
+ if (time.isValid())
+ return time;
+ }
+
+ {
+ // For historical reasons, the string argument is parsed as datetime, not as only time
+ const QDateTime dateTime = QDateTime::fromString(string, Qt::ISODate);
+ if (dateTime.isValid()) {
+ qCWarning(lcRootProperties())
+ << string << "is a date/time string being passed to formatTime()."
+ << "You should only pass time strings to formatTime().";
+ return dateTime.time();
+ }
+ }
+
+ engine->throwError(QStringLiteral("Invalid argument passed to formatTime(): %1").arg(string));
+ return std::nullopt;
+}
+
+QString QtObject::formatTime(const QTime &time, const QString &format) const
+{
+ return time.toString(format);
+}
+
+QString QtObject::formatTime(const QString &time, const QString &format) const
+{
+
+ if (auto qTime = timeFromString(time, v4Engine()))
+ return formatTime(qTime.value(), format);
+
+ return QString();
+}
+
+QString QtObject::formatTime(const QTime &time, Qt::DateFormat format) const
+{
+ return formatDateTimeObjectUsingDateFormat(time, format);
+}
- QVariant argVariant = scope.engine->toVariant(argv[0], -1);
- QTime time;
- if (argv[0].as<DateObject>() || (argVariant.userType() == QMetaType::QString))
- time = argVariant.toDateTime().time();
- else // if (argVariant.type() == QVariant::Time), or invalid.
- time = argVariant.toTime();
- return formatDateTimeObject(time, scope, QLatin1String("Qt.formatTime"), argc, argv);
+QString QtObject::formatTime(const QString &time, Qt::DateFormat format) const
+{
+ if (auto qTime = timeFromString(time, v4Engine()))
+ return formatTime(qTime.value(), format);
+
+ return QString();
+}
+
+#if QT_CONFIG(qml_locale)
+QString QtObject::formatTime(const QTime &time, const QLocale &locale,
+ QLocale::FormatType formatType) const
+{
+ return locale.toString(time, formatType);
}
+QString QtObject::formatTime(const QString &time, const QLocale &locale,
+ QLocale::FormatType formatType) const
+{
+ if (auto qTime = timeFromString(time, v4Engine()))
+ return locale.toString(qTime.value(), formatType);
+
+ return QString();
+}
+#endif
+
/*!
\qmlmethod string Qt::formatDateTime(datetime dateTime, variant format, variant localeFormatOption)
@@ -954,17 +776,23 @@ with the \a format values below to produce the following results:
\sa Locale
*/
-ReturnedValue QtObject::method_formatDateTime(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QString QtObject::formatDateTime(const QDateTime &dateTime, const QString &format) const
{
- QV4::Scope scope(b);
- if (argc < 1)
- THROW_GENERIC_ERROR("Qt.formatDateTime(): Missing argument");
- if (argc > 3)
- THROW_GENERIC_ERROR("Qt.formatDateTime(): Stray arguments; formatDate takes at most 3 arguments.");
+ return dateTime.toString(format);
+}
- QDateTime dt = scope.engine->toVariant(argv[0], -1).toDateTime();
- return formatDateTimeObject(dt, scope, QLatin1String("Qt.formatDateTime"), argc, argv);
+QString QtObject::formatDateTime(const QDateTime &dateTime, Qt::DateFormat format) const
+{
+ return formatDateTimeObjectUsingDateFormat(dateTime, format);
+}
+
+#if QT_CONFIG(qml_locale)
+QString QtObject::formatDateTime(const QDateTime &dateTime, const QLocale &locale,
+ QLocale::FormatType formatType) const
+{
+ return locale.toString(dateTime, formatType);
}
+#endif
/*!
\qmlmethod bool Qt::openUrlExternally(url target)
@@ -977,15 +805,9 @@ ReturnedValue QtObject::method_formatDateTime(const FunctionObject *b, const Val
still fail to launch or fail to open the requested URL. This result will not be reported back
to the application.
*/
-ReturnedValue QtObject::method_openUrlExternally(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+bool QtObject::openUrlExternally(const QUrl &url) const
{
- QV4::Scope scope(b);
- if (argc != 1)
- return QV4::Encode(false);
-
- ScopedValue result(scope, method_resolvedUrl(b, thisObject, argv, argc));
- QUrl url(result->toQStringNoThrow());
- return scope.engine->fromVariant(QQml_guiProvider()->openUrlExternally(url));
+ return QQml_guiProvider()->openUrlExternally(resolvedUrl(url));
}
/*!
@@ -993,24 +815,13 @@ ReturnedValue QtObject::method_openUrlExternally(const FunctionObject *b, const
Returns \a url resolved relative to the URL of the caller.
*/
-ReturnedValue QtObject::method_resolvedUrl(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QUrl QtObject::resolvedUrl(const QUrl &url) const
{
- QV4::Scope scope(b);
- if (argc != 1)
- return Encode::undefined();
-
- QUrl url = scope.engine->toVariant(argv[0], -1).toUrl();
- QQmlEngine *e = scope.engine->qmlEngine();
- QQmlEnginePrivate *p = nullptr;
- if (e) p = QQmlEnginePrivate::get(e);
- if (p) {
- if (QQmlRefPointer<QQmlContextData> ctxt = scope.engine->callingQmlContext())
- return Encode(scope.engine->newString(ctxt->resolvedUrl(url).toString()));
- else
- return Encode(scope.engine->newString(url.toString()));
- }
-
- return Encode(scope.engine->newString(e->baseUrl().resolved(url).toString()));
+ if (QQmlRefPointer<QQmlContextData> ctxt = v4Engine()->callingQmlContext())
+ return ctxt->resolvedUrl(url);
+ if (QQmlEngine *engine = qmlEngine())
+ return engine->baseUrl().resolved(url);
+ return url;
}
/*!
@@ -1018,58 +829,36 @@ ReturnedValue QtObject::method_resolvedUrl(const FunctionObject *b, const Value
Returns a list of the font families available to the application.
*/
-ReturnedValue QtObject::method_fontFamilies(const FunctionObject *b, const Value *, const Value *, int argc)
+QStringList QtObject::fontFamilies() const
{
- QV4::Scope scope(b);
- if (argc != 0)
- THROW_GENERIC_ERROR("Qt.fontFamilies(): Invalid arguments");
-
- return scope.engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
+ return QQml_guiProvider()->fontFamilies();
}
/*!
\qmlmethod string Qt::md5(data)
Returns a hex string of the md5 hash of \a data.
*/
-ReturnedValue QtObject::method_md5(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QString QtObject::md5(const QString &data) const
{
- QV4::Scope scope(b);
- if (argc != 1)
- THROW_GENERIC_ERROR("Qt.md5(): Invalid arguments");
-
- QByteArray data = argv[0].toQStringNoThrow().toUtf8();
- QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
- return Encode(scope.engine->newString(QLatin1String(result.toHex())));
+ return QLatin1String(QCryptographicHash::hash(data.toUtf8(), QCryptographicHash::Md5).toHex());
}
/*!
\qmlmethod string Qt::btoa(data)
Binary to ASCII - this function returns a base64 encoding of \a data.
*/
-ReturnedValue QtObject::method_btoa(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QString QtObject::btoa(const QString &data) const
{
- QV4::Scope scope(b);
- if (argc != 1)
- THROW_GENERIC_ERROR("Qt.btoa(): Invalid arguments");
-
- QByteArray data = argv[0].toQStringNoThrow().toUtf8();
-
- return Encode(scope.engine->newString(QLatin1String(data.toBase64())));
+ return QLatin1String(data.toUtf8().toBase64());
}
/*!
\qmlmethod string Qt::atob(data)
ASCII to binary - this function decodes the base64 encoded \a data string and returns it.
*/
-ReturnedValue QtObject::method_atob(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QString QtObject::atob(const QString &data) const
{
- QV4::Scope scope(b);
- if (argc != 1)
- THROW_GENERIC_ERROR("Qt.atob(): Invalid arguments");
-
- QByteArray data = argv[0].toQStringNoThrow().toLatin1();
-
- return Encode(scope.engine->newString(QString::fromUtf8(QByteArray::fromBase64(data))));
+ return QString::fromUtf8(QByteArray::fromBase64(data.toLatin1()));
}
/*!
@@ -1081,10 +870,10 @@ QQmlEngine::quit() signal to the QCoreApplication::quit() slot.
\sa exit()
*/
-ReturnedValue QtObject::method_quit(const FunctionObject *b, const Value *, const Value *, int)
+void QtObject::quit() const
{
- QQmlEnginePrivate::get(b->engine()->qmlEngine())->sendQuit();
- return Encode::undefined();
+ if (QQmlEngine *engine = qmlEngine())
+ QQmlEnginePrivate::get(engine)->sendQuit();
}
/*!
@@ -1098,16 +887,10 @@ ReturnedValue QtObject::method_quit(const FunctionObject *b, const Value *, cons
\sa quit()
*/
-ReturnedValue QtObject::method_exit(const FunctionObject *b, const Value *, const Value *argv, int argc)
+void QtObject::exit(int retCode) const
{
- QV4::Scope scope(b);
- if (argc != 1)
- THROW_GENERIC_ERROR("Qt.exit(): Invalid arguments");
-
- int retCode = argv[0].toNumber();
-
- QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendExit(retCode);
- return QV4::Encode::undefined();
+ if (QQmlEngine *engine = qmlEngine())
+ QQmlEnginePrivate::get(engine)->sendExit(retCode);
}
/*!
@@ -1134,11 +917,14 @@ If this is the case, consider using \l{QtQml::Qt::createComponent()}{Qt.createCo
See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function.
*/
-ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QObject *QtObject::createQmlObject(const QString &qml, QObject *parent, const QUrl &url) const
{
- QV4::Scope scope(b);
- if (argc < 2 || argc > 3)
- THROW_GENERIC_ERROR("Qt.createQmlObject(): Invalid arguments");
+ QQmlEngine *engine = qmlEngine();
+ if (!engine) {
+ v4Engine()->throwError(QStringLiteral("Qt.createQmlObject(): "
+ "Can only be called on a QML engine."));
+ return nullptr;
+ }
struct Error {
static ReturnedValue create(QV4::ExecutionEngine *v4, const QList<QQmlError> &errors) {
@@ -1169,14 +955,10 @@ ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Va
}
};
- QQmlEngine *engine = scope.engine->qmlEngine();
+ QQmlRefPointer<QQmlContextData> context = v4Engine()->callingQmlContext();
+ if (!context)
+ context = QQmlContextData::get(QQmlEnginePrivate::get(engine)->rootContext);
- QQmlRefPointer<QQmlContextData> context = scope.engine->callingQmlContext();
- if (!context) {
- QQmlEngine *qmlEngine = scope.engine->qmlEngine();
- if (qmlEngine)
- context = QQmlContextData::get(QQmlEnginePrivate::get(qmlEngine)->rootContext);
- }
Q_ASSERT(context);
QQmlContext *effectiveContext = nullptr;
if (context->isPragmaLibraryContext())
@@ -1185,44 +967,42 @@ ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Va
effectiveContext = context->asQQmlContext();
Q_ASSERT(effectiveContext);
- QString qml = argv[0].toQStringNoThrow();
if (qml.isEmpty())
- RETURN_RESULT(Encode::null());
-
- QUrl url;
- if (argc > 2)
- url = QUrl(argv[2].toQStringNoThrow());
- else
- url = QUrl(QLatin1String("inline"));
+ return nullptr;
+ QUrl resolvedUrl = url;
if (url.isValid() && url.isRelative())
- url = context->resolvedUrl(url);
+ resolvedUrl = context->resolvedUrl(url);
- QObject *parentArg = nullptr;
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, argv[1]);
- if (!!qobjectWrapper)
- parentArg = qobjectWrapper->object();
- if (!parentArg)
- THROW_GENERIC_ERROR("Qt.createQmlObject(): Missing parent object");
+ if (!parent) {
+ v4Engine()->throwError(QStringLiteral("Qt.createQmlObject(): Missing parent object"));
+ return nullptr;
+ }
QQmlRefPointer<QQmlTypeData> typeData = QQmlEnginePrivate::get(engine)->typeLoader.getType(
- qml.toUtf8(), url, QQmlTypeLoader::Synchronous);
+ qml.toUtf8(), resolvedUrl, QQmlTypeLoader::Synchronous);
Q_ASSERT(typeData->isCompleteOrError());
QQmlComponent component(engine);
QQmlComponentPrivate *componentPrivate = QQmlComponentPrivate::get(&component);
componentPrivate->fromTypeData(typeData);
componentPrivate->progress = 1.0;
+ Scope scope(v4Engine());
if (component.isError()) {
ScopedValue v(scope, Error::create(scope.engine, component.errors()));
- RETURN_RESULT(scope.engine->throwError(v));
+ scope.engine->throwError(v);
+ return nullptr;
}
- if (!component.isReady())
- THROW_GENERIC_ERROR("Qt.createQmlObject(): Component is not ready");
+ if (!component.isReady()) {
+ v4Engine()->throwError(QStringLiteral("Qt.createQmlObject(): Component is not ready"));
+ return nullptr;
+ }
if (!effectiveContext->isValid()) {
- THROW_GENERIC_ERROR("Qt.createQmlObject(): Cannot create a component in an invalid context");
+ v4Engine()->throwError(QStringLiteral("Qt.createQmlObject(): Cannot create a component "
+ "in an invalid context"));
+ return nullptr;
}
QObject *obj = component.beginCreate(effectiveContext);
@@ -1230,12 +1010,11 @@ ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Va
QQmlData::get(obj, true)->explicitIndestructibleSet = false;
QQmlData::get(obj)->indestructible = false;
-
- obj->setParent(parentArg);
+ obj->setParent(parent);
QList<QQmlPrivate::AutoParentFunction> functions = QQmlMetaType::parentFunctions();
for (int ii = 0; ii < functions.count(); ++ii) {
- if (QQmlPrivate::Parented == functions.at(ii)(obj, parentArg))
+ if (QQmlPrivate::Parented == functions.at(ii)(obj, parent))
break;
}
}
@@ -1243,12 +1022,12 @@ ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Va
if (component.isError()) {
ScopedValue v(scope, Error::create(scope.engine, component.errors()));
- return scope.engine->throwError(v);
+ scope.engine->throwError(v);
+ return nullptr;
}
Q_ASSERT(obj);
-
- return QV4::QObjectWrapper::wrap(scope.engine, obj);
+ return obj;
}
/*!
@@ -1295,101 +1074,59 @@ See \l {Dynamic QML Object Creation from JavaScript} for more information on usi
To create a QML object from an arbitrary string of QML (instead of a file),
use \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}.
*/
-ReturnedValue QtObject::method_createComponent(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QQmlComponent *QtObject::createComponent(const QUrl &url, QObject *parent) const
{
- QV4::Scope scope(b);
- if (argc < 1 || argc > 3)
- THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
-
- QQmlEngine *engine = scope.engine->qmlEngine();
+ return createComponent(url, QQmlComponent::PreferSynchronous, parent);
+}
- QQmlRefPointer<QQmlContextData> context = scope.engine->callingQmlContext();
- if (!context) {
- QQmlEngine *qmlEngine = scope.engine->qmlEngine();
- if (qmlEngine)
- context = QQmlContextData::get(QQmlEnginePrivate::get(qmlEngine)->rootContext);
+QQmlComponent *QtObject::createComponent(const QUrl &url, QQmlComponent::CompilationMode mode,
+ QObject *parent) const
+{
+ if (mode != QQmlComponent::Asynchronous && mode != QQmlComponent::PreferSynchronous) {
+ v4Engine()->throwError(QStringLiteral("Invalid compilation mode %1").arg(mode));
+ return nullptr;
}
+
+ if (url.isEmpty())
+ return nullptr;
+
+ QQmlEngine *engine = qmlEngine();
+ if (!engine)
+ return nullptr;
+
+ QQmlRefPointer<QQmlContextData> context = v4Engine()->callingQmlContext();
+ if (!context)
+ context = QQmlContextData::get(QQmlEnginePrivate::get(engine)->rootContext);
+
Q_ASSERT(context);
QQmlRefPointer<QQmlContextData> effectiveContext
= context->isPragmaLibraryContext() ? nullptr : context;
- QString arg = argv[0].toQStringNoThrow();
- if (arg.isEmpty())
- RETURN_RESULT(QV4::Encode::null());
-
- QQmlComponent::CompilationMode compileMode = QQmlComponent::PreferSynchronous;
- QObject *parentArg = nullptr;
-
- int consumedCount = 1;
- if (argc > 1) {
- ScopedValue lastArg(scope, argv[argc-1]);
-
- // The second argument could be the mode enum
- if (argv[1].isInteger()) {
- int mode = argv[1].integerValue();
- if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous))
- THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
- compileMode = QQmlComponent::CompilationMode(mode);
- consumedCount += 1;
- } else {
- // The second argument could be the parent only if there are exactly two args
- if ((argc != 2) || !(lastArg->isObject() || lastArg->isNull()))
- THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
- }
-
- if (consumedCount < argc) {
- if (lastArg->isObject()) {
- Scoped<QObjectWrapper> qobjectWrapper(scope, lastArg);
- if (qobjectWrapper)
- parentArg = qobjectWrapper->object();
- if (!parentArg)
- THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object");
- } else if (lastArg->isNull()) {
- parentArg = nullptr;
- } else {
- THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object");
- }
- }
- }
-
- QUrl url = context->resolvedUrl(QUrl(arg));
- QQmlComponent *c = new QQmlComponent(engine, url, compileMode, parentArg);
+ QQmlComponent *c = new QQmlComponent(engine, context->resolvedUrl(url), mode, parent);
QQmlComponentPrivate::get(c)->creationContext = effectiveContext;
QQmlData::get(c, true)->explicitIndestructibleSet = false;
QQmlData::get(c)->indestructible = false;
-
- return QV4::QObjectWrapper::wrap(scope.engine, c);
+ return c;
}
-ReturnedValue QtObject::method_get_uiLanguage(const FunctionObject *b, const Value * /*thisObject*/, const Value * /*argv*/, int /*argc*/)
+QString QtObject::uiLanguage() const
{
- QV4::Scope scope(b);
- QJSEngine *jsEngine = scope.engine->jsEngine();
- if (!jsEngine)
- return Encode::null();
-
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(scope.engine);
- if (ep && ep->propertyCapture) {
- static const QMetaProperty metaProperty
- = QQmlEngine::staticMetaObject.property(
- QQmlEngine::staticMetaObject.indexOfProperty("uiLanguage"));
- QQmlEngine *e = QQmlEnginePrivate::get(ep);
- e->captureProperty(e, metaProperty);
- }
+ if (const QJSEngine *e = jsEngine())
+ return e->uiLanguage();
+ return QString();
+}
- return Encode(scope.engine->newString(QJSEnginePrivate::get(jsEngine)->uiLanguage));
+void QtObject::setUiLanguage(const QString &uiLanguage)
+{
+ if (QJSEngine *e = jsEngine())
+ e->setUiLanguage(uiLanguage);
}
-ReturnedValue QtObject::method_set_uiLanguage(const FunctionObject *b, const Value * /*thisObject*/, const Value *argv, int argc)
+QBindable<QString> QtObject::uiLanguageBindable()
{
- Scope scope(b);
- if (!argc)
- THROW_TYPE_ERROR();
- QJSEngine *jsEngine = scope.engine->jsEngine();
- if (!jsEngine)
- THROW_TYPE_ERROR();
- jsEngine->setUiLanguage(argv[0].toQString());
- return Encode::undefined();
+ if (QJSEngine *e = jsEngine())
+ return QBindable<QString>(&QJSEnginePrivate::get(e)->uiLanguage);
+ return QBindable<QString>();
}
#if QT_CONFIG(qml_locale)
@@ -1413,19 +1150,14 @@ ReturnedValue QtObject::method_set_uiLanguage(const FunctionObject *b, const Val
\sa Locale
*/
-ReturnedValue QtObject::method_locale(const FunctionObject *b, const Value *, const Value *argv, int argc)
+QLocale QtObject::locale() const
{
- QV4::Scope scope(b);
- QString code;
- if (argc > 1)
- THROW_GENERIC_ERROR("locale() requires 0 or 1 argument");
- if (argc == 1 && !argv[0].isString())
- THROW_TYPE_ERROR_WITH_MESSAGE("locale(): argument (locale code) must be a string");
-
- if (argc == 1)
- code = argv[0].toQStringNoThrow();
+ return QLocale();
+}
- return QQmlLocale::locale(scope.engine, code);
+QLocale QtObject::locale(const QString &name) const
+{
+ return QLocale(name);
}
#endif
@@ -1489,67 +1221,52 @@ DEFINE_OBJECT_VTABLE(QQmlBindingFunction);
\since 5.0
*/
-ReturnedValue QtObject::method_binding(const FunctionObject *b, const Value *, const Value *argv, int argc)
-{
- QV4::Scope scope(b);
- if (argc != 1)
- THROW_GENERIC_ERROR("binding() requires 1 argument");
- const QV4::FunctionObject *f = argv[0].as<FunctionObject>();
- if (!f)
- THROW_TYPE_ERROR_WITH_MESSAGE("binding(): argument (binding expression) must be a function");
+QJSValue QtObject::binding(const QJSValue &function) const
+{
+ const QV4::FunctionObject *f = QJSValuePrivate::asManagedType<FunctionObject>(&function);
+ QV4::ExecutionEngine *e = v4Engine();
+ if (!f) {
+ return QJSValuePrivate::fromReturnedValue(
+ e->throwError(
+ QStringLiteral(
+ "binding(): argument (binding expression) must be a function")));
+ }
- return Encode(scope.engine->memoryManager->allocate<QQmlBindingFunction>(f));
+ return QJSValuePrivate::fromReturnedValue(
+ Encode(e->memoryManager->allocate<QQmlBindingFunction>(f)));
}
-ReturnedValue QtObject::method_get_platform(const FunctionObject *b, const Value *thisObject, const Value *, int)
+QQmlPlatform *QtObject::platform()
{
- QV4::Scope scope(b);
- // ### inefficient. Should be just a value based getter
- const Object *o = thisObject->as<Object>();
- if (!o)
- THROW_TYPE_ERROR();
- const QtObject *qt = o->as<QtObject>();
- if (!qt)
- THROW_TYPE_ERROR();
-
- if (!qt->d()->platform)
- // Only allocate a platform object once
- qt->d()->platform = new QQmlPlatform(scope.engine->jsEngine());
-
- return QV4::QObjectWrapper::wrap(scope.engine, qt->d()->platform);
+ if (!m_platform)
+ m_platform = new QQmlPlatform(this);
+ return m_platform;
}
-ReturnedValue QtObject::method_get_application(const FunctionObject *b, const Value *thisObject, const Value *, int)
+QQmlApplication *QtObject::application()
{
- QV4::Scope scope(b);
- // ### inefficient. Should be just a value based getter
- const Object *o = thisObject->as<Object>();
- if (!o)
- THROW_TYPE_ERROR();
- const QtObject *qt = o->as<QtObject>();
- if (!qt)
- THROW_TYPE_ERROR();
-
- if (!qt->d()->application)
+ if (!m_application)
// Only allocate an application object once
- qt->d()->application = QQml_guiProvider()->application(scope.engine->jsEngine());
+ m_application = QQml_guiProvider()->application(this);
- return QV4::QObjectWrapper::wrap(scope.engine, qt->d()->application);
+ return m_application;
}
-ReturnedValue QtObject::method_get_inputMethod(const FunctionObject *b, const Value *, const Value *, int)
+QObject *QtObject::inputMethod() const
{
- QObject *o = QQml_guiProvider()->inputMethod();
- return QV4::QObjectWrapper::wrap(b->engine(), o);
+ return QQml_guiProvider()->inputMethod();
}
-ReturnedValue QtObject::method_get_styleHints(const FunctionObject *b, const Value *, const Value *, int)
+QObject *QtObject::styleHints() const
{
- QObject *o = QQml_guiProvider()->styleHints();
- return QV4::QObjectWrapper::wrap(b->engine(), o);
+ return QQml_guiProvider()->styleHints();
}
+QJSValue QtObject::callLater() const
+{
+ return m_callLater;
+}
void QV4::Heap::ConsoleObject::init()
{
@@ -1873,8 +1590,6 @@ ReturnedValue ConsoleObject::method_exception(const FunctionObject *b, const Val
return writeToConsole(b, argv, argc, Error, true);
}
-
-
void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions extensions)
{
ExecutionEngine *v4 = globalObject->engine();
@@ -1889,13 +1604,11 @@ void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions ext
globalObject->defineDefaultProperty(QStringLiteral("qsTrId"), QV4::GlobalExtensions::method_qsTrId);
globalObject->defineDefaultProperty(QStringLiteral("QT_TRID_NOOP"), QV4::GlobalExtensions::method_qsTrIdNoOp);
+ // Initialize the Qt global object for the uiLanguage property
ScopedString qtName(scope, v4->newString(QStringLiteral("Qt")));
ScopedObject qt(scope, globalObject->get(qtName));
- if (!qt) {
- qt = v4->newObject();
- globalObject->defineDefaultProperty(qtName, qt);
- }
- qt->defineAccessorProperty(QStringLiteral("uiLanguage"), QV4::QtObject::method_get_uiLanguage, QV4::QtObject::method_set_uiLanguage);
+ if (!qt)
+ v4->createQtObject();
// string prototype extension
scope.engine->stringPrototype()->defineDefaultProperty(QStringLiteral("arg"), QV4::GlobalExtensions::method_string_arg);
@@ -2236,7 +1949,8 @@ be passed on to the function invoked. Note that if redundant calls
are eliminated, then only the last set of arguments will be passed to the
function.
*/
-ReturnedValue QtObject::method_callLater(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+ReturnedValue QtObject::method_callLater(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc)
{
return b->engine()->delayedCallQueue()->addUniquelyAndExecuteLater(b, thisObject, argv, argc);
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index 65c68503e3..4ab982d579 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -54,29 +54,21 @@
#include <private/qqmlglobal_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qjsengine_p.h>
+#include <private/qqmlplatform_p.h>
#include <QtCore/qnamespace.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qpoint.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qqmlengine.h>
QT_BEGIN_NAMESPACE
-class QQmlEngine;
-
namespace QV4 {
namespace Heap {
-struct QtObject : Object {
- void init(QQmlEngine *qmlEngine);
- QObject *platform;
- QObject *application;
-
- enum { Finished = -1 };
- int enumeratorIterator;
- int keyIterator;
-
- bool isComplete() const
- { return enumeratorIterator == Finished; }
-};
-
struct ConsoleObject : Object {
void init();
};
@@ -90,73 +82,139 @@ DECLARE_HEAP_OBJECT(QQmlBindingFunction, FunctionObject) {
}
-namespace QtInQml {
-Q_NAMESPACE
-QML_FOREIGN_NAMESPACE(Qt)
-QML_NAMED_ELEMENT(Qt)
-QML_ADDED_IN_VERSION(2, 0)
-Q_CLASSINFO("QML.ManualRegistration", "true")
-// should add the functions defined below...
-}
-
-struct QtObject : Object
+class Q_QML_EXPORT QtObject : public QObject
{
- V4_OBJECT2(QtObject, Object)
-
- static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
- static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
-
- static ReturnedValue method_isQtObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_color(const FunctionObject *b, const Value *thisObject,
- const Value *argv, int argc);
- static ReturnedValue method_rgba(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_hsla(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_hsva(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_colorEqual(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_font(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_rect(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_point(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_size(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_vector2d(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_vector3d(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_vector4d(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_quaternion(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_matrix4x4(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_lighter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_darker(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_alpha(const FunctionObject *b, const Value *thisObject,
- const Value *argv, int argc);
- static ReturnedValue method_tint(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_formatDate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_formatTime(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_formatDateTime(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_openUrlExternally(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_fontFamilies(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_md5(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_btoa(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_atob(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_quit(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_exit(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_resolvedUrl(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_createQmlObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_createComponent(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_get_uiLanguage(const FunctionObject *b, const Value *, const Value *, int);
- static ReturnedValue method_set_uiLanguage(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ Q_OBJECT
+ Q_PROPERTY(QQmlApplication *application READ application CONSTANT)
+ Q_PROPERTY(QQmlPlatform *platform READ platform CONSTANT)
+ Q_PROPERTY(QObject *inputMethod READ inputMethod CONSTANT)
+ Q_PROPERTY(QObject *styleHints READ styleHints CONSTANT)
+ Q_PROPERTY(QJSValue callLater READ callLater CONSTANT)
+
+#if QT_CONFIG(translation)
+ Q_PROPERTY(QString uiLanguage READ uiLanguage WRITE setUiLanguage BINDABLE uiLanguageBindable)
+#endif
+
+ QML_NAMED_ELEMENT(Qt)
+ QML_SINGLETON
+ QML_EXTENDED_NAMESPACE(QT_PREPEND_NAMESPACE(Qt))
+ QML_ADDED_IN_VERSION(2, 0)
+
+ Q_CLASSINFO("QML.StrictArguments", "true")
+
+public:
+ enum LoadingMode { Asynchronous = 0, Synchronous = 1 };
+ Q_ENUM(LoadingMode);
+
+ static QtObject *create(QQmlEngine *, QJSEngine *jsEngine);
+
+ Q_INVOKABLE QJSValue include(const QString &url, const QJSValue &callback = QJSValue()) const;
+ Q_INVOKABLE bool isQtObject(const QJSValue &value) const;
+
+ Q_INVOKABLE QVariant color(const QString &name) const;
+ Q_INVOKABLE QVariant rgba(double r, double g, double b, double a = 1) const;
+ Q_INVOKABLE QVariant hsla(double h, double s, double l, double a = 1) const;
+ Q_INVOKABLE QVariant hsva(double h, double s, double v, double a = 1) const;
+ Q_INVOKABLE bool colorEqual(const QVariant &lhs, const QVariant &rhs) const;
+
+ Q_INVOKABLE QRectF rect(double x, double y, double width, double height) const;
+ Q_INVOKABLE QPointF point(double x, double y) const;
+ Q_INVOKABLE QSizeF size(double width, double height) const;
+ Q_INVOKABLE QVariant vector2d(double x, double y) const;
+ Q_INVOKABLE QVariant vector3d(double x, double y, double z) const;
+ Q_INVOKABLE QVariant vector4d(double x, double y, double z, double w) const;
+ Q_INVOKABLE QVariant quaternion(double scalar, double x, double y, double z) const;
+
+ Q_INVOKABLE QVariant matrix4x4() const;
+ Q_INVOKABLE QVariant matrix4x4(double m11, double m12, double m13, double m14,
+ double m21, double m22, double m23, double m24,
+ double m31, double m32, double m33, double m34,
+ double m41, double m42, double m43, double m44) const;
+ Q_INVOKABLE QVariant matrix4x4(const QJSValue &value) const;
+
+ Q_INVOKABLE QVariant lighter(const QJSValue &color, double factor = 1.5) const;
+ Q_INVOKABLE QVariant darker(const QJSValue &color, double factor = 2.0) const;
+ Q_INVOKABLE QVariant alpha(const QJSValue &baseColor, double value) const;
+ Q_INVOKABLE QVariant tint(const QJSValue &baseColor, const QJSValue &tintColor) const;
+
+ Q_INVOKABLE QString formatDate(const QDate &date, const QString &format) const;
+ Q_INVOKABLE QString formatDate(const QDate &date, Qt::DateFormat format) const;
+
+ Q_INVOKABLE QString formatTime(const QTime &time, const QString &format) const;
+ Q_INVOKABLE QString formatTime(const QString &time, const QString &format) const;
+ Q_INVOKABLE QString formatTime(const QTime &time, Qt::DateFormat format) const;
+ Q_INVOKABLE QString formatTime(const QString &time, Qt::DateFormat format) const;
+
+ Q_INVOKABLE QString formatDateTime(const QDateTime &date, const QString &format) const;
+ Q_INVOKABLE QString formatDateTime(const QDateTime &date, Qt::DateFormat format) const;
+
#if QT_CONFIG(qml_locale)
- static ReturnedValue method_locale(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ Q_INVOKABLE QString formatDate(const QDate &date, const QLocale &locale = QLocale(),
+ QLocale::FormatType formatType = QLocale::ShortFormat) const;
+ Q_INVOKABLE QString formatTime(const QTime &time, const QLocale &locale = QLocale(),
+ QLocale::FormatType formatType = QLocale::ShortFormat) const;
+ Q_INVOKABLE QString formatTime(const QString &time, const QLocale &locale = QLocale(),
+ QLocale::FormatType formatType = QLocale::ShortFormat) const;
+ Q_INVOKABLE QString formatDateTime(const QDateTime &date, const QLocale &locale = QLocale(),
+ QLocale::FormatType formatType = QLocale::ShortFormat) const;
+ Q_INVOKABLE QLocale locale() const;
+ Q_INVOKABLE QLocale locale(const QString &name) const;
+#endif
+
+ Q_INVOKABLE QUrl resolvedUrl(const QUrl &url) const;
+ Q_INVOKABLE bool openUrlExternally(const QUrl &url) const;
+
+ Q_INVOKABLE QVariant font(const QJSValue &fontSpecifier) const;
+ Q_INVOKABLE QStringList fontFamilies() const;
+
+ Q_INVOKABLE QString md5(const QString &data) const;
+ Q_INVOKABLE QString btoa(const QString &data) const;
+ Q_INVOKABLE QString atob(const QString &data) const;
+
+ Q_INVOKABLE void quit() const;
+ Q_INVOKABLE void exit(int retCode) const;
+
+ Q_INVOKABLE QObject *createQmlObject(const QString &qml, QObject *parent,
+ const QUrl &url = QUrl(QStringLiteral("inline"))) const;
+ Q_INVOKABLE QQmlComponent *createComponent(const QUrl &url, QObject *parent) const;
+ Q_INVOKABLE QQmlComponent *createComponent(
+ const QUrl &url, QQmlComponent::CompilationMode mode = QQmlComponent::PreferSynchronous,
+ QObject *parent = nullptr) const;
+
+ Q_INVOKABLE QJSValue binding(const QJSValue &function) const;
+
+ // We can't make this invokable as it uses actual varargs
+ static ReturnedValue method_callLater(const FunctionObject *b, const Value *thisObject,
+ const Value *argv, int argc);
+
+#if QT_CONFIG(translation)
+ QString uiLanguage() const;
+ void setUiLanguage(const QString &uiLanguage);
+ QBindable<QString> uiLanguageBindable();
#endif
- static ReturnedValue method_binding(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_get_platform(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_get_application(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_get_inputMethod(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue method_get_styleHints(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ // Not const because created on first use, and parented to this.
+ QQmlPlatform *platform();
+ QQmlApplication *application();
- static ReturnedValue method_callLater(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ QObject *inputMethod() const;
+ QObject *styleHints() const;
+ QJSValue callLater() const;
private:
- void addAll();
- ReturnedValue findAndAdd(const QString *name, bool &foundProperty) const;
+ friend struct ExecutionEngine;
+
+ QtObject(QV4::ExecutionEngine *engine);
+
+ QQmlEngine *qmlEngine() const { return m_engine->qmlEngine(); }
+ QJSEngine *jsEngine() const { return m_engine->jsEngine(); }
+ QV4::ExecutionEngine *v4Engine() const { return m_engine; }
+
+ QQmlPlatform *m_platform = nullptr;
+ QQmlApplication *m_application = nullptr;
+
+ QV4::ExecutionEngine *m_engine = nullptr;
+ QJSValue m_callLater;
};
struct ConsoleObject : Object
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 0639533bac..afee2c3878 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -314,7 +314,7 @@ public:
return QFontDatabase::families();
}
- bool openUrlExternally(QUrl &url) override
+ bool openUrlExternally(const QUrl &url) override
{
#ifndef QT_NO_DESKTOPSERVICES
return QDesktopServices::openUrl(url);
diff --git a/tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml b/tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml
index b323b49662..33b94d753c 100644
--- a/tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml
+++ b/tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml
@@ -1,3 +1,4 @@
+import QtQml
import Qt.test 1.0
MyQmlObject {
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 985b8c7a98..03fc8e5ad4 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -1782,15 +1782,15 @@ void tst_qqmlecmascript::componentCreation_data()
<< "null";
QTest::newRow("invalidSecondArg")
<< "invalidSecondArg"
- << ":40: Error: Qt.createComponent(): Invalid arguments"
+ << "" // We cannot catch this case as coercing a string to a number is valid in JavaScript
<< "";
QTest::newRow("invalidThirdArg")
<< "invalidThirdArg"
- << ":45: Error: Qt.createComponent(): Invalid parent object"
+ << ":45: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
<< "";
QTest::newRow("invalidMode")
<< "invalidMode"
- << ":50: Error: Qt.createComponent(): Invalid arguments"
+ << ":50: Error: Invalid compilation mode -666"
<< "";
}
@@ -3448,6 +3448,9 @@ void tst_qqmlecmascript::scriptConnect()
QVERIFY(object != nullptr);
QCOMPARE(object->methodCalled(), false);
+
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("When matching arguments for MyQmlObject_QML_[0-9]+::methodNoArgs\\(\\):"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Too many arguments, ignoring 5"));
emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->methodCalled(), true);
@@ -3461,6 +3464,8 @@ void tst_qqmlecmascript::scriptConnect()
QVERIFY(object != nullptr);
QCOMPARE(object->methodCalled(), false);
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("When matching arguments for MyQmlObject_QML_[0-9]+::methodNoArgs\\(\\):"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Too many arguments, ignoring 5"));
emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->methodCalled(), true);
@@ -6365,7 +6370,7 @@ void tst_qqmlecmascript::include()
// Non-library relative include
{
QQmlComponent component(&engine, testFileUrl("include.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test0").toInt(), 99);
@@ -6375,13 +6380,12 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test3").toBool(), true);
QCOMPARE(o->property("test3_1").toBool(), true);
- delete o;
}
// Library relative include
{
QQmlComponent component(&engine, testFileUrl("include_shared.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test0").toInt(), 99);
@@ -6391,13 +6395,12 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test3").toBool(), true);
QCOMPARE(o->property("test3_1").toBool(), true);
- delete o;
}
// Callback
{
QQmlComponent component(&engine, testFileUrl("include_callback.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test1").toBool(), true);
@@ -6407,17 +6410,15 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test5").toBool(), true);
QCOMPARE(o->property("test6").toBool(), true);
- delete o;
}
// Including file with ".pragma library"
{
QQmlComponent component(&engine, testFileUrl("include_pragma.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test1").toInt(), 100);
- delete o;
}
// Including file with ".pragma library", shadowing a global var
@@ -6435,7 +6436,7 @@ void tst_qqmlecmascript::include()
server.serveDirectory(dataDirectory());
QQmlComponent component(&engine, testFileUrl("include_remote_missing.qml"));
- QObject *o = component.beginCreate(engine.rootContext());
+ QScopedPointer<QObject> o(component.beginCreate(engine.rootContext()));
QVERIFY(o != nullptr);
o->setProperty("serverBaseUrl", server.baseUrl().toString());
component.completeCreate();
@@ -6446,13 +6447,12 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test2").toBool(), true);
QCOMPARE(o->property("test3").toBool(), true);
- delete o;
}
// include from resources
{
QQmlComponent component(&engine, QUrl("qrc:///data/include.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test0").toInt(), 99);
@@ -6462,7 +6462,6 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test3").toBool(), true);
QCOMPARE(o->property("test3_1").toBool(), true);
- delete o;
}
}
@@ -7495,14 +7494,13 @@ void tst_qqmlecmascript::registeredFlagMethod()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("registeredFlagMethod.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<QObject> o(component.create());
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(o.data());
QVERIFY(object != nullptr);
QCOMPARE(object->buttons(), 0);
emit object->basicSignal();
QCOMPARE(object->buttons(), Qt::RightButton);
-
- delete object;
}
// QTBUG-23138
diff --git a/tests/auto/qml/qqmlqt/data/qtObjectContents.qml b/tests/auto/qml/qqmlqt/data/qtObjectContents.qml
deleted file mode 100644
index c85e7986e9..0000000000
--- a/tests/auto/qml/qqmlqt/data/qtObjectContents.qml
+++ /dev/null
@@ -1,10 +0,0 @@
-import QtQuick 2.0
-
-QtObject {
- property var values: Object()
- Component.onCompleted: {
- for (var key in Qt) {
- values[key] = Qt[key]
- }
- }
-}
diff --git a/tests/auto/qml/qqmlqt/data/resolvedUrl.qml b/tests/auto/qml/qqmlqt/data/resolvedUrl.qml
index 06ef48b82b..aa57c73627 100644
--- a/tests/auto/qml/qqmlqt/data/resolvedUrl.qml
+++ b/tests/auto/qml/qqmlqt/data/resolvedUrl.qml
@@ -3,11 +3,13 @@ import QtQuick 2.0
QtObject {
property string result
property bool isString: false
+ property bool isObject: false
Component.onCompleted: {
var a = Qt.resolvedUrl("resolvedUrl.qml");
result = a;
isString = (typeof a) == "string"
+ isObject = (typeof a) == "object"
}
}
diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
index a6d8a52e0e..9406ba5d6a 100644
--- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
+++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
@@ -180,9 +180,9 @@ void tst_qqmlqt::rgba()
{
QQmlComponent component(&engine, testFileUrl("rgba.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.rgba(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.rgba(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "rgba.qml:6: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -201,9 +201,9 @@ void tst_qqmlqt::hsla()
{
QQmlComponent component(&engine, testFileUrl("hsla.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.hsla(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.hsla(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "hsla.qml:6: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -221,9 +221,9 @@ void tst_qqmlqt::hsva()
{
QQmlComponent component(&engine, testFileUrl("hsva.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.hsva(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.hsva(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "hsva.qml:6: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -241,8 +241,8 @@ void tst_qqmlqt::colorEqual()
{
QQmlComponent component(&engine, testFileUrl("colorEqual.qml"));
- QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":6: Error: Qt.colorEqual(): Invalid arguments"));
- QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":7: Error: Qt.colorEqual(): Invalid arguments"));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":6: Error: Insufficient arguments"));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":7: Error: Insufficient arguments"));
QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":9: Error: Qt.colorEqual(): Invalid color name"));
QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":10: Error: Qt.colorEqual(): Invalid color name"));
QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":12: Error: Qt.colorEqual(): Invalid arguments"));
@@ -322,8 +322,8 @@ void tst_qqmlqt::rect()
{
QQmlComponent component(&engine, testFileUrl("rect.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.rect(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.rect(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -341,8 +341,8 @@ void tst_qqmlqt::point()
{
QQmlComponent component(&engine, testFileUrl("point.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.point(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.point(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -359,8 +359,8 @@ void tst_qqmlqt::size()
{
QQmlComponent component(&engine, testFileUrl("size.qml"));
- QString warning1 = component.url().toString() + ":7: Error: Qt.size(): Invalid arguments";
- QString warning2 = component.url().toString() + ":8: Error: Qt.size(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":7: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":8: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -378,8 +378,8 @@ void tst_qqmlqt::vector2d()
{
QQmlComponent component(&engine, testFileUrl("vector2.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.vector2d(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.vector2d(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -396,8 +396,8 @@ void tst_qqmlqt::vector3d()
{
QQmlComponent component(&engine, testFileUrl("vector.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.vector3d(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.vector3d(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -414,8 +414,8 @@ void tst_qqmlqt::vector4d()
{
QQmlComponent component(&engine, testFileUrl("vector4.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.vector4d(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.vector4d(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -432,8 +432,8 @@ void tst_qqmlqt::quaternion()
{
QQmlComponent component(&engine, testFileUrl("quaternion.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.quaternion(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.quaternion(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -450,7 +450,7 @@ void tst_qqmlqt::matrix4x4()
{
QQmlComponent component(&engine, testFileUrl("matrix4x4.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.matrix4x4(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Too many arguments";
QString warning2 = component.url().toString() + ":7: Error: Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array";
QString warning3 = component.url().toString() + ":8: Error: Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
@@ -471,7 +471,7 @@ void tst_qqmlqt::font()
{
QQmlComponent component(&engine, testFileUrl("font.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.font(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Too many arguments";
QString warning2 = component.url().toString() + ":7: Error: Qt.font(): Invalid argument: no valid font subproperties specified";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -495,9 +495,9 @@ void tst_qqmlqt::lighter()
{
QQmlComponent component(&engine, testFileUrl("lighter.qml"));
- QString warning1 = component.url().toString() + ":5: Error: Qt.lighter(): Invalid arguments";
- QString warning2 = component.url().toString() + ":10: Error: Qt.lighter(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "lighter.qml:5: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":10: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -520,9 +520,9 @@ void tst_qqmlqt::darker()
{
QQmlComponent component(&engine, testFileUrl("darker.qml"));
- QString warning1 = component.url().toString() + ":5: Error: Qt.darker(): Invalid arguments";
- QString warning2 = component.url().toString() + ":10: Error: Qt.darker(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "darker.qml:5: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":10: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -545,8 +545,8 @@ void tst_qqmlqt::alpha()
{
QQmlComponent component(&engine, testFileUrl("alpha.qml"));
- QString warning1 = component.url().toString() + ":5: Error: Qt.alpha(): Wrong number of arguments provided";
- QString warning2 = component.url().toString() + ":10: Error: Qt.alpha(): Wrong number of arguments provided";
+ QString warning1 = component.url().toString() + ":5: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":10: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -576,8 +576,8 @@ void tst_qqmlqt::tint()
{
QQmlComponent component(&engine, testFileUrl("tint.qml"));
- QString warning1 = component.url().toString() + ":7: Error: Qt.tint(): Invalid arguments";
- QString warning2 = component.url().toString() + ":8: Error: Qt.tint(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":7: Error: Too many arguments";
+ QString warning2 = component.url().toString() + ":8: Error: Insufficient arguments";
QString warning3 = component.url().toString() + ":13: Error: Insufficient arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
@@ -604,9 +604,10 @@ void tst_qqmlqt::color()
{
QQmlComponent component(&engine, testFileUrl("color.qml"));
- QStringList warnings = { ":7: Error: Qt.color(): Argument must be a string",
- ":8: Error: Qt.color(): Qt.color takes exactly one argument",
- ":9: Error: Qt.color(): Qt.color takes exactly one argument" };
+ QStringList warnings = { ":6: Error: \"taint\" is not a valid color name",
+ ":7: Error: \"0.5\" is not a valid color name",
+ ":8: Error: Insufficient arguments",
+ ":9: Error: Too many arguments" };
for (const QString &warning : warnings)
QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + warning));
@@ -682,7 +683,7 @@ void tst_qqmlqt::md5()
{
QQmlComponent component(&engine, testFileUrl("md5.qml"));
- QString warning1 = component.url().toString() + ":4: Error: Qt.md5(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":4: Error: Insufficient arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QScopedPointer<QObject> object(component.create());
@@ -696,9 +697,9 @@ void tst_qqmlqt::createComponent()
{
QQmlComponent component(&engine, testFileUrl("createComponent.qml"));
- QString warning1 = component.url().toString() + ":9: Error: Qt.createComponent(): Invalid arguments";
- QString warning2 = component.url().toString() + ":10: Error: Qt.createComponent(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "createComponent.qml:9: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":10: Error: Invalid compilation mode 10";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -733,18 +734,22 @@ void tst_qqmlqt::createQmlObject()
{
QQmlComponent component(&engine, testFileUrl("createQmlObject.qml"));
- QString warning1 = component.url().toString() + ":7: Error: Qt.createQmlObject(): Invalid arguments";
+ QString warning1 = "createQmlObject.qml:7: Error: Unable to determine callable overload";
QString warning2 = component.url().toString()+ ":10: Error: Qt.createQmlObject(): failed to create object: \n " + testFileUrl("inline").toString() + ":2:10: Blah is not a type";
QString warning3 = component.url().toString()+ ":11: Error: Qt.createQmlObject(): failed to create object: \n " + testFileUrl("main.qml").toString() + ":4:14: Duplicate property name";
- QString warning4 = component.url().toString()+ ":9: Error: Qt.createQmlObject(): Missing parent object";
- QString warning5 = component.url().toString()+ ":8: Error: Qt.createQmlObject(): Invalid arguments";
+ QString warning4 = component.url().toString()+ ":9: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed.";
+ QString warning5 = component.url().toString()+ ":8: Error: Too many arguments";
QString warning6 = "RunTimeError: Qt.createQmlObject(): failed to create object: \n " + testFileUrl("inline").toString() + ":3:16: Cannot assign object type QObject with no default method";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning7 = "Could not convert argument 1 at";
+ QString warning8 = "expression for noParent@";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning4));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning5));
QTest::ignoreMessage(QtDebugMsg, qPrintable(warning6));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning7));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning8));
QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
@@ -808,28 +813,41 @@ void tst_qqmlqt::dateTimeFormatting()
QQmlComponent component(&eng, testFileUrl("formatting.qml"));
QStringList warnings;
- warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":36: Error: Qt.formatDate(): Missing argument"
- << component.url().toString() + ":40: Error: Qt.formatTime(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":39: Error: Qt.formatTime(): Missing argument"
- << component.url().toString() + ":43: Error: Qt.formatDateTime(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":42: Error: Qt.formatDateTime(): Missing argument";
+ warnings
+ << component.url().toString() + ":37: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
+ << component.url().toString() + ":40: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
+ << component.url().toString() + ":43: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed.";
foreach (const QString &warning, warnings)
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- QObject *object = component.createWithInitialProperties({
+ warnings.clear();
+ warnings
+ << "formatting.qml:36: Error: Unable to determine callable overload"
+ << "formatting.qml:39: Error: Unable to determine callable overload"
+ << "formatting.qml:42: Error: Unable to determine callable overload"
+ << "Could not convert argument 1 at"
+ << "expression for err_date2@"
+ << "Could not convert argument 1 at"
+ << "expression for err_time2@"
+ << "Could not convert argument 1 at"
+ << "expression for err_dateTime2@";
+
+ foreach (const QString &warning, warnings)
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning));
+
+ QScopedPointer<QObject> object(component.createWithInitialProperties({
{"qdate", date},
{"qtime", time},
{"qdatetime", dateTime}
- });
+ }));
QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
QVERIFY(object != nullptr);
QVERIFY(inputProperties.count() > 0);
QVariant result;
foreach(const QString &prop, inputProperties) {
- QVERIFY(QMetaObject::invokeMethod(object, method.toUtf8().constData(),
+ QVERIFY(QMetaObject::invokeMethod(object.data(), method.toUtf8().constData(),
Q_RETURN_ARG(QVariant, result),
Q_ARG(QVariant, prop)));
QStringList output = result.toStringList();
@@ -837,8 +855,6 @@ void tst_qqmlqt::dateTimeFormatting()
for (int i=0; i<output.count(); i++)
QCOMPARE(output[i], expectedResults[i]);
}
-
- delete object;
}
void tst_qqmlqt::dateTimeFormatting_data()
@@ -884,28 +900,63 @@ void tst_qqmlqt::dateTimeFormattingVariants()
QQmlComponent component(&eng, testFileUrl("formatting.qml"));
QStringList warnings;
- warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":36: Error: Qt.formatDate(): Missing argument"
- << component.url().toString() + ":40: Error: Qt.formatTime(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":39: Error: Qt.formatTime(): Missing argument"
- << component.url().toString() + ":43: Error: Qt.formatDateTime(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":42: Error: Qt.formatDateTime(): Missing argument";
+ warnings << component.url().toString() + ":37: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
+ << component.url().toString() + ":40: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
+ << component.url().toString() + ":43: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed.";
- foreach (const QString &warning, warnings)
+ for (const QString &warning : qAsConst(warnings))
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- QObject *object = component.createWithInitialProperties({{"qvariant", variant}});
+ warnings.clear();
+ warnings << "formatting.qml:36: Error: Unable to determine callable overload."
+ << "formatting.qml:39: Error: Unable to determine callable overload."
+ << "formatting.qml:42: Error: Unable to determine callable overload."
+ << "Could not convert argument 1 at"
+ << "expression for err_date2@"
+ << "Could not convert argument 1 at"
+ << "expression for err_time2@"
+ << "Could not convert argument 1 at"
+ << "expression for err_dateTime2@";
+
+ for (const QString &warning : qAsConst(warnings))
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning));
+
+ warnings.clear();
+ if (method == QStringLiteral("formatTime") && variant.typeId() == QMetaType::QString) {
+ for (int i = 0; i < 4; ++i) {
+ QTest::ignoreMessage(QtWarningMsg,
+ "\"2011/05/31 11:16:39.755\" is a "
+ "date/time string being passed to formatTime(). You should only "
+ "pass time strings to formatTime().");
+ }
+ }
+
+ if (variant.typeId() == QMetaType::QColor || variant.typeId() == QMetaType::Int) {
+ if (method == "formatTime") {
+ // formatTime has special error handling as it parses the strings itself.
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(
+ "formatting.qml:18: Error: Invalid argument passed to "
+ "formatTime"));
+ } else {
+ QTest::ignoreMessage(QtWarningMsg,
+ QRegularExpression("Could not convert argument 0 at"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(method + "@"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(
+ "TypeError: Passing incompatible arguments to "
+ "C.. functions from JavaScript is not allowed."));
+ }
+ }
+
+ QScopedPointer<QObject> object(component.createWithInitialProperties({{"qvariant", variant}}));
QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
QVERIFY(object != nullptr);
QVariant result;
- QVERIFY(QMetaObject::invokeMethod(object, method.toUtf8().constData(),
+ QVERIFY(QMetaObject::invokeMethod(object.data(), method.toUtf8().constData(),
Q_RETURN_ARG(QVariant, result),
Q_ARG(QVariant, QString(QLatin1String("qvariant")))));
QStringList output = result.toStringList();
QCOMPARE(output, expectedResults);
-
- delete object;
}
void tst_qqmlqt::dateTimeFormattingVariants_data()
@@ -997,45 +1048,25 @@ void tst_qqmlqt::dateTimeFormattingVariants_data()
temporary = QVariant::fromValue(color).toDateTime();
QTest::newRow("formatDate, qcolor")
<< "formatDate" << QVariant::fromValue(color)
- << (QStringList()
- << QLocale().toString(temporary.date(), QLocale::ShortFormat)
- << QLocale().toString(temporary.date(), QLocale::LongFormat)
- << temporary.date().toString("ddd MMMM d yy"));
+ << QStringList();
QTest::newRow("formatDateTime, qcolor")
<< "formatDateTime" << QVariant::fromValue(color)
- << (QStringList()
- << QLocale().toString(temporary, QLocale::ShortFormat)
- << QLocale().toString(temporary, QLocale::LongFormat)
- << temporary.toString("M/d/yy H:m:s a"));
+ << QStringList();
QTest::newRow("formatTime, qcolor")
<< "formatTime" << QVariant::fromValue(color)
- << (QStringList()
- << QLocale().toString(temporary.time(), QLocale::ShortFormat)
- << QLocale().toString(temporary.time(), QLocale::LongFormat)
- << temporary.time().toString("H:m:s a")
- << temporary.time().toString("hh:mm:ss.zzz"));
+ << QStringList();
int integer(4);
temporary = QVariant::fromValue(integer).toDateTime();
QTest::newRow("formatDate, int")
<< "formatDate" << QVariant::fromValue(integer)
- << (QStringList()
- << QLocale().toString(temporary.date(), QLocale::ShortFormat)
- << QLocale().toString(temporary.date(), QLocale::LongFormat)
- << temporary.date().toString("ddd MMMM d yy"));
+ << QStringList();
QTest::newRow("formatDateTime, int")
<< "formatDateTime" << QVariant::fromValue(integer)
- << (QStringList()
- << QLocale().toString(temporary, QLocale::ShortFormat)
- << QLocale().toString(temporary, QLocale::LongFormat)
- << temporary.toString("M/d/yy H:m:s a"));
+ << QStringList();
QTest::newRow("formatTime, int")
<< "formatTime" << QVariant::fromValue(integer)
- << (QStringList()
- << QLocale().toString(temporary.time(), QLocale::ShortFormat)
- << QLocale().toString(temporary.time(), QLocale::LongFormat)
- << temporary.time().toString("H:m:s a")
- << temporary.time().toString("hh:mm:ss.zzz"));
+ << QStringList();
}
void tst_qqmlqt::dateTimeFormattingWithLocale()
@@ -1054,8 +1085,13 @@ void tst_qqmlqt::dateTimeFormattingWithLocale()
auto dateString = o->property("dateString").toString();
QCOMPARE(dateString, QLocale("de_DE").toString(date, QLocale::ShortFormat));
- QString warningMsg = url.toString() + QLatin1String(":11: Error: Qt.formatTime(): Third argument must be a Locale format option");
- QTest::ignoreMessage(QtMsgType::QtWarningMsg, warningMsg.toUtf8().constData());
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Could not convert argument 1 at"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("invalidUsage@"));
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ qPrintable(url.toString() + QStringLiteral(":11: TypeError: Passing incompatible "
+ "arguments to C++ functions from "
+ "JavaScript is not allowed.")));
QMetaObject::invokeMethod(o.get(), "invalidUsage");
}
@@ -1076,7 +1112,7 @@ void tst_qqmlqt::btoa()
{
QQmlComponent component(&engine, testFileUrl("btoa.qml"));
- QString warning1 = component.url().toString() + ":4: Error: Qt.btoa(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":4: Error: Insufficient arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QScopedPointer<QObject> object(component.create());
@@ -1089,7 +1125,7 @@ void tst_qqmlqt::atob()
{
QQmlComponent component(&engine, testFileUrl("atob.qml"));
- QString warning1 = component.url().toString() + ":4: Error: Qt.atob(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":4: Error: Insufficient arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QScopedPointer<QObject> object(component.create());
@@ -1102,7 +1138,7 @@ void tst_qqmlqt::fontFamilies()
{
QQmlComponent component(&engine, testFileUrl("fontFamilies.qml"));
- QString warning1 = component.url().toString() + ":4: Error: Qt.fontFamilies(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":4: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QScopedPointer<QObject> object(component.create());
@@ -1141,7 +1177,8 @@ void tst_qqmlqt::resolvedUrl()
QVERIFY(object != nullptr);
QCOMPARE(object->property("result").toString(), component.url().toString());
- QCOMPARE(object->property("isString").toBool(), true);
+ QCOMPARE(object->property("isString").toBool(), false);
+ QCOMPARE(object->property("isObject").toBool(), true);
}
void tst_qqmlqt::later_data()
@@ -1245,39 +1282,56 @@ void tst_qqmlqt::later()
void tst_qqmlqt::qtObjectContents()
{
- QQmlComponent component(&engine, testFileUrl("qtObjectContents.qml"));
+ QByteArray qml =
+ "import QtQml\n"
+ "QtObject {\n"
+ " property int vLoadingModeAsynchronous: Qt.Asynchronous\n"
+ " property int vLoadingModeSynchronous: Qt.Synchronous\n";
- QScopedPointer<QObject> object(component.create());
- QVERIFY(object != nullptr);
+ const QMetaObject *qtMetaObject = &Qt::staticMetaObject;
+ for (int ii = 0; ii < qtMetaObject->enumeratorCount(); ++ii) {
+ const QMetaEnum enumerator = qtMetaObject->enumerator(ii);
+ for (int jj = 0; jj < enumerator.keyCount(); ++jj) {
+ const QByteArray key = enumerator.key(jj);
+ QVERIFY(!key.isEmpty());
- QVERIFY(object->property("values").canConvert<QJSValue>());
- QVariantMap values = object->property("values").value<QJSValue>().toVariant().toMap();
+ // We don't want to check for Qt.green and things like that.
+ // They're nonsensical
+ if (QChar::fromLatin1(key.front()).isLower())
+ continue;
- QSet<const char *> keys;
- int uniqueKeys = 0;
- const QMetaObject *qtMetaObject = &Qt::staticMetaObject;
+ qml += QByteArray(" property int v") + enumerator.name() + key
+ + QByteArray(": Qt.") + key + '\n';
+ }
+ }
+
+ qml += "}\n";
+
+ QQmlComponent component(&engine);
+ component.setData(qml, QUrl());
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY2(object != nullptr, qPrintable(component.errorString()));
+
+ bool ok = false;
for (int ii = 0; ii < qtMetaObject->enumeratorCount(); ++ii) {
- QMetaEnum enumerator = qtMetaObject->enumerator(ii);
+ const QMetaEnum enumerator = qtMetaObject->enumerator(ii);
for (int jj = 0; jj < enumerator.keyCount(); ++jj) {
- auto key = enumerator.key(jj);
-// qDebug() << "key:" << key;
- if (!keys.contains(key)) {
- ++uniqueKeys;
- keys.insert(key);
- }
- QVERIFY(values.contains(key));
- QVariant value = values.value(key);
- QVERIFY(value.canConvert<int>());
- QCOMPARE(value.toInt(), enumerator.value(jj));
+ const QByteArray key = enumerator.key(jj);
+
+ if (QChar::fromLatin1(key.front()).isLower())
+ continue;
+
+ QCOMPARE(object->property(QByteArray("v") + enumerator.name() + key).toInt(&ok),
+ enumerator.value(jj));
+ QVERIFY(ok);
}
}
- QVERIFY(values.contains("Asynchronous"));
- QCOMPARE(values.value("Asynchronous").toInt(), 0);
- ++uniqueKeys;
- QVERIFY(values.contains("Synchronous"));
- QCOMPARE(values.value("Synchronous").toInt(), 1);
- ++uniqueKeys;
- QCOMPARE(values.count(), uniqueKeys);
+
+ QCOMPARE(object->property("vLoadingModeAsynchronous").toInt(&ok), 0);
+ QVERIFY(ok);
+ QCOMPARE(object->property("vLoadingModeSynchronous").toInt(&ok), 1);
+ QVERIFY(ok);
}
class TimeProvider: public QObject