author | Giulio Cesare Solaroli <giulio.cesare@solaroli.it> | 2011-10-03 16:04:12 (UTC) |
---|---|---|
committer | Giulio Cesare Solaroli <giulio.cesare@solaroli.it> | 2011-10-03 16:04:12 (UTC) |
commit | 541bb378ddece2eab135a8066a16994e94436dea (patch) (side-by-side diff) | |
tree | ff160ea3e26f7fe07fcfd401387c5a0232ca715e /frontend/gamma/js/Clipperz/PM/UI/Web | |
parent | 1bf431fd3d45cbdf4afa3e12afefe5d24f4d3bc7 (diff) | |
parent | ecad5e895831337216544e81f1a467e0c68c4a6a (diff) | |
download | clipperz-541bb378ddece2eab135a8066a16994e94436dea.zip clipperz-541bb378ddece2eab135a8066a16994e94436dea.tar.gz clipperz-541bb378ddece2eab135a8066a16994e94436dea.tar.bz2 |
Merge pull request #1 from gcsolaroli/master
First version of the restructured repository
Diffstat (limited to 'frontend/gamma/js/Clipperz/PM/UI/Web') (more/less context) (ignore whitespace changes)
44 files changed, 9934 insertions, 0 deletions
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js new file mode 100644 index 0000000..4378b19 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js @@ -0,0 +1,148 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.AccountPanel = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.AccountPanel.superclass.constructor.apply(this, arguments); + +// this._initiallySelectedTab = args.selected || 'ACCOUNT'; + this._initiallySelectedTab = args.selected || 'PASSPHRASE'; + this._tabPanelControllerConfiguration = { +// 'ACCOUNT': { +// tab: 'accountTab', +// panel: 'accountPanel' +// }, + 'PASSPHRASE': { + tab: 'passphraseTab', + panel: 'passphrasePanel' + }, + 'PREFERENCES': { + tab: 'preferencesTab', + panel: 'preferencesPanel' + }, + 'LOGIN_HISTORY': { + tab: 'loginHistoryTab', + panel: 'loginHistoryPanel' + } + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.AccountPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.AccountPanel component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { +//Clipperz.log("AccountPanel.renderSelf element", this.element()); + this.append(this.element(), [ + {tag:'div', cls:'header', children:[ + {tag:'div', cls:'subPanelTabs', children:[ + {tag:'ul', children:[ +// {tag:'li', id:this.getId('accountTab'), children:[{tag:'a', href:'#', html:'Account'}], cls:'first'}, + {tag:'li', id:this.getId('passphraseTab'), children:[{tag:'a', href:'#', html:'Passphrase'}], cls:'first'}, + {tag:'li', id:this.getId('preferencesTab'), children:[{tag:'a', href:'#', html:'Preferences'}]}, + {tag:'li', id:this.getId('loginHistoryTab'), children:[{tag:'a', href:'#', html:'Login history'}]} + ]} + ]} + ]}, + {tag:'div', cls:'body', children:[ + {tag:'div', cls:'accountPanel', children:[ + {tag:'div', cls:'subPanelContent', children:[ + {tag:'ul', children:[ +// {tag:'li', id:this.getId('accountPanel'), children:[ +// {tag:'h3', html:"-- Account --"} +// ]}, + {tag:'li', id:this.getId('passphrasePanel'), children:[ + {tag:'h3', cls:'changePassphrase', html:"Change passphrase"}, + {tag:'form', id:this.getId('changePassphrase'), cls:'changePassphrase', children:[ + {tag:'div', cls:'currentCredentials', children:[ + {tag:'div', cls:'field username', children:[ + {tag:'label', html:"username", 'for':this.getId('currentUsername')}, + {tag:'input', id:this.getId('currentUsername')} + ]}, + {tag:'div', cls:'field passphrase', children:[ + {tag:'label', html:"passphrase", 'for':this.getId('currentPassphrase')}, + {tag:'input', id:this.getId('currentPassphrase')} + ]} + ]}, + {tag:'div', cls:'newPassphrase', children:[ + {tag:'div', cls:'field', children:[ + {tag:'label', html:"new passphrase", 'for':this.getId('newPassphrase')}, + {tag:'input', id:this.getId('newPassphrase')} + ]}, + {tag:'div', cls:'field', children:[ + {tag:'label', html:"re-new passphrase", 'for':this.getId('reNewPassphrase')}, + {tag:'input', id:this.getId('reNewPassphrase')} + ]} + ]}, + {tag:'div', cls:'confirm', children:[ + {tag:'input', type:'checkbox', id:this.getId('confirm')}, + {tag:'label', html:"I understand that Clipperz will not be able to recover a lost passphrase", 'for':this.getId('confirm')} + ]} + ]}, + {tag:'div', cls:'clear'}, + {tag:'div', cls:'confirmButton', id:this.getId('confirmationButton'), children:[ + {tag:'span', html:"change passphrase"} + ]}, + + {tag:'h3', cls:'manageOTP', html:"Manage One-Time Passphrases"}, + {} + ]}, + {tag:'li', id:this.getId('preferencesPanel'), children:[ + {tag:'h3', html:"-- Preferences --"} + ]}, + {tag:'li', id:this.getId('loginHistoryPanel'), children:[ + {tag:'h3', html:"-- Login History --"} + ]} + ]} + ]} + ]} + ]}, + {tag:'div', cls:'footer'} + ]); + + this.tabPanelController().setup({selected:this.initiallySelectedTab()}); + }, + + //------------------------------------------------------------------------- + + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AppPage.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AppPage.js new file mode 100644 index 0000000..67247df --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AppPage.js @@ -0,0 +1,78 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.AppPage = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.AppPage.superclass.constructor.call(this, args); + + this._element = args.element || null; + + this._slots = { + 'cardGrid' : this.getId('cardGrid'), +// 'directLoginGrid' : this.getId('directLoginGrid'), + 'accountPanel': this.getId('accountPanel'), + 'dataPanel': this.getId('dataPanel'), + 'toolsPanel': this.getId('toolsPanel'), + 'userInfoBox': this.getId('userInfoBox'), + 'tabSidePanel': this.getId('tabSidePanel') + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.AppPage, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.AppPage component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), {tag:'div', id:this.getId('userInfoBox'), cls:'userInfoBox'}); + this.append(this.element(), {tag:'div', id:this.getId('sidePanels'), cls:'sidePanels'}); + this.append(this.getId('sidePanels'), {tag:'div', id:this.getId('tabSidePanel'), cls:'tabSidePanel', children:[]}); + + this.append(this.element(), {tag:'div', id:this.getId('mainPanels'), cls:'mainPanels'}); + this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('cardGrid'), cls:'gridComponent cardGrid'}); +// this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('directLoginGrid'), cls:'gridComponent directLoginGrid'}); + this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('accountPanel'), cls:'otherPanel'}); + this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('dataPanel'), cls:'otherPanel'}); + this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('toolsPanel'), cls:'otherPanel'}); + }, + + //------------------------------------------------------------------------- + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js new file mode 100644 index 0000000..42a6052 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js @@ -0,0 +1,109 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.BookmarkletComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.BookmarkletComponent.superclass.constructor.apply(this, arguments); + MochiKit.Signal.connect(Clipperz.PM.Strings.Languages, 'switchLanguage', this, 'updateBookmarkletURLs'); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.BookmarkletComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.BookmarkletComponent component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { +// var bookmarkletUrl; +// +// if (Clipperz_IEisBroken == true) { +// bookmarkletUrl = bookmarklet_ie; +// } else { +/// bookmarkletUrl = bookmarklet; +// bookmarkletUrl = Clipperz.PM.Strings['bookmarklet']; +// } + + this.append(this.element(), {tag:'div', cls:'bookmarklet', children: [ + {tag:'div', id:this.getId('linkBlock'), cls:'bookmarklet_link', children:[ +// {tag:'a', id:this.getId('link'), href:bookmarkletUrl, children:[ + {tag:'a', id:this.getId('link'), href:'#', children:[ + {tag:'div', cls:'icon'}, + {tag:'div', cls:'text', children:[ + {tag:'span', html:"add to Clipperz"} + ]} + ]} + ]} + ]}); + + new Clipperz.PM.UI.Common.Components.Tooltip({ + element: this.getElement('linkBlock'), + text: "Drag and drop the \"add to Clipperz\" link above to the bookmark bar.", + position: 'BELOW' + }); + + MochiKit.Signal.connect(this.getId('link'), 'onclick', this, 'handleOnclick'); + this.updateBookmarkletURLs(); + }, + + //------------------------------------------------------------------------- + + 'handleOnclick': function (anEvent) { + anEvent.preventDefault(); + +Clipperz.log("BOOKMARKLET CLICK"); + }, + + //------------------------------------------------------------------------- + + 'updateBookmarkletURLs': function () { + var bookmarkletUrl; + + if (Clipperz_IEisBroken == true) { + bookmarkletUrl = bookmarklet_ie; + } else { +// bookmarkletUrl = bookmarklet; + bookmarkletUrl = Clipperz.PM.Strings.getValue('bookmarklet'); + } + + this.getElement('link').href = bookmarkletUrl; + }, + + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js new file mode 100644 index 0000000..e3238ca --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js @@ -0,0 +1,881 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.CardDialogComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.CardDialogComponent.superclass.constructor.apply(this, arguments); + + this._tabPanelController = null; + + this._tabPanelControllerConfiguration = { + 'DETAILS': { + tab: 'detailTab', + panel: 'detailTabpanel' + }, + 'DIRECT_LOGINS': { + tab: 'directLoginTab', + panel: 'directLoginTabpanel' + }, + 'SHARING': { + tab: 'sharingTab', + panel: 'sharingTabpanel' + } + }; + + this._tooltips = null; + + this._isSavingEnabled = false; + this._hintMode = 'OFF'; // 'ON' + + this._fieldComponents = {}; + this._directLoginComponents = {}; + + this._displayMode = 'fixed'; // 'scrollable'; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.CardDialogComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.CardDialogComponent component"; + }, + + //------------------------------------------------------------------------- + + 'tabPanelController': function () { + if (this._tabPanelController == null) { + this._tabPanelController = new Clipperz.PM.UI.Common.Controllers.TabPanelController({ + component:this, + configuration:this._tabPanelControllerConfiguration + }); + + MochiKit.Signal.connect(this._tabPanelController, 'tabSelected', this, 'handleTabSelected') + } + + return this._tabPanelController; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { + this.append(this.element(), {tag:'div', cls:'CardDialog mainDialog loading', id:this.getId('panel'), children: [ + {tag:'form', id:this.getId('form'), children:[ +// {tag:'input', type:'text', id:this.getId('hidden'), cls:'hidden'}, + {tag:'div', cls:'header', children:[ + {tag:'div', cls:'title', children:[ + {tag:'input', type:'text', id:this.getId('title')} + ]} + ]}, + {tag:'div', id:this.getId('body'), cls:'body', children:[ + {tag:'div', cls:'tabs', children:[ + {tag:'ul', cls:'tabs', children:[ + {tag:'li', id:this.getId('detailTab'), children:[{tag:'span', html:"details"}]}, + {tag:'li', id:this.getId('directLoginTab'), children:[ + {tag:'span', html:"direct logins"}//, +// {tag:'div', id:this.getId('addDirectLoginButton'), cls:'addDirectLoginButton', children:[ +// {tag:'span', html:"+"} +// ]} + ]}, + {tag:'li', id:this.getId('sharingTab'), children:[{tag:'span', html:"sharing"}]} + ]} + ]}, + {tag:'div', cls:'tabPanels', children:[ + {tag:'ul', cls:'tabPanels', children:[ + {tag:'li', id:this.getId('detailTabpanel'), cls:'tabPanel', children:[ + {tag:'div', id:this.getId('recordFields'), children:[ + {tag:'table', cls:'fields', cellpadding:'0', id:this.getId('fieldTable'), cellspacing:'0', children:[ + {tag:'thead', children:[ + {tag:'tr', children:[ + {tag:'th', cls:'fieldStateTH', html:""}, + {tag:'th', cls:'fieldLabelTH', html:"label"}, + {tag:'th', cls:'fieldLockTH', html:""}, + {tag:'th', cls:'fieldValueTH', html:"value"}, + {tag:'th', cls:'fieldActionTH', html:""}, + {tag:'th', cls:'fieldDeleteTH', html:""} + ]} + ]}, + {tag:'tfoot'}, + {tag:'tbody', id:this.getId('tableBody'), children:[ + {tag:'tr', id:this.getId('newFieldTR'), cls:'newFieldTR', children:[ + {tag:'td', cls:'fieldState'}, + {tag:'td', cls:'fieldLabel', children:[ + {tag:'input', cls:'label', id:this.getId('newFieldLabel')} + ]}, + {tag:'td', cls:'fieldLock', children:[ + {tag:'div', cls:'unlocked', id:this.getId('newFieldIsLocked')} + ]}, + {tag:'td', cls:'fieldValue', children:[ + {tag:'div', cls:'unlocked', id:this.getId('newFieldValueWrapper'), children:[ + {tag:'input', type:'text', cls:'value', id:this.getId('newFieldValue')} + ]} + ]}, + {tag:'td', cls:'fieldAction', children:[ + {tag:'div', html:' '} + ]}, + {tag:'td', cls:'fieldAddDelete', children:[ + {tag:'div', cls:'new', children:[ + {tag:'span', children:[ + {tag:'a', href:'#', id:this.getId('newFieldAddButton'), html:"add"} + ]} + ]} + ]} + ]} + ]} + ]} + ]}, + {tag:'div', cls:'notes', children:[ + {tag:'div', children:[ + {tag:'textarea', id:this.getId('recordNote'), value:""} + ]} + ]} + ]}, + {tag:'li', id:this.getId('directLoginTabpanel'), cls:'tabPanel', children:[ + {tag:'div', id:this.getId('directLoginsComponentContainer'), cls:'directLoginsComponentContainer', children:[ + {tag:'div', id:this.getId('directLogins'), cls:'directLogins', children:[ + {tag:'div', id:this.getId('addNewDirectLoginSplash'), cls:'addNewDirectLoginSplash', children:[ + {tag:'h3', html:"Here you can add a Direct Login for this card: instant access to your favorit website!"}, + {tag:'a', href:'#', id:this.getId('addNewDirectLoginSplashButton'), children:[{tag:'span', html:"Add Direct Login"}]} + ]}, + {tag:'div', id:this.getId('directLoginsList')}, + {tag:'div', cls:'addDirectLoginListItem', id:this.getId('addDirectLoginListItem'), children:[{tag:'a', href:'#', id:this.getId('addNewDirectLoginListItemButton'), children:[{tag:'span', html:"Add Direct Login"}]}]} + ]}, + {tag:'div', id:this.getId('directLoginEditDetail'), cls:'directLoginEditDetail'} + ]} + ]}, + {tag:'li', id:this.getId('sharingTabpanel'), cls:'tabPanel', children:[ + {tag:'h2', html:"Coming soon!"} + ]} + ]} + ]}, + {tag:'div', cls:'mask', children:[ + {tag:'div', id:this.getId('progress'), children:[ + {tag:'h3', id:this.getId('progressDescription'), cls:'progressDescription', html:"Loading"}, + {tag:'div', id:this.getId('progressBar')} + ]}, + {tag:'div', id:this.getId('error'), cls:'error', children:[ + {tag:'div', cls:'img'}, + {tag:'p', id:this.getId('errorMessage')} + ]} + ]} + ]}, + {tag:'div', cls:'footer', children:[ + {tag:'div', cls:'buttonArea', children:[ + {tag:'div', cls:'cancel', id:this.getId('cancelButton'), html:"cancel"}, + {tag:'div', cls:'save disabled', id:this.getId('saveButton'), html:"save"} + ]} + ]} + ]} + ]}); + + + this.insertAllTooltips(); + + this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); + + this.tabPanelController().setup({selected:'DETAILS'}); +// this.tabPanelController().setup({selected:'DIRECT_LOGINS'}); + + MochiKit.Style.hideElement(this.getId('error')); + MochiKit.Style.hideElement(this.getElement('directLoginEditDetail')); + MochiKit.Style.hideElement(this.getElement('addDirectLoginListItem')); + this.plumbDetailsPanel(); + + MochiKit.Signal.connect(this.getId('cancelButton'), 'onclick', this, 'handleCancelEvent'); + MochiKit.Signal.connect(this.getId('saveButton'), 'onclick', this, 'handleSaveEvent'); + + MochiKit.Signal.connect(this.getId('addNewDirectLoginSplashButton'), 'onclick', this, 'handleAddDirectLogin'); + MochiKit.Signal.connect(this.getId('addNewDirectLoginListItemButton'), 'onclick', this, 'handleAddDirectLogin'); + + MochiKit.Signal.connect(MochiKit.DOM.currentDocument().body, 'onkeydown', this, 'handleKeyEvent'); + }, + + //------------------------------------------------------------------------- + + 'displayMode': function () { + return this._displayMode; + }, + + 'setDisplayMode': function (aValue) { + this._displayMode = aValue; + }, + + //------------------------------------------------------------------------- + + 'plumbDetailsPanel': function () { + MochiKit.Signal.connect(this.getId('title'), 'onfocus', MochiKit.Base.method(this, 'handleOnFocusEvent', this.getElement('title').parentNode)); + MochiKit.Signal.connect(this.getId('title'), 'onblur', MochiKit.Base.method(this, 'handleLooseFocusEvent', this.getElement('title').parentNode)); + MochiKit.Signal.connect(this.getId('title'), 'onchange', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue')); + MochiKit.Signal.connect(this.getId('title'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue')); + + MochiKit.Signal.connect(this.getId('recordNote'), 'onfocus', MochiKit.Base.method(this, 'handleOnFocusEvent', MochiKit.Selector.findChildElements(this.element(), ['div.notes'])[0])); + MochiKit.Signal.connect(this.getId('recordNote'), 'onblur', MochiKit.Base.method(this, 'handleLooseFocusEvent', MochiKit.Selector.findChildElements(this.element(), ['div.notes'])[0])); + MochiKit.Signal.connect(this.getId('recordNote'), 'onchange', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue')); + MochiKit.Signal.connect(this.getId('recordNote'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue')); + + MochiKit.Signal.connect(this.getId('newFieldValue'), 'onkeydown', this, 'handleKeyDownOnNewFieldValue'); + + MochiKit.Signal.connect(this.getId('newFieldLabel'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue')); + MochiKit.Signal.connect(this.getId('newFieldIsLocked'), 'onclick', this, 'toggleNewFieldIsHidden'); + MochiKit.Signal.connect(this.getId('newFieldValue'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue')); + + MochiKit.Signal.connect(this.getId('newFieldAddButton'), 'onclick', this, 'handleAddClick'); + }, + + //------------------------------------------------------------------------- + + 'insertAllTooltips': function () { + var tooltips; + var tooltipEnabled; + + tooltips = {}; + tooltipEnabled = (this.hintMode() == 'ON'); + + tooltips['title'] = new Clipperz.PM.UI.Common.Components.Tooltip({ + 'element': this.getElement('title'), + 'text': "Insert here the title of the card", + 'position': 'RIGHT' + }); + this.addComponent(tooltips['title']); + MochiKit.Signal.connect(this.getId('title'), 'onfocus', MochiKit.Base.method(this, 'showTooltipOnFocus', 'title')); + MochiKit.Signal.connect(this.getId('title'), 'onblur', MochiKit.Base.method(this, 'hideTooltipOnBlur', 'title')); + + tooltips['newFieldTR'] = new Clipperz.PM.UI.Common.Components.Tooltip({ + 'element': this.getElement('newFieldTR'), + 'text': "Insert your card new values here", + 'position': 'RIGHT' + }); + this.addComponent(tooltips['newFieldTR']); + MochiKit.Signal.connect(this.getId('newFieldLabel'), 'onfocus', MochiKit.Base.method(this, 'showTooltipOnFocus', 'newFieldTR')); + MochiKit.Signal.connect(this.getId('newFieldValue'), 'onblur', MochiKit.Base.method(this, 'hideTooltipOnBlur', 'newFieldTR')); + + tooltips['recordNote'] = new Clipperz.PM.UI.Common.Components.Tooltip({ + 'element': this.getElement('recordNote'), + 'text': "You can insert some notes here", + 'position': 'RIGHT' + }); + this.addComponent(tooltips['recordNote']); + MochiKit.Signal.connect(this.getId('recordNote'), 'onfocus', MochiKit.Base.method(this, 'showTooltipOnFocus', 'recordNote')); + MochiKit.Signal.connect(this.getId('recordNote'), 'onblur', MochiKit.Base.method(this, 'hideTooltipOnBlur', 'recordNote')); + + this._tooltips = tooltips; + }, + + //......................................................................... + + 'updateAllTooltipsEnabledMode': function (aStatus) { + var tooltipLabel; + var tooltipEnabled; + + tooltipEnabled = (aStatus == 'ON') ? true : false; + + for (tooltipLabel in this.tooltips()) { + this.tooltips()[tooltipLabel].setIsEnabled(tooltipEnabled); + } + }, + + //......................................................................... + + 'tooltips': function () { + return this._tooltips; + }, + + //......................................................................... + + 'showTooltipOnFocus': function (aTooltip, anEvent) { + MochiKit.Async.callLater(0.5, MochiKit.Base.method(this.tooltips()[aTooltip], 'show')); + }, + + //......................................................................... + + 'hideTooltipOnBlur': function (aTooltip, anEvent) { + this.tooltips()[aTooltip].hide(); + }, + + //------------------------------------------------------------------------- + + 'displayElement': function() { + return this.getElement('panel'); + }, + + //------------------------------------------------------------------------- + + 'fieldComponents': function () { + return this._fieldComponents; + }, + + //------------------------------------------------------------------------- + + 'directLoginComponents': function () { + return this._directLoginComponents; + }, + + //------------------------------------------------------------------------- + + 'hintMode': function () { + return this._hintMode; + }, + + 'setHintMode': function (aValue) { + if (this._hintMode != aValue) { + this._hintMode = aValue; + + this.updateAllTooltipsEnabledMode(this._hintMode); +// if (this._hintMode == 'ON') { +// this.enableHints(); +// } + } + }, + + //------------------------------------------------------------------------- + + 'focusOnNewFieldLabel': function () { + this.getElement('newFieldLabel').focus(); + }, + + //========================================================================= + + 'isSavingEnabled': function () { + return this._isSavingEnabled; + }, + + 'setShouldEnableSaving': function (aValue) { + this._isSavingEnabled = aValue || this.newFieldHasPendingChanges(); + + if (this._isSavingEnabled == true) { + MochiKit.DOM.addElementClass(this.getElement('panel'), 'hasPendingChanges'); + MochiKit.DOM.removeElementClass(this.getId('saveButton'), 'disabled'); + } else { + MochiKit.DOM.removeElementClass(this.getElement('panel'), 'hasPendingChanges'); + MochiKit.DOM.addElementClass(this.getId('saveButton'), 'disabled'); + } + }, + + //========================================================================= + + 'title': function () { + return this.getElement('title').value; + }, + + 'setTitle': function (aValue) { + this.renderTitle(aValue); + }, + + //------------------------------------------------------------------------- + + 'renderTitle': function (aValue) { + this.getElement('title').value = Clipperz.Base.sanitizeString(aValue); + }, + + //------------------------------------------------------------------------- + + 'setFocusOnTitleField': function () { + this.getElement('title').focus(); + }, + + //------------------------------------------------------------------------- + + 'disableCardTitleEditing': function () { + this.getElement('title').disabled = true; + MochiKit.DOM.addElementClass(this.getElement('title').parentNode, 'disabled'); + }, + + + 'enableCardTitleEditing': function () { + this.getElement('title').disabled = false; + MochiKit.DOM.removeElementClass(this.getElement('title').parentNode, 'disabled'); + }, + + //========================================================================= + + 'notes': function () { + return this.getElement('recordNote').value; + }, + + 'setNotes': function (aValue) { + this.renderNotes(aValue); + }, + + //------------------------------------------------------------------------- + + 'renderNotes': function (aValue) { + var noteElement; + + noteElement = this.getElement('recordNote'); + + if ((aValue != null) && (typeof(aValue) != 'undefined')) { + noteElement.value = aValue; + } else { + noteElement.value = ""; + } + + this.fixNotesHeight(); + }, + + //========================================================================= + + 'addFieldRowComponent': function (aFieldComponent) { + var fieldTR; + + fieldTR = this.insertBefore(this.getElement('newFieldTR'), {tag:'tr', id:'recordFieldReferece_'+aFieldComponent.reference()}); + aFieldComponent.renderInNode(fieldTR); + this.fieldComponents()[aFieldComponent.reference()] = aFieldComponent; + }, + + //========================================================================= + + 'addDirectLoginComponent': function (aDirectLoginComponent) { + var directLoginDIV; + + if (MochiKit.Base.keys(this.directLoginComponents()).length == 0) { + this.hideNewDirectLoginSplash(); + } + + directLoginDIV = this.append(this.getElement('directLoginsList'), {tag:'div', cls:'directLoginItem'}); + aDirectLoginComponent.renderInNode(directLoginDIV); + this.directLoginComponents()[aDirectLoginComponent.reference()] = aDirectLoginComponent; + }, + + 'removeDirectLoginComponent': function (aDirectLoginComponent) { + delete this.directLoginComponents()[aDirectLoginComponent.reference()]; + aDirectLoginComponent.remove(); + + if (MochiKit.Base.keys(this.directLoginComponents()).length == 0) { + this.showNewDirectLoginSplash(); + } + }, + + //========================================================================= + + 'showNewDirectLoginSplash': function () { + MochiKit.Style.showElement(this.getElement('addNewDirectLoginSplash')); + MochiKit.Style.hideElement(this.getElement('addDirectLoginListItem')); + }, + + 'hideNewDirectLoginSplash': function () { + MochiKit.Style.hideElement(this.getElement('addNewDirectLoginSplash')); + MochiKit.Style.showElement(this.getElement('addDirectLoginListItem')); + }, + + //========================================================================= + + 'renderDirectLoginEditingComponent': function (aDirectLoginEditingComponent) { + aDirectLoginEditingComponent.renderInNode(this.getElement('directLoginEditDetail')); + }, + + 'placeDirectLoginEditingComponent': function () { + var width; + + width = MochiKit.Style.getElementDimensions(this.getElement('directLoginsComponentContainer'))['w']; + + return Clipperz.Async.callbacks("CardDialogComponent.renderDirectLoginEditingComponent", [ + MochiKit.Base.bind(function () { + MochiKit.Style.setElementPosition (this.getElement('directLoginEditDetail'), {x:width, y:-MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h']}); + MochiKit.Style.setElementDimensions(this.getElement('directLoginEditDetail'), {w:width}); + }, this), + + MochiKit.Base.noop + ], {trace:false}); + }, + + //========================================================================= + + 'newFieldLabel': function () { + return this.getElement('newFieldLabel').value; + }, + + 'setNewFieldLabel': function (aValue) { + this.getElement('newFieldLabel').value = aValue; + }, + + //------------------------------------------------------------------------- + + 'newFieldValue': function () { + return this.getElement('newFieldValue').value; + }, + + 'setNewFieldValue': function (aValue) { + this.getElement('newFieldValue').value = aValue; + }, + + //------------------------------------------------------------------------- + + 'newFieldIsHidden': function () { + return MochiKit.DOM.hasElementClass(this.getElement('newFieldIsLocked'), 'locked'); + }, + + 'setNewFieldIsHidden': function (aValue) { + MochiKit.DOM.setElementClass(this.getElement('newFieldIsLocked'), (aValue ? 'locked': 'unlocked')); + MochiKit.DOM.setElementClass(this.getElement('newFieldValueWrapper'), (aValue ? 'locked': 'unlocked')); + }, + + 'toggleNewFieldIsHidden': function (anEvent) { + anEvent.preventDefault(); + + this.setNewFieldIsHidden(! this.newFieldIsHidden()); + MochiKit.Signal.signal(this, 'changedValue'); + }, + + //------------------------------------------------------------------------- + + 'newFieldHasPendingChanges': function () { + return ((this.newFieldLabel() != '') || (this.newFieldValue() != '') || (this.newFieldIsHidden() == true)); + }, + + 'resetNewFieldInputs': function () { + this.setNewFieldLabel(''); + this.setNewFieldValue(''); + this.setNewFieldIsHidden(false); + }, + + //========================================================================= + + 'handleKeyDownOnNewFieldValue': function (anEvent) { + MochiKit.Signal.signal(this, 'keyPressed', anEvent); +/* + if ((anEvent.key().string == 'KEY_TAB') && this.newFieldHasPendingChanges()) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'addField'); + this.getElement('newFieldLabel').focus(); + } +*/ + }, + + //------------------------------------------------------------------------- + + 'handleAddClick': function (anEvent) { + anEvent.preventDefault(); + MochiKit.Signal.signal(this, 'addField'); + this.getElement('newFieldLabel').focus(); + }, + + //========================================================================= + + 'handleDeleteClick': function (aFieldKey, anEvent) { + anEvent.preventDefault(); + MochiKit.Signal.signal(this, 'deleteField', aFieldKey); + }, + + //------------------------------------------------------------------------- + + 'toggleLock': function (aFieldKey, anEvent) { + var shouldRedrawAsLocked; + var currentTRElement; + + anEvent.preventDefault(); + + currentTRElement = Clipperz.DOM.get(aFieldKey); + shouldRedrawAsLocked = (MochiKit.DOM.hasElementClass(currentTRElement, 'locked') ? false : true); + + this.renderFieldTR(currentTRElement, { + label:MochiKit.Selector.findChildElements(currentTRElement, ['td.fieldLabel input'])[0].value, + value:MochiKit.Selector.findChildElements(currentTRElement, ['td.fieldValue input'])[0].value + }, shouldRedrawAsLocked, MochiKit.DOM.hasElementClass(currentTRElement, 'new')); + }, + + //========================================================================= + + 'fixNotesHeight': function () { + var element; + + element = this.getElement('recordNote'); + + if (element.scrollHeight == 0) { + MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'fixNotesHeight')); + } else { + var textareaHeight; + + textareaHeight = Math.min(Math.max(50, element.scrollHeight), 500); + + MochiKit.Style.setElementDimensions(element, {h:textareaHeight}, 'px'); + MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'fixRendering')); + } + }, + + //------------------------------------------------------------------------- + + 'fixRendering': function () { +// var height; + var y; + var scrollHeight; + var viewportHeight; + var viewportY; + var footerElement; + var footerElementPosition; + var footerElementDimensions; + var footerComputedHeight; + +// height = MochiKit.Style.getElementDimensions(this.displayElement())['h']; + y = MochiKit.Style.getElementPosition(this.displayElement())['y']; + + footerElement = MochiKit.Selector.findChildElements(this.displayElement(), ['div.footer'])[0]; + footerElementPosition = MochiKit.Style.getElementPosition(footerElement); + footerElementDimensions = MochiKit.Style.getElementDimensions(footerElement); + footerComputedHeight = footerElementPosition['y'] + footerElementDimensions['h'] - y; + +// scrollHeight = this.displayElement().scrollHeight; + scrollHeight = footerComputedHeight; + + viewportHeight = MochiKit.Style.getViewportDimensions()['h']; + viewportY = MochiKit.Style.getViewportPosition()['y']; + + if ((y + scrollHeight) > (viewportY + viewportHeight)) { + this.setDisplayMode('scrollable'); + MochiKit.DOM.addElementClass(this.element(), 'scrollable'); + MochiKit.DOM.removeElementClass(this.element(), 'fixed'); + MochiKit.Style.setElementPosition(this.displayElement(), {y:Math.max(0, Math.min(y, (viewportY + viewportHeight) - scrollHeight))}, 'px'); + MochiKit.Visual.ScrollTo(this.displayElement(), {duration:0.5}); + } else { + this.setDisplayMode('fixed'); + MochiKit.DOM.removeElementClass(this.element(), 'scrollable'); + MochiKit.DOM.addElementClass(this.element(), 'fixed'); + } + }, + + //========================================================================= + + 'unselectCurrentSelectedItems': function () { + MochiKit.Iter.forEach(MochiKit.Selector.findChildElements(this.displayElement(), ['.selectedField']), function (anElement) { + MochiKit.DOM.removeElementClass(anElement, 'selectedField'); + }); + }, + + //========================================================================= + + 'hideProgressMask': function () { + MochiKit.DOM.removeElementClass(this.getId('panel'), 'loading'); + }, + + 'showProgressMask': function () { + this.getElement('progressDescription').innerHTML = "Saving"; + MochiKit.DOM.addElementClass(this.getId('panel'), 'loading'); + }, + + 'showError': function (anError) { +//console.log(">>> showError", anError); + MochiKit.Style.hideElement(this.getId('progress')); + this.getElement('errorMessage').innerHTML = Clipperz.PM.Strings.errorDescriptionForException(anError['message']); + MochiKit.Style.showElement(this.getId('error')); + }, + + //------------------------------------------------------------------------- + + 'cancel': function () { +/* + var deferredResult; + + deferredResult = new Clipperz.Async.Deferred("CardDialogComponent.cancel", {trace:false}); + deferredResult.addCallback(MochiKit.Base.method(this, 'isSavingEnabled')); + deferredResult.addIf([ + MochiKit.Base.method(this, 'askConfirmationForLoosingPendingChanges') + ], []); + deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Signal.signal, this, 'cancel')); + deferredResult.callback(); + + return deferredResult; +*/ + MochiKit.Signal.signal(this, 'cancel'); + }, + + 'handleCancelEvent': function (anEvent) { + anEvent.preventDefault(); + this.cancel(); + }, + + //------------------------------------------------------------------------- + + 'handleSaveEvent': function (anEvent) { + anEvent.preventDefault(); + + if (! MochiKit.DOM.hasElementClass(anEvent.src(), 'disabled')) { + MochiKit.Signal.signal(this, 'save'); + } + }, + + //------------------------------------------------------------------------- + + 'handleAddDirectLogin': function (anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'addDirectLogin'); + }, + + //------------------------------------------------------------------------- + + 'handleOnFocusEvent': function (anElement, anEvent) { + this.unselectCurrentSelectedItems(); + MochiKit.DOM.addElementClass(anElement, 'selectedField'); + }, + + 'handleLooseFocusEvent': function (anElement, anEvent) { + this.unselectCurrentSelectedItems(); + }, + + //------------------------------------------------------------------------- + + 'handleTabSelected': function (aSelectedTab) { + this.unselectCurrentSelectedItems(); + + switch (aSelectedTab) { + case 'DETAILS': +// MochiKit.Style.hideElement(this.getElement('addDirectLoginButton')); + break; + case 'DIRECT_LOGINS': +// MochiKit.Style.showElement(this.getElement('addDirectLoginButton')); + break; + case 'SHARING': +// MochiKit.Style.hideElement(this.getElement('addDirectLoginButton')); + break; + } + }, + + //------------------------------------------------------------------------- + + 'handleKeyEvent': function (anEvent) { +//console.log("####", anEvent.key().string); + if (anEvent.key().string == 'KEY_ESCAPE') { + MochiKit.Signal.signal(this, 'changedValue'); + this.cancel(); + } else if (anEvent.key().string == 'KEY_ENTER') { + if (anEvent.target().nodeName == 'TEXTAREA') { + + } else { + anEvent.preventDefault(); + } + } + }, + + //========================================================================= + + 'askConfirmationForLoosingPendingChanges': function () { + var deferredResult; + var confirmationDialog; + + confirmationDialog = new Clipperz.PM.UI.Common.Components.SimpleMessagePanel({ + title: "Alert", + text: "Should lost pending changes?", + type: 'ALERT', + buttons: [ + {text:"Cancel", result:'CANCEL', isDefault:true}, + {text:"Ok", result:'OK'} + ] + }); + + deferredResult = new Clipperz.Async.Deferred("CardDialogComponent.askConfirmationForLoosingPendingChanges", {trace:false}); +// deferredResult = confirmationDialog.deferredShow({openFromElement:anEvent.src(), onOkCloseToElement:MochiKit.DOM.currentDocument().body, onCancelCloseToElement:anEvent.src()}); + deferredResult.addMethod(confirmationDialog, 'deferredShow', { + 'openFromElement': this.getElement('cancelButton'), + 'onOkCloseToElement': null, // this.getElement('cancelButton'), + 'onCancelCloseToElement': this.getElement('cancelButton') + }); +// deferredResult.addCallback(function () { console.log("DELETE: " + anObject.toString(), anObject); }); +// deferredResult.addErrbackPass(function () { console.log("skip deletion: " + anObject.toString(), anObject); }); + deferredResult.callback(); + + return deferredResult; + }, + + //========================================================================= + + 'showDirectLoginEditingComponent': function () { + var width; + var transition; + var duration; + + width = MochiKit.Style.getElementDimensions(this.getElement('directLoginsComponentContainer'))['w']; + transition = MochiKit.Visual.Transitions.sinoidal; + duration = 1; + + return Clipperz.Async.callbacks("CardDialogComponent.showDirectLoginEditingComponent", [ + MochiKit.Base.method(this, 'disableCardTitleEditing'), + MochiKit.Base.method(this.tabPanelController(), 'disable'), + + MochiKit.Base.bind(function () { + MochiKit.Style.setElementPosition (this.getElement('directLoginEditDetail'), {x:width, y:-MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h']}); + MochiKit.Style.setElementDimensions(this.getElement('directLoginEditDetail'), {w:width}); + MochiKit.Style.showElement(this.getElement('directLoginEditDetail')); + MochiKit.Style.setOpacity(this.getElement('directLoginEditDetail'), 0); + MochiKit.Style.setElementDimensions(this.getElement('directLoginsComponentContainer'), { + h:Math.max( + MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h'], + MochiKit.Style.getElementDimensions(this.getElement('directLoginEditDetail'))['h'] + ) + }); +// MochiKit.Style.setElementDimensions(this.getElement('directLoginsComponentContainer'), {h:MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h']}); + }, this), + MochiKit.Base.partial(Clipperz.Visual.deferredAnimations, MochiKit.Visual.Parallel, [ + new MochiKit.Visual.Move(this.getElement('directLogins'), {x:-width, y:0, mode:'relative', transition:transition, sync:true}), + new MochiKit.Visual.Opacity(this.getElement('directLogins'), {from:1.0, to:0.0, transition:transition, sync:true}), + new MochiKit.Visual.Move(this.getElement('directLoginEditDetail'), {x:-width, y:0, mode:'relative', transition:transition, sync:true}), + new MochiKit.Visual.Opacity(this.getElement('directLoginEditDetail'), {from:0.0, to:1.0, transition:transition, sync:true}) + ], {duration:duration}), + + MochiKit.Base.noop + ], {trace:false}); + }, + + //------------------------------------------------------------------------- + + 'hideDirectLoginEditingComponent': function () { + var width; + var transition; + var duration; + + width = MochiKit.Style.getElementDimensions(this.getElement('directLoginsComponentContainer'))['w']; + transition = MochiKit.Visual.Transitions.sinoidal; + duration = 1; + + return Clipperz.Async.callbacks("CardDialogComponent.hideDirectLoginEditingComponent", [ + MochiKit.Base.partial(Clipperz.Visual.deferredAnimations, MochiKit.Visual.Parallel, [ + new MochiKit.Visual.Move(this.getElement('directLogins'), {x:width, y:0, mode:'relative', transition:transition, sync:true}), + new MochiKit.Visual.Opacity(this.getElement('directLogins'), {from:0.0, to:1.0, transition:transition, sync:true}), + new MochiKit.Visual.Move(this.getElement('directLoginEditDetail'), {x:width, y:0, mode:'relative', transition:transition, sync:true}), + new MochiKit.Visual.Opacity(this.getElement('directLoginEditDetail'), {from:1.0, to:0.0, transition:transition, sync:true}) + ], {duration:duration}), +// MochiKit.Base.partial(MochiKit.Visual.appear, this.getElement('addDirectLoginButton'), {duration:0.3}), + Clipperz.Async.clearResult, + MochiKit.Base.partial(MochiKit.Style.hideElement, this.getElement('directLoginEditDetail')), +// MochiKit.Base.partial(MochiKit.Style.showElement, this.getElement('directLogins')), + MochiKit.Base.partial(MochiKit.Style.setElementDimensions, this.getElement('directLoginsComponentContainer'), {h:MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h']}), + + MochiKit.Base.method(this, 'enableCardTitleEditing'), + MochiKit.Base.method(this.tabPanelController(), 'enable') + ], {trace:false}); + }, + + //========================================================================= + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js new file mode 100644 index 0000000..126c5b1 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js @@ -0,0 +1,182 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent.superclass.constructor.apply(this, arguments); + + this._reference = args.reference || Clipperz.Base.exception.raise('MandatoryParameter'); + this._faviconComponent = null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent component"; + }, + + //------------------------------------------------------------------------- + + 'reference': function () { + return this._reference; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { +//console.log(">>> CardDialogRecordDirectLoginComponent.renderSelf"); + this.append(this.element(), [ + {tag:'div', cls:'cardDialogRecordDirectLoginComponent_favicon', children:[ + {tag:'img', cls:'favicon', id:this.getId('favicon')} + ]}, + {tag:'div', cls:'cardDialogRecordDirectLoginComponent_label', children:[ + {tag:'input', id:this.getId('label'), type:'text'} + ]}, + {tag:'div', cls:'open', children:[ + {tag:'span', children:[ + {tag:'a', href:'open', id:this.getId('open'), html:' '} + ]} + ]}, + {tag:'div', cls:'edit', children:[ + {tag:'span', children:[ + {tag:'a', href:'edit', id:this.getId('edit'), html:"edit"} + ]} + ]}, + {tag:'div', cls:'delete', children:[ + {tag:'span', children:[ + {tag:'a', href:'delete', id:this.getId('delete'), html:"delete"} + ]} + ]} +/* + {tag:'td', cls:'fieldState'}, + {tag:'td', cls:'fieldLabel', children:[ + {tag:'input', cls:'label', id:this.getId('label')} + ]}, + {tag:'td', cls:'fieldLock', children:[ + {tag:'div', cls:'unlocked', id:this.getId('isHidden')} + ]}, + {tag:'td', cls:'fieldValue', children:[ + {tag:'div', cls:'unlocked', id:this.getId('valueWrapper'), children:[ + {tag:'input', type:'text', cls:'value', id:this.getId('value')} + ]} + ]}, + {tag:'td', cls:'fieldAddDelete', children:[ + {tag:'div', cls:'delete', children:[ + {tag:'span', children:[ + {tag:'a', href:'#', id:this.getId('delete'), html:"delete"} + ]} + ]} + ]} +*/ + ]); + + MochiKit.Signal.connect(this.getId('label'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue')); + MochiKit.Signal.connect(this.getId('open'), 'onclick', this, 'openDirectLogin'); + MochiKit.Signal.connect(this.getId('edit'), 'onclick', this, 'editDirectLogin'); + MochiKit.Signal.connect(this.getId('delete'), 'onclick', this, 'deleteDirectLogin'); + }, + + //------------------------------------------------------------------------- + + 'shouldShowElementWhileRendering': function () { + return false; + }, + + //------------------------------------------------------------------------- + + 'faviconComponent': function () { + if (this._faviconComponent == null) { +//console.log("created the FAVICON component"); + this._faviconComponent = new Clipperz.PM.UI.Common.Components.FaviconComponent({element:this.getId('favicon')}); + } + + return this._faviconComponent; + }, + + //========================================================================= + + 'label': function () { + return this.getElement('label').value; + }, + + 'setLabel': function (aValue) { + this.getElement('label').value = Clipperz.Base.sanitizeString(aValue); + }, + + //------------------------------------------------------------------------- + + 'favicon': function () { +// return this.getElement('favicon').src; + return this.faviconComponent().src(); + }, + + 'setFavicon': function (aValue) { +// this.getElement('favicon').src = Clipperz.Base.sanitizeString(aValue); + this.faviconComponent().setSrc(Clipperz.Base.sanitizeString(aValue)); + }, + + //========================================================================= + + 'openDirectLogin': function (anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'openDirectLogin', this.reference()); + }, + + //------------------------------------------------------------------------- + + 'editDirectLogin': function (anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'editDirectLogin', this.reference()); +//console.log("EDIT DIRECT LOGIN"); + }, + + //------------------------------------------------------------------------- + + 'deleteDirectLogin': function (anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'deleteDirectLogin', this.reference()); +//console.log("DELETE DIRECT LOGIN"); + }, + + + + //========================================================================= + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js new file mode 100644 index 0000000..c1a7c13 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js @@ -0,0 +1,190 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent.superclass.constructor.apply(this, arguments); + + this._reference = args.reference || Clipperz.Base.exception.raise('MandatoryParameter'); + this._actionType = null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { + this.append(this.element(), [ + {tag:'td', cls:'fieldState'}, + {tag:'td', cls:'fieldLabel', children:[ + {tag:'input', cls:'label', id:this.getId('label')} + ]}, + {tag:'td', cls:'fieldLock', children:[ + {tag:'div', cls:'unlocked', id:this.getId('isHidden')} + ]}, + {tag:'td', cls:'fieldValue', children:[ + {tag:'div', cls:'unlocked', id:this.getId('valueWrapper'), children:[ + {tag:'input', type:'text', cls:'value', id:this.getId('value')} + ]} + ]}, + {tag:'td', cls:'fieldAction', children:[ + {tag:'a', href:'#', id:this.getId('actionLink'), html:' '} + ]}, + {tag:'td', cls:'fieldAddDelete', children:[ + {tag:'div', cls:'delete', children:[ + {tag:'span', children:[ + {tag:'a', href:'#', id:this.getId('delete'), html:"delete"} + ]} + ]} + ]} + ]); + + MochiKit.Signal.connect(this.getId('label'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue')); + MochiKit.Signal.connect(this.getId('isHidden'), 'onclick', this, 'toggleIsHidden'); + MochiKit.Signal.connect(this.getId('value'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue')); + MochiKit.Signal.connect(this.getId('actionLink'), 'onclick', this, 'handleActionLink'); + MochiKit.Signal.connect(this.getId('delete'), 'onclick', this, 'deleteField'); +// MochiKit.Signal.connect(this.getId('delete'), 'onclick', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'deleteField', this.reference())); + }, + + //------------------------------------------------------------------------- + + 'shouldShowElementWhileRendering': function () { + return false; + }, + + //========================================================================= + + 'reference': function () { + return this._reference; + }, + + //========================================================================= + + 'label': function () { + return this.getElement('label').value; + }, + + 'setLabel': function (aValue) { +// this.getElement('label').value = Clipperz.Base.sanitizeString(aValue); + this.getElement('label').value = aValue; + }, + + //========================================================================= + + 'value': function () { + return this.getElement('value').value; + }, + + 'setValue': function (aValue) { +// this.getElement('value').value = Clipperz.Base.sanitizeString(aValue); + this.getElement('value').value = aValue; + }, + + //------------------------------------------------------------------------- + + 'actionType': function () { + return this._actionType; + }, + + 'setActionType': function (anActionType) { + this._actionType = anActionType; + + switch (this._actionType) { + case 'NONE': + MochiKit.Style.hideElement(this.getId('actionLink')); + MochiKit.DOM.setElementClass(this.getId('actionLink'), ''); + break; + case 'URL': + MochiKit.Style.showElement(this.getId('actionLink')); + MochiKit.DOM.setElementClass(this.getId('actionLink'), 'url'); + break; + case 'EMAIL': + MochiKit.Style.showElement(this.getId('actionLink')); + MochiKit.DOM.setElementClass(this.getId('actionLink'), 'email'); + break; + case 'PASSWORD': + MochiKit.Style.showElement(this.getId('actionLink')); + MochiKit.DOM.setElementClass(this.getId('actionLink'), 'password'); + break; + } + }, + + //========================================================================= + + 'isHidden': function () { +// return this.getElement('value').value; + return MochiKit.DOM.hasElementClass(this.getElement('isHidden'), 'locked'); + }, + + 'setIsHidden': function (aValue) { +// this.getElement('value').value = Clipperz.Base.sanitizeString(aValue); + MochiKit.DOM.setElementClass(this.getElement('isHidden'), (aValue ? 'locked': 'unlocked')); + MochiKit.DOM.setElementClass(this.getElement('valueWrapper'), (aValue ? 'locked': 'unlocked')); + }, + + 'toggleIsHidden': function (anEvent) { + anEvent.preventDefault(); + + this.setIsHidden(! this.isHidden()); + MochiKit.Signal.signal(this, 'changedValue'); + }, + + //========================================================================= + + 'handleActionLink': function (anEvent) { + anEvent.preventDefault(); + +//console.log("ACTION LINK - " + this.actionType()); + MochiKit.Signal.signal(this, 'performAction', this.reference(), anEvent.target()); + }, + + //========================================================================= + + 'deleteField': function (anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'deleteField', this.reference()); + }, + + //========================================================================= + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ColumnManager.js new file mode 100644 index 0000000..bfc7e61 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ColumnManager.js @@ -0,0 +1,203 @@ +/* + +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.Components'); + +//############################################################################# + +Clipperz.PM.UI.Web.Components.ColumnManager = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.ColumnManager.superclass.constructor.call(this, args); + + this._name = args.name || Clipperz.Base.exception.raise('MandatoryParameter'); + this._selector = args.selector || Clipperz.Base.exception.raise('MandatoryParameter');; + this._label = args.label || null; + this._isSortable = args.sortable || false; + this._comparator = args.comparator || null; + this._sorted = args.sorted || 'UNSORTED'; // 'ASCENDING' | 'DESCENDING' | 'UNSORTED' + this._cssClass = args.cssClass || ''; + + this._signalIdentifiers = []; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.ColumnManager, Clipperz.PM.UI.Common.Components.BaseComponent, { + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.ColumnManager - " + this._name; + }, + + 'name': function () { + return this._name; + }, + + 'label': function () { + return this._label; + }, + + 'selector': function () { + return this._selector; + }, + + 'comparator': function() { + return this._comparator; + }, + + 'cssClass': function() { + return this._cssClass; + }, + + //------------------------------------------------------------------------- + + 'isSortable': function () { + return this._isSortable; + }, + + //------------------------------------------------------------------------- + + 'sorted': function () { + return this._sorted; + }, + + 'isSorted': function () { + return (this.sorted() != 'UNSORTED'); + }, + + 'setSorted': function(aValue) { + this._sorted = aValue; + this.updateSortIcon(); + }, + + //------------------------------------------------------------------------- + + 'signalIdentifiers': function () { + return this._signalIdentifiers; + }, + + 'resetSignalIdentifiers': function () { + this._signalIdentifiers = []; + }, + + //------------------------------------------------------------------------- + + 'disconnectRowsSignals': function () { + MochiKit.Base.map(MochiKit.Signal.disconnect, this.signalIdentifiers()); + this.resetSignalIdentifiers(); + }, + + 'connectEvent': function () { + var ident; + + ident = MochiKit.Signal.connect.apply(null, arguments); + this.signalIdentifiers().push(ident); + }, + + //------------------------------------------------------------------------- + + 'renderHeader': function(aTRElement) { + var thElement; + + thElement = Clipperz.DOM.Helper.append(aTRElement, {tag:'th', cls:(this.cssClass() + 'TH'), id:this.getId('sortLink'), children:[ + {tag:'span', html:this.label() ? this.label() : ' '} + ]}); + + if (this.isSortable()) { + Clipperz.DOM.Helper.append(thElement, {tag:'span', cls:'sortable', children:[ + {tag:'a', href:'#'/*, id:this.getId('sortLink')*/, html:' '} + ]}); + + MochiKit.DOM.addElementClass(thElement, 'sortable'); + MochiKit.Signal.connect(thElement, 'onclick', this, 'handleClickOnSortingCriteria'); + }; + + this.updateSortIcon(); + }, + + //------------------------------------------------------------------------- + + 'toggleSorting': function () { + var result; + switch (this.sorted()) { + case 'UNSORTED': + result = 'ASCENDING'; + break; + case 'ASCENDING': + result = 'DESCENDING'; + break; + case 'DESCENDING': + result = 'ASCENDING'; + break; + default: + result = 'UNSORTED'; + break; + } + + this.setSorted(result); + + return result; + }, + + //------------------------------------------------------------------------- + + 'sortElementClass': function () { + return this.sorted().toLowerCase(); + }, + + //------------------------------------------------------------------------- + + 'updateSortIcon': function () { + if (this.isSortable()) { + MochiKit.DOM.removeElementClass(this.getId('sortLink'), 'ascending'); + MochiKit.DOM.removeElementClass(this.getId('sortLink'), 'descending'); + MochiKit.DOM.removeElementClass(this.getId('sortLink'), 'unsorted'); + + MochiKit.DOM.addElementClass(this.getId('sortLink'), this.sortElementClass()); + } + }, + + //------------------------------------------------------------------------- + + 'renderCell': function(aRowElement, anObject) { + Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[{tag:'span', html:anObject[this.name()]}]}); + }, + + //----------------------------------------------------- + + 'handleClickOnSortingCriteria': function (anEvent) { + anEvent.preventDefault(); + MochiKit.Signal.signal(this, 'sort', this); + }, + + //----------------------------------------------------- + '__syntax_fix__' : 'syntax fix' + +}); + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js new file mode 100644 index 0000000..61d6ead --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js @@ -0,0 +1,71 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent.superclass.constructor.apply(this, arguments); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { + this.append(this.element(), [ + {tag:'div', cls:'createNewCardSplash', id:this.getId('button'), children:[ + {tag:'span', html:"Create New Card"} + ]} + ]); + + MochiKit.Signal.connect(this.getElement('button'), 'onclick', this, 'handleClick'); + }, + + //------------------------------------------------------------------------- + + 'handleClick': function (anEvent) { + anEvent.preventDefault(); + MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'addCard', this.element()); + }, + + //------------------------------------------------------------------------- + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js new file mode 100644 index 0000000..91d99e3 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js @@ -0,0 +1,111 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.DataPanel = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.DataPanel.superclass.constructor.apply(this, arguments); + + this._initiallySelectedTab = args.selected || 'OFFLINE_COPY'; + this._tabPanelControllerConfiguration = { + 'OFFLINE_COPY': { + tab: 'offlineCopyTab', + panel: 'offlineCopyPanel' + }, + 'SHARING': { + tab: 'sharingTab', + panel: 'sharingPanel' + }, + 'IMPORT': { + tab: 'importTab', + panel: 'importPanel' + }, + 'EXPORT': { + tab: 'exportTab', + panel: 'exportPanel' + } + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DataPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.DataPanel component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), [ + {tag:'div', cls:'header', children:[ + {tag:'div', cls:'subPanelTabs', children:[ + {tag:'ul', children:[ + {tag:'li', id:this.getId('offlineCopyTab'), children:[{tag:'a', href:'#', html:'Offline copy'}], cls:'first'}, + {tag:'li', id:this.getId('sharingTab'), children:[{tag:'a', href:'#', html:'Sharing'}]}, + {tag:'li', id:this.getId('importTab'), children:[{tag:'a', href:'#', html:'Import'}]}, + {tag:'li', id:this.getId('exportTab'), children:[{tag:'a', href:'#', html:'Export'}]} + ]} + ]} + ]}, + {tag:'div', cls:'body', children:[ + {tag:'div', cls:'accountPanel', children:[ + {tag:'div', cls:'subPanelContent', children:[ + {tag:'ul', children:[ + {tag:'li', id:this.getId('offlineCopyPanel'), children:[ + {tag:'h3', html:"Offline copy"} + ]}, + {tag:'li', id:this.getId('sharingPanel'), children:[ + {tag:'h3', html:"Sharing"} + ]}, + {tag:'li', id:this.getId('importPanel'), children:[ + {tag:'h3', html:"Import"} + ]}, + {tag:'li', id:this.getId('exportPanel'), children:[ + {tag:'h3', html:"Export"} + ]} + ]} + ]} + ]} + ]}, + {tag:'div', cls:'footer'} + ]); + + this.tabPanelController().setup({selected:this.initiallySelectedTab()}); + }, + + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DateColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DateColumnManager.js new file mode 100644 index 0000000..3f8aa88 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DateColumnManager.js @@ -0,0 +1,72 @@ +/* + +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.Components'); + +//############################################################################# + +Clipperz.PM.UI.Web.Components.DateColumnManager = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.DateColumnManager.superclass.constructor.call(this, args); + + this._format = args.format || Clipperz.Base.exception.raise('MandatoryParameter'); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DateColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, { + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.DateColumnManager component"; + }, + + //------------------------------------------------------------------------- + + 'format': function () { + return this._format; + }, + + //------------------------------------------------------------------------- + + 'renderCell': function(aRowElement, anObject) { + Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[ + { + tag:'span', + title:Clipperz.PM.Date.formatDateWithTemplate(anObject[this.name()], "D, d M Y H:i:s"), + html:Clipperz.PM.Date.formatDateWithTemplate(anObject[this.name()], this.format()) + } + ]}); + }, + + //----------------------------------------------------- + + '__syntax_fix__' : 'syntax fix' +}); + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js new file mode 100644 index 0000000..ee60f2f --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js @@ -0,0 +1,70 @@ +/* + +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.Components'); + +//############################################################################# + +Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager.superclass.constructor.call(this, args); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager, Clipperz.PM.UI.Web.Components.LinkColumnManager, { + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager component"; + }, + + //------------------------------------------------------------------------- + + 'renderCell': function(aRowElement, anObject) { + var tdElement; + var linkElement; + + tdElement = Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[ + {tag:'div', cls:'delete', children:[ + {tag:'span', children:[ + {tag:'a', href:'delete', html:"delete"} + ]} + ]} + ]}); + + linkElement = MochiKit.DOM.getFirstElementByTagAndClassName('a', null, tdElement); +// MochiKit.Signal.connect(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject'])); + this.connectEvent(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject'])); + }, + + //----------------------------------------------------- + '__syntax_fix__' : 'syntax fix' +}); + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js new file mode 100644 index 0000000..4bf9020 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js @@ -0,0 +1,90 @@ +/* + +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.Components'); + +//############################################################################# + +Clipperz.PM.UI.Web.Components.DirectLoginColumnManager = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.DirectLoginColumnManager.superclass.constructor.call(this, args); + + this._actionMethod = args.actionMethod || null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, { + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.DateColumnManager component"; + }, + + //------------------------------------------------------------------------- + + 'actionMethod': function () { + return this._actionMethod; + }, + + //------------------------------------------------------------------------- + + 'renderCell': function(aRowElement, anObject) { + var tdElement; + var linkElement; + + tdElement = Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[ + {tag:'div', cls:'directLogin_directLogin', children:[ + {tag:'div', cls:'directLogin_directLogin_body', children:[ + {tag:'a', href:'#', html:anObject[this.name()]} + ]} + ]} + ]}); + + linkElement = MochiKit.DOM.getFirstElementByTagAndClassName('a', null, tdElement); +// MochiKit.Signal.connect(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject'])); + this.connectEvent(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject'])); + }, + + //----------------------------------------------------- + + 'handleLinkClick': function (anObject, anEvent) { + anEvent.preventDefault(); + + if (this.actionMethod() != null) { + this.actionMethod()(anObject, anEvent); + } + }, + + //----------------------------------------------------- + '__syntax_fix__' : 'syntax fix' +}); + +*/
\ No newline at end of file diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js new file mode 100644 index 0000000..9a9c0b2 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js @@ -0,0 +1,168 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent.superclass.constructor.apply(this, arguments); + + this._formFieldName = args.formFieldName || Clipperz.Base.exception.raise('MandatoryParameter'); + this._fields = args.fields || Clipperz.Base.exception.raise('MandatoryParameter'); + this._initiallySelectedFieldKey = args.selectedFieldKey || null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent component"; + }, + + //------------------------------------------------------------------------- + + 'formFieldName': function () { + return this._formFieldName; + }, + + //------------------------------------------------------------------------- + + 'fields': function () { + return this._fields; + }, + + //------------------------------------------------------------------------- + + 'selectedValue': function () { + var result; + + result = this.getElement('select').value; + + if (result == '---') { + result = null; + } + + return result; + }, + + 'initiallySelectedFieldKey': function () { + return this._initiallySelectedFieldKey; + }, + + //========================================================================= + + 'renderSelf': function() { + var initiallySelectedOptions; + + this.append(this.element(), {tag:'div', id:this.getId('div'), cls:'binding', children:[ + {tag:'span', cls:'formFieldName', html:this.formFieldName()}, + {tag:'span', cls:'fieldLock', id:this.getId('isHidden'), children:[ + {tag:'a', href:'#', id:this.getId('showHide'), html:' '} + ]}, + {tag:'input', id:this.getId('input'), cls:'formFieldExampleValue', disabled:true, value:''}, + {tag:'select', name:this.formFieldName(), id:this.getId('select'), cls:'formFieldMatchinCardField', children: + MochiKit.Base.flattenArguments( + {tag:'option', value:'---', html:"---"}, + MochiKit.Base.map( + MochiKit.Base.bind(function (aField) { return {tag:'option', value:aField['reference'], html:aField['label']}; }, this), + this.fields() + ) + ) + } + ]}); + + MochiKit.Signal.connect(this.getElement('select'), 'onchange', this, 'handleSelectChange'); + MochiKit.Signal.connect(this.getElement('showHide'), 'onclick', this, 'handleShowHide'); + + if (! MochiKit.Base.isUndefinedOrNull(this.initiallySelectedFieldKey())) { + initiallySelectedOptions = MochiKit.Selector.findChildElements(this.element(), ['option[value=' + this.initiallySelectedFieldKey() + ']']); + if (initiallySelectedOptions.length == 1) { + MochiKit.DOM.updateNodeAttributes(initiallySelectedOptions[0], {selected:true}); + this.handleSelectChange(); + } + } + }, + + //------------------------------------------------------------------------- + + 'setFieldValue': function (aValue) { + this.getElement('input').value = aValue; + }, + + 'isHidden': function () { + return MochiKit.DOM.hasElementClass(this.getElement('div'), 'locked'); + }, + + 'setIsHidden': function (aValue) { + if (aValue == true) { + MochiKit.DOM.addElementClass(this.getElement('div'), 'locked'); + MochiKit.DOM.addElementClass(this.getElement('div'), 'showLocked'); + } else { + MochiKit.DOM.removeElementClass(this.getElement('div'), 'locked'); + MochiKit.DOM.removeElementClass(this.getElement('div'), 'showLocked'); + } + }, + + 'isShowLocked': function () { + return MochiKit.DOM.hasElementClass(this.getElement('div'), 'showLocked'); + }, + + //------------------------------------------------------------------------- + + 'handleSelectChange': function (anEvent) { +// this.getElement('input').value = this.valueOfField(anEvent.src().value); + MochiKit.Signal.signal(this, 'bindChange', this); + }, + + 'handleShowHide': function (anEvent) { + anEvent.preventDefault(); + + if (this.isShowLocked()) { + MochiKit.DOM.removeElementClass(this.getElement('div'), 'showLocked'); + } else { + MochiKit.DOM.addElementClass(this.getElement('div'), 'showLocked'); + } + }, + + //========================================================================= + __syntaxFix__: "syntax fix" +}); + + + + + + + + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js new file mode 100644 index 0000000..d254c29 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js @@ -0,0 +1,481 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent.superclass.constructor.apply(this, arguments); + + this._tabPanelController = null; + + this._initiallySelectedTab = args.selected || 'TYPE'; + this._tabPanelControllerConfiguration = { + 'LABEL': { + tab: 'labelTab', + panel: 'labelTabpanel' + }, + 'TYPE': { + tab: 'typeTab', + panel: 'typeTabpanel' + }, + 'CONFIGURATION': { + tab: 'configurationTab', + panel: 'configurationTabpanel' + }, + 'BINDINGS': { + tab: 'bindingsTab', + panel: 'bindingsTabpanel' + }, + 'FAVICON': { + tab: 'faviconTab', + panel: 'faviconTabpanel' + }, + 'DONE': { + tab: 'doneTab', + panel: 'doneTabpanel' + } + }; + + this._directLoginReference = null; + + this._directLoginFavicon = null; + + this._updateFaviconCounter = 0; + this._faviconComponent = null; + + this._bindingComponents = []; + this._formValueComponents = []; + + return this; +} + +//============================================================================= + +//Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent, Clipperz.PM.UI.Common.Components.TabPanelComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent component"; + }, + + //========================================================================= + + 'directLoginReference': function () { + return this._directLoginReference; + }, + + //------------------------------------------------------------------------- + + 'setDirectLoginReference': function (aDirectLoginReference) { + this._directLoginReference = aDirectLoginReference; + + return this._directLoginReference; + }, + + //========================================================================= + + 'label': function () { + return this.getElement('label').value + }, + + 'setLabel': function (aValue) { +//console.log("##> LABEL: " + aValue); + this.getElement('label').value = (aValue ? aValue : ''); + }, + + //------------------------------------------------------------------------- + + 'favicon': function () { + return this.getElement('faviconURL').value; + }, + + 'setFavicon': function (aValue) { + var regexp; + var displayValue; + + regexp = new RegExp('^data\:\/\/.*', 'i'); + if (regexp.test(aValue)) { + displayValue = '' + } else { + displayValue = (aValue ? aValue : ''); + } + + this.getElement('faviconURL').value = displayValue; + this.faviconComponent().setSrc(aValue); + }, + +// 'setFaviconData': function (aValue) { +// this.getElement('faviconIcon').src = aValue; +// }, + + 'directLoginFavicon': function () { + return this._directLoginFavicon; + }, + + 'setDirectLoginFavicon': function (aValue) { + this._directLoginFavicon = aValue; + this.setFavicon(aValue); + }, + + //------------------------------------------------------------------------- + + 'bookmarkletConfiguration': function () { + return this.getElement('bookmarkletConfiguration').value + }, + + 'setBookmarkletConfiguration': function (aValue) { + this.getElement('bookmarkletConfiguration').value = aValue; + }, + + 'highlightConfigurationSyntaxError': function () { + MochiKit.DOM.addElementClass(this.getElement('bookmarkletConfiguration'), 'error'); + }, + + 'removeHighlightConfigurationSyntaxError': function () { + MochiKit.DOM.removeElementClass(this.getElement('bookmarkletConfiguration'), 'error'); + }, + + //========================================================================= + + 'disableAllPanels': function () { + this.getElement('label').disabled = true; + MochiKit.DOM.addElementClass(this.getElement('label').parentNode, 'disabled'); + + this.tabPanelController().selectTab(null); + }, + + //------------------------------------------------------------------------- + +// 'disableLabelField': function () { +// this.getElement('label').disabled = true; +// MochiKit.DOM.addElementClass(this.getElement('label').parentNode, 'disabled'); +// }, + + 'enableLabelField': function () { + this.getElement('label').disabled = false; + MochiKit.DOM.removeElementClass(this.getElement('label').parentNode, 'disabled'); + this.tabPanelController().selectTab('LABEL'); + }, + + //------------------------------------------------------------------------- + +// 'disableTypeField': function () { +// this.tabPanelController().selectTab(null); +// }, + + 'enableTypeField': function () { + this.tabPanelController().selectTab('TYPE'); + }, + + //------------------------------------------------------------------------- + +// 'disableConfigurationField': function () { +// this.tabPanelController().selectTab(null); +// }, + + 'enableConfigurationField': function () { + this.tabPanelController().selectTab('CONFIGURATION'); + }, + + //------------------------------------------------------------------------- + +// 'disableBindingFields': function () { +// this.tabPanelController().selectTab(null); +// }, + + 'enableBindingFields': function () { + this.tabPanelController().selectTab('BINDINGS'); + }, + + //------------------------------------------------------------------------- + +// 'disableFaviconField': function () { +// this.tabPanelController().selectTab(null); +// }, + + 'enableFaviconField': function () { + this.tabPanelController().selectTab('FAVICON'); + }, + + //------------------------------------------------------------------------- + + 'enableDonePanel': function () { + this.tabPanelController().selectTab('DONE'); + }, + + //========================================================================= + + 'shouldShowElementWhileRendering': function() { + return false; + }, + + //========================================================================= + + 'faviconComponent': function () { + if (this._faviconComponent == null) { + this._faviconComponent = new Clipperz.PM.UI.Common.Components.FaviconComponent({element:this.getId('favicon')}); + } + + return this._faviconComponent; + }, + + //========================================================================= + + 'tabPanelController': function () { + if (this._tabPanelController == null) { + this._tabPanelController = new Clipperz.PM.UI.Common.Controllers.TabPanelController({ + component:this, + configuration:this._tabPanelControllerConfiguration + }); + + MochiKit.Signal.connect(this._tabPanelController, 'tabSelected', this, 'handleTabSelected') + } + + return this._tabPanelController; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { + var bookmarkletComponent; + + this.append(this.element(), {tag:'div', cls:'directLoginEditing', id:this.getId('panel'), children: [ +// {tag:'div', cls:'back', children:[ +// {tag:'a', href:'#', id:this.getId('back'), html:" "} +// ]}, + {tag:'form', id:this.getId('form'), cls:'directLoginEditingForm', children:[ + {tag:'div', cls:'title', children:[ + {tag:'img', id:this.getId('favicon'), cls:'favicon'}, + {tag:'input', type:'text', id:this.getId('label')} //, +// {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.LABEL.description')}]}, + ]}, + {tag:'div', cls:'tabContainer', children:[ + {tag:'ul', cls:'tabs', children:[ + {tag:'li', id:this.getId('labelTab'), children:[{tag:'span', html:"label"}]}, + {tag:'li', id:this.getId('typeTab'), children:[{tag:'span', html:"type"}]}, + {tag:'li', id:this.getId('configurationTab'), children:[{tag:'span', html:"configuration"}]}, + {tag:'li', id:this.getId('bindingsTab'), children:[{tag:'span', html:"bindings"}]}, + {tag:'li', id:this.getId('faviconTab'), children:[{tag:'span', html:"favicon"}]}, + {tag:'li', id:this.getId('doneTab'), children:[{tag:'span', html:"done"}]} + ]}, + {tag:'ul', cls:'tabPanels', children:[ + {tag:'li', id:this.getId('labelTabpanel'), cls:'tabPanel label', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.LABEL.description')}]} + ]}, + {tag:'li', id:this.getId('typeTabpanel'), cls:'tabPanel type', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.TYPE.description')}]}, + {tag:'h2', html:"type"} + ]}, + {tag:'li', id:this.getId('configurationTabpanel'), cls:'tabPanel configuration', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.CONFIGURATION.description')}]}, + {tag:'div', cls:'bookmarkletConfigurationWrapper', children:[ + {tag:'textarea', id:this.getId('bookmarkletConfiguration'), value:""}, +// {tag:'div', cls:'bookmarkletComponentWrapper', children:[{tag:'div', id:this.getId('bookmarkletComponent'), cls:'bookmarkletComponent'}]} + {tag:'div', id:this.getId('bookmarkletComponent'), cls:'bookmarkletComponent'} + ]} + ]}, + {tag:'li', id:this.getId('bindingsTabpanel'), cls:'tabPanel bindings', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.BINDINGS.description')}]}, + {tag:'div', cls:'bindings', id:this.getId('bindings'), children:[]}, + {tag:'div', cls:'formValues', id:this.getId('formValues'), children:[]} + ]}, + {tag:'li', id:this.getId('faviconTabpanel'), cls:'tabPanel favicon', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.FAVICON.description')}]}, + {tag:'div', cls:'favicon', children:[ + {tag:'input', type:'text', id:this.getId('faviconURL')} + ]} + ]}, + {tag:'li', id:this.getId('doneTabpanel'), cls:'tabPanel done', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', id:this.getId('doneDescription')/*, html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.DONE.description')*/}]} + ]} + ]} + ]} + ]}, + {tag:'div', cls:'clear'} + ]}); + + bookmarkletComponent = new Clipperz.PM.UI.Web.Components.BookmarkletComponent({element:this.getElement('bookmarkletComponent')}); + bookmarkletComponent.render(); + + this.tabPanelController().setup(/*{selected:this.initiallySelectedTab()}*/); + + MochiKit.Signal.connect(this.getId('label'), 'onchange', this, 'changedValue'); + MochiKit.Signal.connect(this.getId('label'), 'onkeyup', this, 'changedValue'); + + MochiKit.Signal.connect(this.getId('bookmarkletConfiguration'), 'onchange', this, 'changedValue'); + MochiKit.Signal.connect(this.getId('bookmarkletConfiguration'), 'onkeyup', this, 'changedValue'); + + MochiKit.Signal.connect(this.getId('faviconURL'), 'onchange', this, 'changedValue'); + MochiKit.Signal.connect(this.getId('faviconURL'), 'onkeyup', this, 'changedValue'); + + MochiKit.Signal.connect(this.getId('panel'), 'onkeydown',this, 'handleKeyEvent'); + }, + + //------------------------------------------------------------------------- + + 'handleTabSelected': function (aSelectedTab) { + switch (aSelectedTab) { + case 'DETAILS': + break; + case 'DIRECT_LOGINS': + MochiKit.Style.hideElement(this.getElement('backToDirectLoginList')); + break; + case 'SHARING': + break; + } + }, + + //========================================================================= + + 'incrementUpdateFaviconCounter': function () { + this._updateFaviconCounter ++; + }, + + 'decrementUpdateFaviconCounter': function () { + this._updateFaviconCounter --; + }, + + 'updateFaviconCounter': function () { + return this._updateFaviconCounter; + }, + + //------------------------------------------------------------------------- + + 'updateFavicon': function () { + this.decrementUpdateFaviconCounter(); + + if (this.updateFaviconCounter() == 0) { + this.setFavicon(this.favicon()); + } + }, + + //========================================================================= + + 'bindingComponents': function () { + return this._bindingComponents; + }, + + 'clearAllBindingsComponents': function () { + MochiKit.Iter.forEach(this.bindingComponents(), MochiKit.Base.methodcaller('remove')); + this._bindingComponents = []; + this.getElement('bindings').innerHTML = ''; + }, + + 'addBindingComponent': function (aBindingComponent) { + this.bindingComponents().push(aBindingComponent); + aBindingComponent.renderInNode(this.append(this.getElement('bindings'), {tag:'div'})); + }, + + //========================================================================= + + 'formValueComponents': function () { + return this._formValueComponents; + }, + + 'clearAllFormValueComponents': function () { + MochiKit.Iter.forEach(this.formValueComponents(), MochiKit.Base.methodcaller('remove')); + this._formValueComponents = []; + this.getElement('formValues').innerHTML = ''; + }, + + 'addFormValueComponent': function (aFormValueComponent) { + this.formValueComponents().push(aFormValueComponent); + aFormValueComponent.renderInNode(this.append(this.getElement('formValues'), {tag:'div'})); + }, + + //========================================================================= + + 'changedValue': function (anEvent) { + MochiKit.Signal.signal(this, 'changedValue', anEvent); + + this.incrementUpdateFaviconCounter(); + MochiKit.Async.callLater(1, MochiKit.Base.method(this, 'updateFavicon')); + }, + + //------------------------------------------------------------------------- + + 'handleBackClick': function (anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'back'); + }, + + //========================================================================= + + 'bottomMargin': function () { + return MochiKit.Style.getElementPosition(this.element().parentNode)['y'] + + MochiKit.Style.getElementDimensions(this.element())['h']; + }, + + //========================================================================= + + 'focusOnLabelElement': function () { + this.getElement('label').focus(); + }, + + 'focusOnBookmarkletConfigurationElement': function () { + this.getElement('bookmarkletConfiguration').focus(); + }, + + 'focusOnFaviconElement': function () { + this.getElement('faviconURL').focus(); + }, + + //========================================================================= + + 'setDoneDescriptionWithKeys': function (someKeys) { +// {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', id:this.getId('doneDescription')/*, html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.DONE.description')*/}]} + this.getElement('doneDescription').innerHTML = Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.DONE.description', someKeys); + }, + + //========================================================================= + + 'handleKeyEvent': function (anEvent) { + MochiKit.Signal.signal(this, 'keyPressed', anEvent); +/* + if (anEvent.key().string == 'KEY_ENTER') { + if (anEvent.target().nodeName != 'TEXTAREA') { + MochiKit.Signal.signal(this, 'moveForward'); + anEvent.preventDefault(); + } + } else if (anEvent.key().string == 'KEY_TAB') { + if ((anEvent.target().nodeName == 'INPUT') || (anEvent.target().nodeName == 'TEXTAREA')) { + MochiKit.Signal.signal(this, 'moveForward'); + anEvent.preventDefault(); + } + } +*/ + }, + + //========================================================================= + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js new file mode 100644 index 0000000..b91eb98 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js @@ -0,0 +1,179 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent.superclass.constructor.apply(this, arguments); + + this._formFieldName = args.formFieldName || Clipperz.Base.exception.raise('MandatoryParameter'); + this._fieldOptions = args.fieldOptions || Clipperz.Base.exception.raise('MandatoryParameter'); + this._initialValue = args.initialValue || null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent component"; + }, + + //------------------------------------------------------------------------- + + 'formFieldName': function () { + return this._formFieldName; + }, + + //------------------------------------------------------------------------- + + 'fieldOptions': function () { + return this._fieldOptions; + }, + + 'fieldType': function () { + return this.fieldOptions()['type']; + }, + + 'optionValues': function () { + return MochiKit.Base.map(function (anOptionValue) { + return { + 'label': anOptionValue['label'] || anOptionValue['value'], + 'value': anOptionValue['value'] + } + }, this.fieldOptions()['options']); + }, + + //------------------------------------------------------------------------- + + 'selectedValue': function () { + var result; + + result = this.getElement('select').value; + + if (result == '---') { + result = null; + } + + return result; + }, + + 'initialValue': function () { + return this._initialValue; + }, + + //========================================================================= + + 'renderSelf': function() { +//console.log(">>> DirectLoginEditingFormValueComponent.renderSelf"); +//console.log("FIELD OPTIONS", this.fieldOptions()); +//console.log("OPTION VALUES", this.optionValues()); + this.append(this.element(), {tag:'div', id:this.getId('div'), cls:'formValue', children:[ + {tag:'span', cls:'formFieldName', html:this.formFieldName()}, + {tag:'div', id:this.getId('values')} + ]}); + + if ((this.fieldType() == 'radio') || (this.fieldType() == 'select')) { + this.append(this.getElement('values'), + {tag:'select', name:this.formFieldName(), id:this.getId('select'), cls:'formFieldMatchinCardField', children: + MochiKit.Base.flattenArguments( +// {tag:'option', value:'---', html:"---"}, + MochiKit.Base.map( + MochiKit.Base.bind(function (aValue) { return {tag:'option', value:aValue['value'], html:aValue['label']}; }, this), + this.optionValues() + ) + ) + } + ); + + MochiKit.Signal.connect(this.getElement('select'), 'onchange', this, 'handleSelectChange'); + + if (! MochiKit.Base.isUndefinedOrNull(this.initialValue())) { + var initiallySelectedOptions; + initiallySelectedOptions = MochiKit.Selector.findChildElements(this.element(), ['option[value=' + this.initialValue() + ']']); + if (initiallySelectedOptions.length == 1) { + MochiKit.DOM.updateNodeAttributes(initiallySelectedOptions[0], {selected:true}); + this.handleSelectChange(); + } else { + Clipperz.DOM.Helper.insertBefore(this.getElement('select').childNodes[0], {tag:'option', value:'---', html:"", selected:true}); + } + } else { + Clipperz.DOM.Helper.insertBefore(this.getElement('select').childNodes[0], {tag:'option', value:'---', html:"", selected:true}); + } + } else if (this.fieldType() == 'checkbox') { + this.append(this.getElement('values'), + {tag:'input', type:'checkbox', name:this.formFieldName(), id:this.getId('checkbox'), cls:'formFieldMatchinCardField'} + ); + + MochiKit.Signal.connect(this.getElement('checkbox'), 'onchange', this, 'handleSelectChange'); + + if (this.initialValue()) { + MochiKit.DOM.updateNodeAttributes(this.getElement('checkbox'), {checked:true}); + } + } else { + WTF = TODO; + } +//console.log("<<< DirectLoginEditingFormValueComponent.renderSelf"); + }, + + //========================================================================= + + 'handleSelectChange': function (anEvent) { +//console.log("handleSelectChange", anEvent, anEvent.src(), anEvent.src().value); + var options; + + options = {}; + + options['fieldName'] = this.formFieldName(); + + if (this.fieldType() == 'checkbox') { + options['selectedValue'] = (this.getElement('checkbox').checked ? 1 : null); + } else { + options['selectedValue'] = this.selectedValue(); + } + + MochiKit.Signal.signal(this, 'formValueChange', options); + }, + + //========================================================================= + __syntaxFix__: "syntax fix" +}); + + + + + + + + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js new file mode 100644 index 0000000..1f49575 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js @@ -0,0 +1,271 @@ +/* + +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.Components'); + +//############################################################################# + +Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager.superclass.constructor.call(this, args); + + this._enterLeaveCounter = 0; + this._selectedRowObject = null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, { + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager component"; + }, + + //------------------------------------------------------------------------- + + 'renderHeader': function(aTRElement) { + Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager.superclass.renderHeader.call(this, aTRElement); + + Clipperz.DOM.Helper.append(MochiKit.DOM.currentDocument().body, {tag:'div', cls:'DirectLoginListPopup', id:this.getId('DirectLoginListPopup'), children:[ + {tag:'div', cls:'DirectLoginListPopup_body', children:[ + {tag:'ul', id:this.getId('DirectLoginListPopup_list'), children:[ +// {tag:'li', children:[ +// {tag:'img', cls:'favicon', src:'http://www.microsoft.com/favicon.ico'}, +// {tag:'a', href:'#', html:"Google Mail"} +// ]}, +// ... + ]} + ]}, + {tag:'div', cls:'DirectLoginListPopup_footer'} + ]}); + + MochiKit.Style.hideElement(this.getId('DirectLoginListPopup')); + + // BEWARE: use MochiKit.Signal.connect instead of this.connectEvent, as the HEADER is NOT redrawn after each refresh + MochiKit.Signal.connect(this.getId('DirectLoginListPopup'), 'onmouseenter', this, 'handleDirectLoginListPopupEnter'); + MochiKit.Signal.connect(this.getId('DirectLoginListPopup'), 'onmouseleave', this, 'handleDirectLoginListPopupLeave'); + }, + + //------------------------------------------------------------------------- + + 'renderCell': function(aRowElement, anObject) { + var i,c; + var directLoginsInfo; + + directLoginsInfo = anObject[this.name()]; + + TDElement = Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:'card_directLogins'}); + + c = Math.min(2, directLoginsInfo.length); + for (i=0; i<c; i++) { + var elementID; + + elementID = 'directLogin_' + directLoginsInfo[i]['_reference']; + + Clipperz.DOM.Helper.append(TDElement, {tag:'div', cls:'card_directLogin', children:[ + {tag:'div', cls:'card_directLogin_body', children:[ + {tag:'a', href:'#', id:elementID, html:directLoginsInfo[i]['label']} + ]} + ]}); +// MochiKit.Signal.connect(elementID, 'onclick', MochiKit.Base.method(this, 'handleDirectLoginClick', directLoginsInfo[i]['_rowObject'])); + this.connectEvent(elementID, 'onclick', MochiKit.Base.method(this, 'handleDirectLoginClick', directLoginsInfo[i]['_rowObject'])); + } + + if (directLoginsInfo.length > 2) { + var ellipsesElement; + + ellipsesElement = Clipperz.DOM.Helper.append(TDElement, {tag:'div', cls:'card_directLogin_ellipses', children:[ + {tag:'div', cls:'card_directLogin_ellipses_body', children:[ + {tag:'span', html:'…'} + ]} + ]}); + +/// MochiKit.Signal.connect(ellipsesElement, 'onmouseenter', MochiKit.Base.method(this, 'handleEllipsesEnter', anObject)); +/// MochiKit.Signal.connect(ellipsesElement, 'onmouseleave', MochiKit.Base.method(this, 'handleEllipsesLeave')); +// MochiKit.Signal.connect(TDElement, 'onmouseleave', MochiKit.Base.method(this, 'handleTDLeave')); + this.connectEvent(TDElement, 'onmouseleave', MochiKit.Base.method(this, 'handleTDLeave')); + } +// MochiKit.Signal.connect(TDElement, 'onmouseenter', MochiKit.Base.method(this, 'handleTDEnter', anObject)); + this.connectEvent(TDElement, 'onmouseenter', MochiKit.Base.method(this, 'handleTDEnter', anObject)); + + }, + + //========================================================================= +/* + 'handleEllipsesEnter': function (aRecordInfo, anEvent) { + this._enterLeaveCounter ++; + if (this._enterLeaveCounter > 2) { + this._enterLeaveCounter = 2; + } + + if (this._enterLeaveCounter == 1) { + this.showDirectLoginListPopup(aRecordInfo, anEvent.src()); + } + }, + + 'handleEllipsesLeave': function (anEvent) { + this._enterLeaveCounter --; + + MochiKit.Async.callLater(0.3, MochiKit.Base.bind(function () { + if (this._enterLeaveCounter == 0) { + this.hideDirectLoginListPopup(); + } + }, this)) + }, +*/ + //------------------------------------------------------------------------- + + 'handleTDEnter': function (aRecordInfo, anEvent) { + if (MochiKit.Selector.findChildElements(anEvent.src(), ['div.card_directLogin_ellipses']).length > 0) { + this._enterLeaveCounter ++; + if (this._enterLeaveCounter > 2) { + this._enterLeaveCounter = 2; + } + + if (this._enterLeaveCounter == 1) { + this.showDirectLoginListPopup(aRecordInfo, anEvent.src()); + } + } else { + if (this._selectedRowObject != null) { + this.hideDirectLoginListPopup(); + } + } + }, + + 'handleTDLeave': function (anEvent) { + this._enterLeaveCounter --; + if (this._enterLeaveCounter < 0) { + this._enterLeaveCounter = 0; + } + + MochiKit.Async.callLater(0.3, MochiKit.Base.bind(function () { + if (this._enterLeaveCounter == 0) { + this.hideDirectLoginListPopup(); + } + }, this)) + }, + + //------------------------------------------------------------------------- + + 'handleDirectLoginListPopupEnter': function (anEvent) { + this._enterLeaveCounter ++; + if (this._enterLeaveCounter > 2) { + this._enterLeaveCounter = 2; + } + }, + + 'handleDirectLoginListPopupLeave': function (anEvent) { + this._enterLeaveCounter --; + if (this._enterLeaveCounter < 0) { + this._enterLeaveCounter = 0; + } + + MochiKit.Async.callLater(0.3, MochiKit.Base.bind(function () { + if (this._enterLeaveCounter == 0) { + this.hideDirectLoginListPopup(); + } + }, this)) + }, + + //========================================================================= + + 'showDirectLoginListPopup': function (aRecordInfo, anElement) { + var position; + var directLoginsInfo; + var directLoginsListElement; + var ellipsesElement; + + + ellipsesElement = MochiKit.Selector.findChildElements(anElement, ['div.card_directLogin_ellipses'])[0]; + position = MochiKit.Style.getElementPosition(ellipsesElement); +// position = MochiKit.Style.getElementPosition(anElement); + position.x += 14; + position.y -= 26; + + MochiKit.Style.setElementPosition(this.getId('DirectLoginListPopup'), position /*[, units='px'] */); + + directLoginsListElement = this.getElement('DirectLoginListPopup_list'); + directLoginsListElement.innerHTML = ''; + + directLoginsInfo = aRecordInfo[this.name()]; + c = directLoginsInfo.length; + for (i=0; i<c; i++) { + var elementID; + var label; + var trunkedLabel; + + label = directLoginsInfo[i]['label']; + trunkedLabel = (label.length > 20 ? label.slice(0,20) + '…' : label); + + elementID = this.getId('directLoginList_' + directLoginsInfo[i]['_reference']); + + Clipperz.DOM.Helper.append(directLoginsListElement, {tag:'li', children:[ + {tag:'div', children:[ + {tag:'img', cls:'favicon', src:directLoginsInfo[i]['favicon']}, + (label == trunkedLabel ? {tag:'a', href:'#', id:elementID, html:trunkedLabel} : {tag:'a', href:'#', id:elementID, title:label, html:trunkedLabel}) + ]} + ]}); + +// MochiKit.Signal.connect(elementID, 'onclick', MochiKit.Base.method(this, 'handleDirectLoginClick', directLoginsInfo[i]['_rowObject'])); + this.connectEvent(elementID, 'onclick', MochiKit.Base.method(this, 'handleDirectLoginClick', directLoginsInfo[i]['_rowObject'])); + } + +// MochiKit.Style.showElement(this.getId('DirectLoginListPopup')); + MochiKit.Visual.appear(this.getId('DirectLoginListPopup'), {duration:0.5}); + MochiKit.Signal.signal(this, 'selectRow', aRecordInfo); + + this._selectedRowObject = aRecordInfo; + }, + + //------------------------------------------------------------------------- + + 'hideDirectLoginListPopup': function () { + if (this._selectedRowObject != null) { + MochiKit.Signal.signal(this, 'unselectRow', this._selectedRowObject); + MochiKit.Visual.fade(this.getId('DirectLoginListPopup'), {duration:0.5}); + this._selectedRowObject = null; + this._enterLeaveCounter = 0; + } + }, + + //========================================================================= + + 'handleDirectLoginClick': function (aDirectLogin, anEvent) { + anEvent.preventDefault(); +// aDirectLogin.runDirectLogin(); + Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.openDirectLogin(aDirectLogin); + }, + + //------------------------------------------------------------------------- + + '__syntax_fix__' : 'syntax fix' + +}); + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/FaviconColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/FaviconColumnManager.js new file mode 100644 index 0000000..19d1635 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/FaviconColumnManager.js @@ -0,0 +1,89 @@ +/* + +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.Components'); + +//############################################################################# + +Clipperz.PM.UI.Web.Components.FaviconColumnManager = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.FaviconColumnManager.superclass.constructor.call(this, args); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.FaviconColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, { + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.FaviconColumnManager component"; + }, + + //------------------------------------------------------------------------- + + 'renderCell': function(aRowElement, anObject) { + var faviconImageElement; + var faviconUrl; + + faviconImageElement = this.getId('favicon'); + faviconUrl = anObject[this.name()]; + + if (faviconUrl == null) { + faviconUrl = Clipperz.PM.Strings.getValue('defaultFaviconUrl'); + } + + Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[ + {tag:'img', id:faviconImageElement, src:faviconUrl} + ]}); + + MochiKit.Signal.connect(faviconImageElement, 'onload', this, 'handleLoadedFaviconImage'); + MochiKit.Signal.connect(faviconImageElement, 'onerror', this, 'handleMissingFaviconImage'); + MochiKit.Signal.connect(faviconImageElement, 'onabort', this, 'handleMissingFaviconImage'); + }, + + //----------------------------------------------------- + + 'handleLoadedFaviconImage': function(anEvent) { + MochiKit.Signal.disconnectAllTo(anEvent.src()); + if (anEvent.src().complete == false) { + anEvent.src().src = Clipperz.PM.Strings.getValue('defaultFaviconUrl'); + } + }, + + //----------------------------------------------------- + + 'handleMissingFaviconImage': function(anEvent) { + MochiKit.Signal.disconnectAllTo(anEvent.src()); + anEvent.src().src = Clipperz.PM.Strings.getValue('defaultFaviconUrl'); + }, + + //----------------------------------------------------- + '__syntax_fix__' : 'syntax fix' +}); + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/GridComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/GridComponent.js new file mode 100644 index 0000000..8b3e6c9 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/GridComponent.js @@ -0,0 +1,262 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.GridComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.GridComponent.superclass.constructor.apply(this, arguments); + + this._columnsManagers = args.columnsManagers; + + this._rowsObjects = []; + this._noRowsGridComponent = null; + + this._slots = { + 'headerSlot': this.getId('headerSlot') + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.GridComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.GridComponent component"; + }, + + //------------------------------------------------------------------------- + + 'rows': function () { + throw Clipperz.Base.exception.AbstractMethod; +// return this._rows; + }, + + //------------------------------------------------------------------------- + + 'columnsManagers': function () { + return this._columnsManagers; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), [ + {tag:'div', cls:'header', children:[ + {tag:'form', id:this.getId('searchForm'), cls:'search', children:[ + {tag:'div', cls:'search', children:[ + {tag:'input', type:'text', id:this.getId('search'), cls:'search', placeholder:"search", name:'textToSearch'/*, value:"clipperz"*/} + ]}, + {tag:'div', cls:'clearSearchButton', id:this.getId('clearSearch')}, +// {tag:'input', type:'button', cls:'searchButton', name:'searchButton', value:"search"}, + {tag:'div', cls:'headerSlot', id:this.getId('headerSlot')} + ]} + ]}, + {tag:'div', cls:'body', children:[ + {tag:'div', cls:'rows', id:this.getId('rows'), children:[ + {tag:'table', cellpadding:'0', cellspacing:'0', cls:'rows', children:[ + {tag:'thead', children:[ + {tag:'tr', id:this.getId('thead_tr'), children:[]} + ]}, + {tag:'tbody', id:this.getId('gridRows'), children:[]} + ]} + ]}, + {tag:'div', cls:'noRowsBlock', id:this.getId('noRowsBlock'), children:[]} + ]}, + {tag:'div', cls:'footer'} + ]); + + this.renderHeader(); + MochiKit.Signal.connect(this.getId('clearSearch'), 'onclick', this, 'clearSearchHandler'); + }, + + //------------------------------------------------------------------------- + + 'renderHeader': function () { + var headerElement; + + headerElement = this.getElement('thead_tr'); + headerElement.innerHTML = ""; + + MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) { + aColumnManager.renderHeader(headerElement); + }); + }, + + //------------------------------------------------------------------------- + + 'update': function (someObjects) { + this._rowsObjects = someObjects + this.refresh(); + this.focus(); + }, + + 'focus': function () { + this.getElement('search').focus(); + }, + + //------------------------------------------------------------------------- + + 'startSearch': function () { +//console.log("--> startSearch"); + MochiKit.DOM.addElementClass(this.getElement('search'), 'running'); + }, + + 'endSearch': function () { + MochiKit.DOM.removeElementClass(this.getElement('search'), 'running'); +//console.log("<-- startSearch"); + }, + + //------------------------------------------------------------------------- + + 'disconnectColumnManagersRowsSignals': function () { + MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) { + aColumnManager.disconnectRowsSignals(); + }); + }, + + //------------------------------------------------------------------------- + + 'refresh': function () { + var gridRowsElement; + var rowClass; + + this.disconnectColumnManagersRowsSignals(); + + { + MochiKit.DOM.removeElementClass(this.getElement('search'), 'disabled'); +// MochiKit.DOM.setNodeAttribute(this.getElement('search'), 'disabled', null); + MochiKit.DOM.removeElementClass(this.element(), 'empty'); + MochiKit.DOM.removeElementClass(this.element(), 'noRows'); + } + + + gridRowsElement = this.getElement('gridRows'); + gridRowsElement.innerHTML = ""; + + MochiKit.DOM.removeElementClass(this.element(), 'empty'); + + rowClass = 'odd'; + MochiKit.Iter.forEach(this._rowsObjects, MochiKit.Base.bind(function (aRowObject) { + var cardRowElement; + + cardRowElement = this.append(gridRowsElement, {tag:'tr', id:this.getId(aRowObject['_reference']), cls:rowClass}); + MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) { + aColumnManager.renderCell(cardRowElement, aRowObject); + }); + + rowClass = (rowClass == 'odd') ? 'even' : 'odd'; + }, this)); + }, + + //----------------------------------------------------------------------------- + + 'filterElement': function () { + return this.getElement('search'); + }, + + //------------------------------------------------------------------------- + + 'shouldShowElementWhileRendering': function () { + return false; + }, + + //------------------------------------------------------------------------- + + 'selectRow': function (aRowObject) { + MochiKit.DOM.addElementClass(this.getId(aRowObject['_reference']), 'selected'); + }, + + 'unselectRow': function (aRowObject) { + MochiKit.DOM.removeElementClass(this.getId(aRowObject['_reference']), 'selected'); + }, + + //------------------------------------------------------------------------- +/* + 'passOpenDirectLogin': function(aDirectLoginReferenceId) { + MochiKit.Signal.signal(this, 'openDirectLogin', aDirectLoginReferenceId); + }, +*/ + //------------------------------------------------------------------------- + + 'clearSearchHandler': function (anEvent) { + var searchElement; + + anEvent.preventDefault(); + + searchElement = this.getElement('search'); + searchElement.value = ""; + searchElement.focus(); + }, + + //------------------------------------------------------------------------- + + 'drawEmpty': function () { + this.disconnectColumnManagersRowsSignals(); + MochiKit.DOM.addElementClass(this.getElement('search'), 'disabled'); +// MochiKit.DOM.setNodeAttribute(this.getElement('search'), 'disabled', 'disabled'); + + gridRowsElement = this.getElement('gridRows'); + gridRowsElement.innerHTML = ""; + MochiKit.DOM.addElementClass(this.element(), 'empty'); + }, + + //------------------------------------------------------------------------- + + 'setNoRowsGridComponent': function (aComponent) { + this.removeNoRowsGridComponent(); + this._noRowsGridComponent = aComponent; + + this.disconnectColumnManagersRowsSignals(); + MochiKit.DOM.addElementClass(this.getElement('search'), 'disabled'); +// MochiKit.DOM.setNodeAttribute(this.getElement('search'), 'disabled', 'disabled'); + + gridRowsElement = this.getElement('gridRows'); + gridRowsElement.innerHTML = ""; + MochiKit.DOM.addElementClass(this.element(), 'noRows'); + + if (aComponent != null) { + aComponent.renderInNode(this.getElement('noRowsBlock')); + } + }, + + 'removeNoRowsGridComponent': function () { + if (this._noRowsGridComponent != null) { + this._noRowsGridComponent.remove(); + this._noRowsGridComponent = null; + } + }, + + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ImageColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ImageColumnManager.js new file mode 100644 index 0000000..07b8dcc --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ImageColumnManager.js @@ -0,0 +1,68 @@ +/* + +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.Components'); + +//############################################################################# + +Clipperz.PM.UI.Web.Components.ImageColumnManager = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.ImageColumnManager.superclass.constructor.call(this, args); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.ImageColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, { + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.ImageColumnManager component"; + }, + + //------------------------------------------------------------------------- + + 'renderCell': function(aRowElement, anObject) { + Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[ + {tag:'img', src:anObject[this.name()]} + ]}); + +// return Clipperz.Async.callbacks("ImageColumnManager.renderCell", [ +// this.selector(), +// MochiKit.Base.bind(function (aValue) { +// Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[ +// {tag:'img', src:aValue} +// ]}); +// }, this) +// ], {trace:false}, anObject); + }, + + //----------------------------------------------------- + '__syntax_fix__' : 'syntax fix' +}); + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LinkColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LinkColumnManager.js new file mode 100644 index 0000000..e833190 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LinkColumnManager.js @@ -0,0 +1,92 @@ +/* + +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.Components'); + +//############################################################################# + +Clipperz.PM.UI.Web.Components.LinkColumnManager = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.LinkColumnManager.superclass.constructor.call(this, args); + + this._actionMethod = args.actionMethod || null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LinkColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, { + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.DateColumnManager component"; + }, + + //------------------------------------------------------------------------- + + 'actionMethod': function () { + return this._actionMethod; + }, + + //------------------------------------------------------------------------- + + 'renderCell': function(aRowElement, anObject) { + var tdElement; + var linkElement; + + tdElement = Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[ + {tag:'span', children:[ + {tag:'a', href:'#', html:anObject[this.name()]} + ]} + ]}); + + linkElement = MochiKit.DOM.getFirstElementByTagAndClassName('a', null, tdElement); +// MochiKit.Signal.connect(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject'])); + this.connectEvent(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject'])); + }, + + //----------------------------------------------------- + + 'handleLinkClick': function (anObject, anEvent) { + anEvent.preventDefault(); + + if (this.actionMethod() != null) { + var deferredResult; + + deferredResult = new Clipperz.Async.Deferred("LinkColumnManager.handleLinkClick", {trace:false}); +// deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'selectRow', anObject); + deferredResult.addCallback(this.actionMethod(), anObject, anEvent); +// deferredResult.addBothPass(MochiKit.Signal.signal, this, 'unselectRow', anObject); + deferredResult.callback(); + } + }, + + //----------------------------------------------------- + '__syntax_fix__' : 'syntax fix' +}); + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginForm.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginForm.js new file mode 100644 index 0000000..de20853 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginForm.js @@ -0,0 +1,203 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.LoginForm = function(args) { + args = args || {}; + + this._autocomplete = args.autocomplete || 'off'; + + Clipperz.PM.UI.Web.Components.LoginForm.superclass.constructor.apply(this, arguments); + + this._slots = { + 'passphraseEntropy': this.getId('passphraseEntropy') + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LoginForm, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.LoginForm component"; + }, + + 'autocomplete': function () { + return this._autocomplete; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { + this.append(this.element(), {tag:'div', id:'loginBox', children:[ + {tag:'div', cls:'header'}, + {tag:'div', cls:'body', id:this.getId('body'), children:[ + {tag:'div', id:this.getId('loginForm'), children:[ + {tag:'div', children:[ + {tag:'h4', html:'Login'}, +// {tag:'form', cls:'loginForm', autocomplete:this.autocomplete(), children:[ + {tag:'form', id:this.getId('form'), cls:'loginForm', children:[ + {tag:'label', html:'username', 'for':this.getId('usernameField')}, + {tag:'input', id:this.getId('usernameField'), type:'text', cls:'username'/*, value:'joe'*/}, + {tag:'ul', id:this.getId('passwordOptions'), children:[ + {tag:'li', id:this.getId('passphraseOption'), children:[ + {tag:'label', html:'passphrase / OTP', 'for':this.getId('passphraseField')}, + {tag:'input', id:this.getId('passphraseField'), type:'password', cls:'password'/*, value:'clipperz'*/} + ]} // , +/* + {tag:'li', id:this.getId('otpOption'), children:[ + {tag:'label', html:'one-time password', 'for':this.getId('otpField_1')}, + {tag:'input', id:this.getId('otpField_1'), type:'text', cls:'otp', value:'abcd-efgh'}, + {tag:'input', id:this.getId('otpField_2'), type:'text', cls:'otp', value:'abcd-efgh'}, + {tag:'input', id:this.getId('otpField_3'), type:'text', cls:'otp', value:'abcd-efgh'}, + {tag:'input', id:this.getId('otpField_4'), type:'text', cls:'otp', value:'abcd-efgh'} + ]} +*/ + ]}, +// {tag:'input', id:this.getId('otpCheckbox'), type:'checkbox', cls:'checkbox'}, +// {tag:'label', html:'use a one-time passphrase', 'for':this.getId('otpCheckbox'), cls:'checkbox'}, + + {tag:'div', cls:'translations', children:[ + {tag:'h4', html:'choose your language'}, + {tag:'ul', children:[ + {tag:'li', cls:'selected', html:'english'}, + {tag:'li', html:'italiano'}, + {tag:'li', html:'dutch'}, + {tag:'li', html:'french'}, + {tag:'li', html:'spanish'}, + {tag:'li', html:'chinese'}, + {tag:'li', html:'japanese'}, + {tag:'li', html:'portugal'}, + {tag:'li', html:'arabic'} + ]} + ]}, + + {tag:'input', id:this.getId('submitButton'), type:'submit', value:'login', cls:'submit'} + ]} + ]} + ]} + ]}, + {tag:'div', cls:'footer'} + ]}); + + if (this.autocomplete() == 'off') { + MochiKit.DOM.updateNodeAttributes(this.getElement('form'), {autocomplete:'off'}); + } + +// Clipperz.Style.setBackgroundGradient(this.getElement('body'), {from:"#ff9955", to:"#ff6622"}) + +// this.setEntropyDisplay(new Clipperz.PM.UI.Common.Components.PasswordEntropyDisplay(this.getElement('passphraseField'))); + +// MochiKit.Signal.connect(this.getId('otpCheckbox'), 'onclick', this, 'togglePasswordFields'); +// this.showPassphraseField(); + + this.getElement('usernameField').focus(); + + MochiKit.Signal.connect(this.getElement('loginForm'), 'onsubmit', this, 'loginEventHandler'); + }, + + //----------------------------------------------------------------------------- +/* + 'togglePasswordFields': function(anEvent) { + var shouldUseOTP; + + shouldUseOTP = this.getElement('otpCheckbox').checked; + + if (shouldUseOTP == false) { + this.showPassphraseField(); + } else { + this.showOTPFields(); + } + }, +*/ + //----------------------------------------------------------------------------- +/* + 'showPassphraseField': function() { + this.showElement('passphraseOption'); + this.hideElement('otpOption'); + }, +*/ + //----------------------------------------------------------------------------- + + 'focusOnPassphraseField': function () { + this.getElement('passphraseField').focus(); + this.getElement('passphraseField').select(); + }, + + //----------------------------------------------------------------------------- +/* + 'showOTPFields': function() { + this.hideElement('passphraseOption'); + this.showElement('otpOption'); + }, +*/ + //------------------------------------------------------------------------- + + 'loginEventHandler': function(anEvent) { + var username; + var passphrase; +// var shouldUseOTP; +// var otp; + var signalArguments; + + anEvent.preventDefault(); + + username = this.getElement('usernameField').value; + passphrase = this.getElement('passphraseField').value; +// otp = this.getElement('otpField_1').value + +// this.getElement('otpField_2').value + +// this.getElement('otpField_3').value + +// this.getElement('otpField_4').value; +// shouldUseOTP = this.getElement('otpCheckbox').checked; + + signalArguments = {username:username}; + +// if (shouldUseOTP) { +// signalArguments.otp = otp; +// } else { + signalArguments.passphrase = passphrase; +// } + + MochiKit.Signal.signal(this, 'doLogin', signalArguments); + }, + + //------------------------------------------------------------------------- + + 'submitButtonElement': function() { + return this.getElement('submitButton'); + }, + + //------------------------------------------------------------------------- + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginPage.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginPage.js new file mode 100644 index 0000000..49c030d --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginPage.js @@ -0,0 +1,206 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.LoginPage = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.LoginPage.superclass.constructor.apply(this, arguments); + + this._slots = { + 'loginForm': this.getId('loginBoxSlot') + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LoginPage, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.LoginPage component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), [ + {tag:'div', id:this.getId('loginBoxSlot')}, + {tag:'div', id:'main', children:[ + {tag:'div', id:'featurePoints', children:[ + {tag:'table', children:[ + {tag:'tr', children:[ + {tag:'td', children:[ + {tag:'div', cls:'block', children:[ + {tag:'h3', html:'Clipperz is:'}, + {tag:'ul', children:[ + {tag:'li', html:'a secure and simple password manager'}, + {tag:'li', html:'an effective single sign-on solution'}, + {tag:'li', html:'a digital vault for your personal data'} + ]} + ]}, + {tag:'div', cls:'block', children:[ + {tag:'h3', html:'Clipperz benefits:'}, + {tag:'ul', children:[ + {tag:'li', html:'free and completely anonymous'}, + {tag:'li', html:'access it any time from any computer'}, + {tag:'li', html:'no software to download and nothing to install'}, + {tag:'li', html:'avoid keeping secrets on your PC or on paper'} + ]} + ]} + ]}, {tag:'td', children:[ + {tag:'div', cls:'block', children:[ + {tag:'h3', html:'Clipperz security:'}, + {tag:'ul', children:[ + {tag:'li', html:'your secretes are locally encrypted by your browser before being uploaded to Clipperz'}, + {tag:'li', html:'the encryption key is a passphrase known only to you'}, + {tag:'li', html:'Clipperz hosts your sensitive data in an encrypted form and could never access the data in its plain form'}, + {tag:'li', html:'Clipperz is built upon standard encryption schemes, nothing fancies of homemade'}, + {tag:'li', html:'you can review the source code anytime you like, but you need to know nothing about cryptography to be an happy user!'} + ]} + ]} + ]} + ]} + ]} + ]}, + {tag:'div', cls:'activeFeatures', children:[ + {tag:'div', id:this.getId('registerButton'), cls:'createAccountLink', children:[ + {tag:'canvas', id:this.getId('registerButtonIcon')}, + {tag:'a', href:'#', id:this.getId('createAccountLink'), cls:'createAccountLink', children:[ + {tag:'span', cls:'payoff', html:"Free sign up!"}, + {tag:'span', cls:'link', html:"Create account >>"} + ]} + ]}, + {tag:'div', cls:'keepTogether', children:[ + {tag:'div', id:this.getId('screenshotLink'), cls:'screenshotLink', children:[ + {tag:'canvas', id:this.getId('lookIcon')}, + {tag:'a', href:'#', cls:'screenshotLink', children:[ + {tag:'span', cls:'payoff', html:"Look Clipperz!"}, + {tag:'span', cls:'link', html:"screenshot tour >>"} + ]} + ]}, + {tag:'div', id:this.getId('offlineLink'), cls:'offlineLink', children:[ + {tag:'canvas', id:this.getId('downloadIcon')}, + {tag:'a', href:'#', cls:'offlineLink', children:[ + {tag:'span', cls:'payoff', html:"Download!"}, + {tag:'span', cls:'link', html:"Offline version >>"} + ]} + ]} + ]} + ]} + ]} + ]); + + this.setRegistrationButtonIconDefaultColors(); + this.setLookIconDefaultColors(); + this.setDownloadIconDefaultColors(); + +// MochiKit.Signal.connect(this.getElement('createAccountLink'), 'onclick', this, 'handleCreateAccountLink') + + MochiKit.Signal.connect(this.getElement('registerButton'), 'onmouseenter', this, 'handleMouseEnterOnRegisterButtonIcon'); + MochiKit.Signal.connect(this.getElement('registerButton'), 'onmouseleave', this, 'handleMouseLeaveOnRegisterButtonIcon'); + + MochiKit.Signal.connect(this.getElement('screenshotLink'), 'onmouseenter', this, 'handleMouseEnterOnLookIcon'); + MochiKit.Signal.connect(this.getElement('screenshotLink'), 'onmouseleave', this, 'handleMouseLeaveOnLookIcon'); + + MochiKit.Signal.connect(this.getElement('offlineLink'), 'onmouseenter', this, 'handleMouseEnterOnDownloadIcon'); + MochiKit.Signal.connect(this.getElement('offlineLink'), 'onmouseleave', this, 'handleMouseLeaveOnDownloadIcon'); + + MochiKit.Signal.connect(this.getElement('createAccountLink'), 'onclick', this, 'handleCreateAccountLink') + }, + + //------------------------------------------------------------------------- + + 'setRegistrationButtonIconDefaultColors': function () { + Clipperz.PM.UI.Canvas.registerButton.normal(this.getElement('registerButtonIcon'), "#eeeeee", "#eeeeee", "#ecab12", "#e14624", "#ffffff"); + }, + + 'setRegistrationButtonIconHoverColors': function () { + Clipperz.PM.UI.Canvas.registerButton.normal(this.getElement('registerButtonIcon'), "#cccccc", "#999999", "#ffb710", "#ff4d27", "#ffffff"); + }, + + 'handleMouseEnterOnRegisterButtonIcon': function (anEvent) { + this.setRegistrationButtonIconHoverColors(); + }, + + 'handleMouseLeaveOnRegisterButtonIcon': function (anEvent) { + this.setRegistrationButtonIconDefaultColors(); + }, + + //------------------------------------------------------------------------- + + 'setLookIconDefaultColors': function () { + Clipperz.PM.UI.Canvas.coverActions.look(this.getElement('lookIcon'), "#7e7e7e", "#ffffff", 1); + }, + + 'setLookIconHoverColors': function () { + Clipperz.PM.UI.Canvas.coverActions.look(this.getElement('lookIcon'), "#666666", "#ffffff", 2); + }, + + 'handleMouseEnterOnLookIcon': function (anEvent) { + this.setLookIconHoverColors(); + }, + + 'handleMouseLeaveOnLookIcon': function (anEvent) { + this.setLookIconDefaultColors(); + }, + + //------------------------------------------------------------------------- + + 'setDownloadIconDefaultColors': function () { + Clipperz.PM.UI.Canvas.coverActions.download(this.getElement('downloadIcon'), "#7e7e7e", "#ffffff", 1); + }, + + 'setDownloadIconHoverColors': function () { + Clipperz.PM.UI.Canvas.coverActions.download(this.getElement('downloadIcon'), "#666666", "#ffffff", 2); + }, + + 'handleMouseEnterOnDownloadIcon': function (anEvent) { + this.setDownloadIconHoverColors(); + }, + + 'handleMouseLeaveOnDownloadIcon': function (anEvent) { + this.setDownloadIconDefaultColors(); + }, + + //------------------------------------------------------------------------- + + 'handleCreateAccountLink': function (anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'createNewAccountClick', anEvent.src()); + }, + + //------------------------------------------------------------------------- + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js new file mode 100644 index 0000000..03c7b9e --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js @@ -0,0 +1,155 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.LoginProgress = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.LoginProgress.superclass.constructor.apply(this, arguments); + + this._deferred = null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LoginProgress, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.LoginProgress component"; + }, + + //------------------------------------------------------------------------- + + 'deferred': function() { + return this._deferred; + }, + + 'setDeferred': function(aValue) { + this._deferred = aValue; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { +// var loginProgressElement; +// +// loginProgressElement = MochiKit.DOM.getElement('loginProgress'); +// +// if (loginProgressElement == null) { +// loginProgressElement = this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress'}, true); +// } + +//console.log(">> LoginProgress.renderSelf", this.element()); + this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress', children: [ +// this.append(loginProgressElement, [ + {tag:'div', cls:'header', children:[ + {tag:'h3', id:this.getId('title'), html:"login progress"} + ]}, + {tag:'div', cls:'body', children:[ + {tag:'div', id:this.getId('progressBar')}, + {tag:'div', id:this.getId('errorBox'), cls:'errorBox', children:[ +// {tag:'div', cls:'img ALERT', children:[{tag:'div'}]}, + {tag:'div', cls:'img ALERT', children:[{tag:'canvas', id:this.getId('canvas')}]}, + {tag:'p', html:"Login failed"} + ]} + ]}, + {tag:'div', cls:'footer', children:[ + {tag:'div', cls:'buttonArea', id:this.getId('buttonArea'), children:[ + {tag:'div', cls:'button', id:this.getId('button'), children:[ + {tag:'a', href:'#', id:this.getId('buttonLink'), html:"cancel"} + ]} + ]} + ]} + ]}); +// ]); + + Clipperz.PM.UI.Canvas.marks['!'](this.getElement('canvas'), "#ffffff"); + + this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); + MochiKit.Style.hideElement(this.getElement('errorBox')); + + MochiKit.Signal.connect(this.getId('buttonLink'), 'onclick', this, 'cancelEventHandler'); + }, + + //------------------------------------------------------------------------- + + 'displayElement': function() { + return MochiKit.DOM.getElement('loginProgress'); + }, + + //------------------------------------------------------------------------- + + 'cancelEventHandler': function(anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'cancelEvent'); + }, + + //------------------------------------------------------------------------- + + 'disableCancel': function() { + MochiKit.Style.hideElement(this.getElement('buttonArea')); + }, + + //------------------------------------------------------------------------- + + 'showErrorMessage': function() { + this.getElement('buttonLink').innerHTML = "close"; + + MochiKit.Style.hideElement(this.getElement('progressBar')); + + this.getElement('title').innerHTML = "Error"; + MochiKit.Style.showElement(this.getElement('errorBox')); + MochiKit.Style.showElement(this.getElement('buttonArea')); + }, + + //------------------------------------------------------------------------- + + 'deferredHideModalAndRemove': function(someParameters, aResult) { + var deferredResult; + + deferredResult = new Clipperz.Async.Deferred("LoginProgress.deferredHideModalAndRemove", {trace:false}); + deferredResult.addMethod(this, 'deferredHideModal'); + deferredResult.addMethod(this, 'remove'); + deferredResult.addCallback(function () { + return aResult; + }); + deferredResult.callback(someParameters); + + return deferredResult; + }, + + //------------------------------------------------------------------------- + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js new file mode 100644 index 0000000..b40d1f3 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js @@ -0,0 +1,430 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.NewUserCreationComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.NewUserCreationComponent.superclass.constructor.apply(this, arguments); + + this._tabPanelController = null; + + this._initiallySelectedTab = args.selected || 'CREDENTIALS'; + this._tabPanelControllerConfiguration = { + 'CREDENTIALS': { + tab: 'credentialsTab', + panel: 'credentialsTabpanel' + }, + 'CHECK_CREDENTIALS': { + tab: 'checkCredentialsTab', + panel: 'checkCredentialsTabpanel' + }, + 'TERMS_OF_SERVICE': { + tab: 'termsOfServiceTab', + panel: 'termsOfServiceTabpanel' + }, + 'CREATE_USER': { + tab: 'createUserTab', + panel: 'createUserTabpanel' + } //, +/* + 'LOGIN': { + tab: 'loginTab', + panel: 'loginTabpanel' + } +*/ + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.NewUserCreationComponent, Clipperz.PM.UI.Common.Components.TabPanelComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.NewUserCreationComponent component"; + }, + + //========================================================================= + + 'disableAllPanels': function () { + this.tabPanelController().selectTab(null); + }, + + //------------------------------------------------------------------------- + + 'enableCredentialsPanel': function () { + this.tabPanelController().selectTab('CREDENTIALS'); + }, + + 'enableCheckCredentialsPanel': function () { + this.tabPanelController().selectTab('CHECK_CREDENTIALS'); + }, + + 'enableTermsOfServicePanel': function () { + this.tabPanelController().selectTab('TERMS_OF_SERVICE'); + }, + + 'enableCreateUserPanel': function () { + this.tabPanelController().selectTab('CREATE_USER'); + }, + +// 'enableLoginPanel': function () { +// this.tabPanelController().selectTab('LOGIN'); +// }, + + //========================================================================= + + 'shouldShowElementWhileRendering': function() { + return false; + }, + + //========================================================================= + + 'tabPanelController': function () { + if (this._tabPanelController == null) { + this._tabPanelController = new Clipperz.PM.UI.Common.Controllers.TabPanelController({ + component:this, + configuration:this._tabPanelControllerConfiguration + }); + + MochiKit.Signal.connect(this._tabPanelController, 'tabSelected', this, 'handleTabSelected') + } + + return this._tabPanelController; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { +//console.log('** Clipperz.targetModalDimensionsAndPosition', Clipperz.Base.serializeJSON(Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition)); + + this.append(this.element(), {tag:'div', cls:'NewUserCreation mainDialog', id:this.getId('panel'), children: [ + {tag:'form', id:this.getId('form'), cls:'newUserCreationForm', children:[ + {tag:'div', cls:'header', children:[ + {tag:'div', cls:'title', children:[ + {tag:'h3', id:this.getId('title'), html:"Create new user"} + ]} + ]}, + {tag:'div', id:this.getId('body'), cls:'body', children:[ + {tag:'div', cls:'tabContainer', children:[ + {tag:'ul', cls:'tabs', children:[ + {tag:'li', id:this.getId('credentialsTab'), children:[{tag:'span', html:"credentials"}]}, + {tag:'li', id:this.getId('checkCredentialsTab'), children:[{tag:'span', html:"credentials check"}]}, + {tag:'li', id:this.getId('termsOfServiceTab'), children:[{tag:'span', html:"terms of service"}]}, + {tag:'li', id:this.getId('createUserTab'), children:[{tag:'span', html:"create user"}]} //, +// {tag:'li', id:this.getId('loginTab'), children:[{tag:'span', html:"login"}]}, + ]}, + {tag:'ul', cls:'tabPanels', children:[ + {tag:'li', id:this.getId('credentialsTabpanel'), cls:'tabPanel credentials', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.CREDENTIALS.description')}]}, + {tag:'ul', cls:'credentials', children:[ + {tag:'li', children:[{tag:'span', cls:'label', html:"username"}, {tag:'input', type:'text', id:this.getId('username')/*, value:'test'*/}]}, + {tag:'li', children:[{tag:'span', cls:'label', html:"passphrase"}, {tag:'input', type:'password', id:this.getId('passphrase')/*, value:'test'*/}]} + ]} + ]}, + {tag:'li', id:this.getId('checkCredentialsTabpanel'), cls:'tabPanel checkCredentials', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.CHECK_CREDENTIALS.description')}]}, + {tag:'ul', cls:'credentials', children:[ + {tag:'li', children:[{tag:'span', cls:'label', html:"re-passphrase"}, {tag:'input', type:'password', id:this.getId('re-passphrase')/*, value:'test'*/}]} + ]} + ]}, + {tag:'li', id:this.getId('termsOfServiceTabpanel'), cls:'tabPanel termsOfService', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.TERMS_OF_SERVICE.description')}]}, + {tag:'ul', cls:'termsOfService', children:[ + {tag:'li', children:[{tag:'input', type:'checkbox', id:this.getId('awareOfUnrecoverablePassphrase')/*, checked:true*/}, {tag:'label', cls:'label', 'for':this.getId('awareOfUnrecoverablePassphrase'), html:"I understand that Clipperz will not be able to recover a lost passphrase."}]}, + {tag:'li', children:[{tag:'input', type:'checkbox', id:this.getId('readTermsOfService')/*, checked:true*/}, {tag:'label', cls:'label', 'for':this.getId('readTermsOfService'), htmlString:"I have read and agreed to the <a href='http://www.clipperz.com/terms_of_service' target='_blank'>Terms of Service</a>."}]} + ]} + ]}, + {tag:'li', id:this.getId('createUserTabpanel'), cls:'tabPanel createUser', children:[ + {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.CREATE_USER.description')}]}, + {tag:'ul', cls:'createUserStates', children:[ + {tag:'li', cls:'creating', id:this.getId('creatingRegistering'), children:[{tag:'span', html:"registering user"}]}, + {tag:'li', cls:'done', id:this.getId('creatingDone'), children:[{tag:'span', html:"done"}]}, + {tag:'li', cls:'fail', id:this.getId('creatingFailed'), children:[{tag:'span', html:"fail"}]} + ]} + ]} //, +// {tag:'li', id:this.getId('loginTabpanel'), cls:'tabPanel login', children:[ +// {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.LOGIN.description')}]}, +// ]} + ]} + ]} + ]}, + {tag:'div', id:this.getId('footer'), cls:'footer', children:[ + {tag:'div', cls:'buttonArea', children:[ +// {tag:'div', cls:'cancel', id:this.getId('cancelButton'), html:"cancel"}, +// {tag:'div', cls:'save disabled', id:this.getId('saveButton'), html:"save"} + ]} + ]} + ]}, + {tag:'div', cls:'clear'} + ]}); + + this.tabPanelController().setup(); +// MochiKit.Signal.connect(this.getId('panel'), 'onkeydown', this, 'handleKeyEvent'); + MochiKit.Signal.connect(MochiKit.DOM.currentDocument().body, 'onkeydown', this, 'handleKeyEvent'); + MochiKit.Signal.connect(this.getId('awareOfUnrecoverablePassphrase'), 'onchange', this, 'handleTermsOfServiceCheckboxChange'); + MochiKit.Signal.connect(this.getId('readTermsOfService'), 'onchange', this, 'handleTermsOfServiceCheckboxChange'); + }, + + //------------------------------------------------------------------------- +/* + 'resetContent': function () { + this.getElement('username').value = ''; + this.getElement('passphrase').value = ''; + }, +*/ + //------------------------------------------------------------------------- + + 'displayElement': function() { + return this.getElement('panel'); + }, + + //------------------------------------------------------------------------- + + 'handleTabSelected': function (aSelectedTab) { +/* + switch (aSelectedTab) { + case 'DETAILS': + break; + case 'DIRECT_LOGINS': + MochiKit.Style.hideElement(this.getElement('backToDirectLoginList')); + break; + case 'SHARING': + break; + } +*/ + }, + + //========================================================================= + + 'username': function () { + return this.getElement('username').value; + }, + + 'usernameElement': function () { + return this.getElement('username'); + }, + + 'passphrase': function () { + return this.getElement('passphrase').value; + }, + + 'rePassphrase': function () { + return this.getElement('re-passphrase').value; + }, + + 'awareOfUnrecoverablePassphrase': function () { + return this.getElement('awareOfUnrecoverablePassphrase').value; + }, + + 'readTermsOfService': function () { + return this.getElement('readTermsOfService').value; + }, + + //========================================================================= +/* + 'incrementUpdateFaviconCounter': function () { + this._updateFaviconCounter ++; + }, + + 'decrementUpdateFaviconCounter': function () { + this._updateFaviconCounter --; + }, + + 'updateFaviconCounter': function () { + return this._updateFaviconCounter; + }, +*/ + //------------------------------------------------------------------------- +/* + 'updateFavicon': function () { + this.decrementUpdateFaviconCounter(); + + if (this.updateFaviconCounter() == 0) { + this.setFavicon(this.favicon()); + } + }, +*/ + //========================================================================= +/* + 'bindingComponents': function () { + return this._bindingComponents; + }, + + 'clearAllBindingsComponents': function () { + MochiKit.Iter.forEach(this.bindingComponents(), MochiKit.Base.methodcaller('remove')); + this._bindingComponents = []; + this.getElement('bindings').innerHTML = ''; + }, + + 'addBindingComponent': function (aBindingComponent) { + this.bindingComponents().push(aBindingComponent); + aBindingComponent.renderInNode(this.append(this.getElement('bindings'), {tag:'div'})); + }, +*/ + //========================================================================= +/* + 'formValueComponents': function () { + return this._formValueComponents; + }, + + 'clearAllFormValueComponents': function () { + MochiKit.Iter.forEach(this.formValueComponents(), MochiKit.Base.methodcaller('remove')); + this._formValueComponents = []; + this.getElement('formValues').innerHTML = ''; + }, + + 'addFormValueComponent': function (aFormValueComponent) { + this.formValueComponents().push(aFormValueComponent); + aFormValueComponent.renderInNode(this.append(this.getElement('formValues'), {tag:'div'})); + }, +*/ + //========================================================================= + + 'changedValue': function (anEvent) { + MochiKit.Signal.signal(this, 'changedValue', anEvent); + + this.incrementUpdateFaviconCounter(); + MochiKit.Async.callLater(1, MochiKit.Base.method(this, 'updateFavicon')); + }, + + //------------------------------------------------------------------------- + + 'handleBackClick': function (anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'back'); + }, + + //========================================================================= + + 'bottomMargin': function () { + var result; + +// TODO: WTF!!! +// result = MochiKit.Style.getElementPosition(this.element())['y'] + +// MochiKit.Style.getElementDimensions(this.element())['h']; + +// result = MochiKit.Style.getElementPosition(this.getElement('footer'))['y']; +//console.log("### bottomMargin"); +//console.log('displayElement', this.displayElement()); +//console.log('-- Clipperz.targetModalDimensionsAndPosition', Clipperz.Base.serializeJSON(Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition)); +//console.log('element', MochiKit.Style.getElementPosition('modalDialog') ['y'], MochiKit.Style.getElementDimensions('modalDialog')['h']); +// result = 450; + + result = Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition['position']['y'] + + Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition['dimensions']['h'] - + 60; + + return result; + }, + + //========================================================================= + + 'focusOnUsernameElement': function () { + MochiKit.Async.callLater(0.1, MochiKit.Base.method(this.getElement('username'), 'focus')); + }, + + 'focusOnRePassphraseElement': function () { + this.getElement('re-passphrase').focus(); + }, +/* + 'focusOnBookmarkletConfigurationElement': function () { + this.getElement('bookmarkletConfiguration').focus(); + }, + + 'focusOnFaviconElement': function () { + this.getElement('faviconURL').focus(); + }, +*/ + + //========================================================================= + + 'hideAllProgeressStates': function () { + MochiKit.Style.hideElement(this.getElement('creatingRegistering')); + MochiKit.Style.hideElement(this.getElement('creatingDone')); + MochiKit.Style.hideElement(this.getElement('creatingFailed')); + }, + + 'showProgressOnUserCreation': function () { +//Clipperz.log(">>> NewUserCreationComponent.showProgressOnUserCreation"); + this.hideAllProgeressStates(); + MochiKit.Style.showElement(this.getElement('creatingRegistering')); + }, + + 'showUserCreationDone': function () { +//Clipperz.log(">>> NewUserCreationComponent.showUserCreationDone"); + this.hideAllProgeressStates(); + MochiKit.Style.showElement(this.getElement('creatingDone')); +//Clipperz.log("<<< NewUserCreationComponent.showUserCreationDone"); + }, + + 'showUserCreationFailed': function () { +//Clipperz.log(">>> NewUserCreationComponent.showUserCreationFailed"); + this.hideAllProgeressStates(); + MochiKit.Style.showElement(this.getElement('creatingFailed')); + }, + + //========================================================================= + + 'handleKeyEvent': function (anEvent) { + MochiKit.Signal.signal(this, 'keyPressed', anEvent); +/* + if (anEvent.key().string == 'KEY_ENTER') { + if (anEvent.target().nodeName != 'TEXTAREA') { + MochiKit.Signal.signal(this, 'moveForward'); + anEvent.preventDefault(); + } + } else if (anEvent.key().string == 'KEY_TAB') { + if ((anEvent.target().nodeName == 'INPUT') || (anEvent.target().nodeName == 'TEXTAREA')) { + MochiKit.Signal.signal(this, 'moveForward'); + anEvent.preventDefault(); + } + } +*/ + }, + + 'handleTermsOfServiceCheckboxChange': function (anEvent) { + MochiKit.Signal.signal(this, 'changedValue'); + }, + + //========================================================================= + + 'clear': function () { + this.tabPanelController().selectTab(null); + Clipperz.PM.UI.Web.Components.NewUserCreationComponent.superclass.clear.apply(this, arguments); + }, + + //========================================================================= + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/Page.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/Page.js new file mode 100644 index 0000000..bed6675 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/Page.js @@ -0,0 +1,71 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.Page = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.Page.superclass.constructor.apply(this, arguments); + + this._slots = { + 'header': 'pageHeader', + 'body': 'pageBody', + 'footer': 'pageFooter' + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.Page, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.Page component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), [ + {tag:'div', id:'pageHeaderAndBody', cls:'pageHeaderAndBody', children:[ + {tag:'div', id:'pageHeader', cls:'pageHeader'}, + {tag:'div', id:'pageBody', cls:'pageBody'} + ]}, + {tag:'div', id:'pageFooter', cls:'pageFooter'} + ]); + + }, + + //------------------------------------------------------------------------- + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageFooter.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageFooter.js new file mode 100644 index 0000000..11135d8 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageFooter.js @@ -0,0 +1,71 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.PageFooter = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.PageFooter.superclass.constructor.apply(this, arguments); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.PageFooter, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.PageFooter component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), [ + {tag:'div', cls:'footerWrapper', children:[ + {tag:'div', cls:'footerContent', children:[ +// {tag:'div', cls:'footerStarIcon'}, + {tag:'canvas', id:this.getId('footerStarIcon'), cls:'footerStarIcon'}, + {tag:'span', cls:'copyright', html:'Copyright © 2009 Clipperz Srl'}, + {tag:'a', href:'http://www.clipperz.com/terms_of_service', target:'_blank', html:'terms of service'}, + {tag:'a', href:'http://www.clipperz.com/privacy_policy', target:'_blank', html:'privacy policy'}, + {tag:'span', cls:'applicationVersion', html:'application version: [1992]'} + ]} + ]} + ]); + + Clipperz.PM.UI.Canvas.star.normal(this.getElement('footerStarIcon'), "#7e7e7e"); + }, + + //------------------------------------------------------------------------- + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageHeader.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageHeader.js new file mode 100644 index 0000000..3924434 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageHeader.js @@ -0,0 +1,184 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.PageHeader = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.PageHeader.superclass.constructor.apply(this, arguments); + this._newsIsOpen = args.newsIsOpen || false; + this._animationDuration = args.animationDuration || 0.5; + + this._offset = 82; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.PageHeader, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.PageHeader component"; + }, + + //------------------------------------------------------------------------- + + 'iframeURL': function () { +// return './rss_view.html'; + return 'http://www.clipperz.com/files/clipperz.com/appTips/index.html'; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), [ + {tag:'div', id:'miscLinks', children:[ + {tag:'ul', children:[ + {tag:'li', children:[{tag:'a', id:'donateHeaderLink', stringID:'pageHeader.donation', href:'http://www.clipperz.com/donations', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.donation')}]}, + {tag:'li', children:[{tag:'a', id:'forumHeaderLink', stringID:'pageHeader.forum', href:'http://www.clipperz.com/forum', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.forum')}]}, + {tag:'li', children:[{tag:'a', id:'creditsHeaderLink', stringID:'pageHeader.credits', href:'http://www.clipperz.com/credits', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.credits')}]}, + {tag:'li', children:[{tag:'a', id:'feedbackHeaderLink', stringID:'pageHeader.feedback', href:'http://www.clipperz.com/contact', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.feedback')}]}, + {tag:'li', children:[{tag:'a', id:'helpHeaderLink', stringID:'pageHeader.help', href:'http://www.clipperz.com/support/user_guide', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.help')}]} + ]} + ]}, + {tag:'div', id:'logoFrame', children:[ + {tag:'a', href:'http://www.clipperz.com', target:'_blank', children:[{tag:'div', id:'logo'}]}, + {tag:'h5', cls:'clipperzPayoff', html:'keep it to yourself!'} + ]}, + {tag:'div', id:'news', cls:'hidden', children:[ +// {tag:'div', cls:'close', children:[ +// {tag:'a', href:'#', id:this.getId('closeTips'), html:'x'} +// ]}, + {tag:'div', id:'newsframe', children:[ + {tag:'iframe', id:this.getId('iframe'), src:this.iframeURL()} + ]}, + {tag:'div', id:this.getId('newsGrip'), cls:'grip', children:[]} + ]}, + {tag:'div', id:'featureTabs', children:[ + {tag:'table', children:[{tag:'tr', children:[ + {tag:'td', children:[{tag:'div', id:'feature_store', children:[{tag:'canvas', cls:'featureIcon', id:this.getId('storeIcon')}, {tag:'span', html:"Store and manage your password and online credentials"}]}]}, + {tag:'td', children:[{tag:'div', id:'feature_protect', children:[{tag:'canvas', cls:'featureIcon', id:this.getId('protectIcon')}, {tag:'span', html:"Protect all your sensitive data"}]}]}, + {tag:'td', children:[{tag:'div', id:'feature_directLogin', children:[{tag:'canvas', cls:'featureIcon', id:this.getId('directLoginIcon')}, {tag:'span', html:"Login to your web services without entering any username or password"}]}]}, + {tag:'td', children:[{tag:'div', id:'feature_share', children:[{tag:'canvas', cls:'featureIcon', id:this.getId('shareIcon')}, {tag:'span', html:"Share secret with family members and associates"}]}]} + ]}]} + ]} + ]); + + Clipperz.PM.UI.Canvas.features.store(this.getElement('storeIcon'), "#ffffff"); + Clipperz.PM.UI.Canvas.features.protect(this.getElement('protectIcon'), "#ffffff"); + Clipperz.PM.UI.Canvas.features.directLogin(this.getElement('directLoginIcon'), "#ffffff"); + Clipperz.PM.UI.Canvas.features.share(this.getElement('shareIcon'), "#ffffff", "#ffffff", "#ff0000"); + + MochiKit.Signal.connect(this.getElement('newsGrip'), 'onclick', this, 'toggleTips'); + MochiKit.Signal.connect(this.getElement('iframe'), 'onload', this, 'handleIframeDidLoad'); + }, + + //------------------------------------------------------------------------- + + 'switchToLoggedMode': function() { +// MochiKit.Style.addElementClass(this.element(), 'logged'); + MochiKit.Style.hideElement('featureTabs'); + }, + + //------------------------------------------------------------------------- + + 'animationDuration': function () { + return this._animationDuration; + }, + + 'offset': function () { + return this._offset; + }, + + //------------------------------------------------------------------------- + + 'isNewsOpen': function () { + return this._newsIsOpen; + }, + + 'toggleNewsIsOpen': function () { + this._newsIsOpen = !this._newsIsOpen; + }, + + 'toggleTips': function(anEvent) { + anEvent.preventDefault(); + + if (this.isNewsOpen() == true) { + MochiKit.Visual.Move(Clipperz.DOM.get('news'), { + x: 0, + y: -this.offset(), + mode: 'relative', + duration: this.animationDuration(), + beforeStart: function () { + MochiKit.DOM.setElementClass(Clipperz.DOM.get('news'), 'hiding'); + }, + afterFinish: function () { + Clipperz.DOM.get('newsframe').innerHTML = ""; + MochiKit.DOM.setElementClass(Clipperz.DOM.get('news'), 'hidden'); + } + }) + this.toggleNewsIsOpen(); + } else { + MochiKit.DOM.addElementClass('newsframe', 'loading'); + MochiKit.Visual.Move(Clipperz.DOM.get('news'), { + x: 0, + y: this.offset(), + mode: 'relative', + duration: this.animationDuration(), + beforeStart: MochiKit.Base.bind(function () { + this.append(Clipperz.DOM.get('newsframe'), {tag:'iframe', id:this.getId('iframe'), src:this.iframeURL()}); + + MochiKit.Signal.connect(this.getElement('iframe'), 'onload', this, 'handleIframeDidLoad'); + MochiKit.DOM.setElementClass(Clipperz.DOM.get('news'), 'opening'); + }, this), + afterFinish: function () { + MochiKit.DOM.setElementClass(Clipperz.DOM.get('news'), 'open'); + } + }) + this.toggleNewsIsOpen(); + } + }, + + //------------------------------------------------------------------------- + + 'handleIframeDidLoad': function (anEvent) { + if (this.isNewsOpen() == false) { + this.toggleTips(anEvent); + } + + MochiKit.DOM.removeElementClass('newsframe', 'loading'); + MochiKit.Signal.disconnectAllTo(this.getElement('iframe')); + }, + + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PasswordTooltip.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PasswordTooltip.js new file mode 100644 index 0000000..79c8d4f --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PasswordTooltip.js @@ -0,0 +1,164 @@ +/* + +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.Common.Components'); + +Clipperz.PM.UI.Web.Components.PasswordTooltip = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.PasswordTooltip.superclass.constructor.apply(this, arguments); + + this._referenceElement = args.referenceElement || Clipperz.Base.exception.raise('MandatoryParameter'); + this._text = args.text || Clipperz.Base.exception.raise('MandatoryParameter'); + + this._boxDimensions = null; + this._isVisible = false; + + this.renderSelf(); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.PasswordTooltip, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.PasswordTooltip component"; + }, + + //------------------------------------------------------------------------- + + 'referenceElement': function () { + return this._referenceElement; + }, + + //------------------------------------------------------------------------- + + 'text': function () { + return this._text; + }, + + 'setText': function (aValue) { + this._text = aValue; + }, + + //------------------------------------------------------------------------- + + 'isVisible': function () { + return this._isVisible; + }, + + 'setIsVisible': function (aValue) { + this._isVisible = aValue; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { + this.append(MochiKit.DOM.getElement('Clipperz_PM_UI_Common_Components_Tooltip_wrapperNode'), {tag:'div', id:this.getId('tooltip'), cls:'passwordTooltip', children:[ + {tag:'div', id:this.getId('body'), cls:'passwordTooltip_body', children:[ + {tag:'div', cls:'passwordTooltip_text', children:[ + {tag:'span', html:this.text()} + ]}, + {tag:'div', id:this.getId('footer'), cls:'passwordTooltip_footer'} + ]}, + {tag:'div', id:this.getId('arrow'), cls:'passwordTooltip_arrow'} + ]}); + + this._boxDimensions = MochiKit.Style.getElementDimensions(this.getId('body')); +// this._boxDimensions.h += MochiKit.Style.getElementDimensions(this.getId('footer')).h; + + MochiKit.Style.hideElement(this.displayElement()); + MochiKit.Signal.connect(this.element(), 'onmouseenter', this, 'show'); + MochiKit.Signal.connect(this.element(), 'onmouseleave', this, 'hide'); + }, + + //----------------------------------------------------- + + 'displayElement': function() { + return this.getElement('tooltip'); + }, + + //------------------------------------------------------------------------- + + 'boxDimensions': function () { + return this._boxDimensions; + }, + + //------------------------------------------------------------------------- + + 'show': function () { + var elementSizeAndPosition; + var arrowPosition; + var bodyPosition; + + if (this.isVisible() == false) { + arrowPosition = {}; + bodyPosition = {}; + + this.setIsVisible(true); + elementSizeAndPosition = Clipperz.Style.getSizeAndPosition(this.element()); + + MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:36, h:13}, 'px'); + bodyPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - this.boxDimensions().w/2); + bodyPosition.y = elementSizeAndPosition.position.y - this.boxDimensions().h - 13; + + arrowPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - 36/2); + arrowPosition.y = elementSizeAndPosition.position.y - 13; + + MochiKit.Style.setElementPosition(this.getId('body'), bodyPosition); + MochiKit.Style.setElementPosition(this.getId('arrow'), arrowPosition); + MochiKit.Visual.appear(this.displayElement(), {duration:0.4}); + } + }, + + 'hide': function () { + if (this.isVisible() == true) { + MochiKit.Visual.fade(this.displayElement(), {duration:0.4}); + this.setIsVisible(false); + } + }, + + //------------------------------------------------------------------------- +/* + 'shouldRemoveElementWhenClearningUp': function () { + return false; + }, +*/ + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" +}); + +Clipperz.PM.UI.Web.Components.PasswordTooltip.initTooltips = function () { + Clipperz.DOM.Helper.insertBefore(MochiKit.DOM.currentDocument().body.childNodes[0], {tag:'div', id:'Clipperz_PM_UI_Web_Components_PasswordTooltip_wrapperNode'}); +} + +MochiKit.DOM.addLoadEvent(Clipperz.PM.UI.Web.Components.PasswordTooltip.initTooltips); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/RulerComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/RulerComponent.js new file mode 100644 index 0000000..ab8a38c --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/RulerComponent.js @@ -0,0 +1,324 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.RulerComponent = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.RulerComponent.superclass.constructor.apply(this, arguments); + + this._translationContext = args.translationContext || Clipperz.Base.exception.raise('MandatoryParameter'); +// this._steps = args.steps || Clipperz.Base.exception.raise('MandatoryParameter'); + this._steps = args.steps; + + this._currentStep = -1; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.RulerComponent, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.RulerComponent component"; + }, + + //------------------------------------------------------------------------- + + 'resetStatus': function (args) { + args = args || {}; + + if (this.currentStep() != 0) { + var shouldAnimateTransition; + + shouldAnimateTransition = args.animateTransition || false; + + if (shouldAnimateTransition) { + this.moveToFirstStep(MochiKit.Base.method(this, 'cursorMoved')); + } else { + this._currentStep = 0; + this.cursorMoved(); + } + } + }, + + //------------------------------------------------------------------------- + + 'translationContext': function () { + return this._translationContext; + }, + + 'steps': function () { + return this._steps; + }, + + 'setSteps': function (aValue) { + this._steps = aValue; + this.renderStepsComponents(); + this.resetStatus(); + }, + + 'translatedStepDescription': function (aStep) { + return Clipperz.PM.Strings.getValue(this.translationContext() + '.' + aStep + '.' + 'name'); + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.setElement(this.append(MochiKit.DOM.currentDocument().body, [ + {tag:'div', id:this.getId('rulerWrapper'), cls:'rulerWrapper fixed', children:[ + {tag:'div', cls:'ruler', children:[ + {tag:'a', href:'#', id:this.getId('exit'), cls:'exit', html:' '}, + {tag:'a', href:'#', id:this.getId('smallPreviousButton'), cls:'smallButton previous', html:' '}, + {tag:'a', href:'#', id:this.getId('smallNextButton'), cls:'smallButton next', html:' '}, + {tag:'div', cls:'marker', id:this.getId('marker'), children:[ + {tag:'div', cls:'previous', id:this.getId('previousButton')}, + {tag:'div', cls:'markerBody'}, + {tag:'div', cls:'next', id:this.getId('nextButton')} + ]}, + {tag:'div', cls:'steps', id:this.getId('stepsFrame')}, +// {tag:'div', cls:'steps' + ' ' + 'steps_' + this.steps().length, children:[ +// {tag:'ul', id:this.getId('steps'), children:MochiKit.Base.map(MochiKit.Base.bind(function (aStep) { return {tag:'li', children:[{tag:'span', html:this.translatedStepDescription(aStep)}]}}, this), this.steps())} +// ]}, + {tag:'div', cls:'dots', id:this.getId('dotsFrame')} +// {tag:'div', cls:'dots' + ' ' + 'steps_' + this.steps().length, children:[ +// {tag:'ul', id:this.getId('dots'), children:MochiKit.Base.map(function (aStep) { return {tag:'li', children:[{tag:'span', html:'*'}]}}, this.steps())} +// ]} + ]} + ]} + ])); +//console.log("ELEMENT", this.element()); + + MochiKit.Signal.connect(this.getElement('exit'), 'onclick', this, 'handleExit'); + + MochiKit.Signal.connect(this.getElement('previousButton'), 'onclick', this, 'handlePrevious'); + MochiKit.Signal.connect(this.getElement('smallPreviousButton'), 'onclick', this, 'handlePrevious'); + + MochiKit.Signal.connect(this.getElement('nextButton'), 'onclick', this, 'handleNext'); + MochiKit.Signal.connect(this.getElement('smallNextButton'), 'onclick', this, 'handleNext'); + + this.enablePrevious(false); + this.enableNext(false); + +// this.cursorMoved(); + }, + + //......................................................................... + + 'renderStepsComponents': function () { + var stepsFrame; + var dotsFrame; + + stepsFrames = this.getElement('stepsFrame'); + MochiKit.DOM.setElementClass(stepsFrames, 'steps'); + MochiKit.DOM.addElementClass(stepsFrames, 'steps_' + this.steps().length); + + stepsFrames.innerHTML = ""; + this.append(stepsFrames, {tag:'ul', id:this.getId('steps'), children:MochiKit.Base.map( + MochiKit.Base.bind(function (aStep) { return {tag:'li', children:[{tag:'span', html:this.translatedStepDescription(aStep)}]}}, this), + this.steps())} + ); + + dotsFrames = this.getElement('dotsFrame'); + MochiKit.DOM.setElementClass(dotsFrames, 'dots'); + MochiKit.DOM.addElementClass(dotsFrames, 'steps_' + this.steps().length); + + dotsFrames.innerHTML = ""; + this.append(dotsFrames, {tag:'ul', id:this.getId('dots'), children:MochiKit.Base.map( + function (aStep) { return {tag:'li', children:[{tag:'span', html:'*'}]}; }, + this.steps())} + ); + }, + + //------------------------------------------------------------------------- + + 'handleExit': function (anEvent) { + anEvent.preventDefault(); + + MochiKit.Signal.signal(this, 'exit'); + }, + + //------------------------------------------------------------------------- + + 'handlePrevious': function (anEvent) { + anEvent.preventDefault(); + +// if (!MochiKit.DOM.hasElementClass(this.getElement('previousButton'), 'disabled')) { +// this.moveBackward(); +// } + + MochiKit.Signal.signal(this, 'moveBackward'); + }, + + 'handleNext': function (anEvent) { + anEvent.preventDefault(); + +// if (!MochiKit.DOM.hasElementClass(this.getElement('nextButton'), 'disabled')) { +// this.moveForward(); +// } + + MochiKit.Signal.signal(this, 'moveForward'); + }, + + //------------------------------------------------------------------------- + + 'currentStep': function () { + return this._currentStep; + }, + + 'markerInitialOffset': function () { + return -246; + }, + + 'markerStepOffset': function () { + return 410 / (this.steps().length - 1); +// return 100; + }, + + //------------------------------------------------------------------------- + + 'moveToFirstStep': function (aCallback) { + var stepsToMove; + + stepsToMove = this._currentStep; + this._currentStep = 0; + + this.enablePrevious(false); + this.enableNext(false); +// MochiKit.Signal.signal(this, 'moveBackward'); + MochiKit.Base.map( + function (anElement) { MochiKit.DOM.removeElementClass(anElement, 'selected'); }, + MochiKit.Selector.findChildElements(this.element(), ['li.selected']) + ); + new MochiKit.Visual.Move(this.getElement('marker'), { + x:-(this.markerStepOffset() * stepsToMove), + mode:'relative', + duration:(0.5 * (stepsToMove/2)), +// afterFinish:MochiKit.Base.method(this, 'cursorMoved') + afterFinish:MochiKit.Base.compose(MochiKit.Base.method(this, 'cursorMoved'), aCallback) + }); + }, + + 'moveBackward': function (aCallback) { + this._currentStep --; + + this.enablePrevious(false); + this.enableNext(false); +// MochiKit.Signal.signal(this, 'moveBackward'); + MochiKit.Base.map( + function (anElement) { MochiKit.DOM.removeElementClass(anElement, 'selected'); }, + MochiKit.Selector.findChildElements(this.element(), ['li.selected']) + ); + new MochiKit.Visual.Move(this.getElement('marker'), { + x:-this.markerStepOffset(), + mode:'relative', + duration:0.5, +// afterFinish:MochiKit.Base.method(this, 'cursorMoved') + afterFinish:MochiKit.Base.compose(MochiKit.Base.method(this, 'cursorMoved'), aCallback) + }); + }, + + 'moveForward': function (aCallback) { + this._currentStep ++; + + if (this._currentStep < this.steps().length) { + this.enablePrevious(false); + this.enableNext(false); +// MochiKit.Signal.signal(this, 'moveForward'); + MochiKit.Base.map( + function (anElement) { MochiKit.DOM.removeElementClass(anElement, 'selected'); }, + MochiKit.Selector.findChildElements(this.element(), ['li.selected']) + ); + new MochiKit.Visual.Move(this.getElement('marker'), { + x:this.markerStepOffset(), + mode:'relative', + duration:0.5, +// afterFinish:MochiKit.Base.method(this, 'cursorMoved') + afterFinish:MochiKit.Base.compose(MochiKit.Base.method(this, 'cursorMoved'), aCallback) + }); + } else { + MochiKit.Signal.signal(this, 'done'); + } + }, + + //------------------------------------------------------------------------- + + 'enablePrevious': function (aValue) { + if (aValue == true) { + MochiKit.DOM.removeElementClass(this.getElement('previousButton'), 'disabled'); + MochiKit.DOM.removeElementClass(this.getElement('smallPreviousButton'), 'disabled'); + } else { + MochiKit.DOM.addElementClass(this.getElement('previousButton'), 'disabled'); + MochiKit.DOM.addElementClass(this.getElement('smallPreviousButton'), 'disabled'); + } + }, + +// 'disablePrevious': function () { +// MochiKit.DOM.addElementClass(this.getElement('previousButton'), 'disabled'); +// }, + + //......................................................................... + + 'enableNext': function (aValue) { + if (aValue == true) { + MochiKit.DOM.removeElementClass(this.getElement('nextButton'), 'disabled'); + MochiKit.DOM.removeElementClass(this.getElement('smallNextButton'), 'disabled'); + } else { + MochiKit.DOM.addElementClass(this.getElement('nextButton'), 'disabled'); + MochiKit.DOM.addElementClass(this.getElement('smallNextButton'), 'disabled'); + } + }, + +// 'disableNext': function () { +// MochiKit.DOM.addElementClass(this.getElement('nextButton'), 'disabled'); +// }, + + //------------------------------------------------------------------------- + + 'cursorMoved': function () { + MochiKit.Style.setElementPosition(this.getElement('marker'), {x:this.markerStepOffset() * this.currentStep() + this.markerInitialOffset()}) + MochiKit.Signal.signal(this, 'cursorMoved'); + + MochiKit.DOM.addElementClass(this.getElement('steps').childNodes[this.currentStep()], 'selected'); + MochiKit.DOM.addElementClass(this.getElement('dots').childNodes[this.currentStep()], 'selected'); + }, + + //------------------------------------------------------------------------- + + 'setDisplayMode': function (aValue) { + MochiKit.DOM.removeElementClass(this.getElement('rulerWrapper'), 'fixed'); + MochiKit.DOM.removeElementClass(this.getElement('rulerWrapper'), 'scrollable'); + MochiKit.DOM.addElementClass(this.getElement('rulerWrapper'), aValue); + }, + + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TabSidePanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TabSidePanel.js new file mode 100644 index 0000000..39a1ccb --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TabSidePanel.js @@ -0,0 +1,193 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.TabSidePanel = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.TabSidePanel.superclass.constructor.call(this, args); + + this._element = args.element || null; + + this._slots = { + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.TabSidePanel, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.TabSidePanel component"; + }, + + //------------------------------------------------------------------------- + + 'deselectAllTabs': function() { + var tabListItems; + + tabListItems = [ + 'cardsLI', +// 'directLoginLI', + 'accountLI', + 'dataLI', + 'toolsLI' + ]; + +//Clipperz.log("=== TabSidePanel.tabSelected anEvent.src().id", anEvent.src().id); + for (var i in tabListItems) { +//Clipperz.log("=== TabSidePanel.tabSelected aTabListItem", tabListItems[i]); + MochiKit.DOM.removeElementClass(this.getId(tabListItems[i]), 'selected'); + } + }, + + 'selectTab': function(aTabName) { + this.deselectAllTabs(); + MochiKit.DOM.addElementClass(this.getId(this.listItemIdForTabNamed(aTabName)), 'selected'); + MochiKit.Signal.signal(this, 'tabSelected', aTabName); + }, + + 'tabNameForAnchorId': function(anId) { + var result; + + switch(anId) { + case 'cards_tabSidePanel': + result = 'cards'; + break; +// case 'directLogins_tabSidePanel': +// result = 'directLogins'; +// break; + case 'account_tabSidePanel': + result = 'account'; + break; + case 'data_tabSidePanel': + result = 'data'; + break; + case 'tools_tabSidePanel': + result = 'tools'; + break; + } + + return result; + }, + + 'listItemIdForTabNamed': function(aTabName) { + var result; + + switch (aTabName) { + case 'cards': + result = 'cardsLI'; + break; +// case 'directLogins': +// result = 'directLoginLI'; +// break; + case 'account': + result = 'accountLI'; + break; + case 'data': + result = 'dataLI'; + break; + case 'tools': + result = 'toolsLI'; + break; + } + + return result; + }, + + 'tabSelected': function (anEvent) { + this.selectTab(this.tabNameForAnchorId(anEvent.src().id)); +// anEvent.stop(); + anEvent.preventDefault(); + }, + + //------------------------------------------------------------------------- + + 'addCard': function (anEvent) { + anEvent.stop(); + MochiKit.Signal.signal(this, 'addCard', anEvent.src()); + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), [ + {tag:'div', cls:'header'}, + {tag:'div', cls:'body', children:[ + {tag:'ul', cls:'mainTabs', children:[ + {tag:'li', id:this.getId('cardsLI'), cls:'cards', children:[ + {tag:'a', id:'cards_tabSidePanel', href:'#', html:"cards"}, + {tag:'div', cls:'selectionHighlighter', children:[ + {tag:'img', src:'./images/old/main/tabs/selectionHighligher.png'}, + {tag:'a', id:this.getId('addCardA'), cls:'add', href:'#', children:[ + {tag:'span', html:"add"}, + {tag:'h3', html:"+"} + ]} + ]} + ]} + ]}, + {tag:'ul', cls:'otherTabs', children:[ + {tag:'li', id:this.getId('accountLI'), children:[ + {tag:'a', id:'account_tabSidePanel', href:'#', html:"account"}, + {tag:'div', cls:'selectionHighlighter', children:[ + {tag:'img', src:'./images/old/main/tabs/selectionHighligherGray.png'} + ]} + ]}, + {tag:'li', id:this.getId('dataLI'), children:[ + {tag:'a', id:'data_tabSidePanel', href:'#', html:"data"}, + {tag:'div', cls:'selectionHighlighter', children:[ + {tag:'img', src:'./images/old/main/tabs/selectionHighligherGray.png'} + ]} + ]}, + {tag:'li', id:this.getId('toolsLI'), children:[ + {tag:'a', id:'tools_tabSidePanel', href:'#', html:"tools"}, + {tag:'div', cls:'selectionHighlighter', children:[ + {tag:'img', src:'./images/old/main/tabs/selectionHighligherGray.png'} + ]} + ]} + ]} + ]}, + {tag:'div', cls:'footer'} + ]); + + MochiKit.Signal.connect('cards_tabSidePanel', 'onclick', this, 'tabSelected'); +// MochiKit.Signal.connect('directLogins_tabSidePanel', 'onclick', this, 'tabSelected'); + MochiKit.Signal.connect('account_tabSidePanel', 'onclick', this, 'tabSelected'); + MochiKit.Signal.connect('data_tabSidePanel', 'onclick', this, 'tabSelected'); + MochiKit.Signal.connect('tools_tabSidePanel', 'onclick', this, 'tabSelected'); + MochiKit.Signal.connect(this.getId('addCardA'), 'onclick', this, 'addCard'); + }, + + //------------------------------------------------------------------------- + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TextColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TextColumnManager.js new file mode 100644 index 0000000..97e81b4 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TextColumnManager.js @@ -0,0 +1,53 @@ +/* + +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.Components'); + +//############################################################################# + +Clipperz.PM.UI.Web.Components.TextColumnManager = function(args) { + args = args || {}; + Clipperz.PM.UI.Web.Components.TextColumnManager.superclass.constructor.call(this, args); + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.TextColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, { + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.TextColumnManager component"; + }, + + //----------------------------------------------------- + + '__syntax_fix__' : 'syntax fix' + +}); + diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js new file mode 100644 index 0000000..179c495 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js @@ -0,0 +1,113 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.ToolsPanel = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.ToolsPanel.superclass.constructor.apply(this, arguments); + + this._initiallySelectedTab = args.selected || 'PASSWORD_GENERATOR'; + this._tabPanelControllerConfiguration = { + 'PASSWORD_GENERATOR': { + tab: 'passwordGeneratorTab', + panel: 'passwordGeneratorPanel' + }, + 'BOOKMARKLET': { + tab: 'bookmarkletTab', + panel: 'bookmarkletPanel' + }, + 'COMPACT_EDITION': { + tab: 'compactEditionTab', + panel: 'compactEditionPanel' + }, + 'HTTP_AUTH': { + tab: 'httpAuthTab', + panel: 'httpAuthPanel' + } + }; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.ToolsPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.ToolsPanel component"; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), [ + {tag:'div', cls:'header', children:[ + {tag:'div', cls:'subPanelTabs', children:[ + {tag:'ul', children:[ + {tag:'li', id:this.getId('passwordGeneratorTab'), children:[{tag:'a', href:'#', html:'Password generator'}], cls:'first'}, + {tag:'li', id:this.getId('bookmarkletTab'), children:[{tag:'a', href:'#', html:'Bookmarklet'}]}, + {tag:'li', id:this.getId('compactEditionTab'), children:[{tag:'a', href:'#', html:'Compact edition'}]}, + {tag:'li', id:this.getId('httpAuthTab'), children:[{tag:'a', href:'#', html:'HTTP Auth'}]} + ]} + ]} + ]}, + {tag:'div', cls:'body', children:[ + {tag:'div', cls:'accountPanel', children:[ + {tag:'div', cls:'subPanelContent', children:[ + {tag:'ul', children:[ + {tag:'li', id:this.getId('passwordGeneratorPanel'), children:[ + {tag:'h3', html:"Password generator"} + ]}, + {tag:'li', id:this.getId('bookmarkletPanel'), children:[ + {tag:'h3', html:"Bookmarklet"} + ]}, + {tag:'li', id:this.getId('compactEditionPanel'), children:[ + {tag:'h3', html:"Compact edition"} + ]}, + {tag:'li', id:this.getId('httpAuthPanel'), children:[ + {tag:'h3', html:"HTTP Auth"} + ]} + ]} + ]} + ]} + ]}, + {tag:'div', cls:'footer'} + ]); + + this.tabPanelController().setup({selected:this.initiallySelectedTab()}); + }, + + //------------------------------------------------------------------------- + + + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js new file mode 100644 index 0000000..5b9d522 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js @@ -0,0 +1,184 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.UnlockPasswordComponent = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.UnlockPasswordComponent.superclass.constructor.apply(this, arguments); + + this._openFromElement = args.openFromElement || null; + this._onOkCloseToElement = args.onOkCloseToElement || null; + this._onCancelCloseToElement = args.onCancelCloseToElement || null; + + this._progressBarComponent = null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.UnlockPasswordComponent, Clipperz.PM.UI.Common.Components.SimpleMessagePanel, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.UnlockPasswordComponent component"; + }, + + //------------------------------------------------------------------------- + + 'getPassphrase': function () { +/* var deferredResult; + + if (this.passphrase() == null) { + this.deferredShowModal({'openFromElement': this.openFromElement()}); + deferredResult = this.deferred(); + } else { + deferredResult = MochiKit.Async.succeed(this.passphrase()); + } + + return deferredResult; +*/ + + this.deferredShowModal({'openFromElement': this.openFromElement()}); + + return this.deferred(); + }, + + //------------------------------------------------------------------------- + + 'deferredShowModal': function (someParameters) { + return Clipperz.Async.callbacks("UnlockPasswordComponent.deferredShowModal", [ + MochiKit.Base.bind(Clipperz.PM.UI.Web.Components.UnlockPasswordComponent.superclass.deferredShowModal, this, someParameters), + MochiKit.Base.method(this, 'getElement', 'passphrase'), + MochiKit.Base.methodcaller('focus') + ], {trace:false}) + }, + + //------------------------------------------------------------------------- + + 'openFromElement': function () { + return this._openFromElement; + }, + + 'onOkCloseToElement': function () { + return this._onOkCloseToElement; + }, + + 'onCancelCloseToElement': function () { + return this._onCancelCloseToElement; + }, + + //------------------------------------------------------------------------- + + 'renderSelf': function() { + Clipperz.PM.UI.Web.Components.UnlockPasswordComponent.superclass.renderSelf.apply(this, arguments); + + this.append(this.getElement('container'), {tag:'div', cls:'passphrase', children: [ +// {tag:'form', id:this.getId('passphraseForm'), children:[ + {tag:'input', id:this.getId('passphrase'), type:'password', name:'passphrase', value:''} +// ]} + ]}); + + MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn', this, 'userSuccessfullyLoggedInHandler'); + MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'userLoginFailed', this, 'userLoginFailedHandler'); + + +// MochiKit.Async.callLater(0.1, MochiKit.Base.method(this.getElement('passphrase'), 'focus')); +// this.getElement('passphrase').select(); + }, + + //------------------------------------------------------------------------- + + 'showProgressBar': function () { + var progressBarElement; + + this.getElement('container').innerHTML = ''; + + progressBarElement = this.append(this.getElement('container'), {tag:'div', cls:'progressBarWrapper'}); + this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':progressBarElement})); + + this.setButtons([{text:"Cancel", result:'CANCEL'}]); + }, + + //------------------------------------------------------------------------- + + 'showFailure': function () { + this.setType('ALERT'); + this.setTitle("Login failed"); + this.setText("Wrong passphrase; the unlock has failed."); + this.getElement('container').innerHTML = ''; + this.setButtons([{text:"Close", result:'CANCEL', isDefault:true}]); + }, + + //------------------------------------------------------------------------- + + 'closeOk': function () { + var passphrase; + + passphrase = this.getElement('passphrase').value; + this.showProgressBar(); +// this.deferred().callback(passphrase); + MochiKit.Async.callLater(0.5, MochiKit.Base.method(this.deferred(), 'callback', passphrase)); + this._deferred = null; + }, + + 'closeCancel': function () { + this.deferredHideModal({closeToElement:this.onCancelCloseToElement()}); + this.deferred().cancel(); + this._deferred = null; + }, + + //------------------------------------------------------------------------- + + 'userSuccessfullyLoggedInHandler': function (anEvent) { + this.deferredHideModal({closeToElement:this.onOkCloseToElement()}); + }, + + 'userLoginFailedHandler': function (anEvent) { +//console.log("############### FAILED LOGIN ################"); + this.showFailure(); + }, + + //------------------------------------------------------------------------- +/* + 'deferredShow': function (someArgs, aResult) { + this.deferredShowModal(someArgs); + +// this.deferred().addMethod(this, 'deferredHideModal', {closeToElement:someArgs.onOkCloseToElement }); +// this.deferred().addErrback (MochiKit.Base.method(this, 'deferredHideModal', {closeToElement:someArgs.onCancelCloseToElement })); +// this.deferred().addCallback(MochiKit.Async.succeed, aResult); + + return this.deferred(); + }, +*/ + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" +}); diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UserInfoBox.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UserInfoBox.js new file mode 100644 index 0000000..f26118e --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UserInfoBox.js @@ -0,0 +1,346 @@ +/* + +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.Components'); + +Clipperz.PM.UI.Web.Components.UserInfoBox = function(args) { + args = args || {}; + + Clipperz.PM.UI.Web.Components.UserInfoBox.superclass.constructor.apply(this, arguments); + + this._slots = { }; + this._isLocked = false; + this._lockTooltip = null; + + return this; +} + +//============================================================================= + +Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.UserInfoBox, Clipperz.PM.UI.Common.Components.BaseComponent, { + + //------------------------------------------------------------------------- + + 'toString': function () { + return "Clipperz.PM.UI.Web.Components.UserInfoBox component"; + }, + + //------------------------------------------------------------------------- + + 'handleLogout': function(anEvent) { +//Clipperz.log(">>> UserInfoBox.handleLogout"); + anEvent.preventDefault(); + MochiKit.Signal.signal(this, 'logout'); +//Clipperz.log("<<< UserInfoBox.handleLogout"); + }, + + //------------------------------------------------------------------------- + + 'lockTooltip': function () { + return this._lockTooltip; + }, + + //------------------------------------------------------------------------- + + 'isLocked': function () { + return this._isLocked; + }, + + 'setIsLocked': function (aValue) { + this._isLocked = aValue; + }, + + 'toggleLock': function(anEvent) { + var deferredResult; + var shouldLock; + +//console.log(">>> UserInfoBox.toggleLock [locked: " + this.isLocked() + "]"); + anEvent.preventDefault(); + this.lockTooltip().hide(); + + shouldLock = (this.isLocked() == false); + + if (shouldLock) { + var maskElement; + + this.setIsLocked(true); + maskElement = this.getId('modalDialogMask'); + deferredResult = Clipperz.Async.callbacks("UserInfoBox.toggleLock [lock]", [ + MochiKit.Base.partial(MochiKit.DOM.addElementClass, this.element(), 'locked'), + MochiKit.Base.partial(Clipperz.Visual.deferredAnimation, MochiKit.Visual.appear, maskElement, {from:0.0, to:0.75, duration:0.5}), + MochiKit.Base.method(Clipperz.PM.RunTime.mainController, 'setPassphraseDelegate', MochiKit.Base.method(this, 'askForPassphrase')), + MochiKit.Base.partial(MochiKit.Signal.signal, this, 'lock') + ], {trace:false}); + } else { + deferredResult = Clipperz.Async.callbacks("UserInfoBox.toggleLock [unlock]", [ + MochiKit.Base.partial(MochiKit.Signal.signal, this, 'unlock') + ], {trace:false}); + } +//console.log("<<< UserInfoBox.toggleLock"); + + return deferredResult; + }, + + //------------------------------------------------------------------------- + + 'unlock': function () { + var deferredResult; + var maskElement; + + this.setIsLocked(false); + maskElement = this.getId('modalDialogMask'); + + deferredResult = Clipperz.Async.callbacks("UserInfoBox.unlock", [ + MochiKit.Base.partial(Clipperz.Visual.deferredAnimation, MochiKit.Visual.fade, maskElement, {from:0.75, to:0.0, duration:0.5}), +// Clipperz.Visual.deferredAnimation(MochiKit.Visual.fade, maskElement, {from:0.75, to:0.0, duration:0.5}), + MochiKit.Base.partial(MochiKit.DOM.removeElementClass, this.element(), 'locked') + ], {trace:false}); + }, + + //------------------------------------------------------------------------- + + 'askForPassphrase': function () { + var unlockPasswordComponent; +/* + var deferredResult; + + deferredResult = new Clipperz.Async.Deferred("UserInfoBox.askForPassphrase", {trace:false}); + deferredResult.addCallback(MochiKit.Async.succeed, 'test'); + + deferredResult.callback(); + + return deferredResult; +*/ +//console.log(">>> UserInfoBox.askForPassphrase"); + unlockPasswordComponent = new Clipperz.PM.UI.Web.Components.UnlockPasswordComponent({ + 'title': "Unlock account", + 'text': "Insert the passprase to unlock the account", + 'type': 'INFO', + 'buttons': [ + {text:"Cancel", result:'CANCEL'}, + {text:"Unlock", result:'OK', isDefault:true} + ], + 'openFromElement': this.getElement('lock'), + 'onOkCloseToElement': null, + 'onCancelCloseToElement': this.getId('lock') + }); +//console.log("<<< UserInfoBox.askForPassphrase"); + + return unlockPasswordComponent.getPassphrase(); + }, + + //========================================================================= + + 'renderSelf': function(/*aContainer, aPosition*/) { + this.append(this.element(), [ +// {tag:'canvas', id:this.getId('canvas'), cls:'canvas', width:'188', height:'154'}, + {tag:'div', cls:'header', children:[ + {tag:'h1', html:"Welcome"}, + {tag:'a', cls:'lockButton', href:'#', id:this.getId('lock'), html:' '} + ]}, + {tag:'div', cls:'body', children:[ + {tag:'h3', id:this.getId('username'), html:""}, + {tag:'ul', children:[ + {tag:'li', id:this.getId('cards'), children:[ + {tag:'span', id:this.getId('cardsNumber'), cls:'number', html:"-"}, + {tag:'span', id:this.getId('cardsLabel'), html:"cards"} + ]}, + {tag:'li', id:this.getId('directLogins'), children:[ + {tag:'span', id:this.getId('directLoginsNumber'), cls:'number', html:"-"}, + {tag:'span', id:this.getId('directLoginsLabel'), html:"direct logins"} + ]} + ]}, + {tag:'a', href:'#', id:this.getId('logout'), html:"logout >"} + ]}, + {tag:'div', cls:'footer'} + ]); + + MochiKit.Signal.connect(this.getElement('logout'), 'onclick', this, 'handleLogout'); + MochiKit.Signal.connect(this.getElement('lock'), 'onclick', this, 'toggleLock'); + + this._lockTooltip = new Clipperz.PM.UI.Common.Components.Tooltip({ + element: this.getElement('lock'), + text: "Click here to lock/unlock your account.", + position: 'RIGHT' + }); + + Clipperz.DOM.Helper.append(MochiKit.DOM.currentDocument().body, + {tag:'div', id:this.getId('modalDialogWrapper'), cls:'modalDialogWrapper', children:[ + {tag:'div', id:this.getId('modalDialogMask'), cls:'modalDialogMask userInfoBoxMask'} + ]} + ); + MochiKit.Style.hideElement(this.getId('modalDialogMask')); + +// this.drawUserInfoBackground(this.getElement('canvas')); + }, + + //------------------------------------------------------------------------- +/* + 'drawUserInfoBackground': function (canvas) { + var kMyDrawingFunctionWidth = 188.0; + var kMyDrawingFunctionHeight = 154.0; + + var context = canvas.getContext("2d"); + var color; + var resolution; + var alignStroke; + var path; + var pointX; + var pointY; + var controlPoint1X; + var controlPoint1Y; + var controlPoint2X; + var controlPoint2Y; + var gradient; + if (window.devicePixelRatio) + resolution = window.devicePixelRatio; + else + resolution = 1.0; + resolution *= 0.5 * (canvas.width / kMyDrawingFunctionWidth + canvas.height / kMyDrawingFunctionHeight); + + context.save(); + context.scale(canvas.width / kMyDrawingFunctionWidth, canvas.height / kMyDrawingFunctionHeight); + context.clearRect(0.0, 0.0, kMyDrawingFunctionWidth, kMyDrawingFunctionHeight); + + // Setup for Shadow Effect + color = "rgba(0.0%, 0.0%, 0.0%, 0.667)"; + context.save(); + context.shadowColor = color; + context.shadowBlur = 3.0; + context.shadowOffsetX = 5.729 * Math.cos(7.592) * resolution; + context.shadowOffsetY = 5.729 * Math.sin(7.592) * resolution; + + // Layer 1 + + alignStroke = 0.0; + context.beginPath(); + pointX = 169.5; + pointY = 141.5; + pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution; + pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution; + context.moveTo(pointX, pointY); + pointX = 177.5; + pointY = 133.5; + pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution; + pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution; + controlPoint1X = 173.889; + controlPoint1Y = 141.5; + controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution; + controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution; + controlPoint2X = 177.5; + controlPoint2Y = 137.889; + controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution; + controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution; + context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY); + pointX = 177.5; + pointY = 19.5; + pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution; + pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution; + context.lineTo(pointX, pointY); + pointX = 169.5; + pointY = 11.5; + pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution; + pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution; + controlPoint1X = 177.5; + controlPoint1Y = 15.111; + controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution; + controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution; + controlPoint2X = 173.889; + controlPoint2Y = 11.5; + controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution; + controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution; + context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY); + pointX = 18.5; + pointY = 11.5; + pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution; + pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution; + context.lineTo(pointX, pointY); + pointX = 10.5; + pointY = 19.5; + pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution; + pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution; + controlPoint1X = 14.111; + controlPoint1Y = 11.5; + controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution; + controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution; + controlPoint2X = 10.5; + controlPoint2Y = 15.111; + controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution; + controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution; + context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY); + pointX = 10.5; + pointY = 133.5; + pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution; + pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution; + context.lineTo(pointX, pointY); + pointX = 18.5; + pointY = 141.5; + pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution; + pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution; + controlPoint1X = 10.5; + controlPoint1Y = 137.889; + controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution; + controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution; + controlPoint2X = 14.111; + controlPoint2Y = 141.5; + controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution; + controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution; + context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY); + pointX = 169.5; + pointY = 141.5; + pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution; + pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution; + context.lineTo(pointX, pointY); + context.closePath(); + gradient = context.createLinearGradient(94.0, 11.5, 94.0, 141.5); + color = "#EE9B69"; + gradient.addColorStop(0.0, color); + color = "#E38D62"; + gradient.addColorStop(1.0, color); + context.fillStyle = gradient; + context.fill(); + + // Shadow Effect + context.restore(); + + context.restore(); + }, +*/ + //------------------------------------------------------------------------- + + 'updateUserDetails': function (someUserInfo) { + var elementName; + + for (elementName in someUserInfo) { + this.getElement(elementName).innerHTML = someUserInfo[elementName]; + } + }, + + //------------------------------------------------------------------------- + __syntaxFix__: "syntax fix" +}); 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" +}); |