MediaWiki:Gadget-ReferenceTooltips.js
Jump to navigation
Jump to search
Note: After publishing, 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: Press Ctrl-F5.
/** * Reference tooltips * * Adds a tooltip to references when hovering over or clicking them * Based on [[mw:Reference tooltips]] * * @author Cqm * * @todo Add fade in/fade out animations for config form and tooltip * @todo Find some way to detect of user has keyboard/mouse * as windows 8 supports touchscreens and a mouse * so allow hover activation if that's the case * */ ;(function ($, mw) { 'use strict'; function tooltips() { var i, settings, timer; /** * Cookie functions */ function createCookie() { $.cookie('ref-tooltips', 'on-200-hover', { path: '/', expires: 90 }); return 'on-200-hover'; } function getCookie() { var cookie = $.cookie('ref-tooltips') || createCookie(), storedVars = cookie.split('-'), touchscreen = 'ontouchstart' in document.documentElement; settings = { on: storedVars[0], delay: storedVars[1], delayNo: parseInt(storedVars[1], 10), action: storedVars[2] }; if (settings.action === 'hover') { settings.hover = true; settings.click = false; } if (settings.action === 'click') { settings.hover = false; settings.click = true; } if (touchscreen === true) { settings.action = 'click'; settings.hover = false; settings.click = true; } mw.log(settings); } function modifyCookie() { var inputs = document.getElementById('rsw-config-action').getElementsByTagName('input'); for (i = 0; i < inputs.length; i += 1) { if (inputs[i].checked) { settings.action = inputs[i].value; } } settings.delay = $('#rsw-config-delay input').first().val(); // in case someone sets a greater value manually if (parseInt(settings.delay, 10) > 1000) { settings.delay = '1000'; } $.cookie('ref-tooltips', 'on' + '-' + settings.delay + '-' + settings.action, { path: '/', expires: 90 }); window.location.reload(false); } function disableTooltips() { // just use defaults for delay and action as no one really cares $.cookie('ref-tooltips', 'off-200-hover', { path: '/', expires: 90 }); window.location.reload(false); } /** * Create and remove functions */ function removeConfig() { $('#rsw-config').remove(); $('#rsw-config-background').remove(); } function createConfig() { var body, form, formBackground, formLeft, formTop; // use this for formBackground height/width body = document.body; // for config positioning formTop = ($(window).height() / 4) + 'px'; formLeft = (($(window).width() - 510) / 2) + 'px'; // create form container form = $('<div/>', { 'id': 'rsw-config' }).css({ 'top': formTop, 'left': formLeft }).append( $('<div/>', { 'id': 'rsw-config-header' }).append( $('<span/>', { 'id': 'rsw-config-title', 'html': 'Reference Tooltip Settings' }), $('<span/>', { 'id': 'rsw-config-close', 'title': 'Close settings', 'click': function () { removeConfig(); } }) ), $('<div/>', { 'id': 'rsw-config-body' }).append( $('<form/>').append( $('<input>', { 'id': 'rsw-config-disable', 'type': 'button', 'value': 'Disable reference tooltips', 'click': function () { disableTooltips(); } }), $('<div/>', { 'id': 'rsw-config-note', 'html': 'Once disabled, reference tooltips can be re-enabled using the link at the bottom of the page.' }), $('<label/>', { 'id': 'rsw-config-delay', 'html': 'Delay before the tooltip appears (in milliseconds): ' }).append( $('<input>', { 'type': 'number', 'step': '50', 'min': '0', 'max': '1000', 'value': settings.delay }) ), $('<br>'), $('<span/>', { 'id': 'rsw-config-action', 'html': 'Tooltip is activated by: ' }).append( $('<label/>', { 'html': 'Hover' }).prepend( $('<input>', { 'type': 'radio', 'name': 'tooltip-action', 'checked': settings.hover, 'value': 'hover' }) ), $('<label/>', { 'html': 'Click' }).prepend( $('<input>', { 'type': 'radio', 'name': 'tooltip-action', 'checked': settings.click, 'value': 'click' }) ) ) ) ), $('<div/>', { 'id': 'rsw-config-footer' }).append( $('<button/>', { 'id': 'rsw-config-save', 'type': 'button', 'html': 'Save settings', 'click': function () { modifyCookie(); } }) ) ); formBackground = $('<div/>', { 'id': 'rsw-config-background', 'click': function () { removeConfig(); } }).css({ 'height': body.clientHeight + 'px', 'width': body.clientWidth + 'px' }); $('body').append(form); $('body').append(formBackground); } function removeTooltip() { $('.rsw-tooltip').remove(); } function createTooltip(event) { var offset, refId, ref, openSettings, tooltip, tooltipHeight, tooltipWidth, top, left; if ($('.rsw-tooltip').length) { removeTooltip(); } offset = $(event.target).offset(); // use native js for most of this as it's easier to debug refId = event.target.href.split('#')[1]; ref = $('#' + refId).children('.reference-text').clone(); openSettings = $('<span/>', { 'id': 'rsw-tooltip-settings', 'click': function () { createConfig(); } }); tooltip = $('<div/>', { 'class': 'rsw-tooltip' }).append( openSettings, ref ); $('body').append(tooltip); tooltipHeight = $('.rsw-tooltip').height(); tooltipWidth = $('.rsw-tooltip').width(); top = offset.top - tooltipHeight - 25; left = offset.left - 7; // if above the top of the page if (top < window.pageYOffset) { top = window.pageYOffset; } // if too far right // only an issue in monobook if ((tooltipWidth + left) > $('body').width()) { left = $('body').width() - tooltipWidth; } $('.rsw-tooltip').css({ 'top': top + 'px', 'left': left + 'px' }); } /** * Functions for each tooltip activation action */ function tooltipHover() { function hide() { timer = window.setTimeout(function () { removeTooltip(); }, 500); } $('.reference').mouseover(function (event) { window.clearTimeout(timer); window.setTimeout(function () { createTooltip(event); }, settings.delayNo); }); $('body').mouseover(function (event) { var hoverTarget; if ($('.rsw-tooltip').length) { mw.log(event.target); hoverTarget = $(event.target); if (hoverTarget.is('.rsw-tooltip, .rsw-tooltip *')) { window.clearTimeout(timer); return; } hide(); } }); } function tooltipClick() { $('body').on('click', function (event) { var clickTarget; clickTarget = $(event.target); if (clickTarget.is('.reference') || clickTarget.is('.reference a')) { event.preventDefault(); window.setTimeout(function () { createTooltip(event); }, settings.delayNo); } if ($('.rsw-tooltip').length) { if (clickTarget.is('.rsw-tooltip, .rsw-tooltip *')) { return; } removeTooltip(); } }); } /** * Functions to run straight away */ function accessConfig() { var settingsLink; settingsLink = $('<span/>', { 'id': 'rsw-config-open', 'title': 'Configure reference tooltips' }).append( $('<a/>', { 'html': '[Reference Tooltip Settings]', 'click': function () { createConfig(); } }) ); // after categories module in oasis if (mw.config.get('skin') === 'oasis' && $('#WikiaArticleCategories').length) { $('#WikiaArticleCategories').after(settingsLink); } else { $('#mw-content-text').append(settingsLink); } } function tooltipAction() { getCookie(); if (settings.on === 'off') { return; } if (settings.action === 'click') { tooltipClick(); } if (settings.action === 'hover') { tooltipHover(); } } /** * Function invocation */ accessConfig(); tooltipAction(); } $(function () { var namespace = mw.config.get('wgNamespaceNumber'); if (namespace === 0 || namespace === 4) { if ($('.references').length === 0) { mw.log('no references'); return; } if (mw.config.get('wgAction') !== 'view') { return; } tooltips(); } }); }(jQuery, mediaWiki));