jenkins-bot has submitted this change and it was merged.

Change subject: Take page visibility into account for search checkins
......................................................................


Take page visibility into account for search checkins

The page visibility api should let us get a slightly better look at how
long users are actually looking at the page. caniuse.com reports this
is supported in >90% of browsers wordwide.

Page visibility isn't a 100% match to what we need. To accommodate
accessibility tools the page visibility spec allows for browsers to 
consider being obscured by other apps to still be "visible", but this
is still an improvement from where we are today. Specifically background
tabs, or pages visible on a locked machine, are no longer considered 
active for the purpose of checkins.

Bug: T145102
Change-Id: Ib093f0cb411a4ef45d4996c966c90bf1691497b3
---
M modules/ext.wikimediaEvents.searchSatisfaction.js
1 file changed, 70 insertions(+), 4 deletions(-)

Approvals:
  Jdrewniak: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/modules/ext.wikimediaEvents.searchSatisfaction.js 
b/modules/ext.wikimediaEvents.searchSatisfaction.js
index 12777e2..c61cd98 100644
--- a/modules/ext.wikimediaEvents.searchSatisfaction.js
+++ b/modules/ext.wikimediaEvents.searchSatisfaction.js
@@ -213,7 +213,8 @@
        }
 
        /**
-        * Executes an action at the given times.
+        * Executes an action at or after the page has been visible the 
specified
+        * number of seconds.
         *
         * @param {number[]} checkinTimes Times (in seconds from start) when the
         *  action should be executed.
@@ -221,8 +222,73 @@
         * @private
         */
        function interval( checkinTimes, fn ) {
-               var checkin = checkinTimes.shift(),
+               var hidden, visibilityChange,
+                       checkin = checkinTimes.shift(),
                        timeout = checkin;
+
+               if ( document.hidden !== undefined ) {
+                       hidden = 'hidden';
+                       visibilityChange = 'visibilitychange';
+               } else if ( document.mozHidden !== undefined ) {
+                       hidden = 'mozHidden';
+                       visibilityChange = 'mozvisibilitychange';
+               } else if ( document.msHidden !== undefined ) {
+                       hidden = 'msHidden';
+                       visibilityChange = 'msvisibilitychange';
+               } else if ( document.webkitHidden !== undefined ) {
+                       hidden = 'webkitHidden';
+                       visibilityChange = 'webkitvisibilitychange';
+               }
+
+               /**
+                * Generally similar to setTimeout, but turns itself on/off on 
page
+                * visibility changes.
+                *
+                * @param {Function} fn The action to execute
+                * @param {number} delay The number of ms the page should be 
visible before
+                *  calling fn
+                * @private
+                */
+               function setVisibleTimeout( fn, delay ) {
+                       var handleVisibilityChange,
+                               timeoutId = null,
+                               lastStartedAt = 0,
+                               onComplete = function () {
+                                       timeoutId = null;
+                                       if ( document.removeEventListener ) {
+                                               document.removeEventListener( 
visibilityChange, handleVisibilityChange, false );
+                                       }
+                                       fn();
+                               };
+
+                       handleVisibilityChange = function () {
+                               var now = new Date().getTime();
+
+                               if ( document[ hidden ] ) {
+                                       // pause timeout if running
+                                       if ( timeoutId !== null ) {
+                                               // Subtract the amount of time 
we have waited so far.
+                                               delay = Math.max( 0, delay - 
Math.max( 0, now - lastStartedAt ) );
+                                               clearTimeout( timeoutId );
+                                               timeoutId = null;
+                                               if ( delay === 0 ) {
+                                                       onComplete();
+                                               }
+                                       }
+                               } else {
+                                       // resume timeout if not running
+                                       if ( timeoutId === null ) {
+                                               lastStartedAt = now;
+                                               timeoutId = setTimeout( 
onComplete, delay );
+                                       }
+                               }
+                       };
+
+                       if ( hidden !== undefined && document.addEventListener 
) {
+                               document.addEventListener( visibilityChange, 
handleVisibilityChange, false );
+                       }
+                       handleVisibilityChange();
+               }
 
                function action() {
                        var current = checkin;
@@ -231,11 +297,11 @@
                        checkin = checkinTimes.shift();
                        if ( checkin ) {
                                timeout = checkin - current;
-                               setTimeout( action, 1000 * timeout );
+                               setVisibleTimeout( action, 1000 * timeout );
                        }
                }
 
-               setTimeout( action, 1000 * timeout );
+               setVisibleTimeout( action, 1000 * timeout );
        }
 
        /**

-- 
To view, visit https://gerrit.wikimedia.org/r/311844
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib093f0cb411a4ef45d4996c966c90bf1691497b3
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/WikimediaEvents
Gerrit-Branch: master
Gerrit-Owner: EBernhardson <ebernhard...@wikimedia.org>
Gerrit-Reviewer: Jdrewniak <jdrewn...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to