X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=resources%2Fmediawiki%2Fmediawiki.js;h=f3bb414703953151cf96e72af3c512661dd92a8c;hb=edb0cc8e1501304f92b74677bc7bd7b9f23b6f27;hp=7764beacb3533bd609c34ac0b3dd521cb0e47ade;hpb=32234445e06df7ba8f7508b16feff0a58d346348;p=lhc%2Fweb%2Fwiklou.git diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js index 7764beacb3..f3bb414703 100644 --- a/resources/mediawiki/mediawiki.js +++ b/resources/mediawiki/mediawiki.js @@ -12,7 +12,9 @@ var mw = ( function ( $, undefined ) { /* 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 @@ -325,6 +327,70 @@ var mw = ( function ( $, undefined ) { return { /* 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`. + * + * @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(); } : + function () { return +new Date(); }; + }() ), + + /** + * 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 @@ -1894,6 +1960,12 @@ var mw = ( function ( $, undefined ) { JSON.stringify( descriptor.style ), JSON.stringify( descriptor.messages ) ]; + // Attempted workaround for a possible Opera bug (bug 57567). + // This regex should never match under sane conditions. + if ( /^\s*\(/.test( args[1] ) ) { + args[1] = 'function' + args[1]; + log( 'Detected malformed function stringification (bug 57567)' ); + } } catch ( e ) { return; }