mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
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:
parent
700930043a
commit
f8701a0b9f
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 = '=';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user