summaryrefslogtreecommitdiff
path: root/frontend/delta/js/Clipperz/PM/DataModel/Record.js
Unidiff
Diffstat (limited to 'frontend/delta/js/Clipperz/PM/DataModel/Record.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/Clipperz/PM/DataModel/Record.js891
1 files changed, 891 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/PM/DataModel/Record.js b/frontend/delta/js/Clipperz/PM/DataModel/Record.js
new file mode 100644
index 0000000..379872a
--- a/dev/null
+++ b/frontend/delta/js/Clipperz/PM/DataModel/Record.js
@@ -0,0 +1,891 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
26if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
27
28
29Clipperz.PM.DataModel.Record = function(args) {
30 Clipperz.PM.DataModel.Record.superclass.constructor.apply(this, arguments);
31
32 this._updateDate = (args.updateDate ? Clipperz.PM.Date.parse(args.updateDate) : Clipperz.Base.exception.raise('MandatoryParameter'));
33
34 this._retrieveIndexDataFunction = args.retrieveIndexDataFunction|| Clipperz.Base.exception.raise('MandatoryParameter');
35 this._updateIndexDataFunction = args.updateIndexDataFunction || Clipperz.Base.exception.raise('MandatoryParameter');
36
37 this._retrieveDirectLoginIndexDataFunction = args.retrieveDirectLoginIndexDataFunction|| null;
38 this._setDirectLoginIndexDataFunction = args.setDirectLoginIndexDataFunction || null;
39 this._removeDirectLoginIndexDataFunction = args.removeDirectLoginIndexDataFunction|| null;
40
41 this._createNewDirectLoginFunction = args.createNewDirectLoginFunction || null;
42
43 this._directLogins = {};
44
45 this._versions = {};
46
47 this._currentRecordVersion = null;
48 if (this.isBrandNew()) {
49 var newVersion;
50
51 this.setNotes('');
52 newVersion = new Clipperz.PM.DataModel.Record.Version({
53 'retrieveKeyFunction':MochiKit.Base.method(this, 'getVersionKey'),
54 'getVersion': MochiKit.Base.method(this, 'getVersion')
55
56 });
57 this._versions[newVersion.reference()] = newVersion;
58 this._currentVersionReference = newVersion.reference();
59 // this.setLabel('');
60 }
61
62 return this;
63}
64
65
66Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.EncryptedRemoteObject, {
67
68 'toString': function() {
69 return "Record (" + this.reference() + ")";
70 },
71
72 //-------------------------------------------------------------------------
73
74 'reference': function () {
75 return this._reference;
76 },
77
78 //=========================================================================
79
80 'getIndexData': function () {
81 return this._retrieveIndexDataFunction(this.reference());
82 },
83
84 //.........................................................................
85
86 'getIndexDataForKey': function (aKey) {
87 return Clipperz.Async.callbacks("Record.getIndexDataForKey", [
88 MochiKit.Base.method(this, 'getIndexData'),
89 MochiKit.Base.itemgetter(aKey)
90 ], {trace:false});
91 },
92
93 //-------------------------------------------------------------------------
94
95 'setIndexDataForKey': function (aKey, aValue) {
96 // return this._updateIndexDataFunction(this.reference(), aKey, aValue);
97
98 var deferredResult;
99
100 deferredResult = new Clipperz.Async.Deferred("Record.setIndexDataForKey", {trace:false});
101 deferredResult.addMethod(this, 'getIndexDataForKey', aKey);
102 deferredResult.addCallback(MochiKit.Base.bind(function (aCurrentValue) {
103 var result;
104 var originalValue;
105
106 originalValue = this.transientState().getValue('originalValues.indexData.' + aKey);
107 if (originalValue == null) {
108 originalValue = this.transientState().setValue('originalValues.indexData.' + aKey, aCurrentValue);
109 }
110
111 if (aCurrentValue != aValue) {
112 if (originalValue != aValue) {
113 this.transientState().setValue('hasPendingChanges.indexData.' + aKey, true);
114 } else {
115 this.transientState().setValue('hasPendingChanges.indexData.' + aKey, false);
116 }
117
118 result = this._updateIndexDataFunction(this.reference(), aKey, aValue);
119 } else {
120 result = MochiKit.Async.succeed(aValue);
121 }
122
123 return result;
124 }, this));
125
126 deferredResult.callback();
127
128 return deferredResult;
129 },
130
131 //=========================================================================
132/*
133 'key': function () {
134 return this.getIndexDataForKey('key');
135 },
136*/
137 //=========================================================================
138
139 'label': function () {
140 return this.getIndexDataForKey('label');
141 },
142
143 //.........................................................................
144
145 'setLabel': function (aValue) {
146 return this.setIndexDataForKey('label', aValue);
147 },
148
149 //=========================================================================
150
151 'headerNotes': function () {
152 return this.getIndexDataForKey('notes');
153 },
154
155 //-------------------------------------------------------------------------
156
157 'notes': function () {
158 return Clipperz.Async.callbacks("Record.notes", [
159 MochiKit.Base.method(this, 'headerNotes'),
160 MochiKit.Base.bind(function (someHeaderNotes) {
161 var result;
162
163 if ((someHeaderNotes == null) || (typeof(someHeaderNotes) == 'undefined')) {
164 result = this.getValue('notes');
165 } else {
166 result = MochiKit.Async.succeed(someHeaderNotes);
167 }
168
169 return result;
170 }, this)
171 ], {trace:false});
172 },
173
174 //.........................................................................
175
176 'setNotes': function (aValue) {
177 return this.setValue('notes', aValue);
178 },
179
180 //=========================================================================
181
182 'updateDate': function () {
183 return MochiKit.Async.succeed(this._updateDate);
184 },
185
186 //=========================================================================
187
188 'favicon': function () {
189 var result;
190 var directLogins;
191
192 directLogins = MochiKit.Base.values(this.directLogins());
193 if (directLogins.length > 0) {
194 result = directLogins[0].favicon();
195 // } else if (/* is there an URL to use for searching a favicon */){
196 } else {
197 result = null; //MochiKit.Async.succeed(Clipperz.PM.Strings['defaultFaviconUrl']);
198 }
199
200 return result;
201 },
202
203 //-------------------------------------------------------------------------
204
205 'searchableContent': function () {
206 var deferredResult;
207
208 deferredResult = new Clipperz.Async.Deferred("Record.searchableContent", {trace:false});
209
210 deferredResult.collectResults({
211 'recordLabel': MochiKit.Base.method(this, 'label'),
212 'directLoginLabels': [
213 MochiKit.Base.method(this, 'directLoginReferences'),
214 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.itemgetter('label'))
215 ]
216 })
217 deferredResult.addCallback(function (someValues) {
218 return someValues['recordLabel'] + ' ' + someValues['directLoginLabels'].join(' ');
219 });
220 deferredResult.callback();
221
222 return deferredResult;
223 },
224
225 //-------------------------------------------------------------------------
226
227 'isMatching': function (aRegExp) {
228 return Clipperz.Async.callbacks("deferredFilterFunction", [
229 MochiKit.Base.method(this, 'searchableContent'),
230 MochiKit.Base.method(aRegExp, 'test'),
231 function (doesItMatch) {
232 var result;
233
234 if (doesItMatch) {
235 result = MochiKit.Async.succeed('match');
236 } else {
237 result = MochiKit.Async.fail('miss');
238 }
239
240 return result;
241 }
242 ], {trace:false});
243 },
244
245 //=========================================================================
246
247 'content': function () {
248 var deferredResult;
249 varresult;
250
251 result = {
252 'fields': [],
253 'directLogins': []
254 };
255
256 deferredResult = new Clipperz.Async.Deferred("Record.content", {trace:false});
257 deferredResult.addMethod(this, 'reference');
258 deferredResult.addCallback(function (aValue) { result['reference'] = aValue; });
259 deferredResult.addMethod(this, 'label');
260 deferredResult.addCallback(function (aValue) { result['title'] = aValue; });
261 deferredResult.addMethod(this, 'notes');
262 deferredResult.addCallback(function (aValue) { result['notes'] = aValue; });
263
264 deferredResult.addMethod(this, 'fields');
265 deferredResult.addCallback(MochiKit.Base.values);
266 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.methodcaller('content'));
267 deferredResult.addCallback(Clipperz.Async.collectAll);
268 deferredResult.addCallback(MochiKit.Base.map, function (aValue) { result['fields'].push(aValue); });
269
270 deferredResult.addMethod(this, 'directLogins');
271 deferredResult.addCallback(MochiKit.Base.values);
272 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.methodcaller('content'));
273 deferredResult.addCallback(Clipperz.Async.collectAll);
274 deferredResult.addCallback(MochiKit.Base.map, function (aValue) { result['directLogins'].push(aValue); });
275 deferredResult.addCallback(function () { return result; });
276
277 deferredResult.callback();
278
279 return deferredResult;
280 },
281
282 //=========================================================================
283
284 'directLogins': function () {
285 return this._directLogins;
286 },
287
288 'addDirectLogin': function (aDirectLogin) {
289 this._directLogins[aDirectLogin.reference()] = aDirectLogin;
290 },
291
292 'directLoginWithReference': function (aDirectLoginReference) {
293 return this._directLogins[aDirectLoginReference];
294 },
295
296 'createNewDirectLoginFunction': function () {
297 return this._createNewDirectLoginFunction;
298 },
299
300 'saveOriginalDirectLoginStatusToTransientState': function () {
301 if (this.transientState().getValue('directLogins') == null) {
302 // this.transientState().setValue('directLogins', this._directLogins)
303 MochiKit.Iter.forEach(MochiKit.Base.keys(this._directLogins), MochiKit.Base.bind(function(aKey) {
304 this.transientState().setValue('directLogins' + '.' + aKey, this._directLogins[aKey])
305 }, this))
306 }
307 },
308
309 'createNewDirectLogin': function () {
310 this.saveOriginalDirectLoginStatusToTransientState();
311
312 return this.createNewDirectLoginFunction()(this);
313 },
314
315 'removeDirectLogin': function(aDirectLogin) {
316 this.saveOriginalDirectLoginStatusToTransientState();
317
318 return Clipperz.Async.callbacks("Record.removeDirectLogin", [
319 MochiKit.Base.method(this, 'removeValue', 'directLogins' + '.' + aDirectLogin.reference()),
320 MochiKit.Base.bind(function () {
321 delete this._directLogins[aDirectLogin.reference()]
322 }, this)
323 ], {trace:false});
324
325 },
326
327 'directLoginReferences': function () {
328 var result;
329
330 result = Clipperz.Async.callbacks("Record.directLoginReferences", [
331 MochiKit.Base.method(this, 'directLogins'),
332 MochiKit.Base.values,
333 function (someDirectLogins) {
334 var result;
335 var i,c;
336
337 result = [];
338 c = someDirectLogins.length;
339 for (i=0; i<c; i++) {
340 result.push(Clipperz.Async.collectResults("Record.directLoginReferences - collectResults", {
341 '_rowObject': MochiKit.Async.succeed,
342 '_reference': MochiKit.Base.methodcaller('reference'),
343 'label': MochiKit.Base.methodcaller('label'),
344 'favicon': MochiKit.Base.methodcaller('favicon')
345 }, {trace:false})(someDirectLogins[i]));
346 };
347
348 return result;
349 },
350 Clipperz.Async.collectAll
351 ], {trace:false});
352
353 return result;
354 },
355
356 //=========================================================================
357
358 'unpackRemoteData': function (someData) {
359 var result;
360
361/*
362 this._currentRecordVersion = new Clipperz.PM.DataModel.Record.Version({
363 'reference': someData['currentVersion']['reference'],
364 'retrieveKeyFunction': MochiKit.Base.method(this, 'getCurrentRecordVersionKey'),
365 'remoteData': someData['currentVersion'],
366 });
367*/
368 var versionKey;
369
370 for (versionKey in someData['versions']) {
371 this._versions[versionKey] = new Clipperz.PM.DataModel.Record.Version({
372 'reference': versionKey,
373 'retrieveKeyFunction':MochiKit.Base.method(this, 'getVersionKey'),
374 'remoteData': someData['versions'][versionKey],
375 'getVersion': MochiKit.Base.method(this, 'getVersion')
376 })
377 }
378
379 // this._currentVersionReference = someData['currentVersion']['reference'];
380 this._currentVersionReference = someData['currentVersion'];
381
382 result = Clipperz.PM.DataModel.Record.superclass.unpackRemoteData.apply(this, arguments);
383
384 return result;
385 },
386
387 //-------------------------------------------------------------------------
388
389 'unpackData': function (someData) {
390 var result;
391
392 result = Clipperz.PM.DataModel.Record.superclass.unpackData.apply(this, arguments);
393
394 if (MochiKit.Base.isUndefinedOrNull(result['notes'])) {
395 result['notes'] = ''
396 }
397
398 return result;
399 },
400
401 //-------------------------------------------------------------------------
402
403 'prepareRemoteDataWithKey': function (aKey) {
404 var deferredResult;
405 varnewVersionKey;
406 var result;
407
408 newVersionKey = Clipperz.PM.Crypto.randomKey();
409 result = {};
410
411 deferredResult = new Clipperz.Async.Deferred("Record.prepareRemoteDataWithKey", {trace:false});
412 deferredResult.addCallbackList([
413 Clipperz.Async.collectResults("Record.prepareRemoteDataWithKey - collect results", {
414 'isBrandNew': MochiKit.Base.method(this, 'isBrandNew'),
415 'versionHasPendingChanges':[
416 // MochiKit.Base.method(this, 'getCurrentRecordVersion'),
417 // MochiKit.Base.methodcaller('hasPendingChanges')
418 MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'hasPendingChanges')
419 ]
420 }),
421 Clipperz.Async.or,
422
423 Clipperz.Async.deferredIf("Current Version has pending changes", [
424 MochiKit.Base.method(this, 'createNewRecordVersion'),
425 MochiKit.Base.methodcaller('prepareRemoteDataWithKey', newVersionKey),
426 MochiKit.Base.partial(Clipperz.Async.setItem, result, 'currentRecordVersion'),
427 MochiKit.Base.method(this, 'setCurrentRecordVersionKey', newVersionKey)
428 ], []),
429
430 MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.prepareRemoteDataWithKey, this, aKey),
431 MochiKit.Base.partial(Clipperz.Async.setItem, result, 'record'),
432
433 MochiKit.Base.partial(MochiKit.Async.succeed, result)
434 ]);
435
436 deferredResult.callback();
437
438 return deferredResult;
439 },
440
441 //=========================================================================
442
443 'fields': function () {
444 return this.invokeCurrentRecordVersionMethod('fields');
445 },
446
447 'addField': function (someParameters) {
448 return this.invokeCurrentRecordVersionMethod('addField', someParameters);
449 },
450
451 'removeField': function (someParameters) {
452 return this.invokeCurrentRecordVersionMethod('removeField', someParameters);
453 },
454
455 //'sortFieldReference': function (someSortedFieldReferences) {
456 // return this.invokeCurrentRecordVersionMethod('sortFieldReference', someSortedFieldReferences);
457 //},
458
459 'getFieldsValues': function () {
460 return this.invokeCurrentRecordVersionMethod('getFieldsValues');
461 },
462
463 'fieldWithLabel': function (aLabel) {
464 return Clipperz.Async.callbacks("Record.fieldWithLabel", [
465 MochiKit.Base.method(this, 'fields'),
466 MochiKit.Base.values,
467 MochiKit.Base.partial(Clipperz.Async.deferredFilter, function (aField) {
468 return Clipperz.Async.callbacks("Record.fieldWithLabel - check field label", [
469 MochiKit.Base.methodcaller('label'),
470 MochiKit.Base.partial(MochiKit.Base.operator.eq, aLabel)
471 ], {trace:false}, aField);
472 }),
473 function (someFilteredResults) {
474 var result;
475
476 switch (someFilteredResults.length) {
477 case 0:
478 result = null;
479 break;
480 case 1:
481 result = someFilteredResults[0];
482 break;
483 default:
484 WTF = TODO;
485 break;
486 }
487
488 return result;
489 }
490 ], {trace:false});
491 },
492
493 //=========================================================================
494
495 'getVersion': function (aVersionReference) {
496 return Clipperz.Async.callbacks("Record.getVersion", [
497 MochiKit.Base.method(this, 'getVersions'),
498 MochiKit.Base.itemgetter(aVersionReference)
499 ], {trace:false});
500 },
501
502 //-------------------------------------------------------------------------
503
504 'getVersionKey': function (aVersionReference) {
505 vardeferredResult;
506 var transientStateKey;
507
508 transientStateKey = 'versionKeys' + '.' + aVersionReference;
509 if (this.transientState().getValue(transientStateKey) != null) {
510 deferredResult = MochiKit.Async.succeed(this.transientState().getValue(transientStateKey));
511 } else {
512 deferredResult = Clipperz.Async.callbacks("Record.getVersionKey", [
513 MochiKit.Base.method(this, 'getVersions'),
514 MochiKit.Base.partial(MochiKit.Base.operator.eq, aVersionReference, this.currentVersionReference()),
515 Clipperz.Async.deferredIf("getVersionKey for current version", [
516 MochiKit.Base.method(this, 'getCurrentRecordVersionKey'),
517 MochiKit.Base.method(this.transientState(), 'setValue', transientStateKey)
518 ],[
519 MochiKit.Async.fail
520 ])
521 ], {trace:false});
522 }
523
524 return deferredResult;
525 },
526
527 //-------------------------------------------------------------------------
528
529 'versions': function () {
530 return this._versions;
531 },
532
533 'getVersions': function () {
534 return Clipperz.Async.callbacks("Record.versions", [
535 MochiKit.Base.method(this, 'getValue', 'fakeKey, just to trigger unpackRemoteData'),
536 MochiKit.Base.bind(function () { return this._versions; }, this)
537 ], {trace:false});
538 },
539
540 //-------------------------------------------------------------------------
541
542 'getCurrentRecordVersion': function () {
543 return Clipperz.Async.callbacks("Record.getCurrentRecordVersion", [
544 // MochiKit.Base.method(this, 'getValue', 'fakeKey, just to trigger unpackRemoteData'),
545 // MochiKit.Base.bind(function () { return this._currentRecordVersion; }, this)
546
547 MochiKit.Base.method(this, 'versions'),
548 MochiKit.Base.itemgetter(this.currentVersionReference()),
549 Clipperz.Async.deferredIf("The current version is available", [
550 MochiKit.Async.succeed
551 ], [
552 MochiKit.Base.method(this, 'getVersions'),
553 MochiKit.Base.bind(function (someVersions) { return someVersions[this.currentVersionReference()]}, this)
554 ])
555 ], {trace:false});
556 },
557
558 'setCurrentRecordVersion': function (aRecordVersion) {
559 this._currentVersionReference = aRecordVersion.reference();
560 },
561
562 //.........................................................................
563
564 'currentVersionReference': function () {
565 return this._currentVersionReference;
566 },
567
568 //-------------------------------------------------------------------------
569
570 'createNewRecordVersion': function () {
571 var deferredResult;
572
573 if (this.isBrandNew()) {
574 deferredResult = this.getCurrentRecordVersion();
575 } else {
576 var newVersion;
577
578 newVersion = new Clipperz.PM.DataModel.Record.Version({
579 // 'reference': versionKey,
580 'retrieveKeyFunction':MochiKit.Base.method(this, 'getVersionKey'),
581 // 'remoteData': {},
582 'getVersion': MochiKit.Base.method(this, 'getVersion')
583 })
584 this._versions[newVersion.reference()] = newVersion;
585
586 deferredResult = Clipperz.Async.callbacks("Record.createNewRecordVersion", [
587 // MochiKit.Base.method(this, 'getCurrentRecordVersion'),
588 // MochiKit.Base.methodcaller('values'),
589 MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'values'),
590 MochiKit.Base.method(newVersion, 'setValues'),
591
592 Clipperz.Async.collectResults("Record.createNewRecordVersion [collect results]", {
593 'reference':MochiKit.Base.method(this, 'currentVersionReference'),
594 'key': MochiKit.Base.method(this, 'getCurrentRecordVersionKey')
595 }, {trace:false}),
596 MochiKit.Base.method(newVersion, 'setPreviousVersionReferenceAndKey'),
597
598 // MochiKit.Base.method(this, 'getCurrentRecordVersion'),
599 // MochiKit.Base.method(this, 'revertChanges'),
600 MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'revertChanges'),
601
602 MochiKit.Base.method(this, 'setCurrentRecordVersion', newVersion),
603 MochiKit.Base.partial(MochiKit.Async.succeed, newVersion)
604 ], {trace:false});
605 }
606
607 return deferredResult;
608 },
609
610 //-------------------------------------------------------------------------
611
612 'getCurrentRecordVersionKey': function () {
613 return Clipperz.Async.callbacks("Record.getCurrentRecordVersionKey", [
614 MochiKit.Base.method(this, 'getValue', 'currentVersionKey'),
615 Clipperz.Async.deferredIf("currentVersionKey is NOT null", [
616 MochiKit.Async.succeed
617 ], [
618 MochiKit.Base.method(this, 'getKey')
619 ])
620 ], {trace:false});
621 },
622
623 'setCurrentRecordVersionKey': function (aValue) {
624 //TODO: triple check this method!
625 return Clipperz.Async.callbacks("Record.setCurrentRecordVersionKey", [
626 MochiKit.Base.method(this, 'setValue', 'currentVersionKey', aValue)
627 ], {trace:false});
628 },
629
630 //-------------------------------------------------------------------------
631
632 'invokeCurrentRecordVersionMethod': function (aMethodName, someValues) {
633 return Clipperz.Async.callbacks("Record.invokeCurrentRecordVersionMethod", [
634 MochiKit.Base.method(this, 'getCurrentRecordVersion'),
635 MochiKit.Base.methodcaller(aMethodName, someValues)
636 ], {trace:false});
637 },
638
639
640 'lazilyinvokeCurrentRecordVersionMethod': function (aMethodName, someValues, defaultResult) {
641 return Clipperz.Async.callbacks("Record.lazilyinvokeCurrentRecordVersionMethod", [
642 MochiKit.Base.method(this, 'currentVersionReference'),
643 Clipperz.Async.deferredIf("versions has been loaded", [
644 MochiKit.Base.method(this, 'getCurrentRecordVersion'),
645 MochiKit.Base.methodcaller(aMethodName, someValues),
646 ], [
647 MochiKit.Base.partial(MochiKit.Async.succeed, defaultResult),
648 ])
649 ], {trace:false});
650 },
651
652 //=========================================================================
653
654 'hasPendingChanges': function () {
655 var deferredResult;
656
657 if (this.hasInitiatedObjectDataStore()) {
658 deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.hasPendingChanges", {trace:false});
659 deferredResult.collectResults({
660 'super': MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.hasPendingChanges, this),
661 'currentVersion': [
662 // MochiKit.Base.method(this, 'getCurrentRecordVersion'),
663 // MochiKit.Base.methodcaller('hasPendingChanges')
664 MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'hasPendingChanges')
665 ],
666 'directLogins': [
667 MochiKit.Base.method(this, 'directLogins'),
668 MochiKit.Base.values,
669 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasPendingChanges')),
670 Clipperz.Async.collectAll,
671 Clipperz.Async.or
672 // function(someValues) {
673 // return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
674 // }
675 ]
676 });
677 deferredResult.addCallback(MochiKit.Base.values);
678 deferredResult.addCallback(MochiKit.Base.bind(function(someValues) {
679 var result;
680 result = MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
681
682 if ((result == false) && (this.isBrandNew() == false)) {
683 result = MochiKit.Iter.some(MochiKit.Base.values(this.transientState().getValue('hasPendingChanges.indexData')), MochiKit.Base.operator.identity);
684 }
685
686 return result;
687 }, this));
688
689 deferredResult.callback();
690 } else {
691 deferredResult = Clipperz.Async.callbacks("Recrod.hasPendingChanges [hasInitiatedObjectDataStore == false]", [
692 MochiKit.Base.method(this, 'directLogins'),
693 MochiKit.Base.values,
694 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasPendingChanges')),
695 Clipperz.Async.collectAll,
696 Clipperz.Async.or
697 // function(someValues) {
698 // return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
699 // }
700 ], {trace:false})
701 }
702
703 return deferredResult;
704 },
705
706 //-------------------------------------------------------------------------
707
708 'hasPendingChangesWhenBrandNew': function () {
709 var deferredResult;
710
711 deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.hasPendingChangesWhenBrandNew", {trace:false});
712 deferredResult.collectResults({
713 'label': [
714 MochiKit.Base.method(this, 'label'),
715 MochiKit.Base.partial(MochiKit.Base.operator.ne, '')
716 ],
717 'notes': [
718 MochiKit.Base.method(this, 'notes'),
719 MochiKit.Base.partial(MochiKit.Base.operator.ne, '')
720 ]
721 });
722 // deferredResult.addCallback(MochiKit.Base.values);
723 // deferredResult.addCallback(function(someValues) {
724 // return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
725 // });
726 deferredResult.addCallback(Clipperz.Async.or);
727
728 deferredResult.callback();
729
730 return deferredResult;
731 },
732
733 //-------------------------------------------------------------------------
734
735 'isBrandNewWithNoPendingChanges': function () {
736 vardeferredResult;
737
738 if (this.isBrandNew() == false) {
739 deferredResult = MochiKit.Async.succeed(false);
740 } else {
741 deferredResult = Clipperz.Async.callbacks("Record.isBrandNewWithNoPendingChanges", [
742 MochiKit.Base.method(this, 'hasPendingChanges'),
743 MochiKit.Base.operator.lognot
744 ], {trace:false});
745 }
746
747 return deferredResult;
748 },
749
750 //=========================================================================
751
752 'revertChanges': function () {
753 var deferredResult;
754
755 if (this.isBrandNew() == false) {
756 deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.revertChanges", {trace:false});
757 deferredResult.addMethod(this, 'hasPendingChanges');
758 deferredResult.addIf([
759 // MochiKit.Base.method(this, 'getCurrentRecordVersion'),
760 // MochiKit.Base.methodcaller('revertChanges'),
761 MochiKit.Base.method(this,'invokeCurrentRecordVersionMethod', 'revertChanges'),
762
763 MochiKit.Base.method(this, 'directLogins'),
764 MochiKit.Base.values,
765 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('revertChanges')),
766
767 MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.revertChanges, this)
768 ], [
769 MochiKit.Async.succeed
770 ]);
771 deferredResult.callback();
772 } else {
773 // this.deleteAllCleanTextData();
774 deferredResult = MochiKit.Async.succeed();
775 }
776
777 return deferredResult;
778 },
779
780 //-------------------------------------------------------------------------
781
782 'resetTransientState': function (isCommitting) {
783 // if ((isCommitting == false) && (this.transientState().getValue('directLogins') != null)) {
784 // this._directLogins = this.transientState().getValue('directLogins');
785 // }
786
787 return Clipperz.Async.callbacks("Record.resetTransientState", [
788 //- MochiKit.Base.method(this, 'getCurrentRecordVersion'),
789 //- MochiKit.Base.methodcaller('resetTransientState'),
790 // MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'resetTransientState'),
791 MochiKit.Base.method(this, 'lazilyinvokeCurrentRecordVersionMethod', 'resetTransientState'),
792
793 MochiKit.Base.method(this, 'directLogins'),
794 MochiKit.Base.values,
795 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('resetTransientState')),
796
797 MochiKit.Base.bind(function () {
798 if ((isCommitting == false) && (this.transientState().getValue('directLogins') != null)) {
799 this._directLogins = this.transientState().getValue('directLogins');
800 }
801 }, this),
802
803 MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.resetTransientState, this, isCommitting)
804 ], {trace:false})
805 },
806
807 //-------------------------------------------------------------------------
808
809 'commitTransientState': function () {
810 var deferredResult;
811
812 deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.commitTransientState", {trace:false});
813 deferredResult.addMethod(this, 'hasPendingChanges');
814 deferredResult.addIf([
815 MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.commitTransientState, this),
816 // MochiKit.Base.method(this, 'getCurrentRecordVersion'),
817 // MochiKit.Base.methodcaller('commitTransientState'),
818 MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'commitTransientState'),
819 MochiKit.Base.method(this, 'directLogins'),
820 MochiKit.Base.values,
821 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('commitTransientState'))
822 ], [
823 MochiKit.Async.succeed
824 ]);
825 deferredResult.callback();
826
827 return deferredResult;
828 },
829
830 //=========================================================================
831
832 'retrieveDirectLoginIndexDataFunction': function () {
833 return this._retrieveDirectLoginIndexDataFunction;
834 },
835
836 'setDirectLoginIndexDataFunction': function () {
837 return this._setDirectLoginIndexDataFunction;
838 },
839
840 'removeDirectLoginIndexDataFunction': function () {
841 return this._removeDirectLoginIndexDataFunction;
842 },
843
844 //=========================================================================
845
846 'deleteAllCleanTextData': function () {
847 // return Clipperz.PM.DataModel.Record.superclass.deleteAllCleanTextData.apply(this, arguments);
848
849 return Clipperz.Async.callbacks("Record.deleteAllCleanTextData", [
850 MochiKit.Base.method(this, 'versions'),
851 MochiKit.Base.values,
852 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
853
854 MochiKit.Base.method(this, 'directLogins'),
855 MochiKit.Base.values,
856 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
857
858 MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.deleteAllCleanTextData, this)
859 ], {trace:false});
860 },
861
862 'hasAnyCleanTextData': function () {
863 // return Clipperz.PM.DataModel.Record.superclass.hasAnyCleanTextData.apply(this, arguments);
864
865 return Clipperz.Async.callbacks("Record.hasAnyCleanTextData", [
866 Clipperz.Async.collectResults("Record.hasAnyCleanTextData [collect results]", {
867 'versions':[
868 MochiKit.Base.method(this, 'versions'),
869 MochiKit.Base.values,
870 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
871 Clipperz.Async.collectAll
872 ],
873 'directLogins': [
874 MochiKit.Base.method(this, 'directLogins'),
875 MochiKit.Base.values,
876 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
877 Clipperz.Async.collectAll
878 ],
879 'super': [
880 MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.hasAnyCleanTextData, this)
881 ]
882 }, {trace:false}),
883 Clipperz.Async.or
884 ])
885 },
886
887 //=========================================================================
888 __syntaxFix__: "syntax fix"
889});
890
891