turn resizer into class to make programmatic interaction/cleanup easier

pull/21833/head
Bruno Windels 2018-10-16 15:16:10 +02:00
parent c095e30ae4
commit 30003d8f91
4 changed files with 102 additions and 79 deletions

View File

@ -35,7 +35,7 @@ import RoomListStore from "../../stores/RoomListStore";
import TagOrderActions from '../../actions/TagOrderActions';
import RoomListActions from '../../actions/RoomListActions';
import ResizeHandle from '../views/elements/ResizeHandle';
import {makeResizeable, CollapseDistributor} from '../../resizer'
import {Resizer, CollapseDistributor} from '../../resizer'
// We need to fetch each pinned message individually (if we don't already have it)
// so each pinned message may trigger a request. Limit the number per room for sanity.
// NB. this is just for server notices rather than pinned messages in general.
@ -98,17 +98,18 @@ const LoggedInView = React.createClass({
vertical: "mx_ResizeHandle_vertical",
reverse: "mx_ResizeHandle_reverse"
};
const config = {
const collapseConfig = {
toggleSize: 260 - 50,
onCollapsed: (collapsed) => {
this.setState({collapseLhs: collapsed});
}
};
makeResizeable(
const resizer = new Resizer(
this.resizeContainer,
classNames,
CollapseDistributor,
config);
collapseConfig);
resizer.setClassNames(classNames);
resizer.attach();
},
componentWillMount: function() {

View File

@ -1,72 +0,0 @@
import {Sizer} from "./sizer";
/*
classNames:
// class on resize-handle
handle: string
// class on resize-handle
reverse: string
// class on resize-handle
vertical: string
// class on container
resizing: string
*/
function makeResizeable(container, classNames, distributorCtor, distributorCfg = undefined, sizerCtor = Sizer) {
function isResizeHandle(el) {
return el && el.classList.contains(classNames.handle);
}
function handleMouseDown(event) {
const target = event.target;
if (!isResizeHandle(target) || target.parentElement !== container) {
return;
}
// prevent starting a drag operation
event.preventDefault();
// mark as currently resizing
if (classNames.resizing) {
container.classList.add(classNames.resizing);
}
const resizeHandle = event.target;
const vertical = resizeHandle.classList.contains(classNames.vertical);
const reverse = resizeHandle.classList.contains(classNames.reverse);
const direction = reverse ? 0 : -1;
const sizer = new sizerCtor(container, vertical, reverse);
const items = Array.from(container.children).filter(el => {
return !isResizeHandle(el) && (
isResizeHandle(el.previousElementSibling) ||
isResizeHandle(el.nextElementSibling));
});
const prevItem = resizeHandle.previousElementSibling;
const handleIndex = items.indexOf(prevItem) + 1;
const distributor = new distributorCtor(
container, items, handleIndex,
direction, sizer, distributorCfg);
const onMouseMove = (event) => {
const offset = sizer.offsetFromEvent(event);
distributor.resize(offset);
};
const body = document.body;
const onMouseUp = (event) => {
if (classNames.resizing) {
container.classList.remove(classNames.resizing);
}
const offset = sizer.offsetFromEvent(event);
distributor.finish(offset);
body.removeEventListener("mouseup", onMouseUp, false);
body.removeEventListener("mousemove", onMouseMove, false);
};
body.addEventListener("mouseup", onMouseUp, false);
body.addEventListener("mousemove", onMouseMove, false);
}
container.addEventListener("mousedown", handleMouseDown, false);
}
module.exports = {makeResizeable};

View File

@ -1,9 +1,9 @@
import {Sizer} from "./sizer";
import {FixedDistributor, CollapseDistributor, PercentageDistributor} from "./distributors";
import {makeResizeable} from "./event";
import {Resizer} from "./resizer";
module.exports = {
makeResizeable,
Resizer,
Sizer,
FixedDistributor,
CollapseDistributor,

94
src/resizer/resizer.js Normal file
View File

@ -0,0 +1,94 @@
import {Sizer} from "./sizer";
/*
classNames:
// class on resize-handle
handle: string
// class on resize-handle
reverse: string
// class on resize-handle
vertical: string
// class on container
resizing: string
*/
export class Resizer {
constructor(container, distributorCtor, distributorCfg, sizerCtor = Sizer) {
this.container = container;
this.distributorCtor = distributorCtor;
this.distributorCfg = distributorCfg;
this.sizerCtor = sizerCtor;
this.classNames = {
handle: "resizer-handle",
reverse: "resizer-reverse",
vertical: "resizer-vertical",
resizing: "resizer-resizing",
};
this.mouseDownHandler = (event) => this._onMouseDown(event);
}
setClassNames(classNames) {
this.classNames = classNames;
}
attach() {
this.container.addEventListener("mousedown", this.mouseDownHandler, false);
}
detach() {
this.container.removeEventListener("mousedown", this.mouseDownHandler, false);
}
_isResizeHandle(el) {
return el && el.classList.contains(this.classNames.handle);
}
_onMouseDown(event) {
const target = event.target;
if (!this._isResizeHandle(target) || target.parentElement !== this.container) {
return;
}
// prevent starting a drag operation
event.preventDefault();
// mark as currently resizing
if (this.classNames.resizing) {
this.container.classList.add(this.classNames.resizing);
}
const resizeHandle = event.target;
const vertical = resizeHandle.classList.contains(this.classNames.vertical);
const reverse = resizeHandle.classList.contains(this.classNames.reverse);
const direction = reverse ? 0 : -1;
const sizer = new this.sizerCtor(this.container, vertical, reverse);
const items = Array.from(this.container.children).filter(el => {
return !this._isResizeHandle(el) && (
this._isResizeHandle(el.previousElementSibling) ||
this._isResizeHandle(el.nextElementSibling));
});
const prevItem = resizeHandle.previousElementSibling;
const handleIndex = items.indexOf(prevItem) + 1;
const distributor = new this.distributorCtor(
this.container, items, handleIndex,
direction, sizer, this.distributorCfg);
const onMouseMove = (event) => {
const offset = sizer.offsetFromEvent(event);
distributor.resize(offset);
};
const body = document.body;
const onMouseUp = (event) => {
if (this.classNames.resizing) {
this.container.classList.remove(this.classNames.resizing);
}
const offset = sizer.offsetFromEvent(event);
distributor.finish(offset);
body.removeEventListener("mouseup", onMouseUp, false);
body.removeEventListener("mousemove", onMouseMove, false);
};
body.addEventListener("mouseup", onMouseUp, false);
body.addEventListener("mousemove", onMouseMove, false);
}
}