PageSourceSearch

https://izdatsovet.ru/bitrix/js/main/core/core_window.js

js izdatsovet.ru collected 2026-10-02 21:53:44 UTC 96,650 bytes, 3,964 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 (this.PARAMS.buttons[i])
1441			{
1442				//if (!(this.PARAMS.buttons[i] instanceof BX.CWindowButton))
1443				if (!BX.is_subclass_of(this.PARAMS.buttons[i], BX.CWindowButton))
1444				{
1445					var b = this._checkButton(this.PARAMS.buttons[i]); // hack to set links to real CWindowButton object in btnSave etc;
1446					this.PARAMS.buttons[i] = new BX.CWindowButton(this.PARAMS.buttons[i]);
1447					if (b) this[b] = this.PARAMS.buttons[i];
1448				}
1449
1450				result.push(this.PARAMS.buttons[i].Button(this));
1451			}
1452		}
1453	}
1454
1455	return result;
1456};
1457
1458BX.CDialog.prototype.setAutosave = function () {
1459	if (!this.bSetAutosaveDelay)
1460	{
1461		this.bSetAutosaveDelay = true;
1462		setTimeout(BX.proxy(this.setAutosave, this), 10);
1463	}
1464};
1465
1466BX.CDialog.prototype.SetTitle = function(title)
1467{
1468	this.PARAMS.title = title;
1469	BX.cleanNode(this.PARTS.TITLE_CONTAINER).appendChild(document.createTextNode(this.PARAMS.title));
1470};
1471
1472BX.CDialog.prototype.SetHead = function(head)
1473{
1474	this.PARAMS.head = BX.util.trim(head);
1475	this.PARTS.HEAD.innerHTML = this.PARAMS.head || "&nbsp;";
1476	this.PARTS.HEAD.style.display = this.PARAMS.head ? 'block' : 'none';
1477	this.adjustSize();
1478};
1479
1480BX.CDialog.prototype.Notify = function(note, bError)
1481{
1482	if (!this.PARTS.NOTIFY)
1483	{
1484		this.PARTS.NOTIFY = this.DIV.insertBefore(BX.create('DIV', {
1485			props: {className: 'adm-warning-block'},
1486			children: [
1487				BX.create('SPAN', {
1488					props: {className: 'adm-warning-text'}
1489				}),
1490				BX.create('SPAN', {
1491					props: {className: 'adm-warning-icon'}
1492				}),
1493				BX.create('SPAN', {
1494					props: {className: 'adm-warning-close'},
1495					events: {click: BX.proxy(this.hideNotify, this)}
1496				})
1497			]
1498		}), this.DIV.firstChild);
1499	}
1500
1501	if (bError)
1502		BX.addClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
1503	else
1504		BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-block-red');
1505
1506	this.PARTS.NOTIFY.firstChild.innerHTML = note || '&nbsp;';
1507	this.PARTS.NOTIFY.firstChild.style.width = (this.PARAMS.width-50) + 'px';
1508	BX.removeClass(this.PARTS.NOTIFY, 'adm-warning-animate');
1509};
1510
1511BX.CDialog.prototype.hideNotify = function()
1512{
1513	BX.addClass(this.PARTS.NOTIFY, 'adm-warning-animate');
1514};
1515
1516BX.CDialog.prototype.__adjustHeadToIcon = function()
1517{
1518	if (!this.PARTS.HEAD.offsetHeight)
1519	{
1520		setTimeout(BX.delegate(this.__adjustHeadToIcon, this), 50);
1521	}
1522	else
1523	{
1524		if (this.icon_image && this.icon_image.height && this.icon_image.height > this.PARTS.HEAD.offsetHeight - 5)
1525		{
1526			this.PARTS.HEAD.style.height = this.icon_image.height + 5 + 'px';
1527			this.adjustSize();
1528		}
1529
1530		this.icon_image.onload = null;
1531		this.icon_image = null;
1532	}
1533};
1534
1535BX.CDialog.prototype.SetIcon = function(icon_class)
1536{
1537	if (this.PARAMS.icon != icon_class)
1538	{
1539		if (this.PARAMS.icon)
1540			BX.removeClass(this.PARTS.HEAD, this.PARAMS.icon);
1541
1542		this.PARAMS.icon = icon_class;
1543
1544		if (this.PARAMS.icon)
1545		{
1546			BX.addClass(this.PARTS.HEAD, this.PARAMS.icon);
1547
1548			var icon_file = (BX.style(this.PARTS.HEAD, 'background-image') || BX.style(this.PARTS.HEAD, 'backgroundImage'));
1549			if (BX.type.isNotEmptyString(icon_file) && icon_file != 'none')
1550			{
1551				var match = icon_file.match(new RegExp('url\\s*\\(\\s*(\'|"|)(.+?)(\\1)\\s*\\)'));
1552				if(match)
1553				{
1554					icon_file = match[2];
1555					if (BX.type.isNotEmptyString(icon_file))
1556					{
1557						this.icon_image = new Image();
1558						this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
1559						this.icon_image.src = icon_file;
1560					}
1561				}
1562			}
1563		}
1564	}
1565	this.adjustSize();
1566};
1567
1568BX.CDialog.prototype.SetIconFile = function(icon_file)
1569{
1570	this.icon_image = new Image();
1571	this.icon_image.onload = BX.delegate(this.__adjustHeadToIcon, this);
1572	this.icon_image.src = icon_file;
1573
1574	BX.adjust(this.PARTS.HEAD, {style: {backgroundImage: 'url(' + icon_file + ')', backgroundPosition: 'right 9px'/*'99% center'*/}});
1575	this.adjustSize();
1576};
1577
1578/*
1579BUTTON: {
1580	title: 'title',
1581	'action': function executed in window object context
1582}
1583BX.CDialog.btnSave || BX.CDialog.btnCancel - standard buttons
1584*/
1585
1586BX.CDialog.prototype.SetButtons = function(a)
1587{
1588	if (BX.type.isString(a))
1589	{
1590		if (a.length > 0)
1591		{
1592			this.PARTS.BUTTONS_CONTAINER.innerHTML += a;
1593
1594			var btns = this.PARTS.BUTTONS_CONTAINER.getElementsByTagName('INPUT');
1595			if (btns.length > 0)
1596			{
1597				this.PARAMS.buttons = [];
1598				for (var i = 0; i < btns.length; i++)
1599				{
1600					this.PARAMS.buttons.push(new BX.CWindowButton({btn: btns[i], parentWindow: this}));
1601				}
1602			}
1603		}
1604	}
1605	else
1606	{
1607		this.PARAMS.buttons = a;
1608		BX.adjust(this.PARTS.BUTTONS_CONTAINER, {
1609			children: this.ShowButtons()
1610		});
1611	}
1612	this.adjustSize();
1613};
1614
1615BX.CDialog.prototype.ClearButtons = function()
1616{
1617	BX.cleanNode(this.PARTS.BUTTONS_CONTAINER);
1618	this.adjustSize();
1619};
1620
1621BX.CDialog.prototype.SetContent = function(html)
1622{
1623	this.__form = null;
1624
1625	if (BX.type.isElementNode(html))
1626	{
1627		if (html.parentNode)
1628			html.parentNode.removeChild(html);
1629	}
1630	else if (BX.type.isString(html))
1631	{
1632		html = BX.create('DIV', {html: html});
1633	}
1634
1635	this.PARAMS.content = html;
1636	BX.cleanNode(this.PARTS.CONTENT_DATA);
1637
1638	BX.adjust(this.PARTS.CONTENT_DATA, {
1639		children: [
1640			this.PARTS.HEAD,
1641			BX.create('DIV', {
1642				props: {
1643					className: 'bx-core-adm-dialog-content-wrap-inner'
1644				},
1645				children: [this.PARAMS.content]
1646			})
1647		]
1648	});
1649
1650	if (this.PARAMS.content_url && this.GetForm())
1651	{
1652		this.__form.submitbtn = this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
1653		this.__form.onsubmit = BX.delegate(this.__submit, this);
1654	}
1655};
1656
1657BX.CDialog.prototype.__submit = function(e)
1658{
1659	for (var i=0,len=this.PARAMS.buttons.length; i<len; i++)
1660	{
1661		if (
1662			this.PARAMS.buttons[i]
1663			&& (
1664				this.PARAMS.buttons[i].name && /save|apply/i.test(this.PARAMS.buttons[i].name)
1665				||
1666				this.PARAMS.buttons[i].btn && this.PARAMS.buttons[i].btn.name && /save|apply/i.test(this.PARAMS.buttons[i].btn.name)
1667			)
1668		)
1669		{
1670			this.PARAMS.buttons[i].emulate();
1671			break;
1672		}
1673	}
1674
1675	return BX.PreventDefault(e);
1676};
1677
1678BX.CDialog.prototype.SwapContent = function(cont)
1679{
1680	cont = BX(cont);
1681
1682	BX.cleanNode(this.PARTS.CONTENT_DATA);
1683	cont.parentNode.removeChild(cont);
1684	this.PARTS.CONTENT_DATA.appendChild(cont);
1685	cont.style.display = 'block';
1686	this.SetContent(cont.innerHTML);
1687};
1688
1689// this method deprecated
1690BX.CDialog.prototype.adjustSize = function()
1691{
1692};
1693
1694// this method deprecated
1695BX.CDialog.prototype.__adjustSize = function()
1696{
1697};
1698
1699BX.CDialog.prototype.adjustSizeEx = function()
1700{
1701	BX.defer(this.__adjustSizeEx, this)();
1702};
1703
1704BX.CDialog.prototype.__adjustSizeEx = function()
1705{
1706	var ob = this.PARTS.CONTENT_DATA.firstChild, new_height = 0;
1707	while (ob)
1708	{
1709		new_height += ob.offsetHeight
1710			+ parseInt(BX.style(ob, 'margin-top'))
1711			+ parseInt(BX.style(ob, 'margin-bottom'));
1712
1713		ob = BX.nextSibling(ob);
1714	}
1715
1716	if (new_height)
1717		this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
1718};
1719
1720
1721BX.CDialog.prototype.__onResizeFinished = function()
1722{
1723	BX.WindowManager.saveWindowSize(
1724		this.PARAMS.resize_id || this.PARAMS.content_url, {height: parseInt(this.PARTS.CONTENT_DATA.style.height), width: parseInt(this.PARTS.CONTENT_DATA.style.width)}
1725	);
1726};
1727
1728BX.CDialog.prototype.Show = function(bNotRegister)
1729{
1730	if ((!this.PARAMS.content) && this.PARAMS.content_url && BX.ajax && !bNotRegister)
1731	{
1732		var wait = BX.showWait();
1733
1734		BX.WindowManager.currently_loaded = this;
1735
1736		this.CreateOverlay(parseInt(BX.style(wait, 'z-index'))-1);
1737		this.OVERLAY.style.display = 'block';
1738		this.OVERLAY.className = 'bx-core-dialog-overlay';
1739
1740		var post_data = '', method = 'GET';
1741		if (this.PARAMS.content_post)
1742		{
1743			post_data = this.PARAMS.content_post;
1744			method = 'POST';
1745		}
1746
1747		var url = this.PARAMS.content_url
1748			+ (this.PARAMS.content_url.indexOf('?')<0?'?':'&')+'bxsender=' + this._sender;
1749
1750		this.auth_callback = BX.delegate(function(){
1751			this.PARAMS.content = '';
1752			this.hideNotify();
1753			this.Show();
1754		}, this);
1755
1756		BX.ajax({
1757			method: method,
1758			dataType: 'html',
1759			url: url,
1760			data: post_data,
1761			skipAuthCheck: true,
1762			onsuccess: BX.delegate(function(data) {
1763				BX.closeWait(null, wait);
1764
1765				this.SetContent(data || '&nbsp;');
1766				this.Show();
1767			}, this)
1768		});
1769	}
1770	else
1771	{
1772		BX.WindowManager.currently_loaded = null;
1773		BX.CDialog.superclass.Show.apply(this, arguments);
1774
1775		this.adjustPos();
1776
1777		this.OVERLAY.className = 'bx-core-dialog-overlay';
1778
1779		this.__adjustSize();
1780
1781		BX.addCustomEvent(this, 'onWindowResize', BX.proxy(this.__adjustSize, this));
1782
1783		if (this.PARAMS.resizable && (this.PARAMS.content_url || this.PARAMS.resize_id))
1784			BX.addCustomEvent(this, 'onWindowResizeFinished', BX.delegate(this.__onResizeFinished, this));
1785	}
1786};
1787
1788BX.CDialog.prototype.GetInnerPos = function()
1789{
1790	return {'width': parseInt(this.PARTS.CONTENT_DATA.style.width), 'height': parseInt(this.PARTS.CONTENT_DATA.style.height)};
1791};
1792
1793BX.CDialog.prototype.adjustPos = function()
1794{
1795	if (!this.bExpanded)
1796	{
1797		var windowSize = BX.GetWindowInnerSize();
1798		var windowScroll = BX.GetWindowScrollPos();
1799
1800		BX.adjust(this.DIV, {
1801			style: {
1802				left: parseInt(windowScroll.scrollLeft + windowSize.innerWidth / 2 - parseInt(this.DIV.offsetWidth) / 2) + 'px',
1803				top: Math.max(parseInt(windowScroll.scrollTop + windowSize.innerHe
1803ight / 2 - parseInt(this.DIV.offsetHeight) / 2), 0) + 'px'
1804			}
1805		});
1806	}
1807};
1808
1809BX.CDialog.prototype.GetContent = function () {return this.PARTS.CONTENT_DATA};
1810
1811BX.CDialog.prototype.btnSave = BX.CDialog.btnSave = {
1812	title: BX.message('JS_CORE_WINDOW_SAVE'),
1813	id: 'savebtn',
1814	name: 'savebtn',
1815	className: BX.browser.IsIE() && BX.browser.IsDoctype() && !BX.browser.IsIE10() ? '' : 'adm-btn-save',
1816	action: function () {
1817		this.disableUntilError();
1818		this.parentWindow.PostParameters();
1819	}
1820};
1821
1822BX.CDialog.prototype.btnCancel = BX.CDialog.btnCancel = {
1823	title: BX.message('JS_CORE_WINDOW_CANCEL'),
1824	id: 'cancel',
1825	name: 'cancel',
1826	action: function () {
1827		this.parentWindow.Close();
1828	}
1829};
1830
1831BX.CDialog.prototype.btnClose = BX.CDialog.btnClose = {
1832	title: BX.message('JS_CORE_WINDOW_CLOSE'),
1833	id: 'close',
1834	name: 'close',
1835	action: function () {
1836		this.parentWindow.Close();
1837	}
1838};
1839
1840/* special child for admin forms loaded into public page */
1841BX.CAdminDialog = function(arParams)
1842{
1843	BX.CAdminDialog.superclass.constructor.apply(this, arguments);
1844
1845	this._sender = 'core_window_cadmindialog';
1846
1847	BX.addClass(this.DIV, 'bx-core-adm-admin-dialog');
1848
1849	this.PARTS.CONTENT.insertBefore(this.PARTS.HEAD, this.PARTS.CONTENT.firstChild);
1850	this.PARTS.HEAD.className = 'bx-core-adm-dialog-tabs';
1851};
1852BX.extend(BX.CAdminDialog, BX.CDialog);
1853
1854BX.CAdminDialog.prototype.SetHead = function()
1855{
1856	BX.CAdminDialog.superclass.SetHead.apply(this, arguments);
1857
1858	if (this.PARTS.HEAD.firstChild && BX.type.isElementNode(this.PARTS.HEAD.firstChild))
1859	{
1860		var ob = this.PARTS.HEAD.firstChild, new_width = 0, marginLeft = 0, marginRight = 0;
1861
1862		while (ob)
1863		{
1864			marginLeft = parseInt(BX.style(ob, 'margin-left'), 10);
1865			if (isNaN(marginLeft))
1866			{
1867				marginLeft = 0;
1868			}
1869			marginRight = parseInt(BX.style(ob, 'margin-right'), 10);
1870			if (isNaN(marginRight))
1871			{
1872				marginRight = 0;
1873			}
1874			new_width += ob.offsetWidth + marginLeft + marginRight;
1875			ob = BX.nextSibling(ob);
1876		}
1877
1878		this.SETTINGS.min_width = Math.max(new_width, this.SETTINGS.min_width) - 2;
1879		if (this.PARAMS.width < this.SETTINGS.min_width)
1880		{
1881			BX.adjust(this.PARTS.CONTENT_DATA, {
1882				style: {
1883					width: this.SETTINGS.min_width + 'px'
1884				}
1885			});
1886		}
1887	}
1888};
1889
1890BX.CAdminDialog.prototype.SetContent = function(html)
1891{
1892	this.__form = null;
1893
1894	if (BX.type.isElementNode(html))
1895	{
1896		if (html.parentNode)
1897			html.parentNode.removeChild(html);
1898	}
1899
1900	this.PARAMS.content = html;
1901	BX.cleanNode(this.PARTS.CONTENT_DATA);
1902
1903	BX.adjust(this.PARTS.CONTENT_DATA, {
1904		children: [
1905			this.PARAMS.content || '&nbsp;'
1906		]
1907	});
1908
1909	if (this.PARAMS.content_url && this.GetForm())
1910	{
1911		this.__form.appendChild(BX.create('INPUT', {props:{type:'submit'},style:{display:'none'}}));
1912		this.__form.onsubmit = BX.delegate(this.__submit, this);
1913	}
1914};
1915
1916BX.CAdminDialog.prototype.__adjustSizeEx = function()
1917{
1918	var ob = this.PARTS.CONTENT_DATA.firstChild,
1919		new_height = 0;
1920	while (ob)
1921	{
1922		new_height += ob.offsetHeight
1923			+ parseInt(BX.style(ob, 'margin-top'))
1924			+ parseInt(BX.style(ob, 'margin-bottom'));
1925		ob = BX.nextSibling(ob);
1926	 if (new_height)
1927	 	this.PARTS.CONTENT_DATA.style.height = new_height + 'px';
1928	}
1929};
1930
1931BX.CAdminDialog.prototype.__expandGetSize = function()
1932{
1933	var res = BX.CAdminDialog.superclass.__expandGetSize.apply(this, arguments);
1934
1935	res.width -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-right')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-left'));
1936	res.height -= parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-top')) + parseInt(BX.style(this.PARTS.CONTENT_DATA, 'padding-bottom'));
1937
1938	res.height -= this.PARTS.HEAD.offsetHeight;
1939
1940	return res;
1941};
1942
1943BX.CAdminDialog.prototype.Submit = function()
1944{
1945	var FORM = this.GetForm();
1946	if (FORM && !FORM['bxpublic'] && !/bxpublic=/.test(FORM.action))
1947	{
1948		FORM.appendChild(BX.create('INPUT', {
1949			props: {
1950				type: 'hidden',
1951				name: 'bxpublic',
1952				value: 'Y'
1953			}
1954		}));
1955	}
1956
1957	return BX.CAdminDialog.superclass.Submit.apply(this, arguments);
1958};
1959
1960BX.CAdminDialog.prototype.btnSave = BX.CAdminDialog.btnSave = {
1961	title: BX.message('JS_CORE_WINDOW_SAVE'),
1962	id: 'savebtn',
1963	name: 'savebtn',
1964	className: 'adm-btn-save',
1965	action: function () {
1966		this.disableUntilError();
1967		this.parentWindow.Submit();
1968	}
1969};
1970
1971BX.CAdminDialog.btnCancel = BX.CAdminDialog.superclass.btnCancel;
1972BX.CAdminDialog.btnClose = BX.CAdminDialog.superclass.btnClose;
1973
1974BX.CDebugDialog = function(arParams)
1975{
1976	BX.CDebugDialog.superclass.constructor.apply(this, arguments);
1977};
1978BX.extend(BX.CDebugDialog, BX.CDialog);
1979
1980BX.CDebugDialog.prototype.ShowDetails = function(div_id)
1981{
1982	var div = BX(div_id);
1983	if (div)
1984	{
1985		if (this.div_detail_current)
1986			this.div_detail_current.style.display = 'none';
1987
1988		div.style.display = 'block';
1989		this.div_detail_current = div;
1990	}
1991};
1992
1993BX.CDebugDialog.prototype.SetContent = function(html)
1994{
1995	if (!html)
1996		return;
1997
1998	var arHtml = html.split('#DIVIDER#');
1999	if (arHtml.length > 1)
2000	{
2001		this.PARAMS.content = arHtml[1];
2002
2003		this.PARTS.CONTENT_DATA.style.overflow = 'hidden';
2004
2005		BX.CDebugDialog.superclass.SetContent.apply(this, [arHtml[1]]);
2006
2007		this.PARTS.CONTENT_INNER = this.PARTS.CONTENT_DATA.firstChild.nextSibling;
2008		this.PARTS.CONTENT_TOP = this.PARTS.CONTENT_DATA.insertBefore(BX.create('DIV', {
2009			props: {
2010				className: 'bx-debug-content-top'
2011			},
2012			html: arHtml[0]
2013		}), this.PARTS.CONTENT_INNER);
2014		this.PARTS.CONTENT_INNER.style.overflow = 'auto';
2015	}
2016	else
2017	{
2018		BX.CDebugDialog.superclass.SetContent.apply(this, arguments);
2019	}
2020};
2021
2022BX.CDebugDialog.prototype.__adjustSize = function()
2023{
2024	BX.CDebugDialog.superclass.__adjustSize.apply(this, arguments);
2025
2026	if (this.PARTS.CONTENT_TOP)
2027	{
2028		var new_height = this.PARTS.CONTENT_DATA.offsetHeight - this.PARTS.HEAD.offsetHeight - this.PARTS.CONTENT_TOP.offsetHeight - 38;
2029
2030		if (new_height > 0)
2031		{
2032			this.PARTS.CONTENT_INNER.style.height = new_height + 'px';
2033		}
2034	}
2035};
2036
2037
2038/* class for dialog window with editors */
2039
2040BX.CEditorDialog = function(arParams)
2041{
2042	BX.CEditorDialog.superclass.constructor.apply(this, arguments);
2043
2044	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
2045	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
2046
2047	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2048	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
2049
2050	BX.addClass(this.PARTS.CONTENT, 'bx-core-editor-dialog-content-wrap');
2051	BX.addClass(this.PARTS.CONTENT_DATA, 'bx-core-editor-dialog-content');
2052	BX.addClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-editor-dialog-buttons');
2053};
2054BX.extend(BX.CEditorDialog, BX.CDialog);
2055
2056BX.CEditorDialog.prototype.SetContent  = function()
2057{
2058	BX.CEditorDialog.superclass.SetContent.apply(this, arguments);
2059
2060	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2061};
2062
2063/* class for wizards in admin section */
2064BX.CWizardDialog = function(arParams)
2065{
2066	BX.CWizardDialog.superclass.constructor.apply(this, arguments);
2067
2068	BX.removeClass(this.PARTS.CONTENT, 'bx-core-adm-dialog-content-wrap');
2069	BX.removeClass(this.PARTS.CONTENT_DATA, 'bx-core-adm-dialog-content');
2070	BX.removeClass(this.PARTS.CONTENT_DATA.lastChild, 'bx-core-adm-dialog-content-wrap-inner');
2071	BX.removeClass(this.PARTS.BUTTONS_CONTAINER, 'bx-core-adm-dialog-buttons');
2072
2073	BX.addClass(this.PARTS.CONTENT, 'bx-core-wizard-dialog-content-wrap');
2074};
2075
2076BX.extend(BX.CWizardDialog, BX.CDialog);
2077
2078/* class for auth dialog */
2079BX.CAuthDialog = function(arParams)
2080{
2081	arParams.resizable = false;
2082	arParams.width = 350;
2083	arParams.height = 200;
2084
2085	arParams.buttons = [this.btnSave];
2086
2087	BX.CAuthDialog.superclass.constructor.apply(this, arguments);
2088	this._sender = 'core_window_cauthdialog';
2089
2090	BX.addClass(this.DIV, 'bx-core-auth-dialog');
2091
2092	BX.AUTHAGENT = this;
2093};
2094BX.extend(BX.CAuthDialog, BX.CDialog);
2095
2096BX.CAuthDialog.prototype.btnSave = BX.CAuthDialog.btnSave = {
2097	title: BX.message('JS_CORE_WINDOW_AUTH'),
2098	id: 'savebtn',
2099	name: 'savebtn',
2100	className: 'adm-btn-save',
2101	action: function () {
2102		this.disableUntilError();
2103		this.parentWindow.Submit('', this.parentWindow.PARAMS.content_url);
2104	}
2105};
2106
2107BX.CAuthDialog.prototype.SetError = function(error)
2108{
2109	BX.closeWait();
2110
2111	if (!!error)
2112		this.ShowError(error.MESSAGE || error);
2113};
2114
2115BX.CAuthDialog.prototype.setAuthResult = function(result)
2116{
2117	BX.closeWait();
2118
2119	if (result === false)
2120	{
2121		this.Close();
2122		if (this.PARAMS.callback)
2123			this.PARAMS.callback();
2124	}
2125	else
2126	{
2127		this.SetError(result);
2128	}
2129};
2130
2131/* MENU CLASSES */
2132
2133BX.CWindowFloat = function(node)
2134{
2135	BX.CWindowFloat.superclass.constructor.apply(this, [node, 'float']);
2136
2137	this.SETTINGS.resizable = false;
2138};
2139BX.extend(BX.CWindowFloat, BX.CWindow);
2140
2141BX.CWindowFloat.prototype.adjustPos = function()
2142{
2143	if (this.PARAMS.parent)
2144		this.adjustToNode();
2145	else if (this.PARAMS.x && this.PARAMS.y)
2146		this.adjustToPos([this.PARAMS.x, this.PARAMS.y]);
2147};
2148
2149BX.CWindowFloat.prototype.adjustToPos = function(pos)
2150{
2151	this.DIV.style.left = parseInt(pos[0]) + 'px';
2152	this.DIV.style.top = parseInt(pos[1]) + 'px';
2153};
2154
2155BX.CWindowFloat.prototype.adjustToNodeGetPos = function()
2156{
2157	return BX.pos(this.PARAMS.parent);
2158};
2159
2160BX.CWindowFloat.prototype.adjustToNode = function(el)
2161{
2162	el = el || this.PARAMS.parent;
2163
2164	this.PARAMS.parent = BX(el);
2165
2166	if (this.PARAMS.parent)
2167	{
2168		var pos = this.adjustToNodeGetPos();
2169
2170		this.DIV.style.top = pos.top + 'px';//(pos.top - 26) + 'px';
2171		this.DIV.style.left = pos.left + 'px';
2172
2173		this.PARAMS.parent.OPENER = this;
2174	}
2175};
2176
2177BX.CWindowFloat.prototype.Show = function()
2178{
2179	this.adjustToPos([-1000, -1000]);
2180	BX.CWindowFloat.superclass.Show.apply(this, arguments);
2181	this.adjustPos();
2182};
2183
2184/* menu opener class */
2185/*
2186{
2187	DOMNode DIV,
2188	BX.CMenu or Array MENU,
2189	TYPE = 'hover' | 'click',
2190	TIMEOUT: 1000
2191	ATTACH_MODE: 'top' | 'right'
2192	ACTIVE_CLASS: className for opener element when menu is opened
2193}
2194*/
2195BX.COpener = function(arParams)
2196{
2197	this.PARAMS = arParams || {};
2198
2199	this.MENU = arParams.MENU || [];
2200
2201	this.DIV = arParams.DIV;
2202	this.ATTACH = arParams.ATTACH || arParams.DIV;
2203	this.ATTACH_MODE = arParams.ATTACH_MODE || 'bottom';
2204
2205	this.ACTIVE_CLASS = arParams.ACTIVE_CLASS || '';
2206	this.LEVEL = arParams.LEVEL || 0;
2207
2208	this.CLOSE_ON_CLICK = typeof arParams.CLOSE_ON_CLICK != 'undefined' ? !!arParams.CLOSE_ON_CLICK : true;
2209	this.ADJUST_ON_CLICK = typeof arParams.ADJUST_ON_CLICK != 'undefined' ? !!arParams.ADJUST_ON_CLICK : true;
2210
2211	this.TYPE = this.PARAMS.TYPE == 'hover' ? 'hover' : 'click';
2212
2213	this._openTimeout = null;
2214
2215	if (this.PARAMS.TYPE == 'hover' && arParams.TIMEOUT !== 0)
2216		this.TIMEOUT = arParams.TIMEOUT || 1000;
2217	else
2218		this.TIMEOUT = 0;
2219
2220	if (!!this.PARAMS.MENU_URL)
2221	{
2222		this.bMenuLoaded = false;
2223		this.bMenuLoading = false;
2224
2225		this.MENU = [{
2226			TEXT: BX.message('JS_CORE_LOADING'),
2227			CLOSE_ON_CLICK: false
2228		}];
2229
2230		if (this.PARAMS.MENU_PRELOAD)
2231		{
2232			BX.defer(this.Load, this)();
2233		}
2234	}
2235
2236	BX.ready(BX.defer(this.Init, this));
2237};
2238
2239BX.COpener.prototype.Init = function()
2240{
2241	this.DIV = BX(this.DIV);
2242
2243	switch (this.TYPE)
2244	{
2245		case 'hover':
2246			BX.bind(this.DIV, 'mouseover', BX.proxy(this.Open, this));
2247			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
2248		break;
2249
2250		case 'click':
2251			BX.bind(this.DIV, 'click', BX.proxy(this.Toggle, this));
2252		break;
2253	}
2254
2255	//BX.bind(window, 'scroll', BX.delegate(this.__close_immediately, this));
2256
2257	this.bMenuInit = false;
2258};
2259
2260BX.COpener.prototype.Load = function()
2261{
2262	if (this.PARAMS.MENU_URL && !this.bMenuLoaded)
2263	{
2264		if (!this.bMenuLoading)
2265		{
2266			var url = this.PARAMS.MENU_URL;
2267			if (url.indexOf('sessid=') <= 0)
2268				url += (url.indexOf('?') > 0 ? '&' : '?') + 'sessid=' + BX.bitrix_sessid();
2269
2270			this.bMenuLoading = true;
2271			BX.ajax.loadJSON(url, BX.proxy(this.SetMenu, this), BX.proxy(this.LoadFailed, this));
2272		}
2273	}
2274};
2275
2276BX.COpener.prototype.SetMenu = function(menu)
2277{
2278	this.bMenuLoaded = true;
2279	this.bMenuLoading = false;
2280	if (this.bMenuInit)
2281	{
2282		this.MENU.setItems(menu);
2283	}
2284	else
2285	{
2286		this.MENU = menu;
2287	}
2288};
2289
2290BX.COpener.prototype.LoadFailed = function(type, error)
2291{
2292	this.bMenuLoading = false;
2293	this.SetMenu([{
2294		TEXT: BX.message('JS_CORE_NO_DATA'),
2295		CLOSE_ON_CLICK: true
2296	}]);
2297	BX.debug(arguments);
2298};
2299
2300BX.COpener.prototype.checkAdminMenu = function()
2301{
2302	if (document.documentElement.id == 'bx-admin-prefix')
2303		return true;
2304
2305	return !!BX.findParent(this.DIV, {property: {id: 'bx-admin-prefix'}});
2306};
2307
2308BX.COpener.prototype.Toggle = function(e)
2309{
2310	this.__clear_timeout();
2311
2312	if (!this.bMenuInit || !this.MENU.visible())
2313	{
2314		var t = this.TIMEOUT;
2315		this.TIMEOUT = 0;
2316		this.Open(e);
2317		this.TIMEOUT = t;
2318	}
2319	else
2320	{
2321		this.MENU.Close();
2322	}
2323
2324	return !!(e||window.event) && BX.PreventDefault(e);
2325};
2326
2327BX.COpener.prototype.GetMenu = function()
2328{
2329	if (!this.bMenuInit)
2330	{
2331		if (BX.type.isArray(this.MENU))
2332		{
2333			this.MENU = new BX.CMenu({
2334				ITEMS: this.MENU,
2335				ATTACH_MODE: this.ATTACH_MODE,
2336				SET_ID: this.checkAdminMenu() ? 'bx-admin-prefix' : '',
2337				CLOSE_ON_CLICK: !!this.CLOSE_ON_CLICK,
2338				ADJUST_ON_CLICK: !!this.ADJUST_ON_CLICK,
2339				LEVEL: this.LEVEL,
2340				parent: BX(this.DIV),
2341				parent_attach: BX(this.ATTACH)
2342			});
2343
2344			if (this.LEVEL > 0)
2345			{
2346				BX.bind(this.MENU.DIV, 'mouseover', BX.proxy(this._on_menu_hover, this));
2347				BX.bind(this.MENU.DIV, 'mouseout', BX.proxy(this._on_menu_hout, this));
2348			}
2349		}
2350
2351		BX.addCustomEvent(this.MENU, 'onMenuOpen', BX.proxy(this.handler_onopen, this));
2352		BX.addCustomEvent(this.MENU, 'onMenuClose', BX.proxy(this.handler_onclose, this));
2353
2354		BX.addCustomEvent('onMenuItemHover', BX.proxy(this.handler_onover, this));
2355
2356		this.bMenuInit = true;
2357	}
2358
2359	return this.MENU;
2360};
2361
2362BX.COpener.prototype.Open = function()
2363{
2364	this.GetMenu();
2365
2366	this.bOpen = true;
2367
2368	this.__clear_timeout();
2369
2370	if (this.TIMEOUT > 0)
2371	{
2372		BX.bind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
2373		this._openTimeout = setTimeout(BX.proxy(this.__open, this), this.TIMEOUT);
2374	}
2375	else
2376	{
2377		this.__open();
2378	}
2379
2380	if (!!this.PARAMS.MENU_URL && !this.bMenuLoaded)
2381	{
2382		this._loadTimeout = setTimeout(BX.proxy(this.Load, this), parseInt(this.TIMEOUT/2));
2383	}
2384
2385	return true;
2386};
2387
2388BX.COpener.prototype.__clear_timeout = function()
2389{
2390	if (!!this._openTimeout)
2391		clearTimeout(this._openTimeout);
2392	if (!!this._loadTimeout)
2393		clearTimeout(this._loadTimeout);
2394
2395	BX.unbind(this.DIV, 'mouseout', BX.proxy(this.__clear_timeout, this));
2396};
2397
2398BX.COpener.prototype._on_menu_hover = function()
2399{
2400	this.bMenuHover = true;
2401
2402	this.__clear_timeout();
2403
2404	if (this.ACTIVE_CLASS)
2405		BX.addClass(this.DIV, this.ACTIVE_CLASS);
2406
2407};
2408
2409BX.COpener.prototype._on_menu_hout = function()
2410{
2411	this.bMenuHover = false;
2412};
2413
2414BX.COpener.prototype.handler_onover = function(level, opener)
2415{
2416	if (this.bMenuHover)
2417		return;
2418
2419	if (opener != this && level == this.LEVEL-1 && this.ACTIVE_CLASS)
2420	{
2421		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
2422	}
2423
2424	if (this.bMenuInit && level <= this.LEVEL-1 && this.MENU.visible())
2425	{
2426		if (opener != this)
2427		{
2428			this.__clear_timeout();
2429			this._openTimeout = setTimeout(BX.proxy(this.Close, this), this.TIMEOUT);
2430		}
2431	}
2432};
2433
2434BX.COpener.prototype.handler_onopen = function()
2435{
2436	this.bOpen = true;
2437
2438	if (this.ACTIVE_CLASS)
2439		BX.addClass(this.DIV, this.ACTIVE_CLASS);
2440
2441	BX.defer(function() {
2442		BX.onCustomEvent(this, 'onOpenerMenuOpen');
2443	}, this)();
2444};
2445
2446BX.COpener.prototype.handler_onclose = function()
2447{
2448	this.bOpen = false;
2449	BX.onCustomEvent(this, 'onOpenerMenuClose');
2450
2451	if (this.ACTIVE_CLASS)
2452		BX.removeClass(this.DIV, this.ACTIVE_CLASS);
2453};
2454
2455BX.COpener.prototype.Close = function()
2456{
2457	if (!this.bMenuInit)
2458		return;
2459
2460	if (!!this._openTimeout)
2461		clearTimeout(this._openTimeout);
2462
2463	this.bOpen = false;
2464
2465	this.__close();
2466};
2467
2468BX.COpener.prototype.__open = function()
2469{
2470	this.__clear_timeout();
2471
2472	if (this.bMenuInit && this.bOpen && !this.MENU.visible())
2473		this.MENU.Show();
2474};
2475
2476BX.COpener.prototype.__close = function()
2477{
2478	if (this.bMenuInit && !this.bOpen && this.MENU.visible())
2479		this.MENU.Hide();
2480};
2481
2482BX.COpener.prototype.__close_immediately = function() {
2483	this.bOpen = false; this.__close();
2484};
2485
2486BX.COpener.prototype.isMenuVisible = function() {
2487	return null != this.MENU.visible && this.MENU.visible()
2488};
2489
2490/* common menu class */
2491
2492BX.CMenu = function(arParams)
2493{
2494	BX.CMenu.superclass.constructor.apply(this);
2495
2496	this.DIV.style.width = 'auto';//this.DIV.firstChild.offsetWidth + 'px';
2497	this.DIV.style.height = 'auto';//this.DIV.firstChild.offsetHeight + 'px';
2498
2499	this.PARAMS = arParams || {};
2500	this.PARTS = {};
2501
2502	this.PARAMS.ATTACH_MODE = this.PARAMS.ATTACH_MODE || 'bottom';
2503	this.PARAMS.CLOSE_ON_CLICK = typeof this.PARAMS.CLOSE_ON_CLICK == 'undefined' ? true : this.PARAMS.CLOSE_ON_CLICK;
2504	this.PARAMS.ADJUST_ON_CLICK = typeof this.PARAMS.ADJUST_ON_CLICK == 'undefined' ? true : this.PARAMS.ADJUST_ON_CLICK;
2505	this.PARAMS.LEVEL = this.PARAMS.LEVEL || 0;
2506
2507	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 : '');
2508	if (!!this.PARAMS.SET_ID)
2509		this.DIV.id = this.PARAMS.SET_ID;
2510
2511	if (this.PARAMS.LEVEL == 0)
2512	{
2513		this.ARROW = this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-core-popup-menu-angle'}, style: {left:'15px'}}));
2514	}
2515
2516	if (!!this.PARAMS.CLASS_NAME)
2517		this.DIV.className += ' ' + this.PARAMS.CLASS_NAME;
2518
2519	BX.bind(this.DIV, 'click', BX.eventCancelBubble);
2520
2521	this.ITEMS = [];
2522
2523	this.setItems(this.PARAMS.ITEMS);
2524
2525	BX.addCustomEvent('onMenuOpen', BX.proxy(this._onMenuOpen, this));
2526	BX.addCustomEvent('onMenuItemSelected', BX.proxy(this.Hide, this));
2527};
2528BX.extend(BX.CMenu, BX.CWindowFloat);
2529
2530BX.CMenu.broadcastCloseEvent = function()
2531{
2532	BX.onCustomEvent("onMenuItemSelected");
2533};
2534
2535BX.CMenu._toggleChecked = function()
2536{
2537	BX.toggleClass(this, 'bx-core-popup-menu-item-checked');
2538};
2539
2540BX.CMenu._itemDblClick = function()
2541{
2542	window.location.href = this.href;
2543};
2544
2545BX.CMenu.prototype.toggleArrow = function(v)
2546{
2547	if (!!this.ARROW)
2548	{
2549		if (typeof v == 'undefined')
2550		{
2551			v = this.ARROW.style.visibility == 'hidden';
2552		}
2553
2554		this.ARROW.style.visibility = !!v ? 'visible' : 'hidden';
2555	}
2556};
2557
2558BX.CMenu.prototype.visible = function()
2559{
2560	return this.DIV.style.display !== 'none';
2561};
2562
2563BX.CMenu.prototype._onMenuOpen = function(menu, menu_level)
2564{
2565	if (this.visible())
2566	{
2567		if (menu_level == this.PARAMS.LEVEL && menu != this)
2568		{
2569			this.Hide();
2570		}
2571	}
2572};
2573
2574BX.CMenu.prototype.onUnRegister = function()
2575{
2576	if (!this.visible())
2577		return;
2578
2579	this.Hide();
2580};
2581
2582BX.CMenu.prototype.setItems = function(items)
2583{
2584	this.PARAMS.ITEMS = items;
2585
2586	BX.cleanNode(this.DIV);
2587
2588	if (!!this.ARROW)
2589		this.DIV.appendChild(this.ARROW);
2590
2591	if (this.PARAMS.ITEMS)
2592	{
2593		this.PARAMS.ITEMS = BX.util.array_values(this.PARAMS.ITEMS);
2594
2595		var bIcons = false;
2596		var cnt = 0;
2597		for (var i = 0, len = this.PARAMS.ITEMS.length; i < len; i++)
2598		{
2599			if ((i == 0 || i == len-1) && this.PARAMS.ITEMS[i].SEPARATOR)
2600				continue;
2601
2602			cnt++;
2603
2604			if (!bIcons)
2605				bIcons = !!this.PARAMS.ITEMS[i].GLOBAL_ICON;
2606
2607			this.addItem(this.PARAMS.ITEMS[i], i);
2608		}
2609
2610		// Occam turning in his grave
2611		if (cnt === 1)
2612			BX.addClass(this.DIV, 'bx-core-popup-menu-single-item');
2613		else
2614			BX.removeClass(this.DIV, 'bx-core-popup-menu-single-item');
2615
2616		if (!bIcons)
2617			BX.addClass(this.DIV, 'bx-core-popup-menu-no-icons');
2618		else
2619			BX.removeClass(this.DIV, 'bx-core-popup-menu-no-icons');
2620
2621	}
2622};
2623
2624BX.CMenu.prototype.addItem = function(item)
2625{
2626	this.ITEMS.push(item);
2627
2628	if (item.SEPARATOR)
2629	{
2630		item.NODE = BX.create(
2631			'DIV', {props: {className: 'bx-core-popup-menu-separator'}}
2632		);
2633	}
2634	else
2635	{
2636		var bHasMenu = (!!item.MENU
2637			&& (
2638				(BX.type.isArray(item.MENU) && item.MENU.length > 0)
2639				|| item.MENU instanceof BX.CMenu
2640			) || !!item.MENU_URL
2641		);
2642
2643		if (item.DISABLED)
2644		{
2645			item.CLOSE_ON_CLICK = false;
2646			item.LINK = null;
2647			item.ONCLICK = null;
2648			item.ACTION = null;
2649		}
2650
2651		item.NODE = BX.create(!!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype() ? 'A' : 'SPAN', {
2652			props: {
2653				className: 'bx-core-popup-menu-item'
2654					+ (bHasMenu ? ' bx-core-popup-menu-item-opener' : '')
2655					+ (!!item.DEFAULT ? ' bx-core-popup-menu-item-default' : '')
2656					+ (!!item.DISABLED ? ' bx-core-popup-menu-item-disabled' : '')
2657					+ (!!item.CHECKED ? ' bx-core-popup-menu-item-checked' : ''),
2658					title: !!BX.message['MENU_ENABLE_TOOLTIP'] || !!item.SHOW_TITLE ? item.TITLE || '' : '',
2659				BXMENULEVEL: this.PARAMS.LEVEL
2660			},
2661			attrs: !!item.LINK || BX.browser.IsIE() && !BX.browser.IsDoctype() ? {href: item.LINK || 'javascript:void(0)'} : {},
2662			events: {
2663				mouseover: function()
2664				{
2665					BX.onCustomEvent('onMenuItemHover', [this.BXMENULEVEL, this.OPENER])
2666				}
2667			},
2668			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>'
2669		});
2670
2671		if (bHasMenu && !item.DISABLED)
2672		{
2673			item.NODE.OPENER = new BX.COpener({
2674				DIV: item.NODE,
2675				ACTIVE_CLASS: 'bx-core-popup-menu-item-opened',
2676				TYPE: 'hover',
2677				MENU: item.MENU,
2678				MENU_URL: item.MENU_URL,
2679				MENU_PRELOAD: !!item.MENU_PRELOAD,
2680				LEVEL: this.PARAMS.LEVEL + 1,
2681				ATTACH_MODE:'right',
2682				TIMEOUT: 500
2683			});
2684		}
2685		else if (this.PARAMS.CLOSE_ON_CLICK && (typeof item.CLOSE_ON_CLICK == 'undefined' || !!item.CLOSE_ON_CLICK))
2686		{
2687			BX.bind(item.NODE, 'click', BX.CMenu.broadcastCloseEvent);
2688		}
2689		else if (this.PARAMS.ADJUST_ON_CLICK && (typeof item.ADJUST_ON_CLICK == 'undefined' || !!item.ADJUST_ON_CLICK))
2690		{
2691			BX.bind(item.NODE, 'click', BX.defer(this.adjustPos, this));
2692		}
2693
2694		if (bHasMenu && !!item.LINK)
2695		{
2696			BX.bind(item.NODE, 'dblclick', BX.CMenu._itemDblClick);
2697		}
2698
2699		if (typeof item.CHECKED != 'undefined')
2700		{
2701			BX.bind(item.NODE, 'click', BX.CMenu._toggleChecked);
2702		}
2703
2704		item.ONCLICK = item.ACTION || item.ONCLICK;
2705		if (!!item.ONCLICK)
2706		{
2707			if (BX.type.isString(item.ONCLICK))
2708			{
2709				item.ONCLICK = new Function("event", item.ONCLICK);
2710			}
2711
2712			BX.bind(item.NODE, 'click', item.ONCLICK);
2713		}
2714	}
2715
2716	this.DIV.appendChild(item.NODE);
2717};
2718
2719BX.CMenu.prototype._documentClickBind = function()
2720{
2721	this._documentClickUnBind();
2722	BX.bind(document, 'click', BX.proxy(this._documentClick, this));
2723};
2724
2725BX.CMenu.prototype._documentClickUnBind = function()
2726{
2727	BX.unbind(document, 'click', BX.proxy(this._documentClick, this));
2728};
2729
2730BX.CMenu.prototype._documentClick = function(e)
2731{
2732	e = e||window.event;
2733	if(!!e && !(BX.getEventButton(e) & BX.MSLEFT))
2734		return;
2735
2736	this.Close();
2737};
2738
2739BX.CMenu.prototype.Show = function()
2740{
2741	BX.onCustomEvent(this, 'onMenuOpen', [this, this.PARAMS.LEVEL]);
2742	BX.CMenu.superclass.Show.apply(this, []);
2743
2744	this.bCloseEventFired = false;
2745
2746	BX.addCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
2747
2748	(BX.defer(this._documentClickBind, this))();
2749};
2750
2751BX.CMenu.prototype.Close = // we shouldn't 'Close' window - only hide
2752BX.CMenu.prototype.Hide = function()
2753{
2754	if (!this.visible())
2755		return;
2756
2757	BX.removeCustomEvent(this.PARAMS.parent_attach, 'onChangeNodePosition', BX.proxy(this.adjustToNode, this));
2758
2759	this._documentClickUnBind();
2760
2761	if (!this.bCloseEventFired)
2762	{
2763		BX.onCustomEvent(this, 'onMenuClose', [this, this.PARAMS.LEVEL]);
2764		this.bCloseEventFired = true;
2765	}
2766	BX.CMenu.superclass.Hide.apply(this, arguments);
2767
2768
2769//	this.DIV.onclick = null;
2770	//this.PARAMS.parent.onclick = null;
2771};
2772
2773BX.CMenu.prototype.__adjustMenuToNode = function()
2774{
2775	var pos = BX.pos(this.PARAMS.parent_attach),
2776		bFixed = !!BX.findParent(this.PARAMS.parent_attach, BX.is_fixed);
2777
2778	if (bFixed)
2779		this.DIV.style.position = 'fixed';
2780	else
2781		this.DIV.style.position = 'absolute';
2782
2783	if (!pos.top)
2784	{
2785		this.DIV.style.top = '-1000px';
2786		this.DIV.style.left = '-1000px';
2787	}
2788
2789	if (this.bTimeoutSet) return;
2790
2791	var floatWidth = this.DIV.offsetWidth, floatHeight = this.DIV.offsetHeight;
2792	if (!floatWidth)
2793	{
2794		setTimeout(BX.delegate(function(){
2795			this.bTimeoutSet = false; this.__adjustMenuToNode();
2796		}, this), 100);
2797
2798		this.bTimeoutSet = true;
2799		return;
2800	}
2801
2802	var menu_pos = {},
2803		wndSize = BX.GetWindowSize();
2804
2805/*
2806	if (BX.browser.IsIE() && !BX.browser.IsDoctype())
2807	{
2808		pos.top -= 4; pos.bottom -= 4;
2809		pos.left -= 2; pos.right -= 2;
2810	}
2811*/
2812
2813	switch (this.PARAMS.ATTACH_MODE)
2814	{
2815		case 'bottom':
2816			menu_pos.top = pos.bottom + 9;
2817			menu_pos.left = pos.left;
2818
2819			var arrowPos = 0;
2820			if (!!this.ARROW)
2821			{
2822				if (pos.width > floatWidth)
2823					arrowPos = parseInt(floatWidth/2 - 7);
2824				else
2825					arrowPos = parseInt(Math.min(floatWidth, pos.width)/2 - 7);
2826
2827				if (arrowPos < 7)
2828				{
2829					menu_pos.left -= 15;
2830					arrowPos += 15;
2831				}
2832			}
2833
2834			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
2835			{
2836				var orig_menu_pos = menu_pos.left;
2837				menu_pos.left = wndSize.scrollWidth - floatWidth - 10;
2838
2839				if (!!this.ARROW)
2840					arrowPos += orig_menu_pos - menu_pos.left;
2841			}
2842
2843			if (bFixed)
2844			{
2845				menu_pos.left -= wndSize.scrollLeft;
2846			}
2847
2848			if (!!this.ARROW)
2849				this.ARROW.style.left = arrowPos + 'px';
2850		break;
2851		case 'right':
2852			menu_pos.top = pos.top-1;
2853			menu_pos.left = pos.right;
2854
2855			if (menu_pos.left > wndSize.scrollWidth - floatWidth - 10)
2856			{
2857				menu_pos.left = pos.left - floatWidth - 1;
2858			}
2859		break;
2860	}
2861
2862	if (bFixed)
2863	{
2864		menu_pos.top -= wndSize.scrollTop;
2865	}
2866
2867	if (!!this.ARROW)
2868		this.ARROW.className = 'bx-core-popup-menu-angle';
2869
2870	if((menu_pos.top + floatHeight >
2870 wndSize.scrollTop + wndSize.innerHeight)
2871		|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
2872	{
2873		var new_top = this.PARAMS.ATTACH_MODE == 'bottom'
2874			? pos.top - floatHeight - 9
2875			: pos.bottom - floatHeight + 1;
2876
2877		if((new_top > wndSize.scrollTop)
2878			|| (menu_pos.top + floatHeight > wndSize.scrollHeight))
2879		{
2880			if ((menu_pos.top + floatHeight > wndSize.scrollHeight))
2881			{
2882				menu_pos.top = Math.max(0, wndSize.scrollHeight-floatHeight);
2883				this.toggleArrow(false);
2884			}
2885			else
2886			{
2887				menu_pos.top = new_top;
2888
2889				if (!!this.ARROW)
2890					this.ARROW.className = 'bx-core-popup-menu-angle-bottom';
2891			}
2892		}
2893	}
2894
2895	if (menu_pos.top + menu_pos.left == 0)
2896	{
2897		this.Hide();
2898	}
2899	else
2900	{
2901		this.DIV.style.top = menu_pos.top + 'px';
2902		this.DIV.style.left = menu_pos.left + 'px';
2903	}
2904};
2905
2906BX.CMenu.prototype.adjustToNode = function(el)
2907{
2908	this.PARAMS.parent_attach = BX(el) || this.PARAMS.parent_attach || this.PARAMS.parent;
2909	this.__adjustMenuToNode();
2910};
2911
2912
2913/* components toolbar class */
2914
2915BX.CMenuOpener = function(arParams)
2916{
2917	BX.CMenuOpener.superclass.constructor.apply(this);
2918
2919	this.PARAMS = arParams || {};
2920	this.setParent(this.PARAMS.parent);
2921	this.PARTS = {};
2922
2923	this.SETTINGS.drag_restrict = true;
2924
2925	this.defaultAction = null;
2926
2927	this.timeout = 500;
2928
2929	this.DIV.className = 'bx-component-opener';
2930	this.DIV.ondblclick = BX.PreventDefault;
2931
2932	if (this.PARAMS.component_id)
2933	{
2934		this.PARAMS.transform = !!this.PARAMS.transform;
2935	}
2936
2937	this.OPENERS = [];
2938
2939	this.DIV.appendChild(BX.create('SPAN', {
2940		props: {className: 'bx-context-toolbar' + (this.PARAMS.transform ? ' bx-context-toolbar-vertical-mode' : '')}
2941	}));
2942
2943	//set internal structure and register draggable element
2944	this.PARTS.INNER = this.DIV.firstChild.appendChild(BX.create('SPAN', {
2945		props: {className: 'bx-context-toolbar-inner'},
2946		html: '<span class="bx-context-toolbar-drag-icon"></span><span class="bx-context-toolbar-vertical-line"></span><br>'
2947	}));
2948
2949	this.EXTRA_BUTTONS = {};
2950
2951	var btnCount = 0;
2952	for (var i = 0, len = this.PARAMS.menu.length; i < len; i++)
2953	{
2954		var item = this.addItem(this.PARAMS.menu[i]);
2955		if (null != item)
2956		{
2957			btnCount++;
2958			this.PARTS.INNER.appendChild(item);
2959			this.PARTS.INNER.appendChild(BX.create('BR'));
2960		}
2961	}
2962	var bHasButtons = btnCount > 0;
2963
2964	//menu items will be attached here
2965
2966	this.PARTS.ICONS = this.PARTS.INNER.appendChild(BX.create('SPAN', {
2967		props: {className: 'bx-context-toolbar-icons'}
2968	}));
2969
2970	if (this.PARAMS.component_id)
2971	{
2972		this.PARAMS.pin = !!this.PARAMS.pin;
2973
2974		if (bHasButtons)
2975			this.PARTS.ICONS.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-separator'}}));
2976
2977		this.PARTS.ICON_PIN = this.PARTS.ICONS.appendChild(BX.create('A', {
2978			attrs: {
2979				href: 'javascript:void(0)'
2980			},
2981			props: {
2982				className: this.PARAMS.pin
2983							? 'bx-context-toolbar-pin-fixed'
2984							: 'bx-context-toolbar-pin'
2985			},
2986			events: {
2987				click: BX.delegate(this.__pin_btn_clicked, this)
2988			}
2989		}));
2990	}
2991
2992
2993	if (this.EXTRA_BUTTONS['components2_props'])
2994	{
2995		var btn = this.EXTRA_BUTTONS['components2_props'] || {URL: 'javascript:void(0)'};
2996		if (null == this.defaultAction)
2997		{
2998			this.defaultAction = btn.ONCLICK;
2999			this.defaultActionTitle = btn.TITLE || btn.TEXT;
3000		}
3001
3002		btn.URL = 'javascript:' + BX.util.urlencode(btn.ONCLICK);
3003
3004		this.ATTACH = this.PARTS.ICONS.appendChild(BX.create('SPAN', {
3005			props: {className: 'bx-context-toolbar-button bx-context-toolbar-button-settings' },
3006			children:
3007			[
3008				BX.create('SPAN',
3009				{
3010					props:{className: 'bx-context-toolbar-button-inner'},
3011					children:
3012					[
3013						BX.create('A', {
3014							attrs: {href: btn.URL},
3015							events: {
3016								mouseover: BX.proxy(this.__msover_text, this),
3017								mouseout: BX.proxy(this.__msout_text, this),
3018								mousedown: BX.proxy(this.__msdown_text, this)
3019							},
3020							html: '<span class="bx-context-toolbar-button-icon bx-context-toolbar-settings-icon"></span>'
3021						}),
3022						BX.create('A', {
3023							attrs: {href: 'javascript: void(0)'},
3024							props: {className: 'bx-context-toolbar-button-arrow'},
3025							events: {
3026								mouseover: BX.proxy(this.__msover_arrow, this),
3027								mouseout: BX.proxy(this.__msout_arrow, this),
3028								mousedown: BX.proxy(this.__msdown_arrow, this)
3029							},
3030							html: '<span class="bx-context-toolbar-button-arrow"></span>'
3031						})
3032					]
3033				})
3034			]
3035		}));
3036
3037		this.OPENER = this.ATTACH.firstChild.lastChild;
3038
3039		var opener = this.attachMenu(this.EXTRA_BUTTONS['components2_submenu']['MENU']);
3040
3041		BX.addCustomEvent(opener, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
3042		BX.addCustomEvent(opener, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
3043	}
3044
3045	if (btnCount > 1)
3046	{
3047		this.PARTS.ICONS.appendChild(BX.create('span', { props: {className: 'bx-context-toolbar-separator bx-context-toolbar-separator-switcher'}}));
3048
3049		this.ICON_TRANSFORM = this.PARTS.ICONS.appendChild(BX.create('A', {
3050			attrs: {href: 'javascript: void(0)'},
3051			props: {className: 'bx-context-toolbar-switcher'},
3052			events: {
3053				click: BX.delegate(this.__trf_btn_clicked, this)
3054			}
3055		}));
3056	}
3057
3058	if (this.PARAMS.HINT)
3059	{
3060		this.DIV.BXHINT = this.HINT = new BX.CHint({
3061			parent: this.DIV,
3062			hint:this.PARAMS.HINT.TEXT || '',
3063			title: this.PARAMS.HINT.TITLE || '',
3064			hide_timeout: this.timeout/2,
3065			preventHide: false
3066		});
3067	}
3068
3069	BX.addCustomEvent(this, 'onWindowDragFinished', BX.delegate(this.__onMoveFinished, this));
3070	BX.addCustomEvent('onDynamicModeChange', BX.delegate(this.__onDynamicModeChange, this));
3071	BX.addCustomEvent('onTopPanelCollapse', BX.delegate(this.__onPanelCollapse, this));
3072
3073	BX.addCustomEvent('onMenuOpenerMoved', BX.delegate(this.checkPosition, this));
3074	BX.addCustomEvent('onMenuOpenerUnhide', BX.delegate(this.checkPosition, this));
3075
3076	if (this.OPENERS)
3077	{
3078		for (i=0,len=this.OPENERS.length; i<len; i++)
3079		{
3080			BX.addCustomEvent(this.OPENERS[i], 'onOpenerMenuOpen', BX.proxy(this.__hide_hint, this));
3081		}
3082	}
3083};
3084BX.extend(BX.CMenuOpener, BX.CWindowFloat);
3085
3086BX.CMenuOpener.prototype.setParent = function(new_parent)
3087{
3088	new_parent = BX(new_parent);
3089	if(new_parent.OPENER && new_parent.OPENER != this)
3090	{
3091		new_parent.OPENER.Close();
3092		new_parent.OPENER.clearHoverHoutEvents();
3093	}
3094
3095	if(this.PARAMS.parent && this.PARAMS.parent != new_parent)
3096	{
3097		this.clearHoverHoutEvents();
3098		this.PARAMS.parent.OPENER = null;
3099	}
3100
3101	this.PARAMS.parent = new_parent;
3102	this.PARAMS.parent.OPENER = this;
3103};
3104
3105BX.CMenuOpener.prototype.setHoverHoutEvents = function(hover, hout)
3106{
3107	if(!this.__opener_events_set)
3108	{
3109		BX.bind(this.Get(), 'mouseover', hover);
3110		BX.bind(this.Get(), 'mouseout', hout);
3111		this.__opener_events_set = true;
3112	}
3113};
3114
3115BX.CMenuOpener.prototype.clearHoverHoutEvents = function()
3116{
3117	if(this.Get())
3118	{
3119		BX.unbindAll(this.Get());
3120		this.__opener_events_set = false;
3121	}
3122};
3123
3124
3125BX.CMenuOpener.prototype.unclosable = true;
3126
3127BX.CMenuOpener.prototype.__check_intersection = function(pos_self, pos_other)
3128{
3129	return !(pos_other.right <= pos_self.left || pos_other.left >= pos_self.right
3130			|| pos_other.bottom <= pos_self.top || pos_other.top >= pos_self.bottom);
3131};
3132
3133
3134BX.CMenuOpener.prototype.__msover_text = function() {
3135	this.bx_hover = true;
3136	if (!this._menu_open)
3137		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-hover');
3138};
3139
3140BX.CMenuOpener.prototype.__msout_text = function() {
3141	this.bx_hover = false;
3142	if (!this._menu_open)
3143		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
3144};
3145
3146BX.CMenuOpener.prototype.__msover_arrow = function() {
3147	this.bx_hover = true;
3148	if (!this._menu_open)
3149		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover');
3150};
3151
3152BX.CMenuOpener.prototype.__msout_arrow = function() {
3153	this.bx_hover = false;
3154	if (!this._menu_open)
3155		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
3156};
3157
3158BX.CMenuOpener.prototype.__msdown_text = function() {
3159	this.bx_active = true;
3160	if (!this._menu_open)
3161		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-text-active');
3162};
3163
3164BX.CMenuOpener.prototype.__msdown_arrow = function() {
3165	this.bx_active = true;
3166	if (!this._menu_open)
3167		BX.addClass(this.ATTACH, 'bx-context-toolbar-button-arrow-active');
3168};
3169
3170BX.CMenuOpener.prototype.__menu_close = function() {
3171	this._menu_open = false;
3172	this.bx_active = false;
3173	BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
3174	if (!this.bx_hover)
3175	{
3176		BX.removeClass(this.ATTACH, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
3177		this.bx_hover = false;
3178	}
3179};
3180
3181BX.CMenuOpener.prototype.__menu_open = function() {
3182	this._menu_open = true;
3183};
3184
3185BX.CMenuOpener.prototype.checkPosition = function()
3186{
3187	if (this.isMenuVisible() || this.DIV.style.display == 'none'
3188		|| this == BX.proxy_context || BX.proxy_context.zIndex > this.zIndex)
3189		return;
3190
3191	this.correctPosition(BX.proxy_context);
3192};
3193
3194BX.CMenuOpener.prototype.correctPosition = function(opener)
3195{
3196	var pos_self = BX.pos(this.DIV), pos_other = BX.pos(opener.Get());
3197	if (this.__check_intersection(pos_self, pos_other))
3198	{
3199		var new_top = pos_other.top - pos_self.height;
3200		if (new_top < 0)
3201			new_top = pos_other.bottom;
3202
3203		this.DIV.style.top = new_top + 'px';
3204
3205		BX.addCustomEvent(opener, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
3206		BX.onCustomEvent(this, 'onMenuOpenerMoved');
3207	}
3208};
3209
3210BX.CMenuOpener.prototype.restorePosition = function()
3211{
3212	if (!this.MOUSEOVER && !this.isMenuVisible())
3213	{
3214		if (this.originalPos)
3215			this.DIV.style.top = this.originalPos.top + 'px';
3216
3217		BX.removeCustomEvent(BX.proxy_context, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
3218		if (this.restore_pos_timeout) clearTimeout(this.restore_pos_timeout);
3219	}
3220	else
3221	{
3222		this.restore_pos_timeout = setTimeout(BX.proxy(this.restorePosition, this), this.timeout);
3223	}
3224};
3225
3226
3227BX.CMenuOpener.prototype.Show = function()
3228{
3229	BX.CMenuOpener.superclass.Show.apply(this, arguments);
3230
3231	this.SetDraggable(this.PARTS.INNER.firstChild);
3232
3233	this.DIV.style.width = 'auto';
3234	this.DIV.style.height = 'auto';
3235
3236	if (!this.PARAMS.pin)
3237	{
3238		this.DIV.style.left = '-1000px';
3239		this.DIV.style.top = '-1000px';
3240
3241		this.Hide();
3242	}
3243	else
3244	{
3245		this.bPosAdjusted = true;
3246		this.bMoved = true;
3247
3248		if (this.PARAMS.top) this.DIV.style.top = this.PARAMS.top + 'px';
3249		if (this.PARAMS.left) this.DIV.style.left = this.PARAMS.left + 'px';
3250
3251		this.DIV.style.display = (!BX.admin.dynamic_mode || BX.admin.dynamic_mode_show_borders) ? 'block' : 'none';
3252
3253		if (this.DIV.style.display == 'block')
3254		{
3255			setTimeout(BX.delegate(function() {BX.onCustomEvent(this, 'onMenuOpenerUnhide')}, this), 50);
3256		}
3257	}
3258};
3259
3260BX.CMenuOpener.prototype.executeDefaultAction = function()
3261{
3262	if (this.defaultAction)
3263	{
3264		if (BX.type.isFunction(this.defaultAction))
3265			this.defaultAction();
3266		else if(BX.type.isString(this.defaultAction))
3267			BX.evalGlobal(this.defaultAction);
3268	}
3269};
3270
3271BX.CMenuOpener.prototype.__onDynamicModeChange = function(val)
3272{
3273	this.DIV.style.display = val ? 'block' : 'none';
3274};
3275
3276BX.CMenuOpener.prototype.__onPanelCollapse = function(bCollapsed, dy)
3277{
3278	this.DIV.style.top = (parseInt(this.DIV.style.top) + dy) + 'px';
3279	if (this.PARAMS.pin)
3280	{
3281		this.__savePosition();
3282	}
3283};
3284
3285BX.CMenuOpener.prototype.__onMoveFinished = function()
3286{
3287	BX.onCustomEvent(this, 'onMenuOpenerMoved');
3288
3289	this.bMoved = true;
3290
3291	if (this.PARAMS.pin)
3292		this.__savePosition();
3293};
3294
3295BX.CMenuOpener.prototype.__savePosition = function()
3296{
3297	var arOpts = {};
3298
3299	arOpts.pin = this.PARAMS.pin;
3300	if (!this.PARAMS.pin)
3301	{
3302		arOpts.top = false; arOpts.left = false; arOpts.transform = false;
3303	}
3304	else
3305	{
3306		arOpts.transform = this.PARAMS.transform;
3307		if (this.bMoved)
3308		{
3309			arOpts.left = parseInt(this.DIV.style.left);
3310			arOpts.top = parseInt(this.DIV.style.top);
3311		}
3312	}
3313
3314	BX.WindowManager.saveWindowOptions(this.PARAMS.component_id, arOpts);
3315};
3316
3317BX.CMenuOpener.prototype.__pin_btn_clicked = function() {this.Pin()};
3318BX.CMenuOpener.prototype.Pin = function(val)
3319{
3320	if (null == val)
3321		this.PARAMS.pin = !this.PARAMS.pin;
3322	else
3323		this.PARAMS.pin = !!val;
3324
3325	this.PARTS.ICON_PIN.className = (this.PARAMS.pin ? 'bx-context-toolbar-pin-fixed' : 'bx-context-toolbar-pin');
3326
3327	this.__savePosition();
3328};
3329
3330BX.CMenuOpener.prototype.__trf_btn_clicked = function() {this.Transform()};
3331BX.CMenuOpener.prototype.Transform = function(val)
3332{
3333	var pos = {};
3334
3335	if (null == val)
3336		this.PARAMS.transform = !this.PARAMS.transform;
3337	else
3338		this.PARAMS.transform = !!val;
3339
3340	if (this.bMoved)
3341	{
3342		pos = BX.pos(this.DIV);
3343	}
3344
3345	if (this.PARAMS.transform)
3346		BX.addClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
3347	else
3348		BX.removeClass(this.DIV.firstChild, 'bx-context-toolbar-vertical-mode');
3349
3350	if (!this.bMoved)
3351	{
3352		this.adjustPos();
3353	}
3354	else
3355	{
3356		this.DIV.style.left = (pos.right - this.DIV.offsetWidth - (BX.browser.IsIE() && !BX.browser.IsDoctype() ? 2 : 0)) + 'px';
3357	}
3358
3359	this.__savePosition();
3360};
3361
3362BX.CMenuOpener.prototype.adjustToNodeGetPos = function()
3363{
3364	var pos = BX.pos(this.PARAMS.parent/*, true*/);
3365
3366	var scrollSize = BX.GetWindowScrollSize();
3367	var floatWidth = this.DIV.offsetWidth;
3368
3369	pos.left -= BX.admin.__border_dx;
3370	pos.top -= BX.admin.__border_dx;
3371
3372	if (true || !this.PARAMS.transform)
3373	{
3374		pos.top -= 45;
3375	}
3376
3377	if (pos.left > scrollSize.scrollWidth - floatWidth)
3378	{
3379		pos.left = scrollSize.scrollWidth - floatWidth;
3380	}
3381
3382	return pos;
3383};
3384
3385BX.CMenuOpener.prototype.addItem = function(item)
3386{
3387	if (item.TYPE)
3388	{
3389		this.EXTRA_BUTTONS[item.TYPE] = item;
3390		return null;
3391	}
3392	else
3393	{
3394		var q = new BX.CMenuOpenerItem(item);
3395		if (null == this.defaultAction)
3396		{
3397			if (q.item.ONCLICK)
3398			{
3399				this.defaultAction = item.ONCLICK;
3400			}
3401			else if (q.item.MENU)
3402			{
3403				this.defaultAction = BX.delegate(function() {this.Open()}, q.item.OPENER);
3404			}
3405
3406			this.defaultActionTitle = item.TITLE || item.TEXT;
3407
3408			BX.addClass(q.Get(), 'bx-content-toolbar-default');
3409		}
3410		if (q.item.OPENER) this.OPENERS[this.OPENERS.length] = q.item.OPENER;
3411		return q.Get();
3412	}
3413};
3414
3415BX.CMenuOpener.prototype.attachMenu = function(menu)
3416{
3417	var opener = new BX.COpener({
3418		'DIV':  this.OPENER,
3419		'ATTACH': this.ATTACH,
3420		'MENU': menu,
3421		'TYPE': 'click'
3422	});
3423
3424	this.OPENERS[this.OPENERS.length] = opener;
3425
3426	return opener;
3427};
3428
3429BX.CMenuOpener.prototype.__hide_hint = function()
3430{
3431	if (this.HINT) this.HINT.__hide_immediately();
3432};
3433
3434BX.CMenuOpener.prototype.isMenuVisible = function()
3435{
3436	for (var i=0,len=this.OPENERS.length; i<len; i++)
3437	{
3438		if (this.OPENERS[i].isMenuVisible())
3439			return true;
3440	}
3441
3442	return false;
3443};
3444
3445BX.CMenuOpener.prototype.Hide = function()
3446{
3447	if (!this.PARAMS.pin)
3448	{
3449		this.DIV.style.display = 'none';
3450		BX.onCustomEvent(this, 'onMenuOpenerHide');
3451	}
3452};
3453BX.CMenuOpener.prototype.UnHide = function()
3454{
3455	this.DIV.style.display = 'block';
3456	if (!this.bPosAdjusted && !this.PARAMS.pin)
3457	{
3458		this.adjustPos();
3459		this.bPosAdjusted = true;
3460	}
3461
3462	if (null == this.originalPos && !this.bMoved)
3463	{
3464		this.originalPos = BX.pos(this.DIV);
3465	}
3466
3467	BX.onCustomEvent(this, 'onMenuOpenerUnhide');
3468};
3469
3470BX.CMenuOpenerItem = function(item)
3471{
3472	this.item = item;
3473
3474	if (this.item.ACTION && !this.item.ONCLICK)
3475	{
3476		this.item.ONCLICK = this.item.ACTION;
3477	}
3478
3479	this.DIV = BX.create('SPAN');
3480	this.DIV.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-underlay'}}));
3481
3482	this.WRAPPER = this.DIV.appendChild(BX.create('SPAN', {
3483		props: {className: 'bx-context-toolbar-button-wrapper'},
3484		children: [
3485			BX.create('SPAN', {
3486				props: {className: 'bx-context-toolbar-button', title: item.TITLE},
3487				children: [
3488					BX.create('SPAN', {
3489						props: {className: 'bx-context-toolbar-button-inner'}
3490					})
3491				]
3492			})
3493		]
3494	}));
3495
3496	var btn_icon = BX.create('SPAN', {
3497		props: {className: 'bx-context-toolbar-button-icon' + (this.item.ICON || this.item.ICONCLASS ? ' ' + (this.item.ICON || this.item.ICONCLASS) : '')},
3498		attrs: (
3499				!(this.item.ICON || this.item.ICONCLASS)
3500				&&
3501				(this.item.SRC || this.item.IMAGE)
3502			)
3503			? {
3504				style: 'background: scroll transparent url(' + (this.item.SRC || this.item.IMAGE) + ') no-repeat center center !important;'
3505			}
3506			: {}
3507	}), btn_text = BX.create('SPAN', {
3508		props: {className: 'bx-context-toolbar-button-text'},
3509		text: this.item.TEXT
3510	});
3511
3512	if (this.item.ACTION && !this.item.ONCLICK)
3513	{
3514		this.item.ONCLICK = this.item.ACTION;
3515	}
3516
3517	this.bHasMenu = !!this.item.MENU;
3518	this.bHasAction = !!this.item.ONCLICK;
3519
3520	if (this.bHasAction)
3521	{
3522		this.LINK = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
3523			attrs: {
3524				'href': 'javascript: void(0)'
3525			},
3526			events: {
3527				mouseover: this.bHasMenu ? BX.proxy(this.__msover_text, this) : BX.proxy(this.__msover, this),
3528				mouseout: this.bHasMenu ? BX.proxy(this.__msout_text, this) : BX.proxy(this.__msout, this),
3529				mousedown: this.bHasMenu ? BX.proxy(this.__msdown_text, this) : BX.proxy(this.__msdown, this)
3530			},
3531			children: [btn_icon, btn_text]
3532		}));
3533
3534		if (this.bHasMenu)
3535		{
3536			this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
3537				props: {className: 'bx-context-toolbar-button-arrow'},
3538				attrs: {
3539					'href': 'javascript: void(0)'
3540				},
3541				events: {
3542					mouseover: BX.proxy(this.__msover_arrow, this),
3543					mouseout: BX.proxy(this.__msout_arrow, this),
3544					mousedown: BX.proxy(this.__msdown_arrow, this)
3545				},
3546				children: [
3547					BX.create('SPAN', {props: {className: 'bx-context-toolbar-button-arrow'}})
3548				]
3549			}));
3550		}
3551
3552	}
3553	else if (this.bHasMenu)
3554	{
3555		this.item.ONCLICK = null;
3556
3557		this.LINK = this.LINK_MENU = this.WRAPPER.firstChild.firstChild.appendChild(BX.create('A', {
3558			attrs: {
3559				'href': 'javascript: void(0)'
3560			},
3561			events: {
3562				mouseover: BX.proxy(this.__msover, this),
3563				mouseout: BX.proxy(this.__msout, this),
3564				mousedown: BX.proxy(this.__msdown, this)
3565			},
3566			children: [
3567				btn_icon,
3568				btn_text
3569			]
3570		}));
3571
3572		this.LINK.appendChild(BX.create('SPAN', {props: {className: 'bx-context-toolbar-single-button-arrow'}}));
3573
3574	}
3575
3576	if (this.bHasMenu)
3577	{
3578		this.item.SUBMENU = new BX.CMenu({
3579			ATTACH_MODE:'bottom',
3580			ITEMS:this.item['MENU'],
3581			//PARENT_MENU:this.parentMenu,
3582			parent: this.LINK_MENU,
3583			parent_attach: this.WRAPPER.firstChild
3584		});
3585
3586		this.item.OPENER = new BX.COpener({
3587			DIV: this.LINK_MENU,
3588			TYPE: 'click',
3589			MENU: this.item.SUBMENU
3590		});
3591
3592		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuOpen', BX.proxy(this.__menu_open, this));
3593		BX.addCustomEvent(this.item.OPENER, 'onOpenerMenuClose', BX.proxy(this.__menu_close, this));
3594	}
3595
3596	if (this.bHasAction)
3597	{
3598		BX.bind(this.LINK, 'click', BX.delegate(this.__click, this));
3599	}
3600};
3601
3602BX.CMenuOpenerItem.prototype.Get = function() {return this.DIV;};
3603BX.CMenuOpenerItem.prototype.__msover = function() {
3604	this.bx_hover = true;
3605	if (!this._menu_open)
3606		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover');
3607};
3608BX.CMenuOpenerItem.prototype.__msout = function() {
3609	this.bx_hover = false;
3610	if (!this._menu_open)
3611		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-active');
3612};
3613BX.CMenuOpenerItem.prototype.__msover_text = function() {
3614	this.bx_hover = true;
3615	if (!this._menu_open)
3616		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover');
3617};
3618BX.CMenuOpenerItem.prototype.__msout_text = function() {
3619	this.bx_hover = false;
3620	if (!this._menu_open)
3621		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-hover bx-context-toolbar-button-text-active');
3622};
3623BX.CMenuOpenerItem.prototype.__msover_arrow = function() {
3624	this.bx_hover = true;
3625	if (!this._menu_open)
3626		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover');
3627};
3628BX.CMenuOpenerItem.prototype.__msout_arrow = function() {
3629	this.bx_hover = false;
3630	if (!this._menu_open)
3631		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-hover bx-context-toolbar-button-arrow-active');
3632};
3633BX.CMenuOpenerItem.prototype.__msdown = function() {
3634	this.bx_active = true;
3635	if (!this._menu_open)
3636		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active');
3637};
3638BX.CMenuOpenerItem.prototype.__msdown_text = function() {
3639	this.bx_active = true;
3640	if (!this._menu_open)
3641		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-text-active');
3642};
3643BX.CMenuOpenerItem.prototype.__msdown_arrow = function() {
3644	this.bx_active = true;
3645	if (!this._menu_open)
3646		BX.addClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-arrow-active');
3647};
3648BX.CMenuOpenerItem.prototype.__menu_close = function() {
3649
3650	this._menu_open = false;
3651	this.bx_active = false;
3652	BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-active bx-context-toolbar-button-text-active bx-context-toolbar-button-arrow-active');
3653	if (!this.bx_hover)
3654	{
3655		BX.removeClass(this.LINK.parentNode.parentNode, 'bx-context-toolbar-button-hover bx-context-toolbar-button-text-hover bx-context-toolbar-button-arrow-hover');
3656		this.bx_hover = false;
3657	}
3658};
3659BX.CMenuOpenerItem.prototype.__menu_open = function() {
3660	this._menu_open = true;
3661};
3662
3663BX.CMenuOpenerItem.prototype.__click = function() {BX.evalGlobal(this.item.ONCLICK)};
3664
3665/* global page opener class */
3666BX.CPageOpener = function(arParams)
3667{
3668	//if (null == arParams.pin) arParams.pin = true;
3669	BX.CPageOpener.superclass.constructor.apply(this, arguments);
3670
3671	this.timeout = 505;
3672
3673	window.PAGE_EDIT_CONTROL = this;
3674};
3675BX.extend(BX.CPageOpener, BX.CMenuOpener);
3676
3677BX.CPageOpener.prototype.checkPosition = function()
3678{
3679	if (/*this.isMenuVisible() || this.DIV.style.display == 'none' || */this == BX.proxy_context)
3680		return;
3681
3682	this.correctPosition(BX.proxy_context);
3683};
3684
3685BX.CPageOpener.prototype.correctPosition = function(opener)
3686{
3687	if (this.bPosCorrected) return;
3688	var pos_self;
3689	if (this.DIV.style.display == 'none')
3690	{
3691		pos_self = this.adjustToNodeGetPos();
3692		pos_self.bottom = pos_self.top + 30;
3693		pos_self.right = pos_self.left + 300;
3694	}
3695	else
3696	{
3697		pos_self = BX.pos(this.DIV);
3698	}
3699
3700	var pos_other = BX.pos(opener.Get());
3701	if (this.__check_intersection(pos_self, pos_other))
3702	{
3703		this.DIV.style.display = 'none';
3704		BX.addCustomEvent(opener, 'onMenuOpenerHide', BX.proxy(this.restorePosition, this));
3705
3706		this.bPosCorrected = true;
3707	}
3708};
3709
3710BX.CPageOpener.prototype.restorePosition = function()
3711{
3712	if (BX.proxy_context && BX.proxy_context.Get().style.display == 'none')
3713	{
3714		this.bPosCorrected = false;
3715
3716		if (this.PARAMS.parent.bx_over || this.PARAMS.pin)
3717			this.UnHide();
3718
3719		BX.removeCustomEvent('onMenuOpenerHide', BX.proxy(this.restorePosition, this));
3720	}
3721};
3722
3723BX.CPageOpener.prototype.UnHide = function()
3724{
3725	if (!this.bPosCorrected)
3726		BX.CPageOpener.superclass.UnHide.apply(this, arguments);
3727};
3728
3729BX.CPageOpener.prototype.Remove = function()
3730{
3731	BX.admin.removeComponentBorder(this.PARAMS.parent);
3732	BX.userOptions.save('global', 'settings', 'page_edit_control_enable', 'N');
3733	this.DIV.style.display = 'none';
3734};
3735
3736/******* HINT ***************/
3737BX.CHintSimple = function()
3738{
3739	BX.CHintSimple.superclass.constructor.apply(this, arguments);
3740};
3741BX.extend(BX.CHintSimple, BX.CHint);
3742
3743BX.CHintSimple.prototype.Init = function()
3744{
3745	this.DIV = document.body.appendChild(BX.create('DIV', {props: {className: 'bx-tooltip-simple'}, style: {display: 'none'}, children: [(this.CONTENT = BX.create('DIV'))]}));
3746
3747	if (this.HINT_TITLE)
3748		this.CONTENT.appendChild(BX.create('B', {text: this.HINT_TITLE}));
3749
3750	if (this.HINT)
3751		this.CONTENT_TEXT = this.CONTENT.appendChild(BX.create('DIV')).appendChild(BX.create('SPAN', {html: this.HINT}));
3752
3753	if (this.PARAMS.preventHide)
3754	{
3755		BX.bind(this.DIV, 'mouseout', BX.proxy(this.Hide, this));
3756		BX.bind(this.DIV, 'mouseover', BX.proxy(this.Show, this));
3757	}
3758
3759	this.bInited = true;
3760};
3761
3762/*************************** admin informer **********************************/
3763BX.adminInformer = {
3764
3765	itemsShow: 3,
3766
3767	Init: function (itemsShow)
3768	{
3769		if(itemsShow)
3770			BX.adminInformer.itemsShow = itemsShow;
3771
3772		var informer = BX("admin-informer");
3773
3774		if(informer)
3775			document.body.appendChild(informer);
3776
3777		BX.addCustomEvent("onTopPanelCollapse", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
3778	},
3779
3780	Toggle: function(notifyBlock)
3781	{
3782		var informer = BX("admin-informer");
3783
3784		if(!informer)
3785			return false;
3786
3787		var pos = BX.pos(notifyBlock);
3788
3789		informer.style.top = (parseInt(pos.top)+parseInt(pos.height)+7)+'px';
3790		informer.style.left = pos.left+'px';
3791
3792		if(!BX.hasClass(informer, "adm-informer-active"))
3793			BX.adminInformer.Show(informer);
3794		else
3795			BX.adminInformer.Hide(informer);
3796
3797		return false;
3798	},
3799
3800	Close: function()
3801	{
3802		BX.adminInformer.Hide(BX("admin-informer"));
3803	},
3804
3805	OnInnerClick: function(event)
3806	{
3807		var target = event.target || event.srcElement;
3808
3809		if(target.nodeName.toLowerCase() != 'a' || BX.hasClass(target,"adm-informer-footer"))
3810		{
3811			return BX.PreventDefault(event);
3812		}
3813
3814		return true;
3815	},
3816
3817	ToggleExtra : function()
3818	{
3819		var footerLink = BX("adm-informer-footer");
3820
3821		if (BX.hasClass(footerLink, "adm-informer-footer-collapsed"))
3822			this.ShowAll();
3823		else
3824			this.HideExtra();
3825
3826		return false;
3827	},
3828
3829	ShowAll: function()
3830	{
3831		var informer = BX("admin-informer");
3832		for(var i=0; i<informer.children.length; i++)
3833
3834			if(BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "none") {
3835				informer.children[i].style.display = "block";
3836			}
3837
3838		var footerLink = BX("adm-informer-footer");
3839
3840		if(footerLink.textContent !== undefined)
3841			footerLink.textContent = BX.message('JSADM_AI_HIDE_EXTRA');
3842		else
3843			footerLink.innerText = BX.message('JSADM_AI_HIDE_EXTRA');
3844
3845		BX.removeClass(footerLink, "adm-informer-footer-collapsed");
3846
3847		return false;
3848	},
3849
3850	HideExtra: function()
3851	{
3852		var informer = BX("admin-informer");
3853		var hided = 0;
3854
3855		for(var i=BX.adminInformer.itemsShow+1; i<informer.children.length; i++)
3856		{
3857			if (BX.hasClass(informer.children[i], "adm-informer-item") && informer.children[i].style.display == "block") {
3858				informer.children[i].style.display = "none";
3859				hided++;
3860			}
3861		}
3862
3863		var footerLink = BX("adm-informer-footer");
3864
3865		var linkText = BX.message('JSADM_AI_ALL_NOTIF')+" ("+(BX.adminInformer.itemsShow+parseInt(hided))+")";
3866
3867		if(footerLink.textContent !== undefined)
3868			footerLink.textContent = linkText;
3869		else
3870			footerLink.innerText = linkText;
3871
3872		BX.addClass(footerLink, "adm-informer-footer-collapsed");
3873
3874		return false;
3875	},
3876
3877	Show: function(informer)
3878	{
3879		var notifButton = BX("adm-header-notif-block");
3880		if (notifButton)
3881			BX.addClass(notifButton, "adm-header-notif-block-active");
3882
3883		BX.onCustomEvent(informer, 'onBeforeAdminInformerShow');
3884		setTimeout(
3885			BX.proxy(function() {
3886					BX.bind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
3887				},
3888				BX.adminInformer
3889			),0
3890		);
3891		BX.addClass(informer, "adm-informer-active");
3892		setTimeout(function() {BX.addClass(informer, "adm-informer-animate");},0);
3893	},
3894
3895	Hide: function(informer)
3896	{
3897		var notifButton = BX("adm-header-notif-block");
3898		if (notifButton)
3899			BX.removeClass(notifButton, "adm-header-notif-block-active");
3900
3901		BX.unbind(document, "click", BX.proxy(BX.adminInformer.Close, BX.adminInformer));
3902
3903		BX.removeClass(informer, "adm-informer-animate");
3904
3905		if (this.IsAnimationSupported())
3906			setTimeout(function() {BX.removeClass(informer, "adm-informer-active");}, 300);
3907		else
3908			BX.removeClass(informer, "adm-informer-active");
3909
3910		BX.onCustomEvent(informer, 'onAdminInformerHide');
3911		//setTimeout(function() {BX.adminInformer.HideExtra();},500);
3912	},
3913
3914	IsAnimationSupported : function()
3915	{
3916		var d = document.body || document.documentElement;
3917		if (typeof(d.style.transition) == "string")
3918			return true;
3919		else if (typeof(d.style.MozTransition) == "string")
3920			return true;
3921		else if (typeof(d.style.OTransition) == "string")
3922			return true;
3923		else if (typeof(d.style.WebkitTransition) == "string")
3924			return true;
3925		else if (typeof(d.style.msTransition) == "string")
3926			return true;
3927
3928		return false;
3929	},
3930
3931
3932	SetItemHtml: function(itemIdx, html)
3933	{
3934		var itemHtmlDiv = BX("adm-informer-item-html-"+itemIdx);
3935
3936		if(!itemHtmlDiv)
3937			return false;
3938
3939		itemHtmlDiv.innerHTML = html;
3940
3941		return true;
3942	},
3943
3944	SetItemFooter: function(itemIdx, html)
3945	{
3946		var itemFooterDiv = BX("adm-informer-item-footer-"+itemIdx);
3947
3948		if(!itemFooterDiv)
3949			return false;
3950
3951		itemFooterDiv.innerHTML = html;
3952
3953		if(html)
3954			itemFooterDiv.style.display = "block";
3955		else
3956			itemFooterDiv.style.display = "none";
3957
3958		return true;
3959	}
3960
3961};
3962
3963}
3963)(window);
3964

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.