/*
Copyright 2008-2011 Clipperz Srl
This file is part of Clipperz Community Edition.
Clipperz Community Edition is an online password manager.
For further information about its features and functionalities please
refer to http://www.clipperz.com.
* Clipperz Community Edition 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 Community Edition 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 Community Edition. If not, see
.
*/
if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
if (typeof(Clipperz.PM.Components) == 'undefined') { Clipperz.PM.Components = {}; }
if (typeof(Clipperz.PM.Components.Panels) == 'undefined') { Clipperz.PM.Components.Panels = {}; }
//#############################################################################
Clipperz.PM.Components.Panels.AccountPanel = function(anElement, args) {
//MochiKit.Logging.logDebug(">>> new AccountPanel");
args = args || {};
Clipperz.PM.Components.Panels.AccountPanel.superclass.constructor.call(this, anElement, args);
Clipperz.NotificationCenter.register(null, 'setupDone', this, 'render');
this._shouldLoadLoginHistory = true;
// this.render();
//MochiKit.Logging.logDebug("<<< new AccountPanel");
return this;
}
//=============================================================================
YAHOO.extendX(Clipperz.PM.Components.Panels.AccountPanel, Clipperz.PM.Components.Panels.BasePanel, {
'toString': function() {
return "Clipperz.PM.Components.AccountPanel component";
},
//-------------------------------------------------------------------------
'render': function() {
var errorMessageActor;
var changePasswordButton;
var deleteAccountButton;
try {
//MochiKit.Logging.logDebug(">>> AccountPanel.render");
Clipperz.NotificationCenter.unregister(this);
MochiKit.Signal.disconnectAllTo(this);
this.element().update("");
Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'table', border:'0', cellspacing:'0', cellpadding:'0', children:[
{tag:'tbody', children:[
{tag:'tr', children:[
{tag:'td', valign:'top', width:'200', children:[
{tag:'ul', id:"accountSubMenu", cls:'subMenu', children:[
{tag:'li', id:'changePassphraseTab', htmlString:Clipperz.PM.Strings['changePasswordTabLabel']},
{tag:'li', id:'manageOTPTab', htmlString:Clipperz.PM.Strings['manageOTPTabLabel']},
{tag:'li', id:'accountPreferencesTab', htmlString:Clipperz.PM.Strings['accountPreferencesLabel']},
{tag:'li', id:'loginHistoryTab', htmlString:Clipperz.PM.Strings['accountLoginHistoryLabel']},
{tag:'li', id:'deleteAccountTab', htmlString:Clipperz.PM.Strings['deleteAccountTabLabel']}
// {tag:'li', id:'paidAccountTab'), htmlString:Clipperz.PM.Strings['paidAccountTabLabel']}
]}
]},
{tag:'td', valign:'top', children:[
{tag:'ul', cls:'clipperzTabPanels', children:[
{tag:'li', id:this.getId('changePassphrasePanel'), children:[
{tag:'div', cls:'clipperzSubPanel', children:[
{tag:'h5', htmlString:Clipperz.PM.Strings['changePasswordTabTitle']},
{tag:'div', cls:'panelBody', id:'changePassphraseBlock', children:[
{tag:'form', id:this.getId('changePassphraseForm'), children:[
{tag:'h5', cls:'errorMessage', id:this.getId('changePassphrase_errorMessage')},
{tag:'table', cls:'panelBody', children:[
{tag:'tr', children:[
{tag:'td', children:[
{tag:'span', cls:'formLabel', htmlString:Clipperz.PM.Strings['changePasswordFormUsernameLabel']}
]},
{tag:'td', children:[
{tag:'input', type:'text', name:'username', id:this.getId('changePassphrase_username')}
]}
]},
{tag:'tr', children:[
{tag:'td', children:[
{tag:'span', cls:'formLabel', htmlString:Clipperz.PM.Strings['changePasswordFormOldPassphraseLabel']}
]},
{tag:'td', children:[
{tag:'input', type:'password', name:'oldPassphrase', id:this.getId('changePassphrase_oldPassphrase')}
]}
]},
{tag:'tr', children:[
{tag:'td', children:[
{tag:'span', cls:'formLabel', htmlString:Clipperz.PM.Strings['changePasswordFormNewPassphraseLabel']}
]},
{tag:'td', children:[
{tag:'input', type:'password', name:'newPassphrase', id:this.getId('changePassphrase_newPassphrase')}
]}
]},
{tag:'tr', children:[
{tag:'td', children:[
{tag:'span', cls:'formLabel', htmlString:Clipperz.PM.Strings['changePasswordFormRetypePassphraseLabel']}
]},
{tag:'td', children:[
{tag:'input', type:'password', name:'renewPassphrase', id:this.getId('changePassphrase_renewPassphrase')}
]}
]},
{tag:'tr', children:[
{tag:'td', align:'right', children:[
{tag:'input', type:'checkbox', id:this.getId('changePassphrase_safetyCheck')}
]},
{tag:'td', children:[
{tag:'span', htmlString:Clipperz.PM.Strings['changePasswordFormSafetyCheckboxLabel']}
]}
]}
]},
{tag:'div', cls:'clipperzSubPanelButtonBox', children:[
{tag:'div', id:this.getId('changePassphraseButton')}
]}
]}
]}
]}
]},
{tag:'li', id:this.getId('manageOTPPanel'), children:[
{tag:'div', cls:'clipperzSubPanel', children:[
{tag:'h5', htmlString:Clipperz.PM.Strings['manageOTPTabTitle']},
{tag:'div', cls:'panelDescription', htmlString:Clipperz.PM.Strings['manageOTPTabDescription']},
{tag:'div', id:'OTPComponent'}
]}
]},
{tag:'li', id:this.getId('accountPreferencesPanel'), children:[
{tag:'div', cls:'clipperzSubPanel', children:[
{tag:'h5', htmlString:Clipperz.PM.Strings['accountPreferencesTabTitle']},
{tag:'div', cls:'panelBody', id:this.getId('preferencesPanelBody')}
]}
]},
{tag:'li', id:this.getId('loginHistoryAccountPanel'), children:[
{tag:'div', cls:'clipperzSubPanel', children:[
{tag:'h5', htmlString:Clipperz.PM.Strings['loginHistoryTabTitle']},
{tag:'div', cls:'panelBody', id:'loginHistoryAccountBlock'}
]}
]},
{tag:'li', id:this.getId('deleteAccountPanel'), children:[
{tag:'div', cls:'clipperzSubPanel', children:[
{tag:'h5', htmlString:Clipperz.PM.Strings['deleteAccountTabTitle']},
{tag:'div', cls:'panelBody', id:'deleteAccountBlock', children:[
{tag:'form', id:this.getId('deleteAccountForm'), children:[
{tag:'h5', cls:'errorMessage', id:this.getId('deleteAccount_errorMessage')},
{tag:'table', cls:'panelBody', children:[
{tag:'tr', children:[
{tag:'td', children:[
{tag:'span', cls:'formLabel', htmlString:Clipperz.PM.Strings['deleteAccountFormUsernameLabel']}
]},
{tag:'td', children:[
{tag:'input', type:'text', name:'username', id:this.getId('deleteAccount_username')}
]}
]},
{tag:'tr', children:[
{tag:'td', children:[
{tag:'span', cls:'formLabel', htmlString:Clipperz.PM.Strings['deleteAccountFormPassphraseLabel']}
]},
{tag:'td', children:[
{tag:'input', type:'password', name:'passphrase', id:this.getId('deleteAccount_passphrase')}
]}
]},
{tag:'tr', children:[
{tag:'td', align:'right', children:[
{tag:'input', type:'checkbox', id:this.getId('deleteAccount_safetyCheck')}
]},
{tag:'td', children:[
{tag:'span', htmlString:Clipperz.PM.Strings['deleteAccountFormSafetyCheckboxLabel']}
]}
]}
]},
{tag:'div', cls:'clipperzSubPanelButtonBox', children:[
{tag:'div', id:this.getId('deleteAccountButton')}
]}
]}
]}
]}
]}
/*
{tag:'li', id:this.getId('paidAccountPanel'), children:[
{tag:'div', cls:'clipperzSubPanel', children:[
{tag:'h5', htmlString:Clipperz.PM.Strings['upgradeAccountTabTitle']},
{tag:'div', htmlString:Clipperz.PM.Strings['comingSoon']}
]}
]}
*/
]}
]}
]}
]}
]});
//MochiKit.Logging.logDebug("--- AccountPanel.render - 1");
MochiKit.Signal.connect(this.getId('changePassphraseForm'), 'onkeydown', this, 'onkeydown');
errorMessageActor = this.getActor('changePassphrase_errorMessage');
errorMessageActor.setVisibilityMode(YAHOO.ext.Element.DISPLAY);
errorMessageActor.update("---");
errorMessageActor.hide();
changePasswordButton = new YAHOO.ext.Button(this.getDom('changePassphraseButton'), {text:Clipperz.PM.Strings['changePasswordFormSubmitLabel'], handler:this.doChangePassphrase, scope:this});
//MochiKit.Logging.logDebug("--- AccountPanel.render - 2");
MochiKit.Signal.connect(this.getId('deleteAccountForm'), 'onkeydown', this, 'onkeydown');
errorMessageActor = this.getActor('deleteAccount_errorMessage');
errorMessageActor.setVisibilityMode(YAHOO.ext.Element.DISPLAY);
errorMessageActor.update(Clipperz.PM.Strings['deleteAccountFormEmptyErrorMessage']);
errorMessageActor.hide();
deleteAccountButton = new YAHOO.ext.Button(this.getDom('deleteAccountButton'), {text:Clipperz.PM.Strings['deleteAccountFormSubmitLabel'], handler:this.doDeleteAccount, scope:this});
//MochiKit.Logging.logDebug("--- AccountPanel.render - 5");
if (Clipperz.PM.Proxy.defaultProxy.isReadOnly()) {
this.getElement('changePassphraseForm').addClass('read-only');
// this.getElement('accountPreferencesForm').addClass('read-only');
this.getElement('deleteAccountForm').addClass('read-only');
changePasswordButton.disable();
deleteAccountButton.disable();
}
//MochiKit.Logging.logDebug("--- AccountPanel.render - 6");
new Clipperz.PM.Components.PasswordEntropyDisplay(this.getElement('changePassphrase_oldPassphrase'));
new Clipperz.PM.Components.PasswordEntropyDisplay(this.getElement('changePassphrase_newPassphrase'));
new Clipperz.PM.Components.OTP.MainComponent(YAHOO.ext.Element.get('OTPComponent'), {user:this.user()});
this.tabPanelController().setUp();
Clipperz.NotificationCenter.register(null, 'tabSelected', this, 'tabSelectedHandler');
Clipperz.NotificationCenter.register(null, 'updatedPreferences', this, 'renderPreferences');
Clipperz.NotificationCenter.register(null, 'switchLanguage', this, 'switchLanguageHandler');
//MochiKit.Logging.logDebug("<<< AccountPanel.render");
} catch(exception) {
MochiKit.Logging.logError("### " + exception);
throw exception;
}
},
//-------------------------------------------------------------------------
'tabPanelController': function() {
if (this._tabPanelController == null) {
var tabPanelControllerConfig;
tabPanelControllerConfig = {}
tabPanelControllerConfig['changePassphraseTab'] = this.getId('changePassphrasePanel');
tabPanelControllerConfig['manageOTPTab'] = this.getId('manageOTPPanel');
tabPanelControllerConfig['accountPreferencesTab'] = this.getId('accountPreferencesPanel');
tabPanelControllerConfig['loginHistoryTab'] = this.getId('loginHistoryAccountPanel');
tabPanelControllerConfig['deleteAccountTab'] = this.getId('deleteAccountPanel');
// tabPanelControllerConfig['paidAccountTab'] = this.getId('paidAccountPanel');
this._tabPanelController = new Clipperz.PM.Components.TabPanel.TabPanelController({
name:'accountTabPanel',
config:tabPanelControllerConfig,
selectedTab:'changePassphraseTab'
});
}
return this._tabPanelController;
},
//-------------------------------------------------------------------------
'doChangePassphrase': function() {
if (Clipperz.PM.Proxy.defaultProxy.isReadOnly() == false) {
var username;
var oldPassphrase;
var newPassphrase;
var renewPassphrase;
var safetyCheck;
var areThereAnyErrors;
var errorMessageActor;
errorMessageActor = this.getActor('changePassphrase_errorMessage');
areThereAnyErrors = false;
username = this.getDom('changePassphrase_username').value;
oldPassphrase= this.getDom('changePassphrase_oldPassphrase').value;
newPassphrase= this.getDom('changePassphrase_newPassphrase').value;
renewPassphrase= this.getDom('changePassphrase_renewPassphrase').value;
safetyCheck = this.getDom('changePassphrase_safetyCheck').checked;
if (this.user().username() != username) {
this.showFormErrorMessageAnimation(errorMessageActor, Clipperz.PM.Strings['changePasswordFormWrongUsernameWarning']);
this.getElement('changePassphrase_username').focus().dom.select();
areThereAnyErrors = true;
} else if (this.user().passphrase() != oldPassphrase) {
this.showFormErrorMessageAnimation(errorMessageActor, Clipperz.PM.Strings['changePasswordFormWrongPassphraseWarning']);
this.getElement('changePassphrase_oldPassphrase').focus().dom.select();
areThereAnyErrors = true;
} else if (newPassphrase != renewPassphrase) {
this.showFormErrorMessageAnimation(errorMessageActor, Clipperz.PM.Strings['changePasswordFormWrongRetypePassphraseWarning']);
this.getElement('changePassphrase_renewPassphrase').focus().dom.select();
areThereAnyErrors = true;
} else if (safetyCheck != true) {
this.showFormErrorMessageAnimation(errorMessageActor, Clipperz.PM.Strings['changePasswordFormSafetyCheckWarning']);
this.getElement('changePassphrase_safetyCheck').focus();
areThereAnyErrors = true;
}
if (areThereAnyErrors == false) {
errorMessageActor.hide();
this.doChangePassphraseWithUsernameAndPassphrase(username, newPassphrase);
}
}
},
//-------------------------------------------------------------------------
'doChangePassphraseWithUsernameAndPassphrase': function(anUsername, aPassphrase) {
var deferredResult;
//MochiKit.Logging.logDebug(">>> AccountPanel.doChangePassphraseWithUsernameAndPassphrase - this.user: " + this.user());
deferredResult = new MochiKit.Async.Deferred();
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug(" AccountPanel.doChangePassphraseWithUsernameAndPassphrase 1: " + res); return res;});
deferredResult.addCallback(MochiKit.Base.method(Clipperz.PM.Components.MessageBox(), 'deferredShow'),
{
title:Clipperz.PM.Strings['changePasswordFormProgressDialogTitle'],
text:Clipperz.PM.Strings['changePasswordFormProgressDialogEmptyText'],
width:240,
showProgressBar:true,
showCloseButton:false,
steps:4
},
this.getDom('changePassphraseButton')
);
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug(" AccountPanel.doChangePassphraseWithUsernameAndPassphrase 2: " + res); return res;});
deferredResult.addCallback(MochiKit.Base.method(this.user(), 'changeCredentials'), anUsername, aPassphrase);
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug(" AccountPanel.doChangePassphraseWithUsernameAndPassphrase 3: " + res); return res;});
deferredResult.addCallback(function() {
Clipperz.PM.Components.MessageBox().update({
title:Clipperz.PM.Strings['changePasswordFormProgressDialogConnectedMessageTitle'],
text:Clipperz.PM.Strings['changePasswordFormProgressDialogConnectedMessageText'],
/*showProgressBar:false,*/
step:'next'
});
});
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug(" AccountPanel.doChangePassphraseWithUsernameAndPassphrase 4: " + res); return res;});
deferredResult.addCallback(MochiKit.Async.wait, 1);
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug(" AccountPanel.doChangePassphraseWithUsernameAndPassphrase 5: " + res); return res;});
deferredResult.addCallback(function(anAccountPanel, res) {
Clipperz.PM.Components.MessageBox().hide(YAHOO.ext.Element.get('main'));
anAccountPanel.getDom('changePassphrase_username').value = "";
anAccountPanel.getDom('changePassphrase_oldPassphrase').value = "";
anAccountPanel.getElement('changePassphrase_oldPassphrase').focus();
anAccountPanel.getDom('changePassphrase_newPassphrase').value = "";
anAccountPanel.getElement('changePassphrase_newPassphrase').focus();
anAccountPanel.getDom('changePassphrase_renewPassphrase').value = "";
anAccountPanel.getDom('changePassphrase_safetyCheck').checked = false;
anAccountPanel.getElement('changePassphrase_username').focus();
return res;
}, this);
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug(" AccountPanel.doChangePassphraseWithUsernameAndPassphrase 6: " + res); return res;});
deferredResult.addErrback(function() {
Clipperz.PM.Components.MessageBox().update({
title:Clipperz.PM.Strings['changePasswordFormProgressDialogErrorMessageTitle'],
text:Clipperz.PM.Strings['changePasswordFormProgressDialogErrorMessageText'],
buttons:{'ok':"close"}
});
});
//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug(" AccountPanel.doChangePassphraseWithUsernameAndPassphrase 7: " + res); return res;});
deferredResult.callback();
//MochiKit.Logging.logDebug("<<< AccountPanel.doChangePassphraseWithUsernameAndPassphrase");
},
//-------------------------------------------------------------------------
'doDeleteAccount': function() {
if (Clipperz.PM.Proxy.defaultProxy.isReadOnly() == false) {
var username;
var passphrase;
var safetyCheck;
var areThereAnyErrors;
var errorMessageActor;
errorMessageActor = this.getActor('deleteAccount_errorMessage');
areThereAnyErrors = false;
username = this.getDom('deleteAccount_username').value;
passphrase= this.getDom('deleteAccount_passphrase').value;
safetyCheck = this.getDom('deleteAccount_safetyCheck').checked;
if (this.user().username() != username) {
this.showFormErrorMessageAnimation(errorMessageActor, Clipperz.PM.Strings['deleteAccountFormWrongUsernameWarning']);
this.getElement('deleteAccount_username').focus().dom.select();
areThereAnyErrors = true;
} else if (this.user().passphrase() != passphrase) {
this.showFormErrorMessageAnimation(errorMessageActor, Clipperz.PM.Strings['deleteAccountFormWrongPassphraseWarning']);
this.getElement('deleteAccount_passphrase').focus().dom.select();
areThereAnyErrors = true;
} else if (safetyCheck != true) {
this.showFormErrorMessageAnimation(errorMessageActor, Clipperz.PM.Strings['deleteAccountFormSafetyCheckWarning']);
this.getElement('deleteAccount_safetyCheck').focus();
areThereAnyErrors = true;
}
if (areThereAnyErrors == false) {
var deferred;
deferred = new MochiKit.Async.Deferred();
errorMessageActor.hide();
deferred.addCallback(function() {
var deferredResult;
// TODO: if the form is submitted with the return key, the confirmation dialog is skipped!?
deferredResult = new MochiKit.Async.Deferred();
Clipperz.PM.Components.MessageBox().deferredShow({
title:Clipperz.PM.Strings['accountPanelDeletingAccountPanelConfirmationTitle'],
text:Clipperz.PM.Strings['accountPanelDeleteAccountPanelConfirmationText'],
width:240,
showProgressBar:false,
showCloseButton:false,
buttons:{
'yes':Clipperz.PM.Strings['accountPanelDeleteAccountPanelConfirmButtonLabel'],
'no':Clipperz.PM.Strings['accountPanelDeleteAccountPanelDenyButtonLabel']
},
fn:MochiKit.Base.partial(function(aDeferred, aResult) {
if (aResult == 'yes') {
aDeferred.callback(aResult);
} else {
aDeferred.errback(aResult);
}
}, deferredResult)
});
return deferredResult;
});
deferred.addCallback(MochiKit.Base.method(Clipperz.PM.Components.MessageBox(), 'deferredShow'),
{
title:Clipperz.PM.Strings['accountPanelDeletingAccountPanelProgressTitle'],
text:Clipperz.PM.Strings['accountPanelDeletingAccountPanelProgressText'],
width:240,
showProgressBar:true,
showCloseButton:false
}
);
deferred.addCallback(MochiKit.Base.method(this.user(), 'deleteAccountAction'));
deferred.addCallback(Clipperz.PM.exit, 'accountDeleted.html');
deferred.addErrback(function(res) {
alert(res);
})
deferred.callback();
}
}
},
//-------------------------------------------------------------------------
'showFormErrorMessageAnimation': function(anActor, anErrorMessage, aCallback) {
anActor.update(anErrorMessage);
anActor.show(true);
anActor.play(aCallback);
},
//-------------------------------------------------------------------------
'onkeydown': function(anEvent) {
//MochiKit.Logging.logDebug(">>> onkeydown - " + anEvent.src().id);
if (anEvent.key().code == 13) {
anEvent.stop();
if (anEvent.src() == this.getDom('changePassphraseForm')) {
this.doChangePassphrase();
} else if (anEvent.src() == this.getDom('deleteAccountForm')) {
this.doDeleteAccount();
} else {
}
}
},
//-------------------------------------------------------------------------
'selectSelectedLanguageOption': function() {
var userSelectedLanguage;
userSelectedLanguage = this.user().preferences().preferredLanguage() || "default";
MochiKit.Base.filter(function(anOption) {return (anOption.value == userSelectedLanguage)}, this.getDom('languageSelector').childNodes)[0].selected = true;
},
//-------------------------------------------------------------------------
'doSaveUserPreferences': function() {
var selectedLanguage;
var showDonationReminderDialog;
// var disableUnsecureFaviconLoadingForIE;
//MochiKit.Logging.logDebug(">>> AccountPanel.doSaveUserPreferences");
selectedLanguage = this.getDom('languageSelector').value;
if (selectedLanguage == "default") {
selectedLanguage = null;
}
this.user().preferences().setPreferredLanguage(selectedLanguage);
showDonationReminderDialog = this.getDom('showDonationReminderCheckbox').checked;
this.user().preferences().setShouldShowDonationPanel(showDonationReminderDialog);
// disableUnsecureFaviconLoadingForIE = this.getDom('disableFaviconForIECheckbox').checked;
// this.user().preferences().setDisableUnsecureFaviconLoadingForIE(disableUnsecureFaviconLoadingForIE);
this.user().preferences().saveChanges(this.getDom('saveUserPreferences'));
},
'doCancelUserPreferences': function() {
this.renderPreferences();
},
// 'switchLanguage': function(anEvent) {
// Clipperz.PM.Strings.Languages.setSelectedLanguage(anEvent.src().value);
// },
//-------------------------------------------------------------------------
'renderLoginHistory': function() {
var element;
//MochiKit.Logging.logDebug(">>> AccountPanel.renderLoginHistory");
element = YAHOO.ext.Element.get('loginHistoryAccountBlock');
if (Clipperz.PM.Proxy.defaultProxy.isReadOnly()) {
element.update("");
this.domHelper().append(element, {tag:'div', cls:'loginHistoryReadOnlyMessage', htmlString:Clipperz.PM.Strings['loginHistoryReadOnlyMessage']});
} else {
var deferredResult;
deferredResult = new MochiKit.Async.Deferred();
deferredResult.addCallback(MochiKit.Base.bind(function(anElement) {
anElement.update("");
Clipperz.YUI.DomHelper.append(anElement, {tag:'div', cls:'loadingMessage', htmlString:Clipperz.PM.Strings['loginHistoryLoadingMessage']});
}, this), element);
deferredResult.addCallback(MochiKit.Base.method(this.user(), 'loadLoginHistory'));
deferredResult.addCallback(MochiKit.Base.bind(function(anElement, aResult) {
var loginListItems;
var tBodyElement;
var imageExtension;
var now;
var i, c;
loginListItems = aResult;
//MochiKit.Logging.logDebug("=== loginListItems: " + Clipperz.Base.serializeJSON(loginListItems));
imageExtension = (Clipperz_IEisBroken == true) ? 'gif': 'png';
now = new Date();
anElement.update("");
Clipperz.YUI.DomHelper.append(anElement, {tag:'div', cls:'panelDescription', htmlString:Clipperz.PM.Strings['loginHistoryLoadedMessage']});
Clipperz.YUI.DomHelper.append(anElement, {tag:'table', id:'loginHistoryTable', cellspacing:'0', cellpadding:'2', border:'0', children:[
{tag:'tbody', id:this.getId('loginHistoryTBody'), children:[]}
]});
//# Clipperz.YUI.DomHelper.append(anElement, {tag:'div', id:'loginHistoryFooter', children:[
Clipperz.YUI.DomHelper.append(anElement, {tag:'div', cls:'clipperzSubPanelButtonBox', children:[
{tag:'div', id:this.getId('reloadHistoryButton')}
]});
new YAHOO.ext.Button(this.getDom('reloadHistoryButton'), {text:Clipperz.PM.Strings['loginHistoryReloadButtonLabel'], handler:this.reloadHistory, scope:this});
tBodyElement = this.getElement('loginHistoryTBody');
c = loginListItems.length;
for (i=0; i