wikimedia/mediawiki-extensions-Translate

View on GitHub
resources/js/ext.translate.base.js

Summary

Maintainability
A
0 mins
Test Coverage
( function () {
    'use strict';

    mw.translate = mw.translate || {};

    mw.translate = $.extend( mw.translate, {
        /** @private */
        dirty: false,

        /**
         * A cache for language stats loaded from API, indexed by language code
         *
         * @internal
         */
        languagestats: {},

        /**
         * Storage for language stats loader functions from API, indexed by language code
         *
         * @private
         */
        languageStatsLoader: {},

        /**
         * Get language stats for a language from the API.
         *
         * @internal
         * @param {string} language Language code.
         * @return {jQuery.Deferred}
         */
        loadMessageGroupStatsForLanguage: function ( language ) {
            if ( !mw.translate.languageStatsLoader[ language ] ) {
                mw.translate.languageStatsLoader[ language ] = new mw.Api().get( {
                    action: 'query',
                    meta: 'languagestats',
                    lslanguage: language
                } );
            }

            mw.translate.languageStatsLoader[ language ].done( function ( result ) {
                mw.translate.languagestats[ language ] = result.query.languagestats;
            } );

            return mw.translate.languageStatsLoader[ language ];
        },

        /**
         * Get language stats for a language and group from the API
         *
         * @internal
         * @param {string} language
         * @param {string} group
         * @return {jQuery.Deferred}
         */
        loadMessageGroupStatsForItem: function ( language, group ) {
            var uniqueKey = group + '|' + language;
            if ( !mw.translate.languageStatsLoader[ uniqueKey ] ) {
                mw.translate.languageStatsLoader[ uniqueKey ] = new mw.Api().get( {
                    action: 'query',
                    meta: 'languagestats',
                    lslanguage: language,
                    lsgroup: group
                } );
            }

            mw.translate.languageStatsLoader[ uniqueKey ]
                .done( function ( result ) {
                    if ( result.query.languagestats && result.query.languagestats.length ) {
                        mw.translate.languagestats[ language ] = result.query.languagestats;
                    } else {
                        mw.translate.languagestats[ language ] = [];
                    }

                } );

            return mw.translate.languageStatsLoader[ uniqueKey ];
        },

        /**
         * Load message group information asynchronously.
         *
         * @internal
         * @param {string} id Message group id
         * @param {string|Array} [props] List of properties to load
         * @return {jQuery.Promise} Object containing the requested properties on success.
         */
        getMessageGroup: function ( id, props ) {
            if ( Array.isArray( props ) ) {
                props = props.join( '|' );
            } else if ( props === undefined ) {
                props = 'id|label|description|icon|priority|prioritylangs|priorityforce|workflowstates';
            }

            var params = {
                meta: 'messagegroups',
                mgformat: 'flat',
                mgprop: props,
                mgroot: id,
                formatversion: 2,
                uselang: mw.config.get( 'wgUserLanguage' )
            };

            var api = new mw.Api();

            return api.get( params ).then( function ( result ) {
                return result.query.messagegroups[ 0 ];
            } );
        },

        /**
         * Find a group from an array of message groups as returned by web api
         * and recurse it through sub groups.
         *
         * @internal
         * @param {string} id Group id to search for.
         * @param {Array} groups Array of message groups
         * @return {Object} Message group object
         */
        findGroup: function ( id, groups ) {
            if ( !id ) {
                return groups;
            }

            var result;
            groups.some( function ( group ) {
                if ( group.id === id ) {
                    result = group;
                    return true;
                }

                if ( group.groups ) {
                    group = mw.translate.findGroup( id, group.groups );

                    if ( group ) {
                        result = group;
                        return true;
                    }
                }

                return false;
            } );

            return result;
        },

        /**
         * Check if the current user is allowed to translate on this wiki.
         *
         * @internal
         * @return {boolean}
         */
        canTranslate: function () {
            return mw.config.get( 'TranslateRight' );
        },

        /**
         * Check if the current user is allowed to proofread on this wiki.
         *
         * @internal
         * @return {boolean}
         */
        canProofread: function () {
            return mw.config.get( 'TranslateMessageReviewRight' );
        },

        /**
         * Check if the current user can delete translations on this wiki.
         *
         * @internal
         * @return {boolean}
         */
        canDelete: function () {
            return mw.config.get( 'DeleteRight' ) && mw.config.get( 'TranslateRight' );
        },

        /**
         * Check if the current user can update and manage message groups.
         *
         * @internal
         * @return {boolean}
         */
        canManage: function () {
            return mw.config.get( 'TranslateManageRight' );
        },

        /**
         * Adds missing languages to the language database so that they can be used in ULS.
         *
         * @internal
         * @param {Object} languages Language tags mapped to language names
         * @param {Array} regions Which regions to add the languages.
         */
        addExtraLanguagesToLanguageData: function ( languages, regions ) {
            for ( var code in languages ) {
                if ( code in $.uls.data.languages ) {
                    continue;
                }

                $.uls.data.addLanguage( code, {
                    script: 'Zyyy',
                    regions: regions,
                    autonym: languages[ code ]
                } );
            }
        },

        /**
         * Checks if there are any unsaved edits in Special:Translate
         *
         * @internal
         * @return {boolean|number}
         */
        isDirty: function () {
            // Something being typed in the current editor.
            return mw.translate.dirty ||
                // Previous editors has some unsaved edits
                $( '.tux-status-unsaved' ).length;
        },

        /**
         * Return the language details for usage in HTML attributes
         *
         * @internal
         * @param {string} languageCode
         * @return {Object}
         */
        getLanguageDetailsForHtml: function ( languageCode ) {
            var languageCodeForHtml = languageCode;
            if ( languageCode === mw.config.get( 'wgTranslateDocumentationLanguageCode' ) ) {
                languageCodeForHtml = mw.config.get( 'wgContentLanguage' );
            }

            return {
                code: languageCodeForHtml,
                direction: $.uls.data.getDir( languageCodeForHtml ),
                autonym: $.uls.data.getAutonym( languageCode )
            };
        }
    } );

    /**
     * A warning to be shown if a user tries to close the page or navigate away
     * from it without saving the written translation.
     */
    function translateOnBeforeUnloadRegister() {
        $( window ).on( 'beforeunload', function () {
            if ( mw.translate.isDirty() ) {
                // Return our message
                return mw.msg( 'translate-js-support-unsaved-warning' );
            }
        } );
    }

    $( function () {
        translateOnBeforeUnloadRegister();
    } );
}() );