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 @@
obj[pathItems[pathItems.length - 1]] = (function() {
var cbName = path;
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);
} catch(e) {
// automagic handling of exceptions:
......@@ -580,6 +580,8 @@
s_curTranId++;
postMessage(msg);
// return the transaction id
return s_curTranId - 1;
},
notify: function(m) {
if (!m) throw 'missing arguments to notify function';
......@@ -779,6 +781,19 @@ if (typeof document.contains !== 'function') {
ScopeError.prototype = new Error();
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) {
var result;
try {
......@@ -818,18 +833,18 @@ if (typeof document.contains !== 'function') {
prevent_default = true;
}
function cancelResolver() {
function cancelResolver(msg) {
if ((callback_promise !== undefined) &&
(typeof callback_promise.cancel === "function")) {
callback_promise.cancel();
callback_promise.cancel(msg);
}
}
function canceller() {
function canceller(msg) {
if (handle_event_callback !== undefined) {
target.removeEventListener(type, handle_event_callback, useCapture);
}
cancelResolver();
cancelResolver(msg);
}
function itsANonResolvableTrap(resolve, reject) {
var result;
......@@ -839,7 +854,9 @@ if (typeof document.contains !== 'function') {
evt.preventDefault();
}
cancelResolver();
cancelResolver(
"Cancelling previous event (" + evt.type + ")"
);
try {
result = callback(evt);
......@@ -851,7 +868,7 @@ if (typeof document.contains !== 'function') {
.push(undefined, function handleEventCallbackError(error) {
// Prevent rejecting the loop, if the result cancelled itself
if (!(error instanceof RSVP.CancellationError)) {
canceller();
canceller(error.toString());
reject(error);
}
});
......@@ -926,6 +943,7 @@ if (typeof document.contains !== 'function') {
isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'),
is_page_unloaded = false,
error_list = [],
unhandled_error_type = 0,
all_dependency_loaded_deferred;
window.addEventListener('error', function handleGlobalError(error) {
......@@ -975,6 +993,40 @@ if (typeof document.contains !== 'function') {
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) {
var i,
body,
......@@ -1112,11 +1164,11 @@ if (typeof document.contains !== 'function') {
return new Monitor();
}
function canceller() {
function canceller(msg) {
var len = promise_list.length,
i;
for (i = 0; i < len; i += 1) {
promise_list[i].cancel();
promise_list[i].cancel(msg);
}
// Clean it to speed up other canceller run
promise_list = [];
......@@ -1130,17 +1182,17 @@ if (typeof document.contains !== 'function') {
monitor.isRejected = true;
monitor.rejectedReason = rejectedReason;
resolved = true;
canceller();
canceller(rejectedReason.toString());
return fail(rejectedReason);
};
}, canceller);
monitor.cancel = function cancelMonitor() {
monitor.cancel = function cancelMonitor(msg) {
if (resolved) {
return;
}
resolved = true;
promise.cancel();
promise.cancel(msg);
promise.fail(function rejectMonitorPromise(rejectedReason) {
monitor.isRejected = true;
monitor.rejectedReason = rejectedReason;
......@@ -1199,7 +1251,11 @@ if (typeof document.contains !== 'function') {
function deleteGadgetMonitor(g) {
if (g.hasOwnProperty('__monitor')) {
g.__monitor.cancel();
g.__monitor.cancel(
"Deleting Gadget Monitor " + "(" +
g.element.dataset.gadgetUrl +
")"
);
delete g.__monitor;
g.__job_list = [];
}
......@@ -1324,7 +1380,7 @@ if (typeof document.contains !== 'function') {
function runJob(gadget, name, callback, argument_list) {
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);
gadget.__job_dict[name] = job_promise;
......@@ -1686,6 +1742,7 @@ if (typeof document.contains !== 'function') {
old_element) {
var gadget_instance,
iframe,
transaction_dict = {},
iframe_loading_deferred = RSVP.defer();
if (old_element === undefined) {
throw new Error("DOM element is required to create Iframe Gadget " +
......@@ -1740,15 +1797,29 @@ if (typeof document.contains !== 'function') {
function handleChannelDeclareMethod(trans, method_name) {
gadget_instance[method_name] = function triggerChannelDeclareMethod() {
var argument_list = arguments,
channel_call_id,
wait_promise = new RSVP.Promise(
function handleChannelCall(resolve, reject) {
gadget_instance.__chan.call({
function errorWrap(value) {
return rejectErrorType(value, reject);
}
channel_call_id = gadget_instance.__chan.call({
method: "methodCall",
params: [
method_name,
Array.prototype.slice.call(argument_list, 0)],
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') {
iframe_loading_deferred.reject(params);
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",
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()
.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) {
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);
});
......@@ -2303,6 +2404,7 @@ if (typeof document.contains !== 'function') {
/////////////////////////////////////////////////////////////////
renderJS.Mutex = Mutex;
renderJS.ScopeError = ScopeError;
renderJS.IframeSerializationError = IframeSerializationError;
renderJS.loopEventListener = loopEventListener;
window.rJS = window.renderJS = renderJS;
window.__RenderJSGadget = RenderJSGadget;
......@@ -2601,36 +2703,82 @@ if (typeof document.contains !== 'function') {
function finishAqParentConfiguration(TmpConstructor, root_gadget,
embedded_channel) {
var local_transaction_dict = {};
// Define __aq_parent to inform parent window
root_gadget.__aq_parent =
TmpConstructor.prototype.__aq_parent = function aq_parent(method_name,
argument_list,
time_out) {
var channel_call_id;
return new RSVP.Promise(
function waitForChannelAcquire(resolve, reject) {
embedded_channel.call({
function errorWrap(value) {
return rejectErrorType(value, reject);
}
channel_call_id = embedded_channel.call({
method: "acquire",
params: [
method_name,
argument_list
Array.prototype.slice.call(argument_list, 0)
],
success: resolve,
error: reject,
error: errorWrap,
timeout: time_out
});
},
function cancelChannelCall(msg) {
embedded_channel.notify({
method: "cancelAcquiredMethodCall",
params: [
channel_call_id,
msg
]
});
}
);
};
// bind calls to renderJS method on the instance
embedded_channel.bind("methodCall", function methodCall(trans, v) {
root_gadget[v[0]].apply(root_gadget, v[1])
.push(trans.complete,
function handleMethodCallError(e) {
trans.error(e.toString());
embedded_channel.bind("methodCall",
function methodCall(trans, v, transaction_id) {
local_transaction_dict[transaction_id] =
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) {
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) {
......@@ -2688,4 +2836,4 @@ if (typeof document.contains !== 'function') {
);
}(document, window, RSVP, DOMParser, Channel, MutationObserver, Node,
FileReader, Blob, navigator, Event, URL));
FileReader, Blob, navigator, Event, URL));
\ No newline at end of file
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>989.27523.29749.43383</string> </value>
<value> <string>996.23761.26725.45789</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1613141629.7</float>
<float>1641216662.48</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -379,12 +379,12 @@
obj[pathItems[pathItems.length - 1]] = (function() {
var cbName = path;
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);
} catch(e) {
// automagic handling of exceptions:
......@@ -580,6 +580,8 @@
s_curTranId++;
postMessage(msg);
// return the transaction id
return s_curTranId - 1;
},
notify: function(m) {
if (!m) throw 'missing arguments to notify function';
......@@ -779,6 +781,19 @@ if (typeof document.contains !== 'function') {
ScopeError.prototype = new Error();
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) {
var result;
try {
......@@ -818,18 +833,18 @@ if (typeof document.contains !== 'function') {
prevent_default = true;
}
function cancelResolver() {
function cancelResolver(msg) {
if ((callback_promise !== undefined) &&
(typeof callback_promise.cancel === "function")) {
callback_promise.cancel();
callback_promise.cancel(msg);
}
}
function canceller() {
function canceller(msg) {
if (handle_event_callback !== undefined) {
target.removeEventListener(type, handle_event_callback, useCapture);
}
cancelResolver();
cancelResolver(msg);
}
function itsANonResolvableTrap(resolve, reject) {
var result;
......@@ -839,7 +854,9 @@ if (typeof document.contains !== 'function') {
evt.preventDefault();
}
cancelResolver();
cancelResolver(
"Cancelling previous event (" + evt.type + ")"
);
try {
result = callback(evt);
......@@ -851,7 +868,7 @@ if (typeof document.contains !== 'function') {
.push(undefined, function handleEventCallbackError(error) {
// Prevent rejecting the loop, if the result cancelled itself
if (!(error instanceof RSVP.CancellationError)) {
canceller();
canceller(error.toString());
reject(error);
}
});
......@@ -926,6 +943,7 @@ if (typeof document.contains !== 'function') {
isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'),
is_page_unloaded = false,
error_list = [],
unhandled_error_type = 0,
all_dependency_loaded_deferred;
window.addEventListener('error', function handleGlobalError(error) {
......@@ -975,6 +993,40 @@ if (typeof document.contains !== 'function') {
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) {
var i,
body,
......@@ -1112,11 +1164,11 @@ if (typeof document.contains !== 'function') {
return new Monitor();
}
function canceller() {
function canceller(msg) {
var len = promise_list.length,
i;
for (i = 0; i < len; i += 1) {
promise_list[i].cancel();
promise_list[i].cancel(msg);
}
// Clean it to speed up other canceller run
promise_list = [];
......@@ -1130,17 +1182,17 @@ if (typeof document.contains !== 'function') {
monitor.isRejected = true;
monitor.rejectedReason = rejectedReason;
resolved = true;
canceller();
canceller(rejectedReason.toString());
return fail(rejectedReason);
};
}, canceller);
monitor.cancel = function cancelMonitor() {
monitor.cancel = function cancelMonitor(msg) {
if (resolved) {
return;
}
resolved = true;
promise.cancel();
promise.cancel(msg);
promise.fail(function rejectMonitorPromise(rejectedReason) {
monitor.isRejected = true;
monitor.rejectedReason = rejectedReason;
......@@ -1199,7 +1251,11 @@ if (typeof document.contains !== 'function') {
function deleteGadgetMonitor(g) {
if (g.hasOwnProperty('__monitor')) {
g.__monitor.cancel();
g.__monitor.cancel(
"Deleting Gadget Monitor " + "(" +
g.element.dataset.gadgetUrl +
")"
);
delete g.__monitor;
g.__job_list = [];
}
......@@ -1324,7 +1380,7 @@ if (typeof document.contains !== 'function') {
function runJob(gadget, name, callback, argument_list) {
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);
gadget.__job_dict[name] = job_promise;
......@@ -1686,6 +1742,7 @@ if (typeof document.contains !== 'function') {
old_element) {
var gadget_instance,
iframe,
transaction_dict = {},
iframe_loading_deferred = RSVP.defer();
if (old_element === undefined) {
throw new Error("DOM element is required to create Iframe Gadget " +
......@@ -1740,15 +1797,29 @@ if (typeof document.contains !== 'function') {
function handleChannelDeclareMethod(trans, method_name) {
gadget_instance[method_name] = function triggerChannelDeclareMethod() {
var argument_list = arguments,
channel_call_id,
wait_promise = new RSVP.Promise(
function handleChannelCall(resolve, reject) {
gadget_instance.__chan.call({
function errorWrap(value) {
return rejectErrorType(value, reject);
}
channel_call_id = gadget_instance.__chan.call({
method: "methodCall",
params: [
method_name,
Array.prototype.slice.call(argument_list, 0)],
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') {
iframe_loading_deferred.reject(params);
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",
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()
.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) {
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);
});
......@@ -2303,6 +2404,7 @@ if (typeof document.contains !== 'function') {
/////////////////////////////////////////////////////////////////
renderJS.Mutex = Mutex;
renderJS.ScopeError = ScopeError;
renderJS.IframeSerializationError = IframeSerializationError;
renderJS.loopEventListener = loopEventListener;
window.rJS = window.renderJS = renderJS;
window.__RenderJSGadget = RenderJSGadget;
......@@ -2601,36 +2703,82 @@ if (typeof document.contains !== 'function') {
function finishAqParentConfiguration(TmpConstructor, root_gadget,
embedded_channel) {
var local_transaction_dict = {};
// Define __aq_parent to inform parent window
root_gadget.__aq_parent =
TmpConstructor.prototype.__aq_parent = function aq_parent(method_name,
argument_list,
time_out) {
var channel_call_id;
return new RSVP.Promise(
function waitForChannelAcquire(resolve, reject) {
embedded_channel.call({
function errorWrap(value) {
return rejectErrorType(value, reject);
}
channel_call_id = embedded_channel.call({
method: "acquire",
params: [
method_name,
argument_list
Array.prototype.slice.call(argument_list, 0)
],
success: resolve,
error: reject,
error: errorWrap,
timeout: time_out
});
},
function cancelChannelCall(msg) {
embedded_channel.notify({
method: "cancelAcquiredMethodCall",
params: [
channel_call_id,
msg
]
});
}
);
};
// bind calls to renderJS method on the instance
embedded_channel.bind("methodCall", function methodCall(trans, v) {
root_gadget[v[0]].apply(root_gadget, v[1])
.push(trans.complete,
function handleMethodCallError(e) {
trans.error(e.toString());
embedded_channel.bind("methodCall",
function methodCall(trans, v, transaction_id) {
local_transaction_dict[transaction_id] =
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) {
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) {
......@@ -2688,4 +2836,4 @@ if (typeof document.contains !== 'function') {
);
}(document, window, RSVP, DOMParser, Channel, MutationObserver, Node,
FileReader, Blob, navigator, Event, URL));
FileReader, Blob, navigator, Event, URL));
\ No newline at end of file
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