mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-29 16:44:51 +00:00
a232147b11
Change-Id: I75ac4b378ef485feead9d0eff34ed7877b94b5d0
226 lines
6.5 KiB
JavaScript
226 lines
6.5 KiB
JavaScript
/*!
|
|
* VisualEditor MediaWiki Initialization class.
|
|
*
|
|
* @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
*/
|
|
|
|
/**
|
|
* Initialization MediaWiki Target Analytics.
|
|
*
|
|
* @class
|
|
*
|
|
* @constructor
|
|
* @param {ve.init.mw.Target} target Target class to log events for
|
|
*/
|
|
ve.init.mw.TargetEvents = function ( target ) {
|
|
this.target = target;
|
|
this.timings = { saveRetries: 0 };
|
|
// Events
|
|
this.target.connect( this, {
|
|
saveWorkflowBegin: 'onSaveWorkflowBegin',
|
|
saveWorkflowEnd: 'onSaveWorkflowEnd',
|
|
saveInitiated: 'onSaveInitated',
|
|
save: 'onSaveComplete',
|
|
saveReview: 'onSaveReview',
|
|
saveErrorEmpty: 'onSaveErrorEmpty',
|
|
saveErrorSpamBlacklist: 'onSaveErrorSpamBlacklist',
|
|
saveErrorAbuseFilter: 'onSaveErrorAbuseFilter',
|
|
saveErrorBadToken: 'onSaveErrorBadToken',
|
|
saveErrorNewUser: 'onSaveErrorNewUser',
|
|
saveErrorCaptcha: 'onSaveErrorCaptcha',
|
|
saveErrorUnknown: 'onSaveErrorUnknown',
|
|
surfaceReady: 'onSurfaceReady',
|
|
editConflict: 'onEditConflict',
|
|
showChanges: 'onShowChanges',
|
|
showChangesError: 'onShowChangesError',
|
|
noChanges: 'onNoChanges',
|
|
serializeComplete: 'onSerializeComplete',
|
|
serializeError: 'onSerializeError'
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Target specific ve.track wrapper
|
|
*
|
|
* @param {string} topic Event name
|
|
* @param {Object} data Additional data describing the event, encoded as an object
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.track = function ( topic, data ) {
|
|
data.targetName = this.target.constructor.static.name;
|
|
ve.track( topic, data );
|
|
};
|
|
|
|
/**
|
|
* Track when user begins the save workflow
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveWorkflowBegin = function () {
|
|
this.timings.saveWorkflowBegin = ve.now();
|
|
this.track( 'behavior.lastTransactionTillSaveDialogOpen', {
|
|
duration: this.timings.saveWorkflowBegin - this.timings.lastTransaction
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Track when user ends the save workflow
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveWorkflowEnd = function () {
|
|
this.track( 'behavior.saveDialogClose', { duration: ve.now() - this.timings.saveWorkflowBegin } );
|
|
this.timings.saveWorkflowBegin = null;
|
|
};
|
|
|
|
/**
|
|
* Track when document save is initiated
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveInitated = function () {
|
|
this.timings.saveInitiated = ve.now();
|
|
this.timings.saveRetries++;
|
|
this.track( 'behavior.saveDialogOpenTillSave', {
|
|
duration: this.timings.saveInitiated - this.timings.saveWorkflowBegin
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Track when document save is complete
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveComplete = function () {
|
|
this.track( 'performance.user.saveComplete', { duration: ve.now() - this.timings.saveInitiated } );
|
|
this.timings.saveRetries = 0;
|
|
};
|
|
|
|
/**
|
|
* Track a save error by type
|
|
*
|
|
* @method
|
|
* @param {string} type Text for error type
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.trackSaveError = function ( type ) {
|
|
this.track( 'performance.user.saveError', {
|
|
duration: ve.now() - this.timings.saveInitiated,
|
|
retries: this.timings.saveRetries,
|
|
type: type
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Record the time of the last transaction in response to a 'transact' event on the document.
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.recordLastTransactionTime = function () {
|
|
this.timings.lastTransaction = ve.now();
|
|
};
|
|
|
|
/**
|
|
* Track time elapsed from beginning of save workflow to review
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveReview = function () {
|
|
this.timings.saveReview = ve.now();
|
|
this.track( 'behavior.saveDialogOpenTillReview', {
|
|
duration: this.timings.saveReview - this.timings.saveWorkflowBegin
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Track when save api returns no data
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveErrorEmpty = function () {
|
|
this.trackSaveError( 'empty' );
|
|
};
|
|
|
|
/**
|
|
* Track when spamblacklist save error occurs
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveErrorSpamBlacklist = function () {
|
|
this.trackSaveError( 'spamblacklist' );
|
|
};
|
|
|
|
/**
|
|
* Track when abusefilter save error occurs
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveErrorAbuseFilter = function () {
|
|
this.trackSaveError( 'abusefilter' );
|
|
};
|
|
|
|
/**
|
|
* Track when the save request requires a new edit token
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveErrorBadToken = function () {
|
|
this.trackSaveError( 'badtoken' );
|
|
};
|
|
|
|
/**
|
|
* Track when the save request detects a new user session
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveErrorNewUser = function () {
|
|
this.trackSaveError( 'newuser' );
|
|
};
|
|
|
|
/**
|
|
* Track when the save request requires about captcha
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveErrorCaptcha = function () {
|
|
this.trackSaveError( 'captcha' );
|
|
};
|
|
|
|
/**
|
|
* Track when save request has an unknown error
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSaveErrorUnknown = function () {
|
|
this.trackSaveError( 'unknown' );
|
|
};
|
|
|
|
ve.init.mw.TargetEvents.prototype.onSurfaceReady = function () {
|
|
this.track( 'performance.system.activation', { duration: ve.now() - this.timings.activationStart } );
|
|
this.target.surface.getModel().getDocument().connect( this, {
|
|
transact: 'recordLastTransactionTime'
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Track when save request results in an edit conflict
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onEditConflict = function () {
|
|
this.track( 'performance.user.saveError.editconflict', {
|
|
duration: ve.now() - this.timings.saveInitiated,
|
|
retries: this.timings.saveRetries
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Track when the user enters the review workflow
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onShowChanges = function () {
|
|
this.track( 'performance.user.reviewComplete', { duration: ve.now() - this.timings.saveReview } );
|
|
};
|
|
|
|
/**
|
|
* Track when the diff request fails in the review workflow
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onShowChangesError = function () {
|
|
this.track( 'performance.user.reviewError', { duration: ve.now() - this.timings.saveReview } );
|
|
};
|
|
|
|
/**
|
|
* Track when the diff request detects no changes
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onNoChanges = function () {
|
|
this.track( 'performance.user.reviewComplete', { duration: ve.now() - this.timings.saveReview } );
|
|
};
|
|
|
|
/**
|
|
* Track whe serilization is complete in review workflow
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSerializeComplete = function () {
|
|
this.track( 'performance.user.reviewComplete', { duration: ve.now() - this.timings.saveReview } );
|
|
};
|
|
|
|
/**
|
|
* Track when there is a serlization error
|
|
*/
|
|
ve.init.mw.TargetEvents.prototype.onSerializeError = function () {
|
|
if ( this.timings.saveWorkflowBegin ) {
|
|
// This function can be called by the switch to wikitext button as well, so only log
|
|
// reviewError if we actually got here from the save workflow
|
|
this.track( 'performance.user.reviewError', { duration: ve.now() - this.timings.saveReview } );
|
|
}
|
|
};
|