Skip to content

Commit dcb6bda

Browse files
committed
Fixed media placeholder not shown when blocking Youtube movies.
1 parent bfe1ddc commit dcb6bda

1 file changed

Lines changed: 44 additions & 29 deletions

File tree

src/content/media.js

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
if ("MediaSource" in window) {
2+
let mediaBlocker;
23
let notify = allowed => {
34
let request = {
45
id: "noscript-media",
@@ -22,12 +23,40 @@ if ("MediaSource" in window) {
2223
error(e);
2324
}
2425
};
26+
if ("SecurityPolicyViolationEvent" in window) {
27+
// "Modern" browsers
28+
let createPlaceholders = () => {
29+
let request = notify(false);
30+
for (let me of document.querySelectorAll("video,audio")) {
31+
if (!(me.src || me.currentSrc) || me.src.startsWith("blob")) {
32+
createPlaceholder(me, request);
33+
}
34+
}
35+
}
36+
let processedURIs = new Set();
37+
addEventListener("securitypolicyviolation", e => {
38+
let {blockedURI, violatedDirective} = e;
39+
if (!(e.isTrusted && violatedDirective.startsWith("media-src"))) return;
40+
if (mediaBlocker === undefined && /^data\b/.test(blockedURI)) { // Firefox 81 reports just "data"
41+
debug("mediaBlocker set via CSP listener.")
42+
mediaBlocker = true;
43+
e.stopImmediatePropagation();
44+
return;
45+
}
46+
if (blockedURI.startsWith("blob") &&
47+
!processedURIs.has(blockedURI)) {
48+
processedURIs.add(blockedURI);
49+
setTimeout(createPlaceholders, 0);
50+
}
51+
}, true);
52+
}
2553

2654
if (typeof exportFunction === "function") {
27-
// Mozilla
28-
let mediablocker = true;
55+
// Fallback: Mozilla does not seem to trigger CSP media-src http: for blob: URIs assigned in MSE
56+
window.wrappedJSObject.document.createElement("video").src = "data:"; // triggers early mediaBlocker initialization via CSP
2957
ns.on("capabilities", e => {
3058
mediaBlocker = !ns.allows("media");
59+
if (mediaBlocker) debug("mediaBlocker set via fetched policy.")
3160
});
3261

3362
let unpatched = new Map();
@@ -55,37 +84,23 @@ if ("MediaSource" in window) {
5584
if (mediaBlocker) {
5685
let exposedMime = `${mime} (MSE)`;
5786
setTimeout(() => {
58-
let me = Array.from(document.querySelectorAll("video,audio"))
59-
.find(e => e.srcObject === ms || urls && urls.has(e.src));
60-
if (me) createPlaceholder(me, request);
87+
try {
88+
let allMedia = [...document.querySelectorAll("video,audio")];
89+
let me = allMedia.find(e => e.srcObject === ms ||
90+
urls && (urls.has(e.currentSrc) || urls.has(e.src))) ||
91+
// throwing may cause src not to be assigned at all:
92+
allMedia.find(e => !(e.src || e.currentSrc || e.srcObject));
93+
if (me) createPlaceholder(me, request);
94+
} catch (e) {
95+
error(e);
96+
}
6197
}, 0);
62-
throw new Error(`${exposedMime} blocked by NoScript`);
98+
let msg = `${exposedMime} blocked by NoScript`;
99+
log(msg);
100+
throw new Error(msg);
63101
}
64102

65103
return unpatched.get(window.MediaSource.prototype).addSourceBuffer.call(ms, mime, ...args);
66104
});
67-
68-
} else if ("SecurityPolicyViolationEvent" in window) {
69-
// Chromium
70-
let createPlaceholders = () => {
71-
let request = notify(false);
72-
for (let me of document.querySelectorAll("video,audio")) {
73-
if (!(me.src || me.currentSrc) || me.src.startsWith("blob")) {
74-
createPlaceholder(me, request);
75-
}
76-
}
77-
}
78-
let processedURIs = new Set();
79-
let whenReady = false;
80-
addEventListener("securitypolicyviolation", e => {
81-
if (!e.isTrusted || ns.allows("media")) return;
82-
let {blockedURI, violatedDirective} = e;
83-
if (blockedURI.startsWith("blob") &&
84-
violatedDirective.startsWith("media-src") &&
85-
!processedURIs.has(blockedURI)) {
86-
processedURIs.add(blockedURI);
87-
setTimeout(createPlaceholders, 0);
88-
}
89-
}, true);
90105
}
91106
}

0 commit comments

Comments
 (0)