refactoring and cleanup + minor fixes...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2018-12-25 16:41:02 +03:00
parent 1c390e570a
commit b5f4a08cdf

View File

@ -81,22 +81,29 @@ var normalizeSplit = function(args){
// Helpers... // Helpers...
var makeSplitter = function(separator){ var makeSplitter = function(separator){
return function(...tags){ return function(...tags){
var sp = this[separator] var SP = this[separator]
return normalizeSplit(tags) return normalizeSplit(tags)
.map(function(tag){ .map(function(tag){
return tag.split(sp) }) return tag.split(SP) })
.flat() .flat()
.unique() } } .unique() } }
var makeJoiner = function(separator){
return function(...items){
return normalizeSplit(items).join(this[separator]) } }
var BaseTagsClassPrototype = { var BaseTagsClassPrototype = {
// NOTE: do not include 'g' flag here, it will make the RE objects // NOTE: do not include 'g' flag here, it will make the RE objects
// stateful which will yield very unpredictable results from // stateful which will yield very unpredictable results from
// general system. // general system.
// XXX need separators as attrs too... PATH_SEPARATOR: '/',
PATH_SEPARATOR: /[\\\/]+/, PATH_SEPARATOR_PATTERN: /[\\\/]+/,
SET_SEPARATOR: /:+/,
COMBINED_SEPARATOR: /[:\\\/]+/, SET_SEPARATOR: ':',
SET_SEPARATOR_PATTERN: /:+/,
COMBINED_SEPARATOR_PATTERN: /[:\\\/]+/,
// Utils... // Utils...
// //
@ -107,9 +114,11 @@ var BaseTagsClassPrototype = {
// -> parts // -> parts
// //
// NOTE: these will combine the parts of all the tags... // NOTE: these will combine the parts of all the tags...
splitSet: makeSplitter('SET_SEPARATOR'), splitSet: makeSplitter('SET_SEPARATOR_PATTERN'),
splitPath: makeSplitter('PATH_SEPARATOR'), splitPath: makeSplitter('PATH_SEPARATOR_PATTERN'),
splitTag: makeSplitter('COMBINED_SEPARATOR'), splitTag: makeSplitter('COMBINED_SEPARATOR_PATTERN'),
joinSet: makeJoiner('SET_SEPARATOR'),
joinPath: makeJoiner('PATH_SEPARATOR'),
// Normalize tags... // Normalize tags...
// //
@ -134,7 +143,10 @@ var BaseTagsClassPrototype = {
// as possible. // as possible.
// //
normalize: function(...tags){ normalize: function(...tags){
var that = this var SS = this.SET_SEPARATOR
var PS = this.PATH_SEPARATOR
var SP = this.SET_SEPARATOR_PATTERN
var PP = this.PATH_SEPARATOR_PATTERN
var tagRemovedChars = (this.config || {})['tagRemovedChars'] var tagRemovedChars = (this.config || {})['tagRemovedChars']
tagRemovedChars = tagRemovedChars instanceof RegExp ? tagRemovedChars = tagRemovedChars instanceof RegExp ?
tagRemovedChars tagRemovedChars
@ -148,20 +160,20 @@ var BaseTagsClassPrototype = {
.toLowerCase() .toLowerCase()
.replace(tagRemovedChars, '') .replace(tagRemovedChars, '')
// sort sets within paths... // sort sets within paths...
.split(that.PATH_SEPARATOR) .split(PP)
.map(function(e){ .map(function(e){
return e return e
.split(that.SET_SEPARATOR) .split(SP)
// remove empty set members... // remove empty set members...
.filter(function(t){ .filter(function(t){
return t != '' }) return t != '' })
.unique() .unique()
.sort() .sort()
.join(':') }) .join(SS) })
// NOTE: this also kills the leading '/' // NOTE: this also kills the leading '/'
.filter(function(t){ .filter(function(t){
return t != '' }) return t != '' })
.join('/') }) .join(PS) })
.unique() .unique()
return (tags.length == 1 && !(tags[0] instanceof Array)) ? return (tags.length == 1 && !(tags[0] instanceof Array)) ?
// NOTE: if we got a single tag return it as a single tag... // NOTE: if we got a single tag return it as a single tag...
@ -272,8 +284,10 @@ var BaseTagsPrototype = {
// NOTE: for notes on structure see notes on the Utils section below... // NOTE: for notes on structure see notes on the Utils section below...
PATH_SEPARATOR: BaseTagsClassPrototype.PATH_SEPARATOR, PATH_SEPARATOR: BaseTagsClassPrototype.PATH_SEPARATOR,
PATH_SEPARATOR_PATTERN: BaseTagsClassPrototype.PATH_SEPARATOR_PATTERN,
SET_SEPARATOR: BaseTagsClassPrototype.SET_SEPARATOR, SET_SEPARATOR: BaseTagsClassPrototype.SET_SEPARATOR,
COMBINED_SEPARATOR: BaseTagsClassPrototype.COMBINED_SEPARATOR, SET_SEPARATOR_PATTERN: BaseTagsClassPrototype.SET_SEPARATOR_PATTERN,
COMBINED_SEPARATOR_PATTERN: BaseTagsClassPrototype.COMBINED_SEPARATOR_PATTERN,
// Tag index... // Tag index...
@ -558,12 +572,13 @@ var BaseTagsPrototype = {
// a root/base tag respectively but this seems a bit less useful. // a root/base tag respectively but this seems a bit less useful.
match: function(a, b, cmp){ match: function(a, b, cmp){
var that = this var that = this
var PP = this.PATH_SEPARATOR_PATTERN
// get paths with tag... // get paths with tag...
var paths = function(tag){ var paths = function(tag){
return that.directMatch(tag, cmp) return that.directMatch(tag, cmp)
.filter(function(t){ .filter(function(t){
return that.PATH_SEPARATOR.test(t) }) } return PP.test(t) }) }
// search the path tree... // search the path tree...
// NOTE: this will stop the search on first hit... // NOTE: this will stop the search on first hit...
var search = function(target, tag, seen){ var search = function(target, tag, seen){
@ -688,13 +703,14 @@ var BaseTagsPrototype = {
// //
uniquePaths: function(...list){ uniquePaths: function(...list){
var that = this var that = this
var PS = this.PATH_SEPARATOR
return (list.length == 0 ? return (list.length == 0 ?
this.paths() this.paths()
: this.normalize(normalizeSplit(list))) : this.normalize(normalizeSplit(list)))
// sort by number of path elements (longest first)... // sort by number of path elements (longest first)...
.map(that.splitPath) .map(function(tag){ return that.splitPath(tag) })
.sort(function(a, b){ return b.length - a.length }) .sort(function(a, b){ return b.length - a.length })
.map(function(p){ return p.join('/') }) .map(function(p){ return p.join(PS) })
// remove all paths in tail that match the current... // remove all paths in tail that match the current...
.map(function(p, i, list){ .map(function(p, i, list){
// skip []... // skip []...
@ -793,13 +809,13 @@ var BaseTagsPrototype = {
singleTags: function(value, ...tags){ singleTags: function(value, ...tags){
return this.splitTag(this.tags(...arguments)).unique() }, return this.splitTag(this.tags(...arguments)).unique() },
paths: function(value){ paths: function(value){
var sp = that.PATH_SEPARATOR var PP = this.PATH_SEPARATOR_PATTERN
return this.tags(value) return this.tags(value)
.filter(function(tag){ return sp.test(tag) }) }, .filter(function(tag){ return PP.test(tag) }) },
sets: function(value){ sets: function(value){
var sp = this.SET_SEPARATOR var SP = this.SET_SEPARATOR_PATTERN
return this.tags(value) return this.tags(value)
.filter(function(tag){ return sp.test(tag) }) }, .filter(function(tag){ return SP.test(tag) }) },
// //
// Get all values... // Get all values...
// .values() // .values()
@ -842,6 +858,8 @@ var BaseTagsPrototype = {
// .define('tag', 'concept:tag') // -> 'concept:tag/tag' // .define('tag', 'concept:tag') // -> 'concept:tag/tag'
// //
definitionPaths: function(...tags){ definitionPaths: function(...tags){
var SS = this.SET_SEPARATOR
var PS = this.PATH_SEPARATOR
var definitions = this.definitions || {} var definitions = this.definitions || {}
tags = normalizeSplit(tags) tags = normalizeSplit(tags)
var res = (tags.length == 0 ? var res = (tags.length == 0 ?
@ -851,7 +869,7 @@ var BaseTagsPrototype = {
return [tag, definitions[tag]] })) return [tag, definitions[tag]] }))
.map(function(e){ .map(function(e){
return e[1] != null ? return e[1] != null ?
[e[1].join(':'), e[0]].join('/') [e[1].join(SS), e[0]].join(SP)
: e[1] }) : e[1] })
return arguments.length == 1 && typeof(arguments[0]) == typeof('str') ? return arguments.length == 1 && typeof(arguments[0]) == typeof('str') ?
res[0] res[0]
@ -1208,6 +1226,8 @@ var BaseTagsPrototype = {
// //
define: function(tag, value){ define: function(tag, value){
var that = this var that = this
var SS = this.SET_SEPARATOR
var PS = this.PATH_SEPARATOR
var definitions = this.definitions var definitions = this.definitions
// batch... // batch...
@ -1228,9 +1248,9 @@ var BaseTagsPrototype = {
// get/resolve... // get/resolve...
if(arguments.length == 1){ if(arguments.length == 1){
// NOTE: we expect there to be only one definition... // NOTE: we expect there to be only one definition...
return this.match(tag +'/', [...Object.keys(definitions) || []]) return this.match(tag +PS, [...Object.keys(definitions) || []])
.map(function(d){ .map(function(d){
return definitions[d].join(':') })[0] return definitions[d].join(SP) })[0]
// remove... // remove...
} else if(value == null){ } else if(value == null){
@ -1873,7 +1893,10 @@ var TagsWithDictPrototype = {
// -> [str, ..] // -> [str, ..]
// //
translateTag: function(...tags){ translateTag: function(...tags){
var that = this var SS = this.SET_SEPARATOR
var PS = this.PATH_SEPARATOR
var SP = this.SET_SEPARATOR_PATTERN
var PP = this.PATH_SEPARATOR_PATTERN
var dict = this.dict var dict = this.dict
tags = normalizeSplit(tags) tags = normalizeSplit(tags)
@ -1881,14 +1904,14 @@ var TagsWithDictPrototype = {
tags tags
.map(function(path){ .map(function(path){
return path return path
.split(that.PATH_SEPARATOR) .split(PP)
.map(function(set){ .map(function(set){
return set return set
.split(that.SET_SEPARATOR) .split(SP)
.map(function(tag){ .map(function(tag){
return (dict[tag] || [tag])[0] }) return (dict[tag] || [tag])[0] })
.join(':') }) .join(SS) })
.join('/') }) .join(PS) })
: tags : tags
return arguments.length == 1 && typeof(arguments[0]) == typeof('str') ? return arguments.length == 1 && typeof(arguments[0]) == typeof('str') ?