MediaWiki:Sidebar.js

From Team Fortress Wiki
Jump to: navigation, search

Note: After saving, 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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
// Floating, scrolling sidebar by User:WindPower
var wSidebar = {
	scrollTimeStep: 40, // In milliseconds, 40 ms = 25 fps
	scrollFrames: 20, // Number of frames it takes to reach target position
	fullMode: false,
	node: null,
	oldScroll: 0,
	minHeight: 0,
	timer: null,
	origin: 0,
	target: 0,
	scrollProgress: 0.0,
	getElementsByClassName:function(nodes, c) {
		var ns = [];
		for(var n = 0; n < nodes.length; n++) {
			if(!nodes[n]) continue;
			if(!(nodes[n].className)) continue;
			if(nodes[n].className.indexOf(c) != -1) {
				ns[ns.length] = nodes[n];
			}
		}
		return ns;
	},
	getScroll:function() {
		if(typeof(window.pageYOffset) == 'number') return window.pageYOffset;
		if(document.body && document.body.scrollTop) return document.body.scrollTop;
		if(document.documentElement && (document.documentElement.scrollTop)) return document.documentElement.scrollTop;
		return 0; // derp
	},
	getViewportHeight:function() {
		if (typeof window.innerHeight != 'undefined') return window.innerHeight;
		if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientHeight != 'undefined' && document.documentElement.clientHeight != 0) return document.documentElement.clientHeight;
		try
		{
			return document.getElementsByTagName('body')[0].clientHeight;
		}
		catch(e)
		{
			return 1; // derp
		}
	},
	getElementHeight:function(element) {
		return element.offsetHeight;
	},
	getElementY:function(element) {
		var y = 0;
		while(element){
			y += element.offsetTop;
			element = element.offsetParent;
		}
		return y;
	},
	getTargetHeight:function(oldY, newY) {
		if(newY == oldY) return null; // Ze scrollwheels, zey do nothing
		if(wSidebar.fullMode) // Infobox fits in page
		{
			return Math.max(wSidebar.minHeight, newY);
		}
		if(oldY < newY) // Scrolling down
		{
			return Math.max(wSidebar.minHeight, newY + wSidebar.getViewportHeight() - wSidebar.getElementHeight(wSidebar.node));
		}
		// Scrolling up
		if(newY < wSidebar.getElementY(wSidebar.node)) // If sidebar can be pushed up on screen
		{
			return Math.max(wSidebar.minHeight, newY);
		}
		return null;
	},
	scroll:function(e) {
		var newScroll = wSidebar.getScroll();
		wSidebar.fullMode = wSidebar.getElementHeight(wSidebar.node) <= wSidebar.getViewportHeight();
		var targetHeight = wSidebar.getTargetHeight(wSidebar.oldScroll, newScroll);
		if(targetHeight != null)
		{
			wSidebar.startAnim(wSidebar.getElementY(wSidebar.node), targetHeight);
		}
		else
		{
			wSidebar.resetAnim();
		}
		wSidebar.oldScroll = newScroll;
	},
	startAnim:function(origin, target) {
		wSidebar.scrollProgress = 0.0;
		wSidebar.origin = origin;
		wSidebar.target = target;
		if(wSidebar.timer == null)
		{
			wSidebar.timer = setInterval(wSidebar.scrollAnim, wSidebar.scrollTimeStep);
		}
	},
	resetAnim:function() {
		if(wSidebar.timer != null) {
			clearInterval(wSidebar.timer);
			wSidebar.timer = null;
			wSidebar.scrollProgress = 0.0;
			wSidebar.origin = 0;
			wSidebar.target = 0;
		}
	},
	scrollAnim:function(e) {
		wSidebar.scrollProgress += 1.0 / wSidebar.scrollFrames;
		wSidebar.node.style.top = Math.round(wSidebar.easing(wSidebar.scrollProgress) * (wSidebar.target - wSidebar.origin) + wSidebar.origin, 0).toString() + 'px';
		if(wSidebar.scrollProgress >= 1.0) {
			wSidebar.resetAnim();
		}
	},
	easing:function(x) {
		return (Math.sin((x-.5)*Math.PI)+1)/2;
	},
	init:function() {
		var sidebar = document.getElementById('right-sidebar');
                try
                {
		    var body = document.getElementsByTagName('body')[0];
                }
                catch(e)
                {
                    var body = null; // Oh noes
                }
		if(sidebar && body)
		{
			if(body.getAttribute('class'))
			{
				body.setAttribute('class', body.getAttribute('class') + ' sidebard');
			}
			else
			{
				body.setAttribute('class', 'sidebard');
			}
			wSidebar.node = sidebar.cloneNode(true);
			sidebar.parentNode.removeChild(sidebar);
			document.getElementById('column-one').appendChild(wSidebar.node);
			wSidebar.minHeight = wSidebar.getElementY(wSidebar.node);
			if(typeof window.attachEvent != 'undefined')
			{
				window.attachEvent("onscroll", wSidebar.scroll);
			}
			else if(typeof document.addEventListener != 'undefined')
			{
				document.addEventListener('scroll', wSidebar.scroll, false);
			}
			else
			{
				window.onscroll = wSidebar.scroll;
			}
			wSidebar.scroll(); // Force trigger on load
		}
	}
}
addOnloadHook(wSidebar.init);