AtlasTools.js

Revision as of 01:21, 24 September 2016 by BrianFreud (talk | contribs) (Created page with "→‎jshint esversion: 6, bitwise: false: →‎globals stratics, mw, jQuery: →‎Init: (function ($) { "use strict"; $('#editlocation').append('<input type="button" value=...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Note: After saving, 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: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/* jshint esversion: 6, bitwise: false */
/* globals stratics, mw, jQuery */

/* Init */
(function ($) {
 "use strict";

$('#editlocation').append('<input type="button" value="Click to select a pin to edit" id="pinSelect"/><div id="pinEditDiv">')
    .find('.pinEditCancel, .pinEditStore, .pinEditSubmit')
    .invis()
    .add('#pinSelect')
    .button();

var nbsp = '&nbsp;';
var br = '<br>';

/* Create a large box for directions in the bottom left corner */
stratics.f.util.$makeDirections = () => {
    return $('<div>', {
        'class': 'largeFloatingInstructions',
        id: 'instructionBox'
    }).appendTo('body');
};

/* Destroys the large box for directions in the bottom left corner */
stratics.f.util.removeDirections = () => {
    return $('#instructionBox').remove();
};

/* Empties the edit pin tab, resetting it back to initial state */
stratics.f.atlas.ui.resetEditPin = () => {
    $('#pinSelect, #pinEditDiv').show();
    $('.pinEditCancel, .pinEditStore').invis();
    $('#toolmenu').tabs('enable');
    return $('#pinEditDiv').empty();
};

/* Event handler for markup AJAX request */
$('body').on('markupArrived', function () {
    let wiki = stratics.wiki,
        marker = 'ADD LOCATIONS HERE.  DO NOT MODIFY ABOVE THIS LINE.';
    var markup = stratics.wiki.markup;

    $('#toolmenu').dialog('close');
    stratics.f.util.$makeDirections().html('Submitting edits, please wait...');

    if (markup.length > 0 && wiki.openEdits.length > 0) {
        let edits = wiki.openEdits;
        for (let edit of edits) {
            if (Array.isArray(edit)) { // Pin edit
                markup = markup.replace(edit[0], edit[1]);
            } else if ('string' === typeof edit) { // Pin addition
                markup = markup.replace(marker, marker + '\n' + edit);
            }
        }
    }

    stratics.wiki.markup = markup;
    stratics.f.wiki.submitMarkup('[Pin Editor]: Edits to ' + wiki.openEdits.length + ' pins.', stratics.wiki.markup); // Asynch
    wiki.openEdits = [];
    stratics.wiki.markup = '';
});

/* Submits a markup edit to the server */
stratics.f.wiki.submitMarkup = function (summary, content) {
    stratics.f.wiki.api.postWithToken("edit", {
        action: "edit",
        title: mw.config.get("wgPageName"),
        summary: summary,
        text: content
    }).done(function (result, jqXHR) {
        mw.log("Saved successfully");
        $('#instructionBox').html('Edits saved.  Reloading the page.');
        stratics.f.util.reloadPage();
    }).fail(function (code, result) {
        if (code === "http") {
            mw.log("HTTP error: " + result.textStatus); // result.xhr contains the jqXHR object
        } else if (code === "ok-but-empty") {
            mw.log("Got an empty response from the server");
        } else {
            mw.log("API error: " + code);
        }
        $('#instructionBox').html('An error occurred.<br>Please try again.');
    });
};

/* Retrieves the wiki markup for a page; defaults to the current page. */
stratics.f.wiki.getMarkup = (page) => {
    var getPage = (callback, page) => {
        $.get('http://stratics.com/w/api.php?action=query&prop=revisions&rvprop=content&format=json&formatversion=2&titles=' + page, (data) => {
            callback.apply(data);
        });
    };
    getPage(function () {
        stratics.wiki.markup = this.query.pages[0].revisions[0].content;
        $('body').trigger('markupArrived');
    }, page || mw.config.get("wgPageName"));
};

/* Creates a string of markup with data for a single pin */
stratics.f.wiki.buildPinMarkup = (data) => {
    let retval = '-->{{UOAddPin|' + [data.type.replace('_',' '), data.x, data.y, data.name].join('|');
    if (data.hasOwnProperty('page') && undefined !== data.page && data.page.length > 0) {
        retval += '|link=' + data.page;
    }
    return retval + '}}<!--';
};

/* Reset a pin to its original location */
stratics.f.wiki.setPinCoordsOrig = ($pin) => {
    let [x, y] = $pin.attr('id').split(':'),
        offset = {
            x: ~~$pin.attr('data-offsetX'),
            y: ~~$pin.attr('data-offsetY')
        };

    $pin.css({
        left: (~~x - offset.x) + 'px',
        top: (~~y - offset.y) + 'px'
    });  
};

/* Gets the original markup for a pin */
stratics.f.wiki.getPinMarkupOrig = (data) => {
    let info = $('#editlocation').data('selection').attr('id').split(':');

    return stratics.f.wiki.buildPinMarkup({
        x: info[0],
        y: info[1],
        type: info[2],
        name: $('#editName').data('initial'),
        page: $('#editPage').data('initial')
    });
};

/* Gets the new markup for a pin on the edit tab */
stratics.f.wiki.getPinMarkupEdit = (data) => {
    return stratics.f.wiki.buildPinMarkup({
        x: $('#editX').val(),
        y: $('#editY').val(),
        type: $('#editType').val(),
        name: $('#editName').val(),
        page: $('#editPage').val()
    });
};

/* Gets the new markup for a pin on the add tab */
stratics.f.wiki.getPinMarkupAdd = (data) => {
    let info = $('#getloccoords').split(' x ');

    return stratics.f.wiki.buildPinMarkup({
        x: info[0],
        y: info[1],
        type: $('#getlocselect').val(),
        name: $('#getlocdescription').val(),
        page: $('#getlocwikipage').val()
    });
};

/* Allows the keyboard to be used to control the arrow buttons on the edit pin tab. */
stratics.f.atlas.movePinByKey = e => {
    var key = stratics.keycodes[e.which] || false;
    if (!!key && e.which > 32 && e.which < 41) {
        e.preventDefault();
        e.stopPropagation();
    }
    $('#arrow' + key).trigger('click');
};

/* Handles a change to a pin's location on the X axis */
stratics.f.atlas.changePinX = function (amount) {
    var $pin = stratics.f.atlas.changePinInput($('#editX'), amount);
    var left = parseInt($pin.css('left'), 10);
    $pin.css('left', ~~left + ~~amount);
    return;
};

/* Handles a change to a pin's location on the Y axis */
stratics.f.atlas.changePinY = function (amount) {
    var $pin = stratics.f.atlas.changePinInput($('#editY'), amount);
    var top = parseInt($pin.css('top'), 10);
    $pin.css('top', ~~top + ~~amount);
    return;
};

/* Utility function to change the value in an pin location input. */
/* Returns a jQuery-wrapped element which is the pin on the map. */
stratics.f.atlas.changePinInput = function ($pin, amount) {
    var val = $pin.val();
    $pin.val(~~val + ~~amount);
    return $('#editlocation').data('selection');
};

/* Populate the Edit location tab when a location is selected. */
$('#editlocation').on('pinSelected', function (e) {
    let $pin = $(e.target).data('selection'),
        makehtml = stratics.f.util.makehtml;
    let info = $pin.attr('id').split(':'),
        arrowBtn = (value, id) => {
            return makehtml('input', {
                id: 'arrow' + id,
                type: 'button',
                style: "width:2em;height:2em;opacity:.8;",
                value
            });
    };

    $('#pinSelect').attr('value', 'Click to select another pin to edit')
        .hide();
    $('#pinEditDiv').empty()
        .append([
            br,
            $pin.html(),
            nbsp,
            $('<input>', {
                id: 'editName',
                style: 'width:30em;',
                type: 'text',
                value: $pin.attr('data-name')
            }).data('initial', $pin.attr('data-name')),
            $('<div>', {id:'arrowControls', style:'float:right;'}).append([
                arrowBtn('🡼','NW'),
                arrowBtn('🡹','N'),
                arrowBtn('🡽','NE'),
                br,
                arrowBtn('🡸','W'),
                $('<span>', {style:'vertical-align: bottom;display:inline-block;width:2em;height:2em;'}),
                arrowBtn('🡺','E'),
                br,
                arrowBtn('🡿','SW'),
                arrowBtn('🡻','S'),
                arrowBtn('🡾','SE')
            ]),
            br, br,
            'Location: ',
            '<label>x:' + makehtml('input', {
                id: 'editX',
                style: 'width:6em;margin-left:5px;margin-right:10px;',
                type: 'number',
                value: info[0]
            }) + '</label>',
            $('<label>y:' + makehtml('input', {
                id: 'editY',
                style: 'width:6em;margin-left:5px;margin-right:10px;',
                type: 'number',
                value: info[1]
            }) + '</label>').data('initial', info[2]),
            $('#getlocselect').clone()
            .attr('id', 'editType')
            .val(info[2].replace(/_/g, ' '))
            .data('initial', info[2]),
            br, br,
            '<label>Wikipage: ' + makehtml('input', {
                id: 'editPage',
                style: 'width:28em;',
                type: 'text',
                value: $pin.attr('data-page') || ''
            }) + '</label>',
        ])
        .find('img')
        .attr('id', 'editImage');

    $('#editX').data('initial', info[0]);
    $('#editY').data('initial', info[1]);
    $('#editPage').data('initial', $pin.attr('data-page'));

    /* Start: Move pin click handlers */
    let setArrowClick = (dir, x, y) => {
        $('#arrow' + dir).click(() => {
            if (!!x) stratics.f.atlas.changePinX(x);
            if (!!y) stratics.f.atlas.changePinY(y);
        });
    };
    setArrowClick('N', 0, -1);
    setArrowClick('W', -1, 0);
    setArrowClick('S', 0, 1);
    setArrowClick('E', 1, 0);
    setArrowClick('NW', -1, -1);
    setArrowClick('SW', -1, 1);
    setArrowClick('NE', 1, -1);
    setArrowClick('SE', 1, 1);
    /* End: Move pin click handlers */

    /* Handlers for changes directly to the x and y inputs */
    $('#editX, #editY').on('change, keyup input mousewheel', () => {
        let $pin = $('#editlocation').data('selection');
        let offset = {
            x: ~~$pin.attr('data-offsetX'),
            y: ~~$pin.attr('data-offsetY')
        };

        $pin.css({
            left: (~~$('#editX').val() - offset.x) + 'px',
            top: (~~$('#editY').val() - offset.y) + 'px'
        });
    });

    /* Pin-type change handler */
    $('#editType').change(() => {
        $('#editlocation').data('selection')
            .add('#editImage')
            .each(() => {
                let classes = $(this).attr('class'),
                    newClass = 'icon-' + $('#editType').val().replace(/\s/g, '_');
                $(this).attr('class', classes.replace(/icon\-\S+/, newClass));
            });
    });

    /* Enable keyboard movement of pins */
    $('body').on('keydown.pinselect', function (e) {
        if (!$(e.target).is('#editName, #editX, #editY, #editType')) {
            stratics.f.atlas.movePinByKey(e);
        }
    });

    $('#toolmenu').tabs('disable')
        .dialog('open');
});

/* Turns off pin-selection mode */
stratics.f.atlas.ui.disablePinSelectionMode = (e) => {
    e.preventDefault();
    $('.map-holder').css('cursor','default');
    $('body').off('keyup.checkEscape');
    $('span.pin').off('click.pinSelect');
    stratics.f.util.removeDirections();
    $('.menutrigger').show();
};

/* Handler for the "select a pin to edit" button */
$('#pinSelect').click(function () {
    /* Turns on pin-selection mode */
    $('#toolmenu').dialog('close');
    $('.map-holder').css('cursor','pointer');
    $('.menutrigger').hide();
    stratics.f.util.$makeDirections().html('Click on a pin on the map to select it.<br/>Hit the escape key to cancel.');

    $('body').trigger('focus');

    /* Handler for ESC being pressed */
    $('body').on('keyup.checkEscape', function (e) {
        if (e.which === 27) {
            stratics.f.atlas.ui.disablePinSelectionMode(e);
            stratics.f.atlas.ui.resetEditPin();
            $('#toolmenu').dialog('open');
        }
    });

    /* Handler for a click on a pin */
    $('span.pin').on('click.pinSelect', function (e) {
        stratics.f.atlas.ui.disablePinSelectionMode(e);
        $('.pinEditCancel, .pinEditStore', '#editlocation').vis();
        $('#editlocation').data('selection', $(this))
            .trigger('pinSelected');
    });
});

/* Handler for the "cancel editing pin" button */
$('#editlocation').on('click', '.pinEditCancel', () => {
    stratics.f.wiki.setPinCoordsOrig($('#editlocation').data('selection'));
    stratics.f.atlas.ui.resetEditPin();
});

/* Handler for the "store pin edit" button */
$('#editlocation').on('click', '.pinEditStore', () => {
    let wikiF = stratics.f.wiki;

    $('body').off('keydown.pinselect');
    stratics.wiki.openEdits.push([wikiF.getPinMarkupOrig(), wikiF.getPinMarkupEdit()]);
    $('.pinEditSubmit').vis();
    stratics.f.atlas.ui.resetEditPin();
});

/* Handler for the "submit edits" button */
$('.pinEditSubmit').click(() => {
    stratics.f.wiki.getMarkup(); // Asynch request
    $(this).invis();
});

})(jQuery);