// $Id$ /** * Represents a Solr parameter. * * @param properties A map of fields to set. Refer to the list of public fields. * @class Parameter */ AjaxSolr.Parameter = AjaxSolr.Class.extend( /** @lends AjaxSolr.Parameter.prototype */ { /** * The parameter's name. * * @field * @private * @type String */ name: null, /** * The parameter's value. * * @field * @private * @type String */ value: null, /** * The parameter's local parameters. * * @field * @private * @type Object * @default {} */ locals: {}, /** * Returns the value. If called with an argument, sets the value. * * @param {String|Number|String[]|Number[]} [value] The value to set. * @returns The value. */ val: function (value) { if (value === undefined) { return this.value; } else { this.value = value; } }, /** * Returns the value of a local parameter. If called with a second argument, * sets the value of a local parameter. * * @param {String} name The name of the local parameter. * @param {String|Number|String[]|Number[]} [value] The value to set. * @returns The value. */ local: function (name, value) { if (value === undefined) { return this.locals[name]; } else { this.locals[name] = value; } }, /** * Deletes a local parameter. * * @param {String} name The name of the local parameter. */ remove: function (name) { delete this.locals[name]; }, /** * Returns the Solr parameter as a query string key-value pair. * *

IE6 calls the default toString() if you write store.toString() * . So, we need to choose another name for toString().

*/ string: function () { var pairs = []; for (var name in this.locals) { if (this.locals[name]) { pairs.push(name + '=' + encodeURIComponent(this.locals[name])); } } var prefix = pairs.length ? '{!' + pairs.join('%20') + '}' : ''; if (this.value) { return this.name + '=' + prefix + this.valueString(this.value); } // For dismax request handlers, if the q parameter has local params, the // q parameter must be set to a non-empty value. In case the q parameter // has local params but is empty, use the q.alt parameter, which accepts // wildcards. else if (this.name == 'q' && prefix) { return 'q.alt=' + prefix + encodeURIComponent('*:*'); } else { return ''; } }, /** * Parses a string formed by calling string(). * * @param {String} str The string to parse. */ parseString: function (str) { var param = str.match(/^([^=]+)=(?:\{!([^\}]*)\})?(.*)$/); if (param) { var matches; while (matches = /([^\s=]+)=(\S*)/g.exec(decodeURIComponent(param[2]))) { this.locals[matches[1]] = decodeURIComponent(matches[2]); param[2] = param[2].replace(matches[0], ''); // Safari's exec seems not to do this on its own } if (param[1] == 'q.alt') { this.name = 'q'; // if q.alt is present, assume it is because q was empty, as above } else { this.name = param[1]; this.value = this.parseValueString(param[3]); } } }, /** * Returns the value as a URL-encoded string. * * @private * @param {String|Number|String[]|Number[]} value The value. * @returns {String} The URL-encoded string. */ valueString: function (value) { value = AjaxSolr.isArray(value) ? value.join(',') : value; return encodeURIComponent(value); }, /** * Parses a URL-encoded string to return the value. * * @private * @param {String} str The URL-encoded string. * @returns {Array} The value. */ parseValueString: function (str) { str = decodeURIComponent(str); return str.indexOf(',') == -1 ? str : str.split(','); } }); /** * Escapes a value, to be used in, for example, an fq parameter. Surrounds * strings containing spaces or colons in double quotes. * * @public * @param {String|Number} value The value. * @returns {String} The escaped value. */ AjaxSolr.Parameter.escapeValue = function (value) { // If the field value has a space or a colon in it, wrap it in quotes, // unless it is a range query or it is already wrapped in quotes. if (value.match(/[ :]/) && !value.match(/[\[\{]\S+ TO \S+[\]\}]/) && !value.match(/^["\(].*["\)]$/)) { return '"' + value + '"'; } return value; }