Making WordPress.org

Changeset 3852


Ignore:
Timestamp:
08/24/2016 08:22:35 PM (7 years ago)
Author:
coffee2code
Message:

developer.wordpress.org: Implement a tabbed interface for writing and previewing user contributed notes.

Also wraps form header in 'h3' tag so it appears in table of contents.

Props keesiemeijer.
See #1905.

Location:
sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/comments.php

    r3788 r3852  
    6666
    6767        <?php comment_form( array(
     68            'class_form'          => 'comment-form tab-container',
    6869            'comment_field'       => DevHub_User_Submitted_Content::wp_editor_comments(),
    69             'comment_notes_after' => '<p>' .
     70            'comment_notes_after' => DevHub_Note_Preview::comment_preview() .
     71                '<p>' .
    7072                __( 'Notes should supplement code reference entries, for example examples, tips, explanations, use-cases, and best practices.', 'wporg' ) .
    7173                '</p><p>' .
     
    8890        ) ); ?>
    8991
    90         <!-- Comment Preview -->
    91         <div id='comment-preview' class='comment byuser depth-1' style='display:none;'>
    92             <article class='comment-body'>
    93                 <header class='comment-meta'>
    94                     <div>
    95                         <?php _e( 'Preview', 'wporg' ); ?>
    96                         <span class='spinner' style='display:none'></span>
    97                     </div>
    98                 </header>
    99                 <div class='comment-content'></div>
    100             </article>
    101         </div>
    102 
    10392    <?php endif; ?>
    10493
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/functions.php

    r3790 r3852  
    259259function header_js() {
    260260    // Output CSS to hide markup with the class 'hide-if-js'. Ensures the markup is visible if JS is not present.
    261     echo "<script type=\"text/javascript\">jQuery( '<style>.hide-if-js { display: none; }</style>' ).appendTo( 'head' );</script>\n";
     261    // Add class 'js' to the body element if JavaScript is enabled
     262    echo "
     263    <script type=\"text/javascript\">
     264        jQuery( '<style>.hide-if-js { display: none; }</style>' ).appendTo( 'head' );
     265        jQuery( function($) {
     266            $( 'body' ).addClass('js');
     267        } );
     268    </script>\n";
    262269}
    263270
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/inc/user-content-preview.php

    r3790 r3852  
    3636    public static function scripts_and_styles() {
    3737        if ( is_singular() ) {
    38             wp_enqueue_script( 'wporg-developer-preview', get_template_directory_uri() . '/js/user-notes-preview.js', array( 'jquery', 'quicktags', 'wporg-developer-function-reference' ), '20160809', true );
     38            wp_enqueue_script( 'wporg-developer-tabs', get_template_directory_uri() . '/js/tabs.js', array( 'jquery' ), '20160809', true );
     39            wp_enqueue_script( 'wporg-developer-preview', get_template_directory_uri() . '/js/user-notes-preview.js', array( 'jquery', 'wporg-developer-function-reference', 'wporg-developer-tabs'  ), '20160809', true );
    3940            wp_localize_script( 'wporg-developer-preview', 'wporg_note_preview', array(
    40                 'ajaxurl' => admin_url( 'admin-ajax.php' ),
    41                 'nonce'   => wp_create_nonce( 'preview_nonce' ),
    42                 'preview' => __( 'preview note', 'wporg' ),
     41                'ajaxurl'       => admin_url( 'admin-ajax.php' ),
     42                'nonce'         => wp_create_nonce( 'preview_nonce' ),
     43                'preview'       => __( 'preview note', 'wporg' ),
     44                'preview_empty' => __( 'Nothing to preview', 'wporg' ),
     45                'is_admin'      => is_admin(),
    4346            ) );
    4447        }
     
    5558        }
    5659
    57         $comment = apply_filters('pre_comment_content', $_POST['preview_comment'] );
     60        $comment = apply_filters( 'pre_comment_content', $_POST['preview_comment'] );
    5861        $comment = wp_unslash( $comment );
    5962        $comment = apply_filters( 'get_comment_text', $comment );
    60         $comment = apply_filters( 'comment_text', $comment );       
     63        $comment = apply_filters( 'comment_text', $comment );
    6164
    6265        wp_send_json_success( array( 'comment' => $comment ) );
    6366    }
     67
     68    /**
     69     * Captures the comment-preview markup displayed (and populated) below the Add Note form.
     70     *
     71     * @access public
     72     * @static
     73     *
     74     * @return string Comment preview HTML markup.
     75     */
     76    public static function comment_preview() {
     77        if ( ! class_exists( 'DevHub_Note_Preview' ) ) {
     78            return '';
     79        }
     80
     81        ob_start();
     82?>
     83        <div id='comment-preview' class='tab-section comment byuser depth-1 comment-preview' aria-hidden="true">
     84            <article class='preview-body comment-body'>
     85                <div class='preview-content comment-content'></div>
     86            </article>
     87        </div>
     88        <?php
     89
     90        return ob_get_clean();
     91    }
    6492}
    6593
    66 
    6794DevHub_Note_Preview::init();
    68 
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/inc/user-content.php

    r3790 r3852  
    9090            }
    9191
    92             wp_enqueue_script( 'wporg-developer-user-notes', get_template_directory_uri() . '/js/user-notes.js', array( 'quicktags', 'wporg-developer-preview' ), '20160809', true );
     92            wp_enqueue_script( 'wporg-developer-user-notes', get_template_directory_uri() . '/js/user-notes.js', array( 'quicktags' ), '20160809', true );
    9393            if ( get_option( 'thread_comments' ) ) {
    9494                wp_enqueue_script( 'comment-reply' );
     
    127127    public static function wp_editor_comments() {
    128128        ob_start();
    129         echo '<p class="comment-form-comment"><label for="comment">' . _x( 'Add Note or Feedback', 'noun', 'wporg' ) . '</label>';
     129        echo '<h3><label for="comment">' . _x( 'Add Note or Feedback', 'noun', 'wporg' ) . '</label></h3>';
     130
     131        if ( class_exists( 'DevHub_Note_Preview' ) ) {
     132            echo '<ul class="tablist" style="display:none;">';
     133            echo '<li><a href="#comment-form-comment">' . __( 'Write', 'wporg' ) . '</a></li>';
     134            echo '<li><a href="#comment-preview">' . __( 'Preview', 'wporg' ) . '</a></li></ul>';
     135        }
     136
     137        $style = '<style type="text/css">';
     138        ob_start();
     139        include get_stylesheet_directory() . '/stylesheets/editor-style.css';
     140        $style .= ob_get_clean();
     141        $style .=' </style>';
     142
     143        echo '<div class="comment-form-comment tab-section" id="comment-form-comment">';
    130144        wp_editor( '', 'comment', array(
    131145            'media_buttons' => false,
     146            'editor_css'    => $style,
    132147            'textarea_name' => 'comment',
    133148            'textarea_rows' => 8,
     
    138153            'tinymce'       => false,
    139154        ) );
    140         echo '</p>';
     155        echo '</div>';
    141156        return ob_get_clean();
    142157    }
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/js/user-notes-preview.js

    r3788 r3852  
    44 */
    55
    6 var wporg_developer_note_preview = ( function( $ ) {
     6( function( $ ) {
    77
    8     var textarea, preview, previewContent, spinner;
     8    var textarea, textareaHeight, text, preview, previewContent, tabs, processing, spinner;
    99
    10     function init( textarea_selector, preview_selector ) {
     10    function init() {
    1111
    12         textarea = $( textarea_selector );
    13         preview = $( preview_selector );
     12        if ( undefined === wporg_note_preview ) {
     13            return;
     14        }
    1415
    15         if ( textarea.length && preview.length && ( undefined !== wporg_note_preview ) ) {
     16        textarea = $( '.comment-form textarea' );
     17        preview = $( '#comment-preview' );
     18        tabs = $( '#commentform .tablist' ).find( 'a' );
     19        spinner = $( '<span class="spinner" style="display:none;"></span>' );
     20        text = '';
     21        processing = false;
    1622
    17             previewContent = $( '.comment-content', preview );
    18             spinner = $( '.spinner', preview );
     23        if ( textarea.length && preview.length && tabs.length ) {
    1924
    20             if ( previewContent.length && spinner.length ) {
     25            // Append spinner to preview tab
     26            tabs.parents( 'li[role="presentation"]:last' ).append( spinner );
    2127
    22                 add_preview_button();
     28            previewContent = $( '.preview-content', preview );
    2329
    24                 var current_text = textarea.val();
     30            if ( previewContent.length ) {
    2531
    26                 if ( current_text.length ) {
    27                     update_preview( current_text );
     32                if ( !textarea.val().length ) {
     33                    previewContent.text( wporg_note_preview.preview_empty );
    2834                }
    2935
    30                 add_preview_events();
     36                previewEvents();
    3137            }
    3238        }
    3339    }
    3440
    35     function add_preview_button() {
    36         QTags.addButton( 'preview', wporg_note_preview.preview, function() {
    37             var pos = preview.position();
    38             $( 'html,body' ).animate( {
    39                 scrollTop: pos.top
    40             }, 1000 );
     41    function previewEvents() {
     42
     43        tabs.on( "keydown.note_preview, click.note_preview", function( e ) {
     44
     45            if ( 'comment-preview' === $( this ).attr( 'aria-controls' ) ) {
     46
     47                if ( !processing ) {
     48                    current_text = $.trim( textarea.val() );
     49                    if ( current_text.length && ( current_text !== wporg_note_preview.preview_empty ) ) {
     50                        if ( wporg_note_preview.preview_empty === previewContent.text() ) {
     51                            // Remove "Nothing to preview" if there's new current text.
     52                            previewContent.text( '' );
     53                        }
     54                        // Update the preview.
     55                        updatePreview( current_text );
     56                    } else {
     57                        previewContent.text( wporg_note_preview.preview_empty );
     58                    }
     59                }
     60
     61                // Remove outline from tab if clicked.
     62                if ( "click" === e.type ) {
     63                    $( this ).blur();
     64                }
     65            } else {
     66                textarea.focus();
     67            }
     68        } );
     69
     70        // Set preview heigth when the textarea is visible
     71        $( '#add-user-note, .table-of-contents a[href="#add-note-or-feedback"]' ).click( function( e ) {
     72            e.preventDefault();
     73            tabs.parents( '.tablist' ).show();
     74            setTimeout( function() {
     75                textareaHeight = textarea.outerHeight( true );
     76                if ( 0 < textareaHeight ) {
     77                    preview.css( 'min-height', textareaHeight + 'px' );
     78                }
     79            }, 500 );
    4180        } );
    4281    }
    4382
    44     function add_preview_events() {
     83    function updatePreview( content ) {
    4584
    46         // Update Preview after QuickTag button is clicked.
    47         var buttons = $( '#qt_comment_toolbar' ).find( 'input' ).not( '#qt_comment_preview' );
    48         buttons.on( 'click', function() {
    49             // Set timeout to let the quicktags do it's thing first.
    50             setTimeout( function() {
    51                 update_preview( textarea.val() );
    52             }, 500 );
    53         } );
     85        // Don't update preview if nothing changed
     86        if ( text == content ) {
     87            spinner.hide();
     88            return;
     89        }
    5490
    55         // Update Preview after keykup event.
    56         // Delay updating the preview by 2 seconds to not overload the server.
    57         textarea.bind( 'keyup', debounce( function( e ) {
    58             update_preview( $( this ).val() );
    59         }, 2000 ) );
     91        spinner.show();
     92        text = content;
     93        processing = true;
    6094
    61         // Display a spinner as soon as the comment form changes input.
    62         textarea.bind( 'input propertychange selectionchange', function( e ) {
    63             spinner.show();
    64         } );
    65     }
    66 
    67     function update_preview( content ) {
    68         spinner.show();
    6995        $.post( wporg_note_preview.ajaxurl, {
    7096            action: "preview_comment",
     
    74100
    75101        .done( function( response ) {
    76             update_preview_html( response.data.comment );
     102            updatePreview_HTML( response.data.comment );
    77103        } )
    78104
     
    83109        .always( function( response ) {
    84110            spinner.hide();
     111            processing = false;
     112
     113            // Make first child of the preview focusable
     114            preview.children().first().attr( {
     115                'tabindex': '0'
     116            } );
    85117        } );
    86118    }
    87119
    88120    // Add toggle links to source code in preview if needed.
    89     function update_source_code() {
    90 
     121    function updateSourceCode() {
    91122        if ( undefined !== wporg_developer ) {
    92123            wporg_developer.sourceCodeDisplay( preview );
     
    94125    }
    95126
    96     function update_preview_html( content ) {
     127    function updatePreview_HTML( content ) {
    97128        // Update preview content
    98129        previewContent.html( content );
     
    103134
    104135        // Add toggle link to source code in preview if needed.
    105         update_source_code();
     136        updateSourceCode();
    106137        spinner.hide();
    107138    }
    108139
    109     // https://remysharp.com/2010/07/21/throttling-function-calls
    110     function debounce( fn, delay ) {
    111         var timer = null;
    112         return function() {
    113             var context = this,
    114                 args = arguments;
    115             clearTimeout( timer );
    116             timer = setTimeout( function() {
    117                 fn.apply( context, args );
    118             }, delay );
    119         };
    120     }
    121 
    122     return {
    123         init: init
    124     }
     140    init();
    125141
    126142} )( jQuery );
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/js/user-notes.js

    r3788 r3852  
    1313
    1414    function showCommentForm() {
    15         $( '#respond, #add-user-note' ).toggle();
    16        
    17         var preview = $( '#comment-preview' );
    18         if( preview.length && ( wporg_developer_note_preview !== undefined ) ) {
    19             preview.show();
     15        $( '#respond' ).show();
     16        $( '#add-user-note').hide();
    2017
    21             //Initialize preview with textarea and preview selectors
    22             wporg_developer_note_preview.init( '.comment-form textarea', '#comment-preview' );
    23         }
     18        var target = $( '#commentform #add-note-or-feedback' );
     19        if ( target.length ) {
     20            var pos = target.offset();
    2421
    25         if ( pos = $( '#submit' ).position() ) {
    26             if ( pos.top < $(window).scrollTop() ) {
    27                 // Scroll up
    28                 $( 'html,body' ).animate( {scrollTop:pos.top}, 1000 );
    29             }
    30             else if ( pos.top + jQuery("selector").height() > $(window).scrollTop() + (window.innerHeight || document.documentElement.clientHeight) ){
    31                 // Scroll down
    32                 $( 'html,body' ).animate( {scrollTop:pos.top - (window.innerHeight || document.documentElement.clientHeight) + $( '#submit' ).height() + 30}, 1000 );
    33             }
     22            $( 'html,body' ).animate( {
     23                scrollTop: pos.top
     24            }, 1000 );
    3425        }
    3526    }
    3627
    3728    $( '#respond, #add-user-note' ).toggle();
    38     $( '#add-user-note' ).click( function( e ) {
     29    $( '#add-user-note, .table-of-contents a[href="#add-note-or-feedback"]' ).click( function( e ) {
    3930        e.preventDefault();
    4031
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/scss/main.scss

    r3788 r3852  
    325325        clear: both;
    326326        margin: 0 0 1.5em;
     327    }
     328
     329    /* =Tabs
     330    ----------------------------------------------- */
     331
     332    .tablist {
     333        margin: 0;
     334    }
     335    .tablist li {
     336        display: inline-block;
     337        list-style: none;
     338    }
     339    .tablist a {
     340        border-color: none;
     341        background-color: transparent;
     342        border-color: transparent;
     343        border-image: none;
     344        border-style: solid solid none;
     345        border-width: 1px 1px 0;   
     346        display: inline-block;
     347        padding: .5em 1em;
     348        margin-bottom:-1px;
     349    }
     350    .tablist a[aria-selected],
     351    .tablist a:focus {
     352        background-color: #fff;
     353        border-color: #ccc;
     354        border-radius: 3px 3px 0 0;
     355        color: #333; 
     356    }
     357    .tab-section {
     358        margin-top: 0;
     359        padding: 0;
     360        border: none;
     361    }
     362    .tab-section[aria-hidden="true"] {
     363        display: none;
     364    }
     365    .tab-section:focus {
     366        background: #eee;
     367        outline: thin dotted;
    327368    }
    328369
     
    11891230            overflow: auto;
    11901231            border: 1px solid #dfdfdf;
    1191             border-radius: 2px;
     1232            border-radius: 0 2px 2px 2px;
    11921233
    11931234            article {
     
    11961237        }
    11971238
    1198         #comment-preview {
     1239        #comment-preview,
     1240        .js & .comment-form-comment {
     1241            margin-top: 0;
     1242            border: 1px solid #ccc;
     1243            border-radius: 0 3px 3px 3px;
    11991244            clear:both;
     1245        }
     1246
     1247        #comment-preview.tab-section-selected {
     1248            border-radius: 3px;
    12001249        }
    12011250
     
    12041253        }
    12051254
    1206         #comment-preview .spinner {
     1255        label[for=comment],
     1256        .comment-form-comment,
     1257        .comment-preview {
     1258            margin-bottom: 1em;
     1259        }
     1260
     1261        .js & .comment-form-comment {
     1262            padding: 0 .7em .7em;
     1263        }
     1264
     1265        .tablist .spinner {
    12071266            background: url("/wp-includes/images/spinner-2x.gif") no-repeat scroll 0 50%;
    12081267            -webkit-background-size: 20px 20px;
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/stylesheets/main.css

    r3788 r3852  
    287287  /* Clearing */
    288288  /* =Content
     289    ----------------------------------------------- */
     290  /* =Tabs
    289291    ----------------------------------------------- */
    290292  /* =Media
     
    678680}
    679681
     682.devhub-wrap .tablist {
     683  margin: 0;
     684}
     685
     686.devhub-wrap .tablist li {
     687  display: inline-block;
     688  list-style: none;
     689}
     690
     691.devhub-wrap .tablist a {
     692  border-color: none;
     693  background-color: transparent;
     694  border-color: transparent;
     695  border-image: none;
     696  border-style: solid solid none;
     697  border-width: 1px 1px 0;
     698  display: inline-block;
     699  padding: .5em 1em;
     700  margin-bottom: -1px;
     701}
     702
     703.devhub-wrap .tablist a[aria-selected],
     704.devhub-wrap .tablist a:focus {
     705  background-color: #fff;
     706  border-color: #ccc;
     707  border-radius: 3px 3px 0 0;
     708  color: #333;
     709}
     710
     711.devhub-wrap .tab-section {
     712  margin-top: 0;
     713  padding: 0;
     714  border: none;
     715}
     716
     717.devhub-wrap .tab-section[aria-hidden="true"] {
     718  display: none;
     719}
     720
     721.devhub-wrap .tab-section:focus {
     722  background: #eee;
     723  outline: thin dotted;
     724}
     725
    680726.devhub-wrap .page-content img.wp-smiley,
    681727.devhub-wrap .entry-content img.wp-smiley,
     
    15641610  overflow: auto;
    15651611  border: 1px solid #dfdfdf;
    1566   border-radius: 2px;
     1612  border-radius: 0 2px 2px 2px;
    15671613}
    15681614
     
    15751621}
    15761622
    1577 .devhub-wrap.single-wp-parser-function #comment-preview, .devhub-wrap.single-wp-parser-method #comment-preview, .devhub-wrap.single-wp-parser-hook #comment-preview, .devhub-wrap.single-wp-parser-class #comment-preview {
     1623.devhub-wrap.single-wp-parser-function #comment-preview,
     1624.js .devhub-wrap.single-wp-parser-function .comment-form-comment, .devhub-wrap.single-wp-parser-method #comment-preview,
     1625.js .devhub-wrap.single-wp-parser-method .comment-form-comment, .devhub-wrap.single-wp-parser-hook #comment-preview,
     1626.js .devhub-wrap.single-wp-parser-hook .comment-form-comment, .devhub-wrap.single-wp-parser-class #comment-preview,
     1627.js .devhub-wrap.single-wp-parser-class .comment-form-comment {
     1628  margin-top: 0;
     1629  border: 1px solid #ccc;
     1630  border-radius: 0 3px 3px 3px;
    15781631  clear: both;
     1632}
     1633
     1634.devhub-wrap.single-wp-parser-function #comment-preview.tab-section-selected, .devhub-wrap.single-wp-parser-method #comment-preview.tab-section-selected, .devhub-wrap.single-wp-parser-hook #comment-preview.tab-section-selected, .devhub-wrap.single-wp-parser-class #comment-preview.tab-section-selected {
     1635  border-radius: 3px;
    15791636}
    15801637
     
    15831640}
    15841641
    1585 .devhub-wrap.single-wp-parser-function #comment-preview .spinner, .devhub-wrap.single-wp-parser-method #comment-preview .spinner, .devhub-wrap.single-wp-parser-hook #comment-preview .spinner, .devhub-wrap.single-wp-parser-class #comment-preview .spinner {
     1642.devhub-wrap.single-wp-parser-function label[for=comment],
     1643.devhub-wrap.single-wp-parser-function .comment-form-comment,
     1644.devhub-wrap.single-wp-parser-function .comment-preview, .devhub-wrap.single-wp-parser-method label[for=comment],
     1645.devhub-wrap.single-wp-parser-method .comment-form-comment,
     1646.devhub-wrap.single-wp-parser-method .comment-preview, .devhub-wrap.single-wp-parser-hook label[for=comment],
     1647.devhub-wrap.single-wp-parser-hook .comment-form-comment,
     1648.devhub-wrap.single-wp-parser-hook .comment-preview, .devhub-wrap.single-wp-parser-class label[for=comment],
     1649.devhub-wrap.single-wp-parser-class .comment-form-comment,
     1650.devhub-wrap.single-wp-parser-class .comment-preview {
     1651  margin-bottom: 1em;
     1652}
     1653
     1654.js .devhub-wrap.single-wp-parser-function .comment-form-comment, .js .devhub-wrap.single-wp-parser-method .comment-form-comment, .js .devhub-wrap.single-wp-parser-hook .comment-form-comment, .js .devhub-wrap.single-wp-parser-class .comment-form-comment {
     1655  padding: 0 .7em .7em;
     1656}
     1657
     1658.devhub-wrap.single-wp-parser-function .tablist .spinner, .devhub-wrap.single-wp-parser-method .tablist .spinner, .devhub-wrap.single-wp-parser-hook .tablist .spinner, .devhub-wrap.single-wp-parser-class .tablist .spinner {
    15861659  background: url("/wp-includes/images/spinner-2x.gif") no-repeat scroll 0 50%;
    15871660  -webkit-background-size: 20px 20px;
Note: See TracChangeset for help on using the changeset viewer.