Optimized JavaScript activity in background tabs
authorAlexander Ebert <ebert@woltlab.com>
Wed, 11 Oct 2017 15:45:14 +0000 (17:45 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 11 Oct 2017 15:45:14 +0000 (17:45 +0200)
wcfsetup/install/files/js/WoltLabSuite/Core/Date/Time/Relative.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Redactor/Autosave.js

index 6e7355d2698c92325c74c8f7a8b2df3cbf510411..7d1cc8bfaa67e28a39c5faf81f8f24b304c729e3 100644 (file)
@@ -10,6 +10,8 @@ define(['Dom/ChangeListener', 'Language', 'WoltLabSuite/Core/Date/Util', 'WoltLa
        "use strict";
        
        var _elements = elByTag('time');
+       var _isActive = true;
+       var _isPending = false;
        var _offset = null;
        
        /**
@@ -25,12 +27,37 @@ define(['Dom/ChangeListener', 'Language', 'WoltLabSuite/Core/Date/Util', 'WoltLa
                        new Repeating(this._refresh.bind(this), 60000);
                        
                        DomChangeListener.add('WoltLabSuite/Core/Date/Time/Relative', this._refresh.bind(this));
+                       
+                       document.addEventListener('visibilitychange', this._onVisibilityChange.bind(this));
+               },
+               
+               _onVisibilityChange: function () {
+                       if (document.hidden) {
+                               _isActive = false;
+                               _isPending = false;
+                       }
+                       else {
+                               _isActive = true;
+                               
+                               // force immediate refresh
+                               if (_isPending) {
+                                       this._refresh();
+                                       _isPending = false;
+                               }
+                       }
                },
                
                _refresh: function() {
+                       // activity is suspended while the tab is hidden, but force an
+                       // immediate refresh once the page is active again
+                       if (!_isActive) {
+                               if (!_isPending) _isPending = true;
+                               return;
+                       }
+                       
                        var date = new Date();
                        var timestamp = (date.getTime() - date.getMilliseconds()) / 1000;
-                       if (_offset === null) _offset = timestamp - TIME_NOW;
+                       if (_offset === null) _offset = timestamp - window.TIME_NOW;
                        
                        for (var i = 0, length = _elements.length; i < length; i++) {
                                var element = _elements[i];
index c0fe0a815d44803304602c0c822cd1c70c27e5ca..5962535659d4844ec6326d6b946413e23ab7765d 100644 (file)
@@ -46,6 +46,8 @@ define(['Core', 'Devtools', 'EventHandler', 'Language', 'Dom/Traverse', './Metac
                        this._metaData = {};
                        this._editor = null;
                        this._element = element;
+                       this._isActive = true;
+                       this._isPending = false;
                        this._key = Core.getStoragePrefix() + elData(this._element, 'autosave');
                        this._lastMessage = '';
                        this._originalMessage = '';
@@ -74,6 +76,19 @@ define(['Core', 'Devtools', 'EventHandler', 'Language', 'Dom/Traverse', './Metac
                        
                        // clear editor content on reset
                        EventHandler.add('com.woltlab.wcf.redactor2', 'reset_' + this._element.id, this.hideOverlay.bind(this));
+                       
+                       document.addEventListener('visibilitychange', this._onVisibilityChange.bind(this));
+               },
+               
+               _onVisibilityChange: function () {
+                       if (document.hidden) {
+                               this._isActive = false;
+                               this._isPending = true;
+                       }
+                       else {
+                               this._isActive = true;
+                               this._isPending = false;
+                       }
                },
                
                /**
@@ -146,6 +161,8 @@ define(['Core', 'Devtools', 'EventHandler', 'Language', 'Dom/Traverse', './Metac
                        this._timer = window.setInterval(this._saveToStorage.bind(this), _frequency * 1000);
                        
                        this._saveToStorage();
+                       
+                       this._isPending = false;
                },
                
                /**
@@ -158,6 +175,7 @@ define(['Core', 'Devtools', 'EventHandler', 'Language', 'Dom/Traverse', './Metac
                        
                        window.clearInterval(this._timer);
                        this._timer = null;
+                       this._isPending = false;
                },
                
                /**
@@ -260,6 +278,13 @@ define(['Core', 'Devtools', 'EventHandler', 'Language', 'Dom/Traverse', './Metac
                 * @protected
                 */
                _saveToStorage: function() {
+                       if (!this._isActive) {
+                               if (!this._isPending) return;
+                               
+                               // save one last time before suspending
+                               this._isPending = false;
+                       }
+                       
                        //noinspection JSUnresolvedVariable
                        if (window.ENABLE_DEVELOPER_TOOLS && Devtools._internal_.editorAutosave() === false) {
                                //noinspection JSUnresolvedVariable