Skip to content

Commit 6d9e854

Browse files
committed
Remove unused (and broken) hideTrackingElement Click to Load code path
The hideTrackingElement code path was originally intended for use with YouTube Click to Load placeholders. The thinking was to keep the original YouTube video elements on the page, in case the website referenced the original element when creating a video. Unfortunately that didn't work out, since keeping the original element on the page caused problems such as duplicate placeholders being displayed. We already stopped using that code path, let's tidy things up and remove it. While we're at it, let's fix the element resizing for Chrome MV3 builds. It turns out that when the declarativeNetRequest API blocks an element, the element is automatically "collapsed" (hidden). When this happens, getBoundingClientRect() considers the element to have a width and height of 0. Fall back to getComputedStyle when that happens.
1 parent 71695fd commit 6d9e854

File tree

1 file changed

+26
-86
lines changed

1 file changed

+26
-86
lines changed

src/features/click-to-load.js

Lines changed: 26 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -316,19 +316,6 @@ class DuckWidget {
316316
break
317317
}
318318

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-
332319
/*
333320
* Modify the overlay to include a Facebook iFrame, which
334321
* starts invisible. Once loaded, fade out and remove the overlay
@@ -367,33 +354,11 @@ class DuckWidget {
367354
}
368355
}
369356

370-
function replaceTrackingElement (widget, trackingElement, placeholderElement, hideTrackingElement = false, currentPlaceholder = null) {
357+
function replaceTrackingElement (widget, trackingElement, placeholderElement, currentPlaceholder = null) {
371358
widget.dispatchEvent(trackingElement, 'ddg-ctp-tracking-element')
372359

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)
397362

398363
widget.dispatchEvent(placeholderElement, 'ddg-ctp-placeholder-element')
399364
}
@@ -486,14 +451,12 @@ async function replaceYouTubeCTL (trackingElement, widget, togglePlaceholder = f
486451
}
487452

488453
// 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.
492454
if (isYoutubePreviewsEnabled === true) {
493455
const { youTubePreview, shadowRoot } = await createYouTubePreview(trackingElement, widget)
494456
const currentPlaceholder = togglePlaceholder ? document.getElementById(`yt-ctl-dialog-${widget.widgetID}`) : null
457+
resizeElementToMatch(currentPlaceholder || trackingElement, youTubePreview)
495458
replaceTrackingElement(
496-
widget, trackingElement, youTubePreview, /* hideTrackingElement= */ false, currentPlaceholder
459+
widget, trackingElement, youTubePreview, currentPlaceholder
497460
)
498461
showExtraUnblockIfShortPlaceholder(shadowRoot, youTubePreview)
499462

@@ -502,8 +465,9 @@ async function replaceYouTubeCTL (trackingElement, widget, togglePlaceholder = f
502465
widget.autoplay = false
503466
const { blockingDialog, shadowRoot } = await createYouTubeBlockingDialog(trackingElement, widget)
504467
const currentPlaceholder = togglePlaceholder ? document.getElementById(`yt-ctl-preview-${widget.widgetID}`) : null
468+
resizeElementToMatch(currentPlaceholder || trackingElement, blockingDialog)
505469
replaceTrackingElement(
506-
widget, trackingElement, blockingDialog, /* hideTrackingElement= */ false, currentPlaceholder
470+
widget, trackingElement, blockingDialog, currentPlaceholder
507471
)
508472
showExtraUnblockIfShortPlaceholder(shadowRoot, blockingDialog)
509473
}
@@ -632,44 +596,30 @@ function getLearnMoreLink (mode) {
632596
}
633597

634598
/**
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
639602
*/
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'
643618
}
644619

645-
const stylesToCopy = ['display', 'visibility', 'position', 'top', 'bottom', 'left', 'right',
646-
'transform', 'margin']
647-
widget.originalElementStyle = {}
648-
const allOriginalElementStyles = getComputedStyle(originalElement)
649620
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]
654622
}
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
673623
}
674624

675625
/**
@@ -1152,11 +1102,6 @@ async function createYouTubeBlockingDialog (trackingElement, widget) {
11521102
button.addEventListener('click', widget.clickFunction(trackingElement, contentBlock))
11531103
textButton.addEventListener('click', widget.clickFunction(trackingElement, contentBlock))
11541104

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-
11601105
return {
11611106
blockingDialog: contentBlock,
11621107
shadowRoot
@@ -1181,11 +1126,6 @@ async function createYouTubePreview (originalElement, widget) {
11811126

11821127
youTubePreview.appendChild(makeFontFaceStyleElement())
11831128

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-
11891129
// Protect the contents of our placeholder inside a shadowRoot, to avoid
11901130
// it being styled by the website's stylesheets.
11911131
const shadowRoot = youTubePreview.attachShadow({ mode: devMode ? 'open' : 'closed' })

0 commit comments

Comments
 (0)