Skip to content

Commit 1b55488

Browse files
shakyShanegithub-actions[bot]
authored andcommitted
Release build 4.22.1 [ci release]
1 parent 658da08 commit 1b55488

File tree

92 files changed

+664
-324
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+664
-324
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ node_modules/
44
.env
55
build/
66
docs/
7+
test-results/
8+
playwright-report/
79
Sources/ContentScopeScripts/dist/

Sources/ContentScopeScripts/dist/contentScopeIsolated.js

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3249,6 +3249,11 @@
32493249
/** @type {import("./video-player-icon").VideoPlayerIcon | null} */
32503250
videoPlayerIcon = null
32513251

3252+
selectors = {
3253+
videoElement: '#player video',
3254+
container: '#player .html5-video-player'
3255+
}
3256+
32523257
/**
32533258
* @param {import("../duck-player.js").UserValues} userValues
32543259
* @param {import("./overlays.js").Environment} environment
@@ -3310,26 +3315,11 @@
33103315
});
33113316
}
33123317

3313-
/**
3314-
* Set up the overlay
3315-
* @param {import("../duck-player.js").UserValues} userValues
3316-
* @param {import("./util").VideoParams} params
3317-
*/
3318-
addLargeOverlay (userValues, params) {
3319-
const playerVideo = document.querySelector('#player video');
3320-
const containerElement = document.querySelector('#player .html5-video-player');
3321-
3322-
if (playerVideo && containerElement) {
3323-
this.stopVideoFromPlaying(playerVideo);
3324-
this.appendOverlayToPage(containerElement, params);
3325-
}
3326-
}
3327-
33283318
/**
33293319
* @param {import("./util").VideoParams} params
33303320
*/
33313321
addSmallDaxOverlay (params) {
3332-
const containerElement = document.querySelector('#player .html5-video-player');
3322+
const containerElement = document.querySelector(this.selectors.container);
33333323
if (!containerElement) {
33343324
console.error('no container element');
33353325
return
@@ -3366,9 +3356,12 @@
33663356
];
33673357

33683358
if (conditions.some(Boolean)) {
3369-
const playerElement = document.querySelector('#player');
3370-
3371-
if (!playerElement) {
3359+
/**
3360+
* Don't continue until we've been able to find the HTML elements that we inject into
3361+
*/
3362+
const videoElement = document.querySelector(this.selectors.videoElement);
3363+
const playerContainer = document.querySelector(this.selectors.container);
3364+
if (!videoElement || !playerContainer) {
33723365
return null
33733366
}
33743367

@@ -3392,7 +3385,8 @@
33923385
if ('alwaysAsk' in userValues.privatePlayerMode) {
33933386
if (!userValues.overlayInteracted) {
33943387
if (!this.environment.hasOneTimeOverride()) {
3395-
this.addLargeOverlay(userValues, params);
3388+
this.stopVideoFromPlaying();
3389+
this.appendOverlayToPage(playerContainer, params);
33963390
}
33973391
} else {
33983392
this.addSmallDaxOverlay(params);
@@ -3426,15 +3420,16 @@
34263420
/**
34273421
* Just brute-force calling video.pause() for as long as the user is seeing the overlay.
34283422
*/
3429-
stopVideoFromPlaying (videoElement) {
3430-
this.sideEffect('pausing the <video> element', () => {
3423+
stopVideoFromPlaying () {
3424+
this.sideEffect(`pausing the <video> element with selector '${this.selectors.videoElement}'`, () => {
34313425
/**
34323426
* Set up the interval - keep calling .pause() to prevent
34333427
* the video from playing
34343428
*/
34353429
const int = setInterval(() => {
3436-
if (videoElement instanceof HTMLVideoElement && videoElement.isConnected) {
3437-
videoElement.pause();
3430+
const video = /** @type {HTMLVideoElement} */(document.querySelector(this.selectors.videoElement));
3431+
if (video?.isConnected) {
3432+
video.pause();
34383433
}
34393434
}, 10);
34403435

@@ -3445,13 +3440,9 @@
34453440
return () => {
34463441
clearInterval(int);
34473442

3448-
if (videoElement?.isConnected) {
3449-
videoElement.play();
3450-
} else {
3451-
const video = document.querySelector('#player video');
3452-
if (video instanceof HTMLVideoElement) {
3453-
video.play();
3454-
}
3443+
const video = /** @type {HTMLVideoElement} */(document.querySelector(this.selectors.videoElement));
3444+
if (video?.isConnected) {
3445+
video.play();
34553446
}
34563447
}
34573448
});

build/android/contentScope.js

Lines changed: 5 additions & 2 deletions
Large diffs are not rendered by default.

build/chrome-mv3/inject.js

Lines changed: 5 additions & 2 deletions
Large diffs are not rendered by default.

build/chrome/inject.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/contentScope.js

Lines changed: 27 additions & 33 deletions
Large diffs are not rendered by default.

build/firefox/inject.js

Lines changed: 5 additions & 2 deletions
Large diffs are not rendered by default.

build/integration/contentScope.js

Lines changed: 27 additions & 33 deletions
Large diffs are not rendered by default.

build/locales/ctl-locales.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/windows/contentScope.js

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8422,6 +8422,11 @@
84228422
/** @type {import("./video-player-icon").VideoPlayerIcon | null} */
84238423
videoPlayerIcon = null
84248424

8425+
selectors = {
8426+
videoElement: '#player video',
8427+
container: '#player .html5-video-player'
8428+
}
8429+
84258430
/**
84268431
* @param {import("../duck-player.js").UserValues} userValues
84278432
* @param {import("./overlays.js").Environment} environment
@@ -8483,26 +8488,11 @@
84838488
});
84848489
}
84858490

8486-
/**
8487-
* Set up the overlay
8488-
* @param {import("../duck-player.js").UserValues} userValues
8489-
* @param {import("./util").VideoParams} params
8490-
*/
8491-
addLargeOverlay (userValues, params) {
8492-
const playerVideo = document.querySelector('#player video');
8493-
const containerElement = document.querySelector('#player .html5-video-player');
8494-
8495-
if (playerVideo && containerElement) {
8496-
this.stopVideoFromPlaying(playerVideo);
8497-
this.appendOverlayToPage(containerElement, params);
8498-
}
8499-
}
8500-
85018491
/**
85028492
* @param {import("./util").VideoParams} params
85038493
*/
85048494
addSmallDaxOverlay (params) {
8505-
const containerElement = document.querySelector('#player .html5-video-player');
8495+
const containerElement = document.querySelector(this.selectors.container);
85068496
if (!containerElement) {
85078497
console.error('no container element');
85088498
return
@@ -8539,9 +8529,12 @@
85398529
];
85408530

85418531
if (conditions.some(Boolean)) {
8542-
const playerElement = document.querySelector('#player');
8543-
8544-
if (!playerElement) {
8532+
/**
8533+
* Don't continue until we've been able to find the HTML elements that we inject into
8534+
*/
8535+
const videoElement = document.querySelector(this.selectors.videoElement);
8536+
const playerContainer = document.querySelector(this.selectors.container);
8537+
if (!videoElement || !playerContainer) {
85458538
return null
85468539
}
85478540

@@ -8565,7 +8558,8 @@
85658558
if ('alwaysAsk' in userValues.privatePlayerMode) {
85668559
if (!userValues.overlayInteracted) {
85678560
if (!this.environment.hasOneTimeOverride()) {
8568-
this.addLargeOverlay(userValues, params);
8561+
this.stopVideoFromPlaying();
8562+
this.appendOverlayToPage(playerContainer, params);
85698563
}
85708564
} else {
85718565
this.addSmallDaxOverlay(params);
@@ -8599,15 +8593,16 @@
85998593
/**
86008594
* Just brute-force calling video.pause() for as long as the user is seeing the overlay.
86018595
*/
8602-
stopVideoFromPlaying (videoElement) {
8603-
this.sideEffect('pausing the <video> element', () => {
8596+
stopVideoFromPlaying () {
8597+
this.sideEffect(`pausing the <video> element with selector '${this.selectors.videoElement}'`, () => {
86048598
/**
86058599
* Set up the interval - keep calling .pause() to prevent
86068600
* the video from playing
86078601
*/
86088602
const int = setInterval(() => {
8609-
if (videoElement instanceof HTMLVideoElement && videoElement.isConnected) {
8610-
videoElement.pause();
8603+
const video = /** @type {HTMLVideoElement} */(document.querySelector(this.selectors.videoElement));
8604+
if (video?.isConnected) {
8605+
video.pause();
86118606
}
86128607
}, 10);
86138608

@@ -8618,13 +8613,9 @@
86188613
return () => {
86198614
clearInterval(int);
86208615

8621-
if (videoElement?.isConnected) {
8622-
videoElement.play();
8623-
} else {
8624-
const video = document.querySelector('#player video');
8625-
if (video instanceof HTMLVideoElement) {
8626-
video.play();
8627-
}
8616+
const video = /** @type {HTMLVideoElement} */(document.querySelector(this.selectors.videoElement));
8617+
if (video?.isConnected) {
8618+
video.play();
86288619
}
86298620
}
86308621
});

integration-test/playwright/duckplayer.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,19 @@ test.describe('Duck Player Overlays on Video Player in YouTube.com', () => {
108108
// Then then the overlay shows and blocks the video from playing
109109
await overlays.overlayBlocksVideo()
110110
})
111+
test('Overlay blocks video from playing (supporting DOM appearing over time)', async ({ page }, workerInfo) => {
112+
const overlays = DuckplayerOverlays.create(page, workerInfo)
113+
114+
// Given overlays feature is enabled
115+
await overlays.overlaysEnabled()
116+
117+
// And my setting is 'always ask'
118+
await overlays.userSettingIs('always ask')
119+
await overlays.gotoPlayerPage({ variant: 'incremental-dom' })
120+
121+
// Then then the overlay shows and blocks the video from playing
122+
await overlays.overlayBlocksVideo()
123+
})
111124
test('Overlay is removed when new settings arrive', async ({ page }, workerInfo) => {
112125
const overlays = DuckplayerOverlays.create(page, workerInfo)
113126

integration-test/playwright/page-objects/duckplayer-overlays.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,19 @@ export class DuckplayerOverlays {
5454
await this.page.goto(this.overlaysPage)
5555
}
5656

57-
async gotoPlayerPage () {
58-
await this.page.goto(this.playerPage + '?videoID=123')
57+
/**
58+
* @param {object} [params]
59+
* @param {"default" | "incremental-dom"} [params.variant]
60+
* - we are replicating different strategies in the HTML to capture regressions/bugs
61+
*/
62+
async gotoPlayerPage (params = {}) {
63+
const { variant = 'default' } = params
64+
const urlParams = new URLSearchParams([
65+
['videoID', '123'],
66+
['variant', variant]
67+
])
68+
69+
await this.page.goto(this.playerPage + '?' + urlParams.toString())
5970
}
6071

6172
async gotoSerpProxyPage () {

integration-test/test-pages/duckplayer/pages/player.html

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,33 @@
66
<title>Duck Player - Player Overlay</title>
77
<link rel="stylesheet" href="../../shared/style.css">
88
<style>
9+
*, *:before, *:after {
10+
box-sizing: border-box;
11+
}
912
.container {
10-
width: 800px;
11-
height: 600px;
13+
max-width: 800px;
14+
aspect-ratio: 16/9;
1215
background: blue;
1316
}
17+
#player {
18+
height: 100%;
19+
}
1420
.html5-video-player {
1521
position: relative;
22+
height: 100%;
23+
border: 2px dotted red;
1624
}
1725
body {
1826
max-width: 100%;
1927
}
2028
.tools {
2129
margin-bottom: 1rem;
2230
}
31+
video {
32+
display: block;
33+
height: 100%;
34+
width: 100%;
35+
}
2336
</style>
2437
</head>
2538
<body>
@@ -39,8 +52,36 @@
3952
</div>
4053
</div>
4154
</template>
55+
4256
<script type="module">
43-
document.querySelector('main').innerHTML = document.querySelector('template[id="inner"]').innerHTML;
57+
const variant = new URLSearchParams(window.location.search).get('variant') || 'default';
58+
const main = document.querySelector('main');
59+
const html = (selector) => document.querySelector(selector).innerHTML
60+
61+
const knownVariants = {
62+
"default": () => {
63+
main.innerHTML = html('template[id="inner"]');
64+
},
65+
"incremental-dom": () => {
66+
main.innerHTML = `<div class="container"><div id="player"></div></div>`
67+
setTimeout(() => {
68+
const player = main.querySelector('#player');
69+
player.innerHTML = `
70+
<div class="html5-video-player">
71+
<video width="800px" height="600px"></video>
72+
</div>
73+
`
74+
}, 100);
75+
},
76+
}
77+
78+
if (variant in knownVariants) {
79+
console.log('executing page variant', variant)
80+
knownVariants[variant]();
81+
} else {
82+
console.warn('variant not found', variant)
83+
}
84+
4485
</script>
4586
</body>
4687
</html>

src/features/click-to-load.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,7 @@ function makeShareFeedbackLink () {
11561156
feedbackLink.style.cssText = styles.feedbackLink
11571157
feedbackLink.target = '_blank'
11581158
feedbackLink.href = '#'
1159-
feedbackLink.text = 'Share Feedback'
1159+
feedbackLink.text = sharedStrings.shareFeedback
11601160
// Open Feedback Form page through background event to avoid browser blocking extension link
11611161
feedbackLink.addEventListener('click', function (e) {
11621162
e.preventDefault()
@@ -1649,6 +1649,8 @@ function createYouTubePreview (originalElement, widget) {
16491649
const previewToggleRow = document.createElement('div')
16501650
previewToggleRow.style.cssText = styles.youTubePreviewToggleRow
16511651

1652+
// TODO: Use `widget.replaceSettings.placeholder.previewToggleEnabledDuckDuckGoText` for toggle
1653+
// copy when implementing mobile YT CTL Preview
16521654
const previewToggle = makeToggleButtonWithText(
16531655
widget.replaceSettings.placeholder.previewToggleEnabledText,
16541656
widget.getMode(),

src/features/click-to-load/ctl-config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,7 @@ export function getConfig (locale) {
10041004
placeholder: {
10051005
previewToggleEnabledText: ytStrings.infoPreviewToggleEnabledText,
10061006
previewInfoText: ytStrings.infoPreviewInfoText,
1007+
previewToggleEnabledDuckDuckGoText: ytStrings.infoPreviewToggleEnabledText,
10071008
videoPlayIcon: {
10081009
lightMode: videoPlayLight,
10091010
darkMode: videoPlayDark

0 commit comments

Comments
 (0)