mirror of
				http://git.whoc.org.uk/git/password-manager.git
				synced 2025-10-31 03:17:35 +01:00 
			
		
		
		
	offline copy link and better feedback when saving
Added offline copy link (still rough UI) and improved feedback when performing tasks that would eventually save data (long operation)
This commit is contained in:
		| @@ -22,12 +22,12 @@ refer to http://www.clipperz.com. | ||||
| */ | ||||
|  | ||||
| "use strict"; | ||||
| Clipperz.Base.module('Clipperz.PM.DataModel'); | ||||
|  | ||||
| try { if (typeof(Clipperz.KeyValueObjectStore) == 'undefined') { throw ""; }} catch (e) { | ||||
| 	throw "Clipperz.PM.DataModel.EncryptedRemoteObject depends on Clipperz.KeyValueObjectStore!"; | ||||
| }   | ||||
|  | ||||
| Clipperz.Base.module('Clipperz.PM.DataModel'); | ||||
|  | ||||
| //if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | ||||
| //if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } | ||||
|  | ||||
| @@ -46,21 +46,19 @@ Clipperz.PM.DataModel.EncryptedRemoteObject = function(args) { | ||||
|  | ||||
| 	this._retrieveRemoteDataFunction	= args.retrieveRemoteDataFunction	|| null; | ||||
| 	this._remoteData					= args.remoteData					|| null; | ||||
| //	this._remoteData					= args.remoteData ? Clipperz.Base.deepClone(args.remoteData) : null; | ||||
|  | ||||
| 	if ((!this._isBrandNew) && ((this._retrieveRemoteDataFunction == null) && (this._remoteData == null))) { | ||||
| 		Clipperz.Base.exception.raise('MandatoryParameter'); | ||||
| 	} | ||||
|  | ||||
| 	this._encryptedDataKeypath			= args.encryptedDataKeypath			|| 'data'; | ||||
| 	this._encryptedVersionKeypath		= args.encryptedVersionKeypath		|| 'version'; | ||||
|  | ||||
| 	this._encryptedDataKeypath			= args.encryptedDataKeypath			|| 'data';		//Clipperz.Base.exception.raise('MandatoryParameter'); | ||||
| 	this._encryptedVersionKeypath		= args.encryptedVersionKeypath		|| 'version';	//Clipperz.Base.exception.raise('MandatoryParameter'); | ||||
|  | ||||
| 	 | ||||
| 	this._transientState = null; | ||||
| 	this._deferredLocks = {}; | ||||
|  | ||||
| 	if (this._isBrandNew == true) { | ||||
| 		this._objectDataStore = new Clipperz.KeyValueObjectStore(/*{'name':'EncryptedRemoteObject.objectDataStore [1]'}*/); | ||||
| 		this._objectDataStore = new Clipperz.KeyValueObjectStore(); | ||||
| 	} else { | ||||
| 		this._objectDataStore = null; | ||||
| 	} | ||||
| @@ -111,7 +109,7 @@ Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(nul | ||||
|  | ||||
| 	'transientState': function () { | ||||
| 		if (this._transientState == null) { | ||||
| 			this._transientState = new Clipperz.KeyValueObjectStore(/*{'name':'EncryptedRemoteObject.transientState [2]'}*/); | ||||
| 			this._transientState = new Clipperz.KeyValueObjectStore(); | ||||
| 		} | ||||
| 		 | ||||
| 		return this._transientState; | ||||
| @@ -166,6 +164,7 @@ Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(nul | ||||
| 	//------------------------------------------------------------------------- | ||||
|  | ||||
| 	'hasLoadedRemoteData': function () { | ||||
| //console.log("EncryptedRemoteObject.hasLoadedRemoteData", this._remoteData); | ||||
| 		return (this._remoteData != null); | ||||
| 	}, | ||||
|  | ||||
| @@ -237,7 +236,7 @@ Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(nul | ||||
|  | ||||
| 	'decryptedDataStore': function () { | ||||
| 		if (this._decryptedDataStore == null) { | ||||
| 			this._decryptedDataStore = new Clipperz.KeyValueObjectStore(/*{'name':'EncryptedRemoteObject.decryptedDataStore [3]'}*/); | ||||
| 			this._decryptedDataStore = new Clipperz.KeyValueObjectStore(); | ||||
| 		}; | ||||
| 		 | ||||
| 		return this._decryptedDataStore; | ||||
| @@ -343,7 +342,7 @@ Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(nul | ||||
|  | ||||
| 			if (this._objectDataStore == null) { | ||||
| //console.log("EncryptedRemoteObject._getObjectDataStore", this._reference); | ||||
| 				this._objectDataStore = new Clipperz.KeyValueObjectStore(/*{'name':'EncryptedRemoteObject.objectDataStore [4]'}*/); | ||||
| 				this._objectDataStore = new Clipperz.KeyValueObjectStore(); | ||||
|  | ||||
| 				innerDeferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObject._getObjectDataStore <inner deferred>", {trace:false}); | ||||
| 				innerDeferredResult.addMethod(this, 'getDecryptedData'); | ||||
| @@ -434,7 +433,6 @@ Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(nul | ||||
| 	'commitTransientState': function () { | ||||
| 		var deferredResult; | ||||
|  | ||||
| //		if (this.transientState().getValue('__prepareRemoteData') == true) { | ||||
| 		if (this.transientState().getValue('packedRemoteData') != null) { | ||||
| 			deferredResult = Clipperz.Async.callbacks("EncryptedRemoteObject.commitTransientState - prepareRemoteData", [ | ||||
| 				MochiKit.Base.bind(function (someData) { | ||||
| @@ -463,6 +461,7 @@ Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(nul | ||||
| 	//------------------------------------------------------------------------- | ||||
|  | ||||
| 	'revertChanges': function () { | ||||
| //console.log("> EncryptedRemoveObject.revertChanges", this.toString(), this.hasInitiatedObjectDataStore()); | ||||
| 		if (this.hasInitiatedObjectDataStore()) { | ||||
| 			this._objectDataStore.removeAllData(); | ||||
| 			this._objectDataStore = null; | ||||
| @@ -523,7 +522,6 @@ Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(nul | ||||
|  | ||||
| 	'prepareRemoteDataWithKey': function (aKey) { | ||||
| 		return Clipperz.Async.callbacks("EncryptedRemoteObject.prepareRemoteDataWithKey", [ | ||||
| //			MochiKit.Base.method(this.transientState(), 'setValue', '__prepareRemoteData', true), | ||||
| 			MochiKit.Base.method(this, '_getObjectDataStore'), | ||||
| 			MochiKit.Base.methodcaller('values'), | ||||
| 			MochiKit.Base.method(this, 'packData'), | ||||
|   | ||||
| @@ -21,6 +21,9 @@ refer to http://www.clipperz.com. | ||||
|  | ||||
| */ | ||||
|  | ||||
| "use strict"; | ||||
|  | ||||
| Clipperz.Base.module('Clipperz.PM.DataModel'); | ||||
| try { if (typeof(Clipperz.PM.DataModel.Record) == 'undefined') { throw ""; }} catch (e) { | ||||
| 	throw "Clipperz.PM.DataModel.Record.Version depends on Clipperz.PM.DataModel.Record!"; | ||||
| }   | ||||
| @@ -29,7 +32,7 @@ Clipperz.PM.DataModel.Record.Version = function(args) { | ||||
| 	Clipperz.PM.DataModel.Record.Version.superclass.constructor.apply(this, arguments); | ||||
|  | ||||
| 	this._getVersionFunction = args.getVersion	|| Clipperz.Base.exception.raise('MandatoryParameter'); | ||||
| 	this._fields = null; | ||||
| //	this._fields = null; | ||||
|  | ||||
| 	return this; | ||||
| } | ||||
| @@ -43,9 +46,9 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record.Version, Clipperz.PM.DataModel | ||||
|  | ||||
| 	//------------------------------------------------------------------------- | ||||
|  | ||||
| 	'reference': function () { | ||||
| 		return this._reference; | ||||
| 	}, | ||||
| //	'reference': function () { | ||||
| //		return this._reference; | ||||
| //	}, | ||||
| 	 | ||||
| 	//------------------------------------------------------------------------- | ||||
| /* | ||||
| @@ -128,13 +131,13 @@ console.log("Record.Version.hasPendingChanges"); | ||||
| 		deferredResult.addCallback(MochiKit.Base.bind(function () { | ||||
| 			var innerDeferredResult; | ||||
|  | ||||
| 			if (this._fields == null) { | ||||
| //			if (this._fields == null) { | ||||
| 				innerDeferredResult = new Clipperz.Async.Deferred("Record.Version.fields <inner deferred>", {trace:false}); | ||||
| 				innerDeferredResult.addMethod(this, 'getValue', 'fields'); | ||||
| 				innerDeferredResult.addCallback(MochiKit.Base.bind(function (someObjectData) { | ||||
| 					var reference; | ||||
|  | ||||
| 					this._fields = {}; | ||||
| 					var result = {}; | ||||
| //					this._fields = {}; | ||||
| 					 | ||||
| 					for (reference in someObjectData) { | ||||
| 						var	recordVersionField; | ||||
| @@ -144,15 +147,17 @@ console.log("Record.Version.hasPendingChanges"); | ||||
| 							'reference':		reference | ||||
| 						}); | ||||
| 			 | ||||
| 						this._fields[reference] = recordVersionField; | ||||
| //						this._fields[reference] = recordVersionField; | ||||
| 						result[reference] = recordVersionField; | ||||
| 					} | ||||
|  | ||||
| 					return this._fields; | ||||
| //					return this._fields; | ||||
| 					return result; | ||||
| 				}, this)); | ||||
| 				innerDeferredResult.callback(); | ||||
| 			} else { | ||||
| 				innerDeferredResult = MochiKit.Async.succeed(this._fields); | ||||
| 			} | ||||
| //			} else { | ||||
| //				innerDeferredResult = MochiKit.Async.succeed(this._fields); | ||||
| //			} | ||||
| 			 | ||||
| 			return innerDeferredResult; | ||||
| 		}, this)); | ||||
| @@ -182,10 +187,9 @@ console.log("Record.Version.hasPendingChanges"); | ||||
| 			MochiKit.Base.methodcaller('values'), | ||||
| 			Clipperz.Base.serializeJSON, | ||||
|  | ||||
| 			MochiKit.Base.bind(function () { this._fields[newField.reference()] = newField; }, this), | ||||
| //			MochiKit.Base.bind(function () { this._fields[newField.reference()] = newField; }, this), | ||||
| 			MochiKit.Base.method(newField,	'setLabel',		someParameters['label']), | ||||
| 			MochiKit.Base.method(newField,	'setValue',		someParameters['value']), | ||||
| //			MochiKit.Base.method(newField,	'setIsHidden',	someParameters['isHidden']), | ||||
| 			MochiKit.Base.method(newField,	'setIsHidden',	someParameters['hidden']), | ||||
|  | ||||
| 			MochiKit.Base.method(this, '_getObjectDataStore'), | ||||
| @@ -201,39 +205,12 @@ console.log("Record.Version.hasPendingChanges"); | ||||
| 	'removeField': function (aField) { | ||||
| 		return Clipperz.Async.callbacks("Record.Version.removeField", [ | ||||
| 			MochiKit.Base.method(this, 'fields'), | ||||
| 			MochiKit.Base.bind(function () { delete this._fields[aField.reference()]; }, this), | ||||
| //			MochiKit.Base.bind(function () { delete this._fields[aField.reference()]; }, this), | ||||
| 			MochiKit.Base.method(this, 'removeValue', 'fields' + '.' + aField.reference()) | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
|  | ||||
| 	//------------------------------------------------------------------------- | ||||
| /* | ||||
| 	'sortFieldReference': function (someSortedFieldReferences) { | ||||
|  | ||||
|  | ||||
|  | ||||
| 	}, | ||||
| */ | ||||
| 	//========================================================================= | ||||
| /* | ||||
| 	'directLogins': function () { | ||||
| 		return MochiKit.Base.values(this._directLogins); | ||||
| 	}, | ||||
|  | ||||
| 	'addDirectLogin': function (aDirectLogin) { | ||||
| 		this._directLogins[aDirectLogin.reference()] = aDirectLogin; | ||||
| 	}, | ||||
| */ | ||||
|  | ||||
| 	//========================================================================= | ||||
| /* | ||||
| 	'updateValues': function (anotherVersion) { | ||||
| 		return Clipperz.Async.callbacks("Record.Version.updateValue", [ | ||||
| 			MochiKit.Base.partial(MochiKit.Async.succeed, this) | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
| */ | ||||
| 	//========================================================================= | ||||
|  | ||||
| 	'setRemoteData': function (aValue) { | ||||
| 		this._remoteData = aValue; | ||||
| @@ -241,7 +218,7 @@ console.log("Record.Version.hasPendingChanges"); | ||||
| 		return aValue; | ||||
| 	}, | ||||
|  | ||||
| 	//========================================================================= | ||||
| 	//------------------------------------------------------------------------- | ||||
|  | ||||
| 	'getVersionFunction': function () { | ||||
| 		return this._getVersionFunction; | ||||
| @@ -276,9 +253,10 @@ console.log("Record.Version.hasPendingChanges"); | ||||
| 	//========================================================================= | ||||
|  | ||||
| 	'revertChanges': function () { | ||||
| //console.log("Record.Version.revertChanges", this.reference(), this.transientState()['originalReference']); | ||||
| 		this.setReference(this.transientState()['originalReference']); | ||||
| 		Clipperz.PM.DataModel.Record.Version.superclass.revertChanges.apply(this, arguments); | ||||
| 		this._fields = null; | ||||
| //		this._fields = null; | ||||
| 	}, | ||||
|  | ||||
| 	//------------------------------------------------------------------------- | ||||
| @@ -313,15 +291,15 @@ console.log("Record.Version.hasPendingChanges"); | ||||
| 	}, | ||||
|  | ||||
| 	//========================================================================= | ||||
|  | ||||
| /* | ||||
| 	'deleteAllCleanTextData': function () { | ||||
| 		this._fields = null; | ||||
| //		this._fields = null; | ||||
| 		return Clipperz.PM.DataModel.Record.Version.superclass.deleteAllCleanTextData.apply(this, arguments); | ||||
| 	}, | ||||
|  | ||||
| 	'hasAnyCleanTextData': function () { | ||||
| //		return Clipperz.PM.DataModel.Record.Version.superclass.hasAnyCleanTextData.apply(this, arguments); | ||||
|  | ||||
| 		return Clipperz.PM.DataModel.Record.Version.superclass.hasAnyCleanTextData.apply(this, arguments); | ||||
| / * | ||||
| 		var	deferredResult; | ||||
| 		 | ||||
| 		deferredResult = new Clipperz.Async.Deferred("Record.Version.hasAnyCleanTextData", {trace:false}); | ||||
| @@ -335,8 +313,9 @@ console.log("Record.Version.hasPendingChanges"); | ||||
| 		deferredResult.callback(); | ||||
|  | ||||
| 		return deferredResult; | ||||
| * / | ||||
| 	}, | ||||
|  | ||||
| */ | ||||
| 	//========================================================================= | ||||
| 	__syntaxFix__: "syntax fix" | ||||
| }); | ||||
|   | ||||
| @@ -77,9 +77,9 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt | ||||
|  | ||||
| 	//------------------------------------------------------------------------- | ||||
|  | ||||
| 	'reference': function () { | ||||
| 		return this._reference; | ||||
| 	}, | ||||
| //	'reference': function () { | ||||
| //		return this._reference; | ||||
| //	}, | ||||
| 	 | ||||
| 	//========================================================================= | ||||
|  | ||||
| @@ -171,6 +171,10 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt | ||||
| 		return new RegExp('^\\s+|\\s+$', 'g'); | ||||
| 	}, | ||||
|  | ||||
| //	'tagCleanupRegExp': function () { | ||||
| //		return new RegExp('\\' + Clipperz.PM.DataModel.Record.tagSpace, 'g'); | ||||
| //	}, | ||||
| 	 | ||||
| 	//............................................................................ | ||||
|  | ||||
| 	'filterOutTags': function (aValue) { | ||||
| @@ -217,7 +221,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt | ||||
| 		match = tagRegEx.exec(aLabel); | ||||
| 		while (match != null) { | ||||
| 			result[match[1]] = true; | ||||
| 		    match = tagRegEx.exec(aLabel); | ||||
| 			match = tagRegEx.exec(aLabel); | ||||
| 		}		 | ||||
| 		 | ||||
| 		return result; | ||||
| @@ -232,10 +236,12 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt | ||||
| 	}, | ||||
|  | ||||
| 	'addTag': function (aNewTag) { | ||||
| //		var	tag = aNewTag.replace(/\s/g, Clipperz.PM.DataModel.Record.tagSpace); | ||||
| //console.log("TAG", aNewTag, tag); | ||||
| 		return Clipperz.Async.callbacks("Record.addTag", [ | ||||
| 			MochiKit.Base.method(this, 'fullLabel'), | ||||
| 			MochiKit.Base.method(this, 'extractTagsFromFullLabel'), | ||||
| 			function (someTags) { someTags[aNewTag] = true; /* console.log("UPDATED TAGS", someTags); */ return someTags; }, | ||||
| 			function (someTags) { someTags[aNewTag] = true; return someTags; }, | ||||
| 			MochiKit.Base.method(this, 'updateTags') | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
| @@ -631,12 +637,18 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt | ||||
| 		var	deferredResult; | ||||
| 		var transientStateKey; | ||||
|  | ||||
| 		if (typeof(aVersionReference) == 'undefined') { | ||||
| 			console.log("ERROR; getVersionKey aVersionReference is undefined"); | ||||
| 		} | ||||
|  | ||||
| 		transientStateKey = 'versionKeys' + '.' + aVersionReference; | ||||
| 		if (this.transientState().getValue(transientStateKey) != null) { | ||||
| 			deferredResult = MochiKit.Async.succeed(this.transientState().getValue(transientStateKey)); | ||||
| 		} else { | ||||
| 			deferredResult = Clipperz.Async.callbacks("Record.getVersionKey", [ | ||||
| //MochiKit.Base.bind(function () {console.log("VERSION REFERENCE", aVersionReference, this.currentVersionReference()); }, this), | ||||
| 				MochiKit.Base.method(this, 'getVersions'), | ||||
| //function (aValue) { console.log("VERSIONs", aValue); return aValue; }, | ||||
| 				MochiKit.Base.partial(MochiKit.Base.operator.eq, aVersionReference, this.currentVersionReference()), | ||||
| 				Clipperz.Async.deferredIf("getVersionKey for current version", [ | ||||
| 					MochiKit.Base.method(this, 'getCurrentRecordVersionKey'), | ||||
| @@ -758,7 +770,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt | ||||
| 	'invokeCurrentRecordVersionMethod': function (aMethodName, someValues) { | ||||
| 		return Clipperz.Async.callbacks("Record.invokeCurrentRecordVersionMethod", [ | ||||
| 			MochiKit.Base.method(this, 'getCurrentRecordVersion'), | ||||
| 			MochiKit.Base.methodcaller(aMethodName, someValues) | ||||
| 			MochiKit.Base.methodcaller(aMethodName, someValues), | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
|  | ||||
| @@ -833,26 +845,18 @@ deferredResult.addCallback(function (aValue) { console.log("Record.hasPendingCha | ||||
|  | ||||
| 	'hasPendingChanges': function () { | ||||
| 		var deferredResult; | ||||
| //		var recordReference = this.reference(); | ||||
| 		var	self = this; | ||||
| 		var recordReference = this.reference(); | ||||
| //		var	self = this; | ||||
|  | ||||
| 		deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.hasPendingChanges", {trace:false}); | ||||
| 		deferredResult.collectResults({ | ||||
| 			'super': [ | ||||
| 				MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.hasPendingChanges, this), | ||||
|  | ||||
| //				MochiKit.Base.method(this, 'hasInitiatedObjectDataStore'), | ||||
| //				Clipperz.Async.deferredIf("Record.hasPendingChanges - hasInitiatedObjectDataStore", [ | ||||
| //					MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.hasPendingChanges, this), | ||||
| //				], [ | ||||
| //					MochiKit.Base.partial(MochiKit.Async.succeed, false), | ||||
| //				]), | ||||
| 			],	 | ||||
| 			'currentVersion': [ | ||||
| //				MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'hasPendingChanges') | ||||
| 				MochiKit.Base.method(this, 'hasInitiatedObjectDataStore'), | ||||
| 				Clipperz.Async.deferredIf("Record.hasPendingChanges - hasInitiatedObjectDataStore", [ | ||||
| 					MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'hasPendingChanges') | ||||
| 					MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'hasPendingChanges'), | ||||
| 				], [ | ||||
| 					MochiKit.Base.partial(MochiKit.Async.succeed, false), | ||||
| 				]), | ||||
| @@ -939,39 +943,47 @@ console.log("Record.hasPendingChanges RESULT", result); | ||||
|  | ||||
| 	'revertChanges': function () { | ||||
| 		var deferredResult; | ||||
| 		var recordReference = this.reference(); | ||||
| //		var recordReference = this.reference(); | ||||
| 		 | ||||
| 		if (this.isBrandNew() == false) { | ||||
| /* | ||||
| /* */ | ||||
| 			deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.revertChanges", {trace:false}); | ||||
| 			deferredResult.addMethod(this, 'hasPendingChanges'); | ||||
| deferredResult.addCallback(function (aValue) {  | ||||
| 	if (recordReference == 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045') { | ||||
| 		console.log("Record.revertChanges - hasPendingChanges", aValue); | ||||
| 	} | ||||
| //deferredResult.addCallback(function (aValue) {  | ||||
| //	if (recordReference == 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045') { | ||||
| //		console.log("Record.revertChanges - hasPendingChanges", aValue); | ||||
| //	} | ||||
| //	return aValue; | ||||
| 	return true; | ||||
| }); | ||||
| //	return true; | ||||
| //}); | ||||
| 			deferredResult.addIf([ | ||||
| //function (aValue) { console.log("Record.revertChanges - 1"); return aValue; }, | ||||
| 				MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'revertChanges'), | ||||
| //function (aValue) { console.log("Record.revertChanges - 2"); return aValue; }, | ||||
| 				 | ||||
| 				MochiKit.Base.method(this, 'directLogins'), | ||||
| //function (aValue) { console.log("Record.revertChanges - 3"); return aValue; }, | ||||
| 				MochiKit.Base.values, | ||||
| //function (aValue) { console.log("Record.revertChanges - 4"); return aValue; }, | ||||
| 				MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('revertChanges')), | ||||
| //function (aValue) { console.log("Record.revertChanges - 5"); return aValue; }, | ||||
|  | ||||
| 				MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.revertChanges, this) | ||||
| 				MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.revertChanges, this), | ||||
| //function (aValue) { console.log("Record.revertChanges - 6"); return aValue; }, | ||||
| 			], [ | ||||
| 				MochiKit.Async.succeed | ||||
| 			]); | ||||
| 			deferredResult.callback(); | ||||
| */ | ||||
| /* * / | ||||
| 			deferredResult = Clipperz.Async.callbacks("Clipperz.PM.DataModel.Record.revertChanges", [ | ||||
| 				MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'revertChanges'), | ||||
| 				MochiKit.Base.method(this, 'directLogins'), | ||||
| 				MochiKit.Base.values, | ||||
| 				MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('revertChanges')), | ||||
|  | ||||
| 				MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.revertChanges, this) | ||||
| 				MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'revertChanges'), | ||||
| 				MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.revertChanges, this), | ||||
| 			], {trace:false}); | ||||
| / * */ | ||||
| 		} else { | ||||
| //			this.deleteAllCleanTextData(); | ||||
| 			deferredResult = MochiKit.Async.succeed(); | ||||
| @@ -1115,7 +1127,7 @@ deferredResult.addCallback(function (aValue) { | ||||
| 			}, | ||||
| //function (aValue) { console.log("Sorted Keys", aValue); return aValue; }, | ||||
| 			MochiKit.Base.partial(MochiKit.Base.map, function (aReference) { return currentFieldValues[aReference]; }), | ||||
| function (aValue) { console.log("Sorted Field values", aValue); return aValue; }, | ||||
| //function (aValue) { console.log("Sorted Field values", aValue); return aValue; }, | ||||
| 			MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addField')), | ||||
| 			Clipperz.Async.collectAll, | ||||
| 		], [ | ||||
| @@ -1147,7 +1159,7 @@ function (aValue) { console.log("Sorted Field values", aValue); return aValue; } | ||||
| 			Clipperz.Async.collectAll, | ||||
|  | ||||
| 			MochiKit.Base.method(aRecord, 'directLogins'), MochiKit.Base.values, | ||||
| function (aValue) { console.log("-> DirectLogin Values", aValue); return aValue; }, | ||||
| //function (aValue) { console.log("-> DirectLogin Values", aValue); return aValue; }, | ||||
| 			MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addDirectLogin')), | ||||
| //function (aValue) { console.log("-> DirectLogin Values", aValue); return aValue; }, | ||||
| //			Clipperz.Async.collectAll, | ||||
| @@ -1173,10 +1185,11 @@ Clipperz.PM.DataModel.Record.defaultCardInfo = { | ||||
| }; | ||||
| Clipperz.PM.DataModel.Record.defaultSearchField = '_searchableContent'; | ||||
|  | ||||
| Clipperz.PM.DataModel.Record.tagChar = '\uE009'; | ||||
| Clipperz.PM.DataModel.Record.specialTagChar = '\uE010'; | ||||
| Clipperz.PM.DataModel.Record.tagChar =			'\uE009'; | ||||
| Clipperz.PM.DataModel.Record.specialTagChar =	'\uE010'; | ||||
| //Clipperz.PM.DataModel.Record.tagSpace =			'\uE011'; | ||||
| Clipperz.PM.DataModel.Record.specialTagsConstructor = function (aTag) { | ||||
| 	return Clipperz.PM.DataModel.Record.specialTagChar + aTag; | ||||
| 	return Clipperz.PM.DataModel.Record.specialTagChar + aTag;	//.replace(/\s/g, Clipperz.PM.DataModel.Record.tagSpace); | ||||
| } | ||||
| Clipperz.PM.DataModel.Record.archivedTag = Clipperz.PM.DataModel.Record.specialTagsConstructor('ARCH'); | ||||
| Clipperz.PM.DataModel.Record.regExpForTag = function (aTag) { | ||||
|   | ||||
| @@ -227,7 +227,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, { | ||||
| 		 | ||||
| 							this._records[reference] = record; | ||||
| 						} else { | ||||
| Clipperz.log("SKIPPING record " + reference + " as there are no stas associated - " + Clipperz.Base.serializeJSON(someData['records'][reference])); | ||||
| Clipperz.log("SKIPPING record " + reference + " as there are no stats associated - " + Clipperz.Base.serializeJSON(someData['records'][reference])); | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
|   | ||||
| @@ -547,11 +547,12 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
|  | ||||
| 	'getRecordsInfo': function (someInfo, shouldIncludeArchivedCards) { | ||||
| 	'getRecordsInfo': function (someInfo /*, shouldIncludeArchivedCards */) { | ||||
| 		return Clipperz.Async.callbacks("User.getRecordsInfo", [ | ||||
| 			MochiKit.Base.method(this, 'getRecords'), | ||||
| 			MochiKit.Base.partial(MochiKit.Base.map, Clipperz.Async.collectResults("collectResults", someInfo, {trace:false})), | ||||
| 			Clipperz.Async.collectAll, | ||||
| /* | ||||
| 			function (aResult) { | ||||
| 				var result; | ||||
| 				 | ||||
| @@ -563,7 +564,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { | ||||
| 				 | ||||
| 				return result; | ||||
| 			} | ||||
| 			 | ||||
| */			 | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
| 	 | ||||
| @@ -665,21 +666,15 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { | ||||
| 		var	user = this; | ||||
| 		 | ||||
| 		return Clipperz.Async.callbacks("User.cloneRecord", [ | ||||
| //			MochiKit.Base.method(this, 'createNewRecord'), | ||||
| //			MochiKit.Base.methodcaller('setUpWithRecord', aRecord), | ||||
| //			function (aValue) { result = aValue; return aValue; }, | ||||
| //			MochiKit.Base.method(this, 'saveChanges'), | ||||
| //			function () { return result; } | ||||
|  | ||||
| 			MochiKit.Base.method(this, 'hasPendingChanges'), | ||||
| 			Clipperz.Async.deferredIf("User has pending changes", [ | ||||
| 				MochiKit.Async.fail | ||||
| 			], [ | ||||
| 				MochiKit.Base.method(user, 'createNewRecord'), | ||||
| 				MochiKit.Base.methodcaller('setUpWithRecord', aRecord), | ||||
| 				function (aValue) { result = aValue; return aValue; }, | ||||
| 				MochiKit.Base.method(user, 'saveChanges'), | ||||
| 				function () { return result; } | ||||
| //				function (aValue) { result = aValue; return aValue; }, | ||||
| //				MochiKit.Base.method(user, 'saveChanges'), | ||||
| //				function () { return result; } | ||||
| 			]) | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
| @@ -781,9 +776,13 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, { | ||||
|  | ||||
| 	'revertChanges': function () { | ||||
| 		return Clipperz.Async.callbacks("User.revertChanges", [ | ||||
| //function (aValue) { console.log("User.revertChanges - 1"); return aValue; }, | ||||
| 			MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'), | ||||
| //function (aValue) { console.log("User.revertChanges - 2"); return aValue; }, | ||||
| 			MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'), | ||||
| 			MochiKit.Base.method(this, 'resetTransientState', false) | ||||
| //function (aValue) { console.log("User.revertChanges - 3"); return aValue; }, | ||||
| 			MochiKit.Base.method(this, 'resetTransientState', false), | ||||
| //function (aValue) { console.log("User.revertChanges - 4"); return aValue; }, | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
|  | ||||
|   | ||||
| @@ -21,6 +21,7 @@ refer to http://www.clipperz.com. | ||||
|  | ||||
| */ | ||||
|  | ||||
| "use strict"; | ||||
| Clipperz.Base.module('Clipperz.PM.UI.Components.Panels'); | ||||
|  | ||||
| Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel = React.createClass({ | ||||
| @@ -30,6 +31,10 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel = React.createClass({ | ||||
| 		MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'toggleSettingsPanel'); | ||||
| 	}, | ||||
|  | ||||
| 	handleDownloadOfflineCopyLink: function (anEvent) { | ||||
| 		MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'downloadOfflineCopy'); | ||||
| 	}, | ||||
| 	 | ||||
| 	//========================================================================= | ||||
|  | ||||
| 	render: function () { | ||||
| @@ -45,33 +50,39 @@ Clipperz.PM.UI.Components.Panels.ExtraFeaturesPanel = React.createClass({ | ||||
| 					Clipperz.PM.UI.Components.Button({eventName:'settingsToggleButton', label:"menu", handler:this.settingsToggleHandler}) | ||||
| 				]) | ||||
| 			]), | ||||
| 			React.DOM.h2({}, "Extra features") | ||||
|  | ||||
| 			React.DOM.div({}, [ | ||||
| 				React.DOM.ul({}, [ | ||||
| 					React.DOM.li({}, [ | ||||
| 						React.DOM.h1({}, "Account"), | ||||
| 					]), | ||||
| 					React.DOM.li({}, [ | ||||
| 						React.DOM.h1({}, "Data"), | ||||
| 						React.DOM.ul({}, [ | ||||
| 							React.DOM.li({}, [ | ||||
| 								React.DOM.h2({}, "Offline copy"), | ||||
| 								React.DOM.div({}, [ | ||||
| 									React.DOM.p({}, "With just one click you can dump all your encrypted data from Clipperz servers to your hard disk and create a read-only offline version of Clipperz to be used when you are not connected to the Internet."), | ||||
| 									React.DOM.a({'onClick':this.handleDownloadOfflineCopyLink}, "Download") | ||||
| 								]) | ||||
| 							]), | ||||
| 							React.DOM.li({}, [ | ||||
| 								React.DOM.h2({}, "Sharing"), | ||||
| 							]), | ||||
| 							React.DOM.li({}, [ | ||||
| 								React.DOM.h2({}, "Import"), | ||||
| 							]), | ||||
| 							React.DOM.li({}, [ | ||||
| 								React.DOM.h2({}, "Export"), | ||||
| 							]) | ||||
| 						]) | ||||
| 					]), | ||||
| 					React.DOM.li({}, [ | ||||
| 						React.DOM.h1({}, "Tools"), | ||||
| 					]) | ||||
| 				]) | ||||
| 			]) | ||||
| 		]); | ||||
| /* | ||||
| 		<div id="extraFeaturesPanel" class="panel extraFeatures"> | ||||
|  | ||||
| 			<div class="warnings"> | ||||
| 				<ul> | ||||
| 					<li>Synchronize local data</li> | ||||
| 				</ul> | ||||
| 			</div> | ||||
|  | ||||
| 			<ul> | ||||
| 				<li>Account</li> | ||||
| 				<li>Subscription</li> | ||||
| 			</ul> | ||||
|  | ||||
| 			<ul> | ||||
| 				<li>Local Data</li> | ||||
| 				<li>OTP</li> | ||||
| 			</ul> | ||||
|  | ||||
| 			<div class="donation"> | ||||
| 				<a>Make a donation</a> | ||||
| 			</div> | ||||
| 		</div> | ||||
| */ | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	//========================================================================= | ||||
|   | ||||
| @@ -60,7 +60,7 @@ Clipperz.PM.UI.Components.Selections = React.createClass({ | ||||
| 		var	filterType; | ||||
| 		var	filterValue; | ||||
|  | ||||
| console.log("SELECTIONS PROPS", this.props); | ||||
| //console.log("SELECTIONS PROPS", this.props); | ||||
| 		tagInfo = this.props['tags'] ? this.props['tags'] : {}; | ||||
| 		tags = MochiKit.Base.filter(Clipperz.PM.DataModel.Record.isRegularTag, MochiKit.Base.keys(tagInfo)).sort(Clipperz.Base.caseInsensitiveCompare); | ||||
| 		archivedCardsCount = this.props['archivedCardsCount']; | ||||
|   | ||||
| @@ -73,6 +73,7 @@ Clipperz.PM.UI.MainController = function() { | ||||
| 		'showArchivedCards', 'hideArchivedCards', | ||||
| 		'goBackToMainPage', | ||||
| 		'maskClick', | ||||
| 		'downloadOfflineCopy', | ||||
| 	]); | ||||
|  | ||||
| //	MochiKit.Signal.connect(MochiKit.DOM.currentDocument(), 'onselectionchange', this, 'selectionChange_handler'); | ||||
| @@ -636,6 +637,7 @@ console.log("SET USER", aUser); | ||||
| 		var deferredResult; | ||||
|  | ||||
| 		deferredResult = new Clipperz.Async.Deferred('MainController.refreshUI', {trace:false}); | ||||
| 		deferredResult.addMethod(this, 'resetRecordsInfo'), | ||||
| 		deferredResult.addMethod(this, 'refreshSelectedCards'); | ||||
| 		deferredResult.addMethod(this, 'renderTags'); | ||||
| 		 | ||||
| @@ -1034,9 +1036,12 @@ console.log("SET USER", aUser); | ||||
| //	}, | ||||
|  | ||||
| 	saveChanges: function () { | ||||
| 		//	TODO: handle errors while savings | ||||
| 		return Clipperz.Async.callbacks("MainController.saveChanges", [ | ||||
| 			MochiKit.Base.method(this.overlay(), 'show', "saving …", true), | ||||
| 			MochiKit.Base.method(this.user(), 'saveChanges'), | ||||
| 			MochiKit.Base.method(this, 'resetRecordsInfo'), | ||||
| //			MochiKit.Base.method(this, 'resetRecordsInfo'), | ||||
| 			MochiKit.Base.method(this.overlay(), 'done', "saved", 1), | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
|  | ||||
| @@ -1046,11 +1051,11 @@ console.log("SET USER", aUser); | ||||
| 		 | ||||
| 		return Clipperz.Async.callbacks("MainController.saveCardEdits_handler", [ | ||||
| 			MochiKit.Base.method(currentPage, 'setProps', {'showGlobalMask':true}), | ||||
| 			MochiKit.Base.method(this.overlay(), 'show', "saving …", true), | ||||
| //			MochiKit.Base.method(this.overlay(), 'show', "saving …", true), | ||||
| 			MochiKit.Base.method(this, 'saveChanges'), | ||||
| 			MochiKit.Base.method(currentPage, 'setProps', {'mode':'view', 'showGlobalMask':false}), | ||||
| 			MochiKit.Base.method(this, 'refreshUI', aRecordReference), | ||||
| 			MochiKit.Base.method(this.overlay(), 'done', "saved", 1), | ||||
| //			MochiKit.Base.method(this.overlay(), 'done', "saved", 1), | ||||
| 		], {trace:false}); | ||||
| 	}, | ||||
|  | ||||
| @@ -1160,16 +1165,26 @@ console.log("SET USER", aUser); | ||||
| 	}, | ||||
|  | ||||
| 	cloneCard_handler: function (anEvent) { | ||||
| 		var	cardInfo; | ||||
|  | ||||
| //console.log("CLONE CARD", anEvent['reference']); | ||||
| 		return Clipperz.Async.callbacks("MainController.cloneCard_handler", [ | ||||
| 			MochiKit.Base.method(this.user(), 'getRecord', anEvent['reference']), | ||||
| 			MochiKit.Base.method(this.user(), 'cloneRecord'), | ||||
| 			MochiKit.Base.methodcaller('reference'), | ||||
| 			Clipperz.Async.collectResults("MainController.cloneCard_handler <card info>", { | ||||
| 				'label': MochiKit.Base.methodcaller('label'), | ||||
| 				'reference': MochiKit.Base.methodcaller('reference') | ||||
| 			}, {trace:false}), | ||||
| 			function (aValue) { cardInfo = aValue; return aValue; }, | ||||
| 			MochiKit.Base.method(this, 'saveChanges'), | ||||
|  | ||||
| 			function (aValue) { | ||||
| 				MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'cardSelected', cardInfo); | ||||
| 			}, | ||||
| 			 | ||||
| 			function (aValue) { return cardInfo['reference']; }, | ||||
| 			MochiKit.Base.method(this, 'refreshUI'), | ||||
| //			MochiKit.Base.bind(function () { | ||||
| //				this.pages()[this.currentPage()].setProps({'mode': 'edit'}); | ||||
| //			}, this), | ||||
| 		], {trace:false}); | ||||
| 		], {trace:true}); | ||||
| 	}, | ||||
| 	 | ||||
| 	enterEditMode: function () { | ||||
| @@ -1322,7 +1337,27 @@ console.log("SET USER", aUser); | ||||
| 	hasKeyboard: function () { | ||||
| 		return this._hasKeyboard; | ||||
| 	}, | ||||
| 	 | ||||
|  | ||||
| 	//============================================================================ | ||||
|  | ||||
| 	'downloadOfflineCopy_handler': function (anEvent) { | ||||
| 		var downloadHref; | ||||
| 		var	deferredResult; | ||||
| 		var newWindow; | ||||
| 		 | ||||
| 		downloadHref = window.location.href.replace(/\/[^\/]*$/,'') + Clipperz_dumpUrl; | ||||
| 		newWindow = window.open("", ""); | ||||
|  | ||||
| 		deferredResult = new Clipperz.Async.Deferred("AppController.handleDownloadOfflineCopy", {trace:false}); | ||||
| 		deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'echo', {'echo':"echo"}); | ||||
| 		deferredResult.addCallback(function(aWindow) { | ||||
| 			aWindow.location.href = downloadHref; | ||||
| 		}, newWindow); | ||||
| 		deferredResult.callback(); | ||||
| 		 | ||||
| 		return deferredResult; | ||||
| 	}, | ||||
|  | ||||
| 	//============================================================================ | ||||
| /* | ||||
| 	wrongAppVersion: function (anError) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Giulio Cesare Solaroli
					Giulio Cesare Solaroli