Commit 42306bb0 authored by Romain Courteaud's avatar Romain Courteaud Committed by Gabriel Monnerat

Allow to cancel method call in an iframe gadget

parent 9a7a349a
...@@ -379,12 +379,12 @@ ...@@ -379,12 +379,12 @@
obj[pathItems[pathItems.length - 1]] = (function() { obj[pathItems[pathItems.length - 1]] = (function() {
var cbName = path; var cbName = path;
return function(params) { return function(params) {
return trans.invoke(cbName, params); return trans.invoke(cbName, params, m.id);
}; };
})(); })();
} }
} }
var resp = regTbl[method](trans, m.params); var resp = regTbl[method](trans, m.params, m.id);
if (!trans.delayReturn() && !trans.completed()) trans.complete(resp); if (!trans.delayReturn() && !trans.completed()) trans.complete(resp);
} catch(e) { } catch(e) {
// automagic handling of exceptions: // automagic handling of exceptions:
...@@ -580,6 +580,8 @@ ...@@ -580,6 +580,8 @@
s_curTranId++; s_curTranId++;
postMessage(msg); postMessage(msg);
// return the transaction id
return s_curTranId - 1;
}, },
notify: function(m) { notify: function(m) {
if (!m) throw 'missing arguments to notify function'; if (!m) throw 'missing arguments to notify function';
......
...@@ -1022,9 +1022,10 @@ ...@@ -1022,9 +1022,10 @@
function handleChannelDeclareMethod(trans, method_name) { function handleChannelDeclareMethod(trans, method_name) {
gadget_instance[method_name] = function triggerChannelDeclareMethod() { gadget_instance[method_name] = function triggerChannelDeclareMethod() {
var argument_list = arguments, var argument_list = arguments,
channel_call_id,
wait_promise = new RSVP.Promise( wait_promise = new RSVP.Promise(
function handleChannelCall(resolve, reject) { function handleChannelCall(resolve, reject) {
gadget_instance.__chan.call({ channel_call_id = gadget_instance.__chan.call({
method: "methodCall", method: "methodCall",
params: [ params: [
method_name, method_name,
...@@ -1032,6 +1033,15 @@ ...@@ -1032,6 +1033,15 @@
success: resolve, success: resolve,
error: reject error: reject
}); });
},
function cancelChannelCall(msg) {
gadget_instance.__chan.notify({
method: "cancelMethodCall",
params: [
channel_call_id,
msg
]
});
} }
); );
...@@ -1883,6 +1893,7 @@ ...@@ -1883,6 +1893,7 @@
function finishAqParentConfiguration(TmpConstructor, root_gadget, function finishAqParentConfiguration(TmpConstructor, root_gadget,
embedded_channel) { embedded_channel) {
var local_transaction_dict = {};
// Define __aq_parent to inform parent window // Define __aq_parent to inform parent window
root_gadget.__aq_parent = root_gadget.__aq_parent =
TmpConstructor.prototype.__aq_parent = function aq_parent(method_name, TmpConstructor.prototype.__aq_parent = function aq_parent(method_name,
...@@ -1905,14 +1916,31 @@ ...@@ -1905,14 +1916,31 @@
}; };
// bind calls to renderJS method on the instance // bind calls to renderJS method on the instance
embedded_channel.bind("methodCall", function methodCall(trans, v) { embedded_channel.bind("methodCall",
root_gadget[v[0]].apply(root_gadget, v[1]) function methodCall(trans, v, transaction_id) {
.push(trans.complete, local_transaction_dict[transaction_id] =
function handleMethodCallError(e) { root_gadget[v[0]].apply(root_gadget, v[1])
.push(function handleMethodCallSuccess() {
// drop the promise reference, to allow garbage collection
delete local_transaction_dict[transaction_id];
trans.complete.apply(trans, arguments);
}, function handleMethodCallError(e) {
// drop the promise reference, to allow garbage collection
delete local_transaction_dict[transaction_id];
trans.error(e.toString()); trans.error(e.toString());
}); });
trans.delayReturn(true); trans.delayReturn(true);
}); });
embedded_channel.bind("cancelMethodCall",
function cancelMethodCall(trans, v) {
if (local_transaction_dict.hasOwnProperty(v[0])) {
local_transaction_dict[v[0]].cancel(v[1]);
// drop the promise reference, to allow garbage collection
delete local_transaction_dict[v[0]];
}
});
} }
function bootstrap(url) { function bootstrap(url) {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
service_started = false, service_started = false,
job_started = false, job_started = false,
event_started = false, event_started = false,
method_cancel_called = false,
state_change_callback_called = false, state_change_callback_called = false,
state_change_count = 0, state_change_count = 0,
init_state = {bar: 'foo'}, init_state = {bar: 'foo'},
...@@ -110,6 +111,16 @@ ...@@ -110,6 +111,16 @@
'acquireMethodRequestedWithAcquisitionError') 'acquireMethodRequestedWithAcquisitionError')
.declareMethod('callErrorAcquire', function (param1, param2) { .declareMethod('callErrorAcquire', function (param1, param2) {
return this.plugErrorAcquire(param1, param2); return this.plugErrorAcquire(param1, param2);
})
.declareMethod('triggerMethodToCancel', function () {
return new RSVP.Promise(function () {
return;
}, function () {
method_cancel_called = true;
});
})
.declareMethod('wasMethodCancelCalled', function () {
return method_cancel_called;
}); });
}(window, rJS)); }(window, rJS));
...@@ -5667,7 +5667,7 @@ ...@@ -5667,7 +5667,7 @@
gadget.__sub_gadget_dict = {}; gadget.__sub_gadget_dict = {};
stop(); stop();
expect(23); expect(25);
gadget.declareGadget(url, { gadget.declareGadget(url, {
sandbox: 'iframe', sandbox: 'iframe',
element: document.getElementById('qunit-fixture'), element: document.getElementById('qunit-fixture'),
...@@ -5846,6 +5846,25 @@ ...@@ -5846,6 +5846,25 @@
"acquireMethodRequestedWithAcquisitionError", "acquireMethodRequestedWithAcquisitionError",
error error
); );
})
// cancel call is correctly propagated by declareMethod
.push(function () {
var method_to_cancel = new_gadget.triggerMethodToCancel();
return new RSVP.Queue(RSVP.delay(400))
.push(function () {
return RSVP.all([
method_to_cancel,
method_to_cancel.cancel()
]);
});
})
.push(undefined, function (error) {
ok(error instanceof RSVP.CancellationError, error);
return new_gadget.wasMethodCancelCalled();
})
.push(function (result) {
ok(result, 'Embedded method not cancelled');
}); });
}) })
.fail(function (error) { .fail(function (error) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment