Make WordPress Core

Changeset 38637


Ignore:
Timestamp:
09/21/2016 08:56:28 AM (10 years ago)
Author:
SergeyBiryukov
Message:

Editor: Improve post.js documentation.

Props jipmoors, boblinthorst.
Fixes #38118.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/js/post.js

    r38425 r38637  
    22/* global theList:true, theExtraList:true, getUserSetting, setUserSetting, commentReply */
    33
     4/**
     5 * Contains all dynamic functionality needed on post and term pages.
     6 *
     7 * @summary Control page and term functionality.
     8 */
     9
    410var commentsBox, WPSetThumbnailHTML, WPSetThumbnailID, WPRemoveThumbnail, wptitlehint, makeSlugeditClickable, editPermalink;
    5 // Back-compat: prevent fatal errors
     11// Backwards compatibility: prevent fatal errors.
    612makeSlugeditClickable = editPermalink = function(){};
    713
     14// Make sure the wp object exists.
    815window.wp = window.wp || {};
    916
     
    1118        var titleHasFocus = false;
    1219
    13 commentsBox = {
    14         st : 0,
    15 
    16         get : function(total, num) {
    17                 var st = this.st, data;
    18                 if ( ! num )
    19                         num = 20;
    20 
    21                 this.st += num;
    22                 this.total = total;
    23                 $( '#commentsdiv .spinner' ).addClass( 'is-active' );
    24 
    25                 data = {
    26                         'action' : 'get-comments',
    27                         'mode' : 'single',
    28                         '_ajax_nonce' : $('#add_comment_nonce').val(),
    29                         'p' : $('#post_ID').val(),
    30                         'start' : st,
    31                         'number' : num
    32                 };
    33 
    34                 $.post(ajaxurl, data,
    35                         function(r) {
    36                                 r = wpAjax.parseAjaxResponse(r);
    37                                 $('#commentsdiv .widefat').show();
    38                                 $( '#commentsdiv .spinner' ).removeClass( 'is-active' );
    39 
    40                                 if ( 'object' == typeof r && r.responses[0] ) {
    41                                         $('#the-comment-list').append( r.responses[0].data );
    42 
    43                                         theList = theExtraList = null;
    44                                         $( 'a[className*=\':\']' ).unbind();
    45 
    46                                         if ( commentsBox.st > commentsBox.total )
    47                                                 $('#show-comments').hide();
    48                                         else
    49                                                 $('#show-comments').show().children('a').html(postL10n.showcomm);
    50 
    51                                         return;
    52                                 } else if ( 1 == r ) {
    53                                         $('#show-comments').html(postL10n.endcomm);
    54                                         return;
     20        /**
     21         * Control loading of comments on the post and term edit pages.
     22         *
     23         * @type {{st: number, get: commentsBox.get, load: commentsBox.load}}
     24         *
     25         * @namespace commentsBox
     26         */
     27        commentsBox = {
     28                // Comment offset to use when fetching new comments.
     29                st : 0,
     30
     31                /**
     32                 * Fetch comments using AJAX and display them in the box.
     33                 *
     34                 * @param {int} total Total number of comments for this post.
     35                 * @param {int} num   Optional. Number of comments to fetch, defaults to 20.
     36                 * @returns {boolean} Always returns false.
     37                 *
     38                 * @memberof commentsBox
     39                 */
     40                get : function(total, num) {
     41                        var st = this.st, data;
     42                        if ( ! num )
     43                                num = 20;
     44
     45                        this.st += num;
     46                        this.total = total;
     47                        $( '#commentsdiv .spinner' ).addClass( 'is-active' );
     48
     49                        data = {
     50                                'action' : 'get-comments',
     51                                'mode' : 'single',
     52                                '_ajax_nonce' : $('#add_comment_nonce').val(),
     53                                'p' : $('#post_ID').val(),
     54                                'start' : st,
     55                                'number' : num
     56                        };
     57
     58                        $.post(
     59                                ajaxurl,
     60                                data,
     61                                function(r) {
     62                                        r = wpAjax.parseAjaxResponse(r);
     63                                        $('#commentsdiv .widefat').show();
     64                                        $( '#commentsdiv .spinner' ).removeClass( 'is-active' );
     65
     66                                        if ( 'object' == typeof r && r.responses[0] ) {
     67                                                $('#the-comment-list').append( r.responses[0].data );
     68
     69                                                theList = theExtraList = null;
     70                                                $( 'a[className*=\':\']' ).unbind();
     71
     72                                                // If the offset is over the total number of comments we cannot fetch any more, so hide the button.
     73                                                if ( commentsBox.st > commentsBox.total )
     74                                                        $('#show-comments').hide();
     75                                                else
     76                                                        $('#show-comments').show().children('a').html(postL10n.showcomm);
     77
     78                                                return;
     79                                        } else if ( 1 == r ) {
     80                                                $('#show-comments').html(postL10n.endcomm);
     81                                                return;
     82                                        }
     83
     84                                        $('#the-comment-list').append('<tr><td colspan="2">'+wpAjax.broken+'</td></tr>');
    5585                                }
    56 
    57                                 $('#the-comment-list').append('<tr><td colspan="2">'+wpAjax.broken+'</td></tr>');
    58                         }
     86                        );
     87
     88                        return false;
     89                },
     90
     91                /**
     92                 * Load the next batch of comments.
     93                 *
     94                 * @param {int} total Total number of comments to load.
     95                 *
     96                 * @memberof commentsBox
     97                 */
     98                load: function(total){
     99                        this.st = jQuery('#the-comment-list tr.comment:visible').length;
     100                        this.get(total);
     101                }
     102        };
     103
     104        /**
     105         * Overwrite the content of the Featured Image postbox
     106         *
     107         * @param {string} html New HTML to be displayed in the content area of the postbox.
     108         *
     109         * @global
     110         */
     111        WPSetThumbnailHTML = function(html){
     112                $('.inside', '#postimagediv').html(html);
     113        };
     114
     115        /**
     116         * Set the Image ID of the Featured Image
     117         *
     118         * @param {int} id The post_id of the image to use as Featured Image.
     119         *
     120         * @global
     121         */
     122        WPSetThumbnailID = function(id){
     123                var field = $('input[value="_thumbnail_id"]', '#list-table');
     124                if ( field.length > 0 ) {
     125                        $('#meta\\[' + field.attr('id').match(/[0-9]+/) + '\\]\\[value\\]').text(id);
     126                }
     127        };
     128
     129        /**
     130         * Remove the Featured Image
     131         *
     132         * @param {string} nonce Nonce to use in the request.
     133         *
     134         * @global
     135         */
     136        WPRemoveThumbnail = function(nonce){
     137                $.post(ajaxurl, {
     138                        action: 'set-post-thumbnail', post_id: $( '#post_ID' ).val(), thumbnail_id: -1, _ajax_nonce: nonce, cookie: encodeURIComponent( document.cookie )
     139                },
     140                        /**
     141                         * Handle server response
     142                         *
     143                         * @param {string} str Response, will be '0' when an error occured otherwise contains link to add Featured Image.
     144                         */
     145                        function(str){
     146                        if ( str == '0' ) {
     147                                alert( setPostThumbnailL10n.error );
     148                        } else {
     149                                WPSetThumbnailHTML(str);
     150                        }
     151                }
    59152                );
    60 
    61                 return false;
    62         },
    63 
    64         load: function(total){
    65                 this.st = jQuery('#the-comment-list tr.comment:visible').length;
    66                 this.get(total);
    67         }
    68 };
    69 
    70 WPSetThumbnailHTML = function(html){
    71         $('.inside', '#postimagediv').html(html);
    72 };
    73 
    74 WPSetThumbnailID = function(id){
    75         var field = $('input[value="_thumbnail_id"]', '#list-table');
    76         if ( field.length > 0 ) {
    77                 $('#meta\\[' + field.attr('id').match(/[0-9]+/) + '\\]\\[value\\]').text(id);
    78         }
    79 };
    80 
    81 WPRemoveThumbnail = function(nonce){
    82         $.post(ajaxurl, {
    83                 action: 'set-post-thumbnail', post_id: $( '#post_ID' ).val(), thumbnail_id: -1, _ajax_nonce: nonce, cookie: encodeURIComponent( document.cookie )
    84         }, function(str){
    85                 if ( str == '0' ) {
    86                         alert( setPostThumbnailL10n.error );
    87                 } else {
    88                         WPSetThumbnailHTML(str);
    89                 }
    90         }
    91         );
    92 };
    93 
    94 $(document).on( 'heartbeat-send.refresh-lock', function( e, data ) {
    95         var lock = $('#active_post_lock').val(),
    96                 post_id = $('#post_ID').val(),
    97                 send = {};
    98 
    99         if ( ! post_id || ! $('#post-lock-dialog').length )
    100                 return;
    101 
    102         send.post_id = post_id;
    103 
    104         if ( lock )
    105                 send.lock = lock;
    106 
    107         data['wp-refresh-post-lock'] = send;
    108 
    109 }).on( 'heartbeat-tick.refresh-lock', function( e, data ) {
    110         // Post locks: update the lock string or show the dialog if somebody has taken over editing
    111         var received, wrap, avatar;
    112 
    113         if ( data['wp-refresh-post-lock'] ) {
    114                 received = data['wp-refresh-post-lock'];
    115 
    116                 if ( received.lock_error ) {
    117                         // show "editing taken over" message
    118                         wrap = $('#post-lock-dialog');
    119 
    120                         if ( wrap.length && ! wrap.is(':visible') ) {
    121                                 if ( wp.autosave ) {
    122                                         // Save the latest changes and disable
    123                                         $(document).one( 'heartbeat-tick', function() {
    124                                                 wp.autosave.server.suspend();
    125                                                 wrap.removeClass('saving').addClass('saved');
    126                                                 $(window).off( 'beforeunload.edit-post' );
    127                                         });
    128 
    129                                         wrap.addClass('saving');
    130                                         wp.autosave.server.triggerSave();
     153        };
     154
     155        /**
     156         * Heartbeat locks.
     157         *
     158         * Used to lock editing of an object by only one user at a time.
     159         *
     160         * When the user does not send a heartbeat in a heartbeat-time
     161         * the user is no longer editing and another user can start editing.
     162         */
     163        $(document).on( 'heartbeat-send.refresh-lock', function( e, data ) {
     164                var lock = $('#active_post_lock').val(),
     165                        post_id = $('#post_ID').val(),
     166                        send = {};
     167
     168                if ( ! post_id || ! $('#post-lock-dialog').length )
     169                        return;
     170
     171                send.post_id = post_id;
     172
     173                if ( lock )
     174                        send.lock = lock;
     175
     176                data['wp-refresh-post-lock'] = send;
     177
     178        }).on( 'heartbeat-tick.refresh-lock', function( e, data ) {
     179                // Post locks: update the lock string or show the dialog if somebody has taken over editing.
     180                var received, wrap, avatar;
     181
     182                if ( data['wp-refresh-post-lock'] ) {
     183                        received = data['wp-refresh-post-lock'];
     184
     185                        if ( received.lock_error ) {
     186                                // Show "editing taken over" message.
     187                                wrap = $('#post-lock-dialog');
     188
     189                                if ( wrap.length && ! wrap.is(':visible') ) {
     190                                        if ( wp.autosave ) {
     191                                                // Save the latest changes and disable.
     192                                                $(document).one( 'heartbeat-tick', function() {
     193                                                        wp.autosave.server.suspend();
     194                                                        wrap.removeClass('saving').addClass('saved');
     195                                                        $(window).off( 'beforeunload.edit-post' );
     196                                                });
     197
     198                                                wrap.addClass('saving');
     199                                                wp.autosave.server.triggerSave();
     200                                        }
     201
     202                                        if ( received.lock_error.avatar_src ) {
     203                                                avatar = $( '<img class="avatar avatar-64 photo" width="64" height="64" alt="" />' ).attr( 'src', received.lock_error.avatar_src.replace( /&amp;/g, '&' ) );
     204                                                wrap.find('div.post-locked-avatar').empty().append( avatar );
     205                                        }
     206
     207                                        wrap.show().find('.currently-editing').text( received.lock_error.text );
     208                                        wrap.find('.wp-tab-first').focus();
    131209                                }
    132 
    133                                 if ( received.lock_error.avatar_src ) {
    134                                         avatar = $( '<img class="avatar avatar-64 photo" width="64" height="64" alt="" />' ).attr( 'src', received.lock_error.avatar_src.replace( /&amp;/g, '&' ) );
    135                                         wrap.find('div.post-locked-avatar').empty().append( avatar );
     210                        } else if ( received.new_lock ) {
     211                                $('#active_post_lock').val( received.new_lock );
     212                        }
     213                }
     214        }).on( 'before-autosave.update-post-slug', function() {
     215                titleHasFocus = document.activeElement && document.activeElement.id === 'title';
     216        }).on( 'after-autosave.update-post-slug', function() {
     217
     218                /*
     219                 * Create slug area only if not already there
     220                 * and the title field was not focused (user was not typing a title) when autosave ran.
     221                 */
     222                if ( ! $('#edit-slug-box > *').length && ! titleHasFocus ) {
     223                        $.post( ajaxurl, {
     224                                        action: 'sample-permalink',
     225                                        post_id: $('#post_ID').val(),
     226                                        new_title: $('#title').val(),
     227                                        samplepermalinknonce: $('#samplepermalinknonce').val()
     228                                },
     229                                function( data ) {
     230                                        if ( data != '-1' ) {
     231                                                $('#edit-slug-box').html(data);
     232                                        }
    136233                                }
    137 
    138                                 wrap.show().find('.currently-editing').text( received.lock_error.text );
    139                                 wrap.find('.wp-tab-first').focus();
    140                         }
    141                 } else if ( received.new_lock ) {
    142                         $('#active_post_lock').val( received.new_lock );
    143                 }
    144         }
    145 }).on( 'before-autosave.update-post-slug', function() {
    146         titleHasFocus = document.activeElement && document.activeElement.id === 'title';
    147 }).on( 'after-autosave.update-post-slug', function() {
    148         // Create slug area only if not already there
    149         // and the title field was not focused (user was not typing a title) when autosave ran
    150         if ( ! $('#edit-slug-box > *').length && ! titleHasFocus ) {
    151                 $.post( ajaxurl, {
    152                                 action: 'sample-permalink',
    153                                 post_id: $('#post_ID').val(),
    154                                 new_title: $('#title').val(),
    155                                 samplepermalinknonce: $('#samplepermalinknonce').val()
    156                         },
    157                         function( data ) {
    158                                 if ( data != '-1' ) {
    159                                         $('#edit-slug-box').html(data);
    160                                 }
    161                         }
    162                 );
    163         }
    164 });
     234                        );
     235                }
     236        });
    165237
    166238}(jQuery));
    167239
     240/**
     241 * Heartbeat refresh nonces.
     242 */
    168243(function($) {
    169244        var check, timeout;
    170245
     246        /**
     247         * Only allow to check for nonce refresh every 30 seconds.
     248         */
    171249        function schedule() {
    172250                check = false;
     
    206284}(jQuery));
    207285
     286/**
     287 * All post and postbox controls and functionality.
     288 */
    208289jQuery(document).ready( function($) {
    209290        var stamp, visibility, $submitButtons, updateVisibility, updateText,
     
    221302        postboxes.add_postbox_toggles(pagenow);
    222303
    223         // Clear the window name. Otherwise if this is a former preview window where the user navigated to edit another post,
    224         // and the first post is still being edited, clicking Preview there will use this window to show the preview.
     304        /*
     305         * Clear the window name. Otherwise if this is a former preview window where the user navigated to edit another post,
     306         * and the first post is still being edited, clicking Preview there will use this window to show the preview.
     307         */
    225308        window.name = '';
    226309
    227310        // Post locks: contain focus inside the dialog. If the dialog is shown, focus the first item.
    228311        $('#post-lock-dialog .notification-dialog').on( 'keydown', function(e) {
     312                // Don't do anything when [tab] is pressed.
    229313                if ( e.which != 9 )
    230314                        return;
     
    232316                var target = $(e.target);
    233317
     318                // [shift] + [tab] on first tab cycles back to last tab.
    234319                if ( target.hasClass('wp-tab-first') && e.shiftKey ) {
    235320                        $(this).find('.wp-tab-last').focus();
    236321                        e.preventDefault();
     322                // [tab] on last tab cycles back to first tab.
    237323                } else if ( target.hasClass('wp-tab-last') && ! e.shiftKey ) {
    238324                        $(this).find('.wp-tab-first').focus();
     
    241327        }).filter(':visible').find('.wp-tab-first').focus();
    242328
    243         // Set the heartbeat interval to 15 sec. if post lock dialogs are enabled
     329        // Set the heartbeat interval to 15 sec. if post lock dialogs are enabled.
    244330        if ( wp.heartbeat && $('#post-lock-dialog').length ) {
    245331                wp.heartbeat.interval( 15 );
    246332        }
    247333
    248         // The form is being submitted by the user
     334        // The form is being submitted by the user.
    249335        $submitButtons = $submitpost.find( ':submit, a.submitdelete, #post-preview' ).on( 'click.edit-post', function( event ) {
    250336                var $button = $(this);
     
    266352                        }
    267353
    268                         // Stop autosave
     354                        // Stop auto save.
    269355                        if ( wp.autosave ) {
    270356                                wp.autosave.server.suspend();
     
    351437        });
    352438
    353         // Autosave new posts after a title is typed
     439        // Auto save new posts after a title is typed.
    354440        if ( $( '#auto_draft' ).val() ) {
    355441                $( '#title' ).blur( function() {
     
    360446                        }
    361447
    362                         // Cancel the autosave when the blur was triggered by the user submitting the form
     448                        // Cancel the auto save when the blur was triggered by the user submitting the form.
    363449                        $('form#post').one( 'submit', function() {
    364450                                cancel = true;
     
    389475        });
    390476
     477        /*
     478         * When the user is trying to load another page, or reloads current page
     479         * show a confirmation dialog when there are unsaved changes.
     480         */
    391481        $(window).on( 'beforeunload.edit-post', function() {
    392482                var editor = typeof tinymce !== 'undefined' && tinymce.get('content');
     
    402492                }
    403493
    404                 // Unload is triggered (by hand) on removing the Thickbox iframe.
    405                 // Make sure we process only the main document unload.
     494                /*
     495                 * Unload is triggered (by hand) on removing the Thickbox iframe.
     496                 * Make sure we process only the main document unload.
     497                 */
    406498                if ( event.target && event.target.nodeName != '#document' ) {
    407499                        return;
     
    436528        });
    437529
    438         // multi-taxonomies
     530        // Multiple Taxonomies.
    439531        if ( $('#tagsdiv-post_tag').length ) {
    440532                window.tagBox && window.tagBox.init();
     
    448540        }
    449541
    450         // categories
     542        // Handle categories.
    451543        $('.categorydiv').each( function(){
    452544                var this_id = $(this).attr('id'), catAddBefore, catAddAfter, taxonomyParts, taxonomy, settingName;
     
    456548                taxonomy = taxonomyParts.join('-');
    457549                settingName = taxonomy + '_tab';
    458                 if ( taxonomy == 'category' )
     550
     551                if ( taxonomy == 'category' ) {
    459552                        settingName = 'cats';
     553                }
    460554
    461555                // TODO: move to jQuery 1.3+, support for multiple hierarchical taxonomies, see wp-lists.js
     
    466560                        $('#' + taxonomy + '-tabs').siblings('.tabs-panel').hide();
    467561                        $(t).show();
    468                         if ( '#' + taxonomy + '-all' == t )
     562                        if ( '#' + taxonomy + '-all' == t ) {
    469563                                deleteUserSetting( settingName );
    470                         else
     564                        } else {
    471565                                setUserSetting( settingName, 'pop' );
     566                        }
    472567                });
    473568
     
    475570                        $('a[href="#' + taxonomy + '-pop"]', '#' + taxonomy + '-tabs').click();
    476571
    477                 // Ajax Cat
    478                 $( '#new' + taxonomy ).one( 'focus', function() { $( this ).val( '' ).removeClass( 'form-input-tip' ); } );
    479 
     572                // Add category button controls.
     573                $('#new' + taxonomy).one( 'focus', function() {
     574                        $( this ).val( '' ).removeClass( 'form-input-tip' );
     575                });
     576
     577                // On [enter] submit the taxonomy.
    480578                $('#new' + taxonomy).keypress( function(event){
    481579                        if( 13 === event.keyCode ) {
     
    484582                        }
    485583                });
    486                 $('#' + taxonomy + '-add-submit').click( function(){ $('#new' + taxonomy).focus(); });
    487 
     584
     585                // After submitting a new taxonomy, re-focus the input field.
     586                $('#' + taxonomy + '-add-submit').click( function() {
     587                        $('#new' + taxonomy).focus();
     588                });
     589
     590                /**
     591                 * Before adding a new taxonomy, disable submit button.
     592                 *
     593                 * @param {Object} s Taxonomy object which will be added.
     594                 *
     595                 * @returns {Object}
     596                 */
    488597                catAddBefore = function( s ) {
    489                         if ( !$('#new'+taxonomy).val() )
     598                        if ( !$('#new'+taxonomy).val() ) {
    490599                                return false;
     600                        }
     601
    491602                        s.data += '&' + $( ':checked', '#'+taxonomy+'checklist' ).serialize();
    492603                        $( '#' + taxonomy + '-add-submit' ).prop( 'disabled', true );
     
    494605                };
    495606
     607                /**
     608                 * Re-enable submit button after a taxonomy has been added.
     609                 *
     610                 * Re-enable submit button.
     611                 * If the taxonomy has a parent place the taxonomy underneath the parent.
     612                 *
     613                 * @param {Object} r Response.
     614                 * @param {Object} s Taxonomy data.
     615                 *
     616                 * @returns void
     617                 */
    496618                catAddAfter = function( r, s ) {
    497619                        var sup, drop = $('#new'+taxonomy+'_parent');
     
    511633                });
    512634
     635                // Add new taxonomy button toggles input form visibility.
    513636                $('#' + taxonomy + '-add-toggle').click( function( e ) {
    514637                        e.preventDefault();
     
    518641                });
    519642
     643                // Sync checked items between "All {taxonomy}" and "Most used" lists.
    520644                $('#' + taxonomy + 'checklist, #' + taxonomy + 'checklist-pop').on( 'click', 'li.popular-category > label input[type="checkbox"]', function() {
    521645                        var t = $(this), c = t.is(':checked'), id = t.val();
     
    526650        }); // end cats
    527651
    528         // Custom Fields
     652        // Custom Fields postbox.
    529653        if ( $('#postcustom').length ) {
    530                 $( '#the-list' ).wpList( { addAfter: function() {
    531                         $('table#list-table').show();
    532                 }, addBefore: function( s ) {
    533                         s.data += '&post_id=' + $('#post_ID').val();
    534                         return s;
    535                 }
     654                $( '#the-list' ).wpList( {
     655                        /**
     656                         * Add current post_ID to request to fetch custom fields
     657                         *
     658                         * @param {Object} s Request object.
     659                         *
     660                         * @returns {Object} Data modified with post_ID attached.
     661                         */
     662                        addBefore: function( s ) {
     663                                s.data += '&post_id=' + $('#post_ID').val();
     664                                return s;
     665                        },
     666                        /**
     667                         * Show the listing of custom fields after fetching.
     668                         */
     669                        addAfter: function() {
     670                                $('table#list-table').show();
     671                        }
    536672                });
    537673        }
    538674
    539         // submitdiv
     675        /*
     676         * Publish Post box (#submitdiv)
     677         */
    540678        if ( $('#submitdiv').length ) {
    541679                stamp = $('#timestamp').html();
    542680                visibility = $('#post-visibility-display').html();
    543681
     682                /**
     683                 * When the visibility of a post changes sub-options should be shown or hidden.
     684                 *
     685                 * @returns void
     686                 */
    544687                updateVisibility = function() {
     688                        // Show sticky for public posts.
    545689                        if ( $postVisibilitySelect.find('input:radio:checked').val() != 'public' ) {
    546690                                $('#sticky').prop('checked', false);
     
    549693                                $('#sticky-span').show();
    550694                        }
     695
     696                        // Show password input field for password protected post.
    551697                        if ( $postVisibilitySelect.find('input:radio:checked').val() != 'password' ) {
    552698                                $('#password-span').hide();
     
    556702                };
    557703
     704                /**
     705                 * Make sure all labels represent the current settings.
     706                 *
     707                 * @returns {boolean} False when an invalid timestamp has been selected, otherwise True.
     708                 */
    558709                updateText = function() {
    559710
     
    569720                        currentDate = new Date( $('#cur_aa').val(), $('#cur_mm').val() -1, $('#cur_jj').val(), $('#cur_hh').val(), $('#cur_mn').val() );
    570721
     722                        // Catch unexpected date problems.
    571723                        if ( attemptedDate.getFullYear() != aa || (1 + attemptedDate.getMonth()) != mm || attemptedDate.getDate() != jj || attemptedDate.getMinutes() != mn ) {
    572724                                $timestampdiv.find('.timestamp-wrap').addClass('form-invalid');
     
    576728                        }
    577729
     730                        // Determine what the publish should be depending on the date and post status.
    578731                        if ( attemptedDate > currentDate && $('#original_post_status').val() != 'future' ) {
    579732                                publishOn = postL10n.publishOnFuture;
     
    586739                                $('#publish').val( postL10n.update );
    587740                        }
    588                         if ( originalDate.toUTCString() == attemptedDate.toUTCString() ) { //hack
     741
     742                        // If the date is the same, set it to trigger update events.
     743                        if ( originalDate.toUTCString() == attemptedDate.toUTCString() ) {
     744                                // Re-set to the current value.
    589745                                $('#timestamp').html(stamp);
    590746                        } else {
     
    601757                        }
    602758
     759                        // Add "privately published" to post status when applies.
    603760                        if ( $postVisibilitySelect.find('input:radio:checked').val() == 'private' ) {
    604761                                $('#publish').val( postL10n.update );
     
    622779                                        $('#misc-publishing-actions .edit-post-status').show();
    623780                        }
     781
     782                        // Update "Status:" to currently selected status.
    624783                        $('#post-status-display').html($('option:selected', postStatus).text());
     784
     785                        // Show or hide the "Save Draft" button.
    625786                        if ( $('option:selected', postStatus).val() == 'private' || $('option:selected', postStatus).val() == 'publish' ) {
    626787                                $('#save-post').hide();
     
    636797                };
    637798
     799                // Show the visibility options and hide the toggle button when opened.
    638800                $( '#visibility .edit-visibility').click( function( e ) {
    639801                        e.preventDefault();
     
    647809                });
    648810
     811                // Cancel visibility selection area and hide it from view.
    649812                $postVisibilitySelect.find('.cancel-post-visibility').click( function( event ) {
    650813                        $postVisibilitySelect.slideUp('fast');
     
    658821                });
    659822
     823                // Set the selected visibility as current.
    660824                $postVisibilitySelect.find('.save-post-visibility').click( function( event ) { // crazyhorse - multiple ok cancels
    661825                        $postVisibilitySelect.slideUp('fast');
     
    665829                        if ( $postVisibilitySelect.find('input:radio:checked').val() != 'public' ) {
    666830                                $('#sticky').prop('checked', false);
    667                         } // WEAPON LOCKED
     831                        }
    668832
    669833                        if ( $('#sticky').prop('checked') ) {
     
    677841                });
    678842
     843                // When the selection changes, update labels.
    679844                $postVisibilitySelect.find('input:radio').change( function() {
    680845                        updateVisibility();
    681846                });
    682847
     848                // Edit publish time click.
    683849                $timestampdiv.siblings('a.edit-timestamp').click( function( event ) {
    684850                        if ( $timestampdiv.is( ':hidden' ) ) {
     
    691857                });
    692858
     859                // Cancel editing the publish time and hide the settings.
    693860                $timestampdiv.find('.cancel-timestamp').click( function( event ) {
    694861                        $timestampdiv.slideUp('fast').siblings('a.edit-timestamp').show().focus();
     
    702869                });
    703870
     871                // Save the changed timestamp.
    704872                $timestampdiv.find('.save-timestamp').click( function( event ) { // crazyhorse - multiple ok cancels
    705873                        if ( updateText() ) {
     
    710878                });
    711879
     880                // Cancel submit when an invalid timestamp has been selected.
    712881                $('#post').on( 'submit', function( event ) {
    713882                        if ( ! updateText() ) {
     
    723892                });
    724893
     894                // Post Status edit click.
    725895                $postStatusSelect.siblings('a.edit-post-status').click( function( event ) {
    726896                        if ( $postStatusSelect.is( ':hidden' ) ) {
     
    733903                });
    734904
     905                // Save the Post Status changes and hide the options.
    735906                $postStatusSelect.find('.save-post-status').click( function( event ) {
    736907                        $postStatusSelect.slideUp( 'fast' ).siblings( 'a.edit-post-status' ).show().focus();
     
    739910                });
    740911
     912                // Cancel Post Status editing and hide the options.
    741913                $postStatusSelect.find('.cancel-post-status').click( function( event ) {
    742914                        $postStatusSelect.slideUp( 'fast' ).siblings( 'a.edit-post-status' ).show().focus();
     
    745917                        event.preventDefault();
    746918                });
    747         } // end submitdiv
    748 
    749         // permalink
     919        }
     920
     921        /**
     922         * Handle the editing of the post_name. Create the required HTML elements and update the changes via AJAX.
     923         *
     924         * @summary Permalink aka slug aka post_name editing
     925         *
     926         * @global
     927         *
     928         * @returns void
     929         */
    750930        function editPermalink() {
    751931                var i, slug_value,
     
    761941                        full = $('#editable-post-name-full');
    762942
    763                 // Deal with Twemoji in the post-name
     943                // Deal with Twemoji in the post-name.
    764944                full.find( 'img' ).replaceWith( function() { return this.alt; } );
    765945                full = full.html();
    766946
    767947                permalink.html( permalinkInner );
     948
     949                // Save current content to revert to when cancelling.
    768950                $el = $( '#editable-post-name' );
    769951                revert_e = $el.html();
    770952
    771953                buttons.html( '<button type="button" class="save button button-small">' + postL10n.ok + '</button> <button type="button" class="cancel button-link">' + postL10n.cancel + '</button>' );
     954
     955                // Save permalink changes.
    772956                buttons.children( '.save' ).click( function() {
    773957                        var new_slug = $el.children( 'input' ).val();
     
    777961                                return;
    778962                        }
    779                         $.post(ajaxurl, {
    780                                 action: 'sample-permalink',
    781                                 post_id: postId,
    782                                 new_slug: new_slug,
    783                                 new_title: $('#title').val(),
    784                                 samplepermalinknonce: $('#samplepermalinknonce').val()
    785                         }, function(data) {
    786                                 var box = $('#edit-slug-box');
    787                                 box.html(data);
    788                                 if (box.hasClass('hidden')) {
    789                                         box.fadeIn('fast', function () {
    790                                                 box.removeClass('hidden');
    791                                         });
     963
     964                        $.post(
     965                                ajaxurl,
     966                                {
     967                                        action: 'sample-permalink',
     968                                        post_id: postId,
     969                                        new_slug: new_slug,
     970                                        new_title: $('#title').val(),
     971                                        samplepermalinknonce: $('#samplepermalinknonce').val()
     972                                },
     973                                function(data) {
     974                                        var box = $('#edit-slug-box');
     975                                        box.html(data);
     976                                        if (box.hasClass('hidden')) {
     977                                                box.fadeIn('fast', function () {
     978                                                        box.removeClass('hidden');
     979                                                });
     980                                        }
     981
     982                                        buttons.html(buttonsOrig);
     983                                        permalink.html(permalinkOrig);
     984                                        real_slug.val(new_slug);
     985                                        $( '.edit-slug' ).focus();
     986                                        wp.a11y.speak( postL10n.permalinkSaved );
    792987                                }
    793 
    794                                 buttons.html(buttonsOrig);
    795                                 permalink.html(permalinkOrig);
    796                                 real_slug.val(new_slug);
    797                                 $( '.edit-slug' ).focus();
    798                                 wp.a11y.speak( postL10n.permalinkSaved );
    799                         });
    800                 });
    801 
     988                        );
     989                });
     990
     991                // Cancel editing of permalink.
    802992                buttons.children( '.cancel' ).click( function() {
    803993                        $('#view-post-btn').show();
     
    809999                });
    8101000
     1001                // If more than 1/4th of 'full' is '%', make it empty.
    8111002                for ( i = 0; i < full.length; ++i ) {
    8121003                        if ( '%' == full.charAt(i) )
    8131004                                c++;
    8141005                }
    815 
    8161006                slug_value = ( c > full.length / 4 ) ? '' : full;
     1007
    8171008                $el.html( '<input type="text" id="new-post-slug" value="' + slug_value + '" autocomplete="off" />' ).children( 'input' ).keydown( function( e ) {
    8181009                        var key = e.which;
    819                         // On enter, just save the new slug, don't save the post.
     1010                        // On [enter], just save the new slug, don't save the post.
    8201011                        if ( 13 === key ) {
    8211012                                e.preventDefault();
    8221013                                buttons.children( '.save' ).click();
    8231014                        }
     1015                        // On [esc] cancel the editing.
    8241016                        if ( 27 === key ) {
    8251017                                buttons.children( '.cancel' ).click();
     
    8341026        });
    8351027
     1028        /**
     1029         * Add screen reader text to the title prompt when needed.
     1030         *
     1031         * @summary Title screen reader text handler.
     1032         *
     1033         * @param {string} id Optional. HTML ID to add the screen reader helper text to.
     1034         *
     1035         * @global
     1036         *
     1037         * @returns void
     1038         */
    8361039        wptitlehint = function(id) {
    8371040                id = id || 'title';
     
    8601063        wptitlehint();
    8611064
    862         // Resize the visual and text editors
     1065        // Resize the WYSIWYG and plain text editors.
    8631066        ( function() {
    8641067                var editor, offset, mce,
     
    8661069                        $postdivrich = $('#postdivrich');
    8671070
    868                 // No point for touch devices
     1071                // If there are no textareas or we are on a touch device, we can't do anything.
    8691072                if ( ! $textarea.length || 'ontouchstart' in window ) {
    870                         // Hide the resize handle
     1073                        // Hide the resize handle.
    8711074                        $('#content-resize-handle').hide();
    8721075                        return;
    8731076                }
    8741077
     1078                /**
     1079                 * Handle drag event.
     1080                 *
     1081                 * @param {Object} event Event containing details about the drag.
     1082                 */
    8751083                function dragging( event ) {
    8761084                        if ( $postdivrich.hasClass( 'wp-editor-expand' ) ) {
     
    8871095                }
    8881096
     1097                /**
     1098                 * When the dragging stopped make sure we return focus and do a sanity check on the height.
     1099                 */
    8891100                function endDrag() {
    8901101                        var height, toolbarHeight;
     
    9101121                        $document.off( '.wp-editor-resize' );
    9111122
    912                         // sanity check
     1123                        // Sanity check: normalize height to stay within acceptable ranges.
    9131124                        if ( height && height > 50 && height < 5000 ) {
    9141125                                setUserSetting( 'ed_size', height );
     
    9371148        })();
    9381149
     1150        // TinyMCE specific handling of Post Format changes to reflect in the editor.
    9391151        if ( typeof tinymce !== 'undefined' ) {
    940                 // When changing post formats, change the editor body class
     1152                // When changing post formats, change the editor body class.
    9411153                $( '#post-formats-select input.post-format' ).on( 'change.set-editor-class', function() {
    9421154                        var editor, body, format = this.id;
     
    9511163        }
    9521164
    953         // Save on pressing Ctrl/Command + S in the Text editor
     1165        // Save on pressing [ctrl]/[command] + [s] in the Text editor.
    9541166        $textarea.on( 'keydown.wp-autosave', function( event ) {
     1167                // Key [s] has code 83.
    9551168                if ( event.which === 83 ) {
    9561169                        if ( event.shiftKey || event.altKey || ( isMac && ( ! event.metaKey || event.ctrlKey ) ) || ( ! isMac && ! event.ctrlKey ) ) {
     
    9631176        });
    9641177
     1178        // If the last status was auto-draft and the save is triggered, edit the current URL.
    9651179        if ( $( '#original_post_status' ).val() === 'auto-draft' && window.history.replaceState ) {
    9661180                var location;
     
    9761190});
    9771191
     1192/**
     1193 * TinyMCE word count display
     1194 */
    9781195( function( $, counter ) {
    9791196        $( function() {
     
    9831200                        contentEditor;
    9841201
     1202                /**
     1203                 * Get the word count from TinyMCE and display it
     1204                 */
    9851205                function update() {
    9861206                        var text, count;
     
    10011221                }
    10021222
     1223                /**
     1224                 * Bind the word count update triggers.
     1225                 *
     1226                 * When a node change in the main TinyMCE editor has been triggered.
     1227                 * When a key has been released in the plain text content editor.
     1228                 */
    10031229                $( document ).on( 'tinymce-editor-init', function( event, editor ) {
    10041230                        if ( editor.id !== 'content' ) {
Note: See TracChangeset for help on using the changeset viewer.