Skip to content

Commit dbbc71c

Browse files
author
Shane Osbourne
committed
Duck Player macOS
1 parent 561cb93 commit dbbc71c

File tree

25 files changed

+852
-117
lines changed

25 files changed

+852
-117
lines changed

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ let package = Package(
2121
dependencies: [],
2222
resources: [
2323
.process("dist/contentScope.js"),
24+
.process("dist/contentScopeIsolated.js"),
2425
.copy("dist/pages"),
2526
]
2627
),

inject/apple.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,48 @@ import { isTrackerOrigin } from '../src/trackers'
88

99
function initCode () {
1010
// @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f
11-
const processedConfig = processConfig($CONTENT_SCOPE$, $USER_UNPROTECTED_DOMAINS$, $USER_PREFERENCES$)
11+
const json = $CONTENT_SCOPE$
12+
13+
json.features.duckPlayer = {
14+
state: 'enabled',
15+
exceptions: [],
16+
settings: {
17+
overlays: {
18+
youtube: {
19+
state: 'disabled'
20+
},
21+
serpProxy: {
22+
state: 'disabled'
23+
}
24+
},
25+
domains: [
26+
{
27+
domain: 'www.youtube.com',
28+
patchSettings: [
29+
{
30+
op: 'replace',
31+
path: '/overlays/youtube/state',
32+
value: 'enabled'
33+
}
34+
]
35+
},
36+
{
37+
domain: 'duckduckgo.com',
38+
patchSettings: [
39+
{
40+
op: 'replace',
41+
path: '/overlays/serpProxy/state',
42+
value: 'enabled'
43+
}
44+
]
45+
}
46+
]
47+
}
48+
}
49+
50+
// @ts-expect-error https://app.asana.com/0/1201614831475344/1203979574128023/f
51+
const processedConfig = processConfig(json, $USER_UNPROTECTED_DOMAINS$, $USER_PREFERENCES$)
52+
1253
if (isGloballyDisabled(processedConfig)) {
1354
return
1455
}

integration-test/playwright/duckplayer.spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,12 @@ test.describe('Duck Player Overlays on Video Player in YouTube.com', () => {
224224
await overlays.userSettingWasUpdatedTo('always ask remembered') // updated
225225
})
226226
})
227+
228+
test.describe('serp proxy', () => {
229+
test('serp proxy is enabled', async ({ page }, workerInfo) => {
230+
const overlays = DuckplayerOverlays.create(page, workerInfo)
231+
await overlays.serpProxyEnabled()
232+
await overlays.gotoSerpProxyPage()
233+
await overlays.userValuesCallIsProxied()
234+
})
235+
})

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const userValues = {
3535
export class DuckplayerOverlays {
3636
overlaysPage = '/duckplayer/pages/overlays.html'
3737
playerPage = '/duckplayer/pages/player.html'
38+
serpProxyPage = '/duckplayer/pages/serp-proxy.html'
3839
/**
3940
* @param {import("@playwright/test").Page} page
4041
* @param {import("@duckduckgo/messaging/lib/test-utils.mjs").PlatformInfo} platform
@@ -55,6 +56,25 @@ export class DuckplayerOverlays {
5556
await this.page.goto(this.playerPage + '?videoID=123')
5657
}
5758

59+
async gotoSerpProxyPage () {
60+
await this.page.goto(this.serpProxyPage)
61+
}
62+
63+
async userValuesCallIsProxied () {
64+
const calls = await this.page.evaluate(readOutgoingMessages)
65+
expect(calls).toMatchObject([
66+
{
67+
payload: {
68+
context: 'contentScopeScripts',
69+
featureName: 'duckPlayer',
70+
params: {},
71+
method: 'getUserValues',
72+
id: 'getUserValues.response'
73+
}
74+
}
75+
])
76+
}
77+
5878
async overlayBlocksVideo () {
5979
await this.page.locator('ddg-video-overlay').waitFor({ state: 'visible', timeout: 1000 })
6080
await this.page.getByRole('link', { name: 'Watch in Duck Player' }).waitFor({ state: 'visible', timeout: 1000 })
@@ -72,6 +92,13 @@ export class DuckplayerOverlays {
7292
await this.setup({ config: loadConfig('overlays') })
7393
}
7494

95+
async serpProxyEnabled () {
96+
const config = loadConfig('overlays')
97+
const domains = config.features.duckPlayer.settings.domains[0].patchSettings
98+
config.features.duckPlayer.settings.domains[0].patchSettings = domains.filter(x => x.path === '/overlays/serpProxy/state')
99+
await this.setup({ config })
100+
}
101+
75102
async videoOverlayDoesntShow () {
76103
expect(await this.page.locator('ddg-video-overlay').count()).toBe(0)
77104
}

integration-test/test-pages/duckplayer/config/overlays.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
"overlays": {
99
"youtube": {
1010
"state": "disabled"
11+
},
12+
"serpProxy": {
13+
"state": "disabled"
1114
}
1215
},
1316
"domains": [
@@ -18,6 +21,11 @@
1821
"op": "replace",
1922
"path": "/overlays/youtube/state",
2023
"value": "enabled"
24+
},
25+
{
26+
"op": "replace",
27+
"path": "/overlays/serpProxy/state",
28+
"value": "enabled"
2129
}
2230
]
2331
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width">
6+
<title>Serp Proxy</title>
7+
<link rel="stylesheet" href="../../shared/style.css">
8+
<style>
9+
.container {
10+
width: 800px;
11+
height: 460px;
12+
position: relative;
13+
}
14+
15+
.overlay, .overlay__wrap {
16+
position: absolute;
17+
margin: auto;
18+
bottom: 0;
19+
right: 0;
20+
left: 0;
21+
top: 0
22+
}
23+
24+
.overlay {
25+
z-index: 1;
26+
display: block;
27+
overflow: hidden;
28+
background: #222;
29+
background: rgba(45, 45, 45, 0.9);
30+
text-align: center;
31+
color: #fafafa
32+
}
33+
34+
.is-mobile .overlay {
35+
position: fixed
36+
}
37+
38+
.overlay__wrap {
39+
display: table;
40+
height: 100%
41+
}
42+
43+
.overlay__content {
44+
display: table-cell;
45+
vertical-align: middle;
46+
text-align: center;
47+
line-height: 1.2
48+
}
49+
50+
.overlay__title {
51+
margin: .5em 0 .25em;
52+
font-weight: 300
53+
}
54+
55+
.overlay__text {
56+
font-weight: 300;
57+
color: #bbb
58+
}
59+
60+
.overlay__link {
61+
color: #49a9f2
62+
}
63+
64+
.overlay__btn-list {
65+
padding: 1em .5em
66+
}
67+
68+
.is-mobile .overlay__btn-list {
69+
padding-left: 0;
70+
padding-right: 0
71+
}
72+
73+
.overlay__btn-list__li {
74+
display: inline-block;
75+
width: 11em;
76+
margin: 0 .25em .5em
77+
}
78+
79+
.is-mobile .overlay__btn-list__li {
80+
width: 46%;
81+
margin-left: 1%;
82+
margin-right: 1%
83+
}
84+
85+
.overlay__btn {
86+
display: block;
87+
padding: .65em 0;
88+
text-align: center;
89+
line-height: 1.2;
90+
border-color: #fafafa;
91+
color: #fafafa
92+
}
93+
94+
.overlay__btn--single {
95+
display: inline-block;
96+
padding: .65em;
97+
margin: 1em .5em
98+
}
99+
100+
.overlay__btn:hover {
101+
background-color: #fafafa;
102+
color: #222
103+
}
104+
</style>
105+
</head>
106+
<body>
107+
<script src="../../shared/utils.js"></script>
108+
<p><a href="../index.html">[Duck Player]</a></p>
109+
<h1>Serp Proxy</h1>
110+
<div class="container">
111+
<div class="overlay overlay--duck-player">
112+
<div class="overlay__wrap">
113+
<div class="overlay__content"><h3 class="overlay__title detail__media__duck-player__header">Choose How You
114+
Watch</h3>
115+
<p class="overlay__text overlay--duck-player__text">Watch in Duck Player to block personalized ads on
116+
YouTube and prevent your viewing activity from influencing YouTube recommendations.</p>
117+
<ul class="overlay__btn-list">
118+
<li class="overlay__btn-list__li"><a class="btn btn--gray overlay__btn js-video-youtube" href="#"
119+
title="Watch on YouTube">Watch on YouTube</a></li>
120+
<li class="overlay__btn-list__li"><a class="btn btn--blue overlay__btn js-video-duck-player"
121+
href="#"
122+
title="Watch in Duck Player">Watch in Duck Player</a></li>
123+
</ul>
124+
<label class="overlay--duck-player__remember"><input type="checkbox" class="js-video-remember">Remember
125+
my
126+
choice</label></div>
127+
</div>
128+
</div>
129+
</div>
130+
<script>
131+
window.addEventListener('ddg-serp-yt-response', (evt) => {
132+
console.log('got response')
133+
console.log(evt.detail)
134+
})
135+
window.dispatchEvent(new CustomEvent('ddg-serp-yt', {
136+
detail: {
137+
kind: 'readUserValues'
138+
}
139+
}))
140+
</script>
141+
</body>
142+
</html>

0 commit comments

Comments
 (0)