Skip to content

Commit 19d228d

Browse files
authored
Redesign of the scrolling zones (codex-team#634)
* update table * Fix mouse button * scrollZones * build * zones resize
1 parent 1e5e779 commit 19d228d

File tree

6 files changed

+66
-96
lines changed

6 files changed

+66
-96
lines changed

dist/editor.js

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Changelog
2+
### 2.11.5
3+
4+
- `Fix` *RectangeSelection* — Redesign of the scrolling zones
25

36
### 2.11.4
47

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@editorjs/editorjs",
3-
"version": "2.11.4",
3+
"version": "2.11.5",
44
"description": "Editor.js — Native JS, based on API and Open Source",
55
"main": "dist/editor.js",
66
"types": "./types/index.d.ts",
@@ -61,8 +61,8 @@
6161
"postcss-nested": "^3.0.0",
6262
"postcss-nested-ancestors": "^2.0.0",
6363
"postcss-nesting": "^6.0.0",
64-
"postcss-preset-env": "^6.5.0",
6564
"postcss-smart-import": "^0.7.6",
65+
"postcss-preset-env": "^6.5.0",
6666
"raw-loader": "^0.5.1",
6767
"rimraf": "^2.6.2",
6868
"stylelint": "^9.3.0",

src/components/modules/blockSelection.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ export default class BlockSelection extends Module {
110110
const {BlockManager} = this.Editor;
111111
/**
112112
* When one page consist of two or more EditorJS instances
113-
* Shortcut module tries to handle all events. Thats why Editor's selection works inside the target Editor, but for
114-
* others error occurs because nothing to select.
113+
* Shortcut module tries to handle all events. Thats why Editor's selection works inside the target Editor, but
114+
* for others error occurs because nothing to select.
115115
*
116116
* Prevent such actions if focus is not inside the Editor
117117
*/

src/components/modules/rectangleSelection.ts

Lines changed: 54 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import $ from '../dom';
1111
import SelectionUtils from '../selection';
1212
import Block from '../block';
1313
import UI from './ui';
14+
import Timeout = NodeJS.Timeout;
1415

1516
export default class RectangleSelection extends Module {
1617
/**
@@ -41,7 +42,7 @@ export default class RectangleSelection extends Module {
4142
/**
4243
* Height of scroll zone on boundary of screen
4344
*/
44-
private readonly HEIGHT_OF_SCROLL_ZONE = 25;
45+
private readonly HEIGHT_OF_SCROLL_ZONE = 40;
4546

4647
/**
4748
* Scroll zone type indicators
@@ -59,6 +60,11 @@ export default class RectangleSelection extends Module {
5960
*/
6061
private mousedown: boolean = false;
6162

63+
/**
64+
* Is scrolling now
65+
*/
66+
private isScrolling: boolean = false;
67+
6268
/**
6369
* Mouse is in scroll zone
6470
*/
@@ -87,48 +93,27 @@ export default class RectangleSelection extends Module {
8793
*/
8894
private overlayRectangle: HTMLDivElement;
8995

90-
/**
91-
* Coords of redactor
92-
*/
93-
private left;
94-
private top;
95-
9696
/**
9797
* Module Preparation
9898
* Creating rect and hang handlers
9999
*/
100100
public prepare(): void {
101101
const {Listeners} = this.Editor;
102-
const {overlayTopScrollZone, overlayBottomScrollZone, container, overlay} = this.genHTML();
103-
104-
Listeners.on(overlayBottomScrollZone, 'mouseenter', (event) => {
105-
this.inScrollZone = this.BOTTOM_SCROLL_ZONE;
106-
this.scrollVertical(this.SCROLL_SPEED);
107-
});
108-
109-
Listeners.on(overlayTopScrollZone, 'mouseenter', (event) => {
110-
this.inScrollZone = this.TOP_SCROLL_ZONE;
111-
this.scrollVertical(-this.SCROLL_SPEED);
112-
});
113-
114-
Listeners.on(overlayBottomScrollZone, 'mouseleave', (event) => {
115-
this.inScrollZone = null;
116-
});
117-
118-
Listeners.on(overlayTopScrollZone, 'mouseleave', (event) => {
119-
this.inScrollZone = null;
120-
});
102+
const {container} = this.genHTML();
121103

122104
Listeners.on(container, 'mousedown', (event: MouseEvent) => {
123-
if (event.button !== this.MAIN_MOUSE_BUTTON) { return; }
105+
if (event.button !== this.MAIN_MOUSE_BUTTON) {
106+
return;
107+
}
124108
this.startSelection(event.pageX, event.pageY);
125109
}, false);
126110

127-
Listeners.on(document.body, 'mousemove', (event) => {
111+
Listeners.on(document.body, 'mousemove', (event: MouseEvent) => {
128112
this.changingRectangle(event);
113+
this.scrollByZones(event.clientY);
129114
}, false);
130115

131-
Listeners.on(document.body, 'mouseleave', (event) => {
116+
Listeners.on(document.body, 'mouseleave', () => {
132117
this.clearSelection();
133118
this.endSelection();
134119
});
@@ -137,7 +122,7 @@ export default class RectangleSelection extends Module {
137122
this.changingRectangle(event);
138123
}, false);
139124

140-
Listeners.on(document.body, 'mouseup', (event) => {
125+
Listeners.on(document.body, 'mouseup', () => {
141126
this.endSelection();
142127
}, false);
143128
}
@@ -161,7 +146,6 @@ export default class RectangleSelection extends Module {
161146
this.mousedown = true;
162147
this.startX = pageX;
163148
this.startY = pageY;
164-
const container = document.querySelector('.' + UI.CSS.editorWrapper);
165149
}
166150

167151
/**
@@ -188,24 +172,42 @@ export default class RectangleSelection extends Module {
188172
this.isRectSelectionActivated = false;
189173
}
190174

175+
/**
176+
* Scroll If mouse in scroll zone
177+
* @param {number} clientY - Y coord of mouse
178+
*/
179+
private scrollByZones(clientY) {
180+
this.inScrollZone = null;
181+
if (clientY <= this.HEIGHT_OF_SCROLL_ZONE) {
182+
this.inScrollZone = this.TOP_SCROLL_ZONE;
183+
}
184+
if (document.documentElement.clientHeight - clientY <= this.HEIGHT_OF_SCROLL_ZONE) {
185+
this.inScrollZone = this.BOTTOM_SCROLL_ZONE;
186+
}
187+
188+
if (!this.inScrollZone) {
189+
this.isScrolling = false;
190+
return;
191+
}
192+
193+
if (!this.isScrolling) {
194+
this.scrollVertical(this.inScrollZone === this.TOP_SCROLL_ZONE ? -this.SCROLL_SPEED : this.SCROLL_SPEED);
195+
this.isScrolling = true;
196+
}
197+
}
198+
191199
private genHTML() {
192-
const container = document.querySelector('.' + UI.CSS.editorWrapper);
200+
const container = this.Editor.UI.nodes.holder.querySelector('.' + UI.CSS.editorWrapper);
193201
const overlay = $.make('div', RectangleSelection.CSS.overlay, {});
194202
const overlayContainer = $.make('div', RectangleSelection.CSS.overlayContainer, {});
195203
const overlayRectangle = $.make('div', RectangleSelection.CSS.rect, {});
196-
const overlayTopScrollZone = $.make('div', RectangleSelection.CSS.topScrollZone, {});
197-
const overlayBottomScrollZone = $.make('div', RectangleSelection.CSS.bottomScrollZone, {});
198204

199205
overlayContainer.appendChild(overlayRectangle);
200206
overlay.appendChild(overlayContainer);
201-
document.body.appendChild(overlayTopScrollZone);
202-
document.body.appendChild(overlayBottomScrollZone);
203207
container.appendChild(overlay);
204208

205209
this.overlayRectangle = overlayRectangle as HTMLDivElement;
206210
return {
207-
overlayBottomScrollZone,
208-
overlayTopScrollZone,
209211
container,
210212
overlay,
211213
};
@@ -219,8 +221,9 @@ export default class RectangleSelection extends Module {
219221
if (!(this.inScrollZone && this.mousedown)) {
220222
return;
221223
}
222-
this.mouseY += speed;
224+
const lastOffset = window.pageYOffset;
223225
window.scrollBy(0, speed);
226+
this.mouseY += window.pageYOffset - lastOffset;
224227
setTimeout(() => {
225228
this.scrollVertical(speed);
226229
}, 0);
@@ -286,14 +289,14 @@ export default class RectangleSelection extends Module {
286289
const isSelecteMode = firstBlockInStack.selected;
287290

288291
if (this.rectCrossesBlocks && !isSelecteMode) {
289-
for (let i = 0; i < this.stackOfSelected.length; i++) {
290-
this.Editor.BlockSelection.selectBlockByIndex(this.stackOfSelected[i]);
292+
for (const it of this.stackOfSelected) {
293+
this.Editor.BlockSelection.selectBlockByIndex(it);
291294
}
292295
}
293296

294297
if (!this.rectCrossesBlocks && isSelecteMode) {
295-
for (let i = 0; i < this.stackOfSelected.length; i++) {
296-
this.Editor.BlockSelection.unSelectBlockByIndex(this.stackOfSelected[i]);
298+
for (const it of this.stackOfSelected) {
299+
this.Editor.BlockSelection.unSelectBlockByIndex(it);
297300
}
298301
}
299302
}
@@ -328,7 +331,7 @@ export default class RectangleSelection extends Module {
328331
private genInfoForMouseSelection() {
329332
const widthOfRedactor = document.body.offsetWidth;
330333
const centerOfRedactor = widthOfRedactor / 2;
331-
const Y = this.getHorizontalMousePosition();
334+
const Y = this.mouseY - window.pageYOffset;
332335
const elementUnderMouse = document.elementFromPoint(centerOfRedactor, Y);
333336
const blockInCurrentPos = this.Editor.BlockManager.getBlockByChildNode(elementUnderMouse);
334337
let index;
@@ -347,21 +350,6 @@ export default class RectangleSelection extends Module {
347350
};
348351
}
349352

350-
/**
351-
* Get mouse Y coord with accounting Scroll zone
352-
*/
353-
private getHorizontalMousePosition() {
354-
let value = this.mouseY - window.pageYOffset;
355-
// To look at the item below the zone
356-
if (this.inScrollZone === this.TOP_SCROLL_ZONE) {
357-
value += this.HEIGHT_OF_SCROLL_ZONE;
358-
}
359-
if (this.inScrollZone === this.BOTTOM_SCROLL_ZONE) {
360-
value -= this.HEIGHT_OF_SCROLL_ZONE;
361-
}
362-
return value;
363-
}
364-
365353
/**
366354
* Select block with index index
367355
* @param index - index of block in redactor
@@ -394,19 +382,20 @@ export default class RectangleSelection extends Module {
394382
const reduction = !generalSelection;
395383

396384
// When the selection is too fast, some blocks do not have time to be noticed. Fix it.
397-
if (!reduction && (index > this.stackOfSelected[sizeStack - 1] || this.stackOfSelected[sizeStack - 1] === undefined)) {
398-
let i = this.stackOfSelected[sizeStack - 1] + 1 || index;
385+
if (!reduction && (index > this.stackOfSelected[sizeStack - 1] ||
386+
this.stackOfSelected[sizeStack - 1] === undefined)) {
387+
let ind = this.stackOfSelected[sizeStack - 1] + 1 || index;
399388

400-
for (i; i <= index; i++) {
401-
this.addBlockInSelection(i);
389+
for (ind; ind <= index; ind++) {
390+
this.addBlockInSelection(ind);
402391
}
403392
return;
404393
}
405394

406395
// for both directions
407396
if (!reduction && (index < this.stackOfSelected[sizeStack - 1])) {
408-
for (let i = this.stackOfSelected[sizeStack - 1] - 1; i >= index; i--) {
409-
this.addBlockInSelection(i);
397+
for (let ind = this.stackOfSelected[sizeStack - 1] - 1; ind >= index; ind--) {
398+
this.addBlockInSelection(ind);
410399
}
411400
return;
412401
}

src/styles/ui.css

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -85,28 +85,6 @@
8585
background-color: rgba(46, 170, 220, 0.2);
8686
border: 1px solid transparent;
8787
}
88-
89-
&__scroll-zone {
90-
91-
92-
&--top {
93-
top: 0;
94-
width: 100%;
95-
height: 30px;
96-
position: fixed;
97-
pointer-events: auto;
98-
z-index: 10500;
99-
}
100-
101-
&--bottom {
102-
bottom: 0;
103-
width: 100%;
104-
height: 30px;
105-
position: fixed;
106-
pointer-events: auto;
107-
z-index: 10500;
108-
}
109-
}
11088
}
11189

11290
svg {

0 commit comments

Comments
 (0)