PageSourceSearch

https://www.nsu.ru/bitrix/js/main/core/core_window.js

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

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.