User:Arashiryuu0/common.js

/** * @namespace Personal_JS */ // 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, esversion: 6 /* globals mw */ /** * Callback for when Fandom is ready. * @callback cb * @returns {void} */ /** * Method used for logging. * @callback logMethod * @example * // The Logger object doesn't inherit from the Object prototype so we can't do `Logger.propertyIsEnumerable('log')`. * Logger.log('enumerable:', Object.getOwnPropertyDescriptor(Logger, 'log').enumerable); * @returns {void} */ /** * Initialization IIFE. * @returns {void} */   'use strict'; if (window.UCP && window.UCP.localJS) return; /**    * Cache of fired hooks. */   const fired = new mw.Map; /**    * @type {cb} * @returns {void} */   const loaded = function  { if (fired.exists('loaded')) return; const slice = Array.prototype.slice; const toString = Object.prototype.toString; const levels = ['log', 'dir', 'info', 'warn', 'debug', 'error']; window.importArticles.apply(null, [			{				type: 'style',				articles: [					'u:no-game-no-life:User:Arashiryuu0/common.css'				]			},			{				type: 'script',				articles: [					'u:dev:MediaWiki:Preact.js'				]			}		]); /**		 * Binds all methods listed to the same target object. * @param {*} target * @returns {*} */		const bindAll = function (target) { const args = slice.call(arguments, 1); const bind = function (key) { target[key] = target[key].bind(target); };			if (!args.length) return target; (				Array.isArray(args[0])					? args[0]					: args			).forEach(bind); return target; };       /**         * Creates log methods. * @name makeLog * @param {string|number} level * @param {string} name * @returns {logMethod} */       const makeLog = function (level, name) { const useParts = function { return [ '%c[' + name + ']%c \u2014 %s', 'color: #82AAFF;', 'color: #F78C6A;', new Date.toUTCString ];			};           return function  { console.group.apply(null, useParts); console[level].apply(null, arguments); console.groupEnd; };       };        const Logger = levels.reduce(function (o, level) {			Object.defineProperty(o, level, { value: makeLog(level, 'User:Arashiryuu0/common.js') });			return o;        }, Object.create(null)); bindAll(Logger, levels); Object.defineProperty(Logger, Symbol.toStringTag, {			configurable: false,			enumerable: false,			writable: false,			value: 'Logger'       }); /**        * Determines if something is undefined or null. * Accounting for `document.all` and other potential weirdness version. * @param {*} anything * @returns {boolean} */       const isNil = function (anything) { return anything === undefined || anything === null; };       /**         * Simple polyfill for the nullish coalescing operator (??) * @param {*} expected * @param {*} fallback * @returns {*} */       const nullishCoalesce = function (expected, fallback) { return isNil(expected) ? fallback : expected; };       /**         * Safely traverses an object. * @param {*} obj * @param {string} path * @returns {*|false} */       const getProp = function (obj, path) { return path.split(/\s?\.\s?/).reduce(function (o, prop) {				return o && o[prop];			}, obj); };       /**         * Gets a more accurate description of an object than `typeof`. * @name typeOf * @param {*} item * @returns {string} */		const typeOf = function (item) { return toString .call(item) .match(/\[object (\w+)\]/i)[1] .toLowerCase; };       /**         * Checks whether something is a Node instance. * @name isNode * @param {*} tester * @returns {boolean} */       function isNode (tester) { return tester instanceof Node; }       /**         * Loading scripts through the ResourceLoader via mw.loader * @returns {void} */       ;(function  {            const sUri = 'https://reds-test.fandom.com/wiki/User:Arashiryuu0/sandbox';            const sQuery = '?ctype=text/javascript&action=raw';            const queries = [				sUri + sQuery,				sUri + '.javascript' + sQuery			];            const load = function (url) {                if (typeof url !== 'string') return;                mw.loader.load(url);            };            queries.forEach(load);        }); /**        * Disables tab selecting unwanted elements. */       ;(function  {			const bannerItems = [				document.querySelector('.wds-global-navigation__logo')			].concat(slice.call(document.querySelectorAll('.wds-global-navigation__link')));			bannerItems.forEach(function (item) { if (!item) return; item.setAttribute('tabindex', '-1'); });		});		/**		 * Add custom buttons to page. */		;(function {			if (fired.exists('buttons')) return;			const wdsButtons = document.querySelectorAll('.wiki-tools.wds-button-group');			if (!wdsButtons.length) return;			const createElement = function (type, props) {				if (typeof type !== 'string' || typeOf(props) !== 'object') return;				const element = document.createElement(type);				Object.assign(element, props);				return element;			};			const buttons = [				createElement('a', { className: wdsButtons[0].firstElementChild.className.replace('wiki-tools__search', 'wiki-tools__user-js'), textContent: 'JS', href: '/wiki/User:Arashiryuu0/common.js', style: { fontSize: '16px', color: 'var(--wds-secondary-button-label-color, white)' }				}),				createElement('a', { className: wdsButtons[0].firstElementChild.className.replace('wiki-tools__search', 'wiki-tools__user-css'), textContent: 'CSS', href: '/wiki/User:Arashiryuu0/common.css', style: { fontSize: '16px', color: 'var(--wds-secondary-button-label-color, white)' }				}),				createElement('a', { className: wdsButtons[0].firstElementChild.className.replace('wiki-tools__search', 'wiki-tools__random'), textContent: '?', href: '/wiki/Special:Random', style: { fontSize: '16px', color: 'var(--wds-secondary-button-label-color, white)' }				})			];			wdsButtons.forEach(function (wds) { buttons.map(function (button) {					return button.cloneNode(true);				}).forEach(function (button) {					if (!button) return;					wds.appendChild(button);				}); /**				 * fix button positioning * layout should be: * search, discussions, recent changes, theme, my buttons, dropdown */				wds.appendChild(wds.querySelector('.wds-dropdown')); });			fired.set('buttons', true);		}); window.UCP.Logger = Logger; window.UCP.Utils = Object.assign(Object.create(null), {			type: typeOf,			isNil: isNil,			isNode: isNode,			bindAll: bindAll,			getProp: getProp,			nullishCoalesce: nullishCoalesce		}); bindAll(window.UCP.Utils, Object.keys(window.UCP.Utils)); Object.defineProperty(window.UCP.Utils, Symbol.toStringTag, {			configurable: false,			enumerable: false,			writable: false,			value: 'Utils'		}); fired.set('loaded', true); };	/**	 * Waits for the document to finish loading and defers callback execution. * @returns {void} */	function wait { if (document.readyState !== 'complete') return setTimeout(wait, 1000); mw.hook('window.ready').add(loaded); }	window.UCP = window.UCP || {}; window.UCP.localJS = { cache: fired }; wait; }); /*@end@*/
 * (function {