fix editing of drafts with inline images losing track of part numbers, r=neil, bug 692875
This commit is contained in:
Родитель
6d9f4536ab
Коммит
6fcda69e4e
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче