mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 17:33:49 +01:00
Client side API now supports modules which are instanciated per application or per window; removed et2_debug function from et2_core_common, now using corresponding API function.
This commit is contained in:
parent
a5be6a5016
commit
d310b14ecf
@ -35,7 +35,7 @@ var et2_arrayMgr = Class.extend({
|
||||
// Hold a reference to the data
|
||||
if (typeof _data == "undefined" || !_data)
|
||||
{
|
||||
et2_debug("error", "Invalid data passed to content array manager!");
|
||||
egw.debug("error", "Invalid data passed to content array manager!");
|
||||
_data = {};
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ var et2_arrayMgr = Class.extend({
|
||||
catch(e)
|
||||
{
|
||||
proto.compiledExpressions[_ident] = null;
|
||||
et2_debug("error", "Error while compiling PHP->JS ", e);
|
||||
egw.debug("error", "Error while compiling PHP->JS ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ var et2_arrayMgr = Class.extend({
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
et2_debug("error", e);
|
||||
egw.debug("error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,49 +27,6 @@ if (typeof Array.prototype.indexOf == "undefined")
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* ET2_DEBUGLEVEL specifies which messages are printed to the console. Decrease
|
||||
* the value of ET2_DEBUGLEVEL to get less messages.
|
||||
*/
|
||||
var ET2_DEBUGLEVEL = 4;
|
||||
|
||||
function et2_debug(_level)
|
||||
{
|
||||
if (typeof console != "undefined")
|
||||
{
|
||||
// Get the passed parameters and remove the first entry
|
||||
var args = [];
|
||||
for (var i = 1; i < arguments.length; i++)
|
||||
{
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
|
||||
if (_level == "log" && ET2_DEBUGLEVEL >= 4 &&
|
||||
typeof console.log == "function")
|
||||
{
|
||||
console.log.apply(console, args);
|
||||
}
|
||||
|
||||
if (_level == "info" && ET2_DEBUGLEVEL >= 3 &&
|
||||
typeof console.info == "function")
|
||||
{
|
||||
console.info.apply(console, args);
|
||||
}
|
||||
|
||||
if (_level == "warn" && ET2_DEBUGLEVEL >= 2 &&
|
||||
typeof console.warn == "function")
|
||||
{
|
||||
console.warn.apply(console, args);
|
||||
}
|
||||
|
||||
if (_level == "error" && ET2_DEBUGLEVEL >= 1 &&
|
||||
typeof console.error == "function")
|
||||
{
|
||||
console.error.apply(console, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array with all types supported by the et2_checkType function.
|
||||
*/
|
||||
@ -202,7 +159,7 @@ function et2_checkType(_val, _type, _attr, _cname)
|
||||
function _err() {
|
||||
var res = et2_typeDefaults[_type];
|
||||
|
||||
et2_debug("warn", "'" + _val + "' was not of specified _type '" +
|
||||
egw.debug("warn", "'" + _val + "' was not of specified _type '" +
|
||||
_type + (_attr != null ? "' for attribute '" + _attr + "' " : "") +
|
||||
"and is now '" + res + "'");
|
||||
|
||||
@ -270,7 +227,7 @@ function et2_checkType(_val, _type, _attr, _cname)
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
et2_debug("error", "Error while parsing JS event handler code", e,_val);
|
||||
egw.debug("error", "Error while parsing JS event handler code", e,_val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -380,7 +337,7 @@ function et2_validateAttrib(_id, _attrib)
|
||||
if (typeof _attrib["name"] == "undefined")
|
||||
{
|
||||
_attrib["name"] = _id;
|
||||
et2_debug("log", "Human name ('name'-Field) for attribute '" +
|
||||
egw.debug("log", "Human name ('name'-Field) for attribute '" +
|
||||
_id + "' has not been supplied, set to '" + _id + "'");
|
||||
console.debug(_attrib);
|
||||
}
|
||||
@ -388,7 +345,7 @@ console.debug(_attrib);
|
||||
if (typeof _attrib["description"] == "undefined")
|
||||
{
|
||||
_attrib["description"] = "";
|
||||
et2_debug("log", "Description for attribute '" +
|
||||
egw.debug("log", "Description for attribute '" +
|
||||
_id + "' has not been supplied");
|
||||
}
|
||||
|
||||
@ -400,7 +357,7 @@ console.debug(_attrib);
|
||||
{
|
||||
if (et2_validTypes.indexOf(_attrib["type"]) < 0)
|
||||
{
|
||||
et2_debug("error", "Invalid type for attribute '" + _id +
|
||||
egw.debug("error", "Invalid type for attribute '" + _id +
|
||||
"' supplied.");
|
||||
}
|
||||
}
|
||||
@ -655,7 +612,7 @@ function et2_insertLinkText(_text, _node, _target)
|
||||
{
|
||||
if(!_node)
|
||||
{
|
||||
et2_debug("warn", "et2_insertLinkText called without node", _text, _node, _target);
|
||||
egw.debug("warn", "et2_insertLinkText called without node", _text, _node, _target);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -677,7 +634,7 @@ function et2_insertLinkText(_text, _node, _target)
|
||||
{
|
||||
if(!s.href)
|
||||
{
|
||||
et2_debug("warn", "et2_activateLinks gave bad data", s, _node, _target);
|
||||
egw.debug("warn", "et2_activateLinks gave bad data", s, _node, _target);
|
||||
s.href = "";
|
||||
}
|
||||
var a = $j(document.createElement("a"))
|
||||
|
@ -273,7 +273,7 @@
|
||||
"created": new Date().getTime(),
|
||||
"class": className
|
||||
}
|
||||
et2_debug("log", "*" + this.__OBJ_UID + " (" + className + ")");
|
||||
egw.debug("log", "*" + this.__OBJ_UID + " (" + className + ")");
|
||||
}
|
||||
|
||||
if (this.init)
|
||||
@ -323,7 +323,7 @@
|
||||
if (getMem_freeMem_trace)
|
||||
{
|
||||
delete(tracedObjects[this.__OBJ_UID]);
|
||||
et2_debug("log", "-" + this.__OBJ_UID);
|
||||
egw.debug("log", "-" + this.__OBJ_UID);
|
||||
}
|
||||
|
||||
// Delete every object entry
|
||||
@ -382,7 +382,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("error", this, "Attribute '" + _name + "' does not exist!");
|
||||
egw.debug("error", this, "Attribute '" + _name + "' does not exist!");
|
||||
}
|
||||
};
|
||||
|
||||
@ -417,7 +417,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("warn", this, "Attribute '" + _name + "' does not exist!");
|
||||
egw.debug("warn", this, "Attribute '" + _name + "' does not exist!");
|
||||
}
|
||||
};
|
||||
|
||||
@ -445,7 +445,7 @@
|
||||
{
|
||||
// Key does not exist - delete it and issue a warning
|
||||
delete(_attrs[key]);
|
||||
et2_debug("warn", this, "Attribute '" + key +
|
||||
egw.debug("warn", this, "Attribute '" + key +
|
||||
"' does not exist in " + _attrs.type+"!");
|
||||
}
|
||||
}
|
||||
|
@ -403,7 +403,7 @@
|
||||
var js = _php_compileJSCode(_vars, syntaxTree);
|
||||
|
||||
// Log the successfull compiling
|
||||
et2_debug("log", "Compiled PHP " + _expr + " --> " + js);
|
||||
egw.debug("log", "Compiled PHP " + _expr + " --> " + js);
|
||||
|
||||
// Prepate the attributes for the function constuctor
|
||||
var attrs = [];
|
||||
|
@ -41,7 +41,7 @@ function et2_register_widget(_constructor, _types)
|
||||
// types.
|
||||
if (et2_registry[type])
|
||||
{
|
||||
et2_debug("warn", "Widget class registered for " + type +
|
||||
egw.debug("warn", "Widget class registered for " + type +
|
||||
" will be overwritten.");
|
||||
}
|
||||
|
||||
@ -272,7 +272,7 @@ var et2_widget = Class.extend({
|
||||
assign: function(_obj) {
|
||||
if (typeof _obj._children == "undefined")
|
||||
{
|
||||
et2_debug("log", "Foo!");
|
||||
this.egw().debug("log", "Foo!");
|
||||
}
|
||||
|
||||
// Create a clone of all child elements of the given object
|
||||
@ -345,7 +345,7 @@ var et2_widget = Class.extend({
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("error", this, "Widget is not supported by this widget class", _node);
|
||||
this.egw().debug("error", this, "Widget is not supported by this widget class", _node);
|
||||
// throw("Widget is not supported by this widget class!");
|
||||
}
|
||||
},
|
||||
@ -537,7 +537,7 @@ var et2_widget = Class.extend({
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("warn", "Attributes cannot be objects", this, key, data[key]);
|
||||
this.egw().debug("warn", "Attributes cannot be objects", this, key, data[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -579,7 +579,7 @@ var et2_widget = Class.extend({
|
||||
// Try again, but skip the fancy stuff
|
||||
// TODO: Figure out why the getEntry() call doesn't always work
|
||||
var entry = modifications.data[_node.getAttribute("id")];
|
||||
if(entry) et2_debug("warn", "getEntry("+_node.getAttribute("id")+") failed, but the data is there.", modifications, entry);
|
||||
if(entry) this.egw().debug("warn", "getEntry("+_node.getAttribute("id")+") failed, but the data is there.", modifications, entry);
|
||||
}
|
||||
if(entry && entry.type)
|
||||
{
|
||||
@ -687,8 +687,16 @@ var et2_widget = Class.extend({
|
||||
return this._parent.egw();
|
||||
}
|
||||
|
||||
// Return the global egw instance if none is given
|
||||
return egw('phpgwapi');
|
||||
// Get the window this object belongs to
|
||||
var wnd = null;
|
||||
if (this.implements(et2_IDOMNode))
|
||||
{
|
||||
var node = this.getDOMNode();
|
||||
wnd = node.ownerDocument.parentNode || node.ownerDocument.defaultView;
|
||||
}
|
||||
|
||||
// If we're the root object, return the phpgwapi API instance
|
||||
return egw('phpgwapi', wnd);
|
||||
}
|
||||
|
||||
return this._egw;
|
||||
@ -831,4 +839,3 @@ var et2_widget = Class.extend({
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
@ -121,7 +121,7 @@ var et2_dataview_column = Class.extend({
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("warn", "Invalid visibility option for column: ", _value);
|
||||
this.egw().debug("warn", "Invalid visibility option for column: ", _value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -96,7 +96,7 @@ var et2_dataview_dataProvider = Class.extend(et2_IDataProvider, {
|
||||
|
||||
if (typeof this._registeredRows[_idx] != "undefined")
|
||||
{
|
||||
et2_debug("warn", "Overriding data row for index " + _idx);
|
||||
this.egw().debug("warn", "Overriding data row for index " + _idx);
|
||||
}
|
||||
|
||||
// Associate the given data row with that index
|
||||
|
@ -214,9 +214,9 @@ var et2_dataview_grid = Class.extend(et2_dataview_IViewRange, {
|
||||
// regarding to the count of elements managed in it
|
||||
if (count < Math.pow(ET2_PARTITION_TREE_WIDTH, depth - 1))
|
||||
{
|
||||
et2_debug("info", "Rebuilding dataview partition tree");
|
||||
this.egw().debug("info", "Rebuilding dataview partition tree");
|
||||
this._partitionTree.rebuild();
|
||||
et2_debug("info", "Done.");
|
||||
this.egw().debug("info", "Done.");
|
||||
}
|
||||
|
||||
// Reset the "treeChanged" function.
|
||||
|
@ -144,7 +144,7 @@ var et2_dataview_partitionNode = Class.extend([et2_dataview_IPartitionHeight,
|
||||
// complete tree!
|
||||
if (isNaN(this._height))
|
||||
{
|
||||
et2_debug("error", "calculateHeight returned a NaN value!");
|
||||
this.egw().debug("error", "calculateHeight returned a NaN value!");
|
||||
this._height = 0;
|
||||
}
|
||||
|
||||
|
@ -506,7 +506,7 @@ var et2_dataview_partitionOrganizationNode = et2_dataview_partitionNode.extend(
|
||||
|
||||
if (Math.abs(actualTop - calculatedTop) > 1)
|
||||
{
|
||||
et2_debug("warn", i, "Position missmatch at idx ", idx,
|
||||
egw.debug("warn", i, "Position missmatch at idx ", idx,
|
||||
actualTop, calculatedTop, node);
|
||||
}
|
||||
|
||||
@ -515,7 +515,7 @@ var et2_dataview_partitionOrganizationNode = et2_dataview_partitionNode.extend(
|
||||
|
||||
if (Math.abs(actualHeight - calculateHeight) > 1)
|
||||
{
|
||||
et2_debug("warn", i, "Height missmatch at idx ", idx,
|
||||
egw.debug("warn", i, "Height missmatch at idx ", idx,
|
||||
actualHeight, calculateHeight, node);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ var et2_dataview_partitionTree = et2_dataview_partitionOrganizationNode.extend({
|
||||
this._dataProvider = _dataProvider;
|
||||
this._rowProvider = _rowProvider;
|
||||
|
||||
et2_debug("Creating partition tree with ", this._count,
|
||||
egw.debug("Creating partition tree with ", this._count,
|
||||
" elements of avgHeight ", this._avgHeight);
|
||||
|
||||
// Append a spacer node to the children
|
||||
|
@ -166,7 +166,7 @@ var et2_dataview_rowProvider = Class.extend({
|
||||
|
||||
if (!supportsAttr)
|
||||
{
|
||||
et2_debug("warn", "et2_IDetachedDOM widget " +
|
||||
egw.debug("warn", "et2_IDetachedDOM widget " +
|
||||
widget._type + " does not support " + data.attribute);
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ var et2_dataview_rowProvider = Class.extend({
|
||||
|
||||
// Issue a warning - widgets which do not implement et2_IDOMNode
|
||||
// are very slow
|
||||
et2_debug("warn", "Non-clonable widget '"+ entry.widget._type + "' in dataview row - this " +
|
||||
egw.debug("warn", "Non-clonable widget '"+ entry.widget._type + "' in dataview row - this " +
|
||||
"might be slow", entry);
|
||||
|
||||
// Set the placeholder for the entry to null
|
||||
@ -399,7 +399,7 @@ var et2_dataview_rowProvider = Class.extend({
|
||||
nodes[j] = entry.nodeFuncs[j](_row[0]);
|
||||
}
|
||||
if(typeof nodes[0] == "undefined")
|
||||
et2_debug("warn", "Missing node", entry.widget.id,nodes, entry );
|
||||
egw.debug("warn", "Missing node", entry.widget.id,nodes, entry );
|
||||
|
||||
// Set the array managers first
|
||||
entry.widget._mgrs = mgrs;
|
||||
|
@ -247,7 +247,7 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
|
||||
},
|
||||
|
||||
applyFilters: function() {
|
||||
et2_debug("info", "Changing nextmatch filters to ", this.activeFilters);
|
||||
this.egw().debug("info", "Changing nextmatch filters to ", this.activeFilters);
|
||||
|
||||
// Clear the dataprovider and the dataview container - this will cause
|
||||
// the grid to reload.
|
||||
@ -295,7 +295,7 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
|
||||
|
||||
var colName = name + (name != "" && child_names.length > 0 ? "_" : "") + child_names.join("_");
|
||||
if(colName == "") {
|
||||
et2_debug("info", "Unable to generate nm column name for ", _widget);
|
||||
this.egw().debug("info", "Unable to generate nm column name for ", _widget);
|
||||
}
|
||||
return colName;
|
||||
},
|
||||
@ -417,7 +417,7 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
|
||||
}
|
||||
}
|
||||
} else if (colMgr.columns[i].fixedWidth) {
|
||||
et2_debug("info", "Could not save column width - no name", colMgr.columns[i].id);
|
||||
this.egw().debug("info", "Could not save column width - no name", colMgr.columns[i].id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -663,7 +663,7 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
|
||||
|
||||
if (!template.proxiedTemplate)
|
||||
{
|
||||
et2_debug("error", "Error while loading definition template for" +
|
||||
this.egw().debug("error", "Error while loading definition template for" +
|
||||
"nextmatch widget.");
|
||||
return;
|
||||
}
|
||||
@ -676,7 +676,7 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("error", "Nextmatch widget expects a grid to be the " +
|
||||
this.egw().debug("error", "Nextmatch widget expects a grid to be the " +
|
||||
"first child of the defined template.");
|
||||
return;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ var et2_grid = et2_DOMWidget.extend([et2_IDetachedDOM], {
|
||||
function _readColNode(node, nodeName) {
|
||||
if (y >= h)
|
||||
{
|
||||
et2_debug("warn", "Skipped grid cell in column, '" +
|
||||
this.egw().debug("warn", "Skipped grid cell in column, '" +
|
||||
nodeName + "'");
|
||||
return;
|
||||
}
|
||||
@ -234,7 +234,7 @@ var et2_grid = et2_DOMWidget.extend([et2_IDetachedDOM], {
|
||||
function _readRowNode(node, nodeName) {
|
||||
if (x >= w)
|
||||
{
|
||||
et2_debug("warn", "Skipped grid cell in row, '" +
|
||||
this.egw().debug("warn", "Skipped grid cell in row, '" +
|
||||
nodeName + "'");
|
||||
return;
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ var et2_selectbox = et2_inputWidget.extend({
|
||||
{
|
||||
if(jQuery("option[value='"+_value+"']", this.input).attr("selected", true).length == 0)
|
||||
{
|
||||
et2_debug("warning", "Tried to set value that isn't an option", this, _value);
|
||||
this.egw().debug("warning", "Tried to set value that isn't an option", this, _value);
|
||||
//console.trace();
|
||||
}
|
||||
}
|
||||
|
@ -67,10 +67,14 @@ var et2_template = et2_DOMWidget.extend({
|
||||
|
||||
if (this.id != "")
|
||||
{
|
||||
// Get the window this object belongs to
|
||||
var node = this.getDOMNode();
|
||||
var wnd = node.ownerDocument.parentNode || node.ownerDocument.defaultView;
|
||||
|
||||
// Set the api instance to the first part of the name of the
|
||||
// template
|
||||
var splitted = this.id.split('.');
|
||||
this.setApiInstance(egw(splitted[0]));
|
||||
this.setApiInstance(egw(splitted[0], wnd));
|
||||
|
||||
this.createProxy();
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ etemplate2.prototype._createArrayManagers = function(_data)
|
||||
{
|
||||
if (typeof _data[neededEntries[i]] == "undefined" || !_data[neededEntries[i]])
|
||||
{
|
||||
et2_debug("log", "Created not passed entry '" + neededEntries[i] +
|
||||
egw.debug("log", "Created not passed entry '" + neededEntries[i] +
|
||||
"' in data array.");
|
||||
_data[neededEntries[i]] = {};
|
||||
}
|
||||
@ -257,7 +257,7 @@ etemplate2.prototype.submit = function(button)
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("info", "Form got submitted with values: ", values);
|
||||
egw.debug("info", "Form got submitted with values: ", values);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -316,7 +316,7 @@ etemplate2.prototype.getValues = function(_root)
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("error", "ID collision while writing at path " +
|
||||
egw.debug("error", "ID collision while writing at path " +
|
||||
"node '" + path[i] + "'");
|
||||
}
|
||||
}
|
||||
@ -324,7 +324,7 @@ etemplate2.prototype.getValues = function(_root)
|
||||
// Check whether the entry is really undefined
|
||||
if (typeof _target[id] != "undefined")
|
||||
{
|
||||
et2_debug("error", _widget, "Overwriting value of '" + _widget.id +
|
||||
egw.debug("error", _widget, "Overwriting value of '" + _widget.id +
|
||||
"', id exists twice!");
|
||||
}
|
||||
|
||||
@ -374,6 +374,6 @@ if (typeof egw_json_register_plugin != "undefined")
|
||||
}
|
||||
else
|
||||
{
|
||||
et2_debug("info", "EGW JSON Plugin could not be registered, running ET2 standalone.");
|
||||
egw.debug("info", "EGW JSON Plugin could not be registered, running ET2 standalone.");
|
||||
}
|
||||
|
||||
|
@ -21,5 +21,6 @@
|
||||
egw_config;
|
||||
egw_images;
|
||||
egw_jsonq;
|
||||
egw_files;
|
||||
*/
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
egw_core;
|
||||
*/
|
||||
|
||||
egw().extend('config', function() {
|
||||
egw.extend('config', egw.MODULE_GLOBAL, function() {
|
||||
|
||||
/**
|
||||
* Clientside config
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* EGroupware clientside API object
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
@ -14,21 +14,6 @@
|
||||
|
||||
var egw;
|
||||
|
||||
/**
|
||||
* IE Fix for array.indexOf
|
||||
*/
|
||||
if (typeof Array.prototype.indexOf == "undefined")
|
||||
{
|
||||
Array.prototype.indexOf = function(_elem) {
|
||||
for (var i = 0; i < this.length; i++)
|
||||
{
|
||||
if (this[i] === _elem)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This code setups the egw namespace and adds the "extend" function, which is
|
||||
* used by extension modules to inject their content into the egw object.
|
||||
@ -51,9 +36,111 @@ if (typeof Array.prototype.indexOf == "undefined")
|
||||
// Extend the egw object
|
||||
for (var key in _from)
|
||||
{
|
||||
if (typeof _to[key] === 'undefined')
|
||||
_to[key] = _from[key];
|
||||
}
|
||||
}
|
||||
|
||||
function createEgwInstance(_egw, _modules, _list, _app, _window)
|
||||
{
|
||||
// Clone the global object
|
||||
var instance = cloneObject(_egw);
|
||||
|
||||
// Let "_window" be exactly null, if it evaluates to false
|
||||
_window = _window ? _window : null;
|
||||
|
||||
// Set the application name and the window the API instance belongs to
|
||||
instance.appName = _app ? _app : null;
|
||||
instance.window = _window;
|
||||
|
||||
// Insert the newly created instance into the instances list
|
||||
_list.push({
|
||||
'window': _window,
|
||||
'app': _app,
|
||||
'instance': instance
|
||||
});
|
||||
|
||||
// Re-instanciate all modules which are marked as "local"
|
||||
for (var key in _modules)
|
||||
{
|
||||
// Get the module object
|
||||
var mod = _modules[key];
|
||||
|
||||
if (mod.flags !== _egw.MODULE_GLOBAL)
|
||||
{
|
||||
_to[key] = _from[key];
|
||||
// If the module is marked as application local and an
|
||||
// application instance is given or if the module is marked as
|
||||
// window local and a window instance is given, re-instanciate
|
||||
// this module.
|
||||
if (((mod.flags & _egw.MODULE_APP_LOCAL) && (_app)) ||
|
||||
((mod.flags & _egw.MODULE_WND_LOCAL) && (_window)))
|
||||
{
|
||||
var extension = mod.code.call(instance, instance,
|
||||
_window ? _window : window);
|
||||
mergeObjects(instance, extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
function getEgwInstance(_egw, _modules, _instances, _app, _window)
|
||||
{
|
||||
// Generate the hash key for the instance descriptor object
|
||||
var hash = _window ? _app + "_" + _window.location : _app;
|
||||
|
||||
// Let "_window" be exactly null, if it evaluates to false
|
||||
_window = _window ? _window : null;
|
||||
|
||||
// Create a new entry if the calculated hash does not exist
|
||||
if (typeof _instances[hash] === 'undefined')
|
||||
{
|
||||
_instances[hash] = [];
|
||||
return createEgwInstance(_egw, _modules, _instances[hash], _app,
|
||||
_window);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise search for the api instance corresponding to the given
|
||||
// window
|
||||
for (var i = 0; i < _instances[hash].length; i++)
|
||||
{
|
||||
if (_instances[hash][i].window === _window)
|
||||
{
|
||||
return _instances[hash][i].instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're still here, no API instance for the given window has been
|
||||
// found -- create a new entry
|
||||
return createEgwInstance(_egw, _modules, _instances[hash], _app, _window);
|
||||
}
|
||||
|
||||
function cleanupEgwInstances(_instances)
|
||||
{
|
||||
// Iterate over the egw instances and check whether the window they
|
||||
// correspond to is still open.
|
||||
for (var key in _instances)
|
||||
{
|
||||
for (var i = _instances[key].length - 1; i >= 0; i--)
|
||||
{
|
||||
// Get the instance descriptor
|
||||
var instDescr = _instances[key][i];
|
||||
|
||||
// Check whether the window this API instance belongs to is
|
||||
// still opened. If not, remove the API instance.
|
||||
if (instDescr.window && instDescr.window.closed)
|
||||
{
|
||||
_instances[key].splice(i, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// If all instances for the current hash have been deleted, delete
|
||||
// the hash entry itself
|
||||
if (_instances[key].length === 0)
|
||||
{
|
||||
delete _instances[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -69,67 +156,112 @@ if (typeof Array.prototype.indexOf == "undefined")
|
||||
else
|
||||
{
|
||||
/**
|
||||
* EGW_DEBUGLEVEL specifies which messages are printed to the console.
|
||||
* Decrease the value of EGW_DEBUGLEVEL to get less messages.
|
||||
* Modules contains all currently loaded egw extension modules. A module
|
||||
* is stored as an object of the following form:
|
||||
* {
|
||||
* name: <NAME OF THE OBJECT>,
|
||||
* code: <REFERENCE TO THE MODULE FUNCTION>,
|
||||
* flags: <MODULE FLAGS (local, global, etc.)
|
||||
* }
|
||||
*/
|
||||
var EGW_DEBUGLEVEL = 4;
|
||||
var modules = {};
|
||||
|
||||
/**
|
||||
* Modules contains all currently loaded egw extension modules.
|
||||
* instances contains all api instances. These are organized as a hash
|
||||
* of the form _app + _window.location. For each of these hashes a list
|
||||
* of instances is stored, where the instance itself is an entry of the
|
||||
* form
|
||||
* {
|
||||
* instance: <EGW_API_OBJECT>,
|
||||
* app: <APPLICATION NAME>,
|
||||
* window: <WINDOW REFERENCE>
|
||||
* }
|
||||
*/
|
||||
var modules = [];
|
||||
var instances = {};
|
||||
|
||||
var localEgw = {};
|
||||
/**
|
||||
* Set a interval which is used to cleanup unused API instances all 10
|
||||
* seconds.
|
||||
*/
|
||||
window.setInterval(function() {cleanupEgwInstances(instances);}, 10000);
|
||||
|
||||
/**
|
||||
* The egw function returns an instance of the client side api. If no
|
||||
* parameter is given, an egw istance, which is not bound to a certain
|
||||
* application is returned.
|
||||
* You may pass either an application name (as string) to the egw
|
||||
* function and/or a window object. If you specify both, the app name
|
||||
* has to preceed the window object reference. If no window object is
|
||||
* given, the root window will be used.
|
||||
*/
|
||||
egw = function(_app) {
|
||||
egw = function() {
|
||||
|
||||
// If no argument is given, simply return the global egw object, or
|
||||
// check whether 'window.egw_appName' is set correctly.
|
||||
if (typeof _app === 'undefined')
|
||||
// Get the window/app reference
|
||||
var _app = "";
|
||||
var _window = window;
|
||||
|
||||
switch (arguments.length)
|
||||
{
|
||||
// TODO: Remove this code, window.egw_appName will be removed
|
||||
// in the future.
|
||||
if (typeof window.egw_appName == 'string')
|
||||
{
|
||||
_app = window.egw_appName;
|
||||
}
|
||||
else
|
||||
{
|
||||
case 0:
|
||||
// Return the global instance
|
||||
return egw;
|
||||
}
|
||||
|
||||
case 1:
|
||||
if (typeof arguments[0] === 'string')
|
||||
{
|
||||
_app = arguments[0];
|
||||
}
|
||||
else if (typeof arguments[0] === 'object')
|
||||
{
|
||||
_window = arguments[0];
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_app = arguments[0];
|
||||
_window = arguments[1];
|
||||
break;
|
||||
|
||||
default:
|
||||
throw "Invalid count of parameters";
|
||||
}
|
||||
|
||||
if (typeof _app == 'string')
|
||||
{
|
||||
// If a argument is given, this represents the current application
|
||||
// name. Check whether we already have a copy of the egw object for
|
||||
// that application. If yes, return it.
|
||||
if (typeof localEgw[_app] === 'undefined')
|
||||
{
|
||||
// Otherwise clone the global egw object, set the application
|
||||
// name and return it
|
||||
localEgw[_app] = cloneObject(egw);
|
||||
localEgw[_app].appName = _app;
|
||||
}
|
||||
|
||||
return localEgw[_app];
|
||||
}
|
||||
|
||||
this.debug("error", "Non-string argument given to the egw function.");
|
||||
// Generate an API instance
|
||||
return getEgwInstance(egw, modules, instances, _app, _window);
|
||||
}
|
||||
|
||||
var globalEgw = {
|
||||
|
||||
/**
|
||||
* The MODULE_GLOBAL flag describes a module as global. A global
|
||||
* module always works on the same data.
|
||||
*/
|
||||
MODULE_GLOBAL: 0x00,
|
||||
|
||||
/**
|
||||
* The MODULE_APP_LOCAL flag is used to describe a module as local
|
||||
* for each application. Each time an api object is requested for
|
||||
* another application, the complete module gets recreated.
|
||||
*/
|
||||
MODULE_APP_LOCAL: 0x01,
|
||||
|
||||
/**
|
||||
* The MODULE_WND_LOCAL flag is used to describe a module as local
|
||||
* for each window. Each time an api object is requested for another
|
||||
* window, the complete module gets recreated.
|
||||
*/
|
||||
MODULE_WND_LOCAL: 0x02,
|
||||
|
||||
/**
|
||||
* Name of the application the egw object belongs to.
|
||||
*/
|
||||
appName: null,
|
||||
|
||||
/**
|
||||
* Reference to the window this egw object belongs to.
|
||||
*/
|
||||
window: window,
|
||||
|
||||
/**
|
||||
* Returns the current application name. The current application
|
||||
* name equals the name, which was given when calling the egw
|
||||
@ -159,74 +291,65 @@ if (typeof Array.prototype.indexOf == "undefined")
|
||||
*
|
||||
* @param _module should be a string containing the name of the new
|
||||
* module.
|
||||
* @param _flags specifies whether the extension should be treated
|
||||
* as a local or a global module.
|
||||
* @param _code should be a function, which returns an object that
|
||||
* should extend the egw object.
|
||||
*/
|
||||
extend: function(_module, _code) {
|
||||
extend: function(_module, _flags, _code) {
|
||||
|
||||
// Check whether the given module has already been loaded.
|
||||
if (modules.indexOf(_module) < 0) {
|
||||
// Check whether that module is already registered
|
||||
if (typeof modules[_module] === 'undefined')
|
||||
{
|
||||
// Create a new module entry
|
||||
modules[_module] = {
|
||||
'code': _code,
|
||||
'flags': _flags,
|
||||
'name': _module
|
||||
};
|
||||
|
||||
// Call the function specified by "_code" which returns
|
||||
// nothing but an object containing the extension.
|
||||
var content = _code.call(this);
|
||||
// Generate the global extension
|
||||
var globalExtension = _code.call(egw, egw, window);
|
||||
|
||||
// Merge the extension into the egw function
|
||||
mergeObjects(egw, content);
|
||||
// Merge the global extension into the egw function
|
||||
mergeObjects(egw, globalExtension);
|
||||
|
||||
// Merge the extension into the local egw object
|
||||
for (var key in localEgw) {
|
||||
mergeObjects(localEgw[key], content);
|
||||
// Iterate over the instances and merge the modules into
|
||||
// them
|
||||
for (var key in instances)
|
||||
{
|
||||
for (var i = 0; i < instances[key].length; i++)
|
||||
{
|
||||
// Get the instance descriptor
|
||||
var instDescr = instances[key][i];
|
||||
|
||||
// Merge the module into the instance
|
||||
if (_flags !== egw.MODULE_GLOBAL)
|
||||
{
|
||||
mergeObjects(instDescr.instance, _code.call(
|
||||
instDescr.instance, instDescr.instance,
|
||||
instDescr.window ? instDescr.window : window));
|
||||
}
|
||||
else
|
||||
{
|
||||
mergeObjects(instDescr.instance, globalExtension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register the module as loaded
|
||||
modules.push(_module);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The debug function can be used to send a debug message to the
|
||||
* java script console. The first parameter specifies the debug
|
||||
* level, all other parameters are passed to the corresponding
|
||||
* console function.
|
||||
*/
|
||||
debug: function(_level) {
|
||||
if (typeof console != "undefined")
|
||||
{
|
||||
// Get the passed parameters and remove the first entry
|
||||
var args = [];
|
||||
for (var i = 1; i < arguments.length; i++)
|
||||
{
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
dumpModules: function() {
|
||||
return modules;
|
||||
},
|
||||
|
||||
if (_level == "log" && EGW_DEBUGLEVEL >= 4 &&
|
||||
typeof console.log == "function")
|
||||
{
|
||||
console.log.apply(console, args);
|
||||
}
|
||||
|
||||
if (_level == "info" && EGW_DEBUGLEVEL >= 3 &&
|
||||
typeof console.info == "function")
|
||||
{
|
||||
console.info.apply(console, args);
|
||||
}
|
||||
|
||||
if (_level == "warn" && EGW_DEBUGLEVEL >= 2 &&
|
||||
typeof console.warn == "function")
|
||||
{
|
||||
console.warn.apply(console, args);
|
||||
}
|
||||
|
||||
if (_level == "error" && EGW_DEBUGLEVEL >= 1 &&
|
||||
typeof console.error == "function")
|
||||
{
|
||||
console.error.apply(console, args);
|
||||
}
|
||||
}
|
||||
dumpInstances: function() {
|
||||
return instances;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Merge the globalEgw functions into the egw object.
|
||||
mergeObjects(egw, globalEgw);
|
||||
}
|
||||
})();
|
||||
|
70
phpgwapi/js/jsapi/egw_debug.js
Normal file
70
phpgwapi/js/jsapi/egw_debug.js
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* EGroupware clientside API object
|
||||
*
|
||||
* @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 (as AT stylite.de)
|
||||
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
|
||||
egw.extend('debug', egw.MODULE_WND_LOCAL, function(_egw, _wnd) {
|
||||
|
||||
/**
|
||||
* DEBUGLEVEL specifies which messages are printed to the console.
|
||||
* Decrease the value of EGW_DEBUGLEVEL to get less messages.
|
||||
*/
|
||||
var DEBUGLEVEL = 4;
|
||||
|
||||
/**
|
||||
* The debug function can be used to send a debug message to the
|
||||
* java script console. The first parameter specifies the debug
|
||||
* level, all other parameters are passed to the corresponding
|
||||
* console function.
|
||||
*/
|
||||
return {
|
||||
debug: function(_level) {
|
||||
if (typeof _wnd.console != "undefined")
|
||||
{
|
||||
// Get the passed parameters and remove the first entry
|
||||
var args = [];
|
||||
for (var i = 1; i < arguments.length; i++)
|
||||
{
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
|
||||
if (_level == "log" && DEBUGLEVEL >= 4 &&
|
||||
typeof _wnd.console.log == "function")
|
||||
{
|
||||
_wnd.console.log.apply(_wnd.console, args);
|
||||
}
|
||||
|
||||
if (_level == "info" && DEBUGLEVEL >= 3 &&
|
||||
typeof _wnd.console.info == "function")
|
||||
{
|
||||
_wnd.console.info.apply(_wnd.console, args);
|
||||
}
|
||||
|
||||
if (_level == "warn" && DEBUGLEVEL >= 2 &&
|
||||
typeof _wnd.console.warn == "function")
|
||||
{
|
||||
_wnd.console.warn.apply(_wnd.console, args);
|
||||
}
|
||||
|
||||
if (_level == "error" && DEBUGLEVEL >= 1 &&
|
||||
typeof _wnd.console.error == "function")
|
||||
{
|
||||
_wnd.console.error.apply(_wnd.console, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
153
phpgwapi/js/jsapi/egw_files.js
Normal file
153
phpgwapi/js/jsapi/egw_files.js
Normal file
@ -0,0 +1,153 @@
|
||||
/**
|
||||
* EGroupware clientside API object
|
||||
*
|
||||
* @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 (as AT stylite.de)
|
||||
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery; // Used for traversing the DOM
|
||||
egw_core;
|
||||
egw_debug;
|
||||
*/
|
||||
|
||||
egw.extend('files', egw.MODULE_GLOBAL, function() {
|
||||
|
||||
/**
|
||||
* Array which contains all currently bound in javascript and css files.
|
||||
*/
|
||||
var files = {};
|
||||
|
||||
/**
|
||||
* Gather all already loaded JavaScript and CSS files on document load.
|
||||
*
|
||||
* TODO: Currently this can only contain the JS files present in the main
|
||||
* window.
|
||||
*/
|
||||
$j(document).ready(function() {
|
||||
$j("script, link").each(function() {
|
||||
var elem = $j(this);
|
||||
|
||||
if (elem.attr("src"))
|
||||
{
|
||||
files[elem.attr("src")] = true;
|
||||
}
|
||||
|
||||
if (elem.attr("href"))
|
||||
{
|
||||
files[elem.attr("href")] = true;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
function includeJSFile(_jsFile, _callback, _context)
|
||||
{
|
||||
var alreadyLoaded = false;
|
||||
|
||||
if (typeof files[_jsFile] === 'undefined')
|
||||
{
|
||||
// Create the script node which contains the new file
|
||||
var scriptnode = document.createElement('script');
|
||||
scriptnode.type = "text/javascript";
|
||||
scriptnode.src = _jsFile;
|
||||
scriptnode._originalSrc = _jsFile;
|
||||
|
||||
// Setup the 'onload' handler for FF, Opera, Chrome
|
||||
scriptnode.onload = function(e) {
|
||||
this.debug('info', 'Retrieved JS file "%s" from server', _jsFile);
|
||||
_callback.call(_context, _jsFile);
|
||||
};
|
||||
|
||||
// IE
|
||||
if (typeof scriptnode.readyState != 'undefined')
|
||||
{
|
||||
if (scriptnode.readyState != 'complete' &&
|
||||
scriptnode.readyState != 'loaded')
|
||||
{
|
||||
scriptnode.onreadystatechange = function() {
|
||||
var node = window.event.srcElement;
|
||||
if (node.readyState == 'complete' || node.readyState == 'loaded')
|
||||
{
|
||||
this.debug('info', 'Retrieved JS file "%s" from server', _jsFile);
|
||||
_callback.call(_context, _jsFile);
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
alreadyLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Append the newly create script node to the head
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
head.appendChild(scriptnode);
|
||||
|
||||
// Request the given javascript file
|
||||
this.debug('info', 'Requested JS file "%s" from server', _jsFile);
|
||||
}
|
||||
|
||||
// If the file is already loaded, call the callback
|
||||
if (alreadyLoaded)
|
||||
{
|
||||
window.setTimeout(
|
||||
function() {
|
||||
_callback.call(_context, _jsFile);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
includeJS: function(_jsFiles, _callback, _context) {
|
||||
// Also allow including a single javascript file
|
||||
if (typeof _jsFiles === 'string')
|
||||
{
|
||||
_jsFiles = [_jsFiles];
|
||||
}
|
||||
|
||||
var loaded = 0;
|
||||
|
||||
// Include all given JS files, if all are successfully loaded, call
|
||||
// the context function
|
||||
for (var i = 0; i < _jsFiles.length; i++)
|
||||
{
|
||||
includeJSFile.call(this, _jsFiles[i], function(_file) {
|
||||
loaded++;
|
||||
if (loaded == _jsFiles.length && _callback) {
|
||||
_callback.call(_context);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
includeCSS: function(_cssFile) {
|
||||
//Check whether the requested file has already been included
|
||||
if (typeof files[_cssFile] === 'undefined')
|
||||
{
|
||||
files[_cssFile] = true;
|
||||
|
||||
// Create the node which is used to include the css fiel
|
||||
var cssnode = document.createElement('link');
|
||||
cssnode.type = "text/css";
|
||||
cssnode.rel = "stylesheet";
|
||||
cssnode.href = _cssFile;
|
||||
|
||||
// Get the head node and append the newly created "link" node
|
||||
// to it.
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
head.appendChild(cssnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
egw_core;
|
||||
*/
|
||||
|
||||
egw().extend('images', function() {
|
||||
egw.extend('images', egw.MODULE_GLOBAL, function() {
|
||||
|
||||
/**
|
||||
* Map to serverside available images for users template-set
|
||||
|
325
phpgwapi/js/jsapi/egw_json.js
Normal file
325
phpgwapi/js/jsapi/egw_json.js
Normal file
@ -0,0 +1,325 @@
|
||||
/**
|
||||
* EGroupware clientside API object
|
||||
*
|
||||
* @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 (as AT stylite.de)
|
||||
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
jquery.jquery;
|
||||
|
||||
egw_core;
|
||||
egw_utils;
|
||||
egw_files;
|
||||
*/
|
||||
|
||||
egw.extend('json', egw.MODULE_WND_LOCAL, function(_egw, _wnd) {
|
||||
|
||||
/**
|
||||
* Object which contains all registered handlers for JS responses.
|
||||
* The handlers are organized per response type in the top level of the
|
||||
* object, where each response type can have an array of handlers attached
|
||||
* to it.
|
||||
*/
|
||||
var plugins = {};
|
||||
|
||||
/**
|
||||
* Internal implementation of the JSON request object.
|
||||
*/
|
||||
function json_request(_menuaction, _parameters, _callback, _context, _egw)
|
||||
{
|
||||
// Initialize undefined parameters
|
||||
if (typeof _parameters === 'undefined')
|
||||
{
|
||||
_parameters = [];
|
||||
}
|
||||
|
||||
if (typeof _callback === 'undefined')
|
||||
{
|
||||
_callback = null;
|
||||
}
|
||||
|
||||
if (typeof _context === 'undefined')
|
||||
{
|
||||
_context = null;
|
||||
}
|
||||
|
||||
// Copy the parameters
|
||||
this.parameters = _parameters;
|
||||
this.egw = _egw;
|
||||
this.callback = _callback;
|
||||
this.context = _context;
|
||||
|
||||
this.request = null;
|
||||
this.sender = null;
|
||||
this.callback = null;
|
||||
|
||||
this.onLoadFinish = null;
|
||||
this.jsFiles = 0;
|
||||
this.jsCount = 0;
|
||||
|
||||
this.alertHandler = this.alertFunc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function which is currently used to display alerts -- may be replaced by
|
||||
* some API function.
|
||||
*/
|
||||
json_request.prototype.alertFunc = function(_message, _details)
|
||||
{
|
||||
alert(_message);
|
||||
if(_details) _egw_json_debug_log(_message, _details);
|
||||
}
|
||||
|
||||
var json = {
|
||||
|
||||
/** The constructor of the egw_json_request class.
|
||||
*
|
||||
* @param _menuaction the menuaction function which should be called and
|
||||
* which handles the actual request. If the menuaction is a full featured
|
||||
* url, this one will be used instead.
|
||||
* @param _parameters which should be passed to the menuaction function.
|
||||
* @param _callback specifies the callback function which should be
|
||||
* called, once the request has been sucessfully executed.
|
||||
* @param _context is the context which will be used for the callback function
|
||||
*/
|
||||
request: function(_menuaction, _parameters, _callback, _context)
|
||||
{
|
||||
return new json_request(_menuaction, _parameters, _callback,
|
||||
_context, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new handler plugin.
|
||||
*
|
||||
* @param _callback is the callback function which should be called
|
||||
* whenever a response is comming from the server.
|
||||
* @param _context is the context in which the callback function should
|
||||
* be called. If null is given, the plugin is executed in the context
|
||||
* of the request object.
|
||||
* @param _type is an optional parameter defaulting to 'global'.
|
||||
* it describes the response type which this plugin should be
|
||||
* handling.
|
||||
*/
|
||||
registerJSONPlugin: function(_callback, _context, _type)
|
||||
{
|
||||
// _type defaults to 'global'
|
||||
if (typeof _type === 'undefined')
|
||||
{
|
||||
_type = 'global';
|
||||
}
|
||||
|
||||
// Create an array for the given category inside the plugins object
|
||||
if (typeof plugins[_type] === 'undefined')
|
||||
{
|
||||
plugins[_type] = [];
|
||||
}
|
||||
|
||||
// Add the entry
|
||||
plugins[_type].push({
|
||||
'callback': _callback,
|
||||
'context': _context,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a previously registered plugin.
|
||||
*
|
||||
* @param _callback is the callback function which should be called
|
||||
* whenever a response is comming from the server.
|
||||
* @param _context is the context in which the callback function should
|
||||
* be called.
|
||||
* @param _type is an optional parameter defaulting to 'global'.
|
||||
* it describes the response type which this plugin should be
|
||||
* handling.
|
||||
*/
|
||||
unregisterJSONPlugin: function(_callback, _context, _type)
|
||||
{
|
||||
// _type defaults to 'global'
|
||||
if (typeof _type === 'undefined')
|
||||
{
|
||||
_type = 'global';
|
||||
}
|
||||
|
||||
if (typeof plugins[_type] !== 'undefined') {
|
||||
for (var i = 0; i < plugins[_type].length; i++)
|
||||
{
|
||||
if (plugins[_type][i].callback == _callback &&
|
||||
plugins[_type][i].context == _context)
|
||||
{
|
||||
plugins[_type].slice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Regisert the "alert" plugin
|
||||
json.registerPlugin(function(type, res) {
|
||||
//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)
|
||||
return true;
|
||||
}
|
||||
throw 'Invalid parameters';
|
||||
}, null, 'alert');
|
||||
|
||||
// Register the "assign" plugin
|
||||
json.registerPlugin(function(type, res) {
|
||||
//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;
|
||||
|
||||
if (res.data.key == "innerHTML")
|
||||
{
|
||||
egw_insertJS(res.data.value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
throw 'Invalid parameters';
|
||||
}, null, 'assign');
|
||||
|
||||
// Register the "data" plugin
|
||||
json.registerPlugin(function(type, res) {
|
||||
//Callback the caller in order to allow him to handle the data
|
||||
if (this.callback)
|
||||
{
|
||||
this.callback.call(this.sender, res.data);
|
||||
return true;
|
||||
}
|
||||
}, null, 'data');
|
||||
|
||||
// Register the "script" plugin
|
||||
json.registerPlugin(function(type, res) {
|
||||
if (typeof res.data == 'string')
|
||||
{
|
||||
try
|
||||
{
|
||||
var func = new Function(res.data);
|
||||
func.call(window);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
this.egw.debug('error', 'Error while executing script: ',
|
||||
res.data)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
throw 'Invalid parameters';
|
||||
}, null, 'script');
|
||||
|
||||
// Register the "apply" plugin
|
||||
json.registerPlugin(function(type, res) {
|
||||
if (typeof res.data.func == 'string' &&
|
||||
typeof window[res.data.func] == 'function')
|
||||
{
|
||||
try
|
||||
{
|
||||
window[res.data.func].apply(window, res.data.parms);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
this.egw.debug('error', 'Function', res.data.func,
|
||||
'Parameters', res.data.parms);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
throw 'Invalid parameters';
|
||||
}, null, 'apply');
|
||||
|
||||
// Register the "jquery" plugin
|
||||
json.registerPlugin(function(type, res) {
|
||||
if (typeof res.data.select == 'string' &&
|
||||
typeof res.data.func == 'string')
|
||||
{
|
||||
try
|
||||
{
|
||||
var jQueryObject = $j(res.data.select, this.context);
|
||||
jQueryObject[res.data.func].apply(jQueryObject, res.data.parms);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
this.egw.debug('error', 'Function', res.data.func,
|
||||
'Parameters', res.data.parms);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
throw 'Invalid parameters';
|
||||
}, null, 'jquery');
|
||||
|
||||
// Register the "redirect" plugin
|
||||
json.registerPlugin(function(type, res) {
|
||||
//console.log(res.data.url);
|
||||
if (typeof res.data.url == 'string' &&
|
||||
typeof res.data.global == 'boolean')
|
||||
{
|
||||
//Special handling for framework reload
|
||||
res.data.global |= (res.data.url.indexOf("?cd=10") > 0);
|
||||
|
||||
if (res.data.global)
|
||||
{
|
||||
egw_topWindow().location.href = res.data.url;
|
||||
}
|
||||
else
|
||||
{
|
||||
egw_appWindowOpen(this.app, res.data.url);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
throw 'Invalid parameters';
|
||||
}, null, 'redirect');
|
||||
|
||||
// Register the 'css' plugin
|
||||
json.registerPlugin(function(type, res) {
|
||||
if (typeof res.data == 'string')
|
||||
{
|
||||
this.egw.includeCSS(res.data);
|
||||
return true;
|
||||
}
|
||||
throw 'Invalid parameters';
|
||||
}, null, 'css');
|
||||
|
||||
// Register the 'js' plugin
|
||||
json.registerPlugin(function(type, res) {
|
||||
if (typeof res.data == 'string')
|
||||
{
|
||||
this.jsCount++;
|
||||
var self = this;
|
||||
|
||||
this.egw.includeJS(res.data, function() {
|
||||
self.jsFiles++;
|
||||
if (self.jsFiles == self.jsCount && this.onLoadFinish)
|
||||
{
|
||||
this.onLoadFinish.call(this.sender);
|
||||
}
|
||||
});
|
||||
}
|
||||
throw 'Invalid parameters';
|
||||
}, null, 'js');
|
||||
|
||||
// Return the extension
|
||||
return json;
|
||||
});
|
||||
|
@ -14,9 +14,10 @@
|
||||
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
egw_debug;
|
||||
*/
|
||||
|
||||
egw().extend('jsonq', function() {
|
||||
egw.extend('jsonq', egw.MODULE_GLOBAL, function() {
|
||||
|
||||
/**
|
||||
* Queued json requests (objects with attributes menuaction, parameters, context, callback, sender and callbeforesend)
|
||||
@ -35,6 +36,79 @@ egw().extend('jsonq', function() {
|
||||
*/
|
||||
var jsonq_timer = null;
|
||||
|
||||
/**
|
||||
* Dispatch responses received
|
||||
*
|
||||
* @param object _data uid => response pairs
|
||||
*/
|
||||
function jsonq_callback(_data)
|
||||
{
|
||||
if (typeof _data != 'object') throw "jsonq_callback called with NO object as parameter!";
|
||||
|
||||
var json = new egw_json_request('none');
|
||||
for(var uid in _data)
|
||||
{
|
||||
if (typeof jsonq_queue[uid] == 'undefined')
|
||||
{
|
||||
console.log("jsonq_callback received response for not existing queue uid="+uid+"!");
|
||||
console.log(_data[uid]);
|
||||
continue;
|
||||
}
|
||||
var job = jsonq_queue[uid];
|
||||
var response = _data[uid];
|
||||
|
||||
// fake egw_json_request object, to call it with the current response
|
||||
json.callback = job.callback;
|
||||
json.sender = job.sender;
|
||||
json.handleResponse({response: response});
|
||||
|
||||
delete jsonq_queue[uid];
|
||||
}
|
||||
// if nothing left in queue, stop interval-timer to give browser a rest
|
||||
if (jsonq_timer && typeof jsonq_queue['u'+(jsonq_uid-1)] != 'object')
|
||||
{
|
||||
window.clearInterval(jsonq_timer);
|
||||
jsonq_timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the whole job-queue to the server in a single json request with menuaction=queue
|
||||
*/
|
||||
function jsonq_send()
|
||||
{
|
||||
if (jsonq_uid > 0 && typeof jsonq_queue['u'+(jsonq_uid-1)] == 'object')
|
||||
{
|
||||
var jobs_to_send = {};
|
||||
var something_to_send = false;
|
||||
for(var uid in jsonq_queue)
|
||||
{
|
||||
var job = jsonq_queue[uid];
|
||||
|
||||
if (job.menuaction == 'send') continue; // already send to server
|
||||
|
||||
// if job has a callbeforesend callback, call it to allow it to modify pararmeters
|
||||
if (typeof job.callbeforesend == 'function')
|
||||
{
|
||||
job.callbeforesend.call(job.sender, job.parameters);
|
||||
}
|
||||
jobs_to_send[uid] = {
|
||||
menuaction: job.menuaction,
|
||||
parameters: job.parameters
|
||||
};
|
||||
job.menuaction = 'send';
|
||||
job.parameters = null;
|
||||
something_to_send = true;
|
||||
}
|
||||
if (something_to_send)
|
||||
{
|
||||
// TODO: Passing this to the "home" application looks quite ugly
|
||||
var request = new egw_json_request('home.queue', jobs_to_send, this);
|
||||
request.sendRequest(true, jsonq_callback, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Send a queued JSON call to the server
|
||||
@ -64,82 +138,12 @@ egw().extend('jsonq', function() {
|
||||
// check / send queue every N ms
|
||||
var self = this;
|
||||
jsonq_timer = window.setInterval(function(){
|
||||
self.jsonq_send();
|
||||
jsonq_send.call(self);
|
||||
}, 100);
|
||||
}
|
||||
return uid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Send the whole job-queue to the server in a single json request with menuaction=queue
|
||||
*/
|
||||
jsonq_send: function()
|
||||
{
|
||||
if (jsonq_uid > 0 && typeof jsonq_queue['u'+(jsonq_uid-1)] == 'object')
|
||||
{
|
||||
var jobs_to_send = {};
|
||||
var something_to_send = false;
|
||||
for(var uid in jsonq_queue)
|
||||
{
|
||||
var job = jsonq_queue[uid];
|
||||
}
|
||||
|
||||
if (job.menuaction == 'send') continue; // already send to server
|
||||
|
||||
// if job has a callbeforesend callback, call it to allow it to modify pararmeters
|
||||
if (typeof job.callbeforesend == 'function')
|
||||
{
|
||||
job.callbeforesend.call(job.sender, job.parameters);
|
||||
}
|
||||
jobs_to_send[uid] = {
|
||||
menuaction: job.menuaction,
|
||||
parameters: job.parameters
|
||||
};
|
||||
job.menuaction = 'send';
|
||||
job.parameters = null;
|
||||
something_to_send = true;
|
||||
}
|
||||
if (something_to_send)
|
||||
{
|
||||
new egw_json_request('home.queue', jobs_to_send, this).sendRequest(true, this.jsonq_callback, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Dispatch responses received
|
||||
*
|
||||
* @param object _data uid => response pairs
|
||||
*/
|
||||
jsonq_callback: function(_data)
|
||||
{
|
||||
if (typeof _data != 'object') throw "jsonq_callback called with NO object as parameter!";
|
||||
|
||||
var json = new egw_json_request('none');
|
||||
for(var uid in _data)
|
||||
{
|
||||
if (typeof jsonq_queue[uid] == 'undefined')
|
||||
{
|
||||
console.log("jsonq_callback received response for not existing queue uid="+uid+"!");
|
||||
console.log(_data[uid]);
|
||||
continue;
|
||||
}
|
||||
var job = jsonq_queue[uid];
|
||||
var response = _data[uid];
|
||||
|
||||
// fake egw_json_request object, to call it with the current response
|
||||
json.callback = job.callback;
|
||||
json.sender = job.sender;
|
||||
json.handleResponse({response: response});
|
||||
|
||||
delete jsonq_queue[uid];
|
||||
}
|
||||
// if nothing left in queue, stop interval-timer to give browser a rest
|
||||
if (jsonq_timer && typeof jsonq_queue['u'+(jsonq_uid-1)] != 'object')
|
||||
{
|
||||
window.clearInterval(jsonq_timer);
|
||||
jsonq_timer = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
});
|
||||
|
@ -16,7 +16,7 @@
|
||||
egw_core;
|
||||
*/
|
||||
|
||||
egw().extend('lang', function() {
|
||||
egw.extend('lang', egw.MODULE_GLOBAL, function() {
|
||||
|
||||
/**
|
||||
* Translations
|
||||
|
@ -17,7 +17,7 @@
|
||||
egw_link;
|
||||
*/
|
||||
|
||||
egw().extend('links', function() {
|
||||
egw.extend('links', egw.MODULE_GLOBAL, function() {
|
||||
|
||||
/**
|
||||
* Link registry
|
||||
|
@ -16,7 +16,7 @@
|
||||
egw_core;
|
||||
*/
|
||||
|
||||
egw().extend('preferences', function() {
|
||||
egw.extend('preferences', egw.MODULE_GLOBAL, function() {
|
||||
|
||||
/**
|
||||
* Object holding the prefences as 2-dim. associative array, use
|
||||
|
@ -16,7 +16,7 @@
|
||||
egw_core;
|
||||
*/
|
||||
|
||||
egw().extend('user', function() {
|
||||
egw.extend('user', egw.MODULE_GLOBAL, function() {
|
||||
|
||||
/**
|
||||
* Data about current user
|
||||
|
165
phpgwapi/js/jsapi/egw_utils.js
Normal file
165
phpgwapi/js/jsapi/egw_utils.js
Normal file
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* EGroupware clientside API object
|
||||
*
|
||||
* @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 (as AT stylite.de)
|
||||
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
|
||||
egw.extend('utils', egw.MODULE_GLOBAL, function() {
|
||||
|
||||
function json_escape_string(input)
|
||||
{
|
||||
var len = input.length;
|
||||
var res = "";
|
||||
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
switch (input.charAt(i))
|
||||
{
|
||||
case '"':
|
||||
res += '\\"';
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
res += '\\n';
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
res += '\\r';
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
res += '\\\\';
|
||||
break;
|
||||
|
||||
case '\/':
|
||||
res += '\\/';
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
res += '\\b';
|
||||
break;
|
||||
|
||||
case '\f':
|
||||
res += '\\f';
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
res += '\\t';
|
||||
break;
|
||||
|
||||
default:
|
||||
res += input.charAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function json_encode_simple(input)
|
||||
{
|
||||
switch (input.constructor)
|
||||
{
|
||||
case String:
|
||||
return '"' + json_escape_string(input) + '"';
|
||||
|
||||
case Number:
|
||||
return input.toString();
|
||||
|
||||
case Boolean:
|
||||
return input ? 'true' : 'false';
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function json_encode(input)
|
||||
{
|
||||
if (input == null || !input && input.length == 0) return 'null';
|
||||
|
||||
var simple_res = json_encode_simple(input);
|
||||
if (simple_res == null)
|
||||
{
|
||||
switch (input.constructor)
|
||||
{
|
||||
case Array:
|
||||
var buf = [];
|
||||
for (var k in input)
|
||||
{
|
||||
//Filter non numeric entries
|
||||
if (!isNaN(k))
|
||||
buf.push(json_encode(input[k]));
|
||||
}
|
||||
return '[' + buf.join(',') + ']';
|
||||
|
||||
case Object:
|
||||
var buf = [];
|
||||
for (var k in input)
|
||||
{
|
||||
buf.push(json_encode_simple(k) + ':' + json_encode(input[k]));
|
||||
}
|
||||
return '{' + buf.join(',') + '}';
|
||||
|
||||
default:
|
||||
switch(typeof input)
|
||||
{
|
||||
case 'array':
|
||||
var buf = [];
|
||||
for (var k in input)
|
||||
{
|
||||
//Filter non numeric entries
|
||||
if (!isNaN(k))
|
||||
buf.push(json_encode(input[k]));
|
||||
}
|
||||
return '[' + buf.join(',') + ']';
|
||||
|
||||
case 'object':
|
||||
var buf = [];
|
||||
for (var k in input)
|
||||
{
|
||||
buf.push(json_encode_simple(k) + ':' + json_encode(input[k]));
|
||||
}
|
||||
return '{' + buf.join(',') + '}';
|
||||
|
||||
}
|
||||
return 'null';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return simple_res;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the utils object which contains references to all functions
|
||||
// covered by it.
|
||||
var utils = {};
|
||||
|
||||
// Check whether the browser already supports encoding JSON -- if yes, use
|
||||
// its implementation, otherwise our own
|
||||
if (typeof window.JSON !== 'undefined' && typeof window.JSON.stringify !== 'undefined')
|
||||
{
|
||||
utils["jsonEncode"] = JSON.stringify;
|
||||
}
|
||||
else
|
||||
{
|
||||
utils["jsonEncode"] = json_encode;
|
||||
}
|
||||
|
||||
// Return the extension
|
||||
return {"utils": utils};
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user