PageSourceSearch

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

js ekamedcenter.ru collected 2026-09-28 13:30:41 UTC 98,321 bytes, 4,013 lines download raw bytes

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

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.