User:Equazcion/Floater.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. |
![]() | This user script seems to have a documentation page at User:Equazcion/Floater and an accompanying .css page at User:Equazcion/Floater.css. |
mw.loader.using( ['mediawiki.util', 'mediawiki.user'], function () {
return;
// Disable for now, as this script is throwing exceptions
var imageHistory = "https://upload.wikimedia.org/wikipedia/commons/1/1d/Clock_simple_white.svg";
var imageEdit = "http://upload.wikimedia.org/wikipedia/commons/e/ec/Btn_edit.gif";
var imageSwitch = "https://upload.wikimedia.org/wikipedia/commons/e/e8/Play_blauw.png";
// Load prerequisites
importStylesheet('User:Equazcion/Floater.css');
loadJQViewport();
// Predict a static floater height
var floaterHeight = 31;
// Create/insert empty Floater div
$('#mw-head').prepend('<div hidden="hidden" class="floater" ' +
'style="top:' + '-' + floaterHeight + 'px;' +
'">.</div>');
// Grab the div
var floater = $('.floater');
// Set URL prefix
var pre = location.protocol + '//' + mw.config.get('wgPageContentLanguage') + '.' + mw.config.get('wgNoticeProject') + '.org' + '/w/index.php?title=';
// Construct the page title line here. Long titles will need to be truncated.
if (mw.config.get('wgPageName').length > 40){
if (mw.config.get('wgNamespaceNumber') == 0){
pageNS = '';
} else if (mw.config.get('wgNamespaceNumber') == 4) {
pageNS = 'WP:';
} else if (mw.config.get('wgNamespaceNumber') == 5) {
pageNS = 'WP Talk:';
} else if (mw.config.get('wgNamespaceNumber') == 8) {
pageNS = 'MW:';
} else if (mw.config.get('wgNamespaceNumber') == 9) {
pageNS = 'MW Talk:';
} else if (mw.config.get('wgNamespaceNumber') == 14) {
pageNS = 'Cat:';
} else if (mw.config.get('wgNamespaceNumber') == 15) {
pageNS = 'Cat talk:';
} else {
pageNS = mw.config.get('wgCanonicalNamespace') + ':';
}
var pageTitle = pageNS + mw.config.get('wgTitle').substr(0,7) + '...' + mw.config.get('wgTitle').substr(-15);
var titleLine = '<li style="margin-right:10px;font-size:0.85em;"><abbr style="border-bottom:none;" title="' + mw.config.get('wgPageName').replace(/_/g,' ') + '">' + pageTitle.replace(/_/g,' ') + '</abbr></li>';
} else {
var titleLine = '<li style="margin-right:10px;font-size:0.9em;">' + mw.config.get('wgPageName').replace(/_/g,' ') + '</li>';
}
// If the current page has an "add section" tab, construct a link
if ($('#ca-addsection').length > 0){
var addSection = '<li><a href="' + pre + mw.config.get('wgPageName') + '&action=edit§ion=new' + '"><span style="font-size:1.15em;margin-right:3px;">+</span>Section</a>' + '</li>';
} else {
var addSection = '';
}
// Add preview and save buttons if we're editing
if ((mw.config.get('wgAction') == 'edit') || (mw.config.get('wgAction') == 'submit')){
var editButton = '<li class="buttonLi"><input class="button" form="editform" type="submit" value="Preview" name="wpPreview"></input></li>' +
'<li class="buttonLi"><input class="button" form="editform" type="submit" value="Save" name="wpSave"></input></li>' +
'<li><a href="' + pre + mw.config.get('wgPageName') + '&action=edit' + '"><img style="padding-right:5px;margin-bottom:3px;" src="' + imageEdit + '" height="17px" alt="">Edit</a>' + '</li>';
} else {
var editButton = '<li><a href="' + pre + mw.config.get('wgPageName') + '&action=edit' + '"><img style="padding-right:5px;margin-bottom:3px;" src="' + imageEdit + '" height="17px" alt="">Edit</a>' + '</li>';
}
// Leave out main/talk switch and history buttons on Special pages
if (mw.config.get('wgNamespaceNumber') > -1){
var switchButton = '<li><a href="' + pre + getAssoc('url') + '"><img style="padding-right:5px;margin-bottom:3px;opacity:0.9;" src="' + imageSwitch + '" height="15px" alt="">' + getAssoc('name') + '</a>' + '</li>';
var historyButton = '<li><a href="' + pre + mw.config.get('wgPageName') + '&action=history' + '"><img style="padding-right:3px;margin-bottom:3px;" src="' + imageHistory + '" height="17px" alt="">History</a>' + '</li>';
} else {
var switchButton = '';
var historyButton = '';
}
// Fill the Floater div with some crap
floater.html(
// Left section for page title, edit, history, and main/talk toggle
'<div style="font-weight:bold;float:left;font-size:0.9em;">' +
'<ul class="floaterPagelinks" style="margin-left:10px;list-style-type:none;list-style-image:none;display:inline;">' +
titleLine +
editButton +
addSection +
historyButton +
switchButton +
'</ul>' +
'</div>' +
// Small links for info, logs, whatlinkshere
'<div style="float:left;margin-top:-7px;margin-left:-15px;">' +
'<ul class="smallLinks" style="list-style-type:disc;">' +
'<li><a href="' + pre + mw.config.get('wgPageName') + '&action=info" title="Information for this page">I</a></li>' +
'<li>|</li>' +
'<li><a href="/wiki/Special:Log/' + mw.config.get('wgPageName') + '" title="Page logs">L</a></li>' +
'<li>|</li>' +
'<li><a href="/wiki/Special:WhatLinksHere/' + mw.config.get('wgPageName') + '" title="What Links Here">W</a></li>' +
'<li>|</li>' +
'<li><a class="gotoTop" href="#topTop" title="Go back to the top">Top</a></li>' +
'</ul>' +
'</div>' +
// Search bar
'<div style="float:right;margin-top:3px;font-size:.9em;">' +
'<form class="searchform" action="/w/index.php">' +
'<div id="simpleSearch2" class="simpleSearch" style="margin-top:-4px;margin-bottom:-20px;margin-right: 25px;width:14em;">' +
'<input id="searchInput2" class="mw-searchInput" placeholder="Search" name="search" tabindex="10" autocomplete="off" style="width:100%;"></input>' +
'<button id="searchButton" name="button" type="submit" style="position: absolute;right: 0px;top: 0px;padding: 0.45em 0.4em 0.2em 0.3em;margin-right: 20px;border: medium none;cursor: pointer;background-color: transparent;background-image: none;">' +
'<img width="12" height="13" alt="Search" src="//bits.wikimedia.org/static-1.22wmf18/skins/vector/images/search-ltr.png?303-4"></img>' +
'</button>' +
'<input type="hidden" value="Special:Search" name="title"></input>' +
'</div>' +
'</form>' +
'</div>' +
// User links
'<div style="float:right;font-size:.8em;font-weight:bold;margin-top:1px;">' +
'<ul class="floaterUserlinks" style="list-style-type:none;list-style-image:none;display:inline;margin-right:20px;">' +
'<li class="floaterUserpageLink"><a title="Your user page" href = "/wiki/User:' + mw.config.get('wgUserName') + '">' + mw.config.get('wgUserName') + '</a></li>' +
//'<li><a class="mw-echo-notifications-badge" href="/wiki/Special:Notifications"></a></li>' +
'<li><a title="Your talk page" href = "/wiki/User talk:' + mw.config.get('wgUserName') + '">' + 'Talk' + '</a></li>' +
'<li><a title="Your preferences" href = "/wiki/Special:Preferences">' + 'Prefs' + '</a></li>' +
'<li><a title="Go to your watchlist" href = "/wiki/Special:Watchlist">' + 'Watchlist' + '</a></li>' +
'<li><a title="Display your contribution history" href = "/wiki/Special:Contributions/' + mw.config.get('wgUserName') + '">' + 'Contribs' + '</a></li>' +
'<li id="utcdate2"><a title="Click to purge this page" href="' + pre + mw.config.get('wgPageName') + '&action=purge"></a></li>' +
'</ul>' +
'</div>');
// Set the "go to top" click function: Go to the MediaWiki top anchor, then scroll up some more
$('a.gotoTop').click(function(){
window.location.hash="top";
window.scrollBy(0, -floaterHeight - 50);
});
// Wait half a sec for images to load etc. b4 un-hiding Floater
setTimeout(function(){floater.prop('hidden', false)},500);
// Listen for TOC or other internal anchor clicks and adjust page scrolling to un-obscure the associated header
$(window).on('hashchange', function(){
adjustForHash();
});
// Run the scroll function once on load after additional half-second delay to display Floater in case we come in mid-page
setTimeout(function(){
scroll();
adjustForHash();
},500);
function adjustForHash(){
// If we're coming in mid-page due to an anchor link, make sure the anchored header isn't obscured by Floater
if (window.location.hash) {
// Get DOM version of the anchored header using [0], then use DOM method to get its viewport coordinates
var anchorCoords = $('[id="' + window.location.hash.replace('#','') + '"]:last')[0].getBoundingClientRect();
// If the pagetop links aren't in view and the anchored header is likely obscured by Floater, scroll up to reveal it
if (($('#p-namespaces ul li:above-the-top').length > 0) && (anchorCoords.bottom < 25)){
window.scrollBy(0, -floaterHeight - 5);
}
}
}
// Set the function for scrolling
$(window).scroll(function(){
scroll();
});
// Use :above-the-top (from plugin below) to check for pagetop stuff outside window. If they're there, start the music.
function scroll(){
if ($('#p-namespaces ul li:above-the-top').length > 0){
floater.css('top','0');
} else {
floater.css('top','-' + floaterHeight + 'px');
}
}
// Find the title of the associated talk or main page. Is there an easier way?
function getAssoc(type){
var toggledTitle = '';
var toggled = '';
var ns = mw.config.get('wgNamespaceNumber');
var title = mw.config.get('wgTitle');
if (ns == 0){
toggledTitle = "Talk:" + title;
toggled = "Talk";
} else if (ns == 1){
toggledTitle = title;
toggled = "Article";
} else if (ns == 2){
toggledTitle = "User_talk:" + title;
toggled = "Talk";
} else if (ns == 3){
toggledTitle = "User:" + title;
toggled = "User page";
} else if (ns == 4){
toggledTitle = "Wikipedia_talk:" + title;
toggled = "Talk";
} else if (ns == 5){
toggledTitle = "Wikipedia:" + title;
toggled = "Project page";
} else if (ns == 6){
toggledTitle = "File_talk:" + title;
toggled = "Talk";
} else if (ns == 7){
toggledTitle = "File:" + title;
toggled = "File page";
} else if (ns == 8){
toggledTitle = "MediaWiki_talk:" + title;
toggled = "Talk";
} else if (ns == 9){
toggledTitle = "MediaWiki:" + title;
toggled = "MediaWiki page";
} else if (ns == 10){
toggledTitle = "Template_talk:" + title;
toggled = "Talk";
} else if (ns == 11){
toggledTitle = "Template:" + title;
toggled = "Template page";
} else if (ns == 12){
toggledTitle = "Help_talk:" + title;
toggled = "Talk";
} else if (ns == 13){
toggledTitle = "Help:" + title;
toggled = "Help page";
} else if (ns == 14){
toggledTitle = "Category_talk:" + title;
toggled = "Talk";
} else if (ns == 15){
toggledTitle = "Category" + title;
toggled = "Cat page";
} else if (ns == 16){
toggledTitle = "Portal_talk:" + title;
toggled = "Talk";
} else if (ns == 17){
toggledTitle = "Portal:" + title;
toggled = "Portal page";
}
if (type == 'url'){
var returned = toggledTitle;
} else if (type == 'name'){
var returned = toggled;
}
return returned;
}
// Add the :above-the-top jQuery selector, which we use to check if user has scrolled past a certain point.
function loadJQViewport(){
/* Excerpt from http://www.appelsiini.net/projects/viewport, Copyright (c) 2008-2009 Mika Tuupola, MIT license: http://www.opensource.org/licenses/mit-license.php
$(":above-the-top") */
(function($) {
$.abovethetop = function(element, settings){
var top = $(window).scrollTop();
return top >= $(element).offset().top + $(element).height() - settings.threshold;
};
$.extend($.expr[':'], {
"above-the-top": function(a, i, m) {
return $.abovethetop(a, {threshold : 0});
}
});
})(jQuery);
}
//If the clock gadget is enabled, replicate it for Floater
if (mw.user.options.get('gadget-UTCLiveClock') == 1){
var $target;
function showTime($target){
var dateNode = $('#utcdate2');
if (!dateNode){return;}
var now = new Date();
var hh = now.getUTCHours();
var mm = now.getUTCMinutes();
var ss = now.getUTCSeconds();
if ($target === undefined){$target = $(dateNode).find('a:first');}
var time = ( hh < 10 ? '0' + hh : hh ) +
':' + ( mm < 10 ? '0' + mm : mm ) +
':' + ( ss < 10 ? '0' + ss : ss );
$target.text(time);
var ms = now.getUTCMilliseconds();
setTimeout( function(){showTime($target); }, 1100 - ms);
}
showTime();
}
// The rest of this replicates the MediaWiki suggest functionality for Floater's search box
var map2, resultRenderCache2, searchboxesSelectors2;
var $searchInput2 = $('#searchInput2');
var $searchRegion2 = $('#simpleSearch2');
function computeResultRenderCache2(context){
var $form, formAction, baseHref, linkParams;
$form = context.config.$region.closest('form');
formAction = $form.attr('action');
baseHref = formAction + (formAction.match(/\?/) ? '&' : '?');
linkParams = {};
$.each( $form.serializeArray(), function (idx, obj){linkParams[obj.name] = obj.value;});
return {textParam: context.data.$textbox.attr('name'), linkParams: linkParams, baseHref: baseHref};
}
function renderFunction2(text, context){
if (!resultRenderCache2){resultRenderCache2 = computeResultRenderCache2(context);}
resultRenderCache2.linkParams[resultRenderCache2.textParam] = text;
this.append($('<span>').css('whiteSpace', 'nowrap').text(text)).wrap($('<a>')
.attr('href', resultRenderCache2.baseHref + $.param( resultRenderCache2.linkParams)).addClass('mw-searchSuggest-link'));
}
searchboxesSelectors2 = ['#searchInput2'];
$(searchboxesSelectors2.join(', ')).suggestions({fetch: function (query){
var $el, jqXhr;
if (query.length !== 0){
$el = $(this);
jqXhr = $.ajax({url: mw.util.wikiScript('api'),data: {format: 'json', action: 'opensearch', search: query, namespace: 0, suggest: ''},
dataType: 'json', success: function (data){if ($.isArray(data) && data.length){$el.suggestions('suggestions', data[1]);}}});
$el.data('request', jqXhr);
}},
cancel: function (){
var jqXhr = $(this).data('request');
if (jqXhr && $.isFunction(jqXhr.abort)){jqXhr.abort();$(this).removeData('request');
}},result: {render: renderFunction2,select: function ($input){$input.closest('form').submit();}},
delay: 120, highlightInput: true}).bind('paste cut drop', function (){$(this).trigger('keypress');});
function specialrenderFunction2(query, context){
var $el = this;
if (!resultRenderCache2){resultRenderCache2 = computeResultRenderCache2(context);}
resultRenderCache2.linkParams[resultRenderCache2.textParam] = query;
if ($el.children().length === 0){
$el.append($('<div>').addClass('special-label').text(mw.msg('searchsuggest-containing')), $('<div>').addClass('special-query').text(query).autoEllipsis()).show();
} else {$el.find('.special-query').text(query).autoEllipsis();}
if ($el.parent().hasClass('mw-searchSuggest-link')){
$el.parent().attr('href', resultRenderCache2.baseHref + $.param(resultRenderCache2.linkParams) + '&fulltext=1');
} else {$el.wrap($('<a>').attr('href', resultRenderCache2.baseHref + $.param(resultRenderCache2.linkParams) + '&fulltext=1').addClass('mw-searchSuggest-link'));}
}
$searchInput2.attr('placeholder', mw.msg('searchsuggest-search')).placeholder();
$searchInput2.suggestions({result: {render: renderFunction2, select: function ($input){$input.closest('form').submit();}},
special: {
render: specialrenderFunction2, select: function ($input){$input.closest('form').append($('<input type="hidden" name="fulltext" value="1"/>'));
$input.closest('form').submit();}}, $region: $searchRegion2});
});