forked from extern/egroupware
Attempt of fixing legacy JavaScript functions, only tested for simple cases
This commit is contained in:
parent
d996537c35
commit
e4ed4399cf
@ -47,7 +47,7 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned, {
|
||||
},
|
||||
"onclick": {
|
||||
"name": "onclick",
|
||||
"type": "js",
|
||||
"type": "string",
|
||||
"description": "JS code which is executed when the element is clicked."
|
||||
}
|
||||
},
|
||||
@ -200,7 +200,7 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned, {
|
||||
if (this.node)
|
||||
{
|
||||
$j(this.node).bind("click.et2_baseWidget", this, function(e) {
|
||||
return e.data.click.call(e.data,e);
|
||||
return e.data.click.call(e.data, this);
|
||||
});
|
||||
}
|
||||
|
||||
@ -232,10 +232,10 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned, {
|
||||
return this.getDOMNode(this);
|
||||
},
|
||||
|
||||
click: function(event) {
|
||||
click: function(_node) {
|
||||
if (this.onclick)
|
||||
{
|
||||
return this.onclick.call(this, event);
|
||||
return this.onclick(_node);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -80,70 +80,6 @@ function et2_form_name(_cname,_name)
|
||||
return parts.length ? name + '['+parts.join('][')+']' : name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve javascript pseudo functions in onclick or onchange:
|
||||
* - egw::link('$l','$p') calls egw.link($l,$p)
|
||||
* - form::name('name') returns expanded name/id taking into account the name at that point of the template hierarchy
|
||||
* - egw::lang('Message ...') translate the message, calls egw.lang()
|
||||
* - confirm('message') translates 'message' and adds a '?' if not present
|
||||
* - window.open() replaces it with egw_openWindowCentered2()
|
||||
* - xajax_doXMLHTTP('etemplate. replace ajax calls in widgets with special handler not requiring etemplate run rights
|
||||
*
|
||||
* @param string _val onclick, onchange, ... action
|
||||
* @param string _cname name-prefix / name-space
|
||||
* @return string
|
||||
*/
|
||||
function et2_js_pseudo_funcs(_val, _cname)
|
||||
{
|
||||
|
||||
// TODO: Call et2 specific egw instance
|
||||
// Move this function to the API!
|
||||
|
||||
if (_val.indexOf('egw::link(') != -1)
|
||||
{
|
||||
_val = _val.replace(/egw::link\(/g,'egw.link(');
|
||||
}
|
||||
|
||||
if (_val.indexOf('form::name(') != -1)
|
||||
{
|
||||
_val = _val.replace(/form::name\(/g,_cname ? "et2_form_name('"+_cname+"'," : '(');
|
||||
}
|
||||
|
||||
if (_val.indexOf('egw::lang(') != -1)
|
||||
{
|
||||
_val = _val.replace(/egw::lang\(/g,'egw.lang(');
|
||||
}
|
||||
|
||||
// ToDo: inserts the styles of a named template
|
||||
/*if (preg_match('/template::styles\(["\']{1}(.*)["\']{1}\)/U',$on,$matches))
|
||||
{
|
||||
$tpl = $matches[1] == $this->name ? $this : new etemplate($matches[1]);
|
||||
$on = str_replace($matches[0],"'<style>".str_replace(array("\n","\r"),'',$tpl->style)."</style>'",$on);
|
||||
}*/
|
||||
|
||||
// translate messages in confirm()
|
||||
if (_val.indexOf('confirm(') != -1)
|
||||
{
|
||||
_val = _val.replace(/confirm\((['"])(.*?)(\?)?['"]\)/,"confirm(egw.lang($1$2$1)+'$3')"); // add ? if not there, saves extra phrase
|
||||
}
|
||||
|
||||
// replace window.open() with EGw's egw_openWindowCentered2()
|
||||
if (_val.indexOf('window.open(') != -1)
|
||||
{
|
||||
_val = _val.replace(/window.open\('(.*)','(.*)','dependent=yes,width=([^,]*),height=([^,]*),scrollbars=yes,status=(.*)'\)/,
|
||||
"egw_openWindowCentered2('$1', '$2', $3, $4, '$5')");
|
||||
}
|
||||
|
||||
// replace xajax calls to code in widgets, with the "etemplate" handler,
|
||||
// this allows to call widgets with the current app, otherwise everyone would need etemplate run rights
|
||||
if (_val.indexOf("xajax_doXMLHTTP('etemplate.") != -1)
|
||||
{
|
||||
_val = _val.replace(/^xajax_doXMLHTTP\('etemplate\.([a-z]+_widget\.[a-zA-Z0-9_]+)\'/,
|
||||
"xajax_doXMLHTTP('"+egw.getAppName()+".$1.etemplate'");
|
||||
}
|
||||
return _val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given value is of the given type. Strings are converted
|
||||
* into the corresponding type. The (converted) value is returned. All supported
|
||||
@ -193,50 +129,6 @@ function et2_checkType(_val, _type, _attr, _cname)
|
||||
return _err();
|
||||
}
|
||||
|
||||
if (_type == "js")
|
||||
{
|
||||
// Handle the default case
|
||||
if (_val === null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_val instanceof Function)
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
// Create a new function containing the code
|
||||
if (typeof _val == "string")
|
||||
{
|
||||
if (_val !== "")
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse JS code properly
|
||||
_val = et2_js_pseudo_funcs(_val, _cname);
|
||||
if(_val == "1") return function() {return true;};
|
||||
|
||||
// Check for remaining row data
|
||||
if(_val.indexOf("$") >= 0 || _val.indexOf("@") >= 0)
|
||||
{
|
||||
// Still needs parsing
|
||||
return _val;
|
||||
}
|
||||
return new Function(_val);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
egw.debug("error", "Error while parsing JS event handler code", e,_val);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return _err();
|
||||
}
|
||||
|
||||
// Check whether the given value is of the type "string"
|
||||
if (_type == "string")
|
||||
{
|
||||
|
@ -41,7 +41,7 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
||||
},
|
||||
"onchange": {
|
||||
"name": "onchange",
|
||||
"type": "js",
|
||||
"type": "string",
|
||||
"description": "JS code which is executed when the value changes."
|
||||
},
|
||||
"validation_error": {
|
||||
@ -113,7 +113,7 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
||||
change: function(_node) {
|
||||
if (this.onchange)
|
||||
{
|
||||
return this.onchange.apply(_node);
|
||||
return this.onchange(_node);
|
||||
}
|
||||
},
|
||||
|
||||
|
135
etemplate/js/et2_core_legacyJSFunctions.js
Normal file
135
etemplate/js/et2_core_legacyJSFunctions.js
Normal file
@ -0,0 +1,135 @@
|
||||
/**
|
||||
* eGroupWare eTemplate2 - A simple PHP expression parser written in JS
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package etemplate
|
||||
* @subpackage api
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stöckel
|
||||
* @copyright Stylite 2011
|
||||
* @version $Id: et2_core_phpExpressionCompiler.js 38256 2012-03-05 13:07:38Z igel457 $
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
et2_interfaces;
|
||||
et2_core_common;
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* Resolve javascript pseudo functions in onclick or onchange:
|
||||
* - egw::link('$l','$p') calls egw.link($l,$p)
|
||||
* - form::name('name') returns expanded name/id taking into account the name at that point of the template hierarchy
|
||||
* - egw::lang('Message ...') translate the message, calls egw.lang()
|
||||
* - confirm('message') translates 'message' and adds a '?' if not present
|
||||
* - window.open() replaces it with egw_openWindowCentered2()
|
||||
* - xajax_doXMLHTTP('etemplate. replace ajax calls in widgets with special handler not requiring etemplate run rights
|
||||
*
|
||||
* @param string _val onclick, onchange, ... action
|
||||
* @param string _cname name-prefix / name-space
|
||||
* @return string
|
||||
*/
|
||||
function js_pseudo_funcs(_val)
|
||||
{
|
||||
if (_val.indexOf('egw::link(') != -1)
|
||||
{
|
||||
_val = _val.replace(/egw::link\(/g,'egw.link(');
|
||||
}
|
||||
|
||||
if (_val.indexOf('form::name(') != -1)
|
||||
{
|
||||
// XXX Use the widget reference XXX
|
||||
//_val = _val.replace(/form::name\(/g,_cname ? "et2_form_name('"+_cname+"'," : '(');
|
||||
}
|
||||
|
||||
if (_val.indexOf('egw::lang(') != -1)
|
||||
{
|
||||
_val = _val.replace(/egw::lang\(/g,'egw.lang(');
|
||||
}
|
||||
|
||||
// ToDo: inserts the styles of a named template
|
||||
/*if (preg_match('/template::styles\(["\']{1}(.*)["\']{1}\)/U',$on,$matches))
|
||||
{
|
||||
$tpl = $matches[1] == $this->name ? $this : new etemplate($matches[1]);
|
||||
$on = str_replace($matches[0],"'<style>".str_replace(array("\n","\r"),'',$tpl->style)."</style>'",$on);
|
||||
}*/
|
||||
|
||||
// translate messages in confirm()
|
||||
if (_val.indexOf('confirm(') != -1)
|
||||
{
|
||||
_val = _val.replace(/confirm\((['"])(.*?)(\?)?['"]\)/,"confirm(egw.lang($1$2$1)+'$3')"); // add ? if not there, saves extra phrase
|
||||
}
|
||||
|
||||
// replace window.open() with EGw's egw_openWindowCentered2()
|
||||
if (_val.indexOf('window.open(') != -1)
|
||||
{
|
||||
_val = _val.replace(/window.open\('(.*)','(.*)','dependent=yes,width=([^,]*),height=([^,]*),scrollbars=yes,status=(.*)'\)/,
|
||||
"egw_openWindowCentered2('$1', '$2', $3, $4, '$5')");
|
||||
}
|
||||
|
||||
// replace xajax calls to code in widgets, with the "etemplate" handler,
|
||||
// this allows to call widgets with the current app, otherwise everyone would need etemplate run rights
|
||||
if (_val.indexOf("xajax_doXMLHTTP('etemplate.") != -1)
|
||||
{
|
||||
_val = _val.replace(/^xajax_doXMLHTTP\('etemplate\.([a-z]+_widget\.[a-zA-Z0-9_]+)\'/,
|
||||
"xajax_doXMLHTTP('"+egw.getAppName()+".$1.etemplate'");
|
||||
}
|
||||
return _val;
|
||||
}
|
||||
|
||||
this.et2_compileLegacyJS = function(_code, _widget, _context) {
|
||||
// Replace the javascript pseudo-functions
|
||||
_code = js_pseudo_funcs(_code);
|
||||
|
||||
// Check whether _code is simply "1" -- if yes replace it accordingly
|
||||
if (_code === '1')
|
||||
{
|
||||
_code = 'return true;';
|
||||
}
|
||||
|
||||
// Check whether some pseudo-variables still reside inside of the code,
|
||||
// if yes, replace them.
|
||||
if (_code.indexOf("$") >= 0 || _code.indexOf("@") >= 0)
|
||||
{
|
||||
// Get the content array manager for the widget
|
||||
var mgr = _widget.getArrayMgr("content");
|
||||
if (mgr)
|
||||
{
|
||||
_code = mgr.expandName(_code);
|
||||
}
|
||||
}
|
||||
|
||||
// Context is the context in which the function will run. Set context to
|
||||
// null as a default, so that it's possible to find bugs where "this" is
|
||||
// accessed in the code, but not properly set.
|
||||
var context = _context ? _context : null;
|
||||
|
||||
// Check whether the given widget implements the "et2_IDOMNode"
|
||||
// interface
|
||||
if (!context && _widget.implements(et2_IDOMNode))
|
||||
{
|
||||
context = _widget.getDOMNode();
|
||||
}
|
||||
|
||||
// Generate the function itself
|
||||
var func = new Function('egw', 'widget', 'window', _code);
|
||||
|
||||
// Execute the code and return its results, pass the egw instance and
|
||||
// the widget
|
||||
return function() {
|
||||
// Get the egw reference
|
||||
var egw = _widget.egw();
|
||||
|
||||
// Dump the executed code for debugging
|
||||
egw.debug('log', 'Executing legacy JS code: ', _code);
|
||||
|
||||
// Return the result of the called function
|
||||
return func.call(context, egw, _widget, egw.window);
|
||||
}
|
||||
}
|
||||
|
||||
}).call(window);
|
||||
|
@ -953,20 +953,11 @@ var et2_nextmatch_header_bar = Class.extend(et2_INextmatchHeader, {
|
||||
var input = select.input;
|
||||
if(this.nextmatch.options.settings[name+"_onchange"])
|
||||
{
|
||||
// Get the onchange function string
|
||||
var onchange = this.nextmatch.options.settings[name+"_onchange"];
|
||||
// onchange needs to get current values
|
||||
if(typeof onchange == "string") {
|
||||
// Don't change original so we can do this again
|
||||
onchange = et2_js_pseudo_funcs(onchange, this.nextmatch.id);
|
||||
if(onchange.indexOf("$") >= 0 || onchange.indexOf("@") >= 0) {
|
||||
var mgr = this.nextmatch.getArrayMgr("content");
|
||||
if(mgr) onchange = mgr.expandName(onchange);
|
||||
}
|
||||
onchange = new Function(onchange);
|
||||
}
|
||||
input.change(this.nextmatch, function(event) {
|
||||
onchange(event);
|
||||
});
|
||||
|
||||
// Connect it to the onchange event of the input element
|
||||
input.change(this.nextmatch, et2_compileLegacyJS(onchange, this.nextmatch, input));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ var et2_button = et2_baseWidget.extend([et2_IInput, et2_IDetachedDOM], {
|
||||
},
|
||||
"onclick": {
|
||||
"name": "onclick",
|
||||
"type": "js",
|
||||
"type": "string",
|
||||
"description": "JS code which gets executed when the button is clicked"
|
||||
}
|
||||
},
|
||||
@ -89,23 +89,12 @@ var et2_button = et2_baseWidget.extend([et2_IInput, et2_IDetachedDOM], {
|
||||
return this.btn ? this.btn[0] : null;
|
||||
},
|
||||
|
||||
onclick: function(e) {
|
||||
onclick: function(_node) {
|
||||
// Execute the JS code connected to the event handler
|
||||
if (this.options.onclick)
|
||||
{
|
||||
// onclick needs to get current values
|
||||
if(typeof this.options.onclick == "string") {
|
||||
// Don't change this.options.onclick so we can do this again
|
||||
var onclick = et2_js_pseudo_funcs(this.options.onclick, this.id);
|
||||
if(onclick.indexOf("$") >= 0 || onclick.indexOf("@") >= 0) {
|
||||
var mgr = this.getArrayMgr("content");
|
||||
if(mgr) onclick = mgr.expandName(onclick);
|
||||
}
|
||||
onclick = new Function(onclick);
|
||||
if(!onclick())
|
||||
return false;
|
||||
}
|
||||
else if (!this.options.onclick())
|
||||
// Exectute the legacy JS code
|
||||
if (!(et2_compileLegacyJS(this.options.onclick, this, _node))())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ var et2_progress = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
},
|
||||
"onchange": {
|
||||
"name": "onchange",
|
||||
"type": "js",
|
||||
"type": "string",
|
||||
"description": "JS code which is executed when the value changes."
|
||||
}
|
||||
},
|
||||
|
@ -42,6 +42,7 @@
|
||||
et2_core_xml;
|
||||
et2_core_arrayMgr;
|
||||
et2_core_interfaces;
|
||||
et2_core_legacyJSFunctions;
|
||||
|
||||
// Include the client side api core
|
||||
jsapi.egw_core;
|
||||
|
Loading…
Reference in New Issue
Block a user