User:Gary Queen/layout.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | Documentation for this user script can be added at User:Gary Queen/layout. |
/*
GARY KING'S LAYOUT
FIXME When action=purge, icons are moved up higher.
TODO Change wikEd icon to text.
TODO Add a link to disable all (or also some) of the functions here.
TODO Separate page into functions.
TODO Consider templates (Template:) short pages? (In monobook.js)
TODO Automatically enlarge lead images to 300px when a size has not been set?
*/
/*
hook
*/
addOnloadHook(function()
{
pagesLayout();
});
/*
useful functions
*/
function $(element)
{
return document.getElementById(element);
}
Object.prototype.addClass = function(newClass)
{
element = this;
if (element.className)
{
classes = element.className.split(' ');
classes.push(newClass);
return element.className = classes.join(' ');
}
else return element.className = newClass;
}
Object.prototype.hasClass = function(classToCheck)
{
element = this;
if (!element.className) return false;
classes = element.className.split(' ');
for (var i = 0; i < classes.length; i++)
{
if (classes[i] == classToCheck)
return true;
}
return false;
}
Object.prototype.removeClass = function(oldClass)
{
element = this;
if (!element.className) return false;
classes = element.className.split(' ');
newClasses = [];
for (var i = 0; i < classes.length; i++)
{
if (classes[i] != oldClass)
newClasses.push(classes[i]);
}
return element.className = newClasses;
}
String.prototype.trim = function()
{
return this.replace(/^[\s|\n]+|[\s|\n]+$/g, '');
}
String.prototype.ltrim = function()
{
return this.replace(/^[\s|\n]+/, '');
}
String.prototype.rtrim = function()
{
return this.replace(/[\s|\n]+$/, '');
}
/*
do page layout
*/
function pagesLayout()
{
/*
variables
*/
var content = $('content');
var jumpToNav = $('jump-to-nav');
var pPersonal = $('p-personal');
var afterJumpToNav = jumpToNav.nextSibling.nextSibling.nextSibling.nextSibling;
var bodyContent = $('bodyContent');
var cactions = $('p-cactions');
var caEdit = $('ca-edit');
var caMain = $('ca-nstab-main');
var contentSub = $('contentSub');
var firstDiffElement = content.getElementsByClassName('diff')[0];
var globalWrapper = $('globalWrapper');
var h2 = content.getElementsByTagName('h2');
var paragraphs = content.getElementsByTagName('p');
var pBody = pPersonal.getElementsByClassName('pBody')[0];
var pendingChanges = $('mw-fr-revisiontag');
var relLinks = content.getElementsByClassName('rellink');
var section0 = $('section-0');
var siteSub = $('siteSub');
var toc = $('toc');
var tPrint = $('t-print');
var userMessages = content.getElementsByClassName('usermessage');
var wikiPreview = $('wikiPreview');
var wikitables = content.getElementsByClassName('wikitable');
// don't indent lines in certain cases
// italicized lines that are not indented and therefore look like hatnotes
for (var i = 0; i < paragraphs.length; i++)
{
p = paragraphs[i];
if (p.parentNode != bodyContent && p.parentNode != wikiPreview) continue;
if (p.childNodes.length == 1 && p.firstChild.nodeName == 'I' && p.previousSibling.previousSibling.previousSibling.previousSibling != jumpToNav) p.style.textIndent = 0;
}
// merge multiple hatnotes together
// TODO Make these work together? i.e. if a dablink is followed by a reflink, merge them anyway.
function mergeLinks(className)
{
links = content.getElementsByClassName(className);
for (var i = links.length - 1; i >= 0; i--)
{
l = links[i];
// give "title" attribute to node
l.title = className;
if (!l.nextSibling || !l.nextSibling.nextSibling || !l.nextSibling.nextSibling.hasClass(className)) continue;
nextEl = l.nextSibling.nextSibling;
nextEl.addClass('merged-hatnote');
text = document.createTextNode(className == 'dablink' ? ' ' : '. ');
l.appendChild(text);
l.appendChild(nextEl);
}
}
mergeLinks('dablink');
mergeLinks('rellink');
// contentSub (redirects, contribution page user info, etc.)
if (contentSub.firstChild)
{
if (pendingChanges)
{
newPCDiv = document.createElement('div');
newPCDiv.addClass('contentSub');
newPCDiv.style.display = 'block';
newPCDiv.appendChild(pendingChanges);
contentSub.parentNode.insertBefore(newPCDiv, jumpToNav);
}
contentSub.addClass('merged-content-sub');
if (contentSub.firstChild.nodeType == 3) contentSub.firstChild.nodeValue = contentSub.firstChild.nodeValue.replace(/^\s+/g, '');
newDiv = document.createElement('div');
newDiv.style.display = 'block';
newDiv.addClass('contentSub');
contentSub.parentNode.insertBefore(newDiv, contentSub.nextSibling);
}
else contentSub.addClass('contentSub');
// move a left-aligned thumb image to before any header that immediately precedes it
leftAlignedThumb = 'tleft';
thumbs = content.getElementsByClassName(leftAlignedThumb);
for (var i = 0; i < thumbs.length; i++)
{
t = thumbs[i];
movedText = 'This left-aligned image thumb was moved from the section below to the section above, in accordance with the Manual of Style (WP:MOS).';
// immediately precedes it
if (!t.previousSibling && !t.previousSibling.previousSibling) continue;
prev = t.previousSibling.previousSibling;
if (prev.nodeName == 'H3' || prev.nodeName == 'H4' || prev.nodeName == 'H5')
{
t.parentNode.insertBefore(t, prev);
t.title = movedText;
}
// preceded by a rellink, then precedes it
if (!prev.previousSibling && !prev.previousSibling.previousSibling && !prev.previousSibling.previousSibling.hasClass('rellink')) continue;
prev = prev.previousSibling.previousSibling;
if (prev && (prev.nodeName == 'H3' || prev.nodeName == 'H4' || prev.nodeName == 'H5'))
{
t.parentNode.insertBefore(t, prev);
t.title = movedText;
}
}
// indent rellinks if an image is to the left of it
for (var i = 0; i < relLinks.length; i++)
{
l = relLinks[i];
if (!l.previousSibling) continue;
two = l.previousSibling.previousSibling;
three = two.previousSibling;
four = three.previousSibling;
if ((two && two.hasClass(leftAlignedThumb)) || (three && three.hasClass(leftAlignedThumb)) || (four && four.hasClass(leftAlignedThumb))) l.addClass('text-indent');
}
// proper padding for left- and right-aligned tables
function checkAndFixTableMargins(table, alignment)
{
if (alignment != 'left' && alignment != 'right') return false;
margin = (alignment == 'left' ? table.style.marginRight : table.style.marginLeft);
type = margin.substring(margin.length - 2, margin.length);
value = parseInt(margin);
if (type == 'em' && value < 1) result = '1em';
else if (type == 'px' && value < 13) result = '13px';
if (alignment == 'left') table.style.marginRight = result;
else table.style.marginLeft = result;
return result;
}
for (var i = 0; i < wikitables.length; i++)
checkAndFixTableMargins(wikitables[i], wikitables[i].align)
// add more space above .usermessage on Main Page
if (wgCanonicalNamespace == '' && wgTitle == wgMainPageTitle && userMessages.length > 0)
userMessages[0].style.margin = '2em 0 0 0';
// have no max width for non-standard TOCs
toctitle = $('toctitle');
if (!toctitle) appendCSS('.toc { max-width: none; }');
// add accesskeys for QE section links
for (var i = 1; i <= 9; i++)
{
link = $('sectionlink-' + i);
if (!link) break;
link.accessKey = i;
}
// number h2 headers
if (!(wgCanonicalNamespace == '' && wgTitle == wgMainPageTitle) && (wgAction == 'view' || wgAction == 'purge'))
{
if (firstDiffElement) start = 2;
else if (toc) start = 1;
else start = 0;
begin = 0;
for (var i = start; i < h2.length; i++)
{
number = document.createElement('span');
number.addClass('heading-number');
number.appendChild(document.createTextNode(begin + 1 + '. '));
h2[i].insertBefore(number, h2[i].firstChild);
begin++;
}
}
// remove diff whitespace, around .diff-deletedline and .diff-addedline
deletedLines = content.getElementsByClassName('diff-deletedline');
addedLines = content.getElementsByClassName('diff-addedline');
function trimDiffs(elements)
{
for (var i = 0; i < elements.length; i++)
{
if (!elements[i].firstChild) continue;
elements[i].firstChild.innerHTML = elements[i].firstChild.innerHTML.trim();
}
}
// FIXME Removes * and perhaps other characters at beginning of the line.
/*trimDiffs(deletedLines);
trimDiffs(addedLines);*/
// TODO Use white-space: pre-wrap; on deletedLines[i].firstChild and strip whtiespace added
// by the software so that added/removed whitespaces are more clear?
// remove extra line breaks - only in articles, for now at least
if (wgCanonicalNamespace == '')
{
// at the beginning of the page
next = afterJumpToNav;
if (next.hasClass('dablink'))
{
next2 = next.nextSibling.nextSibling;
next3 = next2.nextSibling.nextSibling;
if (next2.nodeName == 'P' && next2.firstChild.nodeName == 'BR')
next2.removeChild(next2.firstChild);
else if (next3.nodeName == 'P' && next3.firstChild.nodeName == 'BR')
next3.removeChild(next3.firstChild);
}
// before the TOC
if (toc && toc.previousSibling.previousSibling)
{
beforeTOC = toc.previousSibling.previousSibling;
if (beforeTOC.nodeName == 'P' && beforeTOC.childNodes.length == 1 && beforeTOC.firstChild.nodeName == 'BR')
beforeTOC.parentNode.removeChild(beforeTOC);
}
}
}