MediaWiki:FundraisingBanners/CoreJS-2017.js

From Meta, a Wikimedia project coordination wiki

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.
/* MediaWiki:FundraisingBanners/CoreJS-2017.js
 * Core code for banner forms
 */

var frb = frb || {};

/**
 * Main function to submit to paymentswiki
 *
 * @param  {Object} options
 * - method (required)
 * - submethod (optional)
 * - gateway (optional)
 * - ffname (optional)
 * - skipValidation (optional boolean, for pp-usd. Not yet implemented.)
 */
frb.submitForm = function(options) {

    var form = document.getElementById('frb-form');
    var uri = new mw.Uri('https://payments.wikimedia.org/index.php/Special:GatewayFormChooser');
    var params = {};

    /* Form selection data */
    params.payment_method = options.method;
    if ( options.submethod ) {
        params.payment_submethod = options.submethod;
    }
    if ( options.gateway ) {
        params.gateway = options.gateway;
    }
    if ( options.ffname ) {
        params.ffname = options.ffname;
    }
    if ( options.variant ) {
        params.variant = options.variant;
    }
    params.recurring = frb.getRecurring(form);

    params.currency_code = frb.getCurrency(mw.centralNotice.data.country) || 'USD';

    params.uselang = mw.centralNotice.data.uselang || 'en';
    params.country = mw.centralNotice.data.country || 'XX';

    if ( params.uselang === 'pt' && params.country === 'BR' ) {
        params.uselang = 'pt-br';
    }
    if ( params.uselang === 'es' && 
        ( params.country === 'AR' || params.country === 'CL' || 
          params.country === 'CO' || params.country === 'MX' || 
          params.country === 'PE' || params.country === 'UY' )
    ) {
        params.uselang = 'es-419';
    }

    /* Adyen override. frb.ccAdyenCountries is defined in LocalizeJS-2017.js */
    if ( params.payment_method === 'cc' && frb.ccAdyenCountries.indexOf( params.country ) !== -1 ) {
        params.gateway = 'adyen';
    }

    /* Amount */
    var amount = frb.getAmount(form);
    // See if "Pay the fee" is checked
    if ( $('#frb-ptf-checkbox').prop('checked') ) {
        amount = amount + frb.calculateFee(amount);
    }
    if ( !frb.validateAmount(amount) ) {
        return false; // Amount problem, bail out of submitting
    }
    params.amount = amount;

    /* Tracking info */
    params.utm_medium   = 'sitenotice';
    params.utm_campaign = mw.centralNotice.data.campaign || 'test';
    params.utm_source   = frb.buildUtmSource(params);
    // No longer used since we have banner history, could use to store something else
    // params.utm_key   = mw.centralNotice.bannerData.cookieCount || 0;

    /* Link to Banner History if enabled */
    var mixins = mw.centralNotice.getDataProperty( 'mixins' );
    if ( mixins && mixins.bannerHistoryLogger ) {
        params.bannerhistlog = mw.centralNotice.bannerHistoryLogger.id;
    }

    uri.extend(params);

    if ( mixins && mixins.bannerHistoryLogger ) {
        mw.centralNotice.bannerHistoryLogger.ensureLogSent().always(function() {
            window.location.href = uri.toString();
        });
    } else {
        window.location.href = uri.toString();
    }

};

/**
 * Build the utm_source for analytics.
 *
 * Own function so it can be overriden for weird tests
 *
 * @param  {Object} params
 * @return {string} utm_source
 */
frb.buildUtmSource = function(params) {

    var utm_source;
    var fullDottedPaymentMethod = params.payment_method;
    if ( params.recurring ) {
        fullDottedPaymentMethod = 'r' + fullDottedPaymentMethod;
    }
    if ( params.payment_submethod ) {
        fullDottedPaymentMethod = fullDottedPaymentMethod + '.' + params.payment_submethod;
    }

    utm_source = mw.centralNotice.data.banner;
    utm_source += '.no-LP.' + fullDottedPaymentMethod;

    return utm_source;
};

/**
 * Determine if we should show recurring choice on step 2
 * @param  {Object} options     Including method and optional gateway
 * @param  {String} country
 * @return {boolean}
 */
frb.shouldShowRecurring = function(options, country) {

    if ( frb.noRecurringCountries.indexOf( country ) !== -1 ) { // Defined in LocalizeJS-2017.js
        return false;
    }
    if ( options.method === 'paypal' ) {
        return true;
    }
    if ( options.method === 'cc' ) {
        if ( options.gateway === 'adyen' || frb.ccAdyenCountries.indexOf( country ) !== -1 ) { // Defined in LocalizeJS-2017.js
            return false;
        } else {
            return true;
        }
    }
    return false;
};

/* Is recurring method selected?
 *
 * Own function so can be overriden for different forms
 */
frb.getRecurring = function(form) {
    return form.frequency.value === 'monthly';
};

/**
 * Return amount selected
 */
frb.getAmount = function(form) {
    var amount = null;

    // If there are some amount radio buttons, then look for the checked one
    if (form.amount) {
        for (var i = 0; i < form.amount.length; i++) {
            if (form.amount[i].checked) {
                amount = form.amount[i].value;
            }
        }
    }

    // Check the "other" amount box
    if (form.otherAmount.value !== '') {
        var otherAmount = form.otherAmount.value;
        otherAmount = otherAmount.replace(/[,.](\d)$/, ':$10');
        otherAmount = otherAmount.replace(/[,.](\d)(\d)$/, ':$1$2');
        otherAmount = otherAmount.replace(/[$£€¥,.]/g, '');
        otherAmount = otherAmount.replace(/:/, '.');
        amount = otherAmount;
    }

    amount = parseFloat(amount);
    if ( isNaN(amount) ) {
        return 0;
    } else {
        return amount;
    }

};

/**
 * Check if given amount is valid i.e. a positive number, between minimum and maximum.
 * If not, show an error and return false.
 *
 * @param  {number}  amount [description]
 * @return {boolean}        [description]
 */
frb.validateAmount = function( amount ) {
    var currency  = frb.getCurrency( mw.centralNotice.data.country );
    var minAmount = frb.amounts.minimums[ currency ];
    var errorMessage;
    if ( amount === null || isNaN(amount) || amount <= 0 || amount < minAmount ) {
        errorMessage = "{{int:Donate_interface-smallamount-error}}"
            .replace( '$1', minAmount + ' ' + currency );
        window.alert( errorMessage );
        return false;
    } else if ( amount > 10000 * minAmount ) {
        errorMessage = "{{int:Donate_interface-bigamount-error}}"
            .replace( '$1', 10000*minAmount )
            .replace( '$2', currency )
            .replace( '$3', 'benefactors@wikimedia.org' );
        window.alert( errorMessage );
        return false;
    } else {
        return true;
    }
};

/**
 * Shared code for amount input handling
 */
frb.initAmountOptions = function() {

    // Reset "Other" input if user clicks a preset amount
    $('#frb-form [id^=frb-amt-ps]').click(function() {
        $('#frb-amt-other-input').val('');
    });

    // Block typing non-numerics in input field, otherwise Safari allows them and then chokes
    // https://phabricator.wikimedia.org/T118741, https://phabricator.wikimedia.org/T173431
    document.getElementById('frb-amt-other-input').onkeypress = function(e) {
        // Allow special keys in Firefox
        if ((e.code == 'ArrowLeft') || (e.code == 'ArrowRight') ||
            (e.code == 'ArrowUp') || (e.code == 'ArrowDown') ||
            (e.code == 'Delete') || (e.code == 'Backspace')) {
            return;
        }
        var chr = String.fromCharCode(e.which);
        if ("0123456789., ".indexOf(chr) === -1) {
            return false;
        }
    };

};
/* End of MediaWiki:FundraisingBanners/CoreJS-2017.js */