mirror of
http://git.whoc.org.uk/git/password-manager.git
synced 2025-10-25 17:47:34 +02:00
Implemented Attachments in client
This commit is contained in:
374
frontend/delta/js/Clipperz/PM/DataModel/Attachment.js
Normal file
374
frontend/delta/js/Clipperz/PM/DataModel/Attachment.js
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
|
||||
Copyright 2008-2015 Clipperz Srl
|
||||
|
||||
This file is part of Clipperz, the online password manager.
|
||||
For further information about its features and functionalities please
|
||||
refer to http://www.clipperz.com.
|
||||
|
||||
* Clipperz 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.
|
||||
|
||||
* Clipperz 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 Clipperz. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
*/
|
||||
|
||||
Clipperz.Base.module('Clipperz.PM.DataModel');
|
||||
|
||||
Clipperz.PM.DataModel.Attachment = function(args) {
|
||||
args = args || {};
|
||||
|
||||
Clipperz.PM.DataModel.Attachment.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().retrieveAttachmentIndexDataFunction()
|
||||
// || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||
// this._setIndexDataFunction = args.setIndexDataFunction
|
||||
// || this.record().setAttachmentIndexDataFunction()
|
||||
// || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||
// this._removeIndexDataFunction = args.removeIndexDataFunction
|
||||
// || this.record().removeAttachmentIndexDataFunction()
|
||||
// || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||
|
||||
// this.setFile(args.file);
|
||||
|
||||
this._transientState = null;
|
||||
|
||||
this._isBrandNew = MochiKit.Base.isUndefinedOrNull(args.reference);
|
||||
|
||||
this.record().bindAttachment(this);
|
||||
|
||||
if (this._isBrandNew) {
|
||||
this.setKey(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(256/8));
|
||||
this.setNonce(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Clipperz.Base.extend(Clipperz.PM.DataModel.Attachment, Object, {
|
||||
|
||||
'toString': function() {
|
||||
return "Attachment (" + 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(), 'removeAttachment', this)
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'file': function () {
|
||||
// return this.getValue('name');
|
||||
return MochiKit.Async.succeed(this._file);
|
||||
},
|
||||
|
||||
'setFile': function (aFile) {
|
||||
this._file = aFile || null;
|
||||
|
||||
/* These ones will disappear when the application is closed */
|
||||
this._name = aFile ? aFile['name'] : null;
|
||||
this._contentType = aFile ? aFile['type'] : null;
|
||||
this._size = aFile ? aFile['size'] : null;
|
||||
|
||||
/* These ones will be saved in the Record */
|
||||
return Clipperz.Async.callbacks("Attachment.setFile", [
|
||||
MochiKit.Base.method(this, 'setValue', 'name', aFile['name']),
|
||||
MochiKit.Base.method(this, 'setValue', 'contentType', aFile['type']),
|
||||
MochiKit.Base.method(this, 'setValue', 'size', aFile['size']),
|
||||
|
||||
MochiKit.Base.partial(MochiKit.Async.succeed, this),
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'name': function () {
|
||||
return this.getValue('name');
|
||||
},
|
||||
|
||||
'contentType': function () {
|
||||
return this.getValue('contentType');
|
||||
},
|
||||
|
||||
'size': function () {
|
||||
return this.getValue('size');
|
||||
},
|
||||
|
||||
'metadata': function () {
|
||||
var deferredResult;
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("Attachment.metadata [collect results]", {trace:false});
|
||||
deferredResult.collectResults({
|
||||
'name': MochiKit.Base.method(this, 'name'),
|
||||
'type': MochiKit.Base.method(this, 'contentType'),
|
||||
'size': MochiKit.Base.method(this, 'size'),
|
||||
}, {trace:false});
|
||||
deferredResult.callback();
|
||||
|
||||
return deferredResult;
|
||||
|
||||
// return {
|
||||
// 'name': this._name,
|
||||
// 'type': this._type,
|
||||
// 'size': this._size,
|
||||
// }
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'key': function () {
|
||||
var byteArray;
|
||||
|
||||
byteArray = new Clipperz.ByteArray();
|
||||
|
||||
return Clipperz.Async.callbacks("Attachment.key", [
|
||||
MochiKit.Base.method(this, 'getValue', 'key'),
|
||||
MochiKit.Base.method(byteArray, 'appendBase64String'),
|
||||
function(aByteArray) { return new Uint8Array(aByteArray.arrayValues()); }
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
// 'key': function () {
|
||||
// var result;
|
||||
|
||||
// result = new Clipperz.ByteArray();
|
||||
|
||||
// return Clipperz.Async.callbacks("Attachment.key", [
|
||||
// MochiKit.Base.method(this, 'getValue', 'key'),
|
||||
// MochiKit.Base.method(result, 'appendBase64String'),
|
||||
// function(aByteArray) { return new Clipperz.Crypto.AES.Key({key: aByteArray}); }
|
||||
// ], {trace:false});
|
||||
// },
|
||||
|
||||
'nonce': function () {
|
||||
var byteArray;
|
||||
|
||||
byteArray = new Clipperz.ByteArray();
|
||||
|
||||
return Clipperz.Async.callbacks("Attachment.nonce", [
|
||||
MochiKit.Base.method(this, 'getValue', 'nonce'),
|
||||
MochiKit.Base.method(byteArray, 'appendBase64String'),
|
||||
function(aByteArray) { return new Uint8Array(aByteArray.arrayValues()); }
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
// 'nonce': function () {
|
||||
// var result;
|
||||
|
||||
// result = new Clipperz.ByteArray();
|
||||
|
||||
// return Clipperz.Async.callbacks("Attachment.nonce", [
|
||||
// MochiKit.Base.method(this, 'getValue', 'nonce'),
|
||||
// MochiKit.Base.method(result, 'appendBase64String')
|
||||
// ], {trace:false});
|
||||
// },
|
||||
|
||||
'setKey': function (aByteArray) {
|
||||
this.setValue('key', aByteArray.toBase64String());
|
||||
},
|
||||
|
||||
// 'setKey': function (aKey) {
|
||||
// var byteArray = aKey.key();
|
||||
// var serializedData = byteArray.toBase64String();
|
||||
|
||||
// this.setValue('key', serializedData);
|
||||
// },
|
||||
|
||||
'setNonce': function (aByteArray) {
|
||||
this.setValue('nonce', aByteArray.toBase64String());
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'serializedData': function () {
|
||||
return Clipperz.Async.collectResults("Attachment.serializedData", {
|
||||
'name': MochiKit.Base.method(this, 'name'),
|
||||
'contentType': MochiKit.Base.method(this, 'contentType'),
|
||||
'size': MochiKit.Base.method(this, 'size'),
|
||||
}, {trace:false})()
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'hasPendingChanges': function () {
|
||||
var result;
|
||||
// var deferredResult;
|
||||
|
||||
result = false;
|
||||
result = result || this.isBrandNew();
|
||||
|
||||
return MochiKit.Async.succeed(result);
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'revertChanges': function () {
|
||||
return MochiKit.Async.succeed();
|
||||
},
|
||||
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'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;
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'actualKey': function (aValueKey) {
|
||||
var actualKey;
|
||||
|
||||
actualKey = 'attachments' + '.' + this.reference();
|
||||
if (aValueKey != '') {
|
||||
actualKey = actualKey + '.' + aValueKey;
|
||||
}
|
||||
|
||||
return actualKey;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'getValue': function (aValueKey) {
|
||||
return this.record().getValue(this.actualKey(aValueKey));
|
||||
},
|
||||
|
||||
'setValue': function (aValueKey, aValue) {
|
||||
return Clipperz.Async.callbacks("Attachment.setValue", [
|
||||
// MochiKit.Base.method(this, 'getValue', ''),
|
||||
// MochiKit.Base.bind(function (aValue) {
|
||||
// if (this.originalConfiguration() == null) {
|
||||
// this.setOriginalConfiguration(aValue);
|
||||
// }
|
||||
// }, this),
|
||||
MochiKit.Base.method(this.record(), 'setValue', this.actualKey(aValueKey), aValue)
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
'removeValue': function (aValueKey) {
|
||||
return this.record().removeValue(this.actualKey(aValueKey));
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'content': function () {
|
||||
// return this.serializedData();
|
||||
// return MochiKit.Async.succeed(this);
|
||||
|
||||
var deferredResult;
|
||||
var fieldValues;
|
||||
|
||||
fieldValues = {};
|
||||
deferredResult = new Clipperz.Async.Deferred("Attachment.content", {trace:false});
|
||||
deferredResult.addMethod(this, 'reference');
|
||||
deferredResult.addCallback(function (aValue) { fieldValues['reference'] = aValue; });
|
||||
deferredResult.callback();
|
||||
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'deleteAllCleanTextData': function () {
|
||||
this._name = null;
|
||||
this._contentType = null;
|
||||
this._size = null;
|
||||
|
||||
this.resetTransientState();
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'hasAnyCleanTextData': function () {
|
||||
var result;
|
||||
|
||||
result = false;
|
||||
|
||||
result = result || (this._name != null);
|
||||
result = result || (this._contentType != null);
|
||||
result = result || (this._size != null);
|
||||
result = result || (MochiKit.Base.keys(this.transientState()).length != 0);
|
||||
|
||||
return MochiKit.Async.succeed(result);
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
__syntaxFix__: "syntax fix"
|
||||
});
|
||||
|
||||
Clipperz.PM.DataModel.Attachment.MAX_ATTACHMENT_SIZE = 50*1024*1024;
|
||||
|
||||
Clipperz.PM.DataModel.Attachment.contentTypeIcon = function (aContentType) {
|
||||
var result;
|
||||
|
||||
result = 'other file';
|
||||
|
||||
if (aContentType == "application/pdf") {
|
||||
result = 'pdf file';
|
||||
} else if (aContentType.indexOf('image/') == 0) {
|
||||
result = 'image file';
|
||||
} else if (aContentType.indexOf('model/') == 0) {
|
||||
result = 'other file';
|
||||
} else if (aContentType.indexOf('audio/') == 0) {
|
||||
result = 'audio file';
|
||||
} else if (aContentType.indexOf('text/') == 0) {
|
||||
result = 'text file';
|
||||
} else if (aContentType.indexOf('video/') == 0) {
|
||||
result = 'video file';
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
@@ -55,7 +55,7 @@ Clipperz.PM.DataModel.DirectLogin = function(args) {
|
||||
|
||||
this._isBrandNew = MochiKit.Base.isUndefinedOrNull(args.reference);
|
||||
|
||||
this.record().addDirectLogin(this);
|
||||
this.record().bindDirectLogin(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -1018,7 +1018,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.DirectLogin, Object, {
|
||||
'removeValue': function (aValueKey) {
|
||||
// return this.record().removeValue(this.actualKey(aValueKey));
|
||||
|
||||
return Clipperz.Async.callbacks("DirectLogin.setValue", [
|
||||
return Clipperz.Async.callbacks("DirectLogin.removeValue", [
|
||||
MochiKit.Base.method(this, 'originalConfiguration'),
|
||||
Clipperz.Async.deferredIf("originalConfiguration has been set", [
|
||||
], [
|
||||
|
||||
@@ -192,7 +192,7 @@ Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(nul
|
||||
innerDeferredResult = MochiKit.Async.succeed(this._remoteData);
|
||||
} else {
|
||||
innerDeferredResult = Clipperz.Async.callbacks("EncryptedRemoteObjects.getRemoteData <inner deferred>", [
|
||||
MochiKit.Base.partial(this.retrieveRemoteDataFunction(), this.reference()),
|
||||
MochiKit.Base.partial(this.retrieveRemoteDataFunction(), this),
|
||||
MochiKit.Base.method(this, 'setRemoteData'),
|
||||
], {trace:false});
|
||||
}
|
||||
@@ -542,3 +542,19 @@ Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(nul
|
||||
//-------------------------------------------------------------------------
|
||||
__syntaxFix__: "syntax fix"
|
||||
});
|
||||
|
||||
/*
|
||||
Clipperz.PM.DataModel.EncryptedRemoteObject.emptyObjectWithKey = function (aKey) {
|
||||
var key = "clipperz";
|
||||
var value = new Clipperz.ByteArray();
|
||||
var version = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
|
||||
// var remoteData = Clipperz.PM.Crypto.encrypt({'key':key, 'value':value, 'version':version});
|
||||
var remoteData = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(key, value);
|
||||
|
||||
return new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
||||
'reference': Clipperz.PM.Crypto.randomKey(),
|
||||
'remoteData': remoteData,
|
||||
'retrieveKeyFunction': function () { return key; },
|
||||
});
|
||||
};
|
||||
*/
|
||||
@@ -41,11 +41,18 @@ Clipperz.PM.DataModel.Record = function(args) {
|
||||
this._retrieveDirectLoginIndexDataFunction = args.retrieveDirectLoginIndexDataFunction || null;
|
||||
this._setDirectLoginIndexDataFunction = args.setDirectLoginIndexDataFunction || null;
|
||||
this._removeDirectLoginIndexDataFunction = args.removeDirectLoginIndexDataFunction || null;
|
||||
|
||||
this._createNewDirectLoginFunction = args.createNewDirectLoginFunction || null;
|
||||
|
||||
this._retrieveAttachmentIndexDataFunction = args.retrieveAttachmentIndexDataFunction || null;
|
||||
this._setAttachmentIndexDataFunction = args.setAttachmentIndexDataFunction || null;
|
||||
this._removeAttachmentIndexDataFunction = args.removeAttachmentIndexDataFunction || null;
|
||||
this._createNewAttachmentFunction = args.createNewAttachmentFunction || null;
|
||||
|
||||
this._attachmentServerStatus = {};
|
||||
|
||||
this._tags = [];
|
||||
this._directLogins = {};
|
||||
this._attachments = {};
|
||||
this._versions = {};
|
||||
|
||||
this._currentRecordVersion = null;
|
||||
@@ -132,6 +139,16 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
setAttachmentServerStatus: function(anObject) {
|
||||
this._attachmentServerStatus = anObject;
|
||||
},
|
||||
|
||||
getAttachmentServerStatus: function() {
|
||||
return this._attachmentServerStatus;
|
||||
},
|
||||
|
||||
//============================================================================
|
||||
/*
|
||||
'key': function () {
|
||||
@@ -283,6 +300,12 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
||||
return MochiKit.Async.succeed(this._accessDate);
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
attachmentsCount: function() {
|
||||
return MochiKit.Base.keys(this.attachments()).length;
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'favicon': function () {
|
||||
@@ -374,6 +397,13 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
||||
deferredResult.addCallback(MochiKit.Base.map, function (aValue) { result['directLogins'].push(aValue); });
|
||||
deferredResult.addCallback(function () { return result; });
|
||||
|
||||
deferredResult.addMethod(this, 'attachments');
|
||||
deferredResult.addCallback(MochiKit.Base.values);
|
||||
deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.methodcaller('content'));
|
||||
deferredResult.addCallback(Clipperz.Async.collectAll);
|
||||
deferredResult.addCallback(MochiKit.Base.map, function (aValue) { result['directLogins'].push(aValue); });
|
||||
deferredResult.addCallback(function () { return result; });
|
||||
|
||||
deferredResult.callback();
|
||||
|
||||
return deferredResult;
|
||||
@@ -385,7 +415,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
||||
return this._directLogins;
|
||||
},
|
||||
|
||||
'addDirectLogin': function (aDirectLogin) {
|
||||
'bindDirectLogin': function (aDirectLogin) {
|
||||
this._directLogins[aDirectLogin.reference()] = aDirectLogin;
|
||||
},
|
||||
|
||||
@@ -400,12 +430,13 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
||||
'saveOriginalDirectLoginStatusToTransientState': function () {
|
||||
if (this.transientState().getValue('directLogins') == null) {
|
||||
// this.transientState().setValue('directLogins', this._directLogins)
|
||||
this.transientState().setValue('directLogins', {});
|
||||
MochiKit.Iter.forEach(MochiKit.Base.keys(this._directLogins), MochiKit.Base.bind(function(aKey) {
|
||||
this.transientState().setValue('directLogins' + '.' + aKey, this._directLogins[aKey])
|
||||
}, this))
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
'createNewDirectLogin': function () {
|
||||
this.saveOriginalDirectLoginStatusToTransientState();
|
||||
|
||||
@@ -453,6 +484,81 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
||||
return result;
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
// TODO: !!!!
|
||||
'attachments': function () {
|
||||
return this._attachments;
|
||||
},
|
||||
|
||||
'bindAttachment': function (anAttachment) {
|
||||
this._attachments[anAttachment.reference()] = anAttachment;
|
||||
},
|
||||
|
||||
'attachmentWithReference': function (anAttachmentReference) {
|
||||
return this._attachments[anAttachmentReference];
|
||||
},
|
||||
|
||||
'createNewAttachmentFunction': function () {
|
||||
return this._createNewAttachmentFunction;
|
||||
},
|
||||
|
||||
'saveOriginalAttachmentStatusToTransientState': function () {
|
||||
if (this.transientState().getValue('attachments') == null) {
|
||||
// console.log("saving attachments to transient state: ts:", this.transientState());
|
||||
this.transientState().setValue('attachments', {});
|
||||
MochiKit.Iter.forEach(MochiKit.Base.keys(this._attachments), MochiKit.Base.bind(function(aKey) {
|
||||
// console.log("saving attachment to transient state:", this._attachments[aKey]);
|
||||
this.transientState().setValue('attachments' + '.' + aKey, this._attachments[aKey])
|
||||
}, this))
|
||||
}
|
||||
},
|
||||
|
||||
'createNewAttachment': function () {
|
||||
this.saveOriginalAttachmentStatusToTransientState();
|
||||
return this.createNewAttachmentFunction()(this);
|
||||
},
|
||||
|
||||
'removeAttachment': function(anAttachment) {
|
||||
this.saveOriginalAttachmentStatusToTransientState();
|
||||
return Clipperz.Async.callbacks("Record.removeAttachment", [
|
||||
MochiKit.Base.method(this, 'removeValue', 'attachments' + '.' + anAttachment.reference()),
|
||||
MochiKit.Base.bind(function () {
|
||||
this._removeAttachmentIndexDataFunction(anAttachment.reference());
|
||||
delete this._attachments[anAttachment.reference()]
|
||||
}, this)
|
||||
], {trace:false});
|
||||
|
||||
},
|
||||
|
||||
'attachmentReferences': function () {
|
||||
var result;
|
||||
|
||||
result = Clipperz.Async.callbacks("Record.attachmentReferences", [
|
||||
MochiKit.Base.method(this, 'attachments'),
|
||||
MochiKit.Base.values,
|
||||
function (someAttachments) {
|
||||
var result;
|
||||
var i,c;
|
||||
|
||||
result = [];
|
||||
c = someAttachments.length;
|
||||
for (i=0; i<c; i++) {
|
||||
result.push(Clipperz.Async.collectResults("Record.attachmentReferences - collectResults", {
|
||||
'_rowObject': MochiKit.Async.succeed,
|
||||
'_reference': MochiKit.Base.methodcaller('reference'),
|
||||
// 'label': MochiKit.Base.methodcaller('label'),
|
||||
// 'favicon': MochiKit.Base.methodcaller('favicon')
|
||||
}, {trace:false})(someAttachments[i]));
|
||||
};
|
||||
|
||||
return result;
|
||||
},
|
||||
Clipperz.Async.collectAll
|
||||
], {trace:false});
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'unpackRemoteData': function (someData) {
|
||||
@@ -508,6 +614,8 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
||||
newVersionKey = Clipperz.PM.Crypto.randomKey();
|
||||
result = {};
|
||||
|
||||
result['attachments'] = MochiKit.Base.keys(this.attachments());
|
||||
|
||||
deferredResult = new Clipperz.Async.Deferred("Record.prepareRemoteDataWithKey", {trace:false});
|
||||
deferredResult.addCallbackList([
|
||||
Clipperz.Async.collectResults("Record.prepareRemoteDataWithKey - collect results", {
|
||||
@@ -581,7 +689,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.Encrypt
|
||||
result = someFilteredResults[0];
|
||||
break;
|
||||
default:
|
||||
Clipperz.log("Warning: Record.fieldWithLabel('" + aLabel + "') is returning more than one result: " + someFilteredResults.length);
|
||||
//console.log("Warning: Record.fieldWithLabel('" + aLabel + "') is returning more than one result: " + someFilteredResults.length);
|
||||
result = someFilteredResults[0];
|
||||
break;
|
||||
}
|
||||
@@ -607,7 +715,7 @@ Clipperz.log("Warning: Record.fieldWithLabel('" + aLabel + "') is returning more
|
||||
var transientStateKey;
|
||||
|
||||
if (typeof(aVersionReference) == 'undefined') {
|
||||
Clipperz.log("ERROR; getVersionKey aVersionReference is undefined");
|
||||
console.log("ERROR; getVersionKey aVersionReference is undefined");
|
||||
}
|
||||
|
||||
transientStateKey = 'versionKeys' + '.' + aVersionReference;
|
||||
@@ -757,60 +865,6 @@ Clipperz.log("Warning: Record.fieldWithLabel('" + aLabel + "') is returning more
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
/*
|
||||
'hasPendingChanges': function () {
|
||||
var deferredResult;
|
||||
|
||||
if (this.hasInitiatedObjectDataStore()) {
|
||||
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),
|
||||
'currentVersion': [
|
||||
// MochiKit.Base.method(this, 'getCurrentRecordVersion'),
|
||||
// MochiKit.Base.methodcaller('hasPendingChanges')
|
||||
MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'hasPendingChanges')
|
||||
],
|
||||
'directLogins': [
|
||||
MochiKit.Base.method(this, 'directLogins'),
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasPendingChanges')),
|
||||
Clipperz.Async.collectAll,
|
||||
Clipperz.Async.or
|
||||
// function(someValues) {
|
||||
// return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
|
||||
// }
|
||||
]
|
||||
});
|
||||
deferredResult.addCallback(function (aValue) { console.log("Record.hasPendingChanges", aValue); return aValue; });
|
||||
deferredResult.addCallback(MochiKit.Base.values);
|
||||
deferredResult.addCallback(MochiKit.Base.bind(function(someValues) {
|
||||
var result;
|
||||
result = MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
|
||||
|
||||
if ((result == false) && (this.isBrandNew() == false)) {
|
||||
result = MochiKit.Iter.some(MochiKit.Base.values(this.transientState().getValue('hasPendingChanges.indexData')), MochiKit.Base.operator.identity);
|
||||
}
|
||||
|
||||
return result;
|
||||
}, this));
|
||||
|
||||
deferredResult.callback();
|
||||
} else {
|
||||
deferredResult = Clipperz.Async.callbacks("Recrod.hasPendingChanges [hasInitiatedObjectDataStore == false]", [
|
||||
MochiKit.Base.method(this, 'directLogins'),
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasPendingChanges')),
|
||||
Clipperz.Async.collectAll,
|
||||
Clipperz.Async.or
|
||||
// function(someValues) {
|
||||
// return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
|
||||
// }
|
||||
], {trace:false})
|
||||
}
|
||||
|
||||
return deferredResult;
|
||||
},
|
||||
*/
|
||||
|
||||
'hasPendingChanges': function () {
|
||||
var deferredResult;
|
||||
@@ -836,27 +890,18 @@ deferredResult.addCallback(function (aValue) { console.log("Record.hasPendingCha
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasPendingChanges')),
|
||||
Clipperz.Async.collectAll,
|
||||
Clipperz.Async.or
|
||||
],
|
||||
'attachments': [
|
||||
MochiKit.Base.method(this, 'attachments'),
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasPendingChanges')),
|
||||
Clipperz.Async.collectAll,
|
||||
Clipperz.Async.or
|
||||
]
|
||||
});
|
||||
//deferredResult.addCallback(function (someValues) {
|
||||
// if (recordReference == 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045') {
|
||||
// console.log("Record.hasPendingChanges VALUES", someValues);
|
||||
// }
|
||||
// return someValues;
|
||||
//})
|
||||
}, {trace:true});
|
||||
deferredResult.addCallback(MochiKit.Base.values);
|
||||
deferredResult.addCallback(MochiKit.Base.bind(function(someValues) {
|
||||
var result;
|
||||
result = MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
|
||||
/*
|
||||
if ((result == false) && (this.isBrandNew() == false)) {
|
||||
console.log("TRANSIENT STATE", this.transientState());
|
||||
console.log("TRANSIENT STATE - hasPendingChanges", this.transientState().getValue('hasPendingChanges.indexData'));
|
||||
result = MochiKit.Iter.some(MochiKit.Base.values(this.transientState().getValue('hasPendingChanges.indexData')), MochiKit.Base.operator.identity);
|
||||
}
|
||||
console.log("Record.hasPendingChanges RESULT", result);
|
||||
*/
|
||||
return result;
|
||||
deferredResult.addCallback(MochiKit.Base.bind(function (someValues) {
|
||||
return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
|
||||
}, this));
|
||||
|
||||
deferredResult.callback();
|
||||
@@ -911,6 +956,8 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
//=========================================================================
|
||||
|
||||
'revertChanges': function () {
|
||||
// console.log("Revert changes: attachments in transient state", this.transientState().getValue('attachments'));
|
||||
|
||||
var deferredResult;
|
||||
// var recordReference = this.reference();
|
||||
|
||||
@@ -926,19 +973,19 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
// return true;
|
||||
//});
|
||||
deferredResult.addIf([
|
||||
//function (aValue) { console.log("Record.revertChanges - 1"); return aValue; },
|
||||
MochiKit.Base.method(this, 'cancelRevertedAttachmentsUpload'),
|
||||
|
||||
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.method(this, 'attachments'),
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('revertChanges')),
|
||||
|
||||
MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.revertChanges, this),
|
||||
//function (aValue) { console.log("Record.revertChanges - 6"); return aValue; },
|
||||
MochiKit.Base.method(this, '_getObjectDataStore'),
|
||||
], [
|
||||
MochiKit.Async.succeed
|
||||
@@ -962,6 +1009,19 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
return deferredResult;
|
||||
},
|
||||
|
||||
cancelRevertedAttachmentsUpload: function() {
|
||||
var reference;
|
||||
|
||||
var transientStateAttachments = (this.transientState() ? this.transientState().values()['attachments'] : {}) || {};
|
||||
var savedReferences = MochiKit.Base.keys(transientStateAttachments);
|
||||
|
||||
for (reference in this.attachments()) {
|
||||
if (savedReferences.indexOf(reference) < 0) {
|
||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'cancelAttachment', this.attachments()[reference]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'resetTransientState': function (isCommitting) {
|
||||
@@ -969,6 +1029,8 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
// this._directLogins = this.transientState().getValue('directLogins');
|
||||
// }
|
||||
|
||||
// console.log("Reset transient state: attachments:", this.transientState().getValue('directLogins'));
|
||||
|
||||
return Clipperz.Async.callbacks("Record.resetTransientState", [
|
||||
//- MochiKit.Base.method(this, 'getCurrentRecordVersion'),
|
||||
//- MochiKit.Base.methodcaller('resetTransientState'),
|
||||
@@ -979,9 +1041,18 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('resetTransientState')),
|
||||
|
||||
MochiKit.Base.method(this, 'attachments'),
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('resetTransientState')),
|
||||
|
||||
MochiKit.Base.bind(function () {
|
||||
if ((isCommitting == false) && (this.transientState().getValue('directLogins') != null)) {
|
||||
this._directLogins = this.transientState().getValue('directLogins');
|
||||
if (isCommitting == false) {
|
||||
if (this.transientState().getValue('directLogins') != null) {
|
||||
this._directLogins = this.transientState().getValue('directLogins');
|
||||
}
|
||||
if (this.transientState().getValue('attachments') != null) {
|
||||
this._attachments = this.transientState().getValue('attachments');
|
||||
}
|
||||
}
|
||||
}, this),
|
||||
|
||||
@@ -1003,6 +1074,10 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'commitTransientState'),
|
||||
MochiKit.Base.method(this, 'directLogins'),
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('commitTransientState')),
|
||||
|
||||
MochiKit.Base.method(this, 'attachments'),
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('commitTransientState'))
|
||||
], [
|
||||
MochiKit.Async.succeed
|
||||
@@ -1028,6 +1103,20 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'retrieveAttachmentIndexDataFunction': function () {
|
||||
return this._retrieveAttachmentIndexDataFunction;
|
||||
},
|
||||
|
||||
'setAttachmentIndexDataFunction': function () {
|
||||
return this._setAttachmentIndexDataFunction;
|
||||
},
|
||||
|
||||
'removeAttachmentIndexDataFunction': function () {
|
||||
return this._removeAttachmentIndexDataFunction;
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'deleteAllCleanTextData': function () {
|
||||
// return Clipperz.PM.DataModel.Record.superclass.deleteAllCleanTextData.apply(this, arguments);
|
||||
|
||||
@@ -1040,6 +1129,10 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
|
||||
|
||||
MochiKit.Base.method(this, 'attachments'),
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
|
||||
|
||||
MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.deleteAllCleanTextData, this)
|
||||
], {trace:false});
|
||||
},
|
||||
@@ -1061,6 +1154,12 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
|
||||
Clipperz.Async.collectAll
|
||||
],
|
||||
'attachments': [
|
||||
MochiKit.Base.method(this, 'attachments'),
|
||||
MochiKit.Base.values,
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
|
||||
Clipperz.Async.collectAll
|
||||
],
|
||||
'super': [
|
||||
MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.hasAnyCleanTextData, this)
|
||||
]
|
||||
@@ -1131,10 +1230,12 @@ console.log("Record.hasPendingChanges RESULT", result);
|
||||
MochiKit.Base.method(aRecord, 'directLogins'), MochiKit.Base.values,
|
||||
//function (aValue) { console.log("-> SETUP WITH RECORD: DirectLogin Values", aValue); return aValue; },
|
||||
// TODO: possibly broken implementation of direct login cloning
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addDirectLogin')),
|
||||
MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'bindDirectLogin')),
|
||||
//function (aValue) { console.log("-> DirectLogin Values", aValue); return aValue; },
|
||||
// Clipperz.Async.collectAll,
|
||||
|
||||
// TODO: attachments
|
||||
|
||||
MochiKit.Base.bind(function () { return this; }, this)
|
||||
], {trace:false});
|
||||
},
|
||||
@@ -1230,7 +1331,8 @@ Clipperz.PM.DataModel.Record.defaultCardInfo = {
|
||||
'_isArchived': MochiKit.Base.methodcaller('isArchived'),
|
||||
'_isBrandNew': MochiKit.Base.methodcaller('isBrandNew'),
|
||||
'label': MochiKit.Base.methodcaller('label'),
|
||||
'favicon': MochiKit.Base.methodcaller('favicon')
|
||||
'favicon': MochiKit.Base.methodcaller('favicon'),
|
||||
'attachmentsCount': MochiKit.Base.methodcaller('attachmentsCount'),
|
||||
};
|
||||
Clipperz.PM.DataModel.Record.defaultSearchField = '_searchableContent';
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ refer to http://www.clipperz.com.
|
||||
|
||||
try { if (typeof(Clipperz.PM.DataModel.User) == 'undefined') { throw ""; }} catch (e) {
|
||||
throw "Clipperz.PM.DataModel.User.Header.RecordIndex depends on Clipperz.PM.DataModel.User!";
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof(Clipperz.PM.DataModel.User.Header) == 'undefined') { Clipperz.PM.DataModel.User.Header = {}; }
|
||||
|
||||
@@ -49,13 +49,25 @@ Clipperz.PM.DataModel.User.Header.RecordIndex = function(args) {
|
||||
}
|
||||
});
|
||||
|
||||
//console.log("RECORD INDEX args", args);
|
||||
this._attachmentsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
|
||||
'name': 'attachmentsData',
|
||||
'retrieveKeyFunction': args.retrieveKeyFunction,
|
||||
'remoteData': {
|
||||
'data': args.attachmentsData['data'],
|
||||
'version': args.encryptedDataVersion,
|
||||
}
|
||||
});
|
||||
|
||||
this._tagsData =
|
||||
this._lock = new MochiKit.Async.DeferredLock();
|
||||
this._transientState = null;
|
||||
|
||||
this._retrieveRecordDetailFunction = args.retrieveRecordDetailFunction || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||
|
||||
this._recordsIndex = args.recordsData['index'] || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||
this._directLoginsIndex = args.directLoginsData['index'] || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||
this._attachmentsIndex = args.attachmentsData['index'] || Clipperz.Base.exception.raise('MandatoryParameter');
|
||||
|
||||
this._records = null;
|
||||
|
||||
@@ -97,6 +109,16 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'attachmentsIndex': function () {
|
||||
return this._attachmentsIndex;
|
||||
},
|
||||
|
||||
'attachmentsData': function () {
|
||||
return this._attachmentsData;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'lock': function () {
|
||||
return this._lock;
|
||||
},
|
||||
@@ -164,6 +186,28 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'getAttachmentIndexData': function (anAttachmentReference) {
|
||||
// TODO:
|
||||
return this.attachmentsData().getValue(this.attachmentsIndex()[anAttachmentReference]);
|
||||
},
|
||||
|
||||
'setAttachmentIndexData': function (anAttachmentReference, aKey, aValue) {
|
||||
// TODO:
|
||||
return this.attachmentsData().setValue(this.attachmentsIndex()[anAttachmentReference] + '.' + aKey, aValue);
|
||||
},
|
||||
|
||||
'addAttachmentIndexData': function (anAttachmentReference) {
|
||||
// TODO:
|
||||
return this.attachmentsData().setValue(this.attachmentsIndex()[anAttachmentReference], {});
|
||||
},
|
||||
|
||||
'removeAttachmentIndexData': function (anAttachmentReference) {
|
||||
// TODO:
|
||||
return this.attachmentsData().removeValue(this.attachmentsIndex()[anAttachmentReference])
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'records': function () {
|
||||
var deferredResult;
|
||||
|
||||
@@ -184,6 +228,9 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
||||
],
|
||||
'directLogins': [
|
||||
MochiKit.Base.method(this.directLoginsData(), 'values')
|
||||
],
|
||||
'attachments': [
|
||||
MochiKit.Base.method(this.attachmentsData(), 'values')
|
||||
]
|
||||
})
|
||||
innerDeferredResult.addCallback(MochiKit.Base.bind(function (someData) {
|
||||
@@ -193,6 +240,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
||||
|
||||
recordsInvertedIndex = Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(this.recordsIndex());
|
||||
directLoginsInvertedIndex = Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(this.directLoginsIndex());
|
||||
attachmentsInvertedIndex = Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(this.attachmentsIndex());
|
||||
|
||||
this._records = {};
|
||||
|
||||
@@ -201,13 +249,15 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
||||
var reference;
|
||||
var updateDate;
|
||||
var accessDate;
|
||||
var attachmentsCount;
|
||||
|
||||
reference = recordsInvertedIndex[indexReference];
|
||||
|
||||
if (typeof(someData['recordsStats'][reference]) != 'undefined') {
|
||||
updateDate = someData['recordsStats'][reference]['updateDate'];
|
||||
accessDate = someData['recordsStats'][reference]['accessDate'];
|
||||
|
||||
// attachmentsCount = (someData['attachmentsCount'][reference]) ? someData['attachmentsCount'][reference] : 0;
|
||||
|
||||
record = new Clipperz.PM.DataModel.Record({
|
||||
'reference': reference,
|
||||
'retrieveKeyFunction': MochiKit.Base.method(this, 'getRecordKey'),
|
||||
@@ -221,8 +271,12 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
|
||||
'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
|
||||
'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
|
||||
'removeDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'removeDirectLoginIndexData'),
|
||||
|
||||
'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin')
|
||||
'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin'),
|
||||
|
||||
'retrieveAttachmentIndexDataFunction': MochiKit.Base.method(this, 'getAttachmentIndexData'),
|
||||
'setAttachmentIndexDataFunction': MochiKit.Base.method(this, 'setAttachmentIndexData'),
|
||||
'removeAttachmentIndexDataFunction': MochiKit.Base.method(this, 'removeAttachmentIndexData'),
|
||||
'createNewAttachmentFunction': MochiKit.Base.method(this, 'createNewAttachment'),
|
||||
});
|
||||
|
||||
this._records[reference] = record;
|
||||
@@ -248,6 +302,24 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stats associated
|
||||
}
|
||||
}
|
||||
|
||||
//console.log("RecordIndex.Records: attachments data:", someData['attachments']);
|
||||
for (indexReference in someData['attachments']) {
|
||||
var reference;
|
||||
var record;
|
||||
|
||||
reference = attachmentsInvertedIndex[indexReference];
|
||||
record = this._records[recordsInvertedIndex[someData['attachments'][indexReference]['record']]];
|
||||
|
||||
if (record != null) {
|
||||
new Clipperz.PM.DataModel.Attachment({
|
||||
'reference': reference,
|
||||
'record': record
|
||||
});
|
||||
} else {
|
||||
Clipperz.logWarning("WARNING: Attachment without a matching RECORD!!");
|
||||
}
|
||||
}
|
||||
|
||||
return this._records;
|
||||
}, this));
|
||||
innerDeferredResult.callback();
|
||||
@@ -295,8 +367,12 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stats associated
|
||||
'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
|
||||
'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
|
||||
'removeDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'removeDirectLoginIndexData'),
|
||||
'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin'),
|
||||
|
||||
'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin')
|
||||
'retrieveAttachmentIndexDataFunction': MochiKit.Base.method(this, 'getAttachmentIndexData'),
|
||||
'setAttachmentIndexDataFunction': MochiKit.Base.method(this, 'setAttachmentIndexData'),
|
||||
'removeAttachmentIndexDataFunction': MochiKit.Base.method(this, 'removeAttachmentIndexData'),
|
||||
'createNewAttachmentFunction': MochiKit.Base.method(this, 'createNewAttachment'),
|
||||
});
|
||||
|
||||
this.transientState().setValue('newRecordsReferences' + '.' + newRecord.reference(), newRecord);
|
||||
@@ -372,6 +448,40 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stats associated
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'removeAttachment': function (anAttachment) {
|
||||
// TODO:
|
||||
// this.directLoginsData().removeValue(this.directLoginsIndex()[aDirectLogin.reference()]);
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'createNewAttachment': function (aRecord) {
|
||||
// TODO:
|
||||
|
||||
// var newDirectLogin;
|
||||
var newAttachment;
|
||||
// var newDirectLoginIndexValue;
|
||||
var newAttachmentIndexValue;
|
||||
|
||||
// newDirectLogin = new Clipperz.PM.DataModel.DirectLogin({record:aRecord});
|
||||
newAttachment = new Clipperz.PM.DataModel.Attachment({'record':aRecord});
|
||||
// newDirectLoginIndexValue = MochiKit.Base.listMax(MochiKit.Base.map(function (aValue) { return aValue * 1; }, MochiKit.Base.values(this.directLoginsIndex()))) + 1;
|
||||
newAttachmentIndexValue = MochiKit.Base.listMax(MochiKit.Base.map(function (aValue) { return aValue * 1; }, MochiKit.Base.values(this.attachmentsIndex()))) + 1;
|
||||
|
||||
// this.transientState().setValue('newDirectLoginReferences' + '.' + newDirectLogin.reference(), newDirectLogin);
|
||||
this.transientState().setValue('newAttachmentReferences' + '.' + newAttachment.reference(), newAttachment);
|
||||
|
||||
// this.directLoginsIndex()[newDirectLogin.reference()] = newDirectLoginIndexValue;
|
||||
this.attachmentsIndex()[newAttachment.reference()] = newAttachmentIndexValue;
|
||||
// this.directLoginsData().setValue(this.directLoginsIndex()[newDirectLogin.reference()], {'record': this.recordsIndex()[aRecord.reference()]});
|
||||
this.attachmentsData().setValue(this.attachmentsIndex()[newAttachment.reference()], {'record': this.recordsIndex()[aRecord.reference()]});
|
||||
|
||||
// return newDirectLogin;
|
||||
return newAttachment;
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'deleteAllCleanTextData': function () {
|
||||
return Clipperz.Async.callbacks("User.Header.RecordIndex.deleteAllCleanTextData", [
|
||||
MochiKit.Base.method(this, 'recordsData'),
|
||||
@@ -396,6 +506,10 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stats associated
|
||||
MochiKit.Base.method(this, 'directLoginsData'),
|
||||
MochiKit.Base.methodcaller('hasAnyCleanTextData')
|
||||
],
|
||||
'attachmentsData': [
|
||||
MochiKit.Base.method(this, 'attachmentsData'),
|
||||
MochiKit.Base.methodcaller('hasAnyCleanTextData')
|
||||
],
|
||||
});
|
||||
|
||||
deferredResult.addCallback(Clipperz.Async.or);
|
||||
@@ -418,8 +532,13 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stats associated
|
||||
'directLoginsData': [
|
||||
MochiKit.Base.method(this, 'directLoginsData'),
|
||||
MochiKit.Base.methodcaller('hasPendingChanges')
|
||||
],
|
||||
'attachments': [
|
||||
MochiKit.Base.method(this, 'attachmentsData'),
|
||||
MochiKit.Base.methodcaller('hasPendingChanges')
|
||||
]
|
||||
});
|
||||
//deferredResult.addCallback(function (aValue) { console.log("HAS PENDING CHANGES", aValue); return aValue; });
|
||||
deferredResult.addCallback(Clipperz.Async.or);
|
||||
deferredResult.callback();
|
||||
|
||||
@@ -437,6 +556,9 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stats associated
|
||||
|
||||
MochiKit.Base.method(this, 'directLoginsData'),
|
||||
MochiKit.Base.methodcaller('commitTransientState'),
|
||||
|
||||
MochiKit.Base.method(this, 'attachmentsData'),
|
||||
MochiKit.Base.methodcaller('commitTransientState'),
|
||||
|
||||
MochiKit.Base.method(this, 'resetTransientState', true)
|
||||
], {trace:false});
|
||||
@@ -474,9 +596,21 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stats associated
|
||||
}
|
||||
}, this),
|
||||
|
||||
MochiKit.Base.bind(function () {
|
||||
// TODO:
|
||||
var attachmentReference;
|
||||
|
||||
for (attachmentReference in this.transientState().getValue('newAttachmentReferences')) {
|
||||
delete this.attachmentsIndex()[attachmentReference];
|
||||
}
|
||||
}, this),
|
||||
|
||||
MochiKit.Base.method(this, 'directLoginsData'),
|
||||
MochiKit.Base.methodcaller('revertChanges'),
|
||||
|
||||
MochiKit.Base.method(this, 'attachmentsData'),
|
||||
MochiKit.Base.methodcaller('revertChanges'),
|
||||
|
||||
MochiKit.Base.method(this, 'resetTransientState', false)
|
||||
], {trace:false});
|
||||
},
|
||||
@@ -528,6 +662,15 @@ Clipperz.log("SKIPPING record " + reference + " as there are no stats associated
|
||||
]
|
||||
});
|
||||
deferredResult.addCallback(Clipperz.Async.setItem, result, 'directLogins');
|
||||
|
||||
deferredResult.collectResults({
|
||||
'index': MochiKit.Base.partial(MochiKit.Async.succeed, this.attachmentsIndex()),
|
||||
'data': [
|
||||
MochiKit.Base.method(this.attachmentsData(), 'prepareRemoteDataWithKey', aKey),
|
||||
MochiKit.Base.itemgetter('data')
|
||||
]
|
||||
});
|
||||
deferredResult.addCallback(Clipperz.Async.setItem, result, 'attachments');
|
||||
|
||||
deferredResult.addCallback(MochiKit.Async.succeed, result);
|
||||
|
||||
|
||||
@@ -254,6 +254,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
'recordsData': {'data':null, 'index':{}},
|
||||
'recordsStats': null,
|
||||
'directLoginsData': {'data':null, 'index':{}},
|
||||
'attachmentsData': {'data':null, 'index':{}},
|
||||
'encryptedDataVersion': Clipperz.PM.Crypto.encryptingFunctions.currentVersion,
|
||||
'retrieveRecordDetailFunction': MochiKit.Base.method(this, 'getRecordDetail')
|
||||
}),
|
||||
@@ -465,13 +466,16 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
case '0.1':
|
||||
var headerData;
|
||||
|
||||
//console.log("Server data", someServerData);
|
||||
headerData = Clipperz.Base.evalJSON(someServerData['header']);
|
||||
|
||||
//console.log("headerData", headerData);
|
||||
recordsIndex = new Clipperz.PM.DataModel.User.Header.RecordIndex({
|
||||
'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
|
||||
'recordsData': headerData['records'],
|
||||
'recordsStats': someServerData['recordsStats'],
|
||||
'directLoginsData': headerData['directLogins'],
|
||||
'attachmentsData': headerData['attachments'] || {'data': null, 'index':{}},
|
||||
'encryptedDataVersion': someServerData['version'],
|
||||
'retrieveRecordDetailFunction': MochiKit.Base.method(this, 'getRecordDetail')
|
||||
});
|
||||
@@ -695,7 +699,7 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
|
||||
result = someFilteredResults[0];
|
||||
break;
|
||||
default:
|
||||
Clipperz.log("Warning: User.recordWithLabel('" + aLabel + "') is returning more than one result: " + someFilteredResults.length);
|
||||
//console.log("Warning: User.recordWithLabel('" + aLabel + "') is returning more than one result: " + someFilteredResults.length);
|
||||
result = someFilteredResults[0];
|
||||
break;
|
||||
}
|
||||
@@ -723,8 +727,13 @@ Clipperz.log("Warning: User.recordWithLabel('" + aLabel + "') is returning more
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
'getRecordDetail': function (aRecordReference) {
|
||||
return this.connection().message('getRecordDetail', {reference: aRecordReference});
|
||||
'getRecordDetail': function (aRecord) {
|
||||
// return this.connection().message('getRecordDetail', {reference: aRecordReference});
|
||||
|
||||
return Clipperz.Async.callbacks("User.getRecordDetail", [
|
||||
MochiKit.Base.method(this.connection(), 'message', 'getRecordDetail', {reference: aRecord.reference()}),
|
||||
function(someInfo) { aRecord.setAttachmentServerStatus(someInfo['attachmentStatus']); return someInfo;}, // Couldn't find a better way...
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -750,6 +759,7 @@ Clipperz.log("Warning: User.recordWithLabel('" + aLabel + "') is returning more
|
||||
'createNewRecordFromJSON': function(someJSON) {
|
||||
var deferredResult;
|
||||
|
||||
// TODO: how do we handle attachments?
|
||||
deferredResult = new Clipperz.Async.Deferred("User.createNewRecordFromJSON", {trace:false});
|
||||
deferredResult.collectResults({
|
||||
'recordIndex': MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
|
||||
@@ -770,6 +780,7 @@ Clipperz.log("Warning: User.recordWithLabel('" + aLabel + "') is returning more
|
||||
});
|
||||
|
||||
return Clipperz.Async.callbacks("User.createNewRecordFromJSON__inner", [
|
||||
// TODO: check if we should invoke the create new direct login methon on Record instead of calling it directly on the index
|
||||
MochiKit.Base.method(recordIndex, 'createNewDirectLogin', record),
|
||||
MochiKit.Base.methodcaller('setLabel', aDirectLogin['label']),
|
||||
MochiKit.Base.methodcaller('setBookmarkletConfiguration', configuration),
|
||||
@@ -937,6 +948,22 @@ Clipperz.log("Warning: User.recordWithLabel('" + aLabel + "') is returning more
|
||||
], {trace:false});
|
||||
},
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
'addNewAttachment': function(anAttachment) {
|
||||
console.log("Adding attachment", anAttachment);
|
||||
},
|
||||
*/
|
||||
'uploadAttachment': function(aRecordReference, anAttachmentReference, someData) {
|
||||
// TODO: pass a callback to handle onProgress events (and modify Connection accordingly)
|
||||
this.connection().message('uploadAttachment', {
|
||||
'recordReference': aRecordReference,
|
||||
'attachmentReference': anAttachmentReference,
|
||||
'data': someData
|
||||
});
|
||||
},
|
||||
|
||||
//=========================================================================
|
||||
|
||||
'hasPendingChanges': function () {
|
||||
@@ -1035,6 +1062,7 @@ Clipperz.log("Warning: User.recordWithLabel('" + aLabel + "') is returning more
|
||||
header = {};
|
||||
header['records'] = someHeaderPackedData['recordIndex']['records'];
|
||||
header['directLogins'] = someHeaderPackedData['recordIndex']['directLogins'];
|
||||
header['attachments'] = someHeaderPackedData['recordIndex']['attachments'];
|
||||
header['preferences'] = {'data': someHeaderPackedData['preferences']['data']};
|
||||
header['oneTimePasswords'] = {'data': someHeaderPackedData['oneTimePasswords']['data']};
|
||||
header['version'] = '0.1';
|
||||
|
||||
Reference in New Issue
Block a user