summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Translate/resources/js/ext.translate.special.translate.js
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/Translate/resources/js/ext.translate.special.translate.js')
-rw-r--r--www/wiki/extensions/Translate/resources/js/ext.translate.special.translate.js399
1 files changed, 399 insertions, 0 deletions
diff --git a/www/wiki/extensions/Translate/resources/js/ext.translate.special.translate.js b/www/wiki/extensions/Translate/resources/js/ext.translate.special.translate.js
new file mode 100644
index 00000000..103cfb8c
--- /dev/null
+++ b/www/wiki/extensions/Translate/resources/js/ext.translate.special.translate.js
@@ -0,0 +1,399 @@
+( function () {
+ 'use strict';
+
+ var state = {
+ group: null,
+ language: null,
+ messageList: null
+ };
+
+ mw.translate = mw.translate || {};
+
+ mw.translate = $.extend( mw.translate, {
+
+ /**
+ * Change the group that is currently displayed
+ * in the TUX translation editor.
+ *
+ * @param {Object} group a message group object.
+ */
+ changeGroup: function ( group ) {
+ var changes;
+
+ if ( !checkDirty() ) {
+ return;
+ }
+
+ state.group = group.id;
+
+ changes = {
+ group: group.id,
+ showMessage: null
+
+ };
+
+ mw.translate.changeUrl( changes );
+ mw.translate.updateTabLinks( changes );
+ $( '.tux-editor-header .group-warning' ).empty();
+ state.messageList.changeSettings( changes );
+ updateGroupInformation( state );
+ },
+
+ changeLanguage: function ( language ) {
+ var changes = {
+ language: language,
+ showMessage: null
+ };
+
+ state.language = language;
+
+ mw.translate.changeUrl( changes );
+ mw.translate.updateTabLinks( changes );
+ $( '.tux-editor-header .group-warning' ).empty();
+ state.messageList.changeSettings( changes );
+ updateGroupInformation( state );
+
+ },
+
+ changeFilter: function ( filter ) {
+ if ( !checkDirty() ) {
+ return;
+ }
+
+ mw.translate.changeUrl( { filter: filter, showMessage: null } );
+ state.messageList.changeSettings( { filter: getActualFilter( filter ) } );
+ },
+
+ changeUrl: function ( params, forceChange ) {
+ var uri = new mw.Uri( window.location.href );
+
+ uri.extend( params );
+
+ // Support removing keys from the query
+ $.each( params, function ( key, val ) {
+ if ( val === null ) {
+ delete uri.query[ key ];
+ }
+ } );
+
+ if ( uri.toString() === window.location.href ) {
+ return;
+ }
+
+ // If supported by the browser and requested, change the URL with
+ // this URI but try not to leave the page.
+ if ( !forceChange && history.pushState && $( '.tux-messagelist' ).length ) {
+ history.pushState( uri, null, uri.toString() );
+ } else {
+ // For old browsers, just reload
+ window.location.href = uri.toString();
+ }
+ },
+
+ /**
+ * Updates the navigation tabs.
+ *
+ * @param {Object} params Url parameters to update.
+ * @since 2013.05
+ */
+ updateTabLinks: function ( params ) {
+ $( '.tux-tab a' ).each( function () {
+ var $a, uri;
+
+ $a = $( this );
+ uri = new mw.Uri( $a.prop( 'href' ) );
+ uri.extend( params );
+ $a.prop( 'href', uri.toString() );
+ } );
+ }
+ } );
+
+ function getActualFilter( filter ) {
+ var realFilters, uri;
+
+ realFilters = [ '!ignored' ];
+ uri = new mw.Uri( window.location.href );
+ if ( uri.query.optional !== '1' ) {
+ realFilters.push( '!optional' );
+ }
+ if ( filter ) {
+ realFilters.push( filter );
+ }
+
+ return realFilters.join( '|' );
+ }
+
+ function checkDirty() {
+ if ( mw.translate.isDirty() ) {
+ // eslint-disable-next-line no-alert
+ return confirm( mw.msg( 'translate-js-support-unsaved-warning' ) );
+ }
+ return true;
+ }
+
+ // Returns an array of jQuery objects of rows of translated
+ // and proofread messages in the TUX editors.
+ // Used several times.
+ function getTranslatedMessages( $translateContainer ) {
+ $translateContainer = $translateContainer || $( '.ext-translate-container' );
+ return $translateContainer.find( '.tux-message-item' )
+ .filter( '.translated, .proofread' );
+ }
+
+ /**
+ * Updates all group specific stuff on the page.
+ *
+ * @param {Object} state Information about current group and language.
+ * @param {string} state.group Message group id.
+ * @param {string} state.language Language.
+ */
+ function updateGroupInformation( state ) {
+ var props = 'id|priority|prioritylangs|priorityforce|description';
+
+ mw.translate.recentGroups.append( state.group );
+
+ mw.translate.getMessageGroup( state.group, props ).done( function ( group ) {
+ updateDescription( group );
+ updateGroupWarning( group, state.language );
+ } );
+ }
+
+ function updateDescription( group ) {
+ var
+ api = new mw.Api(),
+ $description = $( '.tux-editor-header .description' );
+
+ if ( group.description === null ) {
+ $description.empty();
+ return;
+ }
+
+ api.parse( group.description ).done( function ( parsedDescription ) {
+ // The parsed text is returned in a <p> tag,
+ // so it's removed here.
+ $description.html( parsedDescription );
+ } ).fail( function () {
+ $description.empty();
+ mw.log( 'Error parsing description for group ' + group.id );
+ } );
+ }
+
+ function updateGroupWarning( group, language ) {
+ var preferredLanguages, headerMessage, languagesMessage,
+ $groupWarning = $( '.tux-editor-header .group-warning' );
+
+ if ( isPriorityLanguage( language, group.prioritylangs ) ) {
+ return;
+ }
+
+ // Make a comma-separated list of preferred languages
+ preferredLanguages = $.map( group.prioritylangs, function ( lang ) {
+ // bidi isolation for language names
+ return '<bdi>' + $.uls.data.getAutonym( lang ) + '</bdi>';
+ } ).join( ', ' );
+
+ headerMessage = mw.message(
+ group.priorityforce ?
+ 'tpt-discouraged-language-force-header' :
+ 'tpt-discouraged-language-header',
+ $.uls.data.getAutonym( language )
+ ).parse();
+
+ languagesMessage = mw.message(
+ group.priorityforce ?
+ 'tpt-discouraged-language-force-content' :
+ 'tpt-discouraged-language-content',
+ preferredLanguages
+ ).parse();
+
+ $groupWarning.append(
+ $( '<p>' ).append( $( '<strong>' ).text( headerMessage ) ),
+ // html because of the <bdi> and because it's parsed
+ $( '<p>' ).html( languagesMessage )
+ );
+ }
+
+ function isPriorityLanguage( language, priorityLanguages ) {
+ // Don't show priority notice if the language is message documentation.
+ if ( language === mw.config.get( 'wgTranslateDocumentationLanguageCode' ) ) {
+ return true;
+ }
+
+ // If no priority language is set, return early.
+ if ( !priorityLanguages ) {
+ return true;
+ }
+
+ if ( priorityLanguages.indexOf( language ) !== -1 ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ function setupLanguageSelector( $element ) {
+ var ulsOptions = {
+ languages: mw.config.get( 'wgTranslateLanguages' ),
+ showRegions: [ 'SP' ].concat( $.fn.lcd.defaults.showRegions ),
+ onSelect: function ( language ) {
+ mw.translate.changeLanguage( language );
+ $element.text( $.uls.data.getAutonym( language ) );
+ },
+ ulsPurpose: 'translate-special-translate',
+ quickList: function () {
+ return mw.uls.getFrequentLanguageList();
+ }
+ };
+
+ mw.translate.addExtraLanguagesToLanguageData( ulsOptions.languages, [ 'SP' ] );
+ $element.uls( ulsOptions );
+ }
+
+ $( function () {
+ var $translateContainer, $hideTranslatedButton, $messageList,
+ filter, uri, position, offset, limit;
+
+ $messageList = $( '.tux-messagelist' );
+ state.group = $( '.tux-messagetable-loader' ).data( 'messagegroup' );
+ state.language = $messageList.data( 'targetlangcode' );
+
+ if ( $messageList.length ) {
+ $messageList.messagetable();
+ state.messageList = $messageList.data( 'messagetable' );
+
+ uri = new mw.Uri( window.location.href );
+ filter = uri.query.filter;
+ offset = uri.query.showMessage;
+ if ( offset ) {
+ limit = uri.query.limit || 1;
+ // Default to no filters
+ filter = filter || '';
+ }
+
+ if ( filter === undefined ) {
+ filter = '!translated';
+ }
+
+ $( '.tux-message-selector li' ).each( function () {
+ var $this = $( this );
+
+ if ( $this.data( 'filter' ) === filter ) {
+ $this.addClass( 'selected' );
+ }
+ } );
+
+ mw.translate.changeUrl( {
+ group: state.group,
+ language: state.language,
+ filter: filter,
+ showMessage: offset,
+ optional: offset ? 1 : undefined
+ } );
+
+ // Start loading messages
+ state.messageList.changeSettings( {
+ group: state.group,
+ language: state.language,
+ offset: offset,
+ limit: limit,
+ filter: getActualFilter( filter )
+ } );
+ }
+
+ if ( $( 'body' ).hasClass( 'rtl' ) ) {
+ position = {
+ my: 'right top',
+ at: 'right+80 bottom+5'
+ };
+ }
+ $( '.tux-breadcrumb__item--aggregate' ).msggroupselector( {
+ onSelect: mw.translate.changeGroup,
+ language: state.language,
+ position: position,
+ recent: mw.translate.recentGroups.get()
+ } );
+
+ updateGroupInformation( state );
+
+ $( '.ext-translate-language-selector .uls' ).one( 'click', function () {
+ var $target = $( this );
+ mw.loader.using( 'ext.uls.mediawiki' ).done( function () {
+ setupLanguageSelector( $target );
+ $target.click();
+ } );
+ } );
+
+ if ( $.fn.translateeditor ) {
+ // New translation editor
+ $( '.tux-message' ).translateeditor();
+ }
+
+ $translateContainer = $( '.ext-translate-container' );
+
+ if ( mw.translate.canProofread() ) {
+ $translateContainer.find( '.proofread-mode-button' ).removeClass( 'hide' );
+ }
+
+ $hideTranslatedButton = $translateContainer.find( '.tux-editor-clear-translated' );
+ $hideTranslatedButton
+ .prop( 'disabled', !getTranslatedMessages( $translateContainer ).length )
+ .click( function () {
+ getTranslatedMessages( $translateContainer ).remove();
+ $( this ).prop( 'disabled', true );
+ } );
+
+ // Message filter click handler
+ $translateContainer.find( '.row.tux-message-selector > li' ).on( 'click', function () {
+ var newFilter,
+ $this = $( this );
+
+ if ( $this.hasClass( 'more' ) ) {
+ return false;
+ }
+
+ newFilter = $this.data( 'filter' );
+
+ // Remove the 'selected' class from all the items.
+ // Some of them could have been moved to under the "more" menu,
+ // so everything under .row.tux-message-selector is searched.
+ $translateContainer.find( '.row.tux-message-selector .selected' )
+ .removeClass( 'selected' );
+ mw.translate.changeFilter( newFilter );
+ $this.addClass( 'selected' );
+
+ // TODO: this could should be in messagetable
+ if ( newFilter === '!translated' ) {
+ $hideTranslatedButton
+ .removeClass( 'hide' )
+ .prop( 'disabled', !getTranslatedMessages( $translateContainer ).length );
+ } else {
+ $hideTranslatedButton.addClass( 'hide' );
+ }
+
+ return false;
+ } );
+
+ // TODO: this could should be in messagetable
+ if ( $( '.tux-messagetable-loader' ).data( 'filter' ) === '!translated' ) {
+ $hideTranslatedButton.removeClass( 'hide' );
+ } else {
+ $hideTranslatedButton.addClass( 'hide' );
+ }
+
+ // Don't let clicking the items in the "more" menu
+ // affect the rest of it.
+ $( '.row.tux-message-selector .more ul' )
+ .on( 'click', function ( e ) {
+ e.stopPropagation();
+ } );
+
+ $( '#tux-option-optional' ).on( 'change', function () {
+ var uri = new mw.Uri( window.location.href ),
+ checked = $( this ).prop( 'checked' );
+
+ mw.translate.changeUrl( { optional: checked ? 1 : 0 } );
+ mw.translate.changeFilter( uri.query.filter );
+ } );
+ } );
+
+}() );