/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Gareth Johnson
*/
/**
* Defines {@link baja.ViewQuery}.
* @module baja/ord/ViewQuery
*/
define([ "bajaScript/sys",
"bajaScript/baja/ord/OrdQuery" ],
function (baja, OrdQuery) {
"use strict";
var subclass = baja.subclass,
callSuper = baja.callSuper,
strictArg = baja.strictArg;
function parseViewQuery(body) {
// Parse the view query (viewId?params)
var res,
view,
regex,
params;
if (body) {
res = /^([^?]*)(?:[?](.*))?$/.exec(body);
}
if (!res || (res && res.length < 2)) {
throw new Error("Invalid view query: " + body);
}
// Note down the view query information onto the ORD target so it can be accessed
view = {
id: res[1] || "",
params: {}
};
// If there are some view parameters then parse them
if (res[2]) {
regex = /([^=]+)=([^;]*);?/g;
params = regex.exec(res[2]);
while (params) {
view.params[decodeURIComponent(params[1])] = decodeURIComponent(params[2]);
params = regex.exec(res[2]);
}
}
return view;
}
/**
* `ViewQuery` defines user agent information.
*
* @class
* @alias baja.ViewQuery
* @extends OrdQuery
*
* @param {String|Object} body the view query body or an object literal for
* the view id and parameters.
* @param {String} [body.id] view id.
* @param {Object} [body.params] view parameters (key value pairs in an Object Literal).
*/
var ViewQuery = function ViewQuery(body) {
// If an Object is passed in then attempt to get id and params from object
if (body && typeof body === "object") {
var params = body.params || {},
i;
this.$view = {
id: body.id || "",
params: params
};
// Build up a new view query body String
i = 0;
body = this.$view.id;
baja.iterate(params, function (prop, propName) {
if (i === 0) {
body += "?";
} else if (i > 0) {
body += ";";
}
body += propName + "=" + prop;
++i;
});
} else {
this.$view = parseViewQuery(body);
}
callSuper(ViewQuery, this, [ {
scheme: baja.ViewScheme.DEFAULT,
schemeName: "view",
body: strictArg(body, String)
} ]);
};
subclass(ViewQuery, OrdQuery);
/**
* Normalize the query and return true if modified.
*
* @private
*
* @param {baja.OrdQueryList} list
* @param {Number} index
*
* @returns {Boolean}
*/
ViewQuery.prototype.normalize = function (list, index) {
var modified = false;
if (list.get(index + 1) &&
list.get(index + 1).getSchemeName().equals("view")) {
//NCCB-20196: merge adjacent ViewQueries
var first = list.get(index),
firstParams = first.getParameters(),
second = list.get(index + 1),
secondParams = second.getParameters(),
mergedViewId = second.getViewId() ? second.getViewId() : first.getViewId(), //use second if present
mergeParams = {};
Object.keys(firstParams).forEach(function (attr) {
mergeParams[attr] = firstParams[attr];
});
Object.keys(secondParams).forEach(function (attr) {
mergeParams[attr] = secondParams[attr];
});
list.set(index, new ViewQuery({
id: mergedViewId,
params: mergeParams
}));
// If the next scheme is the same as this one then
list.remove(index + 1);
modified = true;
} else if (index < list.size() - 1) {
// Ensure view query is always the last in the list
list.remove(index);
modified = true;
}
return modified;
};
/**
* Return the view id (this could be view type spec or the name of a Px view).
*
* @returns {String}
*/
ViewQuery.prototype.getViewId = function () {
return this.$view.id;
};
/**
* Return the view parameters as an object literal.
*
* Please note, this returns a defensive copy of the parameters.
*
* @returns {Object} the parameters.
*/
ViewQuery.prototype.getParameters = function () {
var o = {};
baja.iterate(this.$view.params, function (prop, propName) {
o[propName] = prop;
});
return o;
};
return ViewQuery;
});