Making WordPress.org

Ticket #1504: 1504.patch

File 1504.patch, 40.3 KB (added by keesiemeijer, 7 years ago)

First pass of adding feedback to user contributed notes

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

     
    3232                <?php endif; // check for comment navigation ?>
    3333
    3434                <ol class="comment-list">
    35                         <?php
     35                        <?php
     36                                $feedback_editor = false;
     37
    3638                                /* Loop through and list the comments. Tell wp_list_comments()
    3739                                 * to use wporg_developer_comment() to format the comments.
    3840                                 * If you want to override this in a child theme, then you can
     
    4446                                } else {
    4547                                        $ordered_comments = wporg_developer_get_ordered_notes();
    4648                                        if ( $ordered_comments ) {
    47                                                 wp_list_comments( array( 'callback' => 'wporg_developer_user_note' ), $ordered_comments );
     49                                                $feedback_editor = array_filter(  wp_list_pluck( $ordered_comments, 'show_editor') );
     50                                                wporg_developer_list_notes( $ordered_comments, array('avatar_size' => 32) );
    4851                                        }
    4952                                }
    5053                        ?>
     
    6265
    6366        <?php if ( \DevHub\is_parsed_post_type() && DevHub\can_user_post_note( true, get_the_ID() ) ) : ?>
    6467
    65                 <p id="add-user-note" style="display:none;"><a href=""><?php _e( 'Have a note or feedback to contribute?', 'wporg' ); ?></a></p>
     68                <?php
     69                $add_note_style = !empty( $feedback_editor ) ? '' : 'display:none;'; ?>
     70                <p id="add-user-note" style="<?php echo $add_note_style; ?>"><a href="<?php echo user_trailingslashit( get_permalink() ) . '#respond'; ?>"><?php _e( 'Have a note or feedback to contribute?', 'wporg' ); ?></a></p>
    6671
    67                 <?php comment_form( array(
    68                         'class_form'          => 'comment-form tab-container',
    69                         'comment_field'       => DevHub_User_Submitted_Content::wp_editor_comments(),
    70                         'comment_notes_after' => DevHub_Note_Preview::comment_preview() .
    71                                 '<p>' .
     72                <?php
     73                $args = array(
     74                        'comment_notes_after' => '<p>' .
    7275                                __( 'Notes should supplement code reference entries, for example examples, tips, explanations, use-cases, and best practices.', 'wporg' ) .
    7376                                '</p><p>' .
    7477                                __( 'Feedback can be to report errors or omissions with the documentation on this page. Such feedback will not be publicly posted.', 'wporg' ) .
     
    8285                                sprintf( __( '<strong>NOTE:</strong> All contributions are licensed under <a href="%s">GFDL</a> and are moderated before appearing on the site.', 'wporg' ), 'https://gnu.org/licenses/fdl.html' ) .
    8386                                '</p>',
    8487                        'label_submit'        => __( 'Add Note or Feedback', 'wporg' ),
     88                        'cancel_reply_link'   => '',
    8589                        'must_log_in'         => '<p>' . sprintf(
    8690                                __( 'You must <a href="%s">log in</a> before being able to contribute a note or feedback.', 'wporg' ),
    8791                                'https://wordpress.org/support/bb-login.php?redirect_to=' . urlencode( get_comments_link() )
    8892                        ) . '</p>',
    89                         'title_reply'         =>  '', //'Add Example'
    90                 ) ); ?>
     93                        'title_reply'         => '', //'Add Example'
     94                        'title_reply_to'      => '',
     95                );
     96               
     97                if ( class_exists( 'DevHub_Note_Preview' ) ) {
     98                        $args['comment_notes_after'] = DevHub_Note_Preview::comment_preview() . $args['comment_notes_after'];
     99                        $args['class_form']          = 'comment-form tab-container';
     100                }
    91101
     102                if( class_exists( 'DevHub_User_Submitted_Content') ) {
     103                        $args['comment_field'] = DevHub_User_Submitted_Content::wp_editor_comments();
     104                }
     105               
     106                // Insert comment form if feedback form is not already used
     107                if( empty( $feedback_editor ) ) {
     108                        comment_form( $args );
     109                }       
     110                ?>
    92111        <?php endif; ?>
    93112
    94113        <?php if ( ! \DevHub\is_parsed_post_type() && comments_open() ) : ?>
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/inc/template-tags.php

     
    7575        if ( ! function_exists( 'wporg_developer_get_ordered_notes' ) ) :
    7676                /**
    7777                 * Get contibuted notes ordered by vote
    78                  *
    79                  * By default only top level comments are returned.
    80                  * If child notes are included use wp_list_comments() or a custom walker for display.
    81                  * unapproved notes for the current user are included.
    8278                 *
     79                 * Only the parent notes are ordered by vote count.
     80                 * Child notes are added to to the parent note 'child_notes' property.
     81                 * Unapproved notes for the current user are included.
     82                 * Use wporg_developer_list_notes() to display the notes.
     83                 *
    8384                 * @param integer $post_id Optional. Post id to get comments for
    8485                 * @param array $args Arguments used for get_comments().
    8586                 * @return array Array with comment objects
     
    9293                                $post_id = get_the_ID();
    9394                        }
    9495
    95                         $order    = array();
    9696                        $defaults = array(
    9797                                'post__in'           => array( $post_id ),
    9898                                'type'               => 'comment',
    9999                                'status'             => 'approve',
    100100                                'include_unapproved' => array_filter( array( get_current_user_id() ) ),
    101                                 'parent'             => false,
    102101                        );
    103102
    104103                        if ( is_super_admin() ) {
    105104                                $defaults['status'] = 'all';
    106105                        }
    107106
    108                         $args = wp_parse_args( $args, $defaults );
     107                        $args     = wp_parse_args( $args, $defaults );
     108                        $comments = get_comments( $args );
    109109
    110                         $comments = get_comments( $args );
    111                
    112110                        if ( ! $comments ) {
    113111                                return;
    114112                        }
    115113
     114                        // Check if the current page is a reply to a note.
     115                        $reply_id = 0;
     116                        if ( isset( $_GET['replytocom'] ) && $_GET['replytocom'] ) {
     117                                $reply_id = absint( $_GET['replytocom'] );
     118                        }
     119
     120                        $order = $children = array();
     121                        $voting = class_exists( 'DevHub_User_Contributed_Notes_Voting' );
     122
     123                        // Remove child notes and add the vote count order for parent notes
    116124                        foreach ( $comments as $key => $comment ) {
    117                                 $order[ $key ] = (int) DevHub_User_Contributed_Notes_Voting::count_votes( $comment->comment_ID, 'difference' );
     125                                if ( 0 === (int) $comment->comment_parent ) {
     126                                        $vote_count = $voting ? (int) DevHub_User_Contributed_Notes_Voting::count_votes( $comment->comment_ID, 'difference' ) : 0;
     127                                        $order[ $key ] = $vote_count;
     128                                } else {
     129                                        unset( $comments[ $key ] );
     130                                        $children[ $comment->comment_parent ][] = $comment;
     131                                }
    118132                        }
    119133
     134                        $show_editor = false;
     135
     136                        // Add children notes to their parents.
     137                        foreach ( $comments as $key => $comment ) {
     138                                $comments[ $key ]->child_notes = array();
     139                                $comments[ $key ]->show_editor  = false;
     140
     141
     142                                if ( array_key_exists( $comment->comment_ID, $children ) ) {
     143                                        $comments[ $key ]->child_notes = array_reverse( $children[ $comment->comment_ID ] );
     144                                }
     145
     146                                if ( !$show_editor && ( $reply_id && ( $reply_id === (int) $comment->comment_ID ) ) ) {
     147                                        // Show the editor when replying to this parent comment
     148                                        $comments[ $key ]->show_editor = true;
     149                                        $show_editor = true;
     150                                }
     151                        }
     152
    120153                        // sort the posts by votes
    121154                        array_multisort( $order, SORT_DESC, $comments );
    122155
     
    124157                }
    125158        endif;
    126159
     160        if ( !function_exists( 'wporg_developer_list_notes' ) ) :
     161                /**
     162                 * List user contributed notes.
     163                 *
     164                 * @param array   $comments Array with comment objects.
     165                 * @param array   $args Comment display arguments.
     166                 * @return void
     167                 */
     168                function wporg_developer_list_notes( $comments, $args ) {
     169                        $can_user_post_note = DevHub\can_user_post_note( true, get_the_ID() );
     170                        $is_user_logged_in  = is_user_logged_in();
     171                        $user_content       = class_exists( 'DevHub_User_Submitted_Content' );
     172                        $display_editor     = $is_user_logged_in && $can_user_post_note && $user_content;
     173
     174                        foreach ( $comments as $comment ) {
     175
     176                                $comment_id = $comment->comment_ID;
     177
     178                                // Display parent comment.
     179                                wporg_developer_user_note( $comment, $args, 1 );
     180
     181                                // Show or hide feedback notes.
     182                                $class = $comment->show_editor ? '' : ' hide-if-js';
     183                                echo "<section id='feedback-{$comment_id}' class='feedback{$class}'>\n";
     184
     185                                // Display child comments.
     186                                if ( !empty( $comment->child_notes ) ) {
     187
     188                                        echo "<h4 class='feedback-title'>Feedback</h4>\n";
     189                                        echo "<ul class='children'>\n";
     190                                        foreach ( $comment->child_notes as $child_note ) {
     191                                                wporg_developer_user_note( $child_note, $args, 2, $comment->show_editor );
     192                                        }
     193                                        echo "</ul>\n";
     194                                }
     195
     196                                // Display feedback form.
     197                                if ( $display_editor ) {
     198                                        // Show or hide the editor depending if we're adding feedback.
     199                                        $display = $comment->show_editor ? 'show' : 'hide';
     200                                        echo DevHub_User_Submitted_Content::wp_editor_feedback( $comment, $display );
     201                                }
     202                                echo "</section><!-- .feedback -->\n";
     203
     204                                // Feedback links to log in, add feedback or show feedback.
     205                                echo "<footer class='feedback-links' >\n";
     206                                if ( $can_user_post_note ) {
     207                                        $feedback_link = trailingslashit( get_permalink() ) . "?replytocom={$comment_id}#feedback-{$comment_id}";
     208                                        $display = '';
     209                                        $aria = '';
     210                                        echo '';
     211                                        if ( !$is_user_logged_in ) {
     212                                                $class = 'login';
     213                                                $feedback_text = __( 'Log in to add feedback', 'wporg' );
     214                                                $feedback_link = 'https://wordpress.org/support/bb-login.php?redirect_to=' . urlencode( $feedback_link );
     215                                        } else {
     216                                                $class ='add';
     217                                                $feedback_text = __( 'Add feedback to this note', 'wporg' );
     218                                                $aria = " aria-expanded='false' aria_controls='feedback-editor-{$comment_id}' aria-label='" . esc_attr( $feedback_text ) . "'";
     219                                                // Hide 'add feedback' if editor is displayed.
     220                                                $display = $display_editor && $comment->show_editor ? ' style="display:none"' : '';
     221                                        }
     222
     223                                        echo '<a class="feedback-' . $class . '" href="' . esc_url( $feedback_link ) . '"' . $display . $aria .' rel="nofollow">' . $feedback_text . '</a>';
     224                                }
     225
     226                                // close parent list item
     227                                echo "</footer>\n</article><!-- .comment-body -->\n</li>\n";
     228                        }
     229                }
     230        endif;
     231
    127232        if ( ! function_exists( 'wporg_developer_user_note' ) ) :
    128233                /**
    129234                 * Template for user contributed notes.
     235                 *
     236                 * @param object $comment Comment object.
     237                 * @param array $args Arguments.
     238                 * @param int $depth Nested comment depth.
     239                 * @return void
    130240                 */
    131241                function wporg_developer_user_note( $comment, $args, $depth ) {
    132                         $GLOBALS['comment'] = $comment;
    133                         $count = (int) DevHub_User_Contributed_Notes_Voting::count_votes( $comment->comment_ID, 'difference' );
    134                         $curr_user_note = DevHub_User_Contributed_Notes_Voting::is_current_user_note( $comment->comment_ID );
     242                        $GLOBALS['comment']       = $comment;
     243                        $GLOBALS['comment_depth'] = $depth;
    135244
     245                        $approved           = ( 0 < (int) $comment->comment_approved ) ? true : false;
     246                        $parent             = ( 0 === (int) $comment->comment_parent ) ? true : false;
     247                        $voting             = class_exists( 'DevHub_User_Contributed_Notes_Voting' );
     248                        $count              = $voting ? (int)  DevHub_User_Contributed_Notes_Voting::count_votes( $comment->comment_ID, 'difference' ) : 0;
     249                        $curr_user_note     = $voting ? (bool) DevHub_User_Contributed_Notes_Voting::is_current_user_note( $comment->comment_ID ) : false;
     250                        $is_user_logged_in  = is_user_logged_in();
     251                        $can_user_post_note = DevHub\can_user_post_note( true, get_the_ID() );
     252
     253                        // Classes
    136254                        $comment_class = array();
     255
    137256                        if ( -1 > $count ) {
    138257                                $comment_class[] = 'bad-note';
    139258                        }
     259
    140260                        if ( $curr_user_note ) {
    141261                                $comment_class[] = 'user-submitted-note';
    142262                        }
     263
     264                        if ( !$approved ) {
     265                                $comment_class[] = 'user-note-moderated';
     266                        }
     267
     268                        // This would all be moot if core passed the $comment context for 'get_comment_author_link' filter
     269                        if ( $comment->user_id ) {
     270                                $commenter = get_user_by( 'id', $comment->user_id );
     271                                $url = 'https://profiles.wordpress.org/' . esc_attr( $commenter->user_nicename ) . '/';
     272                                $author = get_the_author_meta( 'display_name', $comment->user_id );
     273                        } else {
     274                                $url = $comment->comment_author_url;
     275                                $author = $comment->comment_author;
     276                        }
     277
     278                        $comment_author_link = '';
     279                        if ( $url ) {
     280                                $comment_author_link = "<a href='$url' rel='external nofollow' class='url'>";
     281                        }
     282                        $comment_author_link .= $author;
     283                        if ( $url ) {
     284                                $comment_author_link .= '</a>';
     285                        }
     286
     287                        $date = sprintf( _x( '%1$s ago', '%1$s = human-readable time difference', 'wporg' ),
     288                                human_time_diff( get_comment_time( 'U' ),
     289                                        current_time( 'timestamp' ) )
     290                        );
    143291                        ?>
     292                        <li id="comment-<?php comment_ID(); ?>" data-comment-id="<?php echo $comment->comment_ID;  ?>" <?php comment_class( implode( ' ', $comment_class ) ); ?>>
     293                        <article id="div-comment-<?php comment_ID(); ?>" class="comment-body">
    144294
    145                         <li id="comment-<?php comment_ID(); ?>" <?php comment_class( implode( ' ', $comment_class ) ); ?>>
    146                         <article id="div-comment-<?php comment_ID(); ?>" class="comment-body">
    147                                 <a href="#comment-content-<?php echo $comment->comment_ID; ?>" class="screen-reader-text"><?php _e( 'Skip to note content', 'wporg' ); ?></a>
     295                        <?php if ( $parent ) : ?>
     296                                <a href="#comment-content-<?php echo $comment->comment_ID; ?>" class="screen-reader-text"><?php _e( 'Skip to note content', 'wporg' ); ?></a>
    148297                                <header class="comment-meta">
    149                                         <?php DevHub_User_Contributed_Notes_Voting::show_voting(); ?>
     298
     299                                <?php
     300                                if ( $voting ) {
     301                                        DevHub_User_Contributed_Notes_Voting::show_voting();
     302                                }
     303                                ?>
    150304                                        <div class="comment-author vcard">
    151305                                                <span class="comment-author-attribution">
    152                                                 <?php if ( 0 != $args['avatar_size'] ) {
    153                                                                 echo get_avatar( $comment, $args['avatar_size'] );
    154                                                 } ?>
    155 
    156306                                                <?php
    157                                                         // This would all be moot if core passed the $comment context for 'get_comment_author_link' filter
    158                                                         if ( $comment->user_id ) {
    159                                                                 $commenter = get_user_by( 'id', $comment->user_id );
    160                                                                 $url = 'https://profiles.wordpress.org/' . esc_attr( $commenter->user_nicename ) . '/';
    161                                                                 $author = get_the_author_meta( 'display_name', $comment->user_id );
    162                                                         } else {
    163                                                                 $url = $comment->comment_author_url;
    164                                                                 $author = $comment->comment_author;
    165                                                         }
     307                                                if ( 0 != $args['avatar_size'] ) {
     308                                                        echo get_avatar( $comment, $args['avatar_size'] );
     309                                                }
    166310
    167                                                         $comment_author_link = '';
    168                                                         if ( $url ) {
    169                                                                 $comment_author_link = "<a href='$url' rel='external nofollow' class='url'>";
    170                                                         }
    171                                                         $comment_author_link .= $author;
    172                                                         if ( $url ) {
    173                                                                 $comment_author_link .= '</a>';
    174                                                         }
    175 
    176                                                         printf( __( 'Contributed by %s', 'wporg' ), sprintf( '<cite class="fn">%s</cite>', $comment_author_link ) );
     311                                                printf( __( 'Contributed by %s', 'wporg' ), sprintf( '<cite class="fn">%s</cite>', $comment_author_link ) );
    177312                                                ?>
    178313
    179314                                                </span>
    180315                                                &mdash;
    181316                                                <a href="<?php echo esc_url( get_comment_link( $comment->comment_ID ) ); ?>">
    182317                                                        <time datetime="<?php comment_time( 'c' ); ?>">
    183                                                         <?php
    184                                                                 printf( _x( '%1$s ago', '%1$s = human-readable time difference', 'wporg' ),
    185                                                                         human_time_diff( get_comment_time( 'U' ),
    186                                                                         current_time( 'timestamp' ) )
    187                                                                 );
    188                                                         ?>
     318                                                        <?php echo $date;  ?>
    189319                                                        </time>
    190320                                                </a>
    191                                                 <?php edit_comment_link( __( 'Edit', 'wporg' ), '<span class="edit-link">&mdash; ', '</span>' ); ?>
     321                                                <?php edit_comment_link( __( 'Edit', 'wporg' ), '<span class="edit-link">&mdash; ', '</span> ' ); ?>
     322                                                <?php if ( !$approved ) : ?>
     323                                                        &mdash; <span class="comment-awaiting-moderation"><?php _e( 'awaiting moderation', 'wporg' ); ?></span>
     324                                                <?php endif; ?>
     325
    192326                                        </div>
    193327                                </header>
    194328                                <!-- .comment-metadata -->
     329                        <?php endif; ?>
    195330
    196331                                <div class="comment-content" id="comment-content-<?php echo $comment->comment_ID; ?>">
    197                                         <?php comment_text(); ?>
    198                                 </div>
    199                                 <!-- .comment-content -->
     332                                <?php
     333                                if ( $parent ) {
     334                                        comment_text();
     335                                } else {
    200336
    201                                 <?php if ( '0' == $comment->comment_approved ) : ?>
    202                                         <footer class="comment-footer">
    203                                                 <p class="comment-awaiting-moderation"><?php _e( 'Your note is awaiting moderation.', 'wporg' ); ?></p>
    204                                         </footer>
    205                                         <!-- .comment-footer -->
    206                                 <?php endif; ?>
     337                                        $text = get_comment_text()  . ' &mdash; ';
     338                                        $text .= sprintf( __( 'By %s', 'wporg' ), sprintf( '<cite class="fn">%s</cite>', $comment_author_link ) ) . ' &mdash; ';
     339                                        $text .= ' <a href="'. esc_url( get_comment_link( $comment->comment_ID ) ) . '">';
     340                                        $text .= '<time datetime="' . get_comment_time( 'c' ) . '">' . $date . '</time></a>';
    207341
    208                                 <?php
    209                                         comment_reply_link( array_merge( $args, array(
    210                                                 'add_below' => 'div-comment',
    211                                                 'depth'     => $depth,
    212                                                 'max_depth' => $args['max_depth'],
    213                                                 'before'    => '<div class="reply">',
    214                                                 'after'     => '</div>',
    215                                         ) ) );
     342                                        if ( current_user_can( 'edit_comment', $comment->comment_ID ) ) {
     343                                                $text .= ' &mdash; <a class="comment-edit-link" href="' . get_edit_comment_link( $comment->comment_ID ) .'">';
     344                                                $text .= __( 'Edit', 'wporg' ) . '</a>';
     345                                        }
     346
     347                                        if ( !$approved ) {
     348                                                $text .= ' &mdash; <span class="comment-awaiting-moderation">' . __( 'awaiting moderation', 'wporg' ) . '</span>';
     349                                        }
     350
     351                                        echo apply_filters( 'comment_text', $text );
     352                                }
    216353                                ?>
    217                         </article><!-- .comment-body -->
    218                         <?php
     354                                </div><!-- .comment-content -->
     355
     356                        <?php if ( !$parent ) : ?>
     357                        </article>
     358                        </li>
     359                        <?php endif; ?>
     360                <?php           
    219361                }
    220362        endif; // ends check for wporg_developer_user_note()
    221363
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/inc/user-content.php

     
    4040                // Remove reply to link
    4141                add_filter( 'comment_reply_link',              '__return_empty_string' );
    4242
     43                // Remove cancel reply link
     44                add_filter( 'cancel_comment_reply_link',       '__return_empty_string' );
     45
    4346                // Disable smilie conversion
    4447                remove_filter( 'comment_text',                 'convert_smilies',    20 );
    4548
     
    5861                // Tweak code contained in shortcode
    5962                add_filter( 'syntaxhighlighter_precode',       array( __CLASS__, 'syntaxhighlighter_precode' ) );
    6063
     64                // Allowed HTML for a new child comment
     65                add_filter( 'preprocess_comment', array( __CLASS__, 'comment_new_allowed_html' ) );
     66
     67                // Allowed HTML for an edited child comment (There is no decent hook to filter child comments only)
     68                add_action( 'edit_comment', array( __CLASS__, 'comment_edit_allowed_html' ) );
     69
    6170        }
    6271
    6372        /**
     
    7988        }
    8089
    8190        /**
     91         * Updates edited child comments with allowed HTML.
     92         * Allowed html is <strong>, <em>, <code> and <a>.
     93         *
     94         * @param int $comment_ID Comment ID.
     95         */
     96        public static function comment_edit_allowed_html( $comment_ID ) {
     97
     98                // Get the edited comment.
     99                $comment = get_comment( $comment_ID, ARRAY_A );
     100                if ( empty( $comment ) ) {
     101                        return;
     102                }
     103
     104                if ( ( 0 === (int) $comment['comment_parent'] ) || empty( $comment['comment_content'] ) ) {
     105                        return;
     106                }
     107
     108                $content = $comment['comment_content'];
     109                $data    = self::comment_new_allowed_html( $comment );
     110
     111                if ( $data['comment_content'] !== $content ) {
     112                        $commentarr = array(
     113                                'comment_ID' => $data['comment_ID'],
     114                                'comment_content' => $data['comment_content']
     115                        );
     116
     117                        // Update comment content.
     118                        wp_update_comment( $commentarr );
     119                }
     120        }
     121
     122        /**
     123         * Filter new child comments content with allowed HTML.
     124         * Allowed html is <strong>, <em>, <code> and <a>.
     125         *
     126         * @param array $commentdata Array with comment data.
     127         * @return array Array with filtered comment data.
     128         */
     129        public static function comment_new_allowed_html( $commentdata ) {
     130                $comment_parent = isset( $commentdata['comment_parent'] ) ? absint( $commentdata['comment_parent'] ) : 0;
     131                $comment_content = isset( $commentdata['comment_content'] ) ? trim( $commentdata['comment_content'] ) : '';
     132
     133                if ( ( $comment_parent === 0 ) || !$comment_content ) {
     134                        return $commentdata;
     135                }
     136
     137                $allowed_html = array(
     138                        'a'      => array(
     139                                'href'   => true,
     140                                'rel'    => true,
     141                                'target' => true,
     142                        ),
     143                        'em'     => array(),
     144                        'strong' => array(),
     145                        'code'   => array(),
     146                );
     147
     148                $allowed_protocols = array( 'http', 'https' );
     149
     150                $comment_content = wp_kses( $comment_content, $allowed_html, $allowed_protocols );
     151                $commentdata['comment_content'] = preg_replace( '/\r?\n|\r/', '', $comment_content );
     152
     153                return $commentdata;
     154        }
     155
     156        /**
    82157         * Enqueues scripts and styles.
    83158         */
    84159        public static function scripts_and_styles() {
     
    87162                        wp_enqueue_style( 'syntaxhighlighter-core' );
    88163                        wp_enqueue_style( 'syntaxhighlighter-theme-default' );
    89164
    90                         wp_enqueue_script( 'wporg-developer-user-notes', get_template_directory_uri() . '/js/user-notes.js', array( 'quicktags' ), '20160824', true );
    91                         if ( get_option( 'thread_comments' ) ) {
    92                                 wp_enqueue_script( 'comment-reply' );
    93                         }
     165                        wp_enqueue_script( 'wporg-developer-user-notes', get_template_directory_uri() . '/js/user-notes.js', array( 'jquery', 'quicktags' ), '20160809', true );
     166                        wp_enqueue_script( 'wporg-developer-user-notes-feedback', get_template_directory_uri() . '/js/user-notes-feedback.js', array( 'jquery', 'quicktags' ), '20160809', true );
     167                        wp_localize_script( 'wporg-developer-user-notes-feedback', 'wporg_note_feedback', array(
     168                                'show'        => __( 'Show Feedback', 'wporg' ),
     169                                'hide'        => __( 'Hide Feedback', 'wporg' ),
     170                        ) );
    94171                }
    95172        }
    96173
     
    154231                return ob_get_clean();
    155232        }
    156233
     234        /**
     235         * Capture an {@see wp_editor()} instance as the 'User Contributed Notes' feedback form.
     236         *
     237         * Uses output buffering to capture the editor instance.
     238         *
     239         * @return string HTML output for the wp_editor-ized feedback form.
     240         */
     241        public static function wp_editor_feedback( $comment, $display = 'show', $content = '' ) {
     242
     243                if ( !isset( $comment->comment_ID ) && absint( $comment->comment_ID ) ) {
     244                        return '';
     245                }
     246
     247                $comment_id = $comment->comment_ID;
     248
     249                static $instance = 0;
     250                $instance++;
     251
     252                $display = ( 'hide' === $display ) ? ' style="display: none;"' : '';
     253                $title = __( 'Add feedback to this note', 'wporg' );
     254                $form_type = '';
     255                $button_text = __( 'Add Feedback', 'wporg' );
     256
     257                if ( !empty( $content ) ) {
     258                        $title = __( 'Edit feedback', 'wporg' );
     259                        $form_type = '-edit';
     260                        $button_text = __( 'Edit Feedback', 'wporg' );
     261                }
     262
     263                $allowed_tags = '';
     264                foreach ( array( '<strong>', '<em>', '<code>', '<a>' ) as $tag ) {
     265                        $allowed_tags .= '<code>' . htmlentities( $tag ) . '</code>, ';
     266                }
     267
     268                ob_start();
     269                echo "<div id='feedback-editor-{$comment_id}' class='feedback-editor'{$display}>\n";
     270                echo "<p class='feedback-editor-title'>{$title}</p>\n";
     271                echo '<form id="feedback-form-' . $instance . $form_type . '" class="feedback-form" method="post" action="' . site_url( '/wp-comments-post.php' ) . '" name="feedback-form-' . $instance ."\">\n";
     272
     273                wp_editor( '', 'feedback-' . $instance, array(
     274                        'media_buttons' => false,
     275                        'textarea_name' => 'comment',
     276                        'textarea_rows' => 3,
     277                        'quicktags'     => array(
     278                                'buttons' => 'strong,em'
     279                        ),
     280                        'teeny'         => true,
     281                        'tinymce'       => false,
     282                ) );
     283
     284                echo '<p><strong>' . __( 'Note', 'wporg' ) . '</strong>: ' . __( 'No newlines allowed', 'wporg' ) . '. ';
     285                printf( __( 'Allowed tags: %s', 'wporg' ), trim( $allowed_tags, ', ' ) ) . "</p>\n";
     286                echo "<p><input id='submit-{$instance}' class='submit' type='submit' value='Add Feedback' name='submit-{$instance}'>\n";
     287                echo "<input type='hidden' name='comment_post_ID' value='" . get_the_ID() . "' id='comment_post_ID-{$instance}' />\n";
     288                echo "<input type='hidden' name='comment_parent' id='comment_parent-{$instance}' value='{$comment_id}' />\n";
     289                echo "</p>\n</form>\n</div><!-- #feedback-editor-{$comment_id} -->\n";
     290                return ob_get_clean();
     291        }
     292
    157293} // DevHub_User_Submitted_Content
    158294
    159295DevHub_User_Submitted_Content::init();
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/js/user-notes-feedback.js

     
     1( function( $ ) {
     2
     3        var feedbackToggle = $( '<a class="feedback-toggle" href="#">Show Feedback</a>' );
     4        var hash = window.location.hash;
     5
     6        if ( !hash.match( /#comment\-[0-9]+$/ ) ) {
     7                hash = '';
     8        }
     9       
     10        $( '.feedback-editor' ).each( function() {
     11
     12                // Hide hidden editor with 'hide-if-js' class.
     13                if( 'none' === $(this).css('display') ) {
     14                        $( this ).show().addClass( 'hide-if-js' );
     15                }
     16
     17                // Add quicktag 'inline code' button to editor.
     18                var id = $( this ).find( 'textarea' ).attr( 'id' );
     19                if ( id.length ) {
     20                        QTags.addButton( 'inline-code', 'inline code', '<code>', '</code>', '', '', '', id );
     21                }
     22        } );
     23
     24        // Loop through feedback notes
     25        $( '.comment' ).each( function() {
     26
     27                var feedbackLinks = $( this ).find( '.feedback-links' );
     28                var childComments = $( this ).find( 'ul.children' );
     29
     30               
     31                if ( childComments.length && feedbackLinks.length ) {
     32                        var feedback = $( this ).find( '.feedback' );
     33                        var toggle = feedbackToggle.clone();
     34
     35                        toggle.attr( {
     36                                'aria-expanded': 'false',
     37                                'aria-controls': 'feedback-' + getCommentID( $(this) )
     38                        } );
     39
     40                        if ( !feedback.hasClass( 'hide-if-js' ) ) {
     41                                toggle.text( 'Hide Feedback' );
     42                        }
     43                        // If feedback is found add a show/hide link
     44                        feedbackLinks.find( '.feedback-add' ).show();
     45                        feedbackLinks.append( toggle );
     46                }
     47
     48                if ( feedbackLinks.length ) {
     49                        // Move feedback links before feedback.
     50                        clonedElements = $( '<div class="feedback-links"></div>' ).append( feedbackLinks.clone().children() );
     51
     52                        $( this ).find( '.feedback' ).first().before( clonedElements );
     53                        //$( this ).find( 'div.feedback-links' ).show();
     54                        feedbackLinks.addClass( 'bottom hide-if-js' );
     55                }
     56        } );
     57
     58        // Returns comment ID from data attribute.
     59        function getCommentID( el ) {
     60                return $(el).is("[data-comment-id") ? el.data( 'comment-id' ) : 0;
     61        }
     62
     63        // Removes added elements
     64        function resetComment( el ) {
     65
     66                var children = el.find( 'ul.children' );
     67                if ( !children.length ) {
     68                        el.find( '.feedback-toggle' ).remove();
     69                }
     70
     71                el.find( '.feedback-links.bottom' ).addClass( 'hide-if-js' );
     72        }
     73
     74        // Show hidden child comments if the fragment identifier is a comment ID (e.g. #comment-63). 
     75        $( document ).ready( function() {
     76
     77                var childComments = $( '.comment' ).find( 'ul.children' );
     78
     79                if ( !( hash.length && childComments.length ) ) {
     80                        return;
     81                }
     82
     83                var hashComment = childComments.find( hash ).first();
     84                if ( hashComment.length ) {
     85
     86                        var parent = hashComment.closest( '.comment.depth-1' );
     87                        if ( parent.find( '.feedback' ).hasClass( 'hide-if-js' ) ) {
     88                                // Show child comments.
     89                                parent.find( '.feedback-toggle' ).first().trigger( 'click' );
     90                        }
     91
     92                        // Scroll to the child comment.
     93                        var pos = hashComment.offset();
     94                        $( 'html,body' ).animate( {
     95                                scrollTop: pos.top - 32
     96                        }, 1 );
     97                }
     98        } );
     99
     100        // Show/Hide feedback toggle link.
     101        $( document ).on( 'click', '.feedback-toggle', function( e ) {
     102                e.preventDefault();
     103
     104                var parent = $( this ).closest( '.comment' );
     105                if ( !parent.length ) {
     106                        return;
     107                }
     108
     109                resetComment( parent );
     110                var feedback = parent.find( '.feedback' );
     111                var toggleLinks = parent.find( '.feedback-toggle' );
     112
     113                if ( feedback.hasClass( 'hide-if-js' ) ) {
     114                        // Feedback is hidden.
     115
     116                        // Show feedback.
     117                        toggleLinks.text( 'Hide Feedback' );
     118                        feedback.removeClass( 'hide-if-js' );
     119                        toggleLinks.attr( 'aria-expanded', 'true' );
     120
     121                        // Go to the clicked feedback toggle link.
     122                        var pos = $( this ).offset();
     123                        $( 'html,body' ).animate( {
     124                                scrollTop: pos.top - 32
     125                        }, 1000 );
     126
     127                        // Add feedback links at the bottom if there are over 3 feedback notes.
     128                        var children = parent.find( 'ul.children > li' );
     129                        if ( 3 < children.length ) {
     130                                var feedbackLinks = parent.find( '.feedback-links.bottom' );
     131                                feedbackLinks.removeClass( 'hide-if-js' );
     132                        }
     133
     134                } else {
     135                        // Hide feedback.
     136                        toggleLinks.text( 'Show Feedback' );
     137                        feedback.addClass( 'hide-if-js' );
     138                        toggleLinks.attr( 'aria-expanded', 'false' );
     139
     140                        // Hide editor.
     141                        var editor = feedback.find( '.feedback-editor' );
     142                        editor.addClass( 'hide-if-js' );
     143
     144                        parent.find( '.feedback-add' ).attr( 'aria-expanded', 'false' );
     145                }
     146        } );
     147
     148        // Show editor when the add feedback link is clicked.
     149        $( document ).on( 'click', '.feedback-add', function( e ) {
     150                e.preventDefault();
     151
     152                var parent = $( this ).closest( '.comment' );
     153                if ( !parent.length ) {
     154                        return;
     155                }
     156
     157                resetComment( parent );
     158
     159                var feedback = parent.find( '.feedback' );
     160                var children = parent.find( 'ul.children' );
     161                var feedbackLinks = parent.find( '.feedback-add' );
     162
     163                // Show feedback.
     164                feedback.removeClass( 'hide-if-js' );
     165                feedbackLinks.attr( 'aria-expanded', 'true' );
     166
     167                // Show the feedback editor.
     168                var editor = feedback.find( '.feedback-editor' );
     169                editor.removeClass( 'hide-if-js' );
     170
     171                // Change the toggle link text to 'Hide Feedback'.
     172                var toggleLinks = parent.find( '.feedback-toggle' );
     173                if ( toggleLinks.length ) {
     174                        toggleLinks.attr( 'aria-expanded', 'true' );
     175                        toggleLinks.text( 'Hide Feedback' );
     176                }
     177
     178                // If there are no child comments add a 'Hide Feedback' link.
     179                if ( !children.length ) {
     180                        var hide = feedbackToggle.clone();
     181                        hide.text( 'Hide Feedback' );
     182                        hide.attr( {
     183                                'aria-expanded': 'true',
     184                                'aria-controls': 'feedback-' + getCommentID( parent )
     185                        } );
     186                        parent.find( '.feedback-links' ).append( hide );
     187                }
     188
     189                // Go to the feedback editor and give it focus.
     190                var pos = editor.offset();
     191                $( 'html,body' ).animate( {
     192                        scrollTop: pos.top - 32
     193                }, 1000, function() {
     194                        editor.find( 'textarea' ).focus();
     195                } );
     196        } );
     197
     198} )( jQuery );
     199 No newline at end of file
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/js/user-notes.js

     
    1313
    1414        function showCommentForm() {
    1515                $( '#respond' ).show();
    16                 $( '#add-user-note').hide();
     16                $( '#add-user-note' ).hide();
    1717
    1818                var target = $( '#commentform #add-note-or-feedback' );
    1919                if ( target.length ) {
    2020                        var pos = target.offset();
    2121
    2222                        $( 'html,body' ).animate( {
    23                                 scrollTop: pos.top
     23                                scrollTop: pos.top - 32
    2424                        }, 1000 );
    2525                }
    2626        }
     
    3737        }
    3838
    3939        // Add php and js buttons to QuickTags.
    40         QTags.addButton( 'php', 'php', '[php]', '[/php]' );
    41         QTags.addButton( 'js', 'js', '[js]', '[/js]' );
    42         QTags.addButton( 'inline-code', 'inline code', '<code>', '</code>' );
     40        QTags.addButton( 'php', 'php', '[php]', '[/php]', '', '', '', 'comment' );
     41        QTags.addButton( 'js', 'js', '[js]', '[/js]', '', '', '', 'comment' );
     42        QTags.addButton( 'inline-code', 'inline code', '<code>', '</code>', '', '', '', 'comment' );
    4343
    4444        // Override tab within user notes textarea to actually insert a tab character.
    4545        // Copied from code within core's wp-admin/js/common.js.
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/scss/main.scss

     
    12161216                        opacity: 1;
    12171217                }
    12181218
     1219                .comment-awaiting-moderation {
     1220                        background-color: #fff8e5;
     1221                        padding: .2em .5em;
     1222                        border-radius: 3px;
     1223                        border: 1px solid #ffb900;
     1224                }
     1225
    12191226                .comment-list,
    12201227                .comment-list ol {
    12211228                        list-style: none;
     
    12251232
    12261233                .comment-list li,
    12271234                #comment-preview {
    1228                         margin-top: 2.5rem;
     1235                        margin-top: 3rem;
    12291236                        background: #fff;
    12301237                        overflow: auto;
    1231                         border: 1px solid #dfdfdf;
    1232                         border-radius: 0 2px 2px 2px;
    12331238
    12341239                        article {
    12351240                                overflow: auto;
    12361241                        }
    12371242                }
    12381243
     1244                .comment-list li.depth-1,
     1245                #comment-preview {
     1246                        border: 1px solid #dfdfdf;
     1247                        border-radius: 2px;
     1248                }
     1249
     1250                /* Feedback */
     1251                .comment-list li.depth-2 {
     1252                        border-top: 1px solid #dfdfdf;
     1253                        padding: 0;
     1254                        margin: 0;
     1255
     1256                        .comment-content {
     1257                                padding: 1rem 0;
     1258                        }
     1259                        .comment-content p {
     1260                                margin-bottom: 0;
     1261                                font-size: .9em;
     1262                        }
     1263                }
     1264
     1265                .comment ul.children {
     1266                        margin: 0 0 1.5em 0;
     1267                        border-bottom: 1px solid #dfdfdf;
     1268                }
     1269
     1270                .feedback {
     1271                        width: 90%;
     1272                        float: right;
     1273                        margin-right: 1.5rem;
     1274                }
     1275
     1276                .feedback-links {
     1277                        margin: 0 1.5rem  1em 1.5rem;
     1278                        font-size: 0.9em;
     1279                        clear:both;
     1280                }
     1281
     1282                .feedback-editor-title,
     1283                .feedback-title {                       
     1284                        font-size: 1.8rem;
     1285                font-weight: 300;
     1286                line-height: 2.2rem;
     1287                margin-bottom: 1em;
     1288                }
     1289
     1290                .feedback-toggle {
     1291                        margin: 0 0 0 1.5rem;
     1292                        display: inline-block;
     1293                }
     1294
     1295                #wp-feedback-wrap {
     1296                        padding-bottom: 1em;
     1297                }
     1298
    12391299                #comment-preview,
    12401300                .js & .comment-form-comment {
    12411301                        margin-top: 0;
     
    13041364                        padding: 2rem 1.5rem .5rem;
    13051365                }
    13061366
    1307                 .comment-footer {
    1308                         margin: 0 1em;
    1309                         padding: 0 0 1em 0;
    1310                         position: relative;
    1311                         overflow: auto;
    1312 
    1313                         a {
    1314                                 float: right;
    1315                         }
    1316 
    1317                         p {
    1318                                 margin-bottom: 0;
    1319                         }
    1320                 }
    1321 
    13221367                .comment-content ol {
    13231368                        list-style: decimal inside;
    13241369                        margin: 0 0 1.5em 0;
  • sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-developer/stylesheets/main.css

     
    15821582  word-wrap: break-word;
    15831583}
    15841584
     1585.devhub-wrap.single-wp-parser-function, .devhub-wrap.single-wp-parser-method, .devhub-wrap.single-wp-parser-hook, .devhub-wrap.single-wp-parser-class {
     1586  /* Feedback */
     1587}
     1588
    15851589.devhub-wrap.single-wp-parser-function .bad-note .comment-content, .devhub-wrap.single-wp-parser-method .bad-note .comment-content, .devhub-wrap.single-wp-parser-hook .bad-note .comment-content, .devhub-wrap.single-wp-parser-class .bad-note .comment-content {
    15861590  opacity: .6;
    15871591}
     
    15901594  opacity: 1;
    15911595}
    15921596
     1597.devhub-wrap.single-wp-parser-function .comment-awaiting-moderation, .devhub-wrap.single-wp-parser-method .comment-awaiting-moderation, .devhub-wrap.single-wp-parser-hook .comment-awaiting-moderation, .devhub-wrap.single-wp-parser-class .comment-awaiting-moderation {
     1598  background-color: #fff8e5;
     1599  padding: .2em .5em;
     1600  border-radius: 3px;
     1601  border: 1px solid #ffb900;
     1602}
     1603
    15931604.devhub-wrap.single-wp-parser-function .comment-list,
    15941605.devhub-wrap.single-wp-parser-function .comment-list ol, .devhub-wrap.single-wp-parser-method .comment-list,
    15951606.devhub-wrap.single-wp-parser-method .comment-list ol, .devhub-wrap.single-wp-parser-hook .comment-list,
     
    16051616.devhub-wrap.single-wp-parser-method #comment-preview, .devhub-wrap.single-wp-parser-hook .comment-list li,
    16061617.devhub-wrap.single-wp-parser-hook #comment-preview, .devhub-wrap.single-wp-parser-class .comment-list li,
    16071618.devhub-wrap.single-wp-parser-class #comment-preview {
    1608   margin-top: 2.5rem;
     1619  margin-top: 3rem;
    16091620  background: #fff;
    16101621  overflow: auto;
    1611   border: 1px solid #dfdfdf;
    1612   border-radius: 0 2px 2px 2px;
    16131622}
    16141623
    16151624.devhub-wrap.single-wp-parser-function .comment-list li article,
     
    16201629  overflow: auto;
    16211630}
    16221631
     1632.devhub-wrap.single-wp-parser-function .comment-list li.depth-1,
     1633.devhub-wrap.single-wp-parser-function #comment-preview, .devhub-wrap.single-wp-parser-method .comment-list li.depth-1,
     1634.devhub-wrap.single-wp-parser-method #comment-preview, .devhub-wrap.single-wp-parser-hook .comment-list li.depth-1,
     1635.devhub-wrap.single-wp-parser-hook #comment-preview, .devhub-wrap.single-wp-parser-class .comment-list li.depth-1,
     1636.devhub-wrap.single-wp-parser-class #comment-preview {
     1637  border: 1px solid #dfdfdf;
     1638  border-radius: 2px;
     1639}
     1640
     1641.devhub-wrap.single-wp-parser-function .comment-list li.depth-2, .devhub-wrap.single-wp-parser-method .comment-list li.depth-2, .devhub-wrap.single-wp-parser-hook .comment-list li.depth-2, .devhub-wrap.single-wp-parser-class .comment-list li.depth-2 {
     1642  border-top: 1px solid #dfdfdf;
     1643  padding: 0;
     1644  margin: 0;
     1645}
     1646
     1647.devhub-wrap.single-wp-parser-function .comment-list li.depth-2 .comment-content, .devhub-wrap.single-wp-parser-method .comment-list li.depth-2 .comment-content, .devhub-wrap.single-wp-parser-hook .comment-list li.depth-2 .comment-content, .devhub-wrap.single-wp-parser-class .comment-list li.depth-2 .comment-content {
     1648  padding: 1rem 0;
     1649}
     1650
     1651.devhub-wrap.single-wp-parser-function .comment-list li.depth-2 .comment-content p, .devhub-wrap.single-wp-parser-method .comment-list li.depth-2 .comment-content p, .devhub-wrap.single-wp-parser-hook .comment-list li.depth-2 .comment-content p, .devhub-wrap.single-wp-parser-class .comment-list li.depth-2 .comment-content p {
     1652  margin-bottom: 0;
     1653  font-size: .9em;
     1654}
     1655
     1656.devhub-wrap.single-wp-parser-function .comment ul.children, .devhub-wrap.single-wp-parser-method .comment ul.children, .devhub-wrap.single-wp-parser-hook .comment ul.children, .devhub-wrap.single-wp-parser-class .comment ul.children {
     1657  margin: 0 0 1.5em 0;
     1658  border-bottom: 1px solid #dfdfdf;
     1659}
     1660
     1661.devhub-wrap.single-wp-parser-function .feedback, .devhub-wrap.single-wp-parser-method .feedback, .devhub-wrap.single-wp-parser-hook .feedback, .devhub-wrap.single-wp-parser-class .feedback {
     1662  width: 90%;
     1663  float: right;
     1664  margin-right: 1.5rem;
     1665}
     1666
     1667.devhub-wrap.single-wp-parser-function .feedback-links, .devhub-wrap.single-wp-parser-method .feedback-links, .devhub-wrap.single-wp-parser-hook .feedback-links, .devhub-wrap.single-wp-parser-class .feedback-links {
     1668  margin: 0 1.5rem  1em 1.5rem;
     1669  font-size: 0.9em;
     1670  clear: both;
     1671}
     1672
     1673.devhub-wrap.single-wp-parser-function .feedback-editor-title,
     1674.devhub-wrap.single-wp-parser-function .feedback-title, .devhub-wrap.single-wp-parser-method .feedback-editor-title,
     1675.devhub-wrap.single-wp-parser-method .feedback-title, .devhub-wrap.single-wp-parser-hook .feedback-editor-title,
     1676.devhub-wrap.single-wp-parser-hook .feedback-title, .devhub-wrap.single-wp-parser-class .feedback-editor-title,
     1677.devhub-wrap.single-wp-parser-class .feedback-title {
     1678  font-size: 1.8rem;
     1679  font-weight: 300;
     1680  line-height: 2.2rem;
     1681  margin-bottom: 1em;
     1682}
     1683
     1684.devhub-wrap.single-wp-parser-function .feedback-toggle, .devhub-wrap.single-wp-parser-method .feedback-toggle, .devhub-wrap.single-wp-parser-hook .feedback-toggle, .devhub-wrap.single-wp-parser-class .feedback-toggle {
     1685  margin: 0 0 0 1.5rem;
     1686  display: inline-block;
     1687}
     1688
     1689.devhub-wrap.single-wp-parser-function #wp-feedback-wrap, .devhub-wrap.single-wp-parser-method #wp-feedback-wrap, .devhub-wrap.single-wp-parser-hook #wp-feedback-wrap, .devhub-wrap.single-wp-parser-class #wp-feedback-wrap {
     1690  padding-bottom: 1em;
     1691}
     1692
    16231693.devhub-wrap.single-wp-parser-function #comment-preview,
    16241694.js .devhub-wrap.single-wp-parser-function .comment-form-comment, .devhub-wrap.single-wp-parser-method #comment-preview,
    16251695.js .devhub-wrap.single-wp-parser-method .comment-form-comment, .devhub-wrap.single-wp-parser-hook #comment-preview,
     
    16841754  padding: 2rem 1.5rem .5rem;
    16851755}
    16861756
    1687 .devhub-wrap.single-wp-parser-function .comment-footer, .devhub-wrap.single-wp-parser-method .comment-footer, .devhub-wrap.single-wp-parser-hook .comment-footer, .devhub-wrap.single-wp-parser-class .comment-footer {
    1688   margin: 0 1em;
    1689   padding: 0 0 1em 0;
    1690   position: relative;
    1691   overflow: auto;
    1692 }
    1693 
    1694 .devhub-wrap.single-wp-parser-function .comment-footer a, .devhub-wrap.single-wp-parser-method .comment-footer a, .devhub-wrap.single-wp-parser-hook .comment-footer a, .devhub-wrap.single-wp-parser-class .comment-footer a {
    1695   float: right;
    1696 }
    1697 
    1698 .devhub-wrap.single-wp-parser-function .comment-footer p, .devhub-wrap.single-wp-parser-method .comment-footer p, .devhub-wrap.single-wp-parser-hook .comment-footer p, .devhub-wrap.single-wp-parser-class .comment-footer p {
    1699   margin-bottom: 0;
    1700 }
    1701 
    17021757.devhub-wrap.single-wp-parser-function .comment-content ol, .devhub-wrap.single-wp-parser-method .comment-content ol, .devhub-wrap.single-wp-parser-hook .comment-content ol, .devhub-wrap.single-wp-parser-class .comment-content ol {
    17031758  list-style: decimal inside;
    17041759  margin: 0 0 1.5em 0;