wp/wp-admin/js/inline-edit-post.js
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     1 /* global inlineEditL10n, ajaxurl, typenow */
     1 /* global inlineEditL10n, ajaxurl, typenow */
     2 
     2 /**
       
     3  * This file contains the functions needed for the inline editing of posts.
       
     4  *
       
     5  * @since 2.7.0
       
     6  */
       
     7 
       
     8 window.wp = window.wp || {};
       
     9 
       
    10 /**
       
    11  * Manages the quick edit and bulk edit windows for editing posts or pages.
       
    12  *
       
    13  * @namespace
       
    14  *
       
    15  * @since 2.7.0
       
    16  * @access public
       
    17  *
       
    18  * @type {Object}
       
    19  *
       
    20  * @property {string} type The type of inline editor.
       
    21  * @property {string} what The prefix before the post id.
       
    22  *
       
    23  */
     3 var inlineEditPost;
    24 var inlineEditPost;
     4 (function($) {
    25 ( function( $, wp ) {
     5 inlineEditPost = {
    26 
     6 
    27 	inlineEditPost = {
       
    28 
       
    29 	/**
       
    30 	 * @summary Initializes the inline and bulk post editor.
       
    31 	 *
       
    32 	 * Binds event handlers to the escape key to close the inline editor
       
    33 	 * and to the save and close buttons. Changes DOM to be ready for inline
       
    34 	 * editing. Adds event handler to bulk edit.
       
    35 	 *
       
    36 	 * @memberof inlineEditPost
       
    37 	 * @since 2.7.0
       
    38 	 *
       
    39 	 * @returns {void}
       
    40 	 */
     7 	init : function(){
    41 	init : function(){
     8 		var t = this, qeRow = $('#inline-edit'), bulkRow = $('#bulk-edit');
    42 		var t = this, qeRow = $('#inline-edit'), bulkRow = $('#bulk-edit');
     9 
    43 
    10 		t.type = $('table.widefat').hasClass('pages') ? 'page' : 'post';
    44 		t.type = $('table.widefat').hasClass('pages') ? 'page' : 'post';
       
    45 		// Post id prefix.
    11 		t.what = '#post-';
    46 		t.what = '#post-';
    12 
    47 
    13 		// prepare the edit rows
    48 		/**
       
    49 		 * @summary Bind escape key to revert the changes and close the quick editor.
       
    50 		 *
       
    51 		 * @returns {boolean} The result of revert.
       
    52 		 */
    14 		qeRow.keyup(function(e){
    53 		qeRow.keyup(function(e){
       
    54 			// Revert changes if escape key is pressed.
    15 			if ( e.which === 27 ) {
    55 			if ( e.which === 27 ) {
    16 				return inlineEditPost.revert();
    56 				return inlineEditPost.revert();
    17 			}
    57 			}
    18 		});
    58 		});
       
    59 
       
    60 		/**
       
    61 		 * @summary Bind escape key to revert the changes and close the bulk editor.
       
    62 		 *
       
    63 		 * @returns {boolean} The result of revert.
       
    64 		 */
    19 		bulkRow.keyup(function(e){
    65 		bulkRow.keyup(function(e){
       
    66 			// Revert changes if escape key is pressed.
    20 			if ( e.which === 27 ) {
    67 			if ( e.which === 27 ) {
    21 				return inlineEditPost.revert();
    68 				return inlineEditPost.revert();
    22 			}
    69 			}
    23 		});
    70 		});
    24 
    71 
    25 		$('a.cancel', qeRow).click(function(){
    72 		/**
       
    73 		 * @summary Revert changes and close the quick editor if the cancel button is clicked.
       
    74 		 *
       
    75 		 * @returns {boolean} The result of revert.
       
    76 		 */
       
    77 		$( '.cancel', qeRow ).click( function() {
    26 			return inlineEditPost.revert();
    78 			return inlineEditPost.revert();
    27 		});
    79 		});
    28 		$('a.save', qeRow).click(function(){
    80 
       
    81 		/**
       
    82 		 * @summary Save changes in the quick editor if the save(named: update) button is clicked.
       
    83 		 *
       
    84 		 * @returns {boolean} The result of save.
       
    85 		 */
       
    86 		$( '.save', qeRow ).click( function() {
    29 			return inlineEditPost.save(this);
    87 			return inlineEditPost.save(this);
    30 		});
    88 		});
       
    89 
       
    90 		/**
       
    91 		 * @summary If enter is pressed, and the target is not the cancel button, save the post.
       
    92 		 *
       
    93 		 * @returns {boolean} The result of save.
       
    94 		 */
    31 		$('td', qeRow).keydown(function(e){
    95 		$('td', qeRow).keydown(function(e){
    32 			if ( e.which === 13 && ! $( e.target ).hasClass( 'cancel' ) ) {
    96 			if ( e.which === 13 && ! $( e.target ).hasClass( 'cancel' ) ) {
    33 				return inlineEditPost.save(this);
    97 				return inlineEditPost.save(this);
    34 			}
    98 			}
    35 		});
    99 		});
    36 
   100 
    37 		$('a.cancel', bulkRow).click(function(){
   101 		/**
       
   102 		 * @summary Revert changes and close the bulk editor if the cancel button is clicked.
       
   103 		 *
       
   104 		 * @returns {boolean} The result of revert.
       
   105 		 */
       
   106 		$( '.cancel', bulkRow ).click( function() {
    38 			return inlineEditPost.revert();
   107 			return inlineEditPost.revert();
    39 		});
   108 		});
    40 
   109 
       
   110 		/**
       
   111 		 * @summary Disables the password input field when the private post checkbox is checked.
       
   112 		 */
    41 		$('#inline-edit .inline-edit-private input[value="private"]').click( function(){
   113 		$('#inline-edit .inline-edit-private input[value="private"]').click( function(){
    42 			var pw = $('input.inline-edit-password-input');
   114 			var pw = $('input.inline-edit-password-input');
    43 			if ( $(this).prop('checked') ) {
   115 			if ( $(this).prop('checked') ) {
    44 				pw.val('').prop('disabled', true);
   116 				pw.val('').prop('disabled', true);
    45 			} else {
   117 			} else {
    46 				pw.prop('disabled', false);
   118 				pw.prop('disabled', false);
    47 			}
   119 			}
    48 		});
   120 		});
    49 
   121 
    50 		// add events
   122 		/**
    51 		$('#the-list').on('click', 'a.editinline', function(){
   123 		 * @summary Bind click event to the .editinline link which opens the quick editor.
       
   124 		 */
       
   125 		$('#the-list').on( 'click', 'a.editinline', function( e ) {
       
   126 			e.preventDefault();
    52 			inlineEditPost.edit(this);
   127 			inlineEditPost.edit(this);
    53 			return false;
       
    54 		});
   128 		});
    55 
   129 
    56 		$('#bulk-edit').find('fieldset:first').after(
   130 		$('#bulk-edit').find('fieldset:first').after(
    57 			$('#inline-edit fieldset.inline-edit-categories').clone()
   131 			$('#inline-edit fieldset.inline-edit-categories').clone()
    58 		).siblings( 'fieldset:last' ).prepend(
   132 		).siblings( 'fieldset:last' ).prepend(
    59 			$('#inline-edit label.inline-edit-tags').clone()
   133 			$('#inline-edit label.inline-edit-tags').clone()
    60 		);
   134 		);
    61 
   135 
    62 		$('select[name="_status"] option[value="future"]', bulkRow).remove();
   136 		$('select[name="_status"] option[value="future"]', bulkRow).remove();
    63 
   137 
       
   138 		/**
       
   139 		 * @summary Adds onclick events to the apply buttons.
       
   140 		 */
    64 		$('#doaction, #doaction2').click(function(e){
   141 		$('#doaction, #doaction2').click(function(e){
    65 			var n = $(this).attr('id').substr(2);
   142 			var n;
       
   143 
       
   144 			t.whichBulkButtonId = $( this ).attr( 'id' );
       
   145 			n = t.whichBulkButtonId.substr( 2 );
       
   146 
    66 			if ( 'edit' === $( 'select[name="' + n + '"]' ).val() ) {
   147 			if ( 'edit' === $( 'select[name="' + n + '"]' ).val() ) {
    67 				e.preventDefault();
   148 				e.preventDefault();
    68 				t.setBulk();
   149 				t.setBulk();
    69 			} else if ( $('form#posts-filter tr.inline-editor').length > 0 ) {
   150 			} else if ( $('form#posts-filter tr.inline-editor').length > 0 ) {
    70 				t.revert();
   151 				t.revert();
    71 			}
   152 			}
    72 		});
   153 		});
    73 	},
   154 	},
    74 
   155 
       
   156 	/**
       
   157 	 * @summary Toggles the quick edit window.
       
   158 	 *
       
   159 	 * Hides the window when it's active and shows the window when inactive.
       
   160 	 *
       
   161 	 * @memberof inlineEditPost
       
   162 	 * @since 2.7.0
       
   163 	 *
       
   164 	 * @param {Object} el Element within a post table row.
       
   165 	 */
    75 	toggle : function(el){
   166 	toggle : function(el){
    76 		var t = this;
   167 		var t = this;
    77 		$( t.what + t.getId( el ) ).css( 'display' ) === 'none' ? t.revert() : t.edit( el );
   168 		$( t.what + t.getId( el ) ).css( 'display' ) === 'none' ? t.revert() : t.edit( el );
    78 	},
   169 	},
    79 
   170 
       
   171 	/**
       
   172 	 * @summary Creates the bulk editor row to edit multiple posts at once.
       
   173 	 *
       
   174 	 * @memberof inlineEditPost
       
   175 	 * @since 2.7.0
       
   176 	 */
    80 	setBulk : function(){
   177 	setBulk : function(){
    81 		var te = '', type = this.type, tax, c = true;
   178 		var te = '', type = this.type, c = true;
    82 		this.revert();
   179 		this.revert();
    83 
   180 
    84 		$('#bulk-edit td').attr('colspan', $('.widefat:first thead th:visible').length);
   181 		$( '#bulk-edit td' ).attr( 'colspan', $( 'th:visible, td:visible', '.widefat:first thead' ).length );
       
   182 
    85 		// Insert the editor at the top of the table with an empty row above to maintain zebra striping.
   183 		// Insert the editor at the top of the table with an empty row above to maintain zebra striping.
    86 		$('table.widefat tbody').prepend( $('#bulk-edit') ).prepend('<tr class="hidden"></tr>');
   184 		$('table.widefat tbody').prepend( $('#bulk-edit') ).prepend('<tr class="hidden"></tr>');
    87 		$('#bulk-edit').addClass('inline-editor').show();
   185 		$('#bulk-edit').addClass('inline-editor').show();
    88 
   186 
       
   187 		/**
       
   188 		 * @summary Create a HTML div with the title and a delete link(cross-icon) for each selected post.
       
   189 		 *
       
   190 		 * Get the selected posts based on the checked checkboxes in the post table.
       
   191 		 * Create a HTML div with the title and a link(delete-icon) for each selected post.
       
   192 		 */
    89 		$( 'tbody th.check-column input[type="checkbox"]' ).each( function() {
   193 		$( 'tbody th.check-column input[type="checkbox"]' ).each( function() {
       
   194 
       
   195 			// If the checkbox for a post is selected, add the post to the edit list.
    90 			if ( $(this).prop('checked') ) {
   196 			if ( $(this).prop('checked') ) {
    91 				c = false;
   197 				c = false;
    92 				var id = $(this).val(), theTitle;
   198 				var id = $(this).val(), theTitle;
    93 				theTitle = $('#inline_'+id+' .post_title').html() || inlineEditL10n.notitle;
   199 				theTitle = $('#inline_'+id+' .post_title').html() || inlineEditL10n.notitle;
    94 				te += '<div id="ttle'+id+'"><a id="_'+id+'" class="ntdelbutton" title="'+inlineEditL10n.ntdeltitle+'">X</a>'+theTitle+'</div>';
   200 				te += '<div id="ttle'+id+'"><a id="_'+id+'" class="ntdelbutton" title="'+inlineEditL10n.ntdeltitle+'">X</a>'+theTitle+'</div>';
    95 			}
   201 			}
    96 		});
   202 		});
    97 
   203 
       
   204 		// If no checkboxes where checked, just hide the quick/bulk edit rows.
    98 		if ( c ) {
   205 		if ( c ) {
    99 			return this.revert();
   206 			return this.revert();
   100 		}
   207 		}
   101 
   208 
       
   209 		// Add onclick events to the delete-icons in the bulk editors the post title list.
   102 		$('#bulk-titles').html(te);
   210 		$('#bulk-titles').html(te);
       
   211 		/**
       
   212 		 * @summary Binds on click events to the checkboxes before the posts in the table.
       
   213 		 *
       
   214 		 * @listens click
       
   215 		 */
   103 		$('#bulk-titles a').click(function(){
   216 		$('#bulk-titles a').click(function(){
   104 			var id = $(this).attr('id').substr(1);
   217 			var id = $(this).attr('id').substr(1);
   105 
   218 
   106 			$('table.widefat input[value="' + id + '"]').prop('checked', false);
   219 			$('table.widefat input[value="' + id + '"]').prop('checked', false);
   107 			$('#ttle'+id).remove();
   220 			$('#ttle'+id).remove();
   108 		});
   221 		});
   109 
   222 
   110 		// enable autocomplete for tags
   223 		// Enable auto-complete for tags when editing posts.
   111 		if ( 'post' === type ) {
   224 		if ( 'post' === type ) {
   112 			// support multi taxonomies?
   225 			$( 'tr.inline-editor textarea[data-wp-taxonomy]' ).each( function ( i, element ) {
   113 			tax = 'post_tag';
   226 				/*
   114 			$('tr.inline-editor textarea[name="tax_input['+tax+']"]').suggest( ajaxurl + '?action=ajax-tag-search&tax=' + tax, { delay: 500, minchars: 2, multiple: true, multipleSep: inlineEditL10n.comma } );
   227 				 * While Quick Edit clones the form each time, Bulk Edit always re-uses
   115 		}
   228 				 * the same form. Let's check if an autocomplete instance already exists.
       
   229 				 */
       
   230 				if ( $( element ).autocomplete( 'instance' ) ) {
       
   231 					// jQuery equivalent of `continue` within an `each()` loop.
       
   232 					return;
       
   233 				}
       
   234 
       
   235 				$( element ).wpTagsSuggest();
       
   236 			} );
       
   237 		}
       
   238 
       
   239 		// Scrolls to the top of the table where the editor is rendered.
   116 		$('html, body').animate( { scrollTop: 0 }, 'fast' );
   240 		$('html, body').animate( { scrollTop: 0 }, 'fast' );
   117 	},
   241 	},
   118 
   242 
       
   243 	/**
       
   244 	 * @summary Creates a quick edit window for the post that has been clicked.
       
   245 	 *
       
   246 	 * @memberof inlineEditPost
       
   247 	 * @since 2.7.0
       
   248 	 *
       
   249 	 * @param {number|Object} id The id of the clicked post or an element within a post
       
   250 	 *                           table row.
       
   251 	 * @returns {boolean} Always returns false at the end of execution.
       
   252 	 */
   119 	edit : function(id) {
   253 	edit : function(id) {
   120 		var t = this, fields, editRow, rowData, status, pageOpt, pageLevel, nextPage, pageLoop = true, nextLevel, cur_format, f, val;
   254 		var t = this, fields, editRow, rowData, status, pageOpt, pageLevel, nextPage, pageLoop = true, nextLevel, f, val, pw;
   121 		t.revert();
   255 		t.revert();
   122 
   256 
   123 		if ( typeof(id) === 'object' ) {
   257 		if ( typeof(id) === 'object' ) {
   124 			id = t.getId(id);
   258 			id = t.getId(id);
   125 		}
   259 		}
   126 
   260 
   127 		fields = ['post_title', 'post_name', 'post_author', '_status', 'jj', 'mm', 'aa', 'hh', 'mn', 'ss', 'post_password', 'post_format', 'menu_order'];
   261 		fields = ['post_title', 'post_name', 'post_author', '_status', 'jj', 'mm', 'aa', 'hh', 'mn', 'ss', 'post_password', 'post_format', 'menu_order', 'page_template'];
   128 		if ( t.type === 'page' ) {
   262 		if ( t.type === 'page' ) {
   129 			fields.push('post_parent', 'page_template');
   263 			fields.push('post_parent');
   130 		}
   264 		}
   131 
   265 
   132 		// add the new edit row with an extra blank row underneath to maintain zebra striping.
   266 		// Add the new edit row with an extra blank row underneath to maintain zebra striping.
   133 		editRow = $('#inline-edit').clone(true);
   267 		editRow = $('#inline-edit').clone(true);
   134 		$('td', editRow).attr('colspan', $('.widefat:first thead th:visible').length);
   268 		$( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '.widefat:first thead' ).length );
   135 
   269 
   136 		$(t.what+id).hide().after(editRow).after('<tr class="hidden"></tr>');
   270 		$(t.what+id).removeClass('is-expanded').hide().after(editRow).after('<tr class="hidden"></tr>');
   137 
   271 
   138 		// populate the data
   272 		// Populate fields in the quick edit window.
   139 		rowData = $('#inline_'+id);
   273 		rowData = $('#inline_'+id);
   140 		if ( !$(':input[name="post_author"] option[value="' + $('.post_author', rowData).text() + '"]', editRow).val() ) {
   274 		if ( !$(':input[name="post_author"] option[value="' + $('.post_author', rowData).text() + '"]', editRow).val() ) {
   141 			// author no longer has edit caps, so we need to add them to the list of authors
   275 
       
   276 			// The post author no longer has edit capabilities, so we need to add them to the list of authors.
   142 			$(':input[name="post_author"]', editRow).prepend('<option value="' + $('.post_author', rowData).text() + '">' + $('#' + t.type + '-' + id + ' .author').text() + '</option>');
   277 			$(':input[name="post_author"]', editRow).prepend('<option value="' + $('.post_author', rowData).text() + '">' + $('#' + t.type + '-' + id + ' .author').text() + '</option>');
   143 		}
   278 		}
   144 		if ( $( ':input[name="post_author"] option', editRow ).length === 1 ) {
   279 		if ( $( ':input[name="post_author"] option', editRow ).length === 1 ) {
   145 			$('label.inline-edit-author', editRow).hide();
   280 			$('label.inline-edit-author', editRow).hide();
   146 		}
   281 		}
   147 
   282 
   148 		// hide unsupported formats, but leave the current format alone
       
   149 		cur_format = $('.post_format', rowData).text();
       
   150 		$('option.unsupported', editRow).each(function() {
       
   151 			var $this = $(this);
       
   152 			if ( $this.val() !== cur_format ) {
       
   153 				$this.remove();
       
   154 			}
       
   155 		});
       
   156 
       
   157 		for ( f = 0; f < fields.length; f++ ) {
   283 		for ( f = 0; f < fields.length; f++ ) {
   158 			val = $('.'+fields[f], rowData);
   284 			val = $('.'+fields[f], rowData);
   159 			// Deal with Twemoji
   285 
       
   286 			/**
       
   287 			 * @summary Replaces the image for a Twemoji(Twitter emoji) with it's alternate text.
       
   288 			 *
       
   289 			 * @returns Alternate text from the image.
       
   290 			 */
   160 			val.find( 'img' ).replaceWith( function() { return this.alt; } );
   291 			val.find( 'img' ).replaceWith( function() { return this.alt; } );
   161 			val = val.text();
   292 			val = val.text();
   162 			$(':input[name="' + fields[f] + '"]', editRow).val( val );
   293 			$(':input[name="' + fields[f] + '"]', editRow).val( val );
   163 		}
   294 		}
   164 
   295 
   170 		}
   301 		}
   171 		if ( $( '.sticky', rowData ).text() === 'sticky' ) {
   302 		if ( $( '.sticky', rowData ).text() === 'sticky' ) {
   172 			$( 'input[name="sticky"]', editRow ).prop( 'checked', true );
   303 			$( 'input[name="sticky"]', editRow ).prop( 'checked', true );
   173 		}
   304 		}
   174 
   305 
   175 		// hierarchical taxonomies
   306 		/**
       
   307 		 * @summary Creates the select boxes for the categories.
       
   308 		 */
   176 		$('.post_category', rowData).each(function(){
   309 		$('.post_category', rowData).each(function(){
   177 			var taxname,
   310 			var taxname,
   178 				term_ids = $(this).text();
   311 				term_ids = $(this).text();
   179 
   312 
   180 			if ( term_ids ) {
   313 			if ( term_ids ) {
   181 				taxname = $(this).attr('id').replace('_'+id, '');
   314 				taxname = $(this).attr('id').replace('_'+id, '');
   182 				$('ul.'+taxname+'-checklist :checkbox', editRow).val(term_ids.split(','));
   315 				$('ul.'+taxname+'-checklist :checkbox', editRow).val(term_ids.split(','));
   183 			}
   316 			}
   184 		});
   317 		});
   185 
   318 
   186 		//flat taxonomies
   319 		/**
       
   320 		 * @summary Gets all the taxonomies for live auto-fill suggestions.
       
   321 		 * When typing the name of a tag.
       
   322 		 */
   187 		$('.tags_input', rowData).each(function(){
   323 		$('.tags_input', rowData).each(function(){
   188 			var terms = $(this),
   324 			var terms = $(this),
   189 				taxname = $(this).attr('id').replace('_' + id, ''),
   325 				taxname = $(this).attr('id').replace('_' + id, ''),
   190 				textarea = $('textarea.tax_input_' + taxname, editRow),
   326 				textarea = $('textarea.tax_input_' + taxname, editRow),
   191 				comma = inlineEditL10n.comma;
   327 				comma = inlineEditL10n.comma;
   198 					terms = terms.replace(/,/g, comma);
   334 					terms = terms.replace(/,/g, comma);
   199 				}
   335 				}
   200 				textarea.val(terms);
   336 				textarea.val(terms);
   201 			}
   337 			}
   202 
   338 
   203 			textarea.suggest( ajaxurl + '?action=ajax-tag-search&tax=' + taxname, { delay: 500, minchars: 2, multiple: true, multipleSep: inlineEditL10n.comma } );
   339 			textarea.wpTagsSuggest();
   204 		});
   340 		});
   205 
   341 
   206 		// handle the post status
   342 		// Handle the post status.
   207 		status = $('._status', rowData).text();
   343 		status = $('._status', rowData).text();
   208 		if ( 'future' !== status ) {
   344 		if ( 'future' !== status ) {
   209 			$('select[name="_status"] option[value="future"]', editRow).remove();
   345 			$('select[name="_status"] option[value="future"]', editRow).remove();
   210 		}
   346 		}
   211 
   347 
       
   348 		pw = $( '.inline-edit-password-input' ).prop( 'disabled', false );
   212 		if ( 'private' === status ) {
   349 		if ( 'private' === status ) {
   213 			$('input[name="keep_private"]', editRow).prop('checked', true);
   350 			$('input[name="keep_private"]', editRow).prop('checked', true);
   214 			$('input.inline-edit-password-input').val('').prop('disabled', true);
   351 			pw.val( '' ).prop( 'disabled', true );
   215 		}
   352 		}
   216 
   353 
   217 		// remove the current page and children from the parent dropdown
   354 		// Remove the current page and children from the parent dropdown.
   218 		pageOpt = $('select[name="post_parent"] option[value="' + id + '"]', editRow);
   355 		pageOpt = $('select[name="post_parent"] option[value="' + id + '"]', editRow);
   219 		if ( pageOpt.length > 0 ) {
   356 		if ( pageOpt.length > 0 ) {
   220 			pageLevel = pageOpt[0].className.split('-')[1];
   357 			pageLevel = pageOpt[0].className.split('-')[1];
   221 			nextPage = pageOpt;
   358 			nextPage = pageOpt;
   222 			while ( pageLoop ) {
   359 			while ( pageLoop ) {
   241 		$('.ptitle', editRow).focus();
   378 		$('.ptitle', editRow).focus();
   242 
   379 
   243 		return false;
   380 		return false;
   244 	},
   381 	},
   245 
   382 
       
   383 	/**
       
   384 	 * @summary Saves the changes made in the quick edit window to the post.
       
   385 	 * AJAX saving is only for Quick Edit and not for bulk edit.
       
   386 	 *
       
   387 	 * @since 2.7.0
       
   388 	 *
       
   389 	 * @param   {int}     id The id for the post that has been changed.
       
   390 	 * @returns {boolean}    false, so the form does not submit when pressing
       
   391 	 *                       Enter on a focused field.
       
   392 	 */
   246 	save : function(id) {
   393 	save : function(id) {
   247 		var params, fields, page = $('.post_status_page').val() || '';
   394 		var params, fields, page = $('.post_status_page').val() || '';
   248 
   395 
   249 		if ( typeof(id) === 'object' ) {
   396 		if ( typeof(id) === 'object' ) {
   250 			id = this.getId(id);
   397 			id = this.getId(id);
   261 		};
   408 		};
   262 
   409 
   263 		fields = $('#edit-'+id).find(':input').serialize();
   410 		fields = $('#edit-'+id).find(':input').serialize();
   264 		params = fields + '&' + $.param(params);
   411 		params = fields + '&' + $.param(params);
   265 
   412 
   266 		// make ajax request
   413 		// Make ajax request.
   267 		$.post( ajaxurl, params,
   414 		$.post( ajaxurl, params,
   268 			function(r) {
   415 			function(r) {
       
   416 				var $errorNotice = $( '#edit-' + id + ' .inline-edit-save .notice-error' ),
       
   417 					$error = $errorNotice.find( '.error' );
       
   418 
   269 				$( 'table.widefat .spinner' ).removeClass( 'is-active' );
   419 				$( 'table.widefat .spinner' ).removeClass( 'is-active' );
       
   420 				$( '.ac_results' ).hide();
   270 
   421 
   271 				if (r) {
   422 				if (r) {
   272 					if ( -1 !== r.indexOf( '<tr' ) ) {
   423 					if ( -1 !== r.indexOf( '<tr' ) ) {
   273 						$(inlineEditPost.what+id).siblings('tr.hidden').addBack().remove();
   424 						$(inlineEditPost.what+id).siblings('tr.hidden').addBack().remove();
   274 						$('#edit-'+id).before(r).remove();
   425 						$('#edit-'+id).before(r).remove();
   275 						$(inlineEditPost.what+id).hide().fadeIn();
   426 						$( inlineEditPost.what + id ).hide().fadeIn( 400, function() {
       
   427 							// Move focus back to the Quick Edit link. $( this ) is the row being animated.
       
   428 							$( this ).find( '.editinline' ).focus();
       
   429 							wp.a11y.speak( inlineEditL10n.saved );
       
   430 						});
   276 					} else {
   431 					} else {
   277 						r = r.replace( /<.[^<>]*?>/g, '' );
   432 						r = r.replace( /<.[^<>]*?>/g, '' );
   278 						$('#edit-'+id+' .inline-edit-save .error').html(r).show();
   433 						$errorNotice.removeClass( 'hidden' );
       
   434 						$error.html( r );
       
   435 						wp.a11y.speak( $error.text() );
   279 					}
   436 					}
   280 				} else {
   437 				} else {
   281 					$('#edit-'+id+' .inline-edit-save .error').html(inlineEditL10n.error).show();
   438 					$errorNotice.removeClass( 'hidden' );
       
   439 					$error.html( inlineEditL10n.error );
       
   440 					wp.a11y.speak( inlineEditL10n.error );
   282 				}
   441 				}
   283 			},
   442 			},
   284 		'html');
   443 		'html');
       
   444 
       
   445 		// Prevent submitting the form when pressing Enter on a focused field.
   285 		return false;
   446 		return false;
   286 	},
   447 	},
   287 
   448 
       
   449 	/**
       
   450 	 * @summary Hides and empties the Quick Edit and/or Bulk Edit windows.
       
   451 	 *
       
   452 	 * @memberof    inlineEditPost
       
   453 	 * @since 2.7.0
       
   454 	 *
       
   455 	 * @returns {boolean} Always returns false.
       
   456 	 */
   288 	revert : function(){
   457 	revert : function(){
   289 		var id = $('table.widefat tr.inline-editor').attr('id');
   458 		var $tableWideFat = $( '.widefat' ),
       
   459 			id = $( '.inline-editor', $tableWideFat ).attr( 'id' );
   290 
   460 
   291 		if ( id ) {
   461 		if ( id ) {
   292 			$( 'table.widefat .spinner' ).removeClass( 'is-active' );
   462 			$( '.spinner', $tableWideFat ).removeClass( 'is-active' );
       
   463 			$( '.ac_results' ).hide();
   293 
   464 
   294 			if ( 'bulk-edit' === id ) {
   465 			if ( 'bulk-edit' === id ) {
   295 				$('table.widefat #bulk-edit').removeClass('inline-editor').hide().siblings('tr.hidden').remove();
   466 
       
   467 				// Hide the bulk editor.
       
   468 				$( '#bulk-edit', $tableWideFat ).removeClass( 'inline-editor' ).hide().siblings( '.hidden' ).remove();
   296 				$('#bulk-titles').empty();
   469 				$('#bulk-titles').empty();
       
   470 
       
   471 				// Store the empty bulk editor in a hidden element.
   297 				$('#inlineedit').append( $('#bulk-edit') );
   472 				$('#inlineedit').append( $('#bulk-edit') );
       
   473 
       
   474 				// Move focus back to the Bulk Action button that was activated.
       
   475 				$( '#' + inlineEditPost.whichBulkButtonId ).focus();
   298 			} else {
   476 			} else {
       
   477 
       
   478 				// Remove both the inline-editor and its hidden tr siblings.
   299 				$('#'+id).siblings('tr.hidden').addBack().remove();
   479 				$('#'+id).siblings('tr.hidden').addBack().remove();
   300 				id = id.substr( id.lastIndexOf('-') + 1 );
   480 				id = id.substr( id.lastIndexOf('-') + 1 );
   301 				$(this.what+id).show();
   481 
       
   482 				// Show the post row and move focus back to the Quick Edit link.
       
   483 				$( this.what + id ).show().find( '.editinline' ).focus();
   302 			}
   484 			}
   303 		}
   485 		}
   304 
   486 
   305 		return false;
   487 		return false;
   306 	},
   488 	},
   307 
   489 
       
   490 	/**
       
   491 	 * @summary Gets the id for a the post that you want to quick edit from the row
       
   492 	 * in the quick edit table.
       
   493 	 *
       
   494 	 * @memberof    inlineEditPost
       
   495 	 * @since 2.7.0
       
   496 	 *
       
   497 	 * @param   {Object} o DOM row object to get the id for.
       
   498 	 * @returns {string}   The post id extracted from the table row in the object.
       
   499 	 */
   308 	getId : function(o) {
   500 	getId : function(o) {
   309 		var id = $(o).closest('tr').attr('id'),
   501 		var id = $(o).closest('tr').attr('id'),
   310 			parts = id.split('-');
   502 			parts = id.split('-');
   311 		return parts[parts.length - 1];
   503 		return parts[parts.length - 1];
   312 	}
   504 	}
   313 };
   505 };
   314 
   506 
   315 $( document ).ready( function(){ inlineEditPost.init(); } );
   507 $( document ).ready( function(){ inlineEditPost.init(); } );
   316 
   508 
   317 // Show/hide locks on posts
   509 // Show/hide locks on posts.
   318 $( document ).on( 'heartbeat-tick.wp-check-locked-posts', function( e, data ) {
   510 $( document ).on( 'heartbeat-tick.wp-check-locked-posts', function( e, data ) {
   319 	var locked = data['wp-check-locked-posts'] || {};
   511 	var locked = data['wp-check-locked-posts'] || {};
   320 
   512 
   321 	$('#the-list tr').each( function(i, el) {
   513 	$('#the-list tr').each( function(i, el) {
   322 		var key = el.id, row = $(el), lock_data, avatar;
   514 		var key = el.id, row = $(el), lock_data, avatar;
   326 				lock_data = locked[key];
   518 				lock_data = locked[key];
   327 				row.find('.column-title .locked-text').text( lock_data.text );
   519 				row.find('.column-title .locked-text').text( lock_data.text );
   328 				row.find('.check-column checkbox').prop('checked', false);
   520 				row.find('.check-column checkbox').prop('checked', false);
   329 
   521 
   330 				if ( lock_data.avatar_src ) {
   522 				if ( lock_data.avatar_src ) {
   331 					avatar = $('<img class="avatar avatar-18 photo" width="18" height="18" />').attr( 'src', lock_data.avatar_src.replace(/&amp;/g, '&') );
   523 					avatar = $( '<img class="avatar avatar-18 photo" width="18" height="18" alt="" />' ).attr( 'src', lock_data.avatar_src.replace( /&amp;/g, '&' ) );
   332 					row.find('.column-title .locked-avatar').empty().append( avatar );
   524 					row.find('.column-title .locked-avatar').empty().append( avatar );
   333 				}
   525 				}
   334 				row.addClass('wp-locked');
   526 				row.addClass('wp-locked');
   335 			}
   527 			}
   336 		} else if ( row.hasClass('wp-locked') ) {
   528 		} else if ( row.hasClass('wp-locked') ) {
   349 
   541 
   350 	if ( check.length ) {
   542 	if ( check.length ) {
   351 		data['wp-check-locked-posts'] = check;
   543 		data['wp-check-locked-posts'] = check;
   352 	}
   544 	}
   353 }).ready( function() {
   545 }).ready( function() {
       
   546 
   354 	// Set the heartbeat interval to 15 sec.
   547 	// Set the heartbeat interval to 15 sec.
   355 	if ( typeof wp !== 'undefined' && wp.heartbeat ) {
   548 	if ( typeof wp !== 'undefined' && wp.heartbeat ) {
   356 		wp.heartbeat.interval( 15 );
   549 		wp.heartbeat.interval( 15 );
   357 	}
   550 	}
   358 });
   551 });
   359 
   552 
   360 }(jQuery));
   553 })( jQuery, window.wp );