aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/v8/qv8engine.cpp3
-rw-r--r--src/declarative/qml/v8/qv8typewrapper.cpp28
-rw-r--r--src/declarative/qml/v8/qv8typewrapper_p.h1
-rw-r--r--tests/auto/declarative/qdeclarativeconnection/data/moduleapi-target.qml22
-rw-r--r--tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp64
5 files changed, 117 insertions, 1 deletions
diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp
index 8eaf9024ea..5b74f48170 100644
--- a/src/declarative/qml/v8/qv8engine.cpp
+++ b/src/declarative/qml/v8/qv8engine.cpp
@@ -208,7 +208,6 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint)
if (r) {
switch (r->resourceType()) {
case QV8ObjectResource::ContextType:
- case QV8ObjectResource::TypeType:
case QV8ObjectResource::XMLHttpRequestType:
case QV8ObjectResource::DOMNodeType:
case QV8ObjectResource::SQLDatabaseType:
@@ -216,6 +215,8 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint)
case QV8ObjectResource::Context2DType:
case QV8ObjectResource::ParticleDataType:
return QVariant();
+ case QV8ObjectResource::TypeType:
+ return m_typeWrapper.toVariant(r);
case QV8ObjectResource::QObjectType:
return qVariantFromValue<QObject *>(m_qobjectWrapper.toQObject(r));
case QV8ObjectResource::ListType:
diff --git a/src/declarative/qml/v8/qv8typewrapper.cpp b/src/declarative/qml/v8/qv8typewrapper.cpp
index f46aaab320..c89d5ab8ae 100644
--- a/src/declarative/qml/v8/qv8typewrapper.cpp
+++ b/src/declarative/qml/v8/qv8typewrapper.cpp
@@ -128,6 +128,34 @@ v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QDeclarativeTypeName
return rv;
}
+QVariant QV8TypeWrapper::toVariant(QV8ObjectResource *r)
+{
+ Q_ASSERT(r->resourceType() == QV8ObjectResource::TypeType);
+ QV8TypeResource *resource = static_cast<QV8TypeResource *>(r);
+ QV8Engine *v8engine = resource->engine;
+
+ if (resource->typeNamespace) {
+ if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi(resource->importNamespace)) {
+ if (moduleApi->scriptCallback) {
+ moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine());
+ moduleApi->scriptCallback = 0;
+ moduleApi->qobjectCallback = 0;
+ } else if (moduleApi->qobjectCallback) {
+ moduleApi->qobjectApi = moduleApi->qobjectCallback(v8engine->engine(), v8engine->engine());
+ moduleApi->scriptCallback = 0;
+ moduleApi->qobjectCallback = 0;
+ }
+
+ if (moduleApi->qobjectApi) {
+ return QVariant::fromValue<QObject*>(moduleApi->qobjectApi);
+ }
+ }
+ }
+
+ // only QObject Module API can be converted to a variant.
+ return QVariant();
+}
+
v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property,
const v8::AccessorInfo &info)
{
diff --git a/src/declarative/qml/v8/qv8typewrapper_p.h b/src/declarative/qml/v8/qv8typewrapper_p.h
index 2e79946a6e..f9309f8e28 100644
--- a/src/declarative/qml/v8/qv8typewrapper_p.h
+++ b/src/declarative/qml/v8/qv8typewrapper_p.h
@@ -75,6 +75,7 @@ public:
v8::Local<v8::Object> newObject(QObject *, QDeclarativeType *, TypeNameMode = IncludeEnums);
v8::Local<v8::Object> newObject(QObject *, QDeclarativeTypeNameCache *, const void *,
TypeNameMode = IncludeEnums);
+ QVariant toVariant(QV8ObjectResource *);
private:
static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
diff --git a/tests/auto/declarative/qdeclarativeconnection/data/moduleapi-target.qml b/tests/auto/declarative/qdeclarativeconnection/data/moduleapi-target.qml
new file mode 100644
index 0000000000..8803f24542
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeconnection/data/moduleapi-target.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+import MyTestModuleApi 1.0 as MyTestModuleApi
+
+Item {
+ id: rootObject
+ objectName: "rootObject"
+ property int newIntPropValue: 12
+
+ property int moduleIntPropChangedCount: 0
+ property int moduleOtherSignalCount: 0
+
+ function setModuleIntProp() {
+ MyTestModuleApi.intProp = newIntPropValue;
+ newIntPropValue = newIntPropValue + 1;
+ }
+
+ Connections {
+ target: MyTestModuleApi
+ onIntPropChanged: moduleIntPropChangedCount = moduleIntPropChangedCount + 1;
+ onOtherSignal: moduleOtherSignalCount = moduleOtherSignalCount + 1;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp b/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
index 37cce5c578..c726fde0e8 100644
--- a/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
+++ b/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
@@ -68,6 +68,7 @@ private slots:
void unknownSignals();
void errors_data();
void errors();
+ void moduleApiTarget();
private:
QDeclarativeEngine engine;
@@ -229,6 +230,69 @@ void tst_qdeclarativeconnection::errors()
QCOMPARE(errors.at(0).description(), error);
}
+
+class MyTestModuleApi : public QObject
+{
+Q_OBJECT
+Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged)
+
+public:
+ MyTestModuleApi(QObject *parent = 0) : QObject(parent), m_intProp(0), m_changeCount(0) {}
+ ~MyTestModuleApi() {}
+
+ Q_INVOKABLE int otherMethod(int val) { return val + 4; }
+
+ int intProp() const { return m_intProp; }
+ void setIntProp(int val)
+ {
+ if (++m_changeCount % 3 == 0) emit otherSignal();
+ m_intProp = val; emit intPropChanged();
+ }
+
+signals:
+ void intPropChanged();
+ void otherSignal();
+
+private:
+ int m_intProp;
+ int m_changeCount;
+};
+
+static QObject *module_api_factory(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(engine)
+ Q_UNUSED(scriptEngine)
+ MyTestModuleApi *api = new MyTestModuleApi();
+ return api;
+}
+
+// QTBUG-20937
+void tst_qdeclarativeconnection::moduleApiTarget()
+{
+ qmlRegisterModuleApi("MyTestModuleApi", 1, 0, module_api_factory);
+ QDeclarativeComponent component(&engine, QUrl(SRCDIR "/data/moduleapi-target.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 0);
+ QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0);
+
+ QMetaObject::invokeMethod(object, "setModuleIntProp");
+ QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 1);
+ QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0);
+
+ QMetaObject::invokeMethod(object, "setModuleIntProp");
+ QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 2);
+ QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0);
+
+ // the module API emits otherSignal every 3 times the int property changes.
+ QMetaObject::invokeMethod(object, "setModuleIntProp");
+ QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 3);
+ QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 1);
+
+ delete object;
+}
+
QTEST_MAIN(tst_qdeclarativeconnection)
#include "tst_qdeclarativeconnection.moc"