User:Arashiryuu0/global.js

/** * Testing out UCP global JS. * @namespace UCPGlobal */ // jshint browser: true, devel: true, jquery: true // jshint strict: true, freeze: true, eqeqeq: true, futurehostile: true // jshint newcap: true, noarg: true, quotmark: single, shadow: outer // jshint latedef: true, undef: true, unused: true /* global mw, Promise, Symbol */ /** * @typedef {object} LogProps * @property {string} name - Namespace doing the logging. * @property {string} type - Level to be used for logging. */ /** * Finalized log method. * @callback logMethod * @params {...any} * @returns {void} */ /** * @typedef {object} ImportObject * @property {string} type * @property {string[]} articles */ /** * Initialization IIFE. * @returns {void} */   	'use strict'; if (window.UCP && window.UCP.globalJS) return; var has = Object.prototype.hasOwnProperty, slice = Array.prototype.slice, levels = ['log', 'info', 'warn', 'debug', 'error'], preloads = 2; function isNil (n) { return n === undefined || n === null; }	function queryTree (tree, query, options) { if (isNil(options)) options = {}; options.walkable = isNil(options.walkable) ? Object.keys(tree) : options.walkable; options.ignore = isNil(options.ignore) ? [] : options.ignore; if (typeof query === 'string') { if (has.call(tree, query)) return tree[query]; } else if (query(tree)) { return tree; }		if (isNil(tree)) return null; var ret = null; var len; var i;		if (Array.isArray(tree)) { for (i = 0, len = tree.length; i < len; i++) { var value = tree[i]; ret = queryTree(value, query, options); if (!isNil(ret)) return ret; }		} else { for (i = 0, len = options.walkable.length; i < len; i++) { var key = options.walkable[i]; if (!has.call(tree, key) || options.ignore.includes(key)) continue; ret = queryTree(tree[key], query, options); if (!isNil(ret)) return ret; }		}		return ret; }	/**	 * Bidirectional Hash Map */	function BiMap { return new Proxy(this, {			get: function (target, prop) {				if (Reflect.has(target, prop)) return target[prop];				var keys = Object.keys(target);				if (!keys.length) return null;				var hit = keys.find(function (key) { return target[key] == prop; // jshint ignore: line });				return hit;			},			set: function (target, prop, value) {				if (isNil(value)) return Reflect.set(target, prop, value);				var proto = Object.getPrototypeOf(value);				if (typeof value === 'object' && proto.constructor.name === 'Object') return Reflect.set(target, prop, new BiMap);				return Reflect.set(target, prop, value);			}		}); }	Object.freeze(BiMap); Object.freeze(BiMap.prototype); var run = function { var myHook = mw.hook('window.ready'); var getLevel = function (level) { return levels.includes(level) ? level : 'log'; };		var _log = function (props) { if (typeof props !== 'object' || props.toString !== '[object Object]') return null; var name = props.name || 'Logger|', type = getLevel(props.type); name += name === 'Logger|' ? type : 'log'; return function { var args = slice.call(arguments), time = new Date.toUTCString, parts = [ '%c[' + name + ']%c \u2014 %s', 'color: #C3E88D;', '',						time ];				console.group.apply(null, parts); console[type].apply(null, args); console.groupEnd; };		};		var Logger = { log: _log({ type: 'log' }), info: _log({ type: 'info' }), warn: _log({ type: 'warn' }), debug: _log({ type: 'debug' }), error: _log({ type: 'error' }) };		Object.defineProperty(Logger, Symbol.toStringTag, {			configurable: false,			writbable: false,			value: 'Logger'		}); Object.freeze(Logger); window.importArticles.apply(null, [			{				type: 'script',				articles: [					'u:dev:MediaWiki:Toasts.js',					'u:dev:MediaWiki:Preact.js',					'u:dev:MediaWiki:CodeblockLineNumbers/code.js'				]			},			{				type: 'style',				articles: [					'u:dev:MediaWiki:CodeblockLineNumbers.css'				]			}		]); ;(function {			if (window.hljs) return;			[				'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.0/styles/atom-one-dark.min.css',				'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.0/highlight.min.js'			].forEach(function (url, index) { var isCss = index === 0, type = isCss ? 'text' : 'script'; $.get(url, void 0, $.noop, type).then(function handleHljs {					if (isCss) {						var link = document.createElement('link');						link.setAttribute('href', url);						link.setAttribute('rel', 'stylesheet');						document.head.appendChild(link);					} else {						mw.hook('wikipage.content').add(function ($content) { if (!$content) $content = $('body'); $content.find('.mw-highlight pre').each(function (i, element) {								window.hljs.highlightBlock(element);							}); });					}					--preloads;				}, Logger.error); });		});		/**		 * Change source editor theme. * @returns {void} */		;(function {		    var pageType = window.location.href.split('?')[0].split('.').pop,			    isEditPage = window.location.search === '?action=edit';			if (!isEditPage || !['css', 'js', 'javascript'].includes(pageType)) return;			function getTheme  {				return 'ace/theme/tomorrow_night';			}			mw.hook('codeEditor.configure').add(function  { setTimeout(function {					var editor = window.ace.edit(document.querySelector('.editor.ace_editor'));					editor.setTheme(getTheme);				}, 100); });		});		/**		 * Codeblock theme buttons */		;(function {			if (!['css', 'js', 'json', 'javascript'].includes(window.location.href.split('.').pop)) return;			var base = 'https://dev.fandom.com/wiki/MediaWiki:Highlight-js/styles/',				themes = [					'atom-one-dark',					'tomorrow-night',					'solarized-dark',					'monokai-sublime',					'dracula',					'vs2015',					'nord'				],				buttons = [],				container = document.createElement('div');			container.setAttribute('id', 'code-button-container');			container.setAttribute('style', 'display: block; padding: 5px 0 10px 0; text-align: center;');			function handleLinks (links, activeTheme) {				var found = links.find(function (link) { return link.getAttribute('href').includes(activeTheme); });				links.forEach(function (link) { link.setAttribute('disabled', ''); });				if (!found) {					var fresh = document.createElement('link');					fresh.setAttribute('rel', 'stylesheet');					fresh.setAttribute('href', base + activeTheme + '.css?action=raw&ctype=text/css');					document.head.appendChild(fresh);					return;				}				found.removeAttribute('disabled');			}			function setTheme (theme) {				var links = slice.call(document.querySelectorAll('link[href*="' + base + '"]'));				handleLinks(links, theme);			}			function buttonClick (button) {				var theme = button.getAttribute('data-theme');				return function {					if (!theme) return;					setTheme(theme);				};			}			function addButtons  {				if (buttons.length || document.contains(container)) return;				var target = document.getElementById('mw-clearyourcache');				if (!target) return;				themes.forEach(function (theme, idx) { if (idx === 4) { var n = document.createElement('hr'); n.setAttribute('style', 'visibility: hidden; margin: 0;'); buttons.push(n); }					var btn = document.createElement('div'); btn.setAttribute('class', 'wds-button'); btn.setAttribute('data-theme', theme); btn.setAttribute('style', 'margin-right: 2px;'); btn.textContent = theme; btn.addEventListener('click', buttonClick(btn)); buttons.push(btn); });				buttons.forEach(function (button) { container.appendChild(button); });				target.appendChild(container);			}			mw.hook('wikipage.content').add(addButtons);		}); function getFromHook (hookName) { if (typeof hookName !== 'string') return Promise.reject('Invalid hook name, hook names must be strings.'); return new Promise(function (resolve) {				mw.hook(hookName).add(resolve);			}); }		function getHookValues { var args = slice.call(arguments); var stringCheck = function (s) { return typeof s === 'string'; };			var mapFn = function (hookName) { return getFromHook(hookName); };			if (!args.length || !args.every(stringCheck)) return []; return args.map(mapFn); }		function ready (modules) { var toasts, lines, utils; if (document.readyState !== 'complete' || preloads > 0) return setTimeout(ready, 1000, modules); toasts = modules[0]; lines = modules[1]; utils = { '$': $,				'mw': mw, 'pull': window.importArticles, 'lines': lines, 'logger': Logger, 'toasts': toasts, 'classes': { 'BiMap': BiMap },				'queryTree': queryTree };			Object.freeze(utils); myHook.fire(utils); }		myHook.add(function (utils) {			var highlightTheme = document.head.querySelector('link[href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.0/styles/atom-one-dark.min.css"]'),			   href = highlightTheme && highlightTheme.getAttribute('href');		    if (utils.lines) utils.lines.process;			if (utils.logger) utils.logger.log('_readyDeps', utils);			if (href) {				href = href.replace(/atom-one-(light|dark)/, 'vs2015');				highlightTheme.setAttribute('href', href);			}			window._readyDeps = utils;		}); Promise .all(getHookValues('dev.toasts', 'dev.CodeblockLineNumbers')) .then(ready, Logger.error); };	var wait = function { if (document.readyState !== 'complete') return setTimeout(wait, 1000); setTimeout(run, 0); };	window.UCP = window.UCP || {}; window.UCP.globalJS = true; mw.hook('dev.preact').add(function (Preact) {		var useState = Preact.useState,			useEffect = Preact.useEffect,			useReducer = Preact.useReducer, // jshint ignore: line			render = Preact.render,			h = Preact.h;		function Clock {			var _d = useState(new Date);			var hovered = useState(false);			useEffect(function  { var interval = setInterval(function {					_d.set(new Date);				}, 1000); return function { clearInterval(interval); };			}, []);			return h('span', { className: 'clock', children: [ h('span', {						className: 'clock-day',						children: _d.value.toLocaleDateString(void 0, { weekday: 'long' })					}), h('span', {						className: 'clock-separator',						children: String.fromCharCode(160)					}), h('span', {						className: 'clock-time',						children: _d.value.toLocaleTimeString(void 0, { hour12: false })					}) ],				onMouseEnter: function (e) { if (hovered.value) return; e.target.classList.add('hovered'); hovered.set(true); },				onMouseLeave: function (e) { if (!hovered.value) return; e.target.classList.remove('hovered'); hovered.set(false); },				onClick: function { location.href = location.href; }			});		}		function addClock {			if (document.getElementById('DisplayClock')) return;			const timeRoot = Object.assign(document.createElement('div'), { id: 'DisplayClock' });			const target = document.querySelector('.fandom-community-header__top-container + .fandom-community-header__local-navigation');			target.appendChild(timeRoot);			render(h(Clock), timeRoot);		}		addClock;	}); wait; }); /*@end@*/
 * (function {