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.

//<nowiki>

( function ( $, mw ) {

    if ( mw.config.get( 'wgAction' ) === 'view' &&

         mw.config.get( 'wgPageName' ).indexOf('Wikipedia:Requested_articles') === 0 &&

         mw.config.get( 'wgPageName' ) !== "Wikipedia:Requested_articles" &&

         !$( "#mw-diff-ntitle1" ).length &&

         !$( "#mw-revision-info" ).length ) {

        

        // Load and display form

        mw.loader.using(  "mediawiki.api", "mediawiki.util"  ).then( function () {

            $.getJSON(

                mw.util.wikiScript('api'),

                {

                    format: 'json',

                    action: 'query',

                    prop: 'revisions',

                    rvprop: 'content',

                    rvlimit: 1,

                    titles: "User:Enterprisey/req-helper.js/tpl-panel.js"

                }

            ).done( function ( data ) {

                var pageId = Object.keys(data.query.pages)[0];

                var panelHtml = data.query.pagespageId].revisions0]['*'];

                $( "#jump-to-nav" ).after( panelHtml );

                

                $( "#req-helper-panel input.view-option" ).click( updateRequestActions );

                $( "#req-helper-panel input[type='radio']" ).click( updateRequestDisplay );

                

                // Enable save button if there are requests marked for deletion

                $( "#mw-content-text" ).on( "click", "a.delete-action", updateSaveChangesButton );

                

                // Save handler

                $( "#save-changes" ).click( function ( event ) {

                    $( "#save-changes" ).prop( "disabled", true );

                    editPage( function ( wikitext ) {

                        $( ".marked-for-deletion" ).each( function ( index, element ) {

                            var pageTitle = $( element ).children( "a" ).first().text();

                            wikitext = removeRequest( wikitext, pageTitle );

                        } );

                        return wikitext;

                    } );

                } ); // end save handler

                

                // Mark blue handler

                $( "#mark-bluelinks" ).click( function ( event ) {

                    forEachRequest( function ( element ) {

                        

                        var elemClass = $( element ).attr( "class" );

                        if( $( "#also-mark-redirects" ).is( ":checked" ) ) {

                            if( elemClass !== "mw-redirect" && elemClass ) return;

                        } else {

                            if( elemClass ) return;

                        }

                        

                        if( !$( element ).parent().hasClass( "marked-for-deletion" ) ) {

                            $( element ).parent().addClass( "marked-for-deletion" );

                        }



                        // Ensure that the text of the action link is correct

                        if( $( element ).parent().hasClass( "marked-for-deletion" ) ) {

                            $( element ).parent().find( ".delete-action" ).text( "undelete" );

                        }

                    } );

                    updateSaveChangesButton();

                } ); // end mark handler

                

                // Create action links, initially hidden

                forEachRequest( function ( link ) {

                    $( "<span>" )

                        .insertAfter( link )

                        .addClass( "request-actions" )

                        .css( "margin-left", "0.25em" )

                        .append( $( "<span>", { "text": "( ", "class": "action-parenthesis" } ) )

                        .append( $( "<a>" )

                            .text( "search" )

                            .addClass( "search-action" )

                            .attr( "href", "https://www.google.com/search?q=" + $( link ).text().replace( / /, "+" ) ) )

                        .append( $( "<span>", { "text": " | ", "class": "action-separator" } ) )

                        .append( $( "<a>" )

                            .text( "delete" )

                            .addClass( "delete-action" )

                            .click( function ( e ) {

                                $( link ).parent().toggleClass( "marked-for-deletion" );

                                if( $( this ).text() === "delete" ) {

                                    $( this ).text( "undelete" );

                                } else {

                                    $( this ).text( "delete" );

                                }

                            } ) )

                        .append( $( "<span>", { "text": " )", "class": "action-parenthesis" } ) );

                } ); // end action link creation loop

                

                // Make a style element to be used by updateRequestActions

                $( "#req-helper-panel" ).append( $( "<style>", { "id": "visibility-css" } ) );

                updateRequestActions();

                

                updatePageIssues();

            } ); // end form-loaded handler

        } ); // end mw.loader.using handler

    } // end initial if block



    /**

     * Removes a request with the given page title from the given wikitext.

     * @returns The wikitext, with the specified request removed.

     */

    function removeRequest ( wikitext, pageTitle ) {



        // Sanitize the page title so we can put it in a regex

        // (regex from http://stackoverflow.com/a/3561711)

        pageTitle = pageTitle.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');



        

            "\\*\\s?\\[\\[" + pageTitle + "\\]\\].*?\n",

            "\\*\\s?\\{\\{req\\|" + pageTitle + "\\}\\}.*?\n"

        ].forEach( function ( regex ) {

            regex = new RegExp( regex, "i" );

            wikitext = wikitext.replace( regex, "" );

        } );

        return wikitext;

    }

    

    function updateSaveChangesButton () {

        var numMarkedRequests = $( ".marked-for-deletion" ).length;

        $( "#save-changes" ).prop( "disabled", numMarkedRequests === 0 );

        $( "#save-changes" ).text( numMarkedRequests ? ( "Delete " + numMarkedRequests + " request" + ( ( numMarkedRequests === 1 ) ? "" : "s" ) ) : "Save changes" );

    }

    

    // Takes a callback that takes a *link* object

    function forEachRequest ( callback ) {



        // Precompute a list of navboxes

        var navboxes = arrayFromNodeList( document.getElementsByClassName( "navbox" ) );

        var links = arrayFromNodeList( document.querySelectorAll( "#mw-content-text a" ) );



        for( var i = 0; i < links.length; i++ ) {

            var element = linksi];

            

            // Test to make sure it's an actual request

            if( navboxes.some( function ( navbox ) { return $.contains( navbox, element ); } ) ) continue;

            if( $( element ).children( ".tocnumber" ).length ) continue;

            if( $( element ).parent().prop( "tagName" ) !== "LI" ) continue;

            if( $( element ).parents( "#toc" ).length ) continue;

            if( $( element ).parent().children( "a" ).first().text() !== $( element ).text() ) continue;

            

            // Run callback

            callback( element );

        }

    }

    

    function updateRequestDisplay () {

        var noSourcesAction = $( "input[name=no-sources]:checked" ).val(),

            someSourcesAction = $( "input[name=some-sources]:checked" ).val();

        forEachRequest( function ( link ) {

            // Highlight articles based on # of provided refs

            var listElement = $( link ).parent();

            if( listElement.children( ".external" ).length === 0 ) {

                if( noSourcesAction === "hide" ) {

                    listElement.hide();

                } else {

                    listElement.show();

                    listElement.css( "background-color",  ( $( "input[name=no-sources]:checked" ).val() === "highlight" ) ? "#FEE" : "#FFF" );

                }

            } else {

                if( someSourcesAction === "hide" ) {

                    listElement.hide();

                } else {

                    listElement.show();

                    listElement.css( "background-color",  ( $( "input[name=some-sources]:checked" ).val() === "highlight" ) ? "#EFE" : "#FFF" );

                }

            }

        } );

    }

    

    function updateRequestActions () {

        var showSearch = $( "#show-search-option" ).is( ":checked" ),

            showDelete = $( "#show-delete-option" ).is( ":checked" );

            

        // Make sure we aren't destroying any deletion state

        if( !showDelete && $( ".marked-for-deletion" ).length !== 0 ) {

            if( window.confirm( "You've marked some requests for deletion. " +

				"Are you sure you want to exit mark-for-deletion mode without deleting the requests?" ) ) {

                

                // Wipe deletion state

                $( "a.delete-action" ).text( "delete" );

                $( "li.marked-for-deletion" ).toggleClass( "marked-for-deletion" );

                $( "#save-changes" ).prop( "disabled", true );

            } else {

                

                // The user is indecisive; get out

                $( "#show-delete-option" ).prop( "checked", true );

                return;

            }

        }

        

        var newVisibilityCss = "";

        if( !showSearch && !showDelete ) newVisibilityCss += "span.action-parenthesis{display:none;}";

        if( !showSearch ) newVisibilityCss += "a.search-action{display:none;}";

        if( !showDelete ) newVisibilityCss += "a.delete-action{display:none;}";

        if( !showSearch || !showDelete ) newVisibilityCss += "span.action-separator{display:none;}";

        $( "#visibility-css" ).html( newVisibilityCss );

    }

    

    function updatePageIssues () {

    	$( "#page-issues" ).empty().append( "<ul></ul>" );

    	var addIssue = function ( issue ) { return $( "<li>" ).html( issue ).appendTo( "#page-issues ul" ); };

        $.getJSON(

            mw.util.wikiScript('api'),

            {

                format: 'json',

                action: 'query',

                prop: 'revisions',

                rvprop: 'content',

                rvlimit: 1,

                titles: mw.config.get( 'wgPageName' )

            }

        ).done( function ( data ) {

            var pageId = Object.keys(data.query.pages)[0];

            var wikitext = data.query.pagespageId].revisions0]['*'];

            

            // Regex counter from http://stackoverflow.com/a/4009768

            var refs = ( wikitext.match( /<ref>/g ) || [] ).length;

            if( refs ) {

                addIssue( refs + " &lt;ref&gt; tag" + ( ( refs === 1 ) ? "" : "s" ) );

            }

            

            var noLinkReqs = [];

            forEachRequest( function ( element ) {

            	if(  "<a ", "<i>" ].indexOf( $( element ).parent().html().substring( 0, 3 ) ) === -1 ) {

            	    //console.log( [ "<a>", "<i>" ].indexOf( $( element ).parent().html().substring( 0, 3 ) ) + ", " + $( element ).parent().html().substring( 0, 3 ) );

            		noLinkReqs.push( $( element ).parent().html() );

            	}

            } );

            if( noLinkReqs.length ) {

                addIssue( noLinkReqs.length + " req" + ( ( noLinkReqs.length === 1 ) ? "" : "s" ) + " without a link" )

                    .append( $( "<a>", { "text": "(highlight)", "role": "button", "style": "margin-left: 0.75ch" } )

                        .click( function ( event ) {

                            forEachRequest( function ( element ) {

                                if( noLinkReqs.indexOf( $( element ).parent().html() ) !== -1 ) {

                                	$( element ).parent().css( "background-color", "#FCC" );

                                }

                            } );

                            $( this ).remove();

                        } ) );

            }

            

            var timestamps = ( wikitext.match( /\(UTC\)/g ) || [] ).length;

            if( timestamps ) {

            	addIssue( timestamps + " timestamp" + ( ( timestamps === 1 ) ? "" : "s" ) );

            }

            

            // Set state overall

            if( $( "#page-issues ul li").length ) {

                $( "#page-issues" ).css( "background-color", "#FEE" );

            } else {

                $( "#page-issues" ).css( { "vertical-align": "center",

                                           "text-align": "center" } );

                $( "#page-issues" ).css( "background-color", "#EFE" );

                $( "#page-issues" ).text( "(no issues)" );

            }

        } ); // End get-page-wikitext handler

    }

    

    function editPage ( processWikitext ) {

        $( "#req-helper-panel table").append( "<tr><td colspan=5><ul id='req-status'></ul></td></tr>" );

        var status = function ( newStatus ) { return $( "<li> ").appendTo( "#req-helper-panel ul#req-status" ).text( newStatus ); };



        status( $( ".marked-for-deletion" ).length + " item(s) to delete." );



        var wikitext;

        var getTextStatus = status( "Getting wikitext..." );

        $.getJSON(

            mw.util.wikiScript('api'),

            {

                format: 'json',

                action: 'query',

                prop: 'revisions',

                rvprop: 'content',

                rvlimit: 1,

                titles: mw.config.get( 'wgPageName' )

            }

        ).done( function ( data ) {

            var pageId = Object.keys(data.query.pages)[0];

            var wikitext = data.query.pagespageId].revisions0]['*'];

            getTextStatus.text( "Got wikitext." );

            wikitext = processWikitext( wikitext );

            status( "Processed wikitext." );

            var saveStatus = status( "Saving page..." );

            var plural = ( $( ".marked-for-deletion" ).length === 1 ) ? "" : "s";

            ( new mw.Api() ).postWithEditToken( {

                action: "edit",

                title: mw.config.get( 'wgPageName' ),

                summary: "Removing " + $( ".marked-for-deletion" ).length + " request" + plural + " ([[User:APerson/req-helper|req-helper]])",

                text: wikitext

            } ).done ( function ( data ) {

                if( data && data. && data..result && data..result == 'Success' ) {

                    saveStatus.html( "<b>Saved page!</b> (" )

                        .append( $( "<a>" )

                            .text( "reload" )

                            .attr( "href", "#" )

                            .click( function () { document.location.reload( true ); } ) )

                        .append( ")" );

                } else {

                    saveStatus.text( "There was an error saving the page." );

                    console.log( "Page save result: " + JSON.stringify( data ) );

                }

            } );

        } ); // end get-current-page-wikitext handler

    }



    // Silly utility function, from https://stackoverflow.com/a/5242912/1757964

    function arrayFromNodeList( nl ) {

        var arr = [];

        for ( var i = 0, ref = arr.length = nl.length; i < ref; i++ ) {

            arri = nli];

        }

        return arr;

    }

}( jQuery, mediaWiki ) );

//</nowiki>