Autosave:

* Remove editor.js as a dependency for autosave.js, as it was in 3.5.
 * Remove heartbeat.js as an implicit dependency.
 * Abstract out the serialization of title/content/excerpt for comparisons.

props azaozz.
fixes #24756.



git-svn-id: http://core.svn.wordpress.org/trunk@24774 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Andrew Nacin 2013-07-23 03:05:21 +00:00
parent 80158fee6c
commit bbc4aa5317
2 changed files with 69 additions and 60 deletions

View File

@ -7,12 +7,12 @@ jQuery(document).ready( function($) {
if ( 'content' == editor.id ) {
editor.onLoad.add( function() {
editor.save();
autosaveLast = ( $('#title').val() || '' ) + ( $('#content').val() || '' );
autosaveLast = wp.autosave.getCompareString();
});
}
});
} else {
autosaveLast = ( $('#title').val() || '' ) + ( $('#content').val() || '' );
autosaveLast = wp.autosave.getCompareString();
}
autosavePeriodical = $.schedule({time: autosaveL10n.autosaveInterval * 1000, func: function() { autosave(); }, repeat: true, protect: true});
@ -40,21 +40,23 @@ jQuery(document).ready( function($) {
});
window.onbeforeunload = function(){
var mce = typeof(tinymce) != 'undefined' ? tinymce.activeEditor : false, title, content;
var editor = typeof(tinymce) != 'undefined' ? tinymce.activeEditor : false, compareString;
if ( mce && !mce.isHidden() ) {
if ( mce.isDirty() )
if ( editor && ! editor.isHidden() ) {
if ( editor.isDirty() )
return autosaveL10n.saveAlert;
} else {
if ( fullscreen && fullscreen.settings.visible ) {
title = $('#wp-fullscreen-title').val() || '';
content = $("#wp_mce_fullscreen").val() || '';
compareString = wp.autosave.getCompareString({
post_title: $('#wp-fullscreen-title').val() || '',
content: $('#wp_mce_fullscreen').val() || '',
excerpt: $('#excerpt').val() || ''
});
} else {
title = $('#post #title').val() || '';
content = $('#post #content').val() || '';
compareString = wp.autosave.getCompareString();
}
if ( ( title || content ) && title + content != autosaveLast )
if ( compareString != autosaveLast )
return autosaveL10n.saveAlert;
}
};
@ -246,7 +248,7 @@ function autosave_loading() {
function autosave_enable_buttons() {
jQuery(document).trigger('autosave-enable-buttons');
if ( ! wp.heartbeat.hasConnectionError() ) {
if ( ! wp.heartbeat || ! wp.heartbeat.hasConnectionError() ) {
// delay that a bit to avoid some rare collisions while the DOM is being updated.
setTimeout(function(){
var parent = jQuery('#submitpost');
@ -273,26 +275,27 @@ function delayed_autosave() {
autosave = function() {
var post_data = wp.autosave.getPostData(),
doAutoSave = post_data.autosave,
compareString,
successCallback;
blockSave = true;
// post_data.content cannot be retrieved at the moment
if ( ! post_data.autosave )
return false;
// No autosave while thickbox is open (media buttons)
if ( jQuery("#TB_window").css('display') == 'block' )
doAutoSave = false;
return false;
compareString = wp.autosave.getCompareString( post_data );
// Nothing to save or no change.
if ( ( post_data["post_title"].length == 0 && post_data["content"].length == 0 ) || post_data["post_title"] + post_data["content"] == autosaveLast ) {
doAutoSave = false;
}
if ( doAutoSave ) {
autosaveLast = post_data["post_title"] + post_data["content"];
jQuery(document).triggerHandler('wpcountwords', [ post_data["content"] ]);
} else {
if ( compareString == autosaveLast )
return false;
}
autosaveLast = compareString;
jQuery(document).triggerHandler('wpcountwords', [ post_data["content"] ]);
// Disable buttons until we know the save completed.
autosave_disable_buttons();
@ -305,7 +308,7 @@ autosave = function() {
jQuery.ajax({
data: post_data,
beforeSend: doAutoSave ? autosave_loading : null,
beforeSend: autosave_loading,
type: "POST",
url: ajaxurl,
success: successCallback
@ -382,13 +385,21 @@ wp.autosave.getPostData = function() {
data['auto_draft'] = '1';
return data;
}
};
// Concatenate title, content and excerpt. Used to track changes when auto-saving.
wp.autosave.getCompareString = function( post_data ) {
if ( typeof post_data === 'object' ) {
return ( post_data.post_title || '' ) + '::' + ( post_data.content || '' ) + '::' + ( post_data.excerpt || '' );
}
return ( $('#title').val() || '' ) + '::' + ( $('#content').val() || '' ) + '::' + ( $('#excerpt').val() || '' );
};
wp.autosave.local = {
lastsaveddata: '',
lastSavedData: '',
blog_id: 0,
ajaxurl: window.ajaxurl || 'wp-admin/admin-ajax.php',
hasStorage: false,
// Check if the browser supports sessionStorage and it's not disabled
@ -492,7 +503,7 @@ wp.autosave.local = {
* @return bool
*/
save: function( data ) {
var result = false;
var result = false, post_data, compareString;
if ( ! data ) {
post_data = wp.autosave.getPostData();
@ -502,12 +513,14 @@ wp.autosave.local = {
post_data.autosave = true;
}
// If the content and title did not change since the last save, don't save again
if ( post_data.post_title + ': ' + post_data.content == this.lastsaveddata )
// Cannot get the post data at the moment
if ( ! post_data.autosave )
return false;
// Cannot get the post data at the moment
if ( !post_data.autosave )
compareString = wp.autosave.getCompareString( post_data );
// If the content, title and excerpt did not change since the last save, don't save again
if ( compareString == this.lastSavedData )
return false;
post_data['save_time'] = (new Date()).getTime();
@ -515,7 +528,7 @@ wp.autosave.local = {
result = this.setData( post_data );
if ( result )
this.lastsaveddata = post_data.post_title + ': ' + post_data.content;
this.lastSavedData = compareString;
return result;
},
@ -524,8 +537,8 @@ wp.autosave.local = {
init: function( settings ) {
var self = this;
// Check if the browser supports sessionStorage and editor.js is loaded
if ( ! this.checkStorage() || typeof switchEditors == 'undefined' )
// Check if the browser supports sessionStorage and it's not disabled
if ( ! this.checkStorage() )
return;
// Don't run if the post type supports neither 'editor' (textarea#content) nor 'excerpt'.
@ -538,23 +551,15 @@ wp.autosave.local = {
if ( !this.blog_id )
this.blog_id = typeof window.autosaveL10n != 'undefined' ? window.autosaveL10n.blog_id : 0;
this.checkPost();
$(document).ready( function(){ self.run(); } );
},
// Run on DOM ready
run: function() {
var self = this, post_data;
var self = this;
// Set the comparison string
if ( !this.lastsaveddata ) {
post_data = wp.autosave.getPostData();
if ( post_data.content && $('#wp-content-wrap').hasClass('tmce-active') )
this.lastsaveddata = post_data.post_title + ': ' + switchEditors.pre_wpautop( post_data.content );
else
this.lastsaveddata = post_data.post_title + ': ' + post_data.content;
}
// Check if the local post data is different than the loaded post data.
this.checkPost();
// Set the schedule
this.schedule = $.schedule({
@ -605,7 +610,7 @@ wp.autosave.local = {
* @return void
*/
checkPost: function() {
var self = this, post_data = this.getData(), content, check_data, strip_tags = false, notice,
var self = this, post_data = this.getData(), content, post_title, excerpt, notice,
post_id = $('#post_ID').val() || 0, cookie = wpCookies.get( 'wp-saving-post-' + post_id );
if ( ! post_data )
@ -625,20 +630,24 @@ wp.autosave.local = {
if ( $('#has-newer-autosave').length )
return;
content = $('#content').val() || '';
post_title = $('#title').val() || '';
excerpt = $('#excerpt').val() || '';
if ( $('#wp-content-wrap').hasClass('tmce-active') && typeof switchEditors != 'undefined' )
content = switchEditors.pre_wpautop( content );
// cookie == 'check' means the post was not saved properly, always show #local-storage-notice
if ( cookie != 'check' ) {
content = $('#content').val();
check_data = $.extend( {}, post_data );
if ( $('#wp-content-wrap').hasClass('tmce-active') )
content = switchEditors.pre_wpautop( content );
if ( this.compare( content, check_data.content ) && this.compare( $('#title').val(), check_data.post_title ) && this.compare( $('#excerpt').val(), check_data.excerpt ) )
return;
if ( cookie != 'check' && this.compare( content, post_data.content ) && this.compare( post_title, post_data.post_title ) && this.compare( excerpt, post_data.excerpt ) ) {
return;
}
this.restore_post_data = post_data;
this.undo_post_data = wp.autosave.getPostData();
this.undo_post_data = {
content: content,
post_title: post_title,
excerpt: excerpt
};
notice = $('#local-storage-notice');
$('.wrap h2').first().after( notice.addClass('updated').show() );
@ -666,7 +675,7 @@ wp.autosave.local = {
if ( post_data ) {
// Set the last saved data
this.lastsaveddata = post_data.post_title + ': ' + post_data.content;
this.lastSavedData = wp.autosave.getCompareString( post_data );
if ( $('#title').val() != post_data.post_title )
$('#title').focus().val( post_data.post_title || '' );
@ -674,7 +683,7 @@ wp.autosave.local = {
$('#excerpt').val( post_data.excerpt || '' );
editor = typeof tinymce != 'undefined' && tinymce.get('content');
if ( editor && ! editor.isHidden() ) {
if ( editor && ! editor.isHidden() && typeof switchEditors != 'undefined' ) {
// Make sure there's an undo level in the editor
editor.undoManager.add();
editor.setContent( post_data.content ? switchEditors.wpautop( post_data.content ) : '' );
@ -689,7 +698,7 @@ wp.autosave.local = {
return false;
}
}
};
wp.autosave.local.init();

View File

@ -103,7 +103,7 @@ function wp_default_scripts( &$scripts ) {
'dismiss' => __('Dismiss'),
) );
$scripts->add( 'autosave', "/wp-includes/js/autosave$suffix.js", array('schedule', 'wp-ajax-response', 'editor'), false, 1 );
$scripts->add( 'autosave', "/wp-includes/js/autosave$suffix.js", array('schedule', 'wp-ajax-response'), false, 1 );
$scripts->add( 'heartbeat', "/wp-includes/js/heartbeat$suffix.js", array('jquery'), false, 1 );
did_action( 'init' ) && $scripts->localize( 'heartbeat', 'heartbeatSettings',