UNPKG

@garyp/common-object-x

Version:
456 lines (355 loc) 8.95 kB
const { Compositex } = require('./Compositex'); const { Streamx } = require('./Streamx'); //--------------------------------------------------------------------- //--------------------------------------------------------------------- "use strict"; class Toolsx extends Compositex { constructor() { super(); } /* -- static methods -- currentBlt */ //---------------------------------- //Class Variable Support //Class Variable Accessors static current(arg) { if (arg !== undefined) Toolsx.Current = arg; else if (Toolsx.Current == null) Toolsx.Current = Toolsx.currentBlt(); return Toolsx.Current; } static commonClassLib(arg) { if (arg !== undefined) Toolsx.CommonClassLib = arg; else if (Toolsx.CommonClassLib == null) Toolsx.CommonClassLib = Toolsx.commonClassLibBlt(); return Toolsx.CommonClassLib; } //---------------------------------- associationClass() { return this.commonClassLib().at("Associationx"); } canBeDictionary(obj) { //Manual return obj.zzunwrap().isDictionary(); } classFromObject(cl) { return cl.constructor; } classFromString(nm) { this.throw("classFromString -- FACTORY NEEDED"); } classNameOfClass(cl) { if (this.isString(cl)) return cl; return cl.name; } classNameOfObject(cl) { return this.classNameOfClass(object.constructor); } coerceBoolean(value) { var str, first, trues; if(this.isBoolean(value)) return value; if(this.isNumber(value)) return this.objectEquals(value,1); str = value.toString().zzwrap().asLowerCase(); if(str.isEmpty()) return false; first = str.zzwrap().first(); if(this.objectEquals(first,"t") || this.objectEquals(first,"y")) return true; trues = this.collClass().on([ "true" , "yes" , "1" ]).zzwrap(); trues.zzunwrap().forEach(ea => { if(this.objectEquals(ea,str)) return true }); return false; } coerceClass(arg) { if(arg == null) return null; if(this.isClass(arg)) return arg; if(this.isString(arg)) return this.classFromString(arg); //Assume object instance return this.classFromObject(arg); } coerceFloat(o) { return parseFloat(o); } coerceInstance(obj) { if(obj.isString()) return this.throw("String not supported for \"coerceInstance\""); return this.isClass(obj) ? new obj() : obj; } coerceInteger(o) { return parseInt(o); } coercePair(o) { return isCollection(o) && this.objectEquals(o.zzwrap().size(),2) ? o : this.pairWith(o,o); } coercePrimTypeFromString(s) { //Boolean/Float/Integer if(this.objectEquals(s,"null")) return null; if(this.pairWith("true","false").includes(s)) return this.coerceBoolean(s); if(s.zzwrap().isValidInteger()) return this.coerceInteger(s); return this.coerceFloat(s); } collClass() { //foo return this.commonClassLib().at("Collectionx"); } commonClassLib() { return this.constructor.commonClassLib(); } cr() { //Manual return "\r"; } dictClass() { return this.commonClassLib().at("Dictionaryx"); } endLineString() { //Manual return "\n"; } evaluateWith(evaluable,arg1) { //Manual return evaluable(arg1); } evaluateWithWith(evaluable,arg1,arg2) { //Manual return evaluable(arg1, arg2); } evaluateBlock(block) { //Manual //block is a jscript fct return block(); } getMethodFor(methodNm, o) { //Manual //js only var fctTarget, fct; fctTarget = (o != null) ? o : window; fct = fctTarget[methodNm]; return fct; } hasWhitespace(str) { //Manual //Note for space or tab only use e.g. /[ \t]/.test(str) return /\s/.test(str); } isKindOf(o, classOrNm) { //Manual var aClass = this.coerceClass(classOrNm); return o instanceof aClass; } isMemberOf(o, classOrNm) { //Manual return this.coerceClass(o) === this.coerceClass(classOrNm); } isBlank(aObject) { /* Blanks: #() '' nil */ var object; object = aObject.zzunwrap(); if(object == null) return true; if(this.isString(object)) return this.isWhitespace(object); if(this.isCollection(object)) return this.objectEquals(aObject.zzwrap().size(),0); return false; } isBoolean(o) { //Manual if (o == null) return false; return typeof o.zzunwrap() == typeof true } isClass(o) { //Manual //limitation here -- if arg is a function, we would also ans true return o instanceof Function; } isCollection(o) { //Manual if (o == null) return false; return o.zzunwrap() instanceof Array; } isDictionary(o) { //Manual //gpTry - we can do best estimate in js if (this.isNil(o)) return false; var raw = o.zzunwrap(); return raw.constructor == Object; } isMethodDefinedFor(methodNm, o) { //Manual return o[methodNm] !== undefined; } isNil(o) { //Manual //return true if nil or undefined //Double equal coerces null to undefined and vice-versa if(o) return false; else return o == null; } isNumber(o) { //Manual //int and float both ans identical type in js, but we hit both here to be sure if (o == null) return false; return (typeof o == typeof 1) || (typeof o == typeof 1.5); } isSmalltalk() { //Manual return false; } isSpace(string) { //Manual return this.objectEquals(string.asString()," "); } isString(o) { //Manual if (o == null) return false; return typeof o.zzunwrap() == typeof "a" } isUndefined(o) { //Manual //Strictly undefined (in js) return o === undefined; } isWhitespace(str) { //Manual /* ^ -- match beginning of line \s* -- match zero to many whitespace chars $ -- match end of line */ return (new RegExp(/^\s*$/)).test(str); } keyValue(key, value) { return this.associationClass().keyValue(key,value); } lf() { //Manual return "\n"; } newColl() { return this.collClass().on(this.newRawColl()); } newDict() { return this.dictClass().on(this.newRawDict()); } newline() { //Manual return "\n"; } newRawColl() { return []; } newRawDict() { return {}; } objectUnderstands(o, selector) { return o[selector] != null; } openTextWindowOnHappy(text, happy) { //Manual -- TODO -- use "happy" in js, e.g. in Div etc. console.log(text); } pairWith(a, b) { return this.collClass().withWith(a,b); } pointClass() { return this.commonClassLib().at("Pointx"); } privateIndexForPublic(smalltalkIndex) { /* Given public <smalltalkIndex>, return private <javaScriptIndex> So: st object = 1 based (no change) js object = 0 based (-1) */ if(smalltalkIndex <= 0) return smalltalkIndex; return this.isSmalltalk() ? smalltalkIndex : smalltalkIndex - 1; } processFunctionCall(line) { /* line format is like: foo(10, 'foo', 25); */ var strm, fctName, args; strm = this.newStream(line); fctName = strm.upTo("("); args = strm.parseTypedArgs(); return this.runFunctionNamedWithArguments(fctName,args.zzunwrap()); } publicIndexForPrivate(privateIndex) { /* Given private <javaScriptIndex>, return public <smalltalkIndex> Answer the public index. privateIndex is the index of our wrapped object st is 1 based js is 0 based We want to answer public e.g. 1 based So: st -> privateIndex + 0 js -> privateIndex + 1 */ if(privateIndex < 0) return privateIndex; return this.isSmalltalk() ? privateIndex : privateIndex + 1; } runFunctionNamedWithArguments(fctName,args) { //Manual //js only //spread function "..." expands arg array into proper individual args window[fctName](...args); } streamClass() { return Streamx; } throw(err) { throw err; } xY(x, y) { return this.pointClass().xY(x,y); } //Class Methods static currentBlt() { return new this() } } //---------------------------------- //Class Variable Initialization Toolsx.Current = null; Toolsx.CommonClassLib = null; Number.prototype.isNumber = function(o) { return isNumber(o); } function coerceFloat(o) { return Toolsx.current().coerceFloat(o); } function coerceInteger(o) { return Toolsx.current().coerceInteger(o); } function isString(o) { return Toolsx.current().isString(o); } function isNumber(o) { return Toolsx.current().isNumber(o); } function isCollection(o) { return Toolsx.current().isCollection(o); } function isBlank(o) { return Toolsx.current().isBlank(o); } function isBlankValue(o) { return isBlank(o); } function notBlankValue(o) { return !isBlankValue(o); } function isNotBlank(o) { return !isBlank(o); } exports.Toolsx = Toolsx;