@@ -11,6 +11,7 @@ import $ from '../dom';
11
11
import SelectionUtils from '../selection' ;
12
12
import Block from '../block' ;
13
13
import UI from './ui' ;
14
+ import Timeout = NodeJS . Timeout ;
14
15
15
16
export default class RectangleSelection extends Module {
16
17
/**
@@ -41,7 +42,7 @@ export default class RectangleSelection extends Module {
41
42
/**
42
43
* Height of scroll zone on boundary of screen
43
44
*/
44
- private readonly HEIGHT_OF_SCROLL_ZONE = 25 ;
45
+ private readonly HEIGHT_OF_SCROLL_ZONE = 40 ;
45
46
46
47
/**
47
48
* Scroll zone type indicators
@@ -59,6 +60,11 @@ export default class RectangleSelection extends Module {
59
60
*/
60
61
private mousedown : boolean = false ;
61
62
63
+ /**
64
+ * Is scrolling now
65
+ */
66
+ private isScrolling : boolean = false ;
67
+
62
68
/**
63
69
* Mouse is in scroll zone
64
70
*/
@@ -87,48 +93,27 @@ export default class RectangleSelection extends Module {
87
93
*/
88
94
private overlayRectangle : HTMLDivElement ;
89
95
90
- /**
91
- * Coords of redactor
92
- */
93
- private left ;
94
- private top ;
95
-
96
96
/**
97
97
* Module Preparation
98
98
* Creating rect and hang handlers
99
99
*/
100
100
public prepare ( ) : void {
101
101
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 ( ) ;
121
103
122
104
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
+ }
124
108
this . startSelection ( event . pageX , event . pageY ) ;
125
109
} , false ) ;
126
110
127
- Listeners . on ( document . body , 'mousemove' , ( event ) => {
111
+ Listeners . on ( document . body , 'mousemove' , ( event : MouseEvent ) => {
128
112
this . changingRectangle ( event ) ;
113
+ this . scrollByZones ( event . clientY ) ;
129
114
} , false ) ;
130
115
131
- Listeners . on ( document . body , 'mouseleave' , ( event ) => {
116
+ Listeners . on ( document . body , 'mouseleave' , ( ) => {
132
117
this . clearSelection ( ) ;
133
118
this . endSelection ( ) ;
134
119
} ) ;
@@ -137,7 +122,7 @@ export default class RectangleSelection extends Module {
137
122
this . changingRectangle ( event ) ;
138
123
} , false ) ;
139
124
140
- Listeners . on ( document . body , 'mouseup' , ( event ) => {
125
+ Listeners . on ( document . body , 'mouseup' , ( ) => {
141
126
this . endSelection ( ) ;
142
127
} , false ) ;
143
128
}
@@ -161,7 +146,6 @@ export default class RectangleSelection extends Module {
161
146
this . mousedown = true ;
162
147
this . startX = pageX ;
163
148
this . startY = pageY ;
164
- const container = document . querySelector ( '.' + UI . CSS . editorWrapper ) ;
165
149
}
166
150
167
151
/**
@@ -188,24 +172,42 @@ export default class RectangleSelection extends Module {
188
172
this . isRectSelectionActivated = false ;
189
173
}
190
174
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
+
191
199
private genHTML ( ) {
192
- const container = document . querySelector ( '.' + UI . CSS . editorWrapper ) ;
200
+ const container = this . Editor . UI . nodes . holder . querySelector ( '.' + UI . CSS . editorWrapper ) ;
193
201
const overlay = $ . make ( 'div' , RectangleSelection . CSS . overlay , { } ) ;
194
202
const overlayContainer = $ . make ( 'div' , RectangleSelection . CSS . overlayContainer , { } ) ;
195
203
const overlayRectangle = $ . make ( 'div' , RectangleSelection . CSS . rect , { } ) ;
196
- const overlayTopScrollZone = $ . make ( 'div' , RectangleSelection . CSS . topScrollZone , { } ) ;
197
- const overlayBottomScrollZone = $ . make ( 'div' , RectangleSelection . CSS . bottomScrollZone , { } ) ;
198
204
199
205
overlayContainer . appendChild ( overlayRectangle ) ;
200
206
overlay . appendChild ( overlayContainer ) ;
201
- document . body . appendChild ( overlayTopScrollZone ) ;
202
- document . body . appendChild ( overlayBottomScrollZone ) ;
203
207
container . appendChild ( overlay ) ;
204
208
205
209
this . overlayRectangle = overlayRectangle as HTMLDivElement ;
206
210
return {
207
- overlayBottomScrollZone,
208
- overlayTopScrollZone,
209
211
container,
210
212
overlay,
211
213
} ;
@@ -219,8 +221,9 @@ export default class RectangleSelection extends Module {
219
221
if ( ! ( this . inScrollZone && this . mousedown ) ) {
220
222
return ;
221
223
}
222
- this . mouseY += speed ;
224
+ const lastOffset = window . pageYOffset ;
223
225
window . scrollBy ( 0 , speed ) ;
226
+ this . mouseY += window . pageYOffset - lastOffset ;
224
227
setTimeout ( ( ) => {
225
228
this . scrollVertical ( speed ) ;
226
229
} , 0 ) ;
@@ -286,14 +289,14 @@ export default class RectangleSelection extends Module {
286
289
const isSelecteMode = firstBlockInStack . selected ;
287
290
288
291
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 ) ;
291
294
}
292
295
}
293
296
294
297
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 ) ;
297
300
}
298
301
}
299
302
}
@@ -328,7 +331,7 @@ export default class RectangleSelection extends Module {
328
331
private genInfoForMouseSelection ( ) {
329
332
const widthOfRedactor = document . body . offsetWidth ;
330
333
const centerOfRedactor = widthOfRedactor / 2 ;
331
- const Y = this . getHorizontalMousePosition ( ) ;
334
+ const Y = this . mouseY - window . pageYOffset ;
332
335
const elementUnderMouse = document . elementFromPoint ( centerOfRedactor , Y ) ;
333
336
const blockInCurrentPos = this . Editor . BlockManager . getBlockByChildNode ( elementUnderMouse ) ;
334
337
let index ;
@@ -347,21 +350,6 @@ export default class RectangleSelection extends Module {
347
350
} ;
348
351
}
349
352
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
-
365
353
/**
366
354
* Select block with index index
367
355
* @param index - index of block in redactor
@@ -394,19 +382,20 @@ export default class RectangleSelection extends Module {
394
382
const reduction = ! generalSelection ;
395
383
396
384
// 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 ;
399
388
400
- for ( i ; i <= index ; i ++ ) {
401
- this . addBlockInSelection ( i ) ;
389
+ for ( ind ; ind <= index ; ind ++ ) {
390
+ this . addBlockInSelection ( ind ) ;
402
391
}
403
392
return ;
404
393
}
405
394
406
395
// for both directions
407
396
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 ) ;
410
399
}
411
400
return ;
412
401
}
0 commit comments