Make WordPress Core

Ticket #31590: 31590.3.diff

File 31590.3.diff, 11.9 KB (added by peterwilsoncc, 7 years ago)
  • src/wp-includes/comment-template.php

    diff --git a/src/wp-includes/comment-template.php b/src/wp-includes/comment-template.php
    index 0f8f7a39c8..3b7a46c8cb 100644
    a b function get_comment_reply_link( $args = array(), $comment = null, $post = null 
    16671667                        $args['login_text']
    16681668                );
    16691669        } else {
    1670                 $onclick = sprintf(
    1671                         'return addComment.moveForm( "%1$s-%2$s", "%2$s", "%3$s", "%4$s" )',
    1672                         $args['add_below'], $comment->comment_ID, $args['respond_id'], $post->ID
     1670                $data_attributes = array(
     1671                        'commentid'        => $comment->comment_ID,
     1672                        'postid'           => $post->ID,
     1673                        'belowelement'     => $args['add_below'] . '-' . $comment->comment_ID,
     1674                        'respondelement'   => $args['respond_id'],
    16731675                );
    16741676
     1677                $data_attribute_string = '';
     1678
     1679                foreach ( $data_attributes as $name => $value ) {
     1680                        $data_attribute_string .= " data-${name}=\"" . esc_attr( $value ) . "\"";
     1681                }
     1682
     1683                $data_attribute_string = trim( $data_attribute_string );
     1684
    16751685                $link = sprintf(
    1676                         "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s' aria-label='%s'>%s</a>",
    1677                         esc_url( add_query_arg( 'replytocom', $comment->comment_ID, get_permalink( $post->ID ) ) ) . '#' . $args['respond_id'],
    1678                         $onclick,
     1686                        "<a rel='nofollow' class='comment-reply-link' href='%s' %s aria-label='%s'>%s</a>",
     1687                        esc_url( add_query_arg( 'replytocom', $comment->comment_ID ) ) . "#" . $args['respond_id'],
     1688                        $data_attribute_string,
    16791689                        esc_attr( sprintf( $args['reply_to_text'], $comment->comment_author ) ),
    16801690                        $args['reply_text']
    16811691                );
  • src/wp-includes/js/comment-reply.js

    diff --git a/src/wp-includes/js/comment-reply.js b/src/wp-includes/js/comment-reply.js
    index 3ddf7744ce..55a4e9c9b0 100644
    a b  
    55 *
    66 * @type {Object}
    77 */
    8 var addComment = {
     8var addComment;
     9addComment = ( function( window ) {
     10        // Avoid scope lookups on commonly used variables.
     11        var document = window.document;
     12
     13        // Settings.
     14        var config = {
     15                commentReplyClass : 'comment-reply-link',
     16                cancelReplyId     : 'cancel-comment-reply-link',
     17                commentFormId     : 'commentform',
     18                temporaryFormId   : 'wp-temp-form-div',
     19                parentIdFieldId   : 'comment_parent',
     20                postIdFieldId     : 'comment_post_ID'
     21        };
     22
     23        // Check browser cuts the mustard.
     24        var cutsTheMustard = 'querySelector' in document && 'addEventListener' in window;
     25
     26        /*
     27         * Check browser supports dataset.
     28         * !! sets the variable to true if the property exists.
     29         */
     30        var supportsDataset = !! document.body.dataset;
     31
     32        // For holding the cancel element.
     33        var cancelElement;
     34
     35        // For holding the comment form element.
     36        var commentFormElement;
     37
     38        // The respond element.
     39        var respondElement;
     40
     41        // Initialise the events.
     42        init();
     43
    944        /**
    10          * @summary Retrieves the elements corresponding to the given IDs.
     45         * Add events to links classed .comment-reply-link.
    1146         *
    12          * @since 2.7.0
     47         * Searches the context for reply links and adds the JavaScript events
     48         * required to move the comment form. To allow for lazy loading of
     49         * comments this method is exposed as window.commentReply.init().
     50         *
     51         * @since 5.0.0
    1352         *
    14          * @param {string} commId The comment ID.
    15          * @param {string} parentId The parent ID.
    16          * @param {string} respondId The respond ID.
    17          * @param {string} postId The post ID.
    18          * @returns {boolean} Always returns false.
     53         * @param {HTMLElement} context The parent DOM element to search for links.
    1954         */
    20         moveForm: function( commId, parentId, respondId, postId ) {
    21                 var div, element, style, cssHidden,
    22                         t           = this,
    23                         comm        = t.I( commId ),
    24                         respond     = t.I( respondId ),
    25                         cancel      = t.I( 'cancel-comment-reply-link' ),
    26                         parent      = t.I( 'comment_parent' ),
    27                         post        = t.I( 'comment_post_ID' ),
    28                         commentForm = respond.getElementsByTagName( 'form' )[0];
    29 
    30                 if ( ! comm || ! respond || ! cancel || ! parent || ! commentForm ) {
     55        function init( context ) {
     56                if ( true !== cutsTheMustard ) {
     57                        return;
     58                }
     59
     60                // Get required elements.
     61                cancelElement = getElementById( config.cancelReplyId );
     62                commentFormElement = getElementById( config.commentFormId );
     63
     64                // No cancel element, no replies.
     65                if ( ! cancelElement ) {
    3166                        return;
    3267                }
    3368
    34                 t.respondId = respondId;
    35                 postId = postId || false;
     69                cancelElement.addEventListener( 'touchstart', cancelEvent );
     70                cancelElement.addEventListener( 'click',      cancelEvent );
     71
     72                var links = replyLinks( context );
     73                var element;
     74
     75                for ( var i = 0, l = links.length; i < l; i++ ) {
     76                        element = links[i];
     77
     78                        element.addEventListener( 'touchstart', clickEvent );
     79                        element.addEventListener( 'click',      clickEvent );
     80                }
     81        }
     82
     83        /**
     84         * Return all links classed .comment-reply-link.
     85         *
     86         * @since 5.0.0
     87         *
     88         * @param {HTMLElement} context The parent DOM element to search for links.
     89         *
     90         * @return {HTMLCollection|NodeList|Array}
     91         */
     92        function replyLinks( context ) {
     93                var selectorClass = config.commentReplyClass;
     94                var allReplyLinks;
     95
     96                // childNodes is a handy check to ensure the context is a HTMLElement.
     97                if ( ! context || ! context.childNodes ) {
     98                        context = document;
     99                }
    36100
    37                 if ( ! t.I( 'wp-temp-form-div' ) ) {
    38                         div = document.createElement( 'div' );
    39                         div.id = 'wp-temp-form-div';
    40                         div.style.display = 'none';
    41                         respond.parentNode.insertBefore( div, respond );
     101                if ( document.getElementsByClassName ) {
     102                        // Fastest.
     103                        allReplyLinks = context.getElementsByClassName( selectorClass );
     104                }
     105                else {
     106                        // Fast.
     107                        allReplyLinks = context.querySelectorAll( '.' + selectorClass );
    42108                }
    43109
    44                 comm.parentNode.insertBefore( respond, comm.nextSibling );
    45                 if ( post && postId ) {
    46                         post.value = postId;
     110                return allReplyLinks;
     111        }
     112
     113        /**
     114         * Cancel event handler.
     115         *
     116         * @since 5.0.0
     117         *
     118         * @param {Event} event The calling event.
     119         */
     120        function cancelEvent( event ) {
     121                var cancelLink = this;
     122                var temporaryFormId  = config.temporaryFormId;
     123                var temporaryElement = getElementById( temporaryFormId );
     124
     125                if ( ! temporaryElement || ! respondElement ) {
     126                        // Conditions for cancel link fail.
     127                        return;
    47128                }
    48                 parent.value = parentId;
    49                 cancel.style.display = '';
    50129
    51                 /**
    52                  * @summary Puts back the comment, hides the cancel button and removes the onclick event.
    53                  *
    54                  * @returns {boolean} Always returns false.
     130                getElementById( config.parentIdFieldId ).value = '0';
     131
     132                // Move the respond form back in place of the temporary element.
     133                temporaryElement.parentNode.replaceChild( respondElement ,temporaryElement );
     134                cancelLink.style.display = 'none';
     135                event.preventDefault();
     136        }
     137
     138        /**
     139         * Click event handler.
     140         *
     141         * @since 5.0.0
     142         *
     143         * @param {Event} event The calling event.
     144         */
     145        function clickEvent( event ) {
     146                var replyLink = this,
     147                        commId    = getDataAttribute( replyLink, 'belowelement'),
     148                        parentId  = getDataAttribute( replyLink, 'commentid' ),
     149                        respondId = getDataAttribute( replyLink, 'respondelement'),
     150                        postId    = getDataAttribute( replyLink, 'postid'),
     151                        follow;
     152
     153                /*
     154                 * Third party comments systems can hook into this function via the global scope,
     155                 * therefore the click event needs to reference the global scope.
    55156                 */
    56                 cancel.onclick = function() {
    57                         var t       = addComment,
    58                                 temp    = t.I( 'wp-temp-form-div' ),
    59                                 respond = t.I( t.respondId );
     157                follow = window.addComment.moveForm(commId, parentId, respondId, postId);
     158                if ( false === follow ) {
     159                        event.preventDefault();
     160                }
     161        }
    60162
    61                         if ( ! temp || ! respond ) {
    62                                 return;
    63                         }
     163        /**
     164         * Backward compatible getter of data-* attribute.
     165         *
     166         * Uses element.dataset if it exists, otherwise uses getAttribute.
     167         *
     168         * @since 5.0.0
     169         *
     170         * @param {HTMLElement} Element DOM element with the attribute.
     171         * @param {String}      Attribute the attribute to get.
     172         *
     173         * @return {String}
     174         */
     175        function getDataAttribute( element, attribute ) {
     176                if ( supportsDataset ) {
     177                        return element.dataset[attribute];
     178                }
     179                else {
     180                        return element.getAttribute( 'data-' + attribute );
     181                }
     182        }
    64183
    65                         t.I( 'comment_parent' ).value = '0';
    66                         temp.parentNode.insertBefore( respond, temp );
    67                         temp.parentNode.removeChild( temp );
    68                         this.style.display = 'none';
    69                         this.onclick = null;
    70                         return false;
    71                 };
     184        /**
     185         * Get element by ID.
     186         *
     187         * Local alias for document.getElementById.
     188         *
     189         * @since 5.0.0
     190         *
     191         * @param {HTMLElement} The requested element.
     192         */
     193        function getElementById( elementId ) {
     194                return document.getElementById( elementId );
     195        }
     196
     197        /**
     198         * Moves the reply form from its current position to the reply location.
     199         *
     200         * @since 2.7.0
     201         *
     202         * @param {String} addBelowId HTML ID of element the form follows.
     203         * @param {String} commentId  Database ID of comment being replied to.
     204         * @param {String} respondId  HTML ID of 'respond' element.
     205         * @param {String} postId     Database ID of the post.
     206         */
     207        function moveForm( addBelowId, commentId, respondId, postId ) {
     208                // Get elements based on their IDs.
     209                var addBelowElement = getElementById( addBelowId );
     210                respondElement  = getElementById( respondId );
     211
     212                // Get the hidden fields.
     213                var parentIdField   = getElementById( config.parentIdFieldId );
     214                var postIdField     = getElementById( config.postIdFieldId );
     215                var element, cssHidden, style;
     216
     217                if ( ! addBelowElement || ! respondElement || ! parentIdField ) {
     218                        // Missing key elements, fail.
     219                        return;
     220                }
     221
     222                addPlaceHolder( respondElement );
     223
     224                // Set the value of the post.
     225                if ( postId && postIdField ) {
     226                        postIdField.value = postId;
     227                }
     228
     229                parentIdField.value = commentId;
     230
     231                cancelElement.style.display = '';
     232                addBelowElement.parentNode.insertBefore( respondElement, addBelowElement.nextSibling );
    72233
    73234                /*
    74                  * Sets initial focus to the first form focusable element.
    75                  * Uses try/catch just to avoid errors in IE 7- which return visibility
    76                  * 'inherit' when the visibility value is inherited from an ancestor.
     235                 * This is for backward compatibility with third party commenting systems
     236                 * hooking into the event using older techniques.
    77237                 */
     238                cancelElement.onclick = function(){
     239                        return false;
     240                };
     241
     242                // Focus on the first field in the comment form.
    78243                try {
    79                         for ( var i = 0; i < commentForm.elements.length; i++ ) {
    80                                 element = commentForm.elements[i];
     244                        for ( var i = 0; i < commentFormElement.elements.length; i++ ) {
     245                                element = commentFormElement.elements[i];
    81246                                cssHidden = false;
    82247
    83                                 // Modern browsers.
     248                                // Get elements computed style.
    84249                                if ( 'getComputedStyle' in window ) {
     250                                        // Modern browsers.
    85251                                        style = window.getComputedStyle( element );
    86                                 // IE 8.
    87252                                } else if ( document.documentElement.currentStyle ) {
     253                                        // IE 8.
    88254                                        style = element.currentStyle;
    89255                                }
    90256
    var addComment = { 
    107273                                // Stop after the first focusable element.
    108274                                break;
    109275                        }
     276                }
     277                catch(e) {
    110278
    111                 } catch( er ) {}
     279                }
    112280
     281                /*
     282                 * false is returned for backward compatibility with third party commenting systems
     283                 * hooking into this function.
     284                 */
    113285                return false;
    114         },
     286        }
    115287
    116288        /**
    117          * @summary Returns the object corresponding to the given ID.
     289         * Add placeholder element.
     290         *
     291         * Places a place holder element above the #respond element for
     292         * the form to be returned to if needs be.
    118293         *
    119294         * @since 2.7.0
    120295         *
    121          * @param {string} id The ID.
    122          * @returns {Element} The element belonging to the ID.
     296         * @param {HTMLelement} respondElement the #respond element holding comment form.
    123297         */
    124         I: function( id ) {
    125                 return document.getElementById( id );
     298        function addPlaceHolder( respondElement ) {
     299                var temporaryFormId  = config.temporaryFormId;
     300                var temporaryElement = getElementById( temporaryFormId );
     301
     302                if ( temporaryElement ) {
     303                        // The element already exists, no need to recreate.
     304                        return;
     305                }
     306
     307                temporaryElement = document.createElement( 'div' );
     308                temporaryElement.id = temporaryFormId;
     309                temporaryElement.style.display = 'none';
     310                respondElement.parentNode.insertBefore( temporaryElement, respondElement );
    126311        }
    127 };
     312
     313        return {
     314                init: init,
     315                moveForm: moveForm
     316        };
     317})( window );