+ };
+
+ that.pp2limit = function(initial) {
+ var res = initial || "";
+
+ that.visitFields(function(field, value) {
+ if (res) res += ",";
+ res += field + "=" + value.replace(/[\\|,]/g, '\\$&');
+ });
+ return res;
+ }
+
+ that.pp2catLimit = function() {
+ var res = "";
+
+ that.visitCategories(function(id) {
+ if (res) res += ",";
+ res += "category~" + id.replace(/[\\,]/g, '\\$&');
+ });
+ return res;
+ }
+
+ // Returns a hash of key=value pairs representing the filter-set
+ // These will become part of the URL-fragment representing the state
+ that.fragmentItems = function() {
+ var hash = {};
+
+ for (var i in m_list) {
+ var filter = m_list[i];
+ var type = filter.type;
+ if (type === 'target') {
+ hash['xt-' + filter.id] = filter.name;
+ } else if (type === 'field') {
+ // Ugly names, but we need to include the value because fields can be repeated
+ hash['xf-' + filter.field + '-' + filter.value] = 1;
+ } else if (type === 'category') {
+ hash['xc-' + filter.id] = 1;
+ } else {
+ alert("unsupported filter-type '" + type + "'");
+ }
+ }
+
+ return hash;
+ }
+
+ return that;
+}
+
+
+// Factory functions for filters. These can be of several types.
+function targetFilter(id, name) {
+ return {
+ type: 'target',
+ id: id,
+ name: name
+ };
+}
+
+function fieldFilter(field, value) {
+ return {
+ type: 'field',
+ field: field,
+ value: value
+ };
+}
+
+function categoryFilter(id) {
+ return {
+ type: 'category',
+ id: id
+ };