mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-06-20 09:58:04 +02:00
changed et2_core_inheritance.js to implement ClassWithAttributes extending Class from egw_inheritance and changed et2 objects to use ClassWithAttributes when required (also fixed lots of IDE warnings / added docu)
This commit is contained in:
parent
f517b5786f
commit
ac18b6cc8d
@ -503,7 +503,7 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode,
|
|||||||
*
|
*
|
||||||
* @augments Class
|
* @augments Class
|
||||||
*/
|
*/
|
||||||
var et2_surroundingsMgr = Class.extend(
|
var et2_surroundingsMgr = ClassWithAttributes.extend(
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
/*egw:uses
|
/*egw:uses
|
||||||
et2_core_common;
|
et2_core_common;
|
||||||
et2_core_inheritance;
|
egw_inheritance;
|
||||||
et2_core_phpExpressionCompiler;
|
et2_core_phpExpressionCompiler;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* EGroupware eTemplate2 - JS code for implementing inheritance
|
* EGroupware eTemplate2 - JS code for implementing inheritance with attributes
|
||||||
*
|
*
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @package etemplate
|
* @package etemplate
|
||||||
@ -14,360 +14,19 @@
|
|||||||
|
|
||||||
/*egw:uses
|
/*egw:uses
|
||||||
et2_core_common;
|
et2_core_common;
|
||||||
|
egw_inheritance;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
var ClassWithAttributes = Class.extend(
|
||||||
* Usage of the JS inheritance system
|
{
|
||||||
* ----------------------------------
|
|
||||||
*
|
|
||||||
* To create a class write
|
|
||||||
*
|
|
||||||
* MyClass = Class.extend([interfaces, ] functions);
|
|
||||||
*
|
|
||||||
* where "interfaces" is a single interface or an array of interfaces and
|
|
||||||
* functions an object containing the functions the class implements.
|
|
||||||
*
|
|
||||||
* An interface has to be created in the following way:
|
|
||||||
*
|
|
||||||
* var IBreathingObject = new Interface({
|
|
||||||
* breath: function() {}
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* var Human = Class.extend(IBreathingObject, {
|
|
||||||
* walk: function() {
|
|
||||||
* console.log("Walking");
|
|
||||||
* },
|
|
||||||
* speak: function(_words) {
|
|
||||||
* console.log(_words);
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* As "Human" does not implement the function "breath", "Human" is treated as
|
|
||||||
* abstract. Trying to create an instance of "Human" will throw an exception.
|
|
||||||
* However
|
|
||||||
*
|
|
||||||
* Human.prototype.implements(IBreathingObject);
|
|
||||||
*
|
|
||||||
* will return true. Lets create a specific class of "Human":
|
|
||||||
*
|
|
||||||
* var ChuckNorris = Human.extend({
|
|
||||||
* breath: function() {
|
|
||||||
* console.log("Chuck Norris does not breath, he holds air hostage.");
|
|
||||||
* },
|
|
||||||
* speak: function(_words) {
|
|
||||||
* console.warn("Chuck Norris says:");
|
|
||||||
* this._super(_words);
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
|
|
||||||
// The following code is mostly taken from
|
|
||||||
// http://ejohn.org/blog/simple-javascript-inheritance/
|
|
||||||
// some parts were slightly changed for better understanding. Added possiblity
|
|
||||||
// to use interfaces.
|
|
||||||
|
|
||||||
/* Simple JavaScript Inheritance
|
|
||||||
* By John Resig http://ejohn.org/
|
|
||||||
* MIT Licensed
|
|
||||||
*/
|
|
||||||
// Inspired by base2 and Prototype
|
|
||||||
(function(){
|
|
||||||
var initializing = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn this to "true" to track creation and destruction of elements
|
|
||||||
*/
|
|
||||||
var getMem_freeMem_trace = false;
|
|
||||||
|
|
||||||
var tracedObjects = {};
|
|
||||||
|
|
||||||
// Check whether "function decompilation" works - fnTest is normally used to
|
|
||||||
// check whether a
|
|
||||||
var fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
|
||||||
|
|
||||||
// Base "Class" for interfaces - needed to check whether an object is an
|
|
||||||
// interface
|
|
||||||
this.Interface = function(fncts) {
|
|
||||||
for (var key in fncts)
|
|
||||||
{
|
|
||||||
this[key] = fncts[key];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The addInterfaceFunctions function adds all interface functions the class has
|
|
||||||
* to implement to the class prototype.
|
|
||||||
*/
|
|
||||||
function addInterfaceFunctions(prototype, interfaces)
|
|
||||||
{
|
|
||||||
// Remember all interface functions in the prototype
|
|
||||||
var ifaces = ((typeof prototype["_ifacefuncs"] == "undefined") ? [] :
|
|
||||||
prototype["_ifacefuncs"]);
|
|
||||||
|
|
||||||
prototype["_ifacefuncs"] = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < interfaces.length; i++)
|
|
||||||
{
|
|
||||||
var iface = interfaces[i];
|
|
||||||
if (iface instanceof Interface)
|
|
||||||
{
|
|
||||||
for (var key in iface)
|
|
||||||
{
|
|
||||||
prototype["_ifacefuncs"].push(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw("Interfaces must be instance of Interface!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < ifaces.length; i++)
|
|
||||||
{
|
|
||||||
prototype["_ifacefuncs"].push(ifaces[i]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function addAttributeFunctions(prototype, _super)
|
|
||||||
{
|
|
||||||
function _copyMerge(_new, _old)
|
|
||||||
{
|
|
||||||
var result = {};
|
|
||||||
|
|
||||||
// Copy the new object
|
|
||||||
if (typeof _new != "undefined")
|
|
||||||
{
|
|
||||||
for (var key in _new)
|
|
||||||
{
|
|
||||||
result[key] = _new[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge the old object
|
|
||||||
for (var key in _old)
|
|
||||||
{
|
|
||||||
if (typeof result[key] == "undefined")
|
|
||||||
{
|
|
||||||
result[key] = _old[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
var attributes = {};
|
|
||||||
|
|
||||||
// Copy the old attributes
|
|
||||||
for (var key in prototype.attributes)
|
|
||||||
{
|
|
||||||
attributes[key] = _copyMerge({}, prototype.attributes[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the old attributes to the new ones. If the attributes already
|
|
||||||
// exist, they are merged.
|
|
||||||
for (var key in _super.attributes)
|
|
||||||
{
|
|
||||||
var _old = _super.attributes[key];
|
|
||||||
var _new = {};
|
|
||||||
|
|
||||||
attributes[key] = _copyMerge(attributes[key], _old);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the attributes
|
|
||||||
for (var key in attributes)
|
|
||||||
{
|
|
||||||
et2_validateAttrib(key, attributes[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
prototype.attributes = attributes;
|
|
||||||
};
|
|
||||||
|
|
||||||
function classExtend(interfaces, prop) {
|
|
||||||
|
|
||||||
if (typeof prop == "undefined")
|
|
||||||
{
|
|
||||||
prop = interfaces;
|
|
||||||
interfaces = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a single interface is given, encapsulate it in an array
|
|
||||||
if (!(interfaces instanceof Array))
|
|
||||||
{
|
|
||||||
interfaces = [interfaces];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof prop.attributes == "undefined")
|
|
||||||
{
|
|
||||||
prop.attributes = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
var _super = this.prototype;
|
|
||||||
|
|
||||||
// Instantiate a base class (but only create the instance,
|
|
||||||
// don't run the init constructor)
|
|
||||||
initializing = true;
|
|
||||||
var prototype = new this();
|
|
||||||
initializing = false;
|
|
||||||
|
|
||||||
// Copy the properties over onto the new prototype
|
|
||||||
for (var name in prop) {
|
|
||||||
// Check if we're overwriting an existing function and check whether
|
|
||||||
// the function actually uses "_super" - the RegExp test function
|
|
||||||
// silently converts the funciton prop[name] to a string.
|
|
||||||
if (typeof prop[name] == "function" &&
|
|
||||||
typeof _super[name] == "function" && fnTest.test(prop[name]))
|
|
||||||
{
|
|
||||||
prototype[name] = (function(name, fn){
|
|
||||||
return function() {
|
|
||||||
var tmp = this._super;
|
|
||||||
|
|
||||||
// Add a new ._super() method that is the same method
|
|
||||||
// but on the super-class
|
|
||||||
this._super = _super[name];
|
|
||||||
|
|
||||||
// The method only need to be bound temporarily, so we
|
|
||||||
// remove it when we're done executing
|
|
||||||
var ret = fn.apply(this, arguments);
|
|
||||||
this._super = tmp;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
})(name, prop[name]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prototype[name] = prop[name];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the interface functions and the "implements" function to the
|
|
||||||
// prototype
|
|
||||||
addInterfaceFunctions(prototype, interfaces);
|
|
||||||
|
|
||||||
// Merge the attributes and create the functions corresponding to the
|
|
||||||
// attributes
|
|
||||||
addAttributeFunctions(prototype, _super);
|
|
||||||
|
|
||||||
// The dummy class constructor
|
|
||||||
function Class() {
|
|
||||||
// All construction is actually done in the init method
|
|
||||||
if (!initializing)
|
|
||||||
{
|
|
||||||
// Check whether the object implements all interface functions
|
|
||||||
for (var i = 0; i < this._ifacefuncs.length; i++)
|
|
||||||
{
|
|
||||||
var func = this._ifacefuncs[i];
|
|
||||||
if (!(typeof this[func] == "function"))
|
|
||||||
{
|
|
||||||
throw("Trying to create abstract object, interface " +
|
|
||||||
"function '" + func + "' not implemented.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do some tracing of the getMem_freeMem_trace is activated
|
|
||||||
if (getMem_freeMem_trace)
|
|
||||||
{
|
|
||||||
this.__OBJ_UID = "obj_" + egw.uid();
|
|
||||||
var className = this.className();
|
|
||||||
tracedObjects[this.__OBJ_UID] = {
|
|
||||||
"created": new Date().getTime(),
|
|
||||||
"class": className
|
|
||||||
}
|
|
||||||
egw.debug("log", "*" + this.__OBJ_UID + " (" + className + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.init)
|
|
||||||
{
|
|
||||||
this.init.apply(this, arguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate our constructed prototype object
|
|
||||||
Class.prototype = prototype;
|
|
||||||
|
|
||||||
// Enforce the constructor to be what we expect
|
|
||||||
Class.prototype.constructor = Class;
|
|
||||||
|
|
||||||
// And make this class extendable
|
|
||||||
Class.extend = classExtend;
|
|
||||||
|
|
||||||
return Class;
|
|
||||||
};
|
|
||||||
|
|
||||||
// The base Class implementation (does nothing)
|
|
||||||
this.Class = function(){};
|
|
||||||
|
|
||||||
// Create a new Class that inherits from this class. The first parameter
|
|
||||||
// is an array which defines a set of interfaces the object has to
|
|
||||||
// implement. An interface is simply an object with named functions.
|
|
||||||
Class.extend = classExtend;
|
|
||||||
|
|
||||||
// The base class has no attributes
|
|
||||||
Class.prototype.attributes = {};
|
|
||||||
|
|
||||||
// Add the basic functions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor function - it calls "destroy" if it has been defined and then
|
|
||||||
* deletes all keys of this element, so that any access to this element will
|
|
||||||
* eventually throw an exception, making it easier to hunt down memory leaks.
|
|
||||||
*/
|
|
||||||
Class.prototype.free = function() {
|
|
||||||
if (this.destroy)
|
|
||||||
{
|
|
||||||
this.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trace the freeing of the object
|
|
||||||
if (getMem_freeMem_trace)
|
|
||||||
{
|
|
||||||
delete(tracedObjects[this.__OBJ_UID]);
|
|
||||||
egw.debug("log", "-" + this.__OBJ_UID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete every object entry
|
|
||||||
for (var key in this)
|
|
||||||
{
|
|
||||||
delete(this[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't raise an exception when attempting to free an element multiple
|
|
||||||
// times.
|
|
||||||
this.free = function() {};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Some debug functions for memory leak hunting
|
|
||||||
if (getMem_freeMem_trace)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Prints a list of all objects UIDs which have not been freed yet.
|
|
||||||
*/
|
|
||||||
Class.prototype.showTrace = function() {
|
|
||||||
console.log(tracedObjects);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* VERY slow - for debugging only!
|
|
||||||
*/
|
|
||||||
Class.prototype.className = function() {
|
|
||||||
for (var key in window)
|
|
||||||
{
|
|
||||||
if (key.substr(0, 3) == "et2" && this.constructor == window[key])
|
|
||||||
{
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the given attribute. If the property does not
|
* Returns the value of the given attribute. If the property does not
|
||||||
* exist, an error message is issued.
|
* exist, an error message is issued.
|
||||||
|
*
|
||||||
|
* @param {string} _name
|
||||||
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
Class.prototype.getAttribute = function(_name) {
|
getAttribute: function(_name) {
|
||||||
if (typeof this.attributes[_name] != "undefined" &&
|
if (typeof this.attributes[_name] != "undefined" &&
|
||||||
!this.attributes[_name].ignore)
|
!this.attributes[_name].ignore)
|
||||||
{
|
{
|
||||||
@ -384,15 +43,19 @@
|
|||||||
{
|
{
|
||||||
egw.debug("error", this, "Attribute '" + _name + "' does not exist!");
|
egw.debug("error", this, "Attribute '" + _name + "' does not exist!");
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The setAttribute function sets the attribute with the given name to
|
* The setAttribute function sets the attribute with the given name to
|
||||||
* the given value. _override defines, whether this[_name] will be set,
|
* the given value. _override defines, whether this[_name] will be set,
|
||||||
* if this key already exists. _override defaults to true. A warning
|
* if this key already exists. _override defaults to true. A warning
|
||||||
* is issued if the attribute does not exist.
|
* is issued if the attribute does not exist.
|
||||||
|
*
|
||||||
|
* @param {string} _name
|
||||||
|
* @param {*} _value
|
||||||
|
* @param {boolean} _override
|
||||||
*/
|
*/
|
||||||
Class.prototype.setAttribute = function(_name, _value, _override) {
|
setAttribute: function(_name, _value, _override) {
|
||||||
if (typeof this.attributes[_name] != "undefined")
|
if (typeof this.attributes[_name] != "undefined")
|
||||||
{
|
{
|
||||||
if (!this.attributes[_name].ignore)
|
if (!this.attributes[_name].ignore)
|
||||||
@ -419,16 +82,16 @@
|
|||||||
{
|
{
|
||||||
egw.debug("warn", this, "Attribute '" + _name + "' does not exist!");
|
egw.debug("warn", this, "Attribute '" + _name + "' does not exist!");
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* generateAttributeSet sanitizes the given associative array of attributes
|
* generateAttributeSet sanitizes the given associative array of attributes
|
||||||
* (by passing each entry to "et2_checkType" and checking for existance of
|
* (by passing each entry to "et2_checkType" and checking for existance of
|
||||||
* the attribute) and adds the default values to the associative array.
|
* the attribute) and adds the default values to the associative array.
|
||||||
*
|
*
|
||||||
* @param _attrs is the associative array containing the attributes.
|
* @param {object} _attrs is the associative array containing the attributes.
|
||||||
*/
|
*/
|
||||||
Class.prototype.generateAttributeSet = function(_attrs) {
|
generateAttributeSet: function(_attrs) {
|
||||||
|
|
||||||
// Sanity check and validation
|
// Sanity check and validation
|
||||||
for (var key in _attrs)
|
for (var key in _attrs)
|
||||||
@ -466,15 +129,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return _attrs;
|
return _attrs;
|
||||||
};
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The initAttributes function sets the attributes to their default
|
* The initAttributes function sets the attributes to their default
|
||||||
* values. The attributes are not overwritten, which means, that the
|
* values. The attributes are not overwritten, which means, that the
|
||||||
* default is only set, if either a setter exists or this[propName] does
|
* default is only set, if either a setter exists or this[propName] does
|
||||||
* not exist yet.
|
* not exist yet.
|
||||||
|
*
|
||||||
|
* @param {object} _attrs is the associative array containing the attributes.
|
||||||
*/
|
*/
|
||||||
Class.prototype.initAttributes = function(_attrs) {
|
initAttributes: function(_attrs) {
|
||||||
for (var key in _attrs)
|
for (var key in _attrs)
|
||||||
{
|
{
|
||||||
if (typeof this.attributes[key] != "undefined" && !this.attributes[key].ignore && !(_attrs[key] == undefined))
|
if (typeof this.attributes[key] != "undefined" && !this.attributes[key].ignore && !(_attrs[key] == undefined))
|
||||||
@ -482,38 +147,14 @@
|
|||||||
this.setAttribute(key, _attrs[key], false);
|
this.setAttribute(key, _attrs[key], false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
/**
|
_validate_attributes: function(attributes)
|
||||||
* The implements function can be used to check whether the object
|
{
|
||||||
* implements the given interface.
|
// Validate the attributes
|
||||||
*/
|
for (var key in attributes)
|
||||||
Class.prototype.implements = function(_iface) {
|
|
||||||
for (var key in _iface)
|
|
||||||
{
|
{
|
||||||
if (this._ifacefuncs.indexOf(key) < 0)
|
et2_validateAttrib(key, attributes[key]);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* The instanceOf function can be used to check for both - classes and
|
|
||||||
* interfaces. Please don't change the case of this function as this
|
|
||||||
* affects IE and Opera support.
|
|
||||||
*/
|
|
||||||
Class.prototype.instanceOf = function(_obj) {
|
|
||||||
if (_obj instanceof Interface)
|
|
||||||
{
|
|
||||||
return this.implements(_obj);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return this instanceof _obj;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}).call(window);
|
|
||||||
|
|
@ -24,11 +24,11 @@ var et2_IDOMNode = new Interface({
|
|||||||
* Returns the DOM-Node of the current widget. The return value has to be
|
* Returns the DOM-Node of the current widget. The return value has to be
|
||||||
* a plain DOM node. If you want to return an jQuery object as you receive
|
* a plain DOM node. If you want to return an jQuery object as you receive
|
||||||
* it with
|
* it with
|
||||||
*
|
*
|
||||||
* obj = $j(node);
|
* obj = $j(node);
|
||||||
*
|
*
|
||||||
* simply return obj[0];
|
* simply return obj[0];
|
||||||
*
|
*
|
||||||
* @param _sender The _sender parameter defines which widget is asking for
|
* @param _sender The _sender parameter defines which widget is asking for
|
||||||
* the DOMNode. Depending on that, the widget may return different nodes.
|
* the DOMNode. Depending on that, the widget may return different nodes.
|
||||||
* This is used in the grid. Normally the _sender parameter can be omitted
|
* This is used in the grid. Normally the _sender parameter can be omitted
|
||||||
@ -58,19 +58,19 @@ var et2_IInput = new Interface({
|
|||||||
* Causes the dirty flag to be reseted.
|
* Causes the dirty flag to be reseted.
|
||||||
*/
|
*/
|
||||||
resetDirty: function() {},
|
resetDirty: function() {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the data to see if it is valid, as far as the client side can tell.
|
* Checks the data to see if it is valid, as far as the client side can tell.
|
||||||
* Return true if it's not possible to tell on the client side, because the server
|
* Return true if it's not possible to tell on the client side, because the server
|
||||||
* will have the chance to validate also.
|
* will have the chance to validate also.
|
||||||
*
|
*
|
||||||
* The messages array is to be populated with everything wrong with the data,
|
* The messages array is to be populated with everything wrong with the data,
|
||||||
* so don't stop checking after the first problem unless it really makes sense
|
* so don't stop checking after the first problem unless it really makes sense
|
||||||
* to ignore other problems.
|
* to ignore other problems.
|
||||||
*
|
*
|
||||||
* @param {String[]} messages List of messages explaining the failure(s).
|
* @param {String[]} messages List of messages explaining the failure(s).
|
||||||
* messages should be fairly short, and already translated.
|
* messages should be fairly short, and already translated.
|
||||||
*
|
*
|
||||||
* @return {boolean} True if the value is valid (enough), false to fail
|
* @return {boolean} True if the value is valid (enough), false to fail
|
||||||
*/
|
*/
|
||||||
isValid: function(messages) {}
|
isValid: function(messages) {}
|
||||||
@ -101,7 +101,7 @@ var et2_ISubmitListener = new Interface({
|
|||||||
/**
|
/**
|
||||||
* Called whenever the template gets submitted. Return false if you want to
|
* Called whenever the template gets submitted. Return false if you want to
|
||||||
* stop submission.
|
* stop submission.
|
||||||
*
|
*
|
||||||
* @param _values contains the values which will be sent to the server.
|
* @param _values contains the values which will be sent to the server.
|
||||||
* Listeners may change these values before they get submitted.
|
* Listeners may change these values before they get submitted.
|
||||||
*/
|
*/
|
||||||
@ -119,6 +119,8 @@ var et2_IDetachedDOM = new Interface({
|
|||||||
* Creates a list of attributes which can be set when working in the
|
* Creates a list of attributes which can be set when working in the
|
||||||
* "detached" mode. The result is stored in the _attrs array which is provided
|
* "detached" mode. The result is stored in the _attrs array which is provided
|
||||||
* by the calling code.
|
* by the calling code.
|
||||||
|
*
|
||||||
|
* @param {array} _attrs
|
||||||
*/
|
*/
|
||||||
getDetachedAttributes: function(_attrs) {},
|
getDetachedAttributes: function(_attrs) {},
|
||||||
|
|
||||||
|
@ -102,9 +102,9 @@ function et2_createWidget(_name, _attrs, _parent)
|
|||||||
/**
|
/**
|
||||||
* The et2 widget base class.
|
* The et2 widget base class.
|
||||||
*
|
*
|
||||||
* @augments Class
|
* @augments ClassWithAttributes
|
||||||
*/
|
*/
|
||||||
var et2_widget = Class.extend(
|
var et2_widget = ClassWithAttributes.extend(
|
||||||
{
|
{
|
||||||
attributes: {
|
attributes: {
|
||||||
"id": {
|
"id": {
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
* header, etc.) and contains the root container: an instance of
|
* header, etc.) and contains the root container: an instance of
|
||||||
* et2_dataview_view_grid, which can be accessed using the "grid" property of
|
* et2_dataview_view_grid, which can be accessed using the "grid" property of
|
||||||
* this object.
|
* this object.
|
||||||
*
|
*
|
||||||
* @augments Class
|
* @augments Class
|
||||||
*/
|
*/
|
||||||
var et2_dataview = Class.extend({
|
var et2_dataview = Class.extend({
|
||||||
@ -55,7 +55,9 @@ var et2_dataview = Class.extend({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for the grid container
|
* Constructor for the grid container
|
||||||
* @param object _parentNode is the DOM-Node into which the grid view will be inserted
|
*
|
||||||
|
* @param {DOMElement} _parentNode is the DOM-Node into which the grid view will be inserted
|
||||||
|
* @param {egw} _egw
|
||||||
* @memberOf et2_dataview
|
* @memberOf et2_dataview
|
||||||
*/
|
*/
|
||||||
init: function(_parentNode, _egw) {
|
init: function(_parentNode, _egw) {
|
||||||
@ -158,7 +160,7 @@ var et2_dataview = Class.extend({
|
|||||||
resize: function(_w, _h) {
|
resize: function(_w, _h) {
|
||||||
// Not fully initialized yet...
|
// Not fully initialized yet...
|
||||||
if (!this.columnMgr) return;
|
if (!this.columnMgr) return;
|
||||||
|
|
||||||
if (this.width != _w)
|
if (this.width != _w)
|
||||||
{
|
{
|
||||||
this.width = _w;
|
this.width = _w;
|
||||||
@ -192,7 +194,7 @@ var et2_dataview = Class.extend({
|
|||||||
/**
|
/**
|
||||||
* Recalculates the stylesheets which determine the column visibility and
|
* Recalculates the stylesheets which determine the column visibility and
|
||||||
* width.
|
* width.
|
||||||
*
|
*
|
||||||
* @param setDefault boolean Allow admins to save current settings as default for all users
|
* @param setDefault boolean Allow admins to save current settings as default for all users
|
||||||
*/
|
*/
|
||||||
updateColumns: function(setDefault) {
|
updateColumns: function(setDefault) {
|
||||||
@ -297,11 +299,11 @@ var et2_dataview = Class.extend({
|
|||||||
this.visibleColumnCount++;
|
this.visibleColumnCount++;
|
||||||
|
|
||||||
// Update the visibility of the column
|
// Update the visibility of the column
|
||||||
this.egw.css("." + col.tdClass,
|
this.egw.css("." + col.tdClass,
|
||||||
"display: table-cell; " +
|
"display: table-cell; " +
|
||||||
"!important;");
|
"!important;");
|
||||||
|
|
||||||
// Ugly browser dependant code - each browser seems to treat the
|
// Ugly browser dependant code - each browser seems to treat the
|
||||||
// right (collapsed) border of the row differently
|
// right (collapsed) border of the row differently
|
||||||
var subBorder = 0;
|
var subBorder = 0;
|
||||||
var subHBorder = 0;
|
var subHBorder = 0;
|
||||||
@ -336,12 +338,12 @@ var et2_dataview = Class.extend({
|
|||||||
|
|
||||||
// Write the width of the header columns
|
// Write the width of the header columns
|
||||||
var headerWidth = Math.max(0, (col.width - this.headerBorderWidth - subHBorder));
|
var headerWidth = Math.max(0, (col.width - this.headerBorderWidth - subHBorder));
|
||||||
this.egw.css(".egwGridView_outer ." + col.divClass,
|
this.egw.css(".egwGridView_outer ." + col.divClass,
|
||||||
"width: " + headerWidth + "px;");
|
"width: " + headerWidth + "px;");
|
||||||
|
|
||||||
// Write the width of the body-columns
|
// Write the width of the body-columns
|
||||||
var columnWidth = Math.max(0, (col.width - this.columnBorderWidth - subBorder));
|
var columnWidth = Math.max(0, (col.width - this.columnBorderWidth - subBorder));
|
||||||
this.egw.css(".egwGridView_grid ." + col.divClass,
|
this.egw.css(".egwGridView_grid ." + col.divClass,
|
||||||
"width: " + columnWidth + "px;");
|
"width: " + columnWidth + "px;");
|
||||||
|
|
||||||
totalWidth += col.width;
|
totalWidth += col.width;
|
||||||
@ -486,7 +488,7 @@ var et2_dataview = Class.extend({
|
|||||||
* Reads the scrollbar width
|
* Reads the scrollbar width
|
||||||
*/
|
*/
|
||||||
_getScrollbarWidth: function(_table) {
|
_getScrollbarWidth: function(_table) {
|
||||||
// Create a temporary td and two divs, which are inserted into the
|
// Create a temporary td and two divs, which are inserted into the
|
||||||
// DOM-Tree. The outer div has a fixed size and "overflow" set to auto.
|
// DOM-Tree. The outer div has a fixed size and "overflow" set to auto.
|
||||||
// When the second div is inserted, it will be forced to display a scrollbar.
|
// When the second div is inserted, it will be forced to display a scrollbar.
|
||||||
var div_inner = $j(document.createElement("div"))
|
var div_inner = $j(document.createElement("div"))
|
||||||
|
@ -49,7 +49,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
* requesting action links for a row. The row data, the index of the row and
|
* requesting action links for a row. The row data, the index of the row and
|
||||||
* the uid are passed as parameters to the function.
|
* the uid are passed as parameters to the function.
|
||||||
* uid is passed to the function.
|
* uid is passed to the function.
|
||||||
* @param _context is the context in which the _rowCallback and the
|
* @param _context is the context in which the _rowCallback and the
|
||||||
* _linkCallback are called.
|
* _linkCallback are called.
|
||||||
* @param _actionObjectManager is the object that manages the action
|
* @param _actionObjectManager is the object that manages the action
|
||||||
* objects.
|
* objects.
|
||||||
@ -64,7 +64,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
this._rowCallback = _rowCallback;
|
this._rowCallback = _rowCallback;
|
||||||
this._linkCallback = _linkCallback;
|
this._linkCallback = _linkCallback;
|
||||||
this._context = _context;
|
this._context = _context;
|
||||||
|
|
||||||
// Initialize list of child controllers
|
// Initialize list of child controllers
|
||||||
this._children = [];
|
this._children = [];
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
this._makeIndexVisible,
|
this._makeIndexVisible,
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
|
||||||
// Record the child
|
// Record the child
|
||||||
if(this._parentController != null)
|
if(this._parentController != null)
|
||||||
{
|
{
|
||||||
@ -106,7 +106,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
|
|
||||||
// Clear the selection timeout
|
// Clear the selection timeout
|
||||||
this._clearTimer();
|
this._clearTimer();
|
||||||
|
|
||||||
// Remove the child from the child list
|
// Remove the child from the child list
|
||||||
if(this._parentController != null)
|
if(this._parentController != null)
|
||||||
{
|
{
|
||||||
@ -125,7 +125,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
* The update function queries the server for changes in the currently
|
* The update function queries the server for changes in the currently
|
||||||
* managed index range -- those changes are then merged into the current
|
* managed index range -- those changes are then merged into the current
|
||||||
* view without a complete rebuild of every row.
|
* view without a complete rebuild of every row.
|
||||||
*
|
*
|
||||||
* @param {boolean} clear Skip the fancy stuff, dump everything and start again.
|
* @param {boolean} clear Skip the fancy stuff, dump everything and start again.
|
||||||
* Completely clears the grid and selection.
|
* Completely clears the grid and selection.
|
||||||
*/
|
*/
|
||||||
@ -147,7 +147,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
|
|
||||||
// Free selection manager
|
// Free selection manager
|
||||||
this._selectionMgr.clear();
|
this._selectionMgr.clear();
|
||||||
|
|
||||||
// Clear the map
|
// Clear the map
|
||||||
this._indexMap = {}
|
this._indexMap = {}
|
||||||
// Update selection manager, it uses this by reference
|
// Update selection manager, it uses this by reference
|
||||||
@ -211,7 +211,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
{
|
{
|
||||||
// Skip any extra keys
|
// Skip any extra keys
|
||||||
if(typeof data[key] != "object" || data[key] == null || typeof data[key][uid_key] == "undefined") continue;
|
if(typeof data[key] != "object" || data[key] == null || typeof data[key][uid_key] == "undefined") continue;
|
||||||
|
|
||||||
// Add to row / uid map
|
// Add to row / uid map
|
||||||
var entry = this._getIndexEntry(idx++);
|
var entry = this._getIndexEntry(idx++);
|
||||||
entry.uid = data[key][uid_key]+"";
|
entry.uid = data[key][uid_key]+"";
|
||||||
@ -252,7 +252,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the row information of the passed node, or null if not available
|
* Returns the row information of the passed node, or null if not available
|
||||||
*
|
*
|
||||||
* @param {DOMNode} node
|
* @param {DOMNode} node
|
||||||
* @return {string|false} UID, or false if not found
|
* @return {string|false} UID, or false if not found
|
||||||
*/
|
*/
|
||||||
@ -260,7 +260,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
// Whatever the node, find a TR
|
// Whatever the node, find a TR
|
||||||
var row_node = $j(node).closest('tr');
|
var row_node = $j(node).closest('tr');
|
||||||
var row = false
|
var row = false
|
||||||
|
|
||||||
// Check index map - simple case
|
// Check index map - simple case
|
||||||
var indexed = this._getIndexEntry(row_node.index());
|
var indexed = this._getIndexEntry(row_node.index());
|
||||||
if(indexed && indexed.row && indexed.row.getDOMNode() == row_node[0])
|
if(indexed && indexed.row && indexed.row.getDOMNode() == row_node[0])
|
||||||
@ -280,7 +280,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check children
|
// Check children
|
||||||
for(var i = 0; !row && i < this._children.length; i++)
|
for(var i = 0; !row && i < this._children.length; i++)
|
||||||
{
|
{
|
||||||
@ -612,7 +612,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
{
|
{
|
||||||
$j(tr).addClass("subentry");
|
$j(tr).addClass("subentry");
|
||||||
$j("td:first",tr).children("div").last().addClass("level_" + d + " indentation");
|
$j("td:first",tr).children("div").last().addClass("level_" + d + " indentation");
|
||||||
|
|
||||||
if(this.entry.idx == 0)
|
if(this.entry.idx == 0)
|
||||||
{
|
{
|
||||||
// Set the CSS for the level - required so columns line up
|
// Set the CSS for the level - required so columns line up
|
||||||
@ -811,7 +811,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
|
|
||||||
_fetchCallback: function (_response) {
|
_fetchCallback: function (_response) {
|
||||||
this.self._lastModification = _response.lastModification;
|
this.self._lastModification = _response.lastModification;
|
||||||
|
|
||||||
// Do nothing if _response.order evaluates to false
|
// Do nothing if _response.order evaluates to false
|
||||||
if (!_response.order)
|
if (!_response.order)
|
||||||
{
|
{
|
||||||
@ -834,7 +834,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
for(var i = this.start; i < this.start + order.length; i++)
|
for(var i = this.start; i < this.start + order.length; i++)
|
||||||
delete this.self._queue[i];
|
delete this.self._queue[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the current index map for the updated region
|
// Get the current index map for the updated region
|
||||||
var idxMap = this.self._getIndexMapping(this.start, order.length);
|
var idxMap = this.self._getIndexMapping(this.start, order.length);
|
||||||
|
|
||||||
@ -860,11 +860,11 @@ var et2_dataview_controller = Class.extend({
|
|||||||
|
|
||||||
// Now it's OK to invalidate, if it wasn't before
|
// Now it's OK to invalidate, if it wasn't before
|
||||||
this.self._grid.doInvalidate = true;
|
this.self._grid.doInvalidate = true;
|
||||||
|
|
||||||
// Update the total element count in the grid
|
// Update the total element count in the grid
|
||||||
this.self._grid.setTotalCount(_response.total);
|
this.self._grid.setTotalCount(_response.total);
|
||||||
this.self._selectionMgr.setTotalCount(_response.total);
|
this.self._selectionMgr.setTotalCount(_response.total);
|
||||||
|
|
||||||
// Schedule an invalidate, in case total is the same
|
// Schedule an invalidate, in case total is the same
|
||||||
this.self._grid.invalidate();
|
this.self._grid.invalidate();
|
||||||
},
|
},
|
||||||
@ -892,7 +892,7 @@ var et2_dataview_controller = Class.extend({
|
|||||||
this._context,
|
this._context,
|
||||||
{},
|
{},
|
||||||
0,
|
0,
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this._selectionMgr.registerRow("",0,placeholder.get(0), links);
|
this._selectionMgr.registerRow("",0,placeholder.get(0), links);
|
||||||
|
@ -24,14 +24,14 @@
|
|||||||
* manage an external action object interface for each visible row and proxy all
|
* manage an external action object interface for each visible row and proxy all
|
||||||
* state changes between an dummy action object, that does no selection handling,
|
* state changes between an dummy action object, that does no selection handling,
|
||||||
* and the external action object interface.
|
* and the external action object interface.
|
||||||
*
|
*
|
||||||
* @augments Class
|
* @augments Class
|
||||||
*/
|
*/
|
||||||
var et2_dataview_selectionManager = Class.extend(
|
var et2_dataview_selectionManager = Class.extend(
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param _parent
|
* @param _parent
|
||||||
* @param _indexMap
|
* @param _indexMap
|
||||||
* @param _actionObjectManager
|
* @param _actionObjectManager
|
||||||
@ -214,10 +214,10 @@ var et2_dataview_selectionManager = Class.extend(
|
|||||||
this.resetSelection();
|
this.resetSelection();
|
||||||
|
|
||||||
this._selectAll = true;
|
this._selectAll = true;
|
||||||
|
|
||||||
// Tell action manager to do all
|
// Tell action manager to do all
|
||||||
this._actionObjectManager.setAllSelected(true);
|
this._actionObjectManager.setAllSelected(true);
|
||||||
|
|
||||||
// Update the selection
|
// Update the selection
|
||||||
for (var key in this._registeredRows)
|
for (var key in this._registeredRows)
|
||||||
{
|
{
|
||||||
@ -519,7 +519,7 @@ var et2_dataview_selectionManager = Class.extend(
|
|||||||
// Query all unknown ranges from the server
|
// Query all unknown ranges from the server
|
||||||
for (var i = 0; i < queryRanges.length; i++)
|
for (var i = 0; i < queryRanges.length; i++)
|
||||||
{
|
{
|
||||||
this._queryRangeCallback.call(this._context, queryRanges[i],
|
this._queryRangeCallback.call(this._context, queryRanges[i],
|
||||||
function (_order) {
|
function (_order) {
|
||||||
for (var j = 0; j < _order.length; j++)
|
for (var j = 0; j < _order.length; j++)
|
||||||
{
|
{
|
||||||
|
@ -26,10 +26,10 @@ var ET2_COL_VISIBILITY_ALWAYS_NOSELECT = 3;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class which stores the data of a single column.
|
* Class which stores the data of a single column.
|
||||||
*
|
*
|
||||||
* @augments Class
|
* @augments Class
|
||||||
*/
|
*/
|
||||||
var et2_dataview_column = Class.extend({
|
var et2_dataview_column = ClassWithAttributes.extend({
|
||||||
|
|
||||||
attributes: {
|
attributes: {
|
||||||
"id": {
|
"id": {
|
||||||
@ -72,7 +72,7 @@ var et2_dataview_column = Class.extend({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param _attrs
|
* @param _attrs
|
||||||
* @memberOf et2_dataview_column
|
* @memberOf et2_dataview_column
|
||||||
*/
|
*/
|
||||||
@ -114,7 +114,7 @@ var et2_dataview_column = Class.extend({
|
|||||||
set_visibility: function(_value) {
|
set_visibility: function(_value) {
|
||||||
// If visibility is always, don't turn it off
|
// If visibility is always, don't turn it off
|
||||||
if(this.visibility == ET2_COL_VISIBILITY_ALWAYS || this.visibility == ET2_COL_VISIBILITY_ALWAYS_NOSELECT) return;
|
if(this.visibility == ET2_COL_VISIBILITY_ALWAYS || this.visibility == ET2_COL_VISIBILITY_ALWAYS_NOSELECT) return;
|
||||||
|
|
||||||
if(_value === true)
|
if(_value === true)
|
||||||
{
|
{
|
||||||
this.visibility = ET2_COL_VISIBILITY_VISIBLE;
|
this.visibility = ET2_COL_VISIBILITY_VISIBLE;
|
||||||
@ -167,6 +167,8 @@ var et2_dataview_columns = Class.extend({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the total width of the header row
|
* Set the total width of the header row
|
||||||
|
*
|
||||||
|
* @param {(string|number)} _width
|
||||||
*/
|
*/
|
||||||
setTotalWidth: function(_width) {
|
setTotalWidth: function(_width) {
|
||||||
if (_width != this.totalWidth && _width > 0)
|
if (_width != this.totalWidth && _width > 0)
|
||||||
@ -178,6 +180,8 @@ var et2_dataview_columns = Class.extend({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index of the colum with the given id
|
* Returns the index of the colum with the given id
|
||||||
|
*
|
||||||
|
* @param {string} _id
|
||||||
*/
|
*/
|
||||||
getColumnIndexById: function(_id) {
|
getColumnIndexById: function(_id) {
|
||||||
for (var i = 0; i < this.columns.length; i++)
|
for (var i = 0; i < this.columns.length; i++)
|
||||||
@ -192,6 +196,8 @@ var et2_dataview_columns = Class.extend({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the column with the given id
|
* Returns the column with the given id
|
||||||
|
*
|
||||||
|
* @param {string} _id
|
||||||
*/
|
*/
|
||||||
getColumnById: function(_id) {
|
getColumnById: function(_id) {
|
||||||
var idx = this.getColumnIndexById(_id);
|
var idx = this.getColumnIndexById(_id);
|
||||||
@ -200,6 +206,8 @@ var et2_dataview_columns = Class.extend({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the width of the column with the given index
|
* Returns the width of the column with the given index
|
||||||
|
*
|
||||||
|
* @param {number} _idx
|
||||||
*/
|
*/
|
||||||
getColumnWidth: function(_idx) {
|
getColumnWidth: function(_idx) {
|
||||||
if (this.totalWidth > 0 && _idx >= 0 && _idx < this.columns.length)
|
if (this.totalWidth > 0 && _idx >= 0 && _idx < this.columns.length)
|
||||||
@ -262,6 +270,8 @@ var et2_dataview_columns = Class.extend({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a column visiblity set
|
* Sets a column visiblity set
|
||||||
|
*
|
||||||
|
* @param {object} _set
|
||||||
*/
|
*/
|
||||||
setColumnVisibilitySet: function(_set) {
|
setColumnVisibilitySet: function(_set) {
|
||||||
for (var k in _set)
|
for (var k in _set)
|
||||||
@ -331,7 +341,7 @@ var et2_dataview_columns = Class.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
remRelWidth -= fixedTotal / tw;
|
remRelWidth -= fixedTotal / tw;
|
||||||
|
|
||||||
// Check whether the width of columns with relative width is larger than their
|
// Check whether the width of columns with relative width is larger than their
|
||||||
// maxWidth
|
// maxWidth
|
||||||
var done;
|
var done;
|
||||||
@ -419,13 +429,13 @@ var et2_dataview_columns = Class.extend({
|
|||||||
this.columnWidths.push(w);
|
this.columnWidths.push(w);
|
||||||
usedTotal += w;
|
usedTotal += w;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deal with any accumulated rounding errors
|
// Deal with any accumulated rounding errors
|
||||||
if(usedTotal != tw)
|
if(usedTotal != tw)
|
||||||
{
|
{
|
||||||
var column, columnIndex;
|
var column, columnIndex;
|
||||||
var remaining_width = (usedTotal - tw);
|
var remaining_width = (usedTotal - tw);
|
||||||
|
|
||||||
// Pick the first relative column and use it
|
// Pick the first relative column and use it
|
||||||
for(columnIndex = 0; columnIndex < this.columns.length; columnIndex++)
|
for(columnIndex = 0; columnIndex < this.columns.length; columnIndex++)
|
||||||
{
|
{
|
||||||
@ -452,7 +462,7 @@ var et2_dataview_columns = Class.extend({
|
|||||||
for(var i = 0; i < this.columns.length; i++)
|
for(var i = 0; i < this.columns.length; i++)
|
||||||
{
|
{
|
||||||
var col = this.columns[i];
|
var col = this.columns[i];
|
||||||
col.fixedWidth -= Math.round(this.columnWidths[i] / tw * remaining_width)
|
col.fixedWidth -= Math.round(this.columnWidths[i] / tw * remaining_width);
|
||||||
this.columnWidths[i] = Math.max(0, Math.min(col.fixedWidth,tw));
|
this.columnWidths[i] = Math.max(0, Math.min(col.fixedWidth,tw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict"
|
"use strict";
|
||||||
|
|
||||||
/*egw:uses
|
/*egw:uses
|
||||||
jquery.jquery;
|
jquery.jquery;
|
||||||
@ -30,10 +30,10 @@
|
|||||||
* A container does not know where it resides inside the grid, or whether it is
|
* A container does not know where it resides inside the grid, or whether it is
|
||||||
* currently visible or not -- this information is efficiently managed by the
|
* currently visible or not -- this information is efficiently managed by the
|
||||||
* et2_dataview_grid container.
|
* et2_dataview_grid container.
|
||||||
*
|
*
|
||||||
* @augments Class
|
* @augments Class
|
||||||
*/
|
*/
|
||||||
var et2_dataview_container = Class.extend(et2_dataview_IInvalidatable,
|
var et2_dataview_container = Class.extend(et2_dataview_IInvalidatable,
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Initializes the container object.
|
* Initializes the container object.
|
||||||
@ -77,6 +77,9 @@ var et2_dataview_container = Class.extend(et2_dataview_IInvalidatable,
|
|||||||
* Sets the "destroyCallback" -- the given function gets called whenever
|
* Sets the "destroyCallback" -- the given function gets called whenever
|
||||||
* the container is destroyed. This instance is passed as an parameter to
|
* the container is destroyed. This instance is passed as an parameter to
|
||||||
* the callback.
|
* the callback.
|
||||||
|
*
|
||||||
|
* @param {function} _callback
|
||||||
|
* @param {object} _context
|
||||||
*/
|
*/
|
||||||
setDestroyCallback: function(_callback, _context) {
|
setDestroyCallback: function(_callback, _context) {
|
||||||
this._destroyCallback = _callback;
|
this._destroyCallback = _callback;
|
||||||
@ -182,6 +185,8 @@ var et2_dataview_container = Class.extend(et2_dataview_IInvalidatable,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a certain node from the container
|
* Removes a certain node from the container
|
||||||
|
*
|
||||||
|
* @param {DOMElement} _node
|
||||||
*/
|
*/
|
||||||
removeNode: function(_node) {
|
removeNode: function(_node) {
|
||||||
// Get the index of the node in the nodes array
|
// Get the index of the node in the nodes array
|
||||||
@ -296,6 +301,8 @@ var et2_dataview_container = Class.extend(et2_dataview_IInvalidatable,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the top of the element.
|
* Sets the top of the element.
|
||||||
|
*
|
||||||
|
* @param {number} _value
|
||||||
*/
|
*/
|
||||||
setTop: function(_value) {
|
setTop: function(_value) {
|
||||||
this._top = _value;
|
this._top = _value;
|
||||||
@ -303,6 +310,8 @@ var et2_dataview_container = Class.extend(et2_dataview_IInvalidatable,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the index of the element.
|
* Sets the index of the element.
|
||||||
|
*
|
||||||
|
* @param {number} _value
|
||||||
*/
|
*/
|
||||||
setIndex: function(_value) {
|
setIndex: function(_value) {
|
||||||
this._index = _value;
|
this._index = _value;
|
||||||
@ -355,46 +364,16 @@ var et2_dataview_container = Class.extend(et2_dataview_IInvalidatable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
},
|
||||||
|
|
||||||
});
|
/**
|
||||||
|
* Returns the height of a node in pixels and zero if the element is not
|
||||||
/**
|
* visible. The height is clamped to positive values.
|
||||||
* Returns the height of a node in pixels and zero if the element is not
|
*
|
||||||
* visible. The height is clamped to positive values.
|
* @param {DOMElement} _node
|
||||||
* The browser switch is placed at this position as the _nodeHeight function is
|
*/
|
||||||
* one of the most frequently called functions in the whole grid code and should
|
_nodeHeight: function(_node)
|
||||||
* stay quite fast.
|
|
||||||
*/
|
|
||||||
/*if ($j.browser.mozilla)
|
|
||||||
{
|
|
||||||
et2_dataview_container.prototype._nodeHeight = function(_node)
|
|
||||||
{
|
|
||||||
var height = 0;
|
|
||||||
// Firefox sometimes provides fractional pixel values - we are
|
|
||||||
// forced to use those - we can obtain the fractional pixel height
|
|
||||||
// by using the window.getComputedStyle function
|
|
||||||
var compStyle = getComputedStyle(_node, null);
|
|
||||||
if (compStyle)
|
|
||||||
{
|
|
||||||
var styleHeightStr = compStyle.getPropertyValue("height");
|
|
||||||
height = parseFloat(styleHeightStr.substr(0,
|
|
||||||
styleHeightStr.length - 2));
|
|
||||||
|
|
||||||
if (isNaN(height) || height < 1)
|
|
||||||
{
|
|
||||||
height = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{*/
|
|
||||||
et2_dataview_container.prototype._nodeHeight = function(_node)
|
|
||||||
{
|
{
|
||||||
return _node.offsetHeight;
|
return _node.offsetHeight;
|
||||||
};
|
}
|
||||||
//}
|
});
|
||||||
|
|
||||||
|
@ -19,15 +19,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The row provider contains prototypes (full clonable dom-trees)
|
* The row provider contains prototypes (full clonable dom-trees)
|
||||||
* for all registered row types.
|
* for all registered row types.
|
||||||
*
|
*
|
||||||
* @augments Class
|
* @augments Class
|
||||||
*/
|
*/
|
||||||
var et2_dataview_rowProvider = Class.extend(
|
var et2_dataview_rowProvider = Class.extend(
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param _outerId
|
* @param _outerId
|
||||||
* @param _columnIds
|
* @param _columnIds
|
||||||
* @memberOf et2_dataview_rowProvider
|
* @memberOf et2_dataview_rowProvider
|
||||||
@ -57,6 +57,10 @@ var et2_dataview_rowProvider = Class.extend(
|
|||||||
* Returns a clone of the prototype with the given name. If the generator
|
* Returns a clone of the prototype with the given name. If the generator
|
||||||
* callback function is given, this function is called if the prototype
|
* callback function is given, this function is called if the prototype
|
||||||
* does not yet registered.
|
* does not yet registered.
|
||||||
|
*
|
||||||
|
* @param {string} _name
|
||||||
|
* @param {function} _generator
|
||||||
|
* @param {object} _context
|
||||||
*/
|
*/
|
||||||
getPrototype: function(_name, _generator, _context) {
|
getPrototype: function(_name, _generator, _context) {
|
||||||
if (typeof this._prototypes[_name] == "undefined")
|
if (typeof this._prototypes[_name] == "undefined")
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* Object which resizes an inner node to the maximum extend of an outer node
|
* Object which resizes an inner node to the maximum extend of an outer node
|
||||||
* (without creating a scrollbar) - it achieves that by performing some very
|
* (without creating a scrollbar) - it achieves that by performing some very
|
||||||
* nasty and time consuming calculations.
|
* nasty and time consuming calculations.
|
||||||
*
|
*
|
||||||
* @augments Class
|
* @augments Class
|
||||||
*/
|
*/
|
||||||
var et2_dynheight = Class.extend(
|
var et2_dynheight = Class.extend(
|
||||||
@ -51,6 +51,9 @@ var et2_dynheight = Class.extend(
|
|||||||
/**
|
/**
|
||||||
* Resizes the inner node. When this is done, the callback function is
|
* Resizes the inner node. When this is done, the callback function is
|
||||||
* called.
|
* called.
|
||||||
|
*
|
||||||
|
* @param {function} _callback
|
||||||
|
* @param {object} _context
|
||||||
*/
|
*/
|
||||||
update: function(_callback, _context) {
|
update: function(_callback, _context) {
|
||||||
// Check whether the inner node is actually visible - if not, don't
|
// Check whether the inner node is actually visible - if not, don't
|
||||||
@ -103,7 +106,7 @@ var et2_dynheight = Class.extend(
|
|||||||
var h = Math.max(this.minHeight, oh + ot - it - bh -
|
var h = Math.max(this.minHeight, oh + ot - it - bh -
|
||||||
this.innerMargin - this.outerMargin);
|
this.innerMargin - this.outerMargin);
|
||||||
this.innerNode.height(h);
|
this.innerNode.height(h);
|
||||||
|
|
||||||
// Update the width
|
// Update the width
|
||||||
// Some checking to make sure it doesn't overflow the width when user
|
// Some checking to make sure it doesn't overflow the width when user
|
||||||
// resizes the window
|
// resizes the window
|
||||||
@ -117,7 +120,7 @@ var et2_dynheight = Class.extend(
|
|||||||
{
|
{
|
||||||
this.innerNode.width(w);
|
this.innerNode.width(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the callback function
|
// Call the callback function
|
||||||
if (typeof _callback != "undefined")
|
if (typeof _callback != "undefined")
|
||||||
{
|
{
|
||||||
@ -129,6 +132,9 @@ var et2_dynheight = Class.extend(
|
|||||||
/**
|
/**
|
||||||
* Function used internally which collects all DOM-Nodes which are located
|
* Function used internally which collects all DOM-Nodes which are located
|
||||||
* below this element.
|
* below this element.
|
||||||
|
*
|
||||||
|
* @param {DOMElement} _node
|
||||||
|
* @param {number} _bottom
|
||||||
*/
|
*/
|
||||||
_collectBottomNodes: function(_node, _bottom) {
|
_collectBottomNodes: function(_node, _bottom) {
|
||||||
// Calculate the bottom position of the inner node
|
// Calculate the bottom position of the inner node
|
||||||
|
@ -19,16 +19,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The row provider contains prototypes (full clonable dom-trees)
|
* The row provider contains prototypes (full clonable dom-trees)
|
||||||
* for all registered row types.
|
* for all registered row types.
|
||||||
*
|
*
|
||||||
* @augments Class
|
* @augments Class
|
||||||
*/
|
*/
|
||||||
var et2_nextmatch_rowProvider = Class.extend(
|
var et2_nextmatch_rowProvider = ClassWithAttributes.extend(
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Creates the nextmatch row provider.
|
* Creates the nextmatch row provider.
|
||||||
*
|
*
|
||||||
|
* @param {et2_nextmatch_rowProvider} _rowProvider
|
||||||
|
* @param {function} _subgridCallback
|
||||||
|
* @param {object} _context
|
||||||
* @memberOf et2_nextmatch_rowProvider
|
* @memberOf et2_nextmatch_rowProvider
|
||||||
*/
|
*/
|
||||||
init: function (_rowProvider, _subgridCallback, _context) {
|
init: function (_rowProvider, _subgridCallback, _context) {
|
||||||
@ -77,7 +80,7 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
// interface or do not support all attributes listed in the et2_IDetachedDOM
|
// interface or do not support all attributes listed in the et2_IDetachedDOM
|
||||||
// interface. A warning is issued for all those widgets as they heavily
|
// interface. A warning is issued for all those widgets as they heavily
|
||||||
// degrade the performance of the dataview
|
// degrade the performance of the dataview
|
||||||
var seperated = rowTemplate.seperated =
|
var seperated = rowTemplate.seperated =
|
||||||
this._seperateWidgets(variableAttributes);
|
this._seperateWidgets(variableAttributes);
|
||||||
|
|
||||||
// Remove all DOM-Nodes of all widgets inside the "remaining" slot from
|
// Remove all DOM-Nodes of all widgets inside the "remaining" slot from
|
||||||
@ -169,7 +172,7 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
tr.appendChild(row);
|
tr.appendChild(row);
|
||||||
|
|
||||||
// Make the row expandable
|
// Make the row expandable
|
||||||
if (typeof _data.content["is_parent"] !== "undefined"
|
if (typeof _data.content["is_parent"] !== "undefined"
|
||||||
&& _data.content["is_parent"])
|
&& _data.content["is_parent"])
|
||||||
{
|
{
|
||||||
_row.makeExpandable(true, function () {
|
_row.makeExpandable(true, function () {
|
||||||
@ -189,12 +192,12 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
* Placeholder for empty row
|
* Placeholder for empty row
|
||||||
*
|
*
|
||||||
* The empty row placeholder is used when there are no results to display.
|
* The empty row placeholder is used when there are no results to display.
|
||||||
* This allows the user to still have a drop target, or use actions that
|
* This allows the user to still have a drop target, or use actions that
|
||||||
* do not require a row ID, such as 'Add new'.
|
* do not require a row ID, such as 'Add new'.
|
||||||
*/
|
*/
|
||||||
_createEmptyPrototype: function() {
|
_createEmptyPrototype: function() {
|
||||||
var label = this._context && this._context.options && this._context.options.settings.placeholder;
|
var label = this._context && this._context.options && this._context.options.settings.placeholder;
|
||||||
|
|
||||||
var placeholder = $j(document.createElement("td"))
|
var placeholder = $j(document.createElement("td"))
|
||||||
.attr("colspan",this._rowProvider.getColumnCount())
|
.attr("colspan",this._rowProvider.getColumnCount())
|
||||||
.css("height","19px")
|
.css("height","19px")
|
||||||
@ -208,6 +211,8 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array containing objects which have variable attributes
|
* Returns an array containing objects which have variable attributes
|
||||||
|
*
|
||||||
|
* @param {et2_widget} _widget
|
||||||
*/
|
*/
|
||||||
_getVariableAttributeSet: function(_widget) {
|
_getVariableAttributeSet: function(_widget) {
|
||||||
var variableAttributes = [];
|
var variableAttributes = [];
|
||||||
@ -337,6 +342,8 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes to DOM code for all widgets in the "remaining" slot
|
* Removes to DOM code for all widgets in the "remaining" slot
|
||||||
|
*
|
||||||
|
* @param {object} _rowTemplate
|
||||||
*/
|
*/
|
||||||
_stripTemplateRow: function(_rowTemplate) {
|
_stripTemplateRow: function(_rowTemplate) {
|
||||||
_rowTemplate.placeholders = [];
|
_rowTemplate.placeholders = [];
|
||||||
@ -347,7 +354,7 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
|
|
||||||
// Issue a warning - widgets which do not implement et2_IDOMNode
|
// Issue a warning - widgets which do not implement et2_IDOMNode
|
||||||
// are very slow
|
// are very slow
|
||||||
egw.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);
|
"might be slow", entry);
|
||||||
|
|
||||||
// Set the placeholder for the entry to null
|
// Set the placeholder for the entry to null
|
||||||
@ -374,7 +381,7 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
},
|
},
|
||||||
|
|
||||||
_nodeIndex: function(_node) {
|
_nodeIndex: function(_node) {
|
||||||
if(_node.parentNode == null)
|
if(_node.parentNode == null)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -391,6 +398,9 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a function which does a relative access on the given DOM-Node
|
* Returns a function which does a relative access on the given DOM-Node
|
||||||
|
*
|
||||||
|
* @param {DOMElement} _root
|
||||||
|
* @param {DOMElement} _target
|
||||||
*/
|
*/
|
||||||
_compileDOMAccessFunc: function(_root, _target) {
|
_compileDOMAccessFunc: function(_root, _target) {
|
||||||
function recordPath(_root, _target, _path)
|
function recordPath(_root, _target, _path)
|
||||||
@ -427,6 +437,8 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds relative paths to the DOM-Nodes and compiles fast-access functions
|
* Builds relative paths to the DOM-Nodes and compiles fast-access functions
|
||||||
|
*
|
||||||
|
* @param {object} _rowTemplate
|
||||||
*/
|
*/
|
||||||
_buildNodeAccessFuncs: function(_rowTemplate) {
|
_buildNodeAccessFuncs: function(_rowTemplate) {
|
||||||
for (var i = 0; i < _rowTemplate.seperated.detachable.length; i++)
|
for (var i = 0; i < _rowTemplate.seperated.detachable.length; i++)
|
||||||
@ -448,6 +460,10 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies additional row data (like the class) to the tr
|
* Applies additional row data (like the class) to the tr
|
||||||
|
*
|
||||||
|
* @param {object} _data
|
||||||
|
* @param {DOMElement} _tr
|
||||||
|
* @param {object} _mgrs
|
||||||
*/
|
*/
|
||||||
_setRowData: function (_data, _tr, _mgrs) {
|
_setRowData: function (_data, _tr, _mgrs) {
|
||||||
// TODO: Implement other fields than "class"
|
// TODO: Implement other fields than "class"
|
||||||
@ -479,7 +495,7 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
// If not using category (tracker, calendar list) look for sel_options in the rows
|
// If not using category (tracker, calendar list) look for sel_options in the rows
|
||||||
if(!categories) categories = _mgrs["sel_options"].parentMgr.getEntry(category_location);
|
if(!categories) categories = _mgrs["sel_options"].parentMgr.getEntry(category_location);
|
||||||
if(!categories) categories = _mgrs["sel_options"].getEntry("${row}["+category_location + "]");
|
if(!categories) categories = _mgrs["sel_options"].getEntry("${row}["+category_location + "]");
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
if(categories) this.categories = categories;
|
if(categories) this.categories = categories;
|
||||||
}
|
}
|
||||||
@ -525,11 +541,11 @@ var et2_nextmatch_rowProvider = Class.extend(
|
|||||||
/**
|
/**
|
||||||
* @augments et2_widget
|
* @augments et2_widget
|
||||||
*/
|
*/
|
||||||
var et2_nextmatch_rowWidget = et2_widget.extend(et2_IDOMNode,
|
var et2_nextmatch_rowWidget = et2_widget.extend(et2_IDOMNode,
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param _mgrs
|
* @param _mgrs
|
||||||
* @param _row
|
* @param _row
|
||||||
* @memberOf et2_nextmatch_rowWidget
|
* @memberOf et2_nextmatch_rowWidget
|
||||||
@ -549,6 +565,8 @@ var et2_nextmatch_rowWidget = et2_widget.extend(et2_IDOMNode,
|
|||||||
/**
|
/**
|
||||||
* Copies the given array manager and clones the given widgets and inserts
|
* Copies the given array manager and clones the given widgets and inserts
|
||||||
* them into the row which has been passed in the constructor.
|
* them into the row which has been passed in the constructor.
|
||||||
|
*
|
||||||
|
* @param {array} _widgets
|
||||||
*/
|
*/
|
||||||
createWidgets: function(_widgets) {
|
createWidgets: function(_widgets) {
|
||||||
// Clone the given the widgets with this element as parent
|
// Clone the given the widgets with this element as parent
|
||||||
@ -557,7 +575,7 @@ var et2_nextmatch_rowWidget = et2_widget.extend(et2_IDOMNode,
|
|||||||
{
|
{
|
||||||
// Disabled columns might be missing widget - skip it
|
// Disabled columns might be missing widget - skip it
|
||||||
if(!_widgets[i]) continue;
|
if(!_widgets[i]) continue;
|
||||||
|
|
||||||
this._widgets[i] = _widgets[i].clone(this);
|
this._widgets[i] = _widgets[i].clone(this);
|
||||||
this._widgets[i].loadingFinished();
|
this._widgets[i].loadingFinished();
|
||||||
// Set column alignment from widget
|
// Set column alignment from widget
|
||||||
@ -570,6 +588,9 @@ var et2_nextmatch_rowWidget = et2_widget.extend(et2_IDOMNode,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the column node for the given sender
|
* Returns the column node for the given sender
|
||||||
|
*
|
||||||
|
* @param {et2_widget} _sender
|
||||||
|
* @return {DOMElement}
|
||||||
*/
|
*/
|
||||||
getDOMNode: function(_sender) {
|
getDOMNode: function(_sender) {
|
||||||
for (var i = 0; i < this._widgets.length; i++)
|
for (var i = 0; i < this._widgets.length; i++)
|
||||||
@ -588,11 +609,11 @@ var et2_nextmatch_rowWidget = et2_widget.extend(et2_IDOMNode,
|
|||||||
/**
|
/**
|
||||||
* @augments et2_widget
|
* @augments et2_widget
|
||||||
*/
|
*/
|
||||||
var et2_nextmatch_rowTemplateWidget = et2_widget.extend(et2_IDOMNode,
|
var et2_nextmatch_rowTemplateWidget = et2_widget.extend(et2_IDOMNode,
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param _root
|
* @param _root
|
||||||
* @param _row
|
* @param _row
|
||||||
* @memberOf et2_nextmatch_rowTemplateWidget
|
* @memberOf et2_nextmatch_rowTemplateWidget
|
||||||
@ -632,6 +653,9 @@ var et2_nextmatch_rowTemplateWidget = et2_widget.extend(et2_IDOMNode,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the column node for the given sender
|
* Returns the column node for the given sender
|
||||||
|
*
|
||||||
|
* @param {et2_widget} _sender
|
||||||
|
* @return {DOMElement}
|
||||||
*/
|
*/
|
||||||
getDOMNode: function(_sender) {
|
getDOMNode: function(_sender) {
|
||||||
|
|
||||||
|
@ -88,7 +88,10 @@ function etemplate2(_container, _menuaction)
|
|||||||
// Unique ID to prevent DOM collisions across multiple templates
|
// Unique ID to prevent DOM collisions across multiple templates
|
||||||
this.uniqueId = _container.getAttribute("id") ? _container.getAttribute("id").replace('.','-') : '';
|
this.uniqueId = _container.getAttribute("id") ? _container.getAttribute("id").replace('.','-') : '';
|
||||||
|
|
||||||
// Preset the object variable
|
/**
|
||||||
|
* Preset the object variable
|
||||||
|
* @type {et2_container}
|
||||||
|
*/
|
||||||
this.widgetContainer = null;
|
this.widgetContainer = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<script src="../../../phpgwapi/js/jsapi/egw_css.js"></script>
|
<script src="../../../phpgwapi/js/jsapi/egw_css.js"></script>
|
||||||
<script src="../../../phpgwapi/js/jsapi/egw_debug.js"></script>
|
<script src="../../../phpgwapi/js/jsapi/egw_debug.js"></script>
|
||||||
|
|
||||||
|
<script src="../../../phpgwapi/js/jsapi/egw_inheritance.js"></script>
|
||||||
<script src="../et2_core_inheritance.js"></script>
|
<script src="../et2_core_inheritance.js"></script>
|
||||||
<script src="../et2_core_interfaces.js"></script>
|
<script src="../et2_core_interfaces.js"></script>
|
||||||
<script src="../et2_core_common.js"></script>
|
<script src="../et2_core_common.js"></script>
|
||||||
@ -98,7 +99,7 @@
|
|||||||
data[i] = "uid_" + i;
|
data[i] = "uid_" + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dataprovider = Class.extend(et2_IDataProvider, {
|
var dataprovider = ClassWithAttributes.extend(et2_IDataProvider, {
|
||||||
|
|
||||||
dataFetch: function (_queriedRange, _callback, _context) {
|
dataFetch: function (_queriedRange, _callback, _context) {
|
||||||
var response = {
|
var response = {
|
||||||
|
@ -58,6 +58,9 @@ window.app = {classes: {}};
|
|||||||
* // Underscore private by convention
|
* // Underscore private by convention
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
|
*
|
||||||
|
* @class AppJS
|
||||||
|
* @augments Class
|
||||||
*/
|
*/
|
||||||
var AppJS = Class.extend(
|
var AppJS = Class.extend(
|
||||||
{
|
{
|
||||||
@ -68,11 +71,15 @@ var AppJS = Class.extend(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal reference to etemplate2 widget tree
|
* Internal reference to etemplate2 widget tree
|
||||||
|
*
|
||||||
|
* @var {et2_container}
|
||||||
*/
|
*/
|
||||||
et2: null,
|
et2: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal reference to egw client-side api object for current app and window
|
* Internal reference to egw client-side api object for current app and window
|
||||||
|
*
|
||||||
|
* @var {egw}
|
||||||
*/
|
*/
|
||||||
egw: null,
|
egw: null,
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* This code setups the egw namespace and adds the "extend" function, which is
|
* 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.
|
* used by extension modules to inject their content into the egw object.
|
||||||
*/
|
*/
|
||||||
(function(_parent) {
|
(function() {
|
||||||
|
|
||||||
var instanceUid = 0;
|
var instanceUid = 0;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@
|
|||||||
{
|
{
|
||||||
if (_cond(_arr[i]))
|
if (_cond(_arr[i]))
|
||||||
{
|
{
|
||||||
_arr.splice(i, 1)
|
_arr.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,19 +173,20 @@
|
|||||||
/**
|
/**
|
||||||
* Creates an api instance for the given application and the given window.
|
* Creates an api instance for the given application and the given window.
|
||||||
*
|
*
|
||||||
* @param _egw is the global _egw instance which should be used.
|
* @param {globalEgw} _egw is the global _egw instance which should be used.
|
||||||
* @param _modules is the hash map which contains references to all module
|
* @param {object} _modules is the hash map which contains references to all module
|
||||||
* descriptors.
|
* descriptors.
|
||||||
* @param _moduleInstances is the the object which contains the application
|
* @param {object} _moduleInstances is the the object which contains the application
|
||||||
* and window specific module instances.
|
* and window specific module instances.
|
||||||
* @param _list is the overall instances list, to which the module should be
|
* @param {array} _list is the overall instances list, to which the module should be
|
||||||
* added.
|
* added.
|
||||||
* @param _instances refers to all api instances.
|
* @param {object} _instances is the overall instances list, to which the module should be
|
||||||
* @param _app is the application for which the instance should be created.
|
* added.
|
||||||
* @param _wnd is the window for which the instance should be created.
|
* @param {string} _app is the application for which the instance should be created.
|
||||||
|
* @param {DOMElement} _window is the window for which the instance should be created.
|
||||||
|
* @return {egw}
|
||||||
*/
|
*/
|
||||||
function createEgwInstance(_egw, _modules, _moduleInstances, _list,
|
function createEgwInstance(_egw, _modules, _moduleInstances, _list, _instances, _app, _window)
|
||||||
_instances, _app, _window)
|
|
||||||
{
|
{
|
||||||
// Clone the global object
|
// Clone the global object
|
||||||
var instance = cloneObject(_egw);
|
var instance = cloneObject(_egw);
|
||||||
@ -237,18 +238,18 @@
|
|||||||
* Returns a egw instance for the given application and the given window. If
|
* Returns a egw instance for the given application and the given window. If
|
||||||
* the instance does not exist now, the instance will be created.
|
* the instance does not exist now, the instance will be created.
|
||||||
*
|
*
|
||||||
* @param _egw is the global _egw instance which should be used.
|
* @param {globalEgw} _egw is the global _egw instance which should be used.
|
||||||
* @param _modules is the hash map which contains references to all module
|
* @param {object} _modules is the hash map which contains references to all module
|
||||||
* descriptors.
|
* descriptors.
|
||||||
* @param _moduleInstances is the the object which contains the application
|
* @param {object} _moduleInstances is the the object which contains the application
|
||||||
* and window specific module instances.
|
* and window specific module instances.
|
||||||
* @param _list is the overall instances list, to which the module should be
|
* @param {object} _instances is the overall instances list, to which the module should be
|
||||||
* added.
|
* added.
|
||||||
* @param _app is the application for which the instance should be created.
|
* @param {string} _app is the application for which the instance should be created.
|
||||||
* @param _wnd is the window for which the instance should be created.
|
* @param {DOMElement} _window is the window for which the instance should be created.
|
||||||
|
* @return {egw}
|
||||||
*/
|
*/
|
||||||
function getEgwInstance(_egw, _modules, _moduleInstances, _instances, _app,
|
function getEgwInstance(_egw, _modules, _moduleInstances, _instances, _app, _window)
|
||||||
_window)
|
|
||||||
{
|
{
|
||||||
// Generate the hash key for the instance descriptor object
|
// Generate the hash key for the instance descriptor object
|
||||||
var hash = _app ? _app : '~global~';
|
var hash = _app ? _app : '~global~';
|
||||||
@ -435,6 +436,8 @@
|
|||||||
* function and/or a window object. If you specify both, the app name
|
* 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
|
* has to preceed the window object reference. If no window object is
|
||||||
* given, the root window will be used.
|
* given, the root window will be used.
|
||||||
|
*
|
||||||
|
* @return {egw}
|
||||||
*/
|
*/
|
||||||
var egw = function() {
|
var egw = function() {
|
||||||
|
|
||||||
@ -471,7 +474,7 @@
|
|||||||
// Generate an API instance
|
// Generate an API instance
|
||||||
return getEgwInstance(egw, modules, moduleInstances, instances,
|
return getEgwInstance(egw, modules, moduleInstances, instances,
|
||||||
_app, _window);
|
_app, _window);
|
||||||
}
|
};
|
||||||
|
|
||||||
var globalEgw = {
|
var globalEgw = {
|
||||||
|
|
||||||
@ -686,9 +689,8 @@
|
|||||||
return {
|
return {
|
||||||
'instances': instances,
|
'instances': instances,
|
||||||
'moduleInstances': moduleInstances
|
'moduleInstances': moduleInstances
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Merge the globalEgw functions into the egw object.
|
// Merge the globalEgw functions into the egw object.
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
* ----------------------------------
|
* ----------------------------------
|
||||||
*
|
*
|
||||||
* To create a class write
|
* To create a class write
|
||||||
*
|
*
|
||||||
* MyClass = Class.extend([interfaces, ] functions);
|
* MyClass = Class.extend([interfaces, ] functions);
|
||||||
*
|
*
|
||||||
* where "interfaces" is a single interface or an array of interfaces and
|
* where "interfaces" is a single interface or an array of interfaces and
|
||||||
@ -28,7 +28,7 @@
|
|||||||
* var IBreathingObject = new Interface({
|
* var IBreathingObject = new Interface({
|
||||||
* breath: function() {}
|
* breath: function() {}
|
||||||
* });
|
* });
|
||||||
*
|
*
|
||||||
* var Human = Class.extend(IBreathingObject, {
|
* var Human = Class.extend(IBreathingObject, {
|
||||||
* walk: function() {
|
* walk: function() {
|
||||||
* console.log("Walking");
|
* console.log("Walking");
|
||||||
@ -37,13 +37,13 @@
|
|||||||
* console.log(_words);
|
* console.log(_words);
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
*
|
*
|
||||||
* As "Human" does not implement the function "breath", "Human" is treated as
|
* As "Human" does not implement the function "breath", "Human" is treated as
|
||||||
* abstract. Trying to create an instance of "Human" will throw an exception.
|
* abstract. Trying to create an instance of "Human" will throw an exception.
|
||||||
* However
|
* However
|
||||||
*
|
*
|
||||||
* Human.prototype.implements(IBreathingObject);
|
* Human.prototype.implements(IBreathingObject);
|
||||||
*
|
*
|
||||||
* will return true. Lets create a specific class of "Human":
|
* will return true. Lets create a specific class of "Human":
|
||||||
*
|
*
|
||||||
* var ChuckNorris = Human.extend({
|
* var ChuckNorris = Human.extend({
|
||||||
@ -57,17 +57,20 @@
|
|||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// The following code is mostly taken from
|
// The following code is mostly taken from
|
||||||
// http://ejohn.org/blog/simple-javascript-inheritance/
|
// http://ejohn.org/blog/simple-javascript-inheritance/
|
||||||
// some parts were slightly changed for better understanding. Added possiblity
|
// some parts were slightly changed for better understanding. Added possiblity
|
||||||
// to use interfaces.
|
// to use interfaces.
|
||||||
|
|
||||||
/* Simple JavaScript Inheritance
|
/**
|
||||||
|
* Simple JavaScript Inheritance
|
||||||
* By John Resig http://ejohn.org/
|
* By John Resig http://ejohn.org/
|
||||||
* MIT Licensed
|
* MIT Licensed
|
||||||
|
*
|
||||||
|
* Inspired by base2 and Prototype
|
||||||
*/
|
*/
|
||||||
// Inspired by base2 and Prototype
|
(function()
|
||||||
(function(){
|
{
|
||||||
var initializing = false;
|
var initializing = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,11 +81,16 @@
|
|||||||
var tracedObjects = {};
|
var tracedObjects = {};
|
||||||
|
|
||||||
// Check whether "function decompilation" works - fnTest is normally used to
|
// Check whether "function decompilation" works - fnTest is normally used to
|
||||||
// check whether a
|
// check whether a
|
||||||
var fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
var fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
||||||
|
|
||||||
// Base "Class" for interfaces - needed to check whether an object is an
|
/**
|
||||||
// interface
|
* Base "Class" for interfaces - needed to check whether an object is an
|
||||||
|
* interface
|
||||||
|
*
|
||||||
|
* @param {object} fncts
|
||||||
|
* @class {Interface}
|
||||||
|
*/
|
||||||
this.Interface = function(fncts) {
|
this.Interface = function(fncts) {
|
||||||
for (var key in fncts)
|
for (var key in fncts)
|
||||||
{
|
{
|
||||||
@ -93,6 +101,9 @@
|
|||||||
/**
|
/**
|
||||||
* The addInterfaceFunctions function adds all interface functions the class has
|
* The addInterfaceFunctions function adds all interface functions the class has
|
||||||
* to implement to the class prototype.
|
* to implement to the class prototype.
|
||||||
|
*
|
||||||
|
* @param {Class} prototype
|
||||||
|
* @param {array} interfaces
|
||||||
*/
|
*/
|
||||||
function addInterfaceFunctions(prototype, interfaces)
|
function addInterfaceFunctions(prototype, interfaces)
|
||||||
{
|
{
|
||||||
@ -159,24 +170,32 @@
|
|||||||
attributes[key] = _copyMerge({}, prototype.attributes[key]);
|
attributes[key] = _copyMerge({}, prototype.attributes[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prototype._validate_attributes)
|
|
||||||
{
|
|
||||||
prototype._validate_attributes(prototype, attributes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the old attributes to the new ones. If the attributes already
|
// Add the old attributes to the new ones. If the attributes already
|
||||||
// exist, they are merged.
|
// exist, they are merged.
|
||||||
for (var key in _super.attributes)
|
for (var key in _super.attributes)
|
||||||
{
|
{
|
||||||
var _old = _super.attributes[key];
|
var _old = _super.attributes[key];
|
||||||
var _new = {};
|
|
||||||
|
|
||||||
attributes[key] = _copyMerge(attributes[key], _old);
|
attributes[key] = _copyMerge(attributes[key], _old);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(prototype._validate_attributes)
|
||||||
|
{
|
||||||
|
prototype._validate_attributes(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
prototype.attributes = attributes;
|
prototype.attributes = attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Class that inherits from this class. The first parameter
|
||||||
|
* is an array which defines a set of interfaces the object has to
|
||||||
|
* implement. An interface is simply an object with named functions.
|
||||||
|
*
|
||||||
|
* @param {array} interfaces
|
||||||
|
* @param {object} prop
|
||||||
|
* @return {Class}
|
||||||
|
*/
|
||||||
function classExtend(interfaces, prop) {
|
function classExtend(interfaces, prop) {
|
||||||
|
|
||||||
if (typeof prop == "undefined")
|
if (typeof prop == "undefined")
|
||||||
@ -243,7 +262,11 @@
|
|||||||
// attributes
|
// attributes
|
||||||
addAttributeFunctions(prototype, _super);
|
addAttributeFunctions(prototype, _super);
|
||||||
|
|
||||||
// The dummy class constructor
|
/**
|
||||||
|
* The dummy class constructor
|
||||||
|
*
|
||||||
|
* @constructor {Class}
|
||||||
|
*/
|
||||||
function Class() {
|
function Class() {
|
||||||
// All construction is actually done in the init method
|
// All construction is actually done in the init method
|
||||||
if (!initializing)
|
if (!initializing)
|
||||||
@ -254,7 +277,7 @@
|
|||||||
var func = this._ifacefuncs[i];
|
var func = this._ifacefuncs[i];
|
||||||
if (!(typeof this[func] == "function"))
|
if (!(typeof this[func] == "function"))
|
||||||
{
|
{
|
||||||
throw("Trying to create abstract object, interface " +
|
throw("Trying to create abstract object, interface " +
|
||||||
"function '" + func + "' not implemented.");
|
"function '" + func + "' not implemented.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,7 +290,7 @@
|
|||||||
tracedObjects[this.__OBJ_UID] = {
|
tracedObjects[this.__OBJ_UID] = {
|
||||||
"created": new Date().getTime(),
|
"created": new Date().getTime(),
|
||||||
"class": className
|
"class": className
|
||||||
}
|
};
|
||||||
egw.debug("log", "*" + this.__OBJ_UID + " (" + className + ")");
|
egw.debug("log", "*" + this.__OBJ_UID + " (" + className + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +307,15 @@
|
|||||||
// Enforce the constructor to be what we expect
|
// Enforce the constructor to be what we expect
|
||||||
Class.prototype.constructor = Class;
|
Class.prototype.constructor = Class;
|
||||||
|
|
||||||
// And make this class extendable
|
/**
|
||||||
|
* Create a new Class that inherits from this class. The first parameter
|
||||||
|
* is an array which defines a set of interfaces the object has to
|
||||||
|
* implement. An interface is simply an object with named functions.
|
||||||
|
*
|
||||||
|
* @param {array} interfaces
|
||||||
|
* @param {object} prop
|
||||||
|
* @return {Class}
|
||||||
|
*/
|
||||||
Class.extend = classExtend;
|
Class.extend = classExtend;
|
||||||
|
|
||||||
return Class;
|
return Class;
|
||||||
@ -293,9 +324,15 @@
|
|||||||
// The base Class implementation (does nothing)
|
// The base Class implementation (does nothing)
|
||||||
this.Class = function(){};
|
this.Class = function(){};
|
||||||
|
|
||||||
// Create a new Class that inherits from this class. The first parameter
|
/**
|
||||||
// is an array which defines a set of interfaces the object has to
|
* Create a new Class that inherits from this class. The first parameter
|
||||||
// implement. An interface is simply an object with named functions.
|
* is an array which defines a set of interfaces the object has to
|
||||||
|
* implement. An interface is simply an object with named functions.
|
||||||
|
*
|
||||||
|
* @param {array} interfaces
|
||||||
|
* @param {object} prop
|
||||||
|
* @return {Class}
|
||||||
|
*/
|
||||||
Class.extend = classExtend;
|
Class.extend = classExtend;
|
||||||
|
|
||||||
// The base class has no attributes
|
// The base class has no attributes
|
||||||
@ -356,12 +393,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return "?";
|
return "?";
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The implements function can be used to check whether the object
|
* The implements function can be used to check whether the object
|
||||||
* implements the given interface.
|
* implements the given interface.
|
||||||
|
*
|
||||||
|
* @param {Class} _iface interface to check
|
||||||
*/
|
*/
|
||||||
Class.prototype.implements = function(_iface) {
|
Class.prototype.implements = function(_iface) {
|
||||||
for (var key in _iface)
|
for (var key in _iface)
|
||||||
@ -378,6 +417,8 @@
|
|||||||
* The instanceOf function can be used to check for both - classes and
|
* The instanceOf function can be used to check for both - classes and
|
||||||
* interfaces. Please don't change the case of this function as this
|
* interfaces. Please don't change the case of this function as this
|
||||||
* affects IE and Opera support.
|
* affects IE and Opera support.
|
||||||
|
*
|
||||||
|
* @param {Class} _obj object to check
|
||||||
*/
|
*/
|
||||||
Class.prototype.instanceOf = function(_obj) {
|
Class.prototype.instanceOf = function(_obj) {
|
||||||
if (_obj instanceof Interface)
|
if (_obj instanceof Interface)
|
||||||
|
@ -35,8 +35,8 @@ egw.extend('lang', egw.MODULE_GLOBAL, function() {
|
|||||||
/**
|
/**
|
||||||
* Set translation for a given application
|
* Set translation for a given application
|
||||||
*
|
*
|
||||||
* @param string _app
|
* @param {string} _app
|
||||||
* @param object _message message => translation pairs
|
* @param {object} _messages message => translation pairs
|
||||||
* @memberOf egw
|
* @memberOf egw
|
||||||
*/
|
*/
|
||||||
set_lang_arr: function(_app, _messages)
|
set_lang_arr: function(_app, _messages)
|
||||||
@ -50,8 +50,9 @@ egw.extend('lang', egw.MODULE_GLOBAL, function() {
|
|||||||
/**
|
/**
|
||||||
* Translate a given phrase replacing optional placeholders
|
* Translate a given phrase replacing optional placeholders
|
||||||
*
|
*
|
||||||
* @param string _msg message to translate
|
* @param {string} _msg message to translate
|
||||||
* @param string _arg1 ... _argN
|
* @param {...string} _arg1 ... _argN
|
||||||
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
lang: function(_msg, _arg1)
|
lang: function(_msg, _arg1)
|
||||||
{
|
{
|
||||||
@ -91,10 +92,10 @@ egw.extend('lang', egw.MODULE_GLOBAL, function() {
|
|||||||
/**
|
/**
|
||||||
* Load default langfiles for an application: common, _appname, custom
|
* Load default langfiles for an application: common, _appname, custom
|
||||||
*
|
*
|
||||||
* @param _window
|
* @param {DOMElement} _window
|
||||||
* @param {string} _appname name of application to load translations for
|
* @param {string} _appname name of application to load translations for
|
||||||
* @param {function} _callback
|
* @param {function} _callback
|
||||||
* @param _context
|
* @param {object} _context
|
||||||
*/
|
*/
|
||||||
langRequireApp: function(_window, _appname, _callback, _context)
|
langRequireApp: function(_window, _appname, _callback, _context)
|
||||||
{
|
{
|
||||||
@ -114,17 +115,17 @@ egw.extend('lang', egw.MODULE_GLOBAL, function() {
|
|||||||
* Includes the language files for the given applications -- if those
|
* Includes the language files for the given applications -- if those
|
||||||
* do not already exist, include them.
|
* do not already exist, include them.
|
||||||
*
|
*
|
||||||
* @param _window is the window which needs the language -- this is
|
* @param {DOMElement} _window is the window which needs the language -- this is
|
||||||
* needed as the "ready" event has to be postponed in that window until
|
* needed as the "ready" event has to be postponed in that window until
|
||||||
* all lang files are included.
|
* all lang files are included.
|
||||||
* @param _apps is an array containing the applications for which the
|
* @param {array} _apps is an array containing the applications for which the
|
||||||
* data is needed as objects of the following form:
|
* data is needed as objects of the following form:
|
||||||
* {
|
* {
|
||||||
* app: <APPLICATION NAME>,
|
* app: <APPLICATION NAME>,
|
||||||
* lang: <LANGUAGE CODE>
|
* lang: <LANGUAGE CODE>
|
||||||
* }
|
* }
|
||||||
* @param function _callback called after loading, if not given ready event will be postponed instead
|
* @param {function} _callback called after loading, if not given ready event will be postponed instead
|
||||||
* @param object _context for callback
|
* @param {object} _context for callback
|
||||||
*/
|
*/
|
||||||
langRequire: function(_window, _apps, _callback, _context) {
|
langRequire: function(_window, _apps, _callback, _context) {
|
||||||
// Get the ready and the files module for the given window
|
// Get the ready and the files module for the given window
|
||||||
|
@ -339,16 +339,17 @@ egw.extend('links', egw.MODULE_GLOBAL, function() {
|
|||||||
/**
|
/**
|
||||||
* Query a title of _app/_id
|
* Query a title of _app/_id
|
||||||
*
|
*
|
||||||
* @param string _app
|
* @param {string} _app
|
||||||
* @param string|int _id
|
* @param {(string|int)} _id
|
||||||
* @param function _callback optinal callback, required if for responses from the server
|
* @param {function} _callback optinal callback, required if for responses from the server
|
||||||
* @param object _context context for the callback
|
* @param {object} _context context for the callback
|
||||||
|
* @param {boolean} _force_reload true load again from server, even if already cached
|
||||||
* @return string|boolean|null string with title if it exist in local cache or null if not
|
* @return string|boolean|null string with title if it exist in local cache or null if not
|
||||||
*/
|
*/
|
||||||
link_title: function(_app, _id, _callback, _context)
|
link_title: function(_app, _id, _callback, _context, _force_reload)
|
||||||
{
|
{
|
||||||
// check if we have a cached title --> return it direct
|
// check if we have a cached title --> return it direct
|
||||||
if (typeof title_cache[_app] != 'undefined' && typeof title_cache[_app][_id] != 'undefined')
|
if (typeof title_cache[_app] != 'undefined' && typeof title_cache[_app][_id] != 'undefined' && _force_reload !== true)
|
||||||
{
|
{
|
||||||
if (typeof _callback == 'function')
|
if (typeof _callback == 'function')
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user