mediawiki.log: Move #warn and #deprecate to mediawiki.js and add tracking
authorTimo Tijhof <krinklemail@gmail.com>
Fri, 7 Feb 2014 02:36:53 +0000 (18:36 -0800)
committerOri.livneh <ori@wikimedia.org>
Wed, 19 Feb 2014 18:57:34 +0000 (18:57 +0000)
* Moved #warn and #deprecate from mediawiki.log.js (only loaded
  in debug mode) to main mediawiki.js.
  This means warnings will now be available in the console at all
  times instead of only when the user (re)loaded the page in
  ResourceLoader's debug mode. Deprecation notices are generally
  useful and should be discoverable from the console (just like
  notices from the browser itself for JS and CSS).
  It doesn't affect user experience as the notices invisible to
  the page and sent to an appropiate view (e.g. developer console).
  Our console emulator (the HTML-based  one, like Firebug Lite)
  remains exclusively loaded in debug mode.

* Start tracking usage via mw.track.
  For example, calls to mw.user.wikiGetlink, will be tracked as:
  { topic: "mw.deprecate", data: "wikiGetlink" }
  As all tracking, this isn't sent or stored anywhere by default.
  Extensions, hooks and other scripts can subscribe and actually
  log them (i.e. WikimediaEvents extension).

Also:

* Fixed odd tab between 'var' and 'args' in mediawiki.log.js

* Added minor optimisation by using a single local lookup for slice
  instead of three properties deep from a global variable lookup.

* Moved down code for mw.log in mediawiki.js so that we don't
  mix nested classes (mw.log#...) between other sibling methods
  of mw itself. This also simplifies the documentation by using
  jsduck's linear @class context.

* Simplify console && console.log check in mediawiki.log.js polyfil.

Change-Id: I67737de5abe0d655091fbe453a3b924f5068308c

resources/mediawiki/mediawiki.js
resources/mediawiki/mediawiki.log.js

index bf2cf4c..8b78370 100644 (file)
@@ -438,19 +438,6 @@ var mw = ( function ( $, undefined ) {
                        } );
                },
 
-               /**
-                * Dummy placeholder for {@link mw.log}
-                * @method
-                */
-               log: ( function () {
-                       var log = function () {};
-                       log.warn = function () {};
-                       log.deprecate = function ( obj, key, val ) {
-                               obj[key] = val;
-                       };
-                       return log;
-               }() ),
-
                // Make the Map constructor publicly available.
                Map: Map,
 
@@ -528,6 +515,75 @@ var mw = ( function ( $, undefined ) {
                        return mw.message.apply( mw.message, arguments ).toString();
                },
 
+               /**
+                * Dummy placeholder for {@link mw.log}
+                * @method
+                */
+               log: ( function () {
+                       // Also update the restoration of methods in mediawiki.log.js
+                       // when adding or removing methods here.
+                       var log = function () {};
+
+                       /**
+                        * @class mw.log
+                        * @singleton
+                        */
+
+                       /**
+                        * Write a message the console's warning channel.
+                        * Also logs a stacktrace for easier debugging.
+                        * Each action is silently ignored if the browser doesn't support it.
+                        *
+                        * @param {string...} msg Messages to output to console
+                        */
+                       log.warn = function () {
+                               var console = window.console;
+                               if ( console && console.warn ) {
+                                       console.warn.apply( console, arguments );
+                                       if ( console.trace ) {
+                                               console.trace();
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Create a property in a host object that, when accessed, will produce
+                        * a deprecation warning in the console with backtrace.
+                        *
+                        * @param {Object} obj Host object of deprecated property
+                        * @param {string} key Name of property to create in `obj`
+                        * @param {Mixed} val The value this property should return when accessed
+                        * @param {string} [msg] Optional text to include in the deprecation message.
+                        */
+                       log.deprecate = !Object.defineProperty ? function ( obj, key, val ) {
+                               obj[key] = val;
+                       } : function ( obj, key, val, msg ) {
+                               msg = 'MWDeprecationWarning: Use of "' + key + '" property is deprecated.' +
+                                       ( msg ? ( ' ' + msg ) : '' );
+                               try {
+                                       Object.defineProperty( obj, key, {
+                                               configurable: true,
+                                               enumerable: true,
+                                               get: function () {
+                                                       mw.track( 'mw.deprecate', key );
+                                                       log.warn( msg );
+                                                       return val;
+                                               },
+                                               set: function ( newVal ) {
+                                                       mw.track( 'mw.deprecate', key );
+                                                       log.warn( msg );
+                                                       val = newVal;
+                                               }
+                                       } );
+                               } catch ( err ) {
+                                       // IE8 can throw on Object.defineProperty
+                                       obj[key] = val;
+                               }
+                       };
+
+                       return log;
+               }() ),
+
                /**
                 * Client-side module loader which integrates with the MediaWiki ResourceLoader
                 * @class mw.loader
index 75e4c96..dd22e35 100644 (file)
@@ -8,28 +8,32 @@
 
 ( function ( mw, $ ) {
 
-       /**
-        * @class mw.log
-        * @singleton
-        */
+       // Reference to dummy
+       // We don't need the dummy, but it has other methods on it
+       // that we need to restore afterwards.
+       var original = mw.log,
+               slice = Array.prototype.slice;
 
        /**
-        * Logs a message to the console.
+        * Logs a message to the console in debug mode.
         *
         * In the case the browser does not have a console API, a console is created on-the-fly by appending
         * a `<div id="mw-log-console">` element to the bottom of the body and then appending this and future
         * messages to that, instead of the console.
         *
+        * @member mw.log
         * @param {string...} msg Messages to output to console.
         */
        mw.log = function () {
                // Turn arguments into an array
-               var     args = Array.prototype.slice.call( arguments ),
+               var args = slice.call( arguments ),
                        // Allow log messages to use a configured prefix to identify the source window (ie. frame)
                        prefix = mw.config.exists( 'mw.log.prefix' ) ? mw.config.get( 'mw.log.prefix' ) + '> ' : '';
 
                // Try to use an existing console
-               if ( window.console !== undefined && $.isFunction( window.console.log ) ) {
+               // Generally we can cache this, but in this case we want to re-evaluate this as a
+               // global property live so that things like Firebug Lite can take precedence.
+               if ( window.console && window.console.log ) {
                        args.unshift( prefix );
                        window.console.log.apply( window.console, args );
                        return;
                } );
        };
 
-       /**
-        * Write a message the console's warning channel.
-        * Also logs a stacktrace for easier debugging.
-        * Each action is silently ignored if the browser doesn't support it.
-        *
-        * @param {string...} msg Messages to output to console
-        */
-       mw.log.warn = function () {
-               var console = window.console;
-               if ( console && console.warn ) {
-                       console.warn.apply( console, arguments );
-                       if ( console.trace ) {
-                               console.trace();
-                       }
-               }
-       };
-
-       /**
-        * Create a property in a host object that, when accessed, will produce
-        * a deprecation warning in the console with backtrace.
-        *
-        * @param {Object} obj Host object of deprecated property
-        * @param {string} key Name of property to create in `obj`
-        * @param {Mixed} val The value this property should return when accessed
-        * @param {string} [msg] Optional text to include in the deprecation message.
-        */
-       mw.log.deprecate = !Object.defineProperty ? function ( obj, key, val ) {
-               obj[key] = val;
-       } : function ( obj, key, val, msg ) {
-               msg = 'MWDeprecationWarning: Use of "' + key + '" property is deprecated.' +
-                       ( msg ? ( ' ' + msg ) : '' );
-               try {
-                       Object.defineProperty( obj, key, {
-                               configurable: true,
-                               enumerable: true,
-                               get: function () {
-                                       mw.log.warn( msg );
-                                       return val;
-                               },
-                               set: function ( newVal ) {
-                                       mw.log.warn( msg );
-                                       val = newVal;
-                               }
-                       } );
-               } catch ( err ) {
-                       // IE8 can throw on Object.defineProperty
-                       obj[key] = val;
-               }
-       };
+       // Restore original methods
+       mw.log.warn = original.warn;
+       mw.log.deprecate = original.deprecate;
 
 }( mediaWiki, jQuery ) );