19 files changed, 1477 insertions, 791 deletions
diff --git a/frontend/gamma/js/Clipperz/PM/Connection.js b/frontend/gamma/js/Clipperz/PM/Connection.js index b4e8aaa..a05a310 100644 --- a/frontend/gamma/js/Clipperz/PM/Connection.js +++ b/frontend/gamma/js/Clipperz/PM/Connection.js | |||
@@ -1,91 +1,92 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2011 Clipperz Srl | 3 | Copyright 2008-2011 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz Community Edition. | 5 | This file is part of Clipperz Community Edition. |
6 | Clipperz Community Edition is an online password manager. | 6 | Clipperz Community Edition is an online password manager. |
7 | For further information about its features and functionalities please | 7 | For further information about its features and functionalities please |
8 | refer to http://www.clipperz.com. | 8 | refer to http://www.clipperz.com. |
9 | 9 | ||
10 | * Clipperz Community Edition is free software: you can redistribute | 10 | * Clipperz Community Edition is free software: you can redistribute |
11 | it and/or modify it under the terms of the GNU Affero General Public | 11 | it and/or modify it under the terms of the GNU Affero General Public |
12 | License as published by the Free Software Foundation, either version | 12 | License as published by the Free Software Foundation, either version |
13 | 3 of the License, or (at your option) any later version. | 13 | 3 of the License, or (at your option) any later version. |
14 | 14 | ||
15 | * Clipperz Community Edition is distributed in the hope that it will | 15 | * Clipperz Community Edition is distributed in the hope that it will |
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | 16 | be useful, but WITHOUT ANY WARRANTY; without even the implied |
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. | 18 | See the GNU Affero General Public License for more details. |
19 | 19 | ||
20 | * You should have received a copy of the GNU Affero General Public | 20 | * You should have received a copy of the GNU Affero General Public |
21 | License along with Clipperz Community Edition. If not, see | 21 | License along with Clipperz Community Edition. If not, see |
22 | <http://www.gnu.org/licenses/>. | 22 | <http://www.gnu.org/licenses/>. |
23 | 23 | ||
24 | */ | 24 | */ |
25 | 25 | ||
26 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | 26 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } |
27 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | 27 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } |
28 | 28 | ||
29 | //----------------------------------------------------------------------------- | 29 | //----------------------------------------------------------------------------- |
30 | // | 30 | // |
31 | // Abstract C O N N E C T I O N class | 31 | // Abstract C O N N E C T I O N class |
32 | // | 32 | // |
33 | //----------------------------------------------------------------------------- | 33 | //----------------------------------------------------------------------------- |
34 | 34 | ||
35 | Clipperz.PM.Connection = function (args) { | 35 | Clipperz.PM.Connection = function (args) { |
36 | args = args || {}; | 36 | args = args || {}; |
37 | 37 | ||
38 | this._proxy = args.proxy || Clipperz.PM.Proxy.defaultProxy; | 38 | this._proxy = args.proxy || Clipperz.PM.Proxy.defaultProxy; |
39 | this._getCredentialsFunction = args.getCredentialsFunction; | 39 | this._getCredentialsFunction = args.getCredentialsFunction; |
40 | 40 | ||
41 | this._clipperz_pm_crypto_version = null; | 41 | this._clipperz_pm_crypto_version = null; |
42 | this._connectionId = null; | 42 | this._connectionId = null; |
43 | this._sharedSecret = null; | 43 | this._sharedSecret = null; |
44 | this._serverLockValue = null; | ||
44 | 45 | ||
45 | return this; | 46 | return this; |
46 | } | 47 | } |
47 | 48 | ||
48 | Clipperz.PM.Connection.prototype = MochiKit.Base.update(null, { | 49 | Clipperz.PM.Connection.prototype = MochiKit.Base.update(null, { |
49 | 50 | ||
50 | 'toString': function() { | 51 | 'toString': function() { |
51 | return "Connection [" + this.version() + "]"; | 52 | return "Connection [" + this.version() + "]"; |
52 | }, | 53 | }, |
53 | 54 | ||
54 | //========================================================================= | 55 | //========================================================================= |
55 | 56 | ||
56 | 'version': function() { | 57 | 'version': function() { |
57 | throw Clipperz.Base.exception.AbstractMethod; | 58 | throw Clipperz.Base.exception.AbstractMethod; |
58 | }, | 59 | }, |
59 | 60 | ||
60 | 'clipperz_pm_crypto_version': function() { | 61 | 'clipperz_pm_crypto_version': function() { |
61 | if (this._clipperz_pm_crypto_version == null) { | 62 | if (this._clipperz_pm_crypto_version == null) { |
62 | var connectionVersions; | 63 | var connectionVersions; |
63 | varversions; | 64 | varversions; |
64 | varversion; | 65 | varversion; |
65 | var i, c; | 66 | var i, c; |
66 | 67 | ||
67 | version = null; | 68 | version = null; |
68 | connectionVersions = Clipperz.PM.Connection.communicationProtocol.versions; | 69 | connectionVersions = Clipperz.PM.Connection.communicationProtocol.versions; |
69 | versions = MochiKit.Base.keys(connectionVersions); | 70 | versions = MochiKit.Base.keys(connectionVersions); |
70 | c = versions.length; | 71 | c = versions.length; |
71 | for (i=0; i<c; i++) { | 72 | for (i=0; i<c; i++) { |
72 | if (! (versions[i] == 'current')) { | 73 | if (! (versions[i] == 'current')) { |
73 | if (this instanceof connectionVersions[versions[i]]) { | 74 | if (this instanceof connectionVersions[versions[i]]) { |
74 | version = versions[i]; | 75 | version = versions[i]; |
75 | }; | 76 | }; |
76 | } | 77 | } |
77 | } | 78 | } |
78 | 79 | ||
79 | this._clipperz_pm_crypto_version = version; | 80 | this._clipperz_pm_crypto_version = version; |
80 | } | 81 | } |
81 | 82 | ||
82 | return this._clipperz_pm_crypto_version; | 83 | return this._clipperz_pm_crypto_version; |
83 | }, | 84 | }, |
84 | 85 | ||
85 | //------------------------------------------------------------------------- | 86 | //------------------------------------------------------------------------- |
86 | 87 | ||
87 | 'defaultErrorHandler': function(anErrorString, anException) { | 88 | 'defaultErrorHandler': function(anErrorString, anException) { |
88 | MochiKit.Logging.logError("### Connection.defaultErrorHandler: " + anErrorString + " (" + anException + ")"); | 89 | MochiKit.Logging.logError("### Connection.defaultErrorHandler: " + anErrorString + " (" + anException + ")"); |
89 | }, | 90 | }, |
90 | 91 | ||
91 | //------------------------------------------------------------------------- | 92 | //------------------------------------------------------------------------- |
@@ -101,96 +102,106 @@ MochiKit.Logging.logError("### Connection.defaultErrorHandler: " + anErrorString | |||
101 | //========================================================================= | 102 | //========================================================================= |
102 | 103 | ||
103 | 'proxy': function () { | 104 | 'proxy': function () { |
104 | return this._proxy; | 105 | return this._proxy; |
105 | }, | 106 | }, |
106 | 107 | ||
107 | //========================================================================= | 108 | //========================================================================= |
108 | 109 | ||
109 | 'register': function () { | 110 | 'register': function () { |
110 | throw Clipperz.Base.exception.AbstractMethod; | 111 | throw Clipperz.Base.exception.AbstractMethod; |
111 | }, | 112 | }, |
112 | 113 | ||
113 | 'login': function() { | 114 | 'login': function() { |
114 | throw Clipperz.Base.exception.AbstractMethod; | 115 | throw Clipperz.Base.exception.AbstractMethod; |
115 | }, | 116 | }, |
116 | 117 | ||
117 | //------------------------------------------------------------------------- | 118 | //------------------------------------------------------------------------- |
118 | 119 | ||
119 | 'message': function(someArguments, aCallback) { | 120 | 'message': function(someArguments, aCallback) { |
120 | throw Clipperz.Base.exception.AbstractMethod; | 121 | throw Clipperz.Base.exception.AbstractMethod; |
121 | }, | 122 | }, |
122 | 123 | ||
123 | //------------------------------------------------------------------------- | 124 | //------------------------------------------------------------------------- |
124 | 125 | ||
125 | 'serverSideUserCredentials': function() { | 126 | 'serverSideUserCredentials': function() { |
126 | throw Clipperz.Base.exception.AbstractMethod; | 127 | throw Clipperz.Base.exception.AbstractMethod; |
127 | }, | 128 | }, |
128 | 129 | ||
129 | //========================================================================= | 130 | //========================================================================= |
130 | 131 | ||
131 | 'sharedSecret': function () { | 132 | 'sharedSecret': function () { |
132 | return this._sharedSecret; | 133 | return this._sharedSecret; |
133 | }, | 134 | }, |
134 | 135 | ||
135 | 'setSharedSecret': function (aValue) { | 136 | 'setSharedSecret': function (aValue) { |
136 | this._sharedSecret = aValue; | 137 | this._sharedSecret = aValue; |
137 | }, | 138 | }, |
138 | 139 | ||
139 | //------------------------------------------------------------------------- | 140 | //------------------------------------------------------------------------- |
140 | 141 | ||
141 | 'connectionId': function() { | 142 | 'connectionId': function() { |
142 | return this._connectionId; | 143 | return this._connectionId; |
143 | }, | 144 | }, |
144 | 145 | ||
145 | 'setConnectionId': function(aValue) { | 146 | 'setConnectionId': function(aValue) { |
146 | this._connectionId = aValue; | 147 | this._connectionId = aValue; |
147 | }, | 148 | }, |
148 | 149 | ||
150 | //------------------------------------------------------------------------- | ||
151 | |||
152 | 'serverLockValue': function () { | ||
153 | return this._serverLockValue; | ||
154 | }, | ||
155 | |||
156 | 'setServerLockValue': function (aValue) { | ||
157 | this._serverLockValue = aValue; | ||
158 | }, | ||
159 | |||
149 | //========================================================================= | 160 | //========================================================================= |
150 | /* | 161 | /* |
151 | //TODO: ????? | 162 | //TODO: ????? |
152 | 'oneTimePassword': function() { | 163 | 'oneTimePassword': function() { |
153 | return this._oneTimePassword; | 164 | return this._oneTimePassword; |
154 | }, | 165 | }, |
155 | 166 | ||
156 | 'setOneTimePassword': function(aValue) { | 167 | 'setOneTimePassword': function(aValue) { |
157 | this._oneTimePassword = aValue; | 168 | this._oneTimePassword = aValue; |
158 | }, | 169 | }, |
159 | */ | 170 | */ |
160 | //========================================================================= | 171 | //========================================================================= |
161 | 172 | ||
162 | 'reset': function() { | 173 | 'reset': function() { |
163 | this.setSharedSecret(null); | 174 | this.setSharedSecret(null); |
164 | this.setConnectionId(null); | 175 | this.setConnectionId(null); |
165 | }, | 176 | }, |
166 | 177 | ||
167 | //========================================================================= | 178 | //========================================================================= |
168 | __syntaxFix__: "syntax fix" | 179 | __syntaxFix__: "syntax fix" |
169 | 180 | ||
170 | } | 181 | } |
171 | ); | 182 | ); |
172 | 183 | ||
173 | 184 | ||
174 | if (typeof(Clipperz.PM.Connection.SRP) == 'undefined') { Clipperz.PM.Connection.SRP = {}; } | 185 | if (typeof(Clipperz.PM.Connection.SRP) == 'undefined') { Clipperz.PM.Connection.SRP = {}; } |
175 | //----------------------------------------------------------------------------- | 186 | //----------------------------------------------------------------------------- |
176 | // | 187 | // |
177 | // S R P [ 1 . 0 ] C O N N E C T I O N class | 188 | // S R P [ 1 . 0 ] C O N N E C T I O N class |
178 | // | 189 | // |
179 | //----------------------------------------------------------------------------- | 190 | //----------------------------------------------------------------------------- |
180 | 191 | ||
181 | Clipperz.PM.Connection.SRP['1.0'] = function (args) { | 192 | Clipperz.PM.Connection.SRP['1.0'] = function (args) { |
182 | Clipperz.PM.Connection.call(this, args); | 193 | Clipperz.PM.Connection.call(this, args); |
183 | 194 | ||
184 | return this; | 195 | return this; |
185 | } | 196 | } |
186 | 197 | ||
187 | Clipperz.PM.Connection.SRP['1.0'].prototype = MochiKit.Base.update(new Clipperz.PM.Connection(), { | 198 | Clipperz.PM.Connection.SRP['1.0'].prototype = MochiKit.Base.update(new Clipperz.PM.Connection(), { |
188 | 199 | ||
189 | 'version': function() { | 200 | 'version': function() { |
190 | return '1.0'; | 201 | return '1.0'; |
191 | }, | 202 | }, |
192 | 203 | ||
193 | //========================================================================= | 204 | //========================================================================= |
194 | 205 | ||
195 | 'register': function (someUserData) { | 206 | 'register': function (someUserData) { |
196 | vardeferredResult; | 207 | vardeferredResult; |
@@ -275,227 +286,239 @@ Clipperz.PM.Connection.SRP['1.0'].prototype = MochiKit.Base.update(new Clipperz. | |||
275 | 'parameters': { | 286 | 'parameters': { |
276 | 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(anUsername, aOneTimePassword), | 287 | 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(anUsername, aOneTimePassword), |
277 | 'oneTimePasswordKeyChecksum': Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(anUsername, aOneTimePassword) | 288 | 'oneTimePasswordKeyChecksum': Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(anUsername, aOneTimePassword) |
278 | } | 289 | } |
279 | } | 290 | } |
280 | 291 | ||
281 | return args; | 292 | return args; |
282 | }, anUsername, oneTimePassword); | 293 | }, anUsername, oneTimePassword); |
283 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'OTP_login_loadingOTP'); | 294 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'OTP_login_loadingOTP'); |
284 | deferredResult.addCallback(MochiKit.Base.method(Clipperz.PM.Proxy.defaultProxy, 'handshake')); | 295 | deferredResult.addCallback(MochiKit.Base.method(Clipperz.PM.Proxy.defaultProxy, 'handshake')); |
285 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'OTP_login_extractingPassphrase'); | 296 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'OTP_login_extractingPassphrase'); |
286 | deferredResult.addCallback(function(aResult) { | 297 | deferredResult.addCallback(function(aResult) { |
287 | return Clipperz.PM.Crypto.deferredDecrypt(oneTimePassword, aResult['data'], aResult['version']); | 298 | return Clipperz.PM.Crypto.deferredDecrypt(oneTimePassword, aResult['data'], aResult['version']); |
288 | }); | 299 | }); |
289 | deferredResult.addCallback(function(aResult) { | 300 | deferredResult.addCallback(function(aResult) { |
290 | return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString(); | 301 | return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString(); |
291 | }); | 302 | }); |
292 | deferredResult.addMethod(this, 'doLoginWithUsernameAndPassphrase', anUsername), | 303 | deferredResult.addMethod(this, 'doLoginWithUsernameAndPassphrase', anUsername), |
293 | */ | 304 | */ |
294 | var args; | 305 | var args; |
295 | var normalizedOTP; | 306 | var normalizedOTP; |
296 | 307 | ||
297 | normalizedOTP = Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(someParameters['password']); | 308 | normalizedOTP = Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(someParameters['password']); |
298 | 309 | ||
299 | args = { | 310 | args = { |
300 | 'message': 'oneTimePassword', | 311 | 'message': 'oneTimePassword', |
301 | 'version': Clipperz.PM.Connection.communicationProtocol.currentVersion, | 312 | 'version': Clipperz.PM.Connection.communicationProtocol.currentVersion, |
302 | 'parameters': { | 313 | 'parameters': { |
303 | 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(someParameters['username'], normalizedOTP), | 314 | 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(someParameters['username'], normalizedOTP), |
304 | 'oneTimePasswordKeyChecksum':Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(someParameters['username'], normalizedOTP) | 315 | 'oneTimePasswordKeyChecksum':Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(someParameters['username'], normalizedOTP) |
305 | } | 316 | } |
306 | } | 317 | } |
307 | 318 | ||
308 | return Clipperz.Async.callbacks("Connction.redeemOTP", [ | 319 | return Clipperz.Async.callbacks("Connction.redeemOTP", [ |
309 | MochiKit.Base.method(this.proxy(), 'handshake', args), | 320 | MochiKit.Base.method(this.proxy(), 'handshake', args), |
310 | function(aResult) { | 321 | function(aResult) { |
311 | return Clipperz.PM.Crypto.deferredDecrypt({ | 322 | return Clipperz.PM.Crypto.deferredDecrypt({ |
312 | value:aResult['data'], | 323 | value:aResult['data'], |
313 | key:normalizedOTP, | 324 | key:normalizedOTP, |
314 | version:aResult['version'] | 325 | version:aResult['version'] |
315 | }); | 326 | }); |
316 | }, | 327 | }, |
317 | function(aResult) { | 328 | function(aResult) { |
318 | return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString(); | 329 | return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString(); |
319 | } | 330 | } |
320 | ], {trace:false}) | 331 | ], {trace:false}) |
321 | }, | 332 | }, |
322 | 333 | ||
323 | 'login': function(/*anUsername, aPassphrase*/) { | 334 | 'login': function(isReconnecting) { |
324 | vardeferredResult; | 335 | vardeferredResult; |
325 | var cryptoVersion; | 336 | var cryptoVersion; |
326 | var srpConnection; | 337 | var srpConnection; |
327 | 338 | ||
328 | cryptoVersion = this.clipperz_pm_crypto_version(); | 339 | cryptoVersion = this.clipperz_pm_crypto_version(); |
329 | |||
330 | deferredResult = new Clipperz.Async.Deferred("Connection.login", {trace:false}); | 340 | deferredResult = new Clipperz.Async.Deferred("Connection.login", {trace:false}); |
331 | deferredResult.addCallback(this.getCredentialsFunction()); | 341 | deferredResult.addCallback(this.getCredentialsFunction()); |
332 | deferredResult.addMethod(this, 'normalizedCredentials'); | 342 | deferredResult.addMethod(this, 'normalizedCredentials'); |
333 | // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_sendingCredentials'); | 343 | // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_sendingCredentials'); |
334 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); | 344 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); |
335 | deferredResult.addCallback(MochiKit.Base.bind(function(someCredentials) { | 345 | deferredResult.addCallback(MochiKit.Base.bind(function(someCredentials) { |
336 | srpConnection = new Clipperz.Crypto.SRP.Connection({ C:someCredentials['username'], P:someCredentials['password'], hash:this.hash() }); | 346 | srpConnection = new Clipperz.Crypto.SRP.Connection({ C:someCredentials['username'], P:someCredentials['password'], hash:this.hash() }); |
337 | }, this)); | 347 | }, this)); |
338 | deferredResult.addCallback(function() { | 348 | deferredResult.addCallback(function() { |
339 | var result; | 349 | var result; |
340 | 350 | ||
341 | result = { | 351 | result = { |
342 | message: 'connect', | 352 | message: 'connect', |
343 | version: cryptoVersion, | 353 | version: cryptoVersion, |
344 | parameters: { | 354 | parameters: { |
345 | C: srpConnection.C(), | 355 | C: srpConnection.C(), |
346 | A: srpConnection.A().asString(16) | 356 | A: srpConnection.A().asString(16) |
347 | // reconnecting: this.connectionId() | 357 | // reconnecting: this.connectionId() |
348 | } | 358 | } |
349 | }; | 359 | }; |
350 | 360 | ||
351 | // TODO: ????? | 361 | // TODO: ????? |
352 | // if (isReconnecting == true) { | 362 | // if (isReconnecting == true) { |
353 | // args.parameters['reconnecting'] = aConnection.connectionId(); | 363 | // args.parameters['reconnecting'] = aConnection.connectionId(); |
354 | // } | 364 | // } |
355 | 365 | ||
356 | return result; | 366 | return result; |
357 | }); | 367 | }); |
358 | deferredResult.addMethod(this.proxy(), 'handshake'); | 368 | deferredResult.addMethod(this.proxy(), 'handshake'); |
359 | // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_credentialVerification'); | 369 | // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_credentialVerification'); |
360 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); | 370 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); |
361 | deferredResult.addCallback(function(someParameters) { | 371 | deferredResult.addCallback(function(someParameters) { |
362 | var result; | 372 | var result; |
363 | 373 | ||
364 | srpConnection.set_s(new Clipperz.Crypto.BigInt(someParameters['s'], 16)); | 374 | srpConnection.set_s(new Clipperz.Crypto.BigInt(someParameters['s'], 16)); |
365 | srpConnection.set_B(new Clipperz.Crypto.BigInt(someParameters['B'], 16)); | 375 | srpConnection.set_B(new Clipperz.Crypto.BigInt(someParameters['B'], 16)); |
366 | 376 | ||
367 | //TODO: ????? | 377 | //TODO: ????? |
368 | // if (typeof(someParameters['oneTimePassword']) != 'undefined') { | 378 | // if (typeof(someParameters['oneTimePassword']) != 'undefined') { |
369 | // this.setOneTimePassword(someParameters['oneTimePassword']); | 379 | // this.setOneTimePassword(someParameters['oneTimePassword']); |
370 | // } | 380 | // } |
371 | 381 | ||
372 | result = { | 382 | result = { |
373 | message: 'credentialCheck', | 383 | message: 'credentialCheck', |
374 | version: cryptoVersion, | 384 | version: cryptoVersion, |
375 | parameters: { | 385 | parameters: { |
376 | M1: srpConnection.M1() | 386 | M1: srpConnection.M1() |
377 | } | 387 | } |
378 | }; | 388 | }; |
379 | 389 | ||
380 | return result; | 390 | return result; |
381 | }); | 391 | }); |
382 | deferredResult.addMethod(this.proxy(), 'handshake'); | 392 | deferredResult.addMethod(this.proxy(), 'handshake'); |
383 | deferredResult.addCallback(function(someParameters) { | 393 | deferredResult.addCallback(function(someParameters) { |
384 | var result; | 394 | var result; |
385 | 395 | ||
386 | if (someParameters['M2'] == srpConnection.M2()) { | 396 | if (someParameters['M2'] == srpConnection.M2()) { |
387 | result = MochiKit.Async.succeed(someParameters); | 397 | result = MochiKit.Async.succeed(someParameters); |
388 | } else { | 398 | } else { |
389 | result = MochiKit.Async.fail(Clipperz.PM.Connection.exception.WrongChecksum); | 399 | result = MochiKit.Async.fail(Clipperz.PM.Connection.exception.WrongChecksum); |
390 | } | 400 | } |
391 | 401 | ||
392 | return result; | 402 | return result; |
393 | }); | 403 | }); |
394 | deferredResult.addCallback(MochiKit.Base.bind(function(someParameters) { | 404 | deferredResult.addCallback(MochiKit.Base.bind(function(someParameters) { |
395 | this.setConnectionId(someParameters['connectionId']); | 405 | this.setConnectionId(someParameters['connectionId']); |
396 | this.setSharedSecret(srpConnection.K()); | 406 | this.setSharedSecret(srpConnection.K()); |
397 | 407 | ||
398 | // TODO: ????? | 408 | // TODO: ????? |
399 | // if (this.oneTimePassword() != null) { | 409 | // if (this.oneTimePassword() != null) { |
400 | /// ?? result = this.user().oneTimePasswordManager().archiveOneTimePassword(this.oneTimePassword())); | 410 | /// ?? result = this.user().oneTimePasswordManager().archiveOneTimePassword(this.oneTimePassword())); |
401 | // } | 411 | // } |
412 | |||
413 | if ((isReconnecting == true) && (this.serverLockValue() != someParameters['lock'])) { | ||
414 | throw Clipperz.PM.Connection.exception.StaleData; | ||
415 | } else { | ||
416 | this.setServerLockValue(someParameters['lock']); | ||
417 | } | ||
418 | |||
402 | return someParameters; | 419 | return someParameters; |
403 | }, this)); | 420 | }, this)); |
404 | // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_loggedIn'); | 421 | // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_loggedIn'); |
405 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); | 422 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); |
406 | deferredResult.addCallback(MochiKit.Async.succeed, {result:"done"}); | 423 | deferredResult.addCallback(MochiKit.Async.succeed, {result:"done"}); |
407 | 424 | ||
408 | deferredResult.callback(); | 425 | deferredResult.callback(); |
409 | 426 | ||
410 | return deferredResult; | 427 | return deferredResult; |
411 | }, | 428 | }, |
412 | 429 | ||
413 | //========================================================================= | 430 | //========================================================================= |
414 | 431 | ||
415 | 'logout': function() { | 432 | 'logout': function() { |
416 | return Clipperz.Async.callbacks("Connection.logout", [ | 433 | return Clipperz.Async.callbacks("Connection.logout", [ |
417 | MochiKit.Base.method(this, 'setSharedSecret'), | 434 | MochiKit.Base.method(this, 'setSharedSecret'), |
418 | MochiKit.Base.method(this.proxy(), 'logout', {}) | 435 | MochiKit.Base.method(this.proxy(), 'logout', {}) |
419 | ], {trace:false}); | 436 | ], {trace:false}); |
420 | }, | 437 | }, |
421 | 438 | ||
422 | //========================================================================= | 439 | //========================================================================= |
423 | 440 | ||
424 | 'ping': function () { | 441 | 'ping': function () { |
425 | //TODO: ping the server in order to have a valid session | 442 | //TODO: ping the server in order to have a valid session |
426 | }, | 443 | }, |
427 | 444 | ||
428 | //========================================================================= | 445 | //========================================================================= |
429 | 446 | ||
430 | 'message': function(aMessageName, someParameters) { | 447 | 'message': function(aMessageName, someParameters) { |
431 | var args; | 448 | var args; |
449 | var parameters; | ||
450 | |||
451 | parameters = someParameters || {}; | ||
452 | if (typeof(parameters['user']) != 'undefined') { | ||
453 | parameters['user']['lock'] = this.serverLockValue(); | ||
454 | } | ||
432 | 455 | ||
433 | //console.log(">>> Connection.message", aMessageName, someParameters); | 456 | //console.log(">>> Connection.message", aMessageName, someParameters); |
434 | args = { | 457 | args = { |
435 | message: aMessageName, | 458 | message: aMessageName, |
436 | srpSharedSecret: this.sharedSecret(), | 459 | srpSharedSecret: this.sharedSecret(), |
437 | parameters: (someParameters || {}) | 460 | // parameters: (someParameters || {}) |
461 | parameters: parameters | ||
438 | } | 462 | } |
439 | 463 | ||
440 | return this.sendMessage(args); | 464 | return this.sendMessage(args); |
441 | }, | 465 | }, |
442 | 466 | ||
443 | //------------------------------------------------------------------------- | 467 | //------------------------------------------------------------------------- |
444 | 468 | ||
445 | 'sendMessage': function(someArguments) { | 469 | 'sendMessage': function(someArguments) { |
446 | vardeferredResult; | 470 | vardeferredResult; |
447 | 471 | ||
448 | deferredResult = new Clipperz.Async.Deferred("Connection.sendMessage", {trace:false}); | 472 | deferredResult = new Clipperz.Async.Deferred("Connection.sendMessage", {trace:false}); |
449 | deferredResult.addMethod(this.proxy(), 'message', someArguments); | 473 | deferredResult.addMethod(this.proxy(), 'message', someArguments); |
450 | deferredResult.addCallback(MochiKit.Base.bind(function(res) { | 474 | deferredResult.addCallback(MochiKit.Base.bind(function(res) { |
451 | if (typeof(res['lock']) != 'undefined') { | 475 | if (typeof(res['lock']) != 'undefined') { |
452 | //TODO: ????? | 476 | this.setServerLockValue(res['lock']); |
453 | // ?? this.user().setLock(res['lock']); | ||
454 | } | 477 | } |
455 | return res; | 478 | return res; |
456 | }, this)); | 479 | }, this)); |
457 | 480 | ||
458 | deferredResult.addErrback(MochiKit.Base.method(this, 'messageExceptionHandler'), someArguments); | 481 | deferredResult.addErrback(MochiKit.Base.method(this, 'messageExceptionHandler'), someArguments); |
459 | deferredResult.callback(); | 482 | deferredResult.callback(); |
460 | 483 | ||
461 | return deferredResult | 484 | return deferredResult |
462 | }, | 485 | }, |
463 | 486 | ||
464 | //------------------------------------------------------------------------- | 487 | //------------------------------------------------------------------------- |
465 | 488 | ||
466 | 'messageExceptionHandler': function(anOriginalMessageArguments, anError) { | 489 | 'messageExceptionHandler': function(anOriginalMessageArguments, anError) { |
467 | var result; | 490 | var result; |
468 | 491 | ||
469 | console.log(">>> Connection.messageExceptionHandler", anError, anError.message); | 492 | console.log(">>> Connection.messageExceptionHandler", anError, anError.message); |
470 | if (anError instanceof MochiKit.Async.CancelledError) { | 493 | if (anError instanceof MochiKit.Async.CancelledError) { |
471 | result = anError; | 494 | result = anError; |
472 | } else { | 495 | } else { |
473 | if ((anError.message == 'Trying to communicate without an active connection')|| | 496 | if ((anError.message == 'Trying to communicate without an active connection')|| |
474 | (anError.message == 'No tollManager available for current session') | 497 | (anError.message == 'No tollManager available for current session') |
475 | ) { | 498 | ) { |
476 | result = this.reestablishConnection(anOriginalMessageArguments); | 499 | result = this.reestablishConnection(anOriginalMessageArguments); |
477 | } else if (anError.message == 'Session with stale data') { | 500 | } else if (anError.message == 'Session with stale data') { |
478 | MochiKit.Signal.signal(this, 'EXCEPTION'); | 501 | MochiKit.Signal.signal(this, 'EXCEPTION'); |
479 | } else { | 502 | } else { |
480 | result = anError; | 503 | result = anError; |
481 | } | 504 | } |
482 | } | 505 | } |
483 | console.log("<<< Connection.messageExceptionHandler", anError) | 506 | console.log("<<< Connection.messageExceptionHandler", anError) |
484 | 507 | ||
485 | return result;; | 508 | return result;; |
486 | }, | 509 | }, |
487 | 510 | ||
488 | //========================================================================= | 511 | //========================================================================= |
489 | 512 | ||
490 | 'reestablishConnection': function(anOriginalMessageArguments) { | 513 | 'reestablishConnection': function(anOriginalMessageArguments) { |
491 | var deferredResult; | 514 | var deferredResult; |
492 | 515 | ||
493 | deferredResult = new Clipperz.Async.Deferred("Connection.reestablishConnection"); | 516 | deferredResult = new Clipperz.Async.Deferred("Connection.reestablishConnection"); |
494 | deferredResult.addMethod(this, 'reset'); | 517 | deferredResult.addMethod(this, 'reset'); |
495 | deferredResult.addMethod(this, 'login', true); | 518 | deferredResult.addMethod(this, 'login', true); |
496 | deferredResult.addCallback(MochiKit.Base.bind(function(aMessage) { | 519 | deferredResult.addCallback(MochiKit.Base.bind(function(aMessage) { |
497 | aMessage['srpSharedSecret'] = this.sharedSecret(); | 520 | aMessage['srpSharedSecret'] = this.sharedSecret(); |
498 | return aMessage; | 521 | return aMessage; |
499 | }, this), anOriginalMessageArguments); | 522 | }, this), anOriginalMessageArguments); |
500 | deferredResult.addMethod(this, 'sendMessage'); | 523 | deferredResult.addMethod(this, 'sendMessage'); |
501 | deferredResult.addErrback(MochiKit.Signal.signal, this, 'EXCEPTION', null); | 524 | deferredResult.addErrback(MochiKit.Signal.signal, this, 'EXCEPTION', null); |
@@ -542,75 +565,76 @@ console.log("<<< Connection.messageExceptionHandler", anError) | |||
542 | 565 | ||
543 | }); | 566 | }); |
544 | 567 | ||
545 | 568 | ||
546 | 569 | ||
547 | //----------------------------------------------------------------------------- | 570 | //----------------------------------------------------------------------------- |
548 | // | 571 | // |
549 | // S R P [ 1 . 1 ] C O N N E C T I O N class | 572 | // S R P [ 1 . 1 ] C O N N E C T I O N class |
550 | // | 573 | // |
551 | //----------------------------------------------------------------------------- | 574 | //----------------------------------------------------------------------------- |
552 | 575 | ||
553 | Clipperz.PM.Connection.SRP['1.1'] = function (args) { | 576 | Clipperz.PM.Connection.SRP['1.1'] = function (args) { |
554 | Clipperz.PM.Connection.SRP['1.0'].call(this, args); | 577 | Clipperz.PM.Connection.SRP['1.0'].call(this, args); |
555 | 578 | ||
556 | return this; | 579 | return this; |
557 | } | 580 | } |
558 | 581 | ||
559 | Clipperz.PM.Connection.SRP['1.1'].prototype = MochiKit.Base.update(new Clipperz.PM.Connection.SRP['1.0'](), { | 582 | Clipperz.PM.Connection.SRP['1.1'].prototype = MochiKit.Base.update(new Clipperz.PM.Connection.SRP['1.0'](), { |
560 | 583 | ||
561 | 'version': function() { | 584 | 'version': function() { |
562 | return '1.1'; | 585 | return '1.1'; |
563 | }, | 586 | }, |
564 | 587 | ||
565 | //----------------------------------------------------------------------------- | 588 | //----------------------------------------------------------------------------- |
566 | 589 | ||
567 | 'normalizedCredentials': function(someValues) { | 590 | 'normalizedCredentials': function(someValues) { |
568 | var result; | 591 | var result; |
569 | 592 | ||
570 | result = {} | 593 | result = {} |
571 | result['username'] = this.hash()(new Clipperz.ByteArray(someValues['username'] + someValues['password'])).toHexString().substring(2); | 594 | result['username'] = this.hash()(new Clipperz.ByteArray(someValues['username'] + someValues['password'])).toHexString().substring(2); |
572 | result['password'] = this.hash()(new Clipperz.ByteArray(someValues['password'] + someValues['username'])).toHexString().substring(2); | 595 | result['password'] = this.hash()(new Clipperz.ByteArray(someValues['password'] + someValues['username'])).toHexString().substring(2); |
573 | 596 | ||
574 | return result; | 597 | return result; |
575 | }, | 598 | }, |
576 | 599 | ||
577 | //----------------------------------------------------------------------------- | 600 | //----------------------------------------------------------------------------- |
578 | 601 | ||
579 | 'hash': function() { | 602 | 'hash': function() { |
580 | return Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].hash; | 603 | return Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].hash; |
581 | }, | 604 | }, |
582 | 605 | ||
583 | //----------------------------------------------------------------------------- | 606 | //----------------------------------------------------------------------------- |
584 | __syntaxFix__: "syntax fix" | 607 | __syntaxFix__: "syntax fix" |
585 | 608 | ||
586 | }); | 609 | }); |
587 | 610 | ||
588 | Clipperz.PM.Connection.exception = { | 611 | Clipperz.PM.Connection.exception = { |
589 | WrongChecksum: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.InvalidValue"), | 612 | WrongChecksum: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.InvalidValue"), |
613 | StaleData: new MochiKit.Base.NamedError("Stale data"), | ||
590 | UnexpectedRequest:new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.UnexpectedRequest") | 614 | UnexpectedRequest:new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.UnexpectedRequest") |
591 | }; | 615 | }; |
592 | 616 | ||
593 | 617 | ||
594 | Clipperz.PM.Connection.communicationProtocol = { | 618 | Clipperz.PM.Connection.communicationProtocol = { |
595 | 'currentVersion': '0.2', | 619 | 'currentVersion': '0.2', |
596 | 'versions': { | 620 | 'versions': { |
597 | '0.1': Clipperz.PM.Connection.SRP['1.0'],//Clipperz.Crypto.SRP.versions['1.0'].Connection, | 621 | '0.1': Clipperz.PM.Connection.SRP['1.0'],//Clipperz.Crypto.SRP.versions['1.0'].Connection, |
598 | '0.2': Clipperz.PM.Connection.SRP['1.1']//Clipperz.Crypto.SRP.versions['1.1'].Connection | 622 | '0.2': Clipperz.PM.Connection.SRP['1.1']//Clipperz.Crypto.SRP.versions['1.1'].Connection |
599 | }, | 623 | }, |
600 | 'fallbackVersions': { | 624 | 'fallbackVersions': { |
601 | // 'current':'0.1', | 625 | // 'current':'0.1', |
602 | '0.2': '0.1', | 626 | '0.2': '0.1', |
603 | '0.1': null | 627 | '0.1': null |
604 | } | 628 | } |
605 | }; | 629 | }; |
606 | 630 | ||
607 | MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, { | 631 | MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, { |
608 | 'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion] | 632 | 'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion] |
609 | }); | 633 | }); |
610 | 634 | ||
611 | MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.fallbackVersions, { | 635 | MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.fallbackVersions, { |
612 | 'current': Clipperz.PM.Connection.communicationProtocol.fallbackVersions[Clipperz.PM.Connection.communicationProtocol.currentVersion] | 636 | 'current': Clipperz.PM.Connection.communicationProtocol.fallbackVersions[Clipperz.PM.Connection.communicationProtocol.currentVersion] |
613 | }); | 637 | }); |
614 | 638 | ||
615 | 639 | ||
616 | 640 | ||
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.js index 72d4006..646ce21 100644 --- a/frontend/gamma/js/Clipperz/PM/DataModel/User.js +++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.js | |||
@@ -1,152 +1,152 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2011 Clipperz Srl | 3 | Copyright 2008-2011 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz Community Edition. | 5 | This file is part of Clipperz Community Edition. |
6 | Clipperz Community Edition is an online password manager. | 6 | Clipperz Community Edition is an online password manager. |
7 | For further information about its features and functionalities please | 7 | For further information about its features and functionalities please |
8 | refer to http://www.clipperz.com. | 8 | refer to http://www.clipperz.com. |
9 | 9 | ||
10 | * Clipperz Community Edition is free software: you can redistribute | 10 | * Clipperz Community Edition is free software: you can redistribute |
11 | it and/or modify it under the terms of the GNU Affero General Public | 11 | it and/or modify it under the terms of the GNU Affero General Public |
12 | License as published by the Free Software Foundation, either version | 12 | License as published by the Free Software Foundation, either version |
13 | 3 of the License, or (at your option) any later version. | 13 | 3 of the License, or (at your option) any later version. |
14 | 14 | ||
15 | * Clipperz Community Edition is distributed in the hope that it will | 15 | * Clipperz Community Edition is distributed in the hope that it will |
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | 16 | be useful, but WITHOUT ANY WARRANTY; without even the implied |
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. | 18 | See the GNU Affero General Public License for more details. |
19 | 19 | ||
20 | * You should have received a copy of the GNU Affero General Public | 20 | * You should have received a copy of the GNU Affero General Public |
21 | License along with Clipperz Community Edition. If not, see | 21 | License along with Clipperz Community Edition. If not, see |
22 | <http://www.gnu.org/licenses/>. | 22 | <http://www.gnu.org/licenses/>. |
23 | 23 | ||
24 | */ | 24 | */ |
25 | 25 | ||
26 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | 26 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } |
27 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | 27 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } |
28 | if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } | 28 | if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } |
29 | 29 | ||
30 | 30 | ||
31 | //############################################################################# | 31 | //############################################################################# |
32 | 32 | ||
33 | Clipperz.PM.DataModel.User = function (args) { | 33 | Clipperz.PM.DataModel.User = function (args) { |
34 | args = args || {}; | 34 | args = args || {}; |
35 | 35 | ||
36 | Clipperz.PM.DataModel.User.superclass.constructor.apply(this, arguments); | 36 | Clipperz.PM.DataModel.User.superclass.constructor.apply(this, arguments); |
37 | 37 | ||
38 | this._username = args.username || null; | 38 | this._username = args.username || null; |
39 | this._getPassphraseFunction = args.getPassphraseFunction || null; | 39 | this._getPassphraseFunction = args.getPassphraseFunction || null; |
40 | 40 | ||
41 | this._data = null; | 41 | this._data = null; |
42 | 42 | ||
43 | this._connection = null; | 43 | this._connection = null; |
44 | this._connectionVersion = 'current'; | 44 | this._connectionVersion = 'current'; |
45 | 45 | ||
46 | this._serverData = null; | 46 | this._serverData = null; |
47 | this._serverLockValue = null; | 47 | //this._serverLockValue = null; |
48 | this._transientState = null; | 48 | this._transientState = null; |
49 | 49 | ||
50 | this._deferredLocks = { | 50 | this._deferredLocks = { |
51 | 'passphrase': new MochiKit.Async.DeferredLock(), | 51 | 'passphrase': new MochiKit.Async.DeferredLock(), |
52 | 'serverData': new MochiKit.Async.DeferredLock(), | 52 | 'serverData': new MochiKit.Async.DeferredLock(), |
53 | // 'recordsIndex': new MochiKit.Async.DeferredLock(), | 53 | // 'recordsIndex': new MochiKit.Async.DeferredLock(), |
54 | // 'directLoginsIndex':new MochiKit.Async.DeferredLock() | 54 | // 'directLoginsIndex':new MochiKit.Async.DeferredLock() |
55 | // 'preferences': new MochiKit.Async.DeferredLock() | 55 | // 'preferences': new MochiKit.Async.DeferredLock() |
56 | // 'oneTimePasswords': new MochiKit.Async.DeferredLock() | 56 | // 'oneTimePasswords': new MochiKit.Async.DeferredLock() |
57 | '__syntaxFix__': 'syntax fix' | 57 | '__syntaxFix__': 'syntax fix' |
58 | }; | 58 | }; |
59 | 59 | ||
60 | return this; | 60 | return this; |
61 | } | 61 | } |
62 | 62 | ||
63 | Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { | 63 | Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { |
64 | 64 | ||
65 | 'toString': function () { | 65 | 'toString': function () { |
66 | return "Clipperz.PM.DataModel.User - " + this.username(); | 66 | return "Clipperz.PM.DataModel.User - " + this.username(); |
67 | }, | 67 | }, |
68 | 68 | ||
69 | //------------------------------------------------------------------------- | 69 | //------------------------------------------------------------------------- |
70 | 70 | ||
71 | 'username': function () { | 71 | 'username': function () { |
72 | return this._username; | 72 | return this._username; |
73 | }, | 73 | }, |
74 | 74 | ||
75 | 'setUsername': function (aValue) { | 75 | 'setUsername': function (aValue) { |
76 | this._username = aValue; | 76 | this._username = aValue; |
77 | }, | 77 | }, |
78 | 78 | ||
79 | //------------------------------------------------------------------------- | 79 | //------------------------------------------------------------------------- |
80 | 80 | ||
81 | 'displayName': function() { | 81 | 'displayName': function() { |
82 | return "" + this.username() + ""; | 82 | return "" + this.username() + ""; |
83 | }, | 83 | }, |
84 | 84 | ||
85 | //------------------------------------------------------------------------- | 85 | //------------------------------------------------------------------------- |
86 | 86 | ||
87 | 'data': function () { | 87 | 'data': function () { |
88 | if (this._data == null) { | 88 | if (this._data == null) { |
89 | this._data = new Clipperz.KeyValueObjectStore(/*{'name':'User.data [1]'}*/); | 89 | this._data = new Clipperz.KeyValueObjectStore(/*{'name':'User.data [1]'}*/); |
90 | }; | 90 | }; |
91 | 91 | ||
92 | return this._data; | 92 | return this._data; |
93 | }, | 93 | }, |
94 | 94 | ||
95 | //------------------------------------------------------------------------- | 95 | //------------------------------------------------------------------------- |
96 | 96 | /* | |
97 | 'serverLockValue': function () { | 97 | 'serverLockValue': function () { |
98 | return this._serverLockValue; | 98 | return this._serverLockValue; |
99 | }, | 99 | }, |
100 | 100 | ||
101 | 'setServerLockValue': function (aValue) { | 101 | 'setServerLockValue': function (aValue) { |
102 | this._serverLockValue = aValue; | 102 | this._serverLockValue = aValue; |
103 | }, | 103 | }, |
104 | 104 | */ | |
105 | //------------------------------------------------------------------------- | 105 | //------------------------------------------------------------------------- |
106 | 106 | ||
107 | 'transientState': function () { | 107 | 'transientState': function () { |
108 | if (this._transientState == null) { | 108 | if (this._transientState == null) { |
109 | this._transientState = {} | 109 | this._transientState = {} |
110 | } | 110 | } |
111 | 111 | ||
112 | return this._transientState; | 112 | return this._transientState; |
113 | }, | 113 | }, |
114 | 114 | ||
115 | 'resetTransientState': function (isCommitting) { | 115 | 'resetTransientState': function (isCommitting) { |
116 | this._transientState = null; | 116 | this._transientState = null; |
117 | }, | 117 | }, |
118 | 118 | ||
119 | //------------------------------------------------------------------------- | 119 | //------------------------------------------------------------------------- |
120 | 120 | ||
121 | 'deferredLockForSection': function(aSectionName) { | 121 | 'deferredLockForSection': function(aSectionName) { |
122 | return this._deferredLocks[aSectionName]; | 122 | return this._deferredLocks[aSectionName]; |
123 | }, | 123 | }, |
124 | 124 | ||
125 | //------------------------------------------------------------------------- | 125 | //------------------------------------------------------------------------- |
126 | 126 | ||
127 | 'getPassphrase': function() { | 127 | 'getPassphrase': function() { |
128 | var deferredResult; | 128 | var deferredResult; |
129 | 129 | ||
130 | deferredResult = new Clipperz.Async.Deferred("User.getPassphrase", {trace:false}); | 130 | deferredResult = new Clipperz.Async.Deferred("User.getPassphrase", {trace:false}); |
131 | deferredResult.acquireLock(this.deferredLockForSection('passphrase')); | 131 | deferredResult.acquireLock(this.deferredLockForSection('passphrase')); |
132 | deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', this.getPassphraseFunction()); | 132 | deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', this.getPassphraseFunction()); |
133 | deferredResult.releaseLock(this.deferredLockForSection('passphrase')); | 133 | deferredResult.releaseLock(this.deferredLockForSection('passphrase')); |
134 | deferredResult.callback(); | 134 | deferredResult.callback(); |
135 | 135 | ||
136 | return deferredResult; | 136 | return deferredResult; |
137 | }, | 137 | }, |
138 | 138 | ||
139 | 'getPassphraseFunction': function () { | 139 | 'getPassphraseFunction': function () { |
140 | return this._getPassphraseFunction; | 140 | return this._getPassphraseFunction; |
141 | }, | 141 | }, |
142 | 142 | ||
143 | //------------------------------------------------------------------------- | 143 | //------------------------------------------------------------------------- |
144 | 144 | ||
145 | 'getCredentials': function () { | 145 | 'getCredentials': function () { |
146 | return Clipperz.Async.collectResults("User; get username and passphrase", { | 146 | return Clipperz.Async.collectResults("User; get username and passphrase", { |
147 | 'username': MochiKit.Base.method(this, 'username'), | 147 | 'username': MochiKit.Base.method(this, 'username'), |
148 | 'password': MochiKit.Base.method(this, 'getPassphrase') | 148 | 'password': MochiKit.Base.method(this, 'getPassphrase') |
149 | }, {trace:false})(); | 149 | }, {trace:false})(); |
150 | }, | 150 | }, |
151 | 151 | ||
152 | //------------------------------------------------------------------------- | 152 | //------------------------------------------------------------------------- |
@@ -175,206 +175,206 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { | |||
175 | 175 | ||
176 | return deferredResult; | 176 | return deferredResult; |
177 | }, | 177 | }, |
178 | 178 | ||
179 | //------------------------------------------------------------------------- | 179 | //------------------------------------------------------------------------- |
180 | 180 | ||
181 | 'initialSetupWithNoData': function () { | 181 | 'initialSetupWithNoData': function () { |
182 | this._serverData = { | 182 | this._serverData = { |
183 | 'version': '0.1', | 183 | 'version': '0.1', |
184 | 'statistics': "", | 184 | 'statistics': "", |
185 | 'header': { | 185 | 'header': { |
186 | 'data': null, | 186 | 'data': null, |
187 | 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, | 187 | 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, |
188 | 188 | ||
189 | 'recordsIndex': new Clipperz.PM.DataModel.User.Header.RecordIndex({ | 189 | 'recordsIndex': new Clipperz.PM.DataModel.User.Header.RecordIndex({ |
190 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), | 190 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), |
191 | 'recordsData': {'data':null, 'index':{}}, | 191 | 'recordsData': {'data':null, 'index':{}}, |
192 | 'recordsStats': null, | 192 | 'recordsStats': null, |
193 | 'directLoginsData': {'data':null, 'index':{}}, | 193 | 'directLoginsData': {'data':null, 'index':{}}, |
194 | 'encryptedDataVersion': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, | 194 | 'encryptedDataVersion': Clipperz.PM.Crypto.encryptingFunctions.currentVersion, |
195 | 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') | 195 | 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') |
196 | }), | 196 | }), |
197 | 'preferences': new Clipperz.PM.DataModel.User.Header.Preferences({ | 197 | 'preferences': new Clipperz.PM.DataModel.User.Header.Preferences({ |
198 | 'name':'preferences', | 198 | 'name':'preferences', |
199 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') | 199 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') |
200 | }), | 200 | }), |
201 | 'oneTimePasswords': new Clipperz.PM.DataModel.User.Header.OneTimePasswords({ | 201 | 'oneTimePasswords': new Clipperz.PM.DataModel.User.Header.OneTimePasswords({ |
202 | 'name':'preferences', | 202 | 'name':'preferences', |
203 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') | 203 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase') |
204 | }) | 204 | }) |
205 | } | 205 | } |
206 | }; | 206 | }; |
207 | 207 | ||
208 | // this._serverLockValue = Clipperz.PM.Crypto.randomKey(); | 208 | // this._serverLockValue = Clipperz.PM.Crypto.randomKey(); |
209 | }, | 209 | }, |
210 | 210 | ||
211 | //......................................................................... | 211 | //......................................................................... |
212 | 212 | ||
213 | 'registerAsNewAccount': function () { | 213 | 'registerAsNewAccount': function () { |
214 | var deferredResult; | 214 | var deferredResult; |
215 | 215 | ||
216 | deferredResult = new Clipperz.Async.Deferred("User.registerAsNewAccount", {trace:false}); | 216 | deferredResult = new Clipperz.Async.Deferred("User.registerAsNewAccount", {trace:false}); |
217 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3}); | 217 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3}); |
218 | deferredResult.addMethod(this, 'initialSetupWithNoData') | 218 | deferredResult.addMethod(this, 'initialSetupWithNoData') |
219 | deferredResult.addMethod(this, 'getPassphrase'); | 219 | deferredResult.addMethod(this, 'getPassphrase'); |
220 | deferredResult.addMethod(this, 'prepareRemoteDataWithKey'); | 220 | deferredResult.addMethod(this, 'prepareRemoteDataWithKey'); |
221 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); | 221 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); |
222 | deferredResult.addMethod(this.connection(), 'register'); | 222 | deferredResult.addMethod(this.connection(), 'register'); |
223 | deferredResult.addCallback(MochiKit.Base.itemgetter('lock')); | 223 | // deferredResult.addCallback(MochiKit.Base.itemgetter('lock')); |
224 | deferredResult.addMethod(this, 'setServerLockValue'); | 224 | // deferredResult.addMethod(this, 'setServerLockValue'); |
225 | deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyRegistered'); | 225 | deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyRegistered'); |
226 | 226 | ||
227 | // deferredResult.addErrback (MochiKit.Base.method(this, 'handleRegistrationFailure')); | 227 | // deferredResult.addErrback (MochiKit.Base.method(this, 'handleRegistrationFailure')); |
228 | 228 | ||
229 | deferredResult.callback(); | 229 | deferredResult.callback(); |
230 | 230 | ||
231 | return deferredResult; | 231 | return deferredResult; |
232 | }, | 232 | }, |
233 | 233 | ||
234 | //------------------------------------------------------------------------- | 234 | //------------------------------------------------------------------------- |
235 | 235 | ||
236 | 'login': function () { | 236 | 'login': function () { |
237 | var deferredResult; | 237 | var deferredResult; |
238 | 238 | ||
239 | deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false}); | 239 | deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false}); |
240 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3}); | 240 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3}); |
241 | deferredResult.addMethod(this, 'getPassphrase'); | 241 | deferredResult.addMethod(this, 'getPassphrase'); |
242 | deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue); | 242 | deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue); |
243 | deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [ | 243 | deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [ |
244 | MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':1}), | 244 | MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':1}), |
245 | MochiKit.Base.method(this, 'getCredentials'), | 245 | MochiKit.Base.method(this, 'getCredentials'), |
246 | MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'), | 246 | MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'), |
247 | MochiKit.Base.method(this.data(), 'setValue', 'passphrase') | 247 | MochiKit.Base.method(this.data(), 'setValue', 'passphrase') |
248 | ], [])); | 248 | ], [])); |
249 | deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase')); | 249 | deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase')); |
250 | deferredResult.addMethod(this.connection(), 'login'); | 250 | deferredResult.addMethod(this.connection(), 'login', false); |
251 | deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn'); | 251 | deferredResult.addCallbackPass(MochiKit.Signal.signal,Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn'); |
252 | deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback')); | 252 | deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback')); |
253 | 253 | ||
254 | deferredResult.callback(); | 254 | deferredResult.callback(); |
255 | 255 | ||
256 | return deferredResult; | 256 | return deferredResult; |
257 | }, | 257 | }, |
258 | 258 | ||
259 | //......................................................................... | 259 | //......................................................................... |
260 | 260 | ||
261 | 'handleConnectionFallback': function(aValue) { | 261 | 'handleConnectionFallback': function(aValue) { |
262 | var result; | 262 | var result; |
263 | 263 | ||
264 | if (aValue instanceof MochiKit.Async.CancelledError) { | 264 | if (aValue instanceof MochiKit.Async.CancelledError) { |
265 | result = aValue; | 265 | result = aValue; |
266 | } else { | 266 | } else { |
267 | this.setConnectionVersion(Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()]); | 267 | this.setConnectionVersion(Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()]); |
268 | 268 | ||
269 | if (this.connectionVersion() != null) { | 269 | if (this.connectionVersion() != null) { |
270 | result = new Clipperz.Async.Deferred("User.handleConnectionFallback - retry"); | 270 | result = new Clipperz.Async.Deferred("User.handleConnectionFallback - retry"); |
271 | 271 | ||
272 | result.addMethod(this, 'login'); | 272 | result.addMethod(this, 'login'); |
273 | result.callback(); | 273 | result.callback(); |
274 | } else { | 274 | } else { |
275 | result = Clipperz.Async.callbacks("User.handleConnectionFallback - failed", [ | 275 | result = Clipperz.Async.callbacks("User.handleConnectionFallback - failed", [ |
276 | MochiKit.Base.method(this.data(), 'removeValue', 'passphrase'), | 276 | MochiKit.Base.method(this.data(), 'removeValue', 'passphrase'), |
277 | MochiKit.Base.method(this, 'setConnectionVersion', 'current'), | 277 | MochiKit.Base.method(this, 'setConnectionVersion', 'current'), |
278 | MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userLoginFailed'), | 278 | MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userLoginFailed'), |
279 | MochiKit.Base.partial(MochiKit.Async.fail, Clipperz.PM.DataModel.User.exception.LoginFailed) | 279 | MochiKit.Base.partial(MochiKit.Async.fail, Clipperz.PM.DataModel.User.exception.LoginFailed) |
280 | ], {trace:false}); | 280 | ], {trace:false}); |
281 | } | 281 | } |
282 | } | 282 | } |
283 | 283 | ||
284 | return result; | 284 | return result; |
285 | }, | 285 | }, |
286 | 286 | ||
287 | //------------------------------------------------------------------------- | 287 | //------------------------------------------------------------------------- |
288 | 288 | ||
289 | 'lock': function () { | 289 | 'lock': function () { |
290 | return Clipperz.Async.callbacks("User.lock", [ | 290 | return Clipperz.Async.callbacks("User.lock", [ |
291 | MochiKit.Base.method(this, 'deleteAllCleanTextData') | 291 | MochiKit.Base.method(this, 'deleteAllCleanTextData') |
292 | ], {trace:false}); | 292 | ], {trace:false}); |
293 | }, | 293 | }, |
294 | 294 | ||
295 | //------------------------------------------------------------------------- | 295 | //------------------------------------------------------------------------- |
296 | 296 | ||
297 | 'logout': function () { | 297 | 'logout': function () { |
298 | return Clipperz.Async.callbacks("User.logout", [ | 298 | return Clipperz.Async.callbacks("User.logout", [ |
299 | MochiKit.Base.method(this, 'deleteAllCleanTextData'), | 299 | MochiKit.Base.method(this, 'deleteAllCleanTextData'), |
300 | MochiKit.Base.method(this.connection(), 'logout') | 300 | MochiKit.Base.method(this.connection(), 'logout') |
301 | ], {trace:false}); | 301 | ], {trace:false}); |
302 | }, | 302 | }, |
303 | 303 | ||
304 | //------------------------------------------------------------------------- | 304 | //------------------------------------------------------------------------- |
305 | 305 | ||
306 | 'headerFormatVersion': function(anHeader) { | 306 | 'headerFormatVersion': function(anHeader) { |
307 | var result; | 307 | var result; |
308 | 308 | ||
309 | if (anHeader.charAt(0) == '{') { | 309 | if (anHeader.charAt(0) == '{') { |
310 | varheaderData; | 310 | varheaderData; |
311 | 311 | ||
312 | headerData = Clipperz.Base.evalJSON(anHeader); | 312 | headerData = Clipperz.Base.evalJSON(anHeader); |
313 | result = headerData['version']; | 313 | result = headerData['version']; |
314 | } else { | 314 | } else { |
315 | result = 'LEGACY'; | 315 | result = 'LEGACY'; |
316 | } | 316 | } |
317 | 317 | ||
318 | return result; | 318 | return result; |
319 | }, | 319 | }, |
320 | 320 | ||
321 | //------------------------------------------------------------------------- | 321 | //------------------------------------------------------------------------- |
322 | 322 | ||
323 | 'unpackServerData': function (someServerData) { | 323 | 'unpackServerData': function (someServerData) { |
324 | var unpackedData; | 324 | var unpackedData; |
325 | var headerVersion; | 325 | var headerVersion; |
326 | 326 | ||
327 | varrecordsIndex; | 327 | varrecordsIndex; |
328 | var preferences; | 328 | var preferences; |
329 | var oneTimePasswords; | 329 | var oneTimePasswords; |
330 | 330 | ||
331 | //console.log(">>> ***************** user.unpackServerData", someServerData); | 331 | //console.log(">>> ***************** user.unpackServerData", someServerData); |
332 | this.setServerLockValue(someServerData['lock']); | 332 | // this.setServerLockValue(someServerData['lock']); |
333 | 333 | ||
334 | headerVersion = this.headerFormatVersion(someServerData['header']); | 334 | headerVersion = this.headerFormatVersion(someServerData['header']); |
335 | 335 | ||
336 | switch (headerVersion) { | 336 | switch (headerVersion) { |
337 | case 'LEGACY': | 337 | case 'LEGACY': |
338 | varlegacyHeader; | 338 | varlegacyHeader; |
339 | 339 | ||
340 | legacyHeader = new Clipperz.PM.DataModel.User.Header.Legacy({ | 340 | legacyHeader = new Clipperz.PM.DataModel.User.Header.Legacy({ |
341 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), | 341 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), |
342 | 'remoteData': { | 342 | 'remoteData': { |
343 | 'data': someServerData['header'], | 343 | 'data': someServerData['header'], |
344 | 'version': someServerData['version'], | 344 | 'version': someServerData['version'], |
345 | 'recordsStats': someServerData['recordsStats'] | 345 | 'recordsStats': someServerData['recordsStats'] |
346 | }, | 346 | }, |
347 | // 'encryptedDataKeypath': 'data', | 347 | // 'encryptedDataKeypath': 'data', |
348 | // 'encryptedVersionKeypath': 'version', | 348 | // 'encryptedVersionKeypath': 'version', |
349 | 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') | 349 | 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') |
350 | }); | 350 | }); |
351 | 351 | ||
352 | recordsIndex = legacyHeader; | 352 | recordsIndex = legacyHeader; |
353 | preferences = legacyHeader; | 353 | preferences = legacyHeader; |
354 | oneTimePasswords= legacyHeader; | 354 | oneTimePasswords= legacyHeader; |
355 | break; | 355 | break; |
356 | case '0.1': | 356 | case '0.1': |
357 | varheaderData; | 357 | varheaderData; |
358 | 358 | ||
359 | headerData = Clipperz.Base.evalJSON(someServerData['header']); | 359 | headerData = Clipperz.Base.evalJSON(someServerData['header']); |
360 | 360 | ||
361 | recordsIndex = new Clipperz.PM.DataModel.User.Header.RecordIndex({ | 361 | recordsIndex = new Clipperz.PM.DataModel.User.Header.RecordIndex({ |
362 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), | 362 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), |
363 | 'recordsData': headerData['records'], | 363 | 'recordsData': headerData['records'], |
364 | 'recordsStats': someServerData['recordsStats'], | 364 | 'recordsStats': someServerData['recordsStats'], |
365 | 'directLoginsData': headerData['directLogins'], | 365 | 'directLoginsData': headerData['directLogins'], |
366 | 'encryptedDataVersion': someServerData['version'], | 366 | 'encryptedDataVersion': someServerData['version'], |
367 | 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') | 367 | 'retrieveRecordDetailFunction':MochiKit.Base.method(this, 'getRecordDetail') |
368 | }); | 368 | }); |
369 | 369 | ||
370 | //Still missing a test case that actually fais with the old version of the code, where the check for undefined was missing | 370 | //Still missing a test case that actually fais with the old version of the code, where the check for undefined was missing |
371 | if (typeof(headerData['preferences']) != 'undefined') { | 371 | if (typeof(headerData['preferences']) != 'undefined') { |
372 | preferences= new Clipperz.PM.DataModel.User.Header.Preferences({ | 372 | preferences= new Clipperz.PM.DataModel.User.Header.Preferences({ |
373 | 'name':'preferences', | 373 | 'name':'preferences', |
374 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), | 374 | 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'), |
375 | 'remoteData': { | 375 | 'remoteData': { |
376 | 'data': headerData['preferences']['data'], | 376 | 'data': headerData['preferences']['data'], |
377 | 'version': someServerData['version'] | 377 | 'version': someServerData['version'] |
378 | } | 378 | } |
379 | }); | 379 | }); |
380 | } else { | 380 | } else { |
@@ -617,175 +617,175 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { | |||
617 | ]//, | 617 | ]//, |
618 | // 'statistics': [ | 618 | // 'statistics': [ |
619 | // MochiKit.Base.method(this, 'getStatistics'), | 619 | // MochiKit.Base.method(this, 'getStatistics'), |
620 | // MochiKit.Base.methodcaller(aMethodName, aValue) | 620 | // MochiKit.Base.methodcaller(aMethodName, aValue) |
621 | // ] | 621 | // ] |
622 | }, {trace:false})(); | 622 | }, {trace:false})(); |
623 | }, | 623 | }, |
624 | 624 | ||
625 | //------------------------------------------------------------------------- | 625 | //------------------------------------------------------------------------- |
626 | 626 | ||
627 | 'invokeMethodNamedOnRecords': function (aMethodName, aValue) { | 627 | 'invokeMethodNamedOnRecords': function (aMethodName, aValue) { |
628 | return Clipperz.Async.callbacks("User.invokeMethodNamedOnRecords[" + aMethodName + "]", [ | 628 | return Clipperz.Async.callbacks("User.invokeMethodNamedOnRecords[" + aMethodName + "]", [ |
629 | MochiKit.Base.method(this, 'getRecords'), | 629 | MochiKit.Base.method(this, 'getRecords'), |
630 | MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller(aMethodName, aValue)), | 630 | MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller(aMethodName, aValue)), |
631 | Clipperz.Async.collectAll | 631 | Clipperz.Async.collectAll |
632 | ], {trace:false}); | 632 | ], {trace:false}); |
633 | }, | 633 | }, |
634 | 634 | ||
635 | //========================================================================= | 635 | //========================================================================= |
636 | 636 | ||
637 | 'hasPendingChanges': function () { | 637 | 'hasPendingChanges': function () { |
638 | vardeferredResult; | 638 | vardeferredResult; |
639 | 639 | ||
640 | deferredResult = new Clipperz.Async.Deferred("User.hasPendingChanges", {trace:false}); | 640 | deferredResult = new Clipperz.Async.Deferred("User.hasPendingChanges", {trace:false}); |
641 | deferredResult.collectResults({ | 641 | deferredResult.collectResults({ |
642 | 'header': [ | 642 | 'header': [ |
643 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasPendingChanges'), | 643 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasPendingChanges'), |
644 | MochiKit.Base.values | 644 | MochiKit.Base.values |
645 | ], | 645 | ], |
646 | 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasPendingChanges') | 646 | 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasPendingChanges') |
647 | }); | 647 | }); |
648 | deferredResult.addCallback(Clipperz.Async.or); | 648 | deferredResult.addCallback(Clipperz.Async.or); |
649 | deferredResult.callback(); | 649 | deferredResult.callback(); |
650 | // recordsIndex = legacyHeader; | 650 | // recordsIndex = legacyHeader; |
651 | // preferences = legacyHeader; | 651 | // preferences = legacyHeader; |
652 | // oneTimePasswords= legacyHeader; | 652 | // oneTimePasswords= legacyHeader; |
653 | 653 | ||
654 | return deferredResult; | 654 | return deferredResult; |
655 | }, | 655 | }, |
656 | 656 | ||
657 | //========================================================================= | 657 | //========================================================================= |
658 | 658 | ||
659 | 'commitTransientState': function () { | 659 | 'commitTransientState': function () { |
660 | return Clipperz.Async.callbacks("User.commitTransientState", [ | 660 | return Clipperz.Async.callbacks("User.commitTransientState", [ |
661 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'commitTransientState'), | 661 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'commitTransientState'), |
662 | MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'commitTransientState'), | 662 | MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'commitTransientState'), |
663 | 663 | ||
664 | MochiKit.Base.method(this, 'transientState'), | 664 | MochiKit.Base.method(this, 'transientState'), |
665 | MochiKit.Base.itemgetter('lock'), | 665 | // MochiKit.Base.itemgetter('lock'), |
666 | MochiKit.Base.method(this, 'setServerLockValue'), | 666 | // MochiKit.Base.method(this, 'setServerLockValue'), |
667 | MochiKit.Base.method(this, 'resetTransientState', true) | 667 | MochiKit.Base.method(this, 'resetTransientState', true) |
668 | ], {trace:false}); | 668 | ], {trace:false}); |
669 | }, | 669 | }, |
670 | 670 | ||
671 | //------------------------------------------------------------------------- | 671 | //------------------------------------------------------------------------- |
672 | 672 | ||
673 | 'revertChanges': function () { | 673 | 'revertChanges': function () { |
674 | return Clipperz.Async.callbacks("User.revertChanges", [ | 674 | return Clipperz.Async.callbacks("User.revertChanges", [ |
675 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'), | 675 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'), |
676 | MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'), | 676 | MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'), |
677 | MochiKit.Base.method(this, 'resetTransientState', false) | 677 | MochiKit.Base.method(this, 'resetTransientState', false) |
678 | ], {trace:false}); | 678 | ], {trace:false}); |
679 | }, | 679 | }, |
680 | 680 | ||
681 | //========================================================================= | 681 | //========================================================================= |
682 | 682 | ||
683 | 'deleteAllCleanTextData': function () { | 683 | 'deleteAllCleanTextData': function () { |
684 | return Clipperz.Async.callbacks("User.deleteAllCleanTextData", [ | 684 | return Clipperz.Async.callbacks("User.deleteAllCleanTextData", [ |
685 | MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'deleteAllCleanTextData'), | 685 | MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'deleteAllCleanTextData'), |
686 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'deleteAllCleanTextData'), | 686 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'deleteAllCleanTextData'), |
687 | 687 | ||
688 | MochiKit.Base.method(this.data(), 'removeAllData'), | 688 | MochiKit.Base.method(this.data(), 'removeAllData'), |
689 | MochiKit.Base.method(this, 'resetTransientState', false) | 689 | MochiKit.Base.method(this, 'resetTransientState', false) |
690 | ], {trace:false}); | 690 | ], {trace:false}); |
691 | }, | 691 | }, |
692 | 692 | ||
693 | //------------------------------------------------------------------------- | 693 | //------------------------------------------------------------------------- |
694 | 694 | ||
695 | 'hasAnyCleanTextData': function () { | 695 | 'hasAnyCleanTextData': function () { |
696 | vardeferredResult; | 696 | vardeferredResult; |
697 | 697 | ||
698 | deferredResult = new Clipperz.Async.Deferred("User.hasAnyCleanTextData", {trace:false}); | 698 | deferredResult = new Clipperz.Async.Deferred("User.hasAnyCleanTextData", {trace:false}); |
699 | deferredResult.collectResults({ | 699 | deferredResult.collectResults({ |
700 | 'header':[ | 700 | 'header':[ |
701 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasAnyCleanTextData'), | 701 | MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasAnyCleanTextData'), |
702 | MochiKit.Base.values | 702 | MochiKit.Base.values |
703 | ], | 703 | ], |
704 | 'records':MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasAnyCleanTextData'), | 704 | 'records':MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasAnyCleanTextData'), |
705 | 'data': MochiKit.Base.bind(function () { | 705 | 'data': MochiKit.Base.bind(function () { |
706 | return MochiKit.Async.succeed(! this.data().isEmpty()); | 706 | return MochiKit.Async.succeed(! this.data().isEmpty()); |
707 | }, this), | 707 | }, this), |
708 | 'transientState':MochiKit.Base.bind(function () { | 708 | 'transientState':MochiKit.Base.bind(function () { |
709 | return MochiKit.Async.succeed(MochiKit.Base.keys(this.transientState()).length != 0); | 709 | return MochiKit.Async.succeed(MochiKit.Base.keys(this.transientState()).length != 0); |
710 | }, this) | 710 | }, this) |
711 | }); | 711 | }); |
712 | deferredResult.addCallback(Clipperz.Async.or); | 712 | deferredResult.addCallback(Clipperz.Async.or); |
713 | deferredResult.callback(); | 713 | deferredResult.callback(); |
714 | 714 | ||
715 | return deferredResult; | 715 | return deferredResult; |
716 | }, | 716 | }, |
717 | 717 | ||
718 | //========================================================================= | 718 | //========================================================================= |
719 | 719 | ||
720 | 'prepareRemoteDataWithKey': function (aKey /*, aCurrentKey*/) { | 720 | 'prepareRemoteDataWithKey': function (aKey /*, aCurrentKey*/) { |
721 | var deferredResult; | 721 | var deferredResult; |
722 | varresult; | 722 | varresult; |
723 | 723 | ||
724 | result = {}; | 724 | result = {}; |
725 | deferredResult = new Clipperz.Async.Deferred("User.prepareRemoteDataWithKey", {trace:false}); | 725 | deferredResult = new Clipperz.Async.Deferred("User.prepareRemoteDataWithKey", {trace:false}); |
726 | deferredResult.addMethod(this, 'invokeMethodNamedOnHeader', 'prepareRemoteDataWithKey', aKey /*, aCurrentKey*/); | 726 | deferredResult.addMethod(this, 'invokeMethodNamedOnHeader', 'prepareRemoteDataWithKey', aKey /*, aCurrentKey*/); |
727 | deferredResult.addCallback(MochiKit.Base.bind(function (aResult, someHeaderPackedData) { | 727 | deferredResult.addCallback(MochiKit.Base.bind(function (aResult, someHeaderPackedData) { |
728 | var header; | 728 | var header; |
729 | 729 | ||
730 | header = {}; | 730 | header = {}; |
731 | header['records'] = someHeaderPackedData['recordIndex']['records']; | 731 | header['records'] = someHeaderPackedData['recordIndex']['records']; |
732 | header['directLogins'] = someHeaderPackedData['recordIndex']['directLogins']; | 732 | header['directLogins'] = someHeaderPackedData['recordIndex']['directLogins']; |
733 | header['preferences'] = {'data': someHeaderPackedData['preferences']['data']}; // this._serverData['header']['preferences']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['preferences']; //??????????? | 733 | header['preferences'] = {'data': someHeaderPackedData['preferences']['data']}; // this._serverData['header']['preferences']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['preferences']; //??????????? |
734 | header['oneTimePasswords'] = {'data': someHeaderPackedData['oneTimePasswords']['data']}; // this._serverData['header']['oneTimePasswords']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['oneTimePasswords']; //??????????? | 734 | header['oneTimePasswords'] = {'data': someHeaderPackedData['oneTimePasswords']['data']}; // this._serverData['header']['oneTimePasswords']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['oneTimePasswords']; //??????????? |
735 | header['version'] = '0.1'; | 735 | header['version'] = '0.1'; |
736 | 736 | ||
737 | aResult['header'] = Clipperz.Base.serializeJSON(header); | 737 | aResult['header'] = Clipperz.Base.serializeJSON(header); |
738 | aResult['statistics'] = this._serverData['statistics']; //"someHeaderPackedData['statistics']['data']"; | 738 | aResult['statistics'] = this._serverData['statistics']; //"someHeaderPackedData['statistics']['data']"; |
739 | 739 | ||
740 | return aResult; | 740 | return aResult; |
741 | }, this), result); | 741 | }, this), result); |
742 | deferredResult.addCallback(Clipperz.Async.setItem, result, 'version', Clipperz.PM.Crypto.encryptingFunctions.currentVersion); | 742 | deferredResult.addCallback(Clipperz.Async.setItem, result, 'version', Clipperz.PM.Crypto.encryptingFunctions.currentVersion); |
743 | deferredResult.addCallback(Clipperz.Async.setItem, result, 'lock', this.serverLockValue()); | 743 | // deferredResult.addCallback(Clipperz.Async.setItem, result, 'lock', this.serverLockValue()); |
744 | deferredResult.callback(); | 744 | deferredResult.callback(); |
745 | 745 | ||
746 | return deferredResult; | 746 | return deferredResult; |
747 | }, | 747 | }, |
748 | 748 | ||
749 | //========================================================================= | 749 | //========================================================================= |
750 | 750 | ||
751 | 'saveChanges': function () { | 751 | 'saveChanges': function () { |
752 | vardeferredResult; | 752 | vardeferredResult; |
753 | var messageParameters; | 753 | var messageParameters; |
754 | 754 | ||
755 | messageParameters = {}; | 755 | messageParameters = {}; |
756 | 756 | ||
757 | deferredResult = new Clipperz.Async.Deferred("User.saveChangaes", {trace:false}); | 757 | deferredResult = new Clipperz.Async.Deferred("User.saveChangaes", {trace:false}); |
758 | 758 | ||
759 | deferredResult.addMethod(this, 'getHeaderIndex', 'recordsIndex'); | 759 | deferredResult.addMethod(this, 'getHeaderIndex', 'recordsIndex'); |
760 | deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords')); | 760 | deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords')); |
761 | deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'records'); | 761 | deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'records'); |
762 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); | 762 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); |
763 | 763 | ||
764 | deferredResult.addMethod(this, 'getPassphrase'); | 764 | deferredResult.addMethod(this, 'getPassphrase'); |
765 | deferredResult.addMethod(this, 'prepareRemoteDataWithKey'); | 765 | deferredResult.addMethod(this, 'prepareRemoteDataWithKey'); |
766 | deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'user'); | 766 | deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'user'); |
767 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); | 767 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); |
768 | 768 | ||
769 | deferredResult.addCallback(MochiKit.Async.succeed, messageParameters); | 769 | deferredResult.addCallback(MochiKit.Async.succeed, messageParameters); |
770 | deferredResult.addMethod(this.connection(), 'message', 'saveChanges'); | 770 | deferredResult.addMethod(this.connection(), 'message', 'saveChanges'); |
771 | deferredResult.addCallback(MochiKit.Base.update, this.transientState()) | 771 | deferredResult.addCallback(MochiKit.Base.update, this.transientState()) |
772 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); | 772 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); |
773 | 773 | ||
774 | deferredResult.addMethod(this, 'commitTransientState'); | 774 | deferredResult.addMethod(this, 'commitTransientState'); |
775 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); | 775 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); |
776 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved'); | 776 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved'); |
777 | 777 | ||
778 | deferredResult.addErrbackPass(MochiKit.Base.method(this, 'revertChanges')); | 778 | deferredResult.addErrbackPass(MochiKit.Base.method(this, 'revertChanges')); |
779 | deferredResult.addErrbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'failureWhileSavingUserData'); | 779 | deferredResult.addErrbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'failureWhileSavingUserData'); |
780 | 780 | ||
781 | deferredResult.callback(); | 781 | deferredResult.callback(); |
782 | 782 | ||
783 | return deferredResult; | 783 | return deferredResult; |
784 | }, | 784 | }, |
785 | 785 | ||
786 | //========================================================================= | 786 | //========================================================================= |
787 | __syntaxFix__: "syntax fix" | 787 | __syntaxFix__: "syntax fix" |
788 | }); | 788 | }); |
789 | 789 | ||
790 | //----------------------------------------------------------------------------- | 790 | //----------------------------------------------------------------------------- |
791 | 791 | ||
diff --git a/frontend/gamma/js/Clipperz/PM/PIN.js b/frontend/gamma/js/Clipperz/PM/PIN.js new file mode 100644 index 0000000..bc932b2 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/PIN.js | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz Community Edition. | ||
6 | Clipperz Community Edition is an online password manager. | ||
7 | For further information about its features and functionalities please | ||
8 | refer to http://www.clipperz.com. | ||
9 | |||
10 | * Clipperz Community Edition is free software: you can redistribute | ||
11 | it and/or modify it under the terms of the GNU Affero General Public | ||
12 | License as published by the Free Software Foundation, either version | ||
13 | 3 of the License, or (at your option) any later version. | ||
14 | |||
15 | * Clipperz Community Edition is distributed in the hope that it will | ||
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
18 | See the GNU Affero General Public License for more details. | ||
19 | |||
20 | * You should have received a copy of the GNU Affero General Public | ||
21 | License along with Clipperz Community Edition. If not, see | ||
22 | <http://www.gnu.org/licenses/>. | ||
23 | |||
24 | */ | ||
25 | |||
26 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | ||
27 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | ||
28 | if (typeof(Clipperz.PM.PIN) == 'undefined') { Clipperz.PM.PIN = {}; } | ||
29 | |||
30 | MochiKit.Base.update(Clipperz.PM.PIN, { | ||
31 | |||
32 | //------------------------------------------------------------------------- | ||
33 | |||
34 | '__repr__': function () { | ||
35 | return "[" + this.NAME + " " + this.VERSION + "]"; | ||
36 | }, | ||
37 | |||
38 | //------------------------------------------------------------------------- | ||
39 | |||
40 | 'toString': function () { | ||
41 | return this.__repr__(); | ||
42 | }, | ||
43 | |||
44 | 'CREDENTIALS': 'CLIPPERZ.CREDENTIALS', | ||
45 | 'FAILURE_COUNT': 'CLIPPERZ.FAILED_LOGIN_COUNT', | ||
46 | 'ALLOWED_RETRY': 3, | ||
47 | |||
48 | //------------------------------------------------------------------------- | ||
49 | |||
50 | 'isSet': function () { | ||
51 | return (this.storedCredentials() != null); | ||
52 | }, | ||
53 | |||
54 | 'storedCredentials': function () { | ||
55 | return localStorage[this.CREDENTIALS]; | ||
56 | }, | ||
57 | |||
58 | //------------------------------------------------------------------------- | ||
59 | |||
60 | 'recordFailedAttempt': function () { | ||
61 | varfailureCount; | ||
62 | varresult; | ||
63 | |||
64 | failureCount = localStorage[this.FAILURE_COUNT]; | ||
65 | |||
66 | if (failureCount == null) { | ||
67 | failureCount = 0 | ||
68 | } | ||
69 | |||
70 | failureCount ++; | ||
71 | |||
72 | if (failureCount < this.ALLOWED_RETRY) { | ||
73 | localStorage[this.FAILURE_COUNT] = failureCount; | ||
74 | result = failureCount; | ||
75 | } else { | ||
76 | this.removeLocalCredentials(); | ||
77 | result = -1; | ||
78 | } | ||
79 | |||
80 | return result; | ||
81 | }, | ||
82 | |||
83 | 'resetFailedAttemptCount': function () { | ||
84 | localStorage.removeItem(this.FAILURE_COUNT); | ||
85 | }, | ||
86 | |||
87 | 'failureCount': function () { | ||
88 | return localStorage[this.FAILURE_COUNT]; | ||
89 | }, | ||
90 | |||
91 | //------------------------------------------------------------------------- | ||
92 | |||
93 | 'deriveKeyFromPin': function (aPIN) { | ||
94 | return Clipperz.Crypto.SHA.sha256(new Clipperz.ByteArray(aPIN)); | ||
95 | }, | ||
96 | |||
97 | 'credentialsWithPIN': function (aPIN) { | ||
98 | varbyteArrayValue; | ||
99 | var decryptedValue; | ||
100 | varresult; | ||
101 | |||
102 | byteArrayValue = (new Clipperz.ByteArray()).appendBase64String(localStorage[this.CREDENTIALS]); | ||
103 | decryptedValue = Clipperz.Crypto.AES.decrypt(this.deriveKeyFromPin(aPIN), byteArrayValue).asString(); | ||
104 | try { | ||
105 | result = Clipperz.Base.evalJSON(decryptedValue); | ||
106 | } catch (error) { | ||
107 | result = {'username':'fakeusername', 'passphrase':'fakepassphrase'}; | ||
108 | } | ||
109 | |||
110 | return result; | ||
111 | }, | ||
112 | |||
113 | 'setCredentialsWithPIN': function (aPIN, someCredentials) { | ||
114 | varencodedValue; | ||
115 | varbyteArrayValue; | ||
116 | var encryptedValue; | ||
117 | |||
118 | encodedValue = Clipperz.Base.serializeJSON(someCredentials); | ||
119 | byteArrayValue = new Clipperz.ByteArray(encodedValue); | ||
120 | encryptedValue = Clipperz.Crypto.AES.encrypt(this.deriveKeyFromPin(aPIN), byteArrayValue).toBase64String(); | ||
121 | |||
122 | localStorage[this.CREDENTIALS] = encryptedValue; | ||
123 | }, | ||
124 | |||
125 | 'removeLocalCredentials': function () { | ||
126 | localStorage.removeItem(this.CREDENTIALS); | ||
127 | localStorage.removeItem(this.FAILURE_COUNT); | ||
128 | }, | ||
129 | |||
130 | //------------------------------------------------------------------------- | ||
131 | __syntaxFix__: "syntax fix" | ||
132 | |||
133 | }); | ||
134 | |||
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.OfflineCache.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.OfflineCache.js new file mode 100644 index 0000000..803c590 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.OfflineCache.js | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz Community Edition. | ||
6 | Clipperz Community Edition is an online password manager. | ||
7 | For further information about its features and functionalities please | ||
8 | refer to http://www.clipperz.com. | ||
9 | |||
10 | * Clipperz Community Edition is free software: you can redistribute | ||
11 | it and/or modify it under the terms of the GNU Affero General Public | ||
12 | License as published by the Free Software Foundation, either version | ||
13 | 3 of the License, or (at your option) any later version. | ||
14 | |||
15 | * Clipperz Community Edition is distributed in the hope that it will | ||
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
18 | See the GNU Affero General Public License for more details. | ||
19 | |||
20 | * You should have received a copy of the GNU Affero General Public | ||
21 | License along with Clipperz Community Edition. If not, see | ||
22 | <http://www.gnu.org/licenses/>. | ||
23 | |||
24 | */ | ||
25 | |||
26 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | ||
27 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | ||
28 | |||
29 | //============================================================================= | ||
30 | |||
31 | Clipperz.PM.Proxy.OfflineCache = function(args) { | ||
32 | args = args || {}; | ||
33 | |||
34 | Clipperz.PM.Proxy.Offline.superclass.constructor.call(this, args); | ||
35 | |||
36 | //this._dataStore = args.dataStore || new Clipperz.PM.Proxy.Offline.DataStore(args); | ||
37 | |||
38 | return this; | ||
39 | } | ||
40 | |||
41 | Clipperz.Base.extend(Clipperz.PM.Proxy.OfflineCache, Clipperz.PM.Proxy, { | ||
42 | |||
43 | 'toString': function () { | ||
44 | return "Clipperz.PM.Proxy.OfflineCache"; | ||
45 | }, | ||
46 | |||
47 | //------------------------------------------------------------------------- | ||
48 | |||
49 | //'dataStore': function () { | ||
50 | // return this._dataStore; | ||
51 | //}, | ||
52 | |||
53 | //------------------------------------------------------------------------- | ||
54 | |||
55 | 'sendMessage': function(aFunctionName, someParameters) { | ||
56 | throw Clipperz.Base.exception.MethodNotImplementedYet; | ||
57 | // return this.dataStore().processMessage(aFunctionName, someParameters); | ||
58 | }, | ||
59 | |||
60 | //------------------------------------------------------------------------- | ||
61 | |||
62 | __syntaxFix__: "syntax fix" | ||
63 | |||
64 | }); | ||
65 | |||
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js index 2a03fdf..b9d7adf 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js | |||
@@ -361,96 +361,100 @@ Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.BaseComponent, /*Ext.Compo | |||
361 | for (slotName in this.slotComponents()) { | 361 | for (slotName in this.slotComponents()) { |
362 | this.slotComponents()[slotName].remove(); | 362 | this.slotComponents()[slotName].remove(); |
363 | delete this.slotComponents()[slotName]; | 363 | delete this.slotComponents()[slotName]; |
364 | } | 364 | } |
365 | 365 | ||
366 | for (componentId in this.components()) { | 366 | for (componentId in this.components()) { |
367 | this.components()[componentId].remove(); | 367 | this.components()[componentId].remove(); |
368 | delete this.components()[componentId]; | 368 | delete this.components()[componentId]; |
369 | } | 369 | } |
370 | 370 | ||
371 | this.clear(); | 371 | this.clear(); |
372 | MochiKit.Signal.disconnectAll(this); | 372 | MochiKit.Signal.disconnectAll(this); |
373 | }, | 373 | }, |
374 | 374 | ||
375 | 'append': function(aNode, aValue) { | 375 | 'append': function(aNode, aValue) { |
376 | return Clipperz.DOM.Helper.append(aNode, aValue); | 376 | return Clipperz.DOM.Helper.append(aNode, aValue); |
377 | }, | 377 | }, |
378 | 378 | ||
379 | 'insertBefore': function (aNode, aValue) { | 379 | 'insertBefore': function (aNode, aValue) { |
380 | return Clipperz.DOM.Helper.insertBefore(aNode, aValue); | 380 | return Clipperz.DOM.Helper.insertBefore(aNode, aValue); |
381 | }, | 381 | }, |
382 | 382 | ||
383 | 'insertAfter': function (aNode, aValue) { | 383 | 'insertAfter': function (aNode, aValue) { |
384 | return Clipperz.DOM.Helper.insertAfter(aNode, aValue); | 384 | return Clipperz.DOM.Helper.insertAfter(aNode, aValue); |
385 | }, | 385 | }, |
386 | 386 | ||
387 | //------------------------------------------------------------------------- | 387 | //------------------------------------------------------------------------- |
388 | 388 | ||
389 | 'getId': function(aValue) { | 389 | 'getId': function(aValue) { |
390 | varresult; | 390 | varresult; |
391 | 391 | ||
392 | if (typeof(aValue) != 'undefined') { | 392 | if (typeof(aValue) != 'undefined') { |
393 | result = this._ids[aValue]; | 393 | result = this._ids[aValue]; |
394 | 394 | ||
395 | if (typeof(result) == 'undefined') { | 395 | if (typeof(result) == 'undefined') { |
396 | _Clipperz_PM_Components_base_id_ ++; | 396 | _Clipperz_PM_Components_base_id_ ++; |
397 | 397 | ||
398 | result = "Clipperz_PM_Components_" + aValue + "_" + _Clipperz_PM_Components_base_id_; | 398 | result = "Clipperz_PM_Components_" + aValue + "_" + _Clipperz_PM_Components_base_id_; |
399 | this._ids[aValue] = result; | 399 | this._ids[aValue] = result; |
400 | } | 400 | } |
401 | } else { | 401 | } else { |
402 | // result = Clipperz.PM.UI.Common.Components.BaseComponent.superclass.getId.call(this); | 402 | // result = Clipperz.PM.UI.Common.Components.BaseComponent.superclass.getId.call(this); |
403 | throw "call to BaseComponent.getId with an undefined value"; | 403 | throw "call to BaseComponent.getId with an undefined value"; |
404 | } | 404 | } |
405 | 405 | ||
406 | return result; | 406 | return result; |
407 | }, | 407 | }, |
408 | 408 | ||
409 | 'getAnchor': function (aValue) { | ||
410 | return '#' + this.getId(aValue); | ||
411 | }, | ||
412 | |||
409 | //------------------------------------------------------------------------- | 413 | //------------------------------------------------------------------------- |
410 | 414 | ||
411 | 'getElement': function(aValue) { | 415 | 'getElement': function(aValue) { |
412 | return Clipperz.DOM.get(this.getId(aValue)); | 416 | return Clipperz.DOM.get(this.getId(aValue)); |
413 | }, | 417 | }, |
414 | 418 | ||
415 | //------------------------------------------------------------------------- | 419 | //------------------------------------------------------------------------- |
416 | 420 | ||
417 | 'hideElement': function(anElementName) { | 421 | 'hideElement': function(anElementName) { |
418 | MochiKit.Style.hideElement(this.getElement(anElementName)); | 422 | MochiKit.Style.hideElement(this.getElement(anElementName)); |
419 | }, | 423 | }, |
420 | 424 | ||
421 | 'showElement': function(anElementName) { | 425 | 'showElement': function(anElementName) { |
422 | MochiKit.Style.showElement(this.getElement(anElementName)); | 426 | MochiKit.Style.showElement(this.getElement(anElementName)); |
423 | }, | 427 | }, |
424 | 428 | ||
425 | //------------------------------------------------------------------------- | 429 | //------------------------------------------------------------------------- |
426 | 430 | ||
427 | 'activate': function () { | 431 | 'activate': function () { |
428 | this._isActive = true; | 432 | this._isActive = true; |
429 | }, | 433 | }, |
430 | 434 | ||
431 | 'deactivate': function () { | 435 | 'deactivate': function () { |
432 | this._isActive = false; | 436 | this._isActive = false; |
433 | }, | 437 | }, |
434 | 438 | ||
435 | 'isActive': function () { | 439 | 'isActive': function () { |
436 | return this._isActive; | 440 | return this._isActive; |
437 | }, | 441 | }, |
438 | 442 | ||
439 | //------------------------------------------------------------------------- | 443 | //------------------------------------------------------------------------- |
440 | 444 | ||
441 | 'hideSlot': function(aSlotName) { | 445 | 'hideSlot': function(aSlotName) { |
442 | if (this.componentForSlotNamed(aSlotName)) { | 446 | if (this.componentForSlotNamed(aSlotName)) { |
443 | this.componentForSlotNamed(aSlotName).deactivate(); | 447 | this.componentForSlotNamed(aSlotName).deactivate(); |
444 | } | 448 | } |
445 | MochiKit.Style.hideElement(this.elementForSlotNamed(aSlotName)); | 449 | MochiKit.Style.hideElement(this.elementForSlotNamed(aSlotName)); |
446 | }, | 450 | }, |
447 | 451 | ||
448 | 'showSlot': function(aSlotName) { | 452 | 'showSlot': function(aSlotName) { |
449 | if (this.componentForSlotNamed(aSlotName)) { | 453 | if (this.componentForSlotNamed(aSlotName)) { |
450 | this.componentForSlotNamed(aSlotName).activate(); | 454 | this.componentForSlotNamed(aSlotName).activate(); |
451 | } | 455 | } |
452 | MochiKit.Style.showElement(this.elementForSlotNamed(aSlotName)); | 456 | MochiKit.Style.showElement(this.elementForSlotNamed(aSlotName)); |
453 | }, | 457 | }, |
454 | 458 | ||
455 | //------------------------------------------------------------------------- | 459 | //------------------------------------------------------------------------- |
456 | 460 | ||
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js index 716d851..1010c9d 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js | |||
@@ -17,89 +17,97 @@ refer to http://www.clipperz.com. | |||
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. | 18 | See the GNU Affero General Public License for more details. |
19 | 19 | ||
20 | * You should have received a copy of the GNU Affero General Public | 20 | * You should have received a copy of the GNU Affero General Public |
21 | License along with Clipperz Community Edition. If not, see | 21 | License along with Clipperz Community Edition. If not, see |
22 | <http://www.gnu.org/licenses/>. | 22 | <http://www.gnu.org/licenses/>. |
23 | 23 | ||
24 | */ | 24 | */ |
25 | 25 | ||
26 | Clipperz.Base.module('Clipperz.PM.UI.Common.Components'); | 26 | Clipperz.Base.module('Clipperz.PM.UI.Common.Components'); |
27 | 27 | ||
28 | Clipperz.PM.UI.Common.Components.Button = function(args) { | 28 | Clipperz.PM.UI.Common.Components.Button = function(args) { |
29 | args = args || {}; | 29 | args = args || {}; |
30 | 30 | ||
31 | Clipperz.PM.UI.Common.Components.Button.superclass.constructor.apply(this, arguments); | 31 | Clipperz.PM.UI.Common.Components.Button.superclass.constructor.apply(this, arguments); |
32 | 32 | ||
33 | this._element = args.element || Clipperz.Base.exception.raise('MandatoryParameter'); | 33 | this._element = args.element || Clipperz.Base.exception.raise('MandatoryParameter'); |
34 | this._text = args.text || Clipperz.Base.exception.raise('MandatoryParameter'); | 34 | this._text = args.text || Clipperz.Base.exception.raise('MandatoryParameter'); |
35 | this._isDefault = args.isDefault|| false; | 35 | this._isDefault = args.isDefault|| false; |
36 | 36 | ||
37 | this.render(); | 37 | this.render(); |
38 | 38 | ||
39 | return this; | 39 | return this; |
40 | } | 40 | } |
41 | 41 | ||
42 | //============================================================================= | 42 | //============================================================================= |
43 | 43 | ||
44 | Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.Button, Clipperz.PM.UI.Common.Components.BaseComponent, { | 44 | Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.Button, Clipperz.PM.UI.Common.Components.BaseComponent, { |
45 | 45 | ||
46 | //------------------------------------------------------------------------- | 46 | //------------------------------------------------------------------------- |
47 | 47 | ||
48 | 'toString': function () { | 48 | 'toString': function () { |
49 | return "Clipperz.PM.UI.Common.Components.Button component"; | 49 | return "Clipperz.PM.UI.Common.Components.Button component"; |
50 | }, | 50 | }, |
51 | 51 | ||
52 | //------------------------------------------------------------------------- | 52 | //------------------------------------------------------------------------- |
53 | 53 | ||
54 | 'text': function () { | 54 | 'text': function () { |
55 | return this._text; | 55 | return this._text; |
56 | }, | 56 | }, |
57 | 57 | ||
58 | 'isDefault': function () { | 58 | 'isDefault': function () { |
59 | return this._isDefault; | 59 | return this._isDefault; |
60 | }, | 60 | }, |
61 | 61 | ||
62 | //------------------------------------------------------------------------- | 62 | //------------------------------------------------------------------------- |
63 | 63 | ||
64 | 'renderSelf': function () { | 64 | 'renderSelf': function () { |
65 | this.append(this.element(), {tag:'div', id:this.getId('wrapper'), cls:'button_wrapper', children:[ | 65 | /* |
66 | this.append(this.element(), {tag:'div', id:this.getId('button'), cls:'button_wrapper', children:[ | ||
66 | {tag:'div', id:this.getId('bodyWrapper'), cls:'button_bodyWrapper', children:[ | 67 | {tag:'div', id:this.getId('bodyWrapper'), cls:'button_bodyWrapper', children:[ |
67 | {tag:'div', id:this.getId('body'), cls:'button_body', children:[ | 68 | {tag:'div', id:this.getId('body'), cls:'button_body', children:[ |
68 | {tag:'span', html:this.text()} | 69 | {tag:'span', html:this.text()} |
69 | ]}, | 70 | ]}, |
70 | {tag:'div', id:this.getId('footer'), cls:'button_footer'} | 71 | {tag:'div', id:this.getId('footer'), cls:'button_footer'} |
71 | ]} | 72 | ]} |
72 | ]}); | 73 | ]}); |
74 | */ | ||
75 | /* | ||
76 | this.append(this.element(), {tag:'div', id:this.getId('button'), cls:'button', children:[ | ||
77 | {tag:'span', html:this.text()} | ||
78 | ]}); | ||
79 | */ | ||
80 | this.append(this.element(), {tag:'a', id:this.getId('button'), cls:'button', html:this.text()}); | ||
73 | 81 | ||
74 | if (this.isDefault()) { | 82 | if (this.isDefault()) { |
75 | MochiKit.DOM.addElementClass(this.getId('wrapper'), 'default'); | 83 | MochiKit.DOM.addElementClass(this.getId('button'), 'default'); |
76 | } | 84 | } |
77 | 85 | ||
78 | MochiKit.Signal.connect(this.getId('wrapper'), 'onmouseenter',this, 'handleOnMouseEnter'); | 86 | // MochiKit.Signal.connect(this.getId('button'), 'onmouseenter',this, 'handleOnMouseEnter'); |
79 | MochiKit.Signal.connect(this.getId('wrapper'), 'onmouseleave',this, 'handleOnMouseLeave'); | 87 | // MochiKit.Signal.connect(this.getId('button'), 'onmouseleave',this, 'handleOnMouseLeave'); |
80 | MochiKit.Signal.connect(this.getId('wrapper'), 'onmousedown',this, 'handleOnMouseDown'); | 88 | // MochiKit.Signal.connect(this.getId('button'), 'onmousedown',this, 'handleOnMouseDown'); |
81 | MochiKit.Signal.connect(this.getId('wrapper'), 'onclick', this, 'handleOnClick'); | 89 | MochiKit.Signal.connect(this.getId('button'), 'onclick', this, 'handleOnClick'); |
82 | }, | 90 | }, |
83 | 91 | ||
84 | //------------------------------------------------------------------------- | 92 | //------------------------------------------------------------------------- |
85 | 93 | /* | |
86 | 'handleOnMouseEnter': function (anEvent) { | 94 | 'handleOnMouseEnter': function (anEvent) { |
87 | MochiKit.DOM.addElementClass(this.getId('wrapper'), 'hover'); | 95 | MochiKit.DOM.addElementClass(this.getId('button'), 'hover'); |
88 | }, | 96 | }, |
89 | 97 | ||
90 | 'handleOnMouseLeave': function (anEvent) { | 98 | 'handleOnMouseLeave': function (anEvent) { |
91 | MochiKit.DOM.removeElementClass(this.getId('wrapper'), 'hover'); | 99 | MochiKit.DOM.removeElementClass(this.getId('button'), 'hover'); |
92 | MochiKit.DOM.removeElementClass(this.getId('wrapper'), 'clicked'); | 100 | MochiKit.DOM.removeElementClass(this.getId('button'), 'clicked'); |
93 | }, | 101 | }, |
94 | 102 | ||
95 | 'handleOnMouseDown': function (anEvent) { | 103 | 'handleOnMouseDown': function (anEvent) { |
96 | MochiKit.DOM.addElementClass(this.getId('wrapper'), 'clicked'); | 104 | MochiKit.DOM.addElementClass(this.getId('button'), 'clicked'); |
97 | }, | 105 | }, |
98 | 106 | */ | |
99 | 'handleOnClick': function (anEvent) { | 107 | 'handleOnClick': function (anEvent) { |
100 | MochiKit.Signal.signal(this, 'onclick', anEvent); | 108 | MochiKit.Signal.signal(this, 'onclick', anEvent); |
101 | }, | 109 | }, |
102 | 110 | ||
103 | //------------------------------------------------------------------------- | 111 | //------------------------------------------------------------------------- |
104 | __syntaxFix__: "syntax fix" | 112 | __syntaxFix__: "syntax fix" |
105 | }); | 113 | }); |
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js index 1992154..1d816a9 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js | |||
@@ -53,141 +53,159 @@ Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.SimpleMessagePanel, Clippe | |||
53 | return "Clipperz.PM.UI.Common.Components.SimpleMessagePanel component"; | 53 | return "Clipperz.PM.UI.Common.Components.SimpleMessagePanel component"; |
54 | }, | 54 | }, |
55 | 55 | ||
56 | //------------------------------------------------------------------------- | 56 | //------------------------------------------------------------------------- |
57 | 57 | ||
58 | 'deferred': function() { | 58 | 'deferred': function() { |
59 | if (this._deferred == null) { | 59 | if (this._deferred == null) { |
60 | this._deferred = new Clipperz.Async.Deferred("SimpleMessagePanel.deferred", {trace:false}); | 60 | this._deferred = new Clipperz.Async.Deferred("SimpleMessagePanel.deferred", {trace:false}); |
61 | } | 61 | } |
62 | 62 | ||
63 | return this._deferred; | 63 | return this._deferred; |
64 | }, | 64 | }, |
65 | 65 | ||
66 | //------------------------------------------------------------------------- | 66 | //------------------------------------------------------------------------- |
67 | 67 | ||
68 | 'title': function () { | 68 | 'title': function () { |
69 | return this._title; | 69 | return this._title; |
70 | }, | 70 | }, |
71 | 71 | ||
72 | 'setTitle': function (aValue) { | 72 | 'setTitle': function (aValue) { |
73 | this._title = aValue; | 73 | this._title = aValue; |
74 | 74 | ||
75 | if (this.getElement('title') != null) { | 75 | if (this.getElement('title') != null) { |
76 | this.getElement('title').innerHTML = aValue; | 76 | this.getElement('title').innerHTML = aValue; |
77 | } | 77 | } |
78 | }, | 78 | }, |
79 | 79 | ||
80 | //------------------------------------------------------------------------- | 80 | //------------------------------------------------------------------------- |
81 | 81 | ||
82 | 'text': function () { | 82 | 'text': function () { |
83 | return this._text; | 83 | return this._text; |
84 | }, | 84 | }, |
85 | 85 | ||
86 | 'setText': function (aValue) { | 86 | 'setText': function (aValue) { |
87 | this._text = aValue; | 87 | this._text = aValue; |
88 | 88 | ||
89 | if (this.getElement('text') != null) { | 89 | if (this.getElement('text') != null) { |
90 | this.getElement('text').innerHTML = aValue; | 90 | this.getElement('text').innerHTML = aValue; |
91 | } | 91 | } |
92 | }, | 92 | }, |
93 | 93 | ||
94 | //------------------------------------------------------------------------- | 94 | //------------------------------------------------------------------------- |
95 | 95 | ||
96 | 'type': function () { | 96 | 'type': function () { |
97 | return this._type; | 97 | return this._type; |
98 | }, | 98 | }, |
99 | 99 | ||
100 | 'setType': function (aValue) { | 100 | 'setType': function (aValue) { |
101 | if (this.getElement('icon') != null) { | 101 | // if (this.getElement('icon') != null) { |
102 | MochiKit.DOM.removeElementClass(this.getId('icon'), this._type); | 102 | // MochiKit.DOM.removeElementClass(this.getId('icon'), this._type); |
103 | MochiKit.DOM.addElementClass(this.getId('icon'), aValue); | 103 | // MochiKit.DOM.addElementClass(this.getId('icon'), aValue); |
104 | } | 104 | // } |
105 | 105 | ||
106 | this._type = aValue; | 106 | this._type = aValue; |
107 | }, | 107 | }, |
108 | 108 | ||
109 | 'icon': function () { | ||
110 | var type = this.type(); | ||
111 | var result; | ||
112 | |||
113 | if (type == 'ALERT') { | ||
114 | result = '!'; | ||
115 | } else if (type == 'INFO') { | ||
116 | result = 'i'; | ||
117 | } else if (type == 'ERROR') { | ||
118 | result = '!'; | ||
119 | } | ||
120 | |||
121 | return result; | ||
122 | }, | ||
123 | |||
109 | //------------------------------------------------------------------------- | 124 | //------------------------------------------------------------------------- |
110 | 125 | ||
111 | 'buttons': function () { | 126 | 'buttons': function () { |
112 | return this._buttons; | 127 | return this._buttons; |
113 | }, | 128 | }, |
114 | 129 | ||
115 | 'setButtons': function (someValues) { | 130 | 'setButtons': function (someValues) { |
116 | MochiKit.Iter.forEach(this.buttonComponents(), MochiKit.Base.methodcaller('clear')); | 131 | MochiKit.Iter.forEach(this.buttonComponents(), MochiKit.Base.methodcaller('clear')); |
117 | 132 | ||
118 | this._buttons = someValues; | 133 | this._buttons = someValues; |
119 | 134 | ||
120 | if (this.getElement('buttonArea') != null) { | 135 | if (this.getElement('buttonArea') != null) { |
121 | this.renderButtons(); | 136 | this.renderButtons(); |
122 | } | 137 | } |
123 | }, | 138 | }, |
124 | 139 | ||
125 | //......................................................................... | 140 | //......................................................................... |
126 | 141 | ||
127 | 'buttonComponents': function () { | 142 | 'buttonComponents': function () { |
128 | return this._buttonComponents; | 143 | return this._buttonComponents; |
129 | }, | 144 | }, |
130 | 145 | ||
131 | //------------------------------------------------------------------------- | 146 | //------------------------------------------------------------------------- |
132 | 147 | ||
133 | 'renderSelf': function() { | 148 | 'renderSelf': function() { |
134 | this.append(this.element(), {tag:'div', cls:'SimpleMessagePanel', id:this.getId('panel'), children: [ | 149 | this.append(this.element(), {tag:'div', cls:'SimpleMessagePanel', id:this.getId('panel'), children: [ |
135 | {tag:'div', cls:'header', children:[]}, | 150 | // {tag:'div', cls:'header', children:[]}, |
136 | {tag:'div', cls:'body', children:[ | 151 | {tag:'div', cls:'body', children:[ |
137 | {tag:'div', id:this.getId('icon'),cls:'img ' + this.type(), children:[{tag:'div'}]}, | 152 | // {tag:'div', id:this.getId('icon'),cls:'img ' + this.type(), children:[{tag:'div'}]}, |
153 | {tag:'div', /*id:this.getId('icon'),*/cls:'img ' + this.type(), children:[{tag:'canvas', id:this.getId('icon')}]}, | ||
138 | {tag:'h3', id:this.getId('title'),html:this.title()}, | 154 | {tag:'h3', id:this.getId('title'),html:this.title()}, |
139 | {tag:'p', id:this.getId('text'),html:this.text()}, | 155 | {tag:'p', id:this.getId('text'),html:this.text()}, |
140 | {tag:'div', id:this.getId('container')}, | 156 | {tag:'div', id:this.getId('container')}, |
141 | {tag:'div', id:this.getId('buttonArea'), cls:'buttonArea', children:[]} | 157 | {tag:'div', id:this.getId('buttonArea'), cls:'buttonArea', children:[]} |
142 | ]}, | 158 | ]} |
143 | {tag:'div', cls:'footer', children:[]} | 159 | // {tag:'div', cls:'footer', children:[]} |
144 | ]}); | 160 | ]}); |
145 | 161 | ||
162 | Clipperz.PM.UI.Canvas.marks[this.icon()](this.getElement('icon'), "#ffffff"); | ||
163 | |||
146 | MochiKit.Signal.connect(this.getId('panel'), 'onkeydown', this, 'keyDownHandler'); | 164 | MochiKit.Signal.connect(this.getId('panel'), 'onkeydown', this, 'keyDownHandler'); |
147 | 165 | ||
148 | this.renderButtons(); | 166 | this.renderButtons(); |
149 | }, | 167 | }, |
150 | 168 | ||
151 | //------------------------------------------------------------------------- | 169 | //------------------------------------------------------------------------- |
152 | 170 | ||
153 | 'renderButtons': function () { | 171 | 'renderButtons': function () { |
154 | this.getElement('buttonArea').innerHTML = ''; | 172 | this.getElement('buttonArea').innerHTML = ''; |
155 | 173 | ||
156 | MochiKit.Base.map(MochiKit.Base.bind(function (aButton) { | 174 | MochiKit.Base.map(MochiKit.Base.bind(function (aButton) { |
157 | var buttonElement; | 175 | var buttonElement; |
158 | var buttonComponent; | 176 | var buttonComponent; |
159 | 177 | ||
160 | // element = this.append(this.getElement('buttonArea'), {tag:'div', cls:'button' + (aButton['isDefault'] === true ? ' default' : ''), children:[ | 178 | // element = this.append(this.getElement('buttonArea'), {tag:'div', cls:'button' + (aButton['isDefault'] === true ? ' default' : ''), children:[ |
161 | // {tag:'a', href:'#'/*, id:this.getId('buttonLink')*/, html:aButton['text']} | 179 | // {tag:'a', href:'#'/*, id:this.getId('buttonLink')*/, html:aButton['text']} |
162 | // ]}); | 180 | // ]}); |
163 | 181 | ||
164 | buttonElement = this.append(this.getElement('buttonArea'), {tag:'div'}); | 182 | buttonElement = this.append(this.getElement('buttonArea'), {tag:'div'}); |
165 | buttonComponent = new Clipperz.PM.UI.Common.Components.Button({'element':buttonElement, 'text':aButton['text'], 'isDefault':aButton['isDefault']}); | 183 | buttonComponent = new Clipperz.PM.UI.Common.Components.Button({'element':buttonElement, 'text':aButton['text'], 'isDefault':aButton['isDefault']}); |
166 | this.buttonComponents().push(buttonComponent); | 184 | this.buttonComponents().push(buttonComponent); |
167 | 185 | ||
168 | MochiKit.Signal.connect(buttonComponent, 'onclick', MochiKit.Base.method(this, 'buttonEventHandler', aButton)); | 186 | MochiKit.Signal.connect(buttonComponent, 'onclick', MochiKit.Base.method(this, 'buttonEventHandler', aButton)); |
169 | }, this), MochiKit.Iter.reversed(this.buttons())); | 187 | }, this), MochiKit.Iter.reversed(this.buttons())); |
170 | }, | 188 | }, |
171 | 189 | ||
172 | //------------------------------------------------------------------------- | 190 | //------------------------------------------------------------------------- |
173 | 191 | ||
174 | 'displayElement': function() { | 192 | 'displayElement': function() { |
175 | return this.getElement('panel'); | 193 | return this.getElement('panel'); |
176 | }, | 194 | }, |
177 | 195 | ||
178 | //------------------------------------------------------------------------- | 196 | //------------------------------------------------------------------------- |
179 | 197 | ||
180 | 'closeOk': function () { | 198 | 'closeOk': function () { |
181 | this.deferred().callback(); | 199 | this.deferred().callback(); |
182 | this._deferred = null; | 200 | this._deferred = null; |
183 | }, | 201 | }, |
184 | 202 | ||
185 | 'closeCancel': function () { | 203 | 'closeCancel': function () { |
186 | this.deferred().cancel(); | 204 | this.deferred().cancel(); |
187 | this._deferred = null; | 205 | this._deferred = null; |
188 | }, | 206 | }, |
189 | 207 | ||
190 | 'closeError': function () { | 208 | 'closeError': function () { |
191 | this.deferred().errback(); | 209 | this.deferred().errback(); |
192 | this._deferred = null; | 210 | this._deferred = null; |
193 | }, | 211 | }, |
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardDetail.js b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardDetail.js new file mode 100644 index 0000000..32dfa63 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardDetail.js | |||
@@ -0,0 +1,299 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz Community Edition. | ||
6 | Clipperz Community Edition is an online password manager. | ||
7 | For further information about its features and functionalities please | ||
8 | refer to http://www.clipperz.com. | ||
9 | |||
10 | * Clipperz Community Edition is free software: you can redistribute | ||
11 | it and/or modify it under the terms of the GNU Affero General Public | ||
12 | License as published by the Free Software Foundation, either version | ||
13 | 3 of the License, or (at your option) any later version. | ||
14 | |||
15 | * Clipperz Community Edition is distributed in the hope that it will | ||
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
18 | See the GNU Affero General Public License for more details. | ||
19 | |||
20 | * You should have received a copy of the GNU Affero General Public | ||
21 | License along with Clipperz Community Edition. If not, see | ||
22 | <http://www.gnu.org/licenses/>. | ||
23 | |||
24 | */ | ||
25 | |||
26 | Clipperz.Base.module('Clipperz.PM.UI.Mobile.Components'); | ||
27 | |||
28 | Clipperz.PM.UI.Mobile.Components.CardDetail = function(args) { | ||
29 | args = args || {}; | ||
30 | |||
31 | Clipperz.PM.UI.Mobile.Components.CardDetail.superclass.constructor.apply(this, arguments); | ||
32 | |||
33 | //this._cardReference = null; | ||
34 | |||
35 | return this; | ||
36 | } | ||
37 | |||
38 | //============================================================================= | ||
39 | |||
40 | Clipperz.Base.extend(Clipperz.PM.UI.Mobile.Components.CardDetail, Clipperz.PM.UI.Common.Components.BaseComponent, { | ||
41 | |||
42 | //------------------------------------------------------------------------- | ||
43 | |||
44 | 'toString': function () { | ||
45 | return "Clipperz.PM.UI.Mobile.Components.CardDetail component"; | ||
46 | }, | ||
47 | |||
48 | //------------------------------------------------------------------------- | ||
49 | /* | ||
50 | 'cardReference': function () { | ||
51 | return this._cardReference; | ||
52 | }, | ||
53 | |||
54 | 'setCardReference': function (aValue) { | ||
55 | this._cardReference = aValue; | ||
56 | }, | ||
57 | */ | ||
58 | //------------------------------------------------------------------------- | ||
59 | |||
60 | 'renderSelf': function () { | ||
61 | console.log("CardDetail.renderSelf"); | ||
62 | this.append(this.element(), {tag:'div', cls:'cardDetail', children:[ | ||
63 | {tag:'div', cls:'toolbar', children:[ | ||
64 | {tag:'a', href:'#', cls:'back', html:"List"}, | ||
65 | {tag:'h1', id:this.getId('cardTitle'), html:"…"} | ||
66 | ]}, | ||
67 | {tag:'div', cls:'scroll', id:this.getId('cardDetails'), children:[ | ||
68 | ]} | ||
69 | ]}); | ||
70 | }, | ||
71 | /* | ||
72 | 'renderSelf': function() { | ||
73 | this.append(this.element(), [ | ||
74 | {tag:'div', cls:'cardDetail', id:this.getId('cardDetail'), children:[ | ||
75 | {tag:'div', id:this.getId('progressBar')} //, | ||
76 | ]} | ||
77 | ]); | ||
78 | |||
79 | this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); | ||
80 | MochiKit.Signal.signal(Clipperz.PM.UI.Common.Controllers.ProgressBarController.defaultController, 'updateProgress', 0); | ||
81 | }, | ||
82 | */ | ||
83 | |||
84 | 'setTitle': function (aValue) { | ||
85 | this.getElement('cardTitle').innerHTML = aValue; | ||
86 | }, | ||
87 | |||
88 | 'fieldListElement': function () { | ||
89 | varresult; | ||
90 | |||
91 | result = this.getElement('fieldList'); | ||
92 | if (result == null) { | ||
93 | result = this.append(this.getElement('cardDetails'), {tag:'ul', cls:'rounded', id:this.getId('fieldList')}); | ||
94 | } | ||
95 | |||
96 | return result; | ||
97 | }, | ||
98 | |||
99 | 'renderFieldValues': function (someFieldValues) { | ||
100 | varfieldClass; | ||
101 | |||
102 | if ((someFieldValues['actionType'] != 'NONE') || (someFieldValues['label'] != '') && (someFieldValues['value'] != '')) { | ||
103 | if (someFieldValues['isHidden'] == true) { | ||
104 | fieldClass = 'password'; | ||
105 | } else { | ||
106 | fieldClass = ''; | ||
107 | } | ||
108 | |||
109 | this.append(this.fieldListElement(), {tag:'li', cls:'cardField', children:[ | ||
110 | {tag:'a', href:'#', cls:fieldClass, html:someFieldValues['value'], children:[ | ||
111 | {tag:'small', cls:'label', html:someFieldValues['label']} | ||
112 | ]} | ||
113 | ]}) | ||
114 | } | ||
115 | }, | ||
116 | |||
117 | 'addField': function (aField) { | ||
118 | var deferredResult; | ||
119 | varfieldValues; | ||
120 | |||
121 | fieldValues = {}; | ||
122 | deferredResult = new Clipperz.Async.Deferred("CardDetail.addField", {trace:false}); | ||
123 | deferredResult.addMethod(aField, 'label'); | ||
124 | deferredResult.addCallback(function (aValue) { fieldValues['label'] = aValue; }); | ||
125 | deferredResult.addMethod(aField, 'value'); | ||
126 | deferredResult.addCallback(function (aValue) { fieldValues['value'] = aValue; }); | ||
127 | deferredResult.addMethod(aField, 'actionType'); | ||
128 | deferredResult.addCallback(function (aValue) { fieldValues['actionType'] = aValue; }); | ||
129 | deferredResult.addMethod(aField, 'isHidden'); | ||
130 | deferredResult.addCallback(function (aValue) { fieldValues['isHidden'] = aValue; }); | ||
131 | deferredResult.addMethod(this, 'renderFieldValues', fieldValues); | ||
132 | deferredResult.callback(); | ||
133 | |||
134 | return deferredResult; | ||
135 | }, | ||
136 | |||
137 | //------------------------------------------------------------------------- | ||
138 | |||
139 | 'directLoginElement': function () { | ||
140 | varresult; | ||
141 | |||
142 | result = this.getElement('directLoginList'); | ||
143 | if (result == null) { | ||
144 | this.append(this.getElement('cardDetails'), {tag:'h2', html:"Direct login"}); | ||
145 | result = this.append(this.getElement('cardDetails'), {tag:'ul', cls:'rounded', id:this.getId('directLoginList')}); | ||
146 | } | ||
147 | |||
148 | return result; | ||
149 | }, | ||
150 | |||
151 | 'addDirectLogin': function (aDirectLogin) { | ||
152 | this.append(this.directLoginElement(), {tag:'li', cls:'directLogin forward', children:[ | ||
153 | {tag:'a', href:'#', html:"direct login", children:[ | ||
154 | {tag:'small', cls:'favicon', children:[{tag:'img', cls:'favicon', src:'http://www.clipperz.com/favicon.ico'}]} | ||
155 | ]} | ||
156 | ]}) | ||
157 | |||
158 | console.log("ADD DIRECT LOGIN", aDirectLogin); | ||
159 | }, | ||
160 | |||
161 | //========================================================================= | ||
162 | |||
163 | 'showCard': function (aCard) { | ||
164 | var deferredResult; | ||
165 | |||
166 | // this.render(); | ||
167 | |||
168 | console.log("CardDetail.showCard", aCard); | ||
169 | deferredResult = new Clipperz.Async.Deferred("CardDetail.showCard", {trace:false}); | ||
170 | deferredResult.addMethod(aCard, 'label'); | ||
171 | deferredResult.addMethod(this, 'setTitle'); | ||
172 | |||
173 | deferredResult.addMethod(aCard, 'fields'); | ||
174 | deferredResult.addCallback(MochiKit.Base.values); | ||
175 | deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'addField')); | ||
176 | |||
177 | deferredResult.addMethod(aCard, 'directLogins'); | ||
178 | deferredResult.addCallback(MochiKit.Base.values); | ||
179 | deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'addDirectLogin')); | ||
180 | |||
181 | |||
182 | deferredResult.callback(); | ||
183 | |||
184 | return deferredResult; | ||
185 | // return Clipperz.Async.callbacks("CardDialogController.updateComponentState", [ | ||
186 | // MochiKit.Base.method(this.record(), 'hasPendingChanges'), | ||
187 | // MochiKit.Base.method(this.cardDialogComponent(), 'setShouldEnableSaving'), | ||
188 | // | ||
189 | // MochiKit.Base.method(this.record(), 'label'), | ||
190 | // MochiKit.Base.method(this.cardDialogComponent(), 'setTitle'), | ||
191 | // MochiKit.Base.method(this.record(), 'notes'), | ||
192 | // MochiKit.Base.method(this.cardDialogComponent(), 'setNotes'), | ||
193 | // | ||
194 | // MochiKit.Base.method(this.record(), 'fields'), | ||
195 | // MochiKit.Base.values, | ||
196 | // MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addCardDialogComponentWithField')), | ||
197 | // | ||
198 | // MochiKit.Base.method(this.record(), 'directLogins'), | ||
199 | // MochiKit.Base.values, | ||
200 | // MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addCardDialogComponentWithDirectLogin')), | ||
201 | // | ||
202 | // MochiKit.Base.method(this.cardDialogComponent(), 'resetNewFieldInputs'), | ||
203 | // MochiKit.Base.noop | ||
204 | // ], {trace:false}); | ||
205 | |||
206 | }, | ||
207 | |||
208 | //========================================================================= | ||
209 | |||
210 | 'showCardDetails': function (someData) { | ||
211 | this.element().innerHTML = ''; | ||
212 | this.append(this.element(), [ | ||
213 | {tag:'fieldset', id:this.getId('fields'), children:MochiKit.Base.map(function (aFieldData) { | ||
214 | return {tag:'div', cls:'row', children:[ | ||
215 | {tag:'label', html:aFieldData['label']}, | ||
216 | // {tag:'span', cls:('fieldValue ' + (aFieldData['isHidden']? 'password' : 'text')), html:aFieldData['value']} | ||
217 | {tag:'div', cls:('fieldValue ' + (aFieldData['isHidden']? 'password' : 'text')), children:[ | ||
218 | {tag:'div', children:[{tag:'p', html:aFieldData['value']}]} | ||
219 | ]} | ||
220 | // {tag:'input', type:'text', cls:('fieldValue ' + (aFieldData['isHidden']? 'password' : 'text')), value:aFieldData['value'], disabled:true} | ||
221 | |||
222 | ]} | ||
223 | }, someData['fields'])} | ||
224 | ]); | ||
225 | |||
226 | MochiKit.Iter.forEach(MochiKit.Selector.findChildElements(this.element(), ['span.password']), MochiKit.Base.bind(function (aPasswordElement) { | ||
227 | MochiKit.Signal.connect(aPasswordElement, 'onclick', function (anEvent) { alert(MochiKit.DOM.scrapeText(anEvent.src())); }) | ||
228 | }, this)); | ||
229 | |||
230 | if (someData['directLogins'].length > 0) { | ||
231 | this.append(this.element(), [ | ||
232 | {tag:'h2', html:"Direct logins"}, | ||
233 | {tag:'fieldset', id:this.getId('directLogins'), children:MochiKit.Base.map(function (aDirectLoginData) { | ||
234 | return {tag:'div', cls:'row', id:('directLogin_' + aDirectLoginData['_reference']), children:[ | ||
235 | {tag:'img', cls:'favicon', src:aDirectLoginData['favicon']}, | ||
236 | // {tag:'input', cls:'directLogin', disabled:'disabled', type:'text', name:aDirectLoginData['label'], value:aDirectLoginData['label']} | ||
237 | {tag:'span', cls:'directLogin', html:aDirectLoginData['label']} | ||
238 | ]} | ||
239 | }, someData['directLogins'])} | ||
240 | ]); | ||
241 | |||
242 | MochiKit.Base.map(MochiKit.Base.bind(function (aRowNode) { | ||
243 | MochiKit.Signal.connect(aRowNode, 'onclick', this, 'directLoginClickHandler'); | ||
244 | }, this), | ||
245 | MochiKit.Selector.findChildElements(this.getElement('directLogins'), ['div.row']) | ||
246 | ) | ||
247 | }; | ||
248 | |||
249 | if (someData['notes'] != '') { | ||
250 | this.append(this.element(), [ | ||
251 | {tag:'h2', html:"Notes"}, | ||
252 | {tag:'fieldset', id:this.getId('fieldset'), children:[ | ||
253 | {tag:'div', cls:'row notes', children:[ | ||
254 | {tag:'span', html:someData['notes']} | ||
255 | ]} | ||
256 | ]} | ||
257 | ]); | ||
258 | }; | ||
259 | |||
260 | return true; | ||
261 | }, | ||
262 | |||
263 | //------------------------------------------------------------------------- | ||
264 | /* | ||
265 | 'toggleClickHandler': function (anEvent) { | ||
266 | varnextState; | ||
267 | varfieldValue; | ||
268 | |||
269 | //console.log("TOGGLE"); | ||
270 | anEvent.preventDefault; | ||
271 | fieldValue = MochiKit.Selector.findChildElements(anEvent.src().parentNode.parentNode, ['span.password'])[0]; | ||
272 | |||
273 | nextState = (MochiKit.DOM.getNodeAttribute(anEvent.src(), 'toggled') != 'true'); | ||
274 | if (nextState) { | ||
275 | MochiKit.DOM.removeElementClass(fieldValue, 'clear'); | ||
276 | } else { | ||
277 | MochiKit.DOM.addElementClass(fieldValue, 'clear'); | ||
278 | } | ||
279 | |||
280 | MochiKit.DOM.setNodeAttribute(anEvent.src(), 'toggled', nextState); | ||
281 | }, | ||
282 | * / | ||
283 | //========================================================================= | ||
284 | /* | ||
285 | 'directLoginClickHandler': function (anEvent) { | ||
286 | anEvent.preventDefault(); | ||
287 | |||
288 | if (/(directLogin_)/.test(anEvent.src().id)) { | ||
289 | var directLoginReference; | ||
290 | |||
291 | directLoginReference = anEvent.src().id.match(/(directLogin_)(.*)/)[2]; | ||
292 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'selectedDirectLogin', {cardReference:this.cardReference(), directLoginReference:directLoginReference}); | ||
293 | } | ||
294 | }, | ||
295 | */ | ||
296 | //========================================================================= | ||
297 | |||
298 | __syntaxFix__: "syntax fix" | ||
299 | }); | ||
diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardList.js b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardList.js index c3f2701..a4aa212 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardList.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/CardList.js | |||
@@ -1,201 +1,254 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2011 Clipperz Srl | 3 | Copyright 2008-2011 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz Community Edition. | 5 | This file is part of Clipperz Community Edition. |
6 | Clipperz Community Edition is an online password manager. | 6 | Clipperz Community Edition is an online password manager. |
7 | For further information about its features and functionalities please | 7 | For further information about its features and functionalities please |
8 | refer to http://www.clipperz.com. | 8 | refer to http://www.clipperz.com. |
9 | 9 | ||
10 | * Clipperz Community Edition is free software: you can redistribute | 10 | * Clipperz Community Edition is free software: you can redistribute |
11 | it and/or modify it under the terms of the GNU Affero General Public | 11 | it and/or modify it under the terms of the GNU Affero General Public |
12 | License as published by the Free Software Foundation, either version | 12 | License as published by the Free Software Foundation, either version |
13 | 3 of the License, or (at your option) any later version. | 13 | 3 of the License, or (at your option) any later version. |
14 | 14 | ||
15 | * Clipperz Community Edition is distributed in the hope that it will | 15 | * Clipperz Community Edition is distributed in the hope that it will |
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | 16 | be useful, but WITHOUT ANY WARRANTY; without even the implied |
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. | 18 | See the GNU Affero General Public License for more details. |
19 | 19 | ||
20 | * You should have received a copy of the GNU Affero General Public | 20 | * You should have received a copy of the GNU Affero General Public |
21 | License along with Clipperz Community Edition. If not, see | 21 | License along with Clipperz Community Edition. If not, see |
22 | <http://www.gnu.org/licenses/>. | 22 | <http://www.gnu.org/licenses/>. |
23 | 23 | ||
24 | */ | 24 | */ |
25 | 25 | ||
26 | Clipperz.Base.module('Clipperz.PM.UI.iPhone.Components'); | 26 | Clipperz.Base.module('Clipperz.PM.UI.Mobile.Components'); |
27 | 27 | ||
28 | Clipperz.PM.UI.iPhone.Components.CardList = function(args) { | 28 | Clipperz.PM.UI.Mobile.Components.CardList = function(args) { |
29 | args = args || {}; | 29 | args = args || {}; |
30 | 30 | ||
31 | Clipperz.PM.UI.iPhone.Components.CardList.superclass.constructor.apply(this, arguments); | 31 | Clipperz.PM.UI.Mobile.Components.CardList.superclass.constructor.apply(this, arguments); |
32 | 32 | ||
33 | this._cardDetail = null; | 33 | this._cardDetail = null; |
34 | 34 | ||
35 | return this; | 35 | return this; |
36 | } | 36 | } |
37 | 37 | ||
38 | //============================================================================= | 38 | //============================================================================= |
39 | 39 | ||
40 | Clipperz.Base.extend(Clipperz.PM.UI.iPhone.Components.CardList, Clipperz.PM.UI.Common.Components.BaseComponent, { | 40 | Clipperz.Base.extend(Clipperz.PM.UI.Mobile.Components.CardList, Clipperz.PM.UI.Common.Components.BaseComponent, { |
41 | 41 | ||
42 | //------------------------------------------------------------------------- | 42 | //------------------------------------------------------------------------- |
43 | 43 | ||
44 | 'toString': function () { | 44 | 'toString': function () { |
45 | return "Clipperz.PM.UI.iPhone.Components.CardList component"; | 45 | return "Clipperz.PM.UI.Mobile.Components.CardList component"; |
46 | }, | 46 | }, |
47 | 47 | ||
48 | //------------------------------------------------------------------------- | 48 | //------------------------------------------------------------------------- |
49 | 49 | ||
50 | 'renderSelf': function(/*aContainer, aPosition*/) { | 50 | 'renderSelf': function () { |
51 | this.append(this.element(), [ | 51 | this.append(this.element(), {tag:'div', cls:'cardList', children:[ |
52 | {tag:'div', cls:'toolbar', id:'toolbar', children:[ | 52 | {tag:'div', cls:'toolbar', children:[ |
53 | {tag:'h1', id:'pageTitle', html:"cards"}, | 53 | {tag:'h1', html:"clipperz"}, |
54 | {tag:'a', id:'backButton', cls:'button', href:'#', html:"cards"} | 54 | // {tag:'input', name:'search', type:'search', autocomplete:'off', placeholder:"search", id:this.getId('search')}, |
55 | {tag:'a', href:'#', id:'settings', cls:'button', html:"*"} | ||
55 | ]}, | 56 | ]}, |
56 | {tag:'div', cls:'cardList', id:this.getId('cardList'), children:[ | 57 | {tag:'div', cls:'scroll', id:this.getId('listBox'), children:[ |
57 | {tag:'form', title:'search', cls:'panel cardListSearchForm', id:this.getId('cardListSearchForm'), children:[ | 58 | {tag:'ul', cls:'rounded', id:this.getId('list'), children:[ |
58 | {tag:'input', type:'search', name:'search', value:"", placeholder:"search", id:this.getId('searchField')} | 59 | {tag:'li', html:'loading'} |
59 | ]}, | 60 | ]} |
60 | {tag:'ul', cls:'panel cardListPanel', id:this.getId('cardListPanel'), children:[]} | 61 | ]} |
61 | ]}, | 62 | ]}); |
62 | {tag:'div', cls:'panel cardDetailPanel', id:this.getId('cardDetail')} | 63 | |
63 | ]); | 64 | MochiKit.Signal.connect(this.getElement('list'), 'onclick', this, 'cardSelectionHandler'); |
65 | MochiKit.Signal.connect(this.getElement('list'), 'ontouchstart',this, 'cardSelectionHandler'); | ||
66 | // MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onsubmit', this,'searchHandler'); | ||
67 | // MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeydown', this,'searchHandler'); | ||
68 | // MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeyup', this,'searchHandler'); | ||
69 | |||
70 | // MochiKit.Signal.connect(this.getElement('cardListPanel'), 'onclick', this,'cardListClickHandler'); | ||
71 | // MochiKit.Signal.connect('backButton', 'onclick', this,'backButtonClickHandler'); | ||
72 | |||
73 | // MochiKit.Style.hideElement('backButton'); | ||
74 | // MochiKit.Style.hideElement(this.getElement('cardDetail')); | ||
75 | }, | ||
64 | 76 | ||
65 | MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onsubmit', this,'searchHandler'); | 77 | 'showCards': function (someCards) { |
66 | MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeydown', this,'searchHandler'); | 78 | varcardListElement; |
67 | MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeyup', this,'searchHandler'); | 79 | if (this.isFullyRendered() == false) { |
80 | this.render(); | ||
81 | }; | ||
82 | |||
83 | cardListElement = this.getElement('list') | ||
84 | |||
85 | cardInfo = { | ||
86 | '_rowObject': MochiKit.Async.succeed, | ||
87 | '_reference': MochiKit.Base.methodcaller('reference'), | ||
88 | '_searchableContent':MochiKit.Base.methodcaller('searchableContent'), | ||
89 | 'label': MochiKit.Base.methodcaller('label'), | ||
90 | 'favicon': MochiKit.Base.methodcaller('favicon') | ||
91 | }; | ||
92 | |||
93 | //console.log("someCards", someCards); | ||
94 | deferredResult = new Clipperz.Async.Deferred("CardList.showCards", {trace:false}); | ||
95 | deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("CardList.value - collectResults", cardInfo, {trace:false})); | ||
96 | deferredResult.addCallback(Clipperz.Async.collectAll); | ||
97 | deferredResult.addCallback(MochiKit.Base.methodcaller('sort', Clipperz.Base.caseInsensitiveKeyComparator('label'))); | ||
98 | deferredResult.addCallbackPass(MochiKit.DOM.replaceChildNodes, cardListElement); | ||
99 | // deferredResult.addCallbackPass(MochiKit.DOM.removeElementClass, cardListElement, 'loading'); | ||
100 | deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'appendCardToList', cardListElement)); | ||
101 | deferredResult.callback(someCards); | ||
102 | }, | ||
68 | 103 | ||
69 | MochiKit.Signal.connect(this.getElement('cardListPanel'), 'onclick', this,'cardListClickHandler'); | 104 | 'appendCardToList': function (aCardListElement, aCardInfo) { |
70 | MochiKit.Signal.connect('backButton', 'onclick', this,'backButtonClickHandler'); | 105 | //console.log("appendCardToList", aCardInfo); |
106 | this.append(aCardListElement, {tag:'li', cls:'cardListItem arrow', cardreference:aCardInfo['_reference'], children:[ | ||
107 | {tag:'a', href:'#', html:aCardInfo['label'], children:[ | ||
108 | {tag:'small', cls:'favicon', children:[{tag:'img', cls:'favicon', src:aCardInfo['favicon']}]} | ||
109 | ]} | ||
110 | ]}); | ||
111 | }, | ||
112 | |||
113 | 'cardSelectionHandler': function (anEvent) { | ||
114 | var listElement; | ||
115 | varcardReference; | ||
71 | 116 | ||
72 | MochiKit.Style.hideElement('backButton'); | 117 | anEvent.preventDefault(); |
73 | MochiKit.Style.hideElement(this.getElement('cardDetail')); | 118 | |
119 | listElement = anEvent.target(); | ||
120 | if (MochiKit.DOM.getNodeAttribute(listElement, 'cardreference') == null) { | ||
121 | listElement = MochiKit.DOM.getFirstParentByTagAndClassName(anEvent.target(), tagName='li', className='cardListItem'); | ||
122 | } | ||
123 | cardReference = MochiKit.DOM.getNodeAttribute(listElement, 'cardreference'); | ||
124 | console.log("###", listElement, cardReference); | ||
125 | //TODO: Notify card with reference MochiKit.DOM.getNodeAttribute(listElement, 'cardreference') has been selected | ||
126 | MochiKit.Signal.signal(this, 'selectedCard', cardReference); | ||
74 | }, | 127 | }, |
75 | 128 | ||
76 | //------------------------------------------------------------------------- | 129 | //------------------------------------------------------------------------- |
77 | 130 | /* | |
78 | 'searchHandler': function (anEvent) { | 131 | 'searchHandler': function (anEvent) { |
79 | if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ENTER')) { //RETURN | 132 | if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ENTER')) { //RETURN |
80 | anEvent.preventDefault(); | 133 | anEvent.preventDefault(); |
81 | } else { | 134 | } else { |
82 | if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ESCAPE')) { | 135 | if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ESCAPE')) { |
83 | anEvent.target().value = ""; | 136 | anEvent.target().value = ""; |
84 | } | 137 | } |
85 | 138 | ||
86 | if (anEvent.type() == 'keyup') { | 139 | if (anEvent.type() == 'keyup') { |
87 | MochiKit.Signal.signal(this, 'searchEvent', anEvent.target().value); | 140 | MochiKit.Signal.signal(this, 'searchEvent', anEvent.target().value); |
88 | } | 141 | } |
89 | } | 142 | } |
90 | }, | 143 | }, |
91 | 144 | ||
92 | //------------------------------------------------------------------------- | 145 | //------------------------------------------------------------------------- |
93 | 146 | ||
94 | 'update': function (someObjects) { | 147 | 'update': function (someObjects) { |
95 | varcardListPanel; | 148 | varcardListPanel; |
96 | var i,c; | 149 | var i,c; |
97 | 150 | ||
98 | cardListPanel = this.getElement('cardListPanel'); | 151 | cardListPanel = this.getElement('cardListPanel'); |
99 | cardListPanel.innerHTML = ''; | 152 | cardListPanel.innerHTML = ''; |
100 | 153 | ||
101 | c = someObjects.length; | 154 | c = someObjects.length; |
102 | 155 | ||
103 | for (i=0; i<c; i++) { | 156 | for (i=0; i<c; i++) { |
104 | this.append(cardListPanel, {tag:'li', cls:'cardListItem', id:('cardListItem_' + someObjects[i]['_reference']), children:[ | 157 | this.append(cardListPanel, {tag:'li', cls:'cardListItem', id:('cardListItem_' + someObjects[i]['_reference']), children:[ |
105 | {tag:'img', src:(someObjects[i]['favicon'] ? someObjects[i]['favicon'] : 'data:application/octet-stream;charset=utf-8;base64,AAABAAEAFxcAAAEAGAD8BgAAFgAAACgAAAAXAAAALgAAAAEAGAAAAAAAAAAAABIXAAASFwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////9zAC////////////////////////////////////////////////////////////////////////////////////////////9pAG////////////////////////////////////////////////////////////////////////////////////////////9rAC////////////////////////////////////////////////////////////////////////////////////////////9yAHP////////////////////////IyMizs7O6urrq6ur////////////Ozs6zs7Ozs7Pq6ur///////////////////////8AAAD////////////////////V1dWXl5eXl5eXl5elpaX4+Pj////Ozs6Xl5eXl5eXl5eenp7///////////////////////8AAAD////////////////////Ozs6Xl5eXl5eXl5eXl5fBwcHq6uqenp6Xl5eXl5eXl5eXl5f///////////////////////8AAAD////////////////////j4+OXl5eXl5eXl5eXl5eXl5elpaWXl5eXl5eXl5eXl5ezs7P///////////////////////8AAAD////////////////////////IyMiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eenp7x8fH////////////////////////////////////////////////////4+PilpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5fOzs7////////////////////////////////////////////////////////q6uq6urqXl5eXl5eXl5eXl5eXl5eXl5eenp7V1dX4+Pj///////////////////////8AAAD////////////4+PjOzs6lpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5e6urrj4+P///////////////8AAAD////////////BwcGXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fx8fH///////////8AAAD///////////+zs7OXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fj4+P///////////8AAAD////////////IyMiXl5eXl5eXl5eXl5e6urqXl5eXl5eXl5eXl5esrKylpaWXl5eXl5eXl5eenp7x8fH///////////8AAAD////////////////Ozs7Ozs7V1dX4+Pj///+Xl5eXl5eXl5eXl5fOzs7////q6urOzs7Ozs7q6ur///////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD////////////////////////////////////IyMiXl5eXl5eenp7x8fH///////////////////////////////////8AAAD////////////////////////////////////////j4+Pj4+Px8fH///////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo=')}, | 158 | {tag:'img', src:(someObjects[i]['favicon'] ? someObjects[i]['favicon'] : 'data:application/octet-stream;charset=utf-8;base64,AAABAAEAFxcAAAEAGAD8BgAAFgAAACgAAAAXAAAALgAAAAEAGAAAAAAAAAAAABIXAAASFwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////9zAC////////////////////////////////////////////////////////////////////////////////////////////9pAG////////////////////////////////////////////////////////////////////////////////////////////9rAC////////////////////////////////////////////////////////////////////////////////////////////9yAHP////////////////////////IyMizs7O6urrq6ur////////////Ozs6zs7Ozs7Pq6ur///////////////////////8AAAD////////////////////V1dWXl5eXl5eXl5elpaX4+Pj////Ozs6Xl5eXl5eXl5eenp7///////////////////////8AAAD////////////////////Ozs6Xl5eXl5eXl5eXl5fBwcHq6uqenp6Xl5eXl5eXl5eXl5f///////////////////////8AAAD////////////////////j4+OXl5eXl5eXl5eXl5eXl5elpaWXl5eXl5eXl5eXl5ezs7P///////////////////////8AAAD////////////////////////IyMiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eenp7x8fH////////////////////////////////////////////////////4+PilpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5fOzs7////////////////////////////////////////////////////////q6uq6urqXl5eXl5eXl5eXl5eXl5eXl5eenp7V1dX4+Pj///////////////////////8AAAD////////////4+PjOzs6lpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5e6urrj4+P///////////////8AAAD////////////BwcGXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fx8fH///////////8AAAD///////////+zs7OXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fj4+P///////////8AAAD////////////IyMiXl5eXl5eXl5eXl5e6urqXl5eXl5eXl5eXl5esrKylpaWXl5eXl5eXl5eenp7x8fH///////////8AAAD////////////////Ozs7Ozs7V1dX4+Pj///+Xl5eXl5eXl5eXl5fOzs7////q6urOzs7Ozs7q6ur///////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD////////////////////////////////////IyMiXl5eXl5eenp7x8fH///////////////////////////////////8AAAD////////////////////////////////////////j4+Pj4+Px8fH///////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo=')}, |
106 | {tag:'a', id:('cardListReference_' + someObjects[i]['_reference']), href:'#', html:someObjects[i]['label']} | 159 | {tag:'a', id:('cardListReference_' + someObjects[i]['_reference']), href:'#', html:someObjects[i]['label']} |
107 | ]}) | 160 | ]}) |
108 | 161 | ||
109 | MochiKit.Signal.connect('cardListItem_' + someObjects[i]['_reference'], 'onclick', this, 'cardListClickHandler'); | 162 | MochiKit.Signal.connect('cardListItem_' + someObjects[i]['_reference'], 'onclick', this, 'cardListClickHandler'); |
110 | } | 163 | } |
111 | 164 | ||
112 | }, | 165 | }, |
113 | 166 | ||
114 | 'cardListClickHandler': function (anEvent) { | 167 | 'cardListClickHandler': function (anEvent) { |
115 | anEvent.preventDefault(); | 168 | anEvent.preventDefault(); |
116 | 169 | ||
117 | if (/(cardListReference_|cardListItem_)/.test(anEvent.target().id)) { | 170 | if (/(cardListReference_|cardListItem_)/.test(anEvent.target().id)) { |
118 | var cardListReference; | 171 | var cardListReference; |
119 | 172 | ||
120 | cardListReference = anEvent.target().id.match(/(cardListReference_|cardListItem_)(.*)/)[2]; | 173 | cardListReference = anEvent.target().id.match(/(cardListReference_|cardListItem_)(.*)/)[2]; |
121 | //console.log("Showing detail for card named", cardListReference); | 174 | //console.log("Showing detail for card named", cardListReference); |
122 | MochiKit.Signal.signal(this, 'selectedCard', cardListReference); | 175 | MochiKit.Signal.signal(this, 'selectedCard', cardListReference); |
123 | } | 176 | } |
124 | }, | 177 | }, |
125 | 178 | ||
126 | //========================================================================= | 179 | //========================================================================= |
127 | 180 | ||
128 | 'cardDetail': function (someData) { | 181 | 'cardDetail': function (someData) { |
129 | if (this._cardDetail == null) { | 182 | if (this._cardDetail == null) { |
130 | this._cardDetail = new Clipperz.PM.UI.iPhone.Components.CardDetail({element:this.getElement('cardDetail')}); | 183 | this._cardDetail = new Clipperz.PM.UI.Mobile.Components.CardDetail({element:this.getElement('cardDetail')}); |
131 | } | 184 | } |
132 | 185 | ||
133 | return this._cardDetail; | 186 | return this._cardDetail; |
134 | }, | 187 | }, |
135 | 188 | ||
136 | //------------------------------------------------------------------------- | 189 | //------------------------------------------------------------------------- |
137 | 190 | ||
138 | 'removeCardDetail': function () { | 191 | 'removeCardDetail': function () { |
139 | if (this._cardDetail != null) { | 192 | if (this._cardDetail != null) { |
140 | this._cardDetail.remove(); | 193 | this._cardDetail.remove(); |
141 | this._cardDetail = null; | 194 | this._cardDetail = null; |
142 | } | 195 | } |
143 | }, | 196 | }, |
144 | 197 | ||
145 | //========================================================================= | 198 | //========================================================================= |
146 | 199 | ||
147 | 'showCard': function (someData) { | 200 | 'showCard': function (someData) { |
148 | vardeferredResult; | 201 | vardeferredResult; |
149 | varoffset; | 202 | varoffset; |
150 | 203 | ||
151 | offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480); | 204 | offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480); |
152 | this.cardDetail().render(); | 205 | this.cardDetail().render(); |
153 | this.cardDetail().setCardReference(someData['_reference']); | 206 | this.cardDetail().setCardReference(someData['_reference']); |
154 | MochiKit.Style.setElementPosition(this.cardDetail().element(), {x:offset}); | 207 | MochiKit.Style.setElementPosition(this.cardDetail().element(), {x:offset}); |
155 | new MochiKit.Visual.Sequence([ | 208 | new MochiKit.Visual.Sequence([ |
156 | // new MochiKit.Visual.Move(this.cardDetail().element(), {x:offset, y:45, mode:'absolute', duration:0, sync:true}), | 209 | // new MochiKit.Visual.Move(this.cardDetail().element(), {x:offset, y:45, mode:'absolute', duration:0, sync:true}), |
157 | new MochiKit.Visual.Parallel([ | 210 | new MochiKit.Visual.Parallel([ |
158 | new MochiKit.Visual.Move(this.getElement('cardList'), {x:-offset, y:0, mode:'relative',transition:MochiKit.Visual.Transitions.linear, sync:true}), | 211 | new MochiKit.Visual.Move(this.getElement('cardList'), {x:-offset, y:0, mode:'relative',transition:MochiKit.Visual.Transitions.linear, sync:true}), |
159 | new MochiKit.Visual.Move(this.getElement('cardDetail'), {x:0, y:45, mode:'absolute',transition:MochiKit.Visual.Transitions.linear, sync:true}), | 212 | new MochiKit.Visual.Move(this.getElement('cardDetail'), {x:0, y:45, mode:'absolute',transition:MochiKit.Visual.Transitions.linear, sync:true}), |
160 | // new MochiKit.Visual.ScrollTo('toolbar', {sync:true}), | 213 | // new MochiKit.Visual.ScrollTo('toolbar', {sync:true}), |
161 | MochiKit.Visual.appear ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true}) | 214 | MochiKit.Visual.appear ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true}) |
162 | ], {duration:1, sync:true}), | 215 | ], {duration:1, sync:true}), |
163 | MochiKit.Visual.fade(this.getElement('cardList'), {duration:0, sync:true}) | 216 | MochiKit.Visual.fade(this.getElement('cardList'), {duration:0, sync:true}) |
164 | ], {}) | 217 | ], {}) |
165 | 218 | ||
166 | MochiKit.DOM.getElement('pageTitle').innerHTML = someData['title']; | 219 | MochiKit.DOM.getElement('pageTitle').innerHTML = someData['title']; |
167 | 220 | ||
168 | return true; | 221 | return true; |
169 | }, | 222 | }, |
170 | 223 | ||
171 | //------------------------------------------------------------------------- | 224 | //------------------------------------------------------------------------- |
172 | 225 | ||
173 | 'showCardDetails': function (someData) { | 226 | 'showCardDetails': function (someData) { |
174 | return this.cardDetail().showCardDetails(someData); | 227 | return this.cardDetail().showCardDetails(someData); |
175 | }, | 228 | }, |
176 | 229 | ||
177 | //========================================================================= | 230 | //========================================================================= |
178 | 231 | ||
179 | 'backButtonClickHandler': function (anEvent) { | 232 | 'backButtonClickHandler': function (anEvent) { |
180 | varoffset; | 233 | varoffset; |
181 | 234 | ||
182 | anEvent.preventDefault(); | 235 | anEvent.preventDefault(); |
183 | 236 | ||
184 | MochiKit.DOM.getElement('pageTitle').innerHTML = "cards"; | 237 | MochiKit.DOM.getElement('pageTitle').innerHTML = "cards"; |
185 | 238 | ||
186 | offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480); | 239 | offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480); |
187 | MochiKit.Style.setElementPosition(this.getElement('cardList'), {x:-offset}); | 240 | MochiKit.Style.setElementPosition(this.getElement('cardList'), {x:-offset}); |
188 | MochiKit.DOM.showElement(this.getElement('cardList')); | 241 | MochiKit.DOM.showElement(this.getElement('cardList')); |
189 | 242 | ||
190 | new MochiKit.Visual.Parallel([ | 243 | new MochiKit.Visual.Parallel([ |
191 | new MochiKit.Visual.Move(this.getElement('cardList'), {x:offset, y:0, mode:'relative',transition:MochiKit.Visual.Transitions.linear, sync:true}), | 244 | new MochiKit.Visual.Move(this.getElement('cardList'), {x:offset, y:0, mode:'relative',transition:MochiKit.Visual.Transitions.linear, sync:true}), |
192 | new MochiKit.Visual.Move(this.getElement('cardDetail'), {x:offset, y:0, mode:'relative',transition:MochiKit.Visual.Transitions.linear, sync:true}), | 245 | new MochiKit.Visual.Move(this.getElement('cardDetail'), {x:offset, y:0, mode:'relative',transition:MochiKit.Visual.Transitions.linear, sync:true}), |
193 | MochiKit.Visual.fade (this.getElement('cardDetail'), { transition:MochiKit.Visual.Transitions.linear, sync:true}), | 246 | MochiKit.Visual.fade (this.getElement('cardDetail'), { transition:MochiKit.Visual.Transitions.linear, sync:true}), |
194 | MochiKit.Visual.fade ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true}) | 247 | MochiKit.Visual.fade ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true}) |
195 | ], {duration:1, afterFinish:MochiKit.Base.method(this, 'removeCardDetail')}) | 248 | ], {duration:1, afterFinish:MochiKit.Base.method(this, 'removeCardDetail')}) |
196 | 249 | ||
197 | }, | 250 | }, |
198 | 251 | */ | |
199 | //========================================================================= | 252 | //========================================================================= |
200 | __syntaxFix__: "syntax fix" | 253 | __syntaxFix__: "syntax fix" |
201 | }); | 254 | }); |
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/LoginForm.js b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/LoginForm.js new file mode 100644 index 0000000..eafcdbc --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Components/LoginForm.js | |||
@@ -0,0 +1,356 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz Community Edition. | ||
6 | Clipperz Community Edition is an online password manager. | ||
7 | For further information about its features and functionalities please | ||
8 | refer to http://www.clipperz.com. | ||
9 | |||
10 | * Clipperz Community Edition is free software: you can redistribute | ||
11 | it and/or modify it under the terms of the GNU Affero General Public | ||
12 | License as published by the Free Software Foundation, either version | ||
13 | 3 of the License, or (at your option) any later version. | ||
14 | |||
15 | * Clipperz Community Edition is distributed in the hope that it will | ||
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
18 | See the GNU Affero General Public License for more details. | ||
19 | |||
20 | * You should have received a copy of the GNU Affero General Public | ||
21 | License along with Clipperz Community Edition. If not, see | ||
22 | <http://www.gnu.org/licenses/>. | ||
23 | |||
24 | */ | ||
25 | |||
26 | Clipperz.Base.module('Clipperz.PM.UI.Mobile.Components'); | ||
27 | |||
28 | Clipperz.PM.UI.Mobile.Components.LoginForm = function(args) { | ||
29 | args = args || {}; | ||
30 | |||
31 | this._pin = ''; | ||
32 | |||
33 | this._message = null; | ||
34 | this._steps = 0; | ||
35 | this._actualSteps = 0; | ||
36 | |||
37 | this._callback = null; | ||
38 | this._errorCallback = null; | ||
39 | |||
40 | this._mode = 'CREDENTIALS'; | ||
41 | |||
42 | Clipperz.PM.UI.Mobile.Components.LoginForm.superclass.constructor.apply(this, arguments); | ||
43 | |||
44 | return this; | ||
45 | } | ||
46 | |||
47 | //============================================================================= | ||
48 | |||
49 | Clipperz.Base.extend(Clipperz.PM.UI.Mobile.Components.LoginForm, Clipperz.PM.UI.Common.Components.BaseComponent, { | ||
50 | |||
51 | //------------------------------------------------------------------------- | ||
52 | |||
53 | 'toString': function () { | ||
54 | return "Clipperz.PM.UI.Mobile.Components.LoginForm component"; | ||
55 | }, | ||
56 | |||
57 | //------------------------------------------------------------------------- | ||
58 | |||
59 | 'callback': function () { | ||
60 | return this._callback; | ||
61 | }, | ||
62 | |||
63 | 'errorCallback': function () { | ||
64 | return this._errorCallback; | ||
65 | }, | ||
66 | |||
67 | //------------------------------------------------------------------------- | ||
68 | |||
69 | 'mode': function () { | ||
70 | return this._mode; | ||
71 | }, | ||
72 | |||
73 | 'setMode': function (aValue) { | ||
74 | this._mode = aValue; | ||
75 | }, | ||
76 | |||
77 | //.......................................................................... | ||
78 | |||
79 | 'pin': function () { | ||
80 | return this._pin; | ||
81 | }, | ||
82 | |||
83 | 'setPin': function (aValue) { | ||
84 | this._pin = aValue; | ||
85 | }, | ||
86 | |||
87 | //.......................................................................... | ||
88 | |||
89 | 'username': function () { | ||
90 | return this._username; | ||
91 | }, | ||
92 | |||
93 | 'setUsername': function (aValue) { | ||
94 | this._username = aValue; | ||
95 | }, | ||
96 | |||
97 | //.......................................................................... | ||
98 | |||
99 | 'passphrase': function () { | ||
100 | return this._passphrase; | ||
101 | }, | ||
102 | |||
103 | 'setPassphrase': function (aValue) { | ||
104 | this._passphrase = aValue; | ||
105 | }, | ||
106 | |||
107 | //------------------------------------------------------------------------- | ||
108 | |||
109 | 'message': function () { | ||
110 | return this._message; | ||
111 | }, | ||
112 | |||
113 | '_setMessage': function (aValue) { | ||
114 | this._message = aValue; | ||
115 | |||
116 | if (aValue == null) { | ||
117 | MochiKit.Style.hideElement(this.getElement('credentialsMessage')); | ||
118 | } else { | ||
119 | this.getElement('message').innerHTML = aValue; | ||
120 | MochiKit.Style.showElement(this.getElement('credentialsMessage')); | ||
121 | } | ||
122 | }, | ||
123 | |||
124 | 'setMessage': function (aValue) { | ||
125 | this._setMessage(aValue); | ||
126 | MochiKit.DOM.removeElementClass(this.getElement('credentialsMessage'), 'error'); | ||
127 | }, | ||
128 | |||
129 | 'setErrorMessage': function (aValue) { | ||
130 | this._setMessage(aValue); | ||
131 | MochiKit.DOM.addElementClass(this.getElement('credentialsMessage'), 'error'); | ||
132 | }, | ||
133 | |||
134 | //------------------------------------------------------------------------- | ||
135 | |||
136 | 'setCallbacks': function (args) { | ||
137 | this._callback = args['callback']; | ||
138 | this._errorCallback = args['errorCallback']; | ||
139 | }, | ||
140 | |||
141 | 'showErrors': function (args) { | ||
142 | //console.log("LoginForm.showErrors", args); | ||
143 | if (args['previousFailedAttempt'] == 'LOGIN') { | ||
144 | this.setErrorMessage("Wrong credentials"); | ||
145 | } else if (args['previousFailedAttempt'] == 'PIN') { | ||
146 | if (args['failedAttempts'] == -1) { | ||
147 | this.setErrorMessage("Wrong PIN - Resetted"); | ||
148 | } else { | ||
149 | this.setErrorMessage("Wrong PIN"); | ||
150 | } | ||
151 | } else { | ||
152 | this.setMessage(null); | ||
153 | } | ||
154 | }, | ||
155 | |||
156 | 'updateWithArgs': function (args) { | ||
157 | this.renderIfNeeded(); | ||
158 | this.setCallbacks(args); | ||
159 | this.showErrors(args); | ||
160 | this.updateRendering(); | ||
161 | }, | ||
162 | |||
163 | 'showPinLogin': function (args) { | ||
164 | this.setPin(''); | ||
165 | this.setMode('PIN'); | ||
166 | this.updateWithArgs(args); | ||
167 | |||
168 | // $(this.getAnchor('PIN')).focus(); | ||
169 | this.getElement('PIN').focus(); | ||
170 | }, | ||
171 | |||
172 | 'showCredentialsLogin': function (args) { | ||
173 | this.setMode('CREDENTIALS'); | ||
174 | this.updateWithArgs(args); | ||
175 | |||
176 | if (this.getElement('usernameField').value.length == 0) { | ||
177 | // $(this.getAnchor('usernameField')).focus(); | ||
178 | this.getElement('usernameField').focus(); | ||
179 | } else { | ||
180 | // $(this.getAnchor('passphraseField')).focus(); | ||
181 | this.getElement('passphraseField').focus(); | ||
182 | this.getElement('passphraseField').select(); | ||
183 | } | ||
184 | }, | ||
185 | |||
186 | //------------------------------------------------------------------------- | ||
187 | |||
188 | 'renderIfNeeded': function () { | ||
189 | if (this.isFullyRendered() == false) { | ||
190 | this.render(); | ||
191 | }; | ||
192 | this.updateRendering(); | ||
193 | }, | ||
194 | |||
195 | 'updateRendering': function () { | ||
196 | MochiKit.Style.showElement(this.getElement('credentialsBody')); | ||
197 | MochiKit.Style.hideElement(this.getElement('validating')); | ||
198 | |||
199 | // this.hideAllPanes(); | ||
200 | MochiKit.Base.map(function (aNode) { MochiKit.Style.hideElement(aNode); }, MochiKit.Selector.findDocElements('div.credentialsBody > div')); | ||
201 | if (this.mode() == 'CREDENTIALS') { | ||
202 | selectedPanel = this.getElement('credentials') | ||
203 | } else if (this.mode() == 'PIN') { | ||
204 | selectedPanel = this.getElement('pin') | ||
205 | // this.updatePinDisplay(); | ||
206 | } else { | ||
207 | throw 'Unhandled login form mode'; | ||
208 | } | ||
209 | MochiKit.Style.showElement(selectedPanel); | ||
210 | |||
211 | MochiKit.Style.hideElement(this.getElement('validating')); | ||
212 | }, | ||
213 | |||
214 | 'renderSelf': function() { | ||
215 | var selectedPanel; | ||
216 | this.append(this.element(), {tag:'div', id:'login', children:[ | ||
217 | {tag:'div', cls:'toolbar', children:[ | ||
218 | {tag:'h1', html:"clipperz"} | ||
219 | ]}, | ||
220 | {tag:'div', cls:'scroll', children:[ | ||
221 | //================================================================== | ||
222 | {tag:'div', cls:'credentialsMessage', id:this.getId('credentialsMessage'), children:[ | ||
223 | {tag:'h1', cls:'message', id:this.getId('message'), html:"Message"} | ||
224 | ]}, | ||
225 | //================================================================== | ||
226 | {tag:'div', cls:'credentialsBody', id:this.getId('credentialsBody'), children:[ | ||
227 | //-------------------------------------------------------------- | ||
228 | {tag:'div', cls:'pin', id:this.getId('pin'), children:[ | ||
229 | {tag:'form', cls:'scroll', id:this.getId('pinForm'), children:[ | ||
230 | {tag:'ul', cls:'edit rounded', children:[ | ||
231 | {tag:'li', children:[{tag:'input', type:'number', name:'PIN', placeholder:"PIN", id:this.getId('PIN') }]}, | ||
232 | ]}, | ||
233 | {tag:'a', href:'#', cls:'greenButton', id:this.getId('pinSubmitButton'), html:"Login"} | ||
234 | ]} | ||
235 | ]}, | ||
236 | //-------------------------------------------------------------- | ||
237 | {tag:'div', cls:'credentials', id:this.getId('credentials'), children:[ | ||
238 | {tag:'form', cls:'scroll', id:this.getId('credentialsForm'), children:[ | ||
239 | {tag:'ul', cls:'edit rounded', children:[ | ||
240 | {tag:'li', children:[{tag:'input', type:'email', name:'name', /*value:'joe',*/ placeholder:"username", id:this.getId('usernameField') }]}, | ||
241 | {tag:'li', children:[{tag:'input', type:'password', name:'passphrase', /*value:'clipperz',*/placeholder:"passphrase", id:this.getId('passphraseField') }]} | ||
242 | ]}, | ||
243 | {tag:'a', href:'#', cls:'greenButton', id:this.getId('credentialsSubmitButton'), html:"Login"} | ||
244 | // {tag:'input', type:'submit', cls:'greenButton', id:this.getId('credentialsSubmitButton'), value:"Login"} | ||
245 | |||
246 | ]} | ||
247 | ]}, | ||
248 | //-------------------------------------------------------------- | ||
249 | ]}, | ||
250 | //================================================================== | ||
251 | {tag:'div', cls:'validating', id:this.getId('validating'), children:[ | ||
252 | {tag:'div', cls:'loading', children:[ | ||
253 | {tag:'div', cls:'spinner', children:[ | ||
254 | {tag:'div', cls:'bar01'}, | ||
255 | {tag:'div', cls:'bar02'}, | ||
256 | {tag:'div', cls:'bar03'}, | ||
257 | {tag:'div', cls:'bar04'}, | ||
258 | {tag:'div', cls:'bar05'}, | ||
259 | {tag:'div', cls:'bar06'}, | ||
260 | {tag:'div', cls:'bar07'}, | ||
261 | {tag:'div', cls:'bar08'}, | ||
262 | {tag:'div', cls:'bar09'}, | ||
263 | {tag:'div', cls:'bar10'}, | ||
264 | {tag:'div', cls:'bar11'}, | ||
265 | {tag:'div', cls:'bar12'} | ||
266 | ]} | ||
267 | ]}, | ||
268 | {tag:'div', id:this.getId('loadingMessage')}, | ||
269 | {tag:'a', href:'#', cls:'grayButton', id:this.getId('loginCancelButton'), html:"Cancel"} | ||
270 | ]} | ||
271 | //================================================================== | ||
272 | ]} | ||
273 | ]}); | ||
274 | |||
275 | MochiKit.Signal.connect(this.getElement('credentialsForm'), 'onsubmit', this, 'submitCredentialsHandler'); | ||
276 | MochiKit.Signal.connect(this.getElement('credentialsSubmitButton'), 'onclick', this, 'submitCredentialsHandler'); | ||
277 | |||
278 | MochiKit.Signal.connect(this.getElement('pinForm'), 'onsubmit', this, 'submitPinHandler'); | ||
279 | MochiKit.Signal.connect(this.getElement('pinSubmitButton'), 'onclick', this, 'submitPinHandler'); | ||
280 | |||
281 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'initProgress', this, 'initProgressHandle'); | ||
282 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'updateProgress',this, 'updateProgressHandle'); | ||
283 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'advanceProgress',this, 'advanceProgressHandle'); | ||
284 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'progressDone', this, 'progressDoneHandle'); | ||
285 | }, | ||
286 | |||
287 | //------------------------------------------------------------------------- | ||
288 | |||
289 | 'submitPinHandler': function (anEvent) { | ||
290 | varpin; | ||
291 | |||
292 | this.setMessage(null); | ||
293 | pin = this.getElement('PIN').value; | ||
294 | // $(this.getAnchor('PIN')).blur(); | ||
295 | this.getElement('PIN').blur(); | ||
296 | |||
297 | credentials = Clipperz.PM.PIN.credentialsWithPIN(pin); | ||
298 | this.loginWithCredentials(credentials); | ||
299 | }, | ||
300 | |||
301 | 'submitCredentialsHandler': function (anEvent) { | ||
302 | //console.log("submitCredentialsHandler"); | ||
303 | varcredentials; | ||
304 | |||
305 | this.setMessage(null); | ||
306 | |||
307 | credentials = {}; | ||
308 | credentials['username'] = this.getElement('usernameField').value; | ||
309 | credentials['passphrase'] = this.getElement('passphraseField').value; | ||
310 | // $(this.getAnchor('passphraseField')).blur(); | ||
311 | this.getElement('passphraseField').blur(); | ||
312 | |||
313 | this.loginWithCredentials(credentials); | ||
314 | }, | ||
315 | |||
316 | //------------------------------------------------------------------------- | ||
317 | |||
318 | 'loginWithCredentials': function (someCredentials) { | ||
319 | varargs; | ||
320 | |||
321 | args = {}; | ||
322 | args['credentials'] = someCredentials; | ||
323 | args['errorCallback'] = this.errorCallback(); | ||
324 | |||
325 | MochiKit.Style.hideElement(this.getElement('credentialsBody')); | ||
326 | MochiKit.Style.showElement(this.getElement('validating')); | ||
327 | |||
328 | MochiKit.Async.callLater(0.1, this.callback(), args); | ||
329 | }, | ||
330 | |||
331 | //------------------------------------------------------------------------- | ||
332 | |||
333 | 'initProgressHandle': function (anEvent) { | ||
334 | //console.log("** initProgressHandle", anEvent); | ||
335 | this._steps = anEvent['steps']; | ||
336 | this._actualSteps = 0; | ||
337 | }, | ||
338 | |||
339 | 'updateProgressHandle': function (anEvent) { | ||
340 | //console.log("** updateProgressHandle", anEvent); | ||
341 | this._steps += anEvent['extraSteps']; | ||
342 | }, | ||
343 | |||
344 | 'advanceProgressHandle': function (anEvent) { | ||
345 | //console.log("** advanceProgressHandle", anEvent); | ||
346 | this._actualSteps ++; | ||
347 | //console.log("STEPS: " + this._actualSteps + "/" + this._steps); | ||
348 | }, | ||
349 | |||
350 | 'progressDoneHandle': function (anEvent) { | ||
351 | //console.log("** progressDoneHandle", anEvent); | ||
352 | }, | ||
353 | |||
354 | //------------------------------------------------------------------------- | ||
355 | __syntaxFix__: "syntax fix" | ||
356 | }); | ||
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Mobile/Controllers/MainController.js b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Controllers/MainController.js new file mode 100644 index 0000000..12a61f7 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Mobile/Controllers/MainController.js | |||
@@ -0,0 +1,393 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz Community Edition. | ||
6 | Clipperz Community Edition is an online password manager. | ||
7 | For further information about its features and functionalities please | ||
8 | refer to http://www.clipperz.com. | ||
9 | |||
10 | * Clipperz Community Edition is free software: you can redistribute | ||
11 | it and/or modify it under the terms of the GNU Affero General Public | ||
12 | License as published by the Free Software Foundation, either version | ||
13 | 3 of the License, or (at your option) any later version. | ||
14 | |||
15 | * Clipperz Community Edition is distributed in the hope that it will | ||
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
18 | See the GNU Affero General Public License for more details. | ||
19 | |||
20 | * You should have received a copy of the GNU Affero General Public | ||
21 | License along with Clipperz Community Edition. If not, see | ||
22 | <http://www.gnu.org/licenses/>. | ||
23 | |||
24 | */ | ||
25 | |||
26 | Clipperz.Base.module('Clipperz.PM.UI.Mobile.Controllers'); | ||
27 | |||
28 | Clipperz.PM.UI.Mobile.Controllers.MainController = function() { | ||
29 | this._jQTouch = null; | ||
30 | this._user = null; | ||
31 | this._proxy = null; | ||
32 | this._loginForm = null; | ||
33 | this._cardList = null; | ||
34 | this._cardDetail= null; | ||
35 | |||
36 | return this; | ||
37 | } | ||
38 | |||
39 | MochiKit.Base.update(Clipperz.PM.UI.Mobile.Controllers.MainController.prototype, { | ||
40 | |||
41 | 'toString': function () { | ||
42 | return "Clipperz.PM.UI.Mobile.Controllers.MainController"; | ||
43 | }, | ||
44 | |||
45 | //------------------------------------------------------------------------- | ||
46 | |||
47 | 'user': function () { | ||
48 | return this._user; | ||
49 | }, | ||
50 | |||
51 | 'setUser': function (aValue) { | ||
52 | this._user = aValue; | ||
53 | }, | ||
54 | |||
55 | //------------------------------------------------------------------------- | ||
56 | |||
57 | 'jQTouch': function () { | ||
58 | return this._jQTouch; | ||
59 | }, | ||
60 | |||
61 | 'setJQTouch': function (aValue) { | ||
62 | this._jQTouch = aValue; | ||
63 | }, | ||
64 | |||
65 | //========================================================================= | ||
66 | |||
67 | 'run': function () { | ||
68 | console.log("MainController.run"); | ||
69 | |||
70 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'doLogin', MochiKit.Base.method(this, 'doLogin')); | ||
71 | Clipperz.DOM.Helper.overwrite(MochiKit.DOM.currentDocument().body, {tag:'div', id:'jqt', children:[ | ||
72 | {tag:'div', id:'loginForm'}, | ||
73 | {tag:'div', id:'cardList'}, | ||
74 | {tag:'div', id:'cardDetail'}, | ||
75 | {tag:'div', id:'preferences'} | ||
76 | ]}); | ||
77 | |||
78 | this.showLoginForm(); | ||
79 | |||
80 | this.initjQTouch(); | ||
81 | |||
82 | |||
83 | // this.showAddToHomeScreenBaloon(); | ||
84 | // this.selectInitialProxy(); | ||
85 | }, | ||
86 | |||
87 | 'initjQTouch': function () { | ||
88 | var jqt; | ||
89 | |||
90 | jqt = new $.jQTouch({ | ||
91 | icon: 'data:image/png;charset=utf-8;base64,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', | ||
92 | // icon4: 'jqtouch4.png', | ||
93 | // startupScreen: null, //Pass a string path to a 320px x 460px startup screen for full screen apps. | ||
94 | statusBar: 'black-translucent', //Styles the status bar when running as a fullscreen app. Other options are `default`, `black`, and `black-translucent`. | ||
95 | // addGlossToIcon: true, //Set to 'false' to prevent automatic glossy button effect on icon. | ||
96 | preloadImages: false, //Pass an array of image paths to load them before page loads. Ex: `['images/link_over.png', 'images/link_select.png']` | ||
97 | fixedViewport: true, //Removes the user's ability to scale the page. Ensures the site behaves more like an application. | ||
98 | // fullScreen: true, //The website will become a fullscreen application when saved to a user's home screen. Set to `false` to disable. | ||
99 | // fullScreenClass: 'fullscreen' //Adds a class to the `<body>` when running in full-screen mode, to allow for easy detection and styling. Set to `false` to disable. | ||
100 | // themeSelectionSelector: '#jqt #themes ul', //??? | ||
101 | |||
102 | // useAnimations: true, //Set to `false` to disable all animations. | ||
103 | // useFastTouch: true, //Removes ~350ms onClick delay when tapping a link (use in conjunction with the .tap() event) **Experimental** | ||
104 | // useTouchScroll: true, //Adds support for iOS5 scrolling. Set to false to disable. **Experimental** | ||
105 | |||
106 | cacheGetRequests: false, //Automatically caches GET requests, so subsequent taps reference the pre-loaded views. (default: true) | ||
107 | |||
108 | // backSelector: '.back, .cancel, .goback', //A CSS selector for back links/buttons. When clicked, the page history goes back one, automatically reversing whichever entrance animation was used. | ||
109 | |||
110 | // cubeSelector: '.cube', //Link selector for a cube animation. | ||
111 | // dissolveSelector: '.dissolve', //Link selector for a dissolve animation. | ||
112 | // fadeSelector: '.fade', //Link selector for a fade animation. | ||
113 | // flipSelector: '.flip', //Link selector for a 3d flip animation. | ||
114 | formSelector: null, //Sets which forms are automatically submitted via Ajax. (default: 'form') | ||
115 | // popSelector: '.pop', //Link selector for a pop animation. (default: '.pop') | ||
116 | // slideSelector: 'body > * > ul li a', //Link selector for the default slide-left transition. By default applies to all links within an unordered list. Accepts any jQuery-capable selector `'li > a, a:not(.dontslide)'`, etc. (default: 'body > * > ul li a') | ||
117 | // slideupSelector: '.slideup', //Link selector for a slide up animation. (default: '.slideup') | ||
118 | // submitSelector: '.submit', //Selector which, when clicked, will submit its parent form (and close keyboard if open). (default: '.submit') | ||
119 | // swapSelector: '.swap', //Link selector for 3d swap animation. (default: '.swap') | ||
120 | // touchSelector: 'a, .touch', //Selector for items which are automatically given expanded touch events. This makes ordinary links more responsive and provides trigger events like `swipe` (default: 'a, .touch') | ||
121 | |||
122 | debug: false | ||
123 | }); | ||
124 | |||
125 | this.setJQTouch(jqt); | ||
126 | }, | ||
127 | |||
128 | //========================================================================= | ||
129 | |||
130 | 'showAddToHomeScreenBaloon': function () { | ||
131 | console.log(">>> showAddToHomeScreenBaloon"); | ||
132 | }, | ||
133 | |||
134 | //------------------------------------------------------------------------- | ||
135 | |||
136 | 'selectInitialProxy': function () { | ||
137 | //console.log(">>> selectInitialProxy"); | ||
138 | if (this.isOnline()) { | ||
139 | //console.log("--- selectInitialProxy: using default proxy"); | ||
140 | this._proxy = Clipperz.PM.Proxy.defaultProxy; | ||
141 | } else { | ||
142 | if (this.hasLocalData()) { | ||
143 | //console.log("--- selectInitialProxy: using local cache proxy"); | ||
144 | this._proxy = new Clipperz.PM.Proxy.OfflineCache({'shouldPayTolls':false}); | ||
145 | } else { | ||
146 | this.showOfflineError(); | ||
147 | } | ||
148 | } | ||
149 | }, | ||
150 | |||
151 | //------------------------------------------------------------------------- | ||
152 | |||
153 | 'showLoginForm': function (args) { | ||
154 | args = args || {}; | ||
155 | |||
156 | args['callback'] = MochiKit.Base.method(this, 'doLogin'); | ||
157 | |||
158 | if (Clipperz.PM.PIN.isSet()) { | ||
159 | args['errorCallback'] = MochiKit.Base.method(this, 'handleFailedPinLogin'); | ||
160 | this.loginForm().showPinLogin(args); | ||
161 | } else { | ||
162 | args['errorCallback'] = MochiKit.Base.method(this, 'handleFailedCredentialsLogin'); | ||
163 | this.loginForm().showCredentialsLogin(args); | ||
164 | } | ||
165 | }, | ||
166 | |||
167 | //......................................................................... | ||
168 | |||
169 | 'handleFailedCredentialsLogin': function () { | ||
170 | console.log("LOGIN FAILED"); | ||
171 | this.showLoginForm({'previousFailedAttempt':'LOGIN'}); | ||
172 | }, | ||
173 | |||
174 | //......................................................................... | ||
175 | |||
176 | 'handleFailedPinLogin': function () { | ||
177 | varfailedAttempts; | ||
178 | varstatus; | ||
179 | |||
180 | failedAttempts = Clipperz.PM.PIN.recordFailedAttempt(); | ||
181 | this.showLoginForm({'previousFailedAttempt':'PIN', 'failedAttempts': failedAttempts}); | ||
182 | }, | ||
183 | |||
184 | //------------------------------------------------------------------------- | ||
185 | |||
186 | 'doLogin': function (someArgs) { | ||
187 | var deferredResult; | ||
188 | var credentials; | ||
189 | var errorCallback; | ||
190 | var user; | ||
191 | var getPassphraseDelegate; | ||
192 | |||
193 | //console.log(">>> MainController.doLogin", someArgs); | ||
194 | credentials = someArgs['credentials']; | ||
195 | errorCallback = someArgs['errorCallback'] || MochiKit.Base.noop; | ||
196 | |||
197 | getPassphraseDelegate = MochiKit.Base.partial(MochiKit.Async.succeed, credentials.passphrase); | ||
198 | user = new Clipperz.PM.DataModel.User({'username':credentials.username, 'getPassphraseFunction':getPassphraseDelegate}); | ||
199 | |||
200 | deferredResult = new Clipperz.Async.Deferred('MainController.doLogin', {trace:false}); | ||
201 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':4}); | ||
202 | deferredResult.addCallback(MochiKit.Async.wait, 0.1); | ||
203 | deferredResult.addMethod(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'deferredEntropyCollection'); | ||
204 | deferredResult.addMethod(user, 'login'); | ||
205 | deferredResult.addCallbacks( | ||
206 | MochiKit.Base.method(this, 'processSuccessfulLogin', user), | ||
207 | errorCallback | ||
208 | ); | ||
209 | deferredResult.callback(); | ||
210 | |||
211 | return deferredResult; | ||
212 | }, | ||
213 | |||
214 | //.......................................................................... | ||
215 | |||
216 | 'processSuccessfulLogin': function (aUser) { | ||
217 | var deferredResult; | ||
218 | |||
219 | deferredResult = new Clipperz.Async.Deferred('MainController.processSuccessfulLogin', {trace:false}); | ||
220 | deferredResult.addMethod(Clipperz.PM.PIN, 'resetFailedAttemptCount'); | ||
221 | // deferredResult.addMethod(this, 'removeLoginForm'); | ||
222 | deferredResult.addMethod(this, 'setUser', aUser); | ||
223 | deferredResult.addMethod(this, 'setupApplication'); | ||
224 | deferredResult.addMethod(this, 'runApplication'); | ||
225 | deferredResult.callback(); | ||
226 | |||
227 | return deferredResult; | ||
228 | }, | ||
229 | |||
230 | //------------------------------------------------------------------------- | ||
231 | |||
232 | 'setupApplication': function () { | ||
233 | vardeferredResult; | ||
234 | |||
235 | console.log(">>> setupApplication"); | ||
236 | deferredResult = new Clipperz.Async.Deferred("MainController.setupApplication", {trace:false}); | ||
237 | deferredResult.addMethod(this, 'welcomeFirstTimeUser'); | ||
238 | deferredResult.addMethod(this, 'showPaymentReminder'); | ||
239 | deferredResult.addMethod(this, 'copyDataLocally'); | ||
240 | deferredResult.callback(arguments); | ||
241 | |||
242 | return deferredResult; | ||
243 | }, | ||
244 | |||
245 | |||
246 | //.......................................................................... | ||
247 | |||
248 | 'isFirstTimeUser': function () { | ||
249 | return false; | ||
250 | }, | ||
251 | |||
252 | 'welcomeFirstTimeUser': function () { | ||
253 | vardeferredResult; | ||
254 | |||
255 | deferredResult = new Clipperz.Async.Deferred('MainController.welcomeFirstTimeUser', {trace:false}); | ||
256 | |||
257 | if (this.isFirstTimeUser()) { | ||
258 | deferredResult.addCallback(function () { console.log("--> welcome"); }); | ||
259 | } | ||
260 | deferredResult.callback(); | ||
261 | |||
262 | return deferredResult; | ||
263 | }, | ||
264 | |||
265 | //.......................................................................... | ||
266 | |||
267 | 'shouldShowPaymentReminder': function () { | ||
268 | return true; | ||
269 | }, | ||
270 | |||
271 | 'showPaymentReminder': function () { | ||
272 | vardeferredResult; | ||
273 | |||
274 | deferredResult = new Clipperz.Async.Deferred('MainController.showPaymentReminder', {trace:false}); | ||
275 | |||
276 | if (this.shouldShowPaymentReminder()) { | ||
277 | deferredResult.addCallback(function () { console.log("--> payment reminder"); }); | ||
278 | } | ||
279 | deferredResult.callback(); | ||
280 | |||
281 | return deferredResult; | ||
282 | }, | ||
283 | |||
284 | //.......................................................................... | ||
285 | |||
286 | 'canCopyDataLocally': function () { | ||
287 | return false; | ||
288 | }, | ||
289 | |||
290 | 'copyDataLocally': function () { | ||
291 | vardeferredResult; | ||
292 | |||
293 | deferredResult = new Clipperz.Async.Deferred('MainController.copyDataLocally', {trace:false}); | ||
294 | |||
295 | if (this.canCopyDataLocally()) { | ||
296 | deferredResult.addCallback(function () { console.log("--> copy data locally"); }); | ||
297 | } | ||
298 | deferredResult.callback(); | ||
299 | |||
300 | return deferredResult; | ||
301 | |||
302 | }, | ||
303 | |||
304 | //------------------------------------------------------------------------- | ||
305 | |||
306 | 'runApplication': function () { | ||
307 | var deferredResult; | ||
308 | |||
309 | //console.log(">>> runApplication"); | ||
310 | deferredResult = new Clipperz.Async.Deferred('MainController.runApplication', {trace:true}); | ||
311 | deferredResult.addMethod(this.user(), 'getRecords'); | ||
312 | deferredResult.addMethod(this, 'showCards'); | ||
313 | deferredResult.callback(); | ||
314 | |||
315 | return deferredResult; | ||
316 | }, | ||
317 | |||
318 | //========================================================================= | ||
319 | |||
320 | 'showOfflineError': function (anException) { | ||
321 | alert("Error: " + anException); | ||
322 | throw anException; | ||
323 | }, | ||
324 | |||
325 | //========================================================================= | ||
326 | |||
327 | 'isOnline': function() { | ||
328 | return navigator.onLine; | ||
329 | }, | ||
330 | |||
331 | 'hasLocalData': function() { | ||
332 | return false; | ||
333 | }, | ||
334 | |||
335 | //========================================================================= | ||
336 | |||
337 | 'loginForm': function() { | ||
338 | if (this._loginForm == null) { | ||
339 | this._loginForm = new Clipperz.PM.UI.Mobile.Components.LoginForm({element:MochiKit.DOM.getElement('loginForm')}); | ||
340 | } | ||
341 | |||
342 | return this._loginForm; | ||
343 | }, | ||
344 | |||
345 | 'removeLoginForm': function () { | ||
346 | if (this._loginForm != null) { | ||
347 | this._loginForm.remove(); | ||
348 | this._loginForm = null; | ||
349 | } | ||
350 | }, | ||
351 | |||
352 | //------------------------------------------------------------------------- | ||
353 | |||
354 | 'cardList': function () { | ||
355 | if (this._cardList == null) { | ||
356 | this._cardList = new Clipperz.PM.UI.Mobile.Components.CardList({element:MochiKit.DOM.getElement('cardList')}); | ||
357 | MochiKit.Signal.connect(this._cardList, 'selectedCard', this, 'selectCardHandler'); | ||
358 | } | ||
359 | |||
360 | return this._cardList; | ||
361 | }, | ||
362 | |||
363 | 'showCards': function (someCards) { | ||
364 | this.cardList().showCards(someCards); | ||
365 | this.jQTouch().goTo('#cardList', 'slideleft'); | ||
366 | }, | ||
367 | |||
368 | //------------------------------------------------------------------------- | ||
369 | |||
370 | 'cardDetail': function () { | ||
371 | if (this._cardDetail == null) { | ||
372 | this._cardDetail = new Clipperz.PM.UI.Mobile.Components.CardDetail({element:MochiKit.DOM.getElement('cardDetail')}); | ||
373 | } | ||
374 | |||
375 | return this._cardDetail; | ||
376 | }, | ||
377 | |||
378 | 'selectCardHandler': function (aCardReference) { | ||
379 | var deferredResult; | ||
380 | |||
381 | deferredResult = new Clipperz.Async.Deferred("MainController.selectCardHandler", {trace:true}); | ||
382 | deferredResult.addMethod(this.cardDetail(), 'render'); | ||
383 | deferredResult.addMethod(this.jQTouch(), 'goTo', '#cardDetail', 'slideleft'); | ||
384 | deferredResult.addMethod(this.user(), 'getRecord', aCardReference); | ||
385 | deferredResult.addMethod(this.cardDetail(), 'showCard'); | ||
386 | deferredResult.callback(); | ||
387 | |||
388 | return deferredResult; | ||
389 | }, | ||
390 | |||
391 | //========================================================================= | ||
392 | __syntaxFix__: "syntax fix" | ||
393 | }); | ||
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js index ee6d7a3..d6b0574 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js | |||
@@ -1,145 +1,150 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2011 Clipperz Srl | 3 | Copyright 2008-2011 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz Community Edition. | 5 | This file is part of Clipperz Community Edition. |
6 | Clipperz Community Edition is an online password manager. | 6 | Clipperz Community Edition is an online password manager. |
7 | For further information about its features and functionalities please | 7 | For further information about its features and functionalities please |
8 | refer to http://www.clipperz.com. | 8 | refer to http://www.clipperz.com. |
9 | 9 | ||
10 | * Clipperz Community Edition is free software: you can redistribute | 10 | * Clipperz Community Edition is free software: you can redistribute |
11 | it and/or modify it under the terms of the GNU Affero General Public | 11 | it and/or modify it under the terms of the GNU Affero General Public |
12 | License as published by the Free Software Foundation, either version | 12 | License as published by the Free Software Foundation, either version |
13 | 3 of the License, or (at your option) any later version. | 13 | 3 of the License, or (at your option) any later version. |
14 | 14 | ||
15 | * Clipperz Community Edition is distributed in the hope that it will | 15 | * Clipperz Community Edition is distributed in the hope that it will |
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | 16 | be useful, but WITHOUT ANY WARRANTY; without even the implied |
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. | 18 | See the GNU Affero General Public License for more details. |
19 | 19 | ||
20 | * You should have received a copy of the GNU Affero General Public | 20 | * You should have received a copy of the GNU Affero General Public |
21 | License along with Clipperz Community Edition. If not, see | 21 | License along with Clipperz Community Edition. If not, see |
22 | <http://www.gnu.org/licenses/>. | 22 | <http://www.gnu.org/licenses/>. |
23 | 23 | ||
24 | */ | 24 | */ |
25 | 25 | ||
26 | Clipperz.Base.module('Clipperz.PM.UI.Web.Components'); | 26 | Clipperz.Base.module('Clipperz.PM.UI.Web.Components'); |
27 | 27 | ||
28 | Clipperz.PM.UI.Web.Components.AccountPanel = function(args) { | 28 | Clipperz.PM.UI.Web.Components.AccountPanel = function(args) { |
29 | args = args || {}; | 29 | args = args || {}; |
30 | 30 | ||
31 | Clipperz.PM.UI.Web.Components.AccountPanel.superclass.constructor.apply(this, arguments); | 31 | Clipperz.PM.UI.Web.Components.AccountPanel.superclass.constructor.apply(this, arguments); |
32 | 32 | ||
33 | //this._initiallySelectedTab = args.selected || 'ACCOUNT'; | 33 | //this._initiallySelectedTab = args.selected || 'ACCOUNT'; |
34 | this._initiallySelectedTab = args.selected || 'PASSPHRASE'; | 34 | this._initiallySelectedTab = args.selected || 'PASSPHRASE'; |
35 | this._tabPanelControllerConfiguration = { | 35 | this._tabPanelControllerConfiguration = { |
36 | // 'ACCOUNT': { | 36 | // 'ACCOUNT': { |
37 | // tab:'accountTab', | 37 | // tab:'accountTab', |
38 | // panel:'accountPanel' | 38 | // panel:'accountPanel' |
39 | // }, | 39 | // }, |
40 | 'PASSPHRASE': { | 40 | 'PASSPHRASE': { |
41 | tab:'passphraseTab', | 41 | tab:'passphraseTab', |
42 | panel:'passphrasePanel' | 42 | panel:'passphrasePanel' |
43 | }, | 43 | }, |
44 | 'OTP': { | ||
45 | tab:'OTPTab', | ||
46 | panel:'OTPPanel' | ||
47 | }, | ||
44 | 'PREFERENCES': { | 48 | 'PREFERENCES': { |
45 | tab:'preferencesTab', | 49 | tab:'preferencesTab', |
46 | panel:'preferencesPanel' | 50 | panel:'preferencesPanel' |
47 | }, | 51 | }, |
48 | 'LOGIN_HISTORY': { | 52 | 'LOGIN_HISTORY': { |
49 | tab:'loginHistoryTab', | 53 | tab:'loginHistoryTab', |
50 | panel:'loginHistoryPanel' | 54 | panel:'loginHistoryPanel' |
51 | } | 55 | } |
52 | }; | 56 | }; |
53 | 57 | ||
54 | return this; | 58 | return this; |
55 | } | 59 | } |
56 | 60 | ||
57 | //============================================================================= | 61 | //============================================================================= |
58 | 62 | ||
59 | Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.AccountPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { | 63 | Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.AccountPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { |
60 | 64 | ||
61 | //------------------------------------------------------------------------- | 65 | //------------------------------------------------------------------------- |
62 | 66 | ||
63 | 'toString': function () { | 67 | 'toString': function () { |
64 | return "Clipperz.PM.UI.Web.Components.AccountPanel component"; | 68 | return "Clipperz.PM.UI.Web.Components.AccountPanel component"; |
65 | }, | 69 | }, |
66 | 70 | ||
67 | //------------------------------------------------------------------------- | 71 | //------------------------------------------------------------------------- |
68 | 72 | ||
69 | 'renderSelf': function(/*aContainer, aPosition*/) { | 73 | 'renderSelf': function(/*aContainer, aPosition*/) { |
70 | //Clipperz.log("AccountPanel.renderSelf element", this.element()); | 74 | //Clipperz.log("AccountPanel.renderSelf element", this.element()); |
71 | this.append(this.element(), [ | 75 | this.append(this.element(), [ |
72 | {tag:'div', cls:'header', children:[ | 76 | {tag:'div', cls:'header', children:[ |
73 | {tag:'div', cls:'subPanelTabs', children:[ | 77 | {tag:'div', cls:'subPanelTabs', children:[ |
74 | {tag:'ul', children:[ | 78 | {tag:'ul', children:[ |
75 | // {tag:'li', id:this.getId('accountTab'), children:[{tag:'a', href:'#', html:'Account'}], cls:'first'}, | 79 | // {tag:'li', id:this.getId('accountTab'), children:[{tag:'a', href:'#', html:'Account'}], cls:'first'}, |
76 | {tag:'li', id:this.getId('passphraseTab'), children:[{tag:'a', href:'#', html:'Passphrase'}], cls:'first'}, | 80 | {tag:'li', id:this.getId('passphraseTab'), children:[{tag:'a', href:'#', html:'Passphrase'}], cls:'first'}, |
81 | {tag:'li', id:this.getId('OTPTab'), children:[{tag:'a', href:'#', html:'One Time Passwords'}]}, | ||
77 | {tag:'li', id:this.getId('preferencesTab'), children:[{tag:'a', href:'#', html:'Preferences'}]}, | 82 | {tag:'li', id:this.getId('preferencesTab'), children:[{tag:'a', href:'#', html:'Preferences'}]}, |
78 | {tag:'li', id:this.getId('loginHistoryTab'),children:[{tag:'a', href:'#', html:'Login history'}]} | 83 | {tag:'li', id:this.getId('loginHistoryTab'),children:[{tag:'a', href:'#', html:'Login history'}]} |
79 | ]} | 84 | ]} |
80 | ]} | 85 | ]} |
81 | ]}, | 86 | ]}, |
82 | {tag:'div', cls:'body', children:[ | 87 | {tag:'div', cls:'body', children:[ |
83 | {tag:'div', cls:'accountPanel', children:[ | 88 | {tag:'div', cls:'accountPanel', children:[ |
84 | {tag:'div', cls:'subPanelContent', children:[ | 89 | {tag:'div', cls:'subPanelContent', children:[ |
85 | {tag:'ul', children:[ | 90 | {tag:'ul', children:[ |
86 | // {tag:'li', id:this.getId('accountPanel'),children:[ | 91 | // {tag:'li', id:this.getId('accountPanel'),children:[ |
87 | // {tag:'h3', html:"-- Account --"} | 92 | // {tag:'h3', html:"-- Account --"} |
88 | // ]}, | 93 | // ]}, |
89 | {tag:'li', id:this.getId('passphrasePanel'),children:[ | 94 | {tag:'li', id:this.getId('passphrasePanel'),children:[ |
90 | {tag:'h3', cls:'changePassphrase', html:"Change passphrase"}, | 95 | {tag:'h3', cls:'changePassphrase', html:"Change passphrase"}, |
91 | {tag:'form', id:this.getId('changePassphrase'), cls:'changePassphrase', children:[ | 96 | {tag:'form', id:this.getId('changePassphrase'), cls:'changePassphrase', children:[ |
92 | {tag:'div', cls:'currentCredentials', children:[ | 97 | {tag:'div', cls:'currentCredentials', children:[ |
93 | {tag:'div', cls:'field username', children:[ | 98 | {tag:'div', cls:'field username', children:[ |
94 | {tag:'label', html:"username", 'for':this.getId('currentUsername')}, | 99 | {tag:'label', html:"username", 'for':this.getId('currentUsername')}, |
95 | {tag:'input', id:this.getId('currentUsername')} | 100 | {tag:'input', id:this.getId('currentUsername')} |
96 | ]}, | 101 | ]}, |
97 | {tag:'div', cls:'field passphrase', children:[ | 102 | {tag:'div', cls:'field passphrase', children:[ |
98 | {tag:'label', html:"passphrase", 'for':this.getId('currentPassphrase')}, | 103 | {tag:'label', html:"passphrase", 'for':this.getId('currentPassphrase')}, |
99 | {tag:'input', id:this.getId('currentPassphrase')} | 104 | {tag:'input', id:this.getId('currentPassphrase')} |
100 | ]} | 105 | ]} |
101 | ]}, | 106 | ]}, |
102 | {tag:'div', cls:'newPassphrase', children:[ | 107 | {tag:'div', cls:'newPassphrase', children:[ |
103 | {tag:'div', cls:'field', children:[ | 108 | {tag:'div', cls:'field', children:[ |
104 | {tag:'label', html:"new passphrase", 'for':this.getId('newPassphrase')}, | 109 | {tag:'label', html:"new passphrase", 'for':this.getId('newPassphrase')}, |
105 | {tag:'input', id:this.getId('newPassphrase')} | 110 | {tag:'input', id:this.getId('newPassphrase')} |
106 | ]}, | 111 | ]}, |
107 | {tag:'div', cls:'field', children:[ | 112 | {tag:'div', cls:'field', children:[ |
108 | {tag:'label', html:"re-new passphrase", 'for':this.getId('reNewPassphrase')}, | 113 | {tag:'label', html:"re-new passphrase", 'for':this.getId('reNewPassphrase')}, |
109 | {tag:'input', id:this.getId('reNewPassphrase')} | 114 | {tag:'input', id:this.getId('reNewPassphrase')} |
110 | ]} | 115 | ]} |
111 | ]}, | 116 | ]}, |
112 | {tag:'div', cls:'confirm', children:[ | 117 | {tag:'div', cls:'confirm', children:[ |
113 | {tag:'input', type:'checkbox', id:this.getId('confirm')}, | 118 | {tag:'input', type:'checkbox', id:this.getId('confirm')}, |
114 | {tag:'label', html:"I understand that Clipperz will not be able to recover a lost passphrase", 'for':this.getId('confirm')} | 119 | {tag:'label', html:"I understand that Clipperz will not be able to recover a lost passphrase", 'for':this.getId('confirm')} |
115 | ]} | 120 | ]} |
116 | ]}, | 121 | ]}, |
117 | {tag:'div', cls:'clear'}, | 122 | {tag:'div', cls:'clear'}, |
118 | {tag:'div', cls:'confirmButton', id:this.getId('confirmationButton'), children:[ | 123 | {tag:'div', cls:'confirmButton', id:this.getId('confirmationButton'), children:[ |
119 | {tag:'span', html:"change passphrase"} | 124 | {tag:'span', html:"change passphrase"} |
125 | ]} | ||
120 | ]}, | 126 | ]}, |
121 | 127 | {tag:'li', id:this.getId('OTPPanel'), children:[ | |
122 | {tag:'h3', cls:'manageOTP', html:"Manage One-Time Passphrases"}, | 128 | // {tag:'h3', html:"Manage One-Time Passphrases"} |
123 | {} | ||
124 | ]}, | 129 | ]}, |
125 | {tag:'li', id:this.getId('preferencesPanel'), children:[ | 130 | {tag:'li', id:this.getId('preferencesPanel'), children:[ |
126 | {tag:'h3', html:"-- Preferences --"} | 131 | // {tag:'h3', html:"-- Preferences --"} |
127 | ]}, | 132 | ]}, |
128 | {tag:'li', id:this.getId('loginHistoryPanel'), children:[ | 133 | {tag:'li', id:this.getId('loginHistoryPanel'), children:[ |
129 | {tag:'h3', html:"-- Login History --"} | 134 | // {tag:'h3', html:"-- Login History --"} |
130 | ]} | 135 | ]} |
131 | ]} | 136 | ]} |
132 | ]} | 137 | ]} |
133 | ]} | 138 | ]} |
134 | ]}, | 139 | ]}, |
135 | {tag:'div', cls:'footer'} | 140 | {tag:'div', cls:'footer'} |
136 | ]); | 141 | ]); |
137 | 142 | ||
138 | this.tabPanelController().setup({selected:this.initiallySelectedTab()}); | 143 | this.tabPanelController().setup({selected:this.initiallySelectedTab()}); |
139 | }, | 144 | }, |
140 | 145 | ||
141 | //------------------------------------------------------------------------- | 146 | //------------------------------------------------------------------------- |
142 | 147 | ||
143 | 148 | ||
144 | __syntaxFix__: "syntax fix" | 149 | __syntaxFix__: "syntax fix" |
145 | }); | 150 | }); |
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js index d2f1045..462d864 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js | |||
@@ -37,72 +37,80 @@ Clipperz.PM.UI.Web.Components.DataPanel = function(args) { | |||
37 | panel:'offlineCopyPanel' | 37 | panel:'offlineCopyPanel' |
38 | }, | 38 | }, |
39 | 'SHARING': { | 39 | 'SHARING': { |
40 | tab:'sharingTab', | 40 | tab:'sharingTab', |
41 | panel:'sharingPanel' | 41 | panel:'sharingPanel' |
42 | }, | 42 | }, |
43 | 'IMPORT': { | 43 | 'IMPORT': { |
44 | tab:'importTab', | 44 | tab:'importTab', |
45 | panel:'importPanel' | 45 | panel:'importPanel' |
46 | }, | 46 | }, |
47 | 'EXPORT': { | 47 | 'EXPORT': { |
48 | tab:'exportTab', | 48 | tab:'exportTab', |
49 | panel:'exportPanel' | 49 | panel:'exportPanel' |
50 | } | 50 | } |
51 | }; | 51 | }; |
52 | 52 | ||
53 | return this; | 53 | return this; |
54 | } | 54 | } |
55 | 55 | ||
56 | //============================================================================= | 56 | //============================================================================= |
57 | 57 | ||
58 | Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DataPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { | 58 | Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DataPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { |
59 | 59 | ||
60 | //------------------------------------------------------------------------- | 60 | //------------------------------------------------------------------------- |
61 | 61 | ||
62 | 'toString': function () { | 62 | 'toString': function () { |
63 | return "Clipperz.PM.UI.Web.Components.DataPanel component"; | 63 | return "Clipperz.PM.UI.Web.Components.DataPanel component"; |
64 | }, | 64 | }, |
65 | 65 | ||
66 | //------------------------------------------------------------------------- | 66 | //------------------------------------------------------------------------- |
67 | 67 | ||
68 | 'renderSelf': function(/*aContainer, aPosition*/) { | 68 | 'renderSelf': function(/*aContainer, aPosition*/) { |
69 | this.append(this.element(), [ | 69 | this.append(this.element(), [ |
70 | {tag:'div', cls:'header', children:[ | 70 | {tag:'div', cls:'header', children:[ |
71 | {tag:'div', cls:'subPanelTabs', children:[ | 71 | {tag:'div', cls:'subPanelTabs', children:[ |
72 | {tag:'ul', children:[ | 72 | {tag:'ul', children:[ |
73 | {tag:'li', id:this.getId('offlineCopyTab'),children:[{tag:'a', href:'#', html:'Offline copy'}], cls:'first'}, | 73 | {tag:'li', id:this.getId('offlineCopyTab'),children:[{tag:'a', href:'#', html:'Offline copy'}], cls:'first'}, |
74 | {tag:'li', id:this.getId('sharingTab'), children:[{tag:'a', href:'#', html:'Sharing'}]}, | 74 | {tag:'li', id:this.getId('sharingTab'), children:[{tag:'a', href:'#', html:'Sharing'}]}, |
75 | {tag:'li', id:this.getId('importTab'), children:[{tag:'a', href:'#', html:'Import'}]}, | 75 | {tag:'li', id:this.getId('importTab'), children:[{tag:'a', href:'#', html:'Import'}]}, |
76 | {tag:'li', id:this.getId('exportTab'), children:[{tag:'a', href:'#', html:'Export'}]} | 76 | {tag:'li', id:this.getId('exportTab'), children:[{tag:'a', href:'#', html:'Export'}]} |
77 | ]} | 77 | ]} |
78 | ]} | 78 | ]} |
79 | ]}, | 79 | ]}, |
80 | {tag:'div', cls:'body', children:[ | 80 | {tag:'div', cls:'body', children:[ |
81 | {tag:'div', cls:'accountPanel', children:[ | 81 | {tag:'div', cls:'accountPanel', children:[ |
82 | {tag:'div', cls:'subPanelContent', children:[ | 82 | {tag:'div', cls:'subPanelContent', children:[ |
83 | {tag:'ul', children:[ | 83 | {tag:'ul', children:[ |
84 | {tag:'li', id:this.getId('offlineCopyPanel'),children:[ | 84 | {tag:'li', id:this.getId('offlineCopyPanel'),children:[ |
85 | {tag:'h3', html:"Offline copy"} | 85 | // {tag:'h3', html:"Offline copy"}, |
86 | {tag:'p', html:"With just one click you can dump all your encrypted data from Clipperz servers to your hard disk and create a read-only offline version of Clipperz to be used when you are not connected to the Internet."}, | ||
87 | {tag:'a', id:this.getId('offlineCopyDownloadLink'), href:'#', html:"Download", cls:'downloadOfflineCopy'} | ||
86 | ]}, | 88 | ]}, |
87 | {tag:'li', id:this.getId('sharingPanel'),children:[ | 89 | {tag:'li', id:this.getId('sharingPanel'),children:[ |
88 | {tag:'h3', html:"Sharing"} | 90 | // {tag:'h3', html:"Sharing"} |
89 | ]}, | 91 | ]}, |
90 | {tag:'li', id:this.getId('importPanel'), children:[ | 92 | {tag:'li', id:this.getId('importPanel'), children:[ |
91 | {tag:'h3', html:"Import"} | 93 | // {tag:'h3', html:"Import"} |
92 | ]}, | 94 | ]}, |
93 | {tag:'li', id:this.getId('exportPanel'), children:[ | 95 | {tag:'li', id:this.getId('exportPanel'), children:[ |
94 | {tag:'h3', html:"Export"} | 96 | // {tag:'h3', html:"Export"} |
95 | ]} | 97 | ]} |
96 | ]} | 98 | ]} |
97 | ]} | 99 | ]} |
98 | ]} | 100 | ]} |
99 | ]}, | 101 | ]}, |
100 | {tag:'div', cls:'footer'} | 102 | {tag:'div', cls:'footer'} |
101 | ]); | 103 | ]); |
102 | 104 | ||
103 | this.tabPanelController().setup({selected:this.initiallySelectedTab()}); | 105 | this.tabPanelController().setup({selected:this.initiallySelectedTab()}); |
106 | MochiKit.Signal.connect(this.getId('offlineCopyDownloadLink'), 'onclick', this, 'downloadOfflineCopy'); | ||
107 | }, | ||
108 | |||
109 | 'downloadOfflineCopy': function (anEvent) { | ||
110 | anEvent.preventDefault(); | ||
111 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'downloadOfflineCopy', anEvent.src()); | ||
104 | }, | 112 | }, |
105 | 113 | ||
106 | //------------------------------------------------------------------------- | 114 | //------------------------------------------------------------------------- |
107 | __syntaxFix__: "syntax fix" | 115 | __syntaxFix__: "syntax fix" |
108 | }); | 116 | }); |
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js index 5d082b5..26506e7 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js | |||
@@ -37,116 +37,120 @@ Clipperz.PM.UI.Web.Components.LoginProgress = function(args) { | |||
37 | 37 | ||
38 | //============================================================================= | 38 | //============================================================================= |
39 | 39 | ||
40 | Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LoginProgress, Clipperz.PM.UI.Common.Components.BaseComponent, { | 40 | Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LoginProgress, Clipperz.PM.UI.Common.Components.BaseComponent, { |
41 | 41 | ||
42 | //------------------------------------------------------------------------- | 42 | //------------------------------------------------------------------------- |
43 | 43 | ||
44 | 'toString': function () { | 44 | 'toString': function () { |
45 | return "Clipperz.PM.UI.Web.Components.LoginProgress component"; | 45 | return "Clipperz.PM.UI.Web.Components.LoginProgress component"; |
46 | }, | 46 | }, |
47 | 47 | ||
48 | //------------------------------------------------------------------------- | 48 | //------------------------------------------------------------------------- |
49 | 49 | ||
50 | 'deferred': function() { | 50 | 'deferred': function() { |
51 | return this._deferred; | 51 | return this._deferred; |
52 | }, | 52 | }, |
53 | 53 | ||
54 | 'setDeferred': function(aValue) { | 54 | 'setDeferred': function(aValue) { |
55 | this._deferred = aValue; | 55 | this._deferred = aValue; |
56 | }, | 56 | }, |
57 | 57 | ||
58 | //------------------------------------------------------------------------- | 58 | //------------------------------------------------------------------------- |
59 | 59 | ||
60 | 'renderSelf': function() { | 60 | 'renderSelf': function() { |
61 | // var loginProgressElement; | 61 | // var loginProgressElement; |
62 | // | 62 | // |
63 | // loginProgressElement = MochiKit.DOM.getElement('loginProgress'); | 63 | // loginProgressElement = MochiKit.DOM.getElement('loginProgress'); |
64 | // | 64 | // |
65 | // if (loginProgressElement == null) { | 65 | // if (loginProgressElement == null) { |
66 | // loginProgressElement = this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress'}, true); | 66 | // loginProgressElement = this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress'}, true); |
67 | // } | 67 | // } |
68 | 68 | ||
69 | //console.log(">> LoginProgress.renderSelf", this.element()); | 69 | //console.log(">> LoginProgress.renderSelf", this.element()); |
70 | this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress', children: [ | 70 | this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress', children: [ |
71 | // this.append(loginProgressElement, [ | 71 | // this.append(loginProgressElement, [ |
72 | {tag:'div', cls:'header', children:[ | 72 | {tag:'div', cls:'header', children:[ |
73 | {tag:'h3', id:this.getId('title'), html:"login progress"} | 73 | {tag:'h3', id:this.getId('title'), html:"login progress"} |
74 | ]}, | 74 | ]}, |
75 | {tag:'div', cls:'body', children:[ | 75 | {tag:'div', cls:'body', children:[ |
76 | {tag:'div', id:this.getId('progressBar')}, | 76 | {tag:'div', id:this.getId('progressBar')}, |
77 | {tag:'div', id:this.getId('errorBox'), cls:'errorBox', children:[ | 77 | {tag:'div', id:this.getId('errorBox'), cls:'errorBox', children:[ |
78 | // {tag:'div',cls:'img ALERT', children:[{tag:'div'}]}, | 78 | // {tag:'div',cls:'img ALERT', children:[{tag:'div'}]}, |
79 | {tag:'div',cls:'img ALERT', children:[{tag:'canvas', id:this.getId('canvas')}]}, | 79 | {tag:'div',cls:'img ALERT', children:[{tag:'canvas', id:this.getId('canvas')}]}, |
80 | {tag:'p', html:"Login failed"} | 80 | {tag:'p', html:"Login failed"} |
81 | ]} | 81 | ]} |
82 | ]}, | 82 | ]}, |
83 | {tag:'div', cls:'footer', children:[ | 83 | {tag:'div', cls:'footer', children:[ |
84 | {tag:'div', cls:'buttonArea', id:this.getId('buttonArea'), children:[ | 84 | {tag:'div', cls:'buttonArea', id:this.getId('buttonArea'), children:[ |
85 | {tag:'div', cls:'button', id:this.getId('button'), children:[ | 85 | // {tag:'div', cls:'button', id:this.getId('button'), children:[ |
86 | {tag:'a', href:'#', id:this.getId('buttonLink'), html:"cancel"} | 86 | // {tag:'a', href:'#', id:this.getId('buttonLink'), html:"cancel"} |
87 | ]} | 87 | // ]} |
88 | {tag:'a', cls:'button', id:this.getId('button'), html:"cancel"} | ||
88 | ]} | 89 | ]} |
89 | ]} | 90 | ]} |
90 | ]}); | 91 | ]}); |
91 | // ]); | 92 | // ]); |
92 | 93 | ||
93 | Clipperz.PM.UI.Canvas.marks['!'](this.getElement('canvas'), "#ffffff"); | 94 | Clipperz.PM.UI.Canvas.marks['!'](this.getElement('canvas'), "#ffffff"); |
94 | 95 | ||
95 | this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); | 96 | this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); |
96 | MochiKit.Style.hideElement(this.getElement('errorBox')); | 97 | MochiKit.Style.hideElement(this.getElement('errorBox')); |
97 | 98 | ||
98 | MochiKit.Signal.connect(this.getId('buttonLink'), 'onclick', this, 'cancelEventHandler'); | 99 | // MochiKit.Signal.connect(this.getId('buttonLink'), 'onclick', this, 'cancelEventHandler'); |
100 | MochiKit.Signal.connect(this.getId('button'), 'onclick', this, 'cancelEventHandler'); | ||
99 | }, | 101 | }, |
100 | 102 | ||
101 | //------------------------------------------------------------------------- | 103 | //------------------------------------------------------------------------- |
102 | 104 | ||
103 | 'displayElement': function() { | 105 | 'displayElement': function() { |
104 | return MochiKit.DOM.getElement('loginProgress'); | 106 | return MochiKit.DOM.getElement('loginProgress'); |
105 | }, | 107 | }, |
106 | 108 | ||
107 | //------------------------------------------------------------------------- | 109 | //------------------------------------------------------------------------- |
108 | 110 | ||
109 | 'cancelEventHandler': function(anEvent) { | 111 | 'cancelEventHandler': function(anEvent) { |
110 | anEvent.preventDefault(); | 112 | anEvent.preventDefault(); |
111 | 113 | ||
112 | MochiKit.Signal.signal(this, 'cancelEvent'); | 114 | MochiKit.Signal.signal(this, 'cancelEvent'); |
113 | }, | 115 | }, |
114 | 116 | ||
115 | //------------------------------------------------------------------------- | 117 | //------------------------------------------------------------------------- |
116 | 118 | ||
117 | 'disableCancel': function() { | 119 | 'disableCancel': function() { |
118 | MochiKit.Style.hideElement(this.getElement('buttonArea')); | 120 | MochiKit.Style.hideElement(this.getElement('buttonArea')); |
119 | }, | 121 | }, |
120 | 122 | ||
121 | //------------------------------------------------------------------------- | 123 | //------------------------------------------------------------------------- |
122 | 124 | ||
123 | 'showErrorMessage': function() { | 125 | 'showErrorMessage': function() { |
124 | this.getElement('buttonLink').innerHTML = "close"; | 126 | // this.getElement('buttonLink').innerHTML = "close"; |
127 | this.getElement('button').innerHTML = "close"; | ||
128 | MochiKit.DOM.addElementClass(this.getElement('button'), 'default'); | ||
125 | 129 | ||
126 | MochiKit.Style.hideElement(this.getElement('progressBar')); | 130 | MochiKit.Style.hideElement(this.getElement('progressBar')); |
127 | 131 | ||
128 | this.getElement('title').innerHTML = "Error"; | 132 | this.getElement('title').innerHTML = "Error"; |
129 | MochiKit.Style.showElement(this.getElement('errorBox')); | 133 | MochiKit.Style.showElement(this.getElement('errorBox')); |
130 | MochiKit.Style.showElement(this.getElement('buttonArea')); | 134 | MochiKit.Style.showElement(this.getElement('buttonArea')); |
131 | }, | 135 | }, |
132 | 136 | ||
133 | //------------------------------------------------------------------------- | 137 | //------------------------------------------------------------------------- |
134 | 138 | ||
135 | 'deferredHideModalAndRemove': function(someParameters, aResult) { | 139 | 'deferredHideModalAndRemove': function(someParameters, aResult) { |
136 | vardeferredResult; | 140 | vardeferredResult; |
137 | 141 | ||
138 | deferredResult = new Clipperz.Async.Deferred("LoginProgress.deferredHideModalAndRemove", {trace:false}); | 142 | deferredResult = new Clipperz.Async.Deferred("LoginProgress.deferredHideModalAndRemove", {trace:false}); |
139 | deferredResult.addMethod(this, 'deferredHideModal'); | 143 | deferredResult.addMethod(this, 'deferredHideModal'); |
140 | deferredResult.addMethod(this, 'remove'); | 144 | deferredResult.addMethod(this, 'remove'); |
141 | deferredResult.addCallback(function () { | 145 | deferredResult.addCallback(function () { |
142 | return aResult; | 146 | return aResult; |
143 | }); | 147 | }); |
144 | deferredResult.callback(someParameters); | 148 | deferredResult.callback(someParameters); |
145 | 149 | ||
146 | return deferredResult; | 150 | return deferredResult; |
147 | }, | 151 | }, |
148 | 152 | ||
149 | //------------------------------------------------------------------------- | 153 | //------------------------------------------------------------------------- |
150 | 154 | ||
151 | __syntaxFix__: "syntax fix" | 155 | __syntaxFix__: "syntax fix" |
152 | }); | 156 | }); |
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js index 3ee6189..0fa369f 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js | |||
@@ -37,74 +37,74 @@ Clipperz.PM.UI.Web.Components.ToolsPanel = function(args) { | |||
37 | panel:'passwordGeneratorPanel' | 37 | panel:'passwordGeneratorPanel' |
38 | }, | 38 | }, |
39 | 'BOOKMARKLET': { | 39 | 'BOOKMARKLET': { |
40 | tab:'bookmarkletTab', | 40 | tab:'bookmarkletTab', |
41 | panel:'bookmarkletPanel' | 41 | panel:'bookmarkletPanel' |
42 | }, | 42 | }, |
43 | 'COMPACT_EDITION': { | 43 | 'COMPACT_EDITION': { |
44 | tab:'compactEditionTab', | 44 | tab:'compactEditionTab', |
45 | panel:'compactEditionPanel' | 45 | panel:'compactEditionPanel' |
46 | }, | 46 | }, |
47 | 'HTTP_AUTH': { | 47 | 'HTTP_AUTH': { |
48 | tab:'httpAuthTab', | 48 | tab:'httpAuthTab', |
49 | panel:'httpAuthPanel' | 49 | panel:'httpAuthPanel' |
50 | } | 50 | } |
51 | }; | 51 | }; |
52 | 52 | ||
53 | return this; | 53 | return this; |
54 | } | 54 | } |
55 | 55 | ||
56 | //============================================================================= | 56 | //============================================================================= |
57 | 57 | ||
58 | Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.ToolsPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { | 58 | Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.ToolsPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, { |
59 | 59 | ||
60 | //------------------------------------------------------------------------- | 60 | //------------------------------------------------------------------------- |
61 | 61 | ||
62 | 'toString': function () { | 62 | 'toString': function () { |
63 | return "Clipperz.PM.UI.Web.Components.ToolsPanel component"; | 63 | return "Clipperz.PM.UI.Web.Components.ToolsPanel component"; |
64 | }, | 64 | }, |
65 | 65 | ||
66 | //------------------------------------------------------------------------- | 66 | //------------------------------------------------------------------------- |
67 | 67 | ||
68 | 'renderSelf': function(/*aContainer, aPosition*/) { | 68 | 'renderSelf': function(/*aContainer, aPosition*/) { |
69 | this.append(this.element(), [ | 69 | this.append(this.element(), [ |
70 | {tag:'div', cls:'header', children:[ | 70 | {tag:'div', cls:'header', children:[ |
71 | {tag:'div', cls:'subPanelTabs', children:[ | 71 | {tag:'div', cls:'subPanelTabs', children:[ |
72 | {tag:'ul', children:[ | 72 | {tag:'ul', children:[ |
73 | {tag:'li', id:this.getId('passwordGeneratorTab'),children:[{tag:'a', href:'#', html:'Password generator'}], cls:'first'}, | 73 | {tag:'li', id:this.getId('passwordGeneratorTab'),children:[{tag:'a', href:'#', html:'Password generator'}], cls:'first'}, |
74 | {tag:'li', id:this.getId('bookmarkletTab'), children:[{tag:'a', href:'#', html:'Bookmarklet'}]}, | 74 | {tag:'li', id:this.getId('bookmarkletTab'), children:[{tag:'a', href:'#', html:'Bookmarklet'}]}, |
75 | {tag:'li', id:this.getId('compactEditionTab'), children:[{tag:'a', href:'#', html:'Compact edition'}]}, | 75 | {tag:'li', id:this.getId('compactEditionTab'), children:[{tag:'a', href:'#', html:'Compact edition'}]}, |
76 | {tag:'li', id:this.getId('httpAuthTab'), children:[{tag:'a', href:'#', html:'HTTP Auth'}]} | 76 | {tag:'li', id:this.getId('httpAuthTab'), children:[{tag:'a', href:'#', html:'HTTP Auth'}]} |
77 | ]} | 77 | ]} |
78 | ]} | 78 | ]} |
79 | ]}, | 79 | ]}, |
80 | {tag:'div', cls:'body', children:[ | 80 | {tag:'div', cls:'body', children:[ |
81 | {tag:'div', cls:'accountPanel', children:[ | 81 | {tag:'div', cls:'accountPanel', children:[ |
82 | {tag:'div', cls:'subPanelContent', children:[ | 82 | {tag:'div', cls:'subPanelContent', children:[ |
83 | {tag:'ul', children:[ | 83 | {tag:'ul', children:[ |
84 | {tag:'li', id:this.getId('passwordGeneratorPanel'),children:[ | 84 | {tag:'li', id:this.getId('passwordGeneratorPanel'),children:[ |
85 | {tag:'h3', html:"Password generator"} | 85 | // {tag:'h3', html:"Password generator"} |
86 | ]}, | 86 | ]}, |
87 | {tag:'li', id:this.getId('bookmarkletPanel'),children:[ | 87 | {tag:'li', id:this.getId('bookmarkletPanel'),children:[ |
88 | {tag:'h3', html:"Bookmarklet"} | 88 | // {tag:'h3', html:"Bookmarklet"} |
89 | ]}, | 89 | ]}, |
90 | {tag:'li', id:this.getId('compactEditionPanel'), children:[ | 90 | {tag:'li', id:this.getId('compactEditionPanel'), children:[ |
91 | {tag:'h3', html:"Compact edition"} | 91 | // {tag:'h3', html:"Compact edition"} |
92 | ]}, | 92 | ]}, |
93 | {tag:'li', id:this.getId('httpAuthPanel'), children:[ | 93 | {tag:'li', id:this.getId('httpAuthPanel'), children:[ |
94 | {tag:'h3', html:"HTTP Auth"} | 94 | // {tag:'h3', html:"HTTP Auth"} |
95 | ]} | 95 | ]} |
96 | ]} | 96 | ]} |
97 | ]} | 97 | ]} |
98 | ]} | 98 | ]} |
99 | ]}, | 99 | ]}, |
100 | {tag:'div', cls:'footer'} | 100 | {tag:'div', cls:'footer'} |
101 | ]); | 101 | ]); |
102 | 102 | ||
103 | this.tabPanelController().setup({selected:this.initiallySelectedTab()}); | 103 | this.tabPanelController().setup({selected:this.initiallySelectedTab()}); |
104 | }, | 104 | }, |
105 | 105 | ||
106 | //------------------------------------------------------------------------- | 106 | //------------------------------------------------------------------------- |
107 | 107 | ||
108 | 108 | ||
109 | __syntaxFix__: "syntax fix" | 109 | __syntaxFix__: "syntax fix" |
110 | }); | 110 | }); |
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js index 9a0e744..1ab2e69 100644 --- a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js | |||
@@ -190,137 +190,162 @@ MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.AppController.prototype, { | |||
190 | 190 | ||
191 | deferredResult = new Clipperz.Async.Deferred("AppController.populateUserInfo", {trace:false}); | 191 | deferredResult = new Clipperz.Async.Deferred("AppController.populateUserInfo", {trace:false}); |
192 | deferredResult.collectResults({ | 192 | deferredResult.collectResults({ |
193 | 'username':MochiKit.Base.methodcaller('displayName'), | 193 | 'username':MochiKit.Base.methodcaller('displayName'), |
194 | 'cardsNumber':[ | 194 | 'cardsNumber':[ |
195 | MochiKit.Base.methodcaller('getRecords'), | 195 | MochiKit.Base.methodcaller('getRecords'), |
196 | function (someResults) { return someResults.length; } | 196 | function (someResults) { return someResults.length; } |
197 | ], | 197 | ], |
198 | 'directLoginsNumber': [ | 198 | 'directLoginsNumber': [ |
199 | MochiKit.Base.methodcaller('getDirectLogins'), | 199 | MochiKit.Base.methodcaller('getDirectLogins'), |
200 | function (someResults) { return someResults.length; } | 200 | function (someResults) { return someResults.length; } |
201 | ] | 201 | ] |
202 | }) | 202 | }) |
203 | deferredResult.addMethod(this.userInfoBox(), 'updateUserDetails'); | 203 | deferredResult.addMethod(this.userInfoBox(), 'updateUserDetails'); |
204 | deferredResult.callback(this.user()); | 204 | deferredResult.callback(this.user()); |
205 | 205 | ||
206 | return deferredResult; | 206 | return deferredResult; |
207 | }, | 207 | }, |
208 | 208 | ||
209 | //----------------------------------------------------------------------------- | 209 | //----------------------------------------------------------------------------- |
210 | 210 | ||
211 | 'run': function(args) { | 211 | 'run': function(args) { |
212 | var deferredResult; | 212 | var deferredResult; |
213 | varslot; | 213 | varslot; |
214 | varpage; | 214 | varpage; |
215 | var user; | 215 | var user; |
216 | 216 | ||
217 | slot = args.slot; | 217 | slot = args.slot; |
218 | user = args.user; | 218 | user = args.user; |
219 | 219 | ||
220 | this.setUser(user); | 220 | this.setUser(user); |
221 | 221 | ||
222 | slot.setContent(this.appPage()); | 222 | slot.setContent(this.appPage()); |
223 | 223 | ||
224 | this.appPage().slotNamed('userInfoBox').setContent(this.userInfoBox()); | 224 | this.appPage().slotNamed('userInfoBox').setContent(this.userInfoBox()); |
225 | this.appPage().slotNamed('tabSidePanel').setContent(this.tabSidePanel()); | 225 | this.appPage().slotNamed('tabSidePanel').setContent(this.tabSidePanel()); |
226 | 226 | ||
227 | this.appPage().slotNamed('accountPanel').setContent(this.accountPanel()); | 227 | this.appPage().slotNamed('accountPanel').setContent(this.accountPanel()); |
228 | this.appPage().slotNamed('dataPanel').setContent(this.dataPanel()); | 228 | this.appPage().slotNamed('dataPanel').setContent(this.dataPanel()); |
229 | this.appPage().slotNamed('toolsPanel').setContent(this.toolsPanel()); | 229 | this.appPage().slotNamed('toolsPanel').setContent(this.toolsPanel()); |
230 | 230 | ||
231 | this.hideAllAppPageTabSlots(); | 231 | this.hideAllAppPageTabSlots(); |
232 | this.appPage().showSlot(this.slotNameForTab('cards')); | 232 | this.appPage().showSlot(this.slotNameForTab('cards')); |
233 | 233 | ||
234 | MochiKit.Signal.connect(this.tabSidePanel(), 'tabSelected',this, 'handleTabSelected'); | 234 | MochiKit.Signal.connect(this.tabSidePanel(), 'tabSelected',this, 'handleTabSelected'); |
235 | MochiKit.Signal.connect(this.tabSidePanel(), 'addCard', this, 'handleAddCard'); | 235 | MochiKit.Signal.connect(this.tabSidePanel(), 'addCard', this, 'handleAddCard'); |
236 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'addCard', this, 'handleAddCard'); | 236 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'addCard', this, 'handleAddCard'); |
237 | 237 | ||
238 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'downloadOfflineCopy',this, 'handleDownloadOfflineCopy'); | ||
239 | |||
238 | deferredResult = new Clipperz.Async.Deferred("AppController.run", {trace:false}); | 240 | deferredResult = new Clipperz.Async.Deferred("AppController.run", {trace:false}); |
239 | 241 | ||
240 | deferredResult.addMethod(this.cardsController(), 'run', {slot:this.appPage().slotNamed('cardGrid'), user:user}); | 242 | deferredResult.addMethod(this.cardsController(), 'run', {slot:this.appPage().slotNamed('cardGrid'), user:user}); |
241 | // deferredResult.addMethod(this.directLoginsController(), 'run', {slot:this.appPage().slotNamed('directLoginGrid'), user:user}); | 243 | // deferredResult.addMethod(this.directLoginsController(), 'run', {slot:this.appPage().slotNamed('directLoginGrid'), user:user}); |
242 | deferredResult.addMethod(this, 'populateUserInfo'); | 244 | deferredResult.addMethod(this, 'populateUserInfo'); |
243 | 245 | ||
244 | deferredResult.addCallback(MochiKit.Visual.ScrollTo, 'miscLinks', {duration:0}); | 246 | deferredResult.addCallback(MochiKit.Visual.ScrollTo, 'miscLinks', {duration:0}); |
245 | deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'CARDS_CONTROLLER_DID_RUN'); | 247 | deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'CARDS_CONTROLLER_DID_RUN'); |
246 | deferredResult.addMethod(this.tabSidePanel(), 'selectTab', 'cards'); | 248 | deferredResult.addMethod(this.tabSidePanel(), 'selectTab', 'cards'); |
247 | deferredResult.callback(); | 249 | deferredResult.callback(); |
248 | }, | 250 | }, |
249 | 251 | ||
250 | //----------------------------------------------------------------------------- | 252 | //----------------------------------------------------------------------------- |
251 | 253 | ||
252 | 'handleTabSelected': function (selectedTabName) { | 254 | 'handleTabSelected': function (selectedTabName) { |
253 | var aTabName; | 255 | var aTabName; |
254 | var aSlotName; | 256 | var aSlotName; |
255 | 257 | ||
256 | //Clipperz.log(">>> AppController.handleTabSelected", selectedTabName); | 258 | //Clipperz.log(">>> AppController.handleTabSelected", selectedTabName); |
257 | this.hideAllAppPageTabSlots(); | 259 | this.hideAllAppPageTabSlots(); |
258 | this.appPage().showSlot(this.slotNameForTab(selectedTabName)); | 260 | this.appPage().showSlot(this.slotNameForTab(selectedTabName)); |
259 | 261 | ||
260 | switch (selectedTabName) { | 262 | switch (selectedTabName) { |
261 | case 'cards': | 263 | case 'cards': |
262 | this.cardsController().focus(); | 264 | this.cardsController().focus(); |
263 | break; | 265 | break; |
264 | // case 'directLogins': | 266 | // case 'directLogins': |
265 | // this.directLoginsController().focus(); | 267 | // this.directLoginsController().focus(); |
266 | // break; | 268 | // break; |
267 | case 'data': | 269 | case 'data': |
268 | break; | 270 | break; |
269 | case 'account': | 271 | case 'account': |
270 | break; | 272 | break; |
271 | case 'tools': | 273 | case 'tools': |
272 | break; | 274 | break; |
273 | } | 275 | } |
274 | //Clipperz.log("<-- AppController.handleTabSelected", aTabName); | 276 | //Clipperz.log("<-- AppController.handleTabSelected", aTabName); |
275 | }, | 277 | }, |
276 | 278 | ||
277 | //============================================================================= | 279 | //============================================================================= |
278 | 280 | ||
279 | 'handleAddCard': function (aSourceElement) { | 281 | 'handleAddCard': function (aSourceElement) { |
280 | //Clipperz.log("=== AppController.addCard", aSourceElement); | 282 | //Clipperz.log("=== AppController.addCard", aSourceElement); |
281 | this.cardsController().addCard(aSourceElement); | 283 | this.cardsController().addCard(aSourceElement); |
282 | }, | 284 | }, |
283 | 285 | ||
284 | //============================================================================= | 286 | //============================================================================= |
285 | 287 | ||
286 | 'userDataSuccessfullySavedHandler': function (anEvent) { | 288 | 'userDataSuccessfullySavedHandler': function (anEvent) { |
287 | this.populateUserInfo(); | 289 | this.populateUserInfo(); |
288 | }, | 290 | }, |
289 | 291 | ||
290 | //============================================================================= | 292 | //============================================================================= |
291 | 293 | ||
292 | 'handleLogout': function(anEvent) { | 294 | 'handleLogout': function(anEvent) { |
293 | var deferredResult; | 295 | var deferredResult; |
294 | 296 | ||
295 | deferredResult = new Clipperz.Async.Deferred("AppController.handleLogout", {trace:false}); | 297 | deferredResult = new Clipperz.Async.Deferred("AppController.handleLogout", {trace:false}); |
296 | deferredResult.addMethod(this.user(), 'logout'); | 298 | deferredResult.addMethod(this.user(), 'logout'); |
297 | deferredResult.addCallback(MochiKit.Signal.signal, this, 'logout'); | 299 | deferredResult.addCallback(MochiKit.Signal.signal, this, 'logout'); |
298 | deferredResult.callback(); | 300 | deferredResult.callback(); |
299 | 301 | ||
300 | return deferredResult; | 302 | return deferredResult; |
301 | }, | 303 | }, |
302 | 304 | ||
303 | //----------------------------------------------------------------------------- | 305 | //----------------------------------------------------------------------------- |
304 | 306 | ||
305 | 'handleLock': function (anEvent) { | 307 | 'handleLock': function (anEvent) { |
306 | return Clipperz.Async.callbacks("AppController.handleLock", [ | 308 | return Clipperz.Async.callbacks("AppController.handleLock", [ |
307 | MochiKit.Base.method(this.cardsController(), 'deleteAllCleanTextData'), | 309 | MochiKit.Base.method(this.cardsController(), 'deleteAllCleanTextData'), |
308 | MochiKit.Base.method(this.user(), 'lock') | 310 | MochiKit.Base.method(this.user(), 'lock') |
309 | ], {trace:false}); | 311 | ], {trace:false}); |
310 | }, | 312 | }, |
311 | 313 | ||
312 | //............................................................................. | 314 | //............................................................................. |
313 | 315 | ||
314 | 'handleUnlock': function (anEvent) { | 316 | 'handleUnlock': function (anEvent) { |
315 | return Clipperz.Async.callbacks("AppController.handleUnock", [ | 317 | return Clipperz.Async.callbacks("AppController.handleUnock", [ |
316 | MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress'), | 318 | MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress'), |
317 | MochiKit.Base.method(this.user(), 'login'), | 319 | MochiKit.Base.method(this.user(), 'login'), |
318 | MochiKit.Base.method(this.cardsController(), 'focus'), | 320 | MochiKit.Base.method(this.cardsController(), 'focus'), |
319 | MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'progressDone'), | 321 | MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'progressDone'), |
320 | MochiKit.Base.method(this.userInfoBox(), 'unlock') | 322 | MochiKit.Base.method(this.userInfoBox(), 'unlock') |
321 | ], {trace:false}); | 323 | ], {trace:false}); |
322 | }, | 324 | }, |
323 | 325 | ||
326 | 'handleDownloadOfflineCopy': function (anEvent) { | ||
327 | console.log("AppController.handleDownloadOfflineCopy"); | ||
328 | var downloadHref; | ||
329 | |||
330 | downloadHref = window.location.href.replace(/\/[^\/]*$/,'') + Clipperz_dumpUrl; | ||
331 | |||
332 | if (Clipperz_IEisBroken == true) { | ||
333 | window.open(downloadHref, ""); | ||
334 | } else { | ||
335 | vardeferredResult; | ||
336 | var newWindow; | ||
337 | |||
338 | newWindow = window.open("", ""); | ||
339 | |||
340 | deferredResult = new Clipperz.Async.Deferred("AppController.handleDownloadOfflineCopy", {trace:true}); | ||
341 | deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'echo', {'echo':"echo"}); | ||
342 | deferredResult.addCallback(function(aWindow) { | ||
343 | aWindow.location.href = downloadHref; | ||
344 | }, newWindow); | ||
345 | deferredResult.callback(); | ||
346 | } | ||
347 | }, | ||
348 | |||
324 | //============================================================================= | 349 | //============================================================================= |
325 | __syntaxFix__: "syntax fix" | 350 | __syntaxFix__: "syntax fix" |
326 | }); | 351 | }); |
diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js deleted file mode 100644 index 5380aa1..0000000 --- a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js +++ b/dev/null | |||
@@ -1,163 +0,0 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz Community Edition. | ||
6 | Clipperz Community Edition is an online password manager. | ||
7 | For further information about its features and functionalities please | ||
8 | refer to http://www.clipperz.com. | ||
9 | |||
10 | * Clipperz Community Edition is free software: you can redistribute | ||
11 | it and/or modify it under the terms of the GNU Affero General Public | ||
12 | License as published by the Free Software Foundation, either version | ||
13 | 3 of the License, or (at your option) any later version. | ||
14 | |||
15 | * Clipperz Community Edition is distributed in the hope that it will | ||
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
18 | See the GNU Affero General Public License for more details. | ||
19 | |||
20 | * You should have received a copy of the GNU Affero General Public | ||
21 | License along with Clipperz Community Edition. If not, see | ||
22 | <http://www.gnu.org/licenses/>. | ||
23 | |||
24 | */ | ||
25 | |||
26 | Clipperz.Base.module('Clipperz.PM.UI.iPhone.Components'); | ||
27 | |||
28 | Clipperz.PM.UI.iPhone.Components.CardDetail = function(args) { | ||
29 | args = args || {}; | ||
30 | |||
31 | Clipperz.PM.UI.iPhone.Components.CardDetail.superclass.constructor.apply(this, arguments); | ||
32 | |||
33 | this._cardReference = null; | ||
34 | |||
35 | return this; | ||
36 | } | ||
37 | |||
38 | //============================================================================= | ||
39 | |||
40 | Clipperz.Base.extend(Clipperz.PM.UI.iPhone.Components.CardDetail, Clipperz.PM.UI.Common.Components.BaseComponent, { | ||
41 | |||
42 | //------------------------------------------------------------------------- | ||
43 | |||
44 | 'toString': function () { | ||
45 | return "Clipperz.PM.UI.iPhone.Components.CardDetail component"; | ||
46 | }, | ||
47 | |||
48 | //------------------------------------------------------------------------- | ||
49 | |||
50 | 'cardReference': function () { | ||
51 | return this._cardReference; | ||
52 | }, | ||
53 | |||
54 | 'setCardReference': function (aValue) { | ||
55 | this._cardReference = aValue; | ||
56 | }, | ||
57 | |||
58 | //------------------------------------------------------------------------- | ||
59 | |||
60 | 'renderSelf': function(/*aContainer, aPosition*/) { | ||
61 | this.append(this.element(), [ | ||
62 | {tag:'div', cls:'cardDetail', id:this.getId('cardDetail'), children:[ | ||
63 | {tag:'div', id:this.getId('progressBar')} //, | ||
64 | // {tag:'h1', cls:'loading', html:"loading"} | ||
65 | ]} | ||
66 | ]); | ||
67 | |||
68 | this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); | ||
69 | MochiKit.Signal.signal(Clipperz.PM.UI.Common.Controllers.ProgressBarController.defaultController, 'updateProgress', 0); | ||
70 | }, | ||
71 | |||
72 | //========================================================================= | ||
73 | |||
74 | 'showCardDetails': function (someData) { | ||
75 | this.element().innerHTML = ''; | ||
76 | this.append(this.element(), [ | ||
77 | {tag:'fieldset', id:this.getId('fields'), children:MochiKit.Base.map(function (aFieldData) { | ||
78 | return {tag:'div', cls:'row', children:[ | ||
79 | {tag:'label', html:aFieldData['label']}, | ||
80 | // {tag:'span', cls:('fieldValue ' + (aFieldData['isHidden']? 'password' : 'text')), html:aFieldData['value']} | ||
81 | {tag:'div', cls:('fieldValue ' + (aFieldData['isHidden']? 'password' : 'text')), children:[ | ||
82 | {tag:'div', children:[{tag:'p', html:aFieldData['value']}]} | ||
83 | ]} | ||
84 | // {tag:'input', type:'text', cls:('fieldValue ' + (aFieldData['isHidden']? 'password' : 'text')), value:aFieldData['value'], disabled:true} | ||
85 | |||
86 | ]} | ||
87 | }, someData['fields'])} | ||
88 | ]); | ||
89 | |||
90 | MochiKit.Iter.forEach(MochiKit.Selector.findChildElements(this.element(), ['span.password']), MochiKit.Base.bind(function (aPasswordElement) { | ||
91 | MochiKit.Signal.connect(aPasswordElement, 'onclick', function (anEvent) { alert(MochiKit.DOM.scrapeText(anEvent.src())); }) | ||
92 | }, this)); | ||
93 | |||
94 | if (someData['directLogins'].length > 0) { | ||
95 | this.append(this.element(), [ | ||
96 | {tag:'h2', html:"Direct logins"}, | ||
97 | {tag:'fieldset', id:this.getId('directLogins'), children:MochiKit.Base.map(function (aDirectLoginData) { | ||
98 | return {tag:'div', cls:'row', id:('directLogin_' + aDirectLoginData['_reference']), children:[ | ||
99 | {tag:'img', cls:'favicon', src:aDirectLoginData['favicon']}, | ||
100 | // {tag:'input', cls:'directLogin', disabled:'disabled', type:'text', name:aDirectLoginData['label'], value:aDirectLoginData['label']} | ||
101 | {tag:'span', cls:'directLogin', html:aDirectLoginData['label']} | ||
102 | ]} | ||
103 | }, someData['directLogins'])} | ||
104 | ]); | ||
105 | |||
106 | MochiKit.Base.map(MochiKit.Base.bind(function (aRowNode) { | ||
107 | MochiKit.Signal.connect(aRowNode, 'onclick', this, 'directLoginClickHandler'); | ||
108 | }, this), | ||
109 | MochiKit.Selector.findChildElements(this.getElement('directLogins'), ['div.row']) | ||
110 | ) | ||
111 | }; | ||
112 | |||
113 | if (someData['notes'] != '') { | ||
114 | this.append(this.element(), [ | ||
115 | {tag:'h2', html:"Notes"}, | ||
116 | {tag:'fieldset', id:this.getId('fieldset'), children:[ | ||
117 | {tag:'div', cls:'row notes', children:[ | ||
118 | {tag:'span', html:someData['notes']} | ||
119 | ]} | ||
120 | ]} | ||
121 | ]); | ||
122 | }; | ||
123 | |||
124 | return true; | ||
125 | }, | ||
126 | |||
127 | //------------------------------------------------------------------------- | ||
128 | /* | ||
129 | 'toggleClickHandler': function (anEvent) { | ||
130 | varnextState; | ||
131 | varfieldValue; | ||
132 | |||
133 | //console.log("TOGGLE"); | ||
134 | anEvent.preventDefault; | ||
135 | fieldValue = MochiKit.Selector.findChildElements(anEvent.src().parentNode.parentNode, ['span.password'])[0]; | ||
136 | |||
137 | nextState = (MochiKit.DOM.getNodeAttribute(anEvent.src(), 'toggled') != 'true'); | ||
138 | if (nextState) { | ||
139 | MochiKit.DOM.removeElementClass(fieldValue, 'clear'); | ||
140 | } else { | ||
141 | MochiKit.DOM.addElementClass(fieldValue, 'clear'); | ||
142 | } | ||
143 | |||
144 | MochiKit.DOM.setNodeAttribute(anEvent.src(), 'toggled', nextState); | ||
145 | }, | ||
146 | */ | ||
147 | //========================================================================= | ||
148 | |||
149 | 'directLoginClickHandler': function (anEvent) { | ||
150 | anEvent.preventDefault(); | ||
151 | |||
152 | if (/(directLogin_)/.test(anEvent.src().id)) { | ||
153 | var directLoginReference; | ||
154 | |||
155 | directLoginReference = anEvent.src().id.match(/(directLogin_)(.*)/)[2]; | ||
156 | MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'selectedDirectLogin', {cardReference:this.cardReference(), directLoginReference:directLoginReference}); | ||
157 | } | ||
158 | }, | ||
159 | |||
160 | //========================================================================= | ||
161 | |||
162 | __syntaxFix__: "syntax fix" | ||
163 | }); | ||
diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js deleted file mode 100644 index 5341878..0000000 --- a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js +++ b/dev/null | |||
@@ -1,178 +0,0 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz Community Edition. | ||
6 | Clipperz Community Edition is an online password manager. | ||
7 | For further information about its features and functionalities please | ||
8 | refer to http://www.clipperz.com. | ||
9 | |||
10 | * Clipperz Community Edition is free software: you can redistribute | ||
11 | it and/or modify it under the terms of the GNU Affero General Public | ||
12 | License as published by the Free Software Foundation, either version | ||
13 | 3 of the License, or (at your option) any later version. | ||
14 | |||
15 | * Clipperz Community Edition is distributed in the hope that it will | ||
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
18 | See the GNU Affero General Public License for more details. | ||
19 | |||
20 | * You should have received a copy of the GNU Affero General Public | ||
21 | License along with Clipperz Community Edition. If not, see | ||
22 | <http://www.gnu.org/licenses/>. | ||
23 | |||
24 | */ | ||
25 | |||
26 | Clipperz.Base.module('Clipperz.PM.UI.iPhone.Components'); | ||
27 | |||
28 | Clipperz.PM.UI.iPhone.Components.LoginForm = function(args) { | ||
29 | args = args || {}; | ||
30 | |||
31 | Clipperz.PM.UI.iPhone.Components.LoginForm.superclass.constructor.apply(this, arguments); | ||
32 | |||
33 | return this; | ||
34 | } | ||
35 | |||
36 | //============================================================================= | ||
37 | |||
38 | Clipperz.Base.extend(Clipperz.PM.UI.iPhone.Components.LoginForm, Clipperz.PM.UI.Common.Components.BaseComponent, { | ||
39 | |||
40 | //------------------------------------------------------------------------- | ||
41 | |||
42 | 'toString': function () { | ||
43 | return "Clipperz.PM.UI.iPhone.Components.LoginForm component"; | ||
44 | }, | ||
45 | |||
46 | //------------------------------------------------------------------------- | ||
47 | |||
48 | 'focusOnUsername': function () { | ||
49 | this.getElement('username').focus(); | ||
50 | }, | ||
51 | |||
52 | //------------------------------------------------------------------------- | ||
53 | |||
54 | 'username': function () { | ||
55 | return this.getElement('username').value; | ||
56 | }, | ||
57 | |||
58 | 'passphrase': function () { | ||
59 | return this.getElement('passphrase').value; | ||
60 | }, | ||
61 | |||
62 | //------------------------------------------------------------------------- | ||
63 | |||
64 | 'renderSelf': function(/*aContainer, aPosition*/) { | ||
65 | this.append(this.element(), [ | ||
66 | {tag:'div', cls:'toolbar iPhoneClipperzToolbar', children:[ | ||
67 | {tag:'h1', id:'pageTitle', html:'Clipperz'}, | ||
68 | {tag:'a', id:'backButton', cls:'button', href:'#', html:"back"} | ||
69 | ]}, | ||
70 | {tag:'form', title:'Theaters', cls:'panel toolbarlessPanel loginForm', id:this.getId('loginFormPanel'), children:[ | ||
71 | {tag:'fieldset', id:this.getId('fieldset'), children:[ | ||
72 | {tag:'div', cls:'row', children:[ | ||
73 | {tag:'label', html:"username"}, | ||
74 | {tag:'input', type:'text', name:'username', value:"", autocorrect:'off', autocapitalize:'off', id:this.getId('username')} | ||
75 | ]}, | ||
76 | {tag:'div', cls:'row', children:[ | ||
77 | {tag:'label', html:"passphrase"}, | ||
78 | {tag:'input', type:'password', name:'passphrase', value:"", id:this.getId('passphrase')} | ||
79 | ]} | ||
80 | ]}, | ||
81 | {tag:'a', cls:'whiteButton', type:'submit', href:'#', html:"Login", id:this.getId('submit')} | ||
82 | ]}, | ||
83 | {tag:'div', cls:'panel toolbarlessPanel loginProgressPanel', id:this.getId('loginProgressPanel'), children:[ | ||
84 | {tag:'div', id:this.getId('progressBar')} //, | ||
85 | // {tag:'a', cls:'whiteButton', type:'submit', href:'#', html:"Cancel", id:this.getId('cancel')} | ||
86 | ]}, | ||
87 | {tag:'div', cls:'panel loginErrorPanel', id:this.getId('loginErrorPanel'), children:[ | ||
88 | {tag:'div', cls:'errorMessage', id:this.getId('errorMessageBox'), children:[ | ||
89 | {tag:'h2', id:this.getId('errorMessage'), html:"Login failed"} | ||
90 | ]} | ||
91 | ]} | ||
92 | ]); | ||
93 | |||
94 | MochiKit.Signal.connect(this.getElement('submit'), 'onclick',this, 'submitHandler'); | ||
95 | MochiKit.Signal.connect(this.getElement('loginFormPanel'), 'onsubmit',this, 'submitHandler'); | ||
96 | |||
97 | // MochiKit.Signal.connect(this.getElement('cancel'), 'onclick',this, 'cancelHandler'); | ||
98 | MochiKit.Signal.connect('backButton', 'onclick',this, 'backHandler'); | ||
99 | |||
100 | this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')})); | ||
101 | |||
102 | // MochiKit.Style.hideElement(this.getElement('errorMessage')); | ||
103 | |||
104 | this.showLoginForm(); | ||
105 | // MochiKit.Async.callLater(0.2, MochiKit.Base.method(this, 'focusOnUsername')); | ||
106 | }, | ||
107 | |||
108 | //------------------------------------------------------------------------- | ||
109 | |||
110 | 'showLoginForm': function () { | ||
111 | MochiKit.Style.showElement(this.getElement('loginFormPanel')); | ||
112 | MochiKit.Style.hideElement(this.getElement('loginProgressPanel')); | ||
113 | MochiKit.Style.hideElement(this.getElement('loginErrorPanel')); | ||
114 | MochiKit.Style.hideElement('backButton'); | ||
115 | }, | ||
116 | |||
117 | 'slideInLoginForm': function () { | ||
118 | varoffset; | ||
119 | |||
120 | offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480); | ||
121 | |||
122 | MochiKit.Style.showElement(this.getElement('loginFormPanel')); | ||
123 | MochiKit.Style.setElementPosition(this.getElement('loginFormPanel'), {x:-offset, y:0}); | ||
124 | |||
125 | new MochiKit.Visual.Sequence([ | ||
126 | new MochiKit.Visual.Parallel([ | ||
127 | new MochiKit.Visual.Move(this.getElement('loginErrorPanel'), {x:offset, y:0, mode:'relative',transition:MochiKit.Visual.Transitions.linear, sync:true}), | ||
128 | new MochiKit.Visual.Move(this.getElement('loginFormPanel'), {x:0, y:0, mode:'absolute',transition:MochiKit.Visual.Transitions.linear, sync:true}), | ||
129 | MochiKit.Visual.fade ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true}) | ||
130 | ], {duration:0.5, sync:true}), | ||
131 | MochiKit.Visual.fade(this.getElement('loginErrorPanel'), {duration:0, sync:true}) | ||
132 | ], {}) | ||
133 | }, | ||
134 | |||
135 | 'showLoginProgress': function () { | ||
136 | MochiKit.Style.hideElement(this.getElement('loginFormPanel')); | ||
137 | MochiKit.Style.showElement(this.getElement('loginProgressPanel')); | ||
138 | }, | ||
139 | |||
140 | 'showLoginError': function (anError) { | ||
141 | this.getElement('errorMessage').innerHTML = "Login error"; | ||
142 | |||
143 | MochiKit.Style.showElement('backButton'); | ||
144 | MochiKit.Style.hideElement(this.getElement('loginProgressPanel')); | ||
145 | MochiKit.Style.showElement(this.getElement('loginErrorPanel')); | ||
146 | MochiKit.Style.setElementPosition(this.getElement('loginErrorPanel'), {x:0, y:45}); | ||
147 | }, | ||
148 | |||
149 | //------------------------------------------------------------------------- | ||
150 | /* | ||
151 | 'disableCancelButton': function () { | ||
152 | MochiKit.DOM.hideElement(this.getElement('cancel')); | ||
153 | }, | ||
154 | */ | ||
155 | //------------------------------------------------------------------------- | ||
156 | |||
157 | 'submitHandler': function (anEvent) { | ||
158 | anEvent.preventDefault(); | ||
159 | |||
160 | MochiKit.Signal.signal(this, 'doLogin', {'username':this.username(), 'passphrase':this.passphrase()}); | ||
161 | }, | ||
162 | |||
163 | 'cancelHandler': function (anEvent) { | ||
164 | anEvent.preventDefault(); | ||
165 | |||
166 | //console.log("CANCEL"); | ||
167 | }, | ||
168 | |||
169 | 'backHandler': function (anEvent) { | ||
170 | anEvent.preventDefault(); | ||
171 | |||
172 | this.slideInLoginForm(); | ||
173 | }, | ||
174 | |||
175 | //------------------------------------------------------------------------- | ||
176 | |||
177 | __syntaxFix__: "syntax fix" | ||
178 | }); | ||
diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js deleted file mode 100644 index 3fcaae1..0000000 --- a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js +++ b/dev/null | |||
@@ -1,369 +0,0 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz Community Edition. | ||
6 | Clipperz Community Edition is an online password manager. | ||
7 | For further information about its features and functionalities please | ||
8 | refer to http://www.clipperz.com. | ||
9 | |||
10 | * Clipperz Community Edition is free software: you can redistribute | ||
11 | it and/or modify it under the terms of the GNU Affero General Public | ||
12 | License as published by the Free Software Foundation, either version | ||
13 | 3 of the License, or (at your option) any later version. | ||
14 | |||
15 | * Clipperz Community Edition is distributed in the hope that it will | ||
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
18 | See the GNU Affero General Public License for more details. | ||
19 | |||
20 | * You should have received a copy of the GNU Affero General Public | ||
21 | License along with Clipperz Community Edition. If not, see | ||
22 | <http://www.gnu.org/licenses/>. | ||
23 | |||
24 | */ | ||
25 | |||
26 | Clipperz.Base.module('Clipperz.PM.UI.iPhone.Controllers'); | ||
27 | |||
28 | //Some parts of this controller have been derived from the iUI library. | ||
29 | |||
30 | Clipperz.PM.UI.iPhone.Controllers.MainController = function() { | ||
31 | this._loginForm = null; | ||
32 | this._cardList = null; | ||
33 | this._cachedValues =null; | ||
34 | this._user = null; | ||
35 | |||
36 | if (typeof window.onorientationchange == 'object') { | ||
37 | MochiKit.Signal.connect(window, 'onorientationchange', this, 'orientationChangeHandler'); | ||
38 | MochiKit.Async.callLater(0, MochiKit.Base.method(this, 'orientationChangeHandler')); | ||
39 | } else { | ||
40 | this.setOrientation('portrait'); | ||
41 | // this.setOrientation('landscape'); | ||
42 | } | ||
43 | |||
44 | this.addMetaTag('viewport', 'width=devicewidth; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;'); | ||
45 | this.addMetaTag('apple-mobile-web-app-capable', 'yes'); | ||
46 | this.addMetaTag('apple-mobile-web-app-status-bar-style', 'black'); | ||
47 | |||
48 | this.addLinkTag('apple-touch-icon', 'data:image/png;charset=utf-8;base64,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'); | ||
49 | //this.addLinkTag('apple-touch-startup-image', 'default.png'); | ||
50 | |||
51 | // if (!window.navigator.standalone)// not running as an installed app | ||
52 | |||
53 | MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'selectedDirectLogin', this, 'selectedDirectLoginHandler'); | ||
54 | |||
55 | MochiKit.DOM.addElementClass(document.body, 'iPhone'); | ||
56 | return this; | ||
57 | } | ||
58 | |||
59 | MochiKit.Base.update(Clipperz.PM.UI.iPhone.Controllers.MainController.prototype, { | ||
60 | |||
61 | 'toString': function () { | ||
62 | return "Clipperz.PM.UI.iPhone.Controllers.MainController"; | ||
63 | }, | ||
64 | |||
65 | //========================================================================= | ||
66 | |||
67 | 'user': function () { | ||
68 | return this._user; | ||
69 | }, | ||
70 | |||
71 | 'setUser': function (aValue) { | ||
72 | this._user = aValue; | ||
73 | }, | ||
74 | |||
75 | //========================================================================= | ||
76 | |||
77 | 'loginForm': function() { | ||
78 | if (this._loginForm == null) { | ||
79 | MochiKit.DOM.removeElement('mainDiv'); | ||
80 | this._loginForm = new Clipperz.PM.UI.iPhone.Components.LoginForm({element:MochiKit.DOM.currentDocument().body}); | ||
81 | MochiKit.Signal.connect(this._loginForm, 'doLogin', this, 'doLoginHandler') | ||
82 | } | ||
83 | |||
84 | return this._loginForm; | ||
85 | }, | ||
86 | |||
87 | 'removeLoginForm': function () { | ||
88 | if (this._loginForm != null) { | ||
89 | this._loginForm.remove(); | ||
90 | this._loginForm = null; | ||
91 | } | ||
92 | }, | ||
93 | |||
94 | //----------------------------------------------------------------------------- | ||
95 | |||
96 | 'cardList': function () { | ||
97 | if (this._cardList == null) { | ||
98 | this._cardList = new Clipperz.PM.UI.iPhone.Components.CardList({element:MochiKit.DOM.currentDocument().body}); | ||
99 | MochiKit.Signal.connect(this._cardList, 'searchEvent',this, 'searchEventHandler') | ||
100 | MochiKit.Signal.connect(this._cardList, 'selectedCard',this, 'selecetedCardHandler') | ||
101 | } | ||
102 | |||
103 | return this._cardList; | ||
104 | }, | ||
105 | |||
106 | //========================================================================= | ||
107 | |||
108 | 'currentWidth': function () { | ||
109 | return this._currentWidth; | ||
110 | }, | ||
111 | |||
112 | 'setCurrentWidth': function (aValue) { | ||
113 | this._currentWidth = aValue; | ||
114 | }, | ||
115 | |||
116 | //========================================================================= | ||
117 | |||
118 | 'orientationChangeHandler': function () { | ||
119 | switch(window.orientation) { | ||
120 | case 0: | ||
121 | this.setOrientation('portrait'); | ||
122 | break; | ||
123 | case 90: | ||
124 | case -90: | ||
125 | this.setOrientation('landscape'); | ||
126 | break; | ||
127 | } | ||
128 | }, | ||
129 | |||
130 | //------------------------------------------------------------------------- | ||
131 | |||
132 | 'setOrientation': function (anOrientation) { | ||
133 | document.body.setAttribute('orientation', anOrientation); | ||
134 | setTimeout(scrollTo, 100, 0, 1); | ||
135 | }, | ||
136 | |||
137 | //------------------------------------------------------------------------- | ||
138 | |||
139 | 'slidePages': function (fromPage, toPage, backwards) { | ||
140 | var axis; | ||
141 | var slideDone; | ||
142 | |||
143 | slideDone = function () { | ||
144 | // console.log("slideDone"); | ||
145 | if (!hasClass(toPage, "dialog")) { | ||
146 | fromPage.removeAttribute("selected"); | ||
147 | } | ||
148 | checkTimer = setInterval(checkOrientAndLocation, 300); | ||
149 | setTimeout(updatePage, 0, toPage, fromPage); | ||
150 | fromPage.removeEventListener('webkitTransitionEnd', slideDone, false); | ||
151 | } | ||
152 | |||
153 | axis = (backwards ? fromPage : toPage).getAttribute("axis"); | ||
154 | |||
155 | clearInterval(checkTimer); | ||
156 | |||
157 | if (canDoSlideAnim() && axis != 'y') { | ||
158 | slide2(fromPage, toPage, backwards, slideDone); | ||
159 | } else { | ||
160 | slide1(fromPage, toPage, backwards, axis, slideDone); | ||
161 | } | ||
162 | }, | ||
163 | |||
164 | //------------------------------------------------------------------------- | ||
165 | |||
166 | 'getCachedValues': function () { | ||
167 | var deferredResult; | ||
168 | |||
169 | if (this._cachedObjects != null) { | ||
170 | deferredResult = MochiKit.Async.succeed(this._cachedObjects); | ||
171 | } else { | ||
172 | deferredResult = new Clipperz.Async.Deferred("MainController.getCachedValues", {trace:false}); | ||
173 | deferredResult.addMethod(this.user(), 'getRecords'); | ||
174 | deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("MainController.getCachedValues - collectResults", { | ||
175 | '_rowObject': MochiKit.Async.succeed, | ||
176 | '_reference': MochiKit.Base.methodcaller('reference'), | ||
177 | 'label': MochiKit.Base.methodcaller('label'), | ||
178 | 'favicon': MochiKit.Base.methodcaller('favicon'), | ||
179 | '_searchableContent':MochiKit.Base.methodcaller('searchableContent') | ||
180 | }, {trace:false})); | ||
181 | deferredResult.addCallback(Clipperz.Async.collectAll); | ||
182 | deferredResult.addCallback(MochiKit.Base.bind(function (someRows) { | ||
183 | this._cachedObjects = someRows; | ||
184 | return this._cachedObjects; | ||
185 | }, this)); | ||
186 | deferredResult.callback(); | ||
187 | } | ||
188 | |||
189 | return deferredResult; | ||
190 | }, | ||
191 | //========================================================================= | ||
192 | |||
193 | 'run': function(shouldShowRegistrationForm) { | ||
194 | this.loginForm().render(); | ||
195 | MochiKit.Async.callLater(1, MochiKit.Base.method(this.loginForm(), 'focusOnUsername')); | ||
196 | }, | ||
197 | |||
198 | //========================================================================= | ||
199 | |||
200 | 'doLoginHandler': function (someArgs) { | ||
201 | var deferredResult; | ||
202 | varparameters; | ||
203 | varshouldUseOTP; | ||
204 | // var loginProgress; | ||
205 | varuser; | ||
206 | var getPassphraseDelegate; | ||
207 | |||
208 | parameters = someArgs; | ||
209 | shouldUseOTP = (typeof(parameters.passphrase) == 'undefined'); | ||
210 | |||
211 | getPassphraseDelegate = MochiKit.Base.partial(MochiKit.Async.succeed, parameters.passphrase); | ||
212 | user = new Clipperz.PM.DataModel.User({'username':parameters.username, 'getPassphraseFunction':getPassphraseDelegate}); | ||
213 | |||
214 | deferredResult = new Clipperz.Async.Deferred("MainController.doLogin", {trace:false}); | ||
215 | deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':4}); | ||
216 | deferredResult.addMethod(this.loginForm(), 'showLoginProgress'); | ||
217 | deferredResult.addCallback(MochiKit.Async.wait, 0.1); | ||
218 | deferredResult.addMethod(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'deferredEntropyCollection'); | ||
219 | deferredResult.addMethod(user, 'login'); | ||
220 | deferredResult.addMethod(this, 'setUser', user); | ||
221 | deferredResult.addMethod(user, 'getRecords'); | ||
222 | deferredResult.addMethod(this, 'removeLoginForm'); | ||
223 | deferredResult.addMethod(this.cardList(), 'render'); | ||
224 | deferredResult.addMethod(this, 'displaySelectedRecords', ''); | ||
225 | deferredResult.addErrback(MochiKit.Base.method(this.loginForm(), 'showLoginError')); | ||
226 | deferredResult.callback(); | ||
227 | |||
228 | return deferredResult; | ||
229 | }, | ||
230 | |||
231 | //========================================================================= | ||
232 | |||
233 | 'searchEventHandler': function (aValue) { | ||
234 | //console.log("searching for ... " + aValue); | ||
235 | return this.displaySelectedRecords(aValue); | ||
236 | }, | ||
237 | |||
238 | //========================================================================= | ||
239 | |||
240 | '_displaySelectedRows': function (aFilter, someRows) { | ||
241 | var result; | ||
242 | |||
243 | result = someRows; | ||
244 | |||
245 | if (aFilter != null) { | ||
246 | var filter; | ||
247 | varfilterRegExp; | ||
248 | |||
249 | filter = aFilter.replace(/[^A-Za-z0-9]/g, "\\$&"); | ||
250 | filterRegExp = new RegExp(filter, "i"); | ||
251 | result = MochiKit.Base.filter(function (aCachedResult) { return filterRegExp.test(aCachedResult['_searchableContent'])}, result); | ||
252 | } | ||
253 | |||
254 | |||
255 | result.sort(MochiKit.Base.partial(function (aKey, aComparator, aObject, bObject) { | ||
256 | return aComparator(aObject[aKey], bObject[aKey]); | ||
257 | }, 'label', Clipperz.Base.caseInsensitiveCompare)); | ||
258 | |||
259 | this.cardList().update(result); | ||
260 | }, | ||
261 | |||
262 | //------------------------------------------------------------------------- | ||
263 | |||
264 | 'displaySelectedRecords': function (aFilter) { | ||
265 | return Clipperz.Async.callbacks("MainController.displaySelectedrows", [ | ||
266 | MochiKit.Base.method(this, 'getCachedValues'), | ||
267 | MochiKit.Base.method(this, '_displaySelectedRows', aFilter) | ||
268 | ], {trace:false}); | ||
269 | }, | ||
270 | |||
271 | //========================================================================= | ||
272 | |||
273 | 'selecetedCardHandler': function (aRecordReference) { | ||
274 | vardeferredResult; | ||
275 | varrecordData; | ||
276 | |||
277 | recordData = {}; | ||
278 | //console.log("Showing detail for card with reference", aRecordReference); | ||
279 | deferredResult = new Clipperz.Async.Deferred("MainController.selectedCardHandler", {trace:false}); | ||
280 | deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); | ||
281 | deferredResult.collectResults({ | ||
282 | '_reference':MochiKit.Base.methodcaller('reference'), | ||
283 | 'title': MochiKit.Base.methodcaller('label'), | ||
284 | 'favicon': MochiKit.Base.methodcaller('favicon') | ||
285 | }); | ||
286 | deferredResult.addCallback(function (someData) { | ||
287 | MochiKit.Base.update(recordData, someData); | ||
288 | }) | ||
289 | deferredResult.addMethod(this.cardList(), 'showCard', recordData); | ||
290 | |||
291 | deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); | ||
292 | deferredResult.addMethodcaller('notes'); | ||
293 | deferredResult.addCallback(function (someNotes) { | ||
294 | recordData['notes'] = someNotes; | ||
295 | }) | ||
296 | |||
297 | deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); | ||
298 | deferredResult.addMethodcaller('getCurrentRecordVersion'); | ||
299 | deferredResult.addMethodcaller('fields'); | ||
300 | deferredResult.addCallback(MochiKit.Base.values); | ||
301 | deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("MainController.selectedCardHandler - fields", { | ||
302 | 'label':MochiKit.Base.methodcaller('label'), | ||
303 | 'value':MochiKit.Base.methodcaller('value'), | ||
304 | 'isHidden':MochiKit.Base.methodcaller('isHidden') | ||
305 | }, {trace:false})); | ||
306 | deferredResult.addCallback(Clipperz.Async.collectAll); | ||
307 | deferredResult.addCallback(function (someData) { | ||
308 | recordData['fields'] = someData; | ||
309 | }); | ||
310 | |||
311 | deferredResult.addMethod(this.user(), 'getRecord', aRecordReference); | ||
312 | deferredResult.addMethodcaller('directLogins'); | ||
313 | deferredResult.addCallback(MochiKit.Base.values); | ||
314 | deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("MainController.selectedCardHandler - directLogins", { | ||
315 | 'label': MochiKit.Base.methodcaller('label'), | ||
316 | 'favicon': MochiKit.Base.methodcaller('favicon'), | ||
317 | '_reference':MochiKit.Base.methodcaller('reference') | ||
318 | }, {trace:false})); | ||
319 | deferredResult.addCallback(Clipperz.Async.collectAll); | ||
320 | deferredResult.addCallback(function (someData) { | ||
321 | recordData['directLogins'] = someData; | ||
322 | }); | ||
323 | |||
324 | deferredResult.addMethod(this.cardList(), 'showCardDetails', recordData); | ||
325 | deferredResult.callback(); | ||
326 | |||
327 | return deferredResult; | ||
328 | }, | ||
329 | |||
330 | //========================================================================= | ||
331 | |||
332 | 'selectedDirectLoginHandler': function (someData) { | ||
333 | vardeferredResult; | ||
334 | |||
335 | //console.log("<<< signal - directLogin"); | ||
336 | deferredResult = new Clipperz.Async.Deferred("MainController.selectedDirectLoginHandler", {trace:false}); | ||
337 | deferredResult.addMethod(this.user(), 'getRecord', someData['cardReference']); | ||
338 | deferredResult.addMethodcaller('directLogins'); | ||
339 | deferredResult.addCallback(MochiKit.Base.itemgetter(someData['directLoginReference'])); | ||
340 | // deferredResult.addMethodcaller('runDirectLogin'); | ||
341 | deferredResult.addCallback(Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.openDirectLogin); | ||
342 | deferredResult.callback(); | ||
343 | |||
344 | return deferredResult; | ||
345 | }, | ||
346 | |||
347 | //========================================================================= | ||
348 | |||
349 | 'addMetaTag': function (aName, aContent) { | ||
350 | varmetaTag; | ||
351 | |||
352 | metaTag = document.createElement('meta'); | ||
353 | metaTag.name = aName; | ||
354 | metaTag.content = aContent; | ||
355 | document.getElementsByTagName('head')[0].appendChild(metaTag); | ||
356 | }, | ||
357 | |||
358 | 'addLinkTag': function (aRel, anHref) { | ||
359 | var linkTag; | ||
360 | |||
361 | linkTag = document.createElement('link'); | ||
362 | linkTag.rel = aRel; | ||
363 | linkTag.href = anHref; | ||
364 | document.getElementsByTagName('head')[0].appendChild(linkTag); | ||
365 | }, | ||
366 | |||
367 | //========================================================================= | ||
368 | __syntaxFix__: "syntax fix" | ||
369 | }); \ No newline at end of file | ||