/*global exports: false, require: false, console: false, Cc: false, Ci: false */
/*jslint onevar: false */
// Released under the MIT/X11 license
// http://www.opensource.org/licenses/mit-license.php
"use strict";
// ==============================================================
var Cc = require("chrome").Cc;
var Ci = require("chrome").Ci;
var urlMod = require("url");
/**
* Function for the management of the prototypal inheritace
* David Flanagan, Javascript: The Definitve Guide,
* IV. edition, O'Reilly, 2006, p. 168
*
* @param superobject
* @return new object, it needs new prototype.constructor
*
* <pre>
* function Father(x) {
* this.family = x;
* }
*
* function Son(x,w) {
* Father.call(this,x);
* this.wife = w;
* }
* Son.prototype = heir(Father);
* Son.prototype.constructor = Son;
* </pre>
*/
exports.heir = function heir(p) {
function F() {};
F.prototype = p.prototype;
return new F();
};
/**
* get parameters of URL as an object (name, value)
*/
var getParamsFromURL = exports.getParamsFromURL = function getParamsFromURL (url, base) {
if (!url || (url.toString().length === 0)) {
throw new Error("Missing URL value!");
}
if (!(url instanceof urlMod.URL)) {
url = new urlMod.URL(url.toString(), base);
}
var paramsArr = url.path.split("?");
if (paramsArr.length === 1) {
return {};
}
// get convert URL parameters to an Object
var params = {}, s = [];
paramsArr[1].split('&').forEach(function(par) {
s = par.split('=');
params[s[0]] = s[1];
});
return params;
};
/**
* parse XML object out of string working around various bugs in Gecko implementation
* see https://developer.mozilla.org/en/E4X for more information
*
* @param inStr String with unparsed XML string
* @return XML object
*/
exports.parseXMLfromString = function parseXMLfromString (inStuff) {
// if (typeof inStuff !== 'string') In future we should recognize this.response
// and get just .text property out of it. TODO
var respStr = inStuff.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, ""); // bug 336551
return new XML(respStr);
};
/**
* Get a bug no from URL ... fails with aliases
* It should theoretically belong to bzpage.js, but we don't have
* unit tests there yet, so keeping here.
*
* @param url String with URL to be analyzed
* @return String with the bug ID (hopefully number, but not for aliases)
*/
exports.getBugNo = function getBugNo(url) {
var params = getParamsFromURL(url);
if (params && params.id) {
return params.id;
}
};
/**
* format date to be in ISO format (just day part)
*
* @param date
* @return string with the formatted date
*/
exports.getISODate = function getISODate(dateStr) {
function pad(n) {
return n < 10 ? '0' + n : n;
}
var date = new Date(dateStr);
return date.getFullYear() + '-' + pad(date.getMonth() + 1) + '-' +
pad(date.getDate());
};
/**
* Check whether an item is member of the list. Idea is just to make long if
* commands slightly more readable.
*
* @param mbr string to be searched in the list
* @param list list
* @return position of the string in the list, or -1 if none found.
*/
var isInList = exports.isInList = function isInList(mbr, list) {
if (!list) {
return false;
}
return (list.indexOf(mbr) !== -1);
};
/**
* Make sure value returned is Array
*
* @param Array/String
* @return Array
*
* If something else than Array or String is passed to the function
* the result will be untouched actual argument of the call.
*/
var valToArray = exports.valToArray = function valToArray(val) {
var isArr = val &&
val.constructor &&
val.constructor.name === "Array";
return isArr ? val : [val];
};
/**
* Merges two comma separated string as a list and returns new string
*
* @param str String with old values
* @param value String/Array with other values
* @return String with merged lists
*/
exports.addCSVValue = function addCSVValue(str, value) {
var parts = (str.trim().length > 0 ? str.split(/[,\s]+/) : []);
if (!value) {
return str;
}
if (!isInList(value, parts)) {
var newValue = valToArray(value);
parts = parts.concat(newValue);
}
// this is necessary to get comma-space separated string even when
// value is an array already
parts = parts.join(",").split(",");
return parts.join(", ");
};
/**
* Treats comma separated string as a list and removes one item from it
*
* @param str String treated as a list
* @param value String with the value to be removed from str
* @return String with the resulting list comma separated
*/
exports.removeCSVValue = function removeCSVValue(str, value) {
str = str.trim();
var parts = str ? str.split(/[,\s]+/) : [];
var valueArr = value instanceof Array ? value : value.split(/[,\s]+/);
parts = parts.filter(function (e, i, a) {
return (!isInList(e, valueArr));
});
return parts.join(", ");
};
/**
* select element of the array where regexp in the first element matches second
* parameter of this function
*
* @param list Array with regexps and return values
* @param chosingMark String by which the element of array is to be matched
* @return Object chosen element
*/
var filterByRegexp = exports.filterByRegexp =
function filterByRegexp(list, chosingMark) {
var chosenPair = [];
if (list.length > 0) {
chosenPair = list.filter(function (pair) {
return new RegExp(pair.regexp, "i").test(chosingMark);
});
}
if (chosenPair.length > 0) {
return chosenPair[0].addr;
} else {
return "";
}
};
/**
* remove elements from the page based on their IDs
*
* @param doc Document object
* @param target String/Array with ID(s)
* @param remove Boolean indicating whether the node should be
* actually removed or just hidden.
* @return none
* TODO remove parameter could be replaced by function which would
* do actual activity.
*/
exports.killNodes = function killNodes(doc, target, remove) {
target = target.trim();
var targetArr = target instanceof Array ? target : target.split(/[,\s]+/);
targetArr.forEach(function(x) {
if (remove) {
var targetNode = doc.getElementById(x);
targetNode.parentNode.removeChild(targetNode);
} else {
x.style.display = "none";
}
});
};
exports.getObjectKeys = function getObjectKeys(obj) {
var keys = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
keys.push(key);
}
}
return keys;
};
exports.removeDuplicates = function removeDuplicates (arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) {
arr.splice (j, 1);
}
}
}
return arr;
};