Greasy Fork 支持简体中文。

OverDrive Transcriber

Transcribes books you read on OverDrive for offline reading

目前為 2018-04-24 提交的版本,檢視 最新版本

// ==UserScript==
// @name OverDrive Transcriber
// @description Transcribes books you read on OverDrive for offline reading
// @namespace Violentmonkey Scripts
// @match *://*.read.overdrive.com/*
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-start
// @version 0.1
// ==/UserScript==

(function() {
    var content_html_regex = /content\/.*\.html/;
    
    function parse(url, content) {
        var html = document.createElement("html");
        html.innerHTML = content;
        
        var url_match = url.match(/\/content\/(([0-9]+)_[^/.]*)\.html/);
        if (!url_match)
            // shouldn't happen
            return;
        var book_id = url_match[2];
        var var_id = url_match[1];
        
        var titleel = html.getElementsByTagName("title")[0];
        if (!titleel)
            return;

        var title = titleel.innerHTML;
        /*console.log(book_id);
        console.log(var_id);
        console.log(title);*/
        
        GM_setValue("TITLE:" + book_id, title.toString());
        
        var setcontents = function(contents) {
            GM_setValue("CONTENTS:" + var_id, contents.toString());
        }

        var scripts = html.getElementsByTagName("script");
        var regex = /^ *parent\.[^;(]*\(.*?['"](.*?)['"]/;
        var set = false;
        for (var i = 0; i < scripts.length; i++) {
            var matchobj = scripts[i].innerHTML.match(regex);
            if (matchobj) {
                var text = atob(matchobj[1]);
                setcontents(text);
                set = true;
            }
        }
        
        if (!set) {
            if (html.querySelectorAll("body > p").length >= 0) {
                var body = html.getElementsByTagName("body")[0].cloneNode(true);
                body.removeAttribute("xmlns");
                body.removeAttribute("onload");
                setcontents(body.outerHTML);
            }
        }
    }
    
    var original_open = window.XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function(method, url) {
        if (!url)
            return;

        if (url.match(content_html_regex)) {
            this.addEventListener("readystatechange", function() {
                if (this.readyState === 4) {
                    parse(url, this.responseText);
                }
            });
        }
        original_open.apply(this, arguments);
    };
    
    function run_iframe(iframe) {
        var ifdocument = iframe.contentDocument || iframe.contentWindow.document;
        parse(iframe.src, ifdocument.documentElement.innerHTML)
    }
    
    function find_iframes() {
        var iframes = document.getElementsByTagName("iframe");
        for (var i = 0; i < iframes.length; i++) {
            if (iframes[i].src.match(content_html_regex)) {
                (function(iframes, i) {
                    iframes[i].onload = function() {
                        run_iframe(iframes[i]);
                    }
                    
                    run_iframe(iframes[i]);
                })(iframes, i);
            }
        }
    }
    
    function start() {
        new MutationObserver(find_iframes).observe(document.documentElement, {
            attributes: true,
            childList: true
        });
        find_iframes();
    }
    
    if (document.readyState === "interactive" || document.readyState === "complete") {
        start();
    } else {
        document.addEventListener("DOMContentLoaded", start, false);
    }
})();