-
-
Save heldr/6720204 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2011 Yahoo! Inc. All rights reserved. | |
*/ | |
/*jslint nomen: true */ | |
(function () { | |
'use strict'; | |
function mix(target, source){ | |
var attribute; | |
for(attribute in source){ | |
if(source.hasOwnProperty(attribute)){ | |
target[attribute] = source[attribute]; | |
} | |
} | |
return target | |
} | |
window.Selector = function Selector(data) { | |
var selectorInstance = function () { | |
return selectorInstance.__invoke.apply(selectorInstance, arguments); | |
}; | |
if (typeof data === 'string') { | |
data = JSON.parse(data); | |
} | |
mix(selectorInstance, { | |
data: data, | |
focus: function (path) { | |
var pathParts = path.split('.'), | |
data = this.data, | |
self = this; | |
pathParts.forEach(function (attribute) { | |
if (!self.isset(data) || !self.isset(data[attribute])) { | |
data = null; | |
return; | |
} | |
data = data[attribute]; | |
}); | |
return Selector(data); | |
}, | |
__invoke: function (path, defaultValue) { | |
path = this.clearPath(path); | |
switch (this.askingFor(path)) { | |
case 'list': | |
defaultValue = defaultValue === undefined ? [] : defaultValue; | |
return this.getList(path, defaultValue); | |
case 'dictionary': | |
return this.getDictionaryFromPath(path); | |
default: | |
return this.getOne(path, defaultValue); | |
} | |
}, | |
findOne: function (contextPath, fieldPath, value) { | |
var items = this.findAll(contextPath, fieldPath, value); | |
return items[0]; | |
}, | |
findAll: function (contextPath, fieldPath, value) { | |
var contextObjects = this.getAll(contextPath), | |
foundObjects = contextObjects.filter(function (item) { | |
var contextParser = Selector(item), | |
foundValues = contextParser("[" + fieldPath + "]"); | |
return foundValues.indexOf(value) > -1; | |
}); | |
return foundObjects; | |
}, | |
isList: function (data) { | |
return data instanceof Array; | |
}, | |
//protected from here | |
clearPath: function (path) { | |
return path.replace(/\s+/g, ''); | |
}, | |
askingFor: function (path) { | |
var posFirstChar = 0, | |
posLastChar = path.length - 1; | |
if (path.indexOf('[') === posFirstChar && path.indexOf(']') === posLastChar) { | |
return 'list'; | |
} | |
if (path.indexOf('{') === posFirstChar && path.indexOf('}') === posLastChar) { | |
return 'dictionary'; | |
} | |
return 'one'; | |
}, | |
getList: function (path, defaultValue) { | |
path = path.replace(/\[|\]/g, ''); | |
return this.getAll(path, defaultValue); | |
}, | |
getDictionaryFromPath: function (path) { | |
var keys, values, pathParts; | |
path = path.replace(/\{|\}/g, ''); | |
pathParts = path.split(':'); | |
keys = pathParts[0]; | |
values = pathParts[1]; | |
return this.getDictionary(keys, values); | |
}, | |
getOne: function (path, defaultValue) { | |
var results = this.getAll(path); | |
return results[0] !== undefined ? results[0] : defaultValue; | |
}, | |
getAll: function (path, defaultValue) { | |
var self = this, | |
orToken = '|', | |
possiblePaths = path.split(orToken), | |
result, | |
possiblePath; | |
defaultValue = defaultValue !== undefined ? defaultValue : []; | |
possiblePaths.forEach(function (possiblePath) { | |
if (result !== undefined) { return; } | |
result = self.getAllFromPath(possiblePath); | |
}); | |
if (result !== undefined) { | |
return result; | |
} | |
return defaultValue; | |
}, | |
getAllFromPath: function (path) { | |
var self = this, | |
pathParts = path.split('.'), | |
results = [], | |
data = this.data; | |
pathParts.forEach(function (attribute) { | |
if (data === undefined) { return; } | |
results = data = self.getAllWithAttribute(data, attribute); | |
}); | |
return results.length === 0 ? undefined : results; | |
}, | |
getAllWithAttribute: function (data, attribute) { | |
var results = [], | |
self = this; | |
data = data instanceof Array ? data : [data]; | |
data.forEach(function (item) { | |
if (!self.isset(item)) { return; } | |
if (!self.isset(item[attribute])) { return; } | |
if (self.isList(item[attribute])) { | |
results = results.concat(item[attribute]); | |
} else { | |
results.push(item[attribute]); | |
} | |
}); | |
return results; | |
}, | |
isset: function (data) { | |
return data !== undefined && data !== null; | |
}, | |
getDictionary: function (keysPath, valuesPath) { | |
var keys = this.getAll(keysPath), | |
values = this.getAll(valuesPath, []), | |
result = {}; | |
if (!keys || !(keys instanceof Array) || !keys.length) { | |
return {}; | |
} | |
keys.forEach(function (key, position) { | |
result[key] = values[position] === undefined ? null : values[position]; | |
}); | |
return result; | |
} | |
}); | |
return selectorInstance; | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment