Changeset 42389
- Timestamp:
- 12/12/2017 02:32:33 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/js/heartbeat.js
r41839 r42389 28 28 29 29 ( function( $, window, undefined ) { 30 31 /** 32 * Constructs the Heartbeat API. 33 * 34 * @since 3.6.0 35 * 36 * @returns {Object} An instance of the Heartbeat class. 37 * @constructor 38 */ 30 39 var Heartbeat = function() { 31 40 var $document = $(document), 32 41 settings = { 33 // Suspend/resume 42 // Suspend/resume. 34 43 suspend: false, 35 44 36 // Whether suspending is enabled 45 // Whether suspending is enabled. 37 46 suspendEnabled: true, 38 47 39 // Current screen id, defaults to the JS global 'pagenow' when present (in the admin) or 'front' 48 // Current screen id, defaults to the JS global 'pagenow' when present 49 // (in the admin) or 'front'. 40 50 screenId: '', 41 51 42 // XHR request URL, defaults to the JS global 'ajaxurl' when present 52 // XHR request URL, defaults to the JS global 'ajaxurl' when present. 43 53 url: '', 44 54 45 // Timestamp, start of the last connection request 55 // Timestamp, start of the last connection request. 46 56 lastTick: 0, 47 57 48 // Container for the enqueued items 58 // Container for the enqueued items. 49 59 queue: {}, 50 60 51 // Connect interval (in seconds) 61 // Connect interval (in seconds). 52 62 mainInterval: 60, 53 63 54 // Used when the interval is set to 5 sec. temporarily 64 // Used when the interval is set to 5 sec. temporarily. 55 65 tempInterval: 0, 56 66 57 // Used when the interval is reset 67 // Used when the interval is reset. 58 68 originalInterval: 0, 59 69 … … 61 71 minimalInterval: 0, 62 72 63 // Used together with tempInterval 73 // Used together with tempInterval. 64 74 countdown: 0, 65 75 66 // Whether a connection is currently in progress 76 // Whether a connection is currently in progress. 67 77 connecting: false, 68 78 69 // Whether a connection error occurred 79 // Whether a connection error occurred. 70 80 connectionError: false, 71 81 72 // Used to track non-critical errors 82 // Used to track non-critical errors. 73 83 errorcount: 0, 74 84 75 // Whether at least one connection has completed successfully85 // Whether at least one connection has been completed successfully. 76 86 hasConnected: false, 77 87 78 // Whether the current browser window is in focus and the user is active 88 // Whether the current browser window is in focus and the user is active. 79 89 hasFocus: true, 80 90 … … 82 92 userActivity: 0, 83 93 84 // Flag s whether events tracking user activity were set94 // Flag whether events tracking user activity were set. 85 95 userActivityEvents: false, 86 96 97 // Timer that keeps track of how long a user has focus. 87 98 checkFocusTimer: 0, 99 100 // Timer that keeps track of how long needs to be waited before connecting to 101 // the server again. 88 102 beatTimer: 0 89 103 }; 90 104 91 105 /** 92 * Set local vars and events, then start 93 * 94 * @access private 95 * 96 * @return void 106 * Sets local variables and events, then starts the heartbeat. 107 * 108 * @access private 109 * 110 * @since 3.8.0 111 * 112 * @returns {void} 97 113 */ 98 114 function initialize() { … … 107 123 } 108 124 109 // Pull in options passed from PHP 125 // Pull in options passed from PHP. 110 126 if ( typeof window.heartbeatSettings === 'object' ) { 111 127 options = window.heartbeatSettings; 112 128 113 // The XHR URL can be passed as option when window.ajaxurl is not set 129 // The XHR URL can be passed as option when window.ajaxurl is not set. 114 130 if ( ! settings.url && options.ajaxurl ) { 115 131 settings.url = options.ajaxurl; 116 132 } 117 133 118 // The interval can be from 15 to 120 sec. and can be set temporarily to 5 sec. 119 // It can be set in the initial options or changed later from JS and/or from PHP. 134 /* 135 * The interval can be from 15 to 120 sec. and can be set temporarily to 5 sec. 136 * It can be set in the initial options or changed later through JS and/or 137 * through PHP. 138 */ 120 139 if ( options.interval ) { 121 140 settings.mainInterval = options.interval; … … 128 147 } 129 148 130 // Used to limit the number of AJAX requests. Overrides all other intervals if they are shorter. 131 // Needed for some hosts that cannot handle frequent requests and the user may exceed the allocated server CPU time, etc. 132 // The minimal interval can be up to 600 sec. however setting it to longer than 120 sec. will limit or disable 133 // some of the functionality (like post locks). 134 // Once set at initialization, minimalInterval cannot be changed/overridden. 149 /* 150 * Used to limit the number of AJAX requests. Overrides all other intervals if 151 * they are shorter. Needed for some hosts that cannot handle frequent requests 152 * and the user may exceed the allocated server CPU time, etc. The minimal 153 * interval can be up to 600 sec. however setting it to longer than 120 sec. 154 * will limit or disable some of the functionality (like post locks). Once set 155 * at initialization, minimalInterval cannot be changed/overridden. 156 */ 135 157 if ( options.minimalInterval ) { 136 158 options.minimalInterval = parseInt( options.minimalInterval, 10 ); … … 142 164 } 143 165 144 // 'screenId' can be added from settings on the front end where the JS global 'pagenow' is not set 166 // 'screenId' can be added from settings on the front end where the JS global 167 // 'pagenow' is not set. 145 168 if ( ! settings.screenId ) { 146 169 settings.screenId = options.screenId || 'front'; … … 152 175 } 153 176 154 // Convert to milliseconds 177 // Convert to milliseconds. 155 178 settings.mainInterval = settings.mainInterval * 1000; 156 179 settings.originalInterval = settings.mainInterval; 157 180 158 // Switch the interval to 120 sec. by using the Page Visibility API. 159 // If the browser doesn't support it (Safari < 7, Android < 4.4, IE < 10), the interval 160 // will be increased to 120 sec. after 5 min. of mouse and keyboard inactivity. 181 /* 182 * Switch the interval to 120 seconds by using the Page Visibility API. 183 * If the browser doesn't support it (Safari < 7, Android < 4.4, IE < 10), the 184 * interval will be increased to 120 seconds after 5 minutes of mouse and keyboard 185 * inactivity. 186 */ 161 187 if ( typeof document.hidden !== 'undefined' ) { 162 188 hidden = 'hidden'; … … 197 223 198 224 $(window).on( 'unload.wp-heartbeat', function() { 199 // Don't connect any more225 // Don't connect anymore. 200 226 settings.suspend = true; 201 227 202 // Abort the last request if not completed 228 // Abort the last request if not completed. 203 229 if ( settings.xhr && settings.xhr.readyState !== 4 ) { 204 230 settings.xhr.abort(); … … 209 235 window.setInterval( checkUserActivity, 30000 ); 210 236 211 // Start one tick after DOM ready 237 // Start one tick after DOM ready. 212 238 $document.ready( function() { 213 239 settings.lastTick = time(); … … 217 243 218 244 /** 219 * Return the current time according to the browser 220 * 221 * @access private 222 * 223 * @return int 245 * Returns the current time according to the browser. 246 * 247 * @access private 248 * 249 * @since 3.6.0 250 * 251 * @returns {number} Returns the current time. 224 252 */ 225 253 function time() { … … 228 256 229 257 /** 230 * Check if the iframe is from the same origin 231 * 232 * @access private 233 * 234 * @return bool 258 * Checks if the iframe is from the same origin. 259 * 260 * @access private 261 * 262 * @since 3.6.0 263 * 264 * @returns {boolean} Returns whether or not the iframe is from the same origin. 235 265 */ 236 266 function isLocalFrame( frame ) { 237 267 var origin, src = frame.src; 238 268 239 // Need to compare strings as WebKit doesn't throw JS errors when iframes have different origin. 240 // It throws uncatchable exceptions. 269 /* 270 * Need to compare strings as WebKit doesn't throw JS errors when iframes have 271 * different origin. It throws uncatchable exceptions. 272 */ 241 273 if ( src && /^https?:\/\//.test( src ) ) { 242 274 origin = window.location.origin ? window.location.origin : window.location.protocol + '//' + window.location.host; … … 257 289 258 290 /** 259 * Check if the document's focus has changed 260 * 261 * @access private 262 * 263 * @return void 291 * Checks if the document's focus has changed. 292 * 293 * @access private 294 * 295 * @since 4.1.0 296 * 297 * @returns {void} 264 298 */ 265 299 function checkFocus() { … … 272 306 273 307 /** 274 * Set error state and fire an event on XHR errors or timeout 275 * 276 * @access private 277 * 278 * @param string error The error type passed from the XHR 279 * @param int status The HTTP status code passed from jqXHR (200, 404, 500, etc.) 280 * @return void 308 * Sets error state and fires an event on XHR errors or timeout. 309 * 310 * @access private 311 * 312 * @since 3.8.0 313 * 314 * @param {string} error The error type passed from the XHR. 315 * @param {number} status The HTTP status code passed from jqXHR 316 * (200, 404, 500, etc.). 317 * 318 * @returns {void} 281 319 */ 282 320 function setErrorState( error, status ) { … … 286 324 switch ( error ) { 287 325 case 'abort': 288 // do nothing326 // Do nothing. 289 327 break; 290 328 case 'timeout': 291 // no response for 30 sec.329 // No response for 30 sec. 292 330 trigger = true; 293 331 break; … … 318 356 319 357 /** 320 * Clear the error state and fire an event 321 * 322 * @access private 323 * 324 * @return void 358 * Clears the error state and fires an event if there is a connection error. 359 * 360 * @access private 361 * 362 * @since 3.8.0 363 * 364 * @returns {void} 325 365 */ 326 366 function clearErrorState() { 327 // Has connected successfully 367 // Has connected successfully. 328 368 settings.hasConnected = true; 329 369 … … 336 376 337 377 /** 338 * Gather the data and connect to the server 339 * 340 * @access private 341 * 342 * @return void 378 * Gathers the data and connects to the server. 379 * 380 * @access private 381 * 382 * @since 3.6.0 383 * 384 * @returns {void} 343 385 */ 344 386 function connect() { … … 354 396 355 397 heartbeatData = $.extend( {}, settings.queue ); 356 // Clear the data queue , anything added after this point will be send on the next tick398 // Clear the data queue. Anything added after this point will be sent on the next tick. 357 399 settings.queue = {}; 358 400 … … 404 446 $document.trigger( 'heartbeat-tick', [response, textStatus, jqXHR] ); 405 447 406 // Do this last , can trigger the next XHR if connection time > 5 sec. and newInterval == 'fast'448 // Do this last. Can trigger the next XHR if connection time > 5 sec. and newInterval == 'fast'. 407 449 if ( newInterval ) { 408 450 interval( newInterval ); … … 415 457 416 458 /** 417 * Schedule the next connection459 * Schedules the next connection. 418 460 * 419 461 * Fires immediately if the connection time is longer than the interval. … … 421 463 * @access private 422 464 * 423 * @return void 465 * @since 3.8.0 466 * 467 * @returns {void} 424 468 */ 425 469 function scheduleNextTick() { … … 461 505 462 506 /** 463 * Set the internal state when the browser window becomes hidden or loses focus 464 * 465 * @access private 466 * 467 * @return void 507 * Sets the internal state when the browser window becomes hidden or loses focus. 508 * 509 * @access private 510 * 511 * @since 3.6.0 512 * 513 * @returns {void} 468 514 */ 469 515 function blurred() { … … 472 518 473 519 /** 474 * Set the internal state when the browser window becomes visible or is in focus 475 * 476 * @access private 477 * 478 * @return void 520 * Sets the internal state when the browser window becomes visible or is in focus. 521 * 522 * @access private 523 * 524 * @since 3.6.0 525 * 526 * @returns {void} 479 527 */ 480 528 function focused() { … … 491 539 492 540 /** 493 * Runs when the user becomes active after a period of inactivity 494 * 495 * @access private 496 * 497 * @return void 541 * Runs when the user becomes active after a period of inactivity. 542 * 543 * @access private 544 * 545 * @since 3.6.0 546 * 547 * @returns {void} 498 548 */ 499 549 function userIsActive() { … … 511 561 512 562 /** 513 * Check for user activity 514 * 515 * Runs every 30 sec. 516 * Sets 'hasFocus = true' if user is active and the window is in the background. 517 * Set 'hasFocus = false' if the user has been inactive (no mouse or keyboard activity) 518 * for 5 min. even when the window has focus. 519 * 520 * @access private 521 * 522 * @return void 563 * Checks for user activity. 564 * 565 * Runs every 30 sec. Sets 'hasFocus = true' if user is active and the window is 566 * in the background. Sets 'hasFocus = false' if the user has been inactive 567 * (no mouse or keyboard activity) for 5 min. even when the window has focus. 568 * 569 * @access private 570 * 571 * @since 3.8.0 572 * 573 * @returns {void} 523 574 */ 524 575 function checkUserActivity() { … … 553 604 } 554 605 555 // Public methods 556 557 /** 558 * Whether the window (or any local iframe in it) has focus, or the user is active 559 * 560 * @return bool 606 // Public methods. 607 608 /** 609 * Checks whether the window (or any local iframe in it) has focus, or the user 610 * is active. 611 * 612 * @since 3.6.0 613 * @memberOf wp.heartbeat.prototype 614 * 615 * @returns {boolean} True if the window or the user is active. 561 616 */ 562 617 function hasFocus() { … … 565 620 566 621 /** 567 * Whether there is a connection error 568 * 569 * @return bool 622 * Checks whether there is a connection error. 623 * 624 * @since 3.6.0 625 * 626 * @memberOf wp.heartbeat.prototype 627 * 628 * @returns {boolean} True if a connection error was found. 570 629 */ 571 630 function hasConnectionError() { … … 574 633 575 634 /** 576 * Connect asap regardless of 'hasFocus'635 * Connects as soon as possible regardless of 'hasFocus' state. 577 636 * 578 637 * Will not open two concurrent connections. If a connection is in progress, 579 638 * will connect again immediately after the current connection completes. 580 639 * 581 * @return void 640 * @since 3.8.0 641 * 642 * @memberOf wp.heartbeat.prototype 643 * 644 * @returns {void} 582 645 */ 583 646 function connectNow() { … … 587 650 588 651 /** 589 * Disable suspending 590 * 591 * Should be used only when Heartbeat is performing critical tasks like autosave, post-locking, etc. 592 * Using this on many screens may overload the user's hosting account if several 593 * browser windows/tabs are left open for a long time. 594 * 595 * @return void 652 * Disables suspending. 653 * 654 * Should be used only when Heartbeat is performing critical tasks like 655 * autosave, post-locking, etc. Using this on many screens may overload the 656 * user's hosting account if several browser windows/tabs are left open for a 657 * long time. 658 * 659 * @since 3.8.0 660 * 661 * @memberOf wp.heartbeat.prototype 662 * 663 * @returns {void} 596 664 */ 597 665 function disableSuspend() { … … 600 668 601 669 /** 602 * Get/Set the interval 603 * 604 * When setting to 'fast' or 5, by default interval is 5 sec. for the next 30 ticks (for 2 min and 30 sec). 605 * In this case the number of 'ticks' can be passed as second argument. 606 * If the window doesn't have focus, the interval slows down to 2 min. 607 * 608 * @param mixed speed Interval: 'fast' or 5, 15, 30, 60, 120 609 * @param string ticks Used with speed = 'fast' or 5, how many ticks before the interval reverts back 610 * @return int Current interval in seconds 670 * Gets/Sets the interval. 671 * 672 * When setting to 'fast' or 5, the interval is 5 seconds for the next 30 ticks 673 * (for 2 minutes and 30 seconds) by default. In this case the number of 'ticks' 674 * can be passed as second argument. If the window doesn't have focus, the 675 * interval slows down to 2 min. 676 * 677 * @since 3.6.0 678 * 679 * @memberOf wp.heartbeat.prototype 680 * 681 * @param {string|number} speed Interval: 'fast' or 5, 15, 30, 60, 120. Fast 682 * equals 5. 683 * @param {string} ticks Tells how many ticks before the interval reverts 684 * back. Used with speed = 'fast' or 5. 685 * 686 * @returns {number} Current interval in seconds. 611 687 */ 612 688 function interval( speed, ticks ) { … … 668 744 669 745 /** 670 * Enqueue data to send with the next XHR 671 * 672 * As the data is send asynchronously, this function doesn't return the XHR response. 673 * To see the response, use the custom jQuery event 'heartbeat-tick' on the document, example: 746 * Enqueues data to send with the next XHR. 747 * 748 * As the data is send asynchronously, this function doesn't return the XHR 749 * response. To see the response, use the custom jQuery event 'heartbeat-tick' 750 * on the document, example: 674 751 * $(document).on( 'heartbeat-tick.myname', function( event, data, textStatus, jqXHR ) { 675 752 * // code 676 753 * }); 677 * If the same 'handle' is used more than once, the data is not overwritten when the third argument is 'true'. 678 * Use wp.heartbeat.isQueued('handle') to see if any data is already queued for that handle. 679 * 680 * $param string handle Unique handle for the data. The handle is used in PHP to receive the data. 681 * $param mixed data The data to send. 682 * $param bool noOverwrite Whether to overwrite existing data in the queue. 683 * $return bool Whether the data was queued or not. 754 * If the same 'handle' is used more than once, the data is not overwritten when 755 * the third argument is 'true'. Use `wp.heartbeat.isQueued('handle')` to see if 756 * any data is already queued for that handle. 757 * 758 * @since 3.6.0 759 * 760 * @memberOf wp.heartbeat.prototype 761 * 762 * @param {string} handle Unique handle for the data, used in PHP to 763 * receive the data. 764 * @param {*} data The data to send. 765 * @param {boolean} noOverwrite Whether to overwrite existing data in the queue. 766 * 767 * @returns {boolean} True if the data was queued. 684 768 */ 685 769 function enqueue( handle, data, noOverwrite ) { … … 696 780 697 781 /** 698 * Check if data with a particular handle is queued 699 * 700 * $param string handle The handle for the data 701 * $return bool Whether some data is queued with this handle 782 * Checks if data with a particular handle is queued. 783 * 784 * @since 3.6.0 785 * 786 * @param {string} handle The handle for the data. 787 * 788 * @returns {boolean} True if the data is queued with this handle. 702 789 */ 703 790 function isQueued( handle ) { … … 708 795 709 796 /** 710 * Remove data with a particular handle from the queue 711 * 712 * $param string handle The handle for the data 713 * $return void 797 * Removes data with a particular handle from the queue. 798 * 799 * @since 3.7.0 800 * 801 * @memberOf wp.heartbeat.prototype 802 * 803 * @param {string} handle The handle for the data. 804 * 805 * @returns {void} 714 806 */ 715 807 function dequeue( handle ) { … … 720 812 721 813 /** 722 * Get data that was enqueued with a particular handle 723 * 724 * $param string handle The handle for the data 725 * $return mixed The data or undefined 814 * Gets data that was enqueued with a particular handle. 815 * 816 * @since 3.7.0 817 * 818 * @memberOf wp.heartbeat.prototype 819 * 820 * @param {string} handle The handle for the data. 821 * 822 * @returns {*} The data or undefined. 726 823 */ 727 824 function getQueuedItem( handle ) { … … 733 830 initialize(); 734 831 735 // Expose public methods 832 // Expose public methods. 736 833 return { 737 834 hasFocus: hasFocus, … … 753 850 */ 754 851 window.wp = window.wp || {}; 852 853 /** 854 * Contains the Heartbeat API. 855 * 856 * @namespace wp.heartbeat 857 * @type {Heartbeat} 858 */ 755 859 window.wp.heartbeat = new Heartbeat(); 756 860
Note: See TracChangeset
for help on using the changeset viewer.