wp/wp-includes/js/autosave.js
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
       
     1 /**
       
     2  * @output wp-includes/js/autosave.js
       
     3  */
       
     4 
     1 /* global tinymce, wpCookies, autosaveL10n, switchEditors */
     5 /* global tinymce, wpCookies, autosaveL10n, switchEditors */
     2 // Back-compat
     6 // Back-compat
     3 window.autosave = function() {
     7 window.autosave = function() {
     4 	return true;
     8 	return true;
     5 };
     9 };
     6 
    10 
     7 /**
    11 /**
     8  * @summary Adds autosave to the window object on dom ready.
    12  * Adds autosave to the window object on dom ready.
     9  *
    13  *
    10  * @since 3.9.0
    14  * @since 3.9.0
    11  *
    15  *
    12  * @param {jQuery} $ jQuery object.
    16  * @param {jQuery} $ jQuery object.
    13  * @param {window} The window object.
    17  * @param {window} The window object.
    14  *
    18  *
    15  */
    19  */
    16 ( function( $, window ) {
    20 ( function( $, window ) {
    17 	/**
    21 	/**
    18 	 * @summary Auto saves the post.
    22 	 * Auto saves the post.
    19 	 *
    23 	 *
    20 	 * @since 3.9.0
    24 	 * @since 3.9.0
    21 	 *
    25 	 *
    22 	 * @returns {Object}
    26 	 * @returns {Object}
    23 	 * 	{{
    27 	 * 	{{
    34 		var initialCompareString,
    38 		var initialCompareString,
    35 			lastTriggerSave = 0,
    39 			lastTriggerSave = 0,
    36 			$document = $(document);
    40 			$document = $(document);
    37 
    41 
    38 		/**
    42 		/**
    39 		 * @summary Returns the data saved in both local and remote autosave.
    43 		 * Returns the data saved in both local and remote autosave.
    40 		 *
    44 		 *
    41 		 * @since 3.9.0
    45 		 * @since 3.9.0
    42 		 *
    46 		 *
    43 		 * @param {string} type The type of autosave either local or remote.
    47 		 * @param {string} type The type of autosave either local or remote.
    44 		 *
    48 		 *
    97 
   101 
    98 			return data;
   102 			return data;
    99 		}
   103 		}
   100 
   104 
   101 		/**
   105 		/**
   102 		 * @summary Concatenates the title, content and excerpt.
   106 		 * Concatenates the title, content and excerpt. This is used to track changes
   103 		 *
   107 		 * when auto-saving.
   104 		 * This is used to track changes when auto-saving.
       
   105 		 *
   108 		 *
   106 		 * @since 3.9.0
   109 		 * @since 3.9.0
   107 		 *
   110 		 *
   108 		 * @param {Object} postData The object containing the post data.
   111 		 * @param {Object} postData The object containing the post data.
   109 		 *
   112 		 *
   116 
   119 
   117 			return ( $('#title').val() || '' ) + '::' + ( $('#content').val() || '' ) + '::' + ( $('#excerpt').val() || '' );
   120 			return ( $('#title').val() || '' ) + '::' + ( $('#content').val() || '' ) + '::' + ( $('#excerpt').val() || '' );
   118 		}
   121 		}
   119 
   122 
   120 		/**
   123 		/**
   121 		 * @summary Disables save buttons.
   124 		 * Disables save buttons.
   122 		 *
   125 		 *
   123 		 * @since 3.9.0
   126 		 * @since 3.9.0
   124 		 *
   127 		 *
   125 		 * @returns {void}
   128 		 * @returns {void}
   126 		 */
   129 		 */
   130 			// Re-enable 5 sec later. Just gives autosave a head start to avoid collisions.
   133 			// Re-enable 5 sec later. Just gives autosave a head start to avoid collisions.
   131 			setTimeout( enableButtons, 5000 );
   134 			setTimeout( enableButtons, 5000 );
   132 		}
   135 		}
   133 
   136 
   134 		/**
   137 		/**
   135 		 * @summary Enables save buttons.
   138 		 * Enables save buttons.
   136 		 *
   139 		 *
   137 		 * @since 3.9.0
   140 		 * @since 3.9.0
   138 		 *
   141 		 *
   139 		 * @returns {void}
   142 		 * @returns {void}
   140 		 */
   143 		 */
   141 		function enableButtons() {
   144 		function enableButtons() {
   142 			$document.trigger( 'autosave-enable-buttons' );
   145 			$document.trigger( 'autosave-enable-buttons' );
   143 		}
   146 		}
   144 
   147 
   145 		/**
   148 		/**
   146 		 * @summary Gets the content editor.
   149 		 * Gets the content editor.
   147 		 *
   150 		 *
   148 		 * @since 4.6.0
   151 		 * @since 4.6.0
   149 		 *
   152 		 *
   150 		 * @returns {boolean|*} Returns either false if the editor is undefined,
   153 		 * @returns {boolean|*} Returns either false if the editor is undefined,
   151 		 * 						or the instance of the content editor.
   154 		 * 						or the instance of the content editor.
   153 		function getEditor() {
   156 		function getEditor() {
   154 			return typeof tinymce !== 'undefined' && tinymce.get('content');
   157 			return typeof tinymce !== 'undefined' && tinymce.get('content');
   155 		}
   158 		}
   156 
   159 
   157 		/**
   160 		/**
   158 		 * @summary Autosave in localStorage.
   161 		 * Autosave in localStorage.
   159 		 *
   162 		 *
   160 		 * @since 3.9.0
   163 		 * @since 3.9.0
   161 		 *
   164 		 *
   162 		 * @returns {
   165 		 * @returns {
   163 		 * {
   166 		 * {
   174 			var blog_id, post_id, hasStorage, intervalTimer,
   177 			var blog_id, post_id, hasStorage, intervalTimer,
   175 				lastCompareString,
   178 				lastCompareString,
   176 				isSuspended = false;
   179 				isSuspended = false;
   177 
   180 
   178 			/**
   181 			/**
   179 			 * @summary Checks if the browser supports sessionStorage and it's not disabled.
   182 			 * Checks if the browser supports sessionStorage and it's not disabled.
   180 			 *
   183 			 *
   181 			 * @since 3.9.0
   184 			 * @since 3.9.0
   182 			 *
   185 			 *
   183 			 * @returns {boolean} True if the sessionStorage is supported and enabled.
   186 			 * @returns {boolean} True if the sessionStorage is supported and enabled.
   184 			 */
   187 			 */
   195 				hasStorage = result;
   198 				hasStorage = result;
   196 				return result;
   199 				return result;
   197 			}
   200 			}
   198 
   201 
   199 			/**
   202 			/**
   200 			 * @summary Initializes the local storage.
   203 			 * Initializes the local storage.
   201 			 *
   204 			 *
   202 			 * @since 3.9.0
   205 			 * @since 3.9.0
   203 			 *
   206 			 *
   204 			 * @returns {boolean|Object} False if no sessionStorage in the browser or an Object
   207 			 * @returns {boolean|Object} False if no sessionStorage in the browser or an Object
   205 			 *                           containing all postData for this blog.
   208 			 *                           containing all postData for this blog.
   219 
   222 
   220 				return stored_obj;
   223 				return stored_obj;
   221 			}
   224 			}
   222 
   225 
   223 			/**
   226 			/**
   224 			 * @summary Sets the storage for this blog.
   227 			 * Sets the storage for this blog. Confirms that the data was saved
   225 			 *
   228 			 * successfully.
   226 			 * Confirms that the data was saved successfully.
       
   227 			 *
   229 			 *
   228 			 * @since 3.9.0
   230 			 * @since 3.9.0
   229 			 *
   231 			 *
   230 			 * @returns {boolean} True if the data was saved successfully, false if it wasn't saved.
   232 			 * @returns {boolean} True if the data was saved successfully, false if it wasn't saved.
   231 			 */
   233 			 */
   240 
   242 
   241 				return false;
   243 				return false;
   242 			}
   244 			}
   243 
   245 
   244 			/**
   246 			/**
   245 			 * @summary Gets the saved post data for the current post.
   247 			 * Gets the saved post data for the current post.
   246 			 *
   248 			 *
   247 			 * @since 3.9.0
   249 			 * @since 3.9.0
   248 			 *
   250 			 *
   249 			 * @returns {boolean|Object} False if no storage or no data or the postData as an Object.
   251 			 * @returns {boolean|Object} False if no storage or no data or the postData as an Object.
   250 			 */
   252 			 */
   257 
   259 
   258 				return stored[ 'post_' + post_id ] || false;
   260 				return stored[ 'post_' + post_id ] || false;
   259 			}
   261 			}
   260 
   262 
   261 			/**
   263 			/**
   262 			 * @summary Sets (save or delete) post data in the storage.
   264 			 * Sets (save or delete) post data in the storage.
   263 			 *
   265 			 *
   264 			 * If stored_data evaluates to 'false' the storage key for the current post will be removed.
   266 			 * If stored_data evaluates to 'false' the storage key for the current post will be removed.
   265 			 *
   267 			 *
   266 			 * @since 3.9.0
   268 			 * @since 3.9.0
   267 			 *
   269 			 *
   286 
   288 
   287 				return setStorage( stored );
   289 				return setStorage( stored );
   288 			}
   290 			}
   289 
   291 
   290 			/**
   292 			/**
   291 			 * @summary Sets isSuspended to true.
   293 			 * Sets isSuspended to true.
   292 			 *
   294 			 *
   293 			 * @since 3.9.0
   295 			 * @since 3.9.0
   294 			 *
   296 			 *
   295 			 * @returns {void}
   297 			 * @returns {void}
   296 			 */
   298 			 */
   297 			function suspend() {
   299 			function suspend() {
   298 				isSuspended = true;
   300 				isSuspended = true;
   299 			}
   301 			}
   300 
   302 
   301 			/**
   303 			/**
   302 			 * @summary Sets isSuspended to false.
   304 			 * Sets isSuspended to false.
   303 			 *
   305 			 *
   304 			 * @since 3.9.0
   306 			 * @since 3.9.0
   305 			 *
   307 			 *
   306 			 * @returns {void}
   308 			 * @returns {void}
   307 			 */
   309 			 */
   308 			function resume() {
   310 			function resume() {
   309 				isSuspended = false;
   311 				isSuspended = false;
   310 			}
   312 			}
   311 
   313 
   312 			/**
   314 			/**
   313 			 * @summary Saves post data for the current post.
   315 			 * Saves post data for the current post.
   314 			 *
   316 			 *
   315 			 * Runs on a 15 sec. interval, saves when there are differences in the post title or content.
   317 			 * Runs on a 15 sec. interval, saves when there are differences in the post title or content.
   316 			 * When the optional data is provided, updates the last saved post data.
   318 			 * When the optional data is provided, updates the last saved post data.
   317 			 *
   319 			 *
   318 			 * @since 3.9.0
   320 			 * @since 3.9.0
   357 
   359 
   358 				return result;
   360 				return result;
   359 			}
   361 			}
   360 
   362 
   361 			/**
   363 			/**
   362 			 * @summary Initializes the auto save function.
   364 			 * Initializes the auto save function.
   363 			 *
   365 			 *
   364 			 * Checks whether the editor is active or not to use the editor events
   366 			 * Checks whether the editor is active or not to use the editor events
   365 			 * to autosave, or uses the values from the elements to autosave.
   367 			 * to autosave, or uses the values from the elements to autosave.
   366 			 *
   368 			 *
   367 			 * Runs on DOM ready.
   369 			 * Runs on DOM ready.
   417 					wpCookies.set( 'wp-saving-post', post_id + '-check', 24 * 60 * 60, false, false, secure );
   419 					wpCookies.set( 'wp-saving-post', post_id + '-check', 24 * 60 * 60, false, false, secure );
   418 				});
   420 				});
   419 			}
   421 			}
   420 
   422 
   421 			/**
   423 			/**
   422 			 * @summary Compares 2 strings.
   424 			 * Compares 2 strings. Removes whitespaces in the strings before comparing them.
   423 			 *
       
   424 			 * Removes whitespaces in the strings before comparing them.
       
   425 			 *
   425 			 *
   426 			 * @since 3.9.0
   426 			 * @since 3.9.0
   427 			 *
   427 			 *
   428 			 * @param {string} str1 The first string.
   428 			 * @param {string} str1 The first string.
   429 			 * @param {string} str2 The second string.
   429 			 * @param {string} str2 The second string.
   436 
   436 
   437 				return ( removeSpaces( str1 || '' ) === removeSpaces( str2 || '' ) );
   437 				return ( removeSpaces( str1 || '' ) === removeSpaces( str2 || '' ) );
   438 			}
   438 			}
   439 
   439 
   440 			/**
   440 			/**
   441 			 * @summary Checks if the saved data for the current post (if any) is different
   441 			 * Checks if the saved data for the current post (if any) is different than the
   442 			 * than the loaded post data on the screen.
   442 			 * loaded post data on the screen.
   443 			 *
   443 			 *
   444 			 * Shows a standard message letting the user restore the post data if different.
   444 			 * Shows a standard message letting the user restore the post data if different.
   445 			 *
   445 			 *
   446 			 * @since 3.9.0
   446 			 * @since 3.9.0
   447 			 *
   447 			 *
   505 					});
   505 					});
   506 				});
   506 				});
   507 			}
   507 			}
   508 
   508 
   509 			/**
   509 			/**
   510 			 * @summary Restores the current title, content and excerpt from postData.
   510 			 * Restores the current title, content and excerpt from postData.
   511 			 *
   511 			 *
   512 			 * @since 3.9.0
   512 			 * @since 3.9.0
   513 			 *
   513 			 *
   514 			 * @param {Object} postData The object containing all post data.
   514 			 * @param {Object} postData The object containing all post data.
   515 			 *
   515 			 *
   573 				resume: resume
   573 				resume: resume
   574 			};
   574 			};
   575 		}
   575 		}
   576 
   576 
   577 		/**
   577 		/**
   578 		 * @summary Auto saves the post on the server.
   578 		 * Auto saves the post on the server.
   579 		 *
   579 		 *
   580 		 * @since 3.9.0
   580 		 * @since 3.9.0
   581 		 *
   581 		 *
   582 		 * @returns {Object} {
   582 		 * @returns {Object} {
   583 		 * 	{
   583 		 * 	{
   594 				nextRun = 0,
   594 				nextRun = 0,
   595 				isSuspended = false;
   595 				isSuspended = false;
   596 
   596 
   597 
   597 
   598 			/**
   598 			/**
   599 			 * @summary  Blocks saving for the next 10 seconds.
   599 			 * Blocks saving for the next 10 seconds.
   600 			 *
   600 			 *
   601 			 * @since 3.9.0
   601 			 * @since 3.9.0
   602 			 *
   602 			 *
   603 			 * @returns {void}
   603 			 * @returns {void}
   604 			 */
   604 			 */
   610 					_blockSave = false;
   610 					_blockSave = false;
   611 				}, 10000 );
   611 				}, 10000 );
   612 			}
   612 			}
   613 
   613 
   614 			/**
   614 			/**
   615 			 * @summary Sets isSuspended to true.
   615 			 * Sets isSuspended to true.
   616 			 *
   616 			 *
   617 			 * @since 3.9.0
   617 			 * @since 3.9.0
   618 			 *
   618 			 *
   619 			 * @returns {void}
   619 			 * @returns {void}
   620 			 */
   620 			 */
   621 			function suspend() {
   621 			function suspend() {
   622 				isSuspended = true;
   622 				isSuspended = true;
   623 			}
   623 			}
   624 
   624 
   625 			/**
   625 			/**
   626 			 * @summary Sets isSuspended to false.
   626 			 * Sets isSuspended to false.
   627 			 *
   627 			 *
   628 			 * @since 3.9.0
   628 			 * @since 3.9.0
   629 			 *
   629 			 *
   630 			 * @returns {void}
   630 			 * @returns {void}
   631 			 */
   631 			 */
   632 			function resume() {
   632 			function resume() {
   633 				isSuspended = false;
   633 				isSuspended = false;
   634 			}
   634 			}
   635 
   635 
   636 			/**
   636 			/**
   637 			 * @summary Triggers the autosave with the post data.
   637 			 * Triggers the autosave with the post data.
   638 			 *
   638 			 *
   639 			 * @since 3.9.0
   639 			 * @since 3.9.0
   640 			 *
   640 			 *
   641 			 * @param {Object} data The post data.
   641 			 * @param {Object} data The post data.
   642 			 *
   642 			 *
   656 					$( '#auto_draft' ).val('');
   656 					$( '#auto_draft' ).val('');
   657 				}
   657 				}
   658 			}
   658 			}
   659 
   659 
   660 			/**
   660 			/**
   661 			 * @summary Saves immediately.
   661 			 * Saves immediately.
   662 			 *
   662 			 *
   663 			 * Resets the timing and tells heartbeat to connect now.
   663 			 * Resets the timing and tells heartbeat to connect now.
   664 			 *
   664 			 *
   665 			 * @since 3.9.0
   665 			 * @since 3.9.0
   666 			 *
   666 			 *
   670 				nextRun = 0;
   670 				nextRun = 0;
   671 				wp.heartbeat.connectNow();
   671 				wp.heartbeat.connectNow();
   672 			}
   672 			}
   673 
   673 
   674 			/**
   674 			/**
   675 			 * @summary Checks if the post content in the textarea has changed since page load.
   675 			 * Checks if the post content in the textarea has changed since page load.
   676 			 *
   676 			 *
   677 			 * This also happens when TinyMCE is active and editor.save() is triggered by
   677 			 * This also happens when TinyMCE is active and editor.save() is triggered by
   678 			 * wp.autosave.getPostData().
   678 			 * wp.autosave.getPostData().
   679 			 *
   679 			 *
   680 			 * @since 3.9.0
   680 			 * @since 3.9.0
   684 			function postChanged() {
   684 			function postChanged() {
   685 				return getCompareString() !== initialCompareString;
   685 				return getCompareString() !== initialCompareString;
   686 			}
   686 			}
   687 
   687 
   688 			/**
   688 			/**
   689 			 * @summary Checks if the post can be saved or not.
   689 			 * Checks if the post can be saved or not.
   690 			 *
   690 			 *
   691 			 * If the post hasn't changed or it cannot be updated,
   691 			 * If the post hasn't changed or it cannot be updated,
   692 			 * because the autosave is blocked or suspended, the function returns false.
   692 			 * because the autosave is blocked or suspended, the function returns false.
   693 			 *
   693 			 *
   694 			 * @since 3.9.0
   694 			 * @since 3.9.0
   731 
   731 
   732 				return postData;
   732 				return postData;
   733 			}
   733 			}
   734 
   734 
   735 			/**
   735 			/**
   736 			 * @summary Sets the next run, based on the autosave interval.
   736 			 * Sets the next run, based on the autosave interval.
   737 			 *
   737 			 *
   738 			 * @private
   738 			 * @private
   739 			 *
   739 			 *
   740 			 * @since 3.9.0
   740 			 * @since 3.9.0
   741 			 *
   741 			 *
   744 			function _schedule() {
   744 			function _schedule() {
   745 				nextRun = ( new Date() ).getTime() + ( autosaveL10n.autosaveInterval * 1000 ) || 60000;
   745 				nextRun = ( new Date() ).getTime() + ( autosaveL10n.autosaveInterval * 1000 ) || 60000;
   746 			}
   746 			}
   747 
   747 
   748 			/**
   748 			/**
   749 			 * @summary Sets the autosaveData on the autosave heartbeat.
   749 			 * Sets the autosaveData on the autosave heartbeat.
   750 			 *
   750 			 *
   751 			 * @since 3.9.0
   751 			 * @since 3.9.0
   752 			 *
   752 			 *
   753 			 * @returns {void}
   753 			 * @returns {void}
   754 			 */
   754 			 */
   758 				if ( autosaveData ) {
   758 				if ( autosaveData ) {
   759 					data.wp_autosave = autosaveData;
   759 					data.wp_autosave = autosaveData;
   760 				}
   760 				}
   761 
   761 
   762 				/**
   762 				/**
   763 				 * @summary Triggers the autosave of the post with the autosave data
   763 				 * Triggers the autosave of the post with the autosave data on the autosave
   764 				 * on the autosave heartbeat.
   764 				 * heartbeat.
   765 				 *
   765 				 *
   766 				 * @since 3.9.0
   766 				 * @since 3.9.0
   767 				 *
   767 				 *
   768 				 * @returns {void}
   768 				 * @returns {void}
   769 				 */
   769 				 */
   770 			}).on( 'heartbeat-tick.autosave', function( event, data ) {
   770 			}).on( 'heartbeat-tick.autosave', function( event, data ) {
   771 				if ( data.wp_autosave ) {
   771 				if ( data.wp_autosave ) {
   772 					response( data.wp_autosave );
   772 					response( data.wp_autosave );
   773 				}
   773 				}
   774 				/**
   774 				/**
   775 				 * @summary Disables buttons and throws a notice when the connection is lost.
   775 				 * Disables buttons and throws a notice when the connection is lost.
   776 				 *
   776 				 *
   777 				 * @since 3.9.0
   777 				 * @since 3.9.0
   778 				 *
   778 				 *
   779 				 * @returns {void}
   779 				 * @returns {void}
   780 				 */
   780 				 */
   791 					$notice.show();
   791 					$notice.show();
   792 					disableButtons();
   792 					disableButtons();
   793 				}
   793 				}
   794 
   794 
   795 				/**
   795 				/**
   796 				 * @summary Enables buttons when the connection is restored.
   796 				 * Enables buttons when the connection is restored.
   797 				 *
   797 				 *
   798 				 * @since 3.9.0
   798 				 * @since 3.9.0
   799 				 *
   799 				 *
   800 				 * @returns {void}
   800 				 * @returns {void}
   801 				 */
   801 				 */
   814 				resume: resume
   814 				resume: resume
   815 			};
   815 			};
   816 		}
   816 		}
   817 
   817 
   818 		/**
   818 		/**
   819 		 * @summary Sets the autosave time out.
   819 		 * Sets the autosave time out.
   820 		 *
   820 		 *
   821 		 * Wait for TinyMCE to initialize plus 1 second. for any external css to finish loading,
   821 		 * Wait for TinyMCE to initialize plus 1 second. for any external css to finish loading,
   822 		 * then save to the textarea before setting initialCompareString.
   822 		 * then save to the textarea before setting initialCompareString.
   823 		 * This avoids any insignificant differences between the initial textarea content and the content
   823 		 * This avoids any insignificant differences between the initial textarea content and the content
   824 		 * extracted from the editor.
   824 		 * extracted from the editor.