summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/qobject.js6
-rw-r--r--tests/qml/tst_metaobjectpublisher.qml77
-rw-r--r--tests/qml/wrapper.html32
3 files changed, 114 insertions, 1 deletions
diff --git a/src/qobject.js b/src/qobject.js
index cbff4f1..048295c 100644
--- a/src/qobject.js
+++ b/src/qobject.js
@@ -71,6 +71,12 @@ function QObject(name, data, webChannel)
qObject.destroyed.connect(function() {
if (webChannel.objectMap[objectId] === qObject) {
delete webChannel.objectMap[objectId];
+ // reset the now deleted QObject to an empty {} object
+ // just assigning {} though would not have the desired effect, but the
+ // below also ensures all external references will see the empty map
+ for (var prop in qObject) {
+ delete qObject[prop];
+ }
}
});
return qObject;
diff --git a/tests/qml/tst_metaobjectpublisher.qml b/tests/qml/tst_metaobjectpublisher.qml
index 6f1d825..afbf624 100644
--- a/tests/qml/tst_metaobjectpublisher.qml
+++ b/tests/qml/tst_metaobjectpublisher.qml
@@ -57,6 +57,24 @@ WebChannelTest {
property var foo: 1
property var bar: 1
}
+ QtObject {
+ id: myFactory
+ function create(id)
+ {
+ return component.createObject(myFactory, {objectName: id});
+ }
+ }
+
+ Component {
+ id: component
+ QtObject {
+ property var myProperty : 0
+ function myMethod(arg) {
+ mySignal(arg, myProperty);
+ }
+ signal mySignal(var arg1, var arg2)
+ }
+ }
MetaObjectPublisher {
id: publisher
@@ -76,7 +94,8 @@ WebChannelTest {
{
publisher.registerObjects({
"myObj": myObj,
- "myOtherObj": myOtherObj
+ "myOtherObj": myOtherObj,
+ "myFactory": myFactory
});
}
@@ -188,4 +207,60 @@ WebChannelTest {
awaitIdle();
}
+ function test_wrapper()
+ {
+ loadUrl("wrapper.html");
+ awaitInit();
+
+ var msg = awaitMessage();
+ compare(msg.data.type, "Qt.invokeMethod");
+ compare(msg.data.object, "myFactory");
+ compare(msg.data.method, "create");
+
+ awaitIdle();
+
+ msg = awaitMessage();
+ compare(msg.data.type, "Qt.connectToSignal");
+ compare(msg.data.signal, "destroyed");
+ verify(msg.data.object);
+ var objId = msg.data.object;
+ var obj = publisher.unwrapObject(objId);
+ verify(obj);
+ compare(obj.objectName, "testObj");
+
+ msg = awaitMessage();
+ compare(msg.data.type, "Qt.connectToSignal");
+ compare(msg.data.object, objId);
+ compare(msg.data.signal, "mySignal");
+
+ msg = awaitMessage();
+ compare(msg.data.type, "Qt.setProperty");
+ compare(msg.data.object, objId);
+ compare(obj.myProperty, 42);
+
+ msg = awaitMessage();
+ compare(msg.data.type, "Qt.invokeMethod");
+ compare(msg.data.object, objId);
+ compare(msg.data.method, "myMethod");
+ compare(msg.data.args, ["foobar"]);
+
+ msg = awaitMessage();
+ compare(msg.data.label, "signalReceived");
+ compare(msg.data.args, ["foobar", 42]);
+
+ // pass QObject* on the fly and trigger deleteLater from client side
+ webChannel.sendMessage("triggerDelete");
+ awaitIdle();
+
+ msg = awaitMessage();
+ compare(msg.data.type, "Qt.invokeMethod");
+ compare(msg.data.object, objId);
+ compare(msg.data.method, "deleteLater");
+ verify(!publisher.unwrapObject(objId));
+
+ webChannel.sendMessage("report");
+ msg = awaitMessage();
+ compare(msg.data.label, "report");
+ compare(msg.data.obj, {});
+ }
}
diff --git a/tests/qml/wrapper.html b/tests/qml/wrapper.html
new file mode 100644
index 0000000..a6c313b
--- /dev/null
+++ b/tests/qml/wrapper.html
@@ -0,0 +1,32 @@
+<html>
+ <head>
+ <script type="text/javascript" src="qrc:///qwebchannel/webchannel.js"></script>
+ <script type="text/javascript" src="qrc:///qwebchannel/qobject.js"></script>
+ <script type="text/javascript">
+ //BEGIN SETUP
+ var baseUrl = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search)[1]);
+ new QWebChannel(baseUrl, function(channel) {
+ setupQObjectWebChannel(channel, function() {
+ myFactory.create("testObj", function(obj) {
+ window[obj.objectName()] = obj;
+ obj.mySignal.connect(function(arg1, arg2) {
+ channel.exec({label: "signalReceived", args: [arg1, arg2]});
+ });
+ obj.myProperty = 42;
+ obj.myMethod("foobar");
+ });
+ channel.subscribe("triggerDelete", function() {
+ console.log(testObj);
+ testObj.deleteLater();
+ });
+ channel.subscribe("report", function() {
+ channel.exec({label:"report", obj: testObj})
+ });
+ });
+ });
+ //END SETUP
+ </script>
+ </head>
+ <body>
+ </body>
+</html>