MediaWiki:Gadget-ondemand-fullscreenPopup.js

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
JS-код ниже относится к скрытому гаджету ondemand-fullscreenPopup. Он вызывается по умолчанию на страницах в категории Википедия:Страницы с гаджетом по требованию fullscreenPopup.

После сохранения или недавних изменений очистите кэш браузера.

/*
 * По идее и с теоретической помощью участника:Serhio Magpie, с благодарностью.
 * Создание попапов с заранее заданным содержимым при нажатии на кнопку-ссылку на странице.
 * Этот скрипт создан для шаблонов Интерактивных схем метрополитена,
 * но им можно пользоваться и для создания попапа в других случаях.
 */

if ($('.popup-extend').length)
	$(function() {
		var api,
			windowManager,
			change = {};

		function showPage(event, links) {
			var cur = $(event.currentTarget).closest('.popup-table').find('.imgtogglemini'),
				version = mw.html.escape(cur.data('version'));
			const pairs = [
				['&lt;templatestyles ', '<templatestyles '],
				['&lt;span ', '<span '],
				['&lt;div ', '<div '],
				['&lt;/', '</'],
				['&#039;', "'"],
				['&gt;', '>']
			];
			windowManager.getWindow(version).then(function() {
					windowManager.openWindow(version);
				})
				.fail(function() {
					var pagename = mw.html.escape(cur.data('pagename')),
						qr = cur.data('query'),
						width = window.innerWidth,
						imagewidth = Math.floor(Math.max(width * 0.6,
							Number(mw.html.escape('' + cur.data('width'))))),
						minwidth = Number(mw.html.escape('' + cur.data('textwidth')));
					Object.keys(qr).forEach(function(item) {
						qr[item] = mw.html.escape(qr[item]);
						Object.values(pairs).forEach(function(value) {
							qr[item] = qr[item].replaceAll(value[0], value[1]);
						});
					});
					change[version] = (imagewidth + minwidth < width) ? imagewidth : false;
					api.get({
							action: 'parse',
							contentmodel: 'wikitext',
							text: qr[0] + '|pagename=' + pagename + '|language=' + mw.config.get('wgUserLanguage') +
								'|width=' + imagewidth + qr[1],
							prop: 'text',
							format: 'json',
							formatversion: 2
						})
						.done(function(data) {
							createPopup(pagename, data.parse.text, version,
								mw.html.escape(cur.data('help')) || 'help',
								function(pd) {
									firsttime(cur, version, pd, minwidth);
								},
								function() {
									everytime(version, width, cur.data('helppage'), links);
								});
							windowManager.openWindow(version);
						});
				});
		}

		function createPopup(title, content, version, icontitle, firstcallback, everycallback) {
			var ProcessDialog = function(config) {
				ProcessDialog.super.call(this, config);
			};
			OO.inheritClass(ProcessDialog, OO.ui.ProcessDialog);
			ProcessDialog.static.name = 'myDialog';
			ProcessDialog.static.title = $('<div>').html($('<span>').text(title));
			ProcessDialog.static.actions = [{
				action: 'close',
				flags: ['safe', 'close']
			}, {
				action: 'help',
				icon: 'infoFilled',
				title: icontitle,
				flags: 'primary'
			}];
			ProcessDialog.prototype.initialize = function() {
				ProcessDialog.super.prototype.initialize.apply(this, arguments);
				this.content = new OO.ui.PanelLayout({
					padded: true,
					expanded: true
				});
				this.content.$element.append(content);
				this.$body.append(this.content.$element);
				firstcallback(this);
				ProcessDialog.prototype.getSetupProcess = function(data) {
					return ProcessDialog.super.prototype.getSetupProcess.call(this, data)
						.next(everycallback, this);
				};
			};
			ProcessDialog.prototype.getActionProcess = function(action) {
				var dialog = this;
				if (action == 'close')
					return new OO.ui.Process(function() {
						dialog.close({
							action: 'close'
						});
					});
				return ProcessDialog.super.prototype.getActionProcess.call(this, action);
			};
			windowManager.addWindows({
				[version]: new ProcessDialog({
					classes: ['popup-window', 'popup-' + version],
					size: 'full'
				})
			});
		}

		function firsttime(cur, version, pd, minwidth) {
			var proposed,
				curpopup = '.popup-version-opened-' + version;
			if (change[version]) {
				waitForElm(curpopup + ' .mw-collapsible').then(function(coll) {
					var div = $(coll).parent().children().first().children().first();
					if ($(div).prop("tagName") !== 'DIV')
						div = div.next();
					div.css({
						width: Number(div.css('width').match(/\d+/)[0]) + 20,
						maxHeight: (proposed = (window.innerHeight - pd.getContentHeight() +
							pd.getBodyHeight() - Math.floor(3.5 *
								$(($(coll).closest('table').find('tr'))[0]).height()))),
						overflowY: 'auto',
						float: 'left'
					});
					$(coll).css({
						maxHeight: proposed,
						overflowY: 'auto'
					});
					if (coll.clientWidth < minwidth + 6) {
						$(coll).css({
							clear: 'both',
							maxHeight: 'none',
							overflowY: 'inherit'
						});
						div.css({
							maxHeight: 'none',
							overflowY: 'inherit'
						});
						$(curpopup).find('.noresize').css('float', 'inherit');
					}
					if (mw.html.escape(cur.data('nohr')) == 'yes')
						$($(curpopup + ' hr')[0]).css('display', 'none');
				});
			}
			mw.util.addCSS(curpopup +
				' .mw-collapsible-toggle {display:none;}');
			$(curpopup + ' .oo-ui-processDialog-actions-primary a').off();
		}

		function everytime(version, maxwidth, helppage, links) {
			var curpopup = $('.popup-version-opened-' + version).closest('.oo-ui-processDialog-content');
			curpopup.find('.oo-ui-image-invert').removeClass('oo-ui-image-invert');
			curpopup.find('.oo-ui-processDialog-actions-primary a').removeAttr('role')
				.off('click keydown keypress mousedown');
			$('body').trigger('refresh-imagehighlight-' + (links ? 'links' : 'nolinks'));
			if (helppage) {
				curpopup.find('.oo-ui-processDialog-actions-primary a').attr({
					href: '/wiki/' + helppage,
					target: '_popuphelp'
				});
			}
			if (change[version]) {
				var des = curpopup.find('*'),
					popup = curpopup.find('.popupclass');
				des.each(function(data) {
					var item = $(des[data]);
					if (item.css('clear') == 'both')
						item.css('clear', 'inherit');
					if (item.css('max-width') != 'none')
						item.css('max-width', '');
				});
				popup.find('hr').remove();
				popup.find('.noresize').css('float', 'left');
				popup.parent().css('width', Math.floor(Math.max(maxwidth * 0.96, change[version])));
			}
		}

		function waitForElm(selector) {
			return new Promise(function(resolve) {
				if (document.querySelector(selector)) {
					return resolve(document.querySelector(selector));
				}

				const observer = new MutationObserver(function() {
					if (document.querySelector(selector)) {
						resolve(document.querySelector(selector));
						observer.disconnect();
					}
				});

				observer.observe(document.body, {
					childList: true,
					subtree: true
				});
			});
		}

		function createcallback(value) {
			return function() {
				var cur = $(this);
				cur.html($('<a>').html(cur.html()));
				cur.click(function(event) {
					if (!windowManager) {
						windowManager = new OO.ui.WindowManager();
						$(document.body).append(windowManager.$element);
					}
					showPage(event, value);
				});
			};
		}

		mw.loader.using(['mediawiki.util', 'mediawiki.api', 'oojs', 'oojs-ui'])
			.then(function() {
				if (!$('.skin-minerva').length)
					$('.popup-placeholder').remove();
				api = new mw.Api();
				$('.metrominiicon').closest('a').attr('target', '_popuphelp');
				if ($('.popup-extend-links').length) {
					$('.popup-extend-links').each(createcallback(true));
					$('.popup-extend-nolinks').each(createcallback(false));
				} else
					$('.popup-extend-nolinks').each(createcallback(true));
			});
	});