refactoring + minor tweaks...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-04-24 16:20:52 +03:00
parent 56f3adfc35
commit 40ecbd8970
2 changed files with 122 additions and 98 deletions

View File

@ -30,6 +30,26 @@ FeatureLinearizationError.prototype.constructor = FeatureLinearizationError
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// Base feature...
//
// Feature(obj)
// -> feature
//
// Feature(feature-set, obj)
// -> feature
//
// Feature(tag, obj)
// -> feature
//
// Feature(tag, suggested)
// -> feature
//
// Feature(tag, actions)
// -> feature
//
// Feature(feature-set, tag, actions)
// -> feature
//
// //
// Feature attributes: // Feature attributes:
// .tag - feature tag (string) // .tag - feature tag (string)
@ -87,16 +107,30 @@ FeatureLinearizationError.prototype.constructor = FeatureLinearizationError
// considered on setup... // considered on setup...
// //
// //
// XXX this could install the handlers in two locations: var Feature =
// - mixin if available... module.Feature =
// - base object (currently implemented) object.Constructor('Feature', {
// should the first be done? //__featureset__: Features,
var FeatureProto = __featureset__: null,
module.FeatureProto = {
// Attributes...
tag: null, tag: null,
//title: null,
//doc: null,
//priority: null,
//exclusive: null,
//suggested: null,
//depends: null,
//actions: null,
//config: null,
//handlers: null,
isApplicable: function(actions){ return true }, isApplicable: function(actions){ return true },
// API...
getPriority: function(human_readable){ getPriority: function(human_readable){
var res = this.priority || 0 var res = this.priority || 0
res = res == 'high' ? 99 res = res == 'high' ? 99
@ -109,9 +143,12 @@ module.FeatureProto = {
: res == 0 ? 'normal' : res == 0 ? 'normal'
: res == -99 ? 'low' : res == -99 ? 'low'
: res) : res)
: res : res },
},
// XXX this could install the handlers in two locations:
// - mixin if available...
// - base object (currently implemented)
// should the first be done?
setup: function(actions){ setup: function(actions){
var that = this var that = this
@ -156,7 +193,7 @@ module.FeatureProto = {
// custom setup... // custom setup...
// XXX is this the correct way??? // XXX is this the correct way???
if(this.hasOwnProperty('setup') && this.setup !== FeatureProto.setup){ if(this.hasOwnProperty('setup') && this.setup !== Feature.prototype.setup){
this.setup(actions) this.setup(actions)
} }
@ -178,7 +215,7 @@ module.FeatureProto = {
} }
// XXX // XXX
if(this.hasOwnProperty('remove') && this.setup !== FeatureProto.remove){ if(this.hasOwnProperty('remove') && this.setup !== Feature.prototype.remove){
this.remove(actions) this.remove(actions)
} }
@ -188,102 +225,93 @@ module.FeatureProto = {
return this return this
}, },
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // XXX EXPERIMENTAL: if called from a feature-set this will add self
// XXX is hard-coded default feature-set a good way to go??? // to that feature-set...
// // XXX do we need this to be .__new__(..) and not .__init__(..)
// Feature(obj) __new__: function(context, feature_set, tag, obj){
// -> feature // NOTE: we need to account for context here -- inc length...
// if(arguments.length == 3){
// Feature(feature-set, obj) // Feature(<tag>, <obj>)
// -> feature if(typeof(feature_set) == typeof('str')){
// obj = tag
// Feature(tag, obj) tag = feature_set
// -> feature //feature_set = Features
// // XXX EXPERIMENTAL...
// Feature(tag, suggested) feature_set = context instanceof FeatureSet ?
// -> feature context
// : (this.__featureset__ || Features)
// Feature(tag, actions)
// -> feature
//
// Feature(feature-set, tag, actions)
// -> feature
//
var Feature =
module.Feature =
function Feature(feature_set, tag, obj){
if(arguments.length == 2){
// Feature(<tag>, <obj>)
if(typeof(feature_set) == typeof('str')){
obj = tag
tag = feature_set
feature_set = Features
// Feature(<feature-set>, <obj>) // Feature(<feature-set>, <obj>)
} else { } else {
obj = tag obj = tag
tag = null tag = null
}
// Feature(<obj>)
// NOTE: we need to account for context here -- inc length...
} else if(arguments.length == 2){
obj = feature_set
//feature_set = Features
// XXX EXPERIMENTAL...
feature_set = context instanceof FeatureSet ?
context
: (this.__featureset__ || Features)
} }
// Feature(<obj>) if(tag != null && obj.tag != null && obj.tag != tag){
} else if(arguments.length == 1){ throw 'Error: tag and obj.tag mismatch, either use one or both must match.' }
obj = feature_set
feature_set = Features
}
if(tag != null && obj.tag != null && obj.tag != tag){ // action...
throw 'Error: tag and obj.tag mismatch, either use one or both must match.' if(obj instanceof actions.Action){
} if(tag == null){
throw 'Error: need a tag to make a feature out of an action' }
var f = {
tag: tag,
actions: obj,
}
obj = f
// action... // meta-feature...
if(obj instanceof actions.Action){ } else if(obj.constructor === Array){
if(tag == null){ if(tag == null){
throw 'Error: need a tag to make a feature out of an action' throw 'Error: need a tag to make a meta-feature'
}
var f = {
tag: tag,
suggested: obj,
}
obj = f
} }
var f = {
tag: tag, // feature-set...
actions: obj, if(feature_set){
feature_set[obj.tag] = obj
} }
obj = f
// meta-feature... return obj
} else if(obj.constructor === Array){ },
if(tag == null){ })
throw 'Error: need a tag to make a meta-feature'
}
var f = {
tag: tag,
suggested: obj,
}
obj = f
// feature...
} else {
obj.__proto__ = FeatureProto
}
if(feature_set){
feature_set[obj.tag] = obj
}
return obj
}
Feature.prototype = FeatureProto
Feature.prototype.constructor = Feature
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var FeatureSetProto = { //---------------------------------------------------------------------
__feature__: Feature,
__actions__: actions.Actions,
var FeatureSet =
module.FeatureSet =
object.Constructor('FeatureSet', {
// if true, .setup(..) will report things it's doing... // if true, .setup(..) will report things it's doing...
__verbose__: null, __verbose__: null,
__actions__: actions.Actions,
// NOTE: a feature is expected to write a reference to itself to the
// feature-set (context)...
Feature: Feature,
// List of registered features... // List of registered features...
get features(){ get features(){
var that = this var that = this
@ -1068,7 +1096,7 @@ var FeatureSetProto = {
// do the setup... // do the setup...
var that = this var that = this
var setup = FeatureProto.setup var setup = Feature.prototype.setup
features.features.forEach(function(n){ features.features.forEach(function(n){
// setup... // setup...
if(that[n] != null){ if(that[n] != null){
@ -1122,17 +1150,13 @@ var FeatureSetProto = {
return graph return graph
}, },
// shorthand for: Feature(<feature-set>, ...) })
Feature: function(){
return this.__feature__.apply(null, [this].concat([...arguments])) },
}
var FeatureSet =
module.FeatureSet = object.Constructor('FeatureSet', FeatureSetProto)
//--------------------------------------------------------------------- /*********************************************************************/
// default feature set...
var Features = var Features =
module.Features = new FeatureSet() module.Features = new FeatureSet()

View File

@ -1,6 +1,6 @@
{ {
"name": "ig-features", "name": "ig-features",
"version": "3.4.1", "version": "3.4.2",
"description": "", "description": "",
"main": "features.js", "main": "features.js",
"scripts": { "scripts": {