Daniel Werner has uploaded a new change for review.

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


Change subject: dv.util.inherit changed so __proto__ of related objects 
displays a proper name
......................................................................

dv.util.inherit changed so __proto__ of related objects displays a proper name

or: "Episode II: eval() Strikes Back".
With this change, during debugging instances of constructors created with 
dv.util.inherit will
display useful information of their prototype when looking at their __proto__

Change-Id: Iad63505c28f7b95a0b21a1882d72ba052f9c41cf
---
M DataValues/resources/dataValues.util.js
M DataValues/tests/qunit/dataValues.util.inherit.tests.js
2 files changed, 36 insertions(+), 16 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DataValues 
refs/changes/53/50753/1

diff --git a/DataValues/resources/dataValues.util.js 
b/DataValues/resources/dataValues.util.js
index d64c70d..1e7bd8d 100644
--- a/DataValues/resources/dataValues.util.js
+++ b/DataValues/resources/dataValues.util.js
@@ -8,6 +8,33 @@
        'use strict';
 
        /**
+        * Helper to create a named function which will execute a given 
function.
+        *
+        * @param {string} name Name of the new function. All characters not 
matching [\w$] will be
+        *        removed.
+        * @param {Function} [originalFn] Function which will be executed by 
new function. If not given,
+        *        an empty function will be used instead.
+        * @return Function
+        *
+        * @throws {Error} If the given name has no characters matching [\w$].
+        */
+       function createNamedFunction( name, originalFn ) {
+               var namedFn,
+                       evilsSeed = originalFn || $.noop,
+                       fnName = name.replace( /(?:(^\d+)|[^\w$])/ig, '' );
+
+               if( !fnName ) {
+                       // only bad characters were in the name!
+                       throw new Error( 'Bad function name given. At least one 
word character or $ required.' );
+               }
+
+               eval( 'namedFn = function ' + fnName +
+                       '(){ evilsSeed.apply( this, arguments ); }' );
+
+               return namedFn;
+       }
+
+       /**
         * Module for utilities of the DataValues extension.
         * @since 0.1
         * @type Object
@@ -44,24 +71,16 @@
                                constructor = false;
                        }
                }
-               // if no name is given, find suitable constructor's name
-               name = name || constructor.name || ( base.name ? base.name + 
'_SubProto' : 'SomeInherited' );
-               // make sure name is just a function name and not some 
executable JavaScript
-               name = name.replace( /(?:(^\d+)|[^\w$])/ig, '' );
+               // If no name is given, find suitable constructor name. We want 
proper names here, so
+               // instances can easily be identified during debugging.
+               var constructorName = name || constructor.name || ( base.name ? 
base.name + '_SubProto' : 'SomeInherited' ),
+                       prototypeName = base.name || 'SomeProto';
 
-               if( !name ) { // only bad characters were in the name!
-                       throw new Error( 'Bad constructor name given. Only word 
characters and $ are allowed.' );
-               }
+               // function we execute in our real constructor
+               var NewConstructor = createNamedFunction( constructorName, 
constructor || base );
 
-               // function we execute in our real constructor created by evil 
eval:
-               var evilsSeed = constructor || base,
-                       NewConstructor;
-
-               // for creating a named function with a variable name, there is 
just no other way...
-               eval( 'NewConstructor = function ' + name +
-                       '(){ evilsSeed.apply( this, arguments ); }' );
-
-               var NewPrototype = function(){}; // new constructor for 
avoiding base constructor and with it any side-effects
+               // new constructor for avoiding direct use of base constructor 
and its potential side-effects
+               var NewPrototype = createNamedFunction( prototypeName );
                NewPrototype.prototype = base.prototype;
 
                NewConstructor.prototype = $.extend(
diff --git a/DataValues/tests/qunit/dataValues.util.inherit.tests.js 
b/DataValues/tests/qunit/dataValues.util.inherit.tests.js
index a301bdd..74fd363 100644
--- a/DataValues/tests/qunit/dataValues.util.inherit.tests.js
+++ b/DataValues/tests/qunit/dataValues.util.inherit.tests.js
@@ -153,6 +153,7 @@
                        [ 'function()xxx(){};', 'functionxxx' ],
                        [ 'xyz;${]123', 'xyz$123' ],
                        [ ';a;1;$;b;_;', 'a1$b_' ],
+                       [ 'a1$b2c3d4;', 'a1$b2c3d4' ],
                        [ '();', false ],
                        [ '42', false ], // can't start function name with 
number
                        [ 'class', false ], // reserved word

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iad63505c28f7b95a0b21a1882d72ba052f9c41cf
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/DataValues
Gerrit-Branch: master
Gerrit-Owner: Daniel Werner <[email protected]>

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

Reply via email to