403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/js/ui/sidepanel/layout/src/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/js/ui/sidepanel/layout/src/index.js
import 'ui.fonts.opensans';
import './css/style.css';
import 'sidepanel';
import { Dom, Tag, Type, BaseError, Event, Runtime } from 'main.core';
import { BaseEvent, EventEmitter } from 'main.core.events';
import { CloseButton, CancelButton, BaseButton } from 'ui.buttons';
import { Menu, type MenuOptions, Item as MenuItem } from 'ui.sidepanel.menu';

const UI = BX.UI;
const SidePanel = BX.SidePanel;

type DesignOptions = {
	margin: ?boolean;
	section: ?boolean;
	alignButtonsLeft: ?boolean;
};

type SidePanelMenuOptions = {
	...MenuOptions;
	contentAttribute: ?string;
};

type Options = {
	extensions: ?Array<string>;
	title: ?string;
	toolbar: ?Function;
	content: string | Element | Promise | BX.Promise;
	buttons: ?Function;
	design: ?DesignOptions;
	menu: ?SidePanelMenuOptions;
};

function prepareOptions(options: Options = {}): Options
{
	options = { ...options };
	options.design = { ...options.design };
	options.design = {
		margin: true,
		section: true,
		...options.design,
	};

	options.extensions = [...(options.extensions || []),
		'ui.sidepanel.layout',
		'ui.buttons',
	];
	if (options.toolbar)
	{
		options.extensions.push('ui.buttons.icons');
	}

	if (options.design.section)
	{
		options.extensions.push('ui.sidepanel-content');
	}

	if (options.menu)
	{
		options.extensions.push('ui.sidepanel.menu');
	}

	return options;
}

export class Layout
{
	static createContent(options: Options = {}): Promise<any | HTMLElement>
	{
		options = prepareOptions(options);

		return top.BX.Runtime
			.loadExtension(options.extensions)
			.then(() => (new Layout(options)).render())
		;
	}

	static createLayout(options: Options = {}): Promise
	{
		options = prepareOptions(options);

		return top.BX.Runtime
			.loadExtension(options.extensions)
			.then(() => new Layout(options))
		;
	}

	#container;
	#containerFooter;
	#options;
	#menu: Menu;

	constructor(options: Options = {})
	{
		this.#options = prepareOptions(options);
		const menuOptions = this.#options.menu;
		if (menuOptions)
		{
			this.#menu = new Menu(Object.assign(menuOptions));
			if (Type.isUndefined(menuOptions.contentAttribute))
			{
				menuOptions.contentAttribute = 'data-menu-item-id';
			}

			if (menuOptions.contentAttribute)
			{
				this.#menu.subscribe('click', (event: BaseEvent) => {
					this.#onMenuItemClick((event.getData() || {}).item);
				});
			}
		}
	}

	getContainer(): HTMLElement
	{
		if (!this.#container)
		{
			this.#container = Tag.render`<div class="ui-sidepanel-layout"></div>`;
		}

		return this.#container;
	}

	getMenu(): Menu
	{
		return this.#menu;
	}

	getFooterContainer(): HTMLElement
	{
		if (!this.#containerFooter)
		{
			this.#containerFooter = Tag.render`<div class="ui-sidepanel-layout-footer"></div>`;
		}

		return this.#containerFooter;
	}

	render(content: string = '', promised: boolean = false)
	{
		if (this.#options.content && !promised)
		{
			content = this.#options.content();
			if (
				Object.prototype.toString.call(content) === '[object Promise]'
				|| (content.toString && content.toString() === '[object BX.Promise]')
			)
			{
				return content.then((content) => this.render(content, true));
			}
		}

		const container = this.getContainer();
		container.innerHTML = '';

		// HEADER
		if (this.#options.title)
		{
			const title = Tag.safe`${this.#options.title}`;
			const header = Tag.render`
				<div class="ui-sidepanel-layout-header">
					<div class="ui-sidepanel-layout-title">${title}</div>
				</div>
			`;

			if (Type.isFunction(this.#options.toolbar))
			{
				const toolbar = Tag.render`<div class="ui-sidepanel-layout-toolbar"></div>`;
				this.#options.toolbar({ ...UI }).forEach((button) => {
					if (button instanceof BaseButton)
					{
						button.renderTo(toolbar);
					}
					else if (Type.isDomNode(button))
					{
						Dom.append(button, toolbar);
					}
					else
					{
						throw new BaseError(`Wrong button type ${button}`);
					}
				});

				Dom.append(toolbar, header);
			}

			Dom.append(header, container);
		}

		// CONTENT
		{
			const design = this.#options.design;
			const classes = ['ui-sidepanel-layout-content'];
			const styles = [];
			if (design.margin)
			{
				if (design.margin === true)
				{
					classes.push('ui-sidepanel-layout-content-margin');
				}
				else
				{
					styles.push(`margin: ${design.margin}`);
				}
			}
			let contentElement = Tag.render`<div class="${classes.join(' ')}" style="${styles.join('; ')}"></div>`;
			Dom.append(contentElement, container);

			if (this.#menu)
			{
				this.#menu.renderTo(contentElement);
			}
			Dom.append(Tag.render`<div class="ui-sidepanel-layout-content-inner"></div>`, contentElement);
			contentElement = contentElement.lastElementChild;

			if (design.section)
			{
				Dom.append(Tag.render`<div class="ui-slider-section ui-sidepanel-layout-content-fill-height"></div>`, contentElement);
				contentElement = contentElement.firstElementChild;
			}

			if (Type.isString(content))
			{
				contentElement.innerHTML = content;
			}
			else if (content instanceof Element)
			{
				Dom.append(content, contentElement);
			}

			if (this.#menu)
			{
				this.#onMenuItemClick(this.#menu.getActiveItem(), contentElement);
			}
		}

		// FOOTER
		const isButtonsUndefined = Type.isUndefined(this.#options.buttons);
		if (Type.isFunction(this.#options.buttons) || isButtonsUndefined)
		{
			const cancelButton = new CancelButton({ onclick: () => SidePanel.Instance.close() });
			const closeButton = new CloseButton({ onclick: () => SidePanel.Instance.close() });
			const defaults = {
				...UI,
				cancelButton,
				closeButton,
			};
			if (isButtonsUndefined)
			{
				this.#options.buttons = () => [closeButton];
			}

			const buttonList = this.#options.buttons(defaults);
			if (buttonList && buttonList.length > 0)
			{
				Dom.append(Tag.render`<div class="ui-sidepanel-layout-footer-anchor"></div>`, container);

				const classes = ['ui-sidepanel-layout-buttons'];
				if (this.#options.design.alignButtonsLeft)
				{
					classes.push('ui-sidepanel-layout-buttons-align-left');
				}
				const buttons = Tag.render`<div class="${classes.join(' ')}"></div>`;
				Dom.append(buttons, this.getFooterContainer());
				buttonList.forEach((button) => {
					if (button instanceof BaseButton)
					{
						button.renderTo(buttons);
					}
					else if (Type.isDomNode(button))
					{
						Dom.append(button, buttons);
					}
					else
					{
						throw new BaseError(`Wrong button type ${button}`);
					}
				});
				Dom.append(this.getFooterContainer(), container);
			}
		}

		setTimeout(() => {
			this.afterRender();
		});

		return container;
	}

	afterRender()
	{
		this.#adjustFooter();

		const resizeHandler = Runtime.throttle(this.#adjustFooter, 300, this);
		Event.bind(window, 'resize', resizeHandler);

		const topSlider = SidePanel.Instance.getTopSlider();
		if (topSlider)
		{
			EventEmitter.subscribeOnce(topSlider, 'SidePanel.Slider:onDestroy', () => {
				Event.unbind(window, 'resize', resizeHandler);
			});
		}
	}

	#getScrollWidth(): number
	{
		const div = Tag.render`<div style="overflow-y: scroll; width: 50px; height: 50px; opacity: 0; pointer-events: none; position: absolute;"></div>`;
		Dom.append(div, document.body);
		const scrollWidth = div.offsetWidth - div.clientWidth;
		Dom.remove(div);

		return scrollWidth;
	}

	#adjustFooter()
	{
		const parentSet = this.getContainer().parentNode;

		if (
			parentSet !== null
			&& parentSet.scrollWidth > parentSet.offsetWidth
		)
		{
			Dom.style(this.getFooterContainer(), 'bottom', `${this.#getScrollWidth()}px`);
		}
		else
		{
			Dom.style(this.getFooterContainer(), 'bottom', 0);
		}
	}

	#onMenuItemClick(item: MenuItem, container: HTMLElement = null)
	{
		if (!item)
		{
			return;
		}

		const id = item.getId();
		const attr = this.#options.menu.contentAttribute;
		if (!attr)
		{
			return;
		}

		container = container || this.#container;
		let nodes = container.querySelectorAll(`[${attr}]`);
		nodes = Array.prototype.slice.call(nodes);
		nodes.forEach((node) => {
			node.hidden = node.getAttribute(attr) !== id;
		});
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit