User:Torty3/test.js

/******************************************************************  Listing Editor v1.4.2 (torty3)

( function ( mw, $ ) {   'use strict';    importStylesheet('Mediawiki:Gadget-ListingEditor.css');

var namespace = mw.config.get( 'wgNamespaceNumber' ); if (namespace != 0 && namespace != 2 && namespace != 4) { return; }   if ( mw.config.get('wgAction') != 'view' || $('#mw-revision-info').length             || $('#mw-diff-ntitle1').length || $('#ca-viewsource').length ) { return; }   var allFields = { 'type': {size:8, right:true, newline:true, parameter:'type', label:'Type', tip:'type of listing' }, 'name': {size:36, right:false, newline:false, parameter:'name', label:'Name', tip:'name of place'}, 'alt': {size:32, right:true, newline:false, parameter:'alt', label:'alt', tip:'also known as'}, 'url': {size:36, right:false, newline:false, parameter:'url', label:'Website', tip:'http://www.example.com'}, 'email': {size:32, right:true, newline:true, parameter:'email', label:'Email', tip:'hello@example.com'}, 'address': {size:36, right:false, newline:false, parameter:'address', label:'Address', tip:'address of place'}, 'lat': {size:10, right:true, newline:false, parameter:'lat', label:'Latitude', tip:'11.11111'}, 'long': {size:10, right:true, newline:false, parameter:'long', label:'Longitude', tip:'111.11111'}, 'directions': {size:36, right:false, newline:true, parameter:'directions', label:'Directions', tip:'how to get here'}, 'phone': {size:24, right:false, newline:false, parameter:'phone', label:'Phone', tip: '+55 555 555-5555'}, 'tollfree': {size:20, right:true, newline:false, parameter:'tollfree', label:'Tollfree', tip:'+1 800 100 1000'}, 'fax': {size:20, right:true, newline:false, parameter:'fax', label:'Fax', tip: '+55 555 555-555'}, 'image': {size:20, right:true, newline:true, parameter:'image', label:'Image', tip: 'image of place'}, 'hours': {size:28, right:false, newline:false, parameter:'hours', label:'Hours', tip: '9AM-5PM or 9:00-17:00'}, 'checkin': {size:12, right:true, newline:false, parameter:'checkin', label:'Check-in', tip: 'check in time'}, 'checkout': {size:12, right:true, newline:false, parameter:'checkout', label:'Check-out', tip: 'check out time'}, 'price': {size:28, right:false, newline:true, parameter:'price', label:'Price', tip: 'entry or service price'}, 'content': {cols:34, rows:8, right:false, newline:true, parameter:'content', label:'Content', tip: 'description of place'} };   var currencySigns = ['\u00A3', '\u20AC', '\u00A5', '\u20A9']; var listingTypes = {'see':'see', 'do':'do', 'buy':'buy', 'eat':'eat', 'drink':'drink', 'sleep':'sleep', 'listing':'listing'}; var sectionHeadings = {'See':'see', 'Do':'do', 'Buy':'buy', 'Eat':'eat', 'Drink':'drink', 'Sleep':'sleep', 'Connect':'listing', 'Wait':'see', 'See_and_Do':'see', 'Eat_and_Drink':'eat'}; var LICENSE_TEXT = 'By clicking "Submit", you agree to the Terms of use, and you irrevocably agree to release your contribution under the CC-BY-SA 3.0 License.' var translateStr = { 'add': 'add listing', 'edit': 'edit', 'closed': 'Closed?', 'saving': 'Saving', 'submit': 'Submit', 'cancel': 'Cancel', 'validationalert': 'Please enter either a name or an address', 'added': 'Added listing for ', 'updated': 'Updated listing for ', 'removed': 'Closed listing for ', 'cities': 'Cities', 'destination': 'Other_destinations', 'geomap': 'locate on geomap', 'help-page': 'http://en.wikivoyage.org/wiki/Wikivoyage:Listing_editor', 'enter-captcha': 'Enter CAPTCHA', 'external-links': 'Your edit includes new external links.' };   var sectionText, listingText, inlineListing; wrapContent; addListingButtons; addEditButtons; // makes it easier to traverse the DOM - but potential for code incompatibility function wrapContent { $('h2').each(function{            $(this).nextUntil("h2").addBack.wrapAll(' ');        }); }   function addListingButtons  { if ($('#'+translateStr['cities']).length || $('#'+translateStr['destination']).length || $('#'+'Islands').length || $('#'+'print-districts').length) { return false; }       var editButton = $(' ') .html(' ['+translateStr['add']+']' ) .click(function {               var listingEntry = $(this).parent;                popupForm('add', listingEntry);            }); for (var key in sectionHeadings) { key = encodeURIComponent(key).replace(/%20/g,'_').replace(/%/g,'.'); $(document.getElementById(key)).parent('h2').addClass('mw-addhere'); $(document.getElementById(key)).closest('div.mw-h2section').children('h3').addClass('mw-addhere'); }       $('.mw-addhere').append(editButton); }   function addEditButtons  { // css included as import stylesheet is too slow var editButton = $('') .html(' '+translateStr['edit']+'' ) .click(function {               var listingEntry = $(this).parent;                popupForm('edit', listingEntry);            }); $('span.vcard').append( editButton ); }   /*** Functions to retrieve entry details ***/ function getIdentifier(entry) { var id = {}; var name = entry.find('.org').text; var address = entry.find('.label').text; var alt = entry.find('.nickname').text; if (name) { id['name'] = name; }       else if (address) { id['address'] = address; }       else { id['alt'] = alt; }       return id; }   function isInline(entry) { if (entry.parent('p').length == 0) return false; return true; }     function findSectionNumber(entry) { var link = entry.find( '.mw-editsection a' ).attr( 'href' ); if (link === undefined) link = entry.closest('div.mw-h2section').find( '.mw-editsection a' ).attr( 'href' ); if (link != undefined) return link.split( '=' ).pop; return 0; }   function findSectionType(entry) { var section = entry.closest('div.mw-h2section').children('h2').find('.mw-headline').attr('id'); for (var key in sectionHeadings) { if (section == key) return sectionHeadings[key]; }       return listingTypes.listing; }   function getSectionText(number) { var wikiText = $.ajax({           url: mw.util.wikiScript(''),            data: { title:wgPageName, action:'raw', section:number },            async: false,            cache: false // required        }).responseText; return wikiText; }     function replaceSpecial( str ) { return str.replace(/([.?*+^$[\]\\{}|-])/g, "\\$1"); }   function getListingWikitextBraces(entry) { sectionText = sectionText.replace(/[^\S\n]+/g,' '); var id = getIdentifier(entry); for (var key in id) break; var search = allFields[key]['parameter']; id[key] = replaceSpecial(id[key]); var listingRegex = new RegExp(search+"\\s?=\\W*?"+id[key]+"\\W*?(\\||}})"); var string = sectionText.match(listingRegex)[0]; var index = sectionText.indexOf(string);

var curly = 2; var str1 = , str2 = ; // search for open and close braces for (var i=index; i>0; i--) { if (sectionText[i]=='}') ++curly; else if (sectionText[i]=='{') --curly; if(curly == 0) { str1 = sectionText.substr(i,index-i); break; }       }        if (string.indexOf('}}') < 0) curly = 2; var textLength = sectionText.length; for (var j=index+string.length; j<textLength; j++) { if (sectionText[j]=='{') ++curly; else if (sectionText[j]=='}') --curly; if (curly == 0) { str2 = sectionText.substr(index, j-index+1); break; }       }        if (str2 === '') str2 = sectionText.substr(index, textLength); string = str1 + str2; return $.trim(string); }   function wikiTextToListing(string) { var typeRegex = new RegExp('{{('+listingTypes['see']+'|'+listingTypes['do'] +'|'+listingTypes['buy'] +'|'+listingTypes['eat'] + '|'+listingTypes['drink'] +'|'+listingTypes['sleep']+'|'+listingTypes['listing']+')','g'); string = string.slice(0,-2); string = string.replace(typeRegex,'{{listing| '+allFields['type']['parameter']+'=$1'); string = string.replace(/{{vCard/g,'{{listing'); var listing = {}; var lastKey; var listParams = string.split('|'); for (var j=1;j 0) { var key = $.trim(param.substr(0, index)); var value = $.trim(param.substr(index+1)); listing[key] = value; lastKey = key; }           else if (listing[lastKey].length) { listing[lastKey] += '|' + param; }       }        return listing; }   function getListing (entry) { listingText = getListingWikitextBraces(entry); var listing = wikiTextToListing(listingText); return listing; }

/*** Functions to handle form creation and editing ***/ function popupForm(mode, entry) { mw.loader.using( ['jquery.ui'], function {        var sectionType, listing;        var sectionNumber = findSectionNumber(entry);        inlineListing = isInline(entry);        sectionText = getSectionText(sectionNumber);        if (mode == 'add') {            sectionType = findSectionType(entry);            listing = {};        }        else {            sectionType = '';            listing = getListing(entry);         }        var form = $(createForm(mode, sectionType, listing));        // modal form - must submit or cancel        form.dialog({ modal: true, height: 'auto', width: 'auto', title: translateStr[mode], buttons: [ {  text: '?', id: 'listing-help', click: function { window.open(translateStr['help-page']);}}, {  text: translateStr['submit'], click: function { if(validateForm) { formToText(mode, sectionNumber); $(this).dialog('close'); }                      }                },                {text: translateStr['cancel'], click: function {$(this).dialog('destroy').remove}} ],           open: function { $('.ui-dialog-buttonpane').append(' '+LICENSE_TEXT+' '); if ($('#input-address').val != '') { $('#geomap-link').attr('href', $('#geomap-link').attr('href') + '&location='                                + encodeURIComponent($('#input-address').val)); }               else if ($('#input-name').val != '') { $('#geomap-link').attr('href', $('#geomap-link').attr('href') + '&location='                                + encodeURIComponent($('#input-name').val)); }                               $('#input-address').change( function  {                    var link = $('#geomap-link').attr('href');                    var index = link.indexOf('&location');                    if (index < 0) index = link.length;                    $('#geomap-link').attr('href', link.substr(0,index) + '&location=' + encodeURIComponent($('#input-address').val));               }); },           close: function { $(this).dialog('destroy').remove} });     });    }    function createForm(mode, type, listing) { var form = $(''); var leftFields = $('').appendTo(form); var rightFields = $('').appendTo(form); $(' ').appendTo(form);

//create form according to fields for (var key in allFields) { var keyvalue = allFields[key]; var node = $(' ') .attr('id', 'div_' + key);

var label = $(' ').appendTo(node) .text(keyvalue['label']) .attr('for', 'input-' + key);

// input text for everything except content which gets textarea var parameter = keyvalue['parameter'];

if (key == 'type') { var subnode = $('').appendTo(node); for (var n in listingTypes) { var option = $(''); option.text(listingTypes[n]).appendTo(subnode); }               if (mode == 'add') { subnode.val(listingTypes[type]); listing[parameter] = listingTypes[type]; }           }            else if (key != 'content') { var subnode = $(' ').appendTo(node) .attr('size', keyvalue['size']); }           else { var subnode = $(' ').appendTo(node) .attr('cols', keyvalue['cols']) .attr('rows', keyvalue['rows']); }

subnode.attr('placeholder', keyvalue['tip']) .attr('id', 'input-' + key);

if (listing[parameter]) { subnode.val(listing[parameter]); }

// customise hiding parameters if (listing[allFields['type']['parameter']] == listingTypes['sleep'] && key == 'hours') node.hide; if (key == 'checkin' || key == 'checkout' || key == 'fax' || key == 'image') node.hide; // some special form features if (key == 'type' && mode == 'edit') { var closedSpan = $(''); var closedLabel = $('<label for="input-closed">').appendTo(closedSpan) .text(translateStr['closed']); var closedInput = $(' ').appendTo(closedSpan) .attr('id', 'input-closed'); node.append(closedSpan); }           if (key == 'price') { var currencySpan = $('<span id="span_currency">'); for (var i=0; i < currencySigns.length; i++) { var currencyButton = $(' ') .html('&#32; <a href="javascript:">'+currencySigns[i]+'</a> ' ) .click(function {                           var caretPos = document.getElementById('input-price').selectionStart;                            var price = $('#input-price').val;                            $('#input-price').val(price.substring(0, caretPos) + $(this).find('a').text + price.substring(caretPos) );                       }); currencySpan.append(currencyButton); }               node.append(currencySpan); }           if (key == 'lat') { var latlngStr = '?'; if ($('#geodata').length) { var latlng = $('#geodata').text.split('; '); latlngStr += 'lat='+latlng[0]+'&lon='+latlng[1]+'&zoom=15'; }               node.append(' <a id="geomap-link" target="_blank" '                    +'href="http://maps.wikivoyage-ev.org/w/geomap.php'+latlngStr+'">'                    +translateStr['geomap']+'</a> '); }

if (key == 'content') { form.append(node); }           else if (allFields[key]['right'] == true) { rightFields.append(node); }           else { leftFields.append(node); }       }        return form; }   function validateForm { //TODO more form validation? if ($('#input-name').val ==  && $('#input-address').val ==  && $('#input-alt').val == '') { alert(translateStr['validationalert']); return false; }       $('#input-content').val($.trim($('#input-content').val).replace(/\n+/g, ' ')); var webRegex = new RegExp('^https?://', 'i'); var url = $('#input-url').val; if (!webRegex.test(url) && url != '') { $('#input-url').val('http://' + url); }       return true; }   function upperCaseFirst(str) { str = str.toLowerCase.replace(/\b[a-z]/g, function(letter) {           return letter.toUpperCase;        }); return str; }   function formToText(mode, number) { var listing = {}; for ( var key in allFields ) { var parameter = allFields[key]['parameter']; listing[parameter]= $("#input-"+key).val; }       if (listing[allFields['type']['parameter']] != listingTypes.sleep) { listing[allFields['checkin']['parameter']] = null; listing[allFields['checkout']['parameter']] = null; }       else { listing[allFields['hours']['parameter']] = null; }       var text = listingToStr(listing); var summary = '/* ' +upperCaseFirst($("#input-type").val) + ' */ '; if (mode == 'add') { summary += translateStr['added']; var index = sectionText.indexOf('==='); if ( index == 0 ) { index = sectionText.indexOf('===='); }           if ( index > 0 ) { sectionText = sectionText.substr(0, index) + '* ' + text + '\n' + sectionText.substr(index); }           else { sectionText += '\n'+ '* ' +text; }       }        else { if ($('#input-closed').is(':checked')) { text = ''; summary += translateStr['removed']; sectionText = sectionText.replace(new RegExp('\\n\\*+\\s?'+listingText), listingText); }           else { summary += translateStr['updated']; }                   sectionText = sectionText.replace(listingText, text); }       summary += $("#input-name").val; saveForm(summary, sectionText, number, , ); return; }   function savingForm { var progress = $(' '+translateStr['saving']+'... '); progress.dialog({           modal: true,            height: 100,            width: 300,            title: '',        }); $(".ui-dialog-titlebar").hide; }     function saveForm(summary, content, number, cid, answer) { $.ajax( {           url: mw.util.wikiScript( 'api' ),            data: {                'format': 'json',                'action': 'edit',                'title': mw.config.get('wgPageName'),                'section': number,                'token': mw.user.tokens.get( 'csrfToken' ),                'text': content,                'summary': summary,                'captchaid': cid,                'captchaword': answer            },            type: 'POST',            datatype: 'json',            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 if ( data && data.edit.spamblacklist ) { alert( 'Error: "'+ data.edit.spamblacklist + '" has been blacklisted' ); $('#progress-dialog').dialog('destroy').remove; } else if ( data && data.edit.captcha ) { var captcha = $(' ').text(translateStr['external-links']); var image = $('<img class="fancycaptcha-image">') .attr('src', data.edit.captcha.url) .appendTo(captcha); var label = $('<label for="input-captcha">').text(translateStr['enter-captcha']).appendTo(captcha); var input = $('<input id="input-captcha" type="text">').appendTo(captcha); captcha.dialog({                       title: translateStr['enter-captcha'],                        buttons: [                            {   text: translateStr['submit'], click: function {                                    saveForm(summary, content, number, data.edit.captcha.id, $('#input-captcha').val);                                    }                            },                            {   text: translateStr['cancel'], click: function {                                    $(this).dialog('destroy').remove;                                    $('#progress-dialog').dialog('destroy').remove;                            }}                        ]                    }); } else { alert( 'Error: Unknown result from API.' ); }           },            error: function( xhr ) { alert( 'Error: Request failed.' ); }       } )        savingForm;    }  function listingToStr(listing) {      var saveStr = '{{'+listing[allFields['type']['parameter']];     if (!inlineListing && allFields['type']['newline']) saveStr += '\n';    for ( var key in allFields ) {        var parameter = allFields[key]['parameter'];        if (key != 'type' && listing[parameter] != null) {            if (inlineListing) {                if (listing[parameter] != ) {                    saveStr += ' | ' + parameter + '=' +listing[parameter];                }            }            else {                if (key != 'image' || listing[allFields['image']['parameter']] != ) {                     saveStr +='| '+parameter+ '=' + listing[parameter];                }                if (allFields[key]['newline']) {                    saveStr += '\n';                }                else {                    saveStr += ' '; }           }        }    }    saveStr += '}}'; return saveStr; } } ( mediaWiki, jQuery ) );