/* Copyright 2008-2011 Clipperz Srl This file is part of Clipperz's Javascript Crypto Library. Javascript Crypto Library provides web developers with an extensive and efficient set of cryptographic functions. The library aims to obtain maximum execution speed while preserving modularity and reusability. For further information about its features and functionalities please refer to http://www.clipperz.com * Javascript Crypto Library is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * Javascript Crypto Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. * You should have received a copy of the GNU Affero General Public License along with Javascript Crypto Library. If not, see . */ Clipperz.Base.module('Clipperz.PM.DataModel'); Clipperz.PM.DataModel.DirectLogin = function(args) { args = args || {}; Clipperz.PM.DataModel.DirectLogin.superclass.constructor.apply(this, arguments); this._reference = args.reference || Clipperz.PM.Crypto.randomKey(); this._record = args.record || Clipperz.Base.exception.raise('MandatoryParameter'); this._retrieveIndexDataFunction = args.retrieveIndexDataFunction || this.record().retrieveDirectLoginIndexDataFunction() || Clipperz.Base.exception.raise('MandatoryParameter'); this._setIndexDataFunction = args.setIndexDataFunction || this.record().setDirectLoginIndexDataFunction() || Clipperz.Base.exception.raise('MandatoryParameter'); this._removeIndexDataFunction = args.removeIndexDataFunction || this.record().removeDirectLoginIndexDataFunction() || Clipperz.Base.exception.raise('MandatoryParameter'); this._inputs = null; this._bindings = null; this._formValues = null; // this._inputsDeferredLock = new MochiKit.Async.DeferredLock(); // this._bindingsDeferredLock = new MochiKit.Async.DeferredLock(); // this._formValuesDeferredLock = new MochiKit.Async.DeferredLock(); this._transientState = null; this._isBrandNew = MochiKit.Base.isUndefinedOrNull(args.reference); this.record().addDirectLogin(this); return this; } Clipperz.Base.extend(Clipperz.PM.DataModel.DirectLogin, Object, { 'toString': function() { return "DirectLogin (" + this.reference() + ")"; }, //========================================================================= 'reference': function () { return this._reference; }, //------------------------------------------------------------------------- 'record': function () { return this._record; }, //========================================================================= 'isBrandNew': function () { return this._isBrandNew; }, //========================================================================= 'removeIndexDataFunction': function () { return this._removeIndexDataFunction; }, 'remove': function () { return Clipperz.Async.callbacks("DirectLogin.remove", [ MochiKit.Base.partial(this.removeIndexDataFunction(), this.reference()), MochiKit.Base.method(this.record(), 'removeDirectLogin', this) ], {trace:false}); }, //========================================================================= /* 'inputsDeferredLock': function () { return this._inputsDeferredLock; }, 'bindingsDeferredLock': function () { return this._bindingsDeferredLock; }, 'formValuesDeferredLock': function () { return this._formValuesDeferredLock; }, */ //========================================================================= 'label': function () { return this.getIndexDataForKey('label'); }, 'setLabelKeepingBackwardCompatibilityWithBeta': function (aValue) { return Clipperz.Async.callbacks("DirectLogin.setLabelKeepingBackwardCompatibilityWithBeta", [ MochiKit.Base.method(this, 'setIndexDataForKey', 'label', aValue), MochiKit.Base.method(this, 'setValue', 'label', aValue) ], {trace:false}); }, 'setLabel': function (aValue) { return this.setLabelKeepingBackwardCompatibilityWithBeta(aValue); // return this.setIndexDataForKey('label', aValue); }, //========================================================================= 'favicon': function () { return this.getIndexDataForKey('favicon'); }, 'setFavicon': function (aValue) { return this.setIndexDataForKey('favicon', aValue); }, 'faviconUrlWithBookmarkletConfiguration': function (aBookmarkletConfiguration) { var result; if (! MochiKit.Base.isUndefinedOrNull(aBookmarkletConfiguration['page']['favicon'])) { result = aBookmarkletConfiguration['page']['favicon']; } else if (! MochiKit.Base.isUndefinedOrNull(aBookmarkletConfiguration['form']['attributes']['action'])) { var actionUrl; var hostname; actionUrl = aBookmarkletConfiguration['form']['attributes']['action']; hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1'); result = "http://" + hostname + "/favicon.ico"; } else { result = null; } return result; }, //------------------------------------------------------------------------- /* 'faviconData': function () { var regexp = new RegExp('^data\:\/\/.*', 'i'); return Clipperz.Async.callbacks("DirectLogin.favicon", [ MochiKit.Base.method(this, 'getIndexDataForKey', 'favicon'), MochiKit.Base.method(regexp, 'test'), Clipperz.Async.deferredIf("is data URL", [ MochiKit.Base.method(this, 'getIndexDataForKey', 'favicon') ], [ MochiKit.Base.method(this, 'transientState'), MochiKit.Base.itemgetter('faviconData'), Clipperz.Async.deferredIf('has a chaced value for the favicon data', [ MochiKit.Base.operator.identity ], [ MochiKit.Base.method(this, 'getIndexDataForKey', 'favicon'), MochiKit.Base.method(this, 'loadFaviconDataFromURL') ]) ]) ], {trace:false}); }, //------------------------------------------------------------------------- 'loadFaviconDataFromURL': function (anURL) { var deferredResult; var image; deferredResult = new Clipperz.Async.Deferred("DirectLogin.loadFaviconDataFromURL", {trace:false}); deferredResult.addCallback(function (anEvent) { var image = anEvent.src(); var canvas = document.createElement("canvas"); var result; canvas.width = image.width; canvas.height = image.height; var ctx = canvas.getContext("2d"); ctx.drawImage(image, 0, 0); result = canvas.toDataURL(/*"image/png"* /); return result; }); deferredResult.addErrback(MochiKit.Async.succeed, Clipperz.PM.Strings.getValue('defaultFaviconUrl')); deferredResult.addBoth(MochiKit.Base.bind(function (aDataUrl) { this.transientState()['faviconData'] = aDataUrl; return aDataUrl; }, this)); image = new Image(); MochiKit.Signal.connect(image, 'onload', MochiKit.Base.method(deferredResult, 'callback')); MochiKit.Signal.connect(image, 'onerror', MochiKit.Base.method(deferredResult, 'errback')); MochiKit.Signal.connect(image, 'onabort', MochiKit.Base.method(deferredResult, 'errback')); image.src = anURL; return deferredResult; }, */ //========================================================================= 'type': function () { return this.getValue('formData.attributes.type') }, //========================================================================= 'serializedData': function () { return Clipperz.Async.collectResults("DirectLogin.serializedData", { 'bookmarkletVersion': MochiKit.Base.method(this, 'getValue', 'bookmarkletVersion'), 'formData': MochiKit.Base.method(this, 'getValue', 'formData'), 'formValues': MochiKit.Base.method(this, 'getValue', 'formValues'), 'bindingData': [ MochiKit.Base.method(this, 'bindings'), function (someBindings) { var result; var bindingKey; result = {} for (bindingKey in someBindings) { result[bindingKey] = someBindings[bindingKey].serializedData(); } return result; } ] }, {trace:false})() }, //========================================================================= /* 'fixFormDataFromBookmarkletVersion_0_1': function(aValue) { //{"type":"radio", "name":"action", "value":"new-user", "checked":false }, { "type":"radio", "name":"action", "value":"sign-in", "checked":true } // || // \ / // \/ //{"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}]} var result; var inputs; var updatedInputs; var radios; result = aValue; inputs = aValue['inputs']; updatedInputs = MochiKit.Base.filter(function(anInput) { var result; var type; type = anInput['type'] || 'text'; result = type.toLowerCase() != 'radio'; return result; }, inputs); radios = MochiKit.Base.filter(function(anInput) { var result; var type; type = anInput['type'] || 'text'; result = type.toLowerCase() == 'radio'; return result; }, inputs); if (radios.length > 0) { var updatedRadios; updatedRadios = {}; MochiKit.Iter.forEach(radios, MochiKit.Base.bind(function(aRadio) { var radioConfiguration; radioConfiguration = updatedRadios[aRadio['name']]; if (radioConfiguration == null) { radioConfiguration = {type:'radio', name:aRadio['name'], options:[]}; updatedRadios[aRadio['name']] = radioConfiguration; } // TODO: remove the value: field and replace it with element.dom.value = radioConfiguration.options.push({value:aRadio['value'], checked:aRadio['checked']}); // TODO: shoud remove the 'formValues' call, as it is now deferred // if ((aRadio['checked'] == true) && (this.formValues()[aRadio['name']] == null)) { // this.formValues()[aRadio['name']] = aRadio['value']; // } }, this)) updatedInputs = MochiKit.Base.concat(updatedInputs, MochiKit.Base.values(updatedRadios)); } delete result.inputs; result.inputs = updatedInputs; return result; }, '_fixConfiguration': function (aConfiguration) { var fixedConfiguration; // var inputs; // var bindings; // var i,c; fixedConfiguration = Clipperz.Base.deepClone(aConfiguration); //console.log("PROCESS CONFIGURATION", aConfiguration); switch (aConfiguration['bookmarkletVersion']) { case '0.1': fixedConfiguration['formData'] = this.fixFormDataFromBookmarkletVersion_0_1(aConfiguration['formData']); break; case '0.2': fixedConfiguration['formData'] = aConfiguration['formData']; break; } / * aConfiguration['_inputs'] = []; c = formData['inputs'].length; for (i=0; i", {trace:false}); // innerDeferredResult.addMethod(this.record(), 'getValue', 'directLogins' + '.' + this.reference()); innerDeferredResult.addMethod(this, 'getValue', ''), innerDeferredResult.addMethod(this, 'setOriginalState'); innerDeferredResult.addMethod(this, '_fixConfiguration'); innerDeferredResult.addMethod(this._objectDataStore, 'initWithValues'); // innerDeferredResult.addMethod(this._objectDataStore, 'setValues'); innerDeferredResult.callback(); } else { innerDeferredResult = MochiKit.Async.succeed(this._objectDataStore); } return innerDeferredResult; }, this)); deferredResult.releaseLock(this.objectDataStoreDeferredLock()); deferredResult.callback(); return deferredResult; }, //------------------------------------------------------------------------- 'hasInitiatedObjectDataStore': function () { return (this._objectDataStore != null); }, //------------------------------------------------------------------------- 'resetObjectDataStore': function () { this._objectDataStore.removeAllData(); this._objectDataStore = null; }, */ //========================================================================= 'bookmarkletConfiguration': function () { return Clipperz.Async.callbacks("DirectLogin.bookmarkletConfiguration", [ Clipperz.Async.collectResults("DirectLogin.bookmarkletConfiguration ", { 'label': MochiKit.Base.method(this, 'label'), 'configuration': MochiKit.Base.method(this, 'getValue', '') }, {trace:false}), function (someValues) { var result; if (someValues['configuration'] != null) { var configuration; configuration = { 'page': { 'title': someValues['label'] // 'favicon' // 'url' }, 'form': someValues['configuration']['formData'], 'version': someValues['configuration']['bookmarkletVersion'] } result = Clipperz.Base.formatJSON(configuration); } else { result = ''; } return result; } ], {trace:false}); }, //------------------------------------------------------------------------- 'setBookmarkletConfiguration': function (aValue) { var bookmarkletConfiguration; bookmarkletConfiguration = Clipperz.PM.DataModel.DirectLogin.checkBookmarkletConfiguration(aValue); //console.log("BOOKMARKLET CONFIGURATION", bookmarkletConfiguration); return Clipperz.Async.callbacks("DirectLogin.setBookmarkletConfiguration", [ MochiKit.Base.method(this, 'setValue', 'formData', bookmarkletConfiguration['form']), //function (aValue) { console.log("SET VALUE - formData", aValue); return aValue; }, MochiKit.Base.method(this, 'setValue', 'bookmarkletVersion', bookmarkletConfiguration['version']), MochiKit.Base.method(this, 'favicon'), Clipperz.Async.deferredIf("the favicon is not set", [ ], [ MochiKit.Base.method(this, 'faviconUrlWithBookmarkletConfiguration', bookmarkletConfiguration), MochiKit.Base.method(this, 'setFavicon') ]), MochiKit.Base.method(this, 'updateInputsAfterChangingBookmarkletConfiguration'), MochiKit.Base.method(this, 'updateFormValuesAfterChangingBookmarkletConfiguration'), MochiKit.Base.method(this, 'updateBindingsAfterChangingBookmarkletConfiguration'), MochiKit.Base.noop ], {trace:false}); }, //========================================================================= 'formAttributes': function () { return this.getValue('formData.attributes'); }, //========================================================================= 'inputs': function () { return Clipperz.Async.callbacks("DirectLogin.inputs", [ Clipperz.Async.deferredIf("this._inputs is defined", [ ], [ MochiKit.Base.method(this, 'updateInputsAfterChangingBookmarkletConfiguration') ]) ], {trace:false}, this._inputs); }, 'setInputWithFormDataConfiguration': function (aFormDataConfiguration) { this._inputs = {}; if (aFormDataConfiguration != null) { MochiKit.Iter.forEach(aFormDataConfiguration['inputs'], MochiKit.Base.bind(function (anInputData) { var newInput; newInput = new Clipperz.PM.DataModel.DirectLoginInput(anInputData); this._inputs[newInput.name()] = newInput; }, this)); } return this._inputs; }, 'updateInputsAfterChangingBookmarkletConfiguration': function () { return Clipperz.Async.callbacks("DirectLogin.updateInputsAfterChangingBookmarkletConfiguration", [ // MochiKit.Base.method(this, 'getValue', ''), //function (aValue) { console.log("VALUE", aValue); return aValue }, MochiKit.Base.method(this, 'getValue', 'formData'), //function (aValue) { console.log("FORM DATA", aValue); return aValue }, MochiKit.Base.method(this, 'setInputWithFormDataConfiguration') ], {trace:false}); }, //========================================================================= 'inputValues': function () { return Clipperz.Async.callbacks("DirectLogin.inputValues", [ MochiKit.Base.method(this, 'inputs'), MochiKit.Base.values, //function (aValue) { console.log("INPUTS", aValue); return aValue; }, MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.partial(MochiKit.Base.method(this, 'inputValue'))), Clipperz.Async.collectAll, Clipperz.Base.mergeItems ], {trace:false}); }, 'inputValue': function (anInput) { var deferredResult; deferredResult = new Clipperz.Async.Deferred("DirectLogin.inputValue", {trace:false}); if (anInput.needsFormValue()) { deferredResult.addMethod(this, 'formValues'); deferredResult.addCallback(MochiKit.Base.itemgetter(anInput.name())); deferredResult.addMethodcaller('value'); } else if (anInput.needsBinding()) { deferredResult.addMethod(this, 'bindings'); deferredResult.addCallback(MochiKit.Base.itemgetter(anInput.name())); deferredResult.addMethodcaller('field'); deferredResult.addMethodcaller('value'); } else { deferredResult.addCallback(MochiKit.Async.succeed, anInput.value()); } deferredResult.addCallback(function (anActualValue) { return [anInput.name(), anActualValue]; }); deferredResult.callback(); return deferredResult; }, //========================================================================= 'bindings': function () { return Clipperz.Async.callbacks("DirectLogin.bindings", [ Clipperz.Async.deferredIf("this._bindings is defined", [ ], [ MochiKit.Base.method(this, 'updateBindingsAfterChangingBookmarkletConfiguration'), MochiKit.Base.bind(function () { return this._bindings;}, this) ]) ], {trace:false}, this._bindings); }, 'bindFormFieldWithLabelToRecordFieldWithLabel': function (aFormFieldLabel, aRecordFieldLabel) { return Clipperz.Async.callbacks("DirectLogin.bindFormFieldWithLabelToCardFieldWithLabel", [ Clipperz.Async.collectResults("DirectLogin.bindFormFieldWithLabelToCardFieldWithLabel - collect results", { 'binding': [ MochiKit.Base.method(this, 'bindings'), MochiKit.Base.itemgetter(aFormFieldLabel) ], 'field': [ MochiKit.Base.method(this.record(), 'fieldWithLabel', aRecordFieldLabel) ] }), function (someValues) { someValues['binding'].setField(someValues['field']) } ], {trace:false}); }, //------------------------------------------------------------------------- /* 'bindingValues': function () { return Clipperz.Async.callbacks("DirectLogin.bindingValues", [ Clipperz.Async.collectResults("DirectLogin.bindingValues [collectResults]", { 'fieldValues': [ MochiKit.Base.method(this, 'record'), MochiKit.Base.methodcaller('getFieldsValues') ], 'bindings': MochiKit.Base.method(this, 'bindings') }, {trace:false}), function (someData) { var result; var bindingKey; result = {}; for (bindingKey in someData['bindings']) { result[bindingKey] = someData['fieldValues'][someData['bindings'][bindingKey].fieldKey()]['value']; } return result; } ], {trace:false}); }, */ //------------------------------------------------------------------------- 'updateBindingsAfterChangingBookmarkletConfiguration': function () { return Clipperz.Async.callbacks("DirectLogin.updateBindingsAfterChangingBookmarkletConfiguration", [ Clipperz.Async.collectResults("DirectLogin.updateBindingsAfterChangingBookmarkletConfiguration", { 'currentValues': MochiKit.Base.method(this, 'getValue', ''), 'originalValues': MochiKit.Base.method(this, 'originalConfiguration'), 'inputs': MochiKit.Base.method(this, 'inputs') }, {trace:false}), MochiKit.Base.bind(function (someValues) { var availableBindingValues; var inputRequiringBindingValues; var newBindingValues; if (MochiKit.Base.isUndefinedOrNull(someValues['originalValues']) || MochiKit.Base.isUndefinedOrNull(someValues['originalValues']['bindingData'])) { availableBindingValues = {}; } else { availableBindingValues = Clipperz.Base.deepClone(someValues['originalValues']['bindingData']) } if (someValues['currentValues'] != null) { MochiKit.Base.update(availableBindingValues, someValues['currentValues']['bindingData']); } this._bindings = {}; newBindingValues = {} MochiKit.Iter.forEach(MochiKit.Base.filter(MochiKit.Base.methodcaller('needsBinding'), MochiKit.Base.values(someValues['inputs'])), MochiKit.Base.bind(function (anInput) { var newBinding; newBindingValues[anInput.name()] = availableBindingValues[anInput.name()]; newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, { 'key': anInput.name(), 'field': availableBindingValues[anInput.name()] }); this._bindings[anInput.name()] = newBinding; }, this)) //console.log("THIS._BINDINGS", this._bindings); return newBindingValues; /* this._bindings = {}; //console.log("CONFIGURATION", aConfiguration); if (someValues['currentValues'] != null) { if (someValues['currentValues']['bindingData'] != null) { var bindingKey; //console.log("BINDING DATA", someValues['currentValues']['bindingData']); for (bindingKey in someValues['currentValues']['bindingData']) { var newBinding; newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, { 'key': bindingKey, 'field': someValues['currentValues']['bindingData'][bindingKey] }); this._bindings[newBinding.key()] = newBinding; } } else if (someValues['currentValues']['legacyBindingData'] == null) { var bindingKey; for (bindingKey in someValues['currentValues']['legacyBindingData']) { var newBinding; newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, { 'key': bindingKey, 'field': someValues['currentValues']['legacyBindingData'][bindingKey] }); this._bindings[newBinding.key()] = newBinding; } } else { WTF = TODO; } } return this._bindings; */ }, this), MochiKit.Base.method(this, 'setValue', 'bindingData') ], {trace:false}); }, //========================================================================= 'formValues': function () { return Clipperz.Async.callbacks("DirectLogin.formValues", [ Clipperz.Async.deferredIf("this._formValues is defined", [ ], [ MochiKit.Base.method(this, 'updateFormValuesAfterChangingBookmarkletConfiguration'), MochiKit.Base.bind(function () { return this._formValues;}, this) ]) ], {trace:false}, this._formValues); }, //------------------------------------------------------------------------- 'updateFormValuesAfterChangingBookmarkletConfiguration': function () { return Clipperz.Async.callbacks("DirectLogin.updateFormValuesAfterChangingBookmarkletConfiguration", [ Clipperz.Async.collectResults("DirectLogin.updateFormValuesAfterChangingBookmarkletConfiguration ", { 'currentValues': MochiKit.Base.method(this, 'getValue', ''), 'originalValues': MochiKit.Base.method(this, 'originalConfiguration'), 'inputs': MochiKit.Base.method(this, 'inputs') }, {trace:false}), MochiKit.Base.bind(function (someValues) { var availableFormValues; var inputRequiringFormValues; var newFormValues; if (MochiKit.Base.isUndefinedOrNull(someValues['originalValues']) || MochiKit.Base.isUndefinedOrNull(someValues['originalValues']['formValues'])) { availableFormValues = {}; } else { availableFormValues = Clipperz.Base.deepClone(someValues['originalValues']['formValues']) } MochiKit.Base.update(availableFormValues, someValues['currentValues']['formValues']); this._formValues = {}; newFormValues = {}; MochiKit.Iter.forEach(MochiKit.Base.filter(MochiKit.Base.methodcaller('needsFormValue'), MochiKit.Base.values(someValues['inputs'])), MochiKit.Base.bind(function (anInput) { var newFormValue; var fieldOptions; fieldOptions = { 'type': anInput.type(), 'options': anInput.options() }; newFormValues[anInput.name()] = availableFormValues[anInput.name()] newFormValue = new Clipperz.PM.DataModel.DirectLoginFormValue(this, { 'key': anInput.name(), 'fieldOptions': fieldOptions, 'value': availableFormValues[anInput.name()] }); this._formValues[anInput.name()] = newFormValue; }, this)) return newFormValues; }, this), MochiKit.Base.method(this, 'setValue', 'formValues') ], {trace:false}); }, //========================================================================= 'retrieveIndexDataFunction': function () { return this._retrieveIndexDataFunction; }, 'getIndexDataForKey': function (aKey) { return Clipperz.Async.callbacks("DirectLogin.getIndexDataForKey", [ MochiKit.Base.partial(this.retrieveIndexDataFunction(), this.reference()), Clipperz.Async.deferredIf("DirectLogin.getIndexDataForKey - index data not null", [ MochiKit.Base.itemgetter(aKey) ],[ MochiKit.Async.succeed ]) ], {trace:false}); }, //------------------------------------------------------------------------- 'setIndexDataForKey': function (aKey, aValue) { return Clipperz.Async.callbacks("DirectLogin.setValueForKey", [ MochiKit.Base.method(this, 'getIndexDataForKey', aKey), MochiKit.Base.bind(function (anActualValue) { var transientStateKey; transientStateKey = 'original_' + aKey; if (MochiKit.Base.isUndefinedOrNull(this.transientState()[transientStateKey])) { if (anActualValue != aValue) { this.transientState()[transientStateKey] = anActualValue; } } else if (this.transientState()[transientStateKey] == aValue) { this.transientState()[transientStateKey] = null; } }, this), MochiKit.Base.partial(this._setIndexDataFunction, this.reference(), aKey, aValue) ], {trace:false}) }, //------------------------------------------------------------------------- /* 'setValueForKey': function (aKey, aValue) { return Clipperz.Async.callbacks("DirectLogin.setValueForKey", [ MochiKit.Base.method(this, 'getIndexDataForKey', aKey), MochiKit.Base.bind(function (anActualValue) { var transientStateKey; transientStateKey = 'original_' + aKey; if (MochiKit.Base.isUndefinedOrNull(this.transientState()[transientStateKey])) { if (anActualValue != aValue) { this.transientState()[transientStateKey] = anActualValue; } } else if (this.transientState()[transientStateKey] == aValue) { this.transientState()[transientStateKey] = null; } }, this), MochiKit.Base.method(this, 'setIndexDataForKey', aKey, aValue) ], {trace:false}) }, */ //========================================================================= /* 'storedConfiguration': function () { return this.record().getValue('directLogins' + '.' + this.reference()); }, // 'setStoredConfiguration': function (aValue) { // return this.record().setValue('directLogins' + '.' + this.reference(), aValue); // }, */ //========================================================================= 'hasPendingChanges': function () { var result; var deferredResult; result = false; result = result || this.isBrandNew(); result = result || (! MochiKit.Base.isUndefinedOrNull(this.transientState()['original_label'])); result = result || (! MochiKit.Base.isUndefinedOrNull(this.transientState()['original_favicon'])); if ((result == false) && (this.originalConfiguration() != null)) { deferredResult = Clipperz.Async.callbacks("DirectLogin.hasPendingChanges", [ MochiKit.Base.method(this, 'serializedData'), MochiKit.Base.bind(function (aCurrentConfiguration) { var originalConfiguration; var currentConfiguration; var result; originalConfiguration = this.originalConfiguration(); currentConfiguration = aCurrentConfiguration; result = false; result = result || (MochiKit.Base.compare(originalConfiguration['bookmarkletVersion'], currentConfiguration['bookmarkletVersion']) != 0); result = result || (MochiKit.Base.compare(originalConfiguration['formData'], currentConfiguration['formData']) != 0); result = result || (MochiKit.Base.compare(originalConfiguration['formValues'], currentConfiguration['formValues']) != 0); result = result || (MochiKit.Base.compare(originalConfiguration['bindingData'], currentConfiguration['bindingData']) != 0); return result; }, this) ], {trace:false}); } else { deferredResult = MochiKit.Async.succeed(result); } return deferredResult; }, //------------------------------------------------------------------------- 'revertChanges': function () { var deferredResult; if (this.transientState()['original_label'] != null) { this.setLabel(this.transientState()['original_label']); } if (this.transientState()['original_favicon'] != null) { this.setFavicon(this.transientState()['original_favicon']); } if (this.originalConfiguration() != null) { deferredResult = this.setValue('', this.originalConfiguration()); } else { deferredResult = MochiKit.Async.succeed(); } this._inputs = null; this._bindings = null; this._formValues = null; this.resetTransientState(false); /* if (this.hasInitiatedObjectDataStore()) { deferredResult = Clipperz.Async.callbacks("DirectLogin.revertChanges", [ // MochiKit.Base.method(this.record(), 'setValue', 'directLogins' + '.' + this.reference(), this.originalState()), MochiKit.Base.method(this, 'setValue', '', this.originalState()), MochiKit.Base.method(this, 'resetObjectDataStore') ], {trace:false}) } else { deferredResult = MochiKit.Async.succeed(); } */ return deferredResult; }, //========================================================================= 'transientState': function () { if (this._transientState == null) { this._transientState = {} } return this._transientState; }, 'resetTransientState': function (isCommitting) { this._transientState = null; }, 'commitTransientState': function (isCommitting) { this._transientState = null; this._isBrandNew = false; }, //------------------------------------------------------------------------- 'originalConfiguration': function () { return this.transientState()['original_configuration']; }, 'setOriginalConfiguration': function (aConfiguration) { this.transientState()['original_configuration'] = Clipperz.Base.deepClone(aConfiguration); }, //========================================================================= 'actualKey': function (aValueKey) { var actualKey; actualKey = 'directLogins' + '.' + this.reference(); if (aValueKey != '') { actualKey = actualKey + '.' + aValueKey; } return actualKey; }, //------------------------------------------------------------------------- 'getValue': function (aValueKey) { return this.record().getValue(this.actualKey(aValueKey)); }, 'setValue': function (aValueKey, aValue) { // return this.record().setValue(this.actualKey(aValueKey), aValue); return Clipperz.Async.callbacks("DirectLogin.setValue", [ MochiKit.Base.method(this, 'getValue', ''), MochiKit.Base.bind(function (aValue) { if (this.originalConfiguration() == null) { this.setOriginalConfiguration(aValue); } }, this), // MochiKit.Base.method(this, 'originalConfiguration'), // Clipperz.Async.deferredIf("originalConfiguration has been set", [ // ], [ // MochiKit.Base.method(this, 'getValue', ''), // MochiKit.Base.method(this, 'setOriginalConfiguration') // ]), MochiKit.Base.method(this.record(), 'setValue', this.actualKey(aValueKey), aValue) ], {trace:false}); }, 'removeValue': function (aValueKey) { // return this.record().removeValue(this.actualKey(aValueKey)); return Clipperz.Async.callbacks("DirectLogin.setValue", [ MochiKit.Base.method(this, 'originalConfiguration'), Clipperz.Async.deferredIf("originalConfiguration has been set", [ ], [ MochiKit.Base.method(this, 'getValue', ''), MochiKit.Base.method(this, 'setOriginalConfiguration') ]), MochiKit.Base.method(this.record(), 'removeValue', this.actualKey(aValueKey)) ], {trace:false}); }, //========================================================================= 'deleteAllCleanTextData': function () { this._inputs = null; this._bindings = null; this._formValues = null; this.resetTransientState(); }, //------------------------------------------------------------------------- 'hasAnyCleanTextData': function () { var result; result = false; result = result || (this._inputs != null); result = result || (this._bindings != null); result = result || (this._formValues != null); result = result || (MochiKit.Base.keys(this.transientState()).length != 0); return MochiKit.Async.succeed(result); }, //========================================================================= __syntaxFix__: "syntax fix" }); //############################################################################# Clipperz.PM.DataModel.DirectLogin.exception = { 'WrongBookmarkletConfiguration': new MochiKit.Base.NamedError("Clipperz.PM.DataModel.DirectLogin.exception.WrongBookmarkletConfiguration") }; Clipperz.PM.DataModel.DirectLogin.checkBookmarkletConfiguration = function(aConfiguration) { var configuration; try { configuration = Clipperz.Base.evalJSON(aConfiguration); // configuration = Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration(configuration); if (MochiKit.Base.isUndefinedOrNull(configuration['page']['title']) || MochiKit.Base.isUndefinedOrNull(configuration['form']['attributes']['action']) // || MochiKit.Base.isUndefinedOrNull(configuration['form']['attributes']['method']) || MochiKit.Base.isUndefinedOrNull(configuration['form']['inputs']) || MochiKit.Base.isUndefinedOrNull(configuration['version']) ) { throw Clipperz.PM.DataModel.DirectLogin.exception.WrongBookmarkletConfiguration; } // if (MochiKit.Base.isUndefinedOrNull(configuration['favicon'])) { // throw Clipperz.PM.DataModel.DirectLogin.exception.WrongBookmarkletConfiguration; // } } catch (exception) { throw exception; } return configuration; };