User:Thundercraft5/global.js/utils.js

/* jshint esversion: 6, forin: true, immed: true, indent: 4, latedef: true, newcap: true, noarg: true, undef: true, undef: true, unused: true, browser: true, jquery: true, onevar: true, eqeqeq: true, multistr: true, -W093, -W040 /* global mw, checkThis, checkObj, checkFunction, addMethods, setWindowVals */ "use strict"; window.setWindowVals = function(values) { for (const [k, v] of Object.entries(values)) window[k] = v; };

setWindowVals({	addMethods(o, proto, methods) {		var options = {};		if (typeof(proto) === 'object') methods = proto, proto = undefined;		for (const [name, func] of Object.entries(methods)) {			options[name] = {				value: func,				configurable: true,				enumerable: false,				writable: true,			};		}		Object.defineProperties(proto ? o.prototype : o, options);		return options;	},	checkThis(v, type) {		if ( v === null || v === undefined || (typeof(type) === "function" 				? ( /* jshint ignore:start */ !(v instanceof type) || v.constructor?.name === type.constructor.name /* jshint ignore:end */ )				: (type && typeof(v) !== type)			) ) {			var [, parent, name] = (new Error.stack.replace(/\s*at (.+)/, '')).match(/^(?:[^\0]+?)at (?:(?:.+?\.){1,})?(.+?)\.(\w+)/);			throw new TypeError( typeof(type) === "function" ? `${parent}.prototype.${name} requires that 'this' be ${type.name.match(/^[aeiouy]/i) ? 'an' : 'a'} ${type.name}` : typeof(type) === "string" ? `${parent}.prototype.${name} requires that 'this' be ${type.match(/^[aeiouy]/i) ? 'an' : 'a'} ${type}` : `${parent}.prototype.${name} called on null or undefined` );		}		return v;	},	checkObj(o) {		if (o === null || o	=== undefined) throw new TypeError('Cannot convert null or undefined to object');		return o;	},	checkFunction(f) {		try {			[].map(f);			return f;		} catch(e) {			throw new TypeError(e.message);		}	},	recurseObject(o, callback) {	   function recurse(o, callback, seen=new Set) {	        if (['function', 'object'].includes(typeof(o)) && o !== null && !seen.has(o)) {	        	seen.add(o);	            for (const [k, v] of Object.entries(o)) {	                if (['function', 'object'].includes(typeof(v)) && v !== null && !seen.has(v)) {	                    recurse(v, callback, seen);	                    seen.add(v);	                } else {	                    callback(k, v, o);	                }	            }	        }	    }	    return recurse(o, callback);	}, });

addMethods(Array, true, {	tail {		checkThis(this, Array);		this.push(this.shift);		return this;	},	untail {		checkThis(this, Array);		this.unshift(this.pop);		return this;	},	remove(index) {		checkThis(this, Array);		this.splice(index || 0, 1);		return this.length;	},	insert(index, ...items) {		checkThis(this, Array);		this.splice(index || 0, 0, ...items);		return this.length;	},	drop(startIndex, endIndex=undefined) {		checkThis(this, Array);		return this.splice(startIndex || 0, this.length-(endIndex || 0));	},	clean {		checkThis(this, Array);		return this.filter((v) => v !== null || v !== undefined);	} });

Blob.prototype.createObjectURL = function { return URL.createObjectURL(this); };

addMethods(String, true, {	forEachMatch(pattern, callback, thisArg) {		checkThis(this);		checkFunction(callback);		var i = 0;		var v = String(this);		if (!new RegExp(pattern).global) pattern = new RegExp(pattern, (pattern.flags || '') + "g");		for (var match of v.matchAll(pattern)) {			i++;			match = match.tail.concat(i);			callback.apply(thisArg, match);		}		return v;	}, });

addMethods(Object, {	forOwn(o, callback, thisArg) {		checkObj(o);		checkFunction(callback);		let count = 0;		for (const i in o) {			if (o.hasOwnProperty(i)) {				count++;				callback.call(thisArg, o[i], i, o, count);			}		}		return o;	},

forOwnRight(o, callback, thisArg) { checkObj(o); checkFunction(callback); var results = Object.getOwnPropertyNames(o); for (var i = results.length; i--;) { callback.call(thisArg, o[results[i]], results[i], o, i); }	},	forNames(o, callback, thisArg) { checkObj(o); checkFunction(callback); let count = 0; for (const name of Object.getOwnPropertyNames(o)) { count++; callback.call(thisArg, o[name], name, o, count); }		return o;	}, });

$.extend($.fn, {	exists {		return !!$(this).length;	},	replaceHtml(search, repl) {		$(this).html($(this).html.replace(search, repl));		return this;	},	outerHtml(v) {		var $this = $(this);		return v ? $this.prop('outerHTML', v) : $this.prop('outerHTML');	},	replaceOuterHtml(search, repl) {		$(this).outerHtml($(this).outerHtml.replace(search, repl));		return this;	},	replaceProp(name, search, repl) {		$(this).prop(name, $(this).prop(name).replace(search, repl));			return this;	},	replaceAttr(name, search, repl) {		$(this).attr(name, $(this).attr(name).replace(search, repl));		return this;	} });

$.extend({	getUrlVar(name, url) {		return mw.util.getParamValue(name, url);	},	getUrlVars(url) {		url = ((url || ).match(/^.+?(\?.+)$/) || [])[1] || window.location.search;		var ret = {};		if (!url) return null;		url = url.replace(/^\?/, ).split('&');		url.forEach(function(v) { v = v.match('([^=]+)=(.+)'); v.shift; if (v[1] === "true" || v[1] === "false" || v[1] === "null") { switch(v[1]) { case("true"): v[1] = true; break; case("false"): v[1] = false; break; case("null"): v[1] = null; break; }			} else if (v[1].match(/^(\d+?)$/)) { v[1] = Number(v[1]); }			ret[v[0]] = v[1]; });		return ret;	},	executeScriptPage(v) {		var wiki, page, lang, url, prefix,			oldVal = v,			server = mw.config.get('wgServer'),			def = new this.Deferred;		if (v.match(/^(u|url):/)) {			v = v.match(/^(?:u|url):(\S+?):([a-z]+?:)?([^\n\[\]<>\{\}\|]+)/);			v.shift;			wiki = v[0], lang = v[1], page = v[2];		}		wiki = wiki || ;		page = page || v;		if (wiki.toLowerCase.match(/^wp|wikipedia$/)) wiki = (lang || 'en') + '.wikipedia.org', lang = null;		if (wiki.toLowerCase.match(/^mw|mediawiki$/)) wiki = 'mediawiki.org', lang = null;		var namespace = page.match(/^(.+?):/) ? page.match(/^(.+?):/)[1] : 'MediaWiki',			page = page.match(/^(.+?):(.+)/) ? page.match(/^(?:.+?):(.+)/)[1] : page;		wiki = wiki || server.replace('.fandom.com', ).replace('https://', );		prefix = lang !== null || (!wiki.match(/\.fandom\.com/) || !oldVal.match(/\./)) ? '.fandom.com' : ;		url = 			'https://' + wiki + prefix + (lang ? '/' + lang.replace(':', ) : ) + '/wiki/' + namespace + ':'				+ (!page.match(/\.(js|javascript)$/) ? page + '.js' : page) + '?action=raw&ctype=text/javascript'; try { this.getScript(url).then(def.resolve); } catch(e) { def.reject(e); console.warn('jQuery.executeScriptPage exeption:', e.message, e.stack, undefined); }		return def; },	joinIfArray(v, sep) { return Array.isArray(v) ? v.join(sep || '') : v;	}, getStyle(page, id) { page = page || window.location.pathname.replace(mw.config.get('wgPageName')); const get = page => { return this.get(page, res => {				this(' ', { id: id, type: "text/css", text: res, }).appendTo('head');			}); };		const setUrl = page => { return page.match(/^u:/) ? `/load.php?mode=articles&articles=${page}&only=styles` : new mw.Uri(page).extend({ 						ctype: "text/javascript", 						action: "raw" 					}) .toString; };		if (Array.isArray(page)) { page.forEach((v, k, arr) => arr[k] = get(setUrl(v))); return page; } else { return get(setUrl(page)); }	},	asyncEach(promises, callback, thisArg, ...appendArgs) { return this.when.apply(this, promises).then(function {			Array.from(arguments).forEach(v => callback.apply(thisArg || window, [v].concat(appendArgs)));		}); }, });

window.Cookies = { raw { return document.cookie; },

generateCookieString(key, value, { domain, maxAge=60*60*24*365, expires=60*60*24*365, secure, samesite }={}) { var obj = { [key]: value, domain, maxAge, expires, secure, samesite }; var ret = [];

for (const [k, v] of Object.entries(obj)) { if (v) ret.push(`${k}=${encodeURIComponent(v)}`); }		return ret.join('; '); },

toJson(replacer, space) { return JSON.stringify(this.toObject, replacer, space); },

parseCookies(str) { var ret = {}; str.split(/\s*;\s*/) .map(v => v.split('=')) .forEach(([ key, value ]) => ret[key] = value); return ret; },

toObject { return this.parseCookies(this.raw); },

get(name) { return this.toObject[name]; },

set(name, value, options) { return document.cookie = this.generateCookieString(name, value, options); },

delete(name) { if (!this.has(name)) return false; document.cookie = name +'=; expires=' + new Date; return true; },

has(name) { return !!this.get(name); },

list { return Object.keys(this.toObject); },	forEach(callbackfn, thisArg=window) { for (const [k, v] of this.entries) { callbackfn.call(thisArg, v, k, this); }		},

* keys { for (const key of Object.keys(this.toObject)) { yield key; }	},

* entries { for (const [key, value] of Object.entries(this.toObject)) { yield [key, value]; }	},

* values { for (const value of Object.values(this.toObject)) { yield value; }	},

toString { return this.raw; },

get store { return this.toObject; },	[Symbol.toStringTag]: 'CookieManager', };

window.Cookies[Symbol.iterator] = window.Cookies.entries; var props = {};

for (const k in window.Cookies) { if (window.Cookies.hasOwnProperty(k)) props[k] = k !== 'store' ? {		configurable: false, writable: false, enumerable: true, } : {		get: Object.getOwnPropertyDescriptor(window.Cookies, 'store').get, }; }

Object.defineProperties(window.Cookies, $.extend(props, { [Symbol.toStringTag]: { enumerable: false, },	[Symbol.iterator]: { enumerable: false, }, }));

(function {	let dbName = "Test";	let request = window.indexedDB.open(dbName, 2);	let customerData = [		{ ssn: "444-44-4444", name: "Bill", age: 35, email: "bill@company.com" },		{ ssn: "555-55-5555", name: "Donna", age: 32, email: "donna@home.org" }	];	request.onerror = console.warn;	request.onupgradeneeded = function(event) {		let db = event.target.result;		let objectStore = db.createObjectStore("customers", { keyPath: "ssn" });		console.log(objectStore, db);

objectStore.createIndex("name", "name", { unique: false }); objectStore.createIndex("email", "email", { unique: true }); objectStore.transaction.oncomplete = function(event) { let customerObjectStore = db.transaction("customers", "readwrite").objectStore("customers"); customerData.forEach(function(customer) {				console.log(customer);				customerObjectStore.add(customer);			}); };	}; });