PageSourceSearch

https://web.rosknroll.fi/rosknroll/js/dhtmlxSuite/sources/dhtmlxMenu/codebase/ext/dhtmlxmenu_ext.js

js rosknroll.fi collected 2026-09-26 03:00:22 UTC 27,725 bytes, 769 lines download raw bytes

1/*
2Product Name: dhtmlxSuite 
3Version: 5.1.0 
4Edition: Professional 
5License: content of this file is covered by DHTMLX Commercial or Enterprise license. Usage without proper license is prohibited. To obtain it contact [email protected]
6Copyright UAB Dinamenta http://www.dhtmlx.com
7*/
8
9// enable/disable
10
11dhtmlXMenuObject.prototype.setItemEnabled = function(id) {
12	this._changeItemState(id, "enabled", this._getItemLevelType(id));
13};
14dhtmlXMenuObject.prototype.setItemDisabled = function(id) {
15	this._changeItemState(id, "disabled", this._getItemLevelType(id));
16};
17dhtmlXMenuObject.prototype.isItemEnabled = function(id) {
18	return (this.itemPull[this.idPrefix+id]!=null?(this.itemPull[this.idPrefix+id]["state"]=="enabled"):false);
19};
20
21// enable/disable sublevel item
22dhtmlXMenuObject.prototype._changeItemState = function(id, newState, levelType) {
23	var t = false;
24	var j = this.idPrefix + id;
25	if ((this.itemPull[j] != null) && (this.idPull[j] != null)) {
26		if (this.itemPull[j]["state"] != newState) {
27			this.itemPull[j]["state"] = newState;
28			if (this.itemPull[j]["parent"] == this.idPrefix+this.topId && !this.conf.context) {
29				this.idPull[j].className = "dhtmlxMenu_"+this.conf.skin+"_TopLevel_Item_"+(this.itemPull[j]["state"]=="enabled"?"Normal":"Disabled");
30			} else {
31				this.idPull[j].className = "sub_item"+(this.itemPull[j]["state"]=="enabled"?"":"_dis");
32			}
33			
34			this._updateItemComplexState(this.idPrefix+id, this.itemPull[this.idPrefix+id]["complex"], false);
35			this._updateItemImage(id, levelType);
36			// if changeItemState attached to onClick event and changing applies to selected item all selection should be reparsed
37			if ((this.idPrefix + this.conf.last_click == j) && (levelType != "TopLevel")) {
38				this._redistribSubLevelSelection(j, this.itemPull[j]["parent"]);
39			}
40			if (levelType == "TopLevel" && !this.conf.context) { // rebuild style.left and show nested polygons
41				// this._redistribTopLevelSelection(id, "parent");
42			}
43		}
44	}
45	return t;
46};
47
48
49// set-get text
50dhtmlXMenuObject.prototype.getItemText = function(id) {
51	return (this.itemPull[this.idPrefix+id]!=null?this.itemPull[this.idPrefix+id]["title"]:"");
52};
53
54dhtmlXMenuObject.prototype.setItemText = function(id, text) {
55	id = this.idPrefix + id;
56	if ((this.itemPull[id] != null) && (this.idPull[id] != null)) {
57		this._clearAndHide();
58		this.itemPull[id]["title"] = text;
59		if (this.itemPull[id]["parent"] == this.idPrefix+this.topId && !this.conf.context) {
60			// top level
61			var tObj = null;
62			for (var q=0; q<this.idPull[id].childNodes.length; q++) {
63				try { if (this.idPull[id].childNodes[q].className == "top_level_text") tObj = this.idPull[id].childNodes[q]; } catch(e) {}
64			}
65			if (String(this.itemPull[id]["title"]).length == "" || this.itemPull[id]["title"] == null) {
66				if (tObj != null) tObj.parentNode.removeChild(tObj);
67			} else {
68				if (!tObj) {
69					tObj = document.createElement("DIV");
70					tObj.className = "top_level_text";
71					if (this.conf.rtl && this.idPull[id].childNodes.length > 0) this.idPull[id].insertBefore(tObj,this.idPull[id].childNodes[0]); else this.idPull[id].appendChild(tObj);
72				}
73				tObj.innerHTML = this.itemPull[id]["title"];
74			}
75		} else {
76			// sub level
77			var tObj = null;
78			for (var q=0; q<this.idPull[id].childNodes[1].childNodes.length; q++) {
79				if (String(this.idPull[id].childNodes[1].childNodes[q].className||"") == "sub_item_text") tObj = this.idPull[id].childNodes[1].childNodes[q];
80			}
81			if (String(this.itemPull[id]["title"]).length == "" || this.itemPull[id]["title"] == null) {
82				if (tObj) {
83					tObj.parentNode.removeChild(tObj);
84					tObj = null;
85					this.idPull[id].childNodes[1].innerHTML = "&nbsp;";
86				}
87			} else {
88				if (!tObj) {
89					tObj = document.createElement("DIV");
90					tObj.className = "sub_item_text";
91					this.idPull[id].childNodes[1].innerHTML = "";
92					this.idPull[id].childNodes[1].appendChild(tObj);
93				}
94				tObj.innerHTML = this.itemPull[id]["title"];
95			}
96		}
97	}
98};
99
100// load from html
101dhtmlXMenuObject.prototype.loadFromHTML = function(objId, clearAfterAdd, onLoad) {
102	
103	var t = this.conf.tags.item;
104	this.conf.tags.item = "div";
105	
106	var node = (typeof(objId)=="string"?document.getElementById(objId):objId);
107	var items = this._xmlToJson(node, this.idPrefix+this.topId);
108	this._initObj(items);
109	
110	this.conf.tags.item = t;
111	
112	if (clearAfterAdd) node.parentNode.removeChild(node);
113	node = objOd = null;
114	
115	if (onload != null) {
116		if (typeof(onLoad) == "function") {
117			onLoad();
118		} else if (typeof(window[onLoad]) == "function") {
119			window[onLoad]();
120		}
121	}
122};
123
124// show/hide items
125dhtmlXMenuObject.prototype.hideItem = function(id) {
126	this._changeItemVisible(id, false);
127};
128
129dhtmlXMenuObject.prototype.showItem = function(id) {
130	this._changeItemVisible(id, true);
131};
132
133dhtmlXMenuObject.prototype.isItemHidden = function(id) {
134	var isHidden = null;
135	if (this.idPull[this.idPrefix+id] != null) { isHidden = (this.idPull[this.idPrefix+id].style.display == "none"); }
136	return isHidden;
137};
138
139dhtmlXMenuObject.prototype._changeItemVisible = function(id, visible) {
140	var itemId = this.idPrefix+id;
141	if (this.itemPull[itemId] == null) return;
142	if (this.itemPull[itemId]["type"] == "separator") { itemId = "separator_"+itemId; }
143	if (this.idPull[itemId] == null) return;
144	this.idPull[itemId].style.display = (visible?"":"none");
145	this._redefineComplexState(this.itemPull[this.idPrefix+id]["parent"]);
146};
147
148// userdata
149dhtmlXMenuObject.prototype.setUserData = function(id, name, value) {
150	this.userData[this.idPrefix+id+"_"+name] = value;
151};
152
153dhtmlXMenuObject.prototype.getUserData = function(id, name) {
154	return (this.userData[this.idPrefix+id+"_"+name]!=null?this.userData[this.idPrefix+id+"_"+name]:null);
155};
156
157// open-mode (win/web)
158dhtmlXMenuObject.prototype.setOpenMode = function(mode) {
159	this.conf.mode = (mode=="win"?"win":"web");
160};
161
162// web-mode timeout
163dhtmlXMenuObject.prototype.setWebModeTimeout = function(tm) {
164	this.conf.tm_sec = (!isNaN(tm)?tm:400);
165};
166
167// icons
168dhtmlXMenuObject.prototype.getItemImage = function(id) {
169	var imgs = new Array(null, null);
170	id = this.idPrefix+id;
171	if (this.itemPull[id]["type"] == "item") {
172		imgs[0] = this.itemPull[id]["imgen"];
173		imgs[1] = this.itemPull[id]["imgdis"];
174	}
175	return imgs;
176};
177
178dhtmlXMenuObject.prototype.setItemImage = function(id, img, imgDis) {
179	if (this.itemPull[this.idPrefix+id]["type"] != "item") return;
180	this.itemPull[this.idPrefix+id]["imgen"] = img;
181	this.itemPull[this.idPrefix+id]["imgdis"] = imgDis;
182	this._updateItemImage(id, this._getItemLevelType(id));
183};
184
185dhtmlXMenuObject.prototype.clearItemImage = function(id) {
186	this.setItemImage(id, "", "");
187};
188
189// visible area
190dhtmlXMenuObject.prototype.setVisibleArea = function(x1, x2, y1, y2) {
191	this.conf.v_enabled = true;
192	this.conf.v.x1 = x1;
193	this.conf.v.x2 = x2;
194	this.conf.v.y1 = y1;
195	this.conf.v.y2 = y2;
196};
197
198// tooltips
199dhtmlXMenuObject.prototype.setTooltip = function(id, tip) {
200	id = this.idPrefix+id;
201	if (!(this.itemPull[id] != null && this.idPull[id] != null)) return;
202	this.idPull[id].title = (tip.length > 0 ? tip : null);
203	this.itemPull[id]["tip"] = tip;
204};
205
206dhtmlXMenuObject.prototype.getTooltip = function(id) {
207	if (this.itemPull[this.idPrefix+id] == null) return null;
208	return this.itemPull[this.idPrefix+id]["tip"];
209};
210
211
212
213dhtmlXMenuObject.prototype.setTopText = function(text) {
214	if (this.conf.context) return;
215	if (this._topText == null) {
216		this._topText = document.createElement("DIV");
217		this._topText.className = "dhtmlxMenu_TopLevel_Text_"+(this.conf.rtl?"left":(this.conf.align=="left"?"right":"left"));
218		this.base.appendChild(this._topText);
219	}
220	this._topText.innerHTML = text;
221};
222
223dhtmlXMenuObject.prototype.setAlign = function(align) {
224	if (this.conf.align == align) return;
225	if (align == "left" || align == "right") {
226		// if (this.setRTL) this.setRTL(false);
227		this.conf.align = align;
228		if (this.cont) this.cont.className = (this.conf.align=="right"?"align_right":"align_left");
229		if (this._topText != null) this._topText.className = "dhtmlxMenu_TopLevel_Text_"+(this.conf.align=="left"?"right":"left");
230	}
231};
232
233dhtmlXMenuObject.prototype.setHref = function(itemId, href, target) {
234	if (this.itemPull[this.idPrefix+itemId] == null) return;
235	this.itemPull[this.idPrefix+itemId]["href_link"] = href;
236	if (target != null) this.itemPull[this.idPrefix+itemId]["href_target"] = target;
237};
238
239dhtmlXMenuObject.prototype.clearHref = function(itemId) {
240	if (this.itemPull[this.idPrefix+itemId] == null) return;
241	delete this.itemPull[this.idPrefix+itemId]["href_link"];
242	delete this.itemPull[this.idPrefix+itemId]["href_target"];
243};
244/*
245File [id="file"] -> Open [id="open"] -> Last Save [id="lastsave"]
246getCircuit("lastsave") will return Array("file", "open", "lastsave");
247*/
248
249dhtmlXMenuObject.prototype.getCircuit = function(id) {
250	var parents = new Array(id);
251	while (this.getParentId(id) != this.topId) {
252		id = this.getParentId(id);
253		parents[parents.length] = id;
254	}
255	return parents.reverse();
256};
257
258// checkboxes
259dhtmlXMenuObject.prototype._getCheckboxState = function(id) {
260	if (this.itemPull[this.idPrefix+id] == null) return null;
261	return this.itemPull[this.idPrefix+id]["checked"];
262};
263
264dhtmlXMenuObject.prototype._setCheckboxState = function(id, state) {
265	if (this.itemPull[this.idPrefix+id] == null) return;
266	this.itemPull[this.idPrefix+id]["checked"] = state;
267};
268
269dhtmlXMenuObject.prototype._updateCheckboxImage = function(id) {
270	if (this.idPull[this.idPrefix+id] == null) return;
271	this.itemPull[this.idPrefix+id]["imgen"] = "chbx_"+(this._getCheckboxState(id)?"1":"0");
272	this.itemPull[this.idPrefix+id]["imgdis"] = this.itemPull[this.idPrefix+id]["imgen"];
273	try { this.idPull[this.idPrefix+id].childNodes[(this.conf.rtl?2:0)].childNodes[0].className = "sub_icon "+this.itemPull[this.idPrefix+id]["imgen"]; } catch(e){}
274};
275
276dhtmlXMenuObject.prototype._checkboxOnClickHandler = function(id, type, casState) {
277	if (type.charAt(1)=="d") return;
278	if (this.itemPull[this.idPrefix+id] == null) return;
279	var state = this._getCheckboxState(id);
280	if (this.checkEvent("onCheckboxClick")) {
281		if (this.callEvent("onCheckboxClick", [id, state, this.conf.ctx_zoneid, casState])) {
282			this.setCheckboxState(id, !state);
283		}
284	} else {
285		this.setCheckboxState(id, !state);
286	}
287	// call onClick if exists
288	if (this.checkEvent("onClick")) this.callEvent("onClick", [id]);
289};
290
291dhtmlXMenuObject.prototype.setCheckboxState = function(id, state) {
292	this._setCheckboxState(id, state);
293	this._updateCheckboxImage(id);
294};
295
296dhtmlXMenuObject.prototype.getCheckboxState = function(id) {
297	return this._getCheckboxState(id);
298};
299
300dhtmlXMenuObject.prototype.addCheckbox = function(mode, nextToId, pos, itemId, itemText, state, disabled) {
301	// checks
302	if (this.conf.context && nextToId == this.topId) {
303		// adding checkbox as first element to context menu
304		// do nothing
305	} else {
306		if (this.itemPull[this.idPrefix+nextToId] == null) return;
307		if (mode == "child" && this.itemPull[this.idPrefix+nextToId]["type"] != "item") return;
308	}
309	//
310	var img = "chbx_"+(state?"1":"0");
311	var imgDis = img;
312	//
313	
314	if (mode == "sibling") {
315		
316		var id = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
317		var parentId = this.idPrefix+this.getParentId(nextToId);
318		this._addItemIntoGlobalStrorage(id, parentId, itemText, "checkbox", disabled, img, imgDis);
319		this.itemPull[id]["checked"] = state;
320		this._renderSublevelItem(id, this.getItemPosition(nextToId));
321	} else {
322		
323		var id = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
324		var parentId = this.idPrefix+nextToId;
325		this._addItemIntoGlobalStrorage(id, parentId, itemText, "checkbox", disabled, img, imgDis);
326		this.itemPull[id]["checked"] = state;
327		if (this.idPull["polygon_"+parentId] == null) { this._renderSublevelPolygon(parentId, parentId); }
328		this._renderSublevelItem(id, pos-1);
329		this._redefineComplexState(parentId);
330	}
331};
332
333
334// hot-keys
335dhtmlXMenuObject.prototype.setHotKey = function(id, hkey) {
336	
337	id = this.idPrefix+id;
338	
339	if (!(this.itemPull[id] != null && this.idPull[id] != null)) return;
340	if (this.itemPull[id]["parent"] == this.idPrefix+this.topId && !this.conf.context) return;
341	if (this.itemPull[id]["complex"]) return;
342	var t = this.itemPull[id]["type"];
343	if (!(t == "item" || t == "checkbox" || t == "radio")) return;
344	
345	// retrieve obj
346	var hkObj = null;
347	try { if (this.idPull[id].childNodes[this.conf.rtl?0:2].childNodes[0].className == "sub_item_hk") hkObj = this.idPull[id].childNodes[this.conf.rtl?0:2].childNodes[0]; } catch(e){}
348	
349	if (hkey.length == 0) {
350		// remove if exists
351		this.itemPull[id]["hotkey_backup"] = this.itemPull[id]["hotkey"];
352		this.itemPull[id]["hotkey"] = "";
353		if (hkObj != null) hkObj.parentNode.removeChild(hkObj);
354		
355	} else {
356		
357		// add if needed or change
358		this.itemPull[id]["hotkey"] = hkey;
359		this.itemPull[id]["hotkey_backup"] = null;
360		//
361		if (hkObj == null) {
362			hkObj = document.createElement("DIV");
363			hkObj.className = "sub_item_hk";
364			var item = this.idPull[id].childNodes[this.conf.rtl?0:2];
365			while (item.childNodes.length > 0) item.removeChild(item.childNodes[0]);
366			item.appendChild(hkObj);
367		}
368		hkObj.innerHTML = hkey;
369
370	}
371};
372
373dhtmlXMenuObject.prototype.getHotKey = function(id) {
374	if (this.itemPull[this.idPrefix+id] == null) return null;
375	return this.itemPull[this.idPrefix+id]["hotkey"];
376};
377
378
379// overflow control
380dhtmlXMenuObject.prototype._clearAllSelectedSubItemsInPolygon = function(polygon) {
381	var subIds = this._getSubItemToDeselectByPolygon(polygon);
382	// hide opened polygons and selected items
383	for (var q=0; q<this.conf.opened_poly.length; q++) {
384		if (this.conf.opened_poly[q] != polygon) this._hidePolygon(this.conf.opened_poly[q]);
385	}
386	for (var q=0; q<subIds.length; q++) {
387		if (this.idPull[subIds[q]] != null && this.itemPull[subIds[q]]["state"] == "enabled") {
388			this.idPull[subIds[q]].className = "dhtmlxMenu_"+this.conf.skin+"_SubLevelArea_Item_Normal";
389		}
390	}
391};
392
393// define normal/disabled arrows in polygon
394dhtmlXMenuObject.prototype._checkArrowsState = function(id) {
395	var polygon = this.idPull["polygon_"+id].childNodes[1];
396	var arrowUp = this.idPull["arrowup_"+id];
397	var arrowDown = this.idPull["arrowdown_"+id];
398	if (polygon.scrollTop == 0) {
399		arrowUp.className = "dhtmlxMenu_"+this.conf.skin+"_SubLevelArea_ArrowUp_Disabled";
400	} else {
401		arrowUp.className = "dhtmlxMenu_"+this.conf.skin+"_SubLevelArea_ArrowUp" + (arrowUp.over ? "_Over" : "");
402	}
403	if (polygon.scrollTop + polygon.offsetHeight < polygon.scrollHeight) {
404		arrowDown.className = "dhtmlxMenu_"+this.conf.skin+"_SubLevelArea_ArrowDown" + (arrowDown.over ? "_Over" : "");
405	} else {
406		arrowDown.className = "dhtmlxMenu_"+this.conf.skin+"_SubLevelArea_ArrowDown_Disabled";
407	}
408	polygon = arrowUp = arrowDown = null;
409};
410
411// add up-limit-arrow
412dhtmlXMenuObject.prototype._addUpArrow = function(id) {
413	var that = this;
414	var arrow = document.createElement("DIV");
415	arrow.pId = this.idPrefix+id;
416	arrow.id = "arrowup_"+this.idPrefix+id;
417	arrow.className = "dhtmlxMenu_"+this.conf.skin+"_SubLevelArea_ArrowUp";
418	
419	arrow.over = false;
420	arrow.onselectstart = function(e) { e = e||event; if (e.preventDefault) e.preventDefault(); else e.returnValue = false; return false; }
421	arrow.oncontextmenu = function(e) { e = e||event; if (e.preventDefault) e.preventDefault(); else e.returnValue = false; return false; }
422	// actions
423	arrow.onmouseover = function() {
424		if (that.conf.mode == "web") { window.clearTimeout(that.conf.tm_handler); }
425		that._clearAllSelectedSubItemsInPolygon(this.pId);
426		if (this.className == "dhtmlxMenu_"+that.conf.skin+"_SubLevelArea_ArrowUp_Disabled") return;
427		this.className = "dhtmlxMenu_"+that.conf.skin+"_SubLevelArea_ArrowUp_Over";
428		this.over = true;
429		that._canScrollUp = true;
430		that._doScrollUp(this.pId, true);
431	}
432	arrow.onmouseout = function() {
433		if (that.conf.mode == "web") {
434			window.clearTimeout(that.conf.tm_handler);
435			that.conf.tm_handler = window.setTimeout(function(){that._clearAndHide();}, that.conf.tm_sec, "JavaScript");
436		}
437		this.over = false;
438		that._canScrollUp = false;
439		if (this.className == "dhtmlxMenu_"+that.conf.skin+"_SubLevelArea_ArrowUp_Disabled") return;
440		this.className = "dhtmlxMenu_"+that.conf.skin+"_SubLevelArea_ArrowUp";
441		window.clearTimeout(that.conf.of_utm);
442	}
443	arrow.onclick = function(e) {
444		e = e||event;
445		if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
446		e.cancelBubble = true;
447		return false;
448	}
449	
450	var polygon = this.idPull["polygon_"+this.idPrefix+id];
451	polygon.childNodes[0].appendChild(arrow);
452	
453	this.idPull[arrow.id] = arrow;
454	polygon = arrow = null;
455};
456
457dhtmlXMenuObject.prototype._addDownArrow = function(id) {
458	
459	var that = this;
460	var arrow = document.createElement("DIV");
461	arrow.pId = this.idPrefix+id;
462	arrow.id = "arrowdown_"+this.idPrefix+id;
463	arrow.className = "dhtmlxMenu_"+this.conf.skin+"_SubLevelArea_ArrowDown";
464	
465	arrow.over = false;
466	arrow.onselectstart = function(e) { e = e||event; if (e.preventDefault) e.preventDefault(); else e.returnValue = false; return false; }
467	arrow.oncontextmenu = function(e) { e = e||event; if (e.preventDefault) e.preventDefault(); else e.returnValue = false; return false; }
468	
469	// actions
470	arrow.onmouseover = function() {
471		if (that.conf.mode == "web") { window.clearTimeout(that.conf.tm_handler); }
472		that._clearAllSelectedSubItemsInPolygon(this.pId);
473		if (this.className == "dhtmlxMenu_"+that.conf.skin+"_SubLevelArea_ArrowDown_Disabled") return;
474		this.className = "dhtmlxMenu_"+that.conf.skin+"_SubLevelArea_ArrowDown_Over";
475		this.over = true;
476		that._canScrollDown = true;
477		that._doScrollDown(this.pId, true);
478	}
479	arrow.onmouseout = function() {
480		if (that.conf.mode == "web") {
481			window.clearTimeout(that.conf.tm_handler);
482			that.conf.tm_handler = window.setTimeout(function(){that._clearAndHide();}, that.conf.tm_sec, "JavaScript");
483		}
484		this.over = false;
485		that._canScrollDown = false;
486		if (this.className == "dhtmlxMenu_"+that.conf.skin+"_SubLevelArea_ArrowDown_Disabled") return;
487		this.className = "dhtmlxMenu_"+that.conf.skin+"_SubLevelArea_ArrowDown";
488		window.clearTimeout(that.conf.of_dtm);
489	}
490	arrow.onclick = function(e) {
491		e = e||event;
492		if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
493		e.cancelBubble = true;
494		return false;
495	}
496	
497	var polygon = this.idPull["polygon_"+this.idPrefix+id];
498	polygon.childNodes[2].appendChild(arrow);
499	
500	this.idPull[arrow.id] = arrow;
501	polygon = arrow = null;
502};
503
504dhtmlXMenuObject.prototype._removeUpArrow = function(id) {
505	var fullId = "arrowup_"+this.idPrefix+id;
506	this._removeArrow(fullId);
507};
508
509dhtmlXMenuObject.prototype._removeDownArrow = function(id) {
510	var fullId = "arrowdown_"+this.idPrefix+id;
511	this._removeArrow(fullId);
512};
513
514dhtmlXMenuObject.prototype._removeArrow = function(fullId) {
515	var arrow = this.idPull[fullId];
516	arrow.onselectstart = null;
517	arrow.oncontextmenu = null;
518	arrow.onmouseover = null;
519	arrow.onmouseout = null;
520	arrow.onclick = null;
521	if (arrow.parentNode) arrow.parentNode.removeChild(arrow);
522	arrow = null;
523	this.idPull[fullId] = null;
524	try { delete this.idPull[fullId]; } catch(e) {}
525};
526
527dhtmlXMenuObject.prototype._isArrowExists = function(id) {
528	if (this.idPull["arrowup_"+id] != null && this.idPull["arrowdown_"+id] != null) return true;
529	return false;
530};
531
532// scroll down
533dhtmlXMenuObject.prototype._doScrollUp = function(id, checkArrows) {
534	var polygon = this.idPull["polygon_"+id].childNodes[1];
535	if (this._canScrollUp && polygon.scrollTop > 0) {
536		var theEnd = false;
537		var nextScrollTop = polygon.scrollTop - this.conf.of_ustep;
538		if (nextScrollTop < 0) {
539			theEnd = true;
540			nextScrollTop = 0;
541		}
542		polygon.scrollTop = nextScrollTop;
543		if (!theEnd) {
544			var that = this;
545			this.conf.of_utm = window.setTimeout(function() {
546				that._doScrollUp(id, false);
547				that = null;
548			}, this.conf.of_utime);
549		} else {
550			checkArrows = true;
551		}
552	} else {
553		this._canScrollUp = false;
554		this._checkArrowsState(id);
555	}
556	if (checkArrows) {
557		this._checkArrowsState(id);
558	}
559};
560
561dhtmlXMenuObject.prototype._doScrollDown = function(id, checkArrows) {
562	var polygon = this.idPull["polygon_"+id].childNodes[1];
563	if (this._canScrollDown && polygon.scrollTop + polygon.offsetHeight <= polygon.scrollHeight) {
564		var theEnd = false;
565		var nextScrollTop = polygon.scrollTop + this.conf.of_dstep;
566		if (nextScrollTop + polygon.offsetHeight >= polygon.scrollHeight) {
567			theEnd = true;
568			nextScrollTop = polygon.scrollHeight - polygon.offsetHeight;
569		}
570		polygon.scrollTop = nextScrollTop;
571		if (!theEnd) {
572			var that = this;
573			this.conf.of_dtm = window.setTimeout(function() {
574				that._doScrollDown(id, false);
575				that = null;
576			}, this.conf.of_dtime);
577		} else {
578			checkArrows = true;
579		}
580	} else {
581		this._canScrollDown = false;
582		this._checkArrowsState(id);
583	}
584	if (checkArrows) {
585		this._checkArrowsState(id);
586	}
587};
588
589dhtmlXMenuObject.prototype._countPolygonItems = function(id) {
590	var count = 0;
591	for (var a in this.itemPull) {
592		var par = this.itemPull[a]["parent"];
593		var tp = this.itemPull[a]["type"];
594		if (par == this.idPrefix+id && (tp == "item" || tp == "radio" || tp == "checkbox")) { count++; }
595	}
596	return count;
597};
598
599dhtmlXMenuObject.prototype.setOverflowHeight = function(itemsNum) {
600	
601	// set auto overflow mode
602	if (itemsNum === "auto") {
603		this.conf.overflow_limit = 0;
604		this.conf.auto_overflow = true;
605		return;
606	}
607	
608	// no existing limitation, now new limitation
609	if (this.conf.overflow_limit == 0 && itemsNum <= 0) return;
610	
611	// hide menu to prevent visible changes
612	this._clearAndHide();
613	
614	// redefine existing limitation, arrows will added automatically with showPlygon
615	if (this.conf.overflow_limit >= 0 && itemsNum > 0) {
616		this.conf.overflow_limit = itemsNum;
617		return;
618	}
619	
620	// remove existing limitation
621	if (this.conf.overflow_limit > 0 && itemsNum <= 0) {
622		for (var a in this.itemPull) {
623			if (this._isArrowExists(a)) {
624				var b = String(a).replace(this.idPrefix, "");
625				this._removeUpArrow(b);
626				this._removeDownArrow(b);
627				// remove polygon's height
628				this.idPull["polygon_"+a].childNodes[1].style.height = "";
629			}
630		}
631		this.conf.overflow_limit = 0;
632		return;
633	}
634};
635
636
637// radiobuttons
638dhtmlXMenuObject.prototype._getRadioImgObj = function(id) {
639	try { var imgObj = this.idPull[this.idPrefix+id].childNodes[(this.conf.rtl?2:0)].childNodes[0] } catch(e) { var imgObj = null; }
640	return imgObj;
641};
642
643dhtmlXMenuObject.prototype._setRadioState = function(id, state) {
644	// if (this.itemPull[this.idPrefix+id]["state"] != "enabled") return;
645	var imgObj = this._getRadioImgObj(id);
646	if (imgObj != null) {
647		// fix, added in 0.4
648		var rObj = this.itemPull[this.idPrefix+id];
649		rObj["checked"] = state;
650		rObj["imgen"] = "rdbt_"+(rObj["checked"]?"1":"0");
651		rObj["imgdis"] = rObj["imgen"];
652		imgObj.className = "sub_icon "+rObj["imgen"];
653	}
654};
655
656dhtmlXMenuObject.prototype._radioOnClickHandler = function(id, type, casState) {
657	if (type.charAt(1)=="d" || this.itemPull[this.idPrefix+id]["group"]==null) return;
658	// deselect all from the same group
659	var group = this.itemPull[this.idPrefix+id]["group"];
660	if (this.checkEvent("onRadioClick")) {
661		if (this.callEvent("onRadioClick", [group, this.getRadioChecked(group), id, this.conf.ctx_zoneid, casState])) {
662			this.setRadioChecked(group, id);
663		}
664	} else {
665		this.setRadioChecked(group, id);
666	}
667	// call onClick if exists
668	if (this.checkEvent("onClick")) this.callEvent("onClick", [id]);
669};
670
671dhtmlXMenuObject.prototype.getRadioChecked = function(group) {
672	var id = null;
673	for (var q=0; q<this.radio[group].length; q++) {
674		var itemId = this.radio[group][q].replace(this.idPrefix, "");
675		var imgObj = this._getRadioImgObj(itemId);
676		if (imgObj != null) {
677			var checked = (imgObj.className).match(/rdbt_1$/gi);
678			if (checked != null) id = itemId;
679		}
680	}
681	return id;
682};
683
684dhtmlXMenuObject.prototype.setRadioChecked = function(group, id) {
685	if (this.radio[group] == null) return;
686	for (var q=0; q<this.radio[group].length; q++) {
687		var itemId = this.radio[group][q].replace(this.idPrefix, "");
688		this._setRadioState(itemId, (itemId==id));
689	}
690}
691
692dhtmlXMenuObject.prototype.addRadioButton = function(mode, nextToId, pos, itemId, itemText, group, state, disabled) {
693	// radiobutton
694	if (this.conf.context && nextToId == this.topId) {
695		// adding radiobutton as first element to context menu
696		// do nothing
697	} else {
698		if (this.itemPull[this.idPrefix+nextToId] == null) return;
699		if (mode == "child" && this.itemPull[this.idPrefix+nextToId]["type"] != "item") return;
700	}
701	
702	var id = this.idPrefix+(itemId!=null?itemId:this._genStr(24));
703	var img = "rdbt_"+(state?"1":"0");
704	var imgDis = img;
705	//
706	if (mode == "sibling") {
707		var parentId = this.idPrefix+this.getParentId(nextToId);
708		this._addItemIntoGlobalStrorage(id, parentId, itemText, "radio", disabled, img, imgDis);
709		this._renderSublevelItem(id, this.getItemPosition(nextToId));
710	} else {
711		var parentId = this.idPrefix+nextToId;
712		this._addItemIntoGlobalStrorage(id, parentId, itemText, "radio", disabled, img, imgDis);
713		if (this.idPull["polygon_"+parentId] == null) { this._renderSublevelPolygon(parentId, parentId); }
714		this._renderSublevelItem(id, pos-1);
715		this._redefineComplexState(parentId);
716	}
717	//
718	var gr = (group!=null?group:this._genStr(24));
719	this.itemPull[id]["group"] = gr;
720	//
721	if (this.radio[gr]==null) { this.radio[gr] = new Array(); }
722	this.radio[gr][this.radio[gr].length] = id;
723	//
724	if (state == true) this.setRadioChecked(gr, String(id).replace(this.idPrefix, ""));
725};
726
727
728// serialize
729dhtmlXMenuObject.prototype.serialize = function() {
730	var xml = "<menu>"+this._readLevel(this.idPrefix+this.topId)+"</menu>";
731	return xml;
732};
733
734dhtmlXMenuObject.prototype._readLevel = function(parentId) {
735	var xml = "";
736	for (var a in this.itemPull) {
737		if (this.itemPull[a]["parent"] == parentId) {
738			var imgEn = "";
739			var imgDis = "";
740			var hotKey = "";
741			var itemId = String(this.itemPull[a]["id"]).replace(this.idPrefix,"");
742			var itemType = "";
743			var itemText = (this.itemPull[a]["title"]!=""?' text="'+this.itemPull[a]["title"]+'"':"");
744			var itemState = "";
745			if (this.itemPull[a]["type"] == "item") {
746				if (this.itemPull[a]["imgen"] != "") imgEn = ' img="'+this.itemPull[a]["imgen"]+'"';
747				if (this.itemPull[a]["imgdis"] != "") imgDis = ' imgdis="'+this.itemPull[a]["imgdis"]+'"';
748				if (this.itemPull[a]["hotkey"] != "") hotKey = '<hotkey>'+this.itemPull[a]["hotkey"]+'</hotkey>';
749			}
750			if (this.itemPull[a]["type"] == "separator") {
751				itemType = ' type="separator"';
752			} else {
753				if (this.itemPull[a]["state"] == "disabled") itemState = ' enabled="false"';
754			}
755			if (this.itemPull[a]["type"] == "checkbox") {
756				itemType = ' type="checkbox"'+(this.itemPull[a]["checked"]?' checked="true"':"");
757			}
758			if (this.itemPull[a]["type"] == "radio") {
759				itemType = ' type="radio" group="'+this.itemPull[a]["group"]+'" '+(this.itemPull[a]["checked"]?' checked="true"':"");
760			}
761			xml += "<item id='"+itemId+"'"+itemText+itemType+imgEn+imgDis+itemState+">";
762			xml += hotKey;
763			if (this.itemPull[a]["complex"]) xml += this._readLevel(a);
764			xml += "</item>";
765		}
766	}
767	return xml;
768};
769

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.