mediawiki-extensions-Popups/resources/ext.popups/checkin.js
Baha 4afa1958a0 Add reading depth
Use schema revision 16163887.

Add the 'checkin' action, which is accompanied by the 'checkin'
property. The action is logged at the following seconds
(Fibonacci numbers) after the page loads: 1, 2, 3, 5, 8, 13, 21,
34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765.
The `checkin` property contains the values listed above.

Bug: T147314
Change-Id: Ib9ec7bd0e60aa34a04e32222b025347f6ee31794
2016-12-21 15:08:20 -05:00

131 lines
3.8 KiB
JavaScript

( function ( mw, $ ) {
var pageVisibility = mw.popups.pageVisibility,
checkin = {
/**
* Checkin times - Fibonacci numbers
*
* Exposed for testing only.
*
* @type {number[]}
* @private
*/
CHECKIN_TIMES: [ 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,
377, 610, 987, 1597, 2584, 4181, 6765 ],
/**
* Have checkin actions been setup already?
*
* Exposed for testing only.
*
* @private
* @type {boolean}
*/
haveCheckinActionsBeenSetup: false
};
/**
* A customized `setTimeout` function that takes page visibility into account
*
* If the document is not visible to the user, e.g. browser window is minimized,
* then pause the time. Otherwise execute `callback` after `delay` milliseconds.
* The callback won't be executed if the browser does not suppor the page visibility
* API.
*
* Exposed for testing only.
*
* @see https://www.w3.org/TR/page-visibility/#dom-document-hidden
* @private
* @param {Function} callback Function to call when the time is up
* @param {number} delay The number of milliseconds to wait before executing the callback
*/
checkin.setVisibleTimeout = function ( callback, delay ) {
var hiddenPropertyName = pageVisibility.getDocumentHiddenPropertyName( document ),
visibilityChangeEventName = pageVisibility.getDocumentVisibilitychangeEventName( document ),
timeoutId,
lastStartedAt;
if ( !hiddenPropertyName || !visibilityChangeEventName ) {
return;
}
/**
* Execute the callback and turn off listening to the visibilitychange event
*/
function done() {
callback();
$( document ).off( visibilityChangeEventName, visibilityChangeHandler );
}
/**
* Pause or resume the timer depending on the page visibility state
*/
function visibilityChangeHandler() {
var millisecondsPassed;
// Pause the timer if the page is hidden ...
if ( pageVisibility.isDocumentHidden( document ) ) {
// ... and only if the timer has started.
// Timer may not have been started if the document opened in a
// hidden tab for example. The timer will be started when the
// document is visible to the user.
if ( lastStartedAt ) {
millisecondsPassed = new Date().getTime() - lastStartedAt;
delay = Math.max( 0, delay - millisecondsPassed );
clearTimeout( timeoutId );
}
} else {
lastStartedAt = new Date().getTime();
timeoutId = setTimeout( done, delay );
}
}
visibilityChangeHandler();
$( document ).on( visibilityChangeEventName, visibilityChangeHandler );
};
/**
* Perform the passed `checkin` action at the predefined times
*
* Actions are setup only once no matter how many times this function is
* called. Ideally this function should be called once.
*
* @see checkin.CHECKIN_TIMES
* @param {Function} checkinAction
*/
checkin.setupActions = function( checkinAction ) {
var timeIndex = 0,
timesLength = checkin.CHECKIN_TIMES.length,
time, // current checkin time
nextTime; // the checkin time that will be logged next
if ( checkin.haveCheckinActionsBeenSetup ) {
return;
}
/**
* Execute the checkin action with the current checkin time
*
* If more checkin times are left, then setup a timer to log the next one.
*/
function setup() {
time = checkin.CHECKIN_TIMES[ timeIndex ];
checkinAction( time );
timeIndex += 1;
if ( timeIndex < timesLength ) {
nextTime = checkin.CHECKIN_TIMES[ timeIndex ];
// Execute the callback after the number of seconds left till the
// next checkin time.
checkin.setVisibleTimeout( setup, ( nextTime - time ) * 1000 );
}
}
checkin.setVisibleTimeout( setup, checkin.CHECKIN_TIMES[ timeIndex ] * 1000 );
checkin.haveCheckinActionsBeenSetup = true;
};
mw.popups.checkin = checkin;
}( mediaWiki, jQuery ) );