מדיה ויקי:GlobalWatchlistConfig.js

מתוך ויקיפדיה, האנציקלופדיה החופשית

הערה: לאחר הפרסום, ייתכן שיהיה צורך לנקות את זיכרון המטמון (cache) של הדפדפן כדי להבחין בשינויים.

  • פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
  • גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
  • אינטרנט אקספלורר / אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
  • אופרה: ללחוץ על Ctrl-F5.
/**
 * Global Watchlist script
 *
 * Client-side user script to create a functional "global" watchlist
 *
 * @author DannyS712
 * @version 8.0.0
 */
/* jshint maxerr: 999, esversion: 6 */
/* eslint array-bracket-spacing: ["error", "always"]
	array-element-newline: ["error", "consistent"]
	comma-dangle: ["error", {"arrays": "always-multiline", "objects": "always-multiline"}]
	dot-location: ["error", "property"]
	function-call-argument-newline: ["error", "consistent"]
	multiline-ternary: ["error", "always-multiline"]
	object-property-newline: ["error", { "allowAllPropertiesOnSameLine": true }]
	quotes: ["error", "single"]
	valid-jsdoc: ["error", { "requireReturn": false }] */
/* globals GlobalWatchlist, $, mw, OO, Set, Promise */
/* Broken by IKhitron */
$(() => { // eslint-disable-line max-lines-per-function
	const GlobalWatchlist = {};
	window.GlobalWatchlist = GlobalWatchlist;

	GlobalWatchlist.cfg = {
		name: '[[:w:en:User:DannyS712/Global watchlist|Global Watchlist]]',
		version: '8.0.0',
		versionCSS: '5.1',
		versionDoc: '1.1',
		versionI18n: '1.1',
		versionTests: '2.2.0',
	};

	/**
	 * Initialize GlobalWatchlist script
	 *
	 * @group Manager/Split
	 * @param {number} mode Mode the script should start in, passed to mode()
	 */
	GlobalWatchlist.init = function() {
		mw.loader.load('//meta.wikimedia.org/w/index.php?title=User:DannyS712/Global watchlist.css&action=raw&ctype=text/css', 'text/css');
		const defaultCfg = {
				configMode: 0,
				confirmAllSites: true,
				fastMode: false,
				flags: {
					anon: 0,
					bot: 0,
					minor: 0,
					totalStr: 'unread'
				},
				groupPage: true,
				siteList: ['en.wikipedia', 'meta.wikimedia', 'commons.wikimedia', 'www.wikidata'],
				testNoActions: false,
				types: {
					edits: true,
					logEntries: true,
					newPages: true,
					totalStr: 'edit|log|new'
				},
				wlStr: 'ids|title|flags|loginfo|parsedcomment|user|tags',
			},
			mwCfg = mw.config.get(['skin', 'wgUserName', 'wgUserLanguage']);

		const cfg = {
			debugMode: mwCfg.wgUserName === 'DannyS712 test' ? 2 : 1,
			globalJS: `User:${mwCfg.wgUserName}/common.js`,
			lang: mwCfg.wgUserLanguage,
			minerva: mwCfg.skin === 'minerva',
		};

		$.get(mw.util.wikiScript(), {
				title: 'MediaWiki:Gadget-GlobalWatchlist.json',
				action: 'raw'
			})
			.done(function(data) {
				var WGWC = JSON.parse(data);
				$.get(mw.util.wikiScript(), {
						title: 'User:' + mw.config.get('wgUserName') + '/GlobalWatchlist.json',
						action: 'raw'
					})
					.done(function(data1) {
						$.extend(WGWC, JSON.parse(data1));
						const flags = {
								anon: WGWC.anonFilter || 0,
								bot: WGWC.botFilter || 0,
								minor: WGWC.minorFilter || 0
							},
							types = {
								edits: WGWC.showEdits !== false,
								logEntries: WGWC.showLogEntries !== false,
								newPages: WGWC.showNewPages !== false
							};
						flags.totalStr = ['unread', GlobalWatchlist.help.flag(flags.bot, 'bot'), GlobalWatchlist.help.flag(flags.anon, 'anon'), GlobalWatchlist.help.flag(flags.minor, 'minor')].join('');
						types.totalStr = ((types.edits ? 'edit|' : '') + (types.newPages ? 'new|' : '') + (types.logEntries ? 'log|' : '')).replace(/\|+$/, '');

						if (WGWC.fastMode) {
							cfg.fastMode = true;
							cfg.wlStr = 'ids|title|flags|loginfo';
						}
						cfg.configMode = 2;
						cfg.siteList = WGWC.sites;
						cfg.groupPage = WGWC.groupPage;
						cfg.confirmAllSites = WGWC.confirmAllSites;
						cfg.flags = flags;
						cfg.types = types;
					})
					.always(function() {
						const userSettings = cfg;
						GlobalWatchlist.cfg = $.extend({}, GlobalWatchlist.cfg, defaultCfg, userSettings);
						new mw.Api().getMessages(Object.values(GlobalWatchlist.i18n.mwMsgs)).then((mwUserLocalMsgs) => {
							const localMsgs = {},
								translations = $.extend({}, GlobalWatchlist.i18n.en, GlobalWatchlist.i18n[mwCfg.wgUserLanguage] || {});
							Object.keys(GlobalWatchlist.i18n.mwMsgs).forEach((k) => {
								localMsgs[`gw-msg-${k}`] = mwUserLocalMsgs[GlobalWatchlist.i18n.mwMsgs[k]];
							});
							if (mwCfg.wgUserLanguage !== 'qqx') {
								Object.keys(translations).forEach((k) => {
									localMsgs[`gw-msg-${k}`] = translations[k];
								});
							}
							mw.messages.set(localMsgs);
							GlobalWatchlist.cfg.mode = 2;
							GlobalWatchlist.help.setUp(2, 'globalWatchlistSettings');
							$('#mw-content-text').empty().append(GlobalWatchlist.settings.create());
							GlobalWatchlist.settings.prefill();
						});
					});
			});
	};

	/**
	 * Send a debug statement to the console
	 *
	 * @group Manager/Both
	 * @param {string} key Unique key to identify where the message was sent from
	 * @param {*|*[]} msg Message content
	 * @param {number} [level=1] The debug level necessary to show the message
	 */
	GlobalWatchlist.debug = function(key, msg, level = 1) {
		if (GlobalWatchlist.cfg.debugMode >= level) {
			console.log(`GlobalWatchlist@${key}:`); // eslint-disable-line no-console
			console.log(msg); // eslint-disable-line no-console
		}
	};

	/**
	 * Throw an error
	 *
	 * @group Manager/Both
	 * @param {string} info Description
	 * @param {*} error Error
	 */
	GlobalWatchlist.error = function(info, error) {
		GlobalWatchlist.debug(`ERROR: ${info}`, error, 0);
		alert('GlobalWatchlist error, please check the console!'); // eslint-disable-line no-alert
		throw new Error(`Error: ${info} - ${error}`);
	};

	/**
	 * @group Settings
	 */
	GlobalWatchlist.settings = {

		/**
		 * Save new user options
		 *
		 * @param {string} newOptions New options to save
		 */
		actuallySaveOptions: function(newOptions) {
			new mw.Api().edit(
					'User:' + mw.config.get('wgUserName') + '/GlobalWatchlist.json',
					function() {
						return {
							text: JSON.stringify(newOptions),
							summary: 'Change global watchlist settings',
						};
					}
				)
				.done(() => {
					GlobalWatchlist.debug('Settings.actuallySaveOptions', 'should be done');
					GlobalWatchlist.help.notify('settingsSaved');
					GlobalWatchlist.help.notify('redirecting');
					if (GlobalWatchlist.cfg.debugMode < 2) {
						setTimeout(() => {
							window.location.href = window.location.href.replace('GlobalWatchlistConfig', 'GlobalWatchlist');
						}, 2000);
					}
				}).fail(() => {
					new mw.Api().create('User:' + mw.config.get('wgUserName') + '/GlobalWatchlist.json', {
							summary: 'Create global watchlist settings'
						},
						'{}'
					).fail(() => {
						GlobalWatchlist.debug('Settings.actuallySaveOptions', 'something went wrong');
						GlobalWatchlist.help.notify('savingFailed');
					});
				});
		},

		/**
		 * Add a site row
		 *
		 * @param {string} [start=''] starting value for text input
		 * @return {OO.ui.ActionFieldLayout} created row
		 */
		addRow: function(start = '') {
			const num = GlobalWatchlist.elements.sites.length,
				row = new OO.ui.ActionFieldLayout(
					new OO.ui.TextInputWidget({
						classes: ['globalWatch-site-text'],
						value: start,
					}),
					GlobalWatchlist.OOUI.buttonInput('remove', '', ['destructive'], () => {
						GlobalWatchlist.elements.sites[num].toggle();
					})
				);
			GlobalWatchlist.elements.sitelist.addItems([row]);
			GlobalWatchlist.elements.sites.push(row);
			return row;
		},

		/**
		 * Return the elements to render the settings page
		 *
		 * @return {HTMLElement[]} Elements for display
		 */
		create: function() {
			return [
				GlobalWatchlist.OOUI.buttonInputSimpleE('resetChanges', GlobalWatchlist.settings.prefill, 'history'),
				GlobalWatchlist.OOUI.buttonE('Back', 'GlobalWatchlist', 'previous'),
				$('<hr>'),
				$('<br>'),
				$('<div id="globalWatch-sites">').append(
					GlobalWatchlist.OOUI.labelE('siteList'),
					$('<div id="globalWatch-sites-list">'),
					GlobalWatchlist.elements.sitelist.$element,
					GlobalWatchlist.OOUI.buttonInputSimpleE('add', GlobalWatchlist.settings.addRow, 'add'),
					GlobalWatchlist.OOUI.buttonInputSimpleE('save', GlobalWatchlist.settings.saveChanges, 'bookmark')
				),
				$('<div id="globalWatch-filters">').append(
					$('<div id="globalWatch-filters-label">').append(GlobalWatchlist.OOUI.labelE('filters')),
					$('<hr>'),
					$('<div id="globalWatch-filters-list">').append(
						GlobalWatchlist.elements.anon.$element,
						GlobalWatchlist.elements.bot.$element,
						GlobalWatchlist.elements.minor.$element
					),
					$('<hr>'),
					$('<div id="globalWatch-settings-other">').append(
						GlobalWatchlist.OOUI.optionsE('otherOptions', ['groupPage', 'confirmAllSites', 'fastMode']),
						GlobalWatchlist.OOUI.optionsE('changetypes', ['edits', 'logEntries', 'newPages'])
					)
				),
			];
		},

		/**
		 * Fill in settings elements based on current settings
		 */
		prefill: function() {
			const c = $.extend({}, GlobalWatchlist.cfg, GlobalWatchlist.cfg.types, GlobalWatchlist.cfg.flags);

			['anon', 'bot', 'minor'].forEach((s) => {
				GlobalWatchlist.elements[s].selectItemByData(c[s]);
			});
			['edits', 'logEntries', 'newPages', 'groupPage', 'confirmAllSites', 'fastMode'].forEach((s) => {
				GlobalWatchlist.elements[s].setSelected(c[s]);
			});

			GlobalWatchlist.elements.sitelist.clearItems();
			GlobalWatchlist.cfg.siteList.forEach((s, i) => {
				GlobalWatchlist.elements.sites[i].toggle(true);
				GlobalWatchlist.elements.sitelist.addItems([GlobalWatchlist.elements.sites[i]]);
				$('.globalWatch-site-text:last > input')[0].value = s;
			});
			GlobalWatchlist.elements.sites[GlobalWatchlist.cfg.siteList.length].toggle(true);
			GlobalWatchlist.elements.sitelist.addItems([GlobalWatchlist.elements.sites[GlobalWatchlist.cfg.siteList.length]]);
			$('.globalWatch-site-text:last > input')[0].value = '';
		},

		/**
		 * Save the new specified settings, with validation
		 */
		saveChanges: function() {
			const e = GlobalWatchlist.elements;
			console.log('e: ');
			console.log(e);
			const settings = {
				anonFilter: e.anon.findSelectedItem().data,
				botFilter: e.bot.findSelectedItem().data,
				confirmAllSites: e.confirmAllSites.isSelected(),
				fastMode: e.fastMode.isSelected(),
				groupPage: e.groupPage.isSelected(),
				minorFilter: e.minor.findSelectedItem().data,
				showEdits: e.edits.isSelected(),
				showLogEntries: e.logEntries.isSelected(),
				showNewPages: e.newPages.isSelected(),
				sites: [...new Set($('div.oo-ui-actionFieldLayout:visible .globalWatch-site-text > input').filter(function() {
					return this.value && this.value !== '';
				}).map((s, f) => f.value).toArray())],
			};
			GlobalWatchlist.settings.validate(settings).then((validation) => {
				GlobalWatchlist.debug('Settings.saveChanges - chosen and settingsValidation', [settings, validation]);
				if (validation.length > 0) {
					OO.ui.alert(new OO.ui.HtmlSnippet(`<ul><li>${validation.join('</li><li>')}</li></ul>`), {
						title: 'Invalid settings'
					});
				} else if (GlobalWatchlist.cfg.testNoActions) {
					GlobalWatchlist.debug('Settings.saveChanges - skipping, testNoActions', settings);
				} else {
					// eslint-disable-next-line prefer-template, prefer-named-capture-group
					GlobalWatchlist.settings.actuallySaveOptions(settings);
				}
			});
		},

		/**
		 * Validate the chosen settings
		 *
		 * @param {object} settings Chosen settings
		 * @return {jQuery.Promise} Validation of settings
		 */
		validate: function(settings) {
			return new Promise((resolve) => {
				new mw.Api().get({
					action: 'query',
					meta: 'globaluserinfo',
					guiprop: 'merged', // eslint-disable-line sort-keys
				}).done((response) => {
					const accounts = response.query.globaluserinfo.merged.map((s) => s.url.replace(/https:\/\/|\.org/g, '')),
						badSites = settings.sites.filter((s) => accounts.indexOf(s) === -1);
					let errors = [];
					GlobalWatchlist.debug('Settings.validate - bad sites', badSites);

					if (settings.sites.length === 0) {
						errors.push('nosites');
					}
					if (!settings.showEdits && !settings.showNewPages && !settings.showLogEntries) {
						errors.push('nochanges');
					}
					if (settings.anonFilter === 1 && settings.botFilter === 1) {
						errors.push('anonbot');
					}
					if (settings.anonFilter === 1 && settings.minorFilter === 1) {
						errors.push('anonminor');
					}
					errors = errors.map((e) => mw.msg(`gw-msg-settings-error-${e}`));
					if (badSites.length > 0) {
						errors.push(mw.msg('gw-msg-settings-error-badsites', badSites.join(', ')));
					}

					resolve(errors);
				});
			});
		},
	};

	GlobalWatchlist.watchlists = {}; // @group GlobalWatchlist

	/**
	 * @group Manager/Split
	 */
	GlobalWatchlist.help = {

		/**
		 * Helper for creating ForeignApi objects
		 *
		 * Separate from main GlobalWatchlist.Site object so that
		 * the api can overridden by tests for controlling results
		 *
		 * @group GlobalWatchlist
		 * @param {string} site Site for the api
		 * @return {mw.ForeignApi} created api instance
		 */
		api: function(site) {
			return new mw.ForeignApi(`//${site}.org/w/api.php`);
		},

		/**
		 * Helper for specifying watchlist api filters
		 *
		 * @group GlobalWatchlist
		 * @param {number} setting Value of the setting
		 * @param {string} msg Text for the setting
		 * @return {string} Text based on the setting
		 */
		flag: function(setting, msg) {
			if (setting === 1) {
				return `|${msg}`;
			}
			if (setting === 2) {
				return `|!${msg}`;
			}
			return '';
		},

		/**
		 * Show the user a notification
		 *
		 * @todo Use when an error is caught instead of alert
		 *
		 * @group Manager/Both
		 * @param {string} msg Key to unique message to show
		 */
		notify: function(msg) {
			mw.notify(mw.msg(`gw-msg-notify-${msg}`), {
				title: 'Global Watchlist'
			});
		},

		/**
		 * Set up page display and create elements
		 *
		 * @group Manager/Split
		 * @param {number} mode Identifier for which mode the script is in
		 * @param {string} page Identifier for which page is being shown
		 */
		setUp: function(mode, page) {
			window.document.title = mw.msg(`gw-msg-title-${page}`);
			$(`#${GlobalWatchlist.cfg.minerva ? 'section_0' : 'firstHeading'}`)[0].innerText = mw.msg(`gw-msg-heading-${page}`);

			GlobalWatchlist.elements = {
				anon: GlobalWatchlist.OOUI.filter('anon'),
				bot: GlobalWatchlist.OOUI.filter('bot'),
				confirmAllSites: GlobalWatchlist.OOUI.checkBox('option-confirmAllSites'),
				edits: GlobalWatchlist.OOUI.checkBox('show-edits'),
				fastMode: GlobalWatchlist.OOUI.checkBox('option-fastMode'),
				groupPage: GlobalWatchlist.OOUI.checkBox('option-groupPage'),
				logEntries: GlobalWatchlist.OOUI.checkBox('show-logEntries'),
				minor: GlobalWatchlist.OOUI.filter('minor'),
				newPages: GlobalWatchlist.OOUI.checkBox('show-newPages'),
				sitelist: new OO.ui.FieldsetLayout(),
				sites: [],
			};
			GlobalWatchlist.cfg.siteList.forEach((s) => GlobalWatchlist.settings.addRow(s));
			GlobalWatchlist.settings.addRow();
		},
	};

	/**
	 * @group Manager/Split
	 */
	GlobalWatchlist.OOUI = {

		/**
		 * Get an OO.ui.ButtonWidget element
		 *
		 * @group Both
		 * @param {string} msg Key to message for text to show
		 * @param {string} target Target for the link
		 * @param {string} [icon] Optional icon to show
		 * @return {jQuery} Created element
		 */
		buttonE: function(msg, target, icon) {
			return new OO.ui.ButtonWidget({
				flags: ['progressive'],
				href: `/wiki/Special:BlankPage/${target}`,
				icon: icon,
				label: mw.msg(`gw-msg-globalWatchlist${msg}Link`),
			}).$element;
		},

		/**
		 * Get an OO.ui.ButtonInputWidget
		 *
		 * @group Both
		 * @param {string} msg Key to message for text to show
		 * @param {string} id Id for the widget
		 * @param {string[]} [flags] Flags for the widget
		 * @param {Function} onClick Function to call when clicked
		 * @param {string} [icon] Optional icon to show
		 * @param {string} [classes] Optional classes to apply
		 * @return {OO.ui.ButtonInputWidget} Created widget
		 */
		buttonInput: function(msg, id, flags, onClick, icon, classes) { // eslint-disable-line max-params
			return new OO.ui.ButtonInputWidget({
				classes: [classes],
				flags: flags,
				icon: icon,
				id: id,
				label: mw.msg(`gw-msg-${msg}`),
			}).on('click', onClick);
		},

		/**
		 * Simple shortcut for buttonInput function
		 * @see GlobalWatchlist.help.buttonInput
		 *
		 * @group Settings
		 * @param {string} msg Key to message for text to show
		 * @param {Function} onClick Function to call when clicked
		 * @param {string} [icon] Optional icon to show
		 * @return {jQuery} Created element
		 */
		buttonInputSimpleE: function(msg, onClick, icon) {
			return GlobalWatchlist.OOUI.buttonInput(msg, `globalWatch-${msg}`, [], onClick, icon).$element;
		},

		/**
		 * Get an OO.ui.CheckboxMultioptionWidget
		 *
		 * @group Settings
		 * @param {string} label Key to message for text to show
		 * @return {OO.ui.CheckboxMultioptionWidget} Created widget
		 */
		checkBox: function(label) {
			return new OO.ui.CheckboxMultioptionWidget({
				label: mw.msg(`gw-msg-${label}`)
			});
		},

		/**
		 * Get an OO.ui.RadioSelectWidget
		 *
		 * @group Settings
		 * @param {string} filter one of 'anon', 'bot', or 'minor'
		 * @return {OO.ui.RadioSelectWidget} Created filter
		 */
		filter: function(filter) {
			return new OO.ui.RadioSelectWidget({
				items: ['either', `only-${filter}`, `not-${filter}`].map((m, i) => new OO.ui.RadioOptionWidget({
					data: i,
					label: mw.msg(`gw-msg-filter-${m}`)
				})),
				text: mw.msg(`gw-msg-filter-${filter}`),
			});
		},

		/**
		 * Get an OO.ui.LabelWidget element
		 *
		 * @group Both
		 * @param {string} msg Key to message for text to show
		 * @return {jQuery} Element created
		 */
		labelE: function(msg) {
			return new OO.ui.LabelWidget({
				label: mw.msg(`gw-msg-${msg}`)
			}).$element;
		},

		/**
		 * Get elements for a set of options
		 *
		 * @group Settings
		 * @param {string} msg Key to message for text to show
		 * @param {string[]} items Keys to GlobalWatchlist.elements for the items
		 * @return {jQuery[]} Label and checkboxes for the options
		 */
		optionsE: function(msg, items) {
			return [
				GlobalWatchlist.OOUI.labelE(msg),
				new OO.ui.CheckboxMultiselectWidget({
					items: items.map((i) => GlobalWatchlist.elements[i])
				}).$element,
			];
		},

		/**
		 * Get an OO.ui.ToggleButtonWidget
		 *
		 * @group GlobalWatchlist
		 * @param {string} msg Key to message for text to show
		 * @param {boolean} value Whether the toggle should be enabled
		 * @param {Function} onClick Function to call when clicked
		 * @return {OO.ui.ToggleButtonWidget} Created widget
		 */
		toggleButton: function(msg, value, onClick) {
			return new OO.ui.ToggleButtonWidget({
				disabled: GlobalWatchlist.cfg.fastMode,
				label: mw.msg(`gw-msg-option-${msg}`),
				value: value,
			}).on('click', onClick);
		},
	};
	GlobalWatchlist.i18n = {
		en: {
			'asOf': 'As of $1',
			'filter-anon': 'Anonymous edits',
			'filter-bot': 'Bot edits',
			'filter-either': 'Either',
			'filter-not-anon': 'Only edits made by logged-in users',
			'filter-not-bot': 'Only non-bot edits',
			'filter-not-minor': 'Only non-minor edits',
			'filter-only-anon': 'Only edits made anonymously',
			'filter-only-bot': 'Only bot edits',
			'filter-only-minor': 'Only minor edits',
			'globalWatchlistBackLink': 'Back to Global watchlist',
			'globalWatchlistLink': 'Global watchlist',
			'globalWatchlistSettingsLink': 'Settings',
			'heading-globalWatchlist': 'Global watchlist',
			'heading-globalWatchlistSettings': 'Global watchlist settings',
			'notify-redirecting': 'Redirecting back to global watchlist...',
			'notify-savingFailed': 'Failed to save settings. Please try again',
			'option-confirmAllSites': 'Require confirmation before marking all sites as seen',
			'option-fastMode': 'Load faster, at the expense of less detail',
			'otherOptions': 'Other settings',
			'resetChanges': 'Reset changes made',
			'settings-error-anonbot': 'Anonymous users cannot make bot edits',
			'settings-error-anonminor': 'Anonymous users cannot make minor edits',
			'settings-error-badsites': 'Invalid site(s): $1',
			'settings-error-nochanges': 'No change types selected',
			'settings-error-nosites': 'No sites selected',
			'show-edits': 'Show page edits',
			'show-logEntries': 'Show log entries',
			'show-newPages': 'Show new page creations',
			'siteList': 'User defined site list',
			'title-globalWatchlist': 'Global watchlist',
			'title-globalWatchlistSettings': 'Global watchlist settings',
		},
		he: {
			'asOf': 'נכון ל־$1',
			'filter-anon': 'עריכות אלמונים',
			'filter-bot': 'עריכות בוט',
			'filter-either': 'שניהם',
			'filter-not-anon': 'רק עריכות של משתמשים מחוברים',
			'filter-not-bot': 'רק עריכות של לא בוטים',
			'filter-not-minor': 'רק עריכות לא משניות',
			'filter-only-anon': 'רק עריכות של אלמונים',
			'filter-only-bot': 'רק עריכות של בוטים',
			'filter-only-minor': 'רק עריכות משניות',
			'globalWatchlistBackLink': 'חזרה לרשימת מעקב גלובלית',
			'globalWatchlistLink': 'רשימת מעקב גלובלית',
			'heading-globalWatchlist': 'רשימת מעקב גלובלית',
			'heading-globalWatchlistSettings': 'הגדרות רשימת מעקב גלובלית',
			'notify-savingFailed': 'שמירת ההגדרות נכשלה. נא לנסות שוב',
			'notify-redirecting': 'הפניה חזרה לרשימת מעקב גלובלית...',
			'option-confirmAllSites': 'לדרוש אישור לפני סימון כל האתרים כאתרים שנצפו',
			'option-fastMode': 'לטעון מהר יותר ולוותר על חלק מהפרטים',
			'otherOptions': 'הגדרות אחרות',
			'resetChanges': 'איפוס השינויים שנעשו',
			'settings-error-anonbot': 'משתמשים אלמוניים אינם יכולים לערוך כבוטים',
			'settings-error-anonminor': 'משתמשים אלמוניים אינם יכולים לעשות עריכות משניות',
			'settings-error-badsites': 'אתרים בלתי־תקינים: $1',
			'settings-error-nochanges': 'לא נבחרו סוגי עריכות',
			'settings-error-nosites': 'לא נבחרו אתרים',
			'show-edits': 'הצגת עריכות דף',
			'show-logEntries': 'הצגת רשומות יומן',
			'show-newPages': 'הצגת דפים חדשים',
			'siteList': 'רשימת האתרים להצגה',
			'title-globalWatchlist': 'רשימת מעקב גלובלית',
			'title-globalWatchlistSettings': 'הגדרות רשימת מעקב גלובלית',
		},
		mwMsgs: {
			'add': 'htmlform-cloner-create',
			'changes': 'nchanges',
			'changetypes': 'rcfilters-filtergroup-changetype',
			'editCount': 'ntimes',
			'editWatchlist': 'watchlistedit-normal-title',
			'filter-minor': 'rcfilters-filter-minor-label',
			'filters': 'whatlinkshere-filters',
			'notify-settingsSaved': 'savedprefs',
			'option-groupPage': 'rcfilters-group-results-by-page',
			'option-live': 'rcfilters-liveupdates-button',
			'remove': 'htmlform-cloner-delete',
			'save': 'saveprefs',
		}
	};
});

mw.loader.using(['mediawiki.util', 'mediawiki.api', 'mediawiki.ForeignApi', 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows', 'oojs-ui.styles.icons-movement', 'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-content', 'oojs-ui.styles.icons-media', 'oojs-ui.styles.icons-moderation'], () => {
	$(() => {
		if (mw.config.get('wgNamespaceNumber') === -1 && mw.config.get('wgCanonicalSpecialPageName') === 'Blankpage' &&
			(mw.config.get('wgTitle').split('/'))[1] === 'GlobalWatchlistConfig' && mw.config.get('wgDBname') === 'hewiki')
			GlobalWatchlist.init();
	});
});