Files
ThreadNet-Web/src/resizer/item.ts
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

132 lines
4.0 KiB
TypeScript
Raw Normal View History

2018-12-19 23:51:19 +01:00
/*
2024-09-09 14:57:16 +01:00
Copyright 2024 New Vector Ltd.
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
2018-12-19 23:51:19 +01:00
2024-09-09 14:57:16 +01:00
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
2018-12-19 23:51:19 +01:00
*/
2021-06-29 13:11:58 +01:00
import Resizer, { IConfig } from "./resizer";
2020-10-20 11:03:03 +01:00
import Sizer from "./sizer";
2023-07-07 13:37:26 +01:00
export default class ResizeItem<C extends IConfig> {
2020-10-13 12:28:23 +01:00
public readonly domNode: HTMLElement;
protected readonly id: string | null;
protected reverse: boolean;
public constructor(
handle: HTMLElement,
2023-07-07 13:37:26 +01:00
public readonly resizer: Resizer<C, any>,
2020-10-13 12:28:23 +01:00
public readonly sizer: Sizer,
2021-08-24 13:05:46 +02:00
public readonly container?: HTMLElement,
) {
2020-10-20 11:03:03 +01:00
this.reverse = resizer.isReverseResizeHandle(handle);
2021-08-24 13:05:46 +02:00
if (container) {
this.domNode = container;
2021-08-24 13:05:46 +02:00
} else {
this.domNode = <HTMLElement>(this.reverse ? handle.nextElementSibling : handle.previousElementSibling);
}
2020-10-20 11:03:03 +01:00
this.id = handle.getAttribute("data-id");
2018-12-19 23:51:19 +01:00
}
2023-07-07 13:37:26 +01:00
private copyWith(
handle: HTMLElement,
resizer: Resizer<C, any>,
sizer: Sizer,
container?: HTMLElement,
): ResizeItem<C> {
const Ctor = this.constructor as typeof ResizeItem;
2021-08-24 13:05:46 +02:00
return new Ctor(handle, resizer, sizer, container);
2018-12-19 23:51:19 +01:00
}
2023-07-07 13:37:26 +01:00
private advance(forwards: boolean): ResizeItem<C> | undefined {
2018-12-19 23:51:19 +01:00
// opposite direction from fromResizeHandle to get back to handle
let handle: Element | null | undefined = this.reverse
? this.domNode.previousElementSibling
: this.domNode.nextElementSibling;
2018-12-19 23:51:19 +01:00
const moveNext = forwards !== this.reverse; // xor
// iterate at least once to avoid infinite loop
do {
if (moveNext) {
handle = handle?.nextElementSibling;
2018-12-19 23:51:19 +01:00
} else {
handle = handle?.previousElementSibling;
2018-12-19 23:51:19 +01:00
}
2020-10-20 11:03:03 +01:00
} while (handle && !this.resizer.isResizeHandle(<HTMLElement>handle));
2019-01-14 20:24:54 +01:00
2018-12-19 23:51:19 +01:00
if (handle) {
2020-10-20 11:03:03 +01:00
const nextHandle = this.copyWith(<HTMLElement>handle, this.resizer, this.sizer);
2018-12-19 23:51:19 +01:00
nextHandle.reverse = this.reverse;
return nextHandle;
}
}
2023-07-07 13:37:26 +01:00
public next(): ResizeItem<C> | undefined {
return this.advance(true);
2018-12-19 23:51:19 +01:00
}
2023-07-07 13:37:26 +01:00
public previous(): ResizeItem<C> | undefined {
return this.advance(false);
2018-12-19 23:51:19 +01:00
}
public size(): number {
2018-12-19 23:51:19 +01:00
return this.sizer.getItemSize(this.domNode);
}
public offset(): number {
2018-12-19 23:51:19 +01:00
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 {
2020-10-13 12:28:23 +01:00
return this.sizer.getDesiredItemSize(this.domNode);
}
public setRawSize(size: string): void {
2018-12-19 23:51:19 +01:00
this.sizer.setItemSize(this.domNode, size);
2020-10-13 12:28:23 +01:00
}
public setSize(size: number): void {
2020-10-13 12:28:23 +01:00
this.setRawSize(`${Math.round(size)}px`);
this.resizer.config?.onResized?.(size, this.id, this.domNode);
2018-12-19 23:51:19 +01:00
}
public clearSize(): void {
this.sizer.clearItemSize(this.domNode);
this.resizer.config?.onResized?.(null, this.id, this.domNode);
}
2023-07-07 13:37:26 +01:00
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) {
2020-10-20 11:03:03 +01:00
return this.copyWith(<HTMLElement>firstHandle, this.resizer, this.sizer);
}
}
2023-07-07 13:37:26 +01:00
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) {
2020-10-20 11:03:03 +01:00
return this.copyWith(<HTMLElement>lastHandle, this.resizer, this.sizer);
}
}
2018-12-19 23:51:19 +01:00
}