Sleazy Fork is available in English.

SexInSex 阅读器

【SexInSex 阅读器】是一款用来浏览SexInSex论坛的油猴插件。

// ==UserScript==
// @name              SexInSex 阅读器
// @version           0.9.0
// @description       【SexInSex 阅读器】是一款用来浏览SexInSex论坛的油猴插件。
// @author            xpurple
// @license           MIT
// @updateUrl         https://gist.githubusercontent.com/irunay/436f9f1e7156775b719207527d8d3e42/raw/sis.js
// @match             *://sexinsex.net/bbs/*
// @require           https://cdn.bootcss.com/zepto/1.2.0/zepto.js
// @require           https://cdn.bootcss.com/vue/2.6.10/vue.min.js
// @namespace https://greasyfork.org/users/445664
// ==/UserScript==

/*

    //开发调试模式,把依赖注入页面

    var jq_script = document.createElement('script');
    jq_script.src = "https://cdn.bootcss.com/zepto/1.2.0/zepto.js";

    jq_script.onload = function(){
        var vue_script = document.createElement('script');
        vue_script.src = "https://cdn.bootcss.com/vue/2.6.10/vue.js";
        vue_script.onload = function(){
            var sis_script = document.createElement('script');
            sis_script.src = "http://127.0.0.1/sis/sis.js";
            document.head.appendChild(sis_script);
        }
        document.head.appendChild(vue_script);
    }
    document.head.appendChild(jq_script);

*/

var SIS_APP = (function($, Vue) {

    'use strict';

    function init_page(){

        var body_content = document.body.innerHTML;
        var title = $('title').text();

        var doctype = document.implementation.createDocumentType('html', '', '');

        if(document.doctype) {
            document.replaceChild(doctype, document.doctype);
        } else {
            document.insertBefore(doctype, document.childNodes[0]);
        }


        document.open();
        document.write(`
            <html>
                <head>
                    <meta charset="utf-8">
                    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
                    <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
                    <title>${title}</title>
                    <style>
                        body{font-size:14px;background:#a2c672; font-family:"Microsoft YaHei",微软雅黑,"MicrosoftJhengHei",华文细黑,STHeiti;}
                        .card{margin:1em 0;background-color:#a7ca78}
                        .card-header{font-size:1.25rem;}
                    </style>
                </head>
                <body>
                    <div class="container"><div id="sis_app"></div></div>
                </body>
            </html>
        `);
        document.close();
    }

    function index_data(){

        var data = {
            'forumlist': [],
        };

        $('.forumlist').each(function(i, f){
            var item = {};
            item.sublist = [];
            item.name = $(f).find('h3').first().find('a').text();
            item.link = $(f).find('h3').first().find('a').attr('href');

            $(f).find('th.new').each(function(ii, ff){
                var subitem = {};
                subitem.name = $(ff).find('h2').first().text();
                subitem.link = $(ff).find('h2').first().find('a').attr('href');
                subitem.link = subitem.link.replace(/forum-(\d+)-(\d+)\.html/g,"forumdisplay.php?fid=$1&filter=0&orderby=dateline&ascdesc=DESC&page=$2");
                item.sublist.push(subitem);
            })

            data.forumlist.push(item);
        });

        console.log(data);

        return data;
    }

    function forum_data(){

        var data = {
            'list': [],
            'page':{
                'total': 0,
                'list':[]
            }
        };

        $('.threadlist form table').each(function(i, f){
            if(i < 1){
                return;
            }

            var item = {};
            item.sublist = [];
            item.name = $(f).find('thead.separation b').first().text();

            $(f).find('tbody[id]').each(function(ii, ff){
                var subitem = {};
                var thread_title = $(ff).find('th.hot,th.common,th.lock');
                var thread_author = $(ff).find('td.author');

                if(!thread_title.length) return;

                subitem.name = $(thread_title).find('span[id] a').first().text();
                subitem.link = $(thread_title).find('span[id] a').first().attr('href');

                if ($(thread_title).find('em').length) {
                    subitem.cat = $(thread_title).find('em').text();
                }

                if (!subitem.link) return;

                if(!thread_author.length) {
                    console.error('【thread_author】', thread_author);
                };

                subitem.author = $(thread_author).find('cite a').first().text();
                subitem.authorid = $(thread_author).find('cite a').attr('href').replace(/.*uid=(\d+)/, "$1");
                subitem.pubdate = $(thread_author).find('em').text();

                if (subitem.link.search(/viewthread\.php/) != -1) {
                    subitem.link = subitem.link + '&authorid=' + subitem.authorid;
                } else {
                    subitem.link = subitem.link.replace(/thread-(\d+)-(\d+)-(\d+)\.html/g, "viewthread.php?tid=$1&page=1&authorid=") + subitem.authorid;
                }

                item.sublist.push(subitem);
            })

            data.list.push(item);
        });

        $("div.pages_btns").first().find("div.pages > *").each(function(i, p){
            if ($(p).is("em")) {
                data.page.total = $(p).text().trim();
                return;
            }
            var item = {};
            item.label = $(p).text().trim();

            if ($(p).is("a")) {
                item.link = $(p).attr('href');
            } else {
                item.link = "#"
            }

            if ($(p).is("strong")) {
                item.cur = true;
            } else {
                item.cur = false;
            }

            if (item.label.trim() == '') {
                return;
            }

            data.page.list.push(item);
        })

        return data;
    }

    function thread_data(){
        var data = {
            'list': [],
            'page':{
                'total': 0,
                'list':[]
            }
        };

        data.thread_title = $(".viewthread").first().find('h1').first().text();

        $(".viewthread").each(function(i, t){
            var post_author = $(t).find("td.postauthor > cite").first().text().trim();
            var post_date = $(t).find("td.postcontent .postinfo").text();
            var post_content = $(t).find("td.postcontent div.postmessage div.t_msgfont").first().html();
            var post_num = $(t).find("td.postcontent .postinfo strong").text().trim();
            post_date = post_date.replace(/.*(\d{4}-\d+-\d+ \d+:\d+).*/gs, "$1");

            //非。!】”」…?结尾的不换行
            post_content = post_content.replace(/(?<=.{25,})(?<![\u3002\uff01\u3011\u201d\u300d\u2026\uff1f])\<br\>/mg, '');
            post_content = post_content.replace(/<font([^>]*)>/, '<font>');
            post_content = post_content.replace(/style="([^"]*)"/, '');
            data.list.push({
                'num': post_num,
                'author': post_author,
                'date': post_date,
                'content': post_content,
            })
        })

        $("div.pages_btns").first().find("div.pages > *").each(function(i, p){
            if ($(p).is("em")) {
                data.page.total = $(p).text().trim();
                return;
            }
            var item = {};
            item.label = $(p).text().trim();

            if ($(p).is("a")) {
                item.link = $(p).attr('href');
            } else {
                item.link = "#"
            }

            if ($(p).is("strong")) {
                item.cur = true;
            } else {
                item.cur = false;
            }

            if (item.label.trim() == '') {
                return;
            }

            data.page.list.push(item);
        })
        return data;
    }

    function sis_app(){

        var template = {
            'index_tpl': `
                <div>
                    <div class="card" v-for="item in forumlist">
                        <div class="card-header">
                            <b><a v-bind:href="item.link" >{{ item.name }}</a></b>
                        </div>
                        <div class="card-body">
                            <p v-for="subitem in item.sublist">
                                <a v-bind:href="subitem.link" >{{ subitem.name}}</a>
                            </p>
                        </div>
                    </div>
                </div>
            `,
            'forum_tpl': `
                <div>
                    <div v-for="(item, key) in list">
                        <h4>{{ item.name }}</h4>
                        <hr>
                        <div>
                            <p v-for="(value2, key2) in item.sublist">
                                <a v-bind:href="value2.link" target="_blank"><em v-if="value2.cat">{{value2.cat}}</em>{{value2.name}}</a>
                                <br>
                                <span class="font-italic">{{value2.author}} - {{value2.pubdate}}</span>
                            </p>
                        </div>
                    </div>
                </div>
                <nav aria-label="Pagination">
                  <ul class="pagination">
                    <li class="page-item" v-bind:class="{active: p.cur}" v-for="p in page.list">
                      <a class="page-link" v-bind:href="p.link">{{p.label}} <span v-if="p.cur" class="sr-only">(current)</span> </a>
                    </li>
                  </ul>
                </nav>
            `,
            'thread_tpl': `
                <div>
                    <h5>{{ thread_title }}</h5>
                    <hr>
                    <div>
                        <div class="card" v-for="post in list">
                          <div class="card-body">
                            <h6 class="card-subtitle mb-2 text-muted">{{post.num}} - {{post.author}} - {{post.date}}</h6>
                            <p class="card-text" v-html="post.content"></p>
                          </div>
                        </div>
                    </div>
                    <nav aria-label="Pagination">
                      <ul class="pagination">
                        <li class="page-item" v-bind:class="{active: p.cur}" v-for="p in page.list">
                          <a class="page-link" v-bind:href="p.link">{{p.label}} <span v-if="p.cur" class="sr-only">(current)</span> </a>
                        </li>
                      </ul>
                    </nav>
                </div>
            `
        };

        // http://sexinsex.net/bbs/viewthread.php?tid=7553901&page=1&authorid=15262419
        const routes = {
            '/bbs/index.php': {
                'data': index_data,
                'template': template.index_tpl
            },
            '/bbs/forumdisplay.php': {
                'data': forum_data,
                'template': template.forum_tpl
            },
            '/bbs/viewthread.php': {
                'data': thread_data,
                'template': template.thread_tpl
            }
        };

        var current_uri = window.location.pathname;

        current_uri = current_uri.replace(/thread-.*\.html/, 'viewthread.php');
        current_uri = current_uri.replace(/forum-.*\.html/, 'forumdisplay.php');
        current_uri = current_uri.replace(/^\/bbs\/$/, '/bbs/index.php');

        console.log("current_uri:", current_uri);

        if (!routes[current_uri]) return;

        var v_data = routes[current_uri].data();
        var v_template = routes[current_uri].template;

        console.log("data:", v_data);
        console.log("template:", v_template);

        init_page();

        $("#sis_app").html(v_template);

        var app = new Vue({
            el: '#sis_app',
            data: v_data
        });

    }

    return {
        'init_page': init_page,
        'sis_app': sis_app,
        'forum_data': forum_data,
        'thread_data': thread_data,
    }

})(window.Zepto, window.Vue);

SIS_APP.sis_app();