split up zoomlevels into a separate thing. they are no longer in the filters array

This commit is contained in:
Konstantin Käfer 2011-01-26 11:34:51 -05:00
parent 5bd5b0fe9d
commit 51f12c9198
9 changed files with 77 additions and 33 deletions

View File

@ -760,20 +760,28 @@ mess.Parser = function Parser(env) {
// Selectors are made out of one or more Elements, see above.
//
selector: function() {
var a, attachment = null;
var a, attachment;
var e, elements = [];
var f, filters = [];
var z, zoom;
while (
(e = $(this.element)) ||
(z = $(this.zoom)) ||
(f = $(this.filter)) ||
(a = $(this.attachment))
) {
if (e) {
elements.push(e);
} else if (z) {
if (zoom) {
zoom.intersect(z);
} else {
zoom = z;
}
} else if (f) {
filters.push(f);
} else if (attachment !== null) {
} else if (attachment) {
throw errorMessage('Encountered second attachment name', i - 1);
} else {
attachment = a;
@ -783,27 +791,35 @@ mess.Parser = function Parser(env) {
if (c === '{' || c === '}' || c === ';' || c === ',') { break }
}
if (elements.length > 0 || filters.length > 0 || attachment !== null) {
return new tree.Selector(elements, filters, attachment, memo);
if (elements.length > 0 || filters.length > 0 || attachment || zoom) {
return new tree.Selector(elements, filters, zoom, attachment, memo);
}
},
filter: function() {
save();
var key, op, val;
if (! $('[')) return;
if (key = $(/^[a-zA-Z0-9-_]+/) || $(this.entities.quoted)) {
if ((op = $(this.entities.comparison)) &&
(val = $(this.entities.quoted) || $(/^[\w-]+/))) {
if (! $(']')) return;
if (key == 'zoom') {
return new tree.ZoomFilter(op, val, memo);
} else {
return new tree.Filter(key, op, val, memo);
}
return new tree.Filter(key, op, val, memo);
}
}
},
zoom: function() {
save();
var op, val;
if ($(/^\[zoom/g) &&
(op = $(this.entities.comparison)) &&
(val = $(/^\d+/)) &&
$(']')) {
return new tree.ZoomFilter(op, val, memo);
}
},
//
// The `block` rule is used by `ruleset` and `mixin.definition`.
// It's a wrapper around the `primary` rule, with added `{}`.

View File

@ -244,6 +244,7 @@ mess.Renderer = function Renderer(env) {
var winners = [];
var ancestors = [];
var belowThreshold = false;
var def;
while (def = definitions.shift()) {
if (belowThreshold) {
@ -275,20 +276,17 @@ mess.Renderer = function Renderer(env) {
var negatedZoom = tree.ZoomFilter.newFromRange([0, Infinity]);
for (var i = 0; i < definitions.length; i++) {
var definition = definitions[i];
var zooms = definition.selector.filters.filter(function(f) {
return f instanceof tree.ZoomFilter;
});
// Merge all zoom filters without overwriting existing zoom
// filters; they might be referenced in other selectors.
var zoom = tree.ZoomFilter.newFromRange([0, Infinity]);
zooms.forEach(function(f) { zoom.intersection(f); });
var selector = definitions[i].selector;
// Only add the negated current zoom when there actually are zoom filters.
var negation = zooms.length ? zoom.negate() : false;
if (selector.zoom) {
var zoom = selector.zoom.clone();
var negation = zoom.negate();
zoom.intersection(negatedZoom);
} else {
var zoom = negatedZoom.clone();
}
zoom.intersection(negatedZoom);
var zoomRanges = zoom.getRanges();
if (!zoomRanges.length) {
continue;
@ -299,13 +297,13 @@ mess.Renderer = function Renderer(env) {
}
// Resolve regular filters.
var filters = definition.selector.filters.filter(function(f) {
var filters = selector.filters.filter(function(f) {
return f instanceof tree.Filter;
});
var negation = filters.map(function(f) { return f.negate(); });
// add in existing negations
// TODO: run uniq on this.
filters.push.apply(filters, negatedFilters);
// Throw out contradicting rules.
@ -316,12 +314,12 @@ mess.Renderer = function Renderer(env) {
negatedFilters.push.apply(negatedFilters, negation);
}
definition.selector.filters = filters;
definition.selector.zoom = zoom;
selector.filters = filters;
selector.zoom = zoom;
// Add a separate rule for each zoom range.
for (var j = 0; j < zoomRanges.length; j++) {
var rule = definition.clone();
var rule = definitions[i].clone();
rule.selector.zoom = tree.ZoomFilter.newFromRange(zoomRanges[j]);
rules.push(rule);
}
@ -392,7 +390,7 @@ mess.Renderer = function Renderer(env) {
// in order from high specificity to low.
var bySymbolizer = that.splitSymbolizers(matching);
for (sym in bySymbolizer) {
for (var sym in bySymbolizer) {
// Create styles out of chains of one-symbolizer rules,
// and assign those styles to layers
var new_style = new mess.tree.Style(

View File

@ -26,6 +26,11 @@ tree.Comparison.prototype = {
},
eval: function() {
return this;
},
clone: function() {
var obj = Object.create(Object.getPrototypeOf(this));
obj.value = this.value;
return obj;
}
};

View File

@ -36,7 +36,7 @@ tree.Filter.prototype.conflictsWith = function(filter) {
filter.op.value === '=') {
return true;
}
if (this.val.toString() === filter.val.toString() &&
((this.op.value === '!=' && filter.op.value === '=') ||
(this.op.value === '=' && filter.op.value === '!='))) {
@ -56,6 +56,14 @@ tree.Filter.prototype.overrides = function(filter) {
if (this.op.value === '=') return true;
};
tree.Filter.prototype.clone = function() {
var obj = Object.create(Object.getPrototypeOf(this));
obj.key = this.key;
obj.op = this.op.clone();
obj.val = this.val.clone ? this.val.clone() : this.val;
obj.index = this.index;
return obj;
};
tree.Filter.sound = function(filters) {
for (var i = 0; i < filters.length; i++) {

View File

@ -128,6 +128,11 @@ tree.Ruleset.prototype = {
var instance = new tree.Selector();
instance.elements = parent.elements.concat(selector.elements);
instance.filters = parent.filters.concat(selector.filters);
if (parent.zoom && selector.zoom) {
instance.zoom = parent.zoom.clone().intersection(selector.zoom);
} else if (parent.zoom || selector.zoom) {
instance.zoom = (parent.zoom || selector.zoom).clone()
}
instance.attachment = selector.attachment;
instance.index = selector.index;

View File

@ -1,9 +1,10 @@
(function(tree) {
tree.Selector = function Selector(elements, filters, attachment, index) {
tree.Selector = function Selector(elements, filters, zoom, attachment, index) {
this.elements = elements || [];
this.attachment = attachment || '__default__';
this.filters = filters || [];
this.zoom = zoom;
this.index = index;
};
@ -27,12 +28,13 @@ tree.Selector.prototype.clone = function() {
* [ID, Class, Filters, Position in document]
*/
tree.Selector.prototype.specificity = function() {
var zoomSpecificity = this.zoom ? this.zoom.specificity : 0;
return this.elements.reduce(function(memo, e) {
var spec = e.specificity();
memo[0] += spec[0];
memo[1] += spec[1];
return memo;
}, [0, 0, this.filters.length, this.index]);
}, [0, 0, this.filters.length + zoomSpecificity, this.index]);
};
/**
@ -58,7 +60,6 @@ tree.Selector.prototype.layers = function(env) {
tree.Selector.prototype.simplifiedFilters = function() {
var simplified = [];
filters: for (var i = 0; i < this.filters.length; i++) {
if (!(this.filters[i] instanceof tree.Filter)) continue filters;
// Operate from the back so that we don't run into renumbering problems
// when deleting items from the array.
for (var j = simplified.length - 1; j >= 0; j--) {

View File

@ -18,6 +18,13 @@ tree.Value.prototype = {
return this.value.map(function(e) {
return e.toString(env);
}).join(', ');
},
clone: function() {
var obj = Object.create(Object.getPrototypeOf(this));
if (Array.isArray(obj)) obj.value = this.value.slice();
else obj.value = this.value;
obj.is = this.is;
return obj;
}
};

View File

@ -9,6 +9,7 @@ tree.ZoomFilter = function ZoomFilter(op, value, index) {
};
}
this.range = tree.ZoomFilter.rangeFromCondition(op.value, value);
this.specificity = 1;
};
tree.ZoomFilter.newFromRange = function(range) {
@ -99,7 +100,9 @@ tree.ZoomFilter.prototype.intersection = function(filter) {
for (var i = 0; i < this.range.length; i++) {
this.range[i] = this.range[i] && filter.range[i];
}
this.specificity += filter.specificity;
}
return this;
};
/**
@ -133,6 +136,7 @@ tree.ZoomFilter.prototype.toXML = function(env) {
tree.ZoomFilter.prototype.clone = function() {
var obj = Object.create(Object.getPrototypeOf(this));
obj.range = this.range.slice();
obj.specificity = this.specificity;
return obj;
}

View File

@ -1,8 +1,8 @@
[
{"elements":["#world","#countries"],"filters":[{"key":"NAME","op":"=","val":"United States"}]},
{"elements":["#world"],"filters":[{"key":"NAME","op":"=","val":"United States"},{"range":"0000001111111111111111"}]},
{"elements":["#world"],"filters":[{"key":"NAME","op":"=","val":"United States"}],"zoom":{"range":"0000001111111111111111","specificity":1}},
{"elements":["#world"],"filters":[{"key":"NAME","op":"=","val":"United States"}]},
{"elements":["#world"],"filters":[{"key":"NAME","op":"=","val":"Canada"}]},
{"elements":[],"filters":[{"range":"0000001111111111111111"}]},
{"elements":[],"zoom":{"range":"0000001111111111111111","specificity":1}},
{"elements":[],"filters":[{"key":"NAME","op":"=","val":"United States"}]}
]
]