User:EnterpriseyBot/reply-dialog.js

// foo ( function ( $, mw ) {   var TIMESTAMP_REGEX = /\(UTC\)$/m;

/**    * This function converts any (index-able) iterable into a list. */   function iterableToList( nl ) { var arr = new Array( nl.length ); for(var i=-1,l=nl.length;++i!==l;arr[i]=nl[i]); return arr; }

/**    * When there's a panel being shown, this function sets the status * in the panel. */   function setStatus ( status, callback ) { var statusElement = $( "#reply-dialog-status" ); statusElement.fadeOut( function {            statusElement.html( status ).fadeIn( callback );        } ) }

/**    * Using the text in #reply-dialog-field, add a reply to the * current page. */   function doReply( context, level ) { var wikitext; $.getJSON(           mw.util.wikiScript('api'),            {                format: 'json',                action: 'query',                prop: 'revisions',                rvprop: 'content',                rvlimit: 1,                titles: mw.config.get( 'wgPageName' )            }        ).done( function ( data ) {            try {                var pageId = Object.keys(data.query.pages)[0];                wikitext = data.query.pages[pageId].revisions[0]['*'];                var reply = document.getElementById( "reply-dialog-field" ).value;                var newWikitext = wikitext.replace( context, context + "\n" + ":".repeat( level + 1 ) + reply + " ~" );                setStatus( "Generating wikitext..." );

$.ajax( {                   url: mw.util.wikiScript( 'api' ),                    type: 'POST',                    dataType: 'json',                    data: {                        format: 'json',                        action: 'edit',                        title: mw.config.get( 'wgPageName' ),                        summary: "Replying with reply-dialog (testing)",                        token: mw.user.tokens.get( 'editToken' ),                        text: newWikitext                    }                } ).done ( function ( data ) {                    if ( data && data.edit && data.edit.result && data.edit.result == 'Success' ) {                        setStatus( "Reply saved! (Reload)" );                    } else {                        setStatus( "While saving, the edit query returned an error. =(" ); }               } ).fail ( function { setStatus( "While saving, the AJAX request failed." ); } );           } catch ( e ) {                setStatus( "While getting the wikitext, there was an error." );               console.log( "Content request error: " + e.message );                console.log( "Content request response: " + JSON.stringify( data ) );            }        } ).fail( function  {            setStatus( "While getting the wikitext, there was an AJAX error." );       } );    }

/**    * Adds a "(reply)" link after the provided text node. */   function attachLinkAfterTextNode( node, level ) {

// Verify that this text node ends with a timestamp if( !TIMESTAMP_REGEX.test( node.textContent ) ) return;

// Construct new link var newLinkWrapper = document.createElement( "span" ); newLinkWrapper.className = "reply-dialog-wrapper"; var newLink = document.createElement( "a" ); newLink.href = "#"; newLink.appendChild( document.createTextNode( "reply" ) ); newLink.addEventListener( "click", function ( evt ) {

// Create panel var panelEl = document.createElement( "div" ); panelEl.style = "border: thin gray solid; padding: 5px; box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);"; panelEl.innerHTML = "Reply "; node.parentNode.insertBefore( panelEl, newLinkWrapper.nextSibling );

// Button event listener document.getElementById( "reply-dialog-button" ) .addEventListener( "click", function { doReply( node.textContent, level ); } );

// Cancel default event handler evt.preventDefault; return false; } );       newLinkWrapper.appendChild( document.createTextNode( "(" ) ); newLinkWrapper.appendChild( newLink ); newLinkWrapper.appendChild( document.createTextNode( ")" ) );

// Insert new link into DOM var parent = node.parentNode; parent.insertBefore( newLinkWrapper, node.nextSibling ); }

/**    * Uses attachLinkAfterTextNode to add a reply link after every * timestamp on the page. */   function attachLinks  { var mainContent = document.querySelector( "#mw-content-text .mw-parser-output" ); var contentEls = mainContent.children;

// Loop until we get a header var headerIndex = 0; for( headerIndex = 0; headerIndex < contentEls.length; headerIndex++ ) { if( contentEls[ headerIndex ].tagName.toLowerCase === "h2" ) break; }

if( headerIndex === contentEls.length ) { console.log( "Hit end of loop!" ); return; }

// Main recursive parsing function function parseNode( node, currLevel ) {

// Detect if it's a text node if( node.nodeType === 3 ) { attachLinkAfterTextNode( node, currLevel ); return; } else if( /p|dl|dd|ul|li/.test( node.tagName.toLowerCase ) ) { if( /dl|ul/.test( node.tagName.toLowerCase ) ) { currLevel++; }               iterableToList( node.childNodes ).map( function( node ) {                    parseNode( node, currLevel );                } ); }       }

contentEls = iterableToList( contentEls ).slice( headerIndex + 1); contentEls.map( function ( el ) { parseNode( el, 0 ); } ); }

function onReady { attachLinks; }

var currNamespace = mw.config.get( "wgNamespaceNumber" ); if ( currNamespace % 2 === 1 || currNamespace === 4 ) { mw.loader.load( "mediawiki.ui.input", "text/css" ); mw.loader.using( "mediawiki.util" ).then( function {            $( document ).ready( onReady );        } ); } }( jQuery, mediaWiki ) ); //