First commit
This commit is contained in:
267
framework/unify/extender.js
Normal file
267
framework/unify/extender.js
Normal file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user