fix editing of drafts with inline images losing track of part numbers, r=neil, bug 692875

This commit is contained in:
David Bienvenu 2011-11-04 07:45:09 -07:00
Родитель 6d9f4536ab
Коммит 6fcda69e4e
8 изменённых файлов: 80 добавлений и 21 удалений

Просмотреть файл

@ -251,7 +251,7 @@ public:
[ptr] native nsMsgAttachmentHandler(nsMsgAttachmentHandler);
[ptr] native nsMsgAttachedFile(nsMsgAttachedFile);
[scriptable, uuid(fd21915b-0b12-4ab1-b3c9-feec98fcb6d1)]
[scriptable, uuid(22cfe1cb-4e9a-451f-82e5-0b75d2b65a95)]
interface nsIMsgSend : nsISupports
{
//
@ -400,6 +400,18 @@ interface nsIMsgSend : nsISupports
void getMessageId(out ACString messageID);
/// When saving as draft, the folder uri we saved to.
readonly attribute ACString folderUri;
/**
* After a draft is saved, use this to get the mime part number for the dom
* node in the editor embedded object list with the passed in index.
*
* @param aDomIndex - index in the editor dom embedded object list of
* the part we're interested in. These are generally images.
*
* @return the mime part number for that object.
*/
ACString getPartForDomIndex(in long aDomIndex);
attribute nsMsgKey messageKey;
nsIPrompt getDefaultPrompt();

Просмотреть файл

@ -153,7 +153,7 @@ nsMsgAttachmentHandler::nsMsgAttachmentHandler() :
mMHTMLPart(PR_FALSE),
mPartUserOmissionOverride(PR_FALSE),
mMainBody(PR_FALSE),
mNodeIndex(-1),
// For analyzing the attachment file...
m_size(0),
m_unprintable_count(0),

Просмотреть файл

@ -92,8 +92,6 @@ class nsMsgAttachmentHandler
public:
nsMsgAttachmentHandler();
~nsMsgAttachmentHandler();
//
public:
nsresult SnarfAttachment(nsMsgCompFields *compFields);
int PickEncoding (const char *charset, nsIMsgSend* mime_delivery_state);
@ -178,7 +176,9 @@ public:
bool mMHTMLPart; // This is true if its an MHTML part, otherwise, false
bool mPartUserOmissionOverride; // This is true if the user send send the email without this part
bool mMainBody; // True if this is a main body.
PRInt32 mNodeIndex; //If this is an embedded image, this is the index of the
// corresponding domNode in the editor's
//GetEmbeddedObjects. Otherwise, it will be -1.
//
// Vars for analyzing file data...
//

Просмотреть файл

@ -394,6 +394,7 @@ nsresult nsMsgCompose::ResetUrisForEmbeddedObjects()
mMsgSend->GetFolderUri(folderUri);
nsCOMPtr<nsIMsgFolder> folder;
rv = GetExistingFolder(folderUri, getter_AddRefs(folder));
NS_ENSURE_SUCCESS(rv, rv);
folder->GetBaseMessageURI(baseMsgUri);
NS_ENSURE_SUCCESS(rv, rv);
@ -407,6 +408,8 @@ nsresult nsMsgCompose::ResetUrisForEmbeddedObjects()
nsCOMPtr<nsIDOMHTMLImageElement> image = do_QueryInterface(domElement);
if (!image)
continue;
nsCString partNum;
mMsgSend->GetPartForDomIndex(i, partNum);
// do we care about anything besides images?
nsAutoString objURL;
image->GetSrc(objURL);
@ -426,6 +429,15 @@ nsresult nsMsgCompose::ResetUrisForEmbeddedObjects()
newURI.Append('#');
newURI.AppendInt(newMsgKey);
nsString restOfUrl(Substring(objURL, restOfUrlIndex, objURL.Length() - restOfUrlIndex));
PRInt32 partIndex = restOfUrl.Find("part=");
if (partIndex != kNotFound)
{
partIndex += 5;
PRInt32 endPart = restOfUrl.FindChar('&', partIndex);
PRInt32 existingPartLen = (endPart == kNotFound) ? -1 : endPart - partIndex;
restOfUrl.Replace(partIndex, existingPartLen, NS_ConvertASCIItoUTF16(partNum));
}
nsCOMPtr<nsIMsgMessageService> msgService;
rv = GetMessageServiceFromURI(newURI, getter_AddRefs(msgService));
if (NS_FAILED(rv))

Просмотреть файл

@ -753,7 +753,6 @@ nsMsgComposeAndSend::GatherMimeAttachments()
mainbody = m_related_part->GetChild(0);
mainbody->SetMainPart(PR_TRUE);
}
if (m_plaintext)
{
//
@ -1019,7 +1018,22 @@ nsMsgComposeAndSend::GatherMimeAttachments()
// to a lot of prompts about not being able to fetch this part!
//
if (m_attachments[i].mPartUserOmissionOverride)
{
// look for earlier part with the same content id. If we find it,
// need to remember the mapping between our node index and the
// part num of the earlier part.
PRInt32 nodeIndex = m_attachments[i].mNodeIndex;
if (nodeIndex != -1)
{
for (PRUint32 j = 0; j < i; j++)
{
if (m_attachments[j].mNodeIndex != -1 &&
m_attachments[j].m_contentId.Equals(m_attachments[i].m_contentId))
m_partNumbers[nodeIndex] = m_partNumbers[m_attachments[j].mNodeIndex];
}
}
continue;
}
// Now, we need to add this part to the m_related_part member so the
// message will be generated correctly.
@ -1155,6 +1169,10 @@ nsMsgComposeAndSend::PreProcessPart(nsMsgAttachmentHandler *ma,
if (!part)
return 0;
status = toppart->AddChild(part);
// Remember the part number if it has a node index.
if (ma->mNodeIndex != -1)
m_partNumbers[ma->mNodeIndex] = part->m_partNum;
if (NS_FAILED(status))
return 0;
status = part->SetType(ma->m_type.get());
@ -1346,7 +1364,6 @@ nsMsgComposeAndSend::GetEmbeddedObjectInfo(nsIDOMNode *node, nsMsgAttachmentData
forceToBeAttached = PR_TRUE;
}
}
// Now, we know the types of objects this node can be, so we will do
// our query interface here and see what we come up with
nsCOMPtr<nsIDOMHTMLBodyElement> body = (do_QueryInterface(node));
@ -1544,6 +1561,8 @@ nsMsgComposeAndSend::GetMultipartRelatedCount(bool forceToBeCalculated /*=false*
{
if (count > 0)
{
// preallocate space for part numbers
m_partNumbers.SetLength(count);
// Let parse the list to count the number of valid objects. BTW, we can remove the others from the list
nsMsgAttachmentData attachment;
@ -1561,13 +1580,10 @@ nsMsgComposeAndSend::GetMultipartRelatedCount(bool forceToBeCalculated /*=false*
mEmbeddedObjectList->QueryElementAt(i, NS_GET_IID(nsIDOMNode), getter_AddRefs(node));
if (!node)
continue;
bool acceptObject = false;
rv = GetEmbeddedObjectInfo(node, &attachment, &acceptObject);
if (NS_SUCCEEDED(rv) && acceptObject)
count ++;
else
mEmbeddedObjectList->DeleteElementAt(i);
}
}
mMultipartRelatedAttachmentCount = (PRInt32)count;
@ -1871,20 +1887,14 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
}
nsCOMPtr<nsIDOMNode> node;
for (i = mPreloadedAttachmentCount; i < (mPreloadedAttachmentCount + multipartCount); i++)
for (i = mPreloadedAttachmentCount; i < (mPreloadedAttachmentCount + multipartCount);)
{
// MUST set this to get placed in the correct part of the message
m_attachments[i].mMHTMLPart = PR_TRUE;
locCount++;
m_attachments[i].mDeleteFile = PR_TRUE;
m_attachments[i].m_done = PR_FALSE;
m_attachments[i].SetMimeDeliveryState(this);
// Ok, now we need to get the element in the array and do the magic
// to process this element.
//
locCount++;
mEmbeddedObjectList->QueryElementAt(locCount, NS_GET_IID(nsIDOMNode), getter_AddRefs(node));
if (!node)
return NS_ERROR_MIME_MPART_ATTACHMENT_ERROR;
@ -1892,10 +1902,17 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
bool acceptObject = false;
rv = GetEmbeddedObjectInfo(node, &attachment, &acceptObject);
NS_ENSURE_SUCCESS(rv, NS_ERROR_MIME_MPART_ATTACHMENT_ERROR);
if (!acceptObject)
continue;
// MUST set this to get placed in the correct part of the message
m_attachments[i].mMHTMLPart = PR_TRUE;
m_attachments[i].mDeleteFile = PR_TRUE;
m_attachments[i].m_done = PR_FALSE;
m_attachments[i].SetMimeDeliveryState(this);
m_attachments[i].mNodeIndex = locCount;
j++;
domSaveArray[j].node = node;
@ -1957,6 +1974,8 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
(*aNewsCount)++;
}
}
else
m_attachments[i].m_contentId = m_attachments[duplicateOf].m_contentId;
//
// Ok, while we are here, we should whack the DOM with the generated
@ -2000,6 +2019,7 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
if (!domURL.IsEmpty())
domSaveArray[j].url = ToNewCString(NS_LossyConvertUTF16toASCII(domURL));
}
i++;
}
rv = GetBodyFromEditor();
@ -2050,7 +2070,6 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
m_related_part->SetMimeDeliveryState(this);
m_related_part->SetType(MULTIPART_RELATED);
// We are now going to use the m_related_part as a way to store the
// MHTML message for this email.
//
@ -4015,6 +4034,13 @@ nsMsgComposeAndSend::GetFolderUri(nsACString &aFolderUri)
return NS_OK;
}
NS_IMETHODIMP
nsMsgComposeAndSend::GetPartForDomIndex(PRInt32 aDomIndex, nsACString &aPartNum)
{
aPartNum = m_partNumbers.SafeElementAt(aDomIndex, EmptyCString());
return NS_OK;
}
NS_IMETHODIMP
nsMsgComposeAndSend::GetMessageId(nsACString& aMessageId)
{

Просмотреть файл

@ -327,6 +327,9 @@ public:
// Variable for storing the draft name;
nsCString m_folderName;
// mapping between editor dom node indexes and saved mime part numbers.
nsTArray<nsCString> m_partNumbers;
//
// These variables are needed for message Copy operations!
//

Просмотреть файл

@ -65,7 +65,8 @@ nsMsgSendPart::nsMsgSendPart(nsIMsgSend* state, const char *part_charset)
m_charset_name[sizeof(m_charset_name)-1] = '\0';
m_children = nsnull;
m_numchildren = 0;
// if we're not added as a child, the default part number will be "1".
m_partNum = "1";
SetMimeDeliveryState(state);
m_parent = nsnull;
@ -199,6 +200,10 @@ int nsMsgSendPart::AddChild(nsMsgSendPart* child)
m_children = tmp;
m_children[m_numchildren - 1] = child;
child->m_parent = this;
nsCString partNum(m_partNum);
partNum.Append(".");
partNum.AppendInt(m_numchildren);
child->m_partNum = partNum;
return 0;
}

Просмотреть файл

@ -95,6 +95,7 @@ public:
{
return m_mainpart;
}
nsCString m_partNum;
protected:
int CopyString(char** dest, const char* src);
int PushBody(const char* buffer, PRInt32 length);