Synchronized phpgwapi/js/jsapi, phpgwapi/js/egw_json.js and phpgwapi/inc/class.egw_json.inc.php with trunk

This commit is contained in:
Andreas Stöckel 2010-06-23 09:14:09 +00:00
parent b8309adec4
commit 8c0e4cce64
3 changed files with 266 additions and 97 deletions

View File

@ -184,9 +184,10 @@ class egw_json_response
*/
public function sendResult()
{
$this->sendHeader();
$inst = self::get();
echo $this->getJSON();
$inst->sendHeader();
echo $inst->getJSON();
}
/**
@ -202,7 +203,7 @@ class egw_json_response
*/
protected function addGeneric($key, $data)
{
$this->responseArray[] = array(
self::get()->responseArray[] = array(
'type' => $key,
'data' => $data,
);
@ -218,10 +219,11 @@ class egw_json_response
public function data($data)
{
/* Only allow adding the data response once */
if (!$this->hasData)
$inst = self::get();
if (!$inst->hasData)
{
$this->addGeneric('data', $data);
$this->hasData = true;
$inst->addGeneric('data', $data);
$inst->hasData = true;
}
else
{
@ -317,6 +319,8 @@ class egw_json_response
* Redirect to given url
*
* @param string $url
* @param boolean $global specifies whether to redirect the whole framework
* or only the current application
*/
public function redirect($url, $global = false)
{
@ -330,6 +334,43 @@ class egw_json_response
}
}
/**
* Displays an error message on the client
*/
public function error($msg)
{
if (is_string($msg))
{
$this->addGeneric('error', $msg);
}
}
/**
* Includes the given CSS file. Every url can only be included once.
*
* @param string $url specifies the url to the css file to include
*/
public function includeCSS($url)
{
if (is_string($url))
{
$this->addGeneric('css', $url);
}
}
/**
* Includes the given JS file. Every url can only be included once.
*
* @param string $url specifies the url to the css file to include
*/
public function includeScript($url)
{
if (is_string($url))
{
self::get()->addGeneric('js', $url);
}
}
/**
* Returns the actual JSON code generated by calling the above "add" function.
*
@ -337,8 +378,10 @@ class egw_json_response
*/
public function getJSON()
{
$inst = self::get();
/* Wrap the result array into a parent "response" Object */
$res = array('response' => $this->responseArray);
$res = array('response' => $inst->responseArray);
return json_encode($res); //PHP5.3+, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
}
@ -348,7 +391,9 @@ class egw_json_response
*/
public function __destruct()
{
$this->sendResult();
//Only send the response if this instance is the singleton instance
if ($this == self::get())
$this->sendResult();
}
}
@ -382,7 +427,17 @@ class egw_json_response
$args = func_get_args();
$func = array_shift($args);
$this->script("window['".$func."'].apply(window, ".json_encode($args).");");
$this->script("try{window['".$func."'].apply(window, ".json_encode($args).");} catch(e) {_egw_json_debug_log(e);}");
}
public function addIncludeCSS($url)
{
$this->includeCSS($url);
}
public function addIncludeScript($url)
{
$this->includeScript($url);
}
public function getXML()

View File

@ -116,15 +116,24 @@ function egw_json_encode(input)
}
/* The constructor of the egw_json_request class.
/**
* Some variables needed to store which JS and CSS files have already be included
*/
var egw_json_files = {};
/** The constructor of the egw_json_request class.
* @param string _menuaction the menuaction function which should be called and which handles the actual request
* @param array _parameters which should be passed to the menuaction function.
*/
function egw_json_request(_menuaction, _parameters)
*/
function egw_json_request(_menuaction, _parameters, _context)
{
//Copy the supplied parameters
this.menuaction = _menuaction;
this.context = window.document;
if (typeof _context != 'undefined')
this.context = _context;
if (typeof _parameters != 'undefined')
{
this.parameters = _parameters;
@ -187,7 +196,9 @@ egw_json_request.prototype.sendRequest = function(_async, _callback, _sender)
data: request_obj,
dataType: 'json',
type: 'POST',
success: this.handleResponse});
success: this.handleResponse,
error: function(_xmlhttp,_err) { alert('Ajax request to '+this.url+'?menuaction='+this.menuaction+' failed: '+_err); }
});
}
egw_json_request.prototype.alertFunc = function(_message, _details)
@ -195,14 +206,24 @@ egw_json_request.prototype.alertFunc = function(_message, _details)
alert(_message);
}
function _egw_json_debug_log(_msg)
function _egw_json_debug_log(_msg, _e)
{
if (typeof console != "undefined" && typeof console.log != "undefined")
{
console.log(_msg);
console.log(_msg, _e);
}
}
/* Displays an json error message */
egw_json_request.prototype.jsonError = function(_msg, _e)
{
var msg = 'EGW JSON Error: '._msg;
//Log and show the error message
_egw_json_bebug_log(msg, _e);
this.alertHandler(msg);
}
/* Internal function which handles the response from the server */
egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRequest)
{
@ -211,93 +232,152 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
var hasResponse = false;
for (var i = 0; i < data.response.length; i++)
{
var res = data.response[i];
switch (data.response[i].type)
try
{
case 'alert':
//Check whether all needed parameters have been passed and call the alertHandler function
if ((typeof res.data.message != 'undefined') &&
(typeof res.data.details != 'undefined'))
{
this.alertHandler(
res.data.message,
res.data.details)
hasResponse = true;
}
break;
case 'assign':
//Check whether all needed parameters have been passed and call the alertHandler function
if ((typeof res.data.id != 'undefined') &&
(typeof res.data.key != 'undefined') &&
(typeof res.data.value != 'undefined'))
{
var obj = document.getElementById(res.data.id);
if (obj)
var res = data.response[i];
switch (data.response[i].type)
{
case 'alert':
//Check whether all needed parameters have been passed and call the alertHandler function
if ((typeof res.data.message != 'undefined') &&
(typeof res.data.details != 'undefined'))
{
this.alertHandler(
res.data.message,
res.data.details)
hasResponse = true;
} else
throw 'Invalid parameters';
break;
case 'assign':
//Check whether all needed parameters have been passed and call the alertHandler function
if ((typeof res.data.id != 'undefined') &&
(typeof res.data.key != 'undefined') &&
(typeof res.data.value != 'undefined'))
{
var obj = document.getElementById(res.data.id);
if (obj)
{
obj[res.data.key] = res.data.value;
hasResponse = true;
}
} else
throw 'Invalid parameters';
break;
case 'data':
//Callback the caller in order to allow him to handle the data
if (this.callback)
{
obj[res.data.key] = res.data.value;
this.callback.call(this.sender, res.data);
hasResponse = true;
}
}
break;
case 'data':
//Callback the caller in order to allow him to handle the data
if (this.callback)
{
this.callback.call(this.sender, res.data);
hasResponse = true;
}
break;
case 'script':
if (typeof res.data == 'string')
{
try
break;
case 'script':
if (typeof res.data == 'string')
{
var func = function() {eval(res.data);};
func.call(window);
}
catch (e)
try
{
var func = function() {eval(res.data);};
func.call(window);
}
catch (e)
{
e.code = res.data;
_egw_json_debug_log(e);
}
hasResponse = true;
} else
throw 'Invalid parameters';
break;
case 'jquery':
if (typeof res.data.select == 'string' &&
typeof res.data.func == 'string')
{
e.code = res.data;
_egw_json_debug_log(e);
}
hasResponse = true;
}
break;
case 'jquery':
if (typeof res.data.select == 'string' &&
typeof res.data.func == 'string')
{
try
try
{
var jQueryObject = $(res.data.select, this.context);
jQueryObject[res.data.func].apply(jQueryObject, res.data.parms);
}
catch (e)
{
_egw_json_debug_log(e);
}
hasResponse = true;
} else
throw 'Invalid parameters';
break;
case 'redirect':
if (typeof res.data.url == 'string' &&
typeof res.data.global == 'boolean')
{
var jQueryObject = $(res.data.select);
jQueryObject[res.data.func].apply(jQueryObject, res.data.parms);
}
catch (e)
{
_egw_json_debug_log(e);
}
hasResponse = true;
}
break;
case 'redirect':
if (typeof res.data.url == 'string' &&
typeof res.data.global == 'boolean')
{
//Special handling for framework reload
if (res.data.url.indexOf("?cd=10") > 0)
res.data.global = true;
//Special handling for framework reload
if (res.data.url.indexOf("?cd=10") > 0)
res.data.global = true;
if (res.data.global)
if (res.data.global)
{
egw_topWindow().location.href = res.data.url;
}
else
{
window.location.href = res.data.url;
}
hasResponse = true;
} else
throw 'Invalid parameters';
break;
case 'css':
if (typeof res.data == 'string')
{
egw_topWindow().location.href = res.data.url;
}
else
//Check whether the requested file had already be included
if (!egw_json_files[res.data])
{
egw_json_files[res.data] = true;
//Get the head node and append a new link node with the stylesheet url to it
var headID = document.getElementsByTagName('head')[0];
var cssnode = document.createElement('link');
cssnode.type = "text/css";
cssnode.rel = "stylesheet";
cssnode.href = res.data;
headID.appendChild(cssnode);
}
hasResponse = true;
} else
throw 'Invalid parameters';
break;
case 'js':
if (typeof res.data == 'string')
{
window.location.href = res.data.url;
}
}
break;
//Check whether the requested file had already be included
if (!egw_json_files[res.data])
{
egw_json_files[res.data] = true;
//Get the head node and append a new script node with the js file to it
var headID = document.getElementsByTagName('head')[0];
var scriptnode = document.createElement('script');
scriptnode.type = "text/javascript";
scriptnode.src = res.data;
headID.appendChild(scriptnode);
}
hasResponse = true;
} else
throw 'Invalid parameters';
break;
case 'error':
if (typeof res.data == 'string')
{
this.jsonError(res.data);
hasResponse = true;
} else
throw 'Invalid parameters';
break;
}
} catch(e) {
this.jsonError('Internal JSON handler error', e);
}
}

View File

@ -39,19 +39,53 @@ else if (document.layers)
is_ns4 = true;
}
/**
* Seperates all script tags from the given html code and returns the seperately
* @param object _html object that the html code from which the script should be seperated. The html code has to be stored in _html.html, the result js will be written to _html.js
*/
egw_seperateJavaScript = function(_html)
{
var html = _html.html;
var in_pos = html.search(/<script/im);
var out_pos = html.search(/<\/script>/im);
while (in_pos > -1 && out_pos > -1)
{
/*Seperate the whole <script...</script> tag */
var js_str = html.substring(in_pos, out_pos+9);
/*Remove the initial tag */
/*js_str = js_str.substring(js_str.search(/>/) + 1);*/
_html.js += js_str;
html = html.substring(0, in_pos) + html.substring(out_pos + 9);
var in_pos = html.search(/<script/im);
var out_pos = html.search(/<\/script>/im);
}
_html.html = html;
}
/**
* Returns the top window which contains the current egw_instance, even for popup windows
*/
function egw_topWindow()
{
if (window.opener)
if (typeof window.parent != "undefined" && typeof window.parent.top != "undefined")
{
return window.parent.top;
}
if (typeof window.opener != "undefined" && typeof window.opener.top != "undefined")
{
return window.opener.top;
}
else
{
return window.top;
}
return window.top;
}
/**