OMG Beau Peep! Reader

Read comics more easily with keyboard shortcuts and no distracting content

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         OMG Beau Peep! Reader
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @description  Read comics more easily with keyboard shortcuts and no distracting content
// @author       You
// @match        http://www.omgbeaupeep.com/*
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    console.info('beautifying beau peep...')
    var state
    var img
    var imageStore = [] // [{prev, next, img}, {}, ...]

    // inject the scaffolding
    var fragment = document.createDocumentFragment()
    img = document.createElement('img')
    var classAttribute = document.createAttribute('class')
    classAttribute.value = 'Reader-image'
    img.setAttributeNode(classAttribute)
    fragment.appendChild(img)
    document.body.insertBefore(fragment, document.body.firstChild)

    // do the first run of injection
    state = docToObj(document, window.location.href)
    imageStore.push(state)
    updateImage(state.img)
    fetchPage(state.next)
    fetchPage(state.prev)

    window.setTimeout(function() {
        try {
            var toBeRemoved = [].filter.call(document.body.children, function(e) {return !e.classList.contains('Reader-image')})
            toBeRemoved.forEach(function(removeMe) {
                removeMe.remove()
            })
        } catch (e) {}

        setupHandlers()
    }, 500)

    function setupHandlers() {
        document.onkeydown = undefined
        document.addEventListener('keyup', handleKeyup)
    }

    function handleKeyup(e) {
        e.stopImmediatePropagation()

	    switch (e.key) {
		    case 'ArrowLeft':
		        getImage(state.prev)
	    	    return

    		case 'ArrowRight':
		        getImage(state.next)
	    	    return
    	}
    }

    function getImage(url) {
        // show the requested image, and prefetch the next and prev if not already cached

        var obj = imageStore.find(function(e) { return e.url === url })
        if (!obj) return
        state = obj
        updateImage(state.img)
        window.history.pushState({},"", state.url);

        var prev = imageStore.find(function(e) { return e.url === state.prev })
        var next = imageStore.find(function(e) { return e.url === state.next })

        if (!prev) {
           fetchPage(state.prev)
        }
        if (!next) {
           fetchPage(state.next)
        }
    }

    function fetchPage(url) {
        if (!url) return

        var xhr = new XMLHttpRequest()
        xhr.onreadystatechange = handleXHR
        xhr.open('GET', url, true)
        xhr.responseType = "document"
        xhr.send()

        function handleXHR() {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status === 200) {
                    var obj = docToObj(xhr.responseXML, xhr.responseURL)
                    imageStore.push(obj)
                    // actually HTTP fetch the image
                    var imgxhr = new XMLHttpRequest()
                    imgxhr.open('GET', obj.img, true) // FIXME will this use the cache if possible?
                    imgxhr.send()
                } else {
                    img['src'] = 'something broke'
                    console.error('unsuccessful ajax attempt, could not load next image')
                }
            }
        }
    }


    function docToObj(doc, url) {
        var picElement = doc.querySelector('img.picture')
        var nextUrl = picElement.parentElement['href'] + '/'
        var previousUrl = doc.querySelector('select[name=page]').previousElementSibling['href']
        var imageUrl = picElement['src']

        previousUrl && (previousUrl += '/')

        return {url: url, next: nextUrl, prev: previousUrl, img: imageUrl}
    }

    function updateImage(url) {
        img['src'] = url
        window.scrollTo({top: 0})
    }

    var styles = '\
body {\
    margin: 0;\
}\
.Reader-image {\
    display: block;\
    margin: 0 auto;\
    cursor: pointer;\
';

    GM_addStyle(styles)

    console.info('done beautifying.')
})();