//<nowiki> 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! (<a href='javascript:window.location.reload(true)' class='reload'>Reload</a>)" );
} 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 = "<input type='text' id='reply-dialog-field' class='mw-ui-input' /><button id='reply-dialog-button' class='mw-ui-button mw-ui-constructive'>Reply</button><span id='reply-dialog-status'></span>";
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 ) );
//</nowiki>