Ori.livneh has uploaded a new change for review.
https://gerrit.wikimedia.org/r/99547
Change subject: mediawiki.js: add `mw.track`, imported from VisualEditor
......................................................................
mediawiki.js: add `mw.track`, imported from VisualEditor
`mw.track` implements a topic-based message broker / event bus for JavaScript
code. Its distinguishing characteristic is that subscribers are called with
each event that matches their topic filter, including any events that fired
before the subscriber registered. This allows code to be instrumented to report
performance data without having to know anything about subscribers, and it
makes it trivial to attach MediaWiki events to any event logging system -- not
just EventLogging, but also Google Analytics, New Relic, etc., which is a
compelling feature for third-party users.
The implementation is ported from VisualEditor, where it was introduced in
change I29740fa7a and subsequently refined. I did not port
`ve.trackSubscribeAll`, since it is syntactic sugar for calling
`ve.trackSubscribe` with the empty string as a subscription. It made sense to
have a wrapper for VE, since registering a handler for all VE events is a
credible use-case, but it seems less legitimate if `track` is expanded to the
entire MediaWiki ecosystem.
Change-Id: I8c7af097e6a9b2781ba3d6625d1132b7788ce8da
---
M resources/mediawiki/mediawiki.js
1 file changed, 66 insertions(+), 1 deletion(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/47/99547/1
diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js
index 724ca5e..4b3272a 100644
--- a/resources/mediawiki/mediawiki.js
+++ b/resources/mediawiki/mediawiki.js
@@ -12,7 +12,9 @@
/* Private Members */
var hasOwn = Object.prototype.hasOwnProperty,
- slice = Array.prototype.slice;
+ slice = Array.prototype.slice,
+ trackCallbacks = $.Callbacks( 'memory' ),
+ trackQueue = [];
/**
* Log a message to window.console, if possible. Useful to force
logging of some
@@ -326,6 +328,69 @@
/* Public Members */
/**
+ * Get the current time, measured in milliseconds since January
1, 1970 (UTC).
+ *
+ * On browsers that implement the Navigation Timing API, this
function will produce floating-point
+ * values with microsecond precision that are guaranteed to be
monotonic. On all other browsers,
+ * it will fall back to using `Date.now`.
+ *
+ * @returns {number} Current time
+ */
+ now: ( function () {
+ var perf = window.performance,
+ navStart = perf && perf.timing &&
perf.timing.navigationStart;
+ return navStart && typeof perf.now === 'function' ?
+ function () { return navStart + perf.now(); } :
Date.now;
+ }() ),
+
+ /**
+ * Track an analytic event.
+ *
+ * This method provides a generic means for MediaWiki
JavaScript code to capture state
+ * information for analysis. Each logged event specifies a
string topic name that describes
+ * the kind of event that it is. Topic names consist of
dot-separated path components,
+ * arranged from most general to most specific. Each path
component should have a clear and
+ * well-defined purpose.
+ *
+ * Data handlers are registered via `mw.trackSubscribe`, and
receive the full set of
+ * events that match their subcription, including those that
fired before the handler was
+ * bound.
+ *
+ * @param {string} topic Topic name
+ * @param {Object} [data] Data describing the event, encoded as
an object
+ */
+ track: function ( topic, data ) {
+ trackQueue.push( { topic: topic, timeStamp: mw.now(),
data: data } );
+ trackCallbacks.fire( trackQueue );
+ },
+
+ /**
+ * Register a handler for subset of analytic events, specified
by topic
+ *
+ * Handlers will be called once for each tracked event,
including any events that fired before the
+ * handler was registered; 'this' is set to a plain object with
a 'timeStamp' property indicating
+ * the exact time at which the event fired, a string 'topic'
property naming the event, and a
+ * 'data' property which is an object of event-specific data.
The event topic and event data are
+ * also passed to the callback as the first and second
arguments, respectively.
+ *
+ * @param {string} topic Handle events whose name starts with
this string prefix
+ * @param {Function} callback Handler to call for each matching
tracked event
+ */
+ trackSubscribe: function ( topic, callback ) {
+ var seen = 0;
+
+ trackCallbacks.add( function ( trackQueue ) {
+ var event;
+ for ( ; seen < trackQueue.length; seen++ ) {
+ event = trackQueue[ seen ];
+ if ( event.topic.indexOf( topic ) === 0
) {
+ callback.call( event,
event.topic, event.data );
+ }
+ }
+ } );
+ },
+
+ /**
* Dummy placeholder for {@link mw.log}
* @method
*/
--
To view, visit https://gerrit.wikimedia.org/r/99547
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8c7af097e6a9b2781ba3d6625d1132b7788ce8da
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Ori.livneh <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits