Skip to content

Instantly share code, notes, and snippets.

@ahn
Created January 14, 2016 13:53
Show Gist options
  • Save ahn/7d82017bef2f5641c7e7 to your computer and use it in GitHub Desktop.
Save ahn/7d82017bef2f5641c7e7 to your computer and use it in GitHub Desktop.
/**
var css2mongo = require('css2mongo');
css2mongo('.foo.bar[xxx="yyy"], #AAA');
{
"$or": [
{
"$and": [
{
"classes": {
"$all": [
"bar",
"foo"
]
}
},
{
"xxx": "yyy"
}
]
},
{
"id": "AAA"
}
]
}
*/
var slick = require('slick');
function cssToMongoQuery(css) {
if (typeof css === 'string') {
css = slick.parse(css);
}
if (css.length === 1) {
return exprToMongoQuery(css[0]);
}
var or = [];
for (var i=0; i<css.length; i++) {
or.push(exprToMongoQuery(css[i]));
}
return {'$or': or};
}
function exprToMongoQuery(expr) {
if (expr.length !== 1) {
throw "ERROR: Multiple parts in an expressions doesn't make sense";
}
var part = expr[0];
var and = [];
if (part.id) {
and.push(idToMongoQuery(part.id));
}
if (part.tag !== '*') {
and.push(tagToMongoQuery(part.tag));
}
if (part.classList) {
and.push(classesToMongoQuery(part.classList));
}
if (part.attributes) {
and.push(attributesToMongoQuery(part.attributes));
}
// TODO: pseudo classes
if (and.length === 1) {
return and[0];
}
return {$and: and};
}
function classesToMongoQuery(classes) {
if (classes.length === 1) {
return { classes: classes[0] };
}
return {classes: {$all: classes}};
}
function idToMongoQuery(id) {
return {id: id};
}
function tagToMongoQuery(tag) {
return {type: tag};
}
function attributesToMongoQuery(attrs) {
if (attrs.length === 1) {
return attrToMongoQuery(attrs[0]);
}
return {$and: attrs.map(attrToMongoQuery)};
}
function attrToMongoQuery(attr) {
var q = {};
var op = attr.operator;
if (op === '=') {
q[attr.name] = attr.value;
}
else {
// TODO: other operators
throw "Unknown operator: " + attr.operator;
}
return q;
}
module.exports = cssToMongoQuery;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment