User:Wiki Barry/common.js

importArticles({   type: 'script',    articles: [		'u:dev:MediaWiki:PageRenameAuto-update/code.js',        'u:dev:MediaWiki:MassCategorization/code.js',        'u:dev:MediaWiki:MassRename/code.js',        'u:dev:MediaWiki:MassPatrol/code.js',        'u:dev:MediaWiki:MassRenameRevert/code.js',        'u:dev:MediaWiki:MassEdit/code.js',        'u:dev:MediaWiki:MassProtect/code.js',        'u:dev:MediaWiki:AjaxBatchDelete.js',        'u:dev:MediaWiki:AjaxDiff/code.js',        'u:dev:MediaWiki:FastCreate.js',        'u:dev:MediaWiki:SelectiveDelete/code.js',        'u:dev:MediaWiki:ViewDeleted/code.js',        /*'u:dev:MediaWiki:AjaxEdit.js',*/        'u:dev:MediaWiki:FixWantedFiles/code.js',        'u:dev:MediaWiki:AnalyticsShortcut.js',        'u:dev:MediaWiki:FileUsageAuto-update/code.js',        /*'u:dev:MediaWiki:CategoryRenameAuto-update/code.js',*/        ] });

//Used With Fast Create. Will fiddle around later to make a "create dungeon page" button. /*window.FCButtons = [ {       label: 'Create userpage', target: 'User:TheGoldenPatrik1', summary: 'Creating', content: '', alwaysDisplay: true, placement: '.wds-global-navigation__user-menu .wds-list' },   {        label: 'Sandbox', target: 'User:TheGoldenPatrik1/Sandbox', summary: 'Creating via Script', content: 'This is my Sandbox.', prepend: true, require: mw.config.get('wgPageName') === 'User:TheGoldenPatrik1' } ];*/

/** * FileForm * Creates an interactive form that fills out a template when uploading a file * @author Caburum * @see https://dev.fandom.com/wiki/Preact * @see https://dev.fandom.com/wiki/Fetch */

/* jshint esversion: 5, esnext: false, browser: true, jquery: true, latedef: true, undef: true, unused: true, eqeqeq: true, -W084, maxerr: 999999 /* global mw, importArticles */

(function {	// Make Special:NewFiles button go to Special:Upload	if (mw.config.get('wgCanonicalSpecialPageName') === 'Newimages') {		$('#page-header-add-new-photo').attr('href', mw.util.getUrl('Special:Upload')).off;	}

// Only run on Special:Upload if (		mw.config.get('wgCanonicalSpecialPageName') !== 'Upload'		|| mw.util.getParamValue('wpForReUpload')		|| $('#fileform').length // already initialized		|| $('.mw-destfile-warning').length // ignore if there is a warning for now (@todo: form needs to persist through this)	) return;

var config, // Preact shorthands preact, h /* h('div', props) */, tags /* tags.div(props) */, useState, useEffect, useReducer;

function shouldHide(data, state) { // hide if data.if doesn't match the current state return data.if && !Object.keys(data.if).every(function(key) {			return data.if[key].includes(state[key]);		}); }

function generateTemplate(params) { // Generate template var template = ) : ;	}

// Creates various input elements function InputElement(props) { function onFieldChange(e) { props.state.set(function(state) {				// we need to create a new object in order to trigger a state update				var newState = {};				newState[props.id] = e.target.value;				return Object.assign({}, state, newState);			}); }

// Initialize state if it hasn't already useEffect(function {			if (!props.state.value[props.id]) onFieldChange({ target: { value: props.type === 'select' ? props.default : '' } });		}, []);

var id = 'fileform-' + props.id; switch (props.type) { // multiline input case 'textarea': return tags.textarea({				id: id,				value: props.state.value[props.id],				onInput: onFieldChange,				rows: 1			}); // plain one-line input case 'input': return tags.input({				id: id,				value: props.state.value[props.id],				onInput: onFieldChange,				type: 'text',				placeholder: props.default			}); // dropdown with values case 'select': return tags.select({				id: id,				value: props.state.value[props.id],				onInput: onFieldChange,				children: Object.keys(props.options).map(function(option) { return tags.option({						value: option,						child: props.options[option],						// selected: props.default === option // set in initial useEffect					}); })			});			// one-line input with suggested values case 'datalist': return preact.frag([				tags.input({ id: id, value: props.state.value[props.id], onInput: onFieldChange, list: id + '-list', placeholder: props.options[props.default] }),				tags.datalist({ id: id + '-list', children: Object.keys(props.options).map(function(option) {						return tags.option({ value: option, child: props.options[option] });					})				})			]);			// error default: return tags.div({				class: 'error',				child: 'Unknown type'			}); }	}

function FormElements(props) { useEffect(function {			// console.log('FileForm state change:', props.state.value);			$('#wpUploadDescription').val(generateTemplate(props.state.value));		}, [props.state.value]);

return tags.div({			id: 'fileform-fields',			children: props.config.form.map(function(data) { data.state = props.state; return tags.tr({					style: {						display: shouldHide(data, props.state.value) ? 'none': null					},					children: [						tags.td({ child: tags.label({							for: 'fileform-' + data.id,							child: data.label + ' '						})}),						tags.td({ child: h(InputElement, data)})					]				}); })		});	}

function Tabber(props) { return tags.div({			class: 'wds-tabs__wrapper with-bottom-border',			child: tags.ul({ class: 'wds-tabs', children: props.items.map(function(item) {					return tags.li({ onClick: function { props.state.dispatch(item.id); },						class: 'wds-tabs__tab ' + (props.state.state === item.id ? 'wds-is-current' : ''), child: tags.div({							class: 'wds-tabs__tab-label',							child: tags.a({ child: item.label, href: '#!' + item.id							})						}) });				})			})		});	}

// The root component of the app function App { var fieldState = useState({});

var previousTemplate = useState(''); var tabberState = useReducer(function(state, newState) {			var mwSummary = $('#mw-htmlform-description .mw-htmlform-field-HTMLTextAreaField');			switch (newState) {				case 'fileform':					// When going back, tell the user that their custom changes won't be saved					if ( previousTemplate.value !== $('#wpUploadDescription').val.trim && !confirm('Returning to the form will overwrite your changes. Do you want to go back?') ) return state;					mwSummary.hide;					break;				case 'mw':					previousTemplate.set(generateTemplate(fieldState.value));					mwSummary.show;					break;			}			return newState;		}, 'fileform');

// Generate field elements return tags.td({ colspan: 2, child: tags.table({ children: [ h(Tabber, {				items: [					{ label: 'FileForm', id: 'fileform' },					{ label: $('label[for="wpUploadDescription"]').text.replace(':', '').trim || 'Summary', id: 'mw' }				],				state: tabberState			}), tags.tr({ // for debugging				child: 'Form state: ' + JSON.stringify(fieldState.value),				style: { display: 'none' }			}), tabberState.state === 'fileform' ? h(FormElements, {				config: config,				state: fieldState			}) : null ]})});	}

function init { // Remove original form $('#mw-htmlform-description .mw-htmlform-field-HTMLTextAreaField').hide; // summary $('.mw-htmlform-field-Licenses, #mw-htmlform-description tr:has(#mw-license-preview), .mw-upload-editlicenses').remove; // license stuff

// Add container for our form $('#fileform').remove; var container = $(' ').insertAfter('#mw-htmlform-description tr:has(#wpDestFile)').get(0); container.innerHTML = ''; preact.render(			h(App),			container		); }

var defaultConfig = { template: 'File', form: [] };	$.when($.Deferred(function(defer) { mw.hook('dev.preact').add(function(_preact) {			// Assign to our shorthands			preact = _preact;			h = preact.h;			tags = preact.tags;			useState = preact.useState;			useEffect = preact.useEffect;			useReducer = preact.useReducer;

defer.resolve; });	}), $.Deferred(function(defer) {		mw.hook('dev.fetch').add(function(fetch) { fetch({				request: function(resolve, reject) {					var page = 'User:Wiki Barry/test.json';					new mw.Api.get({ formatversion: 2, action: 'query', prop: 'revisions', rvslots: 'main', rvprop: 'content', titles: page }).done(function (d) { if (d.error) reject(console.error(d.error)); if (d.query.pages[0].missing) reject(console.error('FileForm: Config not found at ' + page)); else try { var parsedConfig = JSON.parse(d.query.pages[0].revisions[0].slots.main.content); var config = Object.assign(defaultConfig, parsedConfig); if (!config.form.length) return reject(console.error('FileForm: Empty form config')); resolve(config); } catch(e) { reject(console.error('FileForm: Failed to load config: ' + e)) } }).fail(function(e) { reject(console.error(e)); });				},				name: 'FileForm'			}).then(function(_config) {				config = _config;				defer.resolve;			}); });	})).then(init);

importArticles({		type: 'script',		articles: [			'u:dev:MediaWiki:Preact.js',			'u:dev:MediaWiki:Fetch.js'		]	}); });