From 6571489ef9bb49b2231a423de1d741939b390e8e Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 20 Jan 2011 11:53:28 -0500 Subject: [PATCH] Adding zoomfilter type to alleviate filter complexity --- lib/mess/index.js | 2 +- lib/mess/parser.js | 6 +- lib/mess/tree/filter.js | 123 ++---------------------------------- lib/mess/tree/zoomfilter.js | 120 +++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 118 deletions(-) create mode 100644 lib/mess/tree/zoomfilter.js diff --git a/lib/mess/index.js b/lib/mess/index.js index f7d84c1..8da86f2 100644 --- a/lib/mess/index.js +++ b/lib/mess/index.js @@ -82,7 +82,7 @@ var mess = { 'selector', 'quoted', 'expression', 'rule', 'call', 'url', 'alpha', 'import', 'mixin', 'comment', 'anonymous', 'value', 'javascript', - 'comparison', 'reference', 'filter' + 'comparison', 'reference', 'filter', 'zoomfilter' ].forEach(function (n) { require(path.join('mess', 'tree', n)); }); diff --git a/lib/mess/parser.js b/lib/mess/parser.js index b08eb20..a5ed03d 100644 --- a/lib/mess/parser.js +++ b/lib/mess/parser.js @@ -858,7 +858,11 @@ mess.Parser = function Parser(env) { if ((op = $(this.entities.comparison)) && (val = $(this.entities.quoted) || $(/^[\w-]+/))) { if (! $(']')) return; - return new(tree.Filter)(key, op, val, memo); + if (key == 'zoom') { + return new(tree.ZoomFilter)(key, op, val, memo); + } else { + return new(tree.Filter)(key, op, val, memo); + } } } }, diff --git a/lib/mess/tree/filter.js b/lib/mess/tree/filter.js index 7228ffd..1576b5f 100644 --- a/lib/mess/tree/filter.js +++ b/lib/mess/tree/filter.js @@ -6,126 +6,17 @@ tree.Filter = function(key, op, val, index) { this.op = op; this.val = val; this.index = index; - - /** - * Create an array of true, false values - * which denotes whether this filter should apply - * to each of the zoom levels from 0-22. - */ - if (this.key === 'zoom') { - var val = parseInt(this.val, 10); - this.zoom_range = []; - - if (this.op.value === '>' || this.op.value === '>=') { - if (this.op.value === '>') val++; - for (var i = 0; i < this.max_zoom; i++) { - this.zoom_range[i] = (i <= val); - } - } else { - // TODO: non-correct ops will fail here - if (this.op.value === '<') val--; - for (var i = 0; i < this.max_zoom; i++) { - this.zoom_range[i] = (i >= val); - } - } - } - - this.zooms = { - '1': [200000000, 500000000], - '2': [100000000, 200000000], - '3': [50000000, 100000000], - '4': [25000000, 50000000], - '5': [12500000, 25000000], - '6': [6500000, 12500000], - '7': [3000000, 6500000], - '8': [1500000, 3000000], - '9': [750000, 1500000], - '10': [400000, 750000], - '11': [200000, 400000], - '12': [100000, 200000], - '13': [50000, 100000], - '14': [25000, 50000], - '15': [12500, 25000], - '16': [5000, 12500], - '17': [2500, 5000], - '18': [1000, 2500], - '19': [500, 1000], - '20': [250, 500], - '21': [100, 250], - '22': [50, 100] - }; -}; - -/** - * Find the overlap of this and another set - */ -tree.Filter.prototype.intersection = function(filter) { - if (filter.zoom_range) { - for (var i = 0; i < this.max_zoom; i++) { - this.zoom_range[i] = this.zoom_range[i] && filter.zoom_range[i]; - } - } -}; - -/** - * Find the union of this and another set - */ -tree.Filter.prototype.union = function(filter) { - if (filter.zoom_range) { - for (var i = 0; i < this.max_zoom; i++) { - this.zoom_range[i] = this.zoom_range[i] || filter.zoom_range[i]; - } - } -}; - -/** - * Invert this style rule. Apply to all zoom levels - * that the rule previously did not apply to and - * vice versa. - * - * Usage is for doing the equivalent of an ElseFilter - * for defaulting to non-zoom-filtered rules - */ -tree.Filter.prototype.inverse = function() { - for (var i = 0; i < this.max_zoom; i++) { - this.zoom_range[i] = !this.zoom_range[i]; - } }; tree.Filter.prototype.toCSS = function(env) { - if (this.key === 'zoom') { - if (parseInt(this.val) > 22 || parseInt(this.val) < 0) { - throw { - message: 'Only zoom levels between 0 and 22 supported.', - index: this.index - } - } - if (this.op.toCSS() == '>') { - return '' + this.zooms[this.val][0] + - ''; - } - if (this.op.toCSS() == '> =') { - return '' + this.zooms[this.val][1] + - ''; - } - if (this.op.toCSS() == '<') { - return '' + this.zooms[this.val][1] + - ''; - } - if (this.op.toCSS() == '< =') { - return '' + this.zooms[this.val][0] + - ''; - } - } else { - if (this.val.is) { - this.val = this.val.toCSS((this.val.is == 'string')); - } - return '[' + this.key + '] ' + - this.op.toCSS() + - ' ' + - this.val + - ''; + if (this.val.is) { + this.val = this.val.toCSS((this.val.is == 'string')); } + return '[' + this.key + '] ' + + this.op.toCSS() + + ' ' + + this.val + + ''; }; })(require('mess/tree')); diff --git a/lib/mess/tree/zoomfilter.js b/lib/mess/tree/zoomfilter.js new file mode 100644 index 0000000..31708b4 --- /dev/null +++ b/lib/mess/tree/zoomfilter.js @@ -0,0 +1,120 @@ +(function(tree) { + +tree.ZoomFilter = function(key, op, val, index) { + this.key = key; + this.op = op; + this.val = parseInt(val); + this.index = index; + this.zoom_range = this.create_range(this.op.value, this.val); + + this.zooms = { + + }; +}; + +/** + * Create an array of true, false values + * which denotes whether this filter should apply + * to each of the zoom levels from 0-22. + */ +tree.ZoomFilter.prototype.create_range = function(op, value) { + var max_zoom = 22; + var zoom_range = []; + if (op === '>' || op === '>=') { + if (op === '>') val++; + for (var i = 0; i < max_zoom; i++) { + zoom_range[i] = (i >= val); + } + } else { + if (op === '<') val--; + for (var i = 0; i < max_zoom; i++) { + zoom_range[i] = (i <= val); + } + } + return zoom_range; +}; + +/** + * Find the overlap of this and another set + */ +tree.ZoomFilter.prototype.intersection = function(filter) { + if (filter.zoom_range) { + for (var i = 0; i < this.max_zoom; i++) { + this.zoom_range[i] = this.zoom_range[i] && filter.zoom_range[i]; + } + } +}; + +/** + * Find the union of this and another set + */ +tree.ZoomFilter.prototype.union = function(filter) { + if (filter.zoom_range) { + for (var i = 0; i < this.max_zoom; i++) { + this.zoom_range[i] = this.zoom_range[i] || filter.zoom_range[i]; + } + } +}; + +/** + * Invert this style rule. Apply to all zoom levels + * that the rule previously did not apply to and + * vice versa. + * + * Usage is for doing the equivalent of an ElseFilter + * for defaulting to non-zoom-filtered rules + */ +tree.ZoomFilter.prototype.inverse = function() { + for (var i = 0; i < this.max_zoom; i++) { + this.zoom_range[i] = !this.zoom_range[i]; + } +}; + +tree.ZoomFilter.prototype.toCSS = function(env) { + if (this.val > 22 || this.val < 0) { + throw { + message: 'Only zoom levels between 0 and 22 supported.', + index: this.index + } + } + + var zooms = { + '1': [200000000, 500000000], + '2': [100000000, 200000000], + '3': [50000000, 100000000], + '4': [25000000, 50000000], + '5': [12500000, 25000000], + '6': [6500000, 12500000], + '7': [3000000, 6500000], + '8': [1500000, 3000000], + '9': [750000, 1500000], + '10': [400000, 750000], + '11': [200000, 400000], + '12': [100000, 200000], + '13': [50000, 100000], + '14': [25000, 50000], + '15': [12500, 25000], + '16': [5000, 12500], + '17': [2500, 5000], + '18': [1000, 2500], + '19': [500, 1000], + '20': [250, 500], + '21': [100, 250], + '22': [50, 100]}; + + switch (this.op.value) { + case '>': + return '' + zooms[this.val][0] + + ''; + case '>=': + return '' + zooms[this.val][1] + + ''; + case '<': + return '' + zooms[this.val][1] + + ''; + case '<=': + return '' + zooms[this.val][0] + + ''; + } +}; +})(require('mess/tree'));