EBernhardson has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/379568 )

Change subject: Add js function setVisibleTimeout
......................................................................

Add js function setVisibleTimeout

Add a library function functionally similar to setTimeout that
only considers time when the page is visible. This is useful
both for analytics purposes, and when you want to temporarily
put something on screen and be reasonably certain it doesn't
go away until a user has seen it.

Change-Id: I7d8ea85602cae9cfc72e0155bc3092049ecafd43
---
M resources/Resources.php
A resources/src/mediawiki.libs/mediawiki.libs.visibleTimeout.js
2 files changed, 97 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/68/379568/1

diff --git a/resources/Resources.php b/resources/Resources.php
index 1ebe210..a24f56b 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -1635,6 +1635,11 @@
                'targets' => [ 'desktop', 'mobile' ],
        ],
 
+       'mediawiki.libs.visibleTimeout' => [
+               'scripts' => 
'resources/src/mediawiki.libs/mediawiki.libs.visibleTimeout.js',
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
+
        /* MediaWiki Page */
 
        'mediawiki.page.gallery' => [
diff --git a/resources/src/mediawiki.libs/mediawiki.libs.visibleTimeout.js 
b/resources/src/mediawiki.libs/mediawiki.libs.visibleTimeout.js
new file mode 100644
index 0000000..a1a0d7c
--- /dev/null
+++ b/resources/src/mediawiki.libs/mediawiki.libs.visibleTimeout.js
@@ -0,0 +1,92 @@
+( function ( mw, undefined ) {
+       var hidden, visibilityChange,
+               nextVisibleTimeoutId = 0,
+               activeTimeouts = {};
+
+       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 after visible timeout has 
expired.
+        * @param {number} delay The number of ms the page should be visible 
before
+        *  calling fn.
+        */
+       mw.libs.setVisibleTimeout = function ( fn, delay ) {
+               var handleVisibilityChange,
+                       timeoutId = null,
+                       visibleTimeoutId = nextVisibleTimeoutId++,
+                       lastStartedAt = new Date().getTime(),
+                       clearVisibleTimeout = function () {
+                               if ( timeoutId !== null ) {
+                                       clearTimeout( timeoutId );
+                                       timeoutId = null;
+                               }
+                               delete activeTimeouts[visibleTimeoutId];
+                               if ( hidden !== undefined ) {
+                                       document.removeEventListener( 
visibilityChange, handleVisibilityChange, false );
+                               }
+                       },
+                       onComplete = function () {
+                               clearVisibleTimeout();
+                               fn();
+                       };
+
+               handleVisibilityChange = function () {
+                       var now = new Date().getTime();
+
+                       if ( document[ hidden ] ) {
+                               // pause timeout if running
+                               if ( timeoutId !== null ) {
+                                       delay = Math.max( 0, delay - Math.max( 
0, now - lastStartedAt ) );
+                                       if ( delay === 0 ) {
+                                               onComplete();
+                                       } else {
+                                               clearTimeout( timeoutId );
+                                               timeoutId = null;
+                                       }
+                               }
+                       } else {
+                               // resume timeout if not running
+                               if ( timeoutId === null ) {
+                                       lastStartedAt = now;
+                                       timeoutId = setTimeout( onComplete, 
delay );
+                               }
+                       }
+               };
+
+               activeTimeouts[visibleTimeoutId] = clearVisibleTimeout;
+               if ( hidden !== undefined ) {
+                       document.addEventListener( visibilityChange, 
handleVisibilityChange, false );
+               }
+               handleVisibilityChange();
+
+               return visibleTimeoutId;
+       };
+
+       /**
+        * Cancel a visible timeout previously established by calling 
setVisibleTimeout.
+        * Passing an invalid ID silently does nothing.
+        *
+        * @param {number} visibleTimeoutId The identifier of the visible 
timeout you want
+        *  to cancel. This ID was returned by the corresponding call to 
setVisibleTimeout().
+        */
+       mw.libs.clearVisibleTimeout = function ( visibleTimeoutId ) {
+               if ( activeTimeouts.hasOwnProperty( visibleTimeoutId ) ) {
+                       activeTimeouts[visibleTimeoutId]();
+               }
+       };
+}( mediaWiki ) );

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7d8ea85602cae9cfc72e0155bc3092049ecafd43
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: EBernhardson <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to