1 // $Id$ 2 3 /** 4 * Represents a Solr parameter. 5 * 6 * @param properties A map of fields to set. Refer to the list of public fields. 7 * @class Parameter 8 */ 9 AjaxSolr.Parameter = AjaxSolr.Class.extend( 10 /** @lends AjaxSolr.Parameter.prototype */ 11 { 12 /** 13 * The parameter's name. 14 * 15 * @field 16 * @private 17 * @type String 18 */ 19 name: null, 20 21 /** 22 * The parameter's value. 23 * 24 * @field 25 * @private 26 * @type String 27 */ 28 value: null, 29 30 /** 31 * The parameter's local parameters. 32 * 33 * @field 34 * @private 35 * @type Object 36 * @default {} 37 */ 38 locals: {}, 39 40 /** 41 * Returns the value. If called with an argument, sets the value. 42 * 43 * @param {String|Number|String[]|Number[]} [value] The value to set. 44 * @returns The value. 45 */ 46 val: function (value) { 47 if (value === undefined) { 48 return this.value; 49 } 50 else { 51 this.value = value; 52 } 53 }, 54 55 /** 56 * Returns the value of a local parameter. If called with a second argument, 57 * sets the value of a local parameter. 58 * 59 * @param {String} name The name of the local parameter. 60 * @param {String|Number|String[]|Number[]} [value] The value to set. 61 * @returns The value. 62 */ 63 local: function (name, value) { 64 if (value === undefined) { 65 return this.locals[name]; 66 } 67 else { 68 this.locals[name] = value; 69 } 70 }, 71 72 /** 73 * Deletes a local parameter. 74 * 75 * @param {String} name The name of the local parameter. 76 */ 77 remove: function (name) { 78 delete this.locals[name]; 79 }, 80 81 /** 82 * Returns the Solr parameter as a query string key-value pair. 83 * 84 * <p>IE6 calls the default toString() if you write <tt>store.toString() 85 * </tt>. So, we need to choose another name for toString().</p> 86 */ 87 string: function () { 88 var pairs = []; 89 90 for (var name in this.locals) { 91 if (this.locals[name]) { 92 pairs.push(name + '=' + encodeURIComponent(this.locals[name])); 93 } 94 } 95 96 var prefix = pairs.length ? '{!' + pairs.join('%20') + '}' : ''; 97 98 if (this.value) { 99 return this.name + '=' + prefix + this.valueString(this.value); 100 } 101 // For dismax request handlers, if the q parameter has local params, the 102 // q parameter must be set to a non-empty value. In case the q parameter 103 // has local params but is empty, use the q.alt parameter, which accepts 104 // wildcards. 105 else if (this.name == 'q' && prefix) { 106 return 'q.alt=' + prefix + encodeURIComponent('*:*'); 107 } 108 else { 109 return ''; 110 } 111 }, 112 113 /** 114 * Parses a string formed by calling string(). 115 * 116 * @param {String} str The string to parse. 117 */ 118 parseString: function (str) { 119 var param = str.match(/^([^=]+)=(?:\{!([^\}]*)\})?(.*)$/); 120 if (param) { 121 var matches; 122 123 while (matches = /([^\s=]+)=(\S*)/g.exec(decodeURIComponent(param[2]))) { 124 this.locals[matches[1]] = decodeURIComponent(matches[2]); 125 param[2] = param[2].replace(matches[0], ''); // Safari's exec seems not to do this on its own 126 } 127 128 if (param[1] == 'q.alt') { 129 this.name = 'q'; 130 // if q.alt is present, assume it is because q was empty, as above 131 } 132 else { 133 this.name = param[1]; 134 this.value = this.parseValueString(param[3]); 135 } 136 } 137 }, 138 139 /** 140 * Returns the value as a URL-encoded string. 141 * 142 * @private 143 * @param {String|Number|String[]|Number[]} value The value. 144 * @returns {String} The URL-encoded string. 145 */ 146 valueString: function (value) { 147 value = AjaxSolr.isArray(value) ? value.join(',') : value; 148 return encodeURIComponent(value); 149 }, 150 151 /** 152 * Parses a URL-encoded string to return the value. 153 * 154 * @private 155 * @param {String} str The URL-encoded string. 156 * @returns {Array} The value. 157 */ 158 parseValueString: function (str) { 159 str = decodeURIComponent(str); 160 return str.indexOf(',') == -1 ? str : str.split(','); 161 } 162 }); 163 164 /** 165 * Escapes a value, to be used in, for example, an fq parameter. Surrounds 166 * strings containing spaces or colons in double quotes. 167 * 168 * @public 169 * @param {String|Number} value The value. 170 * @returns {String} The escaped value. 171 */ 172 AjaxSolr.Parameter.escapeValue = function (value) { 173 // If the field value has a space or a colon in it, wrap it in quotes, 174 // unless it is a range query or it is already wrapped in quotes. 175 if (value.match(/[ :]/) && !value.match(/[\[\{]\S+ TO \S+[\]\}]/) && !value.match(/^["\(].*["\)]$/)) { 176 return '"' + value + '"'; 177 } 178 return value; 179 } 180