<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[41265] trunk/src/wp-includes/js/autosave.js: Docs: Improve JavaScript documentation in autosave.js.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/41265">41265</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/41265","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>adamsilverstein</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2017-08-18 14:23:06 +0000 (Fri, 18 Aug 2017)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Docs: Improve JavaScript documentation in autosave.js.
Add and improve JSDOC blocks.
Props carolinegeven.
Fixes <a href="https://core.trac.wordpress.org/ticket/41203">#41203</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesjsautosavejs">trunk/src/wp-includes/js/autosave.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesjsautosavejs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/js/autosave.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/autosave.js 2017-08-18 13:09:45 UTC (rev 41264)
+++ trunk/src/wp-includes/js/autosave.js 2017-08-18 14:23:06 UTC (rev 41265)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4,16 +4,45 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> };
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * @summary Adds autosave to the window object on dom ready.
+ *
+ * @since 3.9.0
+ *
+ * @param {jQuery} $ jQuery object.
+ * @param {window} The window object.
+ *
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> ( function( $, window ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Auto saves the post.
+ *
+ * @since 3.9.0
+ *
+ * @returns {Object}
+ * {{
+ * getPostData: getPostData,
+ * getCompareString: getCompareString,
+ * disableButtons: disableButtons,
+ * enableButtons: enableButtons,
+ * local: ({hasStorage, getSavedPostData, save, suspend, resume}|*),
+ * server: ({tempBlockSave, triggerSave, postChanged, suspend, resume}|*)}
+ * }
+ * The object with all functions for autosave.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function autosave() {
</span><span class="cx" style="display: block; padding: 0 10px"> var initialCompareString,
</span><span class="cx" style="display: block; padding: 0 10px"> lastTriggerSave = 0,
</span><span class="cx" style="display: block; padding: 0 10px"> $document = $(document);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Returns the data saved in both local and remote autosave
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @summary Returns the data saved in both local and remote autosave.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return object Object containing the post data
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 3.9.0
+ *
+ * @param {string} type The type of autosave either local or remote.
+ *
+ * @returns {Object} Object containing the post data.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function getPostData( type ) {
</span><span class="cx" style="display: block; padding: 0 10px"> var post_name, parent_id, data,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -21,7 +50,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> cats = [],
</span><span class="cx" style="display: block; padding: 0 10px"> editor = getEditor();
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Don't run editor.save() more often than every 3 sec.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Don't run editor.save() more often than every 3 seconds.
</ins><span class="cx" style="display: block; padding: 0 10px"> // It is resource intensive and might slow down typing in long posts on slow devices.
</span><span class="cx" style="display: block; padding: 0 10px"> if ( editor && editor.isDirty() && ! editor.isHidden() && time - 3000 > lastTriggerSave ) {
</span><span class="cx" style="display: block; padding: 0 10px"> editor.save();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -69,7 +98,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return data;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Concatenate title, content and excerpt. Used to track changes when auto-saving.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Concatenates the title, content and excerpt.
+ *
+ * This is used to track changes when auto-saving.
+ *
+ * @since 3.9.0
+ *
+ * @param {Object} postData The object containing the post data.
+ *
+ * @returns {string} A concatenated string with title, content and excerpt.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function getCompareString( postData ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( typeof postData === 'object' ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return ( postData.post_title || '' ) + '::' + ( postData.content || '' ) + '::' + ( postData.excerpt || '' );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -78,27 +117,71 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return ( $('#title').val() || '' ) + '::' + ( $('#content').val() || '' ) + '::' + ( $('#excerpt').val() || '' );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Disables save buttons.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function disableButtons() {
</span><span class="cx" style="display: block; padding: 0 10px"> $document.trigger('autosave-disable-buttons');
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Re-enable 5 sec later. Just gives autosave a head start to avoid collisions.
</span><span class="cx" style="display: block; padding: 0 10px"> setTimeout( enableButtons, 5000 );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Enables save buttons.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function enableButtons() {
</span><span class="cx" style="display: block; padding: 0 10px"> $document.trigger( 'autosave-enable-buttons' );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Gets the content editor.
+ *
+ * @since 4.6.0
+ *
+ * @returns {boolean|*} Returns either false if the editor is undefined,
+ * or the instance of the content editor.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function getEditor() {
</span><span class="cx" style="display: block; padding: 0 10px"> return typeof tinymce !== 'undefined' && tinymce.get('content');
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Autosave in localStorage
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Autosave in localStorage.
+ *
+ * @since 3.9.0
+ *
+ * @returns {
+ * {
+ * hasStorage: *,
+ * getSavedPostData: getSavedPostData,
+ * save: save,
+ * suspend: suspend,
+ * resume: resume
+ * }
+ * }
+ * The object with all functions for local storage autosave.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function autosaveLocal() {
</span><span class="cx" style="display: block; padding: 0 10px"> var blog_id, post_id, hasStorage, intervalTimer,
</span><span class="cx" style="display: block; padding: 0 10px"> lastCompareString,
</span><span class="cx" style="display: block; padding: 0 10px"> isSuspended = false;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Check if the browser supports sessionStorage and it's not disabled
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Checks if the browser supports sessionStorage and it's not disabled.
+ *
+ * @since 3.9.0
+ *
+ * @returns {boolean} True if the sessionStorage is supported and enabled.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function checkStorage() {
</span><span class="cx" style="display: block; padding: 0 10px"> var test = Math.random().toString(),
</span><span class="cx" style="display: block; padding: 0 10px"> result = false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -114,9 +197,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Initialize the local storage
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @summary Initializes the local storage.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return mixed False if no sessionStorage in the browser or an Object containing all postData for this blog
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 3.9.0
+ *
+ * @returns {boolean|Object} False if no sessionStorage in the browser or an Object
+ * containing all postData for this blog.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function getStorage() {
</span><span class="cx" style="display: block; padding: 0 10px"> var stored_obj = false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -135,11 +221,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Set the storage for this blog
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @summary Sets the storage for this blog.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * Confirms that the data was saved successfully.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return bool
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 3.9.0
+ *
+ * @returns {boolean} True if the data was saved successfully, false if it wasn't saved.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function setStorage( stored_obj ) {
</span><span class="cx" style="display: block; padding: 0 10px"> var key;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -154,9 +242,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Get the saved post data for the current post
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @summary Gets the saved post data for the current post.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return mixed False if no storage or no data or the postData as an Object
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 3.9.0
+ *
+ * @returns {boolean|Object} False if no storage or no data or the postData as an Object.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function getSavedPostData() {
</span><span class="cx" style="display: block; padding: 0 10px"> var stored = getStorage();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -169,12 +259,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Set (save or delete) post data in the storage.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @summary Sets (save or delete) post data in the storage.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * If stored_data evaluates to 'false' the storage key for the current post will be removed
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * If stored_data evaluates to 'false' the storage key for the current post will be removed.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * $param stored_data The post data to store or null/false/empty to delete the key
- * @return bool
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 3.9.0
+ *
+ * @param {Object|boolean|null} stored_data The post data to store or null/false/empty to delete the key.
+ *
+ * @returns {boolean} True if data is stored, false if data was removed.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function setData( stored_data ) {
</span><span class="cx" style="display: block; padding: 0 10px"> var stored = getStorage();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -194,22 +287,39 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return setStorage( stored );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Sets isSuspended to true.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function suspend() {
</span><span class="cx" style="display: block; padding: 0 10px"> isSuspended = true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Sets isSuspended to false.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function resume() {
</span><span class="cx" style="display: block; padding: 0 10px"> isSuspended = false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Save post data for the current post
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @summary Saves post data for the current post.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * Runs on a 15 sec. interval, saves when there are differences in the post title or content.
</span><span class="cx" style="display: block; padding: 0 10px"> * When the optional data is provided, updates the last saved post data.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * $param data optional Object The post data for saving, minimum 'post_title' and 'content'
- * @return bool
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 3.9.0
+ *
+ * @param {Object} data The post data for saving, minimum 'post_title' and 'content'.
+ *
+ * @returns {boolean} Returns true when data has been saved, otherwise it returns false.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function save( data ) {
</span><span class="cx" style="display: block; padding: 0 10px"> var postData, compareString,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -232,7 +342,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> lastCompareString = initialCompareString;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // If the content, title and excerpt did not change since the last save, don't save again
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // If the content, title and excerpt did not change since the last save, don't save again.
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( compareString === lastCompareString ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -248,12 +358,24 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return result;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Run on DOM ready
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Initializes the auto save function.
+ *
+ * Checks whether the editor is active or not to use the editor events
+ * to autosave, or uses the values from the elements to autosave.
+ *
+ * Runs on DOM ready.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function run() {
</span><span class="cx" style="display: block; padding: 0 10px"> post_id = $('#post_ID').val() || 0;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Check if the local post data is different than the loaded post data.
</span><span class="cx" style="display: block; padding: 0 10px"> if ( $( '#wp-content-wrap' ).hasClass( 'tmce-active' ) ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> // If TinyMCE loads first, check the post 1.5 sec. after it is ready.
</span><span class="cx" style="display: block; padding: 0 10px"> // By this time the content has been loaded in the editor and 'saved' to the textarea.
</span><span class="cx" style="display: block; padding: 0 10px"> // This prevents false positives.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -274,6 +396,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> post_id = $('#post_ID').val() || 0;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( editor && ! editor.isHidden() ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Last onSubmit event in the editor, needs to run after the content has been moved to the textarea.
</span><span class="cx" style="display: block; padding: 0 10px"> editor.on( 'submit', function() {
</span><span class="cx" style="display: block; padding: 0 10px"> save({
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -295,7 +418,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> });
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Strip whitespace and compare two strings
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Compares 2 strings.
+ *
+ * Removes whitespaces in the strings before comparing them.
+ *
+ * @since 3.9.0
+ *
+ * @param {string} str1 The first string.
+ * @param {string} str2 The second string.
+ * @returns {boolean} True if the strings are the same.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function compare( str1, str2 ) {
</span><span class="cx" style="display: block; padding: 0 10px"> function removeSpaces( string ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return string.toString().replace(/[\x20\t\r\n\f]+/g, '');
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -305,11 +438,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Check if the saved data for the current post (if any) is different than the loaded post data on the screen
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @summary Checks if the saved data for the current post (if any) is different
+ * than the loaded post data on the screen.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * Shows a standard message letting the user restore the post data if different.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return void
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 3.9.0
+ *
+ * @returns {void}
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function checkPost() {
</span><span class="cx" style="display: block; padding: 0 10px"> var content, post_title, excerpt, $notice,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -352,6 +488,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> .addClass( 'notice-warning' );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( $newerAutosaveNotice.length ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> // If there is a "server" autosave notice, hide it.
</span><span class="cx" style="display: block; padding: 0 10px"> // The data in the session storage is either the same or newer.
</span><span class="cx" style="display: block; padding: 0 10px"> $newerAutosaveNotice.slideUp( 150, function() {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -369,7 +506,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> });
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Restore the current title, content and excerpt from postData.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Restores the current title, content and excerpt from postData.
+ *
+ * @since 3.9.0
+ *
+ * @param {Object} postData The object containing all post data.
+ *
+ * @returns {boolean} True if the post is restored.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function restorePost( postData ) {
</span><span class="cx" style="display: block; padding: 0 10px"> var editor;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -395,9 +540,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> editor.nodeChanged();
</span><span class="cx" style="display: block; padding: 0 10px"> });
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Make sure the Text editor is selected
</span><span class="cx" style="display: block; padding: 0 10px"> $( '#content-html' ).click();
</span><span class="cx" style="display: block; padding: 0 10px"> $( '#content' ).focus();
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Using document.execCommand() will let the user undo.
</span><span class="cx" style="display: block; padding: 0 10px"> document.execCommand( 'selectAll' );
</span><span class="cx" style="display: block; padding: 0 10px"> document.execCommand( 'insertText', false, postData.content || '' );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -427,13 +574,34 @@
</span><span class="cx" style="display: block; padding: 0 10px"> };
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Autosave on the server
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Auto saves the post on the server.
+ *
+ * @since 3.9.0
+ *
+ * @returns {Object} {
+ * {
+ * tempBlockSave: tempBlockSave,
+ * triggerSave: triggerSave,
+ * postChanged: postChanged,
+ * suspend: suspend,
+ * resume: resume
+ * }
+ * } The object all functions for autosave.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function autosaveServer() {
</span><span class="cx" style="display: block; padding: 0 10px"> var _blockSave, _blockSaveTimer, previousCompareString, lastCompareString,
</span><span class="cx" style="display: block; padding: 0 10px"> nextRun = 0,
</span><span class="cx" style="display: block; padding: 0 10px"> isSuspended = false;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Block saving for the next 10 sec.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ /**
+ * @summary Blocks saving for the next 10 seconds.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function tempBlockSave() {
</span><span class="cx" style="display: block; padding: 0 10px"> _blockSave = true;
</span><span class="cx" style="display: block; padding: 0 10px"> window.clearTimeout( _blockSaveTimer );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -443,15 +611,37 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }, 10000 );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Sets isSuspended to true.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function suspend() {
</span><span class="cx" style="display: block; padding: 0 10px"> isSuspended = true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Sets isSuspended to false.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function resume() {
</span><span class="cx" style="display: block; padding: 0 10px"> isSuspended = false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Runs on heartbeat-response
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Triggers the autosave with the post data.
+ *
+ * @since 3.9.0
+ *
+ * @param {Object} data The post data.
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function response( data ) {
</span><span class="cx" style="display: block; padding: 0 10px"> _schedule();
</span><span class="cx" style="display: block; padding: 0 10px"> _blockSave = false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -468,11 +658,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Save immediately
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @summary Saves immediately.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Resets the timing and tells heartbeat to connect now
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Resets the timing and tells heartbeat to connect now.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return void
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 3.9.0
+ *
+ * @returns {void}
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function triggerSave() {
</span><span class="cx" style="display: block; padding: 0 10px"> nextRun = 0;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -480,18 +672,29 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Checks if the post content in the textarea has changed since page load.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @summary Checks if the post content in the textarea has changed since page load.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * This also happens when TinyMCE is active and editor.save() is triggered by
</span><span class="cx" style="display: block; padding: 0 10px"> * wp.autosave.getPostData().
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @return bool
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 3.9.0
+ *
+ * @return {boolean} True if the post has been changed.
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> function postChanged() {
</span><span class="cx" style="display: block; padding: 0 10px"> return getCompareString() !== initialCompareString;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Runs on 'heartbeat-send'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Checks if the post can be saved or not.
+ *
+ * If the post hasn't changed or it cannot be updated,
+ * because the autosave is blocked or suspended, the function returns false.
+ *
+ * @since 3.9.0
+ *
+ * @returns {Object} Returns the post data.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function save() {
</span><span class="cx" style="display: block; padding: 0 10px"> var postData, compareString;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -529,21 +732,54 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return postData;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Sets the next run, based on the autosave interval.
+ *
+ * @private
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> function _schedule() {
</span><span class="cx" style="display: block; padding: 0 10px"> nextRun = ( new Date() ).getTime() + ( autosaveL10n.autosaveInterval * 1000 ) || 60000;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Sets the autosaveData on the autosave heartbeat.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> $document.on( 'heartbeat-send.autosave', function( event, data ) {
</span><span class="cx" style="display: block; padding: 0 10px"> var autosaveData = save();
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( autosaveData ) {
</span><span class="cx" style="display: block; padding: 0 10px"> data.wp_autosave = autosaveData;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ /**
+ * @summary Triggers the autosave of the post with the autosave data
+ * on the autosave heartbeat.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> }).on( 'heartbeat-tick.autosave', function( event, data ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( data.wp_autosave ) {
</span><span class="cx" style="display: block; padding: 0 10px"> response( data.wp_autosave );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Disables buttons and throws a notice when the connection is lost.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> }).on( 'heartbeat-connection-lost.autosave', function( event, error, status ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> // When connection is lost, keep user from submitting changes.
</span><span class="cx" style="display: block; padding: 0 10px"> if ( 'timeout' === error || 603 === status ) {
</span><span class="cx" style="display: block; padding: 0 10px"> var $notice = $('#lost-connection-notice');
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -555,6 +791,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $notice.show();
</span><span class="cx" style="display: block; padding: 0 10px"> disableButtons();
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ /**
+ * @summary Enables buttons when the connection is restored.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> }).on( 'heartbeat-connection-restored.autosave', function() {
</span><span class="cx" style="display: block; padding: 0 10px"> $('#lost-connection-notice').hide();
</span><span class="cx" style="display: block; padding: 0 10px"> enableButtons();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -571,10 +815,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> };
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // Wait for TinyMCE to initialize plus 1 sec. for any external css to finish loading,
- // then 'save' to the textarea before setting initialCompareString.
- // This avoids any insignificant differences between the initial textarea content and the content
- // extracted from the editor.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+ * @summary Sets the autosave time out.
+ *
+ * Wait for TinyMCE to initialize plus 1 second. for any external css to finish loading,
+ * then save to the textarea before setting initialCompareString.
+ * This avoids any insignificant differences between the initial textarea content and the content
+ * extracted from the editor.
+ *
+ * @since 3.9.0
+ *
+ * @returns {void}
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> $document.on( 'tinymce-editor-init.autosave', function( event, editor ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( editor.id === 'content' ) {
</span><span class="cx" style="display: block; padding: 0 10px"> window.setTimeout( function() {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -583,6 +835,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }, 1000 );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }).ready( function() {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Set the initial compare string in case TinyMCE is not used or not loaded first
</span><span class="cx" style="display: block; padding: 0 10px"> initialCompareString = getCompareString();
</span><span class="cx" style="display: block; padding: 0 10px"> });
</span></span></pre>
</div>
</div>
</body>
</html>