1 var autosave, autosaveLast = '', autosavePeriodical, autosaveOldMessage = '', autosaveDelayPreview = false, notSaved = true, blockSave = false, fullscreen, autosaveLockRelease = true;
3 jQuery(document).ready( function($) {
6 autosaveLast = $('#post #title').val() + $('#post #content').val();
7 autosavePeriodical = $.schedule({time: autosaveL10n.autosaveInterval * 1000, func: function() { autosave(); }, repeat: true, protect: true});
9 //Disable autosave after the form has been submitted
10 $("#post").submit(function() {
11 $.cancel(autosavePeriodical);
12 autosaveLockRelease = false;
15 $('input[type="submit"], a.submitdelete', '#submitpost').click(function(){
17 window.onbeforeunload = null;
18 $(':button, :submit', '#submitpost').each(function(){
20 if ( t.hasClass('button-primary') )
21 t.addClass('button-primary-disabled');
23 t.addClass('button-disabled');
25 if ( $(this).attr('id') == 'publish' )
26 $('#ajax-loading').css('visibility', 'visible');
28 $('#draft-ajax-loading').css('visibility', 'visible');
31 window.onbeforeunload = function(){
32 var mce = typeof(tinyMCE) != 'undefined' ? tinyMCE.activeEditor : false, title, content;
34 if ( mce && !mce.isHidden() ) {
36 return autosaveL10n.saveAlert;
38 if ( fullscreen && fullscreen.settings.visible ) {
39 title = $('#wp-fullscreen-title').val();
40 content = $("#wp_mce_fullscreen").val();
42 title = $('#post #title').val();
43 content = $('#post #content').val();
46 if ( ( title || content ) && title + content != autosaveLast )
47 return autosaveL10n.saveAlert;
51 $(window).unload( function(e) {
52 if ( ! autosaveLockRelease )
55 // unload fires (twice) on removing the Thickbox iframe. Make sure we process only the main document unload.
56 if ( e.target && e.target.nodeName != '#document' )
64 action: 'wp-remove-post-lock',
65 _wpnonce: $('#_wpnonce').val(),
66 post_ID: $('#post_ID').val(),
67 active_post_lock: $('#active_post_lock').val()
73 $('#post-preview').click(function(){
74 if ( $('#auto_draft').val() == '1' && notSaved ) {
75 autosaveDelayPreview = true;
83 doPreview = function() {
84 $('input#wp-preview').val('dopreview');
85 $('form#post').attr('target', 'wp-preview').submit().attr('target', '');
88 * Workaround for WebKit bug preventing a form submitting twice to the same action.
89 * https://bugs.webkit.org/show_bug.cgi?id=28633
91 if ( $.browser.safari ) {
92 $('form#post').attr('action', function(index, value) {
93 return value + '?t=' + new Date().getTime();
97 $('input#wp-preview').val('');
100 // This code is meant to allow tabbing from Title to Post if tinyMCE is defined.
101 if ( typeof tinyMCE != 'undefined' ) {
102 $('#title')[$.browser.opera ? 'keypress' : 'keydown'](function (e) {
103 if ( e.which == 9 && !e.shiftKey && !e.controlKey && !e.altKey ) {
104 if ( ($('#auto_draft').val() == '1') && ($("#title").val().length > 0) ) { autosave(); }
105 if ( tinyMCE.activeEditor && ! tinyMCE.activeEditor.isHidden() && dotabkey ) {
108 tinyMCE.activeEditor.focus();
115 // autosave new posts after a title is typed but not if Publish or Save Draft is clicked
116 if ( '1' == $('#auto_draft').val() ) {
117 $('#title').blur( function() {
118 if ( !this.value || $('#auto_draft').val() != '1' )
125 function autosave_parse_response(response) {
126 var res = wpAjax.parseAjaxResponse(response, 'autosave'), message = '', postID, sup;
128 if ( res && res.responses && res.responses.length ) {
129 message = res.responses[0].data; // The saved message or error.
130 // someone else is editing: disable autosave, set errors
131 if ( res.responses[0].supplemental ) {
132 sup = res.responses[0].supplemental;
133 if ( 'disable' == sup['disable_autosave'] ) {
134 autosave = function() {};
135 autosaveLockRelease = false;
136 res = { errors: true };
139 if ( sup['active-post-lock'] ) {
140 jQuery('#active_post_lock').val( sup['active-post-lock'] );
143 if ( sup['alert'] ) {
144 jQuery('#autosave-alert').remove();
145 jQuery('#titlediv').after('<div id="autosave-alert" class="error below-h2"><p>' + sup['alert'] + '</p></div>');
148 jQuery.each(sup, function(selector, value) {
149 if ( selector.match(/^replace-/) ) {
150 jQuery('#'+selector.replace('replace-', '')).val(value);
155 // if no errors: add slug UI
157 postID = parseInt( res.responses[0].id, 10 );
158 if ( !isNaN(postID) && postID > 0 ) {
159 autosave_update_slug(postID);
163 if ( message ) { // update autosave message
164 jQuery('.autosave-message').html(message);
165 } else if ( autosaveOldMessage && res ) {
166 jQuery('.autosave-message').html( autosaveOldMessage );
171 // called when autosaving pre-existing post
172 function autosave_saved(response) {
174 autosave_parse_response(response); // parse the ajax response
175 autosave_enable_buttons(); // re-enable disabled form buttons
178 // called when autosaving new post
179 function autosave_saved_new(response) {
181 var res = autosave_parse_response(response), postID;
182 if ( res && res.responses.length && !res.errors ) {
183 // An ID is sent only for real auto-saves, not for autosave=0 "keepalive" saves
184 postID = parseInt( res.responses[0].id, 10 );
185 if ( !isNaN(postID) && postID > 0 ) {
187 jQuery('#auto_draft').val('0'); // No longer an auto-draft
189 autosave_enable_buttons();
190 if ( autosaveDelayPreview ) {
191 autosaveDelayPreview = false;
195 autosave_enable_buttons(); // re-enable disabled form buttons
199 function autosave_update_slug(post_id) {
200 // create slug area only if not already there
201 if ( 'undefined' != makeSlugeditClickable && jQuery.isFunction(makeSlugeditClickable) && !jQuery('#edit-slug-box > *').size() ) {
202 jQuery.post( ajaxurl, {
203 action: 'sample-permalink',
205 new_title: fullscreen && fullscreen.settings.visible ? jQuery('#wp-fullscreen-title').val() : jQuery('#title').val(),
206 samplepermalinknonce: jQuery('#samplepermalinknonce').val()
209 if ( data !== '-1' ) {
210 jQuery('#edit-slug-box').html(data);
211 makeSlugeditClickable();
218 function autosave_loading() {
219 jQuery('.autosave-message').html(autosaveL10n.savingText);
222 function autosave_enable_buttons() {
223 // delay that a bit to avoid some rare collisions while the DOM is being updated.
224 setTimeout(function(){
225 jQuery(':button, :submit', '#submitpost').removeAttr('disabled');
226 jQuery('.ajax-loading').css('visibility', 'hidden');
230 function autosave_disable_buttons() {
231 jQuery(':button, :submit', '#submitpost').prop('disabled', true);
232 // Re-enable 5 sec later. Just gives autosave a head start to avoid collisions.
233 setTimeout(autosave_enable_buttons, 5000);
236 function delayed_autosave() {
237 setTimeout(function(){
244 autosave = function() {
245 // (bool) is rich editor enabled and active
247 var rich = (typeof tinyMCE != "undefined") && tinyMCE.activeEditor && !tinyMCE.activeEditor.isHidden(),
248 post_data, doAutoSave, ed, origStatus, successCallback;
250 autosave_disable_buttons();
254 post_ID: jQuery("#post_ID").val() || 0,
255 autosavenonce: jQuery('#autosavenonce').val(),
256 post_type: jQuery('#post_type').val() || "",
260 jQuery('.tags-input').each( function() {
261 post_data[this.name] = this.value;
264 // We always send the ajax request in order to keep the post lock fresh.
265 // This (bool) tells whether or not to write the post to the DB during the ajax request.
268 // No autosave while thickbox is open (media buttons)
269 if ( jQuery("#TB_window").css('display') == 'block' )
272 /* Gotta do this up here so we can check the length when tinyMCE is in use */
273 if ( rich && doAutoSave ) {
274 ed = tinyMCE.activeEditor;
275 // Don't run while the TinyMCE spellcheck is on. It resets all found words.
276 if ( ed.plugins.spellchecker && ed.plugins.spellchecker.active ) {
279 if ( 'mce_fullscreen' == ed.id || 'wp_mce_fullscreen' == ed.id )
280 tinyMCE.get('content').setContent(ed.getContent({format : 'raw'}), {format : 'raw'});
281 tinyMCE.triggerSave();
285 if ( fullscreen && fullscreen.settings.visible ) {
286 post_data["post_title"] = jQuery('#wp-fullscreen-title').val() || '';
287 post_data["content"] = jQuery("#wp_mce_fullscreen").val() || '';
289 post_data["post_title"] = jQuery("#title").val() || '';
290 post_data["content"] = jQuery("#content").val() || '';
293 if ( jQuery('#post_name').val() )
294 post_data["post_name"] = jQuery('#post_name').val();
296 // Nothing to save or no change.
297 if ( ( post_data["post_title"].length == 0 && post_data["content"].length == 0 ) || post_data["post_title"] + post_data["content"] == autosaveLast ) {
301 origStatus = jQuery('#original_post_status').val();
304 jQuery("[name='post_category[]']:checked").each( function(i) {
305 goodcats.push(this.value);
307 post_data["catslist"] = goodcats.join(",");
309 if ( jQuery("#comment_status").prop("checked") )
310 post_data["comment_status"] = 'open';
311 if ( jQuery("#ping_status").prop("checked") )
312 post_data["ping_status"] = 'open';
313 if ( jQuery("#excerpt").size() )
314 post_data["excerpt"] = jQuery("#excerpt").val();
315 if ( jQuery("#post_author").size() )
316 post_data["post_author"] = jQuery("#post_author").val();
317 if ( jQuery("#parent_id").val() )
318 post_data["parent_id"] = jQuery("#parent_id").val();
319 post_data["user_ID"] = jQuery("#user-id").val();
320 if ( jQuery('#auto_draft').val() == '1' )
321 post_data["auto_draft"] = '1';
324 autosaveLast = post_data["post_title"] + post_data["content"];
325 jQuery(document).triggerHandler('wpcountwords', [ post_data["content"] ]);
327 post_data['autosave'] = 0;
330 if ( post_data["auto_draft"] == '1' ) {
331 successCallback = autosave_saved_new; // new post
333 successCallback = autosave_saved; // pre-existing post
336 autosaveOldMessage = jQuery('#autosave').html();
339 beforeSend: doAutoSave ? autosave_loading : null,
342 success: successCallback