PageSourceSearch

https://www.belcantofund.com/bitrix/js/main/core/core_window.js

js belcantofund.com collected 2026-10-02 05:04:30 UTC 96,650 bytes, 3,962 lines download raw bytes

1;(function(window) {
2if (BX.WindowManager) return;
3
4/* windows manager */
5BX.WindowManager = {
6	_stack: [],
7	_runtime_resize: {},
8	_delta: 2,
9	_delta_start: 1000,
10	currently_loaded: null,
11
12	settings_category: 'BX.WindowManager.9.5',
13
14	register: function (w)
15	{
16		this.currently_loaded = null;
17		var div = w.Get();
18
19		div.style.zIndex = w.zIndex = this.GetZIndex();
20
21		w.WM_REG_INDEX = this._stack.length;
22		this._stack.push(w);
23
24		if (this._stack.length < 2)
25		{
26			BX.bind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
27		}
28	},
29
30	unregister: function (w)
31	{
32		if (null == w.WM_REG_INDEX)
33			return null;
34
35		var _current;
36		if (this._stack.length > 0)
37		{
38			while ((_current = this.__pop_stack()) != w)
39			{
40				if (!_current)
41				{
42					_current = null;
43					break;
44				}
45			}
46
47			if (this._stack.length <= 0)
48			{
49				this.enableKeyCheck();
50			}
51
52			return _current;
53		}
54		else
55		{
56			return null;
57		}
58	},
59
60	__pop_stack: function(clean)
61	{
62		if (this._stack.length > 0)
63		{
64			var _current = this._stack.pop();
65			_current.WM_REG_INDEX = null;
66			BX.onCustomEvent(_current, 'onWindowUnRegister', [clean === true]);
67
68			return _current;
69		}
70		else
71			return null;
72	},
73
74	clean: function()
75	{
76		while (this.__pop_stack(true)){}
77		this._stack = null;
78		this.disableKeyCheck();
79	},
80
81	Get: function()
82	{
83		if (this.currently_loaded)
84			return this.currently_loaded;
85		else if (this._stack.length > 0)
86			return this._stack[this._stack.length-1];
87		else
88			return null;
89	},
90
91	setStartZIndex: function(value)
92	{
93		this._delta_start = value;
94	},
95
96	restoreStartZIndex: function()
97	{
98		this._delta_start = 1000;
99	},
100
101	GetZIndex: function()
102	{
103		var _current;
104		return (null != (_current = this._stack[this._stack.length-1])
105			? parseInt(_current.Get().style.zIndex) + this._delta
106			: this._delta_start
107		);
108	},
109
110	__get_check_url: function(url)
111	{
112		var pos = url.indexOf('?');
113		return pos == -1 ? url : url.substring(0, pos);
114	},
115
116	saveWindowSize: function(url, params)
117	{
118		var check_url = this.__get_check_url(url);
119		if (BX.userOptions)
120		{
121			BX.userOptions.save(this.settings_category, 'size_' + check_url, 'width', params.width);
122			BX.userOptions.save(this.settings_category, 'size_' + check_url, 'height', params.height);
123		}
124
125		this._runtime_resize[check_url] = params;
126	},
127
128	saveWindowOptions: function(wnd_id, opts)
129	{
130		if (BX.userOptions)
131		{
132			for (var i in opts)
133			{
134				if(opts.hasOwnProperty(i))
135				{
136					BX.userOptions.save(this.settings_category, 'options_' + wnd_id, i, opts[i]);
137				}
138			}
139		}
140	},
141
142	getRuntimeWindowSize: function(url)
143	{
144		return this._runtime_resize[this.__get_check_url(url)];
145	},
146
147	disableKeyCheck: function()
148	{
149		BX.unbind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
150	},
151
152	enableKeyCheck: function()
153	{
154		BX.bind(document, 'keyup', BX.proxy(this.__checkKeyPress, this));
155	},
156
157	__checkKeyPress: function(e)
158	{
159		if (null == e)
160			e = window.event;
161
162		if (e.keyCode == 27)
163		{
164			var wnd = BX.WindowManager.Get();
165			if (wnd && !wnd.unclosable) wnd.Close();
166		}
167	}
168};
169
170BX.garbage(BX.WindowManager.clean, BX.WindowManager);
171
172/* base button class */
173BX.CWindowButton = function(params)
174{
175	if (params.btn)
176	{
177		this.btn = params.btn;
178		this.parentWindow = params.parentWindow;
179
180		if (/save|apply/i.test(this.btn.name))
181		{
182			BX.bind(this.btn, 'click', BX.delegate(this.disableUntilError, this));
183		}
184	}
185	else
186	{
187		this.title = params.title; // html value attr
188		this.hint = params.hint; // html title attr
189		this.id = params.id; // html name and id attrs
190		this.name = params.name; // html name or value attrs when id and title 're absent
191		this.className = params.className; // className for button input
192
193		this.action = params.action;
194		this.onclick = params.onclick;
195
196		// you can override button creation method
197		if (params.Button && BX.type.isFunction(params.Button))
198			this.Button = params.Button;
199
200		this.btn = null;
201	}
202};
203
204BX.CWindowButton.prototype.disable = function()
205{
206	if (this.btn)
207		this.parentWindow.showWait(this.btn);
208};
209BX.CWindowButton.prototype.enable = function(){
210	if (this.btn)
211		this.parentWindow.closeWait(this.btn);
212};
213
214BX.CWindowButton.prototype.emulate = function()
215{
216	if (this.btn && this.btn.disabled)
217		return;
218
219	var act =
220		this.action
221		? BX.delegate(this.action, this)
222		: (
223			this.onclick
224			? this.onclick
225			: (
226				this.btn
227				? this.btn.getAttribute('onclick')
228				: ''
229			)
230		);
231
232	if (act)
233	{
234		setTimeout(act, 50);
235		if (this.btn && /save|apply/i.test(this.btn.name) && !this.action)
236		{
237			this.disableUntilError();
238		}
239	}
240};
241
242BX.CWindowButton.prototype.Button = function(parentWindow)
243{
244	this.parentWindow = parentWindow;
245
246	var btn = {
247		props: {
248			'type': 'button',
249			'name': this.id ? this.id : this.name,
250			'value': this.title ? this.title : this.name,
251			'id': this.id
252		}
253	};
254
255	if (this.hint)
256		btn.props.title = this.hint;
257	if (!!this.className)
258		btn.props.className = this.className;
259
260	if (this.action)
261	{
262		btn.events = {
263			'click': BX.delegate(this.action, this)
264		};
265	}
266	else if (this.onclick)
267	{
268		if (BX.browser.IsIE())
269		{
270			btn.events = {
271				'click': BX.delegate(function() {eval(this.onclick)}, this)
272			};
273		}
274		else
275		{
276			btn.attrs = {
277				'onclick': this.onclick
278			};
279		}
280	}
281
282	this.btn = BX.create('INPUT', btn);
283
284	return this.btn;
285};
286
287BX.CWindowButton.prototype.disableUntilError = function() {
288	this.disable();
289	if (!this.__window_error_handler_set)
290	{
291		BX.addCustomEvent(this.parentWindow, 'onWindowError', BX.delegate(this.enable, this));
292		this.__window_error_handler_set = true;
293	}
294};
295
296/* base window class */
297BX.CWindow = function(div, type)
298{
299	this.DIV = div || document.createElement('DIV');
300
301	this.SETTINGS = {
302		resizable: false,
303		min_height: 0,
304		min_width: 0,
305		top: 0,
306		left: 0,
307		draggable: false,
308		drag_restrict: true,
309		resize_restrict: true
310	};
311
312	this.ELEMENTS = {
313		draggable: [],
314		resizer: [],
315		close: []
316	};
317
318	this.type = type == 'float' ? 'float' : 'dialog';
319
320	BX.adjust(this.DIV, {
321		props: {
322			className: 'bx-core-window'
323		},
324		style: {
325			'zIndex': 0,
326			'position': 'absolute',
327			'display': 'none',
328			'top': this.SETTINGS.top + 'px',
329			'left': this.SETTINGS.left + 'px',
330			'height': '100px',
331			'width': '100px'
332		}
333	});
334
335	this.isOpen = false;
336
337	BX.addCustomEvent(this, 'onWindowRegister', BX.delegate(this.onRegister, this));
338	BX.addCustomEvent(this, 'onWindowUnRegister', BX.delegate(this.onUnRegister, this));
339
340	this.MOUSEOVER = null;
341	BX.bind(this.DIV, 'mouseover', BX.delegate(this.__set_msover, this));
342	BX.bind(this.DIV, 'mouseout', BX.delegate(this.__unset_msover, this));
343
344	BX.ready(BX.delegate(function() {
345		document.body.appendChild(this.DIV);
346	}, this));
347};
348
349BX.CWindow.prototype.Get = function () {return this.DIV};
350BX.CWindow.prototype.visible = function() {return this.isOpen;};
351
352BX.CWindow.prototype.Show = function(bNotRegister)
353{
354	this.DIV.style.display = 'block';
355
356	if (!bNotRegister)
357	{
358		BX.WindowManager.register(this);
359		BX.onCustomEvent(this, 'onWindowRegister');
360	}
361};
362
363BX.CWindow.prototype.Hide = function()
364{
365	BX.WindowManager.unregister(this);
366	this.DIV.style.display = 'none';
367};
368
369BX.CWindow.prototype.onRegister = function()
370{
371	this.isOpen = true;
372};
373
374BX.CWindow.prototype.onUnRegister = function(clean)
375{
376	this.isOpen = false;
377
378	if (clean || (this.PARAMS && this.PARAMS.content_url))
379	{
380		if (clean) {BX.onCustomEvent(this, 'onWindowClose', [this, true]);}
381
382		if (this.DIV.parentNode)
383			this.DIV.parentNode.removeChild(this.DIV);
384	}
385	else
386	{
387		this.DIV.style.display = 'none';
388	}
389};
390
391BX.CWindow.prototype.CloseDialog = // compatibility
392BX.CWindow.prototype.Close = function(bImmediately)
393{
394	BX.onCustomEvent(this, 'onBeforeWindowClose', [this]);
395	if (bImmediately !== true)
396	{
397		if (this.denyClose)
398			return false;
399	}
400
401	BX.onCustomEvent(this, 'onWindowClose', [this]);
402
403	//this crashes vis editor in ie via onWindowResizeExt event handler
404	//if (this.bExpanded) this.__expand();
405	// alternative version:
406	if (this.bExpanded)
407	{
408		var pDocElement = BX.GetDocElement();
409		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
410		pDocElement.style.overflow = this.__expand_settings.overflow;
411	}
412
413	BX.WindowManager.unregister(this);
414
415	return true;
416};
417
418BX.CWindow.prototype.SetResize = function(elem)
419{
420	elem.style.cursor = 'se-resize';
421	BX.bind(elem, 'mousedown', BX.proxy(this.__startResize, this));
422
423	this.ELEMENTS.resizer.push(elem);
424	this.SETTINGS.resizable = true;
425};
426
427BX.CWindow.prototype.SetExpand = function(elem, event_name)
428{
429	event_name = event_name || 'click';
430	BX.bind(elem, event_name, BX.proxy(this.__expand, this));
431};
432
433BX.CWindow.prototype.__expand_onresize = function()
434{
435	var windowSize = BX.GetWindowInnerSize();
436	this.DIV.style.width = windowSize.innerWidth + "px";
437	this.DIV.style.height = windowSize.innerHeight + "px";
438
439	BX.onCustomEvent(this, 'onWindowResize');
440};
441
442BX.CWindow.prototype.__expand = function()
443{
444	var pDocElement = BX.GetDocElement();
445
446	if (!this.bExpanded)
447	{
448		var wndScroll = BX.GetWindowScrollPos(),
449			wndSize = BX.GetWindowInnerSize();
450
451		this.__expand_settings = {
452			resizable: this.SETTINGS.resizable,
453			draggable: this.SETTINGS.draggable,
454			width: this.DIV.style.width,
455			height: this.DIV.style.height,
456			left: this.DIV.style.left,
457			top: this.DIV.style.top,
458			scrollTop: wndScroll.scrollTop,
459			scrollLeft: wndScroll.scrollLeft,
460			overflow: BX.style(pDocElement, 'overflow')
461		};
462
463		this.SETTINGS.resizable = false;
464		this.SETTINGS.draggable = false;
465
466		window.scrollTo(0,0);
467		pDocElement.style.overflow = 'hidden';
468
469		this.DIV.style.top = '0px';
470		this.DIV.style.left = '0px';
471
472		this.DIV.style.width = wndSize.innerWidth + 'px';
473		this.DIV.style.height = wndSize.innerHeight + 'px';
474
475		this.bExpanded = true;
476
477		BX.onCustomEvent(this, 'onWindowExpand');
478		BX.onCustomEvent(this, 'onWindowResize');
479
480		BX.bind(window, 'resize', BX.proxy(this.__expand_onresize, this));
481	}
482	else
483	{
484		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
485
486		this.SETTINGS.resizable = this.__expand_settings.resizable;
487		this.SETTINGS.draggable = this.__expand_settings.draggable;
488
489		pDocElement.style.overflow = this.__expand_settings.overflow;
490
491		this.DIV.style.top = this.__expand_settings.top;
492		this.DIV.style.left = this.__expand_settings.left;
493		this.DIV.style.width = this.__expand_settings.width;
494		this.DIV.style.height = this.__expand_settings.height;
495
496		window.scrollTo(this.__expand_settings.scrollLeft, this.__expand_settings.scrollTop);
497
498		this.bExpanded = false;
499
500		BX.onCustomEvent(this, 'onWindowNarrow');
501		BX.onCustomEvent(this, 'onWindowResize');
502
503	}
504};
505
506BX.CWindow.prototype.Resize = function(x, y)
507{
508	var new_width = Math.max(x - this.pos.left + this.dx, this.SETTINGS.min_width);
509	var new_height = Math.max(y - this.pos.top + this.dy, this.SETTINGS.min_height);
510
511	if (this.SETTINGS.resize_restrict)
512	{
513		var scrollSize = BX.GetWindowScrollSize();
514
515		if (this.pos.left + new_width > scrollSize.scrollWidth - this.dw)
516			new_width = scrollSize.scrollWidth - this.pos.left - this.dw;
517	}
518
519	this.DIV.style.width = new_width + 'px';
520	this.DIV.style.height = new_height + 'px';
521
522	BX.onCustomEvent(this, 'onWindowResize');
523};
524
525BX.CWindow.prototype.__startResize = function(e)
526{
527	if (!this.SETTINGS.resizable)
528		return false;
529
530	if(!e) e = window.event;
531
532	this.wndSize = BX.GetWindowScrollPos();
533	this.wndSize.innerWidth = BX.GetWindowInnerSize().innerWidth;
534
535	this.pos = BX.pos(this.DIV);
536
537	this.x = e.clientX + this.wndSize.scrollLeft;
538	this.y = e.clientY + this.wndSize.scrollTop;
539
540	this.dx = this.pos.left + this.pos.width - this.x;
541	this.dy = this.pos.top + this.pos.height - this.y;
542	this.dw = this.pos.width - parseInt(this.DIV.style.width);
543
544	BX.bind(document, "mousemove", BX.proxy(this.__moveResize, this));
545	BX.bind(document, "mouseup", BX.proxy(this.__stopResize, this));
546
547	if(document.body.setCapture)
548		document.body.setCapture();
549
550	document.onmousedown = BX.False;
551
552	var b = document.body;
553	b.ondrag = b.onselectstart = BX.False;
554	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
555	b.style.cursor = 'se-resize';
556
557	BX.onCustomEvent(this, 'onWindowResizeStart');
558
559	return true;
560};
561
562BX.CWindow.prototype.__moveResize = function(e)
563{
564	if(!e) e = window.event;
565
566	var windowScroll = BX.GetWindowScrollPos();
567
568	var x = e.clientX + windowScroll.scrollLeft;
569	var y = e.clientY + windowScroll.scrollTop;
570
571	if(this.x == x && this.y == y)
572		return;
573
574	this.Resize(x, y);
575
576	this.x = x;
577	this.y = y;
578};
579
580BX.CWindow.prototype.__stopResize = function()
581{
582	if(document.body.releaseCapture)
583		document.body.releaseCapture();
584
585	BX.unbind(document, "mousemove", BX.proxy(this.__moveResize, this));
586	BX.unbind(document, "mouseup", BX.proxy(this.__stopResize, this));
587
588	document.onmousedown = null;
589
590	var b = document.body;
591	b.ondrag = b.onselectstart = null;
592	b.style.MozUserSelect = this.DIV.style.MozUserSelect = '';
593	b.style.cursor = '';
594
595	BX.onCustomEvent(this, 'onWindowResizeFinished')
596};
597
598BX.CWindow.prototype.SetClose = function(elem)
599{
600	BX.bind(elem, 'click', BX.proxy(this.Close, this));
601	this.ELEMENTS.close.push(elem);
602};
603
604BX.CWindow.prototype.SetDraggable = function(elem)
605{
606	BX.bind(elem, 'mousedown', BX.proxy(this.__startDrag, this));
607
608	elem.style.cursor = 'move';
609
610	this.ELEMENTS.draggable.push(elem);
611	this.SETTINGS.draggable = true;
612};
613
614BX.CWindow.prototype.Move = function(x, y)
615{
616	var dxShadow = 1; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
617
618	var left = parseInt(this.DIV.style.left)+x;
619	var top = parseInt(this.DIV.style.top)+y;
620
621	if (this.SETTINGS.drag_restrict)
622	{
623		//Left side
624		if (left < 0)
625			left = 0;
626
627		//Right side
628		var scrollSize = BX.GetWindowScrollSize();
629		var floatWidth = this.DIV.offsetWidth;
630		var floatHeight = this.DIV.offsetHeight;
631
632		if (left > (scrollSize.scrollWidth - floatWidth - dxShadow))
633			left = scrollSize.scrollWidth - floatWidth - dxShadow;
634
635		if (top > (scrollSize.scrollHeight - floatHeight - dxShadow))
636			top = scrollSize.scrollHeight - floatHeight - dxShadow;
637
638		//Top side
639		if (top < 0)
640			top = 0;
641	}
642
643	this.DIV.style.left = left+'px';
644	this.DIV.style.top = top+'px';
645
646	//this.AdjustShadow(div);
647};
648
649BX.CWindow.prototype.__startDrag = function(e)
650{
651	if (!this.SETTINGS.draggable)
652		return false;
653
654	if(!e) e = window.event;
655
656	this.x = e.clientX + document.body.scrollLeft;
657	this.y = e.clientY + document.body.scrollTop;
658
659	this.__bWasDragged = false;
660	BX.bind(document, "mousemove", BX.proxy(this.__moveDrag, this));
661	BX.bind(document, "mouseup", BX.proxy(this.__stopDrag, this));
662
663	if(document.body.setCapture)
664		document.body.setCapture();
665
666	document.onmousedown = BX.False;
667
668	var b = document.body;
669	b.ondrag = b.onselectstart = BX.False;
670	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
671	b.style.cursor = 'move';
672	return BX.PreventDefault(e);
673};
674
675BX.CWindow.prototype.__moveDrag = function(e)
676{
677	if(!e) e = window.event;
678
679	var x = e.clientX + document.body.scrollLeft;
680	var y = e.clientY + document.body.scrollTop;
681
682	if(this.x == x && this.y == y)
683		return;
684
685	this.Move((x - this.x), (y - this.y));
686	this.x = x;
687	this.y = y;
688
689	if (!this.__bWasDragged)
690	{
691		BX.onCustomEvent(this, 'onWindowDragStart');
692		this.__bWasDragged = true;
693		BX.bind(BX.proxy_context, "click", BX.PreventDefault);
694	}
695
696	BX.onCustomEvent(this, 'onWindowDrag');
697};
698
699BX.CWindow.prototype.__stopDrag = function(e)
700{
701	if(document.body.releaseCapture)
702		document.body.releaseCapture();
703
704	BX.unbind(document, "mousemove", BX.proxy(this.__moveDrag, this));
705	BX.unbind(document, "mouseup", BX.proxy(this.__stopDrag, this));
706
707	document.onmousedown = null;
708
709	var b = document.body;
710	b.ondrag = b.onselectstart = null;
711	b.style.MozUserSelect = this.DIV.style.MozUserSelect = '';
712	b.style.cursor = '';
713
714	if (this.__bWasDragged)
715	{
716		BX.onCustomEvent(this, 'onWindowDragFinished');
717		var _proxy_context = BX.proxy_context;
718		setTimeout(function(){BX.unbind(_proxy_context, "click", BX.PreventDefault)}, 100);
719		this.__bWasDragged = false;
720	}
721	return BX.PreventDefault(e);
722};
723
724BX.CWindow.prototype.DenyClose = function()
725{
726	this.denyClose = true;
727};
728
729BX.CWindow.prototype.AllowClose = function()
730{
731	this.denyClose = false;
732};
733
734BX.CWindow.prototype.ShowError = function(str)
735{
736	BX.onCustomEvent(this, 'onWindowError', [str]);
737
738	if (this._wait)
739		BX.closeWait(this._wait);
740
741	window.alert(str);
742};
743
744BX.CWindow.prototype.__set_msover = function() {this.MOUSEOVER = true;};
745BX.CWindow.prototype.__unset_msover = function() {this.MOUSEOVER = false;};
746
747/* dialog window class extends window class */
748BX.CWindowDialog = function() {
749	var a = arguments;
750	a[1] = 'dialog';
751	BX.CWindowDialog.superclass.constructor.apply(this, a);
752
753	this.DIV.style.top = '10px';
754	this.OVERLAY = null;
755};
756BX.extend(BX.CWindowDialog, BX.CWindow);
757
758BX.CWindowDialog.prototype.__resizeOverlay = function()
759{
760	var windowSize = BX.GetWindowScrollSize();
761	this.OVERLAY.style.width = windowSize.scrollWidth + "px";
762};
763
764BX.CWindowDialog.prototype.CreateOverlay = function(zIndex)
765{
766	if (null == this.OVERLAY)
767	{
768		var windowSize = BX.GetWindowScrollSize();
769		this.OVERLAY = document.body.appendChild(BX.create("DIV", {
770			style: {
771				position: 'absolute',
772				top: '0px',
773				left: '0px',
774				zIndex: zIndex || (parseInt(this.DIV.style.zIndex)-2),
775				width: windowSize.scrollWidth + "px",
776				height: windowSize.scrollHeight + "px"
777			}
778		}));
779	}
780
781	return this.OVERLAY;
782};
783
784BX.CWindowDialog.prototype.Show = function()
785{
786	BX.CWindowDialog.superclass.Show.apply(this, arguments);
787
788	this.CreateOverlay();
789
790	this.OVERLAY.style.display = 'block';
791	this.OVERLAY.style.zIndex = parseInt(this.DIV.style.zIndex)-2;
792
793	BX.unbind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
794	BX.bind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
795};
796
797BX.CWindowDialog.prototype.onUnRegister = function(clean)
798{
799	BX.CWindowDialog.superclass.onUnRegister.apply(this, arguments);
800
801	if (this.clean)
802	{
803		if (this.OVERLAY.parentNode)
804			this.OVERLAY.parentNode.removeChild(this.OVERLAY);
805	}
806	else
807	{
808		this.OVERLAY.style.display = 'none';
809	}
810
811	BX.unbind(window, 'resize', BX.proxy(this.__resizeOverlay, this));
812};
813
814/* standard bitrix dialog extends BX.CWindowDialog */
815/*
816	arParams = {
817		(
818			title: 'dialog title',
819			head: 'head block html',
820			content: 'dialog content',
821			icon: 'head icon classname or filename',
822
823			resize_id: 'some id to save resize information'// useless if resizable = false
824		)
825		or
826		(
827			content_url: url to content load
828				loaded content scripts can use BX.WindowManager.Get() to get access to the current window object
829		)
830
831		height: window_height_in_pixels,
832		width: window_width_in_pixels,
833
834		draggable: true|false,
835		resizable: true|false,
836
837		min_height: min_window_height_in_pixels, // useless if resizable = false
838		min_width: min_window_width_in_pixels, // useless if resizable = false
839
840		buttons: [
841			'html_code',
842			BX.CDialog.btnSave, BX.CDialog.btnCancel, BX.CDialog.btnClose
843		]
844	}
845*/
846BX.CDialog = function(arParams)
847{
848	BX.CDialog.superclass.constructor.apply(this);
849
850	this._sender = 'core_window_cdialog';
851
852	this.PARAMS = arParams || {};
853
854	for (var i in this.defaultParams)
855	{
856		if (typeof this.PARAMS[i] == 'undefined')
857			this.PARAMS[i] = this.defaultParams[i];
858	}
859
860	this.PARAMS.width = (!isNaN(parseInt(this.PARAMS.width)))
861		? this.PARAMS.width
862		: this.defaultParams['width'];
863	this.PARAMS.height = (!isNaN(parseInt(this.PARAMS.height)))
864		? this.PARAMS.height
865		: this.defaultParams['height'];
866
867	if (this.PARAMS.resize_id || this.PARAMS.content_url)
868	{
869		var arSize = BX.WindowManager.getRuntimeWindowSize(this.PARAMS.resize_id || this.PARAMS.content_url);
870		if (arSize)
871		{
872			this.PARAMS.width = arSize.width;
873			this.PARAMS.height = arSize.height;
874		}
875	}
876
877	BX.addClass(this.DIV, 'bx-core-adm-dialog');
878	this.DIV.id = 'bx-admin-prefix';
879
880	this.PARTS = {};
881
882	this.DIV.style.height = null;
883	this.DIV.style.width = null;
884
885	this.PARTS.TITLEBAR = this.DIV.appendChild(BX.create('DIV', {props: {
886			className: 'bx-core-adm-dialog-head'
887		}
888	}));
889
890	this.PARTS.TITLE_CONTAINER = this.PARTS.TITLEBAR.appendChild(BX.create('SPAN', {
891		props: {className: 'bx-core-adm-dialog-head-inner'},
892		text: this.PARAMS.title
893	}));
894
895	this.PARTS.TITLEBAR_ICONS = this.PARTS.TITLEBAR.appendChild(BX.create('DIV', {
896		props: {
897			className: 'bx-core-adm-dialog-head-icons'
898		},
899		children: (this.PARAMS.resizable ? [
900			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-expand', title: BX.message('JS_CORE_WINDOW_EXPAND')}}),
901			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-close', title: BX.message('JS_CORE_WINDOW_CLOSE')}})
902		] : [
903			BX.create('SPAN', {props: {className: 'bx-core-adm-icon-close', title: BX.message('JS_CORE_WINDOW_CLOSE')}})
904		])
905	}));
906
907
908	this.PARTS.CONTENT = this.DIV.appendChild(BX.create('DIV', {
909		props: {className: 'bx-core-adm-dialog-content-wrap adm-workarea'}
910	}));
911
912	this.PARTS.CONTENT_DATA = this.PARTS.CONTENT.appendChild(BX.create('DIV', {
913		props: {className: 'bx-core-adm-dialog-content'},
914		style: {
915			height: this.PARAMS.height + 'px',
916			width: this.PARAMS.width + 'px'
917		}
918	}));
919
920	this.PARTS.HEAD = this.PARTS.CONTENT_DATA.appendChild(BX.create('DIV', {
921		props: {
922			className: 'bx-core-adm-dialog-head-block' + (this.PARAMS.icon ? ' ' + this.PARAMS.icon : '')
923		}
924	}));
925
926	this.SetHead(this.PARAMS.head);
927	this.SetContent(this.PARAMS.content);
928	this.SetTitle(this.PARAMS.title);
929	this.SetClose(this.PARTS.TITLEBAR_ICONS.lastChild);
930
931	if (this.PARAMS.resizable)
932	{
933		this.SetExpand(this.PARTS.TITLEBAR_ICONS.firstChild);
934		this.SetExpand(this.PARTS.TITLEBAR, 'dblclick');
935
936		BX.addCustomEvent(this, 'onWindowExpand', BX.proxy(this.__onexpand, this));
937		BX.addCustomEvent(this, 'onWindowNarrow', BX.proxy(this.__onexpand, this));
938	}
939
940	this.PARTS.FOOT = this.PARTS.BUTTONS_CONTAINER = this.PARTS.CONTENT.appendChild(BX.create('DIV', {
941			props: {
942				className: 'bx-core-adm-dialog-buttons'
943			},
944			//events: {
945			//	'click': BX.delegateEvent({property:{type: /button|submit/}}, BX.delegate(function() {this.showWait(BX.proxy_context)}, this))
946			//},
947			children: this.ShowButtons()
948		}
949	));
950
951	if (this.PARAMS.draggable)
952		this.SetDraggable(this.PARTS.TITLEBAR);
953
954	if (this.PARAMS.resizable)
955	{
956		this.PARTS.RESIZER = this.DIV.appendChild(BX.create('DIV', {
957			props: {className: 'bx-core-resizer'}
958		}));
959
960		this.SetResize(this.PARTS.RESIZER);
961
962		this.SETTINGS.min_width = this.PARAMS.min_width;
963		this.SETTINGS.min_height = this.PARAMS.min_height;
964	}
965
966	this.auth_callback = BX.delegate(function(){
967		this.PARAMS.content = '';
968		this.hideNotify();
969		this.Show();
970	}, this)
971};
972BX.extend(BX.CDialog, BX.CWindowDialog);
973
974BX.CDialog.prototype.defaultParams = {
975	width: 700,
976	height: 400,
977	min_width: 500,
978	min_height: 300,
979
980	resizable: true,
981	draggable: true,
982
983	title: '',
984	icon: ''
985};
986
987BX.CDialog.prototype.showWait = function(el)
988{
989	if (BX.type.isElementNode(el) && (el.type == 'button' || el.type == 'submit'))
990	{
991		BX.defer(function(){el.disabled = true})();
992
993		var bSave = (BX.hasClass(el, 'adm-btn-save') || BX.hasClass(el, 'adm-btn-save')),
994			pos = BX.pos(el, true);
995
996		el.bxwaiter = this.PARTS.FOOT.appendChild(BX.create('DIV', {
997			props: {className: 'adm-btn-load-img' + (bSave ? '-green' : '')},
998			style: {
999				top: parseInt((pos.bottom + pos.top)/2 - 10) + 'px',
1000				left: parseInt((pos.right + pos.left)/2 - 10) + 'px'
1001			}
1002		}));
1003
1004		BX.addClass(el, 'adm-btn-load');
1005
1006		this.lastWaitElement = el;
1007
1008		return el.bxwaiter;
1009	}
1010	return null;
1011};
1012
1013BX.CDialog.prototype.closeWait = function(el)
1014{
1015	el = el || this.lastWaitElement;
1016
1017	if (BX.type.isElementNode(el))
1018	{
1019		if (el.bxwaiter)
1020		{
1021			if(el.bxwaiter.parentNode)
1022			{
1023				el.bxwaiter.parentNode.removeChild(el.bxwaiter);
1024			}
1025
1026			el.bxwaiter = null;
1027		}
1028
1029		el.disabled = false;
1030		BX.removeClass(el, 'adm-btn-load');
1031
1032		if (this.lastWaitElement == el)
1033			this.lastWaitElement = null;
1034	}
1035};
1036
1037BX.CDialog.prototype.Authorize = function(arAuthResult)
1038{
1039	this.bSkipReplaceContent = true;
1040	this.ShowError(BX.message('JSADM_AUTH_REQ'));
1041
1042	BX.onCustomEvent(this, 'onWindowError', []);
1043
1044	BX.closeWait();
1045
1046	(new BX.CAuthDialog({
1047		content_url: this.PARAMS.content_url,
1048		auth_result: arAuthResult,
1049		callback: BX.delegate(function(){
1050			if (this.auth_callback)
1051				this.auth_callback()
1052		}, this)
1053	})).Show();
1054};
1055
1056BX.CDialog.prototype.ShowError = function(str)
1057{
1058	BX.onCustomEvent(this, 'onWindowError', [str]);
1059
1060	this.closeWait();
1061
1062	if (this._wait)
1063		BX.closeWait(this._wait);
1064
1065	this.Notify(str, true);
1066};
1067
1068
1069BX.CDialog.prototype.__expandGetSize = function()
1070{
1071	var pDocElement = BX.GetDocElement();
1072	pDocElement.style.overflow = 'hidden';
1073
1074	var wndSize = BX.GetWindowInnerSize();
1075
1076	pDocElement.scrollTop = 0;
1077
1078	this.DIV.style.top = '-' + this.dxShadow + 'px';
1079	this.DIV.style.left = '-' + this.dxShadow + 'px';
1080
1081	return {
1082		width: (wndSize.innerWidth - parseInt(BX.style(this.PARTS.CONTENT, 'padding-right')) - parseInt(BX.style(this.PARTS.CONTENT, 'padding-left'))) + this.dxShadow,
1083		height: (wndSize.innerHeight - this.PARTS.TITLEBAR.offsetHeight - this.PARTS.FOOT.offsetHeight - parseInt(BX.style(this.PARTS.CONTENT, 'padding-top')) - parseInt(BX.style(this.PARTS.CONTENT, 'padding-bottom'))) + this.dxShadow
1084	};
1085};
1086
1087BX.CDialog.prototype.__expand = function()
1088{
1089	var pDocElement = BX.GetDocElement();
1090	this.dxShadow = 2;
1091
1092	if (!this.bExpanded)
1093	{
1094		var wndScroll = BX.GetWindowScrollPos();
1095
1096		this.__expand_settings = {
1097			resizable: this.SETTINGS.resizable,
1098			draggable: this.SETTINGS.draggable,
1099			width: this.PARTS.CONTENT_DATA.style.width,
1100			height: this.PARTS.CONTENT_DATA.style.height,
1101			left: this.DIV.style.left,
1102			top: this.DIV.style.top,
1103			scrollTop: wndScroll.scrollTop,
1104			scrollLeft: wndScroll.scrollLeft,
1105			overflow: BX.style(pDocElement, 'overflow')
1106		};
1107
1108		this.SETTINGS.resizable = false;
1109		this.SETTINGS.draggable = false;
1110
1111		var pos = this.__expandGetSize();
1112
1113		this.PARTS.CONTENT_DATA.style.width = pos.width + 'px';
1114		this.PARTS.CONTENT_DATA.style.height = pos.height + 'px';
1115
1116		window.scrollTo(0,0);
1117		pDocElement.style.overflow = 'hidden';
1118
1119		this.bExpanded = true;
1120
1121		BX.onCustomEvent(this, 'onWindowExpand');
1122		BX.onCustomEvent(this, 'onWindowResize');
1123		BX.onCustomEvent(this, 'onWindowResizeExt', [{'width': pos.width, 'height': pos.height}]);
1124
1125		BX.bind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1126	}
1127	else
1128	{
1129		BX.unbind(window, 'resize', BX.proxy(this.__expand_onresize, this));
1130
1131		this.SETTINGS.resizable = this.__expand_settings.resizable;
1132		this.SETTINGS.draggable = this.__expand_settings.draggable;
1133
1134		pDocElement.style.overflow = this.__expand_settings.overflow;
1135
1136		this.DIV.style.top = this.__expand_settings.top;
1137		this.DIV.style.left = this.__expand_settings.left;
1138		this.PARTS.CONTENT_DATA.style.width = this.__expand_settings.width;
1139		this.PARTS.CONTENT_DATA.style.height = this.__expand_settings.height;
1140		window.scrollTo(this.__expand_settings.scrollLeft, this.__expand_settings.scrollTop);
1141		this.bExpanded = false;
1142
1143		BX.onCustomEvent(this, 'onWindowNarrow');
1144		BX.onCustomEvent(this, 'onWindowResize');
1145		BX.onCustomEvent(this, 'onWindowResizeExt', [{'width': parseInt(this.__expand_settings.width), 'height': parseInt(this.__expand_settings.height)}]);
1146	}
1147};
1148
1149BX.CDialog.prototype.__expand_onresize = function()
1150{
1151	var pos = this.__expandGetSize();
1152
1153	this.PARTS.CONTENT_DATA.style.width = pos.width + 'px';
1154	this.PARTS.CONTENT_DATA.style.height = pos.height + 'px';
1155
1156	BX.onCustomEvent(this, 'onWindowResize');
1157	BX.onCustomEvent(this, 'onWindowResizeExt', [pos]);
1158};
1159
1160BX.CDialog.prototype.__onexpand = function()
1161{
1162	var ob = this.PARTS.TITLEBAR_ICONS.firstChild;
1163	ob.className = BX.toggle(ob.className, ['bx-core-adm-icon-expand', 'bx-core-adm-icon-narrow']);
1164	ob.title = BX.toggle(ob.title, [BX.message('JS_CORE_WINDOW_EXPAND'), BX.message('JS_CORE_WINDOW_NARROW')]);
1165
1166	if (this.PARTS.RESIZER)
1167	{
1168		this.PARTS.RESIZER.style.display = this.bExpanded ? 'none' : 'block';
1169	}
1170};
1171
1172
1173BX.CDialog.prototype.__startResize = function(e)
1174{
1175	if (!this.SETTINGS.resizable)
1176		return false;
1177
1178	if(!e) e = window.event;
1179
1180	this.wndSize = BX.GetWindowScrollPos();
1181	this.wndSize.innerWidth = BX.GetWindowInnerSize().innerWidth;
1182
1183	this.pos = BX.pos(this.PARTS.CONTENT_DATA);
1184
1185	this.x = e.clientX + this.wndSize.scrollLeft;
1186	this.y = e.clientY + this.wndSize.scrollTop;
1187
1188	this.dx = this.pos.left + this.pos.width - this.x;
1189	this.dy = this.pos.top + this.pos.height - this.y;
1190
1191
1192	// TODO: suspicious
1193	this.dw = this.pos.width - parseInt(this.PARTS.CONTENT_DATA.style.width) + parseInt(BX.style(this.PARTS.CONTENT, 'padding-right'));
1194
1195	BX.bind(document, "mousemove", BX.proxy(this.__moveResize, this));
1196	BX.bind(document, "mouseup", BX.proxy(this.__stopResize, this));
1197
1198	if(document.body.setCapture)
1199		document.body.setCapture();
1200
1201	document.onmousedown = BX.False;
1202
1203	var b = document.body;
1204	b.ondrag = b.onselectstart = BX.False;
1205	b.style.MozUserSelect = this.DIV.style.MozUserSelect = 'none';
1206	b.style.cursor = 'se-resize';
1207
1208	BX.onCustomEvent(this, 'onWindowResizeStart');
1209
1210	return true;
1211};
1212
1213BX.CDialog.prototype.Resize = function(x, y)
1214{
1215	var new_width = Math.max(x - this.pos.left + this.dx, this.SETTINGS.min_width);
1216	var new_height = Math.max(y - this.pos.top + this.dy, this.SETTINGS.min_height);
1217
1218	if (this.SETTINGS.resize_restrict)
1219	{
1220		var scrollSize = BX.GetWindowScrollSize();
1221
1222		if (this.pos.left + new_width > scrollSize.scrollWidth - this.dw)
1223			new_width = scrollSize.scrollWidth - this.pos.left - this.dw;
1224	}
1225
1226	this.PARTS.CONTENT_DATA.style.width = new_width + 'px';
1227	this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
1228
1229	BX.onCustomEvent(this, 'onWindowResize');
1230	BX.onCustomEvent(this, 'onWindowResizeExt', [{'height': new_height, 'width': new_width}]);
1231};
1232
1233BX.CDialog.prototype.SetSize = function(obSize)
1234{
1235	this.PARTS.CONTENT_DATA.style.width = obSize.width + 'px';
1236	this.PARTS.CONTENT_DATA.style.height = obSize.height + 'px';
1237
1238	BX.onCustomEvent(this, 'onWindowResize');
1239	BX.onCustomEvent(this, 'onWindowResizeExt', [obSize]);
1240};
1241
1242BX.CDialog.prototype.GetParameters = function(form_name)
1243{
1244	var form = this.GetForm();
1245
1246	if(!form)
1247		return "";
1248
1249	var i, s = "";
1250	var n = form.elements.length;
1251
1252	var delim = '';
1253	for(i=0; i<n; i++)
1254	{
1255		if (s != '') delim = '&';
1256		var el = form.elements[i];
1257		if (el.disabled)
1258			continue;
1259
1260		switch(el.type.toLowerCase())
1261		{
1262			case 'text':
1263			case 'textarea':
1264			case 'password':
1265			case 'hidden':
1266				if (null == form_name && el.name.substr(el.name.length-4) == '_alt' && form.elements[el.name.substr(0, el.name.length-4)])
1267					break;
1268				s += delim + el.name + '=' + BX.util.urlencode(el.value);
1269				break;
1270			case 'radio':
1271				if(el.checked)
1272					s += delim + el.name + '=' + BX.util.urlencode(el.value);
1273				break;
1274			case 'checkbox':
1275				s += delim + el.name + '=' + BX.util.urlencode(el.checked ? 'Y':'N');
1276				break;
1277			case 'select-one':
1278				var val = "";
1279				if (null == form_name && form.elements[el.name + '_alt'] && el.selectedIndex == 0)
1280					val = form.elements[el.name+'_alt'].value;
1281				else
1282					val = el.value;
1283				s += delim + el.name + '=' + BX.util.urlencode(val);
1284				break;
1285			case 'select-multiple':
1286				var j, bAdded = false;
1287				var l = el.options.length;
1288				for (j=0; j<l; j++)
1289				{
1290					if (el.options[j].selected)
1291					{
1292						s += delim + el.name + '=' + BX.util.urlencode(el.options[j].value);
1293						bAdded = true;
1294					}
1295				}
1296				if (!bAdded)
1297					s += delim + el.name + '=';
1298				break;
1299			default:
1300				break;
1301		}
1302	}
1303
1304	return s;
1305};
1306
1307BX.CDialog.prototype.PostParameters = function(params)
1308{
1309	var url = this.PARAMS.content_url;
1310
1311	if (null == params)
1312		params = "";
1313
1314	params += (params == "" ? "" : "&") + "bxsender=" + this._sender;
1315
1316	var index = url.indexOf('?');
1317	if (index == -1)
1318		url += '?' + params;
1319	else
1320		url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
1321
1322	BX.showWait();
1323
1324	this.auth_callback = BX.delegate(function(){
1325		this.hideNotify();
1326		this.PostParameters(params);
1327	}, this);
1328
1329	BX.ajax.Setup({skipAuthCheck:true},true);
1330	BX.ajax.post(url, this.GetParameters(), BX.delegate(function(result) {
1331		BX.closeWait();
1332		if (!this.bSkipReplaceContent)
1333		{
1334			this.ClearButtons(); // buttons are appended during form reload, so we should clear footer
1335			this.SetContent(result);
1336			this.Show(true);
1337		}
1338
1339		this.bSkipReplaceContent = false;
1340	}, this));
1341};
1342
1343BX.CDialog.prototype.Submit = function(params, url)
1344{
1345	var FORM = this.GetForm();
1346	if (FORM)
1347	{
1348		FORM.onsubmit = null;
1349
1350		FORM.method = 'POST';
1351		if (!FORM.action || url)
1352		{
1353			url = url || this.PARAMS.content_url;
1354			if (null != params)
1355			{
1356				var index = url.indexOf('?');
1357				if (index == -1)
1358					url += '?' + params;
1359				else
1360					url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
1361			}
1362
1363			FORM.action = url;
1364		}
1365
1366		if (!FORM._bxsender)
1367		{
1368			FORM._bxsender = FORM.appendChild(BX.create('INPUT', {
1369				attrs: {
1370					type: 'hidden',
1371					name: 'bxsender',
1372					value: this._sender
1373				}
1374			}));
1375		}
1376
1377		this._wait = BX.showWait();
1378
1379		this.auth_callback = BX.delegate(function(){
1380			this.hideNotify();
1381			this.Submit(params);
1382		}, this);
1383
1384		BX.ajax.submit(FORM, BX.delegate(function(){this.closeWait()}, this));
1385	}
1386	else
1387	{
1388		window.alert('no form registered!');
1389	}
1390};
1391
1392BX.CDialog.prototype.GetForm = function()
1393{
1394	if (null == this.__form)
1395	{
1396		var forms = this.PARTS.CONTENT_DATA.getElementsByTagName('FORM');
1397		this.__form = forms[0] ? forms[0] : null;
1398	}
1399
1400	return this.__form;
1401};
1402
1403BX.CDialog.prototype.GetRealForm = function()
1404{
1405	if (null == this.__rform)
1406	{
1407		var forms = this.PARTS.CONTENT_DATA.getElementsByTagName('FORM');
1408		this.__rform = forms[1] ? forms[1] : (forms[0] ? forms[0] : null);
1409	}
1410
1411	return this.__rform;
1412};
1413
1414BX.CDialog.prototype._checkButton = function(btn)
1415{
1416	var arCustomButtons = ['btnSave', 'btnCancel', 'btnClose'];
1417
1418	for (var i = 0; i < arCustomButtons.length; i++)
1419	{
1420		if (this[arCustomButtons[i]] && (btn == this[arCustomButtons[i]]))
1421			return arCustomButtons[i];
1422	}
1423
1424	return false;
1425};
1426
1427BX.CDialog.prototype.ShowButtons = function()
1428{
1429	var result = [];
1430	if (this.PARAMS.buttons)
1431	{
1432		if (this.PARAMS.buttons.title) this.PARAMS.buttons = [this.PARAMS.buttons];
1433
1434		for (var i=0, len=this.PARAMS.buttons.length; i<len; i++)
1435		{
1436			if (BX.type.isNotEmptyString(this.PARAMS.buttons[i]))
1437			{
1438				result.push(this.PARAMS.buttons[i]);
1439			}
1440			else if (BX.type.isElementNode(this.PARAMS.buttons[i]))
1441			{
1442				result.push(this.PARAMS.buttons[i]);
1443			}
1444			else if (this.PARAMS.buttons[i])
1445			{
1446				//if (!(this.PARAMS.buttons[i] instanceof BX.CWindowButton))
1447				if (!BX.is_subclass_of(this.PARAMS.buttons[i], BX.CWindowButton))
1448				{
1449					var b = this._checkButton(this.PARAMS.buttons[i]); // hack to set links to real CWindowButton object in btnSave etc;
1450					this.PARAMS.buttons[i] = new BX.CWindowButton(this.PARAMS.buttons[i]);
1451					if (b) this[b] = this.PARAMS.buttons[i];
1452				}
1453
1454				result.push(this.PARAMS.buttons[i].Button(this));
1455			}
1456		}
1457	}
1458
1459	return result;
1460};
1461
1462BX.CDialog.prototype.setAutosave = function () {
1463	if (!this.bSetAutosaveDelay)
1464	{
1465		this.bSetAutosaveDelay = true;
1466		setTimeout(BX.proxy(this.setAutosave, this), 10);
1467	}
1468};
1469
1470BX.CDialog.prototype.SetTitle = function(title)
1471{
1472	this.PARAMS.title = title;
1473	BX.cleanNode(this.PARTS.TITLE_CONTAINER).appendChild(document.createTextNode(this.PARAMS.title));
1474};
1475
1476BX.CDialog.prototype.SetHead = function(head)
1477{
1478	this.PARAMS.head = BX.util.trim(head);
1479	this.PARTS.HEAD.innerHTML = this.PARAMS.head || "&nbsp;";
1480	this.PARTS.HEAD.style.display = this.PARAMS.head ? 'block' : 'none';
1481	this.adjustSize();
1482};
1483
1484BX.CDialog.prototype.Notify = function(note, bError)
1485{
1486	if (!this.PARTS.NOTIFY)
1487	{
1488		this.PARTS.NOTIFY = this.DIV.insertBefore(BX.create('DIV', {
1489			props: {className: 'adm-warning-block'},
1490			children: [
1491				BX.create('SPAN', {
1492					props: {className: 'adm-warning-text'}
1493				}),
1494				BX.create('SPAN', {
1495					props: {className: 'adm-warning-icon'}
1496				}),
1497				BX.create('SPAN', {
1498					props: {className: 'adm-warning-close'},
1499					events: {click: BX.proxy(this.hideNotify, this)}
1500				})
1501			]
1502		}), this.DIV.firstChild);
1503	}
1504
1505	if (bError)
1506		BX.addClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
1507	else
1508		BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
1509
1510	this.PARTS.NOTIFY.firstChild.innerHTML = note || '&nbsp;';
1511	this.PARTS.NOTIFY.firstChild.style.width = (this.PARAMS.width-50) + 'px';
1512	BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-animate');
1513};
1514
1515BX.CDialog.prototype.hideNotify = function()
1516{
1517	BX.addClass(this.PARTS.NOTIFY, 'adm-warning-animate');
1518};
1519
1520BX.CDialog.prototype.__adjustHeadToIcon = function()
1521{
1522	if (!this.PARTS.HEAD.offsetHeight)
1523	{
1524		setTimeout(BX.delegate(this.__adjustHeadToIcon, this), 50);
1525	}
1526	else
1527	{
1528		if (this.icon_image && this.icon_image.height && this.icon_image.height > this.PARTS.HEAD.offsetHeight - 5)
1529		{
1530			this.PARTS.HEAD.style.height = this.icon_image.height + 5 + 'px';
1531			this.adjustSize();
1532		}
1533
1534		this.icon_image.onload = null;
1535		this.icon_image = null;
1536	}
1537};
1538
1539BX.CDialog.prototype.SetIcon = function(icon_class)
1540{
1541	if (this.PARAMS.icon != icon_class)
1542	{
1543		if (this.PARAMS.icon)
1544			BX.removeClass(this.PARTS.HEAD, this.PARAMS.icon);
1545
1546		this.PARAMS.icon = icon_class;
1547
1548		if (this.PARAMS.icon)
1549		{
1550			BX.addClass(this.PARTS.HEAD, this.PARAMS.icon);
1551
1552			var icon_file = (BX.style(this.PARTS.HEAD, 'background-image') || BX.style(this.PARTS.HEAD, 'backgroundImage'));
1553			if (BX.type.isNotEmptyString(icon_file) && icon_file != 'none')
1554			{
1555				var match = icon_file.match(new RegExp('url\\s*\\(\\s*(\'|"|)(.+?)(\\1)\\s*\\)'));
1556				if(match)
1557				{
1558					icon_file = match[2];
1559					if (BX.type.isNotEmptyString(icon_file))
1560					{
1561						this.icon_image = new Image();
1562						this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
1563						this.icon_image.src = icon_file;
1564					}
1565				}
1566			}
1567		}
1568	}
1569	this.adjustSize();
1570};
1571
1572BX.CDialog.prototype.SetIconFile = function(icon_file)
1573{
1574	this.icon_image = new Image();
1575	this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
1576	this.icon_image.src = icon_file;
1577
1578	BX.adjust(this.PARTS.HEAD, {style: {backgroundImage: 'url(' + icon_file + ')', backgroundPosition: 'right 9px'/*'99% center'*/}});
1579	this.adjustSize();
1580};
1581
1582/*
1583BUTTON: {
1584	title: 'title',
1585	'action': function executed in window object context
1586}
1587BX.CDialog.btnSave || BX.CDialog.btnCancel - standard buttons
1588*/
1589
1590BX.CDialog.prototype.SetButtons = function(a)
1591{
1592	if (BX.type.isString(a))
1593	{
1594		if (a.length > 0)
1595		{
1596			this.PARTS.BUTTONS_CONTAINER.innerHTML += a;
1597
1598			var btns = this.PARTS.BUTTONS_CONTAINER.getElementsByTagName('INPUT');
1599			if (btns.length > 0)
1600			{
1601				this.PARAMS.buttons = [];
1602				for (var i = 0; i < btns.length; i++)
1603				{
1604					this.PARAMS.buttons.push(new BX.CWindowButton({btn: btns[i], parentWindow: this}));
1605				}
1606			}
1607		}
1608	}
1609	else
1610	{
1611		this.PARAMS.buttons = a;
1612		BX.adjust(this.PARTS.BUTTONS_CONTAINER, {
1613			children: this.ShowButtons()
1614		});
1615	}
1616	this.adjustSize();
1617};
1618
1619BX.CDialog.prototype.ClearButtons = function()
1620{
1621	BX.cleanNode(this.PARTS.BUTTONS_CONTAINER);
1622	this.adjustSize();
1623};
1624
1625BX.CDialog.prototype.SetContent = function(html)
1626{
1627	this.__form = null;
1628
1629	if (BX.type.isElementNode(html))
1630	{
1631		if (html.parentNode)
1632			html.parentNode.removeChild(html);
1633	}
1634	else if (BX.type.isString(html))
1635	{
1636		html = BX.create('DIV', {html: html});
1637	}
1638
1639	this.PARAMS.content = html;
1640	BX.cleanNode(this.PARTS.CONTENT_DATA);
1641
1642	BX.adjust(this.PARTS.CONTENT_DATA, {
1643		children: [
1644			this.PARTS.HEAD,
1645			BX.create('DIV', {
1646				props: {
1647					className: 'bx-core-adm-dialog-content-wrap-inner'
1648				},
1649				children: [this.PARAMS.content]
1650			})
1651		]
1652	});
1653
1654	if (this.PARAMS.content_url && this.GetForm())
1655	{
1656		this.__form.submitbtn = this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
1657		this.__form.onsubmit = BX.delegate(this.__submit, this);
1658	}
1659};
1660
1661BX.CDialog.prototype.__submit = function(e)
1662{
1663	for (var i=0,len=this.PARAMS.buttons.length; i<len; i++)
1664	{
1665		if (
1666			this.PARAMS.buttons[i]
1667			&& (
1668				this.PARAMS.buttons[i].name && /save|apply/i.test(this.PARAMS.buttons[i].name)
1669				||
1670				this.PARAMS.buttons[i].btn && this.PARAMS.buttons[i].btn.name && /save|apply/i.test(this.PARAMS.buttons[i].btn.name)
1671			)
1672		)
1673		{
1674			this.PARAMS.buttons[i].emulate();
1675			break;
1676		}
1677	}
1678
1679	return BX.PreventDefault(e);
1680};
1681
1682BX.CDialog.prototype.SwapContent = function(cont)
1683{
1684	cont = BX(cont);
1685
1686	BX.cleanNode(this.PARTS.CONTENT_DATA);
1687	cont.parentNode.removeChild(cont);
1688	this.PARTS.CONTENT_DATA.appendChild(cont);
1689	cont.style.display = 'block';
1690	this.SetContent(cont.innerHTML);
1691};
1692
1693// this method deprecated
1694BX.CDialog.prototype.adjustSize = function()
1695{
1696};
1697
1698// this method deprecated
1699BX.CDialog.prototype.__adjustSize = function()
1700{
1701};
1702
1703BX.CDialog.prototype.adjustSizeEx = function()
1704{
1705	BX.defer(this.__adjustSizeEx, this)();
1706};
1707
1708BX.CDialog.prototype.__adjustSizeEx = function()
1709{
1710	var ob = this.PARTS.CONTENT_DATA.firstChild,
1711		new_height = 0,
1712		marginTop,
1713		marginBottom;
1714
1715	while (ob)
1716	{
1717		if (BX.type.isElementNode(ob))
1718		{
1719			marginTop = parseInt(BX.style(ob, 'margin-top'), 10);
1720			if (isNaN(marginTop))
1721				marginTop = 0;
1722			marginBottom = parseInt(BX.style(ob, 'margin-bottom'), 10);
1723			if (isNaN(marginBottom))
1724				marginBottom = 0;
1725			new_height += ob.offsetHeight + marginTop + marginBottom;
1726		}
1727		ob = BX.nextSibling(ob);
1728	}
1729
1730	if (new_height)
1731		this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
1732};
1733
1734
1735BX.CDialog.prototype.__onResizeFinished = function()
1736{
1737	BX.WindowManager.saveWindowSize(
1738		this.PARAMS.resize_id || this.PARAMS.content_url, {height: parseInt(this.PARTS.CONTENT_DATA.style.height), width: parseInt(this.PARTS.CONTENT_DATA.style.width)}
1739	);
1740};
1741
1742BX.CDialog.prototype.Show = function(bNotRegister)
1743{
1744	if ((!this.PARAMS.content) && this.PARAMS.content_url && BX.ajax && !bNotRegister)
1745	{
1746		var wait = BX.showWait();
1747
1748		BX.WindowManager.currently_loaded = this;
1749
1750		this.CreateOverlay(parseInt(BX.style(wait, 'z-index'))-1);
1751		this.OVERLAY.style.display = 'block';
1752		this.OVERLAY.className = 'bx-core-dialog-overlay';
1753
1754		var post_data = '', method = 'GET';
1755		if (this.PARAMS.content_post)
1756		{
1757			post_data = this.PARAMS.content_post;
1758			method = 'POST';
1759		}
1760
1761		var url = this.PARAMS.content_url
1762			+ (this.PARAMS.content_url.indexOf('?')<0?'?':'&')+'bxsender=' + this._sender;
1763
1764		this.auth_callback = BX.delegate(function(){
1765			this.PARAMS.content = '';
1766			this.hideNotify();
1767			this.Show();
1768		}, this);
1769
1770		BX.ajax({
1771			method: method,
1772			dataType: 'html',
1773			url: url,
1774			data: post_data,
1775			skipAuthCheck: true,
1776			onsuccess: BX.delegate(function(data) {
1777				BX.closeWait(null, wait);
1778
1779				this.SetContent(data || '&nbsp;');
1780				this.Show();
1781			}, this)
1782		});
1783	}
1784	else
1785	{
1786		BX.WindowManager.currently_loaded = null;
1787		BX.CDialog.superclass.Show.apply(this, arguments);
1788
1789		this.adjustPos();
1790
1791		this.OVERLAY.className = 'bx-core-dialog-overlay';
1792
1793		this.__adjustSize();
1794
1795		BX.addCustomEvent(this, 'onWindowResize', BX.proxy(this.__adjustSize, this));
1796
1797		if (this.PARAMS.resizable && (this.PARAMS.content_url || this.PARAMS.resize_id))
1798			BX.addCustomEvent(this, 'onWindowResizeFinished', BX.delegate(this.__onResizeFinished, this));
1799	}
1800};
1801
1802BX.CDialog.prototype.GetInnerPos = function()
1803{
1804	return {'width': parseInt(this.PARTS.CONTENT_DATA.style.width), 'height': parseInt(this.PARTS.CONTENT_DATA.style.height)};
1805};
1806
1807BX.CDialog.prototype.adjustPos = function()
1808{
1809	if (!this.bExpanded)
1810	{
1811		var windowSize = BX.GetWindowInnerSize();
1812		var windowScroll = BX.GetWindowScrollPos();
1813
1814		BX.adjust(this.DIV, {
1815			style: {
1816				left: parseInt(windowScroll.scrollLeft + windowSize.innerWidth / 2 - parseInt(this.DIV.offsetWidth) / 2) + 'px',
1817				top: Math.max(parseInt(windowScroll.scrollTop + windowSize.innerHe
1817ight / 2 - parseInt(this.DIV.offsetHeight) / 2), 0) + 'px'
1818			}
1819		});
1820	}
1821};
1822
1823BX.CDialog.prototype.GetContent = function () {return this.PARTS.CONTENT_DATA};
1824
1825BX.CDialog.prototype.btnSave = BX.CDialog.btnSave = {
1826	title: BX.message('JS_CORE_WINDOW_SAVE'),
1827	id: 'savebtn',
1828	name: 'savebtn',
1829	className: BX.browser.IsIE() && BX.browser.IsDoctype() && !BX.browser.IsIE10() ? '' : 'adm-btn-save',
1830	action: function () {
1831		this.disableUntilError();
1832		this.parentWindow.PostParameters();
1833	}
1834};
1835
1836BX.CDialog.prototype.btnCancel = BX.CDialog.btnCancel = {
1837	title: BX.message('JS_CORE_WINDOW_CANCEL'),
1838	id: 'cancel',
1839	name: 'cancel',
1840	action: function () {
1841		this.parentWindow.Close();
1842	}
1843};
1844
1845BX.CDialog.prototype.btnClose = BX.CDialog.btnClose = {
1846	title: BX.message('JS_CORE_WINDOW_CLOSE'),
1847	id: 'close',
1848	name: 'close',
1849	action: function () {
1850		this.parentWindow.Close();
1851	}
1852};
1853
1854/* special child for admin forms loaded into public page */
1855BX.CAdminDialog = function(arParams)
1856{
1857	BX.CAdminDialog.superclass.constructor.apply(this, arguments);
1858
1859	this._sender = 'core_window_cadmindialog';
1860
1861	BX.addClass(this.DIV, 'bx-core-adm-admin-dialog');
1862
1863	this.PARTS.CONTENT.insertBefore(this.PARTS.HEAD, this.PARTS.CONTENT.firstChild);
1864	this.PARTS.HEAD.className = 'bx-core-adm-dialog-tabs';
1865};
1866BX.extend(BX.CAdminDialog, BX.CDialog);
1867
1868BX.CAdminDialog.prototype.SetHead = function()
1869{
1870	BX.CAdminDialog.superclass.SetHead.apply(this, arguments);
1871
1872	if (this.PARTS.HEAD.firstChild && BX.type.isElementNode(this.PARTS.HEAD.firstChild))
1873	{
1874		var ob = this.PARTS.HEAD.firstChild, new_width = 0, marginLeft = 0, marginRight = 0;
1875
1876		while (ob)
1877		{
1878			if (BX.type.isElementNode(ob))
1879			{
1880				marginLeft = parseInt(BX.style(ob, 'margin-left'), 10);
1881				if (isNaN(marginLeft))
1882					marginLeft = 0;
1883				marginRight = parseInt(BX.style(ob, 'margin-right'), 10);
1884				if (isNaN(marginRight))
1885					marginRight = 0;
1886				new_width += ob.offsetWidth + marginLeft + marginRight;
1887			}
1888			ob = BX.nextSibling(ob);
1889		}
1890
1891		this.SETTINGS.min_width = Math.max(new_width, this.SETTINGS.min_width) - 2;
1892		if (this.PARAMS.width < this.SETTINGS.min_width)
1893		{
1894			BX.adjust(this.PARTS.CONTENT_DATA, {
1895				style: {
1896					width: this.SETTINGS.min_width + 'px'
1897				}
1898			});
1899		}
1900	}
1901};
1902
1903BX.CAdminDialog.prototype.SetContent = function(html)
1904{
1905	this.__form = null;
1906
1907	if (BX.type.isElementNode(html))
1908	{
1909		if (html.parentNode)
1910			html.parentNode.removeChild(html);
1911	}
1912
1913	this.PARAMS.content = html;
1914	BX.cleanNode(this.PARTS.CONTENT_DATA);
1915
1916	BX.adjust(this.PARTS.CONTENT_DATA, {
1917		children: [
1918			this.PARAMS.content || '&nbsp;'
1919		]
1920	});
1921
1922	if (this.PARAMS.content_url && this.GetForm())
1923	{
1924		this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
1925		this.__form.onsubmit = BX.delegate(this.__submit, this);
1926	}
1927};
1928
1929BX.CAdminDialog.prototype.__expandGetSize = function()
1930{
1931	var res = BX.CAdminDialog.superclass.__expandGetSize.apply(this, arguments);
1932
1933	res.width -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-right')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-left'));
1934	res.height -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-top')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-bottom'));
1935
1936	res.height -= this.PARTS.HEAD.offsetHeight;
1937
1938	return res;
1939};
1940
1941BX.CAdminDialog.prototype.Submit = function()
1942{
1943	var FORM = this.GetForm();
1944	if (FORM && !FORM['bxpublic'] && !/bxpublic=/.test(FORM.action))
1945	{
1946		FORM.appendChild(BX.create('INPUT', {
1947			props: {
1948				type: 'hidden',
1949				name: 'bxpublic',
1950				value: 'Y'
1951			}
1952		}));
1953	}
1954
1955	return BX.CAdminDialog.superclass.Submit.apply(this, arguments);
1956};
1957
1958BX.CAdminDialog.prototype.btnSave = BX.CAdminDialog.btnSave = {
1959	title: BX.message('JS_CORE_WINDOW_SAVE'),
1960	id: 'savebtn',
1961	name: 'savebtn',
1962	className: 'adm-btn-save',
1963	action: function () {
1964		this.disableUntilError();
1965		this.parentWindow.Submit();
1966	}
1967};
1968
1969BX.CAdminDialog.btnCancel = BX.CAdminDialog.superclass.btnCancel;
1970BX.CAdminDialog.btnClose = BX.CAdminDialog.superclass.btnClose;
1971
1972BX.CDebugDialog = function(arParams)
1973{
1974	BX.CDebugDialog.superclass.constructor.apply(this, arguments);
1975};
1976BX.extend(BX.CDebugDialog, BX.CDialog);
1977
1978BX.CDebugDialog.prototype.ShowDetails = function(div_id)
1979{
1980	var div = BX(div_id);
1981	if (div)
1982	{
1983		if (this.div_detail_current)
1984			this.div_detail_current.style.display = 'none';
1985
1986		div.style.display = 'block';
1987		this.div_detail_current = div;
1988	}
1989};
1990
1991BX.CDebugDialog.prototype.SetContent = function(html)
1992{
1993	if (!html)
1994		return;
1995
1996	var arHtml = html.split('#DIVIDER#');
1997	if (arHtml.length > 1)
1998	{
1999		this.PARAMS.content = arHtml[1];
2000
2001		this.PARTS.CONTENT_DATA.style.overflow = 'hidden';
2002
2003		BX.CDebugDialog.superclass.SetContent.apply(this, [arHtml[1]]);
2004
2005		this.PARTS.CONTENT_INNER = this.PARTS.CONTENT_DATA.firstChild.nextSibling;
2006		this.PARTS.CONTENT_TOP = this.PARTS.CONTENT_DATA.insertBefore(BX.create('DIV', {
2007			props: {
2008				className: 'bx-debug-content-top'
2009			},
2010			html: arHtml[0]
2011		}), this.PARTS.CONTENT_INNER);
2012		this.PARTS.CONTENT_INNER.style.overflow = 'auto';
2013	}
2014	else
2015	{
2016		BX.CDebugDialog.superclass.SetContent.apply(this, arguments);
2017	}
2018};
2019
2020BX.CDebugDialog.prototype.__adjustSize = function()
2021{
2022	BX.CDebugDialog.superclass.__adjustSize.apply(this, arguments);
2023
2024	if (this.PARTS.CONTENT_TOP)
2025	{
2026		var new_height = this.PARTS.CONTENT_DATA.offsetHeight - this.PARTS.HEAD.offsetHeight - this.PARTS.CONTENT_TOP.offsetHeight - 38;
2027
2028		if (new_height > 0)
2029		{
2030			this.PARTS.CONTENT_INNER.style.height = new_height + 'px';
2031		}
2032	}
2033};
2034
2035
2036/* class for dialog window with editors */
2037
2038BX.CEditorDialog = function(arParams)
2039{
2040	BX.CEditorDialog.superclass.constructor.apply(this, arguments);
2041
2042	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
2043	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
2044
2045	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2046	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
2047
2048	BX.addClass(this.PARTS.CONTENT, 'bx-core-editor-dialog-content-wrap');
2049	BX.addClass(this.PARTS.CONTENT_DATA, 'bx-core-editor-dialog-content');
2050	BX.addClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-editor-dialog-buttons');
2051};
2052BX.extend(BX.CEditorDialog, BX.CDialog);
2053
2054BX.CEditorDialog.prototype.SetContent  = function()
2055{
2056	BX.CEditorDialog.superclass.SetContent.apply(this, arguments);
2057
2058	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2059};
2060
2061/* class for wizards in admin section */
2062BX.CWizardDialog = function(arParams)
2063{
2064	BX.CWizardDialog.superclass.constructor.apply(this, arguments);
2065
2066	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
2067	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
2068	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2069	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
2070
2071	BX.addClass(this.PARTS.CONTENT, 'bx-core-wizard-dialog-content-wrap');
2072};
2073
2074BX.extend(BX.CWizardDialog, BX.CDialog);
2075
2076/* class for auth dialog */
2077BX.CAuthDialog = function(arParams)
2078{
2079	arParams.resizable = false;
2080	arParams.width = 350;
2081	arParams.height = 200;
2082
2083	arParams.buttons = [this.btnSave];
2084
2085	BX.CAuthDialog.superclass.constructor.apply(this, arguments);
2086	this._sender = 'core_window_cauthdialog';
2087
2088	BX.addClass(this.DIV, 'bx-core-auth-dialog');
2089
2090	BX.AUTHAGENT = this;
2091};
2092BX.extend(BX.CAuthDialog, BX.CDialog);
2093
2094BX.CAuthDialog.prototype.btnSave = BX.CAuthDialog.btnSave = {
2095	title: BX.message('JS_CORE_WINDOW_AUTH'),
2096	id: 'savebtn',
2097	name: 'savebtn',
2098	className: 'adm-btn-save',
2099	action: function () {
2100		this.disableUntilError();
2101		this.parentWindow.Submit('', this.parentWindow.PARAMS.content_url);
2102	}
2103};
2104
2105BX.CAuthDialog.prototype.SetError = function(error)
2106{
2107	BX.closeWait();
2108
2109	if (!!error)
2110		this.ShowError(error.MESSAGE || error);
2111};
2112
2113BX.CAuthDialog.prototype.setAuthResult = function(result)
2114{
2115	BX.closeWait();
2116
2117	if (result === false)
2118	{
2119		this.Close();
2120		if (this.PARAMS.callback)
2121			this.PARAMS.callback();
2122	}
2123	else
2124	{
2125		this.SetError(result);
2126	}
2127};
2128
2129/* MENU CLASSES */
2130
2131BX.CWindowFloat = function(node)
2132{
2133	BX.CWindowFloat.superclass.constructor.apply(this, [node, 'float']);
2134
2135	this.SETTINGS.resizable = false;
2136};
2137BX.extend(BX.CWindowFloat, BX.CWindow);
2138
2139BX.CWindowFloat.prototype.adjustPos = function()
2140{
2141	if (this.PARAMS.parent)
2142		this.adjustToNode();
2143	else if (this.PARAMS.x && this.PARAMS.y)
2144		this.adjustToPos([this.PARAMS.x, this.PARAMS.y]);
2145};
2146
2147BX.CWindowFloat.prototype.adjustToPos = function(pos)
2148{
2149	this.DIV.style.left = parseInt(pos[0]) + 'px';
2150	this.DIV.style.top = parseInt(pos[1]) + 'px';
2151};
2152
2153BX.CWindowFloat.prototype.adjustToNodeGetPos = function()
2154{
2155	return BX.pos(this.PARAMS.parent);
2156};
2157
2158BX.CWindowFloat.prototype.adjustToNode = function(el)
2159{
2160	el = el || this.PARAMS.parent;
2161
2162	this.PARAMS.parent = BX(el);
2163
2164	if (this.PARAMS.parent)
2165	{
2166		var pos = this.adjustToNodeGetPos();
2167
2168		this.DIV.style.top = pos.top + 'px';//(pos.top - 26) + 'px';
2169		this.DIV.style.left = pos.left + 'px';
2170
2171		this.PARAMS.parent.OPENER = this;
2172	}
2173};
2174
2175BX.CWindowFloat.prototype.Show = function()
2176{
2177	this.adjustToPos([-1000, -1000]);
2178	BX.CWindowFloat.superclass.Show.apply(this, arguments);
2179	this.adjustPos();
2180};
2181
2182/* menu opener class */
2183/*
2184{
2185	DOMNode DIV,
2186	BX.CMenu or Array MENU,
2187	TYPE = 'hover' | 'click',
2188	TIMEOUT: 1000
2189	ATTACH_MODE: 'top' | 'right'
2190	ACTIVE_CLASS: className for opener element when menu is opened
2191}
2192*/
2193BX.COpener = function(arParams)
2194{
2195	this.PARAMS = arParams || {};
2196
2197	this.MENU = arParams.MENU || [];
2198
2199	this.DIV = arParams.DIV;
2200	this.ATTACH = arParams.ATTACH || arParams.DIV;
2201	this.ATTACH_MODE = arParams.ATTACH_MODE || 'bottom';
2202
2203	this.ACTIVE_CLASS = arParams.ACTIVE_CLASS || '';
2204	this.LEVEL = arParams.LEVEL || 0;
2205
2206	this.CLOSE_ON_CLICK = typeof arParams.CLOSE_ON_CLICK != 'undefined' ? !!arParams.CLOSE_ON_CLICK : true;
2207	this.ADJUST_ON_CLICK = typeof arParams.ADJUST_ON_CLICK != 'undefined' ? !!arParams.ADJUST_ON_CLICK : true;
2208
2209	this.TYPE = this.PARAMS.TYPE == 'hover' ? 'hover' : 'click';
2210
2211	this._openTimeout = null;
2212
2213	if (this.PARAMS.TYPE == 'hover' && arParams.TIMEOUT !== 0)
2214		this.TIMEOUT = arParams.TIMEOUT || 1000;
2215	else
2216		this.TIMEOUT = 0;
2217
2218	if (!!this.PARAMS.MENU_URL)
2219	{
2220		this.bMenuLoaded = false;
2221		this.bMenuLoading = false;
2222
2223		this.MENU = [{
2224			TEXT: BX.message('JS_CORE_LOADING'),
2225			CLOSE_ON_CLICK: false
2226		}];
2227
2228		if (this.PARAMS.MENU_PRELOAD)
2229		{
2230			BX.defer(this.Load, this)();
2231		}
2232	}
2233
2234	BX.ready(BX.defer(this.Init, this));
2235};
2236
2237BX.COpener.prototype.Init = function()
2238{
2239	this.DIV = BX(this.DIV);
2240
2241	switch (this.TYPE)
2242	{
2243		case 'hover':
2244			BX.bind(this.DIV, 'mouseover', BX.proxy(this.Open, this));
2245			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
2246		break;
2247
2248		case 'click':
2249			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
2250		break;
2251	}
2252
2253	//BX.bind(window, 'scroll', BX.delegate(this.__close_immediately, this));
2254
2255	this.bMenuInit = false;
2256};
2257
2258BX.COpener.prototype.Load = function()
2259{
2260	if (this.PARAMS.MENU_URL && !this.bMenuLoaded)
2261	{
2262		if (!this.bMenuLoading)
2263		{
2264			var url = this.PARAMS.MENU_URL;
2265			if (url.indexOf('sessid=') <= 0)
2266				url += (url.indexOf('?') > 0 ? '&' : '?') + 'sessid=' + BX.bitrix_sessid();
2267
2268			this.bMenuLoading = true;
2269			BX.ajax.loadJSON(url, BX.proxy(this.SetMenu, this), BX.proxy(this.LoadFailed, this));
2270		}
2271	}
2272};
2273
2274BX.COpener.prototype.SetMenu = function(menu)
2275{
2276	this.bMenuLoaded = true;
2277	this.bMenuLoading = false;
2278	if (this.bMenuInit)
2279	{
2280		this.MENU.setItems(menu);
2281	}
2282	else
2283	{
2284		this.MENU = menu;
2285	}
2286};
2287
2288BX.COpener.prototype.LoadFailed = function(type, error)
2289{
2290	this.bMenuLoading = false;
2291	this.SetMenu([{
2292		TEXT: BX.message('JS_CORE_NO_DATA'),
2293		CLOSE_ON_CLICK: true
2294	}]);
2295	BX.debug(arguments);
2296};
2297
2298BX.COpener.prototype.checkAdminMenu = function()
2299{
2300	if (document.documentElement.id == 'bx-admin-prefix')
2301		return true;
2302
2303	return !!BX.findParent(this.DIV, {property: {id: 'bx-admin-prefix'}});
2304};
2305
2306BX.COpener.prototype.Toggle = function(e)
2307{
2308	this.__clear_timeout();
2309
2310	if (!this.bMenuInit || !this.MENU.visible())
2311	{
2312		var t = this.TIMEOUT;
2313		this.TIMEOUT = 0;
2314		this.Open(e);
2315		this.TIMEOUT = t;
2316	}
2317	else
2318	{
2319		this.MENU.Close();
2320	}
2321
2322	return !!(e||window.event) && BX.PreventDefault(e);
2323};
2324
2325BX.COpener.prototype.GetMenu = function()
2326{
2327	if (!this.bMenuInit)
2328	{
2329		if (BX.type.isArray(this.MENU))
2330		{
2331			this.MENU = new BX.CMenu({
2332				ITEMS: this.MENU,
2333				ATTACH_MODE: this.ATTACH_MODE,
2334				SET_ID: this.checkAdminMenu() ? 'bx-admin-prefix' : '',
2335				CLOSE_ON_CLICK: !!this.CLOSE_ON_CLICK,
2336				ADJUST_ON_CLICK: !!this.ADJUST_ON_CLICK,
2337				LEVEL: this.LEVEL,
2338				parent: BX(this.DIV),
2339				parent_attach: BX(this.ATTACH)
2340			});
2341
2342			if (this.LEVEL > 0)
2343			{
2344				BX.bind(this.MENU.DIV, 'mouseover', BX.proxy(this._on_menu_hover, this));
2345				BX.bind(this.MENU.DIV, 'mouseout', BX.proxy(this._on_menu_hout, this));
2346			}
2347		}
2348
2349		BX.addCustomEvent(this.MENU, 'onMenuOpen', BX.proxy(this.handler_onopen, this));
2350		BX.addCustomEvent(this.MENU, 'onMenuClose', BX.proxy(this.handler_onclose, this));
2351
2352		BX.addCustomEvent('onMenuItemHover', BX.proxy(this.handler_onover, this));
2353
2354		this.bMenuInit = true;
2355	}
2356
2357	return this.MENU;
2358};
2359
2360BX.COpener.prototype.Open = function()
2361{
2362	this.GetMenu();
2363
2364	this.bOpen = true;
2365
2366	this.__clear_timeout();
2367
2368	if (this.TIMEOUT > 0)
2369	{
2370		BX.bind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
2371		this._openTimeout = setTimeout(BX.proxy(this.__open, this), this.TIMEOUT);
2372	}
2373	else
2374	{
2375		this.__open();
2376	}
2377
2378	if (!!this.PARAMS.MENU_URL && !this.bMenuLoaded)
2379	{
2380		this._loadTimeout = setTimeout(BX.proxy(this.Load, this), parseInt(this.TIMEOUT/2));
2381	}
2382
2383	return true;
2384};
2385
2386BX.COpener.prototype.__clear_timeout = function()
2387{
2388	if (!!this._openTimeout)
2389		clearTimeout(this._openTimeout);
2390	if (!!this._loadTimeout)
2391		clearTimeout(this._loadTimeout);
2392
2393	BX.unbind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
2394};
2395
2396BX.COpener.prototype._on_menu_hover = function()
2397{
2398	this.bMenuHover = true;
2399
2400	this.__clear_timeout();
2401
2402	if (this.ACTIVE_CLASS)
2403		BX.addClass(this.DIV, this.ACTIVE_CLASS);
2404
2405};
2406
2407BX.COpener.prototype._on_menu_hout = function()
2408{
2409	this.bMenuHover = false;
2410};
2411
2412BX.COpener.prototype.handler_onover = function(level, opener)
2413{
2414	if (this.bMenuHover)
2415		return;
2416
2417	if (opener != this && level == this.LEVEL-1 && this.ACTIVE_CLASS)
2418	{
2419		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
2420	}
2421
2422	if (this.bMenuInit && level <= this.LEVEL-1 && this.MENU.visible())
2423	{
2424		if (opener != this)
2425		{
2426			this.__clear_timeout();
2427			this._openTimeout = setTimeout(BX.proxy(this.Close, this), this.TIMEOUT);
2428		}
2429	}
2430};
2431
2432BX.COpener.prototype.handler_onopen = function()
2433{
2434	this.bOpen = true;
2435
2436	if (this.ACTIVE_CLASS)
2437		BX.addClass(this.DIV, this.ACTIVE_CLASS);
2438
2439	BX.defer(function() {
2440		BX.onCustomEvent(this, 'onOpenerMenuOpen');
2441	}, this)();
2442};
2443
2444BX.COpener.prototype.handler_onclose = function()
2445{
2446	this.bOpen = false;
2447	BX.onCustomEvent(this, 'onOpenerMenuClose');
2448
2449	if (this.ACTIVE_CLASS)
2450		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
2451};
2452
2453BX.COpener.prototype.Close = function()
2454{
2455	if (!this.bMenuInit)
2456		return;
2457
2458	if (!!this._openTimeout)
2459		clearTimeout(this._openTimeout);
2460
2461	this.bOpen = false;
2462
2463	this.__close();
2464};
2465
2466BX.COpener.prototype.__open = function()
2467{
2468	this.__clear_timeout();
2469
2470	if (this.bMenuInit && this.bOpen && !this.MENU.visible())
2471		this.MENU.Show();
2472};
2473
2474BX.COpener.prototype.__close = function()
2475{
2476	if (this.bMenuInit && !this.bOpen && this.MENU.visible())
2477		this.MENU.Hide();
2478};
2479
2480BX.COpener.prototype.__close_immediately = function() {
2481	this.bOpen = false; this.__close();
2482};
2483
2484BX.COpener.prototype.isMenuVisible = function() {
2485	return null != this.MENU.visible && this.MENU.visible()
2486};
2487
2488/* common menu class */
2489
2490BX.CMenu = function(arParams)
2491{
2492	BX.CMenu.superclass.constructor.apply(this);
2493
2494	this.DIV.style.width = 'auto';//this.DIV.firstChild.offsetWidth + 'px';
2495	this.DIV.style.height = 'auto';//this.DIV.firstChild.offsetHeight + 'px';
2496
2497	this.PARAMS = arParams || {};
2498	this.PARTS = {};
2499
2500	this.PARAMS.ATTACH_MODE = this.PARAMS.ATTACH_MODE || 'bottom';
2501	this.PARAMS.CLOSE_ON_CLICK = typeof this.PARAMS.CLOSE_ON_CLICK == 'undefined' ? true : this.PARAMS.CLOSE_ON_CLICK;
2502	this.PARAMS.ADJUST_ON_CLICK = typeof this.PARAMS.ADJUST_ON_CLICK == 'undefined' ? true : this.PARAMS.ADJUST_ON_CLICK;
2503	this.PARAMS.LEVEL = this.PARAMS.LEVEL || 0;
2504
2505	this.DIV.className = 'bx-core-popup-menu bx-core-popup-menu-' + this.PARAMS.ATTACH_MODE + ' bx-core-popup-menu-level' + this.PARAMS.LEVEL + (typeof this.PARAMS.ADDITIONAL_CLASS != 'undefined' ? ' ' + this.PARAMS.ADDITIONAL_CLASS : '');
2506	if (!!this.PARAMS.SET_ID)
2507		this.DIV.id = this.PARAMS.SET_ID;
2508
2509	if (this.PARAMS.LEVEL == 0)
2510	{
2511		this.ARROW = this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-core-popup-menu-angle'}, style: {left:'15px'}}));
2512	}
2513
2514	if (!!this.PARAMS.CLASS_NAME)
2515		this.DIV.className += ' ' + this.PARAMS.CLASS_NAME;
2516
2517	BX.bind(this.DIV, 'click', BX.eventCancelBubble);
2518
2519	this.ITEMS = [];
2520
2521	this.setItems(this.PARAMS.ITEMS);
2522
2523	BX.addCustomEvent('onMenuOpen', BX.proxy(this._onMenuOpen, this));
2524	BX.addCustomEvent('onMenuItemSelected', BX.proxy(this.Hide, this));
2525};
2526BX.extend(BX.CMenu, BX.CWindowFloat);
2527
2528BX.CMenu.broadcastCloseEvent = function()
2529{
2530	BX.onCustomEvent("onMenuItemSelected");
2531};
2532
2533BX.CMenu._toggleChecked = function()
2534{
2535	BX.toggleClass(this, 'bx-core-popup-menu-item-checked');
2536};
2537
2538BX.CMenu._itemDblClick = function()
2539{
2540	window.location.href = this.href;
2541};
2542
2543BX.CMenu.prototype.toggleArrow = function(v)
2544{
2545	if (!!this.ARROW)
2546	{
2547		if (typeof v == 'undefined')
2548		{
2549			v = this.ARROW.style.visibility == 'hidden';
2550		}
2551
2552		this.ARROW.style.visibility = !!v ? 'visible' : 'hidden';
2553	}
2554};
2555
2556BX.CMenu.prototype.visible = function()
2557{
2558	return this.DIV.style.display !== 'none';
2559};
2560
2561BX.CMenu.prototype._onMenuOpen = function(menu, menu_level)
2562{
2563	if (this.visible())
2564	{
2565		if (menu_level == this.PARAMS.LEVEL && menu != this)
2566		{
2567			this.Hide();
2568		}
2569	}
2570};
2571
2572BX.CMenu.prototype.onUnRegister = function()
2573{
2574	if (!this.visible())
2575		return;
2576
2577	this.Hide();
2578};
2579
2580BX.CMenu.prototype.setItems = function(items)
2581{
2582	this.PARAMS.ITEMS = items;
2583
2584	BX.cleanNode(this.DIV);
2585
2586	if (!!this.ARROW)
2587		this.DIV.appendChild(this.ARROW);
2588
2589	if (this.PARAMS.ITEMS)
2590	{
2591		this.PARAMS.ITEMS = BX.util.array_values(this.PARAMS.ITEMS);
2592
2593		var bIcons = false;
2594		var cnt = 0;
2595		for (var i = 0, len = this.PARAMS.ITEMS.length; i < len; i++)
2596		{
2597			if ((i == 0 || i == len-1) && this.PARAMS.ITEMS[i].SEPARATOR)
2598				continue;
2599
2600			cnt++;
2601
2602			if (!bIcons)
2603				bIcons = !!this.PARAMS.ITEMS[i].GLOBAL_ICON;
2604
2605			this.addItem(this.PARAMS.ITEMS[i], i);
2606		}
2607
2608		// Occam turning in his grave
2609		if (cnt === 1)
2610			BX.addClass(this.DIV, 'bx-core-popup-menu-single-item');
2611		else
2612			BX.removeClass(this.DIV, 'bx-core-popup-menu-single-item');
2613
2614		if (!bIcons)
2615			BX.addClass(this.DIV, 'bx-core-popup-menu-no-icons');
2616		else
2617			BX.removeClass(this.DIV, 'bx-core-popup-menu-no-icons');
2618
2619	}
2620};
2621
2622BX.CMenu.prototype.addItem = function(item)
2623{
2624	this.ITEMS.push(item);
2625
2626	if (item.SEPARATOR)
2627	{
2628		item.NODE = BX.create(
2629			'DIV', {props: {className: 'bx-core-popup-menu-separator'}}
2630		);
2631	}
2632	else
2633	{
2634		var bHasMenu = (!!item.MENU
2635			&& (
2636				(BX.type.isArray(item.MENU) && item.MENU.length > 0)
2637				|| item.MENU instanceof BX.CMenu
2638			) || !!item.MENU_URL
2639		);
2640
2641		if (item.DISABLED)
2642		{
2643			item.CLOSE_ON_CLICK = false;
2644			item.LINK = null;
2645			item.ONCLICK = null;
2646			item.ACTION = null;
2647		}
2648
2649		item.NODE = BX.create(!!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype() ? 'A' : 'SPAN', {
2650			props: {
2651				className: 'bx-core-popup-menu-item'
2652					+ (bHasMenu ? ' bx-core-popup-menu-item-opener' : '')
2653					+ (!!item.DEFAULT ? ' bx-core-popup-menu-item-default' : '')
2654					+ (!!item.DISABLED ? ' bx-core-popup-menu-item-disabled' : '')
2655					+ (!!item.CHECKED ? ' bx-core-popup-menu-item-checked' : ''),
2656					title: !!BX.message['MENU_ENABLE_TOOLTIP'] || !!item.SHOW_TITLE ? item.TITLE || '' : '',
2657				BXMENULEVEL: this.PARAMS.LEVEL
2658			},
2659			attrs: !!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype() ? {href: item.LINK || 'javascript:void(0)'} : {},
2660			events: {
2661				mouseover: function()
2662				{
2663					BX.onCustomEvent('onMenuItemHover', [this.BXMENULEVEL, this.OPENER])
2664				}
2665			},
2666			html: '<span class="bx-core-popup-menu-item-icon' + (item.GLOBAL_ICON ? ' '+item.GLOBAL_ICON : '') + '"></span><span class="bx-core-popup-menu-item-text">'+item.TEXT+'</span>'
2667		});
2668
2669		if (bHasMenu && !item.DISABLED)
2670		{
2671			item.NODE.OPENER = new BX.COpener({
2672				DIV: item.NODE,
2673				ACTIVE_CLASS: 'bx-core-popup-menu-item-opened',
2674				TYPE: 'hover',
2675				MENU: item.MENU,
2676				MENU_URL: item.MENU_URL,
2677				MENU_PRELOAD: !!item.MENU_PRELOAD,
2678				LEVEL: this.PARAMS.LEVEL + 1,
2679				ATTACH_MODE:'right',
2680				TIMEOUT: 500
2681			});
2682		}
2683		else if (this.PARAMS.CLOSE_ON_CLICK && (typeof item.CLOSE_ON_CLICK == 'undefined' || !!item.CLOSE_ON_CLICK))
2684		{
2685			BX.bind(item.NODE, 'click', BX.CMenu.broadcastCloseEvent);
2686		}
2687		else if (this.PARAMS.ADJUST_ON_CLICK && (typeof item.ADJUST_ON_CLICK == 'undefined' || !!item.ADJUST_ON_CLICK))
2688		{
2689			BX.bind(item.NODE, 'click', BX.defer(this.adjustPos, this));
2690		}
2691
2692		if (bHasMenu && !!item.LINK)
2693		{
2694			BX.bind(item.NODE, 'dblclick', BX.CMenu._itemDblClick);
2695		}
2696
2697		if (typeof item.CHECKED != 'undefined')
2698		{
2699			BX.bind(item.NODE, 'click', BX.CMenu._toggleChecked);
2700		}
2701
2702		item.ONCLICK = item.ACTION || item.ONCLICK;
2703		if (!!item.ONCLICK)
2704		{
2705			if (BX.type.isString(item.ONCLICK))
2706			{
2707				item.ONCLICK = new Function("event", item.ONCLICK);
2708			}
2709
2710			BX.bind(item.NODE, 'click', item.ONCLICK);
2711		}
2712	}
2713
2714	this.DIV.appendChild(item.NODE);
2715};
2716
2717BX.CMenu.prototype._documentClickBind = function()
2718{
2719	this._documentClickUnBind();
2720	BX.bind(document, 'click', BX.proxy(this._documentClick, this));
2721};
2722
2723BX.CMenu.prototype._documentClickUnBind = function()
2724{
2725	BX.unbind(document, 'click', BX.proxy(this._documentClick, this));
2726};
2727
2728BX.CMenu.prototype._documentClick = function(e)
2729{
2730	e = e||window.event;
2731	if(!!e && !(BX.getEventButton(e) & BX.MSLEFT))
2732		return;
2733
2734	this.Close();
2735};
2736
2737BX.CMenu.prototype.Show = function()
2738{
2739	BX.onCustomEvent(this, 'onMenuOpen', [this, this.PARAMS.LEVEL]);
2740	BX.CMenu.superclass.Show.apply(this, []);
2741
2742	this.bCloseEventFired = false;
2743
2744	BX.addCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
2745
2746	(BX.defer(this._documentClickBind, this))();
2747};
2748
2749BX.CMenu.prototype.Close = // we shouldn't 'Close' window - only hide
2750BX.CMenu.prototype.Hide = function()
2751{
2752	if (!this.visible())
2753		return;
2754
2755	BX.removeCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
2756
2757	this._documentClickUnBind();
2758
2759	if (!this.bCloseEventFired)
2760	{
2761		BX.onCustomEvent(this, 'onMenuClose', [this, this.PARAMS.LEVEL]);
2762		this.bCloseEventFired = true;
2763	}
2764	BX.CMenu.superclass.Hide.apply(this, arguments);
2765
2766
2767//	this.DIV.onclick = null;
2768	//this.PARAMS.parent.onclick = null;
2769};
2770
2771BX.CMenu.prototype.__adjustMenuToNode = function()
2772{
2773	var pos = BX.pos(this.PARAMS.parent_attach),
2774		bFixed = !!BX.findParent(this.PARAMS.parent_attach, BX.is_fixed);
2775
2776	if (bFixed)
2777		this.DIV.style.position = 'fixed';
2778	else
2779		this.DIV.style.position = 'absolute';
2780
2781	if (!pos.top)
2782	{
2783		this.DIV.style.top = '-1000px';
2784		this.DIV.style.left = '-1000px';
2785	}
2786
2787	if (this.bTimeoutSet) return;
2788
2789	var floatWidth = this.DIV.offsetWidth, floatHeight = this.DIV.offsetHeight;
2790	if (!floatWidth)
2791	{
2792		setTimeout(BX.delegate(function(){
2793			this.bTimeoutSet = false; this.__adjustMenuToNode();
2794		}, this), 100);
2795
2796		this.bTimeoutSet = true;
2797		return;
2798	}
2799
2800	var menu_pos = {},
2801		wndSize = BX.GetWindowSize();
2802
2803/*
2804	if (BX.browser.IsIE() && !BX.browser.IsDoctype())
2805	{
2806		pos.top -= 4; pos.bottom -= 4;
2807		pos.left -= 2; pos.right -= 2;
2808	}
2809*/
2810
2811	switch (this.PARAMS.ATTACH_MODE)
2812	{
2813		case 'bottom':
2814			menu_pos.top = pos.bottom + 9;
2815			menu_pos.left = pos.left;
2816
2817			var arrowPos = 0;
2818			if (!!this.ARROW)
2819			{
2820				if (pos.width > floatWidth)
2821					arrowPos = parseInt(floatWidth/2 - 7);
2822				else
2823					arrowPos = parseInt(Math.min(floatWidth, pos.width)/2 - 7);
2824
2825				if (arrowPos < 7)
2826				{
2827					menu_pos.left -= 15;
2828					arrowPos += 15;
2829				}
2830			}
2831
2832			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
2833			{
2834				var orig_menu_pos = menu_pos.left;
2835				menu_pos.left = wndSize.scrollWidth - floatWidth - 10;
2836
2837				if (!!this.ARROW)
2838					arrowPos += orig_menu_pos - menu_pos.left;
2839			}
2840
2841			if (bFixed)
2842			{
2843				menu_pos.left -= wndSize.scrollLeft;
2844			}
2845
2846			if (!!this.ARROW)
2847				this.ARROW.style.left = arrowPos + 'px';
2848		break;
2849		case 'right':
2850			menu_pos.top = pos.top-1;
2851			menu_pos.left = pos.right;
2852
2853			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
2854			{
2855				menu_pos.left = pos.left - floatWidth - 1;
2856			}
2857		break;
2858	}
2859
2860	if (bFixed)
2861	{
2862		menu_pos.top -= wndSize.scrollTop;
2863	}
2864
2865	if (!!this.ARROW)
2866		this.ARROW.className = 'bx-core-popup-menu-angle';
2867
2868	if((menu_pos.top + floatHeight >
2868 wndSize.scrollTop + wndSize.innerHeight)
2869		|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
2870	{
2871		var new_top = this.PARAMS.ATTACH_MODE == 'bottom'
2872			? pos.top - floatHeight - 9
2873			: pos.bottom - floatHeight + 1;
2874
2875		if((new_top > wndSize.scrollTop)
2876			|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
2877		{
2878			if ((menu_pos.top + floatHeight > wndSize.scrollHeight))
2879			{
2880				menu_pos.top = Math.max(0, wndSize.scrollHeight-floatHeight);
2881				this.toggleArrow(false);
2882			}
2883			else
2884			{
2885				menu_pos.top = new_top;
2886
2887				if (!!this.ARROW)
2888					this.ARROW.className = 'bx-core-popup-menu-angle-bottom';
2889			}
2890		}
2891	}
2892
2893	if (menu_pos.top + menu_pos.left == 0)
2894	{
2895		this.Hide();
2896	}
2897	else
2898	{
2899		this.DIV.style.top = menu_pos.top + 'px';
2900		this.DIV.style.left = menu_pos.left + 'px';
2901	}
2902};
2903
2904BX.CMenu.prototype.adjustToNode = function(el)
2905{
2906	this.PARAMS.parent_attach = BX(el) || this.PARAMS.parent_attach || this.PARAMS.parent;
2907	this.__adjustMenuToNode();
2908};
2909
2910
2911/* components toolbar class */
2912
2913BX.CMenuOpener = function(arParams)
2914{
2915	BX.CMenuOpener.superclass.constructor.apply(this);
2916
2917	this.PARAMS = arParams || {};
2918	this.setParent(this.PARAMS.parent);
2919	this.PARTS = {};
2920
2921	this.SETTINGS.drag_restrict = true;
2922
2923	this.defaultAction = null;
2924
2925	this.timeout = 500;
2926
2927	this.DIV.className = 'bx-component-opener';
2928	this.DIV.ondblclick = BX.PreventDefault;
2929
2930	if (this.PARAMS.component_id)
2931	{
2932		this.PARAMS.transform = !!this.PARAMS.transform;
2933	}
2934
2935	this.OPENERS = [];
2936
2937	this.DIV.appendChild(BX.create('SPAN', {
2938		props: {className: 'bx-context-toolbar' + (this.PARAMS.transform ? ' bx-context-toolbar-vertical-mode' : '')}
2939	}));
2940
2941	//set internal structure and register draggable element
2942	this.PARTS.INNER = this.DIV.firstChild.appendChild(BX.create('SPAN', {
2943		props: {className: 'bx-context-toolbar-inner'},
2944		html: '<span class="bx-context-toolbar-drag-icon"></span><span class="bx-context-toolbar-vertical-line"></span><br>'
2945	}));
2946
2947	this.EXTRA_BUTTONS = {};
2948
2949	var btnCount = 0;
2950	for (var i = 0, len = this.PARAMS.menu.length; i < len; i++)
2951	{
2952		var item = this.addItem(this.PARAMS.menu[i]);
2953		if (null != item)
2954		{
2955			btnCount++;
2956			this.PARTS.INNER.appendChild(item);
2957			this.PARTS.INNER.appendChild(BX.create('BR'));
2958		}
2959	}
2960	var bHasButtons = btnCount > 0;
2961
2962	//menu items will be attached here
2963
2964	this.PARTS.ICONS = this.PARTS.INNER.appendChild(BX.create('SPAN', {
2965		props: {className: 'bx-context-toolbar-icons'}
2966	}));
2967
2968	if (this.PARAMS.component_id)
2969	{
2970		this.PARAMS.pin = !!this.PARAMS.pin;
2971
2972		if (bHasButtons)
2973			this.PARTS.ICONS.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-separator'}}));
2974
2975		this.PARTS.ICON_PIN = this.PARTS.ICONS.appendChild(BX.create('A', {
2976			attrs: {
2977				href: 'javascript:void(0)'
2978			},
2979			props: {
2980				className: this.PARAMS.pin
2981							? 'bx-context-toolbar-pin-fixed'
2982							: 'bx-context-toolbar-pin'
2983			},
2984			events: {
2985				click: BX.delegate(this.__pin_btn_clicked, this)
2986			}
2987		}));
2988	}
2989
2990
2991	if (this.EXTRA_BUTTONS['components2_props'])
2992	{
2993		var btn = this.EXTRA_BUTTONS['components2_props'] || {URL: 'javascript:void(0)'};
2994		if (null == this.defaultAction)
2995		{
2996			this.defaultAction = btn.ONCLICK;
2997			this.defaultActionTitle = btn.TITLE || btn.TEXT;
2998		}
2999
3000		btn.URL = 'javascript:' + BX.util.urlencode(btn.ONCLICK);
3001
3002		this.ATTACH = this.PARTS.ICONS.appendChild(BX.create('SPAN', {
3003			props: {className: 'bx-context-toolbar-button bx-context-toolbar-button-settings' },
3004			children:
3005			[
3006				BX.create('SPAN',
3007				{
3008					props:{className: 'bx-context-toolbar-button-inner'},
3009					children:
3010					[
3011						BX.create('A', {
3012							attrs: {href: btn.URL},
3013							events: {
3014								mouseover: BX.proxy(this.__msover_text, this),
3015								mouseout: BX.proxy(this.__msout_text, this),
3016								mousedown: BX.proxy(this.__msdown_text, this)
3017							},
3018							html: '<span class="bx-context-toolbar-button-icon bx-context-toolbar-settings-icon"></span>'
3019						}),
3020						BX.create('A', {
3021							attrs: {href: 'javascript: void(0)'},
3022							props: {className: 'bx-context-toolbar-button-arrow'},
3023							events: {
3024								mouseover: BX.proxy(this.__msover_arrow, this),
3025								mouseout: BX.proxy(this.__msout_arrow, this),
3026								mousedown: BX.proxy(this.__msdown_arrow, this)
3027							},
3028							html: '<span class="bx-context-toolbar-button-arrow"></span>'
3029						})
3030					]
3031				})
3032			]
3033		}));
3034
3035		this.OPENER = this.ATTACH.firstChild.lastChild;
3036
3037		var opener = this.attachMenu(this.EXTRA_BUTTONS['components2_submenu']['MENU']);
3038
3039		BX.addCustomEvent(opener, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
3040		BX.addCustomEvent(opener, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
3041	}
3042
3043	if (btnCount > 1)
3044	{
3045		this.PARTS.ICONS.appendChild(BX.create('span', { props: {className: 'bx-context-toolbar-separator bx-context-toolbar-separator-switcher'}}));
3046
3047		this.ICON_TRANSFORM = this.PARTS.ICONS.appendChild(BX.create('A', {
3048			attrs: {href: 'javascript: void(0)'},
3049			props: {className: 'bx-context-toolbar-switcher'},
3050			events: {
3051				click: BX.delegate(this.__trf_btn_clicked, this)
3052			}
3053		}));
3054	}
3055
3056	if (this.PARAMS.HINT)
3057	{
3058		this.DIV.BXHINT = this.HINT = new BX.CHint({
3059			parent: this.DIV,
3060			hint:this.PARAMS.HINT.TEXT || '',
3061			title: this.PARAMS.HINT.TITLE || '',
3062			hide_timeout: this.timeout/2,
3063			preventHide: false
3064		});
3065	}
3066
3067	BX.addCustomEvent(this, 'onWindowDragFinished', BX.delegate(this.__onMoveFinished, this));
3068	BX.addCustomEvent('onDynamicModeChange', BX.delegate(this.__onDynamicModeChange, this));
3069	BX.addCustomEvent('onTopPanelCollapse', BX.delegate(this.__onPanelCollapse, this));
3070
3071	BX.addCustomEvent('onMenuOpenerMoved', BX.delegate(this.checkPosition, this));
3072	BX.addCustomEvent('onMenuOpenerUnhide', BX.delegate(this.checkPosition, this));
3073
3074	if (this.OPENERS)
3075	{
3076		for (i=0,len=this.OPENERS.length; i<len; i++)
3077		{
3078			BX.addCustomEvent(this.OPENERS[i], 'onOpenerMenuOpen', BX.proxy(this.__hide_hint, this));
3079		}
3080	}
3081};
3082BX.extend(BX.CMenuOpener, BX.CWindowFloat);
3083
3084BX.CMenuOpener.prototype.setParent = function(new_parent)
3085{
3086	new_parent = BX(new_parent);
3087	if(new_parent.OPENER && new_parent.OPENER != this)
3088	{
3089		new_parent.OPENER.Close();
3090		new_parent.OPENER.clearHoverHoutEvents();
3091	}
3092
3093	if(this.PARAMS.parent && this.PARAMS.parent != new_parent)
3094	{
3095		this.clearHoverHoutEvents();
3096		this.PARAMS.parent.OPENER = null;
3097	}
3098
3099	this.PARAMS.parent = new_parent;
3100	this.PARAMS.parent.OPENER = this;
3101};
3102
3103BX.CMenuOpener.prototype.setHoverHoutEvents = function(hover, hout)
3104{
3105	if(!this.__opener_events_set)
3106	{
3107		BX.bind(this.Get(), 'mouseover', hover);
3108		BX.bind(this.Get(), 'mouseout', hout);
3109		this.__opener_events_set = true;
3110	}
3111};
3112
3113BX.CMenuOpener.prototype.clearHoverHoutEvents = function()
3114{
3115	if(this.Get())
3116	{
3117		BX.unbindAll(this.Get());
3118		this.__opener_events_set = false;
3119	}
3120};
3121
3122
3123BX.CMenuOpener.prototype.unclosable = true;
3124
3125BX.CMenuOpener.prototype.__check_intersection = function(pos_self, pos_other)
3126{
3127	return !(pos_other.right <= pos_self.left || pos_other.left >= pos_self.right
3128			|| pos_other.bottom <= pos_self.top || pos_other.top >= pos_self.bottom);
3129};
3130
3131
3132BX.CMenuOpener.prototype.__msover_text = function() {
3133	this.bx_hover = true;
3134	if (!this._menu_open)
3135		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-hover');
3136};
3137
3138BX.CMenuOpener.prototype.__msout_text = function() {
3139	this.bx_hover = false;
3140	if (!this._menu_open)
3141		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
3142};
3143
3144BX.CMenuOpener.prototype.__msover_arrow = function() {
3145	this.bx_hover = true;
3146	if (!this._menu_open)
3147		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover');
3148};
3149
3150BX.CMenuOpener.prototype.__msout_arrow = function() {
3151	this.bx_hover = false;
3152	if (!this._menu_open)
3153		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
3154};
3155
3156BX.CMenuOpener.prototype.__msdown_text = function() {
3157	this.bx_active = true;
3158	if (!this._menu_open)
3159		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-active');
3160};
3161
3162BX.CMenuOpener.prototype.__msdown_arrow = function() {
3163	this.bx_active = true;
3164	if (!this._menu_open)
3165		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-active');
3166};
3167
3168BX.CMenuOpener.prototype.__menu_close = function() {
3169	this._menu_open = false;
3170	this.bx_active = false;
3171	BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
3172	if (!this.bx_hover)
3173	{
3174		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
3175		this.bx_hover = false;
3176	}
3177};
3178
3179BX.CMenuOpener.prototype.__menu_open = function() {
3180	this._menu_open = true;
3181};
3182
3183BX.CMenuOpener.prototype.checkPosition = function()
3184{
3185	if (this.isMenuVisible() || this.DIV.style.display == 'none'
3186		|| this == BX.proxy_context || BX.proxy_context.zIndex > this.zIndex)
3187		return;
3188
3189	this.correctPosition(BX.proxy_context);
3190};
3191
3192BX.CMenuOpener.prototype.correctPosition = function(opener)
3193{
3194	var pos_self = BX.pos(this.DIV), pos_other = BX.pos(opener.Get());
3195	if (this.__check_intersection(pos_self, pos_other))
3196	{
3197		var new_top = pos_other.top - pos_self.height;
3198		if (new_top < 0)
3199			new_top = pos_other.bottom;
3200
3201		this.DIV.style.top = new_top + 'px';
3202
3203		BX.addCustomEvent(opener, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
3204		BX.onCustomEvent(this, 'onMenuOpenerMoved');
3205	}
3206};
3207
3208BX.CMenuOpener.prototype.restorePosition = function()
3209{
3210	if (!this.MOUSEOVER && !this.isMenuVisible())
3211	{
3212		if (this.originalPos)
3213			this.DIV.style.top = this.originalPos.top + 'px';
3214
3215		BX.removeCustomEvent(BX.proxy_context, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
3216		if (this.restore_pos_timeout) clearTimeout(this.restore_pos_timeout);
3217	}
3218	else
3219	{
3220		this.restore_pos_timeout = setTimeout(BX.proxy(this.restorePosition, this), this.timeout);
3221	}
3222};
3223
3224
3225BX.CMenuOpener.prototype.Show = function()
3226{
3227	BX.CMenuOpener.superclass.Show.apply(this, arguments);
3228
3229	this.SetDraggable(this.PARTS.INNER.firstChild);
3230
3231	this.DIV.style.width = 'auto';
3232	this.DIV.style.height = 'auto';
3233
3234	if (!this.PARAMS.pin)
3235	{
3236		this.DIV.style.left = '-1000px';
3237		this.DIV.style.top = '-1000px';
3238
3239		this.Hide();
3240	}
3241	else
3242	{
3243		this.bPosAdjusted = true;
3244		this.bMoved = true;
3245
3246		if (this.PARAMS.top) this.DIV.style.top = this.PARAMS.top + 'px';
3247		if (this.PARAMS.left) this.DIV.style.left = this.PARAMS.left + 'px';
3248
3249		this.DIV.style.display = (!BX.admin.dynamic_mode || BX.admin.dynamic_mode_show_borders) ? 'block' : 'none';
3250
3251		if (this.DIV.style.display == 'block')
3252		{
3253			setTimeout(BX.delegate(function() {BX.onCustomEvent(this, 'onMenuOpenerUnhide')}, this), 50);
3254		}
3255	}
3256};
3257
3258BX.CMenuOpener.prototype.executeDefaultAction = function()
3259{
3260	if (this.defaultAction)
3261	{
3262		if (BX.type.isFunction(this.defaultAction))
3263			this.defaultAction();
3264		else if(BX.type.isString(this.defaultAction))
3265			BX.evalGlobal(this.defaultAction);
3266	}
3267};
3268
3269BX.CMenuOpener.prototype.__onDynamicModeChange = function(val)
3270{
3271	this.DIV.style.display = val ? 'block' : 'none';
3272};
3273
3274BX.CMenuOpener.prototype.__onPanelCollapse = function(bCollapsed, dy)
3275{
3276	this.DIV.style.top = (parseInt(this.DIV.style.top) + dy) + 'px';
3277	if (this.PARAMS.pin)
3278	{
3279		this.__savePosition();
3280	}
3281};
3282
3283BX.CMenuOpener.prototype.__onMoveFinished = function()
3284{
3285	BX.onCustomEvent(this, 'onMenuOpenerMoved');
3286
3287	this.bMoved = true;
3288
3289	if (this.PARAMS.pin)
3290		this.__savePosition();
3291};
3292
3293BX.CMenuOpener.prototype.__savePosition = function()
3294{
3295	var arOpts = {};
3296
3297	arOpts.pin = this.PARAMS.pin;
3298	if (!this.PARAMS.pin)
3299	{
3300		arOpts.top = false; arOpts.left = false; arOpts.transform = false;
3301	}
3302	else
3303	{
3304		arOpts.transform = this.PARAMS.transform;
3305		if (this.bMoved)
3306		{
3307			arOpts.left = parseInt(this.DIV.style.left);
3308			arOpts.top = parseInt(this.DIV.style.top);
3309		}
3310	}
3311
3312	BX.WindowManager.saveWindowOptions(this.PARAMS.component_id, arOpts);
3313};
3314
3315BX.CMenuOpener.prototype.__pin_btn_clicked = function() {this.Pin()};
3316BX.CMenuOpener.prototype.Pin = function(val)
3317{
3318	if (null == val)
3319		this.PARAMS.pin = !this.PARAMS.pin;
3320	else
3321		this.PARAMS.pin = !!val;
3322
3323	this.PARTS.ICON_PIN.className = (this.PARAMS.pin ? 'bx-context-toolbar-pin-fixed' : 'bx-context-toolbar-pin');
3324
3325	this.__savePosition();
3326};
3327
3328BX.CMenuOpener.prototype.__trf_btn_clicked = function() {this.Transform()};
3329BX.CMenuOpener.prototype.Transform = function(val)
3330{
3331	var pos = {};
3332
3333	if (null == val)
3334		this.PARAMS.transform = !this.PARAMS.transform;
3335	else
3336		this.PARAMS.transform = !!val;
3337
3338	if (this.bMoved)
3339	{
3340		pos = BX.pos(this.DIV);
3341	}
3342
3343	if (this.PARAMS.transform)
3344		BX.addClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
3345	else
3346		BX.removeClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
3347
3348	if (!this.bMoved)
3349	{
3350		this.adjustPos();
3351	}
3352	else
3353	{
3354		this.DIV.style.left = (pos.right - this.DIV.offsetWidth - (BX.browser.IsIE() && !BX.browser.IsDoctype() ? 2 : 0)) + 'px';
3355	}
3356
3357	this.__savePosition();
3358};
3359
3360BX.CMenuOpener.prototype.adjustToNodeGetPos = function()
3361{
3362	var pos = BX.pos(this.PARAMS.parent/*, true*/);
3363
3364	var scrollSize = BX.GetWindowScrollSize();
3365	var floatWidth = this.DIV.offsetWidth;
3366
3367	pos.left -= BX.admin.__border_dx;
3368	pos.top -= BX.admin.__border_dx;
3369
3370	if (true || !this.PARAMS.transform)
3371	{
3372		pos.top -= 45;
3373	}
3374
3375	if (pos.left > scrollSize.scrollWidth - floatWidth)
3376	{
3377		pos.left = scrollSize.scrollWidth - floatWidth;
3378	}
3379
3380	return pos;
3381};
3382
3383BX.CMenuOpener.prototype.addItem = function(item)
3384{
3385	if (item.TYPE)
3386	{
3387		this.EXTRA_BUTTONS[item.TYPE] = item;
3388		return null;
3389	}
3390	else
3391	{
3392		var q = new BX.CMenuOpenerItem(item);
3393		if (null == this.defaultAction)
3394		{
3395			if (q.item.ONCLICK)
3396			{
3397				this.defaultAction = item.ONCLICK;
3398			}
3399			else if (q.item.MENU)
3400			{
3401				this.defaultAction = BX.delegate(function() {this.Open()}, q.item.OPENER);
3402			}
3403
3404			this.defaultActionTitle = item.TITLE || item.TEXT;
3405
3406			BX.addClass(q.Get(), 'bx-content-toolbar-default');
3407		}
3408		if (q.item.OPENER) this.OPENERS[this.OPENERS.length] = q.item.OPENER;
3409		return q.Get();
3410	}
3411};
3412
3413BX.CMenuOpener.prototype.attachMenu = function(menu)
3414{
3415	var opener = new BX.COpener({
3416		'DIV':  this.OPENER,
3417		'ATTACH': this.ATTACH,
3418		'MENU': menu,
3419		'TYPE': 'click'
3420	});
3421
3422	this.OPENERS[this.OPENERS.length] = opener;
3423
3424	return opener;
3425};
3426
3427BX.CMenuOpener.prototype.__hide_hint = function()
3428{
3429	if (this.HINT) this.HINT.__hide_immediately();
3430};
3431
3432BX.CMenuOpener.prototype.isMenuVisible = function()
3433{
3434	for (var i=0,len=this.OPENERS.length; i<len; i++)
3435	{
3436		if (this.OPENERS[i].isMenuVisible())
3437			return true;
3438	}
3439
3440	return false;
3441};
3442
3443BX.CMenuOpener.prototype.Hide = function()
3444{
3445	if (!this.PARAMS.pin)
3446	{
3447		this.DIV.style.display = 'none';
3448		BX.onCustomEvent(this, 'onMenuOpenerHide');
3449	}
3450};
3451BX.CMenuOpener.prototype.UnHide = function()
3452{
3453	this.DIV.style.display = 'block';
3454	if (!this.bPosAdjusted && !this.PARAMS.pin)
3455	{
3456		this.adjustPos();
3457		this.bPosAdjusted = true;
3458	}
3459
3460	if (null == this.originalPos && !this.bMoved)
3461	{
3462		this.originalPos = BX.pos(this.DIV);
3463	}
3464
3465	BX.onCustomEvent(this, 'onMenuOpenerUnhide');
3466};
3467
3468BX.CMenuOpenerItem = function(item)
3469{
3470	this.item = item;
3471
3472	if (this.item.ACTION && !this.item.ONCLICK)
3473	{
3474		this.item.ONCLICK = this.item.ACTION;
3475	}
3476
3477	this.DIV = BX.create('SPAN');
3478	this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-underlay'}}));
3479
3480	this.WRAPPER = this.DIV.appendChild(BX.create('SPAN', {
3481		props: {className: 'bx-context-toolbar-button-wrapper'},
3482		children: [
3483			BX.create('SPAN', {
3484				props: {className: 'bx-context-toolbar-button', title: item.TITLE},
3485				children: [
3486					BX.create('SPAN', {
3487						props: {className: 'bx-context-toolbar-button-inner'}
3488					})
3489				]
3490			})
3491		]
3492	}));
3493
3494	var btn_icon = BX.create('SPAN', {
3495		props: {className: 'bx-context-toolbar-button-icon' + (this.item.ICON || this.item.ICONCLASS ? ' ' + (this.item.ICON || this.item.ICONCLASS) : '')},
3496		attrs: (
3497				!(this.item.ICON || this.item.ICONCLASS)
3498				&&
3499				(this.item.SRC || this.item.IMAGE)
3500			)
3501			? {
3502				style: 'background: scroll transparent url(' + (this.item.SRC || this.item.IMAGE) + ') no-repeat center center !important;'
3503			}
3504			: {}
3505	}), btn_text = BX.create('SPAN', {
3506		props: {className: 'bx-context-toolbar-button-text'},
3507		text: this.item.TEXT
3508	});
3509
3510	if (this.item.ACTION && !this.item.ONCLICK)
3511	{
3512		this.item.ONCLICK = this.item.ACTION;
3513	}
3514
3515	this.bHasMenu = !!this.item.MENU;
3516	this.bHasAction = !!this.item.ONCLICK;
3517
3518	if (this.bHasAction)
3519	{
3520		this.LINK = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
3521			attrs: {
3522				'href': 'javascript: void(0)'
3523			},
3524			events: {
3525				mouseover: this.bHasMenu ? BX.proxy(this.__msover_text, this) : BX.proxy(this.__msover, this),
3526				mouseout: this.bHasMenu ? BX.proxy(this.__msout_text, this) : BX.proxy(this.__msout, this),
3527				mousedown: this.bHasMenu ? BX.proxy(this.__msdown_text, this) : BX.proxy(this.__msdown, this)
3528			},
3529			children: [btn_icon, btn_text]
3530		}));
3531
3532		if (this.bHasMenu)
3533		{
3534			this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
3535				props: {className: 'bx-context-toolbar-button-arrow'},
3536				attrs: {
3537					'href': 'javascript: void(0)'
3538				},
3539				events: {
3540					mouseover: BX.proxy(this.__msover_arrow, this),
3541					mouseout: BX.proxy(this.__msout_arrow, this),
3542					mousedown: BX.proxy(this.__msdown_arrow, this)
3543				},
3544				children: [
3545					BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-arrow'}})
3546				]
3547			}));
3548		}
3549
3550	}
3551	else if (this.bHasMenu)
3552	{
3553		this.item.ONCLICK = null;
3554
3555		this.LINK = this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
3556			attrs: {
3557				'href': 'javascript: void(0)'
3558			},
3559			events: {
3560				mouseover: BX.proxy(this.__msover, this),
3561				mouseout: BX.proxy(this.__msout, this),
3562				mousedown: BX.proxy(this.__msdown, this)
3563			},
3564			children: [
3565				btn_icon,
3566				btn_text
3567			]
3568		}));
3569
3570		this.LINK.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-single-button-arrow'}}));
3571
3572	}
3573
3574	if (this.bHasMenu)
3575	{
3576		this.item.SUBMENU = new BX.CMenu({
3577			ATTACH_MODE:'bottom',
3578			ITEMS:this.item['MENU'],
3579			//PARENT_MENU:this.parentMenu,
3580			parent: this.LINK_MENU,
3581			parent_attach: this.WRAPPER.firstChild
3582		});
3583
3584		this.item.OPENER = new BX.COpener({
3585			DIV: this.LINK_MENU,
3586			TYPE: 'click',
3587			MENU: this.item.SUBMENU
3588		});
3589
3590		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
3591		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
3592	}
3593
3594	if (this.bHasAction)
3595	{
3596		BX.bind(this.LINK, 'click', BX.delegate(this.__click, this));
3597	}
3598};
3599
3600BX.CMenuOpenerItem.prototype.Get = function() {return this.DIV;};
3601BX.CMenuOpenerItem.prototype.__msover = function() {
3602	this.bx_hover = true;
3603	if (!this._menu_open)
3604		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover');
3605};
3606BX.CMenuOpenerItem.prototype.__msout = function() {
3607	this.bx_hover = false;
3608	if (!this._menu_open)
3609		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-active');
3610};
3611BX.CMenuOpenerItem.prototype.__msover_text = function() {
3612	this.bx_hover = true;
3613	if (!this._menu_open)
3614		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover');
3615};
3616BX.CMenuOpenerItem.prototype.__msout_text = function() {
3617	this.bx_hover = false;
3618	if (!this._menu_open)
3619		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
3620};
3621BX.CMenuOpenerItem.prototype.__msover_arrow = function() {
3622	this.bx_hover = true;
3623	if (!this._menu_open)
3624		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover');
3625};
3626BX.CMenuOpenerItem.prototype.__msout_arrow = function() {
3627	this.bx_hover = false;
3628	if (!this._menu_open)
3629		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
3630};
3631BX.CMenuOpenerItem.prototype.__msdown = function() {
3632	this.bx_active = true;
3633	if (!this._menu_open)
3634		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active');
3635};
3636BX.CMenuOpenerItem.prototype.__msdown_text = function() {
3637	this.bx_active = true;
3638	if (!this._menu_open)
3639		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-active');
3640};
3641BX.CMenuOpenerItem.prototype.__msdown_arrow = function() {
3642	this.bx_active = true;
3643	if (!this._menu_open)
3644		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-active');
3645};
3646BX.CMenuOpenerItem.prototype.__menu_close = function() {
3647
3648	this._menu_open = false;
3649	this.bx_active = false;
3650	BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
3651	if (!this.bx_hover)
3652	{
3653		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
3654		this.bx_hover = false;
3655	}
3656};
3657BX.CMenuOpenerItem.prototype.__menu_open = function() {
3658	this._menu_open = true;
3659};
3660
3661BX.CMenuOpenerItem.prototype.__click = function() {BX.evalGlobal(this.item.ONCLICK)};
3662
3663/* global page opener class */
3664BX.CPageOpener = function(arParams)
3665{
3666	//if (null == arParams.pin) arParams.pin = true;
3667	BX.CPageOpener.superclass.constructor.apply(this, arguments);
3668
3669	this.timeout = 505;
3670
3671	window.PAGE_EDIT_CONTROL = this;
3672};
3673BX.extend(BX.CPageOpener, BX.CMenuOpener);
3674
3675BX.CPageOpener.prototype.checkPosition = function()
3676{
3677	if (/*this.isMenuVisible() || this.DIV.style.display == 'none' || */this == BX.proxy_context)
3678		return;
3679
3680	this.correctPosition(BX.proxy_context);
3681};
3682
3683BX.CPageOpener.prototype.correctPosition = function(opener)
3684{
3685	if (this.bPosCorrected) return;
3686	var pos_self;
3687	if (this.DIV.style.display == 'none')
3688	{
3689		pos_self = this.adjustToNodeGetPos();
3690		pos_self.bottom = pos_self.top + 30;
3691		pos_self.right = pos_self.left + 300;
3692	}
3693	else
3694	{
3695		pos_self = BX.pos(this.DIV);
3696	}
3697
3698	var pos_other = BX.pos(opener.Get());
3699	if (this.__check_intersection(pos_self, pos_other))
3700	{
3701		this.DIV.style.display = 'none';
3702		BX.addCustomEvent(opener, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
3703
3704		this.bPosCorrected = true;
3705	}
3706};
3707
3708BX.CPageOpener.prototype.restorePosition = function()
3709{
3710	if (BX.proxy_context && BX.proxy_context.Get().style.display == 'none')
3711	{
3712		this.bPosCorrected = false;
3713
3714		if (this.PARAMS.parent.bx_over || this.PARAMS.pin)
3715			this.UnHide();
3716
3717		BX.removeCustomEvent('onMenuOpenerHide', BX.proxy(this.restorePosition, this));
3718	}
3719};
3720
3721BX.CPageOpener.prototype.UnHide = function()
3722{
3723	if (!this.bPosCorrected)
3724		BX.CPageOpener.superclass.UnHide.apply(this, arguments);
3725};
3726
3727BX.CPageOpener.prototype.Remove = function()
3728{
3729	BX.admin.removeComponentBorder(this.PARAMS.parent);
3730	BX.userOptions.save('global', 'settings', 'page_edit_control_enable', 'N');
3731	this.DIV.style.display = 'none';
3732};
3733
3734/******* HINT ***************/
3735BX.CHintSimple = function()
3736{
3737	BX.CHintSimple.superclass.constructor.apply(this, arguments);
3738};
3739BX.extend(BX.CHintSimple, BX.CHint);
3740
3741BX.CHintSimple.prototype.Init = function()
3742{
3743	this.DIV = document.body.appendChild(BX.create('DIV', {props: {className: 'bx-tooltip-simple'}, style: {display: 'none'}, children: [(this.CONTENT = BX.create('DIV'))]}));
3744
3745	if (this.HINT_TITLE)
3746		this.CONTENT.appendChild(BX.create('B', {text: this.HINT_TITLE}));
3747
3748	if (this.HINT)
3749		this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV')).appendChild(BX.create('SPAN', {html: this.HINT}));
3750
3751	if (this.PARAMS.preventHide)
3752	{
3753		BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
3754		BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
3755	}
3756
3757	this.bInited = true;
3758};
3759
3760/*************************** admin informer **********************************/
3761BX.adminInformer = {
3762
3763	itemsShow: 3,
3764
3765	Init: function (itemsShow)
3766	{
3767		if(itemsShow)
3768			BX.adminInformer.itemsShow = itemsShow;
3769
3770		var informer = BX("admin-informer");
3771
3772		if(informer)
3773			document.body.appendChild(informer);
3774
3775		BX.addCustomEvent("onTopPanelCollapse", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
3776	},
3777
3778	Toggle: function(notifyBlock)
3779	{
3780		var informer = BX("admin-informer");
3781
3782		if(!informer)
3783			return false;
3784
3785		var pos = BX.pos(notifyBlock);
3786
3787		informer.style.top = (parseInt(pos.top)+parseInt(pos.height)+7)+'px';
3788		informer.style.left = pos.left+'px';
3789
3790		if(!BX.hasClass(informer, "adm-informer-active"))
3791			BX.adminInformer.Show(informer);
3792		else
3793			BX.adminInformer.Hide(informer);
3794
3795		return false;
3796	},
3797
3798	Close: function()
3799	{
3800		BX.adminInformer.Hide(BX("admin-informer"));
3801	},
3802
3803	OnInnerClick: function(event)
3804	{
3805		var target = event.target || event.srcElement;
3806
3807		if(target.nodeName.toLowerCase() != 'a' || BX.hasClass(target,"adm-informer-footer"))
3808		{
3809			return BX.PreventDefault(event);
3810		}
3811
3812		return true;
3813	},
3814
3815	ToggleExtra : function()
3816	{
3817		var footerLink = BX("adm-informer-footer");
3818
3819		if (BX.hasClass(footerLink, "adm-informer-footer-collapsed"))
3820			this.ShowAll();
3821		else
3822			this.HideExtra();
3823
3824		return false;
3825	},
3826
3827	ShowAll: function()
3828	{
3829		var informer = BX("admin-informer");
3830		for(var i=0; i<informer.children.length; i++)
3831
3832			if(BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "none") {
3833				informer.children[i].style.display = "block";
3834			}
3835
3836		var footerLink = BX("adm-informer-footer");
3837
3838		if(footerLink.textContent !== undefined)
3839			footerLink.textContent = BX.message('JSADM_AI_HIDE_EXTRA');
3840		else
3841			footerLink.innerText = BX.message('JSADM_AI_HIDE_EXTRA');
3842
3843		BX.removeClass(footerLink, "adm-informer-footer-collapsed");
3844
3845		return false;
3846	},
3847
3848	HideExtra: function()
3849	{
3850		var informer = BX("admin-informer");
3851		var hided = 0;
3852
3853		for(var i=BX.adminInformer.itemsShow+1; i<informer.children.length; i++)
3854		{
3855			if (BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "block") {
3856				informer.children[i].style.display = "none";
3857				hided++;
3858			}
3859		}
3860
3861		var footerLink = BX("adm-informer-footer");
3862
3863		var linkText = BX.message('JSADM_AI_ALL_NOTIF')+" ("+(BX.adminInformer.itemsShow+parseInt(hided))+")";
3864
3865		if(footerLink.textContent !== undefined)
3866			footerLink.textContent = linkText;
3867		else
3868			footerLink.innerText = linkText;
3869
3870		BX.addClass(footerLink, "adm-informer-footer-collapsed");
3871
3872		return false;
3873	},
3874
3875	Show: function(informer)
3876	{
3877		var notifButton = BX("adm-header-notif-block");
3878		if (notifButton)
3879			BX.addClass(notifButton, "adm-header-notif-block-active");
3880
3881		BX.onCustomEvent(informer, 'onBeforeAdminInformerShow');
3882		setTimeout(
3883			BX.proxy(function() {
3884					BX.bind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
3885				},
3886				BX.adminInformer
3887			),0
3888		);
3889		BX.addClass(informer, "adm-informer-active");
3890		setTimeout(function() {BX.addClass(informer, "adm-informer-animate");},0);
3891	},
3892
3893	Hide: function(informer)
3894	{
3895		var notifButton = BX("adm-header-notif-block");
3896		if (notifButton)
3897			BX.removeClass(notifButton, "adm-header-notif-block-active");
3898
3899		BX.unbind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
3900
3901		BX.removeClass(informer, "adm-informer-animate");
3902
3903		if (this.IsAnimationSupported())
3904			setTimeout(function() {BX.removeClass(informer, "adm-informer-active");}, 300);
3905		else
3906			BX.removeClass(informer, "adm-informer-active");
3907
3908		BX.onCustomEvent(informer, 'onAdminInformerHide');
3909		//setTimeout(function() {BX.adminInformer.HideExtra();},500);
3910	},
3911
3912	IsAnimationSupported : function()
3913	{
3914		var d = document.body || document.documentElement;
3915		if (typeof(d.style.transition) == "string")
3916			return true;
3917		else if (typeof(d.style.MozTransition) == "string")
3918			return true;
3919		else if (typeof(d.style.OTransition) == "string")
3920			return true;
3921		else if (typeof(d.style.WebkitTransition) == "string")
3922			return true;
3923		else if (typeof(d.style.msTransition) == "string")
3924			return true;
3925
3926		return false;
3927	},
3928
3929
3930	SetItemHtml: function(itemIdx, html)
3931	{
3932		var itemHtmlDiv = BX("adm-informer-item-html-"+itemIdx);
3933
3934		if(!itemHtmlDiv)
3935			return false;
3936
3937		itemHtmlDiv.innerHTML = html;
3938
3939		return true;
3940	},
3941
3942	SetItemFooter: function(itemIdx, html)
3943	{
3944		var itemFooterDiv = BX("adm-informer-item-footer-"+itemIdx);
3945
3946		if(!itemFooterDiv)
3947			return false;
3948
3949		itemFooterDiv.innerHTML = html;
3950
3951		if(html)
3952			itemFooterDiv.style.display = "block";
3953		else
3954			itemFooterDiv.style.display = "none";
3955
3956		return true;
3957	}
3958
3959};
3960
3961}
3961)(window);
3962

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.