feat: show call participants in room list (Discord-style)
Docker / Docker Buildx (push) Has been cancelled
Build Debian package / Build package (release) Has been cancelled
Build and Deploy / prepare (release) Has been cancelled
Deploy release / Deploy to Cloudflare Pages (release) Has been cancelled
Build and Deploy / Trigger Pro pipeline (release) Has been cancelled
Build and Deploy / Windows arm64 (release) Has been cancelled
Build and Deploy / Windows x64 (release) Has been cancelled
Build and Deploy / macOS (release) Has been cancelled
Build and Deploy / Linux amd64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / Linux arm64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / ${{ needs.prepare.outputs.deploy == 'true' && 'Deploy' || 'Deploy (dry-run)' }} (release) Has been cancelled
Build and Deploy / Deploy builds to ESS (release) Has been cancelled
Docker / Docker Buildx (push) Has been cancelled
Build Debian package / Build package (release) Has been cancelled
Build and Deploy / prepare (release) Has been cancelled
Deploy release / Deploy to Cloudflare Pages (release) Has been cancelled
Build and Deploy / Trigger Pro pipeline (release) Has been cancelled
Build and Deploy / Windows arm64 (release) Has been cancelled
Build and Deploy / Windows x64 (release) Has been cancelled
Build and Deploy / macOS (release) Has been cancelled
Build and Deploy / Linux amd64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / Linux arm64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / ${{ needs.prepare.outputs.deploy == 'true' && 'Deploy' || 'Deploy (dry-run)' }} (release) Has been cancelled
Build and Deploy / Deploy builds to ESS (release) Has been cancelled
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { BaseDistributor } from "./fixed";
|
||||
import ResizeItem from "../item";
|
||||
import { type IConfig } from "../resizer";
|
||||
import type Resizer from "../resizer";
|
||||
import type Sizer from "../sizer";
|
||||
|
||||
export interface ICollapseConfig extends IConfig {
|
||||
toggleSize: number;
|
||||
onCollapsed?(collapsed: boolean, id: string | null, element: HTMLElement): void;
|
||||
isItemCollapsed(element: HTMLElement): boolean;
|
||||
}
|
||||
|
||||
export class CollapseItem extends ResizeItem<ICollapseConfig> {
|
||||
public notifyCollapsed(collapsed: boolean): void {
|
||||
this.resizer.config?.onCollapsed?.(collapsed, this.id, this.domNode);
|
||||
}
|
||||
|
||||
public get isCollapsed(): boolean {
|
||||
return this.resizer.config?.isItemCollapsed?.(this.domNode) ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
export default class CollapseDistributor extends BaseDistributor<ICollapseConfig, CollapseItem> {
|
||||
public static createItem(
|
||||
resizeHandle: HTMLDivElement,
|
||||
resizer: Resizer<ICollapseConfig, CollapseItem>,
|
||||
sizer: Sizer,
|
||||
container?: HTMLElement,
|
||||
): CollapseItem {
|
||||
return new CollapseItem(resizeHandle, resizer, sizer, container);
|
||||
}
|
||||
|
||||
private readonly toggleSize: number | undefined;
|
||||
private isCollapsed: boolean;
|
||||
|
||||
public constructor(item: CollapseItem) {
|
||||
super(item);
|
||||
this.toggleSize = item.resizer?.config?.toggleSize;
|
||||
this.isCollapsed = item.isCollapsed;
|
||||
}
|
||||
|
||||
public resize(newSize: number): void {
|
||||
const isCollapsedSize = !!this.toggleSize && newSize < this.toggleSize;
|
||||
if (isCollapsedSize !== this.isCollapsed) {
|
||||
this.isCollapsed = isCollapsedSize;
|
||||
this.item.notifyCollapsed(isCollapsedSize);
|
||||
}
|
||||
if (!isCollapsedSize) {
|
||||
super.resize(newSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import ResizeItem from "../item";
|
||||
import Sizer from "../sizer";
|
||||
import { type IConfig } from "../resizer";
|
||||
import type Resizer from "../resizer";
|
||||
|
||||
export abstract class BaseDistributor<C extends IConfig, I extends ResizeItem<C> = ResizeItem<C>> {
|
||||
public static createSizer(containerElement: HTMLElement, vertical: boolean, reverse: boolean): Sizer {
|
||||
return new Sizer(containerElement, vertical, reverse);
|
||||
}
|
||||
|
||||
private readonly beforeOffset: number;
|
||||
|
||||
public constructor(public readonly item: I) {
|
||||
this.beforeOffset = item.offset();
|
||||
}
|
||||
|
||||
public get size(): string {
|
||||
return this.item.getSize();
|
||||
}
|
||||
|
||||
public set size(size: string) {
|
||||
this.item.setRawSize(size);
|
||||
}
|
||||
|
||||
public resize(size: number): void {
|
||||
this.item.setSize(size);
|
||||
}
|
||||
|
||||
public resizeFromContainerOffset(offset: number): void {
|
||||
this.resize(offset - this.beforeOffset);
|
||||
}
|
||||
|
||||
public start(): void {
|
||||
this.item.start();
|
||||
}
|
||||
|
||||
public finish(): void {
|
||||
this.item.finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
distributors translate a moving cursor into
|
||||
CSS/DOM changes by calling the sizer
|
||||
|
||||
they have two methods:
|
||||
`resize` receives then new item size
|
||||
`resizeFromContainerOffset` receives resize handle location
|
||||
within the container bounding box. For internal use.
|
||||
This method usually ends up calling `resize` once the start offset is subtracted.
|
||||
*/
|
||||
export default class FixedDistributor<
|
||||
C extends IConfig,
|
||||
I extends ResizeItem<C> = ResizeItem<C>,
|
||||
> extends BaseDistributor<C, I> {
|
||||
public static createItem(resizeHandle: HTMLDivElement, resizer: Resizer<any>, sizer: Sizer): ResizeItem<any> {
|
||||
return new ResizeItem(resizeHandle, resizer, sizer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import Sizer from "../sizer";
|
||||
import FixedDistributor from "./fixed";
|
||||
import { type IConfig } from "../resizer";
|
||||
|
||||
class PercentageSizer extends Sizer {
|
||||
public start(item: HTMLElement): void {
|
||||
if (this.vertical) {
|
||||
item.style.minHeight = "";
|
||||
} else {
|
||||
item.style.minWidth = "";
|
||||
}
|
||||
}
|
||||
|
||||
public finish(item: HTMLElement): void {
|
||||
const parent = item.offsetParent as HTMLElement;
|
||||
if (!parent) return;
|
||||
if (this.vertical) {
|
||||
const p = ((item.offsetHeight / parent.offsetHeight) * 100).toFixed(2) + "%";
|
||||
item.style.minHeight = p;
|
||||
item.style.height = p;
|
||||
} else {
|
||||
const p = ((item.offsetWidth / parent.offsetWidth) * 100).toFixed(2) + "%";
|
||||
item.style.minWidth = p;
|
||||
item.style.width = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default class PercentageDistributor extends FixedDistributor<IConfig> {
|
||||
public static createSizer(containerElement: HTMLElement, vertical: boolean, reverse: boolean): PercentageSizer {
|
||||
return new PercentageSizer(containerElement, vertical, reverse);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
export { default as FixedDistributor } from "./distributors/fixed";
|
||||
export { default as PercentageDistributor } from "./distributors/percentage";
|
||||
export { default as CollapseDistributor } from "./distributors/collapse";
|
||||
export { default as Resizer } from "./resizer";
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type IConfig } from "./resizer";
|
||||
import type Resizer from "./resizer";
|
||||
import type Sizer from "./sizer";
|
||||
|
||||
export default class ResizeItem<C extends IConfig> {
|
||||
public readonly domNode: HTMLElement;
|
||||
protected readonly id: string | null;
|
||||
protected reverse: boolean;
|
||||
|
||||
public constructor(
|
||||
handle: HTMLElement,
|
||||
public readonly resizer: Resizer<C, any>,
|
||||
public readonly sizer: Sizer,
|
||||
public readonly container?: HTMLElement,
|
||||
) {
|
||||
this.reverse = resizer.isReverseResizeHandle(handle);
|
||||
if (container) {
|
||||
this.domNode = container;
|
||||
} else {
|
||||
this.domNode = <HTMLElement>(this.reverse ? handle.nextElementSibling : handle.previousElementSibling);
|
||||
}
|
||||
this.id = handle.getAttribute("data-id");
|
||||
}
|
||||
|
||||
private copyWith(
|
||||
handle: HTMLElement,
|
||||
resizer: Resizer<C, any>,
|
||||
sizer: Sizer,
|
||||
container?: HTMLElement,
|
||||
): ResizeItem<C> {
|
||||
const Ctor = this.constructor as typeof ResizeItem;
|
||||
return new Ctor(handle, resizer, sizer, container);
|
||||
}
|
||||
|
||||
private advance(forwards: boolean): ResizeItem<C> | undefined {
|
||||
// opposite direction from fromResizeHandle to get back to handle
|
||||
let handle: Element | null | undefined = this.reverse
|
||||
? this.domNode.previousElementSibling
|
||||
: this.domNode.nextElementSibling;
|
||||
const moveNext = forwards !== this.reverse; // xor
|
||||
// iterate at least once to avoid infinite loop
|
||||
do {
|
||||
if (moveNext) {
|
||||
handle = handle?.nextElementSibling;
|
||||
} else {
|
||||
handle = handle?.previousElementSibling;
|
||||
}
|
||||
} while (handle && !this.resizer.isResizeHandle(<HTMLElement>handle));
|
||||
|
||||
if (handle) {
|
||||
const nextHandle = this.copyWith(<HTMLElement>handle, this.resizer, this.sizer);
|
||||
nextHandle.reverse = this.reverse;
|
||||
return nextHandle;
|
||||
}
|
||||
}
|
||||
|
||||
public next(): ResizeItem<C> | undefined {
|
||||
return this.advance(true);
|
||||
}
|
||||
|
||||
public previous(): ResizeItem<C> | undefined {
|
||||
return this.advance(false);
|
||||
}
|
||||
|
||||
public size(): number {
|
||||
return this.sizer.getItemSize(this.domNode);
|
||||
}
|
||||
|
||||
public offset(): number {
|
||||
return this.sizer.getItemOffset(this.domNode);
|
||||
}
|
||||
|
||||
public start(): void {
|
||||
this.sizer.start(this.domNode);
|
||||
}
|
||||
|
||||
public finish(): void {
|
||||
this.sizer.finish(this.domNode);
|
||||
}
|
||||
|
||||
public getSize(): string {
|
||||
return this.sizer.getDesiredItemSize(this.domNode);
|
||||
}
|
||||
|
||||
public setRawSize(size: string): void {
|
||||
this.sizer.setItemSize(this.domNode, size);
|
||||
}
|
||||
|
||||
public setSize(size: number): void {
|
||||
this.setRawSize(`${Math.round(size)}px`);
|
||||
this.resizer.config?.onResized?.(size, this.id, this.domNode);
|
||||
}
|
||||
|
||||
public clearSize(): void {
|
||||
this.sizer.clearItemSize(this.domNode);
|
||||
this.resizer.config?.onResized?.(null, this.id, this.domNode);
|
||||
}
|
||||
|
||||
public first(): ResizeItem<C> | undefined {
|
||||
if (!this.domNode.parentElement?.children) {
|
||||
return;
|
||||
}
|
||||
const firstHandle = Array.from(this.domNode.parentElement.children).find((el) => {
|
||||
return this.resizer.isResizeHandle(<HTMLElement>el);
|
||||
});
|
||||
if (firstHandle) {
|
||||
return this.copyWith(<HTMLElement>firstHandle, this.resizer, this.sizer);
|
||||
}
|
||||
}
|
||||
|
||||
public last(): ResizeItem<C> | undefined {
|
||||
if (!this.domNode.parentElement?.children) {
|
||||
return;
|
||||
}
|
||||
const lastHandle = Array.from(this.domNode.parentElement.children)
|
||||
.reverse()
|
||||
.find((el) => {
|
||||
return this.resizer.isResizeHandle(<HTMLElement>el);
|
||||
});
|
||||
if (lastHandle) {
|
||||
return this.copyWith(<HTMLElement>lastHandle, this.resizer, this.sizer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2018-2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { throttle } from "lodash";
|
||||
|
||||
import type FixedDistributor from "./distributors/fixed";
|
||||
import type ResizeItem from "./item";
|
||||
import type Sizer from "./sizer";
|
||||
|
||||
interface IClassNames {
|
||||
// class on resize-handle
|
||||
handle?: string;
|
||||
// class on resize-handle
|
||||
reverse?: string;
|
||||
// class on resize-handle
|
||||
vertical?: string;
|
||||
// class on container
|
||||
resizing?: string;
|
||||
}
|
||||
|
||||
export interface IConfig {
|
||||
onResizeStart?(): void;
|
||||
onResizeStop?(): void;
|
||||
onResized?(size: number | null, id: string | null, element: HTMLElement): void;
|
||||
handler?: HTMLDivElement;
|
||||
}
|
||||
|
||||
export default class Resizer<C extends IConfig, I extends ResizeItem<C> = ResizeItem<C>> {
|
||||
private classNames: IClassNames;
|
||||
|
||||
// TODO move vertical/horizontal to config option/container class
|
||||
// as it doesn't make sense to mix them within one container/Resizer
|
||||
public constructor(
|
||||
public container: HTMLElement | null,
|
||||
private readonly distributorCtor: {
|
||||
new (item: I): FixedDistributor<C, I>;
|
||||
createItem(resizeHandle: HTMLDivElement, resizer: Resizer<C, I>, sizer: Sizer, container?: HTMLElement): I;
|
||||
createSizer(containerElement: HTMLElement | null, vertical: boolean, reverse: boolean): Sizer;
|
||||
},
|
||||
public readonly config?: C,
|
||||
) {
|
||||
this.classNames = {
|
||||
handle: "resizer-handle",
|
||||
reverse: "resizer-reverse",
|
||||
vertical: "resizer-vertical",
|
||||
resizing: "resizer-resizing",
|
||||
};
|
||||
}
|
||||
|
||||
public setClassNames(classNames: IClassNames): void {
|
||||
this.classNames = classNames;
|
||||
}
|
||||
|
||||
public attach(): void {
|
||||
const attachment = this?.config?.handler?.parentElement ?? this.container;
|
||||
attachment?.addEventListener("mousedown", this.onMouseDown, false);
|
||||
window.addEventListener("resize", this.onResize);
|
||||
}
|
||||
|
||||
public detach(): void {
|
||||
const attachment = this?.config?.handler?.parentElement ?? this.container;
|
||||
attachment?.removeEventListener("mousedown", this.onMouseDown, false);
|
||||
window.removeEventListener("resize", this.onResize);
|
||||
}
|
||||
|
||||
/**
|
||||
Gives the distributor for a specific resize handle, as if you would have started
|
||||
to drag that handle. Can be used to manipulate the size of an item programmatically.
|
||||
@param {number} handleIndex the index of the resize handle in the container
|
||||
@return {FixedDistributor} a new distributor for the given handle
|
||||
*/
|
||||
public forHandleAt(handleIndex: number): FixedDistributor<C, I> | undefined {
|
||||
const handles = this.getResizeHandles();
|
||||
const handle = handles[handleIndex];
|
||||
if (handle) {
|
||||
const { distributor } = this.createSizerAndDistributor(<HTMLDivElement>handle);
|
||||
return distributor;
|
||||
}
|
||||
}
|
||||
|
||||
public forHandleWithId(id: string): FixedDistributor<C, I> | undefined {
|
||||
const handles = this.getResizeHandles();
|
||||
const handle = handles.find((h) => h.getAttribute("data-id") === id);
|
||||
if (handle) {
|
||||
const { distributor } = this.createSizerAndDistributor(<HTMLDivElement>handle);
|
||||
return distributor;
|
||||
}
|
||||
}
|
||||
|
||||
public isReverseResizeHandle(el: HTMLElement): boolean {
|
||||
return el.classList.contains(this.classNames.reverse!);
|
||||
}
|
||||
|
||||
public isResizeHandle(el: HTMLElement): boolean {
|
||||
return el.classList.contains(this.classNames.handle!);
|
||||
}
|
||||
|
||||
private onMouseDown = (event: MouseEvent): void => {
|
||||
const LEFT_MOUSE_BUTTON = 0;
|
||||
if (event.button !== LEFT_MOUSE_BUTTON) {
|
||||
return;
|
||||
}
|
||||
// use closest in case the resize handle contains
|
||||
// child dom nodes that can be the target
|
||||
const resizeHandle = event.target && (<HTMLDivElement>event.target).closest(`.${this.classNames.handle}`);
|
||||
const hasHandler = this?.config?.handler;
|
||||
// prevent that stacked resizer's are both activated with one mouse event
|
||||
// (this is possible because the mouse events are connected to the containers not the handles)
|
||||
if (
|
||||
!resizeHandle || // if no resizeHandle exist / mouse event hit the container not the handle
|
||||
(!hasHandler && resizeHandle.parentElement !== this.container) || // no handler from config -> check if the containers match
|
||||
(hasHandler && resizeHandle !== hasHandler)
|
||||
) {
|
||||
// handler from config -> check if the handlers match
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent starting a drag operation
|
||||
event.preventDefault();
|
||||
|
||||
// mark as currently resizing
|
||||
if (this.classNames.resizing) {
|
||||
this.container?.classList?.add(this.classNames.resizing);
|
||||
}
|
||||
this.config?.onResizeStart?.();
|
||||
|
||||
const { sizer, distributor } = this.createSizerAndDistributor(<HTMLDivElement>resizeHandle);
|
||||
distributor.start();
|
||||
|
||||
const onMouseMove = (event: MouseEvent): void => {
|
||||
const offset = sizer.offsetFromEvent(event);
|
||||
distributor.resizeFromContainerOffset(offset);
|
||||
};
|
||||
|
||||
const body = document.body;
|
||||
const finishResize = (): void => {
|
||||
if (this.classNames.resizing) {
|
||||
this.container?.classList?.remove(this.classNames.resizing);
|
||||
}
|
||||
distributor.finish();
|
||||
this.config?.onResizeStop?.();
|
||||
body.removeEventListener("mouseup", finishResize, false);
|
||||
document.removeEventListener("mouseleave", finishResize, false);
|
||||
body.removeEventListener("mousemove", onMouseMove, false);
|
||||
};
|
||||
body.addEventListener("mouseup", finishResize, false);
|
||||
document.addEventListener("mouseleave", finishResize, false);
|
||||
body.addEventListener("mousemove", onMouseMove, false);
|
||||
};
|
||||
|
||||
private onResize = throttle(
|
||||
() => {
|
||||
const distributors = this.getDistributors();
|
||||
|
||||
// relax all items if they had any overconstrained flexboxes
|
||||
distributors.forEach((d) => d.start());
|
||||
distributors.forEach((d) => d.finish());
|
||||
},
|
||||
100,
|
||||
{ trailing: true, leading: true },
|
||||
);
|
||||
|
||||
public getDistributors = (): FixedDistributor<C, I>[] => {
|
||||
return this.getResizeHandles().map((handle) => {
|
||||
const { distributor } = this.createSizerAndDistributor(<HTMLDivElement>handle);
|
||||
return distributor;
|
||||
});
|
||||
};
|
||||
|
||||
private createSizerAndDistributor(resizeHandle: HTMLDivElement): {
|
||||
sizer: Sizer;
|
||||
distributor: FixedDistributor<C, I>;
|
||||
} {
|
||||
const vertical = resizeHandle.classList.contains(this.classNames.vertical!);
|
||||
const reverse = this.isReverseResizeHandle(resizeHandle);
|
||||
const Distributor = this.distributorCtor;
|
||||
const useItemContainer = this.config?.handler ? this.container : undefined;
|
||||
const sizer = Distributor.createSizer(this.container, vertical, reverse);
|
||||
const item = Distributor.createItem(resizeHandle, this, sizer, useItemContainer ?? undefined);
|
||||
const distributor = new Distributor(item);
|
||||
return { sizer, distributor };
|
||||
}
|
||||
|
||||
private getResizeHandles(): HTMLElement[] {
|
||||
if (this?.config?.handler) {
|
||||
return [this.config.handler];
|
||||
}
|
||||
if (!this.container?.children) return [];
|
||||
return Array.from(this.container.querySelectorAll(`.${this.classNames.handle}`));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2018-2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
/**
|
||||
implements DOM/CSS operations for resizing.
|
||||
The sizer determines what CSS mechanism is used for sizing items, like flexbox, ...
|
||||
*/
|
||||
export default class Sizer {
|
||||
public constructor(
|
||||
protected readonly container: HTMLElement,
|
||||
protected readonly vertical: boolean,
|
||||
protected readonly reverse: boolean,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@param {Element} item the dom element being resized
|
||||
@return {number} how far the edge of the item is from the edge of the container
|
||||
*/
|
||||
public getItemOffset(item: HTMLElement): number {
|
||||
const offset = (this.vertical ? item.offsetTop : item.offsetLeft) - this.getOffset();
|
||||
if (this.reverse) {
|
||||
return this.getTotalSize() - (offset + this.getItemSize(item));
|
||||
} else {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@param {Element} item the dom element being resized
|
||||
@return {number} the width/height of an item in the container
|
||||
*/
|
||||
public getItemSize(item: HTMLElement): number {
|
||||
return this.vertical ? item.offsetHeight : item.offsetWidth;
|
||||
}
|
||||
|
||||
/** @return {number} the width/height of the container */
|
||||
public getTotalSize(): number {
|
||||
return this.vertical ? this.container.offsetHeight : this.container.offsetWidth;
|
||||
}
|
||||
|
||||
/** @return {number} container offset to offsetParent */
|
||||
private getOffset(): number {
|
||||
return this.vertical ? this.container.offsetTop : this.container.offsetLeft;
|
||||
}
|
||||
|
||||
/** @return {number} container offset to document */
|
||||
private getPageOffset(): number {
|
||||
let element = this.container;
|
||||
let offset = 0;
|
||||
while (element) {
|
||||
const pos = this.vertical ? element.offsetTop : element.offsetLeft;
|
||||
offset = offset + pos;
|
||||
element = <HTMLElement>element.offsetParent;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
public getDesiredItemSize(item: HTMLElement): string {
|
||||
if (this.vertical) {
|
||||
return item.style.height;
|
||||
} else {
|
||||
return item.style.width;
|
||||
}
|
||||
}
|
||||
|
||||
public setItemSize(item: HTMLElement, size: string): void {
|
||||
if (this.vertical) {
|
||||
item.style.height = size;
|
||||
} else {
|
||||
item.style.width = size;
|
||||
}
|
||||
}
|
||||
|
||||
public clearItemSize(item: HTMLElement): void {
|
||||
if (this.vertical) {
|
||||
item.style.removeProperty("height");
|
||||
} else {
|
||||
item.style.removeProperty("width");
|
||||
}
|
||||
}
|
||||
|
||||
public start(item: HTMLElement): void {}
|
||||
|
||||
public finish(item: HTMLElement): void {}
|
||||
|
||||
/**
|
||||
@param {MouseEvent} event the mouse event
|
||||
@return {number} the distance between the cursor and the edge of the container,
|
||||
along the applicable axis (vertical or horizontal)
|
||||
*/
|
||||
public offsetFromEvent(event: MouseEvent): number {
|
||||
const pos = this.vertical ? event.pageY : event.pageX;
|
||||
if (this.reverse) {
|
||||
return this.getPageOffset() + this.getTotalSize() - pos;
|
||||
} else {
|
||||
return pos - this.getPageOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user