api/js/dhtmlxMenu/sources/dhtmlxmenu.js   F
last analyzed

Complexity

Total Complexity 529
Complexity/F 5.63

Size

Lines of Code 2209
Function Count 94

Duplication

Duplicated Lines 1463
Ratio 66.23 %

Importance

Changes 0
Metric Value
eloc 1407
dl 1463
loc 2209
rs 0.8
c 0
b 0
f 0
wmc 529
mnd 435
bc 435
fnc 94
bpm 4.6276
cpm 5.6276
noi 11

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like api/js/dhtmlxMenu/sources/dhtmlxmenu.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
//v.3.6 build 131108
0 ignored issues
show
Coding Style introduced by
File has mixed line endings; this may cause incorrect results
Loading history...
2
3
/*
4
Copyright DHTMLX LTD. http://www.dhtmlx.com
5
You allowed to use this component or parts of it under GPL terms
6
To use it on other terms or get Professional edition of the component please contact us at [email protected]
7
*/
8
/**
9
*   @desc: a constructor, creates a new dhtmlxMenu object, baseId defines a base object for the top menu level
10
*   @param: baseId - id of the html element to which a menu will be attached, in case of a contextual menu - if specified, will used as a contextual zone
11
*   @type: public
12
*/
13
function dhtmlXMenuObject(baseId, skin) {
14
	var main_self = this;
15
	
16
	this.addBaseIdAsContextZone = null;
17
	
18
	this.isDhtmlxMenuObject = true;
19
	
20
	// skin settings
21
	this.skin = (skin != null ? skin : (typeof(dhtmlx) != "undefined" && typeof(dhtmlx.skin) == "string" ? dhtmlx.skin : "dhx_skyblue"));
22
	this.imagePath = "";
23
	
24
	// iframe
25
	this._isIE6 = false;
26
	if (_isIE) this._isIE6 = (window.XMLHttpRequest==null?true:false);
27
	
28
	if (baseId == null) {
29
		this.base = document.body;
30
	} else {
31
		var baseObj = (typeof(baseId)=="string"?document.getElementById(baseId):baseId);
32
		if (baseObj != null) {
33
			this.base = baseObj;
34
			if (!this.base.id) this.base.id = (new Date()).valueOf();
35
			while (this.base.childNodes.length > 0) { this.base.removeChild(this.base.childNodes[0]); }
36
			this.base.className += " dhtmlxMenu_"+this.skin+"_Middle dir_left";
37
			this.base._autoSkinUpdate = true;
38
			 // preserv default oncontextmenu for future restorin in case of context menu
39
			if (this.base.oncontextmenu) this.base._oldContextMenuHandler = this.base.oncontextmenu;
40
			//
41
			this.addBaseIdAsContextZone = this.base.id;
42
			this.base.onselectstart = function(e) { e = e || event; e.returnValue = false; return false; }
43
			this.base.oncontextmenu = function(e) { e = e || event; e.returnValue = false; return false; }
44
		} else {
45
			this.base = document.body;
46
		}
47
	}
48
	// this.topId = topId;
49
	this.topId = "dhxWebMenuTopId";
50
	
51
	// 
52
	if (!this.extendedModule) {
53
		// add notify for menu
54
		var t = function(){alert(this.i18n.dhxmenuextalert);};
0 ignored issues
show
Debugging Code Best Practice introduced by
The alert UI element is often considered obtrusive and is generally only used as a temporary measure. Consider replacing it with another UI element.
Loading history...
55
		var extMethods = new Array("setItemEnabled", "setItemDisabled", "isItemEnabled", "_changeItemState", "getItemText", "setItemText",
56
				"loadFromHTML", "hideItem", "showItem", "isItemHidden", "_changeItemVisible", "setUserData", "getUserData",
57
				"setOpenMode", "setWebModeTimeout", "enableDynamicLoading", "_updateLoaderIcon", "getItemImage", "setItemImage",
58
				"clearItemImage", "setAutoShowMode", "setAutoHideMode", "setContextMenuHideAllMode", "getContextMenuHideAllMode",
59
				"setVisibleArea", "setTooltip", "getTooltip", "setHotKey", "getHotKey", "setItemSelected", "setTopText", "setRTL",
60
				"setAlign", "setHref", "clearHref", "getCircuit", "_clearAllSelectedSubItemsInPolygon", "_checkArrowsState",
61
				"_addUpArrow", "_addDownArrow", "_removeUpArrow", "_removeDownArrow", "_isArrowExists", "_doScrollUp", "_doScrollDown",
62
				"_countPolygonItems", "setOverflowHeight", "_getRadioImgObj", "_setRadioState", "_radioOnClickHandler",
63
				"getRadioChecked", "setRadioChecked", "addRadioButton", "_getCheckboxState", "_setCheckboxState", "_readLevel",
64
				"_updateCheckboxImage", "_checkboxOnClickHandler", "setCheckboxState", "getCheckboxState", "addCheckbox", "serialize");
65
		for (var q=0; q<extMethods.length; q++) if (!this[extMethods[q]]) this[extMethods[q]] = t;
66
		extMethods = null;
67
	}
68
	
69
	// should be used for frameset in IE
70
	this.fixedPosition = false;
71
	
72
	this.menuSelected = -1;
73
	this.menuLastClicked = -1;
74
	this.idPrefix = "";
75
	this.itemTagName = "item";
76
	this.itemTextTagName = "itemtext";
77
	this.userDataTagName = "userdata";
78
	this.itemTipTagName = "tooltip";
79
	this.itemHotKeyTagName = "hotkey";
80
	this.itemHrefTagName = "href";
81
	this.dirTopLevel = "bottom";
82
	this.dirSubLevel = "right";
83
	this.menuX1 = null;
84
	this.menuX2 = null;
85
	this.menuY1 = null;
86
	this.menuY2 = null;
87
	this.menuMode = "web";
88
	this.menuTimeoutMsec = 400;
89
	this.menuTimeoutHandler = null;
90
	this.autoOverflow = false;
91
	this.idPull = {};
92
	this.itemPull = {};
93
	this.userData = {};
94
	this.radio = {};
95
	//
96
	this._rtl = false;
97
	this._align = "left";
98
	//
99
	this.menuTouched = false;
100
	//
101
	this.zIndInit = 1200;
102
	this.zInd = this.zIndInit;
103
	this.zIndStep = 50;
104
	//
105
	this.menuModeTopLevelTimeout = true; // shows sublevel polygons from toplevel items with delay
106
	this.menuModeTopLevelTimeoutTime = 200; // msec
107
	//
108
	// default skin
109
	// this.skin = "Standard";
110
	
111
	// skin-based params
112
	this._topLevelBottomMargin = 1;
113
	this._topLevelRightMargin = 0;
114
	this._topLevelOffsetLeft = 1;
115
	this._arrowFFFix = (_isIE?(document.compatMode=="BackCompat"?0:-4):-4); // border fixer for FF for arrows polygons
116
	
117
	/**
118
	*   @desc: changes menu skin
119
	*   @param: skin - skin name
120
	*   @type: public
121
	*/
122 View Code Duplication
	this.setSkin = function(skin) {
123
		var oldSkin = this.skin;
124
		this.skin = skin;
125
		switch (this.skin){
126
			case "dhx_black":
127
			case "dhx_blue":
128
			case "dhx_skyblue":
129
			case "dhx_web":
130
				this._topLevelBottomMargin = 2;
131
				this._topLevelRightMargin = 1;
132
				this._topLevelOffsetLeft = 1;
133
				this._arrowFFFix = (_isIE?(document.compatMode=="BackCompat"?0:-4):-4);
134
				break;
135
			case "dhx_web":
0 ignored issues
show
Bug introduced by
The test: "dhx_web" is already covered by the case statement in line 129. This statement will not be executed.
Loading history...
136
				this._arrowFFFix = 0;
137
				break;
138
			case "dhx_terrace":
139
				this._topLevelBottomMargin = 0;
140
				this._topLevelRightMargin = 0;
141
				this._topLevelOffsetLeft = 0;
142
				this._arrowFFFix = (_isIE?(document.compatMode=="BackCompat"?0:-4):-4);
143
				break;
144
		}
145
		if (this.base._autoSkinUpdate) {
146
			this.base.className = this.base.className.replace("dhtmlxMenu_"+oldSkin+"_Middle", "")+" dhtmlxMenu_"+this.skin+"_Middle";
147
		}
148
		
149
		for (var a in this.idPull) {
150
			this.idPull[a].className = String(this.idPull[a].className).replace(oldSkin, this.skin);
151
			
152
		}
153
	}
154
	this.setSkin(this.skin);
155
	//
156
	this.dLoad = false;
157
	this.dLoadUrl = "";
158
	this.dLoadSign = "?";
159
	this.loaderIcon = false;
160
	this.limit = 0;
161
	//
162
	this._scrollUpTM = null;
163
	this._scrollUpTMTime = 20;
164
	this._scrollUpTMStep = 3;
165
	this._scrollDownTM = null;
166
	this._scrollDownTMTime = 20;
167
	this._scrollDownTMStep = 3;
168
	/* context menu */
169
	this.context = false;
170
	this.contextZones = {};
171
	this.contextMenuZoneId = false;
172
	this.contextAutoShow = true;	/* default open action */
173
	this.contextAutoHide = true;	/* default close action */
174
	this.contextHideAllMode = true; /* true will hide all opened contextual menu polygons on mouseout, false - all except topleft */
175
	
176
	this._selectedSubItems = new Array();
177
	this._openedPolygons = new Array();
178
	this._addSubItemToSelected = function(item, polygon) {
179
		var t = true;
180
		for (var q=0; q<this._selectedSubItems.length; q++) { if ((this._selectedSubItems[q][0] == item) && (this._selectedSubItems[q][1] == polygon)) { t = false; } }
181
		if (t == true) { this._selectedSubItems.push(new Array(item, polygon)); }
182
		return t;
183
	}
184 View Code Duplication
	this._removeSubItemFromSelected = function(item, polygon) {
185
		var m = new Array();
186
		var t = false;
187
		for (var q=0; q<this._selectedSubItems.length; q++) { if ((this._selectedSubItems[q][0] == item) && (this._selectedSubItems[q][1] == polygon)) { t = true; } else { m[m.length] = this._selectedSubItems[q]; } }
188
		if (t == true) { this._selectedSubItems = m; }
189
		return t;
190
	}
191 View Code Duplication
	this._getSubItemToDeselectByPolygon = function(polygon) {
192
		var m = new Array();
193
		for (var q=0; q<this._selectedSubItems.length; q++) {
194
			if (this._selectedSubItems[q][1] == polygon) {
195
				m[m.length] = this._selectedSubItems[q][0];
196
				m = m.concat(this._getSubItemToDeselectByPolygon(this._selectedSubItems[q][0]));
197
				var t = true;
198
				for (var w=0; w<this._openedPolygons.length; w++) { if (this._openedPolygons[w] == this._selectedSubItems[q][0]) { t = false; } }
199
				if (t == true) { this._openedPolygons[this._openedPolygons.length] = this._selectedSubItems[q][0]; }
200
				this._selectedSubItems[q][0] = -1;
201
				this._selectedSubItems[q][1] = -1;
202
			}
203
		}
204
		return m;
205
	}
206
	/* end */
207
	/* define polygon's position for dinamic content rendering and shows it, added in version 0.3 */
208 View Code Duplication
	this._hidePolygon = function(id) {
209
		if (this.idPull["polygon_" + id] != null) {
210
			if (typeof(this._menuEffect) != "undefined" && this._menuEffect !== false) {
211
				this._hidePolygonEffect("polygon_"+id);
212
			} else {
213
				// already hidden
214
				if (this.idPull["polygon_"+id].style.display == "none") return;
215
				//
216
				this.idPull["polygon_"+id].style.display = "none";
217
				if (this.idPull["arrowup_"+id] != null) { this.idPull["arrowup_"+id].style.display = "none"; }
218
				if (this.idPull["arrowdown_"+id] != null) { this.idPull["arrowdown_"+id].style.display = "none"; }
219
				this._updateItemComplexState(id, true, false);
220
				// hide ie6 cover
221
				if (this._isIE6) { if (this.idPull["polygon_"+id+"_ie6cover"] != null) { this.idPull["polygon_"+id+"_ie6cover"].style.display = "none"; } }
222
			}
223
			// call event
224
			id = String(id).replace(this.idPrefix, "");
225
			if (id == this.topId) id = null;
226
			this.callEvent("onHide", [id]);
227
			
228
			// corners
229
			if (id != null && this.skin == "dhx_terrace" && this.itemPull[this.idPrefix+id].parent == this.idPrefix+this.topId) {
230
				this._improveTerraceButton(this.idPrefix+id, true);
231
			}
232
			
233
			
234
		}
235
	}
236
	this._showPolygon = function(id, openType) {
237
		
238
		var itemCount = this._countVisiblePolygonItems(id);
239
		if (itemCount == 0) return;
240
		var pId = "polygon_"+id;
241
		if ((this.idPull[pId] != null) && (this.idPull[id] != null)) {
242
		
243
			if (this.menuModeTopLevelTimeout && this.menuMode == "web" && !this.context) {
244
				if (!this.idPull[id]._mouseOver && openType == this.dirTopLevel) return;
245
			}
246
			
247
			// detect visible area
248
			if (!this.fixedPosition) this._autoDetectVisibleArea();
249
			
250
			// show arrows
251
			var arrUpH = 0;
252
			var arrDownH = 0;
253
			//
254
			var arrowUp = null;
255
			var arrowDown = null;
256
			
257
			// show polygon
258
			this.idPull[pId].style.visibility = "hidden";
259
			this.idPull[pId].style.left = "0px";
260
			this.idPull[pId].style.top = "0px";
261
			this.idPull[pId].style.display = "";
262
			this.idPull[pId].style.zIndex = this.zInd;
263
			
264
			//
265 View Code Duplication
			if (this.autoOverflow) {
266
				if (this.idPull[pId].firstChild.offsetHeight > this.menuY1+this.menuY2) {
267
					var t0 = Math.floor((this.menuY2-this.menuY1-35)/24);
268
					this.limit = t0;
269
				} else {
270
					this.limit = 0;
271
					
272
					if (this.idPull["arrowup_"+id] != null) this._removeUpArrow(String(id).replace(this.idPrefix,""));
273
					if (this.idPull["arrowdown_"+id] != null) this._removeDownArrow(String(id).replace(this.idPrefix,""));
274
				}
275
			}
276
			
277
			//#menu_overflow:06062008#{
278 View Code Duplication
			if (this.limit > 0 && this.limit < itemCount)  {
279
				
280
				// add overflow arrows if they not exists
281
				if (this.idPull["arrowup_"+id] == null) this._addUpArrow(String(id).replace(this.idPrefix,""));
282
				if (this.idPull["arrowdown_"+id] == null) this._addDownArrow(String(id).replace(this.idPrefix,""));
283
				
284
				// configure up arrow
285
				arrowUp = this.idPull["arrowup_"+id];
286
				arrowUp.style.visibility = "hidden";
287
				arrowUp.style.display = "";
288
				arrowUp.style.zIndex = this.zInd;
289
				arrUpH = arrowUp.offsetHeight;
290
				
291
				// configure bottom arrow
292
				arrowDown = this.idPull["arrowdown_"+id];
293
				arrowDown.style.visibility = "hidden";
294
				arrowDown.style.display = "";
295
				arrowDown.style.zIndex = this.zInd;
296
				arrDownH = arrowDown.offsetHeight;
297
			}
298
			//#}
299
			
300
			if (this.limit > 0) {
301
				if (this.limit < itemCount)  {
302
					// set fixed size
303
					// this.idPull[pId].style.height = this.idPull[pId].tbd.childNodes[0].offsetHeight*this.limit+"px";// + arrUpH + arrDownH;
304
					this.idPull[pId].style.height = 24*this.limit+"px";
305
					this.idPull[pId].scrollTop = 0;
306
				} else {
307
					// remove fixed size
308
					this.idPull[pId].style.height = "";
309
				}
310
			}
311
			//
312
			this.zInd += this.zIndStep;
313
			//
314
			// console.log(this.idPull)
315
			if (this.itemPull[id] != null) {
316
				var parPoly = "polygon_"+this.itemPull[id]["parent"];
317
			} else if (this.context) {
318
				var parPoly = this.idPull[this.idPrefix+this.topId];
319
			}
320
			/*
321
			// debug info
322
			if (parPoly == null) {
323
				alert("Implementation error. Please report [email protected]");
324
			}
325
			*/
326
			//
327
			//
328
			// define position
329
			var srcX = (this.idPull[id].tagName != null ? getAbsoluteLeft(this.idPull[id]) : this.idPull[id][0]);
330
			var srcY = (this.idPull[id].tagName != null ? getAbsoluteTop(this.idPull[id]) : this.idPull[id][1]);
331
			var srcW = (this.idPull[id].tagName != null ? this.idPull[id].offsetWidth : 0);
332
			var srcH = (this.idPull[id].tagName != null ? this.idPull[id].offsetHeight : 0);
333
			
334
			var x = 0;
335
			var y = 0;
336
			var w = this.idPull[pId].offsetWidth;
337
			var h = this.idPull[pId].offsetHeight + arrUpH + arrDownH;
338
			
339
			//console.log(srcY,h,window.innerHeight,document.body.scrollTop)
340
			/*
341
			var bottomOverflow = (srcY+h > window.innerHeight+document.body.scrollTop);
342
			if (bottomOverflow) {
343
				if (openType == "bottom") openType = "top";
344
				if (openType == "right" || openType == "left") {
345
					srcY = srcY-h;
346
				}
347
			}
348
			*/
349
			// pos
350 View Code Duplication
			if (openType == "bottom") {
351
				if (this._rtl) {
352
					x = srcX + (srcW!=null?srcW:0) - w;
353
				} else {
354
					if (this._align == "right") {
355
						x = srcX + srcW - w;
356
					} else {
357
						x = srcX - 1 + (openType==this.dirTopLevel?this._topLevelRightMargin:0);
358
					}
359
				}
360
				y = srcY - 1 + srcH + this._topLevelBottomMargin;
361
			}
362
			if (openType == "right") { x = srcX + srcW - 1; y = srcY + 2; }
363
			if (openType == "left") { x = srcX - this.idPull[pId].offsetWidth + 2; y = srcY + 2; }
364
			if (openType == "top") { x = srcX - 1; y = srcY - h + 2; }
365
			
366
			// overflow check
367 View Code Duplication
			if (this.fixedPosition) {
368
				// use fixed document.body/window dimension if required
369
				var mx = 65536;
370
				var my = 65536;
371
			} else {
372
				var mx = (this.menuX2!=null?this.menuX2:0);
373
				var my = (this.menuY2!=null?this.menuY2:0);
374
				
375
				if (mx == 0) {
376
					if (window.innerWidth) {
377
						mx = window.innerWidth;
378
						my = window.innerHeight;
379
					} else {
380
						mx = document.body.offsetWidth;
381
						my = document.body.scrollHeight;
382
					}
383
				}
384
			}
385
			if (x+w > mx && !this._rtl) {
386
				// no space on right, open to left
387
				x = srcX - w + 2;
388
			}
389
			if (x < this.menuX1 && this._rtl) {
390
				// no space on left, open to right
391
				x = srcX + srcW - 2;
392
			}
393
			if (x < 0) {
394
				// menu floats left
395
				x = 0;
396
			}
397
			if (y+h > my && this.menuY2 != null) {
398
				y = Math.max(srcY + srcH - h + 2, (this._isVisibleArea?this.menuY1+2:2));
399
				// open from top level
400
				if (this.context && this.idPrefix+this.topId == id && arrowDown != null) {
401
					// autoscroll prevent because menu mouse pointer will right over downarrow
402
					y = y-2;
403
				}
404
				if (this.itemPull[id] != null && !this.context) {
405
					if (this.itemPull[id]["parent"] == this.idPrefix+this.topId) y = y - this.base.offsetHeight;
406
				}
407
			}
408
			//
409
			this.idPull[pId].style.left = x+"px";
410
			this.idPull[pId].style.top = y+arrUpH+"px";
411
			//
412
			if (typeof(this._menuEffect) != "undefined" && this._menuEffect !== false) {
413
				this._showPolygonEffect(pId);
414
			} else {
415
				this.idPull[pId].style.visibility = "";
416
				//#menu_overflow:06062008#{
417 View Code Duplication
				if (this.limit > 0 && this.limit < itemCount)  {
418
					// this.idPull[pId].scrollTop = 0;
419
					arrowUp.style.left = x+"px";
420
					arrowUp.style.top = y+"px";
421
					arrowUp.style.width = w+this._arrowFFFix+"px";
422
					arrowUp.style.visibility = "";
423
					//
424
					arrowDown.style.left = x+"px";
425
					arrowDown.style.top = y+h-arrDownH+"px";
426
					arrowDown.style.width = w+this._arrowFFFix+"px";
427
					arrowDown.style.visibility = "";
428
					//
429
					this._checkArrowsState(id);
430
				}
431
				//#}
432
				// show ie6 cover
433
				if (this._isIE6) {
434
					var pIdIE6 = pId+"_ie6cover";
435
					if (this.idPull[pIdIE6] == null) {
436
						var ifr = document.createElement("IFRAME");
437
						ifr.className = "dhtmlxMenu_IE6CoverFix_"+this.skin;
438
						ifr.frameBorder = 0;
439
						ifr.setAttribute("src", "javascript:false;");
440
						document.body.insertBefore(ifr, document.body.firstChild);
441
						this.idPull[pIdIE6] = ifr;
442
					}
443
					this.idPull[pIdIE6].style.left = x+"px";
444
					this.idPull[pIdIE6].style.top = y+"px";
445
					this.idPull[pIdIE6].style.width = w+"px";
446
					this.idPull[pIdIE6].style.height = h+"px";
447
					this.idPull[pIdIE6].style.zIndex = this.idPull[pId].style.zIndex-1;
448
					this.idPull[pIdIE6].style.display = "";
449
				}
450
			}
451
			
452
			id = String(id).replace(this.idPrefix, "");
453
			if (id == this.topId) id = null;
454
			this.callEvent("onShow", [id]);
455
			
456
			// corners
457
			if (id != null && this.skin == "dhx_terrace" && this.itemPull[this.idPrefix+id].parent == this.idPrefix+this.topId) {
458
				this._improveTerraceButton(this.idPrefix+id, false);
459
			}
460
			// this.callEvent("_onPolyShow",[id.replace(this.idPrefix,"")]);
461
			
462
		}
463
	}
464
	/* redistrib sublevel selection: select id and deselect other, added in version 0.3 */
465 View Code Duplication
	this._redistribSubLevelSelection = function(id, parentId) {
466
		// clear previosly selected items
467
		while (this._openedPolygons.length > 0) this._openedPolygons.pop();
468
		// this._openedPolygons = new Array();
469
		var i = this._getSubItemToDeselectByPolygon(parentId);
470
		this._removeSubItemFromSelected(-1, -1);
471
		for (var q=0; q<i.length; q++) { if ((this.idPull[i[q]] != null) && (i[q] != id)) { if (this.itemPull[i[q]]["state"] == "enabled") { this.idPull[i[q]].className = "sub_item"; } } }
472
		// hide polygons
473
		for (var q=0; q<this._openedPolygons.length; q++) { if (this._openedPolygons[q] != parentId) { this._hidePolygon(this._openedPolygons[q]); } }
474
		// add new selection into list new
475
		if (this.itemPull[id]["state"] == "enabled") {
476
			this.idPull[id].className = "sub_item_selected";
477
			if (this.itemPull[id]["complex"] && this.dLoad && (this.itemPull[id]["loaded"]=="no")) {
478
				if (this.loaderIcon == true) { this._updateLoaderIcon(id, true); }
479
				var xmlLoader = new dtmlXMLLoaderObject(this._xmlParser, window);
480
				this.itemPull[id]["loaded"] = "get";
481
				this.callEvent("onXLS", []);
482
				xmlLoader.loadXML(this.dLoadUrl+this.dLoadSign+"action=loadMenu&parentId="+id.replace(this.idPrefix,"")+"&etc="+new Date().getTime());
483
			}
484
			// show
485
			if (this.itemPull[id]["complex"] || (this.dLoad && (this.itemPull[id]["loaded"] == "yes"))) {
486
				// make arrow over
487
				if ((this.itemPull[id]["complex"]) && (this.idPull["polygon_" + id] != null))  {
488
					this._updateItemComplexState(id, true, true);
489
					this._showPolygon(id, this.dirSubLevel);
490
				}
491
			}
492
			this._addSubItemToSelected(id, parentId);
493
			this.menuSelected = id;
494
		}
495
	}
496
	/* onClickMenu action (click on any end item to perform some actions)
497
	   optimized in version 0.3 added type feature (click on disabled items, click on complex nodes)
498
	   attachEvent feature from 0.4 */
499 View Code Duplication
	this._doOnClick = function(id, type, casState) {
500
		this.menuLastClicked = id;
501
		// href
502
		if (this.itemPull[this.idPrefix+id]["href_link"] != null && this.itemPull[this.idPrefix+id].state == "enabled") {
503
			var form = document.createElement("FORM");
504
			var k = String(this.itemPull[this.idPrefix+id]["href_link"]).split("?");
505
			form.action = k[0];
506
			if (k[1] != null) {
507
				var p = String(k[1]).split("&");
508
				for (var q=0; q<p.length; q++) {
509
					var j = String(p[q]).split("=");
510
					var m = document.createElement("INPUT");
511
					m.type = "hidden";
512
					m.name = (j[0]||"");
513
					m.value = (j[1]||"");
514
					form.appendChild(m);
515
				}
516
			}
517
			if (this.itemPull[this.idPrefix+id]["href_target"] != null) { form.target = this.itemPull[this.idPrefix+id]["href_target"]; }
518
			form.style.display = "none";
519
			document.body.appendChild(form);
520
			form.submit();
521
			if (form != null) {
522
				document.body.removeChild(form);
523
				form = null;
524
			}
525
			return;
526
		}
527
		//
528
		// some fixes
529
		if (type.charAt(0)=="c") return; // can't click on complex item
530
		if (type.charAt(1)=="d") return; // can't click on disabled item
531
		if (type.charAt(2)=="s") return; // can't click on separator
532
		//
533
		if (this.checkEvent("onClick")) {
534
			// this.callEvent("onClick", [id, type, this.contextMenuZoneId]);
535
			this.callEvent("onClick", [id, this.contextMenuZoneId, casState]);
536
		} else {
537
			if ((type.charAt(1) == "d") || (this.menuMode == "win" && type.charAt(2) == "t")) return;
538
		}
539
		if (this.context && this._isContextMenuVisible() && this.contextAutoHide) {
540
			this._hideContextMenu();
541
		} else {
542
			// if menu unloaded from click event
543
			if (this._clearAndHide) this._clearAndHide();
544
		}
545
	}
546
	/* onTouchMenu action (select topLevel item), attachEvent added in 0.4 */
547
	this._doOnTouchMenu = function(id) {
548
		if (this.menuTouched == false) {
549
			this.menuTouched = true;
550
			if (this.checkEvent("onTouch")) {
551
				this.callEvent("onTouch", [id]);
552
			}
553
		}
554
	}
555
	// this._onTouchHandler = function(id) { }
556
	// this._setOnTouchHandler = function(handler) { this._onTouchHandler = function(id) { handler(id); } }
557
	/* return menu array of all nested objects */
558 View Code Duplication
	this._searchMenuNode = function(node, menu) {
559
		var m = new Array();
560
		for (var q=0; q<menu.length; q++) {
561
			if (typeof(menu[q]) == "object") {
562
				if (menu[q].length == 5) { if (typeof(menu[q][0]) != "object") { if ((menu[q][0].replace(this.idPrefix, "") == node) && (q == 0)) { m = menu; } } }
563
				var j = this._searchMenuNode(node, menu[q]);
564
				if (j.length > 0) { m = j; }
565
			}
566
		}
567
		return m;
568
	}
569
	/* return array of subitems for single menu object */
570
	/* modified in version 0.3 */
571
	this._getMenuNodes = function(node) {
572
		var m = new Array;
573
		for (var a in this.itemPull) { if (this.itemPull[a]["parent"] == node) { m[m.length] = a; } }
574
		return m;
575
	}
576
	/* generate random string with specified length */
577
	this._genStr = function(w) {
578
		var s = ""; var z = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
579
		for (var q=0; q<w; q++) s += z.charAt(Math.round(Math.random() * (z.length-1)));
580
		return s;
581
	}
582
	/**
583
	*	@desc: return item type by id
584
	*	@param: id
585
	*	@type: public
586
	*/
587
	this.getItemType = function(id) {
588
		id = this.idPrefix+id;
589
		if (this.itemPull[id] == null) { return null; }
590
		return this.itemPull[id]["type"];
591
	}
592
	/*
593
	*	@desc: iterator, calls user-defined handler for each existing item and pass item id into it
594
	*	@param: handler - user-defined handler
595
	*	@type: public
596
	*/
597
	this.forEachItem = function(handler) {
598
		for (var a in this.itemPull) { handler(String(a).replace(this.idPrefix, "")); }
599
	}
600
	/* clear selection and hide menu on onbody click event, optimized in version 0.3 */
601 View Code Duplication
	this._clearAndHide = function() {
602
		main_self.menuSelected = -1;
603
		main_self.menuLastClicked = -1;
604
		while (main_self._openedPolygons.length > 0) { main_self._openedPolygons.pop(); }
605
		for (var q=0; q<main_self._selectedSubItems.length; q++) {
606
			var id = main_self._selectedSubItems[q][0];
607
			// clear all selection
608
			if (main_self.idPull[id] != null) {
609
				if (main_self.itemPull[id]["state"] == "enabled") {
610
					if (main_self.idPull[id].className == "sub_item_selected") main_self.idPull[id].className = "sub_item";
611
					if (main_self.idPull[id].className == "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Selected") {
612
						// main_self.idPull[id].className = "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Normal";
613
						// custom css
614
						// console.log(main_self.itemPull[this.id])
615
						if (main_self.itemPull[id]["cssNormal"] != null) {
616
							// alert(1)
617
							main_self.idPull[id].className = main_self.itemPull[id]["cssNormal"];
618
						} else {
619
							// default css
620
							main_self.idPull[id].className = "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Normal";
621
						}
622
					}
623
				}
624
			}
625
			main_self._hidePolygon(id);
626
		}
627
		// added in 0.4
628
		// main_self._hidePolygon(main_self.idPrefix+main_self.topId);
629
		main_self.menuTouched = false;
630
		//
631
		// hide all contextmenu polygons on mouseout
632
		if (main_self.context) {
633
			if (main_self.contextHideAllMode) {
634
				main_self._hidePolygon(main_self.idPrefix+main_self.topId);
635
				main_self.zInd = main_self.zIndInit;
636
			} else {
637
				main_self.zInd = main_self.zIndInit+main_self.zIndStep;
638
			}
639
		}
640
	}
641
	/* loading and parsing through xml, optimized in version 0.3 */
642
	this._doOnLoad = function() {}
643
	/**
644
	*   @desc: loads menu data from an xml file and calls onLoadFunction when loading is done
645
	*   @param: xmlFile - an xml file with webmenu data
646
	*   @param: onLoadFunction - a function that is called after loading is done
647
	*   @type: public
648
	*/
649
	this.loadXML = function(xmlFile, onLoadFunction) {
650
		if (onLoadFunction) this._doOnLoad = function() { onLoadFunction(); };
651
		this.callEvent("onXLS", []);
652
		this._xmlLoader.loadXML(xmlFile);
653
	}
654
	/**
655
	*   @desc: loads menu data from an xml string and calls onLoadFunction when loading is done
656
	*   @param: xmlFile - an xml string with webmenu data
657
	*   @param: onLoadFunction - function that is called after loading is done
658
	*   @type: public
659
	*/
660
	this.loadXMLString = function(xmlString, onLoadFunction) {
661
		if (onLoadFunction) this._doOnLoad = function() { onLoadFunction(); };
662
		this._xmlLoader.loadXMLString(xmlString);
663
	}
664 View Code Duplication
	this._buildMenu = function(t, parentId) {
665
		// if (parentId==null) { parentId = this.topId;}
666
		var u = 0;
667
		for (var q=0; q<t.childNodes.length; q++) {
668
			if (t.childNodes[q].tagName == this.itemTagName) {
669
				var r = t.childNodes[q];
670
				var item = {};
671
				// basic
672
				item["id"] = this.idPrefix+(r.getAttribute("id")||this._genStr(24));
673
				item["title"] = r.getAttribute("text")||"";
674
				// images
675
				item["imgen"] = r.getAttribute("img")||"";
676
				item["imgdis"] = r.getAttribute("imgdis")||"";
677
				item["tip"] = "";
678
				item["hotkey"] = "";
679
				// custom css
680
				if (r.getAttribute("cssNormal") != null) { item["cssNormal"] = r.getAttribute("cssNormal"); }
681
				// type
682
				item["type"] = r.getAttribute("type")||"item";
683
//#menu_checks:06062008{
684
				if (item["type"] == "checkbox") {
685
					item["checked"] = (r.getAttribute("checked")!=null);
686
					// set classname
687
					item["imgen"] = "chbx_"+(item["checked"]?"1":"0");
688
					item["imgdis"] = item["imgen"];
689
				}
690
//#}
691
//#menu_radio:06062008{
692
				if (item["type"] == "radio") {
693
					item["checked"] = (r.getAttribute("checked")!=null);
694
					item["imgen"] = "rdbt_"+(item["checked"]?"1":"0");
695
					item["imgdis"] = item["imgen"];
696
					item["group"] = r.getAttribute("group")||this._genStr(24);
697
					if (this.radio[item["group"]]==null) { this.radio[item["group"]] = new Array(); }
698
					this.radio[item["group"]][this.radio[item["group"]].length] = item["id"];
699
				}
700
//#}
701
				// enable/disable
702
				item["state"] = (r.getAttribute("enabled")!=null||r.getAttribute("disabled")!=null?(r.getAttribute("enabled")=="false"||r.getAttribute("disabled")=="true"?"disabled":"enabled"):"enabled");
703
				item["parent"] = (parentId!=null?parentId:this.idPrefix+this.topId);
704
				// item["complex"] = (((this.dLoad)&&(parentId!=null))?(r.getAttribute("complex")!=null?true:false):(this._buildMenu(r,item["id"])>0));
705
				item["complex"] = (this.dLoad?(r.getAttribute("complex")!=null?true:false):(this._buildMenu(r,item["id"])>0));
706
				if (this.dLoad && item["complex"]) { item["loaded"] = "no"; }
707
				this.itemPull[item["id"]] = item;
708
				// check for user data
709
				for (var w=0; w<r.childNodes.length; w++) {
710
					// added in 0.4
711
					var tagNm = r.childNodes[w].tagName;
712
					if (tagNm != null) { tagNm = tagNm.toLowerCase(); }
713
					//
714
					if (tagNm == this.userDataTagName) {
715
						var d = r.childNodes[w];
716
						if (d.getAttribute("name")!=null) { this.userData[item["id"]+"_"+d.getAttribute("name")] = (d.firstChild!=null&&d.firstChild.nodeValue!=null?d.firstChild.nodeValue:""); }
717
					}
718
					// extended text, added in 0.4
719
					if (tagNm == this.itemTextTagName) { item["title"] = r.childNodes[w].firstChild.nodeValue; }
720
					// tooltips, added in 0.4
721
					if (tagNm == this.itemTipTagName) { item["tip"] = r.childNodes[w].firstChild.nodeValue; }
722
					// hotkeys, added in 0.4
723
					if (tagNm == this.itemHotKeyTagName) { item["hotkey"] = r.childNodes[w].firstChild.nodeValue; }
724
					// hrefs
725
					if (tagNm == this.itemHrefTagName && item["type"] == "item") {
726
						item["href_link"] = r.childNodes[w].firstChild.nodeValue;
727
						if (r.childNodes[w].getAttribute("target") != null) { item["href_target"] = r.childNodes[w].getAttribute("target"); }
728
					}
729
				}
730
				u++;
731
			}
732
		}
733
		return u;
734
	}
735
	/* parse incoming xml */
736 View Code Duplication
	this._xmlParser = function() {
737
		if (main_self.dLoad) {
738
			var t = this.getXMLTopNode("menu");
739
			parentId = (t.getAttribute("parentId")!=null?t.getAttribute("parentId"):null);
740
			if (parentId == null) {
741
				// alert(1)
742
				// main_self.idPrefix = main_self._genStr(12);
743
				main_self._buildMenu(t, null);
744
				main_self._initTopLevelMenu();
745
			} else {
746
				main_self._buildMenu(t, main_self.idPrefix+parentId);
747
				main_self._addSubMenuPolygon(main_self.idPrefix+parentId, main_self.idPrefix+parentId);//, main_self.idPull[main_self.idPrefix+parentId]);
748
				if (main_self.menuSelected == main_self.idPrefix+parentId) {
749
					var pId = main_self.idPrefix+parentId;
750
					var isTop = main_self.itemPull[main_self.idPrefix+parentId]["parent"]==main_self.idPrefix+main_self.topId;
751
					var level = ((isTop&&(!main_self.context))?main_self.dirTopLevel:main_self.dirSubLevel);
752
					var isShow = false;
753
					if (isTop && main_self.menuModeTopLevelTimeout && main_self.menuMode == "web" && !main_self.context) {
754
						var item = main_self.idPull[main_self.idPrefix+parentId];
755
						if (item._mouseOver == true) {
756
							var delay = main_self.menuModeTopLevelTimeoutTime - (new Date().getTime()-item._dynLoadTM);
757
							if (delay > 1) {
758
								item._menuOpenTM = window.setTimeout(function(){ main_self._showPolygon(pId, level); }, delay);
759
								isShow = true;
760
							}
761
						}
762
					}
763
					if (!isShow) { main_self._showPolygon(pId, level); }
764
				}
765
				main_self.itemPull[main_self.idPrefix+parentId]["loaded"] = "yes";
766
				// console.log(main_self.loaderIcon)
767
				if (main_self.loaderIcon == true) { main_self._updateLoaderIcon(main_self.idPrefix+parentId, false); }
768
			}
769
			this.destructor();
770
			main_self.callEvent("onXLE",[]);
771
		} else {
772
			var t = this.getXMLTopNode("menu");
773
			// alert(3)
774
			// main_self.idPrefix = main_self._genStr(12);
775
			main_self._buildMenu(t, null);
776
			main_self.init();
777
			main_self.callEvent("onXLE",[]);
778
			main_self._doOnLoad();
779
		}
780
	}
781
	this._xmlLoader = new dtmlXMLLoaderObject(this._xmlParser, window);
782
	/* show sublevel item */
783 View Code Duplication
	this._showSubLevelItem = function(id,back) {
784
		if (document.getElementById("arrow_" + this.idPrefix + id) != null) { document.getElementById("arrow_" + this.idPrefix + id).style.display = (back?"none":""); }
785
		if (document.getElementById("image_" + this.idPrefix + id) != null) { document.getElementById("image_" + this.idPrefix + id).style.display = (back?"none":""); }
786
		if (document.getElementById(this.idPrefix + id) != null) { document.getElementById(this.idPrefix + id).style.display = (back?"":"none"); }
787
	}
788
	/* hide sublevel item */
789
	this._hideSubLevelItem = function(id) {
790
		this._showSubLevelItem(id,true)
791
	}
792
	// generating id prefix
793
	this.idPrefix = this._genStr(12);
794
	
795
	/* attach body events */
796
	this._bodyClick = function(e) {
797
		e = e||event;
798
		if (e.button == 2 || (_isOpera && e.ctrlKey == true)) return;
799
		if (main_self.context) {
800
			if (main_self.contextAutoHide && (!_isOpera || (main_self._isContextMenuVisible() && _isOpera))) main_self._hideContextMenu();
801
		} else {
802
			if (main_self._clearAndHide) main_self._clearAndHide();
803
		}
804
	}
805
	this._bodyContext = function(e) {
806
		e = e||event;
807
		var t = String((e.srcElement||e.target).className);
808
		if (t.search("dhtmlxMenu") != -1 && t.search("SubLevelArea") != -1) return;
809
		var toHide = true;
810
		var testZone = e.target || e.srcElement;
811
		while (testZone != null) {
812
			if (testZone.id != null) if (main_self.isContextZone(testZone.id)) toHide = false;
813
			if (testZone == document.body) toHide = false;
814
			testZone = testZone.parentNode;
815
		}
816
		if (toHide) main_self.hideContextMenu();
817
	}
818
	
819
	if (typeof(window.addEventListener) != "undefined") {
820
		window.addEventListener("click", this._bodyClick, false);
821
		window.addEventListener("contextmenu", this._bodyContext, false);
822
	} else {
823
		document.body.attachEvent("onclick", this._bodyClick);
824
		document.body.attachEvent("oncontextmenu", this._bodyContext);
825
	}
826
	
827
	// add menu to global store
828
	this._UID = this._genStr(32);
829
	dhtmlxMenuObjectLiveInstances[this._UID] = this;
830
	
831
	/* events */
832
	dhtmlxEventable(this);
833
	//
834
	return this;
835
}
836
dhtmlXMenuObject.prototype.init = function() {
837
	if (this._isInited == true) return;
838
	if (this.dLoad) {
839
		this.callEvent("onXLS", []);
840
		// this._xmlLoader.loadXML(this.dLoadUrl+"?action=loadMenu&parentId="+this.topId+"&topId="+this.topId);
841
		this._xmlLoader.loadXML(this.dLoadUrl+this.dLoadSign+"action=loadMenu&etc="+new Date().getTime()); // &&parentId=topId&"+this.topId+"&topId="+this.topId);
842
	} else {
843
		this._initTopLevelMenu();
844
		this._isInited = true;
845
	}
846
}
847 View Code Duplication
dhtmlXMenuObject.prototype._countVisiblePolygonItems = function(id) {
848
	/*
849
	var count = 0;
850
	if ((this.idPull["polygon_"+id] != null) && (this.idPull[id] != null)) {
851
		for (var q=0; q<this.idPull["polygon_"+id].childNodes.length; q++) {
852
			var node = this.idPull["polygon_"+id].childNodes[q];
853
			count += (((node.style.display=="none")||(node.className=="dhtmlxMenu_SubLevelArea_Separator"))?0:1);
854
		}
855
	}
856
	*/
857
	/* updated in 0.4 */
858
	var count = 0;
859
	// console.log(this.idPull)
860
	for (var a in this.itemPull) {
861
		//console.log(a)
862
		var par = this.itemPull[a]["parent"];
863
		var tp = this.itemPull[a]["type"];
864
		if (this.idPull[a] != null) {
865
			// console.log(this.idPull[a])
866
			// alert(1111)
867
			if (par == id && (tp == "item" || tp == "radio" || tp == "checkbox") && this.idPull[a].style.display != "none") {
868
				count++;
869
			}
870
		}
871
	}
872
	return count;
873
}
874 View Code Duplication
dhtmlXMenuObject.prototype._redefineComplexState = function(id) {
875
	// alert(id)
876
	if (this.idPrefix+this.topId == id) { return; }
877
	if ((this.idPull["polygon_"+id] != null) && (this.idPull[id] != null)) {
878
		var u = this._countVisiblePolygonItems(id);
879
		if ((u > 0) && (!this.itemPull[id]["complex"])) { this._updateItemComplexState(id, true, false); }
880
		if ((u == 0) && (this.itemPull[id]["complex"])) { this._updateItemComplexState(id, false, false); }
881
	}
882
}
883
/* complex arrow manipulations, over added in 0.4 */
884 View Code Duplication
dhtmlXMenuObject.prototype._updateItemComplexState = function(id, state, over) {
885
	// 0.2 FIX :: topLevel's items can have complex items with arrow
886
	if ((!this.context) && (this._getItemLevelType(id.replace(this.idPrefix,"")) == "TopLevel")) {
887
		// 30.06.2008 fix > complex state for top level item, state only, no arrow
888
		this.itemPull[id]["complex"] = state;
889
		return;
890
	}
891
	if ((this.idPull[id] == null) || (this.itemPull[id] == null)) { return; }
892
	// 0.2 FIX :: end
893
	this.itemPull[id]["complex"] = state;
894
	// fixed in 0.4 for context
895
	if (id == this.idPrefix+this.topId) return;
896
	// end fix
897
	// try to retrieve arrow img object
898
	var arrowObj = null;
899
	
900
	
901
	var item = this.idPull[id].childNodes[this._rtl?0:2];
902
	if (item.childNodes[0]) if (String(item.childNodes[0].className).search("complex_arrow") === 0) arrowObj = item.childNodes[0];
903
	
904
	if (this.itemPull[id]["complex"]) {
905
		// create arrow
906
		if (arrowObj == null) {
907
			arrowObj = document.createElement("DIV");
908
			arrowObj.className = "complex_arrow";
909
			arrowObj.id = "arrow_"+id;
910
			while (item.childNodes.length > 0) item.removeChild(item.childNodes[0]);
911
			item.appendChild(arrowObj);
912
		}
913
		// over state added in 0.4
914
		
915
		if (this.dLoad && (this.itemPull[id]["loaded"] == "get") && this.loaderIcon) {
916
			// change arrow to loader
917
			if (arrowObj.className != "complex_arrow_loading") arrowObj.className = "complex_arrow_loading";
918
		} else {
919
			arrowObj.className = "complex_arrow";
920
		}
921
		
922
		return;
923
	}
924
	
925
	if ((!this.itemPull[id]["complex"]) && (arrowObj!=null)) {
926
		item.removeChild(arrowObj);
927
		if (this.itemPull[id]["hotkey_backup"] != null && this.setHotKey) { this.setHotKey(id.replace(this.idPrefix, ""), this.itemPull[id]["hotkey_backup"]); }
928
	}
929
	
930
}
931
932
/* return css-part level type */
933
dhtmlXMenuObject.prototype._getItemLevelType = function(id) {
934
	return (this.itemPull[this.idPrefix+id]["parent"]==this.idPrefix+this.topId?"TopLevel":"SubLevelArea");
935
}
936
/****************************************************************************************************************************************************/
937
/*								 	"TOPLEVEL" LOW-LEVEL RENDERING						    */
938
/* redistrib selection in case of top node in real-time mode */
939 View Code Duplication
dhtmlXMenuObject.prototype._redistribTopLevelSelection = function(id, parent) {
940
	// kick polygons and decelect before selected menues
941
	var i = this._getSubItemToDeselectByPolygon("parent");
942
	this._removeSubItemFromSelected(-1, -1);
943
	for (var q=0; q<i.length; q++) {
944
		if (i[q] != id) { this._hidePolygon(i[q]); }
945
		if ((this.idPull[i[q]] != null) && (i[q] != id)) { this.idPull[i[q]].className = this.idPull[i[q]].className.replace(/Selected/g, "Normal"); }
946
	}
947
	// check if enabled
948
	if (this.itemPull[this.idPrefix+id]["state"] == "enabled") {
949
		this.idPull[this.idPrefix+id].className = "dhtmlxMenu_"+this.skin+"_TopLevel_Item_Selected";
950
		//
951
		this._addSubItemToSelected(this.idPrefix+id, "parent");
952
		this.menuSelected = (this.menuMode=="win"?(this.menuSelected!=-1?id:this.menuSelected):id);
953
		if ((this.itemPull[this.idPrefix+id]["complex"]) && (this.menuSelected != -1)) { this._showPolygon(this.idPrefix+id, this.dirTopLevel); }
954
	}
955
}
956 View Code Duplication
dhtmlXMenuObject.prototype._initTopLevelMenu = function() {
957
	// console.log(this.idPull);
958
	this.dirTopLevel = "bottom";
959
	this.dirSubLevel = (this._rtl?"left":"right");
960
	if (this.context) {
961
		this.idPull[this.idPrefix+this.topId] = new Array(0,0);
962
		this._addSubMenuPolygon(this.idPrefix+this.topId, this.idPrefix+this.topId);
963
	} else {
964
		var m = this._getMenuNodes(this.idPrefix + this.topId);
965
		for (var q=0; q<m.length; q++) {
966
			if (this.itemPull[m[q]]["type"] == "item") this._renderToplevelItem(m[q], null);
967
			if (this.itemPull[m[q]]["type"] == "separator") this._renderSeparator(m[q], null);
968
		}
969
	}
970
}
971
/* add top menu item, complex define that submenues are in presence */
972 View Code Duplication
dhtmlXMenuObject.prototype._renderToplevelItem = function(id, pos) {
973
	var main_self = this;
974
	var m = document.createElement("DIV");
975
	m.id = id;
976
	// custom css
977
	if (this.itemPull[id]["state"] == "enabled" && this.itemPull[id]["cssNormal"] != null) {
978
		m.className = this.itemPull[id]["cssNormal"];
979
	} else {
980
		m.className = "dhtmlxMenu_"+this.skin+"_TopLevel_Item_"+(this.itemPull[id]["state"]=="enabled"?"Normal":"Disabled");
981
	}
982
	
983
	// text
984
	if (this.itemPull[id]["title"] != "") {
985
		var t1 = document.createElement("DIV");
986
		t1.className = "top_level_text";
987
		t1.innerHTML = this.itemPull[id]["title"];
988
		m.appendChild(t1);
989
	}
990
	// tooltip
991
	if (this.itemPull[id]["tip"].length > 0) m.title = this.itemPull[id]["tip"];
992
	//
993
	// image in top level
994
	if ((this.itemPull[id]["imgen"]!="")||(this.itemPull[id]["imgdis"]!="")) {
995
		var imgTop=this.itemPull[id][(this.itemPull[id]["state"]=="enabled")?"imgen":"imgdis"];
996
		if (imgTop) {
997
			var img = document.createElement("IMG");
998
			img.border = "0";
999
			img.id = "image_"+id;
1000
			img.src= this.imagePath+imgTop;
1001
			img.className = "dhtmlxMenu_TopLevel_Item_Icon";
1002
			if (m.childNodes.length > 0 && !this._rtl) m.insertBefore(img, m.childNodes[0]); else m.appendChild(img);
1003
		}
1004
	}
1005
	m.onselectstart = function(e) { e = e || event; e.returnValue = false; return false; }
1006
	m.oncontextmenu = function(e) { e = e || event; e.returnValue = false; return false; }
1007
	// add container for top-level items if not exists yet
1008
	if (!this.cont) {
1009
		this.cont = document.createElement("DIV");
1010
		this.cont.dir = "ltr";
1011
		this.cont.className = (this._align=="right"?"align_right":"align_left");
1012
		this.base.appendChild(this.cont);
1013
	}
1014
	// insert
1015
	/*
1016
	if (pos != null) { pos++; if (pos < 0) pos = 0; if (pos > this.base.childNodes.length - 1) pos = null; }
1017
	if (pos != null) this.base.insertBefore(m, this.base.childNodes[pos]); else this.base.appendChild(m);
1018
	*/
1019
	if (pos != null) { pos++; if (pos < 0) pos = 0; if (pos > this.cont.childNodes.length - 1) pos = null; }
1020
	if (pos != null) this.cont.insertBefore(m, this.cont.childNodes[pos]); else this.cont.appendChild(m);
1021
	
1022
	
1023
	//
1024
	this.idPull[m.id] = m;
1025
	// create submenues
1026
	if (this.itemPull[id]["complex"] && (!this.dLoad)) this._addSubMenuPolygon(this.itemPull[id]["id"], this.itemPull[id]["id"]);
1027
	// events
1028
	m.onmouseover = function() {
1029
		if (main_self.menuMode == "web") { window.clearTimeout(main_self.menuTimeoutHandler); }
1030
		// kick polygons and decelect before selected menues
1031
		var i = main_self._getSubItemToDeselectByPolygon("parent");
1032
		main_self._removeSubItemFromSelected(-1, -1);
1033
		for (var q=0; q<i.length; q++) {
1034
			if (i[q] != this.id) { main_self._hidePolygon(i[q]); }
1035
			if ((main_self.idPull[i[q]] != null) && (i[q] != this.id)) {
1036
				// custom css
1037
				if (main_self.itemPull[i[q]]["cssNormal"] != null) {
1038
					main_self.idPull[i[q]].className = main_self.itemPull[i[q]]["cssNormal"];
1039
				} else {
1040
					if (main_self.idPull[i[q]].className == "sub_item_selected") main_self.idPull[i[q]].className = "sub_item";
1041
					main_self.idPull[i[q]].className = main_self.idPull[i[q]].className.replace(/Selected/g, "Normal");
1042
				}
1043
			}
1044
		}
1045
		// check if enabled
1046
		if (main_self.itemPull[this.id]["state"] == "enabled") {
1047
			this.className = "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Selected";
1048
			//
1049
			main_self._addSubItemToSelected(this.id, "parent");
1050
			main_self.menuSelected = (main_self.menuMode=="win"?(main_self.menuSelected!=-1?this.id:main_self.menuSelected):this.id);
1051
			if (main_self.dLoad && (main_self.itemPull[this.id]["loaded"]=="no")) {
1052
				if (main_self.menuModeTopLevelTimeout && main_self.menuMode == "web" && !main_self.context) {
1053
					this._mouseOver = true;
1054
					this._dynLoadTM = new Date().getTime();
1055
				}
1056
				var xmlLoader = new dtmlXMLLoaderObject(main_self._xmlParser, window);
1057
				main_self.itemPull[this.id]["loaded"] = "get";
1058
				main_self.callEvent("onXLS", []);
1059
				xmlLoader.loadXML(main_self.dLoadUrl+main_self.dLoadSign+"action=loadMenu&parentId="+this.id.replace(main_self.idPrefix,"")+"&etc="+new Date().getTime());
1060
			}
1061
			if ((!main_self.dLoad) || (main_self.dLoad && (!main_self.itemPull[this.id]["loaded"] || main_self.itemPull[this.id]["loaded"]=="yes"))) {
1062
				if ((main_self.itemPull[this.id]["complex"]) && (main_self.menuSelected != -1)) {
1063
					if (main_self.menuModeTopLevelTimeout && main_self.menuMode == "web" && !main_self.context) {
1064
						this._mouseOver = true;
1065
						var showItemId = this.id;
1066
						this._menuOpenTM = window.setTimeout(function(){main_self._showPolygon(showItemId, main_self.dirTopLevel);}, main_self.menuModeTopLevelTimeoutTime);
1067
					} else {
1068
						main_self._showPolygon(this.id, main_self.dirTopLevel);
1069
					}
1070
				}
1071
			}
1072
		}
1073
		main_self._doOnTouchMenu(this.id.replace(main_self.idPrefix, ""));
1074
	}
1075
	m.onmouseout = function() {
1076
		if (!((main_self.itemPull[this.id]["complex"]) && (main_self.menuSelected != -1)) && (main_self.itemPull[this.id]["state"]=="enabled")) {
1077
			// custom css
1078
			// console.log(main_self.itemPull[this.id])
1079
			if (main_self.itemPull[this.id]["cssNormal"] != null) {
1080
				// alert(1)
1081
				m.className = main_self.itemPull[this.id]["cssNormal"];
1082
			} else {
1083
				// default css
1084
				m.className = "dhtmlxMenu_"+main_self.skin+"_TopLevel_Item_Normal";
1085
			}
1086
		}
1087
		if (main_self.menuMode == "web") {
1088
			window.clearTimeout(main_self.menuTimeoutHandler);
1089
			main_self.menuTimeoutHandler = window.setTimeout(function(){main_self._clearAndHide();}, main_self.menuTimeoutMsec, "JavaScript");
1090
		}
1091
		if (main_self.menuModeTopLevelTimeout && main_self.menuMode == "web" && !main_self.context) {
1092
			this._mouseOver = false;
1093
			window.clearTimeout(this._menuOpenTM);
1094
		}
1095
	}
1096
	m.onclick = function(e) {
1097
		if (main_self.menuMode == "web") { window.clearTimeout(main_self.menuTimeoutHandler); }
1098
		// fix, added in 0.4
1099
		if (main_self.menuMode != "web" && main_self.itemPull[this.id]["state"] == "disabled") { return; }
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
1100
		//
1101
		e = e || event;
1102
		e.cancelBubble = true;
1103
		e.returnValue = false;
1104
		
1105
		if (main_self.menuMode == "win") {
1106
			if (main_self.itemPull[this.id]["complex"]) {
1107
				if (main_self.menuSelected == this.id) { main_self.menuSelected = -1; var s = false; } else { main_self.menuSelected = this.id; var s = true; }
1108
				if (s) { main_self._showPolygon(this.id, main_self.dirTopLevel); } else { main_self._hidePolygon(this.id); }
1109
			}
1110
		}
1111
		var tc = (main_self.itemPull[this.id]["complex"]?"c":"-");
1112
		var td = (main_self.itemPull[this.id]["state"]!="enabled"?"d":"-");
1113
		var cas = {"ctrl": e.ctrlKey, "alt": e.altKey, "shift": e.shiftKey};
1114
		main_self._doOnClick(this.id.replace(main_self.idPrefix, ""), tc+td+"t", cas);
1115
		return false;
1116
	}
1117
	
1118
	if (this.skin == "dhx_terrace") {
1119
		this._improveTerraceSkin();
1120
	}
1121
}
1122
/****************************************************************************************************************************************************/
1123
/**
1124
*   @desc: empty function, now more used from 90226
1125
*   @type: public
1126
*/
1127
dhtmlXMenuObject.prototype.setImagePath = function() { /* no more used */ }
1128
/**
1129
*   @desc: defines an url where necessary user embedded icons are located
1130
*   @param: path - url to images
1131
*   @type: public
1132
*/
1133
dhtmlXMenuObject.prototype.setIconsPath = function(path) { this.imagePath = path; }
1134
/**
1135
*   @desc: alias for setIconsPath
1136
*   @type: public
1137
*/
1138
dhtmlXMenuObject.prototype.setIconPath = dhtmlXMenuObject.prototype.setIconsPath;
1139
/* real-time update icon in menu */
1140 View Code Duplication
dhtmlXMenuObject.prototype._updateItemImage = function(id, levelType) {
1141
	// search existsing image
1142
	
1143
	id = this.idPrefix+id;
1144
	var isTopLevel = (this.itemPull[id]["parent"] == this.idPrefix+this.topId && !this.context);
1145
	
1146
	// search existing image
1147
	var imgObj = null;
1148
	if (isTopLevel) {
1149
		for (var q=0; q<this.idPull[id].childNodes.length; q++) {
1150
			try { if (this.idPull[id].childNodes[q].className == "dhtmlxMenu_TopLevel_Item_Icon") imgObj = this.idPull[id].childNodes[q]; } catch(e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
1151
		}
1152
	} else {
1153
		try { var imgObj = this.idPull[id].childNodes[this._rtl?2:0].childNodes[0]; } catch(e) { }
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
1154
	}
1155
	
1156
	if (this.itemPull[id]["type"] == "radio") {
1157
		var imgSrc = this.itemPull[id][(this.itemPull[id]["state"]=="enabled"?"imgen":"imgdis")];
1158
		// console.log(this.itemPull[this.idPrefix+id])
1159
	} else {
1160
		var imgSrc = this.itemPull[id][(this.itemPull[id]["state"]=="enabled"?"imgen":"imgdis")];
1161
	}
1162
	
1163
	if (imgSrc.length > 0) {
1164
		if (imgObj != null) {
1165
			imgObj.src = this.imagePath+imgSrc;
1166
		} else {
1167
			if (isTopLevel) {
1168
				var imgObj = document.createElement("IMG");
1169
				imgObj.className = "dhtmlxMenu_TopLevel_Item_Icon";
1170
				imgObj.src = this.imagePath+imgSrc;
1171
				imgObj.border = "0";
1172
				imgObj.id = "image_"+id;
1173
				if (!this._rtl && this.idPull[id].childNodes.length > 0) this.idPull[id].insertBefore(imgObj,this.idPull[id].childNodes[0]); else this.idPull[id].appendChild(imgObj);
1174
				
1175
			} else {
1176
				
1177
				var imgObj = document.createElement("IMG");
1178
				imgObj.className = "sub_icon";
1179
				imgObj.src = this.imagePath+imgSrc;
1180
				imgObj.border = "0";
1181
				imgObj.id = "image_"+id;
1182
				var item = this.idPull[id].childNodes[this._rtl?2:0];
1183
				while (item.childNodes.length > 0) item.removeChild(item.childNodes[0]);
1184
				item.appendChild(imgObj);
1185
				
1186
			}
1187
		}
1188
	} else {
1189
		if (imgObj != null) imgObj.parentNode.removeChild(imgObj);
1190
	}
1191
}
1192
/**
1193
*   @desc: removes an item from the menu with all nested sublevels
1194
*   @param: id - id of the item for removing
1195
*   @type: public
1196
*/
1197 View Code Duplication
dhtmlXMenuObject.prototype.removeItem = function(id, _isTId, _recCall) {
1198
	if (!_isTId) id = this.idPrefix + id;
1199
	
1200
	var pId = null;
1201
	
1202
	if (id != this.idPrefix+this.topId) {
1203
		
1204
		if (this.itemPull[id] == null) return;
1205
		
1206
		// effects
1207
		if (this.idPull["polygon_"+id] && this.idPull["polygon_"+id]._tmShow) window.clearTimeout(this.idPull["polygon_"+id]._tmShow);
1208
		
1209
		// separator top
1210
		var t = this.itemPull[id]["type"];
1211
		
1212
		if (t == "separator") {
1213
			var item = this.idPull["separator_"+id];
1214
			if (this.itemPull[id]["parent"] == this.idPrefix+this.topId) {
1215
				item.onclick = null;
1216
				item.onselectstart = null;
1217
				item.id = null;
1218
				item.parentNode.removeChild(item);
1219
			} else {
1220
				item.childNodes[0].childNodes[0].onclick = null;
1221
				item.childNodes[0].childNodes[0].onselectstart = null;
1222
				item.childNodes[0].childNodes[0].id = null;
1223
				item.childNodes[0].removeChild(item.childNodes[0].childNodes[0]);
1224
				item.removeChild(item.childNodes[0]);
1225
				item.parentNode.removeChild(item);
1226
			}
1227
			this.idPull["separator_"+id] = null;
1228
			this.itemPull[id] = null;
1229
			delete this.idPull["separator_"+id];
1230
			delete this.itemPull[id];
1231
			item = null;
1232
		} else {
1233
			// item checkbox radio
1234
			pId = this.itemPull[id]["parent"];
1235
			var item = this.idPull[id];
1236
			item.onclick = null;
1237
			item.oncontextmenu = null;
1238
			item.onmouseover = null;
1239
			item.onmouseout = null;
1240
			item.onselectstart = null;
1241
			item.id = null;
1242
			while (item.childNodes.length > 0) item.removeChild(item.childNodes[0]);
1243
			item.parentNode.removeChild(item);
1244
			this.idPull[id] = null;
1245
			this.itemPull[id] = null;
1246
			delete this.idPull[id];
1247
			delete this.itemPull[id];
1248
			item = null;
1249
			
1250
		}
1251
		t = null;
1252
	}
1253
	
1254
	// clear nested items
1255
	for (var a in this.itemPull) if (this.itemPull[a]["parent"] == id) this.removeItem(a, true, true);
1256
	
1257
	// check if empty polygon left
1258
	var p2 = new Array(id);
1259
	if (pId != null && !_recCall) {
1260
		if (this.idPull["polygon_"+pId] != null) {
1261
			if (this.idPull["polygon_"+pId].tbd.childNodes.length == 0) {
1262
				p2.push(pId);
1263
				this._updateItemComplexState(pId, false, false);
1264
			}
1265
		}
1266
	}
1267
	
1268
	// delete nested polygons and parent's if any
1269
	for (var q=0; q<p2.length; q++) {
1270
		if (this.idPull["polygon_"+p2[q]]) {
1271
			var p = this.idPull["polygon_"+p2[q]];
1272
			p.onclick = null;
1273
			p.oncontextmenu = null;
1274
			p.tbl.removeChild(p.tbd);
1275
			p.tbd = null;
1276
			p.removeChild(p.tbl);
1277
			p.tbl = null;
1278
			p.id = null;
1279
			p.parentNode.removeChild(p);
1280
			p = null;
1281
			if (this._isIE6) {
1282
				var pc = "polygon_"+p2[q]+"_ie6cover";
1283
				if (this.idPull[pc] != null) { document.body.removeChild(this.idPull[pc]); delete this.idPull[pc]; }
1284
			}
1285
			if (this.idPull["arrowup_"+id] != null && this._removeArrow) this._removeArrow("arrowup_"+id);
1286
			if (this.idPull["arrowdown_"+id] != null && this._removeArrow) this._removeArrow("arrowdown_"+id);
1287
			//
1288
			this.idPull["polygon_"+p2[q]] = null;
1289
			delete this.idPull["polygon_"+p2[q]];
1290
		}
1291
	}
1292
	p2 = null;
1293
	
1294
	// update corners
1295
	if (this.skin == "dhx_terrace" && arguments.length == 1) this._improveTerraceSkin();
1296
	
1297
}
1298
/* collect parents for remove complex item */
1299 View Code Duplication
dhtmlXMenuObject.prototype._getAllParents = function(id) {
1300
	var parents = new Array();
1301
	for (var a in this.itemPull) {
1302
		if (this.itemPull[a]["parent"] == id) {
1303
			parents[parents.length] = this.itemPull[a]["id"];
1304
			if (this.itemPull[a]["complex"]) {
1305
				var t = this._getAllParents(this.itemPull[a]["id"]);
1306
				for (var q=0; q<t.length; q++) { parents[parents.length] = t[q]; }
1307
			}
1308
		}
1309
	}
1310
	return parents;
1311
}
1312
1313
//#menu_context:06062008{
1314
	
1315
/****************************************************************************************************************************************************/
1316
/*								 	CONTEXT STUFF								    */
1317
/* render dhtmlxMenu as context menu of base object */
1318
/**
1319
*   @desc: renders menu as contextual
1320
*   @type: public
1321
*/
1322
dhtmlXMenuObject.prototype.renderAsContextMenu = function() {
1323
	this.context = true;
1324
	if (this.base._autoSkinUpdate == true) {
1325
		this.base.className = this.base.className.replace("dhtmlxMenu_"+this.skin+"_Middle","");
1326
		this.base._autoSkinUpdate = false;
1327
	}
1328
	if (this.addBaseIdAsContextZone != null) { this.addContextZone(this.addBaseIdAsContextZone); }
1329
}
1330
/**
1331
*   @desc: adds a contextual zone to a contextual menu
1332
*   @param: zoneId - id of the object on page to render as a contextual zone
1333
*   @type: public
1334
*/
1335 View Code Duplication
dhtmlXMenuObject.prototype.addContextZone = function(zoneId) {
1336
	if (zoneId == document.body) {
1337
		zoneId = "document.body."+this.idPrefix;
1338
		var zone = document.body;
1339
	} else {
1340
		var zone = document.getElementById(zoneId);
1341
	}
1342
	var zoneExists = false;
1343
	for (var a in this.contextZones) { zoneExists = zoneExists || (a == zoneId) || (this.contextZones[a] == zone); }
1344
	if (zoneExists == true) return false;
1345
	this.contextZones[zoneId] = zone;
1346
	var main_self = this;
1347
	if (_isOpera) {
1348
		this.operaContext = function(e){ main_self._doOnContextMenuOpera(e, main_self); }
1349
		zone.addEventListener("mouseup", this.operaContext, false);
1350
		//
1351
	} else {
1352
		if (zone.oncontextmenu != null && !zone._oldContextMenuHandler) zone._oldContextMenuHandler = zone.oncontextmenu;
1353
		zone.oncontextmenu = function(e) {
1354
			// autoclose any other opened context menues
1355
			for (var q in dhtmlxMenuObjectLiveInstances) {
1356
				if (q != main_self._UID) {
1357
					if (dhtmlxMenuObjectLiveInstances[q].context) {
1358
						dhtmlxMenuObjectLiveInstances[q]._hideContextMenu();
1359
					}
1360
				}
1361
			}
1362
			//
1363
			e = e||event;
1364
			e.cancelBubble = true;
1365
			e.returnValue = false;
1366
			main_self._doOnContextBeforeCall(e, this);
1367
			return false;
1368
		}
1369
	}
1370
}
1371
dhtmlXMenuObject.prototype._doOnContextMenuOpera = function(e, main_self) {
1372
	// autoclose any other opened context menues
1373
	for (var q in dhtmlxMenuObjectLiveInstances) {
1374
		if (q != main_self._UID) {
1375
			if (dhtmlxMenuObjectLiveInstances[q].context) {
1376
				dhtmlxMenuObjectLiveInstances[q]._hideContextMenu();
1377
			}
1378
		}
1379
	}
1380
	//
1381
	e.cancelBubble = true;
1382
	e.returnValue = false;
1383
	if (e.button == 0 && e.ctrlKey == true) { main_self._doOnContextBeforeCall(e, this); }
1384
	return false;
1385
}
1386
/**
1387
*   @desc: removes an object from contextual zones list
1388
*   @param: zoneId - id of a contextual zone
1389
*   @type: public
1390
*/
1391 View Code Duplication
dhtmlXMenuObject.prototype.removeContextZone = function(zoneId) {
1392
	if (!this.isContextZone(zoneId)) return false;
1393
	if (zoneId == document.body) zoneId = "document.body."+this.idPrefix;
1394
	var zone = this.contextZones[zoneId];
1395
	if (_isOpera) {
1396
		zone.removeEventListener("mouseup", this.operaContext, false);
1397
	} else {
1398
		zone.oncontextmenu = (zone._oldContextMenuHandler!=null?zone._oldContextMenuHandler:null);
1399
		zone._oldContextMenuHandler = null;
1400
	}
1401
	try {
1402
		this.contextZones[zoneId] = null;
1403
		delete this.contextZones[zoneId];
1404
 	} catch(e){}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
1405
	return true;
1406
}
1407
/**
1408
*   @desc: returns true if an object is used as a contextual zone for the menu
1409
*   @param: zoneId - id of the object to check
1410
*   @type: public
1411
*/
1412
dhtmlXMenuObject.prototype.isContextZone = function(zoneId) {
1413
	if (zoneId == document.body && this.contextZones["document.body."+this.idPrefix] != null) return true;
1414
	var isZone = false;
1415
	if (this.contextZones[zoneId] != null) { if (this.contextZones[zoneId] == document.getElementById(zoneId)) isZone = true; }
1416
	return isZone;
1417
}
1418
dhtmlXMenuObject.prototype._isContextMenuVisible = function() {
1419
	if (this.idPull["polygon_"+this.idPrefix+this.topId] == null) return false;
1420
	return (this.idPull["polygon_"+this.idPrefix+this.topId].style.display == "");
1421
}
1422
dhtmlXMenuObject.prototype._showContextMenu = function(x, y, zoneId) {
1423
	// hide any opened context menu/polygons
1424
	this._clearAndHide();
1425
	// this._hideContextMenu();
1426
	// open
1427
	if (this.idPull["polygon_"+this.idPrefix+this.topId] == null) return false;
1428
	window.clearTimeout(this.menuTimeoutHandler);
1429
	this.idPull[this.idPrefix+this.topId] = new Array(x, y);
1430
	this._showPolygon(this.idPrefix+this.topId, "bottom");
1431
	this.callEvent("onContextMenu", [zoneId]);
1432
}
1433
dhtmlXMenuObject.prototype._hideContextMenu = function() {
1434
	if (this.idPull["polygon_"+this.idPrefix+this.topId] == null) return false;
1435
	this._clearAndHide();
1436
	this._hidePolygon(this.idPrefix+this.topId);
1437
	this.zInd = this.zIndInit;
1438
}
1439
/****************************************************************************************************************************************************/
1440 View Code Duplication
dhtmlXMenuObject.prototype._doOnContextBeforeCall = function(e, cZone) {
1441
	this.contextMenuZoneId = cZone.id;
1442
	this._clearAndHide();
1443
	this._hideContextMenu();
1444
	
1445
	// scroll settings
1446
	var p = (e.srcElement||e.target);
1447
	var px = (_isIE||_isOpera||_KHTMLrv?e.offsetX:e.layerX);
1448
	var py = (_isIE||_isOpera||_KHTMLrv?e.offsetY:e.layerY);
1449
	var mx = getAbsoluteLeft(p)+px;
1450
	var my = getAbsoluteTop(p)+py;
1451
	
1452
	if (this.checkEvent("onBeforeContextMenu")) {
1453
		if (this.callEvent("onBeforeContextMenu", [cZone.id,e])) {
1454
			if (this.contextAutoShow) {
1455
				this._showContextMenu(mx, my, cZone.id);
1456
				this.callEvent("onAfterContextMenu", [cZone.id,e]);
1457
			}
1458
		}
1459
	} else {
1460
		if (this.contextAutoShow) {
1461
			this._showContextMenu(mx, my, cZone.id);
1462
			this.callEvent("onAfterContextMenu", [cZone.id]);
1463
		}
1464
	}
1465
}
1466
/* public: user call for show/hide context menu */
1467
/**
1468
*   @desc: usercall to show a contextual menu
1469
*   @param: x - position of the menu on x axis
1470
*   @param: y - position of the menu on y axis
1471
*   @type: public
1472
*/
1473
dhtmlXMenuObject.prototype.showContextMenu = function(x, y) {
1474
	this._showContextMenu(x, y, false);
1475
}
1476
/**
1477
*   @desc: usercall to hide a contextual menu
1478
*   @type: public
1479
*/
1480
dhtmlXMenuObject.prototype.hideContextMenu = function() {
1481
	this._hideContextMenu();
1482
}
1483
dhtmlXMenuObject.prototype._autoDetectVisibleArea = function() {
1484
	if (this._isVisibleArea) return;
1485
	//
1486
	this.menuX1 = document.body.scrollLeft;
1487
	this.menuX2 = this.menuX1+(window.innerWidth||document.body.clientWidth);
1488
	this.menuY1 = Math.max((_isIE?document.documentElement:document.getElementsByTagName("html")[0]).scrollTop, document.body.scrollTop);
1489
	// this.menuY2 = this.menuY1+(_isIE?(document.documentElement?Math.max(document.documentElement.clientHeight:document.body.clientHeight):window.innerHeight);
1490
	this.menuY2 = this.menuY1+(_isIE?Math.max(document.documentElement.clientHeight||0,document.documentElement.offsetHeight||0,document.body.clientHeight||0):window.innerHeight);
1491
	
1492
}
1493
/* inner - returns true if prognozided polygon layout off the visible area */
1494
/*dhtmlXMenuObject.prototype._isInVisibleArea = function(x, y, w, h) {
1495
	return ((x >= this.menuX1) && (x+w<=this.menuX2) && (y >= this.menuY1) && (y+h <= this.menuY2));
1496
}*/
1497
1498
1499
//#}
1500
1501
/**
1502
*   @desc: returns item's position in the current polygon
1503
*   @param: id - the item
1504
*   @type: public
1505
*/
1506 View Code Duplication
dhtmlXMenuObject.prototype.getItemPosition = function(id) {
1507
	id = this.idPrefix+id;
1508
	var pos = -1;
1509
	if (this.itemPull[id] == null) return pos;
1510
	var parent = this.itemPull[id]["parent"];
1511
	// var obj = (this.idPull["polygon_"+parent]!=null?this.idPull["polygon_"+parent].tbd:this.base);
1512
	var obj = (this.idPull["polygon_"+parent]!=null?this.idPull["polygon_"+parent].tbd:this.cont);
1513
	for (var q=0; q<obj.childNodes.length; q++) { if (obj.childNodes[q]==this.idPull["separator_"+id]||obj.childNodes[q]==this.idPull[id]) { pos = q; } }
1514
	return pos;
1515
}
1516
1517
/**
1518
*   @desc: sets new item's position in the current polygon (moves an item inside the single level)
1519
*   @param: id - the item
1520
*   @param: pos - the position (int)
1521
*   @type: public
1522
*/
1523 View Code Duplication
dhtmlXMenuObject.prototype.setItemPosition = function(id, pos) {
1524
	id = this.idPrefix+id;
1525
	if (this.idPull[id] == null) { return; }
1526
	// added in 0.4
1527
	var isOnTopLevel = (this.itemPull[id]["parent"] == this.idPrefix+this.topId);
1528
	//
1529
	var itemData = this.idPull[id];
1530
	var itemPos = this.getItemPosition(id.replace(this.idPrefix,""));
1531
	var parent = this.itemPull[id]["parent"];
1532
	// var obj = (this.idPull["polygon_"+parent]!=null?this.idPull["polygon_"+parent].tbd:this.base);
1533
	var obj = (this.idPull["polygon_"+parent]!=null?this.idPull["polygon_"+parent].tbd:this.cont);
1534
	obj.removeChild(obj.childNodes[itemPos]);
1535
	if (pos < 0) pos = 0;
1536
	// added in 0.4
1537
	if (isOnTopLevel && pos < 1) { pos = 1; }
1538
	//
1539
	if (pos < obj.childNodes.length) { obj.insertBefore(itemData, obj.childNodes[pos]); } else { obj.appendChild(itemData); }
1540
}
1541
1542
/**
1543
*   @desc: returns parent's id
1544
*   @param: id - the item
1545
*   @type: public
1546
*/
1547
dhtmlXMenuObject.prototype.getParentId = function(id) {
1548
	id = this.idPrefix+id;
1549
	if (this.itemPull[id] == null) { return null; }
1550
	return ((this.itemPull[id]["parent"]!=null?this.itemPull[id]["parent"]:this.topId).replace(this.idPrefix,""));
1551
}
1552
/* public: add item */
1553
1554
/**
1555
*   @desc: adds a new sibling item
1556
*   @param: nextToId - id of the element after which a new one will be inserted
1557
*   @param: itemId - id of a new item
1558
*   @param: itemText - text of a new item
1559
*   @param: disabled - true|false, whether the item is disabled or not
1560
*   @param: img - image for the enabled item
1561
*   @param: imgDis - image for the disabled item
1562
*   @type: public
1563
*/
1564
dhtmlXMenuObject.prototype.addNewSibling = function(nextToId, itemId, itemText, disabled, imgEnabled, imgDisabled) {
1565
	var id = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1566
	var parentId = this.idPrefix+(nextToId!=null?this.getParentId(nextToId):this.topId);
1567
	// console.log(id, parentId)
1568
	// console.log(id, ",", parentId)
1569
	this._addItemIntoGlobalStrorage(id, parentId, itemText, "item", disabled, imgEnabled, imgDisabled);
1570
	if ((parentId == this.idPrefix+this.topId) && (!this.context)) {
1571
		this._renderToplevelItem(id, this.getItemPosition(nextToId));
1572
	} else {
1573
		this._renderSublevelItem(id, this.getItemPosition(nextToId));
1574
	}
1575
}
1576
1577
/**
1578
*   @desc: adds a new child item
1579
*   @param: parentId - the item which will contain a new item in the sublevel
1580
*   @param: position - the position of a new item
1581
*   @param: itemId - id of a new item
1582
*   @param: itemText - text of a new item
1583
*   @param: disabled - true|false, whether the item is disabled or not
1584
*   @param: img - image for the enabled item
1585
*   @param: imgDis - image for the disabled item
1586
*   @type: public
1587
*/
1588 View Code Duplication
dhtmlXMenuObject.prototype.addNewChild = function(parentId, pos, itemId, itemText, disabled, imgEnabled, imgDisabled) {
1589
	if (parentId == null) {
1590
		if (this.context) {
1591
			parentId = this.topId;
1592
		} else {
1593
			this.addNewSibling(parentId, itemId, itemText, disabled, imgEnabled, imgDisabled);
1594
			if (pos != null) this.setItemPosition(itemId, pos);
1595
			return;
1596
		}
1597
	}
1598
	itemId = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1599
	// remove hotkey, added in 0.4
1600
	if (this.setHotKey) this.setHotKey(parentId, "");
1601
	//
1602
	parentId = this.idPrefix+parentId;
1603
	this._addItemIntoGlobalStrorage(itemId, parentId, itemText, "item", disabled, imgEnabled, imgDisabled);
1604
	if (this.idPull["polygon_"+parentId] == null) { this._renderSublevelPolygon(parentId, parentId); }
1605
	this._renderSublevelItem(itemId, pos-1);
1606
	// console.log(parentId)
1607
	this._redefineComplexState(parentId);
1608
}
1609
1610
/* add item to storage */
1611 View Code Duplication
dhtmlXMenuObject.prototype._addItemIntoGlobalStrorage = function(itemId, itemParentId, itemText, itemType, disabled, img, imgDis) {
1612
	var item = {
1613
		id:	itemId,
1614
		title:	itemText,
1615
		imgen:	(img!=null?img:""),
1616
		imgdis:	(imgDis!=null?imgDis:""),
1617
		type:	itemType,
1618
		state:	(disabled==true?"disabled":"enabled"),
1619
		parent:	itemParentId,
1620
		complex:false,
1621
		hotkey:	"",
1622
		tip:	""};
1623
	this.itemPull[item.id] = item;
1624
}
1625
/* recursively creates and adds submenu polygon */
1626 View Code Duplication
dhtmlXMenuObject.prototype._addSubMenuPolygon = function(id, parentId) {
1627
	var s = this._renderSublevelPolygon(id, parentId);
1628
	var j = this._getMenuNodes(parentId);
1629
	for (q=0; q<j.length; q++) { if (this.itemPull[j[q]]["type"] == "separator") { this._renderSeparator(j[q], null); } else { this._renderSublevelItem(j[q], null); } }
1630
	if (id == parentId) { var level = "topLevel"; } else { var level = "subLevel"; }
1631
	for (var q=0; q<j.length; q++) { if (this.itemPull[j[q]]["complex"]) { this._addSubMenuPolygon(id, this.itemPull[j[q]]["id"]); } }
1632
}
1633
/* inner: add single subpolygon/item/separator */
1634 View Code Duplication
dhtmlXMenuObject.prototype._renderSublevelPolygon = function(id, parentId) {
1635
	var s = document.createElement("DIV");
1636
	s.className = "dhtmlxMenu_"+this.skin+"_SubLevelArea_Polygon "+(this._rtl?"dir_right":"");
1637
	s.dir = "ltr";
1638
	s.oncontextmenu = function(e) { e = e||event; e.returnValue = false; e.cancelBubble = true; return false; }
1639
	s.id = "polygon_" + parentId;
1640
	s.onclick = function(e) { e = e || event; e.cancelBubble = true; }
1641
	s.style.display = "none";
1642
	document.body.insertBefore(s, document.body.firstChild);
1643
	//
1644
	var tbl = document.createElement("TABLE");
1645
	tbl.className = "dhtmlxMebu_SubLevelArea_Tbl";
1646
	tbl.cellSpacing = 0;
1647
	tbl.cellPadding = 0;
1648
	tbl.border = 0;
1649
	var tbd = document.createElement("TBODY");
1650
	tbl.appendChild(tbd);
1651
	s.appendChild(tbl);
1652
	s.tbl = tbl;
1653
	s.tbd = tbd;
1654
	// polygon
1655
	this.idPull[s.id] = s;
1656
	if (this.sxDacProc != null) {
1657
		this.idPull["sxDac_" + parentId] = new this.sxDacProc(s, s.className);
1658
		if (_isIE) {
1659
			this.idPull["sxDac_" + parentId]._setSpeed(this.dacSpeedIE);
1660
			this.idPull["sxDac_" + parentId]._setCustomCycle(this.dacCyclesIE);
1661
		} else {
1662
			this.idPull["sxDac_" + parentId]._setSpeed(this.dacSpeed);
1663
			this.idPull["sxDac_" + parentId]._setCustomCycle(this.dacCycles);
1664
		}
1665
	}
1666
	return s;
1667
}
1668 View Code Duplication
dhtmlXMenuObject.prototype._renderSublevelItem = function(id, pos) {
1669
	var main_self = this;
1670
	
1671
	var tr = document.createElement("TR");
1672
	tr.className = (this.itemPull[id]["state"]=="enabled"?"sub_item":"sub_item_dis");
1673
	
1674
	// icon
1675
	var t1 = document.createElement("TD");
1676
	t1.className = "sub_item_icon";
1677
	var icon = this.itemPull[id][(this.itemPull[id]["state"]=="enabled"?"imgen":"imgdis")];
1678
	if (icon != "") {
1679
		var tp = this.itemPull[id]["type"];
1680
		if (tp=="checkbox"||tp=="radio") {
1681
			var img = document.createElement("DIV");
1682
			img.id = "image_"+this.itemPull[id]["id"];
1683
			img.className = "sub_icon "+icon;
1684
			t1.appendChild(img);
1685
		}
1686
		if (!(tp=="checkbox"||tp=="radio")) {
1687
			var img = document.createElement("IMG");
1688
			img.id = "image_"+this.itemPull[id]["id"];
1689
			img.className = "sub_icon";
1690
			img.src = this.imagePath+icon;
1691
			t1.appendChild(img);
1692
		}
1693
	}
1694
	
1695
	// text
1696
	var t2 = document.createElement("TD");
1697
	t2.className = "sub_item_text";
1698
	if (this.itemPull[id]["title"] != "") {
1699
		var t2t = document.createElement("DIV");
1700
		t2t.className = "sub_item_text";
1701
		t2t.innerHTML = this.itemPull[id]["title"];
1702
		t2.appendChild(t2t);
1703
	} else {
1704
		t2.innerHTML = "&nbsp;";
1705
	}
1706
	
1707
	// hotkey/sublevel arrow
1708
	var t3 = document.createElement("TD");
1709
	t3.className = "sub_item_hk";
1710
	if (this.itemPull[id]["complex"]) {
1711
		
1712
		var arw = document.createElement("DIV");
1713
		arw.className = "complex_arrow";
1714
		arw.id = "arrow_"+this.itemPull[id]["id"];
1715
		t3.appendChild(arw);
1716
		
1717
	} else {
1718
		if (this.itemPull[id]["hotkey"].length > 0 && !this.itemPull[id]["complex"]) {
1719
			var t3t = document.createElement("DIV");
1720
			t3t.className = "sub_item_hk";
1721
			t3t.innerHTML = this.itemPull[id]["hotkey"];
1722
			t3.appendChild(t3t);
1723
		} else {
1724
			t3.innerHTML = "&nbsp;";
1725
		}
1726
	}
1727
	tr.appendChild(this._rtl?t3:t1);
1728
	tr.appendChild(t2);
1729
	tr.appendChild(this._rtl?t1:t3);
1730
	
1731
	
1732
	//
1733
	tr.id = this.itemPull[id]["id"];
1734
	tr.parent = this.itemPull[id]["parent"];
1735
	// tooltip, added in 0.4
1736
	if (this.itemPull[id]["tip"].length > 0) tr.title = this.itemPull[id]["tip"];
1737
	//
1738
	if (!this._hideTMData) this._hideTMData = {};
1739
	
1740
	tr.onselectstart = function(e) { e = e || event; e.returnValue = false; return false; }
1741
	tr.onmouseover = function(e) {
1742
		if (main_self._hideTMData[this.id]) window.clearTimeout(main_self._hideTMData[this.id]);
1743
		if (main_self.menuMode == "web") window.clearTimeout(main_self.menuTimeoutHandler);
1744
		if (!this._visible) main_self._redistribSubLevelSelection(this.id, this.parent); // if not visible
1745
		this._visible = true;
1746
	}
1747
	tr.onmouseout = function() {
1748
		if (main_self.menuMode == "web") {
1749
			if (main_self.menuTimeoutHandler) window.clearTimeout(main_self.menuTimeoutHandler);
1750
			main_self.menuTimeoutHandler = window.setTimeout(function(){if(main_self&&main_self._clearAndHide)main_self._clearAndHide();}, main_self.menuTimeoutMsec, "JavaScript");
1751
		}
1752
		var k = this;
1753
		if (main_self._hideTMData[this.id]) window.clearTimeout(main_self._hideTMData[this.id]);
1754
		main_self._hideTMData[this.id] = window.setTimeout(function(){k._visible=false;}, 50);
1755
	}
1756
	tr.onclick = function(e) {
1757
		// added in 0.4, preven complex closing if user event not defined
1758
		if (!main_self.checkEvent("onClick") && main_self.itemPull[this.id]["complex"]) return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
1759
		//
1760
		e = e || event; e.cancelBubble = true;
1761
		e.returnValue = false;
1762
		tc = (main_self.itemPull[this.id]["complex"]?"c":"-");
1763
		td = (main_self.itemPull[this.id]["state"]=="enabled"?"-":"d");
1764
		var cas = {"ctrl": e.ctrlKey, "alt": e.altKey, "shift": e.shiftKey};
1765
		switch (main_self.itemPull[this.id]["type"]) {
1766
			case "checkbox":
1767
				main_self._checkboxOnClickHandler(this.id.replace(main_self.idPrefix, ""), tc+td+"n", cas);
1768
				break;
1769
			case "radio":
1770
				main_self._radioOnClickHandler(this.id.replace(main_self.idPrefix, ""), tc+td+"n", cas);
1771
				break;
1772
			case "item":
1773
				main_self._doOnClick(this.id.replace(main_self.idPrefix, ""), tc+td+"n", cas);
1774
				break;
1775
		}
1776
		return false;
1777
	}
1778
	// add
1779
	var polygon = this.idPull["polygon_"+this.itemPull[id]["parent"]];
1780
	if (pos != null) { pos++; if (pos < 0) pos = 0; if (pos > polygon.tbd.childNodes.length - 1) pos = null; }
1781
	if (pos != null && polygon.tbd.childNodes[pos] != null) polygon.tbd.insertBefore(tr, polygon.tbd.childNodes[pos]); else polygon.tbd.appendChild(tr);
1782
	this.idPull[tr.id] = tr;
1783
}
1784
/****************************************************************************************************************************************************/
1785
/*								 	SEPARATOR								    */
1786 View Code Duplication
dhtmlXMenuObject.prototype._renderSeparator = function(id, pos) {
1787
	var level = (this.context?"SubLevelArea":(this.itemPull[id]["parent"]==this.idPrefix+this.topId?"TopLevel":"SubLevelArea"));
1788
	if (level == "TopLevel" && this.context) return;
1789
	
1790
	var main_self = this;
1791
	
1792
	if (level != "TopLevel") {
1793
		var tr = document.createElement("TR");
1794
		tr.className = "sub_sep";
1795
		var td = document.createElement("TD");
1796
		td.colSpan = "3";
1797
		tr.appendChild(td);
1798
	}
1799
	
1800
	var k = document.createElement("DIV");
1801
	k.id = "separator_"+id;
1802
	k.className = (level=="TopLevel"?"top_sep":"sub_sep");
1803
	k.onselectstart = function(e) { e = e || event; e.returnValue = false; }
1804
	k.onclick = function(e) {
1805
		e = e || event; e.cancelBubble = true;
1806
		var cas = {"ctrl": e.ctrlKey, "alt": e.altKey, "shift": e.shiftKey};
1807
		main_self._doOnClick(this.id.replace("separator_" + main_self.idPrefix, ""), "--s", cas);
1808
	}
1809
	if (level == "TopLevel") {
1810
		if (pos != null) {
1811
			pos++; if (pos < 0) { pos = 0; }
1812
			// if (this.base.childNodes[pos] != null) { this.base.insertBefore(k, this.base.childNodes[pos]); } else { this.base.appendChild(k); }
1813
			if (this.cont.childNodes[pos] != null) { this.cont.insertBefore(k, this.cont.childNodes[pos]); } else { this.cont.appendChild(k); }
1814
		} else {
1815
			// add as a last item
1816
			// var last = this.base.childNodes[this.base.childNodes.length-1];
1817
			var last = this.cont.childNodes[this.cont.childNodes.length-1];
1818
			// if (String(last).search("TopLevel_Text") == -1) { this.base.appendChild(k); } else { this.base.insertBefore(k, last); }
1819
			if (String(last).search("TopLevel_Text") == -1) { this.cont.appendChild(k); } else { this.cont.insertBefore(k, last); }
1820
		}
1821
		this.idPull[k.id] = k;
1822
	} else {
1823
		var polygon = this.idPull["polygon_"+this.itemPull[id]["parent"]];
1824
		if (pos != null) { pos++; if (pos < 0) pos = 0; if (pos > polygon.tbd.childNodes.length - 1) pos = null; }
1825
		if (pos != null && polygon.tbd.childNodes[pos] != null) polygon.tbd.insertBefore(tr, polygon.tbd.childNodes[pos]); else polygon.tbd.appendChild(tr);
0 ignored issues
show
Bug introduced by
The variable tr does not seem to be initialized in case level != "TopLevel" on line 1792 is false. Are you sure the function insertBefore handles undefined variables?
Loading history...
1826
		td.appendChild(k);
0 ignored issues
show
Bug introduced by
The variable td does not seem to be initialized in case level != "TopLevel" on line 1792 is false. Are you sure this can never be the case?
Loading history...
1827
		this.idPull[k.id] = tr;
1828
	}
1829
}
1830
/**
1831
*   @desc: add a new separator
1832
*   @param: nextToId - id of the element after which a new separator will be inserted
1833
*   @param: itemId - id of a new separator
1834
*   @type: public
1835
*/
1836
dhtmlXMenuObject.prototype.addNewSeparator = function(nextToId, itemId) { //, disabled) {
1837
	itemId = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
1838
	var parentId = this.idPrefix+this.getParentId(nextToId);
1839
	// if ((parentId == this.idPrefix+this.topId) && (!this.context)) { return; }
1840
	// this._addItemIntoGlobalStrorage(itemId, parentId, "", "item", disabled, "", "");
1841
	// this._addItemIntoGlobalStrorage(itemId, parentId, "", "item", false, "", "");
1842
	this._addItemIntoGlobalStrorage(itemId, parentId, "", "separator", false, "", "");
1843
	this._renderSeparator(itemId, this.getItemPosition(nextToId));
1844
}
1845
/****************************************************************************************************************************************************/
1846
// hide any opened polygons
1847
/**
1848
*   @desc: hides any open menu polygons
1849
*   @type: public
1850
*/
1851
dhtmlXMenuObject.prototype.hide = function() {
1852
	this._clearAndHide();
1853
}
1854
/**
1855
*   @desc: clear all loaded items
1856
*   @type: public
1857
*/
1858
dhtmlXMenuObject.prototype.clearAll = function() {
1859
	/*
1860
	for (var a in this.itemPull) {
1861
		if (this.itemPull[a]["parent"] == this.idPrefix+this.topId) {
1862
			this.removeItem(String(a).replace(this.idPrefix,""));
1863
		}
1864
	}
1865
	*/
1866
	this.removeItem(this.idPrefix+this.topId, true);
1867
	this._isInited = false;
1868
	this.idPrefix = this._genStr(12);
1869
	this.itemPull = {};
1870
}
1871
/****************************************************************************************************************************************************/
1872
/**
1873
*   @desc: unloads menu from page (destructor)
1874
*   @type: public
1875
*/
1876 View Code Duplication
dhtmlXMenuObject.prototype.unload = function() {
1877
	
1878
	if (typeof(window.addEventListener) == "function") {
1879
		window.removeEventListener("click", this._bodyClick, false);
1880
		window.removeEventListener("contextmenu", this._bodyContext, false);
1881
	} else {
1882
		document.body.detachEvent("onclick", this._bodyClick);
1883
		document.body.detachEvent("oncontextmenu", this._bodyContext);
1884
	}
1885
	this._bodyClick = null;
1886
	this._bodyContext = null;
1887
	
1888
	// will recursively remove all items
1889
	this.removeItem(this.idPrefix+this.topId, true);
1890
	
1891
	this.itemPull = null;
1892
	this.idPull = null;
1893
	
1894
	// clear context zones
1895
	if (this.context) for (var a in this.contextZones) this.removeContextZone(a);
1896
	
1897
	if (this.cont != null) {
1898
		this.cont.className = "";
1899
		this.cont.parentNode.removeChild(this.cont);
1900
		this.cont = null;
1901
	}
1902
	
1903
	if (this.base != null) {
1904
		this.base.className = "";
1905
		if (!this.context) this.base.oncontextmenu = (this.base._oldContextMenuHandler||null);
1906
		this.base.onselectstart = null;
1907
		this.base = null;
1908
	}
1909
	this.setSkin = null;
1910
	
1911
	this.detachAllEvents();
1912
	
1913
	if (this._xmlLoader) {
1914
		this._xmlLoader.destructor();
1915
		this._xmlLoader = null;
1916
	}
1917
	
1918
	this._align = null;
1919
	this._arrowFFFix = null;
1920
	this._isIE6 = null;
1921
	this._isInited = null;
1922
	this._rtl = null;
1923
	this._scrollDownTMStep = null;
1924
	this._scrollDownTMTime = null;
1925
	this._scrollUpTMStep = null;
1926
	this._scrollUpTMTime = null;
1927
	this._topLevelBottomMargin = null;
1928
	this._topLevelOffsetLeft = null;
1929
	this._topLevelBottomMargin = null;
1930
	this._topLevelRightMargin = null;
1931
	this.addBaseIdAsContextZone = null;
1932
	this.context = null;
1933
	this.contextAutoHide = null;
1934
	this.contextAutoShow = null;
1935
	this.contextHideAllMode = null;
1936
	this.contextMenuZoneId = null;
1937
	this.dLoad = null;
1938
	this.dLoadSign = null;
1939
	this.dLoadUrl = null;
1940
	this.loaderIcon = null;
1941
	this.fixedPosition = null;
1942
	this.dirSubLevel = null;
1943
	this.dirTopLevel = null;
1944
	this.limit = null;
1945
	this.menuSelected = null;
1946
	this.menuLastClicked = null;
1947
	this.idPrefix = null;
1948
	this.imagePath = null;
1949
	this.menuMode = null;
1950
	this.menuModeTopLevelTimeout = null;
1951
	this.menuModeTopLevelTimeoutTime = null;
1952
	this.menuTimeoutHandler = null;
1953
	this.menuTimeoutMsec = null;
1954
	this.menuTouched = null;
1955
	this.isDhtmlxMenuObject = null;
1956
	this.itemHotKeyTagName = null;
1957
	this.itemHrefTagName = null;
1958
	this.itemTagName = null;
1959
	this.itemTextTagName = null;
1960
	this.itemTipTagName = null;
1961
	this.userDataTagName = null;
1962
	this.skin = null;
1963
	this.topId = null;
1964
	this.dacCycles = null;
1965
	this.dacCyclesIE = null;
1966
	this.dacSpeed = null;
1967
	this.dacSpeedIE = null;
1968
	this.zInd = null;
1969
	this.zIndInit = null;
1970
	this.zIndStep = null;
1971
	
1972
	//
1973
	// unload basic methods
1974
	
1975
	this._enableDacSupport = null;
1976
	this._selectedSubItems = null;
1977
	this._openedPolygons = null;
1978
	this._addSubItemToSelected = null;
1979
	this._removeSubItemFromSelected = null;
1980
	this._getSubItemToDeselectByPolygon = null;
1981
	this._hidePolygon = null;
1982
	this._showPolygon = null;
1983
	this._redistribSubLevelSelection = null;
1984
	this._doOnClick = null;
1985
	this._doOnTouchMenu = null;
1986
	this._searchMenuNode = null;
1987
	this._getMenuNodes = null;
1988
	this._genStr = null;
1989
	this._clearAndHide = null;
1990
	this._doOnLoad = null;
1991
	this.getItemType = null;
1992
	this.forEachItem = null;
1993
	this.init = null;
1994
	this.loadXML = null;
1995
	this.loadXMLString = null;
1996
	this._buildMenu = null;
1997
	this._xmlParser = null;
1998
	this._showSubLevelItem = null;
1999
	this._hideSubLevelItem = null;
2000
	this._countVisiblePolygonItems = null;
2001
	this._redefineComplexState = null;
2002
	this._updateItemComplexState = null;
2003
	this._getItemLevelType = null;
2004
	this._redistribTopLevelSelection = null;
2005
	this._initTopLevelMenu = null;
2006
	this._renderToplevelItem = null;
2007
	this.setImagePath = null;
2008
	this.setIconsPath = null;
2009
	this.setIconPath = null;
2010
	this._updateItemImage = null;
2011
	this.removeItem = null;
2012
	this._getAllParents = null;
2013
	this.renderAsContextMenu = null;
2014
	this.addContextZone = null;
2015
	this.removeContextZone = null;
2016
	this.isContextZone = null;
2017
	this._isContextMenuVisible = null;
2018
	this._showContextMenu = null;
2019
	this._doOnContextBeforeCall = null;
2020
	this._autoDetectVisibleArea = null;
2021
	this._addItemIntoGlobalStrorage = null;
2022
	this._addSubMenuPolygon = null;
2023
	this._renderSublevelPolygon = null;
2024
	this._renderSublevelItem = null;
2025
	this._renderSeparator = null;
2026
	this._hideContextMenu = null;
2027
	this.clearAll = null;
2028
	this.getItemPosition = null;
2029
	this.setItemPosition = null;
2030
	this.getParentId = null;
2031
	this.addNewSibling = null;
2032
	this.addNewChild = null;
2033
	this.addNewSeparator = null;
2034
	this.attachEvent = null;
2035
	this.callEvent = null;
2036
	this.checkEvent = null;
2037
	this.eventCatcher = null;
2038
	this.detachEvent = null;
2039
	this.dhx_Event = null;
2040
	this.unload = null;
2041
	this.items = null;
2042
	this.radio = null;
2043
	this.detachAllEvents = null;
2044
	this.hide = null;
2045
	this.showContextMenu = null;
2046
	this.hideContextMenu = null;
2047
	
2048
	
2049
	// unload extended methods
2050
	this._changeItemState = null;
2051
	this._changeItemVisible = null;
2052
	this._updateLoaderIcon = null;
2053
	this._clearAllSelectedSubItemsInPolygon = null;
2054
	this._checkArrowsState = null;
2055
	this._addUpArrow = null;
2056
	this._addDownArrow = null;
2057
	this._removeUpArrow = null;
2058
	this._removeDownArrow = null;
2059
	this._isArrowExists = null;
2060
	this._doScrollUp = null;
2061
	this._doScrollDown = null;
2062
	this._countPolygonItems = null;
2063
	this._getRadioImgObj = null;
2064
	this._setRadioState = null;
2065
	this._radioOnClickHandler = null;
2066
	this._getCheckboxState = null;
2067
	this._setCheckboxState = null;
2068
	this._readLevel = null;
2069
	this._updateCheckboxImage = null;
2070
	this._checkboxOnClickHandler = null;
2071
	this._removeArrow = null;
2072
	this.setItemEnabled = null;
2073
	this.setItemDisabled = null;
2074
	this.isItemEnabled = null;
2075
	this.getItemText = null;
2076
	this.setItemText = null;
2077
	this.loadFromHTML = null;
2078
	this.hideItem = null;
2079
	this.showItem = null;
2080
	this.isItemHidden = null;
2081
	this.setUserData = null;
2082
	this.getUserData = null;
2083
	this.setOpenMode = null;
2084
	this.setWebModeTimeout = null;
2085
	this.enableDynamicLoading = null;
2086
	this.getItemImage = null;
2087
	this.setItemImage = null;
2088
	this.clearItemImage = null;
2089
	this.setAutoShowMode = null;
2090
	this.setAutoHideMode = null;
2091
	this.setContextMenuHideAllMode = null;
2092
	this.getContextMenuHideAllMode = null;
2093
	this.setVisibleArea = null;
2094
	this.setTooltip = null;
2095
	this.getTooltip = null;
2096
	this.setHotKey = null;
2097
	this.getHotKey = null;
2098
	this.setItemSelected = null;
2099
	this.setTopText = null;
2100
	this.setRTL = null;
2101
	this.setAlign = null;
2102
	this.setHref = null;
2103
	this.clearHref = null;
2104
	this.getCircuit = null;
2105
	this.contextZones = null;
2106
	this.setOverflowHeight = null;
2107
	this.userData = null;
2108
	this.getRadioChecked = null;
2109
	this.setRadioChecked = null;
2110
	this.addRadioButton = null;
2111
	this.setCheckboxState = null;
2112
	this.getCheckboxState = null;
2113
	this.addCheckbox = null;
2114
	this.serialize = null;
2115
	
2116
	
2117
	this.extendedModule = null;
2118
	
2119
	// remove menu from global store
2120
	dhtmlxMenuObjectLiveInstances[this._UID] = null;
2121
	try { delete dhtmlxMenuObjectLiveInstances[this._UID]; } catch(e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
2122
	this._UID = null;
2123
	
2124
}
2125
// dhtmlxmenu global store
2126
var dhtmlxMenuObjectLiveInstances = {};
2127
2128
dhtmlXMenuObject.prototype.i18n = {
2129
	dhxmenuextalert: "dhtmlxmenu_ext.js required"
2130
};
2131
2132
//menu
2133 View Code Duplication
(function(){
2134
	dhtmlx.extend_api("dhtmlXMenuObject",{
2135
		_init:function(obj){
2136
			return [obj.parent, obj.skin];
2137
		},
2138
		align:"setAlign",
2139
		top_text:"setTopText",
2140
		context:"renderAsContextMenu",
2141
		icon_path:"setIconsPath",
2142
		open_mode:"setOpenMode",
2143
		rtl:"setRTL",
2144
		skin:"setSkin",
2145
		dynamic:"enableDynamicLoading",
2146
		xml:"loadXML",
2147
		items:"items",
2148
		overflow:"setOverflowHeight"
2149
	},{
2150
		items:function(arr,parent){
2151
			var pos = 100000;
2152
			var lastItemId = null;
2153
			for (var i=0; i < arr.length; i++) {
2154
				var item=arr[i];
2155
				if (item.type == "separator") {
2156
					this.addNewSeparator(lastItemId, pos, item.id);
2157
					lastItemId = item.id;
2158
				} else {
2159
					this.addNewChild(parent, pos, item.id, item.text, item.disabled, item.img, item.img_disabled);
2160
					lastItemId = item.id;
2161
					if (item.items) this.items(item.items,item.id);
2162
				}
2163
			}
2164
		}
2165
	});
2166
})();
2167
2168
// terrace
2169
dhtmlXMenuObject.prototype._improveTerraceSkin = function() {
2170
	
2171
	for (var a in this.itemPull) {
2172
		
2173
		if (this.itemPull[a].parent == this.idPrefix+this.topId && this.idPull[a] != null) { // this.idPull[a] will null for separator
2174
			
2175
			var bl = false;
2176
			var br = false;
2177
			
2178
			// left side, first item, not sep
2179
			if (this.idPull[a].parentNode.firstChild == this.idPull[a]) {
2180
				bl = true;
2181
			}
2182
			
2183
			// right side, last item, not sep
2184
			if (this.idPull[a].parentNode.lastChild == this.idPull[a]) {
2185
				br = true;
2186
			}
2187
			
2188
			// check siblings
2189
			for (var b in this.itemPull) {
2190
				if (this.itemPull[b].type == "separator" && this.itemPull[b].parent == this.idPrefix+this.topId) {
2191
					if (this.idPull[a].nextSibling == this.idPull["separator_"+b]) {
2192
						br = true;
2193
					}
2194
					if (this.idPull[a].previousSibling == this.idPull["separator_"+b]) {
2195
						bl = true;
2196
					}
2197
				}
2198
			}
2199
			
2200
			this.idPull[a].style.borderLeft = (bl?"1px solid #cecece":"0px solid white");
2201
			this.idPull[a].style.borderTopLeftRadius = this.idPull[a].style.borderBottomLeftRadius = (bl?"5px":"0px");
2202
			
2203
			this.idPull[a].style.borderTopRightRadius = this.idPull[a].style.borderBottomRightRadius = (br?"5px":"0px");
2204
			
2205
			this.idPull[a]._bl = bl;
2206
			this.idPull[a]._br = br;
2207
			
2208
		}
2209
	}
2210
	
2211
};
2212
2213
dhtmlXMenuObject.prototype._improveTerraceButton = function(id, state) {
2214
	if (state) {
2215
		this.idPull[id].style.borderBottomLeftRadius = (this.idPull[id]._bl ? "5px" : "0px");
2216
		this.idPull[id].style.borderBottomRightRadius = (this.idPull[id]._br ? "5px" : "0px");
2217
	} else {
2218
		this.idPull[id].style.borderBottomLeftRadius = "0px";
2219
		this.idPull[id].style.borderBottomRightRadius = "0px";
2220
	}
2221
};