User:Fred Gandt/controlSiteWidth.js

$( document ).ready( => {	"use strict";	const CSW_TOOLBOX_LI = mw.util.addPortletLink( "p-tb", "#", "Control site width", "Control site width and alignment" ),		MW_HEAD = document.getElementById( "mw-head" ),		USER_NAME = mw.config.get( "wgUserName" ),		USER_CSW_CSS_TITLE = `User:${USER_NAME}/controlSiteWidth.css`,		SCRIPT_TITLE = "User:Fred Gandt/controlSiteWidth.js",		USER_OPTION_NAME = "userjs-fg-control-site-width",		cE = element => document.createElement( element ),		CSW_ALIGN_FIELDSET_LEGEND = cE( "legend" ),		CSW_ALIGN_FIELDSET = cE( "fieldset" ),		CSW_COLOR = cE( "input" ),		CSW_WIDTH = cE( "input" ),		CSW_SAVE = cE( "input" ),		CSW_FORM = cE( "form" ),		BODY = document.body,		label = ( npt, txt, disp ) => {			const LABEL = cE( "label" );			LABEL.textContent = txt;			LABEL.style.display = disp || "block";			LABEL.append( npt );			return LABEL;		},		radio = val => {			const RADIO = cE( "input" ); RADIO.type = "radio"; RADIO.name = "align"; RADIO.value = val[ 1 ]; RADIO.checked = user_options.align === val[ 1 ]; RADIO.style.marginRight = ".5em"; return label( RADIO, `${val[ 0 ]} ` ); },		getFormValues = => ( {			width: CSW_WIDTH.value,			color: CSW_COLOR.value,			align: CSW_FORM.align.value		} ), api = ( data, fnc ) => { data.format = "json"; $.ajax( {				type: "POST",				url: "/w/api.php",				dataType: data.format,				data: data,				success: data => fnc( data ),				error: data => console.error( data ) // TODO: inform the user			} ); },		api_editCSWCSS = => { api( {				action: "edit",				title: USER_CSW_CSS_TITLE,				text: `#mw-panel { background-color: #f6f6f6; width: 11em; left: unset; padding: 0 } body { background-color: ${user_options.color}; margin: ${user_options.align} } body, #mw-head { max-width: ${user_options.width}px }				contentformat: "text/css",				contentmodel: "css",				notminor: "1",				recreate: "1",				summary: `semi-automated edit to establish rules in accordance with user settings derived by ${SCRIPT_TITLE}`,				token: mw.user.tokens.values.csrfToken			}, data => console.warn( "TODO: inform the user" ) ); };	let user_options = mw.user.options.values[ USER_OPTION_NAME ]; if ( user_options ) { user_options = JSON.parse( user_options ); } else { if ( !confirm( `The script "${SCRIPT_TITLE}" needs to edit your common.css; allow it?` ) ) { return; }		user_options = { width: innerWidth, color: "#f6f6f6", align: "center" }; api( {			action: "edit",			title: `User:${USER_NAME}/common.css`,			appendtext: ` /* Due to the way Cascading Style Sheets work; this import should be maintained at the end of this stylesheet */ @import url( "/w/index.php?title=User:${mw.util.wikiUrlencode( USER_NAME )}/controlSiteWidth.css&action=raw&ctype=text/css" );`,			contentformat: "text/css",			contentmodel: "css",			notminor: "1",			recreate: "1",			summary: `semi-automated edit adding import of rules in accordance with user settings derived by ${SCRIPT_TITLE}`,			token: mw.user.tokens.values.csrfToken		}, data => {			api_editCSWCSS;			console.warn( "TODO: inform the user" );		} ); }	CSW_WIDTH.style.width = "8ch"; CSW_WIDTH.value = user_options.width; CSW_WIDTH.type = "number"; CSW_ALIGN_FIELDSET_LEGEND.textContent = "Align"; CSW_ALIGN_FIELDSET.style.borderColor = "#a7d7f9"; CSW_ALIGN_FIELDSET.style.paddingBottom = ".5em"; CSW_ALIGN_FIELDSET.style.margin = "0 0 .5em"; CSW_ALIGN_FIELDSET.append( CSW_ALIGN_FIELDSET_LEGEND, ...[		[ "Left", "0 auto 0 0" ],		[ "Center", "0 auto" ],		[ "Right", "0 0 0 auto" ]	].map( val => radio( val ) ) ); CSW_COLOR.value = user_options.color; CSW_COLOR.type = "color"; CSW_SAVE.style.marginLeft = "1em"; CSW_SAVE.type = "button"; CSW_SAVE.disabled = true; CSW_SAVE.value = "Save"; CSW_FORM.setAttribute( "style", "display: none; border: 1px solid #a7d7f9; margin-top: .5em; padding: .5em;" ); CSW_FORM.append( label( CSW_WIDTH, "Width in pixels" ), CSW_ALIGN_FIELDSET, label( CSW_COLOR, "Background color", "inline" ), CSW_SAVE ); CSW_TOOLBOX_LI.firstElementChild.addEventListener( "click", evt => {		evt.preventDefault;		const CSW_FORM_DISPLAYED = CSW_FORM.style.display === "block";		CSW_FORM.style.display = CSW_FORM_DISPLAYED ? "none" : "block";	} ); CSW_SAVE.addEventListener( "click", => {		if ( confirm( `Saving these settings will initiate an edit on your user page ${USER_CSW_CSS_TITLE}; continue?` ) ) {			Object.assign( user_options, getFormValues );			CSW_SAVE.disabled = true;			api( { action: "options", optionname: USER_OPTION_NAME, optionvalue: JSON.stringify( user_options ), token: mw.user.tokens.values.csrfToken }, data => { if ( data.options && data.options === "success" ) { CSW_FORM.style.display = "none"; } else { console.warn( "TODO: inform the user" ); }			} );			api_editCSWCSS;		}	}, { passive: true } ); CSW_FORM.addEventListener( "input", evt => {		const FV = getFormValues;		CSW_SAVE.disabled = ( FV.width === user_options.width && FV.color === user_options.color && FV.align === user_options.align );		BODY.style.maxWidth = MW_HEAD.style.maxWidth = `${FV.width}px`;		BODY.style.backgroundColor = FV.color;		BODY.style.margin = FV.align;	} ); CSW_TOOLBOX_LI.append( CSW_FORM ); } );
 * 1) footer { background-color: #f6f6f6; padding: 1em 1em 3em }
 * 1) mw-head { right: unset }`,