267 lines
4.0 KiB
JavaScript
267 lines
4.0 KiB
JavaScript
|
|
/*
|
||
|
|
|
||
|
|
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;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|