- 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
This commit is contained in:
Bruno Windels 2019-01-14 20:24:54 +01:00
parent 961e0d24df
commit 9ecb23ce71
7 changed files with 94 additions and 133 deletions

View file

@ -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",

View file

@ -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,
};

View file

@ -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,
};

View file

@ -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);
}
}
}

View file

@ -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);

View file

@ -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,
};

View file

@ -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`;
}
}