OMG Beau Peep! Reader

Read comics more easily with keyboard shortcuts and no distracting content

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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.')
})();