Commit 8609902e authored by Romain Courteaud's avatar Romain Courteaud

erp5_xhtml_style/web_renderjs_ui: renderjs 0.26.0

parent dfa60381
...@@ -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';
...@@ -779,6 +781,19 @@ if (typeof document.contains !== 'function') { ...@@ -779,6 +781,19 @@ if (typeof document.contains !== 'function') {
ScopeError.prototype = new Error(); ScopeError.prototype = new Error();
ScopeError.prototype.constructor = ScopeError; ScopeError.prototype.constructor = ScopeError;
/////////////////////////////////////////////////////////////////
// renderJS.IframeSerializationError
/////////////////////////////////////////////////////////////////
function IframeSerializationError(message) {
this.name = "IframeSerializationError";
if ((message !== undefined) && (typeof message !== "string")) {
throw new TypeError('You must pass a string.');
}
this.message = message || "Parameter serialization failed";
}
IframeSerializationError.prototype = new Error();
IframeSerializationError.prototype.constructor = IframeSerializationError;
function ensurePushableQueue(callback, argument_list, context) { function ensurePushableQueue(callback, argument_list, context) {
var result; var result;
try { try {
...@@ -818,18 +833,18 @@ if (typeof document.contains !== 'function') { ...@@ -818,18 +833,18 @@ if (typeof document.contains !== 'function') {
prevent_default = true; prevent_default = true;
} }
function cancelResolver() { function cancelResolver(msg) {
if ((callback_promise !== undefined) && if ((callback_promise !== undefined) &&
(typeof callback_promise.cancel === "function")) { (typeof callback_promise.cancel === "function")) {
callback_promise.cancel(); callback_promise.cancel(msg);
} }
} }
function canceller() { function canceller(msg) {
if (handle_event_callback !== undefined) { if (handle_event_callback !== undefined) {
target.removeEventListener(type, handle_event_callback, useCapture); target.removeEventListener(type, handle_event_callback, useCapture);
} }
cancelResolver(); cancelResolver(msg);
} }
function itsANonResolvableTrap(resolve, reject) { function itsANonResolvableTrap(resolve, reject) {
var result; var result;
...@@ -839,7 +854,9 @@ if (typeof document.contains !== 'function') { ...@@ -839,7 +854,9 @@ if (typeof document.contains !== 'function') {
evt.preventDefault(); evt.preventDefault();
} }
cancelResolver(); cancelResolver(
"Cancelling previous event (" + evt.type + ")"
);
try { try {
result = callback(evt); result = callback(evt);
...@@ -851,7 +868,7 @@ if (typeof document.contains !== 'function') { ...@@ -851,7 +868,7 @@ if (typeof document.contains !== 'function') {
.push(undefined, function handleEventCallbackError(error) { .push(undefined, function handleEventCallbackError(error) {
// Prevent rejecting the loop, if the result cancelled itself // Prevent rejecting the loop, if the result cancelled itself
if (!(error instanceof RSVP.CancellationError)) { if (!(error instanceof RSVP.CancellationError)) {
canceller(); canceller(error.toString());
reject(error); reject(error);
} }
}); });
...@@ -926,6 +943,7 @@ if (typeof document.contains !== 'function') { ...@@ -926,6 +943,7 @@ if (typeof document.contains !== 'function') {
isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'), isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'),
is_page_unloaded = false, is_page_unloaded = false,
error_list = [], error_list = [],
unhandled_error_type = 0,
all_dependency_loaded_deferred; all_dependency_loaded_deferred;
window.addEventListener('error', function handleGlobalError(error) { window.addEventListener('error', function handleGlobalError(error) {
...@@ -975,6 +993,40 @@ if (typeof document.contains !== 'function') { ...@@ -975,6 +993,40 @@ if (typeof document.contains !== 'function') {
return url; return url;
} }
function getErrorTypeMapping() {
var error_type_mapping = {
1: renderJS.AcquisitionError,
2: RSVP.CancellationError
};
// set the unhandle error type to be used as default
error_type_mapping[unhandled_error_type] = IframeSerializationError;
return error_type_mapping;
}
function convertObjectToErrorType(error) {
var error_type,
error_type_mapping = getErrorTypeMapping();
for (error_type in error_type_mapping) {
if (error_type_mapping.hasOwnProperty(error_type) &&
error instanceof error_type_mapping[error_type]) {
return error_type;
}
}
return unhandled_error_type;
}
function rejectErrorType(value, reject) {
var error_type_mapping = getErrorTypeMapping();
if (value.hasOwnProperty("type") &&
error_type_mapping.hasOwnProperty(value.type)) {
value = new error_type_mapping[value.type](
value.msg
);
}
return reject(value);
}
function letsCrash(e) { function letsCrash(e) {
var i, var i,
body, body,
...@@ -1112,11 +1164,11 @@ if (typeof document.contains !== 'function') { ...@@ -1112,11 +1164,11 @@ if (typeof document.contains !== 'function') {
return new Monitor(); return new Monitor();
} }
function canceller() { function canceller(msg) {
var len = promise_list.length, var len = promise_list.length,
i; i;
for (i = 0; i < len; i += 1) { for (i = 0; i < len; i += 1) {
promise_list[i].cancel(); promise_list[i].cancel(msg);
} }
// Clean it to speed up other canceller run // Clean it to speed up other canceller run
promise_list = []; promise_list = [];
...@@ -1130,17 +1182,17 @@ if (typeof document.contains !== 'function') { ...@@ -1130,17 +1182,17 @@ if (typeof document.contains !== 'function') {
monitor.isRejected = true; monitor.isRejected = true;
monitor.rejectedReason = rejectedReason; monitor.rejectedReason = rejectedReason;
resolved = true; resolved = true;
canceller(); canceller(rejectedReason.toString());
return fail(rejectedReason); return fail(rejectedReason);
}; };
}, canceller); }, canceller);
monitor.cancel = function cancelMonitor() { monitor.cancel = function cancelMonitor(msg) {
if (resolved) { if (resolved) {
return; return;
} }
resolved = true; resolved = true;
promise.cancel(); promise.cancel(msg);
promise.fail(function rejectMonitorPromise(rejectedReason) { promise.fail(function rejectMonitorPromise(rejectedReason) {
monitor.isRejected = true; monitor.isRejected = true;
monitor.rejectedReason = rejectedReason; monitor.rejectedReason = rejectedReason;
...@@ -1199,7 +1251,11 @@ if (typeof document.contains !== 'function') { ...@@ -1199,7 +1251,11 @@ if (typeof document.contains !== 'function') {
function deleteGadgetMonitor(g) { function deleteGadgetMonitor(g) {
if (g.hasOwnProperty('__monitor')) { if (g.hasOwnProperty('__monitor')) {
g.__monitor.cancel(); g.__monitor.cancel(
"Deleting Gadget Monitor " + "(" +
g.element.dataset.gadgetUrl +
")"
);
delete g.__monitor; delete g.__monitor;
g.__job_list = []; g.__job_list = [];
} }
...@@ -1324,7 +1380,7 @@ if (typeof document.contains !== 'function') { ...@@ -1324,7 +1380,7 @@ if (typeof document.contains !== 'function') {
function runJob(gadget, name, callback, argument_list) { function runJob(gadget, name, callback, argument_list) {
if (gadget.__job_dict.hasOwnProperty(name)) { if (gadget.__job_dict.hasOwnProperty(name)) {
gadget.__job_dict[name].cancel(); gadget.__job_dict[name].cancel(name + " : Cancelling previous job");
} }
var job_promise = ensurePushableQueue(callback, argument_list, gadget); var job_promise = ensurePushableQueue(callback, argument_list, gadget);
gadget.__job_dict[name] = job_promise; gadget.__job_dict[name] = job_promise;
...@@ -1686,6 +1742,7 @@ if (typeof document.contains !== 'function') { ...@@ -1686,6 +1742,7 @@ if (typeof document.contains !== 'function') {
old_element) { old_element) {
var gadget_instance, var gadget_instance,
iframe, iframe,
transaction_dict = {},
iframe_loading_deferred = RSVP.defer(); iframe_loading_deferred = RSVP.defer();
if (old_element === undefined) { if (old_element === undefined) {
throw new Error("DOM element is required to create Iframe Gadget " + throw new Error("DOM element is required to create Iframe Gadget " +
...@@ -1740,15 +1797,29 @@ if (typeof document.contains !== 'function') { ...@@ -1740,15 +1797,29 @@ if (typeof document.contains !== 'function') {
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({ function errorWrap(value) {
return rejectErrorType(value, reject);
}
channel_call_id = gadget_instance.__chan.call({
method: "methodCall", method: "methodCall",
params: [ params: [
method_name, method_name,
Array.prototype.slice.call(argument_list, 0)], Array.prototype.slice.call(argument_list, 0)],
success: resolve, success: resolve,
error: reject error: errorWrap
});
},
function cancelChannelCall(msg) {
gadget_instance.__chan.notify({
method: "cancelMethodCall",
params: [
channel_call_id,
msg
]
}); });
} }
); );
...@@ -1771,15 +1842,45 @@ if (typeof document.contains !== 'function') { ...@@ -1771,15 +1842,45 @@ if (typeof document.contains !== 'function') {
iframe_loading_deferred.reject(params); iframe_loading_deferred.reject(params);
return "OK"; return "OK";
}); });
gadget_instance.__chan.bind("cancelAcquiredMethodCall",
function handleChannelCancel(trans,
params) {
var transaction_id = params[0],
msg = params[1];
if (transaction_dict.hasOwnProperty(transaction_id)) {
transaction_dict[transaction_id].cancel(msg);
delete transaction_dict[transaction_id];
}
return "OK";
});
gadget_instance.__chan.bind("acquire", gadget_instance.__chan.bind("acquire",
function handleChannelAcquire(trans, params) { function handleChannelAcquire(trans, params,
transaction_id) {
function cleanUpTransactionDict(transaction_id) {
if (transaction_dict.hasOwnProperty(transaction_id)) {
delete transaction_dict[transaction_id];
}
}
new RSVP.Queue() new RSVP.Queue()
.push(function () { .push(function () {
return gadget_instance.__aq_parent.apply(gadget_instance, params); var promise = gadget_instance.__aq_parent.apply(
gadget_instance,
params
);
transaction_dict[transaction_id] = promise;
return promise;
})
.then(function () {
cleanUpTransactionDict(transaction_id);
trans.complete.apply(trans, arguments);
}) })
.then(trans.complete)
.fail(function handleChannelAcquireError(e) { .fail(function handleChannelAcquireError(e) {
trans.error(e.toString()); var message = e instanceof Error ? e.message : e;
trans.error({
type: convertObjectToErrorType(e),
msg: message
});
return cleanUpTransactionDict(transaction_id);
}); });
trans.delayReturn(true); trans.delayReturn(true);
}); });
...@@ -2303,6 +2404,7 @@ if (typeof document.contains !== 'function') { ...@@ -2303,6 +2404,7 @@ if (typeof document.contains !== 'function') {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
renderJS.Mutex = Mutex; renderJS.Mutex = Mutex;
renderJS.ScopeError = ScopeError; renderJS.ScopeError = ScopeError;
renderJS.IframeSerializationError = IframeSerializationError;
renderJS.loopEventListener = loopEventListener; renderJS.loopEventListener = loopEventListener;
window.rJS = window.renderJS = renderJS; window.rJS = window.renderJS = renderJS;
window.__RenderJSGadget = RenderJSGadget; window.__RenderJSGadget = RenderJSGadget;
...@@ -2601,36 +2703,82 @@ if (typeof document.contains !== 'function') { ...@@ -2601,36 +2703,82 @@ if (typeof document.contains !== 'function') {
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,
argument_list, argument_list,
time_out) { time_out) {
var channel_call_id;
return new RSVP.Promise( return new RSVP.Promise(
function waitForChannelAcquire(resolve, reject) { function waitForChannelAcquire(resolve, reject) {
embedded_channel.call({ function errorWrap(value) {
return rejectErrorType(value, reject);
}
channel_call_id = embedded_channel.call({
method: "acquire", method: "acquire",
params: [ params: [
method_name, method_name,
argument_list Array.prototype.slice.call(argument_list, 0)
], ],
success: resolve, success: resolve,
error: reject, error: errorWrap,
timeout: time_out timeout: time_out
}); });
},
function cancelChannelCall(msg) {
embedded_channel.notify({
method: "cancelAcquiredMethodCall",
params: [
channel_call_id,
msg
]
});
} }
); );
}; };
// 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",
function methodCall(trans, v, transaction_id) {
local_transaction_dict[transaction_id] =
root_gadget[v[0]].apply(root_gadget, v[1]) root_gadget[v[0]].apply(root_gadget, v[1])
.push(trans.complete, .push(function handleMethodCallSuccess() {
function handleMethodCallError(e) { // drop the promise reference, to allow garbage collection
trans.error(e.toString()); delete local_transaction_dict[transaction_id];
trans.complete.apply(trans, arguments);
}, function handleMethodCallError(e) {
var error_type = convertObjectToErrorType(e),
message;
if (e instanceof Error) {
if (error_type !== unhandled_error_type) {
message = e.message;
} else {
message = e.toString();
}
} else {
message = e;
}
// drop the promise reference, to allow garbage collection
delete local_transaction_dict[transaction_id];
trans.error({
type: error_type,
msg: message
});
}); });
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) {
......
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>989.27523.29749.43383</string> </value> <value> <string>996.23761.26725.45789</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1613141629.7</float> <float>1641216662.48</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -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';
...@@ -779,6 +781,19 @@ if (typeof document.contains !== 'function') { ...@@ -779,6 +781,19 @@ if (typeof document.contains !== 'function') {
ScopeError.prototype = new Error(); ScopeError.prototype = new Error();
ScopeError.prototype.constructor = ScopeError; ScopeError.prototype.constructor = ScopeError;
/////////////////////////////////////////////////////////////////
// renderJS.IframeSerializationError
/////////////////////////////////////////////////////////////////
function IframeSerializationError(message) {
this.name = "IframeSerializationError";
if ((message !== undefined) && (typeof message !== "string")) {
throw new TypeError('You must pass a string.');
}
this.message = message || "Parameter serialization failed";
}
IframeSerializationError.prototype = new Error();
IframeSerializationError.prototype.constructor = IframeSerializationError;
function ensurePushableQueue(callback, argument_list, context) { function ensurePushableQueue(callback, argument_list, context) {
var result; var result;
try { try {
...@@ -818,18 +833,18 @@ if (typeof document.contains !== 'function') { ...@@ -818,18 +833,18 @@ if (typeof document.contains !== 'function') {
prevent_default = true; prevent_default = true;
} }
function cancelResolver() { function cancelResolver(msg) {
if ((callback_promise !== undefined) && if ((callback_promise !== undefined) &&
(typeof callback_promise.cancel === "function")) { (typeof callback_promise.cancel === "function")) {
callback_promise.cancel(); callback_promise.cancel(msg);
} }
} }
function canceller() { function canceller(msg) {
if (handle_event_callback !== undefined) { if (handle_event_callback !== undefined) {
target.removeEventListener(type, handle_event_callback, useCapture); target.removeEventListener(type, handle_event_callback, useCapture);
} }
cancelResolver(); cancelResolver(msg);
} }
function itsANonResolvableTrap(resolve, reject) { function itsANonResolvableTrap(resolve, reject) {
var result; var result;
...@@ -839,7 +854,9 @@ if (typeof document.contains !== 'function') { ...@@ -839,7 +854,9 @@ if (typeof document.contains !== 'function') {
evt.preventDefault(); evt.preventDefault();
} }
cancelResolver(); cancelResolver(
"Cancelling previous event (" + evt.type + ")"
);
try { try {
result = callback(evt); result = callback(evt);
...@@ -851,7 +868,7 @@ if (typeof document.contains !== 'function') { ...@@ -851,7 +868,7 @@ if (typeof document.contains !== 'function') {
.push(undefined, function handleEventCallbackError(error) { .push(undefined, function handleEventCallbackError(error) {
// Prevent rejecting the loop, if the result cancelled itself // Prevent rejecting the loop, if the result cancelled itself
if (!(error instanceof RSVP.CancellationError)) { if (!(error instanceof RSVP.CancellationError)) {
canceller(); canceller(error.toString());
reject(error); reject(error);
} }
}); });
...@@ -926,6 +943,7 @@ if (typeof document.contains !== 'function') { ...@@ -926,6 +943,7 @@ if (typeof document.contains !== 'function') {
isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'), isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'),
is_page_unloaded = false, is_page_unloaded = false,
error_list = [], error_list = [],
unhandled_error_type = 0,
all_dependency_loaded_deferred; all_dependency_loaded_deferred;
window.addEventListener('error', function handleGlobalError(error) { window.addEventListener('error', function handleGlobalError(error) {
...@@ -975,6 +993,40 @@ if (typeof document.contains !== 'function') { ...@@ -975,6 +993,40 @@ if (typeof document.contains !== 'function') {
return url; return url;
} }
function getErrorTypeMapping() {
var error_type_mapping = {
1: renderJS.AcquisitionError,
2: RSVP.CancellationError
};
// set the unhandle error type to be used as default
error_type_mapping[unhandled_error_type] = IframeSerializationError;
return error_type_mapping;
}
function convertObjectToErrorType(error) {
var error_type,
error_type_mapping = getErrorTypeMapping();
for (error_type in error_type_mapping) {
if (error_type_mapping.hasOwnProperty(error_type) &&
error instanceof error_type_mapping[error_type]) {
return error_type;
}
}
return unhandled_error_type;
}
function rejectErrorType(value, reject) {
var error_type_mapping = getErrorTypeMapping();
if (value.hasOwnProperty("type") &&
error_type_mapping.hasOwnProperty(value.type)) {
value = new error_type_mapping[value.type](
value.msg
);
}
return reject(value);
}
function letsCrash(e) { function letsCrash(e) {
var i, var i,
body, body,
...@@ -1112,11 +1164,11 @@ if (typeof document.contains !== 'function') { ...@@ -1112,11 +1164,11 @@ if (typeof document.contains !== 'function') {
return new Monitor(); return new Monitor();
} }
function canceller() { function canceller(msg) {
var len = promise_list.length, var len = promise_list.length,
i; i;
for (i = 0; i < len; i += 1) { for (i = 0; i < len; i += 1) {
promise_list[i].cancel(); promise_list[i].cancel(msg);
} }
// Clean it to speed up other canceller run // Clean it to speed up other canceller run
promise_list = []; promise_list = [];
...@@ -1130,17 +1182,17 @@ if (typeof document.contains !== 'function') { ...@@ -1130,17 +1182,17 @@ if (typeof document.contains !== 'function') {
monitor.isRejected = true; monitor.isRejected = true;
monitor.rejectedReason = rejectedReason; monitor.rejectedReason = rejectedReason;
resolved = true; resolved = true;
canceller(); canceller(rejectedReason.toString());
return fail(rejectedReason); return fail(rejectedReason);
}; };
}, canceller); }, canceller);
monitor.cancel = function cancelMonitor() { monitor.cancel = function cancelMonitor(msg) {
if (resolved) { if (resolved) {
return; return;
} }
resolved = true; resolved = true;
promise.cancel(); promise.cancel(msg);
promise.fail(function rejectMonitorPromise(rejectedReason) { promise.fail(function rejectMonitorPromise(rejectedReason) {
monitor.isRejected = true; monitor.isRejected = true;
monitor.rejectedReason = rejectedReason; monitor.rejectedReason = rejectedReason;
...@@ -1199,7 +1251,11 @@ if (typeof document.contains !== 'function') { ...@@ -1199,7 +1251,11 @@ if (typeof document.contains !== 'function') {
function deleteGadgetMonitor(g) { function deleteGadgetMonitor(g) {
if (g.hasOwnProperty('__monitor')) { if (g.hasOwnProperty('__monitor')) {
g.__monitor.cancel(); g.__monitor.cancel(
"Deleting Gadget Monitor " + "(" +
g.element.dataset.gadgetUrl +
")"
);
delete g.__monitor; delete g.__monitor;
g.__job_list = []; g.__job_list = [];
} }
...@@ -1324,7 +1380,7 @@ if (typeof document.contains !== 'function') { ...@@ -1324,7 +1380,7 @@ if (typeof document.contains !== 'function') {
function runJob(gadget, name, callback, argument_list) { function runJob(gadget, name, callback, argument_list) {
if (gadget.__job_dict.hasOwnProperty(name)) { if (gadget.__job_dict.hasOwnProperty(name)) {
gadget.__job_dict[name].cancel(); gadget.__job_dict[name].cancel(name + " : Cancelling previous job");
} }
var job_promise = ensurePushableQueue(callback, argument_list, gadget); var job_promise = ensurePushableQueue(callback, argument_list, gadget);
gadget.__job_dict[name] = job_promise; gadget.__job_dict[name] = job_promise;
...@@ -1686,6 +1742,7 @@ if (typeof document.contains !== 'function') { ...@@ -1686,6 +1742,7 @@ if (typeof document.contains !== 'function') {
old_element) { old_element) {
var gadget_instance, var gadget_instance,
iframe, iframe,
transaction_dict = {},
iframe_loading_deferred = RSVP.defer(); iframe_loading_deferred = RSVP.defer();
if (old_element === undefined) { if (old_element === undefined) {
throw new Error("DOM element is required to create Iframe Gadget " + throw new Error("DOM element is required to create Iframe Gadget " +
...@@ -1740,15 +1797,29 @@ if (typeof document.contains !== 'function') { ...@@ -1740,15 +1797,29 @@ if (typeof document.contains !== 'function') {
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({ function errorWrap(value) {
return rejectErrorType(value, reject);
}
channel_call_id = gadget_instance.__chan.call({
method: "methodCall", method: "methodCall",
params: [ params: [
method_name, method_name,
Array.prototype.slice.call(argument_list, 0)], Array.prototype.slice.call(argument_list, 0)],
success: resolve, success: resolve,
error: reject error: errorWrap
});
},
function cancelChannelCall(msg) {
gadget_instance.__chan.notify({
method: "cancelMethodCall",
params: [
channel_call_id,
msg
]
}); });
} }
); );
...@@ -1771,15 +1842,45 @@ if (typeof document.contains !== 'function') { ...@@ -1771,15 +1842,45 @@ if (typeof document.contains !== 'function') {
iframe_loading_deferred.reject(params); iframe_loading_deferred.reject(params);
return "OK"; return "OK";
}); });
gadget_instance.__chan.bind("cancelAcquiredMethodCall",
function handleChannelCancel(trans,
params) {
var transaction_id = params[0],
msg = params[1];
if (transaction_dict.hasOwnProperty(transaction_id)) {
transaction_dict[transaction_id].cancel(msg);
delete transaction_dict[transaction_id];
}
return "OK";
});
gadget_instance.__chan.bind("acquire", gadget_instance.__chan.bind("acquire",
function handleChannelAcquire(trans, params) { function handleChannelAcquire(trans, params,
transaction_id) {
function cleanUpTransactionDict(transaction_id) {
if (transaction_dict.hasOwnProperty(transaction_id)) {
delete transaction_dict[transaction_id];
}
}
new RSVP.Queue() new RSVP.Queue()
.push(function () { .push(function () {
return gadget_instance.__aq_parent.apply(gadget_instance, params); var promise = gadget_instance.__aq_parent.apply(
gadget_instance,
params
);
transaction_dict[transaction_id] = promise;
return promise;
})
.then(function () {
cleanUpTransactionDict(transaction_id);
trans.complete.apply(trans, arguments);
}) })
.then(trans.complete)
.fail(function handleChannelAcquireError(e) { .fail(function handleChannelAcquireError(e) {
trans.error(e.toString()); var message = e instanceof Error ? e.message : e;
trans.error({
type: convertObjectToErrorType(e),
msg: message
});
return cleanUpTransactionDict(transaction_id);
}); });
trans.delayReturn(true); trans.delayReturn(true);
}); });
...@@ -2303,6 +2404,7 @@ if (typeof document.contains !== 'function') { ...@@ -2303,6 +2404,7 @@ if (typeof document.contains !== 'function') {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
renderJS.Mutex = Mutex; renderJS.Mutex = Mutex;
renderJS.ScopeError = ScopeError; renderJS.ScopeError = ScopeError;
renderJS.IframeSerializationError = IframeSerializationError;
renderJS.loopEventListener = loopEventListener; renderJS.loopEventListener = loopEventListener;
window.rJS = window.renderJS = renderJS; window.rJS = window.renderJS = renderJS;
window.__RenderJSGadget = RenderJSGadget; window.__RenderJSGadget = RenderJSGadget;
...@@ -2601,36 +2703,82 @@ if (typeof document.contains !== 'function') { ...@@ -2601,36 +2703,82 @@ if (typeof document.contains !== 'function') {
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,
argument_list, argument_list,
time_out) { time_out) {
var channel_call_id;
return new RSVP.Promise( return new RSVP.Promise(
function waitForChannelAcquire(resolve, reject) { function waitForChannelAcquire(resolve, reject) {
embedded_channel.call({ function errorWrap(value) {
return rejectErrorType(value, reject);
}
channel_call_id = embedded_channel.call({
method: "acquire", method: "acquire",
params: [ params: [
method_name, method_name,
argument_list Array.prototype.slice.call(argument_list, 0)
], ],
success: resolve, success: resolve,
error: reject, error: errorWrap,
timeout: time_out timeout: time_out
}); });
},
function cancelChannelCall(msg) {
embedded_channel.notify({
method: "cancelAcquiredMethodCall",
params: [
channel_call_id,
msg
]
});
} }
); );
}; };
// 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",
function methodCall(trans, v, transaction_id) {
local_transaction_dict[transaction_id] =
root_gadget[v[0]].apply(root_gadget, v[1]) root_gadget[v[0]].apply(root_gadget, v[1])
.push(trans.complete, .push(function handleMethodCallSuccess() {
function handleMethodCallError(e) { // drop the promise reference, to allow garbage collection
trans.error(e.toString()); delete local_transaction_dict[transaction_id];
trans.complete.apply(trans, arguments);
}, function handleMethodCallError(e) {
var error_type = convertObjectToErrorType(e),
message;
if (e instanceof Error) {
if (error_type !== unhandled_error_type) {
message = e.message;
} else {
message = e.toString();
}
} else {
message = e;
}
// drop the promise reference, to allow garbage collection
delete local_transaction_dict[transaction_id];
trans.error({
type: error_type,
msg: message
});
}); });
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) {
......
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