221 lines
6.3 KiB
JavaScript
221 lines
6.3 KiB
JavaScript
var entries = []; // list of news items
|
|
|
|
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
|
|
"Friday", "Saturday"];
|
|
var months = ["January", "February", "March", "April", "May", "June", "July",
|
|
"August", "September", "October", "November", "December"];
|
|
|
|
// event complete: stop propagation of the event
|
|
function stopPropagation(event) {
|
|
if (event.preventDefault) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
} else {
|
|
event.returnValue = false;
|
|
}
|
|
}
|
|
|
|
// scroll back to the previous article
|
|
function prevArticle(event) {
|
|
for (var i=entries.length; --i>=0;) {
|
|
if (entries[i].anchor.offsetTop < document.documentElement.scrollTop) {
|
|
window.location.hash=entries[i].anchor.id;
|
|
stopPropagation(event);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// advance to the next article
|
|
function nextArticle(event) {
|
|
for (var i=1; i<entries.length; i++) {
|
|
if (entries[i].anchor.offsetTop-20 > document.documentElement.scrollTop) {
|
|
window.location.hash=entries[i].anchor.id;
|
|
stopPropagation(event);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// process keypresses
|
|
function navkey(event) {
|
|
var checkbox = document.getElementById('navkeys');
|
|
if (!checkbox || !checkbox.checked) return;
|
|
|
|
if (!event) event=window.event;
|
|
key=event.keyCode;
|
|
|
|
if (!document.documentElement) return;
|
|
if (!entries[0].anchor || !entries[0].anchor.offsetTop) return;
|
|
|
|
if (key == 'J'.charCodeAt(0)) nextArticle(event);
|
|
if (key == 'K'.charCodeAt(0)) prevArticle(event);
|
|
}
|
|
|
|
// create (or reset) a cookie
|
|
function createCookie(name,value,days) {
|
|
if (days) {
|
|
var date = new Date();
|
|
date.setTime(date.getTime()+(days*24*60*60*1000));
|
|
var expires = "; expires="+date.toGMTString();
|
|
}
|
|
else expires = "";
|
|
document.cookie = name+"="+value+expires+"; path=/";
|
|
}
|
|
|
|
// read a cookie
|
|
function readCookie(name) {
|
|
var nameEQ = name + "=";
|
|
var ca = document.cookie.split(';');
|
|
for(var i=0;i < ca.length;i++) {
|
|
var c = ca[i];
|
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
|
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// each time the value of the option changes, update the cookie
|
|
function selectOption() {
|
|
var checkbox = document.getElementById('navkeys');
|
|
if (!checkbox) return;
|
|
createCookie("navkeys", checkbox.checked?'true':'false', 365);
|
|
}
|
|
|
|
// add navkeys option to sidebar
|
|
function addOption(event) {
|
|
if (entries.length > 1 && entries[entries.length-1].parent.offsetTop > 0) {
|
|
var sidebar = document.getElementById('sidebar');
|
|
if (!sidebar) return;
|
|
|
|
for (var i=entries.length; --i>=0;) {
|
|
var a = entries[i].anchor = document.createElement('a');
|
|
a.id = "news-" + i;
|
|
entries[i].parent.insertBefore(a, entries[i].parent.firstChild);
|
|
}
|
|
|
|
var h2 = document.createElement('h2');
|
|
h2.appendChild(document.createTextNode('Options'));
|
|
sidebar.appendChild(h2);
|
|
|
|
var form = document.createElement('form');
|
|
var p = document.createElement('p');
|
|
var input = document.createElement('input');
|
|
input.type = "checkbox";
|
|
input.id = "navkeys";
|
|
p.appendChild(input);
|
|
var a = document.createElement('a');
|
|
a.title = "Navigate entries";
|
|
a.appendChild(document.createTextNode('Enable '));
|
|
var code = document.createElement('code');
|
|
code.appendChild(document.createTextNode('J'));
|
|
a.appendChild(code);
|
|
a.appendChild(document.createTextNode(' and '));
|
|
code = document.createElement('code');
|
|
code.appendChild(document.createTextNode('K'));
|
|
a.appendChild(code);
|
|
a.appendChild(document.createTextNode(' keys'));
|
|
p.appendChild(a);
|
|
form.appendChild(p);
|
|
sidebar.appendChild(form);
|
|
|
|
var cookie = readCookie("navkeys");
|
|
if (cookie && cookie == 'true') input.checked = true;
|
|
input.onclick = selectOption;
|
|
document.onkeydown = navkey;
|
|
}
|
|
}
|
|
|
|
// convert date to local time
|
|
var localere = /^(\w+) (\d+) (\w+) \d+ 0?(\d\d?:\d\d):\d\d ([AP]M) (EST|EDT|CST|CDT|MST|MDT|PST|PDT)/;
|
|
function localizeDate(element) {
|
|
var date = new Date();
|
|
date.setTime(Date.parse(element.innerHTML + " GMT"));
|
|
|
|
var local = date.toLocaleString();
|
|
var match = local.match(localere);
|
|
if (match) {
|
|
element.innerHTML = match[4] + ' ' + match[5].toLowerCase();
|
|
element.title = match[6] + " \u2014 " +
|
|
match[1] + ', ' + match[3] + ' ' + match[2];
|
|
return days[date.getDay()] + ', ' + months[date.getMonth()] + ' ' +
|
|
date.getDate() + ', ' + date.getFullYear();
|
|
} else {
|
|
element.title = element.innerHTML + ' GMT';
|
|
element.innerHTML = local;
|
|
return days[date.getDay()] + ', ' + date.getDate() + ' ' +
|
|
months[date.getMonth()] + ' ' + date.getFullYear();
|
|
}
|
|
|
|
}
|
|
|
|
// find entries (and localizeDates)
|
|
function findEntries() {
|
|
|
|
var span = document.getElementsByTagName('span');
|
|
|
|
for (var i=0; i<span.length; i++) {
|
|
if (span[i].className == "date" && span[i].title == "GMT") {
|
|
var date = localizeDate(span[i]);
|
|
|
|
var parent = span[i];
|
|
while (parent && parent.className != 'news') {
|
|
parent = parent.parentNode;
|
|
}
|
|
|
|
if (parent) {
|
|
var info = entries[entries.length] = new Object();
|
|
info.parent = parent;
|
|
info.date = date;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// insert/remove date headers to indicate change of date in local time zone
|
|
function moveDateHeaders() {
|
|
lastdate = ''
|
|
for (var i=0; i<entries.length; i++) {
|
|
var parent = entries[i].parent;
|
|
var date = entries[i].date;
|
|
|
|
sibling = parent.previousSibling;
|
|
while (sibling && sibling.nodeType != 1) {
|
|
sibling = sibling.previousSibling;
|
|
}
|
|
|
|
if (sibling && sibling.nodeName.toLowerCase() == 'h2') {
|
|
if (lastdate == date) {
|
|
sibling.parentNode.removeChild(sibling);
|
|
} else {
|
|
sibling.innerHTML = date;
|
|
lastdate = date;
|
|
}
|
|
} else if (lastdate != date) {
|
|
var h2 = document.createElement('h2');
|
|
h2.className = 'date'
|
|
h2.appendChild(document.createTextNode(date));
|
|
parent.parentNode.insertBefore(h2, parent);
|
|
lastdate = date;
|
|
}
|
|
}
|
|
}
|
|
|
|
// adjust dates to local time zones, optionally provide navigation keys
|
|
function personalize() {
|
|
findEntries();
|
|
addOption();
|
|
moveDateHeaders();
|
|
}
|
|
|
|
// hook event
|
|
window.onload = personalize;
|
|
if (document.addEventListener) {
|
|
onDOMLoad = function() {
|
|
window.onload = undefined;
|
|
personalize();
|
|
};
|
|
document.addEventListener("DOMContentLoaded", onDOMLoad, false);
|
|
}
|