您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
复制 hitoma.la notomi.la e-hentai 图片链接到剪贴板
// ==UserScript== // @name la-image-extractor // @name:zh-CN la 图片地址复制 // @description copy image source in hitomi.la notomi.la e-hentai.org to clipboard // @description:zh-CN 复制 hitoma.la notomi.la e-hentai 图片链接到剪贴板 // @version 0.2.5 // @author jferroal // @license GPL-3.0 // @require https://greasyfork.org/scripts/31793-jmul/code/JMUL.js?version=209567 // @include https://hitomi.la/reader/* // @include https://nozomi.la/tag/* // @include https://e-hentai.org/s/* // @grant GM_xmlhttpRequest // @run-at document-idle // @namespace https://greasyfork.org/users/34556-jferroal // ==/UserScript== (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ class Button { constructor(label, eventHandlers = []) { this.element = document.createElement('div'); this.addCss(Button.DefaultCss); this.element.innerText = label; this.listeners = {}; this.listen(eventHandlers); this.parent = null; } onClick(handler) { this.listen({'click': handler}); } listen(handlers) { for (const event in handlers) { if (handlers.hasOwnProperty(event)) { this.element.addEventListener(event, handlers[event]); } } } addCss(css) { for (const styleName in css) { if (css.hasOwnProperty(styleName)) { this.element.style[styleName] = css[styleName]; } } } appendTo(element) { this.parent = element; element.appendChild(this.element); } removeFrom() { this.parent.removeChild(this.element); } removeListener() { for (const event in this.listeners) { if (this.listeners.hasOwnProperty(event)) { this.element.removeEventListener(event, this.listeners[event]); } } } } Button.DefaultCss = { textAlign: 'center', width: '120px', lineHeight: '40px', backgroundColor: 'skyblue', color: 'white', cursor: 'pointer', borderRadius: '8px', boxShadow: '0px 0px 8px 4px rgba(0, 0, 0, .2)', position: 'fixed', right: '80px', bottom: '80px' }; module.exports = Button; },{}],2:[function(require,module,exports){ const {createFullScreenElement, href, innerText, isEhentai} = require('./utils'); let _EhentaiState = {}; function constructImage(src) { const img = document.createElement('img'); img.style.width = '100vw'; img.style.maxWidth = '100vw'; img.setAttribute('src', src); return img; } function loadMore() { _EhentaiState.ImageContainer.removeChild(_EhentaiState.LoadMoreBtn); const targets = _EhentaiState.ImageSources .slice(_EhentaiState.ImageAppendedCount, _EhentaiState.ImageAppendedCount + _EhentaiState.ImagePerPage); let i = 0; for (const src of targets) { let timer = setTimeout(() => { const img = constructImage(src); document.querySelector(_EhentaiState.ImageContainerSelector).appendChild(img); clearTimeout(timer); timer = null; }, i * _EhentaiState.ImageElementCreationDefer); _EhentaiState.ImageAppendedCount += 1; i += 1; } if (_EhentaiState.ImageAppendedCount < _EhentaiState.ImageSources.length) { _EhentaiState.ImageContainer.appendChild(_EhentaiState.LoadMoreBtn); } } module.exports = { initEhentai() { if (!isEhentai()) return; const [ MainContainerSelector, TopPaginationSelector, ImageContainerSelector, BottomPaginationSelector, ImagesSelector, TitleSelector ] = ['#i1', '#i2', '#i3', '#i4', '#i3 img', 'title']; const NextPagePattern = /<div id="i3"><a onclick="return load_image\((\d+), '([\w\d]+)'\)"/gi; const ImageSourcePattern = /<img id="img" src="(.*)" style=".*?" onerror=".*?" \/>/gi; const ImageElementCreationDefer = 200; const ImagePerPage = 20; const PostId = href().split('/')[5].split('-')[0]; _EhentaiState.ImageContainer = document.querySelector(ImageContainerSelector); _EhentaiState.LoadMoreBtn = document.createElement('div'); _EhentaiState.LoadMoreBtn.style.width = '100%'; _EhentaiState.LoadMoreBtn.style.lineHeight = '48px'; _EhentaiState.LoadMoreBtn.style.margin = '24px 60px'; _EhentaiState.LoadMoreBtn.style.cursor = 'pointer'; _EhentaiState.LoadMoreBtn.style.backgroundColor = 'lightskyblue'; _EhentaiState.LoadMoreBtn.style.borderRadius = '8px'; _EhentaiState.LoadMoreBtn.innerText = 'LOAD MORE'; _EhentaiState.LoadMoreBtn.addEventListener('click', loadMore); _EhentaiState.FetchAllRunning = false; _EhentaiState.ImageAppendedCount = 1; _EhentaiState.ImageSources = ['first_image_placeholder']; _EhentaiState = Object.assign(_EhentaiState, { MainContainerSelector, TopPaginationSelector, ImageContainerSelector, BottomPaginationSelector, ImagesSelector, TitleSelector, NextPagePattern, ImageSourcePattern, ImageElementCreationDefer, ImagePerPage, PostId, }); }, fetchEhentaiAll() { if (_EhentaiState.FetchAllRunning) return; _EhentaiState.FetchAllRunning = true; function getNextImage(page, hash) { const url = `https://e-hentai.org/s/${hash}/${_EhentaiState.PostId}-${page}`; const xmlhttp = new XMLHttpRequest(); xmlhttp.open('GET', url); xmlhttp.onreadystatechange = function () { if (this.readyState !== 4) return; if (this.status === 200) { const [, p, h] = _EhentaiState.NextPagePattern.exec(this.responseText); _EhentaiState.NextPagePattern.lastIndex = -1; const hasNext = parseInt(p, 10) !== _EhentaiState.ImageSources.length; if (!hasNext) { const loadedElem = createFullScreenElement('ALL IMAGE SOURCES LOADED'); document.body.appendChild(loadedElem); let timer = setTimeout(() => { document.body.removeChild(loadedElem); clearTimeout(timer); timer = null; }, 3000); _EhentaiState.FetchAllRunning = false; return; } const [, imageSource] = _EhentaiState.ImageSourcePattern.exec(this.responseText); _EhentaiState.ImageSourcePattern.lastIndex = -1; _EhentaiState.ImageSources.push(imageSource); if (_EhentaiState.ImageAppendedCount < _EhentaiState.ImagePerPage) { // load IMAGE PER PAGE COUNT image at first const img = constructImage(imageSource); _EhentaiState.ImageContainer.appendChild(img); _EhentaiState.ImageAppendedCount += 1; } else { _EhentaiState.ImageContainer.appendChild(_EhentaiState.LoadMoreBtn); } getNextImage(p, h); } }; xmlhttp.send(); } const mainContainer = document.querySelector(_EhentaiState.MainContainerSelector); window.addEventListener('resize', () => { document.querySelector(_EhentaiState.MainContainerSelector).style.maxWidth = '100vw'; }); mainContainer.style.width = '100vw'; mainContainer.style.maxWidth = '100vw'; document.querySelector(_EhentaiState.TopPaginationSelector).style.display = 'none'; document.querySelector(_EhentaiState.BottomPaginationSelector).style.display = 'none'; const [, page, hash] = _EhentaiState.NextPagePattern.exec( document.querySelector(_EhentaiState.MainContainerSelector).innerHTML ); getNextImage(page, hash); }, extractEhentaiImages() { const img = document.querySelector(_EhentaiState.ImagesSelector); const title = innerText(document.querySelector(_EhentaiState.TitleSelector)); return `${title}\n${[img.src, ..._EhentaiState.ImageSources.slice(1)].join('\n')}\n${'= ='.repeat(20)}`; } }; },{"./utils":6}],3:[function(require,module,exports){ const {href, innerText, isHitomi} = require('./utils'); let _HitomiState = {}; module.exports = { initHitomi() { if (!isHitomi()) return; _HitomiState.ImgsSrcSelector = '.img-url'; _HitomiState.TitleSelector = 'title'; _HitomiState.Adapost = false; _HitomiState.NumberOfFrontEnds = 2; }, extractHitomiImages() { const {ImgsSrcSelector, TitleSelector, Adapost, NumberOfFrontEnds} = _HitomiState; let images = Array.from(document.querySelectorAll(ImgsSrcSelector)); let title = encodeURIComponent(innerText(document.querySelector(TitleSelector), '- | -').split(' | ')[0]); const mat = /\/\d*(\d)\.html/.exec(href()); let lv = mat && parseInt(mat[1], 10); if (!lv || Number.isNaN(lv)) { lv = '1'; } const magic = Adapost ? 'a' : String.fromCharCode(((lv === 1 ? 0 : lv) % NumberOfFrontEnds) + 97); images = images.map(s => s.innerText.replace('//g.hitomi.la', `https://${magic}a.hitomi.la`)); return `${title}\n${images.join('\n')}\n${'= ='.repeat(20)}`; } }; },{"./utils":6}],4:[function(require,module,exports){ const {isHitomi, isNozomi, isEhentai, copyToClipboard} = require('./utils'); const Button = require('./Button'); const {initHitomi, extractHitomiImages} = require('./hitomi'); const {initNozomi, extractNozomiImages, fetchNozomiAll} = require('./nozomi'); const {initEhentai, extractEhentaiImages, fetchEhentaiAll} = require('./ehentai'); (function () { initHitomi(); initNozomi(); initEhentai(); // create button to click if (isNozomi() || isEhentai()) { const btn = new Button('Fetch All'); btn.addCss({bottom: '160px', zIndex: '999'}); btn.appendTo(document.body); btn.onClick(() => { if (isNozomi()) { fetchNozomiAll(); } if (isEhentai()) { fetchEhentaiAll(); } }); } const btn = new Button('Copy Sources'); btn.addCss({zIndex: '999'}); btn.onClick(() => { // prepare str2Paste let str2paste = ''; if (isHitomi()) { str2paste = extractHitomiImages(); } else if (isNozomi()) { str2paste = extractNozomiImages(); } else { str2paste = extractEhentaiImages(); } copyToClipboard(str2paste); }); btn.appendTo(document.body); })(); },{"./Button":1,"./ehentai":2,"./hitomi":3,"./nozomi":5,"./utils":6}],5:[function(require,module,exports){ const {innerText, createFullScreenElement} = require('./utils'); // TODO: refactor const [ ImgSrcSelector, TitleSelector, ContentSelector, ThumbnailDivsSelector ] = ['.tag-list-img', 'h1', '.content', '#thumbnail-divs']; function JSPack() { // Module-level (private) variables var el, bBE = false, m = this; // Raw byte arrays m._DeArray = function (a, p, l) { return [a.slice(p, p + l)]; }; m._EnArray = function (a, p, l, v) { for (var i = 0; i < l; a[p + i] = v[i] ? v[i] : 0, i++) ; }; // ASCII characters m._DeChar = function (a, p) { return String.fromCharCode(a[p]); }; m._EnChar = function (a, p, v) { a[p] = v.charCodeAt(0); }; // Little-endian (un)signed N-byte integers m._DeInt = function (a, p) { var lsb = bBE ? (el.len - 1) : 0, nsb = bBE ? -1 : 1, stop = lsb + nsb * el.len, rv, i, f; for (rv = 0, i = lsb, f = 1; i != stop; rv += (a[p + i] * f), i += nsb, f *= 256) ; if (el.bSigned && (rv & Math.pow(2, el.len * 8 - 1))) { rv -= Math.pow(2, el.len * 8); } return rv; }; m._EnInt = function (a, p, v) { var lsb = bBE ? (el.len - 1) : 0, nsb = bBE ? -1 : 1, stop = lsb + nsb * el.len, i; v = (v < el.min) ? el.min : (v > el.max) ? el.max : v; for (i = lsb; i != stop; a[p + i] = v & 0xff, i += nsb, v >>= 8) ; }; // ASCII character strings m._DeString = function (a, p, l) { for (var rv = new Array(l), i = 0; i < l; rv[i] = String.fromCharCode(a[p + i]), i++) ; return rv.join(''); }; m._EnString = function (a, p, l, v) { for (var t, i = 0; i < l; a[p + i] = (t = v.charCodeAt(i)) ? t : 0, i++) ; }; // Little-endian N-bit IEEE 754 floating point m._De754 = function (a, p) { var s, e, m, i, d, nBits, mLen, eLen, eBias, eMax; mLen = el.mLen, eLen = el.len * 8 - el.mLen - 1, eMax = (1 << eLen) - 1, eBias = eMax >> 1; i = bBE ? 0 : (el.len - 1); d = bBE ? 1 : -1; s = a[p + i]; i += d; nBits = -7; for (e = s & ((1 << (-nBits)) - 1), s >>= (-nBits), nBits += eLen; nBits > 0; e = e * 256 + a[p + i], i += d, nBits -= 8) ; for (m = e & ((1 << (-nBits)) - 1), e >>= (-nBits), nBits += mLen; nBits > 0; m = m * 256 + a[p + i], i += d, nBits -= 8) ; switch (e) { case 0: // Zero, or denormalized number e = 1 - eBias; break; case eMax: // NaN, or +/-Infinity return m ? NaN : ((s ? -1 : 1) * Infinity); default: // Normalized number m = m + Math.pow(2, mLen); e = e - eBias; break; } return (s ? -1 : 1) * m * Math.pow(2, e - mLen); }; m._En754 = function (a, p, v) { var s, e, m, i, d, c, mLen, eLen, eBias, eMax; mLen = el.mLen, eLen = el.len * 8 - el.mLen - 1, eMax = (1 << eLen) - 1, eBias = eMax >> 1; s = v < 0 ? 1 : 0; v = Math.abs(v); if (isNaN(v) || (v === Infinity)) { m = isNaN(v) ? 1 : 0; e = eMax; } else { e = Math.floor(Math.log(v) / Math.LN2); // Calculate log2 of the value if (v * (c = Math.pow(2, -e)) < 1) { e--; c *= 2; } // Math.log() isn't 100% reliable // Round by adding 1/2 the significand's LSD if (e + eBias >= 1) { v += el.rt / c; } // Normalized: mLen significand digits else { v += el.rt * Math.pow(2, 1 - eBias); } // Denormalized: <= mLen significand digits if (v * c >= 2) { e++; c /= 2; } // Rounding can increment the exponent if (e + eBias >= eMax) { // Overflow m = 0; e = eMax; } else if (e + eBias >= 1) { // Normalized - term order matters, as Math.pow(2, 52-e) and v*Math.pow(2, 52) can overflow m = (v * c - 1) * Math.pow(2, mLen); e = e + eBias; } else { // Denormalized - also catches the '0' case, somewhat by chance m = v * Math.pow(2, eBias - 1) * Math.pow(2, mLen); e = 0; } } for (i = bBE ? (el.len - 1) : 0, d = bBE ? -1 : 1; mLen >= 8; a[p + i] = m & 0xff, i += d, m /= 256, mLen -= 8) ; for (e = (e << mLen) | m, eLen += mLen; eLen > 0; a[p + i] = e & 0xff, i += d, e /= 256, eLen -= 8) ; a[p + i - d] |= s * 128; }; // Class data m._sPattern = '(\\d+)?([AxcbBhHsfdiIlL])'; m._lenLut = { 'A': 1, 'x': 1, 'c': 1, 'b': 1, 'B': 1, 'h': 2, 'H': 2, 's': 1, 'f': 4, 'd': 8, 'i': 4, 'I': 4, 'l': 4, 'L': 4 }; m._elLut = { 'A': {en: m._EnArray, de: m._DeArray}, 's': {en: m._EnString, de: m._DeString}, 'c': {en: m._EnChar, de: m._DeChar}, 'b': {en: m._EnInt, de: m._DeInt, len: 1, bSigned: true, min: -Math.pow(2, 7), max: Math.pow(2, 7) - 1}, 'B': {en: m._EnInt, de: m._DeInt, len: 1, bSigned: false, min: 0, max: Math.pow(2, 8) - 1}, 'h': {en: m._EnInt, de: m._DeInt, len: 2, bSigned: true, min: -Math.pow(2, 15), max: Math.pow(2, 15) - 1}, 'H': {en: m._EnInt, de: m._DeInt, len: 2, bSigned: false, min: 0, max: Math.pow(2, 16) - 1}, 'i': {en: m._EnInt, de: m._DeInt, len: 4, bSigned: true, min: -Math.pow(2, 31), max: Math.pow(2, 31) - 1}, 'I': {en: m._EnInt, de: m._DeInt, len: 4, bSigned: false, min: 0, max: Math.pow(2, 32) - 1}, 'l': {en: m._EnInt, de: m._DeInt, len: 4, bSigned: true, min: -Math.pow(2, 31), max: Math.pow(2, 31) - 1}, 'L': {en: m._EnInt, de: m._DeInt, len: 4, bSigned: false, min: 0, max: Math.pow(2, 32) - 1}, 'f': {en: m._En754, de: m._De754, len: 4, mLen: 23, rt: Math.pow(2, -24) - Math.pow(2, -77)}, 'd': {en: m._En754, de: m._De754, len: 8, mLen: 52, rt: 0} }; // Unpack a series of n elements of size s from array a at offset p with fxn m._UnpackSeries = function (n, s, a, p) { for (var fxn = el.de, rv = [], i = 0; i < n; rv.push(fxn(a, p + i * s)), i++) ; return rv; }; // Pack a series of n elements of size s from array v at offset i to array a at offset p with fxn m._PackSeries = function (n, s, a, p, v, i) { for (var fxn = el.en, o = 0; o < n; fxn(a, p + o * s, v[i + o]), o++) ; }; // Unpack the octet array a, beginning at offset p, according to the fmt string m.Unpack = function (fmt, a, p) { // Set the private bBE flag based on the format string - assume big-endianness bBE = (fmt.charAt(0) != '<'); p = p ? p : 0; var re = new RegExp(this._sPattern, 'g'), m, n, s, rv = []; while (m = re.exec(fmt)) { n = ((m[1] == undefined) || (m[1] == '')) ? 1 : parseInt(m[1]); s = this._lenLut[m[2]]; if ((p + n * s) > a.length) { return undefined; } switch (m[2]) { case 'A': case 's': rv.push(this._elLut[m[2]].de(a, p, n)); break; case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': case 'l': case 'L': case 'f': case 'd': el = this._elLut[m[2]]; rv.push(this._UnpackSeries(n, s, a, p)); break; } p += n * s; } return Array.prototype.concat.apply([], rv); }; // Pack the supplied values into the octet array a, beginning at offset p, according to the fmt string m.PackTo = function (fmt, a, p, values) { // Set the private bBE flag based on the format string - assume big-endianness bBE = (fmt.charAt(0) !== '<'); var re = new RegExp(this._sPattern, 'g'), m, n, s, i = 0, j; while (m = re.exec(fmt)) { n = ((m[1] === undefined) || (m[1] === '')) ? 1 : parseInt(m[1]); s = this._lenLut[m[2]]; if ((p + n * s) > a.length) { return false; } switch (m[2]) { case 'A': case 's': if ((i + 1) > values.length) { return false; } this._elLut[m[2]].en(a, p, n, values[i]); i += 1; break; case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': case 'l': case 'L': case 'f': case 'd': el = this._elLut[m[2]]; if ((i + n) > values.length) { return false; } this._PackSeries(n, s, a, p, values, i); i += n; break; case 'x': for (j = 0; j < n; j++) { a[p + j] = 0; } break; } p += n * s; } return a; }; // Pack the supplied values into a new octet array, according to the fmt string m.Pack = function (fmt, values) { return this.PackTo(fmt, new Array(this.CalcLength(fmt)), 0, values); }; // Determine the number of bytes represented by the format string m.CalcLength = function (fmt) { var re = new RegExp(this._sPattern, 'g'), m, sum = 0; while (m = re.exec(fmt)) { sum += (((m[1] == undefined) || (m[1] == '')) ? 1 : parseInt(m[1])) * this._lenLut[m[2]]; } return sum; }; } var nozomiextension = '.nozomi'; var nozomidir = 'nozomi'; var domain = 'n.nozomi.la'; var postdir = 'post'; var results_array = {}; var outstanding_requests = {}; var number_of_outstanding_requests = 0; var nozomi, total_items; var tag, tag_for_hash = '', area, page_number; var nozomi_address; function dgebi(id) { return document.getElementById(id); } function path_from_postid(postid) { if (postid.length < 3) return postid; return postid.replace(/^(.*(..)(.))$/, '$3/$2/$1'); } function resize_thumbnails() { var c = document.getElementsByClassName('content')[0]; if (!c) { return; } var s = c.clientWidth; var n = Math.ceil(6.0 * s / 1000.0); var w = ((s - (10.0 * n + 10.0) - 0.5) / n) - 2.0; var divs = document.getElementsByClassName('thumbnail-div'); for (var i = 0; i < divs.length; i++) { var div = divs[i]; div.style.width = (w + 'px'); div.style.height = (w + 'px'); } } function check_dates() { var format = 'lll'; var localize_title = function (el) { if (!el) { return; } var str = el.title; if (str) { var m = moment(str); el.title = m.format(format); } }; //post view localize_title(document.querySelectorAll('.post img')[0]); } function urlencode(str) { return str.replace(/[;\/?:@=&]/g, function (c) { return '%' + c.charCodeAt(0).toString(16); return '%' + c.charCodeAt(0).toString(16); }); } function fetch_nozomi(totalImageCount) { var filepath = decodeURIComponent(document.location.href.replace(/.*nozomi\.la\//, '')); if (!filepath) { tag = 'index'; page_number = 1; } else { var elements = filepath.replace(/\.html$/, '').split('-'); if (elements.length < 2) return; while (elements.length > 2) { elements[1] = elements[0] + '-' + elements[1]; elements.shift(); } tag = elements[0]; if (tag.match(/\//)) { var area_elements = tag.split(/\//); if (area_elements.length !== 2) return; area = area_elements[0]; if (!area || area.match(/[^A-Za-z0-9_]/)) return; tag = area_elements[1]; } if (!tag || tag.match(/\//)) return; if (tag === 'index-Popular') { tag_for_hash = '-Popular'; } else if (area) { tag_for_hash = tag; } page_number = parseInt(elements[1]); if (!page_number || page_number < 1) return; } nozomi_address = '//' + [domain, urlencode(tag)].join('/') + nozomiextension; if (area) { nozomi_address = '//' + [domain, nozomidir, urlencode(tag)].join('/') + nozomiextension; } var start_byte = 0; var end_byte = totalImageCount * 4 - 1; var xhr = new XMLHttpRequest(); const loadingElement = createFullScreenElement(); document.body.appendChild(loadingElement); xhr.open('GET', nozomi_address); xhr.responseType = 'arraybuffer'; xhr.setRequestHeader('Range', 'bytes=' + start_byte.toString() + '-' + end_byte.toString()); xhr.onreadystatechange = function (oEvent) { if (xhr.readyState === 4) { if (xhr.status === 200 || xhr.status === 206) { var arrayBuffer = xhr.response; // Note: not oReq.responseText if (arrayBuffer) { var arr = new Uint8Array(arrayBuffer); //e.g. [0x00, 0x5D, 0x39, 0x72, 0x00, 0x5D, 0x39, 0x82, ...] var jspack = new JSPack(); var total = arr.length / 4; //32-bit unsigned integers nozomi = jspack.Unpack(total + 'I', arr); total_items = parseInt(xhr.getResponseHeader('Content-Range').replace(/^[Bb]ytes \d+-\d+\//, '')) / 4; get_jsons(); document.body.removeChild(loadingElement); } } } }; xhr.send(); } function get_jsons() { var datas = []; for (var i in nozomi) { var postid = nozomi[i]; if (postid in results_array) { datas.push(results_array[postid]); continue; } if (!outstanding_requests[postid]) { outstanding_requests[postid] = 1; ++number_of_outstanding_requests; get_json(postid); //calling a function is REQUIRED to give postid its own scope } } if (number_of_outstanding_requests) return; results_to_page(datas); } function get_json(postid) { var url = '//j.nozomi.la/' + postdir + '/' + path_from_postid(postid.toString()) + '.json'; var xmlhttp = new XMLHttpRequest(); xmlhttp.open('GET', url); xmlhttp.onreadystatechange = function () { if (this.readyState === 4) { if (this.status === 200) { results_array[postid] = JSON.parse(this.responseText); } else { results_array[postid] = ''; } delete outstanding_requests[postid]; --number_of_outstanding_requests; get_jsons(); } }; xmlhttp.send(); } function results_to_page(datas) { var tc = Object.create(null); var to = {}; dgebi('thumbnail-divs').innerHTML = ''; var ul = document.getElementsByClassName('title')[0].nextElementSibling; ul.innerHTML = ''; var p = function (l) { var areas = ['general', 'artist', 'copyright', 'character']; for (var a in areas) { var area = areas[a]; for (var i in l[area]) { var tag = l[area][i]; if (tag.tag in tc === false) { tc[tag.tag] = 1; } else { tc[tag.tag]++; } to[tag.tag] = tag; } } }; for (var d in datas) { var data = datas[d]; if (!data) continue; var div = document.createElement('div'); div.classList.add('thumbnail-div'); var a = document.createElement('a'); a.href = '/post/' + data.postid + '.html#' + tag_for_hash; var img = document.createElement('img'); img.classList.add('tag-list-img'); img.crossOrigin = 'Anonymous'; img.src = data.imageurl.replace(/\/\/i\.nozomi\.la\//, '//tn.nozomi.la/') + '.jpg'; img.title = data.date; a.appendChild(img); div.appendChild(a); dgebi('thumbnail-divs').appendChild(div); p(data); } resize_thumbnails(); setTimeout(resize_thumbnails, 10); check_dates(); } module.exports = { initNozomi() { return; }, fetchNozomiAll() { const totalPage = parseInt(innerText(document.querySelector('.page-container li:last-child'), 1), 10); const totalImageCount = totalPage * 64; // prettify page const elementsToRemove = [ document.querySelector('.page-container'), document.querySelector('.navbar'), document.querySelector('.sidebar') ]; for (const elem of elementsToRemove) { elem.style.display = 'none'; } const mainContent = document.querySelector('.content'); mainContent.style.margin = '0 auto'; const thumbnailsContainer = document.getElementById('thumbnail-divs'); for (const e of Array.from(thumbnailsContainer.getElementsByClassName('thumbnail-div'))) { thumbnailsContainer.removeChild(e); } fetch_nozomi(totalImageCount); }, extractNozomiImages() { let images = Array.from(document.querySelectorAll(ImgSrcSelector)); let title = document.querySelector(TitleSelector).innerText; images = images.map(s => s.src.replace('//tn', '//i').split('.').slice(0, 4).join('.')); return `${title}\n${images.join('\n')}\n${'= ='.repeat(20)}`; } }; },{"./utils":6}],6:[function(require,module,exports){ module.exports = { isHitomi() { return window && window.location && /hitomi/gi.test(window.location.href); }, isNozomi() { return window && window.location && /nozomi.la\/tag/gi.test(window.location.href); }, isEhentai() { return window && window.location && /e-hentai.org\/s/gi.test(window.location.href); }, copyToClipboard(content) { const el = document.createElement('textarea'); el.value = content; document.body.appendChild(el); el.select(); document.execCommand('copy'); document.body.removeChild(el); }, href(d = '') { return (window && window.location && window.location.href) || d; }, innerText(elem, d = '') { return (elem && elem.innerText) || d; }, matchAll(content, pat) { let matches = []; let match = pat.exec(content); while (match) { matches.push(match[1]); match = pat.exec(content); } pat.lastIndex = -1; return matches; }, createFullScreenElement(text) { const elem = document.createElement('div'); elem.style.position = 'fixed'; elem.style.top = '0'; elem.style.right = '0'; elem.style.bottom = '0'; elem.style.left = '0'; elem.style.display = 'flex'; elem.style.backgroundColor = 'rgba(0, 0, 0, 0.56)'; elem.style.justifyContent = 'center'; elem.style.alignItems = 'center'; elem.style.fontSize = '72px'; elem.style.zIndex = '999'; elem.innerText = text; return elem; } }; },{}]},{},[4]);