Adds direct links to Post Search results to go directly to post, instead of topic.
// ==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);