User:Andrybak/Scripts/copy-section-link.js

// Fixed version of User:Enterprisey/copy-section-link.js // $.when(   $.ready,    mw.loader.using( [ "mediawiki.util", "oojs-ui-core", "oojs-ui-widgets" ] ) ).then( function  {	/*	 * The convoluted function is needed, because there are different HTML	 * layouts for "headings" in different skins.	 * In Vector 2022, layout of ==Second level== versus ===Third level===	 * headings is different even for a _single_ skin.	 *	 * The HTML layout is either	 *     	 * or	 *     	 *	 * For details, see:	 *   - https://www.mediawiki.org/w/index.php?title=Heading_HTML_changes&oldid=6538029	 */	// Returns a plain HTMLElement	function findEditSectionForHeader(header) {		// in Vector, the bracketed [edit] section link is a direct child element/node		const maybeVectorEditSection = header.querySelector('.mw-editsection');		if (maybeVectorEditSection) {			return maybeVectorEditSection;		}		// in other skins, the bracketed [edit] section link is a sibling of  etc if (header.parentElement.classList.contains('mw-heading')) { const maybeEditSection = header.parentElement.querySelector('.mw-editsection'); if (maybeEditSection) { return maybeEditSection; }		}		return null; }	/*	 * The search for all section headings starts with * finding all  tags, which aren't for the table of contents. * From the  tags, we find the "[edit] section links". */	const allHeaders = $("#mw-content-text .mw-parser-output").find(":header").filter(':not(#mw-toc-heading)');

allHeaders.each( function(i, header) {       var popup = null;        var editSection = findEditSectionForHeader(header);        let target;        if (editSection === null) {        	target = $(header);        	console.warn('[copy-section-link]', 'edit section link not found:', target);        } else {        	target = $(editSection);        }        target.append($( "", { "class": "copy-section-link-pilcrow" } ) .text( "¶" ) .click( function {                    if( popup === null ) {                        const hash = header.id ? header.id : header.querySelector('.mw-headline')?.id;                        var oldid = mw.util.getParamValue( "oldid" );                        var popupContent;                        function makeContent( pageName, id ) {                            var wikitext = (pageName + "#" + hash).replace( /_/g, " " );                            if( !window.copySectionLinkNoSquareBrackets ) {                               wikitext =  + wikitext + ;                            }                            return $( ' ', { "class": "copy-section-link-content" } ).append( $( " ", { "id": "copy-section-wikilink" + id } ).text( wikitext ), $( " " )                                   .text( "Copy" ) .css( { "padding": "0.5em", "cursor": "pointer", "margin-left": "0.5em" } ) .click( function {                                        var textField = $( this ).prev;                                        try {                                            navigator.clipboard.writeText( textField.text );                                        } catch( e ) {                                            textField.select;                                            document.execCommand( "copy" );                                        }                                    } ), $( " " ),                               $( "" ) .attr( "href", mw.util.getUrl( pageName ) + "#" + encodeURIComponent( hash ) ) .text( "external" ) );                       }

var generalCss = { 'font-size': '0.9rem', 'font-family': 'sans-serif' };

var index; if( oldid ) { popupContent = makeContent( "Special:Permalink/" + oldid ); popupContent.css( generalCss ); popupContent.css( { 'padding-top': '0.5em', 'font-weight': 'normal' } ); } else { var normalPanel = new OO.ui.TabPanelLayout( 'normal', {                               label: 'Link',                                $content: makeContent( mw.config.get( 'wgPageName' ), 'normal' )                            } ); var permalinkPanel = new OO.ui.TabPanelLayout( 'permalink', {                               label: 'Permalink',                                $content: makeContent( 'Special:Permalink/' + mw.config.get( 'wgCurRevisionId' ), 'permalink' )                            } ); index = new OO.ui.IndexLayout; index.addTabPanels( [ normalPanel, permalinkPanel ] ); popupContent = index.$element; }                       popup = new OO.ui.PopupWidget( {                            $content: popupContent,                            $floatableContainer: $( this ),                            padded: true,                            width: 400,                            height: 190,                            align: 'forwards',                        } ); $( this ).after( popup.$element ); if( index ) { index.$menu.find( 'span.oo-ui-labelElement-label' ).css( generalCss ); index.$content.css( generalCss ); }

popup.toggle( true ); } else { popup.toggle; }               } ) );    } );    mw.util.addCSS( ".copy-section-link-pilcrow" + "{ display: none; margin-left: 1em; font-size: initial; }" + ".mw-heading:hover .copy-section-link-pilcrow, " + "h1:hover .copy-section-link-pilcrow, h2:hover .copy-section-link-pilcrow, h3:hover .copy-section-link-pilcrow," + "h4:hover .copy-section-link-pilcrow, h5:hover .copy-section-link-pilcrow, h6:hover .copy-section-link-pilcrow" + "{ display: inline; }" + ".copy-section-link-pilcrow + .oo-ui-widget" + "{ font-weight: normal; }" ); } ); //