summaryrefslogtreecommitdiff
path: root/frontend/delta/js/Clipperz/PM/DataModel/DirectLogin.js
Unidiff
Diffstat (limited to 'frontend/delta/js/Clipperz/PM/DataModel/DirectLogin.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/Clipperz/PM/DataModel/DirectLogin.js1086
1 files changed, 1086 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/PM/DataModel/DirectLogin.js b/frontend/delta/js/Clipperz/PM/DataModel/DirectLogin.js
new file mode 100644
index 0000000..8db90de
--- a/dev/null
+++ b/frontend/delta/js/Clipperz/PM/DataModel/DirectLogin.js
@@ -0,0 +1,1086 @@
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
24Clipperz.Base.module('Clipperz.PM.DataModel');
25
26Clipperz.PM.DataModel.DirectLogin = function(args) {
27 args = args || {};
28
29 Clipperz.PM.DataModel.DirectLogin.superclass.constructor.apply(this, arguments);
30
31 this._reference =args.reference
32 ||Clipperz.PM.Crypto.randomKey();
33 this._record =args.record
34 ||Clipperz.Base.exception.raise('MandatoryParameter');
35
36 this._retrieveIndexDataFunction = args.retrieveIndexDataFunction
37 ||this.record().retrieveDirectLoginIndexDataFunction()
38 ||Clipperz.Base.exception.raise('MandatoryParameter');
39 this._setIndexDataFunction = args.setIndexDataFunction
40 ||this.record().setDirectLoginIndexDataFunction()
41 ||Clipperz.Base.exception.raise('MandatoryParameter');
42 this._removeIndexDataFunction =args.removeIndexDataFunction
43 ||this.record().removeDirectLoginIndexDataFunction()
44 ||Clipperz.Base.exception.raise('MandatoryParameter');
45
46 this._inputs = null;
47 this._bindings = null;
48 this._formValues = null;
49
50 // this._inputsDeferredLock = new MochiKit.Async.DeferredLock();
51 // this._bindingsDeferredLock = new MochiKit.Async.DeferredLock();
52 // this._formValuesDeferredLock = new MochiKit.Async.DeferredLock();
53
54 this._transientState = null;
55
56 this._isBrandNew = MochiKit.Base.isUndefinedOrNull(args.reference);
57
58 this.record().addDirectLogin(this);
59
60 return this;
61}
62
63Clipperz.Base.extend(Clipperz.PM.DataModel.DirectLogin, Object, {
64
65 'toString': function() {
66 return "DirectLogin (" + this.reference() + ")";
67 },
68
69 //=========================================================================
70
71 'reference': function () {
72 return this._reference;
73 },
74
75 //-------------------------------------------------------------------------
76
77 'record': function () {
78 return this._record;
79 },
80
81 //=========================================================================
82
83 'isBrandNew': function () {
84 return this._isBrandNew;
85 },
86
87 //=========================================================================
88
89 'removeIndexDataFunction': function () {
90 return this._removeIndexDataFunction;
91 },
92
93 'remove': function () {
94 return Clipperz.Async.callbacks("DirectLogin.remove", [
95 MochiKit.Base.partial(this.removeIndexDataFunction(), this.reference()),
96 MochiKit.Base.method(this.record(), 'removeDirectLogin', this)
97 ], {trace:false});
98 },
99
100 //=========================================================================
101 /*
102 'inputsDeferredLock': function () {
103 return this._inputsDeferredLock;
104 },
105
106 'bindingsDeferredLock': function () {
107 return this._bindingsDeferredLock;
108 },
109
110 'formValuesDeferredLock': function () {
111 return this._formValuesDeferredLock;
112 },
113*/
114 //=========================================================================
115
116 'label': function () {
117 return this.getIndexDataForKey('label');
118 },
119
120 'setLabelKeepingBackwardCompatibilityWithBeta': function (aValue) {
121 return Clipperz.Async.callbacks("DirectLogin.setLabelKeepingBackwardCompatibilityWithBeta", [
122 MochiKit.Base.method(this, 'setIndexDataForKey', 'label', aValue),
123 MochiKit.Base.method(this, 'setValue', 'label', aValue)
124 ], {trace:false});
125 },
126
127 'setLabel': function (aValue) {
128 return this.setLabelKeepingBackwardCompatibilityWithBeta(aValue);
129 // return this.setIndexDataForKey('label', aValue);
130 },
131
132 //=========================================================================
133
134 'favicon': function () {
135 return this.getIndexDataForKey('favicon');
136 },
137
138 'setFavicon': function (aValue) {
139 return this.setIndexDataForKey('favicon', aValue);
140 },
141
142 'faviconUrlWithBookmarkletConfiguration': function (aBookmarkletConfiguration) {
143 varresult;
144
145 if (! MochiKit.Base.isUndefinedOrNull(aBookmarkletConfiguration['page']['favicon'])) {
146 result = aBookmarkletConfiguration['page']['favicon'];
147 } else if (! MochiKit.Base.isUndefinedOrNull(aBookmarkletConfiguration['form']['attributes']['action'])) {
148 var actionUrl;
149 var hostname;
150
151 actionUrl = aBookmarkletConfiguration['form']['attributes']['action'];
152 hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1');
153 result = "http://" + hostname + "/favicon.ico";
154 } else {
155 result = null;
156 }
157
158
159 return result;
160 },
161
162 //-------------------------------------------------------------------------
163/*
164 'faviconData': function () {
165 var regexp = new RegExp('^data\:\/\/.*', 'i');
166
167 return Clipperz.Async.callbacks("DirectLogin.favicon", [
168 MochiKit.Base.method(this, 'getIndexDataForKey', 'favicon'),
169 MochiKit.Base.method(regexp, 'test'),
170 Clipperz.Async.deferredIf("is data URL", [
171 MochiKit.Base.method(this, 'getIndexDataForKey', 'favicon')
172 ], [
173 MochiKit.Base.method(this, 'transientState'),
174 MochiKit.Base.itemgetter('faviconData'),
175 Clipperz.Async.deferredIf('has a chaced value for the favicon data', [
176 MochiKit.Base.operator.identity
177 ], [
178 MochiKit.Base.method(this, 'getIndexDataForKey', 'favicon'),
179 MochiKit.Base.method(this, 'loadFaviconDataFromURL')
180 ])
181
182 ])
183 ], {trace:false});
184 },
185
186 //-------------------------------------------------------------------------
187
188 'loadFaviconDataFromURL': function (anURL) {
189 var deferredResult;
190 var image;
191
192 deferredResult = new Clipperz.Async.Deferred("DirectLogin.loadFaviconDataFromURL", {trace:false});
193 deferredResult.addCallback(function (anEvent) {
194 var image = anEvent.src();
195 var canvas = document.createElement("canvas");
196 var result;
197
198 canvas.width = image.width;
199 canvas.height = image.height;
200
201 var ctx = canvas.getContext("2d");
202 ctx.drawImage(image, 0, 0);
203
204 result = canvas.toDataURL(/*"image/png"* /);
205
206 return result;
207 });
208 deferredResult.addErrback(MochiKit.Async.succeed, Clipperz.PM.Strings.getValue('defaultFaviconUrl'));
209 deferredResult.addBoth(MochiKit.Base.bind(function (aDataUrl) {
210 this.transientState()['faviconData'] = aDataUrl;
211
212 return aDataUrl;
213 }, this));
214
215 image = new Image();
216 MochiKit.Signal.connect(image, 'onload', MochiKit.Base.method(deferredResult, 'callback'));
217 MochiKit.Signal.connect(image, 'onerror', MochiKit.Base.method(deferredResult, 'errback'));
218 MochiKit.Signal.connect(image, 'onabort', MochiKit.Base.method(deferredResult, 'errback'));
219
220 image.src = anURL;
221
222 return deferredResult;
223 },
224*/
225
226 //=========================================================================
227
228 'type': function () {
229 return this.getValue('formData.attributes.type')
230 },
231
232 //=========================================================================
233
234 'serializedData': function () {
235 return Clipperz.Async.collectResults("DirectLogin.serializedData", {
236 'bookmarkletVersion': MochiKit.Base.method(this, 'getValue', 'bookmarkletVersion'),
237 'formData': MochiKit.Base.method(this, 'getValue', 'formData'),
238 'formValues': MochiKit.Base.method(this, 'getValue', 'formValues'),
239 'bindingData': [
240 MochiKit.Base.method(this, 'bindings'),
241 function (someBindings) {
242 var result;
243 var bindingKey;
244
245 result = {}
246 for (bindingKey in someBindings) {
247 result[bindingKey] = someBindings[bindingKey].serializedData();
248 }
249
250 return result;
251 }
252 ]
253 }, {trace:false})()
254 },
255
256 //=========================================================================
257/*
258 'fixFormDataFromBookmarkletVersion_0_1': function(aValue) {
259//{"type":"radio", "name":"action", "value":"new-user", "checked":false }, { "type":"radio", "name":"action", "value":"sign-in", "checked":true }
260 // ||
261 // \ /
262 // \/
263//{"name":"dominio", "type":"radio", "options":[{"value":"@alice.it", "checked":true}, {"value":"@tin.it", "checked":false}, {"value":"@virgilio.it", "checked":false}, {"value":"@tim.it", "checked":false}]}
264 var result;
265 var inputs;
266 var updatedInputs;
267 var radios;
268
269 result = aValue;
270 inputs = aValue['inputs'];
271
272 updatedInputs = MochiKit.Base.filter(function(anInput) {
273 varresult;
274 var type;
275
276 type = anInput['type'] || 'text';
277 result = type.toLowerCase() != 'radio';
278
279 return result;
280 }, inputs);
281 radios = MochiKit.Base.filter(function(anInput) {
282 varresult;
283 var type;
284
285 type = anInput['type'] || 'text';
286 result = type.toLowerCase() == 'radio';
287
288 return result;
289 }, inputs);
290
291 if (radios.length > 0) {
292 var updatedRadios;
293
294 updatedRadios = {};
295 MochiKit.Iter.forEach(radios, MochiKit.Base.bind(function(aRadio) {
296 varradioConfiguration;
297
298 radioConfiguration = updatedRadios[aRadio['name']];
299 if (radioConfiguration == null) {
300 radioConfiguration = {type:'radio', name:aRadio['name'], options:[]};
301 updatedRadios[aRadio['name']] = radioConfiguration;
302 }
303
304 //TODO: remove the value: field and replace it with element.dom.value = <some value>
305 radioConfiguration.options.push({value:aRadio['value'], checked:aRadio['checked']});
306
307 //TODO: shoud remove the 'formValues' call, as it is now deferred
308 // if ((aRadio['checked'] == true) && (this.formValues()[aRadio['name']] == null)) {
309 // this.formValues()[aRadio['name']] = aRadio['value'];
310 // }
311 }, this))
312
313 updatedInputs = MochiKit.Base.concat(updatedInputs, MochiKit.Base.values(updatedRadios));
314 }
315
316 delete result.inputs;
317 result.inputs = updatedInputs;
318
319 return result;
320 },
321
322 '_fixConfiguration': function (aConfiguration) {
323 var fixedConfiguration;
324 // var inputs;
325 // var bindings;
326 // var i,c;
327
328 fixedConfiguration = Clipperz.Base.deepClone(aConfiguration);
329
330//Clipperz.log("PROCESS CONFIGURATION", aConfiguration);
331 switch (aConfiguration['bookmarkletVersion']) {
332 case '0.1':
333 fixedConfiguration['formData'] = this.fixFormDataFromBookmarkletVersion_0_1(aConfiguration['formData']);
334 break;
335 case '0.2':
336 fixedConfiguration['formData'] = aConfiguration['formData'];
337 break;
338 }
339
340 / *
341 aConfiguration['_inputs'] = [];
342 c = formData['inputs'].length;
343 for (i=0; i<c; i++) {
344 aConfiguration['_inputs'].push(new Clipperz.PM.DataModel.DirectLoginInput(formData['inputs'][i]));
345 }
346* /
347/ *
348 aConfiguration['_bindings'] = {};
349 if (aConfiguration['legacyBindingData'] == null) {
350 if (aConfiguration['bindingData'] != null) {
351 var bindingKey;
352
353 for (bindingKey in aConfiguration['bindingData']) {
354 var newBinding;
355
356 newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(bindingKey, {fieldKey:aConfiguration['bindingData'][bindingKey]});
357 aConfiguration['_bindings'][newBinding.key()] = newBinding;
358 }
359 } else {
360 var editableFields;
361
362 editableFields = MochiKit.Base.filter(function(aField) {
363 var result;
364 var type;
365
366 type = aField['type'].toLowerCase();
367 result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select'));
368
369 return result;
370 }, aConfiguration['_inputs']);
371
372 MochiKit.Iter.forEach(editableFields, MochiKit.Base.bind(function(anEditableField) {
373 var newBinding;
374
375 newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(anEditableField['name']);
376 aConfiguration['_bindings'][newBinding.key()] = newBinding;
377 }, this));
378 }
379
380 } else {
381 var bindingKey;
382
383 for (bindingKey in aConfiguration['legacyBindingData']) {
384 var newBinding;
385
386 newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(bindingKey, {fieldName:aConfiguration['legacyBindingData'][bindingKey]});
387 aConfiguration['_bindings'][newBinding.key()] = newBinding;
388 }
389 }
390* /
391
392 return fixedConfiguration;
393 },
394
395 //-------------------------------------------------------------------------
396
397 'getObjectDataStore': function () {
398 var deferredResult;
399
400 deferredResult = new Clipperz.Async.Deferred("DirectLogin.getObjectDataStore", {trace:false});
401 deferredResult.acquireLock(this.objectDataStoreDeferredLock());
402 deferredResult.addCallback(MochiKit.Base.bind(function () {
403 var innerDeferredResult;
404
405 if (this._objectDataStore == null) {
406 this._objectDataStore = new Clipperz.KeyValueObjectStore();
407
408 innerDeferredResult = new Clipperz.Async.Deferred("DirectLogin.getObjectDataStore <inner deferred>", {trace:false});
409 // innerDeferredResult.addMethod(this.record(), 'getValue', 'directLogins' + '.' + this.reference());
410 innerDeferredResult.addMethod(this, 'getValue', ''),
411 innerDeferredResult.addMethod(this, 'setOriginalState');
412 innerDeferredResult.addMethod(this, '_fixConfiguration');
413 innerDeferredResult.addMethod(this._objectDataStore, 'initWithValues');
414 // innerDeferredResult.addMethod(this._objectDataStore, 'setValues');
415 innerDeferredResult.callback();
416 } else {
417 innerDeferredResult = MochiKit.Async.succeed(this._objectDataStore);
418 }
419
420 return innerDeferredResult;
421 }, this));
422 deferredResult.releaseLock(this.objectDataStoreDeferredLock());
423 deferredResult.callback();
424
425 return deferredResult;
426 },
427
428 //-------------------------------------------------------------------------
429
430 'hasInitiatedObjectDataStore': function () {
431 return (this._objectDataStore != null);
432 },
433
434 //-------------------------------------------------------------------------
435
436 'resetObjectDataStore': function () {
437 this._objectDataStore.removeAllData();
438 this._objectDataStore = null;
439 },
440*/
441 //=========================================================================
442
443 'bookmarkletConfiguration': function () {
444 return Clipperz.Async.callbacks("DirectLogin.bookmarkletConfiguration", [
445 Clipperz.Async.collectResults("DirectLogin.bookmarkletConfiguration <inner results>", {
446 'label': MochiKit.Base.method(this, 'label'),
447 'configuration': MochiKit.Base.method(this, 'getValue', '')
448 }, {trace:false}),
449 function (someValues) {
450 var result;
451
452 if (someValues['configuration'] != null) {
453 varconfiguration;
454
455 configuration = {
456 'page': {
457 'title': someValues['label']
458 //'favicon'
459 // 'url'
460 },
461 'form': someValues['configuration']['formData'],
462 'version':someValues['configuration']['bookmarkletVersion']
463 }
464
465 result = Clipperz.Base.formatJSON(configuration);
466 } else {
467 result = '';
468 }
469
470 return result;
471 }
472 ], {trace:false});
473
474 },
475
476 //-------------------------------------------------------------------------
477
478 'setBookmarkletConfiguration': function (aValue) {
479 var bookmarkletConfiguration;
480
481 bookmarkletConfiguration = Clipperz.PM.DataModel.DirectLogin.checkBookmarkletConfiguration(aValue);
482
483 return Clipperz.Async.callbacks("DirectLogin.setBookmarkletConfiguration", [
484 MochiKit.Base.method(this, 'setValue', 'formData', bookmarkletConfiguration['form']),
485 MochiKit.Base.method(this, 'setValue', 'bookmarkletVersion', bookmarkletConfiguration['version']),
486
487 MochiKit.Base.method(this, 'favicon'),
488 Clipperz.Async.deferredIf("the favicon is not set", [
489 ], [
490 MochiKit.Base.method(this, 'faviconUrlWithBookmarkletConfiguration', bookmarkletConfiguration),
491 MochiKit.Base.method(this, 'setFavicon')
492 ]),
493
494 MochiKit.Base.method(this, 'updateInputsAfterChangingBookmarkletConfiguration'),
495 MochiKit.Base.method(this, 'updateFormValuesAfterChangingBookmarkletConfiguration'),
496 MochiKit.Base.method(this, 'updateBindingsAfterChangingBookmarkletConfiguration'),
497
498 MochiKit.Base.noop
499 ], {trace:false});
500 },
501
502 //=========================================================================
503
504 'formAttributes': function () {
505 return this.getValue('formData.attributes');
506 },
507
508 //=========================================================================
509
510 'inputs': function () {
511 return Clipperz.Async.callbacks("DirectLogin.inputs", [
512 Clipperz.Async.deferredIf("this._inputs is defined", [
513 ], [
514 MochiKit.Base.method(this, 'updateInputsAfterChangingBookmarkletConfiguration')
515 ])
516 ], {trace:false}, this._inputs);
517 },
518
519 'setInputWithFormDataConfiguration': function (aFormDataConfiguration) {
520 this._inputs = {};
521
522 if (aFormDataConfiguration != null) {
523 MochiKit.Iter.forEach(aFormDataConfiguration['inputs'], MochiKit.Base.bind(function (anInputData) {
524 var newInput;
525
526 newInput = new Clipperz.PM.DataModel.DirectLoginInput(anInputData);
527 this._inputs[newInput.name()] = newInput;
528 }, this));
529 }
530
531 return this._inputs;
532 },
533
534 'updateInputsAfterChangingBookmarkletConfiguration': function () {
535 return Clipperz.Async.callbacks("DirectLogin.updateInputsAfterChangingBookmarkletConfiguration", [
536 MochiKit.Base.method(this, 'getValue', 'formData'),
537 MochiKit.Base.method(this, 'setInputWithFormDataConfiguration')
538 ], {trace:false});
539 },
540
541 //=========================================================================
542
543 'inputValues': function () {
544 return Clipperz.Async.callbacks("DirectLogin.inputValues", [
545 MochiKit.Base.method(this, 'inputs'),
546 MochiKit.Base.values,
547 MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.partial(MochiKit.Base.method(this, 'inputValue'))),
548 Clipperz.Async.collectAll,
549 Clipperz.Base.mergeItems
550 ], {trace:false});
551 },
552
553 'inputValue': function (anInput) {
554 vardeferredResult;
555
556 deferredResult = new Clipperz.Async.Deferred("DirectLogin.inputValue", {trace:false});
557
558 if (anInput.needsFormValue()) {
559 deferredResult.addMethod(this, 'formValues');
560 deferredResult.addCallback(MochiKit.Base.itemgetter(anInput.name()));
561 deferredResult.addMethodcaller('value');
562 } else if (anInput.needsBinding()) {
563 deferredResult.addMethod(this, 'bindings');
564 deferredResult.addCallback(MochiKit.Base.itemgetter(anInput.name()));
565 deferredResult.addMethodcaller('field');
566 deferredResult.addMethodcaller('value');
567 } else {
568 deferredResult.addCallback(MochiKit.Async.succeed, anInput.value());
569 }
570 deferredResult.addCallback(function (anActualValue) {
571 return [anInput.name(), anActualValue];
572 });
573
574 deferredResult.callback();
575
576 return deferredResult;
577 },
578
579 //=========================================================================
580
581 'bindings': function () {
582 return Clipperz.Async.callbacks("DirectLogin.bindings", [
583 Clipperz.Async.deferredIf("this._bindings is defined", [
584 ], [
585 MochiKit.Base.method(this, 'updateBindingsAfterChangingBookmarkletConfiguration'),
586 MochiKit.Base.bind(function () { return this._bindings;}, this)
587 ])
588 ], {trace:false}, this._bindings);
589 },
590
591 'bindFormFieldWithLabelToRecordFieldWithLabel': function (aFormFieldLabel, aRecordFieldLabel) {
592 return Clipperz.Async.callbacks("DirectLogin.bindFormFieldWithLabelToCardFieldWithLabel", [
593 Clipperz.Async.collectResults("DirectLogin.bindFormFieldWithLabelToCardFieldWithLabel - collect results", {
594 'binding': [
595 MochiKit.Base.method(this, 'bindings'),
596 MochiKit.Base.itemgetter(aFormFieldLabel)
597 ],
598 'field': [
599 MochiKit.Base.method(this.record(), 'fieldWithLabel', aRecordFieldLabel)
600 ]
601 }),
602 function (someValues) {
603 someValues['binding'].setField(someValues['field'])
604 }
605 ], {trace:false});
606 },
607
608 //-------------------------------------------------------------------------
609/*
610 'bindingValues': function () {
611 return Clipperz.Async.callbacks("DirectLogin.bindingValues", [
612 Clipperz.Async.collectResults("DirectLogin.bindingValues [collectResults]", {
613 'fieldValues': [
614 MochiKit.Base.method(this, 'record'),
615 MochiKit.Base.methodcaller('getFieldsValues')
616 ],
617 'bindings': MochiKit.Base.method(this, 'bindings')
618 }, {trace:false}),
619 function (someData) {
620 var result;
621 varbindingKey;
622
623 result = {};
624 for (bindingKey in someData['bindings']) {
625 result[bindingKey] = someData['fieldValues'][someData['bindings'][bindingKey].fieldKey()]['value'];
626 }
627
628 return result;
629 }
630 ], {trace:false});
631 },
632*/
633 //-------------------------------------------------------------------------
634
635 'updateBindingsAfterChangingBookmarkletConfiguration': function () {
636 return Clipperz.Async.callbacks("DirectLogin.updateBindingsAfterChangingBookmarkletConfiguration", [
637 Clipperz.Async.collectResults("DirectLogin.updateBindingsAfterChangingBookmarkletConfiguration<collect results>", {
638 'currentValues':MochiKit.Base.method(this, 'getValue', ''),
639 'originalValues':MochiKit.Base.method(this, 'originalConfiguration'),
640 'inputs': MochiKit.Base.method(this, 'inputs')
641 }, {trace:false}),
642 MochiKit.Base.bind(function (someValues) {
643 var availableBindingValues;
644 var inputRequiringBindingValues;
645 var newBindingValues;
646
647 if (MochiKit.Base.isUndefinedOrNull(someValues['originalValues']) || MochiKit.Base.isUndefinedOrNull(someValues['originalValues']['bindingData'])) {
648 availableBindingValues = {};
649 } else {
650 availableBindingValues = Clipperz.Base.deepClone(someValues['originalValues']['bindingData'])
651 }
652
653 if (someValues['currentValues'] != null) {
654 MochiKit.Base.update(availableBindingValues, someValues['currentValues']['bindingData']);
655 }
656
657 this._bindings = {};
658 newBindingValues = {}
659 MochiKit.Iter.forEach(MochiKit.Base.filter(MochiKit.Base.methodcaller('needsBinding'), MochiKit.Base.values(someValues['inputs'])), MochiKit.Base.bind(function (anInput) {
660 varnewBinding;
661
662 newBindingValues[anInput.name()] = availableBindingValues[anInput.name()];
663 newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, {
664 'key': anInput.name(),
665 'field':availableBindingValues[anInput.name()]
666 });
667
668 this._bindings[anInput.name()] = newBinding;
669 }, this))
670
671 return newBindingValues;
672
673/*
674 this._bindings = {};
675
676 if (someValues['currentValues'] != null) {
677 if (someValues['currentValues']['bindingData'] != null) {
678 var bindingKey;
679
680 for (bindingKey in someValues['currentValues']['bindingData']) {
681 var newBinding;
682
683 newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, {
684 'key': bindingKey,
685 'field':someValues['currentValues']['bindingData'][bindingKey]
686 });
687 this._bindings[newBinding.key()] = newBinding;
688 }
689 } else if (someValues['currentValues']['legacyBindingData'] == null) {
690 var bindingKey;
691
692 for (bindingKey in someValues['currentValues']['legacyBindingData']) {
693 var newBinding;
694
695 newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, {
696 'key': bindingKey,
697 'field':someValues['currentValues']['legacyBindingData'][bindingKey]
698 });
699 this._bindings[newBinding.key()] = newBinding;
700 }
701 } else {
702 WTF = TODO;
703 }
704 }
705
706 return this._bindings;
707*/
708 }, this),
709 MochiKit.Base.method(this, 'setValue', 'bindingData')
710 ], {trace:false});
711 },
712
713 //=========================================================================
714
715 'formValues': function () {
716 return Clipperz.Async.callbacks("DirectLogin.formValues", [
717 Clipperz.Async.deferredIf("this._formValues is defined", [
718 ], [
719 MochiKit.Base.method(this, 'updateFormValuesAfterChangingBookmarkletConfiguration'),
720 MochiKit.Base.bind(function () { return this._formValues;}, this)
721 ])
722 ], {trace:false}, this._formValues);
723 },
724
725 //-------------------------------------------------------------------------
726
727 'updateFormValuesAfterChangingBookmarkletConfiguration': function () {
728 return Clipperz.Async.callbacks("DirectLogin.updateFormValuesAfterChangingBookmarkletConfiguration", [
729 Clipperz.Async.collectResults("DirectLogin.updateFormValuesAfterChangingBookmarkletConfiguration <collect results>", {
730 'currentValues':MochiKit.Base.method(this, 'getValue', ''),
731 'originalValues':MochiKit.Base.method(this, 'originalConfiguration'),
732 'inputs': MochiKit.Base.method(this, 'inputs')
733 }, {trace:false}),
734 MochiKit.Base.bind(function (someValues) {
735 var availableFormValues;
736 var inputRequiringFormValues;
737 var newFormValues;
738
739 if (MochiKit.Base.isUndefinedOrNull(someValues['originalValues']) || MochiKit.Base.isUndefinedOrNull(someValues['originalValues']['formValues'])) {
740 availableFormValues = {};
741 } else {
742 availableFormValues = Clipperz.Base.deepClone(someValues['originalValues']['formValues'])
743 }
744
745 MochiKit.Base.update(availableFormValues, someValues['currentValues']['formValues']);
746
747 this._formValues = {};
748 newFormValues = {};
749 MochiKit.Iter.forEach(MochiKit.Base.filter(MochiKit.Base.methodcaller('needsFormValue'), MochiKit.Base.values(someValues['inputs'])), MochiKit.Base.bind(function (anInput) {
750 varnewFormValue;
751 var fieldOptions;
752
753 fieldOptions = {
754 'type': anInput.type(),
755 'options':anInput.options()
756 };
757
758 newFormValues[anInput.name()] = availableFormValues[anInput.name()]
759 newFormValue = new Clipperz.PM.DataModel.DirectLoginFormValue(this, {
760 'key': anInput.name(),
761 'fieldOptions':fieldOptions,
762 'value': availableFormValues[anInput.name()]
763 });
764
765 this._formValues[anInput.name()] = newFormValue;
766 }, this))
767
768 return newFormValues;
769 }, this),
770 MochiKit.Base.method(this, 'setValue', 'formValues')
771 ], {trace:false});
772 },
773
774 //=========================================================================
775
776 'retrieveIndexDataFunction': function () {
777 return this._retrieveIndexDataFunction;
778 },
779
780 'getIndexDataForKey': function (aKey) {
781 return Clipperz.Async.callbacks("DirectLogin.getIndexDataForKey", [
782 MochiKit.Base.partial(this.retrieveIndexDataFunction(), this.reference()),
783 Clipperz.Async.deferredIf("DirectLogin.getIndexDataForKey - index data not null", [
784 MochiKit.Base.itemgetter(aKey)
785 ],[
786 MochiKit.Async.succeed
787 ])
788 ], {trace:false});
789 },
790
791 //-------------------------------------------------------------------------
792
793 'setIndexDataForKey': function (aKey, aValue) {
794 return Clipperz.Async.callbacks("DirectLogin.setValueForKey", [
795 MochiKit.Base.method(this, 'getIndexDataForKey', aKey),
796 MochiKit.Base.bind(function (anActualValue) {
797 var transientStateKey;
798
799 transientStateKey = 'original_' + aKey;
800 if (MochiKit.Base.isUndefinedOrNull(this.transientState()[transientStateKey])) {
801 if (anActualValue != aValue) {
802 this.transientState()[transientStateKey] = anActualValue;
803 }
804 } else if (this.transientState()[transientStateKey] == aValue) {
805 this.transientState()[transientStateKey] = null;
806 }
807 }, this),
808 MochiKit.Base.partial(this._setIndexDataFunction, this.reference(), aKey, aValue)
809 ], {trace:false})
810 },
811
812 //-------------------------------------------------------------------------
813/*
814 'setValueForKey': function (aKey, aValue) {
815 return Clipperz.Async.callbacks("DirectLogin.setValueForKey", [
816 MochiKit.Base.method(this, 'getIndexDataForKey', aKey),
817 MochiKit.Base.bind(function (anActualValue) {
818 var transientStateKey;
819
820 transientStateKey = 'original_' + aKey;
821 if (MochiKit.Base.isUndefinedOrNull(this.transientState()[transientStateKey])) {
822 if (anActualValue != aValue) {
823 this.transientState()[transientStateKey] = anActualValue;
824 }
825 } else if (this.transientState()[transientStateKey] == aValue) {
826 this.transientState()[transientStateKey] = null;
827 }
828 }, this),
829 MochiKit.Base.method(this, 'setIndexDataForKey', aKey, aValue)
830 ], {trace:false})
831 },
832*/
833 //=========================================================================
834/*
835 'storedConfiguration': function () {
836 return this.record().getValue('directLogins' + '.' + this.reference());
837 },
838
839 //'setStoredConfiguration': function (aValue) {
840 // return this.record().setValue('directLogins' + '.' + this.reference(), aValue);
841 //},
842*/
843 //=========================================================================
844
845 'hasPendingChanges': function () {
846 varresult;
847 var deferredResult;
848
849 result = false;
850 result = result || this.isBrandNew();
851 result = result || (! MochiKit.Base.isUndefinedOrNull(this.transientState()['original_label']));
852 result = result || (! MochiKit.Base.isUndefinedOrNull(this.transientState()['original_favicon']));
853
854 if ((result == false) && (this.originalConfiguration() != null)) {
855 deferredResult = Clipperz.Async.callbacks("DirectLogin.hasPendingChanges", [
856 MochiKit.Base.method(this, 'serializedData'),
857 MochiKit.Base.bind(function (aCurrentConfiguration) {
858 varoriginalConfiguration;
859 var currentConfiguration;
860 var result;
861
862 originalConfiguration = this.originalConfiguration();
863 currentConfiguration = aCurrentConfiguration;
864
865 result = false;
866 result = result || (MochiKit.Base.compare(originalConfiguration['bookmarkletVersion'], currentConfiguration['bookmarkletVersion'])!= 0);
867 result = result || (MochiKit.Base.compare(originalConfiguration['formData'], currentConfiguration['formData']) != 0);
868 result = result || (MochiKit.Base.compare(originalConfiguration['formValues'], currentConfiguration['formValues']) != 0);
869 result = result || (MochiKit.Base.compare(originalConfiguration['bindingData'], currentConfiguration['bindingData']) != 0);
870
871 return result;
872 }, this)
873 ], {trace:false});
874 } else {
875 deferredResult = MochiKit.Async.succeed(result);
876 }
877
878 return deferredResult;
879 },
880
881 //-------------------------------------------------------------------------
882
883 'revertChanges': function () {
884 var deferredResult;
885
886 if (this.transientState()['original_label'] != null) {
887 this.setLabel(this.transientState()['original_label']);
888 }
889
890 if (this.transientState()['original_favicon'] != null) {
891 this.setFavicon(this.transientState()['original_favicon']);
892 }
893
894 if (this.originalConfiguration() != null) {
895 deferredResult = this.setValue('', this.originalConfiguration());
896 } else {
897 deferredResult = MochiKit.Async.succeed();
898 }
899
900 this._inputs = null;
901 this._bindings = null;
902 this._formValues= null;
903
904 this.resetTransientState(false);
905
906/*
907 if (this.hasInitiatedObjectDataStore()) {
908 deferredResult = Clipperz.Async.callbacks("DirectLogin.revertChanges", [
909 // MochiKit.Base.method(this.record(), 'setValue', 'directLogins' + '.' + this.reference(), this.originalState()),
910 MochiKit.Base.method(this, 'setValue', '', this.originalState()),
911 MochiKit.Base.method(this, 'resetObjectDataStore')
912 ], {trace:false})
913 } else {
914 deferredResult = MochiKit.Async.succeed();
915 }
916*/
917 return deferredResult;
918 },
919
920
921 //=========================================================================
922
923 'transientState': function () {
924 if (this._transientState == null) {
925 this._transientState = {}
926 }
927
928 return this._transientState;
929 },
930
931 'resetTransientState': function (isCommitting) {
932 this._transientState = null;
933 },
934
935 'commitTransientState': function (isCommitting) {
936 this._transientState = null;
937 this._isBrandNew = false;
938 },
939
940 //-------------------------------------------------------------------------
941
942 'originalConfiguration': function () {
943 return this.transientState()['original_configuration'];
944 },
945
946 'setOriginalConfiguration': function (aConfiguration) {
947 this.transientState()['original_configuration'] = Clipperz.Base.deepClone(aConfiguration);
948 },
949
950 //=========================================================================
951
952 'actualKey': function (aValueKey) {
953 var actualKey;
954
955 actualKey = 'directLogins' + '.' + this.reference();
956 if (aValueKey != '') {
957 actualKey = actualKey + '.' + aValueKey;
958 }
959
960 return actualKey;
961 },
962
963 //-------------------------------------------------------------------------
964
965 'getValue': function (aValueKey) {
966 return this.record().getValue(this.actualKey(aValueKey));
967 },
968
969 'setValue': function (aValueKey, aValue) {
970 // return this.record().setValue(this.actualKey(aValueKey), aValue);
971
972 return Clipperz.Async.callbacks("DirectLogin.setValue", [
973 MochiKit.Base.method(this, 'getValue', ''),
974 MochiKit.Base.bind(function (aValue) {
975 if (this.originalConfiguration() == null) {
976 this.setOriginalConfiguration(aValue);
977 }
978 }, this),
979 // MochiKit.Base.method(this, 'originalConfiguration'),
980 // Clipperz.Async.deferredIf("originalConfiguration has been set", [
981 // ], [
982 // MochiKit.Base.method(this, 'getValue', ''),
983 // MochiKit.Base.method(this, 'setOriginalConfiguration')
984 // ]),
985 MochiKit.Base.method(this.record(), 'setValue', this.actualKey(aValueKey), aValue)
986 ], {trace:false});
987 },
988
989 'removeValue': function (aValueKey) {
990 // return this.record().removeValue(this.actualKey(aValueKey));
991
992 return Clipperz.Async.callbacks("DirectLogin.setValue", [
993 MochiKit.Base.method(this, 'originalConfiguration'),
994 Clipperz.Async.deferredIf("originalConfiguration has been set", [
995 ], [
996 MochiKit.Base.method(this, 'getValue', ''),
997 MochiKit.Base.method(this, 'setOriginalConfiguration')
998 ]),
999 MochiKit.Base.method(this.record(), 'removeValue', this.actualKey(aValueKey))
1000 ], {trace:false});
1001 },
1002
1003 //=========================================================================
1004
1005 'content': function () {
1006 // return this.serializedData();
1007 // return MochiKit.Async.succeed(this);
1008
1009 var deferredResult;
1010 varfieldValues;
1011
1012 fieldValues = {};
1013 deferredResult = new Clipperz.Async.Deferred("DirectLogin.content", {trace:false});
1014 deferredResult.addMethod(this, 'reference');
1015 deferredResult.addCallback(function (aValue) { fieldValues['reference'] = aValue; });
1016 deferredResult.addMethod(this, 'label');
1017 deferredResult.addCallback(function (aValue) { fieldValues['label'] = aValue; });
1018 deferredResult.addMethod(this, 'favicon');
1019 deferredResult.addCallback(function (aValue) { fieldValues['favicon'] = aValue; });
1020 deferredResult.addCallback(function () { return fieldValues; });
1021 deferredResult.callback();
1022
1023 return deferredResult;
1024 },
1025
1026 //=========================================================================
1027
1028 'deleteAllCleanTextData': function () {
1029 this._inputs = null;
1030 this._bindings = null;
1031 this._formValues = null;
1032
1033 this.resetTransientState();
1034 },
1035
1036 //-------------------------------------------------------------------------
1037
1038 'hasAnyCleanTextData': function () {
1039 var result;
1040
1041 result = false;
1042
1043 result = result || (this._inputs != null);
1044 result = result || (this._bindings != null);
1045 result = result || (this._formValues != null);
1046 result = result || (MochiKit.Base.keys(this.transientState()).length != 0);
1047
1048 return MochiKit.Async.succeed(result);
1049 },
1050
1051 //=========================================================================
1052 __syntaxFix__: "syntax fix"
1053});
1054
1055//#############################################################################
1056
1057Clipperz.PM.DataModel.DirectLogin.exception = {
1058 'WrongBookmarkletConfiguration': new MochiKit.Base.NamedError("Clipperz.PM.DataModel.DirectLogin.exception.WrongBookmarkletConfiguration")
1059};
1060
1061Clipperz.PM.DataModel.DirectLogin.checkBookmarkletConfiguration = function(aConfiguration) {
1062 var configuration;
1063
1064 try {
1065 configuration = Clipperz.Base.evalJSON(aConfiguration);
1066 // configuration = Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration(configuration);
1067
1068 if (MochiKit.Base.isUndefinedOrNull(configuration['page']['title'])
1069 ||MochiKit.Base.isUndefinedOrNull(configuration['form']['attributes']['action'])
1070 // ||MochiKit.Base.isUndefinedOrNull(configuration['form']['attributes']['method'])
1071 ||MochiKit.Base.isUndefinedOrNull(configuration['form']['inputs'])
1072 ||MochiKit.Base.isUndefinedOrNull(configuration['version'])
1073 ) {
1074 throw Clipperz.PM.DataModel.DirectLogin.exception.WrongBookmarkletConfiguration;
1075 }
1076
1077 // if (MochiKit.Base.isUndefinedOrNull(configuration['favicon'])) {
1078 // throw Clipperz.PM.DataModel.DirectLogin.exception.WrongBookmarkletConfiguration;
1079 // }
1080
1081 } catch (exception) {
1082 throw exception;
1083 }
1084
1085 return configuration;
1086};