Making WordPress.org

Changeset 12677


Ignore:
Timestamp:
06/26/2023 08:52:54 AM (3 years ago)
Author:
amieiro
Message:

Translate: Preload the suggestions

See https://github.com/WordPress/wordpress.org/pull/141

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js

    r12586 r12677  
     1/* global $gp */
    12( function( $ ){
    23    /**
    3      * Stores the originalId of the translations for which OpenAI has already been queried,
    4      * to avoid making the query another time.
     4     * Stores (caches) the translation memory (TM) suggestions that has already been queried,
     5     * to avoid making the query another time. The key is the originalId.
    56     *
    67     * @type {array}
    78     */
     9    var TMSuggestionRequested = [];
     10
     11    /**
     12     * Stores (caches) the OpenAI suggestions that has already been queried,
     13     * to avoid making the query another time. The key is the originalId.
     14     *
     15     * @type {array}
     16     */
    817    var OpenAITMSuggestionRequested = [];
    918
    1019    /**
    11      * Stores the originalId of the translations for which DeepL has already been queried,
    12      * to avoid making the query another time.
     20     * Stores (caches) the DeepL suggestions that has already been queried,
     21     * to avoid making the query another time. The key is the originalId.
    1322     *
    1423     * @type {array}
     
    1625    var DeeplTMSuggestionRequested = [];
    1726
    18     function fetchSuggestions( $container, apiUrl, originalId, translationId, nonce ) {
     27    /**
     28     * Stores (caches) the "Other Languages" suggestions that has already been queried,
     29     * to avoid making the query another time. The key is the originalId.
     30     *
     31     * @type {array}
     32     */
     33    var OtherLanguagesSuggestionRequested = [];
     34
     35    /**
     36     * Requests the suggestions from an external system, stores them in the cache and appended them to the container.
     37     * If the suggestions are already in the cache, they are appended to the container.
     38     *
     39     * @param {object} $container    The container where the suggestions will be stored.
     40     * @param {string} apiUrl        The URL of the API.
     41     * @param {number} originalId    The ID of the original string.
     42     * @param {number} translationId The ID of the translation string.
     43     * @param {string} nonce         The nonce to use to make the request.
     44     * @param {string} type          The type of suggestions to fetch: TM, OpenAI, DeepL, OL (Other Languages).
     45     *
     46     * @return {void}
     47     */
     48    function fetchSuggestions( $container, apiUrl, originalId, translationId, nonce, type ) {
     49        var cachedSuggestion = getTheSuggestionFromTheCache( type, originalId );
     50        if ( cachedSuggestion ) {
     51            $container.removeClass( 'fetching' );
     52            $container.find( '.suggestions__loading-indicator' ).remove();
     53            if ( isThisTypeOfSuggestionInTheContainer( $container, type ) ) {
     54                return;
     55            }
     56
     57            $container.append( cachedSuggestion );
     58            removeNoSuggestionsMessage( $container );
     59            copyTranslationMemoryToSidebarTab( $container );
     60            return;
     61        }
     62        // Store a string with a space to avoid making the same request another time.
     63        storeTheSuggestionInTheCache( type, originalId, ' ' );
    1964        var xhr = $.ajax( {
    2065            url: apiUrl,
     
    3277            if ( response.success ) {
    3378                $container.append( response.data );
     79                storeTheSuggestionInTheCache( type, originalId, response.data );
    3480                removeNoSuggestionsMessage( $container );
    35                 copyTranslationMemoryToSidebarTab();
     81                copyTranslationMemoryToSidebarTab( $container );
    3682            } else {
    3783                $container.append( $( '<span/>', { 'text': 'Error while loading suggestions.' } ) );
     
    5298
    5399    /**
     100     * Gets the suggestions for the first row and stores them in the local cache.
     101     *
     102     * @return {void}
     103     */
     104    function getSuggestionsForTheFirstRow() {
     105        var firstEditor = $( '#translations' ).find( '.editor' ).first();
     106        var row_id = firstEditor.closest( 'tr' ).attr( 'row' );
     107        if ( ! row_id ) {
     108            return;
     109        }
     110        firstEditor.row_id = row_id;
     111        firstEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
     112        firstEditor.translation_id = $gp.editor.translation_id_from_row_id( row_id );
     113        maybeFetchTranslationMemorySuggestions( firstEditor );
     114        maybeFetchOpenAISuggestions( firstEditor );
     115        maybeFetchDeeplSuggestions( firstEditor );
     116        maybeFetchOtherLanguageSuggestions( firstEditor );
     117    }
     118
     119    /**
     120     * Gets a suggestion from the local cache.
     121     *
     122     * @param {string} type       The type of suggestions to fetch: TM, OpenAI, DeepL, OL (Other Languages).
     123     * @param {number} originalId The ID of the original string.
     124     *
     125     * @return {string|boolean}  The suggestion if it is in the cache, false otherwise.
     126     */
     127    function getTheSuggestionFromTheCache( type, originalId ) {
     128
     129        switch ( type ) {
     130            case 'TM':
     131                if ( ! ( originalId in TMSuggestionRequested ) ) {
     132                    return false;
     133                }
     134                return TMSuggestionRequested[ originalId ];
     135                break;
     136            case 'OpenAI':
     137                if ( ! ( originalId in OpenAITMSuggestionRequested ) ) {
     138                    return false;
     139                }
     140                return OpenAITMSuggestionRequested[ originalId ];
     141                break;
     142            case 'DeepL':
     143                if ( ! ( originalId in DeeplTMSuggestionRequested ) ) {
     144                    return false;
     145                }
     146                return DeeplTMSuggestionRequested[ originalId ];
     147                break;
     148            case 'OL':
     149                if ( ! ( originalId in OtherLanguagesSuggestionRequested ) ) {
     150                    return false;
     151                }
     152                return OtherLanguagesSuggestionRequested[ originalId ];
     153                break;
     154        }
     155    }
     156
     157    /**
     158     * Stores the suggestion in the local cache (JavaScript variables).
     159     *
     160     * @param {string} type       The type of suggestions to fetch: TM, OpenAI, DeepL, OL (Other Languages).
     161     * @param {number} originalId The ID of the original string.
     162     * @param {string} suggestion The suggestion to store.
     163     *
     164     * @return {void}
     165     */
     166    function storeTheSuggestionInTheCache( type, originalId, suggestion ) {
     167        switch (type) {
     168            case 'TM':
     169                TMSuggestionRequested[ originalId ] = suggestion;
     170                break;
     171            case 'OpenAI':
     172                OpenAITMSuggestionRequested[ originalId ] = suggestion;
     173                break;
     174            case 'DeepL':
     175                DeeplTMSuggestionRequested[ originalId ] = suggestion;
     176                break;
     177            case 'OL':
     178                OtherLanguagesSuggestionRequested[ originalId ] = suggestion;
     179                break;
     180        }
     181    }
     182
     183    /**
    54184     * Copies the translation memory to the sidebar tab and adds the number of items in the TM to the tab.
    55185     *
    56      * @return {void}
    57      */
    58     function copyTranslationMemoryToSidebarTab(){
    59         var divSidebarWithTM = $gp.editor.current.find( '.meta.translation-memory' ).first();
     186     * @param {object} $container The container where the suggestions are stored.
     187     *
     188     * @return {void}
     189     */
     190    function copyTranslationMemoryToSidebarTab( $container ){
     191        var editor = $container.closest( '.editor' );
     192        var divSidebarWithTM = editor.find( '.meta.translation-memory' ).first();
    60193        var divId = divSidebarWithTM.attr( 'data-row-id' );
    61         var TMcontainer = $gp.editor.current.find( '.suggestions__translation-memory' );
     194        var TMcontainer = editor.find( '.suggestions__translation-memory' );
    62195        if ( !TMcontainer.length ) {
    63196            return;
     
    72205
    73206    /**
    74      * Add the suggestion from the translation memory to the translation textarea if
     207     * Adds the suggestion from the translation memory to the translation textarea if
    75208     * the suggestion has 100% of accuracy.
     209     *
     210     * @param {string} data The HTML response from the TM.
    76211     *
    77212     * @return {void}
     
    98233    }
    99234
    100     function maybeFetchTranslationMemorySuggestions() {
    101         var $container = $gp.editor.current.find( '.suggestions__translation-memory' );
     235    /**
     236     * Fetches the suggestions from the translation memory.
     237     *
     238     * @param {object} editor The editor object.
     239     *
     240     * @return {void}
     241     */
     242    function maybeFetchTranslationMemorySuggestions( editor ) {
     243        var $container = editor.find( '.suggestions__translation-memory' );
    102244        if ( !$container.length ) {
    103245            return;
     
    108250        }
    109251
    110         if ( !$gp.editor.current.find('translation-suggestion.with-tooltip.translation').first() ) {
     252        if ( !editor.find('translation-suggestion.with-tooltip.translation').first() ) {
    111253            return;
    112254        }
     
    114256        $container.addClass( 'fetching' );
    115257
    116         var originalId = $gp.editor.current.original_id;
    117         var translationId = $gp.editor.current.translation_id;
     258        var originalId = editor.original_id;
     259        var translationId = editor.translation_id;
    118260        var nonce = $container.data( 'nonce' );
    119261
    120         fetchSuggestions( $container, window.WPORG_TRANSLATION_MEMORY_API_URL, originalId, translationId, nonce );
     262        fetchSuggestions( $container, window.WPORG_TRANSLATION_MEMORY_API_URL, originalId, translationId, nonce, 'TM' );
    121263    }
    122264
     
    124266     * Gets the suggestions from the OpenAI API.
    125267     *
     268     * @param {object} editor The editor object.
     269     *
    126270     * @return {void}
    127271     **/
    128     function maybeFetchOpenAISuggestions() {
    129         maybeFetchExternalSuggestions( 'OpenAI', gpTranslationSuggestions.get_external_translations.get_openai_translations, window.WPORG_TRANSLATION_MEMORY_OPENAI_API_URL );
     272    function maybeFetchOpenAISuggestions( editor ) {
     273        maybeFetchExternalSuggestions( editor, 'OpenAI', gpTranslationSuggestions.get_external_translations.get_openai_translations, window.WPORG_TRANSLATION_MEMORY_OPENAI_API_URL );
    130274    }
    131275
     
    133277     * Gets the suggestions from the DeepL API.
    134278     *
     279     * @param {object} editor The editor object.
     280     *
    135281     * @return {void}
    136282     **/
    137     function maybeFetchDeeplSuggestions() {
    138         maybeFetchExternalSuggestions( 'DeepL', gpTranslationSuggestions.get_external_translations.get_deepl_translations, window.WPORG_TRANSLATION_MEMORY_DEEPL_API_URL );
     283    function maybeFetchDeeplSuggestions( editor ) {
     284        maybeFetchExternalSuggestions( editor, 'DeepL', gpTranslationSuggestions.get_external_translations.get_deepl_translations, window.WPORG_TRANSLATION_MEMORY_DEEPL_API_URL );
    139285    }
    140286
     
    142288     * Gets the suggestions from an external service.
    143289     *
    144      * @param type                   The type of the external service: OpenAI or DeepL.
    145      * @param getExternalSuggestions Whether to get the suggestions from the external service.
    146      * @param apiUrl                 The URL of the API.
    147      *
    148      * @return {void}
    149      */
    150     function maybeFetchExternalSuggestions( type, getExternalSuggestions, apiUrl ) {
    151         var $container = $gp.editor.current.find( '.suggestions__translation-memory' );
     290     * @param {object}  editor                 The editor.
     291     * @param {string}  type                   The type of the external service: OpenAI or DeepL.
     292     * @param {boolean} getExternalSuggestions Whether to get the suggestions from the external service.
     293     * @param {string}  apiUrl                 The URL of the API.
     294     *
     295     * @return {void}
     296     */
     297    function maybeFetchExternalSuggestions( editor, type, getExternalSuggestions, apiUrl ) {
     298        var $container = editor.find( '.suggestions__translation-memory' );
    152299        if ( !$container.length ) {
    153300            return;
     
    156303            return;
    157304        }
    158         var originalId = $gp.editor.current.original_id;
    159         var translationId = $gp.editor.current.translation_id;
     305        var originalId = editor.original_id;
     306        var translationId = editor.translation_id;
    160307        var nonce = $container.data( 'nonce' );
    161308
    162         if( true === wasRequestMade( type, originalId ) ) {
    163             return;
    164         }
    165 
    166         fetchSuggestions( $container, apiUrl, originalId, translationId, nonce );
    167     }
    168 
    169     /**
    170      * Checks if the request was already made for this originalId and type.
    171      *
    172      * @param type        The type of the external service: OpenAI or DeepL.
    173      * @param originalId  The original ID.
    174      *
    175      * @returns {boolean} Whether the request was already made.
    176      */
    177     function wasRequestMade( type, originalId ) {
    178         if ('OpenAI' === type) {
    179             if ( originalId in OpenAITMSuggestionRequested ) {
    180                 return true;
    181             } else {
    182                 OpenAITMSuggestionRequested[originalId] = true;
    183             }
    184         }
    185         if ('DeepL' === type) {
    186             if ( originalId in DeeplTMSuggestionRequested ) {
    187                 return true;
    188             } else {
    189                 DeeplTMSuggestionRequested[originalId] = true;
    190             }
    191         }
    192         return false;
    193     }
    194 
    195     function maybeFetchOtherLanguageSuggestions() {
    196         var $container = $gp.editor.current.find( '.suggestions__other-languages' );
     309        fetchSuggestions( $container, apiUrl, originalId, translationId, nonce, type );
     310    }
     311
     312    /**
     313     * Gets the suggestions from other languages.
     314     *
     315     * @param {object} editor The editor object.
     316     *
     317     * @return {void}
     318     **/
     319    function maybeFetchOtherLanguageSuggestions( editor ) {
     320        var $container = editor.find( '.suggestions__other-languages' );
    197321        if ( ! $container.length ) {
    198322            return;
     
    205329        $container.addClass( 'fetching' );
    206330
    207         var originalId = $gp.editor.current.original_id;
    208         var translationId = $gp.editor.current.translation_id;
     331        var originalId = editor.original_id;
     332        var translationId = editor.translation_id;
    209333        var nonce = $container.data( 'nonce' );
    210334
    211         fetchSuggestions( $container, window.WPORG_OTHER_LANGUAGES_API_URL, originalId , translationId,  nonce );
     335        fetchSuggestions( $container, window.WPORG_OTHER_LANGUAGES_API_URL, originalId , translationId,  nonce, 'OL' );
    212336    }
    213337
     
    217341     * This is needed because the suggestions are loaded asynchronously.
    218342     *
    219      * @param $container
     343     * @param {object} $container The container where the suggestions are stored.
     344     *
     345     * @return {void}
    220346     */
    221347    function removeNoSuggestionsMessage( $container ) {
     
    224350            $container.find( '.no-suggestions' ).hide();
    225351        } else {
    226             $container = removeNoSuggestionsDuplicateMessage( $container );
     352            removeNoSuggestionsDuplicateMessage( $container );
    227353        }
    228354    }
     
    231357     * Removes duplicate "No suggestions" messages.
    232358     *
    233      * @param $container
    234      * @returns {*|jQuery}
     359     * @param {object} $container The container where the suggestions are stored.
     360     *
     361     * @return {void}
    235362     */
    236363    function removeNoSuggestionsDuplicateMessage( $container ) {
     
    248375            }
    249376        });
    250 
    251         return $html.prop('outerHTML');
    252377    }
    253378    function copySuggestion( event ) {
     
    274399    }
    275400
     401    /**
     402     * Checks if the suggestions of a certain type are in the container.
     403     *
     404     * @param {object} container The container.
     405     * @param {string} type The type of the suggestions: OpenAI or DeepL.
     406     *
     407     * @return {boolean}
     408     */
     409    function isThisTypeOfSuggestionInTheContainer( container, type ) {
     410        switch ( type ) {
     411            case 'TM':
     412                if ( container.find( '.translation-suggestion.with-tooltip.translation' ).length > 0 ) {
     413                    return true;
     414                }
     415                break;
     416            case 'OpenAI':
     417                if ( container.find( '.translation-suggestion.with-tooltip.openai' ).length > 0 ) {
     418                    return true;
     419                }
     420                break;
     421            case 'DeepL':
     422                if ( container.find( '.translation-suggestion.with-tooltip.deepl' ).length > 0 ) {
     423                    return true;
     424                }
     425                break;
     426        }
     427        return false;
     428    }
     429
    276430    $gp.editor.show = ( function( original ) {
    277431        return function() {
    278432            original.apply( $gp.editor, arguments );
    279             maybeFetchTranslationMemorySuggestions();
    280             maybeFetchOpenAISuggestions();
    281             maybeFetchDeeplSuggestions();
    282             maybeFetchOtherLanguageSuggestions();
    283         }
     433            maybeFetchTranslationMemorySuggestions( $gp.editor.current );
     434            maybeFetchOpenAISuggestions( $gp.editor.current );
     435            maybeFetchDeeplSuggestions( $gp.editor.current );
     436            maybeFetchOtherLanguageSuggestions( $gp.editor.current );
     437            var nextEditor = $gp.editor.current.nextAll('tr.editor' ).first();
     438            if ( nextEditor.length ) {
     439                var row_id = nextEditor.closest( 'tr' ).attr( 'row' );
     440                nextEditor.row_id = row_id;
     441                nextEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
     442                nextEditor.translation_id = $gp.editor.translation_id_from_row_id( row_id );
     443                maybeFetchTranslationMemorySuggestions( nextEditor );
     444                maybeFetchOpenAISuggestions( nextEditor );
     445                maybeFetchDeeplSuggestions( nextEditor );
     446                maybeFetchOtherLanguageSuggestions( nextEditor );
     447            }
     448        };
    284449    })( $gp.editor.show );
    285450
     
    290455            $( $gp.editor.table )
    291456                .on( 'click', '.translation-suggestion', copySuggestion );
    292         }
     457            $( document ).ready( function() {
     458                getSuggestionsForTheFirstRow();
     459            });
     460        };
    293461    })( $gp.editor.install_hooks );
    294462
Note: See TracChangeset for help on using the changeset viewer.