23980: convert relative href= and src= to absolute. r=sfraser

This commit is contained in:
akkana%netscape.com 2000-03-22 01:33:59 +00:00
parent 159267f7c4
commit 46ace3d54b
9 changed files with 168 additions and 48 deletions

View File

@ -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; }

View File

@ -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<nsIURI> 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");

View File

@ -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<count;i++)
nsAutoString name = aNode.GetText();
if (name.Equals("document_info"))
{
const nsString& key=aNode.GetKeyAt(i);
const nsString& value=aNode.GetValueAt(i);
if (key.Equals("charset"))
PRInt32 count=aNode.GetAttributeCount();
for(PRInt32 i=0;i<count;i++)
{
if (mCharsetOverride.Length() == 0)
mCharsetOverride.Assign(value);
InitEncoder();
const nsString& key=aNode.GetKeyAt(i);
if (key.Equals("charset"))
{
const nsString& value=aNode.GetValueAt(i);
if (mCharsetOverride.IsEmpty())
mCharsetOverride.Assign(value);
InitEncoder();
}
else if (key.Equals("uri"))
{
nsAutoString uristring (aNode.GetValueAt(i));
// strip double quotes from beginning and end
uristring.Trim("\"", PR_TRUE, PR_TRUE);
// And make it into a URI:
if (!uristring.IsEmpty())
NS_NewURI(getter_AddRefs(mURI), uristring);
}
}
}
}

View File

@ -49,6 +49,7 @@
#include "nsCOMPtr.h"
#include "nsHTMLTokens.h" // for eHTMLTags
#include "nsISaveAsCharset.h" // Some compilers can't do nsCOMPtr on a forward type
#include "nsIURI.h"
#define NS_IHTMLCONTENTSINKSTREAM_IID \
{0xa39c6bff, 0x15f0, 0x11d2, \
@ -185,6 +186,9 @@ protected:
PRInt32 mColPos;
PRBool mInBody;
PRUint32 mFlags;
nsCOMPtr<nsIURI> mURI;
PRBool mDoFormat;
PRBool mDoHeader;
PRBool mBodyOnly;

View File

@ -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; }

View File

@ -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<nsIURI> 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");

View File

@ -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<count;i++)
nsAutoString name = aNode.GetText();
if (name.Equals("document_info"))
{
const nsString& key=aNode.GetKeyAt(i);
const nsString& value=aNode.GetValueAt(i);
if (key.Equals("charset"))
PRInt32 count=aNode.GetAttributeCount();
for(PRInt32 i=0;i<count;i++)
{
if (mCharsetOverride.Length() == 0)
mCharsetOverride.Assign(value);
InitEncoder();
const nsString& key=aNode.GetKeyAt(i);
if (key.Equals("charset"))
{
const nsString& value=aNode.GetValueAt(i);
if (mCharsetOverride.IsEmpty())
mCharsetOverride.Assign(value);
InitEncoder();
}
else if (key.Equals("uri"))
{
nsAutoString uristring (aNode.GetValueAt(i));
// strip double quotes from beginning and end
uristring.Trim("\"", PR_TRUE, PR_TRUE);
// And make it into a URI:
if (!uristring.IsEmpty())
NS_NewURI(getter_AddRefs(mURI), uristring);
}
}
}
}

View File

@ -49,6 +49,7 @@
#include "nsCOMPtr.h"
#include "nsHTMLTokens.h" // for eHTMLTags
#include "nsISaveAsCharset.h" // Some compilers can't do nsCOMPtr on a forward type
#include "nsIURI.h"
#define NS_IHTMLCONTENTSINKSTREAM_IID \
{0xa39c6bff, 0x15f0, 0x11d2, \
@ -185,6 +186,9 @@ protected:
PRInt32 mColPos;
PRBool mInBody;
PRUint32 mFlags;
nsCOMPtr<nsIURI> mURI;
PRBool mDoFormat;
PRBool mDoHeader;
PRBool mBodyOnly;

View File

@ -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<nsIHTMLContentSink> 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<nsIHTMLContentSink> 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<nsIHTMLContentSink> 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);