[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/ -> autosave.js (source)

   1  /**
   2   * @output wp-includes/js/autosave.js
   3   */
   4  
   5  /* global tinymce, wpCookies, autosaveL10n, switchEditors */
   6  // Back-compat.
   7  window.autosave = function() {
   8      return true;
   9  };
  10  
  11  /**
  12   * Adds autosave to the window object on dom ready.
  13   *
  14   * @since 3.9.0
  15   *
  16   * @param {jQuery} $ jQuery object.
  17   * @param {window} The window object.
  18   *
  19   */
  20  ( function( $, window ) {
  21      /**
  22       * Auto saves the post.
  23       *
  24       * @since 3.9.0
  25       *
  26       * @return {Object}
  27       *     {{
  28       *         getPostData: getPostData,
  29       *         getCompareString: getCompareString,
  30       *         disableButtons: disableButtons,
  31       *         enableButtons: enableButtons,
  32       *         local: ({hasStorage, getSavedPostData, save, suspend, resume}|*),
  33       *         server: ({tempBlockSave, triggerSave, postChanged, suspend, resume}|*)
  34       *     }}
  35       *     The object with all functions for autosave.
  36       */
  37  	function autosave() {
  38          var initialCompareString,
  39              initialCompareData = {},
  40              lastTriggerSave    = 0,
  41              $document          = $( document );
  42  
  43          /**
  44           * Sets the initial compare data.
  45           *
  46           * @since 5.6.1
  47           */
  48  		function setInitialCompare() {
  49              initialCompareData = {
  50                  post_title: $( '#title' ).val() || '',
  51                  content: $( '#content' ).val() || '',
  52                  excerpt: $( '#excerpt' ).val() || ''
  53              };
  54  
  55              initialCompareString = getCompareString( initialCompareData );
  56          }
  57  
  58          /**
  59           * Returns the data saved in both local and remote autosave.
  60           *
  61           * @since 3.9.0
  62           *
  63           * @param {string} type The type of autosave either local or remote.
  64           *
  65           * @return {Object} Object containing the post data.
  66           */
  67  		function getPostData( type ) {
  68              var post_name, parent_id, data,
  69                  time = ( new Date() ).getTime(),
  70                  cats = [],
  71                  editor = getEditor();
  72  
  73              // Don't run editor.save() more often than every 3 seconds.
  74              // It is resource intensive and might slow down typing in long posts on slow devices.
  75              if ( editor && editor.isDirty() && ! editor.isHidden() && time - 3000 > lastTriggerSave ) {
  76                  editor.save();
  77                  lastTriggerSave = time;
  78              }
  79  
  80              data = {
  81                  post_id: $( '#post_ID' ).val() || 0,
  82                  post_type: $( '#post_type' ).val() || '',
  83                  post_author: $( '#post_author' ).val() || '',
  84                  post_title: $( '#title' ).val() || '',
  85                  content: $( '#content' ).val() || '',
  86                  excerpt: $( '#excerpt' ).val() || ''
  87              };
  88  
  89              if ( type === 'local' ) {
  90                  return data;
  91              }
  92  
  93              $( 'input[id^="in-category-"]:checked' ).each( function() {
  94                  cats.push( this.value );
  95              });
  96              data.catslist = cats.join(',');
  97  
  98              if ( post_name = $( '#post_name' ).val() ) {
  99                  data.post_name = post_name;
 100              }
 101  
 102              if ( parent_id = $( '#parent_id' ).val() ) {
 103                  data.parent_id = parent_id;
 104              }
 105  
 106              if ( $( '#comment_status' ).prop( 'checked' ) ) {
 107                  data.comment_status = 'open';
 108              }
 109  
 110              if ( $( '#ping_status' ).prop( 'checked' ) ) {
 111                  data.ping_status = 'open';
 112              }
 113  
 114              if ( $( '#auto_draft' ).val() === '1' ) {
 115                  data.auto_draft = '1';
 116              }
 117  
 118              return data;
 119          }
 120  
 121          /**
 122           * Concatenates the title, content and excerpt. This is used to track changes
 123           * when auto-saving.
 124           *
 125           * @since 3.9.0
 126           *
 127           * @param {Object} postData The object containing the post data.
 128           *
 129           * @return {string} A concatenated string with title, content and excerpt.
 130           */
 131  		function getCompareString( postData ) {
 132              if ( typeof postData === 'object' ) {
 133                  return ( postData.post_title || '' ) + '::' + ( postData.content || '' ) + '::' + ( postData.excerpt || '' );
 134              }
 135  
 136              return ( $('#title').val() || '' ) + '::' + ( $('#content').val() || '' ) + '::' + ( $('#excerpt').val() || '' );
 137          }
 138  
 139          /**
 140           * Disables save buttons.
 141           *
 142           * @since 3.9.0
 143           *
 144           * @return {void}
 145           */
 146  		function disableButtons() {
 147              $document.trigger('autosave-disable-buttons');
 148  
 149              // Re-enable 5 sec later. Just gives autosave a head start to avoid collisions.
 150              setTimeout( enableButtons, 5000 );
 151          }
 152  
 153          /**
 154           * Enables save buttons.
 155           *
 156           * @since 3.9.0
 157           *
 158           * @return {void}
 159           */
 160  		function enableButtons() {
 161              $document.trigger( 'autosave-enable-buttons' );
 162          }
 163  
 164          /**
 165           * Gets the content editor.
 166           *
 167           * @since 4.6.0
 168           *
 169           * @return {boolean|*} Returns either false if the editor is undefined,
 170           *                     or the instance of the content editor.
 171           */
 172  		function getEditor() {
 173              return typeof tinymce !== 'undefined' && tinymce.get('content');
 174          }
 175  
 176          /**
 177           * Autosave in localStorage.
 178           *
 179           * @since 3.9.0
 180           *
 181           * @return {
 182           * {
 183           *     hasStorage: *,
 184           *     getSavedPostData: getSavedPostData,
 185           *     save: save,
 186           *     suspend: suspend,
 187           *     resume: resume
 188           *     }
 189           * }
 190           * The object with all functions for local storage autosave.
 191           */
 192  		function autosaveLocal() {
 193              var blog_id, post_id, hasStorage, intervalTimer,
 194                  lastCompareString,
 195                  isSuspended = false;
 196  
 197              /**
 198               * Checks if the browser supports sessionStorage and it's not disabled.
 199               *
 200               * @since 3.9.0
 201               *
 202               * @return {boolean} True if the sessionStorage is supported and enabled.
 203               */
 204  			function checkStorage() {
 205                  var test = Math.random().toString(),
 206                      result = false;
 207  
 208                  try {
 209                      window.sessionStorage.setItem( 'wp-test', test );
 210                      result = window.sessionStorage.getItem( 'wp-test' ) === test;
 211                      window.sessionStorage.removeItem( 'wp-test' );
 212                  } catch(e) {}
 213  
 214                  hasStorage = result;
 215                  return result;
 216              }
 217  
 218              /**
 219               * Initializes the local storage.
 220               *
 221               * @since 3.9.0
 222               *
 223               * @return {boolean|Object} False if no sessionStorage in the browser or an Object
 224               *                          containing all postData for this blog.
 225               */
 226  			function getStorage() {
 227                  var stored_obj = false;
 228                  // Separate local storage containers for each blog_id.
 229                  if ( hasStorage && blog_id ) {
 230                      stored_obj = sessionStorage.getItem( 'wp-autosave-' + blog_id );
 231  
 232                      if ( stored_obj ) {
 233                          stored_obj = JSON.parse( stored_obj );
 234                      } else {
 235                          stored_obj = {};
 236                      }
 237                  }
 238  
 239                  return stored_obj;
 240              }
 241  
 242              /**
 243               * Sets the storage for this blog. Confirms that the data was saved
 244               * successfully.
 245               *
 246               * @since 3.9.0
 247               *
 248               * @return {boolean} True if the data was saved successfully, false if it wasn't saved.
 249               */
 250  			function setStorage( stored_obj ) {
 251                  var key;
 252  
 253                  if ( hasStorage && blog_id ) {
 254                      key = 'wp-autosave-' + blog_id;
 255                      sessionStorage.setItem( key, JSON.stringify( stored_obj ) );
 256                      return sessionStorage.getItem( key ) !== null;
 257                  }
 258  
 259                  return false;
 260              }
 261  
 262              /**
 263               * Gets the saved post data for the current post.
 264               *
 265               * @since 3.9.0
 266               *
 267               * @return {boolean|Object} False if no storage or no data or the postData as an Object.
 268               */
 269  			function getSavedPostData() {
 270                  var stored = getStorage();
 271  
 272                  if ( ! stored || ! post_id ) {
 273                      return false;
 274                  }
 275  
 276                  return stored[ 'post_' + post_id ] || false;
 277              }
 278  
 279              /**
 280               * Sets (save or delete) post data in the storage.
 281               *
 282               * If stored_data evaluates to 'false' the storage key for the current post will be removed.
 283               *
 284               * @since 3.9.0
 285               *
 286               * @param {Object|boolean|null} stored_data The post data to store or null/false/empty to delete the key.
 287               *
 288               * @return {boolean} True if data is stored, false if data was removed.
 289               */
 290  			function setData( stored_data ) {
 291                  var stored = getStorage();
 292  
 293                  if ( ! stored || ! post_id ) {
 294                      return false;
 295                  }
 296  
 297                  if ( stored_data ) {
 298                      stored[ 'post_' + post_id ] = stored_data;
 299                  } else if ( stored.hasOwnProperty( 'post_' + post_id ) ) {
 300                      delete stored[ 'post_' + post_id ];
 301                  } else {
 302                      return false;
 303                  }
 304  
 305                  return setStorage( stored );
 306              }
 307  
 308              /**
 309               * Sets isSuspended to true.
 310               *
 311               * @since 3.9.0
 312               *
 313               * @return {void}
 314               */
 315  			function suspend() {
 316                  isSuspended = true;
 317              }
 318  
 319              /**
 320               * Sets isSuspended to false.
 321               *
 322               * @since 3.9.0
 323               *
 324               * @return {void}
 325               */
 326  			function resume() {
 327                  isSuspended = false;
 328              }
 329  
 330              /**
 331               * Saves post data for the current post.
 332               *
 333               * Runs on a 15 seconds interval, saves when there are differences in the post title or content.
 334               * When the optional data is provided, updates the last saved post data.
 335               *
 336               * @since 3.9.0
 337               *
 338               * @param {Object} data The post data for saving, minimum 'post_title' and 'content'.
 339               *
 340               * @return {boolean} Returns true when data has been saved, otherwise it returns false.
 341               */
 342  			function save( data ) {
 343                  var postData, compareString,
 344                      result = false;
 345  
 346                  if ( isSuspended || ! hasStorage ) {
 347                      return false;
 348                  }
 349  
 350                  if ( data ) {
 351                      postData = getSavedPostData() || {};
 352                      $.extend( postData, data );
 353                  } else {
 354                      postData = getPostData('local');
 355                  }
 356  
 357                  compareString = getCompareString( postData );
 358  
 359                  if ( typeof lastCompareString === 'undefined' ) {
 360                      lastCompareString = initialCompareString;
 361                  }
 362  
 363                  // If the content, title and excerpt did not change since the last save, don't save again.
 364                  if ( compareString === lastCompareString ) {
 365                      return false;
 366                  }
 367  
 368                  postData.save_time = ( new Date() ).getTime();
 369                  postData.status = $( '#post_status' ).val() || '';
 370                  result = setData( postData );
 371  
 372                  if ( result ) {
 373                      lastCompareString = compareString;
 374                  }
 375  
 376                  return result;
 377              }
 378  
 379              /**
 380               * Initializes the auto save function.
 381               *
 382               * Checks whether the editor is active or not to use the editor events
 383               * to autosave, or uses the values from the elements to autosave.
 384               *
 385               * Runs on DOM ready.
 386               *
 387               * @since 3.9.0
 388               *
 389               * @return {void}
 390               */
 391  			function run() {
 392                  post_id = $('#post_ID').val() || 0;
 393  
 394                  // Check if the local post data is different than the loaded post data.
 395                  if ( $( '#wp-content-wrap' ).hasClass( 'tmce-active' ) ) {
 396  
 397                      /*
 398                       * If TinyMCE loads first, check the post 1.5 seconds after it is ready.
 399                       * By this time the content has been loaded in the editor and 'saved' to the textarea.
 400                       * This prevents false positives.
 401                       */
 402                      $document.on( 'tinymce-editor-init.autosave', function() {
 403                          window.setTimeout( function() {
 404                              checkPost();
 405                          }, 1500 );
 406                      });
 407                  } else {
 408                      checkPost();
 409                  }
 410  
 411                  // Save every 15 seconds.
 412                  intervalTimer = window.setInterval( save, 15000 );
 413  
 414                  $( 'form#post' ).on( 'submit.autosave-local', function() {
 415                      var editor = getEditor(),
 416                          post_id = $('#post_ID').val() || 0;
 417  
 418                      if ( editor && ! editor.isHidden() ) {
 419  
 420                          // Last onSubmit event in the editor, needs to run after the content has been moved to the textarea.
 421                          editor.on( 'submit', function() {
 422                              save({
 423                                  post_title: $( '#title' ).val() || '',
 424                                  content: $( '#content' ).val() || '',
 425                                  excerpt: $( '#excerpt' ).val() || ''
 426                              });
 427                          });
 428                      } else {
 429                          save({
 430                              post_title: $( '#title' ).val() || '',
 431                              content: $( '#content' ).val() || '',
 432                              excerpt: $( '#excerpt' ).val() || ''
 433                          });
 434                      }
 435  
 436                      var secure = ( 'https:' === window.location.protocol );
 437                      wpCookies.set( 'wp-saving-post', post_id + '-check', 24 * 60 * 60, false, false, secure );
 438                  });
 439              }
 440  
 441              /**
 442               * Compares 2 strings. Removes whitespaces in the strings before comparing them.
 443               *
 444               * @since 3.9.0
 445               *
 446               * @param {string} str1 The first string.
 447               * @param {string} str2 The second string.
 448               * @return {boolean} True if the strings are the same.
 449               */
 450  			function compare( str1, str2 ) {
 451  				function removeSpaces( string ) {
 452                      return string.toString().replace(/[\x20\t\r\n\f]+/g, '');
 453                  }
 454  
 455                  return ( removeSpaces( str1 || '' ) === removeSpaces( str2 || '' ) );
 456              }
 457  
 458              /**
 459               * Checks if the saved data for the current post (if any) is different than the
 460               * loaded post data on the screen.
 461               *
 462               * Shows a standard message letting the user restore the post data if different.
 463               *
 464               * @since 3.9.0
 465               *
 466               * @return {void}
 467               */
 468  			function checkPost() {
 469                  var content, post_title, excerpt, $notice,
 470                      postData = getSavedPostData(),
 471                      cookie = wpCookies.get( 'wp-saving-post' ),
 472                      $newerAutosaveNotice = $( '#has-newer-autosave' ).parent( '.notice' ),
 473                      $headerEnd = $( '.wp-header-end' );
 474  
 475                  if ( cookie === post_id + '-saved' ) {
 476                      wpCookies.remove( 'wp-saving-post' );
 477                      // The post was saved properly, remove old data and bail.
 478                      setData( false );
 479                      return;
 480                  }
 481  
 482                  if ( ! postData ) {
 483                      return;
 484                  }
 485  
 486                  content = $( '#content' ).val() || '';
 487                  post_title = $( '#title' ).val() || '';
 488                  excerpt = $( '#excerpt' ).val() || '';
 489  
 490                  if ( compare( content, postData.content ) && compare( post_title, postData.post_title ) &&
 491                      compare( excerpt, postData.excerpt ) ) {
 492  
 493                      return;
 494                  }
 495  
 496                  /*
 497                   * If '.wp-header-end' is found, append the notices after it otherwise
 498                   * after the first h1 or h2 heading found within the main content.
 499                   */
 500                  if ( ! $headerEnd.length ) {
 501                      $headerEnd = $( '.wrap h1, .wrap h2' ).first();
 502                  }
 503  
 504                  $notice = $( '#local-storage-notice' )
 505                      .insertAfter( $headerEnd )
 506                      .addClass( 'notice-warning' );
 507  
 508                  if ( $newerAutosaveNotice.length ) {
 509  
 510                      // If there is a "server" autosave notice, hide it.
 511                      // The data in the session storage is either the same or newer.
 512                      $newerAutosaveNotice.slideUp( 150, function() {
 513                          $notice.slideDown( 150 );
 514                      });
 515                  } else {
 516                      $notice.slideDown( 200 );
 517                  }
 518  
 519                  $notice.find( '.restore-backup' ).on( 'click.autosave-local', function() {
 520                      restorePost( postData );
 521                      $notice.fadeTo( 250, 0, function() {
 522                          $notice.slideUp( 150 );
 523                      });
 524                  });
 525              }
 526  
 527              /**
 528               * Restores the current title, content and excerpt from postData.
 529               *
 530               * @since 3.9.0
 531               *
 532               * @param {Object} postData The object containing all post data.
 533               *
 534               * @return {boolean} True if the post is restored.
 535               */
 536  			function restorePost( postData ) {
 537                  var editor;
 538  
 539                  if ( postData ) {
 540                      // Set the last saved data.
 541                      lastCompareString = getCompareString( postData );
 542  
 543                      if ( $( '#title' ).val() !== postData.post_title ) {
 544                          $( '#title' ).trigger( 'focus' ).val( postData.post_title || '' );
 545                      }
 546  
 547                      $( '#excerpt' ).val( postData.excerpt || '' );
 548                      editor = getEditor();
 549  
 550                      if ( editor && ! editor.isHidden() && typeof switchEditors !== 'undefined' ) {
 551                          if ( editor.settings.wpautop && postData.content ) {
 552                              postData.content = switchEditors.wpautop( postData.content );
 553                          }
 554  
 555                          // Make sure there's an undo level in the editor.
 556                          editor.undoManager.transact( function() {
 557                              editor.setContent( postData.content || '' );
 558                              editor.nodeChanged();
 559                          });
 560                      } else {
 561  
 562                          // Make sure the Text editor is selected.
 563                          $( '#content-html' ).trigger( 'click' );
 564                          $( '#content' ).trigger( 'focus' );
 565  
 566                          // Using document.execCommand() will let the user undo.
 567                          document.execCommand( 'selectAll' );
 568                          document.execCommand( 'insertText', false, postData.content || '' );
 569                      }
 570  
 571                      return true;
 572                  }
 573  
 574                  return false;
 575              }
 576  
 577              blog_id = typeof window.autosaveL10n !== 'undefined' && window.autosaveL10n.blog_id;
 578  
 579              /*
 580               * Check if the browser supports sessionStorage and it's not disabled,
 581               * then initialize and run checkPost().
 582               * Don't run if the post type supports neither 'editor' (textarea#content) nor 'excerpt'.
 583               */
 584              if ( checkStorage() && blog_id && ( $('#content').length || $('#excerpt').length ) ) {
 585                  $( run );
 586              }
 587  
 588              return {
 589                  hasStorage: hasStorage,
 590                  getSavedPostData: getSavedPostData,
 591                  save: save,
 592                  suspend: suspend,
 593                  resume: resume
 594              };
 595          }
 596  
 597          /**
 598           * Auto saves the post on the server.
 599           *
 600           * @since 3.9.0
 601           *
 602           * @return {Object} {
 603           *     {
 604           *         tempBlockSave: tempBlockSave,
 605           *         triggerSave: triggerSave,
 606           *         postChanged: postChanged,
 607           *         suspend: suspend,
 608           *         resume: resume
 609           *         }
 610           *     } The object all functions for autosave.
 611           */
 612  		function autosaveServer() {
 613              var _blockSave, _blockSaveTimer, previousCompareString, lastCompareString,
 614                  nextRun = 0,
 615                  isSuspended = false;
 616  
 617  
 618              /**
 619               * Blocks saving for the next 10 seconds.
 620               *
 621               * @since 3.9.0
 622               *
 623               * @return {void}
 624               */
 625  			function tempBlockSave() {
 626                  _blockSave = true;
 627                  window.clearTimeout( _blockSaveTimer );
 628  
 629                  _blockSaveTimer = window.setTimeout( function() {
 630                      _blockSave = false;
 631                  }, 10000 );
 632              }
 633  
 634              /**
 635               * Sets isSuspended to true.
 636               *
 637               * @since 3.9.0
 638               *
 639               * @return {void}
 640               */
 641  			function suspend() {
 642                  isSuspended = true;
 643              }
 644  
 645              /**
 646               * Sets isSuspended to false.
 647               *
 648               * @since 3.9.0
 649               *
 650               * @return {void}
 651               */
 652  			function resume() {
 653                  isSuspended = false;
 654              }
 655  
 656              /**
 657               * Triggers the autosave with the post data.
 658               *
 659               * @since 3.9.0
 660               *
 661               * @param {Object} data The post data.
 662               *
 663               * @return {void}
 664               */
 665  			function response( data ) {
 666                  _schedule();
 667                  _blockSave = false;
 668                  lastCompareString = previousCompareString;
 669                  previousCompareString = '';
 670  
 671                  $document.trigger( 'after-autosave', [data] );
 672                  enableButtons();
 673  
 674                  if ( data.success ) {
 675                      // No longer an auto-draft.
 676                      $( '#auto_draft' ).val('');
 677                  }
 678              }
 679  
 680              /**
 681               * Saves immediately.
 682               *
 683               * Resets the timing and tells heartbeat to connect now.
 684               *
 685               * @since 3.9.0
 686               *
 687               * @return {void}
 688               */
 689  			function triggerSave() {
 690                  nextRun = 0;
 691                  wp.heartbeat.connectNow();
 692              }
 693  
 694              /**
 695               * Checks if the post content in the textarea has changed since page load.
 696               *
 697               * This also happens when TinyMCE is active and editor.save() is triggered by
 698               * wp.autosave.getPostData().
 699               *
 700               * @since 3.9.0
 701               *
 702               * @return {boolean} True if the post has been changed.
 703               */
 704  			function postChanged() {
 705                  var changed = false;
 706  
 707                  // If there are TinyMCE instances, loop through them.
 708                  if ( window.tinymce ) {
 709                      window.tinymce.each( [ 'content', 'excerpt' ], function( field ) {
 710                          var editor = window.tinymce.get( field );
 711  
 712                          if ( ! editor || editor.isHidden() ) {
 713                              if ( ( $( '#' + field ).val() || '' ) !== initialCompareData[ field ] ) {
 714                                  changed = true;
 715                                  // Break.
 716                                  return false;
 717                              }
 718                          } else if ( editor.isDirty() ) {
 719                              changed = true;
 720                              return false;
 721                          }
 722                      } );
 723  
 724                      if ( ( $( '#title' ).val() || '' ) !== initialCompareData.post_title ) {
 725                          changed = true;
 726                      }
 727  
 728                      return changed;
 729                  }
 730  
 731                  return getCompareString() !== initialCompareString;
 732              }
 733  
 734              /**
 735               * Checks if the post can be saved or not.
 736               *
 737               * If the post hasn't changed or it cannot be updated,
 738               * because the autosave is blocked or suspended, the function returns false.
 739               *
 740               * @since 3.9.0
 741               *
 742               * @return {Object} Returns the post data.
 743               */
 744  			function save() {
 745                  var postData, compareString;
 746  
 747                  // window.autosave() used for back-compat.
 748                  if ( isSuspended || _blockSave || ! window.autosave() ) {
 749                      return false;
 750                  }
 751  
 752                  if ( ( new Date() ).getTime() < nextRun ) {
 753                      return false;
 754                  }
 755  
 756                  postData = getPostData();
 757                  compareString = getCompareString( postData );
 758  
 759                  // First check.
 760                  if ( typeof lastCompareString === 'undefined' ) {
 761                      lastCompareString = initialCompareString;
 762                  }
 763  
 764                  // No change.
 765                  if ( compareString === lastCompareString ) {
 766                      return false;
 767                  }
 768  
 769                  previousCompareString = compareString;
 770                  tempBlockSave();
 771                  disableButtons();
 772  
 773                  $document.trigger( 'wpcountwords', [ postData.content ] )
 774                      .trigger( 'before-autosave', [ postData ] );
 775  
 776                  postData._wpnonce = $( '#_wpnonce' ).val() || '';
 777  
 778                  return postData;
 779              }
 780  
 781              /**
 782               * Sets the next run, based on the autosave interval.
 783               *
 784               * @private
 785               *
 786               * @since 3.9.0
 787               *
 788               * @return {void}
 789               */
 790  			function _schedule() {
 791                  nextRun = ( new Date() ).getTime() + ( autosaveL10n.autosaveInterval * 1000 ) || 60000;
 792              }
 793  
 794              /**
 795               * Sets the autosaveData on the autosave heartbeat.
 796               *
 797               * @since 3.9.0
 798               *
 799               * @return {void}
 800               */
 801              $( function() {
 802                  _schedule();
 803              }).on( 'heartbeat-send.autosave', function( event, data ) {
 804                  var autosaveData = save();
 805  
 806                  if ( autosaveData ) {
 807                      data.wp_autosave = autosaveData;
 808                  }
 809  
 810                  /**
 811                   * Triggers the autosave of the post with the autosave data on the autosave
 812                   * heartbeat.
 813                   *
 814                   * @since 3.9.0
 815                   *
 816                   * @return {void}
 817                   */
 818              }).on( 'heartbeat-tick.autosave', function( event, data ) {
 819                  if ( data.wp_autosave ) {
 820                      response( data.wp_autosave );
 821                  }
 822                  /**
 823                   * Disables buttons and throws a notice when the connection is lost.
 824                   *
 825                   * @since 3.9.0
 826                   *
 827                   * @return {void}
 828                   */
 829              }).on( 'heartbeat-connection-lost.autosave', function( event, error, status ) {
 830  
 831                  // When connection is lost, keep user from submitting changes.
 832                  if ( 'timeout' === error || 603 === status ) {
 833                      var $notice = $('#lost-connection-notice');
 834  
 835                      if ( ! wp.autosave.local.hasStorage ) {
 836                          $notice.find('.hide-if-no-sessionstorage').hide();
 837                      }
 838  
 839                      $notice.show();
 840                      disableButtons();
 841                  }
 842  
 843                  /**
 844                   * Enables buttons when the connection is restored.
 845                   *
 846                   * @since 3.9.0
 847                   *
 848                   * @return {void}
 849                   */
 850              }).on( 'heartbeat-connection-restored.autosave', function() {
 851                  $('#lost-connection-notice').hide();
 852                  enableButtons();
 853              });
 854  
 855              return {
 856                  tempBlockSave: tempBlockSave,
 857                  triggerSave: triggerSave,
 858                  postChanged: postChanged,
 859                  suspend: suspend,
 860                  resume: resume
 861              };
 862          }
 863  
 864          /**
 865           * Sets the autosave time out.
 866           *
 867           * Wait for TinyMCE to initialize plus 1 second. for any external css to finish loading,
 868           * then save to the textarea before setting initialCompareString.
 869           * This avoids any insignificant differences between the initial textarea content and the content
 870           * extracted from the editor.
 871           *
 872           * @since 3.9.0
 873           *
 874           * @return {void}
 875           */
 876          $( function() {
 877              // Set the initial compare string in case TinyMCE is not used or not loaded first.
 878              setInitialCompare();
 879          }).on( 'tinymce-editor-init.autosave', function( event, editor ) {
 880              // Reset the initialCompare data after the TinyMCE instances have been initialized.
 881              if ( 'content' === editor.id || 'excerpt' === editor.id ) {
 882                  window.setTimeout( function() {
 883                      editor.save();
 884                      setInitialCompare();
 885                  }, 1000 );
 886              }
 887          });
 888  
 889          return {
 890              getPostData: getPostData,
 891              getCompareString: getCompareString,
 892              disableButtons: disableButtons,
 893              enableButtons: enableButtons,
 894              local: autosaveLocal(),
 895              server: autosaveServer()
 896          };
 897      }
 898  
 899      /** @namespace wp */
 900      window.wp = window.wp || {};
 901      window.wp.autosave = autosave();
 902  
 903  }( jQuery, window ));


Generated: Fri Apr 19 01:00:02 2024 Cross-referenced by PHPXref 0.7.1