Skip to content

Commit 5433953

Browse files
author
Shane Osbourne
committed
fix(duck-player): hotfix: capture the correct url before a click occurs
1 parent 561cb93 commit 5433953

File tree

3 files changed

+60
-23
lines changed

3 files changed

+60
-23
lines changed

src/features/duckplayer/overlays.js

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ export async function initOverlays (environment, comms) {
245245
const OpenInDuckPlayer = {
246246
clickBoundElements: new Map(),
247247
enabled: false,
248-
248+
/** @type {string|null} */
249+
lastMouseOver: null,
249250
bindEventsToAll: () => {
250251
if (!OpenInDuckPlayer.enabled) {
251252
return
@@ -256,38 +257,69 @@ export async function initOverlays (environment, comms) {
256257
return VideoThumbnail.isSingleVideoURL(element?.getAttribute('href')) ||
257258
element.getAttribute('id') === 'media-container-link'
258259
}
259-
const excludeAlreadyBound = (element) => !OpenInDuckPlayer.clickBoundElements.has(element)
260-
261260
videoLinksAndPreview
262-
.filter(excludeAlreadyBound)
263-
.forEach(element => {
264-
if (isValidVideoLinkOrPreview(element)) {
265-
const onClickOpenDuckPlayer = (event) => {
266-
event.preventDefault()
267-
event.stopPropagation()
268-
269-
const link = event.target.closest('a')
270-
271-
if (link) {
272-
const href = VideoParams.fromHref(link.href)?.toPrivatePlayerUrl()
261+
.forEach((/** @type {HTMLElement|HTMLAnchorElement} */element) => {
262+
// bail when this element was already seen
263+
if (OpenInDuckPlayer.clickBoundElements.has(element)) return
264+
265+
// bail if it's not a valid element
266+
if (!isValidVideoLinkOrPreview(element)) return
267+
268+
// handle mouseover + click events
269+
const handler = {
270+
handleEvent (event) {
271+
switch (event.type) {
272+
case 'mouseover': {
273+
/**
274+
* Store the element's link value on hover - this occurs just in time
275+
* before the youtube overlay take sover the event space
276+
*/
277+
const href = element instanceof HTMLAnchorElement
278+
? VideoParams.fromHref(element.href)?.toPrivatePlayerUrl()
279+
: null
273280
if (href) {
274-
comms.openInDuckPlayerViaMessage({ href })
281+
OpenInDuckPlayer.lastMouseOver = href
275282
}
283+
break
276284
}
285+
case 'click': {
286+
/**
287+
* On click, the receiver might be the preview element - if
288+
* it is, we want to use the last hovered `a` tag instead
289+
*/
290+
event.preventDefault()
291+
event.stopPropagation()
292+
293+
const link = event.target.closest('a')
294+
const fromClosest = VideoParams.fromHref(link?.href)?.toPrivatePlayerUrl()
295+
296+
if (fromClosest) {
297+
comms.openInDuckPlayerViaMessage({ href: fromClosest })
298+
} else if (OpenInDuckPlayer.lastMouseOver) {
299+
comms.openInDuckPlayerViaMessage({ href: OpenInDuckPlayer.lastMouseOver })
300+
} else {
301+
// could not navigate, doing nothing
302+
}
277303

278-
return false
304+
break
305+
}
306+
}
279307
}
308+
}
280309

281-
element.addEventListener('click', onClickOpenDuckPlayer, true)
310+
// register both handlers
311+
element.addEventListener('mouseover', handler, true)
312+
element.addEventListener('click', handler, true)
282313

283-
OpenInDuckPlayer.clickBoundElements.set(element, onClickOpenDuckPlayer)
284-
}
314+
// store the handler for removal later (eg: if settings change)
315+
OpenInDuckPlayer.clickBoundElements.set(element, handler)
285316
})
286317
},
287318

288319
disable: () => {
289-
OpenInDuckPlayer.clickBoundElements.forEach((functionToRemove, element) => {
290-
element.removeEventListener('click', functionToRemove, true)
320+
OpenInDuckPlayer.clickBoundElements.forEach((handler, element) => {
321+
element.removeEventListener('mouseover', handler, true)
322+
element.removeEventListener('click', handler, true)
291323
OpenInDuckPlayer.clickBoundElements.delete(element)
292324
})
293325

src/features/duckplayer/util.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,13 @@ export class VideoParams {
215215
* @returns {VideoParams|null}
216216
*/
217217
static fromHref (href) {
218-
const url = new URL(href)
218+
let url
219+
try {
220+
url = new URL(href)
221+
} catch (e) {
222+
return null
223+
}
224+
219225
const vParam = url.searchParams.get('v')
220226
const tParam = url.searchParams.get('t')
221227

src/trackers.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
/**
32
* Check if the current document origin is on the tracker list, using the provided lookup trie.
43
* @param {object} trackerLookup Trie lookup of tracker domains

0 commit comments

Comments
 (0)