MediaWiki:Gadget-externalsearch.js

From wikishia

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.
/**
 * Add Google Search to the simple MediaWiki Search bar per simple toggle arrow.
 *
 * Created by [[User:Perhelion]] 2018-09, similar to [[d:User:Bene*]]/externalsearch.js 2013-06
 * Dependencies: mediawiki.language
 */
/* eslint indent:["error","tab",{"outerIIFEBody":0}] */
/* global mediaWiki, jQuery */

(function (mw, $) {
'use strict';

var i18nData = {
		en: {
			title: 'Google for Wiki',
			description: 'Use the Google Search for ',
			placeholder: ' Google', // append
			// default writing directionality
			dir: 'ltr',
			left: 'left',
			right: 'right'
		},
		de: {
			title: 'Google für Wiki',
			description: 'Verwende die Google-Suche für ',
			placeholder: ' mit Google'
		},
		es: {
			title: 'Google para wiki',
			description: 'Use la búsqueda de Google para ',
			placeholder: ' con Google'
		},
		fr: {
			title: 'Google pour Wiki',
			description: 'Utilisez Google Search pour ',
			placeholder: ' avec Google'
		},
		it: {
			title: 'Google per Wiki',
			description: 'Utilizza la Ricerca Google per ',
			placeholder: ' con Google'
		},
		pl: {
			title: 'Google dla Wiki',
			description: 'Użyj wyszukiwarki Google dla ',
			placeholder: ' z Google'
		},
		ru: {
			title: 'Google для Wiki'
		}
		// TODO: extend translations here
	}, i18nLang = mw.config.get('wgUserLanguage'),
	// cologneblue has no ids
	isGoBtn = ['vector', 'minerva'].indexOf(mw.config.get('skin')) < 0, // 'timeless', 'monobook', 'modern'
	checked = false,
	options = {},
	arrowDown = 'url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2212%22 height=%2212%22 fill=%22%2354595d%22 %3E%3Cpath d=%22M1 4h10L6 9 1 4%22/%3E%3C/svg%3E")',
	color = / stroke=%22(?:%23|#)?([\d\w]+)%22/,
	$search,
	$searchG,
	searchIcon,
	$searchButton,
	$toggleArrow = {
		'cursor': 'pointer',
		'position': 'absolute',
		'margin-top': '.19em',
		'width': '1em',
		'height': '1em',
		'background-repeat': 'no-repeat',
		'background-position': 'center',
		'backgroundImage': arrowDown
	};

if ($('body').is('.rtl') || isGoBtn) {
	i18nData.en.dir = 'rtl';
	i18nData.en.left = 'right';
	i18nData.en.right = 'left';
}

/**
* @param {string} key - of the message
* @return {string} the localized version of the message.
*/
function i18n(key) {
	return (i18nData[i18nLang].hasOwnProperty(key) ?
		i18nData[i18nLang][key] :
		i18nData.en[key]);
}

function toggle() {
	var g = 1, o;
	if ((checked = !checked)) {
		g = 2;
		$search.hide();
		$searchG.show().focus();
		setTimeout(function () {
			options.fieldset[0].css({
				borderColor: '#47E',
				boxShadow: '',
				transition: 'all 0.3s' });
		}, 40);
	} else {
		$searchG.hide();
		$search.show().focus();
	}
	for (o in options) {
		o = options[o];
		var attrs = o[g];
		if (attrs.hasOwnProperty('style')) {
			for (var a in attrs) {
				if (a === 'style') o[0].css(attrs[a]);
				else o[0].attr(a, attrs[a]);
			}
		} else { o[0].attr(attrs); }
	}
	// Theoretically searchIcon should not change, but it does!?!
	if (searchIcon)
		options.searchButton[0].css({ backgroundImage: searchIcon.replace(color[g - 1], color[g - 2]) });
}

function init() {
	var $searchform = $('#searchform'),
		$fieldset = $('#simpleSearch, #searchBody'),
		$simpleSearch = $fieldset.find('*[name=title]'),
		arrowRTL = { ltr: 'M8 11V1L3 6l5 5', rtl: 'M4 1v10l5-5-5-5' },
		hoverColor = function (evt) {
			var e = $(evt.target),
				doColor = ['000%22', color[checked ? 0 : 1] + '%22'];
			if (evt.type === 'mouseenter') doColor[1] = doColor.shift(); // reverse
			e.css({ backgroundImage: String.prototype.replace.apply(e.css('backgroundImage'), doColor) });
		};
	arrowRTL = arrowDown
		.replace(/M1 4h10L6 9 1 4/, arrowRTL[i18nData.en.dir])
		.replace(/%2354595d/, '%2347E');

	searchIcon = $searchButton.css('backgroundImage');
	if (!searchIcon || searchIcon === 'none')
		searchIcon = '';
	color = ['47E', (searchIcon && (color = searchIcon.match(color)) && color[1]) || '54595d'];
	$searchG = $search.clone();
	$searchG.attr({
		name: 'q',
		placeholder: $.trim($search.attr('placeholder').replace(mw.config.get('wgSiteName'), '')) + i18n('placeholder')
	}).insertAfter($search.hide());

	options = {
		searchButton: [$searchButton, {
			title: $searchButton.attr('title'),
			name: $searchButton.attr('name')
		}, {
			title: i18n('description') + mw.config.get('wgSiteName'),
			name: ''
		}],
		searchform: [$searchform, {
			action: mw.config.get('wgScript'), target: '' }, // $searchform.attr( 'action' )
		{ action: '//www.google.com/search', target: '_blank' }],
		fieldset: [$fieldset, { style: { borderColor: $fieldset.css('borderColor'), transition: '' } }, { style: { borderColor: '#E43', boxShadow: '0 0 8px #FB1' } }],
		simpleSearch: [$simpleSearch, {
			name: 'title', // $simpleSearch.attr( 'name' )
			value: 'Special:Search' // $simpleSearch.val()
		}, {
			name: 'sitesearch',
			value: mw.config.get('wgServer').replace(/\/\//, '') + mw.config.get('wgArticlePath').replace(/\$1$/, '')
		}],
		toggleArrow: [$toggleArrow, { title: i18n('title'), style: { backgroundImage: arrowDown } }, { title: $search.attr('placeholder'), style: { backgroundImage: arrowRTL } }]
	};

	if (searchIcon)
		$searchButton.on('mouseenter mouseleave', hoverColor);
	$toggleArrow.on('mouseenter mouseleave', hoverColor);
}

$(function () {
	i18nLang = i18nLang.split('-')[0];
	if (!(i18nLang in i18nData)) {
		i18nLang = 'en';
		// Try better fallback
		var chain = mw.language.getFallbackLanguages();
		for (var i = chain.length - 1; i >= 0; i--) {
			if (chain[i] in i18nData)
				i18nLang = chain[i]; // no break as lower i is better
		}
	}
	$search = $('#searchInput');
	// Nothing to do
	if (!$search.length) return;

	if (isGoBtn) {
		isGoBtn = '.4em';
	} else {
		$search.css('width', '96%');
		isGoBtn = '1.1em';
	}
	$searchButton = $('#searchButton, #mw-searchButton').css(i18nData.en.right, 'auto');
	$toggleArrow[i18n('right')] = isGoBtn;
	$toggleArrow = $('<span>', {
		'id': 'toggleArrow',
		'class': 'mw-collapsible-arrow mw-collapsible-toggle-expanded', // has PNG fallback
		'title': i18n('title'),
		'mouseup': toggle
	}).css($toggleArrow).one('mousedown', init)
		.appendTo($search.parent());
});

}(mediaWiki, jQuery));