Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name FanfictionQomplete
- // @description Proper multi-chapter reading mode with less clutter.
- // @namespace https://greasyfork.org/en/users/11891-qon
- // @author Qon
- // @include https://www.fanfiction.net/s/*/*
- // @include https://www.fanfiction.net/r/*/*
- // @include https://www.fictionpress.com/s/*/*
- // @include https://www.fimfiction.net/story/*/*
- // @include http://www.fimfiction.net/story/*/*
- // @compatible firefox
- // @compatible chrome
- // @noframes
- // @grant GM_xmlhttpRequest
- // @grant GM_getValue
- // @grant GM_setValue
- // @run-at document-start
- // @license Simple Public License 2.0 (SimPL) https://tldrlegal.com/license/simple-public-license-2.0-%28simpl%29
- // ==/UserScript==
- // javascript:var script=document.createElement("script");var t=new Date(Date());script.src="https://greasyfork.org/en/scripts/10182-fanfictionqomplete/code/fanfictionqomplete.js?"+t.getFullYear()+t.getMonth()+t.getDate();document.body.appendChild(script);window.setTimeout(function(){document.runFFQomplete();},500);
- /*
- TODO
- --Font size
- Minimize Qontrol panel or something to reduce button amount
- Add support for other sites
- fimfiction.com chapter selector
- Change width by dragging the border? and position?
- Add copies of all links at the end of a fanfic.
- Save scroll, because the browser built in one doesn't work between browser restarts
- */
- var live = true
- polyfill()
- var siteMatch = /^.*?www\.(.*?)\..*?\//.exec(document.location.href)[1]
- var hash_settings = document.location.hash.slice(1).split('&')
- if(hash_settings.map(c=>c.split('=')[0]).includes('Qomplete')) {
- checkForBadJavascripts ([
- [true, /static\.fimfiction\.net\/js\/scripts\.js\?uupAcQPf/, null]
- ,[false, /\$\(window\)\.scroll\( function\(e\)/ /*)*/, null]])
- window.addEventListener('load', runFFQomplete)}
- else {window.addEventListener('load', injectQompleteButton)}
- function injectQompleteButton() {
- switch(siteMatch){
- case 'fimfiction':
- var lc = document.getElementById('chapter_title')
- lc = lc&&lc.parentNode
- lc = lc&&lc.getElementsByClassName('button-group')[0]
- var btn = document.createElement('a')
- btn.addEventListener('click', runFFQomplete)
- btn.setAttribute('class', 'styled_button styled_button_grey button-icon-only')
- btn.setAttribute('title', 'Append all following chapters and remove unecessary bloat.')
- btn.innerHTML = 'Qomplete!'
- lc.insertBefore(btn,lc.lastChild.previousSibling)
- break;
- case 'fanfiction':
- case 'fictionpress':
- var lc = document.getElementsByClassName('lc')[0] || document.getElementById('gui_table1i').firstElementChild.firstElementChild.firstElementChild
- var btn = document.createElement('button')
- // btn.setAttribute('onclick', 'runFFQomplete();')
- btn.addEventListener('click', runFFQomplete)
- btn.setAttribute('class', 'btn')
- btn.setAttribute('style', 'margin-left:12px;margin-right:2px;')
- btn.setAttribute('title', 'Append all following chapters and remove unecessary bloat.')
- btn.innerHTML = 'Qomplete!'
- lc.appendChild(btn)
- break;
- }}
- function runFFQomplete() {
- // Add the loaded settings to url bar so that they don't get changed for this tab if the settings are changed elsewhere.
- var settings = readSettings()
- saveSettings(settings)
- var re = getChapRE()
- // TODO remove vvv?
- window.addEventListener('load', ()=>{
- var a = document.getElementsByClassName('skiptranslate')
- for (; a.length; a[0].remove());
- document.body.removeAttribute('style')})
- // Initialisations
- var appendedNow = 1
- var notAppendedYet = 0
- var chapArr = []
- var activeChap = parseInt(urlGetChap(document.location.href))
- // Grab the elements we want
- var title = document.getElementsByTagName('title')[0]
- var profile_top = getProfileTop()
- var ficpic = profile_top&&profile_top.getElementsByTagName('img')[0]
- var statusComplete = !!(/Status: Complete/.exec(profile_top&&profile_top.innerHTML))
- var chap_select = document.getElementById('chap_select')
- var latestChap = getLatestChap()
- var favicons = getFavicons()
- var chap = chapFromPage(document.location.href, document) // Get the chapter that is already loaded
- clean()
- // Now, add items. The ones we kept and modified and new ones.
- addStyle()
- title.innerHTML = fixTitleText(title.innerHTML)
- document.head.appendChild(title)
- for (i=0;i<favicons.length;i+=1) {document.head.appendChild(favicons[i])}
- if(ficpic){dataURLify(ficpic)} // window.addEventListener('load_image',load_image,false); // Make sure image has properly loaded
- addProgressBar()
- updateLoading(activeChap - 1, appendedNow, notAppendedYet, latestChap)
- addProfile()
- addQontrolPanel()
- document.body.appendChild(chap)
- addFollowingChapters()
- console.log('WQDSAD')
- function addFollowingChapters(){
- console.log('SADASD')
- for (i = activeChap; i < latestChap; i += 1)
- appendChapterFromURL(urlSetChap(document.location.href, i + 1));
- if (activeChap == latestChap) {
- loadQomplete()}
- else {
- appendNextChap(activeChap + 1)}}
- function addQontrolPanel(){
- var panel = document.createElement('div')
- panel.setAttribute('class', 'panel')
- addButtons(panel)
- document.getElementById('profile').firstChild.appendChild(panel)}
- function getLatestChap(){
- if(siteMatch==='fanfiction'||siteMatch==='fictionpress'){
- var lc = chap_select ? chap_select.children.length : 1
- console.log('JHHLL:License')
- if(/(?:fanfiction\.net|fictionpress\.com)\/r/.test(document.location.href)) {
- var as = document.getElementById('content_wrapper_inner').firstElementChild.nextElementSibling
- if(as) lc = [].slice.call(as.getElementsByTagName('a')).map(q=>urlGetChap(q.href)).reduce((p,q)=>Math.max(p,q),1)
- }
- return lc
- }
- if(siteMatch==='fimfiction') {
- try {
- return document.getElementById('chapter_format').getElementsByClassName('title')[0].getElementsByTagName('ul')[0].getElementsByTagName('li').length }
- catch (e) {}}}
- function getChapRE(){if(siteMatch==='fanfiction'||siteMatch==='fictionpress'||siteMatch==='fimfiction') return /(^.*?\/.*?\/\d+\/(?:.*\/)?)(\d+)(\/?[^#]*)/}
- function getProfileTop() {
- if(siteMatch==='fanfiction'||siteMatch==='fictionpress'){return document.getElementById('profile_top')}
- if(siteMatch==='fimfiction') {return document.getElementsByClassName('inner')[0]}}
- function getFavicons() {
- return [].slice.call(document.head.getElementsByTagName('link')).filter(c=>(/favicon/.test(c.href)))}
- function readSettings() {
- var settings = {Qomplete:1}
- var parr = ['center','bgcol','edge','width','fontsz']
- if(live){
- for(var i in parr) {
- settings[parr[i]] = GM_getValue(parr[i],0)}}
- var hash_settings = document.location.hash.slice(1).split('&')
- for(var i=0; i<hash_settings.length; ++i){
- var kv = hash_settings[i].split('=')
- if(parr.includes(kv[0])) {
- settings[kv[0]] = parseInt(kv[1])}}
- return settings}
- function saveSettings(o) {
- var q = []
- var parr = ['Qomplete','center','bgcol','edge','width','fontsz']
- for(var k in o) {
- if(o.hasOwnProperty(k) && parr.includes(k)) {
- if(live) {GM_setValue(k,o[k])}
- q.push(k+'='+o[k])}}
- window.location = '#'+q.join('&')}
- function addProgressBar(){
- var loadwrap = document.createElement('div')
- loadwrap.setAttribute('class', 'wrap')
- loadwrap.style.position = 'sticky'
- loadwrap.style.top = '0px'
- var loading = document.createElement('div')
- loading.style.float = 'left'
- loading.setAttribute('id', 'loading')
- loadwrap.appendChild(loading)
- document.body.appendChild(loadwrap)}
- function addProfile(){
- var profile = document.createElement('div')
- profile.setAttribute('class', 'wrap profile')
- profile.setAttribute('id', 'profile')
- var pad = document.createElement('div')
- pad.setAttribute('class', 'pad')
- if(profile_top) pad.appendChild(profile_top)
- profile.appendChild(pad)
- document.body.appendChild(profile)}
- function dataURLify(img){
- // http://pastebin.ca/1425789
- // Simple function that checks for JPG, GIF and PNG from image data. Otherwise returns false.
- function mime_from_data(data) {
- if ('GIF' ==data.substr(0,3))return 'image/gif';
- else if('PNG' ==data.substr(1,3))return 'image/png';
- else if('JFIF'==data.substr(6,4))return 'image/jpg';
- return false; }
- // Generates the binary data string from character / multibyte data
- function data_string(data) {
- var data_string='';
- for(var i=0,il=data.length;i<il;i++)data_string+=String.fromCharCode(data[i].charCodeAt(0)&0xff);
- return data_string; }
- function load_image(tries) {
- GM_xmlhttpRequest({
- method: 'GET',
- url: img.src,
- overrideMimeType: 'text/plain; charset=x-user-defined',
- onload: function(xhr) {
- var data = data_string(xhr.responseText);
- if(mime_from_data(data)) {
- var base64_data = btoa(data); // Encode to base64 string
- var data_url = 'data:' + mime_from_data(data) + ';base64,' + base64_data; // Make the data url
- img.src = data_url }
- else if (tries>0) {
- load_image(tries-1) }}})}
- load_image(5)}
- function urlGetChap(url) {
- var arr = re.exec(url)
- return arr&&arr[2]||1}
- function urlSetChap(url, n) {
- var arr = re.exec(url)
- if(!arr) {
- arr = re.exec(url+'0/1/')
- if(/(?:fanfiction\.net|fictionpress\.com)\/r/.test(document.location.href)) {
- arr[1] = arr[1] + arr[1].split('\/').length==5?'':'0\/'
- }
- }
- return arr[1] + n + ((siteMatch==='fimfiction') ? arr[3] : arr[3].replace(/\/[^\/]*$/, ""))}
- function inc(url) {
- var arr = re.exec(url)
- return urlSetChap(url, ++parseInt(urlGetChap(url))) }
- function chapFromPage(url, page) {
- var storytext;
- if(siteMatch==='fanfiction'||siteMatch==='fictionpress'){
- storytext = page.getElementById('storytext') || page.getElementById('gui_table1i').firstElementChild.nextElementSibling }
- else if(siteMatch==='fimfiction') {
- storytext = page.getElementsByClassName('chapter_content')[0]
- storytext.style = ''
- var styles = storytext.getElementsByTagName('style')
- for(style of styles) {
- style.remove()}}
- if( storytext) {
- // var ps = storytext.getElementsByTagName('p'), d = 0; for (q of ps) {q.style.color = 'hsl(' + d + ' ,20%, 80%)'; q.innerHTML = q.innerHTML.replace(/([\.,?!])/g, '<span style="color:hsl(' + d + ' ,100%, 50%);">$1</span>'); d = (d + 1 / ps.length * 360) % 360}
- var wrap = page.createElement('div')
- wrap.setAttribute('class', 'wrap col')
- wrap.setAttribute('id', urlGetChap(url))
- var pad = page.createElement('div')
- pad.setAttribute('class', 'pad')
- var chapdiv = page.createElement('div')
- chapdiv.setAttribute('class', 'chapter')
- var chapspan = page.createElement('span')
- chapspan.innerHTML = urlGetChap(url) + '. '
- var title = page.getElementsByTagName('title')[0]
- var chaptitle = page.createElement('a')
- chaptitle.setAttribute('href', url.replace(/#.*$/, ""))
- chaptitle.setAttribute('class', 'external')
- if (siteMatch==='fanfiction' || siteMatch==='fictionpress') {
- var newChapTitle = /(.*(| [Cc]hapter [^:]+: .*)), a .*/.exec(title.innerHTML)}
- else if(siteMatch==='fimfiction') {
- var newChapTitle = /(.*) - FIMFiction.net/.exec(title.innerHTML)}
- chaptitle.innerHTML = newChapTitle ? newChapTitle[1] : title.innerHTML
- chapdiv.appendChild(chapspan)
- chapdiv.appendChild(chaptitle)
- chapdiv.appendChild(document.createElement('hr'))
- chapdiv.appendChild(storytext)
- pad.appendChild(chapdiv)
- wrap.appendChild(pad)
- return wrap
- }
- else return null}
- function clean(){
- var ptbuttons = profile_top&&profile_top.getElementsByTagName('button')
- if (ptbuttons&&ptbuttons.length) {ptbuttons[0].remove()}
- for (; document.head.firstElementChild;) document.head.firstElementChild.remove();
- for (; document.body.firstElementChild;) document.body.firstElementChild.remove();
- document.body.removeAttribute('style')}
- function addStyle(){
- var style = document.createElement('style')
- style.setAttribute('type', 'text/css')
- style.innerHTML =
- `body{background-color:#000;color:#ccc;margin:0;padding:0;font-family:"Verdana";}
- ul.tags > li{display:inline;}
- ul.tags > li::before{content:" #"}
- #loading{position:inherit;width:100%;height:5px;}
- button, select{border-radius:4px;padding:4px 12px;background: linear-gradient(to bottom, #333, #000);border-width: 1px;color:#ccc;background-color:#000;}
- button:hover{background-image:none;}
- .panel{text-align:center;}
- a.external, option.external{background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFZJREFUeF59z4EJADEIQ1F36k7u5E7ZKXeUQPACJ3wK7UNokVxVk9kHnQH7bY9hbDyDhNXgjpRLqFlo4M2GgfyJHhjq8V4agfrgPQX3JtJQGbofmCHgA/nAKks+JAjFAAAAAElFTkSuQmCC") no-repeat scroll right center;padding-right: 13px;}
- div.wrap{max-width:1300px;margin:auto;padding:0px 5px 0px 5px;}
- div.wrap:nth-of-type(2){padding-top:5px;margin-top:50px;}
- div.wrap:last-child{padding-bottom:5px;margin-bottom:50px;}
- div.pad{background-color:#222;padding:50px;}
- .chapter{}#profile_top{}img{float:left;}canvas{float:left;}
- a:link{color:#555;}a:visited{color:#555;}a:hover{color:#aaa;}a:active{color:#aaa;}
- option{}
- option:nth-of-type(6n+1)::before{content:"";padding-left:3px;margin-left:-3px;margin-right:4px;background:linear-gradient(to bottom, #f00, #ff0);}
- option:nth-of-type(6n+2)::before{content:"";padding-left:3px;margin-left:-3px;margin-right:4px;background:linear-gradient(to bottom, #ff0, #0f0);}
- option:nth-of-type(6n+3)::before{content:"";padding-left:3px;margin-left:-3px;margin-right:4px;background:linear-gradient(to bottom, #0f0, #0ff);}
- option:nth-of-type(6n+4)::before{content:"";padding-left:3px;margin-left:-3px;margin-right:4px;background:linear-gradient(to bottom, #0ff, #00f);}
- option:nth-of-type(6n+5)::before{content:"";padding-left:3px;margin-left:-3px;margin-right:4px;background:linear-gradient(to bottom, #00f, #f0f);}
- option:nth-of-type(6n+0)::before{content:"";padding-left:3px;margin-left:-3px;margin-right:4px;background:linear-gradient(to bottom, #f0f, #f00);}
- .col:nth-of-type(6n+${((4-activeChap+60000)%6)}){background-color:#f00;background:linear-gradient(to bottom, #f00, #ff0);}
- .col:nth-of-type(6n+${((5-activeChap+60000)%6)}){background-color:#ff0;background:linear-gradient(to bottom, #ff0, #0f0);}
- .col:nth-of-type(6n+${((6-activeChap+60000)%6)}){background-color:#0f0;background:linear-gradient(to bottom, #0f0, #0ff);}
- .col:nth-of-type(6n+${((7-activeChap+60000)%6)}){background-color:#0ff;background:linear-gradient(to bottom, #0ff, #00f);}
- .col:nth-of-type(6n+${((8-activeChap+60000)%6)}){background-color:#00f;background:linear-gradient(to bottom, #00f, #f0f);}
- .col:nth-of-type(6n+${((9-activeChap+60000)%6)}){background-color:#f0f;background:linear-gradient(to bottom, #f0f, #f00);}
- @media (max-width: 700px) {div.wrap{padding-left:1px;padding-right:1px;} div.pad{padding-left:5px;padding-right:5px;}}
- ${['.profile{background-color:#777;background:linear-gradient(to bottom, #fff, #f0f);}'
- ,'.profile{background-color:#777;background:linear-gradient(to bottom, #fff, #f00);}'
- ,'.profile{background-color:#777;background:linear-gradient(to bottom, #fff, #ff0);}'
- ,'.profile{background-color:#777;background:linear-gradient(to bottom, #fff, #0f0);}'
- ,'.profile{background-color:#777;background:linear-gradient(to bottom, #fff, #0ff);}'
- ,'.profile{background-color:#777;background:linear-gradient(to bottom, #fff, #00f);}'][urlGetChap(document.location.href) % 6]}`
- document.head.appendChild(style)}
- function fixTitleText(titleText){
- if(siteMatch==='fanfiction') {
- var settitle = /(.*?)(?:[Cc]hapter .*, a |, a )(.*) fanfic \| FanFiction/
- var storyname = settitle.exec(titleText)
- if(storyname) {
- return storyname[1]
- +(statusComplete&&activeChap==1?' - Qomplete':(' - chapter '+activeChap+(latestChap!=activeChap?'-'+latestChap:'')))
- +' - '+storyname[2]}}
- if(siteMatch==='fictionpress') {
- var settitle = /(.*?)(?:[Cc]hapter .*, a |, a )(.*) fiction \| FictionPress/
- var storyname = settitle.exec(titleText)
- if(storyname) {
- return storyname[1]
- +(statusComplete&&activeChap==1?' - Qomplete':(' - chapter '+activeChap+(latestChap!=activeChap?'-'+latestChap:'')))
- +' - '+storyname[2]}}
- if(siteMatch==='fimfiction') {
- var settitle = /.* - (.*) - FIMFiction.net/
- var storyname = settitle.exec(titleText)
- if(storyname) {
- return storyname[1] + (' - chapter '+activeChap+(latestChap!=activeChap?'-'+latestChap:''))}}}
- function updateLoading(ignore, appended, downloaded, total) {
- var loading = document.getElementById('loading')
- var p0 = parseInt(ignore / total * 100)
- var p1 = parseInt((appended + ignore) / total * 100)
- if (p1 == 100) {
- setTimeout(function() {
- loading.style.display = 'none'
- }, (activeChap != latestChap) * 100)
- }
- var p2 = parseInt((downloaded + appended + ignore) / total * 100)
- loading.style.background = `linear-gradient(to right, white 0%, #555 ${p0/2}%, white ${p0}%, lime ${p0}%, lime ${p1}%, blue ${p1}%, blue ${p2}%, white ${p2}%, white 100%)`}
- function addButtons(panel){
- var posbtn = document.createElement('button')
- posbtn.setAttribute('id', 'posbtn')
- function centerclick() {
- var settings = readSettings()
- var e = document.getElementById('position-style')
- if (e) {
- if (e.innerHTML == 'div.wrap{margin-left:0px;}') {
- settings.center = 2
- e.innerHTML = 'div.wrap{margin-right:0px;}'
- document.getElementById('posbtn').innerHTML = 'Right'}
- else {
- settings.center = 0
- e.remove()
- document.getElementById('posbtn').innerHTML = 'Centered'}}
- else {
- settings.center = 1
- var s = document.createElement('style')
- s.setAttribute('id', 'position-style')
- s.innerHTML = 'div.wrap{margin-left:0px;}'
- document.head.appendChild(s)
- document.getElementById('posbtn').innerHTML = 'Left'}
- saveSettings(settings)}
- posbtn.setAttribute('onclick', 'centerclick()')
- posbtn.setAttribute('class', 'center;')
- posbtn.innerHTML = 'Centered'
- var bgcolbtn = document.createElement('button')
- bgcolbtn.setAttribute('id', 'bgcolbtn')
- function bgcolclick() {
- var settings = readSettings()
- var e = document.getElementById('bgcol-style')
- if (e) {
- if (e.innerHTML == 'body{color:#000;}a:hover{color:#000;}div.pad{background-color:#fff;}') {
- settings.bgcol = 2
- e.innerHTML = 'body{color:#fff;}div.pad{background-color:#000;}'
- document.getElementById('bgcolbtn').innerHTML = 'Black'}
- else {
- settings.bgcol = 0
- e.remove()
- document.getElementById('bgcolbtn').innerHTML = 'Dark'}}
- else {
- settings.bgcol = 1
- var s = document.createElement('style')
- s.setAttribute('id', 'bgcol-style')
- s.innerHTML = 'body{color:#000;}a:hover{color:#000;}div.pad{background-color:#fff;}'
- document.head.appendChild(s)
- document.getElementById('bgcolbtn').innerHTML = 'White'}
- saveSettings(settings)}
- bgcolbtn.setAttribute('onclick', 'bgcolclick()')
- bgcolbtn.setAttribute('style', 'float:left;')
- bgcolbtn.innerHTML = 'Dark'
- var edgebtn = document.createElement('button')
- edgebtn.setAttribute('id', 'edgebtn')
- function edgeclick() {
- var settings = readSettings()
- var e = document.getElementById('edge-style')
- if (e) {
- settings.edge = 0
- e.remove()
- document.getElementById('edgebtn').innerHTML = 'Rainbow'}
- else {
- settings.edge = 1
- var s = document.createElement('style')
- s.setAttribute('id', 'edge-style')
- s.innerHTML = '.col:nth-of-type(n){background-color:#333;background:#333;}.profile{background-color:#333;background:linear-gradient(to bottom, #fff, #333);}'
- document.head.appendChild(s)
- document.getElementById('edgebtn').innerHTML = 'Edge: Gray'}
- saveSettings(settings)}
- edgebtn.setAttribute('onclick', 'edgeclick()')
- edgebtn.setAttribute('style', 'float:left;')
- edgebtn.innerHTML = 'Rainbow'
- var widthbtn = document.createElement('button')
- widthbtn.setAttribute('id', 'widthbtn')
- function widthclick() {
- var settings = readSettings()
- var e = document.getElementById('width-style')
- if (e) {
- if (e.innerHTML == 'div.wrap{max-width:777px;}') {
- settings.width = 2
- e.innerHTML = 'div.wrap{max-width:100%;}'
- document.getElementById('widthbtn').innerHTML = 'Wide'}
- else {
- settings.width = 0
- e.remove()
- document.getElementById('widthbtn').innerHTML = 'Width: Default'}}
- else {
- settings.width = 1
- var s = document.createElement('style')
- s.setAttribute('id', 'width-style')
- s.innerHTML = 'div.wrap{max-width:777px;}'
- document.head.appendChild(s)
- document.getElementById('widthbtn').innerHTML = 'Narrow'}
- saveSettings(settings)}
- widthbtn.setAttribute('onclick', 'widthclick()')
- widthbtn.setAttribute('class', 'center')
- widthbtn.innerHTML = 'Width: Default'
- var fontszSelect = document.createElement('select')
- fontszSelect.setAttribute('id', 'fontzsselect');
- fontszSelect.setAttribute('style', 'float:left;')
- function setFontSize(pt) {
- var settings = readSettings()
- settings.fontsz = pt||0
- saveSettings(settings)
- var e = document.getElementById('fontsz-style')
- if(pt!=0 && pt!=null && pt!=''){
- var css = `body{font-size:${pt}pt}`
- if (!e) {
- e = document.createElement('style')
- e.setAttribute('id', 'fontsz-style')
- document.head.appendChild(e)}
- e.innerHTML = css}
- else {
- if(e) e.remove()}}
- for(var i = 0; i<=50; i+=1){
- var option = document.createElement('option')
- if(i==settings.fontsz){option.setAttribute('selected','')}
- // option.setAttribute('style',`font-size:${i==0?12:Math.max(3,i)}pt;`)
- option.value = i.toString()
- option.innerHTML = `${i||''}pt`
- fontszSelect.appendChild(option)}
- // fontszSelect.setAttribute('style', `max-height:4em; padding-top:-8em;`)
- fontszSelect.setAttribute('onchange', `setFontSize(this.options[this.selectedIndex].value)`)
- function setSettings(){
- polyfill()
- var live = false
- var e,settings = readSettings()
- if((e=document.getElementById('position-style'))&&settings.center!=null) {e.remove(); document.getElementById('posbtn').innerHTML='Centered'}
- if((e=document.getElementById('bgcol-style'))&&settings.bgcol!=null) {e.remove(); document.getElementById('bgcolbtn').innerHTML='Dark'}
- if((e=document.getElementById('edge-style'))&&settings.edge!=null) {e.remove(); document.getElementById('edgebtn').innerHTML='Rainbow'}
- if((e=document.getElementById('width-style'))&&settings.width!=null) {e.remove(); document.getElementById('widthbtn').innerHTML='Width: Default'}
- for(var i=0; i<settings.center; ++i) {setTimeout(centerclick,0)}
- for(var i=0; i<settings.bgcol; ++i) {setTimeout(bgcolclick,0)}
- for(var i=0; i<settings.edge; ++i) {setTimeout(edgeclick,0)}
- for(var i=0; i<settings.width; ++i) {setTimeout(widthclick,0)}
- setTimeout(setFontSize.bind(null,settings.fontsz),0)}
- var scripttag = document.createElement('script')
- scripttag.setAttribute('id','button-helper')
- scripttag.innerHTML = [
- ,polyfill.toString()
- ,setSettings.toString().slice(23,-1)
- ,readSettings.toString()
- ,saveSettings.toString()
- ,centerclick.toString()
- ,bgcolclick.toString()
- ,edgeclick.toString()
- ,widthclick.toString()
- ,setFontSize.toString()
- ].join('\n')
- posbtn.addEventListener('click',_=>saveSettings(readSettings()))
- widthbtn.addEventListener('click',_=>saveSettings(readSettings()))
- bgcolbtn.addEventListener('click',_=>saveSettings(readSettings()))
- edgebtn.addEventListener('click',_=>saveSettings(readSettings()))
- fontszSelect.addEventListener('change',_=>saveSettings(readSettings()))
- panel.appendChild(posbtn)
- panel.appendChild(widthbtn)
- panel.appendChild(bgcolbtn)
- panel.appendChild(edgebtn)
- panel.appendChild(fontszSelect)
- document.body.appendChild(scripttag)
- if (chap_select) {
- chap_select.setAttribute('onchange', 'if(this.options[this.selectedIndex].value < ' + urlGetChap(document.location.href) + '){' +
- chap_select.getAttribute('onchange') +
- '}' + ' else {document.getElementById(\'\'+this.options[this.selectedIndex].value).scrollIntoView();}')
- chap_select.setAttribute('style', 'float:right;')
- var os = chap_select.getElementsByTagName('option')
- for (i = 0; i < urlGetChap(document.location) - 1; i += 1) {os[i].setAttribute('class', 'external')}
- panel.appendChild(chap_select)}}
- function loadQomplete() {
- var a = document.getElementsByClassName('skiptranslate')
- for (; a.length; a[0].remove());
- a = document.getElementsByClassName('ad_container')
- for (; a.length; a[0].remove());
- document.body.removeAttribute('style')
- updateLoading(activeChap - 1, latestChap - (activeChap - 1), 0, latestChap)}
- function appendChapterFromURL(url) {
- console.log('SCCCC')
- var oReq = new XMLHttpRequest();
- oReq.onload = function() {
- // setTimeout(function(this2){
- var this2 = this // for debug purposes, use comment above as code to simulate delays (and its matching closing part)
- var xmlDoc = new DOMParser().parseFromString(this2.responseText, "text/html")
- var url = this2.responseURL ? this2.responseURL : this2.responseURLfallback
- var chap = chapFromPage(url, xmlDoc)
- if (chap) {
- chapArr[parseInt(urlGetChap(url))] = chap
- notAppendedYet += 1
- updateLoading(activeChap - 1, appendedNow, notAppendedYet, latestChap)}
- // }, Math.random()*8000+50*urlGetChap(this.responseURL), this)
- }
- oReq.responseURLfallback = url
- oReq.open("get", url, true)
- oReq.send()}
- function appendNextChap(n) {
- if (chapArr[n]) {
- document.body.appendChild(chapArr[n])
- appendedNow += 1
- notAppendedYet -= 1
- updateLoading(activeChap - 1, appendedNow, notAppendedYet, latestChap)
- if (n < latestChap) {
- appendNextChap(n + 1)}
- else {
- loadQomplete() }}
- else {
- window.setTimeout(function() {
- appendNextChap(n)
- }, 50) }}
- }
- function polyfill(){
- if (Element.prototype.remove == undefined) {
- Element.prototype.remove = function() {
- this.parentNode.removeChild(this) } }
- if (!Array.prototype.includes) {
- Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
- 'use strict';
- var O = Object(this);
- var len = parseInt(O.length) || 0;
- if (len === 0) {return false; }
- var n = parseInt(arguments[1]) || 0;
- var k;
- if (n >= 0) {k = n; }
- else {
- k = len + n;
- if (k < 0) {k = 0;} }
- var currentElement;
- while (k < len) {
- currentElement = O[k];
- if (searchElement === currentElement || (searchElement !== searchElement && currentElement !== currentElement)) {
- return true; }
- k++; }
- return false; }; }}
- // Source for checkForBadJavascripts: https://gist.github.com/BrockA/2620135
- /*--- checkForBadJavascripts()
- This is a utility function, meant to be used inside a Greasemonkey script that
- has the "@run-at document-start" directive set.
- It Checks for and deletes or replaces specific <script> tags. */
- function checkForBadJavascripts(controlArray) {
- /*--- Note that this is a self-initializing function. The controlArray
- parameter is only active for the FIRST call. After that, it is an
- event listener.
- The control array row is defines like so:
- [bSearchSrcAttr, identifyingRegex, callbackFunction]
- Where:
- bSearchSrcAttr True to search the SRC attribute of a script tag
- false to search the TEXT content of a script tag.
- identifyingRegex A valid regular expression that should be unique
- to that particular script tag.
- callbackFunction An optional function to execute when the script is
- found. Use null if not needed.
- Usage example:
- checkForBadJavascripts ( [
- [false, /old, evil init()/, function () {addJS_Node (init);} ],
- [true, /evilExternalJS/i, null ]
- ] );
- */
- if (!controlArray.length) return null;
- checkForBadJavascripts = function(zEvent) {
- for (var J = controlArray.length - 1; J >= 0; --J) {
- var bSearchSrcAttr = controlArray[J][0];
- var identifyingRegex = controlArray[J][1];
- if (bSearchSrcAttr) {
- if (identifyingRegex.test(zEvent.target.src)) {
- stopBadJavascript(J);
- return false; } }
- else {
- if (identifyingRegex.test(zEvent.target.textContent)) {
- stopBadJavascript(J);
- return false; } } }
- function stopBadJavascript(controlIndex) {
- zEvent.stopPropagation();
- zEvent.preventDefault();
- var callbackFunction = controlArray[J][2];
- if (typeof callbackFunction == "function")
- callbackFunction(zEvent.target);
- //--- Remove the node just to clear clutter from Firebug inspection.
- zEvent.target.parentNode.removeChild(zEvent.target);
- //--- Script is intercepted, remove it from the list.
- controlArray.splice(J, 1);
- if (!controlArray.length) {
- //--- All done, remove the listener.
- window.removeEventListener(
- 'beforescriptexecute', checkForBadJavascripts, true ); } } }
- /*--- Use the "beforescriptexecute" event to monitor scipts as they are loaded.
- See https://developer.mozilla.org/en/DOM/element.onbeforescriptexecute
- Note seems to work on scripts that are dynamically created, despite what
- the spec says. */
- window.addEventListener('beforescriptexecute', checkForBadJavascripts, true);
- return checkForBadJavascripts;}
- function addJS_Node(text, s_URL, funcToRun) {
- var D = document;
- var scriptNode = D.createElement('script');
- scriptNode.type = "text/javascript";
- if (text) scriptNode.textContent = text;
- if (s_URL) scriptNode.src = s_URL;
- if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
- var targ = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
- //--- Don't error check here. if DOM not available, should throw error.
- targ.appendChild(scriptNode);}
- // element.next = function() {
- // if(this.firstChild) return this.firstChild
- // if(this.nextSibling) return this.nextSibling
- // return this.parentNode.nextSibling}
- // window.parentNode.replaceChild(window.cloneNode(false), window); var el = document; while(el) {e.parentNode.replaceChild(el.cloneNode(false), el); el = el.next()} document.head.parentNode.replaceChild(document.head.cloneNode(true), document.head); document.body.parentNode.replaceChild(document.body.cloneNode(true), document.body); var el = document.bodyj elClone = el.cloneNode(true); el.parentNode.replaceChild(elClone, el);
- // document.styleSheets[0].cssText = "";
Add Comment
Please, Sign In to add comment