Initial commit of the current JS implementation of the egw_action system, which will later be used to create context sensitive menus and drag and drop capabilities. The egw_menu.js/egw_menu_dhtml.js files are fully functional (see test in the test dir), implementation of egw_action.js has just started and not even a single line of that has been tested yet.
474
phpgwapi/js/egw_action/egw_action.js
Normal file
@ -0,0 +1,474 @@
|
||||
/**
|
||||
* eGroupWare egw_action framework - egw action framework
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stöckel <as@stylite.de>
|
||||
* @copyright 2011 by Andreas Stöckel
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package egw_action
|
||||
* @version $Id:$
|
||||
*/
|
||||
|
||||
// XXX WARNING: UNTESTED, UNFINISHED, NOT (YET) WORKING CODE! XXX
|
||||
|
||||
/** egwActionHandler Interface **/
|
||||
|
||||
/**
|
||||
* Constructor for the egwActionHandler interface which (at least) should have the
|
||||
* execute function implemented.
|
||||
*/
|
||||
function egwActionHandler(_executeEvent)
|
||||
{
|
||||
//Copy the executeEvent parameter
|
||||
this.execute = _executeEvent;
|
||||
}
|
||||
|
||||
|
||||
/** egwAction Object **/
|
||||
|
||||
/**
|
||||
* Associative array where action classes may register themselves
|
||||
*/
|
||||
var _egwActionClasses =
|
||||
{
|
||||
"default":
|
||||
{
|
||||
"actionConstructor": egwAction,
|
||||
"implementationConstructor": null
|
||||
}
|
||||
}
|
||||
|
||||
function egwAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMultiple)
|
||||
{
|
||||
//Default and check the values
|
||||
if (typeof _id != "string" || !_id)
|
||||
throw "egwAction _id must be a non-empty string!";
|
||||
if (typeof _handler == "undefined")
|
||||
this.handler = null;
|
||||
if (typeof _label == "undefined")
|
||||
_label = "";
|
||||
if (typeof _icon == "undefined")
|
||||
_icon = "";
|
||||
if (typeof _onExecute == "undefined")
|
||||
_onExecute = null;
|
||||
if (typeof _allowOnMultiple == "undefined")
|
||||
_allowOnMultiple = true;
|
||||
|
||||
this.id = _id;
|
||||
this.caption = _caption;
|
||||
this.icon = _icon;
|
||||
this.allowOnMultiple = _allowOnMultiple;
|
||||
this.type = "default"; //All derived classes have to override this!
|
||||
|
||||
this.execJSFnct = null;
|
||||
this.execHandler = false;
|
||||
this.set_onExecute(_onExecute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes this action by using the method specified in the onExecute setter.
|
||||
*
|
||||
* @param array_senders array with references to the objects which caused the action
|
||||
* //TODO: With DragDrop we don't only have senders but also one(!) target.
|
||||
*/
|
||||
egwAction.prototype.execute = function(_senders)
|
||||
{
|
||||
if (this.execJSFnct && typeof this.execJSFnct == "function")
|
||||
{
|
||||
this.execJSFnct(this, _senders);
|
||||
}
|
||||
else if (this.execHandler)
|
||||
{
|
||||
this.handler.execute(this, _senders);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The set_onExecute function is the setter function for the onExecute event of
|
||||
* the egwAction object. There are three possible types the passed "_value" may
|
||||
* take:
|
||||
* 1. _value may be a string with the word "javaScript:" prefixed. The function
|
||||
* which is specified behind the colon and which has to be in the global scope
|
||||
* will be executed.
|
||||
* 2. _value may be a boolean, which specifies whether the external onExecute handler
|
||||
* (passed as "_handler" in the constructor) will be used.
|
||||
* 3. _value may be a JS functino which will then be called.
|
||||
* In all possible situation, the called function will get the following parameters:
|
||||
* 1. A reference to this action
|
||||
* 2. The senders, an array of all objects (JS)/object ids (PHP) which evoked the event
|
||||
*/
|
||||
egwAction.prototype.set_onExecute(_value)
|
||||
{
|
||||
//Reset the onExecute handlers
|
||||
this.execJSFnct = null;
|
||||
this.execHandler = false;
|
||||
|
||||
if (typeof _value == "string")
|
||||
{
|
||||
// Check whether the given string contains a javaScript function which
|
||||
// should be called upon executing the action
|
||||
if (_value.substr(0, 11) == "javaScript:")
|
||||
{
|
||||
//Check whether the given function exists
|
||||
var fnct = _value.substr(11);
|
||||
if (typeof window[fnct] == "function")
|
||||
{
|
||||
this.execJSFnct = window[fnct];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof _value == "boolean")
|
||||
{
|
||||
// There is no direct reference to the PHP code which should be executed,
|
||||
// as the PHP code has knowledge about this.
|
||||
this.execHandler = _value;
|
||||
}
|
||||
else if (typeof _value == "function")
|
||||
{
|
||||
//The JS function has been passed directly
|
||||
this.execJSFnct = _value;
|
||||
}
|
||||
}
|
||||
|
||||
egwAction.prototype.set_caption(_value)
|
||||
{
|
||||
this.caption = _value;
|
||||
}
|
||||
|
||||
egwAction.prototype.set_icon(_value)
|
||||
{
|
||||
this.icon = _value;
|
||||
}
|
||||
|
||||
egwAction.prototype.set_allowOnMultiple(_value)
|
||||
{
|
||||
this.allowOnMultiple = _value;
|
||||
}
|
||||
|
||||
|
||||
/** egwActionManager Object **/
|
||||
|
||||
/**
|
||||
* egwActionManager manages a list of actions, provides functions to add new
|
||||
* actions or to update them via JSON.
|
||||
*/
|
||||
function egwActionManager(_handler)
|
||||
{
|
||||
//Preset the handler parameter to null
|
||||
if (typeof _handler == "undefined")
|
||||
_handler = null;
|
||||
|
||||
this.handler = _handler;
|
||||
this.actions = [];
|
||||
}
|
||||
|
||||
egwActionManager.prototype.addAction = function(_type, _id, _caption, _icon,
|
||||
_onExecute, _allowOnMultiple)
|
||||
{
|
||||
//Get the constructor for the given action type
|
||||
if (!_type)
|
||||
_type = "default";
|
||||
var constructor = _egwActionClasses[_type].actionConstructor;
|
||||
|
||||
if (typeof constructor == "function")
|
||||
{
|
||||
var action = new constructor(_id, this.handler, _caption, _icon, _onExecute,
|
||||
_allowOnMultiple);
|
||||
this.actions.push[action];
|
||||
|
||||
return action;
|
||||
}
|
||||
else
|
||||
throw "Given action type not registered.";
|
||||
}
|
||||
|
||||
egwActionManager.prototype.updateActions = function(_actions)
|
||||
{
|
||||
for (var i = 0 ; i < _actions.length; i++)
|
||||
{
|
||||
//Check whether the given action is already part of this action manager instance
|
||||
var elem = _actions[i];
|
||||
if (typeof elem == "object" && typeof elem.id == "string" && elem.id)
|
||||
{
|
||||
//Check whether the action already exists, and if no, add it to the
|
||||
//actions list
|
||||
var action = this.getAction(elem.id);
|
||||
if (!action)
|
||||
{
|
||||
if (typeof elem.type == "undefined")
|
||||
elem.type = "default";
|
||||
|
||||
var constructor = _egwActionClasses[elem.type].actionConstructor;
|
||||
|
||||
if (typeof constructor == "function")
|
||||
action = new constructor(elem.id, this.handler);
|
||||
else
|
||||
throw "Given action type not registered.";
|
||||
|
||||
this.actions.push(action);
|
||||
}
|
||||
|
||||
//Update the actions by calling the corresponding setter functions
|
||||
//TODO: Hirachical actions will need a reference to their parent -
|
||||
// this parent is has to be translated to a js object
|
||||
//TODO: Maby the setter, JSON, update stuff should somehow be moved
|
||||
// to a own base class.
|
||||
egwActionStoreJSON(elem, action, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
egwActionManager.prototype.getAction = function(_id)
|
||||
{
|
||||
for (var i = 0; i < this.actions.length; i++)
|
||||
{
|
||||
if (this.actions[i].id == _id)
|
||||
return this.actions[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/** egwActionImplementation Interface **/
|
||||
|
||||
/**
|
||||
* Abstract interface for the egwActionImplementation object. The egwActionImplementation
|
||||
* object is responsible for inserting the actual action representation (context menu,
|
||||
* drag-drop code) into the DOM Tree by using the egwActionObjectInterface object
|
||||
* supplied by the object.
|
||||
* To write a "class" which derives from this object, simply write a own constructor,
|
||||
* which replaces "this" with a "new egwActionImplementation" and implement your
|
||||
* code in "doRegisterAction" und "doUnregisterAction".
|
||||
* Register your own implementation within the _egwActionClasses object.
|
||||
*
|
||||
* @param object _action is the parent egwAction object for that instance.
|
||||
*/
|
||||
function egwActionImplementation(_action)
|
||||
{
|
||||
this.action = _action;
|
||||
|
||||
this.doRegisterAction = null;
|
||||
this.doUnregisterAction = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the implementation code into the DOM tree by using the supplied
|
||||
* actionObjectInterface.
|
||||
*
|
||||
* @returns true if the Action had been successfully registered, false if it
|
||||
* had not.
|
||||
*/
|
||||
egwActionImplementation.registerAction = function(_actionObjectInterface)
|
||||
{
|
||||
if (this.doRegisterAction == null)
|
||||
{
|
||||
throw "Abstract function call: registerAction";
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.doRegisterAction(_action, _actionObjectInterface);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister action will be called before an actionObjectInterface is destroyed,
|
||||
* which gives the egwActionImplementation the opportunity to remove the previously
|
||||
* injected code.
|
||||
*
|
||||
* @returns true if the Action had been successfully unregistered, false if it
|
||||
* had not.
|
||||
*/
|
||||
egwActionImplementation.unregisterAction = function(_actionObjectInterface)
|
||||
{
|
||||
if (this.doUnregisterAction == null)
|
||||
{
|
||||
throw "Abstract function call: unregisterAction";
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.doUnregisterAction(_action, _actionObjectInterface);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** egwActionLink Object **/
|
||||
|
||||
/**
|
||||
* The egwActionLink is used to interconnect egwActionObjects and egwActions.
|
||||
* This gives each action object the possibility to decide, whether the action
|
||||
* should be active in this context or not.
|
||||
*
|
||||
* @param _manager is a reference to the egwActionManager whic contains the action
|
||||
* the object wants to link to.
|
||||
*/
|
||||
function egwActionLink(_manager)
|
||||
{
|
||||
this.enabled = true;
|
||||
this.actionId = "";
|
||||
this.actionObj = null;
|
||||
this.manager = _manager;
|
||||
}
|
||||
|
||||
egwActionLink.prototype.updateLink = function (_data)
|
||||
{
|
||||
egwActionStoreJSON(_data, this, true);
|
||||
}
|
||||
|
||||
egwActionLink.prototype.set_enabled = function(_value)
|
||||
{
|
||||
this.enabled = _value;
|
||||
}
|
||||
|
||||
egwActionLink.prototype.set_actionId = function(_value)
|
||||
{
|
||||
this.actionId = _value;
|
||||
this.actionObj = this.manager.getAction(_value);
|
||||
|
||||
if (!this.actionObj)
|
||||
throw "Given action object does not exist!"
|
||||
}
|
||||
|
||||
|
||||
/** egwActionObject Object **/
|
||||
|
||||
/**
|
||||
* The egwActionObject represents an abstract object to which actions may be
|
||||
* applied. Communication with the DOM tree is established by using the
|
||||
* egwActionObjectInterface (AOI), which is passed in the constructor.
|
||||
* egwActionObjects are organized in a tree structure.
|
||||
*
|
||||
* @param string _id is the identifier of the object which
|
||||
* @param object _parent is the parent object in the hirachy. This may be set to NULL
|
||||
* @param object _manager is the action manager this object is connected to
|
||||
* @param object _interaction is the egwActionObjectInterface which connects
|
||||
* this object to the DOM tree.
|
||||
*/
|
||||
function egwActionObject(_id, _parent, _manager, _interaction)
|
||||
{
|
||||
this.id = _id;
|
||||
this.parent = _parent;
|
||||
this.interaction = _interaction;
|
||||
this.children = [];
|
||||
this.actionLinks = [];
|
||||
this.manager = _manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the actionLinks of the given ActionObject.
|
||||
*
|
||||
* @param array _actionLinks contains the information about the actionLinks which
|
||||
* should be updated as an array of objects. Example
|
||||
* [
|
||||
* {
|
||||
* "actionId": "file_delete",
|
||||
* "enabled": true
|
||||
* }
|
||||
* ]
|
||||
* If an supplied link doesn't exist yet, it will be created (if _doCreate is true)
|
||||
* and added to the list. Otherwise the information will just be updated.
|
||||
* @param boolean _recursive If true, the settings will be applied to all child
|
||||
* object (default false)
|
||||
* @param boolean _doCreate If true, not yet existing links will be created (default true)
|
||||
*/
|
||||
egwActionObject.prototype.updateActionLinks = function(_actionLinks, _recursive, _doCreate)
|
||||
{
|
||||
if (typeof _recursive == "undefined")
|
||||
_recursive = false;
|
||||
if (typeof _doCreate == "undefined")
|
||||
_doCreate = true;
|
||||
|
||||
for (var i = 0; i < _actionLinks.length; i++)
|
||||
{
|
||||
var elem = _actionLinks[i];
|
||||
if (typeof elem.actionId != "undefined" && elem.actionId)
|
||||
{
|
||||
//Get the action link object, if it doesn't exists yet, create it
|
||||
var actionLink = this.getActionLink(elem.actionId);
|
||||
if (!actionLink && _doCreate)
|
||||
{
|
||||
actionLink = new egwActionLink(this.manager);
|
||||
}
|
||||
|
||||
//Set the supplied data
|
||||
if (actionLink)
|
||||
{
|
||||
actionLink.updateLink(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_recursive)
|
||||
{
|
||||
for (var i = 0; i < this.children.length; i++)
|
||||
{
|
||||
this.children[i].updateActionLinks(_actionLinks, true, _doCreate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the action link, which contains the association to the action with
|
||||
* the given actionId.
|
||||
*
|
||||
* @param string _actionId name of the action associated to the link
|
||||
*/
|
||||
egwActionObject.prototype.getActionLink = function(_actionId)
|
||||
{
|
||||
for (var i = 0; i < this.actionLinks.length; i++)
|
||||
{
|
||||
if (this.actionLinks[i].actionObj.id == _actionId)
|
||||
{
|
||||
return this.actionLinks[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all actions associated to the object tree, grouped by type.
|
||||
*
|
||||
* @param function _test gets an egwActionObject and should return, whether the
|
||||
* actions of this object are added to the result. Defaults to a "always true"
|
||||
* function.
|
||||
* @param object _groups is an internally used parameter, may be omitted.
|
||||
*/
|
||||
egwActionObject.prototype.getActionImplementationGroups = function(_test, _groups)
|
||||
{
|
||||
// If the _groups parameter hasn't been given preset it to an empty object
|
||||
// (associative array).
|
||||
if (typeof _groups == "undefined")
|
||||
_groups = {};
|
||||
if (typeof _test == "undefined")
|
||||
_test = function(_obj) {return true};
|
||||
|
||||
for (var i = 0; i < this.actionLinks.length; i++)
|
||||
{
|
||||
var action = this.actionsLink[i].actionObj;
|
||||
if (typeof action != "undefined" && _test(this))
|
||||
{
|
||||
if (typeof _groups[action.type] == "undefined")
|
||||
{
|
||||
_groups[action.type] = [];
|
||||
}
|
||||
|
||||
_groups[action.type].push(
|
||||
{
|
||||
"object": this,
|
||||
"link": this.actionLinks[i]
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively add the actions of the children to the result (as _groups is)
|
||||
// a object, only the reference is passed.
|
||||
for (var i = 0; i < this.children.length; i++)
|
||||
{
|
||||
this.children[i].getActionImplementationGroups(_test, _groups);
|
||||
}
|
||||
|
||||
return _groups;
|
||||
}
|
||||
|
39
phpgwapi/js/egw_action/egw_action_common.js
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* eGroupWare egw_action framework - egw action framework
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stöckel <as@stylite.de>
|
||||
* @copyright 2011 by Andreas Stöckel
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package egw_action
|
||||
* @version $Id:$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets properties given in _data in _obj. Checks whether the property keys
|
||||
* exists and if corresponding setter functions are available. Properties starting
|
||||
* with "_" are ignored.
|
||||
*
|
||||
* @param object _data may be an object with data that will be stored inside the
|
||||
* given object.
|
||||
* @param object _obj is the object where the data will be stored.
|
||||
*/
|
||||
function egwActionStoreJSON(_data, _obj, _setterOnly)
|
||||
{
|
||||
for (key in _data)
|
||||
{
|
||||
if (key.charAt(0) != '_')
|
||||
{
|
||||
//Check whether there is a setter function available
|
||||
if (typeof _obj['set_' + key] == "function")
|
||||
{
|
||||
_obj['set_' + key](_data[key]);
|
||||
}
|
||||
else if (typeof _obj[key] != "undefined" && !_setterOnly)
|
||||
{
|
||||
_obj[key] = _data[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
377
phpgwapi/js/egw_action/egw_menu.js
Normal file
@ -0,0 +1,377 @@
|
||||
/**
|
||||
* eGroupWare egw_action framework - JS Menu abstraction
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stöckel <as@stylite.de>
|
||||
* @copyright 2011 by Andreas Stöckel
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package egw_action
|
||||
* @version $Id:$
|
||||
*/
|
||||
|
||||
//Global variable which is used to store the currently active menu so that it
|
||||
//may be closed when another menu openes
|
||||
var _egw_active_menu = null;
|
||||
|
||||
/**
|
||||
* Internal function which generates a menu item with the given parameters as used
|
||||
* in e.g. the egwMenu.addItem function.
|
||||
*/
|
||||
//TODO Icons: write PHP GD script which is cabable of generating the menu icons in various states (disabled, highlighted)
|
||||
function _egwGenMenuItem(_parent, _id, _label, _iconUrl, _onClick)
|
||||
{
|
||||
//Preset the parameters
|
||||
if (typeof _parent == "undefined")
|
||||
_parent = null;
|
||||
if (typeof _id == "undefined")
|
||||
_id = "";
|
||||
if (typeof _label == "undefined")
|
||||
_label = "";
|
||||
if (typeof _iconUrl == "undefined")
|
||||
_iconUrl = "";
|
||||
if (typeof _onClick == "undefined")
|
||||
_onClick = null;
|
||||
|
||||
//Create a menu item with no parent (null) and set the given parameters
|
||||
var item = new egwMenuItem(_parent, _id);
|
||||
item.set_caption(_label);
|
||||
item.set_iconUrl(_iconUrl);
|
||||
item.set_onClick(_onClick);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function which parses the given menu tree in _elements and adds the
|
||||
* elements to the given parent.
|
||||
*/
|
||||
function _egwGenMenuStructure(_elements, _parent)
|
||||
{
|
||||
var items = [];
|
||||
|
||||
//Go through each object in the elements array
|
||||
for (var i = 0; i < _elements.length; i++)
|
||||
{
|
||||
//Go through each key of the current object
|
||||
var obj = _elements[i];
|
||||
var item = new egwMenuItem(_parent, null);
|
||||
for (key in obj)
|
||||
{
|
||||
if (key == "children" && obj[key].constructor === Array)
|
||||
{
|
||||
//Recursively load the children.
|
||||
item.children = _egwGenMenuStructure(obj[key], item);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Directly set the other keys
|
||||
//TODO Sanity neccessary checks here?
|
||||
//TODO Implement menu item getters?
|
||||
if (key == "id" || key == "caption" || key == "iconUrl" ||
|
||||
key == "checkbox" || key == "checked" || key == "groupIndex" ||
|
||||
key == "enabled" || key == "default" || key == "onClick")
|
||||
{
|
||||
item['set_' + key](obj[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items.push(item);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function which searches for the given ID inside an element tree.
|
||||
*/
|
||||
function _egwSearchMenuItem(_elements, _id)
|
||||
{
|
||||
for (var i = 0; i < _elements.length; i++)
|
||||
{
|
||||
if (_elements[i].id === _id)
|
||||
return _elements[i];
|
||||
|
||||
var item = _egwSearchMenuItem(_elements[i].children, _id);
|
||||
if (item)
|
||||
return item;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function which alows to set the onClick handler of multiple menu items
|
||||
*/
|
||||
function _egwSetMenuOnClick(_elements, _onClick)
|
||||
{
|
||||
for (var i = 0; i < _elements.length; i++)
|
||||
{
|
||||
if (_elements[i].onClick === null)
|
||||
{
|
||||
_elements[i].onClick = _onClick;
|
||||
}
|
||||
_egwSetMenuOnClick(_elements[i].children, _onClick);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the egwMenu object. The egwMenu object is a abstract representation
|
||||
* of a context/popup menu. The actual generation of the menu can by done by so
|
||||
* called menu implementations. Those are activated by simply including the JS file
|
||||
* of such an implementation.
|
||||
*
|
||||
* The currently available implementation is the "egwDhtmlxMenu.js" which is based
|
||||
* upon the dhtmlxmenu component.
|
||||
*/
|
||||
function egwMenu()
|
||||
{
|
||||
//The "items" variable contains all menu items of the menu
|
||||
this.children = [];
|
||||
|
||||
//The "instance" variable contains the currently opened instance. There may
|
||||
//only be one instance opened at a time.
|
||||
this.instance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The private _checkImpl function checks whether a menu implementation is available.
|
||||
*
|
||||
* @returns bool whether a menu implemenation is available.
|
||||
*/
|
||||
egwMenu.prototype._checkImpl = function()
|
||||
{
|
||||
return typeof egwMenuImpl == 'function';
|
||||
}
|
||||
|
||||
/**
|
||||
* The showAtElement function shows the menu at the given screen position in an
|
||||
* (hopefully) optimal orientation. There can only be one instance of the menu opened at
|
||||
* one time and the menu implementation should care that there is only one menu
|
||||
* opened globaly at all.
|
||||
*
|
||||
* @param int _x is the x position at which the menu will be opened
|
||||
* @param int _y is the y position at which the menu will be opened
|
||||
* @param bool _force if true, the menu will be reopened at the given position,
|
||||
* even if it already had been opened. Defaults to false.
|
||||
* @returns bool whether the menu had been opened
|
||||
*/
|
||||
egwMenu.prototype.showAt = function(_x, _y, _force)
|
||||
{
|
||||
if (typeof _force == "undefined")
|
||||
_force = false;
|
||||
|
||||
//Hide any other currently active menu
|
||||
if (_egw_active_menu != null)
|
||||
{
|
||||
if (_egw_active_menu == this && !_force)
|
||||
{
|
||||
this.hide();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_egw_active_menu.hide();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.instance == null && this._checkImpl)
|
||||
{
|
||||
//Obtain a new egwMenuImpl object and pass this instance to it
|
||||
this.instance = new egwMenuImpl(this.children);
|
||||
|
||||
_egw_active_menu = this;
|
||||
|
||||
var self = this;
|
||||
this.instance.showAt(_x, _y, function() {
|
||||
self.instance = null;
|
||||
_egw_active_menu = null;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the menu if it is currently opened. Otherwise nothing happenes.
|
||||
*/
|
||||
egwMenu.prototype.hide = function()
|
||||
{
|
||||
//Reset the currently active menu variable
|
||||
if (_egw_active_menu == this)
|
||||
_egw_active_menu = null;
|
||||
|
||||
//Check whether an currently opened instance exists. If it does, close it.
|
||||
if (this.instance != null)
|
||||
{
|
||||
this.instance.hide();
|
||||
this.instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new menu item to the list and returns a reference to that object.
|
||||
*
|
||||
* @param string _id is a unique identifier of the menu item. You can use the
|
||||
* the getItem function to search a specific menu item inside the menu tree. The
|
||||
* id may also be false, null or "", which makes sense for items like seperators,
|
||||
* which you don't want to access anymore after adding them to the menu tree.
|
||||
* @param string _label is the label of the newly generated menu item. Set the label
|
||||
* to "-" in order to create a sperator.
|
||||
* @param string _iconUrl is the URL of the icon which should be prepended to the
|
||||
* menu item. It may be false, null or "" if you don't want a icon to be displayed.
|
||||
* @param function _onClick is the JS function which is being executed when the
|
||||
* menu item is clicked.
|
||||
* @returns egwMenuItem the newly generated menu item, which had been appended to the
|
||||
* menu item list.
|
||||
*/
|
||||
egwMenu.prototype.addItem = function(_id, _label, _iconUrl, _onClick)
|
||||
{
|
||||
//Append the item to the list
|
||||
var item = _egwGenMenuItem(this, _id, _label, _iconUrl, _onClick);
|
||||
this.children.push(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements fromt the menu structure.
|
||||
*/
|
||||
egwMenu.prototype.clear = function()
|
||||
{
|
||||
this.children = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the menu structure from the given object tree. The object tree is an array
|
||||
* of objects which may contain a subset of the menu item properties. The "children"
|
||||
* property of such an object is interpreted as a new sub-menu tree and appended
|
||||
* to that child.
|
||||
*
|
||||
* @param array _elements is a array of elements which should be added to the menu
|
||||
*/
|
||||
egwMenu.prototype.loadStructure = function(_elements)
|
||||
{
|
||||
this.children = _egwGenMenuStructure(_elements, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the given item id within the element tree.
|
||||
*/
|
||||
egwMenu.prototype.getItem = function(_id)
|
||||
{
|
||||
return _egwSearchMenuItem(this.children, _id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given onClick handler to all menu items which don't have a clicked
|
||||
* handler assigned yet.
|
||||
*/
|
||||
egwMenu.prototype.setGlobalOnClick = function(_onClick)
|
||||
{
|
||||
_egwSetMenuOnClick(this.children, _onClick);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the egwMenuItem. Each entry in a menu (including seperators)
|
||||
* is represented by a menu item.
|
||||
*/
|
||||
function egwMenuItem(_parent, _id)
|
||||
{
|
||||
this.id = _id;
|
||||
this.caption = "";
|
||||
this.checkbox = false;
|
||||
this.checked = false;
|
||||
this.groupIndex = 0;
|
||||
this.enabled = true;
|
||||
this.iconUrl = "";
|
||||
this.onClick = null;
|
||||
this.default = false;
|
||||
|
||||
this.children = [];
|
||||
this.parent = _parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the given item id within the element tree.
|
||||
*/
|
||||
egwMenuItem.prototype.getItem = function(_id)
|
||||
{
|
||||
if (this.id === _id)
|
||||
return this;
|
||||
|
||||
return _egwSearchMenuItem(this.children, _id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given onClick handler to all menu items which don't have a clicked
|
||||
* handler assigned yet.
|
||||
*/
|
||||
egwMenuItem.prototype.setGlobalOnClick = function(_onClick)
|
||||
{
|
||||
this.onClick = _onClick;
|
||||
_egwSetMenuOnClick(this.children, _onClick);
|
||||
}
|
||||
|
||||
//Setter functions for the menuitem properties
|
||||
|
||||
egwMenuItem.prototype.set_id = function(_value)
|
||||
{
|
||||
this.id = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_caption = function(_value)
|
||||
{
|
||||
//A value of "-" means that this element is a seperator.
|
||||
this.caption = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_checkbox = function(_value)
|
||||
{
|
||||
this.checkbox = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_checked = function(_value)
|
||||
{
|
||||
if (_value && this.groupIndex > 0)
|
||||
{
|
||||
//Uncheck all other elements in this radio group
|
||||
for (var i = 0; i < this.parent.children.length; i++)
|
||||
{
|
||||
var obj = this.parent.children[i];
|
||||
if (obj.groupIndex == this.groupIndex)
|
||||
obj.checked = false;
|
||||
}
|
||||
}
|
||||
this.checked = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_groupIndex = function(_value)
|
||||
{
|
||||
//If groupIndex is greater than 0 and the element is a checkbox, it is
|
||||
//treated like a radio box
|
||||
this.groupIndex = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_enabled = function(_value)
|
||||
{
|
||||
this.enabled = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_onClick = function(_value)
|
||||
{
|
||||
this.onClick = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_iconUrl = function(_value)
|
||||
{
|
||||
this.iconUrl = _value;
|
||||
}
|
||||
|
||||
egwMenuItem.prototype.set_default = function(_value)
|
||||
{
|
||||
this.default = _value;
|
||||
}
|
||||
|
||||
|
147
phpgwapi/js/egw_action/egw_menu_dhtmlx.js
Normal file
@ -0,0 +1,147 @@
|
||||
/**
|
||||
* eGroupWare egw_action framework - JS Menu abstraction
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Andreas Stöckel <as@stylite.de>
|
||||
* @copyright 2011 by Andreas Stöckel
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package egw_action
|
||||
* @version $Id:$
|
||||
*/
|
||||
|
||||
function egwMenuImpl(_structure)
|
||||
{
|
||||
//Create a new dhtmlxmenu object
|
||||
this.dhtmlxmenu = new dhtmlXMenuObject();
|
||||
this.dhtmlxmenu.setSkin("egw");
|
||||
this.dhtmlxmenu.renderAsContextMenu();
|
||||
|
||||
var self = this;
|
||||
|
||||
//Attach the simple click handler
|
||||
this.dhtmlxmenu.attachEvent("onClick", function(id) {
|
||||
if (id)
|
||||
{
|
||||
var elem = self.dhtmlxmenu.getUserData(id, 'egw_menu');
|
||||
if (elem && elem.onClick)
|
||||
{
|
||||
elem.onClick(elem);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Attach the radiobutton click handler
|
||||
this.dhtmlxmenu.attachEvent("onRadioClick", function(group, idChecked, idClicked, zoneId, casState) {
|
||||
if (idClicked)
|
||||
{
|
||||
var elem = self.dhtmlxmenu.getUserData(idClicked, 'egw_menu');
|
||||
if (elem)
|
||||
{
|
||||
elem.set_checked(true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
//Attach the radiobutton click handler
|
||||
this.dhtmlxmenu.attachEvent("onCheckboxClick", function(id, state, zoneId, casState) {
|
||||
if (id)
|
||||
{
|
||||
var elem = self.dhtmlxmenu.getUserData(id, 'egw_menu');
|
||||
if (elem)
|
||||
{
|
||||
elem.set_checked(!state);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
//Translate the given structure to the dhtmlx object structure
|
||||
this._translateStructure(_structure, this.dhtmlxmenu.topId, 0);
|
||||
}
|
||||
|
||||
egwMenuImpl.prototype._translateStructure = function(_structure, _parentId, _idCnt)
|
||||
{
|
||||
//Initialize the counter which we will use to generate unique id's for all
|
||||
//dhtmlx menu objects
|
||||
var counter = 0;
|
||||
var last_id = null;
|
||||
|
||||
for (var i = 0; i < _structure.length; i++)
|
||||
{
|
||||
var id = 'elem_' + (_idCnt + counter);
|
||||
var elem = _structure[i];
|
||||
|
||||
counter++;
|
||||
|
||||
//Check whether this element is a seperator
|
||||
if (elem.caption == '-' && last_id != null)
|
||||
{
|
||||
//Add the separator next to last_id with the id "id"
|
||||
this.dhtmlxmenu.addNewSeparator(last_id, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (elem.checkbox && elem.groupIndex === 0)
|
||||
{
|
||||
//Add checkbox
|
||||
this.dhtmlxmenu.addCheckbox("child", _parentId, i, id,
|
||||
elem.caption, elem.checked, !elem.enabled);
|
||||
}
|
||||
else if (elem.checkbox && elem.groupIndex > 0)
|
||||
{
|
||||
//Add radiobox
|
||||
elem._dhtmlx_grpid = "grp_" + _idCnt + '_' + elem.groupIndex;
|
||||
this.dhtmlxmenu.addRadioButton("child", _parentId, i, id,
|
||||
elem.caption, elem._dhtmlx_grpid, elem.checked, !elem.enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
var caption = elem.caption;
|
||||
if (elem.default)
|
||||
caption = "<b>" + caption + "</b>"
|
||||
this.dhtmlxmenu.addNewChild(_parentId, i, id, caption, !elem.enabled,
|
||||
elem.iconUrl, elem.iconUrl);
|
||||
}
|
||||
|
||||
if (elem.children.length > 0)
|
||||
{
|
||||
counter += this._translateStructure(elem.children, id, (_idCnt + counter));
|
||||
}
|
||||
}
|
||||
|
||||
//Set the actual egw menu as user data element
|
||||
this.dhtmlxmenu.setUserData(id, 'egw_menu', elem);
|
||||
|
||||
var last_id = id;
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
|
||||
egwMenuImpl.prototype.showAt = function(_x, _y, _onHide)
|
||||
{
|
||||
var self = this;
|
||||
|
||||
if (_onHide)
|
||||
{
|
||||
this.dhtmlxmenu.attachEvent("onHide", function(id) {
|
||||
if (id === null)
|
||||
{
|
||||
_onHide();
|
||||
}
|
||||
});
|
||||
}
|
||||
this.dhtmlxmenu.showContextMenu(_x, _y);
|
||||
}
|
||||
|
||||
egwMenuImpl.prototype.hide = function()
|
||||
{
|
||||
this.dhtmlxmenu.hide();
|
||||
}
|
||||
|
||||
|
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_chrd.gif
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_loader.gif
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_subar.gif
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_subselbg.gif
Normal file
After Width: | Height: | Size: 52 B |
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_subselbg.png
Normal file
After Width: | Height: | Size: 433 B |
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_subsepbg.gif
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_topbg.gif
Normal file
After Width: | Height: | Size: 66 B |
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_topselbg.gif
Normal file
After Width: | Height: | Size: 45 B |
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_topsepbg.gif
Normal file
After Width: | Height: | Size: 68 B |
BIN
phpgwapi/js/egw_action/test/imgs/dhxmenu_upar.gif
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
phpgwapi/js/egw_action/test/imgs/disk.png
Executable file
After Width: | Height: | Size: 620 B |
BIN
phpgwapi/js/egw_action/test/imgs/folder.png
Executable file
After Width: | Height: | Size: 537 B |
BIN
phpgwapi/js/egw_action/test/imgs/page.png
Executable file
After Width: | Height: | Size: 635 B |
BIN
phpgwapi/js/egw_action/test/imgs/wrench.png
Executable file
After Width: | Height: | Size: 610 B |
928
phpgwapi/js/egw_action/test/js/dhtmlxcommon.js
Normal file
@ -0,0 +1,928 @@
|
||||
dhtmlx=function(obj){
|
||||
for (var a in obj) dhtmlx[a]=obj[a];
|
||||
return dhtmlx; //simple singleton
|
||||
};
|
||||
dhtmlx.extend_api=function(name,map,ext){
|
||||
var t = window[name];
|
||||
if (!t) return; //component not defined
|
||||
window[name]=function(obj){
|
||||
if (obj && typeof obj == "object" && !obj.tagName){
|
||||
var that = t.apply(this,(map._init?map._init(obj):arguments));
|
||||
//global settings
|
||||
for (var a in dhtmlx)
|
||||
if (map[a]) this[map[a]](dhtmlx[a]);
|
||||
//local settings
|
||||
for (var a in obj){
|
||||
if (map[a]) this[map[a]](obj[a]);
|
||||
else if (a.indexOf("on")==0){
|
||||
this.attachEvent(a,obj[a]);
|
||||
}
|
||||
}
|
||||
} else
|
||||
var that = t.apply(this,arguments);
|
||||
if (map._patch) map._patch(this);
|
||||
return that||this;
|
||||
};
|
||||
window[name].prototype=t.prototype;
|
||||
if (ext)
|
||||
dhtmlXHeir(window[name].prototype,ext);
|
||||
};
|
||||
|
||||
dhtmlxAjax={
|
||||
get:function(url,callback){
|
||||
var t=new dtmlXMLLoaderObject(true);
|
||||
t.async=(arguments.length<3);
|
||||
t.waitCall=callback;
|
||||
t.loadXML(url)
|
||||
return t;
|
||||
},
|
||||
post:function(url,post,callback){
|
||||
var t=new dtmlXMLLoaderObject(true);
|
||||
t.async=(arguments.length<4);
|
||||
t.waitCall=callback;
|
||||
t.loadXML(url,true,post)
|
||||
return t;
|
||||
},
|
||||
getSync:function(url){
|
||||
return this.get(url,null,true)
|
||||
},
|
||||
postSync:function(url,post){
|
||||
return this.post(url,post,null,true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc: xmlLoader object
|
||||
* @type: private
|
||||
* @param: funcObject - xml parser function
|
||||
* @param: object - jsControl object
|
||||
* @param: async - sync/async mode (async by default)
|
||||
* @param: rSeed - enable/disable random seed ( prevent IE caching)
|
||||
* @topic: 0
|
||||
*/
|
||||
function dtmlXMLLoaderObject(funcObject, dhtmlObject, async, rSeed){
|
||||
this.xmlDoc="";
|
||||
|
||||
if (typeof (async) != "undefined")
|
||||
this.async=async;
|
||||
else
|
||||
this.async=true;
|
||||
|
||||
this.onloadAction=funcObject||null;
|
||||
this.mainObject=dhtmlObject||null;
|
||||
this.waitCall=null;
|
||||
this.rSeed=rSeed||false;
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* @desc: xml loading handler
|
||||
* @type: private
|
||||
* @param: dtmlObject - xmlLoader object
|
||||
* @topic: 0
|
||||
*/
|
||||
dtmlXMLLoaderObject.prototype.waitLoadFunction=function(dhtmlObject){
|
||||
var once = true;
|
||||
this.check=function (){
|
||||
if ((dhtmlObject)&&(dhtmlObject.onloadAction != null)){
|
||||
if ((!dhtmlObject.xmlDoc.readyState)||(dhtmlObject.xmlDoc.readyState == 4)){
|
||||
if (!once)
|
||||
return;
|
||||
|
||||
once=false; //IE 5 fix
|
||||
if (typeof dhtmlObject.onloadAction == "function")
|
||||
dhtmlObject.onloadAction(dhtmlObject.mainObject, null, null, null, dhtmlObject);
|
||||
|
||||
if (dhtmlObject.waitCall){
|
||||
dhtmlObject.waitCall.call(this,dhtmlObject);
|
||||
dhtmlObject.waitCall=null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return this.check;
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc: return XML top node
|
||||
* @param: tagName - top XML node tag name (not used in IE, required for Safari and Mozilla)
|
||||
* @type: private
|
||||
* @returns: top XML node
|
||||
* @topic: 0
|
||||
*/
|
||||
dtmlXMLLoaderObject.prototype.getXMLTopNode=function(tagName, oldObj){
|
||||
if (this.xmlDoc.responseXML){
|
||||
var temp = this.xmlDoc.responseXML.getElementsByTagName(tagName);
|
||||
if(temp.length==0 && tagName.indexOf(":")!=-1)
|
||||
var temp = this.xmlDoc.responseXML.getElementsByTagName((tagName.split(":"))[1]);
|
||||
var z = temp[0];
|
||||
} else
|
||||
var z = this.xmlDoc.documentElement;
|
||||
|
||||
if (z){
|
||||
this._retry=false;
|
||||
return z;
|
||||
}
|
||||
|
||||
if ((_isIE)&&(!this._retry)){
|
||||
//fall back to MS.XMLDOM
|
||||
var xmlString = this.xmlDoc.responseText;
|
||||
var oldObj = this.xmlDoc;
|
||||
this._retry=true;
|
||||
this.xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
|
||||
this.xmlDoc.async=false;
|
||||
this.xmlDoc["loadXM"+"L"](xmlString);
|
||||
|
||||
return this.getXMLTopNode(tagName, oldObj);
|
||||
}
|
||||
dhtmlxError.throwError("LoadXML", "Incorrect XML", [
|
||||
(oldObj||this.xmlDoc),
|
||||
this.mainObject
|
||||
]);
|
||||
|
||||
return document.createElement("DIV");
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc: load XML from string
|
||||
* @type: private
|
||||
* @param: xmlString - xml string
|
||||
* @topic: 0
|
||||
*/
|
||||
dtmlXMLLoaderObject.prototype.loadXMLString=function(xmlString){
|
||||
{
|
||||
try{
|
||||
var parser = new DOMParser();
|
||||
this.xmlDoc=parser.parseFromString(xmlString, "text/xml");
|
||||
}
|
||||
catch (e){
|
||||
this.xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
|
||||
this.xmlDoc.async=this.async;
|
||||
this.xmlDoc["loadXM"+"L"](xmlString);
|
||||
}
|
||||
}
|
||||
|
||||
this.onloadAction(this.mainObject, null, null, null, this);
|
||||
|
||||
if (this.waitCall){
|
||||
this.waitCall();
|
||||
this.waitCall=null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @desc: load XML
|
||||
* @type: private
|
||||
* @param: filePath - xml file path
|
||||
* @param: postMode - send POST request
|
||||
* @param: postVars - list of vars for post request
|
||||
* @topic: 0
|
||||
*/
|
||||
dtmlXMLLoaderObject.prototype.loadXML=function(filePath, postMode, postVars, rpc){
|
||||
if (this.rSeed)
|
||||
filePath+=((filePath.indexOf("?") != -1) ? "&" : "?")+"a_dhx_rSeed="+(new Date()).valueOf();
|
||||
this.filePath=filePath;
|
||||
|
||||
if ((!_isIE)&&(window.XMLHttpRequest))
|
||||
this.xmlDoc=new XMLHttpRequest();
|
||||
else {
|
||||
this.xmlDoc=new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
|
||||
if (this.async)
|
||||
this.xmlDoc.onreadystatechange=new this.waitLoadFunction(this);
|
||||
this.xmlDoc.open(postMode ? "POST" : "GET", filePath, this.async);
|
||||
|
||||
if (rpc){
|
||||
this.xmlDoc.setRequestHeader("User-Agent", "dhtmlxRPC v0.1 ("+navigator.userAgent+")");
|
||||
this.xmlDoc.setRequestHeader("Content-type", "text/xml");
|
||||
}
|
||||
|
||||
else if (postMode)
|
||||
this.xmlDoc.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
|
||||
this.xmlDoc.setRequestHeader("X-Requested-With","XMLHttpRequest");
|
||||
this.xmlDoc.send(null||postVars);
|
||||
|
||||
if (!this.async)
|
||||
(new this.waitLoadFunction(this))();
|
||||
};
|
||||
/**
|
||||
* @desc: destructor, cleans used memory
|
||||
* @type: private
|
||||
* @topic: 0
|
||||
*/
|
||||
dtmlXMLLoaderObject.prototype.destructor=function(){
|
||||
this._filterXPath = null;
|
||||
this._getAllNamedChilds = null;
|
||||
this._retry = null;
|
||||
this.async = null;
|
||||
this.rSeed = null;
|
||||
this.filePath = null;
|
||||
this.onloadAction = null;
|
||||
this.mainObject = null;
|
||||
this.xmlDoc = null;
|
||||
this.doXPath = null;
|
||||
this.doXPathOpera = null;
|
||||
this.doXSLTransToObject = null;
|
||||
this.doXSLTransToString = null;
|
||||
this.loadXML = null;
|
||||
this.loadXMLString = null;
|
||||
// this.waitLoadFunction = null;
|
||||
this.doSerialization = null;
|
||||
this.xmlNodeToJSON = null;
|
||||
this.getXMLTopNode = null;
|
||||
this.setXSLParamValue = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
dtmlXMLLoaderObject.prototype.xmlNodeToJSON = function(node){
|
||||
var t={};
|
||||
for (var i=0; i<node.attributes.length; i++)
|
||||
t[node.attributes[i].name]=node.attributes[i].value;
|
||||
t["_tagvalue"]=node.firstChild?node.firstChild.nodeValue:"";
|
||||
for (var i=0; i<node.childNodes.length; i++){
|
||||
var name=node.childNodes[i].tagName;
|
||||
if (name){
|
||||
if (!t[name]) t[name]=[];
|
||||
t[name].push(this.xmlNodeToJSON(node.childNodes[i]));
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc: Call wrapper
|
||||
* @type: private
|
||||
* @param: funcObject - action handler
|
||||
* @param: dhtmlObject - user data
|
||||
* @returns: function handler
|
||||
* @topic: 0
|
||||
*/
|
||||
function callerFunction(funcObject, dhtmlObject){
|
||||
this.handler=function(e){
|
||||
if (!e)
|
||||
e=window.event;
|
||||
funcObject(e, dhtmlObject);
|
||||
return true;
|
||||
};
|
||||
return this.handler;
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc: Calculate absolute position of html object
|
||||
* @type: private
|
||||
* @param: htmlObject - html object
|
||||
* @topic: 0
|
||||
*/
|
||||
function getAbsoluteLeft(htmlObject){
|
||||
return getOffset(htmlObject).left;
|
||||
}
|
||||
/**
|
||||
* @desc: Calculate absolute position of html object
|
||||
* @type: private
|
||||
* @param: htmlObject - html object
|
||||
* @topic: 0
|
||||
*/
|
||||
function getAbsoluteTop(htmlObject){
|
||||
return getOffset(htmlObject).top;
|
||||
}
|
||||
|
||||
function getOffsetSum(elem) {
|
||||
var top=0, left=0;
|
||||
while(elem) {
|
||||
top = top + parseInt(elem.offsetTop);
|
||||
left = left + parseInt(elem.offsetLeft);
|
||||
elem = elem.offsetParent;
|
||||
}
|
||||
return {top: top, left: left};
|
||||
}
|
||||
function getOffsetRect(elem) {
|
||||
var box = elem.getBoundingClientRect();
|
||||
var body = document.body;
|
||||
var docElem = document.documentElement;
|
||||
var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
|
||||
var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
|
||||
var clientTop = docElem.clientTop || body.clientTop || 0;
|
||||
var clientLeft = docElem.clientLeft || body.clientLeft || 0;
|
||||
var top = box.top + scrollTop - clientTop;
|
||||
var left = box.left + scrollLeft - clientLeft;
|
||||
return { top: Math.round(top), left: Math.round(left) };
|
||||
}
|
||||
function getOffset(elem) {
|
||||
if (elem.getBoundingClientRect) {
|
||||
return getOffsetRect(elem);
|
||||
} else {
|
||||
return getOffsetSum(elem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc: Convert string to it boolean representation
|
||||
* @type: private
|
||||
* @param: inputString - string for covertion
|
||||
* @topic: 0
|
||||
*/
|
||||
function convertStringToBoolean(inputString){
|
||||
if (typeof (inputString) == "string")
|
||||
inputString=inputString.toLowerCase();
|
||||
|
||||
switch (inputString){
|
||||
case "1":
|
||||
case "true":
|
||||
case "yes":
|
||||
case "y":
|
||||
case 1:
|
||||
case true:
|
||||
return true;
|
||||
break;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc: find out what symbol to use as url param delimiters in further params
|
||||
* @type: private
|
||||
* @param: str - current url string
|
||||
* @topic: 0
|
||||
*/
|
||||
function getUrlSymbol(str){
|
||||
if (str.indexOf("?") != -1)
|
||||
return "&"
|
||||
else
|
||||
return "?"
|
||||
}
|
||||
|
||||
function dhtmlDragAndDropObject(){
|
||||
if (window.dhtmlDragAndDrop)
|
||||
return window.dhtmlDragAndDrop;
|
||||
|
||||
this.lastLanding=0;
|
||||
this.dragNode=0;
|
||||
this.dragStartNode=0;
|
||||
this.dragStartObject=0;
|
||||
this.tempDOMU=null;
|
||||
this.tempDOMM=null;
|
||||
this.waitDrag=0;
|
||||
window.dhtmlDragAndDrop=this;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
dhtmlDragAndDropObject.prototype.removeDraggableItem=function(htmlNode){
|
||||
htmlNode.onmousedown=null;
|
||||
htmlNode.dragStarter=null;
|
||||
htmlNode.dragLanding=null;
|
||||
}
|
||||
dhtmlDragAndDropObject.prototype.addDraggableItem=function(htmlNode, dhtmlObject){
|
||||
htmlNode.onmousedown=this.preCreateDragCopy;
|
||||
htmlNode.dragStarter=dhtmlObject;
|
||||
this.addDragLanding(htmlNode, dhtmlObject);
|
||||
}
|
||||
dhtmlDragAndDropObject.prototype.addDragLanding=function(htmlNode, dhtmlObject){
|
||||
htmlNode.dragLanding=dhtmlObject;
|
||||
}
|
||||
dhtmlDragAndDropObject.prototype.preCreateDragCopy=function(e){
|
||||
if ((e||window.event) && (e||event).button == 2)
|
||||
return;
|
||||
|
||||
if (window.dhtmlDragAndDrop.waitDrag){
|
||||
window.dhtmlDragAndDrop.waitDrag=0;
|
||||
document.body.onmouseup=window.dhtmlDragAndDrop.tempDOMU;
|
||||
document.body.onmousemove=window.dhtmlDragAndDrop.tempDOMM;
|
||||
return false;
|
||||
}
|
||||
|
||||
window.dhtmlDragAndDrop.waitDrag=1;
|
||||
window.dhtmlDragAndDrop.tempDOMU=document.body.onmouseup;
|
||||
window.dhtmlDragAndDrop.tempDOMM=document.body.onmousemove;
|
||||
window.dhtmlDragAndDrop.dragStartNode=this;
|
||||
window.dhtmlDragAndDrop.dragStartObject=this.dragStarter;
|
||||
document.body.onmouseup=window.dhtmlDragAndDrop.preCreateDragCopy;
|
||||
document.body.onmousemove=window.dhtmlDragAndDrop.callDrag;
|
||||
window.dhtmlDragAndDrop.downtime = new Date().valueOf();
|
||||
|
||||
|
||||
if ((e)&&(e.preventDefault)){
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
dhtmlDragAndDropObject.prototype.callDrag=function(e){
|
||||
if (!e)
|
||||
e=window.event;
|
||||
dragger=window.dhtmlDragAndDrop;
|
||||
if ((new Date()).valueOf()-dragger.downtime<100) return;
|
||||
|
||||
if ((e.button == 0)&&(_isIE))
|
||||
return dragger.stopDrag();
|
||||
|
||||
if (!dragger.dragNode&&dragger.waitDrag){
|
||||
dragger.dragNode=dragger.dragStartObject._createDragNode(dragger.dragStartNode, e);
|
||||
|
||||
if (!dragger.dragNode)
|
||||
return dragger.stopDrag();
|
||||
|
||||
dragger.dragNode.onselectstart=function(){return false;}
|
||||
dragger.gldragNode=dragger.dragNode;
|
||||
document.body.appendChild(dragger.dragNode);
|
||||
document.body.onmouseup=dragger.stopDrag;
|
||||
dragger.waitDrag=0;
|
||||
dragger.dragNode.pWindow=window;
|
||||
dragger.initFrameRoute();
|
||||
}
|
||||
|
||||
if (dragger.dragNode.parentNode != window.document.body){
|
||||
var grd = dragger.gldragNode;
|
||||
|
||||
if (dragger.gldragNode.old)
|
||||
grd=dragger.gldragNode.old;
|
||||
|
||||
//if (!document.all) dragger.calculateFramePosition();
|
||||
grd.parentNode.removeChild(grd);
|
||||
var oldBody = dragger.dragNode.pWindow;
|
||||
|
||||
if (grd.pWindow && grd.pWindow.dhtmlDragAndDrop.lastLanding)
|
||||
grd.pWindow.dhtmlDragAndDrop.lastLanding.dragLanding._dragOut(grd.pWindow.dhtmlDragAndDrop.lastLanding);
|
||||
|
||||
// var oldp=dragger.dragNode.parentObject;
|
||||
if (_isIE){
|
||||
var div = document.createElement("Div");
|
||||
div.innerHTML=dragger.dragNode.outerHTML;
|
||||
dragger.dragNode=div.childNodes[0];
|
||||
} else
|
||||
dragger.dragNode=dragger.dragNode.cloneNode(true);
|
||||
|
||||
dragger.dragNode.pWindow=window;
|
||||
// dragger.dragNode.parentObject=oldp;
|
||||
|
||||
dragger.gldragNode.old=dragger.dragNode;
|
||||
document.body.appendChild(dragger.dragNode);
|
||||
oldBody.dhtmlDragAndDrop.dragNode=dragger.dragNode;
|
||||
}
|
||||
|
||||
dragger.dragNode.style.left=e.clientX+15+(dragger.fx
|
||||
? dragger.fx*(-1)
|
||||
: 0)
|
||||
+(document.body.scrollLeft||document.documentElement.scrollLeft)+"px";
|
||||
dragger.dragNode.style.top=e.clientY+3+(dragger.fy
|
||||
? dragger.fy*(-1)
|
||||
: 0)
|
||||
+(document.body.scrollTop||document.documentElement.scrollTop)+"px";
|
||||
|
||||
if (!e.srcElement)
|
||||
var z = e.target;
|
||||
else
|
||||
z=e.srcElement;
|
||||
dragger.checkLanding(z, e);
|
||||
}
|
||||
|
||||
dhtmlDragAndDropObject.prototype.calculateFramePosition=function(n){
|
||||
//this.fx = 0, this.fy = 0;
|
||||
if (window.name){
|
||||
var el = parent.frames[window.name].frameElement.offsetParent;
|
||||
var fx = 0;
|
||||
var fy = 0;
|
||||
|
||||
while (el){
|
||||
fx+=el.offsetLeft;
|
||||
fy+=el.offsetTop;
|
||||
el=el.offsetParent;
|
||||
}
|
||||
|
||||
if ((parent.dhtmlDragAndDrop)){
|
||||
var ls = parent.dhtmlDragAndDrop.calculateFramePosition(1);
|
||||
fx+=ls.split('_')[0]*1;
|
||||
fy+=ls.split('_')[1]*1;
|
||||
}
|
||||
|
||||
if (n)
|
||||
return fx+"_"+fy;
|
||||
else
|
||||
this.fx=fx;
|
||||
this.fy=fy;
|
||||
}
|
||||
return "0_0";
|
||||
}
|
||||
dhtmlDragAndDropObject.prototype.checkLanding=function(htmlObject, e){
|
||||
if ((htmlObject)&&(htmlObject.dragLanding)){
|
||||
if (this.lastLanding)
|
||||
this.lastLanding.dragLanding._dragOut(this.lastLanding);
|
||||
this.lastLanding=htmlObject;
|
||||
this.lastLanding=this.lastLanding.dragLanding._dragIn(this.lastLanding, this.dragStartNode, e.clientX,
|
||||
e.clientY, e);
|
||||
this.lastLanding_scr=(_isIE ? e.srcElement : e.target);
|
||||
} else {
|
||||
if ((htmlObject)&&(htmlObject.tagName != "BODY"))
|
||||
this.checkLanding(htmlObject.parentNode, e);
|
||||
else {
|
||||
if (this.lastLanding)
|
||||
this.lastLanding.dragLanding._dragOut(this.lastLanding, e.clientX, e.clientY, e);
|
||||
this.lastLanding=0;
|
||||
|
||||
if (this._onNotFound)
|
||||
this._onNotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
dhtmlDragAndDropObject.prototype.stopDrag=function(e, mode){
|
||||
dragger=window.dhtmlDragAndDrop;
|
||||
|
||||
if (!mode){
|
||||
dragger.stopFrameRoute();
|
||||
var temp = dragger.lastLanding;
|
||||
dragger.lastLanding=null;
|
||||
|
||||
if (temp)
|
||||
temp.dragLanding._drag(dragger.dragStartNode, dragger.dragStartObject, temp, (_isIE
|
||||
? event.srcElement
|
||||
: e.target));
|
||||
}
|
||||
dragger.lastLanding=null;
|
||||
|
||||
if ((dragger.dragNode)&&(dragger.dragNode.parentNode == document.body))
|
||||
dragger.dragNode.parentNode.removeChild(dragger.dragNode);
|
||||
dragger.dragNode=0;
|
||||
dragger.gldragNode=0;
|
||||
dragger.fx=0;
|
||||
dragger.fy=0;
|
||||
dragger.dragStartNode=0;
|
||||
dragger.dragStartObject=0;
|
||||
document.body.onmouseup=dragger.tempDOMU;
|
||||
document.body.onmousemove=dragger.tempDOMM;
|
||||
dragger.tempDOMU=null;
|
||||
dragger.tempDOMM=null;
|
||||
dragger.waitDrag=0;
|
||||
}
|
||||
|
||||
dhtmlDragAndDropObject.prototype.stopFrameRoute=function(win){
|
||||
if (win)
|
||||
window.dhtmlDragAndDrop.stopDrag(1, 1);
|
||||
|
||||
for (var i = 0; i < window.frames.length; i++){
|
||||
try{
|
||||
if ((window.frames[i] != win)&&(window.frames[i].dhtmlDragAndDrop))
|
||||
window.frames[i].dhtmlDragAndDrop.stopFrameRoute(window);
|
||||
} catch(e){}
|
||||
}
|
||||
|
||||
try{
|
||||
if ((parent.dhtmlDragAndDrop)&&(parent != window)&&(parent != win))
|
||||
parent.dhtmlDragAndDrop.stopFrameRoute(window);
|
||||
} catch(e){}
|
||||
}
|
||||
dhtmlDragAndDropObject.prototype.initFrameRoute=function(win, mode){
|
||||
if (win){
|
||||
window.dhtmlDragAndDrop.preCreateDragCopy();
|
||||
window.dhtmlDragAndDrop.dragStartNode=win.dhtmlDragAndDrop.dragStartNode;
|
||||
window.dhtmlDragAndDrop.dragStartObject=win.dhtmlDragAndDrop.dragStartObject;
|
||||
window.dhtmlDragAndDrop.dragNode=win.dhtmlDragAndDrop.dragNode;
|
||||
window.dhtmlDragAndDrop.gldragNode=win.dhtmlDragAndDrop.dragNode;
|
||||
window.document.body.onmouseup=window.dhtmlDragAndDrop.stopDrag;
|
||||
window.waitDrag=0;
|
||||
|
||||
if (((!_isIE)&&(mode))&&((!_isFF)||(_FFrv < 1.8)))
|
||||
window.dhtmlDragAndDrop.calculateFramePosition();
|
||||
}
|
||||
try{
|
||||
if ((parent.dhtmlDragAndDrop)&&(parent != window)&&(parent != win))
|
||||
parent.dhtmlDragAndDrop.initFrameRoute(window);
|
||||
}catch(e){}
|
||||
|
||||
for (var i = 0; i < window.frames.length; i++){
|
||||
try{
|
||||
if ((window.frames[i] != win)&&(window.frames[i].dhtmlDragAndDrop))
|
||||
window.frames[i].dhtmlDragAndDrop.initFrameRoute(window, ((!win||mode) ? 1 : 0));
|
||||
} catch(e){}
|
||||
}
|
||||
}
|
||||
|
||||
var _isFF = false;
|
||||
var _isIE = false;
|
||||
var _isOpera = false;
|
||||
var _isKHTML = false;
|
||||
var _isMacOS = false;
|
||||
var _isChrome = false;
|
||||
|
||||
if (navigator.userAgent.indexOf('Macintosh') != -1)
|
||||
_isMacOS=true;
|
||||
|
||||
|
||||
if (navigator.userAgent.toLowerCase().indexOf('chrome')>-1)
|
||||
_isChrome=true;
|
||||
|
||||
if ((navigator.userAgent.indexOf('Safari') != -1)||(navigator.userAgent.indexOf('Konqueror') != -1)){
|
||||
var _KHTMLrv = parseFloat(navigator.userAgent.substr(navigator.userAgent.indexOf('Safari')+7, 5));
|
||||
|
||||
if (_KHTMLrv > 525){ //mimic FF behavior for Safari 3.1+
|
||||
_isFF=true;
|
||||
var _FFrv = 1.9;
|
||||
} else
|
||||
_isKHTML=true;
|
||||
} else if (navigator.userAgent.indexOf('Opera') != -1){
|
||||
_isOpera=true;
|
||||
_OperaRv=parseFloat(navigator.userAgent.substr(navigator.userAgent.indexOf('Opera')+6, 3));
|
||||
}
|
||||
|
||||
|
||||
else if (navigator.appName.indexOf("Microsoft") != -1){
|
||||
_isIE=true;
|
||||
if (navigator.appVersion.indexOf("MSIE 8.0")!= -1 && document.compatMode != "BackCompat") _isIE=8;
|
||||
if (navigator.appVersion.indexOf("MSIE 9.0")!= -1 && document.compatMode != "BackCompat") _isIE=8;
|
||||
} else {
|
||||
_isFF=true;
|
||||
var _FFrv = parseFloat(navigator.userAgent.split("rv:")[1])
|
||||
}
|
||||
|
||||
|
||||
//multibrowser Xpath processor
|
||||
dtmlXMLLoaderObject.prototype.doXPath=function(xpathExp, docObj, namespace, result_type){
|
||||
if (_isKHTML || (!_isIE && !window.XPathResult))
|
||||
return this.doXPathOpera(xpathExp, docObj);
|
||||
|
||||
if (_isIE){ //IE
|
||||
if (!docObj)
|
||||
if (!this.xmlDoc.nodeName)
|
||||
docObj=this.xmlDoc.responseXML
|
||||
else
|
||||
docObj=this.xmlDoc;
|
||||
|
||||
if (!docObj)
|
||||
dhtmlxError.throwError("LoadXML", "Incorrect XML", [
|
||||
(docObj||this.xmlDoc),
|
||||
this.mainObject
|
||||
]);
|
||||
|
||||
if (namespace != null)
|
||||
docObj.setProperty("SelectionNamespaces", "xmlns:xsl='"+namespace+"'"); //
|
||||
|
||||
if (result_type == 'single'){
|
||||
return docObj.selectSingleNode(xpathExp);
|
||||
}
|
||||
else {
|
||||
return docObj.selectNodes(xpathExp)||new Array(0);
|
||||
}
|
||||
} else { //Mozilla
|
||||
var nodeObj = docObj;
|
||||
|
||||
if (!docObj){
|
||||
if (!this.xmlDoc.nodeName){
|
||||
docObj=this.xmlDoc.responseXML
|
||||
}
|
||||
else {
|
||||
docObj=this.xmlDoc;
|
||||
}
|
||||
}
|
||||
|
||||
if (!docObj)
|
||||
dhtmlxError.throwError("LoadXML", "Incorrect XML", [
|
||||
(docObj||this.xmlDoc),
|
||||
this.mainObject
|
||||
]);
|
||||
|
||||
if (docObj.nodeName.indexOf("document") != -1){
|
||||
nodeObj=docObj;
|
||||
}
|
||||
else {
|
||||
nodeObj=docObj;
|
||||
docObj=docObj.ownerDocument;
|
||||
}
|
||||
var retType = XPathResult.ANY_TYPE;
|
||||
|
||||
if (result_type == 'single')
|
||||
retType=XPathResult.FIRST_ORDERED_NODE_TYPE
|
||||
var rowsCol = new Array();
|
||||
var col = docObj.evaluate(xpathExp, nodeObj, function(pref){
|
||||
return namespace
|
||||
}, retType, null);
|
||||
|
||||
if (retType == XPathResult.FIRST_ORDERED_NODE_TYPE){
|
||||
return col.singleNodeValue;
|
||||
}
|
||||
var thisColMemb = col.iterateNext();
|
||||
|
||||
while (thisColMemb){
|
||||
rowsCol[rowsCol.length]=thisColMemb;
|
||||
thisColMemb=col.iterateNext();
|
||||
}
|
||||
return rowsCol;
|
||||
}
|
||||
}
|
||||
|
||||
function _dhtmlxError(type, name, params){
|
||||
if (!this.catches)
|
||||
this.catches=new Array();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
_dhtmlxError.prototype.catchError=function(type, func_name){
|
||||
this.catches[type]=func_name;
|
||||
}
|
||||
_dhtmlxError.prototype.throwError=function(type, name, params){
|
||||
if (this.catches[type])
|
||||
return this.catches[type](type, name, params);
|
||||
|
||||
if (this.catches["ALL"])
|
||||
return this.catches["ALL"](type, name, params);
|
||||
|
||||
alert("Error type: "+arguments[0]+"\nDescription: "+arguments[1]);
|
||||
return null;
|
||||
}
|
||||
|
||||
window.dhtmlxError=new _dhtmlxError();
|
||||
|
||||
|
||||
//opera fake, while 9.0 not released
|
||||
//multibrowser Xpath processor
|
||||
dtmlXMLLoaderObject.prototype.doXPathOpera=function(xpathExp, docObj){
|
||||
//this is fake for Opera
|
||||
var z = xpathExp.replace(/[\/]+/gi, "/").split('/');
|
||||
var obj = null;
|
||||
var i = 1;
|
||||
|
||||
if (!z.length)
|
||||
return [];
|
||||
|
||||
if (z[0] == ".")
|
||||
obj=[docObj]; else if (z[0] == ""){
|
||||
obj=(this.xmlDoc.responseXML||this.xmlDoc).getElementsByTagName(z[i].replace(/\[[^\]]*\]/g, ""));
|
||||
i++;
|
||||
} else
|
||||
return [];
|
||||
|
||||
for (i; i < z.length; i++)obj=this._getAllNamedChilds(obj, z[i]);
|
||||
|
||||
if (z[i-1].indexOf("[") != -1)
|
||||
obj=this._filterXPath(obj, z[i-1]);
|
||||
return obj;
|
||||
}
|
||||
|
||||
dtmlXMLLoaderObject.prototype._filterXPath=function(a, b){
|
||||
var c = new Array();
|
||||
var b = b.replace(/[^\[]*\[\@/g, "").replace(/[\[\]\@]*/g, "");
|
||||
|
||||
for (var i = 0; i < a.length; i++)
|
||||
if (a[i].getAttribute(b))
|
||||
c[c.length]=a[i];
|
||||
|
||||
return c;
|
||||
}
|
||||
dtmlXMLLoaderObject.prototype._getAllNamedChilds=function(a, b){
|
||||
var c = new Array();
|
||||
|
||||
if (_isKHTML)
|
||||
b=b.toUpperCase();
|
||||
|
||||
for (var i = 0; i < a.length; i++)for (var j = 0; j < a[i].childNodes.length; j++){
|
||||
if (_isKHTML){
|
||||
if (a[i].childNodes[j].tagName&&a[i].childNodes[j].tagName.toUpperCase() == b)
|
||||
c[c.length]=a[i].childNodes[j];
|
||||
}
|
||||
|
||||
else if (a[i].childNodes[j].tagName == b)
|
||||
c[c.length]=a[i].childNodes[j];
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
function dhtmlXHeir(a, b){
|
||||
for (var c in b)
|
||||
if (typeof (b[c]) == "function")
|
||||
a[c]=b[c];
|
||||
return a;
|
||||
}
|
||||
|
||||
function dhtmlxEvent(el, event, handler){
|
||||
if (el.addEventListener)
|
||||
el.addEventListener(event, handler, false);
|
||||
|
||||
else if (el.attachEvent)
|
||||
el.attachEvent("on"+event, handler);
|
||||
}
|
||||
|
||||
//============= XSL Extension ===================================
|
||||
|
||||
dtmlXMLLoaderObject.prototype.xslDoc=null;
|
||||
dtmlXMLLoaderObject.prototype.setXSLParamValue=function(paramName, paramValue, xslDoc){
|
||||
if (!xslDoc)
|
||||
xslDoc=this.xslDoc
|
||||
|
||||
if (xslDoc.responseXML)
|
||||
xslDoc=xslDoc.responseXML;
|
||||
var item =
|
||||
this.doXPath("/xsl:stylesheet/xsl:variable[@name='"+paramName+"']", xslDoc,
|
||||
"http:/\/www.w3.org/1999/XSL/Transform", "single");
|
||||
|
||||
if (item != null)
|
||||
item.firstChild.nodeValue=paramValue
|
||||
}
|
||||
dtmlXMLLoaderObject.prototype.doXSLTransToObject=function(xslDoc, xmlDoc){
|
||||
if (!xslDoc)
|
||||
xslDoc=this.xslDoc;
|
||||
|
||||
if (xslDoc.responseXML)
|
||||
xslDoc=xslDoc.responseXML
|
||||
|
||||
if (!xmlDoc)
|
||||
xmlDoc=this.xmlDoc;
|
||||
|
||||
if (xmlDoc.responseXML)
|
||||
xmlDoc=xmlDoc.responseXML
|
||||
|
||||
//MOzilla
|
||||
if (!_isIE){
|
||||
if (!this.XSLProcessor){
|
||||
this.XSLProcessor=new XSLTProcessor();
|
||||
this.XSLProcessor.importStylesheet(xslDoc);
|
||||
}
|
||||
var result = this.XSLProcessor.transformToDocument(xmlDoc);
|
||||
} else {
|
||||
var result = new ActiveXObject("Msxml2.DOMDocument.3.0");
|
||||
try{
|
||||
xmlDoc.transformNodeToObject(xslDoc, result);
|
||||
}catch(e){
|
||||
result = xmlDoc.transformNode(xslDoc);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
dtmlXMLLoaderObject.prototype.doXSLTransToString=function(xslDoc, xmlDoc){
|
||||
var res = this.doXSLTransToObject(xslDoc, xmlDoc);
|
||||
if(typeof(res)=="string")
|
||||
return res;
|
||||
return this.doSerialization(res);
|
||||
}
|
||||
|
||||
dtmlXMLLoaderObject.prototype.doSerialization=function(xmlDoc){
|
||||
if (!xmlDoc)
|
||||
xmlDoc=this.xmlDoc;
|
||||
if (xmlDoc.responseXML)
|
||||
xmlDoc=xmlDoc.responseXML
|
||||
if (!_isIE){
|
||||
var xmlSerializer = new XMLSerializer();
|
||||
return xmlSerializer.serializeToString(xmlDoc);
|
||||
} else
|
||||
return xmlDoc.xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc:
|
||||
* @type: private
|
||||
*/
|
||||
dhtmlxEventable=function(obj){
|
||||
obj.attachEvent=function(name, catcher, callObj){
|
||||
name='ev_'+name.toLowerCase();
|
||||
if (!this[name])
|
||||
this[name]=new this.eventCatcher(callObj||this);
|
||||
|
||||
return(name+':'+this[name].addEvent(catcher)); //return ID (event name & event ID)
|
||||
}
|
||||
obj.callEvent=function(name, arg0){
|
||||
name='ev_'+name.toLowerCase();
|
||||
if (this[name])
|
||||
return this[name].apply(this, arg0);
|
||||
return true;
|
||||
}
|
||||
obj.checkEvent=function(name){
|
||||
return (!!this['ev_'+name.toLowerCase()])
|
||||
}
|
||||
obj.eventCatcher=function(obj){
|
||||
var dhx_catch = [];
|
||||
var z = function(){
|
||||
var res = true;
|
||||
for (var i = 0; i < dhx_catch.length; i++){
|
||||
if (dhx_catch[i] != null){
|
||||
var zr = dhx_catch[i].apply(obj, arguments);
|
||||
res=res&&zr;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
z.addEvent=function(ev){
|
||||
if (typeof (ev) != "function")
|
||||
ev=eval(ev);
|
||||
if (ev)
|
||||
return dhx_catch.push(ev)-1;
|
||||
return false;
|
||||
}
|
||||
z.removeEvent=function(id){
|
||||
dhx_catch[id]=null;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
obj.detachEvent=function(id){
|
||||
if (id != false){
|
||||
var list = id.split(':'); //get EventName and ID
|
||||
this[list[0]].removeEvent(list[1]); //remove event
|
||||
}
|
||||
}
|
||||
obj.detachAllEvents = function(){
|
||||
for (var name in this){
|
||||
if (name.indexOf("ev_")==0)
|
||||
delete this[name];
|
||||
}
|
||||
}
|
||||
}
|
2190
phpgwapi/js/egw_action/test/js/dhtmlxmenu.js
Normal file
18
phpgwapi/js/egw_action/test/js/dhtmlxmenu_ext.js
Normal file
360
phpgwapi/js/egw_action/test/skins/dhtmlxmenu_egw.css
Normal file
@ -0,0 +1,360 @@
|
||||
/*
|
||||
"DHX SKYBLUE" DHTMLXMENU SKIN 2009
|
||||
*/
|
||||
/****************************************************************************************************************************************************/
|
||||
/* TOPLEVEL */
|
||||
.dhtmlxMenu_egw_Middle {
|
||||
position: relative;
|
||||
height: 20px;
|
||||
border: none;
|
||||
background-image: url("../imgs/dhxmenu_topbg.gif");
|
||||
background-position: top;
|
||||
background-repeat: repeat-x;
|
||||
-moz-user-select: none;
|
||||
padding: 0px 7px;
|
||||
}
|
||||
.dhtmlx_winviewport.dhtmlx_skin_egw div.dhtmlxMenu_egw_Middle,
|
||||
.dhxlayout_fullscreened div.dhtmlxMenu_egw_Middle,
|
||||
.dhx_tabbar_zone.dhx_tabbar_zone_egw div.dhtmlxMenu_egw_Middle,
|
||||
.dhx_acc_base_egw div.dhtmlxMenu_egw_Middle,
|
||||
.dhtmlx_skin_egw div.dhtmlx_window_active div.dhtmlxMenu_egw_Middle,
|
||||
.dhtmlx_skin_egw div.dhtmlx_window_inactive div.dhtmlxMenu_egw_Middle,
|
||||
table.dhtmlxLayoutPolyContainer_egw td.dhtmlxLayoutSinglePoly div.dhtmlxMenu_egw_Middle {
|
||||
height: 29px !important;
|
||||
}
|
||||
|
||||
.dhtmlxMenu_egw_Middle.dir_left div.align_left {
|
||||
float: left;
|
||||
}
|
||||
.dhtmlxMenu_egw_Middle.dir_left div.align_right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
|
||||
/* menu in window, layout, accordion have bottom margin 9px */
|
||||
/*
|
||||
.dhtmlx_skin_egw div.dhtmlx_wins_body_inner div.dhtmlxMenu_egw_Middle,
|
||||
table.dhtmlxLayoutPolyContainer_egw td.dhtmlxLayoutSinglePoly div.dhtmlxMenu_egw_Middle {
|
||||
height: 27px !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.dhtmlxMenu_egw_Layout, .dhtmlxMenu_egw_Accordion {
|
||||
border-bottom: #cedce8 1px solid;
|
||||
}
|
||||
|
||||
.dhtmlxMenu_egw_Middle.in_acccell, .dhtmlxMenu_egw_Middle.in_layoutcell {
|
||||
height: 27px;
|
||||
background-image: url("../imgs/dhxmenu_egw/dhxmenu_bg_acccell.gif");
|
||||
background-position: top;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
*/
|
||||
|
||||
/****************************************************************************************************************************************************/
|
||||
/* TOPLEVEL ITEMS */
|
||||
/* toplevel item normal */
|
||||
div.dhtmlxMenu_egw_TopLevel_Item_Normal,
|
||||
div.dhtmlxMenu_egw_TopLevel_Item_Disabled,
|
||||
div.dhtmlxMenu_egw_TopLevel_Item_Selected {
|
||||
position: relative;
|
||||
float: left;
|
||||
font-family: Arial, Helvetica, Sans-Serif;
|
||||
font-size: 10pt;
|
||||
font-weight: normal;
|
||||
cursor: default;
|
||||
white-space: nowrap;
|
||||
-moz-user-select: none;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
vertical-align: middle;
|
||||
margin: 0px 2px 100px 0px;
|
||||
padding: 0px 5px;
|
||||
color: #000000;
|
||||
}
|
||||
div.dhtmlxMenu_egw_TopLevel_Item_Normal {
|
||||
border-left: #ececec 1px solid !important;
|
||||
border-right: #ececec 1px solid !important;
|
||||
/*
|
||||
background-image:url("../imgs/dhxmenu_egw/dhxmenu_topsepbg.gif");
|
||||
background-position:right center;
|
||||
background-repeat:no-repeat;
|
||||
*/
|
||||
}
|
||||
/* toplevel item disabled */
|
||||
div.dhtmlxMenu_egw_TopLevel_Item_Disabled {
|
||||
color: #999999 !important;
|
||||
}
|
||||
/* toplevel item selected (over) */
|
||||
div.dhtmlxMenu_egw_TopLevel_Item_Selected {
|
||||
background-image: url("../imgs/dhxmenu_topselbg.gif");
|
||||
background-repeat: repeat-x;
|
||||
border-left: #ffffff 1px solid !important;
|
||||
border-right: #ffffff 1px solid !important;
|
||||
}
|
||||
/* toplevel separator */
|
||||
.dhtmlxMenu_egw_Middle div.top_sep {
|
||||
font-size: 1px;
|
||||
cursor: default;
|
||||
-moz-user-select: none;
|
||||
background-image: url("../imgs/dhxmenu_topsepbg.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: top center;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 3px;
|
||||
margin-left: 0px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
/* top level image */
|
||||
.dhtmlxMenu_egw_Middle img.dhtmlxMenu_TopLevel_Item_Icon {
|
||||
float: left;
|
||||
margin: 2px 2px 0px 2px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
|
||||
/* top level text*/
|
||||
div.dhtmlxMenu_egw_TopLevel_Item_Normal div.top_level_text,
|
||||
div.dhtmlxMenu_egw_TopLevel_Item_Disabled div.top_level_text,
|
||||
div.dhtmlxMenu_egw_TopLevel_Item_Selected div.top_level_text {
|
||||
float: left;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
/****************************************************************************************************************************************************/
|
||||
/* SUBLEVEL POLYGON */
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon {
|
||||
position: absolute;
|
||||
background-color: #ececec;
|
||||
border: #aaaaaa 1px outset;
|
||||
overflow: hidden;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
box-shadow: 2px 3px 13px #666666;
|
||||
-moz-box-shadow: 2px 3px 13px #666666;
|
||||
-webkit-box-shadow: 2px 3px 13px #666666;
|
||||
-khtml-box-shadow: 2px 3px 13px #666666;
|
||||
filter:progid:DXImageTransform.Microsoft.Shadow(color=#999999,direction=135,strength=3);
|
||||
-moz-user-select: none;
|
||||
|
||||
}
|
||||
/* IE6 sublevel undercover fix */
|
||||
iframe.dhtmlxMenu_IE6CoverFix_egw {
|
||||
position: absolute;
|
||||
border: none;
|
||||
background: #000000;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
/****************************************************************************************************************************************************/
|
||||
/* SUBLEVEL ITEMS */
|
||||
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl {
|
||||
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item {
|
||||
height: 28px;
|
||||
cursor: default;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_dis {
|
||||
height: 28px;
|
||||
cursor: default;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_selected {
|
||||
height: 28px;
|
||||
cursor: default;
|
||||
background-image: url("../imgs/dhxmenu_subselbg.png");
|
||||
background-repeat: repeat-x;
|
||||
background-position: center;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl td.sub_item_icon {
|
||||
width: 24px;
|
||||
text-align: left;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl td.sub_item_icon img.sub_icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 6px 2px 2px 8px;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl td.sub_item_text {
|
||||
vertical-align: middle;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl div.sub_item_text {
|
||||
font-family: Arial, Helvetica, Sans-Serif;
|
||||
font-size: 10pt;
|
||||
font-weight: normal;
|
||||
color: #000000;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_dis div.sub_item_text {
|
||||
color: #999999 !important;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl td.sub_item_hk {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl td.sub_item_hk div.sub_item_hk {
|
||||
font-family: Arial, Helvetica, Sans-Serif;
|
||||
font-size: 10px;
|
||||
color: #a4bed4;
|
||||
text-align: right;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_selected td.sub_item_hk div.sub_item_hk {
|
||||
color: #999999;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_dis td.sub_item_hk div.sub_item_hk {
|
||||
color: #cecece !important;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon tr.sub_sep {
|
||||
height: 3px;
|
||||
font-size: 1px;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon div.sub_sep {
|
||||
font-size: 1px;
|
||||
border-top: 2px #eeeeee groove;
|
||||
cursor: default;
|
||||
height: 2px;
|
||||
}
|
||||
/****************************************************************************************************************************************************/
|
||||
/* SUBLEVEL ARROWS */
|
||||
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl div.complex_arrow {
|
||||
width: 7px;
|
||||
height: 24px;
|
||||
background-image: url("../imgs/dhxmenu_subar.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0px 0px;
|
||||
float: right;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_selected div.complex_arrow {
|
||||
background-position: -7px 0px !important;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_dis div.complex_arrow {
|
||||
background-position: -14px 0px !important;
|
||||
}
|
||||
/****************************************************************************************************************************************************/
|
||||
/* LOADING ICON */
|
||||
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl div.complex_arrow_loading {
|
||||
width: 7px;
|
||||
height: 24px;
|
||||
background-image: url("../imgs/dhxmenu_loader.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
float: right;
|
||||
}
|
||||
/****************************************************************************************************************************************************/
|
||||
/* UP/DOWN OVERFLOW ARROWS */
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Arrow {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Arrow div.dhtmlxMenu_SubLevelArea_Arrow_Icon {
|
||||
position: relative;
|
||||
margin-top: 6px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 29px;
|
||||
height: 8px;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("../imgs/dhxmenu_upar.gif");
|
||||
}
|
||||
/* up arrows */
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowUp,
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowUp_Over,
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowUp_Disabled {
|
||||
position: absolute;
|
||||
height: 20px;
|
||||
font-size: 1px;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowUp div.dhtmlxMenu_SubLevelArea_Arrow_Icon { background-position: -87px 0px; }
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowUp_Over div.dhtmlxMenu_SubLevelArea_Arrow_Icon { background-position: -116px 0px; }
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowUp_Disabled div.dhtmlxMenu_SubLevelArea_Arrow_Icon { background-position: -145px 0px; }
|
||||
/* down arrows */
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowDown,
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowDown_Over,
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowDown_Disabled {
|
||||
position: absolute;
|
||||
height: 20px;
|
||||
font-size: 1px;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowDown div.dhtmlxMenu_SubLevelArea_Arrow_Icon { background-position: 0px 0px; }
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowDown_Over div.dhtmlxMenu_SubLevelArea_Arrow_Icon { background-position: -29px 0px; }
|
||||
div.dhtmlxMenu_egw_SubLevelArea_ArrowDown_Disabled div.dhtmlxMenu_SubLevelArea_Arrow_Icon { background-position: -58px 0px; }
|
||||
/****************************************************************************************************************************************************/
|
||||
/* TOPLEVEL TEXT */
|
||||
.dhtmlxMenu_egw_Middle div.dhtmlxMenu_TopLevel_Text_right {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
vertical-align: middle;
|
||||
left: none;
|
||||
right: 8px;
|
||||
font-family: Arial, Helvetica, Sans-Serif;
|
||||
font-size: 10pt;
|
||||
color: #000000;
|
||||
cursor: default;
|
||||
}
|
||||
.dhtmlxMenu_egw_Middle div.dhtmlxMenu_TopLevel_Text_left {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
vertical-align: middle;
|
||||
right: none;
|
||||
left: 8px;
|
||||
font-family: Arial, Helvetica, Sans-Serif;
|
||||
font-size: 10pt;
|
||||
color: #000000;
|
||||
cursor: default;
|
||||
}
|
||||
/****************************************************************************************************************************************************/
|
||||
/* ITEM'S CHECKS, RADIOS */
|
||||
/* sublevel */
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl div.sub_icon {
|
||||
float: left;
|
||||
margin: 2px 4px 2px 8px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: top right;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("../imgs/dhxmenu_chrd.gif");
|
||||
}
|
||||
/* checkboxes */
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl div.sub_icon.chbx_0 {
|
||||
background-position: 0px 0px !important;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl div.sub_icon.chbx_1 {
|
||||
background-position: -18px 0px !important;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_dis div.sub_icon.chbx_0 {
|
||||
background-position: -36px 0px !important;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_dis div.sub_icon.chbx_1 {
|
||||
background-position: -54px 0px !important;
|
||||
}
|
||||
/* radios */
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl div.sub_icon.rdbt_0 {
|
||||
background-position: -72px 0px !important;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl div.sub_icon.rdbt_1 {
|
||||
background-position: -90px 0px !important;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_dis div.sub_icon.rdbt_0 {
|
||||
background-position: -108px 0px !important;
|
||||
}
|
||||
div.dhtmlxMenu_egw_SubLevelArea_Polygon table.dhtmlxMebu_SubLevelArea_Tbl tr.sub_item_dis div.sub_icon.rdbt_1 {
|
||||
background-position: -126px 0px !important;
|
||||
}
|
187
phpgwapi/js/egw_action/test/test_menu.html
Normal file
@ -0,0 +1,187 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Test page for the egw menu</title>
|
||||
<link rel="stylesheet" type="text/css" href="skins/dhtmlxmenu_egw.css">
|
||||
<script src="js/dhtmlxcommon.js"></script>
|
||||
<script src="js/dhtmlxmenu.js"></script>
|
||||
<script src="js/dhtmlxmenu_ext.js"></script>
|
||||
<script src="../egw_menu.js"></script>
|
||||
<script src="../egw_menu_dhtmlx.js"></script>
|
||||
</head>
|
||||
<body style="width:95%; height:95%; font-family: sans-serif">
|
||||
<script>
|
||||
|
||||
var menu = new egwMenu();
|
||||
|
||||
menu.loadStructure(
|
||||
[
|
||||
{
|
||||
"id": "file_menu",
|
||||
"caption": "Test1",
|
||||
"children": [
|
||||
{
|
||||
"id": "file_open",
|
||||
"caption": "Open file...",
|
||||
"iconUrl": "imgs/folder.png",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"caption": "-"
|
||||
},
|
||||
{
|
||||
"id": "file_save",
|
||||
"caption": "Save",
|
||||
"enabled": false,
|
||||
"iconUrl": "imgs/disk.png"
|
||||
},
|
||||
{
|
||||
"id": "file_save_as",
|
||||
"caption": "Save as..."
|
||||
},
|
||||
{
|
||||
"caption": "-"
|
||||
},
|
||||
{
|
||||
"caption": "Recently loaded",
|
||||
"children": [
|
||||
{
|
||||
"id": "rec1",
|
||||
"caption": "file1.txt",
|
||||
"iconUrl": "imgs/page.png",
|
||||
},
|
||||
{
|
||||
"id": "rec2",
|
||||
"caption": "file2.txt",
|
||||
"iconUrl": "imgs/page.png",
|
||||
},
|
||||
{
|
||||
"id": "rec3",
|
||||
"caption": "file3.txt",
|
||||
"iconUrl": "imgs/page.png",
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"caption": "Test2",
|
||||
"children": [
|
||||
{
|
||||
"caption": "Use speed enhancer",
|
||||
"checkbox": true,
|
||||
"groupIndex": 0,
|
||||
"checked": true
|
||||
},
|
||||
{
|
||||
"caption": "Reduce memory impact",
|
||||
"checkbox": true,
|
||||
"groupIndex": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"caption": "Test3",
|
||||
"children": [
|
||||
{
|
||||
"caption": "Option1.1",
|
||||
"checkbox": true,
|
||||
"groupIndex": 1,
|
||||
"checked": true
|
||||
},
|
||||
{
|
||||
"caption": "Option1.2",
|
||||
"checkbox": true,
|
||||
"groupIndex": 1
|
||||
},
|
||||
{
|
||||
"caption": "Option1.3",
|
||||
"checkbox": true,
|
||||
"groupIndex": 1
|
||||
},
|
||||
{
|
||||
"caption": "-"
|
||||
},
|
||||
{
|
||||
"caption": "Option2.1",
|
||||
"checkbox": true,
|
||||
"groupIndex": 2
|
||||
},
|
||||
{
|
||||
"caption": "Option2.2",
|
||||
"checkbox": true,
|
||||
"groupIndex": 2,
|
||||
"checked": true
|
||||
},
|
||||
{
|
||||
"caption": "Option2.3",
|
||||
"checkbox": true,
|
||||
"groupIndex": 2
|
||||
},
|
||||
{
|
||||
"caption": "-"
|
||||
},
|
||||
{
|
||||
"caption": "Extra options",
|
||||
"iconUrl": "imgs/wrench.png",
|
||||
"children": [
|
||||
{
|
||||
"caption": "Option1.1",
|
||||
"checkbox": true,
|
||||
"groupIndex": 1
|
||||
},
|
||||
{
|
||||
"caption": "Option1.2",
|
||||
"checkbox": true,
|
||||
"groupIndex": 1
|
||||
},
|
||||
{
|
||||
"caption": "Option1.3",
|
||||
"checkbox": true,
|
||||
"groupIndex": 1,
|
||||
"checked": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
menu.setGlobalOnClick(alertCaption);
|
||||
|
||||
function alertCaption(elem)
|
||||
{
|
||||
if (console && console.log)
|
||||
console.log(elem);
|
||||
}
|
||||
|
||||
function getPageXY(event)
|
||||
{
|
||||
// document.body.scrollTop does not work in IE
|
||||
var scrollTop = document.body.scrollTop ? document.body.scrollTop :
|
||||
document.documentElement.scrollTop;
|
||||
var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft :
|
||||
document.documentElement.scrollLeft;
|
||||
|
||||
// hide the menu first to avoid an "up-then-over" visual effect
|
||||
return {'x': (event.clientX + scrollLeft), 'y': (event.clientY + scrollTop)};
|
||||
}
|
||||
|
||||
document.body.oncontextmenu = function(e)
|
||||
{
|
||||
if (!e)
|
||||
e = window.event;
|
||||
|
||||
var pos = getPageXY(e);
|
||||
show_menu(pos.x, pos.y);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function show_menu(_x, _y)
|
||||
{
|
||||
menu.showAt(_x, _y);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|