User:Nardog/CopySectLink.js

(function copySectLink() {

let dependencies = ['mediawiki.util'];

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 > .minerva-icon{background-color:transparent} .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:var(--background-color-base,#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);

dependencies.push('oojs-ui.styles.icons-editing-advanced');

}

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 = $('').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 = (block, id) => {

let $button = $('').attr({

class: classes + (id ? ' mw-selflink-fragment' : ''),

href: mw.util.getUrl() + (id ? '#' + encodeURI(id): ''),

role: 'button'

}).text('copy').on('click', handler);

if (mw.config.get('skin') === 'minerva') {

$button.attr('title', 'Copy').wrapInner('')

.prepend($('').addClass('minerva-icon oo-ui-icon-copy skin-invert'));

let wrapper = block.querySelector('.mw-editsection');

if (wrapper) {

$button.prependTo(wrapper);

} else {

$button.appendTo(block);

}

} else {

let bracket = block.querySelector('.mw-editsection-bracket:last-child');

if (bracket) {

bracket.before(' | ', $button[0]);

} else {

$('').addClass('mw-editsection').append(

$('').addClass('mw-editsection-bracket').text('['),

$button,

$('').addClass('mw-editsection-bracket').text(']')

).appendTo(block);

}

}

};

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(() => {

if (mw.config.get('wgNamespaceNumber') >= 0) {

addButton(document.getElementById('firstHeading'));

}

mw.hook('wikipage.content').add($content => {

$content.find('.mw-heading > :is(h1, h2, h3, h4, h5, h6)[id]').each(function () {

addButton(this.parentElement, this.id);

});

$content.find(

':is(h1, h2, h3, h4, h5, h6):not(.mw-heading > *, #mw-toc-heading, .wb-sitelinks-heading)[id]'

).each(function () {

addButton(this, this.id);

});

});

});

}());