/* Copyright (c) 2020, 2023, The Unified Company. This code is part of Unify. https://unifyjs.org */ import tools from "./tools.js"; import omitMethods from "./extender.rejectMethods.js"; export default function extender( ...extenderArguments ) { class dummyExtend { callInstance( extenderArgument, argumentsOfSuper ) { return new extenderArgument( ...argumentsOfSuper ); } getExtendMap() { if( typeof document != "undefined") { return document.extendMap; } else { return global.extendMap; } } removeDuplicates( extendMap, parentClassName ) { extendMap[ parentClassName ] = extendMap[ parentClassName ].filter( ( obj, index, arr ) => { return arr.map( mapObj => mapObj.__className ).indexOf( obj.__className ) === index; }); } saveInstanceInExtendMap( instance ) { var parentClassName = this.constructor.name; var extendMap = this.getExtendMap(); if( !extendMap[ parentClassName ] ) { extendMap[ parentClassName ] = new Array(); } extendMap[ parentClassName ].push( instance ); this.removeDuplicates( extendMap, parentClassName ); } inheritPropertiesA( arg ) { var properties = Object.getOwnPropertyNames( arg.prototype ); var propertiesFiltered = properties.filter( prop => prop !== "constructor" ); for ( const prop of propertiesFiltered ) { if( !this[prop] ) { this[ prop ] = arg.prototype[ prop ]; } } } inheritPropertiesFromExtends( arg, root, level ) { if( level > 0 ) { var extendedInstance = new arg.constructor(); var prototype = Object.getPrototypeOf( extendedInstance ); var propertyNames = Object.getOwnPropertyNames( prototype ); propertyNames.forEach( methodName => { if( !omitMethods.includes( methodName ) ) { if( !root[ methodName ] ) { root[ methodName ] = extendedInstance[ methodName ]; } } }); } var extendedClass = tools.getExtendedClass( arg ); if( extendedClass ) { this.inheritPropertiesFromExtends( extendedClass, root, level + 1 ); } } constructor( ...argumentsOfSuper ) { // extenderArguments = this.constructor.extenderArguments; for( const extenderArgument of extenderArguments ) { var instance = this.callInstance( extenderArgument, argumentsOfSuper ); Object.assign( this, instance ); this.saveInstanceInExtendMap( instance ); this.inheritPropertiesA( extenderArgument ); this.inheritPropertiesFromExtends( extenderArgument, this, 0 ); } } } class table { createInstance() { var instance = new arg(); Object.assign( this, instance ); return instance; } assureExtendMap() { if( typeof document == "undefined") { var extendMap = global.extendMap; } else { var extendMap = document.extendMap; } if( !extendMap[ parentClassName ] ) { extendMap[ parentClassName ] = new Array(); } } addInstanceToExtendMap( extendMap, instance ) { var parentClassName = this.constructor.name; extendMap[ parentClassName ].push( instance ); } updateExtendMap( instance ) { this.assureExtendMap(); this.addInstanceToExtendMap( instance ); } getProperties( arg ) { return Object.getOwnPropertyNames( arg.prototype ).filter( prop => prop !== "constructor" ); } updateProperties( arg ) { var properties = this.getProperties( arg ); for ( const property of properties ){ this[ property ] = arg.prototype[ property ] } } /** * Creates an instance of Class. * * @memberOf Class */ constructor(...opts) { for( const arg of extenderArguments ) { var instance = this.createInstance(); this.updateExtendMap( instance ); this.updateProperties( arg ); } } } var isTable = false; for( const arg of extenderArguments ) { var instance = new arg(); if( instance.constructor.name == "table" ) { isTable = true; } } if( isTable ) { return table; } else { //dummyExtend.extenderArguments = extenderArguments; return dummyExtend; } }