WordPress.org

Making WordPress.org

Changeset 8766


Ignore:
Timestamp:
05/09/2019 09:59:52 PM (2 months ago)
Author:
ocean90
Message:

Translate: Split source details into separate <details> elements and add persistent storage for open/close state.

See #4431.

Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/helper-functions.php

    r8758 r8766  
    289289    return $count;
    290290}
     291
     292/**
     293 * Lists file references for a translation.
     294 *
     295 * @param \GP_Project $project Current project.
     296 * @param object      $entry Current translation entry.
     297 */
     298function wporg_references( $project, $entry ) {
     299    ?>
     300    <ul>
     301        <?php
     302        foreach ( $entry->references as $reference ) :
     303            list( $file, $line ) = array_pad( explode( ':', $reference ), 2, 0 );
     304            if ( $source_url = $project->source_url( $file, $line ) ) :
     305                ?>
     306                <li><a target="_blank" href="<?php echo $source_url; ?>"><?php echo $file.':'.$line ?></a></li>
     307            <?php
     308            else :
     309                echo "<li>$file:$line</li>";
     310            endif;
     311        endforeach;
     312        ?>
     313    </ul>
     314    <?php
     315}
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/js/editor.js

    r8751 r8766  
    22    var $html = $( 'html' );
    33    var $document = $( document );
     4
     5    function checkStorage() {
     6        var test = 'test',
     7            result = false;
     8
     9        try {
     10            window.localStorage.setItem( 'test', test );
     11            result = window.localStorage.getItem( 'test' ) === test;
     12            window.localStorage.removeItem( 'test' );
     13        } catch(e) {}
     14
     15        hasStorage = result;
     16        return result;
     17    }
     18
     19    var hasStorage = checkStorage();
    420
    521    // Handle tab view for plural forms.
     
    124140        } );
    125141    }
     142
     143    $gp.editor.keydown  = ( function( original ) {
     144        return function( event ) {
     145            // Shift-Enter = Save.
     146            if ( 13 === event.keyCode && event.shiftKey ) {
     147                var $textarea = $( event.target );
     148
     149                if ( ! $textarea.val().trim() ) {
     150                    $gp.notices.error( 'Translation is empty.' );
     151                    return false;
     152                }
     153
     154                // Check plural forms.
     155                var $textareas = $gp.editor.current.find( '.textareas:not(.active) textarea' );
     156                var isValid = true;
     157                $textareas.each( function() {
     158                    if ( ! this.value.trim() ) {
     159                        isValid = false;
     160                    }
     161                } );
     162
     163                if ( ! isValid ) {
     164                    $gp.notices.error( 'Translation is empty.' );
     165                    return false;
     166                }
     167
     168                $gp.editor.save( $gp.editor.current.find( 'button.translation-actions__save' ) );
     169
     170            // Ctrl-Enter or Ctrl-Shift-B = Copy original.
     171            } else if (
     172                ( 13 === event.keyCode && event.ctrlKey ) ||
     173                ( 66 === event.keyCode && event.shiftKey && event.ctrlKey ) )
     174            {
     175                var $button = $gp.editor.current.find( 'button.translation-actions__copy' );
     176
     177                $button.trigger( 'click' );
     178            } else {
     179                return original.apply( $gp.editor, arguments );
     180            }
     181
     182            return false;
     183        }
     184    })( $gp.editor.keydown );
     185
     186    // Store the open/close state of <details> element in locale storage and apply state when editor is shown.
     187    var DETAILS_STORE_KEY = 'translate-details-state';
     188    function updateDetailsState( type, state ) {
     189        if ( ! hasStorage ) {
     190            return;
     191        }
     192
     193        var store  = window.localStorage.getItem( DETAILS_STORE_KEY );
     194        var states = store ? JSON.parse( store ) : {};
     195
     196        states[ type ] = state;
     197
     198        window.localStorage.setItem( DETAILS_STORE_KEY, JSON.stringify( states ) );
     199    }
     200
     201    function toggleDetails( event ) {
     202        var $el = $( event.target ).closest( 'details' );
     203        var isClosed = $el.attr( 'open' ) === 'open'; // Gets closed when open attribute was previously set.
     204        var className = $el.attr( 'class' ).replace( /^(\S*).*/, '$1' );
     205
     206        updateDetailsState( className, isClosed ? 'close' : 'open' );
     207    }
     208
     209    function applyDetailsState() {
     210        if ( ! hasStorage || ! $gp.editor.current.length ) {
     211            return;
     212        }
     213
     214        var store  = window.localStorage.getItem( DETAILS_STORE_KEY );
     215        var states = store ? JSON.parse( store ) : {};
     216
     217        for ( var type in states ) {
     218            var state = states[ type ];
     219
     220            if ( 'open' === state ) {
     221                $gp.editor.current.find( '.' + type ).attr( 'open', 'open' );
     222            } else {
     223                $gp.editor.current.find( '.' + type ).removeAttr( 'open' );
     224            }
     225        }
     226    }
     227
     228    $gp.editor.show = ( function( original ) {
     229        return function() {
     230            original.apply( $gp.editor, arguments );
     231
     232            applyDetailsState();
     233        }
     234    })( $gp.editor.show );
    126235
    127236    $gp.editor.install_hooks = ( function( original ) {
     
    140249                .on( 'click', 'button.translation-actions__rtl', switchTextDirection )
    141250                .on( 'focus', 'textarea', textareaAutosize )
     251                .on( 'click', 'summary', toggleDetails )
    142252                .on( 'click', 'button.button-menu__toggle', toggleLinkMenu );
    143253        }
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css

    r8751 r8766  
    11body, html {
    22    height: 100%;
     3}
     4
     5body,
     6html,
     7.gp-content,
     8.gp-content textarea,
     9.gp-content input {
     10    color: #191e23;
    311}
    412
     
    313321
    314322table.translations td.translation li {
    315     border-bottom: 1px dotted #eee;
     323    border-bottom: 1px dotted #e2e4e7;
    316324}
    317325
     
    346354table.locale-sub-projects td {
    347355    border: 0;
    348     border-bottom: 1px solid #eee;
    349     border-right: 1px solid #eee;
     356    border-bottom: 1px solid #e2e4e7;
     357    border-right: 1px solid #e2e4e7;
    350358}
    351359
     
    360368table.locale-sub-projects th:first-child,
    361369table.locale-sub-projects td:first-child {
    362     border-left: 1px solid #eee;
     370    border-left: 1px solid #e2e4e7;
    363371}
    364372
     
    447455.editor .meta {
    448456    background: #fff;
    449     border: 1px solid #eee;
     457    border: 1px solid #e2e4e7;
    450458    font-size: 13px;
    451459    margin: 0;
     
    458466.editor .meta h3 {
    459467    text-align: center;
    460     border-bottom: 1px solid #eee;
     468    border-bottom: 1px solid #e2e4e7;
    461469    margin-bottom: 15px;
    462470}
     
    859867    padding: 10px 20px;
    860868    color: #006799;
    861     border-left: 1px solid #eee;
     869    border-left: 1px solid #e2e4e7;
    862870    text-align: center;
    863871}
     
    10281036
    10291037.projects .project-status > div:not(:first-child) {
    1030     border-left: 1px solid #eee;
     1038    border-left: 1px solid #e2e4e7;
    10311039}
    10321040
     
    11611169    color: #509040;
    11621170    padding: 10px 0 10px 15px;
    1163     border-left: 1px solid #eee;
     1171    border-left: 1px solid #e2e4e7;
    11641172}
    11651173
     
    12321240    height: 20px;
    12331241    font: 20px/1 "dashicons";
    1234     border-left: 1px solid #eee;
     1242    border-left: 1px solid #e2e4e7;
    12351243    padding: 5px 0 5px 12px;
    12361244    box-shadow: inset 1px 0 0 #fff;
     
    14971505    float: right;
    14981506    margin: -30px 0 5px 5px;
    1499     background-color: #eee;
     1507    background-color: #e2e4e7;
    15001508    padding: 5px;
    15011509    border: 1px solid #dfdfdf;
     
    18061814.locale-project-contributors-table th {
    18071815    font-weight: bold;
    1808     border-bottom: 1px solid #eee;
     1816    border-bottom: 1px solid #e2e4e7;
    18091817}
    18101818
     
    18591867.locale-project-contributors-table tbody td {
    18601868    padding: 10px 0;
    1861     border-bottom: 1px solid #eee;
     1869    border-bottom: 1px solid #e2e4e7;
    18621870}
    18631871
     
    20022010
    20032011.consistency-table tr {
    2004     border-bottom: 1px solid #eee;
     2012    border-bottom: 1px solid #e2e4e7;
    20052013}
    20062014
     
    21532161    border: 0;
    21542162    background: #fff;
    2155     color: #333;
     2163    color: #191e23;
    21562164    outline: none;
    21572165    padding: 15px 0;
     
    21992207.editor-panel__left {
    22002208    flex: 1;
    2201     border-bottom: 3px solid #eee;
     2209    border-bottom: 3px solid #e2e4e7;
    22022210    min-width: 1%;
    22032211}
     
    22062214    .editor-panel__left {
    22072215        border-bottom: 0;
    2208         border-right: 3px solid #eee;
     2216        border-right: 3px solid #e2e4e7;
    22092217    }
    22102218}
     
    22192227    align-items: center;
    22202228    justify-content: flex-end;
    2221     border-bottom: 1px solid #eee;
    2222     background-color: #fbfbfb;
     2229    border-bottom: 1px solid #e2e4e7;
     2230    background-color: #f3f4f5;
    22232231    height: 40px;
    22242232}
     
    22552263    letter-spacing: 1px;
    22562264    text-transform: uppercase;
    2257     color: #666;
     2265    color: #191e23;
    22582266}
    22592267
     
    23042312
    23052313.panel-header-actions button:hover {
    2306     background: #eee;
     2314    background: #e2e4e7;
    23072315}
    23082316
     
    23472355
    23482356.panel-content summary:focus {
    2349     color: #0073aa;
     2357    color: #191e23;
    23502358}
    23512359
     
    23712379.source-details {
    23722380    padding: 0 10px;
     2381    font-size: 13px;
     2382}
     2383
     2384.source-details summary {
    23732385    color: #666;
    23742386}
    23752387
    2376 .source-details dl + dl {
    2377     margin-top: 10px;
    2378 }
    2379 
    2380 .source-details dt {
    2381     font-size: 12px;
    2382 }
    2383 
    2384 .source-details dd {
    2385     color: #333;
     2388.source-details details[open] summary {
     2389    margin: 0;
     2390}
     2391
     2392.source-details details + details{
     2393    margin-top: 5px;
    23862394}
    23872395
     
    23912399    border-top: 1px solid;
    23922400    border-bottom: 1px solid;
    2393     border-color: #eee;
     2401    border-color: #e2e4e7;
    23942402    background: #fff;
    23952403}
     
    24122420
    24132421.translation-form-wrapper {
    2414     border-bottom: 1px solid #eee;
     2422    border-bottom: 1px solid #e2e4e7;
    24152423    margin-left: -10px;
    24162424    margin-right: -10px;
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/translation-row-editor.php

    r8751 r8766  
    111111                    </div>
    112112
    113                     <details class="source-details">
    114                         <summary>Context</summary>
    115 
     113                    <div class="source-details">
    116114                        <?php if ( $t->context ): ?>
    117                             <dl class="source-details__context">
    118                                 <dt><?php _e( 'Context:', 'glotpress' ); ?></dt>
    119                                 <dd><span class="context bubble"><?php echo esc_translation( $t->context ); ?></span></dd>
    120                             </dl>
     115                            <details open class="source-details__context">
     116                                <summary>Context</summary>
     117                                <span class="context bubble"><?php echo esc_translation( $t->context ); ?></span>
     118                            </details>
    121119                        <?php endif; ?>
    122120                        <?php if ( $t->extracted_comments ) :
    123121                            $comments = trim( preg_replace( '/^translators:/ ', '', $t->extracted_comments ) );
    124122                            ?>
    125                             <dl class="source-details__comments">
    126                                 <dt><?php _e( 'Comment:', 'glotpress' ); ?></dt>
    127                                 <dd><?php echo make_clickable( esc_translation( $comments ) ); ?></dd>
    128                             </dl>
    129                         <?php endif; ?>
    130                         <?php references( $project, $t ); ?>
    131                     </details>
     123                            <details open class="source-details__comment">
     124                                <summary><?php _e( 'Comment', 'glotpress' ); ?></summary>
     125                                <p><?php echo make_clickable( esc_translation( $comments ) ); ?></p>
     126                            </details>
     127                        <?php endif; ?>
     128                        <?php if ( $t->references ) : ?>
     129                            <details class="source-details__references">
     130                                <summary>References</summary>
     131                                <?php wporg_references( $project, $t ); ?>
     132                            </details>
     133                        <?php endif; ?>
     134                    </div>
    132135
    133136                    <div class="translation-wrapper">
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js

    r8732 r8766  
    11( function( $ ){
    2     function fetchTranslationMemorySuggestions( $container, originalId, nonce ) {
     2    function fetchSuggestions( $container, apiUrl, originalId, nonce ) {
    33        var xhr = $.ajax( {
    4             url: window.WPORG_TRANSLATION_MEMORY_API_URL,
     4            url: apiUrl,
    55            data: {
    66                'original': originalId,
     
    3333    function maybeFetchTranslationMemorySuggestions() {
    3434        var $container = $gp.editor.current.find( '.suggestions__translation-memory' );
    35         if ( ! $container.length ) {
     35        if ( !$container.length ) {
    3636            return;
    3737        }
     
    4646        var nonce = $container.data( 'nonce' );
    4747
    48         fetchTranslationMemorySuggestions( $container, originalId , nonce );
    49     }
    50 
    51     function fetchOtherLanguageSuggestions( $container, originalId, nonce ) {
    52         var xhr = $.ajax( {
    53             url: window.WPORG_OTHER_LANGUAGES_API_URL,
    54             data: {
    55                 'original': originalId,
    56                 'nonce': nonce
    57             },
    58             dataType: 'json'
    59         } );
    60 
    61         xhr.done( function( response ) {
    62             $container.find( '.suggestions__loading-indicator' ).remove();
    63             if ( response.success ) {
    64                 $container.append( response.data );
    65             } else {
    66                 $container.append( $( '<span/>', { 'text': 'Error while loading suggestions.' } ) );
    67             }
    68             $container.addClass( 'initialized' );
    69         } );
    70 
    71         xhr.fail( function() {
    72             $container.find( '.suggestions__loading-indicator' ).remove();
    73             $container.append( $( '<span/>', { 'text': 'Error while loading suggestions.' } ) );
    74             $container.addClass( 'initialized' );
    75         } );
    76 
    77         xhr.always( function() {
    78             $container.removeClass( 'fetching' );
    79         } );
     48        fetchSuggestions( $container, window.WPORG_TRANSLATION_MEMORY_API_URL, originalId, nonce );
    8049    }
    8150
     
    9564        var nonce = $container.data( 'nonce' );
    9665
    97         fetchOtherLanguageSuggestions( $container, originalId , nonce );
     66        fetchSuggestions( $container, window.WPORG_OTHER_LANGUAGES_API_URL, originalId , nonce );
    9867    }
    9968
     
    12695
    12796            maybeFetchTranslationMemorySuggestions();
     97            maybeFetchOtherLanguageSuggestions();
    12898        }
    12999    })( $gp.editor.show );
     
    134104
    135105            $( $gp.editor.table )
    136                 .on( 'click', '.translation-suggestion', copySuggestion )
    137                 .on( 'click', '.suggestions__other-languages summary', maybeFetchOtherLanguageSuggestions );
     106                .on( 'click', '.translation-suggestion', copySuggestion );
    138107        }
    139108    })( $gp.editor.install_hooks );
Note: See TracChangeset for help on using the changeset viewer.