Create reading depth schema defined as time spent per page.
==Acceptance Criteria
Create [[https://meta.wikimedia.org/wiki/Schema:ReadingDepth | reading depth schema]] which includes the following as defined within the [[https://meta.wikimedia.org/wiki/Schema:Popups |Popups schema]]:
- `pageTitleSource`
- `namespaceIdSource`
- `pageToken`
- `sessionToken`
- `isAnon`
- (new) `skin`
- actions:
-- `pageLoaded`
-- (new) `pageUnloaded`
As well as (only for the `pageUnloaded` action):
- `totalLength` - interval of time during which article was open (strictly, from first paint to current time).
- `visibleLength` - interval of time during which article was open and visible. Pause timer based on visibility:
- Start the timer when the page is visible.
- Pause the timer when the visibility changes to "hidden" or "unknown".
- When the page has loaded and is visible then start the timer; otherwise, pause the timer.
- `firstPaint` (same as in [[https://meta.wikimedia.org/wiki/Schema:NavigationTiming | NavigationTiming]])
- `domInteractive` (same as in [[https://meta.wikimedia.org/wiki/Schema:NavigationTiming | NavigationTiming]])
---
* An event is only logged if the UA is `sendBeacon`-capable
* A single event is logged with the above information when the user navigates away from the page or closes it.
** i.e. Log an event in an `onbeforeunload` event handler using `sendBeacon`.
* The sampling rate is configurable, default to 0.005%
* This is behind a feature flag.
* This is implemented in the [WikimediaEvents extension](https://www.mediawiki.org/wiki/Extension:WikimediaEvents).
NOTE: browsers which do not support visibility will be paused throughout - these will be filtered out in analysis.
== Implementation Notes
This implementation of reading depth instrumentation should be the source of truth for the page and session tokens in Reading-maintained extensions. This is so that the Page Previews instrumentation, for example, can be tied to the reading depth instrumentation.
```name=page_previews.js,lang=js
function logEvent( data ) {
var readingInstrumentationService = mw.reading.instrumentation;
if ( instrumentation.isUserInSample() ) {
// Instrumentation#getBaseEventData would returns an object that includes the page and session tokens.
data = $.extend( true, {}, instrumentation.getBaseEventData(), data );
mw.track( 'event.Popups', data );
}
}
```