AnonSec Shell
Server IP : 85.193.89.191  /  Your IP : 3.15.198.92
Web Server : Apache
System : Linux 956367-cx40159.tmweb.ru 3.10.0-1160.105.1.el7.x86_64 #1 SMP Thu Dec 7 15:39:45 UTC 2023 x86_64
User : bitrix ( 600)
PHP Version : 8.1.27
Disable Function : NONE
MySQL : OFF  |  cURL : OFF  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /home/bitrix/www/bitrix/js/calendar/planner/src/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/bitrix/www/bitrix/js/calendar/planner/src/selector.js
"use strict";
import {EventEmitter, BaseEvent} from 'main.core.events';
import {Util} from 'calendar.util';
import {Type, Dom, Tag} from 'main.core';
import { EventDragAndDrop } from 'calendar.ui.tools.draganddrop';

export class Selector extends EventEmitter
{
	DOM = {};
	selectMode = false;
	currentDateFrom = new Date();
	currentDateTo = new Date();
	currentFullDay = false;
	useAnimation = true;
	beforeBeginChange = false;

	constructor(params = {})
	{
		super();
		this.setEventNamespace('BX.Calendar.Planner.Selector');

		this.getPosByDate = params.getPosByDate;
		this.getDateByPos = params.getDateByPos;
		this.getPosDateMap = params.getPosDateMap;
		this.getTimelineWidth = params.getTimelineWidth;
		this.getScaleInfo = params.getScaleInfo;
		this.solidStatus = params.solidStatus;

		this.eventDragAndDrop = new EventDragAndDrop(params.getDateByPos, params.getPosByDate, params.getEvents);

		this.useAnimation = params.useAnimation !== false;

		this.render();
	}

	render()
	{
		this.DOM.timeNodes = {};
		this.DOM.timeWrap = Tag.render`
			<div></div>
		`;

		this.DOM.wrap = Tag.render`
			<div class="calendar-planner-timeline-selector" data-bx-planner-meta="selector">
				<span data-bx-planner-meta="selector-resize-left" class="calendar-planner-timeline-drag-left"></span>
				<span class="calendar-planner-timeline-selector-grip"></span>
				<span data-bx-planner-meta="selector-resize-right" class="calendar-planner-timeline-drag-right"></span>
				${this.DOM.timeWrap}
				<div class="calendar-planner-timeline-selector-background"></div>
				${this.renderMoreButton()}
			</div>
		`;

		// prefent draging selector and activating uploader controll in livefeed
		this.DOM.wrap.ondrag = BX.False;
		this.DOM.wrap.ondragstart = BX.False;

		this.DOM.titleNode = Tag.render`<div class="calendar-planner-selector-notice" style="display: none"></div>`;
	}

	renderMoreButton()
	{
		this.DOM.moreButton = Tag.render`
			<div class="calendar-planner-timeline-selector-more-button" style="display: none;"></div>
		`;

		return this.DOM.moreButton;
	}

	shake()
	{
		const shakeClass = 'calendar-planner-selector-shake';
		Dom.addClass(this.DOM.wrap, shakeClass);
		clearTimeout(this.shakeTimeout);
		this.shakeTimeout = setTimeout(() => Dom.removeClass(this.DOM.wrap, shakeClass), 400);
	}

	clearTimeNodes()
	{
		for (const offset in this.DOM.timeNodes)
		{
			this.destroyTimeNode(offset);
		}
	}

	showTimeNode(offsetTop, time, timezone, isWarning = false)
	{
		this.destroyTimeNode(offsetTop);

		const warningClass = isWarning ? '--warning' : '';

		this.DOM.timeNodes[offsetTop] = Tag.render`
			<div class="calendar-planner-timeline-side-notice --left ${warningClass}" style="top: ${offsetTop}px" title="${timezone}">${time}</div>
		`;
		this.DOM.timeWrap.append(this.DOM.timeNodes[offsetTop]);
	}

	destroyTimeNode(offset)
	{
		if (Type.isElementNode(this.DOM.timeNodes[offset]))
		{
			this.DOM.timeNodes[offset].remove();
			this.DOM.timeNodes[offset] = null;
		}
	}

	getWrap()
	{
		return this.DOM.wrap;
	}

	getTitleNode()
	{
		return this.DOM.titleNode;
	}

	/**
	 *
	 *
	 * @params array array of parameters
	 * @params[from]
	 * @params[to]
	 * @params[updateScaleType] bool
	 * @params[updateScaleLimits] bool
	 *
	 * @return null
	 */
	update(params = {})
	{
		if (!Type.isPlainObject(params))
		{
			params = {};
		}

		params.updateScaleType = !!params.updateScaleType;
		params.updateScaleLimits = !!params.updateScaleLimits;
		params.animation = !!params.animation;

		let from = Type.isDate(params.from) ? params.from : BX.parseDate(params.from) || this.currentDateFrom;
		let to = Type.isDate(params.to) ? params.to : BX.parseDate(params.to) || this.currentDateTo;
		this.fullDayMode = params.fullDay !== undefined ? params.fullDay : this.currentFullDay;

		if (Type.isDate(from) && Type.isDate(to))
		{
			this.currentFullDay = this.fullDayMode;

			if (this.fullDayMode)
			{
				from.setHours(0, 0, 0, 0);
				const dayCount = Math.ceil((to.getTime() - from.getTime() + 1) / (1000 * 3600 * 24));
				to = new Date(from.getTime() + (dayCount - 1) * 24 * 3600 * 1000);
				to.setHours(23, 55, 0, 0);
			}

			this.boundaryFrom = from;
			this.currentDateFrom = from;
			this.currentDateTo = to;

			// Update selector
			this.show(
				from,
				to,
				{
					animation: params.animation,
					focus: params.focus
				}
			);
		}

		const isSelectorInThePast = this.currentDateTo.getTime() < this.getScaleInfo().scaleDateFrom.getTime();
		const isSelectorInTheFuture = this.currentDateFrom.getTime() > this.getScaleInfo().scaleDateTo.getTime();
		if (isSelectorInThePast || isSelectorInTheFuture)
		{
			this.DOM.wrap.style.display = 'none';
		}
	}

	show(from, to, params)
	{
		const animation = params.animation && this.useAnimation !== false;
		const focus = params.focus === true;
		const alignCenter = params.alignCenter !== false;

		this.DOM.wrap.style.display = 'block';

		if (Type.isDate(from) && Type.isDate(to))
		{
			let
				fromPos = this.getPosByDate(from),
				toPos = this.getPosByDate(to);

			this.DOM.wrap.style.width = (toPos - fromPos) + 'px';

			if (animation && this.DOM.wrap.style.left && !this.currentFullDay)
			{
				this.transit({
					toX: fromPos,
					// triggerChangeEvents: false, //if everything is broken - uncomment
					focus: focus
				});
			}
			else
			{
				this.DOM.wrap.style.left = fromPos + 'px';
				this.DOM.wrap.style.width = (toPos - fromPos) + 'px';
				if (focus)
				{
					this.focus(true, 200, alignCenter);
				}
				this.checkStatus(fromPos, true);
			}
		}
	}

	hide()
	{
		this.DOM.wrap.style.display = 'none';
	}

	startMove()
	{
		document.addEventListener('pointermove', this.preventDefault, { passive:false });
		this.selectorIsDraged = true;
		this.selectorStartLeft = parseInt(this.DOM.wrap.style.left);
		this.selectorStartScrollLeft = this.DOM.timelineWrap.scrollLeft;

		this.eventDragAndDrop.onDragStart(this.currentDateTo.getTime() - this.currentDateFrom.getTime(), this.selectorStartLeft);

		Dom.addClass(document.body, 'calendar-planner-unselectable');

		this.beforeBeginChange = true;
	}

	move(x)
	{
		if (this.selectorIsDraged)
		{
			let pos = this.selectorStartLeft + x;

			// Correct cursor position acording to changes of scrollleft
			pos -= this.selectorStartScrollLeft - this.DOM.timelineWrap.scrollLeft;
			pos = this.checkPosition(pos);

			if (!this.getDateByPos(pos) || !this.getDateByPos(pos + parseInt(this.DOM.wrap.style.width)))
			{
				return;
			}

			let boundary = this.eventDragAndDrop.getDragBoundary(pos);

			const valueChanged = boundary.from.getTime() !== this.boundaryFrom.getTime();
			if (valueChanged && this.beforeBeginChange)
			{
				this.emit('onBeginChange');
				this.beforeBeginChange = false;
			}

			boundary = this.getAutoScrollBoundary(boundary, valueChanged);
			boundary = this.getConstrainedBoundary(boundary);

			this.setBoundary(boundary);
		}
	}

	getAutoScrollBoundary(boundary, valueChanged)
	{
		const boundaryLeft = boundary.position - this.DOM.timelineWrap.scrollLeft;
		const containerLeft = this.getPosByDate(this.getScaleInfo().scaleDateFrom);
		const boundaryRight = boundaryLeft + boundary.size;
		const containerRight = this.DOM.timelineFixedWrap.offsetWidth;

		if (boundaryRight > containerRight)
		{
			this.scrollSpeed = this.getSpeed(boundaryRight, containerRight);
			boundary.position = containerRight + this.DOM.timelineWrap.scrollLeft - boundary.size;
			this.setAutoScrollInterval(boundary, 1);
		}
		else if (boundaryLeft < containerLeft)
		{
			this.scrollSpeed = this.getSpeed(boundaryLeft, containerLeft);
			boundary.position = containerLeft + this.DOM.timelineWrap.scrollLeft;
			this.setAutoScrollInterval(boundary, -1);
		}
		else
		{
			this.stopAutoScroll(valueChanged);
		}

		return boundary;
	}

	getSpeed(x1, x2)
	{
		return Math.floor(Math.sqrt(Math.abs(x1 - x2))) + 1;
	}

	setAutoScrollInterval(boundary, direction)
	{
		if (!this.scrollInterval)
		{
			this.scrollInterval = setInterval(() => {
				if (!this.getDateByPos(boundary.position + this.scrollSpeed * direction)
					|| !this.getDateByPos(boundary.position + boundary.size + this.scrollSpeed * direction)
				)
				{
					this.stopAutoScroll();
					return;
				}

				this.DOM.timelineWrap.scrollLeft += this.scrollSpeed * direction;
				boundary.position += this.scrollSpeed * direction;
				boundary.from = this.getDateByPos(boundary.position);
				boundary.to = this.getDateByPos(boundary.position + boundary.size);
				this.eventDragAndDrop.setFinalTimeInterval(boundary.from, boundary.to);
				this.setBoundary(boundary);
			}, 13);
		}
	}

	stopAutoScroll(valueChanged = true)
	{
		clearInterval(this.scrollInterval);
		this.scrollInterval = false;

		if (valueChanged || !this.beforeBeginChange)
		{
			this.emit('onStopAutoScroll');
		}
	}

	setBoundary(boundary)
	{
		if (boundary.wasMagnetized)
		{
			this.DOM.wrap.style.transition = 'left .05s, width .1s';
		}
		else
		{
			this.DOM.wrap.style.transition = 'width .1s';
		}

		this.DOM.wrap.style.width = boundary.size + 'px';
		this.DOM.wrap.style.left = boundary.position + 'px';

		this.showTitle(boundary.from, boundary.to);

		this.checkStatus(boundary.position, true);

		this.boundaryFrom = boundary.from;
	}

	getConstrainedBoundary(boundary)
	{
		if (boundary.wasMagnetized || this.fullDayMode)
		{
			return boundary;
		}

		let from = new Date(boundary.from.getTime());
		let to = new Date(boundary.to.getTime());
		const duration = to.getTime() - from.getTime();
		let position = boundary.position;
		let size = boundary.size;
		let wasMagnetized = false;

		if (from.getHours() < this.getScaleInfo().shownTimeFrom)
		{
			from.setHours(this.getScaleInfo().shownTimeFrom, 0, 0, 0);
			to = new Date(from.getTime() + duration);
			wasMagnetized = true;
			position = this.getPosByDate(from);
			size = this.getPosByDate(to) - position;
		}

		if (to.getHours() > this.getScaleInfo().shownTimeTo
			|| (to.getHours() === this.getScaleInfo().shownTimeTo && to.getMinutes() > 0))
		{
			to.setHours(this.getScaleInfo().shownTimeTo, 0, 0, 0);
			from = new Date(to.getTime() - duration);
			wasMagnetized = true;
			position = this.getPosByDate(from);
			size = this.getPosByDate(to) - position;
		}

		return { from, to, position, size, wasMagnetized };
	}

	endMove()
	{
		document.removeEventListener('pointermove', this.preventDefault, { passive:false });
		this.stopAutoScroll();
		if (this.selectorIsDraged)
		{
			this.selectorIsDraged = false;

			const left = this.getPosByDate(this.eventDragAndDrop.getFinalFrom());
			const right = this.getPosByDate(this.eventDragAndDrop.getFinalTo());

			const finalBoundary = this.getConstrainedBoundary({
				from: this.eventDragAndDrop.getFinalFrom(),
				to: this.eventDragAndDrop.getFinalTo(),
				position: left,
				size: right - left
			});

			this.DOM.wrap.style.left = finalBoundary.position + 'px';
			this.DOM.wrap.style.width = finalBoundary.size + 'px';
			this.DOM.wrap.style.transition = 'none';

			this.checkStatus(left, true);
			this.hideTitle();
			this.setValue();
		}
		this.selectorIsDraged = false;
	}

	startResize()
	{
		document.addEventListener('pointermove', this.preventDefault, { passive:false });

		this.selectorIsResized = true;

		this.selectorStartLeft = parseInt(this.DOM.wrap.style.left);
		this.selectorStartWidth = parseInt(this.DOM.wrap.style.width);
		this.selectorStartScrollLeft = this.DOM.timelineWrap.scrollLeft;

		this.beforeBeginChange = true;
	}

	resize(x)
	{
		if (this.selectorIsResized)
		{
			let
				toDate,
				timeTo,
				width = this.selectorStartWidth + x;

			// Correct cursor position according to changes of scrollLeft
			width -= this.selectorStartScrollLeft - this.DOM.timelineWrap.scrollLeft;
			let rightPos = Math.min(this.selectorStartLeft + width, this.getTimelineWidth());
			if (rightPos < this.selectorStartLeft)
			{
				rightPos = this.selectorStartLeft;
			}

			toDate = this.getDateByPos(rightPos, true);

			if (this.fullDayMode)
			{
				if (toDate.getTime() - this.currentDateFrom.getTime() < Util.getDayLength())
				{
					toDate = new Date(this.currentDateFrom.getTime() + Util.getDayLength());
				}

				timeTo = parseInt(toDate.getHours()) + Math.round((toDate.getMinutes() / 60) * 10) / 10;
				toDate.setHours(0, 0, 0, 0);
				if (timeTo > 12)
				{
					toDate = new Date(toDate.getTime() + Util.getDayLength());
					toDate.setHours(0, 0, 0, 0);
				}
				rightPos = this.getPosByDate(toDate);
			}
			else if (this.getScaleInfo().shownTimeFrom !== 0 || this.getScaleInfo().shownTimeTo !== 24)
			{
				let fromDate = this.getDateByPos(this.selectorStartLeft);
				if (toDate && fromDate && fromDate.getDate() !== toDate.getDate())
				{
					toDate = new Date(fromDate.getTime());
					toDate.setHours(this.getScaleInfo().shownTimeTo, 0, 0, 0);
					rightPos = this.getPosByDate(toDate);
				}
			}

			if (this.getPosDateMap()[rightPos])
			{
				this.selectorRoundedRightPos = rightPos;
			}
			else
			{
				let roundedPos = Selector.roundPos(rightPos);
				if (this.getPosDateMap()[roundedPos])
				{
					this.selectorRoundedRightPos = roundedPos;
				}
			}
			if (this.selectorRoundedRightPos < this.selectorStartLeft)
			{
				this.selectorRoundedRightPos = this.selectorStartLeft;
			}

			if (!this.fullDayMode && this.selectorRoundedRightPos - this.DOM.timelineWrap.scrollLeft > this.DOM.timelineFixedWrap.offsetWidth)
			{
				this.selectorRoundedRightPos = this.DOM.timelineWrap.scrollLeft + this.DOM.timelineFixedWrap.offsetWidth;
			}

			width = this.selectorRoundedRightPos - this.selectorStartLeft;

			this.DOM.wrap.style.width = width + 'px';
			this.showTitle(this.getDateByPos(this.selectorStartLeft), this.getDateByPos(this.selectorRoundedRightPos));
			this.checkStatus(this.selectorStartLeft, true);

			if (this.beforeBeginChange)
			{
				this.emit('onBeginChange');
				this.beforeBeginChange = false;
			}
		}
	}

	endResize()
	{
		document.removeEventListener('pointermove', this.preventDefault, { passive:false });
		if (this.selectorIsResized)
		{
			this.selectorIsResized = false;

			let left = parseInt(this.DOM.wrap.style.left);
			let right = left + parseInt(this.DOM.wrap.style.width);
			const from = this.getDateByPos(left);
			const to = this.getDateByPos(right);
			left = this.getPosByDate(from);
			right = this.getPosByDate(to);
			this.DOM.wrap.style.width = (right - left) + 'px';

			this.checkStatus(left, true);
			this.hideTitle();
			this.setValue();
		}
		this.selectorIsResized = false;
	}

	preventDefault(e)
	{
		e.preventDefault();
	}

	isDragged()
	{
		return this.selectorIsResized || this.selectorIsDraged;
	}

	checkStatus(selectorPos, checkPosition)
	{
		if (this.solidStatus)
		{
			Dom.removeClass(this.DOM.wrap, 'calendar-planner-timeline-selector-warning');
			Dom.removeClass(this.mainContWrap, 'calendar-planner-selector-warning');
			Dom.addClass(this.DOM.wrap, 'solid');
		}
		else
		{
			if (!selectorPos)
			{
				selectorPos = Selector.roundPos(this.DOM.wrap.style.left);
			}

			let fromDate, toDate;
			if (checkPosition === true || !this.currentDateFrom)
			{
				let
					selectorWidth = parseInt(this.DOM.wrap.style.width),
					fromPos = selectorPos,
					toPos = fromPos + selectorWidth;

				if (!fromPos && !toPos && !selectorWidth && this.lastFromDate)
				{
					fromDate = this.lastFromDate;
					toDate = this.lastToDate;
				}
				else
				{
					fromDate = this.getDateByPos(fromPos);
					toDate = this.getDateByPos(toPos, true);
					this.lastFromDate = fromDate;
					this.lastToDate = toDate;
				}
			}
			else
			{
				fromDate = this.currentDateFrom;
				toDate = this.currentDateTo;
			}

			this.emit(
				'doCheckStatus',
				new BaseEvent(
				{
						data: {
							dateFrom: fromDate,
							dateTo: toDate
						}
					}
				)
			);
		}
	}

	setSelectorStatus(status)
	{
		this.selectorIsFree = status;
		if (this.selectorIsFree)
		{
			Dom.removeClass(this.DOM.wrap, 'calendar-planner-timeline-selector-warning');
		}
		else
		{
			Dom.addClass(this.DOM.wrap, 'calendar-planner-timeline-selector-warning');
		}
	}

	setValue(selectorPos = null, duration = null)
	{
		if (!selectorPos)
		{
			selectorPos = parseInt(this.DOM.wrap.style.left);
		}
		selectorPos = Math.max(0, selectorPos);
		const selectorWidth = parseInt(this.DOM.wrap.style.width);

		if (selectorPos + selectorWidth > parseInt(this.getTimelineWidth()))
		{
			selectorPos = parseInt(this.getTimelineWidth()) - selectorWidth;
		}

		const dateFrom = this.getDateByPos(selectorPos);
		let dateTo;
		if (duration)
		{
			dateTo = new Date(dateFrom.getTime() + duration);
		}
		else
		{
			dateTo = this.getDateByPos(selectorPos + selectorWidth, true);
		}

		if (dateFrom && dateTo)
		{
			if (this.fullDayMode)
			{
				const dayCount = Math.ceil((dateTo.getTime() - dateFrom.getTime()) / (1000 * 3600 * 24));
				dateTo = new Date(dateFrom.getTime() + (dayCount - 1) * 24 * 3600 * 1000);
				dateTo.setHours(23, 55, 0, 0);
			}
			if (!this.fullDayMode && dateFrom.getDate() !== dateTo.getDate() && dateTo.getHours() !== 0 && dateTo.getMinutes() !== 0)
			{
				const duration = this.currentDateTo.getTime() - this.currentDateFrom.getTime();
				dateTo = new Date(dateFrom.getTime() + duration);
			}

			this.currentDateFrom = dateFrom;
			this.currentDateTo = dateTo;
			this.currentFullDay = this.fullDayMode;
			this.boundaryFrom = this.currentDateFrom;

			this.emit('onChange', new BaseEvent({data: {
				dateFrom: dateFrom,
				dateTo: dateTo,
				fullDay: this.fullDayMode
			}}));
		}
	}

	checkPosition(fromPos, selectorWidth, toPos)
	{
		let scaleInfo = this.getScaleInfo();
		if (!this.fullDayMode && scaleInfo.shownTimeFrom === 0 && scaleInfo.shownTimeTo === 24)
		{
			return fromPos;
		}

		fromPos = fromPos || parseInt(this.DOM.wrap.style.left);
		selectorWidth = selectorWidth || parseInt(this.DOM.wrap.style.width);
		toPos = toPos || (fromPos + selectorWidth);
		if (toPos > parseInt(this.getTimelineWidth()))
		{
			fromPos = parseInt(this.getTimelineWidth()) - selectorWidth;
		}
		else
		{
			let
				fromDate = this.getDateByPos(fromPos),
				toDate = this.getDateByPos(toPos, true),
				timeFrom, timeTo,
				scaleTimeFrom = parseInt(scaleInfo.shownTimeFrom),
				scaleTimeTo = parseInt(scaleInfo.shownTimeTo);

			if (fromDate && toDate)
			{
				if (this.fullDayMode)
				{
					if (fromDate.getHours() > 12)
					{
						fromDate = new Date(fromDate.getTime() + Util.getDayLength());
					}
					fromDate.setHours(0, 0, 0, 0);

					fromPos = this.getPosByDate(fromDate);
				}
				else if (fromDate.getDay() !== toDate.getDay())
				{
					timeFrom = parseInt(fromDate.getHours()) + Math.round((fromDate.getMinutes() / 60) * 10) / 10;
					timeTo = parseInt(toDate.getHours()) + Math.round((toDate.getMinutes() / 60) * 10) / 10;

					if (Math.abs(scaleTimeTo - timeFrom) > Math.abs(scaleTimeFrom - timeTo))
					{
						fromDate.setHours(scaleInfo.shownTimeTo, 0, 0,0);
						fromPos = this.getPosByDate(fromDate) - selectorWidth;
					}
					else
					{
						toDate.setHours(scaleInfo.shownTimeFrom, 0, 0,0);
						fromPos = this.getPosByDate(toDate);
					}
				}
			}
		}
		return Math.max(fromPos, 0);
	}

	transit(params = {})
	{
		this.DOM.wrap.style.display = 'block';

		let duration;
		if (Type.isDate(params.leftDate) && Type.isDate(params.rightDate))
		{
			if (this.fullDayMode)
			{
				const dayCount = Math.ceil((this.currentDateTo.getTime() - this.currentDateFrom.getTime()) / (1000 * 3600 * 24));
				params.leftDate.setHours(0, 0, 0, 0);
				params.rightDate = new Date(params.leftDate.getTime() + (dayCount - 1) * 24 * 3600 * 1000);
				params.rightDate.setHours(23, 55, 0, 0);
			}
			duration = params.rightDate.getTime() - params.leftDate.getTime();
			const fromPos = this.getPosByDate(params.leftDate);
			const toPos = this.getPosByDate(params.rightDate);
			params.toX = fromPos;
			this.DOM.wrap.style.width = (toPos - fromPos) + 'px';
		}

		let
			fromX = params.fromX ?? parseInt(this.DOM.wrap.style.left),
			toX = Selector.roundPos(params.toX ?? fromX),
			triggerChangeEvents = params.triggerChangeEvents !== false,
			focus = !!params.focus;

		if (fromX !== toX)
		{
			if (this.animation)
			{
				this.animation.stop();
			}

			this.emit('onStartTransit');

			this.animation = new BX.easing({
				duration: 300,
				start: {left: fromX},
				finish: {left: toX},
				transition: BX.easing.makeEaseOut(BX.easing.transitions.quart),
				step: (state) => {this.DOM.wrap.style.left = state.left + 'px'},
				complete: () => {
					this.animation = null;
					let
						fromPos = parseInt(this.DOM.wrap.style.left),
						checkedPos = this.checkPosition(fromPos);

					if (checkedPos !== fromPos)
					{
						this.DOM.wrap.style.left = checkedPos + 'px';
					}

					if (triggerChangeEvents)
					{
						this.setValue(checkedPos, duration);
					}

					if (focus)
					{
						this.focus(true, 300);
					}

					setTimeout(() => {
						this.show(
							this.currentDateFrom,
							this.currentDateTo,
							{
								animation: false,
								focus: focus,
								alignCenter: false
							}
						);
					}, 200);

					this.checkStatus(checkedPos);
				}
			});

			this.animation.animate();
		}
		else
		{
			if (triggerChangeEvents)
			{
				this.setValue(false, duration);
			}

			if (focus === true)
			{
				this.focus(true, 300);
			}

			this.checkStatus();
		}
	}

	showTitle(from, to)
	{
		let
			fromDate = new Date(from.getTime()),
			toDate = new Date(to.getTime()),
			selectorTitle = this.getTitleNode(),
			selector = this.DOM.wrap;

		if (this.fullDayMode)
		{
			toDate = new Date(toDate.getTime() - 5 * 60 * 1000);
			if (toDate.getDate() === fromDate.getDate())
			{
				selectorTitle.innerHTML = BX.date.format('d F, D', fromDate.getTime() / 1000);
			}
			else
			{
				selectorTitle.innerHTML =
					BX.date.format('d F', fromDate.getTime() / 1000)
					+ ' - '
					+ BX.date.format('d F', toDate.getTime() / 1000);
			}
		}
		else
		{
			selectorTitle.removeAttribute('style');
			selectorTitle.innerHTML = Util.formatTime(fromDate) + ' - ' + Util.formatTime(toDate);
		}

		selector.appendChild(selectorTitle);

		if (selectorTitle === this.selectorTitle)
		{
			if (selectorTitle.style.display === 'none' || this.selectorHideTimeout)
			{
				this.selectorHideTimeout = clearTimeout(this.selectorHideTimeout);
				// Opacity animation
				this.selectorTitle.style.display = '';
				this.selectorTitle.style.opacity = 0;
				new BX.easing({
					duration: 400,
					start: {opacity: 0},
					finish: {opacity: 100},
					transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
					step: (state)=>{this.selectorTitle.style.opacity = state.opacity / 100;},
					complete: ()=>{this.selectorTitle.removeAttribute('style');}
				}).animate();
			}
		}
		else
		{
			selectorTitle.removeAttribute('style');
		}
	}

	hideTitle(params = {})
	{
		if (!Type.isPlainObject(params))
			params = {};

		let
			timeoutName = params.selectorIndex === undefined ? 'selectorHideTimeout' : 'selectorHideTimeout_' + params.selectorIndex,
			selectorTitle = params.selectorTitle || this.getTitleNode();

		if (this[timeoutName])
			this[timeoutName] = clearTimeout(this[timeoutName]);

		if (params.timeout !== false)
		{
			this[timeoutName] = setTimeout(() => {
				params.timeout = false;
				this.hideTitle(params);
			}, 700);
		}
		else
		{
			// Opacity animation
			selectorTitle.style.display = '';
			selectorTitle.style.opacity = 1;
			new BX.easing({
				duration: 400,
				start: {opacity: 100},
				finish: {opacity: 0},
				transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
				step: (state) => {selectorTitle.style.opacity = state.opacity / 100;},
				complete: () => {
					selectorTitle.removeAttribute('style');
					selectorTitle.style.display = 'none';
				}
			}).animate();
		}
	}

	static roundPos(x)
	{
		return Math.round(parseFloat(x));
	}

	focus(animation = true, timeout = 300, alignCenter)
	{
		alignCenter = alignCenter === true;

		if (this.focusTimeout)
		{
			this.focusTimeout = !!clearTimeout(this.focusTimeout);
		}

		if (this.useAnimation === false)
		{
			animation = false;
		}

		if (timeout)
		{
			this.focusTimeout = setTimeout(() => {this.focus(animation, false, alignCenter);}, timeout);
		}
		else
		{
			const
				screenDelta = 10,
				selectorLeft = parseInt(this.DOM.wrap.style.left),
				selectorWidth = parseInt(this.DOM.wrap.style.width),
				viewWidth = parseInt(this.DOM.timelineWrap.offsetWidth),
				viewLeft = parseInt(this.DOM.timelineWrap.scrollLeft),
				viewRight = viewLeft + viewWidth;

			let newScrollLeft = viewLeft;

			if (selectorLeft < viewLeft + screenDelta
				|| selectorLeft > viewRight - screenDelta
				|| alignCenter
			)
			{
				// Selector is smaller than view - we puting it in the middle of the view
				if (selectorWidth <= viewWidth)
				{
					newScrollLeft = Math.max(Math.round(selectorLeft - ((viewWidth - selectorWidth) / 2 )), screenDelta);

				}
				else // Selector is wider, so we adjust by left side
				{
					newScrollLeft = Math.max(Math.round(selectorLeft - screenDelta), screenDelta);
				}
			}

			if (newScrollLeft !== viewLeft)
			{
				if (animation === false)
				{
					this.DOM.timelineWrap.scrollLeft = newScrollLeft;
				}
				else
				{
					new BX.easing({
						duration: 300,
						start: {scrollLeft: this.DOM.timelineWrap.scrollLeft},
						finish: {scrollLeft: newScrollLeft},
						transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
						step: (state)=>{this.DOM.timelineWrap.scrollLeft = state.scrollLeft;},
						complete: ()=>{}
					}).animate();
				}
			}
		}
	}

	getDuration()
	{
		let duration = Math.round((this.currentDateTo - this.currentDateFrom) / 1000) * 1000;

		if (this.fullDayMode)
		{
			duration += Util.getDayLength();
		}

		return duration;
	}

	getDateFrom()
	{
		return this.currentDateFrom;
	}

	getDateTo()
	{
		return this.currentDateTo;
	}
}

Anon7 - 2022
AnonSec Team