@pilotlab/lux-attributes
Version:
A luxurious user experience framework, developed by your friends at Pilot.
161 lines (149 loc) • 7.65 kB
text/typescript
import is from '@pilotlab/lux-is';
import Debug from '@pilotlab/lux-debug';
import Strings from '@pilotlab/lux-strings';
import { NodeFactoryBase } from '@pilotlab/lux-nodes';
import Attribute from './attribute';
import AttributeBase from './attributeBase';
import AttributesBase from './attributesBase';
import AttributeCreateOptions from './attributeCreateOptions';
import AttributeTools from './attributeTools';
import IAttributesFactory from './interfaces/iAttributesFactory';
import IAttributeFactory from './interfaces/iAttributeFactory';
import IAttribute from './interfaces/iAttribute';
import IAttributes from './interfaces/iAttributes';
import { DataType } from './attributeEnums';
export abstract class AttributeFactoryBase<
TAttribute extends IAttribute,
TAttributes extends IAttributes>
extends NodeFactoryBase<TAttribute, TAttributes>
implements IAttributeFactory {
get collection():IAttributesFactory {
return null;
}
fromObject(obj:any):TAttribute {
try {
if (obj instanceof AttributeBase) return <TAttribute><IAttribute>obj;
else if (is.notEmpty(obj['dataType'])) return this.fromStrings(obj['key'], obj['value'], obj['dataType'].toLocaleLowerCase());
else if (is.notEmpty(obj['value'])) {
let dataType:string = AttributeTools.getDataType(obj['value']);
let value:any = obj['value'];
if (dataType === 'object' && !(value instanceof AttributesBase)) {
dataType = 'collection';
value = this.collection.fromObject(value);
}
return this.fromStrings(obj['key'], value, dataType);
} else {
let attribute:TAttribute;
for (let key in obj){
if (obj.hasOwnProperty(key)) {
let value:any = obj[key];
let dataType:string = AttributeTools.getDataType(value);
attribute = this.fromStrings(key, obj[key], dataType);
break;
}
}
return attribute;
}
} catch (e) { Debug.error(e, 'Attribute.create.fromObject(...)'); }
}
/**
* NOTE: This method is used internally. If an Object is passed as the value and no dataType
* is passed in, or a dataType of COLLECTION is passed, the Object will be placed in an
* Attribute with a dataType of Attributes and the Object will not be converted to an Attributes tree.
* @param key
* @param value Can be a string for most types, but don't pass a string or Object if the dataType is 'collection',
* unless you set the isParseAttributes parameter to true.
* @param dataType {string}
* @returns {IAttribute}
*/
fromStrings(
key:string,
value:any,
dataType:string
):TAttribute {
try {
let node:TAttribute;
if (is.empty(dataType)) dataType = AttributeTools.getDataType(value);
/// Get the string representation of the enum value.
switch (dataType.toLowerCase()) {
case 'bool': // Fall through
case 'boolean':
if (typeof value === 'string') value = (value.toLowerCase() === 'true');
node = this.instance(new AttributeCreateOptions(value, DataType.BOOLEAN), key);
break;
case 'collection':
if (is.notEmpty(value)) {
if (typeof value === 'string') value = JSON.parse(value);
if (!(value instanceof AttributesBase)) {
value = this.collection.fromAny(value);
}
}
node = this.instance(new AttributeCreateOptions(value, DataType.COLLECTION), key);
break;
case 'date_time':
if (typeof value === 'string') value = Date.parse(value);
node = this.instance(new AttributeCreateOptions(value, DataType.DATE_TIME), key);
break;
case 'number':
if (typeof value === 'string') value = parseFloat(value);
node = this.instance(new AttributeCreateOptions(value, DataType.NUMBER), key);
break;
case 'double':
case 'number_double':
if (typeof value === 'string') value = parseFloat(value);
node = this.instance(new AttributeCreateOptions(value, DataType.NUMBER_DOUBLE), key);
break;
case 'int':
case 'number_int':
if (typeof value === 'string') value = parseInt(value);
node = this.instance(new AttributeCreateOptions(value, DataType.NUMBER_INT), key);
break;
case 'function':
if (typeof value === 'string') value = Strings.getFunctionFromString(value);
node = this.instance(new AttributeCreateOptions(value, DataType.FUNCTION), key);
break;
case 'hex_value':
node = this.instance(new AttributeCreateOptions(value, DataType.STRING_HEX_VALUE), key);
break;
case 'html':
if (typeof value === 'string') value = Strings.stringToHtmlDocument(value);
node = this.instance(new AttributeCreateOptions(value, DataType.STRING_HTML), key);
break;
case 'json':
case 'string_json':
node = this.instance(new AttributeCreateOptions(value, DataType.STRING_JSON), key);
break;
case 'reg_exp':
case 'string_reg_exp':
value = new RegExp(value);
node = this.instance(new AttributeCreateOptions(value, DataType.REG_EXP), key);
break;
case 'string':
node = this.instance(new AttributeCreateOptions(value, DataType.STRING), key);
break;
case 'svg':
case 'string_svg':
if (typeof value === 'string') value = Strings.stringToSvgDocument(value);
node = this.instance(new AttributeCreateOptions(value, DataType.STRING_SVG), key);
break;
case 'uri':
case 'string_uri':
node = this.instance(new AttributeCreateOptions(value, DataType.STRING_URI), key);
break;
case 'xml':
case 'string_xml':
if (typeof value === 'string') value = Strings.stringToXmlDocument(value);
node = this.instance(new AttributeCreateOptions(value, DataType.STRING_XML), key);
break;
case 'object':
if (typeof value === 'string') value = JSON.parse(value);
node = this.instance(new AttributeCreateOptions(value, DataType.OBJECT), key);
case 'any': // Fall through to default.
default: // Default to ANY.
node = this.instance(new AttributeCreateOptions(value, DataType.ANY), key);
}
return node;
} catch(e) { Debug.error(`${e} + ', key: ${key}, value: ${value}, dataType: ${dataType}`, 'Attribute.fromStrings(...)'); }
}
} // End class
export default AttributeFactoryBase;