Jump to content

User:Novem Linguae/Scripts/VisualEditorEverywhere.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Novem Linguae (talk | contribs) at 11:20, 23 June 2023 (debug). 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.
// <nowiki>

// TODO: fix the race condition. still present as of 08/31/22. got it when clicking from WT:NPPC to WP:NPPC. not consistently reproducible. use mw.hook( 've.activationComplete' )? list of VE hooks: https://codesearch.wmcloud.org/deployed/?q=mw%5C.hook.*%5C.fire&files=&excludeFiles=&repos=mediawiki%2Fextensions%2FVisualEditor
// TODO: add support for [edit] links in diffs
// TODO: space after vedit is accidentally part of the hyperlink, causing an undesired underline
// TODO: extra space before vedit. can delete the space and just rely on the bracket's padding-right

class VisualEditorEverywhere {
	execute() {
		this.articleName = mw.config.get('wgPageName');
		this.articleName = encodeURIComponent(this.articleName); // fix bug involving & not getting converted to &amp;
		let buttonIsPresent = $('#ca-ve-edit').length;
		let pageIsUserScript = this.articleName.match(/(?:\.js|\.css)$/);
		
		if ( ! buttonIsPresent && ! pageIsUserScript ) {
			this.insertVETab();
			this.insertVESectionLink();
		}
	}

	/** Insert Edit tab at top of page */
	insertVETab() {
		let skin = mw.config.get('skin');
		let htmlToInsert;
		switch ( skin ) {
			case 'timeless':
				htmlToInsert =
`<li id="ca-ve-edit" class="mw-list-item" style="display: inline-block">
	<a href="/w/index.php?title=${this.articleName}&amp;veaction=edit" title="Edit this page [alt-shift-v]" accesskey="v">
		<span>VEdit</span>
	</a>
</li>`;
				break;
			case 'vector-2022':
				htmlToInsert =
`<li id="ca-ve-edit" class="vector-tab-noicon mw-list-item">
	<a href="/w/index.php?title=${this.articleName}&amp;veaction=edit" title="Edit this page [alt-shift-v]" accesskey="v">	VEdit</a>
</li>`;
				break;
			case 'modern':
				htmlToInsert =
`<li id="ca-ve-edit" class="collapsible" style="display: block;">
	<a href="/w/index.php?title=${this.articleName}&amp;veaction=edit" title="Edit this page [alt-shift-v]" accesskey="v">	VEdit</a>
</li>`;
				break;
			case 'minerva':
				htmlToInsert =
`<a id="ca-ve-edit" href="/w/index.php?title=${this.articleName}&amp;veaction=edit" class="edit-page menu__item--page-actions-edit mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-edit-base20 mw-ui-icon-with-label-desktop mw-ui-button mw-ui-quiet userlink" data-mw="interface" data-event-name="menu.edit" role="button" title="Edit this page [alt-shift-v]">VEdit</a>`;
				break;
			case 'vector':
			case 'monobook':
			default:
				htmlToInsert =
`<li id="ca-ve-edit" class="collapsible">
	<a href="/w/index.php?title=${this.articleName}&amp;veaction=edit" title="Edit this page [alt-shift-v]" accesskey="v">VEdit</a>
</li>`;
				break;
		}

		$('#ca-edit').before(htmlToInsert);
		$('#ca-ve-edit').show();
	}

	/** Insert [ vedit ] by each section */
	insertVESectionLink() {
		// Foreach edit button
		$('.mw-editsection').each(function() {
			// Generate visual editor section link for this element
			// Credit to Bartosz Dziewoński (WMF) for this fix
			let veEditHref = $(this).find('a').attr('href').replace('&action=edit', '&veaction=edit');

			// Generate HTML to insert
			let htmlToInsert;

			let skin = mw.config.get('skin');
			switch ( skin ) {
				case 'minerva':
					// Generate HTML to insert
					htmlToInsert = `
						<a href="" class="mw-editsection-visualeditor" style="padding-left:1em; font-size:0.6em; font-family:sans-serif;">vedit</a>
					`;

					$(this).prepend(htmlToInsert);
					break;
				default:
					// Generate HTML to insert
					htmlToInsert = `
						<a href="" class="mw-editsection-visualeditor">vedit</a>
						<span class="mw-editsection-divider">|</span>
					`;

					// Insert the HTML right after <span class="mw-editsection"><span class="mw-editsection-bracket">
					// Inline tags such as <span> do not work with :nth-child, .before(), etc. Must use :first-of-type.
					$(this).children('span:first-of-type').after(htmlToInsert);
					break;
			}

			// Inject our generated URL for the edit button
			$(this).find('.mw-editsection-visualeditor').attr('href', veEditHref);
		});

		this.showVEEditLink();
		
		// Doesn't work :(
		// Good test case is https://en.wikipedia.org/wiki/User_talk:Onel5969?useskin=minerva. Ctrl-F5. 25-50% of the time it will not show the vedit section links.
		/*
		// Fixes a race condition. There's some code in core somewhere that hides visual editor links pretty late in the page load process. Sometimes this user script inserts its links before that code runs.
		// TODO: switch from MutationObserver to mw.hook().add(). https://github.com/NovemLinguae/UserScripts/issues/167
		new MutationObserver(() => {
			showVEEditLink();
			console.log('VisualEditorEverywhere: Mutation observer fired. Race condition prevented.');
		}).observe($('.mw-editsection-visualeditor, .mw-editsection-divider')[0], {childList: true});
		*/
	}

	showVEEditLink() {
		$('.mw-editsection-visualeditor, .mw-editsection-divider').show();
	}
}

$(function() {
	let vee = new VisualEditorEverywhere();
	vee.execute();
});

// </nowiki>