summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
commitef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (side-by-side diff)
treec403752d66a2c4775f00affd4fa8431b29c5b68c /frontend/gamma/js/Clipperz/PM/UI/Web/Controllers
parent597ecfbc0249d83e1b856cbd558340c01237a360 (diff)
downloadclipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2
First version of the newly restructured repository
Diffstat (limited to 'frontend/gamma/js/Clipperz/PM/UI/Web/Controllers') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js329
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js652
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardsController.js207
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js611
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js145
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/FilterController.js158
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js374
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/LoginController.js259
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/MainController.js218
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js469
10 files changed, 3422 insertions, 0 deletions
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js
new file mode 100644
index 0000000..05563bf
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js
@@ -0,0 +1,329 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.AppController = function(args) {
+
+ this._user = null;
+ this._tabSlotNames = {
+ //tabName: slotName
+ 'cards': 'cardGrid',
+// 'directLogins': 'directLoginGrid',
+ 'account': 'accountPanel',
+ 'data': 'dataPanel',
+ 'tools': 'toolsPanel'
+ };
+
+ //controllers
+ this._cardsController = null;
+// this._directLoginsController = null;
+ this._filterController = null; // new Clipperz.PM.UI.Web.Controllers.FilterController();
+
+ //components
+ this._appPage = null;
+ this._userInfoBox = null;
+ this._tabSidePanel = null;
+
+// MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'editCard', this, 'handleEditCard');
+// MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'deleteCard', this, 'handleDeleteCard');
+
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved', this, 'userDataSuccessfullySavedHandler');
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.AppController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.AppController";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setUser': function(anUser) {
+ this._user = anUser;
+ },
+
+ 'user': function() {
+ return this._user;
+ },
+
+ //-----------------------------------------------------------------------------
+/*
+ 'tabSlotNames': function() {
+ return this._tabSlotNames;
+ },
+*/
+ 'slotNameForTab': function(aTabName) {
+ return this._tabSlotNames[aTabName];
+ },
+
+ 'hideAllAppPageTabSlots': function() {
+ var aTabName;
+
+ for (aTabName in this._tabSlotNames) {
+ this.appPage().hideSlot(this.slotNameForTab(aTabName));
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'appPage': function() {
+ if (this._appPage == null) {
+ this._appPage = new Clipperz.PM.UI.Web.Components.AppPage();
+ }
+
+ return this._appPage;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'tabSidePanel': function() {
+ if (this._tabSidePanel == null) {
+ this._tabSidePanel = new Clipperz.PM.UI.Web.Components.TabSidePanel();
+ }
+
+ return this._tabSidePanel;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'userInfoBox': function() {
+ if (this._userInfoBox == null) {
+ this._userInfoBox = new Clipperz.PM.UI.Web.Components.UserInfoBox();
+
+ MochiKit.Signal.connect(this._userInfoBox, 'logout', this, 'handleLogout');
+ MochiKit.Signal.connect(this._userInfoBox, 'lock', this, 'handleLock');
+ MochiKit.Signal.connect(this._userInfoBox, 'unlock', this, 'handleUnlock');
+ }
+
+ return this._userInfoBox;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'accountPanel': function () {
+ if (this._accountPanel == null) {
+ this._accountPanel = new Clipperz.PM.UI.Web.Components.AccountPanel(/*{selected:'Preferences'}*/);
+ }
+
+ return this._accountPanel;
+ },
+
+ //.........................................................................
+
+ 'dataPanel': function () {
+ if (this._dataPanel == null) {
+ this._dataPanel = new Clipperz.PM.UI.Web.Components.DataPanel();
+ }
+
+ return this._dataPanel;
+ },
+
+ //.........................................................................
+
+ 'toolsPanel': function () {
+ if (this._toolsPanel == null) {
+ this._toolsPanel = new Clipperz.PM.UI.Web.Components.ToolsPanel();
+ }
+
+ return this._toolsPanel;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'filterController': function () {
+ if (this._filterController == null) {
+ this._filterController = new Clipperz.PM.UI.Web.Controllers.FilterController();
+ }
+
+ return this._filterController;
+ },
+
+ 'cardsController': function() {
+ if (this._cardsController == null) {
+ this._cardsController = new Clipperz.PM.UI.Web.Controllers.CardsController({'filterController':this._filterController});
+ }
+
+ return this._cardsController;
+ },
+
+ //-----------------------------------------------------------------------------
+/*
+ 'directLoginsController': function() {
+//Clipperz.log(">>> AppController.directLoginsController");
+ if (this._directLoginsController == null) {
+ this._directLoginsController = new Clipperz.PM.UI.Web.Controllers.DirectLoginsController({'filterController':this._filterController});
+ }
+//Clipperz.log("<<< AppController.directLoginsController");
+
+ return this._directLoginsController;
+ },
+*/
+ //-----------------------------------------------------------------------------
+
+ 'populateUserInfo': function() {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.populateUserInfo", {trace:false});
+ deferredResult.collectResults({
+ 'username': MochiKit.Base.methodcaller('displayName'),
+ 'cardsNumber': [
+ MochiKit.Base.methodcaller('getRecords'),
+ function (someResults) { return someResults.length; }
+ ],
+ 'directLoginsNumber': [
+ MochiKit.Base.methodcaller('getDirectLogins'),
+ function (someResults) { return someResults.length; }
+ ]
+ })
+ deferredResult.addMethod(this.userInfoBox(), 'updateUserDetails');
+ deferredResult.callback(this.user());
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(args) {
+ var deferredResult;
+ var slot;
+ var page;
+ var user;
+
+ slot = args.slot;
+ user = args.user;
+
+ this.setUser(user);
+
+ slot.setContent(this.appPage());
+
+ this.appPage().slotNamed('userInfoBox').setContent(this.userInfoBox());
+ this.appPage().slotNamed('tabSidePanel').setContent(this.tabSidePanel());
+
+ this.appPage().slotNamed('accountPanel').setContent(this.accountPanel());
+ this.appPage().slotNamed('dataPanel').setContent(this.dataPanel());
+ this.appPage().slotNamed('toolsPanel').setContent(this.toolsPanel());
+
+ this.hideAllAppPageTabSlots();
+ this.appPage().showSlot(this.slotNameForTab('cards'));
+
+ MochiKit.Signal.connect(this.tabSidePanel(), 'tabSelected', this, 'handleTabSelected');
+ MochiKit.Signal.connect(this.tabSidePanel(), 'addCard', this, 'handleAddCard');
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'addCard', this, 'handleAddCard');
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.run", {trace:false});
+
+ deferredResult.addMethod(this.cardsController(), 'run', {slot:this.appPage().slotNamed('cardGrid'), user:user});
+// deferredResult.addMethod(this.directLoginsController(), 'run', {slot:this.appPage().slotNamed('directLoginGrid'), user:user});
+ deferredResult.addMethod(this, 'populateUserInfo');
+
+ deferredResult.addCallback(MochiKit.Visual.ScrollTo, 'miscLinks', {duration:0});
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'CARDS_CONTROLLER_DID_RUN');
+ deferredResult.addMethod(this.tabSidePanel(), 'selectTab', 'cards');
+ deferredResult.callback();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleTabSelected': function (selectedTabName) {
+ var aTabName;
+ var aSlotName;
+
+//Clipperz.log(">>> AppController.handleTabSelected", selectedTabName);
+ this.hideAllAppPageTabSlots();
+ this.appPage().showSlot(this.slotNameForTab(selectedTabName));
+
+ switch (selectedTabName) {
+ case 'cards':
+ this.cardsController().focus();
+ break;
+// case 'directLogins':
+// this.directLoginsController().focus();
+// break;
+ case 'data':
+ break;
+ case 'account':
+ break;
+ case 'tools':
+ break;
+ }
+//Clipperz.log("<-- AppController.handleTabSelected", aTabName);
+ },
+
+ //=============================================================================
+
+ 'handleAddCard': function (aSourceElement) {
+//Clipperz.log("=== AppController.addCard", aSourceElement);
+ this.cardsController().addCard(aSourceElement);
+ },
+
+ //=============================================================================
+
+ 'userDataSuccessfullySavedHandler': function (anEvent) {
+ this.populateUserInfo();
+ },
+
+ //=============================================================================
+
+ 'handleLogout': function(anEvent) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.handleLogout", {trace:false});
+ deferredResult.addMethod(this.user(), 'logout');
+ deferredResult.addCallback(MochiKit.Signal.signal, this, 'logout');
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleLock': function (anEvent) {
+ return Clipperz.Async.callbacks("AppController.handleLock", [
+ MochiKit.Base.method(this.cardsController(), 'deleteAllCleanTextData'),
+ MochiKit.Base.method(this.user(), 'lock')
+ ], {trace:false});
+ },
+
+ //.............................................................................
+
+ 'handleUnlock': function (anEvent) {
+ return Clipperz.Async.callbacks("AppController.handleUnock", [
+ MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress'),
+ MochiKit.Base.method(this.user(), 'login'),
+ MochiKit.Base.method(this.cardsController(), 'focus'),
+ MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'progressDone'),
+ MochiKit.Base.method(this.userInfoBox(), 'unlock')
+ ], {trace:false});
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js
new file mode 100644
index 0000000..2340aeb
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js
@@ -0,0 +1,652 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.CardDialogController = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Controllers.CardDialogController.superclass.constructor.call(this, args);
+
+ this._record = args.record || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._delegate = args.delegate || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._referenceElement = null;
+ this._cardDialogComponent = null;
+
+ this._fieldsReferences = {};
+ this._directLoginReferences = {};
+
+ this._directLoginWizardController = null;
+ this._directLoginEditingComponent = null;
+ this._isDirectLoginEditingComponentVisible = false;
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.CardDialogController, Object, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.CardDialogController";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'record': function () {
+ return this._record;
+ },
+
+ 'delegate': function () {
+ return this._delegate;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fieldsReferences': function () {
+ return this._fieldsReferences;
+ },
+
+ 'directLoginReferences': function () {
+ return this._directLoginReferences;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'referenceElement': function () {
+ return this._referenceElement;
+ },
+
+ 'setReferenceElement': function (anElement) {
+ this._referenceElement = anElement;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'cardDialogComponent': function () {
+ if (this._cardDialogComponent == null) {
+ this._cardDialogComponent = new Clipperz.PM.UI.Web.Components.CardDialogComponent();
+
+ MochiKit.Signal.connect(this._cardDialogComponent, 'cancel', this, 'handleCancel');
+ MochiKit.Signal.connect(this._cardDialogComponent, 'save', this, 'handleSave');
+
+ MochiKit.Signal.connect(this._cardDialogComponent, 'addField', this, 'handleAddField');
+ MochiKit.Signal.connect(this._cardDialogComponent, 'changedValue', this, 'handleChangedValue');
+
+ MochiKit.Signal.connect(this._cardDialogComponent, 'addDirectLogin',this, 'handleAddDirectLogin');
+ MochiKit.Signal.connect(this._cardDialogComponent, 'keyPressed', this, 'handleCardDialogComponentKeyPressed');
+ }
+
+ return this._cardDialogComponent;
+ },
+
+ //=========================================================================
+
+ 'directLoginWizardController': function () {
+ if (this._directLoginWizardController == null) {
+ this._directLoginWizardController = new Clipperz.PM.UI.Web.Controllers.DirectLoginWizardController({
+ 'cardLabel': this.cardDialogComponent().title(),
+ 'directLoginEditingComponent': this.directLoginEditingComponent()
+ })
+
+ MochiKit.Signal.connect(this._directLoginWizardController, 'exit', this, 'handleHideDirectLoginEditingComponent');
+ MochiKit.Signal.connect(this._directLoginWizardController, 'done', this, 'handleCompleteDirectLoginEditingComponent');
+ }
+
+ return this._directLoginWizardController;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLoginEditingComponent': function () {
+ if (this._directLoginEditingComponent == null) {
+ this._directLoginEditingComponent = new Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent();
+
+ this.cardDialogComponent().renderDirectLoginEditingComponent(this._directLoginEditingComponent);
+
+// MochiKit.Signal.connect(this._directLoginEditingComponent, 'back', this, 'handleHideDirectLoginEditingComponent')
+// MochiKit.Signal.connect(this._directLoginEditingComponent, 'changedValue', this, 'handleChangedValue');
+// MochiKit.Signal.connect(this.__directLoginEditingComponent, 'keyPressed', this, 'handleDirectLoginEditingComponentKeyPressed');
+ }
+
+ return this._directLoginEditingComponent;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isDirectLoginEditingComponentVisible': function () {
+ return this._isDirectLoginEditingComponentVisible;
+ },
+
+ 'setIsDirectLoginEditingComponentVisible': function (aValue) {
+ this._isDirectLoginEditingComponentVisible = aValue;
+ },
+
+ //=========================================================================
+
+ 'run': function (anElement) {
+ var deferredResult;
+
+ this.setReferenceElement(anElement);
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogController.run", {trace:false});
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':11});
+
+ deferredResult.addMethod(this.cardDialogComponent(), 'deferredShowModal', {openFromElement:this.referenceElement()});
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+
+ deferredResult.addMethod(this.record(), 'label');
+ deferredResult.addMethod(this.cardDialogComponent(), 'setTitle');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+
+ deferredResult.addMethod(this, 'updateComponentState');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'progressDone');
+
+ deferredResult.addMethod(this.cardDialogComponent(), 'fixRendering');
+ deferredResult.addMethod(this.cardDialogComponent(), 'hideProgressMask');
+
+ if (this.record().isBrandNew()) {
+ deferredResult.addMethod(this.cardDialogComponent(), 'setHintMode', 'ON');
+ deferredResult.addMethod(this.cardDialogComponent(), 'setFocusOnTitleField');
+ }
+
+ deferredResult.addErrback(MochiKit.Base.method(this.cardDialogComponent(), 'showError'));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'updateComponentState': function () {
+ return Clipperz.Async.callbacks("CardDialogController.updateComponentState", [
+ MochiKit.Base.method(this.record(), 'hasPendingChanges'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'setShouldEnableSaving'),
+
+ MochiKit.Base.method(this.record(), 'label'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'setTitle'),
+ MochiKit.Base.method(this.record(), 'notes'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'setNotes'),
+
+ MochiKit.Base.method(this.record(), 'fields'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addCardDialogComponentWithField')),
+
+ MochiKit.Base.method(this.record(), 'directLogins'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addCardDialogComponentWithDirectLogin')),
+
+ MochiKit.Base.method(this.cardDialogComponent(), 'resetNewFieldInputs'),
+ MochiKit.Base.noop
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addCardDialogComponentWithField': function (aField) {
+ var fieldComponent;
+
+ fieldComponent = new Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent({reference: aField.reference()});
+ MochiKit.Signal.connect(fieldComponent, 'changedValue', this, 'handleChangedValue');
+ MochiKit.Signal.connect(fieldComponent, 'performAction',this, 'handlePerformFieldAction');
+ MochiKit.Signal.connect(fieldComponent, 'deleteField', this, 'handleDeleteField');
+
+// this.fieldsReferences().push({'field':aField, 'component':fieldComponent});
+ this.fieldsReferences()[aField.reference()] = {'field':aField, 'component':fieldComponent};
+
+ return Clipperz.Async.callbacks("CardDialogController.addCardDialogComponentWithField", [
+ MochiKit.Base.method(this.cardDialogComponent(), 'addFieldRowComponent', fieldComponent),
+
+ MochiKit.Base.method(aField, 'label'),
+ MochiKit.Base.method(fieldComponent, 'setLabel'),
+ MochiKit.Base.method(aField, 'value'),
+ MochiKit.Base.method(fieldComponent, 'setValue'),
+ MochiKit.Base.method(aField, 'actionType'),
+ MochiKit.Base.method(fieldComponent, 'setActionType'),
+ MochiKit.Base.method(aField, 'isHidden'),
+ MochiKit.Base.method(fieldComponent, 'setIsHidden')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addCardDialogComponentWithDirectLogin': function (aDirectLogin) {
+ var directLoginComponent;
+
+ directLoginComponent = new Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent({reference: aDirectLogin.reference()});
+ MochiKit.Signal.connect(directLoginComponent, 'changedValue', this, 'handleChangedValue');
+ MochiKit.Signal.connect(directLoginComponent, 'deleteDirectLogin', this, 'handleDeleteDirectLogin');
+ MochiKit.Signal.connect(directLoginComponent, 'editDirectLogin', this, 'handleEditDirectLogin');
+ MochiKit.Signal.connect(directLoginComponent, 'openDirectLogin', this, 'handleOpenDirectLogin');
+
+ this.directLoginReferences()[aDirectLogin.reference()] = {'directLogin':aDirectLogin, 'component':directLoginComponent};
+
+ return Clipperz.Async.callbacks("CardDialogController.addCardDialogComponentWithDirectLogin", [
+ MochiKit.Base.method(this.cardDialogComponent(), 'addDirectLoginComponent', directLoginComponent),
+ MochiKit.Base.method(this, 'refreshDirectLoginComponent', this.directLoginReferences()[aDirectLogin.reference()])
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'refreshDirectLoginComponent': function (aDirectLoginReference) {
+ return Clipperz.Async.callbacks("CardDialogController.refreshDirectLoginComponent", [
+ MochiKit.Base.method(aDirectLoginReference['directLogin'], 'favicon'),
+// MochiKit.Base.method(aDirectLoginReference['directLogin'], 'faviconData'),
+ MochiKit.Base.method(aDirectLoginReference['component'], 'setFavicon'),
+ MochiKit.Base.method(aDirectLoginReference['directLogin'], 'label'),
+ MochiKit.Base.method(aDirectLoginReference['component'], 'setLabel')
+ ], {trace:false});
+ },
+
+ 'refreshDirectLoginComponents': function () {
+ return Clipperz.Async.callbacks("CardDialogController.refreshDirectLoginComponents", [
+ MochiKit.Base.method(this, 'directLoginReferences'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'refreshDirectLoginComponent')),
+ Clipperz.Async.collectAll
+ ])
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordValues': function () {
+ return Clipperz.Async.callbacks('CardDialogController.updateRecordValues', [
+ MochiKit.Base.method(this.cardDialogComponent(), 'title'),
+ MochiKit.Base.method(this.record(), 'setLabel'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'notes'),
+ MochiKit.Base.method(this.record(), 'setNotes'),
+
+ MochiKit.Base.method(this, 'fieldsReferences'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'updateRecordFieldValues')),
+
+ MochiKit.Base.method(this, 'directLoginReferences'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'updateRecordDirectLoginValues')),
+
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'directLoginReference'),
+ MochiKit.Base.method(this.record(), 'directLoginWithReference'),
+ MochiKit.Base.method(this, 'updateRecordDirectLoginDetails'),
+
+ MochiKit.Base.noop
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordFieldValues': function (aFieldReference) {
+ var deferredResult;
+
+ deferredResult = Clipperz.Async.callbacks('CardDialogController.updateRecordFieldValues', [
+ MochiKit.Base.method(aFieldReference['component'], 'label'),
+ MochiKit.Base.method(aFieldReference['field'], 'setLabel'),
+
+ MochiKit.Base.method(aFieldReference['component'], 'value'),
+ MochiKit.Base.method(aFieldReference['field'], 'setValue'),
+
+ MochiKit.Base.method(aFieldReference['component'], 'isHidden'),
+ MochiKit.Base.method(aFieldReference['field'], 'setIsHidden'),
+
+ MochiKit.Base.method(aFieldReference['field'], 'actionType'),
+ MochiKit.Base.method(aFieldReference['component'], 'setActionType')
+ ], {trace:false});
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordDirectLoginValues': function (aDirectLoginReference) {
+ var deferredResult;
+
+ deferredResult = Clipperz.Async.callbacks('CardDialogController.updateRecordDirectLoginValues', [
+ MochiKit.Base.method(aDirectLoginReference['component'], 'label'),
+ MochiKit.Base.method(aDirectLoginReference['directLogin'], 'setLabel')
+ ], {trace:false});
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordDirectLoginDetails': function (aDirectLogin) {
+ var result;
+
+ if (MochiKit.Base.isUndefinedOrNull(aDirectLogin)) {
+ result = MochiKit.Async.succeed();
+ } else {
+ result = Clipperz.Async.callbacks("CardDialogController.updateRecordDirectLoginDetails", [
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'label'),
+ MochiKit.Base.method(aDirectLogin, 'setLabel'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'favicon'),
+ MochiKit.Base.method(aDirectLogin, 'setFavicon')
+ ], {trace:false});
+ }
+
+ return result;
+ },
+
+ //=========================================================================
+
+ 'addField': function () {
+ return this.record().addField({
+ 'label':this.cardDialogComponent().newFieldLabel(),
+ 'value':this.cardDialogComponent().newFieldValue(),
+ 'isHidden':this.cardDialogComponent().newFieldIsHidden()
+ });
+ },
+
+ 'handleAddField': function () {
+ return Clipperz.Async.callbacks("CardDialogController.handleAddField", [
+ MochiKit.Base.method(this, 'addField'),
+
+ MochiKit.Base.method(this, 'addCardDialogComponentWithField'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'resetNewFieldInputs'),
+
+ MochiKit.Base.method(this.cardDialogComponent(), 'fixRendering'),
+ MochiKit.Base.method(this, 'handleChangedValue')
+ ], {trace:false})
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handlePerformFieldAction': function (aFieldID, aTargetElement) {
+//console.log("### targetElement", aTargetElement);
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteField", [
+ MochiKit.Base.method(this.record(), 'fields'),
+ MochiKit.Base.itemgetter(aFieldID),
+ Clipperz.Async.collectResults("CardDialogController.handleDeleteField <collect results>", {
+ 'value': MochiKit.Base.methodcaller('value'),
+ 'type': MochiKit.Base.methodcaller('actionType')
+ }, {trace:false}),
+ MochiKit.Base.bind(function (someValues) {
+ switch (someValues['type']) {
+ case 'NONE':
+ throw "this event handler should not be triggered for fields with type 'NONE'";
+ break;
+ case 'URL':
+ var url;
+
+ url = someValues['value'];
+ if (/^https?\:\/\//.test(url) == false) {
+ url = 'http://' + url;
+ }
+
+ window.open(url);
+ break;
+ case 'EMAIL':
+ var url;
+
+ url = 'mailto:' + someValues['value'];
+
+ MochiKit.DOM.currentWindow().location = url;
+ break;
+ case 'PASSWORD':
+//Clipperz.log("SHOW PASSWORD " + someValues['value']);
+ this.showPasswordTooltip(someValues['value'], aTargetElement);
+ break;
+ }
+ }, this)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleDeleteField': function (aFieldID) {
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteField", [
+ MochiKit.Base.method(this.record(), 'fields'),
+ MochiKit.Base.itemgetter(aFieldID),
+ MochiKit.Base.method(this.record(), 'removeField'),
+
+ MochiKit.Base.method(this, 'fieldsReferences'),
+ MochiKit.Base.itemgetter(aFieldID),
+ MochiKit.Base.itemgetter('component'),
+
+ function (aComponent) {
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteField [fade and remove]", [
+ MochiKit.Base.partial(Clipperz.Visual.deferredAnimation, MochiKit.Visual.fade, aComponent.element(), {from:1.0, to:0.0, duration:0.5}),
+// Clipperz.Visual.deferredAnimation(MochiKit.Visual.fade, aComponent.element(), {from:1.0, to:0.0, duration:0.5}),
+ MochiKit.Base.method(aComponent, 'remove')
+ ], {trace:false});
+ },
+
+ MochiKit.Base.bind(function () {
+ delete this.fieldsReferences()[aFieldID];
+ }, this),
+
+ MochiKit.Base.method(this.cardDialogComponent(), 'fixRendering'),
+ MochiKit.Base.method(this, 'handleChangedValue')
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'handleDeleteDirectLogin': function(aDirectLoginReference) {
+ var cardDialogComponent;
+
+ cardDialogComponent = this.cardDialogComponent();
+
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteDirectLogin", [
+ MochiKit.Base.method(this.record(), 'directLogins'),
+ MochiKit.Base.itemgetter(aDirectLoginReference),
+ MochiKit.Base.methodcaller('remove'),
+
+ MochiKit.Base.method(this, 'directLoginReferences'),
+ MochiKit.Base.itemgetter(aDirectLoginReference),
+ MochiKit.Base.itemgetter('component'),
+
+ function (aComponent) {
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteDirectLogin [fade and remove]", [
+ MochiKit.Base.partial(Clipperz.Visual.deferredAnimation, MochiKit.Visual.fade, aComponent.element(), {from:1.0, to:0.0, duration:0.5}),// Clipperz.Visual.deferredAnimation(MochiKit.Visual.fade, aComponent.element(), {from:1.0, to:0.0, duration:0.5}),
+/// MochiKit.Base.method(aComponent, 'remove')
+ MochiKit.Base.method(cardDialogComponent, 'removeDirectLoginComponent', aComponent)
+ ], {trace:false});
+ },
+
+ MochiKit.Base.bind(function () {
+ delete this.directLoginReferences()[aDirectLoginReference];
+ }, this),
+
+ MochiKit.Base.method(this.cardDialogComponent(), 'fixRendering'),
+ MochiKit.Base.method(this, 'handleChangedValue')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleOpenDirectLogin': function (aDirectLoginReference) {
+ return Clipperz.Async.callbacks("CardDialogController.handleOpenDirectLogin", [
+ MochiKit.Base.method(this.record(), 'directLoginWithReference', aDirectLoginReference),
+ Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.openDirectLogin
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleEditDirectLogin': function (aDirectLoginReference) {
+ return Clipperz.Async.callbacks("CardDialogController.handleEditDirectLogin", [
+ MochiKit.Base.method(this, 'setIsDirectLoginEditingComponentVisible', true),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginReference', aDirectLoginReference),
+ MochiKit.Base.method(this.cardDialogComponent(), 'placeDirectLoginEditingComponent'),
+ MochiKit.Base.method(this.record(), 'directLoginWithReference', aDirectLoginReference),
+ MochiKit.Base.method(this.directLoginWizardController(), 'runWithDirectLogin'),
+ MochiKit.Base.method(this.directLoginWizardController(), 'fixRulerRendering', this.cardDialogComponent().displayMode()),
+ MochiKit.Base.method(this.cardDialogComponent(), 'showDirectLoginEditingComponent')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleHideDirectLoginEditingComponent': function () {
+ return Clipperz.Async.callbacks("CardDialogController.handleHideDirectLoginEditingComponent", [
+ MochiKit.Base.method(this, 'setIsDirectLoginEditingComponentVisible', false),
+ MochiKit.Base.method(this.directLoginWizardController(), 'hideRuler'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginReference', null),
+ MochiKit.Base.method(this, 'refreshDirectLoginComponents'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'hideDirectLoginEditingComponent')
+ ], {trace:false})
+ },
+
+ 'handleCompleteDirectLoginEditingComponent': function (someParameters) {
+ return Clipperz.Async.callbacks("CardDialogController.handleCompleteDirectLoginEditingComponent", [
+ MochiKit.Base.method(this, 'setIsDirectLoginEditingComponentVisible', false),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginReference', null),
+ MochiKit.Base.partial(MochiKit.Async.succeed, someParameters['hasJustBeenAdded']),
+ Clipperz.Async.deferredIf("CardDialogController.handleCompleteDirectLoginEditingComponent - should addTheEditedDirectLogin", [
+ MochiKit.Base.method(this, 'addCardDialogComponentWithDirectLogin', someParameters['directLogin'])
+ ], []),
+ MochiKit.Base.method(this, 'refreshDirectLoginComponents'),
+ MochiKit.Base.method(this, 'handleChangedValue'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'hideDirectLoginEditingComponent')
+ ], {trace:false})
+ },
+
+ //=========================================================================
+
+ 'handleChangedValue': function () {
+ return Clipperz.Async.callbacks("CardDialogController.handleChangedValue", [
+ MochiKit.Base.method(this, 'updateRecordValues'),
+ MochiKit.Base.method(this.record(), 'hasPendingChanges'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'setShouldEnableSaving')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleSave': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogController.handleSave", {trace:false});
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':8});
+ deferredResult.addMethod(this.cardDialogComponent(), 'showProgressMask');
+ deferredResult.addMethod(this.cardDialogComponent(), 'newFieldHasPendingChanges');
+ deferredResult.addIf([
+ MochiKit.Base.method(this, 'addField')
+ ], [])
+ deferredResult.addMethod(this, 'saveChanges');
+ deferredResult.addMethod(this.cardDialogComponent(), 'deferredHideModal', {closeToElement:null});
+ deferredResult.addMethod(this.cardDialogComponent(), 'remove');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'cardDialogComponentClosed');
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'saveChanges': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogController.handleSave", {trace:false});
+ deferredResult.addMethod(this.delegate(), 'saveChanges');
+deferredResult.addErrback(function (aValue) { Clipperz.log("SHIT HAPPENS!!"); return aValue; });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleCancel': function () {
+ var deferredResult;
+
+ if (this.isDirectLoginEditingComponentVisible()) {
+ deferredResult = this.handleHideDirectLoginEditingComponent();
+ } else {
+ deferredResult = new Clipperz.Async.Deferred("CardDialogController.handleCancel", {trace:false});
+ // deferredResult.addMethod(this.record(), 'hasPendingChanges'),
+ deferredResult.addMethod(this.delegate(), 'hasPendingChanges'),
+ deferredResult.addIf([
+ MochiKit.Base.method(this.cardDialogComponent(), 'askConfirmationForLoosingPendingChanges')
+ ], [])
+ deferredResult.addMethod(this.delegate(), 'revertChanges');
+ deferredResult.addMethod(this.cardDialogComponent(), 'deferredHideModal', {closeToElement:this.referenceElement()});
+ deferredResult.addMethod(this.cardDialogComponent(), 'remove');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'cardDialogComponentClosed');
+
+ deferredResult.callback();
+ }
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleAddDirectLogin': function () {
+ return Clipperz.Async.callbacks("CardDialogController.handleAddDirectLogin", [
+ MochiKit.Base.method(this.record(), 'createNewDirectLogin'),
+ MochiKit.Base.bind(function (aDirectLogin) {
+ return Clipperz.Async.callbacks("CardDialogController.handleAddDirectLogin - directLogin", [
+ MochiKit.Base.method(this.cardDialogComponent(), 'newFieldHasPendingChanges'),
+ Clipperz.Async.deferredIf("cardDialogComponent.newFieldHasPendingChanges", [
+ MochiKit.Base.method(this, 'handleAddField')
+ ], []),
+
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginReference', aDirectLogin.reference()),
+ MochiKit.Base.method(this.cardDialogComponent(), 'placeDirectLoginEditingComponent'),
+ MochiKit.Base.method(this.directLoginWizardController(), 'runWithDirectLogin', aDirectLogin, true),
+ MochiKit.Base.method(this.directLoginWizardController(), 'fixRulerRendering', this.cardDialogComponent().displayMode()),
+ MochiKit.Base.method(this.cardDialogComponent(), 'showDirectLoginEditingComponent')
+ ], {trace:false});
+ }, this)
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'handleCardDialogComponentKeyPressed': function (anEvent) {
+ if ((anEvent.key().string == 'KEY_TAB') && this.cardDialogComponent().newFieldHasPendingChanges()) {
+ anEvent.preventDefault();
+
+// MochiKit.Signal.signal(this.cardDialogComponent(), 'addField');
+ this.handleAddField()
+ this.cardDialogComponent().focusOnNewFieldLabel();
+ }
+ },
+
+ //=========================================================================
+
+ 'showPasswordTooltip': function (aValue, anElement) {
+ var passwordTooltip;
+
+ passwordTooltip = new Clipperz.PM.UI.Web.Components.PasswordTooltip({
+ 'referebceElement': anElement,
+ 'text': aValue
+ });
+
+ passwordTooltip.show();
+
+
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardsController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardsController.js
new file mode 100644
index 0000000..b1a34b2
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardsController.js
@@ -0,0 +1,207 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.CardsController = function() {
+ Clipperz.PM.UI.Web.Controllers.CardsController.superclass.constructor.apply(this, arguments);
+
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'cardDialogComponentClosed', this, 'handleHideCard');
+
+ return this;
+}
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.CardsController, Clipperz.PM.UI.Web.Controllers.GridController, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.CardsController";
+ },
+
+ 'createGrid': function () {
+ var grid;
+
+ grid = new Clipperz.PM.UI.Web.Components.GridComponent({columnsManagers: [
+ new Clipperz.PM.UI.Web.Components.FaviconColumnManager({
+ 'name': 'Cards.favicon',
+ 'selector': MochiKit.Base.methodcaller('favicon'),
+ 'cssClass': 'favicon'
+ }),
+ new Clipperz.PM.UI.Web.Components.LinkColumnManager({
+ 'name': 'Cards.title',
+ 'selector': MochiKit.Base.methodcaller('label'),
+ 'label': 'title',
+ 'cssClass': 'title',
+ 'comparator': Clipperz.Base.caseInsensitiveCompare,
+ 'sortable': true,
+ 'sorted': 'ASCENDING',
+// 'actionMethod': function(anObject, anEvent) { MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'editCard', {objectData:anObject, element:anEvent.src()})}
+ 'actionMethod': MochiKit.Base.method(this, 'handleShowCard')
+ }),
+ new Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager({
+ 'name': 'Cards.directLogins',
+ 'selector': MochiKit.Base.methodcaller('directLoginReferences'),
+ 'label': 'direct logins',
+ 'cssClass': 'directLogin'
+ }),
+ new Clipperz.PM.UI.Web.Components.DateColumnManager({
+ 'name': 'Cards.latestUpdate',
+ 'selector': MochiKit.Base.methodcaller('updateDate'),
+ 'label': 'latest update',
+ 'cssClass': 'latestUpdate',
+ 'format': 'd-m-Y',
+ 'comparator': MochiKit.Base.compare,
+ 'sortable': true,
+ 'sorted': 'UNSORTED'
+ }),
+ new Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager({
+ 'name': 'Cards.delete',
+ 'selector': MochiKit.Base.noop,
+ 'cssClass': 'delete',
+// 'actionMethod': function(anObject, anEvent) { MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'deleteCard', {objectData:anObject, element:anEvent.src()})}
+ 'actionMethod': MochiKit.Base.method(this, 'handleDeleteCard')
+ })
+ ]});
+
+ grid.setComponentForSlotNamed(new Clipperz.PM.UI.Web.Components.BookmarkletComponent(), 'headerSlot');
+
+ return grid;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getRows': function () {
+ //TODO relying on user() in GridController, bad code smell :|
+ return this.user().getRecords();
+ },
+
+ //=============================================================================
+
+ 'displayEmptyContent': function () {
+ var emptyGridComponent;
+
+ emptyGridComponent = new Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent();
+
+ return Clipperz.Async.callbacks("CardsController.displayEmptyContent", [
+ MochiKit.Base.method(this.grid(), 'setNoRowsGridComponent', emptyGridComponent),
+ MochiKit.Base.bind(Clipperz.PM.UI.Web.Controllers.CardsController.superclass.displayEmptyContent, this)
+ ], {trace:false});
+ },
+
+ 'displaySelectedRows': function (aFilter) {
+ this.columnManagerWithName('Cards.directLogins').hideDirectLoginListPopup();
+
+ return Clipperz.PM.UI.Web.Controllers.CardsController.superclass.displaySelectedRows.apply(this, arguments);
+ },
+
+ //=============================================================================
+
+ 'handleShowCard': function (anObject, anEvent) {
+ var cardDialogController;
+
+ cardDialogController = new Clipperz.PM.UI.Web.Controllers.CardDialogController({record:anObject, delegate:this});
+ this.grid().selectRow(anObject);
+
+ cardDialogController.run(anEvent.src());
+ },
+
+ //.........................................................................
+
+ 'handleHideCard': function () {
+ this.focus();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'addCard': function (aSourceElement) {
+ return Clipperz.Async.callbacks("CardsController.addCard", [
+ Clipperz.Async.collectResults("CardsController.addCard <inner results>", {
+ 'record': MochiKit.Base.method(this.user(), 'createNewRecord'),
+ 'delegate': MochiKit.Base.partial(MochiKit.Async.succeed, this)
+ }, {trace:false}),
+ function (someParameters) {
+ return new Clipperz.PM.UI.Web.Controllers.CardDialogController(someParameters);
+ },
+ MochiKit.Base.methodcaller('run', aSourceElement)
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleDeleteCard': function (anObject, anEvent) {
+ var deferredResult;
+ var confirmationDialog;
+
+// confirmationDialog = new Clipperz.PM.UI.Common.Components.SimpleMessagePanel({
+ confirmationDialog = new Clipperz.PM.UI.Common.Components.MessagePanelWithProgressBar({
+ 'title': "Delete Card",
+ 'text': "Do you want to delete …",
+ 'type': 'ALERT',
+ 'buttons': [
+ {text:"Cancel", result:'CANCEL'},
+ {text:"Delete", result:'OK', isDefault:true}
+ ],
+ 'canCancelWhileProcessing': false
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.handleDeleteCard", {trace:false});
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':5}),
+ deferredResult.addMethod(this.grid(), 'selectRow', anObject);
+ deferredResult.addMethod(confirmationDialog, 'deferredShowModal', {
+ 'openFromElement': anEvent.src(),
+ 'onOkCloseToElement': null, // MochiKit.DOM.currentDocument().body,
+ 'onCancelCloseToElement': anEvent.src()
+ });
+// deferredResult.addCallback(function () { Clipperz.log("DELETE: " + anObject.toString(), anObject); });
+ deferredResult.addMethod(this.user(), 'deleteRecord', anObject);
+ deferredResult.addBothPass(MochiKit.Base.method(this.grid(), 'unselectRow', anObject));
+ deferredResult.addMethod(this, 'saveChanges');
+ deferredResult.addMethod(confirmationDialog, 'deferredDone');
+ deferredResult.addErrbackPass(function (anError) {
+ var result;
+
+ if (! (anError instanceof MochiKit.Async.CancelledError)) {
+ result = confirmationDialog.deferredError({
+ 'type': 'ALERT',
+ 'title': "Error",
+ 'text': Clipperz.PM.Strings.errorDescriptionForException(anError),
+ 'buttons': [{text:"Close", result:'CANCEL', isDefault:true}]
+ })
+ } else {
+ result = anError;
+ }
+
+ return result;
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js
new file mode 100644
index 0000000..38fdc08
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js
@@ -0,0 +1,611 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.DirectLoginWizardController = function(args) {
+ this._directLoginEditingComponent = args.directLoginEditingComponent || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._cardLabel = args.cardLabel || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ MochiKit.Signal.connect(this._directLoginEditingComponent, 'changedValue', this, 'handleChangedValue');
+ MochiKit.Signal.connect(this._directLoginEditingComponent, 'moveForward', this, 'handleMoveForward');
+ MochiKit.Signal.connect(this._directLoginEditingComponent, 'keyPressed', this, 'handleDirectLoginEditingComponentKeyPressed');
+
+ this._directLogin = null;
+ this._directLoginHasJustBeenAdded = false;
+
+ this._rulerComponent = null;
+
+ this._steps = null;
+ this._currentStepIndex = 0;
+ this._isNextEnabled = false;
+
+ this._recordFields = null;
+ this._originalBindings = null;
+
+ this._bindingComponents = [];
+ this._formValueComponents = [];
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.DirectLoginWizardController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.DirectLoginWizardController";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLogin': function () {
+ return this._directLogin;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLoginHasJustBeenAdded': function () {
+ return this._directLoginHasJustBeenAdded;
+ },
+
+ 'setDirectLoginHasJustBeenAdded': function (aValue) {
+ this._directLoginHasJustBeenAdded = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLoginEditingComponent': function () {
+ return this._directLoginEditingComponent;
+ },
+
+ //=============================================================================
+
+ 'cardLabel': function () {
+ return this._cardLabel;
+ },
+
+ //=============================================================================
+
+ 'resetCurrentStepIndex': function () {
+ this._currentStepIndex = 0;
+ this.rulerComponent().resetStatus();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'enableNext': function (aValue) {
+ this.rulerComponent().enableNext(aValue);
+ this._isNextEnabled = aValue;
+ },
+
+ 'isNextEnabled': function () {
+ return this._isNextEnabled;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'enablePrevious': function (aValue) {
+ this.rulerComponent().enablePrevious(aValue);
+ },
+
+ //=============================================================================
+
+ 'bindingComponents': function () {
+ return this._bindingComponents;
+ },
+
+ 'resetBindingComponents': function () {
+ this.directLoginEditingComponent().clearAllBindingsComponents();
+ this._bindingComponents = [];
+ },
+
+ //=============================================================================
+
+ 'formValueComponents': function () {
+ return this._formValueComponents;
+ },
+
+ 'resetFormValueComponents': function () {
+ this.directLoginEditingComponent().clearAllFormValueComponents();
+ this._formValueComponents = [];
+ },
+
+ //=============================================================================
+
+ 'recordFields': function () {
+ return this._recordFields;
+ },
+
+ 'setRecordFields': function (aValue) {
+ this._recordFields = aValue;
+ },
+
+ 'recordFieldWithReference': function (aReference) {
+ var matchingValues;
+ var result;
+
+ matchingValues = MochiKit.Base.filter(function (aField) { return aField['reference'] == aReference; }, this.recordFields());
+
+ if (matchingValues.length == 0) {
+ result = null;
+ } else {
+ result = matchingValues[0];
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'originalBindings': function () {
+ return this._originalBindings;
+ },
+
+ 'setOriginalBindings': function (aValue) {
+//console.log("BINDINGS", aValue);
+ this._originalBindings = aValue;
+ },
+
+ //=============================================================================
+
+ 'rulerComponent': function () {
+ if (this._rulerComponent == null) {
+ this._rulerComponent = new Clipperz.PM.UI.Web.Components.RulerComponent({
+ translationContext:'Wizards.DirectLoginWizard'
+ });
+ this._rulerComponent.render();
+
+ MochiKit.Signal.connect(this._rulerComponent, 'exit', this, 'handleExit');
+ MochiKit.Signal.connect(this._rulerComponent, 'done', this, 'done');
+ MochiKit.Signal.connect(this._rulerComponent, 'moveForward', this, 'handleMoveForward');
+ MochiKit.Signal.connect(this._rulerComponent, 'moveBackward', this, 'handleMoveBackward');
+ MochiKit.Signal.connect(this._rulerComponent, 'cursorMoved', this, 'handleCursorMoved');
+ }
+
+ return this._rulerComponent;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'showRuler': function (someSteps) {
+ var rulerElement;
+
+ this.setSteps(someSteps);
+
+ rulerElement = this.rulerComponent().element();
+ this.directLoginEditingComponent().disableAllPanels();
+
+ MochiKit.Style.showElement(rulerElement);
+ MochiKit.Style.setElementPosition(rulerElement, {x:-1000, y:this.directLoginEditingComponent().bottomMargin()});
+ new MochiKit.Visual.Move(rulerElement, {
+ x:0, y:this.directLoginEditingComponent().bottomMargin(),
+ mode:'absolute',
+ duration:1,
+ afterFinish:MochiKit.Base.method(this, 'handleCursorMoved')
+ });
+ },
+
+ 'fixRulerRendering': function (aValue) {
+ this.rulerComponent().setDisplayMode(aValue);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hideRuler': function () {
+ new MochiKit.Visual.Move(this.rulerComponent().element(), {x:-1000, mode:'relative', duration:1});
+ },
+
+ 'doneWithRuler': function () {
+ var rulerComponentElement;
+
+ rulerComponentElement = this.rulerComponent().element();
+ new MochiKit.Visual.Move(this.rulerComponent().element(), {
+ x:1000,
+ mode:'relative',
+ duration:1,
+// afterFinish:MochiKit.Base.partial(MochiKit.Style.hideElement, rulerComponentElement)
+ afterFinish:function () { MochiKit.Style.hideElement(rulerComponentElement); }
+ });
+ },
+
+ //=============================================================================
+
+ 'addNewDirectLoginRulerSteps': function () {
+ return MochiKit.Base.concat([ 'LABEL'], this.editDirectLoginRulerSteps());
+
+ },
+
+ 'editDirectLoginRulerSteps': function () {
+ return [ /*'TYPE',*/ 'CONFIGURATION', 'BINDINGS','FAVICON', 'DONE'];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'runWithDirectLogin': function (aDirectLogin, hasJustBeenAdded) {
+ this._directLogin = aDirectLogin;
+ this.setDirectLoginHasJustBeenAdded(hasJustBeenAdded);
+
+ return Clipperz.Async.callbacks("DirectLoginWizardController.runWithDirectLogin", [
+ MochiKit.Base.method(aDirectLogin, 'label'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setLabel'),
+
+ MochiKit.Base.method(aDirectLogin, 'favicon'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginFavicon'),
+
+ MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setBookmarkletConfiguration'),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.method(this, 'setOriginalBindings'),
+
+ MochiKit.Base.method(aDirectLogin, 'record'),
+ MochiKit.Base.methodcaller('fields'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, Clipperz.Async.collectResults("Record.directLoginReferences - collectResults", {
+ 'reference': MochiKit.Base.methodcaller('reference'),
+ 'label': MochiKit.Base.methodcaller('label'),
+ 'isHidden': MochiKit.Base.methodcaller('isHidden'),
+ 'value': MochiKit.Base.methodcaller('value')
+ }, {trace:false})),
+ Clipperz.Async.collectAll,
+
+ MochiKit.Base.method(this, 'setRecordFields'),
+
+ MochiKit.Base.partial(MochiKit.Async.succeed, hasJustBeenAdded),
+ Clipperz.Async.deferredIf("Direct login has just been added", [
+ MochiKit.Base.method(this, 'addNewDirectLoginRulerSteps')
+ ], [
+ MochiKit.Base.method(this, 'editDirectLoginRulerSteps')
+ ]),
+ MochiKit.Base.method(this, 'showRuler')
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'checkState': function () {
+ var enablePrevious;
+ var enableNext;
+
+ enablePrevious = true;
+ enableNext = false;
+
+ this.directLoginEditingComponent().disableAllPanels();
+
+ switch(this.currentStep()) {
+ case 'LABEL':
+ this.directLoginEditingComponent().enableLabelField();
+
+ enableNext = (this.directLoginEditingComponent().label() != '');
+ enablePrevious = false;
+ break;
+ case 'TYPE':
+ this.directLoginEditingComponent().enableTypeField();
+
+ enableNext = true;
+ enablePrevious = true;
+ break
+ case 'CONFIGURATION':
+ this.directLoginEditingComponent().enableConfigurationField();
+
+ enableNext = (this.directLoginEditingComponent().bookmarkletConfiguration() != '');
+
+ if (enableNext == true) {
+ try {
+ Clipperz.PM.DataModel.DirectLogin.checkBookmarkletConfiguration(this.directLoginEditingComponent().bookmarkletConfiguration());
+ this.directLoginEditingComponent().removeHighlightConfigurationSyntaxError();
+ } catch (e) {
+ this.directLoginEditingComponent().highlightConfigurationSyntaxError();
+ enableNext = false;
+ }
+ }
+ break;
+ case 'BINDINGS':
+ enableNext = MochiKit.Iter.every(this.bindingComponents(), function (aBindingComponent) { return aBindingComponent.selectedValue() != null; })
+ this.directLoginEditingComponent().enableBindingFields();
+ break;
+ case 'FAVICON':
+ enableNext = true;
+ this.directLoginEditingComponent().enableFaviconField();
+ break;
+ case 'DONE':
+ enableNext = true;
+ this.directLoginEditingComponent().enableDonePanel();
+ break;
+ }
+
+ if (this.currentStepIndex() > 0) {
+ this.enablePrevious(enablePrevious);
+ } else {
+ this.enablePrevious(false);
+ }
+ this.enableNext(enableNext);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setFocus': function () {
+ switch(this.currentStep()) {
+ case 'LABEL':
+ this.directLoginEditingComponent().focusOnLabelElement();
+ break;
+ case 'TYPE':
+ break;
+ case 'CONFIGURATION':
+ this.directLoginEditingComponent().focusOnBookmarkletConfigurationElement();
+ break;
+ case 'BINDINGS':
+// this.directLoginEditingComponent().getElement('???').focus();
+ break;
+ case 'FAVICON':
+ this.directLoginEditingComponent().focusOnFaviconElement();
+ break;
+ case 'DONE':
+ break;
+ }
+ },
+
+ //=============================================================================
+
+ 'steps': function () {
+ return this._steps;
+ },
+
+ 'setSteps': function (aValue) {
+ this._steps = aValue;
+
+ this.rulerComponent().setSteps(aValue);
+ this.resetCurrentStepIndex();
+ },
+
+ 'currentStepIndex': function () {
+ return this._currentStepIndex;
+ },
+
+ 'currentStep': function () {
+ return this.steps()[this.currentStepIndex()];
+ },
+
+ //=============================================================================
+
+ 'handleExit': function () {
+ MochiKit.Signal.signal(this, 'exit');
+ },
+
+ 'done': function () {
+ this.doneWithRuler();
+
+ Clipperz.Async.callbacks("DirectLoginWizardController.done", [
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'label'),
+ MochiKit.Base.method(this.directLogin(), 'setLabel'),
+
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'bookmarkletConfiguration'),
+ MochiKit.Base.method(this.directLogin(), 'setBookmarkletConfiguration'),
+
+ // Bindings
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'bindingComponents'),
+// MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.bind(function (aBindingComponent) {
+ Clipperz.Async.forEach(MochiKit.Base.bind(function (aBindingComponent) {
+//console.log("aBindingComponent", aBindingComponent);
+// this.directLogin().
+ return Clipperz.Async.callbacks("DirectLoginWizardController.done - update directLogin bindings", [
+ MochiKit.Base.method(this.directLogin(), 'bindings'),
+ MochiKit.Base.itemgetter(aBindingComponent.formFieldName()),
+ MochiKit.Base.methodcaller('setFieldKey', aBindingComponent.selectedValue())
+ ], {trace:false});
+ }, this)),
+
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'favicon'),
+ MochiKit.Base.method(this.directLogin(), 'setFavicon'),
+
+ MochiKit.Base.partial(MochiKit.Signal.signal, this, 'done', {
+ 'directLogin': this.directLogin(),
+ 'hasJustBeenAdded': this.directLoginHasJustBeenAdded()
+ })
+ ], {trace:false});
+ },
+
+ //=============================================================================
+
+ 'handleMoveBackward': function () {
+ if (this._currentStepIndex > 0) {
+ var afterMoveAction;
+
+ this._currentStepIndex --;
+ afterMoveAction = MochiKit.Base.noop;
+
+ switch(this.currentStep()) {
+ case 'LABEL':
+ break;
+ case 'TYPE':
+ break;
+ case 'CONFIGURATION':
+ break;
+ case 'BINDINGS':
+ break;
+ case 'FAVICON':
+ break;
+ case 'DONE':
+ break;
+ };
+
+ this.rulerComponent().moveBackward(afterMoveAction);
+ }
+
+ if (this._currentStepIndex == 0) {
+ this.enablePrevious(false);
+ }
+ },
+
+ 'handleMoveForward': function () {
+ if (this.isNextEnabled()) {
+ var afterMoveAction;
+
+ this._currentStepIndex ++;
+ afterMoveAction = MochiKit.Base.noop;
+
+ switch(this.currentStep()) {
+ case 'LABEL':
+ break;
+ case 'TYPE':
+ break;
+ case 'CONFIGURATION':
+ break;
+ case 'BINDINGS':
+ this.resetBindingComponents();
+ this.resetFormValueComponents();
+
+ afterMoveAction = MochiKit.Base.partial(Clipperz.Async.callbacks, "DirectLoginWizardController.handleMoveForward - BINDINGS", [
+ MochiKit.Base.method(this.directLogin(), 'setBookmarkletConfiguration', this.directLoginEditingComponent().bookmarkletConfiguration()),
+
+ MochiKit.Base.method(this.directLogin(), 'favicon'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginFavicon'),
+
+ MochiKit.Base.method(this.directLogin(), 'bindings'),
+ MochiKit.Base.values,
+ Clipperz.Async.forEach(MochiKit.Base.bind(function (aBinding) {
+ var bindingComponent;
+
+ bindingComponent = new Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent({
+ formFieldName: aBinding.key(),
+ fields: this.recordFields(),
+ selectedFieldKey: aBinding.fieldKey()
+ });
+
+ this.bindingComponents().push(bindingComponent);
+
+ MochiKit.Signal.connect(bindingComponent, 'bindChange', this, 'handleBindChange', bindingComponent);
+ this.directLoginEditingComponent().addBindingComponent(bindingComponent);
+
+ }, this)),
+
+ MochiKit.Base.method(this.directLogin(), 'formValues'),
+ MochiKit.Base.values,
+ Clipperz.Async.forEach(MochiKit.Base.bind(function (aFormValue) {
+ var formValueComponent;
+
+ formValueComponent = new Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent({
+ 'formFieldName': aFormValue.key(),
+ 'fieldOptions': aFormValue.fieldOptions(),
+ 'initialValue': aFormValue.value()
+ });
+
+ this.formValueComponents().push(formValueComponent);
+
+ MochiKit.Signal.connect(formValueComponent, 'formValueChange', this, 'handleFormValueChange', formValueComponent);
+ this.directLoginEditingComponent().addFormValueComponent(formValueComponent);
+ }, this))
+
+ ], {trace:false});
+
+ break;
+ case 'FAVICON':
+ break;
+ case 'DONE':
+ this.directLoginEditingComponent().setDoneDescriptionWithKeys({
+ '__cardName__': this.cardLabel(),
+ '__directLoginName__': this.directLoginEditingComponent().label()
+ });
+ break;
+ };
+
+ this.rulerComponent().moveForward(afterMoveAction);
+ };
+ },
+
+ 'handleCursorMoved': function () {
+ this.checkState();
+ this.setFocus();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleChangedValue': function (anEvent) {
+ this.checkState();
+ },
+
+ //.........................................................................
+
+ 'handleBindChange': function (aDirectLoginEditingBindingComponent) {
+ var selectedField;
+
+ selectedField = this.recordFieldWithReference(aDirectLoginEditingBindingComponent.selectedValue());
+
+ return Clipperz.Async.callbacks("DirectLoginWizardController.handleBindChange", [
+ MochiKit.Base.method(this.directLogin(), 'bindings'),
+ MochiKit.Base.itemgetter(aDirectLoginEditingBindingComponent.formFieldName()),
+ MochiKit.Base.methodcaller('setFieldKey', selectedField['reference']),
+ function () {
+ if (selectedField != null) {
+ aDirectLoginEditingBindingComponent.setFieldValue(selectedField['value']);
+ aDirectLoginEditingBindingComponent.setIsHidden(selectedField['isHidden']);
+ } else {
+ aDirectLoginEditingBindingComponent.setFieldValue('');
+ aDirectLoginEditingBindingComponent.setIsHidden(false);
+ }
+ },
+ MochiKit.Base.method(this, 'checkState')
+ ], {trace:false});
+ },
+
+ //.........................................................................
+
+ 'handleFormValueChange': function (someOptions) {
+ return Clipperz.Async.callbacks("DirectLoginWizardController.handleFormValueChange", [
+ MochiKit.Base.method(this.directLogin(), 'formValues'),
+ MochiKit.Base.itemgetter(someOptions['fieldName']),
+ MochiKit.Base.methodcaller('setValue', someOptions['selectedValue']),
+ MochiKit.Base.method(this, 'checkState')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleDirectLoginEditingComponentKeyPressed': function (anEvent) {
+ if (anEvent.key().string == 'KEY_ENTER') {
+ if (anEvent.target().nodeName != 'TEXTAREA') {
+ anEvent.preventDefault();
+ this.handleMoveForward();
+ }
+ } else if (anEvent.key().string == 'KEY_TAB') {
+ this.handleMoveForward();
+ if ((anEvent.target().nodeName == 'INPUT') || (anEvent.target().nodeName == 'TEXTAREA')) {
+ anEvent.preventDefault();
+ }
+ } else if ((anEvent.key().string == 'KEY_ARROW_RIGHT') && (anEvent.modifier().meta == true)) {
+ this.handleMoveForward();
+ } else if ((anEvent.key().string == 'KEY_ARROW_LEFT') && (anEvent.modifier().meta == true)) {
+ this.handleMoveBackward();
+ } else if (anEvent.key().string == 'KEY_ESCAPE') {
+ anEvent.stop();
+ this.handleExit();
+ }
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js
new file mode 100644
index 0000000..28401a2
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js
@@ -0,0 +1,145 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.DirectLoginsController = function() {
+ Clipperz.PM.UI.Web.Controllers.DirectLoginsController.superclass.constructor.apply(this, arguments);
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.DirectLoginsController, Clipperz.PM.UI.Web.Controllers.GridController, {
+
+ 'createGrid': function () {
+ return new Clipperz.PM.UI.Web.Components.GridComponent({columnsManagers: [
+ new Clipperz.PM.UI.Web.Components.FaviconColumnManager({
+ 'name': 'DirectLogins.favicon',
+ 'selector': MochiKit.Base.methodcaller('favicon'),
+ 'cssClass': 'favicon'
+ }),
+// new Clipperz.PM.UI.Web.Components.LinkColumnManager({
+ new Clipperz.PM.UI.Web.Components.DirectLoginColumnManager({
+ 'name': 'DirectLogins.title',
+ 'selector': MochiKit.Base.methodcaller('label'),
+ 'label': 'title',
+ 'cssClass': 'title',
+ 'comparator': Clipperz.Base.caseInsensitiveCompare,
+ 'sortable': true,
+ 'sorted': 'ASCENDING',
+ 'actionMethod': MochiKit.Base.methodcaller('runDirectLogin')
+ }),
+// new Clipperz.PM.UI.Web.Components.TextColumnManager({ //should be StrengthColumnManager
+// 'label': 'strength',
+// 'cssClass': 'title',
+// 'selector': MochiKit.Base.methodcaller('label') //should be 'strength' or a strenght evaluation function
+// }),
+ new Clipperz.PM.UI.Web.Components.LinkColumnManager({
+ 'name': 'DirectLogins.cardTitle',
+ 'selector': MochiKit.Base.compose(MochiKit.Base.methodcaller('label'), MochiKit.Base.methodcaller('record')),
+ 'label': 'card',
+ 'cssClass': 'cardTitle',
+ 'comparator': Clipperz.Base.caseInsensitiveCompare,
+ 'sortable': true,
+ 'sorted': 'UNSORTED',
+ 'actionMethod': MochiKit.Base.method(this, 'handleShowCard')
+ }),
+// new Clipperz.PM.UI.Web.Components.TextColumnManager({ //should be StrengthColumnManager
+// 'label': 'last access',
+// 'cssClass': 'title',
+// 'selector': MochiKit.Base.methodcaller('label')
+// // 'sortable': true,
+// // 'sorted': 'UNSORTED'
+// }),
+// new Clipperz.PM.UI.Web.Components.TextColumnManager({
+// 'label': 'commands',
+// 'cssClass': 'title',
+// 'selector': MochiKit.Base.methodcaller('label'), //should be a function for commands display
+// }),
+ new Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager({
+ 'name': 'DirectLogins.delete',
+ 'selector': MochiKit.Base.noop,
+ 'cssClass': 'delete',
+// 'actionMethod': function(anObject, anEvent) { MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'deleteDirectLogin', {objectData:anObject, element:anEvent.src()})}
+ 'actionMethod': MochiKit.Base.method(this, 'handleDeleteDirectLogin')
+ })
+ ]});
+
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getRows': function () {
+ // TODO: relying on user() in GridController, bad code smell :|
+ return this.user().getDirectLogins();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleShowCard': function (anObject, anEvent) {
+ var cardDialogController;
+
+ cardDialogController = new Clipperz.PM.UI.Web.Controllers.CardDialogController({record:anObject.record()})
+ cardDialogController.run(anEvent.src());
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleDeleteDirectLogin': function (anObject, anEvent) {
+ var deferredResult;
+ var confirmationDialog;
+
+ confirmationDialog = new Clipperz.PM.UI.Common.Components.SimpleMessagePanel({
+ title: "Delete DirectLogin",
+ text: "Do you want to delete …",
+ type: 'ALERT',
+ buttons: [
+ {text:"Cancel", result:'CANCEL', isDefault:true},
+ {text:"Delete", result:'OK'}
+ ]
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.handleDeleteCard", {trace:false});
+// deferredResult = confirmationDialog.deferredShow({openFromElement:anEvent.src(), onOkCloseToElement:MochiKit.DOM.currentDocument().body, onCancelCloseToElement:anEvent.src()});
+ deferredResult.addMethod(confirmationDialog, 'deferredShow', {
+ 'openFromElement': anEvent.src(),
+ 'onOkCloseToElement': null, // MochiKit.DOM.currentDocument().body,
+ 'onCancelCloseToElement': anEvent.src()
+ });
+ deferredResult.addCallback(function () { Clipperz.log("DELETE: " + anObject.toString(), anObject); });
+ deferredResult.addErrbackPass(function () { Clipperz.log("skip deletion: " + anObject.toString(), anObject); });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+*/ \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/FilterController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/FilterController.js
new file mode 100644
index 0000000..13e02bc
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/FilterController.js
@@ -0,0 +1,158 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.FilterController = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Controllers.FilterController.superclass.constructor.call(this, args);
+
+ this._filterElements = [];
+ this._filter = "";
+
+ this._pendingSearchClicks = 0;
+
+ return this;
+};
+
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.FilterController, Object, {
+
+ //-----------------------------------------------------------------------------
+
+ 'getFilter': function () {
+ return this._filter;
+ },
+
+ '_setFilter': function (aFilterElement, aFilter) {
+ if (aFilter != this._filter) {
+ this._filter = aFilter;
+ MochiKit.Signal.signal(this, 'filterUpdated', aFilter);
+ this.updateFilterElements(aFilterElement, aFilter);
+ }
+ },
+
+ 'setFilter': function (aFilter) {
+ this._setFilter(null, aFilter);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'filterElements': function () {
+ return this._filterElements;
+ },
+
+ 'registerFilterElement': function (aFilterElement) {
+//Clipperz.log("=== FilterController.registerFilterElement", aFilterElement);
+ this._filterElements.push(aFilterElement);
+ MochiKit.Signal.connect(aFilterElement, 'onkeydown', this, 'searchClickHandler');
+ MochiKit.Signal.connect(aFilterElement, 'onfocus', this, 'searchClickHandler');
+ },
+
+ 'removeFilterElement': function (aFilterElement) {
+ var i;
+ var filterElements;
+ for (i=0; i < filterElements; i++) {
+ if (filterElements[i] == aFilterElement);
+ filterElements.splice(i, 1);
+// TODO unregister/disconnect filterElement ?? MochiKit.Signal.disconnect(this.grid().filterElement(), 'updateFilter', this.filterController(), 'handleUpdateFilter');
+ }
+ },
+
+ 'updateFilterElements': function (aSourceElement, aFilterString) {
+ MochiKit.Iter.forEach(this.filterElements(),
+ function (aFilterElement) {
+ if (aFilterElement != aSourceElement) {
+ aFilterElement.value = aFilterString;
+ }
+ }
+ );
+
+ if (aSourceElement != null) {
+ aSourceElement.focus();
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function () {
+//Clipperz.log("=== FilterController.run");
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'pendingSearchClicks': function () {
+ return this._pendingSearchClicks;
+ },
+
+ 'incrementPendingSearchClicks': function () {
+ this._pendingSearchClicks++;
+ },
+
+ 'decrementPendingSearchClicks': function () {
+ this._pendingSearchClicks--;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'searchClickHandler': function (anEvent) {
+ if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ENTER')) {
+ anEvent.preventDefault();
+ } else {
+ var value;
+
+ if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ESCAPE')) {
+ value = ""
+ } else if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ARROW_UP')) {
+ } else if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ARROW_DOWN')) {
+ } else {
+ value = null;
+ }
+
+ this.incrementPendingSearchClicks();
+ MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, "searchClickDeferredHandler", anEvent.src(), value));
+ }
+ },
+
+ //.........................................................................
+
+ 'searchClickDeferredHandler': function (aFilterElement, aValue) {
+ if (aValue != null) {
+ aFilterElement.value = aValue;
+ }
+
+ this.decrementPendingSearchClicks();
+ if (this.pendingSearchClicks()==0) {
+ this._setFilter(aFilterElement, aFilterElement.value);
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+ 'syntaxFix': 'syntax fix'
+}); \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js
new file mode 100644
index 0000000..740a091
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js
@@ -0,0 +1,374 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.GridController = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Controllers.GridController.superclass.constructor.call(this, args);
+
+ this._grid = null;
+ this._user = null;
+ this._sortedColumnManager = null;
+ this._cachedObjects = null;
+ this._filterController = args.filterController || null;
+
+ this._deferredDisplaySelectedRowsInvocation = null;
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.GridController, Object, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.GridController";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'createGrid': function () {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'setupWithGrid': function (aGrid) {
+ this._grid = aGrid;
+
+ if (this._grid != null) {
+ MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) {
+ if (aColumnManager.isSortable()) {
+ if (aColumnManager.isSorted()) {
+ this.setSortedColumnManager(aColumnManager);
+ }
+ MochiKit.Signal.connect(aColumnManager, 'sort', this, 'handleColumnManagerSort');
+ }
+ MochiKit.Signal.connect(aColumnManager, 'selectRow', this, 'handleColumnManagerSelectRow');
+ MochiKit.Signal.connect(aColumnManager, 'unselectRow', this, 'handleColumnManagerUnselectRow');
+ }, this);
+ }
+ },
+
+ 'grid': function() {
+ if (this._grid == null) {
+ this.setupWithGrid(this.createGrid());
+ }
+
+ return this._grid;
+ },
+
+ 'filterController': function () {
+//Clipperz.log('GridController.filterController >>>', this._filterController);
+ if (this._filterController == null) {
+ this._filterController = new Clipperz.PM.UI.Web.Controllers.FilterController();
+ }
+//Clipperz.log('GridController.filterController <<<', this._filterController);
+ return this._filterController;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'columnsManagers': function () {
+ return this.grid().columnsManagers();
+ },
+
+ 'columnManagerWithName': function (aName) {
+ var managers;
+ var result;
+
+ managers = MochiKit.Base.filter(function (aManager) { return aManager.name() == aName; } , this.columnsManagers());
+
+ if (managers.length == 1) {
+ result = managers[0];
+ } else if (managers.length == 0) {
+ result = null;
+ } else {
+ throw "WTF!!!";
+ }
+
+ return result;
+ },
+
+ 'sortedColumnManager': function () {
+ return this._sortedColumnManager;
+ },
+
+ 'setSortedColumnManager': function(aValue) {
+ if (aValue.sorted() != 'UNSORTED') {
+ this._sortedColumnManager = aValue;
+ } else {
+ this._sortedColumnManager = null;
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleColumnManagerSort': function(aSelectedColumnManager) {
+ MochiKit.Iter.forEach(this.columnsManagers(), function(aColumnManager) {
+ if (aSelectedColumnManager != aColumnManager) {
+ if (aColumnManager.isSortable()) {
+ aColumnManager.setSorted('UNSORTED');
+ }
+ }
+ });
+
+ aSelectedColumnManager.toggleSorting();
+ this.setSortedColumnManager(aSelectedColumnManager);
+
+ this.displaySelectedRows(this.filterController().getFilter());
+ },
+
+ 'handleColumnManagerSelectRow': function (aRowObject) {
+ this.grid().selectRow(aRowObject);
+ },
+
+ 'handleColumnManagerUnselectRow': function (aRowObject) {
+ this.grid().unselectRow(aRowObject);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleFilterUpdated': function (aFilter) {
+ if (this.grid().isActive()) {
+ this.displaySelectedRows(aFilter);
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+ // TODO: relying on user() in GridController, bad code smell :|
+ // mhh: a controller should have access to business logic object too. Otherwise it will fail its controller role. [Giulio Cesare]
+
+ 'setUser': function(anUser) {
+ this._user = anUser;
+ },
+
+ 'user': function() {
+ return this._user;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(args) {
+//Clipperz.log("=== GridController.run");
+ var deferredResult;
+
+ this.setUser(args.user);
+ args.slot.setContent(this.grid());
+ this.filterController().registerFilterElement(this.grid().filterElement());
+ MochiKit.Signal.connect(this.filterController(), 'filterUpdated', this, 'handleFilterUpdated');
+
+ return this.displaySelectedRows();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleGenericError': function(anError) {
+ var result;
+
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+Clipperz.log("## GridController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack);
+ result = new MochiKit.Async.CancelledError(anError);
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getRows': function () {
+ throw Clipperz.Base.AbstractMethod;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setDeferredDisplaySelectedRowsInvocation': function (aDeferred) {
+ if (this._deferredDisplaySelectedRowsInvocation != null) {
+ this._deferredDisplaySelectedRowsInvocation.cancel();
+ }
+
+ this._deferredDisplaySelectedRowsInvocation = aDeferred;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'resetDeferredDisplaySelectedRowsInvocation': function () {
+ if (this._deferredDisplaySelectedRowsInvocation != null) {
+ this._deferredDisplaySelectedRowsInvocation.cancel();
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_displaySelectedRows': function (aFilter, someRows) {
+ var result;
+ var delay;
+
+ if ((aFilter != null) && (aFilter != '')) {
+ var filter;
+ var filterRegExp;
+
+ filter = aFilter.replace(/[^A-Za-z0-9]/g, "\\$&");
+ filterRegExp = new RegExp(filter, "i");
+ result = MochiKit.Base.filter(function (aCachedResult) { return filterRegExp.test(aCachedResult['_searchableContent'])}, someRows);
+ delay = 0.002*result.length;
+
+ this.setDeferredDisplaySelectedRowsInvocation(MochiKit.Async.callLater(delay, MochiKit.Base.method(this, "deferredDisplaySelectedRows", result)));
+ } else {
+ result = someRows;
+
+ this.resetDeferredDisplaySelectedRowsInvocation();
+ this.deferredDisplaySelectedRows(result);
+ }
+
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'deferredDisplaySelectedRows': function (someRows) {
+ if (this.sortedColumnManager() != null) {
+ var comparator;
+ var fieldName;
+
+ fieldName = this.sortedColumnManager().name();
+ comparator = this.sortedColumnManager().comparator();
+ if (this.sortedColumnManager().sorted() == 'DESCENDING') {
+ comparator = Clipperz.Base.reverseComparator(comparator);
+ }
+
+ someRows.sort(MochiKit.Base.partial(function(aKey, aComparator, aObject, bObject){
+ return comparator(aObject[aKey], bObject[aKey]);
+ }, this.sortedColumnManager().name(), comparator));
+ }
+
+ this.grid().update(someRows);
+ this.grid().endSearch();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getCachedValues': function () {
+ var deferredResult;
+
+ if (this._cachedObjects != null) {
+ deferredResult = MochiKit.Async.succeed(this._cachedObjects);
+ } else {
+ var objectCollectResultsConfiguration;
+
+ objectCollectResultsConfiguration = {
+ '_rowObject': MochiKit.Async.succeed,
+ '_reference': MochiKit.Base.methodcaller('reference'),
+ '_searchableContent': MochiKit.Base.methodcaller('searchableContent')
+ };
+
+ MochiKit.Base.map(function (aColumnManager) {
+ objectCollectResultsConfiguration[aColumnManager.name()] = aColumnManager.selector();
+ }, this.columnsManagers());
+
+ deferredResult = new Clipperz.Async.Deferred("GridController.getCachedValues", {trace:false});
+ deferredResult.addMethod(this, 'getRows');
+ deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("GridController.getCachedValues - collectResults", objectCollectResultsConfiguration, {trace:false}));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(MochiKit.Base.bind(function (someRows) {
+ this._cachedObjects = someRows;
+ return this._cachedObjects;
+ }, this));
+ deferredResult.callback();
+ }
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hasPendingChanges': function () {
+ return this.user().hasPendingChanges();
+ },
+
+ 'saveChanges': function () {
+ this._cachedObjects = null;
+
+ return Clipperz.Async.callbacks("GridController.saveChanges", [
+ MochiKit.Base.method(this.user(), 'saveChanges'),
+ MochiKit.Base.method(this, 'focus')
+ ], {trace:false});
+ },
+
+ 'revertChanges': function () {
+ return this.user().revertChanges();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'displayEmptyContent': function () {
+ },
+
+ 'hideEmptyContent': function () {
+ this.grid().removeNoRowsGridComponent();
+ },
+
+ 'displaySelectedRows': function (aFilter) {
+ if ((aFilter != null) && (aFilter != '')){
+ this.grid().startSearch();
+ }
+
+ return Clipperz.Async.callbacks("GridController.displaySelectedrows", [
+ MochiKit.Base.method(this, 'getCachedValues'),
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.deferredIf("There are some items to show in the grid", [
+ MochiKit.Base.method(this, 'hideEmptyContent'),
+ MochiKit.Base.method(this, 'getCachedValues'),
+ MochiKit.Base.method(this, '_displaySelectedRows', aFilter)
+ ], [
+ MochiKit.Base.method(this, 'displayEmptyContent'),
+ MochiKit.Base.method(this.grid(), 'endSearch')
+ ])
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'focus': function () {
+ return Clipperz.Async.callbacks("GridController.focus", [
+ MochiKit.Base.method(this, 'displaySelectedRows', this.filterController().getFilter()),
+ MochiKit.Base.method(this.grid(), 'focus')
+ ], {trace:false})
+//*##*/ this.displaySelectedRows(this.filterController().getFilter());
+// this.grid().focus();
+ },
+
+ //=============================================================================
+
+ 'deleteAllCleanTextData': function () {
+ this._cachedObjects = null;
+ this.grid().drawEmpty();
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/LoginController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/LoginController.js
new file mode 100644
index 0000000..d88af41
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/LoginController.js
@@ -0,0 +1,259 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.LoginController = function(args) {
+ this._args = args || {};
+
+ this._loginPage = null;
+
+ this._newUserWizardController = null;
+ this._newUserCreationComponent = null;
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.LoginController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.LoginController";
+ },
+
+ 'args': function () {
+ return this._args;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'loginPage': function() {
+ if (this._loginPage == null) {
+ this._loginPage = new Clipperz.PM.UI.Web.Components.LoginPage();
+
+ MochiKit.Signal.connect(this._loginPage, 'createNewAccountClick', this, 'handleCreateNewAccountClick')
+ }
+
+ return this._loginPage;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(args) {
+ var slot;
+ var loginPage;
+ var loginForm;
+
+ slot = args.slot;
+
+ loginForm = new Clipperz.PM.UI.Web.Components.LoginForm({'autocomplete': this.args()['autocomplete']});
+
+ slot.setContent(this.loginPage());
+ this.loginPage().slotNamed('loginForm').setContent(loginForm);
+
+ MochiKit.Signal.connect(loginForm, 'doLogin', MochiKit.Base.method(this, 'doLogin', loginForm));
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'doLogin', MochiKit.Base.method(this, 'doLogin', loginForm));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'doLogin': function(aLoginForm, anEvent) {
+ var deferredResult;
+ var parameters;
+// var shouldUseOTP;
+ var loginProgress;
+ var user;
+ var getPassphraseDelegate;
+
+ parameters = anEvent;
+// shouldUseOTP = (typeof(parameters.passphrase) == 'undefined');
+
+ getPassphraseDelegate = MochiKit.Base.partial(MochiKit.Async.succeed, parameters.passphrase);
+ user = new Clipperz.PM.DataModel.User({'username':parameters.username, 'getPassphraseFunction':MochiKit.Base.method(Clipperz.PM.RunTime.mainController, 'getPassphrase')});
+
+ loginProgress = new Clipperz.PM.UI.Web.Components.LoginProgress();
+
+ deferredResult = new Clipperz.Async.Deferred("LoginController.doLogin", {trace:false});
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':4});
+ deferredResult.addMethod(Clipperz.PM.RunTime.mainController, 'setPassphraseDelegate', getPassphraseDelegate);
+ deferredResult.addMethod(loginProgress, 'deferredShowModal', {deferredObject:deferredResult, openFromElement:aLoginForm.submitButtonElement()});
+ deferredResult.addMethod(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'deferredEntropyCollection');
+// if (shouldUseOTP == false) {
+ deferredResult.addMethod(user, 'login');
+// } else {
+// deferredResult.addMethod(user, 'loginUsingOTP', parameters.username, parameters.otp);
+// }
+ deferredResult.addCallback(function(aLoginProgress, res) {
+ aLoginProgress.disableCancel();
+ return res;
+ }, loginProgress);
+ deferredResult.addCallback(function () {
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'CARDS_CONTROLLER_DID_RUN', MochiKit.Base.method(loginProgress, 'deferredHideModalAndRemove', {closeToElement:MochiKit.DOM.currentDocument().body}));
+ })
+ deferredResult.addMethod(this, 'userLoggedIn', user, loginProgress, aLoginForm);
+ deferredResult.addErrback (MochiKit.Base.method(this, 'handleFailedLogin', loginProgress));
+
+ deferredResult.addErrback (MochiKit.Base.method(loginProgress, 'deferredHideModalAndRemove', {closeToElement:aLoginForm.submitButtonElement()}));
+ deferredResult.addErrbackPass (MochiKit.Base.method(aLoginForm, 'focusOnPassphraseField'));
+ deferredResult.addBoth(MochiKit.Base.method(Clipperz.PM.RunTime.mainController, 'removePassphraseDelegate', getPassphraseDelegate));
+ deferredResult.callback();
+
+ MochiKit.Signal.connect(loginProgress, 'cancelEvent', deferredResult, 'cancel');
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'userLoggedIn': function(aUser) {
+//Clipperz.log(">>> LoginController.userLoggedIn");
+ MochiKit.Signal.signal(this, 'userLoggedIn', {user: aUser});
+//Clipperz.log("<<< LoginController.userLoggedIn");
+ },
+
+ //=========================================================================
+
+ 'handleCreateNewAccountClick': function (aComponent) {
+// return Clipperz.PM.DataModel.User.registerNewAccount("new", "user");
+ return Clipperz.Async.callbacks("LoginController.handleCreateNewAccountClick", [
+//' MochiKit.Base.method(this, 'newUserCreationComponent'),
+// MochiKit.Base.methodcaller('deferredShowModal', {openFromElement:aComponent}),
+// MochiKit.Base.method(this.newUserWizardController(), 'run')
+
+
+ MochiKit.Base.method(this, 'newUserCreationComponent'),
+ Clipperz.Async.forkAndJoin("Async.test succeedingForkedAndWaitDeferrer", [
+ MochiKit.Base.method(this.newUserCreationComponent(), 'deferredShowModal', {openFromElement:aComponent, duration:0.5}),
+ MochiKit.Base.method(this.newUserWizardController(), 'run')
+ ], {trace:false}),
+// MochiKit.Base.method(this.newUserCreationComponent(), 'enableCredentialsField')
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'newUserWizardController': function () {
+ if (this._newUserWizardController == null) {
+ this._newUserWizardController = new Clipperz.PM.UI.Web.Controllers.NewUserWizardController({
+ 'newUserCreationComponent': this.newUserCreationComponent()
+ })
+
+// MochiKit.Signal.connect(this._newUserWizardController, 'exit', this, 'handleHideNewUserCreationComponent');
+ MochiKit.Signal.connect(this._newUserWizardController, 'done', this, 'handleCompleteNewUserCreationComponent');
+ }
+
+ return this._newUserWizardController;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newUserCreationComponent': function () {
+ if (this._newUserCreationComponent == null) {
+ this._newUserCreationComponent = new Clipperz.PM.UI.Web.Components.NewUserCreationComponent();
+ }
+
+ return this._newUserCreationComponent;
+ },
+
+ 'clearNewUserCreationComponent': function () {
+ if (this._newUserCreationComponent != null) {
+ this._newUserCreationComponent.clear();
+ }
+ this._newUserCreationComponent = null;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleHideNewUserCreationComponent': function () {
+ this.clearNewUserCreationComponent();
+ },
+
+ 'handleCompleteNewUserCreationComponent': function (someParameters) {
+ var deferredResult;
+ var user;
+ var newUserCreationComponent;
+
+ user = someParameters.user;
+ newUserCreationComponent = this.newUserCreationComponent();
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'CARDS_CONTROLLER_DID_RUN', MochiKit.Base.method(newUserCreationComponent, 'deferredHideModal', {closeToElement:MochiKit.DOM.currentDocument().body})),
+
+ deferredResult = new Clipperz.Async.Deferred("LoginController.handleCompleteNewUserCreationComponent", {trace:false});
+
+ deferredResult.addCallbackList([
+ MochiKit.Base.method(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'deferredEntropyCollection'),
+ MochiKit.Base.method(user, 'login'),
+ MochiKit.Base.method(this, 'userLoggedIn', user),
+ MochiKit.Base.method(this, 'clearNewUserCreationComponent')
+ ]);
+ deferredResult.addErrback(function (aValue) { Clipperz.log("WTF!! Error doing the login after creating a new user" + aValue)});
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+
+ //=========================================================================
+
+ 'handleFailedLogin': function(aLoginProgress, anError) {
+ var result;
+
+//console.log("anError", anError);
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+ var deferredResult;
+
+MochiKit.Logging.logError("## MainController - FAILED LOGIN: " + anError);
+ deferredResult = new MochiKit.Async.Deferred();
+
+ aLoginProgress.showErrorMessage("failed login");
+// Clipperz.NotificationCenter.register(loginProgress, 'cancelEvent', deferredResult, 'callback');
+ MochiKit.Signal.connect(aLoginProgress, 'cancelEvent', deferredResult, 'callback');
+ deferredResult.addCallback(MochiKit.Async.fail, anError)
+ result = deferredResult;
+ }
+
+ return result;
+ },
+
+ 'handleGenericError': function(anError) {
+ var result;
+
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+MochiKit.Logging.logError("## MainController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack);
+//console.log(anError);
+ result = new MochiKit.Async.CancelledError(anError);
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/MainController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/MainController.js
new file mode 100644
index 0000000..aa0d6ad
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/MainController.js
@@ -0,0 +1,218 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.MainController = function(args) {
+ this._args = args;
+
+ // controllers
+ this._loginController = null;
+ this._appController = null;
+
+ // components
+ this._headerComponent = null;
+ this._pageComponent = null;
+ this._footerComponent = null;
+
+ this._passphraseDelegateLock = new MochiKit.Async.DeferredLock();
+ this._passphraseDelegateLock.acquire();
+//Clipperz.log('MainController init _passphraseDelegateLock', this._passphraseDelegateLock);
+ this._passphraseDelegate = null;
+
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'remoteRequestSent', this, 'handleRemoteRequestSent');
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'remoteRequestReceived', this, 'handleRemoteRequestReceived');
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.MainController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.MainController";
+ },
+
+ 'args': function () {
+ return this._args;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'headerComponent': function() {
+ if (this._headerComponent == null) {
+ this._headerComponent = new Clipperz.PM.UI.Web.Components.PageHeader();
+ }
+
+ return this._headerComponent;
+ },
+
+ 'footerComponent': function() {
+ if (this._footerComponent == null) {
+ this._footerComponent = new Clipperz.PM.UI.Web.Components.PageFooter();
+ }
+
+ return this._footerComponent;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'pageComponent': function() {
+ if (this._pageComponent == null) {
+ this._pageComponent = new Clipperz.PM.UI.Web.Components.Page({element:MochiKit.DOM.getElement('mainDiv')});
+ }
+
+ return this._pageComponent;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'loginController': function() {
+ if (this._loginController == null) {
+ this._loginController = new Clipperz.PM.UI.Web.Controllers.LoginController(this.args());
+
+ MochiKit.Signal.connect(this._loginController, 'userLoggedIn', this, 'loginControllerUserLoggedInCallback');
+ }
+
+ return this._loginController;
+ },
+
+ 'appController': function() {
+ if (this._appController == null) {
+ this._appController = new Clipperz.PM.UI.Web.Controllers.AppController();
+
+ MochiKit.Signal.connect(this._appController, 'logout', this, 'handleLogout');
+ }
+
+ return this._appController;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(shoudShowRegistrationForm) {
+ this.pageComponent().slotNamed('header').setContent(this.headerComponent());
+ this.pageComponent().slotNamed('footer').setContent(this.footerComponent());
+
+ this.pageComponent().render();
+
+ this.loginController().run({slot:this.pageComponent().slotNamed('body')});
+
+ if (shoudShowRegistrationForm) {
+ MochiKit.Signal.signal(this.loginController().loginPage(), 'createNewAccountClick');
+// this.loginController().handleCreateNewAccountClick();
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getPassphrase': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("MainController.getPassphrase", {trace:false});
+
+ deferredResult.acquireLock(this._passphraseDelegateLock);
+ deferredResult.addMethod(this, 'invokePassphraseDelegate');
+ deferredResult.releaseLock(this._passphraseDelegateLock);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'invokePassphraseDelegate': function () {
+ return this._passphraseDelegate();
+ },
+
+ 'passphraseDelegateLock': function () {
+ return this._passphraseDelegateLock;
+ },
+
+ //.........................................................................
+
+ 'setPassphraseDelegate': function (aDelegate) {
+ var shouldReleaseLock;
+
+ shouldReleaseLock = (this._passphraseDelegate == null);
+
+ this._passphraseDelegate = aDelegate;
+
+ if (shouldReleaseLock) {
+ this._passphraseDelegateLock.release();
+ }
+ },
+
+ //.........................................................................
+
+ 'removePassphraseDelegate': function (aDelegate) {
+ if (this._passphraseDelegate == aDelegate) {
+ this._passphraseDelegate = null;
+ this._passphraseDelegateLock.acquire();
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loginControllerUserLoggedInCallback': function(anEvent) {
+//Clipperz.log(">>> loginControllerUserLoggedInCallback", anEvent);
+// this.setUser(anEvent.parameters()['user']);
+//console.log("--- loginControllerUserLoggedInCallback - 1");
+
+//console.log("--- loginControllerUserLoggedInCallback - 2");
+ this.headerComponent().switchToLoggedMode();
+ this.appController().run({slot:this.pageComponent().slotNamed('body'), user:anEvent['user']});
+//Clipperz.log("<<< loginControllerUserLoggedInCallback");
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleRemoteRequestSent': function () {
+//Clipperz.log("REMOTE REQUEST sent >>>");
+ },
+
+ 'handleRemoteRequestReceived': function () {
+//Clipperz.log("REMOTE REQUEST received <<<");
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleLogout': function(anEvent) {
+ this.exit('logout.html');
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'exit': function(aPageName) {
+//Clipperz.log("### exit " + aPageName);
+ MochiKit.Async.wait(0).addCallback(function() {
+ window.location.href = "./" + aPageName + "?ln=" + Clipperz.PM.Strings.selectedLanguage;
+ });
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js
new file mode 100644
index 0000000..28d9d20
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js
@@ -0,0 +1,469 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library 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.
+
+* Javascript Crypto Library 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 Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.NewUserWizardController = function(args) {
+ this._newUserCreationComponent = args.newUserCreationComponent || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ MochiKit.Signal.connect(this._newUserCreationComponent, 'changedValue', this, 'handleChangedValue');
+ MochiKit.Signal.connect(this._newUserCreationComponent, 'moveForward', this, 'handleMoveForward');
+ MochiKit.Signal.connect(this._newUserCreationComponent, 'keyPressed', this, 'handleNewUserCreationComponentKeyPressed');
+
+ this._rulerComponent = null;
+
+ this._steps = null;
+ this._currentStepIndex = 0;
+ this._isNextEnabled = false;
+
+ this._userCreationState = 'IDLE'; // 'IN PROGRESS', 'DONE', 'FAILED'
+ this._user = null;
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.NewUserWizardController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.NewUserWizardController";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newUserCreationComponent': function () {
+ return this._newUserCreationComponent;
+ },
+
+ //=============================================================================
+
+ 'user': function () {
+ return this._user;
+ },
+
+ 'setUser': function (aValue) {
+ this._user = aValue;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'userCreationState': function () {
+ return this._userCreationState;
+ },
+
+ 'setUserCreationState': function (aValue) {
+//console.log("+++ NewUserWizardController.setUserCreationState", aValue);
+ this._userCreationState = aValue;
+ this.checkState();
+ },
+
+ //=============================================================================
+
+ 'resetCurrentStepIndex': function () {
+ this._currentStepIndex = 0;
+ this.rulerComponent().resetStatus({animateTransition:true});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'enableNext': function (aValue) {
+ this.rulerComponent().enableNext(aValue);
+ this._isNextEnabled = aValue;
+ },
+
+ 'isNextEnabled': function () {
+ return this._isNextEnabled;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'enablePrevious': function (aValue) {
+ this.rulerComponent().enablePrevious(aValue);
+ },
+
+ //=============================================================================
+
+ 'rulerComponent': function () {
+ if (this._rulerComponent == null) {
+ this._rulerComponent = new Clipperz.PM.UI.Web.Components.RulerComponent({
+ translationContext:'Wizards.NewUserWizard'
+ });
+ this._rulerComponent.render();
+
+ MochiKit.Signal.connect(this._rulerComponent, 'exit', this, 'handleExit');
+ MochiKit.Signal.connect(this._rulerComponent, 'done', this, 'done');
+ MochiKit.Signal.connect(this._rulerComponent, 'moveForward', this, 'handleMoveForward');
+ MochiKit.Signal.connect(this._rulerComponent, 'moveBackward', this, 'handleMoveBackward');
+ MochiKit.Signal.connect(this._rulerComponent, 'cursorMoved', this, 'handleCursorMoved');
+ }
+
+ return this._rulerComponent;
+ },
+
+ 'resetRuler': function () {
+// if (this._rulerComponent != null) {
+// this._rulerComponent.clear();
+// }
+// this._rulerComponent = null;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'showRuler': function (someSteps) {
+ var rulerElement;
+
+ this.setSteps(someSteps);
+
+ rulerElement = this.rulerComponent().element();
+ this.newUserCreationComponent().disableAllPanels();
+
+ MochiKit.Style.showElement(rulerElement);
+ MochiKit.Style.setElementPosition(rulerElement, {x:-1000, y:this.newUserCreationComponent().bottomMargin()});
+ new MochiKit.Visual.Move(rulerElement, {
+ x:0, y:this.newUserCreationComponent().bottomMargin(),
+ mode:'absolute',
+ duration:0.5,
+// afterFinish:MochiKit.Base.method(this, 'handleCursorMoved')
+ afterFinish:MochiKit.Base.method(this, 'handleRulerShowed')
+ });
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleRulerShowed':function () {
+ return Clipperz.Async.callbacks("NewUserWizardController.handlerRulerShowed", [
+ MochiKit.Base.method(this.newUserCreationComponent(), 'waitUntilFullyRendered'),
+ MochiKit.Base.method(this, 'handleCursorMoved')
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hideRuler': function () {
+ new MochiKit.Visual.Move(this.rulerComponent().element(), {x:-1000, mode:'relative', duration:0.5});
+ },
+
+ 'doneWithRuler': function () {
+ var rulerComponentElement;
+
+ rulerComponentElement = this.rulerComponent().element();
+ new MochiKit.Visual.Move(this.rulerComponent().element(), {
+ x:1000,
+ mode:'relative',
+ duration:1,
+// afterFinish:MochiKit.Base.partial(MochiKit.Style.hideElement, rulerComponentElement)
+ afterFinish:function () { MochiKit.Style.hideElement(rulerComponentElement); }
+ });
+ },
+
+ //=============================================================================
+
+ 'createNewUserRulerSteps': function () {
+ return [ 'CREDENTIALS', 'CHECK_CREDENTIALS', 'TERMS_OF_SERVICE', 'CREATE_USER'/*, 'LOGIN' */];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ return Clipperz.Async.callbacks("NewUserWizardController.run", [
+ MochiKit.Base.method(this, 'createNewUserRulerSteps'),
+ MochiKit.Base.method(this, 'showRuler')
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'checkState': function () {
+ var enablePrevious;
+ var enableNext;
+
+ enablePrevious = true;
+ enableNext = false;
+
+ this.newUserCreationComponent().disableAllPanels();
+
+ switch(this.currentStep()) {
+ case 'CREDENTIALS':
+ this.newUserCreationComponent().enableCredentialsPanel();
+
+ enableNext = (
+ (this.newUserCreationComponent().username() != '')
+ &&
+ (this.newUserCreationComponent().passphrase() != '')
+ );
+// enablePrevious = false;
+ break;
+ case 'CHECK_CREDENTIALS':
+ this.newUserCreationComponent().enableCheckCredentialsPanel();
+
+ enableNext = (this.newUserCreationComponent().passphrase() == this.newUserCreationComponent().rePassphrase());
+// enablePrevious = true;
+ break
+ case 'TERMS_OF_SERVICE':
+ this.newUserCreationComponent().enableTermsOfServicePanel();
+
+//console.log("awareOfUnrecoverablePassphrase", this.newUserCreationComponent().awareOfUnrecoverablePassphrase());
+//console.log("readTermsOfService", this.newUserCreationComponent().readTermsOfService());
+ enableNext = (
+ (this.newUserCreationComponent().awareOfUnrecoverablePassphrase() == 'on')
+ &&
+ (this.newUserCreationComponent().readTermsOfService() == 'on')
+ )
+ break;
+ case 'CREATE_USER':
+//console.log(">>> CREATE_USER", this.userCreationState());
+ this.newUserCreationComponent().enableCreateUserPanel();
+
+ switch (this.userCreationState()) {
+ case 'IDLE':
+ this.setUserCreationState('IN PROGRESS');
+ this.preformActualUserRegistration();
+
+ enablePrevious = false;
+ enableNext = false;
+ break;
+ case 'IN PROGRESS':
+ enablePrevious = false;
+ enableNext = false;
+ break;
+ case 'DONE':
+ enablePrevious = false;
+ enableNext = true;
+ break;
+ case 'FAILED':
+ enablePrevious = true;
+ enableNext = false;
+ break;
+ };
+ break;
+// case 'LOGIN':
+// this.newUserCreationComponent().enableLoginPanel();
+// break;
+ }
+
+ if (this.currentStepIndex() > 0) {
+ this.enablePrevious(enablePrevious);
+ } else {
+ this.enablePrevious(false);
+ }
+ this.enableNext(enableNext);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setFocus': function () {
+ switch(this.currentStep()) {
+ case 'CREDENTIALS':
+ this.newUserCreationComponent().focusOnUsernameElement();
+ break;
+ case 'CHECK_CREDENTIALS':
+ this.newUserCreationComponent().focusOnRePassphraseElement();
+ break
+ case 'TERMS_OF_SERVICE':
+ break;
+ case 'CREATE_USER':
+ break;
+// case 'LOGIN':
+// break;
+ }
+ },
+
+ //=============================================================================
+
+ 'steps': function () {
+ return this._steps;
+ },
+
+ 'setSteps': function (aValue) {
+ this._steps = aValue;
+
+ this.rulerComponent().setSteps(aValue);
+ this.resetCurrentStepIndex();
+ },
+
+ 'currentStepIndex': function () {
+ return this._currentStepIndex;
+ },
+
+ 'currentStep': function () {
+ return this.steps()[this.currentStepIndex()];
+ },
+
+ //=============================================================================
+
+ 'handleExit': function () {
+ return Clipperz.Async.callbacks("NewUserWizardController.handleExit", [
+// MochiKit.Base.method(this.newUserCreationComponent(), 'resetContent'),
+ Clipperz.Async.forkAndJoin("NewUserWizardController.handleExit - fork and join", [
+ MochiKit.Base.method(this, 'hideRuler'),
+ MochiKit.Base.method(this.newUserCreationComponent(), 'deferredHideModal')
+ ], {trace:false}),
+ MochiKit.Base.method(this, 'resetRuler'),
+// MochiKit.Base.method(this.newUserCreationComponent(), 'reset'),
+ MochiKit.Base.partial(MochiKit.Signal.signal, this, 'exit')
+ ], {trace:false})
+ },
+
+ 'done': function () {
+ this.doneWithRuler();
+ MochiKit.Signal.signal(this, 'done', {'user': this.user()});
+ },
+
+ //=============================================================================
+
+ 'handleMoveBackward': function () {
+ if (this._currentStepIndex > 0) {
+ var afterMoveAction;
+
+ afterMoveAction = MochiKit.Base.noop;
+
+//console.log("<-- backward", this.currentStep());
+ switch(this.currentStep()) {
+ case 'CREDENTIALS':
+ case 'CHECK_CREDENTIALS':
+ case 'TERMS_OF_SERVICE':
+ this._currentStepIndex --;
+ this.rulerComponent().moveBackward(afterMoveAction);
+ break;
+ case 'CREATE_USER':
+ this.setUser(null);
+ this.newUserCreationComponent().hideAllProgeressStates();
+ this.resetCurrentStepIndex();
+ this.setUserCreationState('IDLE');
+ break;
+// case 'LOGIN':
+// break;
+ };
+
+ }
+
+ if (this._currentStepIndex == 0) {
+ this.enablePrevious(false);
+ }
+ },
+
+ 'handleMoveForward': function () {
+ if (this.isNextEnabled()) {
+ var afterMoveAction;
+
+ this._currentStepIndex ++;
+ afterMoveAction = MochiKit.Base.noop;
+
+ switch(this.currentStep()) {
+ case 'CREDENTIALS':
+ break;
+ case 'CHECK_CREDENTIALS':
+ break
+ case 'TERMS_OF_SERVICE':
+ break;
+ case 'CREATE_USER':
+ break;
+// case 'LOGIN':
+// break;
+ };
+
+ this.rulerComponent().moveForward(afterMoveAction);
+ };
+ },
+
+ 'handleCursorMoved': function () {
+// this.checkState();
+// this.setFocus();
+
+ return Clipperz.Async.callbacks("NewUserWizardController.handleCursorMoved", [
+ MochiKit.Base.method(this.newUserCreationComponent(), 'waitUntilFullyRendered'),
+ MochiKit.Base.method(this, 'checkState'),
+ MochiKit.Base.method(this, 'setFocus')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleChangedValue': function (anEvent) {
+ this.checkState();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleNewUserCreationComponentKeyPressed': function (anEvent) {
+//console.log(">>> handleNewUserCreationComponentKeyPressed", anEvent.key().string);
+ if (anEvent.key().string == 'KEY_ENTER') {
+ if (anEvent.target().nodeName != 'TEXTAREA') {
+ anEvent.preventDefault();
+ this.handleMoveForward();
+ }
+ } else if (anEvent.key().string == 'KEY_TAB') {
+ if (anEvent.target() == this.newUserCreationComponent().usernameElement()) {
+ } else {
+ this.handleMoveForward();
+ if ((anEvent.target().nodeName == 'INPUT') || (anEvent.target().nodeName == 'TEXTAREA')) {
+ anEvent.preventDefault();
+ }
+ }
+ } else if ((anEvent.key().string == 'KEY_ARROW_RIGHT') && (anEvent.modifier().meta == true)) {
+ this.handleMoveForward();
+ } else if ((anEvent.key().string == 'KEY_ARROW_LEFT') && (anEvent.modifier().meta == true)) {
+ this.handleMoveBackward();
+ } else if (anEvent.key().string == 'KEY_ESCAPE') {
+ anEvent.stop();
+ this.handleExit();
+ } else {
+ MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'checkState'));
+ }
+ },
+
+ //=============================================================================
+
+ 'preformActualUserRegistration': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("NewUSerWizardController.preformActualUserRegistration", {trace:false});
+ deferredResult.addMethod(this.newUserCreationComponent(), 'showProgressOnUserCreation');
+ deferredResult.addMethod(Clipperz.PM.RunTime.mainController, 'setPassphraseDelegate', MochiKit.Base.method(this.newUserCreationComponent(), 'passphrase'));
+ deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount,
+ this.newUserCreationComponent().username(),
+ MochiKit.Base.method(Clipperz.PM.RunTime.mainController, 'getPassphrase')
+ );
+ deferredResult.addMethod(this, 'setUser');
+ deferredResult.addMethod(this.newUserCreationComponent(), 'showUserCreationDone');
+ deferredResult.addMethod(this, 'setUserCreationState', 'DONE');
+
+// deferredResult.addErrback(MochiKit.Base.method(this.newUserCreationComponent(), 'showUserCreationFailed'));
+// deferredResult.addErrback(MochiKit.Base.method(this, 'setUser', null));
+// deferredResult.addErrback(MochiKit.Base.method(this, 'setUserCreationState', 'FAILED'));
+ deferredResult.addErrback(MochiKit.Base.bind(function (aValue) {
+ this.newUserCreationComponent().showUserCreationFailed();
+ this.setUser(null);
+ this.setUserCreationState('FAILED');
+ }, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});