wp/wp-admin/js/post.js
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     1 /* global postL10n, ajaxurl, wpAjax, setPostThumbnailL10n, postboxes, pagenow, tinymce, alert, deleteUserSetting */
     1 /* global postL10n, ajaxurl, wpAjax, setPostThumbnailL10n, postboxes, pagenow, tinymce, alert, deleteUserSetting */
     2 /* global theList:true, theExtraList:true, getUserSetting, setUserSetting */
     2 /* global theList:true, theExtraList:true, getUserSetting, setUserSetting, commentReply */
       
     3 
       
     4 /**
       
     5  * Contains all dynamic functionality needed on post and term pages.
       
     6  *
       
     7  * @summary Control page and term functionality.
       
     8  */
     3 
     9 
     4 var commentsBox, WPSetThumbnailHTML, WPSetThumbnailID, WPRemoveThumbnail, wptitlehint, makeSlugeditClickable, editPermalink;
    10 var commentsBox, WPSetThumbnailHTML, WPSetThumbnailID, WPRemoveThumbnail, wptitlehint, makeSlugeditClickable, editPermalink;
     5 // Back-compat: prevent fatal errors
    11 // Backwards compatibility: prevent fatal errors.
     6 makeSlugeditClickable = editPermalink = function(){};
    12 makeSlugeditClickable = editPermalink = function(){};
     7 
    13 
       
    14 // Make sure the wp object exists.
     8 window.wp = window.wp || {};
    15 window.wp = window.wp || {};
     9 
    16 
    10 ( function( $ ) {
    17 ( function( $ ) {
    11 	var titleHasFocus = false;
    18 	var titleHasFocus = false;
    12 
    19 
    13 commentsBox = {
    20 	/**
    14 	st : 0,
    21 	 * Control loading of comments on the post and term edit pages.
    15 
    22 	 *
    16 	get : function(total, num) {
    23 	 * @type {{st: number, get: commentsBox.get, load: commentsBox.load}}
    17 		var st = this.st, data;
    24 	 *
    18 		if ( ! num )
    25 	 * @namespace commentsBox
    19 			num = 20;
    26 	 */
    20 
    27 	commentsBox = {
    21 		this.st += num;
    28 		// Comment offset to use when fetching new comments.
    22 		this.total = total;
    29 		st : 0,
    23 		$( '#commentsdiv .spinner' ).addClass( 'is-active' );
    30 
    24 
    31 		/**
    25 		data = {
    32 		 * Fetch comments using AJAX and display them in the box.
    26 			'action' : 'get-comments',
    33 		 *
    27 			'mode' : 'single',
    34 		 * @param {int} total Total number of comments for this post.
    28 			'_ajax_nonce' : $('#add_comment_nonce').val(),
    35 		 * @param {int} num   Optional. Number of comments to fetch, defaults to 20.
    29 			'p' : $('#post_ID').val(),
    36 		 * @returns {boolean} Always returns false.
    30 			'start' : st,
    37 		 *
    31 			'number' : num
    38 		 * @memberof commentsBox
    32 		};
    39 		 */
    33 
    40 		get : function(total, num) {
    34 		$.post(ajaxurl, data,
    41 			var st = this.st, data;
    35 			function(r) {
    42 			if ( ! num )
    36 				r = wpAjax.parseAjaxResponse(r);
    43 				num = 20;
    37 				$('#commentsdiv .widefat').show();
    44 
    38 				$( '#commentsdiv .spinner' ).removeClass( 'is-active' );
    45 			this.st += num;
    39 
    46 			this.total = total;
    40 				if ( 'object' == typeof r && r.responses[0] ) {
    47 			$( '#commentsdiv .spinner' ).addClass( 'is-active' );
    41 					$('#the-comment-list').append( r.responses[0].data );
    48 
    42 
    49 			data = {
    43 					theList = theExtraList = null;
    50 				'action' : 'get-comments',
    44 					$( 'a[className*=\':\']' ).unbind();
    51 				'mode' : 'single',
    45 
    52 				'_ajax_nonce' : $('#add_comment_nonce').val(),
    46 					if ( commentsBox.st > commentsBox.total )
    53 				'p' : $('#post_ID').val(),
    47 						$('#show-comments').hide();
    54 				'start' : st,
    48 					else
    55 				'number' : num
    49 						$('#show-comments').show().children('a').html(postL10n.showcomm);
    56 			};
    50 
    57 
    51 					return;
    58 			$.post(
    52 				} else if ( 1 == r ) {
    59 				ajaxurl,
    53 					$('#show-comments').html(postL10n.endcomm);
    60 				data,
    54 					return;
    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>');
    55 				}
    85 				}
    56 
    86 			);
    57 				$('#the-comment-list').append('<tr><td colspan="2">'+wpAjax.broken+'</td></tr>');
    87 
    58 			}
    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 occurred 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 		}
    59 		);
   152 		);
    60 
   153 	};
    61 		return false;
   154 
    62 	}
   155 	/**
    63 };
   156 	 * Heartbeat locks.
    64 
   157 	 *
    65 WPSetThumbnailHTML = function(html){
   158 	 * Used to lock editing of an object by only one user at a time.
    66 	$('.inside', '#postimagediv').html(html);
   159 	 *
    67 };
   160 	 * When the user does not send a heartbeat in a heartbeat-time
    68 
   161 	 * the user is no longer editing and another user can start editing.
    69 WPSetThumbnailID = function(id){
   162 	 */
    70 	var field = $('input[value="_thumbnail_id"]', '#list-table');
   163 	$(document).on( 'heartbeat-send.refresh-lock', function( e, data ) {
    71 	if ( field.size() > 0 ) {
   164 		var lock = $('#active_post_lock').val(),
    72 		$('#meta\\[' + field.attr('id').match(/[0-9]+/) + '\\]\\[value\\]').text(id);
   165 			post_id = $('#post_ID').val(),
    73 	}
   166 			send = {};
    74 };
   167 
    75 
   168 		if ( ! post_id || ! $('#post-lock-dialog').length )
    76 WPRemoveThumbnail = function(nonce){
   169 			return;
    77 	$.post(ajaxurl, {
   170 
    78 		action: 'set-post-thumbnail', post_id: $( '#post_ID' ).val(), thumbnail_id: -1, _ajax_nonce: nonce, cookie: encodeURIComponent( document.cookie )
   171 		send.post_id = post_id;
    79 	}, function(str){
   172 
    80 		if ( str == '0' ) {
   173 		if ( lock )
    81 			alert( setPostThumbnailL10n.error );
   174 			send.lock = lock;
    82 		} else {
   175 
    83 			WPSetThumbnailHTML(str);
   176 		data['wp-refresh-post-lock'] = send;
    84 		}
   177 
    85 	}
   178 	}).on( 'heartbeat-tick.refresh-lock', function( e, data ) {
    86 	);
   179 		// Post locks: update the lock string or show the dialog if somebody has taken over editing.
    87 };
   180 		var received, wrap, avatar;
    88 
   181 
    89 $(document).on( 'heartbeat-send.refresh-lock', function( e, data ) {
   182 		if ( data['wp-refresh-post-lock'] ) {
    90 	var lock = $('#active_post_lock').val(),
   183 			received = data['wp-refresh-post-lock'];
    91 		post_id = $('#post_ID').val(),
   184 
    92 		send = {};
   185 			if ( received.lock_error ) {
    93 
   186 				// Show "editing taken over" message.
    94 	if ( ! post_id || ! $('#post-lock-dialog').length )
   187 				wrap = $('#post-lock-dialog');
    95 		return;
   188 
    96 
   189 				if ( wrap.length && ! wrap.is(':visible') ) {
    97 	send.post_id = post_id;
   190 					if ( wp.autosave ) {
    98 
   191 						// Save the latest changes and disable.
    99 	if ( lock )
   192 						$(document).one( 'heartbeat-tick', function() {
   100 		send.lock = lock;
   193 							wp.autosave.server.suspend();
   101 
   194 							wrap.removeClass('saving').addClass('saved');
   102 	data['wp-refresh-post-lock'] = send;
   195 							$(window).off( 'beforeunload.edit-post' );
   103 
   196 						});
   104 }).on( 'heartbeat-tick.refresh-lock', function( e, data ) {
   197 
   105 	// Post locks: update the lock string or show the dialog if somebody has taken over editing
   198 						wrap.addClass('saving');
   106 	var received, wrap, avatar;
   199 						wp.autosave.server.triggerSave();
   107 
   200 					}
   108 	if ( data['wp-refresh-post-lock'] ) {
   201 
   109 		received = data['wp-refresh-post-lock'];
   202 					if ( received.lock_error.avatar_src ) {
   110 
   203 						avatar = $( '<img class="avatar avatar-64 photo" width="64" height="64" alt="" />' ).attr( 'src', received.lock_error.avatar_src.replace( /&amp;/g, '&' ) );
   111 		if ( received.lock_error ) {
   204 						wrap.find('div.post-locked-avatar').empty().append( avatar );
   112 			// show "editing taken over" message
   205 					}
   113 			wrap = $('#post-lock-dialog');
   206 
   114 
   207 					wrap.show().find('.currently-editing').text( received.lock_error.text );
   115 			if ( wrap.length && ! wrap.is(':visible') ) {
   208 					wrap.find('.wp-tab-first').focus();
   116 				if ( wp.autosave ) {
       
   117 					// Save the latest changes and disable
       
   118 					$(document).one( 'heartbeat-tick', function() {
       
   119 						wp.autosave.server.suspend();
       
   120 						wrap.removeClass('saving').addClass('saved');
       
   121 						$(window).off( 'beforeunload.edit-post' );
       
   122 					});
       
   123 
       
   124 					wrap.addClass('saving');
       
   125 					wp.autosave.server.triggerSave();
       
   126 				}
   209 				}
   127 
   210 			} else if ( received.new_lock ) {
   128 				if ( received.lock_error.avatar_src ) {
   211 				$('#active_post_lock').val( received.new_lock );
   129 					avatar = $('<img class="avatar avatar-64 photo" width="64" height="64" />').attr( 'src', received.lock_error.avatar_src.replace(/&amp;/g, '&') );
   212 			}
   130 					wrap.find('div.post-locked-avatar').empty().append( avatar );
   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 					}
   131 				}
   233 				}
   132 
   234 			);
   133 				wrap.show().find('.currently-editing').text( received.lock_error.text );
   235 		}
   134 				wrap.find('.wp-tab-first').focus();
   236 	});
   135 			}
       
   136 		} else if ( received.new_lock ) {
       
   137 			$('#active_post_lock').val( received.new_lock );
       
   138 		}
       
   139 	}
       
   140 }).on( 'before-autosave.update-post-slug', function() {
       
   141 	titleHasFocus = document.activeElement && document.activeElement.id === 'title';
       
   142 }).on( 'after-autosave.update-post-slug', function() {
       
   143 	// Create slug area only if not already there
       
   144 	// and the title field was not focused (user was not typing a title) when autosave ran
       
   145 	if ( ! $('#edit-slug-box > *').length && ! titleHasFocus ) {
       
   146 		$.post( ajaxurl, {
       
   147 				action: 'sample-permalink',
       
   148 				post_id: $('#post_ID').val(),
       
   149 				new_title: $('#title').val(),
       
   150 				samplepermalinknonce: $('#samplepermalinknonce').val()
       
   151 			},
       
   152 			function( data ) {
       
   153 				if ( data != '-1' ) {
       
   154 					$('#edit-slug-box').html(data);
       
   155 				}
       
   156 			}
       
   157 		);
       
   158 	}
       
   159 });
       
   160 
   237 
   161 }(jQuery));
   238 }(jQuery));
   162 
   239 
       
   240 /**
       
   241  * Heartbeat refresh nonces.
       
   242  */
   163 (function($) {
   243 (function($) {
   164 	var check, timeout;
   244 	var check, timeout;
   165 
   245 
       
   246 	/**
       
   247 	 * Only allow to check for nonce refresh every 30 seconds.
       
   248 	 */
   166 	function schedule() {
   249 	function schedule() {
   167 		check = false;
   250 		check = false;
   168 		window.clearTimeout( timeout );
   251 		window.clearTimeout( timeout );
   169 		timeout = window.setTimeout( function(){ check = true; }, 300000 );
   252 		timeout = window.setTimeout( function(){ check = true; }, 300000 );
   170 	}
   253 	}
   171 
   254 
   172 	$(document).on( 'heartbeat-send.wp-refresh-nonces', function( e, data ) {
   255 	$(document).on( 'heartbeat-send.wp-refresh-nonces', function( e, data ) {
   173 		var nonce, post_id;
   256 		var post_id,
   174 
   257 			$authCheck = $('#wp-auth-check-wrap');
   175 		if ( check ) {
   258 
   176 			if ( ( post_id = $('#post_ID').val() ) && ( nonce = $('#_wpnonce').val() ) ) {
   259 		if ( check || ( $authCheck.length && ! $authCheck.hasClass( 'hidden' ) ) ) {
       
   260 			if ( ( post_id = $('#post_ID').val() ) && $('#_wpnonce').val() ) {
   177 				data['wp-refresh-post-nonces'] = {
   261 				data['wp-refresh-post-nonces'] = {
   178 					post_id: post_id,
   262 					post_id: post_id
   179 					post_nonce: nonce
       
   180 				};
   263 				};
   181 			}
   264 			}
   182 		}
   265 		}
   183 	}).on( 'heartbeat-tick.wp-refresh-nonces', function( e, data ) {
   266 	}).on( 'heartbeat-tick.wp-refresh-nonces', function( e, data ) {
   184 		var nonces = data['wp-refresh-post-nonces'];
   267 		var nonces = data['wp-refresh-post-nonces'];
   198 	}).ready( function() {
   281 	}).ready( function() {
   199 		schedule();
   282 		schedule();
   200 	});
   283 	});
   201 }(jQuery));
   284 }(jQuery));
   202 
   285 
       
   286 /**
       
   287  * All post and postbox controls and functionality.
       
   288  */
   203 jQuery(document).ready( function($) {
   289 jQuery(document).ready( function($) {
   204 	var stamp, visibility, $submitButtons, updateVisibility, updateText,
   290 	var stamp, visibility, $submitButtons, updateVisibility, updateText,
   205 		sticky = '',
   291 		sticky = '',
   206 		last = 0,
   292 		$textarea = $('#content'),
   207 		co = $('#content'),
       
   208 		$document = $(document),
   293 		$document = $(document),
   209 		$editSlugWrap = $('#edit-slug-box'),
       
   210 		postId = $('#post_ID').val() || 0,
   294 		postId = $('#post_ID').val() || 0,
   211 		$submitpost = $('#submitpost'),
   295 		$submitpost = $('#submitpost'),
   212 		releaseLock = true,
   296 		releaseLock = true,
   213 		$postVisibilitySelect = $('#post-visibility-select'),
   297 		$postVisibilitySelect = $('#post-visibility-select'),
   214 		$timestampdiv = $('#timestampdiv'),
   298 		$timestampdiv = $('#timestampdiv'),
   215 		$postStatusSelect = $('#post-status-select');
   299 		$postStatusSelect = $('#post-status-select'),
       
   300 		isMac = window.navigator.platform ? window.navigator.platform.indexOf( 'Mac' ) !== -1 : false;
   216 
   301 
   217 	postboxes.add_postbox_toggles(pagenow);
   302 	postboxes.add_postbox_toggles(pagenow);
   218 
   303 
   219 	// Clear the window name. Otherwise if this is a former preview window where the user navigated to edit another post,
   304 	/*
   220 	// and the first post is still being edited, clicking Preview there will use this window to show the preview.
   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 	 */
   221 	window.name = '';
   308 	window.name = '';
   222 
   309 
   223 	// Post locks: contain focus inside the dialog. If the dialog is shown, focus the first item.
   310 	// Post locks: contain focus inside the dialog. If the dialog is shown, focus the first item.
   224 	$('#post-lock-dialog .notification-dialog').on( 'keydown', function(e) {
   311 	$('#post-lock-dialog .notification-dialog').on( 'keydown', function(e) {
       
   312 		// Don't do anything when [tab] is pressed.
   225 		if ( e.which != 9 )
   313 		if ( e.which != 9 )
   226 			return;
   314 			return;
   227 
   315 
   228 		var target = $(e.target);
   316 		var target = $(e.target);
   229 
   317 
       
   318 		// [shift] + [tab] on first tab cycles back to last tab.
   230 		if ( target.hasClass('wp-tab-first') && e.shiftKey ) {
   319 		if ( target.hasClass('wp-tab-first') && e.shiftKey ) {
   231 			$(this).find('.wp-tab-last').focus();
   320 			$(this).find('.wp-tab-last').focus();
   232 			e.preventDefault();
   321 			e.preventDefault();
       
   322 		// [tab] on last tab cycles back to first tab.
   233 		} else if ( target.hasClass('wp-tab-last') && ! e.shiftKey ) {
   323 		} else if ( target.hasClass('wp-tab-last') && ! e.shiftKey ) {
   234 			$(this).find('.wp-tab-first').focus();
   324 			$(this).find('.wp-tab-first').focus();
   235 			e.preventDefault();
   325 			e.preventDefault();
   236 		}
   326 		}
   237 	}).filter(':visible').find('.wp-tab-first').focus();
   327 	}).filter(':visible').find('.wp-tab-first').focus();
   238 
   328 
   239 	// 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.
   240 	if ( wp.heartbeat && $('#post-lock-dialog').length ) {
   330 	if ( wp.heartbeat && $('#post-lock-dialog').length ) {
   241 		wp.heartbeat.interval( 15 );
   331 		wp.heartbeat.interval( 15 );
   242 	}
   332 	}
   243 
   333 
   244 	// The form is being submitted by the user
   334 	// The form is being submitted by the user.
   245 	$submitButtons = $submitpost.find( ':submit, a.submitdelete, #post-preview' ).on( 'click.edit-post', function( event ) {
   335 	$submitButtons = $submitpost.find( ':submit, a.submitdelete, #post-preview' ).on( 'click.edit-post', function( event ) {
   246 		var $button = $(this);
   336 		var $button = $(this);
   247 
   337 
   248 		if ( $button.hasClass('disabled') ) {
   338 		if ( $button.hasClass('disabled') ) {
   249 			event.preventDefault();
   339 			event.preventDefault();
   259 		$('form#post').off( 'submit.edit-post' ).on( 'submit.edit-post', function( event ) {
   349 		$('form#post').off( 'submit.edit-post' ).on( 'submit.edit-post', function( event ) {
   260 			if ( event.isDefaultPrevented() ) {
   350 			if ( event.isDefaultPrevented() ) {
   261 				return;
   351 				return;
   262 			}
   352 			}
   263 
   353 
   264 			// Stop autosave
   354 			// Stop auto save.
   265 			if ( wp.autosave ) {
   355 			if ( wp.autosave ) {
   266 				wp.autosave.server.suspend();
   356 				wp.autosave.server.suspend();
       
   357 			}
       
   358 
       
   359 			if ( typeof commentReply !== 'undefined' ) {
       
   360 				/*
       
   361 				 * Warn the user they have an unsaved comment before submitting
       
   362 				 * the post data for update.
       
   363 				 */
       
   364 				if ( ! commentReply.discardCommentChanges() ) {
       
   365 					return false;
       
   366 				}
       
   367 
       
   368 				/*
       
   369 				 * Close the comment edit/reply form if open to stop the form
       
   370 				 * action from interfering with the post's form action.
       
   371 				 */
       
   372 				commentReply.close();
   267 			}
   373 			}
   268 
   374 
   269 			releaseLock = false;
   375 			releaseLock = false;
   270 			$(window).off( 'beforeunload.edit-post' );
   376 			$(window).off( 'beforeunload.edit-post' );
   271 
   377 
   311 		$previewField.val('');
   417 		$previewField.val('');
   312 	});
   418 	});
   313 
   419 
   314 	// This code is meant to allow tabbing from Title to Post content.
   420 	// This code is meant to allow tabbing from Title to Post content.
   315 	$('#title').on( 'keydown.editor-focus', function( event ) {
   421 	$('#title').on( 'keydown.editor-focus', function( event ) {
   316 		var editor, $textarea;
   422 		var editor;
   317 
   423 
   318 		if ( event.keyCode === 9 && ! event.ctrlKey && ! event.altKey && ! event.shiftKey ) {
   424 		if ( event.keyCode === 9 && ! event.ctrlKey && ! event.altKey && ! event.shiftKey ) {
   319 			editor = typeof tinymce != 'undefined' && tinymce.get('content');
   425 			editor = typeof tinymce != 'undefined' && tinymce.get('content');
   320 			$textarea = $('#content');
       
   321 
   426 
   322 			if ( editor && ! editor.isHidden() ) {
   427 			if ( editor && ! editor.isHidden() ) {
   323 				editor.focus();
   428 				editor.focus();
   324 			} else if ( $textarea.length ) {
   429 			} else if ( $textarea.length ) {
   325 				$textarea.focus();
   430 				$textarea.focus();
   329 
   434 
   330 			event.preventDefault();
   435 			event.preventDefault();
   331 		}
   436 		}
   332 	});
   437 	});
   333 
   438 
   334 	// Autosave new posts after a title is typed
   439 	// Auto save new posts after a title is typed.
   335 	if ( $( '#auto_draft' ).val() ) {
   440 	if ( $( '#auto_draft' ).val() ) {
   336 		$( '#title' ).blur( function() {
   441 		$( '#title' ).blur( function() {
   337 			var cancel;
   442 			var cancel;
   338 
   443 
   339 			if ( ! this.value || $('#edit-slug-box > *').length ) {
   444 			if ( ! this.value || $('#edit-slug-box > *').length ) {
   340 				return;
   445 				return;
   341 			}
   446 			}
   342 
   447 
   343 			// 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.
   344 			$('form#post').one( 'submit', function() {
   449 			$('form#post').one( 'submit', function() {
   345 				cancel = true;
   450 				cancel = true;
   346 			});
   451 			});
   347 
   452 
   348 			window.setTimeout( function() {
   453 			window.setTimeout( function() {
   361 		}
   466 		}
   362 	}).on( 'before-autosave.edit-post', function() {
   467 	}).on( 'before-autosave.edit-post', function() {
   363 		$( '.autosave-message' ).text( postL10n.savingText );
   468 		$( '.autosave-message' ).text( postL10n.savingText );
   364 	}).on( 'after-autosave.edit-post', function( event, data ) {
   469 	}).on( 'after-autosave.edit-post', function( event, data ) {
   365 		$( '.autosave-message' ).text( data.message );
   470 		$( '.autosave-message' ).text( data.message );
       
   471 
       
   472 		if ( $( document.body ).hasClass( 'post-new-php' ) ) {
       
   473 			$( '.submitbox .submitdelete' ).show();
       
   474 		}
   366 	});
   475 	});
   367 
   476 
       
   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 	 */
   368 	$(window).on( 'beforeunload.edit-post', function() {
   481 	$(window).on( 'beforeunload.edit-post', function() {
   369 		var editor = typeof tinymce !== 'undefined' && tinymce.get('content');
   482 		var editor = typeof tinymce !== 'undefined' && tinymce.get('content');
   370 
   483 
   371 		if ( ( editor && ! editor.isHidden() && editor.isDirty() ) ||
   484 		if ( ( editor && ! editor.isHidden() && editor.isDirty() ) ||
   372 			( wp.autosave && wp.autosave.server.postChanged() ) ) {
   485 			( wp.autosave && wp.autosave.server.postChanged() ) ) {
   376 	}).on( 'unload.edit-post', function( event ) {
   489 	}).on( 'unload.edit-post', function( event ) {
   377 		if ( ! releaseLock ) {
   490 		if ( ! releaseLock ) {
   378 			return;
   491 			return;
   379 		}
   492 		}
   380 
   493 
   381 		// Unload is triggered (by hand) on removing the Thickbox iframe.
   494 		/*
   382 		// Make sure we process only the main document unload.
   495 		 * Unload is triggered (by hand) on removing the Thickbox iframe.
       
   496 		 * Make sure we process only the main document unload.
       
   497 		 */
   383 		if ( event.target && event.target.nodeName != '#document' ) {
   498 		if ( event.target && event.target.nodeName != '#document' ) {
   384 			return;
   499 			return;
   385 		}
   500 		}
   386 
   501 
   387 		$.ajax({
   502 		var postID = $('#post_ID').val();
   388 			type: 'POST',
   503 		var postLock = $('#active_post_lock').val();
   389 			url: ajaxurl,
   504 
       
   505 		if ( ! postID || ! postLock ) {
       
   506 			return;
       
   507 		}
       
   508 
       
   509 		var data = {
       
   510 			action: 'wp-remove-post-lock',
       
   511 			_wpnonce: $('#_wpnonce').val(),
       
   512 			post_ID: postID,
       
   513 			active_post_lock: postLock
       
   514 		};
       
   515 
       
   516 		if ( window.FormData && window.navigator.sendBeacon ) {
       
   517 			var formData = new window.FormData();
       
   518 
       
   519 			$.each( data, function( key, value ) {
       
   520 				formData.append( key, value );
       
   521 			});
       
   522 
       
   523 			if ( window.navigator.sendBeacon( ajaxurl, formData ) ) {
       
   524 				return;
       
   525 			}
       
   526 		}
       
   527 
       
   528 		// Fall back to a synchronous POST request.
       
   529 		// See https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon
       
   530 		$.post({
   390 			async: false,
   531 			async: false,
   391 			data: {
   532 			data: data,
   392 				action: 'wp-remove-post-lock',
   533 			url: ajaxurl
   393 				_wpnonce: $('#_wpnonce').val(),
       
   394 				post_ID: $('#post_ID').val(),
       
   395 				active_post_lock: $('#active_post_lock').val()
       
   396 			}
       
   397 		});
   534 		});
   398 	});
   535 	});
   399 
   536 
   400 	// multi-taxonomies
   537 	// Multiple Taxonomies.
   401 	if ( $('#tagsdiv-post_tag').length ) {
   538 	if ( $('#tagsdiv-post_tag').length ) {
   402 		window.tagBox && window.tagBox.init();
   539 		window.tagBox && window.tagBox.init();
   403 	} else {
   540 	} else {
   404 		$('#side-sortables, #normal-sortables, #advanced-sortables').children('div.postbox').each(function(){
   541 		$('.meta-box-sortables').children('div.postbox').each(function(){
   405 			if ( this.id.indexOf('tagsdiv-') === 0 ) {
   542 			if ( this.id.indexOf('tagsdiv-') === 0 ) {
   406 				window.tagBox && window.tagBox.init();
   543 				window.tagBox && window.tagBox.init();
   407 				return false;
   544 				return false;
   408 			}
   545 			}
   409 		});
   546 		});
   410 	}
   547 	}
   411 
   548 
   412 	// categories
   549 	// Handle categories.
   413 	$('.categorydiv').each( function(){
   550 	$('.categorydiv').each( function(){
   414 		var this_id = $(this).attr('id'), catAddBefore, catAddAfter, taxonomyParts, taxonomy, settingName;
   551 		var this_id = $(this).attr('id'), catAddBefore, catAddAfter, taxonomyParts, taxonomy, settingName;
   415 
   552 
   416 		taxonomyParts = this_id.split('-');
   553 		taxonomyParts = this_id.split('-');
   417 		taxonomyParts.shift();
   554 		taxonomyParts.shift();
   418 		taxonomy = taxonomyParts.join('-');
   555 		taxonomy = taxonomyParts.join('-');
   419 		settingName = taxonomy + '_tab';
   556 		settingName = taxonomy + '_tab';
   420 		if ( taxonomy == 'category' )
   557 
       
   558 		if ( taxonomy == 'category' ) {
   421 			settingName = 'cats';
   559 			settingName = 'cats';
       
   560 		}
   422 
   561 
   423 		// TODO: move to jQuery 1.3+, support for multiple hierarchical taxonomies, see wp-lists.js
   562 		// TODO: move to jQuery 1.3+, support for multiple hierarchical taxonomies, see wp-lists.js
   424 		$('a', '#' + taxonomy + '-tabs').click( function(){
   563 		$('a', '#' + taxonomy + '-tabs').click( function( e ) {
       
   564 			e.preventDefault();
   425 			var t = $(this).attr('href');
   565 			var t = $(this).attr('href');
   426 			$(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
   566 			$(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
   427 			$('#' + taxonomy + '-tabs').siblings('.tabs-panel').hide();
   567 			$('#' + taxonomy + '-tabs').siblings('.tabs-panel').hide();
   428 			$(t).show();
   568 			$(t).show();
   429 			if ( '#' + taxonomy + '-all' == t )
   569 			if ( '#' + taxonomy + '-all' == t ) {
   430 				deleteUserSetting( settingName );
   570 				deleteUserSetting( settingName );
   431 			else
   571 			} else {
   432 				setUserSetting( settingName, 'pop' );
   572 				setUserSetting( settingName, 'pop' );
   433 			return false;
   573 			}
   434 		});
   574 		});
   435 
   575 
   436 		if ( getUserSetting( settingName ) )
   576 		if ( getUserSetting( settingName ) )
   437 			$('a[href="#' + taxonomy + '-pop"]', '#' + taxonomy + '-tabs').click();
   577 			$('a[href="#' + taxonomy + '-pop"]', '#' + taxonomy + '-tabs').click();
   438 
   578 
   439 		// Ajax Cat
   579 		// Add category button controls.
   440 		$( '#new' + taxonomy ).one( 'focus', function() { $( this ).val( '' ).removeClass( 'form-input-tip' ); } );
   580 		$('#new' + taxonomy).one( 'focus', function() {
   441 
   581 			$( this ).val( '' ).removeClass( 'form-input-tip' );
       
   582 		});
       
   583 
       
   584 		// On [enter] submit the taxonomy.
   442 		$('#new' + taxonomy).keypress( function(event){
   585 		$('#new' + taxonomy).keypress( function(event){
   443 			if( 13 === event.keyCode ) {
   586 			if( 13 === event.keyCode ) {
   444 				event.preventDefault();
   587 				event.preventDefault();
   445 				$('#' + taxonomy + '-add-submit').click();
   588 				$('#' + taxonomy + '-add-submit').click();
   446 			}
   589 			}
   447 		});
   590 		});
   448 		$('#' + taxonomy + '-add-submit').click( function(){ $('#new' + taxonomy).focus(); });
   591 
   449 
   592 		// After submitting a new taxonomy, re-focus the input field.
       
   593 		$('#' + taxonomy + '-add-submit').click( function() {
       
   594 			$('#new' + taxonomy).focus();
       
   595 		});
       
   596 
       
   597 		/**
       
   598 		 * Before adding a new taxonomy, disable submit button.
       
   599 		 *
       
   600 		 * @param {Object} s Taxonomy object which will be added.
       
   601 		 *
       
   602 		 * @returns {Object}
       
   603 		 */
   450 		catAddBefore = function( s ) {
   604 		catAddBefore = function( s ) {
   451 			if ( !$('#new'+taxonomy).val() )
   605 			if ( !$('#new'+taxonomy).val() ) {
   452 				return false;
   606 				return false;
       
   607 			}
       
   608 
   453 			s.data += '&' + $( ':checked', '#'+taxonomy+'checklist' ).serialize();
   609 			s.data += '&' + $( ':checked', '#'+taxonomy+'checklist' ).serialize();
   454 			$( '#' + taxonomy + '-add-submit' ).prop( 'disabled', true );
   610 			$( '#' + taxonomy + '-add-submit' ).prop( 'disabled', true );
   455 			return s;
   611 			return s;
   456 		};
   612 		};
   457 
   613 
       
   614 		/**
       
   615 		 * Re-enable submit button after a taxonomy has been added.
       
   616 		 *
       
   617 		 * Re-enable submit button.
       
   618 		 * If the taxonomy has a parent place the taxonomy underneath the parent.
       
   619 		 *
       
   620 		 * @param {Object} r Response.
       
   621 		 * @param {Object} s Taxonomy data.
       
   622 		 *
       
   623 		 * @returns void
       
   624 		 */
   458 		catAddAfter = function( r, s ) {
   625 		catAddAfter = function( r, s ) {
   459 			var sup, drop = $('#new'+taxonomy+'_parent');
   626 			var sup, drop = $('#new'+taxonomy+'_parent');
   460 
   627 
   461 			$( '#' + taxonomy + '-add-submit' ).prop( 'disabled', false );
   628 			$( '#' + taxonomy + '-add-submit' ).prop( 'disabled', false );
   462 			if ( 'undefined' != s.parsed.responses[0] && (sup = s.parsed.responses[0].supplemental.newcat_parent) ) {
   629 			if ( 'undefined' != s.parsed.responses[0] && (sup = s.parsed.responses[0].supplemental.newcat_parent) ) {
   470 			response: taxonomy + '-ajax-response',
   637 			response: taxonomy + '-ajax-response',
   471 			addBefore: catAddBefore,
   638 			addBefore: catAddBefore,
   472 			addAfter: catAddAfter
   639 			addAfter: catAddAfter
   473 		});
   640 		});
   474 
   641 
   475 		$('#' + taxonomy + '-add-toggle').click( function() {
   642 		// Add new taxonomy button toggles input form visibility.
       
   643 		$('#' + taxonomy + '-add-toggle').click( function( e ) {
       
   644 			e.preventDefault();
   476 			$('#' + taxonomy + '-adder').toggleClass( 'wp-hidden-children' );
   645 			$('#' + taxonomy + '-adder').toggleClass( 'wp-hidden-children' );
   477 			$('a[href="#' + taxonomy + '-all"]', '#' + taxonomy + '-tabs').click();
   646 			$('a[href="#' + taxonomy + '-all"]', '#' + taxonomy + '-tabs').click();
   478 			$('#new'+taxonomy).focus();
   647 			$('#new'+taxonomy).focus();
   479 			return false;
   648 		});
   480 		});
   649 
   481 
   650 		// Sync checked items between "All {taxonomy}" and "Most used" lists.
   482 		$('#' + taxonomy + 'checklist, #' + taxonomy + 'checklist-pop').on( 'click', 'li.popular-category > label input[type="checkbox"]', function() {
   651 		$('#' + taxonomy + 'checklist, #' + taxonomy + 'checklist-pop').on( 'click', 'li.popular-category > label input[type="checkbox"]', function() {
   483 			var t = $(this), c = t.is(':checked'), id = t.val();
   652 			var t = $(this), c = t.is(':checked'), id = t.val();
   484 			if ( id && t.parents('#taxonomy-'+taxonomy).length )
   653 			if ( id && t.parents('#taxonomy-'+taxonomy).length )
   485 				$('#in-' + taxonomy + '-' + id + ', #in-popular-' + taxonomy + '-' + id).prop( 'checked', c );
   654 				$('#in-' + taxonomy + '-' + id + ', #in-popular-' + taxonomy + '-' + id).prop( 'checked', c );
   486 		});
   655 		});
   487 
   656 
   488 	}); // end cats
   657 	}); // end cats
   489 
   658 
   490 	// Custom Fields
   659 	// Custom Fields postbox.
   491 	if ( $('#postcustom').length ) {
   660 	if ( $('#postcustom').length ) {
   492 		$( '#the-list' ).wpList( { addAfter: function() {
   661 		$( '#the-list' ).wpList( {
   493 			$('table#list-table').show();
   662 			/**
   494 		}, addBefore: function( s ) {
   663 			 * Add current post_ID to request to fetch custom fields
   495 			s.data += '&post_id=' + $('#post_ID').val();
   664 			 *
   496 			return s;
   665 			 * @param {Object} s Request object.
   497 		}
   666 			 *
       
   667 			 * @returns {Object} Data modified with post_ID attached.
       
   668 			 */
       
   669 			addBefore: function( s ) {
       
   670 				s.data += '&post_id=' + $('#post_ID').val();
       
   671 				return s;
       
   672 			},
       
   673 			/**
       
   674 			 * Show the listing of custom fields after fetching.
       
   675 			 */
       
   676 			addAfter: function() {
       
   677 				$('table#list-table').show();
       
   678 			}
   498 		});
   679 		});
   499 	}
   680 	}
   500 
   681 
   501 	// submitdiv
   682 	/*
       
   683 	 * Publish Post box (#submitdiv)
       
   684 	 */
   502 	if ( $('#submitdiv').length ) {
   685 	if ( $('#submitdiv').length ) {
   503 		stamp = $('#timestamp').html();
   686 		stamp = $('#timestamp').html();
   504 		visibility = $('#post-visibility-display').html();
   687 		visibility = $('#post-visibility-display').html();
   505 
   688 
       
   689 		/**
       
   690 		 * When the visibility of a post changes sub-options should be shown or hidden.
       
   691 		 *
       
   692 		 * @returns void
       
   693 		 */
   506 		updateVisibility = function() {
   694 		updateVisibility = function() {
       
   695 			// Show sticky for public posts.
   507 			if ( $postVisibilitySelect.find('input:radio:checked').val() != 'public' ) {
   696 			if ( $postVisibilitySelect.find('input:radio:checked').val() != 'public' ) {
   508 				$('#sticky').prop('checked', false);
   697 				$('#sticky').prop('checked', false);
   509 				$('#sticky-span').hide();
   698 				$('#sticky-span').hide();
   510 			} else {
   699 			} else {
   511 				$('#sticky-span').show();
   700 				$('#sticky-span').show();
   512 			}
   701 			}
       
   702 
       
   703 			// Show password input field for password protected post.
   513 			if ( $postVisibilitySelect.find('input:radio:checked').val() != 'password' ) {
   704 			if ( $postVisibilitySelect.find('input:radio:checked').val() != 'password' ) {
   514 				$('#password-span').hide();
   705 				$('#password-span').hide();
   515 			} else {
   706 			} else {
   516 				$('#password-span').show();
   707 				$('#password-span').show();
   517 			}
   708 			}
   518 		};
   709 		};
   519 
   710 
       
   711 		/**
       
   712 		 * Make sure all labels represent the current settings.
       
   713 		 *
       
   714 		 * @returns {boolean} False when an invalid timestamp has been selected, otherwise True.
       
   715 		 */
   520 		updateText = function() {
   716 		updateText = function() {
   521 
   717 
   522 			if ( ! $timestampdiv.length )
   718 			if ( ! $timestampdiv.length )
   523 				return true;
   719 				return true;
   524 
   720 
   528 
   724 
   529 			attemptedDate = new Date( aa, mm - 1, jj, hh, mn );
   725 			attemptedDate = new Date( aa, mm - 1, jj, hh, mn );
   530 			originalDate = new Date( $('#hidden_aa').val(), $('#hidden_mm').val() -1, $('#hidden_jj').val(), $('#hidden_hh').val(), $('#hidden_mn').val() );
   726 			originalDate = new Date( $('#hidden_aa').val(), $('#hidden_mm').val() -1, $('#hidden_jj').val(), $('#hidden_hh').val(), $('#hidden_mn').val() );
   531 			currentDate = new Date( $('#cur_aa').val(), $('#cur_mm').val() -1, $('#cur_jj').val(), $('#cur_hh').val(), $('#cur_mn').val() );
   727 			currentDate = new Date( $('#cur_aa').val(), $('#cur_mm').val() -1, $('#cur_jj').val(), $('#cur_hh').val(), $('#cur_mn').val() );
   532 
   728 
       
   729 			// Catch unexpected date problems.
   533 			if ( attemptedDate.getFullYear() != aa || (1 + attemptedDate.getMonth()) != mm || attemptedDate.getDate() != jj || attemptedDate.getMinutes() != mn ) {
   730 			if ( attemptedDate.getFullYear() != aa || (1 + attemptedDate.getMonth()) != mm || attemptedDate.getDate() != jj || attemptedDate.getMinutes() != mn ) {
   534 				$timestampdiv.find('.timestamp-wrap').addClass('form-invalid');
   731 				$timestampdiv.find('.timestamp-wrap').addClass('form-invalid');
   535 				return false;
   732 				return false;
   536 			} else {
   733 			} else {
   537 				$timestampdiv.find('.timestamp-wrap').removeClass('form-invalid');
   734 				$timestampdiv.find('.timestamp-wrap').removeClass('form-invalid');
   538 			}
   735 			}
   539 
   736 
       
   737 			// Determine what the publish should be depending on the date and post status.
   540 			if ( attemptedDate > currentDate && $('#original_post_status').val() != 'future' ) {
   738 			if ( attemptedDate > currentDate && $('#original_post_status').val() != 'future' ) {
   541 				publishOn = postL10n.publishOnFuture;
   739 				publishOn = postL10n.publishOnFuture;
   542 				$('#publish').val( postL10n.schedule );
   740 				$('#publish').val( postL10n.schedule );
   543 			} else if ( attemptedDate <= currentDate && $('#original_post_status').val() != 'publish' ) {
   741 			} else if ( attemptedDate <= currentDate && $('#original_post_status').val() != 'publish' ) {
   544 				publishOn = postL10n.publishOn;
   742 				publishOn = postL10n.publishOn;
   545 				$('#publish').val( postL10n.publish );
   743 				$('#publish').val( postL10n.publish );
   546 			} else {
   744 			} else {
   547 				publishOn = postL10n.publishOnPast;
   745 				publishOn = postL10n.publishOnPast;
   548 				$('#publish').val( postL10n.update );
   746 				$('#publish').val( postL10n.update );
   549 			}
   747 			}
   550 			if ( originalDate.toUTCString() == attemptedDate.toUTCString() ) { //hack
   748 
       
   749 			// If the date is the same, set it to trigger update events.
       
   750 			if ( originalDate.toUTCString() == attemptedDate.toUTCString() ) {
       
   751 				// Re-set to the current value.
   551 				$('#timestamp').html(stamp);
   752 				$('#timestamp').html(stamp);
   552 			} else {
   753 			} else {
   553 				$('#timestamp').html(
   754 				$('#timestamp').html(
   554 					publishOn + ' <b>' +
   755 					'\n' + publishOn + ' <b>' +
   555 					postL10n.dateFormat.replace( '%1$s', $('option[value="' + $('#mm').val() + '"]', '#mm').text() )
   756 					postL10n.dateFormat
   556 						.replace( '%2$s', jj )
   757 						.replace( '%1$s', $( 'option[value="' + mm + '"]', '#mm' ).attr( 'data-text' ) )
       
   758 						.replace( '%2$s', parseInt( jj, 10 ) )
   557 						.replace( '%3$s', aa )
   759 						.replace( '%3$s', aa )
   558 						.replace( '%4$s', hh )
   760 						.replace( '%4$s', ( '00' + hh ).slice( -2 ) )
   559 						.replace( '%5$s', mn ) +
   761 						.replace( '%5$s', ( '00' + mn ).slice( -2 ) ) +
   560 						'</b> '
   762 						'</b> '
   561 				);
   763 				);
   562 			}
   764 			}
   563 
   765 
       
   766 			// Add "privately published" to post status when applies.
   564 			if ( $postVisibilitySelect.find('input:radio:checked').val() == 'private' ) {
   767 			if ( $postVisibilitySelect.find('input:radio:checked').val() == 'private' ) {
   565 				$('#publish').val( postL10n.update );
   768 				$('#publish').val( postL10n.update );
   566 				if ( 0 === optPublish.length ) {
   769 				if ( 0 === optPublish.length ) {
   567 					postStatus.append('<option value="publish">' + postL10n.privatelyPublished + '</option>');
   770 					postStatus.append('<option value="publish">' + postL10n.privatelyPublished + '</option>');
   568 				} else {
   771 				} else {
   580 					optPublish.html( postL10n.published );
   783 					optPublish.html( postL10n.published );
   581 				}
   784 				}
   582 				if ( postStatus.is(':hidden') )
   785 				if ( postStatus.is(':hidden') )
   583 					$('#misc-publishing-actions .edit-post-status').show();
   786 					$('#misc-publishing-actions .edit-post-status').show();
   584 			}
   787 			}
       
   788 
       
   789 			// Update "Status:" to currently selected status.
   585 			$('#post-status-display').html($('option:selected', postStatus).text());
   790 			$('#post-status-display').html($('option:selected', postStatus).text());
       
   791 
       
   792 			// Show or hide the "Save Draft" button.
   586 			if ( $('option:selected', postStatus).val() == 'private' || $('option:selected', postStatus).val() == 'publish' ) {
   793 			if ( $('option:selected', postStatus).val() == 'private' || $('option:selected', postStatus).val() == 'publish' ) {
   587 				$('#save-post').hide();
   794 				$('#save-post').hide();
   588 			} else {
   795 			} else {
   589 				$('#save-post').show();
   796 				$('#save-post').show();
   590 				if ( $('option:selected', postStatus).val() == 'pending' ) {
   797 				if ( $('option:selected', postStatus).val() == 'pending' ) {
   594 				}
   801 				}
   595 			}
   802 			}
   596 			return true;
   803 			return true;
   597 		};
   804 		};
   598 
   805 
   599 		$( '#visibility .edit-visibility').click( function () {
   806 		// Show the visibility options and hide the toggle button when opened.
       
   807 		$( '#visibility .edit-visibility').click( function( e ) {
       
   808 			e.preventDefault();
   600 			if ( $postVisibilitySelect.is(':hidden') ) {
   809 			if ( $postVisibilitySelect.is(':hidden') ) {
   601 				updateVisibility();
   810 				updateVisibility();
   602 				$postVisibilitySelect.slideDown('fast').find('input[type="radio"]').first().focus();
   811 				$postVisibilitySelect.slideDown( 'fast', function() {
       
   812 					$postVisibilitySelect.find( 'input[type="radio"]' ).first().focus();
       
   813 				} );
   603 				$(this).hide();
   814 				$(this).hide();
   604 			}
   815 			}
   605 			return false;
   816 		});
   606 		});
   817 
   607 
   818 		// Cancel visibility selection area and hide it from view.
   608 		$postVisibilitySelect.find('.cancel-post-visibility').click( function( event ) {
   819 		$postVisibilitySelect.find('.cancel-post-visibility').click( function( event ) {
   609 			$postVisibilitySelect.slideUp('fast');
   820 			$postVisibilitySelect.slideUp('fast');
   610 			$('#visibility-radio-' + $('#hidden-post-visibility').val()).prop('checked', true);
   821 			$('#visibility-radio-' + $('#hidden-post-visibility').val()).prop('checked', true);
   611 			$('#post_password').val($('#hidden-post-password').val());
   822 			$('#post_password').val($('#hidden-post-password').val());
   612 			$('#sticky').prop('checked', $('#hidden-post-sticky').prop('checked'));
   823 			$('#sticky').prop('checked', $('#hidden-post-sticky').prop('checked'));
   614 			$('#visibility .edit-visibility').show().focus();
   825 			$('#visibility .edit-visibility').show().focus();
   615 			updateText();
   826 			updateText();
   616 			event.preventDefault();
   827 			event.preventDefault();
   617 		});
   828 		});
   618 
   829 
       
   830 		// Set the selected visibility as current.
   619 		$postVisibilitySelect.find('.save-post-visibility').click( function( event ) { // crazyhorse - multiple ok cancels
   831 		$postVisibilitySelect.find('.save-post-visibility').click( function( event ) { // crazyhorse - multiple ok cancels
   620 			$postVisibilitySelect.slideUp('fast');
   832 			$postVisibilitySelect.slideUp('fast');
   621 			$('#visibility .edit-visibility').show();
   833 			$('#visibility .edit-visibility').show().focus();
   622 			updateText();
   834 			updateText();
   623 
   835 
   624 			if ( $postVisibilitySelect.find('input:radio:checked').val() != 'public' ) {
   836 			if ( $postVisibilitySelect.find('input:radio:checked').val() != 'public' ) {
   625 				$('#sticky').prop('checked', false);
   837 				$('#sticky').prop('checked', false);
   626 			} // WEAPON LOCKED
   838 			}
   627 
   839 
   628 			if ( $('#sticky').prop('checked') ) {
   840 			if ( $('#sticky').prop('checked') ) {
   629 				sticky = 'Sticky';
   841 				sticky = 'Sticky';
   630 			} else {
   842 			} else {
   631 				sticky = '';
   843 				sticky = '';
   633 
   845 
   634 			$('#post-visibility-display').html(	postL10n[ $postVisibilitySelect.find('input:radio:checked').val() + sticky ]	);
   846 			$('#post-visibility-display').html(	postL10n[ $postVisibilitySelect.find('input:radio:checked').val() + sticky ]	);
   635 			event.preventDefault();
   847 			event.preventDefault();
   636 		});
   848 		});
   637 
   849 
       
   850 		// When the selection changes, update labels.
   638 		$postVisibilitySelect.find('input:radio').change( function() {
   851 		$postVisibilitySelect.find('input:radio').change( function() {
   639 			updateVisibility();
   852 			updateVisibility();
   640 		});
   853 		});
   641 
   854 
       
   855 		// Edit publish time click.
   642 		$timestampdiv.siblings('a.edit-timestamp').click( function( event ) {
   856 		$timestampdiv.siblings('a.edit-timestamp').click( function( event ) {
   643 			if ( $timestampdiv.is( ':hidden' ) ) {
   857 			if ( $timestampdiv.is( ':hidden' ) ) {
   644 				$timestampdiv.slideDown('fast');
   858 				$timestampdiv.slideDown( 'fast', function() {
   645 				$('#mm').focus();
   859 					$( 'input, select', $timestampdiv.find( '.timestamp-wrap' ) ).first().focus();
       
   860 				} );
   646 				$(this).hide();
   861 				$(this).hide();
   647 			}
   862 			}
   648 			event.preventDefault();
   863 			event.preventDefault();
   649 		});
   864 		});
   650 
   865 
       
   866 		// Cancel editing the publish time and hide the settings.
   651 		$timestampdiv.find('.cancel-timestamp').click( function( event ) {
   867 		$timestampdiv.find('.cancel-timestamp').click( function( event ) {
   652 			$timestampdiv.slideUp('fast').siblings('a.edit-timestamp').show().focus();
   868 			$timestampdiv.slideUp('fast').siblings('a.edit-timestamp').show().focus();
   653 			$('#mm').val($('#hidden_mm').val());
   869 			$('#mm').val($('#hidden_mm').val());
   654 			$('#jj').val($('#hidden_jj').val());
   870 			$('#jj').val($('#hidden_jj').val());
   655 			$('#aa').val($('#hidden_aa').val());
   871 			$('#aa').val($('#hidden_aa').val());
   657 			$('#mn').val($('#hidden_mn').val());
   873 			$('#mn').val($('#hidden_mn').val());
   658 			updateText();
   874 			updateText();
   659 			event.preventDefault();
   875 			event.preventDefault();
   660 		});
   876 		});
   661 
   877 
       
   878 		// Save the changed timestamp.
   662 		$timestampdiv.find('.save-timestamp').click( function( event ) { // crazyhorse - multiple ok cancels
   879 		$timestampdiv.find('.save-timestamp').click( function( event ) { // crazyhorse - multiple ok cancels
   663 			if ( updateText() ) {
   880 			if ( updateText() ) {
   664 				$timestampdiv.slideUp('fast');
   881 				$timestampdiv.slideUp('fast');
   665 				$timestampdiv.siblings('a.edit-timestamp').show();
   882 				$timestampdiv.siblings('a.edit-timestamp').show().focus();
   666 			}
   883 			}
   667 			event.preventDefault();
   884 			event.preventDefault();
   668 		});
   885 		});
   669 
   886 
       
   887 		// Cancel submit when an invalid timestamp has been selected.
   670 		$('#post').on( 'submit', function( event ) {
   888 		$('#post').on( 'submit', function( event ) {
   671 			if ( ! updateText() ) {
   889 			if ( ! updateText() ) {
   672 				event.preventDefault();
   890 				event.preventDefault();
   673 				$timestampdiv.show();
   891 				$timestampdiv.show();
   674 
   892 
   678 
   896 
   679 				$( '#publishing-action .spinner' ).removeClass( 'is-active' );
   897 				$( '#publishing-action .spinner' ).removeClass( 'is-active' );
   680 			}
   898 			}
   681 		});
   899 		});
   682 
   900 
       
   901 		// Post Status edit click.
   683 		$postStatusSelect.siblings('a.edit-post-status').click( function( event ) {
   902 		$postStatusSelect.siblings('a.edit-post-status').click( function( event ) {
   684 			if ( $postStatusSelect.is( ':hidden' ) ) {
   903 			if ( $postStatusSelect.is( ':hidden' ) ) {
   685 				$postStatusSelect.slideDown('fast').find('select').focus();
   904 				$postStatusSelect.slideDown( 'fast', function() {
       
   905 					$postStatusSelect.find('select').focus();
       
   906 				} );
   686 				$(this).hide();
   907 				$(this).hide();
   687 			}
   908 			}
   688 			event.preventDefault();
   909 			event.preventDefault();
   689 		});
   910 		});
   690 
   911 
       
   912 		// Save the Post Status changes and hide the options.
   691 		$postStatusSelect.find('.save-post-status').click( function( event ) {
   913 		$postStatusSelect.find('.save-post-status').click( function( event ) {
   692 			$postStatusSelect.slideUp('fast').siblings('a.edit-post-status').show();
   914 			$postStatusSelect.slideUp( 'fast' ).siblings( 'a.edit-post-status' ).show().focus();
   693 			updateText();
   915 			updateText();
   694 			event.preventDefault();
   916 			event.preventDefault();
   695 		});
   917 		});
   696 
   918 
       
   919 		// Cancel Post Status editing and hide the options.
   697 		$postStatusSelect.find('.cancel-post-status').click( function( event ) {
   920 		$postStatusSelect.find('.cancel-post-status').click( function( event ) {
   698 			$('#post-status-select').slideUp('fast').siblings( 'a.edit-post-status' ).show().focus();
   921 			$postStatusSelect.slideUp( 'fast' ).siblings( 'a.edit-post-status' ).show().focus();
   699 			$('#post_status').val( $('#hidden_post_status').val() );
   922 			$('#post_status').val( $('#hidden_post_status').val() );
   700 			updateText();
   923 			updateText();
   701 			event.preventDefault();
   924 			event.preventDefault();
   702 		});
   925 		});
   703 	} // end submitdiv
   926 	}
   704 
   927 
   705 	// permalink
   928 	/**
       
   929 	 * Handle the editing of the post_name. Create the required HTML elements and update the changes via AJAX.
       
   930 	 *
       
   931 	 * @summary Permalink aka slug aka post_name editing
       
   932 	 *
       
   933 	 * @global
       
   934 	 *
       
   935 	 * @returns void
       
   936 	 */
   706 	function editPermalink() {
   937 	function editPermalink() {
   707 		var i, slug_value,
   938 		var i, slug_value,
       
   939 			$el, revert_e,
   708 			c = 0,
   940 			c = 0,
   709 			e = $('#editable-post-name'),
       
   710 			revert_e = e.html(),
       
   711 			real_slug = $('#post_name'),
   941 			real_slug = $('#post_name'),
   712 			revert_slug = real_slug.val(),
   942 			revert_slug = real_slug.val(),
   713 			b = $('#edit-slug-buttons'),
   943 			permalink = $( '#sample-permalink' ),
   714 			revert_b = b.html(),
   944 			permalinkOrig = permalink.html(),
       
   945 			permalinkInner = $( '#sample-permalink a' ).html(),
       
   946 			buttons = $('#edit-slug-buttons'),
       
   947 			buttonsOrig = buttons.html(),
   715 			full = $('#editable-post-name-full');
   948 			full = $('#editable-post-name-full');
   716 
   949 
   717 		// Deal with Twemoji in the post-name
   950 		// Deal with Twemoji in the post-name.
   718 		full.find( 'img' ).replaceWith( function() { return this.alt; } );
   951 		full.find( 'img' ).replaceWith( function() { return this.alt; } );
   719 		full = full.html();
   952 		full = full.html();
   720 
   953 
   721 		$('#view-post-btn').hide();
   954 		permalink.html( permalinkInner );
   722 		b.html('<a href="#" class="save button button-small">'+postL10n.ok+'</a> <a class="cancel" href="#">'+postL10n.cancel+'</a>');
   955 
   723 		b.children('.save').click(function() {
   956 		// Save current content to revert to when cancelling.
   724 			var new_slug = e.children('input').val();
   957 		$el = $( '#editable-post-name' );
       
   958 		revert_e = $el.html();
       
   959 
       
   960 		buttons.html( '<button type="button" class="save button button-small">' + postL10n.ok + '</button> <button type="button" class="cancel button-link">' + postL10n.cancel + '</button>' );
       
   961 
       
   962 		// Save permalink changes.
       
   963 		buttons.children( '.save' ).click( function() {
       
   964 			var new_slug = $el.children( 'input' ).val();
       
   965 
   725 			if ( new_slug == $('#editable-post-name-full').text() ) {
   966 			if ( new_slug == $('#editable-post-name-full').text() ) {
   726 				b.children('.cancel').click();
   967 				buttons.children('.cancel').click();
   727 				return false;
   968 				return;
   728 			}
   969 			}
   729 			$.post(ajaxurl, {
   970 
   730 				action: 'sample-permalink',
   971 			$.post(
   731 				post_id: postId,
   972 				ajaxurl,
   732 				new_slug: new_slug,
   973 				{
   733 				new_title: $('#title').val(),
   974 					action: 'sample-permalink',
   734 				samplepermalinknonce: $('#samplepermalinknonce').val()
   975 					post_id: postId,
   735 			}, function(data) {
   976 					new_slug: new_slug,
   736 				var box = $('#edit-slug-box');
   977 					new_title: $('#title').val(),
   737 				box.html(data);
   978 					samplepermalinknonce: $('#samplepermalinknonce').val()
   738 				if (box.hasClass('hidden')) {
   979 				},
   739 					box.fadeIn('fast', function () {
   980 				function(data) {
   740 						box.removeClass('hidden');
   981 					var box = $('#edit-slug-box');
   741 					});
   982 					box.html(data);
       
   983 					if (box.hasClass('hidden')) {
       
   984 						box.fadeIn('fast', function () {
       
   985 							box.removeClass('hidden');
       
   986 						});
       
   987 					}
       
   988 
       
   989 					buttons.html(buttonsOrig);
       
   990 					permalink.html(permalinkOrig);
       
   991 					real_slug.val(new_slug);
       
   992 					$( '.edit-slug' ).focus();
       
   993 					wp.a11y.speak( postL10n.permalinkSaved );
   742 				}
   994 				}
   743 
   995 			);
   744 				b.html(revert_b);
   996 		});
   745 				real_slug.val(new_slug);
   997 
   746 				$('#view-post-btn').show();
   998 		// Cancel editing of permalink.
   747 			});
   999 		buttons.children( '.cancel' ).click( function() {
   748 			return false;
       
   749 		});
       
   750 
       
   751 		b.children('.cancel').click(function() {
       
   752 			$('#view-post-btn').show();
  1000 			$('#view-post-btn').show();
   753 			e.html(revert_e);
  1001 			$el.html(revert_e);
   754 			b.html(revert_b);
  1002 			buttons.html(buttonsOrig);
       
  1003 			permalink.html(permalinkOrig);
   755 			real_slug.val(revert_slug);
  1004 			real_slug.val(revert_slug);
   756 			return false;
  1005 			$( '.edit-slug' ).focus();
   757 		});
  1006 		});
   758 
  1007 
       
  1008 		// If more than 1/4th of 'full' is '%', make it empty.
   759 		for ( i = 0; i < full.length; ++i ) {
  1009 		for ( i = 0; i < full.length; ++i ) {
   760 			if ( '%' == full.charAt(i) )
  1010 			if ( '%' == full.charAt(i) )
   761 				c++;
  1011 				c++;
   762 		}
  1012 		}
   763 
       
   764 		slug_value = ( c > full.length / 4 ) ? '' : full;
  1013 		slug_value = ( c > full.length / 4 ) ? '' : full;
   765 		e.html('<input type="text" id="new-post-slug" value="'+slug_value+'" />').children('input').keypress(function(e) {
  1014 
   766 			var key = e.keyCode || 0;
  1015 		$el.html( '<input type="text" id="new-post-slug" value="' + slug_value + '" autocomplete="off" />' ).children( 'input' ).keydown( function( e ) {
   767 			// on enter, just save the new slug, don't save the post
  1016 			var key = e.which;
   768 			if ( 13 == key ) {
  1017 			// On [enter], just save the new slug, don't save the post.
   769 				b.children('.save').click();
  1018 			if ( 13 === key ) {
   770 				return false;
  1019 				e.preventDefault();
   771 			}
  1020 				buttons.children( '.save' ).click();
   772 			if ( 27 == key ) {
  1021 			}
   773 				b.children('.cancel').click();
  1022 			// On [esc] cancel the editing.
   774 				return false;
  1023 			if ( 27 === key ) {
       
  1024 				buttons.children( '.cancel' ).click();
   775 			}
  1025 			}
   776 		} ).keyup( function() {
  1026 		} ).keyup( function() {
   777 			real_slug.val(this.value);
  1027 			real_slug.val( this.value );
   778 		}).focus();
  1028 		}).focus();
   779 	}
  1029 	}
   780 
  1030 
   781 	if ( $editSlugWrap.length ) {
  1031 	$( '#titlediv' ).on( 'click', '.edit-slug', function() {
   782 		$editSlugWrap.on( 'click', function( event ) {
  1032 		editPermalink();
   783 			var $target = $( event.target );
  1033 	});
   784 
  1034 
   785 			if ( $target.is('#editable-post-name') || $target.hasClass('edit-slug') ) {
  1035 	/**
   786 				editPermalink();
  1036 	 * Add screen reader text to the title prompt when needed.
   787 			}
  1037 	 *
   788 		});
  1038 	 * @summary Title screen reader text handler.
   789 	}
  1039 	 *
   790 
  1040 	 * @param {string} id Optional. HTML ID to add the screen reader helper text to.
   791 	// word count
  1041 	 *
   792 	if ( typeof(wpWordCount) != 'undefined' ) {
  1042 	 * @global
   793 		$document.triggerHandler('wpcountwords', [ co.val() ]);
  1043 	 *
   794 
  1044 	 * @returns void
   795 		co.keyup( function(e) {
  1045 	 */
   796 			var k = e.keyCode || e.charCode;
       
   797 
       
   798 			if ( k == last )
       
   799 				return true;
       
   800 
       
   801 			if ( 13 == k || 8 == last || 46 == last )
       
   802 				$document.triggerHandler('wpcountwords', [ co.val() ]);
       
   803 
       
   804 			last = k;
       
   805 			return true;
       
   806 		});
       
   807 	}
       
   808 
       
   809 	wptitlehint = function(id) {
  1046 	wptitlehint = function(id) {
   810 		id = id || 'title';
  1047 		id = id || 'title';
   811 
  1048 
   812 		var title = $('#' + id), titleprompt = $('#' + id + '-prompt-text');
  1049 		var title = $('#' + id), titleprompt = $('#' + id + '-prompt-text');
   813 
  1050 
   830 		});
  1067 		});
   831 	};
  1068 	};
   832 
  1069 
   833 	wptitlehint();
  1070 	wptitlehint();
   834 
  1071 
   835 	// Resize the visual and text editors
  1072 	// Resize the WYSIWYG and plain text editors.
   836 	( function() {
  1073 	( function() {
   837 		var editor, offset, mce,
  1074 		var editor, offset, mce,
   838 			$textarea = $('textarea#content'),
       
   839 			$handle = $('#post-status-info'),
  1075 			$handle = $('#post-status-info'),
   840 			$postdivrich = $('#postdivrich');
  1076 			$postdivrich = $('#postdivrich');
   841 
  1077 
   842 		// No point for touch devices
  1078 		// If there are no textareas or we are on a touch device, we can't do anything.
   843 		if ( ! $textarea.length || 'ontouchstart' in window ) {
  1079 		if ( ! $textarea.length || 'ontouchstart' in window ) {
   844 			// Hide the resize handle
  1080 			// Hide the resize handle.
   845 			$('#content-resize-handle').hide();
  1081 			$('#content-resize-handle').hide();
   846 			return;
  1082 			return;
   847 		}
  1083 		}
   848 
  1084 
       
  1085 		/**
       
  1086 		 * Handle drag event.
       
  1087 		 *
       
  1088 		 * @param {Object} event Event containing details about the drag.
       
  1089 		 */
   849 		function dragging( event ) {
  1090 		function dragging( event ) {
   850 			if ( $postdivrich.hasClass( 'wp-editor-expand' ) ) {
  1091 			if ( $postdivrich.hasClass( 'wp-editor-expand' ) ) {
   851 				return;
  1092 				return;
   852 			}
  1093 			}
   853 
  1094 
   858 			}
  1099 			}
   859 
  1100 
   860 			event.preventDefault();
  1101 			event.preventDefault();
   861 		}
  1102 		}
   862 
  1103 
       
  1104 		/**
       
  1105 		 * When the dragging stopped make sure we return focus and do a sanity check on the height.
       
  1106 		 */
   863 		function endDrag() {
  1107 		function endDrag() {
   864 			var height, toolbarHeight;
  1108 			var height, toolbarHeight;
   865 
  1109 
   866 			if ( $postdivrich.hasClass( 'wp-editor-expand' ) ) {
  1110 			if ( $postdivrich.hasClass( 'wp-editor-expand' ) ) {
   867 				return;
  1111 				return;
   881 				height = parseInt( $textarea.css('height'), 10 );
  1125 				height = parseInt( $textarea.css('height'), 10 );
   882 			}
  1126 			}
   883 
  1127 
   884 			$document.off( '.wp-editor-resize' );
  1128 			$document.off( '.wp-editor-resize' );
   885 
  1129 
   886 			// sanity check
  1130 			// Sanity check: normalize height to stay within acceptable ranges.
   887 			if ( height && height > 50 && height < 5000 ) {
  1131 			if ( height && height > 50 && height < 5000 ) {
   888 				setUserSetting( 'ed_size', height );
  1132 				setUserSetting( 'ed_size', height );
   889 			}
  1133 			}
   890 		}
  1134 		}
   891 
  1135 
   908 
  1152 
   909 			event.preventDefault();
  1153 			event.preventDefault();
   910 		}).on( 'mouseup.wp-editor-resize', endDrag );
  1154 		}).on( 'mouseup.wp-editor-resize', endDrag );
   911 	})();
  1155 	})();
   912 
  1156 
       
  1157 	// TinyMCE specific handling of Post Format changes to reflect in the editor.
   913 	if ( typeof tinymce !== 'undefined' ) {
  1158 	if ( typeof tinymce !== 'undefined' ) {
   914 		// When changing post formats, change the editor body class
  1159 		// When changing post formats, change the editor body class.
   915 		$( '#post-formats-select input.post-format' ).on( 'change.set-editor-class', function() {
  1160 		$( '#post-formats-select input.post-format' ).on( 'change.set-editor-class', function() {
   916 			var editor, body, format = this.id;
  1161 			var editor, body, format = this.id;
   917 
  1162 
   918 			if ( format && $( this ).prop( 'checked' ) && ( editor = tinymce.get( 'content' ) ) ) {
  1163 			if ( format && $( this ).prop( 'checked' ) && ( editor = tinymce.get( 'content' ) ) ) {
   919 				body = editor.getBody();
  1164 				body = editor.getBody();
   920 				body.className = body.className.replace( /\bpost-format-[^ ]+/, '' );
  1165 				body.className = body.className.replace( /\bpost-format-[^ ]+/, '' );
   921 				editor.dom.addClass( body, format == 'post-format-0' ? 'post-format-standard' : format );
  1166 				editor.dom.addClass( body, format == 'post-format-0' ? 'post-format-standard' : format );
   922 				$( document ).trigger( 'editor-classchange' );
  1167 				$( document ).trigger( 'editor-classchange' );
   923 			}
  1168 			}
   924 		});
  1169 		});
       
  1170 
       
  1171 		// When changing page template, change the editor body class
       
  1172 		$( '#page_template' ).on( 'change.set-editor-class', function() {
       
  1173 			var editor, body, pageTemplate = $( this ).val() || '';
       
  1174 
       
  1175 			pageTemplate = pageTemplate.substr( pageTemplate.lastIndexOf( '/' ) + 1, pageTemplate.length )
       
  1176 				.replace( /\.php$/, '' )
       
  1177 				.replace( /\./g, '-' );
       
  1178 
       
  1179 			if ( pageTemplate && ( editor = tinymce.get( 'content' ) ) ) {
       
  1180 				body = editor.getBody();
       
  1181 				body.className = body.className.replace( /\bpage-template-[^ ]+/, '' );
       
  1182 				editor.dom.addClass( body, 'page-template-' + pageTemplate );
       
  1183 				$( document ).trigger( 'editor-classchange' );
       
  1184 			}
       
  1185 		});
       
  1186 
       
  1187 	}
       
  1188 
       
  1189 	// Save on pressing [ctrl]/[command] + [s] in the Text editor.
       
  1190 	$textarea.on( 'keydown.wp-autosave', function( event ) {
       
  1191 		// Key [s] has code 83.
       
  1192 		if ( event.which === 83 ) {
       
  1193 			if ( event.shiftKey || event.altKey || ( isMac && ( ! event.metaKey || event.ctrlKey ) ) || ( ! isMac && ! event.ctrlKey ) ) {
       
  1194 				return;
       
  1195 			}
       
  1196 
       
  1197 			wp.autosave && wp.autosave.server.triggerSave();
       
  1198 			event.preventDefault();
       
  1199 		}
       
  1200 	});
       
  1201 
       
  1202 	// If the last status was auto-draft and the save is triggered, edit the current URL.
       
  1203 	if ( $( '#original_post_status' ).val() === 'auto-draft' && window.history.replaceState ) {
       
  1204 		var location;
       
  1205 
       
  1206 		$( '#publish' ).on( 'click', function() {
       
  1207 			location = window.location.href;
       
  1208 			location += ( location.indexOf( '?' ) !== -1 ) ? '&' : '?';
       
  1209 			location += 'wp-post-new-reload=true';
       
  1210 
       
  1211 			window.history.replaceState( null, null, location );
       
  1212 		});
   925 	}
  1213 	}
   926 });
  1214 });
       
  1215 
       
  1216 /**
       
  1217  * TinyMCE word count display
       
  1218  */
       
  1219 ( function( $, counter ) {
       
  1220 	$( function() {
       
  1221 		var $content = $( '#content' ),
       
  1222 			$count = $( '#wp-word-count' ).find( '.word-count' ),
       
  1223 			prevCount = 0,
       
  1224 			contentEditor;
       
  1225 
       
  1226 		/**
       
  1227 		 * Get the word count from TinyMCE and display it
       
  1228 		 */
       
  1229 		function update() {
       
  1230 			var text, count;
       
  1231 
       
  1232 			if ( ! contentEditor || contentEditor.isHidden() ) {
       
  1233 				text = $content.val();
       
  1234 			} else {
       
  1235 				text = contentEditor.getContent( { format: 'raw' } );
       
  1236 			}
       
  1237 
       
  1238 			count = counter.count( text );
       
  1239 
       
  1240 			if ( count !== prevCount ) {
       
  1241 				$count.text( count );
       
  1242 			}
       
  1243 
       
  1244 			prevCount = count;
       
  1245 		}
       
  1246 
       
  1247 		/**
       
  1248 		 * Bind the word count update triggers.
       
  1249 		 *
       
  1250 		 * When a node change in the main TinyMCE editor has been triggered.
       
  1251 		 * When a key has been released in the plain text content editor.
       
  1252 		 */
       
  1253 		$( document ).on( 'tinymce-editor-init', function( event, editor ) {
       
  1254 			if ( editor.id !== 'content' ) {
       
  1255 				return;
       
  1256 			}
       
  1257 
       
  1258 			contentEditor = editor;
       
  1259 
       
  1260 			editor.on( 'nodechange keyup', _.debounce( update, 1000 ) );
       
  1261 		} );
       
  1262 
       
  1263 		$content.on( 'input keyup', _.debounce( update, 1000 ) );
       
  1264 
       
  1265 		update();
       
  1266 	} );
       
  1267 
       
  1268 } )( jQuery, new wp.utils.WordCounter() );