]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/js/autosave.js
Wordpress 3.5
[autoinstalls/wordpress.git] / wp-includes / js / autosave.js
1 var autosave, autosaveLast = '', autosavePeriodical, autosaveOldMessage = '', autosaveDelayPreview = false, notSaved = true, blockSave = false, fullscreen, autosaveLockRelease = true;
2
3 jQuery(document).ready( function($) {
4
5         autosaveLast = ( $('#post #title').val() || '' ) + ( $('#post #content').val() || '' );
6         autosavePeriodical = $.schedule({time: autosaveL10n.autosaveInterval * 1000, func: function() { autosave(); }, repeat: true, protect: true});
7
8         //Disable autosave after the form has been submitted
9         $("#post").submit(function() {
10                 $.cancel(autosavePeriodical);
11                 autosaveLockRelease = false;
12         });
13
14         $('input[type="submit"], a.submitdelete', '#submitpost').click(function(){
15                 blockSave = true;
16                 window.onbeforeunload = null;
17                 $(':button, :submit', '#submitpost').each(function(){
18                         var t = $(this);
19                         if ( t.hasClass('button-primary') )
20                                 t.addClass('button-primary-disabled');
21                         else
22                                 t.addClass('button-disabled');
23                 });
24                 if ( $(this).attr('id') == 'publish' )
25                         $('#major-publishing-actions .spinner').show();
26                 else
27                         $('#minor-publishing .spinner').show();
28         });
29
30         window.onbeforeunload = function(){
31                 var mce = typeof(tinymce) != 'undefined' ? tinymce.activeEditor : false, title, content;
32
33                 if ( mce && !mce.isHidden() ) {
34                         if ( mce.isDirty() )
35                                 return autosaveL10n.saveAlert;
36                 } else {
37                         if ( fullscreen && fullscreen.settings.visible ) {
38                                 title = $('#wp-fullscreen-title').val() || '';
39                                 content = $("#wp_mce_fullscreen").val() || '';
40                         } else {
41                                 title = $('#post #title').val() || '';
42                                 content = $('#post #content').val() || '';
43                         }
44
45                         if ( ( title || content ) && title + content != autosaveLast )
46                                 return autosaveL10n.saveAlert;
47                 }
48         };
49
50         $(window).unload( function(e) {
51                 if ( ! autosaveLockRelease )
52                         return;
53
54                 // unload fires (twice) on removing the Thickbox iframe. Make sure we process only the main document unload.
55                 if ( e.target && e.target.nodeName != '#document' )
56                         return;
57
58                 $.ajax({
59                         type: 'POST',
60                         url: ajaxurl,
61                         async: false,
62                         data: {
63                                 action: 'wp-remove-post-lock',
64                                 _wpnonce: $('#_wpnonce').val(),
65                                 post_ID: $('#post_ID').val(),
66                                 active_post_lock: $('#active_post_lock').val()
67                         }
68                 });
69         } );
70
71         // preview
72         $('#post-preview').click(function(){
73                 if ( $('#auto_draft').val() == '1' && notSaved ) {
74                         autosaveDelayPreview = true;
75                         autosave();
76                         return false;
77                 }
78                 doPreview();
79                 return false;
80         });
81
82         doPreview = function() {
83                 $('input#wp-preview').val('dopreview');
84                 $('form#post').attr('target', 'wp-preview').submit().attr('target', '');
85
86                 /*
87                  * Workaround for WebKit bug preventing a form submitting twice to the same action.
88                  * https://bugs.webkit.org/show_bug.cgi?id=28633
89                  */
90                 if ( $.browser.safari ) {
91                         $('form#post').attr('action', function(index, value) {
92                                 return value + '?t=' + new Date().getTime();
93                         });
94                 }
95
96                 $('input#wp-preview').val('');
97         }
98
99         // This code is meant to allow tabbing from Title to Post content.
100         $('#title').on('keydown.editor-focus', function(e) {
101                 var ed;
102
103                 if ( e.which != 9 )
104                         return;
105
106                 if ( !e.ctrlKey && !e.altKey && !e.shiftKey ) {
107                         if ( typeof(tinymce) != 'undefined' )
108                                 ed = tinymce.get('content');
109
110                         if ( ed && !ed.isHidden() ) {
111                                 $(this).one('keyup', function(e){
112                                         $('#content_tbl td.mceToolbar > a').focus();
113                                 });
114                         } else {
115                                 $('#content').focus();
116                         }
117
118                         e.preventDefault();
119                 }
120         });
121
122         // autosave new posts after a title is typed but not if Publish or Save Draft is clicked
123         if ( '1' == $('#auto_draft').val() ) {
124                 $('#title').blur( function() {
125                         if ( !this.value || $('#auto_draft').val() != '1' )
126                                 return;
127                         delayed_autosave();
128                 });
129         }
130 });
131
132 function autosave_parse_response(response) {
133         var res = wpAjax.parseAjaxResponse(response, 'autosave'), message = '', postID, sup;
134
135         if ( res && res.responses && res.responses.length ) {
136                 message = res.responses[0].data; // The saved message or error.
137                 // someone else is editing: disable autosave, set errors
138                 if ( res.responses[0].supplemental ) {
139                         sup = res.responses[0].supplemental;
140                         if ( 'disable' == sup['disable_autosave'] ) {
141                                 autosave = function() {};
142                                 autosaveLockRelease = false;
143                                 res = { errors: true };
144                         }
145
146                         if ( sup['active-post-lock'] ) {
147                                 jQuery('#active_post_lock').val( sup['active-post-lock'] );
148                         }
149
150                         if ( sup['alert'] ) {
151                                 jQuery('#autosave-alert').remove();
152                                 jQuery('#titlediv').after('<div id="autosave-alert" class="error below-h2"><p>' + sup['alert'] + '</p></div>');
153                         }
154
155                         jQuery.each(sup, function(selector, value) {
156                                 if ( selector.match(/^replace-/) ) {
157                                         jQuery('#'+selector.replace('replace-', '')).val(value);
158                                 }
159                         });
160                 }
161
162                 // if no errors: add slug UI
163                 if ( !res.errors ) {
164                         postID = parseInt( res.responses[0].id, 10 );
165                         if ( !isNaN(postID) && postID > 0 ) {
166                                 autosave_update_slug(postID);
167                         }
168                 }
169         }
170         if ( message ) { // update autosave message
171                 jQuery('.autosave-message').html(message);
172         } else if ( autosaveOldMessage && res ) {
173                 jQuery('.autosave-message').html( autosaveOldMessage );
174         }
175         return res;
176 }
177
178 // called when autosaving pre-existing post
179 function autosave_saved(response) {
180         blockSave = false;
181         autosave_parse_response(response); // parse the ajax response
182         autosave_enable_buttons(); // re-enable disabled form buttons
183 }
184
185 // called when autosaving new post
186 function autosave_saved_new(response) {
187         blockSave = false;
188         var res = autosave_parse_response(response), postID;
189         if ( res && res.responses.length && !res.errors ) {
190                 // An ID is sent only for real auto-saves, not for autosave=0 "keepalive" saves
191                 postID = parseInt( res.responses[0].id, 10 );
192                 if ( !isNaN(postID) && postID > 0 ) {
193                         notSaved = false;
194                         jQuery('#auto_draft').val('0'); // No longer an auto-draft
195                 }
196                 autosave_enable_buttons();
197                 if ( autosaveDelayPreview ) {
198                         autosaveDelayPreview = false;
199                         doPreview();
200                 }
201         } else {
202                 autosave_enable_buttons(); // re-enable disabled form buttons
203         }
204 }
205
206 function autosave_update_slug(post_id) {
207         // create slug area only if not already there
208         if ( 'undefined' != makeSlugeditClickable && jQuery.isFunction(makeSlugeditClickable) && !jQuery('#edit-slug-box > *').size() ) {
209                 jQuery.post( ajaxurl, {
210                                 action: 'sample-permalink',
211                                 post_id: post_id,
212                                 new_title: fullscreen && fullscreen.settings.visible ? jQuery('#wp-fullscreen-title').val() : jQuery('#title').val(),
213                                 samplepermalinknonce: jQuery('#samplepermalinknonce').val()
214                         },
215                         function(data) {
216                                 if ( data !== '-1' ) {
217                                         jQuery('#edit-slug-box').html(data);
218                                         makeSlugeditClickable();
219                                 }
220                         }
221                 );
222         }
223 }
224
225 function autosave_loading() {
226         jQuery('.autosave-message').html(autosaveL10n.savingText);
227 }
228
229 function autosave_enable_buttons() {
230         // delay that a bit to avoid some rare collisions while the DOM is being updated.
231         setTimeout(function(){
232                 jQuery(':button, :submit', '#submitpost').removeAttr('disabled');
233                 jQuery('.spinner', '#submitpost').hide();
234         }, 500);
235 }
236
237 function autosave_disable_buttons() {
238         jQuery(':button, :submit', '#submitpost').prop('disabled', true);
239         // Re-enable 5 sec later. Just gives autosave a head start to avoid collisions.
240         setTimeout(autosave_enable_buttons, 5000);
241 }
242
243 function delayed_autosave() {
244         setTimeout(function(){
245                 if ( blockSave )
246                         return;
247                 autosave();
248         }, 200);
249 }
250
251 autosave = function() {
252         // (bool) is rich editor enabled and active
253         blockSave = true;
254         var rich = (typeof tinymce != "undefined") && tinymce.activeEditor && !tinymce.activeEditor.isHidden(),
255                 post_data, doAutoSave, ed, origStatus, successCallback;
256
257         autosave_disable_buttons();
258
259         post_data = {
260                 action: "autosave",
261                 post_ID:  jQuery("#post_ID").val() || 0,
262                 autosavenonce: jQuery('#autosavenonce').val(),
263                 post_type: jQuery('#post_type').val() || "",
264                 autosave: 1
265         };
266
267         jQuery('.tags-input').each( function() {
268                 post_data[this.name] = this.value;
269         } );
270
271         // We always send the ajax request in order to keep the post lock fresh.
272         // This (bool) tells whether or not to write the post to the DB during the ajax request.
273         doAutoSave = true;
274
275         // No autosave while thickbox is open (media buttons)
276         if ( jQuery("#TB_window").css('display') == 'block' )
277                 doAutoSave = false;
278
279         /* Gotta do this up here so we can check the length when tinymce is in use */
280         if ( rich && doAutoSave ) {
281                 ed = tinymce.activeEditor;
282                 // Don't run while the tinymce spellcheck is on. It resets all found words.
283                 if ( ed.plugins.spellchecker && ed.plugins.spellchecker.active ) {
284                         doAutoSave = false;
285                 } else {
286                         if ( 'mce_fullscreen' == ed.id || 'wp_mce_fullscreen' == ed.id )
287                                 tinymce.get('content').setContent(ed.getContent({format : 'raw'}), {format : 'raw'});
288                         tinymce.triggerSave();
289                 }
290         }
291
292         if ( fullscreen && fullscreen.settings.visible ) {
293                 post_data["post_title"] = jQuery('#wp-fullscreen-title').val() || '';
294                 post_data["content"] = jQuery("#wp_mce_fullscreen").val() || '';
295         } else {
296                 post_data["post_title"] = jQuery("#title").val() || '';
297                 post_data["content"] = jQuery("#content").val() || '';
298         }
299
300         if ( jQuery('#post_name').val() )
301                 post_data["post_name"] = jQuery('#post_name').val();
302
303         // Nothing to save or no change.
304         if ( ( post_data["post_title"].length == 0 && post_data["content"].length == 0 ) || post_data["post_title"] + post_data["content"] == autosaveLast ) {
305                 doAutoSave = false;
306         }
307
308         origStatus = jQuery('#original_post_status').val();
309
310         goodcats = ([]);
311         jQuery("[name='post_category[]']:checked").each( function(i) {
312                 goodcats.push(this.value);
313         } );
314         post_data["catslist"] = goodcats.join(",");
315
316         if ( jQuery("#comment_status").prop("checked") )
317                 post_data["comment_status"] = 'open';
318         if ( jQuery("#ping_status").prop("checked") )
319                 post_data["ping_status"] = 'open';
320         if ( jQuery("#excerpt").size() )
321                 post_data["excerpt"] = jQuery("#excerpt").val();
322         if ( jQuery("#post_author").size() )
323                 post_data["post_author"] = jQuery("#post_author").val();
324         if ( jQuery("#parent_id").val() )
325                 post_data["parent_id"] = jQuery("#parent_id").val();
326         post_data["user_ID"] = jQuery("#user-id").val();
327         if ( jQuery('#auto_draft').val() == '1' )
328                 post_data["auto_draft"] = '1';
329
330         if ( doAutoSave ) {
331                 autosaveLast = post_data["post_title"] + post_data["content"];
332                 jQuery(document).triggerHandler('wpcountwords', [ post_data["content"] ]);
333         } else {
334                 post_data['autosave'] = 0;
335         }
336
337         if ( post_data["auto_draft"] == '1' ) {
338                 successCallback = autosave_saved_new; // new post
339         } else {
340                 successCallback = autosave_saved; // pre-existing post
341         }
342
343         autosaveOldMessage = jQuery('#autosave').html();
344         jQuery.ajax({
345                 data: post_data,
346                 beforeSend: doAutoSave ? autosave_loading : null,
347                 type: "POST",
348                 url: ajaxurl,
349                 success: successCallback
350         });
351 }