( 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(); } ); }() );