WaniKani Post Search Direct Link

Adds direct links to Post Search results to go directly to post, instead of topic.

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

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

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

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

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

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

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        WaniKani Post Search Direct Link
// @namespace   rfindley
// @description Adds direct links to Post Search results to go directly to post, instead of topic.
// @version     1.0.3
// @include     https://www.wanikani.com/*
// @exclude     https://www.wanikani.com/lesson*
// @exclude     https://www.wanikani.com/review*
// @copyright   2015+, Robin Findley
// @license     MIT; http://opensource.org/licenses/MIT
// @run-at      document-end
// @grant       none
// ==/UserScript==

wkgotopost = {};

(function(gobj) {
    if (typeof $ === 'undefined') return;

    var observer;

    //-------------------------------------------------------------------
    // Process a clicked link
    //-------------------------------------------------------------------
    function link_clicked(e) {
        e.preventDefault();
        var target = $(e.target);
        var post = target.closest('tr[id^="post"]');
        var pid = post.attr('id');
        target.html('one moment...');

        var base_url = target.closest('.related-topic').find('a:nth(0)').attr('href');
        var pdate = (new Date(post.find('.timeago:nth(0)').attr('datetime'))).getTime();
        var first_page = 1;
        var last_page = 1;
        var max_depth = 14;

        function find_post(pgnum) {
            var pgurl = base_url+'/page/'+pgnum;
            $.get(pgurl, function(page){
                var pg = $(page);
                if (pgnum == 1) {
                    var last_elem = pg.find('.multi-page li:last a');
                    if (last_elem.length > 0)
                        last_page = Number(last_elem.attr('href').split('/').pop());
                    gobj.last_page = last_page;
                }
                if (pg.find('tr[id="'+pid+'"]').length > 0) {
                    target.off('click');
                    target.attr('href', pgurl+'#'+pid);
                    target.html('click to go');
                } else {
                    if (pgnum != 1) {
                        var sdate = (new Date(pg.find('tr[id^="post"] .timeago:first-child').slice(-1).attr('datetime'))).getTime();
                        if (pdate < sdate)
                            last_page = pgnum-1;
                        else
                            first_page = pgnum+1;
                    }
                    if (max_depth-- > 0)
                        find_post(Math.ceil((first_page+last_page)/2));
                    else
                        console.log('Oops.. too many searches!');
                }
            });
        }
        find_post(1);
    }

    //-------------------------------------------------------------------
    // Process DOM changes due to search, adding link to each post.
    //-------------------------------------------------------------------
    function search_mutation(mutation_list) {
        for (var m_idx = 0; m_idx < mutation_list.length; m_idx++) {
            var added_nodes = mutation_list[m_idx].addedNodes;
            for (var n_idx = 0; n_idx < added_nodes.length; n_idx++) {
                var addition = $(added_nodes[n_idx]);
                if (!addition.hasClass('forum')) continue;
                $('<span class="gotopost">(<a href="javascript(void);">get link</a>)</span>').insertAfter(addition.find('tr[id^="post"] .related-topic>a'));
                addition.find('.gotopost a').on('click', link_clicked);
            }
        }
    }

    //-------------------------------------------------------------------
    // Add a <style> section to the document.
    //-------------------------------------------------------------------
    function addStyle(aCss) {
        var head, style;
        head = document.getElementsByTagName('head')[0];
        if (head) {
            style = document.createElement('style');
            style.setAttribute('type', 'text/css');
            style.textContent = aCss;
            head.appendChild(style);
            return style;
        }
        return null;
    }

    //-------------------------------------------------------------------
    // Startup. Runs at document 'load' event.
    //-------------------------------------------------------------------
    function startup() {
        var elem = $('.search-results')[0];
        if (elem === undefined) return;
        addStyle('.gotopost {margin-left:10px;font-size:smaller;} .gotopost a {text-decoration:underline;}');
        observer = new MutationObserver(search_mutation);
        observer.observe(elem, {
            subtree: true,
            childList: true
        });
    }

    // Run startup() after window.onload event.
    if (document.readyState === 'complete')
        startup();
    else
        window.addEventListener("load", startup);

})(wkgotopost);