@@ -49,10 +49,14 @@ interface CustomScrollAction {
49
49
}
50
50
51
51
// @TODO better shadowdom test, 11 = document fragment
52
- function isElement ( el : any ) {
52
+ function isElement ( el : any ) : el is Element {
53
53
return el != null && typeof el === 'object' && el . nodeType === 1
54
54
}
55
55
56
+ function isDocument ( el : any ) : el is Document {
57
+ return el != null && typeof el === 'object' && el . nodeType === 9
58
+ }
59
+
56
60
function canOverflow (
57
61
overflow : string | null ,
58
62
skipOverflowHiddenElements ?: boolean
@@ -236,6 +240,33 @@ function alignNearest(
236
240
return 0
237
241
}
238
242
243
+ /**
244
+ * Get rect considering iframe
245
+ */
246
+ function getRect ( target : Element ) {
247
+ const clientRect = target . getBoundingClientRect ( )
248
+ const rect = {
249
+ height : clientRect . height ,
250
+ width : clientRect . width ,
251
+ top : clientRect . top ,
252
+ left : clientRect . left ,
253
+ bottom : clientRect . bottom ,
254
+ right : clientRect . right ,
255
+ }
256
+ const doc = target . ownerDocument
257
+ let childWindow = doc ?. defaultView
258
+
259
+ while ( childWindow && window . top !== childWindow ) {
260
+ rect . top += childWindow . frameElement . getBoundingClientRect ( ) . top
261
+ rect . left += childWindow . frameElement . getBoundingClientRect ( ) . left
262
+ rect . bottom += childWindow . frameElement . getBoundingClientRect ( ) . top
263
+ rect . right += childWindow . frameElement . getBoundingClientRect ( ) . left
264
+ childWindow = childWindow . parent
265
+ }
266
+
267
+ return rect
268
+ }
269
+
239
270
export default ( target : Element , options : Options ) : CustomScrollAction [ ] => {
240
271
const {
241
272
scrollMode,
@@ -260,9 +291,14 @@ export default (target: Element, options: Options): CustomScrollAction[] => {
260
291
// Collect all the scrolling boxes, as defined in the spec: https://drafts.csswg.org/cssom-view/#scrolling-box
261
292
const frames : Element [ ] = [ ]
262
293
let cursor = target
263
- while ( isElement ( cursor ) && checkBoundary ( cursor ) ) {
264
- // Move cursor to parent
265
- cursor = cursor . parentNode as Element
294
+ while ( ( isElement ( cursor ) || isDocument ( cursor ) ) && checkBoundary ( cursor ) ) {
295
+ if ( isDocument ( cursor ) ) {
296
+ const document = cursor
297
+ cursor = document . defaultView ?. frameElement as Element
298
+ } else {
299
+ // Move cursor to parent
300
+ cursor = cursor . parentNode as Element
301
+ }
266
302
267
303
// Stop when we reach the viewport
268
304
if ( cursor === scrollingElement ) {
@@ -308,7 +344,7 @@ export default (target: Element, options: Options): CustomScrollAction[] => {
308
344
right : targetRight ,
309
345
bottom : targetBottom ,
310
346
left : targetLeft ,
311
- } = target . getBoundingClientRect ( )
347
+ } = getRect ( target )
312
348
313
349
// These values mutate as we loop through and generate scroll coordinates
314
350
let targetBlock : number =
0 commit comments