From 9ecb23ce71103ec7316799b895ba280e03fd09f9 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 14 Jan 2019 20:24:54 +0100 Subject: [PATCH] cleanup - move some methods to ResizeItem subclass - allow distributor to instanciate sizer and resizeitem it needs through static factory methods, instead of passing in another ctor a distributor can only function with the right item and sizer anyways. - use consistent import/export style - remove obsolete code --- src/components/views/rooms/RoomList.js | 2 +- src/resizer/distributors.js | 43 ++++++---- src/resizer/index.js | 8 +- src/resizer/item.js | 27 ++++--- src/resizer/resizer.js | 30 ++----- src/resizer/room.js | 108 +++++++++---------------- src/resizer/sizer.js | 9 +-- 7 files changed, 94 insertions(+), 133 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 636000c175..79b608ac95 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -167,7 +167,7 @@ module.exports = React.createClass({ const cfg = { onResized: this._onSubListResize, }; - this.resizer = new Resizer(this.resizeContainer, RoomDistributor, cfg, RoomSizer); + this.resizer = new Resizer(this.resizeContainer, RoomDistributor, cfg); this.resizer.setClassNames({ handle: "mx_ResizeHandle", vertical: "mx_ResizeHandle_vertical", diff --git a/src/resizer/distributors.js b/src/resizer/distributors.js index f19b864a09..d273f2782b 100644 --- a/src/resizer/distributors.js +++ b/src/resizer/distributors.js @@ -14,6 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ +import ResizeItem from "./item"; +import Sizer from "./sizer"; + /** distributors translate a moving cursor into CSS/DOM changes by calling the sizer @@ -26,7 +29,15 @@ they have two methods: the offset from the container edge of where the mouse cursor is. */ -class FixedDistributor { +export class FixedDistributor { + static createItem(resizeHandle, resizer, sizer) { + return new ResizeItem(resizeHandle, resizer, sizer); + } + + static createSizer(containerElement, vertical, reverse) { + return new Sizer(containerElement, vertical, reverse); + } + constructor(item) { this.item = item; this.beforeOffset = item.offset(); @@ -45,12 +56,23 @@ class FixedDistributor { finish() {} } +class CollapseItem extends ResizeItem { + notifyCollapsed(collapsed) { + const callback = this.resizer.config.onCollapsed; + if (callback) { + callback(collapsed, this.id, this.domNode); + } + } +} -class CollapseDistributor extends FixedDistributor { - constructor(item, sizer, _container, config) { +export class CollapseDistributor extends FixedDistributor { + static createItem(resizeHandle, resizer, sizer) { + return new CollapseItem(resizeHandle, resizer, sizer); + } + + constructor(item, config) { super(item); this.toggleSize = config && config.toggleSize; - this.onCollapsed = config && config.onCollapsed; this.isCollapsed = false; } @@ -58,13 +80,9 @@ class CollapseDistributor extends FixedDistributor { const isCollapsedSize = newSize < this.toggleSize; if (isCollapsedSize && !this.isCollapsed) { this.isCollapsed = true; - if (this.onCollapsed) { - this.onCollapsed(true, this.item); - } + this.item.notifyCollapsed(true); } else if (!isCollapsedSize && this.isCollapsed) { - if (this.onCollapsed) { - this.onCollapsed(false, this.item); - } + this.item.notifyCollapsed(false); this.isCollapsed = false; } if (!isCollapsedSize) { @@ -72,8 +90,3 @@ class CollapseDistributor extends FixedDistributor { } } } - -module.exports = { - FixedDistributor, - CollapseDistributor, -}; diff --git a/src/resizer/index.js b/src/resizer/index.js index 0720fa36ce..364d077037 100644 --- a/src/resizer/index.js +++ b/src/resizer/index.js @@ -14,17 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {Sizer, FlexSizer} from "./sizer"; import {FixedDistributor, CollapseDistributor} from "./distributors"; -import {Resizer} from "./resizer"; -import {RoomSizer, RoomDistributor} from "./room"; +import Resizer from "./resizer"; +import RoomDistributor from "./room"; module.exports = { Resizer, - Sizer, - FlexSizer, FixedDistributor, CollapseDistributor, - RoomSizer, RoomDistributor, }; diff --git a/src/resizer/item.js b/src/resizer/item.js index ac47e3aea6..6192c6eebb 100644 --- a/src/resizer/item.js +++ b/src/resizer/item.js @@ -15,7 +15,11 @@ limitations under the License. */ export default class ResizeItem { - constructor(domNode, id, reverse, resizer, sizer) { + constructor(handle, resizer, sizer) { + const id = handle.getAttribute("data-id"); + const reverse = resizer.isReverseResizeHandle(handle); + const domNode = reverse ? handle.nextElementSibling : handle.previousElementSibling; + this.domNode = domNode; this.id = id; this.reverse = reverse; @@ -23,11 +27,9 @@ export default class ResizeItem { this.sizer = sizer; } - static fromResizeHandle(handle, resizer, sizer) { - const id = handle.getAttribute("data-id"); - const reverse = resizer.isReverseResizeHandle(handle); - const domNode = reverse ? handle.nextElementSibling : handle.previousElementSibling; - return new ResizeItem(domNode, id, reverse, resizer, sizer); + _copyWith(handle, resizer, sizer) { + const Ctor = this.constructor; + return new Ctor(handle, resizer, sizer); } _advance(forwards) { @@ -43,9 +45,10 @@ export default class ResizeItem { } else { handle = handle.previousElementSibling; } - } while(handle && !this.resizer.isResizeHandle(handle)); + } while (handle && !this.resizer.isResizeHandle(handle)); + if (handle) { - const nextHandle = ResizeItem.fromResizeHandle(handle, this.resizer, this.sizer); + const nextHandle = this._copyWith(handle, this.resizer, this.sizer); nextHandle.reverse = this.reverse; return nextHandle; } @@ -69,7 +72,7 @@ export default class ResizeItem { setSize(size) { this.sizer.setItemSize(this.domNode, size); - const callback = this.resizer.distributorCfg.onResized; + const callback = this.resizer.config.onResized; if (callback) { callback(size, this.id, this.domNode); } @@ -77,7 +80,7 @@ export default class ResizeItem { clearSize() { this.sizer.clearItemSize(this.domNode); - const callback = this.resizer.distributorCfg.onResized; + const callback = this.resizer.config.onResized; if (callback) { callback(null, this.id, this.domNode); } @@ -89,7 +92,7 @@ export default class ResizeItem { return this.resizer.isResizeHandle(el); }); if (firstHandle) { - return ResizeItem.fromResizeHandle(firstHandle, this.resizer, this.sizer); + return this._copyWith(firstHandle, this.resizer, this.sizer); } } @@ -98,7 +101,7 @@ export default class ResizeItem { return this.resizer.isResizeHandle(el); }); if (lastHandle) { - return ResizeItem.fromResizeHandle(lastHandle, this.resizer, this.sizer); + return this._copyWith(lastHandle, this.resizer, this.sizer); } } } diff --git a/src/resizer/resizer.js b/src/resizer/resizer.js index 5d63073da9..4d999652a6 100644 --- a/src/resizer/resizer.js +++ b/src/resizer/resizer.js @@ -14,9 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {Sizer} from "./sizer"; -import ResizeItem from "./item"; - /* classNames: // class on resize-handle @@ -30,14 +27,13 @@ classNames: */ -export class Resizer { +export default class Resizer { // TODO move vertical/horizontal to config option/container class // as it doesn't make sense to mix them within one container/Resizer - constructor(container, distributorCtor, distributorCfg, sizerCtor = Sizer) { + constructor(container, distributorCtor, config) { this.container = container; this.distributorCtor = distributorCtor; - this.distributorCfg = distributorCfg; - this.sizerCtor = sizerCtor; + this.config = config; this.classNames = { handle: "resizer-handle", reverse: "resizer-reverse", @@ -132,25 +128,13 @@ export class Resizer { _createSizerAndDistributor(resizeHandle) { const vertical = resizeHandle.classList.contains(this.classNames.vertical); const reverse = this.isReverseResizeHandle(resizeHandle); - // eslint-disable-next-line new-cap - const sizer = new this.sizerCtor(this.container, vertical, reverse); - const item = ResizeItem.fromResizeHandle(resizeHandle, this, sizer); - // eslint-disable-next-line new-cap - const distributor = new this.distributorCtor( - item, - sizer, - this.container, - this.distributorCfg - ); + const Distributor = this.distributorCtor; + const sizer = Distributor.createSizer(this.container, vertical, reverse); + const item = Distributor.createItem(resizeHandle, this, sizer); + const distributor = new Distributor(item, this.config); return {sizer, distributor}; } - _getResizableItems(reverse) { - return this._getResizeHandles().map((handle) => { - return ResizeItem.fromResizeHandle(handle); - }); - } - _getResizeHandles() { return Array.from(this.container.children).filter(el => { return this.isResizeHandle(el); diff --git a/src/resizer/room.js b/src/resizer/room.js index 6b2951a605..e8c57b0450 100644 --- a/src/resizer/room.js +++ b/src/resizer/room.js @@ -14,16 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {Sizer} from "./sizer"; +import Sizer from "./sizer"; +import ResizeItem from "./item"; class RoomSizer extends Sizer { setItemSize(item, size) { item.style.maxHeight = `${Math.round(size)}px`; item.classList.add("resized-sized"); - // const total = this.getTotalSize(); - // const percent = size / total; - // const growFactor = Math.round(1 + (percent * 100)); - // item.style.flexGrow = `${growFactor}`; } clearItemSize(item) { @@ -32,38 +29,36 @@ class RoomSizer extends Sizer { } } -/* -class RoomSubList extends ResizeItem { - collapsed() { - - } - - id() { - +class RoomSubListItem extends ResizeItem { + isCollapsed() { + return this.domNode.classList.contains("mx_RoomSubList_hidden"); } maxSize() { - + const scrollItem = this.domNode.querySelector(".mx_RoomSubList_scroll"); + const header = this.domNode.querySelector(".mx_RoomSubList_labelContainer"); + const headerHeight = this.sizer.getItemSize(header); + return headerHeight + scrollItem.scrollHeight; } minSize() { + return 74; //size of header + 1 room tile + } + isSized() { + return this.domNode.classList.contains("resized-sized"); } } -*/ -const MIN_SIZE = 74; -// would be good to have a way in here to know if the item can be resized -// - collapsed items can't be resized (.mx_RoomSubList_hidden) -// - items at MIN_SIZE can't be resized smaller -// - items at maxContentHeight can't be resized larger +export default class RoomDistributor { + static createItem(resizeHandle, resizer, sizer) { + return new RoomSubListItem(resizeHandle, resizer, sizer); + } + + static createSizer(containerElement, vertical, reverse) { + return new RoomSizer(containerElement, vertical, reverse); + } -// if you shrink the predecesor, and start dragging down again afterwards, which item has to grow? -/* - either items before (starting from first or last) - or -*/ -class RoomDistributor { constructor(item) { this.item = item; } @@ -72,57 +67,40 @@ class RoomDistributor { return 1; } - _isCollapsed(item) { - return item.domNode.classList.contains("mx_RoomSubList_hidden"); - } - - _contentSize(item) { - const scrollItem = item.domNode.querySelector(".mx_RoomSubList_scroll"); - const header = item.domNode.querySelector(".mx_RoomSubList_labelContainer"); - const headerHeight = item.sizer.getItemSize(header); - return headerHeight + scrollItem.scrollHeight; - } - - _isSized(item) { - return item.domNode.classList.contains("resized-sized"); - } - resize(size) { - console.log("*** starting resize session with size", size); + //console.log("*** starting resize session with size", size); let item = this.item; while (item) { - if (this._isCollapsed(item)) { + const minSize = item.minSize(); + if (item.isCollapsed()) { item = item.previous(); - } - else if (size <= MIN_SIZE) { - console.log(" - resizing", item.id, "to min size", MIN_SIZE); - item.setSize(MIN_SIZE); - const remainder = MIN_SIZE - size; + } else if (size <= minSize) { + //console.log(" - resizing", item.id, "to min size", minSize); + item.setSize(minSize); + const remainder = minSize - size; item = item.previous(); if (item) { size = item.size() - remainder - this._handleSize(); } - } - else { - const contentSize = this._contentSize(item); - if (size > contentSize) { - // console.log(" - resizing", item.id, "to contentSize", contentSize); - item.setSize(contentSize); - const remainder = size - contentSize; + } else { + const maxSize = item.maxSize(); + if (size > maxSize) { + // console.log(" - resizing", item.id, "to maxSize", maxSize); + item.setSize(maxSize); + const remainder = size - maxSize; item = item.previous(); if (item) { size = item.size() + remainder; // todo: handle size here? } - } - else { - console.log(" - resizing", item.id, "to size", size); + } else { + //console.log(" - resizing", item.id, "to size", size); item.setSize(size); item = null; size = 0; } } } - console.log("*** ending resize session"); + //console.log("*** ending resize session"); } resizeFromContainerOffset(containerOffset) { @@ -130,10 +108,10 @@ class RoomDistributor { } start() { - console.log("RoomDistributor::start: setting all items to their actual size in pixels"); + // set all max-height props to the actual height. let item = this.item.first(); - while(item) { - if (!this._isCollapsed(item)) { + while (item) { + if (!item.isCollapsed() && item.isSized()) { item.setSize(item.size()); } item = item.next(); @@ -141,11 +119,5 @@ class RoomDistributor { } finish() { - } } - -module.exports = { - RoomSizer, - RoomDistributor, -}; diff --git a/src/resizer/sizer.js b/src/resizer/sizer.js index cdb11f3270..50861d34d5 100644 --- a/src/resizer/sizer.js +++ b/src/resizer/sizer.js @@ -18,7 +18,7 @@ limitations under the License. implements DOM/CSS operations for resizing. The sizer determines what CSS mechanism is used for sizing items, like flexbox, ... */ -export class Sizer { +export default class Sizer { constructor(container, vertical, reverse) { this.container = container; this.reverse = reverse; @@ -86,10 +86,3 @@ export class Sizer { } } } - -export class FlexSizer extends Sizer { - setItemSize(item, size) { - item.style.flexGrow = `0`; - item.style.flexBasis = `${Math.round(size)}px`; - } -}