Created
January 17, 2013 17:49
Revisions
-
snit-ram created this gist
Jan 17, 2013 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,204 @@ /* * 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; }; })();