MediaWiki:Common.js

From Mine Blocks Wiki
Revision as of 20:13, 6 July 2022 by Zanzlanz (talk | contribs) (Added tooltip and slider functionality provided by User:Tobias_Alcaraz)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
If you find a typo, inconsistency, or error, please sign up and help out the wiki! We can't do it without your help! :D Thank you!

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: 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.
/* Any JavaScript here will be loaded for all users on every page load. */

// Make the rainbow color change like it does in Mine Blocks
var rainbowDivs = document.getElementsByClassName("rainbow-color");
if(rainbowDivs.length > 0) {
	setInterval(function() {
		var dateTime = (((new Date()).getTime()/1000)%1000)*25;
		var rgb = Math.floor((Math.sin(dateTime/19)/2+.5)*255)*0x10000
				+ Math.floor((Math.sin(dateTime/25)/2+.5)*255)*0x100
				+ Math.floor((Math.sin(dateTime/16)/2+.5)*255)*0x1;
		rgb = rgb.toString(16);
		while(rgb.length < 6) rgb = "0" + rgb;
		rgb = "#"+rgb;
		
		for (var i = 0, max = rainbowDivs.length; i < max; i++) {
			rainbowDivs[i].style.backgroundColor = rgb;
		}
	}, 100);
}


// Adjusted tooltip provided by Tobias_Alcaraz. Original author cited below.

// Mine Blocks-styled tooltips. Original code from Minecraft Wiki
// (available under the CC-BY-NC-SA 3.0 license:
// creativecommons.org/licenses/by-nc-sa/3.0/):
// //minecraft.fandom.com/wiki/MediaWiki:Common.js by User:Majr.

// Replaces normal tooltips. Supports a description with line breaks (\n).
(function () {
	var escapeChars = { '\\&': '&#38;', '<': '&#60;', '>': '&#62;' };
	var escape = function (text) {
		// "\" must be escaped first
		return text.replace(/\\\\/g, '&#92;')
			.replace(/\\&|[<>]/g, function (char) { return escapeChars[char]; });
	};
	var $tooltip = $();
	var $win = $(window), winWidth, winHeight, width, height;

	$('#mw-content-text').on({
		'mouseenter.minetip': function (e) {
			$tooltip.remove();

			var $elem = $(this), title = $elem.attr('data-minetip-title');
			if (title === undefined) {
				title = $elem.attr('title');
				if (title !== undefined) {
					title = $.trim(title.replace(/&/g, '\\&'));
					$elem.attr('data-minetip-title', title);
				}
			}

			if (title === 'Empty') {
				return;
			}

			// No title or title only contains formatting codes
			if (title === undefined || title !== '' && title.replace(/&([0-9a-fl-or])/g, '') === '') {
				// Find deepest child title
				var childElem = $elem[0], childTitle;
				do {
					if (childElem.hasAttribute('title')) {
						childTitle = childElem.title;
					}
					childElem = childElem.firstChild;
				} while (childElem && childElem.nodeType === 1);
				if (childTitle === undefined) {
					return;
				}

				// Append child title as title may contain formatting codes
				if (!title) {
					title = '';
				}
				title += $.trim(childTitle.replace(/&/g, '\\&'));

				// Set the retrieved title as data for future use
				$elem.attr('data-minetip-title', title);
			}

			if (!$elem.data('minetip-ready')) {
				// Remove title attributes so the native tooltip doesn't get in the way
				$elem.find('[title]').addBack().removeAttr('title');
				$elem.data('minetip-ready', true);
			}

			if (title === '' || title === 'Invisible-sprite') {
				return;
			}

			var content = '<span class="minetip-title">' + escape(title) + '&r</span>';

			var description = $.trim($elem.attr('data-minetip-text'));
			if (description) {
				// Apply normal escaping plus "/"
				description = escape(description).replace(/\\\//g, '&#47;');
				content += '<span class="minetip-description">' + description.replace(/\\n/g, '<br>') + '&r</span>';
			}

			// Remove reset formatting
			content = content.replace(/&r/g, '');

			$tooltip = $('<div id="minetip-tooltip">');
			$tooltip.html(content).appendTo('body');

			// Cache current window and tooltip size
			winWidth = $win.width();
			winHeight = $win.height();
			width = $tooltip.outerWidth(true);
			height = $tooltip.outerHeight(true);

			// Trigger a mouse movement to position the tooltip
			$elem.trigger('mousemove', e);
		},
		'mousemove.minetip': function (e, trigger) {
			if (!$tooltip.length) {
				$(this).trigger('mouseenter');
				return;
			}

			// Get event data from remote trigger
			e = trigger || e;

			// Get mouse position and add default offsets
			var top = e.clientY - 34;
			var left = e.clientX + 14;

			// If going off the right of the screen, go to the left of the cursor
			if (left + width > winWidth) {
				left -= width + 36;
			}

			// If now going off to the left of the screen, resort to going above the cursor
			if (left < 0) {
				left = 0;
				top -= height - 22;

				// Go below the cursor if too high
				if (top < 0) {
					top += height + 47;
				}
				// Don't go off the top of the screen
			} else if (top < 0) {
				top = 0;
				// Don't go off the bottom of the screen
			} else if (top + height > winHeight) {
				top = winHeight - height;
			}

			// Apply the positions
			$tooltip.css({ top: top, left: left });
		},
		'mouseleave.minetip': function () {
			if (!$tooltip.length) {
				return;
			}

			$tooltip.remove();
			$tooltip = $();
		}
	}, '.minetip, .invslot-item');
}());


/**
 * TimedSlider
 * //dev.wikia.com/wiki/TimedSlider
 *
 * Creates a basic slider that automatically shifts between slides
 * based on a user-specified timer (default once every 1.5 seconds)
 */
/*jshint forin:true, noempty:true, eqeqeq:true, bitwise:true, strict:false, undef:true, unused:true, curly:true, browser:true, jquery:true */
jQuery(function ($) {
	// tsanimate event
	function tsanimate() {
		var $container = $(this),
			$slides = $container.children(),
			$curr = $slides.filter('.ts-active'),
			$next = $curr.next();

		if ($next.length === 0) {
			$next = $slides.first();
		}

		$curr.removeClass('ts-active');
		$next.addClass('ts-active');
	}

	// initialize all timed sliders
	$('.ts-container').each(function () {
		var $container = $(this),
			$slides = $container.children(),
			delayms;

		// if there is more than 1 slide, finish initializing data and
		// turn on the tsanimate event for this slider
		if ($slides.length > 1) {
			delayms = $container.attr('data-delay-ms');
			if (typeof delayms === "string" || typeof delayms === "number") {
				delayms = delayms || 0;
				if (delayms < 100) {
					delayms = 100;
				}
			} else {
				delayms = 1500;
			}
			$container.data('delayms', delayms);
			$container.on('tsanimate', tsanimate);
			$container.trigger('tsanimate');
			var init = window.setInterval(function () {
				$container.trigger('tsanimate');
			}, delayms);
			// Pause animations on mouseover of a designated container (.ts-container)
			// This is so people have a chance to look at the image and click on pages they want to view.
			$container.mouseenter(function () {
				if (!$container.parents('.ts-sync').length) {
					clearInterval(init);
				}
			}).mouseleave(function () {
				if (!$container.parents('.ts-sync').length) {
					init = window.setInterval(function () {
						$container.trigger('tsanimate');
					}, delayms);
				}
			})
			// If the parent container has .ts-sync, all animations stop on mouseover
			// of said container.
			$('.ts-sync').each(function () {
				var $syncContainer = $(this);
				$syncContainer.mouseenter(function () {
					clearInterval(init);
				}).mouseleave(function () {
					init = window.setInterval(function () {
						$container.trigger('tsanimate');
					}, delayms);
				})
			});
		}
	});
});