@garyp/common-object-x
Version:
226 lines (165 loc) • 4.36 kB
JavaScript
//---------------------------------------------------------------------
//---------------------------------------------------------------------
"use strict";
class Compositex {
constructor() {
this.initialize();
}
add(child) {
var elem;
elem = this.basicAdd(child);
this.sizeChanged();
return elem;
}
addAll(coll) {
for (let ea of coll.zzunwrap()) {
this.basicAdd(ea)
}
this.sizeChanged();
}
assertComposite(msg) {
this.assertComment(() => this.isComposite() || this.isListx(),"Must be a composite");
}
at(index) {
if(!(this.isListx() || this.isComposite()))
this.error("#at: must be sent to list or composite");
return this.children().at(index);
}
basicAdd(child) {
return this.childrenContainer().add(this.coerceChild(child));
}
children() {
return this.implementedBySubclass();
}
childrenAsModels() {
return (this.childrenContainer().zzunwrap().map(ea => ea.asModel())).zzwrap();
}
childrenContainer() {
//virtual optional
return this.children();
}
coerceChild(child) {
//Coerce a child before adding it to self
//virtual optional
return child;
}
find(arg) {
if(arg.isString())
return this.findPath(arg);
return this.children().findFor(ea => arg.value(ea));
}
findName(nm) {
return this.children().findFor(ea => this.objectEquals(ea.name(),nm));
}
findPath(arg) {
var parts, result;
if(!(arg.includes('.')))
return this.findName(arg);
parts = arg.zastr().split($);
result = this;
for (let nm of parts.zzunwrap()) {
result = result.find(nm)
}
return result;
}
first() {
//Returns first child
return this.at(1);
}
initialize() {
//Manual (top level method)
//virtual, optional (fyi -- send initialize to super)
}
isComposite() {
//I am type Z, and I have children of type Z
return false;
}
isCompositeL() {
//See comment in #isListx
return this.isListx() || this.isComposite();
}
isEmpty() {
return !this.notEmpty();
}
isListx() {
/* If I am a list, then say I am type Z,
then I generally have children of type Y (optionally of type Z) */
return this.isComposite();
}
last() {
//Returns last child
return this.at(this.size());
}
notEmpty() {
return this.size() > 0;
}
parentNode() {
//Applicable if isComposite=true
return this.implementedBySubclass();
}
removeAll() {
this.childrenContainer().removeAll();
this.sizeChanged();
}
size() {
/* Returns count of number of (direct) children in this composite.
Does not include [nested] children. */
return this.childrenContainer().size();
}
sizeChanged() {
//virtual optional;
}
}
Function.prototype.asNameKey = function() { return this.name; }
String.prototype.asNameKey = function() { return this; }
Object.prototype.isString = function() {
return typeof this == typeof "a";
}
Object.prototype.className = function() {
return this.constructor.name;
}
Object.prototype.asString = function() {
return this.toString();
}
Array.prototype.size = function() {
return this.length;
}
String.prototype.size = function() {
return this.length;
}
Compositex.prototype.objectEquals = function(a, b) {
//Manual
//The purpose of this method is to add support that allows nil args
if (a === null) return b === null;
if (a === undefined) return b === undefined;
return a.equals(b);
}
Object.prototype.equals = function(other) {
//Manual
//Optional override
return this.valueOf() == other.valueOf();
}
String.prototype.paramReplace1 = function(varArgs) {
//replace %s tags with corresponding args
var s = this;
//Note String(o) is a function that converts any object to a String
for (var each of arguments)
s = s.replace("%s", String(each));
return s;
}
Object.prototype.isObjectx = function() {
return false;
}
Object.prototype.isCommonObjectx = function() {
return false;
}
Object.prototype.isCollection = function() {
return Array.isArray(this.valueOf());
}
String.prototype.isEmpty = function() {
return this.length === 0;
}
Array.prototype.isEmpty = function() {
return this.length === 0;
}
exports.Compositex = Compositex;