split up zoomlevels into a separate thing. they are no longer in the filters array
This commit is contained in:
parent
5bd5b0fe9d
commit
51f12c9198
@ -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 `{}`.
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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--) {
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"}]}
|
||||
]
|
||||
]
|
Loading…
Reference in New Issue
Block a user