Redesign of the scrolling zones (#634)

* update table

* Fix mouse button

* scrollZones

* build

* zones resize
This commit is contained in:
horoyami 2019-03-02 00:34:08 +03:00 committed by GitHub
parent 1e5e77925f
commit 19d228db17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 96 deletions

10
dist/editor.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,7 @@
# Changelog
### 2.11.5
- `Fix` *RectangeSelection* — Redesign of the scrolling zones
### 2.11.4

View file

@ -1,6 +1,6 @@
{
"name": "@editorjs/editorjs",
"version": "2.11.4",
"version": "2.11.5",
"description": "Editor.js — Native JS, based on API and Open Source",
"main": "dist/editor.js",
"types": "./types/index.d.ts",
@ -61,8 +61,8 @@
"postcss-nested": "^3.0.0",
"postcss-nested-ancestors": "^2.0.0",
"postcss-nesting": "^6.0.0",
"postcss-preset-env": "^6.5.0",
"postcss-smart-import": "^0.7.6",
"postcss-preset-env": "^6.5.0",
"raw-loader": "^0.5.1",
"rimraf": "^2.6.2",
"stylelint": "^9.3.0",

View file

@ -110,8 +110,8 @@ export default class BlockSelection extends Module {
const {BlockManager} = this.Editor;
/**
* When one page consist of two or more EditorJS instances
* Shortcut module tries to handle all events. Thats why Editor's selection works inside the target Editor, but for
* others error occurs because nothing to select.
* Shortcut module tries to handle all events. Thats why Editor's selection works inside the target Editor, but
* for others error occurs because nothing to select.
*
* Prevent such actions if focus is not inside the Editor
*/

View file

@ -11,6 +11,7 @@ import $ from '../dom';
import SelectionUtils from '../selection';
import Block from '../block';
import UI from './ui';
import Timeout = NodeJS.Timeout;
export default class RectangleSelection extends Module {
/**
@ -41,7 +42,7 @@ export default class RectangleSelection extends Module {
/**
* Height of scroll zone on boundary of screen
*/
private readonly HEIGHT_OF_SCROLL_ZONE = 25;
private readonly HEIGHT_OF_SCROLL_ZONE = 40;
/**
* Scroll zone type indicators
@ -59,6 +60,11 @@ export default class RectangleSelection extends Module {
*/
private mousedown: boolean = false;
/**
* Is scrolling now
*/
private isScrolling: boolean = false;
/**
* Mouse is in scroll zone
*/
@ -87,48 +93,27 @@ export default class RectangleSelection extends Module {
*/
private overlayRectangle: HTMLDivElement;
/**
* Coords of redactor
*/
private left;
private top;
/**
* Module Preparation
* Creating rect and hang handlers
*/
public prepare(): void {
const {Listeners} = this.Editor;
const {overlayTopScrollZone, overlayBottomScrollZone, container, overlay} = this.genHTML();
Listeners.on(overlayBottomScrollZone, 'mouseenter', (event) => {
this.inScrollZone = this.BOTTOM_SCROLL_ZONE;
this.scrollVertical(this.SCROLL_SPEED);
});
Listeners.on(overlayTopScrollZone, 'mouseenter', (event) => {
this.inScrollZone = this.TOP_SCROLL_ZONE;
this.scrollVertical(-this.SCROLL_SPEED);
});
Listeners.on(overlayBottomScrollZone, 'mouseleave', (event) => {
this.inScrollZone = null;
});
Listeners.on(overlayTopScrollZone, 'mouseleave', (event) => {
this.inScrollZone = null;
});
const {container} = this.genHTML();
Listeners.on(container, 'mousedown', (event: MouseEvent) => {
if (event.button !== this.MAIN_MOUSE_BUTTON) { return; }
if (event.button !== this.MAIN_MOUSE_BUTTON) {
return;
}
this.startSelection(event.pageX, event.pageY);
}, false);
Listeners.on(document.body, 'mousemove', (event) => {
Listeners.on(document.body, 'mousemove', (event: MouseEvent) => {
this.changingRectangle(event);
this.scrollByZones(event.clientY);
}, false);
Listeners.on(document.body, 'mouseleave', (event) => {
Listeners.on(document.body, 'mouseleave', () => {
this.clearSelection();
this.endSelection();
});
@ -137,7 +122,7 @@ export default class RectangleSelection extends Module {
this.changingRectangle(event);
}, false);
Listeners.on(document.body, 'mouseup', (event) => {
Listeners.on(document.body, 'mouseup', () => {
this.endSelection();
}, false);
}
@ -161,7 +146,6 @@ export default class RectangleSelection extends Module {
this.mousedown = true;
this.startX = pageX;
this.startY = pageY;
const container = document.querySelector('.' + UI.CSS.editorWrapper);
}
/**
@ -188,24 +172,42 @@ export default class RectangleSelection extends Module {
this.isRectSelectionActivated = false;
}
/**
* Scroll If mouse in scroll zone
* @param {number} clientY - Y coord of mouse
*/
private scrollByZones(clientY) {
this.inScrollZone = null;
if (clientY <= this.HEIGHT_OF_SCROLL_ZONE) {
this.inScrollZone = this.TOP_SCROLL_ZONE;
}
if (document.documentElement.clientHeight - clientY <= this.HEIGHT_OF_SCROLL_ZONE) {
this.inScrollZone = this.BOTTOM_SCROLL_ZONE;
}
if (!this.inScrollZone) {
this.isScrolling = false;
return;
}
if (!this.isScrolling) {
this.scrollVertical(this.inScrollZone === this.TOP_SCROLL_ZONE ? -this.SCROLL_SPEED : this.SCROLL_SPEED);
this.isScrolling = true;
}
}
private genHTML() {
const container = document.querySelector('.' + UI.CSS.editorWrapper);
const container = this.Editor.UI.nodes.holder.querySelector('.' + UI.CSS.editorWrapper);
const overlay = $.make('div', RectangleSelection.CSS.overlay, {});
const overlayContainer = $.make('div', RectangleSelection.CSS.overlayContainer, {});
const overlayRectangle = $.make('div', RectangleSelection.CSS.rect, {});
const overlayTopScrollZone = $.make('div', RectangleSelection.CSS.topScrollZone, {});
const overlayBottomScrollZone = $.make('div', RectangleSelection.CSS.bottomScrollZone, {});
overlayContainer.appendChild(overlayRectangle);
overlay.appendChild(overlayContainer);
document.body.appendChild(overlayTopScrollZone);
document.body.appendChild(overlayBottomScrollZone);
container.appendChild(overlay);
this.overlayRectangle = overlayRectangle as HTMLDivElement;
return {
overlayBottomScrollZone,
overlayTopScrollZone,
container,
overlay,
};
@ -219,8 +221,9 @@ export default class RectangleSelection extends Module {
if (!(this.inScrollZone && this.mousedown)) {
return;
}
this.mouseY += speed;
const lastOffset = window.pageYOffset;
window.scrollBy(0, speed);
this.mouseY += window.pageYOffset - lastOffset;
setTimeout(() => {
this.scrollVertical(speed);
}, 0);
@ -286,14 +289,14 @@ export default class RectangleSelection extends Module {
const isSelecteMode = firstBlockInStack.selected;
if (this.rectCrossesBlocks && !isSelecteMode) {
for (let i = 0; i < this.stackOfSelected.length; i++) {
this.Editor.BlockSelection.selectBlockByIndex(this.stackOfSelected[i]);
for (const it of this.stackOfSelected) {
this.Editor.BlockSelection.selectBlockByIndex(it);
}
}
if (!this.rectCrossesBlocks && isSelecteMode) {
for (let i = 0; i < this.stackOfSelected.length; i++) {
this.Editor.BlockSelection.unSelectBlockByIndex(this.stackOfSelected[i]);
for (const it of this.stackOfSelected) {
this.Editor.BlockSelection.unSelectBlockByIndex(it);
}
}
}
@ -328,7 +331,7 @@ export default class RectangleSelection extends Module {
private genInfoForMouseSelection() {
const widthOfRedactor = document.body.offsetWidth;
const centerOfRedactor = widthOfRedactor / 2;
const Y = this.getHorizontalMousePosition();
const Y = this.mouseY - window.pageYOffset;
const elementUnderMouse = document.elementFromPoint(centerOfRedactor, Y);
const blockInCurrentPos = this.Editor.BlockManager.getBlockByChildNode(elementUnderMouse);
let index;
@ -347,21 +350,6 @@ export default class RectangleSelection extends Module {
};
}
/**
* Get mouse Y coord with accounting Scroll zone
*/
private getHorizontalMousePosition() {
let value = this.mouseY - window.pageYOffset;
// To look at the item below the zone
if (this.inScrollZone === this.TOP_SCROLL_ZONE) {
value += this.HEIGHT_OF_SCROLL_ZONE;
}
if (this.inScrollZone === this.BOTTOM_SCROLL_ZONE) {
value -= this.HEIGHT_OF_SCROLL_ZONE;
}
return value;
}
/**
* Select block with index index
* @param index - index of block in redactor
@ -394,19 +382,20 @@ export default class RectangleSelection extends Module {
const reduction = !generalSelection;
// When the selection is too fast, some blocks do not have time to be noticed. Fix it.
if (!reduction && (index > this.stackOfSelected[sizeStack - 1] || this.stackOfSelected[sizeStack - 1] === undefined)) {
let i = this.stackOfSelected[sizeStack - 1] + 1 || index;
if (!reduction && (index > this.stackOfSelected[sizeStack - 1] ||
this.stackOfSelected[sizeStack - 1] === undefined)) {
let ind = this.stackOfSelected[sizeStack - 1] + 1 || index;
for (i; i <= index; i++) {
this.addBlockInSelection(i);
for (ind; ind <= index; ind++) {
this.addBlockInSelection(ind);
}
return;
}
// for both directions
if (!reduction && (index < this.stackOfSelected[sizeStack - 1])) {
for (let i = this.stackOfSelected[sizeStack - 1] - 1; i >= index; i--) {
this.addBlockInSelection(i);
for (let ind = this.stackOfSelected[sizeStack - 1] - 1; ind >= index; ind--) {
this.addBlockInSelection(ind);
}
return;
}

View file

@ -85,28 +85,6 @@
background-color: rgba(46, 170, 220, 0.2);
border: 1px solid transparent;
}
&__scroll-zone {
&--top {
top: 0;
width: 100%;
height: 30px;
position: fixed;
pointer-events: auto;
z-index: 10500;
}
&--bottom {
bottom: 0;
width: 100%;
height: 30px;
position: fixed;
pointer-events: auto;
z-index: 10500;
}
}
}
svg {