Jump to content

User:Nardog/CodeEditorAssist.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Nardog (talk | contribs) at 13:48, 11 October 2020. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
$(function codeEditorAssist() {
	let isEdit = ['edit', 'submit'].includes(mw.config.get('wgAction'));
	let handleEditor = editor => {
		isEdit && mw.loader.using(['ext.wikiEditor', 'oojs-ui.styles.icons-interactions'], () => {
			$('#wpTextbox1').wikiEditor('addToToolbar', {
				section: 'main',
				group: 'codeeditor-style',
				tools: {
					'codeeditor-settings': {
						label: 'Open code editor settings',
						type: 'button',
						oouiIcon: 'settings',
						action: {
							type: 'callback',
							execute: () => {
								editor.execCommand('showSettingsMenu');
							}
						}
					}
				}
			});
		});
		
		let defSettings;
		let getSettings = () => {
			let settings = editor.getOptions();
			delete settings.mode;
			delete settings.readOnly;
			Object.keys(settings).forEach(k => {
				if (settings[k] === undefined) settings[k] = null;
				if (defSettings && k !== 'showInvisibles' && k !== 'wrap' && settings[k] === defSettings[k])
					delete settings[k];
			});
			return settings;
		};
		defSettings = getSettings();
		defSettings.showInvisibles = false;
		defSettings.wrap = 'off';
		
		let invisiblesBtn = isEdit && document.querySelector('.group-codeeditor-style > [rel="invisibleChars"]');
		let wrapBtn = isEdit && document.querySelector('.group-codeeditor-style > [rel="lineWrapping"]');
		let turnButton = (button, turnsOn) => {
			if (button && button.classList.contains('oo-ui-toggleWidget-' + (turnsOn ? 'off' : 'on')))
				button.firstElementChild.click();
		};
		
		let savedSettings = mw.user.options.get('userjs-codeeditorassist-settings');
		if (savedSettings) {
			savedSettings = JSON.parse(savedSettings);
			turnButton(invisiblesBtn, savedSettings.showInvisibles);
			turnButton(wrapBtn, savedSettings.wrap && savedSettings.wrap !== 'off');
			editor.setOptions(savedSettings);
		}
		
		let api;
		let saveRemoveSettings = (button, isRemoval) => {
			button.disabled = true;
			mw.loader.using('mediawiki.api', () => {
				if (!api) api = new mw.Api();
				api.postWithEditToken({
					action: 'globalpreferences',
					// Removing the option somehow doesn't work, so empty it for now (T207448)
					change: 'userjs-codeeditorassist-settings=' + (isRemoval ? '' : JSON.stringify(getSettings()))
				}).always(response => {
					if (response && response.globalpreferences === 'success') {
						mw.notify(isRemoval
							? 'Removed settings from your global preferences'
							: 'Saved settings to your global preferences'
						);
					} else {
						mw.notify(isRemoval
							? 'Couldn\'t remove settings from your global preferences'
							: 'Couldn\'t save settings to your global preferences',
						{ type: 'error' });
					}
					button.disabled = false;
				});
			});
		};
		
		let $buttons = $('<div class="floatright"></div>')
			.append('<input type="submit" value="Save"> <input type="submit" value="Remove"> <input type="submit" value="Reset">');
		
		$buttons.on('click', 'input', e => {
			if (e.target.value === 'Reset') {
				turnButton(invisiblesBtn);
				turnButton(wrapBtn);
				editor.setOptions(defSettings);
				$('#ace_settingsmenu').parent().detach();
				editor.execCommand('showSettingsMenu');
			} else {
				saveRemoveSettings(e.target, e.target.value === 'Remove');
			}
		});
		
		(new MutationObserver(() => {
			$buttons.appendTo('#ace_settingsmenu > table > tr:last-child > td');
		})).observe(document.body, { childList: true });
	};
	
	let filterEditor = !isEdit && document.querySelector('#wpAceFilterEditor');
	if (isEdit && mw.config.get('wgCodeEditorCurrentLanguage') || filterEditor) {
		let editor;
		let waitForEditor = () => {
			if (!editor) editor = filterEditor || document.querySelector('.ace_editor');
			if (editor && window.ace) {
				mw.loader.using('mediawiki.user', () => {
					handleEditor(ace.edit(editor));
				});
				return true;
			}
		};
		if (!waitForEditor()) {
			let observer = new MutationObserver(() => {
				waitForEditor() && observer.disconnect();
			});
			observer.observe(document.head, { childList: true });
		}
	}
});