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

View File

@ -60,15 +60,6 @@
#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"
@ -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 "nsComObsolete.h"
class nsIDOMElement;
class nsIPrompt;
#define ANY_SERVER "anyfolder://"
@ -172,10 +170,6 @@ 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;
nsAutoString backgroundUrl;
if (NS_SUCCEEDED(GetBackgroundImageUrl(domElement, NS_LITERAL_STRING("background-image"), backgroundUrl)) && !backgroundUrl.IsEmpty())
*_retval = nsIMsgCompConvertible::No; // There is a background image
if (NS_SUCCEEDED(domElement->HasAttribute(NS_LITERAL_STRING("background"), &hasAttribute))
&& hasAttribute) // There is a background image
*_retval = nsIMsgCompConvertible::No;
else if (NS_SUCCEEDED(domElement->HasAttribute(NS_LITERAL_STRING("text"), &hasAttribute)) &&
hasAttribute &&
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("vlink", 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 */
value.Trim(" \t\n\r");
@ -4423,8 +4425,6 @@ 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 == '\"')
{
@ -4440,9 +4440,15 @@ nsresult nsMsgCompose::SetBodyAttributes(nsString& attributes)
}
else
{
/* we found the end of an attribute value */
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);
rv = SetBodyAttribute(m_editor, rootElement, attributeName, attributeValue);
NS_ENSURE_SUCCESS(rv, rv);
@ -4454,6 +4460,7 @@ nsresult nsMsgCompose::SetBodyAttributes(nsString& attributes)
delimiter = '=';
}
}
}
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);
}
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)
{
@ -1498,14 +1472,11 @@ nsMsgComposeAndSend::GetEmbeddedObjectInfo(nsIDOMNode *node, nsMsgAttachmentData
// First, try to see if the body as a background image
if (body)
{
// get the url from computed style
nsAutoString value;
rv = GetBackgroundImageUrl(domElement, NS_LITERAL_STRING("background-image"), value);
if (!value.IsEmpty())
nsAutoString tUrl;
if (NS_SUCCEEDED(body->GetBackground(tUrl)))
{
nsCAutoString turlC;
turlC.AssignWithConversion(value);
turlC.AssignWithConversion(tUrl);
if (NS_SUCCEEDED(nsMsgNewURL(&attachment->url, turlC.get())))
NS_IF_ADDREF(attachment->url);
else
@ -1954,7 +1925,6 @@ typedef struct
char *url;
} domSaveStruct;
nsresult
nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aNewsCount)
{
@ -2130,10 +2100,8 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
}
else if (body)
{
// get the url from computed style
GetBackgroundImageUrl(body, NS_LITERAL_STRING("background-image"), domURL);
if (!domURL.IsEmpty())
ChangeBackgroundImageUrl(body, domURL, newSpec);
body->GetBackground(domURL);
body->SetBackground(newSpec);
}
if (!domURL.IsEmpty())
@ -2168,13 +2136,7 @@ nsMsgComposeAndSend::ProcessMultipartRelated(PRInt32 *aMailboxCount, PRInt32 *aN
else if (image)
image->SetSrc(NS_ConvertASCIItoUCS2(domSaveArray[i].url));
else if (body)
{
// 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));
}
body->SetBackground(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,8 +409,6 @@ 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,37 +844,17 @@ 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.
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:....).
*/
the word is a cid: URL. If so, attempt to
substitute the appropriate mailbox part URL in
its place. */
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) &&
((nsCRT::ToLower(buf[0]) =='c') &&
(nsCRT::ToLower(buf[1]) =='i') &&
(nsCRT::ToLower(buf[2]) =='d') &&
((buf[0]=='c' || buf[0]=='C') &&
(buf[1]=='i' || buf[1]=='I') &&
(buf[2]=='d' || buf[2]=='D') &&
buf[3]==':'))
{
// Make sure it's lowercase, otherwise it won't be found in the hash table