wp/wp-includes/js/autosave.js
changeset 0 d970ebf37754
child 5 5e2f62d02dcd
equal deleted inserted replaced
-1:000000000000 0:d970ebf37754
       
     1 var autosave, autosaveLast = '', autosavePeriodical, autosaveDelayPreview = false, notSaved = true, blockSave = false, fullscreen, autosaveLockRelease = true;
       
     2 
       
     3 jQuery(document).ready( function($) {
       
     4 
       
     5 	if ( $('#wp-content-wrap').hasClass('tmce-active') && typeof switchEditors != 'undefined' ) {
       
     6 		autosaveLast = wp.autosave.getCompareString({
       
     7 			post_title : $('#title').val() || '',
       
     8 			content : switchEditors.pre_wpautop( $('#content').val() ) || '',
       
     9 			excerpt : $('#excerpt').val() || ''
       
    10 		});
       
    11 	} else {
       
    12 		autosaveLast = wp.autosave.getCompareString();
       
    13 	}
       
    14 
       
    15 	autosavePeriodical = $.schedule({time: autosaveL10n.autosaveInterval * 1000, func: function() { autosave(); }, repeat: true, protect: true});
       
    16 
       
    17 	//Disable autosave after the form has been submitted
       
    18 	$("#post").submit(function() {
       
    19 		$.cancel(autosavePeriodical);
       
    20 		autosaveLockRelease = false;
       
    21 	});
       
    22 
       
    23 	$('input[type="submit"], a.submitdelete', '#submitpost').click(function(){
       
    24 		blockSave = true;
       
    25 		window.onbeforeunload = null;
       
    26 		$(':button, :submit', '#submitpost').each(function(){
       
    27 			var t = $(this);
       
    28 			if ( t.hasClass('button-primary') )
       
    29 				t.addClass('button-primary-disabled');
       
    30 			else
       
    31 				t.addClass('button-disabled');
       
    32 		});
       
    33 		if ( $(this).attr('id') == 'publish' )
       
    34 			$('#major-publishing-actions .spinner').show();
       
    35 		else
       
    36 			$('#minor-publishing .spinner').show();
       
    37 	});
       
    38 
       
    39 	window.onbeforeunload = function(){
       
    40 		var editor = typeof(tinymce) != 'undefined' ? tinymce.activeEditor : false, compareString;
       
    41 
       
    42 		if ( editor && ! editor.isHidden() ) {
       
    43 			if ( editor.isDirty() )
       
    44 				return autosaveL10n.saveAlert;
       
    45 		} else {
       
    46 			if ( fullscreen && fullscreen.settings.visible ) {
       
    47 				compareString = wp.autosave.getCompareString({
       
    48 					post_title: $('#wp-fullscreen-title').val() || '',
       
    49 					content: $('#wp_mce_fullscreen').val() || '',
       
    50 					excerpt: $('#excerpt').val() || ''
       
    51 				});
       
    52 			} else {
       
    53 				compareString = wp.autosave.getCompareString();
       
    54 			}
       
    55 
       
    56 			if ( compareString != autosaveLast )
       
    57 				return autosaveL10n.saveAlert;
       
    58 		}
       
    59 	};
       
    60 
       
    61 	$(window).unload( function(e) {
       
    62 		if ( ! autosaveLockRelease )
       
    63 			return;
       
    64 
       
    65 		// unload fires (twice) on removing the Thickbox iframe. Make sure we process only the main document unload.
       
    66 		if ( e.target && e.target.nodeName != '#document' )
       
    67 			return;
       
    68 
       
    69 		$.ajax({
       
    70 			type: 'POST',
       
    71 			url: ajaxurl,
       
    72 			async: false,
       
    73 			data: {
       
    74 				action: 'wp-remove-post-lock',
       
    75 				_wpnonce: $('#_wpnonce').val(),
       
    76 				post_ID: $('#post_ID').val(),
       
    77 				active_post_lock: $('#active_post_lock').val()
       
    78 			}
       
    79 		});
       
    80 	} );
       
    81 
       
    82 	// preview
       
    83 	$('#post-preview').click(function(){
       
    84 		if ( $('#auto_draft').val() == '1' && notSaved ) {
       
    85 			autosaveDelayPreview = true;
       
    86 			autosave();
       
    87 			return false;
       
    88 		}
       
    89 		doPreview();
       
    90 		return false;
       
    91 	});
       
    92 
       
    93 	doPreview = function() {
       
    94 		$('input#wp-preview').val('dopreview');
       
    95 		$('form#post').attr('target', 'wp-preview').submit().attr('target', '');
       
    96 
       
    97 		/*
       
    98 		 * Workaround for WebKit bug preventing a form submitting twice to the same action.
       
    99 		 * https://bugs.webkit.org/show_bug.cgi?id=28633
       
   100 		 */
       
   101 		var ua = navigator.userAgent.toLowerCase();
       
   102 		if ( ua.indexOf('safari') != -1 && ua.indexOf('chrome') == -1 ) {
       
   103 			$('form#post').attr('action', function(index, value) {
       
   104 				return value + '?t=' + new Date().getTime();
       
   105 			});
       
   106 		}
       
   107 
       
   108 		$('input#wp-preview').val('');
       
   109 	}
       
   110 
       
   111 	// This code is meant to allow tabbing from Title to Post content.
       
   112 	$('#title').on('keydown.editor-focus', function(e) {
       
   113 		var ed;
       
   114 
       
   115 		if ( e.which != 9 )
       
   116 			return;
       
   117 
       
   118 		if ( !e.ctrlKey && !e.altKey && !e.shiftKey ) {
       
   119 			if ( typeof(tinymce) != 'undefined' )
       
   120 				ed = tinymce.get('content');
       
   121 
       
   122 			if ( ed && !ed.isHidden() ) {
       
   123 				$(this).one('keyup', function(e){
       
   124 					$('#content_tbl td.mceToolbar > a').focus();
       
   125 				});
       
   126 			} else {
       
   127 				$('#content').focus();
       
   128 			}
       
   129 
       
   130 			e.preventDefault();
       
   131 		}
       
   132 	});
       
   133 
       
   134 	// autosave new posts after a title is typed but not if Publish or Save Draft is clicked
       
   135 	if ( '1' == $('#auto_draft').val() ) {
       
   136 		$('#title').blur( function() {
       
   137 			if ( !this.value || $('#auto_draft').val() != '1' )
       
   138 				return;
       
   139 			delayed_autosave();
       
   140 		});
       
   141 	}
       
   142 
       
   143 	// When connection is lost, keep user from submitting changes.
       
   144 	$(document).on('heartbeat-connection-lost.autosave', function( e, error, status ) {
       
   145 		if ( 'timeout' === error || 503 == status ) {
       
   146 			var notice = $('#lost-connection-notice');
       
   147 			if ( ! wp.autosave.local.hasStorage ) {
       
   148 				notice.find('.hide-if-no-sessionstorage').hide();
       
   149 			}
       
   150 			notice.show();
       
   151 			autosave_disable_buttons();
       
   152 		}
       
   153 	}).on('heartbeat-connection-restored.autosave', function() {
       
   154 		$('#lost-connection-notice').hide();
       
   155 		autosave_enable_buttons();
       
   156 	});
       
   157 });
       
   158 
       
   159 function autosave_parse_response( response ) {
       
   160 	var res = wpAjax.parseAjaxResponse(response, 'autosave'), post_id, sup;
       
   161 
       
   162 	if ( res && res.responses && res.responses.length ) {
       
   163 		if ( res.responses[0].supplemental ) {
       
   164 			sup = res.responses[0].supplemental;
       
   165 
       
   166 			jQuery.each( sup, function( selector, value ) {
       
   167 				if ( selector.match(/^replace-/) )
       
   168 					jQuery( '#' + selector.replace('replace-', '') ).val( value );
       
   169 			});
       
   170 		}
       
   171 
       
   172 		// if no errors: add slug UI and update autosave-message
       
   173 		if ( !res.errors ) {
       
   174 			if ( post_id = parseInt( res.responses[0].id, 10 ) )
       
   175 				autosave_update_slug( post_id );
       
   176 
       
   177 			if ( res.responses[0].data ) // update autosave message
       
   178 				jQuery('.autosave-message').text( res.responses[0].data );
       
   179 		}
       
   180 	}
       
   181 
       
   182 	return res;
       
   183 }
       
   184 
       
   185 // called when autosaving pre-existing post
       
   186 function autosave_saved(response) {
       
   187 	blockSave = false;
       
   188 	autosave_parse_response(response); // parse the ajax response
       
   189 	autosave_enable_buttons(); // re-enable disabled form buttons
       
   190 }
       
   191 
       
   192 // called when autosaving new post
       
   193 function autosave_saved_new(response) {
       
   194 	blockSave = false;
       
   195 	var res = autosave_parse_response(response), post_id;
       
   196 
       
   197 	if ( res && res.responses.length && !res.errors ) {
       
   198 		// An ID is sent only for real auto-saves, not for autosave=0 "keepalive" saves
       
   199 		post_id = parseInt( res.responses[0].id, 10 );
       
   200 
       
   201 		if ( post_id ) {
       
   202 			notSaved = false;
       
   203 			jQuery('#auto_draft').val('0'); // No longer an auto-draft
       
   204 		}
       
   205 
       
   206 		autosave_enable_buttons();
       
   207 
       
   208 		if ( autosaveDelayPreview ) {
       
   209 			autosaveDelayPreview = false;
       
   210 			doPreview();
       
   211 		}
       
   212 	} else {
       
   213 		autosave_enable_buttons(); // re-enable disabled form buttons
       
   214 	}
       
   215 }
       
   216 
       
   217 function autosave_update_slug(post_id) {
       
   218 	// create slug area only if not already there
       
   219 	if ( 'undefined' != makeSlugeditClickable && jQuery.isFunction(makeSlugeditClickable) && !jQuery('#edit-slug-box > *').size() ) {
       
   220 		jQuery.post( ajaxurl, {
       
   221 				action: 'sample-permalink',
       
   222 				post_id: post_id,
       
   223 				new_title: fullscreen && fullscreen.settings.visible ? jQuery('#wp-fullscreen-title').val() : jQuery('#title').val(),
       
   224 				samplepermalinknonce: jQuery('#samplepermalinknonce').val()
       
   225 			},
       
   226 			function(data) {
       
   227 				if ( data !== '-1' ) {
       
   228 					var box = jQuery('#edit-slug-box');
       
   229 					box.html(data);
       
   230 					if (box.hasClass('hidden')) {
       
   231 						box.fadeIn('fast', function () {
       
   232 							box.removeClass('hidden');
       
   233 						});
       
   234 					}
       
   235 					makeSlugeditClickable();
       
   236 				}
       
   237 			}
       
   238 		);
       
   239 	}
       
   240 }
       
   241 
       
   242 function autosave_loading() {
       
   243 	jQuery('.autosave-message').html(autosaveL10n.savingText);
       
   244 }
       
   245 
       
   246 function autosave_enable_buttons() {
       
   247 	jQuery(document).trigger('autosave-enable-buttons');
       
   248 	if ( ! wp.heartbeat || ! wp.heartbeat.hasConnectionError() ) {
       
   249 		// delay that a bit to avoid some rare collisions while the DOM is being updated.
       
   250 		setTimeout(function(){
       
   251 			var parent = jQuery('#submitpost');
       
   252 			parent.find(':button, :submit').removeAttr('disabled');
       
   253 			parent.find('.spinner').hide();
       
   254 		}, 500);
       
   255 	}
       
   256 }
       
   257 
       
   258 function autosave_disable_buttons() {
       
   259 	jQuery(document).trigger('autosave-disable-buttons');
       
   260 	jQuery('#submitpost').find(':button, :submit').prop('disabled', true);
       
   261 	// Re-enable 5 sec later. Just gives autosave a head start to avoid collisions.
       
   262 	setTimeout( autosave_enable_buttons, 5000 );
       
   263 }
       
   264 
       
   265 function delayed_autosave() {
       
   266 	setTimeout(function(){
       
   267 		if ( blockSave )
       
   268 			return;
       
   269 		autosave();
       
   270 	}, 200);
       
   271 }
       
   272 
       
   273 autosave = function() {
       
   274 	var post_data = wp.autosave.getPostData(),
       
   275 		compareString,
       
   276 		successCallback;
       
   277 
       
   278 	blockSave = true;
       
   279 
       
   280 	// post_data.content cannot be retrieved at the moment
       
   281 	if ( ! post_data.autosave )
       
   282 		return false;
       
   283 
       
   284 	// No autosave while thickbox is open (media buttons)
       
   285 	if ( jQuery("#TB_window").css('display') == 'block' )
       
   286 		return false;
       
   287 
       
   288 	compareString = wp.autosave.getCompareString( post_data );
       
   289 
       
   290 	// Nothing to save or no change.
       
   291 	if ( compareString == autosaveLast )
       
   292 		return false;
       
   293 
       
   294 	autosaveLast = compareString;
       
   295 	jQuery(document).triggerHandler('wpcountwords', [ post_data["content"] ]);
       
   296 
       
   297 	// Disable buttons until we know the save completed.
       
   298 	autosave_disable_buttons();
       
   299 
       
   300 	if ( post_data["auto_draft"] == '1' ) {
       
   301 		successCallback = autosave_saved_new; // new post
       
   302 	} else {
       
   303 		successCallback = autosave_saved; // pre-existing post
       
   304 	}
       
   305 
       
   306 	jQuery.ajax({
       
   307 		data: post_data,
       
   308 		beforeSend: autosave_loading,
       
   309 		type: "POST",
       
   310 		url: ajaxurl,
       
   311 		success: successCallback
       
   312 	});
       
   313 
       
   314 	return true;
       
   315 }
       
   316 
       
   317 // Autosave in localStorage
       
   318 // set as simple object/mixin for now
       
   319 window.wp = window.wp || {};
       
   320 wp.autosave = wp.autosave || {};
       
   321 
       
   322 (function($){
       
   323 // Returns the data for saving in both localStorage and autosaves to the server
       
   324 wp.autosave.getPostData = function() {
       
   325 	var ed = typeof tinymce != 'undefined' ? tinymce.activeEditor : null, post_name, parent_id, cats = [],
       
   326 		data = {
       
   327 			action: 'autosave',
       
   328 			autosave: true,
       
   329 			post_id: $('#post_ID').val() || 0,
       
   330 			autosavenonce: $('#autosavenonce').val() || '',
       
   331 			post_type: $('#post_type').val() || '',
       
   332 			post_author: $('#post_author').val() || '',
       
   333 			excerpt: $('#excerpt').val() || ''
       
   334 		};
       
   335 
       
   336 	if ( ed && !ed.isHidden() ) {
       
   337 		// Don't run while the tinymce spellcheck is on. It resets all found words.
       
   338 		if ( ed.plugins.spellchecker && ed.plugins.spellchecker.active ) {
       
   339 			data.autosave = false;
       
   340 			return data;
       
   341 		} else {
       
   342 			if ( 'mce_fullscreen' == ed.id )
       
   343 				tinymce.get('content').setContent(ed.getContent({format : 'raw'}), {format : 'raw'});
       
   344 
       
   345 			tinymce.triggerSave();
       
   346 		}
       
   347 	}
       
   348 
       
   349 	if ( typeof fullscreen != 'undefined' && fullscreen.settings.visible ) {
       
   350 		data['post_title'] = $('#wp-fullscreen-title').val() || '';
       
   351 		data['content'] = $('#wp_mce_fullscreen').val() || '';
       
   352 	} else {
       
   353 		data['post_title'] = $('#title').val() || '';
       
   354 		data['content'] = $('#content').val() || '';
       
   355 	}
       
   356 
       
   357 	/*
       
   358 	// We haven't been saving tags with autosave since 2.8... Start again?
       
   359 	$('.the-tags').each( function() {
       
   360 		data[this.name] = this.value;
       
   361 	});
       
   362 	*/
       
   363 
       
   364 	$('input[id^="in-category-"]:checked').each( function() {
       
   365 		cats.push(this.value);
       
   366 	});
       
   367 	data['catslist'] = cats.join(',');
       
   368 
       
   369 	if ( post_name = $('#post_name').val() )
       
   370 		data['post_name'] = post_name;
       
   371 
       
   372 	if ( parent_id = $('#parent_id').val() )
       
   373 		data['parent_id'] = parent_id;
       
   374 
       
   375 	if ( $('#comment_status').prop('checked') )
       
   376 		data['comment_status'] = 'open';
       
   377 
       
   378 	if ( $('#ping_status').prop('checked') )
       
   379 		data['ping_status'] = 'open';
       
   380 
       
   381 	if ( $('#auto_draft').val() == '1' )
       
   382 		data['auto_draft'] = '1';
       
   383 
       
   384 	return data;
       
   385 };
       
   386 
       
   387 // Concatenate title, content and excerpt. Used to track changes when auto-saving.
       
   388 wp.autosave.getCompareString = function( post_data ) {
       
   389 	if ( typeof post_data === 'object' ) {
       
   390 		return ( post_data.post_title || '' ) + '::' + ( post_data.content || '' ) + '::' + ( post_data.excerpt || '' );
       
   391 	}
       
   392 
       
   393 	return ( $('#title').val() || '' ) + '::' + ( $('#content').val() || '' ) + '::' + ( $('#excerpt').val() || '' );
       
   394 };
       
   395 
       
   396 wp.autosave.local = {
       
   397 
       
   398 	lastSavedData: '',
       
   399 	blog_id: 0,
       
   400 	hasStorage: false,
       
   401 
       
   402 	// Check if the browser supports sessionStorage and it's not disabled
       
   403 	checkStorage: function() {
       
   404 		var test = Math.random(), result = false;
       
   405 
       
   406 		try {
       
   407 			sessionStorage.setItem('wp-test', test);
       
   408 			result = sessionStorage.getItem('wp-test') == test;
       
   409 			sessionStorage.removeItem('wp-test');
       
   410 		} catch(e) {}
       
   411 
       
   412 		this.hasStorage = result;
       
   413 		return result;
       
   414     },
       
   415 
       
   416 	/**
       
   417 	 * Initialize the local storage
       
   418 	 *
       
   419 	 * @return mixed False if no sessionStorage in the browser or an Object containing all post_data for this blog
       
   420 	 */
       
   421 	getStorage: function() {
       
   422 		var stored_obj = false;
       
   423 		// Separate local storage containers for each blog_id
       
   424 		if ( this.hasStorage && this.blog_id ) {
       
   425 			stored_obj = sessionStorage.getItem( 'wp-autosave-' + this.blog_id );
       
   426 
       
   427 			if ( stored_obj )
       
   428 				stored_obj = JSON.parse( stored_obj );
       
   429 			else
       
   430 				stored_obj = {};
       
   431 		}
       
   432 
       
   433 		return stored_obj;
       
   434 	},
       
   435 
       
   436 	/**
       
   437 	 * Set the storage for this blog
       
   438 	 *
       
   439 	 * Confirms that the data was saved successfully.
       
   440 	 *
       
   441 	 * @return bool
       
   442 	 */
       
   443 	setStorage: function( stored_obj ) {
       
   444 		var key;
       
   445 
       
   446 		if ( this.hasStorage && this.blog_id ) {
       
   447 			key = 'wp-autosave-' + this.blog_id;
       
   448 			sessionStorage.setItem( key, JSON.stringify( stored_obj ) );
       
   449 			return sessionStorage.getItem( key ) !== null;
       
   450 		}
       
   451 
       
   452 		return false;
       
   453 	},
       
   454 
       
   455 	/**
       
   456 	 * Get the saved post data for the current post
       
   457 	 *
       
   458 	 * @return mixed False if no storage or no data or the post_data as an Object
       
   459 	 */
       
   460 	getData: function() {
       
   461 		var stored = this.getStorage(), post_id = $('#post_ID').val();
       
   462 
       
   463 		if ( !stored || !post_id )
       
   464 			return false;
       
   465 
       
   466 		return stored[ 'post_' + post_id ] || false;
       
   467 	},
       
   468 
       
   469 	/**
       
   470 	 * Set (save or delete) post data in the storage.
       
   471 	 *
       
   472 	 * If stored_data evaluates to 'false' the storage key for the current post will be removed
       
   473 	 *
       
   474 	 * $param stored_data The post data to store or null/false/empty to delete the key
       
   475 	 * @return bool
       
   476 	 */
       
   477 	setData: function( stored_data ) {
       
   478 		var stored = this.getStorage(), post_id = $('#post_ID').val();
       
   479 
       
   480 		if ( !stored || !post_id )
       
   481 			return false;
       
   482 
       
   483 		if ( stored_data )
       
   484 			stored[ 'post_' + post_id ] = stored_data;
       
   485 		else if ( stored.hasOwnProperty( 'post_' + post_id ) )
       
   486 			delete stored[ 'post_' + post_id ];
       
   487 		else
       
   488 			return false;
       
   489 
       
   490 		return this.setStorage(stored);
       
   491 	},
       
   492 
       
   493 	/**
       
   494 	 * Save post data for the current post
       
   495 	 *
       
   496 	 * Runs on a 15 sec. schedule, saves when there are differences in the post title or content.
       
   497 	 * When the optional data is provided, updates the last saved post data.
       
   498 	 *
       
   499 	 * $param data optional Object The post data for saving, minimum 'post_title' and 'content'
       
   500 	 * @return bool
       
   501 	 */
       
   502 	save: function( data ) {
       
   503 		var result = false, post_data, compareString;
       
   504 
       
   505 		if ( ! data ) {
       
   506 			post_data = wp.autosave.getPostData();
       
   507 		} else {
       
   508 			post_data = this.getData() || {};
       
   509 			$.extend( post_data, data );
       
   510 			post_data.autosave = true;
       
   511 		}
       
   512 
       
   513 		// Cannot get the post data at the moment
       
   514 		if ( ! post_data.autosave )
       
   515 			return false;
       
   516 
       
   517 		compareString = wp.autosave.getCompareString( post_data );
       
   518 
       
   519 		// If the content, title and excerpt did not change since the last save, don't save again
       
   520 		if ( compareString == this.lastSavedData )
       
   521 			return false;
       
   522 
       
   523 		post_data['save_time'] = (new Date()).getTime();
       
   524 		post_data['status'] = $('#post_status').val() || '';
       
   525 		result = this.setData( post_data );
       
   526 
       
   527 		if ( result )
       
   528 			this.lastSavedData = compareString;
       
   529 
       
   530 		return result;
       
   531 	},
       
   532 
       
   533 	// Initialize and run checkPost() on loading the script (before TinyMCE init)
       
   534 	init: function( settings ) {
       
   535 		var self = this;
       
   536 
       
   537 		// Check if the browser supports sessionStorage and it's not disabled
       
   538 		if ( ! this.checkStorage() )
       
   539 			return;
       
   540 
       
   541 		// Don't run if the post type supports neither 'editor' (textarea#content) nor 'excerpt'.
       
   542 		if ( ! $('#content').length && ! $('#excerpt').length )
       
   543 			return;
       
   544 
       
   545 		if ( settings )
       
   546 			$.extend( this, settings );
       
   547 
       
   548 		if ( !this.blog_id )
       
   549 			this.blog_id = typeof window.autosaveL10n != 'undefined' ? window.autosaveL10n.blog_id : 0;
       
   550 
       
   551 		$(document).ready( function(){ self.run(); } );
       
   552 	},
       
   553 
       
   554 	// Run on DOM ready
       
   555 	run: function() {
       
   556 		var self = this;
       
   557 
       
   558 		// Check if the local post data is different than the loaded post data.
       
   559 		this.checkPost();
       
   560 
       
   561 		// Set the schedule
       
   562 		this.schedule = $.schedule({
       
   563 			time: 15 * 1000,
       
   564 			func: function() { wp.autosave.local.save(); },
       
   565 			repeat: true,
       
   566 			protect: true
       
   567 		});
       
   568 
       
   569 		$('form#post').on('submit.autosave-local', function() {
       
   570 			var editor = typeof tinymce != 'undefined' && tinymce.get('content'), post_id = $('#post_ID').val() || 0;
       
   571 
       
   572 			if ( editor && ! editor.isHidden() ) {
       
   573 				// Last onSubmit event in the editor, needs to run after the content has been moved to the textarea.
       
   574 				editor.onSubmit.add( function() {
       
   575 					wp.autosave.local.save({
       
   576 						post_title: $('#title').val() || '',
       
   577 						content: $('#content').val() || '',
       
   578 						excerpt: $('#excerpt').val() || ''
       
   579 					});
       
   580 				});
       
   581 			} else {
       
   582 				self.save({
       
   583 					post_title: $('#title').val() || '',
       
   584 					content: $('#content').val() || '',
       
   585 					excerpt: $('#excerpt').val() || ''
       
   586 				});
       
   587 			}
       
   588 
       
   589 			wpCookies.set( 'wp-saving-post-' + post_id, 'check' );
       
   590 		});
       
   591 	},
       
   592 
       
   593 	// Strip whitespace and compare two strings
       
   594 	compare: function( str1, str2 ) {
       
   595 		function remove( string ) {
       
   596 			return string.toString().replace(/[\x20\t\r\n\f]+/g, '');
       
   597 		}
       
   598 
       
   599 		return ( remove( str1 || '' ) == remove( str2 || '' ) );
       
   600 	},
       
   601 
       
   602 	/**
       
   603 	 * Check if the saved data for the current post (if any) is different than the loaded post data on the screen
       
   604 	 *
       
   605 	 * Shows a standard message letting the user restore the post data if different.
       
   606 	 *
       
   607 	 * @return void
       
   608 	 */
       
   609 	checkPost: function() {
       
   610 		var self = this, post_data = this.getData(), content, post_title, excerpt, notice,
       
   611 			post_id = $('#post_ID').val() || 0, cookie = wpCookies.get( 'wp-saving-post-' + post_id );
       
   612 
       
   613 		if ( ! post_data )
       
   614 			return;
       
   615 
       
   616 		if ( cookie ) {
       
   617 			wpCookies.remove( 'wp-saving-post-' + post_id );
       
   618 
       
   619 			if ( cookie == 'saved' ) {
       
   620 				// The post was saved properly, remove old data and bail
       
   621 				this.setData( false );
       
   622 				return;
       
   623 			}
       
   624 		}
       
   625 
       
   626 		// There is a newer autosave. Don't show two "restore" notices at the same time.
       
   627 		if ( $('#has-newer-autosave').length )
       
   628 			return;
       
   629 
       
   630 		content = $('#content').val() || '';
       
   631 		post_title = $('#title').val() || '';
       
   632 		excerpt = $('#excerpt').val() || '';
       
   633 
       
   634 		if ( $('#wp-content-wrap').hasClass('tmce-active') && typeof switchEditors != 'undefined' )
       
   635 			content = switchEditors.pre_wpautop( content );
       
   636 
       
   637 		// cookie == 'check' means the post was not saved properly, always show #local-storage-notice
       
   638 		if ( cookie != 'check' && this.compare( content, post_data.content ) && this.compare( post_title, post_data.post_title ) && this.compare( excerpt, post_data.excerpt ) ) {
       
   639 			return;
       
   640 		}
       
   641 
       
   642 		this.restore_post_data = post_data;
       
   643 		this.undo_post_data = {
       
   644 			content: content,
       
   645 			post_title: post_title,
       
   646 			excerpt: excerpt
       
   647 		};
       
   648 
       
   649 		notice = $('#local-storage-notice');
       
   650 		$('.wrap h2').first().after( notice.addClass('updated').show() );
       
   651 
       
   652 		notice.on( 'click', function(e) {
       
   653 			var target = $( e.target );
       
   654 
       
   655 			if ( target.hasClass('restore-backup') ) {
       
   656 				self.restorePost( self.restore_post_data );
       
   657 				target.parent().hide();
       
   658 				$(this).find('p.undo-restore').show();
       
   659 			} else if ( target.hasClass('undo-restore-backup') ) {
       
   660 				self.restorePost( self.undo_post_data );
       
   661 				target.parent().hide();
       
   662 				$(this).find('p.local-restore').show();
       
   663 			}
       
   664 
       
   665 			e.preventDefault();
       
   666 		});
       
   667 	},
       
   668 
       
   669 	// Restore the current title, content and excerpt from post_data.
       
   670 	restorePost: function( post_data ) {
       
   671 		var editor;
       
   672 
       
   673 		if ( post_data ) {
       
   674 			// Set the last saved data
       
   675 			this.lastSavedData = wp.autosave.getCompareString( post_data );
       
   676 
       
   677 			if ( $('#title').val() != post_data.post_title )
       
   678 				$('#title').focus().val( post_data.post_title || '' );
       
   679 
       
   680 			$('#excerpt').val( post_data.excerpt || '' );
       
   681 			editor = typeof tinymce != 'undefined' && tinymce.get('content');
       
   682 
       
   683 			if ( editor && ! editor.isHidden() && typeof switchEditors != 'undefined' ) {
       
   684 				// Make sure there's an undo level in the editor
       
   685 				editor.undoManager.add();
       
   686 				editor.setContent( post_data.content ? switchEditors.wpautop( post_data.content ) : '' );
       
   687 			} else {
       
   688 				// Make sure the Text editor is selected
       
   689 				$('#content-html').click();
       
   690 				$('#content').val( post_data.content );
       
   691 			}
       
   692 
       
   693 			return true;
       
   694 		}
       
   695 
       
   696 		return false;
       
   697 	}
       
   698 };
       
   699 
       
   700 wp.autosave.local.init();
       
   701 
       
   702 }(jQuery));