您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
The original fullsize images downloader for gelbooru, and rule34
当前为
// ==UserScript== // @name ImageBoard Downloader // @description The original fullsize images downloader for gelbooru, and rule34 // @namespace https://greasyfork.org/users/155308 // @include https://gelbooru.com* // @include https://rule34.xxx* // @version 0.0.5 // @grant GM_xmlhttpRequest // ==/UserScript== /* 0.0.5 + rule34 downloader + add the imageboard name to the image name [true] 0.0.3 + gelbooru downloader + maximum tags in the image name [10] + tags delimeter in the image name ['-'] */ var clog = function(){};//console.log; var RANDOM = Math.floor(Math.random()*1e6 + 1e6); console.log('start..'); (function(){ var userOptions = initOptions(); var methodsObject = initMethodsObject(); userOptions.set({ 'maxTagsInName': 8, 'tagsDelim': ' ', 'addImgBrdName': false,// add the imageboard name to the image name }); var imageBoard = initImageBoard(); newCssClasses(); //------------------------------------------------------------------------------------// //------------------------------------- SITE LIST ------------------------------------// function initSiteList() { var retVal = { get current(){return this.currentObj.val;}, get gelbooru(){return this.data.gelbooru.val;}, get rule34(){return this.data.rule34.val;}, data: { 'gelbooru': { val: null, regexp: /gelbooru/, style: { color: '#fff', width: '180px', background: '#0773fb', backgroundHover: '#fbb307', colorHover: '#fff', }, init: function(){ this.val = this.val || initGelbooruObject(); }, name: 'gelbooru', }, 'rule34': { val: null, regexp: /rule34/, style: { color: '#fff', width: '180px', background: '#84AE83', backgroundHover: '#fff', colorHover: '#84AE83', }, init: function(){ this.val = this.val || initRule34Object(); }, name: 'rule34', }, }, getData: function( type ){ if( type === undefined || type === null ) return this.currentObj; else if( this.data[type] ) return this.data[type]; return null; }, getDataProp: function( type, prop ){ var dt = this.getData(type); if( dt && dt[prop] ) return dt[prop]; return null; }, style: function(type){ return this.getDataProp( type, 'style' ); }, val: function(type){ return this.getDataProp( type, 'val' ); }, init: function(type){ if( type === undefined || type === null ) this.initCurrent(); else if( this.data[type] ) this.data[type].init(); }, getSiteType: function(url){ url = url || window.location.href; for( var key in this.data ) { if( this.data[key].regexp.test(url) ) return key; } console.error("no site object found for this host"); return null; }, initCurrent: function(){ if( !this.currentObj ) { var type = this.getSiteType(); if( !type ) return; this.currentObj = this.data[type]; } this.currentObj.init(); }, }; retVal.init(); clog("siteList.current: ", retVal.current); return retVal; } //------------------------------------- SITE LIST ------------------------------------// //------------------------------------------------------------------------------------// //------------------------------------ IMAGE BOARD -----------------------------------// function initImageBoard( d ) { var imgBrdCl = initImageBoardClasses(d), imgBrdDt = initImageBoardDataset(d), siteList = initSiteList(), imgBrdDw = initImageBoardDownloader(d), imgBrdId = 'image-board-div-' + RANDOM; var retVal = { get siteList(){return siteList;}, get imgBrdCl(){return imgBrdCl;}, get imgBrdDt(){return imgBrdDt;}, get imgBrdId(){return imgBrdId;}, get imgBrdDw(){return imgBrdDw;}, get images(){return this.data.images;}, get downloader(){return this.data.downloader;}, data: { 'images': { list: null, init: function( doc, type ){ clog("init"); siteList.init(type); imgBrdDt.init(doc); imgBrdCl.init(doc); this.list = this.list || []; this.doc = doc || document; var thumbs = this.doc.querySelectorAll('img.preview'), siteObj = siteList.val(type); clog("siteObj: ", siteObj); var isPost = siteObj.isPost(), imgD; function addNewImage( list, img, isPost ) { list.push({}); var imgD = last(list); imgD.state = 'empty'; imgD.index = list.length - 1; imgD.type = siteObj.name; if( isPost ) siteObj.setImageDataDoc(imgD); else siteObj.setImageDataThumb( imgD, thumb ); imgBrdDt.val( img, 'index', imgD.index); imgBrdCl.addClass( img, 'counted' ); return imgD; } if( isPost ) { var img = siteObj.getPostImage(); if( img && !imgBrdCl.hasClass( img, 'counted') ) { imgD = addNewImage( this.list, img, true ); if( imgD.state === 'ready' ) { siteObj.createDiv( imgBrdId, this.doc); imgBrdDw.init(imgBrdId, this.doc); setReadyImage( imgD, imgBrdCl, imgBrdDt, imgBrdDw ); } } } for( var i = 0, len = thumbs.length, thumb; i < len; ++i ) { thumb = thumbs[i]; if( imgBrdCl.hasClass( thumb, 'counted' ) ) continue; addNewImage( this.list, thumb ); } }, getEmpty: function(){ var empty = []; for( var i = 0; i < this.list.length; ++i ) { if( this.list[i].state === 'empty' ) empty.push(i); } return empty; }, fix: function() { var empty = this.getEmpty(); for( var i = 0, idx, imgD; i < empty.length; ++i ) { idx = empty[i]; imgD = this.list[idx]; imgD.state = 'busy'; this.getImageData(imgD); } }, getImageData: function(imgD) { GM_xmlhttpRequest({ url: imgD.postUrl, method: 'GET', context: { 'index': imgD.index, }, onload: xhrImageData, }); }, }, 'downloader': { init: function(doc, type){ clog("downloader init.."); siteList.init(type); var siteObj = siteList.val(type); siteObj.createDiv( imgBrdId, doc); imgBrdDw.init(imgBrdId, doc); }, isActive: function(){ return imgBrdDw && imgBrdDw.isActive() || false; }, activate: function(doc){ clog("activate"); doc = doc || document; imgBrdCl.init(doc); var thumbs = imgBrdCl.queryAll('counted'); for( var i = 0, len = thumbs.length, thumb, a; i < len; ++i ) { thumb = thumbs[i]; a = thumb.parentNode; if( !imgBrdCl.hasClass(thumb, 'ready' ) ) continue; else if( !imgBrdCl.hasClass( a, 'downloadAttach' ) ) { a.addEventListener('click', handleDownloadEvent, false); imgBrdCl.addClass( a, 'downloadAttach' ); } imgBrdCl.addClass( a, 'downloadActive' ); } imgBrdDw.downloadOn(); }, deactivate: function(doc){ clog("deactivate"); doc = doc || document; imgBrdCl.init(doc); var activ = imgBrdCl.queryAll('downloadActive'); clog("active.length: ", activ.length); for( var i = 0, len = activ.length; i < len; ++i ) imgBrdCl.removeClass( activ[i], 'downloadActive' ); imgBrdDw.downloadOff(); }, downloadAll: function(){ imgBrdDw.downloadAll.click();// =) }, }, }, init: function(doc){ for( var key in this.data ) this.data[key].init(doc); }, fix: function(){ this.data.images.fix(); }, }; retVal.init(d); retVal.fix(); return retVal; } //------------------------------------ IMAGE BOARD -----------------------------------// //------------------------------------------------------------------------------------// //----------------------------------- XRH IMAGE DATA ---------------------------------// function xhrImageData(xhr) { if( xhr.status !== 200 ) { console.error("xhr.status: ", xhr.status, xhr.statusText ); console.error("index: ", xhr.context ? xhr.context.index : null); console.error("postUrl: ", this.url ); return; } var imgD = imageBoard.images.list[xhr.context.index]; if( !imgD || imgD.state === 'ready' ) { console.error("invalid context: ", imgD); return; } var siteObj = imageBoard.siteList.val(imgD.type); if( !siteObj ) { console.error("invalid site type: ", imgD.type); return; } var doc = document.implementation.createHTMLDocument(""); doc.documentElement.innerHTML = xhr.response; siteObj.setImageDataDoc(imgD, doc); clog("xhrImageData[" + imgD.index + "].state : " + imgD.state); if( imgD.state === 'ready' ) { setReadyImage( imgD ); } } function setReadyImage( imgD, imgBrdCl, imgBrdDt, imgBrdDw ) { if( (!imgBrdCl || !imgBrdDt || !imgBrdDw) && imageBoard ) { imgBrdCl = imageBoard.imgBrdCl; imgBrdDt = imageBoard.imgBrdDt; imgBrdDw = imageBoard.imgBrdDw; } var thumb = imgBrdDt.query('index', imgD.index + ''); imgBrdCl.addClass( thumb, 'ready' ); imgBrdDt.val( thumb, 'source', imgD.source ); if( imgD.bytes ) imgBrdDt.val( thumb, 'bytes', imgD.bytes ); imgBrdDw.total += 1; if( imageBoard && imageBoard.downloader.isActive() ) { imageBoard.downloader.activate(); } } //----------------------------------- XRH IMAGE DATA ---------------------------------// //------------------------------------------------------------------------------------// //-------------------------------------- GELBOORU ------------------------------------// function initGelbooruObject() { var retVal = { data: { name: 'gelbooru', hostname: 'gelbooru.com', }, get name(){ return this.data.name; }, get hostname(){return this.data.hostname; }, methodsMap: { getPostImage: 'booru', isPost: 'booru', getPostId: 'booru', getPostUrl: 'booru', setImageDataThumb: 'booru', setImageDataSize: 'booru', setImageDataSourceLowres: 'booru', setImageDataSourceHighres: 'booru', setImageDataTags: 'booru', setImageDataName: 'general', setImageDataExtension: 'general', setImageDataBytes: null, createDiv: 'booru', setImageDataDoc: 'general', }, init: function(){ var name, type; for( name in this.methodsMap ) { type = this.methodsMap[name]; if( type ) this[name] = methodsObject.method(type, name); } } }; retVal.init(); return retVal; } //-------------------------------------- GELBOORU ------------------------------------// //------------------------------------------------------------------------------------// //--------------------------------------- RULE34 -------------------------------------// function initRule34Object() { var retVal = { data: { name: 'rule34', hostname: 'rule34.xxx', }, get name(){ return this.data.name; }, get hostname(){return this.data.hostname; }, methodsMap: { getPostImage: 'booru', isPost: 'booru', getPostId: 'booru', getPostUrl: 'booru', setImageDataThumb: 'booru', setImageDataSize: 'booru', setImageDataSourceLowres: 'booru', setImageDataSourceHighres: 'booru', setImageDataTags: 'booru', setImageDataName: 'general', setImageDataExtension: 'general', setImageDataBytes: null, createDiv: 'booru', setImageDataDoc: 'general', }, init: function(){ var name, type; for( name in this.methodsMap ) { type = this.methodsMap[name]; if( type ) this[name] = methodsObject.method(type, name); } } }; retVal.init(); return retVal; } //--------------------------------------- RULE34 -------------------------------------// //------------------------------------------------------------------------------------// //----------------------------------- METHODS OBJECT ---------------------------------// function initMethodsObject() { var retVal = { data: { 'booru': { val: null, init: function(){ this.val = this.val || getBooruMethodsObject(); }, }, 'general': { val: null, init: function(){ this.val = this.val || getGeneralMethodsObject(); }, }, }, init: function(){ for( var type in this.data ) this.data[type].init(); }, method: function( type, name ){ if( this.data[type] ) { if( name ) return this.data[type].val[name]; return this.data[type].val; } return null; }, }; retVal.init(); return retVal; } function getBooruMethodsObject() { var retVal = { getPostImage: function(doc){ return (doc || document).querySelector('#image'); }, setImageDataThumb: function( imgD, thumb ){ if( thumb && imgD ) { if( thumb.dataset && thumb.dataset.original ) imgD.thumbSource = thumb.dataset.original; else imgD.thumbSource = thumb.src; imgD.postUrl = thumb.parentNode.href; imgD.postId = thumb.parentNode.id.slice(1); } }, setImageDataSourceLowres: function( imgD, doc ){ var img = this.getPostImage(doc); if( img ) imgD.lowresSource = img.src; else return 1; return 0; }, setImageDataSize: function( imgD, doc ){ doc = doc || document; var lis = doc.querySelectorAll('li'), i, li, len = lis.length; for( i = 0; i < len; ++i ) { li = lis[i]; if( li.innerHTML.indexOf('Size:') != -1 ) break; } var match = li.innerHTML.match(/(\d+)x(\d+)/); if( i < len && match ) { imgD.width = match[1]; imgD.height = match[2]; }else console.error("[setImageDataSize] can't find image size (width x height)"); }, setImageDataSourceHighres: function( imgD, doc ){ doc = doc || document; var link = doc.querySelector('li > a[href*="' + this.hostname + '//images/"]'); if( link ) imgD.source = link.href; else if( imgD.lowresSource ) imgD.source = imgD.lowresSource; else{ console.error("[setImageDataSourceHighres] no image source found"); return 1; } }, setImageDataTags: function( imgD, doc ){ doc = doc || document; var getTagName = function( tagElm ) { return last(tagElm.querySelectorAll('a')).innerText.trim().replace(/\s+/g, '_'); }; var tagsType = ['character', 'copyright', 'artist', 'circle', 'general', 'faults']; imgD.tags = imgD.tags || []; imgD.tags.length = 0; for( var i = 0, tags; i < tagsType.length; ++i ) { tags = doc.querySelectorAll('li.tag-type-' + tagsType[i] ); for( var k = 0; tags && k < tags.length; ++k ) imgD.tags.push( getTagName(tags[k]) ); } }, isPost: function( url ){ if( this.getPostId(url) ) return true; return false; }, getPostId: function( postUrl ){ var srch = getLocation( postUrl, 'search' ), keys = getSearchObject( srch ); if( keys.s === 'view' && keys.page === 'post' ) return keys.id; else return null; }, getPostUrl: function( postId ){ return 'https://' + this.hostname + '/index.php?page=post&s=view&id=' + postId; }, createDiv: function(id, doc){ doc = doc || document; var div = doc.querySelector('#' + id); if( div ) return div; div = document.createElement('div'); var insertPlace; if( this.isPost() ) { insertPlace = doc.querySelector('h4 > a#showCommentBox');// gelbooru if( !insertPlace ) insertPlace = doc.querySelector('h4 > a');// rule34 if( insertPlace ) insertPlace = insertPlace.parentNode; else return null; }else{ insertPlace = doc.querySelector('.contain-push > div');// gelbooru if( !insertPlace ) insertPlace = doc.querySelector('div#top');// rule34 if( insertPlace ) insertPlace = insertPlace.nextSibling; else return null; } clog("insertPlace: ", insertPlace); div.setAttribute('id', id); return insertPlace.parentNode.insertBefore( div, insertPlace); }, }; return retVal; } function getGeneralMethodsObject() { var retVal = { setImageDataDoc: function( imgD, doc ){ if( !imgD || imgD.state === 'ready' ) return 1; doc = doc || document; // size this.setImageDataSize( imgD, doc ); // lowres var errN = this.setImageDataSourceLowres( imgD, doc ); // highres errN += this.setImageDataSourceHighres( imgD, doc ); if( errN > 1 ) return errN; if( !imgD.lowresSource ) imgD.lowresSource = imgD.source; // tags this.setImageDataTags( imgD, doc ); // name this.setImageDataName( imgD ); // extension this.setImageDataExtension( imgD ); imgD.state = 'ready'; //clog("imgD[" + imgD.index + "]: ", imgD.source, imgD.state); return 0; }, setImageDataName: function( imgD ){ var tagsLen = imgD.tags.length, uLen = userOptions.val('maxTagsInName'), tagsDelim = userOptions.val('tagsDelim'); imgD.name = ''; if( userOptions.val('addImgBrdName') ) imgD.name += this.name + tagsDelim; for( var i = 0; i < tagsLen && i < uLen; ++i ) imgD.name += imgD.tags[i] + tagsDelim; imgD.name += imgD.postId; }, setImageDataExtension: function( imgD ){ var pathname = getLocation( imgD.source, 'pathname' ); imgD.extension = pathname.match(/\.([a-z\d]+)$/)[1]; }, }; return retVal; } //----------------------------------- METHODS OBJECT ---------------------------------// //------------------------------------------------------------------------------------// //-------------------------------------- DATASET -------------------------------------// function initImageBoardDataset(d) { var retVal = { data: { source: 'data-image-board-source', index: 'data-image-board-index', extension: 'data-image-board-extension', bytes: 'data-image-board-bytes', }, val: function(elm, propName, v){ if( this.data[propName] ) { if( v !== undefined ) elm.setAttribute(this.data[propName], v); else return elm.getAttribute(this.data[propName]); } return null; }, init: function(doc){ this.doc = doc || document; }, getSelector: function(propName, v){ var sel = this.data[propName]; if( sel ) { if( v !== undefined ) { var pos = v.indexOf('='); if( pos > -1 && pos < 2 ) sel += v; else sel += '="' + v + '"'; } return '[' + sel + ']'; } return null; }, query: function(propName, v){ var sel = this.getSelector(propName, v); if( sel ) return this.doc.querySelector(sel); return null; }, queryAll: function(propName, v){ var sel = this.getSelector(propName, v); if( sel ) return this.doc.querySelectorAll(sel); return null; }, }; retVal.init(d); return retVal; } //-------------------------------------- DATASET -------------------------------------// //------------------------------------------------------------------------------------// //-------------------------------------- CLASSES -------------------------------------// function initImageBoardClasses(d) { var retVal = { get counted(){return this.data.counted;}, get viewActive(){return this.data.viewActive;}, get viewAttach(){return this.data.viewAttach;}, get ready(){return this.data.ready;}, get downloaded(){return this.data.downloaded;}, get downloadAttach(){ return this.data.downloadAttach;}, get downloadActive(){ return this.data.downloadActive;}, data: { counted: 'image-board-counted', viewAttach: 'image-board-attach-view-event', viewActive: 'image-board-active-for-view', ready: 'image-board-has-original-source', downloaded: 'image-board-downloaded-original', downloadAttach: 'image-board-attach-download-event', downloadActive: 'image-board-active-for-download', }, hasClass: function(elm, propName){ if( this.data[propName] ) return hasClass(elm, this.data[propName]); return false; }, addClass: function(elm, propName){ if( this.data[propName] ) addClass(elm, this.data[propName]); }, removeClass: function(elm, propName){ if( this.data[propName] ) removeClass(elm, this.data[propName]); }, toggleClass: function(elm, newPropName, oldPropName){ if( oldPropName && !this.data[oldPropName] ) return; else if( !newPropName || !this.data[newPropName] ) return; toggleClass( elm, this.data[newPropName], this.data[oldPropName] ); }, queryAll: function(propName){ if( this.data[propName] ) return this.doc.querySelectorAll('.' + this.data[propName]); return null; }, init: function(doc){this.doc = doc || document;}, }; retVal.init(d); return retVal; } //-------------------------------------- CLASSES -------------------------------------// //------------------------------------------------------------------------------------// //------------------------------------- DOWNLOADER -----------------------------------// function initImageBoardDownloader(d) { var iter = { total : 0, done: 0, }; var retVal = { get total(){return iter.total;}, set total(n){ iter.total = n; this.downloadAllHtml(iter.total, iter.done); }, get done(){return iter.done;}, set done(n){ iter.done = n; this.downloadAllHtml(iter.total, iter.done); }, id: { downloader: 'image-board-downloader-' + RANDOM, downloadAll: 'image-board-download-all-' + RANDOM, downloadSwitch: 'image-board-download-switch-' + RANDOM, }, 'class': { on: 'image-board-downloader-on', off: 'image-board-downloader-off', active: 'image-board-downloader-active', }, init: function(id, doc){ doc = doc || document; var div = doc.querySelector('div#' + id); if( !div ) { console.error("[initImageBoardDownloader] can't init div"); return; } this.val = div.querySelector('#' + this.id.downloader ); if( !this.val ) { this.val = document.createElement('div'); this.val.setAttribute('id', this.id.downloader); var html = '' + '<button id="' + this.id.downloadSwitch + '" class="' + this.class.off + '">Download Mode</button>' + '<button id="' + this.id.downloadAll + '" class="">Download All (0)</button>' + ''; this.val.innerHTML = html; this.val = div.appendChild(this.val); } this.downloadAll = this.val.querySelector('#' + this.id.downloadAll); if( !this.downloadAll.classList.contains(this.class.active) ) { this.downloadAll.addEventListener('click', handleDownloadAllEvent, false); this.downloadAll.classList.add(this.class.active); } this.downloadSwitch = this.val.querySelector('#' + this.id.downloadSwitch); if( !this.downloadSwitch.classList.contains(this.class.active) ) { activateKeyboard(); this.downloadSwitch.addEventListener('click', handleDownloadSwitchEvent, false); this.downloadSwitch.classList.add(this.class.active); } return this.val; }, downloadAllHtml: function( total, loaded ){ if( !this.val ) return; this.downloadAll.innerHTML = '' + 'Download All (' + (loaded ? loaded + ' / ': '') + (total ? total : 0) + ')'; }, downloadOn: function(){ toggleClass( this.downloadSwitch, this.class.on, this.class.off ); }, downloadOff: function(){ toggleClass( this.downloadSwitch, this.class.off, this.class.on ); }, isActive: function(){ if( this.downloadSwitch ) return this.downloadSwitch.classList.contains(this.class.on); return false; }, }; return retVal; } //------------------------------------- DOWNLOADER -----------------------------------// //------------------------------------------------------------------------------------// //------------------------------------ DOWNLOADER-2 ----------------------------------// function handleDownloadEvent(event) { if( !imageBoard.imgBrdCl.hasClass( this, 'downloadActive' ) ) return; event.preventDefault(); var thumb = event.target, index = imageBoard.imgBrdDt.val( thumb, 'index' ), imgD = imageBoard.images.list[index]; downloadFile( imgD ); } function handleDownloadAllEvent(event) { var list = imageBoard.images.list; for( var i = 0, len = list.length, imgD; i < len; ++i ) { imgD = list[i]; downloadFile( imgD ); } } function fileDownloader( name, resource ) { var a = document.createElement('a'), body = document.body || document.getElementsByTagName('body')[0]; a.setAttribute('download', name); a.href = resource; body.appendChild(a); a.click(); body.removeChild(a); } function downloadFile( imgD ) { if( imgD.state !== 'ready' || imgD.downloadState === 'downloaded' || imgD.downloadState === 'inProgress' ) return; imgD.downloadState = 'inProgress'; var hostname = getLocation(imgD.source, 'hostname'); if( hostname === window.location.hostname ) { imageBoardDownloader( imgD, imgD.source ); return; } GM_xmlhttpRequest({ url: imgD.source, method: 'GET', context: { 'index': imgD.index, }, responseType: 'blob', onload: blibBlobDownloader, }); } function blibBlobDownloader( xhr ) { if( xhr.status !== 200 ) { console.error("xhr.status: ", xhr.status, xhr.statusText); console.erorr("url: " + this.url); return; } var wndURL = window.webkitURL || window.URL, resource = wndURL.createObjectURL(xhr.response), imgD = imageBoard.images.list[xhr.context.index]; imageBoardDownloader( imgD, resource ); wndURL.revokeObjectURL( resource ); } function imageBoardDownloader( imgD, resource ) { var name = imgD.name + '.' + imgD.extension; fileDownloader( name, resource ); var thumb = imageBoard.imgBrdDt.query('index', imgD.index + ''); imageBoard.imgBrdCl.addClass( thumb, 'downloaded' ); imgD.downloadState = 'downloaded'; imageBoard.imgBrdDw.done += 1; } function handleDownloadSwitchEvent(event) { if( imageBoard.imgBrdDw.isActive() ) imageBoard.downloader.deactivate(); else imageBoard.downloader.activate(); } function activateKeyboard() { window.addEventListener('keydown', handleKeyboardEvent, false); } function deactivateKeyboard() { window.removeEventListener('keydown', handleKeyboardEvent, false); } function handleKeyboardEvent(event) { var charCode = event.keyCode || event.which, str = String.fromCharCode(charCode); if( str === 'd' || str === 'D' ) { handleDownloadSwitchEvent(); } /* else if( str === 'v' || str === 'V' ) { handleViewerSwitchEvent();// dummy function } else if( str === 's' || str === 'S' ) { if( imageBoard ) { imageBoard.init(); imageBoard.fix(); } } */ } //------------------------------------ DOWNLOADER-2 ----------------------------------// //------------------------------------------------------------------------------------// function handleViewerSwitchEvent(event){}// TODO //------------------------------------------------------------------------------------// //------------------------------------ USER OPTIONS ----------------------------------// function initOptions() { function _setDef(){this.val = this.def;} var retVal = { data: { 'maxTagsInName': { val: null, def: 10, setDef: _setDef, }, 'tagsDelim': { val: null, def: '-', setDef: _setDef, }, 'addImgBrdName': { val: null, def: true, setDef: _setDef, }, /* 'autoRunSource': { val: null, def: true, setDef: _setDef, }, 'autoRunDownloadOn': { val: null, def: false, setDef: _setDef, }, */ }, val: function( opt, v ) { if( this.data[opt] ) { if( v === undefined ) return this.data[opt].val; else this.data[opt].val = v; }else return null; }, setDefs: function(){ for( var key in this.data ) this.data[key].setDef(); }, set: function(obj){ for( var key in obj ) this.val(key, obj[key]); }, }; retVal.setDefs(); return retVal; } //------------------------------------ USER OPTIONS ----------------------------------// //------------------------------------------------------------------------------------// function newCssClasses() { addCssClass(` #image-board-downloader-${RANDOM} { position: relative; text-align: right; top: 2px; right: 10px; bottom: 2px; } #image-board-downloader-${RANDOM} > button { margin: 3px 10px; //color: #fff; color: ${imageBoard.siteList.style().color}; font-weight: bold; width: 180px; border: 0px; padding: 5px; //background: #0773fb; background: ${imageBoard.siteList.style().background}; } #image-board-downloader-${RANDOM} > button:hover { //background: #fbb307; background: ${imageBoard.siteList.style().backgroundHover}; color: ${imageBoard.siteList.style().colorHover}; } .image-board-downloader-off::after { content: " [off]"; } .image-board-downloader-on::after { content: " [on]"; } img.image-board-has-original-source { border-bottom: 5px solid green !important; } .image-board-active-for-download { cursor: default; } `); } function addCssClass(cssClass) { var style = document.createElement('style'), head = document.querySelector('head'); style.type = 'text/css'; if( style.styleSheets ) style.styleSheets.cssText = cssClass; else style.appendChild(document.createTextNode(cssClass)); return head.appendChild(style); } function addClass( elm, name ) { if( elm && name ) elm.classList.add(name); } function removeClass( elm, name ) { if( elm && name ) elm.classList.remove(name); } function hasClass( elm, name ) { if( elm && name ) return elm.classList.contains(name); return false; } function toggleClass( elm, newClass, oldClass ) { if( !elm || !newClass ) return; if( oldClass ) { elm.classList.remove(oldClass); elm.classList.add(newClass); } else if( elm.classList.contains(newClass) ) elm.classList.remove(newClass); else elm.classList.add(newClass); } function getLocation( url, attr ) { if( !attr ) return null; url = url || window.location.href; this.link = this.link || document.createElement('a'); this.link.href = url; return this.link[attr]; } function getSearchObject( search ) { var keys = {} if( search ) { search = search.replace(/^\?/, ''); search.split('&').forEach(function(item){ item = item.split('='); keys[item[0]] = item[1]; }); } return keys; } function last( arr ) { if( arr && arr.length > 0 ) return arr[arr.length-1]; return null; } })();