Skip to content

Instantly share code, notes, and snippets.

@chriskempson
Last active August 3, 2019 20:00
Show Gist options
  • Save chriskempson/f4abaf1bbe31f7abbe2055ff4836c839 to your computer and use it in GitHub Desktop.
Save chriskempson/f4abaf1bbe31f7abbe2055ff4836c839 to your computer and use it in GitHub Desktop.
A little JS and CSS to clean up WillMollyWilly and add a couple of navigational buttons for a more pleasant reading experience.
// ==UserScript==
// @name WillMollyWilly Assist
// @author Chris Kempson (chriskempson.com)
// @version 1.0.0
// @match *://blogs.yahoo.co.jp/willmollywilly*
// @grant none
// ==/UserScript==
// Replaces ----... with <hr>, adds class to sentence numbers, adds class
// to separators (***... and *...)
var el = document.getElementsByClassName('entryTd');
for (var i = 0; i < el.length; i++) {
el[i].innerHTML = el[i].innerHTML.replace(/[-]{4,}/g, '<hr>');
el[i].innerHTML = el[i].innerHTML.replace(/(\([0-9]*\))/g, '<div class="sentence-number">$1</div>');
el[i].innerHTML = el[i].innerHTML.replace(/([*]{2,})/g, '<div class="separator">$1</div>');
el[i].innerHTML = el[i].innerHTML.replace(/([*]{1,})/g, '<div class="separator">$1</div>');
// Remove last hr
var hr = el[i].getElementsByTagName('hr');
hr[hr.length - 1].remove();
}
// Add scroll to previous/next sentence/paragraph and navigate to the
// previous/next pages by on screen buttons or keypresses
var currentHr = -1; // Start from -1 so we advance to 0 (first HR)
var hr = document.getElementById('mainContentsArea').getElementsByTagName('hr');
// Inject buttons
document.body.insertAdjacentHTML('beforeend', '<div id="buttons"><div id="previous">Previous</div><div id="next">Next</div></div>');
var previousNextA = document.querySelectorAll('.forwardNext a');
var previousHref = previousNextA[0].href;
var nextHref = previousNextA[1].href;
function scrollToPrevious()
{
currentHr--;
// Scroll to the previous hr or move to the previous page
if (typeof hr[currentHr] == 'object') {
hr[currentHr].scrollIntoView({ behavior: 'smooth' });
}
else {
window.location.href = previousHref;
}
}
function scrollToNext()
{
currentHr++;
// Scroll to the next hr or move to the previous page
if (typeof hr[currentHr] == 'object') {
hr[currentHr].scrollIntoView({ behavior: 'smooth' });
}
else {
window.location.href = nextHref;
}
}
// Bind to buttons
document.getElementById('previous').onclick = function()
{
scrollToPrevious();
};
document.getElementById('next').onclick = function()
{
scrollToNext();
};
// Bind to keypress
function keydownHandler(event)
{
// When using Yomichan with 'Automatically hide results' enabled,
// Yomichan's popups cause the main window to loose focus and these
// keydown events can no longer function ;_;
switch (event.key) {
case 'ArrowLeft':
scrollToPrevious();
event.preventDefault();
break;
case 'ArrowRight':
scrollToNext();
event.preventDefault();
break;
case 'ArrowUp':
scrollToPrevious();
event.preventDefault();
break;
case 'ArrowDown':
scrollToNext();
event.preventDefault();
break;
case 'j':
scrollToNext();
break;
case 'k':
scrollToPrevious();
break;
}
}
document.addEventListener('keydown', keydownHandler, true);
// Try to keep scroll and currentHr in sync
window.onscroll = function(event)
{
// for (var i = hr.length - 1; i > 0; i--) {
for (var i = 0; i < hr.length; i++) {
if (isScrolledIntoView(hr[i])) {
currentHr = i;
console.log(currentHr);
return;
}
}
};
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
// Inject CSS
document.body.insertAdjacentHTML('beforeend', `
<style>
/* Font stying and spacing fixes */
.entry {
font-family: sans-serif;
line-height: 2.25em;
}
.entryTd font[size="4"] {
font-size: 1.25em;
}
rt {
font-weight: bold;
color: #A77534;
font-size: 0.55em;
}
r {
line-height: 2.5em;
}
.separator,
.sentence-number {
font-size: 0.75em;
font-weight: bold;
color: #A77534;
text-align: right;
margin: -2em 0 -2.5em 0;
}
.separator {
text-align: center;
margin-bottom: -3em;
}
/* Hide annoying Yahoo Search popup*/
#yjSearchPop {
visibility: hidden;
}
/* Expand the main body and hide the side column */
#sideColumn {
display: none;
}
#mainContentsArea .entry .entryBody p {
word-break: normal !important;
}
#mainContentsArea .entry .entryTitle {
width: 894px !important;
}
#mainContentsArea .entry {
width: 898px !important;
}
#mainContentsArea .entryMetaInfo,
#mainContentsArea .entryBody {
width: 868px !important;
}
table {
width: 100% !important;
}
/* Style the hr the JS inserts */
hr {
margin: 1.75em 0 0 0;
border: none;
background-color: #A77534;
background-image: url("https://s.yimg.jp/i/jp/blog/p3/images/folder/boxset/159/dot_hor3.gif");
height: 1px;
}
/* Style the next/previous buttons the JS inserts */
#buttons {
position: fixed;
bottom: 25px;
right: 25px;
font-family: sans-serif;
}
#next,
#previous {
background: #A77534;
color: #fff;
padding: 10px 20px;
margin-top: 1em;
}
</style>`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment