@@ -316,19 +316,6 @@ class DuckWidget {
316
316
break
317
317
}
318
318
319
- // If hidden, restore the tracking element's styles to make
320
- // it visible again.
321
- if ( this . originalElementStyle ) {
322
- for ( const key of [ 'display' , 'visibility' ] ) {
323
- const { value, priority } = this . originalElementStyle [ key ]
324
- if ( value ) {
325
- fbElement . style . setProperty ( key , value , priority )
326
- } else {
327
- fbElement . style . removeProperty ( key )
328
- }
329
- }
330
- }
331
-
332
319
/*
333
320
* Modify the overlay to include a Facebook iFrame, which
334
321
* starts invisible. Once loaded, fade out and remove the overlay
@@ -367,33 +354,11 @@ class DuckWidget {
367
354
}
368
355
}
369
356
370
- function replaceTrackingElement ( widget , trackingElement , placeholderElement , hideTrackingElement = false , currentPlaceholder = null ) {
357
+ function replaceTrackingElement ( widget , trackingElement , placeholderElement , currentPlaceholder = null ) {
371
358
widget . dispatchEvent ( trackingElement , 'ddg-ctp-tracking-element' )
372
359
373
- // Usually the tracking element can simply be replaced with the
374
- // placeholder, but in some situations that isn't possible and the
375
- // tracking element must be hidden instead.
376
- if ( hideTrackingElement ) {
377
- // Don't save original element styles if we've already done it
378
- if ( ! widget . originalElementStyle ) {
379
- // Take care to note existing styles so that they can be restored.
380
- widget . originalElementStyle = getOriginalElementStyle ( trackingElement , widget )
381
- }
382
- // Hide the tracking element and add the placeholder next to it in
383
- // the DOM.
384
- trackingElement . style . setProperty ( 'display' , 'none' , 'important' )
385
- trackingElement . style . setProperty ( 'visibility' , 'hidden' , 'important' )
386
- trackingElement . parentElement . insertBefore ( placeholderElement , trackingElement )
387
- if ( currentPlaceholder ) {
388
- currentPlaceholder . remove ( )
389
- }
390
- } else {
391
- if ( currentPlaceholder ) {
392
- currentPlaceholder . replaceWith ( placeholderElement )
393
- } else {
394
- trackingElement . replaceWith ( placeholderElement )
395
- }
396
- }
360
+ const elementToReplace = currentPlaceholder || trackingElement
361
+ elementToReplace . replaceWith ( placeholderElement )
397
362
398
363
widget . dispatchEvent ( placeholderElement , 'ddg-ctp-placeholder-element' )
399
364
}
@@ -486,14 +451,12 @@ async function replaceYouTubeCTL (trackingElement, widget, togglePlaceholder = f
486
451
}
487
452
488
453
// Show YouTube Preview for embedded video
489
- // TODO: Fix the hideTrackingElement option and reenable, or remove it. It's
490
- // disabled for YouTube videos so far since it caused multiple
491
- // placeholders to be displayed on the page.
492
454
if ( isYoutubePreviewsEnabled === true ) {
493
455
const { youTubePreview, shadowRoot } = await createYouTubePreview ( trackingElement , widget )
494
456
const currentPlaceholder = togglePlaceholder ? document . getElementById ( `yt-ctl-dialog-${ widget . widgetID } ` ) : null
457
+ resizeElementToMatch ( currentPlaceholder || trackingElement , youTubePreview )
495
458
replaceTrackingElement (
496
- widget , trackingElement , youTubePreview , /* hideTrackingElement= */ false , currentPlaceholder
459
+ widget , trackingElement , youTubePreview , currentPlaceholder
497
460
)
498
461
showExtraUnblockIfShortPlaceholder ( shadowRoot , youTubePreview )
499
462
@@ -502,8 +465,9 @@ async function replaceYouTubeCTL (trackingElement, widget, togglePlaceholder = f
502
465
widget . autoplay = false
503
466
const { blockingDialog, shadowRoot } = await createYouTubeBlockingDialog ( trackingElement , widget )
504
467
const currentPlaceholder = togglePlaceholder ? document . getElementById ( `yt-ctl-preview-${ widget . widgetID } ` ) : null
468
+ resizeElementToMatch ( currentPlaceholder || trackingElement , blockingDialog )
505
469
replaceTrackingElement (
506
- widget , trackingElement , blockingDialog , /* hideTrackingElement= */ false , currentPlaceholder
470
+ widget , trackingElement , blockingDialog , currentPlaceholder
507
471
)
508
472
showExtraUnblockIfShortPlaceholder ( shadowRoot , blockingDialog )
509
473
}
@@ -632,44 +596,30 @@ function getLearnMoreLink (mode) {
632
596
}
633
597
634
598
/**
635
- * Reads and stores a set of styles from the original tracking element, and then returns it.
636
- * @param {Element } originalElement Original tracking element (ie iframe)
637
- * @param {DuckWidget } widget The widget Object.
638
- * @returns {{[key: string]: string[]} } Object with styles read from original element.
599
+ * Resizes and positions the target element to match the source element.
600
+ * @param {Element } sourceElement
601
+ * @param {Element } targetElement
639
602
*/
640
- function getOriginalElementStyle ( originalElement , widget ) {
641
- if ( widget . originalElementStyle ) {
642
- return widget . originalElementStyle
603
+ function resizeElementToMatch ( sourceElement , targetElement ) {
604
+ const computedStyle = window . getComputedStyle ( sourceElement )
605
+ const stylesToCopy = [ 'position' , 'top' , 'bottom' , 'left' , 'right' ,
606
+ 'transform' , 'margin' , 'height' , 'width' ]
607
+
608
+ // It's apparently preferable to use the source element's size relative to
609
+ // the current viewport, when resizing the target element. However, the
610
+ // declarativeNetRequest API "collapses" (hides) blocked elements. When
611
+ // that happens, getBoundingClientRect will return all zeros.
612
+ // TODO: Remove this entirely, and always use the computed height/width of
613
+ // the source element instead?
614
+ const { height, width } = sourceElement . getBoundingClientRect ( )
615
+ if ( height > 0 && width > 0 ) {
616
+ computedStyle . height = height + 'px'
617
+ computedStyle . width = width + 'px'
643
618
}
644
619
645
- const stylesToCopy = [ 'display' , 'visibility' , 'position' , 'top' , 'bottom' , 'left' , 'right' ,
646
- 'transform' , 'margin' ]
647
- widget . originalElementStyle = { }
648
- const allOriginalElementStyles = getComputedStyle ( originalElement )
649
620
for ( const key of stylesToCopy ) {
650
- widget . originalElementStyle [ key ] = {
651
- value : allOriginalElementStyles [ key ] ,
652
- priority : originalElement . style . getPropertyPriority ( key )
653
- }
621
+ targetElement . style [ key ] = computedStyle [ key ]
654
622
}
655
-
656
- // Copy current size of the element
657
- const { height : heightViewValue , width : widthViewValue } = originalElement . getBoundingClientRect ( )
658
- widget . originalElementStyle . height = { value : `${ heightViewValue } px` , priority : '' }
659
- widget . originalElementStyle . width = { value : `${ widthViewValue } px` , priority : '' }
660
-
661
- return widget . originalElementStyle
662
- }
663
-
664
- /**
665
- * Copy list of styles to provided element
666
- * @param {{[key: string]: string[]} } originalStyles Object with styles read from original element.
667
- * @param {Element } element Node element to have the styles copied to
668
- */
669
- function copyStylesTo ( originalStyles , element ) {
670
- const { display, visibility, ...filteredStyles } = originalStyles
671
- const cssText = Object . keys ( filteredStyles ) . reduce ( ( cssAcc , key ) => ( cssAcc + `${ key } : ${ filteredStyles [ key ] . value } ;` ) , '' )
672
- element . style . cssText += cssText
673
623
}
674
624
675
625
/**
@@ -1152,11 +1102,6 @@ async function createYouTubeBlockingDialog (trackingElement, widget) {
1152
1102
button . addEventListener ( 'click' , widget . clickFunction ( trackingElement , contentBlock ) )
1153
1103
textButton . addEventListener ( 'click' , widget . clickFunction ( trackingElement , contentBlock ) )
1154
1104
1155
- // Size the placeholder element to match the original video element styles.
1156
- // If no styles are in place, it will get its current size
1157
- const originalStyles = getOriginalElementStyle ( trackingElement , widget )
1158
- copyStylesTo ( originalStyles , contentBlock )
1159
-
1160
1105
return {
1161
1106
blockingDialog : contentBlock ,
1162
1107
shadowRoot
@@ -1181,11 +1126,6 @@ async function createYouTubePreview (originalElement, widget) {
1181
1126
1182
1127
youTubePreview . appendChild ( makeFontFaceStyleElement ( ) )
1183
1128
1184
- // Size the placeholder element to match the original video element styles.
1185
- // If no styles are in place, it will get its current size
1186
- const originalStyles = getOriginalElementStyle ( originalElement , widget )
1187
- copyStylesTo ( originalStyles , youTubePreview )
1188
-
1189
1129
// Protect the contents of our placeholder inside a shadowRoot, to avoid
1190
1130
// it being styled by the website's stylesheets.
1191
1131
const shadowRoot = youTubePreview . attachShadow ( { mode : devMode ? 'open' : 'closed' } )
0 commit comments