User:Ruud Koot/Listing editor/beta1.js

/* KNOWN ISSUES: - not all field are handled yet - cannot edit URLs - 'lat' and 'long' will be lost on save - round-tripping is terribly incomplete - e.g. Wikilinks will be turned into HTML anchors - missing (must have) features - add additional fields to listings - add new listings - does not fail gracefully on errors - does not remove "save" button while saving

mw.loader.using( ['mediawiki.util', 'jquery.client'], function {

var version = 'beta1'

importStylesheet( 'User:Ruud Koot/Listing editor/' + version + '.css' );

var fields = [ 'name', 'alt', 'address', 'directions', 'phone', 'tollfree', 'email', 'fax', 'url', 'hours', 'checkin', 'checkout', 'price', /* 'lat', 'long', */ 'content' ];

var savedEntry     = undefined; /* global? */ var wikiTextSection = undefined; /* global? */ var wikitext        = undefined; /* global? */ var listingType     = undefined; /* global? */

function addEditButtons { var editButton = $( ' [edit]' ).click( startEditing ); $( '.vcard' ).append( editButton ); }

function removeEditButtons { $( '.vcard-edit-button' ).remove }

function addSaveButton( entry ) { var saveButton = $( ' [SAVE!]' ).click( entry, saveTheEdits ); entry.append( saveButton ); }

function addCancelButton( entry ) { var button = $( ' [CANCEL!]' ).click( entry, cancelEditing ); entry.append( button ); }

function startEditing { var entry = $(this).parent;

removeEditButtons;

savedEntry = entry.html; wikitext = theWikitextOfUs( entry );

/* parse into jQuery XML object var jq = $( $.parseXML( ampersandQuote( wikitext ) ) ); alert( jq.find( 'see' ).attr( 'name' ) ); */   addSaveButton( entry ); addCancelButton( entry );

fields.forEach( function ( element, index, array ) {     if (element === 'url') return;      entry.find( '.listing-' + element ).attr( 'contenteditable', true );    } ); }

function saveTheEdits( event ) { var newEntry = serializeListing( event.data ); var newWikitext = wikiTextSection.replace( wikitext, newEntry ); $.ajax({       url: mw.util.wikiScript( 'api' ),        data: {            format: 'json',            action: 'edit',            title: mw.config.get( 'wgPageName' ),            section: theSectionWeAreIn( event.data ),            summary: 'Listing editor (' + version + '): ' + ourIdentifier( event.data ),            text: newWikitext,            token: mw.user.tokens.get( 'csrfToken' )        },        dataType: 'json',        type: 'POST',        success: function( data ) {            if ( data && data.edit && data.edit.result == 'Success' ) {                window.location.reload; // reload page if edit was successful            } else if ( data && data.error ) {                alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );            } else {                alert( 'Error: Unknown result from API.' );            } },       error: function( xhr ) { alert( 'Error: Request failed.' ); }   });  }

function cancelEditing( event ) { event.data.html( savedEntry ); addEditButtons; }

function theSectionWeAreIn( entry ) { return entry.parent.parent.prevAll( 'h2' ).find( '.editsection a' ).attr( 'href' ).split( '=' ).pop; }

function theWikitextOfOurSection( entry ) { var sectionNumber = theSectionWeAreIn( entry ); var wikiText = $.ajax({     type: "GET",      url: '/w/index.php?title=' + mw.config.get('wgPageName') + '&action=raw&oldid=' + mw.config.get('wgCurRevisionId') + '&section=' + sectionNumber,      dataType: 'text',      async: false    }).responseText;

return wikiText; }

function ourIdentifier( entry ) { return entry.find( '.org' ).text }

function theWikitextOfUs( entry ) { var identifier = ourIdentifier( entry ); wikiTextSection = theWikitextOfOurSection( entry ); var regex = new RegExp( "<(see|do|buy|eat|drink|sleep|listing).*" + regexQuote( identifier ) + ".*\\1>" ); var matched = wikiTextSection.match( regex ); var us = matched[0]; listingType = matched[1]

console.log( us ); return us; }

function ampersandQuote( str ) { return str.replace( /&/g, "&amp;" ); }

function regexQuote( str ) { return str.replace(/([.?*+^$[\]\\{}|-])/g, "\\$1"); }

function convertHtmlToWikitext( str ) { return str.replace( /<[/]?i>/ig, "" ).replace( /<[/]?b>/ig, "'"); }

function serializeListing( entry ) { var result = '<' + listingType; fields.slice(0,-1).forEach( function( element, index, array ) {     var value = entry.find( '.listing-' + element ).text;      if ( element === 'url' ) value = entry.find( '.listing-url a' ).attr( 'href' );      if ( value === '' ) return;      result += ' ' + element + '="' + value + '"';    } ); result += '>' + convertHtmlToWikitext( entry.find( '.listing-content' ).html ) + ''; return result; }

addEditButtons;

} );