Krinkle has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/312557

Change subject: resourceloader: Deprecate mw.Map
......................................................................

resourceloader: Deprecate mw.Map

This has never been used outside mediawiki.js for things like mw.config,
and mw.messages.

The public API of those objects will remain, but the constructor will
no longer be supported in the future in order to allow these to be
backed by native Map in the future (with a minimal polyfill rather than
a complete one).

* Remove 'mw.Map(valuesObject)'. (follows-up 63f8d7b9e5).
  This is incompatible with native Map and isn't actually used anywhere.

* Deprecate mw.Map#values. Undocumented and considered private.
  A few uses have appeared in the wild so keep a short deprecation period.

* Update the MediaWiki QUnit runner to construct new maps in setup/teardown
  instead of swapping the internal values object directly.
  Also update the runner to update mediawiki.jqueryMsg's parser default since
  it kept a reference to the first mw.messages object.

* Add 'logName' parameter to mw.log.deprecate(). Default logName
  of property key made sense for its original use case (deprecation warnings
  for global variables, which are a property of the window object). But
  for keys of any other object, we'll want to some context for the name.

* Remove redundant test expect numbers. (Follows-up 7c36375, c4c7007d)

Bug: T146432
Change-Id: I7ff0b230608f5ca582fc6752b59c4bb998c78ba2
---
M resources/src/mediawiki/mediawiki.js
M tests/qunit/data/testrunner.js
M tests/qunit/suites/resources/mediawiki/mediawiki.test.js
3 files changed, 63 insertions(+), 65 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/57/312557/1

diff --git a/resources/src/mediawiki/mediawiki.js 
b/resources/src/mediawiki/mediawiki.js
index de2b8ee..6237391 100644
--- a/resources/src/mediawiki/mediawiki.js
+++ b/resources/src/mediawiki/mediawiki.js
@@ -66,48 +66,20 @@
        }() );
 
        /**
-        * Create an object that can be read from or written to from methods 
that allow
+        * Create an object that can be read from or written to via methods 
that allow
         * interaction both with single and multiple properties at once.
         *
-        *     @example
-        *
-        *     var collection, query, results;
-        *
-        *     // Create your address book
-        *     collection = new mw.Map();
-        *
-        *     // This data could be coming from an external source (eg. 
API/AJAX)
-        *     collection.set( {
-        *         'John Doe': '[email protected]',
-        *         'Jane Doe': '[email protected]',
-        *         'George van Halen': '[email protected]'
-        *     } );
-        *
-        *     wanted = ['John Doe', 'Jane Doe', 'Daniel Jackson'];
-        *
-        *     // You can detect missing keys first
-        *     if ( !collection.exists( wanted ) ) {
-        *         // One or more are missing (in this case: "Daniel Jackson")
-        *         mw.log( 'One or more names were not found in your address 
book' );
-        *     }
-        *
-        *     // Or just let it give you what it can. Optionally fill in from 
a default.
-        *     results = collection.get( wanted, '[email protected]' );
-        *     mw.log( results['Jane Doe'] ); // "[email protected]"
-        *     mw.log( results['Daniel Jackson'] ); // "[email protected]"
-        *
+        * @private
         * @class mw.Map
         *
         * @constructor
-        * @param {Object|boolean} [values] The value-baring object to be 
mapped. Defaults to an
-        *  empty object.
-        *  For backwards-compatibility with mw.config, this can also be `true` 
in which case values
-        *  are copied to the Window object as global variables (T72470). 
Values are copied in
-        *  one direction only. Changes to globals are not reflected in the map.
+        * @param {boolean} [global=false] Whether to synchronise =values to 
the global
+        *  window object (for backwards-compatibility with mw.config; T72470). 
Values are
+        *  copied in one direction only. Changes to globals do not reflect in 
the map.
         */
-       function Map( values ) {
-               if ( values === true ) {
-                       this.values = {};
+       function Map( global ) {
+               this.internalValues = {};
+               if ( global === true ) {
 
                        // Override #set to also set the global variable
                        this.set = function ( selection, value ) {
@@ -129,7 +101,14 @@
                        return;
                }
 
-               this.values = values || {};
+               // Deprecated since MediaWiki 1.28
+               log.deprecate(
+                       this,
+                       'values',
+                       this.internalValues,
+                       'mw.Map#values is deprecated. Use mw.Map#get() 
instead.',
+                       'Map-values'
+               );
        }
 
        /**
@@ -142,8 +121,8 @@
         * @param {Mixed} value
         */
        function setGlobalMapValue( map, key, value ) {
-               map.values[ key ] = value;
-               mw.log.deprecate(
+               map.internalValues[ key ] = value;
+               log.deprecate(
                                window,
                                key,
                                value,
@@ -153,6 +132,8 @@
        }
 
        Map.prototype = {
+               constructor: Map,
+
                /**
                 * Get the value of one or more keys.
                 *
@@ -162,7 +143,7 @@
                 * @param {Mixed} [fallback=null] Value for keys that don't 
exist.
                 * @return {Mixed|Object| null} If selection was a string, 
returns the value,
                 *  If selection was an array, returns an object of key/values.
-                *  If no selection is passed, the 'values' container is 
returned. (Beware that,
+                *  If no selection is passed, the internal container is 
returned. (Beware that,
                 *  as is the default in JavaScript, the object is returned by 
reference.)
                 */
                get: function ( selection, fallback ) {
@@ -181,14 +162,14 @@
                        }
 
                        if ( typeof selection === 'string' ) {
-                               if ( !hasOwn.call( this.values, selection ) ) {
+                               if ( !hasOwn.call( this.internalValues, 
selection ) ) {
                                        return fallback;
                                }
-                               return this.values[ selection ];
+                               return this.internalValues[ selection ];
                        }
 
                        if ( selection === undefined ) {
-                               return this.values;
+                               return this.internalValues;
                        }
 
                        // Invalid selection key
@@ -207,12 +188,12 @@
 
                        if ( $.isPlainObject( selection ) ) {
                                for ( s in selection ) {
-                                       this.values[ s ] = selection[ s ];
+                                       this.internalValues[ s ] = selection[ s 
];
                                }
                                return true;
                        }
                        if ( typeof selection === 'string' && arguments.length 
> 1 ) {
-                               this.values[ selection ] = value;
+                               this.internalValues[ selection ] = value;
                                return true;
                        }
                        return false;
@@ -229,13 +210,13 @@
 
                        if ( $.isArray( selection ) ) {
                                for ( s = 0; s < selection.length; s++ ) {
-                                       if ( typeof selection[ s ] !== 'string' 
|| !hasOwn.call( this.values, selection[ s ] ) ) {
+                                       if ( typeof selection[ s ] !== 'string' 
|| !hasOwn.call( this.internalValues, selection[ s ] ) ) {
                                                return false;
                                        }
                                }
                                return true;
                        }
-                       return typeof selection === 'string' && hasOwn.call( 
this.values, selection );
+                       return typeof selection === 'string' && hasOwn.call( 
this.internalValues, selection );
                }
        };
 
@@ -475,11 +456,14 @@
                 * @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
+                * @param {string} [logName=key] Optional custom name for the 
feature.
+                *  This is used instead of `key` in the message and 
`mw.deprecate` tracking.
                 */
-               log.deprecate = !Object.defineProperty ? function ( obj, key, 
val, msg ) {
+               log.deprecate = !Object.defineProperty ? function ( obj, key, 
val, msg, logName ) {
                        obj[ key ] = val;
-               } : function ( obj, key, val, msg ) {
-                       msg = 'Use of "' + key + '" is deprecated.' + ( msg ? ( 
' ' + msg ) : '' );
+               } : function ( obj, key, val, msg, logName ) {
+                       logName = logName || key;
+                       msg = 'Use of "' + logName + '" is deprecated.' + ( msg 
? ( ' ' + msg ) : '' );
                        var logged = new StringSet();
                        function uniqueTrace() {
                                var trace = new Error().stack;
@@ -494,14 +478,14 @@
                                enumerable: true,
                                get: function () {
                                        if ( uniqueTrace() ) {
-                                               mw.track( 'mw.deprecate', key );
+                                               mw.track( 'mw.deprecate', 
logName );
                                                mw.log.warn( msg );
                                        }
                                        return val;
                                },
                                set: function ( newVal ) {
                                        if ( uniqueTrace() ) {
-                                               mw.track( 'mw.deprecate', key );
+                                               mw.track( 'mw.deprecate', 
logName );
                                                mw.log.warn( msg );
                                        }
                                        val = newVal;
diff --git a/tests/qunit/data/testrunner.js b/tests/qunit/data/testrunner.js
index 79f37dc..b79c192 100644
--- a/tests/qunit/data/testrunner.js
+++ b/tests/qunit/data/testrunner.js
@@ -167,10 +167,11 @@
         */
        QUnit.newMwEnvironment = ( function () {
                var warn, error, liveConfig, liveMessages,
+                       MwMap = mw.config.constructor, // internal use only
                        ajaxRequests = [];
 
-               liveConfig = mw.config.values;
-               liveMessages = mw.messages.values;
+               liveConfig = mw.config;
+               liveMessages = mw.messages;
 
                function suppressWarnings() {
                        warn = mw.log.warn;
@@ -198,14 +199,14 @@
                        // NOTE: It is important that we suppress warnings 
because extend() will also access
                        // deprecated properties and trigger deprecation 
warnings from mw.log#deprecate.
                        suppressWarnings();
-                       copy = $.extend( {}, liveConfig, custom );
+                       copy = $.extend( {}, liveConfig.get(), custom );
                        restoreWarnings();
 
                        return copy;
                }
 
                function freshMessagesCopy( custom ) {
-                       return $.extend( /*deep=*/true, {}, liveMessages, 
custom );
+                       return $.extend( /*deep=*/true, {}, liveMessages.get(), 
custom );
                }
 
                /**
@@ -231,8 +232,15 @@
                                setup: function () {
 
                                        // Greetings, mock environment!
-                                       mw.config.values = freshConfigCopy( 
localEnv.config );
-                                       mw.messages.values = freshMessagesCopy( 
localEnv.messages );
+                                       mw.config = new MwMap();
+                                       mw.config.set( freshConfigCopy( 
localEnv.config ) );
+                                       mw.messages = new MwMap();
+                                       mw.messages.set( freshMessagesCopy( 
localEnv.messages ) );
+                                       // Update reference to mw.messages
+                                       mw.jqueryMsg.setParserDefaults( {
+                                               messages: mw.messages
+                                       } );
+
                                        this.suppressWarnings = 
suppressWarnings;
                                        this.restoreWarnings = restoreWarnings;
 
@@ -251,8 +259,12 @@
                                        $( document ).off( 'ajaxSend', 
trackAjax );
 
                                        // Farewell, mock environment!
-                                       mw.config.values = liveConfig;
-                                       mw.messages.values = liveMessages;
+                                       mw.config = liveConfig;
+                                       mw.messages = liveMessages;
+                                       // Restore reference to mw.messages
+                                       mw.jqueryMsg.setParserDefaults( {
+                                               messages: liveMessages
+                                       } );
 
                                        // As a convenience feature, 
automatically restore warnings if they're
                                        // still suppressed by the end of the 
test.
diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.test.js 
b/tests/qunit/suites/resources/mediawiki/mediawiki.test.js
index ab463a9..1f24a26 100644
--- a/tests/qunit/suites/resources/mediawiki/mediawiki.test.js
+++ b/tests/qunit/suites/resources/mediawiki/mediawiki.test.js
@@ -65,10 +65,13 @@
                );
        } );
 
-       QUnit.test( 'mw.Map', 35, function ( assert ) {
+       QUnit.test( 'mw.Map', function ( assert ) {
                var arry, conf, funky, globalConf, nummy, someValues;
 
+               this.suppressWarnings();
                conf = new mw.Map();
+               this.restoreWarnings();
+
                // Dummy variables
                funky = function () {};
                arry = [];
@@ -126,15 +129,15 @@
                        lorem: 'ipsum'
                }, 'Map.get returns multiple values correctly as an object' );
 
-               assert.deepEqual( conf, new mw.Map( conf.values ), 'new mw.Map 
maps over existing values-bearing object' );
-
                assert.deepEqual( conf.get( [ 'foo', 'notExist' ] ), {
                        foo: 'bar',
                        notExist: null
                }, 'Map.get return includes keys that were not found as null 
values' );
 
                // Interacting with globals and accessing the values object
+               this.suppressWarnings();
                assert.strictEqual( conf.get(), conf.values, 'Map.get returns 
the entire values object by reference (if called without arguments)' );
+               this.restoreWarnings();
 
                conf.set( 'globalMapChecker', 'Hi' );
 
@@ -174,7 +177,7 @@
                assert.ok( mw.config instanceof mw.Map, 'mw.config instance of 
mw.Map' );
        } );
 
-       QUnit.test( 'mw.message & mw.messages', 100, function ( assert ) {
+       QUnit.test( 'mw.message & mw.messages', function ( assert ) {
                var goodbye, hello;
 
                // Convenience method for asserting the same result for 
multiple formats
@@ -189,7 +192,6 @@
                }
 
                assert.ok( mw.messages, 'messages defined' );
-               assert.ok( mw.messages instanceof mw.Map, 'mw.messages instance 
of mw.Map' );
                assert.ok( mw.messages.set( 'hello', 'Hello <b>awesome</b> 
world' ), 'mw.messages.set: Register' );
 
                hello = mw.message( 'hello' );

-- 
To view, visit https://gerrit.wikimedia.org/r/312557
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7ff0b230608f5ca582fc6752b59c4bb998c78ba2
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Krinkle <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to