526 lines
14 KiB
JavaScript
526 lines
14 KiB
JavaScript
/*
|
|
|
|
Copyright 2008-2015 Clipperz Srl
|
|
|
|
This file is part of Clipperz, the online password manager.
|
|
For further information about its features and functionalities please
|
|
refer to http://www.clipperz.com.
|
|
|
|
* Clipperz is free software: you can redistribute it and/or modify it
|
|
under the terms of the GNU Affero General Public License as published
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
* Clipperz is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the GNU Affero General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU Affero General Public
|
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
|
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
|
if (typeof(Clipperz.Base) == 'undefined') { Clipperz.Base = {}; }
|
|
|
|
Clipperz.Base.VERSION = "0.2";
|
|
Clipperz.Base.NAME = "Clipperz.Base";
|
|
|
|
MochiKit.Base.update(Clipperz.Base, {
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'__repr__': function () {
|
|
return "[" + this.NAME + " " + this.VERSION + "]";
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'toString': function () {
|
|
return this.__repr__();
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'itemgetter': function (aKeyPath) {
|
|
// return MochiKit.Base.compose.apply(null, [MochiKit.Base.itemgetter('key3')]);
|
|
return MochiKit.Base.compose.apply(null,
|
|
MochiKit.Base.map(
|
|
MochiKit.Base.itemgetter,
|
|
MochiKit.Iter.reversed(
|
|
aKeyPath.split('.')
|
|
)
|
|
)
|
|
);
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'isUrl': function (aValue) {
|
|
return (MochiKit.Base.urlRegExp.test(aValue));
|
|
},
|
|
|
|
'isEmail': function (aValue) {
|
|
return (MochiKit.Base.emailRegExp.test(aValue));
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'caseInsensitiveCompare': function (a, b) {
|
|
return MochiKit.Base.compare(a.toLowerCase(), b.toLowerCase());
|
|
},
|
|
|
|
'reverseComparator': function (aComparator) {
|
|
return MochiKit.Base.compose(function(aResult) { return -aResult; }, aComparator);
|
|
},
|
|
|
|
'caseInsensitiveKeyComparator': function (aKey) {
|
|
return function (a, b) {
|
|
return MochiKit.Base.compare(a[aKey].toLowerCase(), b[aKey].toLowerCase());
|
|
}
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
/*
|
|
'dependsOn': function(module, deps) {
|
|
if (!(module in Clipperz)) {
|
|
MochiKit[module] = {};
|
|
}
|
|
|
|
if (typeof(dojo) != 'undefined') {
|
|
dojo.provide('Clipperz.' + module);
|
|
}
|
|
for (var i = 0; i < deps.length; i++) {
|
|
if (typeof(dojo) != 'undefined') {
|
|
dojo.require('Clipperz.' + deps[i]);
|
|
}
|
|
if (typeof(JSAN) != 'undefined') {
|
|
JSAN.use('Clipperz.' + deps[i], []);
|
|
}
|
|
if (!(deps[i] in Clipperz)) {
|
|
throw 'Clipperz.' + module + ' depends on Clipperz.' + deps[i] + '!'
|
|
}
|
|
}
|
|
},
|
|
*/
|
|
//-------------------------------------------------------------------------
|
|
|
|
'trim': function (aValue) {
|
|
return aValue.replace(/^\s+|\s+$/g, "");
|
|
},
|
|
|
|
'zipWithRange': function (anArray) {
|
|
return MochiKit.Base.zip(MochiKit.Iter.range(anArray.length), anArray);
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'stringToByteArray': function (aValue) {
|
|
var result;
|
|
var i, c;
|
|
|
|
result = [];
|
|
|
|
c = aValue.length;
|
|
for (i=0; i<c; i++) {
|
|
result[i] = aValue.charCodeAt(i);
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
//.........................................................................
|
|
|
|
'byteArrayToString': function (anArrayOfBytes) {
|
|
var result;
|
|
var i, c;
|
|
|
|
result = "";
|
|
|
|
c = anArrayOfBytes.length;
|
|
for (i=0; i<c; i++) {
|
|
result += String.fromCharCode(anArrayOfBytes[i]);
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'getValueForKeyInFormContent': function (aFormContent, aKey) {
|
|
return aFormContent[1][MochiKit.Base.find(aFormContent[0], aKey)];
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'indexOfObjectInArray': function(anObject, anArray) {
|
|
var result;
|
|
var i, c;
|
|
|
|
result = -1;
|
|
|
|
c = anArray.length;
|
|
for (i=0; ((i<c) && (result < 0)); i++) {
|
|
if (anArray[i] === anObject) {
|
|
result = i;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'removeObjectAtIndexFromArray': function(anIndex, anArray) {
|
|
anArray.splice(anIndex, 1);
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'removeObjectFromArray': function(anObject, anArray) {
|
|
var objectIndex;
|
|
|
|
objectIndex = Clipperz.Base.indexOfObjectInArray(anObject, anArray);
|
|
if (objectIndex > -1) {
|
|
Clipperz.Base.removeObjectAtIndexFromArray(objectIndex, anArray);
|
|
} else {
|
|
Clipperz.log("Trying to remove an object not present in the array");
|
|
throw Clipperz.Base.exception.ObjectNotFound;
|
|
}
|
|
},
|
|
|
|
'removeFromArray': function(anArray, anObject) {
|
|
return Clipperz.Base.removeObjectFromArray(anObject, anArray);
|
|
},
|
|
|
|
'arrayWithUniqueValues': function (anArray) {
|
|
return anArray.filter(function (value, index, self) { return self.indexOf(value) === index; });
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'splitStringAtFixedTokenSize': function(aString, aTokenSize) {
|
|
var result;
|
|
var stringToProcess;
|
|
|
|
stringToProcess = aString;
|
|
result = [];
|
|
if (stringToProcess != null) {
|
|
while (stringToProcess.length > aTokenSize) {
|
|
result.push(stringToProcess.substring(0, aTokenSize));
|
|
stringToProcess = stringToProcess.substring(aTokenSize);
|
|
}
|
|
|
|
result.push(stringToProcess);
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'objectType': function(anObject) {
|
|
var result;
|
|
|
|
if (anObject == null) {
|
|
result = null;
|
|
} else {
|
|
result = typeof(anObject);
|
|
|
|
if (result == "object") {
|
|
if (anObject instanceof Array) {
|
|
result = 'array'
|
|
} else if (anObject.constructor == Boolean) {
|
|
result = 'boolean'
|
|
} else if (anObject instanceof Date) {
|
|
result = 'date'
|
|
} else if (anObject instanceof Error) {
|
|
result = 'error'
|
|
} else if (anObject instanceof Function) {
|
|
result = 'function'
|
|
} else if (anObject.constructor == Number) {
|
|
result = 'number'
|
|
} else if (anObject.constructor == String) {
|
|
result = 'string'
|
|
} else if (anObject instanceof Object) {
|
|
result = 'object'
|
|
} else {
|
|
throw Clipperz.Base.exception.UnknownType;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'escapeHTML': function(aValue) {
|
|
var result;
|
|
|
|
result = aValue;
|
|
result = result.replace(/</g, "<");
|
|
result = result.replace(/>/g, ">");
|
|
|
|
return result;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'deepClone': function(anObject) {
|
|
var result;
|
|
|
|
result = Clipperz.Base.evalJSON(Clipperz.Base.serializeJSON(anObject));
|
|
|
|
return result;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
// 'deepCompare': function (aObject, bObject) {
|
|
// return (Clipperz.Base.serializeJSON(aObject) == Clipperz.Base.serializeJSON(bObject));
|
|
// },
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'evalJSON': function(aString) {
|
|
return JSON.parse(aString);
|
|
},
|
|
|
|
'serializeJSON': function(anObject) {
|
|
return JSON.stringify(anObject);
|
|
},
|
|
|
|
'formatJSON': function (anObject, sIndent) {
|
|
var realTypeOf = function (v) {
|
|
if (typeof(v) == "object") {
|
|
if (v === null) return "null";
|
|
if (v.constructor == (new Array).constructor) return "array";
|
|
if (v.constructor == (new Date).constructor) return "date";
|
|
if (v.constructor == (new RegExp).constructor) return "regex";
|
|
return "object";
|
|
}
|
|
return typeof(v);
|
|
};
|
|
|
|
// function FormatJSON(oData, sIndent) {
|
|
if (arguments.length < 2) {
|
|
var sIndent = "";
|
|
}
|
|
// var sIndentStyle = " ";
|
|
var sIndentStyle = " ";
|
|
var sDataType = realTypeOf(anObject);
|
|
|
|
// open object
|
|
if (sDataType == "array") {
|
|
if (anObject.length == 0) {
|
|
return "[]";
|
|
}
|
|
var sHTML = "[";
|
|
} else if (sDataType == "object") {
|
|
var sHTML = "{";
|
|
} else {
|
|
return "{}";
|
|
}
|
|
// } else {
|
|
// var iCount = 0;
|
|
// $.each(anObject, function() {
|
|
// iCount++;
|
|
// return;
|
|
// });
|
|
// if (iCount == 0) { // object is empty
|
|
// return "{}";
|
|
// }
|
|
// var sHTML = "{";
|
|
// }
|
|
|
|
// loop through items
|
|
var iCount = 0;
|
|
// $.each(anObject, function(sKey, vValue) {
|
|
MochiKit.Iter.forEach(MochiKit.Base.keys(anObject), function(sKey) {
|
|
var vValue = anObject[sKey];
|
|
|
|
if (iCount > 0) {
|
|
sHTML += ",";
|
|
}
|
|
if (sDataType == "array") {
|
|
sHTML += ("\n" + sIndent + sIndentStyle);
|
|
} else {
|
|
sHTML += ("\n" + sIndent + sIndentStyle + "\"" + sKey + "\"" + ": ");
|
|
}
|
|
|
|
// display relevant data type
|
|
switch (realTypeOf(vValue)) {
|
|
case "array":
|
|
case "object":
|
|
sHTML += Clipperz.Base.formatJSON(vValue, (sIndent + sIndentStyle));
|
|
break;
|
|
case "boolean":
|
|
case "number":
|
|
sHTML += vValue.toString();
|
|
break;
|
|
case "null":
|
|
sHTML += "null";
|
|
break;
|
|
case "string":
|
|
sHTML += ("\"" + vValue + "\"");
|
|
break;
|
|
default:
|
|
sHTML += ("TYPEOF: " + typeof(vValue));
|
|
}
|
|
|
|
// loop
|
|
iCount++;
|
|
});
|
|
|
|
// close object
|
|
if (sDataType == "array") {
|
|
sHTML += ("\n" + sIndent + "]");
|
|
} else {
|
|
sHTML += ("\n" + sIndent + "}");
|
|
}
|
|
|
|
// return
|
|
return sHTML;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'mergeItems': function (anArrayOfValues) {
|
|
var result;
|
|
var i, c;
|
|
|
|
result = {};
|
|
|
|
c = anArrayOfValues.length;
|
|
for (i=0; i<c; i++) {
|
|
result[anArrayOfValues[i][0]] = anArrayOfValues[i][1];
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'map': function (fn, lstObj/*, lst... */) {
|
|
var result;
|
|
|
|
if (MochiKit.Base.isArrayLike(lstObj)) {
|
|
result = MochiKit.Base.map.apply(this, arguments);
|
|
} else {
|
|
var keys;
|
|
var values;
|
|
var computedValues;
|
|
|
|
keys = MochiKit.Base.keys(lstObj);
|
|
values = MochiKit.Base.values(lstObj);
|
|
computedValues = MochiKit.Base.map(fn, values);
|
|
|
|
result = Clipperz.Base.mergeItems(MochiKit.Base.zip(keys, computedValues));
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'sanitizeString': function(aValue) {
|
|
var result;
|
|
|
|
if (Clipperz.Base.objectType(aValue) == 'string') {
|
|
result = aValue;
|
|
result = result.replace(/</img,"<");
|
|
result = result.replace(/>/img,">");
|
|
} else {
|
|
result = aValue;
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'module': function(aValue) {
|
|
// aValue = 'Clipperz.PM.Compact'
|
|
//
|
|
// if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
|
|
// if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
|
|
// if (typeof(Clipperz.PM.UI.Common.Components) == 'undefined') { Clipperz.PM.UI.Common.Components = {}; }
|
|
|
|
var currentScope;
|
|
var pathElements;
|
|
var i,c;
|
|
|
|
currentScope = window;
|
|
pathElements = aValue.split('.');
|
|
c = pathElements.length;
|
|
for (i=0; i<c; i++) {
|
|
if (typeof(currentScope[pathElements[i]]) == 'undefined') {
|
|
currentScope[pathElements[i]] = {};
|
|
}
|
|
|
|
currentScope = currentScope[pathElements[i]];
|
|
}
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'exception': {
|
|
'AbstractMethod': new MochiKit.Base.NamedError("Clipperz.Base.exception.AbstractMethod"),
|
|
'UnknownType': new MochiKit.Base.NamedError("Clipperz.Base.exception.UnknownType"),
|
|
'VulnerabilityIssue': new MochiKit.Base.NamedError("Clipperz.Base.exception.VulnerabilityIssue"),
|
|
'MandatoryParameter': new MochiKit.Base.NamedError("Clipperz.Base.exception.MandatoryParameter"),
|
|
'ObjectNotFound': new MochiKit.Base.NamedError("Clipperz.Base.exception.ObjectNotFound"),
|
|
'raise': function (aName) {
|
|
throw Clipperz.Base.exception[aName];
|
|
}
|
|
},
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
'extend': YAHOO.extendX,
|
|
|
|
//-------------------------------------------------------------------------
|
|
__syntaxFix__: "syntax fix"
|
|
|
|
});
|
|
|
|
// Original regExp courtesy of John Gruber: http://daringfireball.net/2009/11/liberal_regex_for_matching_urls
|
|
// Updated to match Clipperz usage pattern.
|
|
//MochiKit.Base.urlRegExp = new RegExp(/\b(([\w-]+:\/\/?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/)))/);
|
|
MochiKit.Base.urlRegExp = new RegExp(/^((([\w-]+:\/\/?)|(www\.))[^\s()<>]+((?:\([\w\d]+\)|([^[:punct:]\s]|\/)))?)/);
|
|
|
|
// RegExp found here: http://www.tipsntracks.com/117/validate-an-email-address-using-regular-expressions.html
|
|
MochiKit.Base.emailRegExp = new RegExp(/^([a-zA-Z0-9_\-\.]+)@(([a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))|(([01]?\d\d?|2[0-4]\d|25[0-5])\.){3}([01]?\d\d?|25[0-5]|2[0-4]\d))$/);
|
|
|
|
|
|
MochiKit.Base.registerComparator('Object dummy comparator',
|
|
function(a, b) {
|
|
return ((a.constructor == Object) && (b.constructor == Object));
|
|
},
|
|
function(a, b) {
|
|
var result;
|
|
var aKeys;
|
|
var bKeys;
|
|
|
|
aKeys = MochiKit.Base.keys(a).sort();
|
|
bKeys = MochiKit.Base.keys(b).sort();
|
|
result = MochiKit.Base.compare(aKeys, bKeys);
|
|
|
|
if (result == 0) {
|
|
var i, c;
|
|
|
|
c = aKeys.length;
|
|
for (i=0; (i<c) && (result == 0); i++) {
|
|
result = MochiKit.Base.compare(a[aKeys[i]], b[bKeys[i]]);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
},
|
|
true
|
|
);
|