User:Nardog/CopySectLink.js

From Wikipedia, the free encyclopedia
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.
mw.config.get('wgNamespaceNumber') >= 0 &&
(function copySectLink() {
	let classes = 'copysectlink';
	let css;
	switch (mw.config.get('skin')) {
		case 'minerva':
			classes += ' cdx-button cdx-button--size-large cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--icon-only cdx-button--weight-quiet';
			css = '.copysectlink{opacity:0.65;font-size:1rem;margin-right:0 !important} .collapsible-heading:not(.open-block) .copysectlink{visibility:hidden} .copysectlink > span + span{display:block;position:absolute;clip:rect(1px,1px,1px,1px);width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden}';
			break;
		case 'timeless':
			classes += ' mw-ui-icon-copy';
			css = '.copysectlink{background-color:#fff;margin-left:-1em} .copysectlink:first-of-type{margin-left:-20px;padding-left:0} .copysectlink::before{content:"";display:inline-block;width:16px;height:16px;background-size:16px 16px;vertical-align:bottom;opacity:0.33}';
	}
	if (css) mw.loader.addStyleTag(css);
	let handler = function (e) {
		e.preventDefault();
		e.stopPropagation();
		let text = (mw.config.get('wgPageName') + (this.hash ? decodeURI(this.hash).replace(
			/[\[\]{|}]/g,
			s => '&#' + s.codePointAt(0) + ';'
		) : '')).replace(/_/g, ' ');
		let $input = $('<input>').attr({
			type: 'text',
			readonly: '',
			style: 'position:fixed;top:-100%'
		}).val(text).appendTo(document.body);
		$input[0].select();
		let copied;
		try {
			copied = document.execCommand('copy');
		} catch (e) {}
		$input.remove();
		if (copied) {
			mw.notify(`Copied "${text}"`);
		} else {
			mw.notify('Copy failed', { type: 'error' });
		}
	};
	let addButton = function () {
		let hn = this.closest('h1, h2, h3, h4, h5, h6');
		if (!hn || hn.querySelector('.copysectlink')) return;
		let id = this.id || hn.id || $(this).data('id');
		if (!id) return;
		let $button = $('<a>').attr({
			class: classes,
			href: mw.util.getUrl() + (id === 'firstHeading' ? '' : '#' + encodeURI(id)),
			role: 'button'
		}).text('copy').on('click', handler);
		if (mw.config.get('skin') === 'minerva') {
			$button.attr('title', 'Copy').wrapInner('<span>')
				.prepend($('<span>').addClass('minerva-icon oo-ui-icon-copy'));
			let wrapper = hn.querySelector('.mw-editsection');
			if (wrapper) {
				$button.prependTo(wrapper);
			} else {
				$button.appendTo(hn);
			}
		} else {
			let bracket = hn.querySelector('.mw-editsection-bracket:last-child');
			if (bracket) {
				bracket.before(' | ', $button[0]);
			} else {
				$('<span>').addClass('mw-editsection').append(
					$('<span>').addClass('mw-editsection-bracket').text('['),
					$button,
					$('<span>').addClass('mw-editsection-bracket').text(']')
				).appendTo(hn);
			}
		}
	};
	let dependencies = ['mediawiki.util'];
	if (css) dependencies.push('oojs-ui.styles.icons-editing-advanced');
	if (['view', 'purge'].includes(mw.config.get('wgAction'))) {
		['ext.gadget.edittop', 'ext.gadget.edit0'].forEach(m => {
			let state = mw.loader.getState(m);
			if (state && state !== 'registered') dependencies.push(m);
		});
	}
	$.when($.ready, mw.loader.using(dependencies)).then(() => {
		addButton.call(document.getElementById('firstHeading'));
		let selector = '.mw-headline';
		if (mw.config.get('wgNamespaceNumber') === 6 &&
			mw.config.get('wgAction') === 'view'
		) {
			selector += ', h2[id]:not(#mw-toc-heading)';
		}
		mw.hook('wikipage.content').add($content => {
			$content.find(selector).each(addButton);
		});
	});
}());