/* Copyright 2018 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** implements DOM/CSS operations for resizing. The sizer determines what CSS mechanism is used for sizing items, like flexbox, ... */ export default class Sizer { 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() { let element = this.container; let offset = 0; while (element) { const pos = this.vertical ? element.offsetTop : element.offsetLeft; offset = offset + pos; element = element.offsetParent as HTMLElement; } return offset; } public setItemSize(item: HTMLElement, size: number) { if (this.vertical) { item.style.height = `${Math.round(size)}px`; } else { item.style.width = `${Math.round(size)}px`; } } public clearItemSize(item: HTMLElement) { if (this.vertical) { item.style.height = null; } else { item.style.width = null; } } // TODO public start(item: HTMLElement) {} // TODO public finish(item: HTMLElement) {} /** @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) { const pos = this.vertical ? event.pageY : event.pageX; if (this.reverse) { return (this.getPageOffset() + this.getTotalSize()) - pos; } else { return pos - this.getPageOffset(); } } }