Make mail news handle inline background url styles which is how editor now sets background urls instead of using the obsolete background attribute on the body:

Bug #116867 --> convert background images from file urls to inline cid urls and attach the image as an inline part.This allows thunderbird and mozilla mail to support background images again.

Bug #170504 --> Compose from template/draft containing "Inline Styles" and a background image loses the background image drops the
inline style.

r=bienvenu
sr=sspitzer
a=sspitzer
This commit is contained in:
scott%scott-macgregor.org 2003-08-18 05:14:41 +00:00
parent 700930043a
commit f8701a0b9f
6 changed files with 142 additions and 37 deletions

View File

@ -60,6 +60,15 @@
#include "nsMsgUtils.h"
#include "nsMsgSimulateError.h"
#include "nsIDOMDocumentView.h"
#include "nsIDOMCSSStyleDeclaration.h"
#include "nsIDOMViewCSS.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMCSSPrimitiveValue.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
#include "nsIMsgCompUtils.h"
#include "nsIMsgMdnGenerator.h"
@ -2132,3 +2141,38 @@ PRBool UseFormatFlowed(const char *charset)
}
nsresult GetBackgroundImageUrl(nsIDOMElement * aElement, const nsAString& aPropertyName, nsAString& aUrl)
{
NS_ENSURE_ARG(aElement);
nsCOMPtr<nsIDOMCSSPrimitiveValue> primCSSValue;
nsCOMPtr<nsIDOMDocument> domDocument;
aElement->GetOwnerDocument(getter_AddRefs(domDocument));
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
if (document)
{
nsCOMPtr<nsIScriptGlobalObject> global;
document->GetScriptGlobalObject(getter_AddRefs(global));
nsCOMPtr<nsIDOMViewCSS> viewCSS(do_QueryInterface(global));
if (viewCSS)
{
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
nsAutoString empty;
viewCSS->GetComputedStyle(aElement, empty, getter_AddRefs(cssDecl));
if (cssDecl)
{
nsAutoString value;
nsCOMPtr<nsIDOMCSSValue> cssValue;
cssDecl->GetPropertyCSSValue(aPropertyName, getter_AddRefs(cssValue));
primCSSValue = do_QueryInterface(cssValue);
if (primCSSValue)
primCSSValue->GetStringValue(aUrl);
}
}
}
return NS_OK;
}

View File

@ -46,6 +46,8 @@
#include "nsIMsgCompUtils.h"
#include "nsComObsolete.h"
class nsIDOMElement;
class nsIPrompt;
#define ANY_SERVER "anyfolder://"
@ -170,6 +172,10 @@ nsresult ConvertBufToPlainText(nsString &aConBuf, PRBool formatflowed = PR_FALSE
// Check if we should use format=flowed
PRBool UseFormatFlowed(const char *charset);
// dom helper method shared by nsMsgSend and nsMsgCompose
nsresult GetBackgroundImageUrl(nsIDOMElement * aElement, const nsAString& aPropertyName, nsAString& aBackgroundUrl);
NS_END_EXTERN_C

View File

@ -4140,9 +4140,9 @@ nsresult nsMsgCompose::TagConvertible(nsIDOMNode *node, PRInt32 *_retval)
{
PRBool hasAttribute;
nsAutoString color;
if (NS_SUCCEEDED(domElement->HasAttribute(NS_LITERAL_STRING("background"), &hasAttribute))
&& hasAttribute) // There is a background image
*_retval = nsIMsgCompConvertible::No;
nsAutoString backgroundUrl;
if (NS_SUCCEEDED(GetBackgroundImageUrl(domElement, NS_LITERAL_STRING("background-image"), backgroundUrl)) && !backgroundUrl.IsEmpty())
*_retval = nsIMsgCompConvertible::No; // There is a background image
else if (NS_SUCCEEDED(domElement->HasAttribute(NS_LITERAL_STRING("text"), &hasAttribute)) &&
hasAttribute &&
NS_SUCCEEDED(domElement->GetAttribute(NS_LITERAL_STRING("text"), color)) &&
@ -4358,7 +4358,7 @@ nsresult nsMsgCompose::SetBodyAttribute(nsIEditor* editor, nsIDOMElement* elemen
name.CompareWithConversion("link", PR_TRUE) == 0 ||
name.CompareWithConversion("vlink", PR_TRUE) == 0 ||
name.CompareWithConversion("alink", PR_TRUE) == 0 ||
name.CompareWithConversion("background", PR_TRUE) == 0)
name.CompareWithConversion("style", PR_TRUE) == 0)
{
/* cleanup the attribute value */
value.Trim(" \t\n\r");
@ -4423,6 +4423,8 @@ nsresult nsMsgCompose::SetBodyAttributes(nsString& attributes)
{
/* we found the end of an attribute name */
attributeName.Assign(start, data - start);
// strip any leading or trailing white space from the attribute name.
attributeName.CompressWhitespace();
start = data + 1;
if (start < end && *start == '\"')
{
@ -4438,25 +4440,18 @@ nsresult nsMsgCompose::SetBodyAttributes(nsString& attributes)
}
else
{
if (delimiter == '\"')
{
/* we found the closing double-quote of an attribute value,
let's find now the real attribute delimiter */
delimiter = ' ';
}
else
{
/* we found the end of an attribute value */
attributeValue.Assign(start, data - start);
rv = SetBodyAttribute(m_editor, rootElement, attributeName, attributeValue);
NS_ENSURE_SUCCESS(rv, rv);
/* we found the end of an attribute value */
if (delimiter =='\"')
data ++; // include the training quote for attribute values which are quoted
attributeValue.Assign(start, data - start);
rv = SetBodyAttribute(m_editor, rootElement, attributeName, attributeValue);
NS_ENSURE_SUCCESS(rv, rv);
/* restart the search for the next pair of attribute */
start = data + 1;
attributeName.Truncate();
attributeValue.Truncate();
delimiter = '=';
}
/* restart the search for the next pair of attribute */
start = data + 1;
attributeName.Truncate();
attributeValue.Truncate();
delimiter = '=';
}
}

View File

@ -1436,7 +1436,33 @@ mime_encoder_output_fn(const char *buf, PRInt32 size, void *closure)
nsMsgComposeAndSend *state = (nsMsgComposeAndSend *) closure;
return mime_write_message_body (state, (char *) buf, size);
}
nsresult nsMsgComposeAndSend::ChangeBackgroundImageUrl(nsIDOMElement * aBodyElement, const nsAString& aCurrentUrl, const nsAString& aNewUrl)
{
nsAutoString styleValue;
aBodyElement->GetAttribute(NS_LITERAL_STRING("style"), styleValue);
PRInt32 startOfUrl = styleValue.Find(PromiseFlatString(aCurrentUrl).get());
if (startOfUrl != kNotFound)
{
// cut out the current url
nsAutoString before;
styleValue.Left(before, startOfUrl);
nsAutoString after;
styleValue.Mid(after, startOfUrl + aCurrentUrl.Length(), styleValue.Length() - (startOfUrl + aCurrentUrl.Length()) );
before.Append(aNewUrl);
before.Append(after);
styleValue = before;
}
// styleValue.ReplaceSubstring(aCurrentUrl, aNewUrl);
aBodyElement->SetAttribute(NS_LITERAL_STRING("style"), styleValue);
return NS_OK;
}
nsresult
nsMsgComposeAndSend::GetEmbeddedObjectInfo(nsIDOMNode *node, nsMsgAttachmentData *attachment, PRBool *acceptObject)
{
@ -1472,16 +1498,19 @@ nsMsgComposeAndSend::GetEmbeddedObjectInfo(nsIDOMNode *node, nsMsgAttachmentData
// First, try to see if the body as a background image
if (body)
{
nsAutoString tUrl;
if (NS_SUCCEEDED(body->GetBackground(tUrl)))
// get the url from computed style
nsAutoString value;
rv = GetBackgroundImageUrl(domElement, NS_LITERAL_STRING("background-image"), value);
if (!value.IsEmpty())
{
nsCAutoString turlC;
turlC.AssignWithConversion(tUrl);
turlC.AssignWithConversion(value);
if (NS_SUCCEEDED(nsMsgNewURL(&attachment->url, turlC.get())))
NS_IF_ADDREF(attachment->url);
else
return NS_OK;
}
}
}
else if (image) // Is this an image?
{
@ -1925,6 +1954,7 @@ typedef struct
char *url;
} domSaveStruct;
nsresult
nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aNewsCount)
{
@ -2100,8 +2130,10 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
}
else if (body)
{
body->GetBackground(domURL);
body->SetBackground(newSpec);
// get the url from computed style
GetBackgroundImageUrl(body, NS_LITERAL_STRING("background-image"), domURL);
if (!domURL.IsEmpty())
ChangeBackgroundImageUrl(body, domURL, newSpec);
}
if (!domURL.IsEmpty())
@ -2136,7 +2168,13 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
else if (image)
image->SetSrc(NS_ConvertASCIItoUCS2(domSaveArray[i].url));
else if (body)
body->SetBackground(NS_ConvertASCIItoUCS2(domSaveArray[i].url));
{
// get the url from computed style
nsString domURL;
GetBackgroundImageUrl(body, NS_LITERAL_STRING("background-image"), domURL);
if (!domURL.IsEmpty())
ChangeBackgroundImageUrl(body, domURL, NS_ConvertASCIItoUCS2(domSaveArray[i].url));
}
nsMemory::Free(domSaveArray[i].url);
}

View File

@ -159,7 +159,7 @@
#include "nsWeakReference.h"
#include "nsIDOMWindowInternal.h"
#include "nsIMsgComposeSecure.h"
#include "nsAString.h"
//
// Some necessary defines...
//
@ -409,6 +409,8 @@ private:
// generates a message id for our message, if necessary
void GenerateMessageId( );
nsresult ChangeBackgroundImageUrl(nsIDOMElement * aBodyElement, const nsAString& aCurrentUrl, const nsAString& aNewUrl);
// add default custom headers to the message
nsresult AddDefaultCustomHeaders();

View File

@ -844,17 +844,37 @@ flush_tag(MimeMultipartRelated* relobj)
while(buf < ptr)
{
/* ### mwelch For each word in the value string, see if
the word is a cid: URL. If so, attempt to
substitute the appropriate mailbox part URL in
its place. */
the word is a cid: URL. If so, attempt to substitute the appropriate mailbox part URL in its place.
mscott: but that's not good enough. A given word may have a cid url inside of it such as
with style rules for background images: url(cid:....).
*/
ptr2=buf; /* walk from the left end rightward */
while((ptr2<ptr) && (!nsCRT::IsAsciiSpace(*ptr2)))
ptr2++;
// make sure we are not dealing with a case of url(cid:....)..if so, account for the url( and the closing ); at the
// end of the style rule
if ( (ptr2 - buf) > 8 && ( nsCRT::ToLower(buf[0]) == 'u' && nsCRT::ToLower(buf[1]) == 'r' &&
nsCRT::ToLower(buf[2]) == 'l' && buf[3] == '(' &&
nsCRT::ToLower(buf[4]) =='c' && nsCRT::ToLower(buf[5]) =='i' &&
nsCRT::ToLower(buf[6]) =='d' && buf[7]==':'))
{
// write out "url(:
status = real_write(relobj, buf, 4);
buf += 4;
// adjust the end ptr2 to go back to the close paren
if ( *(ptr2 - 1) == ';' && *(ptr2 - 2) == ')')
ptr2 -= 2;
}
/* Compare the beginning of the word with "cid:". Yuck. */
if (((ptr2 - buf) > 4) &&
((buf[0]=='c' || buf[0]=='C') &&
(buf[1]=='i' || buf[1]=='I') &&
(buf[2]=='d' || buf[2]=='D') &&
((nsCRT::ToLower(buf[0]) =='c') &&
(nsCRT::ToLower(buf[1]) =='i') &&
(nsCRT::ToLower(buf[2]) =='d') &&
buf[3]==':'))
{
// Make sure it's lowercase, otherwise it won't be found in the hash table