Skip to content

Commit 39c45bf

Browse files
committed
Major cleanup
1 parent 0ea641b commit 39c45bf

File tree

15 files changed

+850
-206
lines changed

15 files changed

+850
-206
lines changed

injected/integration-test/test-pages/duckplayer/config/native.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,17 @@
22
"unprotectedTemporary": [],
33
"features": {
44
"duckPlayerNative": {
5-
"state": "enabled"
5+
"state": "enabled",
6+
"exceptions": [],
7+
"settings": {
8+
"selectors": {
9+
"errorContainer": "body",
10+
"signInRequiredError": "[href*=\"//support.google.com/youtube/answer/3037019\"]",
11+
"videoElement": "#player video",
12+
"videoElementContainer": "#player .html5-video-player"
13+
},
14+
"domains": []
15+
}
616
}
717
}
818
}

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@
163163
await import("/build/contentScope.js").catch(console.error)
164164

165165
const settingsFile = '/duckplayer/config/native.json';
166-
const featureSettings = await fetch(settingsFile).then(x => x.json())
166+
const settings = await fetch(settingsFile).then(x => x.json())
167+
console.log('Settings', settings);
167168

168169
document.dispatchEvent(new CustomEvent('content-scope-init-args', {
169170
detail: {
@@ -180,9 +181,13 @@
180181
'duckPlayerNative'
181182
]
182183
},
183-
featureSettings
184+
featureSettings: settings.features,
184185
}
185186
}))
187+
188+
setTimeout(() => {
189+
document.dispatchEvent(new CustomEvent('initialSetup', { detail: {} }));
190+
})
186191
})();
187192
</script>
188193

injected/src/features/duck-player-native.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import ContentFeature from '../content-feature.js';
22
// import { isBeingFramed } from '../utils.js';
3-
import { DuckPlayerNativeMessages } from './duckplayer-native/native-messages.js';
4-
import { initDuckPlayerNative } from './duckplayer-native/duckplayer-native.js';
3+
import { DuckPlayerNativeMessages } from './duckplayer-native/messages.js';
4+
import { mockTransport } from './duckplayer-native/mock-transport.js';
5+
import { DuckPlayerNative } from './duckplayer-native/duckplayer-native.js';
6+
import { Environment } from './duckplayer-native/environment.js';
57

68
/**
79
* @typedef InitialSettings - The initial payload used to communicate render-blocking information
@@ -10,16 +12,38 @@ import { initDuckPlayerNative } from './duckplayer-native/duckplayer-native.js';
1012

1113
export class DuckPlayerNativeFeature extends ContentFeature {
1214
init(args) {
13-
console.log('LOADING DUCK PLAYER NATIVE SCRIPTS', args);
14-
console.log('Duck Player Native Feature', args?.bundledConfig?.features?.duckPlayerNative);
15+
console.log('[duckplayer-native] Loading', args);
1516

17+
// TODO: Should we keep this?
1618
/**
1719
* This feature never operates in a frame
1820
*/
1921
// if (isBeingFramed()) return;
2022

23+
/**
24+
* @type {import("@duckduckgo/privacy-configuration/schema/features/duckplayer-native.js").DuckPlayerNativeSettings}
25+
*/
26+
// TODO: Why isn't this working?
27+
// const settings = this.getFeatureSetting('settings');
28+
const settings = args?.featureSettings?.duckPlayerNative;
29+
console.log('[duckplayer-native] Selectors', settings?.selectors);
30+
31+
const locale = args?.locale || args?.language || 'en';
32+
const env = new Environment({
33+
debug: this.isDebug,
34+
injectName: import.meta.injectName,
35+
platform: this.platform,
36+
locale,
37+
});
38+
39+
if (env.isIntegrationMode()) {
40+
// TODO: Better way than patching transport?
41+
this.messaging.transport = mockTransport();
42+
}
43+
2144
const comms = new DuckPlayerNativeMessages(this.messaging);
22-
initDuckPlayerNative(comms);
45+
const duckPlayerNative = new DuckPlayerNative(settings, env, comms);
46+
duckPlayerNative.init();
2347
}
2448
}
2549

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
export const MSG_NAME_INITIAL_SETUP = 'initialSetup';
2-
export const MSG_NAME_SET_VALUES = 'setUserValues';
3-
export const MSG_NAME_READ_VALUES = 'getUserValues';
4-
export const MSG_NAME_READ_VALUES_SERP = 'readUserValues';
5-
export const MSG_NAME_OPEN_PLAYER = 'openDuckPlayer';
6-
export const MSG_NAME_OPEN_INFO = 'openInfo';
7-
export const MSG_NAME_PUSH_DATA = 'onUserValuesChanged';
8-
export const MSG_NAME_PIXEL = 'sendDuckPlayerPixel';
9-
export const MSG_NAME_PROXY_INCOMING = 'ddg-serp-yt';
10-
export const MSG_NAME_PROXY_RESPONSE = 'ddg-serp-yt-response';
2+
export const MSG_NAME_CURRENT_TIMESTAMP = 'onCurrentTimestamp';
3+
export const MSG_NAME_MEDIA_CONTROL = 'onMediaControl';
4+
export const MSG_NAME_MUTE_AUDIO = 'onMuteAudio';
5+
export const MSG_NAME_SERP_NOTIFY = 'onSerpNotify';
6+
export const MSG_NAME_YOUTUBE_ERROR = 'onYoutubeError';

injected/src/features/duckplayer-native/custom-error/custom-error.css

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
/* -- VIDEO PLAYER OVERLAY */
22
:host {
3-
position: absolute;
4-
top: 0;
5-
left: 0;
6-
bottom: 0;
7-
right: 0;
8-
z-index: 10000;
93
--title-size: 16px;
104
--title-line-height: 20px;
115
--title-gap: 16px;
126
--button-gap: 6px;
7+
--padding: 4px;
138
--logo-size: 32px;
149
--logo-gap: 8px;
1510
--gutter: 16px;
11+
--background-color: black;
12+
--background-color-alt: #2f2f2f;
13+
14+
position: absolute;
15+
top: 0;
16+
left: 0;
17+
bottom: 0;
18+
right: 0;
19+
z-index: 10000;
20+
height: 100vh;
1621
}
1722
/* iphone 15 */
1823
@media screen and (min-width: 390px) {
@@ -55,17 +60,22 @@
5560
box-sizing: border-box;
5661
}
5762

63+
.wrapper {
64+
align-items: center;
65+
background-color: var(--background-color);
66+
display: flex;
67+
height: 100%;
68+
padding: var(--padding);
69+
}
70+
5871
.error {
5972
align-items: center;
60-
background: rgba(0, 0, 0, 0.6);
6173
display: grid;
62-
height: 100%;
6374
justify-items: center;
6475
}
6576

6677
.error.mobile {
6778
border-radius: var(--inner-radius);
68-
height: 100%;
6979
overflow: auto;
7080

7181
/* Prevents automatic text resizing */
@@ -77,7 +87,14 @@
7787
}
7888
}
7989

90+
.error.framed {
91+
padding: 4px;
92+
border: 4px solid var(--background-color-alt);
93+
border-radius: 16px;
94+
}
95+
8096
.container {
97+
background: var(--background-color);
8198
column-gap: 24px;
8299
display: flex;
83100
flex-flow: row;
@@ -120,7 +137,8 @@
120137
&::before {
121138
content: ' ';
122139
display: block;
123-
background: url('../img/warning-96.data.svg') no-repeat;
140+
background-image: url("data:image/svg+xml,%3Csvg fill='none' viewBox='0 0 96 96' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='red' d='M47.5 70.802c1.945 0 3.484-1.588 3.841-3.5C53.076 58.022 61.218 51 71 51h4.96c2.225 0 4.04-1.774 4.04-4 0-.026-.007-9.022-1.338-14.004a8.02 8.02 0 0 0-5.659-5.658C68.014 26 48 26 48 26s-20.015 0-25.004 1.338a8.01 8.01 0 0 0-5.658 5.658C16 37.986 16 48.401 16 48.401s0 10.416 1.338 15.405a8.01 8.01 0 0 0 5.658 5.658c4.99 1.338 24.504 1.338 24.504 1.338'/%3E%3Cpath fill='%23fff' d='m41.594 58 16.627-9.598-16.627-9.599z'/%3E%3Cpath fill='%23EB102D' d='M87 71c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16'/%3E%3Cpath fill='%23fff' d='M73 77.8a2 2 0 1 1-4 0 2 2 0 0 1 4 0m-2.039-4.4c-.706 0-1.334-.49-1.412-1.12l-.942-8.75c-.079-.7.55-1.33 1.412-1.33h1.962c.785 0 1.492.63 1.413 1.33l-.942 8.75c-.157.63-.784 1.12-1.49 1.12Z'/%3E%3Cpath fill='%23CCC' d='M92.501 59c.298 0 .595.12.823.354.454.468.454 1.23 0 1.698l-2.333 2.4a1.145 1.145 0 0 1-1.65 0 1.227 1.227 0 0 1 0-1.698l2.333-2.4c.227-.234.524-.354.822-.354zm-1.166 10.798h3.499c.641 0 1.166.54 1.166 1.2s-.525 1.2-1.166 1.2h-3.499c-.641 0-1.166-.54-1.166-1.2s.525-1.2 1.166-1.2m-1.982 8.754c.227-.234.525-.354.822-.354h.006c.297 0 .595.12.822.354l2.332 2.4c.455.467.455 1.23 0 1.697a1.145 1.145 0 0 1-1.65 0l-2.332-2.4a1.227 1.227 0 0 1 0-1.697'/%3E%3C/svg%3E%0A");
141+
background-repeat: no-repeat;
124142
height: 48px;
125143
width: 48px;
126144
}
@@ -133,7 +151,7 @@
133151
justify-content: start;
134152

135153
&::before {
136-
background-image: url('../img/warning-128.data.svg');
154+
background-image: url("data:image/svg+xml,%3Csvg fill='none' viewBox='0 0 128 96' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23888' d='M16.912 31.049a1.495 1.495 0 0 1 2.114-2.114l1.932 1.932 1.932-1.932a1.495 1.495 0 0 1 2.114 2.114l-1.932 1.932 1.932 1.932a1.495 1.495 0 0 1-2.114 2.114l-1.932-1.933-1.932 1.933a1.494 1.494 0 1 1-2.114-2.114l1.932-1.932zM.582 52.91a1.495 1.495 0 0 1 2.113-2.115l1.292 1.292 1.291-1.292a1.495 1.495 0 1 1 2.114 2.114L6.1 54.2l1.292 1.292a1.495 1.495 0 1 1-2.113 2.114l-1.292-1.292-1.292 1.292a1.495 1.495 0 1 1-2.114-2.114l1.292-1.291zm104.972-15.452a1.496 1.496 0 0 1 2.114-2.114l1.291 1.292 1.292-1.292a1.495 1.495 0 0 1 2.114 2.114l-1.292 1.291 1.292 1.292a1.494 1.494 0 1 1-2.114 2.114l-1.292-1.292-1.291 1.292a1.495 1.495 0 0 1-2.114-2.114l1.292-1.292zM124.5 54c-.825 0-1.5-.675-1.5-1.5s.675-1.5 1.5-1.5 1.5.675 1.5 1.5-.675 1.5-1.5 1.5M24 67c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2' opacity='.2'/%3E%3Cpath fill='red' d='M63.5 70.802c1.945 0 3.484-1.588 3.841-3.5C69.076 58.022 77.218 51 87 51h4.96c2.225 0 4.04-1.774 4.04-4 0-.026-.007-9.022-1.338-14.004a8.02 8.02 0 0 0-5.659-5.658C84.014 26 64 26 64 26s-20.014 0-25.004 1.338a8.01 8.01 0 0 0-5.658 5.658C32 37.986 32 48.401 32 48.401s0 10.416 1.338 15.405a8.01 8.01 0 0 0 5.658 5.658c4.99 1.338 24.504 1.338 24.504 1.338'/%3E%3Cpath fill='%23fff' d='m57.594 58 16.627-9.598-16.627-9.599z'/%3E%3Cpath fill='%23EB102D' d='M103 71c0 8.837-7.163 16-16 16s-16-7.163-16-16 7.163-16 16-16 16 7.163 16 16'/%3E%3Cpath fill='%23fff' d='M89 77.8a2 2 0 1 1-4 0 2 2 0 0 1 4 0m-2.039-4.4c-.706 0-1.334-.49-1.412-1.12l-.942-8.75c-.079-.7.55-1.33 1.412-1.33h1.962c.785 0 1.492.63 1.413 1.33l-.942 8.75c-.157.63-.784 1.12-1.49 1.12Z'/%3E%3Cpath fill='%23CCC' d='M108.501 59c.298 0 .595.12.823.354.454.468.454 1.23 0 1.698l-2.333 2.4a1.145 1.145 0 0 1-1.65 0 1.226 1.226 0 0 1 0-1.698l2.332-2.4c.228-.234.525-.354.823-.354zm-1.166 10.798h3.499c.641 0 1.166.54 1.166 1.2s-.525 1.2-1.166 1.2h-3.499c-.641 0-1.166-.54-1.166-1.2s.525-1.2 1.166-1.2m-1.982 8.754c.227-.234.525-.354.822-.354h.006c.297 0 .595.12.822.354l2.333 2.4c.454.467.454 1.23 0 1.697a1.146 1.146 0 0 1-1.651 0l-2.332-2.4a1.226 1.226 0 0 1 0-1.697'/%3E%3C/svg%3E%0A");
137155
height: 96px;
138156
width: 128px;
139157
}

injected/src/features/duckplayer-native/custom-error/custom-error.js

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
import mobilecss from './custom-error.css';
1+
import css from './custom-error.css';
22
import { createPolicy, html } from '../../../dom-utils.js';
33
import { customElementsDefine, customElementsGet } from '../../../captured-globals.js';
44

55
/** @typedef {import('../error-detection').YouTubeError} YouTubeError */
66

7-
export function registerCustomElements() {
8-
if (!customElementsGet(CustomError.CUSTOM_TAG_NAME)) {
9-
customElementsDefine(CustomError.CUSTOM_TAG_NAME, CustomError);
10-
}
11-
}
12-
137
/**
148
* The custom element that we use to present our UI elements
159
* over the YouTube player
@@ -27,39 +21,59 @@ export class CustomError extends HTMLElement {
2721
/** @type {string[]} */
2822
messages = [];
2923

24+
static register() {
25+
if (!customElementsGet(CustomError.CUSTOM_TAG_NAME)) {
26+
customElementsDefine(CustomError.CUSTOM_TAG_NAME, CustomError);
27+
}
28+
}
29+
30+
log(message, force = false) {
31+
if (this.testMode || force) {
32+
console.log(`[custom-error] ${message}`);
33+
}
34+
}
35+
3036
connectedCallback() {
3137
this.createMarkupAndStyles();
3238
}
3339

3440
createMarkupAndStyles() {
3541
const shadow = this.attachShadow({ mode: this.testMode ? 'open' : 'closed' });
42+
3643
const style = document.createElement('style');
37-
style.innerText = mobilecss;
44+
style.innerText = css;
45+
3846
const container = document.createElement('div');
47+
container.classList.add('wrapper');
3948
const content = this.render();
4049
container.innerHTML = this.policy.createHTML(content);
4150
shadow.append(style, container);
4251
this.container = container;
52+
53+
if (this.testMode) {
54+
this.log(`Created ${CustomError.CUSTOM_TAG_NAME} with container ${container}`);
55+
}
4356
}
4457

4558
/**
4659
* @returns {string}
4760
*/
4861
render() {
4962
if (!this.title || !this.messages) {
50-
console.warn('missing error text. Please assign before rendering');
63+
console.warn('Missing error title or messages. Please assign before rendering');
5164
return '';
5265
}
5366

54-
const messagesHtml = this.messages.map((message) => html`<p>${message}</p>`);
67+
const { title, messages } = this;
68+
const messagesHtml = messages.map((message) => html`<p>${message}</p>`);
5569

5670
return html`
5771
<div class="error mobile">
5872
<div class="container">
5973
<span class="icon"></span>
6074
6175
<div class="content">
62-
<h1 class="heading">{heading}</h1>
76+
<h1 class="heading">${title}</h1>
6377
<div class="messages">${messagesHtml}</div>
6478
</div>
6579
</div>
@@ -68,21 +82,36 @@ export class CustomError extends HTMLElement {
6882
}
6983
}
7084

85+
/**
86+
* @param {import('../environment').Environment} environment
87+
* @param {YouTubeError} errorId
88+
*/
89+
function getErrorStrings(environment, errorId) {
90+
// TODO: get from environment strings
91+
console.log(`Getting translations for ${errorId} from ${environment}`);
92+
return {
93+
title: 'YouTube won’t let Duck Player load this video',
94+
messages: [
95+
'YouTube doesn’t allow this video to be viewed outside of YouTube.',
96+
'You can still watch this video on YouTube, but without the added privacy of Duck Player.',
97+
],
98+
};
99+
}
100+
71101
/**
72102
*
73103
* @param {HTMLElement} targetElement
74-
* @param {object} options
75-
* @param {string} options.title
76-
* @param {string[]} options.messages
104+
* @param {import('../environment').Environment} environment
105+
* @param {YouTubeError} errorId
77106
*/
78-
export function showError(targetElement, { title, messages }) {
79-
registerCustomElements();
80-
console.log('Appending custom error view');
107+
export function showError(targetElement, environment, errorId) {
108+
const { title, messages } = getErrorStrings(environment, errorId);
109+
CustomError.register();
110+
81111
const customError = /** @type {CustomError} */ (document.createElement(CustomError.CUSTOM_TAG_NAME));
82-
customError.testMode = true;
112+
customError.testMode = environment.isTestMode();
83113
customError.title = title;
84114
customError.messages = messages;
85-
console.log('Custom error view', customError, targetElement);
86115
targetElement.appendChild(customError);
87116

88117
return () => {

0 commit comments

Comments
 (0)