154 lines
5.9 KiB
JavaScript
154 lines
5.9 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
/**
|
||
|
* Zips the pref[n|v] http query params
|
||
|
*
|
||
|
* The Platform allows the use of multiple preference names and values to filter search results,
|
||
|
* eg.: http://<sandbox>.com/../Search-Show?prefn1=refinementColor&prefv1=Blue&prefn2=size&prefv2=16
|
||
|
*
|
||
|
* @param {Object} preferences - HTTP query parameters map specific to selected refinement values
|
||
|
* @return {Object} Map of provided preference name/value pairs
|
||
|
*/
|
||
|
function parsePreferences(preferences) {
|
||
|
var params = {};
|
||
|
var count = Math.floor(Object.keys(preferences).length / 2);
|
||
|
var key = '';
|
||
|
var value = '';
|
||
|
|
||
|
for (var i = 1; i < count + 1; i++) {
|
||
|
key = preferences['prefn' + i];
|
||
|
if (preferences['prefmin' + i]) {
|
||
|
value = {
|
||
|
min: preferences['prefmin' + i],
|
||
|
max: preferences['prefmax' + i]
|
||
|
};
|
||
|
} else {
|
||
|
value = preferences['prefv' + i];
|
||
|
}
|
||
|
params[key] = value;
|
||
|
}
|
||
|
|
||
|
return params;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Detect duplicate parameters and be sure to set object[key] as an array of those parameter values
|
||
|
*
|
||
|
* @param {Object} object The object to check for existing values.
|
||
|
* @param {string} key The key to set on object for the new value.
|
||
|
* @param {string} value The new value to be added to object[key].
|
||
|
* @return {Object} Value or array of values if object[key] has already exists.
|
||
|
*/
|
||
|
function parameterToArray(object, key, value) {
|
||
|
var result = value;
|
||
|
if (object[key]) {
|
||
|
result = object[key];
|
||
|
if (!(result instanceof Array)) {
|
||
|
result = [object[key]];
|
||
|
}
|
||
|
result.push(value);
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
var querystring = function (raw) {
|
||
|
var pair;
|
||
|
var left;
|
||
|
var preferences = {};
|
||
|
|
||
|
if (raw && raw.length > 0) {
|
||
|
var qs = raw.substring(raw.indexOf('?') + 1).replace(/\+/g, '%20').split('&');
|
||
|
for (var i = qs.length - 1; i >= 0; i--) {
|
||
|
pair = qs[i].split('=');
|
||
|
left = decodeURIComponent(pair[0]);
|
||
|
if (left.indexOf('dwvar_') === 0) {
|
||
|
left = left.replace(/__/g, '++');
|
||
|
var variableParts = left.split('_');
|
||
|
if (variableParts.length >= 3) {
|
||
|
if (!this.variables) {
|
||
|
this.variables = {};
|
||
|
}
|
||
|
this.variables[variableParts.slice(2).join('_')] = {
|
||
|
id: variableParts[1].replace(/\+\+/g, '_'),
|
||
|
value: decodeURIComponent(pair[1])
|
||
|
};
|
||
|
continue; // eslint-disable-line no-continue
|
||
|
}
|
||
|
} else if (left.indexOf('dwopt_') === 0) {
|
||
|
left = left.replace(/__/g, '++');
|
||
|
var optionParts = left.split('_');
|
||
|
var productId = optionParts[1].replace(/\+\+/g, '_');
|
||
|
var optionId = optionParts.slice(2).join('_');
|
||
|
var selectedOptionValueId = decodeURIComponent(pair[1]);
|
||
|
if (optionParts.length >= 3) {
|
||
|
if (!this.options) {
|
||
|
this.options = [];
|
||
|
}
|
||
|
this.options.push({
|
||
|
optionId: optionId,
|
||
|
selectedValueId: selectedOptionValueId,
|
||
|
productId: productId
|
||
|
});
|
||
|
continue; // eslint-disable-line no-continue
|
||
|
}
|
||
|
} else if (left.indexOf('pref') === 0) {
|
||
|
preferences[left] = decodeURIComponent(pair[1]);
|
||
|
continue; // eslint-disable-line no-continue
|
||
|
}
|
||
|
|
||
|
this[left] = parameterToArray(this, left, decodeURIComponent(pair[1]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Object.keys(preferences).length) {
|
||
|
this.preferences = parsePreferences(preferences);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
querystring.prototype.toString = function () {
|
||
|
var result = [];
|
||
|
var prefKeyIdx = 1;
|
||
|
var preferences = {};
|
||
|
|
||
|
Object.keys(this).forEach(function (key) {
|
||
|
if (key === 'variables' && this.variables instanceof Object) {
|
||
|
Object.keys(this.variables).forEach(function (variable) {
|
||
|
result.push('dwvar_' +
|
||
|
this.variables[variable].id.replace(/_/g, '__') + '_' +
|
||
|
variable + '=' + encodeURIComponent(this.variables[variable].value));
|
||
|
}, this);
|
||
|
} else if (key === 'options' && this.options instanceof Array) {
|
||
|
this.options.forEach(function (option) {
|
||
|
result.push('dwopt_' +
|
||
|
option.productId.replace(/_/g, '__') + '_' +
|
||
|
option.optionId + '=' + encodeURIComponent(option.selectedValueId));
|
||
|
});
|
||
|
} else if (key === 'preferences' && this.preferences instanceof Object) {
|
||
|
preferences = this.preferences;
|
||
|
Object.keys(preferences).forEach(function (prefKey) {
|
||
|
// Due to the nature of what is passed to this function this may be the literal string "undefined"
|
||
|
if (prefKey !== 'undefined' && preferences[prefKey]) {
|
||
|
result.push('prefn' + prefKeyIdx + '=' + encodeURIComponent(prefKey));
|
||
|
if (preferences[prefKey].min) {
|
||
|
result.push('prefmin' + prefKeyIdx + '=' + encodeURIComponent(preferences[prefKey].min));
|
||
|
result.push('prefmax' + prefKeyIdx + '=' + encodeURIComponent(preferences[prefKey].max));
|
||
|
} else {
|
||
|
result.push('prefv' + prefKeyIdx + '=' + encodeURIComponent(preferences[prefKey]));
|
||
|
}
|
||
|
} else {
|
||
|
var Logger = require('dw/system/Logger');
|
||
|
Logger.warn('We were passed a key "undefined in the preferences object in queryString.js');
|
||
|
}
|
||
|
prefKeyIdx++;
|
||
|
});
|
||
|
} else {
|
||
|
result.push(encodeURIComponent(key) + '=' + encodeURIComponent(this[key]));
|
||
|
}
|
||
|
}, this);
|
||
|
|
||
|
return result.sort().join('&');
|
||
|
};
|
||
|
|
||
|
module.exports = querystring;
|