Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
SCP Foundation: Add names to details pages: Adds the descriptive names from the SCP series index page to the individual detail pages, and provides previous and next buttons to navigate through SCPs.
// ==UserScript==
// @name SCP Foundation: Add names to details pages
// @namespace https://gist.github.com/ksemel/3e189fef865a02ee9956
// @description Adds the descriptive names from the SCP series index page to the individual detail pages, and provides previous and next buttons to navigate through SCPs.
// @author Katherine Semel
// @date 2011-09-02
// @revision 2021-03-07
// @version 3.0
// @include /(?:scp-wiki\.wikidot\.com)\/(?:adult:)?(scp-[0-9]+)/
// @grant GM_xmlhttpRequest
// ==/UserScript==
function addScripts(pageContent) {
// Add the scripts to the document
let script = document.createElement("script");
script.type = 'text/javascript';
script.textContent = updateSCPDisplay.toString();
script.textContent += getSCPname.toString();
document.head.appendChild(script);
}
/*
Get the SCP name from the series page content that we fetched initially
TODO: Fails on "new page" links
TODO: Fails on first/last entry between series
*/
function getSCPname(thisSCP, pageContent) {
let newtitle = '';
//console.log('FIND SCP: ' + thisSCP);
// Grab the text following the /scp-000 reference...
const startSearch = '<li><a href="/scp-' + thisSCP + '">SCP-' + thisSCP + '</a> - ';
const endSearch = '</li>';
const startFind = pageContent.indexOf(startSearch);
if (startFind > 0) {
// ...up to the end of the LI
const endFind = pageContent.indexOf(endSearch, startFind);
// Title is between those indexes
newtitle = 'SCP-' + thisSCP + ': ' + pageContent.substring(startFind + startSearch.length, endFind);
} else {
// Return a placeholder title when failing
newtitle = 'SCP-' + thisSCP + ': ACCESS DENIED';
}
return newtitle;
}
/*
Fetch SCP names and make our HTML changes to add them to the pages
*/
function updateSCPDisplay(pageContent, scpDomain, thisSCP) {
// handle a few formatting differences by adding a title div to pages missing one
if (document.getElementById('page-title') == null) {
let pageTitle = document.createElement("div");
pageTitle.setAttribute('id', 'page-title');
document.getElementById('action-area-top').parentNode.insertBefore(pageTitle, document.getElementById('action-area-top').nextSibling);
}
// Get the next and previous SCPs from the current
thisSCP = thisSCP.toString().padStart(3, '0');
const thisSCPtitle = getSCPname(thisSCP, pageContent);
// Replace the <title>
document.title = 'The SCP Foundation: ' + thisSCPtitle;
// Replace the page-title with the cleaned up contents
document.getElementById('page-title').innerHTML = thisSCPtitle;
let script = document.createElement("div");
script.setAttribute('style', 'width:100%;height:50px;');
// Do we have a Next link?
let nextSCP = parseInt(thisSCP, 10) + 1;
let nextSCPlink = "";
if (nextSCP < 6000) {
nextSCP = nextSCP.toString().padStart(3, '0');
const nextSCPtitle = getSCPname(nextSCP, pageContent);
nextSCPlink = '<a href="' + scpDomain + '/scp-' + nextSCP + '" title="' + nextSCPtitle + '">' + nextSCPtitle + '&nbsp;&raquo;</a>';
script.innerHTML = '<div style="float:right">' + nextSCPlink + '</div>'
}
// Do we have a Previous link?
let prevSCP = parseInt(thisSCP, 10) - 1;
let prevSCPlink = "";
if (prevSCP > 0) {
prevSCP = prevSCP.toString().padStart(3, '0');
const prevSCPtitle = getSCPname(prevSCP, pageContent);
prevSCPlink = '<a href="' + scpDomain + '/scp-' + prevSCP + '" title="' + prevSCPtitle + '">&laquo;&nbsp;' + prevSCPtitle + '</a>';
script.innerHTML += '<div style="float:left">' + prevSCPlink + '</div>';
}
// Add the links under the title
document.getElementById('page-title').parentNode.insertBefore(script, document.getElementById('page-title').nextSibling);
document.getElementById('page-title').style.display = 'block';
}
/*
Kick it off with some RegEx on the url
*/
const thisURL = document.location.href;
// RegEx Builder: https://regex101.com/r/hHMfy6/1
// Returns scpDomain as match 1
// Returns thisSCP as match 2
let regex = /^((?:https|http):\/\/scp-wiki\.wikidot\.com)\/(?:adult:)?(scp-[0-9]+)/g
let match = regex.exec(thisURL);
const scpDomain = match[1];
const thisSCP = match[2].replace('scp-', '');
// Which series? Now vaguely futureproof!
let series = '';
if (thisSCP > 999) {
series = parseInt(thisSCP.toString()[0]) + 1;
series = '-' + series;
}
// Request the series page
GM_xmlhttpRequest({
method: "GET",
url: scpDomain + "/scp-series" + series,
onload: function(response) {
// Add our scripts to the head
addScripts();
// Run the updates
updateSCPDisplay(response.responseText, scpDomain, thisSCP);
}
});
@ksemel

This comment has been minimized.

Copy link
Owner Author

@ksemel ksemel commented Mar 7, 2021

The latest version accounts for more differences on the pages and the potential for additional series.

Fetches the SCP titles more consistently, and adds the page title container on pages that lack it.

Standard Page:
Screen Shot 2021-03-07 at 2 38 22 PM

New SCP Page (no scp yet)
Screen Shot 2021-03-07 at 2 40 03 PM

Custom Designed Page:
Screen Shot 2021-03-07 at 2 40 52 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment