User:Gary/layout.js

/*	GARY'S LAYOUT NOTES shows references as intended. forces a page to be thin.

if (typeof(unsafeWindow) != 'undefined') {	addOnloadHook = unsafeWindow.addOnloadHook; console = unsafeWindow.console; importStylesheet = unsafeWindow.importStylesheet; isDiscussionPage = unsafeWindow.isDiscussionPage; mw = unsafeWindow.mw; }

$(function {	mw.util.addCSS('\ .grey-border { border: 1px solid #aaa; }\ .lead-qe-link { margin-top: 15px; float: right; }\ \		.heading-anchor { visibility: hidden; font-size: .75em; position: absolute; }\ .heading:hover .heading-anchor { visibility: visible; }\ '); });

function adjustReferences {	// For only $('.references').each(function	{		/*			Add reflist to 		*/		var ref = $(this);		var parent = ref.parent;		var parentClass = parent.attr('class');		if (!parent.hasClass('reflist') && !parent.hasClass('refbegin')) 		{			ref.addClass('reflist');			ref.css('padding-left', '3em');		}		/*			Adjust references		*/		// Handle different situations of "references".		var refWrapper;

if (parent.hasClass('reflist')) refWrapper = parent; // "reflist" else refWrapper = ref; var colCount = parseInt(refWrapper.css('-moz-column-count')) || 1; var colWidth = refWrapper.css('-moz-column-width') || '30em';

if (colCount > 1 || (colWidth.substr(colWidth.length - 2, 2) == 'px' && parseInt(colWidth) >= 360)) refWrapper.addClass('autoColumns'); if (refWrapper.get(0).scrollHeight > 250) refWrapper.addClass('grey-border');

// Indicate how many references there are in the box. var numberOfReferences = ref.children.length; var referencesHeading = refWrapper.prev; if (referencesHeading.length && (referencesHeading[0].nodeName == 'H2' || referencesHeading[0].nodeName == 'H3' || referencesHeading[0].nodeName == 'DL')) {			var standardHeadline = $('.mw-headline', referencesHeading).eq(0); var indentedHeadline = referencesHeading.children.eq(0); var referencesHeadling; if (standardHeadline.length) referencesHeadline = standardHeadline; else referencesHeadline = indentedHeadline; var newReferencesNode = $(' ').css('font-size', '75%').css('color', 'grey').css('font-weight', 'normal').append(' (' + numberOfReferences + ' total)'); referencesHeadline.append(newReferencesNode); }	});	// For anything else with 	$('.refbegin').each(function {		var refbegin = $(this); var colCount = parseInt(refbegin.css('-moz-column-count')) || 1; var colWidth = refbegin.css('-moz-column-width') || '30em'; if (colCount > 1 || colWidth.substr(colWidth.length - 2, 2) == 'px' && parseInt(colWidth >= 360)) refbegin.addClass('autoColumns'); if (refbegin.get(0).scrollHeight > 250) refbegin.addClass('grey-border'); }); }

// Get length in pixels function getLengthInPixels(length, emInPixels) {	// 1em ~ 13px if (typeof(emInPixels) == 'undefined') emInPixels = 13; var value = parseInt(length); var type = length.substring(length.length - 2, length.length);

if (type == 'em') {		value = value * emInPixels; type = 'px'; }	return [value, type]; }

// sameCSS("attr", "value", firstjQueryNode, secondjQueryNode, thirdjQueryNode); function sameCSS {	var arguments = Array.prototype.slice.call(arguments); if (arguments.length < 3) return false; var attr = arguments.shift; var value = arguments.shift; for (var i = 0; i < arguments.length; i++) arguments[i].css(attr, value); return true; }

/*	Access keys function accessKeys {	var caEdit = $('#ca-edit'); var caViewSource = $('#ca-viewsource'); /*		Disable access keys */	$('#p-logo').children.eq(0).attr('accesskey', null); // Disable logo // disable access keys, so quickedit can use them if (mw.config.get('wgAction') == 'view' || mw.config.get('wgAction') == 'purge') {		if (caEdit.length) caEdit.children.eq(0).attr('accesskey', null); // edit this page else if (caViewSource.length) caViewSource.children.eq(0).attr('accesskey', null); // view source }	$('#searchInput').attr('accesskey', null); // search box $('#t-recentchangeslinked').children.eq(0).attr('accesskey', null); // related changes /*		Enable access keys */	// TODO Change the text for certain links, like for "edit this page", remove [ctrl-e]; create a common function to use for all of them // add access key to edit/view source, for consistency, as QuickEdit is already using the old one if (caEdit.length) caEdit.children.eq(0).attr('accesskey', 'f'); else if (caViewSource.length) caViewSource.children.eq(0).attr('accesskey', 'f'); // viewing a non-existent page if (!caEdit.children.eq(0).attr('accesskey') && caEdit.children.eq(0).contents.eq(0).text == 'Create this page') caEdit.children.first.attr('accesskey', 'f'); // Diff navigation links // check if we're viewing an oldid page var revisionNav = $('#mw-revision-nav'); var mwPrevlink = $('.mw-prevlink'); var mwNextlink = $('.mw-nextlink'); var prevlink, nextlink; // Viewing a single revision if (revisionNav.length) {		prevlink = revisionNav.children.first; nextlink = revisionNav.children.last; }	else if (mwPrevlink.length || mwNextlink.length) {		prevlink = mwNextlink.eq(0); nextlink = mwPrevlink.eq(0); }	else {		prevlink = $('#differences-prevlink'); nextlink = $('#differences-nextlink'); }

// assign previous and next links if (!$('#wpPreview').length) {		prevlink.attr('accesskey', 'p'); $('#pt-mytalk').children.first.attr('accesskey', null); nextlink.attr('accesskey', 'n'); }	// Content accesskey var contentIds = ['ca-nstab-book', 'ca-nstab-portal', 'ca-nstab-special']; var contentTab = ''; for (var i = 0; i < contentIds.length; i++) {		var id = contentIds[i]; if ($('#' + id).length) {			contentTab = id; break; }	}

if (contentTab) $('#' + contentTab).children.eq(0).attr('accesskey', 'c');

// QuickEdit link var findEdit = $('#t-find-edit'); if (/*$('#contentSub').contents.length && */!$('#ca-nstab-special').length) $('#sectionlink-0').attr('accesskey', 'b'); else if (findEdit.length) findEdit.children.eq(0).attr('accesskey', 'b'); if (mw.config.get('wgPageName') == 'Special:Search' && $('.new').length) $('.new').eq(0).attr('accesskey', 'f'); // creating new page, from search results page // For diffs, jump to article var diffHeading = $('h2').eq(0); if ($('.diff').length && diffHeading.length) diffHeading.attr('id', 'diffHeading').before($('').css('display', 'none').attr('href', '#diffHeading').attr('accesskey', 'd')); // Create link to use to jump

/*		Sidebar links */	var pageSize = $('#t-page-size'), drafts = $('#t-drafts'), goals = $('#t-goals'); // Page Size if (pageSize.length) {		var pageSizeLink = pageSize.children.eq(0).children.eq(0); $('#t-specialpages').children.eq(0).attr('accesskey', null); pageSizeLink.attr('accesskey', 'q'); pageSizeLink.attr('title', pageSizeLink.attr('title') + ' [ctrl-q]'); }	if (drafts.length && !$('.diff').length) drafts.children.eq(0).attr('accesskey', 'd'); // Drafts // if (goals.length) goals.children.eq(0).attr('accesskey', 'g'); // Goals // Disable access key for "Data item" if ($('#t-wikibase').length) $('#t-wikibase').children(':first').attr('accesskey', ''); // Jump to References (replacing Recent Changes). Nullify access key from Recent Changes. if (mw.config.get('wgCanonicalNamespace') == '' && mw.config.get('wgPageName') != 'Main_Page') $('#n-recentchanges').children.first.attr('accesskey', null);

var referenceTerms = ['notes', 'references', 'sources']; // Alternative names var tocList = $('#toc ul').eq(0); var references = ''; function hasReferenceTerm(phrase) {		for (var i = 0; i < referenceTerms.length; i++) {			var pattern = new RegExp(referenceTerms[i], 'i'); if (phrase.match(pattern)) return true; }		return false; }	tocList.children.each(function	{		// Find another "References" section in the TOC			var href = $(this).contents.first.attr('href');		if (hasReferenceTerm(href))		{			href = href.substring(href.indexOf('#') + 1);			references = $('#' + href);			return false;		}	});

if (references.length) {		// Create link to use to jump var jump = $(''); references.after(jump); } }

/*	Page layout function pagesLayout {	var html = $('html'); var bodyContent = $('#bodyContent'); var wikiPreview = $('#wikiPreview'); // same as above, but when previewing a page var mwContent = $('.mw-content-ltr:eq(0)'); var pBody = $('#p-personal .pBody'); var cactions = $('#p-cactions'); var globalWrapper = $('#globalWrapper'); var isPrintable = location.href.match(/&printable=yes/) ? true : false; /*		Layout */	// Fatter pages except when it would exceed page width if (html.innerWidth > 1425) sameCSS('width', '1400px', globalWrapper, cactions, pBody); else sameCSS('width', (html.innerWidth - 25) + 'px', globalWrapper, cactions, pBody); // Thinner page width for articles (1000 pixels wide) var thinnerPage = false; var fatterPage = false; // TODO fatterPages // fatterPageTerms if (typeof(fatterPageTerms) == 'object' && fatterPageTerms.length > 0) {		for (var i = 0; i < fatterPageTerms.length; i++) {			if (mw.config.get('wgPageName').replace(/_/g, ' ').indexOf(fatterPageTerms[i]) != -1) {				fatterPage = true; break; }		}	}	// thinnerPages if (typeof(thinnerPages) == 'object' && thinnerPages.length > 0) {		for (var i = 0; i < thinnerPages.length; i++) {			if (mw.config.get('wgPageName').indexOf(thinnerPages[i].replace(/ /g, '_')) == 0) {				thinnerPage = true; break; }		}	}	// TODO thinnerPageTerms // Thinner pages for articles if (html.innerWidth > 1025 && fatterPage == false && (mw.config.get('wgCanonicalNamespace') ==  || thinnerPage) && (mw.config.get('wgAction') == 'view' || mw.config.get('wgAction') == 'submit' || mw.config.get('wgAction') == 'edit' || mw.config.get('wgAction') == 'purge') && !(mw.util.getParamValue('title') && mw.util.getParamValue('diff')) && !(mw.config.get('wgCanonicalNamespace') ==  && mw.config.get('wgTitle') == mw.config.get('wgMainPageTitle'))) {		sameCSS('width', '1000px', globalWrapper, cactions, pBody); }	// Forced page to use article styles if ($('#thinner-page').length) {		sameCSS('width', '1000px', globalWrapper, cactions, pBody); mw.util.addCSS('#bodyContent > div > p, #wikiPreview > div > p, .text-indent { text-indent: 2em !important; }'); }	// Shorter search text (searchGoButton, mw-searchButton) $('#searchGoButton').attr('value', 'G'); $('#mw-searchButton').attr('value', 'S'); // TODO Recognize empty (can't use it for  since it outputs an empty ). /*		Discussion pages */	// changes for non-discussion and discussion pages; covers discussion pages not in a "talk:" namespace, such as many noticeboards isDiscussionPage = isDiscussionPage || ($('#ca-addsection').length ? true : false); // don't add fancy text changes on pages with short paragraphs (discussions), AND better separate discussions if (isDiscussionPage) {		importStylesheet('User:Gary/short paragraphs.css'); importStylesheet('User:Gary/discussions.css'); }	// don't indent lines in certain cases // italicized lines that are not indented and therefore look like hatnotes $('p').each(function	{		var p = $(this);		if (p.parent.parent[0] != bodyContent[0] && p.parent.parent[0] != wikiPreview[0]) return true;		if (p.children.length == 1 && p.contents.length == 1 && p.children.first[0].nodeName == 'I' && p.prev.length && p.prev[0] != $('.previewnote:first')[0]) p.css('text-indent', 0);	}); /*		Move a left-aligned thumb image to before any header (H3 or lower) that immediately precedes it	*/ var leftAlignedThumb = 'tleft'; var thumbs = $('.' + leftAlignedThumb); function moveLeftAlignedImage(t) {		var 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).'; var prev = t.prev; if (prev && prev[0] && (prev[0].nodeName == 'H3' || prev[0].nodeName == 'H4' || prev[0].nodeName == 'H5')) {			prev.before(t); t.attr('title', movedText); }	}	thumbs.each(function	{		var t = $(this);		if (t.prev) moveLeftAlignedImage(t); else return; // Immediately precedes it		if (t.prev.prev && t.prev.prev.hasClass('rellink')) moveLeftAlignedImage(t.prev); else return; // Preceded by a rellink, then precedes it	}); // indent rellinks if an image is to the left of it	$('.rellink').each(function	{		var l = $(this);		if (!l.prev) return;		var prev = l.prev;		if (!prev.prev) return;		var twoPrev = prev.prev;		if ((prev && prev.hasClass(leftAlignedThumb)) || (twoPrev && twoPrev.hasClass(leftAlignedThumb))) l.addClass('text-indent');	});

// proper padding for left- and right-aligned tables $('.wikitable').each(function	{		var alignment, result;		var table = $(this);		// calculate "alignment"		if (table.attr('align')) alignment = table.attr('align');		else if (table.css('float')) alignment = table.css('float');		if (alignment != 'left' && alignment != 'right') return false;		var margin = (alignment == 'left' ? table.css('margin-right') : table.css('margin-left'));		var pixelLengths = getLengthInPixels(margin)		var value = pixelLengths[0];		var type = pixelLengths[1];		if (type == 'px' && value < 13) result = '13px';		else if ((type == 'em' && value < 1) || !type) result = '1em';		else result = '1em'; // may need to add checks for more "type"s		if (alignment == 'left') table.css('margin-right', result);		else table.css('margin-left', result);	}); // add more space above .usermessage on Main Page var userMessages = $('.usermessage'); if (mw.config.get('wgCanonicalNamespace') == '' && mw.config.get('wgTitle') == mw.config.get('wgMainPageTitle') && userMessages.length) userMessages.eq(0).css('margin', '2em 0 0 0'); /*		TABLE OF CONTENTS */	// have no max width for non-standard TOCs if (!$('#toctitle').length) mw.util.addCSS('.toc { max-width: none; }'); // Move numbers in TOC out of link. $('.tocnumber').each(function	{		var number = $(this);		number.append('.');		number.parent.parent.prepend(number);	}); // add an anchor link next to each heading if (!isPrintable) {		$('.mw-headline').each(function		{			var headline = $(this);			var id = headline.attr('id');			if (id)			{				headline.parent.addClass('heading');				headline.after(' #'); // Link right after the heading.			}		}); }	/*		ARTICLES */	// Clickable Protection Icon: Allows users to click on protection icons to see the protection log. var protectionIcon = $('#protected-icon'); if (protectionIcon.length) protectionIcon.children.first.attr('href', mw.config.get('wgScriptPath') + '/index.php?title=Special:Log&page=' + mw.config.get('wgPageName')); // Give the hatnote tabindexes $('.hatnote:first a').attr('tabindex', 1);

/*		LOGS */	// Highlight Page Log: Highlights recent page actions such as deletions, moves, and protection actions, in the protection log. if (mw.config.get('wgPageName') == 'Special:Log') {		$('#bodyContent ul').first.children.each(function		{			var action = $(this);			var date = action.contents.get(0).nodeValue;			var newDate = new Date(date);			var today = new Date;			var dateDifference = today.getTime - newDate.getTime;

if (dateDifference < 1000 * 60 * 60 * 24 * 7) action.css('background-color', 'yellow'); });	} }

function pagesLayoutInstant {	var isPrintable = location.href.match(/&printable=yes/) ? true : false; var mwContent = $('.mw-content-ltr:eq(0)'); var wikiPreview = $('#wikiPreview'); // same as above, but when previewing a page // loop through top icons and get the one with the largest style.right value, so we can add items to the left of them (such as lead section edit link) var topIcons = $('.topicon'); var numberOfTopIcons = topIcons.length; function getRightDist(element) {		return getLengthInPixels(element.css('right'))[0]; }	function getTrumpIconLength {		var trumpIcons = { 'status-top': 175, 'TemplateUserinfo': 225 }; var trumpIconLength = 0;

for (var icon in trumpIcons) {			if ($('#' + icon).length) {				var trumpIconLength = trumpIcons[icon]; break; }		}		return trumpIconLength; }	var leftMostTopIconRightValue = 0; topIcons.each(function	{		var icon = $(this);		var rightDist = getRightDist(icon);		if (rightDist > leftMostTopIconRightValue) leftMostTopIconRightValue = rightDist;			}); var trumpIconLength = getTrumpIconLength; var distanceRight; if (trumpIconLength) distanceRight = trumpIconLength; else if (leftMostTopIconRightValue) distanceRight = leftMostTopIconRightValue + 25; else distanceRight = 0; /*		Merge multiple hatnotes together */	// TODO Make these work together? i.e. if a hatnote is followed by a reflink, merge them anyway. function mergeLinks(className) {		$($('.' + className).get.reverse).each(function		{			var l = $(this);			l.attr('title', className); // give "title" attribute to node			if (!l.next || !l.next.hasClass(className)) return;			var nextEl = l.next.addClass('merged-hatnote');			l.append(className == 'hatnote' ? ' ' : '. ').append(nextEl);		}); }	if (!wikiPreview.length) {		mergeLinks('hatnote'); mergeLinks('rellink'); }	/*		Move QuickEdit section-0 link to top-right corner of page */	var sectionLink0 = $('#sectionlink-0'); // QE is adding an edit link to the lead section, so move it to the corner if (sectionLink0.length) {		$('#editsection-0').css('display', 'inline'); var link = sectionLink0.parent.addClass('lead-qe-link').css('margin-right', distanceRight + 'px'); if (!mw.util.getParamValue('oldid')) {			var newLink = $('').attr('href', mw.config.get('wgScript') + '?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&action=edit&section=0').attr('title', 'Edit section').append('edit'); // add new edit link into QE edit link sectionLink0.before(newLink, '/'); }		$('#section-0').before(link); // move it	} // number h2 headers; disabled on preview pages since not all headers are shown when editing a section if (!(mw.config.get('wgCanonicalNamespace') == '' && mw.config.get('wgTitle') == mw.config.get('wgMainPageTitle')) && (mw.config.get('wgAction') == 'view' || mw.config.get('wgAction') == 'purge')) {		var diffs = $('.diff'); var h2 = $('h2'); var start; if (diffs.length && $('#toc').length) start = 2; else if (diffs.length || $('#toc').length) start = 1; else start = 0; var begin = 0; for (var i = start; i < h2.length; i++) {			if (h2.eq(i).parent.attr('id') == 'toctitle') continue; var headingNumber = begin + 1; var number = $(' ').addClass('heading-number').attr('id', 'heading-' + headingNumber).append(headingNumber + '. ').after(''); h2.eq(i).children.first.before(number); begin++; }	}	/*		Remove extra line breaks. */	function removeLineBreak(node) {		// Remove nodes that look exactly like this:

if (node[0].nodeName == 'P' && node.contents.length == 1 && node.contents.get(0).nodeName == 'BR') {			node.remove; return true; }		else return false; }	// Get first top-level P	function getFirstP {		var firstP; var firstChild = mwContent.children.first; if (firstChild[0].nodeName == 'P') firstP = firstChild; else {			firstP = firstChild.nextUntil('p').next; if (!firstP.length) firstP = firstChild.next; }		return firstP; }	var firstContentNode = mwContent.children.first; if (firstContentNode.length && mw.config.get('wgAction') == 'view') {		var next = firstContentNode; var lineBreaksRemoved = 'Line breaks have been removed before this line.'; // at the very beginning of the page, find first P node var firstP = getFirstP; var firstPChild = firstP.children.first; if (firstPChild.length && firstPChild[0].nodeName == 'BR') {			var remove = removeLineBreak(firstP); // Remove BR only if there's no text before it. if (!remove && firstP.contents[0].nodeName == 'BR') {				firstPChild.remove; getFirstP.attr('title', lineBreaksRemoved); }			else if (remove) getFirstP.attr('title', lineBreaksRemoved); }		// at the beginning of the page, after a hatnote if (next.hasClass('hatnote') || next[0].nodeName == 'DL') {			next2 = next.next; next3 = next2.next; var removed = false; if (next2[0].nodeName == 'P' && next2.children.length && next2.children.get(0).nodeName == 'BR') {				remove = removeLineBreak(next2); if (!remove) next2.children.eq(0).remove; // at very beginning removed = true; }			else if (next3[0].nodeName == 'P' && next3.children.length && next3.children.get(0).nodeName == 'BR') {				remove = removeLineBreak(next3); if (!remove) next3.children.eq(0).remove; // after a hatnote removed = true; }			if (removed) $('p:first').attr('title', lineBreaksRemoved); }		// remove line breaks surrounding the TOC var toc = $('#toc'); if (toc.length && toc.prev.length) {			var removeBefore = removeLineBreak(toc.prev); // before the TOC var removeAfter = removeLineBreak(toc.next); // after the TOC if (removeBefore || removeAfter) toc.attr('title', 'Line breaks have been removed around this TOC.'); }	}	/*		Adjust references */	// Use "standard references" if page forces it. if ($('#standard-references').length) mw.util.addCSS('.reflist, .refbegin { max-height: 10000px; overflow: visible; }'); // Go through "references" class. if (!isPrintable) adjustReferences; }

// Tasks to perform after everything else has finished loading function finishedLoading {	// Reload anchors var url = location.href.split('/'); if (url[url.length - 1].indexOf('#') != -1) location.href = location.href; }

$(pagesLayoutInstant);

// Can't use .ready since the layout of other scripts are affected. if (typeof(addOnloadHook) != 'undefined') {	addOnloadHook(accessKeys); if (mw.config.get('skin') == 'monobook') addOnloadHook(pagesLayout); addOnloadHook(finishedLoading); }