diff --git a/js/inherit.js b/js/inherit.js deleted file mode 100644 index 34e896b..0000000 --- a/js/inherit.js +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2013-2020, University of Colorado Boulder - -/* eslint-disable bad-text */ -/** - * Utility function for setting up prototypal inheritance. - * Maintains supertype.prototype.constructor while properly copying ES5 getters and setters. - * Supports adding functions to both the prototype itself and the constructor function. - * - * Usage: - * - * // Call the supertype constructor somewhere in the subtype's constructor. - * function A() { scenery.Node.call( this ); }; - * - * // Add prototype functions and/or 'static' functions - * export default inherit( scenery.Node, A, { - * customBehavior: function() { ... }, - * isAnA: true - * }, { - * someStaticFunction: function() { ...} - * } ); - * - * // client calls - * new A().isAnA; // true - * new scenery.Node().isAnA; // undefined - * new A().constructor.name; // 'A' - * A.someStaticFunction(); - * - * @author Jonathan Olson - */ -/* eslint-enable bad-text */ - -import extend from './extend.js'; -import phetCore from './phetCore.js'; - -/** - * @param supertype Constructor for the supertype. - * @param subtype Constructor for the subtype. Generally should contain supertype.call( this, ... ) - * @param prototypeProperties [optional] object containing properties that will be set on the prototype. - * @param staticProperties [optional] object containing properties that will be set on the constructor function itself - * @deprecated - please use ES6 class - */ -function inherit( supertype, subtype, prototypeProperties, staticProperties ) { - assert && assert( typeof supertype === 'function' ); - - function F() {} - - F.prototype = supertype.prototype; // so new F().__proto__ === supertype.prototype - - subtype.prototype = extend( // extend will combine the properties and constructor into the new F copy - new F(), // so new F().__proto__ === supertype.prototype, and the prototype chain is set up nicely - { constructor: subtype }, // overrides the constructor properly - prototypeProperties // [optional] additional properties for the prototype, as an object. - ); - - //Copy the static properties onto the subtype constructor so they can be accessed 'statically' - extend( subtype, staticProperties ); - - return subtype; // pass back the subtype so it can be returned immediately as a module export -} - -phetCore.register( 'inherit', inherit ); - -export default inherit; \ No newline at end of file diff --git a/js/inheritTests.js b/js/inheritTests.js deleted file mode 100644 index ecc23ec..0000000 --- a/js/inheritTests.js +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017-2020, University of Colorado Boulder - -/** - * inherit tests - * - * @author Jonathan Olson (PhET Interactive Simulations) - * @author Sam Reid (PhET Interactive Simulations) - */ - -import inherit from './inherit.js'; - -QUnit.module( 'inherit' ); - -QUnit.test( 'inherit', assert => { - const Person = function( name ) { - this.name = name; - }; - const Warrior = function( name, strength ) { - Person.call( this, name ); - this.strength = strength; - }; - let attacked = false; - inherit( Person, Warrior, - - //Instance Methods - { - attack: () => { - attacked = true; - } - }, - - //Static Methods and fields - { - warriorType: 'swordsman', - getWarriorCastle: () => 'camelot', - get totalWarriorCount() {return 1234;} - } - ); - const galahad = new Warrior( 'galahad', 95 ); - assert.equal( attacked, false, 'Dont call methods before they are invoked' ); - galahad.attack(); - assert.equal( attacked, true, 'call a method added with inherit' ); - assert.equal( Warrior.warriorType, 'swordsman', 'access static field on the constructor method' ); - assert.equal( Warrior.getWarriorCastle(), 'camelot', 'access static method on the constructor method' ); - assert.equal( Warrior.totalWarriorCount, 1234, 'es5 get/set should work on statics' ); -} ); \ No newline at end of file diff --git a/js/main.js b/js/main.js index 5192284..025703a 100644 --- a/js/main.js +++ b/js/main.js @@ -15,14 +15,12 @@ import './escapeHTML.js'; import './EventTimer.js'; import './extend.js'; import './extendDefined.js'; -import './inherit.js'; import './inheritance.js'; import './interleave.js'; import './isArray.js'; import './loadScript.js'; import './memoize.js'; import './merge.js'; -import './mixedWith.js'; import './Namespace.js'; import './openPopup.js'; import './pairs.js'; diff --git a/js/mixedWith.js b/js/mixedWith.js deleted file mode 100644 index 3f10376..0000000 --- a/js/mixedWith.js +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2017-2020, University of Colorado Boulder - -/** - * Helps create a one-of subtype that mixes in certain mixins. - * - * @author Jonathan Olson - */ - -import inherit from './inherit.js'; -import phetCore from './phetCore.js'; - -/** - * Returns a new subtype of the passed in type that has mixins applied. - * @public - * - * Each mixin should be a function that takes a type as a parameter, mixes it into the type when called, and - * optionally returns a function that should be called at the end of the constructor. Additionally, its function name - * is used as part of the returned type name. - * - * For example: - * - * | // Our basic type that we'll want to extend with a mixin - * | function Simulation() { - * | this.name = 'phet-core-sim'; - * | } - * | phetCore.inherit( Object, Simulation ); - * | - * | // Mixin that doesn't require initialization during construction - * | function Playable( type ) { - * | type.prototype.play = function() { - * | console.log( 'many fun, such entertain' ); - * | } - * | } - * | - * | // Mixin that does require initialization during construction (returned) - * | function Runnable( type ) { - * | type.prototype.run = function() { - * | this.running = true; - * | }; - * | return function() { - * | // @private - * | this.running = false; - * | }; - * | } - * | - * | // Easily create a "subtype" of Simulation that is both playable and runnable. - * | // For debugging purposes, its name is overridden as Simulation_Playable_Runnable (indicating the type and mixins - * | // that were applied). Further mixing would concatenate. - * | var PhETSimulation = phetCore.mixedWith( Simulation, Playable, Runnable ); - * | - * | // Instantiation shows both mixins are applied to the prototype, and the initializer ran - * | var mixedSim = new PhETSimulation(); - * | mixedSim.name; // 'phet-core-sim' - * | mixedSim.play(); // >> many fun, such entertain - * | mixedSim.running; // false - * | mixedSim.run(); - * | mixedSim.running; // true - * | - * | // The original type is unaffected - * | var basicSim = new Simulation(); - * | basicSim.play(); // errors - * - * @param {Function} supertype - This is the type you want with mixins, without modifying this original type. - * @param {...Function} mixins - Zero or more (var-args style) of function( type: {Function} ) => {Function|undefined} - * which, when called with a type, will mix in the type. If a return value is provided, - * it should be a function that will be called in the constructor (with the - * constructor's arguments). - * @returns {Function} - The subtype - */ -function mixedWith( supertype, mixins ) { - assert && assert( typeof supertype === 'function' ); - - // Support an arbitrary number of mixins with varargs. Strips off the first argument (the supertype). - mixins = Array.prototype.slice.call( arguments, 1 ); - - // Figure out the preferred type name for our subtype constructor - let name = supertype.name; - mixins.forEach( mixin => { - // A common pattern for mixins with type-scope parameters should be: - // mixedWith( super, someMixin.bind( null, someParameter ) ) - // with someMixin( someParameter, type ). This allows mixing in custom function parameters, etc. defined at the - // type level. - // Chrome prepends 'bound ' for every time a function is bound, so we filter that out with global replacement. - name = name + '_' + mixin.name.replace( /bound /g, '_' ); - } ); - - // Holds all initializer functions that need to be called during construction - const initializers = []; - - // Creates the constructor. - // The 'new Function' pattern is used so that we can have a useful type/constructor name that is type-specific. - // This is not "essential", but it is highly preferred so that types in devtools are understandable. - // The inner closure runs the "wrapped" implicit function. We then call the inner function with our supertype - // and initializer array. Initializers don't have to be appended to the array yet. - const subtype = ( new Function( 'return function( suptype, inits ) {' + - ' return function ' + name + '() {' + - ' var self = this;' + - ' var args = Array.prototype.slice.call( arguments );' + - ' suptype.apply( this, args );' + - ' inits.forEach( function( init ) { init.apply( self, args ); } );' + - ' };' + - '};' )() )( supertype, initializers ); - - // Inherit, so that our prototype and other nice properties carry over. - inherit( supertype, subtype ); - - // Apply the mixins in order, and process initializers - mixins.forEach( mixin => { - const optionalInitializer = mixin( subtype ); - if ( typeof optionalInitializer === 'function' ) { - initializers.push( optionalInitializer ); - } - } ); - - return subtype; -} - -phetCore.register( 'mixedWith', mixedWith ); - -export default mixedWith; \ No newline at end of file diff --git a/js/mixedWithTests.js b/js/mixedWithTests.js deleted file mode 100644 index 186237b..0000000 --- a/js/mixedWithTests.js +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2017-2020, University of Colorado Boulder - -/** - * mixedWith tests - * - * @author Jonathan Olson (PhET Interactive Simulations) - * @author Sam Reid (PhET Interactive Simulations) - */ - -import inherit from './inherit.js'; -import mixedWith from './mixedWith.js'; - -QUnit.module( 'mixedWith' ); - -QUnit.test( 'mixedWith', assert => { - const NAME = 'phet-core-sim'; - - // Our basic type that we'll want to extend with a mixin - function Simulation() { - this.name = NAME; - } - - inherit( Object, Simulation ); - - // Mixin that doesn't require initialization during construction - function Playable( type ) { - type.prototype.play = () => { - window.thisIsProbablyNotDefinedDoNotLogInTests && console.log( 'many fun, such entertain' ); - }; - } - - // Mixin that does require initialization during construction (returned) - function Runnable( type ) { - type.prototype.run = function() { - this.running = true; - }; - return function() { - // @private - this.running = false; - }; - } - - // Easily create a "subtype" of Simulation that is both playable and runnable. - // For debugging purposes, its name is overridden as Simulation_Playable_Runnable (indicating the type and mixins - // that were applied). Further mixing would concatenate. - const PhETSimulation = mixedWith( Simulation, Playable, Runnable ); - - // Instantiation shows both mixins are applied to the prototype, and the initializer ran - const mixedSim = new PhETSimulation(); - assert.equal( mixedSim.name, NAME ); // 'phet-core-sim' - mixedSim.play(); // >> many fun, such entertain - assert.equal( mixedSim.running, false ); // false - mixedSim.run(); - assert.equal( mixedSim.running, true ); // true - - // The original type is unaffected - const basicSim = new Simulation(); - assert.equal( basicSim.play, undefined ); // does not exist - assert.equal( basicSim.running, undefined ); // does not exist - assert.equal( basicSim.run, undefined ); // does not exist -} ); \ No newline at end of file diff --git a/js/phet-core-tests.js b/js/phet-core-tests.js index 87e05d8..582ebe0 100644 --- a/js/phet-core-tests.js +++ b/js/phet-core-tests.js @@ -18,11 +18,9 @@ import './dimensionForEachTests.js'; import './dimensionMapTests.js'; import './EnumerationTests.js'; import './escapeHTMLTests.js'; -import './inheritTests.js'; import './interleaveTests.js'; import './isArrayTests.js'; import './mergeTests.js'; -import './mixedWithTests.js'; import './pairsTests.js'; import './partitionTests.js'; import './swapObjectKeysTests.js';