IE JSON-serializes arrays passed in from different window contextx (eg. popups) as objects (it looses object-type of array), causing them to be JSON serialized as objects and loosing parameters which are undefined

JSON.strigify([123,undefined]) --> "{0:123}" instead of "[123,null]"
This commit is contained in:
Ralf Becker 2015-08-31 12:21:11 +00:00
parent a96d7d50be
commit 284ffa7f13
3 changed files with 29 additions and 25 deletions

View File

@ -68,7 +68,7 @@ class egw_json_request
{ {
$responses = array(); $responses = array();
$response = egw_json_response::get(); $response = egw_json_response::get();
foreach($parameters as $uid => $data) foreach($parameters[0] as $uid => $data)
{ {
//error_log("$uid: menuaction=$data[menuaction], parameters=".array2string($data['parameters'])); //error_log("$uid: menuaction=$data[menuaction], parameters=".array2string($data['parameters']));
$this->handleRequest($data['menuaction'], (array)$data['parameters']); $this->handleRequest($data['menuaction'], (array)$data['parameters']);
@ -158,9 +158,8 @@ class egw_json_request
// they are already loaded, in fact jquery has a problem if loaded twice // they are already loaded, in fact jquery has a problem if loaded twice
egw_framework::js_files(array()); egw_framework::js_files(array());
$parameters = translation::convert($parameters, 'utf-8'); call_user_func_array(array($ajaxClass, $functionName),
translation::convert($parameters, 'utf-8'));
call_user_func_array(array($ajaxClass, $functionName), $parameters);
// check if we have push notifications, if notifications app available // check if we have push notifications, if notifications app available
if (class_exists('notifications_push')) notifications_push::get(); if (class_exists('notifications_push')) notifications_push::get();
@ -688,7 +687,7 @@ class xajaxResponse
return call_user_func_array(array(egw_json_response::get(), $name), $args); return call_user_func_array(array(egw_json_response::get(), $name), $args);
} }
public function addScriptCall($func) public function addScriptCall()
{ {
$args = func_get_args(); $args = func_get_args();
$func = array_shift($args); $func = array_shift($args);

View File

@ -47,7 +47,11 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd) {
{ {
// Copy the parameters // Copy the parameters
this.url = _egw.ajaxUrl(_menuaction); this.url = _egw.ajaxUrl(_menuaction);
this.parameters = _parameters ? _parameters : []; // IE JSON-serializes arrays passed in from different window contextx (eg. popups)
// as objects (it looses object-type of array), causing them to be JSON serialized
// as objects and loosing parameters which are undefined
// JSON.strigify([123,undefined]) --> '{"0":123}' instead of '[123,null]'
this.parameters = _parameters ? [].concat(_parameters) : [];
this.async = _async ? _async : false; this.async = _async ? _async : false;
this.callback = _callback ? _callback : null; this.callback = _callback ? _callback : null;
this.context = _context ? _context : null; this.context = _context ? _context : null;

View File

@ -17,11 +17,11 @@
egw_debug; egw_debug;
*/ */
egw.extend('jsonq', egw.MODULE_GLOBAL, function() { egw.extend('jsonq', egw.MODULE_GLOBAL, function()
{
/** /**
* Queued json requests (objects with attributes menuaction, parameters, context, callback, sender and callbeforesend) * Queued json requests (objects with attributes menuaction, parameters, context, callback, sender and callbeforesend)
* *
* @access private, use jsonq method to queue requests * @access private, use jsonq method to queue requests
*/ */
var jsonq_queue = {}; var jsonq_queue = {};
@ -38,13 +38,13 @@ egw.extend('jsonq', egw.MODULE_GLOBAL, function() {
/** /**
* Dispatch responses received * Dispatch responses received
* *
* @param object _data uid => response pairs * @param {object} _data uid => response pairs
*/ */
function jsonq_callback(_data) function jsonq_callback(_data)
{ {
if (typeof _data != 'object') throw "jsonq_callback called with NO object as parameter!"; if (typeof _data != 'object') throw "jsonq_callback called with NO object as parameter!";
// Abort if type is set (multi-response support) // Abort if type is set (multi-response support)
if (typeof _data.type != 'undefined') return; if (typeof _data.type != 'undefined') return;
@ -59,7 +59,7 @@ egw.extend('jsonq', egw.MODULE_GLOBAL, function() {
} }
var job = jsonq_queue[uid]; var job = jsonq_queue[uid];
var response = _data[uid]; var response = _data[uid];
// fake egw.json_request object, to call it with the current response // fake egw.json_request object, to call it with the current response
json.callback = job.callback; json.callback = job.callback;
json.sender = job.sender; json.sender = job.sender;
@ -106,7 +106,7 @@ egw.extend('jsonq', egw.MODULE_GLOBAL, function() {
if (something_to_send) if (something_to_send)
{ {
// TODO: Passing this to the "home" application looks quite ugly // TODO: Passing this to the "home" application looks quite ugly
var request = egw.json('home.queue', jobs_to_send, jsonq_callback, this) var request = egw.json('home.queue', jobs_to_send, jsonq_callback, this);
request.sendRequest(true); request.sendRequest(true);
} }
} }
@ -115,14 +115,14 @@ egw.extend('jsonq', egw.MODULE_GLOBAL, function() {
return { return {
/** /**
* Send a queued JSON call to the server * Send a queued JSON call to the server
* *
* @param string _menuaction the menuaction function which should be called and * @param {string} _menuaction the menuaction function which should be called and
* which handles the actual request. If the menuaction is a full featured * which handles the actual request. If the menuaction is a full featured
* url, this one will be used instead. * url, this one will be used instead.
* @param array _parameters which should be passed to the menuaction function. * @param {array} _parameters which should be passed to the menuaction function.
* @param function _callback callback function which should be called upon a "data" response is received * @param  {function} _callback callback function which should be called upon a "data" response is received
* @param object _sender is the reference object the callback function should get * @param {object} _sender is the reference object the callback function should get
* @param function _callbeforesend optional callback function which can modify the parameters, eg. to do some own queuing * @param {function} _callbeforesend optional callback function which can modify the parameters, eg. to do some own queuing
* @return string uid of the queued request * @return string uid of the queued request
*/ */
jsonq: function(_menuaction, _parameters, _callback, _sender, _callbeforesend) jsonq: function(_menuaction, _parameters, _callback, _sender, _callbeforesend)
@ -130,12 +130,16 @@ egw.extend('jsonq', egw.MODULE_GLOBAL, function() {
var uid = 'u'+(jsonq_uid++); var uid = 'u'+(jsonq_uid++);
jsonq_queue[uid] = { jsonq_queue[uid] = {
menuaction: _menuaction, menuaction: _menuaction,
parameters: _parameters, // IE JSON-serializes arrays passed in from different window contextx (eg. popups)
// as objects (it looses object-type of array), causing them to be JSON serialized
// as objects and loosing parameters which are undefined
// JSON.strigify([123,undefined]) --> '{"0":123}' instead of '[123,null]'
parameters: _parameters ? [].concat(_parameters) : [],
callback: _callback, callback: _callback,
sender: _sender, sender: _sender,
callbeforesend: _callbeforesend callbeforesend: _callbeforesend
}; };
if (jsonq_timer == null) if (jsonq_timer == null)
{ {
// check / send queue every N ms // check / send queue every N ms
@ -148,7 +152,4 @@ egw.extend('jsonq', egw.MODULE_GLOBAL, function() {
} }
}; };
}); });