@@ -14,22 +14,26 @@ declare global {
14
14
width : number
15
15
}
16
16
}
17
+
18
+ // @TODO better declaration of possible shadowdom hosts
19
+ interface Element {
20
+ host : any
21
+ }
17
22
}
18
23
19
24
import { CustomScrollAction , Options } from './types'
20
25
21
- const isElement = el => el != null && typeof el == 'object' && el . nodeType === 1
22
- const hasScrollableSpace = ( el , axis : 'Y' | 'X' ) => {
23
- if ( axis === 'Y' ) {
24
- return el . clientHeight < el . scrollHeight
25
- }
26
+ // @TODO better shadowdom test, 11 = document fragment
27
+ const isElement = el =>
28
+ el != null &&
29
+ typeof el == 'object' &&
30
+ ( el . nodeType === 1 || el . nodeType === 11 )
26
31
27
- if ( axis === 'X' ) {
28
- return el . clientWidth < el . scrollWidth
29
- }
32
+ const hasScrollableSpace = ( el , axis : 'X' | 'Y' ) =>
33
+ axis === 'X'
34
+ ? el . clientWidth < el . scrollWidth
35
+ : el . clientHeight < el . scrollHeight
30
36
31
- return false
32
- }
33
37
const canOverflow = (
34
38
el ,
35
39
axis : 'Y' | 'X' ,
@@ -63,6 +67,8 @@ const alignNearest = (
63
67
scrollingEdgeStart : number ,
64
68
scrollingEdgeEnd : number ,
65
69
scrollingSize : number ,
70
+ scrollingBorderStart : number ,
71
+ scrollingBorderEnd : number ,
66
72
elementEdgeStart : number ,
67
73
elementEdgeEnd : number ,
68
74
elementSize : number
@@ -139,7 +145,7 @@ const alignNearest = (
139
145
( elementEdgeStart < scrollingEdgeStart && elementSize < scrollingSize ) ||
140
146
( elementEdgeEnd > scrollingEdgeEnd && elementSize > scrollingSize )
141
147
) {
142
- return elementEdgeStart - scrollingEdgeStart
148
+ return elementEdgeStart - scrollingEdgeStart - scrollingBorderStart
143
149
}
144
150
145
151
/**
@@ -186,7 +192,7 @@ const alignNearest = (
186
192
( elementEdgeEnd > scrollingEdgeEnd && elementSize < scrollingSize ) ||
187
193
( elementEdgeStart < scrollingEdgeStart && elementSize > scrollingSize )
188
194
) {
189
- return elementEdgeEnd - scrollingEdgeEnd
195
+ return elementEdgeEnd - scrollingEdgeEnd + scrollingBorderEnd
190
196
}
191
197
192
198
return 0
@@ -219,7 +225,11 @@ export default (
219
225
// Collect all the scrolling boxes, as defined in the spec: https://drafts.csswg.org/cssom-view/#scrolling-box
220
226
const frames : Element [ ] = [ ]
221
227
let parent
222
- while ( isElement ( ( parent = target . parentNode ) ) && checkBoundary ( target ) ) {
228
+ // @TODO have a better shadowdom test here
229
+ while (
230
+ isElement ( ( parent = target . parentNode || target . host ) ) &&
231
+ checkBoundary ( target )
232
+ ) {
223
233
if (
224
234
isScrollable ( parent , skipOverflowHiddenElements ) ||
225
235
parent === viewport
@@ -277,12 +287,15 @@ export default (
277
287
// Collect new scroll positions
278
288
const computations = frames . map ( ( frame ) : CustomScrollAction => {
279
289
const frameRect = frame . getBoundingClientRect ( )
280
- // @TODO fix hardcoding of block => top/Y
290
+ const frameStyle = getComputedStyle ( frame )
291
+ const borderLeft = parseInt ( frameStyle . borderLeftWidth as string , 10 )
292
+ const borderTop = parseInt ( frameStyle . borderTopWidth as string , 10 )
293
+ const borderRight = parseInt ( frameStyle . borderRightWidth as string , 10 )
294
+ const borderBottom = parseInt ( frameStyle . borderBottomWidth as string , 10 )
281
295
282
296
let blockScroll = 0
283
297
let inlineScroll = 0
284
298
285
- // @TODO handle borders
286
299
// @TODO fix the if else pyramid nightmare
287
300
288
301
if ( block === 'start' ) {
@@ -297,9 +310,7 @@ export default (
297
310
targetBlock - frameRect . top ,
298
311
frame . scrollHeight - frame . clientHeight - frame . scrollTop
299
312
)
300
- blockScroll = frame . scrollTop + offset
301
-
302
- targetBlock -= blockScroll - frame . scrollTop
313
+ blockScroll = frame . scrollTop + offset - borderTop
303
314
}
304
315
}
305
316
if ( block === 'center' ) {
@@ -318,9 +329,6 @@ export default (
318
329
)
319
330
320
331
blockScroll = frame . scrollTop + offset
321
-
322
- // Cache the offset so that parent frames can scroll this into view correctly
323
- targetBlock += frame . scrollTop - blockScroll
324
332
}
325
333
}
326
334
@@ -335,10 +343,7 @@ export default (
335
343
const offset =
336
344
0 - Math . min ( frameRect . bottom - targetBlock , frame . scrollTop )
337
345
338
- blockScroll = frame . scrollTop + offset
339
-
340
- // Cache the offset so that parent frames can scroll this into view correctly
341
- targetBlock += frame . scrollTop - blockScroll
346
+ blockScroll = frame . scrollTop + offset + borderBottom
342
347
}
343
348
}
344
349
@@ -352,6 +357,8 @@ export default (
352
357
viewportY ,
353
358
viewportY + viewportHeight ,
354
359
viewportHeight ,
360
+ borderTop ,
361
+ borderBottom ,
355
362
viewportY + targetBlock ,
356
363
viewportY + targetBlock + targetRect . height ,
357
364
targetRect . height
@@ -363,14 +370,13 @@ export default (
363
370
frameRect . top ,
364
371
frameRect . bottom ,
365
372
frameRect . height ,
373
+ borderTop ,
374
+ borderBottom ,
366
375
targetBlock ,
367
376
targetBlock + targetRect . height ,
368
377
targetRect . height
369
378
)
370
379
blockScroll = frame . scrollTop + offset
371
-
372
- // Cache the offset so that parent frames can scroll this into view correctly
373
- targetBlock -= offset
374
380
}
375
381
}
376
382
@@ -386,9 +392,7 @@ export default (
386
392
targetInline - frameRect . left ,
387
393
frame . scrollHeight - frame . clientLeft - frame . scrollLeft
388
394
)
389
- inlineScroll = frame . scrollLeft + offset
390
-
391
- targetInline -= inlineScroll - frame . scrollLeft
395
+ inlineScroll = frame . scrollLeft + offset - borderLeft
392
396
}
393
397
}
394
398
@@ -408,9 +412,6 @@ export default (
408
412
)
409
413
410
414
inlineScroll = frame . scrollLeft + offset
411
-
412
- // Cache the offset so that parent frames can scroll this into view correctly
413
- targetInline += frame . scrollLeft - inlineScroll
414
415
}
415
416
}
416
417
@@ -425,10 +426,7 @@ export default (
425
426
const offset =
426
427
0 - Math . min ( frameRect . right - targetInline , frame . scrollLeft )
427
428
428
- inlineScroll = frame . scrollLeft + offset
429
-
430
- // Cache the offset so that parent frames can scroll this into view correctly
431
- targetInline += frame . scrollLeft - inlineScroll
429
+ inlineScroll = frame . scrollLeft + offset + borderRight
432
430
}
433
431
}
434
432
@@ -442,6 +440,8 @@ export default (
442
440
viewportX ,
443
441
viewportX + viewportWidth ,
444
442
viewportWidth ,
443
+ borderLeft ,
444
+ borderRight ,
445
445
viewportX + targetInline ,
446
446
viewportX + targetInline + targetRect . width ,
447
447
targetRect . width
@@ -453,18 +453,21 @@ export default (
453
453
frameRect . left ,
454
454
frameRect . right ,
455
455
frameRect . width ,
456
+ borderLeft ,
457
+ borderRight ,
456
458
targetInline ,
457
459
targetInline + targetRect . width ,
458
460
targetRect . width
459
461
)
460
462
461
463
inlineScroll = frame . scrollLeft + offset
462
-
463
- // Cache the offset so that parent frames can scroll this into view correctly
464
- targetInline -= offset
465
464
}
466
465
}
467
466
467
+ // Cache the offset so that parent frames can scroll this into view correctly
468
+ targetBlock += frame . scrollTop - blockScroll
469
+ targetInline += frame . scrollLeft - inlineScroll
470
+
468
471
return { el : frame , top : blockScroll , left : inlineScroll }
469
472
} )
470
473
0 commit comments