diff --git a/lib/mess/renderer.js b/lib/mess/renderer.js index 07e14f5..5550b3b 100644 --- a/lib/mess/renderer.js +++ b/lib/mess/renderer.js @@ -4,7 +4,8 @@ var path = require('path'), Step = require('step'), _ = require('underscore')._, sys = require('sys'), - mess = require('mess'); + mess = require('mess'), + tree = require('mess/tree'); require.paths.unshift(path.join(__dirname, '..', 'lib')); @@ -211,7 +212,7 @@ mess.Renderer = function Renderer(env) { // definitions are ordered in specificity, // high to low // - // basically if 'this level' has + // basically if 'this level' has // a filter, then keep going, otherwise // this is the final selector. var winners = []; @@ -244,21 +245,34 @@ mess.Renderer = function Renderer(env) { }, resolve_filters: function(definitions) { - var negated_filters = []; + var negatedFilters = []; + var negatedZoom = new tree.ZoomFilter('zoom', { value: '>=' }, '0'); + for (var i = 0; i < definitions.length; i++) { - if (definitions[i].selector.filters.length) { - // array of the negation of this definition's filters - var negation = definitions[i].selector.filters.map( - function(f) { return f.negate(); }); + var filters = definitions[i].selector.filters; + var normal = filters.filter(function(f) { return f instanceof tree.Filter; }); + var zoom = filters.filter(function(f) { return f instanceof tree.ZoomFilter; }); - // add in existing negations - // TODO: run uniq on this. - definitions[i].selector.filters = - definitions[i].selector.filters.concat(negated_filters); + var negation = normal.map(function(f) { return f.negate(); }); - // add this definition's filter's negations to the list - negated_filters = negated_filters.concat(negation); - } + // add in existing negations + // TODO: run uniq on this. + normal.push.apply(normal, negatedFilters); + + // add this definition's filter's negations to the list + negatedFilters.push.apply(negatedFilters, negation); + + // Merge all zoom filters without overwriting existing zoom + // filters; they might be referenced in other selectors. + var currentZoom = new tree.ZoomFilter('zoom', { value: '>=' }, '0'); + zoom.forEach(function(f) { currentZoom.intersection(f); }); + + // Only add the negated current zoom when there actually are zoom filters. + var negation = zoom.length ? currentZoom.negated() : false; + currentZoom.intersection(negatedZoom); + if (negation) negatedZoom.intersection(negation); + + definitions[i].selector.filters = normal.concat([currentZoom]); } return definitions; }, @@ -348,14 +362,14 @@ mess.Renderer = function Renderer(env) { * @param {Array} stylesheets the results of ruleHash(). * @return Formalized layer definition with .styles = []. */ - + var rulesets = _.flatten(stylesheets.map(function(rulesets) { return rulesets[2].toMSS(); })); var output = [entities(entity_list)]; // TODO: must change when background colors are available - output.push('