Improve JavaScript coding style

To comitted code now passes the Airbnb pattern using jscs
pull/91/head
Francis Lachapelle 2014-09-24 16:06:12 -04:00
parent df37fd8b92
commit 342441ecf8
7 changed files with 844 additions and 831 deletions

View File

@ -1,169 +1,173 @@
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* JavaScript for SOGoContacts */
(function() {
'use strict';
'use strict';
angular.module('SOGo.Authentication', [])
angular.module('SOGo.Authentication', [])
.constant('passwordPolicyConfig', {
'PolicyPasswordChangeUnsupported': -3,
'PolicyPasswordSystemUnknown': -2,
'PolicyPasswordUnknown': -1,
'PolicyPasswordExpired': 0,
'PolicyAccountLocked': 1,
'PolicyChangeAfterReset': 2,
'PolicyPasswordModNotAllowed': 3,
'PolicyMustSupplyOldPassword': 4,
'PolicyInsufficientPasswordQuality': 5,
'PolicyPasswordTooShort': 6,
'PolicyPasswordTooYoung': 7,
'PolicyPasswordInHistory': 8,
'PolicyNoError': 65535
PolicyPasswordChangeUnsupported: -3,
PolicyPasswordSystemUnknown: -2,
PolicyPasswordUnknown: -1,
PolicyPasswordExpired: 0,
PolicyAccountLocked: 1,
PolicyChangeAfterReset: 2,
PolicyPasswordModNotAllowed: 3,
PolicyMustSupplyOldPassword: 4,
PolicyInsufficientPasswordQuality: 5,
PolicyPasswordTooShort: 6,
PolicyPasswordTooYoung: 7,
PolicyPasswordInHistory: 8,
PolicyNoError: 65535
})
// TODO: convert to a Factory recipe?
// TODO: convert to a Factory recipe?
.provider('Authentication', function(passwordPolicyConfig) {
this.readCookie = function(name) {
var foundCookie = null;
var prefix = name + "=";
var pairs = document.cookie.split(';');
for (var i = 0; !foundCookie && i < pairs.length; i++) {
var currentPair = pairs[i];
var start = 0;
while (currentPair.charAt(start) == " ")
start++;
if (start > 0)
currentPair = currentPair.substr(start);
if (currentPair.indexOf(prefix) == 0)
foundCookie = currentPair.substr(prefix.length);
this.readCookie = function(name) {
var foundCookie, prefix, pairs, i, currentPair, start;
foundCookie = null;
prefix = name + '=';
pairs = document.cookie.split(';');
for (i = 0; !foundCookie && i < pairs.length; i++) {
currentPair = pairs[i];
start = 0;
while (currentPair.charAt(start) == ' ')
start++;
if (start > 0)
currentPair = currentPair.substr(start);
if (currentPair.indexOf(prefix) == 0)
foundCookie = currentPair.substr(prefix.length);
}
return foundCookie;
};
this.readLoginCookie = function() {
var loginValues = null,
cookie = this.readCookie('0xHIGHFLYxSOGo'),
value;
if (cookie && cookie.length > 8) {
value = decodeURIComponent(cookie.substr(8));
loginValues = value.base64decode().split(':');
}
return loginValues;
};
this.redirectUrl = function(username, domain) {
var userName, address, baseAddress, altBaseAddress, parts, hostpart, protocol, newAddress;
userName = username;
if (domain)
userName += '@' + domain.value;
address = '' + window.location.href;
baseAddress = ApplicationBaseURL + '/' + encodeURIComponent(userName);
if (baseAddress[0] == '/') {
parts = address.split('/');
hostpart = parts[2];
protocol = parts[0];
baseAddress = protocol + '//' + hostpart + baseAddress;
}
parts = baseAddress.split('/');
parts.splice(0, 3);
altBaseAddress = parts.join('/');
newAddress;
if ((address.startsWith(baseAddress)
|| address.startsWith(altBaseAddress))
&& !address.endsWith('/logoff')) {
newAddress = address;
} else {
newAddress = baseAddress;
}
if (/theme=mobile/.test(window.location.search)) {
newAddress = baseAddress + '/Contacts' + '?theme=mobile';
}
else {
newAddress = baseAddress + '/Contacts';
}
return newAddress;
};
this.$get = ['$q', '$http', function($q, $http) {
var _this = this, service;
service = {
// login: function(username, password, domain, language, rememberLogin) {
// var d = $q.defer();
login: function(data) {
var d = $q.defer(),
username = data.username,
password = data.password,
domain = data.domain,
language,
rememberLogin = data.rememberLogin ? 1 : 0;
if (data.loginSuffix && !username.endsWith(data.loginSuffix)) {
username += loginSuffix;
domain = false;
}
return foundCookie;
};
this.readLoginCookie = function() {
var loginValues = null;
var cookie = this.readCookie("0xHIGHFLYxSOGo");
if (cookie && cookie.length > 8) {
var value = decodeURIComponent(cookie.substr(8));
loginValues = value.base64decode().split(":");
}
return loginValues;
};
this.redirectUrl = function(username, domain) {
var userName = username;
if (domain)
userName += '@' + domain.value;
var address = "" + window.location.href;
var baseAddress = ApplicationBaseURL + "/" + encodeURIComponent(userName);
var altBaseAddress;
if (baseAddress[0] == "/") {
var parts = address.split("/");
var hostpart = parts[2];
var protocol = parts[0];
baseAddress = protocol + "//" + hostpart + baseAddress;
}
var altBaseAddress;
var parts = baseAddress.split("/");
parts.splice(0, 3);
altBaseAddress = parts.join("/");
var newAddress;
if ((address.startsWith(baseAddress)
|| address.startsWith(altBaseAddress))
&& !address.endsWith("/logoff")) {
newAddress = address;
} else {
newAddress = baseAddress;
if (data.language && data.language != 'WONoSelectionString') {
language = data.language;
}
if (/theme=mobile/.test(window.location.search)) {
newAddress = baseAddress + '/Contacts' + '?theme=mobile';
}
else {
newAddress = baseAddress + '/Contacts';
}
return newAddress;
};
this.$get = ['$q', '$http', function($q, $http) {
var self = this;
var service = {
// login: function(username, password, domain, language, rememberLogin) {
// var d = $q.defer();
login: function(data) {
var d = $q.defer(),
username = data.username,
password = data.password,
domain = data.domain,
language,
rememberLogin = data.rememberLogin ? 1 : 0;
if (data.loginSuffix && !username.endsWith(data.loginSuffix)) {
username += loginSuffix;
domain = false;
}
if (data.language && data.language != 'WONoSelectionString') {
language = data.language;
}
$http({
method: 'POST',
url: '/SOGo/connect',
data: {'userName': username,
'password': password,
'domain': domain,
'language': language,
'rememberLogin': rememberLogin}
}).success(function(data, status) {
// Make sure browser's cookies are enabled
var loginCookie = self.readLoginCookie();
if (!loginCookie) {
d.reject(l("cookiesNotEnabled"));
}
else {
// Check password policy
if (typeof(data['expire']) != 'undefined' && typeof(data['grace']) != 'undefined') {
if (data['expire'] < 0 && data['grace'] > 0) {
d.reject({'grace': data['grace']});
//showPasswordDialog('grace', createPasswordGraceDialog, data['grace']);
} else if (data['expire'] > 0 && data['grace'] == -1) {
d.reject({'expire': data['expire']});
//showPasswordDialog('expiration', createPasswordExpirationDialog, data['expire']);
}
else {
d.resolve(self.redirectUrl(username, domain));
}
}
else {
d.resolve(self.redirectUrl(username, domain));
}
}
}).error(function(data, status) {
var msg;
if (data && data['LDAPPasswordPolicyError']) {
var perr = data['LDAPPasswordPolicyError'];
if (perr == passwordPolicyConfig.PolicyNoError) {
msg = l("Wrong username or password.");
}
else {
msg = l("Login failed due to unhandled error case: " + perr);
}
}
else {
msg = l("Unhandled error response");
}
d.reject({error: msg});
});
return d.promise;
$http({
method: 'POST',
url: '/SOGo/connect',
data: {
userName: username,
password: password,
domain: domain,
language: language,
rememberLogin: rememberLogin
}
}).success(function(data, status) {
// Make sure browser's cookies are enabled
var loginCookie = _this.readLoginCookie();
if (!loginCookie) {
d.reject(l('cookiesNotEnabled'));
}
else {
// Check password policy
if (typeof data.expire != 'undefined' && typeof data.grace != 'undefined') {
if (data.expire < 0 && data.grace > 0) {
d.reject({grace: data.grace});
//showPasswordDialog('grace', createPasswordGraceDialog, data['grace']);
} else if (data.expire > 0 && data.grace == -1) {
d.reject({expire: data.expire});
//showPasswordDialog('expiration', createPasswordExpirationDialog, data['expire']);
}
else {
d.resolve(_this.redirectUrl(username, domain));
}
}
};
return service;
}];
else {
d.resolve(_this.redirectUrl(username, domain));
}
}
}).error(function(data, status) {
var msg, perr;
if (data && data.LDAPPasswordPolicyError) {
perr = data.LDAPPasswordPolicyError;
if (perr == passwordPolicyConfig.PolicyNoError) {
msg = l('Wrong username or password.');
}
else {
msg = l('Login failed due to unhandled error case: ' + perr);
}
}
else {
msg = l('Unhandled error response');
}
d.reject({error: msg});
});
return d.promise;
}
};
return service;
}];
});
})();

View File

@ -1,109 +1,111 @@
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
(function() {
'use strict';
'use strict';
/* Constructor */
function Resource($http, $q, path, options) {
angular.extend(this, {
_http: $http,
_q: $q,
_path: path
});
angular.extend(this, options);
}
/* Constructor */
function Resource($http, $q, path, options) {
angular.extend(this, {
_http: $http,
_q: $q,
_path: path
});
angular.extend(this, options);
}
/* The factory we'll use to register with Angular */
Resource.$factory = ['$http', '$q', function($http, $q) {
return function(path, options) {
return new Resource($http, $q, path, options);
};
}];
/* Factory registration in Angular module */
angular.module('SOGo.Common').factory('sgResource', Resource.$factory);
/* Instance methods */
Resource.prototype.path = function(uid) {
return (uid ? this._path + '/' + uid : this._path) + '/view';
/* The factory we'll use to register with Angular */
Resource.$factory = ['$http', '$q', function($http, $q) {
return function(path, options) {
return new Resource($http, $q, path, options);
};
}];
Resource.prototype.find = function(uid) {
var deferred = this._q.defer();
/* Factory registration in Angular module */
angular.module('SOGo.Common').factory('sgResource', Resource.$factory);
this._http
.get(this.path(uid))
.success(deferred.resolve)
.error(deferred.reject);
/* Instance methods */
return deferred.promise;
};
Resource.prototype.path = function(uid) {
return (uid ? this._path + '/' + uid : this._path) + '/view';
};
Resource.prototype.filter = function(uid, params) {
var deferred = this._q.defer();
Resource.prototype.find = function(uid) {
var deferred = this._q.defer();
this._http({
method: 'GET',
url: this.path(uid),
params: params
})
.success(deferred.resolve)
.error(deferred.reject);
this._http
.get(this.path(uid))
.success(deferred.resolve)
.error(deferred.reject);
return deferred.promise;
};
return deferred.promise;
};
Resource.prototype.newguid = function(uid) {
var deferred = this._q.defer();
var path = this._path + '/' + uid + '/newguid';
Resource.prototype.filter = function(uid, params) {
var deferred = this._q.defer();
this._http
.get(path)
.success(deferred.resolve)
.error(deferred.reject);
this._http({
method: 'GET',
url: this.path(uid),
params: params
})
.success(deferred.resolve)
.error(deferred.reject);
return deferred.promise;
};
return deferred.promise;
};
/**
* @function create
* @desc Create a new resource using a specific action
* @param {string} action - the action to be used in the URL
* @param {string} name - the new resource's name
*/
Resource.prototype.create = function(action, name) {
var deferred = this._q.defer();
var path = this._path + '/' + action;
Resource.prototype.newguid = function(uid) {
var deferred = this._q.defer(),
path = this._path + '/' + uid + '/newguid';
this._http
.post(path, { 'name': name })
.success(deferred.resolve)
.error(deferred.reject);
this._http
.get(path)
.success(deferred.resolve)
.error(deferred.reject);
return deferred.promise;
};
return deferred.promise;
};
Resource.prototype.save = function(uid, newValue, options) {
var deferred = this._q.defer();
var action = (options && options.action)? options.action : 'save';
var path = this._path + '/' + uid + '/' + action;
/**
* @function create
* @desc Create a new resource using a specific action
* @param {string} action - the action to be used in the URL
* @param {string} name - the new resource's name
*/
Resource.prototype.create = function(action, name) {
var deferred = this._q.defer(),
path = this._path + '/' + action;
this._http
.post(path, newValue)
.success(deferred.resolve)
.error(deferred.reject);
this._http
.post(path, { name: name })
.success(deferred.resolve)
.error(deferred.reject);
return deferred.promise;
};
return deferred.promise;
};
Resource.prototype.remove = function(uid) {
var deferred = this._q.defer();
var path = this._path + '/' + uid + '/delete';
Resource.prototype.save = function(uid, newValue, options) {
var deferred = this._q.defer(),
action = (options && options.action)? options.action : 'save',
path = this._path + '/' + uid + '/' + action;
this._http
.get(path)
.success(deferred.resolve)
.error(deferred.reject);
this._http
.post(path, newValue)
.success(deferred.resolve)
.error(deferred.reject);
return deferred.promise;
};
return deferred.promise;
};
Resource.prototype.remove = function(uid) {
var deferred = this._q.defer(),
path = this._path + '/' + uid + '/delete';
this._http
.get(path)
.success(deferred.resolve)
.error(deferred.reject);
return deferred.promise;
};
})();

View File

@ -1,116 +1,116 @@
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* JavaScript for common UI services */
(function() {
'use strict';
'use strict';
/**
* @name Dialog
* @constructor
*/
function Dialog() {
}
/**
* @name Dialog
* @constructor
*/
function Dialog() {
}
/**
* @name alert
* @desc Show an alert dialog box with a single "OK" button
* @param {string} title
* @param {string} content
*/
Dialog.alert = function(title, content) {
var modal = this.$modal.open({
template:
'<h2 data-ng-bind-html="title"></h2>' +
'<p data-ng-bind-html="content"></p>' +
'<a class="button button-primary" ng-click="closeModal()">' + l('OK') + '</a>' +
'<span class="close-reveal-modal" ng-click="closeModal()"><i class="icon-close"></i></span>',
windowClass: 'small',
controller: function($scope, $modalInstance) {
$scope.title = title;
$scope.content = content;
$scope.closeModal = function() {
$modalInstance.close();
};
}
});
};
/**
* @name alert
* @desc Show an alert dialog box with a single "OK" button
* @param {string} title
* @param {string} content
*/
Dialog.alert = function(title, content) {
var modal = this.$modal.open({
template:
'<h2 data-ng-bind-html="title"></h2>' +
'<p data-ng-bind-html="content"></p>' +
'<a class="button button-primary" ng-click="closeModal()">' + l('OK') + '</a>' +
'<span class="close-reveal-modal" ng-click="closeModal()"><i class="icon-close"></i></span>',
windowClass: 'small',
controller: function($scope, $modalInstance) {
$scope.title = title;
$scope.content = content;
$scope.closeModal = function() {
$modalInstance.close();
};
}
});
};
/**
* @name confirm
* @desc Show a confirmation dialog box with buttons "Cancel" and "OK"
* @param {string} title
* @param {string} content
* @returns a promise that always resolves, but returns true only if the user user has clicked on the
* 'OK' button
*/
Dialog.confirm = function(title, content) {
var d = this.$q.defer();
var modal = this.$modal.open({
template:
'<h2 data-ng-bind-html="title"></h2>' +
'<p data-ng-bind-html="content"></p>' +
'<a class="button button-primary" ng-click="confirm()">' + l('OK') + '</a>' +
'<a class="button button-secondary" ng-click="closeModal()">' + l('Cancel') + '</a>' +
'<span class="close-reveal-modal" ng-click="closeModal()"><i class="icon-close"></i></span>',
windowClass: 'small',
controller: function($scope, $modalInstance) {
$scope.title = title;
$scope.content = content;
$scope.closeModal = function() {
$modalInstance.close();
d.resolve(false);
};
$scope.confirm = function() {
$modalInstance.close();
d.resolve(true);
};
}
});
return d.promise;
};
/**
* @name confirm
* @desc Show a confirmation dialog box with buttons "Cancel" and "OK"
* @param {string} title
* @param {string} content
* @returns a promise that always resolves, but returns true only if the user user has clicked on the
* 'OK' button
*/
Dialog.confirm = function(title, content) {
var d = this.$q.defer();
this.$modal.open({
template:
'<h2 data-ng-bind-html="title"></h2>' +
'<p data-ng-bind-html="content"></p>' +
'<a class="button button-primary" ng-click="confirm()">' + l('OK') + '</a>' +
'<a class="button button-secondary" ng-click="closeModal()">' + l('Cancel') + '</a>' +
'<span class="close-reveal-modal" ng-click="closeModal()"><i class="icon-close"></i></span>',
windowClass: 'small',
controller: function($scope, $modalInstance) {
$scope.title = title;
$scope.content = content;
$scope.closeModal = function() {
$modalInstance.close();
d.resolve(false);
};
$scope.confirm = function() {
$modalInstance.close();
d.resolve(true);
};
}
});
return d.promise;
};
Dialog.prompt = function(title, inputPlaceholder, options) {
var o = options || {};
var d = this.$q.defer();
var modal = this.$modal.open({
template:
'<h2 ng-bind-html="title"></h2>' +
'<form><input type="' + (o.inputType || 'text')
+ '" placeholder="' + (inputPlaceholder || '') + '" ng-model="inputValue" /></form>' +
'<a class="button button-primary" ng-click="confirm(inputValue)">' + l('OK') + '</a>' +
'<a class="button button-secondary" ng-click="closeModal()">' + l('Cancel') + '</a>' +
'<span class="close-reveal-modal" ng-click="closeModal()"><i class="icon-close"></i></span>',
windowClass: 'small',
Dialog.prompt = function(title, inputPlaceholder, options) {
var o = options || {},
d = this.$q.defer();
this.$modal.open({
template:
'<h2 ng-bind-html="title"></h2>' +
'<form><input type="' + (o.inputType || 'text')
+ '" placeholder="' + (inputPlaceholder || '') + '" ng-model="inputValue" /></form>' +
'<a class="button button-primary" ng-click="confirm(inputValue)">' + l('OK') + '</a>' +
'<a class="button button-secondary" ng-click="closeModal()">' + l('Cancel') + '</a>' +
'<span class="close-reveal-modal" ng-click="closeModal()"><i class="icon-close"></i></span>',
windowClass: 'small',
controller: function($scope, $modalInstance) {
$scope.title = title;
$scope.inputValue = o.inputValue || '';
$scope.closeModal = function() {
$modalInstance.close();
d.resolve(false);
};
$scope.confirm = function(value) {
$modalInstance.close();
d.resolve(value);
};
}
});
return d.promise;
};
controller: function($scope, $modalInstance) {
$scope.title = title;
$scope.inputValue = o.inputValue || '';
$scope.closeModal = function() {
$modalInstance.close();
d.resolve(false);
};
$scope.confirm = function(value) {
$modalInstance.close();
d.resolve(value);
};
}
});
return d.promise;
};
/**
* @memberof Dialog
* @desc The factory we'll register as sgDialog in the Angular module SOGo.UIDesktop
*/
Dialog.$factory = ['$modal', '$q', function($modal, $q) {
angular.extend(Dialog, { $modal: $modal, $q: $q });
/**
* @memberof Dialog
* @desc The factory we'll register as sgDialog in the Angular module SOGo.UIDesktop
*/
Dialog.$factory = ['$modal', '$q', function($modal, $q) {
angular.extend(Dialog, { $modal: $modal, $q: $q });
return Dialog; // return constructor
}];
return Dialog; // return constructor
}];
/* Angular module instanciation */
angular.module('SOGo.UIDesktop', ['mm.foundation'])
/* Angular module instanciation */
angular.module('SOGo.UIDesktop', ['mm.foundation'])
/* Factory registration in Angular module */
/* Factory registration in Angular module */
.factory('sgDialog', Dialog.$factory);
})();

View File

@ -1,53 +1,53 @@
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* JavaScript for common UI services for mobile theme */
(function() {
'use strict';
'use strict';
/**
* @name Dialog
* @constructor
*/
function Dialog() {
}
/**
* @name Dialog
* @constructor
*/
function Dialog() {
}
Dialog.alert = function(title, content) {
var alertPopup = this.$ionicPopup.alert({
title: title,
template: content
});
return alertPopup;
};
Dialog.alert = function(title, content) {
var alertPopup = this.$ionicPopup.alert({
title: title,
template: content
});
return alertPopup;
};
Dialog.confirm = function(title, content) {
var confirmPopup = this.$ionicPopup.confirm({
title: title,
template: content
});
return confirmPopup;
};
Dialog.confirm = function(title, content) {
var confirmPopup = this.$ionicPopup.confirm({
title: title,
template: content
});
return confirmPopup;
};
Dialog.prompt = function(title, content) {
var promptPopup = this.$ionicPopup.prompt({
title: title,
inputPlaceholder: content
});
return promptPopup;
};
Dialog.prompt = function(title, content) {
var promptPopup = this.$ionicPopup.prompt({
title: title,
inputPlaceholder: content
});
return promptPopup;
};
/**
* @memberof Dialog
* @desc The factory we'll register as sgDialog in the Angular module SOGo.UIMobile
*/
Dialog.$factory = ['$ionicPopup', function($ionicPopup) {
angular.extend(Dialog, { $ionicPopup: $ionicPopup });
/**
* @memberof Dialog
* @desc The factory we'll register as sgDialog in the Angular module SOGo.UIMobile
*/
Dialog.$factory = ['$ionicPopup', function($ionicPopup) {
angular.extend(Dialog, { $ionicPopup: $ionicPopup });
return Dialog; // return constructor
}];
return Dialog; // return constructor
}];
/* Angular module instanciation */
angular.module('SOGo.UIMobile', ['ionic'])
/* Angular module instanciation */
angular.module('SOGo.UIMobile', ['ionic'])
/* Factory registration in Angular module */
/* Factory registration in Angular module */
.factory('sgDialog', Dialog.$factory);
})();

View File

@ -1,88 +1,88 @@
//$(document).foundation();
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
String.prototype.startsWith = function(pattern, position) {
position = angular.isNumber(position) ? position : 0;
return this.lastIndexOf(pattern, position) === position;
position = angular.isNumber(position) ? position : 0;
return this.lastIndexOf(pattern, position) === position;
};
String.prototype._base64_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
String.prototype.base64encode = function () {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
var input = this.utf8encode();
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
var input = this.utf8encode();
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._base64_keyStr.charAt(enc1) + this._base64_keyStr.charAt(enc2) +
this._base64_keyStr.charAt(enc3) + this._base64_keyStr.charAt(enc4);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
return output;
output = output +
this._base64_keyStr.charAt(enc1) + this._base64_keyStr.charAt(enc2) +
this._base64_keyStr.charAt(enc3) + this._base64_keyStr.charAt(enc4);
}
return output;
};
String.prototype.base64decode = function() {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
var input = "" + this; // .replace(/[^A-Za-z0-9\+\/\=]/g, "")
while (i < input.length) {
enc1 = this._base64_keyStr.indexOf(input.charAt(i++));
enc2 = this._base64_keyStr.indexOf(input.charAt(i++));
enc3 = this._base64_keyStr.indexOf(input.charAt(i++));
enc4 = this._base64_keyStr.indexOf(input.charAt(i++));
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
var input = "" + this; // .replace(/[^A-Za-z0-9\+\/\=]/g, "")
while (i < input.length) {
enc1 = this._base64_keyStr.indexOf(input.charAt(i++));
enc2 = this._base64_keyStr.indexOf(input.charAt(i++));
enc3 = this._base64_keyStr.indexOf(input.charAt(i++));
enc4 = this._base64_keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
return output;
return output;
};
function l() {
var key = arguments[0];
var value = key;
if (labels[key]) {
value = labels[key];
}
else if (clabels[key]) {
value = clabels[key];
}
for (var i = 1, j = 0; i < arguments.length; i++, j++) {
value = value.replace('%{' + j + '}', arguments[i]);
}
var key = arguments[0];
var value = key;
if (labels[key]) {
value = labels[key];
}
else if (clabels[key]) {
value = clabels[key];
}
for (var i = 1, j = 0; i < arguments.length; i++, j++) {
value = value.replace('%{' + j + '}', arguments[i]);
}
return value;
return value;
}

View File

@ -1,396 +1,403 @@
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
(function() {
'use strict';
'use strict';
/**
* @name Card
* @constructor
* @param {object} futureCardData
*/
function Card(futureCardData) {
/**
* @name Card
* @constructor
* @param {object} futureCardData
*/
function Card(futureCardData) {
// Data is immediately available
if (typeof futureCardData.then !== 'function') {
angular.extend(this, futureCardData);
if (this.pid && !this.id) {
// Prepare for the creation of a new card;
// Get UID from the server.
var newCardData = Card.$$resource.newguid(this.pid);
this.$unwrap(newCardData);
}
}
else {
// The promise will be unwrapped first
this.$unwrap(futureCardData);
}
// Data is immediately available
if (typeof futureCardData.then !== 'function') {
angular.extend(this, futureCardData);
if (this.pid && !this.id) {
// Prepare for the creation of a new card;
// Get UID from the server.
var newCardData = Card.$$resource.newguid(this.pid);
this.$unwrap(newCardData);
this.isNew = true;
}
}
else {
// The promise will be unwrapped first
this.$unwrap(futureCardData);
}
}
Card.$TEL_TYPES = ['work', 'home', 'cell', 'fax', 'pager'];
Card.$EMAIL_TYPES = ['work', 'home', 'pref'];
Card.$URL_TYPES = ['work', 'home', 'pref'];
Card.$ADDRESS_TYPES = ['work', 'home'];
Card.$TEL_TYPES = ['work', 'home', 'cell', 'fax', 'pager'];
Card.$EMAIL_TYPES = ['work', 'home', 'pref'];
Card.$URL_TYPES = ['work', 'home', 'pref'];
Card.$ADDRESS_TYPES = ['work', 'home'];
/**
* @memberof Card
* @desc The factory we'll use to register with Angular
* @returns the Card constructor
*/
Card.$factory = ['$timeout', 'sgSettings', 'sgResource', function($timeout, Settings, Resource) {
angular.extend(Card, {
$$resource: new Resource(Settings.baseURL),
$timeout: $timeout
});
return Card; // return constructor
}];
/**
* @module SOGo.ContactsUI
* @desc Factory registration of Card in Angular module
*/
angular.module('SOGo.ContactsUI')
.factory('sgCard', Card.$factory)
/**
* @name sgAddress
* @memberof ContactsUI
* @desc Directive to format a postal address
*/
.directive('sgAddress', function() {
return {
restrict: 'A',
replace: true,
scope: { data: '=sgAddress' },
controller: ['$scope', function($scope) {
$scope.addressLines = function(data) {
var lines = [];
if (data.street) lines.push(data.street);
if (data.street2) lines.push(data.street2);
var locality_region = [];
if (data.locality) locality_region.push(data.locality);
if (data.region) locality_region.push(data.region);
if (locality_region.length > 0) lines.push(locality_region.join(', '));
if (data.country) lines.push(data.country);
if (data.postalcode) lines.push(data.postalcode);
return lines.join('<br>');
};
}],
template: '<address ng-bind-html="addressLines(data)"></address>'
}
/**
* @memberof Card
* @desc The factory we'll use to register with Angular
* @returns the Card constructor
*/
Card.$factory = ['$timeout', 'sgSettings', 'sgResource', function($timeout, Settings, Resource) {
angular.extend(Card, {
$$resource: new Resource(Settings.baseURL),
$timeout: $timeout
});
/**
* @memberof Card
* @desc Fetch a card from a specific addressbook
* @param {string} addressbook_id - the addressbook ID
* @param {string} card_id - the card ID
* @see {@link AddressBook.$getCard}
*/
Card.$find = function(addressbook_id, card_id) {
var futureCardData = this.$$resource.find([addressbook_id, card_id].join('/'));
return Card; // return constructor
}];
if (card_id) return new Card(futureCardData); // a single card
/**
* @module SOGo.ContactsUI
* @desc Factory registration of Card in Angular module
*/
angular.module('SOGo.ContactsUI')
.factory('sgCard', Card.$factory)
return Card.$unwrapCollection(futureCardData); // a collection of cards
};
/**
* @name sgAddress
* @memberof ContactsUI
* @desc Directive to format a postal address
*/
.directive('sgAddress', function() {
return {
restrict: 'A',
replace: true,
scope: { data: '=sgAddress' },
controller: ['$scope', function($scope) {
$scope.addressLines = function(data) {
var lines = [],
locality_region = [];
if (data.street) lines.push(data.street);
if (data.street2) lines.push(data.street2);
if (data.locality) locality_region.push(data.locality);
if (data.region) locality_region.push(data.region);
if (locality_region.length > 0) lines.push(locality_region.join(', '));
if (data.country) lines.push(data.country);
if (data.postalcode) lines.push(data.postalcode);
return lines.join('<br>');
};
}],
template: '<address ng-bind-html="addressLines(data)"></address>'
}
});
/**
* @memberof Card
* @desc Unwrap to a collection of Card instances
* @param {Object} futureCardData
*/
Card.$unwrapCollection = function(futureCardData) {
var collection = {};
/**
* @memberof Card
* @desc Fetch a card from a specific addressbook
* @param {string} addressbook_id - the addressbook ID
* @param {string} card_id - the card ID
* @see {@link AddressBook.$getCard}
*/
Card.$find = function(addressbook_id, card_id) {
var futureCardData = this.$$resource.find([addressbook_id, card_id].join('/'));
collection.$futureCardData = futureCardData;
if (card_id) return new Card(futureCardData); // a single card
futureCardData.then(function(cards) {
Card.$timeout(function() {
angular.forEach(cards, function(data, index) {
collection[data.id] = new Card(data);
});
});
return Card.$unwrapCollection(futureCardData); // a collection of cards
};
/**
* @memberof Card
* @desc Unwrap to a collection of Card instances
* @param {Object} futureCardData
*/
Card.$unwrapCollection = function(futureCardData) {
var collection = {};
collection.$futureCardData = futureCardData;
futureCardData.then(function(cards) {
Card.$timeout(function() {
angular.forEach(cards, function(data, index) {
collection[data.id] = new Card(data);
});
});
});
return collection;
};
return collection;
};
/**
* @function $id
* @memberof Card.prototype
* @desc Return the card ID
* @returns the card ID
*/
Card.prototype.$id = function() {
return this.$futureCardData.then(function(data) {
return data.id;
});
};
/**
* @function $id
* @memberof Card.prototype
* @desc Return the card ID
* @returns the card ID
*/
Card.prototype.$id = function() {
return this.$futureCardData.then(function(data) {
return data.id;
});
};
/**
* @function $save
* @memberof Card.prototype
* @desc Save the card to the server
*/
Card.prototype.$save = function() {
var action = 'saveAsContact';
if (this.tag == 'vlist') action = 'saveAsList';
//var action = 'saveAs' + this.tag.substring(1).capitalize();
return Card.$$resource.save([this.pid, this.id || '_new_'].join('/'),
this.$omit(),
{ 'action': action })
.then(function (data) {
return data;
});
};
/**
* @function $save
* @memberof Card.prototype
* @desc Save the card to the server
*/
Card.prototype.$save = function() {
var action = 'saveAsContact';
if (this.tag == 'vlist') action = 'saveAsList';
//var action = 'saveAs' + this.tag.substring(1).capitalize();
return Card.$$resource.save([this.pid, this.id || '_new_'].join('/'),
this.$omit(),
{ action: action })
.then(function(data) {
return data;
});
};
Card.prototype.$delete = function(attribute, index) {
if (attribute) {
if (index > -1 && this[attribute].length > index) {
this[attribute].splice(index, 1);
}
Card.prototype.$delete = function(attribute, index) {
if (attribute) {
if (index > -1 && this[attribute].length > index) {
this[attribute].splice(index, 1);
}
}
else {
// No arguments -- delete card
return Card.$$resource.remove([this.pid, this.id].join('/'));
}
};
Card.prototype.$fullname = function() {
var fn = this.fn || '', names;
if (fn.length == 0) {
names = [];
if (this.givenname && this.givenname.length > 0)
names.push(this.givenname);
if (this.nickname && this.nickname.length > 0)
names.push('<em>' + this.nickname + '</em>');
if (this.sn && this.sn.length > 0)
names.push(this.sn);
if (names.length > 0)
fn = names.join(' ');
else if (this.org && this.org.length > 0) {
fn = this.org;
}
else if (this.emails && this.emails.length > 0) {
fn = _.find(this.emails, function(i) { return i.value != ''; }).value;
}
else if (this.c_cn && this.c_cn.length > 0) {
fn = this.c_cn;
}
}
return fn;
};
Card.prototype.$description = function() {
var description = [];
if (this.title) description.push(this.title);
if (this.role) description.push(this.role);
if (this.orgUnits && this.orgUnits.length > 0)
_.forEach(this.orgUnits, function(unit) {
if (unit.value != '')
description.push(unit.value);
});
if (this.org) description.push(this.org);
if (this.description) description.push(this.description);
return description.join(', ');
};
/**
* @function $preferredEmail
* @memberof Card.prototype
* @desc Get the preferred email address
* @param {string} [partial] - a partial string that the email must match
* @returns the first email address of type "pref" or the first address if none found
*/
Card.prototype.$preferredEmail = function(partial) {
var email, re;
if (partial) {
re = new RegExp(partial);
email = _.find(this.emails, function(o) {
return re.test(o.value);
});
}
if (email) {
email = email.value;
}
else {
email = _.find(this.emails, function(o) {
return o.type == 'pref';
});
if (email) {
email = email.value;
}
else if (this.emails && this.emails.length) {
email = this.emails[0].value;
}
else {
email = '';
}
}
return email;
};
/**
* @function $shortFormat
* @memberof Card.prototype
* @param {string} [partial] - a partial string that the email must match
* @returns the fullname along with a matching email address in parentheses
*/
Card.prototype.$shortFormat = function(partial) {
var fullname = this.$fullname(),
email = this.$preferredEmail(partial);
if (email && email != fullname)
fullname += ' (' + email + ')';
return fullname;
};
Card.prototype.$birthday = function() {
return new Date(this.birthday * 1000);
};
Card.prototype.$isCard = function() {
return this.tag == 'vcard';
};
Card.prototype.$isList = function() {
return this.tag == 'vlist';
};
Card.prototype.$addOrgUnit = function(orgUnit) {
if (angular.isUndefined(this.orgUnits)) {
this.orgUnits = [{value: orgUnit}];
}
else {
for (var i = 0; i < this.orgUnits.length; i++) {
if (this.orgUnits[i].value == orgUnit) {
break;
}
else {
// No arguments -- delete card
return Card.$$resource.remove([this.pid, this.id].join('/'));
}
if (i == this.orgUnits.length)
this.orgUnits.push({value: orgUnit});
}
return this.orgUnits.length - 1;
};
Card.prototype.$addCategory = function(category) {
if (angular.isUndefined(this.categories)) {
this.categories = [{value: category}];
}
else {
for (var i = 0; i < this.categories.length; i++) {
if (this.categories[i].value == category) {
break;
}
};
}
if (i == this.categories.length)
this.categories.push({value: category});
}
return this.categories.length - 1;
};
Card.prototype.$fullname = function() {
var fn = this.fn || '';
if (fn.length == 0) {
var names = [];
if (this.givenname && this.givenname.length > 0)
names.push(this.givenname);
if (this.nickname && this.nickname.length > 0)
names.push("<em>" + this.nickname + "</em>");
if (this.sn && this.sn.length > 0)
names.push(this.sn);
if (names.length > 0)
fn = names.join(' ');
else if (this.org && this.org.length > 0) {
fn = this.org;
}
else if (this.emails && this.emails.length > 0) {
fn = _.find(this.emails, function(i) { return i.value != ''; }).value;
}
else if (this.c_cn && this.c_cn.length > 0) {
fn = this.c_cn;
}
Card.prototype.$addEmail = function(type) {
if (angular.isUndefined(this.emails)) {
this.emails = [{type: type, value: ''}];
}
else if (!_.find(this.emails, function(i) { return i.value == ''; })) {
this.emails.push({type: type, value: ''});
}
return this.emails.length - 1;
};
Card.prototype.$addPhone = function(type) {
if (angular.isUndefined(this.phones)) {
this.phones = [{type: type, value: ''}];
}
else if (!_.find(this.phones, function(i) { return i.value == ''; })) {
this.phones.push({type: type, value: ''});
}
return this.phones.length - 1;
};
Card.prototype.$addUrl = function(type, url) {
if (angular.isUndefined(this.urls)) {
this.urls = [{type: type, value: url}];
}
else if (!_.find(this.urls, function(i) { return i.value == url; })) {
this.urls.push({type: type, value: url});
}
return this.urls.length - 1;
};
Card.prototype.$addAddress = function(type, postoffice, street, street2, locality, region, country, postalcode) {
if (angular.isUndefined(this.addresses)) {
this.addresses = [{type: type, postoffice: postoffice, street: street, street2: street2, locality: locality, region: region, country: country, postalcode: postalcode}];
}
else if (!_.find(this.addresses, function(i) {
return i.street == street
&& i.street2 == street2
&& i.locality == locality
&& i.country == country
&& i.postalcode == postalcode;
})) {
this.addresses.push({type: type, postoffice: postoffice, street: street, street2: street2, locality: locality, region: region, country: country, postalcode: postalcode});
}
return this.addresses.length - 1;
};
Card.prototype.$addMember = function(email) {
if (angular.isUndefined(this.refs)) {
this.refs = [{email: email}];
}
else {
for (var i = 0; i < this.refs.length; i++) {
if (this.refs[i].email == email) {
break;
}
}
if (i == this.refs.length)
this.refs.push({email: email});
}
return this.refs.length - 1;
};
return fn;
};
/**
* @function $updateMember
* @memberof Card.prototype
* @desc Update an existing list member from a Card instance.
* A list member has the following attribtues:
* - email
* - reference
* - fn
* @param {number} index
* @param {string} email
* @param {Card} card
*/
Card.prototype.$updateMember = function(index, email, card) {
var ref = {email: email, reference: card.c_name, fn: card.$fullname()};
this.refs[index] = ref;
};
Card.prototype.$description = function() {
var description = [];
if (this.title) description.push(this.title);
if (this.role) description.push(this.role);
if (this.orgUnits && this.orgUnits.length > 0)
_.forEach(this.orgUnits, function(unit) {
if (unit.value != '')
description.push(unit.value);
});
if (this.org) description.push(this.org);
if (this.description) description.push(this.description);
// Unwrap a promise
Card.prototype.$unwrap = function(futureCardData) {
var _this = this;
return description.join(', ');
};
if (futureCardData) {
this.$futureCardData = futureCardData;
}
return this.$futureCardData.then(function(data) {
// The success callback. Calling _.extend from $timeout will wrap it into a try/catch call and return
// a promise resolved immediately.
return Card.$timeout(function() {
angular.extend(_this, data);
console.debug(angular.toJson(data));
return _this;
});
});
};
/**
* @function $preferredEmail
* @memberof Card.prototype
* @desc Get the preferred email address
* @param {string} [partial] - a partial string that the email must match
* @returns the first email address of type "pref" or the first address if none found
*/
Card.prototype.$preferredEmail = function(partial) {
var email;
if (partial) {
var re = new RegExp(partial);
email = _.find(this.emails, function(o) {
return re.test(o.value);
});
}
if (email) {
email = email.value;
}
else {
email = _.find(this.emails, function(o) {
return o.type == 'pref';
});
if (email) {
email = email.value;
}
else if (this.emails && this.emails.length) {
email = this.emails[0].value;
}
else {
email = '';
}
}
return email;
};
/**
* @function $shortFormat
* @memberof Card.prototype
* @param {string} [partial] - a partial string that the email must match
* @returns the fullname along with a matching email address in parentheses
*/
Card.prototype.$shortFormat = function(partial) {
var fullname = this.$fullname();
var email = this.$preferredEmail(partial);
if (email && email != fullname)
fullname += ' (' + email + ')';
return fullname;
};
Card.prototype.$birthday = function() {
return new Date(this.birthday*1000);
};
Card.prototype.$isCard = function() {
return this.tag == 'vcard';
};
Card.prototype.$isList = function() {
return this.tag == 'vlist';
};
Card.prototype.$addOrgUnit = function(orgUnit) {
if (angular.isUndefined(this.orgUnits)) {
this.orgUnits = [{value: orgUnit}];
}
else {
for (var i = 0; i < this.orgUnits.length; i++) {
if (this.orgUnits[i].value == orgUnit) {
break;
}
}
if (i == this.orgUnits.length)
this.orgUnits.push({value: orgUnit});
}
return this.orgUnits.length - 1;
};
Card.prototype.$addCategory = function(category) {
if (angular.isUndefined(this.categories)) {
this.categories = [{value: category}];
}
else {
for (var i = 0; i < this.categories.length; i++) {
if (this.categories[i].value == category) {
break;
}
}
if (i == this.categories.length)
this.categories.push({value: category});
}
return this.categories.length - 1;
};
Card.prototype.$addEmail = function(type) {
if (angular.isUndefined(this.emails)) {
this.emails = [{type: type, value: ''}];
}
else if (!_.find(this.emails, function(i) { return i.value == ''; })) {
this.emails.push({type: type, value: ''});
}
return this.emails.length - 1;
};
Card.prototype.$addPhone = function(type) {
if (angular.isUndefined(this.phones)) {
this.phones = [{type: type, value: ''}];
}
else if (!_.find(this.phones, function(i) { return i.value == ''; })) {
this.phones.push({type: type, value: ''});
}
return this.phones.length - 1;
};
Card.prototype.$addUrl = function(type, url) {
if (angular.isUndefined(this.urls)) {
this.urls = [{type: type, value: url}];
}
else if (!_.find(this.urls, function(i) { return i.value == url; })) {
this.urls.push({type: type, value: url});
}
return this.urls.length - 1;
};
Card.prototype.$addAddress = function(type, postoffice, street, street2, locality, region, country, postalcode) {
if (angular.isUndefined(this.addresses)) {
this.addresses = [{type: type, postoffice: postoffice, street: street, street2: street2, locality: locality, region: region, country: country, postalcode: postalcode}];
}
else if (!_.find(this.addresses, function(i) {
return i.street == street
&& i.street2 == street2
&& i.locality == locality
&& i.country == country
&& i.postalcode == postalcode;
})) {
this.addresses.push({type: type, postoffice: postoffice, street: street, street2: street2, locality: locality, region: region, country: country, postalcode: postalcode});
}
return this.addresses.length - 1;
};
Card.prototype.$addMember = function(email) {
if (angular.isUndefined(this.refs)) {
this.refs = [{email: email}];
}
else {
for (var i = 0; i < this.refs.length; i++) {
if (this.refs[i].email == email) {
break;
}
}
if (i == this.refs.length)
this.refs.push({email: email});
}
return this.refs.length - 1;
};
/**
* @function $updateMember
* @memberof Card.prototype
* @desc Update an existing list member from a Card instance.
* A list member has the following attribtues:
* - email
* - reference
* - fn
* @param {number} index
* @param {string} email
* @param {Card} card
*/
Card.prototype.$updateMember = function(index, email, card) {
var ref = {'email': email, 'reference': card.c_name, 'fn': card.$fullname()};
this.refs[index] = ref;
};
// Unwrap a promise
Card.prototype.$unwrap = function(futureCardData) {
var self = this;
this.$futureCardData = futureCardData;
this.$futureCardData.then(function(data) {
// The success callback. Calling _.extend from $timeout will wrap it into a try/catch call and return
// a promise resolved immediately.
Card.$timeout(function() {
angular.extend(self, data);
});
});
};
// Return a sanitized object used to send to the server
Card.prototype.$omit = function() {
var card = {};
angular.forEach(this, function(value, key) {
if (key != 'constructor' && key[0] != '$') {
card[key] = value;
}
});
return card;
};
// Return a sanitized object used to send to the server
Card.prototype.$omit = function() {
var card = {};
angular.forEach(this, function(value, key) {
if (key != 'constructor' && key[0] != '$') {
card[key] = value;
}
});
return card;
};
})();

View File

@ -1,23 +1,23 @@
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* JavaScript for SOGoRootPage */
(function() {
'use strict';
'use strict';
angular.module('SOGo.MainUI', ['SOGo.Authentication'])
angular.module('SOGo.MainUI', ['SOGo.Authentication'])
.controller('loginController', ['$scope', 'Authentication', function($scope, Authentication) {
$scope.warning = false;
$scope.creds = { username: null, password: null };
$scope.login = function(creds) {
$scope.warning = false;
$scope.creds = { 'username': null, 'password': null };
$scope.login = function(creds) {
$scope.warning = false;
Authentication.login(creds)
.then(function(url) {
window.location.href = url;
}, function(msg) {
$scope.warning = msg.error;
});
return false;
};
Authentication.login(creds)
.then(function(url) {
window.location.href = url;
}, function(msg) {
$scope.warning = msg.error;
});
return false;
};
}]);
})();