User:Tfdyrtswa3w4se5dr/fastload.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// Fastload for Wikipedia
// Released under CC0 1.0 Public Domain Dedication.
// https://creativecommons.org/publicdomain/zero/1.0/
// Known Bugs:
// 1. Discussion tag directs to "Talk:Talk:Page_title".
// 2. Link to edit first summary paragraph is incorrect.
/* jshint boss: true */
(function(doc, undefined){
'use strict';
// No support for Internet Explorer 9 or lower without a polyfill.
if (!history.___pushState || !localStorage) return null;
// Removes old cache
localStorage.clear();
// Check Mobile
var isMobile = /Android|iPhone|iPad|iPod|IEMobile/i.test(navigator.userAgent);
// Query Selectors
var $ = function (query) { return doc.querySelector(query); };
$.id = function (query) { return doc.getElementById(query); };
var endpoint = '/w/index.php';
var urlBase = ___location.protocol + '//' + ___location.host + endpoint +
'?action=render&title=';
var noop = function () {};
var Page = {
content: $.id('content'),
container: $.id('bodyContent'),
firstHeading: $.id('firstHeading'),
};
var Tabs = {
main: $('#ca-nstab-main a'),
edit: $('#ca-edit a'),
move: $('#ca-move a'),
history: $('#ca-history a'),
discussion: $('#ca-talk a'),
star: $('#ca-watch a')
};
var attr = function (element, name, value) {
element.setAttribute(name,
(typeof value === 'function') ?
value(element.getAttribute(name)) : value );
};
var Indicator = {
loading: function () {
Page.content.style.opacity = 0.75;
},
reset: function () {
Page.content.style.opacity = null;
}
};
// AJAX utility
var ajax = function (url, callback, error) {
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200)
callback(req.responseText);
};
req.onerror = error;
req.open("GET", url, true);
req.send();
};
ajax.prefixCache = 'fastload-';
ajax.cache = function (url, callback, error) {
var cache;
if (cache = localStorage.getItem(ajax.prefixCache + url)) {
callback(cache);
} else {
ajax(url, function (data) {
callback(data);
try {
localStorage.setItem(ajax.prefixCache + url, data);
} catch (e) {
localStorage.clear();
localStorage.setItem(ajax.prefixCache + url, data);
}
}, error);
}
};
// Updates Cache Now
localStorage.setItem(ajax.prefixCache + urlBase + mw.config.values.wgTitle, Page.container.innerHTML);
// Writes Wikitext to DOM
var updateDom = function (data, title, pageName) {
Page.container.innerHTML = data;
Page.firstHeading.childNodes[0].nodeValue = title;
var oldClassName = doc.body.className.match(/(?! |^)page-[^ ]+/);
doc.body.classList.remove(oldClassName[0]);
doc.body.classList.add('page-' + pageName);
try {
attr(Tabs.main, 'href', '/wiki/' + pageName);
attr(Tabs.discussion, 'href', '/wiki/Talk:' + pageName);
attr(Tabs.edit, 'href', endpoint + '?title=' + pageName + '&action=edit');
attr(Tabs.history, 'href', endpoint + '?title=' + pageName + '&action=history');
attr(Tabs.move, 'href', '/wiki/Special:MovePage/' + pageName);
attr(Tabs.star, 'href', function (link) {
return link.replace(/title=[^&]+/, 'title=' + pageName);
});
} catch (e) { }
doc.title = title + ' — Wikipedia';
doc.body.scrollTop = 0;
};
// Loads when Hover
var delay;
var eventName = isMobile ? 'touchstart' : 'mouseover';
Page.container.addEventListener(eventName, function (event) {
if (delay) {
clearTimeout(delay);
delay = null;
} else {
delay = setTimeout(function(){
var target = event.target, href = target.getAttribute('href');
delay = null;
// Ignore unless clicked on a /wiki/ link.
if (!target || target.tagName !== 'A' || href.indexOf('/wiki/') == -1)
return true;
var pageName = href.replace(/^(\/\/[^\/]+)?\/wiki\//, '');
ajax.cache(urlBase + pageName, noop, noop);
}, 475);
}
});
Page.container.addEventListener('click', function (event) {
var target = event.target, href = target.getAttribute('href');
// Ignore unless clicked on a /wiki/ link.
if (!target || target.tagName !== 'A' || href.indexOf('/wiki/') == -1)
return true;
var pageName = href.replace(/^(\/\/[^\/]+)?\/wiki\//, '');
var title = target.getAttribute('title');
Indicator.loading();
event.preventDefault();
ajax.cache(urlBase + pageName, function (data) {
setTimeout(function () {
updateDom(data, title, pageName);
Indicator.reset();
}, 100);
history.___pushState({
pageName: pageName,
title: title,
url: href
}, title, href);
}, function () {
window.___location.href = href;
});
});
var currentPath = null;
window.onpopstate = function (event) {
var state = event.state;
if (currentPath !== ___location.href) {
currentPath = ___location.href;
if (state && state.pageName) {
ajax.cache(urlBase + state.pageName, function (data) {
updateDom(data, state.title, state.pageName);
});
} else {
window.___location = ___location.href;
}
}
};
})(document);