Implement auto-updating of the injection script
This commit is contained in:
parent
7908bb9f64
commit
f9585c27d7
@ -42,7 +42,7 @@ $build = createZip("Universal Bypass.zip");
|
||||
$firefox = createZip("Universal Bypass for Firefox.zip");
|
||||
foreach($index as $fn)
|
||||
{
|
||||
if($fn == "README.md")
|
||||
if($fn == "README.md" || $fn == "injection_script.js")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
10
PRIVACY.md
10
PRIVACY.md
@ -1,4 +1,12 @@
|
||||
# Privacy Policy
|
||||
# Universal Bypass Privacy Policy
|
||||
|
||||
## Auto-updating
|
||||
|
||||
In order to provide up-to-date bypasses, Universal Bypass sends a request to Github every hour, and if a new commit is found, it will download the latest "injection script."
|
||||
|
||||
For this, [Github's privacy policy](https://help.github.com/en/github/site-policy/github-privacy-statement) applies.
|
||||
|
||||
## Crowd Bypass
|
||||
|
||||
When Crowd Bypass (Options > "Give and take the destinations of unbypassable shorteners.") is enabled, a request to my server is being sent for it to work, of which I store nothing.
|
||||
|
||||
|
@ -17,6 +17,15 @@
|
||||
"changelog": {
|
||||
"message": "Changelog"
|
||||
},
|
||||
"update": {
|
||||
"message": "Check for updates"
|
||||
},
|
||||
"updateYes": {
|
||||
"message": "Sucessfully updated injection script!"
|
||||
},
|
||||
"updateNo": {
|
||||
"message": "Already up-to-date."
|
||||
},
|
||||
"faq": {
|
||||
"message": "Frequently Asked Questions (FAQ)"
|
||||
},
|
||||
|
164
background.js
164
background.js
@ -47,7 +47,7 @@ isGoodLink=link=>{
|
||||
},
|
||||
countIt=()=>brws.storage.local.set({bypass_counter:++bypassCounter})
|
||||
|
||||
//Install handler
|
||||
// Install handler
|
||||
brws.runtime.onInstalled.addListener(details=>{
|
||||
if(details.reason=="install")
|
||||
{
|
||||
@ -55,8 +55,8 @@ brws.runtime.onInstalled.addListener(details=>{
|
||||
}
|
||||
})
|
||||
|
||||
//Keeping track of options
|
||||
var enabled=true,instantNavigation=true,trackerBypassEnabled=true,instantNavigationTrackers=false,blockIPLoggers=true,crowdEnabled=true,infoBoxEnabled=true,userscript="",bypassCounter=0,refererCache={}
|
||||
// Keeping track of options
|
||||
var bypassCounter=0,enabled=true,instantNavigation=true,trackerBypassEnabled=true,instantNavigationTrackers=false,blockIPLoggers=true,crowdEnabled=true,infoBoxEnabled=true,userScript=""
|
||||
brws.storage.sync.get(["disable","navigation_delay","no_tracker_bypass","no_instant_navigation_trackers","allow_ip_loggers","crowd_bypass_opt_out","crowd_open_delay","no_info_box"],res=>{
|
||||
if(res)
|
||||
{
|
||||
@ -98,7 +98,8 @@ brws.storage.local.get(["userscript","bypass_counter"],res=>{
|
||||
{
|
||||
if(res.userscript)
|
||||
{
|
||||
userscript=res.userscript
|
||||
userScript=res.userscript
|
||||
refreshInjectionScript()
|
||||
}
|
||||
if(res.bypass_counter)
|
||||
{
|
||||
@ -157,16 +158,88 @@ brws.storage.onChanged.addListener(changes=>{
|
||||
}
|
||||
if(changes.userscript)
|
||||
{
|
||||
userscript=changes.userscript.newValue
|
||||
userScript=changes.userscript.newValue
|
||||
refreshInjectionScript()
|
||||
}
|
||||
})
|
||||
|
||||
//Messaging
|
||||
// Injection Script Management
|
||||
let injectionScript = "", upstreamInjectionScript = "", upstreamCommit, channel = {}
|
||||
const downloadInjectionScript = () => new Promise(callback => {
|
||||
const finishDownload = () => {
|
||||
channel = {}
|
||||
;["stop_watching","crowd_path","crowd_query","crowd_queried","crowd_contribute","adlinkfly_info","adlinkfly_target"].forEach(name => {
|
||||
upstreamInjectionScript = upstreamInjectionScript.split("{{channel."+name+"}}").join(channel[name] = "data-"+Math.random().toString().substr(2))
|
||||
})
|
||||
;["crowdWait","crowdDisabled","infoBoxHide"].forEach(name => {
|
||||
upstreamInjectionScript = upstreamInjectionScript.split("{{msg."+name+"}}").join(brws.i18n.getMessage(name).split("\\").join("\\\\").split("\"").join("\\\""))
|
||||
})
|
||||
upstreamInjectionScript = upstreamInjectionScript.split("{{icon/48.png}}").join(brws.runtime.getURL("icon/48.png"))
|
||||
refreshInjectionScript()
|
||||
callback(true)
|
||||
}
|
||||
chrome.runtime.getPackageDirectoryEntry(root => root.createReader().readEntries(res => {
|
||||
let found = false
|
||||
res.forEach(file => {
|
||||
if(file.name == "injection_script.js")
|
||||
{
|
||||
found = true
|
||||
file.file(file => {
|
||||
const reader = new FileReader()
|
||||
reader.onloadend = () => {
|
||||
upstreamInjectionScript = reader.result
|
||||
finishDownload()
|
||||
}
|
||||
reader.readAsText(file)
|
||||
})
|
||||
}
|
||||
})
|
||||
if(!found)
|
||||
{
|
||||
let xhr = new XMLHttpRequest()
|
||||
xhr.onload = () => {
|
||||
const latestCommit = JSON.parse(xhr.responseText).sha
|
||||
if(latestCommit == upstreamCommit)
|
||||
{
|
||||
callback(false)
|
||||
}
|
||||
else
|
||||
{
|
||||
upstreamCommit = latestCommit
|
||||
xhr = new XMLHttpRequest()
|
||||
xhr.onload = () => {
|
||||
upstreamInjectionScript = xhr.responseText
|
||||
finishDownload()
|
||||
}
|
||||
xhr.open("GET", "https://raw.githubusercontent.com/timmyRS/Universal-Bypass/" + upstreamCommit + "/injection_script.js", true)
|
||||
xhr.send()
|
||||
}
|
||||
}
|
||||
xhr.open("GET", "https://api.github.com/repos/timmyRS/Universal-Bypass/commits/master", true)
|
||||
xhr.send()
|
||||
}
|
||||
}))
|
||||
}),
|
||||
refreshInjectionScript = () => {
|
||||
injectionScript = upstreamInjectionScript + "\n" + userScript
|
||||
}
|
||||
downloadInjectionScript()
|
||||
brws.alarms.create("update-injection-script", {periodInMinutes: 60})
|
||||
brws.alarms.onAlarm.addListener(alert => {
|
||||
console.assert(alert.name == "update-injection-script")
|
||||
downloadInjectionScript()
|
||||
})
|
||||
|
||||
// Messaging
|
||||
brws.runtime.onMessage.addListener((req, sender, respond) => {
|
||||
switch(req.type)
|
||||
{
|
||||
case "can-run":
|
||||
respond({enabled, crowdEnabled, infoBoxEnabled, userscript})
|
||||
case "content":
|
||||
respond({enabled, channel, crowdEnabled, infoBoxEnabled, injectionScript})
|
||||
break;
|
||||
|
||||
case "options":
|
||||
respond({upstreamCommit, bypassCounter, userScript})
|
||||
break;
|
||||
|
||||
case "open-tab":
|
||||
@ -194,32 +267,43 @@ brws.runtime.onMessage.addListener((req, sender, respond) => {
|
||||
}
|
||||
})
|
||||
brws.runtime.onConnect.addListener(port => {
|
||||
console.assert(port.name == "adlinkfly-info")
|
||||
port.onMessage.addListener(msg => {
|
||||
let xhr=new XMLHttpRequest(),t="",iu=msg
|
||||
xhr.onload=()=>{
|
||||
let i=new DOMParser().parseFromString(xhr.responseText,"text/html").querySelector("img[src^='//api.miniature.io']")
|
||||
if(i)
|
||||
{
|
||||
let url=new URL(i.src)
|
||||
if(url.search&&url.search.indexOf("url="))
|
||||
switch(port.name)
|
||||
{
|
||||
case "update":
|
||||
downloadInjectionScript().then(success => port.postMessage({success, upstreamCommit}))
|
||||
break;
|
||||
|
||||
case "adlinkfly-info":
|
||||
port.onMessage.addListener(msg => {
|
||||
let xhr=new XMLHttpRequest(),t="",iu=msg
|
||||
xhr.onload=()=>{
|
||||
let i=new DOMParser().parseFromString(xhr.responseText,"text/html").querySelector("img[src^='//api.miniature.io']")
|
||||
if(i)
|
||||
{
|
||||
t=decodeURIComponent(url.search.split("url=")[1].split("&")[0])
|
||||
let url=new URL(i.src)
|
||||
if(url.search&&url.search.indexOf("url="))
|
||||
{
|
||||
t=decodeURIComponent(url.search.split("url=")[1].split("&")[0])
|
||||
}
|
||||
}
|
||||
port.postMessage(t)
|
||||
}
|
||||
port.postMessage(t)
|
||||
}
|
||||
xhr.onerror=()=>port.postMessage(t)
|
||||
if(iu.substr(-1) != "/")
|
||||
{
|
||||
iu += "/"
|
||||
}
|
||||
xhr.open("GET", iu+"info", true)
|
||||
xhr.send()
|
||||
})
|
||||
xhr.onerror=()=>port.postMessage(t)
|
||||
if(iu.substr(-1) != "/")
|
||||
{
|
||||
iu += "/"
|
||||
}
|
||||
xhr.open("GET", iu+"info", true)
|
||||
xhr.send()
|
||||
})
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn("Invalid connection:", port)
|
||||
}
|
||||
})
|
||||
|
||||
//Internal redirects to extension URLs to bypass content script limitations
|
||||
// Internal redirects to extension URLs to bypass content script limitations
|
||||
brws.webRequest.onBeforeRequest.addListener(details=>{
|
||||
if(details.url.substr(38)=="1")
|
||||
{
|
||||
@ -236,6 +320,17 @@ brws.webRequest.onBeforeRequest.addListener(details=>{
|
||||
return encodedRedirect(arr[0],arr[1])
|
||||
},{types:["main_frame"],urls:["*://universal-bypass.org/bypassed?target=*&referer=*"]},["blocking"])
|
||||
|
||||
brws.webRequest.onBeforeRequest.addListener(details=>{
|
||||
countIt()
|
||||
return {redirectUrl:brws.runtime.getURL("html/crowd-bypassed.html")+details.url.substr(43)}
|
||||
},{types:["main_frame"],urls:["https://universal-bypass.org/crowd-bypassed?*"]},["blocking"])
|
||||
|
||||
brws.webRequest.onBeforeRequest.addListener(details=>{
|
||||
return {redirectUrl:brws.runtime.getURL("html/options.html")+details.url.substr(36)}
|
||||
},{types:["main_frame"],urls:["https://universal-bypass.org/options"]},["blocking"])
|
||||
|
||||
// Navigation handling including presenting referer header to destinations
|
||||
var refererCache={}
|
||||
brws.webRequest.onBeforeRequest.addListener(details=>{
|
||||
let arr=details.url.substr(45).split("&referer=")
|
||||
arr[0]=(new URL(decodeURIComponent(arr[0]))).toString()
|
||||
@ -280,16 +375,7 @@ brws.webRequest.onCompleted.addListener(details=>{
|
||||
}
|
||||
},{types:["main_frame"],urls:["<all_urls>"]})
|
||||
|
||||
brws.webRequest.onBeforeRequest.addListener(details=>{
|
||||
countIt()
|
||||
return {redirectUrl:brws.runtime.getURL("html/crowd-bypassed.html")+details.url.substr(43)}
|
||||
},{types:["main_frame"],urls:["https://universal-bypass.org/crowd-bypassed?*"]},["blocking"])
|
||||
|
||||
brws.webRequest.onBeforeRequest.addListener(details=>{
|
||||
return {redirectUrl:brws.runtime.getURL("html/options.html")+details.url.substr(36)}
|
||||
},{types:["main_frame"],urls:["https://universal-bypass.org/options"]},["blocking"])
|
||||
|
||||
//Preflight Bypasses
|
||||
// Preflight Bypasses
|
||||
brws.webRequest.onBeforeRequest.addListener(details=>{
|
||||
if(enabled)
|
||||
{
|
||||
|
1547
content_script.js
1547
content_script.js
File diff suppressed because it is too large
Load Diff
@ -1,2 +1,3 @@
|
||||
var brws=(typeof browser=="undefined"?chrome:browser)
|
||||
const brws=(typeof browser=="undefined"?chrome:browser)
|
||||
document.querySelectorAll("[data-message]").forEach(e=>e.textContent=brws.i18n.getMessage(e.getAttribute("data-message")))
|
||||
document.querySelectorAll("[data-message-nbsp]").forEach(e=>e.innerHTML=brws.i18n.getMessage(e.getAttribute("data-message-nbsp")).split(" ").join(" "))
|
||||
|
@ -8,7 +8,9 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1>Universal Bypass</h1>
|
||||
<p><span data-message="version"></span> <span id="version"></span> · <a href="https://universal-bypass.org/changelog" target="_blank" data-message="changelog"></a> · <a href="https://universal-bypass.org/faq" target="_blank" data-message="faq"></a></p>
|
||||
<p><span data-message="version"></span> <span id="version"></span> · <a href="#" data-message-nbsp="update"></a> · <a href="https://universal-bypass.org/changelog" target="_blank" data-message-nbsp="changelog"></a> · <a href="https://universal-bypass.org/faq" target="_blank" data-message-nbsp="faq"></a> · <a href="https://github.com/timmyrs/Universal-Bypass/blob/master/PRIVACY.md" target="_blank" data-message-nbsp="privacyPolicy"></a></p>
|
||||
<p data-message="updateYes" style="display:none;margin-top:15px"></p>
|
||||
<p data-message="updateNo" style="display:none;margin-top:15px"></p>
|
||||
<div id="counter" style="display:none;margin-top:15px">
|
||||
<span data-message="bypassCounter"></span> <a href="https://universal-bypass.org/support" target="_blank" data-message="support"></a>
|
||||
</div>
|
||||
@ -19,7 +21,7 @@
|
||||
<input type="checkbox" id="option-tracker-bypass"> <label for="option-tracker-bypass"><span data-message="optionsTrackerBypass"></span> (Bit.ly, Goo.gl, T.co, ...)</label> (<a href="https://apimon.de/privacy" target="_blank" data-message="privacyPolicy"></a>)<br>
|
||||
<input type="checkbox" id="option-instant-navigation-trackers"> <label for="option-instant-navigation-trackers" data-message="optionsInstantNavigationTrackers"></label><br>
|
||||
<input type="checkbox" id="option-block-ip-loggers"> <label for="option-block-ip-loggers" data-message="optionsBlockIPLoggers"></label><br>
|
||||
<input type="checkbox" id="option-crowd-bypass"> <label for="option-crowd-bypass" data-message="optionsCrowdBypass"></label> (<a href="https://github.com/timmyrs/Universal-Bypass/blob/master/PRIVACY.md" target="_blank" data-message="privacyPolicy"></a>)<br>
|
||||
<input type="checkbox" id="option-crowd-bypass"> <label for="option-crowd-bypass" data-message="optionsCrowdBypass"></label><br>
|
||||
<input type="checkbox" id="option-crowd-open-delay-toggle"> <span data-message="optionsCrowdAutoOpen"></span><br>
|
||||
<input type="checkbox" id="option-info-box"> <label for="option-info-box" data-message="optionsInfoBox"></label>
|
||||
</ul>
|
||||
|
201
html/options.js
201
html/options.js
@ -1,17 +1,7 @@
|
||||
//Bypass counter
|
||||
brws.storage.local.get(["bypass_counter"],res=>{
|
||||
if(res.bypass_counter>1)
|
||||
{
|
||||
const p=document.querySelector("[data-message='bypassCounter']")
|
||||
p.innerHTML=p.innerHTML.replace("%","<b>"+res.bypass_counter+"</b>")
|
||||
document.getElementById("counter").style.display="block"
|
||||
}
|
||||
})
|
||||
|
||||
//Options
|
||||
document.getElementById("version").textContent=brws.runtime.getManifest().version
|
||||
document.querySelector("[data-message='optionsNavigationDelay']").innerHTML=document.querySelector("[data-message='optionsNavigationDelay']").innerHTML.replace("%",'<input id="option-navigation-delay" type="number" min="0" max="60" skip="1" style="width:34px">')
|
||||
document.querySelector("[data-message='optionsCrowdAutoOpen']").innerHTML=document.querySelector("[data-message='optionsCrowdAutoOpen']").innerHTML.replace("%",'<input id="option-crowd-open-delay" type="number" min="0" max="60" skip="1" style="width:34px">')
|
||||
document.querySelector("[data-message='optionsUserscriptsDescription']").innerHTML=document.querySelector("[data-message='optionsUserscriptsDescription']").textContent.replace("GitHub","<a href='https://github.com/timmyrs/Universal-Bypass/blob/master/injection_script.js' target='_blank'>GitHub</a>")
|
||||
|
||||
const enabledCheckbox=document.getElementById("option-enabled"),
|
||||
enabledLabel=document.querySelector("label[for='option-enabled']"),
|
||||
navigationDelayInput=document.getElementById("option-navigation-delay"),
|
||||
@ -22,8 +12,109 @@ blockIPLoggersCheckbox=document.getElementById("option-block-ip-loggers"),
|
||||
crowdBypassCheckbox=document.getElementById("option-crowd-bypass"),
|
||||
crowdOpenDelayInput=document.getElementById("option-crowd-open-delay"),
|
||||
crowdOpenDelayCheckbox=document.getElementById("option-crowd-open-delay-toggle"),
|
||||
infoBoxCheckbox=document.getElementById("option-info-box")
|
||||
let navigationDelayInputTimer,crowdOpenDelayInputTimer
|
||||
infoBoxCheckbox=document.getElementById("option-info-box"),
|
||||
instantNavigationTrackersLogic = () => {
|
||||
if(!trackerBypassCheckbox.checked||(navigationDelayCheckbox.checked&&navigationDelayInput.value==0))
|
||||
{
|
||||
instantNavigationTrackersCheckbox.setAttribute("disabled","disabled")
|
||||
}
|
||||
else
|
||||
{
|
||||
instantNavigationTrackersCheckbox.removeAttribute("disabled")
|
||||
}
|
||||
},
|
||||
crowdOpenDelayLogic = () => {
|
||||
if(crowdOpenDelayCheckbox.checked)
|
||||
{
|
||||
crowdOpenDelayInput.removeAttribute("disabled")
|
||||
}
|
||||
else
|
||||
{
|
||||
crowdOpenDelayInput.setAttribute("disabled","disabled")
|
||||
}
|
||||
},
|
||||
defaultUserScript=`// Some examples of what you can do with custom bypasses:
|
||||
domainBypass("example.com", () => {
|
||||
// Triggered on example.com and subdomains (e.g. www.example.com)
|
||||
ensureDomLoaded(() => {
|
||||
// Triggered as soon as the DOM is ready
|
||||
// You can use ifElement to check if an element is available via document.querySelector:
|
||||
ifElement("a#skip_button[href]", a => {
|
||||
safelyNavigate(a.href)
|
||||
// safelyNavigate makes sure the given URL is valid
|
||||
}, () => {
|
||||
// Optional function to be called if the given element is not available
|
||||
})
|
||||
})
|
||||
// You can also use awaitElement to wait until an element is available via a query selector:
|
||||
awaitElement("a#skip_button[href]", a => {
|
||||
safelyNavigate(a.href)
|
||||
})
|
||||
})
|
||||
domainBypass(/example\\.(com|org)/, () => {
|
||||
// Triggered if the regex matches any part of the hostname
|
||||
})
|
||||
hrefBypass(/example\\.(com|org)/, () => {
|
||||
// Triggered if the regex matches any part of the URL
|
||||
})
|
||||
// Enjoy! Your changes will be saved automatically.
|
||||
`
|
||||
|
||||
let navigationDelayInputTimer,crowdOpenDelayInputTimer,saveTimer,updating=false,
|
||||
hash=location.hash.toString().replace("#","")
|
||||
editor=ace.edit("userscript",{mode:"ace/mode/javascript",theme:"ace/theme/monokai"})
|
||||
|
||||
if(hash)
|
||||
{
|
||||
document.querySelector("[for='"+hash+"']").className="highlight"
|
||||
}
|
||||
|
||||
brws.runtime.sendMessage({type: "options"}, res => {
|
||||
document.getElementById("version").textContent=brws.runtime.getManifest().version+"-"+(res.upstreamCommit?res.upstreamCommit.substr(0,7):"dev")
|
||||
document.querySelector("[data-message-nbsp='update']").onclick=()=>{
|
||||
if(updating)
|
||||
{
|
||||
return
|
||||
}
|
||||
updating=true
|
||||
let port=brws.runtime.connect({name: "update"})
|
||||
port.onMessage.addListener(res => {
|
||||
document.getElementById("version").textContent=brws.runtime.getManifest().version+"-"+(res.upstreamCommit?res.upstreamCommit.substr(0,7):"dev")
|
||||
let e=document.querySelector("[data-message='update"+(res.success?"Yes":"No")+"']")
|
||||
e.style.display="block"
|
||||
setTimeout(()=>{
|
||||
e.style.display="none"
|
||||
updating=false
|
||||
},3000)
|
||||
port.disconnect()
|
||||
})
|
||||
}
|
||||
if(res.bypassCounter > 1)
|
||||
{
|
||||
const p=document.querySelector("[data-message='bypassCounter']")
|
||||
p.innerHTML=p.innerHTML.replace("%","<b>"+res.bypassCounter+"</b>")
|
||||
document.getElementById("counter").style.display="block"
|
||||
}
|
||||
if(res.userScript)
|
||||
{
|
||||
editor.setValue(res.userScript)
|
||||
}
|
||||
else
|
||||
{
|
||||
editor.setValue(defaultUserScript)
|
||||
}
|
||||
editor.resize()
|
||||
editor.clearSelection()
|
||||
editor.on("change", ()=>{
|
||||
clearInterval(saveTimer)
|
||||
saveTimer=setTimeout(()=>{
|
||||
brws.storage.local.set({
|
||||
userscript: editor.getValue()
|
||||
})
|
||||
},500)
|
||||
})
|
||||
})
|
||||
|
||||
brws.storage.sync.get(["disable","navigation_delay","no_tracker_bypass","no_instant_navigation_trackers","allow_ip_loggers","crowd_bypass_opt_out","crowd_open_delay","no_info_box"],res=>{
|
||||
if(res==undefined)
|
||||
{
|
||||
@ -167,85 +258,3 @@ brws.storage.sync.get(["disable","navigation_delay","no_tracker_bypass","no_inst
|
||||
})
|
||||
}
|
||||
})
|
||||
function instantNavigationTrackersLogic()
|
||||
{
|
||||
if(!trackerBypassCheckbox.checked||(navigationDelayCheckbox.checked&&navigationDelayInput.value==0))
|
||||
{
|
||||
instantNavigationTrackersCheckbox.setAttribute("disabled","disabled")
|
||||
}
|
||||
else
|
||||
{
|
||||
instantNavigationTrackersCheckbox.removeAttribute("disabled")
|
||||
}
|
||||
}
|
||||
function crowdOpenDelayLogic()
|
||||
{
|
||||
if(crowdOpenDelayCheckbox.checked)
|
||||
{
|
||||
crowdOpenDelayInput.removeAttribute("disabled")
|
||||
}
|
||||
else
|
||||
{
|
||||
crowdOpenDelayInput.setAttribute("disabled","disabled")
|
||||
}
|
||||
}
|
||||
|
||||
//Highlight option from hash
|
||||
let hash=location.hash.toString().replace("#","")
|
||||
if(hash)
|
||||
{
|
||||
document.querySelector("[for='"+hash+"']").className="highlight"
|
||||
}
|
||||
|
||||
//Custom Bypasses
|
||||
var example=`// Some examples of what you can do with custom bypasses:
|
||||
domainBypass("example.com", () => {
|
||||
// Triggered on example.com and subdomains (e.g. www.example.com)
|
||||
ensureDomLoaded(() => {
|
||||
// Triggered as soon as the DOM is ready
|
||||
// You can use ifElement to check if an element is available via document.querySelector:
|
||||
ifElement("a#skip_button[href]", a => {
|
||||
safelyNavigate(a.href)
|
||||
// safelyNavigate makes sure the given URL is valid
|
||||
}, () => {
|
||||
// Optional function to be called if the given element is not available
|
||||
})
|
||||
})
|
||||
// You can also use awaitElement to wait until an element is available via a query selector:
|
||||
awaitElement("a#skip_button[href]", a => {
|
||||
safelyNavigate(a.href)
|
||||
})
|
||||
})
|
||||
domainBypass(/example\\.(com|org)/, () => {
|
||||
// Triggered if the regex matches any part of the hostname
|
||||
})
|
||||
hrefBypass(/example\\.(com|org)/, () => {
|
||||
// Triggered if the regex matches any part of the URL
|
||||
})
|
||||
// Enjoy! Your changes will be saved automatically.
|
||||
`,saveTimer,editor=ace.edit("userscript",{mode:"ace/mode/javascript",theme:"ace/theme/monokai"}),
|
||||
span=document.querySelector("[data-message='optionsUserscriptsDescription']")
|
||||
span.innerHTML=span.textContent.replace("GitHub","<a href='https://github.com/timmyrs/Universal-Bypass/blob/master/content_script.js' target='_blank'>GitHub</a>")
|
||||
brws.storage.local.get(["userscript"],res=>{
|
||||
if(res&&res.userscript)
|
||||
{
|
||||
editor.setValue(res.userscript)
|
||||
}
|
||||
else
|
||||
{
|
||||
editor.setValue(example)
|
||||
brws.storage.local.set({
|
||||
userscript: example
|
||||
})
|
||||
}
|
||||
editor.resize()
|
||||
editor.clearSelection()
|
||||
editor.on("change", ()=>{
|
||||
clearInterval(saveTimer)
|
||||
saveTimer=setTimeout(()=>{
|
||||
brws.storage.local.set({
|
||||
userscript: editor.getValue()
|
||||
})
|
||||
},500)
|
||||
})
|
||||
})
|
||||
|
@ -15,6 +15,7 @@
|
||||
"version_name": "12.0-dev",
|
||||
"author": "Tim \"timmyRS\" Speckhals",
|
||||
"permissions": [
|
||||
"alarms",
|
||||
"storage",
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
|
Loading…
x
Reference in New Issue
Block a user