diff --git a/mozilla/content/base/public/nsIDocumentEncoder.h b/mozilla/content/base/public/nsIDocumentEncoder.h index 6ad0c1c5274..a24955fb23f 100644 --- a/mozilla/content/base/public/nsIDocumentEncoder.h +++ b/mozilla/content/base/public/nsIDocumentEncoder.h @@ -89,7 +89,10 @@ public: // to text for mail sending. This differs just slightly // but in an important way from normal formatted, and that is that // lines are space stuffed. This can't (correctly) be done later. - OutputFormatFlowed = 64 + OutputFormatFlowed = 64, + + // Convert links, image src, and script src to absolute URLs when possible + OutputAbsoluteLinks = 128 }; static const nsIID& GetIID() { static nsIID iid = NS_IDOCUMENT_ENCODER_IID; return iid; } diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index adeaf44d040..7d64b88a25c 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -83,6 +83,8 @@ #include "nsIFrame.h" #include "nsLayoutUtils.h" +#include "nsNetUtil.h" // for NS_MakeAbsoluteURI + #include "nsIScriptSecurityManager.h" #include "nsIAggregatePrincipal.h" @@ -2851,10 +2853,18 @@ nsDocument::CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection) converter.AddStartTag("section"); converter.AddStartTag("section_head"); - nsString charset = mCharacterSet; - converter.BeginStartTag("document_info"); - converter.AddAttribute(nsString("charset"),charset); + converter.AddAttribute(nsAutoString("charset"),mCharacterSet); + nsCOMPtr uri (getter_AddRefs(GetDocumentURL())); + if (uri) + { + char* spec = 0; + if (NS_SUCCEEDED(uri->GetSpec(&spec)) && spec) + { + converter.AddAttribute(nsAutoString("uri"), spec); + Recycle(spec); + } + } converter.FinishStartTag("document_info",PR_TRUE,PR_TRUE); converter.AddEndTag("section_head"); diff --git a/mozilla/htmlparser/src/nsHTMLContentSinkStream.cpp b/mozilla/htmlparser/src/nsHTMLContentSinkStream.cpp index a2f477f7c6c..19553e4a15b 100644 --- a/mozilla/htmlparser/src/nsHTMLContentSinkStream.cpp +++ b/mozilla/htmlparser/src/nsHTMLContentSinkStream.cpp @@ -47,6 +47,7 @@ #include "nsIOutputStream.h" #include "nsFileStream.h" +#include "nsNetUtil.h" // for NS_MakeAbsoluteURI static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID); @@ -130,6 +131,7 @@ nsHTMLContentSinkStream::nsHTMLContentSinkStream() mBuffer = nsnull; mBufferSize = 0; mBufferLength = 0; + mFlags = 0; } NS_IMETHODIMP @@ -151,6 +153,7 @@ nsHTMLContentSinkStream::Initialize(nsIOutputStream* aOutStream, ((aFlags & nsIDocumentEncoder::OutputNoDoctype) ? PR_FALSE : PR_TRUE); mMaxColumn = 72; + mFlags = aFlags; mStream = aOutStream; mString = aOutString; @@ -292,10 +295,12 @@ void nsHTMLContentSinkStream::Write(const nsString& aString) return; // If an encoder is being used then convert first convert the input string + // Ideally, we should do this only for the stream case, + // and encode entities (using nsIEntityEncoder) but not charsets + // in the string case. if (mUnicodeEncoder) EncodeToBuffer(aString); - // No need to re-encode strings, since they're going from UCS2 to UCS2 if (mString) { if (mUnicodeEncoder) @@ -310,7 +315,7 @@ void nsHTMLContentSinkStream::Write(const nsString& aString) // Now handle the stream case: nsOutputStream out(mStream); - // If an encoder is being used then convert first convert the input string + // Test again in case there was a problem initializing the unicode encoder: if (mUnicodeEncoder) { out.write(mBuffer, mBufferLength); @@ -376,7 +381,8 @@ nsHTMLContentSinkStream::~nsHTMLContentSinkStream() * @param * @return */ -void nsHTMLContentSinkStream::WriteAttributes(const nsIParserNode& aNode) { +void nsHTMLContentSinkStream::WriteAttributes(const nsIParserNode& aNode) +{ int theCount=aNode.GetAttributeCount(); if(theCount) { int i=0; @@ -413,12 +419,29 @@ void nsHTMLContentSinkStream::WriteAttributes(const nsIParserNode& aNode) { EnsureBufferSize(key.Length()); key.ToCString(mBuffer,mBufferSize); - // send to ouput " [KEY]=" Write(' '); Write(mBuffer); mColPos += 1 + strlen(mBuffer) + 1; - + + // Make all links absolute when converting only the selection: + if ((mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) + && (key.Equals("href", PR_TRUE) || key.Equals("src", PR_TRUE) + // Would be nice to handle OBJECT and APPLET tags, + // but that gets more complicated since we have to + // search the tag list for CODEBASE as well. + // For now, just leave them relative. + )) + { + if (mURI) + { + nsAutoString absURI; + if (NS_SUCCEEDED(NS_MakeAbsoluteURI(value, mURI, absURI)) + && !absURI.IsEmpty()) + value = absURI; + } + } + if (value.Length() > 0) { Write(char(kEqual)); @@ -1120,22 +1143,39 @@ nsHTMLContentSinkStream::AddComment(const nsIParserNode& aNode){ * @return PR_TRUE if successful. */ NS_IMETHODIMP -nsHTMLContentSinkStream::OpenContainer(const nsIParserNode& aNode){ - - const nsString& name = aNode.GetText(); - if (name.Equals("document_info")) +nsHTMLContentSinkStream::OpenContainer(const nsIParserNode& aNode) +{ + // Look for XIF document_info tag. This has a type of userdefined; + // GetText() is slow, so don't call it unless we see the right node type. + eHTMLTags tag = (eHTMLTags)aNode.GetNodeType(); + if (tag == eHTMLTag_userdefined) { - PRInt32 count=aNode.GetAttributeCount(); - for(PRInt32 i=0;i mURI; + PRBool mDoFormat; PRBool mDoHeader; PRBool mBodyOnly; diff --git a/mozilla/layout/base/public/nsIDocumentEncoder.h b/mozilla/layout/base/public/nsIDocumentEncoder.h index 6ad0c1c5274..a24955fb23f 100644 --- a/mozilla/layout/base/public/nsIDocumentEncoder.h +++ b/mozilla/layout/base/public/nsIDocumentEncoder.h @@ -89,7 +89,10 @@ public: // to text for mail sending. This differs just slightly // but in an important way from normal formatted, and that is that // lines are space stuffed. This can't (correctly) be done later. - OutputFormatFlowed = 64 + OutputFormatFlowed = 64, + + // Convert links, image src, and script src to absolute URLs when possible + OutputAbsoluteLinks = 128 }; static const nsIID& GetIID() { static nsIID iid = NS_IDOCUMENT_ENCODER_IID; return iid; } diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp index adeaf44d040..7d64b88a25c 100644 --- a/mozilla/layout/base/src/nsDocument.cpp +++ b/mozilla/layout/base/src/nsDocument.cpp @@ -83,6 +83,8 @@ #include "nsIFrame.h" #include "nsLayoutUtils.h" +#include "nsNetUtil.h" // for NS_MakeAbsoluteURI + #include "nsIScriptSecurityManager.h" #include "nsIAggregatePrincipal.h" @@ -2851,10 +2853,18 @@ nsDocument::CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection) converter.AddStartTag("section"); converter.AddStartTag("section_head"); - nsString charset = mCharacterSet; - converter.BeginStartTag("document_info"); - converter.AddAttribute(nsString("charset"),charset); + converter.AddAttribute(nsAutoString("charset"),mCharacterSet); + nsCOMPtr uri (getter_AddRefs(GetDocumentURL())); + if (uri) + { + char* spec = 0; + if (NS_SUCCEEDED(uri->GetSpec(&spec)) && spec) + { + converter.AddAttribute(nsAutoString("uri"), spec); + Recycle(spec); + } + } converter.FinishStartTag("document_info",PR_TRUE,PR_TRUE); converter.AddEndTag("section_head"); diff --git a/mozilla/parser/htmlparser/src/nsHTMLContentSinkStream.cpp b/mozilla/parser/htmlparser/src/nsHTMLContentSinkStream.cpp index a2f477f7c6c..19553e4a15b 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLContentSinkStream.cpp +++ b/mozilla/parser/htmlparser/src/nsHTMLContentSinkStream.cpp @@ -47,6 +47,7 @@ #include "nsIOutputStream.h" #include "nsFileStream.h" +#include "nsNetUtil.h" // for NS_MakeAbsoluteURI static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID); @@ -130,6 +131,7 @@ nsHTMLContentSinkStream::nsHTMLContentSinkStream() mBuffer = nsnull; mBufferSize = 0; mBufferLength = 0; + mFlags = 0; } NS_IMETHODIMP @@ -151,6 +153,7 @@ nsHTMLContentSinkStream::Initialize(nsIOutputStream* aOutStream, ((aFlags & nsIDocumentEncoder::OutputNoDoctype) ? PR_FALSE : PR_TRUE); mMaxColumn = 72; + mFlags = aFlags; mStream = aOutStream; mString = aOutString; @@ -292,10 +295,12 @@ void nsHTMLContentSinkStream::Write(const nsString& aString) return; // If an encoder is being used then convert first convert the input string + // Ideally, we should do this only for the stream case, + // and encode entities (using nsIEntityEncoder) but not charsets + // in the string case. if (mUnicodeEncoder) EncodeToBuffer(aString); - // No need to re-encode strings, since they're going from UCS2 to UCS2 if (mString) { if (mUnicodeEncoder) @@ -310,7 +315,7 @@ void nsHTMLContentSinkStream::Write(const nsString& aString) // Now handle the stream case: nsOutputStream out(mStream); - // If an encoder is being used then convert first convert the input string + // Test again in case there was a problem initializing the unicode encoder: if (mUnicodeEncoder) { out.write(mBuffer, mBufferLength); @@ -376,7 +381,8 @@ nsHTMLContentSinkStream::~nsHTMLContentSinkStream() * @param * @return */ -void nsHTMLContentSinkStream::WriteAttributes(const nsIParserNode& aNode) { +void nsHTMLContentSinkStream::WriteAttributes(const nsIParserNode& aNode) +{ int theCount=aNode.GetAttributeCount(); if(theCount) { int i=0; @@ -413,12 +419,29 @@ void nsHTMLContentSinkStream::WriteAttributes(const nsIParserNode& aNode) { EnsureBufferSize(key.Length()); key.ToCString(mBuffer,mBufferSize); - // send to ouput " [KEY]=" Write(' '); Write(mBuffer); mColPos += 1 + strlen(mBuffer) + 1; - + + // Make all links absolute when converting only the selection: + if ((mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) + && (key.Equals("href", PR_TRUE) || key.Equals("src", PR_TRUE) + // Would be nice to handle OBJECT and APPLET tags, + // but that gets more complicated since we have to + // search the tag list for CODEBASE as well. + // For now, just leave them relative. + )) + { + if (mURI) + { + nsAutoString absURI; + if (NS_SUCCEEDED(NS_MakeAbsoluteURI(value, mURI, absURI)) + && !absURI.IsEmpty()) + value = absURI; + } + } + if (value.Length() > 0) { Write(char(kEqual)); @@ -1120,22 +1143,39 @@ nsHTMLContentSinkStream::AddComment(const nsIParserNode& aNode){ * @return PR_TRUE if successful. */ NS_IMETHODIMP -nsHTMLContentSinkStream::OpenContainer(const nsIParserNode& aNode){ - - const nsString& name = aNode.GetText(); - if (name.Equals("document_info")) +nsHTMLContentSinkStream::OpenContainer(const nsIParserNode& aNode) +{ + // Look for XIF document_info tag. This has a type of userdefined; + // GetText() is slow, so don't call it unless we see the right node type. + eHTMLTags tag = (eHTMLTags)aNode.GetNodeType(); + if (tag == eHTMLTag_userdefined) { - PRInt32 count=aNode.GetAttributeCount(); - for(PRInt32 i=0;i mURI; + PRBool mDoFormat; PRBool mDoHeader; PRBool mBodyOnly; diff --git a/mozilla/widget/src/xpwidgets/nsXIFFormatConverter.cpp b/mozilla/widget/src/xpwidgets/nsXIFFormatConverter.cpp index 898c522bca2..b7c0d5cdb57 100644 --- a/mozilla/widget/src/xpwidgets/nsXIFFormatConverter.cpp +++ b/mozilla/widget/src/xpwidgets/nsXIFFormatConverter.cpp @@ -42,7 +42,7 @@ #include "nsWidgetsCID.h" #include "nsXIFFormatConverter.h" #include "nsPrimitiveHelpers.h" - +#include "nsIDocumentEncoder.h" static NS_DEFINE_CID(kCParserCID, NS_PARSER_IID); // don't panic. NS_PARSER_IID just has the wrong name. @@ -314,7 +314,9 @@ nsXIFFormatConverter::ConvertFromXIFToText(const nsAutoString & aFromStr, nsCAut // convert it! nsCOMPtr sink; - rv = NS_New_HTMLToTXT_SinkStream(getter_AddRefs(sink),outStream,&platformCharset); + rv = NS_New_HTMLToTXT_SinkStream(getter_AddRefs(sink),outStream,&platformCharset, + nsIDocumentEncoder::OutputSelectionOnly + | nsIDocumentEncoder::OutputAbsoluteLinks); if ( sink ) { parser->SetContentSink(sink); @@ -353,7 +355,9 @@ nsXIFFormatConverter::ConvertFromXIFToUnicode(const nsAutoString & aFromStr, nsA // convert it! nsCOMPtr sink; - rv = NS_New_HTMLToTXT_SinkStream(getter_AddRefs(sink),&aToStr); + rv = NS_New_HTMLToTXT_SinkStream(getter_AddRefs(sink), &aToStr, 0, + nsIDocumentEncoder::OutputSelectionOnly + | nsIDocumentEncoder::OutputAbsoluteLinks); if ( sink ) { parser->SetContentSink(sink); @@ -386,7 +390,9 @@ nsXIFFormatConverter::ConvertFromXIFToHTML(const nsAutoString & aFromStr, nsAuto return rv; nsCOMPtr sink; - rv = NS_New_HTML_ContentSinkStream(getter_AddRefs(sink),&aToStr,0); + rv = NS_New_HTML_ContentSinkStream(getter_AddRefs(sink), &aToStr, + nsIDocumentEncoder::OutputSelectionOnly + | nsIDocumentEncoder::OutputAbsoluteLinks); if ( sink ) { parser->SetContentSink(sink);