author | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2013-10-02 07:59:30 (UTC) |
---|---|---|
committer | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2013-10-02 07:59:30 (UTC) |
commit | 1180b7b195157aaeb4f0d5380e0c886bbd06c2e2 (patch) (unidiff) | |
tree | 709e33a09d9325d382aabaf0a0828e20ebdb96db /frontend/delta/js/Clipperz/PM | |
parent | 20bea94ab6b91c85b171dcf86baba0a64169d508 (diff) | |
download | clipperz-1180b7b195157aaeb4f0d5380e0c886bbd06c2e2.zip clipperz-1180b7b195157aaeb4f0d5380e0c886bbd06c2e2.tar.gz clipperz-1180b7b195157aaeb4f0d5380e0c886bbd06c2e2.tar.bz2 |
Updated /delta
Switched from less to scss. Still no build script to update the final CSS, though.
Added preliminary support for storing account data on browser's local storage for offline viewing. No public backend currently support this feature.
11 files changed, 420 insertions, 42 deletions
diff --git a/frontend/delta/js/Clipperz/PM/DataModel/DevicePreferences.js b/frontend/delta/js/Clipperz/PM/DataModel/DevicePreferences.js new file mode 100644 index 0000000..ff3b33f --- a/dev/null +++ b/frontend/delta/js/Clipperz/PM/DataModel/DevicePreferences.js | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2013 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz, the online password manager. | ||
6 | For further information about its features and functionalities please | ||
7 | refer to http://www.clipperz.com. | ||
8 | |||
9 | * Clipperz is free software: you can redistribute it and/or modify it | ||
10 | under the terms of the GNU Affero General Public License as published | ||
11 | by the Free Software Foundation, either version 3 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | * Clipperz is distributed in the hope that it will be useful, but | ||
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
17 | See the GNU Affero General Public License for more details. | ||
18 | |||
19 | * You should have received a copy of the GNU Affero General Public | ||
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | ||
21 | |||
22 | */ | ||
23 | |||
24 | Clipperz.PM.DataModel.DevicePreferences = function (args) { | ||
25 | args = args || {}; | ||
26 | |||
27 | this._data = null; | ||
28 | |||
29 | Clipperz.PM.DataModel.DevicePreferences.superclass.constructor.apply(this, arguments); | ||
30 | |||
31 | return this; | ||
32 | } | ||
33 | |||
34 | Clipperz.Base.extend(Clipperz.PM.DataModel.DevicePreferences, Object, { | ||
35 | |||
36 | toString: function () { | ||
37 | return "Clipperz.PM.DataModel.DevicePreferences"; | ||
38 | }, | ||
39 | |||
40 | //------------------------------------------------------------------------- | ||
41 | |||
42 | shouldStoreDataLocally: function () { | ||
43 | return (localStorage.getItem('shouldStoreDataLocally') === 'true'); | ||
44 | }, | ||
45 | |||
46 | setShouldStoreDataLocally: function (aValue) { | ||
47 | localStorage.setItem('shouldStoreDataLocally', aValue); | ||
48 | }, | ||
49 | |||
50 | //------------------------------------------------------------------------- | ||
51 | |||
52 | setAccountDataWityResponse: function (aResponse) { | ||
53 | localStorage.setItem('clipperz_dump_data', aResponse['data']); | ||
54 | localStorage.setItem('clipperz_dump_version',aResponse['version']); | ||
55 | localStorage.setItem('clipperz_dump_date', new Date()); | ||
56 | |||
57 | this._data = null; | ||
58 | }, | ||
59 | |||
60 | accountData: function () { | ||
61 | if (this._data == null) { | ||
62 | vardata; | ||
63 | |||
64 | data = localStorage.getItem('clipperz_dump_data'); | ||
65 | if (data != null) { | ||
66 | this._data = JSON.parse(data); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | return this._data; | ||
71 | }, | ||
72 | |||
73 | latestDownload: function () { | ||
74 | varresult; | ||
75 | vardate; | ||
76 | |||
77 | date = localStorage.getItem('clipperz_dump_date'); | ||
78 | if (date != null) { | ||
79 | result = new Date(date); | ||
80 | } else { | ||
81 | result = null; | ||
82 | } | ||
83 | |||
84 | return result; | ||
85 | }, | ||
86 | |||
87 | //========================================================================= | ||
88 | __syntaxFix__: "syntax fix" | ||
89 | }); | ||
90 | |||
diff --git a/frontend/delta/js/Clipperz/PM/Proxy.js b/frontend/delta/js/Clipperz/PM/Proxy.js index 2ac684a..71c784f 100644 --- a/frontend/delta/js/Clipperz/PM/Proxy.js +++ b/frontend/delta/js/Clipperz/PM/Proxy.js | |||
@@ -131,48 +131,49 @@ Clipperz.PM.Proxy.prototype = MochiKit.Base.update(null, { | |||
131 | 131 | ||
132 | //========================================================================= | 132 | //========================================================================= |
133 | 133 | ||
134 | 'processMessage': function (aFunctionName, someParameters, aRequestType) { | 134 | 'processMessage': function (aFunctionName, someParameters, aRequestType) { |
135 | vardeferredResult; | 135 | vardeferredResult; |
136 | 136 | ||
137 | deferredResult = new Clipperz.Async.Deferred("Proxy.processMessage", {trace:false}); | 137 | deferredResult = new Clipperz.Async.Deferred("Proxy.processMessage", {trace:false}); |
138 | deferredResult.addMethod(this, 'payToll', aRequestType); | 138 | deferredResult.addMethod(this, 'payToll', aRequestType); |
139 | deferredResult.addMethod(this, 'sendMessage', aFunctionName); | 139 | deferredResult.addMethod(this, 'sendMessage', aFunctionName); |
140 | deferredResult.addMethod(this, 'setTollCallback'); | 140 | deferredResult.addMethod(this, 'setTollCallback'); |
141 | deferredResult.callback(someParameters); | 141 | deferredResult.callback(someParameters); |
142 | 142 | ||
143 | return deferredResult; | 143 | return deferredResult; |
144 | }, | 144 | }, |
145 | 145 | ||
146 | //========================================================================= | 146 | //========================================================================= |
147 | 147 | ||
148 | '_sendMessage': function (aFunctionName, aVersion, someParameters) { | 148 | '_sendMessage': function (aFunctionName, aVersion, someParameters) { |
149 | throw Clipperz.Base.exception.AbstractMethod; | 149 | throw Clipperz.Base.exception.AbstractMethod; |
150 | }, | 150 | }, |
151 | 151 | ||
152 | 'sendMessage': function (aFunctionName, someParameters) { | 152 | 'sendMessage': function (aFunctionName, someParameters) { |
153 | var deferredResult; | 153 | var deferredResult; |
154 | 154 | ||
155 | console.log("PROXY.sendMessage", aFunctionName, someParameters); | ||
155 | //TODO: read actual application version for a property set at build time | 156 | //TODO: read actual application version for a property set at build time |
156 | deferredResult = new Clipperz.Async.Deferred("Proxy.sendMessage", {trace:false}); | 157 | deferredResult = new Clipperz.Async.Deferred("Proxy.sendMessage", {trace:false}); |
157 | deferredResult.addMethod(this, '_sendMessage', aFunctionName, 'fake-app-version'); | 158 | deferredResult.addMethod(this, '_sendMessage', aFunctionName, 'fake-app-version'); |
158 | deferredResult.addErrback(MochiKit.Base.method(this, 'handleError')); | 159 | deferredResult.addErrback(MochiKit.Base.method(this, 'handleError')); |
159 | deferredResult.callback(someParameters); | 160 | deferredResult.callback(someParameters); |
160 | 161 | ||
161 | return deferredResult; | 162 | return deferredResult; |
162 | }, | 163 | }, |
163 | 164 | ||
164 | //------------------------------------------------------------------------- | 165 | //------------------------------------------------------------------------- |
165 | 166 | ||
166 | 'handleError': function (anError) { | 167 | 'handleError': function (anError) { |
167 | if (anError['message'] == 'Wrong application version') { | 168 | if (anError['message'] == 'Wrong application version') { |
168 | anError['isPermanent'] = true; | 169 | anError['isPermanent'] = true; |
169 | } | 170 | } |
170 | return anError; | 171 | return anError; |
171 | }, | 172 | }, |
172 | 173 | ||
173 | //========================================================================= | 174 | //========================================================================= |
174 | 175 | ||
175 | 'isReadOnly': function () { | 176 | 'isReadOnly': function () { |
176 | return false; | 177 | return false; |
177 | }, | 178 | }, |
178 | 179 | ||
diff --git a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.JSON.js b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.JSON.js index 1638d99..6deee3d 100755 --- a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.JSON.js +++ b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.JSON.js | |||
@@ -36,50 +36,50 @@ Clipperz.PM.Proxy.JSON = function(args) { | |||
36 | 36 | ||
37 | Clipperz.Base.extend(Clipperz.PM.Proxy.JSON, Clipperz.PM.Proxy, { | 37 | Clipperz.Base.extend(Clipperz.PM.Proxy.JSON, Clipperz.PM.Proxy, { |
38 | 38 | ||
39 | 'toString': function() { | 39 | 'toString': function() { |
40 | return "Clipperz.PM.Proxy.JSON"; | 40 | return "Clipperz.PM.Proxy.JSON"; |
41 | }, | 41 | }, |
42 | 42 | ||
43 | //========================================================================= | 43 | //========================================================================= |
44 | 44 | ||
45 | 'url': function () { | 45 | 'url': function () { |
46 | return this._url; | 46 | return this._url; |
47 | }, | 47 | }, |
48 | 48 | ||
49 | //========================================================================= | 49 | //========================================================================= |
50 | 50 | ||
51 | '_sendMessage': function(aFunctionName, aVersion, someParameters) { | 51 | '_sendMessage': function(aFunctionName, aVersion, someParameters) { |
52 | vardeferredResult; | 52 | vardeferredResult; |
53 | var parameters; | 53 | var parameters; |
54 | 54 | ||
55 | parameters = { | 55 | parameters = { |
56 | method: aFunctionName, | 56 | method: aFunctionName, |
57 | version: aVersion, | 57 | version: aVersion, |
58 | parameters: Clipperz.Base.serializeJSON(someParameters) | 58 | parameters: Clipperz.Base.serializeJSON(someParameters) |
59 | }; | 59 | }; |
60 | 60 | console.log("PROXY.JSON._sendMessage", parameters); | |
61 | deferredResult = new Clipperz.Async.Deferred("Proxy.JSON.sendMessage", {trace:false}); | 61 | deferredResult = new Clipperz.Async.Deferred("Proxy.JSON._sendMessage", {trace:false}); |
62 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'remoteRequestSent'); | 62 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'remoteRequestSent'); |
63 | deferredResult.addCallback(MochiKit.Async.doXHR, this.url(), { | 63 | deferredResult.addCallback(MochiKit.Async.doXHR, this.url(), { |
64 | method:'POST', | 64 | method:'POST', |
65 | sendContent:MochiKit.Base.queryString(parameters), | 65 | sendContent:MochiKit.Base.queryString(parameters), |
66 | headers:{"Content-Type":"application/x-www-form-urlencoded"} | 66 | headers:{"Content-Type":"application/x-www-form-urlencoded"} |
67 | }); | 67 | }); |
68 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'remoteRequestReceived'); | 68 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'remoteRequestReceived'); |
69 | deferredResult.addCallback(MochiKit.Base.itemgetter('responseText')); | 69 | deferredResult.addCallback(MochiKit.Base.itemgetter('responseText')); |
70 | deferredResult.addCallback(Clipperz.Base.evalJSON); | 70 | deferredResult.addCallback(Clipperz.Base.evalJSON); |
71 | deferredResult.addCallback(function (someValues) { | 71 | deferredResult.addCallback(function (someValues) { |
72 | if (someValues['result'] == 'EXCEPTION') { | 72 | if (someValues['result'] == 'EXCEPTION') { |
73 | throw someValues['message']; | 73 | throw someValues['message']; |
74 | } | 74 | } |
75 | 75 | ||
76 | return someValues; | 76 | return someValues; |
77 | }) | 77 | }) |
78 | deferredResult.callback(); | 78 | deferredResult.callback(); |
79 | 79 | ||
80 | return deferredResult; | 80 | return deferredResult; |
81 | }, | 81 | }, |
82 | 82 | ||
83 | //========================================================================= | 83 | //========================================================================= |
84 | __syntaxFix__: "syntax fix" | 84 | __syntaxFix__: "syntax fix" |
85 | 85 | ||
diff --git a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js index a3c238c..3f16f70 100644 --- a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js +++ b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js | |||
@@ -9,49 +9,51 @@ refer to http://www.clipperz.com. | |||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | try { if (typeof(Clipperz.PM.Proxy.Offline.DataStore) == 'undefined') { throw ""; }} catch (e) { | 24 | try { if (typeof(Clipperz.PM.Proxy.Offline.DataStore) == 'undefined') { throw ""; }} catch (e) { |
25 | throw "Clipperz.PM.Proxy.Offline.LocalStorageDataStore depends on Clipperz.PM.Proxy.Offline.DataStore!"; | 25 | throw "Clipperz.PM.Proxy.Offline.LocalStorageDataStore depends on Clipperz.PM.Proxy.Offline.DataStore!"; |
26 | } | 26 | } |
27 | 27 | ||
28 | //============================================================================= | 28 | //============================================================================= |
29 | 29 | ||
30 | Clipperz.PM.Proxy.Offline.LocalStorageDataStore = function(args) { | 30 | Clipperz.PM.Proxy.Offline.LocalStorageDataStore = function(args) { |
31 | args = args || {}; | 31 | args = args || {}; |
32 | 32 | ||
33 | this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null); | 33 | //this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null); |
34 | this._data = JSON.parse(localStorage.getItem('clipperz_dump_data')); | ||
35 | |||
34 | this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); | 36 | this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); |
35 | this._shouldPayTolls = args.shouldPayTolls || false; | 37 | this._shouldPayTolls = args.shouldPayTolls || false; |
36 | 38 | ||
37 | this._tolls = {}; | 39 | this._tolls = {}; |
38 | this._currentStaticConnection = null; | 40 | this._currentStaticConnection = null; |
39 | 41 | ||
40 | //Clipperz.PM.Proxy.Offline.LocalStorageDataStore.superclass.constructor.apply(this, arguments); | 42 | //Clipperz.PM.Proxy.Offline.LocalStorageDataStore.superclass.constructor.apply(this, arguments); |
41 | 43 | ||
42 | return this; | 44 | return this; |
43 | } | 45 | } |
44 | 46 | ||
45 | Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.PM.Proxy.Offline.DataStore, { | 47 | Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.PM.Proxy.Offline.DataStore, { |
46 | 48 | ||
47 | //========================================================================= | 49 | //========================================================================= |
48 | 50 | ||
49 | '_knock': function(aConnection, someParameters) { | 51 | '_knock': function(aConnection, someParameters) { |
50 | var result; | 52 | var result; |
51 | 53 | ||
52 | result = { | 54 | result = { |
53 | toll: this.getTollForRequestType(someParameters['requestType']) | 55 | toll: this.getTollForRequestType(someParameters['requestType']) |
54 | } | 56 | } |
55 | 57 | ||
56 | return result; | 58 | return result; |
57 | }, | 59 | }, |
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/CardDetail.js b/frontend/delta/js/Clipperz/PM/UI/Components/CardDetail.js index df514a2..12ddce3 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/CardDetail.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/CardDetail.js | |||
@@ -16,127 +16,180 @@ refer to http://www.clipperz.com. | |||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | Clipperz.PM.UI.Components.CardDetail = React.createClass({ | 24 | Clipperz.PM.UI.Components.CardDetail = React.createClass({ |
25 | 25 | ||
26 | getDefaultProps: function () { | 26 | getDefaultProps: function () { |
27 | return { | 27 | return { |
28 | // searchDelay: 0.3 | 28 | // searchDelay: 0.3 |
29 | } | 29 | } |
30 | }, | 30 | }, |
31 | 31 | ||
32 | propTypes: { | 32 | propTypes: { |
33 | card: React.PropTypes.object.isRequired | 33 | card: React.PropTypes.object.isRequired |
34 | }, | 34 | }, |
35 | 35 | ||
36 | getInitialState: function () { | 36 | getInitialState: function () { |
37 | return { | 37 | return { |
38 | // showSearch: false, | 38 | // showSearch: false, |
39 | // searchTimer: null, | 39 | // searchTimer: null, |
40 | unmaskedFields: new Clipperz.Set(), | ||
40 | starred: false | 41 | starred: false |
41 | }; | 42 | }; |
42 | }, | 43 | }, |
43 | 44 | ||
44 | handleDirectLoginClick: function (aDirectLoginReference, anEvent) { | 45 | handleDirectLoginClick: function (aDirectLoginReference, anEvent) { |
45 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'runDirectLogin', {record:this.props.card['reference'], directLogin:aDirectLoginReference}); | 46 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'runDirectLogin', {record:this.props.card['reference'], directLogin:aDirectLoginReference}); |
46 | }, | 47 | }, |
47 | 48 | ||
49 | toggleFieldVisibility: function (aField, anEvent) { | ||
50 | var unmaskedFields; | ||
51 | var fieldReference; | ||
52 | |||
53 | unmaskedFields = this.state['unmaskedFields']; | ||
54 | fieldReference = aField['reference'] | ||
55 | if (unmaskedFields.contains(fieldReference)) { | ||
56 | unmaskedFields.remove(fieldReference) | ||
57 | } else { | ||
58 | unmaskedFields.add(fieldReference) | ||
59 | } | ||
60 | |||
61 | this.setState({'unmaskedFields': unmaskedFields}); | ||
62 | }, | ||
63 | |||
64 | handleGoAction: function (aField, anEvent) { | ||
65 | var newWindow; | ||
66 | |||
67 | newWindow = MochiKit.DOM.currentWindow().open(aField['value'], '_blank'); | ||
68 | newWindow.focus(); | ||
69 | }, | ||
70 | |||
71 | handleEmailAction: function (aField, anEvent) { | ||
72 | MochiKit.DOM.currentWindow().location = 'mailto:' + aField['value']; | ||
73 | }, | ||
74 | |||
48 | //========================================================================= | 75 | //========================================================================= |
49 | 76 | ||
50 | normalizeFieldValue: function (aValue) { | 77 | normalizeFieldValue: function (aValue) { |
51 | varresult = []; | 78 | varresult = []; |
52 | varrows = aValue.split('\n'); | 79 | varrows = aValue.split('\n'); |
53 | 80 | ||
54 | for (var i = 0; i < rows.length; i++) { | 81 | for (var i = 0; i < rows.length; i++) { |
55 | if (i > 0) { | 82 | if (i > 0) { |
56 | result.push(React.DOM.br()); | 83 | result.push(React.DOM.br()); |
57 | } | 84 | } |
58 | result.push(rows[i].replace(/[\s]/g, '\u00A0')); | 85 | result.push(rows[i].replace(/[\s]/g, '\u00A0')); |
59 | } | 86 | } |
60 | 87 | ||
61 | return result; | 88 | return result; |
62 | }, | 89 | }, |
63 | 90 | ||
64 | renderField: function (aField) { | 91 | renderFieldActionButton: function (aField) { |
65 | //console.log("FIELD", aField); | 92 | // varactionLabel; |
66 | varactionLabel; | 93 | var result; |
67 | 94 | ||
68 | if (aField['actionType'] == 'URL') { | 95 | if (aField['actionType'] == 'URL') { |
69 | actionLabel = "go"; | 96 | result = React.DOM.div({className:'actionWrapper', onClick:MochiKit.Base.method(this, 'handleGoAction', aField)}, [ |
97 | React.DOM.a({className:aField['actionType']}, "go") | ||
98 | ]); | ||
70 | } else if (aField['actionType'] == 'PASSWORD') { | 99 | } else if (aField['actionType'] == 'PASSWORD') { |
71 | actionLabel = "locked"; | 100 | var icon; |
101 | |||
102 | if (this.state['unmaskedFields'].contains(aField['reference'])) { | ||
103 | icon = "unlocked"; | ||
104 | } else { | ||
105 | icon = "locked"; | ||
106 | } | ||
107 | result =React.DOM.div({className:'actionWrapper', onClick:MochiKit.Base.method(this, 'toggleFieldVisibility', aField)}, [ | ||
108 | React.DOM.a({className:aField['actionType']}, icon) | ||
109 | ]); | ||
72 | } else if (aField['actionType'] == 'EMAIL') { | 110 | } else if (aField['actionType'] == 'EMAIL') { |
73 | actionLabel = "email"; | 111 | result =React.DOM.div({className:'actionWrapper', onClick:MochiKit.Base.method(this, 'handleEmailAction', aField)}, [ |
112 | React.DOM.a({className:aField['actionType']}, "email") | ||
113 | ]); | ||
74 | } else { | 114 | } else { |
75 | actionLabel = ""; | 115 | result = null; |
116 | } | ||
117 | |||
118 | return result; | ||
119 | }, | ||
120 | |||
121 | renderField: function (aField) { | ||
122 | //console.log("FIELD", aField); | ||
123 | var fieldExtraClass; | ||
124 | |||
125 | fieldExtraClass = aField['actionType']; | ||
126 | if (this.state['unmaskedFields'].contains(aField['reference'])) { | ||
127 | fieldExtraClass = fieldExtraClass + ' unlocked'; | ||
76 | } | 128 | } |
77 | 129 | ||
78 | returnReact.DOM.div({className:'listItem ' + aField['actionType']}, [ | 130 | returnReact.DOM.div({className:'listItem ' + fieldExtraClass, key:aField['reference']}, [ |
79 | React.DOM.div({className:'fieldWrapper'}, [ | 131 | React.DOM.div({className:'fieldWrapper'}, [ |
80 | React.DOM.div({className:'fieldInnerWrapper'}, [ | 132 | React.DOM.div({className:'fieldInnerWrapper'}, [ |
81 | React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aField['label'])), | 133 | React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aField['label'])), |
82 | React.DOM.div({className:'valueWrapper'}, React.DOM.span({className:'value ' + aField['actionType']}, this.normalizeFieldValue(aField['value']))) | 134 | React.DOM.div({className:'valueWrapper'}, React.DOM.span({className:'value ' + fieldExtraClass}, this.normalizeFieldValue(aField['value']))) |
83 | ]) | 135 | ]) |
84 | ]), | 136 | ]), |
85 | React.DOM.div({className:'actionWrapper'}, [ | 137 | this.renderFieldActionButton(aField) |
86 | React.DOM.div({className:aField['actionType']}, actionLabel) | 138 | // React.DOM.div({className:'actionWrapper'}, [ |
87 | ]) | 139 | // React.DOM.div({className:aField['actionType']}, actionLabel) |
140 | // ]) | ||
88 | ]); | 141 | ]); |
89 | }, | 142 | }, |
90 | 143 | ||
91 | renderDirectLogin: function (aDirectLogin) { | 144 | renderDirectLogin: function (aDirectLogin) { |
92 | //console.log("DIRECT LOGIN", aDirectLogin); | 145 | //console.log("DIRECT LOGIN", aDirectLogin); |
93 | returnReact.DOM.div({className:'listItem', onClick:MochiKit.Base.method(this, 'handleDirectLoginClick', aDirectLogin['reference'])}, [ | 146 | returnReact.DOM.div({className:'listItem', onClick:MochiKit.Base.method(this, 'handleDirectLoginClick', aDirectLogin['reference'])}, [ |
94 | React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aDirectLogin['label'])), | 147 | React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aDirectLogin['label'])), |
95 | React.DOM.div({className:'faviconWrapper'}, React.DOM.img({className:'favicon', src:aDirectLogin['favicon']})), | 148 | React.DOM.div({className:'faviconWrapper'}, React.DOM.img({className:'favicon', src:aDirectLogin['favicon']})), |
96 | React.DOM.div({className:'directLoginLinkWrapper'}, React.DOM.span({className:'directLoginLink'}, "go")) | 149 | React.DOM.div({className:'directLoginLinkWrapper'}, React.DOM.span({className:'directLoginLink'}, "go")) |
97 | ]); | 150 | ]); |
98 | }, | 151 | }, |
99 | 152 | ||
100 | handleBackClick: function (anEvent) { | 153 | handleBackClick: function (anEvent) { |
101 | window.history.back(); | 154 | // window.history.back(); |
155 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'goBack'); | ||
102 | }, | 156 | }, |
103 | 157 | ||
104 | handleStarClick: function (anEvent) { | 158 | handleStarClick: function (anEvent) { |
105 | this.setState({starred: !this.state['starred']}); | 159 | this.setState({starred: !this.state['starred']}); |
106 | }, | 160 | }, |
107 | 161 | ||
108 | //========================================================================= | 162 | //========================================================================= |
109 | 163 | ||
110 | render: function () { | 164 | render: function () { |
111 | var card = this.props.card; | 165 | var card = this.props.card; |
112 | var starredStatus = (this.state['starred'] ? "starred" : "unstarred"); | 166 | // var starredStatus = (this.state['starred'] ? "starred" : "unstarred"); |
113 | 167 | ||
114 | if ((typeof(card['fields']) != 'undefined') && (card['notes'] != '')) { | 168 | if ((typeof(card['fields']) != 'undefined') && (card['notes'] != '')) { |
115 | card['fields'].push({ 'actionType': 'NOTES', 'isHidden': false, 'label': "notes", 'reference': "notes", 'value': card['notes'] }) | 169 | card['fields'].push({ 'actionType': 'NOTES', 'isHidden': false, 'label': "notes", 'reference': "notes", 'value': card['notes'] }) |
116 | } | 170 | } |
117 | 171 | ||
118 | returnReact.DOM.div({className:'cardDetail'}, [ | 172 | returnReact.DOM.div({className:'cardDetail'}, [ |
119 | React.DOM.div({className:'header'}, [ | 173 | React.DOM.div({className:'header'}, [ |
120 | React.DOM.div({className:'titleWrapper'}, React.DOM.div({className:'title'}, card.title)), | 174 | React.DOM.div({className:'titleWrapper'}, React.DOM.div({className:'title'}, card.title)), |
121 | // React.DOM.div({className:'titleWrapper'}, React.DOM.div({className:'title'}, card.title + ' ' + card.title + ' ' + card.title + ' ' + card.title)), | ||
122 | React.DOM.div({className:'backWrapper'}, React.DOM.a({className:'button back', onClick:this.handleBackClick}, "back")), | 175 | React.DOM.div({className:'backWrapper'}, React.DOM.a({className:'button back', onClick:this.handleBackClick}, "back")), |
123 | React.DOM.div({className:'starWrapper'}, React.DOM.a({className:'star', onClick:this.handleStarClick}, starredStatus)) | 176 | // React.DOM.div({className:'starWrapper'}, React.DOM.a({className:'star', onClick:this.handleStarClick}, starredStatus)) |
124 | ]), | 177 | ]), |
125 | React.DOM.div({className:'content'}, [ | 178 | React.DOM.div({className:'content'}, [ |
126 | card.fields ? React.DOM.div({className:'fields'}, MochiKit.Base.map(this.renderField, card.fields)) : null, | 179 | card.fields ? React.DOM.div({className:'fields'}, MochiKit.Base.map(this.renderField, card.fields)) : null, |
127 | card.directLogins ? React.DOM.div({className:'directLogins'}, MochiKit.Base.map(this.renderDirectLogin,card.directLogins)): null | 180 | card.directLogins ? React.DOM.div({className:'directLogins'}, MochiKit.Base.map(this.renderDirectLogin,card.directLogins)): null |
128 | ]), | 181 | ]), |
129 | React.DOM.div({className:'footer'}, [ | 182 | React.DOM.div({className:'footer'}, [ |
130 | /* | 183 | /* |
131 | // React.DOM.a({className:'cancel'}, "cancel"), | 184 | // React.DOM.a({className:'cancel'}, "cancel"), |
132 | // React.DOM.a({className:'save'}, "save") | 185 | // React.DOM.a({className:'save'}, "save") |
133 | 186 | ||
134 | React.DOM.a({className:'cancel button'}, "failed"), | 187 | React.DOM.a({className:'cancel button'}, "failed"), |
135 | React.DOM.a({className:'save button'}, "done") | 188 | React.DOM.a({className:'save button'}, "done") |
136 | */ | 189 | */ |
137 | ]) | 190 | ]) |
138 | ]); | 191 | ]); |
139 | } | 192 | } |
140 | 193 | ||
141 | //========================================================================= | 194 | //========================================================================= |
142 | }); | 195 | }); |
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/CardList.js b/frontend/delta/js/Clipperz/PM/UI/Components/CardList.js index 66d20f1..5a44a4a 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/CardList.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/CardList.js | |||
@@ -76,86 +76,93 @@ Clipperz.PM.UI.Components.CardList = React.createClass({ | |||
76 | 76 | ||
77 | focusOnSearchField: function () { | 77 | focusOnSearchField: function () { |
78 | console.log("focusOnSearchField", this.refs['searchField']); | 78 | console.log("focusOnSearchField", this.refs['searchField']); |
79 | this.refs['searchField'].getDOMNode.focus(); | 79 | this.refs['searchField'].getDOMNode.focus(); |
80 | }, | 80 | }, |
81 | 81 | ||
82 | searchBox: function () { | 82 | searchBox: function () { |
83 | var result; | 83 | var result; |
84 | 84 | ||
85 | if (this.state.showSearch) { | 85 | if (this.state.showSearch) { |
86 | result =React.DOM.div({className:'searchBox'}, [ | 86 | result =React.DOM.div({className:'searchBox'}, [ |
87 | React.DOM.div(null, [ | 87 | React.DOM.div(null, [ |
88 | React.DOM.input({type:'search', placeholder:"search", ref:'searchField', onChange:this.updateSearchText}) | 88 | React.DOM.input({type:'search', placeholder:"search", ref:'searchField', onChange:this.updateSearchText}) |
89 | ]) | 89 | ]) |
90 | ]); | 90 | ]); |
91 | } else { | 91 | } else { |
92 | result = null; | 92 | result = null; |
93 | } | 93 | } |
94 | 94 | ||
95 | return result; | 95 | return result; |
96 | }, | 96 | }, |
97 | 97 | ||
98 | //========================================================================= | 98 | //========================================================================= |
99 | 99 | ||
100 | showPreferences: function (anEvent) { | ||
101 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'showPreferences', anEvent); | ||
102 | }, | ||
103 | |||
104 | //========================================================================= | ||
105 | |||
100 | cardItem: function (aRecordReference) { | 106 | cardItem: function (aRecordReference) { |
101 | varreference = aRecordReference['_reference']; | 107 | varreference = aRecordReference['_reference']; |
102 | varselectedCard = (reference == this.props.selectedCard); | 108 | varselectedCard = (reference == this.props.selectedCard); |
103 | 109 | ||
104 | returnReact.DOM.div({className:'listItem', onClick:MochiKit.Base.method(this, 'handleClickOnCardDetail', reference)}, [ | 110 | //TODO: verify if it is possible to put the onClick handler on the container 'div', instead of adding it to each 'div' item. |
111 | returnReact.DOM.div({className:'listItem', key:reference, onClick:MochiKit.Base.method(this, 'handleClickOnCardDetail', reference)}, [ | ||
105 | React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aRecordReference.label)), | 112 | React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aRecordReference.label)), |
106 | // React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label)), | 113 | // React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label)), |
107 | React.DOM.div({className:'faviconWrapper'}, aRecordReference.favicon ? React.DOM.img({className:'favicon', src:aRecordReference.favicon}) : React.DOM.div({className:'favicon'}, '\u00A0')), | 114 | React.DOM.div({className:'faviconWrapper'}, aRecordReference.favicon ? React.DOM.img({className:'favicon', src:aRecordReference.favicon}) : React.DOM.div({className:'favicon'}, '\u00A0')), |
108 | React.DOM.div({className:'detailLinkWrapper'}, React.DOM.span({className:'detailLink ' + (selectedCard ? 'icon-spin' : '')}, (selectedCard ? "loading" : "detail"))) | 115 | React.DOM.div({className:'detailLinkWrapper'}, React.DOM.span({className:'detailLink ' + (selectedCard ? 'icon-spin' : '')}, (selectedCard ? "loading" : "detail"))) |
109 | ]); | 116 | ]); |
110 | }, | 117 | }, |
111 | 118 | ||
112 | handleClickOnCardDetail: function (aRecordReference, anEvent) { | 119 | handleClickOnCardDetail: function (aRecordReference, anEvent) { |
113 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'showRecord', aRecordReference); | 120 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'showRecord', aRecordReference); |
114 | }, | 121 | }, |
115 | 122 | ||
116 | cardListItems: function () { | 123 | cardListItems: function () { |
117 | varlist; | 124 | varlist; |
118 | varresult; | 125 | varresult; |
119 | 126 | ||
120 | list = this.props['cardList']; | 127 | list = this.props['cardList']; |
121 | 128 | ||
122 | if (typeof(list) != 'undefined') { | 129 | if (typeof(list) != 'undefined') { |
123 | result = MochiKit.Base.map(MochiKit.Base.method(this, 'cardItem'), list); | 130 | result = MochiKit.Base.map(MochiKit.Base.method(this, 'cardItem'), list); |
124 | } else { | 131 | } else { |
125 | result = null; | 132 | result = null; |
126 | } | 133 | } |
127 | 134 | ||
128 | return result; | 135 | return result; |
129 | }, | 136 | }, |
130 | 137 | ||
131 | //========================================================================= | 138 | //========================================================================= |
132 | 139 | ||
133 | handleChange: function (anEvent) { | 140 | handleChange: function (anEvent) { |
134 | // varrefs = this.refs; | 141 | // varrefs = this.refs; |
135 | // var refName = MochiKit.Base.filter(function (aRefName) { return refs[aRefName].getDOMNode() == anEvent.target}, MochiKit.Base.keys(this.refs))[0]; | 142 | // var refName = MochiKit.Base.filter(function (aRefName) { return refs[aRefName].getDOMNode() == anEvent.target}, MochiKit.Base.keys(this.refs))[0]; |
136 | // var newState = {}; | 143 | // var newState = {}; |
137 | // | 144 | // |
138 | // newState[refName] = event.target.value; | 145 | // newState[refName] = event.target.value; |
139 | // this.setState(newState); | 146 | // this.setState(newState); |
140 | }, | 147 | }, |
141 | 148 | ||
142 | //========================================================================= | 149 | //========================================================================= |
143 | 150 | ||
144 | render: function() { | 151 | render: function() { |
145 | returnReact.DOM.div(null, [ | 152 | returnReact.DOM.div(null, [ |
146 | React.DOM.div({className:'header'}, [ | 153 | React.DOM.div({className:'header'}, [ |
147 | React.DOM.a({className:'account'}, 'clipperz'), | 154 | React.DOM.a({className:'account'}, 'clipperz'), |
148 | React.DOM.div({className:'features'}, [ | 155 | React.DOM.div({className:'features'}, [ |
149 | React.DOM.a({className:'addCard'}, 'add'), | 156 | // React.DOM.a({className:'addCard'}, 'add'), |
150 | React.DOM.a({className:'search ' + (this.state.showSearch ? 'selected' : ''), onClick:this.toggleSearch}, 'search'), | 157 | React.DOM.a({className:'search ' + (this.state.showSearch ? 'selected' : ''), onClick:this.toggleSearch}, 'search'), |
151 | React.DOM.a({className:'settings'}, 'settings') | 158 | React.DOM.a({className:'settings', onClick:this.showPreferences}, 'settings') |
152 | ]), | 159 | ]), |
153 | // this.searchBox() | 160 | // this.searchBox() |
154 | ]), | 161 | ]), |
155 | this.searchBox(), | 162 | this.searchBox(), |
156 | React.DOM.div({className:'content cardList'}, this.cardListItems()), | 163 | React.DOM.div({className:'content cardList'}, this.cardListItems()), |
157 | ]); | 164 | ]); |
158 | } | 165 | } |
159 | 166 | ||
160 | //========================================================================= | 167 | //========================================================================= |
161 | }); | 168 | }); |
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Checkbox.js b/frontend/delta/js/Clipperz/PM/UI/Components/Checkbox.js new file mode 100644 index 0000000..9538063 --- a/dev/null +++ b/frontend/delta/js/Clipperz/PM/UI/Components/Checkbox.js | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2013 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz, the online password manager. | ||
6 | For further information about its features and functionalities please | ||
7 | refer to http://www.clipperz.com. | ||
8 | |||
9 | * Clipperz is free software: you can redistribute it and/or modify it | ||
10 | under the terms of the GNU Affero General Public License as published | ||
11 | by the Free Software Foundation, either version 3 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | * Clipperz is distributed in the hope that it will be useful, but | ||
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
17 | See the GNU Affero General Public License for more details. | ||
18 | |||
19 | * You should have received a copy of the GNU Affero General Public | ||
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | ||
21 | |||
22 | */ | ||
23 | |||
24 | Clipperz.PM.UI.Components.Checkbox = React.createClass({ | ||
25 | //http://development.tobypitman.com/iphoneCheckboxes/iphoneCheckboxes2.html | ||
26 | |||
27 | propTypes: { | ||
28 | 'checked': React.PropTypes.bool.isRequired, | ||
29 | 'id': React.PropTypes.string.isRequired, | ||
30 | 'eventHandler':React.PropTypes.func.isRequired | ||
31 | }, | ||
32 | |||
33 | //========================================================================= | ||
34 | |||
35 | render: function () { | ||
36 | returnReact.DOM.div({className:'checkbox', onClick:this.props['eventHandler']}, [ | ||
37 | React.DOM.input({name:this.props['id'], id:this.props['id'], value:this.props['id'], type:'checkbox', checked:this.props['checked']}), | ||
38 | React.DOM.label({className:'check', 'for':this.props['id']}), | ||
39 | React.DOM.label({className:'info', 'for':this.props['id']}, "enable local storage") | ||
40 | ]); | ||
41 | } | ||
42 | |||
43 | //========================================================================= | ||
44 | }); | ||
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/LoginForm.js b/frontend/delta/js/Clipperz/PM/UI/Components/LoginForm.js index 2b5b4a4..801549f 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/LoginForm.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/LoginForm.js | |||
@@ -71,49 +71,49 @@ Clipperz.PM.UI.Components.LoginForm = React.createClass({ | |||
71 | } | 71 | } |
72 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'doLogin', credentials); | 72 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'doLogin', credentials); |
73 | }, | 73 | }, |
74 | 74 | ||
75 | handleRegistrationLinkClick: function (event) { | 75 | handleRegistrationLinkClick: function (event) { |
76 | event.preventDefault(); | 76 | event.preventDefault(); |
77 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'showRegistrationForm'); | 77 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'showRegistrationForm'); |
78 | }, | 78 | }, |
79 | 79 | ||
80 | //------------------------------------------------------------------------- | 80 | //------------------------------------------------------------------------- |
81 | 81 | ||
82 | shouldEnableLoginButton: function () { | 82 | shouldEnableLoginButton: function () { |
83 | var result; | 83 | var result; |
84 | 84 | ||
85 | return( | 85 | return( |
86 | ((this.state['username'] != '') && (this.state['passphrase'] != '')) | 86 | ((this.state['username'] != '') && (this.state['passphrase'] != '')) |
87 | || | 87 | || |
88 | (this.state['pin'] != '') | 88 | (this.state['pin'] != '') |
89 | ) && !this.props['disabled']; | 89 | ) && !this.props['disabled']; |
90 | }, | 90 | }, |
91 | 91 | ||
92 | 92 | ||
93 | loginForm: function () { | 93 | loginForm: function () { |
94 | registrationLink =React.DOM.div({'className':'registrationLink'}, [ | 94 | registrationLink =React.DOM.div({'className':'registrationLink'}, [ |
95 | React.DOM.a({'onClick':this.handleRegistrationLinkClick}, "Need an account") | 95 | React.DOM.a({'onClick':this.handleRegistrationLinkClick}, "Sign up") |
96 | ]); | 96 | ]); |
97 | returnReact.DOM.div({'className':'loginForm credentials'},[ | 97 | returnReact.DOM.div({'className':'loginForm credentials'},[ |
98 | React.DOM.form({onChange: this.handleChange, onSubmit:this.handleCredentialSubmit}, [ | 98 | React.DOM.form({onChange: this.handleChange, onSubmit:this.handleCredentialSubmit}, [ |
99 | React.DOM.div(null,[ | 99 | React.DOM.div(null,[ |
100 | React.DOM.label({'for':'name'}, "username"), | 100 | React.DOM.label({'for':'name'}, "username"), |
101 | React.DOM.input({'type':'text', 'name':'name', 'ref':'username', 'placeholder':"username", 'key':'username', 'autoCapitalize':'none'}), | 101 | React.DOM.input({'type':'text', 'name':'name', 'ref':'username', 'placeholder':"username", 'key':'username', 'autoCapitalize':'none'}), |
102 | React.DOM.label({'for':'passphrase'}, "passphrase"), | 102 | React.DOM.label({'for':'passphrase'}, "passphrase"), |
103 | React.DOM.input({'type':'password', 'name':'passphrase', 'ref':'passphrase', 'placeholder':"passphrase", 'key':'passphrase'}) | 103 | React.DOM.input({'type':'password', 'name':'passphrase', 'ref':'passphrase', 'placeholder':"passphrase", 'key':'passphrase'}) |
104 | ]), | 104 | ]), |
105 | React.DOM.button({'type':'submit', 'disabled':!this.shouldEnableLoginButton(), 'className':'button'}, "login") | 105 | React.DOM.button({'type':'submit', 'disabled':!this.shouldEnableLoginButton(), 'className':'button'}, "login") |
106 | ]), | 106 | ]), |
107 | this.props.isNewUserRegistrationAvailable ? registrationLink : null | 107 | this.props.isNewUserRegistrationAvailable ? registrationLink : null |
108 | ]); | 108 | ]); |
109 | }, | 109 | }, |
110 | 110 | ||
111 | handlePINSubmit: function (event) { | 111 | handlePINSubmit: function (event) { |
112 | event.preventDefault(); | 112 | event.preventDefault(); |
113 | 113 | ||
114 | this.refs['pin'].getDOMNode().blur(); | 114 | this.refs['pin'].getDOMNode().blur(); |
115 | 115 | ||
116 | var credentials = { | 116 | var credentials = { |
117 | pin: this.refs['pin'].getDOMNode().value | 117 | pin: this.refs['pin'].getDOMNode().value |
118 | } | 118 | } |
119 | 119 | ||
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js b/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js index cc4a06c..cb5f81a 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js | |||
@@ -73,50 +73,51 @@ Clipperz.Base.extend(Clipperz.PM.UI.Components.Overlay, Object, { | |||
73 | 'resetStatus': function () { | 73 | 'resetStatus': function () { |
74 | MochiKit.Style.showElement(this.element()); | 74 | MochiKit.Style.showElement(this.element()); |
75 | MochiKit.Style.showElement(this.getElement('spinner')); | 75 | MochiKit.Style.showElement(this.getElement('spinner')); |
76 | MochiKit.Style.hideElement(this.getElement('done')); | 76 | MochiKit.Style.hideElement(this.getElement('done')); |
77 | MochiKit.Style.hideElement(this.getElement('failed')); | 77 | MochiKit.Style.hideElement(this.getElement('failed')); |
78 | }, | 78 | }, |
79 | 79 | ||
80 | 'setMessage': function (aMessage) { | 80 | 'setMessage': function (aMessage) { |
81 | if (typeof(aMessage) != 'undefined') { | 81 | if (typeof(aMessage) != 'undefined') { |
82 | this.getElement('title').innerHTML = aMessage; | 82 | this.getElement('title').innerHTML = aMessage; |
83 | } | 83 | } |
84 | }, | 84 | }, |
85 | 85 | ||
86 | 'completed': function (aFunctionToShowResult, aMessage, aDelayBeforeHiding) { | 86 | 'completed': function (aFunctionToShowResult, aMessage, aDelayBeforeHiding) { |
87 | var delay = aDelayBeforeHiding || this.defaultDelay(); | 87 | var delay = aDelayBeforeHiding || this.defaultDelay(); |
88 | 88 | ||
89 | this.hideSpinner(); | 89 | this.hideSpinner(); |
90 | MochiKit.Base.bind(aFunctionToShowResult, this)(); | 90 | MochiKit.Base.bind(aFunctionToShowResult, this)(); |
91 | this.setMessage(aMessage); | 91 | this.setMessage(aMessage); |
92 | 92 | ||
93 | MochiKit.Async.callLater(delay, MochiKit.Base.bind(this.hide, this)) | 93 | MochiKit.Async.callLater(delay, MochiKit.Base.bind(this.hide, this)) |
94 | }, | 94 | }, |
95 | 95 | ||
96 | 'hide': function () { | 96 | 'hide': function () { |
97 | MochiKit.DOM.removeElementClass(this.element(), 'ios-overlay-show'); | 97 | var element = this.element(); |
98 | MochiKit.DOM.addElementClass(this.element(), 'ios-overlay-hide'); | 98 | MochiKit.DOM.removeElementClass(element, 'ios-overlay-show'); |
99 | MochiKit.Async.callLater(1, MochiKit.Style.hideElement, this.element()); | 99 | MochiKit.DOM.addElementClass(element, 'ios-overlay-hide'); |
100 | MochiKit.Async.callLater(1, MochiKit.Style.hideElement, element); | ||
100 | }, | 101 | }, |
101 | 102 | ||
102 | 'hideSpinner': function () { | 103 | 'hideSpinner': function () { |
103 | MochiKit.Style.hideElement(this.getElement('spinner')); | 104 | MochiKit.Style.hideElement(this.getElement('spinner')); |
104 | }, | 105 | }, |
105 | 106 | ||
106 | 'showDoneIcon': function () { | 107 | 'showDoneIcon': function () { |
107 | MochiKit.Style.showElement(this.getElement('done')); | 108 | MochiKit.Style.showElement(this.getElement('done')); |
108 | }, | 109 | }, |
109 | 110 | ||
110 | 'showFailIcon': function () { | 111 | 'showFailIcon': function () { |
111 | MochiKit.Style.showElement(this.getElement('failed')); | 112 | MochiKit.Style.showElement(this.getElement('failed')); |
112 | }, | 113 | }, |
113 | 114 | ||
114 | //------------------------------------------------------------------------- | 115 | //------------------------------------------------------------------------- |
115 | 116 | ||
116 | 'defaultDelay': function () { | 117 | 'defaultDelay': function () { |
117 | return this._defaultDelay; | 118 | return this._defaultDelay; |
118 | }, | 119 | }, |
119 | 120 | ||
120 | //------------------------------------------------------------------------- | 121 | //------------------------------------------------------------------------- |
121 | __syntaxFix__: "syntax fix" | 122 | __syntaxFix__: "syntax fix" |
122 | }); | 123 | }); |
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/PreferencePage.js b/frontend/delta/js/Clipperz/PM/UI/Components/PreferencePage.js new file mode 100644 index 0000000..822acc2 --- a/dev/null +++ b/frontend/delta/js/Clipperz/PM/UI/Components/PreferencePage.js | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2013 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz, the online password manager. | ||
6 | For further information about its features and functionalities please | ||
7 | refer to http://www.clipperz.com. | ||
8 | |||
9 | * Clipperz is free software: you can redistribute it and/or modify it | ||
10 | under the terms of the GNU Affero General Public License as published | ||
11 | by the Free Software Foundation, either version 3 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | * Clipperz is distributed in the hope that it will be useful, but | ||
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
17 | See the GNU Affero General Public License for more details. | ||
18 | |||
19 | * You should have received a copy of the GNU Affero General Public | ||
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | ||
21 | |||
22 | */ | ||
23 | |||
24 | Clipperz.PM.UI.Components.PreferencePage = React.createClass({ | ||
25 | |||
26 | getDefaultProps: function () { | ||
27 | return { | ||
28 | } | ||
29 | }, | ||
30 | |||
31 | propTypes: { | ||
32 | // card: React.PropTypes.object.isRequired | ||
33 | // checked: React.PropTypes.boolean.isRequired | ||
34 | }, | ||
35 | |||
36 | getInitialState: function () { | ||
37 | // return { | ||
38 | // shouldStoreDataLocally: false | ||
39 | // }; | ||
40 | }, | ||
41 | |||
42 | handleBackClick: function (anEvent) { | ||
43 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'goBack'); | ||
44 | }, | ||
45 | |||
46 | toggleShouldStoreDataLocally: function (anEvent) { | ||
47 | // this.setState({shouldStoreDataLocally: !this.state['shouldStoreDataLocally']}); | ||
48 | Clipperz.PM.DataModel.devicePreferences.setShouldStoreDataLocally(!Clipperz.PM.DataModel.devicePreferences.shouldStoreDataLocally()); | ||
49 | this.setState({}); | ||
50 | }, | ||
51 | |||
52 | shouldStoreDataLocally: function () { | ||
53 | return Clipperz.PM.DataModel.devicePreferences.shouldStoreDataLocally(); | ||
54 | }, | ||
55 | |||
56 | syncNow: function (anEvent) { | ||
57 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'synchronizeLocalData'); | ||
58 | }, | ||
59 | |||
60 | //========================================================================= | ||
61 | |||
62 | render: function () { | ||
63 | returnReact.DOM.div({className:'preferences'}, [ | ||
64 | React.DOM.div({className:'header'}, [ | ||
65 | React.DOM.div({className:'titleWrapper'}, React.DOM.div({className:'title'}, "Preferences")), | ||
66 | React.DOM.div({className:'backWrapper'}, React.DOM.a({className:'button back', onClick:this.handleBackClick}, "back")), | ||
67 | ]), | ||
68 | React.DOM.div({className:'content'}, [ | ||
69 | React.DOM.form(null, [ | ||
70 | React.DOM.div({className:'section'}, [ | ||
71 | React.DOM.h4(null, "Local storage"), | ||
72 | React.DOM.p(null, "Store you account data locally for offline viewing"), | ||
73 | new Clipperz.PM.UI.Components.Checkbox({'id':'shouldStoreLocally_checkbox', 'checked':this.shouldStoreDataLocally(), 'eventHandler':this.toggleShouldStoreDataLocally}), | ||
74 | this.shouldStoreDataLocally() ? React.DOM.div({className:'syncInfo'}, [ | ||
75 | // React.DOM.h5(null, "data were never synchronized before"), | ||
76 | React.DOM.a({className:'button', onClick:this.syncNow}, "Sync now") | ||
77 | ]) : null | ||
78 | ]) | ||
79 | ]) | ||
80 | ]), | ||
81 | React.DOM.div({className:'footer'}, [ | ||
82 | |||
83 | ]) | ||
84 | ]); | ||
85 | } | ||
86 | |||
87 | //========================================================================= | ||
88 | }); | ||
diff --git a/frontend/delta/js/Clipperz/PM/UI/MainController.js b/frontend/delta/js/Clipperz/PM/UI/MainController.js index da7540e..20ff041 100644 --- a/frontend/delta/js/Clipperz/PM/UI/MainController.js +++ b/frontend/delta/js/Clipperz/PM/UI/MainController.js | |||
@@ -5,174 +5,234 @@ Copyright 2008-2013 Clipperz Srl | |||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | Clipperz.Base.module('Clipperz.PM.UI'); | 24 | Clipperz.Base.module('Clipperz.PM.UI'); |
25 | 25 | ||
26 | Clipperz.PM.UI.MainController = function() { | 26 | Clipperz.PM.UI.MainController = function() { |
27 | var pages; | 27 | var pages; |
28 | 28 | ||
29 | this._proxy = null; | 29 | // this._proxy = null; |
30 | this._user = null; | 30 | this._user = null; |
31 | this._filter= ''; | 31 | this._filter= ''; |
32 | 32 | ||
33 | //this._currentPage = 'loadingPage'; | 33 | //this._currentPage = 'loadingPage'; |
34 | 34 | ||
35 | this._pageStack = ['loadingPage']; | 35 | this._pageStack = ['loadingPage']; |
36 | this._overlay = new Clipperz.PM.UI.Components.Overlay(); | 36 | this._overlay = new Clipperz.PM.UI.Components.Overlay(); |
37 | pages = { | 37 | pages = { |
38 | 'loginPage': new Clipperz.PM.UI.Components.LoginForm(), | 38 | 'loginPage': new Clipperz.PM.UI.Components.LoginForm(), |
39 | 'registrationPage':new Clipperz.PM.UI.Components.RegistrationWizard(), | 39 | 'registrationPage':new Clipperz.PM.UI.Components.RegistrationWizard(), |
40 | 'cardListPage': new Clipperz.PM.UI.Components.CardList(), | 40 | 'cardListPage': new Clipperz.PM.UI.Components.CardList(), |
41 | 'cardDetailPage':new Clipperz.PM.UI.Components.CardDetail({card: {}}), | 41 | 'cardDetailPage':new Clipperz.PM.UI.Components.CardDetail({card: {}}), |
42 | 'preferencePage':new Clipperz.PM.UI.Components.PreferencePage(), | ||
42 | 'errorPage': new Clipperz.PM.UI.Components.ErrorPage({message:''}) | 43 | 'errorPage': new Clipperz.PM.UI.Components.ErrorPage({message:''}) |
43 | }; | 44 | }; |
44 | 45 | ||
45 | MochiKit.Base.map(function (anId) {React.renderComponent(pages[anId], MochiKit.DOM.getElement(anId))}, MochiKit.Base.keys(pages)); | 46 | MochiKit.Base.map(function (anId) {React.renderComponent(pages[anId], MochiKit.DOM.getElement(anId))}, MochiKit.Base.keys(pages)); |
46 | this._pages = pages; | 47 | this._pages = pages; |
47 | this.registerForNotificationCenterEvents(); | 48 | this.registerForNotificationCenterEvents(); |
49 | MochiKit.Signal.connect(MochiKit.DOM.currentDocument(), 'onselectionchange', this, 'selectionChangeHandler'); | ||
48 | 50 | ||
49 | return this; | 51 | return this; |
50 | } | 52 | } |
51 | 53 | ||
52 | MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, { | 54 | MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, { |
53 | 55 | ||
54 | toString: function () { | 56 | toString: function () { |
55 | return "Clipperz.PM.UI.MainController"; | 57 | return "Clipperz.PM.UI.MainController"; |
56 | }, | 58 | }, |
57 | 59 | ||
58 | //========================================================================= | 60 | //========================================================================= |
59 | 61 | ||
60 | overlay: function () { | 62 | overlay: function () { |
61 | return this._overlay; | 63 | return this._overlay; |
62 | }, | 64 | }, |
63 | 65 | ||
64 | loginForm: function () { | 66 | loginForm: function () { |
65 | return this._loginForm; | 67 | return this._loginForm; |
66 | }, | 68 | }, |
67 | 69 | ||
68 | registrationWizard: function () { | 70 | registrationWizard: function () { |
69 | return this._registrationWizard; | 71 | return this._registrationWizard; |
70 | }, | 72 | }, |
71 | 73 | ||
72 | //========================================================================= | 74 | //========================================================================= |
73 | 75 | ||
74 | isOnline: function() { | 76 | isOnline: function() { |
75 | return navigator.onLine; | 77 | return navigator.onLine; |
78 | // return false; | ||
76 | }, | 79 | }, |
77 | 80 | ||
78 | hasLocalData: function() { | 81 | hasLocalData: function() { |
79 | return false; | 82 | // return false; |
83 | return (Clipperz.PM.DataModel.devicePreferences.accountData() != null); | ||
80 | }, | 84 | }, |
81 | 85 | ||
82 | loginMode: function () { | 86 | loginMode: function () { |
83 | //PIN is set using this command: | 87 | //PIN is set using this command: |
84 | //Clipperz.PM.PIN.setCredentialsWithPIN('1234', {'username':'joe', 'passphrase':'clipperz'}); | 88 | //Clipperz.PM.PIN.setCredentialsWithPIN('1234', {'username':'joe', 'passphrase':'clipperz'}); |
85 | 89 | ||
86 | return Clipperz.PM.PIN.isSet() ? 'PIN' : 'CREDENTIALS'; | 90 | return Clipperz.PM.PIN.isSet() ? 'PIN' : 'CREDENTIALS'; |
87 | }, | 91 | }, |
88 | 92 | ||
89 | //========================================================================= | 93 | //========================================================================= |
90 | 94 | ||
91 | pages: function () { | 95 | pages: function () { |
92 | return this._pages; | 96 | return this._pages; |
93 | }, | 97 | }, |
94 | 98 | ||
95 | pageStack: function () { | 99 | pageStack: function () { |
96 | return this._pageStack; | 100 | return this._pageStack; |
97 | }, | 101 | }, |
98 | 102 | ||
99 | //========================================================================= | 103 | //========================================================================= |
100 | 104 | ||
105 | showOfflineError: function () { | ||
106 | console.log("THE BROWSER IS OFFLINE"); | ||
107 | }, | ||
108 | |||
101 | selectInitialProxy: function () { | 109 | selectInitialProxy: function () { |
102 | if (this.isOnline()) { | 110 | if (this.isOnline()) { |
103 | this._proxy = Clipperz.PM.Proxy.defaultProxy; | 111 | // this._proxy = Clipperz.PM.Proxy.defaultProxy; |
104 | } else { | 112 | } else { |
105 | if (this.hasLocalData()) { | 113 | if (this.hasLocalData()) { |
106 | this._proxy = new Clipperz.PM.Proxy.Offline({dataStore: new Clipperz.PM.Proxy.Offline.LocalStorageDataStore(), shouldPayTolls:false}); | 114 | // this._proxy = new Clipperz.PM.Proxy.Offline({dataStore: new Clipperz.PM.Proxy.Offline.LocalStorageDataStore(), shouldPayTolls:false}); |
115 | Clipperz.PM.Proxy.defaultProxy = new Clipperz.PM.Proxy.Offline({dataStore: new Clipperz.PM.Proxy.Offline.LocalStorageDataStore(), shouldPayTolls:false}); | ||
107 | } else { | 116 | } else { |
108 | this.showOfflineError(); | 117 | this.showOfflineError(); |
109 | } | 118 | } |
110 | } | 119 | } |
111 | }, | 120 | }, |
112 | 121 | ||
113 | proxy: function () { | 122 | //proxy: function () { |
114 | return this._proxy; | 123 | // return this._proxy; |
115 | }, | 124 | //}, |
116 | 125 | ||
117 | //========================================================================= | 126 | //========================================================================= |
118 | 127 | ||
119 | registerForNotificationCenterEvents: function () { | 128 | registerForNotificationCenterEvents: function () { |
120 | var events= ['doLogin', 'registerNewUser', 'showRegistrationForm', 'goBack', 'showRecord', 'searchCards', 'runDirectLogin']; | 129 | var events= [ |
130 | 'doLogin', | ||
131 | 'registerNewUser', | ||
132 | 'showRegistrationForm', | ||
133 | 'goBack', | ||
134 | 'showRecord', | ||
135 | 'searchCards', | ||
136 | 'showPreferences', | ||
137 | 'runDirectLogin', | ||
138 | 'synchronizeLocalData' | ||
139 | ]; | ||
121 | var self= this; | 140 | var self= this; |
122 | 141 | ||
123 | MochiKit.Base.map(function (anEvent) { | 142 | MochiKit.Base.map(function (anEvent) { |
124 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, anEvent, MochiKit.Base.method(self, anEvent)); | 143 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, anEvent, MochiKit.Base.method(self, anEvent)); |
125 | }, events); | 144 | }, events); |
126 | 145 | ||
127 | // MochiKit.Signal.connect(window, 'onpopstate', MochiKit.Base.method(this, 'historyGoBack')); | 146 | // MochiKit.Signal.connect(window, 'onpopstate', MochiKit.Base.method(this, 'historyGoBack')); |
128 | MochiKit.Signal.connect(window, 'onbeforeunload',MochiKit.Base.method(this, 'shouldExitApp')); | 147 | MochiKit.Signal.connect(window, 'onbeforeunload',MochiKit.Base.method(this, 'shouldExitApp')); |
129 | }, | 148 | }, |
130 | 149 | ||
131 | //------------------------------------------------------------------------- | 150 | //------------------------------------------------------------------------- |
132 | 151 | ||
152 | selectionChangeHandler: function (anEvent) { | ||
153 | varselection; | ||
154 | varselectionRange; | ||
155 | varselectionNode; | ||
156 | varvalueElement; | ||
157 | //other hints: http://www.bearpanther.com/2013/05/27/easy-text-selection-in-mobile-safari/ | ||
158 | //SELECTION: https://developer.mozilla.org/en-US/docs/Web/API/Selection | ||
159 | //RANGE: https://developer.mozilla.org/en-US/docs/Web/API/Range | ||
160 | //NODE TYPES: https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType | ||
161 | |||
162 | selection = MochiKit.DOM.currentWindow().getSelection(); | ||
163 | //console.log("-- selection", selection); | ||
164 | selectionRange = selection.getRangeAt(0); | ||
165 | selectionNode = selectionRange.startContainer.childNodes[selectionRange.startOffset]; | ||
166 | //console.log("-- selectionNode", selectionNode); | ||
167 | |||
168 | if (selectionNode != undefined) { | ||
169 | valueElement = MochiKit.DOM.getFirstElementByTagAndClassName('*', 'value', selectionNode); | ||
170 | //console.log("-- valueElement", valueElement); | ||
171 | } | ||
172 | |||
173 | if ((valueElement != null) && (valueElement != selectionNode)) { | ||
174 | var range; | ||
175 | range = MochiKit.DOM.currentDocument().createRange(); | ||
176 | range.selectNodeContents(valueElement); | ||
177 | selection.removeAllRanges(); | ||
178 | selection.addRange(range); | ||
179 | |||
180 | anEvent.preventDefault(); | ||
181 | anEvent.stopPropagation(); | ||
182 | |||
183 | //console.log("updated selection", MochiKit.DOM.currentWindow().getSelection()); | ||
184 | } | ||
185 | //console.log("-----------"); | ||
186 | }, | ||
187 | |||
188 | //------------------------------------------------------------------------- | ||
189 | |||
133 | run: function (parameters) { | 190 | run: function (parameters) { |
134 | var shouldShowRegistrationForm; | 191 | var shouldShowRegistrationForm; |
192 | varcanRegisterNewUsers; | ||
193 | |||
194 | canRegisterNewUsers = Clipperz.PM.Proxy.defaultProxy.canRegisterNewUsers(); | ||
135 | 195 | ||
136 | this.selectInitialProxy(); | 196 | this.selectInitialProxy(); |
137 | shouldShowRegistrationForm = parameters['shouldShowRegistrationForm'] && this.proxy().canRegisterNewUsers(); | 197 | shouldShowRegistrationForm = parameters['shouldShowRegistrationForm'] && canRegisterNewUsers; |
138 | this.pages()['loginPage'].setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable': this.proxy().canRegisterNewUsers()}); | 198 | this.pages()['loginPage'].setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable':canRegisterNewUsers}); |
139 | 199 | ||
140 | if (shouldShowRegistrationForm) { | 200 | if (shouldShowRegistrationForm) { |
141 | this.showRegistrationForm(); | 201 | this.showRegistrationForm(); |
142 | } else { | 202 | } else { |
143 | this.showLoginForm(); | 203 | this.showLoginForm(); |
144 | } | 204 | } |
145 | this.overlay().done("", 0.5); | 205 | this.overlay().done("", 0.5); |
146 | }, | 206 | }, |
147 | 207 | ||
148 | //------------------------------------------------------------------------- | 208 | //------------------------------------------------------------------------- |
149 | 209 | ||
150 | showLoginForm: function () { | 210 | showLoginForm: function () { |
151 | varloginFormPage; | 211 | varloginFormPage; |
152 | 212 | ||
153 | loginFormPage = this.pages()['loginPage']; | 213 | loginFormPage = this.pages()['loginPage']; |
154 | loginFormPage.setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable': this.proxy().canRegisterNewUsers()}); | 214 | loginFormPage.setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable':Clipperz.PM.Proxy.defaultProxy.canRegisterNewUsers()}); |
155 | this.moveInPage(this.currentPage(), 'loginPage'); | 215 | this.moveInPage(this.currentPage(), 'loginPage'); |
156 | MochiKit.Async.callLater(0.5, MochiKit.Base.method(loginFormPage, 'setInitialFocus')); | 216 | MochiKit.Async.callLater(0.5, MochiKit.Base.method(loginFormPage, 'setInitialFocus')); |
157 | }, | 217 | }, |
158 | 218 | ||
159 | showRegistrationForm: function () { | 219 | showRegistrationForm: function () { |
160 | var currentPage; | 220 | var currentPage; |
161 | varregistrationPage; | 221 | varregistrationPage; |
162 | 222 | ||
163 | currentPage = this.currentPage(); | 223 | currentPage = this.currentPage(); |
164 | registrationPage = this.pages()['registrationPage']; | 224 | registrationPage = this.pages()['registrationPage']; |
165 | this.setCurrentPage('loginPage'); | 225 | this.setCurrentPage('loginPage'); |
166 | registrationPage.setProps({}); | 226 | registrationPage.setProps({}); |
167 | this.moveInPage(currentPage, 'registrationPage'); | 227 | this.moveInPage(currentPage, 'registrationPage'); |
168 | MochiKit.Async.callLater(0.5, MochiKit.Base.method(registrationPage, 'setInitialFocus')); | 228 | MochiKit.Async.callLater(0.5, MochiKit.Base.method(registrationPage, 'setInitialFocus')); |
169 | }, | 229 | }, |
170 | 230 | ||
171 | //========================================================================= | 231 | //========================================================================= |
172 | 232 | ||
173 | doLogin: function (event) { | 233 | doLogin: function (event) { |
174 | varcredentials; | 234 | varcredentials; |
175 | var getPassphraseDelegate; | 235 | var getPassphraseDelegate; |
176 | varuser; | 236 | varuser; |
177 | 237 | ||
178 | user = null; | 238 | user = null; |
@@ -302,95 +362,108 @@ MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, { | |||
302 | }, this)); | 362 | }, this)); |
303 | deferredResult.callback(); | 363 | deferredResult.callback(); |
304 | 364 | ||
305 | return deferredResult; | 365 | return deferredResult; |
306 | }, | 366 | }, |
307 | 367 | ||
308 | filter: function (){ | 368 | filter: function (){ |
309 | return this._filter; | 369 | return this._filter; |
310 | }, | 370 | }, |
311 | 371 | ||
312 | setFilter: function (aValue) { | 372 | setFilter: function (aValue) { |
313 | this._filter = aValue; | 373 | this._filter = aValue; |
314 | }, | 374 | }, |
315 | 375 | ||
316 | searchCards: function (someParameters) { | 376 | searchCards: function (someParameters) { |
317 | //console.log("SEARCH CARDS", someParameters); | 377 | //console.log("SEARCH CARDS", someParameters); |
318 | this.setFilter(someParameters); | 378 | this.setFilter(someParameters); |
319 | this.showRecordList(); | 379 | this.showRecordList(); |
320 | }, | 380 | }, |
321 | 381 | ||
322 | //========================================================================= | 382 | //========================================================================= |
323 | 383 | ||
324 | runApplication: function () { | 384 | runApplication: function () { |
325 | MochiKit.Signal.connect(window, 'onpopstate',MochiKit.Base.method(this, 'historyGoBack')); | 385 | MochiKit.Signal.connect(window, 'onpopstate',MochiKit.Base.method(this, 'historyGoBack')); |
386 | /// TODO: remove this TEST HACK | ||
326 | this.moveInPage(this.currentPage(), 'cardListPage'); | 387 | this.moveInPage(this.currentPage(), 'cardListPage'); |
327 | return this.showRecordList(); | 388 | return this.showRecordList(); |
389 | |||
390 | // this.moveInPage(this.currentPage(), 'preferencePage'); | ||
328 | }, | 391 | }, |
329 | 392 | ||
330 | showRecord: function (aRecordReference) { | 393 | showRecord: function (aRecordReference) { |
331 | //console.log("Show Record", aRecordReference); | 394 | //console.log("Show Record", aRecordReference); |
332 | vardeferredResult; | 395 | vardeferredResult; |
333 | 396 | ||
334 | this.pages()['cardListPage'].setProps({selectedCard:aRecordReference}); | 397 | this.pages()['cardListPage'].setProps({selectedCard:aRecordReference}); |
335 | deferredResult = new Clipperz.Async.Deferred('MainController.runApplication', {trace:false}); | 398 | deferredResult = new Clipperz.Async.Deferred('MainController.runApplication', {trace:false}); |
336 | // deferredResult.addMethod(this.user(), 'getRecord', aRecordReference['_reference']); | ||
337 | deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); | 399 | deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); |
338 | deferredResult.addMethodcaller('content'); | 400 | deferredResult.addMethodcaller('content'); |
339 | deferredResult.addCallback(MochiKit.Base.bind(function (aCard) { | 401 | deferredResult.addCallback(MochiKit.Base.bind(function (aCard) { |
340 | //console.log("CARD DETAILS", aCard); | 402 | //console.log("CARD DETAILS", aCard); |
341 | this.pages()['cardDetailPage'].setProps({card: aCard}); | 403 | this.pages()['cardDetailPage'].setProps({card: aCard}); |
342 | this.pages()['cardListPage'].setProps({selectedCard: null}); | 404 | this.pages()['cardListPage'].setProps({selectedCard: null}); |
343 | }, this)); | 405 | }, this)); |
344 | deferredResult.addMethod(this, 'moveInPage', this.currentPage(), 'cardDetailPage', true); | 406 | deferredResult.addMethod(this, 'moveInPage', this.currentPage(), 'cardDetailPage', true); |
345 | deferredResult.callback(); | 407 | deferredResult.callback(); |
346 | 408 | ||
347 | return deferredResult; | 409 | return deferredResult; |
348 | }, | 410 | }, |
349 | 411 | ||
350 | runDirectLogin: function (someParameters) { | 412 | runDirectLogin: function (someParameters) { |
351 | console.log("RUN DIRECT LOGIN", someParameters); | 413 | //console.log("RUN DIRECT LOGIN", someParameters); |
352 | vardeferredResult; | 414 | vardeferredResult; |
353 | 415 | ||
354 | // this.pages()['cardListPage'].setProps({selectedCard:aRecordReference}); | ||
355 | deferredResult = new Clipperz.Async.Deferred('MainController.runDirectLogin', {trace:false}); | 416 | deferredResult = new Clipperz.Async.Deferred('MainController.runDirectLogin', {trace:false}); |
356 | // deferredResult.addMethod(this.user(), 'getRecord', aRecordReference['_reference']); | ||
357 | deferredResult.addMethod(this.user(), 'getRecord', someParameters['record']); | 417 | deferredResult.addMethod(this.user(), 'getRecord', someParameters['record']); |
358 | deferredResult.addMethodcaller('directLoginWithReference', someParameters['directLogin']); | 418 | deferredResult.addMethodcaller('directLoginWithReference', someParameters['directLogin']); |
359 | deferredResult.addCallback(Clipperz.PM.UI.DirectLoginRunner.openDirectLogin); | 419 | deferredResult.addCallback(Clipperz.PM.UI.DirectLoginRunner.openDirectLogin); |
360 | deferredResult.callback(); | 420 | deferredResult.callback(); |
361 | 421 | ||
362 | return deferredResult; | 422 | return deferredResult; |
363 | }, | 423 | }, |
364 | 424 | ||
365 | shouldExitApp: function (anEvent) { | 425 | shouldExitApp: function (anEvent) { |
366 | console.log("SHOULD EXIT APP"); | 426 | //console.log("SHOULD EXIT APP"); |
367 | anEvent.preventDefault(); | 427 | anEvent.preventDefault(); |
368 | anEvent.stopPropagation(); | 428 | anEvent.stopPropagation(); |
369 | }, | 429 | }, |
370 | 430 | ||
371 | //========================================================================= | 431 | //========================================================================= |
372 | 432 | ||
433 | showPreferences: function (anEvent) { | ||
434 | vardeferredResult; | ||
435 | |||
436 | this.pages()['preferencePage'].setProps({}); | ||
437 | deferredResult = new Clipperz.Async.Deferred('MainController.showPreferences', {trace:false}); | ||
438 | deferredResult.addMethod(this, 'moveInPage', this.currentPage(), 'preferencePage', true); | ||
439 | deferredResult.callback(); | ||
440 | |||
441 | return deferredResult; | ||
442 | }, | ||
443 | |||
444 | //========================================================================= | ||
445 | |||
373 | genericErrorHandler: function (anEvent, anError) { | 446 | genericErrorHandler: function (anEvent, anError) { |
374 | var errorMessage; | 447 | var errorMessage; |
375 | varresult; | 448 | varresult; |
376 | 449 | ||
377 | result = anError; | 450 | result = anError; |
378 | errorMessage = "login failed"; | 451 | errorMessage = "login failed"; |
379 | 452 | ||
380 | if (anError['isPermanent'] === true) { | 453 | if (anError['isPermanent'] === true) { |
381 | this.pages()['errorPage'].setProps({message:anError.message}); | 454 | this.pages()['errorPage'].setProps({message:anError.message}); |
382 | this.moveInPage(this.currentPage(), 'errorPage'); | 455 | this.moveInPage(this.currentPage(), 'errorPage'); |
383 | errorMessage = "failure"; | 456 | errorMessage = "failure"; |
384 | } else { | 457 | } else { |
385 | if ('pin' in anEvent) { | 458 | if ('pin' in anEvent) { |
386 | errorCount = Clipperz.PM.PIN.recordFailedAttempt(); | 459 | errorCount = Clipperz.PM.PIN.recordFailedAttempt(); |
387 | if (errorCount == -1) { | 460 | if (errorCount == -1) { |
388 | errorMessage = "PIN resetted"; | 461 | errorMessage = "PIN resetted"; |
389 | } | 462 | } |
390 | } | 463 | } |
391 | } | 464 | } |
392 | this.overlay().failed(errorMessage, 1); | 465 | this.overlay().failed(errorMessage, 1); |
393 | 466 | ||
394 | return result; | 467 | return result; |
395 | }, | 468 | }, |
396 | 469 | ||
@@ -459,33 +532,52 @@ console.log("SHOULD EXIT APP"); | |||
459 | 532 | ||
460 | shouldAddItemToHistory = typeof(addToHistory) == 'undefined' ? false : addToHistory; | 533 | shouldAddItemToHistory = typeof(addToHistory) == 'undefined' ? false : addToHistory; |
461 | 534 | ||
462 | this.slidePage(MochiKit.DOM.getElement(fromPage), MochiKit.DOM.getElement(toPage), 'LEFT'); | 535 | this.slidePage(MochiKit.DOM.getElement(fromPage), MochiKit.DOM.getElement(toPage), 'LEFT'); |
463 | this.setCurrentPage(toPage); | 536 | this.setCurrentPage(toPage); |
464 | 537 | ||
465 | if (shouldAddItemToHistory) { | 538 | if (shouldAddItemToHistory) { |
466 | //console.log("ADD ITEM TO HISTORY"); | 539 | //console.log("ADD ITEM TO HISTORY"); |
467 | //console.log("ADD ITEM TO HISTORY - window", window); | 540 | //console.log("ADD ITEM TO HISTORY - window", window); |
468 | //console.log("ADD ITEM TO HISTORY - window.history", window.history); | 541 | //console.log("ADD ITEM TO HISTORY - window.history", window.history); |
469 | window.history.pushState({'fromPage': fromPage, 'toPage': toPage}); | 542 | window.history.pushState({'fromPage': fromPage, 'toPage': toPage}); |
470 | //# window.history.pushState(); | 543 | //# window.history.pushState(); |
471 | //console.log("ADDED ITEM TO HISTORY"); | 544 | //console.log("ADDED ITEM TO HISTORY"); |
472 | } else { | 545 | } else { |
473 | //console.log("Skip HISTORY"); | 546 | //console.log("Skip HISTORY"); |
474 | } | 547 | } |
475 | }, | 548 | }, |
476 | 549 | ||
477 | moveOutPage: function (fromPage, toPage) { | 550 | moveOutPage: function (fromPage, toPage) { |
478 | this.slidePage(MochiKit.DOM.getElement(fromPage), MochiKit.DOM.getElement(toPage), 'RIGHT'); | 551 | this.slidePage(MochiKit.DOM.getElement(fromPage), MochiKit.DOM.getElement(toPage), 'RIGHT'); |
479 | this.setCurrentPage(toPage); | 552 | this.setCurrentPage(toPage); |
480 | }, | 553 | }, |
481 | 554 | ||
482 | //========================================================================= | 555 | //========================================================================= |
556 | |||
557 | synchronizeLocalData: function (anEvent) { | ||
558 | vardeferredResult; | ||
559 | |||
560 | deferredResult = new Clipperz.Async.Deferred('MainController.synchronizeLocalData', {trace:true}); | ||
561 | // deferredResult.addMethod(this.proxy(), 'message', 'downloadAccountData', {}); | ||
562 | deferredResult.addMethod(this.user().connection(), 'message', 'downloadAccountData', {}); | ||
563 | deferredResult.addCallback(function (aResult) { | ||
564 | Clipperz.PM.DataModel.devicePreferences.setAccountDataWityResponse(aResult); | ||
565 | // localStorage.setItem('clipperz_dump_data', aResult['data']); | ||
566 | // localStorage.setItem('clipperz_dump_version', aResult['version']); | ||
567 | // localStorage.setItem('clipperz_dump_date', new Date()); | ||
568 | }) | ||
569 | deferredResult.callback(); | ||
570 | |||
571 | return deferredResult; | ||
572 | }, | ||
573 | |||
574 | //========================================================================= | ||
483 | /* | 575 | /* |
484 | wrongAppVersion: function (anError) { | 576 | wrongAppVersion: function (anError) { |
485 | // this.pages()['errorPage'].setProps({message:anError.message}); | 577 | // this.pages()['errorPage'].setProps({message:anError.message}); |
486 | // this.moveInPage('errorPage', this.currentPage()); | 578 | // this.moveInPage('errorPage', this.currentPage()); |
487 | }, | 579 | }, |
488 | */ | 580 | */ |
489 | //========================================================================= | 581 | //========================================================================= |
490 | __syntaxFix__: "syntax fix" | 582 | __syntaxFix__: "syntax fix" |
491 | }); | 583 | }); |