Bug #216753 --> Message compose should not automatically convert HTML attributes to CSS styles.

Fix this by setting a flag in editor to not use CSS styles for the background image.

Then back out my fixes in mailnews to work around the inline style editor was giving us. 

With this change, mail compose now handles background images again and they are preserved when you save as draft 
or save as template.

r=neil
sr=bienvenu

a=glazman for the editor change

a=asa for 1.5 final
This commit is contained in:
scott%scott-macgregor.org 2003-09-05 17:49:36 +00:00
parent 91cfff066d
commit c26ce97cd5
7 changed files with 31 additions and 136 deletions

View File

@ -445,7 +445,7 @@ NS_IMETHODIMP
nsHTMLEditor::SetFlags(PRUint32 aFlags) nsHTMLEditor::SetFlags(PRUint32 aFlags)
{ {
if (!mRules) { return NS_ERROR_NULL_POINTER; } if (!mRules) { return NS_ERROR_NULL_POINTER; }
mCSSAware = ((aFlags & nsIPlaintextEditor::eEditorNoCSSMask) == 0); mCSSAware = ((aFlags & (eEditorNoCSSMask | eEditorMailMask)) == 0);
return mRules->SetFlags(aFlags); return mRules->SetFlags(aFlags);
} }
@ -3992,10 +3992,8 @@ nsHTMLEditor::GetEmbeddedObjects(nsISupportsArray** aNodeList)
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(node); nsCOMPtr<nsIDOMElement> element = do_QueryInterface(node);
if (element) if (element)
{ {
nsAutoString bgImageStr; PRBool hasBackground = PR_FALSE;
if (NS_SUCCEEDED(element->HasAttribute(NS_LITERAL_STRING("background"), &hasBackground)) && hasBackground)
mHTMLCSSUtils->GetComputedProperty(element, nsEditProperty::cssBackgroundImage, bgImageStr);
if (!bgImageStr.Equals(NS_LITERAL_STRING("none")))
(*aNodeList)->AppendElement(node); (*aNodeList)->AppendElement(node);
} }
} }

View File

@ -60,15 +60,6 @@
#include "nsMsgUtils.h" #include "nsMsgUtils.h"
#include "nsMsgSimulateError.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 "nsIMsgCompUtils.h"
#include "nsIMsgMdnGenerator.h" #include "nsIMsgMdnGenerator.h"
@ -2141,38 +2132,3 @@ 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,8 +46,6 @@
#include "nsIMsgCompUtils.h" #include "nsIMsgCompUtils.h"
#include "nsComObsolete.h" #include "nsComObsolete.h"
class nsIDOMElement;
class nsIPrompt; class nsIPrompt;
#define ANY_SERVER "anyfolder://" #define ANY_SERVER "anyfolder://"
@ -172,10 +170,6 @@ nsresult ConvertBufToPlainText(nsString &aConBuf, PRBool formatflowed = PR_FALSE
// Check if we should use format=flowed // Check if we should use format=flowed
PRBool UseFormatFlowed(const char *charset); 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 NS_END_EXTERN_C

View File

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

View File

@ -1437,32 +1437,6 @@ mime_encoder_output_fn(const char *buf, PRInt32 size, void *closure)
return mime_write_message_body (state, (char *) buf, size); 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 nsresult
nsMsgComposeAndSend::GetEmbeddedObjectInfo(nsIDOMNode *node, nsMsgAttachmentData *attachment, PRBool *acceptObject) nsMsgComposeAndSend::GetEmbeddedObjectInfo(nsIDOMNode *node, nsMsgAttachmentData *attachment, PRBool *acceptObject)
{ {
@ -1498,14 +1472,11 @@ nsMsgComposeAndSend::GetEmbeddedObjectInfo(nsIDOMNode *node, nsMsgAttachmentData
// First, try to see if the body as a background image // First, try to see if the body as a background image
if (body) if (body)
{ {
// get the url from computed style nsAutoString tUrl;
nsAutoString value; if (NS_SUCCEEDED(body->GetBackground(tUrl)))
rv = GetBackgroundImageUrl(domElement, NS_LITERAL_STRING("background-image"), value);
if (!value.IsEmpty())
{ {
nsCAutoString turlC; nsCAutoString turlC;
turlC.AssignWithConversion(value); turlC.AssignWithConversion(tUrl);
if (NS_SUCCEEDED(nsMsgNewURL(&attachment->url, turlC.get()))) if (NS_SUCCEEDED(nsMsgNewURL(&attachment->url, turlC.get())))
NS_IF_ADDREF(attachment->url); NS_IF_ADDREF(attachment->url);
else else
@ -1954,7 +1925,6 @@ typedef struct
char *url; char *url;
} domSaveStruct; } domSaveStruct;
nsresult nsresult
nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aNewsCount) nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aNewsCount)
{ {
@ -2130,10 +2100,8 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
} }
else if (body) else if (body)
{ {
// get the url from computed style body->GetBackground(domURL);
GetBackgroundImageUrl(body, NS_LITERAL_STRING("background-image"), domURL); body->SetBackground(newSpec);
if (!domURL.IsEmpty())
ChangeBackgroundImageUrl(body, domURL, newSpec);
} }
if (!domURL.IsEmpty()) if (!domURL.IsEmpty())
@ -2168,13 +2136,7 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
else if (image) else if (image)
image->SetSrc(NS_ConvertASCIItoUCS2(domSaveArray[i].url)); image->SetSrc(NS_ConvertASCIItoUCS2(domSaveArray[i].url));
else if (body) 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); nsMemory::Free(domSaveArray[i].url);
} }

View File

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

View File

@ -844,37 +844,17 @@ flush_tag(MimeMultipartRelated* relobj)
while(buf < ptr) while(buf < ptr)
{ {
/* ### mwelch For each word in the value string, see if /* ### 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
mscott: but that's not good enough. A given word may have a cid url inside of it such as its place. */
with style rules for background images: url(cid:....).
*/
ptr2=buf; /* walk from the left end rightward */ ptr2=buf; /* walk from the left end rightward */
while((ptr2<ptr) && (!nsCRT::IsAsciiSpace(*ptr2))) while((ptr2<ptr) && (!nsCRT::IsAsciiSpace(*ptr2)))
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. */ /* Compare the beginning of the word with "cid:". Yuck. */
if (((ptr2 - buf) > 4) && if (((ptr2 - buf) > 4) &&
((nsCRT::ToLower(buf[0]) =='c') && ((buf[0]=='c' || buf[0]=='C') &&
(nsCRT::ToLower(buf[1]) =='i') && (buf[1]=='i' || buf[1]=='I') &&
(nsCRT::ToLower(buf[2]) =='d') && (buf[2]=='d' || buf[2]=='D') &&
buf[3]==':')) buf[3]==':'))
{ {
// Make sure it's lowercase, otherwise it won't be found in the hash table // Make sure it's lowercase, otherwise it won't be found in the hash table