User:Ruud Koot/Listing editor/beta1.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
/* 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 = $( '<a class="vcard-edit-button"> [edit]</a>' ).click( startEditing );
$( '.vcard' ).append( editButton );
}
function removeEditButtons() {
$( '.vcard-edit-button' ).remove()
}
function addSaveButton( entry ) {
var saveButton = $( '<a class="vcard-save-button"> [SAVE!]</a>' ).click( entry, saveTheEdits );
entry.append( saveButton );
}
function addCancelButton( entry ) {
var button = $( '<a class="vcard-cancel-button"> [CANCEL!]</a>' ).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: '[[User:Ruud Koot/Listing editor|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') + '§ion=' + 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, "&" );
}
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() ) + '</' + listingType + '>';
return result;
}
addEditButtons();
} );