Last active
August 3, 2019 20:00
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==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